From 98760f2eb3779d5192cb84d3ba168b2e620340e7 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Thu, 23 Aug 2012 08:41:42 -0400 Subject: [PATCH] [GH #65] Support binding more advanced external commands --- NEWS | 3 +++ io.c | 31 ++++++++++++++++++++++++++++--- io.h | 1 + tig.c | 12 ++++++------ tigrc.5.txt | 14 +++++++++++--- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 3462d73..baabe78 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,9 @@ Improvements: Example: `bind main B !?git rebase -i %(commit)`. - User-defined commands prefixed with a '<' means exit after execution. Example: `bind main C ! 0 ? valuelen + 2 : strlen(arg); } else { + if (quoted) + *quoted = 0; return strcspn(arg, " \t"); } } @@ -46,7 +48,7 @@ static bool split_argv_string(const char *argv[SIZEOF_ARG], int *argc, char *cmd, bool remove_quotes) { while (*cmd && *argc < SIZEOF_ARG) { - bool quoted = FALSE; + char quoted = 0; int valuelen = get_arg_valuelen(cmd, "ed); bool advance = cmd[valuelen] != 0; int quote_offset = !!(quoted && remove_quotes); @@ -141,6 +143,29 @@ argv_append_array(const char ***dst_argv, const char *src_argv[]) } bool +argv_remove_quotes(const char *argv[]) +{ + int argc; + + for (argc = 0; argv[argc]; argc++) { + char quoted = 0; + const char *arg = argv[argc]; + int arglen = get_arg_valuelen(arg, "ed); + + if (!quoted) + continue; + + arg = strndup(arg + 1, arglen - 1 - (arg[arglen - 1] == quoted)); + if (!arg) + return FALSE; + free((void *) argv[argc]); + argv[argc] = arg; + } + + return TRUE; +} + +bool argv_copy(const char ***dst, const char *src[]) { int argc; diff --git a/io.h b/io.h index c184f90..0ccceaa 100644 --- a/io.h +++ b/io.h @@ -29,6 +29,7 @@ size_t argv_size(const char **argv); bool argv_append(const char ***argv, const char *arg); bool argv_append_array(const char ***dst_argv, const char *src_argv[]); bool argv_copy(const char ***dst, const char *src[]); +bool argv_remove_quotes(const char *argv[]); /* * Encoding conversion. diff --git a/tig.c b/tig.c index 07a921a..62ca4a8 100644 --- a/tig.c +++ b/tig.c @@ -3419,12 +3419,12 @@ open_run_request(enum request request) } } - if (!confirmed) - ; /* Nothing */ - else if (req->silent) - io_run_bg(argv); - else - open_external_viewer(argv, NULL, !req->exit); + if (confirmed && argv_remove_quotes(argv)) { + if (req->silent) + io_run_bg(argv); + else + open_external_viewer(argv, NULL, !req->exit); + } } if (argv) diff --git a/tigrc.5.txt b/tigrc.5.txt index 12fbda3..8fc4d88 100644 --- a/tigrc.5.txt +++ b/tigrc.5.txt @@ -349,10 +349,18 @@ are: As an example, the following external command will save the current commit as a patch file: "!git format-patch -1 %(commit)". If your external command requires use of dynamic features, such as subshells, expansion of environment -variables and process control, this can be achieved by using a combination of -git aliases and tig external commands. The following example entries can be -put in either the .gitconfig or .git/config file: +variables and process control, this can be achieved by using a shell command: +.Configure a binding in ~/.tigrc to put a commit ID in the clipboard. +-------------------------------------------------------------------------- +bind generic I !@sh -c "echo -n %(commit) | xclip -selection c" +-------------------------------------------------------------------------- + +Or by using a combination of git aliases and tig external commands. The +following example entries can be put in either the .gitconfig or .git/config +file: + +.Git configuration which binds tig keys to git command aliasas. -------------------------------------------------------------------------- [alias] gitk-bg = !"gitk HEAD --not $(git rev-parse --remotes) &" -- 2.11.4.GIT