From 6257e788144bf7b3a22d779e05fde1c88a5b72ee Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Wed, 13 Dec 2017 15:50:14 -0700 Subject: [PATCH] Add option for log and report command to (not) output via pager * 'report' command now outputs via pager by default too. * Add `pager` config option. * Add command line options to enable/disable pager to 'log' and 'report' command. --- CHANGELOG.md | 3 + docs/user-guide/commands.md | 8 ++ docs/user-guide/configuration.md | 8 ++ watson/cli.py | 133 +++++++++++++++++++++---------- 4 files changed, 109 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 487269f3..519920a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ CHANGELOG This document records all notable changes to Watson. This project adheres to [Semantic Versioning](http://semver.org/). +* Added: the `report` and `log` commands' output can no selectively be run + through a pager. + ## 1.5.2 (2017-08-02) * Fixed: Follow up on the `config` command fix (#161) diff --git a/docs/user-guide/commands.md b/docs/user-guide/commands.md index aa675734..99bca713 100644 --- a/docs/user-guide/commands.md +++ b/docs/user-guide/commands.md @@ -127,6 +127,9 @@ You can also use special shortcut options for easier timespan control: and `--year`, `--month` and `--week` to the current year, month or week respectively. +If you are outputting to the terminal, you can selectively enable a pager +through the `--pager` option. + You can limit the log to a project or a tag using the `--project` and `--tag` options. They can be specified several times each to add multiple projects or tags to the log. @@ -174,6 +177,7 @@ Flag | Help `-p, --project TEXT` | Logs activity only for the given project. You can add other projects by using this option several times. `-T, --tag TEXT` | Logs activity only for frames containing the given tag. You can add several tags by using this option multiple times `-j, --json` | Format the log in JSON instead of plain text +`-g, --pager / -G, --no-pager` | (Don't) view output through a pager. `--help` | Show this message and exit. ## `merge` @@ -329,6 +333,9 @@ You can limit the report to a project or a tag using the `--project` and `--tag` options. They can be specified several times each to add multiple projects or tags to the report. +If you are outputting to the terminal, you can selectively enable a pager +through the `--pager` option. + You can change the output format for the report from *plain text* to *JSON* by using the `--json` option. @@ -413,6 +420,7 @@ Flag | Help `-p, --project TEXT` | Reports activity only for the given project. You can add other projects by using this option several times. `-T, --tag TEXT` | Reports activity only for frames containing the given tag. You can add several tags by using this option multiple times `-j, --json` | Format the report in JSON instead of plain text +`-g, --pager / -G, --no-pager` | (Don't) view output through a pager. `--help` | Show this message and exit. ## `restart` diff --git a/docs/user-guide/configuration.md b/docs/user-guide/configuration.md index 9541d8ae..96e576b3 100644 --- a/docs/user-guide/configuration.md +++ b/docs/user-guide/configuration.md @@ -104,6 +104,13 @@ If `true`, the output of the `log` command will include the currently running frame (if any) by default. The option can be overridden on the command line with the `-c/-C` resp. `--current/--no-current` flags. +#### `options.pager` + +If `true` (or not set), the output of the `log` and `report` command will be +run through a pager by default. The option can be overridden on the command +line with the `-g/-G` or `--pager/--no-pager` flags. If other commands output +in colour, but `log` or `report` do not, try disabling the pager. + #### `options.report_current` If `true`, the output of the `report` command will include the currently @@ -205,6 +212,7 @@ stop_on_restart = false date_format = %Y.%m.%d time_format = %H:%M:%S%z log_current = false +log_pager = true report_current = false ``` diff --git a/watson/cli.py b/watson/cli.py index 045819b7..2006cd7e 100644 --- a/watson/cli.py +++ b/watson/cli.py @@ -352,9 +352,11 @@ def status(watson, project, tags, elapsed): "times") @click.option('-j', '--json', 'format_json', is_flag=True, help="Format the report in JSON instead of plain text") +@click.option('-g/-G', '--pager/--no-pager', 'pager', default=None, + help="(Don't) view output through a pager.") @click.pass_obj def report(watson, current, from_, to, projects, - tags, year, month, week, day, format_json): + tags, year, month, week, day, format_json, pager): """ Display a report of the time spent on each project. @@ -374,6 +376,9 @@ def report(watson, current, from_, to, projects, `--tag` options. They can be specified several times each to add multiple projects or tags to the report. + If you are outputting to the terminal, you can selectively enable a pager + through the `--pager` option. + You can change the output format for the report from *plain text* to *JSON* by using the `--json` option. @@ -452,46 +457,67 @@ def report(watson, current, from_, to, projects, if format_json: click.echo(json.dumps(report, indent=4, sort_keys=True)) + return + + lines = [] + # use the pager, or print directly to the terminal + if pager or (pager is None and + watson.config.getboolean('options', 'pager', True)): + + def _print(line): + lines.append(line) + + def _final_print(lines): + click.echo_via_pager('\n'.join(lines)) else: - click.echo('{} -> {}\n'.format( - style('date', '{:ddd DD MMMM YYYY}'.format( - arrow.get(report['timespan']['from']) + + def _print(line): + click.echo(line) + + def _final_print(lines): + pass + + _print('{} -> {}\n'.format( + style('date', '{:ddd DD MMMM YYYY}'.format( + arrow.get(report['timespan']['from']) + )), + style('date', '{:ddd DD MMMM YYYY}'.format( + arrow.get(report['timespan']['to']) + )) + )) + + projects = report['projects'] + for project in projects: + _print('{project} - {time}'.format( + time=style('time', format_timedelta( + datetime.timedelta(seconds=project['time']) )), - style('date', '{:ddd DD MMMM YYYY}'.format( - arrow.get(report['timespan']['to']) - )) - )) - - projects = report['projects'] - for project in projects: - click.echo('{project} - {time}'.format( - time=style('time', format_timedelta( - datetime.timedelta(seconds=project['time']) - )), - project=style('project', project['name']) - )) + project=style('project', project['name']) + )) - tags = project['tags'] - if tags: - longest_tag = max(len(tag) for tag in tags or ['']) - - for tag in tags: - click.echo('\t[{tag} {time}]'.format( - time=style('time', '{:>11}'.format(format_timedelta( - datetime.timedelta(seconds=tag['time']) - ))), - tag=style('tag', '{:<{}}'.format( - tag['name'], longest_tag - )), - )) - click.echo() - - if len(projects) > 1: - click.echo('Total: {}'.format( - style('time', '{}'.format(format_timedelta( - datetime.timedelta(seconds=report['time']) - ))) - )) + tags = project['tags'] + if tags: + longest_tag = max(len(tag) for tag in tags or ['']) + + for tag in tags: + _print('\t[{tag} {time}]'.format( + time=style('time', '{:>11}'.format(format_timedelta( + datetime.timedelta(seconds=tag['time']) + ))), + tag=style('tag', '{:<{}}'.format( + tag['name'], longest_tag + )), + )) + _print("") + + if len(projects) > 1: + _print('Total: {}'.format( + style('time', '{}'.format(format_timedelta( + datetime.timedelta(seconds=report['time']) + ))) + )) + + _final_print(lines) @cli.command() @@ -529,9 +555,11 @@ def report(watson, current, from_, to, projects, "times") @click.option('-j', '--json', 'format_json', is_flag=True, help="Format the log in JSON instead of plain text") +@click.option('-g/-G', '--pager/--no-pager', 'pager', default=None, + help="(Don't) view output through a pager.") @click.pass_obj def log(watson, current, from_, to, projects, tags, year, month, week, day, - format_json): + format_json, pager): """ Display each recorded session during the given timespan. @@ -544,6 +572,9 @@ def log(watson, current, from_, to, projects, tags, year, month, week, day, and `--year`, `--month` and `--week` to the current year, month or week respectively. + If you are outputting to the terminal, you can selectively enable a pager + through the `--pager` option. + You can limit the log to a project or a tag using the `--project` and `--tag` options. They can be specified several times each to add multiple projects or tags to the log. @@ -616,10 +647,26 @@ def log(watson, current, from_, to, projects, tags, year, month, week, day, ) lines = [] + # use the pager, or print directly to the terminal + if pager or (pager is None and + watson.config.getboolean('options', 'pager', True)): + + def _print(line): + lines.append(line) + + def _final_print(lines): + click.echo_via_pager('\n'.join(lines)) + else: + + def _print(line): + click.echo(line) + + def _final_print(lines): + pass for i, (day, frames) in enumerate(frames_by_day): if i != 0: - lines.append('') + _print('') frames = sorted(frames, key=operator.attrgetter('start')) longest_project = max(len(frame.project) for frame in frames) @@ -629,14 +676,14 @@ def log(watson, current, from_, to, projects, tags, year, month, week, day, (frame.stop - frame.start for frame in frames) ) - lines.append( + _print( "{date} ({daily_total})".format( date=style('date', "{:dddd DD MMMM YYYY}".format(day)), daily_total=style('time', format_timedelta(daily_total)) ) ) - lines.append("\n".join( + _print("\n".join( "\t{id} {start} to {stop} {delta:>11} {project}{tags}".format( delta=format_timedelta(frame.stop - frame.start), project=style('project', @@ -650,7 +697,7 @@ def log(watson, current, from_, to, projects, tags, year, month, week, day, for frame in frames )) - click.echo_via_pager('\n'.join(lines)) + _final_print(lines) @cli.command()