File: complete.lua

package info (click to toggle)
civetweb 1.15%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 4,428 kB
  • sloc: ansic: 30,865; cpp: 1,290; sh: 494; javascript: 204; python: 143; makefile: 93; perl: 6; php: 1
file content (171 lines) | stat: -rw-r--r-- 4,857 bytes parent folder | download | duplicates (6)
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/lua5.2

-- CivetWeb command line completion for bash

--[[ INSTALLING:

To use auto-completion for bash, you need to define a command for the bash built-in
[*complete*](https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html).

Create a file called "civetweb" in the completion folder.
Depending on Linux distribution and version, this might be
/usr/share/bash-completion/completions/, /etc/bash_completion or another folder.

The file has to contain just one line:
complete -C /path/to/civetweb/resources/complete.lua civetweb

The complete command script is implemented in this file.
It needs Lua 5.2 to be installed (for Debian based systems: "sudo apt-get install lua5.2").
In case lua5.2 is not located in /usr/bin/lua5.2 (see "which lua5.2"),
the first line (#!) needs to be adapted accordingly.

--]]

---------------------------------------------------------------------------------------------------

-- 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)
  --[[ comment / uncomment to enable debugging
  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_r = ".htpasswd <mydomain.com> <username>"
htpasswd_a = htpasswd_r .. " <password>"
if (last == "-A") and (this == htpasswd_a:sub(1,#this)) then
  dp("Fill with option template for -A")
  print(htpasswd_a)
  os.exit(0)
end
if (last == "-R") and (this == htpasswd_r:sub(1,#this)) then
  dp("Fill with option template for -R")
  print(htpasswd_r)
  os.exit(0)
end
if (is_a or is_r) then
  dp("Options -A and -R have a fixed number of arguments")
  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
if (is_c) then
  dp("Option -C has just one argument")
  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 .. " --help > " .. optfile .. " 2>&1")
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)