colorize.plugin.zsh 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. # Easier alias to use the plugin
  2. alias ccat="colorize_cat"
  3. alias cless="colorize_less"
  4. # '$0:A' gets the absolute path of this file
  5. ZSH_COLORIZE_PLUGIN_PATH=$0:A
  6. colorize_check_requirements() {
  7. local available_tools=("chroma" "pygmentize")
  8. if [ -z "$ZSH_COLORIZE_TOOL" ]; then
  9. if (( $+commands[pygmentize] )); then
  10. ZSH_COLORIZE_TOOL="pygmentize"
  11. elif (( $+commands[chroma] )); then
  12. ZSH_COLORIZE_TOOL="chroma"
  13. else
  14. echo "Neither 'pygments' nor 'chroma' is installed!" >&2
  15. return 1
  16. fi
  17. fi
  18. if [[ ${available_tools[(Ie)$ZSH_COLORIZE_TOOL]} -eq 0 ]]; then
  19. echo "ZSH_COLORIZE_TOOL '$ZSH_COLORIZE_TOOL' not recognized. Available options are 'pygmentize' and 'chroma'." >&2
  20. return 1
  21. elif (( $+commands["$ZSH_COLORIZE_TOOL"] )); then
  22. echo "Package '$ZSH_COLORIZE_TOOL' is not installed!" >&2
  23. return 1
  24. fi
  25. }
  26. colorize_cat() {
  27. if ! colorize_check_requirements; then
  28. return 1
  29. fi
  30. # If the environment variable ZSH_COLORIZE_STYLE
  31. # is set, use that theme instead. Otherwise,
  32. # use the default.
  33. if [ -z "$ZSH_COLORIZE_STYLE" ]; then
  34. # Both pygmentize & chroma support 'emacs'
  35. ZSH_COLORIZE_STYLE="emacs"
  36. fi
  37. # Use stdin if no arguments have been passed.
  38. if [ $# -eq 0 ]; then
  39. if [[ "$ZSH_COLORIZE_TOOL" == "pygmentize" ]]; then
  40. pygmentize -O style="$ZSH_COLORIZE_STYLE" -g
  41. else
  42. chroma --style="$ZSH_COLORIZE_STYLE" --formatter="${ZSH_COLORIZE_CHROMA_FORMATTER:-terminal}"
  43. fi
  44. return $?
  45. fi
  46. # Guess lexer from file extension, or guess it from file contents if unsuccessful.
  47. local FNAME lexer
  48. for FNAME in "$@"; do
  49. if [[ "$ZSH_COLORIZE_TOOL" == "pygmentize" ]]; then
  50. lexer=$(pygmentize -N "$FNAME")
  51. if [[ $lexer != text ]]; then
  52. pygmentize -O style="$ZSH_COLORIZE_STYLE" -l "$lexer" "$FNAME"
  53. else
  54. pygmentize -O style="$ZSH_COLORIZE_STYLE" -g "$FNAME"
  55. fi
  56. else
  57. chroma --style="$ZSH_COLORIZE_STYLE" --formatter="${ZSH_COLORIZE_CHROMA_FORMATTER:-terminal}" "$FNAME"
  58. fi
  59. done
  60. }
  61. # The less option 'F - Forward forever; like "tail -f".' will not work in this implementation
  62. # caused by the lack of the ability to follow the file within pygmentize.
  63. colorize_less() {
  64. if ! colorize_check_requirements; then
  65. return 1
  66. fi
  67. _cless() {
  68. # LESS="-R $LESS" enables raw ANSI colors, while maintain already set options.
  69. local LESS="-R $LESS"
  70. # This variable tells less to pipe every file through the specified command
  71. # (see the man page of less INPUT PREPROCESSOR).
  72. # 'zsh -ic "colorize_cat %s 2> /dev/null"' would not work for huge files like
  73. # the ~/.zsh_history. For such files the tty of the preprocessor will be supended.
  74. # Therefore we must source this file to make colorize_cat available in the
  75. # preprocessor without the interactive mode.
  76. # `2>/dev/null` will suppress the error for large files 'broken pipe' of the python
  77. # script pygmentize, which will show up if less has not fully "loaded the file"
  78. # (e.g. when not scrolled to the bottom) while already the next file will be displayed.
  79. local LESSOPEN="| zsh -c 'source \"$ZSH_COLORIZE_PLUGIN_PATH\"; \
  80. ZSH_COLORIZE_TOOL=$ZSH_COLORIZE_TOOL ZSH_COLORIZE_STYLE=$ZSH_COLORIZE_STYLE \
  81. colorize_cat %s 2> /dev/null'"
  82. # LESSCLOSE will be set to prevent any errors by executing a user script
  83. # which assumes that his LESSOPEN has been executed.
  84. local LESSCLOSE=""
  85. LESS="$LESS" LESSOPEN="$LESSOPEN" LESSCLOSE="$LESSCLOSE" less "$@"
  86. }
  87. if [ -t 0 ]; then
  88. _cless "$@"
  89. else
  90. # The input is not associated with a terminal, therefore colorize_cat will
  91. # colorize this input and pass it to less.
  92. # Less has now to decide what to use. If any files have been provided, less
  93. # will ignore the input by default, otherwise the colorized input will be used.
  94. # If files have been supplied and the input has been redirected, this will
  95. # lead to unnecessary overhead, but retains the ability to use the less options
  96. # without checking for them inside this script.
  97. colorize_cat | _cless "$@"
  98. fi
  99. }