Skip to content

Commit

Permalink
fix: check valid buffer when scheduling
Browse files Browse the repository at this point in the history
  • Loading branch information
lewis6991 committed Aug 17, 2023
1 parent 55f8fc7 commit dbc56f3
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 65 deletions.
36 changes: 17 additions & 19 deletions lua/gitsigns/actions.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
local void = require('gitsigns.async').void
local scheduler = require('gitsigns.async').scheduler

local async = require('gitsigns.async')
local config = require('gitsigns.config').config
local mk_repeatable = require('gitsigns.repeat').mk_repeatable
local popup = require('gitsigns.popup')
Expand Down Expand Up @@ -167,7 +165,7 @@ end
--- @param bufnr integer
local function update(bufnr)
manager.update(bufnr)
scheduler()
async.scheduler_if_buf_valid(bufnr)
if vim.wo.diff then
require('gitsigns.diffthis').update(bufnr)
end
Expand Down Expand Up @@ -202,7 +200,7 @@ local function get_hunks(bufnr, bcache, greedy, staged)
return
end
hunks = run_diff(text, buftext, false)
scheduler()
async.scheduler()
return hunks
end

Expand Down Expand Up @@ -255,7 +253,7 @@ end
--- • {greedy}: (boolean)
--- Stage all contiguous hunks. Only useful if 'diff_opts'
--- contains `linematch`. Defaults to `true`.
M.stage_hunk = mk_repeatable(void(function(range, opts)
M.stage_hunk = mk_repeatable(async.void(function(range, opts)
opts = opts or {}
local bufnr = current_buf()
local bcache = cache[bufnr]
Expand Down Expand Up @@ -306,7 +304,7 @@ end
--- • {greedy}: (boolean)
--- Stage all contiguous hunks. Only useful if 'diff_opts'
--- contains `linematch`. Defaults to `true`.
M.reset_hunk = mk_repeatable(void(function(range, opts)
M.reset_hunk = mk_repeatable(async.void(function(range, opts)
opts = opts or {}
local bufnr = current_buf()
local bcache = cache[bufnr]
Expand Down Expand Up @@ -353,7 +351,7 @@ end
---
--- Attributes: ~
--- {async}
M.undo_stage_hunk = void(function()
M.undo_stage_hunk = async.void(function()
local bufnr = current_buf()
local bcache = cache[bufnr]
if not bcache then
Expand All @@ -375,7 +373,7 @@ end)
---
--- Attributes: ~
--- {async}
M.stage_buffer = void(function()
M.stage_buffer = async.void(function()
local bufnr = current_buf()

local bcache = cache[bufnr]
Expand Down Expand Up @@ -411,7 +409,7 @@ end)
---
--- Attributes: ~
--- {async}
M.reset_buffer_index = void(function()
M.reset_buffer_index = async.void(function()
local bufnr = current_buf()
local bcache = cache[bufnr]
if not bcache then
Expand Down Expand Up @@ -490,7 +488,7 @@ end

--- @param opts? Gitsigns.NavOpts
--- @param forwards boolean
local nav_hunk = void(function(opts, forwards)
local nav_hunk = async.void(function(opts, forwards)
opts = process_nav_opts(opts)
local bufnr = current_buf()
local bcache = cache[bufnr]
Expand Down Expand Up @@ -859,7 +857,7 @@ end
--- Display full commit message with hunk.
--- • {ignore_whitespace}: (boolean)
--- Ignore whitespace when running blame.
M.blame_line = void(function(opts)
M.blame_line = async.void(function(opts)
if popup.focus_open('blame') then
return
end
Expand All @@ -876,7 +874,7 @@ M.blame_line = void(function(opts)
popup.create({ { { 'Loading...', 'Title' } } }, config.preview_config)
end, 1000)

scheduler()
async.scheduler_if_buf_valid()
local buftext = util.buf_lines(bufnr)
local fileformat = vim.bo[bufnr].fileformat
local lnum = api.nvim_win_get_cursor(0)[1]
Expand Down Expand Up @@ -905,7 +903,7 @@ M.blame_line = void(function(opts)
insert_hunk_hlmarks(blame_fmt, hunk)
end

scheduler()
async.scheduler_if_buf_valid(bufnr)

popup.create(lines_format(blame_fmt, result), config.preview_config, 'blame')
end)
Expand Down Expand Up @@ -948,7 +946,7 @@ end
---
--- @param base string|nil The object/revision to diff against.
--- @param global boolean|nil Change the base of all buffers.
M.change_base = void(function(base, global)
M.change_base = async.void(function(base, global)
base = util.calc_base(base)

if global then
Expand Down Expand Up @@ -1134,7 +1132,7 @@ local function buildqflist(target)
local stat = vim.loop.fs_stat(f_abs)
if stat and stat.type == 'file' then
local a = r:get_show_text(':0:' .. f)
scheduler()
async.scheduler()
local hunks = run_diff(a, util.file_lines(f_abs))
hunks_to_qflist(f_abs, hunks, qflist)
end
Expand Down Expand Up @@ -1170,7 +1168,7 @@ end
--- • {open}: (boolean)
--- Open the quickfix/location list viewer.
--- Defaults to `true`.
M.setqflist = void(function(target, opts)
M.setqflist = async.void(function(target, opts)
opts = opts or {}
if opts.open == nil then
opts.open = true
Expand All @@ -1179,7 +1177,7 @@ M.setqflist = void(function(target, opts)
items = buildqflist(target),
title = 'Hunks',
}
scheduler()
async.scheduler()
if opts.use_location_list then
local nr = opts.nr or 0
vim.fn.setloclist(nr, {}, ' ', qfopts)
Expand Down Expand Up @@ -1263,7 +1261,7 @@ end
---
--- Attributes: ~
--- {async}
M.refresh = void(function()
M.refresh = async.void(function()
manager.reset_signs()
require('gitsigns.highlight').setup_highlights()
require('gitsigns.current_line_blame').setup()
Expand Down
9 changes: 9 additions & 0 deletions lua/gitsigns/async.lua
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,13 @@ end
---able to call the API.
M.scheduler = M.wrap(vim.schedule, 1)

--- @param buf? integer
M.scheduler_if_buf_valid = M.wrap(function(buf, cb)
vim.schedule(function()
if not buf or vim.api.nvim_buf_is_valid(buf) then
cb()
end
end)
end, 2)

return M
6 changes: 3 additions & 3 deletions lua/gitsigns/attach.lua
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ local attach_throttled = throttle_by_id(function(cbuf, ctx, aucmd)

if not git_obj and not ctx then
git_obj = try_worktrees(cbuf, file, encoding)
async.scheduler()
async.scheduler_if_buf_valid(cbuf)
end

if not git_obj then
Expand All @@ -300,7 +300,7 @@ local attach_throttled = throttle_by_id(function(cbuf, ctx, aucmd)
end
local repo = git_obj.repo

async.scheduler()
async.scheduler_if_buf_valid(cbuf)
Status:update(cbuf, {
head = repo.abbrev_head,
root = repo.toplevel,
Expand Down Expand Up @@ -329,7 +329,7 @@ local attach_throttled = throttle_by_id(function(cbuf, ctx, aucmd)

-- On windows os.tmpname() crashes in callback threads so initialise this
-- variable on the main thread.
async.scheduler()
async.scheduler_if_buf_valid(cbuf)

if config.on_attach and config.on_attach(cbuf) == false then
dprint('User on_attach() returned false')
Expand Down
19 changes: 5 additions & 14 deletions lua/gitsigns/current_line_blame.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
local a = require('gitsigns.async')
local wrap = a.wrap
local void = a.void
local scheduler = a.scheduler

local async = require('gitsigns.async')
local cache = require('gitsigns.cache').cache
local config = require('gitsigns.config').config
local util = require('gitsigns.util')
Expand All @@ -18,7 +14,7 @@ local timer = assert(uv.new_timer())

local M = {}

local wait_timer = wrap(uv.timer_start, 4)
local wait_timer = async.wrap(uv.timer_start, 4)

--- @param bufnr integer
--- @param row integer
Expand Down Expand Up @@ -218,15 +214,15 @@ local function update0()

-- Note because the same timer is re-used, this call has a debouncing effect.
wait_timer(timer, opts.delay, 0)
scheduler()
async.scheduler()

local bcache = cache[bufnr]
if not bcache or not bcache.git_obj.object_name then
return
end

local blame_info = run_blame(bufnr, lnum, opts)
scheduler()
async.scheduler_if_buf_valid(bufnr)

local lnum1 = get_lnum()
if bufnr == current_buf() and lnum ~= lnum1 then
Expand All @@ -236,19 +232,14 @@ local function update0()
return
end

if not api.nvim_buf_is_loaded(bufnr) then
-- Buffer is no longer loaded; abort
return
end

vim.b[bufnr].gitsigns_blame_line_dict = blame_info

if blame_info then
handle_blame_info(bufnr, lnum, blame_info, opts)
end
end

local update = void(update0)
local update = async.void(update0)

function M.setup()
local group = api.nvim_create_augroup('gitsigns_blame', {})
Expand Down
23 changes: 10 additions & 13 deletions lua/gitsigns/diffthis.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
local api = vim.api

local void = require('gitsigns.async').void
local scheduler = require('gitsigns.async').scheduler
local awrap = require('gitsigns.async').wrap

local async = require('gitsigns.async')
local gs_cache = require('gitsigns.cache')
local cache = gs_cache.cache

Expand All @@ -14,14 +11,14 @@ local message = require('gitsigns.message')
local throttle_by_id = require('gitsigns.debounce').throttle_by_id

--- @type fun(opts: table): string
local input = awrap(vim.ui.input, 2)
local input = async.awrap(vim.ui.input, 2)

local M = {}

--- @param bufnr integer
--- @param dbufnr integer
--- @param base string
local bufread = void(function(bufnr, dbufnr, base)
local bufread = async.void(function(bufnr, dbufnr, base)
local bcache = cache[bufnr]
local comp_rev = bcache:get_compare_rev(util.calc_base(base))
local text --- @type string[]
Expand All @@ -33,7 +30,7 @@ local bufread = void(function(bufnr, dbufnr, base)
if err then
error(err, 2)
end
scheduler()
async.scheduler_if_buf_valid(bufnr)
if vim.bo[bufnr].fileformat == 'dos' then
text = util.strip_cr(text)
end
Expand All @@ -52,11 +49,11 @@ end)
--- @param bufnr integer
--- @param dbufnr integer
--- @param base string
local bufwrite = void(function(bufnr, dbufnr, base)
local bufwrite = async.void(function(bufnr, dbufnr, base)
local bcache = cache[bufnr]
local buftext = util.buf_lines(dbufnr)
bcache.git_obj:stage_lines(buftext)
scheduler()
async.scheduler_if_buf_valid(bufnr)
vim.bo[dbufnr].modified = false
-- If diff buffer base matches the bcache base then also update the
-- signs.
Expand Down Expand Up @@ -86,7 +83,7 @@ local function create_show_buf(bufnr, base)
local ok, err = pcall(bufread, bufnr, dbuf, base)
if not ok then
message.error(err --[[@as string]])
scheduler()
async.scheduler()
api.nvim_buf_delete(dbuf, { force = true })
return
end
Expand Down Expand Up @@ -145,7 +142,7 @@ end

--- @param base string
--- @param opts Gitsigns.DiffthisOpts
M.diffthis = void(function(base, opts)
M.diffthis = async.void(function(base, opts)
if vim.wo.diff then
return
end
Expand All @@ -169,7 +166,7 @@ M.diffthis = void(function(base, opts)
end)

--- @param base string
M.show = void(function(base)
M.show = async.void(function(base)
local bufnr = api.nvim_get_current_buf()
local bufname = create_show_buf(bufnr, base)
if not bufname then
Expand All @@ -196,7 +193,7 @@ end

-- This function needs to be throttled as there is a call to vim.ui.input
--- @param bufnr integer
M.update = throttle_by_id(void(function(bufnr)
M.update = throttle_by_id(async.void(function(bufnr)
if not vim.wo.diff then
return
end
Expand Down
19 changes: 5 additions & 14 deletions lua/gitsigns/manager.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
local void = require('gitsigns.async').void
local awrap = require('gitsigns.async').wrap
local async = require('gitsigns.async')

local gs_cache = require('gitsigns.cache')
local cache = gs_cache.cache
Expand Down Expand Up @@ -30,14 +29,6 @@ local signs_staged --- @type Gitsigns.Signs

local M = {}

local scheduler_if_buf_valid = awrap(function(buf, cb)
vim.schedule(function()
if vim.api.nvim_buf_is_valid(buf) then
cb()
end
end)
end, 2)

--- @param bufnr integer
--- @param signs Gitsigns.Signs
--- @param hunks Gitsigns.Hunk.Hunk[]
Expand Down Expand Up @@ -421,13 +412,13 @@ M.update = throttle_by_id(function(bufnr, bcache)
local old_hunks, old_hunks_staged = bcache.hunks, bcache.hunks_staged
bcache.hunks, bcache.hunks_staged = nil, nil

scheduler_if_buf_valid(bufnr)
async.scheduler_if_buf_valid(bufnr)
local buftext = util.buf_lines(bufnr)
local git_obj = bcache.git_obj

if not bcache.compare_text or config._refresh_staged_on_update then
bcache.compare_text = git_obj:get_show_text(bcache:get_compare_rev())
scheduler_if_buf_valid(bufnr)
async.scheduler_if_buf_valid(bufnr)
end

bcache.hunks = run_diff(bcache.compare_text, buftext)
Expand All @@ -440,7 +431,7 @@ M.update = throttle_by_id(function(bufnr, bcache)
bcache.hunks_staged = gs_hunks.filter_common(hunks_head, bcache.hunks)
end

scheduler_if_buf_valid(bufnr)
async.scheduler_if_buf_valid(bufnr)

-- Note the decoration provider may have invalidated bcache.hunks at this
-- point
Expand Down Expand Up @@ -536,7 +527,7 @@ function M.setup()
signs_staged = Signs.new(config._signs_staged, 'staged')
end

M.update_debounced = debounce_trailing(config.update_debounce, void(M.update))
M.update_debounced = debounce_trailing(config.update_debounce, async.void(M.update))
end

return M
Loading

0 comments on commit dbc56f3

Please sign in to comment.