Mercurial > libervia-backend
changeset 3485:7b888a488474
misc: update names for D-Bus service file and zsh autocompletion:
- using `li` as main shortcut for `libervia-cli` instead of `jp`
- fix outdated Python version in `_li` zsh completion shell
- following global name change, D-Bus service file is no `org.libervia.Libervia.service`
and it launches `libervia-backend`
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 21 Mar 2021 18:14:41 +0100 |
parents | d7091c635e22 |
children | c9703067c700 |
files | misc/README misc/_jp misc/_li misc/org.libervia.Libervia.service misc/org.salutatoi.SAT.service |
diffstat | 5 files changed, 148 insertions(+), 148 deletions(-) [+] |
line wrap: on
line diff
--- a/misc/README Sat Mar 20 20:42:07 2021 +0100 +++ b/misc/README Sun Mar 21 18:14:41 2021 +0100 @@ -1,15 +1,15 @@ -This directory contains files related to SàT but not directly used by it. +This directory contains files related to Libervia but not directly used by it. -* file _jp: +* file _li: This is the completion file for zsh. To use it, you need to have it in a path accessible in your fpath variable, and to have completion activated. This can be done by the following commands in your .zshrc: ### .zshrc completion ### -fpath=(/path/to/directory/with/_jp/ $fpath) +fpath=(/path/to/directory/with/_li/ $fpath) autoload -U compinit compinit ### end of .zshrc completion ### - Then, you should be able to complete a jp command line by pressing [TAB]. + Then, you should be able to complete a li command line by pressing [TAB]. * org.libervia.Libervia.service: This file is used by D-Bus to know how to launch the backend, you have to put in in D-Bus services dir (usually /usr/share/dbus-1/services)
--- a/misc/_jp Sat Mar 20 20:42:07 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +0,0 @@ -#compdef jp jp_dev -# jp: a SAT command line tool -# Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org) - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. - -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - - -#TODO: - caching (see _store_cache en _retrieve_cache) -# - filtering imposibles arguments -# - arguments (jids, files) - -PYTHON='python2' - -local optionals subcommands arguments -local context state state_descr line -typeset -A val_args - -_jp() { - eval `/usr/bin/env $PYTHON 2> /dev/null <<- PYTHONEND - import re - from subprocess import check_output - - # import sys - # words_raw="jp_dev " + ' '.join(sys.argv[1:]) # for debugging in a script - words_raw="$words" # $words is the command line currently completed - - words_all = words_raw.split() - prog_name = words_all[0] - - words_no_opt = [word for word in words_all if not word.startswith('-')] # command line without optional arguments - - choices_cache = {} - - ARG = r'[-a-z0-9_]' # charset accepted for an argument name - subcommands_re = re.compile(r"^ +{((?:" + ARG + r"+)(?:," + ARG + r"+)*)}", re.MULTILINE) - optionals_re = re.compile(r"^ {2,}(--?" + ARG + r"+(?: [A-Z_0-9]+)?(?:, --" + ARG + r"+(?: [A-Z_0-9]+)?)?)\n? {2,}(.*(?:\n {4,}.*)*$)", re.MULTILINE) - arguments_re = re.compile(r"^ {2,}([a-z_]" + ARG + r"*) {2,}(.*$)", re.MULTILINE) - clean_re = re.compile(r"(?P<prefix_spaces>^ +)|(?P<double_spaces> {2,})|(?P<newline>\n)|(?P<quote>')|(?P<suffix_spaces> +$)", re.MULTILINE) - - def _clean(desc): - def sub_clean(match): - matched_dict = match.groupdict() - matched = {matched for matched in matched_dict if matched_dict[matched]} - if matched.intersection(('prefix_spaces', 'suffix_spaces')): - return '' - elif matched.intersection(('double_spaces', 'newline')): - return ' ' - elif matched.intersection(('quote',)): - return r"'\''" - else: - raise ValueError - return clean_re.sub(sub_clean, desc) - - def parse_help(jp_help): - # parse the help returning subcommands, optionals arguments, and mandatory arguments - subcommands = subcommands_re.findall(jp_help) - subcommands = {subcommand:"" for subcommand in subcommands[0].split(',')} if subcommands else {} - optionals = dict(optionals_re.findall(jp_help)) - arguments = dict(arguments_re.findall(jp_help)) - for subcommand in subcommands: - subcommands[subcommand] = arguments.pop(subcommand, '') - return subcommands, optionals, arguments - - def get_choice(opt_choice): - choices = choices_cache.get(opt_choice) - if choices is not None: - return choices - if opt_choice == 'PROFILE': - profiles = check_output([prog_name, 'profile', 'list']) - choices = ":profile:(%s)" % ' '.join(profiles.split('\n')) - if choices: - choices_cache[opt_choice] = choices - return choices - else: - return "" - - def construct_opt(opts, desc): - # construct zsh's _arguments line for optional arguments - arg_lines = [] - for opt in opts.split(', '): - try: - opt_name, opt_choice = opt.split() - except ValueError: - # there is no argument - opt_name, opt_choice = opt, None - # arg_lines.append("'()%s[%s]%s'" % (opt_name+('=' if opt_name.startswith('--') else '+'), - arg_lines.append("'()%s[%s]%s'" % (opt_name, - _clean(desc), - "%s" % get_choice(opt_choice) if opt_choice else '' - )) - return ' '.join(arg_lines) - - current_args = [] - - while True: - # parse jp's help recursively until words_no_opt doesn't correspond anymore to a subcommand - try: - current_args.append(words_no_opt.pop(0)) - jp_help = check_output(current_args + ['--help']) - # print "jp_help (%s):\n%s\n\n---\n" % (' '.join(current_args), jp_help) # for debugging - subcommands, optionals, arguments = parse_help(jp_help) - if words_no_opt[0] not in subcommands: - break - except IndexError: - break - - # now we fill the arrays so zsh can use them - env=[] - env.append("optionals=(%s)" % ' '.join(construct_opt(opt, desc) for opt, desc in optionals.items())) - env.append("subcommands=(%s)" % ' '.join(["'%s[%s]'" % (subcommand, _clean(desc)) for subcommand, desc in subcommands.items()])) - env.append("arguments=(%s)" % ' '.join(["'%s[%s]'" % (argument, _clean(desc)) for argument, desc in arguments.items()])) - - print ";".join(env) # this line is for eval - PYTHONEND - ` - - if [ -n "$optionals" ]; then - _values optional $optionals - - fi - if [ -n "$subcommands" ]; then - _values subcommand $subcommands - fi - if [ -n "$arguments" ]; then - #_values argument $arguments - fi -} - - -_jp "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/_li Sun Mar 21 18:14:41 2021 +0100 @@ -0,0 +1,141 @@ +#compdef li libervia-cli li_dev jp jp_dev +# Libervia CLI: Command Line Interface for Libervia +# Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +#TODO: - caching (see _store_cache en _retrieve_cache) +# - filtering imposibles arguments +# - arguments (jids, files) + +PYTHON='python3' + +local optionals subcommands arguments +local context state state_descr line +typeset -A val_args + +_li() { + eval `/usr/bin/env $PYTHON 2> /dev/null <<- PYTHONEND + import re + from subprocess import check_output + + # import sys + # words_raw="li_dev " + ' '.join(sys.argv[1:]) # for debugging in a script + words_raw="$words" # $words is the command line currently completed + + words_all = words_raw.split() + prog_name = words_all[0] + + words_no_opt = [word for word in words_all if not word.startswith('-')] # command line without optional arguments + + choices_cache = {} + + ARG = r'[-a-z0-9_]' # charset accepted for an argument name + subcommands_re = re.compile(r"^ +{((?:" + ARG + r"+)(?:," + ARG + r"+)*)}", re.MULTILINE) + optionals_re = re.compile(r"^ {2,}(--?" + ARG + r"+(?: [A-Z_0-9]+)?(?:, --" + ARG + r"+(?: [A-Z_0-9]+)?)?)\n? {2,}(.*(?:\n {4,}.*)*$)", re.MULTILINE) + arguments_re = re.compile(r"^ {2,}([a-z_]" + ARG + r"*) {2,}(.*$)", re.MULTILINE) + clean_re = re.compile(r"(?P<prefix_spaces>^ +)|(?P<double_spaces> {2,})|(?P<newline>\n)|(?P<quote>')|(?P<suffix_spaces> +$)", re.MULTILINE) + + def _clean(desc): + def sub_clean(match): + matched_dict = match.groupdict() + matched = {matched for matched in matched_dict if matched_dict[matched]} + if matched.intersection(('prefix_spaces', 'suffix_spaces')): + return '' + elif matched.intersection(('double_spaces', 'newline')): + return ' ' + elif matched.intersection(('quote',)): + return r"'\''" + else: + raise ValueError + return clean_re.sub(sub_clean, desc) + + def parse_help(jp_help): + # parse the help returning subcommands, optionals arguments, and mandatory arguments + subcommands = subcommands_re.findall(jp_help) + subcommands = {subcommand:"" for subcommand in subcommands[0].split(',')} if subcommands else {} + optionals = dict(optionals_re.findall(jp_help)) + arguments = dict(arguments_re.findall(jp_help)) + for subcommand in subcommands: + subcommands[subcommand] = arguments.pop(subcommand, '') + return subcommands, optionals, arguments + + def get_choice(opt_choice): + choices = choices_cache.get(opt_choice) + if choices is not None: + return choices + if opt_choice == 'PROFILE': + profiles = check_output([prog_name, 'profile', 'list']) + choices = ":profile:(%s)" % ' '.join(profiles.split('\n')) + if choices: + choices_cache[opt_choice] = choices + return choices + else: + return "" + + def construct_opt(opts, desc): + # construct zsh's _arguments line for optional arguments + arg_lines = [] + for opt in opts.split(', '): + try: + opt_name, opt_choice = opt.split() + except ValueError: + # there is no argument + opt_name, opt_choice = opt, None + # arg_lines.append("'()%s[%s]%s'" % (opt_name+('=' if opt_name.startswith('--') else '+'), + arg_lines.append("'()%s[%s]%s'" % (opt_name, + _clean(desc), + "%s" % get_choice(opt_choice) if opt_choice else '' + )) + return ' '.join(arg_lines) + + current_args = [] + + while True: + # parse li's help recursively until words_no_opt doesn't correspond anymore to a subcommand + try: + current_args.append(words_no_opt.pop(0)) + jp_help = check_output(current_args + ['--help']) + # print "jp_help (%s):\n%s\n\n---\n" % (' '.join(current_args), jp_help) # for debugging + subcommands, optionals, arguments = parse_help(jp_help) + if words_no_opt[0] not in subcommands: + break + except IndexError: + break + + # now we fill the arrays so zsh can use them + env=[] + env.append("optionals=(%s)" % ' '.join(construct_opt(opt, desc) for opt, desc in optionals.items())) + env.append("subcommands=(%s)" % ' '.join(["'%s[%s]'" % (subcommand, _clean(desc)) for subcommand, desc in subcommands.items()])) + env.append("arguments=(%s)" % ' '.join(["'%s[%s]'" % (argument, _clean(desc)) for argument, desc in arguments.items()])) + + print ";".join(env) # this line is for eval + PYTHONEND + ` + + if [ -n "$optionals" ]; then + _values optional $optionals + + fi + if [ -n "$subcommands" ]; then + _values subcommand $subcommands + fi + if [ -n "$arguments" ]; then + #_values argument $arguments + fi +} + + +_li "$@"