@@ -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 ]]
1922end )
2023
@@ -28,9 +31,32 @@ local function parse_entries(s, o)
2831 end , s )
2932end
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+
3156local 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