├── plugin └── FIGlet.vim ├── README └── autoload └── FIGlet.vim /plugin/FIGlet.vim: -------------------------------------------------------------------------------- 1 | " vim:ft=vim foldmethod=marker tw=78: 2 | 3 | " ========================================================================== 4 | " File: FIGlet.vim (global plugin) 5 | " Last Changed: 2022-12-07 6 | " Maintainer: Erik Falor 7 | " Version: 3.2 8 | " License: Vim License 9 | " Source: http://www.vim.org/scripts/script.php?script_id=3359 10 | " GitHub: https://github.com/fadein/vim-FIGlet.git 11 | " ========================================================================== 12 | 13 | " _ _ _ , 14 | " - - / - - 15 | " ('|| || _ _ 16 | " (( ||--|| _-_, < \, / \\ _-_ <> 17 | " (( ||--|| ||_. /-|| || || || \\ 18 | " (( / || ~ || (( || || || ||/ 19 | " -___-\\, ,-_- \/\\ \\_-| \\,/ <> 20 | " / \ 21 | " '----` 22 | " 23 | " :FIGlet takes the same arguments that the program figlet(1) accepts. It 24 | " does a little bit of parsing for arguments it can grok, and passes the rest 25 | " through. If no arguments are given, it will fall back to the global 26 | " parameters you can set in your vimrc file, or the program's own defaults. 27 | " That usually means the 'standard' font and a width of 76 columns. 28 | " 29 | " When the global variable g:use_FIGlet_as_operatorfunc is defined and has a 30 | " true value, the 'operatorfunc' setting will be set such that the g@ command 31 | " will filter the indicated text through figlet(1). g@, being a normal mode 32 | " command, cannot take arguments and may be controlled through these global 33 | " variables: 34 | " 35 | " g:figletFont - the name of the font to use 36 | " g:figletFontDir - full path to the directory storing your figlet fonts 37 | " g:figletOpts - any other arguments you want to pass figlet(1) 38 | " 39 | " :FIGletFontDemo generates a sample of every font on your system. 40 | 41 | " _ _ _ _ _ _ _ _ _ _ _ _ 42 | " / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ 43 | " ( C | o | p | y | l | e | f | t ) ( 2 | 0 | 1 | 6 ) 44 | " \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ 45 | 46 | " Exit quickly when the script has already been loaded 47 | if exists('g:loaded_FIGlet') 48 | finish 49 | endif 50 | 51 | let g:loaded_FIGlet = '3.2' 52 | 53 | 54 | " Check whether there is a figlet(1) program in the path 55 | if !executable('figlet') 56 | if exists('g:use_FIGlet_as_operatorfunc') && g:use_FIGlet_as_operatorfunc 57 | set operatorfunc=FIGlet#FIGletFail 58 | endif 59 | command! -nargs=? FIGletFontDemo :call FIGlet#FIGletFail() 60 | command! -range -nargs=* FIGlet :call FIGlet#FIGletFail() 61 | else 62 | if exists('g:use_FIGlet_as_operatorfunc') && g:use_FIGlet_as_operatorfunc 63 | set operatorfunc=FIGlet#FIGOper 64 | endif 65 | command! -nargs=? FIGletFontDemo :call FIGlet#FIGFontDemo() 66 | command! -range -complete=custom,FIGlet#FIGletComplete -nargs=* FIGlet :,call FIGlet#FIGRange() 67 | endif 68 | 69 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | _____ ___ ____ _ _ _ __ 2 | | ___|_ _/ ___| | ___| |_ (_)/ _|_ _ 3 | | |_ | | | _| |/ _ \ __|____| | |_| | | | 4 | | _| | | |_| | | __/ ||_____| | _| |_| | 5 | |_| |___\____|_|\___|\__| |_|_| \__, | 6 | |___/ 7 | , , , . , . 8 | . _ . .._. -+- _ \./-+- . ,*-+-|_ -+-|_ _ 9 | \_|(_)(_|[ | (/,/'\ | \/\/ | | [ ) | [ )(/, 10 | ._| 11 | @@@@@@@@@ 12 | @@:::::::::@@ 13 | @@:::::::::::::@@ 14 | ggggggggg ggggg@:::::::@@@:::::::@ 15 | g:::::::::ggg::::g@::::::@ @::::::@ 16 | g:::::::::::::::::g@:::::@ @@@@:::::@ 17 | g::::::ggggg::::::gg@:::::@ @::::::::@ 18 | g:::::g g:::::g @:::::@ @::::::::@ 19 | g:::::g g:::::g @:::::@ @:::::::@@ 20 | g:::::g g:::::g @:::::@ @@@@@@@@ 21 | g::::::g g:::::g @::::::@ 22 | g:::::::ggggg:::::g @:::::::@@@@@@@@ 23 | g::::::::::::::::g @@:::::::::::::@ 24 | gg::::::::::::::g @@:::::::::::@ 25 | gggggggg::::::g @@@@@@@@@@@ 26 | g:::::g 27 | gggggg g:::::g 28 | g:::::gg gg:::::g 29 | g::::::ggg:::::::g 30 | gg:::::::::::::g 31 | ggg::::::ggg 32 | gggggg 33 | 34 | .-. 35 | .' `. 36 | .--. .---. .--. .--. .--. `. .'.--. .--. 37 | ' .; :: .; `' '_.': ..'' .; ; : :' .; :: ..' 38 | `.__.': ._.'`.__.':_; `.__,_;:_;`.__.':_; 39 | : : 40 | :_; 41 | 42 | o | |o| o | | | 43 | .,---. ,---.,---|,---|.|--- .,---.,---. |--- ,---. |--- |---.,---. 44 | || | ,---|| || ||| || || | | | | | | ||---' 45 | `` ' `---^`---'`---'``---'``---'` ' `---'`---' `---'` '`---' 46 | 47 | ______________________________ _____ 48 | ________ ____/___ _/_ ____/__ /______ /_ 49 | ___(_)_ /_ __ / _ / __ __ /_ _ \ __/ 50 | ___ _ __/ __/ / / /_/ / _ / / __/ /_ 51 | _(_) /_/ /___/ \____/ /_/ \___/\__/ 52 | 53 | 888 54 | e88'888 e88 88e 888 888 8e 888 888 8e ,"Y88b 888 8e e88 888 55 | d888 '8 d888 888b 888 888 88b 888 888 88b "8" 888 888 88b d888 888 56 | Y888 , Y888 888P 888 888 888 888 888 888 ,ee 888 888 888 Y888 888 57 | "88,e8' "88 88" 888 888 888 888 888 888 "88 888 888 888 "88 888 58 | 59 | 60 | .-._.).--. 61 | `-=-.`-=-. ( )/ `-=-.`-=-. 62 | `-'/ 63 | 64 | (o)__(o)\\ // wWw wWw\\\ ///, 65 | (__ __)(o)(o) wWw wWw (O) (O)((O)(O)) 66 | ( ) || || (O)_ (O)_ / ) ( \ | \ || 67 | )( |(__)| .' __) .' __)/ / \ \||\\|| 68 | ( ) /.--.\( _) ( _) | \____/ ||| \ | 69 | )/ -' `-`.__) )/ '. `--' .`|| || 70 | ( ( `-..-' (_/ \_) 71 | ___ ___ ___ ____ ________ __ __ __ __ ___ _ _ 72 | ||\\//|| // \\ || \\ || || \\||\ || || ||// \\\\// 73 | || \/ ||(( ))|| ))||== ||_//||\\|| \\ /\ //||=|| )/ 74 | || || \\_// ||_// ||___|| \\|| \|| \V/\V/ || ||// 75 | _ _ 76 | _| |_ ___ ._ _ _ ___ | |__ ___ 77 | | | / . \ | ' ' |<_> || / // ._> 78 | |_| \___/ |_|_|_|<___||_\_\\___. 79 | 80 | _ _ _ _ 81 | ___ | | _| | ___ ___ ___ | |_ ___ ___ | | 82 | / . \| |/ . ||___|<_- 136 | || || \\ /-|| || || || || || \\ ||_. 137 | |, ||/ (( || || || || || ||/ ~ || 138 | _-/ \\,/ \/\\ \\, \\/\\ \\, \\,/ ,-_- <> 139 | 140 | 1. If figlet fails to run, your original text is put back w/o messing up your 141 | undo history too much (you can still redo to the oopsie). 142 | 143 | 2. :FIGlet command accepts a range, of lines and has completion. Hit tab 144 | after typing the -f switch to list available fonts. 145 | Get a lot of fonts at http://www.figlet.org/fontdb.cgi 146 | 147 | Ex. Render lines 1 through 7 in the tengwar font: 148 | :1,7FIGlet -f tengwar 149 | 150 | Ex. Render the visual selection in the doom font, centered in 90 columns: 151 | '<,'>FIGlet -w 90 -c -f doom 152 | 153 | 3. Width is inferred from your 'textwidth' (except on Windows with the DOS 154 | build of figlet, as noted above). 155 | 156 | 4. The :FIGletFontDemo command will show you a sample of each font installed 157 | in your font directory. By default this command will render each font 158 | eponymously, or you may specify a snippet of text to render so as to allow 159 | comparison between fonts. 160 | 161 | Ex. See what the word "Supercalifragilisticexpialidocious" looks like in each font: 162 | :FIGletFontDemo Supercalifragilisticexpialidocious 163 | 164 | 5. The g@ operator takes all of the chosen text (selected with motion 165 | commands or text-objects) and puts it all into the same paragraph. 166 | the :FIGlet command works one line at a time. It makes a difference 167 | when rendering text like this: 168 | 169 | 1. 170 | 2. 171 | 172 | :FIGlet outputs: 173 | _ 174 | / | 175 | | | 176 | | |_ 177 | |_(_) 178 | 179 | ____ 180 | |___ \ 181 | __) | 182 | / __/ _ 183 | |_____(_) 184 | 185 | g@ instead outputs: 186 | _ ____ 187 | / | |___ \ 188 | | | __) | 189 | | |_ / __/ _ 190 | |_(_) |_____(_) 191 | -------------------------------------------------------------------------------- /autoload/FIGlet.vim: -------------------------------------------------------------------------------- 1 | " A function to inform the user if there is a problem finding FIGlet 2 | function! FIGlet#FIGletFail(...) 3 | echoerr 'The "figlet" executable was not found in your $PATH' 4 | endfunction 5 | 6 | " Work around some bugs with the DOS build of figlet.exe 7 | " {{{ 8 | if has('dos16') || has('dos32') || has('win16') || has ('win32') || 9 | \has('win64') || has('win95') 10 | "Passing -w causes a stack overflow in figlet.exe about 50% of the time 11 | let s:overrideWidth = 1 12 | "using -- to separate options from text crashes figlet about 50% of the 13 | "time as well. 14 | let s:argsep = '' 15 | else 16 | let s:argsep = '--' 17 | endif "}}} 18 | 19 | " Run the FIGlet program, passing in the applicable options 20 | function! RunFIGlet(text, opts, width, font, fontdir) "{{{ 21 | " set any custom options (such as path to fonts) 22 | if '' != a:opts 23 | let opts = a:opts 24 | elseif exists('g:figletOpts') 25 | let opts = g:figletOpts 26 | else 27 | let opts = '' 28 | endif 29 | 30 | " set the width to &textwidth or default 31 | if exists('s:overrideWidth') 32 | let width = '' 33 | elseif '' != a:width 34 | let width = '-w ' . a:width 35 | elseif &textwidth != 0 36 | let width = '-w ' . &textwidth 37 | else 38 | let width = '-w 76' 39 | endif 40 | 41 | " set the font (figlet itself defaults to 'standard') 42 | if '' != a:font 43 | let font = '-f ' . a:font 44 | elseif exists('g:figletFont') 45 | let font = '-f ' . g:figletFont 46 | else 47 | let font = '' 48 | endif 49 | 50 | " set the font (figlet itself defaults to 'standard') 51 | if '' != a:fontdir 52 | let fontdir = '-d ' . a:fontdir 53 | elseif exists('g:figletFontDir') 54 | let fontdir = '-d ' . g:figletFontDir 55 | else 56 | let fontdir = '' 57 | endif 58 | 59 | let command = printf('figlet %s %s %s %s %s %s', 60 | \opts, width, font, fontdir, s:argsep, shellescape(a:text)) 61 | 62 | try 63 | let result = system(command) 64 | catch /^Vim\%((\a\+)\)\=:E484/ " Can't open file [tempfile] 65 | throw 'figlet error' 66 | endtry 67 | 68 | if 0 != v:shell_error 69 | throw 'figlet error' 70 | endif 71 | return split(result, "\n") 72 | endfunction "}}} 73 | 74 | " Return the font directory to be used by FIGlet - it's either the value of 75 | " g:figletFontDir, or the one compiled-in to FIGlet itself 76 | let s:figletFontDir = '' 77 | function! s:GetFIGletFontDir() "{{{ 78 | if exists('g:figletFontDir') 79 | let s:figletFontDir = g:figletFontDir 80 | else 81 | let s:figletFontDir = split(system('figlet -I2'), "\n")[0] 82 | endif 83 | return s:figletFontDir 84 | endfunction "}}} 85 | 86 | " Return a list of names of all font files in FIGlet's font directory 87 | let s:figletFonts = [] 88 | function! s:GetFIGletFonts() "{{{ 89 | if [] == s:figletFonts 90 | let fontDir = s:GetFIGletFontDir() 91 | let fonts = split(glob(fontDir . '/*.flf'), "\n") 92 | "strip fontDir and ext from each entry 93 | let s:figletFonts = map(fonts, 'fnamemodify(v:val, ":t:r")') 94 | endif 95 | return s:figletFonts 96 | endfunction "}}} 97 | 98 | " For each font found in FIGlet's font directory, generate a small sample 99 | " & show the results in a new scratch buffer. If this buffer hasn't been 100 | " wiped out, subsequent invocations will reload the buffer instead of 101 | " re-generating it 102 | function! FIGlet#FIGFontDemo(...) "{{{ 103 | let bufname = 'FIGletFontDemo.txt' 104 | let bufnum = bufnr(bufname) 105 | let vwinnum = bufwinnr(bufnum) 106 | if bufnum >= 0 && vwinnum < 0 107 | " the buffer already exists && window not open 108 | try 109 | if winnr("$") == 1 && bufname("%") == '' && &modified == 0 110 | execute 'buffer ' . bufnum 111 | else 112 | execute 'sbuffer ' . bufnum 113 | endif 114 | catch /^Vim\%((\a\+)\)\=:E36/ " Not enough room 115 | " Can't split, then switch 116 | execute 'buffer ' . bufnum 117 | endtry 118 | elseif bufnum >= 0 && vwinnum >= 0 119 | " else if buffer exists in a window 120 | " switch to the window 121 | if vwinnum != bufwinnr('%') 122 | execute "normal \" . vwinnum . 'w' 123 | endif 124 | else 125 | " else if no buffer, create it 126 | try 127 | if winnr("$") == 1 && bufname("%") == '' && &modified == 0 128 | execute 'edit ' . bufname 129 | else 130 | execute 'split ' . bufname 131 | endif 132 | catch /^Vim\%((\a\+)\)\=:E36/ " Not enough room 133 | "Can't split, then switch 134 | execute 'edit ' . bufname 135 | endtry 136 | 137 | "set up buffer-local settings for this window 138 | setlocal bufhidden=hide foldcolumn=0 nofoldenable 139 | \nonumber norightleft noswapfile nowrap 140 | 141 | "arrange to have these settings restored upon re-entering the buffer 142 | autocmd BufEnter setlocal noswapfile 143 | \bufhidden=hide nonumber nowrap norightleft 144 | \foldcolumn=0 nofoldenable 145 | 146 | "now that the buffer is set-up 147 | 0put =printf('All FIGlet fonts in %s:', s:GetFIGletFontDir()) 148 | put ='' 149 | for font in s:GetFIGletFonts() 150 | try 151 | echon printf("Demoing font %s...\r", font) 152 | put =font 153 | put ='===========================' 154 | let s:overrideWidth = 1 155 | if a:0 == 1 && len(a:1) > 0 156 | silent put =RunFIGlet(a:1, '-t', '', font, '') 157 | else 158 | silent put =RunFIGlet(font, '-t', '', font, '') 159 | endif 160 | unlet s:overrideWidth 161 | catch /figlet error/ 162 | put =printf('FIGlet failed on font %s', font) 163 | finally 164 | put ='' 165 | endtry 166 | endfor 167 | echon "Done" 168 | 169 | endif 170 | setlocal nomodifiable nomodified nofoldenable 171 | 1 172 | endfunction "}}} 173 | 174 | " Implements command-line completion for the :FIGlet command 175 | let s:completionFonts = '' 176 | function! FIGlet#FIGletComplete(arglead, cmdline, cursorpos) "{{{ 177 | if -1 < strridx(a:cmdline, '-f', a:cursorpos) && 178 | \strridx(a:cmdline, '-f', a:cursorpos) == strridx(a:cmdline, '-', a:cursorpos) 179 | "get a listing of *.flf files in s:figletFontDir 180 | if '' == s:completionFonts 181 | let s:completionFonts = join(s:GetFIGletFonts(), "\n") 182 | endif 183 | return s:completionFonts 184 | else 185 | return "-f\n-d\n-p\n-n\n-s\n-S\n-k\n-W\n-o\n-c\n-l\n-r\n-x\n-L\n-R\n-X\n" 186 | endif 187 | endfunction "}}} 188 | 189 | " The guts of the :FIGlet command - runs figlet over a range of lines 190 | function! FIGlet#FIGRange(...) range "{{{ 191 | "figure out the arguments 192 | let i = 0 193 | let opts = '' 194 | let width = '' 195 | let font = '' 196 | let fontdir = '' 197 | while i < len(a:000) 198 | if '-w' == a:000[i] 199 | let width = a:000[i+1] 200 | let i += 2 201 | elseif '-f' == a:000[i] 202 | let font = a:000[i+1] 203 | let i += 2 204 | elseif '-d' == a:000[i] 205 | let fontdir = a:000[i+1] 206 | let i += 2 207 | else 208 | let opts .= a:000[i] . ' ' 209 | let i += 1 210 | endif 211 | endwhile 212 | 213 | "set the cursor's position at the begining of the range 214 | let pos = [0, a:firstline, 0, 0] 215 | 216 | "collect the specified text into a list 217 | let text = getline(a:firstline, a:lastline) 218 | 219 | "delete the original text 220 | execute printf("%d,%dd", a:firstline, a:lastline) 221 | 222 | let figletText = [] 223 | 224 | "render each line in turn, and accumulate the text 225 | try 226 | for line in text 227 | call extend(figletText, RunFIGlet(line, opts, width, font, fontdir)) 228 | endfor 229 | catch /figlet error/ 230 | undo 231 | echoerr "FIGlet failed to render this text" 232 | endtry 233 | 234 | call s:FIGAppend(pos, figletText) 235 | endfunction "}}} 236 | 237 | " The guts of appending FIGlet text into the buffer. 238 | function! s:FIGAppend(pos, figletText) "{{{ 239 | " undo the FIGlet text replacement in one move instead of two 240 | undojoin 241 | 242 | " append() adds text below the cursor line 243 | " so we need to rewind the line by one 244 | call append(a:pos[1] - 1, a:figletText) 245 | 246 | " mark appended FIGlet text boundaries with `[ and `] markers 247 | call setpos("'[", [0, a:pos[1], 0, 0]) 248 | call setpos("']", [0, a:pos[1] + (len(a:figletText) - 1), 0, 0]) 249 | 250 | " restore cursor position 251 | call setpos('.', a:pos) 252 | endfunction "}}} 253 | 254 | " The guts of the g@ operator - delete the text specified by the motion 255 | " & replace it with the result of calling figlet 256 | function! FIGlet#FIGOper(motionType) "{{{ 257 | "save the cursor's position 258 | let pos = getpos('.') 259 | 260 | " save the contents and attributes of the " register 261 | let saveReg = getreg('"') 262 | let saveRegType = getregtype('"') 263 | 264 | " delete the specified text into register " 265 | if a:0 " Invoked from Visual mode, use '< and '> marks. 266 | silent exe "normal! `<" . a:motionType . "`>x" 267 | elseif a:motionType == 'line' 268 | silent exe "normal! '[V']x" 269 | elseif a:motionType == 'block' 270 | silent exe "normal! `[\`]x" 271 | else 272 | silent exe "normal! `[v`]lx" 273 | endif 274 | 275 | " restore register " 276 | let text = substitute(@", '\_s\+', ' ', 'g') 277 | call setreg('"', saveReg, saveRegType) 278 | 279 | " call RunFIGlet() using defaults or global options 280 | try 281 | let figletText = RunFIGlet(text, '', '', '', '') 282 | catch /figlet error/ 283 | undo 284 | echoerr "FIGlet failed to render this text" 285 | endtry 286 | 287 | call s:FIGAppend(pos, figletText) 288 | endfunction "}}} 289 | 290 | echomsg "Hello from autoload/FIGlet.vim" 291 | --------------------------------------------------------------------------------