-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpopup.lua
More file actions
104 lines (89 loc) · 3 KB
/
Copy pathpopup.lua
File metadata and controls
104 lines (89 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
local buffer = require("peekstack.core.popup.buffer")
local origin = require("peekstack.core.popup.origin")
local window = require("peekstack.core.popup.window")
local diagnostics_ui = require("peekstack.ui.diagnostics")
local keymaps = require("peekstack.ui.keymaps")
local viewport_ui = require("peekstack.ui.viewport")
local M = {}
---@type integer
local next_id = 1
---@param location PeekstackLocation
---@param opts? { buffer_mode?: "copy"|"source", title?: string|PeekstackTitleChunk[], editable?: boolean, ephemeral?: boolean, origin_winid?: integer, parent_popup_id?: integer }
---@return PeekstackPopupModel?
function M.create(location, opts)
opts = opts or {}
local captured_origin = origin.capture(opts.origin_winid)
local prepared = buffer.prepare(location, opts)
if not prepared then
return nil
end
opts.buffer_mode = prepared.buffer_mode
local opened = window.open(prepared.bufnr, location, opts, prepared.line_offset)
if not opened then
if prepared.buffer_mode ~= "source" and vim.api.nvim_buf_is_valid(prepared.bufnr) then
pcall(vim.api.nvim_buf_delete, prepared.bufnr, { force = true })
end
return nil
end
local id = opts.id or next_id
if not opts.id then
next_id = next_id + 1
end
local popup = {
id = id,
bufnr = prepared.bufnr,
source_bufnr = prepared.source_bufnr,
winid = opened.winid,
location = location,
origin = {
winid = captured_origin.winid,
bufnr = captured_origin.bufnr,
row = captured_origin.row,
col = captured_origin.col,
},
origin_bufnr = captured_origin.bufnr,
origin_is_popup = origin.is_popup_origin(captured_origin),
parent_popup_id = opts.parent_popup_id,
title = opened.title,
title_chunks = opened.title_chunks,
pinned = false,
buffer_mode = prepared.buffer_mode,
line_offset = prepared.line_offset,
viewport = prepared.viewport,
created_at = os.time(),
last_active_at = vim.uv.now(),
ephemeral = opts.ephemeral or false,
win_opts = opened.win_opts,
}
keymaps.apply_popup(popup)
vim.b[prepared.bufnr].peekstack_popup_id = id
vim.w[opened.winid].peekstack_popup_id = id
popup.diagnostics = diagnostics_ui.decorate(popup)
popup.viewport_marks = viewport_ui.decorate(popup)
return popup
end
---@param popup PeekstackPopupModel
---@return boolean
function M.focus(popup)
if popup.winid and vim.api.nvim_win_is_valid(popup.winid) then
vim.api.nvim_set_current_win(popup.winid)
return true
end
return false
end
---@param popup PeekstackPopupModel
function M.close(popup)
-- Remove source-mode keymaps before closing the window so they do not
-- leak into normal editing of the shared buffer.
require("peekstack.ui.keymaps").remove_popup(popup)
diagnostics_ui.clear(popup.diagnostics)
viewport_ui.clear(popup.viewport_marks)
if popup.winid and vim.api.nvim_win_is_valid(popup.winid) then
vim.api.nvim_win_close(popup.winid, true)
end
end
--- Reset next_id (for testing).
function M._reset()
next_id = 1
end
return M