devinteske

vimcat

Jan 19th, 2017
1,430
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/sh
  2. #! vi: set noautoindent :: Vi/ViM
  3. #!/usr/bin/env vim
  4. #! This is a shell script that executes itself as a vimscript to do its work
  5. #!-
  6. #! Copyright (c) 2008 Matthew J. Wozniski <mjw@drexel.edu>
  7. #! Copyright (c) 2017 Devin Teske <dteske@FreeBSD.org>
  8. #! All rights reserved.
  9. #!
  10. #! Redistribution and use in source and binary forms, with or without
  11. #! modification, are permitted provided that the following conditions
  12. #! are met:
  13. #! 1. Redistributions of source code must retain the above copyright
  14. #!    notice, this list of conditions and the following disclaimer.
  15. #! 2. Redistributions in binary form must reproduce the above copyright
  16. #!    notice, this list of conditions and the following disclaimer in the
  17. #!    documentation and/or other materials provided with the distribution.
  18. #!
  19. #! THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  20. #! ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. #! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. #! ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  23. #! FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. #! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. #! OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. #! HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. #! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. #! OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. #! SUCH DAMAGE.
  30. #!
  31. #! $FreeBSD$
  32. #! $FrauBSD$
  33. #!
  34. #!########################################################## SH MAIN
  35. : if 0
  36.     : "Bourne shell code goes here, but you cannot use if-statements"
  37.  
  38.     case "$0" in
  39.     /*) script="$0" ;;
  40.      *) script="$PWD/$0"
  41.     esac
  42.  
  43.     : ${UNAME_s:=$( uname -s )}
  44.     export darwin=0
  45.     case "$UNAME_s" in
  46.     Darwin) darwin=1 ;;
  47.     esac
  48.  
  49.     [ $# -lt 1 -o "$1" = "-" ] && {
  50.         tmpfile=$( mktemp -t "${0##*/}.XXXXXXXX" )
  51.         trap 'rm -f "$tmpfile"' EXIT
  52.         eval 'cat > "$tmpfile" || exit'
  53.         [ $# -gt 0 ] && shift 1 # -
  54.         set -- "$tmpfile" "$@"
  55.     }
  56.  
  57.     vim -e -X -R "$@" -c "source $script" -c "visual" \
  58.         -c "bufdo call AnsiHighlight()" -c qa < /dev/tty | awk '
  59.             NR == 1 { sub(/^[^"]*"[^"]*"[[:space:]]*/, "") }
  60.             gsub(/\x1b\[[[:digit:]]+;1H/, "") { }
  61.             !/^\x1b\[\?1l/
  62.         '
  63.  
  64.     exit
  65.  
  66.     : "The remainder of this file is vimscript"
  67. : endif
  68. #!########################################################## VIM FUNCTIONS
  69.  
  70. :
  71. : "Convert info for a highlight group to a string of ANSI color escapes"
  72. :
  73. function! s:GroupToAnsi(groupnum)
  74.     if !exists("s:ansicache")
  75.         let s:ansicache = {}
  76.     endif
  77.  
  78.     let groupnum = a:groupnum
  79.     if !groupnum
  80.         let groupnum = hlID("Normal")
  81.     endif
  82.  
  83.     if has_key(s:ansicache, groupnum)
  84.         return s:ansicache[groupnum]
  85.     endif
  86.  
  87.     let rv = synIDattr(groupnum, "reverse", s:type)
  88.     if rv == "" || rv == -1
  89.         let rv = 0
  90.     endif
  91.  
  92.     let bd = synIDattr(groupnum, "bold", s:type)
  93.     if bd == "" || bd == -1
  94.         let bd = 0
  95.     endif
  96.  
  97.     let fg = synIDattr(groupnum, "fg", s:type)
  98.     let bg = synIDattr(groupnum, "bg", s:type)
  99.  
  100.     if rv
  101.         let temp = bg
  102.         let bg = fg
  103.         let fg = temp
  104.     endif
  105.  
  106.     if fg >= 8 && fg < 16
  107.         let fg -= 8
  108.         let bd = 1
  109.     endif
  110.  
  111.     if fg == "" || fg == -1
  112.         unlet fg
  113.     endif
  114.  
  115.     if !exists("fg") && !groupnum == hlID("Normal")
  116.         let fg = synIDattr(hlID("Normal"), "fg", s:type)
  117.         if fg == "" || fg == -1
  118.             unlet fg
  119.         endif
  120.     endif
  121.  
  122.     if bg == "" || bg == -1
  123.         unlet bg
  124.     endif
  125.  
  126.     if !exists("bg") && !groupnum == hlID("Normal")
  127.         let bg = synIDattr(hlID("Normal"), "bg", s:type)
  128.         if bg == "" || bg == -1
  129.             unlet bg
  130.         endif
  131.     endif
  132.  
  133.     let retv = "\<Esc>[0"
  134.  
  135.     if bd
  136.         let retv .= ";1"
  137.     endif
  138.  
  139.     if exists("fg") && fg < 8
  140.         let retv .= ";3" . fg
  141.     elseif exists("fg")
  142.         let retv .= ";38;5;" . fg
  143.     endif
  144.  
  145.     if exists("bg") && bg < 8
  146.         let retv .= ";4" . bg
  147.     elseif exists("bg")
  148.         let retv .= ";48;5;" . bg
  149.     endif
  150.  
  151.     let retv .= "m"
  152.  
  153.     let s:ansicache[groupnum] = retv
  154.  
  155.     return retv
  156. endfunction
  157.  
  158. function! AnsiHighlight()
  159.     let retv = []
  160.  
  161.     for lnum in range(1, line("$"))
  162.         let last = hlID("Normal")
  163.         let output = s:GroupToAnsi(last) . "\<Esc>[K"
  164.        
  165.         : "Hopefully fix highlighting sync issues"
  166.         exe "norm! " . lnum . "G$"
  167.        
  168.         let line = getline(lnum)
  169.        
  170.         for cnum in range(1, col("."))
  171.             if synIDtrans(synID(lnum, cnum, 1)) != last
  172.                 let last = synIDtrans(synID(lnum, cnum, 1))
  173.                 let output .= s:GroupToAnsi(last)
  174.             endif
  175.            
  176.             let output .= matchstr(line, '\%(\zs.\)\{'.cnum.'}')
  177.         endfor
  178.        
  179.         let retv += ["\r" . output]
  180.     endfor
  181.  
  182.     : "Reset the colors to default after displaying the file"
  183.     let retv[-1] .= "\<Esc>[0m"
  184.  
  185.     if !$darwin
  186.         echo ""
  187.     endif
  188.  
  189.     return writefile([""] + retv, "/dev/stdout", "b")
  190. endfunction
  191.  
  192. #!########################################################## VIM MAIN
  193.  
  194. set nocompatible
  195. if &t_Co
  196.     let s:type = "cterm"
  197. else
  198.     let s:type = "term"
  199. endif
  200.  
  201. : "Prevent statusmsg on exit when reading stdin on Darwin"
  202. if $darwin
  203.     let ignored = system(":")
  204. endif
  205.  
  206. #!##############################################################################
  207. #! END
  208. #!##############################################################################
Add Comment
Please, Sign In to add comment