-
Notifications
You must be signed in to change notification settings - Fork 7
/
z_dir_popup.lua
94 lines (82 loc) · 2.36 KB
/
z_dir_popup.lua
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
--------------------------------------------------------------------------------
-- Usage:
--
-- For use with z.lua (https://github.com/skywind3000/z.lua).
--
-- This script provides a function `z_dir_popup` for use as a "luafunc:" key
-- binding (see https://chrisant996.github.io/clink/clink.html#luakeybindings).
--
-- The command shows a popup to pick from a directory known to z, and then
-- changes to that directory.
--
-- Sample key binding, in .inputrc format:
--[[
"\e[5;5~": "luafunc:z_dir_popup" # Ctrl-PgUp
--]]
if not clink.popuplist then
print("z_dir_popup.lua requires a newer version of Clink; please upgrade.")
return
end
if rl.describemacro then
rl.describemacro("luafunc:z_dir_popup", "Show a popup to pick from a directory known to z, and then change to the directory") -- luacheck: no max line length
end
local function need_cd_drive(dir)
local drive = path.getdrive(dir)
if drive then
local cwd = os.getcwd()
if cwd then
local cwd_drive = path.getdrive(cwd)
if cwd_drive and cwd_drive:lower() == drive:lower() then
return
end
end
end
return drive
end
function z_dir_popup(rl_buffer) -- luacheck: no global
local z = os.getalias("z")
if z then
z = z:match('^"([^"]+)"') or z:match('^([^ ]+)')
end
if not z then
z = "z.cmd"
end
local r = io.popen('"' .. z .. '" -l')
if not r then
rl_buffer:ding()
return
end
local list = {}
for line in r:lines() do
if line ~= "" then
table.insert(list, line)
end
end
r:close()
local dirs = {}
for i = #list, 1, -1 do
table.insert(dirs, list[i])
end
local selected, shifted = clink.popuplist("Z Directories", dirs)
if not selected then
return
end
local dir = selected:match("^ *[0-9.]+ +(.+)$")
if not dir or dir == "" then
rl_buffer:ding()
return
end
if shifted and (clink.version_encoded or 0) >= 10030024 then
rl_buffer:insert(dir)
else
rl_buffer:remove(1, -1)
rl_buffer:setcursor(1)
local drive = need_cd_drive(dir)
if drive then
rl_buffer:insert(" " .. drive .. " & cd " .. dir)
else
rl_buffer:insert(" cd " .. dir)
end
rl.invokecommand("accept-line")
end
end