Skip to content

Commit ab27128

Browse files
committed
cmdline-mode completion mvp
1 parent 83f7195 commit ab27128

3 files changed

Lines changed: 63 additions & 8 deletions

File tree

lua/fzf-lua/actions.lua

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,14 +1243,19 @@ end
12431243
---@param selected string[]
12441244
---@param opts fzf-lua.config.Resolved
12451245
M.complete = function(selected, opts)
1246+
local mode = opts.__CTX.mode
1247+
local cursor = opts.__CTX.cursor
12461248
if not selected[1] then
1247-
if opts.__CTX.mode == "i" then
1249+
if mode == "i" then
12481250
vim.cmd [[noautocmd lua vim.api.nvim_feedkeys('i', 'n', true)]]
1251+
elseif mode == "c" then
1252+
vim.cmd [[noautocmd lua vim.api.nvim_feedkeys(':', 'n', true)]]
1253+
require("fzf-lua.ctx").set_cursor(mode, cursor)
12491254
end
12501255
return
12511256
end
12521257
-- cusror col is 0-based
1253-
local col = opts.__CTX.cursor[2] + 1
1258+
local col = cursor[2] + 1
12541259
local newline, newcol
12551260
if type(opts.complete) == "function" then
12561261
newline, newcol = opts.complete(selected, opts, opts.__CTX.line, col)
@@ -1260,10 +1265,21 @@ M.complete = function(selected, opts)
12601265
newline = line:sub(1, col) .. selected[1] .. after
12611266
newcol = col + #selected[1]
12621267
end
1263-
vim.api.nvim_set_current_line(newline or opts.__CTX.line)
1264-
vim.api.nvim_win_set_cursor(0, { opts.__CTX.cursor[1], newcol or col })
1265-
if opts.__CTX.mode == "i" then
1268+
if mode ~= "c" then
1269+
vim.api.nvim_set_current_line(newline or opts.__CTX.line)
1270+
vim.api.nvim_win_set_cursor(0, { cursor[1], newcol or col })
1271+
end
1272+
if mode == "i" then
12661273
vim.cmd [[noautocmd lua vim.api.nvim_feedkeys('a', 'n', true)]]
1274+
elseif mode == "c" then
1275+
vim.api.nvim_create_autocmd("CmdlineEnter", {
1276+
once = true,
1277+
callback = function()
1278+
vim.fn.setcmdline(newline or opts.__CTX.line)
1279+
require("fzf-lua.ctx").set_cursor(mode, { cursor[1], cursor[2] + (newcol or col) - col })
1280+
end
1281+
})
1282+
vim.cmd [[noautocmd lua vim.api.nvim_feedkeys(':', 'n', true)]]
12671283
end
12681284
end
12691285

lua/fzf-lua/core.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ M.fzf = function(contents, opts)
365365
opts.fzf_opts["--preview-window"] = "hidden:right:0"
366366
end
367367

368+
if opts.__CTX.mode == "c" then vim.api.nvim_feedkeys(vim.keycode("<c-c>"), "n", false) end
368369
-- Create the window before we calculate the preview window layout
369370
local fzf_bufnr = fzf_win:create()
370371

lua/fzf-lua/ctx.lua

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,18 @@ M.refresh = function(opts)
4747
-- not to resume or a different picker, i.e. hide files and open buffers
4848
or winobj and winobj:hidden()
4949
then
50+
local mode = vim.api.nvim_get_mode().mode
5051
ctx = {
51-
mode = vim.api.nvim_get_mode().mode,
52+
mode = mode,
5253
bufnr = vim.api.nvim_get_current_buf(),
5354
bname = vim.api.nvim_buf_get_name(0),
5455
winid = vim.api.nvim_get_current_win(),
5556
last_winid = vim.fn.win_getid(vim.fn.winnr("#")),
5657
alt_bufnr = vim.fn.bufnr("#"),
5758
tabnr = vim.fn.tabpagenr(),
5859
tabh = vim.api.nvim_win_get_tabpage(0),
59-
cursor = vim.api.nvim_win_get_cursor(0),
60-
line = vim.api.nvim_get_current_line(),
60+
cursor = M.get_cursor(mode),
61+
line = M.get_line(mode),
6162
curtab_wins = (function()
6263
local ret = {}
6364
local wins = vim.api.nvim_tabpage_list_wins(0)
@@ -120,4 +121,41 @@ M.set_info = function(x)
120121
info = x
121122
end
122123

124+
-- modified from blink.cmp
125+
function M.get_mode(mode)
126+
mode = mode or vim.api.nvim_get_mode().mode
127+
return (mode == "c" and "cmdline")
128+
or (mode == "t" and "term")
129+
or (vim.fn.getcmdwintype() ~= "" and "cmdwin")
130+
or "default"
131+
end
132+
133+
function M.get_cursor(mode)
134+
mode = M.get_mode(mode)
135+
return mode == "cmdline" and { 1, vim.fn.getcmdpos() - 1 } or vim.api.nvim_win_get_cursor(0)
136+
end
137+
138+
function M.set_cursor(mode, cursor)
139+
mode = M.get_mode(mode)
140+
if vim.tbl_contains({ "default", "term", "cmdwin" }, mode) then
141+
return vim.api.nvim_win_set_cursor(0, cursor)
142+
end
143+
144+
assert(mode == "cmdline", "Unsupported mode for setting cursor: " .. mode)
145+
assert(cursor[1] == 1, "Cursor must be on the first line in cmdline mode")
146+
vim.fn.setcmdpos(cursor[2])
147+
end
148+
149+
function M.get_line(mode, num)
150+
if M.get_mode(mode) == "cmdline" then
151+
assert(num == nil or num == 0,
152+
"Cannot get line number " .. tostring(num) .. " in cmdline mode. Only 0 is supported")
153+
return vim.fn.getcmdline()
154+
end
155+
156+
-- This method works for normal buffers and the terminal prompt
157+
if num == nil then num = M.get_cursor()[1] - 1 end
158+
return vim.api.nvim_buf_get_lines(0, num, num + 1, false)[1]
159+
end
160+
123161
return M

0 commit comments

Comments
 (0)