vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
complete-filename.lua
(1613B)
1 local complete_filename = function(expand)
2 local win = vis.win
3 local file = win.file
4 local pos = win.selection.pos
5 if not pos then return end
6
7 -- TODO do something clever here
8 local range = file:text_object_longword(pos > 0 and pos-1 or pos);
9 if not range then return end
10 if range.finish > pos then range.finish = pos end
11
12 local prefix = file:content(range)
13 if not prefix then return end
14
15 -- Strip leading delimiters for some programming languages
16 local _, j = prefix:find(".*[{[(<'\"]+")
17 if not expand and j then prefix = prefix:sub(j + 1) end
18
19 if prefix:match("^%s*$") then
20 prefix = ""
21 range.start = pos
22 range.finish = pos
23 end
24
25 -- Expand tilda for the home directory
26 _, j = prefix:find('^~')
27 if j ~= nil then
28 local home = assert(os.getenv("HOME"), "$HOME variable not set!")
29 prefix = home .. prefix:sub(j + 1)
30 end
31
32 local cmdfmt = "vis-complete --file '%s'"
33 if expand then cmdfmt = "vis-open -- '%s'*" end
34 local status, out, err = vis:pipe(cmdfmt:format(prefix:gsub("'", "'\\''")))
35 if status ~= 0 or not out then
36 if err then vis:info(err) end
37 return
38 end
39 out = out:gsub("\n$", "")
40
41 if expand then
42 file:delete(range)
43 pos = range.start
44 end
45
46 file:insert(pos, out)
47 win.selection.pos = pos + #out
48 end
49
50 -- complete file path at primary selection location using vis-complete(1)
51 vis:map(vis.modes.INSERT, "<C-x><C-f>", function()
52 complete_filename(false);
53 end, "Complete file name")
54
55 -- complete file path at primary selection location using vis-open(1)
56 vis:map(vis.modes.INSERT, "<C-x><C-o>", function()
57 complete_filename(true);
58 end, "Complete file name (expands path)")