NVIM LUAU

Awesome plugins for Neovim

GitHubAdd Plugin

    Tabline

  • akinsho/bufferline.nvim
    944

    A snazzy bufferline for Neovim

  • crispgm/nvim-tabline
    19

    nvim port of tabline.vim with Lua

  • koenverburg/minimal-tabline.nvim
    2

    A minimal tabline, that's it

  • nanozuki/tabby.nvim
    381

    A declarative, highly configurable, and neovim style tabline plugin. Use your nvim tabs as a workspace multiplexer!

  • noib3/nvim-cokeline
    169

    :nose: A Neovim bufferline for people with addictive personalities

  • romgrk/barbar.nvim
    899

    The neovim tabline plugin.

  • Status Line

  • alvarosevilla95/luatab.nvim
    109

    Tabline lua plugin for neovim

  • b0o/incline.nvim
    105

    ๐ŸŽˆ Floating statuslines for Neovim

  • datwaft/bubbly.nvim
    167

    Bubbly statusline for neovim

  • feline-nvim/feline.nvim
    564

    A minimal, stylish and customizable statusline for Neovim written in Lua

  • konapun/vacuumline.nvim
    17

    A prebuilt configuration for galaxyline inspired by airline

  • NTBBloodbath/galaxyline.nvim
    118

    neovim statusline plugin written in lua

  • nvim-lualine/lualine.nvim
    1434

    A blazing fast and easy to configure neovim statusline plugin written in pure lua.

  • rebelot/heirline.nvim
    208

    Heirline.nvim is a no-nonsense Neovim Statusline plugin designed around recursive inheritance to be exceptionally fast and versatile.

  • tamton-aquib/staline.nvim
    138

    A modern lightweight statusline and bufferline for neovim in lua. Mainly uses unicode symbols for showing info.

  • windwp/windline.nvim
    280

    Animation statusline, floating window statusline. Use lua + luv make some wind

  • Keybinding

  • b0o/mapx.nvim
    141

    ๐Ÿ—บ A better way to create key mappings in Neovim.

  • folke/which-key.nvim
    1189

    ๐Ÿ’ฅ Create key bindings that stick. WhichKey is a lua plugin for Neovim 0.5 that displays a popup with possible keybindings of the command you started typing.

  • mrjones2014/legendary.nvim
    210

    ๐Ÿ—บ๏ธ A legend for your keymaps, commands, and autocmds, with which-key.nvim integration (requires Neovim nightly)

  • simrat39/rust-tools.nvim
    684

    Tools for better development in rust using neovim's builtin lsp

  • LSP

  • b0o/SchemaStore.nvim
    159

    ๐Ÿ› JSON schemas for Neovim

  • folke/trouble.nvim
    1388

    ๐Ÿšฆ A pretty diagnostics, references, telescope results, quickfix and location list to help you solve all the trouble your code is causing.

  • jose-elias-alvarez/nvim-lsp-ts-utils
    373

    Utilities to improve the TypeScript development experience for Neovim's built-in LSP client.

  • neovim/nvim-lspconfig
    3936

    Quickstart configurations for the Nvim LSP client

  • nvim-lua/lsp_extensions.nvim
    193

    Repo to hold a bunch of info & extension callbacks for built-in LSP. Use at your own risk :wink:

  • nvim-lua/lsp-status.nvim
    426

    Utility functions for getting diagnostic status and progress messages from LSP servers, for use in the Neovim statusline

  • ray-x/navigator.lua
    572

    Navigate codes like a breeze๐ŸŽ. Exploring LSP and ๐ŸŒฒTreesitter symbols a piece of ๐Ÿฐ. Take control like a boss ๐Ÿฆ.

  • williamboman/nvim-lsp-installer
    1157

    Neovim plugin that allows you to seamlessly manage LSP servers with :LspInstall. With full Windows support!

  • Guides

  • bennypowers/nvim-regexplainer
    183

    Describe the regexp under the cursor

  • nvim-lua/kickstart.nvim
    2356

    A launch point for your personal nvim configuration

  • Colorschemes

  • catppuccin/nvim
    546

    ๐Ÿจ Soothing pastel theme for NeoVim

  • dharmx/nvim-colo
    26

    Theming utlilities for neovim. This is very experimental at the moment.

  • ful1e5/onedark.nvim
    174

    Atom's iconic One Dark theme for Neovim, written in Lua

  • HUAHUAI23/nvim-quietlight
    0

    A theme for Neovim with support for LSP, Treesitter, and more.

  • kvrohit/substrata.nvim
    56

    A cold, dark color scheme for Neovim

  • lalitmee/cobalt2.nvim
    7

    cobalt2 theme for neovim in Lua using colorbuddy

  • luisiacc/gruvbox-baby
    42

    Gruvbox theme for neovim with full ๐ŸŽ„TreeSitter support.

  • mhartington/oceanic-next
    986

    Oceanic Next theme for neovim

  • Mofiqul/adwaita.nvim
    38

    Neovim colorscheme using Gnome Adwaita syntax

  • Mofiqul/dracula.nvim
    123

    Dracula colorscheme for neovim written in Lua

  • mrjones2014/lighthaus.nvim
    40

    A Lua implementation of lighthaus-theme/vim-lighthaus

  • navarasu/onedark.nvim
    270

    One dark and light colorscheme for neovim >= 0.5.0 written in lua based on Atom's One Dark and Light theme. Additionally, it comes with 5 color variant styles

  • NTBBloodbath/doom-one.nvim
    74

    doom-emacs' doom-one Lua port for Neovim

  • rebelot/kanagawa.nvim
    738

    NeoVim dark colorscheme inspired by the colors of the famous painting by Katsushika Hokusai.

  • rose-pine/neovim
    310

    Soho vibes for Neovim

  • RRethy/nvim-base16
    301

    Neovim plugin for building a sync base16 colorscheme. Includes support for Treesitter and LSP highlight groups.

  • sunjon/Shade.nvim
    374

    An Nvim lua plugin that dims your inactive windows

  • themercorp/themer.lua
    130

    A simple, minimal highlighter plugin for neovim

  • zanglg/nova.nvim
    82

    Another color scheme for neovim written in lua, WIP

  • Comment

  • danymat/neogen
    373

    A better annotation generator. Supports multiple languages and annotation conventions.

  • Utility

  • echasnovski/mini.nvim
    405

    Neovim plugin with collection of minimal, independent, and fast Lua modules dedicated to improve Neovim (version 0.5 and higher) experience

  • hood/popui.nvim
    42

    NeoVim UI sweetness powered by popfix.

  • meznaric/conmenu
    21

  • mrjones2014/dash.nvim
    132

    ๐Ÿƒ๐Ÿ’จ Search Dash.app from your Neovim fuzzy finder. Built with Rust ๐Ÿฆ€ and Lua

  • Cursor Line

  • edluffy/specs.nvim
    233

    ๐Ÿ‘“ A fast and lightweight Neovim lua plugin to keep an eye on where your cursor has jumped.

  • mg979/vim-visual-multi
    2046

    Multiple cursors plugin for vim/neovim

  • Code Runner

  • FeiyouG/command_center.nvim
    57

    Create and manage keybindings and commands in a more organized manner, and search them quickly through Telescope

  • Extras

  • folke/zen-mode.nvim
    377

    ๐Ÿง˜ Distraction-free coding for Neovim

  • goolord/alpha-nvim
    322

    a lua powered greeter like vim-startify / dashboard-nvim

  • Start Up

  • henriquehbr/nvim-startup.lua
    45

    Displays neovim startup time

  • lewis6991/impatient.nvim
    563

    Improve startup time for Neovim

  • Session

  • HUAHUAI23/telescope-session.nvim
    12

    manage your vim session with telescope ๐Ÿ”ญ

  • Fuzzy Finder

  • ibhagwan/fzf-lua
    418

    Improved fzf.vim written in lua

  • nvim-telescope/telescope.nvim
    5023

    Find, Filter, Preview, Pick. All lua, all the time.

  • vijaymarupudi/nvim-fzf
    223

    A Lua API for using fzf in neovim.

  • Misc

  • iggredible/Learn-Vim
    9061

    Learning Vim and Vimscript doesn't have to be hard. This is the guide that you're looking for ๐Ÿ“–

  • m-demare/attempt.nvim
    53

    Manage temporary buffers

  • SmiteshP/nvim-gps
    348

    Simple statusline component that shows what scope you are working inside

  • windwp/nvim-autopairs
    1479

    autopairs for neovim written by lua

  • zegervdv/nrpattern.nvim
    43

    Neovim plugin to expand incrementing/decrementing to more formats.

  • Note Taking

  • jakewvincent/mkdnflow.nvim
    97

    Tools for markdown notebook navigation and management

  • nvim-neorg/neorg
    2078

    Modernity meets insane extensibility. The future of organizing your life in Neovim.

  • Motion

  • jinh0/eyeliner.nvim
    170

    ๐Ÿ‘€ Move faster with unique f/F indicators.

  • Terminal Integration

  • jlesquembre/nterm.nvim
    35

    neovim plugin to interact with the terminal

  • Scrolling

  • karb94/neoscroll.nvim
    765

    Smooth scrolling neovim plugin written in lua

  • Git

  • kdheepak/lazygit.nvim
    313

    Plugin for calling lazygit from within neovim.

  • zegervdv/settle.nvim
    0

    Settle your merge conflicts from Neovim

  • File Explorer

  • kevinhwang91/rnvimr
    451

    Make Ranger running in a floating window to communicate with Neovim via RPC

  • kyazdani42/nvim-tree.lua
    2040

    A file explorer tree for neovim written in lua

  • Snippets

  • L3MON4D3/LuaSnip
    692

    Snippet Engine for Neovim written in Lua.

  • Browser Integration

  • lalitmee/browse.nvim
    0

    browse for anything using your choice of method

  • Indent

  • lukas-reineke/indent-blankline.nvim
    1272

    Indent guides for Neovim

  • Formatting

  • lukas-reineke/lsp-format.nvim
    248

    A wrapper around Neovims native LSP formatting.

  • Syntax

  • m-demare/hlargs.nvim/
    30

    Highlight arguments' definitions and usages, using Treesitter

  • Splits and Window

  • mrjones2014/smart-splits.nvim
    83

    ๐Ÿง  Smart, directional Neovim split resizing and navigation. Think about resizing splits in terms of "move the divider to the left/right/up/down".

  • Completion

  • noib3/nvim-compleet
    413

    :zap: An async autocompletion framework for Neovim

  • zbirenbaum/copilot-cmp
    69

    Lua plugin to turn github copilot into a cmp source

  • zbirenbaum/copilot.lua
    100

    Lua plugin for starting and interacting with github copilot

  • Package Managers

  • NTBBloodbath/cheovim
    145

    Neovim configuration switcher written in Lua. Inspired by chemacs.

  • savq/paq-nvim
    408

    ๐ŸŒš Neovim package manager

  • wbthomason/packer.nvim
    2321

    A use-package inspired plugin manager for Neovim. Uses native packages, supports Luarocks dependencies, written in Lua, allows for expressive config

  • Game

  • ThePrimeagen/vim-be-good
    619

    vim-be-good is a nvim plugin designed to make you better at Vim Movements.

