diff --git a/README.md b/README.md
index d06604c..84459e7 100644
--- a/README.md
+++ b/README.md
@@ -13,23 +13,25 @@ The following screenshot shows javascript call tree 🌲 of variable `browser` i
![navigator](https://user-images.githubusercontent.com/1681295/126022829-291a7a2e-4d24-4fde-8293-5ae61562e67d.jpg)
Explanation:
-- The first line of floating windows shows there are 3 references for the symbol *browser* in closure.js
-- The first reference of browser is an assignment, an emoji 📝 indicates the value is changed in this line. In many
-cases, we search for references to find out when the value changed.
+
+- The first line of floating windows shows there are 3 references for the symbol _browser_ in closure.js
+- The first reference of browser is an assignment, an emoji 📝 indicates the value is changed in this line. In many
+ cases, we search for references to find out when the value changed.
- The second reference of `browser` is inside function `displayName` and `displayName` sit inside `makeFunc`, So you
-will see ` displayName{} <- makeFunc{}`
+ will see ` displayName{} <- makeFunc{}`
- The third similar to the second, as var browser is on the right side of '=', the value not changed in this line
-and emoji is not shown.
+ and emoji is not shown.
#### Example: C++ definition
C++ example: search reference and definition
![cpp_ref](https://user-images.githubusercontent.com/1681295/119215215-8bd7a080-bb0f-11eb-82fc-8cdf1955e6e7.jpg)
-You may find a 🦕 dinosaur(d) on the line of `Rectangle rect,` which means there is a definition (d for def) of rect in this line.
+You may find a 🦕 dinosaur(d) on the line of `Rectangle rect,` which means there is a definition (d for def) of rect in this line.
-``<- f main()`` means the definition is inside function main().
+`<- f main()` means the definition is inside function main().
#### Golang struct type
+
Struct type references in multiple Go ﳑ files
![go_reference](https://user-images.githubusercontent.com/1681295/119123823-54b3b180-ba73-11eb-8790-097601e10f6a.gif)
@@ -37,6 +39,7 @@ Struct type references in multiple Go ﳑ files
This feature can provide you info in which function/class/method the variable was referenced. It is handy for a large
project where class/function definition is too long to fit into the preview window. Also provides a bird's eye view of where the
variable is:
+
- Referenced
- Modified
- Defined
@@ -45,14 +48,14 @@ variable is:
# Features:
- LSP easy setup. Support the most commonly used lsp clients setup. Dynamic lsp activation based on buffer type. This
-also enables you to handle workspace with mixed types of codes (e.g. Go + javascript + yml). A better default setup is
-included for LSP clients.
+ also enables you to handle workspace with mixed types of codes (e.g. Go + javascript + yml). A better default setup is
+ included for LSP clients.
- Out of box experience. 10 lines of minimum vimrc can turn your neovim into a full-featured LSP & Treesitter powered IDE
- Unorthodox UI with floating windows, navigator provides a visual way to manage and navigate through symbols, diagnostic errors, reference etc. It covers
-all features(handler) provided by LSP from commonly used search reference, to less commonly used search for interface
-implementation.
+ all features(handler) provided by LSP from commonly used search reference, to less commonly used search for interface
+ implementation.
- Luv async thread and tasks
@@ -71,14 +74,14 @@ implementation.
- Grouping references/implementation/incoming/outgoing based on file names.
- Treesitter based variable/function context analysis. It is 10x times faster compared to purely rely on LSP. In most
-of the case, it takes treesitter less than 4 ms to read and render all nodes for a file of 1,000 LOC.
+ of the case, it takes treesitter less than 4 ms to read and render all nodes for a file of 1,000 LOC.
- The first plugin, IMO, allows you to search in all treesitter symbols in the workspace.
- Nerdfont, emoji for LSP and treesitter kind
- Optimize display (remove trailing bracket/space), display the caller of reference, de-duplicate lsp results (e.g reference
-in the same line). Using treesitter for file preview highlighter etc
+ in the same line). Using treesitter for file preview highlighter etc
- ccls call hierarchy (Non-standard `ccls/call` API) supports
@@ -186,9 +189,6 @@ EOF
```
-
-
-
Nondefault configuration example:
```lua
@@ -219,7 +219,7 @@ require'navigator'.setup({
code_action_prompt = {enable = true, sign = true, sign_priority = 40, virtual_text = true},
icons = {
-- Code action
- code_action_icon = " ",
+ code_action_icon = "🏏",
-- Diagnostics
diagnostic_head = '🐛',
diagnostic_head_severity_1 = "🈲",
@@ -268,6 +268,7 @@ require'navigator'.setup({
### LSP clients
Built clients:
+
```lua
local servers = {
"angularls", "gopls", "tsserver", "flow", "bashls", "dockerls", "julials", "pylsp", "pyright",
@@ -283,24 +284,24 @@ Navigator will try to load avalible lsp server/client based on filetype. The cli
incremental sync and debounce is enabled by navigator. And the lsp
snippet will be enabled. So you could use COQ and nvim-cmp snippet expand.
-
Other than above setup, additional none default setup are used for following lsp:
-* gopls
-* clangd
-* rust_analyzer
-* sqls
-* sumneko_lua
-* pyright
-* ccls
+- gopls
+- clangd
+- rust_analyzer
+- sqls
+- sumneko_lua
+- pyright
+- ccls
Please check [client setup](https://github.com/ray-x/navigator.lua/blob/26012cf9c172aa788a2e53018d94b32c5c75af75/lua/navigator/lspclient/clients.lua#L98-L234)
-The plugin can work with multiple LSP, e.g sqls+gopls+efm. But there are cases you may need to disable some of the
-servers. (Prevent loading multiple LSP for same source code.) e.g. I saw strange behaviours when I use pyls+pyright+pyls_ms
+The plugin can work with multiple LSP, e.g sqls+gopls+efm. But there are cases you may need to disable some of the
+servers. (Prevent loading multiple LSP for same source code.) e.g. I saw strange behaviours when I use pyls+pyright+pyls_ms
together. If you have multiple similar LSP installed and have trouble with the plugin, please enable only one at a time.
### Disable a lsp client loading from navigator
+
To disable a specific LSP, set `filetypes` to {} e.g.
```lua
@@ -320,56 +321,54 @@ require'navigator'.setup({
### Default keymaps
-| mode | key | function |
-|--- |--- |--- |
-| n | gr | show reference and context |
-| i | \ | signature help |
-| n | \ | signature help |
-| n | gW | workspace symbol |
-| n | gD | declaration |
-| n | g0 | document symbol |
-| n | \ | go to definition (if multiple show listview) |
-| n | gp | definition |
-| n | \ | definition|
-| n | g\ | implementation|
-| n | gT | treesitter document symbol |
-| n | \gT | treesitter symbol for all open buffers |
-| n | K | hover doc |
-| n | \ca | code action (when you see 💡 ) |
-| n | \la | code lens action (when you see a codelens indicator) |
-| v | \cA | range code action (when you see 💡 ) |
-| n | \rn | rename with floating window|
-| n | \re | rename (lsp default)|
-| n | \gi | incoming calls|
-| n | \go | outgoing calls|
-| n | gi | implementation |
-| n | \ D | type definition |
-| n | gL | show line diagnostic |
-| n | gG | show diagnostic for all buffers |
-| n | ]d | next diagnostic|
-| n | [d | previous diagnostic|
-| n | ]r | next treesitter reference/usage|
-| n | [r | previous treesitter reference/usage|
-| n | \ wa | add workspace folder|
-| n | \ wr | remove workspace folder|
-| n | \ wl | print workspace folder|
-| n | \k | toggle reference highlight |
-| i/n | \ | previous item in list|
-| i/n | \ | next item in list|
-| i/n | number 1~9 | move to ith row/item in the list|
-| i/n | \ | previous item in list|
-| i/n | \ | next item in list|
-| n | \j | move cursor to preview (windows move to bottom view point)|
-| n | \k | move cursor to list (windows move to up view point)|
-| i/n | \ | open preview file in nvim/Apply action|
-| n | \ | open preview file in nvim with vsplit|
-| n | \ | open preview file in nvim with split|
-| n | \ | open preview file in nvim/Apply action|
-| i/n | \ | previous page in listview|
-| i/n | \ | next page in listview|
-| i/n | \ | save the modification to preview window to file|
-
-
+| mode | key | function |
+| ---- | --------------- | ---------------------------------------------------------- |
+| n | gr | show reference and context |
+| i | \ | signature help |
+| n | \ | signature help |
+| n | gW | workspace symbol |
+| n | gD | declaration |
+| n | g0 | document symbol |
+| n | \ | go to definition (if multiple show listview) |
+| n | gp | definition |
+| n | \ | definition |
+| n | g\ | implementation |
+| n | gT | treesitter document symbol |
+| n | \gT | treesitter symbol for all open buffers |
+| n | K | hover doc |
+| n | \ca | code action (when you see 💡 ) |
+| n | \la | code lens action (when you see a codelens indicator) |
+| v | \cA | range code action (when you see 💡 ) |
+| n | \rn | rename with floating window |
+| n | \re | rename (lsp default) |
+| n | \gi | incoming calls |
+| n | \go | outgoing calls |
+| n | gi | implementation |
+| n | \ D | type definition |
+| n | gL | show line diagnostic |
+| n | gG | show diagnostic for all buffers |
+| n | ]d | next diagnostic |
+| n | [d | previous diagnostic |
+| n | ]r | next treesitter reference/usage |
+| n | [r | previous treesitter reference/usage |
+| n | \ wa | add workspace folder |
+| n | \ wr | remove workspace folder |
+| n | \ wl | print workspace folder |
+| n | \k | toggle reference highlight |
+| i/n | \ | previous item in list |
+| i/n | \ | next item in list |
+| i/n | number 1~9 | move to ith row/item in the list |
+| i/n | \ | previous item in list |
+| i/n | \ | next item in list |
+| n | \j | move cursor to preview (windows move to bottom view point) |
+| n | \k | move cursor to list (windows move to up view point) |
+| i/n | \ | open preview file in nvim/Apply action |
+| n | \ | open preview file in nvim with vsplit |
+| n | \ | open preview file in nvim with split |
+| n | \ | open preview file in nvim/Apply action |
+| i/n | \ | previous page in listview |
+| i/n | \ | next page in listview |
+| i/n | \ | save the modification to preview window to file |
### Colors/Highlight:
@@ -382,11 +381,9 @@ hi default GHTextViewDark guifg=#e0d8f4 guibg=#332e55
hi default GHListDark guifg=#e0d8f4 guibg=#103234
```
-There are other Lsp highlight been used in this plugin, e.g LspReferenceRead/Text/Write are used for document highlight,
+There are other Lsp highlight been used in this plugin, e.g LspReferenceRead/Text/Write are used for document highlight,
LspDiagnosticsXXX are used for diagnostic. Please check highlight.lua and dochighlight.lua for more info.
-
-
## Dependency
- lspconfig
@@ -399,13 +396,14 @@ 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).
-
## Integration with lspinstall
+
If you'd like to only use the lsp servers installed by lspinstall. Please set
```lua
lspinstall = false
```
+
In the config
## Usage
@@ -431,22 +429,21 @@ require'navigator'.setup({on_attach = function(client, bufnr) require 'illuminat
Highlight I am using:
-* LspReferenceRead, LspReferenceText and LspReferenceWrite are used for `autocmd CursorHold lua vim.lsp.buf.document_highlight()`
-That is where you saw the current symbol been highlighted.
+- LspReferenceRead, LspReferenceText and LspReferenceWrite are used for `autocmd CursorHold lua vim.lsp.buf.document_highlight()`
+ That is where you saw the current symbol been highlighted.
-* GHListDark and GHTextViewDark is used for floating listvew and TextView. They are be based on current background
-(Normal) and PmenuSel
+- 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
+- In future, I will use NormalFloat for floating view. But ATM, most of colorscheme does not define NormalFloat
You can override the above highlight to fit your current colorscheme
-
## commands
-| command | function |
-|--- |--- |
-| LspToggleFmt | toggle lsp auto format |
+| command | function |
+| ------------ | ---------------------- |
+| LspToggleFmt | toggle lsp auto format |
## Screenshots
@@ -465,6 +462,7 @@ Pls check the first part of README
![workspace symbol](https://github.com/ray-x/files/blob/master/img/navigator/workspace_symbol.gif?raw=true)
### highlight document symbol and jump between reference
+
![multiple_symbol_hi3](https://user-images.githubusercontent.com/1681295/120067627-f9f80680-c0bf-11eb-9216-18e5c8547f59.gif)
# Current symbol highlight and jump backward/forward between symbols
@@ -480,7 +478,6 @@ Visual studio code style show errors minimap in scroll bar area
![diagnostic_scroll_bar](https://user-images.githubusercontent.com/1681295/128736430-e365523d-810c-4c16-a3b4-c74969f45f0b.jpg)
-
Diagnostic in single bufer
![diagnostic](https://github.com/ray-x/files/blob/master/img/navigator/diag.jpg?raw=true)
@@ -495,7 +492,6 @@ You can in place edit your code in floating window
https://user-images.githubusercontent.com/1681295/121832919-89cbc080-cd0e-11eb-9778-11d0f356b38d.mov
-
(Note: This feature only avalible in `find reference` and `find diagnostic`, You can not add/remove lines in floating window)
### Implementation
@@ -549,14 +545,12 @@ Codelens for C++/ccls. Symbol reference
![codelens_cpp_ccls](https://user-images.githubusercontent.com/1681295/132429134-abc6547e-79cc-44a4-b7a9-23550b895e51.jpg)
-
-
-
### Predefined LSP symbol nerdfont/emoji
![nerdfont](https://github.com/ray-x/files/blob/master/img/navigator/icon_nerd.jpg?raw=true)
# Break changes and known issues
+
[known issues I am working on](https://github.com/ray-x/navigator.lua/issues/1)
# Todo
diff --git a/lua/navigator.lua b/lua/navigator.lua
index 4923317..a97215d 100644
--- a/lua/navigator.lua
+++ b/lua/navigator.lua
@@ -8,6 +8,7 @@ _NgConfigValues = {
preview_lines_before = 5, -- lines before the highlight line
default_mapping = true,
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"
combined_attach = "both", -- both: use both customized attach and navigator default attach, mine: only use my attach defined in vimrc
@@ -33,7 +34,7 @@ _NgConfigValues = {
-- to load those files
diagnostic_virtual_text = true, -- show virtual for diagnostic message
diagnostic_update_in_insert = false, -- update diagnostic message in insert mode
- diagnostic_scrollbar_sign = {'▃', '█'}, -- set to nil to disable, set to {'╍', 'ﮆ'} to enable diagnostic status in scroll bar area
+ diagnostic_scrollbar_sign = {'▃', '▆', '█'}, -- set to nil to disable, set to {'╍', 'ﮆ'} to enable diagnostic status in scroll bar area
tsserver = {
-- filetypes = {'typescript'} -- disable javascript etc,
-- set to {} to disable the lspclient for all filetype
@@ -46,16 +47,22 @@ _NgConfigValues = {
},
lspinstall = false, -- set to true if you would like use the lsp installed by lspinstall
icons = {
+ icons = true, -- set to false to use system default ( if you using a terminal does not have nerd/icon)
-- Code action
- code_action_icon = " ",
+ code_action_icon = "🏏", -- "",
-- code lens
code_lens_action_icon = " ",
-- Diagnostics
diagnostic_head = '🐛',
+ diagnostic_err = "📛",
+ diagnostic_warn = "👎",
+ diagnostic_info = [[👩]],
+ diagnostic_hint = [[💁]],
+
diagnostic_head_severity_1 = "🈲",
diagnostic_head_severity_2 = "☣️",
diagnostic_head_severity_3 = "👎",
- diagnostic_head_description = "📛",
+ diagnostic_head_description = "👹",
diagnostic_virtual_text = "🦊",
diagnostic_file = "🚑",
-- Values
@@ -131,7 +138,7 @@ M.setup = function(cfg)
-- log("navigator loader")
if _NgConfigValues.code_action_prompt.enable then
- vim.cmd [[autocmd CursorHold * lua require'navigator.codeAction'.code_action_prompt()]]
+ vim.cmd [[autocmd CursorHold,CursorHoldI * lua require'navigator.codeAction'.code_action_prompt()]]
end
-- vim.cmd("autocmd BufNewFile,BufRead *.go setlocal noexpandtab tabstop=4 shiftwidth=4")
if not _NgConfigValues.loaded then
@@ -141,12 +148,6 @@ M.setup = function(cfg)
if _NgConfigValues.ts_fold == true then
require('navigator.foldts').on_attach()
end
-
- --- if code line enabled
- if _NgConfigValues.lsp.code_lens then
- require("navigator.codelens").setup()
- end
-
end
return M
diff --git a/lua/navigator/codeAction.lua b/lua/navigator/codeAction.lua
index 6906cf3..b71c461 100644
--- a/lua/navigator/codeAction.lua
+++ b/lua/navigator/codeAction.lua
@@ -5,9 +5,13 @@ local code_action = {}
local gui = require "navigator.gui"
local config = require("navigator").config_values()
local api = vim.api
+
+local sign_name = "NavigatorLightBulb"
+
+local diagnostic = vim.diagnostic or vim.lsp.diagnostic
code_action.code_action_handler = util.mk_handler(function(err, actions, ctx, cfg)
log(actions, ctx)
- if actions == nil or vim.tbl_isempty(actions) then
+ if actions == nil or vim.tbl_isempty(actions) or err then
print("No code actions available")
return
end
@@ -19,13 +23,16 @@ code_action.code_action_handler = util.mk_handler(function(err, actions, ctx, cf
table.insert(data, title)
actions[i].display_title = title
end
- local width = 0
+ local width = 42
for _, str in ipairs(data) do
if #str > width then
width = #str
end
end
+ local divider = string.rep('─', width + 2)
+
+ table.insert(data, 2, divider)
local apply = require('navigator.lspwrapper').apply_action
local function apply_action(action)
local action_chosen = nil
@@ -42,7 +49,7 @@ code_action.code_action_handler = util.mk_handler(function(err, actions, ctx, cf
apply(action_chosen)
end
- gui.new_list_view {
+ local listview = gui.new_list_view {
items = data,
width = width + 4,
loc = "top_center",
@@ -58,6 +65,9 @@ code_action.code_action_handler = util.mk_handler(function(err, actions, ctx, cf
return pos
end
}
+
+ log("new buffer", listview.bufnr)
+ vim.api.nvim_buf_add_highlight(listview.bufnr, -1, 'Title', 0, 0, -1)
end)
-- https://github.com/glepnir/lspsaga.nvim/blob/main/lua/lspsaga/codeaction.lua
@@ -71,22 +81,17 @@ local get_current_winid = function()
return api.nvim_get_current_win()
end
-local sign_name = "NavigatorLightBulb"
-
-if vim.tbl_isempty(vim.fn.sign_getdefined(sign_name)) then
- vim.fn.sign_define(sign_name,
- {text = config.icons.code_action_icon, texthl = "LspDiagnosticsSignHint"})
-end
-
-local function _update_virtual_text(line)
+local function _update_virtual_text(line, actions)
local namespace = get_namespace()
pcall(api.nvim_buf_clear_namespace, 0, namespace, 0, -1)
if line then
+ log(line, actions)
local icon_with_indent = " " .. config.icons.code_action_icon
+ local title = actions[1].title
pcall(api.nvim_buf_set_extmark, 0, namespace, line, -1, {
- virt_text = {{icon_with_indent, "LspDiagnosticsSignHint"}},
+ virt_text = {{icon_with_indent .. title, "LspDiagnosticsSignHint"}},
virt_text_pos = "overlay",
hl_mode = "combine"
})
@@ -94,6 +99,11 @@ local function _update_virtual_text(line)
end
local function _update_sign(line)
+
+ if vim.tbl_isempty(vim.fn.sign_getdefined(sign_name)) then
+ vim.fn.sign_define(sign_name,
+ {text = config.icons.code_action_icon, texthl = "LspDiagnosticsSignHint"})
+ end
local winid = get_current_winid()
if code_action[winid] == nil then
code_action[winid] = {}
@@ -110,11 +120,14 @@ local function _update_sign(line)
end
end
-local need_check_diagnostic = {["go"] = true, ["python"] = true}
+-- local need_check_diagnostic = {["go"] = true, ["python"] = true}
+local need_check_diagnostic = {['python'] = true}
function code_action:render_action_virtual_text(line, diagnostics)
- return function(_, _, actions)
+ return function(err, actions, context)
+ log(err, line, diagnostics, actions, context)
if actions == nil or type(actions) ~= "table" or vim.tbl_isempty(actions) then
+ -- no actions cleanup
if config.code_action_prompt.virtual_text then
_update_virtual_text(nil)
end
@@ -127,6 +140,7 @@ function code_action:render_action_virtual_text(line, diagnostics)
if next(diagnostics) == nil then
_update_sign(nil)
else
+ -- no diagnostic, no code action sign..
_update_sign(line)
end
else
@@ -139,10 +153,10 @@ function code_action:render_action_virtual_text(line, diagnostics)
if next(diagnostics) == nil then
_update_virtual_text(nil)
else
- _update_virtual_text(line)
+ _update_virtual_text(line, actions)
end
else
- _update_virtual_text(line)
+ _update_virtual_text(line, actions)
end
end
end
@@ -186,7 +200,15 @@ code_action.code_action_prompt = function()
return
end
- local diagnostics = vim.lsp.diagnostic.get_line_diagnostics()
+ local diagnostics
+ if diagnostic.get_line_diagnostics then
+ -- old version
+ diagnostics = diagnostic.get_line_diagnostics()
+ else
+ local lnum = vim.api.nvim_win_get_cursor(0)[1] - 1
+ diagnostics = diagnostic.get(vim.api.nvim_get_current_buf(), {lnum = lnum})
+ end
+
local winid = get_current_winid()
code_action[winid] = code_action[winid] or {}
code_action[winid].lightbulb_line = code_action[winid].lightbulb_line or 0
diff --git a/lua/navigator/codelens.lua b/lua/navigator/codelens.lua
index 8a364f3..27a7a80 100644
--- a/lua/navigator/codelens.lua
+++ b/lua/navigator/codelens.lua
@@ -69,7 +69,9 @@ function M.setup()
local on_codelens = vim.lsp.handlers["textDocument/codeLens"]
vim.lsp.handlers["textDocument/codeLens"] = mk_handler(
function(err, result, ctx, cfg)
- trace(err, result, ctx.client_id, ctx.bufnr, cfg)
+ -- trace(err, result, ctx.client_id, ctx.bufnr, cfg or {})
+ cfg = cfg or {}
+ ctx = ctx or {bufnr = vim.api.nvim_get_current_buf()}
if nvim_0_6() then
on_codelens(err, result, ctx, cfg)
codelens_hdlr(err, result, ctx, cfg)
@@ -139,8 +141,12 @@ function M.run_action()
end
apply(action_chosen)
end
+
+ local divider = string.rep('─', width + 2)
+
+ table.insert(data, 2, divider)
if #data > 0 then
- gui.new_list_view {
+ local lv = gui.new_list_view {
items = data,
width = width + 4,
loc = "top_center",
@@ -156,7 +162,70 @@ function M.run_action()
return pos
end
}
+
+ vim.api.nvim_buf_add_highlight(lv.bufnr, -1, 'Title', 0, 0, -1)
+ end
+end
+
+local virtual_types_ns = api.nvim_create_namespace("ng_virtual_types");
+
+function M.disable()
+ local bufnr = vim.api.nvim_get_current_buf()
+ vim.api.nvim_buf_clear_namespace(bufnr, virtual_types_ns, 0, -1)
+ is_enabled = false
+end
+
+M.inline = function()
+ local lsp = vim.lsp
+ if is_enabled == false then
+ return
+ end
+ if vim.fn.getcmdwintype() == ':' then
+ return
end
+ if #vim.lsp.buf_get_clients() == 0 then
+ return
+ end
+
+ local bufnr = api.nvim_get_current_buf()
+ local parameter = lsp.util.make_position_params()
+ local response = lsp.buf_request_sync(bufnr, "textDocument/codeLens", parameter)
+
+ -- Clear previous highlighting
+ api.nvim_buf_clear_namespace(bufnr, virtual_types_ns, 0, -1)
+
+ 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
+
+ local cmd = vv.command
+ local msg = _NgConfigValues.icons.code_action_icon .. ' '
+ if cmd then
+ local txt = cmd.title or ''
+ txt = txt .. ' ' .. (cmd.command or '') .. ' '
+ msg = msg .. txt .. ' '
+ end
+
+ log(msg)
+ api.nvim_buf_set_extmark(bufnr, virtual_types_ns, start_line, -1, {
+ virt_text = {{msg, "LspCodeLensText"}},
+ virt_text_pos = 'overlay',
+ hl_mode = 'combine'
+ })
+ end
+ end
+ -- else
+ -- api.nvim_command("echohl WarningMsg | echo 'VirtualTypes: No response' | echohl None")
+ end
+
end
return M
diff --git a/lua/navigator/debounce.lua b/lua/navigator/debounce.lua
new file mode 100644
index 0000000..b9d9f76
--- /dev/null
+++ b/lua/navigator/debounce.lua
@@ -0,0 +1,29 @@
+local M = {}
+
+function M.debounce_trailing(ms, fn)
+ local timer = vim.loop.new_timer()
+ return function(...)
+ local argv = {...}
+ timer:start(ms, 0, function()
+ timer:stop()
+ fn(unpack(argv))
+ end)
+ end
+end
+
+function M.throttle_leading(ms, fn)
+ local timer = vim.loop.new_timer()
+ local running = false
+ return function(...)
+ if not running then
+ timer:start(ms, 0, function()
+ running = false
+ timer:stop()
+ end)
+ running = true
+ fn(...)
+ end
+ end
+end
+
+return M
diff --git a/lua/navigator/diagnostics.lua b/lua/navigator/diagnostics.lua
index be657f9..c3abb88 100644
--- a/lua/navigator/diagnostics.lua
+++ b/lua/navigator/diagnostics.lua
@@ -1,11 +1,11 @@
local gui = require "navigator.gui"
local diagnostic_list = {}
-
-_NG_VT_NS = vim.api.nvim_create_namespace("navigator_lua")
+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
--- trace = log
local error = util.error
local path_sep = require"navigator.util".path_sep()
@@ -13,101 +13,160 @@ local mk_handler = require"navigator.util".mk_handler
local path_cur = require"navigator.util".path_cur()
diagnostic_list[vim.bo.filetype] = {}
-local function error_marker(result, client_id)
- if _NgConfigValues.lsp.diagnostic_scrollbar_sign == nil then -- not enabled or already shown
+local function clear_diag_VT(bufnr) -- important for clearing out when no more errors
+ log(bufnr, _NG_VT_DIAG_NS)
+ if bufnr == nil or _NG_VT_DIAG_NS == nil then
return
end
- local first_line = vim.fn.line('w0')
- -- local rootfolder = vim.fn.expand('%:h:t') -- get the current file root folder
- trace(result)
- local bufnr = vim.uri_to_bufnr(result.uri)
- if bufnr ~= vim.api.nvim_get_current_buf() then
- -- log("not same buf", client_id, result.uri, bufnr, vim.fn.bufnr())
- return
+ vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
+ _NG_VT_DIAG_NS = nil
+end
+
+local function get_count(bufnr, level)
+ if vim.diagnostic ~= nil then
+ return #diagnostic.get(bufnr, {severity = level})
+ else
+ return diagnostic.get_count(bufnr, level)
end
- trace(result, bufnr)
+end
- if result == nil or result.diagnostics == nil or #result.diagnostics == 0 then
- local diag_cnt = vim.lsp.diagnostic.get_count(bufnr, [[Error]])
- + vim.lsp.diagnostic.get_count(bufnr, [[Warning]])
- if diag_cnt == 0 and _NG_VT_NS ~= nil then
- vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_NS, 0, -1)
+local function error_marker(result, ctx, config)
+ vim.defer_fn(function()
+ if vim.tbl_isempty(result.diagnostics) then
+ return
end
- return
- end
+ if _NgConfigValues.lsp.diagnostic_scrollbar_sign == nil then -- not enabled or already shown
+ return
+ end
+ local first_line = vim.fn.line('w0')
+ -- local rootfolder = vim.fn.expand('%:h:t') -- get the current file root folder
- -- total line num of current buffer
+ local bufnr = ctx.bufnr
+ if bufnr == nil then
+ bufnr = vim.uri_to_bufnr(result.uri)
+ 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
- -- local winid = vim.fn.win_getid(vim.fn.winnr())
- -- local winid = vim.api.nvim_get_current_win()
- bufnr = vim.api.nvim_get_current_buf()
- local total_num = vim.fn.getbufinfo(bufnr)[1].linecount
- -- local total_num = vim.fn.getbufinfo(vim.fn.winbufnr(winid))[1].linecount
- -- window size of current buffer
+ if not vim.api.nvim_buf_is_loaded(bufnr) then
+ log("buf not loaded")
+ return
- local stats = vim.api.nvim_list_uis()[1]
- local wwidth = stats.width;
- local wheight = stats.height;
+ end
- -- local wwidth = vim.fn.winwidth(winid)
- -- local wheight = vim.fn.winheight(winid)
- if total_num <= wheight then
- return
- end
- if _NG_VT_NS == nil then
- _NG_VT_NS = vim.api.nvim_create_namespace("navigator_lua")
- end
+ trace('schedule callback', result, ctx, config)
+ -- trace(result, bufnr)
- vim.api.nvim_buf_clear_namespace(0, _NG_VT_NS, 0, -1)
- if total_num <= wheight then
- first_line = 0
- end
- local pos = {}
- -- pos of virtual text
- for _, diag in pairs(result.diagnostics) do
- if diag.range and diag.range.start and diag.range.start.line then
- local p = diag.range.start.line
- p = util.round(p * wheight / math.max(wheight, total_num))
- if pos[#pos] and pos[#pos].line == p then
- pos[#pos] = {
- line = p,
- sign = _NgConfigValues.lsp.diagnostic_scrollbar_sign[2],
- severity = diag.severity
- }
- else
- table.insert(pos, {
- line = p,
- sign = _NgConfigValues.lsp.diagnostic_scrollbar_sign[1],
- severity = diag.severity
- })
+ if result == nil or result.diagnostics == nil or #result.diagnostics == 0 then
+ 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")
+ vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
end
+ return
end
- trace("pos", pos, diag.range.start)
- end
- for i, s in pairs(pos) do
- local hl = 'ErrorMsg'
- if s.severity > 1 then
- hl = 'WarningMsg'
+ -- total line num of current buffer
+
+ -- local winid = vim.fn.win_getid(vim.fn.winnr())
+ -- 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 = vim.api.nvim_list_uis()[1]
+ -- local wwidth = stats.width;
+ local wheight = stats.height;
+
+ if total_num <= wheight then
+ return
end
- local l = s.line + first_line
- if l > total_num then
- l = total_num
+ if _NG_VT_DIAG_NS == nil then
+ _NG_VT_DIAG_NS = vim.api.nvim_create_namespace("navigator_lua_diag")
end
- vim.api.nvim_buf_set_extmark(bufnr, _NG_VT_NS, l, -1,
- {virt_text = {{s.sign, hl}}, virt_text_pos = 'right_align'})
- end
+
+ local pos = {}
+ local diags = result.diagnostics
+
+ for i, _ in ipairs(diags) do
+ if not diags[i].range then
+ diags[i].range = {start = {line = diags[i].lnum}}
+ end
+ end
+
+ table.sort(diags, function(a, b)
+ return a.range.start.line < b.range.start.line
+ end)
+ -- pos of virtual text
+ for _, diag in pairs(result.diagnostics) do
+ local p
+ if not diag.range then
+ diag.range = {start = {line = diag.lnum}}
+ end
+ if diag.range and diag.range.start and diag.range.start.line then
+ p = diag.range.start.line
+ p = util.round(p * wheight / math.max(wheight, total_num))
+ if pos[#pos] and pos[#pos].line == p then
+ local bar = '▆'
+ if pos[#pos] == _NgConfigValues.lsp.diagnostic_scrollbar_sign[2] then
+ bar = '█'
+ end
+ pos[#pos] = {line = p, sign = bar, severity = math.min(diag.severity, pos[#pos].severity)}
+ else
+ table.insert(pos, {
+ line = p,
+ sign = _NgConfigValues.lsp.diagnostic_scrollbar_sign[1],
+ severity = diag.severity
+ })
+ end
+ end
+ trace("pos, line:", p, diag.severity, diag.range)
+ end
+
+ if not vim.tbl_isempty(pos) then
+ vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
+ end
+ for i, s in pairs(pos) do
+ local hl = 'ErrorMsg'
+ if s.severity == 2 then
+ hl = 'WarningMsg'
+ else
+ hl = 'DiagnosticInfo'
+ end
+ local l = s.line + first_line
+ if l > total_num then
+ l = total_num
+ end
+ trace("add pos", s, bufnr)
+
+ vim.api.nvim_buf_set_extmark(bufnr, _NG_VT_DIAG_NS, l, -1,
+ {virt_text = {{s.sign, hl}}, virt_text_pos = 'right_align'})
+ end
+
+ end, 10) -- defer in 10ms
+end
+
+local update_err_marker_async = function()
+ local debounce = require'navigator.debounce'.debounce_trailing
+ return debounce(20, error_marker)
end
local diag_hdlr = mk_handler(function(err, result, ctx, config)
- trace(result)
+
+ require"navigator.lspclient.highlight".diagnositc_config_sign()
if err ~= nil then
- log(err, config)
+ log(err, config, result)
return
end
- if vim.fn.mode() ~= 'n' and config.update_in_insert == false then
+
+ local mode = vim.api.nvim_get_mode().mode
+ if mode ~= 'n' and config.update_in_insert == false then
log("skip in insert mode")
return
end
@@ -116,23 +175,26 @@ local diag_hdlr = mk_handler(function(err, result, ctx, config)
if diagnostic_list[ft] == nil then
diagnostic_list[vim.bo.filetype] = {}
end
- -- vim.lsp.diagnostic.clear(vim.fn.bufnr(), client.id, nil, nil)
+
+ local client_id = ctx.client_id
+ -- not sure if I should do this hack
+ if vim.tbl_isempty(result.diagnostics) then
+ if vim.api.nvim_buf_is_loaded(ctx.bufnr) then
+ -- diagnostic.reset(ctx.client_id)
+ -- clear_diag_VT(ctx.bufnr)
+ end
+ return
+ end
+
if util.nvim_0_6() then
+ trace(err, result, ctx, config)
vim.lsp.diagnostic.on_publish_diagnostics(err, result, ctx, config)
else
log("old version of lsp nvim 050")
vim.lsp.diagnostic.on_publish_diagnostics(err, _, result, ctx.client_id, _, config)
end
local uri = result.uri
- if err then
- log("diag", err, result)
- return
- end
- if vim.fn.mode() ~= 'n' and config.update_in_insert == false then
- log("skip in insert mode")
- return
- end
- trace("diag: ", vim.fn.mode(), result, ctx, config)
+ -- trace("diag: ", mode, result, ctx, config)
if result and result.diagnostics then
local item_list = {}
for _, v in ipairs(result.diagnostics) do
@@ -155,6 +217,7 @@ local diag_hdlr = mk_handler(function(err, result, ctx, config)
local bufnr1 = vim.uri_to_bufnr(uri)
if not vim.api.nvim_buf_is_loaded(bufnr1) then
if _NgConfigValues.diagnostic_load_files then
+ -- print('load buffers')
vim.fn.bufload(bufnr1) -- this may slow down the neovim
local pos = v.range.start
local row = pos.line
@@ -178,10 +241,12 @@ local diag_hdlr = mk_handler(function(err, result, ctx, config)
result.uri = uri
end
- error_marker(result, ctx.client_id)
+ local marker = update_err_marker_async()
+ marker(result, ctx, config)
else
- vim.api.nvim_buf_clear_namespace(0, _NG_VT_NS, 0, -1)
- _NG_VT_NS = nil
+ trace("great, no diag errors")
+ vim.api.nvim_buf_clear_namespace(0, _NG_VT_DIAG_NS, 0, -1)
+ _NG_VT_DIAG_NS = nil
end
end)
@@ -196,9 +261,7 @@ local diagnostic_cfg = {
-- and on, using buffer local variables
signs = true,
update_in_insert = _NgConfigValues.lsp.diagnostic_update_in_insert or false,
- severity_sort = function(a, b)
- return a.severity < b.severity
- end
+ severity_sort = {reverse = true}
}
if _NgConfigValues.lsp.diagnostic_virtual_text == false then
@@ -209,24 +272,13 @@ end
M.diagnostic_handler = vim.lsp.with(diag_hdlr, diagnostic_cfg)
M.hide_diagnostic = function()
- if _NG_VT_NS then
- vim.api.nvim_buf_clear_namespace(0, _NG_VT_NS, 0, -1)
- _NG_VT_NS = nil
+ if _NG_VT_DIAG_NS then
+ vim.api.nvim_buf_clear_namespace(0, _NG_VT_DIAG_NS, 0, -1)
+ _NG_VT_DIAG_NS = nil
end
end
M.show_diagnostic = function()
- vim.lsp.diagnostic.get_all()
-
- local bufs = vim.api.nvim_list_bufs()
- for _, buf in ipairs(bufs) do
- local bname = vim.fn.bufname(buf)
- if #bname > 0 and not util.exclude(bname) then
- if vim.api.nvim_buf_is_loaded(buf) then
- vim.lsp.diagnostic.get(buf, nil)
- end
- end
- end
if diagnostic_list[vim.bo.filetype] ~= nil then
-- log(diagnostic_list[vim.bo.filetype])
-- vim.fn.setqflist({}, " ", {title = "LSP", items = diagnostic_list[vim.bo.filetype]})
@@ -239,56 +291,81 @@ M.show_diagnostic = function()
end
-- log(display_items)
if #display_items > 0 then
- gui.new_list_view({
+ local listview = gui.new_list_view({
items = display_items,
api = _NgConfigValues.icons.diagnostic_file .. _NgConfigValues.icons.diagnostic_head
.. " Diagnostic ",
enable_preview_edit = true
})
+ trace("new buffer", listview.bufnr)
+ vim.api.nvim_buf_add_highlight(listview.bufnr, -1, 'Title', 0, 0, -1)
end
end
end
--- set quickfix win
+-- set loc list win
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!")
+ return
+ end
+ local clients = vim.lsp.buf_get_clients(0)
+ local cfg = {open = diag_cnt > 0}
+ for _, client in pairs(clients) do
+ cfg.client_id = client['id']
+ break
+ end
+
if not vim.tbl_isempty(vim.lsp.buf_get_clients(0)) then
- local err_cnt = vim.lsp.diagnostic.get_count(0, [[Error]])
+ local err_cnt = get_count(0, [[Error]])
if err_cnt > 0 and _NgConfigValues.lsp.disply_diagnostic_qf then
- vim.lsp.diagnostic.set_loclist()
+ if diagnostic.set_loclist then
+ diagnostic.set_loclist(cfg)
+ else
+ cfg.namespaces = diagnostic.get_namespace(nil)
+ diagnostic.setloclist(cfg)
+ end
else
vim.cmd("lclose")
end
end
end
-local function clear_diag_VT() -- important for clearing out when no more errors
- vim.api.nvim_buf_clear_namespace(0, _NG_VT_NS, 0, -1)
- _NG_VT_NS = nil
-end
-
-- TODO: callback when scroll
function M.update_err_marker()
- if _NG_VT_NS == nil then
+ trace("update err marker", _NG_VT_DIAG_NS)
+ if _NG_VT_DIAG_NS == nil then
-- nothing to update
return
end
local bufnr = vim.api.nvim_get_current_buf()
- local diag_cnt = vim.lsp.diagnostic.get_count(bufnr, [[Error]])
- + vim.lsp.diagnostic.get_count(bufnr, [[Warning]])
- if diag_cnt == 0 and _NG_VT_NS ~= nil then
- vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_NS, 0, -1)
+ local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]])
+ + get_count(bufnr, [[Info]]) + get_count(bufnr, [[Hint]])
+
+ -- redraw
+ if diag_cnt == 0 and _NG_VT_DIAG_NS ~= nil then
+
+ vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
+ trace("no errors")
return
end
- -- redraw
- vim.api.nvim_buf_clear_namespace(0, _NG_VT_NS, 0, -1)
- local errors = vim.lsp.diagnostic.get(bufnr)
+ vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
+ local errors = diagnostic.get(bufnr)
if #errors == 0 then
+ trace("errors", errors)
return
end
- local result = {diagnostics = errors, uri = errors[1].uri}
- error_marker(result)
+ local uri = vim.uri_from_bufnr(bufnr)
+ local result = {diagnostics = errors, uri = errors[1].uri or uri}
+
+ trace(result)
+ local marker = update_err_marker_async()
+ marker(result, {bufnr = bufnr, method = 'textDocument/publishDiagnostics'})
end
-- TODO: update the marker
@@ -300,4 +377,14 @@ if _NgConfigValues.lsp.diagnostic_scrollbar_sign then
vim.cmd [[autocmd WinScrolled * lua require'navigator.diagnostics'.update_err_marker()]]
end
+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_line_diagnostics()
+ local lnum = vim.api.nvim_win_get_cursor(0)[1] - 1
+ diagnostic.show_line_diagnostics({border = 'single'}, vim.api.nvim_get_current_buf(), lnum)
+end
+
return M
diff --git a/lua/navigator/gui.lua b/lua/navigator/gui.lua
index 9cd3972..7a47f41 100644
--- a/lua/navigator/gui.lua
+++ b/lua/navigator/gui.lua
@@ -58,6 +58,11 @@ function M._preview_location(opts) -- location, width, pos_x, pos_y
uri = uri,
allow_edit = opts.enable_edit
}
+
+ if _NgConfigValues.external then
+ win_opts.external = true
+ win_opts.relative = nil
+ end
-- win_opts.items = contents
win_opts.hl_line = opts.lnum - display_range.start.line
if win_opts.hl_line < 0 then
@@ -84,7 +89,8 @@ function M._preview_location(opts) -- location, width, pos_x, pos_y
border = opts.border,
display_range = win_opts.display_range,
hl_line = win_opts.hl_line,
- allow_edit = win_opts.allow_edit
+ allow_edit = win_opts.allow_edit,
+ external = win_opts.external
})
return w
end
@@ -125,7 +131,7 @@ function M.new_list_view(opts)
if config.width ~= nil and config.width > 0.3 and config.width < 0.99 then
width = math.floor(wwidth * config.width)
end
- width = math.min(120, width)
+ width = math.min(120, width, opts.width or 120)
local wheight = math.floor(1 + api.nvim_get_option("lines")
* (_NgConfigValues.height + _NgConfigValues.preview_height))
local pheight = math.max(_NgConfigValues.preview_lines, math.floor(
@@ -173,6 +179,10 @@ function M.new_list_view(opts)
if transparency == 100 then
transparency = nil
end
+ local ext = _NgConfigValues.external
+ if ext then
+ opts.relative = nil
+ end
return ListView:new({
loc = loc,
prompt = prompt,
@@ -186,6 +196,7 @@ function M.new_list_view(opts)
-- data = display_data,
data = data,
border = border,
+ external = ext,
on_confirm = opts.on_confirm or function(item, split_opts)
log(split_opts)
split_opts = split_opts or {}
@@ -213,6 +224,7 @@ function M.new_list_view(opts)
offset_x = 0,
offset_y = offset_y,
border = border,
+ external = ext,
enable_edit = opts.enable_preview_edit or false
})
end
diff --git a/lua/navigator/lazyloader.lua b/lua/navigator/lazyloader.lua
index bc4cd45..fe7fd34 100644
--- a/lua/navigator/lazyloader.lua
+++ b/lua/navigator/lazyloader.lua
@@ -1,7 +1,7 @@
local log = require"navigator.util".log
_LoadedClients = {}
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
diff --git a/lua/navigator/lspclient/attach.lua b/lua/navigator/lspclient/attach.lua
index 39bd38a..743f072 100644
--- a/lua/navigator/lspclient/attach.lua
+++ b/lua/navigator/lspclient/attach.lua
@@ -14,6 +14,7 @@ local M = {}
M.on_attach = function(client, bufnr)
local uri = vim.uri_from_bufnr(bufnr)
+
if uri == "file://" or uri == "file:///" or #uri < 11 then
log("skip for float buffer", uri)
return {error = "invalid file", result = nil}
@@ -24,7 +25,7 @@ M.on_attach = function(client, bufnr)
diagnostic_map(bufnr)
-- add highlight for Lspxxx
require"navigator.lspclient.highlight".add_highlight()
-
+ require"navigator.lspclient.highlight".diagnositc_config_sign()
api.nvim_buf_set_option(bufnr, "omnifunc", "v:lua.vim.lsp.omnifunc")
require("navigator.lspclient.mapping").setup({
diff --git a/lua/navigator/lspclient/clients.lua b/lua/navigator/lspclient/clients.lua
index db06b0b..3c9e572 100644
--- a/lua/navigator/lspclient/clients.lua
+++ b/lua/navigator/lspclient/clients.lua
@@ -518,6 +518,11 @@ local function setup(user_opts)
wait_lsp_startup(ft, retry, lsp_opts)
+ --- if code line enabled
+ if _NgConfigValues.lsp.code_lens then
+ require("navigator.codelens").setup()
+ end
+
_LoadedClients[ft] = true
-- _LoadedClients[ft] = vim.tbl_extend("keep", _LoadedClients[ft] or {}, {ft})
diff --git a/lua/navigator/lspclient/highlight.lua b/lua/navigator/lspclient/highlight.lua
index d209cfc..f14cdd0 100644
--- a/lua/navigator/lspclient/highlight.lua
+++ b/lua/navigator/lspclient/highlight.lua
@@ -1,20 +1,62 @@
local M = {}
+
+local log = require"navigator.util".log
local api = vim.api
-- lsp sign ﮻ ﯭ ﳀ
function M.diagnositc_config_sign()
- vim.fn.sign_define('LspDiagnosticsSignError',
- {text = '', texthl = 'LspDiagnosticsSignError', linehl = '', numhl = ''})
- vim.fn.sign_define('LspDiagnosticsSignWarning',
- {text = '', texthl = 'LspDiagnosticsSignWarning', linehl = '', numhl = ''})
- vim.fn.sign_define('LspDiagnosticsSignInformation', {
- text = '',
- texthl = 'LspDiagnosticsSignInformation',
- linehl = '',
- numhl = ''
- })
- vim.fn.sign_define('LspDiagnosticsSignHint',
- {text = '💡', texthl = 'LspDiagnosticsSignHint', linehl = '', numhl = ''})
+ if M.configed then
+ return
+ end
+ local icons = _NgConfigValues.icons
+
+ local sign_name = "NavigatorLightBulb"
+ if vim.fn.sign_getdefined(sign_name).text == nil then
+
+ vim.fn
+ .sign_define(sign_name, {text = icons.code_action_icon, texthl = "LspDiagnosticsSignHint"})
+
+ sign_name = "NavigatorCodeLensLightBulb"
+ vim.fn.sign_define(sign_name,
+ {text = icons.code_lens_action_icon, texthl = "LspDiagnosticsSignHint"})
+ end
+
+ local e, w, i, h = icons.diagnostic_err, icons.diagnostic_warn, icons.diagnostic_info,
+ icons.diagnostic_hint
+ if vim.diagnostic ~= nil then
+ local t = vim.fn.sign_getdefined('DiagnosticSignWarn')
+ if vim.tbl_isempty(t) or t[1].text == "W " and icons.icons == true then
+
+ vim.fn.sign_define('DiagnosticSignError',
+ {text = e, texthl = 'DiagnosticError', linehl = '', numhl = ''})
+ vim.fn.sign_define('DiagnosticSignWarn',
+ {text = w, texthl = 'DiagnosticWarn', linehl = '', numhl = ''})
+ vim.fn.sign_define('DiagnosticSignInfo',
+ {text = i, texthl = 'DiagnosticInfo', linehl = '', numhl = ''})
+ vim.fn.sign_define('DiagnosticSignHint',
+ {text = h, texthl = 'DiagnosticHint', linehl = '', numhl = ''})
+
+ t = vim.fn.sign_getdefined('DiagnosticSignWarn')
+ log('*** t ', t, "diagnostic add sign")
+ end
+ else
+ local t = vim.fn.sign_getdefined('LspDiagnosticSignWarn')
+ if vim.tbl_isempty(t) or t[1].text == "W " and icons.icons == true then
+ vim.fn.sign_define('LspDiagnosticsSignError',
+ {text = e, texthl = 'LspDiagnosticsSignError', linehl = '', numhl = ''})
+ vim.fn.sign_define('LspDiagnosticsSignWarning',
+ {text = w, texthl = 'LspDiagnosticsSignWarning', linehl = '', numhl = ''})
+ vim.fn.sign_define('LspDiagnosticsSignInformation', {
+ text = i,
+ texthl = 'LspDiagnosticsSignInformation',
+ linehl = '',
+ numhl = ''
+ })
+ vim.fn.sign_define('LspDiagnosticsSignHint',
+ {text = h, texthl = 'LspDiagnosticsSignHint', linehl = '', numhl = ''})
+ end
+ end
+ M.configed = true
end
function M.add_highlight()
@@ -24,8 +66,12 @@ function M.add_highlight()
api.nvim_command("hi! link LspDiagnosticsUnderlineWarning SpellRare")
api.nvim_command("hi! link LspDiagnosticsUnderlineInformation SpellRare")
api.nvim_command("hi! link LspDiagnosticsUnderlineHint SpellRare")
- api.nvim_command("hi def link NGPreviewTitle Title")
+ 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'},
diff --git a/lua/navigator/lspclient/mapping.lua b/lua/navigator/lspclient/mapping.lua
index bc1050a..ede1920 100644
--- a/lua/navigator/lspclient/mapping.lua
+++ b/lua/navigator/lspclient/mapping.lua
@@ -31,7 +31,7 @@ local key_maps = {
{key = "go", func = "outgoing_calls()"},
{key = "gi", func = "implementation()"},
{key = "D", func = "type_definition()"},
- {key = "gL", func = "diagnostic.show_line_diagnostics( { border = 'single' })"},
+ {key = "gL", func = "require('navigator.diagnostics').show_line_diagnostics()"},
{key = "gG", func = "require('navigator.diagnostics').show_diagnostic()"},
{key = "]d", func = "diagnostic.goto_next({ border = 'single' })"},
{key = "[d", func = "diagnostic.goto_prev({ border = 'single' })"},
@@ -119,7 +119,11 @@ local function set_mapping(user_opts)
if string.find(value.func, "require") then
f = "lua " .. value.func .. ""
elseif string.find(value.func, "diagnostic") then
- f = "lua vim.lsp." .. value.func .. ""
+ local diagnostic = 'lua vim.'
+ if vim.lsp.diagnostic ~= nil then
+ diagnostic = 'lua vim.lsp.'
+ end
+ f = diagnostic .. value.func .. ""
elseif string.find(value.func, "vim.") then
f = "lua " .. value.func .. ""
end
@@ -241,9 +245,11 @@ function M.setup(user_opts)
require"navigator.diagnostics".diagnostic_handler
-- TODO: when active signature merge to neovim, remove this setup:
- local hassig, sig = pcall(require, "lsp_signature")
- if hassig then
- if _NgConfigValues.signature_help_cfg then
+
+ if _NgConfigValues.signature_help_cfg then
+ log("setup signature from navigator")
+ local hassig, sig = pcall(require, "lsp_signature")
+ if hassig then
sig.setup(_NgConfigValues.signature_help_cfg)
end
else
diff --git a/lua/navigator/lspwrapper.lua b/lua/navigator/lspwrapper.lua
index 7f73ce4..32d70ea 100644
--- a/lua/navigator/lspwrapper.lua
+++ b/lua/navigator/lspwrapper.lua
@@ -40,7 +40,7 @@ local function check_lhs(text, symbol)
return false
end
if s < eq and eq ~= eq2 then
- log(symbol, "modified")
+ trace(symbol, "modified")
end
if eq == eq3 + 1 then
return false
diff --git a/lua/navigator/protocal.lua b/lua/navigator/protocal.txt
similarity index 84%
rename from lua/navigator/protocal.lua
rename to lua/navigator/protocal.txt
index 0c4d546..e952e94 100644
--- a/lua/navigator/protocal.lua
+++ b/lua/navigator/protocal.txt
@@ -1,4 +1,4 @@
-parameter
+-- [[ -- parameter
{
position = {
character = 6,
@@ -7,8 +7,7 @@ parameter
textDocument = {
uri = "file:///Users/username/lsp_test/go/interface.go"
}
-}
-
+} ]]
--[[ -- incomming/outgoing
@@ -103,8 +102,8 @@ dir from result { {
-
--- [[ locations/reference from lsp
+-- locations/reference from lsp
+-- [[
{ {
range = {
["end"] = {
@@ -130,7 +129,7 @@ dir from result { {
},
uri = "file:///Users/username/lsp-test/go/interface.go"
} }
---]]
+]] --
-- definition
@@ -1124,3 +1123,173 @@ definition.lua:9: { {
}
}
} }
+
+
+-- rust code lens
+
+
+{ {
+ result = { {
+ command = {
+ arguments = { {
+ args = {
+ cargoArgs = { "run", "--package", "hello", "--bin", "hello" },
+ cargoExtraArgs = {},
+ executableArgs = {},
+ workspaceRoot = "/Users/ray.xu/lsp_test/rust"
+ },
+ kind = "cargo",
+ label = "run hello",
+ location = {
+ targetRange = {
+ end = {
+ character = 1,
+ line = 68
+ },
+ start = {
+ character = 0,
+ line = 45
+ }
+ },
+ targetSelectionRange = {
+ end = {
+ character = 7,
+ line = 45
+ },
+ start = {
+ character = 3,
+ line = 45
+ }
+ },
+ targetUri = "file:///Users/ray.xu/lsp_test/rust/src/main.rs"
+ }
+ } },
+ command = "rust-analyzer.runSingle",
+ title = "▶︎ Run "
+ },
+ range = {
+ end = {
+ character = 7,
+ line = 45
+ },
+ start = {
+ character = 3,
+ line = 45
+ }
+ }
+ }, {
+ command = {
+ arguments = { {
+ args = {
+ cargoArgs = { "run", "--package", "hello", "--bin", "hello" },
+ cargoExtraArgs = {},
+ executableArgs = {},
+ workspaceRoot = "/Users/ray.xu/lsp_test/rust"
+ },
+ kind = "cargo",
+ label = "run hello",
+ location = {
+ targetRange = {
+ end = {
+ character = 1,
+ line = 68
+ },
+ start = {
+ character = 0,
+ line = 45
+ }
+ },
+ targetSelectionRange = {
+ end = {
+ character = 7,
+ line = 45
+ },
+ start = {
+ character = 3,
+ line = 45
+ }
+ },
+ targetUri = "file:///Users/ray.xu/lsp_test/rust/src/main.rs"
+ }
+ } },
+ command = "rust-analyzer.debugSingle",
+ title = "Debug"
+ },
+ range = {
+ end = {
+ character = 7,
+ line = 45
+ },
+ start = {
+ character = 3,
+ line = 45
+ }
+ }
+ }, {
+ data = {
+ impls = {
+ position = {
+ character = 6,
+ line = 2
+ },
+ textDocument = {
+ uri = "file:///Users/ray.xu/lsp_test/rust/src/main.rs"
+ }
+ }
+ },
+ range = {
+ end = {
+ character = 10,
+ line = 2
+ },
+ start = {
+ character = 6,
+ line = 2
+ }
+ }
+ }, {
+ data = {
+ impls = {
+ position = {
+ character = 7,
+ line = 28
+ },
+ textDocument = {
+ uri = "file:///Users/ray.xu/lsp_test/rust/src/main.rs"
+ }
+ }
+ },
+ range = {
+ end = {
+ character = 10,
+ line = 28
+ },
+ start = {
+ character = 7,
+ line = 28
+ }
+ }
+ }, {
+ data = {
+ impls = {
+ position = {
+ character = 7,
+ line = 31
+ },
+ textDocument = {
+ uri = "file:///Users/ray.xu/lsp_test/rust/src/main.rs"
+ }
+ }
+ },
+ range = {
+ end = {
+ character = 10,
+ line = 31
+ },
+ start = {
+ character = 7,
+ line = 31
+ }
+ }
+ } }
+ } }
diff --git a/lua/navigator/render.lua b/lua/navigator/render.lua
index ae8276e..1f096b3 100644
--- a/lua/navigator/render.lua
+++ b/lua/navigator/render.lua
@@ -3,6 +3,9 @@ local trace = require"guihua.log".trace
local M = {}
local clone = require'guihua.util'.clone
local function filename(url)
+ if url == nil then
+ return ''
+ end
return url:match("^.+/(.+)$") or url
end
diff --git a/lua/navigator/util.lua b/lua/navigator/util.lua
index 04472df..6584c37 100644
--- a/lua/navigator/util.lua
+++ b/lua/navigator/util.lua
@@ -393,4 +393,18 @@ function M.partial(func, arg)
end))
end
+-- alternatively: use vim.notify("namespace does not exist or is anonymous", vim.log.levels.ERROR)
+
+function M.warn(msg)
+ vim.api.nvim_echo({{"WRN: " .. msg, "WarningMsg"}}, true, {})
+end
+
+function M.error(msg)
+ vim.api.nvim_echo({{"ERR: " .. msg, "ErrorMsg"}}, true, {})
+end
+
+function M.info(msg)
+ vim.api.nvim_echo({{"Info: " .. msg}}, true, {})
+end
+
return M