Skip to content

Commit 756d13d

Browse files
author
skywind3000
committed
zlua 1.8.1: new -b -i and -b -I for interactive backwards cd
1 parent 4900651 commit 756d13d

File tree

1 file changed

+105
-4
lines changed

1 file changed

+105
-4
lines changed

z.lua

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#! /usr/bin/env lua
22
--=====================================================================
33
--
4-
-- z.lua - a cd command that learns, by skywind 2018, 2019
4+
-- z.lua - a cd command that learns, by skywind 2018, 2019, 2020
55
-- Licensed under MIT license.
66
--
7-
-- Version 1.7.4, Last Modified: 2019/12/29 04:52
7+
-- Version 1.8.1, Last Modified: 2020/02/09 23:33
88
--
99
-- * 10x faster than fasd and autojump, 3x faster than z.sh
1010
-- * available for posix shells: bash, zsh, sh, ash, dash, busybox
@@ -1585,7 +1585,7 @@ function z_cd(patterns)
15851585
io.stderr:write('> ')
15861586
io.stderr:flush()
15871587
local input = io.read('*l')
1588-
if input == nil then
1588+
if input == nil or input == '' then
15891589
return nil
15901590
end
15911591
local index = tonumber(input)
@@ -1767,6 +1767,103 @@ function cd_minus(args, options)
17671767
end
17681768

17691769

1770+
-----------------------------------------------------------------------
1771+
-- cd breadcrumbs: z -b -i, z -b -I
1772+
-----------------------------------------------------------------------
1773+
function cd_breadcrumbs(pwd, interactive)
1774+
local pwd = (pwd == nil or pwd == '') and os.pwd() or pwd
1775+
local pwd = os.path.normpath(pwd)
1776+
local path, _ = os.path.split(pwd)
1777+
local elements = {}
1778+
local interactive = interactive and interactive or 1
1779+
local fullname = os.environ('_ZL_FULL_PATH', false)
1780+
-- fullname = true
1781+
while true do
1782+
local head, name = os.path.split(path)
1783+
if head == path then -- reached root
1784+
table.insert(elements, {head, head})
1785+
break
1786+
elseif name ~= '' then
1787+
table.insert(elements, {name, path})
1788+
else
1789+
break
1790+
end
1791+
path = head
1792+
end
1793+
-- printT(elements)
1794+
local tmpname = '/tmp/zlua.txt'
1795+
local fp = io.stderr
1796+
if interactive == 2 then
1797+
if not windows then
1798+
tmpname = os.tmpname()
1799+
else
1800+
tmpname = os.tmpname():gsub('\\', ''):gsub('%.', '')
1801+
tmpname = os.environ('TMP', '') .. '\\zlua_' .. tmpname .. '.txt'
1802+
end
1803+
fp = io.open(tmpname, 'w')
1804+
end
1805+
-- print table
1806+
local maxsize = string.len(tostring(#elements))
1807+
for i = #elements, 1, -1 do
1808+
local item = elements[i]
1809+
local name = item[1]
1810+
local text = string.rep(' ', maxsize - string.len(i)) .. tostring(i)
1811+
text = text .. ': ' .. (fullname and item[2] or item[1])
1812+
fp:write(text .. '\n')
1813+
end
1814+
if fp ~= io.stderr then
1815+
fp:close()
1816+
end
1817+
-- select from stdin or fzf
1818+
if interactive == 1 then
1819+
io.stderr:write('> ')
1820+
io.stderr:flush()
1821+
local input = io.read('*l')
1822+
if input == nil or input == '' then
1823+
return nil
1824+
end
1825+
local index = tonumber(input)
1826+
if index < 1 or index > #elements then
1827+
return nil
1828+
end
1829+
retval = elements[index][2]
1830+
elseif interactive == 2 then
1831+
local fzf = os.environ('_ZL_FZF', 'fzf')
1832+
local cmd = '--reverse --inline-info --tac '
1833+
local flag = os.environ('_ZL_FZF_FLAG', '')
1834+
flag = (flag == '' or flag == nil) and '+s -e' or flag
1835+
cmd = ((fzf == '') and 'fzf' or fzf) .. ' ' .. cmd .. ' ' .. flag
1836+
if not windows then
1837+
local height = os.environ('_ZL_FZF_HEIGHT', '35%')
1838+
if height ~= nil and height ~= '' and height ~= '0' then
1839+
cmd = cmd .. ' --height ' .. height
1840+
end
1841+
cmd = cmd .. '< "' .. tmpname .. '"'
1842+
else
1843+
cmd = 'type "' .. tmpname .. '" | ' .. cmd
1844+
end
1845+
retval = os.call(cmd)
1846+
os.remove(tmpname)
1847+
if retval == '' or retval == nil then
1848+
return nil
1849+
end
1850+
local pos = retval:find(':')
1851+
if not pos then
1852+
return nil
1853+
end
1854+
retval = retval:sub(1, pos - 1):gsub('^%s*', '')
1855+
index = tonumber((retval == nil) and '0' or retval)
1856+
if index == nil then
1857+
return nil
1858+
elseif index < 1 or index > #elements then
1859+
return nil
1860+
end
1861+
retval = elements[index][2]
1862+
end
1863+
return retval
1864+
end
1865+
1866+
17701867
-----------------------------------------------------------------------
17711868
-- main entry
17721869
-----------------------------------------------------------------------
@@ -1801,7 +1898,11 @@ function main(argv)
18011898
if options['--cd'] or options['-e'] then
18021899
local path = ''
18031900
if options['-b'] then
1804-
path = cd_backward(args, options)
1901+
if Z_INTERACTIVE == 0 then
1902+
path = cd_backward(args, options)
1903+
else
1904+
path = cd_breadcrumbs('', Z_INTERACTIVE)
1905+
end
18051906
elseif options['-'] then
18061907
path = cd_minus(args, options)
18071908
elseif #args == 0 then

0 commit comments

Comments
 (0)