https://github.com/ray-x/navigator.lua

Navigator

  • Source code analysis and navigate tool

  • Easy code navigation, view diagnostic errors, see relationships of functions, variables

  • A plugin combines the power of LSP and ๐ŸŒฒ๐Ÿก Treesitter together. Not only provids a better highlight but also help you analyse symbol context effectively.

  • ctags fuzzy search & build ctags symbols

a short intro of navigator

Here are some examples:

Example: Javascript closure

The following screenshot shows javascript call tree ๐ŸŒฒ of variable browser insides a closure. This feature is similar to incoming & outgoing calls from LSP. It is designed for the symbol analysis.

navigator

Explanation:

  • The first line of floating windows shows there are 3 references for the symbol browser in closure.js
  • The first reference of browser is an assignment, an emoji ๐Ÿ“ indicates the value is changed in this line. In many cases, we search for references to find out when the value changed.
  • The second reference of browser is inside function displayName and displayName sit inside makeFunc, So you will see displayName{} <- makeFunc{}
  • The third similar to the second, as var browser is on the right side of '=', the value not changed in this line and emoji is not shown.

Example: C++ definition

C++ example: search reference and definition cpp_ref You may find a ๐Ÿฆ• dinosaur(d) on the line of Rectangle rect, which means there is a definition (d for def) of rect in this line.

