Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement user-programmable registers
Browse files Browse the repository at this point in the history
 * %(register:r) expansion variable
 * set-register r value
 * !=(r)echo arbitrary shell command
rolandwalker committed May 24, 2018
1 parent e08aebf commit d2fd448
Showing 15 changed files with 482 additions and 20 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -312,6 +312,7 @@ TIG_OBJS = \
src/grep.o \
src/ui.o \
src/apps.o \
src/registers.o \
$(GRAPH_OBJS) \
$(COMPAT_OBJS)

5 changes: 4 additions & 1 deletion doc/manual.adoc
Original file line number Diff line number Diff line change
@@ -194,6 +194,8 @@ following variables.
|%(repo:is-inside-work-tree)
|Whether Tig is running inside a work tree,
either `true` or `false`.
|%(register:x) |A user-defined register value, where `x` is an ASCII
character.
|=============================================================================

Example user-defined commands:
@@ -489,7 +491,8 @@ Prompt
|:script <file> |Execute commands from `<file>`.
|:exec <flags><args...> |Execute command using `<args>` with external
user-defined command option flags defined in `<flags>`.
|:echo <args...> |Display text in the status bar.
|:echo <args...> |Display text in the status bar.
|:set-register <char> <args...> |Load a value into the register named `<char>`.
|=============================================================================

[[external-commands]]
4 changes: 4 additions & 0 deletions doc/tigrc.5.adoc
Original file line number Diff line number Diff line change
@@ -665,6 +665,8 @@ the command that should be executed.
|< |Exit Tig after executing the command.
|> |Re-open Tig instantly in the last displayed view after
executing the command.
|=(x) |Run the command synchronously, and store the first
line of output in the register named `x`.
|=============================================================================

Unless otherwise specified, commands are run in the foreground with their
@@ -717,6 +719,8 @@ following variable names, which are substituted before commands are run:
|%(repo:is-inside-work-tree)
|Whether Tig is running inside a work tree,
either `true` or `false`.
|%(register:x) |A user-defined register value, where `x` is an ASCII
character.
|=============================================================================

Examples:
2 changes: 2 additions & 0 deletions include/tig/argv.h
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
#define TIG_ARGV_H

#include "tig/tig.h"
#include "tig/registers.h"

/*
* Argument array helpers.
@@ -62,6 +63,7 @@ typedef unsigned long argv_number;
struct argv_env {
ARGV_ENV_INFO(ARGV_ENV_FIELDS)
unsigned long goto_lineno;
char *registers[SIZEOF_REGISTERS];
char search[SIZEOF_STR];
char none[1];
};
2 changes: 1 addition & 1 deletion include/tig/display.h
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ bool save_view(struct view *view, const char *path);
bool vertical_split_is_enabled(enum vertical_split vsplit, int height, int width);
int apply_vertical_split(int base_width);

bool open_external_viewer(const char *argv[], const char *dir, bool silent, bool confirm, bool echo, bool quick, bool refresh, const char *notice);
bool open_external_viewer(const char *argv[], const char *dir, bool silent, bool confirm, bool echo, bool quick, char register_key, bool refresh, const char *notice);
void open_editor(const char *file, unsigned int lineno);
void enable_mouse(bool enable);

1 change: 1 addition & 0 deletions include/tig/keys.h
Original file line number Diff line number Diff line change
@@ -84,6 +84,7 @@ struct run_request_flags {
bool internal;
bool echo;
bool quick;
char register_key;
};

struct run_request {
159 changes: 159 additions & 0 deletions include/tig/registers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/* Copyright (c) 2006-2017 Jonas Fonseca <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 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 General Public License for more details.
*/

#ifndef TIG_REGISTERS_H
#define TIG_REGISTERS_H

#include "tig/types.h"

/* Index 0 of the register array, corresponding to character key ASCII
* space, is kept empty and reserved for internal use as "no register".
*/
#define REGISTER_KEY_MIN '!' /* corresponding to index 1 */
#define REGISTER_KEY_MAX '~' /* corresponding to index 94 */
#define REGISTER_KEY_OFFSET 0x20
#define SIZEOF_REGISTERS 1 + REGISTER_KEY_MAX - REGISTER_KEY_OFFSET

#define REGISTER_FLAG_OPEN_STR "=("
#define REGISTER_FLAG_CLOSE_STR ")"
#define REGISTER_ESC_CHAR '\\'

#define is_register_esc_char(ch) \
((ch) == REGISTER_ESC_CHAR)

#define is_register_meta_char(ch) \
(is_register_esc_char(ch) \
|| ((ch) == REGISTER_FLAG_OPEN_STR[1]) \
|| ((ch) == REGISTER_FLAG_CLOSE_STR[0]) \
|| ((ch) == '"') \
|| ((ch) == '\''))

#define at_register_flag_open(p) \
(((p)[0] == REGISTER_FLAG_OPEN_STR[0]) && ((p)[1] == REGISTER_FLAG_OPEN_STR[1]))

#define at_register_flag_close(p) \
((p)[0] == REGISTER_FLAG_CLOSE_STR[0])

#define at_register_escd_pair(p) \
(is_register_esc_char((p)[0]) && is_register_meta_char((p)[1]))

#define register_key_to_index(key) \
((((key) >= REGISTER_KEY_MIN) && ((key) <= REGISTER_KEY_MAX)) ? (unsigned int) (key) - REGISTER_KEY_OFFSET : 0)

bool register_set(const char key, const char *value);
const char *register_get(const char key);

/* metacharacters occur twice, once as an escaped sequence */
#define REGISTER_INFO(_) \
_("\\\\", '\\') \
_("\\(", '(') \
_("\\)", ')') \
_("\\\"", '"') \
_("\\'", '\'') \
_("!", '!') \
_("\"", '"') \
_("#", '#') \
_("$", '$') \
_("%", '%') \
_("&", '&') \
_("'", '\'') \
_("(", '(') \
_(")", ')') \
_("*", '*') \
_("+", '+') \
_(",", ',') \
_("-", '-') \
_(".", '.') \
_("/", '/') \
_("0", '0') \
_("1", '1') \
_("2", '2') \
_("3", '3') \
_("4", '4') \
_("5", '5') \
_("6", '6') \
_("7", '7') \
_("8", '8') \
_("9", '9') \
_(":", ':') \
_(";", ';') \
_("<", '<') \
_("=", '=') \
_(">", '>') \
_("?", '?') \
_("@", '@') \
_("A", 'A') \
_("B", 'B') \
_("C", 'C') \
_("D", 'D') \
_("E", 'E') \
_("F", 'F') \
_("G", 'G') \
_("H", 'H') \
_("I", 'I') \
_("J", 'J') \
_("K", 'K') \
_("L", 'L') \
_("M", 'M') \
_("N", 'N') \
_("O", 'O') \
_("P", 'P') \
_("Q", 'Q') \
_("R", 'R') \
_("S", 'S') \
_("T", 'T') \
_("U", 'U') \
_("V", 'V') \
_("W", 'W') \
_("X", 'X') \
_("Y", 'Y') \
_("Z", 'Z') \
_("[", '[') \
_("\\", '\\') \
_("]", ']') \
_("^", '^') \
_("_", '_') \
_("`", '`') \
_("a", 'a') \
_("b", 'b') \
_("c", 'c') \
_("d", 'd') \
_("e", 'e') \
_("f", 'f') \
_("g", 'g') \
_("h", 'h') \
_("i", 'i') \
_("j", 'j') \
_("k", 'k') \
_("l", 'l') \
_("m", 'm') \
_("n", 'n') \
_("o", 'o') \
_("p", 'p') \
_("q", 'q') \
_("r", 'r') \
_("s", 's') \
_("t", 't') \
_("u", 'u') \
_("v", 'v') \
_("w", 'w') \
_("x", 'x') \
_("y", 'y') \
_("z", 'z') \
_("{", '{') \
_("|", '|') \
_("}", '}') \
_("~", '~')

#endif
/* vim: set ts=8 sw=8 noexpandtab: */
11 changes: 11 additions & 0 deletions src/argv.c
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
#include "tig/repo.h"
#include "tig/options.h"
#include "tig/prompt.h"
#include "tig/registers.h"

