1"
2" Filename: cream-pop.vim
3"
4" Cream -- An easy-to-use configuration of the famous Vim text editor
5" [ http://cream.sourceforge.net ] Copyright (C) 2001-2011 Steve Hall
6"
7" License:
8" This program is free software; you can redistribute it and/or modify
9" it under the terms of the GNU General Public License as published by
10" the Free Software Foundation; either version 3 of the License, or
11" (at your option) any later version.
12" (http://www.gnu.org/licenses/gpl.html)
13"
14" This program is distributed in the hope that it will be useful, but
15" WITHOUT ANY WARRANTY; without even the implied warranty of
16" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17" General Public License for more details.
18"
19" You should have received a copy of the GNU General Public License
20" along with this program; if not, write to the Free Software
21" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22" 02111-1307, USA.
23"
24" Description:
25" Pops up a menu at the cursor upon "(" when the preceding word
26" matches a previously initialized variable (function name). This
27" variable is filetype specific, although general functions can be
28" made global by inclusion .
29"
30" We use the :popup function to display it at the cursor (Win32 only
31" support by Vim at the moment). If there's a match, the function is
32" popped; otherwise it's ignored.
33"
34" Notes:
35" * Default popup menu is restored via Cream_menu_popup() every
36"   <LeftMouse>
37"
38
39function! Cream_pop(word)
40" pop up a menu matching the global variable passed
41" * Assumes a global menu variable (passed in the form "g:TestCow")
42"   already exists (must verify before here!)
43
44	" create popup menu item with same name as variable
45	execute 'let mymenuname = a:word'
46	" remove initial "g:"
47	let mymenuname = strpart(mymenuname, 2)
48	" remove initial encoding + "_"
49	let mypos = match(mymenuname, "_") + 1
50	let mymenuname = strpart(mymenuname, mypos)
51	execute 'let mydescription = ' . a:word . '_menu'
52
53	" display
54	call Cream_pop_menu(mydescription)
55
56	" TODO: now loop and enter every char exactly as entered
57	" until user hits Esc, Enter, motion or end parenthesis
58
59endfunction
60
61function! Cream_pop_words(filetype, word, menu)
62" create global based on the name and create the abbreviation
63" * First argument is intended filetype
64" * Second argument is function name (or, more generally, the object
65"   to be completed on)
66" * Third argument is the description, to be explained between the
67"   parenthesis
68
69	" validate function name
70	" no spaces allowed
71	if match(a:word, " ") != -1
72		call confirm(
73			\ "Invalid function name passed to Cream_pop_words():\n" .
74			\ "   \"" . a:word . "\"\n" .
75			\ "\n" .
76			\ "Quitting..." .
77			\ "\n", "&Ok", 1, "Info")
78		return
79	endif
80
81	" handle ampersands on Win32
82	if has("win32")
83		let menu_contents = substitute(a:menu, '&', '&&', 'g')
84	else
85		let menu_contents = a:menu
86	endif
87
88	" expose global for name *** CONTAINS MENU NAME, minus filename + "_"! ***
89	execute "let g:pop_" . a:filetype . "_" . a:word . ' = a:word'
90	" expose global for menu contents
91	execute "let g:pop_" . a:filetype . "_" . a:word . "_menu = \"" . menu_contents . "\""
92
93endfunction
94
95function! Cream_pop_paren_map(...)
96" use parenthesis to pop up function def info (if global by same name
97" exists)
98" special arguments:
99" o (any)     -- avoids "not found" dialog
100" o "autopop" -- avoids trying current function
101
102	if a:0 > 0
103		let myarg = a:1
104	else
105		let myarg = ""
106	endif
107
108	" back up behind parenthesis to check
109	normal h
110
111	" unless we are at the very end of the line, we need to go back in
112	" order to find the last word typed.
113	if virtcol('.') != virtcol('$')
114		normal! h
115		let myword = expand('<cword>')
116		normal! l
117	else
118		let myword = expand('<cword>')
119	endif
120
121
122	"..........................................................
123	" try our conditioned environment first
124	let word = "g:pop_nil_" . myword
125	if exists(word)
126		" do Pop
127		call Cream_pop(word)
128		return
129	endif
130
131	"..........................................................
132	" try filetype-specific next
133	let word = "g:pop_" . &filetype . "_" . myword
134	if exists(word)
135		" do Pop
136		call Cream_pop(word)
137		return
138	endif
139
140	"..........................................................
141	" try remote function prototype via ctag
142	let mytag = expand("<cword>")
143	" remember pos and file
144	let myvcol = virtcol('.')
145	let myline = line('.')
146	let mybufnr = bufnr("%")
147	let mypos = Cream_pos()
148	" do jump
149	execute "silent! tag " . mytag
150	if  myvcol != virtcol('.')
151	\|| myline != line('.')
152	\|| mybufnr != bufnr("%")
153		" get prototype
154		let myprototype = Cream_Tlist_prototype()
155		" jump back
156		silent! pop
157		" position
158		execute mypos
159		redraw
160		" TODO: remove one from bottom of stack list (forget this jump)
161		"...
162		" display prototype
163		call Cream_pop_menu(myprototype)
164
165		return
166	endif
167	" don't jump back, we didn't move or add to stack
168
169	"..........................................................
170	" quit here if if called via AutoPop
171	if myarg ==? "autopop"
172		" fix position
173		normal l
174		return
175	endif
176
177	"..........................................................
178	" try current function prototype
179	let myprototype = Cream_Tlist_prototype()
180	if myprototype != ""
181		" popup
182		call Cream_pop_menu("current:     " . myprototype)
183		return
184	endif
185
186	if myarg ==? ""
187		" Dialog: no info available
188		let n = confirm(
189			\ "No information available for this word.\n" .
190			\ "\n", "&Ok", 1, "Info")
191	endif
192
193	" fix position
194	normal l
195
196endfunction
197
198function! Cream_pop_menu(menuitem)
199" pop up the prototype under the cursor
200
201	if a:menuitem != ""
202
203		silent! unmenu PopUp
204		silent! unmenu! PopUp
205
206		let menuitem_esc = escape(a:menuitem, ' \.')
207		" handle ampersands on Win32
208		if has("win32")
209			let menuitem_esc = substitute(menuitem_esc, '&', '&&', 'g')
210		endif
211
212		" provide a more free-form description
213		execute 'imenu <silent> PopUp.' . menuitem_esc. ' ' . a:menuitem
214
215		" display
216		" silent causes first usage to do nothing (Win95, 2003-04-04)
217		" BUG HACK: first time through, fails, do twice
218		if !exists("g:cream_popup")
219			let g:cream_popup = 1
220			silent! popup PopUp
221		endif
222		silent! popup PopUp
223
224		" un-backup space check
225		normal l
226		return 1
227
228	endif
229	return 0
230
231endfunction
232
233function! Cream_pop_options()
234" allow user to control pop preference
235" * assumes global has been initialized prior to here
236
237	" only windows has the :popup feature (for now)
238	if !has("win32") && !has("gui_gtk")
239		call confirm(
240			\ "Sorry, Vim's \":popup\" feature is only supported on \n" .
241			\ "the Windows and GTK platforms.\n" .
242			\ "\n", "&Ok", 2, "Warning")
243		return
244	elseif has("gui_gtk") && v:version < 601
245	\ ||   has("gui_gtk") && v:version == 601 && !has("patch433")
246		call confirm(
247			\ "Support for Vim's \":popup\" feature on GTK \n" .
248			\ "was added in version 6.1.433. Please upgrade to use.\n" .
249			\ "\n", "&Continue\n&Quit", 2, "Warning")
250		return
251	endif
252
253	let n = confirm(
254		\ "Use auto-popup information feature? (Prototype indicated\n" .
255		\ "every time an open parenthesis is typed.)\n" .
256		\ "\n", "&Yes\n&No\n&Cancel", 1, "Info")
257	if     n == 1
258		let g:CREAM_POP_AUTO = 1
259		imap <silent> ( (<C-b>:call Cream_pop_paren_map("autopop")<CR>
260	elseif n == 2
261		let g:CREAM_POP_AUTO = 0
262		silent! iunmap (
263	endif
264
265endfunction
266
267function! Cream_pop_init()
268" initializes global auto-pop variable
269
270	"" only windows has the :popup feature (for now)
271	"if !has("win32")
272	"    return
273	"endif
274
275	" make pop automatic upon "("  (default: off)
276	if !exists("g:CREAM_POP_AUTO")
277		let g:CREAM_POP_AUTO = 0
278	endif
279
280	" auto pop (require two parenthesis if off--and single will delay!)
281	if g:CREAM_POP_AUTO == 1
282		imap <silent> ( (<C-b>:call Cream_pop_paren_map("autopop")<CR>
283	endif
284
285endfunction
286
287"=
288" List pop up items
289"
290" * Use "nil" for info boxes on words across any filetype.
291
292"" create fake popup items
293"call Cream_pop_words('nil', 'TestBob', ' NOPE!!!')
294"call Cream_pop_words('vim', 'TestCow', 'size, color, horns')
295
296" vim functions {{{1
297"call Cream_pop_words('vim', 'append', 'append( {lnum}, {string} ) -- append {string} below line {lnum}')
298"call Cream_pop_words('vim', 'argc', 'argc() -- number of files in the argument list')
299"call Cream_pop_words('vim', 'argidx', 'argidx() -- current index in the argument list')
300"call Cream_pop_words('vim', 'argv', 'argv( {nr} ) -- {nr} entry of the argument list')
301"call Cream_pop_words('vim', 'browse', 'browse( {save}, {title}, {initdir}, {default} ) -- put up a file requester')
302"call Cream_pop_words('vim', 'bufexists', 'bufexists( {expr} ) -- TRUE if buffer {expr} exists')
303"call Cream_pop_words('vim', 'buflisted', 'buflisted( {expr} ) -- TRUE if buffer {expr} is listed')
304"call Cream_pop_words('vim', 'bufloaded', 'bufloaded( {expr} ) -- TRUE if buffer {expr} is loaded')
305"call Cream_pop_words('vim', 'bufname', 'bufname( {expr} ) -- Name of the buffer {expr}')
306"call Cream_pop_words('vim', 'bufnr', 'bufnr( {expr} ) -- Number of the buffer {expr}')
307"call Cream_pop_words('vim', 'bufwinnr', 'bufwinnr( {expr} ) -- window number of buffer {expr}')
308"call Cream_pop_words('vim', 'byte2line', 'byte2line( {byte} ) -- line number at byte count {byte}')
309"call Cream_pop_words('vim', 'char2nr', 'char2nr( {expr} ) -- ASCII value of first char in {expr}')
310"call Cream_pop_words('vim', 'cindent', 'cindent( {lnum} ) -- C indent for line {lnum}')
311"call Cream_pop_words('vim', 'col', 'col( {expr} ) -- column nr of cursor or mark')
312"call Cream_pop_words('vim', 'confirm', 'confirm( {msg} [, {choices} [, {default} [, {type}]]] ) -- number of choice picked by user')
313"call Cream_pop_words('vim', 'cscope_connection', 'cscope_connection( [{num} , {dbpath} [, {prepend}]] ) -- checks existence of cscope connection')
314"call Cream_pop_words('vim', 'cursor', 'cursor( {lnum}, {col} ) -- position cursor at {lnum}, {col}')
315"call Cream_pop_words('vim', 'delete', 'delete( {fname} ) -- delete file {fname}')
316"call Cream_pop_words('vim', 'did_filetype', 'did_filetype() -- TRUE if FileType autocommand event used')
317"call Cream_pop_words('vim', 'escape', 'escape( {string}, {chars} ) -- escape {chars} in {string} with \"\\\"')
318"call Cream_pop_words('vim', 'eventhandler', 'eventhandler() -- TRUE if inside an event handler')
319"call Cream_pop_words('vim', 'executable', 'executable( {expr} ) -- 1 if executable {expr} exists')
320"call Cream_pop_words('vim', 'exists', 'exists( {var} ) -- TRUE if {var} exists')
321"call Cream_pop_words('vim', 'expand', 'expand( {expr} ) -- expand special keywords in {expr}')
322"call Cream_pop_words('vim', 'filereadable', 'filereadable( {file} ) -- TRUE if {file} is a readable file')
323"call Cream_pop_words('vim', 'filewritable', 'filewritable( {file} ) -- TRUE if {file} is a writable file')
324"call Cream_pop_words('vim', 'fnamemodify', 'fnamemodify( {fname}, {mods} ) -- modify file name')
325"call Cream_pop_words('vim', 'foldclosed', 'foldclosed( {lnum} ) -- first line of fold at {lnum} if closed')
326"call Cream_pop_words('vim', 'foldclosedend', 'foldclosedend( {lnum} ) -- last line of fold at {lnum} if closed')
327"call Cream_pop_words('vim', 'foldlevel', 'foldlevel( {lnum} ) -- fold level at {lnum}')
328"call Cream_pop_words('vim', 'foldtext', 'foldtext() -- line displayed for closed fold')
329"call Cream_pop_words('vim', 'foreground', 'foreground() -- bring the Vim window to the foreground')
330"call Cream_pop_words('vim', 'getchar', 'getchar( [expr] ) -- get one character from the user')
331"call Cream_pop_words('vim', 'getcharmod', 'getcharmod() -- modifiers for the last typed character')
332"call Cream_pop_words('vim', 'getbufvar', 'getbufvar( {expr}, {varname} ) -- variable {varname} in buffer {expr}')
333"call Cream_pop_words('vim', 'getcwd', 'getcwd() -- the current working directory')
334"call Cream_pop_words('vim', 'getftime', 'getftime( {fname} ) -- last modification time of file')
335"call Cream_pop_words('vim', 'getfsize', 'getfsize( {fname} ) -- size in bytes of file')
336"call Cream_pop_words('vim', 'getline', 'getline( {lnum} ) -- line {lnum} from current buffer')
337"call Cream_pop_words('vim', 'getwinposx', 'getwinposx() -- X coord in pixels of GUI vim window')
338"call Cream_pop_words('vim', 'getwinposy', 'getwinposy() -- Y coord in pixels of GUI vim window')
339"call Cream_pop_words('vim', 'getwinvar', 'getwinvar( {nr}, {varname} ) -- variable {varname} in window {nr}')
340"call Cream_pop_words('vim', 'glob', 'glob( {expr}] ) -- expand file wildcards in {expr}')
341"call Cream_pop_words('vim', 'globpath', 'globpath( {path}, {expr} ) -- do glob({expr}) for all dirs in {path}')
342"call Cream_pop_words('vim', 'has', 'has( {feature} ) -- TRUE if feature {feature} supported')
343"call Cream_pop_words('vim', 'hasmapto', 'hasmapto( {what} [, {mode}] ) -- TRUE if mapping to {what} exists')
344"call Cream_pop_words('vim', 'histadd', 'histadd( {history},{item} ) -- add an item to a history')
345"call Cream_pop_words('vim', 'histdel', 'histdel( {history} [, {item}] ) -- remove an item from a history')
346"call Cream_pop_words('vim', 'histget', 'histget( {history} [, {index}] ) -- get the item {index} from a history')
347"call Cream_pop_words('vim', 'histnr', 'histnr( {history} ) -- highest index of a history')
348"call Cream_pop_words('vim', 'hlexists', 'hlexists( {name} ) -- TRUE if highlight group {name} exists')
349"call Cream_pop_words('vim', 'hlID', 'hlID( {name} ) -- syntax ID of highlight group {name}')
350"call Cream_pop_words('vim', 'hostname', 'hostname() -- name of the machine vim is running on')
351"call Cream_pop_words('vim', 'iconv', 'iconv( {expr}, {from}, {to} ) -- convert encoding of {expr}')
352"call Cream_pop_words('vim', 'indent', 'indent( {lnum} ) -- indent of line {lnum}')
353"call Cream_pop_words('vim', 'input', 'input( {prompt} [, {text}] ) -- get input from the user')
354"call Cream_pop_words('vim', 'inputdialog', 'inputdialog( {prompt} [, {text}] ) -- like input() but in a GUI dialog')
355"call Cream_pop_words('vim', 'inputsecret', 'inputsecret( {prompt} [, {text}] ) -- like input() but hiding the text')
356"call Cream_pop_words('vim', 'isdirectory', 'isdirectory( {directory} ) -- TRUE if {directory} is a directory')
357"call Cream_pop_words('vim', 'libcall', 'libcall( {lib}, {func}, {arg} ) -- call {func} in library {lib} with {arg}')
358"call Cream_pop_words('vim', 'libcallnr', 'libcallnr( {lib}, {func}, {arg} ) -- idem, but return a Number')
359"call Cream_pop_words('vim', 'line', 'line( {expr} ) -- line nr of cursor, last line or mark')
360"call Cream_pop_words('vim', 'line2byte', 'line2byte( {lnum} ) -- byte count of line {lnum}')
361"call Cream_pop_words('vim', 'lispindent', 'lispindent( {lnum} ) -- Lisp indent for line {lnum}')
362"call Cream_pop_words('vim', 'localtime', 'localtime() -- current time')
363"call Cream_pop_words('vim', 'maparg', 'maparg( {name}[, {mode}] ) -- rhs of mapping {name} in mode {mode}')
364"call Cream_pop_words('vim', 'mapcheck', 'mapcheck( {name}[, {mode}] ) -- check for mappings matching {name}')
365"call Cream_pop_words('vim', 'match', 'match( {expr}, {pat}[, {start}] ) -- position where {pat} matches in {expr}')
366"call Cream_pop_words('vim', 'matchend', 'matchend( {expr}, {pat}[, {start} ) -- position where {pat} ends in {expr}')
367"call Cream_pop_words('vim', 'matchstr', 'matchstr( {expr}, {pat}[, {start}] ) -- match of {pat} in {expr}')
368"call Cream_pop_words('vim', 'mode', 'mode() -- String  current editing mode')
369"call Cream_pop_words('vim', 'nextnonblank', 'nextnonblank( {lnum} ) -- line nr of non-blank line >= {lnum}')
370"call Cream_pop_words('vim', 'nr2char', 'nr2char( {expr} ) -- single char with ASCII value {expr}')
371"call Cream_pop_words('vim', 'prevnonblank', 'prevnonblank( {lnum} ) -- line nr of non-blank line <= {lnum}')
372"call Cream_pop_words('vim', 'remote_expr', 'remote_expr( {server}, {string} [, {idvar}] ) -- send expression')
373"call Cream_pop_words('vim', 'remote_foreground', 'remote_foreground( {server} ) -- bring Vim server to the foreground')
374"call Cream_pop_words('vim', 'remote_peek', 'remote_peek( {serverid} [, {retvar}] ) -- check for reply string')
375"call Cream_pop_words('vim', 'remote_read', 'remote_read( {serverid} ) -- read reply string')
376"call Cream_pop_words('vim', 'remote_send', 'remote_send( {server}, {string} [, {idvar}] ) -- send key sequence')
377"call Cream_pop_words('vim', 'rename', 'rename( {from}, {to} ) -- rename (move) file from {from} to {to}')
378"call Cream_pop_words('vim', 'resolve', 'resolve( {filename} ) -- get filename a shortcut points to')
379"call Cream_pop_words('vim', 'search', 'search( {pattern} [, {flags}] ) -- search for {pattern}')
380"call Cream_pop_words('vim', 'searchpair', 'searchpair( {start}, {middle}, {end} [, {flags} [, {skip}]] ) -- search for other end of start/end pair')
381"call Cream_pop_words('vim', 'server2client', 'server2client( {serverid}, {string} ) -- send reply string')
382"call Cream_pop_words('vim', 'serverlist', 'serverlist() -- get a list of available servers')
383"call Cream_pop_words('vim', 'setbufvar', 'setbufvar( {expr}, {varname}, {val} ) -- set {varname} in buffer {expr} to {val}')
384"call Cream_pop_words('vim', 'setline', 'setline( {lnum}, {line} ) -- set line {lnum} to {line}')
385"call Cream_pop_words('vim', 'setwinvar', 'setwinvar( {nr}, {varname}, {val} ) -- set {varname} in window {nr} to {val}')
386"call Cream_pop_words('vim', 'strftime', 'strftime( {format}[, {time}] ) -- time in specified format')
387"call Cream_pop_words('vim', 'stridx', 'stridx( {haystack}, {needle} ) -- first index of {needle} in {haystack}')
388"call Cream_pop_words('vim', 'strlen', 'strlen( {expr} ) -- length of the String {expr}')
389"call Cream_pop_words('vim', 'strpart', 'strpart( {src}, {start}[, {len}] ) -- {len} characters of {src} at {start}')
390"call Cream_pop_words('vim', 'strridx', 'strridx( {haystack}, {needle} ) -- last index of {needle} in {haystack}')
391"call Cream_pop_words('vim', 'strtrans', 'strtrans( {expr} ) -- translate string to make it printable')
392"call Cream_pop_words('vim', 'submatch', 'submatch( {nr} ) -- specific match in \":substitute\"')
393"call Cream_pop_words('vim', 'substitute', 'substitute( {expr}, {pat}, {sub}, {flags} ) -- all {pat} in {expr} replaced with {sub}')
394"call Cream_pop_words('vim', 'synID', 'synID( {line}, {col}, {trans} ) -- syntax ID at {line} and {col}')
395"call Cream_pop_words('vim', 'synIDattr', 'synIDattr( {synID}, {what} [, {mode}] ) -- attribute {what} of syntax ID {synID}')
396"call Cream_pop_words('vim', 'synIDtrans', 'synIDtrans( {synID} ) -- translated syntax ID of {synID}')
397"call Cream_pop_words('vim', 'system', 'system( {expr} ) -- output of shell command {expr}')
398"call Cream_pop_words('vim', 'tempname', 'tempname() -- name for a temporary file')
399"call Cream_pop_words('vim', 'tolower', 'tolower( {expr} ) -- the String {expr} switched to lowercase')
400"call Cream_pop_words('vim', 'toupper', 'toupper( {expr} ) -- the String {expr} switched to uppercase')
401"call Cream_pop_words('vim', 'type', 'type( {name} ) -- type of variable {name}')
402"call Cream_pop_words('vim', 'virtcol', 'virtcol( {expr} ) -- screen column of cursor or mark')
403"call Cream_pop_words('vim', 'visualmode', 'visualmode() -- last visual mode used')
404"call Cream_pop_words('vim', 'winbufnr', 'winbufnr( {nr} ) -- buffer number of window {nr}')
405"call Cream_pop_words('vim', 'wincol', 'wincol() -- window column of the cursor')
406"call Cream_pop_words('vim', 'winheight', 'winheight( {nr} ) -- height of window {nr}')
407"call Cream_pop_words('vim', 'winline', 'winline() -- window line of the cursor')
408"call Cream_pop_words('vim', 'winnr', 'winnr() -- number of current window')
409"call Cream_pop_words('vim', 'winwidth', 'winwidth( {nr} ) -- width of window {nr}')
410
411" 1}}}
412" vim:foldmethod=marker
413