From b3bd23dd0a5f287bbdfe3ed5b7423a8134417cc4 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 4 Apr 2015 12:50:22 +0200 Subject: add file descriptor redirection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- doc/example | 5 ++- doc/syntax | 20 ++++++++- info/auto-auto-complete.texinfo | 25 +++++++++-- src/auto-auto-complete.py | 96 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 137 insertions(+), 9 deletions(-) diff --git a/doc/example b/doc/example index a993b54..d1e6b68 100644 --- a/doc/example +++ b/doc/example @@ -54,11 +54,12 @@ (no-exec ls "'/usr/share/ponysay/balloons'" (case (ponysay .say) (ponythink .think))) ) (suggestion wrap (verbatim none inherit 100 60) - (calc (pipe (stty size) + (calc (pipe (stdin-fd (stty size) (stderr)) (cut -d ' ' -f 2) ) - 10 ) ) - ; in addition to `pipe`(|) to following are also possible `fullpipe`(|&) `cat`(;) `and`(&&) `or`(||) + ; in addition to `pipe`(|) the following are also possible: `fullpipe`(|&) `cat`(;) `and`(&&) `or`(||) + ; in addition to `stdin-fd`(<&) the following are also possible: `stdout-fd` `stderr-fd` `fd-fd` `stdin` `stdout` `stderr` `fd` ) diff --git a/doc/syntax b/doc/syntax index ca44109..df16bbb 100644 --- a/doc/syntax +++ b/doc/syntax @@ -56,10 +56,28 @@ verbatim ::= 'verbatim' _value [{_ value}] calc ::= 'calc' (__ value | _ any_exec) [{_ value | _ any_exec}] -any_exec ::= '(' _ exec_type (__ value | _ any_exec) [{_ value | _ any_exec}] _ ')' +any_exec ::= '(' _ (exec_sequence | exec_redirect) _ ')' + +exec_sequence ::= exec_type (__ value | _ any_exec) [{_ value | _ any_exec}] exec_type ::= "exec" | "calc" | "pipe" | "fullpipe" | "cat" | "and" | "or" +exec_redirect ::= std_redirect | fd_redirect | std_redirect_fd | fd_redirect_fd + +std_redirect ::= input _ any_exec _ value + +fd_redirect ::= "fd" _ any_exec _ (number _value | fdnum _ value) + +std_redirect_fd ::= input "-fd" _ any_exec _ (number | fdnum) + +fd_redirect_fd ::= "fd" _ any_exec _ (number __ number | (number | fdnum) _ fdnum | fdnum _ number) + +input ::= "stdin" | "stdout" | "stderr" + +fdnum :: = "(" _ input _ ")" + +number ::= {"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"} + name ::= {letter | escape | squote | dquote} letter :: $any ^ ' ' ^ \t ^ \n ^ \r ^ \t ^ '\' ^ \' ^ \" diff --git a/info/auto-auto-complete.texinfo b/info/auto-auto-complete.texinfo index 977769e..0931933 100644 --- a/info/auto-auto-complete.texinfo +++ b/info/auto-auto-complete.texinfo @@ -17,7 +17,7 @@ @copying -Copyright @copyright{} 2014 Mattias Andrée +Copyright @copyright{} 2014, 2015 Mattias Andrée @quotation Permission is granted to copy, distribute and/or modify this document @@ -595,13 +595,13 @@ is to give it some default suggestion. The next step is to suggest the terminal's width minus 10 columns. In the Bash shell this can be calculated with -@command{$(( $(stty size | cut -d ' ' -f 2) - 10 ))}. +@command{$(( $(stty size <&2 | cut -d ' ' -f 2) - 10 ))}. @example ( ;We have cut out everything but (suggestion wrap). (suggestion wrap (verbatim none inherit 100 60) - (calc (pipe (stty size) (cut -d ' ' -f 2)) - 10) + (calc (pipe (stdin-fd (stty size) (stderr)) (cut -d ' ' -f 2)) - 10) ) ) @end example @@ -622,6 +622,25 @@ can be used. @code{(a || b || c)} @end table +It was also shown that @code{(stdin-fd (a) (stderr))} translates +into @code{a <&2}. @code{(stdin)}, @code{(stdout)} and @code{(stderr)} +translates into @code{0}, @code{1} and @code{2}, respectively. +Additional @code{(stdin-fd a b)} translates into @code{a <&b}, +@code{(stdout-fd a b)} into @code{a >&b}, @code{(stderr-fd a b)} into @code{a 2>&b} +and @code{(fd-fd a b c)} into @code{a b<>&c}. +You can also redirect to files: + +@table @code +@item (stdin a b) +@code{a < b} +@item (stdout a b) +@code{a > b} +@item (stderr a b) +@code{a 2> b} +@item (fd a b c) +@code{a b> c} +@end table + @node GNU Free Documentation License diff --git a/src/auto-auto-complete.py b/src/auto-auto-complete.py index da8d56f..f883b36 100755 --- a/src/auto-auto-complete.py +++ b/src/auto-auto-complete.py @@ -266,7 +266,7 @@ class GeneratorBASH: return '\'' + text.replace('\'', '\'\\\'\'') + '\'' def makeexec(functionType, function): - if functionType in ('exec', 'pipe', 'fullpipe', 'cat', 'and', 'or'): + if functionType in ('exec', 'pipe', 'fullpipe', 'cat', 'and', 'or', 'stdin', 'stdout', 'stderr', 'stdin-fd', 'stdout-fd', 'stderr-fd', 'fd', 'fd-fd'): elems = [(' %s ' % makeexec(item[0], item[1:]) if isinstance(item, list) else verb(item)) for item in function] if functionType == 'exec': return ' $( %s ) ' % (' '.join(elems)) @@ -280,6 +280,36 @@ class GeneratorBASH: return ' ( %s ) ' % (' && '.join(elems)) if functionType == 'or': return ' ( %s ) ' % (' || '.join(elems)) + if functionType == 'stdin': + if len(elems) == 0: + return 0 + [command, redirection] = elems + return ' %s < %s ' % (command, redirection) + if functionType == 'stdout': + if len(elems) == 0: + return 1 + [command, redirection] = elems + return ' %s > %s ' % (command, redirection) + if functionType == 'stderr': + if len(elems) == 0: + return 2 + [command, redirection] = elems + return ' %s 2> %s ' % (command, redirection) + if functionType == 'stdin-fd': + [command, redirection] = elems + return ' %s <&%s ' % (command, redirection.replace('\'', '').replace(' ', '')) + if functionType == 'stdout-fd': + [command, redirection] = elems + return ' %s >&%s ' % (command, redirection.replace('\'', '').replace(' ', '')) + if functionType == 'stderr-fd': + [command, redirection] = elems + return ' %s 2>&%s ' % (command, redirection.replace('\'', '').replace(' ', '')) + if functionType == 'fd': + [command, fd, redirection] = elems + return ' %s %s<> %s ' % (command, fd.replace('\'', '').replace(' ', ''), redirection) + if functionType == 'fd-fd': + [command, fd, redirection] = elems + return ' %s %s<>&%s ' % (command, fd.replace('\'', '').replace(' ', ''), redirection.replace('\'', '').replace(' ', '')) if functionType in ('params', 'verbatim'): return ' '.join([verb(item) for item in function]) return ' '.join([verb(functionType)] + [verb(item) for item in function]) @@ -462,7 +492,7 @@ class GeneratorFISH: return '\'' + text.replace('\'', '\'\\\'\'') + '\'' def makeexec(functionType, function): - if functionType in ('exec', 'pipe', 'fullpipe', 'cat', 'and', 'or'): + if functionType in ('exec', 'pipe', 'fullpipe', 'cat', 'and', 'or', 'stdin', 'stdout', 'stderr', 'stdin-fd', 'stdout-fd', 'stderr-fd', 'fd', 'fd-fd'): elems = [(' %s ' % makeexec(item[0], item[1:]) if isinstance(item, list) else verb(item)) for item in function] if functionType == 'exec': return ' ( %s ) ' % (' '.join(elems)) @@ -476,6 +506,36 @@ class GeneratorFISH: return ' ( %s ) ' % (' && '.join(elems)) if functionType == 'or': return ' ( %s ) ' % (' || '.join(elems)) + if functionType == 'stdin': + if len(elems) == 0: + return 0 + [command, redirection] = elems + return ' %s < %s ' % (command, redirection) + if functionType == 'stdout': + if len(elems) == 0: + return 1 + [command, redirection] = elems + return ' %s > %s ' % (command, redirection) + if functionType == 'stderr': + if len(elems) == 0: + return 2 + [command, redirection] = elems + return ' %s 2> %s ' % (command, redirection) + if functionType == 'stdin-fd': + [command, redirection] = elems + return ' %s <&%s ' % (command, redirection.replace('\'', '').replace(' ', '')) + if functionType == 'stdout-fd': + [command, redirection] = elems + return ' %s >&%s ' % (command, redirection.replace('\'', '').replace(' ', '')) + if functionType == 'stderr-fd': + [command, redirection] = elems + return ' %s 2>&%s ' % (command, redirection.replace('\'', '').replace(' ', '')) + if functionType == 'fd': + [command, fd, redirection] = elems + return ' %s %s<> %s ' % (command, fd.replace('\'', '').replace(' ', ''), redirection) + if functionType == 'fd-fd': + [command, fd, redirection] = elems + return ' %s %s<>&%s ' % (command, fd.replace('\'', '').replace(' ', ''), redirection.replace('\'', '').replace(' ', '')) if functionType in ('params', 'verbatim'): return ' '.join([verb(item) for item in function]) return ' '.join([verb(functionType)] + [verb(item) for item in function]) @@ -656,7 +716,7 @@ class GeneratorZSH: return '\'' + text.replace('\'', '\'\\\'\'') + '\'' def makeexec(functionType, function): - if functionType in ('exec', 'pipe', 'fullpipe', 'cat', 'and', 'or'): + if functionType in ('exec', 'pipe', 'fullpipe', 'cat', 'and', 'or', 'stdin', 'stdout', 'stderr', 'stdin-fd', 'stdout-fd', 'stderr-fd', 'fd', 'fd-fd'): elems = [(' %s ' % makeexec(item[0], item[1:]) if isinstance(item, list) else verb(item)) for item in function] if functionType == 'exec': return ' $( %s ) ' % (' '.join(elems)) @@ -670,6 +730,36 @@ class GeneratorZSH: return ' ( %s ) ' % (' && '.join(elems)) if functionType == 'or': return ' ( %s ) ' % (' || '.join(elems)) + if functionType == 'stdin': + if len(elems) == 0: + return 0 + [command, redirection] = elems + return ' %s < %s ' % (command, redirection) + if functionType == 'stdout': + if len(elems) == 0: + return 1 + [command, redirection] = elems + return ' %s > %s ' % (command, redirection) + if functionType == 'stderr': + if len(elems) == 0: + return 2 + [command, redirection] = elems + return ' %s 2> %s ' % (command, redirection) + if functionType == 'stdin-fd': + [command, redirection] = elems + return ' %s <&%s ' % (command, redirection.replace('\'', '').replace(' ', '')) + if functionType == 'stdout-fd': + [command, redirection] = elems + return ' %s >&%s ' % (command, redirection.replace('\'', '').replace(' ', '')) + if functionType == 'stderr-fd': + [command, redirection] = elems + return ' %s 2>&%s ' % (command, redirection.replace('\'', '').replace(' ', '')) + if functionType == 'fd': + [command, fd, redirection] = elems + return ' %s %s<> %s ' % (command, fd.replace('\'', '').replace(' ', ''), redirection) + if functionType == 'fd-fd': + [command, fd, redirection] = elems + return ' %s %s<>&%s ' % (command, fd.replace('\'', '').replace(' ', ''), redirection.replace('\'', '').replace(' ', '')) if functionType in ('params', 'verbatim'): return ' '.join([verb(item) for item in function]) return ' '.join([verb(functionType)] + [verb(item) for item in function]) -- cgit v1.2.3-70-g09d2