Repository: boltlessengineer/NativeVim Branch: main Commit: dfe0f6764d08 Files: 12 Total size: 11.3 KB Directory structure: gitextract_fgl05_9y/ ├── .gitignore ├── LICENSE ├── README.md ├── init.lua ├── lsp/ │ ├── gopls.lua │ ├── lua_ls.lua │ └── ts_ls.lua └── lua/ ├── core/ │ ├── lsp.lua │ ├── options.lua │ ├── statusline.lua │ └── treesitter.lua └── util.lua ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # ignore all personal configs I don't want to ship with this config: **/*personal.lua ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2024 Seongmin Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # NativeVim ![preview](https://github.com/boltlessengineer/nativevim/assets/60088301/7d0c6841-6e4c-43e0-8982-dc58328f484c) > NativeVim is a Neovim config without plugins NativeVim is **not**: - a distro[^1] - a plugin/package - or something that tries to reinvent famous plugins NativeVim **doesn't** include: - a package manager (e.g. `lazy.nvim` or `rocks.nvim`) - famous plugins like `nvim-lspconfig`, `nvim-cmp` and `nvim-treesitter` - and any other vim/neovim plugins NativeVim has features like: - basic LSP functionalities - TreeSitter Highlighting - completions and more! > [!CAUTION] > Since this config was developed to demonstrate the most native method, it may be slower or lack features than other configs. ## Why? This is an academical project to see if I can write Neovim config from scratch without any external plugins. So people can understand the Neovim plugin ecosystem more and know what exact plugins they really need. > [!NOTE] > I'm not saying "you don't need any of those plugins". Most plugins out there have their own reasons to be used. > But if you're curious about the solution without them, this project is for you. ## Requirement - Neovim v0.11+ ## How to use NativeVim doesn't support any plugin manager by default. Just clone it to `~/.config/nativevim` and use with `NVIM_APPNAME` environment variable. ```sh # 1. clone it git clone https://github.com/boltlessengineer/nativevim.git ~/.config/nativevim # 2. use it with NVIM_APPNAME NVIM_APPNAME=nativevim nvim ``` > [!NOTE] > NativeVim is just a Neovim config template designed to be read. It's just ~200 lines of lua code. > Take some time and read through the entire codebase to see how it works. > Feel free to open an issue if you have a different opinion about default config. ## Lines of Code ``` -------------------------------------------------------------------------------- Language Files Lines Blank Comment Code -------------------------------------------------------------------------------- Lua 9 235 45 72 118 Markdown 1 69 21 0 48 -------------------------------------------------------------------------------- Total 10 304 66 72 166 -------------------------------------------------------------------------------- ``` [^1]: unless you call [kickstart.nvim] a Neovim distro [kickstart.nvim]: https://github.com/nvim-lua/kickstart.nvim ================================================ FILE: init.lua ================================================ if vim.fn.has("nvim-0.11") == 0 then vim.notify("NativeVim only supports Neovim 0.11+", vim.log.levels.ERROR) return end require("core.options") require("core.treesitter") require("core.lsp") require("core.statusline") ================================================ FILE: lsp/gopls.lua ================================================ ---@type vim.lsp.Config return { cmd = { "gopls" }, root_markers = { "go.work", "go.mod", ".git" }, filetypes = { "go", "gomod", "gowork", "gotmpl" }, } ================================================ FILE: lsp/lua_ls.lua ================================================ ---@type vim.lsp.Config return { cmd = { "lua-language-server" }, root_markers = { ".luarc.json", ".luarc.jsonc", ".luacheckrc", ".stylua.toml", "stylua.toml", "selene.toml", "selene.yml", ".git" }, filetypes = { "lua" }, on_init = require("util").lua_ls_on_init, } ================================================ FILE: lsp/ts_ls.lua ================================================ ---@type vim.lsp.Config return { cmd = { "typescript-language-server", "--stdio" }, root_markers = { "tsconfig.json", "jsconfig.json", "package.json", ".git" }, filetypes = { "javascript", "javascriptreact", "javascript.jsx", "typescript", "typescriptreact", "typescript.tsx" }, init_options = { hostInfo = "neovim", }, } ================================================ FILE: lua/core/lsp.lua ================================================ -- :h lsp-config -- enable lsp completion vim.api.nvim_create_autocmd("LspAttach", { group = vim.api.nvim_create_augroup("UserLspAttach", { clear = true }), callback = function(ev) vim.lsp.completion.enable(true, ev.data.client_id, ev.buf) end, }) -- enable configured language servers -- you can find server configurations from lsp/*.lua files vim.lsp.enable('gopls') vim.lsp.enable('lua_ls') vim.lsp.enable('ts_ls') ================================================ FILE: lua/core/options.lua ================================================ -- general options vim.o.completeopt = "menu,menuone,popup,fuzzy" -- modern completion menu vim.o.foldenable = true -- enable fold vim.o.foldlevel = 99 -- start editing with all folds opened vim.o.foldmethod = "expr" -- use tree-sitter for folding method vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()" -- NOTE: Setting vim options can be opinionated. -- While options above are crucial to make this whole config work as expected, -- below are just list of options I think most users will satisfy. -- Feel free to modify as your preference. vim.o.termguicolors = true -- enable rgb colors vim.o.cursorline = true -- enable cursor line vim.o.number = true -- enable line number vim.o.relativenumber = true -- and relative line number vim.o.signcolumn = "yes" -- always show sign column vim.o.pumheight = 10 -- max height of completion menu vim.o.list = true -- use special characters to represent things like tabs or trailing spaces vim.opt.listchars = { -- NOTE: using `vim.opt` instead of `vim.o` to pass rich object tab = "▏ ", trail = "·", extends = "»", precedes = "«", } vim.opt.diffopt:append("linematch:60") -- second stage diff to align lines vim.o.confirm = true -- show dialog for unsaved file(s) before quit vim.o.updatetime = 200 -- save swap file with 200ms debouncing vim.o.ignorecase = true -- case-insensitive search vim.o.smartcase = true -- , until search pattern contains upper case characters vim.o.smartindent = true -- auto-indenting when starting a new line vim.o.shiftround = true -- round indent to multiple of 'shiftwidth' vim.o.shiftwidth = 0 -- 0 to follow the 'tabstop' value vim.o.tabstop = 4 -- tab width vim.o.undofile = true -- enable persistent undo vim.o.undolevels = 10000 -- 10x more undo levels -- define and keys -- you should use `vim.keycode` to translate keycodes or pass raw keycode values like `" "` instead of just `""` vim.g.mapleader = vim.keycode("") vim.g.maplocalleader = vim.keycode("") -- remove netrw banner for cleaner looking vim.g.netrw_banner = 0 ================================================ FILE: lua/core/statusline.lua ================================================ --[[ :h 'statusline' This is default statusline value: ```lua vim.o.statusline = "%f %h%w%m%r%=%-14.(%l,%c%V%) %P" ``` below is simple example of custom statusline using neovim APIs See `:h 'statusline'` for more information about statusline. ]] ---Show attached LSP clients in `[name1, name2]` format. ---Long server names will be modified. For example, `lua-language-server` will be shorten to `lua-ls` ---Returns an empty string if there aren't any attached LSP clients. ---@return string local function lsp_status() local attached_clients = vim.lsp.get_clients({ bufnr = 0 }) if #attached_clients == 0 then return "" end local names = vim.iter(attached_clients) :map(function(client) local name = client.name:gsub("language.server", "ls") return name end) :totable() return "[" .. table.concat(names, ", ") .. "]" end function _G.statusline() return table.concat({ "%f", "%h%w%m%r", "%=", lsp_status(), " %-14(%l,%c%V%)", "%P", }, " ") end vim.o.statusline = "%{%v:lua._G.statusline()%}" ================================================ FILE: lua/core/treesitter.lua ================================================ --[[ # How to install tree-sitter parsers manually? There are two ways to install tree-sitter parsers - download from git repository 1. download parser to `'runtimepath'` from git repository (e.g. clone to `~/.local/share/nvim/site/pack/*/start/tree-sitter-rust`) 2. write needed queries manually (e.g. `highlights.scm`, `folds.scm`) - install with luarocks 1. install parser with luarocks (e.g. `tree-sitter-css`) 2. add installed path to `'runtimepath'` First way is how `nvim-treesitter`'s `:TSInstall rust` works. `nvim-treesitter` also includes all needed queries for supported languages at this point (09-Jul-2024.) If we do all manually, second way is more convenient because we don't need to manually write all needed queries for each languages. ## 1. install parser with luarocks ```console luarocks \ --lua-version=5.1 \ --tree=$HOME/.local/share/nvim/rocks \ install tree-sitter-rust ``` We need to specify local install path with `--tree` flag. Here, we are using `rocks` folder in `stdpath("data")` (see `:h $XDG_DATA_HOME`.) ## 2. add installed rock to `'packpath'` Installed parser will be in `~/.local/share/nvim/rocks/lib/luarocks/rocks-5.1/tree-sitter-rust/0.0.27-1` where `0.0.27-1` is the installed version. Add this path to `'packpath'` so that Neovim can recognize and register the parser and bundled queries. ```console # create target packpath directory (`treesitter` is arbitrary) mkdir -p $HOME/.local/share/nvim/site/pack/treesitter/start # symlink installed rock to packpath ln -sf $HOME/.local/share/nvim/rocks/lib/luarocks/rocks-5.1/tree-sitter-rust/0.0.27-1 $HOME/.local/share/nvim/site/pack/treesitter/start/tree-sitter-rust ``` ## 3. start the parser in `FileType` AutoCommand ```lua vim.api.nvim_create_autocmd("FileType", { callback = function(ev) pcall(vim.treesitter.start) end }) ``` Add this code in your config. Reopen the editor, and you are done. --]] vim.api.nvim_create_autocmd("FileType", { callback = function() pcall(vim.treesitter.start) end }) ================================================ FILE: lua/util.lua ================================================ local M = {} function M.lua_ls_on_init(client) local path = vim.tbl_get(client, "workspace_folders", 1, "name") if not path then return end -- override the lua-language-server settings for Neovim config client.settings = vim.tbl_deep_extend('force', client.settings, { Lua = { runtime = { version = 'LuaJIT' }, -- Make the server aware of Neovim runtime files workspace = { checkThirdParty = false, library = { vim.env.VIMRUNTIME -- Depending on the usage, you might want to add additional paths here. -- "${3rd}/luv/library" -- "${3rd}/busted/library", } -- or pull in all of 'runtimepath'. NOTE: this is a lot slower -- library = vim.api.nvim_get_runtime_file("", true) } } }) end return M