Skip to content

Instantly share code, notes, and snippets.

@RichardBronosky
Forked from echristopherson/vimcat.sh
Created November 2, 2020 18:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save RichardBronosky/29173fa1f2254e00558e17e1807bceac to your computer and use it in GitHub Desktop.
Save RichardBronosky/29173fa1f2254e00558e17e1807bceac to your computer and use it in GitHub Desktop.
Modified version of Matthew Wozniski's vimcat.sh
#!/bin/bash
#!/usr/bin/env vim
#! This is a bash script that executes itself as a vimscript to do its work
#! vim:ft=vim:ts=2:sts=2:sw=2
: if 0
tmpfile=$(mktemp -t vimcat.XXXXXXXX)
exec 9<>"$tmpfile"
rm "$tmpfile"
output="$(vim -e -X -R "$@" -c "source $0" -c "visual" -c "bufdo call AnsiHighlight()" -c qa 9>&1 &>/dev/null)"
exec 9<&-
echo "$output"
exit
: endif
" AnsiHighlight: Allows for marking up a file, using ANSI color escapes when
" the syntax changes colors, for easy, faithful reproduction.
" Author: Matthew Wozniski (mjw@drexel.edu)
" Date: Fri, 01 Aug 2008 05:22:55 -0400
" Version: 1.0 FIXME
" History: FIXME see :help marklines-history
" License: BSD. Completely open source, but I would like to be
" credited if you use some of this code elsewhere.
" Copyright (c) 2008, Matthew J. Wozniski {{{1
" All rights reserved.
"
" Redistribution and use in source and binary forms, with or without
" modification, are permitted provided that the following conditions are met:
" * Redistributions of source code must retain the above copyright
" notice, this list of conditions and the following disclaimer.
" * Redistributions in binary form must reproduce the above copyright
" notice, this list of conditions and the following disclaimer in the
" documentation and/or other materials provided with the distribution.
" * The names of the contributors may not be used to endorse or promote
" products derived from this software without specific prior written
" permission.
"
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY
" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
" DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
" Turn off vi-compatible mode, unless it's already off {{{1
if &cp
set nocp
endif
let s:type = 'cterm'
if &t_Co == 0
let s:type = 'term'
endif
" Converts info for a highlight group to a string of ANSI color escapes {{{1
function! s:GroupToAnsi(groupnum)
if ! exists("s:ansicache")
let s:ansicache = {}
endif
let groupnum = a:groupnum
if groupnum == 0
let groupnum = hlID('Normal')
endif
if has_key(s:ansicache, groupnum)
return s:ansicache[groupnum]
endif
let fg = synIDattr(groupnum, 'fg', s:type)
let bg = synIDattr(groupnum, 'bg', s:type)
let rv = synIDattr(groupnum, 'reverse', s:type)
let bd = synIDattr(groupnum, 'bold', s:type)
" FIXME other attributes?
if rv == "" || rv == -1
let rv = 0
endif
if bd == "" || bd == -1
let bd = 0
endif
if rv
let temp = bg
let bg = fg
let fg = temp
endif
if fg >= 8 && fg < 16
let fg -= 8
let bd = 1
endif
if fg == "" || fg == -1
unlet fg
endif
if !exists('fg') && !groupnum == hlID('Normal')
let fg = synIDattr(hlID('Normal'), 'fg', s:type)
if fg == "" || fg == -1
unlet fg
endif
endif
if bg == "" || bg == -1
unlet bg
endif
if !exists('bg') && !groupnum == hlID('Normal')
let bg = synIDattr(hlID('Normal'), 'bg', s:type)
if bg == "" || bg == -1
unlet bg
endif
endif
"let retv = "\<Esc>[22;24;25;27;28;49" " I added 49 to reset default background
let retv = "\<Esc>[0" " Why didn't the script use this all along? Doesn't it work everywhere?
if bd
let retv .= ";1"
endif
if exists('fg') && fg < 8
let retv .= ";3" . fg
elseif exists('fg')
let retv .= ";38;5;" . fg " 38;5 is for 256-color xterm
endif
if exists('bg') && bg < 8
let retv .= ";4" . bg
elseif exists('bg')
let retv .= ";48;5;" . bg " 48;5 is for 256-color xterm
endif
let retv .= "m"
let s:ansicache[groupnum] = retv
return retv
endfunction
function! AnsiHighlight()
let retv = []
for lnum in range(1, line('$'))
let last = hlID('Normal')
let output = s:GroupToAnsi(last) . "\<Esc>[K" " Clear to right
" Hopefully fix highlighting sync issues
exe "norm! " . lnum . "G$"
let line = getline(lnum)
for cnum in range(1, col('.'))
if synIDtrans(synID(lnum, cnum, 1)) != last
let last = synIDtrans(synID(lnum, cnum, 1))
let output .= s:GroupToAnsi(last)
endif
let output .= matchstr(line, '\%(\zs.\)\{'.cnum.'}')
"let line = substitute(line, '.', '', '')
"let line = matchstr(line, '^\@<!.*')
endfor
let retv += [output]
endfor
" Reset the colors to default after displaying the file
let retv[-1] .= "\<Esc>[0m"
"return writefile(retv, '/proc/self/fd/9')
return writefile(retv, '/dev/fd/9')
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment