1- local M = {
1+ local M = {
22 { " default-title" }, -- base profile
33 desc = " UI at the bottom of the screen" ,
44 winopts = {
@@ -40,7 +40,7 @@ local M = {
4040 },
4141}
4242
43- local up = {
43+ local up = {
4444 row = 1 ,
4545 col = 0 ,
4646 width = 1 ,
@@ -52,10 +52,114 @@ local up = {
5252 },
5353}
5454
55- M .blines = { winopts = up , previewer = { toggle_behavior = " extend" } }
56- M .lines = M .blines
57- M .grep = M .blines
58- M .grep_curbuf = M .blines
59- M .git = { blame = { winopts = up } }
55+ --- Extract lnum, col from blines/git_blame entries
56+ --- @param sel string[]
57+ --- @param opts table
58+ --- @return integer ?, integer ?
59+ local parse_lnum_col = function (sel , opts )
60+ if not sel [1 ] then return end
61+ local lnum = sel [1 ]:match (" ^%w+ %(.-(%d+)%)" ) -- git_blame
62+ if tonumber (lnum ) then return tonumber (lnum ), 1 end
63+ local entry = FzfLua .path .entry_to_file (sel [1 ], opts )
64+ return entry .line , entry .col
65+ end
66+
67+ -- Credit to phanen@GitHub:
68+ -- https://github.com/ibhagwan/fzf-lua/issues/1754#issuecomment-2944053022
69+ local focused_win = {
70+ -- _treesitter = function(line) return "foo.lua", nil, line:sub(2) end,
71+ -- fzf_opts = { ["--nth"] = "1.." },
72+ fzf_args = " --pointer=" ,
73+ winopts = function ()
74+ local off = vim .o .cmdheight + (vim .o .laststatus and 1 or 0 )
75+ local height = math.ceil (vim .o .lines / 4 )
76+ local ns = vim .api .nvim_create_namespace (" fzf-lua.preview.swiper" )
77+ local buf = vim .api .nvim_get_current_buf ()
78+ local hl = function (start_row , start_col , end_row , end_col )
79+ assert (start_col >= 0 and end_col >= 0 , " start_col and end_col must be non-negative" )
80+ vim .hl .range (buf , ns , " IncSearch" , { start_row , start_col }, { end_row , end_col }, {})
81+ end
82+ local on_buf_change = function ()
83+ vim .api .nvim_buf_clear_namespace (buf , ns , 0 , - 1 )
84+ local lines = vim .o .lines
85+ local l_s = lines - height - off + 1
86+ local l_e = lines - off - 1
87+ local max_columns = vim .o .columns
88+ for r = l_s , l_e do
89+ local state = {}
90+ for c = 1 , max_columns do
91+ local ok , ret = pcall (vim .api .nvim__inspect_cell , 1 , r , c )
92+ if not ok or not ret [1 ] then break end
93+ (function ()
94+ if not state .lnum then -- parsing lnum
95+ local d = tonumber (ret [1 ])
96+ if not state .parsing_lnum and not d then return end
97+ if not state .parsing_lnum then
98+ state .parsing_lnum = d
99+ return
100+ end
101+ if d then
102+ state .parsing_lnum = state .parsing_lnum * 10 + d
103+ return
104+ end
105+ state .lnum , state .parsing_lnum = assert (state .parsing_lnum ), nil
106+ return
107+ end
108+ local in_matched = ret [2 ] and ret [2 ].reverse
109+ if in_matched and not state .in_matched then
110+ state .start_col = math.max (c - 8 , 0 )
111+ state .text = { ret [1 ] }
112+ state .in_matched = in_matched
113+ return
114+ end
115+ if in_matched then
116+ state .text [# state .text + 1 ] = ret [1 ]
117+ return
118+ end
119+ if state .in_matched then
120+ hl (state .lnum - 1 , state .start_col , state .lnum - 1 , c - 8 )
121+ state .in_matched = nil
122+ end
123+ end )()
124+ end
125+ end
126+ end
127+ return {
128+ preview = { hidden = true },
129+ split = (" botright %snew +set\\ nobl" ):format (height ),
130+ on_create = function (e )
131+ vim .api .nvim_create_autocmd (" TextChangedT" , { buffer = e .bufnr , callback = on_buf_change })
132+ end ,
133+ on_close = function ()
134+ vim .api .nvim_buf_clear_namespace (buf , ns , 0 , - 1 )
135+ vim .api .nvim_win_set_cursor (0 , FzfLua .utils .__CTX ().cursor )
136+ FzfLua .utils .zz ()
137+ end ,
138+ }
139+ end ,
140+ actions = {
141+ enter = function (sel , opts )
142+ local lnum , col = parse_lnum_col (sel , opts )
143+ pcall (vim .api .nvim_win_set_cursor , 0 , { lnum , col })
144+ end ,
145+ focus = {
146+ fn = function (sel , opts )
147+ local lnum , col = parse_lnum_col (sel , opts )
148+ if not lnum then return end
149+ local ctx = FzfLua .utils .CTX ()
150+ vim .wo [ctx .winid ].cursorline = true
151+ pcall (vim .api .nvim_win_set_cursor , ctx .winid , { lnum , col })
152+ end ,
153+ field_index = " {}" ,
154+ exec_silent = true ,
155+ },
156+ },
157+ }
158+
159+ M .blines = focused_win
160+ M .git = { blame = focused_win }
161+ M .lines = { winopts = up , previewer = { toggle_behavior = " extend" } }
162+ M .grep = { winopts = up , previewer = { toggle_behavior = " extend" } }
163+ M .grep_curbuf = { winopts = up , previewer = { toggle_behavior = " extend" } }
60164
61165return M
0 commit comments