static bool
concat_argv(const char *argv[], char *buf, size_t buflen, const char *sep, bool quoted)
@@ -376,6 +377,12 @@ format_append_arg(struct format_context *format, const char ***dst_argv, const c
while (arg) {
const char *var = strstr(arg, "%(");
const char *closing = var ? strchr(var, ')') : NULL;

/* todo hardcoding is robust and compact but ugly */
if (var &&
(!strcmp(var, "%(register:\\))") || !strcmp(var, "%(register:))")))
closing++;

const char *next = closing ? closing + 1 : NULL;
const int len = var ? var - arg : strlen(arg);

@@ -468,6 +475,10 @@ argv_format(struct argv_env *argv_env, const char ***dst_argv, const char *src_a
#define FORMAT_REPO_VAR(type, name) \
{ "%(repo:" #name ")", STRING_SIZE("%(repo:" #name ")"), type ## _formatter, &repo.name, "" },
REPO_INFO(FORMAT_REPO_VAR)
#define FORMAT_REGISTER_VAR(namestr, keychar) \
{ "%(register:" namestr ")", STRING_SIZE("%(register:" namestr ")"), argv_string_formatter, \
argv_env->registers[ MIN(keychar,REGISTER_KEY_MAX) - REGISTER_KEY_OFFSET ], "" },
REGISTER_INFO(FORMAT_REGISTER_VAR)
};
struct format_context format = { vars, ARRAY_SIZE(vars), "", 0, file_filter };
int argc;
21 changes: 16 additions & 5 deletions src/display.c
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
#include "tig/draw.h"
#include "tig/display.h"
#include "tig/watch.h"
#include "tig/registers.h"

static void set_terminal_modes(void);

@@ -61,19 +62,29 @@ open_script(const char *path)
}

bool
open_external_viewer(const char *argv[], const char *dir, bool silent, bool confirm, bool echo, bool quick, bool do_refresh, const char *notice)
open_external_viewer(const char *argv[], const char *dir, bool silent, bool confirm, bool echo, bool quick, char register_key, bool do_refresh, const char *notice)
{
bool ok;

if (echo) {
if (echo || register_key) {
char buf[SIZEOF_STR] = "";

io_run_buf(argv, buf, sizeof(buf), dir, false);
if (*buf) {
report("%s", buf);
if (register_key)
register_set(register_key, buf);
if (echo)
report("%s", buf);
else
report_clear();
return true;
} else {
report("No output");
if (register_key)
register_set(register_key, "");
if (echo)
report("No output");
else
report_clear();
return false;
}
} else if (silent || is_script_executing()) {
@@ -148,7 +159,7 @@ open_editor(const char *file, unsigned int lineno)
if (lineno && opt_editor_line_number && string_format(lineno_cmd, "+%u", lineno))
editor_argv[argc++] = lineno_cmd;
editor_argv[argc] = file;
if (!open_external_viewer(editor_argv, repo.cdup, false, false, false, false, true, EDITOR_LINENO_MSG))
if (!open_external_viewer(editor_argv, repo.cdup, false, false, false, false, 0, true, EDITOR_LINENO_MSG))
opt_editor_line_number = false;
}

31 changes: 27 additions & 4 deletions src/keys.c
Original file line number Diff line number Diff line change
@@ -449,7 +449,7 @@ static size_t run_requests;

DEFINE_ALLOCATOR(realloc_run_requests, struct run_request, 8)

#define COMMAND_FLAGS ":!?@<+>"
#define COMMAND_FLAGS ":!?@<+>="

enum status_code
parse_run_request_flags(struct run_request_flags *flags, const char **argv)
@@ -475,6 +475,21 @@ parse_run_request_flags(struct run_request_flags *flags, const char **argv)
flags->echo = 1;
} else if (*argv[0] == '>') {
flags->quick = 1;
} else if (at_register_flag_open(argv[0])
&& at_register_escd_pair(argv[0] + 2)
&& at_register_flag_close(argv[0] + 4)) {
flags->register_key = argv[0][3];
argv[0] += 5;
continue;
} else if (at_register_flag_open(argv[0])
&& argv[0][2] >= REGISTER_KEY_MIN
&& argv[0][2] <= REGISTER_KEY_MAX
&& at_register_flag_close(argv[0] + 3)) {
flags->register_key = argv[0][2];
argv[0] += 4;
continue;
} else if (at_register_flag_open(argv[0])) {
return error("Invalid register flag");
} else if (*argv[0] != '!') {
break;
}
@@ -519,7 +534,7 @@ get_run_request(enum request request)
const char *
format_run_request_flags(const struct run_request *req)
{
static char flags[8];
static char flags[16];
int flagspos = 0;

memset(flags, 0, sizeof(flags));
@@ -530,15 +545,23 @@ format_run_request_flags(const struct run_request *req)
flags[flagspos] = '!'; /* Optional, if other flags are defined */

if (req->flags.silent)
flags[flagspos++] = '@';
flags[flagspos++] = '@';
if (req->flags.confirm)
flags[flagspos++] = '?';
flags[flagspos++] = '?';
if (req->flags.exit)
flags[flagspos++] = '<';
if (req->flags.echo)
flags[flagspos++] = '+';
if (req->flags.quick)
flags[flagspos++] = '>';
if (req->flags.register_key) {
flags[flagspos++] = REGISTER_FLAG_OPEN_STR[0];
flags[flagspos++] = REGISTER_FLAG_OPEN_STR[1];
if (is_register_meta_char(req->flags.register_key))
flags[flagspos++] = REGISTER_ESC_CHAR;
flags[flagspos++] = req->flags.register_key;
flags[flagspos++] = REGISTER_FLAG_CLOSE_STR[0];
}
if (flagspos > 1)
flags[flagspos++] = 0;

95 changes: 94 additions & 1 deletion src/prompt.c
Original file line number Diff line number Diff line change
@@ -223,6 +223,7 @@ readline_variable_generator(const char *text, int state)
#define FORMAT_VAR(type, name) "%(repo:" #name ")",
REPO_INFO(FORMAT_VAR)
#undef FORMAT_VAR
"%(register:",
NULL
};

@@ -268,6 +269,7 @@ readline_action_generator(const char *text, int state)
"save-options",
"exec",
"echo",
"set-register",
#define REQ_GROUP(help)
#define REQ_(req, help) #req
REQ_INFO,
@@ -878,6 +880,67 @@ prompt_update_display(enum view_flag flags)
}
}

bool
parse_set_register(char *key, const char ***dst_argv, const char **src_argv)
{
if (!src_argv || !src_argv[0] || !src_argv[1])
return false;

src_argv++;

/* src_argv is the product of one pass of argv_from_string and arrives
* here in a halfway state. Hack src_argv to tokenize as
* |set-register|"|hello there|
* instead of
* |set-register|" hello there|
* Consider adjusting argv_from_string instead.
*/
char prepend_tok[SIZEOF_STR] = "";
if (strlen(*src_argv) > 2
&& at_register_escd_pair(*src_argv)
&& isspace(src_argv[0][2])) {
string_ncopy(prepend_tok, *src_argv + 1, 1);
*src_argv += 2;
*src_argv += strspn(*src_argv, " ");
argv_prepend(&src_argv, prepend_tok);
} else if (strlen(*src_argv) > 1
&& register_key_to_index(src_argv[0][0])
&& isspace(src_argv[0][1])) {
string_ncopy(prepend_tok, *src_argv, 1);
*src_argv += 1;
*src_argv += strspn(*src_argv, " ");
argv_prepend(&src_argv, prepend_tok);
}
/* end of first hack */


if (strlen(*src_argv) == 2
&& at_register_escd_pair(*src_argv)) {
*key = src_argv[0][1];
} else if (strlen(*src_argv) == 1
&& register_key_to_index(src_argv[0][0])) {
*key = src_argv[0][0];
} else {
return false;
}
src_argv++;


/* Since we src_argv was hacked above, make extra certain it refers to sane
* content. This is reasonable logic, but likely appearing in the wrong place.
*/
while (*src_argv && !src_argv[0][0] && src_argv[1]) {
src_argv++;
*src_argv += strspn(*src_argv, " ");
}
/* end of second hack */

if (!*src_argv || !src_argv[0][0] || !argv_copy(dst_argv, src_argv))
return false;

return true;
}

enum request
run_prompt_command(struct view *view, const char *argv[])
{
@@ -961,6 +1024,35 @@ run_prompt_command(struct view *view, const char *argv[])
report("%s", text);
return REQ_NONE;

} else if (!strcmp(cmd, "set-register")) {
const char **value_argv = NULL;
const char **fmt_argv = NULL;
char value[SIZEOF_STR] = "";
char key;

if (!parse_set_register(&key, &value_argv, argv)) {
report("Error: set-register <char> <expression>");
return REQ_NONE;
}

/* todo string escaping and quote unwrapping, with
* appropriate handling of empty strings. The user
* should be able to clear a register with
* :set-register b ""
*/

if (!argv_format(view->env, &fmt_argv, value_argv, false, true)
|| !argv_to_string(&fmt_argv[0], value, sizeof(value), " ")) {
report("Failed to copy set-register string");
return REQ_NONE;
}

if (!register_set(key, value))
report("Failed to set register");
else
/* this message would be nicer if the key was distinguished in color */
report("Register %c %s", key, value);

} else if (!strcmp(cmd, "save-display")) {
const char *path = argv[1] ? argv[1] : "tig-display.txt";

@@ -1109,7 +1201,8 @@ exec_run_request(struct view *view, struct run_request *req)

if (confirmed)
open_external_viewer(argv, repo.cdup, req->flags.silent,
!req->flags.exit, req->flags.echo, req->flags.quick, false, "");
!req->flags.exit, req->flags.echo,
req->flags.quick, req->flags.register_key, false, "");
}

