forked from neovim/neovim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.lua
More file actions
130 lines (115 loc) · 3.96 KB
/
util.lua
File metadata and controls
130 lines (115 loc) · 3.96 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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
-- Nursery for random things that may later find their way into stdlib if they mature.
local M = {}
--- Adds one or more blank lines above or below the cursor.
-- TODO: move to _core/defaults.lua once it is possible to assign a Lua function to options #25672
--- @param above? boolean Place blank line(s) above the cursor
local function add_blank(above)
local offset = above and 1 or 0
local repeated = vim.fn['repeat']({ '' }, vim.v.count1)
local linenr = vim.api.nvim_win_get_cursor(0)[1]
vim.api.nvim_buf_set_lines(0, linenr - offset, linenr - offset, true, repeated)
end
-- TODO: move to _core/defaults.lua once it is possible to assign a Lua function to options #25672
function M.space_above()
add_blank(true)
end
-- TODO: move to _core/defaults.lua once it is possible to assign a Lua function to options #25672
function M.space_below()
add_blank()
end
--- Gets a buffer by name
--- @param name string
--- @return integer?
function M.get_buf_by_name(name)
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_get_name(buf) == name then
return buf
end
end
end
--- Edit a file in a specific window
--- @param winnr number
--- @param file string
--- @return number buffer number of the edited buffer
M.edit_in = function(winnr, file)
local function resolved_path(path)
if not path or path == '' then
return ''
end
return vim.fn.resolve(vim.fs.abspath(path))
end
return vim.api.nvim_win_call(winnr, function()
local current_buf = vim.api.nvim_win_get_buf(winnr)
local current = resolved_path(vim.api.nvim_buf_get_name(current_buf))
-- Check if the current buffer is already the target file
if current == resolved_path(file) then
return current_buf
end
-- Read the file into the buffer
vim.cmd.edit(vim.fn.fnameescape(file))
return vim.api.nvim_get_current_buf()
end)
end
--- :edit, but it respects commands like :hor, :vert, :tab, etc.
--- @param file string
--- @param mods_str string
function M.wrapped_edit(file, mods_str)
local cmdline = table.concat({ mods_str, 'edit' }, ' ')
local mods = vim.api.nvim_parse_cmd(cmdline, {}).mods
--- @diagnostic disable-next-line: need-check-nil
if mods.tab > 0 or mods.split ~= '' or mods.horizontal or mods.vertical then
local buf = M.get_buf_by_name(file)
if buf == nil then
buf = vim.api.nvim_create_buf(true, false)
end
vim.cmd.sbuffer { buf, mods = mods }
end
vim.cmd.edit { file }
end
--- Read a chunk of data from a file
--- @param file string
--- @param size number
--- @return string? chunk or nil on error
function M.read_chunk(file, size)
local fd = io.open(file, 'rb')
if not fd then
return nil
end
local chunk = fd:read(size)
fd:close()
return tostring(chunk)
end
--- Check if a range in a buffer is inside a Lua codeblock via treesitter injection.
--- Used by :source to detect Lua code in non-Lua files (e.g., vimdoc).
--- @param bufnr integer Buffer number
--- @param line1 integer Start line (1-indexed)
--- @param line2 integer End line (1-indexed)
--- @return boolean True if the range is in a Lua injection
function M.source_is_lua(bufnr, line1, line2)
local parser = vim.treesitter.get_parser(bufnr)
if not parser then
return false
end
-- Parse from buffer start through one line past line2 to include injection closing markers
local range = { line1 - 1, 0, line2 - 1, -1 }
parser:parse({ 0, 0, line2, -1 })
local lang_tree = parser:language_for_range(range)
return lang_tree:lang() == 'lua'
end
--- Returns the exit code string for the current buffer, given:
--- - Channel is attached to the current buffer
--- - Current buffer is a terminal buffer
---
--- @return string
function M.term_exitcode()
local chan_id = vim.bo.channel
if chan_id == 0 or vim.bo.buftype ~= 'terminal' then
return ''
end
local info = vim.api.nvim_get_chan_info(chan_id)
if info.exitcode and info.exitcode >= 0 then
return string.format('[Exit: %d]', info.exitcode)
end
return ''
end
return M