@@ -8,22 +8,18 @@ local make_entry = require "fzf-lua.make_entry"
88local M = {}
99
1010--- @param opts fzf-lua.config.Oldfiles |{}?
11+ --- @param globals string | (fzf-lua.Config |{} )?
1112--- @return thread ?, string ?, table ?
12- M .oldfiles = function (opts )
13+ M .oldfiles = function (opts , globals )
1314 --- @type fzf-lua.config.Oldfiles
14- opts = config .normalize_opts (opts , " oldfiles" )
15+ opts = config .normalize_opts (opts , globals or " oldfiles" )
1516 if not opts then return end
1617
1718 -- cwd implies we want `cwd_only=true`
1819 if opts .cwd and opts .cwd_only == nil then
1920 opts .cwd_only = true
2021 end
2122
22- local current_buffer = vim .api .nvim_get_current_buf ()
23- local current_file = vim .api .nvim_buf_get_name (current_buffer )
24- local sess_tbl = {}
25- local sess_map = {}
26-
2723 local stat_fn = not opts .stat_file and function (_ ) return true end
2824 or type (opts .stat_file ) == " function" and opts .stat_file
2925 or function (file )
@@ -34,47 +30,79 @@ M.oldfiles = function(opts)
3430 and utils .file_is_readable (file ))
3531 end
3632
37- if opts .include_current_session then
38- for _ , buffer in ipairs (vim .split (vim .fn .execute (" :buffers! t" ), " \n " )) do
39- local bufnr = utils .tointeger (buffer :match (" %s*(%d+)" ))
40- if bufnr then
33+ local sorted_named_buffers = function ()
34+ local bufnrs = {}
35+ for i , buffer in ipairs (vim .split (vim .fn .execute (" :buffers! t" ), " \n " )) do
36+ if i > 1 then -- line[1] == "\n"
37+ local bufnr = assert (utils .tointeger (buffer :match (" %s*(%d+)" )))
4138 local file = vim .api .nvim_buf_get_name (bufnr )
42- local fs_stat = stat_fn (file )
43- if # file > 0 and fs_stat and bufnr ~= current_buffer then
44- sess_map [file ] = true
45- table.insert (sess_tbl , file )
39+ local fs_stat = # file > 0 and stat_fn (file )
40+ if fs_stat then
41+ table.insert (bufnrs , { bufnr = bufnr , file = file , curbuf = bufnr == utils .CTX ().bufnr })
4642 end
4743 end
4844 end
45+ return bufnrs
4946 end
5047
51- local contents = function (cb )
52- local function add_entry (x , co )
53- x = make_entry .file (x , opts )
54- if not x then return end
55- cb (x , function (err )
56- coroutine.resume (co )
57- if err then
58- -- close the pipe to fzf, this
59- -- removes the loading indicator in fzf
60- cb (nil )
61- end
62- end )
63- coroutine.yield ()
48+ -- current buffer as a header line
49+ -- since we exclude unnamed/terminal/non-existent files
50+ -- only set header line if first entry matches current buffer
51+ local header_line = function ()
52+ if opts .include_current_session and not opts .ignore_current_buffer then
53+ local buflist = sorted_named_buffers ()
54+ if buflist [1 ] and buflist [1 ].bufnr == utils .CTX ().bufnr then
55+ return true
56+ end
6457 end
58+ end
59+
60+ if header_line () then utils .map_set (opts , " fzf_opts.--header-lines" , 1 ) end
61+
62+ -- NOTE: fzf does not yet support "change-header-lines" transform
63+ -- https://github.com/junegunn/fzf/issues/4659
64+ -- opts._resume_reload = function()
65+ -- return string.format("change-header-lines(%d)", header_line() and 1 or 0)
66+ -- end
6567
68+ local contents = function (cb )
6669 -- run in a coroutine for async progress indication
6770 coroutine.wrap (function ()
6871 local co = coroutine.running ()
6972
70- for _ , file in ipairs (sess_tbl ) do
71- add_entry (file , co )
73+ local curr_buf = utils .CTX ().bufnr
74+ local curr_file = vim .api .nvim_buf_get_name (curr_buf )
75+ local sess_map = {} -- dedup files from current buffers
76+
77+ local function add_entry (x , co , force )
78+ x = make_entry .file (x ,
79+ force and vim .tbl_deep_extend (" force" , {}, opts , { cwd_only = false }) or opts )
80+ if not x then return end
81+ cb (x , function (err )
82+ coroutine.resume (co )
83+ if err then
84+ -- close the pipe to fzf, this
85+ -- removes the loading indicator in fzf
86+ cb (nil )
87+ end
88+ end )
89+ coroutine.yield ()
90+ end
91+
92+ if opts .include_current_session then
93+ for _ , buf in ipairs (sorted_named_buffers ()) do
94+ if not opts .ignore_current_buffer or buf .bufnr ~= curr_buf then
95+ sess_map [buf .file ] = true
96+ -- 3rd arg forces addition of current buffer with cwd_only
97+ add_entry (buf .file , co , buf .curbuf )
98+ end
99+ end
72100 end
73101
74102 -- local start = os.time(); for _ = 1,10000,1 do
75103 for _ , file in ipairs (vim .v .oldfiles ) do
76104 local fs_stat = stat_fn (file )
77- if fs_stat and file ~= current_file and not sess_map [file ] then
105+ if fs_stat and file ~= curr_file and not sess_map [file ] then
78106 add_entry (file , co )
79107 end
80108 end
@@ -90,4 +118,10 @@ M.oldfiles = function(opts)
90118 return core .fzf_exec (contents , opts )
91119end
92120
121+ --- @param opts fzf-lua.config.History |{}?
122+ --- @return thread ?, string ?, table ?
123+ M .history = function (opts )
124+ return M .oldfiles (opts , " history" )
125+ end
126+
93127return M
0 commit comments