Compare commits

..

7 Commits

@ -15,11 +15,11 @@ jobs:
manager: sudo snap manager: sudo snap
packages: go packages: go
- os: ubuntu-22.04 - os: ubuntu-22.04
url: https://github.com/neovim/neovim/releases/download/v0.7.0/nvim-linux64.tar.gz url: https://github.com/neovim/neovim/releases/download/v0.7.2/nvim-linux64.tar.gz
manager: sudo snap manager: sudo snap
packages: go packages: go
- os: ubuntu-22.04 - os: ubuntu-22.04
url: https://github.com/neovim/neovim/releases/download/v0.7.2/nvim-linux64.tar.gz url: https://github.com/neovim/neovim/releases/download/v0.6.1/nvim-linux64.tar.gz
manager: sudo snap manager: sudo snap
packages: go packages: go
steps: steps:

4
.gitignore vendored

@ -1,3 +1,3 @@
selene.toml
lua/navigator.lua.bak lua/navigator.lua.bak
tests/fixtures/tests tests/fixtures/tests

@ -72,11 +72,11 @@ variable is:
- Async request with lsp.buf_request for reference search - Async request with lsp.buf_request for reference search
- Treesitter symbol search. It is handy for large files (Some of LSP e.g. sumneko_lua, there is a 100kb file size limitation?). Also as LSP trying to hide details behind, Treesitter allows you to access all AST semantics. - Treesitter symbol search. It is handy for large files (Some of LSP e.g. sumneko_lua, there is a 100kb file size limitation?)
- FZY search with either native C (if gcc installed) or Lua-JIT - FZY search with either native C (if gcc installed) or Lua-JIT
- LSP multiple symbols highlight/marker and hop between document references - LSP multiple symbol highlight/marker and hop between document references
- Preview definination/references - Preview definination/references
@ -96,7 +96,7 @@ variable is:
- ccls call hierarchy (Non-standard `ccls/call` API) supports - 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. - Syntax folding based on treesitter or LSP_fold folding algorithm. (It behaves similar to vs-code); comment folding
- Treesitter symbols sidebar, LSP document symbole sidebar. Both with preview and folding - Treesitter symbols sidebar, LSP document symbole sidebar. Both with preview and folding
@ -257,14 +257,12 @@ require'navigator'.setup({
-- end, -- end,
-- The attach code will apply to all LSP clients -- 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
default_mapping = true, -- set to false if you will remap every key or if you using old version of nvim- keymaps = {{key = "gK", func = "declaration()"}}, -- a list of key maps
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 -- this kepmap gK will override "gD" mapping function declaration() in default kepmap
-- please check mapping.lua for all keymaps -- please check mapping.lua for all keymaps
treesitter_analysis = true, -- treesitter variable context treesitter_analysis = true, -- treesitter variable context
treesitter_analysis_max_num = 100, -- how many items to run treesitter analysis 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 -- 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 transparency = 50, -- 0 ~ 100 blur the main window, 100: fully transparent, 0: opaque, set to nil or 100 to disable it
@ -273,30 +271,24 @@ require'navigator'.setup({
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 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 = { icons = {
-- Code action -- Code action
code_action_icon = "🏏", -- note: need terminal support, for those not support unicode, might crash code_action_icon = "🏏",
-- Diagnostics -- Diagnostics
diagnostic_head = '🐛', diagnostic_head = '🐛',
diagnostic_head_severity_1 = "🈲", diagnostic_head_severity_1 = "🈲",
-- refer to lua/navigator.lua for more icons setups -- refer to lua/navigator.lua for more icons setups
}, },
lsp_installer = false, -- set to true if you would like use the lsp installed by williamboman/nvim-lsp-installer lsp_installer = false, -- set to true if you would like use the lsp installed by williamboman/nvim-lsp-installer
mason = false, -- set to true if you would like use the lsp installed by williamboman/mason
lsp = { lsp = {
enable = true, -- skip lsp setup if disabled make sure add require('navigator.lspclient.mapping').setup() in you enable = true, -- skip lsp setup if disabled make sure add require('navigator.lspclient.mapping').setup() in you
-- own on_attach -- own on_attach
code_action = {enable = true, sign = true, sign_priority = 40, virtual_text = true}, 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}, 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, -- set to false to disable lsp code format on save (if you are using prettier/efm/formater etc) format_on_save = true, -- set to false to disable lsp code format on save (if you are using prettier/efm/formater etc)
format_options = {async=false}, -- async: disable by default, the option used in vim.lsp.buf.format({async={true|false}, name = 'xxx'})
disable_format_cap = {"sqls", "sumneko_lua", "gopls"}, -- a list of lsp disable format capacity (e.g. if you using efm or vim-codeformat etc), empty {} by default disable_format_cap = {"sqls", "sumneko_lua", "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'}, -- a list of lsp server disabled for your project, e.g. denols and tsserver you may disable_lsp = {'pylsd', 'sqlls'}, -- a list of lsp server disabled for your project, e.g. denols and tsserver you may
--want to enable one lsp server at a time -- only want to enable one lsp server
-- to disable all default config and use your own lsp setup set -- to disable all default config and use your own lsp setup set
-- disable_lsp = 'all' and you may need to hook mapping.setup() in your on_attach -- disable_lsp = 'all'
-- Default {} -- Default {}
diagnostic = { diagnostic = {
underline = true, underline = true,
@ -316,9 +308,9 @@ require'navigator'.setup({
}, },
ctags ={ ctags ={
cmd = 'ctags', cmd = 'ctags',
tagfile = 'tags', tagfile = 'tags'
options = '-R --exclude=.git --exclude=node_modules --exclude=test --exclude=vendor --excmd=number', options = '-R --exclude=.git --exclude=node_modules --exclude=test --exclude=vendor --excmd=number'
}, }
gopls = { -- gopls setting gopls = { -- gopls setting
on_attach = function(client, bufnr) -- on_attach for gopls on_attach = function(client, bufnr) -- on_attach for gopls
-- your special on attach here -- your special on attach here
@ -330,18 +322,6 @@ require'navigator'.setup({
gopls = {gofumpt = false} -- disable gofumpt etc, 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,
sumneko_lua = { sumneko_lua = {
sumneko_root_path = vim.fn.expand("$HOME") .. "/github/sumneko/lua-language-server", 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", sumneko_binary = vim.fn.expand("$HOME") .. "/github/sumneko/lua-language-server/bin/macOS/lua-language-server",
@ -449,7 +429,7 @@ In `playground` folder, there is a `init.lua` and source code for you to play wi
| n | gd | definition | | n | gd | definition |
| n | g0 | document symbol | | n | g0 | document symbol |
| n | \<C-]\> | go to definition (if multiple show listview) | | n | \<C-]\> | go to definition (if multiple show listview) |
| n | gp | definition preview (show Preview) | | n | gp | definition preview (Go to Preview) |
| n | \<C-LeftMouse\> | definition | | n | \<C-LeftMouse\> | definition |
| n | g\<LeftMouse\> | implementation | | n | g\<LeftMouse\> | implementation |
| n | \<Leader>gt | treesitter document symbol | | n | \<Leader>gt | treesitter document symbol |
@ -490,21 +470,20 @@ In `playground` folder, there is a `init.lua` and source code for you to play wi
| n | \<Enter\> | open preview file in nvim/Apply action | | n | \<Enter\> | open preview file in nvim/Apply action |
| n | \<ESC\> | close listview of floating window | | n | \<ESC\> | close listview of floating window |
| i/n | \<C-e\> | 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-b\> | previous page in listview |
| i/n | \<C-f\> | next page in listview | | i/n | \<C-f\> | next page in listview |
| i/n | \<C-s\> | save the modification to preview window to file | | i/n | \<C-s\> | save the modification to preview window to file |
### Colors/Highlight: ### Colors/Highlight:
You can override default highlight GuihuaListDark (listview) and GuihuaTextViewDark (code view) and GuihuaListHl (select item) You can override default highlight GHListDark (listview) and GHTextViewDark (code view) and GHListHl (select item)
e.g. e.g.
```vim ```vim
hi default GuihuaTextViewDark guifg=#e0d8f4 guibg=#332e55 hi default GHTextViewDark guifg=#e0d8f4 guibg=#332e55
hi default GuihuaListDark guifg=#e0d8f4 guibg=#103234 hi default GHListDark guifg=#e0d8f4 guibg=#103234
hi default GuihuaListHl guifg=#e0d8f4 guibg=#404254 hi default GHListHl guifg=#e0d8f4 guibg=#404254
``` ```
There are other Lsp highlight been used in this plugin, e.g LspReferenceRead/Text/Write are used for document highlight, There are other Lsp highlight been used in this plugin, e.g LspReferenceRead/Text/Write are used for document highlight,
@ -522,18 +501,18 @@ The plugin can be loaded lazily (packer `opt = true` ), And it will check if opt
The terminal will need to be able to output nerdfont and emoji correctly. I am using Kitty with nerdfont (Victor Mono). The terminal will need to be able to output nerdfont and emoji correctly. I am using Kitty with nerdfont (Victor Mono).
## Integrat with mason (williamboman/mason.nvim) or lsp_installer (williamboman/nvim-lsp-installer, deprecated) ## Integrat with lsp_installer (williamboman/nvim-lsp-installer)
If you are using mason or lsp_installer and would like to use the lsp servers installed by lsp_installer. Please set If you are using lsp_installer and would like to use the lsp servers installed by lsp_installer. Please set
```lua ```lua
lsp_installer = true --lsp_installer users, deprecated lsp_installer = true
mason = true -- mason user
``` ```
In the config. Also please setup the lsp server from installer setup with `server:setup{opts}` In the config. Also please setup the lsp server from installer setup with `server:setup{opts}`
lsp-installer example: example:
```lua ```lua
use({ use({
'williamboman/nvim-lsp-installer', 'williamboman/nvim-lsp-installer',
@ -546,79 +525,14 @@ lsp-installer example:
'ray-x/navigator.lua', 'ray-x/navigator.lua',
config = function() config = function()
require('navigator').setup({ require('navigator').setup({
debug = true,
lsp_installer = true, lsp_installer = true,
keymaps = { { key = 'gR', func = "require('navigator.reference').async_ref()" } },
}) })
end, end,
}) })
``` ```
for mason
```lua
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
```lua
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,
})
```
Please refer to [lsp_installer_config](https://github.com/ray-x/navigator.lua/blob/master/playground/init_lsp_installer.lua) Please refer to [lsp_installer_config](https://github.com/ray-x/navigator.lua/blob/master/playground/init_lsp_installer.lua)
for more info for more info
@ -634,9 +548,7 @@ To start LSP installed by lsp_installer, please use following setups
require'navigator'.setup({ require'navigator'.setup({
-- lsp_installer = false -- default value is false -- lsp_installer = false -- default value is false
lsp = { lsp = {
tsserver = { cmd = {'your tsserver installed by lsp_installer or mason'} } tsserver = { cmd = {'your tsserver installed by lsp_installer'} }
-- e.g. tsserver = { cmd = {'/home/username/.local/share/nvim/mason/packages/typescript-language-server/node_modules/typescript/bin/tsserver'} }
} }
}) })
@ -651,7 +563,6 @@ require'navigator'.setup({
lsp = { lsp = {
tsserver = { tsserver = {
cmd = { "/Users/username/.local/share/nvim/lsp_servers/python/node_modules/.bin/pyright-langserver", "--stdio" } 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"}
} }
} }
} }
@ -693,27 +604,22 @@ Here is an example [init_lsp_installer.lua](https://github.com/ray-x/navigator.l
### Integration with other lsp plugins (e.g. rust-tools, go.nvim, clangd extension) ### Integration with other lsp plugins (e.g. rust-tools, go.nvim, clangd extension)
There are lots of plugins provides lsp support 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. 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
* [lua-dev](https://github.com/folke/lua-dev.nvim) Dev setup for init.lua and plugin development. Navigator can rust-tools and clangd allow you to setup on_attach from config server
extend lua setup with lua-dev.
Here is an example to setup rust with rust-tools Here is an example to setup rust with rust-tools
```lua ```lua
require'navigator'.setup({ require'navigator'.setup({
lsp = { lsp = {
disable_lsp = { "rust_analyzer", "clangd" }, -- will not run rust_analyzer setup from navigator disable_lsp = { "rust_analyzer", "clangd" }, -- will not run rust_analyzer setup from navigator
['lua-dev'] = { runtime_path=true } -- any non default lua-dev setups }
},
}) })
require('rust-tools').setup({ require('rust-tools').setup({
server = { server = {
on_attach = function(client, bufnr) on_attach = function(client, bufnr)
require('navigator.lspclient.mapping').setup({client=client, bufnr=bufnr}) -- setup navigator keymaps here, 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 -- otherwise, you can define your own commands to call navigator functions
end, end,
} }
@ -723,8 +629,6 @@ require("clangd_extensions").setup {
server = { server = {
on_attach = function(client, bufnr) on_attach = function(client, bufnr)
require('navigator.lspclient.mapping').setup({client=client, bufnr=bufnr}) -- setup navigator keymaps here, 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 -- otherwise, you can define your own commands to call navigator functions
end, end,
} }
@ -760,7 +664,7 @@ Highlight I am using:
- LspReferenceRead, LspReferenceText and LspReferenceWrite are used for `autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()` - 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. 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 - GHListDark and GHTextViewDark is used for floating listvew and TextView. They are be based on current background
(Normal) and PmenuSel (Normal) and PmenuSel
- In future, I will use NormalFloat for floating view. But ATM, most of colorscheme does not define NormalFloat - In future, I will use NormalFloat for floating view. But ATM, most of colorscheme does not define NormalFloat
@ -777,7 +681,6 @@ You can override the above highlight to fit your current colorscheme
| LspRestart | reload lsp | | LspRestart | reload lsp |
| LspToggleFmt | toggle lsp format | | LspToggleFmt | toggle lsp format |
| LspSymbols | document symbol in side panel | | LspSymbols | document symbol in side panel |
| NRefPanel | show symbol reference in side panel |
| TSymobls | treesitter symbol in side panel | | TSymobls | treesitter symbol in side panel |
| Calltree {args} | lsp call hierarchy call tree, args: -i (incomming default), -o (outgoing) | | Calltree {args} | lsp call hierarchy call tree, args: -i (incomming default), -o (outgoing) |
@ -917,14 +820,11 @@ Codelens for C++/ccls. Symbol reference
### VS-code style folding with treesitter ### VS-code style folding with treesitter
Folding is using a hacked version of treesitter folding. (option: ts_fold)
#### folding function #### folding function
![image](https://user-images.githubusercontent.com/1681295/148491596-6cd6c507-c157-4536-b8c4-dc969436763a.png) ![image](https://user-images.githubusercontent.com/1681295/148491596-6cd6c507-c157-4536-b8c4-dc969436763a.png)
#### folding comments #### folding comments
Multiline comments can be folded as it is treated as a block
![image](https://user-images.githubusercontent.com/1681295/148491845-5ffb18ea-f05d-4229-aec3-aa635b3de814.png) ![image](https://user-images.githubusercontent.com/1681295/148491845-5ffb18ea-f05d-4229-aec3-aa635b3de814.png)

@ -477,13 +477,13 @@ DEFAULT KEYMAPS *navigator-default_keymap
COLORS/HIGHLIGHT: *navigator-colors/highlight:* COLORS/HIGHLIGHT: *navigator-colors/highlight:*
You can override default highlight GuihuaListDark (listview) and GuihuaTextViewDark (code view) and GuihuaListHl (select item) You can override default highlight GHListDark (listview) and GHTextViewDark (code view) and GHListHl (select item)
e.g. e.g.
> >
hi default GuihuaTextViewDark guifg=#e0d8f4 guibg=#332e55 hi default GHTextViewDark guifg=#e0d8f4 guibg=#332e55
hi default GuihuaListDark guifg=#e0d8f4 guibg=#103234 hi default GHListDark guifg=#e0d8f4 guibg=#103234
hi default GuihuaListHl guifg=#e0d8f4 guibg=#404254 hi default GHListHl guifg=#e0d8f4 guibg=#404254
< <
There are other Lsp highlight been used in this plugin, e.g LspReferenceRead/Text/Write are used for document highlight, There are other Lsp highlight been used in this plugin, e.g LspReferenceRead/Text/Write are used for document highlight,
@ -644,7 +644,7 @@ Highlight I am using:
* LspReferenceRead, LspReferenceText and LspReferenceWrite are used for `autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()` * 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. 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 * GHListDark and GHTextViewDark is used for floating listvew and TextView. They are be based on current background
(Normal) and PmenuSel (Normal) and PmenuSel
* In future, I will use NormalFloat for floating view. But ATM, most of colorscheme does not define NormalFloat * In future, I will use NormalFloat for floating view. But ATM, most of colorscheme does not define NormalFloat
@ -660,9 +660,8 @@ COMMANDS *navigator-command
| Nctags {args} | show ctags symbols, args: -g regen ctags | | Nctags {args} | show ctags symbols, args: -g regen ctags |
| LspRestart | reload lsp | | LspRestart | reload lsp |
| LspSymbols | document symbol in side panel | | LspSymbols | document symbol in side panel |
| NRefPanel |symbol reference in side panel |
| TSymobls | treesitter symbol in side panel | | TSymobls | treesitter symbol in side panel |
| Calltree {args} | lsp call hierarchy call tree, args: -i (incomming default), -o (outgoing) | | CallTree {args} | lsp call hierarchy call tree, args: -i (incomming default), -o (outgoing) |
:LspToggleFmt *:LspToggleFmt* :LspToggleFmt *:LspToggleFmt*
Toggle lsp auto format. Toggle lsp auto format.
@ -684,9 +683,6 @@ COMMANDS *navigator-command
:TSSymbols *:TSSymbols* :TSSymbols *:TSSymbols*
Treesitter symbol in side panel. Treesitter symbol in side panel.
:NRefPanel *:NRefPanel*
Symbol reference in side panel.
:Calltree [flags] *:Calltree* :Calltree [flags] *:Calltree*
Lsp call hierarchy call tree. Lsp call hierarchy call tree.
[flags]: [flags]:

@ -1,14 +1,11 @@
local M = {} local M = {}
local api = vim.api
local function warn(msg) local function warn(msg)
api.nvim_echo({ { 'WRN: ' .. msg, 'WarningMsg' } }, true, {}) vim.api.nvim_echo({ { 'WRN: ' .. msg, 'WarningMsg' } }, true, {})
end end
local function info(msg) local function info(msg)
if _NgConfigValues.debug then vim.api.nvim_echo({ { 'Info: ' .. msg } }, true, {})
api.nvim_echo({ { 'Info: ' .. msg } }, true, {})
end
end end
_NgConfigValues = { _NgConfigValues = {
@ -19,7 +16,7 @@ _NgConfigValues = {
preview_lines = 40, -- total lines in preview screen preview_lines = 40, -- total lines in preview screen
preview_lines_before = 5, -- lines before the highlight line preview_lines_before = 5, -- lines before the highlight line
default_mapping = true, default_mapping = true,
keymaps = {}, -- e.g keymaps={{key = "GR", func = vim.lsp.buf.references}, } this replace gr default mapping keymaps = {}, -- e.g keymaps={{key = "GR", func = "references()"}, } this replace gr default mapping
external = nil, -- true: enable for goneovim multigrid otherwise false external = nil, -- true: enable for goneovim multigrid otherwise false
border = 'single', -- border style, can be one of 'none', 'single', 'double', "shadow" border = 'single', -- border style, can be one of 'none', 'single', 'double', "shadow"
@ -32,16 +29,11 @@ _NgConfigValues = {
ts_fold = false, ts_fold = false,
treesitter_analysis = true, -- treesitter variable context treesitter_analysis = true, -- treesitter variable context
treesitter_analysis_max_num = 100, -- how many items to run treesitter analysis treesitter_analysis_max_num = 100, -- how many items to run treesitter analysis
treesitter_analysis_condense = true, -- short format of function
transparency = 50, -- 0 ~ 100 blur the main window, 100: fully transparent, 0: opaque, set to nil to disable it transparency = 50, -- 0 ~ 100 blur the main window, 100: fully transparent, 0: opaque, set to nil to disable it
lsp_signature_help = true, -- if you would like to hook ray-x/lsp_signature plugin in navigator 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 -- setup here. if it is nil, navigator will not init signature help
signature_help_cfg = { debug = false }, -- if you would like to init ray-x/lsp_signature plugin in navigator, pass in signature help signature_help_cfg = { debug = false }, -- if you would like to init ray-x/lsp_signature plugin in navigator, pass in signature help
ctags = { ctags = { cmd = 'ctags', tagfile = '.tags' },
cmd = 'ctags',
tagfile = '.tags',
options = '-R --exclude=.git --exclude=node_modules --exclude=test --exclude=vendor --excmd=number',
},
lsp = { lsp = {
enable = true, -- if disabled make sure add require('navigator.lspclient.mapping').setup() in you on_attach enable = true, -- if disabled make sure add require('navigator.lspclient.mapping').setup() in you on_attach
code_action = { code_action = {
@ -51,7 +43,6 @@ _NgConfigValues = {
virtual_text = true, virtual_text = true,
virtual_text_icon = true, virtual_text_icon = true,
}, },
document_highlight = true, -- highlight reference a symbol
code_lens_action = { code_lens_action = {
enable = true, enable = true,
sign = true, sign = true,
@ -66,7 +57,6 @@ _NgConfigValues = {
severity_sort = { reverse = true }, severity_sort = { reverse = true },
}, },
format_on_save = true, -- set to false to disasble lsp code format on save (if you are using prettier/efm/formater etc) format_on_save = true, -- set to false to disasble lsp code format on save (if you are using prettier/efm/formater etc)
format_options = { async = false }, -- async: disable by default, I saw something unexpected
disable_nulls_codeaction_sign = true, -- do not show nulls codeactions (as it will alway has a valid action) disable_nulls_codeaction_sign = true, -- do not show nulls codeactions (as it will alway has a valid action)
disable_format_cap = {}, -- a list of lsp disable file format (e.g. if you using efm or vim-codeformat etc), empty by default disable_format_cap = {}, -- a list of lsp disable file format (e.g. if you using efm or vim-codeformat etc), empty by default
disable_lsp = {}, -- a list of lsp server disabled for your project, e.g. denols and tsserver you may disable_lsp = {}, -- a list of lsp server disabled for your project, e.g. denols and tsserver you may
@ -81,10 +71,6 @@ _NgConfigValues = {
-- filetypes = {'typescript'} -- disable javascript etc, -- filetypes = {'typescript'} -- disable javascript etc,
-- set to {} to disable the lspclient for all filetype -- set to {} to disable the lspclient for all filetype
}, },
['lua-dev'] = { -- navigator can use lua-dev settings to setup sumneko_lua
-- your setting for lua-dev here
-- navigator will setup lua-dev
},
sumneko_lua = { sumneko_lua = {
-- sumneko_root_path = sumneko_root_path, -- sumneko_root_path = sumneko_root_path,
-- sumneko_binary = sumneko_binary, -- sumneko_binary = sumneko_binary,
@ -93,7 +79,6 @@ _NgConfigValues = {
servers = {}, -- you can add additional lsp server so navigator will load the default for you servers = {}, -- you can add additional lsp server so navigator will load the default for you
}, },
lsp_installer = false, -- set to true if you would like use the lsp installed by williamboman/nvim-lsp-installer lsp_installer = false, -- set to true if you would like use the lsp installed by williamboman/nvim-lsp-installer
mason = false, -- set to true if you would like use the lsp installed by williamboman/mason
icons = { icons = {
icons = true, -- set to false to use system default ( if you using a terminal does not have nerd/icon) icons = true, -- set to false to use system default ( if you using a terminal does not have nerd/icon)
-- Code action -- Code action
@ -172,8 +157,6 @@ local extend_config = function(opts)
if opts.debug then if opts.debug then
_NgConfigValues.debug = opts.debug _NgConfigValues.debug = opts.debug
end end
-- enable logs
require('navigator.util').setup()
for key, value in pairs(opts) do for key, value in pairs(opts) do
if _NgConfigValues[key] == nil then if _NgConfigValues[key] == nil then
warn( warn(
@ -216,12 +199,12 @@ local extend_config = function(opts)
else else
if _NgConfigValues[key][k] == nil then if _NgConfigValues[key][k] == nil then
if key == 'lsp' then if key == 'lsp' then
local lsp = require('navigator.lspclient.servers') local lsp = require('navigator.lspclient.clients').lsp
if not vim.tbl_contains(lsp or {}, k) and k ~= 'efm' and k ~= 'null-ls' then if not vim.tbl_contains(lsp or {}, k) and k ~= 'efm' and k ~= 'null-ls' then
info(string.format('[] extend LSP support for %s %s ', key, k)) info(string.format('[] extend LSP support for %s %s ', key, k))
end end
elseif key == 'keymaps' then elseif key == 'keymaps' then
info('keymap override' .. vim.inspect(v)) info('keymap override')
-- skip key check and allow mapping to handle that -- skip key check and allow mapping to handle that
else else
warn(string.format('[] Key %s %s not valid', key, k)) warn(string.format('[] Key %s %s not valid', key, k))
@ -251,14 +234,7 @@ M.setup = function(cfg)
cfg = cfg or {} cfg = cfg or {}
extend_config(cfg) extend_config(cfg)
local cmd_group = api.nvim_create_augroup('NGFtGroup', {}) vim.cmd([[autocmd FileType,BufEnter * lua require'navigator.lspclient.clients'.on_filetype()]]) -- BufWinEnter BufNewFile,BufRead ?
api.nvim_create_autocmd({ 'FileType', 'BufEnter' }, {
group = cmd_group,
pattern = '*',
callback = function()
require('navigator.lspclient.clients').on_filetype()
end,
})
require('navigator.lazyloader').init() require('navigator.lazyloader').init()
require('navigator.lspclient.clients').setup(_NgConfigValues) require('navigator.lspclient.clients').setup(_NgConfigValues)
@ -268,8 +244,7 @@ M.setup = function(cfg)
require('navigator.implementation') require('navigator.implementation')
cfg.lsp = cfg.lsp or _NgConfigValues.lsp cfg.lsp = cfg.lsp or _NgConfigValues.lsp
if cfg.lsp.enable then
if _NgConfigValues.lsp.enable then
require('navigator.diagnostics').config(cfg.lsp.diagnostic) require('navigator.diagnostics').config(cfg.lsp.diagnostic)
end end
if not _NgConfigValues.loaded then if not _NgConfigValues.loaded then
@ -286,6 +261,7 @@ M.setup = function(cfg)
local _start_client = vim.lsp.start_client local _start_client = vim.lsp.start_client
vim.lsp.start_client = function(lsp_config) vim.lsp.start_client = function(lsp_config)
-- add highlight for Lspxxx -- add highlight for Lspxxx
require('navigator.dochighlight').documentHighlight()
require('navigator.lspclient.highlight').add_highlight() require('navigator.lspclient.highlight').add_highlight()
require('navigator.lspclient.highlight').diagnositc_config_sign() require('navigator.lspclient.highlight').diagnositc_config_sign()
-- require('navigator.lspclient.mapping').setup() -- require('navigator.lspclient.mapping').setup()

@ -152,13 +152,9 @@ local code_action_req = function(_call_back_fn, diagnostics)
end end
local function sort_select(action_tuples, opts, on_user_choice) local function sort_select(action_tuples, opts, on_user_choice)
if action_tuples ~= nil and action_tuples[1][2] ~= nil and action_tuples[1][2].command then -- table.sort(action_tuples, function(a, b)
table.sort(action_tuples, function(a, b) -- return a[1] > b[1]
return a[1] > b[1] -- end)
end)
end
trace(action_tuples)
require('guihua.gui').select(action_tuples, opts, on_user_choice) require('guihua.gui').select(action_tuples, opts, on_user_choice)
end end
@ -166,6 +162,8 @@ code_action.code_action = function()
local original_select = vim.ui.select local original_select = vim.ui.select
vim.ui.select = sort_select vim.ui.select = sort_select
log('codeaction')
vim.lsp.buf.code_action() vim.lsp.buf.code_action()
vim.defer_fn(function() vim.defer_fn(function()
vim.ui.select = original_select vim.ui.select = original_select
@ -188,19 +186,17 @@ code_action.range_code_action = function(startpos, endpos)
local original_input = vim.ui.input local original_input = vim.ui.input
vim.ui.input = require('guihua.input').input vim.ui.input = require('guihua.input').input
vim.lsp.buf.range_code_action(context, startpos, endpos)
if vim.fn.has('nvim-0.8') then
vim.lsp.buf.code_action({context=context ,range={start = startpos, ['end'] = endpos}})
else
vim.lsp.buf.range_code_action(context, startpos, endpos)
end
vim.defer_fn(function() vim.defer_fn(function()
vim.ui.select = original_select vim.ui.select = original_select
end, 1000)
vim.defer_fn(function()
vim.ui.input = original_input vim.ui.input = original_input
end, 1000) end, 1000)
end end
code_action.code_action_prompt = function(bufnr) code_action.code_action_prompt = function()
if special_buffers[vim.bo.filetype] then if special_buffers[vim.bo.filetype] then
log('skip buffer', vim.bo.filetype) log('skip buffer', vim.bo.filetype)
return return

@ -5,7 +5,7 @@ local codelens = require('vim.lsp.codelens')
local log = require('navigator.util').log local log = require('navigator.util').log
local trace = require('navigator.util').trace local trace = require('navigator.util').trace
-- trace = log
local lsphelper = require('navigator.lspwrapper') local lsphelper = require('navigator.lspwrapper')
local api = vim.api local api = vim.api
local M = {} local M = {}
@ -61,19 +61,24 @@ local codelens_hdlr = function(err, result, ctx, cfg)
end end
end end
function M.setup(bufnr) function M.setup()
log('setup for ****** ', bufnr) vim.cmd('highlight! link LspCodeLens LspDiagnosticsHint')
vim.api.nvim_set_hl(0, 'LspCodeLens', { link = 'DiagnosticsHint', default = true }) vim.cmd('highlight! link LspCodeLensText LspDiagnosticsInformation')
vim.api.nvim_set_hl(0, 'LspCodeLensText', { link = 'DiagnosticsInformation', default = true }) vim.cmd('highlight! link LspCodeLensTextSign LspDiagnosticsSignInformation')
vim.api.nvim_set_hl(0, 'LspCodeLensSign', { link = 'DiagnosticsInformation', default = true }) vim.cmd('highlight! link LspCodeLensTextSeparator Boolean')
vim.api.nvim_set_hl(0, 'LspCodeLensSeparator', { link = 'Boolean', default = true })
vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI', 'InsertLeave' }, { vim.cmd('augroup navigator.codelenses')
group = vim.api.nvim_create_augroup('nv__codelenses', {}), vim.cmd(' autocmd!')
buffer = bufnr or vim.api.nvim_win_get_buf(), vim.cmd("autocmd BufEnter,CursorHold,InsertLeave <buffer> lua require('navigator.codelens').refresh()")
callback = function() vim.cmd('augroup end')
require('navigator.codelens').refresh() local on_codelens = vim.lsp.handlers['textDocument/codeLens']
end, vim.lsp.handlers['textDocument/codeLens'] = function(err, result, ctx, cfg)
}) -- trace(err, result, ctx.client_id, ctx.bufnr, cfg or {})
cfg = cfg or {}
ctx = ctx or { bufnr = vim.api.nvim_get_current_buf() }
on_codelens(err, result, ctx, cfg)
codelens_hdlr(err, result, ctx, cfg)
end
end end
M.lsp_clients = {} M.lsp_clients = {}
@ -86,7 +91,7 @@ function M.refresh()
if not lsphelper.check_capabilities('codeLensProvider') then if not lsphelper.check_capabilities('codeLensProvider') then
return return
end end
M.inline() vim.lsp.codelens.refresh()
end end
local virtual_types_ns = api.nvim_create_namespace('ng_virtual_types') local virtual_types_ns = api.nvim_create_namespace('ng_virtual_types')
@ -101,13 +106,12 @@ function M.run_action()
local original_select = vim.ui.select local original_select = vim.ui.select
vim.ui.select = require('guihua.gui').select vim.ui.select = require('guihua.gui').select
log('codelens action') log('codeaction')
codelens.run() codelens.run()
vim.defer_fn(function() vim.defer_fn(function()
vim.ui.select = original_select vim.ui.select = original_select
end, 1000) end, 1000)
end end
M.inline = function() M.inline = function()
@ -125,20 +129,42 @@ M.inline = function()
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local parameter = lsp.util.make_position_params() local parameter = lsp.util.make_position_params()
local response = lsp.buf_request_sync(bufnr, 'textDocument/codeLens', parameter)
local on_codelens = vim.lsp.handlers['textDocument/codeLens']
lsp.buf_request(bufnr, 'textDocument/codeLens', parameter, function(err, response, ctx, _) -- Clear previous highlighting
-- Clear previous highlighting api.nvim_buf_clear_namespace(bufnr, virtual_types_ns, 0, -1)
api.nvim_buf_clear_namespace(bufnr, virtual_types_ns, 0, -1)
if response then
if response then log(response)
trace(response) for _, v in ipairs(response) do
if v == nil or v.result == nil then
on_codelens(err, response, ctx, _) return
end -- no response
codelens_hdlr (err, response, ctx, _) for _, vv in pairs(v.result) do
local start_line = -1
for _, vvv in pairs(vv.range) do
start_line = tonumber(vvv.line)
end
local cmd = vv.command
local msg = _NgConfigValues.icons.code_action_icon .. ' '
if cmd then
local txt = cmd.title or ''
txt = txt .. ' ' .. (cmd.command or '') .. ' '
msg = msg .. txt .. ' '
end
log(msg)
api.nvim_buf_set_extmark(bufnr, virtual_types_ns, start_line, -1, {
virt_text = { { msg, 'LspCodeLensText' } },
virt_text_pos = 'overlay',
hl_mode = 'combine',
})
end
end end
end) -- else
-- api.nvim_command("echohl WarningMsg | echo 'VirtualTypes: No response' | echohl None")
end
end end
return M return M

@ -89,7 +89,7 @@ local function ctags_symbols()
local height = _NgConfigValues.height or 0.4 local height = _NgConfigValues.height or 0.4
local width = _NgConfigValues.width or 0.7 local width = _NgConfigValues.width or 0.7
height = math.floor(height * vfn.winheight('%')) height = math.floor(height * vfn.winheight('%'))
width = math.floor(vim.api.nvim_get_option('columns') * width) width = math.floor(width * vfn.winwidth('%'))
local items = {} local items = {}
local ctags_file = _NgConfigValues.ctags.tagfile local ctags_file = _NgConfigValues.ctags.tagfile
if not util.file_exists(ctags_file) then if not util.file_exists(ctags_file) then
@ -118,7 +118,7 @@ local function ctags_symbols()
local opt = { local opt = {
api = '', api = '',
ft = ft, ft = ft,
bg = 'GuihuaListDark', bg = 'GHListDark',
data = result, data = result,
items = result, items = result,
enter = true, enter = true,

@ -3,7 +3,6 @@ local lsphelper = require('navigator.lspwrapper')
local locations_to_items = lsphelper.locations_to_items local locations_to_items = lsphelper.locations_to_items
local gui = require('navigator.gui') local gui = require('navigator.gui')
local log = util.log local log = util.log
local trace = util.trace
local TextView = require('guihua.textview') local TextView = require('guihua.textview')
-- callback for lsp definition, implementation and declaration handler -- callback for lsp definition, implementation and declaration handler
local definition_hdlr = function(err, locations, ctx, _) local definition_hdlr = function(err, locations, ctx, _)
@ -22,10 +21,6 @@ local definition_hdlr = function(err, locations, ctx, _)
end end
local oe = require('navigator.util').encoding(ctx.client_id) local oe = require('navigator.util').encoding(ctx.client_id)
locations = util.dedup(locations)
log(locations)
log("found " .. #locations .. " locations")
if vim.tbl_islist(locations) then if vim.tbl_islist(locations) then
if #locations > 1 then if #locations > 1 then
local items = locations_to_items(locations) local items = locations_to_items(locations)
@ -74,7 +69,7 @@ local function def_preview(timeout_ms)
local row = range.start.line local row = range.start.line
-- in case there are comments -- in case there are comments
row = math.max(row - 3, 1) row = math.max(row - 3, 1)
local delta = range.start.line - row + 3 local delta = range.start.line - row + 1
local uri = data[1].uri or data[1].targetUri local uri = data[1].uri or data[1].targetUri
if not uri then if not uri then
return return
@ -85,12 +80,7 @@ local function def_preview(timeout_ms)
end end
local ok, parsers = pcall(require, 'nvim-treesitter.parsers') local ok, parsers = pcall(require, 'nvim-treesitter.parsers')
local lines_num = 12
-- TODO: 32/64 should be an option
local lines_num = 64
if range['end'] ~= nil then
lines_num = math.max(lines_num, range['end'].line - range.start.line + 4)
end
if ok then if ok then
local ts = require('navigator.treesitter') local ts = require('navigator.treesitter')
local root = parsers.get_parser(bufnr) local root = parsers.get_parser(bufnr)
@ -102,10 +92,10 @@ local function def_preview(timeout_ms)
local sr, _, er, _ = ts.get_node_scope(def_node) local sr, _, er, _ = ts.get_node_scope(def_node)
log(sr, er) log(sr, er)
lines_num = math.max(lines_num, er - sr + 5) -- comments etc lines_num = math.max(lines_num, er - sr + 3) -- comments etc
end end
-- TODO: 32 should be an option -- TODO: 12 should be an option
local definition = vim.api.nvim_buf_get_lines(bufnr, row, range['end'].line + lines_num, false) local definition = vim.api.nvim_buf_get_lines(bufnr, row, range['end'].line + lines_num, false)
local def_line = vim.api.nvim_buf_get_lines(bufnr, range.start.line, range.start.line + 1, false) local def_line = vim.api.nvim_buf_get_lines(bufnr, range.start.line, range.start.line + 1, false)
for _ = 1, math.min(3, #definition), 1 do for _ = 1, math.min(3, #definition), 1 do
@ -117,8 +107,7 @@ local function def_preview(timeout_ms)
end end
end end
local width = 40 local width = 40
local maxwidth = math.floor(vim.fn.winwidth(0) * 4 / 5)
local maxwidth = math.floor( vim.api.nvim_get_option('columns') * 0.8)
for _, value in pairs(definition) do for _, value in pairs(definition) do
-- log(key, value, width) -- log(key, value, width)
width = math.max(width, #value + 4) width = math.max(width, #value + 4)
@ -132,7 +121,7 @@ local function def_preview(timeout_ms)
relative = 'cursor', relative = 'cursor',
style = 'minimal', style = 'minimal',
ft = filetype, ft = filetype,
rect = { width = width, height = math.min(#definition + 3, 16), pos_y = 2 }, -- TODO: 16 hardcoded rect = { width = width, height = #definition + 3, pos_y = 2 },
data = definition, data = definition,
enter = true, enter = true,
border = _NgConfigValues.border or 'shadow', border = _NgConfigValues.border or 'shadow',

@ -2,6 +2,7 @@ local gui = require('navigator.gui')
local diagnostic_list = {} local diagnostic_list = {}
local diagnostic = vim.diagnostic or vim.lsp.diagnostic local diagnostic = vim.diagnostic or vim.lsp.diagnostic
-- local hide = diagnostic.hide or diagnostic.clear -- local hide = diagnostic.hide or diagnostic.clear
_NG_VT_DIAG_NS = vim.api.nvim_create_namespace('navigator_lua_diag')
local util = require('navigator.util') local util = require('navigator.util')
local log = util.log local log = util.log
local trace = require('guihua.log').trace local trace = require('guihua.log').trace
@ -10,8 +11,6 @@ local error = util.error
local path_sep = require('navigator.util').path_sep() local path_sep = require('navigator.util').path_sep()
local path_cur = require('navigator.util').path_cur() local path_cur = require('navigator.util').path_cur()
local empty = util.empty local empty = util.empty
local api = vim.api
_NG_VT_DIAG_NS = api.nvim_create_namespace('navigator_lua_diag')
if not util.nvim_0_6_1() then if not util.nvim_0_6_1() then
util.warn('Navigator 0.4+ only support nvim-0.6+, please use Navigator 0.3.x or a newer version of neovim') util.warn('Navigator 0.4+ only support nvim-0.6+, please use Navigator 0.3.x or a newer version of neovim')
@ -28,7 +27,24 @@ if vim.diagnostic then
} }
end end
local diagnostic_cfg local diagnostic_cfg = {
-- Enable underline, use default values
underline = _NgConfigValues.lsp.diagnostic.underline,
-- Enable virtual
-- Use a function to dynamically turn signs off
-- and on, using buffer local variables
signs = true,
update_in_insert = _NgConfigValues.lsp.diagnostic.update_in_insert or false,
severity_sort = _NgConfigValues.lsp.diagnostic.severity_sort,
float = {
focusable = false,
style = 'minimal',
border = 'rounded',
source = 'always',
header = '',
prefix = '',
},
}
local function get_count(bufnr, level) local function get_count(bufnr, level)
if vim.diagnostic ~= nil then if vim.diagnostic ~= nil then
@ -58,18 +74,15 @@ local function error_marker(result, ctx, config)
if bufnr == nil then if bufnr == nil then
bufnr = vim.uri_to_bufnr(result.uri) bufnr = vim.uri_to_bufnr(result.uri)
end end
local success, fname = pcall(api.nvim_buf_get_name, bufnr) local fname = vim.api.nvim_buf_get_name(bufnr)
if not success then
return
end
local uri = vim.uri_from_fname(fname) local uri = vim.uri_from_fname(fname)
if uri ~= result.uri then if uri ~= result.uri then
log('not same buf', ctx, result.uri, bufnr, vim.fn.bufnr()) log('not same buf', ctx, result.uri, bufnr, vim.fn.bufnr())
return return
end end
if not api.nvim_buf_is_loaded(bufnr) then if not vim.api.nvim_buf_is_loaded(bufnr) then
trace('buf not loaded', bufnr) log('buf not loaded', bufnr)
return return
end end
@ -80,7 +93,7 @@ local function error_marker(result, ctx, config)
local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]]) local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]])
if diag_cnt == 0 and _NG_VT_DIAG_NS ~= nil then if diag_cnt == 0 and _NG_VT_DIAG_NS ~= nil then
log('great no errors') log('great no errors')
api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1) vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
end end
return return
end end
@ -88,12 +101,12 @@ local function error_marker(result, ctx, config)
-- total line num of current buffer -- total line num of current buffer
-- local winid = vim.fn.win_getid(vim.fn.winnr()) -- local winid = vim.fn.win_getid(vim.fn.winnr())
-- local winid = api.nvim_get_current_win() -- local winid = vim.api.nvim_get_current_win()
local total_num = api.nvim_buf_line_count(bufnr) local total_num = vim.api.nvim_buf_line_count(bufnr)
-- local total_num = vim.fn.getbufinfo(vim.fn.winbufnr(winid))[1].linecount -- local total_num = vim.fn.getbufinfo(vim.fn.winbufnr(winid))[1].linecount
-- window size of current buffer -- window size of current buffer
local stats = api.nvim_list_uis()[1] local stats = vim.api.nvim_list_uis()[1]
-- local wwidth = stats.width; -- local wwidth = stats.width;
local wheight = stats.height local wheight = stats.height
@ -101,7 +114,7 @@ local function error_marker(result, ctx, config)
return return
end end
if _NG_VT_DIAG_NS == nil then if _NG_VT_DIAG_NS == nil then
_NG_VT_DIAG_NS = api.nvim_create_namespace('navigator_lua_diag') _NG_VT_DIAG_NS = vim.api.nvim_create_namespace('navigator_lua_diag')
end end
local pos = {} local pos = {}
@ -143,7 +156,7 @@ local function error_marker(result, ctx, config)
end end
if not vim.tbl_isempty(pos) then if not vim.tbl_isempty(pos) then
api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1) vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
end end
for _, s in pairs(pos) do for _, s in pairs(pos) do
local hl = 'ErrorMsg' local hl = 'ErrorMsg'
@ -164,7 +177,7 @@ local function error_marker(result, ctx, config)
end end
trace('add pos', s, bufnr) trace('add pos', s, bufnr)
api.nvim_buf_set_extmark( vim.api.nvim_buf_set_extmark(
bufnr, bufnr,
_NG_VT_DIAG_NS, _NG_VT_DIAG_NS,
l, l,
@ -188,9 +201,9 @@ local diag_hdlr = function(err, result, ctx, config)
return return
end end
local mode = api.nvim_get_mode().mode local mode = vim.api.nvim_get_mode().mode
if mode ~= 'n' and config.update_in_insert == false then if mode ~= 'n' and config.update_in_insert == false then
trace('skip sign update in insert mode') log('skip sign update in insert mode')
end end
local cwd = vim.loop.cwd() local cwd = vim.loop.cwd()
local ft = vim.bo.filetype local ft = vim.bo.filetype
@ -226,18 +239,14 @@ local diag_hdlr = function(err, result, ctx, config)
item.uri = uri item.uri = uri
-- trace(item) -- trace(item)
local head = _NgConfigValues.icons.diagnostic_head local head = _NgConfigValues.icons.diagnostic_head
if v.severity then if v.severity == 1 then
if v.severity == 1 then head = _NgConfigValues.icons.diagnostic_head_severity_1
head = _NgConfigValues.icons.diagnostic_head_severity_1 end
end if v.severity == 2 then
if v.severity == 2 then head = _NgConfigValues.icons.diagnostic_head_severity_2
head = _NgConfigValues.icons.diagnostic_head_severity_2 end
end if v.severity > 2 then
if v.severity > 2 then head = _NgConfigValues.icons.diagnostic_head_severity_3
head = _NgConfigValues.icons.diagnostic_head_severity_3
end
else
v.severity = 2
end end
if v.relatedInformation and v.relatedInformation[1] then if v.relatedInformation and v.relatedInformation[1] then
local info = v.relatedInformation[1] local info = v.relatedInformation[1]
@ -250,7 +259,7 @@ local diag_hdlr = function(err, result, ctx, config)
end end
end end
local bufnr1 = vim.uri_to_bufnr(uri) local bufnr1 = vim.uri_to_bufnr(uri)
local loaded = api.nvim_buf_is_loaded(bufnr1) local loaded = vim.api.nvim_buf_is_loaded(bufnr1)
if _NgConfigValues.diagnostic_load_files then if _NgConfigValues.diagnostic_load_files then
-- print('load buffers') -- print('load buffers')
if not loaded then if not loaded then
@ -258,7 +267,7 @@ local diag_hdlr = function(err, result, ctx, config)
end end
local pos = v.range.start local pos = v.range.start
local row = pos.line local row = pos.line
local line = (api.nvim_buf_get_lines(bufnr1, row, row + 1, false) or { '' })[1] local line = (vim.api.nvim_buf_get_lines(bufnr1, row, row + 1, false) or { '' })[1]
if line ~= nil then if line ~= nil then
item.text = head .. line .. _NgConfigValues.icons.diagnostic_head_description .. v.message item.text = head .. line .. _NgConfigValues.icons.diagnostic_head_description .. v.message
else else
@ -292,7 +301,7 @@ local diag_hdlr = function(err, result, ctx, config)
marker(result, ctx, config) marker(result, ctx, config)
else else
trace('great, no diag errors') trace('great, no diag errors')
api.nvim_buf_clear_namespace(0, _NG_VT_DIAG_NS, 0, -1) vim.api.nvim_buf_clear_namespace(0, _NG_VT_DIAG_NS, 0, -1)
_NG_VT_DIAG_NS = nil _NG_VT_DIAG_NS = nil
end end
end end
@ -303,56 +312,24 @@ end
-- end -- end
local M = {} local M = {}
function M.setup()
if diagnostic_cfg ~= nil and diagnostic_cfg.float ~= nil then diagnostic_cfg.virtual_text = _NgConfigValues.lsp.diagnostic.virtual_text
return if type(_NgConfigValues.lsp.diagnostic.virtual_text) == 'table' then
end diagnostic_cfg.virtual_text.prefix = _NgConfigValues.icons.diagnostic_virtual_text
diagnostic_cfg = {
-- Enable underline, use default values
underline = _NgConfigValues.lsp.diagnostic.underline,
-- Enable virtual
-- Use a function to dynamically turn signs off
-- and on, using buffer local variables
signs = true,
update_in_insert = _NgConfigValues.lsp.diagnostic.update_in_insert or false,
severity_sort = _NgConfigValues.lsp.diagnostic.severity_sort,
float = {
focusable = false,
style = 'minimal',
border = 'rounded',
source = 'always',
header = '',
prefix = '',
},
}
diagnostic_cfg.virtual_text = _NgConfigValues.lsp.diagnostic.virtual_text
if type(_NgConfigValues.lsp.diagnostic.virtual_text) == 'table' then
diagnostic_cfg.virtual_text.prefix = _NgConfigValues.icons.diagnostic_virtual_text
end
-- vim.lsp.handlers["textDocument/publishDiagnostics"]
M.diagnostic_handler = vim.lsp.with(diag_hdlr, diagnostic_cfg)
vim.diagnostic.config(diagnostic_cfg)
if _NgConfigValues.lsp.diagnostic_scrollbar_sign then
api.nvim_create_autocmd({ 'WinScrolled' }, {
group = api.nvim_create_augroup('NGWinScrolledGroup', {}),
pattern = '*',
callback = function()
require('navigator.diagnostics').update_err_marker()
end,
})
end
end end
-- vim.lsp.handlers["textDocument/publishDiagnostics"]
M.diagnostic_handler = vim.lsp.with(diag_hdlr, diagnostic_cfg)
vim.diagnostic.config(diagnostic_cfg)
local function clear_diag_VT(bufnr) -- important for clearing out when no more errors local function clear_diag_VT(bufnr) -- important for clearing out when no more errors
bufnr = bufnr or api.nvim_get_current_buf() bufnr = bufnr or vim.api.nvim_get_current_buf()
log(bufnr, _NG_VT_DIAG_NS) log(bufnr, _NG_VT_DIAG_NS)
if _NG_VT_DIAG_NS == nil then if _NG_VT_DIAG_NS == nil then
return return
end end
api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1) vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
_NG_VT_DIAG_NS = nil _NG_VT_DIAG_NS = nil
end end
@ -394,15 +371,15 @@ M.show_buf_diagnostics = function()
end end
trace('new buffer', listview.bufnr) trace('new buffer', listview.bufnr)
if listview.bufnr then if listview.bufnr then
api.nvim_buf_add_highlight(listview.bufnr, -1, 'Title', 0, 0, -1) vim.api.nvim_buf_add_highlight(listview.bufnr, -1, 'Title', 0, 0, -1)
end end
end end
end end
end end
-- set loc list win -- set loc list win
M.set_diag_loclist = function(bufnr) M.set_diag_loclist = function()
bufnr = bufnr or api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]]) local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]])
if diag_cnt == 0 then if diag_cnt == 0 then
log('great, no errors!') log('great, no errors!')
@ -422,7 +399,7 @@ M.set_diag_loclist = function(bufnr)
if diagnostic.set_loclist then if diagnostic.set_loclist then
diagnostic.set_loclist(cfg) diagnostic.set_loclist(cfg)
else else
cfg.namespaces = diagnostic.get_namespaces() cfg.namespaces = diagnostic.get_namespace(nil)
diagnostic.setloclist(cfg) diagnostic.setloclist(cfg)
end end
else else
@ -438,7 +415,7 @@ function M.update_err_marker()
-- nothing to update -- nothing to update
return return
end end
local bufnr = api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
local diag_cnt = get_count(bufnr, [[Error]]) local diag_cnt = get_count(bufnr, [[Error]])
+ get_count(bufnr, [[Warning]]) + get_count(bufnr, [[Warning]])
@ -447,12 +424,12 @@ function M.update_err_marker()
-- redraw -- redraw
if diag_cnt == 0 and _NG_VT_DIAG_NS ~= nil then if diag_cnt == 0 and _NG_VT_DIAG_NS ~= nil then
api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1) vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
trace('no errors') trace('no errors')
return return
end end
api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1) vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
local errors = diagnostic.get(bufnr) local errors = diagnostic.get(bufnr)
if #errors == 0 then if #errors == 0 then
trace('no errors', errors) trace('no errors', errors)
@ -466,40 +443,30 @@ function M.update_err_marker()
marker(result, { bufnr = bufnr, method = 'textDocument/publishDiagnostics' }) marker(result, { bufnr = bufnr, method = 'textDocument/publishDiagnostics' })
end end
function M.get_line_diagnostic() if _NgConfigValues.lsp.diagnostic_scrollbar_sign then
local lnum = api.nvim_win_get_cursor(0)[1] - 1 vim.cmd([[autocmd WinScrolled * lua require'navigator.diagnostics'.update_err_marker()]])
local diags = diagnostic.get(api.nvim_get_current_buf(), { lnum = lnum }) end
table.sort(diags, function(diag1, diag2) function M.get_line_diagnostic()
return diag1.severity < diag2.severity local lnum = vim.api.nvim_win_get_cursor(0)[1] - 1
end) return diagnostic.get(vim.api.nvim_get_current_buf(), { lnum = lnum })
return diags
end end
function M.show_diagnostics(pos) function M.show_diagnostics(pos)
local bufnr = api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
local lnum = vim.api.nvim_win_get_cursor(0)[1] - 1
local lnum, col = unpack(api.nvim_win_get_cursor(0)) local opt = { border = 'single' }
lnum = lnum - 1 if diagnostic.open_float and type(diagnostic.open_float) == 'function' then
local opt = { border = 'single', severity_sort = true }
if pos ~= nil and type(pos) == 'number' then
opt.scope = 'buffer'
else
if pos == true then if pos == true then
opt.scope = 'cursor' opt.scope = 'cursor'
else else
opt.scope = 'line' opt.scope = 'line'
end end
diagnostic.open_float(bufnr, opt)
else
-- deprecated
diagnostic.show_line_diagnostics(opt, bufnr, lnum)
end end
local diags = M.get_line_diagnostic()
if diags == nil or next(diags) == nil then
return
end
local diag1 = diags[1]
opt.offset_x = -1 * (col - diag1.col)
diagnostic.open_float(bufnr, opt)
end end
function M.treesitter_and_diag_panel() function M.treesitter_and_diag_panel()
@ -509,7 +476,7 @@ function M.treesitter_and_diag_panel()
local results = diagnostic_list[ft] local results = diagnostic_list[ft]
log(diagnostic_list, ft) log(diagnostic_list, ft)
local bufnr = api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
local p = Panel:new({ local p = Panel:new({
header = 'treesitter', header = 'treesitter',
render = function(b) render = function(b)
@ -519,8 +486,7 @@ function M.treesitter_and_diag_panel()
}) })
p:add_section({ p:add_section({
header = 'diagnostic', header = 'diagnostic',
render = function(buf) render = function(bufnr)
log(buf, diagnostic)
if diagnostic_list[ft] ~= nil then if diagnostic_list[ft] ~= nil then
local display_items = {} local display_items = {}
for _, client_items in pairs(results) do for _, client_items in pairs(results) do
@ -541,9 +507,7 @@ function M.treesitter_and_diag_panel()
end end
function M.config(cfg) function M.config(cfg)
M.setup()
cfg = cfg or {} cfg = cfg or {}
log('diag config', cfg)
local default_cfg = { local default_cfg = {
underline = true, underline = true,
virtual_text = true, virtual_text = true,

@ -145,6 +145,7 @@ local handle_document_highlight = function(_, result, ctx)
return return
end end
if type(result) ~= 'table' or vim.fn.empty(result) == 1 then if type(result) ~= 'table' or vim.fn.empty(result) == 1 then
log('clear up', result)
vim.lsp.util.buf_clear_references(ctx.bufnr) vim.lsp.util.buf_clear_references(ctx.bufnr)
return return
end end
@ -204,45 +205,29 @@ local function cmd_nohl()
end end
end end
local nav_doc_hl = function(bufnr) local nav_doc_hl = function()
trace('nav_doc_hl', bufnr) local bufnr = vim.api.nvim_get_current_buf()
bufnr = bufnr or vim.api.nvim_get_current_buf()
local ref_params = vim.lsp.util.make_position_params() local ref_params = vim.lsp.util.make_position_params()
vim.lsp.for_each_buffer_client(bufnr, function(client, _, _) vim.lsp.for_each_buffer_client(bufnr, function(client, _, _)
if client.server_capabilities.documentHighlightProvider == true then if client.server_capabilities.documentHighlightProvider == true then
trace('sending doc highlight', client.name, bufnr)
client.request('textDocument/documentHighlight', ref_params, handle_document_highlight, bufnr) client.request('textDocument/documentHighlight', ref_params, handle_document_highlight, bufnr)
end end
end) end)
end end
local function documentHighlight(bufnr) local function documentHighlight()
bufnr = bufnr or api.nvim_get_current_buf() api.nvim_exec(
[[
if _NgConfigValues.lsp.document_highlight == true then augroup lsp_document_highlight
local group_name = string.format('%s%d', 'NGHiGroup', bufnr) autocmd! * <buffer>
local cmd_group = api.nvim_create_augroup(group_name, {}) autocmd CursorHold,CursorHoldI <buffer> lua require('navigator.dochighlight').nav_doc_hl()
api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()
group = cmd_group, augroup END
buffer = bufnr, ]],
desc = 'document highlight', false
callback = function() )
require('navigator.dochighlight').nav_doc_hl(bufnr)
end,
})
api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, {
group = cmd_group,
buffer = bufnr,
desc = 'clear document highlight',
callback = function()
vim.lsp.util.buf_clear_references(bufnr)
end,
})
end
vim.lsp.handlers['textDocument/documentHighlight'] = function(err, result, ctx) vim.lsp.handlers['textDocument/documentHighlight'] = function(err, result, ctx)
local buffer = ctx.bufnr or api.nvim_get_current_buf() local bufnr = ctx.bufnr or api.nvim_get_current_buf()
if err then if err then
vim.notify(err, vim.lsp.log_levels.ERROR) vim.notify(err, vim.lsp.log_levels.ERROR)
return return
@ -251,18 +236,19 @@ local function documentHighlight(bufnr)
return return
end end
trace('dochl', result) trace('dochl', result)
bufnr = bufnr or 0
if type(result) ~= 'table' then if type(result) ~= 'table' then
vim.lsp.util.buf_clear_references(buffer) vim.lsp.util.buf_clear_references(bufnr)
return return
end end
local client_id = ctx.client_id local client_id = ctx.client_id
vim.lsp.util.buf_clear_references(buffer) vim.lsp.util.buf_clear_references(bufnr)
vim.lsp.util.buf_highlight_references(buffer, result, util.encoding(client_id)) vim.lsp.util.buf_highlight_references(bufnr, result, util.encoding(client_id))
table.sort(result, function(a, b) table.sort(result, function(a, b)
return before(a.range, b.range) return before(a.range, b.range)
end) end)
references[buffer] = result references[bufnr] = result
add_locs(buffer, result) add_locs(bufnr, result)
end end
end end

@ -28,14 +28,19 @@ function M.on_attach()
end end
function M.setup_plugin() function M.setup_plugin()
local cmd_group = api.nvim_create_augroup('NGFoldGroup', {}) api.nvim_command('augroup FoldingCommand')
api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost' }, { api.nvim_command('autocmd! * <buffer>')
group = cmd_group, api.nvim_command("autocmd BufEnter <buffer> lua require'navigator.foldlsp'.update_folds()")
pattern = '*', api.nvim_command("autocmd BufWritePost <buffer> lua require'navigator.foldlsp'.update_folds()")
callback = function() api.nvim_command('augroup end')
require('navigator.foldlsp').update_folds()
end, -- vim.cmd([[
}) --
-- function! folding_nvim#foldexpr()
-- return luaeval(printf('require"navigator.foldlsp".get_fold_indic(%d)', v:lnum))
-- endfunction
--
-- ]])
local clients = vim.lsp.buf_get_clients(0) local clients = vim.lsp.buf_get_clients(0)

@ -21,12 +21,7 @@ function NG_custom_fold_text()
local line = vim.fn.getline(vim.v.foldstart) local line = vim.fn.getline(vim.v.foldstart)
local line_count = vim.v.foldend - vim.v.foldstart + 1 local line_count = vim.v.foldend - vim.v.foldstart + 1
-- log("" .. line .. " // " .. line_count .. " lines") -- log("" .. line .. " // " .. line_count .. " lines")
local ss, se = line:find('^%s*') return '' .. line .. ': ' .. line_count .. ' lines'
local spaces = line:sub(ss, se)
local tabspace = string.rep(' ', vim.o.tabstop)
spaces = spaces:gsub('\t', tabspace)
line = line:gsub('^%s*(.-)%s*$', '%1')
return spaces .. '' .. line .. ': ' .. line_count .. ' lines'
end end
vim.opt.foldtext = NG_custom_fold_text() vim.opt.foldtext = NG_custom_fold_text()
@ -35,6 +30,11 @@ vim.opt.fillchars = { eob = '-', fold = ' ' }
vim.opt.viewoptions:remove('options') vim.opt.viewoptions:remove('options')
function M.setup_fold() function M.setup_fold()
if not parsers.has_parser() then
vim.notify('treesitter folding not enabled for current file', vim.lsp.log_levels.WARN)
return
end
log('setup treesitter folding')
api.nvim_command('augroup FoldingCommand') api.nvim_command('augroup FoldingCommand')
api.nvim_command('autocmd! * <buffer>') api.nvim_command('autocmd! * <buffer>')
api.nvim_command('augroup end') api.nvim_command('augroup end')
@ -43,27 +43,10 @@ function M.setup_fold()
vim.opt.viewoptions:remove('options') vim.opt.viewoptions:remove('options')
local current_window = api.nvim_get_current_win() local current_window = api.nvim_get_current_win()
if not parsers.has_parser() then
api.nvim_win_set_option(current_window, 'foldmethod', 'indent')
log('fallback to indent folding')
return
end
log('setup treesitter folding')
api.nvim_win_set_option(current_window, 'foldmethod', 'expr') api.nvim_win_set_option(current_window, 'foldmethod', 'expr')
api.nvim_win_set_option(current_window, 'foldexpr', 'folding#ngfoldexpr()') api.nvim_win_set_option(current_window, 'foldexpr', 'folding#ngfoldexpr()')
end end
local function get_fold_level(levels, lnum)
local prev_l = levels[lnum]
local prev_ln
if prev_l:find('>') then
prev_ln = tonumber(prev_l:sub(2))
else
prev_ln = tonumber(prev_l)
end
return prev_ln
end
-- This is cached on buf tick to avoid computing that multiple times -- This is cached on buf tick to avoid computing that multiple times
-- Especially not for every line in the file when `zx` is hit -- Especially not for every line in the file when `zx` is hit
local folds_levels = tsutils.memoize_by_buf_tick(function(bufnr) local folds_levels = tsutils.memoize_by_buf_tick(function(bufnr)
@ -119,39 +102,27 @@ local folds_levels = tsutils.memoize_by_buf_tick(function(bufnr)
prev_stop = stop prev_stop = stop
end end
end end
trace(start_counts)
trace(stop_counts)
local levels = {} local levels = {}
local current_level = 0 local current_level = 0
-- We now have the list of fold opening and closing, fill the gaps and mark where fold start -- We now have the list of fold opening and closing, fill the gaps and mark where fold start
local pre_node
for lnum = 0, api.nvim_buf_line_count(bufnr) do for lnum = 0, api.nvim_buf_line_count(bufnr) do
local node, _ = get_node_at_line(lnum + 1) local node, _ = get_node_at_line(lnum + 1)
-- log(lnum, node:type())
local comment = node:type() == 'comment' local comment = node:type() == 'comment'
local next_node, _ = get_node_at_line(lnum + 1)
local next_comment = node and node:type() == 'comment'
local last_trimmed_level = trim_level(current_level) local last_trimmed_level = trim_level(current_level)
current_level = current_level + (start_counts[lnum] or 0) current_level = current_level + (start_counts[lnum] or 0)
local trimmed_level = trim_level(current_level) local trimmed_level = trim_level(current_level)
local current_level2 = current_level - (stop_counts[lnum] or 0) current_level = current_level - (stop_counts[lnum] or 0)
local next_trimmed_level = trim_level(current_level2) local next_trimmed_level = trim_level(current_level)
trace(lnum, node:type(), node, last_trimmed_level, trimmed_level, next_trimmed_level)
if comment then if comment then
trace('comment node', trimmed_level) if lnum == 0 or levels[lnum] == tostring(trimmed_level) then
-- if trimmed_level == 0 then levels[lnum + 1] = '>' .. tostring(trimmed_level + 1) -- allow comment fold independtly
-- trimmed_level = 1 else
-- end levels[lnum + 1] = tostring(trimmed_level + 1) -- allow comment fold independtly
levels[lnum + 1] = tostring(trimmed_level + 2)
if pre_node and pre_node:type() ~= 'comment' then
levels[lnum + 1] = '>' .. tostring(trimmed_level + 2)
end
if next_node and next_node:type() ~= 'comment' then
levels[lnum + 1] = tostring(trimmed_level + 1)
end end
else else
-- Determine if it's the start/end of a fold -- Determine if it's the start/end of a fold
@ -162,59 +133,28 @@ local folds_levels = tsutils.memoize_by_buf_tick(function(bufnr)
-- ( \n ( \n ) \n ( \n ) \n ) -- ( \n ( \n ) \n ( \n ) \n )
-- If it did have such a mechansim, (trimmed_level - last_trimmed_level) -- If it did have such a mechansim, (trimmed_level - last_trimmed_level)
-- would be the correct number of starts to pass on. -- would be the correct number of starts to pass on.
levels[lnum + 1] = tostring(trimmed_level)
if trimmed_level - last_trimmed_level > 0 then if trimmed_level - last_trimmed_level > 0 then
if levels[lnum + 1] ~= '>' .. tostring(trimmed_level) then levels[lnum + 1] = tostring(trimmed_level) -- hack
levels[lnum + 1] = tostring(trimmed_level) -- hack do not fold current line as it is first in fold range levels[lnum + 2] = '>' .. tostring(trimmed_level + 1) -- dirty hack
end elseif trimmed_level - next_trimmed_level > 0 then
levels[lnum + 2] = '>' .. tostring(trimmed_level + 1) -- dirty hack fold start from next line
trace('fold start')
elseif trimmed_level - next_trimmed_level > 0 then -- last line in fold range
-- Ending marks tend to confuse vim more than it helps, particularly when -- Ending marks tend to confuse vim more than it helps, particularly when
-- the fold level changes by at least 2; we can uncomment this if -- the fold level changes by at least 2; we can uncomment this if
-- vim's behavior gets fixed. -- vim's behavior gets fixed.
if lnum ~= 0 then
trace('fold end') levels[lnum] = tostring(trimmed_level + 1)
if levels[lnum + 1] then
trace('already set reset as fold is ending', levels[lnum + 1])
levels[lnum + 1] = tostring(trimmed_level + 1)
else
local prev_ln = get_fold_level(levels, lnum) - 1
if prev_ln == 0 then
prev_ln = 1
end
levels[lnum + 1] = tostring(prev_ln)
end end
-- levels[lnum + 1] = tostring(trimmed_level + 1) levels[lnum + 1] = tostring(trimmed_level)
-- else
current_level = current_level - 1
else else
trace('same') -- if levels[lnum + 1] == nil then
if pre_node and pre_node:type() == 'comment' then levels[lnum + 1] = tostring(trimmed_level + 1)
local prev_ln = get_fold_level(levels, lnum) - 1 -- end
levels[lnum + 1] = tostring(prev_ln)
else
local n = math.max(trimmed_level, 1)
if lnum > 1 then
if levels[lnum + 1] then
trace('already set', levels[lnum + 1])
else
local prev_l = levels[lnum]
if prev_l:find('>') then
levels[lnum + 1] = prev_l:sub(2)
else
levels[lnum + 1] = prev_l
end
end
else
levels[lnum + 1] = tostring(n)
end
end
end end
trace(levels)
end end
pre_node = node
end end
trace(levels) trace(levels)
return levels return levels
end) end)
@ -225,7 +165,7 @@ function M.get_fold_indic(lnum)
local buf = api.nvim_get_current_buf() local buf = api.nvim_get_current_buf()
local shown = false local shown = false
for i = 1, vim.fn.tabpagenr('$') do for i = 1, vim.fn.tabpagenr('$') do
for _, value in pairs(vim.fn.tabpagebuflist(i)) do for key, value in pairs(vim.fn.tabpagebuflist(i)) do
if value == buf then if value == buf then
shown = true shown = true
end end
@ -236,7 +176,7 @@ function M.get_fold_indic(lnum)
end end
local levels = folds_levels(buf) or {} local levels = folds_levels(buf) or {}
-- trace(lnum, levels[lnum]) -- TODO: comment it out in master -- log(lnum, levels[lnum]) -- TODO: comment it out in master
return levels[lnum] or '0' return levels[lnum] or '0'
end end

@ -1,6 +1,5 @@
-- https://github.com/wention/dotfiles/blob/master/.config/nvim/lua/config/lsp.lua -- https://github.com/wention/dotfiles/blob/master/.config/nvim/lua/config/lsp.lua
-- https://github.com/lukas-reineke/dotfiles/blob/master/vim/lua/lsp/handlers.lua -- https://github.com/lukas-reineke/dotfiles/blob/master/vim/lua/lsp/handlers.lua
return { return {
format_hdl = function(err, result, ctx, _) -- FIXME: bufnr is nil format_hdl = function(err, result, ctx, _) -- FIXME: bufnr is nil
if err ~= nil or result == nil then if err ~= nil or result == nil then
@ -32,18 +31,4 @@ return {
end end
end, 100) end, 100)
end, end,
range_format = function()
local old_func = vim.go.operatorfunc
_G.op_func_formatting = function()
print('formatting range')
local start = vim.api.nvim_buf_get_mark(0, '[')
local finish = vim.api.nvim_buf_get_mark(0, ']')
print(vim.inspect(start), vim.inspect(finish))
vim.lsp.buf.range_formatting({}, start, finish)
vim.go.operatorfunc = old_func
_G.op_func_formatting = nil
end
vim.go.operatorfunc = 'v:lua.op_func_formatting'
vim.api.nvim_feedkeys('g@', 'n', false)
end,
} }

@ -1,6 +1,6 @@
local M = {} local M = {}
-- local ListView = require('guihua.listview') local ListView = require('guihua.listview')
-- local TextView = require('guihua.textview') local TextView = require('guihua.textview')
local util = require('navigator.util') local util = require('navigator.util')
local log = util.log local log = util.log
local trace = require('navigator.util').trace local trace = require('navigator.util').trace
@ -16,7 +16,7 @@ function M.new_list_view(opts)
local winnr = active_list_view.win local winnr = active_list_view.win
local bufnr = active_list_view.buf local bufnr = active_list_view.buf
if bufnr and api.nvim_buf_is_valid(bufnr) and winnr and api.nvim_win_is_valid(winnr) then if bufnr and vim.api.nvim_buf_is_valid(bufnr) and winnr and vim.api.nvim_win_is_valid(winnr) then
log('list view already present') log('list view already present')
return active_list_view return active_list_view
end end
@ -35,14 +35,6 @@ function M.new_list_view(opts)
opts.border = config.border or 'shadow' opts.border = config.border or 'shadow'
if vim.fn.hlID('TelescopePromptBorder') > 0 then if vim.fn.hlID('TelescopePromptBorder') > 0 then
opts.border_hl = 'TelescopePromptBorder' opts.border_hl = 'TelescopePromptBorder'
opts.list_hl = 'TelescopeNormal'
opts.bg_hl = 'TelescopePreviewNormal'
opts.sel_hl = 'TelescopeSelection'
else
opts.border_hl = 'FloatBorder'
opts.bg_hl = 'NormalFloat'
opts.list_hl = 'NormalFloat'
opts.sel_hl = 'PmenuSel'
end end
if not items or vim.tbl_isempty(items) then if not items or vim.tbl_isempty(items) then
log('empty data return') log('empty data return')

@ -100,7 +100,7 @@ hierarchy_handler = function(dir, handler, show, api, err, result, ctx, cfg)
trace(dir, handler, api, show, err, result, ctx, cfg) trace(dir, handler, api, show, err, result, ctx, cfg)
ctx = ctx or {} -- can be nil if it is async call ctx = ctx or {} -- can be nil if it is async call
cfg = cfg or {} cfg = cfg or {}
local opts = ctx.opts or {} opts = ctx.opts or {}
vim.validate({ handler = { handler, 'function' }, show = { show, 'function' }, api = { api, 'string' } }) vim.validate({ handler = { handler, 'function' }, show = { show, 'function' }, api = { api, 'string' } })
local bufnr = ctx.bufnr or vim.api.nvim_get_current_buf() local bufnr = ctx.bufnr or vim.api.nvim_get_current_buf()
assert(next(vim.lsp.buf_get_clients(bufnr)), 'Must have a client running to use lsp hierarchy') assert(next(vim.lsp.buf_get_clients(bufnr)), 'Must have a client running to use lsp hierarchy')
@ -142,12 +142,11 @@ local function display_panel(args)
local Panel = require('guihua.panel') local Panel = require('guihua.panel')
local bufnr = args.bufnr or vim.api.nvim_get_current_buf() local bufnr = args.bufnr or vim.api.nvim_get_current_buf()
-- local ft = args.ft or vim.api.nvim_buf_get_option(bufnr, 'buftype') local ft = args.ft or vim.api.nvim_buf_get_option(bufnr, 'buftype')
local items = args.items local items = args.items
local p = Panel:new({ local p = Panel:new({
header = args.header or 'Call Hierarchy', header = args.header or 'Call Hierarchy',
render = function(buf) render = function(bufnr)
log(buf)
return items return items
end, end,
fold = function(panel, node) fold = function(panel, node)

@ -1,6 +1,7 @@
return { return {
init = function() init = function()
local loader = nil local loader = nil
local packer_plugins = packer_plugins or nil -- suppress warnings
local log = require('navigator.util').log local log = require('navigator.util').log
-- packer only -- packer only
if packer_plugins ~= nil then -- packer install if packer_plugins ~= nil then -- packer install
@ -50,7 +51,7 @@ return {
end, end,
load = function(plugin_name, path) load = function(plugin_name, path)
local loader = nil local loader = nil
packer_plugins = packer_plugins or nil -- suppress warnings local packer_plugins = packer_plugins or nil -- suppress warnings
-- packer only -- packer only
if packer_plugins ~= nil then -- packer install if packer_plugins ~= nil then -- packer install
local lazy_plugins = {} local lazy_plugins = {}

@ -4,7 +4,7 @@ local lsp = require('vim.lsp')
local util = require('navigator.util') local util = require('navigator.util')
local log = util.log local log = util.log
local trace = util.trace local trace = util.trace
_NG_Attached = {}
local M = {} local M = {}
M.on_attach = function(client, bufnr) M.on_attach = function(client, bufnr)
@ -23,7 +23,6 @@ M.on_attach = function(client, bufnr)
log('attaching: ', bufnr, client.name, uri) log('attaching: ', bufnr, client.name, uri)
trace(client) trace(client)
_NG_Attached[client.name] = true
-- add highlight for Lspxxx -- add highlight for Lspxxx
require('navigator.lspclient.highlight').add_highlight() require('navigator.lspclient.highlight').add_highlight()
@ -36,16 +35,9 @@ M.on_attach = function(client, bufnr)
}) })
if client.server_capabilities.documentHighlightProvider == true then if client.server_capabilities.documentHighlightProvider == true then
trace('attaching doc highlight: ', bufnr, client.name) require('navigator.dochighlight').documentHighlight()
vim.defer_fn(function()
require('navigator.dochighlight').documentHighlight(bufnr)
end, 50) -- allow a bit time for it to settle down
else
log('skip doc highlight: ', bufnr, client.name)
end end
require('navigator.lspclient.lspkind').init() require('navigator.lspclient.lspkind').init()
local config = require('navigator').config_values() local config = require('navigator').config_values()
@ -70,13 +62,9 @@ M.on_attach = function(client, bufnr)
if _NgConfigValues.lsp.code_action.enable then if _NgConfigValues.lsp.code_action.enable then
if client.server_capabilities.codeActionProvider and client.name ~= 'null-ls' then if client.server_capabilities.codeActionProvider and client.name ~= 'null-ls' then
log('code action enabled for client', client.server_capabilities.codeActionProvider) log('code action enabled for client', client.server_capabilities.codeActionProvider)
api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { api.nvim_command('augroup NCodeAction')
group = api.nvim_create_augroup('NGCodeActGroup_'..tostring(bufnr), {}), vim.cmd([[autocmd CursorHold,CursorHoldI <buffer> lua require'navigator.codeAction'.code_action_prompt()]])
buffer = bufnr, api.nvim_command('augroup end')
callback = function()
require('navigator.codeAction').code_action_prompt(bufnr)
end,
})
end end
end end
end end

@ -4,7 +4,6 @@ local log = ng_util.log
local trace = ng_util.trace local trace = ng_util.trace
local empty = ng_util.empty local empty = ng_util.empty
local warn = ng_util.warn local warn = ng_util.warn
local vfn = vim.fn
_NG_Loaded = {} _NG_Loaded = {}
_LoadedFiletypes = {} _LoadedFiletypes = {}
@ -42,7 +41,6 @@ local disabled_ft = {
'windline', 'windline',
'notify', 'notify',
'nofile', 'nofile',
'help',
'', '',
} }
-- local cap = vim.lsp.protocol.make_client_capabilities() -- local cap = vim.lsp.protocol.make_client_capabilities()
@ -65,45 +63,322 @@ local luadevcfg = {
} }
local luadev = {} local luadev = {}
local user_luadev = _NgConfigValues.lsp['lua-dev']
if user_luadev then
luadev = vim.tbl_deep_extend('force', luadev, user_luadev)
end
require('navigator.lazyloader').load('lua-dev.nvim', 'folke/lua-dev.nvim') require('navigator.lazyloader').load('lua-dev.nvim', 'folke/lua-dev.nvim')
if _NgConfigValues.lsp_installer then if _NgConfigValues.lsp_installer then
require('navigator.lazyloader').load('nvim-lsp-installer', 'williamboman/nvim-lsp-installer') require('navigator.lazyloader').load('nvim-lsp-installer', 'williamboman/nvim-lsp-installer')
end end
local ok, l = pcall(require, 'lua-dev')
if ok and l then
luadev = l.setup(luadevcfg)
end
local function add(lib)
for _, p in pairs(vim.fn.expand(lib, false, true)) do
p = vim.loop.fs_realpath(p)
if p then
library[p] = true
end
end
end
if _NgConfigValues.mason then -- add runtime
require('navigator.lazyloader').load('mason.nvim', 'williamboman/mason.nvim') add('$VIMRUNTIME')
require('navigator.lazyloader').load('mason-lspconfig.nvim', 'williamboman/mason-lspconfig.nvim')
-- add your config
-- local home = vim.fn.expand("$HOME")
add(vim.fn.stdpath('config'))
-- add plugins it may be very slow to add all in path
-- if vim.fn.isdirectory(home .. "/.config/share/nvim/site/pack/packer") then
-- add(home .. "/.local/share/nvim/site/pack/packer/opt/*")
-- add(home .. "/.local/share/nvim/site/pack/packer/start/*")
-- end
library[vim.fn.expand('$VIMRUNTIME/lua')] = true
library[vim.fn.expand('$VIMRUNTIME/lua/vim')] = true
library[vim.fn.expand('$VIMRUNTIME/lua/vim/lsp')] = true
-- [vim.fn.expand("~/repos/nvim/lua")] = true
-- TODO remove onece PR #944 merged to lspconfig
local path_sep = require('navigator.util').path_sep()
local strip_dir_pat = path_sep .. '([^' .. path_sep .. ']+)$'
local strip_sep_pat = path_sep .. '$'
local dirname = function(pathname)
if not pathname or #pathname == 0 then
return
end
local result = pathname:gsub(strip_sep_pat, ''):gsub(strip_dir_pat, '')
if #result == 0 then
return '/'
end
return result
end end
-- TODO end
local setups = {
clojure_lsp = {
root_dir = function(fname)
return util.root_pattern('deps.edn', 'build.boot', 'project.clj', 'shadow-cljs.edn', 'bb.edn', '.git')(fname)
or util.path.dirname(fname)
end,
on_attach = on_attach,
filetypes = { 'clojure', 'edn' },
message_level = vim.lsp.protocol.MessageType.error,
cmd = { 'clojure-lsp' },
},
elixirls = {
on_attach = on_attach,
filetypes = { 'elixir', 'eelixir' },
cmd = { 'elixir-ls' },
message_level = vim.lsp.protocol.MessageType.error,
settings = {
elixirLS = {
dialyzerEnabled = true,
fetchDeps = false,
},
},
root_dir = function(fname)
return util.root_pattern('mix.exs', '.git')(fname) or util.path.dirname(fname)
end,
},
gopls = {
on_attach = on_attach,
-- capabilities = cap,
filetypes = { 'go', 'gomod', 'gohtmltmpl', 'gotexttmpl' },
message_level = vim.lsp.protocol.MessageType.Error,
cmd = {
'gopls', -- share the gopls instance if there is one already
'-remote=auto', --[[ debug options ]] --
-- "-logfile=auto",
-- "-debug=:0",
'-remote.debug=:0',
-- "-rpc.trace",
},
flags = { allow_incremental_sync = true, debounce_text_changes = 1000 },
settings = {
gopls = {
-- more settings: https://github.com/golang/tools/blob/master/gopls/doc/settings.md
-- flags = {allow_incremental_sync = true, debounce_text_changes = 500},
-- not supported
analyses = { unusedparams = true, unreachable = false },
codelenses = {
generate = true, -- show the `go generate` lens.
gc_details = true, -- // Show a code lens toggling the display of gc's choices.
test = true,
tidy = true,
},
usePlaceholders = true,
completeUnimported = true,
staticcheck = true,
matcher = 'fuzzy',
diagnosticsDelay = '500ms',
experimentalWatchedFileDelay = '1000ms',
symbolMatcher = 'fuzzy',
gofumpt = false, -- true, -- turn on for new repos, gofmpt is good but also create code turmoils
buildFlags = { '-tags', 'integration' },
-- buildFlags = {"-tags", "functional"}
},
},
root_dir = function(fname)
return util.root_pattern('go.mod', '.git')(fname) or dirname(fname) -- util.path.dirname(fname)
end,
},
clangd = {
flags = { allow_incremental_sync = true, debounce_text_changes = 500 },
cmd = {
'clangd',
'--background-index',
'--suggest-missing-includes',
'--clang-tidy',
'--header-insertion=iwyu',
'--clang-tidy-checks=-*,llvm-*,clang-analyzer-*',
'--cross-file-rename',
},
filetypes = { 'c', 'cpp', 'objc', 'objcpp' },
on_attach = function(client, bufnr)
client.server_capabilities.documentFormattingProvider = client.server_capabilities.documentFormattingProvider
or true
on_attach(client, bufnr)
end,
},
rust_analyzer = {
root_dir = function(fname)
return util.root_pattern('Cargo.toml', 'rust-project.json', '.git')(fname) or util.path.dirname(fname)
end,
filetypes = { 'rust' },
message_level = vim.lsp.protocol.MessageType.error,
on_attach = on_attach,
settings = {
['rust-analyzer'] = {
assist = { importMergeBehavior = 'last', importPrefix = 'by_self' },
cargo = { loadOutDirsFromCheck = true },
procMacro = { enable = true },
},
},
flags = { allow_incremental_sync = true, debounce_text_changes = 500 },
},
sqls = {
filetypes = { 'sql' },
on_attach = function(client, _)
client.server_capabilities.executeCommandProvider = client.server_capabilities.documentFormattingProvider or true
highlight.diagnositc_config_sign()
require('sqls').setup({ picker = 'telescope' }) -- or default
end,
flags = { allow_incremental_sync = true, debounce_text_changes = 500 },
settings = {
cmd = { 'sqls', '-config', '$HOME/.config/sqls/config.yml' },
-- alterantively:
-- connections = {
-- {
-- driver = 'postgresql',
-- datasourcename = 'host=127.0.0.1 port=5432 user=postgres password=password dbname=user_db sslmode=disable',
-- },
-- },
},
},
sumneko_lua = {
cmd = { 'lua-language-server' },
filetypes = { 'lua' },
on_attach = on_attach,
flags = { allow_incremental_sync = true, debounce_text_changes = 500 },
settings = {
Lua = {
runtime = {
-- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
version = 'LuaJIT',
},
diagnostics = {
enable = true,
-- Get the language server to recognize the `vim` global
globals = { 'vim', 'describe', 'it', 'before_each', 'after_each', 'teardown', 'pending' },
},
completion = { callSnippet = 'Both' },
workspace = {
-- Make the server aware of Neovim runtime files
library = library,
maxPreload = 2000,
preloadFileSize = 40000,
},
telemetry = { enable = false },
},
},
on_new_config = function(cfg, root)
local libs = vim.tbl_deep_extend('force', {}, library)
libs[root] = nil
cfg.settings.Lua.workspace.library = libs
return cfg
end,
},
pyright = {
on_attach = on_attach,
cmd = { 'pyright-langserver', '--stdio' },
filetypes = { 'python' },
flags = { allow_incremental_sync = true, debounce_text_changes = 500 },
settings = {
python = {
formatting = { provider = 'black' },
analysis = {
autoSearchPaths = true,
useLibraryCodeForTypes = true,
diagnosticMode = 'workspace',
},
},
},
},
ccls = {
on_attach = on_attach,
init_options = {
compilationDatabaseDirectory = 'build',
root_dir = [[ util.root_pattern("compile_commands.json", "compile_flags.txt", "CMakeLists.txt", "Makefile", ".git") or util.path.dirname ]],
index = { threads = 2 },
clang = { excludeArgs = { '-frounding-math' } },
},
flags = { allow_incremental_sync = true },
},
jdtls = {
settings = {
java = { signatureHelp = { enabled = true }, contentProvider = { preferred = 'fernflower' } },
},
},
omnisharp = {
cmd = { 'omnisharp', '--languageserver', '--hostPID', tostring(vim.fn.getpid()) },
},
terraformls = {
filetypes = { 'terraform', 'tf' },
},
sourcekit = {
cmd = { 'sourcekit-lsp' },
filetypes = { 'swift' }, -- This is recommended if you have separate settings for clangd.
},
}
local setups = require('navigator.lspclient.clients_default').defaults() setups.sumneko_lua = vim.tbl_deep_extend('force', luadev, setups.sumneko_lua)
local servers = require('navigator.lspclient.servers')
local servers = {
'angularls',
'gopls',
'tsserver',
'flow',
'bashls',
'dockerls',
'julials',
'pylsp',
'pyright',
'jedi_language_server',
'jdtls',
'sumneko_lua',
'vimls',
'html',
'jsonls',
'solargraph',
'cssls',
'yamlls',
'clangd',
'ccls',
'sqls',
'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',
'tflint',
'terraform_lsp',
}
local lsp_installer_servers = {} local lsp_installer_servers = {}
local has_lspinst = false local has_lspinst = false
local has_mason = false
has_lspinst, _ = pcall(require, 'nvim-lsp-installer')
if has_lspinst then
local srvs = require('nvim-lsp-installer.servers').get_installed_servers()
if #srvs > 0 then
lsp_installer_servers = srvs
end
end
has_mason, _ = pcall(require, 'mason-lspconfig') if config.lsp_installer == true then
if has_mason then has_lspinst, _ = pcall(require, 'nvim-lsp-installer')
local srvs=require'mason-lspconfig'.get_installed_servers() if has_lspinst then
if #srvs > 0 then local srvs = require('nvim-lsp-installer.servers').get_installed_servers()
lsp_installer_servers = srvs log('lsp_installered servers', srvs)
if #srvs > 0 then
lsp_installer_servers = srvs
end
end end
log(lsp_installer_servers)
end end
log("lsp_installer:", lsp_installer_servers)
if config.lsp.disable_lsp == 'all' then if config.lsp.disable_lsp == 'all' then
config.lsp.disable_lsp = servers config.lsp.disable_lsp = servers
end end
@ -114,8 +389,8 @@ local ng_default_cfg = {
} }
-- check and load based on file type -- check and load based on file type
local function load_cfg(ft, client, cfg, loaded, starting) local function load_cfg(ft, client, cfg, loaded)
log(ft, client, loaded, starting) log(ft, client, loaded)
trace(cfg) trace(cfg)
if lspconfig[client] == nil then if lspconfig[client] == nil then
log('not supported by nvim', client) log('not supported by nvim', client)
@ -124,7 +399,6 @@ local function load_cfg(ft, client, cfg, loaded, starting)
local lspft = lspconfig[client].document_config.default_config.filetypes local lspft = lspconfig[client].document_config.default_config.filetypes
local additional_ft = setups[client] and setups[client].filetypes or {} local additional_ft = setups[client] and setups[client].filetypes or {}
local bufnr = vim.api.nvim_get_current_buf()
local cmd = cfg.cmd local cmd = cfg.cmd
vim.list_extend(lspft, additional_ft) vim.list_extend(lspft, additional_ft)
@ -140,46 +414,19 @@ local function load_cfg(ft, client, cfg, loaded, starting)
end end
trace('lsp for client', client, cfg) trace('lsp for client', client, cfg)
if cmd == nil or #cmd == 0 or vfn.executable(cmd[1]) == 0 then if cmd == nil or #cmd == 0 or vim.fn.executable(cmd[1]) == 0 then
log('lsp not installed for client', client, cmd, "fallback") log('lsp not installed for client', client, cmd)
return return
end end
if _NG_Loaded == nil then
return log('_NG_Loaded not set')
end
for k, c in pairs(loaded) do for k, c in pairs(loaded) do
if client == k then if client == k then
-- loaded -- loaded
log(client, 'already been loaded for', ft, loaded, c) log(client, 'already been loaded for', ft, loaded, c)
if not _NG_Loaded[bufnr] or _NG_Loaded[bufnr] < 4 then
log('doautocmd filetype')
vim.defer_fn(function()
vim.cmd('doautocmd FileType')
_NG_Loaded[bufnr] = (_NG_Loaded[bufnr] or 0 ) + 1
end, 100)
return
end
end
end
local clients = vim.lsp.buf_get_clients(0)
for _, c in pairs(clients or {}) do
log("lsp start up in progress client", client, c.name)
if c.name == client then
_NG_Loaded[bufnr] = 100
return return
end end
end end
if starting and (starting.cnt or 0) > 0 then
log("lsp start up in progress", starting)
return vim.defer_fn(function()
load_cfg(ft, client, cfg, loaded, { cnt = starting.cnt - 1 })
end,
200)
end
if lspconfig[client] == nil then if lspconfig[client] == nil then
error('client ' .. client .. ' not supported') error('client ' .. client .. ' not supported')
return return
@ -189,27 +436,8 @@ local function load_cfg(ft, client, cfg, loaded, starting)
log('lspconfig setup') log('lspconfig setup')
-- log(lspconfig.available_servers()) -- log(lspconfig.available_servers())
-- force reload with config -- force reload with config
-- lets have a guard here lspconfig[client].setup(cfg)
if not _NG_Loaded[client] then log(client, 'loading for', ft)
log(client, 'loading for', ft, cfg)
log(lspconfig[client])
lspconfig[client].setup(cfg)
_NG_Loaded[client] = true
vim.defer_fn(function()
log('send filetype event')
vim.cmd([[doautocmd Filetype]])
_NG_Loaded[bufnr] = (_NG_Loaded[bufnr] or 0 )+ 1
end, 400)
else
log('send filetype event')
if not _NG_Loaded[bufnr] or _NG_Loaded[bufnr] < 4 then
log('doautocmd filetype')
vim.defer_fn(function()
vim.cmd('doautocmd FileType')
_NG_Loaded[bufnr] = (_NG_Loaded[bufnr] or 0 ) + 1
end, 100)
end
end
end end
-- need to verify the lsp server is up -- need to verify the lsp server is up
end end
@ -227,7 +455,7 @@ local function setup_fmt(client, enabled)
client.server_capabilities.documentFormattingProvider = false client.server_capabilities.documentFormattingProvider = false
else else
client.server_capabilities.documentFormattingProvider = client.server_capabilities.documentFormattingProvider client.server_capabilities.documentFormattingProvider = client.server_capabilities.documentFormattingProvider
or enabled or enabled
end end
end end
@ -253,7 +481,7 @@ end
local loaded = {} local loaded = {}
local function lsp_startup(ft, retry, user_lsp_opts) local function lsp_startup(ft, retry, user_lsp_opts)
retry = retry or false retry = retry or false
local path_sep = require('navigator.util').path_sep()
local capabilities = update_capabilities() local capabilities = update_capabilities()
for _, lspclient in ipairs(servers) do for _, lspclient in ipairs(servers) do
@ -323,7 +551,7 @@ local function lsp_startup(ft, retry, user_lsp_opts)
log(lspclient) log(lspclient)
-- if user provides override values -- if user provides override values
-- cfg.capabilities = capabilities cfg.capabilities = capabilities
log(lspclient, config.lsp.disable_format_cap) log(lspclient, config.lsp.disable_format_cap)
if vim.tbl_contains(config.lsp.disable_format_cap or {}, lspclient) then if vim.tbl_contains(config.lsp.disable_format_cap or {}, lspclient) then
log('fileformat disabled for ', lspclient) log('fileformat disabled for ', lspclient)
@ -407,21 +635,16 @@ local function lsp_startup(ft, retry, user_lsp_opts)
log('lsp installer server config ' .. lspconfig[lspclient].name, installer_cfg) log('lsp installer server config ' .. lspconfig[lspclient].name, installer_cfg)
if installed and installer_cfg then if installed and installer_cfg then
local paths = installer_cfg:get_default_options().cmd_env and installer_cfg:get_default_options().cmd_env.PATH local paths = installer_cfg:get_default_options().cmd_env.PATH
if not paths then
-- for some reason lspinstaller does not install the binary, check default PATH
log('lsp installer does not install the lsp in its path, fallback')
return load_cfg(ft, lspclient, cfg, loaded)
end
paths = vim.split(paths, ':') paths = vim.split(paths, ':')
if vfn.empty(cfg.cmd) == 1 then if vim.fn.empty(cfg.cmd) == 1 then
cfg.cmd = { installer_cfg.name } cfg.cmd = { installer_cfg.name }
end end
if vfn.executable(cfg.cmd[1]) == 0 then if vim.fn.executable(cfg.cmd[1]) == 0 then
for _, path in ipairs(paths) do for _, path in ipairs(paths) do
log(path) log(path)
if vfn.isdirectory(path) == 1 and string.find(path, installer_cfg.root_dir) then if vim.fn.isdirectory(path) == 1 and string.find(path, installer_cfg.root_dir) then
cfg.cmd[1] = path .. path_sep .. cfg.cmd[1] cfg.cmd[1] = path .. path_sep .. cfg.cmd[1]
log(cfg.cmd) log(cfg.cmd)
break break
@ -433,49 +656,17 @@ local function lsp_startup(ft, retry, user_lsp_opts)
end end
end end
end end
if has_mason and _NgConfigValues.mason then
local servers = require'mason-lspconfig'.get_installed_servers()
if not vim.tbl_contains(servers, lspconfig[lspclient].name) then
log('mason server not installed', lspconfig[lspclient].name)
-- return
end
local pkg_name = require "mason-lspconfig.mappings.server".lspconfig_to_package[lspconfig[lspclient].name]
local pkg = require "mason-registry".get_package(pkg_name)
log('lsp installer server config ' .. lspconfig[lspclient].name, pkg)
if pkg then
local path = pkg:get_install_path()
if not path then
-- for some reason lspinstaller does not install the binary, check default PATH
log('lsp installer does not install the lsp in its path, fallback')
return load_cfg(ft, lspclient, cfg, loaded)
end
cfg.cmd = cfg.cmd or {}
cfg.cmd[1] = table.concat({vfn.stdpath('data'), 'mason', 'bin', pkg.name}, path_sep)
if vfn.executable(cfg.cmd[1]) == 0 then
log('failed to find cmd', cfg.cmd[1], "fallback")
return load_cfg(ft, lspclient, cfg, loaded)
else
log('cmd installed', cfg.cmd)
end
end
end
if vfn.executable(cfg.cmd[1]) == 0 then if vim.fn.executable(cfg.cmd[1]) == 0 then
log('lsp server not installed in path ' .. lspclient .. vim.inspect(cfg.cmd), vim.lsp.log_levels.WARN) log('lsp server not installed in path ' .. lspclient .. vim.inspect(cfg.cmd), vim.lsp.log_levels.WARN)
end end
if _NG_Loaded[lspclient] then if _NG_Loaded[lspclient] then
log('client loaded ?', lspclient, _NG_Loaded[lspclient]) log('client loaded ?', lspclient)
end
local starting = {}
if _NG_Loaded[lspclient] == true then
starting = { cnt = 1 }
end end
load_cfg(ft, lspclient, cfg, loaded)
load_cfg(ft, lspclient, cfg, loaded, starting) _NG_Loaded[lspclient] = true
-- load_cfg(ft, lspclient, {}, loaded) -- load_cfg(ft, lspclient, {}, loaded)
::continue:: ::continue::
end end
@ -549,7 +740,7 @@ local function setup(user_opts, cnt)
local bufnr = user_opts.bufnr or vim.api.nvim_get_current_buf() local bufnr = user_opts.bufnr or vim.api.nvim_get_current_buf()
if ft == '' or ft == nil then if ft == '' or ft == nil then
log('nil filetype, callback') log('nil filetype, callback')
local ext = vfn.expand('%:e') local ext = vim.fn.expand('%:e')
if ext ~= '' then if ext ~= '' then
cnt = cnt or 0 cnt = cnt or 0
local opts = vim.deepcopy(user_opts) local opts = vim.deepcopy(user_opts)
@ -629,7 +820,7 @@ local function setup(user_opts, cnt)
--- if code lens enabled --- if code lens enabled
if _NgConfigValues.lsp.code_lens_action.enable then if _NgConfigValues.lsp.code_lens_action.enable then
require('navigator.codelens').setup(bufnr) require('navigator.codelens').setup()
end end
-- _LoadedFiletypes[ft .. tostring(bufnr)] = true -- may prevent lsp config when reboot lsp -- _LoadedFiletypes[ft .. tostring(bufnr)] = true -- may prevent lsp config when reboot lsp
@ -644,38 +835,23 @@ local function on_filetype()
return return
end end
if uri == 'file://' or uri == 'file:///' then if uri == 'file://' or uri == 'file:///' then
trace('skip loading for ft ', ft, uri) log('skip loading for ft ', ft, uri)
return
end
log (_NG_Loaded)
if _NG_Loaded[bufnr] and type(_NG_Loaded[bufnr]) == 'number' and _NG_Loaded[bufnr] > 1 then
log('navigator was loaded for ft', ft, bufnr)
return return
end end
-- on_filetype should only be trigger only once for each bufnr
if _NG_Loaded[bufnr] ~= nil and type(_NG_Loaded[bufnr] == 'number') then
_NG_Loaded[bufnr] = _NG_Loaded[bufnr] + 1 -- do not hook and trigger filetype event multiple times
end
if _NG_Loaded[bufnr] == true then
_NG_Loaded[bufnr] = 1 -- record the count
end
-- as setup will send filetype event as well
log(uri) log(uri)
local wids = vfn.win_findbuf(bufnr) local wids = vim.fn.win_findbuf(bufnr)
if empty(wids) then if empty(wids) then
log('buf not shown return') log('buf not shown return')
end end
setup({ bufnr = bufnr }) setup({ bufnr = bufnr })
_NG_Loaded[bufnr] = 1
end end
return { return {
setup = setup, setup = setup,
get_cfg = get_cfg, get_cfg = get_cfg,
lsp = servers,
add_servers = add_servers, add_servers = add_servers,
on_filetype = on_filetype, on_filetype = on_filetype,
disabled_ft = disabled_ft, disabled_ft = disabled_ft,

@ -1,191 +0,0 @@
local M = {}
local vfn = vim.fn
M.defaults = function()
local has_lsp, lspconfig = pcall(require, 'lspconfig')
local highlight = require('navigator.lspclient.highlight')
if not has_lsp then
return {
setup = function()
vim.notify('loading lsp config failed LSP may not working correctly', vim.lsp.log_levels.WARN)
end,
}
end
local util = lspconfig.util
local on_attach = require('navigator.lspclient.attach').on_attach
local setups = {
clojure_lsp = {
root_dir = function(fname)
return util.root_pattern('deps.edn', 'build.boot', 'project.clj', 'shadow-cljs.edn', 'bb.edn', '.git')(fname)
or util.path.dirname(fname)
end,
on_attach = on_attach,
filetypes = { 'clojure', 'edn' },
message_level = vim.lsp.protocol.MessageType.error,
cmd = { 'clojure-lsp' },
},
elixirls = {
on_attach = on_attach,
filetypes = { 'elixir', 'eelixir' },
cmd = { 'elixir-ls' },
message_level = vim.lsp.protocol.MessageType.error,
settings = {
elixirLS = {
dialyzerEnabled = true,
fetchDeps = false,
},
},
root_dir = function(fname)
return util.root_pattern('mix.exs', '.git')(fname) or util.path.dirname(fname)
end,
},
gopls = {
on_attach = on_attach,
-- capabilities = cap,
filetypes = { 'go', 'gomod', 'gohtmltmpl', 'gotexttmpl' },
message_level = vim.lsp.protocol.MessageType.Error,
cmd = {
'gopls', -- share the gopls instance if there is one already
'-remote=auto', --[[ debug options ]] --
-- "-logfile=auto",
-- "-debug=:0",
'-remote.debug=:0',
-- "-rpc.trace",
},
flags = { allow_incremental_sync = true, debounce_text_changes = 1000 },
settings = {
gopls = {
-- more settings: https://github.com/golang/tools/blob/master/gopls/doc/settings.md
-- flags = {allow_incremental_sync = true, debounce_text_changes = 500},
-- not supported
analyses = { unusedparams = true, unreachable = false },
codelenses = {
generate = true, -- show the `go generate` lens.
gc_details = true, -- // Show a code lens toggling the display of gc's choices.
test = true,
tidy = true,
},
usePlaceholders = true,
completeUnimported = true,
staticcheck = true,
matcher = 'fuzzy',
diagnosticsDelay = '500ms',
experimentalWatchedFileDelay = '1000ms',
symbolMatcher = 'fuzzy',
gofumpt = false, -- true, -- turn on for new repos, gofmpt is good but also create code turmoils
buildFlags = { '-tags', 'integration' },
-- buildFlags = {"-tags", "functional"}
},
},
root_dir = function(fname)
return util.root_pattern('go.mod', '.git')(fname) or dirname(fname) -- util.path.dirname(fname)
end,
},
clangd = {
flags = { allow_incremental_sync = true, debounce_text_changes = 500 },
cmd = {
'clangd',
'--background-index',
'--suggest-missing-includes',
'--clang-tidy',
'--header-insertion=iwyu',
'--clang-tidy-checks=-*,llvm-*,clang-analyzer-*',
'--cross-file-rename',
},
filetypes = { 'c', 'cpp', 'objc', 'objcpp' },
on_attach = function(client, bufnr)
client.server_capabilities.documentFormattingProvider = client.server_capabilities.documentFormattingProvider
or true
on_attach(client, bufnr)
end,
},
rust_analyzer = {
root_dir = function(fname)
return util.root_pattern('Cargo.toml', 'rust-project.json', '.git')(fname) or util.path.dirname(fname)
end,
filetypes = { 'rust' },
message_level = vim.lsp.protocol.MessageType.error,
on_attach = on_attach,
settings = {
['rust-analyzer'] = {
assist = { importMergeBehavior = 'last', importPrefix = 'by_self' },
cargo = { loadOutDirsFromCheck = true },
procMacro = { enable = true },
},
},
flags = { allow_incremental_sync = true, debounce_text_changes = 500 },
},
sqls = {
filetypes = { 'sql' },
on_attach = function(client, _)
client.server_capabilities.executeCommandProvider = client.server_capabilities.documentFormattingProvider
or true
highlight.diagnositc_config_sign()
require('sqls').setup({ picker = 'telescope' }) -- or default
end,
flags = { allow_incremental_sync = true, debounce_text_changes = 500 },
settings = {
cmd = { 'sqls', '-config', '$HOME/.config/sqls/config.yml' },
-- alterantively:
-- connections = {
-- {
-- driver = 'postgresql',
-- datasourcename = 'host=127.0.0.1 port=5432 user=postgres password=password dbname=user_db sslmode=disable',
-- },
-- },
},
},
pyright = {
on_attach = on_attach,
cmd = { 'pyright-langserver', '--stdio' },
filetypes = { 'python' },
flags = { allow_incremental_sync = true, debounce_text_changes = 500 },
settings = {
python = {
formatting = { provider = 'black' },
analysis = {
autoSearchPaths = true,
useLibraryCodeForTypes = true,
diagnosticMode = 'workspace',
},
},
},
},
ccls = {
on_attach = on_attach,
init_options = {
compilationDatabaseDirectory = 'build',
root_dir = [[ util.root_pattern("compile_commands.json", "compile_flags.txt", "CMakeLists.txt", "Makefile", ".git") or util.path.dirname ]],
index = { threads = 2 },
clang = { excludeArgs = { '-frounding-math' } },
},
flags = { allow_incremental_sync = true },
},
jdtls = {
settings = {
java = { signatureHelp = { enabled = true }, contentProvider = { preferred = 'fernflower' } },
},
},
omnisharp = {
cmd = { 'omnisharp', '--languageserver', '--hostPID', tostring(vfn.getpid()) },
},
terraformls = {
filetypes = { 'terraform', 'tf' },
},
sourcekit = {
cmd = { 'sourcekit-lsp' },
filetypes = { 'swift' }, -- This is recommended if you have separate settings for clangd.
},
}
setups.sumneko_lua = require('navigator.lspclient.sumneko_lua').sumneko_lua()
return setups
end
return M

@ -1,3 +1,5 @@
local lsp = require("vim.lsp")
local M = {} local M = {}
local capabilities = vim.lsp.protocol.make_client_capabilities() local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true capabilities.textDocument.completion.completionItem.snippetSupport = true

@ -3,7 +3,6 @@ local M = {}
-- local log = require('navigator.util').log -- local log = require('navigator.util').log
local api = vim.api local api = vim.api
local cmd_group = api.nvim_create_augroup('NGHiGroup', {})
-- lsp sign          ﮻         ﯭ        ﳀ   -- lsp sign          ﮻         ﯭ        ﳀ  
function M.diagnositc_config_sign() function M.diagnositc_config_sign()
if M.configed then if M.configed then
@ -32,41 +31,35 @@ function M.diagnositc_config_sign()
M.configed = true M.configed = true
end end
local colors = {
{ '#aefe00', '#aede00', '#aebe00', '#4e7efe' },
{ '#ff00e0', '#df00e0', '#af00e0', '#fedefe' },
{ '#1000ef', '#2000df', '#2000cf', '#f0f040' },
{ '#d8a8a3', '#c8a8a3', '#b8a8a3', '#4e2c33' },
{ '#ffa724', '#efa024', '#dfa724', '#0040ff' },
{ '#afdc2b', '#09dc4b', '#08d04b', '#ef4f8f' },
}
function M.add_highlight() function M.add_highlight()
-- lsp system default -- lsp system default
api.nvim_command('hi! link DiagnosticUnderlineError SpellBad')
api.nvim_set_hl(0, 'DiagnosticUnderlineError', { link = 'SpellBad', default = true }) api.nvim_command('hi! link DiagnosticUnderlineWarning SpellRare')
api.nvim_set_hl(0, 'DiagnosticUnderlineWarning', { link = 'SpellRare', default = true }) api.nvim_command('hi! link DiagnosticUnderlineInformation SpellRare')
api.nvim_set_hl(0, 'DiagnosticUnderlineInformation', { link = 'SpellRare', default = true }) api.nvim_command('hi! link DiagnosticUnderlineHint SpellRare')
api.nvim_set_hl(0, 'DiagnosticUnderlineHint', { link = 'SpellRare', default = true }) api.nvim_command('hi def link NGPreviewTitle Title')
api.nvim_set_hl(0, 'NGPreviewTitle', { link = 'Title', default = true }) local colors = {
api.nvim_set_hl(0, 'LspReferenceRead', { default = true, link = 'IncSearch'}) { '#aefe00', '#aede00', '#aebe00', '#4e7efe' },
api.nvim_set_hl(0, 'LspReferenceText', { default = true, link = 'Visual'}) { '#ff00e0', '#df00e0', '#af00e0', '#fedefe' },
api.nvim_set_hl( 0, 'LspReferenceWrite', { default = true, link = 'Search'}) { '#1000ef', '#2000df', '#2000cf', '#f0f040' },
{ '#d8a8a3', '#c8a8a3', '#b8a8a3', '#4e2c33' },
{ '#ffa724', '#efa024', '#dfa724', '#0040ff' },
{ '#afdc2b', '#09dc4b', '#08d04b', '#ef4f8f' },
}
for i = 1, #colors do for i = 1, #colors do
for j = 1, 3 do for j = 1, 3 do
local hlg = string.format('NGHiReference_%i_%i', i, j) -- , colors[i][j], colors[i][4] local cmd = string.format('hi! default NGHiReference_%i_%i guibg=%s guifg=%s ', i, j, colors[i][j], colors[i][4])
api.nvim_set_hl(0, hlg, { fg = colors[i][j], bg = colors[i][4], default = true }) vim.cmd(cmd)
end end
end end
end
api.nvim_create_autocmd('ColorScheme', { vim.cmd([[
group = cmd_group, autocmd ColorScheme * |
pattern = '*', hi default LspReferenceRead cterm=bold gui=Bold ctermbg=yellow guifg=yellow guibg=purple4 |
callback = function() hi default LspReferenceText cterm=bold gui=Bold ctermbg=red guifg=SlateBlue guibg=MidnightBlue |
M.add_highlight() hi default LspReferenceWrite cterm=bold gui=Bold,Italic ctermbg=red guifg=DarkSlateBlue guibg=MistyRose
end, ]])
}) end
return M return M

@ -1,7 +1,12 @@
local util = require('navigator.util') local util = require('navigator.util')
local log = util.log local log = util.log
local trace = util.trace local trace = util.trace
local api = vim.api local event_hdlrs = {
{ ev = 'BufWritePre', func = [[require "navigator.diagnostics".set_diag_loclist()]] },
{ ev = 'CursorHold', func = 'document_highlight()' },
{ ev = 'CursorHoldI', func = 'document_highlight()' },
{ ev = 'CursorMoved', func = 'clear_references()' },
}
if vim.lsp.buf.format == nil then if vim.lsp.buf.format == nil then
vim.lsp.buf.format = vim.lsp.buf.formatting vim.lsp.buf.format = vim.lsp.buf.formatting
@ -15,60 +20,56 @@ local single = { '╭', '─', '╮', '│', '╯', '─', '╰', '│' }
-- TODO https://github.com/neovim/neovim/pull/16591 use vimkeymap.set/del -- TODO https://github.com/neovim/neovim/pull/16591 use vimkeymap.set/del
-- LuaFormatter off -- LuaFormatter off
local key_maps = { local key_maps = {
{ key = 'gr', func = require('navigator.reference').async_ref, desc = 'async_ref' }, { key = 'gr', func = "require('navigator.reference').async_ref()" },
{ key = '<Leader>gr', func = require('navigator.reference').reference, desc = 'reference' }, -- reference deprecated { key = '<Leader>gr', func = "require('navigator.reference').reference()" }, -- reference deprecated
{ mode = 'i', key = '<M-k>', func = vim.lsp.signature_help, desc = 'signature_help' }, { mode = 'i', key = '<M-k>', func = 'signature_help()' },
{ key = '<c-k>', func = vim.lsp.buf.signature_help, desc = 'signature_help' }, { key = '<c-k>', func = 'signature_help()' },
{ key = 'g0', func = require('navigator.symbols').document_symbols, desc = 'document_symbols' }, { key = 'g0', func = "require('navigator.symbols').document_symbols()" },
{ key = 'gW', func = require('navigator.workspace').workspace_symbol_live, desc = 'workspace_symbol_live' }, { key = 'gW', func = "require('navigator.workspace').workspace_symbol_live()" },
{ key = '<c-]>', func = require('navigator.definition').definition, desc = 'definition' }, { key = '<c-]>', func = "require('navigator.definition').definition()" },
{ key = 'gd', func = require('navigator.definition').definition, desc = 'definition' }, { key = 'gd', func = "require('navigator.definition').definition()" },
{ key = 'gD', func = vim.lsp.buf.declaration, desc = 'declaration' }, { key = 'gD', func = "declaration({ border = 'rounded', max_width = 80 })" },
{ key = 'gp', func = require('navigator.definition').definition_preview, desc = 'definition_preview' }, { key = 'gp', func = "require('navigator.definition').definition_preview()" },
{ key = '<Leader>gt', func = require('navigator.treesitter').buf_ts, desc = 'buf_ts' }, { key = '<Leader>gt', func = "require('navigator.treesitter').buf_ts()" },
{ key = '<Leader>gT', func = require('navigator.treesitter').bufs_ts, desc = 'bufs_ts' }, { key = '<Leader>gT', func = "require('navigator.treesitter').bufs_ts()" },
{ key = '<Leader>ct', func = require('navigator.ctags').ctags, desc = 'ctags' }, { key = '<Leader>ct', func = "require('navigator.ctags').ctags()" },
{ key = 'K', func = vim.lsp.buf.hover, desc = 'hover' }, { key = 'K', func = 'hover({ popup_opts = { border = single, max_width = 80 }})' },
{ key = '<Space>ca', mode = 'n', func = require('navigator.codeAction').code_action, desc = 'code_action' }, { key = '<Space>ca', mode = 'n', func = "require('navigator.codeAction').code_action()" },
{ { key = '<Space>ca', mode = 'v', func = "require('navigator.codeAction').range_code_action()" },
key = '<Space>ca',
mode = 'v',
func = require('navigator.codeAction').range_code_action,
desc = 'range_code_action',
},
-- { key = '<Leader>re', func = 'rename()' }, -- { key = '<Leader>re', func = 'rename()' },
{ key = '<Space>rn', func = require('navigator.rename').rename, desc = 'rename' }, { key = '<Space>rn', func = "require('navigator.rename').rename()" },
{ key = '<Leader>gi', func = vim.lsp.buf.incoming_calls, desc = 'incoming_calls' }, { key = '<Leader>gi', func = 'incoming_calls()' },
{ key = '<Leader>go', func = vim.lsp.buf.outgoing_calls, desc = 'outgoing_calls' }, { key = '<Leader>go', func = 'outgoing_calls()' },
{ key = 'gi', func = vim.lsp.buf.implementation, desc = 'implementation' }, { key = 'gi', func = 'implementation()' },
{ key = '<Space>D', func = vim.lsp.buf.type_definition, desc = 'type_definition' }, { key = '<Space>D', func = 'type_definition()' },
{ key = 'gL', func = require('navigator.diagnostics').show_diagnostics, desc = 'show_diagnostics' }, { key = 'gL', func = "require('navigator.diagnostics').show_diagnostics()" },
{ key = 'gG', func = require('navigator.diagnostics').show_buf_diagnostics, desc = 'show_buf_diagnostics' }, { key = 'gG', func = "require('navigator.diagnostics').show_buf_diagnostics()" },
{ key = '<Leader>dt', func = require('navigator.diagnostics').toggle_diagnostics, desc = 'toggle_diagnostics' }, { key = '<Leader>dt', func = "require('navigator.diagnostics').toggle_diagnostics()" },
{ key = ']d', func = vim.diagnostic.goto_next, desc = 'next diagnostics' }, { key = ']d', func = "diagnostic.goto_next({ border = 'rounded', max_width = 80})" },
{ key = '[d', func = vim.diagnostic.goto_prev, desc = 'prev diagnostics' }, { key = '[d', func = "diagnostic.goto_prev({ border = 'rounded', max_width = 80})" },
{ key = ']O', func = vim.diagnostic.set_loclist, desc = 'diagnostics set loclist' }, { key = ']O', func = 'diagnostic.set_loclist()' },
{ key = ']r', func = require('navigator.treesitter').goto_next_usage, desc = 'goto_next_usage' }, { key = ']r', func = "require('navigator.treesitter').goto_next_usage()" },
{ key = '[r', func = require('navigator.treesitter').goto_previous_usage, desc = 'goto_previous_usage' }, { key = '[r', func = "require('navigator.treesitter').goto_previous_usage()" },
{ key = '<C-LeftMouse>', func = vim.lsp.buf.definition, desc = 'definition' }, { key = '<C-LeftMouse>', func = 'definition()' },
{ key = 'g<LeftMouse>', func = vim.lsp.buf.implementation, desc = 'implementation' }, { key = 'g<LeftMouse>', func = 'implementation()' },
{ key = '<Leader>k', func = require('navigator.dochighlight').hi_symbol, desc = 'hi_symbol' }, { key = '<Leader>k', func = "require('navigator.dochighlight').hi_symbol()" },
{ key = '<Space>wa', func = require('navigator.workspace').add_workspace_folder, desc = 'add_workspace_folder' }, { key = '<Space>wa', func = "require('navigator.workspace').add_workspace_folder()" },
{ { key = '<Space>wr', func = "require('navigator.workspace').remove_workspace_folder()" },
key = '<Space>wr', { key = '<Space>ff', func = 'format({async = true})', mode = 'n' },
func = require('navigator.workspace').remove_workspace_folder, { key = '<Space>ff', func = 'range_formatting()', mode = 'v' },
desc = 'remove_workspace_folder', { key = '<Space>wl', func = "require('navigator.workspace').list_workspace_folders()" },
}, { key = '<Space>la', mode = 'n', func = "require('navigator.codelens').run_action()" },
{ key = '<Space>ff', func = vim.lsp.buf.format, mode = 'n', desc = 'format' }, }
{ key = '<Space>ff', func = vim.lsp.buf.range_formatting, mode = 'v', desc = 'range format' },
{ local commands = {
key = '<Space>gm', [[command! -nargs=* Nctags lua require("navigator.ctags").ctags(<f-args>)]],
func = require('navigator.formatting').range_format, "command! -nargs=0 LspLog lua require'navigator.lspclient.config'.open_lsp_log()",
mode = 'n', "command! -nargs=0 LspRestart lua require'navigator.lspclient.config'.reload_lsp()",
desc = 'range format operator e.g gmip', "command! -nargs=0 LspToggleFmt lua require'navigator.lspclient.mapping'.toggle_lspformat()<CR>",
}, "command! -nargs=0 LspKeymaps lua require'navigator.lspclient.mapping'.get_keymaps_help()<CR>",
{ key = '<Space>wl', func = require('navigator.workspace').list_workspace_folders, desc = 'list_workspace_folders' }, "command! -nargs=0 LspSymbols lua require'navigator.symbols'.side_panel()<CR>",
{ key = '<Space>la', mode = 'n', func = require('navigator.codelens').run_action, desc = 'run code lens action' }, "command! -nargs=0 TSymbols lua require'navigator.treesitter'.side_panel()<CR>",
"command! -nargs=* Calltree lua require'navigator.hierarchy'.calltree(<f-args>)<CR>",
} }
local key_maps_help = {} local key_maps_help = {}
@ -76,8 +77,8 @@ local key_maps_help = {}
local M = {} local M = {}
local ccls_mappings = { local ccls_mappings = {
{ key = '<Leader>gi', func = require('navigator.cclshierarchy').incoming_calls, desc = 'incoming_calls' }, { key = '<Leader>gi', func = "require('navigator.cclshierarchy').incoming_calls()" },
{ key = '<Leader>go', func = require('navigator.cclshierarchy').outgoing_calls, desc = 'outgoing_calls' }, { key = '<Leader>go', func = "require('navigator.cclshierarchy').outgoing_calls()" },
} }
local check_cap = function(opts) local check_cap = function(opts)
@ -115,25 +116,12 @@ local check_cap = function(opts)
end end
local function set_cmds(_) local function set_cmds(_)
local commands = {
[[command! -nargs=* Nctags lua require("navigator.ctags").ctags(<f-args>)]],
"command! -nargs=0 LspLog lua require'navigator.lspclient.config'.open_lsp_log()",
"command! -nargs=0 LspRestart lua require'navigator.lspclient.config'.reload_lsp()",
"command! -nargs=0 LspToggleFmt lua require'navigator.lspclient.mapping'.toggle_lspformat()<CR>",
"command! -nargs=0 LspKeymaps lua require'navigator.lspclient.mapping'.get_keymaps_help()<CR>",
"command! -nargs=0 LspSymbols lua require'navigator.symbols'.side_panel()<CR>",
"command! -nargs=0 TSymbols lua require'navigator.treesitter'.side_panel()<CR>",
"command! -nargs=0 NRefPanel lua require'navigator.reference'.side_panel()<CR>",
"command! -nargs=* Calltree lua require'navigator.hierarchy'.calltree(<f-args>)<CR>",
}
for _, value in pairs(commands) do for _, value in pairs(commands) do
vim.cmd(value) vim.cmd(value)
end end
end end
-- should works for both 1)attach from known lsp client or from a disabled lsp client -- should works for both 1)attach from known lsp client or from a disabled lsp client
-- executed in on_attach context
local function set_mapping(lsp_attach_info) local function set_mapping(lsp_attach_info)
local opts = { noremap = true, silent = true } local opts = { noremap = true, silent = true }
vim.validate({ vim.validate({
@ -145,17 +133,13 @@ local function set_mapping(lsp_attach_info)
local user_key = _NgConfigValues.keymaps or {} local user_key = _NgConfigValues.keymaps or {}
local bufnr = lsp_attach_info.bufnr or 0 local bufnr = lsp_attach_info.bufnr or 0
local function del_keymap(mode, key, ...) local function del_keymap(...)
local ks = vim.api.nvim_buf_get_keymap(bufnr, mode) vim.api.nvim_buf_del_keymap(bufnr, ...)
if vim.tbl_contains(ks, key) then
vim.api.nvim_buf_del_keymap(bufnr, mode, key, ...)
end
end end
local function set_keymap(...) local function set_keymap(...)
vim.api.nvim_buf_set_keymap(bufnr, ...) vim.api.nvim_buf_set_keymap(bufnr, ...)
end end
-- local function buf_set_option(...) -- local function buf_set_option(...)
-- vim.api.nvim_buf_set_option(bufnr, ...) -- vim.api.nvim_buf_set_option(bufnr, ...)
-- end -- end
@ -183,85 +167,42 @@ local function set_mapping(lsp_attach_info)
key_maps = _NgConfigValues.keymaps or {} key_maps = _NgConfigValues.keymaps or {}
log('setting maps to ', key_maps) log('setting maps to ', key_maps)
end end
local fmtkey, rfmtkey, nrfmtkey local fmtkey, rfmtkey
require('navigator.formatting')
for _, value in pairs(key_maps) do for _, value in pairs(key_maps) do
if value.doc then local f = '<Cmd>lua vim.lsp.buf.' .. value.func .. '<CR>'
vim.notify('doc field no longer supported in navigator mapping, use desc instead') if string.find(value.func, 'require') or string.find(value.func, 'vim.') then
f = '<Cmd>lua ' .. value.func .. '<CR>'
elseif string.find(value.func, 'diagnostic') then
local diagnostic = '<Cmd>lua vim.'
diagnostic = '<Cmd>lua vim.'
f = diagnostic .. value.func .. '<CR>'
-- elseif string.find(value.func, 'vim.') then
-- f = '<Cmd>lua ' .. value.func .. '<string.find(value.func, 'vim.')CR>'
end end
if type(value.func) == 'string' then -- deprecated will remove when 0.8 is out local k = value.key
vim.notify('keymap config updated: ' .. value.key .. ' func ' .. value.func .. ' should be a function') local m = value.mode or 'n'
local f = '<Cmd>lua vim.lsp.buf.' .. value.func .. '<CR>' if string.find(value.func, 'range_formatting') then
if string.find(value.func, 'require') or string.find(value.func, 'vim.') then rfmtkey = value.key
f = '<Cmd>lua ' .. value.func .. '<CR>' elseif string.find(value.func, 'format') then
elseif string.find(value.func, 'diagnostic') then fmtkey = value.key
local diagnostic = '<Cmd>lua vim.'
diagnostic = '<Cmd>lua vim.'
f = diagnostic .. value.func .. '<CR>'
end
local k = value.key
local m = value.mode or 'n'
if string.find(value.func, 'range_formatting') then
rfmtkey = value.key
elseif string.find(value.func, 'format') then
fmtkey = value.key
end
trace('binding', k, f)
set_keymap(m, k, f, opts)
end
if type(value.func) == 'function' then -- new from 0.7.x
-- neovim 0.7.0
opts.buffer = key_maps.buffer or value.buffer
if value.desc then
opts.desc = value.desc
end
opts.buffer = bufnr
vim.keymap.set(value.mode or 'n', value.key, value.func, opts)
if string.find(value.desc, 'range format') and value.mode == 'v' then
rfmtkey = value.key
if string.find(value.desc, 'range format') and value.mode == 'n' then
nrfmtkey = value.key
elseif string.find(value.desc, 'format') then
fmtkey = value.key
end
end
end end
trace('binding', k, f)
set_keymap(m, k, f, opts)
end end
for _, val in pairs(key_maps) do
local helper_msg = ''
if val.desc then
helper_msg = val.desc
elseif type(val.func) == 'string' then
helper_msg = val.func
end
local item = (val.mode or 'n') .. '|' .. val.key .. '|' .. helper_msg for _, val in pairs(key_maps) do
if not vim.tbl_contains(key_maps_help, item) then table.insert(key_maps_help, (val.mode or 'n') .. '|' .. val.key .. '|' .. val.func)
table.insert(key_maps_help, (val.mode or 'n') .. '|' .. val.key .. '|' .. helper_msg)
end
end end
-- if user_opts.cap.document_formatting then -- if user_opts.cap.document_formatting then
if doc_fmt and _NgConfigValues.lsp.format_on_save then if doc_fmt and _NgConfigValues.lsp.format_on_save then
local gn = api.nvim_create_augroup('NavAuGroupFormat', {}) vim.cmd([[
aug NavigatorAuFormat
local fopts = _NgConfigValues.lsp.format_options au!
autocmd BufWritePre <buffer> lua vim.lsp.buf.format({async = true})
if not fopts.async and vim.api.nvim_buf_line_count(0) > 4000 then aug END
fopts.async = true ]])
end
api.nvim_create_autocmd({ 'BufWritePre' }, {
group = gn,
buffer = bufnr,
callback = function()
trace('format' .. vim.inspect(fopts))
vim.lsp.buf.format(fopts)
end,
})
elseif fmtkey then elseif fmtkey then
del_keymap('n', fmtkey) del_keymap('n', fmtkey)
end end
@ -274,19 +215,45 @@ local function set_mapping(lsp_attach_info)
del_keymap('v', rfmtkey) del_keymap('v', rfmtkey)
end end
if not range_fmt and nrfmtkey then
del_keymap('n', nrfmtkey)
end
log('enable format ', doc_fmt, range_fmt, _NgConfigValues.lsp.format_on_save) log('enable format ', doc_fmt, range_fmt, _NgConfigValues.lsp.format_on_save)
end end
local function autocmd() local function autocmd()
local gn = api.nvim_create_augroup('NavAuGroupDocHlAu', {}) vim.api.nvim_exec(
[[
aug NavigatorDocHlAu
au!
au CmdlineLeave : lua require('navigator.dochighlight').cmd_nohl()
aug END
]],
false
)
end
api.nvim_create_autocmd({ 'BufWritePre' }, { local function set_event_handler(user_opts)
group = gn, user_opts = user_opts or {}
callback = require('navigator.dochighlight').cmd_nohl, local file_types =
}) 'c,cpp,h,go,python,vim,sh,javascript,html,css,lua,typescript,rust,javascriptreact,typescriptreact,kotlin,php,dart,nim,java'
-- local format_files = "c,cpp,h,go,python,vim,javascript,typescript" --html,css,
vim.api.nvim_command([[augroup nvim_nv_lsp_autos]])
vim.api.nvim_command([[autocmd!]])
for _, value in pairs(event_hdlrs) do
local f = ''
if string.find(value.func, 'require') ~= nil then
f = 'lua ' .. value.func
else
f = 'lua vim.lsp.buf.' .. value.func
end
local cmd = 'autocmd FileType '
.. file_types
.. ' autocmd nvim_nv_lsp_autos '
.. value.ev
.. ' <buffer> silent! '
.. f
vim.api.nvim_command(cmd)
end
vim.api.nvim_command([[augroup END]])
end end
M.toggle_lspformat = function(on) M.toggle_lspformat = function(on)
@ -320,6 +287,7 @@ function M.setup(attach_opts)
set_cmds(attach_opts) set_cmds(attach_opts)
autocmd() autocmd()
set_event_handler(attach_opts)
local client = attach_opts.client or {} local client = attach_opts.client or {}
local cap = client.server_capabilities or vim.lsp.protocol.make_client_capabilities() local cap = client.server_capabilities or vim.lsp.protocol.make_client_capabilities()
@ -362,14 +330,6 @@ function M.setup(attach_opts)
}) })
end end
api.nvim_create_autocmd({ 'BufWritePre' }, {
group = api.nvim_create_augroup('nvim_nv_event_autos', {}),
buffer = attach_opts.bufnr,
callback = function()
require('navigator.diagnostics').set_diag_loclist(attach_opts.bufnr)
end,
})
local border_style = single local border_style = single
if _NgConfigValues.border == 'double' then if _NgConfigValues.border == 'double' then
border_style = double border_style = double
@ -388,7 +348,7 @@ M.get_keymaps_help = function()
border = 'none', border = 'none',
prompt = true, prompt = true,
enter = true, enter = true,
rect = { height = 24, width = 50 }, rect = { height = 20, width = 90 },
data = key_maps_help, data = key_maps_help,
}) })

@ -1,47 +0,0 @@
return {
'angularls',
'gopls',
'tsserver',
'flow',
'bashls',
'dockerls',
'julials',
'pylsp',
'pyright',
'jedi_language_server',
'jdtls',
'sumneko_lua',
'vimls',
'html',
'jsonls',
'solargraph',
'cssls',
'yamlls',
'clangd',
'ccls',
'sqls',
'denols',
'graphql',
'dartls',
'dotls',
'kotlin_language_server',
'nimls',
'intelephense',
'vuels',
'volar',
'phpactor',
'omnisharp',
'r_language_server',
'rust_analyzer',
'terraformls',
'svelte',
'texlab',
'clojure_lsp',
'elixirls',
'sourcekit',
'fsautocomplete',
'vls',
'hls',
'tflint',
'terraform_lsp',
}

@ -1,89 +0,0 @@
local vfn = vim.fn
local library = {}
local sumneko_cfg = {
cmd = { 'lua-language-server' },
filetypes = { 'lua' },
on_attach = on_attach,
flags = { allow_incremental_sync = true, debounce_text_changes = 500 },
settings = {
Lua = {
runtime = {
-- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
version = 'LuaJIT',
},
diagnostics = {
enable = true,
-- Get the language server to recognize the `vim` global
globals = { 'vim', 'describe', 'it', 'before_each', 'after_each', 'teardown', 'pending' },
},
completion = { callSnippet = 'Both' },
workspace = {
-- Make the server aware of Neovim runtime files
library = library,
maxPreload = 2000,
preloadFileSize = 40000,
},
telemetry = { enable = false },
},
},
on_new_config = function(cfg, root)
local libs = vim.tbl_deep_extend('force', {}, library)
libs[root] = nil
cfg.settings.Lua.workspace.library = libs
return cfg
end,
}
local function add(lib)
for _, p in pairs(vfn.expand(lib, false, true)) do
p = vim.loop.fs_realpath(p)
if p then
library[p] = true
end
end
end
local function sumneko_lua()
-- add runtime
-- add plugins it may be very slow to add all in path
add('$VIMRUNTIME')
-- add your config
-- local home = vfn.expand("$HOME")
add(vfn.stdpath('config'))
library[vfn.expand('$VIMRUNTIME/lua')] = true
library[vfn.expand('$VIMRUNTIME/lua/vim')] = true
library[vfn.expand('$VIMRUNTIME/lua/vim/lsp')] = true
local on_attach = require('navigator.lspclient.attach').on_attach
local luadevcfg = {
library = {
vimruntime = true, -- runtime path
types = true, -- full signature, docs and completion of vim.api, vim.treesitter, vim.lsp and others
plugins = { 'nvim-treesitter', 'plenary.nvim' },
},
lspconfig = {
-- cmd = {sumneko_binary},
on_attach = on_attach,
},
}
local luadev = {}
local user_luadev = _NgConfigValues.lsp['lua-dev']
if user_luadev then
luadevcfg = vim.tbl_deep_extend('force', luadevcfg, user_luadev)
end
require('navigator.lazyloader').load('lua-dev.nvim', 'folke/lua-dev.nvim')
local ok, l = pcall(require, 'lua-dev')
if ok and l then
luadev = l.setup(luadevcfg)
end
sumneko_cfg = vim.tbl_deep_extend('force', sumneko_cfg, luadev)
return sumneko_cfg
end
return {
sumneko_lua = sumneko_lua,
}

@ -19,7 +19,7 @@ cwd = gutil.add_pec(cwd)
local ts_nodes = require('navigator.lru').new(1000, 1024 * 1024) local ts_nodes = require('navigator.lru').new(1000, 1024 * 1024)
local ts_nodes_time = require('navigator.lru').new(1000) local ts_nodes_time = require('navigator.lru').new(1000)
local TS_analysis_enabled = require('navigator').config_values().treesitter_analysis local TS_analysis_enabled = require('navigator').config_values().treesitter_analysis
local nts = require('navigator.treesitter')
-- extract symbol from range -- extract symbol from range
function M.get_symbol(text, range) function M.get_symbol(text, range)
if range == nil then if range == nil then
@ -169,7 +169,7 @@ local function ts_functions(uri, optional)
lerr('ts not enabled') lerr('ts not enabled')
return nil return nil
end end
local ts_func = nts.buf_func local ts_func = require('navigator.treesitter').buf_func
local bufnr = vim.uri_to_bufnr(uri) local bufnr = vim.uri_to_bufnr(uri)
local x = os.clock() local x = os.clock()
trace(ts_nodes) trace(ts_nodes)
@ -230,7 +230,7 @@ local function ts_definition(uri, range, optional)
if optional then if optional then
return return
end end
local ts_def = nts.find_definition local ts_def = require('navigator.treesitter').find_definition
local bufnr = vim.uri_to_bufnr(uri) local bufnr = vim.uri_to_bufnr(uri)
local x = os.clock() local x = os.clock()
trace(ts_nodes) trace(ts_nodes)
@ -252,7 +252,6 @@ local function ts_definition(uri, range, optional)
end end
local function find_ts_func_by_range(funcs, range) local function find_ts_func_by_range(funcs, range)
log(funcs, range)
if funcs == nil or range == nil then if funcs == nil or range == nil then
return nil return nil
end end
@ -353,6 +352,7 @@ function M.locations_to_items(locations, ctx)
local unload_bufnrs = {} local unload_bufnrs = {}
for i, loc in ipairs(locations) do for i, loc in ipairs(locations) do
local funcs = nil
local item = lsp.util.locations_to_items({ loc }, enc)[1] local item = lsp.util.locations_to_items({ loc }, enc)[1]
item.range = locations[i].range or locations[i].targetRange item.range = locations[i].range or locations[i].targetRange
item.uri = locations[i].uri or locations[i].targetUri item.uri = locations[i].uri or locations[i].targetUri
@ -363,25 +363,13 @@ function M.locations_to_items(locations, ctx)
log(cwd) log(cwd)
end end
-- only load top 30 file. -- only load top 30 file.
local proj_file = item.uri:find(cwd) or is_win or i < _NgConfigValues.treesitter_analysis_max_num local proj_file = item.uri:find(cwd) or is_win or i < 30
local unload, def local unload, def
local context = '' if TS_analysis_enabled and proj_file then
if TS_analysis_enabled and proj_file and not ctx.no_show then funcs, unload = ts_functions(item.uri, ts_optional(i, #unload_bufnrs))
local ts_context = nts.ref_context
local bufnr = vim.uri_to_bufnr(item.uri)
if not api.nvim_buf_is_loaded(bufnr) then
log('! load buf !', item.uri, bufnr)
vim.fn.bufload(bufnr)
unload = bufnr
end
context = ts_context({ bufnr = bufnr, pos = item.range }) or ''
log(context)
-- TODO: unload buffers
if unload then if unload then
table.insert(unload_bufnrs, unload) table.insert(unload_bufnrs, unload)
unload = nil
end end
if not uri_def[item.uri] then if not uri_def[item.uri] then
-- find def in file -- find def in file
@ -420,15 +408,9 @@ function M.locations_to_items(locations, ctx)
end end
item.filename = assert(vim.uri_to_fname(item.uri)) item.filename = assert(vim.uri_to_fname(item.uri))
local filename = item.filename:gsub(cwd .. path_sep, path_cur, 1) local filename = item.filename:gsub(cwd .. path_sep, path_cur, 1)
if ctx.no_show then
local shorten = require('guihua.util').shorten
filename = shorten(filename)
end
item.display_filename = filename or item.filename item.display_filename = filename or item.filename
item.call_by = context -- find_ts_func_by_range(funcs, item.range) item.call_by = find_ts_func_by_range(funcs, item.range)
item.rpath = util.get_relative_path(cwd, item.filename) item.rpath = util.get_relative_path(cwd, item.filename)
width = math.max(width, #item.text) width = math.max(width, #item.text)
item.symbol_name = M.get_symbol(item.text, item.range) item.symbol_name = M.get_symbol(item.text, item.range)

@ -11,11 +11,10 @@ local locations_to_items = lsphelper.locations_to_items
local M = {} local M = {}
local ref_view = function(err, locations, ctx, cfg) local ref_view = function(err, locations, ctx, cfg)
cfg = cfg or {}
local truncate = cfg and cfg.truncate or 20 local truncate = cfg and cfg.truncate or 20
local opts = {} local opts = {}
trace('arg1', err, ctx, locations) trace('arg1', err, ctx, locations)
-- log(#locations, locations[1]) log(#locations, locations[1])
if ctx.combine then if ctx.combine then
-- wait for both reference and definition LSP request -- wait for both reference and definition LSP request
if ctx.results == nil then if ctx.results == nil then
@ -42,16 +41,24 @@ local ref_view = function(err, locations, ctx, cfg)
end end
vim.list_extend(locations, definitions.result) vim.list_extend(locations, definitions.result)
end end
if references and references.result and #references.result > 0 then if references and references.result and #references.result > 0 then
local refs = references.result local refs = references.result
for _, value in pairs(locations) do
local vrange = value.range or { start = { line = 0 }, ['end'] = { line = 0 } }
for i = 1, #refs, 1 do
local rg = refs[i].range or {}
trace(value, refs[i])
trace(rg, vrange)
if rg.start.line == vrange.start.line and rg['end'].line == vrange['end'].line then
table.remove(refs, i)
break
end
end
end
vim.list_extend(locations, refs) vim.list_extend(locations, refs)
end end
err = nil err = nil
trace(locations) trace(locations)
-- lets de-dup first 10 elements. some lsp does not recognize definition and reference difference
locations = util.dedup(locations)
trace(locations)
end end
-- log("num", num) -- log("num", num)
-- log("bfnr", bufnr) -- log("bfnr", bufnr)
@ -79,11 +86,11 @@ local ref_view = function(err, locations, ctx, cfg)
local thread_items = vim.deepcopy(items) local thread_items = vim.deepcopy(items)
log('splits: ', #items, #second_part) log('splits: ', #items, #second_part)
local ft = vim.api.nvim_buf_get_option(ctx.bufnr or 0, 'ft') local ft = vim.api.nvim_buf_get_option(ctx.bufnr, 'ft')
local wwidth = vim.api.nvim_get_option('columns') local wwidth = vim.api.nvim_get_option('columns')
local mwidth = _NgConfigValues.width local mwidth = _NgConfigValues.width
width = math.min(width + 30, math.floor(wwidth * mwidth)) width = math.min(width + 30, 120, math.floor(wwidth * mwidth))
-- log(items) -- log(items)
-- log(width) -- log(width)
opts = { opts = {
@ -95,22 +102,12 @@ local ref_view = function(err, locations, ctx, cfg)
api = 'Reference', api = 'Reference',
enable_preview_edit = true, enable_preview_edit = true,
} }
local listview local listview = gui.new_list_view(opts)
if not ctx.no_show then
listview = gui.new_list_view(opts)
if listview == nil then
vim.notify('failed to create preview windows', vim.lsp.log_levels.INFO)
return
end
end
if ctx.no_show then if listview == nil then
opts.side_panel = true vim.notify('failed to create preview windows', vim.lsp.log_levels.INFO)
local data = require('navigator.render').prepare_for_render(items, opts) return
return data
end end
-- trace("update items", listview.ctrl.class) -- trace("update items", listview.ctrl.class)
local nv_ref_async local nv_ref_async
nv_ref_async = vim.loop.new_async(vim.schedule_wrap(function() nv_ref_async = vim.loop.new_async(vim.schedule_wrap(function()
@ -145,9 +142,6 @@ end
local ref_hdlr = function(err, locations, ctx, cfg) local ref_hdlr = function(err, locations, ctx, cfg)
_NgConfigValues.closer = nil _NgConfigValues.closer = nil
trace(err, locations, ctx, cfg) trace(err, locations, ctx, cfg)
if ctx.no_show then
return ref_view(err, locations, ctx, cfg)
end
M.async_hdlr = vim.loop.new_async(vim.schedule_wrap(function() M.async_hdlr = vim.loop.new_async(vim.schedule_wrap(function()
ref_view(err, locations, ctx, cfg) ref_view(err, locations, ctx, cfg)
if M.async_hdlr:is_active() then if M.async_hdlr:is_active() then
@ -222,36 +216,7 @@ local ref = function()
end) end)
end end
local function side_panel()
local Panel = require('guihua.panel')
local currentWord = vim.fn.expand('<cword>')
local p = Panel:new({
scope = 'range',
header = '' .. currentWord .. ' ref ',
render = function(bufnr)
local ft = vim.api.nvim_buf_get_option(bufnr, 'buftype')
if ft == 'nofile' or ft == 'guihua' or ft == 'prompt' then
return
end
local ref_params = vim.lsp.util.make_position_params()
local sync_req = require('navigator.lspwrapper').call_sync
return sync_req(
'textDocument/references',
ref_params,
{ timeout = 1000, bufnr = bufnr, no_show = true },
vim.lsp.with(function(err, locations, ctx, cfg)
cfg.side_panel = true
return ref_hdlr(err, locations, ctx, cfg)
end, { no_show = true })
)
end,
})
p:open(true)
end
return { return {
side_panel = side_panel,
reference_handler = ref_hdlr, reference_handler = ref_hdlr,
reference = ref_req, reference = ref_req,
ref_view = ref_view, ref_view = ref_view,

@ -1,9 +1,7 @@
local util = require('navigator.util') local log = require('guihua.log').info
local log = util.log local trace = require('guihua.log').trace
local trace = util.trace
local clone = require('guihua.util').clone
local M = {} local M = {}
local clone = require('guihua.util').clone
local function filename(url) local function filename(url)
if url == nil then if url == nil then
return '' return ''
@ -71,7 +69,7 @@ function M.prepare_for_render(items, opts)
icon = devicons.get_icon(fn, ext) or icon icon = devicons.get_icon(fn, ext) or icon
end end
-- local call_by_presented = false -- local call_by_presented = false
opts.width = opts.width or math.floor(vim.api.nvim_get_option('columns') * 0.8) opts.width = opts.width or 100
local win_width = opts.width -- buf local win_width = opts.width -- buf
for i = 1, #items do for i = 1, #items do
@ -152,28 +150,52 @@ function M.prepare_for_render(items, opts)
trace(ts_report, header_len) trace(ts_report, header_len)
item.text = item.text:gsub('%s*[%[%(%{]*%s*$', '') item.text = item.text:gsub('%s*[%[%(%{]*%s*$', '')
if item.call_by ~= nil and item.call_by ~= '' then if item.call_by ~= nil and #item.call_by > 0 then
ts_report = ts_report .. '' .. item.call_by trace('call_by:', #item.call_by)
for _, value in pairs(item.call_by) do
if value.node_text then
local txt = value.node_text:gsub('%s*[%[%(%{]*%s*$', '')
local endwise = '{}'
if value.type == 'method' or value.type == 'function' then
endwise = '()'
local syb = items[i].symbol_name
if txt == items[i].symbol_name or (#txt > #syb and txt:sub(#txt - #syb + 1) == syb) then
if ts_report ~= _NgConfigValues.icons.value_definition .. ' ' then
ts_report = ts_report .. _NgConfigValues.icons.value_definition .. ' '
end
header_len = #ts_report + 1
else
ts_report = ts_report .. ''
end
end
if #ts_report > header_len then
ts_report = ts_report .. ''
end
ts_report = ts_report .. value.kind .. txt .. endwise
trace(item)
end
end
end end
if #ts_report > 1 then if #ts_report > 1 then
space, trim = get_pads(win_width, item.text, ts_report) space, trim = get_pads(win_width, item.text, ts_report)
local l = math.max(20, opts.width - math.min(20, #ts_report))
if trim and #item.text < l then
trim = false
end
if trim then if trim then
item.text = string.sub(item.text, 1, l) local ts_r = ts_report or ''
item.text = util.sub_match(item.text) item.text = string.sub(item.text, 1, math.max(1, opts.width - math.max(20, #ts_r)))
local _, j = string.gsub(item.text, [["]], '')
if j % 2 == 1 then
item.text = item.text .. '"'
end
_, j = string.gsub(item.text, [[']], '')
if j % 2 == 1 then
item.text = item.text .. [[']]
end
item.text = item.text .. ''
-- let check if there are unmatched "/' -- let check if there are unmatched "/'
end end
if #space + #item.text + #ts_report >= win_width then if #space + #item.text + #ts_report >= win_width then
if #item.text + #ts_report >= win_width then if #item.text + #ts_report > win_width then
space = ' ' trace('exceeding', #item.text, #ts_report, win_width)
local len = math.max(win_width - #item.text - 4, 16) space = ' '
trace('exceeding', #item.text, #ts_report, win_width, len)
ts_report = ts_report:sub(1, len)
else else
local remain = win_width - #item.text - #ts_report local remain = win_width - #item.text - #ts_report
trace('remain', remain) trace('remain', remain)

@ -23,7 +23,6 @@ local cwd = vim.loop.cwd()
local log = require('navigator.util').log local log = require('navigator.util').log
local lerr = require('navigator.util').error local lerr = require('navigator.util').error
local trace = function(...) end local trace = function(...) end
trace = log
if vim.fn.has('nvim-0.7') == 1 then if vim.fn.has('nvim-0.7') == 1 then
local trace = require('navigator.util').trace local trace = require('navigator.util').trace
end end
@ -110,96 +109,6 @@ function M.find_definition(range, bufnr)
end end
end end
function M.get_tsnode_at_pos(pos, bufnr, ignore_injected_langs)
if not pos or not pos.start then
return
end
local cursor_range = { pos.start.line, pos.start.character }
local buf = bufnr
local root_lang_tree = parsers.get_parser(buf)
if not root_lang_tree then
return
end
local root
if ignore_injected_langs then
for _, tree in ipairs(root_lang_tree:trees()) do
local tree_root = tree:root()
if tree_root and ts_utils.is_in_node_range(tree_root, cursor_range[1], cursor_range[2]) then
root = tree_root
break
end
end
else
root = ts_utils.get_root_for_position(cursor_range[1], cursor_range[2], root_lang_tree)
end
if not root then
return
end
return root:named_descendant_for_range(cursor_range[1], cursor_range[2], cursor_range[1], cursor_range[2])
end
-- Trim spaces and opening brackets from end
local transform_line = function(line)
line = line:gsub("%s*[%[%(%{]*%s*$", "")
line = line:gsub("function", "")
line = line:gsub("func%w*%s+", "")
if _NgConfigValues.treesitter_analysis_condense then
line = line:gsub("%([%a%.,%s%[%]%*]+%)", "()")
-- this is for multi return
line = line:gsub("%([%a%.,%s%[%]%*]+%)", "()")
line = line:gsub("%(%)%s*%(%)", "()")
end
return line
end
function M.ref_context(opts)
if not parsers.has_parser() then
return
end
local options = opts or {}
local bufnr = options.bufnr or 0
local pos = options.pos
if not pos then
pos = {start = vim.lsp.util.make_position_params().position}
end
local indicator_size = options.indicator_size or 100
local type_patterns = options.type_patterns or { "class", "function", "method" }
local transform_fn = options.transform_fn or transform_line
local separator = options.separator or ""
local current_node = M.get_tsnode_at_pos(pos, bufnr)
if not current_node then
log('no node at pos', bufnr, pos)
return ""
end
local lines = {}
local expr = current_node
while expr do
local line = ts_utils._get_line_for_node(expr, type_patterns, transform_fn, bufnr)
log(line)
if line ~= "" and not vim.tbl_contains(lines, line) then
table.insert(lines, 1, line)
end
expr = expr:parent()
end
local text = table.concat(lines, separator)
local text_len = #text
if text_len > indicator_size then
local str = text:sub(1, text_len)
return util.sub_match(str)
end
return text
end
--- Get definitions of bufnr (unique and sorted by order of appearance). --- Get definitions of bufnr (unique and sorted by order of appearance).
--- This function copy from treesitter/refactor/navigation.lua --- This function copy from treesitter/refactor/navigation.lua
local function get_definitions(bufnr) local function get_definitions(bufnr)
@ -212,23 +121,23 @@ local function get_definitions(bufnr)
ts_locals.recurse_local_nodes(loc.definition, function(_, node, _, match) ts_locals.recurse_local_nodes(loc.definition, function(_, node, _, match)
-- lua doesn't compare tables by value, -- lua doesn't compare tables by value,
-- use the value from byte count instead. -- use the value from byte count instead.
local row, col, offset = node:start() local k, l, start = node:start()
local erow, ecol, end_ = node:end_()
trace(node, match) trace(node, match)
trace(row, col, erow, offset, node:parent(), node:parent():start(), node:parent():type()) trace(k, l, start, node:parent(), node:parent():start(), node:parent():type())
if node and node:parent() and string.find(node:parent():type(), 'parameter_declaration') then if node and node:parent() and string.find(node:parent():type(), 'parameter_declaration') then
log('parameter_declaration skip') log('parameter_declaration skip')
return return
end end
nodes_set[offset] = { node = node, type = match or '' } nodes_set[start] = { node = node, type = match or '' }
end) end)
end end
if loc.method then -- for go if loc.method then -- for go
ts_locals.recurse_local_nodes(loc.method, function(def, node, full_match, match) ts_locals.recurse_local_nodes(loc.method, function(def, node, full_match, match)
local row, col, start = node:start() local k, l, start = node:start()
trace(row, col, start, def, node, full_match, match, node:parent(), node:parent():start(), node:parent():type())
trace(k, l, start, def, node, full_match, match, node:parent(), node:parent():start(), node:parent():type())
if node:type() == 'field_identifier' and nodes_set[start] == nil then if node:type() == 'field_identifier' and nodes_set[start] == nil then
nodes_set[start] = { node = node, type = 'method' } nodes_set[start] = { node = node, type = 'method' }
end end
@ -245,32 +154,16 @@ local function get_definitions(bufnr)
end end
if loc.reference then -- for go if loc.reference then -- for go
ts_locals.recurse_local_nodes(loc.reference, function(def, node, full_match, match) ts_locals.recurse_local_nodes(loc.reference, function(def, node, full_match, match)
local row, col, start = node:start() local k, l, start = node:start()
local p1, p1t = '', '' local p1, p1t = '', ''
local p2, p2t = '', '' local p2, p2t = '', ''
local p3, p3t = '', ''
if node:parent() and node:parent():parent() then if node:parent() and node:parent():parent() then
p1 = node:parent() p1 = node:parent()
p1t = node:parent():type() p1t = node:parent():type()
p2 = node:parent():parent() p2 = node:parent():parent()
p2t = node:parent():parent():type() p2t = node:parent():parent():type()
end end
if p2 and p2:parent() then trace(k, l, start, def, node, full_match, match, p1t, p1, node:parent():start(), node:parent():type(), p2, p2t)
p3 = p2:parent()
p3t = p2:parent():type()
end
trace(row, col, start, def, node, full_match, match, p1t, p1, node:parent():start(), node:parent():type(), p2, p2t, p3, p3t)
if p1t == 'arrow_function' then
row, col, start = p1:start()
trace('arrow_function 1', row, col)
nodes_set[start] = { node = p1, type = p1t }
end
if p2t == 'arrow_function' then
row, col, start = p2:start()
trace('arrow_function 2', row, col)
nodes_set[start] = { node = p2, type = p2t }
end
if nodes_set[start] == nil then if nodes_set[start] == nil then
if -- qualified_type : e.g. io.Reader inside interface if -- qualified_type : e.g. io.Reader inside interface
node:parent() node:parent()
@ -317,7 +210,7 @@ local function get_scope(type, source)
local parent = current:parent() local parent = current:parent()
trace(source:type(), source:range(), parent) trace(source:type(), source:range(), parent)
if type == 'method' or type:find('function') and parent ~= nil then if type == 'method' or type == 'function' and parent ~= nil then
trace(parent:type(), parent:range()) trace(parent:type(), parent:range())
-- a function name -- a function name
if parent:type() == 'function_name' then if parent:type() == 'function_name' then
@ -452,14 +345,13 @@ local function get_all_nodes(bufnr, filter, summary)
trace(bufnr, filter, summary) trace(bufnr, filter, summary)
if not bufnr then if not bufnr then
vim.notify('get_all_node invalid bufnr', vim.lsp.log_levels.WARN) vim.notify('get_all_node invalide bufnr', vim.lsp.log_levels.WARN)
end end
summary = summary or false summary = summary or false
local ft = vim.api.nvim_buf_get_option(bufnr, 'filetype') local ft = vim.api.nvim_buf_get_option(bufnr, 'filetype')
if not parsers.has_parser() then if not parsers.has_parser() then
if not require('navigator.lspclient.clients').ft_disabled(ft) then if not require('navigator.lspclient.clients').ft_disabled(ft) then
-- vim.notify('ts not loaded ' .. ft, vim.lsp.log_levels.Debug) vim.notify('ts not loaded ' .. ft, vim.lsp.log_levels.Debug)
log('ts not loaded ' .. ft)
end end
return {} return {}
end end
@ -469,13 +361,17 @@ local function get_all_nodes(bufnr, filter, summary)
local display_filename = fname:gsub(cwd .. path_sep, path_cur, 1) local display_filename = fname:gsub(cwd .. path_sep, path_cur, 1)
local all_nodes = {} local all_nodes = {}
local containers = filter or { -- Support completion-nvim customized label map
-- local customized_labels = vim.g.completion_customize_lsp_label or {}
-- Force some types to act like they are parents
-- instead of neighbors of the next nodes.
local containers = {
['function'] = true, ['function'] = true,
['local_function'] = true, ['local_function'] = true,
['arrow_function'] = true, ['arrow_function'] = true,
['type'] = true, ['type'] = true,
['class'] = true, ['class'] = true,
['call_expression'] = true,
-- ['var'] = true, -- ['var'] = true,
['struct'] = true, ['struct'] = true,
['method'] = true, ['method'] = true,
@ -498,8 +394,8 @@ local function get_all_nodes(bufnr, filter, summary)
for i = 1, n do for i = 1, n do
local index = n + 1 - i local index = n + 1 - i
local parent_def = parents[index] local parent_def = parents[index]
-- trace(parent_def.type, parent_def.node:type(), vim.treesitter.get_node_text(parent_def.node, bufnr)) log(parent_def.type, parent_def.node:type(), vim.treesitter.get_node_text(parent_def.node, bufnr))
-- trace(def.node:type(), vim.treesitter.get_node_text(def.node, bufnr)) log(def.node:type(), vim.treesitter.get_node_text(def.node, bufnr))
if if
ts_utils.is_parent(parent_def.node, def.node) ts_utils.is_parent(parent_def.node, def.node)
or ( or (
@ -513,10 +409,10 @@ local function get_all_nodes(bufnr, filter, summary)
) )
) )
then then
-- trace('is parent', i, index) log('is parent', i, index)
break break
else else
-- trace('leave node', i, index) log('leave node', i, index)
parents[index] = nil parents[index] = nil
end end
end end
@ -543,10 +439,7 @@ local function get_all_nodes(bufnr, filter, summary)
trace('skipped', item.type, item.kind) trace('skipped', item.type, item.kind)
goto continue goto continue
end end
local text = vim.treesitter.get_node_text(tsdata, bufnr) or '' item.node_text = vim.treesitter.get_node_text(tsdata, bufnr) or ''
text = vim.split(text, '\n')[1] or ''
item.node_text = text
log(item.node_text)
local scope, is_func local scope, is_func
if summary then if summary then
@ -554,7 +447,6 @@ local function get_all_nodes(bufnr, filter, summary)
else else
scope, is_func = get_smallest_context(tsdata) scope, is_func = get_smallest_context(tsdata)
end end
log(item, scope, is_func)
if is_func then if is_func then
-- hack for lua and maybe other language aswell -- hack for lua and maybe other language aswell
local parent = tsdata:parent() local parent = tsdata:parent()
@ -584,7 +476,7 @@ local function get_all_nodes(bufnr, filter, summary)
trace(item.node_text, item.kind, item.type) trace(item.node_text, item.kind, item.type)
if scope ~= nil then if scope ~= nil then
if not is_func and summary then if not is_func and summary then
trace('skipped', item.node_text, item.type) log('skipped', item.node_text, item.type)
goto continue goto continue
end end
item.node_scope = ts_utils.node_to_lsp_range(scope) item.node_scope = ts_utils.node_to_lsp_range(scope)
@ -688,7 +580,6 @@ function M.buf_func(bufnr)
local all_nodes, width = get_all_nodes(bufnr, { local all_nodes, width = get_all_nodes(bufnr, {
['function'] = true, ['function'] = true,
['arrow_function'] = true,
['var'] = true, ['var'] = true,
['method'] = true, ['method'] = true,
['class'] = true, ['class'] = true,
@ -722,7 +613,6 @@ function M.buf_func(bufnr)
return false return false
end) end)
end end
log(all_nodes)
return all_nodes, width return all_nodes, width
end end

@ -61,7 +61,7 @@ function M.get_data_from_file(filename, startLine)
return { data = data, line = displayLine } return { data = data, line = displayLine }
end end
function M.io_read(filename) function M.io_read(filename, total)
local f = io.open(filename, 'r') local f = io.open(filename, 'r')
if f == nil then if f == nil then
return nil return nil
@ -172,45 +172,41 @@ function M.get_relative_path(base_path, my_path)
return data return data
end end
M.log = function(...) local level = 'error'
return { ... } if _NgConfigValues.debug == true then
end level = 'info'
M.info = function(...) elseif _NgConfigValues.debug == 'trace' then
return { ... } level = 'trace'
end
M.trace = function(...)
return { ... }
end
M.warn = function(...)
return { ... }
end end
M.error = function(...) local default_config = { use_console = false, use_file = true, level = level }
print(...) if _NgConfigValues.debug_console_output then
default_config.use_console = true
default_config.use_file = false
end end
local level = 'error' M._log = require('guihua.log').new(default_config, true)
if _NgConfigValues.debug then
-- add log to you lsp.log
function M.setup() M.trace = M._log.trace
if _NgConfigValues.debug == true then M.info = M._log.info
level = 'info' M.warn = M._log.warn
elseif _NgConfigValues.debug == 'trace' then M.error = M._log.error
level = 'trace' M.log = M.info
else
M.log = function(...)
return { ... }
end end
local default_config = { use_console = false, use_file = true, level = level } M.info = function(...)
if _NgConfigValues.debug_console_output then return { ... }
default_config.use_console = true
default_config.use_file = false
end end
M.trace = function(...)
M._log = require('guihua.log').new(default_config, true) return { ... }
if _NgConfigValues.debug then end
-- add log to you lsp.log M.warn = function(...)
M.trace = M._log.trace return { ... }
M.info = M._log.info
M.warn = M._log.warn
M.error = M._log.error
M.log = M.info
end end
M.error = M._log.error
end end
function M.fmt(...) function M.fmt(...)
@ -491,47 +487,6 @@ function M.info(msg)
vim.notify('INF: ' .. msg, vim.lsp.log_levels.INFO) vim.notify('INF: ' .. msg, vim.lsp.log_levels.INFO)
end end
function M.dedup(locations)
local m = 10
if m > #locations then
m = #locations
end
local dict = {}
local del = {}
for i = 1, m, 1 do
local value = locations[i]
local range = value.range or value.originSelectionRange or value.targetRange
if not range then
break
end
local key = (value.uri or range.uri or value.targetUri or '')
.. ':'
.. tostring(range.start.line)
.. ':'
.. tostring(range.start.character)
.. ':'
.. tostring(range['end'].line)
.. ':'
.. tostring(range['end'].character)
if dict[key] == nil then
dict[key] = i
else
local j = dict[key]
if not locations[j].definition then
table.insert(del, i)
else
table.insert(del, j)
end
end
end
table.sort(del)
for i = #del, 1, -1 do
M.log('remove ', del[i])
table.remove(locations, del[i])
end
return locations
end
function M.range_inside(outer, inner) function M.range_inside(outer, inner)
if outer == nil or inner == nil then if outer == nil or inner == nil then
return false return false
@ -542,31 +497,4 @@ function M.range_inside(outer, inner)
return outer.start.line <= inner.start.line and outer['end'].line >= inner['end'].line return outer.start.line <= inner.start.line and outer['end'].line >= inner['end'].line
end end
function M.dirname(pathname)
local path_sep = require('navigator.util').path_sep()
local strip_dir_pat = path_sep .. '([^' .. path_sep .. ']+)$'
local strip_sep_pat = path_sep .. '$'
if not pathname or #pathname == 0 then
return
end
local result = pathname:gsub(strip_sep_pat, ''):gsub(strip_dir_pat, '')
if #result == 0 then
return '/'
end
return result
end
function M.sub_match(str)
local _, j = string.gsub(str, [["]], '')
if j % 2 == 1 then
str = str .. '"'
end
_, j = string.gsub(str, [[']], '')
if j % 2 == 1 then
str = str .. [[']]
end
str = str .. ''
return str
end
return M return M

@ -19,7 +19,7 @@ M.remove_workspace_folder = function()
local folders = vim.lsp.buf.list_workspace_folders() local folders = vim.lsp.buf.list_workspace_folders()
if #folders > 1 then if #folders > 1 then
return select(folders, { prompt = 'select workspace to delete' }, function(workspace) select(folders, { prompt = 'select workspace to delete' }, function(workspace)
vim.lsp.buf.remove_workspace_folder(workspace) vim.lsp.buf.remove_workspace_folder(workspace)
end) end)
end end
@ -37,7 +37,7 @@ function M.workspace_symbol_live()
local height = _NgConfigValues.height or 0.4 local height = _NgConfigValues.height or 0.4
height = math.floor(height * vfn.winheight('%')) height = math.floor(height * vfn.winheight('%'))
local width = _NgConfigValues.width or 0.7 local width = _NgConfigValues.width or 0.7
width = math.floor(vim.api.nvim_get_option('columns') * width) width = math.floor(width * vfn.winwidth('%'))
local bufnr = vim.api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
local ft = vim.o.ft local ft = vim.o.ft
local data = { { text = 'input the symbol name to start fuzzy search' } } local data = { { text = 'input the symbol name to start fuzzy search' } }
@ -47,7 +47,7 @@ function M.workspace_symbol_live()
local ListView = require('guihua.listview') local ListView = require('guihua.listview')
local opt = { local opt = {
api = '', api = '',
bg = 'GuihuaListDark', bg = 'GHListDark',
data = data, data = data,
items = data, items = data,
enter = true, enter = true,

@ -41,23 +41,12 @@ local function load_plugins()
use({ 'ray-x/lsp_signature.nvim' }) use({ 'ray-x/lsp_signature.nvim' })
use({ 'ray-x/aurora' }) use({ 'ray-x/aurora' })
use({ use({
-- 'ray-x/navigator.lua', 'ray-x/navigator.lua',
'~/github/ray-x/navigator.lua', -- '~/github/ray-x/navigator.lua',
requires = { 'ray-x/guihua.lua', run = 'cd lua/fzy && make' }, requires = { 'ray-x/guihua.lua', run = 'cd lua/fzy && make' },
config = function() config = function()
require('navigator').setup({ require('navigator').setup({
debug = true, lsp_signature_help = true,
keymaps = {
{ key = 'gK', func = vim.lsp.buf.definition, doc = 'definition' },
{
key = '<leader>ld',
func = require('navigator.diagnostics').show_buf_diagnostics,
desc = 'show_buf_diagnostics',
},
},
icons = {
diagnostic_virtual_text = '',
},
}) })
end, end,
}) })

@ -1,6 +1 @@
std="lua52+vim" std="vim"
[rules]
global_usage = "allow"
multiple_statements = "allow"
unused_variable = "allow"

@ -60,10 +60,10 @@ describe('should run lsp call hierarchy', function()
-- eq(panel.activePanel.sections[1].nodes[1].name, 'measure') -- eq(panel.activePanel.sections[1].nodes[1].name, 'measure')
end) end)
it('should not crash and show hierarchy', function() it('should show hierarchy', function()
vim.fn.setpos('.', { bufn, 24, 15, 0 }) vim.fn.setpos('.', { bufn, 24, 15, 0 })
local ret = require('navigator.hierarchy')._call_hierarchy() local ret = require('navigator.hierarchy')._call_hierarchy()
vim.wait(400, function() end) vim.wait(400, function() end)
eq(ret, ret) -- make sure doesn't crash the result eq(ret, {})
end) end)
end) end)

@ -114,9 +114,9 @@ describe('should run lsp reference', function()
-- print('win', vim.inspect(win)) -- print('win', vim.inspect(win))
print('items', vim.inspect(items)) print('items', vim.inspect(items))
eq(win.ctrl.data[1].display_filename, './tests/fixtures/interface.go') eq(win.ctrl.data[1].display_filename, './interface.go')
eq(win.ctrl.data[2].range.start.line, 14) eq(win.ctrl.data[2].range.start.line, 14)
eq(items[1].display_filename, './tests/fixtures/interface.go') eq(items[1].display_filename, './interface.go')
-- eq(width, 60) -- eq(width, 60)
end) end)
@ -137,7 +137,7 @@ describe('should run lsp reference', function()
-- print('win', vim.inspect(win)) -- print('win', vim.inspect(win))
print('items', vim.inspect(items)) print('items', vim.inspect(items))
-- eq(win.ctrl.data, "./interface.go") -- eq(win.ctrl.data, "./interface.go")
eq(win.ctrl.data[1].display_filename, './tests/fixtures/interface.go') eq(win.ctrl.data[1].display_filename, './interface.go')
eq(win.ctrl.data[2].range.start.line, 14) eq(win.ctrl.data[2].range.start.line, 14)
-- eq(items[1].display_filename, "./interface.go") -- eq(items[1].display_filename, "./interface.go")

@ -1,5 +1,5 @@
[selene] [selene]
base = "lua52" base = "lua51"
name = "vim" name = "vim"
[vim] [vim]
@ -8,11 +8,9 @@ any = true
[_G] [_G]
property = true property = true
writable = "new-fields" writable = "new-fields"
[_NgConfigValues] [_NgConfigValues]
any = true property = true
# property = true writable = "new-fields"
# writable = "full-write"
[debug] [debug]
property = true property = true

@ -1,47 +0,0 @@
---
base: lua52
name: vim
globals:
_G:
property: new-fields
_NgConfigValues:
any: true
after_each:
args:
- type: function
assert.equals:
args:
- type: any
- type: any
- required: false
type: any
assert.is_not:
any: true
assert.same:
args:
- type: any
- type: any
assert.spy:
args:
- type: any
assert.stub:
args:
- type: any
assert.truthy:
args:
- type: any
before_each:
args:
- type: function
debug:
property: read-only
describe:
args:
- type: string
- type: function
it:
args:
- type: string
- type: function
vim:
any: true
Loading…
Cancel
Save