aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2025-07-30 19:36:09 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2026-01-30 18:01:24 +0100
commitdd1aca9ad2f19c6116f4fc8c8a7651b2b7742cbf (patch)
treeb9ccac0e4a7a2df6f222dc9dc16722e465133476
parent4ec576b6d600711160f7e3d10bbe60308c5b232c (diff)
downloadvis-lspc-dd1aca9ad2f19c6116f4fc8c8a7651b2b7742cbf.tar.gz
vis-lspc-dd1aca9ad2f19c6116f4fc8c8a7651b2b7742cbf.zip
improve navigation windows
Remove broken autoscrolling. Add commands to control a code/navigation window pair. Support multiple navigation window pairs. Improve default navigation window keybindings.
-rw-r--r--README.md14
-rw-r--r--init.lua131
-rw-r--r--lspc.lua6
3 files changed, 72 insertions, 79 deletions
diff --git a/README.md b/README.md
index a5ff2d5..81440cb 100644
--- a/README.md
+++ b/README.md
@@ -78,12 +78,12 @@ Alternatively, a plugin manager like [vis-plug](https://github.com/erf/vis-plug)
<C- > - get completions
< o> - open the symbol navigation window
-#### Non-Auto-Jump Navigation Window
+#### Navigation Window
Normal mode:
- < s> - scroll to the selected symbol
- < j> - jump to the selected symbol (switch to the code window)
- < x> - close the navigaion window
+ <p> - scroll to the selected symbol
+ <Enter> - jump to the selected symbol (switch to the code window)
+ <q> - close the navigaion window
### Available commands
@@ -114,7 +114,12 @@ Alternatively, a plugin manager like [vis-plug](https://github.com/erf/vis-plug)
lspc-show-diagnostics - show the available diagnostics of the current line
lspc-next-diagnostic - jump to the next available diagnostic
lspc-prev-diagnostic - jump to the previous available diagnostic
+
+ # navigation windows
lspc-navigate-symbols - navigate a file by its symbols in a seperate window
+ lspc-navwin-scroll - scroll to the selected symbol
+ lspc-navwin-jump - jump to the selected symbol
+ lspc-navwin-close - close the navigation window
### Available configuration options
@@ -141,7 +146,6 @@ Available options are:
* `universal_root_globs = {}` - Globs to consider as workspace root for any language server (e.g. `*.git` or `*.hg`).
* `fallback_dirname_as_root = false` - If set to true a file's directory is used as workspace root if no explicit root was found.
* `navwin_symbols_format = '%s[%.1s] %s\n'` - The format string used to display a symbol in the symbol navigation window.
-* `navwin_auto_scroll = true` - If set to true the code window will scroll to the currently selected symbol in the navigation window without user interaction.
* `navwin_layout = 'vr'` - Layout where the navigation window will be placed (`v[r|l]|h[t|b]`: vertical right or left; horizontal top or bottom).
#### Configure your own Language Server
diff --git a/init.lua b/init.lua
index d01969c..0819cb6 100644
--- a/init.lua
+++ b/init.lua
@@ -1625,19 +1625,19 @@ local function recursive_bfs_symbols_flatten(symbols, indent)
end
--- Scroll the code window to the definition of the symbol selected in the navigation window.
-local function lspc_navwin_scroll_codewin(switch_win)
- local line = lspc.navctx.navwin.selection.line
+local function navwin_scroll_codewin(self, switch_win)
+ local line = self.navwin.selection.line
-- No valid selection in the navigation window
- if line > #lspc.navctx.ranges then
+ if line > #self.ranges then
return
end
- local sel = lsp_pos_to_vis_sel(lspc.navctx.ranges[line].start)
+ local sel = lsp_pos_to_vis_sel(self.ranges[line].start)
-- Set the selection in the code window to the selected symbol
- lspc.navctx.codewin.selection:to(sel.line, sel.col)
+ self.codewin.selection:to(sel.line, sel.col)
if switch_win then
- vis.win = lspc.navctx.codewin
+ vis.win = self.codewin
end
end
@@ -1670,71 +1670,53 @@ local function lspc_navwin_from_symbols(symbols, ctx)
assert(navwin)
assert(codewin)
- lspc.navctx = {
+ ctx = {
navwin = navwin,
codewin = codewin,
ranges = ranges,
old_layout = old_layout,
}
+ lspc.navwins[navwin] = ctx
+ lspc.navwins[codewin] = ctx
+
-- Prepare window to be our symbol navigation window
navwin.file:insert(0, symbols_outline)
navwin:draw()
+ navwin:map(vis.modes.NORMAL, '<Enter>', function()
+ navwin_scroll_codewin(ctx, true)
+ end, 'jump to the selected symbol')
+ navwin:map(vis.modes.NORMAL, 'p', function()
+ navwin_scroll_codewin(ctx, false)
+ end, 'scroll to the selected symbol')
+ navwin:map(vis.modes.NORMAL, 'q', function()
+ navwin:close(true)
+ end, 'close this window')
+
-- Jump to navigation window
vis.win = navwin
- -- Follow the position in the navigation window
- local nav_win_win_highlight_handler
- if lspc.navwin_auto_scroll then
- -- Create event handlers to connect the position in the navigation window to
- -- the original window.
- nav_win_win_highlight_handler = function(win)
- -- This is not the navigation window
- if win ~= lspc.navctx.navwin then
- return true
- end
-
- -- scroll the code window without switching to it.
- lspc_navwin_scroll_codewin(false)
- return true
- end
- vis.events.subscribe(vis.events.WIN_HIGHLIGHT, nav_win_win_highlight_handler)
- else
- navwin:map(vis.modes.NORMAL, ' j', function()
- lspc_navwin_scroll_codewin(true)
- end, 'jump to the selected symbol')
- navwin:map(vis.modes.NORMAL, ' s', function()
- lspc_navwin_scroll_codewin(false)
- end, 'scroll to the selected symbol')
- navwin:map(vis.modes.NORMAL, ' x', function()
- lspc.navctx.navwin:close(true)
- end, 'close the navgation window')
- end
-
-- Remove the event handlers.
local nav_win_close_handler
nav_win_close_handler = function(win)
- if win ~= lspc.navctx.navwin and win ~= lspc.navctx.codewin then
+ -- Not our windows
+ if win ~= navwin and win ~= codewin then
return true
-- The code windows was closed, therefore we can also close the navigation window
- elseif win == lspc.navctx.codewin then
+ elseif win == codewin then
lspc:log('Code window closed. Force close the navigation window.')
- lspc.navctx.navwin:close(true)
- -- Reset everything after closing the navigation window
- else
- -- reset vis' layout
- vis.ui.layout = lspc.navctx.old_layout
-
- -- remove the navigation window event handlers
- if lspc.navwin_auto_jump then
- vis.events.unsubscribe(vis.events.UI_DRAW, nav_win_win_highlight_handler)
- end
-
- -- remove the navigation context
- lspc.navctx = nil
- vis.events.unsubscribe(vis.events.WIN_CLOSE, nav_win_close_handler)
+ navwin:close(true)
+ return
end
+ -- reset vis' layout
+ vis.ui.layout = lspc.navwins[codewin].old_layout
+
+ -- remove the navigation window
+ lspc.navwins[navwin] = nil
+ lspc.navwins[codewin] = nil
+ lspc:log('unsubscribe navwin event handler')
+ vis.events.unsubscribe(vis.events.WIN_CLOSE, nav_win_close_handler)
return true
end
@@ -1982,32 +1964,39 @@ vis:command_register('lspc-navigate-symbols', function(argv, _, win)
if not ls:is_file_opened(win.file.path) then
lspc_open(ls, win, win.file)
end
- if lspc.navctx then
- lspc:err('navigation window already active')
- return
+ if lspc.navwins[win] then
+ lspc.navwins[win].navwin:close(true)
+ else
+ lspc_nav_symbols(ls, win)
end
- lspc_nav_symbols(ls, win)
-end, 'navigate the file by its symbols')
+end, 'toggle the symbol navigation')
-vis:command_register('lspc-navigate-close', function()
- if not lspc.navctx then
- lspc:err('no navigation window active')
- return
+vis:command_register('lspc-navwin-jump', function(_, _, win)
+ local navwin = lspc.navwins[win]
+ if not navwin then
+ lspc:err('no associated navigation window')
+ else
+ navwin_scroll_codewin(navwin, true)
end
- lspc.navctx.navwin:close(true)
-end, 'close the navigation window')
+end, 'jump to the selected symbol')
-vis:command_register('lspc-navigate-jump', function(_, _, win)
- if not lspc.navctx then
- lspc:err('no navigation window active')
- return
- end
- if win ~= lspc.navctx.navwin then
- lspc:err('not in navigation window')
- return
+vis:command_register('lspc-navwin-scroll', function(_, _, win)
+ local navwin = lspc.navwins[win]
+ if not navwin then
+ lspc:err('no associated navigation window')
+ else
+ navwin_scroll_codewin(navwin, false)
end
+end, 'scroll the code window to the selected symbol')
-end, 'navigate to the selected symbol')
+vis:command_register('lspc-navwin-close', function(_, _, win)
+ local navwin = lspc.navwins[win]
+ if not navwin then
+ lspc:err('no associated navigation window')
+ else
+ navwin.navwin:close(true)
+ end
+end, 'close the navigation window')
-- vis-lspc event hooks
vis.events.subscribe(vis.events.WIN_OPEN, function(win)
diff --git a/lspc.lua b/lspc.lua
index b1b5e98..389961d 100644
--- a/lspc.lua
+++ b/lspc.lua
@@ -63,9 +63,6 @@ local lspc = {
navwin_symbol_format = '%s[%.1s] %s\n', -- short version
-- navwin_symbol_format = '%s[%s] %s %d:%d\n', -- verbose version
- -- Automaticaly scroll the code window to the symbol selected in the navigation window.
- navwin_auto_scroll = true,
-
-- The layout where the navigation window will be placed.
-- The following layout identifiers are supported:
-- 'vr' -- DEFAULT: vertical right
@@ -74,6 +71,9 @@ local lspc = {
-- 'hb' -- horizontak bottom
navwin_layout = 'vr',
+ -- active navigation windows
+ navwins = {},
+
-- events
events = {
LS_INITIALIZED = 'LspcEvent::LS_INITIALIZED',