<- f main() means the definition is inside function main().

Golang struct type

Struct type references in multiple Go ๏ณ‘ files

go_reference

This feature can provide you info in which function/class/method the variable was referenced. It is handy for a large project where class/function definition is too long to fit into the preview window. Also provides a bird's eye view of where the variable is:

  • Referenced
  • Modified
  • Defined
  • Called

Features

  • LSP easy setup. Support the most commonly used lsp clients setup. Dynamic lsp activation based on buffer type. This also enables you to handle workspace with mixed types of codes (e.g. Go + javascript + yml). A better LSP default enables

    • autocompletion *(e.g. nvim-cmp),
    • codelens
    • lsp folding
    • go implementation
    • incoming/outgoing call and ccls call hierarchy
    • range formatting
  • Out of box experience. 10 lines of minimum init.lua can turn your neovim into a full-featured LSP & Treesitter powered IDE

  • Lazy loading friendly.

  • UI with floating windows, navigator provides a visual way to manage and navigate through symbols, diagnostic errors, reference etc. It covers all features(handler) provided by LSP from commonly used search reference, to less commonly used search for interface implementation.

  • Code Action GUI

  • Luv async thread and tasks

  • Edit your code in preview window

  • Async request with lsp.buf_request for reference search

  • Treesitter symbol search. It is handy for large files (Some of LSP e.g. lua_ls, there is a 100kb file size limitation?). Also as LSP trying to hide details behind, Treesitter allows you to access all AST semantics.

  • FZY search with either native C (if gcc installed) or Lua-JIT

  • LSP multiple symbols highlight/marker and hop between document references

  • Preview definination/references

  • Better navigation for diagnostic errors, Navigate through all files/buffers that contain errors/warnings

  • Grouping references/implementation/incoming/outgoing based on file names.

  • Treesitter based variable/function context analysis. It is 10x times faster compared to purely rely on LSP. In most of the case, it takes treesitter less than 4 ms to read and render all nodes for a file of 1,000 LOC.

  • The first plugin, IMO, allows you to search in all treesitter symbols in the workspace.

  • Nerdfont, emoji for LSP and treesitter kind

  • Optimize display (remove trailing bracket/space), display the caller of reference, de-duplicate lsp results (e.g reference in the same line). Using treesitter for file preview highlighter etc

  • ccls call hierarchy (Non-standard ccls/call API) supports

  • Syntax folding based on treesitter or LSP_fold folding algorithm. (It behaves similar to vs-code); dedicated comment folding.

  • Treesitter symbols sidebar, LSP document symbole sidebar. Both with preview and folding

  • Calltree: Display and expand Lsp incoming/outgoing calls hierarchy-tree with sidebar

  • Fully support LSP CodeAction, CodeLens, CodeLens action. Help you improve code quality.

  • LRU cache for treesitter nodes

  • Lazy loader friendly

  • Multigrid support (different font and detachable)

  • Side panel (sidebar) and floating windows

Why a new plugin

I'd like to go beyond what the system is offering.

Similar projects / special mentions

  • nvim-lsputils
  • nvim-fzy
  • fuzzy
  • lspsaga
  • fzf-lsp lsp with fzf as gui backend
  • nvim-treesitter-textobjects
  • inc-rename.nvim

Install

Require nvim-0.6.1 or above, nightly (0.8) prefered

