├── .dockerignore ├── .github └── workflows │ └── docker-push.yml ├── .gitignore ├── Dockerfile ├── LICENSE.md ├── README.md ├── godot_sample_project ├── icon.svg ├── icon.svg.import ├── project.godot ├── sample.gd └── sample.tscn ├── justfile ├── nvim_config ├── init.lua ├── lua │ ├── autocmds.lua │ ├── keymaps.lua │ ├── package_manager.lua │ ├── package_manager_config.lua │ └── settings.lua └── stylua.toml └── run.sh /.dockerignore: -------------------------------------------------------------------------------- 1 | **/plugin/packer_compiled.lua 2 | -------------------------------------------------------------------------------- /.github/workflows/docker-push.yml: -------------------------------------------------------------------------------- 1 | name: "🐳 Docker (Build and Push)" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - "nvim_config/**" 9 | - "godot_sample_project/**" 10 | 11 | jobs: 12 | docker: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: set up qemu 16 | uses: docker/setup-qemu-action@v2 17 | 18 | - name: set up docker buildx 19 | uses: docker/setup-buildx-action@v2 20 | 21 | - name: login to docker hub 22 | uses: docker/login-action@v2 23 | with: 24 | username: ${{ secrets.DOCKERHUB_USERNAME }} 25 | password: ${{ secrets.DOCKERHUB_TOKEN }} 26 | 27 | - name: build and push 28 | uses: docker/build-push-action@v3 29 | with: 30 | push: true 31 | tags: niscolas/nvim-godot:latest 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## neovim 2 | nvim_config/**/plugin/packer_compiled.lua 3 | 4 | ## godot 5 | godot_sample_project/**/.import/ 6 | godot_sample_project/**/.godot/ 7 | godot_sample_project/**/export.cfg 8 | godot_sample_project/**/export_presets.cfg 9 | # imported translations (automatically generated from csv files) 10 | godot_sample_project/**/*.translation 11 | # mono-specific ignores 12 | godot_sample_project/**/.mono/ 13 | godot_sample_project/**/data_*/ 14 | godot_sample_project/**/mono_crash.*.json 15 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | RUN apk --no-cache add \ 4 | automake \ 5 | build-base \ 6 | cmake \ 7 | coreutils \ 8 | ctags \ 9 | curl \ 10 | fd \ 11 | git \ 12 | libtool \ 13 | neovim \ 14 | pkgconf \ 15 | py3-pip\ 16 | ripgrep 17 | 18 | RUN pip3 install "gdtoolkit==3.*" 19 | 20 | COPY ./nvim_config /root/.config/nvim 21 | COPY ./godot_sample_project /godot_sample_project 22 | 23 | EXPOSE 6005 24 | EXPOSE 6006 25 | 26 | WORKDIR /godot_sample_project 27 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Nícolas Catarina Parreiras 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ↖️ Table of Contents 2 | 3 |
4 | Neovim logo 5 | Godot logo 6 |
7 | 8 | # nvim-godot 9 | Use Neovim as your Godot code editor 10 | 11 | ## ✨ Features 12 | - ❓ A step-by-step guide on how to setup a dev environment in Neovim to work seamlessly with Godot 13 | - 🔋 A good looking minimal Neovim config with IDE-like features 14 | - 🏃 An executable file to allow Godot to open files directly into Neovim 15 | - 🐋 A Docker Image packed with the Minimal Neovim Config for a quick setup 16 | 17 | ## ⚡ Getting Started 18 | 19 | 1. [🛠️ Installation and Setup](#installation-and-setup-section) 20 | 2. [🏃 The `run.sh` File](#run-sh-section) 21 | 3. [🤖 Godot External Editor Settings](#godot-external-editor-settings-section) 22 | 23 | 24 | ## 🛠️ Installation and Setup 25 | 26 | To be able to leverage the power of the Neovim-Godot integration, you can follow one of these paths: 27 | 28 | ### 🐋 Docker 29 | To get up and running quickly, or to test the setup, you can just run the following command if you have Docker installed: 30 | 31 | ``` 32 | docker run -it -p 6005:6005 -p 6006:6006 niscolas/nvim-godot:latest 33 | ``` 34 | 35 | > 💡 One important thing to note is that the some error messages will appear on Neovim startup related to the Lua Language Server since it doesn't support Alpine (the base image) 36 | 37 | #### ➕ Additional Info 38 | > 💡 You can add the `--rm` option to remove the container as soon as you're finished with testing 39 | 40 | ``` 41 | docker run --rm -it -p 6005:6005 -p 6006:6006 niscolas/nvim-godot:latest 42 | ``` 43 | 44 | > ⚠️ And you can add the `--network host` option to be able to use the host machine (your PC probably) network (I normally have to use it since I broke my Docker settings), but it's advised against 45 | 46 | ``` 47 | docker run --network host -it niscolas/nvim-godot:latest 48 | ``` 49 | 50 | ### ⬇️ Using the Minimal Neovim Config in your machine 51 | 52 | - Can be done by cloning the repo and moving the [nvim_config/](nvim_config/) directory to your `$HOME/.config/nvim` 53 | 54 | **OR** 55 | 56 | - With this simple script: 57 | 58 | > ⚠️ Your current Neovim config will be moved to `$HOME/.config/nvim.old`, make sure that it's already in you Version Control system or that you know what you're doing) 59 | 60 | ``` 61 | mv $HOME/.config/nvim $HOME/.config/nvim.old && \ 62 | git clone https://github.com/niscolas/nvim-godot && \ 63 | mv nvim-godot/nvim_config $HOME/.config/nvim 64 | ``` 65 | 66 | 67 | 68 | 69 | ## 🏃 The `run.sh` File 70 | The [run.sh](run.sh) is an executable `bash` file responsible for opening your terminal and launching Neovim with the correct file (line and column) opened. 71 | 72 | You may need to edit it to fit your needs, the places where changes maybe be needed are commented in the file itself. 73 | 74 | 75 | ## 🤖 Godot External Editor Settings 76 | 1. In Godot, go to `Editor > Editor Settings... > (General Tab) > Text Editor > External` 77 | 2. Set `Use External Editor` to ✅ 78 | 3. Set `Exec Path` to the location of the `run.sh` file on your system 79 | 4. Set `Exec Flags` to `"{file}" "{line},{col}"` 80 |
81 | Step-by-Step with Images 82 | 83 | 84 | 85 |
86 | 87 | ## ⚙️ The Neovim Config 88 | ### 👉 Introduction 89 | > ⚠️ In order for the LSP features to work, you need a running instance of Godot 4 90 | 91 | Out of the box you should have: 92 | - ➡️ Autocompletion (integrated with LSP and Snippets) 93 | - 🧠 General LSP features, just like in Godot's built-in Editor: 94 | - 🌐 Go to Definition 95 | - 🚦 Linting 96 | - 🌸 A nice looking theme (with GDScript highlighting) 97 | 98 | ### 🌸 *aesthetics* 99 | This is the default look of the custom Neovim Config included in this repo: ([🌲 *everforest theme*](https://github.com/sainnhe/everforest)) 100 | > 💡 Screenshots taken from the Neovim instance running on the Docker container! 101 | 102 | 103 |
104 | Extra screenshots 105 | 106 | 107 |
108 | 109 | ### 📦 Settings and Plugins 110 | Most of the Neovim config was copied from [nvim-lua/kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim), with the theme change and the Godot specific LSP, TreeSitter and DAP settings 111 | -------------------------------------------------------------------------------- /godot_sample_project/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /godot_sample_project/icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dag1jtjiggkpe" 6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.svg" 14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /godot_sample_project/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | [application] 12 | 13 | config/name="Sample Project" 14 | config/features=PackedStringArray("4.0", "GL Compatibility") 15 | config/icon="res://icon.svg" 16 | 17 | [rendering] 18 | 19 | renderer/rendering_method="gl_compatibility" 20 | renderer/rendering_method.mobile="gl_compatibility" 21 | -------------------------------------------------------------------------------- /godot_sample_project/sample.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | 4 | # Called when the node enters the scene tree for the first time. 5 | func _ready(): 6 | pass # Replace with function body. 7 | 8 | 9 | # Called every frame. 'delta' is the elapsed time since the previous frame. 10 | func _process(delta): 11 | pass 12 | -------------------------------------------------------------------------------- /godot_sample_project/sample.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://b4d8nkqul0p4m"] 2 | 3 | [ext_resource type="Script" path="res://sample.gd" id="1_1fj00"] 4 | 5 | [node name="Root" type="Node2D"] 6 | script = ExtResource("1_1fj00") 7 | -------------------------------------------------------------------------------- /justfile: -------------------------------------------------------------------------------- 1 | docker-run: 2 | docker run --rm -it --network host niscolas/nvim-godot 3 | 4 | docker-build: 5 | docker image rm niscolas/nvim-godot -f && docker build . --network host -t niscolas/nvim-godot 6 | -------------------------------------------------------------------------------- /nvim_config/init.lua: -------------------------------------------------------------------------------- 1 | -- config based on `https://github.com/nvim-lua/kickstart.nvim` 2 | 3 | -- `require` is a lua method that loads a given module, in this case, 4 | -- the `package_manager` file in the `lua` directory 5 | local is_bootstraping_package_manager = require("package_manager") 6 | if is_bootstraping_package_manager then 7 | return 8 | end 9 | 10 | -- each string passed to the `require` function loads the respective file in 11 | -- the `lua` directory, consult them in order to better understand the config :D 12 | require("settings") 13 | require("autocmds") 14 | require("keymaps") 15 | require("package_manager_config") 16 | -------------------------------------------------------------------------------- /nvim_config/lua/autocmds.lua: -------------------------------------------------------------------------------- 1 | -- automatically source and re-compile packer whenever you save this init.lua 2 | local packer_augroup = vim.api.nvim_create_augroup("Packer", { clear = true }) 3 | vim.api.nvim_create_autocmd("BufWritePost", { 4 | command = "source | silent! LspStop | silent! LspStart | PackerCompile", 5 | group = packer_augroup, 6 | pattern = vim.fn.expand("$MYVIMRC"), 7 | }) 8 | 9 | -- [[ Highlight on yank ]] 10 | -- See `:help vim.highlight.on_yank()` 11 | local highlight_augroup = 12 | vim.api.nvim_create_augroup("YankHighlight", { clear = true }) 13 | 14 | vim.api.nvim_create_autocmd("TextYankPost", { 15 | callback = function() 16 | vim.highlight.on_yank() 17 | end, 18 | group = highlight_augroup, 19 | pattern = "*", 20 | }) 21 | -------------------------------------------------------------------------------- /nvim_config/lua/keymaps.lua: -------------------------------------------------------------------------------- 1 | -- Keymaps for better default experience 2 | -- See `:help vim.keymap.set()` 3 | vim.keymap.set({ "n", "v" }, "", "", { silent = true }) 4 | 5 | -- Remap for dealing with word wrap 6 | vim.keymap.set( 7 | "n", 8 | "k", 9 | "v:count == 0 ? 'gk' : 'k'", 10 | { expr = true, silent = true } 11 | ) 12 | vim.keymap.set( 13 | "n", 14 | "j", 15 | "v:count == 0 ? 'gj' : 'j'", 16 | { expr = true, silent = true } 17 | ) 18 | 19 | -- Diagnostic keymaps 20 | vim.keymap.set("n", "[d", vim.diagnostic.goto_prev) 21 | vim.keymap.set("n", "]d", vim.diagnostic.goto_next) 22 | vim.keymap.set("n", "e", vim.diagnostic.open_float) 23 | vim.keymap.set("n", "q", vim.diagnostic.setloclist) 24 | -------------------------------------------------------------------------------- /nvim_config/lua/package_manager.lua: -------------------------------------------------------------------------------- 1 | local plugins_install_path = vim.fn.stdpath("data") 2 | .. "/site/pack/packer/start/packer.nvim" 3 | local is_bootstrap = false 4 | 5 | -- `packer` is our package manager and it needs to be downloaded externally 6 | -- before loading any plugin 7 | local bootstrap_packer = function() 8 | if vim.fn.empty(vim.fn.glob(plugins_install_path)) > 0 then 9 | is_bootstrap = true 10 | vim.fn.system { 11 | "git", 12 | "clone", 13 | "--depth", 14 | "1", 15 | "https://github.com/wbthomason/packer.nvim", 16 | plugins_install_path, 17 | } 18 | vim.cmd([[packadd packer.nvim]]) 19 | end 20 | end 21 | 22 | bootstrap_packer() 23 | 24 | -- for each package listed here, you can search on github for their 25 | -- name to know more 26 | require("packer").startup(function(use) 27 | -- package manger 28 | use { "wbthomason/packer.nvim" } 29 | 30 | -- lsp: language server protocol 31 | use { "folke/neodev.nvim" } 32 | use { "neovim/nvim-lspconfig" } 33 | use { "williamboman/mason-lspconfig.nvim" } 34 | use { "williamboman/mason.nvim" } 35 | use { "jose-elias-alvarez/null-ls.nvim" } 36 | 37 | -- dap: debug adapter protocol (debugger) 38 | use { "mfussenegger/nvim-dap" } 39 | 40 | -- nvim-cmp: autocompletion 41 | use { "hrsh7th/nvim-cmp" } 42 | use { "hrsh7th/cmp-nvim-lsp" } 43 | use { "L3MON4D3/LuaSnip" } 44 | use { "saadparwaiz1/cmp_luasnip" } 45 | 46 | -- treesitter: code highlighting 47 | use { 48 | "nvim-treesitter/nvim-treesitter", 49 | run = function() 50 | pcall(require("nvim-treesitter.install").update { 51 | with_sync = true, 52 | }) 53 | end, 54 | } 55 | use { -- Additional text objects via treesitter 56 | "nvim-treesitter/nvim-treesitter-textobjects", 57 | after = "nvim-treesitter", 58 | } 59 | 60 | -- git 61 | use { "lewis6991/gitsigns.nvim" } 62 | use { "tpope/vim-fugitive" } 63 | use { "tpope/vim-rhubarb" } 64 | 65 | -- ui 66 | use { "lukas-reineke/indent-blankline.nvim" } -- add indentation guides even on blank lines 67 | use { "numToStr/Comment.nvim" } -- "gc" to comment visual regions/lines 68 | use { "nvim-lualine/lualine.nvim" } 69 | use { "sainnhe/everforest" } 70 | use { "tpope/vim-sleuth" } -- detect tabstop and shiftwidth automatically 71 | 72 | -- telescope 73 | use { "nvim-telescope/telescope.nvim" } 74 | -- Fuzzy Finder Algorithm which requires local dependencies to be built. Only load if `make` is available 75 | use { 76 | "nvim-telescope/telescope-fzf-native.nvim", 77 | run = "make", 78 | cond = vim.fn.executable("make") == 1, 79 | } 80 | 81 | -- misc 82 | use { "nvim-lua/plenary.nvim" } 83 | use { "folke/which-key.nvim" } 84 | 85 | if is_bootstrap then 86 | require("packer").sync() 87 | end 88 | end) 89 | 90 | -- when we are bootstrapping a configuration, it doesn"t 91 | -- make sense to execute the rest of the init.lua. 92 | -- you"ll need to restart nvim, and then it will work. 93 | if is_bootstrap then 94 | print("==================================") 95 | print(" plugins are being installed") 96 | print(" wait until packer completes,") 97 | print(" then restart nvim") 98 | print("==================================") 99 | end 100 | 101 | return is_bootstrap 102 | -------------------------------------------------------------------------------- /nvim_config/lua/package_manager_config.lua: -------------------------------------------------------------------------------- 1 | -- [[ Configure Lualine ]] 2 | -- See `:help lualine` 3 | require("lualine").setup { 4 | options = { 5 | icons_enabled = true, 6 | theme = "everforest", 7 | component_separators = "|", 8 | section_separators = "", 9 | }, 10 | } 11 | 12 | -- [[ Configure Comment.nvim ]] 13 | -- See `:help comment-nvim` 14 | require("Comment").setup() 15 | 16 | -- [[ Configure indent-blankline.nvim ]] 17 | -- See `:help indent_blankline` 18 | require("indent_blankline").setup { 19 | char = "┊", 20 | show_trailing_blankline_indent = false, 21 | } 22 | 23 | -- [[ Configure Gitsigns ]] 24 | -- See `:help gitsigns` 25 | require("gitsigns").setup { 26 | signs = { 27 | add = { text = "+" }, 28 | change = { text = "~" }, 29 | delete = { text = "_" }, 30 | topdelete = { text = "‾" }, 31 | changedelete = { text = "~" }, 32 | }, 33 | } 34 | 35 | -- [[ Configure Telescope ]] 36 | -- See `:help telescope` and `:help telescope.setup()` 37 | require("telescope").setup { 38 | defaults = { 39 | mappings = { 40 | i = { 41 | [""] = false, 42 | [""] = false, 43 | }, 44 | }, 45 | }, 46 | } 47 | 48 | -- Enable telescope fzf native, if installed 49 | pcall(require("telescope").load_extension, "fzf") 50 | 51 | -- See `:help telescope.builtin` 52 | vim.keymap.set( 53 | "n", 54 | "?", 55 | require("telescope.builtin").oldfiles, 56 | { desc = "[?] Find recently opened files" } 57 | ) 58 | vim.keymap.set( 59 | "n", 60 | "", 61 | require("telescope.builtin").buffers, 62 | { desc = "[ ] Find existing buffers" } 63 | ) 64 | vim.keymap.set("n", "/", function() 65 | -- You can pass additional configuration to telescope to change theme, layout, etc. 66 | require("telescope.builtin").current_buffer_fuzzy_find( 67 | require("telescope.themes").get_dropdown { 68 | winblend = 10, 69 | previewer = false, 70 | } 71 | ) 72 | end, { desc = "[/] Fuzzily search in current buffer]" }) 73 | 74 | vim.keymap.set( 75 | "n", 76 | "sf", 77 | require("telescope.builtin").find_files, 78 | { desc = "[S]earch [F]iles" } 79 | ) 80 | vim.keymap.set( 81 | "n", 82 | "sh", 83 | require("telescope.builtin").help_tags, 84 | { desc = "[S]earch [H]elp" } 85 | ) 86 | vim.keymap.set( 87 | "n", 88 | "sw", 89 | require("telescope.builtin").grep_string, 90 | { desc = "[S]earch current [W]ord" } 91 | ) 92 | vim.keymap.set( 93 | "n", 94 | "sg", 95 | require("telescope.builtin").live_grep, 96 | { desc = "[S]earch by [G]rep" } 97 | ) 98 | vim.keymap.set( 99 | "n", 100 | "sd", 101 | require("telescope.builtin").diagnostics, 102 | { desc = "[S]earch [D]iagnostics" } 103 | ) 104 | 105 | -- [[ Configure Treesitter ]] 106 | -- See `:help which-key.nvim` 107 | require("which-key").setup() 108 | 109 | -- [[ Configure Treesitter ]] 110 | -- See `:help nvim-treesitter` 111 | require("nvim-treesitter.configs").setup { 112 | -- Add languages to be installed here that you want installed for treesitter 113 | -- Uncomment other languagues if needed 114 | ensure_installed = { 115 | -- "c", 116 | -- "cpp", 117 | -- "go", 118 | -- "python", 119 | -- "rust", 120 | -- "typescript", 121 | 122 | "c_sharp", 123 | "gdscript", 124 | "lua", 125 | "help", 126 | "vim", 127 | }, 128 | 129 | highlight = { enable = true }, 130 | indent = { enable = true }, 131 | incremental_selection = { 132 | enable = true, 133 | keymaps = { 134 | init_selection = "", 135 | node_incremental = "", 136 | scope_incremental = "", 137 | node_decremental = "", 138 | }, 139 | }, 140 | textobjects = { 141 | select = { 142 | enable = true, 143 | lookahead = true, -- Automatically jump forward to textobj, similar to targets.vim 144 | keymaps = { 145 | -- You can use the capture groups defined in textobjects.scm 146 | ["aa"] = "@parameter.outer", 147 | ["ia"] = "@parameter.inner", 148 | ["af"] = "@function.outer", 149 | ["if"] = "@function.inner", 150 | ["ac"] = "@class.outer", 151 | ["ic"] = "@class.inner", 152 | }, 153 | }, 154 | move = { 155 | enable = true, 156 | set_jumps = true, -- whether to set jumps in the jumplist 157 | goto_next_start = { 158 | ["]m"] = "@function.outer", 159 | ["]]"] = "@class.outer", 160 | }, 161 | goto_next_end = { 162 | ["]M"] = "@function.outer", 163 | ["]["] = "@class.outer", 164 | }, 165 | goto_previous_start = { 166 | ["[m"] = "@function.outer", 167 | ["[["] = "@class.outer", 168 | }, 169 | goto_previous_end = { 170 | ["[M"] = "@function.outer", 171 | ["[]"] = "@class.outer", 172 | }, 173 | }, 174 | swap = { 175 | enable = true, 176 | swap_next = { 177 | ["a"] = "@parameter.inner", 178 | }, 179 | swap_previous = { 180 | ["A"] = "@parameter.inner", 181 | }, 182 | }, 183 | }, 184 | } 185 | 186 | -- [[ Configure LSP ]] 187 | -- This function gets run when an LSP connects to a particular buffer. 188 | local on_attach = function(_, bufnr) 189 | -- NOTE: Remember that lua is a real programming language, and as such it is possible 190 | -- to define small helper and utility functions so you don"t have to repeat yourself 191 | -- many times. 192 | -- 193 | -- In this case, we create a function that lets us more easily define mappings specific 194 | -- for LSP related items. It sets the mode, buffer and description for us each time. 195 | local nmap = function(keys, func, desc) 196 | if desc then 197 | desc = "LSP: " .. desc 198 | end 199 | 200 | vim.keymap.set("n", keys, func, { buffer = bufnr, desc = desc }) 201 | end 202 | 203 | nmap("rn", vim.lsp.buf.rename, "[R]e[n]ame") 204 | nmap("ca", vim.lsp.buf.code_action, "[C]ode [A]ction") 205 | 206 | nmap("gd", vim.lsp.buf.definition, "[G]oto [D]efinition") 207 | nmap( 208 | "gr", 209 | require("telescope.builtin").lsp_references, 210 | "[G]oto [R]eferences" 211 | ) 212 | nmap("gI", vim.lsp.buf.implementation, "[G]oto [I]mplementation") 213 | nmap("D", vim.lsp.buf.type_definition, "Type [D]efinition") 214 | nmap( 215 | "ds", 216 | require("telescope.builtin").lsp_document_symbols, 217 | "[D]ocument [S]ymbols" 218 | ) 219 | nmap( 220 | "ws", 221 | require("telescope.builtin").lsp_dynamic_workspace_symbols, 222 | "[W]orkspace [S]ymbols" 223 | ) 224 | 225 | -- See `:help K` for why this keymap 226 | nmap("K", vim.lsp.buf.hover, "Hover Documentation") 227 | nmap("", vim.lsp.buf.signature_help, "Signature Documentation") 228 | 229 | -- Lesser used LSP functionality 230 | nmap("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") 231 | nmap( 232 | "wa", 233 | vim.lsp.buf.add_workspace_folder, 234 | "[W]orkspace [A]dd Folder" 235 | ) 236 | nmap( 237 | "wr", 238 | vim.lsp.buf.remove_workspace_folder, 239 | "[W]orkspace [R]emove Folder" 240 | ) 241 | nmap("wl", function() 242 | print(vim.inspect(vim.lsp.buf.list_workspace_folders())) 243 | end, "[W]orkspace [L]ist Folders") 244 | end 245 | 246 | -- Enable the following language servers 247 | -- feel free to add/remove any lsps that you want here. they will automatically be installed. 248 | -- add any additional override configuration in the following tables. they will be passed to 249 | -- the `settings` field of the server config. you must look up that documentation yourself. 250 | local servers = { 251 | -- clangd = {}, 252 | -- gopls = {}, 253 | -- pyright = {}, 254 | -- rust_analyzer = {}, 255 | -- tsserver = {}, 256 | 257 | gdscript = {}, 258 | lua_ls = { 259 | Lua = { 260 | workspace = { checkThirdParty = false }, 261 | telemetry = { enable = false }, 262 | }, 263 | }, 264 | } 265 | 266 | local ensure_installed_servers = { "lua_ls" } 267 | 268 | -- [[ Configure null-ls ]] 269 | local null_ls = require("null-ls") 270 | 271 | local lsp_format = function(bufnr) 272 | vim.lsp.buf.format { 273 | filter = function(client) 274 | -- apply whatever logic you want (in this example, we'll only use null-ls) 275 | return client.name == "null-ls" 276 | end, 277 | bufnr = bufnr, 278 | } 279 | end 280 | 281 | local augroup = vim.api.nvim_create_augroup("LspFormatting", {}) 282 | 283 | local null_ls_on_attach = function(client, bufnr) 284 | if not client.supports_method("textDocument/formatting") then 285 | return 286 | end 287 | 288 | vim.api.nvim_clear_autocmds { group = augroup, buffer = bufnr } 289 | vim.api.nvim_create_autocmd("BufWritePre", { 290 | group = augroup, 291 | buffer = bufnr, 292 | callback = function() 293 | lsp_format(bufnr) 294 | end, 295 | }) 296 | end 297 | 298 | null_ls.setup { 299 | on_attach = null_ls_on_attach, 300 | sources = { 301 | null_ls.builtins.formatting.stylua, 302 | null_ls.builtins.formatting.gdformat, 303 | }, 304 | } 305 | 306 | -- [[ Configure Neodev ]] 307 | require("neodev").setup() 308 | 309 | -- [[ Configure Cmp (1) ]] 310 | -- nvim-cmp supports additional completion capabilities, so broadcast that to servers 311 | local capabilities = vim.lsp.protocol.make_client_capabilities() 312 | capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities) 313 | 314 | -- [[ Configure Mason / Mason-LSPconfig ]] 315 | -- Setup mason so it can manage external tooling 316 | require("mason").setup() 317 | 318 | -- Ensure the servers above are installed 319 | local mason_lspconfig = require("mason-lspconfig") 320 | 321 | mason_lspconfig.setup { 322 | ensure_installed = ensure_installed_servers, 323 | } 324 | 325 | for server, opts in pairs(servers) do 326 | require("lspconfig")[server].setup { 327 | capabilities = capabilities, 328 | on_attach = on_attach, 329 | settings = opts, 330 | } 331 | end 332 | 333 | -- [[ Configure Cmp (2), Luasnip ]] 334 | -- See `:help nvim-cmp` 335 | local cmp = require("cmp") 336 | local luasnip = require("luasnip") 337 | 338 | cmp.setup { 339 | snippet = { 340 | expand = function(args) 341 | luasnip.lsp_expand(args.body) 342 | end, 343 | }, 344 | mapping = cmp.mapping.preset.insert { 345 | [""] = cmp.mapping.scroll_docs(-4), 346 | [""] = cmp.mapping.scroll_docs(4), 347 | [""] = cmp.mapping.complete(), 348 | [""] = cmp.mapping.confirm { 349 | behavior = cmp.ConfirmBehavior.Replace, 350 | select = true, 351 | }, 352 | [""] = cmp.mapping(function(fallback) 353 | if cmp.visible() then 354 | cmp.select_next_item() 355 | elseif luasnip.expand_or_jumpable() then 356 | luasnip.expand_or_jump() 357 | else 358 | fallback() 359 | end 360 | end, { "i", "s" }), 361 | [""] = cmp.mapping(function(fallback) 362 | if cmp.visible() then 363 | cmp.select_prev_item() 364 | elseif luasnip.jumpable(-1) then 365 | luasnip.jump(-1) 366 | else 367 | fallback() 368 | end 369 | end, { "i", "s" }), 370 | }, 371 | sources = { 372 | { name = "nvim_lsp" }, 373 | { name = "luasnip" }, 374 | }, 375 | } 376 | 377 | local setup_godot_dap = function() 378 | local dap = require("dap") 379 | 380 | dap.adapters.godot = { 381 | type = "server", 382 | host = "127.0.0.1", 383 | port = 6006, 384 | } 385 | 386 | dap.configurations.gdscript = { 387 | { 388 | launch_game_instance = false, 389 | launch_scene = false, 390 | name = "Launch scene", 391 | project = "${workspaceFolder}", 392 | request = "launch", 393 | type = "godot", 394 | }, 395 | } 396 | end 397 | 398 | setup_godot_dap() 399 | -------------------------------------------------------------------------------- /nvim_config/lua/settings.lua: -------------------------------------------------------------------------------- 1 | -- [[ Setting options ]] 2 | -- See `:help vim.o` 3 | 4 | -- Set highlight on search 5 | vim.o.hlsearch = false 6 | 7 | -- Make line numbers default 8 | vim.wo.number = true 9 | 10 | -- Enable mouse mode 11 | vim.o.mouse = "a" 12 | 13 | -- Enable break indent 14 | vim.o.breakindent = true 15 | 16 | -- Save undo history 17 | vim.o.undofile = true 18 | 19 | -- Case insensitive searching UNLESS /C or capital in search 20 | vim.o.ignorecase = true 21 | vim.o.smartcase = true 22 | 23 | -- Decrease update time 24 | vim.o.updatetime = 250 25 | vim.wo.signcolumn = "yes" 26 | 27 | -- Set colorscheme 28 | vim.o.termguicolors = true 29 | vim.cmd("colorscheme everforest") 30 | 31 | -- Set completeopt to have a better completion experience 32 | vim.o.completeopt = "menuone,noselect" 33 | 34 | -- [[ Basic Keymaps ]] 35 | -- Set as the leader key 36 | -- See `:help mapleader` 37 | -- NOTE: Must happen before plugins are required (otherwise wrong leader will be used) 38 | vim.g.mapleader = " " 39 | vim.g.maplocalleader = " " 40 | -------------------------------------------------------------------------------- /nvim_config/stylua.toml: -------------------------------------------------------------------------------- 1 | call_parentheses = "NoSingleTable" 2 | column_width = 80 3 | indent_type = "Spaces" 4 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # CHANGE IF NEEDED: 4 | # - replace with your Terminal Emulator executable 5 | term_exec="wezterm" 6 | # - replace with your Neovim executable 7 | nvim_exec="nvim" 8 | # - replace with other path for the Neovim server pipe 9 | server_path="$HOME/.cache/nvim/godot-server.pipe" 10 | # - if you don't get the gdscript in nvim on startup increase this number NOTE: delay is in seconds 11 | server_startup_delay=0.1 12 | 13 | start_server() { 14 | "$term_exec" -e "$nvim_exec" --listen "$server_path" 15 | } 16 | 17 | open_file_in_server() { 18 | # - escape stuff because nvim will not 19 | filename=$(printf %q "$1") 20 | "$term_exec" -e "$nvim_exec" --server "$server_path" --remote-send ":n $filename:call cursor($2)" 21 | } 22 | 23 | if ! [ -e "$server_path" ]; then 24 | # - start server FIRST then open the file 25 | start_server & 26 | sleep $server_startup_delay # - wait for the server to start 27 | open_file_in_server "$1" "$2" 28 | else 29 | open_file_in_server "$1" "$2" 30 | fi 31 | --------------------------------------------------------------------------------