Merge pull request #1134 from ZyX-I/man
Generate manual pages Replaces #1132
This commit is contained in:
commit
7e766f0ec8
|
@ -7,7 +7,7 @@ BUILDDIR = _build
|
|||
# Internal variables
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
ALLSPHINXOPTS = -T -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
|
||||
GH_PAGES_SOURCES = source Makefile
|
||||
GH_SOURCE_BRANCH = develop
|
||||
|
@ -32,3 +32,8 @@ html:
|
|||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
**************************************
|
||||
Powerline shell commands’ manual pages
|
||||
**************************************
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
commands/*
|
|
@ -0,0 +1,12 @@
|
|||
:orphan:
|
||||
|
||||
powerline-config manual page
|
||||
============================
|
||||
|
||||
.. automan:: powerline.commands.config
|
||||
:prog: powerline-config
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
:manpage:`powerline(1)`
|
|
@ -0,0 +1,12 @@
|
|||
:orphan:
|
||||
|
||||
powerline-daemon manual page
|
||||
============================
|
||||
|
||||
.. automan:: powerline.commands.daemon
|
||||
:prog: powerline-daemon
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
:manpage:`powerline(1)`
|
|
@ -0,0 +1,12 @@
|
|||
:orphan:
|
||||
|
||||
powerline-lint manual page
|
||||
==========================
|
||||
|
||||
.. automan:: powerline.commands.lint
|
||||
:prog: powerline-lint
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
:manpage:`powerline(1)`, :manpage:`powerline-config(1)`
|
|
@ -0,0 +1,12 @@
|
|||
:orphan:
|
||||
|
||||
powerline manual page
|
||||
=====================
|
||||
|
||||
.. automan:: powerline.commands.main
|
||||
:prog: powerline
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
:manpage:`powerline-daemon(1)`, :manpage:`powerline-config(1)`
|
|
@ -8,7 +8,10 @@ import sys
|
|||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(os.getcwd()))))
|
||||
sys.path.insert(0, os.path.abspath(os.getcwd()))
|
||||
|
||||
extensions = ['powerline_autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode']
|
||||
extensions = [
|
||||
'powerline_autodoc', 'powerline_automan',
|
||||
'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode',
|
||||
]
|
||||
source_suffix = '.rst'
|
||||
master_doc = 'index'
|
||||
project = 'Powerline'
|
||||
|
@ -31,6 +34,22 @@ latex_elements = {
|
|||
''',
|
||||
}
|
||||
|
||||
man_pages = []
|
||||
for doc in os.listdir(os.path.join(os.path.dirname(__file__), 'commands')):
|
||||
if doc.endswith('.rst'):
|
||||
name = doc[:-4]
|
||||
module = 'powerline.commands.{0}'.format(name)
|
||||
get_argparser = __import__(str(module), fromlist=[str('get_argparser')]).get_argparser
|
||||
parser = get_argparser()
|
||||
description = parser.description
|
||||
man_pages.append([
|
||||
'commands/' + name,
|
||||
'powerline' if name == 'main' else 'powerline-' + name,
|
||||
description,
|
||||
'',
|
||||
1
|
||||
])
|
||||
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if not on_rtd: # only import and set the theme if we’re building docs locally
|
||||
|
|
|
@ -15,6 +15,11 @@ Powerline
|
|||
tips-and-tricks
|
||||
license-and-credits
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
commands
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
|
|
|
@ -5,6 +5,14 @@ License and credits
|
|||
Powerline is licensed under the `MIT license
|
||||
<https://raw.github.com/Lokaltog/powerline/develop/LICENSE>`_.
|
||||
|
||||
..
|
||||
This document is parsed by powerline_automan.py module. Do not forget to
|
||||
check that file before altering this one. Specifically it expects
|
||||
``Authors`` and ``Contributors`` sections underlined by ``---``, a list of
|
||||
authors in format ``* `{name} <`` in the “Authors” section and fonts
|
||||
contributor name in format ``The glyphs in the font patcher are created by
|
||||
{name},`` in the “Contributors” section.
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
|
|
|
@ -0,0 +1,384 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import os
|
||||
import re
|
||||
import codecs
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
from docutils.parsers.rst import Directive
|
||||
from docutils.parsers.rst.directives import unchanged_required
|
||||
from docutils import nodes
|
||||
|
||||
from powerline.lib.unicode import u
|
||||
|
||||
|
||||
AUTHOR_LINE_START = '* `'
|
||||
GLYPHS_AUTHOR_LINE_START = '* The glyphs in the font patcher are created by '
|
||||
|
||||
|
||||
def get_authors():
|
||||
credits_file = os.path.join(os.path.dirname(__file__), 'license-and-credits.rst')
|
||||
authors = []
|
||||
glyphs_author = None
|
||||
with codecs.open(credits_file, encoding='utf-8') as CF:
|
||||
section = None
|
||||
prev_line = None
|
||||
for line in CF:
|
||||
line = line[:-1]
|
||||
if line and not line.replace('-', ''):
|
||||
section = prev_line
|
||||
elif section == 'Authors':
|
||||
if line.startswith(AUTHOR_LINE_START):
|
||||
authors.append(line[len(AUTHOR_LINE_START):line.index('<')].strip())
|
||||
elif section == 'Contributors':
|
||||
if line.startswith(GLYPHS_AUTHOR_LINE_START):
|
||||
assert(not glyphs_author)
|
||||
glyphs_author = line[len(GLYPHS_AUTHOR_LINE_START):line.index(',')].strip()
|
||||
prev_line = line
|
||||
return {
|
||||
'authors': ', '.join(authors),
|
||||
'glyphs_author': glyphs_author,
|
||||
}
|
||||
|
||||
|
||||
class AutoManSubparsers(object):
|
||||
def __init__(self):
|
||||
self.parsers = []
|
||||
|
||||
def add_parser(self, command, *args, **kwargs):
|
||||
self.parsers.append((command, AutoManParser(*args, **kwargs)))
|
||||
return self.parsers[-1][1]
|
||||
|
||||
|
||||
Argument = namedtuple('Argument', ('names', 'help', 'choices', 'metavar', 'required', 'nargs', 'is_option', 'is_long_option', 'is_short_option', 'multi', 'can_be_joined'))
|
||||
|
||||
|
||||
def parse_argument(*args, **kwargs):
|
||||
is_option = args[0].startswith('-')
|
||||
is_long_option = args[0].startswith('--')
|
||||
is_short_option = is_option and not is_long_option
|
||||
action = kwargs.get('action', 'store_true')
|
||||
multi = kwargs.get('action') in ('append',)
|
||||
nargs = kwargs.get('nargs') or (1 if kwargs.get('metavar') or action in ('append',) else 0)
|
||||
return Argument(
|
||||
names=args,
|
||||
help=u(kwargs.get('help', '')),
|
||||
choices=[str(choice) for choice in kwargs.get('choices', [])],
|
||||
metavar=kwargs.get('metavar') or args[-1].lstrip('-').replace('-', '_').upper(),
|
||||
required=kwargs.get('required', False) if is_option else (
|
||||
kwargs.get('nargs') not in ('?',)),
|
||||
nargs=nargs,
|
||||
multi=multi,
|
||||
is_option=is_option,
|
||||
is_long_option=is_long_option,
|
||||
is_short_option=is_short_option,
|
||||
can_be_joined=(is_short_option and not multi and not nargs)
|
||||
)
|
||||
|
||||
|
||||
class AutoManGroup(object):
|
||||
is_short_option = False
|
||||
is_option = False
|
||||
is_long_option = False
|
||||
can_be_joined = False
|
||||
|
||||
def __init__(self):
|
||||
self.arguments = []
|
||||
self.required = False
|
||||
|
||||
def add_argument(self, *args, **kwargs):
|
||||
self.arguments.append(parse_argument(*args, **kwargs))
|
||||
|
||||
|
||||
class SurroundWith():
|
||||
def __init__(self, ret, condition, start='[', end=']'):
|
||||
self.ret = ret
|
||||
self.condition = condition
|
||||
self.start = start
|
||||
self.end = end
|
||||
|
||||
def __enter__(self, *args):
|
||||
if self.condition:
|
||||
self.ret.append(nodes.Text(self.start))
|
||||
|
||||
def __exit__(self, *args):
|
||||
if self.condition:
|
||||
self.ret.append(nodes.Text(self.end))
|
||||
|
||||
|
||||
def insert_separators(ret, sep):
|
||||
for i in range(len(ret) - 1, 0, -1):
|
||||
ret.insert(i, nodes.Text(sep))
|
||||
return ret
|
||||
|
||||
|
||||
def format_usage_arguments(arguments, base_length=None):
|
||||
line = []
|
||||
prev_argument = None
|
||||
arg_indexes = [0]
|
||||
arguments = arguments[:]
|
||||
while arguments:
|
||||
argument = arguments.pop(0)
|
||||
if isinstance(argument, nodes.Text):
|
||||
line += [argument]
|
||||
continue
|
||||
can_join_arguments = (
|
||||
argument.is_short_option
|
||||
and prev_argument
|
||||
and prev_argument.can_be_joined
|
||||
and prev_argument.required == argument.required
|
||||
)
|
||||
if (
|
||||
prev_argument
|
||||
and not prev_argument.required
|
||||
and prev_argument.can_be_joined
|
||||
and not can_join_arguments
|
||||
):
|
||||
line.append(nodes.Text(']'))
|
||||
arg_indexes.append(len(line))
|
||||
if isinstance(argument, AutoManGroup):
|
||||
arguments = (
|
||||
[nodes.Text(' (')]
|
||||
+ insert_separators(argument.arguments[:], nodes.Text(' |'))
|
||||
+ [nodes.Text(' )')]
|
||||
+ arguments
|
||||
)
|
||||
else:
|
||||
if not can_join_arguments:
|
||||
line.append(nodes.Text(' '))
|
||||
with SurroundWith(line, not argument.required and not argument.can_be_joined):
|
||||
if argument.can_be_joined and not can_join_arguments and not argument.required:
|
||||
line.append(nodes.Text('['))
|
||||
if argument.is_option:
|
||||
line.append(nodes.strong())
|
||||
name = argument.names[0]
|
||||
if can_join_arguments:
|
||||
name = name[1:]
|
||||
# `--` is automatically transformed into – (EN DASH)
|
||||
# when parsing into HTML. We do not need this.
|
||||
line[-1] += [nodes.Text(char) for char in name]
|
||||
if argument.nargs:
|
||||
assert(argument.nargs in (1, '?'))
|
||||
with SurroundWith(line, argument.nargs == '?' and argument.is_option):
|
||||
if argument.is_long_option:
|
||||
line.append(nodes.Text('='))
|
||||
line.append(nodes.emphasis(text=argument.metavar))
|
||||
elif not argument.is_option:
|
||||
line.append(nodes.strong(text=argument.metavar))
|
||||
if argument.multi:
|
||||
line.append(nodes.Text('…'))
|
||||
prev_argument = argument
|
||||
if (
|
||||
prev_argument
|
||||
and prev_argument.can_be_joined
|
||||
and not prev_argument.required
|
||||
):
|
||||
line.append(nodes.Text(']'))
|
||||
arg_indexes.append(len(line))
|
||||
ret = []
|
||||
if base_length is None:
|
||||
ret = line
|
||||
else:
|
||||
length = base_length
|
||||
prev_arg_idx = arg_indexes.pop(0)
|
||||
while arg_indexes:
|
||||
next_arg_idx = arg_indexes.pop(0)
|
||||
arg_length = sum((len(element.astext()) for element in line[prev_arg_idx:next_arg_idx]))
|
||||
if length + arg_length > 68:
|
||||
ret.append(nodes.Text('\n' + (' ' * base_length)))
|
||||
length = base_length
|
||||
ret += line[prev_arg_idx:next_arg_idx]
|
||||
length += arg_length
|
||||
prev_arg_idx = next_arg_idx
|
||||
return ret
|
||||
|
||||
|
||||
LITERAL_RE = re.compile(r"`(.*?)'")
|
||||
|
||||
|
||||
def parse_argparse_text(text):
|
||||
rst_text = LITERAL_RE.subn(r'``\1``', text)[0]
|
||||
ret = []
|
||||
for i, text in enumerate(rst_text.split('``')):
|
||||
if i % 2 == 0:
|
||||
ret.append(nodes.Text(text))
|
||||
else:
|
||||
ret.append(nodes.literal(text=text))
|
||||
return ret
|
||||
|
||||
|
||||
def flatten_groups(arguments):
|
||||
for argument in arguments:
|
||||
if isinstance(argument, AutoManGroup):
|
||||
for group_argument in flatten_groups(argument.arguments):
|
||||
yield group_argument
|
||||
else:
|
||||
yield argument
|
||||
|
||||
|
||||
def format_arguments(arguments):
|
||||
return [nodes.definition_list(
|
||||
'', *[
|
||||
nodes.definition_list_item(
|
||||
'',
|
||||
nodes.term(
|
||||
# node.Text('') is required because otherwise for some
|
||||
# reason first name node is seen in HTML output as
|
||||
# `<strong>abc</strong>`.
|
||||
'', *([nodes.Text('')] + (
|
||||
insert_separators([
|
||||
nodes.strong('', '', *[nodes.Text(ch) for ch in name])
|
||||
for name in argument.names
|
||||
], ', ')
|
||||
if argument.is_option else
|
||||
# Unless node.Text('') is here metavar is written in
|
||||
# bold in the man page.
|
||||
[nodes.Text(''), nodes.emphasis(text=argument.metavar)]
|
||||
) + (
|
||||
[] if not argument.is_option or not argument.nargs else
|
||||
[nodes.Text(' '), nodes.emphasis('', argument.metavar)]
|
||||
))
|
||||
),
|
||||
nodes.definition('', nodes.paragraph('', *parse_argparse_text(argument.help or ''))),
|
||||
)
|
||||
for argument in flatten_groups(arguments)
|
||||
] + [
|
||||
nodes.definition_list_item(
|
||||
'',
|
||||
nodes.term(
|
||||
'', nodes.Text(''),
|
||||
nodes.strong(text='-h'),
|
||||
nodes.Text(', '),
|
||||
nodes.strong('', '', nodes.Text('-'), nodes.Text('-help')),
|
||||
),
|
||||
nodes.definition('', nodes.paragraph('', nodes.Text('Display help and exit.')))
|
||||
)
|
||||
]
|
||||
)]
|
||||
|
||||
|
||||
def format_subcommand_usage(arguments, subcommands, progname, base_length):
|
||||
return reduce((lambda a, b: a + reduce((lambda c, d: c + d), b, [])), [
|
||||
[
|
||||
[progname]
|
||||
+ format_usage_arguments(arguments)
|
||||
+ [nodes.Text(' '), nodes.strong(text=subcmd)]
|
||||
+ format_usage_arguments(subparser.arguments)
|
||||
+ [nodes.Text('\n')]
|
||||
for subcmd, subparser in subparsers.parsers
|
||||
]
|
||||
for subparsers in subcommands
|
||||
], [])
|
||||
|
||||
|
||||
def format_subcommands(subcommands):
|
||||
return reduce((lambda a, b: a + reduce((lambda c, d: c + d), b, [])), [
|
||||
[
|
||||
[
|
||||
nodes.section(
|
||||
'',
|
||||
nodes.title(text='Arguments specific to ' + subcmd + ' subcommand'),
|
||||
*format_arguments(subparser.arguments),
|
||||
ids=['subcmd-' + subcmd]
|
||||
)
|
||||
]
|
||||
for subcmd, subparser in subparsers.parsers
|
||||
]
|
||||
for subparsers in subcommands
|
||||
], [])
|
||||
|
||||
|
||||
class AutoManParser(object):
|
||||
def __init__(self, description=None, help=None):
|
||||
self.description = description
|
||||
self.help = help
|
||||
self.arguments = []
|
||||
self.subcommands = []
|
||||
|
||||
def add_argument(self, *args, **kwargs):
|
||||
self.arguments.append(parse_argument(*args, **kwargs))
|
||||
|
||||
def add_subparsers(self):
|
||||
self.subcommands.append(AutoManSubparsers())
|
||||
return self.subcommands[-1]
|
||||
|
||||
def add_mutually_exclusive_group(self):
|
||||
self.arguments.append(AutoManGroup())
|
||||
return self.arguments[-1]
|
||||
|
||||
def automan_usage(self, prog):
|
||||
block = nodes.literal_block()
|
||||
progname = nodes.strong()
|
||||
progname += [nodes.Text(prog)]
|
||||
base_length = len(prog)
|
||||
if self.subcommands:
|
||||
block += format_subcommand_usage(self.arguments, self.subcommands, progname, base_length)
|
||||
else:
|
||||
block += [progname]
|
||||
block += format_usage_arguments(self.arguments, base_length)
|
||||
return [block]
|
||||
|
||||
def automan_description(self):
|
||||
ret = []
|
||||
if self.help:
|
||||
ret += parse_argparse_text(self.help)
|
||||
ret += format_arguments(self.arguments) + format_subcommands(self.subcommands)
|
||||
return ret
|
||||
|
||||
|
||||
class AutoMan(Directive):
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
option_spec = dict(prog=unchanged_required)
|
||||
has_content = False
|
||||
|
||||
def run(self):
|
||||
module = self.arguments[0]
|
||||
template_args = {}
|
||||
template_args.update(get_authors())
|
||||
get_argparser = __import__(str(module), fromlist=[str('get_argparser')]).get_argparser
|
||||
parser = get_argparser(AutoManParser)
|
||||
synopsis_section = nodes.section(
|
||||
'',
|
||||
nodes.title(text='Synopsis'),
|
||||
ids=['synopsis-section'],
|
||||
)
|
||||
synopsis_section += parser.automan_usage(self.options['prog'])
|
||||
description_section = nodes.section(
|
||||
'', nodes.title(text='Description'),
|
||||
ids=['description-section'],
|
||||
)
|
||||
description_section += parser.automan_description()
|
||||
author_section = nodes.section(
|
||||
'', nodes.title(text='Author'),
|
||||
nodes.paragraph(
|
||||
'',
|
||||
nodes.Text('Written by {authors} and contributors. The glyphs in the font patcher are created by {glyphs_author}.'.format(
|
||||
**get_authors()
|
||||
))
|
||||
),
|
||||
ids=['author-section']
|
||||
)
|
||||
issues_url = 'https://github.com/Lokaltog/powerline/issues'
|
||||
reporting_bugs_section = nodes.section(
|
||||
'', nodes.title(text='Reporting bugs'),
|
||||
nodes.paragraph(
|
||||
'',
|
||||
nodes.Text('Report {prog} bugs to '.format(
|
||||
prog=self.options['prog'])),
|
||||
nodes.reference(
|
||||
issues_url, issues_url,
|
||||
refuri=issues_url,
|
||||
internal=False,
|
||||
),
|
||||
nodes.Text('.'),
|
||||
),
|
||||
ids=['reporting-bugs-section']
|
||||
)
|
||||
return [synopsis_section, description_section, author_section, reporting_bugs_section]
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_directive('automan', AutoMan)
|
|
@ -0,0 +1,75 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (division, absolute_import, print_function)
|
||||
|
||||
import argparse
|
||||
|
||||
import powerline.bindings.config as config
|
||||
|
||||
|
||||
class StrFunction(object):
|
||||
def __init__(self, function, name=None):
|
||||
self.name = name or function.__name__
|
||||
self.function = function
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
self.function(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
TMUX_ACTIONS = {
|
||||
'source': StrFunction(config.source_tmux_files, 'source'),
|
||||
}
|
||||
|
||||
|
||||
SHELL_ACTIONS = {
|
||||
'command': StrFunction(config.shell_command, 'command'),
|
||||
'uses': StrFunction(config.uses),
|
||||
}
|
||||
|
||||
|
||||
class ConfigArgParser(argparse.ArgumentParser):
|
||||
def parse_args(self, *args, **kwargs):
|
||||
ret = super(ConfigArgParser, self).parse_args(*args, **kwargs)
|
||||
if not hasattr(ret, 'function'):
|
||||
# In Python-3* `powerline-config` (without arguments) raises
|
||||
# AttributeError. I have not found any standard way to display same
|
||||
# error message as in Python-2*.
|
||||
self.error('too few arguments')
|
||||
return ret
|
||||
|
||||
|
||||
def get_argparser(ArgumentParser=ConfigArgParser):
|
||||
parser = ArgumentParser(description='Script used to obtain powerline configuration.')
|
||||
subparsers = parser.add_subparsers()
|
||||
tmux_parser = subparsers.add_parser('tmux', help='Tmux-specific commands')
|
||||
tmux_parser.add_argument(
|
||||
'function',
|
||||
choices=tuple(TMUX_ACTIONS.values()),
|
||||
metavar='ACTION',
|
||||
type=(lambda v: TMUX_ACTIONS.get(v)),
|
||||
help='If action is `source\' then version-specific tmux configuration files are sourced.'
|
||||
)
|
||||
|
||||
shell_parser = subparsers.add_parser('shell', help='Shell-specific commands')
|
||||
shell_parser.add_argument(
|
||||
'function',
|
||||
choices=tuple(SHELL_ACTIONS.values()),
|
||||
type=(lambda v: SHELL_ACTIONS.get(v)),
|
||||
metavar='ACTION',
|
||||
help='If action is `command\' then preferred powerline command is output, if it is `uses\' then powerline-config script will exit with 1 if specified component is disabled and 0 otherwise.',
|
||||
)
|
||||
shell_parser.add_argument(
|
||||
'component',
|
||||
nargs='?',
|
||||
choices=('tmux', 'prompt'),
|
||||
metavar='COMPONENT',
|
||||
help='Only applicable for `uses\' subcommand: makes `powerline-config\' exit with 0 if specific component is enabled and with 1 otherwise. `tmux\' component stands for tmux bindings (e.g. those that notify tmux about current directory changes), `prompt\' component stands for shell prompt.'
|
||||
)
|
||||
shell_parser.add_argument(
|
||||
'-s', '--shell',
|
||||
metavar='SHELL',
|
||||
help='Shell for which query is run',
|
||||
)
|
||||
return parser
|
|
@ -0,0 +1,15 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (division, absolute_import, print_function)
|
||||
|
||||
import argparse
|
||||
|
||||
|
||||
def get_argparser(ArgumentParser=argparse.ArgumentParser):
|
||||
parser = ArgumentParser(description='Daemon that improves powerline performance.')
|
||||
parser.add_argument('--quiet', '-q', action='store_true', help='Without other options: do not complain about already running powerline-daemon instance. Will still exit with 1. With `--kill\' and `--replace\': do not show any messages. With `--foreground\': ignored. Does not silence exceptions in any case.')
|
||||
parser.add_argument('--socket', '-s', help='Specify socket which will be used for connecting to daemon.')
|
||||
arggr = parser.add_mutually_exclusive_group().add_argument
|
||||
arggr('--kill', '-k', action='store_true', help='Kill an already running instance.')
|
||||
arggr('--foreground', '-f', action='store_true', help='Run in the foreground (don’t daemonize).')
|
||||
arggr('--replace', '-r', action='store_true', help='Replace an already running instance.')
|
||||
return parser
|
|
@ -0,0 +1,11 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import (division, absolute_import, print_function)
|
||||
|
||||
import argparse
|
||||
|
||||
|
||||
def get_argparser(ArgumentParser=argparse.ArgumentParser):
|
||||
parser = ArgumentParser(description='Powerline configuration checker.')
|
||||
parser.add_argument('-p', '--config_path', action='append', metavar='PATH', help='Paths where configuration should be checked, in order. You must supply all paths necessary for powerline to work, checking partial (e.g. only user overrides) configuration is not supported.')
|
||||
parser.add_argument('-d', '--debug', action='store_const', const=True, help='Display additional information. Used for debugging `powerline-lint\' itself, not for debugging configuration.')
|
||||
return parser
|
|
@ -0,0 +1,70 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
# WARNING: using unicode_literals causes errors in argparse
|
||||
from __future__ import (division, absolute_import, print_function)
|
||||
|
||||
import argparse
|
||||
|
||||
from powerline.lib import mergedicts, parsedotval
|
||||
|
||||
|
||||
def mergeargs(argvalue):
|
||||
if not argvalue:
|
||||
return None
|
||||
r = {}
|
||||
for subval in argvalue:
|
||||
mergedicts(r, dict([subval]))
|
||||
return r
|
||||
|
||||
|
||||
def finish_args(args):
|
||||
if args.config:
|
||||
args.config = mergeargs((parsedotval(v) for v in args.config))
|
||||
if args.theme_option:
|
||||
args.theme_option = mergeargs((parsedotval(v) for v in args.theme_option))
|
||||
else:
|
||||
args.theme_option = {}
|
||||
if args.renderer_arg:
|
||||
args.renderer_arg = mergeargs((parsedotval(v) for v in args.renderer_arg))
|
||||
|
||||
|
||||
def get_argparser(ArgumentParser=argparse.ArgumentParser):
|
||||
parser = ArgumentParser(description='Powerline prompt and statusline script.')
|
||||
parser.add_argument('ext', nargs=1, help='Extension: application for which powerline command is launched (usually `shell\' or `tmux\').')
|
||||
parser.add_argument('side', nargs='?', choices=('left', 'right', 'above', 'aboveleft'), help='Side: `left\' and `right\' represent left and right side respectively, `above\' emits lines that are supposed to be printed just above the prompt and `aboveleft\' is like concatenating `above\' with `left\' with the exception that only one Python instance is used in this case.')
|
||||
parser.add_argument(
|
||||
'-r', '--renderer_module', metavar='MODULE', type=str,
|
||||
help='Renderer module. Usually something like `.bash\' or `.zsh\', is supposed to be set only in shell-specific bindings file.'
|
||||
)
|
||||
parser.add_argument('-w', '--width', type=int, help='Maximum prompt with. Triggers truncation of some segments.')
|
||||
parser.add_argument('--last_exit_code', metavar='INT', type=int, help='Last exit code.')
|
||||
parser.add_argument('--last_pipe_status', metavar='LIST', default='', type=lambda s: [int(status) for status in s.split()], help='Like above, but is supposed to contain space-separated array of statuses, representing exit statuses of commands in one pipe.')
|
||||
parser.add_argument('--jobnum', metavar='INT', type=int, help='Number of jobs.')
|
||||
parser.add_argument('-c', '--config', metavar='KEY.KEY=VALUE', action='append', help='Configuration overrides for `config.json\'. Is translated to a dictionary and merged with the dictionary obtained from actual JSON configuration: KEY.KEY=VALUE is translated to `{"KEY": {"KEY": VALUE}}\' and then merged recursively. VALUE may be any JSON value, values that are not `null\', `true\', `false\', start with digit, `{\', `[\' are treated like strings. If VALUE is omitted then corresponding key is removed.')
|
||||
parser.add_argument('-t', '--theme_option', metavar='THEME.KEY.KEY=VALUE', action='append', help='Like above, but theme-specific. THEME should point to an existing and used theme to have any effect, but it is fine to use any theme here.')
|
||||
parser.add_argument('-R', '--renderer_arg', metavar='KEY=VAL', action='append', help='Like above, but provides argument for renderer. Is supposed to be used only by shell bindings to provide various data like last_exit_code or last_pipe_status (they are not using `--renderer_arg\' for historical resons: `--renderer_arg\' was added later).')
|
||||
parser.add_argument('-p', '--config_path', action='append', metavar='PATH', help='Path to configuration directory. If it is present then configuration files will only be seeked in the provided path. May be provided multiple times to search in a list of directories.')
|
||||
parser.add_argument('--socket', metavar='ADDRESS', type=str, help='Socket address to use in daemon clients. Is always UNIX domain socket on linux and file socket on Mac OS X. Not used here, present only for compatibility with other powerline clients. This argument must always be the first one and be in a form `--socket ADDRESS\': no `=\' or short form allowed (in other powerline clients, not here).')
|
||||
return parser
|
||||
|
||||
|
||||
def write_output(args, powerline, segment_info, write, encoding):
|
||||
if args.renderer_arg:
|
||||
segment_info.update(args.renderer_arg)
|
||||
if args.side.startswith('above'):
|
||||
for line in powerline.render_above_lines(
|
||||
width=args.width,
|
||||
segment_info=segment_info,
|
||||
mode=segment_info['environ'].get('_POWERLINE_MODE'),
|
||||
):
|
||||
write(line.encode(encoding, 'replace'))
|
||||
write(b'\n')
|
||||
args.side = args.side[len('above'):]
|
||||
|
||||
if args.side:
|
||||
rendered = powerline.render(
|
||||
width=args.width,
|
||||
side=args.side,
|
||||
segment_info=segment_info,
|
||||
mode=segment_info['environ'].get('_POWERLINE_MODE'),
|
||||
)
|
||||
write(rendered.encode(encoding, 'replace'))
|
|
@ -1,18 +1,8 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
# WARNING: using unicode_literals causes errors in argparse
|
||||
from __future__ import (division, absolute_import, print_function)
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
from powerline import Powerline
|
||||
from powerline.lib import mergedicts, parsedotval
|
||||
|
||||
|
||||
def mergeargs(argvalue):
|
||||
if not argvalue:
|
||||
return None
|
||||
r = {}
|
||||
for subval in argvalue:
|
||||
mergedicts(r, dict([subval]))
|
||||
return r
|
||||
from powerline.lib import mergedicts
|
||||
|
||||
|
||||
class ShellPowerline(Powerline):
|
||||
|
@ -47,60 +37,3 @@ class ShellPowerline(Powerline):
|
|||
|
||||
def do_setup(self, obj):
|
||||
obj.powerline = self
|
||||
|
||||
|
||||
def get_argparser(parser=None, *args, **kwargs):
|
||||
if not parser:
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser
|
||||
p = parser(*args, **kwargs)
|
||||
p.add_argument('ext', nargs=1, help='Extension: application for which powerline command is launched (usually `shell\' or `tmux\')')
|
||||
p.add_argument('side', nargs='?', choices=('left', 'right', 'above', 'aboveleft'), help='Side: `left\' and `right\' represent left and right side respectively, `above\' emits lines that are supposed to be printed just above the prompt and `aboveleft\' is like concatenating `above\' with `left\' with the exception that only one Python instance is used in this case.')
|
||||
p.add_argument(
|
||||
'-r', '--renderer_module', metavar='MODULE', type=str,
|
||||
help='Renderer module. Usually something like `.bash\' or `.zsh\', is supposed to be set only in shell-specific bindings file.'
|
||||
)
|
||||
p.add_argument('-w', '--width', type=int, help='Maximum prompt with. Triggers truncation of some segments')
|
||||
p.add_argument('--last_exit_code', metavar='INT', type=int, help='Last exit code')
|
||||
p.add_argument('--last_pipe_status', metavar='LIST', default='', type=lambda s: [int(status) for status in s.split()], help='Like above, but is supposed to contain space-separated array of statuses, representing exit statuses of commands in one pipe.')
|
||||
p.add_argument('--jobnum', metavar='INT', type=int, help='Number of jobs.')
|
||||
p.add_argument('-c', '--config', metavar='KEY.KEY=VALUE', action='append', help='Configuration overrides for `config.json\'. Is translated to a dictionary and merged with the dictionary obtained from actual JSON configuration: KEY.KEY=VALUE is translated to `{"KEY": {"KEY": VALUE}}\' and then merged recursively. VALUE may be any JSON value, values that are not `null\', `true\', `false\', start with digit, `{\', `[\' are treated like strings. If VALUE is omitted then corresponding key is removed.')
|
||||
p.add_argument('-t', '--theme_option', metavar='THEME.KEY.KEY=VALUE', action='append', help='Like above, but theme-specific. THEME should point to an existing and used theme to have any effect, but it is fine to use any theme here.')
|
||||
p.add_argument('-R', '--renderer_arg', metavar='KEY=VAL', action='append', help='Like above, but provides argument for renderer. Is supposed to be used only by shell bindings to provide various data like last_exit_code or last_pipe_status (they are not using --renderer_arg for historical resons: renderer_arg was added later).')
|
||||
p.add_argument('-p', '--config_path', action='append', metavar='PATH', help='Path to configuration directory. If it is present then configuration files will only be seeked in the provided path. May be provided multiple times to search in a list of directories.')
|
||||
p.add_argument('--socket', metavar='ADDRESS', type=str, help='Socket address to use in daemon clients. Is always UNIX domain socket on linux and file socket on Mac OS X. Not used here, present only for compatibility with other powerline clients. This argument must always be the first one and be in a form `--socket ADDRESS\': no `=\' or short form allowed (in other powerline clients, not here).')
|
||||
return p
|
||||
|
||||
|
||||
def finish_args(args):
|
||||
if args.config:
|
||||
args.config = mergeargs((parsedotval(v) for v in args.config))
|
||||
if args.theme_option:
|
||||
args.theme_option = mergeargs((parsedotval(v) for v in args.theme_option))
|
||||
else:
|
||||
args.theme_option = {}
|
||||
if args.renderer_arg:
|
||||
args.renderer_arg = mergeargs((parsedotval(v) for v in args.renderer_arg))
|
||||
|
||||
|
||||
def write_output(args, powerline, segment_info, write, encoding):
|
||||
if args.renderer_arg:
|
||||
segment_info.update(args.renderer_arg)
|
||||
if args.side.startswith('above'):
|
||||
for line in powerline.render_above_lines(
|
||||
width=args.width,
|
||||
segment_info=segment_info,
|
||||
mode=segment_info['environ'].get('_POWERLINE_MODE'),
|
||||
):
|
||||
write(line.encode(encoding, 'replace'))
|
||||
write(b'\n')
|
||||
args.side = args.side[len('above'):]
|
||||
|
||||
if args.side:
|
||||
rendered = powerline.render(
|
||||
width=args.width,
|
||||
side=args.side,
|
||||
segment_info=segment_info,
|
||||
mode=segment_info['environ'].get('_POWERLINE_MODE'),
|
||||
)
|
||||
write(rendered.encode(encoding, 'replace'))
|
||||
|
|
|
@ -1,74 +1,22 @@
|
|||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
'''Script used to obtain powerline configuration'''
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import argparse
|
||||
|
||||
try:
|
||||
import powerline.bindings.config as config
|
||||
from powerline.commands.config import get_argparser
|
||||
except ImportError:
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__)))))
|
||||
import powerline.bindings.config as config
|
||||
from powerline.commands.config import get_argparser
|
||||
|
||||
|
||||
TMUX_ACTIONS = {
|
||||
'source': config.source_tmux_files,
|
||||
}
|
||||
|
||||
|
||||
SHELL_ACTIONS = {
|
||||
'command': config.shell_command,
|
||||
'uses': config.uses,
|
||||
}
|
||||
import powerline.bindings.config as config
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
subparsers = parser.add_subparsers()
|
||||
tmux_parser = subparsers.add_parser('tmux', help='Tmux-specific commands')
|
||||
tmux_parser.add_argument(
|
||||
'function',
|
||||
choices=tuple(TMUX_ACTIONS.values()),
|
||||
metavar='action',
|
||||
type=(lambda v: TMUX_ACTIONS.get(v)),
|
||||
help='If action is `source\' then version-specific tmux configuration files are sourced.'
|
||||
)
|
||||
|
||||
shell_parser = subparsers.add_parser('shell', help='Shell-specific commands')
|
||||
shell_parser.add_argument(
|
||||
'function',
|
||||
choices=tuple(SHELL_ACTIONS.values()),
|
||||
type=(lambda v: SHELL_ACTIONS.get(v)),
|
||||
metavar='action',
|
||||
help='If action is `command\' then preferred powerline command is output, if it is `uses\' then powerline-config script will exit with 1 if specified component is disabled and 0 otherwise.',
|
||||
)
|
||||
shell_parser.add_argument(
|
||||
'component',
|
||||
nargs='?',
|
||||
choices=('tmux', 'prompt'),
|
||||
metavar='component',
|
||||
)
|
||||
shell_parser.add_argument(
|
||||
'-s', '--shell',
|
||||
nargs='?',
|
||||
help='Shell for which query is run',
|
||||
)
|
||||
|
||||
parser = get_argparser()
|
||||
args = parser.parse_args()
|
||||
|
||||
pl = config.create_powerline_logger(args)
|
||||
|
||||
try:
|
||||
function = args.function
|
||||
except AttributeError:
|
||||
# In Python-3* `powerline-config` (without arguments) raises
|
||||
# AttributeError. I have not found any standard way to display same
|
||||
# error message as in Python-2*.
|
||||
parser.error('too few arguments')
|
||||
else:
|
||||
function(pl, args)
|
||||
args.function(pl, args)
|
||||
|
|
|
@ -14,10 +14,14 @@ from time import sleep
|
|||
from functools import partial
|
||||
from io import BytesIO
|
||||
|
||||
from powerline.shell import get_argparser, finish_args, ShellPowerline, write_output
|
||||
from powerline.shell import ShellPowerline
|
||||
from powerline.commands.main import finish_args, write_output
|
||||
from powerline.lib.monotonic import monotonic
|
||||
from powerline.lib.encoding import get_preferred_output_encoding
|
||||
|
||||
from powerline.commands.main import get_argparser as get_main_argparser
|
||||
from powerline.commands.daemon import get_argparser as get_daemon_argparser
|
||||
|
||||
|
||||
is_daemon = False
|
||||
platform = sys.platform.lower()
|
||||
|
@ -41,7 +45,7 @@ class NonInteractiveArgParser(ArgumentParser):
|
|||
raise Exception(self.format_usage())
|
||||
|
||||
|
||||
parser = get_argparser(parser=NonInteractiveArgParser, description='powerline daemon')
|
||||
parser = get_main_argparser(NonInteractiveArgParser)
|
||||
|
||||
EOF = b'EOF\0\0'
|
||||
|
||||
|
@ -350,14 +354,7 @@ def lockpidfile():
|
|||
def main():
|
||||
global address
|
||||
global pidfile
|
||||
p = ArgumentParser(description='Daemon to improve the performance of powerline')
|
||||
p.add_argument('--quiet', '-q', action='store_true', help='Without other options: do not complain about already running powerline-daemon instance. Will still exit with 1. With `--kill\' and `--replace\': do not show any messages. With `--foreground\': ignored. Does not silence exceptions in any case.')
|
||||
p.add_argument('--socket', '-s', help='Specify socket which will be used for connecting to daemon.')
|
||||
a = p.add_mutually_exclusive_group().add_argument
|
||||
a('--kill', '-k', action='store_true', help='Kill an already running instance')
|
||||
a('--foreground', '-f', action='store_true', help='Run in the foreground (dont daemonize)')
|
||||
a('--replace', '-r', action='store_true', help='Replace an already running instance')
|
||||
args = p.parse_args()
|
||||
args = get_daemon_argparser().parse_args()
|
||||
|
||||
if args.socket:
|
||||
address = args.socket
|
||||
|
|
|
@ -1,20 +1,13 @@
|
|||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
'''Powerline configuration checker.'''
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from powerline.lint import check
|
||||
from powerline.commands.lint import get_argparser
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('-p', '--config_path', action='append', metavar='PATH')
|
||||
parser.add_argument('-d', '--debug', action='store_const', const=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parser.parse_args()
|
||||
args = get_argparser().parse_args()
|
||||
sys.exit(check(args.config_path, args.debug))
|
||||
|
|
|
@ -5,7 +5,7 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
|||
import argparse
|
||||
import codecs
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
|
||||
from subprocess import check_output, check_call
|
||||
from getpass import getpass
|
||||
|
@ -107,9 +107,41 @@ def create_ebuilds(version_string, overlay, user, **kwargs):
|
|||
('app-vim', 'powerline-vim'),
|
||||
):
|
||||
pdir = os.path.join(overlay, category, pn)
|
||||
v1_0 = os.path.join(pdir, '{0}-1.0.ebuild'.format(pn))
|
||||
live_ebuild = None
|
||||
for ebuild in os.listdir(pdir):
|
||||
if ebuild.endswith('.ebuild') and '9999' in ebuild:
|
||||
live_ebuild = os.path.join(pdir, ebuild)
|
||||
break
|
||||
assert(live_ebuild)
|
||||
vcur = os.path.join(pdir, '{0}-{1}.ebuild'.format(pn, version_string))
|
||||
shutil.copy2(v1_0, vcur)
|
||||
with open(live_ebuild) as LEF:
|
||||
with open(vcur, 'w') as F:
|
||||
dropnext = False
|
||||
for line in LEF:
|
||||
if line.startswith('EGIT'):
|
||||
# Drop all EGIT_… and the next empty line
|
||||
dropnext = True
|
||||
next_re = re.compile('^$')
|
||||
continue
|
||||
if dropnext:
|
||||
assert(next_re.match(line))
|
||||
dropnext = False
|
||||
continue
|
||||
if line.startswith('# Note the lack of an assignment to ${S}'):
|
||||
next_re = re.compile('^#')
|
||||
dropnext = True
|
||||
line = 'S="${WORKDIR}/${MY_P}"\n'
|
||||
if line.startswith('inherit'):
|
||||
line = line.replace(' git-r3', '')
|
||||
line += '\n'
|
||||
line += 'MY_PN="powerline-status"\n'
|
||||
line += 'MY_P="${MY_PN}-${PV}"'
|
||||
line += '\n'
|
||||
elif line.startswith('HOMEPAGE'):
|
||||
line += 'SRC_URI="mirror://pypi/p/${MY_PN}/${MY_P}.tar.gz"\n'
|
||||
elif line.startswith('KEYWORDS'):
|
||||
line = 'KEYWORDS="~amd64 ~ppc ~x86 ~x86-fbsd"\n'
|
||||
F.write(line)
|
||||
new_files.append(vcur)
|
||||
check_call(['ebuild', vcur, 'manifest'])
|
||||
new_files.append(os.path.join(pdir, 'Manifest'))
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
'''Powerline prompt and statusline script.'''
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
from powerline.shell import ShellPowerline, get_argparser, finish_args, write_output
|
||||
from powerline.shell import ShellPowerline
|
||||
except ImportError:
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__)))))
|
||||
from powerline.shell import ShellPowerline, get_argparser, finish_args, write_output
|
||||
from powerline.shell import ShellPowerline
|
||||
|
||||
from powerline.commands.main import get_argparser, finish_args, write_output
|
||||
from powerline.lib.unicode import get_preferred_output_encoding
|
||||
|
||||
|
||||
|
@ -24,7 +23,7 @@ else:
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = get_argparser(description=__doc__).parse_args()
|
||||
args = get_argparser().parse_args()
|
||||
finish_args(args)
|
||||
powerline = ShellPowerline(args, run_once=True)
|
||||
segment_info = {'args': args, 'environ': os.environ}
|
||||
|
|
|
@ -11,7 +11,7 @@ if sys.version_info < (3,):
|
|||
else:
|
||||
from io import StringIO as StrIO
|
||||
|
||||
from powerline.shell import get_argparser, finish_args
|
||||
from powerline.commands.main import get_argparser, finish_args
|
||||
|
||||
from tests import TestCase
|
||||
from tests.lib import replace_attr
|
||||
|
|
Loading…
Reference in New Issue