SHOW:
|
|
- or go back to the newest paste.
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 | - | export line_offset=0 |
11 | + | #! modification, are permitted provided that the following conditions |
12 | #! are met: | |
13 | - | tmpfile=$( mktemp -t "${0##*/}" ) |
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 | - | shift 1 # - |
16 | + | #! notice, this list of conditions and the following disclaimer in the |
17 | #! documentation and/or other materials provided with the distribution. | |
18 | - | case "${UNAME_s:=$( uname -s )}" in |
18 | + | #! |
19 | - | Darwin) line_offset=1 ;; |
19 | + | #! THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
20 | - | esac |
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 | - | -c "bufdo call AnsiHighlight()" -c qa < /dev/tty | sed |
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 | - | """ |
27 | + | #! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
28 | - | """ The remainder of this file is vimscript |
28 | + | #! OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
29 | - | """ |
29 | + | #! SUCH DAMAGE. |
30 | #! | |
31 | - | " AnsiHighlight: Allows for marking up a file, using ANSI color escapes when |
31 | + | #! $FreeBSD$ |
32 | - | " the syntax changes colors, for easy, faithful reproduction. |
32 | + | #! $FrauBSD$ |
33 | - | " Author: Matthew Wozniski (mjw@drexel.edu) |
33 | + | #! |
34 | - | " Date: Wed, 18 Jan 2017 17:14:29 -0800 |
34 | + | #!########################################################## SH MAIN |
35 | - | " Version: 1.1 |
35 | + | |
36 | - | " History: FIXME see :help marklines-history |
36 | + | |
37 | - | " License: BSD 3-Clause. Below copyright/license must be replicated. |
37 | + | |
38 | case "$0" in | |
39 | - | " Copyright (c) 2008, Matthew J. Wozniski {{{1 |
39 | + | |
40 | - | " Copyright (c) 2017, Devin E. Teske <dteske@FreeBSD.org> |
40 | + | |
41 | - | " All rights reserved. |
41 | + | |
42 | - | " |
42 | + | |
43 | - | " Redistribution and use in source and binary forms, with or without |
43 | + | : ${UNAME_s:=$( uname -s )} |
44 | - | " modification, are permitted provided that the following conditions are met: |
44 | + | export darwin=0 |
45 | - | " * Redistributions of source code must retain the above copyright |
45 | + | case "$UNAME_s" in |
46 | - | " notice, this list of conditions and the following disclaimer. |
46 | + | Darwin) darwin=1 ;; |
47 | - | " * Redistributions in binary form must reproduce the above copyright |
47 | + | |
48 | - | " notice, this list of conditions and the following disclaimer in the |
48 | + | |
49 | - | " documentation and/or other materials provided with the distribution. |
49 | + | |
50 | - | " * The names of the contributors may not be used to endorse or promote |
50 | + | tmpfile=$( mktemp -t "${0##*/}.XXXXXXXX" ) |
51 | - | " products derived from this software without specific prior written |
51 | + | |
52 | - | " permission. |
52 | + | |
53 | - | " |
53 | + | [ $# -gt 0 ] && shift 1 # - |
54 | - | " THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY |
54 | + | |
55 | - | " EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
55 | + | |
56 | - | " WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
56 | + | |
57 | - | " DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY |
57 | + | |
58 | - | " DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
58 | + | -c "bufdo call AnsiHighlight()" -c qa < /dev/tty | awk ' |
59 | - | " (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
59 | + | NR == 1 { sub(/^[^"]*"[^"]*"[[:space:]]*/, "") } |
60 | - | " LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
60 | + | gsub(/\x1b\[[[:digit:]]+;1H/, "") { } |
61 | - | " ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
61 | + | !/^\x1b\[\?1l/ |
62 | - | " (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
62 | + | ' |
63 | - | " SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
63 | + | |
64 | exit | |
65 | - | " Turn off vi-compatible mode, unless it's already off {{{1 |
65 | + | |
66 | - | if &cp |
66 | + | : "The remainder of this file is vimscript" |
67 | - | set nocp |
67 | + | |
68 | #!########################################################## VIM FUNCTIONS | |
69 | ||
70 | - | let s:type = 'cterm' |
70 | + | : |
71 | - | if &t_Co == 0 |
71 | + | : "Convert info for a highlight group to a string of ANSI color escapes" |
72 | - | let s:type = 'term' |
72 | + | : |
73 | function! s:GroupToAnsi(groupnum) | |
74 | if !exists("s:ansicache") | |
75 | - | " Converts info for a highlight group to a string of ANSI color escapes {{{1 |
75 | + | let s:ansicache = {} |
76 | endif | |
77 | - | if ! exists("s:ansicache") |
77 | + | |
78 | - | let s:ansicache = {} |
78 | + | let groupnum = a:groupnum |
79 | - | endif |
79 | + | if !groupnum |
80 | let groupnum = hlID("Normal") | |
81 | - | let groupnum = a:groupnum |
81 | + | endif |
82 | ||
83 | - | if groupnum == 0 |
83 | + | if has_key(s:ansicache, groupnum) |
84 | - | let groupnum = hlID('Normal') |
84 | + | return s:ansicache[groupnum] |
85 | - | endif |
85 | + | endif |
86 | ||
87 | - | if has_key(s:ansicache, groupnum) |
87 | + | let rv = synIDattr(groupnum, "reverse", s:type) |
88 | - | return s:ansicache[groupnum] |
88 | + | if rv == "" || rv == -1 |
89 | - | endif |
89 | + | let rv = 0 |
90 | endif | |
91 | - | let fg = synIDattr(groupnum, 'fg', s:type) |
91 | + | |
92 | - | let bg = synIDattr(groupnum, 'bg', s:type) |
92 | + | let bd = synIDattr(groupnum, "bold", s:type) |
93 | - | let rv = synIDattr(groupnum, 'reverse', s:type) |
93 | + | if bd == "" || bd == -1 |
94 | - | let bd = synIDattr(groupnum, 'bold', s:type) |
94 | + | let bd = 0 |
95 | endif | |
96 | - | " FIXME other attributes? |
96 | + | |
97 | let fg = synIDattr(groupnum, "fg", s:type) | |
98 | - | if rv == "" || rv == -1 |
98 | + | let bg = synIDattr(groupnum, "bg", s:type) |
99 | - | let rv = 0 |
99 | + | |
100 | - | endif |
100 | + | if rv |
101 | let temp = bg | |
102 | - | if bd == "" || bd == -1 |
102 | + | let bg = fg |
103 | - | let bd = 0 |
103 | + | let fg = temp |
104 | - | endif |
104 | + | endif |
105 | ||
106 | - | if rv |
106 | + | if fg >= 8 && fg < 16 |
107 | - | let temp = bg |
107 | + | let fg -= 8 |
108 | - | let bg = fg |
108 | + | let bd = 1 |
109 | - | let fg = temp |
109 | + | endif |
110 | - | endif |
110 | + | |
111 | if fg == "" || fg == -1 | |
112 | - | if fg >= 8 && fg < 16 |
112 | + | unlet fg |
113 | - | let fg -= 8 |
113 | + | endif |
114 | - | let bd = 1 |
114 | + | |
115 | - | endif |
115 | + | if !exists("fg") && !groupnum == hlID("Normal") |
116 | let fg = synIDattr(hlID("Normal"), "fg", s:type) | |
117 | - | if fg == "" || fg == -1 |
117 | + | if fg == "" || fg == -1 |
118 | - | unlet fg |
118 | + | unlet fg |
119 | - | endif |
119 | + | endif |
120 | endif | |
121 | - | if !exists('fg') && !groupnum == hlID('Normal') |
121 | + | |
122 | - | let fg = synIDattr(hlID('Normal'), 'fg', s:type) |
122 | + | if bg == "" || bg == -1 |
123 | - | if fg == "" || fg == -1 |
123 | + | unlet bg |
124 | - | unlet fg |
124 | + | endif |
125 | - | endif |
125 | + | |
126 | - | endif |
126 | + | if !exists("bg") && !groupnum == hlID("Normal") |
127 | let bg = synIDattr(hlID("Normal"), "bg", s:type) | |
128 | - | if bg == "" || bg == -1 |
128 | + | if bg == "" || bg == -1 |
129 | - | unlet bg |
129 | + | unlet bg |
130 | - | endif |
130 | + | endif |
131 | endif | |
132 | - | if !exists('bg') && !groupnum == hlID('Normal') |
132 | + | |
133 | - | let bg = synIDattr(hlID('Normal'), 'bg', s:type) |
133 | + | let retv = "\<Esc>[0" |
134 | - | if bg == "" || bg == -1 |
134 | + | |
135 | - | unlet bg |
135 | + | if bd |
136 | - | endif |
136 | + | let retv .= ";1" |
137 | - | endif |
137 | + | endif |
138 | ||
139 | - | let retv = "\<Esc>[0" |
139 | + | if exists("fg") && fg < 8 |
140 | let retv .= ";3" . fg | |
141 | - | if bd |
141 | + | elseif exists("fg") |
142 | - | let retv .= ";1" |
142 | + | let retv .= ";38;5;" . fg |
143 | - | endif |
143 | + | endif |
144 | ||
145 | - | if exists('fg') && fg < 8 |
145 | + | if exists("bg") && bg < 8 |
146 | - | let retv .= ";3" . fg |
146 | + | let retv .= ";4" . bg |
147 | - | elseif exists('fg') |
147 | + | elseif exists("bg") |
148 | - | let retv .= ";38;5;" . fg |
148 | + | let retv .= ";48;5;" . bg |
149 | - | endif |
149 | + | endif |
150 | ||
151 | - | if exists('bg') && bg < 8 |
151 | + | let retv .= "m" |
152 | - | let retv .= ";4" . bg |
152 | + | |
153 | - | elseif exists('bg') |
153 | + | let s:ansicache[groupnum] = retv |
154 | - | let retv .= ";48;5;" . bg |
154 | + | |
155 | - | endif |
155 | + | return retv |
156 | endfunction | |
157 | - | let retv .= "m" |
157 | + | |
158 | function! AnsiHighlight() | |
159 | - | let s:ansicache[groupnum] = retv |
159 | + | let retv = [] |
160 | ||
161 | - | return retv |
161 | + | for lnum in range(1, line("$")) |
162 | let last = hlID("Normal") | |
163 | let output = s:GroupToAnsi(last) . "\<Esc>[K" | |
164 | ||
165 | - | let retv = [] |
165 | + | : "Hopefully fix highlighting sync issues" |
166 | exe "norm! " . lnum . "G$" | |
167 | - | for lnum in range(1, line('$') + $line_offset) |
167 | + | |
168 | - | let last = hlID('Normal') |
168 | + | let line = getline(lnum) |
169 | - | let output = s:GroupToAnsi(last) . "\<Esc>[K" " Clear to right |
169 | + | |
170 | for cnum in range(1, col(".")) | |
171 | - | " Hopefully fix highlighting sync issues |
171 | + | if synIDtrans(synID(lnum, cnum, 1)) != last |
172 | - | exe "norm! " . lnum . "G$" |
172 | + | let last = synIDtrans(synID(lnum, cnum, 1)) |
173 | let output .= s:GroupToAnsi(last) | |
174 | - | let line = getline(lnum) |
174 | + | endif |
175 | ||
176 | - | for cnum in range(1, col('.')) |
176 | + | let output .= matchstr(line, '\%(\zs.\)\{'.cnum.'}') |
177 | - | if synIDtrans(synID(lnum, cnum, 1)) != last |
177 | + | endfor |
178 | - | let last = synIDtrans(synID(lnum, cnum, 1)) |
178 | + | |
179 | - | let output .= s:GroupToAnsi(last) |
179 | + | let retv += ["\r" . output] |
180 | - | endif |
180 | + | endfor |
181 | ||
182 | - | let output .= matchstr(line, '\%(\zs.\)\{'.cnum.'}') |
182 | + | : "Reset the colors to default after displaying the file" |
183 | - | "let line = substitute(line, '.', '', '') |
183 | + | let retv[-1] .= "\<Esc>[0m" |
184 | - | "let line = matchstr(line, '^\@<!.*') |
184 | + | |
185 | - | endfor |
185 | + | if !$darwin |
186 | echo "" | |
187 | - | let retv += ["\r" . output] |
187 | + | endif |
188 | - | endfor |
188 | + | |
189 | return writefile([""] + retv, "/dev/stdout", "b") | |
190 | - | " Reset the colors to default after displaying the file |
190 | + | |
191 | - | let retv[-1] .= "\<Esc>[0m" |
191 | + | |
192 | #!########################################################## VIM MAIN | |
193 | - | echo "" |
193 | + | |
194 | - | return writefile([""] + retv, '/dev/stdout', 'b') |
194 | + | set nocompatible |
195 | - | endfunction |
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 | #!############################################################################## |