aboutsummaryrefslogtreecommitdiffhomepage
path: root/make_completions.py
blob: 3c74aa3162fc4923508d0399fb526914edc8bf70 (plain)
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
#!/usr/bin/env python

import sys
try:
  import commands
except ImportError:
  import subprocess
import re

# Regexes for performing cleanup

cl = { re.compile(r"-[ \t]*\n[ \t\r]+" ):"",
       re.compile(r"[ \n\t\r]+", re.MULTILINE):" ",
       re.compile(r"^[ \n\t\r]"):"",
       re.compile(r"[ \n\t\r]$"):"" }

def header(cmd):
  print('''#
# Command specific completions for the {0} command.
# These completions were generated from the commands
# man page by the make_completions.py script, but may
# have been hand edited since.
#
'''.format(cmd))

def up_first(s):
  return s[0].upper() + s[1:]

def escape_quotes(s):
  return re.sub('\'', '\\\'', s)

def escape(s):
  return re.sub('([\'"#%*?])', r"\\\1", s)

def clean(s):
  res=s
  for r, str in cl.items():
    res = r.sub(str, res)
  return res

def print_completion( cmd, switch_arr, arg, desc ):

  if len(switch_arr)==0:
    return

  res = "complete -c {0}".format(cmd)
  for sw in switch_arr:

    offset=1
    switch_type = "o"

    if len(sw) == 2:
      switch_type = "s"

    if sw[1] == "-":
      switch_type = "l"
      offset=2

    res += " -{0} {1}".format(switch_type, escape(sw[offset:]))

  res += " --description '{0}'".format(up_first(escape_quotes(clean(desc))))

  print(res)

cmd = sys.argv[1]

header(cmd)

try:
  man = commands.getoutput( "man {0} | col -b".format(cmd))
except NameError:
  man = subprocess.getoutput( "man {0} | col -b".format(cmd))

remainder = man

MODE_NONE = 0
MODE_SWITCH = 1
MODE_BETWEEN = 2
MODE_BETWEEN_IGNORE = 3
MODE_DESC = 4

mode = MODE_NONE
pos = 0
sw=''
sw_arr=[]
switch_end="= \t\n[,"
switch_between_ignore="[="
switch_between_continue=" \t\n|"
before_switch=" \t\r"
between_ignore=" \t\n]"
pc=False
desc=''

can_be_switch =True

for c in man:

  if mode == MODE_NONE:
    if c == '-' and can_be_switch:
      mode = MODE_SWITCH
      sw = '-'

    elif c == '\n':
      can_be_switch = True
    elif before_switch.find(c)<0:
      can_be_switch = False


  elif mode == MODE_SWITCH:
    if not switch_end.find(c)>=0:
      sw+=c
    else:
      if len(sw) > 1:
        sw_arr.append(sw)

      if switch_between_ignore.find(c) >= 0:
        mode=MODE_BETWEEN_IGNORE
      else:
        mode=MODE_BETWEEN
    #  print "End of switch argumnt", sw, "switch to between mode"
      sw=''

  elif mode == MODE_BETWEEN:
    if c == '-':
      mode = MODE_SWITCH
      sw = '-'
    elif switch_between_ignore.find(c) >= 0:
      mode = MODE_BETWEEN_IGNORE
   #   print "Found character", c, "switching to ignore mode"
    elif not switch_between_continue.find(c) >= 0:
      mode = MODE_DESC
      desc = c

  elif mode == MODE_BETWEEN_IGNORE:
    if between_ignore.find(c)>=0:
      mode = MODE_BETWEEN

  elif mode == MODE_DESC:

    stop = False

    if c == '.':
      stop = True

    if c == '\n' and pc == '\n':
      stop=True

    if stop:
      mode=MODE_NONE

      print_completion( cmd, sw_arr, None, desc )

      sw_arr = []

      desc = ''

    else:
      desc += c

  else:
    print("Unknown mode {0}".format(mode))

  pc = c