@@ -37,8 +37,7 @@ local Previewer = {}
3737--- @field winopts_orig table
3838--- @field extensions { [string] : string[] ? }
3939--- @field ueberzug_scaler " crop" | " distort" | " contain" | " fit_contain" | " cover" | " forced_cover"
40- --- @field cached_bufnrs table<integer , [integer , integer] | true ? > items are cached_pos
41- --- @field cached_buffers table<string , fzf-lua.buffer_or_file.Bcache ? >
40+ --- @field bcache fzf-lua.Bcache
4241--- @field listed_buffers table<integer , boolean ? >
4342--- @field clear_on_redraw boolean ?
4443--- @field timers ? table<string , uv.uv_timer_t ? >
@@ -88,9 +87,9 @@ function Previewer.base:new(o, opts)
8887 utils .warn ((" Invalid ueberzug image scaler '%s', option will be omitted." )
8988 :format (o .ueberzug_scaler ))
9089 end
91- -- cached buffers
92- self . cached_bufnrs = {}
93- self . cached_buffers = {}
90+ self . bcache = require ( " fzf-lua.previewer.bcache " ). new ( function ( buf )
91+ self : safe_buf_delete ( buf , true )
92+ end )
9493 -- store currently listed buffers, this helps us determine which buffers
9594 -- navigated with 'vim.lsp.util.show_document' we can safely unload
9695 -- since show_document reuses buffers and I couldn't find a better way
@@ -119,9 +118,7 @@ function Previewer.base:close(do_not_clear_cache)
119118 TSContext .deregister ()
120119 self :restore_winopts ()
121120 self :clear_preview_buf ()
122- if not do_not_clear_cache then
123- self :clear_cached_buffers ()
124- end
121+ if not do_not_clear_cache and self .bcache then self .bcache :clear () end
125122 self .winopts_orig = {}
126123end
127124
@@ -180,7 +177,7 @@ function Previewer.base:safe_buf_delete(bufnr, del_cached)
180177 elseif not api .nvim_buf_is_valid (bufnr ) then
181178 -- print("safe_buf_delete INVALID", bufnr)
182179 return
183- elseif not del_cached and self .cached_bufnrs [ bufnr ] then
180+ elseif not del_cached and self .bcache : get_pos ( bufnr ) then
184181 -- print("safe_buf_delete CACHED", bufnr)
185182 return
186183 end
@@ -225,15 +222,6 @@ function Previewer.base:set_preview_buf(newbuf, min_winopts, no_wipe)
225222 end
226223end
227224
228- function Previewer .base :clear_cached_buffers ()
229- -- clear the buffer cache
230- for _ , c in pairs (self .cached_buffers ) do
231- self :safe_buf_delete (c .bufnr , true )
232- end
233- self .cached_bufnrs = {}
234- self .cached_buffers = {}
235- end
236-
237225--- @param newbuf boolean ?
238226--- @return integer ?
239227function Previewer .base :clear_preview_buf (newbuf )
@@ -454,13 +442,8 @@ function Previewer.base:scroll(direction)
454442 -- Conditionally toggle 'cursorline' based on cursor position
455443 self :maybe_set_cursorline (preview_winid , self .orig_pos )
456444 -- HACK: Hijack cached bufnr value as last scroll position
457- if self .cached_bufnrs [self .preview_bufnr ] then
458- if direction == " reset" then
459- self .cached_bufnrs [self .preview_bufnr ] = true
460- else
461- self .cached_bufnrs [self .preview_bufnr ] = api .nvim_win_get_cursor (preview_winid )
462- end
463- end
445+ self .bcache :update_pos (self .preview_bufnr ,
446+ direction == " reset" or api .nvim_win_get_cursor (preview_winid ))
464447 self .win :update_preview_scrollbar ()
465448 self :update_render_markdown ()
466449 self :update_ts_context ()
@@ -726,56 +709,6 @@ function Previewer.buffer_or_file:populate_terminal_cmd(tmpbuf, cmd, entry)
726709 return true
727710end
728711
729- --- @diagnostic disable-next-line : unused
730- --- @param entry fzf-lua.buffer_or_file.Entry
731- --- @return string ?
732- local key_from_entry = function (entry )
733- if entry .do_not_cache then return nil end
734- return (entry .bufnr and string.format (" bufnr:%d" , entry .bufnr ) or entry .uri or entry .path ) or nil
735- end
736-
737- --- get and check if cached is update-to-date to be reuse
738- --- @param entry fzf-lua.buffer_or_file.Entry
739- --- @return fzf-lua.buffer_or_file.Bcache ?
740- function Previewer .buffer_or_file :check_bcache (entry )
741- local key = key_from_entry (entry )
742- if not key then return end
743- local cached = self .cached_buffers [key ]
744- if not cached then return end
745- entry .cached = cached
746- assert (self .cached_bufnrs [cached .bufnr ])
747- assert (api .nvim_buf_is_valid (cached .bufnr ))
748- if entry .tick ~= cached .tick then
749- cached .invalid = true
750- cached .tick = entry .tick
751- end
752- return cached
753- end
754-
755- --- cache the bufnr for the entry, evict previous cache if exists
756- --- @param bufnr integer
757- --- @param entry fzf-lua.buffer_or_file.Entry
758- --- @param min_winopts boolean ?
759- function Previewer .buffer_or_file :cache_buffer (bufnr , entry , min_winopts )
760- local key = key_from_entry (entry )
761- if not key then return end
762- local cached = self .cached_buffers [key ]
763- if cached then
764- if cached .bufnr == bufnr then
765- -- already cached, nothing to do
766- return cached
767- else
768- -- new cached buffer for key, wipe current cached buf
769- self .cached_bufnrs [cached .bufnr ] = nil
770- self :safe_buf_delete (cached .bufnr )
771- end
772- end
773- self .cached_bufnrs [bufnr ] = true -- reset scroll position
774- self .cached_buffers [key ] = { bufnr = bufnr , min_winopts = min_winopts , tick = entry .tick }
775- -- remove buffer auto-delete since it's now cached
776- vim .bo [bufnr ].bufhidden = " hide"
777- end
778-
779712--- @alias fzf-lua.line (string | [string,string] )[]
780713--- @param content (string | fzf-lua.line )[]
781714--- @return string[] , table
@@ -864,26 +797,28 @@ function Previewer.buffer_or_file:populate_preview_buf(entry_str)
864797 entry = entry or coroutine.yield ()
865798 if entry_str ~= self ._last_entry or not self .win :validate_preview () then return false end
866799 if utils .tbl_isempty (entry ) then return end
867- local cached = self :check_bcache (entry )
800+
801+ -- check if cached is update-to-date to be reuse
802+ local cached , stale = self .bcache :check (entry )
803+ entry .cached = cached
868804
869805 -- same file/buffer as previous entry no need to change preview buf
870- if cached and not cached .invalid and cached .bufnr == self .preview_bufnr then
871- if type (self .cached_bufnrs [self .preview_bufnr ]) == " table"
872- and ((entry .line and entry .line > 0 and entry .line ~= self .orig_pos [1 ])
873- or (entry .col and entry .col > 0 and entry .col - 1 ~= self .orig_pos [2 ])) then
874- -- entry is within the same buffer but line|col has changed
875- -- clear cached buffer position so we scroll to entry's line|col
876- self .cached_bufnrs [self .preview_bufnr ] = true
806+ -- (e.g. only lnum changed, or unhide/resume)
807+ if cached and not stale and cached .bufnr == self .preview_bufnr then
808+ local line = entry .line and entry .line > 0 and entry .line or nil
809+ local col = entry .col and entry .col > 0 and entry .col - 1 or nil
810+ if not vim .deep_equal ({ line , col }, self .orig_pos ) then
811+ self .bcache :reset_pos (self .preview_bufnr )
877812 end
878- self :preview_buf_post (entry )
813+ self :preview_buf_post (entry , cached . min_winopts )
879814 return
880815 end
881- if cached and not cached . invalid then
816+ if cached and not stale then
882817 self :set_preview_buf (cached .bufnr , cached .min_winopts )
883818 self :preview_buf_post (entry , cached .min_winopts )
884819 return
885820 end
886- local reuse_buf = (cached or {}).bufnr -- cached must be invalid now if exists
821+ local reuse_buf = (cached or {}).bufnr -- cached must be stale now if exists
887822 self .clear_on_redraw = false
888823 -- kill previously running terminal jobs
889824 -- when using external commands extension map
@@ -1281,7 +1216,7 @@ function Previewer.buffer_or_file:set_cursor_hl(entry)
12811216 --- @diagnostic disable-next-line : unnecessary-assert
12821217 local buf , win , hls = assert (self .preview_bufnr , self .win .preview_winid , self .win .hls )
12831218 pcall (api .nvim_win_call , win , function ()
1284- local cached_pos = self .cached_bufnrs [ buf ]
1219+ local cached_pos = self .bcache : get_pos ( buf )
12851220 if type (cached_pos ) ~= " table" then cached_pos = nil end
12861221 local lnum , col = entry .line , math.max (1 , entry .col or 1 )
12871222 if not lnum or lnum < 1 then
@@ -1397,7 +1332,7 @@ function Previewer.buffer_or_file:preview_buf_post(entry, min_winopts)
13971332
13981333 -- Should we cache the current preview buffer?
13991334 -- we cache only named buffers with valid path/uri
1400- self : cache_buffer ( self .preview_bufnr , entry , min_winopts )
1335+ self . bcache : set ( entry , self .preview_bufnr , min_winopts )
14011336end
14021337
14031338--- @class fzf-lua.previewer.HelpTags : fzf-lua.previewer.BufferOrFile , {}
0 commit comments