From 82ba3462e10ae2bc9f84dc2ed52a6804828d1639 Mon Sep 17 00:00:00 2001 From: bilder Date: Fri, 24 May 2024 14:23:54 +0800 Subject: [PATCH] feat(finder): auto locate cursor to current reference save save save finish! --- lua/lspsaga/finder/init.lua | 11 ++++++++++- lua/lspsaga/slist.lua | 36 ++++++++++++++++++++++++++++++++++++ lua/lspsaga/util.lua | 17 +++++++++++++++++ test/util_spec.lua | 15 +++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/lua/lspsaga/finder/init.lua b/lua/lspsaga/finder/init.lua index 6870d5455..a46cbdc5b 100644 --- a/lua/lspsaga/finder/init.lua +++ b/lua/lspsaga/finder/init.lua @@ -190,9 +190,18 @@ function fd:handler(method, results, spin_close, done) end if done then + local popup_curosor_line = slist.find_node_by(self.list, function(node) + local value = node.value + local range, bufnr = value.range, value.bufnr + local location = api.nvim_win_get_cursor(self.callerwinid) + local caller_bufnr = api.nvim_win_get_buf(self.callerwinid) + + return range ~= nil and util.is_in_range(location, range) and caller_bufnr == bufnr + end).value.winline + vim.bo[self.lbufnr].modifiable = false spin_close() - api.nvim_win_set_cursor(self.lwinid, { 3, 6 }) + api.nvim_win_set_cursor(self.lwinid, { popup_curosor_line, 6 }) box.indent(ns, self.lbufnr, self.lwinid) api.nvim_create_autocmd('BufEnter', { callback = function(args) diff --git a/lua/lspsaga/slist.lua b/lua/lspsaga/slist.lua index 899db410a..c200f36b7 100644 --- a/lua/lspsaga/slist.lua +++ b/lua/lspsaga/slist.lua @@ -1,3 +1,23 @@ +---@class Node +---@field value NodeValue +---@field next Node +---@field prev Node + +---@class NodeValue +---@field range? Range +---@field bufnr? number +---@field client_id number +---@field inlevel number +---@field line string +---@field uri string +---@field winline number + +---@class Range +---@field start Position +---@field end Position + +---@alias Position {character:number, line:number} + ---single linked list module local M = {} @@ -21,6 +41,22 @@ function M.tail_push(list, node) tmp.next = { value = node } end +--- Finds a node in the linked list that matches the given predicate function. +---@param list Node -- The linked list to search. +---@param predicate fun(node: Node): boolean -- The predicate function to match the node. +---@return Node | nil -- The found node or nil if not found. +function M.find_node_by(list, predicate) + local current = list + while current do + if predicate(current) then + return current + end + current = current.next + end + + return nil +end + function M.find_node(list, curlnum) local tmp = list if not tmp.value then diff --git a/lua/lspsaga/util.lua b/lua/lspsaga/util.lua index e4252941b..7cd5915b6 100644 --- a/lua/lspsaga/util.lua +++ b/lua/lspsaga/util.lua @@ -226,4 +226,21 @@ function M.valid_markdown_parser() end end +---@param location integer[] [row, col] +---@param range { end : { character : number, line : number }, start : { character : number, line : number } } +---@return boolean +function M.is_in_range(location, range) + local row = location[1] + local col = location[2] + local start_row = range.start.line + 1 + local end_row = range['end'].line + 1 + local end_col = range['end'].character + local start_col = range.start.character + + if row >= start_row and row <= end_row and col >= start_col and col <= end_col then + return true + end + return false +end + return M diff --git a/test/util_spec.lua b/test/util_spec.lua index 2ef21eca5..22d8ad15e 100644 --- a/test/util_spec.lua +++ b/test/util_spec.lua @@ -74,4 +74,19 @@ describe('lspsaga util', function() res = util.path_sub('/Users/test/(test-dir)/%proj-rs/src/main.rs', root) assert.is_equal('src/main.rs', res) end) + + it('util.is_in_range', function() + local range = { + ['end'] = { + character = 9, + line = 117, + }, + start = { + character = 6, + line = 117, + }, + } + local location = { 118, 6 } + is_true(util.is_in_range(location, range)) + end) end)