Code

Allow tig to parse control-modified chars in tigrc
[tig.git] / tig.c
diff --git a/tig.c b/tig.c
index e2e83ff8fb320acb494796479f5288eb7e5d6e71..a501db044b3c718dac45dbffb4f8b30f02faccb9 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -1620,16 +1620,17 @@ get_key_value(const char *name)
                if (!strcasecmp(key_table[i].name, name))
                        return key_table[i].value;
 
+       if (strlen(name) == 2 && name[0] == '^' && isprint(*name))
+               return (int)name[1] & 0x1f;
        if (strlen(name) == 1 && isprint(*name))
                return (int) *name;
-
        return ERR;
 }
 
 static const char *
 get_key_name(int key_value)
 {
-       static char key_char[] = "'X'";
+       static char key_char[] = "'X'\0";
        const char *seq = NULL;
        int key;
 
@@ -1637,10 +1638,17 @@ get_key_name(int key_value)
                if (key_table[key].value == key_value)
                        seq = key_table[key].name;
 
-       if (seq == NULL &&
-           key_value < 127 &&
-           isprint(key_value)) {
-               key_char[1] = (char) key_value;
+       if (seq == NULL && key_value < 0x7f) {
+               char *s = key_char + 1;
+
+               if (key_value >= 0x20) {
+                       *s++ = key_value;
+               } else {
+                       *s++ = '^';
+                       *s++ = 0x40 | (key_value & 0x1f);
+               }
+               *s++ = '\'';
+               *s++ = '\0';
                seq = key_char;
        }
 
@@ -2316,7 +2324,7 @@ static struct view views[] = {
        VIEW_(BLAME,  "blame",  &blame_ops,  TRUE,  ref_commit),
        VIEW_(BRANCH, "branch", &branch_ops, TRUE,  ref_head),
        VIEW_(HELP,   "help",   &help_ops,   FALSE, ""),
-       VIEW_(PAGER,  "pager",  &pager_ops,  FALSE, "stdin"),
+       VIEW_(PAGER,  "pager",  &pager_ops,  FALSE, ""),
        VIEW_(STATUS, "status", &status_ops, TRUE,  ""),
        VIEW_(STAGE,  "stage",  &stage_ops,  TRUE,  ""),
 };
@@ -3708,6 +3716,13 @@ view_driver(struct view *view, enum request request)
                break;
 
        case REQ_VIEW_PAGER:
+               if (view == NULL) {
+                       if (!io_open(&VIEW(REQ_VIEW_PAGER)->io, ""))
+                               die("Failed to open stdin");
+                       open_view(view, request, OPEN_PREPARED);
+                       break;
+               }
+
                if (!VIEW(REQ_VIEW_PAGER)->pipe && !VIEW(REQ_VIEW_PAGER)->lines) {
                        report("No pager content, press %s to run command from prompt",
                               get_key(view->keymap, REQ_PROMPT));
@@ -4194,11 +4209,38 @@ static const char *diff_argv[SIZEOF_ARG] = {
                "%(diffargs)", "%(commit)", "--", "%(fileargs)", NULL
 };
 
+static bool
+diff_read(struct view *view, char *data)
+{
+       if (!data) {
+               /* Fall back to retry if no diff will be shown. */
+               if (view->lines == 0 && opt_file_args) {
+                       int pos = argv_size(view->argv)
+                               - argv_size(opt_file_args) - 1;
+
+                       if (pos > 0 && !strcmp(view->argv[pos], "--")) {
+                               for (; view->argv[pos]; pos++) {
+                                       free((void *) view->argv[pos]);
+                                       view->argv[pos] = NULL;
+                               }
+
+                               if (view->pipe)
+                                       io_done(view->pipe);
+                               if (io_run(&view->io, IO_RD, view->dir, view->argv))
+                                       return FALSE;
+                       }
+               }
+               return TRUE;
+       }
+
+       return pager_read(view, data);
+}
+
 static struct view_ops diff_ops = {
        "line",
        diff_argv,
        NULL,
-       pager_read,
+       diff_read,
        pager_draw,
        pager_request,
        pager_grep,
@@ -7737,10 +7779,8 @@ parse_options(int argc, const char *argv[])
        const char **filter_argv = NULL;
        int i;
 
-       if (!isatty(STDIN_FILENO)) {
-               io_open(&VIEW(REQ_VIEW_PAGER)->io, "");
+       if (!isatty(STDIN_FILENO))
                return REQ_VIEW_PAGER;
-       }
 
        if (argc <= 1)
                return REQ_VIEW_MAIN;