Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[GH #65] Support binding more advanced external commands

  • Loading branch information...
commit 98760f2eb3779d5192cb84d3ba168b2e620340e7 1 parent e35b50d
Jonas Fonseca jonas authored

Showing 5 changed files with 49 additions and 12 deletions. Show diff stats Hide diff stats

  1. +3 0  NEWS
  2. +28 3 io.c
  3. +1 0  io.h
  4. +6 6 tig.c
  5. +11 3 tigrc.5.txt
3  NEWS
@@ -24,6 +24,9 @@ Improvements:
24 24 Example: `bind main B !?git rebase -i %(commit)`.
25 25 - User-defined commands prefixed with a '<' means exit after execution.
26 26 Example: `bind main C !<git commit`. (GH #66)
  27 + - User-defined commands are executed unquoted to support shell commands.
  28 + Example: `bind generic I !@sh -c "echo -n %(commit) | xclip -selection c"`.
  29 + (GH #65)
27 30 - Configure case-insensitive searches using: `set ignore-case = yes`.
28 31 - Add "deleted mode" line type for better diff coloring.
29 32 - Open editor when requesting edit action from within a file diff.
31 io.c
@@ -28,16 +28,18 @@ argv_to_string(const char *argv[SIZEOF_ARG], char *buf, size_t buflen, const cha
28 28 }
29 29
30 30 static inline int
31   -get_arg_valuelen(const char *arg, bool *quoted)
  31 +get_arg_valuelen(const char *arg, char *quoted)
32 32 {
33 33 if (*arg == '"' || *arg == '\'') {
34 34 const char *end = *arg == '"' ? "\"" : "'";
35 35 int valuelen = strcspn(arg + 1, end);
36 36
37 37 if (quoted)
38   - *quoted = TRUE;
  38 + *quoted = *arg;
39 39 return valuelen > 0 ? valuelen + 2 : strlen(arg);
40 40 } else {
  41 + if (quoted)
  42 + *quoted = 0;
41 43 return strcspn(arg, " \t");
42 44 }
43 45 }
@@ -46,7 +48,7 @@ static bool
46 48 split_argv_string(const char *argv[SIZEOF_ARG], int *argc, char *cmd, bool remove_quotes)
47 49 {
48 50 while (*cmd && *argc < SIZEOF_ARG) {
49   - bool quoted = FALSE;
  51 + char quoted = 0;
50 52 int valuelen = get_arg_valuelen(cmd, &quoted);
51 53 bool advance = cmd[valuelen] != 0;
52 54 int quote_offset = !!(quoted && remove_quotes);
@@ -141,6 +143,29 @@ argv_append_array(const char ***dst_argv, const char *src_argv[])
141 143 }
142 144
143 145 bool
  146 +argv_remove_quotes(const char *argv[])
  147 +{
  148 + int argc;
  149 +
  150 + for (argc = 0; argv[argc]; argc++) {
  151 + char quoted = 0;
  152 + const char *arg = argv[argc];
  153 + int arglen = get_arg_valuelen(arg, &quoted);
  154 +
  155 + if (!quoted)
  156 + continue;
  157 +
  158 + arg = strndup(arg + 1, arglen - 1 - (arg[arglen - 1] == quoted));
  159 + if (!arg)
  160 + return FALSE;
  161 + free((void *) argv[argc]);
  162 + argv[argc] = arg;
  163 + }
  164 +
  165 + return TRUE;
  166 +}
  167 +
  168 +bool
144 169 argv_copy(const char ***dst, const char *src[])
145 170 {
146 171 int argc;
1  io.h
@@ -29,6 +29,7 @@ size_t argv_size(const char **argv);
29 29 bool argv_append(const char ***argv, const char *arg);
30 30 bool argv_append_array(const char ***dst_argv, const char *src_argv[]);
31 31 bool argv_copy(const char ***dst, const char *src[]);
  32 +bool argv_remove_quotes(const char *argv[]);
32 33
33 34 /*
34 35 * Encoding conversion.
12 tig.c
@@ -3419,12 +3419,12 @@ open_run_request(enum request request)
3419 3419 }
3420 3420 }
3421 3421
3422   - if (!confirmed)
3423   - ; /* Nothing */
3424   - else if (req->silent)
3425   - io_run_bg(argv);
3426   - else
3427   - open_external_viewer(argv, NULL, !req->exit);
  3422 + if (confirmed && argv_remove_quotes(argv)) {
  3423 + if (req->silent)
  3424 + io_run_bg(argv);
  3425 + else
  3426 + open_external_viewer(argv, NULL, !req->exit);
  3427 + }
3428 3428 }
3429 3429
3430 3430 if (argv)
14 tigrc.5.txt
@@ -349,10 +349,18 @@ are:
349 349 As an example, the following external command will save the current commit as
350 350 a patch file: "!git format-patch -1 %(commit)". If your external command
351 351 requires use of dynamic features, such as subshells, expansion of environment
352   -variables and process control, this can be achieved by using a combination of
353   -git aliases and tig external commands. The following example entries can be
354   -put in either the .gitconfig or .git/config file:
  352 +variables and process control, this can be achieved by using a shell command:
355 353
  354 +.Configure a binding in ~/.tigrc to put a commit ID in the clipboard.
  355 +--------------------------------------------------------------------------
  356 +bind generic I !@sh -c "echo -n %(commit) | xclip -selection c"
  357 +--------------------------------------------------------------------------
  358 +
  359 +Or by using a combination of git aliases and tig external commands. The
  360 +following example entries can be put in either the .gitconfig or .git/config
  361 +file:
  362 +
  363 +.Git configuration which binds tig keys to git command aliasas.
356 364 --------------------------------------------------------------------------
357 365 [alias]
358 366 gitk-bg = !"gitk HEAD --not $(git rev-parse --remotes) &"

0 comments on commit 98760f2

Please sign in to comment.
Something went wrong with that request. Please try again.