diff options
Diffstat (limited to 'scripts/context/lua/mtx-fcd.lua')
-rw-r--r-- | scripts/context/lua/mtx-fcd.lua | 772 |
1 files changed, 386 insertions, 386 deletions
diff --git a/scripts/context/lua/mtx-fcd.lua b/scripts/context/lua/mtx-fcd.lua index ba9299020..81e67ca2f 100644 --- a/scripts/context/lua/mtx-fcd.lua +++ b/scripts/context/lua/mtx-fcd.lua @@ -1,386 +1,386 @@ -if not modules then modules = { } end modules ['mtx-fcd'] = { - version = 1.002, - comment = "companion to mtxrun.lua", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files", - comment = "based on the ruby version from 2005", -} - --- This is a kind of variant of the good old ncd (norton change directory) program. This --- script uses the same indirect cmd trick as Erwin Waterlander's wcd program. --- --- The program is called via the stubs fcd.cmd or fcd.sh. On unix one should probably source --- the file: ". fcd args" in order to make the chdir persistent. --- --- You need to create a stub with: --- --- mtxrun --script fcd --stub > fcd.cmd --- mtxrun --script fcd --stub > fcd.sh --- --- The stub starts this script and afterwards runs the created directory change script as --- part if the same run, so that indeed we change. - -local helpinfo = [[ -<?xml version="1.0"?> -<application> - <metadata> - <entry name="name">mtx-fcd</entry> - <entry name="detail">Fast Directory Change</entry> - <entry name="version">1.00</entry> - </metadata> - <flags> - <category name="basic"> - <subcategory> - <flag name="clear"><short>clear the cache</short></flag> - <flag name="clear"><short><ref name="history"/> [entry] clear the history</short></flag> - <flag name="scan"><short>clear the cache and add given path(s)</short></flag> - <flag name="add"><short>add given path(s)</short></flag> - <flag name="find"><short>find given path (can be substring)</short></flag> - <flag name="find"><short><ref name="nohistory"/> find given path (can be substring) but don't use history</short></flag> - <flag name="stub"><short>print platform stub file</short></flag> - <flag name="list"><short>show roots of cached dirs</short></flag> - <flag name="list"><short><ref name="history"/> show history of chosen dirs</short></flag> - <flag name="help"><short>show this help</short></flag> - </subcategory> - </category> - </flags> - <examples> - <category> - <title>Example</title> - <subcategory> - <example><command>fcd --scan t:\</command></example> - <example><command>fcd --add f:\project</command></example> - <example><command>fcd [--find] whatever</command></example> - <example><command>fcd --list</command></example> - </subcategory> - </category> - </examples> -</application> -]] - -local application = logs.application { - name = "mtx-fcd", - banner = "Fast Directory Change 1.00", - helpinfo = helpinfo, -} - -local report = application.report -local writeln = print -- texio.write_nl - -local find, char, byte, lower, gsub, format = string.find, string.char, string.byte, string.lower, string.gsub, string.format - -local mswinstub = [[@echo off - -rem this is: fcd.cmd - -@echo off - -if not exist "%HOME%" goto homepath - -:home - -mtxrun --script mtx-fcd.lua %1 %2 %3 %4 %5 %6 %7 %8 %9 - -if exist "%HOME%\mtx-fcd-goto.cmd" call "%HOME%\mtx-fcd-goto.cmd" - -goto end - -:homepath - -if not exist "%HOMEDRIVE%\%HOMEPATH%" goto end - -mtxrun --script mtx-fcd.lua %1 %2 %3 %4 %5 %6 %7 %8 %9 - -if exist "%HOMEDRIVE%\%HOMEPATH%\mtx-fcd-goto.cmd" call "%HOMEDRIVE%\%HOMEPATH%\mtx-fcd-goto.cmd" - -goto end - -:end -]] - -local unixstub = [[#!/usr/bin/env sh - -# this is: fcd.sh - -# mv fcd.sh fcd -# chmod fcd 755 -# . fcd [args] - -ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9 - -if test -f "$HOME/fcd_stage.sh" ; then - . $HOME/fcd_stage.sh ; -fi; - -]] - -local gotofile -local datafile -local stubfile -local stubdata -local stubdummy -local stubchdir - -if os.platform == 'mswin' then - gotofile = 'mtx-fcd-goto.cmd' - datafile = 'mtx-fcd-data.lua' - stubfile = 'fcd.cmd' - stubdata = mswinstub - stubdummy = 'rem no dir to change to' - stubchdir = 'cd /d "%s"' -else - gotofile = 'mtx-fcd-goto.sh' - datafile = 'mtx-fcd-data.lua' - stubfile = 'fcd.sh' - stubdata = unixstub - stubdummy = '# no dir to change to' - stubchdir = '# cd "%s"' -end - -local homedir = os.env["HOME"] or "" -- no longer TMP etc - -if homedir == "" then - homedir = format("%s/%s",os.env["HOMEDRIVE"] or "",os.env["HOMEPATH"] or "") -end - -if homedir == "/" or not lfs.isdir(homedir) then - os.exit() -end - -local datafile = file.join(homedir,datafile) -local gotofile = file.join(homedir,gotofile) -local hash = nil -local found = { } -local pattern = "" -local version = modules['mtx-fcd'].version - -io.savedata(gotofile,stubdummy) - -if not lfs.isfile(gotofile) then - -- write error - os.exit() -end - -local function fcd_clear(onlyhistory,what) - if onlyhistory and hash and hash.history then - if what and what ~= "" then - hash.history[what] = nil - else - hash.history = { } - end - else - hash = { - name = "fcd cache", - comment = "generated by mtx-fcd.lua", - created = os.date(), - version = version, - paths = { }, - history = { }, - } - end -end - -local function fcd_changeto(dir) - if dir and dir ~= "" then - io.savedata(gotofile,format(stubchdir,dir)) - end -end - -local function fcd_load(forcecreate) - if lfs.isfile(datafile) then - hash = dofile(datafile) - end - if not hash or hash.version ~= version then - if forcecache then - fcd_clear() - else - writeln("empty dir cache") - fcd_clear() - os.exit() - end - end -end - -local function fcd_save() - if hash then - io.savedata(datafile,table.serialize(hash,true)) - end -end - -local function fcd_list(onlyhistory) - if hash then - writeln("") - if onlyhistory then - if next(hash.history) then - for k, v in table.sortedhash(hash.history) do - writeln(format("%s => %s",k,v)) - end - else - writeln("no history") - end - else - local paths = hash.paths - if #paths > 0 then - for i=1,#paths do - local path = paths[i] - writeln(format("%4i %s",#path[2],path[1])) - end - else - writeln("empty cache") - end - end - end -end - -local function fcd_find() - found = { } - pattern = environment.files[1] or "" - if pattern ~= "" then - pattern = string.escapedpattern(pattern) - local paths = hash.paths - for i=1,#paths do - local paths = paths[i][2] - for i=1,#paths do - local path = paths[i] - if find(path,pattern) then - found[#found+1] = path - end - end - end - end -end - -local function fcd_choose(new) - if pattern == "" then - writeln(format("staying in dir %q",(gsub(lfs.currentdir(),"\\","/")))) - return - end - if #found == 0 then - writeln(format("dir %q not found",pattern)) - return - end - local okay = #found == 1 and found[1] or (not new and hash.history[pattern]) - if okay then - writeln(format("changing to %q",okay)) - fcd_changeto(okay) - return - end - local offset = 0 - while true do - if not found[offset] then - offset = 0 - end - io.write("\n") - for i=1,26 do - local v = found[i+offset] - if v then - writeln(format("%s %3i %s",char(i+96),offset+i,v)) - else - break - end - end - offset = offset + 26 - if found[offset+1] then - io.write("\n[press enter for more or select letter]\n\n>> ") - else - io.write("\n[select letter]\n\n>> ") - end - local answer = lower(io.read() or "") - if not answer or answer == 'quit' then - break - elseif #answer > 0 then - local choice = tonumber(answer) - if not choice then - if answer >= "a" and answer <= "z" then - choice = byte(answer) - 96 + offset - 26 - end - end - local newdir = found[choice] - if newdir then - hash.history[pattern] = newdir - writeln(format("changing to %q",newdir)) - fcd_changeto(newdir) - fcd_save() - return - end - else - -- try again - end - end -end - -local function globdirs(path,dirs) - local dirs = dirs or { } - for name in lfs.dir(path) do - if not find(name,"%.$") then - local fullname = path .. "/" .. name - if lfs.isdir(fullname) and not find(fullname,"/%.") then - dirs[#dirs+1] = fullname - globdirs(fullname,dirs) - end - end - end - return dirs -end - -local function fcd_scan() - if hash then - local paths = hash.paths - for i=1,#environment.files do - local name = environment.files[i] - local name = gsub(name,"\\","/") - local name = gsub(name,"/$","") - local list = globdirs(name) - local done = false - for i=1,#paths do - if paths[i][1] == name then - paths[i][2] = list - done = true - break - end - end - if not done then - paths[#paths+1] = { name, list } - end - end - end -end - -local argument = environment.argument - -if argument("clear") then - if argument("history") then - fcd_load() - fcd_clear(true) - else - fcd_clear() - end - fcd_save() -elseif argument("scan") then - fcd_clear() - fcd_scan() - fcd_save() -elseif argument("add") then - fcd_load(true) - fcd_scan() - fcd_save() -elseif argument("stub") then - writeln(stubdata) -elseif argument("list") then - fcd_load() - if argument("history") then - fcd_list(true) - else - fcd_list() - end -elseif argument("help") then - application.help() -elseif argument("exporthelp") then - application.export(argument("exporthelp"),environment.files[1]) -else -- also argument("find") - fcd_load() - fcd_find() - fcd_choose(argument("nohistory")) -end - +if not modules then modules = { } end modules ['mtx-fcd'] = {
+ version = 1.002,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+ comment = "based on the ruby version from 2005",
+}
+
+-- This is a kind of variant of the good old ncd (norton change directory) program. This
+-- script uses the same indirect cmd trick as Erwin Waterlander's wcd program.
+--
+-- The program is called via the stubs fcd.cmd or fcd.sh. On unix one should probably source
+-- the file: ". fcd args" in order to make the chdir persistent.
+--
+-- You need to create a stub with:
+--
+-- mtxrun --script fcd --stub > fcd.cmd
+-- mtxrun --script fcd --stub > fcd.sh
+--
+-- The stub starts this script and afterwards runs the created directory change script as
+-- part if the same run, so that indeed we change.
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-fcd</entry>
+ <entry name="detail">Fast Directory Change</entry>
+ <entry name="version">1.00</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="clear"><short>clear the cache</short></flag>
+ <flag name="clear"><short><ref name="history"/> [entry] clear the history</short></flag>
+ <flag name="scan"><short>clear the cache and add given path(s)</short></flag>
+ <flag name="add"><short>add given path(s)</short></flag>
+ <flag name="find"><short>find given path (can be substring)</short></flag>
+ <flag name="find"><short><ref name="nohistory"/> find given path (can be substring) but don't use history</short></flag>
+ <flag name="stub"><short>print platform stub file</short></flag>
+ <flag name="list"><short>show roots of cached dirs</short></flag>
+ <flag name="list"><short><ref name="history"/> show history of chosen dirs</short></flag>
+ <flag name="help"><short>show this help</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <examples>
+ <category>
+ <title>Example</title>
+ <subcategory>
+ <example><command>fcd --scan t:\</command></example>
+ <example><command>fcd --add f:\project</command></example>
+ <example><command>fcd [--find] whatever</command></example>
+ <example><command>fcd --list</command></example>
+ </subcategory>
+ </category>
+ </examples>
+</application>
+]]
+
+local application = logs.application {
+ name = "mtx-fcd",
+ banner = "Fast Directory Change 1.00",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+local writeln = print -- texio.write_nl
+
+local find, char, byte, lower, gsub, format = string.find, string.char, string.byte, string.lower, string.gsub, string.format
+
+local mswinstub = [[@echo off
+
+rem this is: fcd.cmd
+
+@echo off
+
+if not exist "%HOME%" goto homepath
+
+:home
+
+mtxrun --script mtx-fcd.lua %1 %2 %3 %4 %5 %6 %7 %8 %9
+
+if exist "%HOME%\mtx-fcd-goto.cmd" call "%HOME%\mtx-fcd-goto.cmd"
+
+goto end
+
+:homepath
+
+if not exist "%HOMEDRIVE%\%HOMEPATH%" goto end
+
+mtxrun --script mtx-fcd.lua %1 %2 %3 %4 %5 %6 %7 %8 %9
+
+if exist "%HOMEDRIVE%\%HOMEPATH%\mtx-fcd-goto.cmd" call "%HOMEDRIVE%\%HOMEPATH%\mtx-fcd-goto.cmd"
+
+goto end
+
+:end
+]]
+
+local unixstub = [[#!/usr/bin/env sh
+
+# this is: fcd.sh
+
+# mv fcd.sh fcd
+# chmod fcd 755
+# . fcd [args]
+
+ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9
+
+if test -f "$HOME/fcd_stage.sh" ; then
+ . $HOME/fcd_stage.sh ;
+fi;
+
+]]
+
+local gotofile
+local datafile
+local stubfile
+local stubdata
+local stubdummy
+local stubchdir
+
+if os.platform == 'mswin' then
+ gotofile = 'mtx-fcd-goto.cmd'
+ datafile = 'mtx-fcd-data.lua'
+ stubfile = 'fcd.cmd'
+ stubdata = mswinstub
+ stubdummy = 'rem no dir to change to'
+ stubchdir = 'cd /d "%s"'
+else
+ gotofile = 'mtx-fcd-goto.sh'
+ datafile = 'mtx-fcd-data.lua'
+ stubfile = 'fcd.sh'
+ stubdata = unixstub
+ stubdummy = '# no dir to change to'
+ stubchdir = '# cd "%s"'
+end
+
+local homedir = os.env["HOME"] or "" -- no longer TMP etc
+
+if homedir == "" then
+ homedir = format("%s/%s",os.env["HOMEDRIVE"] or "",os.env["HOMEPATH"] or "")
+end
+
+if homedir == "/" or not lfs.isdir(homedir) then
+ os.exit()
+end
+
+local datafile = file.join(homedir,datafile)
+local gotofile = file.join(homedir,gotofile)
+local hash = nil
+local found = { }
+local pattern = ""
+local version = modules['mtx-fcd'].version
+
+io.savedata(gotofile,stubdummy)
+
+if not lfs.isfile(gotofile) then
+ -- write error
+ os.exit()
+end
+
+local function fcd_clear(onlyhistory,what)
+ if onlyhistory and hash and hash.history then
+ if what and what ~= "" then
+ hash.history[what] = nil
+ else
+ hash.history = { }
+ end
+ else
+ hash = {
+ name = "fcd cache",
+ comment = "generated by mtx-fcd.lua",
+ created = os.date(),
+ version = version,
+ paths = { },
+ history = { },
+ }
+ end
+end
+
+local function fcd_changeto(dir)
+ if dir and dir ~= "" then
+ io.savedata(gotofile,format(stubchdir,dir))
+ end
+end
+
+local function fcd_load(forcecreate)
+ if lfs.isfile(datafile) then
+ hash = dofile(datafile)
+ end
+ if not hash or hash.version ~= version then
+ if forcecache then
+ fcd_clear()
+ else
+ writeln("empty dir cache")
+ fcd_clear()
+ os.exit()
+ end
+ end
+end
+
+local function fcd_save()
+ if hash then
+ io.savedata(datafile,table.serialize(hash,true))
+ end
+end
+
+local function fcd_list(onlyhistory)
+ if hash then
+ writeln("")
+ if onlyhistory then
+ if next(hash.history) then
+ for k, v in table.sortedhash(hash.history) do
+ writeln(format("%s => %s",k,v))
+ end
+ else
+ writeln("no history")
+ end
+ else
+ local paths = hash.paths
+ if #paths > 0 then
+ for i=1,#paths do
+ local path = paths[i]
+ writeln(format("%4i %s",#path[2],path[1]))
+ end
+ else
+ writeln("empty cache")
+ end
+ end
+ end
+end
+
+local function fcd_find()
+ found = { }
+ pattern = environment.files[1] or ""
+ if pattern ~= "" then
+ pattern = string.escapedpattern(pattern)
+ local paths = hash.paths
+ for i=1,#paths do
+ local paths = paths[i][2]
+ for i=1,#paths do
+ local path = paths[i]
+ if find(path,pattern) then
+ found[#found+1] = path
+ end
+ end
+ end
+ end
+end
+
+local function fcd_choose(new)
+ if pattern == "" then
+ writeln(format("staying in dir %q",(gsub(lfs.currentdir(),"\\","/"))))
+ return
+ end
+ if #found == 0 then
+ writeln(format("dir %q not found",pattern))
+ return
+ end
+ local okay = #found == 1 and found[1] or (not new and hash.history[pattern])
+ if okay then
+ writeln(format("changing to %q",okay))
+ fcd_changeto(okay)
+ return
+ end
+ local offset = 0
+ while true do
+ if not found[offset] then
+ offset = 0
+ end
+ io.write("\n")
+ for i=1,26 do
+ local v = found[i+offset]
+ if v then
+ writeln(format("%s %3i %s",char(i+96),offset+i,v))
+ else
+ break
+ end
+ end
+ offset = offset + 26
+ if found[offset+1] then
+ io.write("\n[press enter for more or select letter]\n\n>> ")
+ else
+ io.write("\n[select letter]\n\n>> ")
+ end
+ local answer = lower(io.read() or "")
+ if not answer or answer == 'quit' then
+ break
+ elseif #answer > 0 then
+ local choice = tonumber(answer)
+ if not choice then
+ if answer >= "a" and answer <= "z" then
+ choice = byte(answer) - 96 + offset - 26
+ end
+ end
+ local newdir = found[choice]
+ if newdir then
+ hash.history[pattern] = newdir
+ writeln(format("changing to %q",newdir))
+ fcd_changeto(newdir)
+ fcd_save()
+ return
+ end
+ else
+ -- try again
+ end
+ end
+end
+
+local function globdirs(path,dirs)
+ local dirs = dirs or { }
+ for name in lfs.dir(path) do
+ if not find(name,"%.$") then
+ local fullname = path .. "/" .. name
+ if lfs.isdir(fullname) and not find(fullname,"/%.") then
+ dirs[#dirs+1] = fullname
+ globdirs(fullname,dirs)
+ end
+ end
+ end
+ return dirs
+end
+
+local function fcd_scan()
+ if hash then
+ local paths = hash.paths
+ for i=1,#environment.files do
+ local name = environment.files[i]
+ local name = gsub(name,"\\","/")
+ local name = gsub(name,"/$","")
+ local list = globdirs(name)
+ local done = false
+ for i=1,#paths do
+ if paths[i][1] == name then
+ paths[i][2] = list
+ done = true
+ break
+ end
+ end
+ if not done then
+ paths[#paths+1] = { name, list }
+ end
+ end
+ end
+end
+
+local argument = environment.argument
+
+if argument("clear") then
+ if argument("history") then
+ fcd_load()
+ fcd_clear(true)
+ else
+ fcd_clear()
+ end
+ fcd_save()
+elseif argument("scan") then
+ fcd_clear()
+ fcd_scan()
+ fcd_save()
+elseif argument("add") then
+ fcd_load(true)
+ fcd_scan()
+ fcd_save()
+elseif argument("stub") then
+ writeln(stubdata)
+elseif argument("list") then
+ fcd_load()
+ if argument("history") then
+ fcd_list(true)
+ else
+ fcd_list()
+ end
+elseif argument("help") then
+ application.help()
+elseif argument("exporthelp") then
+ application.export(argument("exporthelp"),environment.files[1])
+else -- also argument("find")
+ fcd_load()
+ fcd_find()
+ fcd_choose(argument("nohistory"))
+end
+
|