forked from Archives/navigator.lua
Compare commits
7 Commits
master
...
neovim_0.6
Author | SHA1 | Date | |
---|---|---|---|
|
251bb84471 | ||
|
c591efe445 | ||
|
c6ed0bc78e | ||
|
00d5d67932 | ||
|
77554e1beb | ||
|
c14f9ca140 | ||
|
25af6afb71 |
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -15,11 +15,11 @@ jobs:
|
||||
manager: sudo snap
|
||||
packages: go
|
||||
- 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
|
||||
packages: go
|
||||
- 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
|
||||
packages: go
|
||||
steps:
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,3 @@
|
||||
selene.toml
|
||||
|
||||
lua/navigator.lua.bak
|
||||
tests/fixtures/tests
|
158
README.md
158
README.md
@ -72,11 +72,11 @@ variable is:
|
||||
|
||||
- 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
|
||||
|
||||
- LSP multiple symbols highlight/marker and hop between document references
|
||||
- LSP multiple symbol highlight/marker and hop between document references
|
||||
|
||||
- Preview definination/references
|
||||
|
||||
@ -96,7 +96,7 @@ variable is:
|
||||
|
||||
- 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
|
||||
|
||||
@ -257,14 +257,12 @@ require'navigator'.setup({
|
||||
-- end,
|
||||
-- The attach code will apply to all LSP clients
|
||||
|
||||
ts_fold = false, -- modified version of treesitter folding
|
||||
default_mapping = true, -- set to false if you will remap every key or if you using old version of nvim-
|
||||
keymaps = {{key = "gK", func = vim.lsp.declaration, desc = 'declaration'}}, -- a list of key maps
|
||||
default_mapping = true, -- set to false if you will remap every key
|
||||
keymaps = {{key = "gK", func = "declaration()"}}, -- a list of key maps
|
||||
-- this kepmap gK will override "gD" mapping function declaration() in default kepmap
|
||||
-- please check mapping.lua for all keymaps
|
||||
treesitter_analysis = true, -- treesitter variable context
|
||||
treesitter_analysis_max_num = 100, -- how many items to run treesitter analysis
|
||||
treesitter_analysis_condense = true, -- condense form for treesitter analysis
|
||||
-- this value prevent slow in large projects, e.g. found 100000 reference in a project
|
||||
transparency = 50, -- 0 ~ 100 blur the main window, 100: fully transparent, 0: opaque, set to nil or 100 to disable it
|
||||
|
||||
@ -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
|
||||
icons = {
|
||||
-- Code action
|
||||
code_action_icon = "🏏", -- note: need terminal support, for those not support unicode, might crash
|
||||
code_action_icon = "🏏",
|
||||
-- Diagnostics
|
||||
diagnostic_head = '🐛',
|
||||
diagnostic_head_severity_1 = "🈲",
|
||||
-- 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
|
||||
mason = false, -- set to true if you would like use the lsp installed by williamboman/mason
|
||||
lsp = {
|
||||
enable = true, -- skip lsp setup if disabled make sure add require('navigator.lspclient.mapping').setup() in you
|
||||
-- own on_attach
|
||||
code_action = {enable = true, sign = true, sign_priority = 40, virtual_text = true},
|
||||
code_lens_action = {enable = true, sign = true, sign_priority = 40, virtual_text = true},
|
||||
document_highlight = true, -- LSP reference highlight,
|
||||
-- it might already supported by you setup, e.g. LunarVim
|
||||
format_on_save = true, -- 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
|
||||
-- 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
|
||||
--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
|
||||
-- disable_lsp = 'all' and you may need to hook mapping.setup() in your on_attach
|
||||
-- disable_lsp = 'all'
|
||||
-- Default {}
|
||||
diagnostic = {
|
||||
underline = true,
|
||||
@ -316,9 +308,9 @@ require'navigator'.setup({
|
||||
},
|
||||
ctags ={
|
||||
cmd = 'ctags',
|
||||
tagfile = 'tags',
|
||||
options = '-R --exclude=.git --exclude=node_modules --exclude=test --exclude=vendor --excmd=number',
|
||||
},
|
||||
tagfile = 'tags'
|
||||
options = '-R --exclude=.git --exclude=node_modules --exclude=test --exclude=vendor --excmd=number'
|
||||
}
|
||||
gopls = { -- gopls setting
|
||||
on_attach = function(client, bufnr) -- on_attach for gopls
|
||||
-- your special on attach here
|
||||
@ -330,18 +322,6 @@ require'navigator'.setup({
|
||||
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_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",
|
||||
@ -449,7 +429,7 @@ In `playground` folder, there is a `init.lua` and source code for you to play wi
|
||||
| n | gd | definition |
|
||||
| n | g0 | document symbol |
|
||||
| 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 | g\<LeftMouse\> | implementation |
|
||||
| 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 | \<ESC\> | close listview of floating window |
|
||||
| i/n | \<C-e\> | close listview of floating window |
|
||||
| n | \<C-q\> | close listview and send results to quickfix |
|
||||
| i/n | \<C-b\> | previous page in listview |
|
||||
| i/n | \<C-f\> | next page in listview |
|
||||
| i/n | \<C-s\> | save the modification to preview window to file |
|
||||
|
||||
### Colors/Highlight:
|
||||
|
||||
You can override default highlight GuihuaListDark (listview) and GuihuaTextViewDark (code view) and GuihuaListHl (select item)
|
||||
You can override default highlight GHListDark (listview) and GHTextViewDark (code view) and GHListHl (select item)
|
||||
|
||||
e.g.
|
||||
|
||||
```vim
|
||||
hi default GuihuaTextViewDark guifg=#e0d8f4 guibg=#332e55
|
||||
hi default GuihuaListDark guifg=#e0d8f4 guibg=#103234
|
||||
hi default GuihuaListHl guifg=#e0d8f4 guibg=#404254
|
||||
hi default GHTextViewDark guifg=#e0d8f4 guibg=#332e55
|
||||
hi default GHListDark guifg=#e0d8f4 guibg=#103234
|
||||
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,
|
||||
@ -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).
|
||||
|
||||
## 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
|
||||
lsp_installer = true --lsp_installer users, deprecated
|
||||
mason = true -- mason user
|
||||
lsp_installer = true
|
||||
|
||||
```
|
||||
|
||||
In the config. Also please setup the lsp server from installer setup with `server:setup{opts}`
|
||||
|
||||
lsp-installer example:
|
||||
example:
|
||||
```lua
|
||||
use({
|
||||
'williamboman/nvim-lsp-installer',
|
||||
@ -546,79 +525,14 @@ lsp-installer example:
|
||||
'ray-x/navigator.lua',
|
||||
config = function()
|
||||
require('navigator').setup({
|
||||
debug = true,
|
||||
lsp_installer = true,
|
||||
keymaps = { { key = 'gR', func = "require('navigator.reference').async_ref()" } },
|
||||
})
|
||||
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)
|
||||
for more info
|
||||
@ -634,9 +548,7 @@ To start LSP installed by lsp_installer, please use following setups
|
||||
require'navigator'.setup({
|
||||
-- lsp_installer = false -- default value is false
|
||||
lsp = {
|
||||
tsserver = { cmd = {'your tsserver installed by lsp_installer or mason'} }
|
||||
-- e.g. tsserver = { cmd = {'/home/username/.local/share/nvim/mason/packages/typescript-language-server/node_modules/typescript/bin/tsserver'} }
|
||||
|
||||
tsserver = { cmd = {'your tsserver installed by lsp_installer'} }
|
||||
}
|
||||
})
|
||||
|
||||
@ -651,7 +563,6 @@ require'navigator'.setup({
|
||||
lsp = {
|
||||
tsserver = {
|
||||
cmd = { "/Users/username/.local/share/nvim/lsp_servers/python/node_modules/.bin/pyright-langserver", "--stdio" }
|
||||
-- or mason: cmd = { "/Users/username/.local/share/nvim/mason/packages/pyright/node_modules/pyright/index.js", "--stdio"}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
There are lots of plugins provides lsp support
|
||||
* go.nvim allow you either hook gopls from go.nvim or from navigator and it can export the lsp setup from go.nvim.
|
||||
* rust-tools and clangd allow you to setup on_attach from config server
|
||||
* [lua-dev](https://github.com/folke/lua-dev.nvim) Dev setup for init.lua and plugin development. Navigator can
|
||||
extend lua setup with lua-dev.
|
||||
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
|
||||
Here is an example to setup rust with rust-tools
|
||||
|
||||
```lua
|
||||
require'navigator'.setup({
|
||||
lsp = {
|
||||
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({
|
||||
server = {
|
||||
on_attach = function(client, bufnr)
|
||||
require('navigator.lspclient.mapping').setup({client=client, bufnr=bufnr}) -- setup navigator keymaps here,
|
||||
|
||||
require("navigator.dochighlight").documentHighlight(bufnr)
|
||||
require('navigator.codeAction').code_action_prompt(bufnr)
|
||||
-- otherwise, you can define your own commands to call navigator functions
|
||||
end,
|
||||
}
|
||||
@ -723,8 +629,6 @@ require("clangd_extensions").setup {
|
||||
server = {
|
||||
on_attach = function(client, bufnr)
|
||||
require('navigator.lspclient.mapping').setup({client=client, bufnr=bufnr}) -- setup navigator keymaps here,
|
||||
require("navigator.dochighlight").documentHighlight(bufnr)
|
||||
require('navigator.codeAction').code_action_prompt(bufnr)
|
||||
-- otherwise, you can define your own commands to call navigator functions
|
||||
end,
|
||||
}
|
||||
@ -760,7 +664,7 @@ Highlight I am using:
|
||||
- LspReferenceRead, LspReferenceText and LspReferenceWrite are used for `autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()`
|
||||
That is where you saw the current symbol been highlighted.
|
||||
|
||||
- GuihuaListDark and GuihuaTextViewDark is used for floating listvew and TextView. They are be based on current background
|
||||
- GHListDark and GHTextViewDark is used for floating listvew and TextView. They are be based on current background
|
||||
(Normal) and PmenuSel
|
||||
|
||||
- In future, I will use NormalFloat for floating view. But ATM, most of colorscheme does not define NormalFloat
|
||||
@ -777,7 +681,6 @@ You can override the above highlight to fit your current colorscheme
|
||||
| LspRestart | reload lsp |
|
||||
| LspToggleFmt | toggle lsp format |
|
||||
| LspSymbols | document symbol in side panel |
|
||||
| NRefPanel | show symbol reference in side panel |
|
||||
| TSymobls | treesitter symbol in side panel |
|
||||
| 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
|
||||
|
||||
Folding is using a hacked version of treesitter folding. (option: ts_fold)
|
||||
|
||||
#### folding function
|
||||
|
||||
![image](https://user-images.githubusercontent.com/1681295/148491596-6cd6c507-c157-4536-b8c4-dc969436763a.png)
|
||||
|
||||
#### 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)
|
||||
|
||||
|
@ -477,13 +477,13 @@ DEFAULT KEYMAPS *navigator-default_keymap
|
||||
|
||||
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.
|
||||
>
|
||||
hi default GuihuaTextViewDark guifg=#e0d8f4 guibg=#332e55
|
||||
hi default GuihuaListDark guifg=#e0d8f4 guibg=#103234
|
||||
hi default GuihuaListHl guifg=#e0d8f4 guibg=#404254
|
||||
hi default GHTextViewDark guifg=#e0d8f4 guibg=#332e55
|
||||
hi default GHListDark guifg=#e0d8f4 guibg=#103234
|
||||
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,
|
||||
@ -644,7 +644,7 @@ Highlight I am using:
|
||||
|
||||
* LspReferenceRead, LspReferenceText and LspReferenceWrite are used for `autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()`
|
||||
That is where you saw the current symbol been highlighted.
|
||||
* GuihuaListDark and GuihuaTextViewDark is used for floating listvew and TextView. They are be based on current background
|
||||
* GHListDark and GHTextViewDark is used for floating listvew and TextView. They are be based on current background
|
||||
(Normal) and PmenuSel
|
||||
* In future, I will use NormalFloat for floating view. But ATM, most of colorscheme does not define NormalFloat
|
||||
|
||||
@ -660,9 +660,8 @@ COMMANDS *navigator-command
|
||||
| Nctags {args} | show ctags symbols, args: -g regen ctags |
|
||||
| LspRestart | reload lsp |
|
||||
| LspSymbols | document symbol in side panel |
|
||||
| NRefPanel |symbol reference 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*
|
||||
Toggle lsp auto format.
|
||||
@ -684,9 +683,6 @@ COMMANDS *navigator-command
|
||||
:TSSymbols *:TSSymbols*
|
||||
Treesitter symbol in side panel.
|
||||
|
||||
:NRefPanel *:NRefPanel*
|
||||
Symbol reference in side panel.
|
||||
|
||||
:Calltree [flags] *:Calltree*
|
||||
Lsp call hierarchy call tree.
|
||||
[flags]:
|
||||
|
@ -1,14 +1,11 @@
|
||||
local M = {}
|
||||
local api = vim.api
|
||||
|
||||
local function warn(msg)
|
||||
api.nvim_echo({ { 'WRN: ' .. msg, 'WarningMsg' } }, true, {})
|
||||
vim.api.nvim_echo({ { 'WRN: ' .. msg, 'WarningMsg' } }, true, {})
|
||||
end
|
||||
|
||||
local function info(msg)
|
||||
if _NgConfigValues.debug then
|
||||
api.nvim_echo({ { 'Info: ' .. msg } }, true, {})
|
||||
end
|
||||
vim.api.nvim_echo({ { 'Info: ' .. msg } }, true, {})
|
||||
end
|
||||
|
||||
_NgConfigValues = {
|
||||
@ -19,7 +16,7 @@ _NgConfigValues = {
|
||||
preview_lines = 40, -- total lines in preview screen
|
||||
preview_lines_before = 5, -- lines before the highlight line
|
||||
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
|
||||
|
||||
border = 'single', -- border style, can be one of 'none', 'single', 'double', "shadow"
|
||||
@ -32,16 +29,11 @@ _NgConfigValues = {
|
||||
ts_fold = false,
|
||||
treesitter_analysis = true, -- treesitter variable context
|
||||
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
|
||||
lsp_signature_help = true, -- if you would like to hook ray-x/lsp_signature plugin in navigator
|
||||
-- setup here. if it is nil, navigator will not init signature help
|
||||
signature_help_cfg = { debug = false }, -- if you would like to init ray-x/lsp_signature plugin in navigator, pass in signature help
|
||||
ctags = {
|
||||
cmd = 'ctags',
|
||||
tagfile = '.tags',
|
||||
options = '-R --exclude=.git --exclude=node_modules --exclude=test --exclude=vendor --excmd=number',
|
||||
},
|
||||
ctags = { cmd = 'ctags', tagfile = '.tags' },
|
||||
lsp = {
|
||||
enable = true, -- if disabled make sure add require('navigator.lspclient.mapping').setup() in you on_attach
|
||||
code_action = {
|
||||
@ -51,7 +43,6 @@ _NgConfigValues = {
|
||||
virtual_text = true,
|
||||
virtual_text_icon = true,
|
||||
},
|
||||
document_highlight = true, -- highlight reference a symbol
|
||||
code_lens_action = {
|
||||
enable = true,
|
||||
sign = true,
|
||||
@ -66,7 +57,6 @@ _NgConfigValues = {
|
||||
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_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_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
|
||||
@ -81,10 +71,6 @@ _NgConfigValues = {
|
||||
-- filetypes = {'typescript'} -- disable javascript etc,
|
||||
-- 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_root_path = sumneko_root_path,
|
||||
-- sumneko_binary = sumneko_binary,
|
||||
@ -93,7 +79,6 @@ _NgConfigValues = {
|
||||
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
|
||||
mason = false, -- set to true if you would like use the lsp installed by williamboman/mason
|
||||
icons = {
|
||||
icons = true, -- set to false to use system default ( if you using a terminal does not have nerd/icon)
|
||||
-- Code action
|
||||
@ -172,8 +157,6 @@ local extend_config = function(opts)
|
||||
if opts.debug then
|
||||
_NgConfigValues.debug = opts.debug
|
||||
end
|
||||
-- enable logs
|
||||
require('navigator.util').setup()
|
||||
for key, value in pairs(opts) do
|
||||
if _NgConfigValues[key] == nil then
|
||||
warn(
|
||||
@ -216,12 +199,12 @@ local extend_config = function(opts)
|
||||
else
|
||||
if _NgConfigValues[key][k] == nil 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
|
||||
info(string.format('[] extend LSP support for %s %s ', key, k))
|
||||
end
|
||||
elseif key == 'keymaps' then
|
||||
info('keymap override' .. vim.inspect(v))
|
||||
info('keymap override')
|
||||
-- skip key check and allow mapping to handle that
|
||||
else
|
||||
warn(string.format('[] Key %s %s not valid', key, k))
|
||||
@ -251,14 +234,7 @@ M.setup = function(cfg)
|
||||
cfg = cfg or {}
|
||||
extend_config(cfg)
|
||||
|
||||
local cmd_group = api.nvim_create_augroup('NGFtGroup', {})
|
||||
api.nvim_create_autocmd({ 'FileType', 'BufEnter' }, {
|
||||
group = cmd_group,
|
||||
pattern = '*',
|
||||
callback = function()
|
||||
require('navigator.lspclient.clients').on_filetype()
|
||||
end,
|
||||
})
|
||||
vim.cmd([[autocmd FileType,BufEnter * lua require'navigator.lspclient.clients'.on_filetype()]]) -- BufWinEnter BufNewFile,BufRead ?
|
||||
require('navigator.lazyloader').init()
|
||||
require('navigator.lspclient.clients').setup(_NgConfigValues)
|
||||
|
||||
@ -268,8 +244,7 @@ M.setup = function(cfg)
|
||||
require('navigator.implementation')
|
||||
|
||||
cfg.lsp = cfg.lsp or _NgConfigValues.lsp
|
||||
|
||||
if _NgConfigValues.lsp.enable then
|
||||
if cfg.lsp.enable then
|
||||
require('navigator.diagnostics').config(cfg.lsp.diagnostic)
|
||||
end
|
||||
if not _NgConfigValues.loaded then
|
||||
@ -286,6 +261,7 @@ M.setup = function(cfg)
|
||||
local _start_client = vim.lsp.start_client
|
||||
vim.lsp.start_client = function(lsp_config)
|
||||
-- add highlight for Lspxxx
|
||||
require('navigator.dochighlight').documentHighlight()
|
||||
require('navigator.lspclient.highlight').add_highlight()
|
||||
require('navigator.lspclient.highlight').diagnositc_config_sign()
|
||||
-- require('navigator.lspclient.mapping').setup()
|
||||
|
@ -152,13 +152,9 @@ local code_action_req = function(_call_back_fn, diagnostics)
|
||||
end
|
||||
|
||||
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)
|
||||
return a[1] > b[1]
|
||||
end)
|
||||
end
|
||||
|
||||
trace(action_tuples)
|
||||
-- table.sort(action_tuples, function(a, b)
|
||||
-- return a[1] > b[1]
|
||||
-- end)
|
||||
require('guihua.gui').select(action_tuples, opts, on_user_choice)
|
||||
end
|
||||
|
||||
@ -166,6 +162,8 @@ code_action.code_action = function()
|
||||
local original_select = vim.ui.select
|
||||
vim.ui.select = sort_select
|
||||
|
||||
log('codeaction')
|
||||
|
||||
vim.lsp.buf.code_action()
|
||||
vim.defer_fn(function()
|
||||
vim.ui.select = original_select
|
||||
@ -188,19 +186,17 @@ code_action.range_code_action = function(startpos, endpos)
|
||||
|
||||
local original_input = vim.ui.input
|
||||
vim.ui.input = require('guihua.input').input
|
||||
|
||||
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.lsp.buf.range_code_action(context, startpos, endpos)
|
||||
vim.defer_fn(function()
|
||||
vim.ui.select = original_select
|
||||
end, 1000)
|
||||
|
||||
vim.defer_fn(function()
|
||||
vim.ui.input = original_input
|
||||
end, 1000)
|
||||
end
|
||||
|
||||
code_action.code_action_prompt = function(bufnr)
|
||||
code_action.code_action_prompt = function()
|
||||
if special_buffers[vim.bo.filetype] then
|
||||
log('skip buffer', vim.bo.filetype)
|
||||
return
|
||||
|
@ -5,7 +5,7 @@ local codelens = require('vim.lsp.codelens')
|
||||
|
||||
local log = require('navigator.util').log
|
||||
local trace = require('navigator.util').trace
|
||||
-- trace = log
|
||||
|
||||
local lsphelper = require('navigator.lspwrapper')
|
||||
local api = vim.api
|
||||
local M = {}
|
||||
@ -61,19 +61,24 @@ local codelens_hdlr = function(err, result, ctx, cfg)
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup(bufnr)
|
||||
log('setup for ****** ', bufnr)
|
||||
vim.api.nvim_set_hl(0, 'LspCodeLens', { link = 'DiagnosticsHint', default = true })
|
||||
vim.api.nvim_set_hl(0, 'LspCodeLensText', { link = 'DiagnosticsInformation', default = true })
|
||||
vim.api.nvim_set_hl(0, 'LspCodeLensSign', { link = 'DiagnosticsInformation', default = true })
|
||||
vim.api.nvim_set_hl(0, 'LspCodeLensSeparator', { link = 'Boolean', default = true })
|
||||
vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI', 'InsertLeave' }, {
|
||||
group = vim.api.nvim_create_augroup('nv__codelenses', {}),
|
||||
buffer = bufnr or vim.api.nvim_win_get_buf(),
|
||||
callback = function()
|
||||
require('navigator.codelens').refresh()
|
||||
end,
|
||||
})
|
||||
function M.setup()
|
||||
vim.cmd('highlight! link LspCodeLens LspDiagnosticsHint')
|
||||
vim.cmd('highlight! link LspCodeLensText LspDiagnosticsInformation')
|
||||
vim.cmd('highlight! link LspCodeLensTextSign LspDiagnosticsSignInformation')
|
||||
vim.cmd('highlight! link LspCodeLensTextSeparator Boolean')
|
||||
|
||||
vim.cmd('augroup navigator.codelenses')
|
||||
vim.cmd(' autocmd!')
|
||||
vim.cmd("autocmd BufEnter,CursorHold,InsertLeave <buffer> lua require('navigator.codelens').refresh()")
|
||||
vim.cmd('augroup end')
|
||||
local on_codelens = vim.lsp.handlers['textDocument/codeLens']
|
||||
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
|
||||
|
||||
M.lsp_clients = {}
|
||||
@ -86,7 +91,7 @@ function M.refresh()
|
||||
if not lsphelper.check_capabilities('codeLensProvider') then
|
||||
return
|
||||
end
|
||||
M.inline()
|
||||
vim.lsp.codelens.refresh()
|
||||
end
|
||||
|
||||
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
|
||||
vim.ui.select = require('guihua.gui').select
|
||||
|
||||
log('codelens action')
|
||||
log('codeaction')
|
||||
|
||||
codelens.run()
|
||||
vim.defer_fn(function()
|
||||
vim.ui.select = original_select
|
||||
end, 1000)
|
||||
|
||||
end
|
||||
|
||||
M.inline = function()
|
||||
@ -125,20 +129,42 @@ M.inline = function()
|
||||
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
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
|
||||
api.nvim_buf_clear_namespace(bufnr, virtual_types_ns, 0, -1)
|
||||
-- Clear previous highlighting
|
||||
api.nvim_buf_clear_namespace(bufnr, virtual_types_ns, 0, -1)
|
||||
|
||||
if response then
|
||||
trace(response)
|
||||
if response then
|
||||
log(response)
|
||||
for _, v in ipairs(response) do
|
||||
if v == nil or v.result == nil then
|
||||
return
|
||||
end -- no response
|
||||
for _, vv in pairs(v.result) do
|
||||
local start_line = -1
|
||||
for _, vvv in pairs(vv.range) do
|
||||
start_line = tonumber(vvv.line)
|
||||
end
|
||||
|
||||
on_codelens(err, response, ctx, _)
|
||||
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
|
||||
|
||||
codelens_hdlr (err, response, ctx, _)
|
||||
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)
|
||||
-- else
|
||||
-- api.nvim_command("echohl WarningMsg | echo 'VirtualTypes: No response' | echohl None")
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -89,7 +89,7 @@ local function ctags_symbols()
|
||||
local height = _NgConfigValues.height or 0.4
|
||||
local width = _NgConfigValues.width or 0.7
|
||||
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 ctags_file = _NgConfigValues.ctags.tagfile
|
||||
if not util.file_exists(ctags_file) then
|
||||
@ -118,7 +118,7 @@ local function ctags_symbols()
|
||||
local opt = {
|
||||
api = ' ',
|
||||
ft = ft,
|
||||
bg = 'GuihuaListDark',
|
||||
bg = 'GHListDark',
|
||||
data = result,
|
||||
items = result,
|
||||
enter = true,
|
||||
|
@ -3,7 +3,6 @@ local lsphelper = require('navigator.lspwrapper')
|
||||
local locations_to_items = lsphelper.locations_to_items
|
||||
local gui = require('navigator.gui')
|
||||
local log = util.log
|
||||
local trace = util.trace
|
||||
local TextView = require('guihua.textview')
|
||||
-- callback for lsp definition, implementation and declaration handler
|
||||
local definition_hdlr = function(err, locations, ctx, _)
|
||||
@ -22,10 +21,6 @@ local definition_hdlr = function(err, locations, ctx, _)
|
||||
end
|
||||
|
||||
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 #locations > 1 then
|
||||
local items = locations_to_items(locations)
|
||||
@ -74,7 +69,7 @@ local function def_preview(timeout_ms)
|
||||
local row = range.start.line
|
||||
-- in case there are comments
|
||||
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
|
||||
if not uri then
|
||||
return
|
||||
@ -85,12 +80,7 @@ local function def_preview(timeout_ms)
|
||||
end
|
||||
|
||||
local ok, parsers = pcall(require, 'nvim-treesitter.parsers')
|
||||
|
||||
-- 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
|
||||
local lines_num = 12
|
||||
if ok then
|
||||
local ts = require('navigator.treesitter')
|
||||
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)
|
||||
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
|
||||
|
||||
-- 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 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
|
||||
@ -117,8 +107,7 @@ local function def_preview(timeout_ms)
|
||||
end
|
||||
end
|
||||
local width = 40
|
||||
|
||||
local maxwidth = math.floor( vim.api.nvim_get_option('columns') * 0.8)
|
||||
local maxwidth = math.floor(vim.fn.winwidth(0) * 4 / 5)
|
||||
for _, value in pairs(definition) do
|
||||
-- log(key, value, width)
|
||||
width = math.max(width, #value + 4)
|
||||
@ -132,7 +121,7 @@ local function def_preview(timeout_ms)
|
||||
relative = 'cursor',
|
||||
style = 'minimal',
|
||||
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,
|
||||
enter = true,
|
||||
border = _NgConfigValues.border or 'shadow',
|
||||
|
@ -2,6 +2,7 @@ local gui = require('navigator.gui')
|
||||
local diagnostic_list = {}
|
||||
local diagnostic = vim.diagnostic or vim.lsp.diagnostic
|
||||
-- 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 log = util.log
|
||||
local trace = require('guihua.log').trace
|
||||
@ -10,8 +11,6 @@ local error = util.error
|
||||
local path_sep = require('navigator.util').path_sep()
|
||||
local path_cur = require('navigator.util').path_cur()
|
||||
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
|
||||
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
|
||||
|
||||
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)
|
||||
if vim.diagnostic ~= nil then
|
||||
@ -58,18 +74,15 @@ local function error_marker(result, ctx, config)
|
||||
if bufnr == nil then
|
||||
bufnr = vim.uri_to_bufnr(result.uri)
|
||||
end
|
||||
local success, fname = pcall(api.nvim_buf_get_name, bufnr)
|
||||
if not success then
|
||||
return
|
||||
end
|
||||
local fname = vim.api.nvim_buf_get_name(bufnr)
|
||||
local uri = vim.uri_from_fname(fname)
|
||||
if uri ~= result.uri then
|
||||
log('not same buf', ctx, result.uri, bufnr, vim.fn.bufnr())
|
||||
return
|
||||
end
|
||||
|
||||
if not api.nvim_buf_is_loaded(bufnr) then
|
||||
trace('buf not loaded', bufnr)
|
||||
if not vim.api.nvim_buf_is_loaded(bufnr) then
|
||||
log('buf not loaded', bufnr)
|
||||
return
|
||||
end
|
||||
|
||||
@ -80,7 +93,7 @@ local function error_marker(result, ctx, config)
|
||||
local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]])
|
||||
if diag_cnt == 0 and _NG_VT_DIAG_NS ~= nil then
|
||||
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
|
||||
return
|
||||
end
|
||||
@ -88,12 +101,12 @@ local function error_marker(result, ctx, config)
|
||||
-- total line num of current buffer
|
||||
|
||||
-- local winid = vim.fn.win_getid(vim.fn.winnr())
|
||||
-- local winid = api.nvim_get_current_win()
|
||||
local total_num = api.nvim_buf_line_count(bufnr)
|
||||
-- local winid = vim.api.nvim_get_current_win()
|
||||
local total_num = vim.api.nvim_buf_line_count(bufnr)
|
||||
-- local total_num = vim.fn.getbufinfo(vim.fn.winbufnr(winid))[1].linecount
|
||||
-- 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 wheight = stats.height
|
||||
|
||||
@ -101,7 +114,7 @@ local function error_marker(result, ctx, config)
|
||||
return
|
||||
end
|
||||
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
|
||||
|
||||
local pos = {}
|
||||
@ -143,7 +156,7 @@ local function error_marker(result, ctx, config)
|
||||
end
|
||||
|
||||
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
|
||||
for _, s in pairs(pos) do
|
||||
local hl = 'ErrorMsg'
|
||||
@ -164,7 +177,7 @@ local function error_marker(result, ctx, config)
|
||||
end
|
||||
trace('add pos', s, bufnr)
|
||||
|
||||
api.nvim_buf_set_extmark(
|
||||
vim.api.nvim_buf_set_extmark(
|
||||
bufnr,
|
||||
_NG_VT_DIAG_NS,
|
||||
l,
|
||||
@ -188,9 +201,9 @@ local diag_hdlr = function(err, result, ctx, config)
|
||||
return
|
||||
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
|
||||
trace('skip sign update in insert mode')
|
||||
log('skip sign update in insert mode')
|
||||
end
|
||||
local cwd = vim.loop.cwd()
|
||||
local ft = vim.bo.filetype
|
||||
@ -226,18 +239,14 @@ local diag_hdlr = function(err, result, ctx, config)
|
||||
item.uri = uri
|
||||
-- trace(item)
|
||||
local head = _NgConfigValues.icons.diagnostic_head
|
||||
if v.severity then
|
||||
if v.severity == 1 then
|
||||
head = _NgConfigValues.icons.diagnostic_head_severity_1
|
||||
end
|
||||
if v.severity == 2 then
|
||||
head = _NgConfigValues.icons.diagnostic_head_severity_2
|
||||
end
|
||||
if v.severity > 2 then
|
||||
head = _NgConfigValues.icons.diagnostic_head_severity_3
|
||||
end
|
||||
else
|
||||
v.severity = 2
|
||||
if v.severity == 1 then
|
||||
head = _NgConfigValues.icons.diagnostic_head_severity_1
|
||||
end
|
||||
if v.severity == 2 then
|
||||
head = _NgConfigValues.icons.diagnostic_head_severity_2
|
||||
end
|
||||
if v.severity > 2 then
|
||||
head = _NgConfigValues.icons.diagnostic_head_severity_3
|
||||
end
|
||||
if v.relatedInformation and v.relatedInformation[1] then
|
||||
local info = v.relatedInformation[1]
|
||||
@ -250,7 +259,7 @@ local diag_hdlr = function(err, result, ctx, config)
|
||||
end
|
||||
end
|
||||
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
|
||||
-- print('load buffers')
|
||||
if not loaded then
|
||||
@ -258,7 +267,7 @@ local diag_hdlr = function(err, result, ctx, config)
|
||||
end
|
||||
local pos = v.range.start
|
||||
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
|
||||
item.text = head .. line .. _NgConfigValues.icons.diagnostic_head_description .. v.message
|
||||
else
|
||||
@ -292,7 +301,7 @@ local diag_hdlr = function(err, result, ctx, config)
|
||||
marker(result, ctx, config)
|
||||
else
|
||||
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
|
||||
end
|
||||
end
|
||||
@ -303,56 +312,24 @@ end
|
||||
-- end
|
||||
|
||||
local M = {}
|
||||
function M.setup()
|
||||
if diagnostic_cfg ~= nil and diagnostic_cfg.float ~= nil then
|
||||
return
|
||||
end
|
||||
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
|
||||
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)
|
||||
|
||||
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)
|
||||
if _NG_VT_DIAG_NS == nil then
|
||||
return
|
||||
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
|
||||
end
|
||||
|
||||
@ -394,15 +371,15 @@ M.show_buf_diagnostics = function()
|
||||
end
|
||||
trace('new buffer', listview.bufnr)
|
||||
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
|
||||
|
||||
-- set loc list win
|
||||
M.set_diag_loclist = function(bufnr)
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
M.set_diag_loclist = function()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]])
|
||||
if diag_cnt == 0 then
|
||||
log('great, no errors!')
|
||||
@ -422,7 +399,7 @@ M.set_diag_loclist = function(bufnr)
|
||||
if diagnostic.set_loclist then
|
||||
diagnostic.set_loclist(cfg)
|
||||
else
|
||||
cfg.namespaces = diagnostic.get_namespaces()
|
||||
cfg.namespaces = diagnostic.get_namespace(nil)
|
||||
diagnostic.setloclist(cfg)
|
||||
end
|
||||
else
|
||||
@ -438,7 +415,7 @@ function M.update_err_marker()
|
||||
-- nothing to update
|
||||
return
|
||||
end
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
|
||||
local diag_cnt = get_count(bufnr, [[Error]])
|
||||
+ get_count(bufnr, [[Warning]])
|
||||
@ -447,12 +424,12 @@ function M.update_err_marker()
|
||||
|
||||
-- redraw
|
||||
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')
|
||||
return
|
||||
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)
|
||||
if #errors == 0 then
|
||||
trace('no errors', errors)
|
||||
@ -466,40 +443,30 @@ function M.update_err_marker()
|
||||
marker(result, { bufnr = bufnr, method = 'textDocument/publishDiagnostics' })
|
||||
end
|
||||
|
||||
function M.get_line_diagnostic()
|
||||
local lnum = api.nvim_win_get_cursor(0)[1] - 1
|
||||
local diags = diagnostic.get(api.nvim_get_current_buf(), { lnum = lnum })
|
||||
if _NgConfigValues.lsp.diagnostic_scrollbar_sign then
|
||||
vim.cmd([[autocmd WinScrolled * lua require'navigator.diagnostics'.update_err_marker()]])
|
||||
end
|
||||
|
||||
table.sort(diags, function(diag1, diag2)
|
||||
return diag1.severity < diag2.severity
|
||||
end)
|
||||
return diags
|
||||
function M.get_line_diagnostic()
|
||||
local lnum = vim.api.nvim_win_get_cursor(0)[1] - 1
|
||||
return diagnostic.get(vim.api.nvim_get_current_buf(), { lnum = lnum })
|
||||
end
|
||||
|
||||
function M.show_diagnostics(pos)
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
|
||||
local lnum, col = unpack(api.nvim_win_get_cursor(0))
|
||||
lnum = lnum - 1
|
||||
local opt = { border = 'single', severity_sort = true }
|
||||
|
||||
if pos ~= nil and type(pos) == 'number' then
|
||||
opt.scope = 'buffer'
|
||||
else
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local lnum = vim.api.nvim_win_get_cursor(0)[1] - 1
|
||||
local opt = { border = 'single' }
|
||||
if diagnostic.open_float and type(diagnostic.open_float) == 'function' then
|
||||
if pos == true then
|
||||
opt.scope = 'cursor'
|
||||
else
|
||||
opt.scope = 'line'
|
||||
end
|
||||
diagnostic.open_float(bufnr, opt)
|
||||
else
|
||||
-- deprecated
|
||||
diagnostic.show_line_diagnostics(opt, bufnr, lnum)
|
||||
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
|
||||
|
||||
function M.treesitter_and_diag_panel()
|
||||
@ -509,7 +476,7 @@ function M.treesitter_and_diag_panel()
|
||||
local results = 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({
|
||||
header = 'treesitter',
|
||||
render = function(b)
|
||||
@ -519,8 +486,7 @@ function M.treesitter_and_diag_panel()
|
||||
})
|
||||
p:add_section({
|
||||
header = 'diagnostic',
|
||||
render = function(buf)
|
||||
log(buf, diagnostic)
|
||||
render = function(bufnr)
|
||||
if diagnostic_list[ft] ~= nil then
|
||||
local display_items = {}
|
||||
for _, client_items in pairs(results) do
|
||||
@ -541,9 +507,7 @@ function M.treesitter_and_diag_panel()
|
||||
end
|
||||
|
||||
function M.config(cfg)
|
||||
M.setup()
|
||||
cfg = cfg or {}
|
||||
log('diag config', cfg)
|
||||
local default_cfg = {
|
||||
underline = true,
|
||||
virtual_text = true,
|
||||
|
@ -145,6 +145,7 @@ local handle_document_highlight = function(_, result, ctx)
|
||||
return
|
||||
end
|
||||
if type(result) ~= 'table' or vim.fn.empty(result) == 1 then
|
||||
log('clear up', result)
|
||||
vim.lsp.util.buf_clear_references(ctx.bufnr)
|
||||
return
|
||||
end
|
||||
@ -204,45 +205,29 @@ local function cmd_nohl()
|
||||
end
|
||||
end
|
||||
|
||||
local nav_doc_hl = function(bufnr)
|
||||
trace('nav_doc_hl', bufnr)
|
||||
bufnr = bufnr or vim.api.nvim_get_current_buf()
|
||||
local nav_doc_hl = function()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local ref_params = vim.lsp.util.make_position_params()
|
||||
vim.lsp.for_each_buffer_client(bufnr, function(client, _, _)
|
||||
if client.server_capabilities.documentHighlightProvider == true then
|
||||
trace('sending doc highlight', client.name, bufnr)
|
||||
client.request('textDocument/documentHighlight', ref_params, handle_document_highlight, bufnr)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function documentHighlight(bufnr)
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
|
||||
if _NgConfigValues.lsp.document_highlight == true then
|
||||
local group_name = string.format('%s%d', 'NGHiGroup', bufnr)
|
||||
local cmd_group = api.nvim_create_augroup(group_name, {})
|
||||
api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
|
||||
group = cmd_group,
|
||||
buffer = bufnr,
|
||||
desc = 'document highlight',
|
||||
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
|
||||
|
||||
local function documentHighlight()
|
||||
api.nvim_exec(
|
||||
[[
|
||||
augroup lsp_document_highlight
|
||||
autocmd! * <buffer>
|
||||
autocmd CursorHold,CursorHoldI <buffer> lua require('navigator.dochighlight').nav_doc_hl()
|
||||
autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()
|
||||
augroup END
|
||||
]],
|
||||
false
|
||||
)
|
||||
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
|
||||
vim.notify(err, vim.lsp.log_levels.ERROR)
|
||||
return
|
||||
@ -251,18 +236,19 @@ local function documentHighlight(bufnr)
|
||||
return
|
||||
end
|
||||
trace('dochl', result)
|
||||
bufnr = bufnr or 0
|
||||
if type(result) ~= 'table' then
|
||||
vim.lsp.util.buf_clear_references(buffer)
|
||||
vim.lsp.util.buf_clear_references(bufnr)
|
||||
return
|
||||
end
|
||||
local client_id = ctx.client_id
|
||||
vim.lsp.util.buf_clear_references(buffer)
|
||||
vim.lsp.util.buf_highlight_references(buffer, result, util.encoding(client_id))
|
||||
vim.lsp.util.buf_clear_references(bufnr)
|
||||
vim.lsp.util.buf_highlight_references(bufnr, result, util.encoding(client_id))
|
||||
table.sort(result, function(a, b)
|
||||
return before(a.range, b.range)
|
||||
end)
|
||||
references[buffer] = result
|
||||
add_locs(buffer, result)
|
||||
references[bufnr] = result
|
||||
add_locs(bufnr, result)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -28,14 +28,19 @@ function M.on_attach()
|
||||
end
|
||||
|
||||
function M.setup_plugin()
|
||||
local cmd_group = api.nvim_create_augroup('NGFoldGroup', {})
|
||||
api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost' }, {
|
||||
group = cmd_group,
|
||||
pattern = '*',
|
||||
callback = function()
|
||||
require('navigator.foldlsp').update_folds()
|
||||
end,
|
||||
})
|
||||
api.nvim_command('augroup FoldingCommand')
|
||||
api.nvim_command('autocmd! * <buffer>')
|
||||
api.nvim_command("autocmd BufEnter <buffer> lua require'navigator.foldlsp'.update_folds()")
|
||||
api.nvim_command("autocmd BufWritePost <buffer> lua require'navigator.foldlsp'.update_folds()")
|
||||
api.nvim_command('augroup 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)
|
||||
|
||||
|
@ -21,12 +21,7 @@ function NG_custom_fold_text()
|
||||
local line = vim.fn.getline(vim.v.foldstart)
|
||||
local line_count = vim.v.foldend - vim.v.foldstart + 1
|
||||
-- log("" .. line .. " // " .. line_count .. " lines")
|
||||
local ss, se = line:find('^%s*')
|
||||
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'
|
||||
return ' ⚡' .. line .. ': ' .. line_count .. ' lines'
|
||||
end
|
||||
|
||||
vim.opt.foldtext = NG_custom_fold_text()
|
||||
@ -35,6 +30,11 @@ vim.opt.fillchars = { eob = '-', fold = ' ' }
|
||||
vim.opt.viewoptions:remove('options')
|
||||
|
||||
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('autocmd! * <buffer>')
|
||||
api.nvim_command('augroup end')
|
||||
@ -43,27 +43,10 @@ function M.setup_fold()
|
||||
vim.opt.viewoptions:remove('options')
|
||||
|
||||
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, 'foldexpr', 'folding#ngfoldexpr()')
|
||||
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
|
||||
-- Especially not for every line in the file when `zx` is hit
|
||||
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
|
||||
end
|
||||
end
|
||||
trace(start_counts)
|
||||
trace(stop_counts)
|
||||
|
||||
local levels = {}
|
||||
local current_level = 0
|
||||
|
||||
-- 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
|
||||
local node, _ = get_node_at_line(lnum + 1)
|
||||
-- log(lnum, node:type())
|
||||
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)
|
||||
current_level = current_level + (start_counts[lnum] or 0)
|
||||
local trimmed_level = trim_level(current_level)
|
||||
local current_level2 = current_level - (stop_counts[lnum] or 0)
|
||||
local next_trimmed_level = trim_level(current_level2)
|
||||
current_level = current_level - (stop_counts[lnum] or 0)
|
||||
local next_trimmed_level = trim_level(current_level)
|
||||
|
||||
trace(lnum, node:type(), node, last_trimmed_level, trimmed_level, next_trimmed_level)
|
||||
if comment then
|
||||
trace('comment node', trimmed_level)
|
||||
-- if trimmed_level == 0 then
|
||||
-- trimmed_level = 1
|
||||
-- end
|
||||
|
||||
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)
|
||||
if lnum == 0 or levels[lnum] == tostring(trimmed_level) then
|
||||
levels[lnum + 1] = '>' .. tostring(trimmed_level + 1) -- allow comment fold independtly
|
||||
else
|
||||
levels[lnum + 1] = tostring(trimmed_level + 1) -- allow comment fold independtly
|
||||
end
|
||||
else
|
||||
-- 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 )
|
||||
-- If it did have such a mechansim, (trimmed_level - last_trimmed_level)
|
||||
-- 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 levels[lnum + 1] ~= '>' .. tostring(trimmed_level) then
|
||||
levels[lnum + 1] = tostring(trimmed_level) -- hack do not fold current line as it is first in fold range
|
||||
end
|
||||
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
|
||||
levels[lnum + 1] = tostring(trimmed_level) -- hack
|
||||
levels[lnum + 2] = '>' .. tostring(trimmed_level + 1) -- dirty hack
|
||||
elseif trimmed_level - next_trimmed_level > 0 then
|
||||
-- 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
|
||||
-- vim's behavior gets fixed.
|
||||
|
||||
trace('fold end')
|
||||
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)
|
||||
if lnum ~= 0 then
|
||||
levels[lnum] = tostring(trimmed_level + 1)
|
||||
end
|
||||
-- levels[lnum + 1] = tostring(trimmed_level + 1)
|
||||
-- else
|
||||
current_level = current_level - 1
|
||||
levels[lnum + 1] = tostring(trimmed_level)
|
||||
else
|
||||
trace('same')
|
||||
if pre_node and pre_node:type() == 'comment' then
|
||||
local prev_ln = get_fold_level(levels, lnum) - 1
|
||||
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
|
||||
-- if levels[lnum + 1] == nil then
|
||||
levels[lnum + 1] = tostring(trimmed_level + 1)
|
||||
-- end
|
||||
end
|
||||
trace(levels)
|
||||
end
|
||||
pre_node = node
|
||||
end
|
||||
trace(levels)
|
||||
|
||||
return levels
|
||||
end)
|
||||
|
||||
@ -225,7 +165,7 @@ function M.get_fold_indic(lnum)
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local shown = false
|
||||
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
|
||||
shown = true
|
||||
end
|
||||
@ -236,7 +176,7 @@ function M.get_fold_indic(lnum)
|
||||
end
|
||||
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'
|
||||
end
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
-- 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
|
||||
|
||||
return {
|
||||
format_hdl = function(err, result, ctx, _) -- FIXME: bufnr is nil
|
||||
if err ~= nil or result == nil then
|
||||
@ -32,18 +31,4 @@ return {
|
||||
end
|
||||
end, 100)
|
||||
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 ListView = require('guihua.listview')
|
||||
-- local TextView = require('guihua.textview')
|
||||
local ListView = require('guihua.listview')
|
||||
local TextView = require('guihua.textview')
|
||||
local util = require('navigator.util')
|
||||
local log = util.log
|
||||
local trace = require('navigator.util').trace
|
||||
@ -16,7 +16,7 @@ function M.new_list_view(opts)
|
||||
local winnr = active_list_view.win
|
||||
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')
|
||||
return active_list_view
|
||||
end
|
||||
@ -35,14 +35,6 @@ function M.new_list_view(opts)
|
||||
opts.border = config.border or 'shadow'
|
||||
if vim.fn.hlID('TelescopePromptBorder') > 0 then
|
||||
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
|
||||
if not items or vim.tbl_isempty(items) then
|
||||
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)
|
||||
ctx = ctx or {} -- can be nil if it is async call
|
||||
cfg = cfg or {}
|
||||
local opts = ctx.opts or {}
|
||||
opts = ctx.opts or {}
|
||||
vim.validate({ handler = { handler, 'function' }, show = { show, 'function' }, api = { api, 'string' } })
|
||||
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')
|
||||
@ -142,12 +142,11 @@ local function display_panel(args)
|
||||
|
||||
local Panel = require('guihua.panel')
|
||||
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 p = Panel:new({
|
||||
header = args.header or 'Call Hierarchy',
|
||||
render = function(buf)
|
||||
log(buf)
|
||||
render = function(bufnr)
|
||||
return items
|
||||
end,
|
||||
fold = function(panel, node)
|
||||
|
@ -1,6 +1,7 @@
|
||||
return {
|
||||
init = function()
|
||||
local loader = nil
|
||||
local packer_plugins = packer_plugins or nil -- suppress warnings
|
||||
local log = require('navigator.util').log
|
||||
-- packer only
|
||||
if packer_plugins ~= nil then -- packer install
|
||||
@ -50,7 +51,7 @@ return {
|
||||
end,
|
||||
load = function(plugin_name, path)
|
||||
local loader = nil
|
||||
packer_plugins = packer_plugins or nil -- suppress warnings
|
||||
local packer_plugins = packer_plugins or nil -- suppress warnings
|
||||
-- packer only
|
||||
if packer_plugins ~= nil then -- packer install
|
||||
local lazy_plugins = {}
|
||||
|
@ -4,7 +4,7 @@ local lsp = require('vim.lsp')
|
||||
local util = require('navigator.util')
|
||||
local log = util.log
|
||||
local trace = util.trace
|
||||
_NG_Attached = {}
|
||||
|
||||
local M = {}
|
||||
|
||||
M.on_attach = function(client, bufnr)
|
||||
@ -23,7 +23,6 @@ M.on_attach = function(client, bufnr)
|
||||
log('attaching: ', bufnr, client.name, uri)
|
||||
|
||||
trace(client)
|
||||
_NG_Attached[client.name] = true
|
||||
|
||||
-- add highlight for Lspxxx
|
||||
require('navigator.lspclient.highlight').add_highlight()
|
||||
@ -36,16 +35,9 @@ M.on_attach = function(client, bufnr)
|
||||
})
|
||||
|
||||
if client.server_capabilities.documentHighlightProvider == true then
|
||||
trace('attaching doc highlight: ', bufnr, client.name)
|
||||
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)
|
||||
require('navigator.dochighlight').documentHighlight()
|
||||
end
|
||||
|
||||
|
||||
|
||||
require('navigator.lspclient.lspkind').init()
|
||||
|
||||
local config = require('navigator').config_values()
|
||||
@ -70,13 +62,9 @@ M.on_attach = function(client, bufnr)
|
||||
if _NgConfigValues.lsp.code_action.enable then
|
||||
if client.server_capabilities.codeActionProvider and client.name ~= 'null-ls' then
|
||||
log('code action enabled for client', client.server_capabilities.codeActionProvider)
|
||||
api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
|
||||
group = api.nvim_create_augroup('NGCodeActGroup_'..tostring(bufnr), {}),
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
require('navigator.codeAction').code_action_prompt(bufnr)
|
||||
end,
|
||||
})
|
||||
api.nvim_command('augroup NCodeAction')
|
||||
vim.cmd([[autocmd CursorHold,CursorHoldI <buffer> lua require'navigator.codeAction'.code_action_prompt()]])
|
||||
api.nvim_command('augroup end')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -4,7 +4,6 @@ local log = ng_util.log
|
||||
local trace = ng_util.trace
|
||||
local empty = ng_util.empty
|
||||
local warn = ng_util.warn
|
||||
local vfn = vim.fn
|
||||
_NG_Loaded = {}
|
||||
|
||||
_LoadedFiletypes = {}
|
||||
@ -42,7 +41,6 @@ local disabled_ft = {
|
||||
'windline',
|
||||
'notify',
|
||||
'nofile',
|
||||
'help',
|
||||
'',
|
||||
}
|
||||
-- local cap = vim.lsp.protocol.make_client_capabilities()
|
||||
@ -65,45 +63,322 @@ local luadevcfg = {
|
||||
}
|
||||
|
||||
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')
|
||||
if _NgConfigValues.lsp_installer then
|
||||
require('navigator.lazyloader').load('nvim-lsp-installer', 'williamboman/nvim-lsp-installer')
|
||||
end
|
||||
|
||||
|
||||
if _NgConfigValues.mason then
|
||||
require('navigator.lazyloader').load('mason.nvim', 'williamboman/mason.nvim')
|
||||
require('navigator.lazyloader').load('mason-lspconfig.nvim', 'williamboman/mason-lspconfig.nvim')
|
||||
local ok, l = pcall(require, 'lua-dev')
|
||||
if ok and l then
|
||||
luadev = l.setup(luadevcfg)
|
||||
end
|
||||
|
||||
local setups = require('navigator.lspclient.clients_default').defaults()
|
||||
local servers = require('navigator.lspclient.servers')
|
||||
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
|
||||
|
||||
-- add runtime
|
||||
add('$VIMRUNTIME')
|
||||
|
||||
-- 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
|
||||
-- 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.
|
||||
},
|
||||
}
|
||||
|
||||
setups.sumneko_lua = vim.tbl_deep_extend('force', luadev, setups.sumneko_lua)
|
||||
|
||||
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 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
|
||||
if config.lsp_installer == true then
|
||||
has_lspinst, _ = pcall(require, 'nvim-lsp-installer')
|
||||
if has_lspinst then
|
||||
local srvs = require('nvim-lsp-installer.servers').get_installed_servers()
|
||||
log('lsp_installered servers', srvs)
|
||||
if #srvs > 0 then
|
||||
lsp_installer_servers = srvs
|
||||
end
|
||||
end
|
||||
log(lsp_installer_servers)
|
||||
end
|
||||
|
||||
has_mason, _ = pcall(require, 'mason-lspconfig')
|
||||
if has_mason then
|
||||
local srvs=require'mason-lspconfig'.get_installed_servers()
|
||||
if #srvs > 0 then
|
||||
lsp_installer_servers = srvs
|
||||
end
|
||||
end
|
||||
log("lsp_installer:", lsp_installer_servers)
|
||||
|
||||
if config.lsp.disable_lsp == 'all' then
|
||||
config.lsp.disable_lsp = servers
|
||||
end
|
||||
@ -114,8 +389,8 @@ local ng_default_cfg = {
|
||||
}
|
||||
|
||||
-- check and load based on file type
|
||||
local function load_cfg(ft, client, cfg, loaded, starting)
|
||||
log(ft, client, loaded, starting)
|
||||
local function load_cfg(ft, client, cfg, loaded)
|
||||
log(ft, client, loaded)
|
||||
trace(cfg)
|
||||
if lspconfig[client] == nil then
|
||||
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 additional_ft = setups[client] and setups[client].filetypes or {}
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local cmd = cfg.cmd
|
||||
vim.list_extend(lspft, additional_ft)
|
||||
|
||||
@ -140,46 +414,19 @@ local function load_cfg(ft, client, cfg, loaded, starting)
|
||||
end
|
||||
|
||||
trace('lsp for client', client, cfg)
|
||||
if cmd == nil or #cmd == 0 or vfn.executable(cmd[1]) == 0 then
|
||||
log('lsp not installed for client', client, cmd, "fallback")
|
||||
if cmd == nil or #cmd == 0 or vim.fn.executable(cmd[1]) == 0 then
|
||||
log('lsp not installed for client', client, cmd)
|
||||
return
|
||||
end
|
||||
if _NG_Loaded == nil then
|
||||
return log('_NG_Loaded not set')
|
||||
end
|
||||
|
||||
for k, c in pairs(loaded) do
|
||||
if client == k then
|
||||
-- loaded
|
||||
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
|
||||
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
|
||||
error('client ' .. client .. ' not supported')
|
||||
return
|
||||
@ -189,27 +436,8 @@ local function load_cfg(ft, client, cfg, loaded, starting)
|
||||
log('lspconfig setup')
|
||||
-- log(lspconfig.available_servers())
|
||||
-- force reload with config
|
||||
-- lets have a guard here
|
||||
if not _NG_Loaded[client] then
|
||||
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
|
||||
lspconfig[client].setup(cfg)
|
||||
log(client, 'loading for', ft)
|
||||
end
|
||||
-- need to verify the lsp server is up
|
||||
end
|
||||
@ -227,7 +455,7 @@ local function setup_fmt(client, enabled)
|
||||
client.server_capabilities.documentFormattingProvider = false
|
||||
else
|
||||
client.server_capabilities.documentFormattingProvider = client.server_capabilities.documentFormattingProvider
|
||||
or enabled
|
||||
or enabled
|
||||
end
|
||||
end
|
||||
|
||||
@ -253,7 +481,7 @@ end
|
||||
local loaded = {}
|
||||
local function lsp_startup(ft, retry, user_lsp_opts)
|
||||
retry = retry or false
|
||||
local path_sep = require('navigator.util').path_sep()
|
||||
|
||||
local capabilities = update_capabilities()
|
||||
|
||||
for _, lspclient in ipairs(servers) do
|
||||
@ -323,7 +551,7 @@ local function lsp_startup(ft, retry, user_lsp_opts)
|
||||
|
||||
log(lspclient)
|
||||
-- if user provides override values
|
||||
-- cfg.capabilities = capabilities
|
||||
cfg.capabilities = capabilities
|
||||
log(lspclient, config.lsp.disable_format_cap)
|
||||
if vim.tbl_contains(config.lsp.disable_format_cap or {}, lspclient) then
|
||||
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)
|
||||
if installed and installer_cfg then
|
||||
local paths = installer_cfg:get_default_options().cmd_env and 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
|
||||
local paths = installer_cfg:get_default_options().cmd_env.PATH
|
||||
paths = vim.split(paths, ':')
|
||||
if vfn.empty(cfg.cmd) == 1 then
|
||||
if vim.fn.empty(cfg.cmd) == 1 then
|
||||
cfg.cmd = { installer_cfg.name }
|
||||
end
|
||||
|
||||
if vfn.executable(cfg.cmd[1]) == 0 then
|
||||
if vim.fn.executable(cfg.cmd[1]) == 0 then
|
||||
for _, path in ipairs(paths) do
|
||||
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]
|
||||
log(cfg.cmd)
|
||||
break
|
||||
@ -433,49 +656,17 @@ local function lsp_startup(ft, retry, user_lsp_opts)
|
||||
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)
|
||||
end
|
||||
|
||||
if _NG_Loaded[lspclient] then
|
||||
log('client loaded ?', lspclient, _NG_Loaded[lspclient])
|
||||
end
|
||||
local starting = {}
|
||||
if _NG_Loaded[lspclient] == true then
|
||||
starting = { cnt = 1 }
|
||||
log('client loaded ?', lspclient)
|
||||
end
|
||||
load_cfg(ft, lspclient, cfg, loaded)
|
||||
|
||||
load_cfg(ft, lspclient, cfg, loaded, starting)
|
||||
_NG_Loaded[lspclient] = true
|
||||
-- load_cfg(ft, lspclient, {}, loaded)
|
||||
::continue::
|
||||
end
|
||||
@ -549,7 +740,7 @@ local function setup(user_opts, cnt)
|
||||
local bufnr = user_opts.bufnr or vim.api.nvim_get_current_buf()
|
||||
if ft == '' or ft == nil then
|
||||
log('nil filetype, callback')
|
||||
local ext = vfn.expand('%:e')
|
||||
local ext = vim.fn.expand('%:e')
|
||||
if ext ~= '' then
|
||||
cnt = cnt or 0
|
||||
local opts = vim.deepcopy(user_opts)
|
||||
@ -629,7 +820,7 @@ local function setup(user_opts, cnt)
|
||||
|
||||
--- if code lens enabled
|
||||
if _NgConfigValues.lsp.code_lens_action.enable then
|
||||
require('navigator.codelens').setup(bufnr)
|
||||
require('navigator.codelens').setup()
|
||||
end
|
||||
|
||||
-- _LoadedFiletypes[ft .. tostring(bufnr)] = true -- may prevent lsp config when reboot lsp
|
||||
@ -644,38 +835,23 @@ local function on_filetype()
|
||||
return
|
||||
end
|
||||
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
|
||||
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)
|
||||
|
||||
local wids = vfn.win_findbuf(bufnr)
|
||||
local wids = vim.fn.win_findbuf(bufnr)
|
||||
if empty(wids) then
|
||||
log('buf not shown return')
|
||||
end
|
||||
setup({ bufnr = bufnr })
|
||||
_NG_Loaded[bufnr] = 1
|
||||
end
|
||||
|
||||
return {
|
||||
setup = setup,
|
||||
get_cfg = get_cfg,
|
||||
lsp = servers,
|
||||
add_servers = add_servers,
|
||||
on_filetype = on_filetype,
|
||||
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 capabilities = vim.lsp.protocol.make_client_capabilities()
|
||||
capabilities.textDocument.completion.completionItem.snippetSupport = true
|
||||
|
@ -3,7 +3,6 @@ local M = {}
|
||||
-- local log = require('navigator.util').log
|
||||
local api = vim.api
|
||||
|
||||
local cmd_group = api.nvim_create_augroup('NGHiGroup', {})
|
||||
-- lsp sign ﮻ ﯭ ﳀ
|
||||
function M.diagnositc_config_sign()
|
||||
if M.configed then
|
||||
@ -32,41 +31,35 @@ function M.diagnositc_config_sign()
|
||||
M.configed = true
|
||||
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()
|
||||
-- lsp system default
|
||||
|
||||
api.nvim_set_hl(0, 'DiagnosticUnderlineError', { link = 'SpellBad', default = true })
|
||||
api.nvim_set_hl(0, 'DiagnosticUnderlineWarning', { link = 'SpellRare', default = true })
|
||||
api.nvim_set_hl(0, 'DiagnosticUnderlineInformation', { link = 'SpellRare', default = true })
|
||||
api.nvim_set_hl(0, 'DiagnosticUnderlineHint', { link = 'SpellRare', default = true })
|
||||
api.nvim_set_hl(0, 'NGPreviewTitle', { link = 'Title', default = true })
|
||||
api.nvim_set_hl(0, 'LspReferenceRead', { default = true, link = 'IncSearch'})
|
||||
api.nvim_set_hl(0, 'LspReferenceText', { default = true, link = 'Visual'})
|
||||
api.nvim_set_hl( 0, 'LspReferenceWrite', { default = true, link = 'Search'})
|
||||
api.nvim_command('hi! link DiagnosticUnderlineError SpellBad')
|
||||
api.nvim_command('hi! link DiagnosticUnderlineWarning SpellRare')
|
||||
api.nvim_command('hi! link DiagnosticUnderlineInformation SpellRare')
|
||||
api.nvim_command('hi! link DiagnosticUnderlineHint SpellRare')
|
||||
api.nvim_command('hi def link NGPreviewTitle Title')
|
||||
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' },
|
||||
}
|
||||
|
||||
for i = 1, #colors do
|
||||
for j = 1, 3 do
|
||||
local hlg = string.format('NGHiReference_%i_%i', i, j) -- , colors[i][j], colors[i][4]
|
||||
api.nvim_set_hl(0, hlg, { fg = colors[i][j], bg = colors[i][4], default = true })
|
||||
local cmd = string.format('hi! default NGHiReference_%i_%i guibg=%s guifg=%s ', i, j, colors[i][j], colors[i][4])
|
||||
vim.cmd(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
vim.cmd([[
|
||||
autocmd ColorScheme * |
|
||||
hi default LspReferenceRead cterm=bold gui=Bold ctermbg=yellow guifg=yellow guibg=purple4 |
|
||||
hi default LspReferenceText cterm=bold gui=Bold ctermbg=red guifg=SlateBlue guibg=MidnightBlue |
|
||||
hi default LspReferenceWrite cterm=bold gui=Bold,Italic ctermbg=red guifg=DarkSlateBlue guibg=MistyRose
|
||||
]])
|
||||
end
|
||||
|
||||
api.nvim_create_autocmd('ColorScheme', {
|
||||
group = cmd_group,
|
||||
pattern = '*',
|
||||
callback = function()
|
||||
M.add_highlight()
|
||||
end,
|
||||
})
|
||||
|
||||
return M
|
||||
|
@ -1,7 +1,12 @@
|
||||
local util = require('navigator.util')
|
||||
local log = util.log
|
||||
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
|
||||
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
|
||||
-- LuaFormatter off
|
||||
local key_maps = {
|
||||
{ key = 'gr', func = require('navigator.reference').async_ref, desc = 'async_ref' },
|
||||
{ key = '<Leader>gr', func = require('navigator.reference').reference, desc = 'reference' }, -- reference deprecated
|
||||
{ mode = 'i', key = '<M-k>', func = vim.lsp.signature_help, desc = 'signature_help' },
|
||||
{ key = '<c-k>', func = vim.lsp.buf.signature_help, desc = 'signature_help' },
|
||||
{ key = 'g0', func = require('navigator.symbols').document_symbols, desc = 'document_symbols' },
|
||||
{ key = 'gW', func = require('navigator.workspace').workspace_symbol_live, desc = 'workspace_symbol_live' },
|
||||
{ key = '<c-]>', func = require('navigator.definition').definition, desc = 'definition' },
|
||||
{ key = 'gd', func = require('navigator.definition').definition, desc = 'definition' },
|
||||
{ key = 'gD', func = vim.lsp.buf.declaration, desc = 'declaration' },
|
||||
{ key = 'gp', func = require('navigator.definition').definition_preview, desc = 'definition_preview' },
|
||||
{ key = '<Leader>gt', func = require('navigator.treesitter').buf_ts, desc = 'buf_ts' },
|
||||
{ key = '<Leader>gT', func = require('navigator.treesitter').bufs_ts, desc = 'bufs_ts' },
|
||||
{ key = '<Leader>ct', func = require('navigator.ctags').ctags, desc = 'ctags' },
|
||||
{ key = 'K', func = vim.lsp.buf.hover, desc = 'hover' },
|
||||
{ key = '<Space>ca', mode = 'n', func = require('navigator.codeAction').code_action, desc = 'code_action' },
|
||||
{
|
||||
key = '<Space>ca',
|
||||
mode = 'v',
|
||||
func = require('navigator.codeAction').range_code_action,
|
||||
desc = 'range_code_action',
|
||||
},
|
||||
{ key = 'gr', func = "require('navigator.reference').async_ref()" },
|
||||
{ key = '<Leader>gr', func = "require('navigator.reference').reference()" }, -- reference deprecated
|
||||
{ mode = 'i', key = '<M-k>', func = 'signature_help()' },
|
||||
{ key = '<c-k>', func = 'signature_help()' },
|
||||
{ key = 'g0', func = "require('navigator.symbols').document_symbols()" },
|
||||
{ key = 'gW', func = "require('navigator.workspace').workspace_symbol_live()" },
|
||||
{ key = '<c-]>', func = "require('navigator.definition').definition()" },
|
||||
{ key = 'gd', func = "require('navigator.definition').definition()" },
|
||||
{ key = 'gD', func = "declaration({ border = 'rounded', max_width = 80 })" },
|
||||
{ key = 'gp', func = "require('navigator.definition').definition_preview()" },
|
||||
{ key = '<Leader>gt', func = "require('navigator.treesitter').buf_ts()" },
|
||||
{ key = '<Leader>gT', func = "require('navigator.treesitter').bufs_ts()" },
|
||||
{ key = '<Leader>ct', func = "require('navigator.ctags').ctags()" },
|
||||
{ key = 'K', func = 'hover({ popup_opts = { border = single, max_width = 80 }})' },
|
||||
{ key = '<Space>ca', mode = 'n', func = "require('navigator.codeAction').code_action()" },
|
||||
{ key = '<Space>ca', mode = 'v', func = "require('navigator.codeAction').range_code_action()" },
|
||||
-- { key = '<Leader>re', func = 'rename()' },
|
||||
{ key = '<Space>rn', func = require('navigator.rename').rename, desc = 'rename' },
|
||||
{ key = '<Leader>gi', func = vim.lsp.buf.incoming_calls, desc = 'incoming_calls' },
|
||||
{ key = '<Leader>go', func = vim.lsp.buf.outgoing_calls, desc = 'outgoing_calls' },
|
||||
{ key = 'gi', func = vim.lsp.buf.implementation, desc = 'implementation' },
|
||||
{ key = '<Space>D', func = vim.lsp.buf.type_definition, desc = 'type_definition' },
|
||||
{ key = 'gL', func = require('navigator.diagnostics').show_diagnostics, desc = 'show_diagnostics' },
|
||||
{ key = 'gG', func = require('navigator.diagnostics').show_buf_diagnostics, desc = 'show_buf_diagnostics' },
|
||||
{ key = '<Leader>dt', func = require('navigator.diagnostics').toggle_diagnostics, desc = 'toggle_diagnostics' },
|
||||
{ key = ']d', func = vim.diagnostic.goto_next, desc = 'next diagnostics' },
|
||||
{ key = '[d', func = vim.diagnostic.goto_prev, desc = 'prev diagnostics' },
|
||||
{ key = ']O', func = vim.diagnostic.set_loclist, desc = 'diagnostics set loclist' },
|
||||
{ key = ']r', func = require('navigator.treesitter').goto_next_usage, desc = 'goto_next_usage' },
|
||||
{ key = '[r', func = require('navigator.treesitter').goto_previous_usage, desc = 'goto_previous_usage' },
|
||||
{ key = '<C-LeftMouse>', func = vim.lsp.buf.definition, desc = 'definition' },
|
||||
{ key = 'g<LeftMouse>', func = vim.lsp.buf.implementation, desc = 'implementation' },
|
||||
{ key = '<Leader>k', func = require('navigator.dochighlight').hi_symbol, desc = 'hi_symbol' },
|
||||
{ key = '<Space>wa', func = require('navigator.workspace').add_workspace_folder, desc = 'add_workspace_folder' },
|
||||
{
|
||||
key = '<Space>wr',
|
||||
func = require('navigator.workspace').remove_workspace_folder,
|
||||
desc = 'remove_workspace_folder',
|
||||
},
|
||||
{ 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' },
|
||||
{
|
||||
key = '<Space>gm',
|
||||
func = require('navigator.formatting').range_format,
|
||||
mode = 'n',
|
||||
desc = 'range format operator e.g gmip',
|
||||
},
|
||||
{ key = '<Space>wl', func = require('navigator.workspace').list_workspace_folders, desc = 'list_workspace_folders' },
|
||||
{ key = '<Space>la', mode = 'n', func = require('navigator.codelens').run_action, desc = 'run code lens action' },
|
||||
{ key = '<Space>rn', func = "require('navigator.rename').rename()" },
|
||||
{ key = '<Leader>gi', func = 'incoming_calls()' },
|
||||
{ key = '<Leader>go', func = 'outgoing_calls()' },
|
||||
{ key = 'gi', func = 'implementation()' },
|
||||
{ key = '<Space>D', func = 'type_definition()' },
|
||||
{ key = 'gL', func = "require('navigator.diagnostics').show_diagnostics()" },
|
||||
{ key = 'gG', func = "require('navigator.diagnostics').show_buf_diagnostics()" },
|
||||
{ key = '<Leader>dt', func = "require('navigator.diagnostics').toggle_diagnostics()" },
|
||||
{ key = ']d', func = "diagnostic.goto_next({ border = 'rounded', max_width = 80})" },
|
||||
{ key = '[d', func = "diagnostic.goto_prev({ border = 'rounded', max_width = 80})" },
|
||||
{ key = ']O', func = 'diagnostic.set_loclist()' },
|
||||
{ key = ']r', func = "require('navigator.treesitter').goto_next_usage()" },
|
||||
{ key = '[r', func = "require('navigator.treesitter').goto_previous_usage()" },
|
||||
{ key = '<C-LeftMouse>', func = 'definition()' },
|
||||
{ key = 'g<LeftMouse>', func = 'implementation()' },
|
||||
{ key = '<Leader>k', func = "require('navigator.dochighlight').hi_symbol()" },
|
||||
{ key = '<Space>wa', func = "require('navigator.workspace').add_workspace_folder()" },
|
||||
{ key = '<Space>wr', func = "require('navigator.workspace').remove_workspace_folder()" },
|
||||
{ key = '<Space>ff', func = 'format({async = true})', mode = 'n' },
|
||||
{ key = '<Space>ff', func = 'range_formatting()', mode = 'v' },
|
||||
{ key = '<Space>wl', func = "require('navigator.workspace').list_workspace_folders()" },
|
||||
{ key = '<Space>la', mode = 'n', func = "require('navigator.codelens').run_action()" },
|
||||
}
|
||||
|
||||
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=* Calltree lua require'navigator.hierarchy'.calltree(<f-args>)<CR>",
|
||||
}
|
||||
|
||||
local key_maps_help = {}
|
||||
@ -76,8 +77,8 @@ local key_maps_help = {}
|
||||
local M = {}
|
||||
|
||||
local ccls_mappings = {
|
||||
{ key = '<Leader>gi', func = require('navigator.cclshierarchy').incoming_calls, desc = 'incoming_calls' },
|
||||
{ key = '<Leader>go', func = require('navigator.cclshierarchy').outgoing_calls, desc = 'outgoing_calls' },
|
||||
{ key = '<Leader>gi', func = "require('navigator.cclshierarchy').incoming_calls()" },
|
||||
{ key = '<Leader>go', func = "require('navigator.cclshierarchy').outgoing_calls()" },
|
||||
}
|
||||
|
||||
local check_cap = function(opts)
|
||||
@ -115,25 +116,12 @@ local check_cap = function(opts)
|
||||
end
|
||||
|
||||
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
|
||||
vim.cmd(value)
|
||||
end
|
||||
end
|
||||
|
||||
-- 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 opts = { noremap = true, silent = true }
|
||||
vim.validate({
|
||||
@ -145,17 +133,13 @@ local function set_mapping(lsp_attach_info)
|
||||
local user_key = _NgConfigValues.keymaps or {}
|
||||
local bufnr = lsp_attach_info.bufnr or 0
|
||||
|
||||
local function del_keymap(mode, key, ...)
|
||||
local ks = vim.api.nvim_buf_get_keymap(bufnr, mode)
|
||||
if vim.tbl_contains(ks, key) then
|
||||
vim.api.nvim_buf_del_keymap(bufnr, mode, key, ...)
|
||||
end
|
||||
local function del_keymap(...)
|
||||
vim.api.nvim_buf_del_keymap(bufnr, ...)
|
||||
end
|
||||
|
||||
local function set_keymap(...)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, ...)
|
||||
end
|
||||
|
||||
-- local function buf_set_option(...)
|
||||
-- vim.api.nvim_buf_set_option(bufnr, ...)
|
||||
-- end
|
||||
@ -183,85 +167,42 @@ local function set_mapping(lsp_attach_info)
|
||||
key_maps = _NgConfigValues.keymaps or {}
|
||||
log('setting maps to ', key_maps)
|
||||
end
|
||||
local fmtkey, rfmtkey, nrfmtkey
|
||||
require('navigator.formatting')
|
||||
local fmtkey, rfmtkey
|
||||
for _, value in pairs(key_maps) do
|
||||
if value.doc then
|
||||
vim.notify('doc field no longer supported in navigator mapping, use desc instead')
|
||||
local f = '<Cmd>lua vim.lsp.buf.' .. value.func .. '<CR>'
|
||||
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
|
||||
if type(value.func) == 'string' then -- deprecated will remove when 0.8 is out
|
||||
vim.notify('keymap config updated: ' .. value.key .. ' func ' .. value.func .. ' should be a function')
|
||||
local f = '<Cmd>lua vim.lsp.buf.' .. value.func .. '<CR>'
|
||||
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>'
|
||||
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
|
||||
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
|
||||
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
|
||||
if not vim.tbl_contains(key_maps_help, item) then
|
||||
table.insert(key_maps_help, (val.mode or 'n') .. '|' .. val.key .. '|' .. helper_msg)
|
||||
end
|
||||
for _, val in pairs(key_maps) do
|
||||
table.insert(key_maps_help, (val.mode or 'n') .. '|' .. val.key .. '|' .. val.func)
|
||||
end
|
||||
|
||||
-- if user_opts.cap.document_formatting then
|
||||
|
||||
if doc_fmt and _NgConfigValues.lsp.format_on_save then
|
||||
local gn = api.nvim_create_augroup('NavAuGroupFormat', {})
|
||||
|
||||
local fopts = _NgConfigValues.lsp.format_options
|
||||
|
||||
if not fopts.async and vim.api.nvim_buf_line_count(0) > 4000 then
|
||||
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,
|
||||
})
|
||||
vim.cmd([[
|
||||
aug NavigatorAuFormat
|
||||
au!
|
||||
autocmd BufWritePre <buffer> lua vim.lsp.buf.format({async = true})
|
||||
aug END
|
||||
]])
|
||||
elseif fmtkey then
|
||||
del_keymap('n', fmtkey)
|
||||
end
|
||||
@ -274,19 +215,45 @@ local function set_mapping(lsp_attach_info)
|
||||
del_keymap('v', rfmtkey)
|
||||
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)
|
||||
end
|
||||
|
||||
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' }, {
|
||||
group = gn,
|
||||
callback = require('navigator.dochighlight').cmd_nohl,
|
||||
})
|
||||
local function set_event_handler(user_opts)
|
||||
user_opts = user_opts or {}
|
||||
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
|
||||
|
||||
M.toggle_lspformat = function(on)
|
||||
@ -320,6 +287,7 @@ function M.setup(attach_opts)
|
||||
set_cmds(attach_opts)
|
||||
|
||||
autocmd()
|
||||
set_event_handler(attach_opts)
|
||||
|
||||
local client = attach_opts.client or {}
|
||||
local cap = client.server_capabilities or vim.lsp.protocol.make_client_capabilities()
|
||||
@ -362,14 +330,6 @@ function M.setup(attach_opts)
|
||||
})
|
||||
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
|
||||
if _NgConfigValues.border == 'double' then
|
||||
border_style = double
|
||||
@ -388,7 +348,7 @@ M.get_keymaps_help = function()
|
||||
border = 'none',
|
||||
prompt = true,
|
||||
enter = true,
|
||||
rect = { height = 24, width = 50 },
|
||||
rect = { height = 20, width = 90 },
|
||||
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_time = require('navigator.lru').new(1000)
|
||||
local TS_analysis_enabled = require('navigator').config_values().treesitter_analysis
|
||||
local nts = require('navigator.treesitter')
|
||||
|
||||
-- extract symbol from range
|
||||
function M.get_symbol(text, range)
|
||||
if range == nil then
|
||||
@ -169,7 +169,7 @@ local function ts_functions(uri, optional)
|
||||
lerr('ts not enabled')
|
||||
return nil
|
||||
end
|
||||
local ts_func = nts.buf_func
|
||||
local ts_func = require('navigator.treesitter').buf_func
|
||||
local bufnr = vim.uri_to_bufnr(uri)
|
||||
local x = os.clock()
|
||||
trace(ts_nodes)
|
||||
@ -230,7 +230,7 @@ local function ts_definition(uri, range, optional)
|
||||
if optional then
|
||||
return
|
||||
end
|
||||
local ts_def = nts.find_definition
|
||||
local ts_def = require('navigator.treesitter').find_definition
|
||||
local bufnr = vim.uri_to_bufnr(uri)
|
||||
local x = os.clock()
|
||||
trace(ts_nodes)
|
||||
@ -252,7 +252,6 @@ local function ts_definition(uri, range, optional)
|
||||
end
|
||||
|
||||
local function find_ts_func_by_range(funcs, range)
|
||||
log(funcs, range)
|
||||
if funcs == nil or range == nil then
|
||||
return nil
|
||||
end
|
||||
@ -353,6 +352,7 @@ function M.locations_to_items(locations, ctx)
|
||||
|
||||
local unload_bufnrs = {}
|
||||
for i, loc in ipairs(locations) do
|
||||
local funcs = nil
|
||||
local item = lsp.util.locations_to_items({ loc }, enc)[1]
|
||||
item.range = locations[i].range or locations[i].targetRange
|
||||
item.uri = locations[i].uri or locations[i].targetUri
|
||||
@ -363,25 +363,13 @@ function M.locations_to_items(locations, ctx)
|
||||
log(cwd)
|
||||
end
|
||||
-- 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 context = ''
|
||||
if TS_analysis_enabled and proj_file and not ctx.no_show then
|
||||
local ts_context = nts.ref_context
|
||||
if TS_analysis_enabled and proj_file then
|
||||
funcs, unload = ts_functions(item.uri, ts_optional(i, #unload_bufnrs))
|
||||
|
||||
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
|
||||
table.insert(unload_bufnrs, unload)
|
||||
unload = nil
|
||||
end
|
||||
if not uri_def[item.uri] then
|
||||
-- find def in file
|
||||
@ -420,15 +408,9 @@ function M.locations_to_items(locations, ctx)
|
||||
end
|
||||
|
||||
item.filename = assert(vim.uri_to_fname(item.uri))
|
||||
|
||||
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.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)
|
||||
width = math.max(width, #item.text)
|
||||
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 ref_view = function(err, locations, ctx, cfg)
|
||||
cfg = cfg or {}
|
||||
local truncate = cfg and cfg.truncate or 20
|
||||
local opts = {}
|
||||
trace('arg1', err, ctx, locations)
|
||||
-- log(#locations, locations[1])
|
||||
log(#locations, locations[1])
|
||||
if ctx.combine then
|
||||
-- wait for both reference and definition LSP request
|
||||
if ctx.results == nil then
|
||||
@ -42,16 +41,24 @@ local ref_view = function(err, locations, ctx, cfg)
|
||||
end
|
||||
vim.list_extend(locations, definitions.result)
|
||||
end
|
||||
|
||||
if references and references.result and #references.result > 0 then
|
||||
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)
|
||||
end
|
||||
err = nil
|
||||
trace(locations)
|
||||
-- lets de-dup first 10 elements. some lsp does not recognize definition and reference difference
|
||||
locations = util.dedup(locations)
|
||||
trace(locations)
|
||||
end
|
||||
-- log("num", num)
|
||||
-- log("bfnr", bufnr)
|
||||
@ -79,11 +86,11 @@ local ref_view = function(err, locations, ctx, cfg)
|
||||
local thread_items = vim.deepcopy(items)
|
||||
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 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(width)
|
||||
opts = {
|
||||
@ -95,22 +102,12 @@ local ref_view = function(err, locations, ctx, cfg)
|
||||
api = 'Reference',
|
||||
enable_preview_edit = true,
|
||||
}
|
||||
local listview
|
||||
if not ctx.no_show then
|
||||
listview = gui.new_list_view(opts)
|
||||
local listview = gui.new_list_view(opts)
|
||||
|
||||
if listview == nil then
|
||||
vim.notify('failed to create preview windows', vim.lsp.log_levels.INFO)
|
||||
return
|
||||
end
|
||||
if listview == nil then
|
||||
vim.notify('failed to create preview windows', vim.lsp.log_levels.INFO)
|
||||
return
|
||||
end
|
||||
|
||||
if ctx.no_show then
|
||||
opts.side_panel = true
|
||||
local data = require('navigator.render').prepare_for_render(items, opts)
|
||||
return data
|
||||
end
|
||||
|
||||
-- trace("update items", listview.ctrl.class)
|
||||
local nv_ref_async
|
||||
nv_ref_async = vim.loop.new_async(vim.schedule_wrap(function()
|
||||
@ -145,9 +142,6 @@ end
|
||||
local ref_hdlr = function(err, locations, ctx, cfg)
|
||||
_NgConfigValues.closer = nil
|
||||
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()
|
||||
ref_view(err, locations, ctx, cfg)
|
||||
if M.async_hdlr:is_active() then
|
||||
@ -222,36 +216,7 @@ local ref = function()
|
||||
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 {
|
||||
side_panel = side_panel,
|
||||
reference_handler = ref_hdlr,
|
||||
reference = ref_req,
|
||||
ref_view = ref_view,
|
||||
|
@ -1,9 +1,7 @@
|
||||
local util = require('navigator.util')
|
||||
local log = util.log
|
||||
local trace = util.trace
|
||||
local clone = require('guihua.util').clone
|
||||
|
||||
local log = require('guihua.log').info
|
||||
local trace = require('guihua.log').trace
|
||||
local M = {}
|
||||
local clone = require('guihua.util').clone
|
||||
local function filename(url)
|
||||
if url == nil then
|
||||
return ''
|
||||
@ -71,7 +69,7 @@ function M.prepare_for_render(items, opts)
|
||||
icon = devicons.get_icon(fn, ext) or icon
|
||||
end
|
||||
-- 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
|
||||
|
||||
for i = 1, #items do
|
||||
@ -152,28 +150,52 @@ function M.prepare_for_render(items, opts)
|
||||
trace(ts_report, header_len)
|
||||
|
||||
item.text = item.text:gsub('%s*[%[%(%{]*%s*$', '')
|
||||
if item.call_by ~= nil and item.call_by ~= '' then
|
||||
ts_report = ts_report .. ' ' .. item.call_by
|
||||
if item.call_by ~= nil and #item.call_by > 0 then
|
||||
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
|
||||
if #ts_report > 1 then
|
||||
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
|
||||
item.text = string.sub(item.text, 1, l)
|
||||
item.text = util.sub_match(item.text)
|
||||
local ts_r = ts_report or ''
|
||||
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 "/'
|
||||
end
|
||||
if #space + #item.text + #ts_report >= win_width then
|
||||
if #item.text + #ts_report >= win_width then
|
||||
space = ' '
|
||||
local len = math.max(win_width - #item.text - 4, 16)
|
||||
|
||||
trace('exceeding', #item.text, #ts_report, win_width, len)
|
||||
ts_report = ts_report:sub(1, len)
|
||||
if #item.text + #ts_report > win_width then
|
||||
trace('exceeding', #item.text, #ts_report, win_width)
|
||||
space = ' '
|
||||
else
|
||||
local remain = win_width - #item.text - #ts_report
|
||||
trace('remain', remain)
|
||||
|
@ -23,7 +23,6 @@ local cwd = vim.loop.cwd()
|
||||
local log = require('navigator.util').log
|
||||
local lerr = require('navigator.util').error
|
||||
local trace = function(...) end
|
||||
trace = log
|
||||
if vim.fn.has('nvim-0.7') == 1 then
|
||||
local trace = require('navigator.util').trace
|
||||
end
|
||||
@ -110,96 +109,6 @@ function M.find_definition(range, bufnr)
|
||||
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).
|
||||
--- This function copy from treesitter/refactor/navigation.lua
|
||||
local function get_definitions(bufnr)
|
||||
@ -212,23 +121,23 @@ local function get_definitions(bufnr)
|
||||
ts_locals.recurse_local_nodes(loc.definition, function(_, node, _, match)
|
||||
-- lua doesn't compare tables by value,
|
||||
-- use the value from byte count instead.
|
||||
local row, col, offset = node:start()
|
||||
local erow, ecol, end_ = node:end_()
|
||||
local k, l, start = node:start()
|
||||
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
|
||||
log('parameter_declaration skip')
|
||||
return
|
||||
end
|
||||
nodes_set[offset] = { node = node, type = match or '' }
|
||||
nodes_set[start] = { node = node, type = match or '' }
|
||||
end)
|
||||
end
|
||||
|
||||
if loc.method then -- for go
|
||||
ts_locals.recurse_local_nodes(loc.method, function(def, node, full_match, match)
|
||||
local row, col, start = node:start()
|
||||
trace(row, col, start, def, node, full_match, match, node:parent(), node:parent():start(), node:parent():type())
|
||||
local k, l, start = node:start()
|
||||
|
||||
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
|
||||
nodes_set[start] = { node = node, type = 'method' }
|
||||
end
|
||||
@ -245,32 +154,16 @@ local function get_definitions(bufnr)
|
||||
end
|
||||
if loc.reference then -- for go
|
||||
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 p2, p2t = '', ''
|
||||
local p3, p3t = '', ''
|
||||
if node:parent() and node:parent():parent() then
|
||||
p1 = node:parent()
|
||||
p1t = node:parent():type()
|
||||
p2 = node:parent():parent()
|
||||
p2t = node:parent():parent():type()
|
||||
end
|
||||
if p2 and p2:parent() then
|
||||
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
|
||||
trace(k, l, start, def, node, full_match, match, p1t, p1, node:parent():start(), node:parent():type(), p2, p2t)
|
||||
if nodes_set[start] == nil then
|
||||
if -- qualified_type : e.g. io.Reader inside interface
|
||||
node:parent()
|
||||
@ -317,7 +210,7 @@ local function get_scope(type, source)
|
||||
local parent = current: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())
|
||||
-- a function name
|
||||
if parent:type() == 'function_name' then
|
||||
@ -452,14 +345,13 @@ local function get_all_nodes(bufnr, filter, summary)
|
||||
|
||||
trace(bufnr, filter, summary)
|
||||
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
|
||||
summary = summary or false
|
||||
local ft = vim.api.nvim_buf_get_option(bufnr, 'filetype')
|
||||
if not parsers.has_parser() then
|
||||
if not require('navigator.lspclient.clients').ft_disabled(ft) then
|
||||
-- vim.notify('ts not loaded ' .. ft, vim.lsp.log_levels.Debug)
|
||||
log('ts not loaded ' .. ft)
|
||||
vim.notify('ts not loaded ' .. ft, vim.lsp.log_levels.Debug)
|
||||
end
|
||||
return {}
|
||||
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 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,
|
||||
['local_function'] = true,
|
||||
['arrow_function'] = true,
|
||||
['type'] = true,
|
||||
['class'] = true,
|
||||
['call_expression'] = true,
|
||||
-- ['var'] = true,
|
||||
['struct'] = true,
|
||||
['method'] = true,
|
||||
@ -498,8 +394,8 @@ local function get_all_nodes(bufnr, filter, summary)
|
||||
for i = 1, n do
|
||||
local index = n + 1 - i
|
||||
local parent_def = parents[index]
|
||||
-- trace(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(parent_def.type, parent_def.node:type(), vim.treesitter.get_node_text(parent_def.node, bufnr))
|
||||
log(def.node:type(), vim.treesitter.get_node_text(def.node, bufnr))
|
||||
if
|
||||
ts_utils.is_parent(parent_def.node, def.node)
|
||||
or (
|
||||
@ -513,10 +409,10 @@ local function get_all_nodes(bufnr, filter, summary)
|
||||
)
|
||||
)
|
||||
then
|
||||
-- trace('is parent', i, index)
|
||||
log('is parent', i, index)
|
||||
break
|
||||
else
|
||||
-- trace('leave node', i, index)
|
||||
log('leave node', i, index)
|
||||
parents[index] = nil
|
||||
end
|
||||
end
|
||||
@ -543,10 +439,7 @@ local function get_all_nodes(bufnr, filter, summary)
|
||||
trace('skipped', item.type, item.kind)
|
||||
goto continue
|
||||
end
|
||||
local text = vim.treesitter.get_node_text(tsdata, bufnr) or ''
|
||||
text = vim.split(text, '\n')[1] or ''
|
||||
item.node_text = text
|
||||
log(item.node_text)
|
||||
item.node_text = vim.treesitter.get_node_text(tsdata, bufnr) or ''
|
||||
local scope, is_func
|
||||
|
||||
if summary then
|
||||
@ -554,7 +447,6 @@ local function get_all_nodes(bufnr, filter, summary)
|
||||
else
|
||||
scope, is_func = get_smallest_context(tsdata)
|
||||
end
|
||||
log(item, scope, is_func)
|
||||
if is_func then
|
||||
-- hack for lua and maybe other language aswell
|
||||
local parent = tsdata:parent()
|
||||
@ -584,7 +476,7 @@ local function get_all_nodes(bufnr, filter, summary)
|
||||
trace(item.node_text, item.kind, item.type)
|
||||
if scope ~= nil then
|
||||
if not is_func and summary then
|
||||
trace('skipped', item.node_text, item.type)
|
||||
log('skipped', item.node_text, item.type)
|
||||
goto continue
|
||||
end
|
||||
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, {
|
||||
['function'] = true,
|
||||
['arrow_function'] = true,
|
||||
['var'] = true,
|
||||
['method'] = true,
|
||||
['class'] = true,
|
||||
@ -722,7 +613,6 @@ function M.buf_func(bufnr)
|
||||
return false
|
||||
end)
|
||||
end
|
||||
log(all_nodes)
|
||||
|
||||
return all_nodes, width
|
||||
end
|
||||
|
@ -61,7 +61,7 @@ function M.get_data_from_file(filename, startLine)
|
||||
return { data = data, line = displayLine }
|
||||
end
|
||||
|
||||
function M.io_read(filename)
|
||||
function M.io_read(filename, total)
|
||||
local f = io.open(filename, 'r')
|
||||
if f == nil then
|
||||
return nil
|
||||
@ -172,45 +172,41 @@ function M.get_relative_path(base_path, my_path)
|
||||
return data
|
||||
end
|
||||
|
||||
M.log = function(...)
|
||||
return { ... }
|
||||
end
|
||||
M.info = function(...)
|
||||
return { ... }
|
||||
end
|
||||
M.trace = function(...)
|
||||
return { ... }
|
||||
end
|
||||
M.warn = function(...)
|
||||
return { ... }
|
||||
end
|
||||
M.error = function(...)
|
||||
print(...)
|
||||
end
|
||||
|
||||
local level = 'error'
|
||||
if _NgConfigValues.debug == true then
|
||||
level = 'info'
|
||||
elseif _NgConfigValues.debug == 'trace' then
|
||||
level = 'trace'
|
||||
end
|
||||
local default_config = { use_console = false, use_file = true, level = level }
|
||||
if _NgConfigValues.debug_console_output then
|
||||
default_config.use_console = true
|
||||
default_config.use_file = false
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
if _NgConfigValues.debug == true then
|
||||
level = 'info'
|
||||
elseif _NgConfigValues.debug == 'trace' then
|
||||
level = 'trace'
|
||||
end
|
||||
local default_config = { use_console = false, use_file = true, level = level }
|
||||
if _NgConfigValues.debug_console_output then
|
||||
default_config.use_console = true
|
||||
default_config.use_file = false
|
||||
end
|
||||
M._log = require('guihua.log').new(default_config, true)
|
||||
if _NgConfigValues.debug then
|
||||
-- add log to you lsp.log
|
||||
|
||||
M._log = require('guihua.log').new(default_config, true)
|
||||
if _NgConfigValues.debug then
|
||||
-- add log to you lsp.log
|
||||
M.trace = M._log.trace
|
||||
M.info = M._log.info
|
||||
M.warn = M._log.warn
|
||||
M.error = M._log.error
|
||||
M.log = M.info
|
||||
M.trace = M._log.trace
|
||||
M.info = M._log.info
|
||||
M.warn = M._log.warn
|
||||
M.error = M._log.error
|
||||
M.log = M.info
|
||||
else
|
||||
M.log = function(...)
|
||||
return { ... }
|
||||
end
|
||||
M.info = function(...)
|
||||
return { ... }
|
||||
end
|
||||
M.trace = function(...)
|
||||
return { ... }
|
||||
end
|
||||
M.warn = function(...)
|
||||
return { ... }
|
||||
end
|
||||
M.error = M._log.error
|
||||
end
|
||||
|
||||
function M.fmt(...)
|
||||
@ -491,47 +487,6 @@ function M.info(msg)
|
||||
vim.notify('INF: ' .. msg, vim.lsp.log_levels.INFO)
|
||||
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)
|
||||
if outer == nil or inner == nil then
|
||||
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
|
||||
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
|
||||
|
@ -19,7 +19,7 @@ M.remove_workspace_folder = function()
|
||||
local folders = vim.lsp.buf.list_workspace_folders()
|
||||
|
||||
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)
|
||||
end)
|
||||
end
|
||||
@ -37,7 +37,7 @@ function M.workspace_symbol_live()
|
||||
local height = _NgConfigValues.height or 0.4
|
||||
height = math.floor(height * vfn.winheight('%'))
|
||||
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 ft = vim.o.ft
|
||||
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 opt = {
|
||||
api = ' ',
|
||||
bg = 'GuihuaListDark',
|
||||
bg = 'GHListDark',
|
||||
data = data,
|
||||
items = data,
|
||||
enter = true,
|
||||
|
@ -41,23 +41,12 @@ local function load_plugins()
|
||||
use({ 'ray-x/lsp_signature.nvim' })
|
||||
use({ 'ray-x/aurora' })
|
||||
use({
|
||||
-- 'ray-x/navigator.lua',
|
||||
'~/github/ray-x/navigator.lua',
|
||||
'ray-x/navigator.lua',
|
||||
-- '~/github/ray-x/navigator.lua',
|
||||
requires = { 'ray-x/guihua.lua', run = 'cd lua/fzy && make' },
|
||||
config = function()
|
||||
require('navigator').setup({
|
||||
debug = 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 = '',
|
||||
},
|
||||
lsp_signature_help = true,
|
||||
})
|
||||
end,
|
||||
})
|
||||
|
@ -1,6 +1 @@
|
||||
std="lua52+vim"
|
||||
|
||||
[rules]
|
||||
global_usage = "allow"
|
||||
multiple_statements = "allow"
|
||||
unused_variable = "allow"
|
||||
std="vim"
|
||||
|
@ -60,10 +60,10 @@ describe('should run lsp call hierarchy', function()
|
||||
-- eq(panel.activePanel.sections[1].nodes[1].name, 'measure')
|
||||
end)
|
||||
|
||||
it('should not crash and show hierarchy', function()
|
||||
it('should show hierarchy', function()
|
||||
vim.fn.setpos('.', { bufn, 24, 15, 0 })
|
||||
local ret = require('navigator.hierarchy')._call_hierarchy()
|
||||
vim.wait(400, function() end)
|
||||
eq(ret, ret) -- make sure doesn't crash the result
|
||||
eq(ret, {})
|
||||
end)
|
||||
end)
|
||||
|
@ -114,9 +114,9 @@ describe('should run lsp reference', function()
|
||||
|
||||
-- print('win', vim.inspect(win))
|
||||
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(items[1].display_filename, './tests/fixtures/interface.go')
|
||||
eq(items[1].display_filename, './interface.go')
|
||||
|
||||
-- eq(width, 60)
|
||||
end)
|
||||
@ -137,7 +137,7 @@ describe('should run lsp reference', function()
|
||||
-- print('win', vim.inspect(win))
|
||||
print('items', vim.inspect(items))
|
||||
-- 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(items[1].display_filename, "./interface.go")
|
||||
|
||||
|
8
vim.toml
8
vim.toml
@ -1,5 +1,5 @@
|
||||
[selene]
|
||||
base = "lua52"
|
||||
base = "lua51"
|
||||
name = "vim"
|
||||
|
||||
[vim]
|
||||
@ -8,11 +8,9 @@ any = true
|
||||
[_G]
|
||||
property = true
|
||||
writable = "new-fields"
|
||||
|
||||
[_NgConfigValues]
|
||||
any = true
|
||||
# property = true
|
||||
# writable = "full-write"
|
||||
property = true
|
||||
writable = "new-fields"
|
||||
|
||||
[debug]
|
||||
property = true
|
||||
|
47
vim.yml
47
vim.yml
@ -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…
Reference in New Issue
Block a user