You can remove your lspconfig setup and use this plugin. The plugin depends on lspconfig and guihua.lua, which provides GUI and fzy support(migrate from romgrk's project).

Plug 'neovim/nvim-lspconfig'
Plug 'ray-x/guihua.lua', {'do': 'cd lua/fzy && make' }
Plug 'ray-x/navigator.lua'

Note: Highly recommend: 'nvim-treesitter/nvim-treesitter'

Packer

use({
    'ray-x/navigator.lua',
    requires = {
        { 'ray-x/guihua.lua', run = 'cd lua/fzy && make' },
        { 'neovim/nvim-lspconfig' },
    },
})

Setup

Easy setup BOTH lspconfig and navigator with one liner. Navigator covers around 20 most used LSP setup.

lua require'navigator'.setup()

Sample vimrc turning your neovim into a full-featured IDE

call plug#begin('~/.vim/plugged')

Plug 'neovim/nvim-lspconfig'
Plug 'ray-x/guihua.lua', {'do': 'cd lua/fzy && make' }
Plug 'ray-x/navigator.lua'

" Plug 'hrsh7th/nvim-cmp' and other plugins you commenly use...

" optional, if you need treesitter symbol support
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}

call plug#end()

" No need for require('lspconfig'), navigator will configure it for you
lua <<EOF
require'navigator'.setup()
EOF

You can remove your lspconfig.lua and use the hooks of navigator.lua. As the navigator will bind keys and handler for you. The LSP will be loaded lazily based on filetype.

A treesitter only mode. In some cases LSP is buggy or not available, you can also use treesitter standalone

call plug#begin('~/.vim/plugged')

Plug 'ray-x/guihua.lua', {'do': 'cd lua/fzy && make' }
Plug 'ray-x/navigator.lua'

" Plug 'hrsh7th/nvim-compe' and other plugins you commenly use...

" optional, if you need treesitter symbol support
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
" optional:
Plug 'nvim-treesitter/nvim-treesitter-refactor' " this provides "go to def" etc

call plug#end()

lua <<EOF
require'navigator'.setup()
EOF

Work with nvim-cmp and nvim-autopairs

The buffer type of navigator floating windows is guihua I would suggest disable guihua for autocomplete. e.g.

require('nvim-autopairs').setup{
disable_filetype = { "TelescopePrompt" , "guihua", "guihua_rust", "clap_input" },

if vim.o.ft == 'clap_input' and vim.o.ft == 'guihua' and vim.o.ft == 'guihua_rust' then
  require'cmp'.setup.buffer { completion = {enable = false} }
end

-- or with autocmd
vim.cmd("autocmd FileType guihua lua require('cmp').setup.buffer { enabled = false }")
vim.cmd("autocmd FileType guihua_rust lua require('cmp').setup.buffer { enabled = false }")

...
}

All configure options

Nondefault configuration example:


