パーソナルツール

head.vim

作者: 小見 拓 最終変更 2012年01月08日 12時13分

  1 " 1度スクリプトを読み込んだら、2度目は読み込まない
  2 :if exists('loaded_head')
  3     :finish
  4 :endif
  5 :let loaded_head = 1
  6
  7 " g:head_file_splitterオプションが設定されていたら、、
  8 " そのオプションの値を使用する
  9 " g:head_file_splitterオプションが設定されていなかったら、、
 10 " スクリプトで定義したデフォルト値を使用する
 11 :if exists('g:head_file_splitter')
 12     :let s:spc = g:head_file_splitter
 13 :else
 14     :if has('win32')
 15         :let s:spc = ";"
 16     :else
 17         :let s:spc = ":"
 18     :endif
 19 :endif
 20
 21 " g:head_display_linesオプションが設定されていたら、その値を使用する
 22 " 設定されていなかったら、スクリプトのデフォルト値を使用する
 23 :if exists('g:head_display_lines')
 24     :let s:viewsize = g:head_display_lines
 25 :else
 26     :let s:viewsize = 10
 27 :endif
 28
 29 " 渡された値で、s:viewsizeを更新する
 30 :function! s:UpdateViewSize(size)
 31     :let s:viewsize = a:size
 32 :endfunction
 33
 34 " head:sample.txt、もしくは、head;sample.txt
 35 " というファイル名を渡されるので、
 36 " このファイルの上の方だけを読み込む
 37 :function! s:HeadRead(path)
 38     " <afile>ならexpand()で展開する
 39     " そうでないなら渡されたファイル名を使用する
 40     :if a:path == "<afile>"
 41         :let l:file = expand(a:path)
 42     :else
 43         :let l:file = a:path
 44     :endif
 45
 46     " 実際に読む込むべきファイルのパスを取得
 47     :let l:prot = matchstr(l:file,'^\(head\)\ze' . s:spc)
 48     :if l:prot != ''
 49         :let l:file = strpart(l:file, strlen(l:prot) + 1)
 50     :endif
 51
 52     " ファイルを読み込んで、バッファにセット
 53     :0,$d
 54     :call setline(1,"foo")
 55     :let l:lines = readfile(l:file, "", s:viewsize)
 56     :let l:i = 0
 57     :while l:i < len(l:lines)
 58         :call setline(l:i + 2, l:lines[l:i])
 59         :let l:i += 1
 60     :endwhile
 61     :1d
 62
 63     " 編集中ではない状態にする
 64     :set nomodified
 65     " ファイルタイプを再判定
 66     :filetype detect
 67 :endfunction
 68
 69 " head:sample.txt、もしくは、head;sample.txt
 70 " というファイル名を渡されるので、
 71 " このファイルの上の方だけをバッファのテキストで更新する
 72 :function! s:HeadWrite(path)
 73     " <afile>ならexpand()で展開する
 74     " そうでないなら渡されたファイル名を使用する
 75     :if a:path == "<afile>"
 76         :let l:file = expand(a:path)
 77     :else
 78         :let l:file = a:path
 79     :endif
 80
 81     " 実際に読む込むべきファイルのパスを取得
 82     :let l:prot = matchstr(l:file,'^\(head\)\ze' . s:spc)
 83     :if l:prot != ''
 84         :let l:file = strpart(l:file, strlen(l:prot) + 1)
 85     :endif
 86
 87     " 更新しても良いか、ユーザに問い合わせ
 88     :let choice = confirm("Are you sure, update '".l:file."' head ?", "&Update\n&Cancel")
 89     :if choice == 1
 90         " 全行読み込んで、ファイルの上の方だけ更新
 91         " 最後に編集中状態をクリア。編集していない状態にする。
 92         :let l:lines = filereadable(l:file)? readfile(l:file): []
 93         :if len(l:lines) > s:viewsize
 94             :let l:i = 0
 95             :while l:i < s:viewsize
 96                 :unlet l:lines[l:i- 1]
 97                 :let l:i += 1
 98             :endwhile
 99
