├── .github
└── FUNDING.yml
├── .gitignore
├── README.markdown
├── doc
└── afterimage.txt
└── plugin
└── afterimage.vim
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: tpope
2 | custom: ["https://www.paypal.me/vimpope"]
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | doc/tags
2 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | afterimage.vim
2 | ==============
3 |
4 | Edit ICO, PNG, and GIF icons. No really. They're converted with
5 | [ImageMagick](http://www.imagemagick.org) to XPM, a plain text image
6 | format with beautiful syntax highlighting in GUI versions of Vim. Here,
7 | it's easier just to show you:
8 |
9 | 
10 |
11 | And yes, I did say edit. Obviously you're not going to be uninstalling
12 | Photoshop anytime soon, but for stupid simple tweaks, it gets the job
13 | done.
14 |
15 | Oh, and it can also handle PDFs (with
16 | [pdftk](http://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/)),
17 | Word Documents (read-only, with [Antiword](http://www.winfield.demon.nl/)),
18 | and Mac OS X plist files.
19 |
20 | Installation
21 | ------------
22 |
23 | If you don't have a preferred installation method, I recommend
24 | installing [pathogen.vim](https://github.com/tpope/vim-pathogen), and
25 | then simply copy and paste:
26 |
27 | cd ~/.vim/bundle
28 | git clone git://github.com/tpope/vim-afterimage.git
29 |
30 | Once help tags have been generated, you can view the manual with
31 | `:help afterimage`.
32 |
33 | Contributing
34 | ------------
35 |
36 | See the contribution guidelines for
37 | [pathogen.vim](https://github.com/tpope/vim-pathogen#readme).
38 |
39 | Self-Promotion
40 | --------------
41 |
42 | Like afterimage.vim? Follow the repository on
43 | [GitHub](https://github.com/tpope/vim-afterimage) and vote for it on
44 | [vim.org](http://www.vim.org/scripts/script.php?script_id=1617). And if
45 | you're feeling especially charitable, follow [tpope](http://tpo.pe/) on
46 | [Twitter](http://twitter.com/tpope) and
47 | [GitHub](https://github.com/tpope).
48 |
49 | License
50 | -------
51 |
52 | Copyright (c) Tim Pope. Distributed under the same terms as Vim itself.
53 | See `:help license`.
54 |
--------------------------------------------------------------------------------
/doc/afterimage.txt:
--------------------------------------------------------------------------------
1 | *afterimage.txt* Edit binary files by converting them to text
2 |
3 | Author: Tim Pope
4 | License: Same terms as Vim itself (see |license|)
5 |
6 | This plugin is only available if 'compatible' is not set.
7 |
8 | BUILT-INS *afterimage-built-ins*
9 |
10 | PNGs, BMPs and GIFs are converted to/from XPM with ImageMagick. XPM is a
11 | plain text format that resembles a C header. GUI versions of Vim will
12 | actually syntax highlight the image data to resemble the original. While no
13 | replacement for a real image editor, this built-in can and has been used to
14 | tweak small icons.
15 |
16 | PDFs are uncompressed/recompressed with pdftk. Even when decompressed, PDFs
17 | are partially a binary format, so this is mostly a novelty.
18 |
19 | Word documents have their text extracted (one way) with antiword.
20 |
21 | OS X binary plists are converted to/from XML with plutil.
22 |
23 | CUSTOMIZATION *afterimage-customization*
24 |
25 | The easiest way to provide custom handlers is to learn from the source to the
26 | built-ins. Briefly:
27 |
28 | AfterimageReadPost() should be called from a BufReadPost,FileReadPost autocmd,
29 | with the argument being a string containing the command to run. The source
30 | and destination files should each be replaced by %s and must appear in that
31 | order. If this function returns true, that means that an entire file was
32 | successfully converted, and that it is appropriate to issue commands like "set
33 | readonly" or "setf myfiletype".
34 |
35 | AfterimageWriteCmd() should be called from a BufWriteCmd,FileWriteCmd autocmd.
36 | The argument is a command in the same format AfterimageReadPost() requires.
37 |
38 | Don't forget to setlocal binary in a BufReadPre,FileReadPre autocmd if the
39 | file is in fact binary.
40 |
41 | If you have a customization you think others could use, feel free to submit it
42 | to the author of this plugin.
43 |
44 | vim:tw=78:et:ft=help:norl:
45 |
--------------------------------------------------------------------------------
/plugin/afterimage.vim:
--------------------------------------------------------------------------------
1 | " afterimage.vim - Edit binary files by converting them to text
2 | " Maintainer: Tim Pope
3 | " Version: 2.2
4 |
5 | " Licensed under the same terms as Vim itself.
6 |
7 | if exists("loaded_afterimage") || &cp
8 | finish
9 | endif
10 | let g:loaded_afterimage = 1
11 |
12 | augroup afterimage
13 | autocmd!
14 |
15 | if !exists("#BufWriteCmd#*.png")
16 | autocmd BufReadPre,FileReadPre *.png,*.gif,*.bmp,*.ico setlocal bin
17 | autocmd BufReadPost,FileReadPost *.png,*.gif,*.bmp if AfterimageReadPost("convert %s xpm:%s")|set ft=xpm|endif|setlocal nobin
18 | autocmd BufReadPost,FileReadPost *.ico if AfterimageReadPost("convert ico:%s xpm:%s")|set ft=xpm|endif|setlocal nobin
19 | autocmd BufWriteCmd,FileWriteCmd *.png call AfterimageWriteCmd("convert %s png:%s")
20 | autocmd BufWriteCmd,FileWriteCmd *.gif call AfterimageWriteCmd("convert %s gif:%s")
21 | autocmd BufWriteCmd,FileWriteCmd *.ico call AfterimageWriteCmd("convert %s ico:%s")
22 | autocmd BufWriteCmd,FileWriteCmd *.bmp call AfterimageWriteCmd("convert %s bmp:%s")
23 | endif
24 |
25 | if !exists("#BufWriteCmd#*.pdf")
26 | autocmd BufReadPre,FileReadPre *.pdf setlocal bin
27 | autocmd BufReadPost,FileReadPost *.pdf call AfterimageReadPost("pdftk %s output %s uncompress")
28 | autocmd BufWriteCmd,FileWriteCmd *.pdf call AfterimageWriteCmd("pdftk %s output %s compress")
29 | endif
30 |
31 | if !exists("#BufReadPre#*.doc")
32 | autocmd BufReadPre,FileReadPre *.doc setlocal bin
33 | autocmd BufReadPost,FileReadPost *.doc if AfterimageReadPost("antiword %s > %s") | setlocal readonly | endif
34 | endif
35 |
36 | if !exists("#BufWriteCmd#*.plist")
37 | autocmd BufReadPre,FileReadPre *.plist setlocal bin ts=2 sw=2
38 | autocmd BufReadPost,FileReadPost *.plist call s:readplist()
39 | autocmd BufWriteCmd,FileWriteCmd *.plist call s:writeplist()
40 | endif
41 |
42 | augroup END
43 |
44 | " Helper functions {{{1
45 |
46 | function! s:esc(arg)
47 | if exists("*shellescape")
48 | return (shellescape(a:arg))
49 | else
50 | return '"'.a:arg.'"'
51 | endif
52 | endfunction
53 |
54 | " Function to check that executing "cmd" works.
55 | " The result is cached in s:have_"cmd" for speed.
56 | function! s:check(cmd)
57 | let name = substitute(a:cmd, '\(\S*\).*', '\1', '')
58 | if !exists("s:have_" . name)
59 | let e = executable(name)
60 | if e < 0
61 | let r = system(name)
62 | let e = (r !~ "not found" && r != "")
63 | endif
64 | exe "let s:have_" . name . "=" . e
65 | endif
66 | exe "return s:have_" . name
67 | endfunction
68 |
69 | " }}}1
70 |
71 | function! AfterimageReadPost(cmd) " {{{1
72 | " AfterimageReadPost() returns true if the process was successful *and* if
73 | " it was an entire file that was converted. This is a good condition on
74 | " which to do things like setting the filetype.
75 | if !s:check(a:cmd)
76 | return 0
77 | endif
78 | " make 'patchmode' empty, we don't want a copy of the written file
79 | let pm_save = &pm
80 | set pm=
81 | " remove 'a' and 'A' from 'cpo' to avoid the alternate file changes
82 | let cpo_save = &cpo
83 | set cpo-=a cpo-=A
84 | " set 'modifiable'
85 | let ma_save = &ma
86 | setlocal ma
87 | " when filtering the whole buffer, it will become empty
88 | let empty = line("'[") == 1 && line("']") == line("$")
89 | let tmp1 = tempname()
90 | let tmp2 = tempname()
91 | " write the just read lines to a temp file
92 | execute "silent '[,']w " . tmp1
93 | " convert the temp file, modified for imagemagick
94 | call system(printf(a:cmd,s:esc(tmp1),s:esc(tmp2)))
95 | " delete the binary lines; remember the line number
96 | let l = line("'[") - 1
97 | if exists(":lockmarks")
98 | lockmarks '[,']d _
99 | else
100 | '[,']d _
101 | endif
102 | " read in the converted lines
103 | setlocal bin
104 | if exists(":lockmarks")
105 | execute "silent lockmarks " . l . "r " . tmp2
106 | else
107 | execute "silent " . l . "r " . tmp2
108 | endif
109 |
110 | " if buffer became empty, delete trailing blank line
111 | if empty
112 | silent $delete _
113 | 1
114 | endif
115 | " delete the temp file and the used buffers
116 | call delete(tmp2)
117 | call delete(tmp1)
118 | silent! exe "bwipe " . tmp2
119 | silent! exe "bwipe " . tmp1
120 | let &pm = pm_save
121 | let &cpo = cpo_save
122 | let &l:ma = ma_save
123 |
124 | return empty
125 | endfunction " }}}1
126 |
127 | function! AfterimageWriteCmd(cmd) " {{{1
128 | if s:check(a:cmd)
129 | let nm = expand("")
130 | let tmp1 = tempname()
131 | let tmp2 = tempname()
132 | exe "noautocmd w ".tmp1
133 | call system(printf(a:cmd,s:esc(tmp1),s:esc(tmp2)))
134 | if !v:shell_error
135 | call rename(tmp2, nm)
136 | setlocal nomodified
137 | else
138 | echohl ErrorMsg
139 | echo "An error occured while trying to convert the file."
140 | echohl NONE
141 | endif
142 | call delete(tmp1)
143 | else
144 | noautocmd w
145 | endif
146 | endfunction " }}}1
147 |
148 | " plist helpers {{{1
149 |
150 | function! s:readplist()
151 | if getline(1) =~ ''
152 | let b:plist_format = "xml1"
153 | setlocal nobin
154 | return
155 | endif
156 | let b:plist_format = "binary1"
157 | if AfterimageReadPost("plutil -convert xml1 %s -o %s")
158 | setf xml
159 | return 1
160 | else
161 | return 0
162 | endif
163 | endfunction
164 |
165 | function! s:writeplist()
166 | if !exists("b:plist_format")
167 | let b:plist_format = "xml1"
168 | endif
169 | call AfterimageWriteCmd("plutil -convert ".b:plist_format." %s -o %s")
170 | endfunction
171 |
172 | " }}}1
173 |
174 | " vim: set sw=2:
175 |
--------------------------------------------------------------------------------