diff --git a/Editor/Config.cs b/Editor/Config.cs index d18559b..77b8cff 100644 --- a/Editor/Config.cs +++ b/Editor/Config.cs @@ -9,7 +9,10 @@ namespace NvimUnity public class Config { public string last_project = ""; - public void MergeMissingDefaults(Config defaults) { } +#if UNITY_EDITOR_WIN + public string neovimLocation = "C:\\Program Files\\Neovim\\bin\\nvim.exe"; +#endif + public void MergeMissingDefaults(Config defaults) { } } public static class ConfigManager diff --git a/Editor/NeovimEditor.cs b/Editor/NeovimEditor.cs index f455ce2..b18ef56 100644 --- a/Editor/NeovimEditor.cs +++ b/Editor/NeovimEditor.cs @@ -60,26 +60,32 @@ public bool OpenProject(string path, int line, int column) { if (OS == "Windows") { + +#if UNITY_EDITOR_WIN var psi = new ProcessStartInfo { FileName = defaultApp, - Arguments = $"{path} {line}", + Arguments = $"{path} {line} {config.neovimLocation}", UseShellExecute = true, CreateNoWindow = false, }; if(debugging) UnityEngine.Debug.Log($"[NvimUnity] Executing: {psi.FileName} {psi.Arguments}"); - Process.Start(defaultApp, $"{path} {line}"); + Process.Start(defaultApp, $"{path} {line} {config.neovimLocation}"); +#endif } else { - // Original behavior for other OSes + +#if !UNITY_EDITOR_WIN + // Original behavior for other OSes ProcessStartInfo psi = Utils.BuildProcessStartInfo(defaultApp, path, line); if(debugging) UnityEngine.Debug.Log($"[NvimUnity] Executing in terminal: {psi.FileName} {psi.Arguments}"); Process.Start(psi); - } +#endif + } return true; } catch (Exception ex) @@ -100,7 +106,13 @@ public bool OpenFile(string filePath, int line) { string cmd = $"e +{line} {filePath}"; string nvimArgs = $"--server {Socket} --remote-send \"{cmd}\""; - string nvimPath = Utils.GetNeovimPath(); + string nvimPath = + +#if UNITY_EDITOR_WIN + config.neovimLocation; +#else + Utils.GetNeovimPath(); +#endif var psi = new ProcessStartInfo { @@ -134,7 +146,19 @@ public void OnGUI() } EditorGUILayout.EndHorizontal(); + + +#if UNITY_EDITOR_WIN + EditorGUILayout.BeginHorizontal(); + GUILayout.Label("Neovim location", EditorStyles.boldLabel, GUILayout.Width(250)); + config.neovimLocation = GUILayout.TextField(config.neovimLocation); + if(GUILayout.Button("Browse", GUILayout.Width(80))){ + config.neovimLocation = EditorUtility.OpenFilePanel("Select neovim", "", "exe"); + ConfigManager.SaveConfig(config); + } + EditorGUILayout.EndHorizontal(); +#endif GUILayout.Space(10); } @@ -189,7 +213,7 @@ public bool TryGetInstallationForPath(string editorPath, out CodeEditor.Installa return true; } - public void Save() + public static void Save() { if (needSaveConfig) { diff --git a/Editor/Utils.cs b/Editor/Utils.cs index 8625241..5d78a79 100644 --- a/Editor/Utils.cs +++ b/Editor/Utils.cs @@ -140,10 +140,10 @@ public static void EnsureLauncherExecutable() } #endif } +#if !UNITY_EDITOR_WIN public static ProcessStartInfo BuildProcessStartInfo(string defaultApp, string path, int line) { -#if !UNITY_EDITOR_WIN string preferredTerminal = NeovimPreferences.GetPreferredTerminal(); string fileName = "/usr/bin/env"; @@ -183,13 +183,12 @@ public static ProcessStartInfo BuildProcessStartInfo(string defaultApp, string p UseShellExecute = true, CreateNoWindow = false }; -#endif - return null; } +#endif +#if !UNITY_EDITOR_WIN public static bool IsTerminalAvailable(string terminalName) { -#if !UNITY_EDITOR_WIN UnityEngine.Debug.Log($"[NvimUnity] Checking if terminal is available: {terminalName}"); try { @@ -213,9 +212,9 @@ public static bool IsTerminalAvailable(string terminalName) { return false; } -#endif - return true; } +#endif + } } diff --git a/README.md b/README.md index 8c5f41d..5dabdeb 100644 --- a/README.md +++ b/README.md @@ -1,284 +1 @@ -![Nvim Unity Banner](Documentation/Banner.png) - -# NvimUnity - -

- Neovim Plugin - - Awesome - - License: MIT -

- -This Unity package integrates Neovim as an external script editor and provides a **Regenerate Project Files** button inside the Unity Editor. - - -## 🧩 Features - -- 🧠 Automatically open C# scripts in Neovim when clicked in Unity -- πŸ–₯️ Opens all files from the same Unity project in the **same terminal and buffer** -- πŸ”„ Regenerate `.csproj` files via a Unity button -- πŸ”Œ Unity package + Neovim plugin architecture -- πŸ”₯ Zero dependency on `nvr` (Neovim Remote) - - -## πŸ“‚ Installation - -### πŸ–₯️ Windows - -Download the latest installer: - -πŸ‘‰ [Download for Windows](https://github.com/apyra/nvim-unity/releases/latest/download/nvimunity-setup.exe) - ---- - -### 🐧 Linux - -βœ… Test and feedbacks required! - - πŸ‘‰ [Download .AppImage](https://github.com/apyra/nvim-unity/releases/latest/download/nvimunity-linux.AppImage) - -- **AppImage (Portable)** - - ```bash - mv NvimUnity.AppImage ~/.local/bin/nvimunity - chmod +x ~/.local/bin/nvimunity - - ``` - -After installing, run with `nvimunity` or find it in your applications. - ---- - -### 🍎 macOS ### - -βœ… Test and feedbacks required! - -πŸ‘‰ [Download for macOS](https://github.com/apyra/nvim-unity/releases/latest/download/NvimUnity.dmg). - -#### Installation Steps - -1. Open the downloaded `.dmg` file. -2. Drag the `NvimUnity.app` into your `Applications` folder. -3. Launch `NvimUnity` from your `Applications` folder. - ---- - -* πŸš€ Nice tip for the standalones: Hold **Shift** while launching to load the last Unity opened project. - -### Unity - -1. Install the Unity package from Git: - -```json -https://github.com/apyra/nvim-unity.git -``` -2. Unity will auto-detect the editor as **"Neovim Code Editor"** in `External Tools`: - -- Go to `Edit > Preferences > External Tools` -- Select **Neovim Code Editor** (no need to browse for `.exe`) - - -### Neovim (Lua) - -### πŸ” File Sync with [nvim-unity-sync](https://github.com/apyra/nvim-unity-sync) - -This plugin keeps your `.csproj` updated when creating/renaming/deleting `.cs` files in nvim even if Unity is closed: - -```lua -{ - "apyra/nvim-unity-sync", - lazy = false, - config = function() - require("unity.plugin").setup() - end, -} -``` - -## Usage - -### Open Files from Unity -- Click in a `.cs` file in Unity and it will open in Neovim, simple like that. -- All files from the same project share a terminal. - -### Regenerate Project Files -- From Unity: `Preferences > External Tools > Regenerate Project Files` -- From Tools Menu: `Tools > Neovim Code Editor > Regenerate Project Files` - -## 🧠 Recommended Configuration - -- [Neovim](https://neovim.io/) *(required)* -- [NvChad](https://nvchad.com/) as your Neovim base, with: - - LSP - - Lazy.nvim - - Mason.nvim - - Telescope - - GitSigns - - Tabs for multi-file editing - - -### πŸ”§ LSP Setup for C# - -Install `omnisharp` using [mason.nvim](https://github.com/williamboman/mason.nvim), it requires .Net installed. - -```lua -local lspconfig = require("lspconfig") -lspconfig.omnisharp.setup { - on_attach = nvlsp.on_attach, - capabilities = nvlsp.capabilities, - cmd = { - "dotnet", - vim.fn.stdpath "data" .. "\\mason\\packages\\omnisharp\\libexec\\OmniSharp.dll", - }, - settings = { - FormattingOptions = { - EnableEditorConfigSupport = false, - OrganizeImports = true, - }, - Sdk = { - IncludePrereleases = true, - }, - }, -} -``` - -> ⚠️ Omnisharp requires `.csproj` and `.sln` in the root folder β€” make sure to use "Regenerate Project Files" if missing. *It may take a second or two to attach into your working buffer. - - -### 🌲 Treesitter Setup - -```lua -{ - "nvim-treesitter/nvim-treesitter", - opts = { - ensure_installed = { - "c_sharp", - }, - }, -} -``` - -Then run `:TSInstall` in Neovim. - - -### πŸ€– Copilot (Optional) - -```lua -{ - "github/copilot.vim", - lazy = false, - config = function() - vim.g.copilot_no_tab_map = true - vim.g.copilot_assume_mapped = true - end, -} -``` - -In `mappings.lua` (NvChad): - -```lua -map("i", "", function() - vim.fn.feedkeys(vim.fn["copilot#Accept"](), "") -end, { desc = "Copilot Accept", noremap = true, silent = true }) -``` - -### 🧬 Vim Fugitive for Git (Optional) - -```lua -use { - 'tpope/vim-fugitive', - config = function() - -- Optional config - end -} -``` - -### πŸ“ Folding with [nvim-ufo](https://github.com/kevinhwang91/nvim-ufo) (Optional) - -```lua -{ - "kevinhwang91/nvim-ufo", - -- your config here -} -``` - -## 🧩 Unity Snippets - -Use [LuaSnip](https://github.com/L3MON4D3/LuaSnip) to insert Unity C# boilerplate. - -### ✍️ Snippet Setup - -**Linux/macOS:** - -``` -~/.config/nvim/lua/snippets/cs.lua -``` - -**Windows:** - -``` -C:/Users/YOUR_USERNAME/AppData/Local/nvim/lua/snippets/cs.lua -``` - -### πŸ”Œ Load Snippets - -**Linux/macOS:** - -```lua -require("luasnip.loaders.from_lua").load({ paths = "~/.config/nvim/lua/snippets" }) -``` - -**Windows:** - -```lua -require("luasnip.loaders.from_lua").lazy_load({ - paths = vim.fn.stdpath("config") .. "/lua/snippets" -}) -``` - -### 🧾 Example Snippets - -```lua --- cs.lua -local ls = require("luasnip") -local s, t, i = ls.snippet, ls.text_node, ls.insert_node - -return { - s("start", { t("void Start() {"), t({"", " "}), i(1), t({"", "}"}) }), - s("update", { t("void Update() {"), t({"", " "}), i(1), t({"", "}"}) }), - s("awake", { t("void Awake() {"), t({"", " "}), i(1), t({"", "}"}) }), - s("fixedupdate", { t("void FixedUpdate() {"), t({"", " "}), i(1), t({"", "}"}) }), - s("onenable", { t("void OnEnable() {"), t({"", " "}), i(1), t({"", "}"}) }), - s("ondisable", { t("void OnDisable() {"), t({"", " "}), i(1), t({"", "}"}) }), - s("ontriggerenter", { t("void OnTriggerEnter(Collider other) {"), t({"", " "}), i(1), t({"", "}"}) }), - s("oncollisionenter", { t("void OnCollisionEnter(Collision collision) {"), t({"", " "}), i(1), t({"", "}"}) }), - s("serializefield", { t("[SerializeField] private "), i(1, "Type"), t(" "), i(2, "variableName"), t(";") }), - s("publicfield", { t("public "), i(1, "Type"), t(" "), i(2, "variableName"), t(";") }), - s("log", { t('Debug.Log("'), i(1, "message"), t('");') }), - s("class", { - t("using UnityEngine;"), t({"", ""}), - t("public class "), i(1, "ClassName"), t(" : MonoBehaviour"), - t({"", "{"}), - t({"", " "}), i(2, "// Your code here"), - t({"", "}"}), - }), -} -``` - -## πŸ› οΈ Known Issues - -When you create, delete, or move scripts in Unity, synchronization with the default code editor only happens after the compilation process. So if you open a script before it has been included in the .csproj, you won’t have LSP goodies like code completion. - -The fastest workflow: First open your project in unity it will automatically generates the .csproj for you. If you don't want to wait for compilation, create .cs files directly in Neovim (e.g., using nvim-tree or an LSP action like "move to its own file") with [nvim-unity-sync](https://github.com/apyra/nvim-unity-sync) installed. And if for some reason any script is not included in the project, run :Usync to sync all .cs files in the Assets folder. Once you have the .csproj already generated, you can edit your code without Unity if you wish. - -## ⚑ Final Note - -Neovim is a blazing-fast editor. With NvChad + LSP + this Unity integration, it becomes a powerful Unity dev environment. - -## πŸ§‘ Contributing - -PRs, issues, ideas welcome! This project is evolving – help shape it πŸš€ - -## πŸ“„ License - -MIT +fork of https://github.com/apyra/nvim-unity containing fixes for windows platform