if (argv)
44 changes: 44 additions & 0 deletions src/registers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* Copyright (c) 2006-2017 Jonas Fonseca <jonas.fonseca@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 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 General Public License for more details.
*/

#include "tig/registers.h"
#include "tig/argv.h"

bool
register_set(const char key, const char *value)
{
unsigned int idx = register_key_to_index(key);

if (!idx)
return false;
if (!argv_env.registers[idx])
argv_env.registers[idx] = calloc(1, SIZEOF_STR);
if (!argv_env.registers[idx])
return false;

string_ncopy_do(argv_env.registers[idx], SIZEOF_STR - 1, value, strlen(value));
return true;
}

const char *
register_get(const char key)
{
unsigned int idx = register_key_to_index(key);

if (!idx)
return NULL;

return argv_env.registers[idx];
}

/* vim: set ts=8 sw=8 noexpandtab: */
2 changes: 1 addition & 1 deletion src/status.c
Original file line number Diff line number Diff line change
@@ -676,7 +676,7 @@ open_mergetool(const char *file)
{
const char *mergetool_argv[] = { "git", "mergetool", file, NULL };

open_external_viewer(mergetool_argv, repo.cdup, false, true, false, true, true, "");
open_external_viewer(mergetool_argv, repo.cdup, false, true, false, true, 0, true, "");
}

