Skip to content

Commit f7fee2e

Browse files
committed
feat(cli): fork when not connected to tty
This makes it so ctrl-q works from within zsh ZLE widgets
1 parent 3f04831 commit f7fee2e

1 file changed

Lines changed: 39 additions & 6 deletions

File tree

lua/fzf-lua/profiles/cli.lua

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ pcall(function()
1515
int execl(const char *, const char *, ...);
1616
int close(int fd);
1717
int openpty(int *amaster, int *aslave, char *name, void *termp, const struct winsize *winp);
18+
int fork(void);
19+
int isatty(int fd);
20+
int fileno(void *stream);
1821
]]
1922
end)
2023

@@ -28,9 +31,32 @@ local function parse_entries(s, o)
2831
end, s)
2932
end
3033

34+
local function isatty(file)
35+
if not ffi then return false end
36+
local fd = ffi.C.fileno(file)
37+
return ffi.C.isatty(fd) ~= 0
38+
end
39+
40+
local function fork(cmd, ...)
41+
if not ffi then return false end
42+
local pid = ffi.C.fork()
43+
if pid < 0 then return end -- fork failed
44+
if pid > 0 then return end -- parent process, do nothing
45+
-- pid == 0, child process, build the shell command
46+
-- tiny delay to let parent (fzf-lua) exit
47+
-- then exec nvim conneced to /dev/tty
48+
local shell_cmd = string.format(
49+
"sleep 0.05; %s %s </dev/tty >/dev/tty 2>/dev/tty", cmd,
50+
table.concat(vim.tbl_map(function(x) return FzfLua.libuv.shellescape(x) end, { ... }), " ")
51+
)
52+
os.execute(shell_cmd)
53+
os.exit(0)
54+
end
55+
3156
local function posix_exec(cmd, ...)
3257
local _is_win = fn.has("win32") == 1 or fn.has("win64") == 1
3358
if type(cmd) ~= "string" or _is_win or not ffi then return end
59+
if not isatty(io.stdout) then return fork(cmd, ...) end
3460
local args = { ... }
3561
-- NOTE: must add NULL to mark end of the vararg
3662
table.insert(args, string.byte("\0"))
@@ -142,13 +168,20 @@ return {
142168
entries[1].line and ("+" .. entries[1].line) or nil,
143169
entries[1].col and ("+norm! %s|"):format(entries[1].col) or nil)
144170
elseif ffi and #entries > 1 then
145-
local file = fn.tempname()
146-
fn.writefile(vim.tbl_map(function(e) -- Format: {filename}:{lnum}:{col}: {text}
171+
local qf_items = {}
172+
for _, e in ipairs(entries) do
147173
local text = e.stripped:match(":%d+:%d?%d?%d?%d?:?(.*)$") or ""
148-
return ("%s:%d:%d: %s"):format(e.path, e.line or 1, e.col or 1, text)
149-
end, entries), file)
150-
posix_exec(fn.exepath("nvim"), "--cmd",
151-
("set nohidden | cfile %s | set hidden&"):format(file))
174+
table.insert(qf_items, {
175+
filename = e.path,
176+
lnum = math.max(1, e.line or 1),
177+
col = math.max(1, e.col or 1),
178+
text = text,
179+
})
180+
end
181+
local qf_str = vim.inspect(qf_items):gsub("\n%s*", " ")
182+
posix_exec(fn.exepath("nvim"), "-c", string.format(
183+
"lua vim.o.hidden=false; vim.fn.setqflist(%s); vim.cmd('cfirst | set hidden&')",
184+
qf_str))
152185
end
153186
quit()
154187
end,

0 commit comments

Comments
 (0)