123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #!/usr/bin/lua5.2
- -- CivetWeb command line completion for bash
- --
- -- To use it, create a file called "civetweb" in the completion folder
- -- (/usr/share/bash-completion/completions/ or /etc/bash_completion)
- -- This file has to contain just one line:
- -- complete -C /path/to/civetweb/resources/complete.lua civetweb
- --
- -- The bash "complete -C" has an awkward interface:
- -- see https://unix.stackexchange.com/questions/250262/how-to-use-bashs-complete-or-compgen-c-command-option
- -- Command line arguments
- cmd = arg[1] -- typically "./civetweb" or whatever path was used
- this = arg[2] -- characters already typed for the next options
- last = arg[3] -- option before this one
- -- Environment variables
- comp_line = os.getenv("COMP_LINE") -- entire command line
- comp_point = os.getenv("COMP_POINT") -- position of cursor (index)
- comp_type = os.getenv("COMP_TYPE") -- type:
- -- 9 for normal completion
- -- 33 when listing alternatives on ambiguous completions
- -- 37 for menu completion
- -- 63 when tabbing between ambiguous completions
- -- 64 to list completions after a partial completion
- -- Debug-Print function (must use absolute path for log file)
- function dp(txt)
- local f = io.open("/tmp/complete.log", "a");
- f:write(txt .. "\n")
- f:close()
- end
- -- Helper function: Check if files exist
- function fileexists(name)
- local f = io.open(name, "r")
- if f then
- f:close()
- return true
- end
- return false
- end
- -- Debug logging
- dp("complete: cmd=" .. cmd .. ", this=" .. this .. ", last=" .. last .. ", type=" .. comp_type)
- -- Trim command line (remove spaces)
- trim_comp_line = string.match(comp_line, "^%s*(.-)%s*$")
-
- if (trim_comp_line == cmd) then
- -- this is the first option
- dp("Suggest --help argument")
- print("--help ")
- os.exit(0)
- end
- is_h = string.find(comp_line, "^%s*" .. cmd .. "%s+%-h%s")
- is_h = is_h or string.find(comp_line, "^%s*" .. cmd .. "%s+%--help%s")
- is_h = is_h or string.find(comp_line, "^%s*" .. cmd .. "%s+%-H%s")
- if (is_h) then
- dp("If --help is used, no additional argument is allowed")
- os.exit(0)
- end
- is_a = string.find(comp_line, "^%s*" .. cmd .. "%s+%-A%s")
- is_c = string.find(comp_line, "^%s*" .. cmd .. "%s+%-C%s")
- is_i = string.find(comp_line, "^%s*" .. cmd .. "%s+%-I%s")
- is_r = string.find(comp_line, "^%s*" .. cmd .. "%s+%-R%s")
- if (is_i) then
- dp("If --I is used, no additional argument is allowed")
- os.exit(0)
- end
- -- -A and -R require the password file as second argument
- htpasswd = ".htpasswd"
- if ((last == "-A") or (last == "-R")) and (this == htpasswd:sub(1,#this)) then
- print(htpasswd)
- os.exit(0)
- end
- -- -C requires an URL, usually starting with http:// or https://
- http = "http://"
- if (last == "-C") and (this == http:sub(1,#this)) then
- print(http)
- print(http.. "localhost/")
- os.exit(0)
- end
- http = "https://"
- if (last == "-C") and (this == http:sub(1,#this)) then
- print(http)
- print(http.. "localhost/")
- os.exit(0)
- end
- -- Take options directly from "--help" output of executable
- optfile = "/tmp/civetweb.options"
- if not fileexists(optfile) then
- dp("options file " .. optfile .. " missing")
- os.execute(cmd .. " -h &> " .. optfile)
- else
- dp("options file " .. optfile .. " found")
- end
- for l in io.lines(optfile) do
- local lkey, lval = l:match("^%s+(%-[^%s]*)%s*([^%s]*)%s*$")
- if lkey then
- local thislen = string.len(this)
- if (thislen>0) and (this == lkey:sub(1,thislen)) then
- print(lkey)
- dp("match: " .. lkey)
- keymatch = true
- end
- if last == lkey then
- valmatch = lval
- end
- end
- end
- if keymatch then
- -- at least one options matches
- os.exit(0)
- end
- if valmatch then
- -- suggest the default value
- print(valmatch)
- os.exit(0)
- end
- -- No context to determine next argument
- dp("no specific option")
- os.exit(0)
|