vim72-20100325-kaoriya-w64j.zip
[MacVim/KaoriYa.git] / runtime / plugin / dicwin.vim
blob7b395c7c7706da38e3f5aafbf77a2800f48840e3
1 " vi:set ts=8 sts=2 sw=2 tw=0 nowrap:
3 " dicwin.vim - Dictionary window
5 " Maintainer:   MURAOKA Taro <koron@tka.att.ne.jp>
6 " Last Change:  04-Aug-2007.
7 " Commands:     <C-k><C-k>  Search word under cursor.
8 "               <C-k>/      Search prompted word.
9 "               <C-k>c      Close dictionary window.
10 "               <C-k>n      Search next. (with last word)
11 "               <C-k>p      Search previous. (with last word)
12 "               <C-k>w      Jump to dictionary window (if exists)
13 " Require:      &runtimepath/dict/gene.txt or &runtimepath/gene.txt
15 " URL where you can get 'gene.txt':
16 "   http://www.namazu.org/~tsuchiya/sdic/data/gene.html
18 if exists('plugin_dicwin_disable')
19   finish
20 endif
21 let s:myname = expand('<sfile>:t:r')
23 " Search default dictionary
24 if !exists('dicwin_dictpath')
25   let s:dict = 'gene.txt'
26   let g:dicwin_dictpath = globpath(&rtp, 'dict/'.s:dict)
27   if g:dicwin_dictpath == ''
28     let dicwin_dictpath = globpath(&rtp, s:dict)
29   endif
30   unlet s:dict
31 endif
32 " Windows return '\\' as directory separator in globpath(), replace it.
33 let dicwin_dictpath = substitute(dicwin_dictpath, '\\', '/', 'g')
35 let s:lastword = ''
36 let s:lastpattern = ''
38 " Kemaps
39 let s:use_mapleader = 0
40 if !exists('g:mapleader')
41   let g:mapleader = "\<C-k>"
42   let s:use_mapleader = 1
43 endif
44 nnoremap <silent> <Leader>k :call <SID>OpenDictionary(g:dicwin_dictpath, expand('<cword>'))<CR>
45 nnoremap <silent> <Leader>n :call <SID>Search(g:dicwin_dictpath, 0)<CR>
46 nnoremap <silent> <Leader>p :call <SID>Search(g:dicwin_dictpath, 1)<CR>
47 nnoremap <silent> <Leader>w :call <SID>GoDictWindow()<CR>
48 nnoremap <silent> <Leader>c :call <SID>Close()<CR>
49 nnoremap <silent> <Leader>/ :call <SID>Query()<CR>
50 nnoremap <silent> <Leader><C-k> :call <SID>OpenDictionary(g:dicwin_dictpath, expand('<cword>'))<CR>
51 nnoremap <silent> <Leader><C-n> :call <SID>Search(g:dicwin_dictpath, 0)<CR>
52 nnoremap <silent> <Leader><C-p> :call <SID>Search(g:dicwin_dictpath, 1)<CR>
53 nnoremap <silent> <Leader><C-w> :call <SID>GoDictWindow()<CR>
54 if s:use_mapleader > 0
55   unlet s:use_mapleader
56   unlet g:mapleader
57 endif
60 " WinEnter/WinLeave hooks
62 function! s:DicWinEnter()
63   if winbufnr(2) > 0
64     exe "normal! 8\<C-W>_"
65   else
66     exe "quit!"
67   endif
68   setlocal wrap
69 endfunction
71 function! s:DicWinLeave()
72   setlocal nowrap
73   normal! zt
74   2 wincmd _
75 endfunction
77 function! s:DicWinUnload()
78   if exists('w:dicwin_dicwin')
79     unlet w:dicwin_dicwin
80   endif
81 endfunction
84 " GenerateSearchPatternEnglish(word)
86 function! s:GenerateSearchPatternEnglish(word)
87   let pat = a:word
88   if pat =~ 's$'
89     if pat =~ 'ies$'
90       let pat = substitute(pat, 'ies$', '\\(ies\\=\\|y\\)', '')
91     else
92       let pat = pat . '\='
93     endif
94   elseif pat =~ 'ied$'
95     let pat = substitute(pat, 'ied$', '\\(y\\|ied\\|ie\\)\\=', '')
96   elseif pat =~ 'ed$'
97     let pat = substitute(pat, 'ed$', '\\(ed\\|e\\)\\=', '')
98   elseif pat =~ 'ing$'
99     if pat =~ '\(.\)\1ing$'
100       let pat = substitute(pat, '\(.\)ing$', '\1\\=\\(ing\\|e\\)\\=', '')
101     else
102       let pat = substitute(pat, 'ing$', '\\(ing\\|e\\)\\=', '')
103     endif
104   elseif pat =~ 'able$'
105     let pat = substitute(pat, 'able$', '\\(able\\|e\\)', '')
106   elseif pat =~ '[.,]$'
107     let pat = substitute(pat, '[,.]$', '', '')
108   endif
109   return "\\c" . pat
110 endfunction
112 function! s:Query()
113   let wquery = input(s:myname. ': Input search word: ')
114   return s:OpenDictionary(g:dicwin_dictpath, wquery)
115 endfunction
118 " Close()
119 "   Close window of dictionary [a:dic].
121 function! s:Close()
122   call s:PrevWindowMark()
123   if s:GoDictWindow() >= 0
124     close
125     call s:PrevWindowRevert()
126   endi
127 endfunction
129 " Search(dic, dir)
130 "   dir: 0:next / 1:previous
131 " Search next/previous word in dictionary.
132 function! s:Search(dic, dir)
133   if filereadable(a:dic) != 1
134     return
135   endif
136   " Check existance of previous searched word
137   if s:lastpattern == '' || s:lastword == ''
138     echohl Error
139     echo s:myname. ': No given word before.'
140     echohl None
141     return
142   endif
143   " Initialize variables for direction
144   if a:dir == 0
145     let cmd = '/'
146     let dirname = 'next'
147     let restart  = 'TOP'
148   else
149     let cmd = '?'
150     let dirname = 'previous'
151     let restart  = 'BOTTOM'
152   endif
153   " Do search
154   call s:PrevWindowMark()
155   call s:OpenDictionaryWindow(a:dic)
156   let line_before = line('.')
157   execute 'silent! normal! ' .cmd. '^' .s:lastpattern. "\\>\<CR>"
158   let line_after = line('.')
159   " Output result
160   if line_before == line_after
161     echohl WarningMsg
162     echo s:myname. ': No other "' .s:lastword. '".'
163   elseif (a:dir == 0 && line_before < line_after) || (a:dir != 0 && line_before > line_after)
164     echo s:myname. ': Found ' .dirname. ' "' .s:lastword. '" in line ' .line_after. '.'
165   else
166     echohl WarningMsg
167     echo s:myname. ': Search from ' .restart. ' and found ' .dirname. ' "' .s:lastword. '".'
168   endif
169   echohl None
170   " Revert previous window
171   call s:PrevWindowRevert()
172 endfunction
174 " OpenDictionary(dic, word)
175 "   Open window of dictionary [a:dic] and search a:word.
177 function! s:OpenDictionary(dic, word)
178   if filereadable(a:dic) != 1
179     return
180   endif
181   if a:word != ''
182     if a:word ==# s:lastword
183       call s:Search(a:dic, 0)
184       return
185     endif
186     " Remember previous window and open dictionary window
187     call s:PrevWindowMark()
188     call s:OpenDictionaryWindow(a:dic)
189     " Search the word
190     let s:lastword = a:word
191     let s:lastpattern = s:GenerateSearchPatternEnglish(a:word)
192     execute "silent! normal! gg/^" . s:lastpattern . "\\%( [+~]\\|$\\)\<CR>"
193     " Output  result
194     if line('.') != 1
195       echo s:myname . ": Found \"" . s:lastword . '".'
196     else
197       echohl ErrorMsg
198       echo s:myname . ": Can't find \"" . s:lastword . '".'
199     endif
200     echohl None
201   else
202     " output 'no word message'
203     echohl WarningMsg
204     echo s:myname . ": No word at under cursor."
205     echohl None
206   endif
207   " Leave dictionary window
208   call s:PrevWindowRevert()
209 endfunction
211 function! s:OpenDictionaryWindow(name)
212   if filereadable(a:name) != 1
213     return
214   endif
215   if s:GoDictWindow() < 0
216     execute "augroup Dictionary"
217     execute "autocmd!"
218     execute "autocmd WinEnter " . a:name . " call <SID>DicWinEnter()"
219     execute "autocmd WinLeave " . a:name . " call <SID>DicWinLeave()"
220     execute "autocmd BufUnload " . a:name . " call <SID>DicWinUnload()"
221     execute "augroup END"
222     execute 'silent normal! :sview ' . a:name ."\<CR>"
223     let w:dicwin_dicwin = 1
224     let s:lastword = ''
225     let s:lastpattern = ''
226     setlocal nowrap
227   endif
228 endfunction
230 function! s:GoDictWindow()
231   return s:GoMarkedWindow('dicwin_dicwin')
232 endfunction
234 function! s:GetMarkedWindow(name)
235   let winnum = 1
236   while winbufnr(winnum) >= 0
237     if getwinvar(winnum, a:name) > 0
238       return winnum
239     endif
240     let winnum = winnum + 1
241   endwhile
242   return -1
243 endfunction
245 function! s:GoMarkedWindow(name)
246   let winnum = s:GetMarkedWindow(a:name)
247   if winnum > 0 && winnr() != winnum
248     execute winnum.'wincmd w'
249   endif
250   return winnum
251 endfunction
253 function! s:PrevWindowMark()
254   let w:dicwin_prevwin = 1
255 endfunction
257 function! s:PrevWindowRevert()
258   if s:GoMarkedWindow('dicwin_prevwin') > 0
259     unlet w:dicwin_prevwin
260   endif
261 endfunction