100             :let l:curbufs = getline(0, line("$"))
101             :call extend(l:curbufs, l:lines)
102             :call writefile(l:curbufs, l:file)
103             :set nomodified
104         :else
105             :call writefile(getline(0, line("$")), l:file)
106             :set nomodified
107         :endif
108         :return
109     :else
110         :return
111     :endif
112 :endfunction
113
114 " tail:sample.txt、もしくは、tail;sample.txt
115 " というファイル名を渡されるので、
116 " このファイルの下の方だけをバッファに読み込む。
117 :function! s:TailRead(path)
118     " <afile>ならexpand()で展開する
119     " そうでないなら渡されたファイル名を使用する
120     :if a:path == "<afile>"
121         :let l:file = expand(a:path)
122     :else
123         :let l:file = a:path
124     :endif
125
126     " 実際に読む込むべきファイルのパスを取得
127     :let l:prot = matchstr(l:file,'^\(tail\)\ze' . s:spc)
128     :if l:prot != ''
129         :let l:file = strpart(l:file, strlen(l:prot) + 1)
130     :endif
131
132     " ファイルを下の方だけ読み込んで、バッファにセットする
133     :0,$d
134     :call setline(1,"foo")
135     :let l:lines = readfile(l:file)
136     :if len(l:lines) > s:viewsize
137         :let l:i = 0
138         :while l:i < s:viewsize
139             :call setline(l:i + 2, l:lines[len(l:lines) - s:viewsize + l:i])
140             :let l:i += 1
141         :endwhile
142     :else
143         :let l:i = 0
144         :while l:i < len(l:lines)
145             :call setline(l:i + 2, l:lines[l:i])
146             :let l:i += 1
147         :endwhile
148     :endif
149     :1d
150
151     " 編集中ではない状態にする
152     :set nomodified
153     " ファイルタイプを再判定
154     :filetype detect
155 :endfunction
156
157 " tail:sample.txt、もしくは、tail;sample.txt
158 " というファイル名を渡されるので、
159 " このファイルの下の方だけをバッファのテキストで更新する
160 :function! s:TailWrite(path)
161     " <afile>ならexpand()で展開する
162     " そうでないなら渡されたファイル名を使用する
163     :if a:path == "<afile>"
164         :let l:file = expand(a:path)
165     :else
166         :let l:file = a:path
167     :endif
168
169     " 実際に読む込むべきファイルのパスを取得
170     :let l:prot = matchstr(l:file,'^\(tail\)\ze' . s:spc)
171     :if l:prot != ''
172         :let l:file = strpart(l:file, strlen(l:prot) + 1)
173     :endif
174
175     " 更新しても良いか、ユーザに問い合わせ
176     :let choice = confirm("Are you sure, update '".l:file."' tail ?", "&Update\n&Cancel")
177     :if choice == 1
178         " 全行読み込んで、ファイルの下の方だけ更新
179         " 最後に編集中状態をクリア。編集していない状態にする。
180         :let l:lines = filereadable(l:file)? readfile(l:file): []
181         :if len(l:lines) > s:viewsize
182             :let l:i = 0
183             :while l:i < s:viewsize
184                 :unlet l:lines[len(l:lines) - 1]
185                 :let l:i += 1
186             :endwhile
187             :call extend(l:lines, getline(0, line("$")))
188             :call writefile(l:lines, l:file)
189             :set nomodified
190         :else
191             :call writefile(getline(0, line("$")), l:file)
192             :set nomodified
193         :endif
194         :return
195     :else
196         :return
197     :endif
198 :endfunction
199
200 " autocmdのグループを定義
201 " head、tailで始まるファイルは、他のスクリプトに操作させたくないので、
202 " autocmd!で、設定されたautocmdを消してしまう。
203 :augroup Head
204     :autocmd!
205     :execute ":autocmd BufReadCmd   head" .s:spc. "*,head" .s:spc. "*/* HeadRead  <afile>"
206     :execute ":autocmd FileReadCmd  head" .s:spc. "*,head" .s:spc. "*/* HeadRead  <afile>"
207     :execute ":autocmd BufWriteCmd  head" .s:spc. "*,head" .s:spc. "*/* HeadWrite <afile>"
208     :execute ":autocmd FileWriteCmd head" .s:spc. "*,head" .s:spc. "*/* HeadWrite <afile>"
209 :augroup END
210 :augroup Tail
211     :autocmd!
212     :execute ":autocmd BufReadCmd   tail" .s:spc. "*,tail" .s:spc. "*/* TailRead  <afile>"
213     :execute ":autocmd FileReadCmd  tail" .s:spc. "*,tail" .s:spc. "*/* TailRead  <afile>"
214     :execute ":autocmd BufWriteCmd  tail" .s:spc. "*,tail" .s:spc. "*/* TailWrite <afile>"
215     :execute ":autocmd FileWriteCmd tail" .s:spc. "*,tail" .s:spc. "*/* TailWrite <afile>"
216 :augroup END
217
218 " ファイルの読み書き用のコマンドを定義
219 :command! -nargs=1 HeadRead  :call s:HeadRead(<f-args>)
220 :command! -nargs=1 HeadWrite :call s:HeadWrite(<f-args>)
221 :command! -nargs=1 TailRead  :call s:TailRead(<f-args>)
222 :command! -nargs=1 TailWrite :call s:TailWrite(<f-args>)
223
224 " プロパティ更新用のコマンドを定義
225 :command! -nargs=1 Head      :call s:UpdateViewSize(<f-args>)
226
227 " スクリプトはここまで
228 :finish
229
230 ==============================================================================
231 スクリプトの説明
232
233 "head;"(Windows以外ではhead:)をファイル名に付けると、
234 ファイルの上から10行のみを読み込み、
235 "tail;"(Windows以外ではtail:)をファイル名に付けると、
236 ファイルの下から10行のみを読み込む。
237 sudo.vimのような処理を行う。
238
239 (Windows)
240 :e head;sample.txt
241 :r head;sample.txt
242 :w head;sample.txt
243 :e tail;sample.txt
244 :r tail;sample.txt
245 :w tail;sample.txt
246
247 (Windows以外)
248 :e head:sample.txt
249 :r head:sample.txt
250 :w head:sample.txt
251 :e tail:sample.txt
252 :r tail:sample.txt
253 :w tail:sample.txt
254
255 ==============================================================================
256 見るべきところ
257
258 ・ユーザーの設定の値の取り方
259 ・augroup、autocmdの使い方
260 ・実際には存在しない、"head;sample.txt""tail;sample.txt"という名前のファイルへの操作をautocmdで横取りする。
261 "set nomodified"で、編集中の状態をリセット
262 "filetype detect"で、ファイルタイプを判定できる
263 ・ユーザに質問を投げて、その結果で処理を変える
264
265 ==============================================================================
266
267 " vim: set et nowrap ff=unix ft=vim :
ドキュメントアクション
コメント
blog comments powered by Disqus