e21fbe7dffff1619c2deb02eea8cccbd7e9814f4

Author
ProbstDJakob <jakob@probstfamilie.de>
Committer
Marc Cornellà <marc.cornella@live.com>
Date

Message

colorize: update plugin to support less options (#8392)

Diff

This diff is truncated to protect this page.

  1diff --git a/plugins/colorize/README.md b/plugins/colorize/README.md
  2index d374430116d26f3332dfb109e37c581c10827d6e..ee4ab80360b188577d6c9f7dc6594098d4ed9cbe 100644
  3--- a/plugins/colorize/README.md
  4+++ b/plugins/colorize/README.md
  5@@ -17,10 +17,10 @@ plugins=(... colorize)
  6 
  7 ### Requirements
  8 
  9-This plugin requires that either of the following tools be installed:
 10+This plugin requires that at least one of the following tools is installed:
 11 
 12-* Chroma: [https://github.com/alecthomas/chroma](https://github.com/alecthomas/chroma)
 13-* Pygments be installed: [pygments.org](https://pygments.org/)
 14+* [Chroma](https://github.com/alecthomas/chroma)
 15+* [Pygments](https://pygments.org/download/)
 16 
 17 ### Colorize tool
 18 
 19@@ -41,12 +41,8 @@ ZSH_COLORIZE_STYLE="colorful"
 20 ## Usage
 21 
 22 * `ccat <file> [files]`: colorize the contents of the file (or files, if more than one are provided).
 23-  If no arguments are passed it will colorize the standard input or stdin.
 24+  If no files are passed it will colorize the standard input.
 25 
 26-* `cless <file> [files]`: colorize the contents of the file (or files, if more than one are provided) and
 27-  open less. If no arguments are passed it will colorize the standard input or stdin.
 28-
 29-Note that `cless` will behave as less when provided more than one file: you have to navigate files with
 30-the commands `:n` for next and `:p` for previous. The downside is that less options are not supported.
 31-But you can circumvent this by either using the LESS environment variable, or by running `ccat file1 file2|less --opts`.
 32-In the latter form, the file contents will be concatenated and presented by less as a single file.
 33+* `cless [less-options] <file> [files]`: colorize the contents of the file (or files, if more than one are provided) and open less.
 34+  If no files are passed it will colorize the standard input.
 35+  The LESSOPEN and LESSCLOSE will be overwritten for this to work, but only in a local scope.
 36diff --git a/plugins/colorize/colorize.plugin.zsh b/plugins/colorize/colorize.plugin.zsh
 37index 3e91a9f4671d28bb13689fa0fd630a0f7fac3e8a..6ed9739fadba3e9cf611b9e1611101f3f4e042f3 100644
 38--- a/plugins/colorize/colorize.plugin.zsh
 39+++ b/plugins/colorize/colorize.plugin.zsh
 40@@ -1,8 +1,11 @@
 41-# easier alias to use the plugin
 42-alias ccat='colorize_via_pygmentize'
 43-alias cless='colorize_via_pygmentize_less'
 44+# Easier alias to use the plugin
 45+alias ccat="colorize_cat"
 46+alias cless="colorize_less"
 47 
 48-colorize_via_pygmentize() {
 49+# '$0:A' gets the absolute path of this file
 50+ZSH_COLORIZE_PLUGIN_PATH=$0:A
 51+
 52+colorize_check_requirements() {
 53     local available_tools=("chroma" "pygmentize")
 54 
 55     if [ -z "$ZSH_COLORIZE_TOOL" ]; then
 56@@ -23,6 +26,12 @@ colorize_via_pygmentize() {
 57         echo "Package '$ZSH_COLORIZE_TOOL' is not installed!" >&2
 58         return 1
 59     fi
 60+}
 61+
 62+colorize_cat() {
 63+    if ! colorize_check_requirements; then
 64+        return 1
 65+    fi
 66 
 67     # If the environment variable ZSH_COLORIZE_STYLE
 68     # is set, use that theme instead. Otherwise,
 69@@ -32,7 +41,7 @@ colorize_via_pygmentize() {
 70         ZSH_COLORIZE_STYLE="emacs"
 71     fi
 72 
 73-    # pygmentize stdin if no arguments passed
 74+    # Use stdin if no arguments have been passed.
 75     if [ $# -eq 0 ]; then
 76         if [[ "$ZSH_COLORIZE_TOOL" == "pygmentize" ]]; then
 77             pygmentize -O style="$ZSH_COLORIZE_STYLE" -g
 78@@ -42,12 +51,9 @@ colorize_via_pygmentize() {
 79         return $?
 80     fi
 81 
 82-    # guess lexer from file extension, or
 83-    # guess it from file contents if unsuccessful
 84-
 85+    # Guess lexer from file extension, or guess it from file contents if unsuccessful.
 86     local FNAME lexer
 87-    for FNAME in "$@"
 88-    do
 89+    for FNAME in "$@"; do
 90         if [[ "$ZSH_COLORIZE_TOOL" == "pygmentize" ]]; then
 91             lexer=$(pygmentize -N "$FNAME")
 92             if [[ $lexer != text ]]; then
 93@@ -61,22 +67,47 @@ colorize_via_pygmentize() {
 94     done
 95 }
 96 
 97-colorize_via_pygmentize_less() (
 98-    # this function is a subshell so tmp_files can be shared to cleanup function
 99-    declare -a tmp_files
100+# The less option 'F - Forward forever; like "tail -f".' will not work in this implementation
101+# caused by the lack of the ability to follow the file within pygmentize.
102+colorize_less() {
103+    if ! colorize_check_requirements; then
104+        return 1
105+    fi
106 
107-    cleanup () {
108-        [[ ${#tmp_files} -gt 0 ]] && rm -f "${tmp_files[@]}"
109-        exit
110-    }
111-    trap 'cleanup' EXIT HUP TERM INT
112+    _cless() {
113+        # LESS="-R $LESS" enables raw ANSI colors, while maintain already set options.
114+        local LESS="-R $LESS"
115 
116-    while (( $# != 0 )); do     #TODO: filter out less opts
117-        tmp_file="$(mktemp -t "tmp.colorize.XXXX.$(sed 's/\//./g' <<< "$1")")"
118-        tmp_files+=("$tmp_file")
119-        colorize_via_pygmentize "$1" > "$tmp_file"
120-        shift 1
121-    done
122+        # This variable tells less to pipe every file through the specified command
123+        # (see the man page of less INPUT PREPROCESSOR).
124+        # 'zsh -ic "colorize_cat %s 2> /dev/null"' would not work for huge files like
125+        # the ~/.zsh_history. For such files the tty of the preprocessor will be supended.
126+        # Therefore we must source this file to make colorize_cat available in the
127+        # preprocessor without the interactive mode.
128+        # `2>/dev/null` will suppress the error for large files 'broken pipe' of the python
129+        # script pygmentize, which will show up if less has not fully "loaded the file"
130+        # (e.g. when not scrolled to the bottom) while already the next file will be displayed.
131+        local LESSOPEN="| zsh -c 'source \"$ZSH_COLORIZE_PLUGIN_PATH\"; \
132+        ZSH_COLORIZE_TOOL=$ZSH_COLORIZE_TOOL ZSH_COLORIZE_STYLE=$ZSH_COLORIZE_STYLE \
133+        colorize_cat %s 2> /dev/null'"
134 
135-    less -f "${tmp_files[@]}"
136-)
137+        # LESSCLOSE will be set to prevent any errors by executing a user script
138+        # which assumes that his LESSOPEN has been executed.
139+        local LESSCLOSE=""