require'navigator'.setup({
  debug = false, -- log output, set to true and log path: ~/.cache/nvim/gh.log
  width = 0.75, -- max width ratio (number of cols for the floating window) / (window width)
  height = 0.3, -- max list window height, 0.3 by default
  preview_height = 0.35, -- max height of preview windows
  border = {"โ•ญ", "โ”€", "โ•ฎ", "โ”‚", "โ•ฏ", "โ”€", "โ•ฐ", "โ”‚"}, -- border style, can be one of 'none', 'single', 'double',
                                                     -- 'shadow', or a list of chars which defines the border
  on_attach = function(client, bufnr)
    -- your hook
  end,
  -- put a on_attach of your own here, e.g
  -- function(client, bufnr)
  --   -- the on_attach will be called at end of navigator on_attach
  -- end,
  -- The attach code will apply to all LSP clients

  ts_fold = false,  -- modified version of treesitter folding
  default_mapping = true,  -- set to false if you will remap every key or if you using old version of nvim-
  keymaps = {{key = "gK", func = vim.lsp.declaration, desc = 'declaration'}}, -- a list of key maps
  -- this kepmap gK will override "gD" mapping function declaration()  in default kepmap
  -- please check mapping.lua for all keymaps
  treesitter_analysis = true, -- treesitter variable context
  treesitter_navigation = true, -- bool|table false: use lsp to navigate between symbol ']r/[r', table: a list of
  --lang using TS navigation
  treesitter_analysis_max_num = 100, -- how many items to run treesitter analysis
  treesitter_analysis_condense = true, -- condense form for treesitter analysis
  -- this value prevent slow in large projects, e.g. found 100000 reference in a project
  transparency = 50, -- 0 ~ 100 blur the main window, 100: fully transparent, 0: opaque,  set to nil or 100 to disable it

  lsp_signature_help = true, -- if you would like to hook ray-x/lsp_signature plugin in navigator
  -- setup here. if it is nil, navigator will not init signature help
  signature_help_cfg = nil, -- if you would like to init ray-x/lsp_signature plugin in navigator, and pass in your own config to signature help
  icons = {
    -- Code action
    code_action_icon = "๐Ÿ", -- note: need terminal support, for those not support unicode, might crash
    -- Diagnostics
    diagnostic_head = '๐Ÿ›',
    diagnostic_head_severity_1 = "๐Ÿˆฒ",
    -- refer to lua/navigator.lua for more icons setups
  },
  mason = false, -- set to true if you would like use the lsp installed by williamboman/mason
  lsp = {
    enable = true,  -- skip lsp setup, and only use treesitter in navigator. 
                    -- Use this if you are not using LSP servers, and only want to enable treesitter support. 
                    -- If you only want to prevent navigator from touching your LSP server configs, 
                    -- use `disable_lsp = "all"` instead. 
                    -- If disabled, make sure add require('navigator.lspclient.mapping').setup({bufnr=bufnr, client=client}) in your
                    -- own on_attach
    code_action = {enable = true, sign = true, sign_priority = 40, virtual_text = true},
    code_lens_action = {enable = true, sign = true, sign_priority = 40, virtual_text = true},
    document_highlight = true, -- LSP reference highlight, 
                               -- it might already supported by you setup, e.g. LunarVim
    format_on_save = true, -- {true|false} set to false to disasble lsp code format on save (if you are using prettier/efm/formater etc)
                           -- table: {enable = {'lua', 'go'}, disable = {'javascript', 'typescript'}} to enable/disable specific language
                              -- enable: a whitelist of language that will be formatted on save
                              -- disable: a blacklist of language that will not be formatted on save
                           -- function: function(bufnr) return true end to enable/disable lsp format on save
    format_options = {async=false}, -- async: disable by default, the option used in vim.lsp.buf.format({async={true|false}, name = 'xxx'})
    disable_format_cap = {"sqlls", "lua_ls", "gopls"},  -- a list of lsp disable format capacity (e.g. if you using efm or vim-codeformat etc), empty {} by default
                                                            -- If you using null-ls and want null-ls format your code
                                                            -- you should disable all other lsp and allow only null-ls.
    -- disable_lsp = {'pylsd', 'sqlls'},  -- prevents navigator from setting up this list of servers. 
                                          -- if you use your own LSP setup, and don't want navigator to setup 
                                          -- any LSP server for you, use `disable_lsp = "all"`.
                                          -- you may need to add this to your own on_attach hook: 
                                          -- require('navigator.lspclient.mapping').setup({bufnr=bufnr, client=client})
                                          -- for e.g. denols and tsserver you may want to enable one lsp server at a time.
                                          -- default value: {}
    diagnostic = {
      underline = true,
      virtual_text = true, -- show virtual for diagnostic message
      update_in_insert = false, -- update diagnostic message in insert mode
    },

    hover = {
      enable = true,
      keymap = {
        ['<C-k>'] = {
          go = function()
            local w = vim.fn.expand('<cWORD>')
            vim.cmd('GoDoc ' .. w)
          end,
          default = function(
            local w = vim.fn.expand('<cWORD>')
            vim.lsp.buf.workspace_symbol(w)
          end,
        },
      },

    diagnostic_scrollbar_sign = {'โ–ƒ', 'โ–†', 'โ–ˆ'}, -- experimental:  diagnostic status in scroll bar area; set to false to disable the diagnostic sign,
                                                 --                for other style, set to {'โ•', '๏ฎ†'} or {'-', '='}
    diagnostic_virtual_text = true,  -- show virtual for diagnostic message
    diagnostic_update_in_insert = false, -- update diagnostic message in insert mode
    display_diagnostic_qf = true, -- always show quickfix if there are diagnostic errors, set to false if you want to ignore it
    tsserver = {
      filetypes = {'typescript'} -- disable javascript etc,
      -- set to {} to disable the lspclient for all filetypes
    },
    ctags ={
      cmd = 'ctags',
      tagfile = 'tags',
      options = '-R --exclude=.git --exclude=node_modules --exclude=test --exclude=vendor --excmd=number',
    },
    gopls = {   -- gopls setting
      on_attach = function(client, bufnr)  -- on_attach for gopls
        -- your special on attach here
        -- e.g. disable gopls format because a known issue https://github.com/golang/go/issues/45732
        print("i am a hook, I will disable document format")
        client.resolved_capabilities.document_formatting = false
      end,
      settings = {
        gopls = {gofumpt = false} -- disable gofumpt etc,
      }
    },
    -- the lsp setup can be a function, .e.g 
    gopls = function()
      local go = pcall(require, "go")
      if go then
        local cfg = require("go.lsp").config()
        cfg.on_attach = function(client)
          client.server_capabilities.documentFormattingProvider = false -- efm/null-ls
        end
        return cfg
      end
    end,

    lua_ls = {
      sumneko_root_path = vim.fn.expand("$HOME") .. "/github/sumneko/lua-language-server",
      sumneko_binary = vim.fn.expand("$HOME") .. "/github/sumneko/lua-language-server/bin/macOS/lua-language-server",
    },
    servers = {'cmake', 'ltex'}, -- by default empty, and it should load all LSP clients avalible based on filetype
    -- but if you whant navigator load  e.g. `cmake` and `ltex` for you , you
    -- can put them in the `servers` list and navigator will auto load them.
    -- you could still specify the custom config  like this
    -- cmake = {filetypes = {'cmake', 'makefile'}, single_file_support = false},
  }
})

LSP clients

Built clients:

local servers = {
  "angularls", "gopls", "tsserver", "flow", "bashls", "dockerls", "julials", "pylsp", "pyright",
  "jedi_language_server", "jdtls", "lua_ls", "vimls", "html", "jsonls", "solargraph", "cssls",
  "yamlls", "clangd", "ccls", "sqlls", "denols", "graphql", "dartls", "dotls",
  "kotlin_language_server", "nimls", "intelephense", "vuels", "phpactor", "omnisharp",
  "r_language_server", "rust_analyzer", "terraformls", "svelte", "texlab", "clojure_lsp", "elixirls",
  "sourcekit", "fsautocomplete", "vls", "hls"
}

Navigator will try to load avalible lsp server/client based on filetype. The clients has none default on_attach. incremental sync and debounce is enabled by navigator. And the lsp snippet will be enabled. So you could use COQ and nvim-cmp snippet expand.

Other than above setup, additional none default setup are used for following lsp:

  • gopls
  • clangd
  • rust_analyzer
  • sqlls
  • lua_ls
  • pyright
  • ccls

Please check client setup

The plugin can work with multiple LSP, e.g sqlls+gopls+efm. But there are cases you may need to disable some of the servers. (Prevent loading multiple LSP for same source code.) e.g. I saw strange behaviours when I use pylsp+pyright+jedi together. If you have multiple similar LSP installed and have trouble with the plugin, please enable only one at a time.

Add your own servers

Above servers covered a small part neovim lspconfig support, You can still use lspconfig to add and config servers not in the list. If you would like to add a server not in the list, you can check this PR https://github.com/ray-x/navigator.lua/pull/107

Alternatively, update following option in setup(if you do not want a PR):

require'navigator'setup{lsp={servers={'cmake', 'lexls'}}}

Above option add cmake and lexls to the default server list

Disable a lsp client loading from navigator

Note: If you have multiple lsp installed for same language, please only enable one at a time by disable others with e.g. disable_lsp={'denols', 'clangd'} To disable a specific LSP, set filetypes to {} e.g.

require'navigator'.setup({
  lsp={
   pylsd={filetype={}}
  }
})

Or:

require'navigator'.setup({
  lsp={
    disable_lsp = {'pylsd', 'sqlls'},
  }
})

Try it your self

In playground folder, there is a init.lua and source code for you to play with. Check playground/README.md for more details

Default keymaps

| mode | key | function | | ---- | --------------- | ---------------------------------------------------------- | | n | gr | async references, definitions and context | | n | <Leader>gr | show reference and context | | i | <m-k> | signature help | | n | <c-k> | signature help | | n | gW | workspace symbol fuzzy finder | | n | gD | declaration | | n | gd | definition | | n | gt | type definition | | n | g0 | document symbol | | n | <C-]> | go to definition (if multiple show listview) | | n | gp | definition preview (show Preview) | | n | gP | type definition preview (show Preview) | | n | <C-LeftMouse> | definition | | n | g<LeftMouse> | implementation | | n | <Leader>gt | treesitter document symbol | | n | <Leader>gT | treesitter symbol for all open buffers | | n | <Leader> ct | ctags symbol search | | n | <Leader> cg | ctags symbol generate | | n | K | hover doc | | n | <Space>ca | code action (when you see ๐Ÿ ) | | n | <Space>la | code lens action (when you see a codelens indicator) | | v | <Space>ca | range code action (when you see ๐Ÿ ) | | n | <Space>rn | rename with floating window | | n | <Leader>re | rename (lsp default) | | n | <Leader>gi | hierarchy incoming calls | | n | <Leader>go | hierarchy outgoing calls | | n | gi | implementation | | n | <Space> D | type definition | | n | gL | show line diagnostic | | n | gG | show diagnostic for all buffers | | n | ]d | next diagnostic | | n | [d | previous diagnostic | | n | <Leader> dt | diagnostic toggle(enable/disable) | | n | ]r | next treesitter reference/usage | | n | [r | previous treesitter reference/usage | | n | <Space> wa | add workspace folder | | n | <Space> wr | remove workspace folder | | n | <Space> wl | print workspace folder | | n | <Leader>k | toggle reference highlight | | i/n | <C-p> | previous item in list | | i/n | <C-n> | next item in list | | i/n | number 1~9 | move to ith row/item in the list | | i/n | <Up> | previous item in list | | i/n | <Down> | next item in list | | n | <Ctrl-w>j | move cursor to preview (windows move to bottom view point) | | n | <Ctrl-w>k | move cursor to list (windows move to up view point) | | i/n | <C-o> | open preview file in nvim/Apply action | | n | <C-v> | open preview file in nvim with vsplit | | n | <C-s> | open preview file in nvim with split | | n | <Enter> | open preview file in nvim/Apply action | | n | <ESC> | close listview of floating window | | i/n | <C-e> | close listview of floating window | | n | <C-q> | close listview and send results to quickfix | | i/n | <C-b> | previous page in listview | | i/n | <C-f> | next page in listview | | i/n | <C-s> | save the modification to preview window to file |

Colors/Highlight

You can override default highlight GuihuaListDark (listview) and GuihuaTextViewDark (code view) and GuihuaListHl (select item)

e.g.

hi default GuihuaTextViewDark guifg=#e0d8f4 guibg=#332e55
hi default GuihuaListDark guifg=#e0d8f4 guibg=#103234
hi default GuihuaListHl guifg=#e0d8f4 guibg=#404254

There are other Lsp highlight been used in this plugin, e.g LspReferenceRead/Text/Write are used for document highlight, LspDiagnosticsXXX are used for diagnostic. Please check highlight.lua and dochighlight.lua for more info.

Dependency

  • lspconfig
  • guihua.lua (provides floating window, FZY)
  • Optional:
    • treesitter (list treesitter symbols, object analysis)
    • lsp-signature (better signature help)

The plugin can be loaded lazily (packer opt = true ), And it will check if optional plugins existance and load those plugins only if they existed.

The terminal will need to be able to output nerdfont and emoji correctly. I am using Kitty with nerdfont (Victor Mono).

Integrate with mason (williamboman/mason.nvim)

If you are using mason and would like to use the lsp servers installed by mason. Please set

mason = true -- mason user

In the config. Also please setup the lsp server from installer setup with server:setup{opts}

for mason

      use("williamboman/mason.nvim")
      use({
        "williamboman/mason-lspconfig.nvim",
        config = function()
          require("mason").setup()
          require("mason-lspconfig").setup({})
        end,
      })

      use({
        "ray-x/navigator.lua",
        requires = {
          { "ray-x/guihua.lua", run = "cd lua/fzy && make" },
          { "neovim/nvim-lspconfig" },
          { "nvim-treesitter/nvim-treesitter" },
        },
        config = function()
          require("navigator").setup({
            mason = true,
          })
        end,
      })

Another way to setup mason is disable navigator lsp setup and using mason setup handlers, pylsp for example

      use("williamboman/mason.nvim")
      use({
        "williamboman/mason-lspconfig.nvim",
        config = function()
          require("mason").setup()
          require("mason-lspconfig").setup_handlers({
            ["pylsp"] = function()
              require("lspconfig").pylsp.setup({
                on_attach = function(client, bufnr)
                  require("navigator.lspclient.mapping").setup({ client = client, bufnr = bufnr }) -- setup navigator keymaps here,
                  require("navigator.dochighlight").documentHighlight(bufnr)
                  require("navigator.codeAction").code_action_prompt(bufnr)
                end,
              })
            end,
          })
          require("mason-lspconfig").setup({})
        end,
      })

      use({
        "navigator.lua",
        requires = {
          { "ray-x/guihua.lua", run = "cd lua/fzy && make" },
          { "nvim-lspconfig" },
          { "nvim-treesitter/nvim-treesitter" },
        },
        config = function()
          require("navigator").setup({
            mason = true,
            lsp = { disable_lsp = { "pylsp" } },  -- disable pylsp setup from navigator
          })
        end,
      })

Alternatively, Navigator can be used to startup the server installed by mason. as it will override the navigator setup

To start LSP installed by mason, please use following setups

require'navigator'.setup({
  -- mason = false -- default value is false
  lsp = {
    tsserver = { cmd = {'your tsserver installed by mason'} }
    -- e.g. tsserver = { cmd = {'/home/username/.local/share/nvim/mason/packages/typescript-language-server/node_modules/typescript/bin/tsserver'} }

  }
})

example cmd setup (mac) for pyright :

require'navigator'.setup({
  -- mason = false -- default value is false

  lsp = {
    tsserver = {
      cmd = { "/Users/username/.local/share/nvim/lsp_servers/python/node_modules/.bin/pyright-langserver", "--stdio" }
      -- or mason: cmd = { "/Users/username/.local/share/nvim/mason/packages/pyright/node_modules/pyright/index.js", "--stdio"}
    }
  }
}

Integration with other lsp plugins (e.g. rust-tools, go.nvim, clangd extension)

There are lots of plugins provides lsp support

  • go.nvim allow you either hook gopls from go.nvim or from navigator and it can export the lsp setup from go.nvim.

  • rust-tools and clangd allow you to setup on_attach from config server

  • neodev Dev setup for lua development. Navigator help you setup neodev

    • setup with neodev
use  {"folke/neodev.nvim", 
  ft = 'lua',
  config =  function()
    require'neodev'.setup{}
  end
}

use {"ray-x/navigator.lua",
  config=function()
    require'navigator'.setup{}
  end
  }
  • Here is an example to setup rust with rust-tools

require('rust-tools').setup({
  server = {
    on_attach = function(client, bufnr)
      require('navigator.lspclient.mapping').setup({client=client, bufnr=bufnr}) -- setup navigator keymaps here,

      require("navigator.dochighlight").documentHighlight(bufnr)
      require('navigator.codeAction').code_action_prompt(bufnr)
      -- otherwise, you can define your own commands to call navigator functions
    end,
  }
})

require("clangd_extensions").setup {
  server = {
    on_attach = function(client, bufnr)
      require('navigator.lspclient.mapping').setup({client=client, bufnr=bufnr}) -- setup navigator keymaps here,
      require("navigator.dochighlight").documentHighlight(bufnr)
      require('navigator.codeAction').code_action_prompt(bufnr)
      -- otherwise, you can define your own commands to call navigator functions
    end,
  }
}

Usage

Please refer to lua/navigator/lspclient/mapping.lua on key mappings. Should be able to work out-of-box.

  • Use <c-e> or :q! to kill the floating window
  • <up/down> (or <c-n>, <c-p>) to move
  • <c-o> or <CR> to open location or apply code actions. Note: <CR> might be bound in insert mode by other plugins

Configuration

In navigator.lua there is a default configuration. You can override the values by passing your own values

e.g

-- The attach will be call at end of navigator on_attach()
require'navigator'.setup({on_attach = function(client, bufnr) require 'illuminate'.on_attach(client)})

Highlighting

I am using:

  • LspReferenceRead, LspReferenceText and LspReferenceWrite are used for autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight() That is where you saw the current symbol been highlighted.

  • GuihuaListDark and GuihuaTextViewDark is used for floating listvew and TextView. They are be based on current background (Normal) and PmenuSel

  • In future, I will use NormalFloat for floating view. But ATM, most of colorscheme does not define NormalFloat

You can override the above highlight to fit your current colorscheme

commands

| command | function | | --------------- | ------------------------------------------------------------------------- | | LspToggleFmt | toggle lsp auto format | | LspKeymaps | show LSP releated keymaps | | Nctags {args} | show ctags symbols, args: -g regen ctags | | LspRestart | reload lsp | | LspToggleFmt | toggle lsp format | | LspSymbols | document symbol in side panel | | LspAndDiag | document symbol and diagnostics in side panel | | NRefPanel | show symbol reference in side panel | | TSymobls | treesitter symbol in side panel | | TsAndDiag | treesitter symbol and diagnostics in side panel | | Calltree {args} | lsp call hierarchy call tree, args: -i (incomming default), -o (outgoing) |

Screenshots

colorscheme: aurora

Reference

Pls check the first part of README

Definition preview

Using treesitter and LSP to view the symbol definition

image

Sidebar, folding, outline

Treesitter outline and Diagnostics

The side panel is vim buffer. You can toggle folds with za/zo/zc

Calltree (Expandable LSP call hierarchy)

GUI and multigrid support

You can load a different font size for floating win

multigrid2

Document Symbol and navigate through the list

doc_symbol_and_navigate The key binding to navigate in the list.

  • up and down key
  • <Ctrl-f/b> for page up and down
  • number key 1~9 go to the ith item.
  • If there are loads of results, would be good to use fzy search prompt to filter out the result you are interested.

Workspace Symbol

workspace symbol

highlight document symbol and jump between reference

multiple_symbol_hi3

Current symbol highlight and jump backward/forward between symbols

Document highlight provided by LSP. Jump between symbols with treesitter (with ]r and [r) doc jump

Diagnostic

Visual studio code style show errors minimap in scroll bar area (Check setup for diagnostic_scrollbar_sign)

diagnostic_scroll_bar

Diagnostic in single bufer

diagnostic

Show diagnostic in all buffers

diagnostic multi files

Edit in preview window

You can in place edit your code in floating window

https://user-images.githubusercontent.com/1681295/121832919-89cbc080-cd0e-11eb-9778-11d0f356b38d.mov

(Note: This feature only avalible in find reference and find diagnostic, You can not add/remove lines in floating window)

Implementation

implementation

Fzy search in reference

fzy_reference

Code actions

code actions

Symbol rename

https://user-images.githubusercontent.com/1681295/200327179-0fc84660-44a8-4ee1-9631-2cc7a17b0b12.mov

Fill struct with gopls

code actions fill struct

Code preview with highlight

treesitter_preview

Treesitter symbol

Treetsitter symbols in all buffers treesitter

Signature help

Improved signature help with current parameter highlighted

signature

show_signature

Call hierarchy (incomming/outgoing calls)

incomming_calls

Light bulb if codeAction available

lightbulb

Codelens

Codelens for gopls/golang. Garbage collection analyse:

codelens

Codelens for C++/ccls. Symbol reference

codelens_cpp_ccls

Predefined LSP symbol nerdfont/emoji

nerdfont

VS-code style folding with treesitter

Folding is using a hacked version of treesitter folding. (option: ts_fold)

folding function

image

folding comments

Multiline comments can be folded as it is treated as a block

image

Debugging the plugin

One simple way to gather debug info and understand what is wrong is to output the debug logs

require'navigator'.setup({
  debug = false, -- log output, set to true and log path: ~/.local/share/nvim/gh.log
  })

-- a example of adding logs in the plugin

local log = require"navigator.util".log

local definition_hdlr = util.mk_handler(function(err, locations, ctx, _)
  -- output your log
  log('[definition] log for locations', locations, "and ctx", ctx)
  if err ~= nil then
    return
  end
end

Break changes and known issues

known issues I am working on

API and extensions

The plugin built on top of guihua, you can extend the plugin based on your requirements. e.g. A side pannel of lsp symbols and lsp diagnostics:

local function treesitter_and_diag_panel()
  local Panel = require('guihua.panel')

  local diag = require('navigator.diagnostics')
  local ft = vim.bo.filetype
  local results = diag.diagnostic_list[ft]
  log(diag.diagnostic_list, ft)

  local bufnr = api.nvim_get_current_buf()
  local p = Panel:new({
    header = 'treesitter',
    render = function(b)
      log('render for ', bufnr, b)
      return require('navigator.treesitter').all_ts_nodes(b)
    end,
  })
  p:add_section({
    header = 'diagnostic',
    render = function(buf)
      log(buf, diagnostic)
      if diag.diagnostic_list[ft] ~= nil then
        local display_items = {}
        for _, client_items in pairs(results) do
          for _, items in pairs(client_items) do
            for _, it in pairs(items) do
              log(it)
              table.insert(display_items, it)
            end
          end
        end
        return display_items
      else
        return {}
      end
    end,
  })
  p:open(true)
end

Todo

  • The project is in the early phase, bugs expected, PRs and suggestions are welcome
  • Async (some of the requests is slow on large codebases and might be good to use co-rountine)
  • More clients. I use go, python, js/ts, java, c/cpp, lua most of the time. Did not test other languages (e.g dart, swift etc)
  • Configuration options

Errors and Bug Reporting

  • Please double check your setup and check if minium setup works or not
  • It should works for 0.6.1, neovim 0.8.x prefered.
  • Check console output
  • Check LspInfo and treesitter status with checkhealth
  • Turn on log and attach the log to your issue if possible you can remove any personal/company info in the log
  • Submit Issue with minium vimrc. Please check playground/init.lua as a vimrc template. !!!Please DONOT use a packer vimrc. That installs everything to default folder!!! Also check this repo navigator bug report