Using Unity Editor With Emacs (Part 2)
A while ago, I wrote an article about using Unity with Emacs. While this article is still useful, I have encountered a few more issues with Unity, and learned better ways to deal with its unique demands. It is written with the assumption that you have already read the aforementioned article.
A new "solution" solution: The Rider plugin
I previously mentioned an issue with the Visual Studio Code “emulation” method
of Emacs integration: having to set FrameworkPathOverride
due to some mono
environment weirdness. There are additional problems with the VS Code support
package: the csc.rsp file is not taken into account when generating the project
build options, meaning that if you want to, for example, enable C# 8 nullable
reference types, OmniSharp will not pick up these options and loudly complain.
The JetBrains Rider IDE support package generates solution and project files
which makes these problems disappear. Unfortunately, it’s not sufficient enough
to make a simple shim which execs its command line arguments as in the solution
described in the previous article; if Unity thinks it’s using Rider, it will
invoke the binary using hardcoded command-line options. This unfortunately
necessitated the creation of a slightly less trivial tool: rider2emacs. This is
a simple Rust tool which translates command-line arguments from Rider to
emacsclient. The latest version of unity.el advises this approach instead of
using the code
shim.
Issues with lsp-mode
finding the project root
Even if you followed the instructions down to the letter in my previous blog
post, you may have run into an issue where LSP still doesn’t work properly. One
potential culprit is that lsp-mode
did not correctly guess the root of the
project, even with lsp-auto-guess-root
enabled; the same might happen if you
use eglot instead. This will likely happen if you aren’t using Git or some other
VCS in your project.
From my understanding, both of these packages depend on determining the project root by using the built-in project.el package. With no recognized VCS set up, project.el is unable to determine the root, and OmniSharp flounders as a result. The simplest solution, of course, is to just set up VCS in your project. (You ought to be doing this anyway!) But if that is not an option for you, the Emacs manual provides guidance on using EDE (Emacs Development Environment) instead, but this is quite a heavyweight solution.
There’s a third option as well: the project-find-functions
variable. To use
this, you essentially create a new project.el “backend” specific to C# projects.
(cl-defmethod project-root ((project (head csharp))) (cdr project)) (defun my/project-try-csharp (dir) (if-let ((root (locate-dominating-file dir (lambda (dir) (directory-files dir nil "\\.sln$" t 1))))) (cons 'csharp root))) (add-hook 'project-find-functions #'my/project-try-csharp)
For more information about project backends, this article is invaluable reading!