From 9e6a100eb01a3275f99558e8fe1a9e3ea7376c77 Mon Sep 17 00:00:00 2001 From: Jason Miller Date: Sun, 17 Nov 2024 01:11:16 -0500 Subject: [PATCH] updates: 20241117 --- README.md | 238 ++-------------- doc/kickstart.txt | 24 -- doc/tags | 3 - init.lua | 708 +++++++++++++++------------------------------- 4 files changed, 242 insertions(+), 731 deletions(-) delete mode 100644 doc/kickstart.txt delete mode 100644 doc/tags diff --git a/README.md b/README.md index 3f19854c..860ba6e7 100644 --- a/README.md +++ b/README.md @@ -1,229 +1,27 @@ -# kickstart.nvim +## ⚙️ My Neovim Configuration -## Introduction +This is my personal neovim configuration and it's unlikely to be perfect +for your use case. -A starting point for Neovim that is: +What is in it? -* Small -* Single-file -* Completely Documented +* *Kickstart*: based configuration +* *Neovimacs*: modeless editing support, with common Emacs bindings in insert mode +* *Esc*: to toggle between insert (emacs bindings) and normal (neovim mode) +* *Tabs*: Prev (F1), Next (F2), New (F3), and Close (F4) to jump around +* *Movement*: Arrows and Tabs (and, yes, I know) +* *Batteries*: Python LSP, completion, treesitter -**NOT** a Neovim distribution, but instead a starting point for your configuration. +## 📦 Installation -## Installation - -### Install Neovim - -Kickstart.nvim targets *only* the latest -['stable'](https://github.com/neovim/neovim/releases/tag/stable) and latest -['nightly'](https://github.com/neovim/neovim/releases/tag/nightly) of Neovim. -If you are experiencing issues, please make sure you have the latest versions. - -### Install External Dependencies - -External Requirements: -- Basic utils: `git`, `make`, `unzip`, C Compiler (`gcc`) -- [ripgrep](https://github.com/BurntSushi/ripgrep#installation) -- Clipboard tool (xclip/xsel/win32yank or other depending on platform) -- A [Nerd Font](https://www.nerdfonts.com/): optional, provides various icons - - if you have it set `vim.g.have_nerd_font` in `init.lua` to true -- Language Setup: - - If want to write Typescript, you need `npm` - - If want to write Golang, you will need `go` - - etc. - -> **NOTE** -> See [Install Recipes](#Install-Recipes) for additional Windows and Linux specific notes -> and quick install snippets - -### Install Kickstart - -> **NOTE** -> [Backup](#FAQ) your previous configuration (if any exists) - -Neovim's configurations are located under the following paths, depending on your OS: - -| OS | PATH | -| :- | :--- | -| Linux, MacOS | `$XDG_CONFIG_HOME/nvim`, `~/.config/nvim` | -| Windows (cmd)| `%localappdata%\nvim\` | -| Windows (powershell)| `$env:LOCALAPPDATA\nvim\` | - -#### Recommended Step - -[Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) this repo -so that you have your own copy that you can modify, then install by cloning the -fork to your machine using one of the commands below, depending on your OS. - -> **NOTE** -> Your fork's url will be something like this: -> `https://github.com//kickstart.nvim.git` - -#### Clone kickstart.nvim -> **NOTE** -> If following the recommended step above (i.e., forking the repo), replace -> `nvim-lua` with `` in the commands below - -
Linux and Mac - -```sh -git clone https://github.com/nvim-lua/kickstart.nvim.git "${XDG_CONFIG_HOME:-$HOME/.config}"/nvim +```bash +cd ~/.config +git clone git@github.com:millerjason/neovimrc.git +ln -s neovimrc nvim ``` -
+### References -
Windows - -If you're using `cmd.exe`: - -``` -git clone https://github.com/nvim-lua/kickstart.nvim.git %localappdata%\nvim\ -``` - -If you're using `powershell.exe` - -``` -git clone https://github.com/nvim-lua/kickstart.nvim.git $env:LOCALAPPDATA\nvim\ -``` - -
- -### Post Installation - -Start Neovim - -```sh -nvim -``` - -That's it! Lazy will install all the plugins you have. Use `:Lazy` to view -current plugin status. Hit `q` to close the window. - -Read through the `init.lua` file in your configuration folder for more -information about extending and exploring Neovim. That also includes -examples of adding popularly requested plugins. - - -### Getting Started - -[The Only Video You Need to Get Started with Neovim](https://youtu.be/m8C0Cq9Uv9o) - -### FAQ - -* What should I do if I already have a pre-existing neovim configuration? - * You should back it up and then delete all associated files. - * This includes your existing init.lua and the neovim files in `~/.local` - which can be deleted with `rm -rf ~/.local/share/nvim/` -* Can I keep my existing configuration in parallel to kickstart? - * Yes! You can use [NVIM_APPNAME](https://neovim.io/doc/user/starting.html#%24NVIM_APPNAME)`=nvim-NAME` - to maintain multiple configurations. For example, you can install the kickstart - configuration in `~/.config/nvim-kickstart` and create an alias: - ``` - alias nvim-kickstart='NVIM_APPNAME="nvim-kickstart" nvim' - ``` - When you run Neovim using `nvim-kickstart` alias it will use the alternative - config directory and the matching local directory - `~/.local/share/nvim-kickstart`. You can apply this approach to any Neovim - distribution that you would like to try out. -* What if I want to "uninstall" this configuration: - * See [lazy.nvim uninstall](https://github.com/folke/lazy.nvim#-uninstalling) information -* Why is the kickstart `init.lua` a single file? Wouldn't it make sense to split it into multiple files? - * The main purpose of kickstart is to serve as a teaching tool and a reference - configuration that someone can easily use to `git clone` as a basis for their own. - As you progress in learning Neovim and Lua, you might consider splitting `init.lua` - into smaller parts. A fork of kickstart that does this while maintaining the - same functionality is available here: - * [kickstart-modular.nvim](https://github.com/dam9000/kickstart-modular.nvim) - * Discussions on this topic can be found here: - * [Restructure the configuration](https://github.com/nvim-lua/kickstart.nvim/issues/218) - * [Reorganize init.lua into a multi-file setup](https://github.com/nvim-lua/kickstart.nvim/pull/473) - -### Install Recipes - -Below you can find OS specific install instructions for Neovim and dependencies. - -After installing all the dependencies continue with the [Install Kickstart](#Install-Kickstart) step. - -#### Windows Installation - -
Windows with Microsoft C++ Build Tools and CMake -Installation may require installing build tools and updating the run command for `telescope-fzf-native` - -See `telescope-fzf-native` documentation for [more details](https://github.com/nvim-telescope/telescope-fzf-native.nvim#installation) - -This requires: - -- Install CMake and the Microsoft C++ Build Tools on Windows - -```lua -{'nvim-telescope/telescope-fzf-native.nvim', build = 'cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release && cmake --install build --prefix build' } -``` -
-
Windows with gcc/make using chocolatey -Alternatively, one can install gcc and make which don't require changing the config, -the easiest way is to use choco: - -1. install [chocolatey](https://chocolatey.org/install) -either follow the instructions on the page or use winget, -run in cmd as **admin**: -``` -winget install --accept-source-agreements chocolatey.chocolatey -``` - -2. install all requirements using choco, exit previous cmd and -open a new one so that choco path is set, and run in cmd as **admin**: -``` -choco install -y neovim git ripgrep wget fd unzip gzip mingw make -``` -
-
WSL (Windows Subsystem for Linux) - -``` -wsl --install -wsl -sudo add-apt-repository ppa:neovim-ppa/unstable -y -sudo apt update -sudo apt install make gcc ripgrep unzip git xclip neovim -``` -
- -#### Linux Install -
Ubuntu Install Steps - -``` -sudo add-apt-repository ppa:neovim-ppa/unstable -y -sudo apt update -sudo apt install make gcc ripgrep unzip git xclip neovim -``` -
-
Debian Install Steps - -``` -sudo apt update -sudo apt install make gcc ripgrep unzip git xclip curl - -# Now we install nvim -curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux64.tar.gz -sudo rm -rf /opt/nvim-linux64 -sudo mkdir -p /opt/nvim-linux64 -sudo chmod a+rX /opt/nvim-linux64 -sudo tar -C /opt -xzf nvim-linux64.tar.gz - -# make it available in /usr/local/bin, distro installs to /usr/bin -sudo ln -sf /opt/nvim-linux64/bin/nvim /usr/local/bin/ -``` -
-
Fedora Install Steps - -``` -sudo dnf install -y gcc make git ripgrep fd-find unzip neovim -``` -
- -
Arch Install Steps - -``` -sudo pacman -S --noconfirm --needed gcc make git ripgrep fd unzip neovim -``` -
+Kickstart: [kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim) +Kickstart Video: [Get Started with Neovim](https://youtu.be/m8C0Cq9Uv9o) diff --git a/doc/kickstart.txt b/doc/kickstart.txt deleted file mode 100644 index cb87ac3f..00000000 --- a/doc/kickstart.txt +++ /dev/null @@ -1,24 +0,0 @@ -================================================================================ -INTRODUCTION *kickstart.nvim* - -Kickstart.nvim is a project to help you get started on your neovim journey. - - *kickstart-is-not* -It is not: -- Complete framework for every plugin under the sun -- Place to add every plugin that could ever be useful - - *kickstart-is* -It is: -- Somewhere that has a good start for the most common "IDE" type features: - - autocompletion - - goto-definition - - find references - - fuzzy finding - - and hinting at what more can be done :) -- A place to _kickstart_ your journey. - - You should fork this project and use/modify it so that it matches your - style and preferences. If you don't want to do that, there are probably - other projects that would fit much better for you (and that's great!)! - - vim:tw=78:ts=8:ft=help:norl: diff --git a/doc/tags b/doc/tags deleted file mode 100644 index 687ae772..00000000 --- a/doc/tags +++ /dev/null @@ -1,3 +0,0 @@ -kickstart-is kickstart.txt /*kickstart-is* -kickstart-is-not kickstart.txt /*kickstart-is-not* -kickstart.nvim kickstart.txt /*kickstart.nvim* diff --git a/init.lua b/init.lua index 220d3045..09aabcd3 100644 --- a/init.lua +++ b/init.lua @@ -1,201 +1,71 @@ ---[[ - -===================================================================== -==================== READ THIS BEFORE CONTINUING ==================== -===================================================================== -======== .-----. ======== -======== .----------------------. | === | ======== -======== |.-""""""""""""""""""-.| |-----| ======== -======== || || | === | ======== -======== || KICKSTART.NVIM || |-----| ======== -======== || || | === | ======== -======== || || |-----| ======== -======== ||:Tutor || |:::::| ======== -======== |'-..................-'| |____o| ======== -======== `"")----------------(""` ___________ ======== -======== /::::::::::| |::::::::::\ \ no mouse \ ======== -======== /:::========| |==hjkl==:::\ \ required \ ======== -======== '""""""""""""' '""""""""""""' '""""""""""' ======== -======== ======== -===================================================================== -===================================================================== - -What is Kickstart? - - Kickstart.nvim is *not* a distribution. - - Kickstart.nvim is a starting point for your own configuration. - The goal is that you can read every line of code, top-to-bottom, understand - what your configuration is doing, and modify it to suit your needs. - - Once you've done that, you can start exploring, configuring and tinkering to - make Neovim your own! That might mean leaving Kickstart just the way it is for a while - or immediately breaking it into modular pieces. It's up to you! - - If you don't know anything about Lua, I recommend taking some time to read through - a guide. One possible example which will only take 10-15 minutes: - - https://learnxinyminutes.com/docs/lua/ - - After understanding a bit more about Lua, you can use `:help lua-guide` as a - reference for how Neovim integrates Lua. - - :help lua-guide - - (or HTML version): https://neovim.io/doc/user/lua-guide.html - -Kickstart Guide: - - TODO: The very first thing you should do is to run the command `:Tutor` in Neovim. - - If you don't know what this means, type the following: - - - - : - - Tutor - - - - (If you already know the Neovim basics, you can skip this step.) - - Once you've completed that, you can continue working through **AND READING** the rest - of the kickstart init.lua. - - Next, run AND READ `:help`. - This will open up a help window with some basic information - about reading, navigating and searching the builtin help documentation. - - This should be the first place you go to look when you're stuck or confused - with something. It's one of my favorite Neovim features. - - MOST IMPORTANTLY, we provide a keymap "sh" to [s]earch the [h]elp documentation, - which is very useful when you're not exactly sure of what you're looking for. - - I have left several `:help X` comments throughout the init.lua - These are hints about where to find more information about the relevant settings, - plugins or Neovim features used in Kickstart. - - NOTE: Look for lines like this - - Throughout the file. These are for you, the reader, to help you understand what is happening. - Feel free to delete them once you know what you're doing, but they should serve as a guide - for when you are first encountering a few different constructs in your Neovim config. - -If you experience any errors while trying to install kickstart, run `:checkhealth` for more info. - -I hope you enjoy your Neovim journey, -- TJ - -P.S. You can delete this when you're done too. It's your config now! :) ---]] - --- Set as the leader key --- See `:help mapleader` --- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used) +-- NOTE: Leader before plugins are loaded (otherwise wrong leader will be used) vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' +vim.g.have_nerd_font = true --- Set to true if you have a Nerd Font installed and selected in the terminal -vim.g.have_nerd_font = false - --- [[ Setting options ]] --- See `:help vim.opt` --- NOTE: You can change these options as you wish! --- For more options, you can see `:help option-list` - --- Make line numbers default -vim.opt.number = true --- You can also add relative line numbers, to help with jumping. --- Experiment for yourself to see if you like it! --- vim.opt.relativenumber = true - --- Enable mouse mode, can be useful for resizing splits for example! -vim.opt.mouse = 'a' - --- Don't show the mode, since it's already in the status line +-- Margins +vim.opt.title = false -- in status, not great with tmux +vim.opt.number = true -- show line number +vim.opt.relativenumber = false vim.opt.showmode = false +vim.opt.signcolumn = 'yes' +vim.opt.cursorline = true +vim.opt.scrolloff = 10 +vim.opt.colorcolumn = '120' +-- vim.opt.breakindent = true -- Sync clipboard between OS and Neovim. --- Schedule the setting after `UiEnter` because it can increase startup-time. --- Remove this option if you want your OS clipboard to remain independent. --- See `:help 'clipboard'` vim.schedule(function() vim.opt.clipboard = 'unnamedplus' end) +vim.opt.mouse = 'nvi' --- Enable break indent -vim.opt.breakindent = true - --- Save undo history +-- File related +vim.opt.autochdir = false +vim.opt.writebackup = false vim.opt.undofile = true +if vim.fn.has 'win32' == 1 or vim.fn.has 'win64' == 1 then + vim.opt.fileformats = 'dos,unix,mac' +elseif vim.fn.has 'mac' == 1 then + vim.opt.fileformats = 'mac,unix,dos' +else + vim.opt.fileformats = 'unix,dos,mac' +end +vim.opt.wildmenu = true +vim.opt.wildmode = 'list:longest,list:full' -- list choices, expand singles +vim.keymap.set('n', 'pv', vim.cmd.Ex, { desc = 'Open explorer [V]' }) --- Case-insensitive searching UNLESS \C or one or more capital letters in the search term +-- Search vim.opt.ignorecase = true vim.opt.smartcase = true +vim.opt.wrapscan = false +vim.opt.inccommand = 'split' -- preview --- Keep signcolumn on by default -vim.opt.signcolumn = 'yes' - --- Decrease update time +-- Performance vim.opt.updatetime = 250 - --- Decrease mapped sequence wait time --- Displays which-key popup sooner vim.opt.timeoutlen = 300 --- Configure how new splits should be opened +-- Windows +-- :sp/:vsp to split windows +-- C-w to jump between them vim.opt.splitright = true vim.opt.splitbelow = true --- Sets how neovim will display certain whitespace characters in the editor. --- See `:help 'list'` --- and `:help 'listchars'` +-- Whitespace vim.opt.list = true vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } --- Preview substitutions live, as you type! -vim.opt.inccommand = 'split' +-- Spelling: "z=" in normal to suggest replacements +vim.opt.spelllang = 'en_us' +vim.opt.spell = true --- Show which line your cursor is on -vim.opt.cursorline = true - --- Minimal number of screen lines to keep above and below the cursor. -vim.opt.scrolloff = 10 - --- [[ Basic Keymaps ]] --- See `:help vim.keymap.set()` - --- Clear highlights on search when pressing in normal mode --- See `:help hlsearch` -vim.keymap.set('n', '', 'nohlsearch') - --- Diagnostic keymaps +-- Diagnostics vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) +vim.keymap.set('n', 'td', function() + vim.diagnostic.enable(not vim.diagnostic.is_enabled()) +end, { silent = true, noremap = true, desc = 'Toggle [D]iagnostics' }) --- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier --- for people to discover. Otherwise, you normally need to press , which --- is not what someone will guess without a bit more experience. --- --- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping --- or just use to exit terminal mode -vim.keymap.set('t', '', '', { desc = 'Exit terminal mode' }) - --- TIP: Disable arrow keys in normal mode --- vim.keymap.set('n', '', 'echo "Use h to move!!"') --- vim.keymap.set('n', '', 'echo "Use l to move!!"') --- vim.keymap.set('n', '', 'echo "Use k to move!!"') --- vim.keymap.set('n', '', 'echo "Use j to move!!"') - --- Keybinds to make split navigation easier. --- Use CTRL+ to switch between windows --- --- See `:help wincmd` for a list of all window commands -vim.keymap.set('n', '', '', { desc = 'Move focus to the left window' }) -vim.keymap.set('n', '', '', { desc = 'Move focus to the right window' }) -vim.keymap.set('n', '', '', { desc = 'Move focus to the lower window' }) -vim.keymap.set('n', '', '', { desc = 'Move focus to the upper window' }) - --- [[ Basic Autocommands ]] --- See `:help lua-guide-autocommands` - --- Highlight when yanking (copying) text --- Try it with `yap` in normal mode --- See `:help vim.highlight.on_yank()` +-- Highlight when yanking (copying) text - "yap" vim.api.nvim_create_autocmd('TextYankPost', { desc = 'Highlight when yanking (copying) text', group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }), @@ -204,8 +74,7 @@ vim.api.nvim_create_autocmd('TextYankPost', { end, }) --- [[ Install `lazy.nvim` plugin manager ]] --- See `:help lazy.nvim.txt` or https://github.com/folke/lazy.nvim for more info +-- Install Lazy from Github local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim' if not vim.uv.fs_stat(lazypath) then local lazyrepo = 'https://github.com/folke/lazy.nvim.git' @@ -216,34 +85,19 @@ if not vim.uv.fs_stat(lazypath) then end ---@diagnostic disable-next-line: undefined-field vim.opt.rtp:prepend(lazypath) --- [[ Configure and install plugins ]] --- --- To check the current status of your plugins, run --- :Lazy --- --- You can press `?` in this menu for help. Use `:q` to close the window --- --- To update plugins you can run --- :Lazy update --- --- NOTE: Here is where you install your plugins. +-- :Lazy require('lazy').setup({ - -- NOTE: Plugins can be added with a link (or for a github repo: 'owner/repo' link). - 'tpope/vim-sleuth', -- Detect tabstop and shiftwidth automatically + -- Detect tabstop and shiftwidth automatically + 'tpope/vim-sleuth', - -- NOTE: Plugins can also be added by using a table, - -- with the first argument being the link and the following - -- keys can be used to configure plugin behavior/loading/etc. - -- - -- Use `opts = {}` to force a plugin to be loaded. - -- + -- Emacs-style keybindings in insert mode + { + 'millerjason/neovimacs.nvim', + opts = {}, + }, - -- Here is a more advanced example where we pass configuration - -- options to `gitsigns.nvim`. This is equivalent to the following Lua: - -- require('gitsigns').setup({ ... }) - -- - -- See `:help gitsigns` to understand what the configuration keys do - { -- Adds git related signs to the gutter, as well as utilities for managing changes + -- Add git changes to gutter + { 'lewis6991/gitsigns.nvim', opts = { signs = { @@ -256,27 +110,12 @@ require('lazy').setup({ }, }, - -- NOTE: Plugins can also be configured to run Lua code when they are loaded. - -- - -- This is often very useful to both group configuration, as well as handle - -- lazy loading plugins that don't need to be loaded immediately at startup. - -- - -- For example, in the following configuration, we use: - -- event = 'VimEnter' - -- - -- which loads which-key before all the UI elements are loaded. Events can be - -- normal autocommands events (`:help autocmd-events`). - -- - -- Then, because we use the `config` key, the configuration only runs - -- after the plugin has been loaded: - -- config = function() ... end - - { -- Useful plugin to show you pending keybinds. + -- Shows keybindings as you go + { 'folke/which-key.nvim', - event = 'VimEnter', -- Sets the loading event to 'VimEnter' - config = function() -- This is the function that runs, AFTER loading + event = 'VimEnter', + config = function() require('which-key').setup() - -- Document existing key chains require('which-key').add { { 'c', group = '[C]ode' }, @@ -290,63 +129,30 @@ require('lazy').setup({ end, }, - -- NOTE: Plugins can specify dependencies. - -- - -- The dependencies are proper plugin specifications as well - anything - -- you do for a plugin at the top level, you can do for a dependency. - -- - -- Use the `dependencies` key to specify the dependencies of a particular plugin - - { -- Fuzzy Finder (files, lsp, etc) + -- Fuzzy finder (file & lsp) + -- :Telescope help_tags + -- See `:help telescope` and `:help telescope.setup()` + -- To see keymaps do this: + -- - Insert mode: + -- - Normal mode: ? + { 'nvim-telescope/telescope.nvim', event = 'VimEnter', branch = '0.1.x', dependencies = { 'nvim-lua/plenary.nvim', - { -- If encountering errors, see telescope-fzf-native README for installation instructions + { 'nvim-telescope/telescope-fzf-native.nvim', - - -- `build` is used to run some command when the plugin is installed/updated. - -- This is only run then, not every time Neovim starts up. build = 'make', - - -- `cond` is a condition used to determine whether this plugin should be - -- installed and loaded. cond = function() return vim.fn.executable 'make' == 1 end, }, { 'nvim-telescope/telescope-ui-select.nvim' }, - - -- Useful for getting pretty icons, but requires a Nerd Font. { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font }, }, config = function() - -- Telescope is a fuzzy finder that comes with a lot of different things that - -- it can fuzzy find! It's more than just a "file finder", it can search - -- many different aspects of Neovim, your workspace, LSP, and more! - -- - -- The easiest way to use Telescope, is to start by doing something like: - -- :Telescope help_tags - -- - -- After running this command, a window will open up and you're able to - -- type in the prompt window. You'll see a list of `help_tags` options and - -- a corresponding preview of the help. - -- - -- Two important keymaps to use while in Telescope are: - -- - Insert mode: - -- - Normal mode: ? - -- - -- This opens a window that shows you all of the keymaps for the current - -- Telescope picker. This is really useful to discover what Telescope can - -- do as well as how to actually do it! - - -- [[ Configure Telescope ]] - -- See `:help telescope` and `:help telescope.setup()` require('telescope').setup { - -- You can put your default mappings / updates / etc. in here - -- All the info you're looking for is in `:help telescope.setup()` - -- -- defaults = { -- mappings = { -- i = { [''] = 'to_fuzzy_refine' }, @@ -375,6 +181,10 @@ require('lazy').setup({ vim.keymap.set('n', 'sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' }) vim.keymap.set('n', 'sr', builtin.resume, { desc = '[S]earch [R]esume' }) vim.keymap.set('n', 's.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' }) + vim.keymap.set('n', 'ff', builtin.find_files, { desc = 'Find [F]iles' }) + vim.keymap.set('n', 'fg', builtin.live_grep, { desc = 'Find [G]rep' }) + vim.keymap.set('n', 'fb', builtin.buffers, { desc = 'Find [B]uffers' }) + vim.keymap.set('n', 'fh', builtin.help_tags, { desc = 'Find [H]elp tags' }) vim.keymap.set('n', '', builtin.buffers, { desc = '[ ] Find existing buffers' }) -- Slightly advanced example of overriding default behavior and theme @@ -394,18 +204,11 @@ require('lazy').setup({ prompt_title = 'Live Grep in Open Files', } end, { desc = '[S]earch [/] in Open Files' }) - - -- Shortcut for searching your Neovim configuration files - vim.keymap.set('n', 'sn', function() - builtin.find_files { cwd = vim.fn.stdpath 'config' } - end, { desc = '[S]earch [N]eovim files' }) end, }, -- LSP Plugins { - -- `lazydev` configures Lua LSP for your Neovim config, runtime and plugins - -- used for completion, annotations and signatures of Neovim apis 'folke/lazydev.nvim', ft = 'lua', opts = { @@ -433,89 +236,24 @@ require('lazy').setup({ 'hrsh7th/cmp-nvim-lsp', }, config = function() - -- Brief aside: **What is LSP?** - -- - -- LSP is an initialism you've probably heard, but might not understand what it is. - -- - -- LSP stands for Language Server Protocol. It's a protocol that helps editors - -- and language tooling communicate in a standardized fashion. - -- - -- In general, you have a "server" which is some tool built to understand a particular - -- language (such as `gopls`, `lua_ls`, `rust_analyzer`, etc.). These Language Servers - -- (sometimes called LSP servers, but that's kind of like ATM Machine) are standalone - -- processes that communicate with some "client" - in this case, Neovim! - -- - -- LSP provides Neovim with features like: - -- - Go to definition - -- - Find references - -- - Autocompletion - -- - Symbol Search - -- - and more! - -- - -- Thus, Language Servers are external tools that must be installed separately from - -- Neovim. This is where `mason` and related plugins come into play. - -- - -- If you're wondering about lsp vs treesitter, you can check out the wonderfully - -- and elegantly composed help section, `:help lsp-vs-treesitter` - - -- This function gets run when an LSP attaches to a particular buffer. - -- That is to say, every time a new file is opened that is associated with - -- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this - -- function will be executed to configure the current buffer vim.api.nvim_create_autocmd('LspAttach', { group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), callback = function(event) - -- NOTE: Remember that Lua is a real programming language, and as such it is possible - -- to define small helper and utility functions so you don't have to repeat yourself. - -- - -- In this case, we create a function that lets us more easily define mappings specific - -- for LSP related items. It sets the mode, buffer and description for us each time. local map = function(keys, func, desc) vim.keymap.set('n', keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc }) end - -- Jump to the definition of the word under your cursor. - -- This is where a variable was first declared, or where a function is defined, etc. - -- To jump back, press . map('gd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') - - -- Find references for the word under your cursor. map('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') - - -- Jump to the implementation of the word under your cursor. - -- Useful when your language has ways of declaring types without an actual implementation. map('gI', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') - - -- Jump to the type of the word under your cursor. - -- Useful when you're not sure what type a variable is and you want to see - -- the definition of its *type*, not where it was *defined*. map('D', require('telescope.builtin').lsp_type_definitions, 'Type [D]efinition') - - -- Fuzzy find all the symbols in your current document. - -- Symbols are things like variables, functions, types, etc. map('ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols') - - -- Fuzzy find all the symbols in your current workspace. - -- Similar to document symbols, except searches over your entire project. map('ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols') - - -- Rename the variable under your cursor. - -- Most Language Servers support renaming across files, etc. map('rn', vim.lsp.buf.rename, '[R]e[n]ame') - - -- Execute a code action, usually your cursor needs to be on top of an error - -- or a suggestion from your LSP for this to activate. map('ca', vim.lsp.buf.code_action, '[C]ode [A]ction') - - -- WARN: This is not Goto Definition, this is Goto Declaration. - -- For example, in C this would take you to the header. map('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') - -- The following two autocommands are used to highlight references of the - -- word under your cursor when your cursor rests there for a little while. - -- See `:help CursorHold` for information about when this is executed - -- - -- When you move your cursor, the highlights will be cleared (the second autocommand). + -- :help CursorHold local client = vim.lsp.get_client_by_id(event.data.client_id) if client and client.supports_method(vim.lsp.protocol.Methods.textDocument_documentHighlight) then local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false }) @@ -540,10 +278,7 @@ require('lazy').setup({ }) end - -- The following code creates a keymap to toggle inlay hints in your - -- code, if the language server you are using supports them - -- - -- This may be unwanted, since they displace some of your code + -- Inlay hints if client and client.supports_method(vim.lsp.protocol.Methods.textDocument_inlayHint) then map('th', function() vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf }) @@ -552,36 +287,16 @@ require('lazy').setup({ end, }) - -- LSP servers and clients are able to communicate to each other what features they support. - -- By default, Neovim doesn't support everything that is in the LSP specification. - -- When you add nvim-cmp, luasnip, etc. Neovim now has *more* capabilities. - -- So, we create new capabilities with nvim cmp, and then broadcast that to the servers. local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities()) - -- Enable the following language servers - -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. - -- - -- Add any additional override configuration in the following tables. Available keys are: - -- - cmd (table): Override the default command used to start the server - -- - filetypes (table): Override the default list of associated filetypes for the server - -- - capabilities (table): Override fields in capabilities. Can be used to disable certain LSP features. - -- - settings (table): Override the default settings passed when initializing the server. - -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/ local servers = { - -- clangd = {}, - -- gopls = {}, - -- pyright = {}, + clangd = {}, + pyright = {}, + black = {}, + isort = {}, + taplo = {}, -- rust_analyzer = {}, - -- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs - -- - -- Some languages (like typescript) have entire language plugins that can be useful: - -- https://github.com/pmizio/typescript-tools.nvim - -- - -- But for many setups, the LSP (`tsserver`) will work just fine - -- tsserver = {}, - -- - lua_ls = { -- cmd = {...}, -- filetypes = { ...}, @@ -591,19 +306,13 @@ require('lazy').setup({ completion = { callSnippet = 'Replace', }, - -- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings - -- diagnostics = { disable = { 'missing-fields' } }, }, }, }, } -- Ensure the servers and tools above are installed - -- To check the current status of installed tools and/or manually install - -- other tools, you can run - -- :Mason - -- - -- You can press `g?` for help in this menu. + -- :Mason require('mason').setup() -- You can add other tools here that you want Mason to install @@ -618,9 +327,6 @@ require('lazy').setup({ handlers = { function(server_name) local server = servers[server_name] or {} - -- This handles overriding only values explicitly passed - -- by the server configuration above. Useful when disabling - -- certain features of an LSP (for example, turning off formatting for tsserver) server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) require('lspconfig')[server_name].setup(server) end, @@ -629,7 +335,8 @@ require('lazy').setup({ end, }, - { -- Autoformat + -- Auto-format + { 'stevearc/conform.nvim', event = { 'BufWritePre' }, cmd = { 'ConformInfo' }, @@ -657,26 +364,24 @@ require('lazy').setup({ end, formatters_by_ft = { lua = { 'stylua' }, - -- Conform can also run multiple formatters sequentially - -- python = { "isort", "black" }, - -- - -- You can use 'stop_after_first' to run the first available formatter from the list - -- javascript = { "prettierd", "prettier", stop_after_first = true }, + python = { 'pyright', 'isort', 'black' }, + md = { 'prettier' }, }, }, }, - { -- Autocompletion + -- Venv selector + -- WIP: https://github.com/linux-cultist/venv-selector.nvim/tree/regexp + -- Wait for a updated release + + -- Auto-completion + { 'hrsh7th/nvim-cmp', event = 'InsertEnter', dependencies = { - -- Snippet Engine & its associated nvim-cmp source { 'L3MON4D3/LuaSnip', build = (function() - -- Build Step is needed for regex support in snippets. - -- This step is not supported in many windows environments. - -- Remove the below condition to re-enable on windows. if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then return end @@ -696,9 +401,7 @@ require('lazy').setup({ }, 'saadparwaiz1/cmp_luasnip', - -- Adds other completion capabilities. - -- nvim-cmp does not ship with all sources by default. They are split - -- into multiple repos for maintenance purposes. + -- Other completions 'hrsh7th/cmp-nvim-lsp', 'hrsh7th/cmp-path', }, @@ -714,59 +417,31 @@ require('lazy').setup({ luasnip.lsp_expand(args.body) end, }, - completion = { completeopt = 'menu,menuone,noinsert' }, - - -- For an understanding of why these mappings were - -- chosen, you will need to read `:help ins-completion` - -- - -- No, but seriously. Please read `:help ins-completion`, it is really good! + completion = { + autocomplete = false, -- Use C-Space + completeopt = 'menu,menuone,noinsert', + }, + -- `:help ins-completion` mapping = cmp.mapping.preset.insert { - -- Select the [n]ext item - [''] = cmp.mapping.select_next_item(), - -- Select the [p]revious item - [''] = cmp.mapping.select_prev_item(), - - -- Scroll the documentation window [b]ack / [f]orward - [''] = cmp.mapping.scroll_docs(-4), - [''] = cmp.mapping.scroll_docs(4), - - -- Accept ([y]es) the completion. - -- This will auto-import if your LSP supports it. - -- This will expand snippets if the LSP sent a snippet. - [''] = cmp.mapping.confirm { select = true }, - - -- If you prefer more traditional completion keymaps, - -- you can uncomment the following lines - --[''] = cmp.mapping.confirm { select = true }, - --[''] = cmp.mapping.select_next_item(), - --[''] = cmp.mapping.select_prev_item(), - - -- Manually trigger a completion from nvim-cmp. - -- Generally you don't need this, because nvim-cmp will display - -- completions whenever it has completion options available. - [''] = cmp.mapping.complete {}, - - -- Think of as moving to the right of your snippet expansion. - -- So if you have a snippet that's like: - -- function $name($args) - -- $body - -- end - -- - -- will move you to the right of each of the expansion locations. - -- is similar, except moving you backwards. - [''] = cmp.mapping(function() + [''] = cmp.mapping.select_next_item(), + [''] = cmp.mapping.select_prev_item(), + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.confirm { select = true }, + [''] = cmp.mapping.abort(), + [''] = cmp.mapping.complete {}, + [''] = cmp.mapping(function() if luasnip.expand_or_locally_jumpable() then luasnip.expand_or_jump() end end, { 'i', 's' }), - [''] = cmp.mapping(function() + [''] = cmp.mapping(function() if luasnip.locally_jumpable(-1) then luasnip.jump(-1) end end, { 'i', 's' }), - - -- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see: - -- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps + [''] = cmp.config.disable, + [''] = cmp.config.disable, }, sources = { { @@ -782,28 +457,21 @@ require('lazy').setup({ end, }, - { -- You can easily change to a different colorscheme. - -- Change the name of the colorscheme plugin below, and then - -- change the command in the config to whatever the name of that colorscheme is. - -- - -- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`. + -- Color scheme + { 'folke/tokyonight.nvim', priority = 1000, -- Make sure to load this before all the other start plugins. init = function() - -- Load the colorscheme here. - -- Like many other themes, this one has different styles, and you could load - -- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'. vim.cmd.colorscheme 'tokyonight-night' - - -- You can configure highlights by doing something like: - vim.cmd.hi 'Comment gui=none' + -- vim.cmd.hi 'Comment gui=none' end, }, -- Highlight todo, notes, etc in comments { 'folke/todo-comments.nvim', event = 'VimEnter', dependencies = { 'nvim-lua/plenary.nvim' }, opts = { signs = false } }, - { -- Collection of various small independent plugins/modules + -- Small plugings + { 'echasnovski/mini.nvim', config = function() -- Better Around/Inside textobjects @@ -821,78 +489,73 @@ require('lazy').setup({ -- - sr)' - [S]urround [R]eplace [)] ['] require('mini.surround').setup() - -- Simple and easy statusline. - -- You could remove this setup call if you don't like it, - -- and try some other statusline plugin local statusline = require 'mini.statusline' - -- set use_icons to true if you have a Nerd Font statusline.setup { use_icons = vim.g.have_nerd_font } - - -- You can configure sections in the statusline by overriding their - -- default behavior. For example, here we set the section for - -- cursor location to LINE:COLUMN ---@diagnostic disable-next-line: duplicate-set-field statusline.section_location = function() return '%2l:%-2v' end - - -- ... and there is more! - -- Check out: https://github.com/echasnovski/mini.nvim end, }, - { -- Highlight, edit, and navigate code + + -- Treesitter navigation + -- :help nvim-treesitter + { 'nvim-treesitter/nvim-treesitter', build = ':TSUpdate', opts = { - ensure_installed = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' }, - -- Autoinstall languages that are not installed + ensure_installed = { + 'bash', + 'c', + 'cmake', + 'cpp', + 'css', + 'cuda', + 'diff', + 'dockerfile', + 'dot', + 'go', + 'gomod', + 'html', + 'java', + 'javascript', + 'json', + 'json5', + 'latex', + 'llvm', + 'lua', + 'luadoc', + 'make', + 'markdown', + 'markdown_inline', + 'nix', + 'python', + 'query', + 'rst', + 'toml', + 'vim', + 'vimdoc', + 'yaml', + }, auto_install = true, highlight = { enable = true, - -- Some languages depend on vim's regex highlighting system (such as Ruby) for indent rules. - -- If you are experiencing weird indenting issues, add the language to - -- the list of additional_vim_regex_highlighting and disabled languages for indent. additional_vim_regex_highlighting = { 'ruby' }, }, indent = { enable = true, disable = { 'ruby' } }, }, config = function(_, opts) - -- [[ Configure Treesitter ]] See `:help nvim-treesitter` - ---@diagnostic disable-next-line: missing-fields require('nvim-treesitter.configs').setup(opts) - - -- There are additional nvim-treesitter modules that you can use to interact - -- with nvim-treesitter. You should go explore a few and see what interests you: - -- - -- - Incremental selection: Included, see `:help nvim-treesitter-incremental-selection-mod` - -- - Show your current context: https://github.com/nvim-treesitter/nvim-treesitter-context - -- - Treesitter + textobjects: https://github.com/nvim-treesitter/nvim-treesitter-textobjects end, }, - -- The following two comments only work if you have downloaded the kickstart repo, not just copy pasted the - -- init.lua. If you want these files, they are in the repository, so you can just download them and - -- place them in the correct locations. - - -- NOTE: Next step on your Neovim journey: Add/Configure additional plugins for Kickstart - -- - -- Here are some example plugins that I've included in the Kickstart repository. - -- Uncomment any of the lines below to enable them (you will need to restart nvim). - -- -- require 'kickstart.plugins.debug', -- require 'kickstart.plugins.indent_line', -- require 'kickstart.plugins.lint', -- require 'kickstart.plugins.autopairs', -- require 'kickstart.plugins.neo-tree', -- require 'kickstart.plugins.gitsigns', -- adds gitsigns recommend keymaps - - -- NOTE: The import below can automatically add your own plugins, configuration, etc from `lua/custom/plugins/*.lua` - -- This is the easiest way to modularize your config. - -- - -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. - -- For additional information, see `:help lazy.nvim-lazy.nvim-structuring-your-plugins` - -- { import = 'custom.plugins' }, }, { ui = { -- If you are using a Nerd Font: set icons to an empty table which will use the @@ -915,5 +578,82 @@ require('lazy').setup({ }, }) --- The line beneath this is called `modeline`. See `:help modeline` --- vim: ts=2 sts=2 sw=2 et +-- Function to center current line vertically +--- C-l will recenter as well as refresh +local function recenter_vertically() + local current_line = vim.fn.line '.' + local window_height = vim.api.nvim_win_get_height(0) + + -- Calculate the ideal scroll position + local scroll_offset = math.floor(window_height / 2) + local target_top_line = math.max(1, current_line - scroll_offset) + + -- Set the window view + vim.api.nvim_win_set_cursor(0, { current_line, 0 }) + vim.fn.winrestview { topline = target_top_line } +end +local function recenter_and_refresh() + vim.cmd 'redraw!' + recenter_vertically() +end +vim.keymap.set('n', '', recenter_and_refresh, { noremap = true, silent = true }) +vim.keymap.set('i', '', recenter_and_refresh, { noremap = true, silent = true }) +vim.keymap.set('c', '', 'n', { expr = true }) + +--- (Re)Undefine undesirable behavior +vim.api.nvim_set_keymap('i', '', '', { noremap = true }) +vim.api.nvim_set_keymap('n', '', '', { noremap = true }) +vim.api.nvim_set_keymap('n', '', '', { noremap = true }) + +-- Terminals/Shell +-- :terminal + +-- Arrows keys for wildmenu +vim.keymap.set('c', '', 'pumvisible() ? "" : ""', { expr = true, noremap = true }) +vim.keymap.set('c', '', 'pumvisible() ? "" : ""', { expr = true, noremap = true }) +vim.keymap.set('c', '', 'pumvisible() ? "" : ""', { expr = true, noremap = true }) +vim.keymap.set('c', '', 'pumvisible() ? "" : ""', { expr = true, noremap = true }) +-- vim.opt.wildcharm = '' -- set wildcharm= + +-- LSP in insert mode +vim.lsp.handlers['textDocument/publishDiagnostics'] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { + update_in_insert = false, +}) + +-- Tab management keys +-- F1-Prev, F2-Next, F3-New, F4-Close +-- +local function safe_tabclose() + local bufnr = vim.api.nvim_get_current_buf() + local buf_windows = vim.call('win_findbuf', bufnr) + local modified = vim.api.nvim_get_option_value('modified', { buf = bufnr }) + + if vim.fn.tabpagenr '$' == 1 then + -- last tab, no-op + return + elseif modified and #buf_windows == 1 then + vim.ui.input({ + prompt = 'Buffer modified, are you sure? ', + }, function(input) + if input == 'y' then + vim.cmd 'tabclose' + end + end) + else + vim.cmd 'tabclose' + end +end +vim.keymap.set('n', '', vim.cmd.tabp, { noremap = true, silent = true }) +vim.keymap.set('n', '', vim.cmd.tabn, { noremap = true, silent = true }) +vim.keymap.set('n', '', ':tabnew', { noremap = true, silent = true }) +vim.keymap.set('n', '', ':tabnew', { noremap = true, silent = true }) +vim.keymap.set('n', '', safe_tabclose, { noremap = true, silent = true }) +vim.keymap.set('i', '', vim.cmd.tabp, { noremap = true, silent = true }) +vim.keymap.set('i', '', vim.cmd.tabn, { noremap = true, silent = true }) +vim.keymap.set('i', '', ':tabnew', { noremap = true, silent = true }) +vim.keymap.set('i', '', ':tabnew', { noremap = true, silent = true }) +vim.keymap.set('i', '', safe_tabclose, { noremap = true, silent = true }) +vim.keymap.set('n', 'tp', vim.cmd.tabn, { desc = 'Tab [p]revious' }) +vim.keymap.set('n', 'tn', vim.cmd.tabp, { desc = 'Tab [n]ext' }) +vim.keymap.set('n', 'to', vim.cmd.tabnew, { desc = 'Tab [o]pen' }) +vim.keymap.set('n', 'tc', safe_tabclose, { desc = 'Tab [c]lose' })