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 81e67ca2f..ba9299020 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 + |