blob: 26fade4d275e10fbe498bffcab53b1b79dbf578c [file] [log] [blame]
Bram Moolenaardfccaf02004-12-31 20:56:11 +00001" vim:set ts=4 sw=4 ai nobackup:
2
3" tar.vim -- a vim plugin for browsing tarfiles
4" Copyright (c) 2002, Michael C. Toren <mct@toren.net>
5"
6" Updates are available from <http://michael.toren.net/code/>. If you
7" find this script useful, or have suggestions for improvements, please
8" let me know.
9"
10" Usage:
11" Once this script is installed, attempting to edit a tarfile will present
12" the user with a list of files contained in the tar archive. By moving the
13" cursor over a filename and pressing ENTER, the contents of a file can be
14" viewed in read-only mode, in a new window. Unfortunately, write support
15" for tarfile components is not currently possible.
16"
17" Requirements:
18" GNU tar, or a tar implementation that supports the "P" (don't strip
19" out leading /'s from filenames), and "O" (extract files to standard
20" output) options. Additionally, gzip is required for handling *.tar.Z,
21" *.tar.gz, and *.tgz compressed tarfiles, and bzip2 is required for
22" handling *.tar.bz2 compressed tarfiles. A unix-like operating system
23" is probably also required.
24"
25" Installation:
26" Place this file, tar.vim, in your $HOME/.vim/plugin directory, and
27" either restart vim, or execute ":source $HOME/.vim/plugin/tar.vim"
28"
29" Todo:
30" - Handle zipfiles?
31" - Implement write support, somehow.
32"
33" License:
34" This program is free software; you can redistribute it and/or modify it
35" under the terms of the GNU General Public License, version 2, as published
36" by the Free Software Foundation.
37"
38" This program is distributed in the hope that it will be useful, but
39" WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
40" or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41" for more details.
42"
43" A copy of the GNU GPL is available as /usr/doc/copyright/GPL on Debian
44" systems, or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html
45" You can also obtain it by writing to the Free Software Foundation, Inc.,
46" 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
47"
48" Changelog:
49" Tue Dec 31 13:38:08 EST 2002 First release to beta testers
50" Sat Jan 4 14:06:19 EST 2003 Version 1.00 released
51
52let s:version = "1.00"
53
54if has("autocmd")
55augroup tar
56 au!
57 au BufReadCmd tarfile:* call s:TarRead(expand("<afile>"), 1)
58 au BufReadCmd tarfile:*/* call s:TarRead(expand("<afile>"), 1)
59 au FileReadCmd tarfile:* call s:TarRead(expand("<afile>"), 0)
60 au FileReadCmd tarfile:*/* call s:TarRead(expand("<afile>"), 0)
61
62 au BufWriteCmd tarfile:* call s:TarWrite(expand("<afile>"))
63 au BufWriteCmd tarfile:*/* call s:TarWrite(expand("<afile>"))
64 au FileWriteCmd tarfile:* call s:TarWrite(expand("<afile>"))
65 au FileWriteCmd tarfile:*/* call s:TarWrite(expand("<afile>"))
66
67 au BufReadCmd *.tar call s:TarBrowse(expand("<afile>"))
68 au BufReadCmd *.tar.gz call s:TarBrowse(expand("<afile>"))
69 au BufReadCmd *.tar.bz2 call s:TarBrowse(expand("<afile>"))
70 au BufReadCmd *.tar.Z call s:TarBrowse(expand("<afile>"))
71 au BufReadCmd *.tgz call s:TarBrowse(expand("<afile>"))
72augroup END
73endif
74
75function! s:TarWrite(argument)
76 echo "ERROR: Sorry, no write support for tarfiles yet"
77endfunction
78
79function! s:TarRead(argument, cleanup)
80 let l:argument = a:argument
81 let l:argument = substitute(l:argument, '^tarfile:', '', '')
82 let l:argument = substitute(l:argument, '^\~', $HOME, '')
83
84 let l:tarfile = l:argument
85 while 1
86 if (l:tarfile == "" || l:tarfile == "/")
87 echo "ERROR: Could not find a readable tarfile in path:" l:argument
88 return
89 endif
90
91 if filereadable(l:tarfile) " found it!
92 break
93 endif
94
95 let l:tarfile = fnamemodify(l:tarfile, ":h")
96 endwhile
97
98 let l:toextract = strpart(l:argument, strlen(l:tarfile) + 1)
99
100 if (l:toextract == "")
101 return
102 endif
103
104 let l:cat = s:TarCatCommand(l:tarfile)
105 execute "r !" . l:cat . " < '" . l:tarfile . "'"
106 \ " | tar OPxf - '" . l:toextract . "'"
107
108 if (a:cleanup)
109 0d "blank line
110 execute "doautocmd BufReadPost " . expand("%")
111 setlocal readonly
112 silent preserve
113 endif
114endfunction
115
116function! s:TarBrowse(tarfile)
117 setlocal noswapfile
118 setlocal buftype=nofile
119 setlocal bufhidden=hide
120 setlocal filetype=
121 setlocal nobuflisted
122 setlocal buftype=nofile
123 setlocal wrap
124
125 let l:tarfile = a:tarfile
126 let b:tarfile = l:tarfile
127 let l:cat = s:TarCatCommand(l:tarfile)
128
129 if ! filereadable(l:tarfile)
130 let l:tarfile = substitute(l:tarfile, '^tarfile:', '', '')
131 endif
132
133 if ! filereadable(l:tarfile)
134 echo "ERROR: File not readable:" l:tarfile
135 return
136 endif
137
138 call s:Say("\" tar.vim version " . s:version)
139 call s:Say("\" Browsing tarfile " . l:tarfile)
140 call s:Say("\" Hit ENTER to view contents in new window")
141 call s:Say("")
142
143 silent execute "r!" . l:cat . "<'" . l:tarfile . "'| tar Ptf - "
144 0d "blank line
145 /^$/1
146
147 setlocal readonly
148 setlocal nomodifiable
149 noremap <silent> <buffer> <cr> :call <SID>TarBrowseSelect()<cr>
150endfunction
151
152function! s:TarBrowseSelect()
153 let l:line = getline(".")
154
155 if (l:line =~ '^" ')
156 return
157 endif
158
159 if (l:line =~ '/$')
160 echo "Please specify a file, not a directory"
161 return
162 endif
163
164 let l:selection = "tarfile:" . b:tarfile . "/" . l:line
165 new
166 wincmd _
167 execute "e " . l:selection
168endfunction
169
170" kludge to deal with compressed archives
171function! s:TarCatCommand(tarfile)
172 if a:tarfile =~# '\.\(gz\|tgz\|Z\)$'
173 let l:cat = "gzip -d -c"
174 elseif a:tarfile =~# '\.bz2$'
175 let l:cat = "bzip2 -d -c"
176 else
177 let l:cat = "cat"
178 endif
179 return l:cat
180endfunction
181
182function! s:Say(string)
183 let @" = a:string
184 $ put
185endfunction