More changelog updates
[stgit.git] / stgit / completion / fish.py
blobb032537cdef2d6885068db014aa30c1bd6f417ee
1 import stgit.commands
2 import stgit.config
3 from stgit import argparse
5 _file_args = ['files', 'dir', 'repo']
6 _has_fish_func_args = [
7 'stg_branches',
8 'all_branches',
9 'applied_patches',
10 'unapplied_patches',
11 'hidden_patches',
12 'other_applied_patches',
13 'commit',
14 'conflicting_files',
15 'dirty_files',
16 'unknown_files',
17 'known_files',
18 'mail_aliases',
22 def _get_file_completion_flag(args):
23 if any(file_arg in args for file_arg in _file_args):
24 return '-r'
25 else:
26 return '-f'
29 def _completions_from_args(args):
30 completions = []
31 for arg in args:
32 if isinstance(arg, argparse.patch_range):
33 for endpoint in arg:
34 if endpoint in _has_fish_func_args:
35 completions.append('(__fish_stg_%s)' % endpoint)
36 elif isinstance(arg, argparse.strings):
37 completions.extend(arg)
38 elif arg in _file_args:
39 pass
40 elif arg in _has_fish_func_args:
41 completions.append('(__fish_stg_%s)' % arg)
42 else:
43 raise AssertionError('unknown arg kind: %s' % arg)
44 return ' '.join(completions)
47 def write_fish_completion(f):
48 def put(*args, **kwargs):
49 kwargs['file'] = f
50 print(*args, **kwargs)
52 commands = stgit.commands.get_commands(allow_cached=False)
53 aliases = []
54 for name, values in stgit.config.DEFAULTS:
55 if name.startswith('stgit.alias.'):
56 alias = name.replace('stgit.alias.', '', 1)
57 command = values[0]
58 aliases.append((alias, command))
60 put(
61 '''\
62 # Fish shell completion for StGit (stg)
64 # To use, copy this file to one of the paths in $fish_complete_path, e.g.:
66 # ~/.config/fish/completions
68 # This file is autogenerated.
70 function __fish_stg_all_branches
71 command git for-each-ref --format='%(refname)' \\
72 refs/heads/ refs/remotes/ 2>/dev/null \\
73 | string replace -r '^refs/heads/(.*)$' '$1\\tLocal Branch' \\
74 | string replace -r '^refs/remotes/(.*)$' '$1\\tRemote Branch'
75 end
77 function __fish_stg_stg_branches
78 command stg branch --list 2>/dev/null \\
79 | string match -r ". s.\\t\\S+" \\
80 | string replace -r ". s.\\t" ""
81 end
83 function __fish_stg_applied_patches
84 command stg series --no-description --noprefix --applied 2>/dev/null
85 end
87 function __fish_stg_other_applied_patches
88 set -l top (command stg top 2>/dev/null)
89 command stg series --no-description --noprefix --applied 2>/dev/null \\
90 | string match --invert "$top"
91 end
93 function __fish_stg_unapplied_patches
94 command stg series --no-description --noprefix --unapplied 2>/dev/null
95 end
97 function __fish_stg_hidden_patches
98 command stg series --no-description --noprefix --hidden 2>/dev/null
99 end
101 function __fish_stg_tags
102 command git tag --sort=-creatordate 2>/dev/null
105 function __fish_stg_commit
106 __fish_stg_all_branches __fish_stg_tags
109 function __fish_stg_conflicting_files
110 command git ls-files --unmerged \\
111 | string replace -rf '^.*\\t(.*)$' '$1' \\
112 | sort -u
115 function __fish_stg_dirty_files
116 command git diff-index --name-only HEAD 2>/dev/null
119 function __fish_stg_unknown_files
120 command git ls-files --others --exclude-standard 2>/dev/null
123 function __fish_stg_known_files
124 command git ls-files 2>/dev/null
127 function __fish_stg_mail_aliases
128 command git config --name-only --get-regexp "^mail\\.alias\\." \\
129 | cut -d. -f 3
130 end'''
133 put(
135 function __fish_stg_is_alias
136 set --local tokens (commandline -opc) (commandline -ct)
137 if test "$tokens[1]" = "stg"
138 switch "$tokens[2]"
139 case %s
140 return 0
141 case '*'
142 return 1
145 end'''
146 % ' '.join(alias for alias, _ in aliases)
149 put(
151 function __fish_stg_complete_alias
152 set --local tokens (commandline -opc) (commandline -ct)
153 set --local cmd "$tokens[2]"
154 set --erase tokens[1 2]
155 switch "$cmd"'''
157 for alias, command in aliases:
158 put(' case', alias)
159 put(' set --prepend tokens', command)
160 put(
161 '''\
163 complete -C"$tokens"
168 put('### Aliases: %s' % ' '.join(alias for alias, _ in aliases))
169 put(
170 "complete -c stg -n '__fish_stg_is_alias' -x",
171 "-a '(__fish_stg_complete_alias)'",
173 for alias, command in aliases:
174 put(
175 "complete -c stg -n '__fish_use_subcommand' -x",
176 """-a %s -d 'Alias for "%s"'""" % (alias, command),
179 put()
181 put('### help')
182 put(
183 "complete -f -c stg -n '__fish_use_subcommand' -x",
184 "-a help -d 'print the detailed command usage'",
186 for cmd, modname, _, _ in commands:
187 mod = stgit.commands.get_command(modname)
188 put(
189 "complete -f -c stg -n '__fish_seen_subcommand_from help'",
190 "-a %s -d '%s'" % (cmd, mod.help),
192 for alias, command in aliases:
193 put(
194 "complete -f -c stg -n '__fish_seen_subcommand_from help'",
195 """-a %s -d 'Alias for "%s"'""" % (alias, command),
198 for cmd, modname, _, _ in commands:
199 mod = stgit.commands.get_command(modname)
200 completions = []
201 put('', '### %s' % cmd, sep='\n')
202 put(
203 "complete -c stg -n '__fish_use_subcommand' -x",
204 "-a %s -d '%s'" % (cmd, mod.help),
207 completions = _completions_from_args(mod.args)
208 if completions:
209 extra = "-ra '%s'" % completions
210 else:
211 extra = ""
213 put(
214 "complete",
215 _get_file_completion_flag(mod.args),
216 "-c stg",
217 "-n '__fish_seen_subcommand_from %s'" % cmd,
218 extra,
220 put(
221 "complete -f -c stg -n '__fish_seen_subcommand_from %s'" % cmd,
222 "-s h -l help -d 'show detailed help for %s'" % cmd,
225 for opt in mod.options:
226 long_opt = ''
227 short_opt = ' '
228 for flag in opt.flags:
229 if len(flag) == 2 and flag.startswith('-'):
230 short_opt = '-s ' + flag[1]
231 if flag.startswith('--'):
232 long_opt = '-l ' + flag[2:]
233 completions = _completions_from_args(opt.args)
234 if completions:
235 extra = "-xa '%s'" % completions
236 else:
237 extra = ""
238 put(
239 "complete",
240 _get_file_completion_flag(opt.args),
241 "-c stg",
242 "-n '__fish_seen_subcommand_from %s'" % cmd,
243 short_opt,
244 long_opt,
245 "-d '%s'" % opt.kwargs.get('short'),
246 extra,
250 if __name__ == '__main__':
251 import sys
253 write_fish_completion(sys.stdout)