static enum request
109 changes: 109 additions & 0 deletions test/script/register-test
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/bin/sh

. libtest.sh
. libgit.sh

LINES=5

in_work_dir create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz"

tigrc <<EOF
set line-graphics = ascii
EOF

steps "
:set-register a value
:exec !assert-var %(register:a) == value
:set-register a
:exec !assert-var %(register:a) == value
:set-register a overwrote_value
:exec !assert-var %(register:a) == overwrote_value
:exec =(a)echo shell_value
:exec !assert-var %(register:a) == shell_value
:exec !=(a)echo bang_shell_value
:exec !assert-var %(register:a) == bang_shell_value
:set-register b %(commit)
:exec !assert-var %(register:b) == ee912870202200a0b9cf4fd86ba57243212d341e
:exec !assert-var X%(register:c) == X
:set-register \\c value
:exec !assert-var X%(register:c) == X
:set-register cc value
:exec !assert-var X%(register:c) == X
:set-register cvalue
:exec !assert-var X%(register:c) == X
:exec =(\\c)echo value
:exec !assert-var X%(register:c) == X
:set-register \\( value
:exec !assert-var %(register:\\() == value
:set-register ( unescaped_value
:exec !assert-var %(register:() == unescaped_value
:exec !assert-var %(register:\\() == unescaped_value
:exec =(\\()echo shell_value
:exec !assert-var %(register:\\() == shell_value
:exec =(()echo unescaped_shell_value
:exec !assert-var %(register:\\() == unescaped_shell_value
:set-register \\\" value
:exec !assert-var '%(register:\\\")' == value
:set-register \" unescaped_value
:exec !assert-var '%(register:\")' == unescaped_value
:exec !assert-var '%(register:\\\")' == unescaped_value
:exec =(\\\")echo shell_value
:exec !assert-var '%(register:\\\")' == shell_value
:exec =(\")echo unescaped_shell_value
:exec !assert-var '%(register:\\\")' == unescaped_shell_value
:set-register \\' value
:exec !assert-var \"%(register:\\')\" == value
:set-register ' unescaped_value
:exec !assert-var \"%(register:')\" == unescaped_value
:exec !assert-var \"%(register:\\')\" == unescaped_value
:exec =(\\')echo shell_value
:exec !assert-var \"%(register:\\')\" == shell_value
:exec =(')echo unescaped_shell_value
:exec !assert-var \"%(register:\\')\" == unescaped_shell_value
:set-register b strip leading space
:exec !assert-var %(register:b) == 'strip leading space'
:set-register ' strip leading space handle irregular unbalanced
:exec !assert-var \"%(register:')\" == 'strip leading space handle irregular unbalanced'
:set-register ' strip leading space coerce irregular balanced'
:exec !assert-var \"%(register:')\" == \"strip leading space coerce irregular balanced'\"
:save-display main.screen
"
test_tig

assert_equals stderr <<EOF
EOF

assert_equals main.screen <<EOF
2014-03-01 17:26 -0500 Jonas Fonseca * [master] WIP: Upgrade to 0.4-SNAPSHO
2014-03-01 15:59 -0500 Jonas Fonseca * Add type parameter for js.Dynamic
2014-01-16 22:51 -0500 Jonas Fonseca * Move classes under org.scalajs.bench
[main] ee912870202200a0b9cf4fd86ba57243212d341e - commit 1 of 48 6%
EOF

assert_vars 29
15 changes: 8 additions & 7 deletions test/tigrc/parse-test
Original file line number Diff line number Diff line change
@@ -53,7 +53,8 @@ bind main 2 @silent command
bind main 3 ?prompted command
bind main 4 <quitting command
bind main 5 +echoed command
bind main 0 !@?<+all modifiers
bind main 6 =(r)save-to-register command
bind main 0 !@?<+>=(r)all modifiers
# Non-ending multi-line command
c\\
@@ -99,9 +100,9 @@ tig warning: ~/.tigrc:25: Unknown color attribute: normally
tig warning: ~/.tigrc:34: Unknown option \`visibility' for column line-number
tig warning: ~/.tigrc:36: Invalid key binding: bind keymap key action
tig warning: ~/.tigrc:37: Invalid key binding: bind keymap key action
tig warning: ~/.tigrc:38: Unknown command flag '%'; expected one of :!?@<+>
tig warning: ~/.tigrc:39: Unknown command flag '|'; expected one of :!?@<+>
tig warning: ~/.tigrc:57: Unknown option command: c
tig warning: ~/.tigrc:38: Unknown command flag '%'; expected one of :!?@<+>=
tig warning: ~/.tigrc:39: Unknown command flag '|'; expected one of :!?@<+>=
tig warning: ~/.tigrc:58: Unknown option command: c
tig warning: Errors while loading HOME/.tigrc.
EOF

@@ -122,7 +123,8 @@ External commands:
3 ?prompted command
4 <quitting command
5 +echoed command
0 @?<+all modifiers
6 =(r)save-to-register command
0 @?<+>=(r)all modifiers
@@ -133,6 +135,5 @@ External commands:
[help] - line 1 of 17 100%
[help] - line 1 of 18 100%
EOF

0 comments on commit d2fd448

Please sign in to comment.