# HG changeset patch # User vimboss # Date 1142891989 0 # Node ID 98a88a884610aa911950623d7cce8d067feda66c # Parent c8680debe1cc85e3f8703edfe5cc2d37bc5d46d8 updated for version 7.0230 diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt --- a/runtime/doc/quickfix.txt +++ b/runtime/doc/quickfix.txt @@ -1,4 +1,4 @@ -*quickfix.txt* For Vim version 7.0aa. Last change: 2006 Mar 19 +*quickfix.txt* For Vim version 7.0aa. Last change: 2006 Mar 20 VIM REFERENCE MANUAL by Bram Moolenaar @@ -878,6 +878,7 @@ prefixes are: %W start of a multi-line warning message %I start of a multi-line informational message %A start of a multi-line message (unspecified type) + %> for next line start with current pattern again |efm-%>| %C continuation of a multi-line message %Z end of a multi-line message These can be used with '+' and '-', see |efm-ignore| below. @@ -929,6 +930,17 @@ starting with a space, followed by any c it also hides line 7 which would trigger a separate error message otherwise. Error format strings are always parsed pattern by pattern until the first match occurs. + *efm-%>* +The %> item can be used to avoid trying patterns that appear earlier in +'errorformat'. This is useful for patterns that match just about anything. +For example, if the error looks like this: + + Error in line 123 of foo.c: ~ + unknown variable "i" ~ + +This can be found with: > + :set efm=xxx,%E%>Error in line %l of %f:,%Z%m +Where "xxx" has a pattern that would also match the second line. Important: There is no memory of what part of the errorformat matched before; every line in the error file gets a complete new run through the error format diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 7.0aa. Last change: 2006 Mar 19 +*todo.txt* For Vim version 7.0aa. Last change: 2006 Mar 20 VIM REFERENCE MANUAL by Bram Moolenaar @@ -30,15 +30,23 @@ be worked on, but only if you sponsor Vi *known-bugs* -------------------- Known bugs and current work ----------------------- -'errorformat': Add a flag %? to check for a match with the next item first. -Helps for continuation lines that may contain just about anything, e.g. an -error message. - error 99 in file foo.c line 1234: - something is wrong here +Links in docs to vimball docs. + +HTML indenting can be slow, find out why. +Add a function to get the current time in usec. reltime([start, [end]]) + reltime().sec == seconds, reltime().usec = microseconds + reltime(start) current time relative to [start] + echo timestring(reltime(start), 3) (3 is nr of digits after dot) + reltime(start, end) difference between start and end -Gnome GUI: lots of error messages during startup. These go away when not -using the notebook for tab labels. Still similar error messages when moving -the toolbar to another location. +Include GetLatestVimScripts script? + +Adjust src/main.aap for installing manpages like in Makefile. + And for generating Vim.app for the Mac. + Install spell files with src/main.aap. + +Gnome2: When moving the toolbar out of the dock, so that it becomes floating, +it can no longer be moved. Win32: Describe how to do debugging. (George Reilly) @@ -51,28 +59,8 @@ 8 Add patch from Muraoka Taro (Mar 16) - With 'nopaste' pasting is wrong, with 'paste' Command-V doesn't work. (Alan Schmitt) -EMBEDDING: Make it possible to run Vim inside a window of another program. -For GTK Neil Bird has a patch to use Vim like a widget. - -Ctags still hasn't included the patch. Darren is looking for someone to do -maintenance. Is there another solution? - -HTML indenting can be slow, find out why. -Add a function to get the current time in usec. reltime([start, [end]]) - reltime().sec == seconds, reltime().usec = microseconds - reltime(start) current time relative to [start] - echo timestring(reltime(start), 3) (3 is nr of digits after dot) - reltime(start, end) difference between start and end -Profiling: - - :profile pause - - :profile resume - -Adjust src/main.aap for installing manpages like in Makefile. - And for generating Vim.app for the Mac. - Install spell files with src/main.aap. - -Add ":smap", Select mode mapping? Otherwise: ":sunmap", so that Visual mode -mappings for normal keys can be removed from Select mode. +Darren is including the patch in ctags. Test it when it's ready. Change +"typename" to "typeref" in C complete code. Add more tests for all new functionality in Vim 7. Especially new functions. @@ -81,7 +69,6 @@ text of a previous change. Awaiting updated patches: -7 Updated Ruby interface. (Ryan Paul) 8 Add ":n" to fnamemodify(): normalize path, remove "../" when possible. Aric Blumer has a patch for this. He will update the patch for 6.3. @@ -1446,7 +1433,6 @@ 7 Wild idea: Not only set highlighting 7 CTRL-] checks the highlight group for finding out what the tag is. 7 Add an explanation how a list of words can be used to highlight misspelled words. -7 Command line completion for ":find" should search in 'path'. 8 Add more command line completion for :syntax. 8 Add more command line completion for :highlight. 8 Add more command line completion for :sign. diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt --- a/runtime/doc/version7.txt +++ b/runtime/doc/version7.txt @@ -1,4 +1,4 @@ -*version7.txt* For Vim version 7.0aa. Last change: 2006 Mar 18 +*version7.txt* For Vim version 7.0aa. Last change: 2006 Mar 20 VIM REFERENCE MANUAL by Bram Moolenaar @@ -36,6 +36,7 @@ Debugger support |new-debug-support| Remote file explorer |new-netrw-explore| Define an operator |new-define-operator| Mapping to an expression |new-map-expression| +Visual and Select mode mappings |new-map-select| Location list |new-location-list| Various new items |new-items-7| @@ -143,6 +144,10 @@ difficult to locate errors. Now the lin reported, relative to the function start. This also means that line numbers for ":breakadd func" are different. +When defining a user command with |:command| the special items could be +abbreviated. This caused unexpected behavior, such as
  • being recognized +as . The items can no longer be abbreviated. + ============================================================================== NEW FEATURES *new-7* @@ -161,8 +166,8 @@ The |string()| function can be used to g variable. Works for Numbers, Strings and composites of them. Then |eval()| can be used to turn the string back into the variable value. -The |:let| command can now use ":let var += expr" like using ":let var = var + -expr". "-=" and ".=" works in a similar way. +The |:let| command can now use "+=". ":let var += expr" works like +":let var = var + expr". "-=" and ".=" works in a similar way. With the |:profile| command you can find out where your function or script wastes its time. @@ -493,6 +498,20 @@ Here the dot will be mapped to whatever Also works for abbreviations. See |:map-| for the details. +Visual and Select mode mappings *new-map-select* +------------------------------- + +Previously Visual mode mappings applied both to Visual and Select mode. With +a trick to have the mappings work in Select mode like they would in Visual +mode. + +Commands have been added to define mappings for Visual and Select mode +separately: |:xmap| and |:smap|. With the associated "noremap" and "unmap" +commands. + +The same is done for menus: |:xmenu|, |:smenu|, etc. + + Location list *new-location-list* ------------- @@ -1103,6 +1122,13 @@ getwinvar() now also works to obtain a b window. Added the "%s" item to 'errorformat'. (Yegappan Lakshmanan) +Added the "%>" item to 'errorformat'. + +For 'errorformat' it was not possible to have a file name that contains the +character that follows after "%f". For example, in "%f:%l:%m" the file name +could not contain ":". Now include the first ":" where the rest of the +pattern matches. In the example a ":" not followed by a line number is +included in the file name. (suggested by Emanuele Giaquinta) GTK GUI: use the GTK file dialog when it's available. Mix from patches by Grahame Bowland and Evan Webb. @@ -1133,12 +1159,6 @@ Lakshmanan) Win32: Balloons can have multiple lines if common controls supports it. (Sergey Khorev) -For 'errorformat' it was not possible to have a file name that contains the -character that follows after "%f". For example, in "%f:%l:%m" the file name -could not contain ":". Now include the first ":" where the rest of the -pattern matches. In the example a ":" not followed by a line number is -included in the file name. (suggested by Emanuele Giaquinta) - For command-line completion the matches for various types of arguments are now sorted: user commands, variables, syntax names, etc. @@ -1233,6 +1253,8 @@ Win32: In the batch files generated by t $VIM if it's set. Example provided by Mathias Michaelis. Also create a vimtutor.bat batch file. +The 'balloonexpr' option is now |global-local|. + ============================================================================== COMPILE TIME CHANGES *compile-changes-7* @@ -1384,9 +1406,6 @@ just before it is invoked VMS: Occasionally CR characters were inserted in the file. Expansion of environment variables was not correct. (Zoltan Arpadffy) -VMS: Improved low level char input (affects just console mode). (Zoltan -Arpadffy) - UTF-8: When 'delcombine' is set "dw" only deleted the last combining character from the first character of the word. @@ -1733,6 +1752,9 @@ change the window size ourselves, but th Peek for a character to get any window resize events and fix 'columns' and 'lines' to undo this. +When using the GTK plug mechanism, resizing and focus was not working +properly. (Neil Bird) + After deleting files from the argument list a session file generated with ":mksession" may contain invalid ":next" commands. diff --git a/runtime/doc/vimball.txt b/runtime/doc/vimball.txt new file mode 100644 --- /dev/null +++ b/runtime/doc/vimball.txt @@ -0,0 +1,66 @@ +*vimball.txt* Vimball Archiver Mar 20, 2006 +Author: Charles E. Campbell, Jr. + (remove NOSPAM from Campbell's email first) +Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. *Vimball-copyright* + The VIM LICENSE applies to Vimball.vim, and Vimball.txt + (see |copyright|) except use "Vimball" instead of "Vim". + No warranty, express or implied. + Use At-Your-Own-Risk! + +============================================================================== +1. Contents *vimball* *vimball-contents* + + 1. Contents......................................: |vimball-contents| + 2. Vimball Manual................................: |vimball-manual| + 3. Vimball History...............................: |vimball-history| + + +============================================================================== +2. Vimball Manual *vimball-manual* + + *:MkVimball* + :[range]MkVimball[!] filename + + This command takes lines holding a path to files to be included in + your vimball; as an example: > + plugin/something.vim + doc/something.txt +< using MkVimball on this range will create a file called + "filename.vba" which can be used by Vimball.vim to re-create these + files. If the "filename.vba" file already exists, then MkVimball + will issue a warning and not create the file. + + However, if you use the exclamation point (!), then MkVimball will + create the "filename.vba" file, overwriting it if it already exists. + This behavior resembles that for |:w|. + + *vimball-extract* + vim filename.vba + + Simply editing a Vimball will cause Vimball.vim to tell the user to + source the file to extract its contents. + + Extraction will only proceed if the first line of a putative vimball + file holds the "Vimball Archiver by Charles E. Campbell, Jr., Ph.D." + line. + + :VimballList *vimball-vimballlist* + + This command will tell Vimball to list the files in the archive, along + with their lengths in lines. + + +============================================================================== +3. Vimball History *vimball-history* + + 3 : Mar 20, 2006 * removed query, now requires sourcing to be + extracted (:so %). Message to that effect + included. + * :VimballList now shows files that would be + extracted. + 2 : Mar 20, 2006 * query, :UseVimball included + 1 : Mar 20, 2006 * initial release + + +============================================================================== +vim:tw=78:ts=8:ft=help:fdm=marker diff --git a/runtime/plugin/vimball.vim b/runtime/plugin/vimball.vim new file mode 100644 --- /dev/null +++ b/runtime/plugin/vimball.vim @@ -0,0 +1,256 @@ +" vimball : construct a file containing both paths and files +" Author: Charles E. Campbell, Jr. +" Date: Mar 20, 2006 +" Version: 3 +" GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim +" Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. +" The VIM LICENSE applies to Vimball.vim, and Vimball.txt +" (see |copyright|) except use "Vimball" instead of "Vim". +" No warranty, express or implied. +" *** *** Use At-Your-Own-Risk! *** *** + +" --------------------------------------------------------------------- +" Load Once: {{{1 +if &cp || exists("g:loaded_vimball") + finish +endif + +let s:keepcpo = &cpo +let g:loaded_vimball = "v3" +set cpo&vim + +" ------------------------------------------------------------------------------ +" Public Interface: {{{1 +com! -ra -na=+ -bang MkVimball call s:MkVimball(,,0,) +com! -na=0 UseVimball call s:Vimball(1) +com! -na=0 VimballList call s:Vimball(0) +au BufReadPost *.vba echohl WarningMsg | echo "Source this file to extract it! (:so %)" | echohl None + +" ===================================================================== +" Functions: {{{1 + +" --------------------------------------------------------------------- +" MkVimball: creates a vimball given a list of paths to files {{{2 +" Vimball Format: +" path +" filesize +" [file] +" path +" filesize +" [file] +fun! s:MkVimball(line1,line2,writelevel,vimballname) range +" call Dfunc("MkVimball(line1=".a:line1." line2=".a:line2." writelevel=".a:writelevel." vimballname<".a:vimballname.">") + let vbname= substitute(a:vimballname,'\.[^.]*$','','e').'.vba' + if !a:writelevel && filereadable(vbname) + echohl Error | echoerr "(MkVimball) file<".vbname."> exists; use ! to insist" | echohl None +" call Dret("MkVimball : file<".vbname."> already exists; use ! to insist") + return + endif + + " user option bypass + let eikeep= &ei + set ei=all + + let home = substitute(&rtp,',.*$','','') + let curdir = getcwd() + exe "cd ".home + + " record current tab, initialize while loop index + let curtabnr = tabpagenr() + let linenr = a:line1 +" call Decho("curtabnr=".curtabnr) + + while linenr <= a:line2 + let svfile = getline(linenr) +" call Decho("svfile<".svfile.">") + + if !filereadable(svfile) + echohl Error | echo "unable to read file<".svfile.">" | echohl None + let &ei= eikeep + exe "cd ".curdir +" call Dret("MkVimball") + return + endif + + " create/switch to mkvimball tab + if !exists("vbtabnr") + tabnew + silent! file Vimball + let vbtabnr= tabpagenr() + else + exe "tabn ".vbtabnr + endif + + let lastline= line("$") + 1 + if lastline == 2 && getline("$") == "" + call setline(1,'" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.') + call setline(2,'UseVimball') + call setline(3,'finish') + let lastline= 4 + endif + call setline(lastline ,svfile) + call setline(lastline+1,0) + exe "$r ".svfile + call setline(lastline+1,line("$") - lastline - 1) +" call Decho("lastline=".lastline." line$=".line("$")) + + " restore to normal tab + exe "tabn ".curtabnr + let linenr= linenr + 1 + endwhile + + " write the vimball + exe "tabn ".vbtabnr + exe "cd ".curdir + if a:really + if a:writelevel + exe "w! ".vbname + else + exe "w ".vbname + endif + endif +" call Decho("Vimball<".vbname."> created") + echo "Vimball<".vbname."> created" + + " remove the evidence + setlocal nomod bh=wipe + exe "tabn ".curtabnr + exe "tabc ".vbtabnr + + " restore options + let &ei= eikeep + +" call Dret("MkVimball") +endfun + +" --------------------------------------------------------------------- +" Vimball: {{{2 +fun! s:Vimball(really) +" call Dfunc("Vimball(really=".a:really.")") + + if getline(1) !~ '^" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.$' + echoerr "(Vimball) The current file does not appear to be a Vimball!" +" call Dret("Vimball") + return + endif + + " initialize + let regakeep = @a + let eikeep = &ei + let vekeep = &ve + let makeep = getpos("'a") + let curtabnr = tabpagenr() + set ei=all ve=all + + " set up vimball tab + tabnew + silent! file Vimball + let vbtabnr= tabpagenr() + let didhelp= "" + + " go to vim plugin home + let home = substitute(&rtp,',.*$','','') + let curdir = getcwd() +" call Decho("exe cd ".home) + exe "cd ".home + let linenr = 4 + let filecnt = 0 + + " give title to listing of (extracted) files from Vimball Archive + if a:really + echohl Title | echomsg "Vimball Archive" | echohl None + else + echohl Title | echomsg "Vimball Archive Listing" | echohl None + endif + + " apportion vimball contents to various files +" call Decho("exe tabn ".curtabnr) + exe "tabn ".curtabnr +" call Decho("linenr=".linenr." line$=".line("$")) + while 1 < linenr && linenr < line("$") + let fname = getline(linenr) + let fsize = getline(linenr+1) + let filecnt = filecnt + 1 + if a:really + echomsg "extracted <".fname.">: ".fsize." lines" + else + echomsg "would extract <".fname.">: ".fsize." lines" + endif +" call Decho(linenr.": will extract file<".fname.">") +" call Decho((linenr+1).": fsize=".fsize) + + " make directories if they don't exist yet + let fnamebuf= fname + while fnamebuf =~ '/' + let dirname = substitute(fnamebuf,'/.*$','','e') + let fnamebuf = substitute(fnamebuf,'^.\{-}/\(.*\)$','\1','e') + if !isdirectory(dirname) +" call Decho("making <".dirname.">") + call mkdir(dirname) + endif + exe "cd ".dirname + endwhile + exe "cd ".home + + " grab specified qty of lines and place into "a" buffer + exe linenr + norm! jjma + exe (linenr + fsize + 1) + silent norm! "ay'a +" call Decho("yanked ".fsize." lines into register-a") + +" call Decho("didhelp<".didhelp."> fname<".fname.">") + if didhelp == "" && fname =~ 'doc/[^/]\+\.txt$' + let didhelp= substitute(fname,'^\(.*\") + endif + + " copy "a" buffer into tab +" call Decho('copy "a buffer into tab#'.vbtabnr) + exe "tabn ".vbtabnr + silent! %d + silent norm! "aPGdd1G +" call Decho("rega<".@a.">") + + " write tab to file +" call Decho("exe w! ".fname) + exe "silent w! ".fname + +" call Decho("exe tabn ".curtabnr) + exe "tabn ".curtabnr +" let oldlinenr = linenr " Decho + let linenr = linenr + fsize + 2 +" call Decho("update linenr= [linenr=".oldlinenr."] + [fsize=".fsize."] + 2 = ".linenr) + endwhile + + " set up help +" call Decho("about to set up help: didhelp<".didhelp.">") + if didhelp != "" +" call Decho("exe helptags ".home."/".didhelp) + exe "helptags ".home."/".didhelp + echomsg "did helptags" + endif + + " make sure a "Press ENTER..." prompt appears to keep the messages showing! + while filecnt < &ch + echomsg " " + let filecnt= filecnt + 1 + endwhile + + " restore events, delete tab and buffer + exe "tabn ".vbtabnr + setlocal nomod bh=wipe + exe "tabn ".curtabnr + exe "tabc ".vbtabnr + let &ei= eikeep + let @a = regakeep + if makeep[0] != 0 + " restore mark a +" call Decho("restore mark-a: makeep=".string(makeep)) + call setpos("'a",makeep) + ka + endif + exe "cd ".curdir + +" call Dret("Vimball") +endfun diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -19382,7 +19382,7 @@ call_user_func(fp, argcount, argvars, re } } #ifdef FEAT_PROFILE - if (do_profiling) + if (do_profiling == PROF_YES) { if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) func_do_profile(fp); @@ -19417,7 +19417,8 @@ call_user_func(fp, argcount, argvars, re } #ifdef FEAT_PROFILE - if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) + if (do_profiling == PROF_YES && (fp->uf_profiling + || (fc.caller != NULL && &fc.caller->func->uf_profiling))) { profile_end(&fp->uf_tm_start); profile_sub_wait(&wait_start, &fp->uf_tm_start); @@ -19467,7 +19468,7 @@ call_user_func(fp, argcount, argvars, re sourcing_lnum = save_sourcing_lnum; current_SID = save_current_SID; #ifdef FEAT_PROFILE - if (do_profiling) + if (do_profiling == PROF_YES) script_prof_restore(&wait_start); #endif @@ -19710,7 +19711,7 @@ get_func_line(c, cookie, indent) fcp->dbg_tick = debug_tick; } #ifdef FEAT_PROFILE - if (do_profiling) + if (do_profiling == PROF_YES) func_line_end(cookie); #endif @@ -19731,7 +19732,7 @@ get_func_line(c, cookie, indent) retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); sourcing_lnum = fcp->linenr; #ifdef FEAT_PROFILE - if (do_profiling) + if (do_profiling == PROF_YES) func_line_start(cookie); #endif } diff --git a/src/ex_cmds.h b/src/ex_cmds.h --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -821,12 +821,22 @@ EX(CMD_slast, "slast", ex_last, EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR), EX(CMD_smagic, "smagic", ex_submagic, RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY), +EX(CMD_smap, "smap", ex_map, + EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), +EX(CMD_smapclear, "smapclear", ex_mapclear, + EXTRA|TRLBAR|CMDWIN), +EX(CMD_smenu, "smenu", ex_menu, + RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EX(CMD_snext, "snext", ex_next, RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR), EX(CMD_sniff, "sniff", ex_sniff, EXTRA|TRLBAR), EX(CMD_snomagic, "snomagic", ex_submagic, RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY), +EX(CMD_snoremap, "snoremap", ex_map, + EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), +EX(CMD_snoremenu, "snoremenu", ex_menu, + RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EX(CMD_source, "source", ex_source, BANG|FILE1|TRLBAR|SBOXOK|CMDWIN), EX(CMD_sort, "sort", ex_sort, @@ -867,6 +877,10 @@ EX(CMD_stselect, "stselect", ex_stag, BANG|TRLBAR|WORD1), EX(CMD_sunhide, "sunhide", ex_buffer_all, RANGE|NOTADR|COUNT|TRLBAR), +EX(CMD_sunmap, "sunmap", ex_unmap, + EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), +EX(CMD_sunmenu, "sunmenu", ex_menu, + EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EX(CMD_suspend, "suspend", ex_stop, TRLBAR|BANG|CMDWIN), EX(CMD_sview, "sview", ex_splitview, @@ -1035,6 +1049,20 @@ EX(CMD_xit, "xit", ex_exit, RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN), EX(CMD_xall, "xall", do_wqall, BANG|TRLBAR), +EX(CMD_xmap, "xmap", ex_map, + EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), +EX(CMD_xmapclear, "xmapclear", ex_mapclear, + EXTRA|TRLBAR|CMDWIN), +EX(CMD_xmenu, "xmenu", ex_menu, + RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), +EX(CMD_xnoremap, "xnoremap", ex_map, + EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), +EX(CMD_xnoremenu, "xnoremenu", ex_menu, + RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), +EX(CMD_xunmap, "xunmap", ex_unmap, + EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), +EX(CMD_xunmenu, "xunmenu", ex_menu, + EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EX(CMD_yank, "yank", ex_operators, RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN), EX(CMD_z, "z", ex_z, diff --git a/src/gui_beval.c b/src/gui_beval.c --- a/src/gui_beval.c +++ b/src/gui_beval.c @@ -28,6 +28,8 @@ general_beval_cb(beval, state) char_u *text; static char_u *result = NULL; long winnr = 0; + char_u *bexpr; + buf_T *save_curbuf; #ifdef FEAT_WINDOWS win_T *cw; #endif @@ -39,39 +41,51 @@ general_beval_cb(beval, state) return; #ifdef FEAT_EVAL - if (*p_bexpr != NUL - && get_beval_info(balloonEval, TRUE, &wp, &lnum, &text, &col) == OK) + if (get_beval_info(balloonEval, TRUE, &wp, &lnum, &text, &col) == OK) { + bexpr = (*wp->w_buffer->b_p_bexpr == NUL) ? p_bexpr + : wp->w_buffer->b_p_bexpr; + if (*bexpr != NUL) + { # ifdef FEAT_WINDOWS - /* Convert window pointer to number. */ - for (cw = firstwin; cw != wp; cw = cw->w_next) - ++winnr; + /* Convert window pointer to number. */ + for (cw = firstwin; cw != wp; cw = cw->w_next) + ++winnr; # endif - set_vim_var_nr(VV_BEVAL_BUFNR, (long)wp->w_buffer->b_fnum); - set_vim_var_nr(VV_BEVAL_WINNR, winnr); - set_vim_var_nr(VV_BEVAL_LNUM, (long)lnum); - set_vim_var_nr(VV_BEVAL_COL, (long)(col + 1)); - set_vim_var_string(VV_BEVAL_TEXT, text, -1); - vim_free(text); - - use_sandbox = was_set_insecurely((char_u *)"balloonexpr", 0); - if (use_sandbox) - ++sandbox; - ++textlock; + set_vim_var_nr(VV_BEVAL_BUFNR, (long)wp->w_buffer->b_fnum); + set_vim_var_nr(VV_BEVAL_WINNR, winnr); + set_vim_var_nr(VV_BEVAL_LNUM, (long)lnum); + set_vim_var_nr(VV_BEVAL_COL, (long)(col + 1)); + set_vim_var_string(VV_BEVAL_TEXT, text, -1); + vim_free(text); - vim_free(result); - result = eval_to_string(p_bexpr, NULL, TRUE); + /* + * Temporarily change the curbuf, so that we can determine whether + * the buffer-local balloonexpr option was set insecurly. + */ + save_curbuf = curbuf; + curbuf = wp->w_buffer; + use_sandbox = was_set_insecurely((char_u *)"balloonexpr", + *curbuf->b_p_bexpr == NUL ? 0 : OPT_LOCAL); + curbuf = save_curbuf; + if (use_sandbox) + ++sandbox; + ++textlock; - if (use_sandbox) - --sandbox; - --textlock; + vim_free(result); + result = eval_to_string(bexpr, NULL, TRUE); + + if (use_sandbox) + --sandbox; + --textlock; - set_vim_var_string(VV_BEVAL_TEXT, NULL, -1); - if (result != NULL && result[0] != NUL) - { - gui_mch_post_balloon(beval, result); - return; + set_vim_var_string(VV_BEVAL_TEXT, NULL, -1); + if (result != NULL && result[0] != NUL) + { + gui_mch_post_balloon(beval, result); + return; + } } } #endif diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -806,9 +806,9 @@ focus_in_event(GtkWidget *widget, GdkEve if (blink_state == BLINK_NONE) gui_mch_start_blink(); - /* make sure keyboard input goes there */ - if (gtk_socket_id == 0) - gtk_widget_grab_focus(gui.drawarea); + /* make sure keyboard input goes to the draw area (if this is focus for a window) */ + if (widget != gui.drawarea) + gtk_widget_grab_focus(gui.drawarea); return TRUE; } @@ -2837,14 +2837,21 @@ get_item_dimensions(GtkWidget *widget, G if (using_gnome && widget != NULL) { # ifdef HAVE_GTK2 + GtkWidget *parent; BonoboDockItem *dockitem; - widget = gtk_widget_get_parent(widget); - dockitem = BONOBO_DOCK_ITEM(widget); - - if (dockitem == NULL || dockitem->is_floating) - return 0; - item_orientation = bonobo_dock_item_get_orientation(dockitem); + parent = gtk_widget_get_parent(widget); + if (G_TYPE_FROM_INSTANCE(parent) == BONOBO_TYPE_DOCK_ITEM) + { + /* Only menu & toolbar are dock items. Could tabline be? + * Seem to be only the 2 defined in GNOME */ + widget = parent; + dockitem = BONOBO_DOCK_ITEM(widget); + + if (dockitem == NULL || dockitem->is_floating) + return 0; + item_orientation = bonobo_dock_item_get_orientation(dockitem); + } # else GnomeDockItem *dockitem; @@ -2911,16 +2918,39 @@ get_menu_tool_height(void) return height; } +/* This controls whether we can set the real window hints at + * start-up when in a GtkPlug. + * 0 = normal processing (default) + * 1 = init. hints set, no-one's tried to reset since last check + * 2 = init. hints set, attempt made to change hints + */ +static int init_window_hints_state = 0; + static void -update_window_manager_hints(void) +update_window_manager_hints(int force_width, int force_height) { static int old_width = 0; static int old_height = 0; + static int old_min_width = 0; + static int old_min_height = 0; static int old_char_width = 0; static int old_char_height = 0; int width; int height; + int min_width; + int min_height; + + /* At start-up, don't try to set the hints until the initial + * values have been used (those that dictate our initial size) + * Let forced (i.e., correct) values thruogh always. + */ + if (!(force_width && force_height) && init_window_hints_state > 0) + { + /* Don't do it! */ + init_window_hints_state = 2; + return; + } /* This also needs to be done when the main window isn't there yet, * otherwise the hints don't work. */ @@ -2934,9 +2964,28 @@ update_window_manager_hints(void) height += get_menu_tool_height(); # endif + /* GtkSockets use GtkPlug's [gui,mainwin] min-size hints to determine + * their actual widget size. When we set our size ourselve (e.g., + * 'set columns=' or init. -geom) we briefly set the min. to the size + * we wish to be instead of the legitimate minimum so that we actually + * resize correctly. + */ + if (force_width && force_height) + { + min_width = force_width; + min_height = force_height; + } + else + { + min_width = width + MIN_COLUMNS * gui.char_width; + min_height = height + MIN_LINES * gui.char_height; + } + /* Avoid an expose event when the size didn't change. */ if (width != old_width || height != old_height + || min_width != old_min_width + || min_height != old_min_height || gui.char_width != old_char_width || gui.char_height != old_char_height) { @@ -2947,8 +2996,8 @@ update_window_manager_hints(void) geometry.height_inc = gui.char_height; geometry.base_width = width; geometry.base_height = height; - geometry.min_width = width + MIN_COLUMNS * gui.char_width; - geometry.min_height = height + MIN_LINES * gui.char_height; + geometry.min_width = min_width; + geometry.min_height = min_height; geometry_mask = GDK_HINT_BASE_SIZE|GDK_HINT_RESIZE_INC |GDK_HINT_MIN_SIZE; # ifdef HAVE_GTK2 @@ -2961,10 +3010,12 @@ update_window_manager_hints(void) gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.formwin, &geometry, geometry_mask); # endif - old_width = width; - old_height = height; - old_char_width = gui.char_width; - old_char_height = gui.char_height; + old_width = width; + old_height = height; + old_min_width = min_width; + old_min_height = min_height; + old_char_width = gui.char_width; + old_char_height = gui.char_height; } } @@ -3211,7 +3262,7 @@ gui_mch_show_tabline(int showit) { /* Note: this may cause a resize event */ gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), showit); - update_window_manager_hints(); + update_window_manager_hints(0, 0); #ifndef HAVE_GTK2 showing_tabline = showit; #endif @@ -3583,35 +3634,31 @@ gui_mch_init(void) /* * Use a Notebook for the tab pages labels. The labels are hidden by * default. - * TODO: currently doesn't work for Gnome. */ - if (!using_gnome) - { - gui.tabline = gtk_notebook_new(); - gtk_widget_show(gui.tabline); - gtk_box_pack_start(GTK_BOX(vbox), gui.tabline, FALSE, FALSE, 0); - gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE); - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), FALSE); - - { - GtkWidget *page, *label; - - /* Add the first tab. */ - page = gtk_vbox_new(FALSE, 0); - gtk_widget_show(page); - gtk_container_add(GTK_CONTAINER(gui.tabline), page); - label = gtk_label_new("-Empty-"); - gtk_widget_show(label); - gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, label); - } - gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page", - GTK_SIGNAL_FUNC(on_select_tab), NULL); - - /* Create a popup menu for the tab line and connect it. */ - tabline_menu = create_tabline_menu(); - gtk_signal_connect_object(GTK_OBJECT(gui.tabline), "button_press_event", - GTK_SIGNAL_FUNC(on_tabline_menu), GTK_OBJECT(tabline_menu)); - } + gui.tabline = gtk_notebook_new(); + gtk_widget_show(gui.tabline); + gtk_box_pack_start(GTK_BOX(vbox), gui.tabline, FALSE, FALSE, 0); + gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE); + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), FALSE); + + { + GtkWidget *page, *label; + + /* Add the first tab. */ + page = gtk_vbox_new(FALSE, 0); + gtk_widget_show(page); + gtk_container_add(GTK_CONTAINER(gui.tabline), page); + label = gtk_label_new("-Empty-"); + gtk_widget_show(label); + gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, label); + } + gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page", + GTK_SIGNAL_FUNC(on_select_tab), NULL); + + /* Create a popup menu for the tab line and connect it. */ + tabline_menu = create_tabline_menu(); + gtk_signal_connect_object(GTK_OBJECT(gui.tabline), "button_press_event", + GTK_SIGNAL_FUNC(on_tabline_menu), GTK_OBJECT(tabline_menu)); #endif gui.formwin = gtk_form_new(); @@ -3705,10 +3752,30 @@ gui_mch_init(void) GTK_SIGNAL_FUNC(enter_notify_event), NULL); } - gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_out_event", - GTK_SIGNAL_FUNC(focus_out_event), NULL); - gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_in_event", - GTK_SIGNAL_FUNC(focus_in_event), NULL); + /* Real windows can get focus ... GtkPlug, being a mere container can't, + * only its widgets. Arguably, this could be common code and we not use + * the window focus at all, but let's be safe. + */ + if (gtk_socket_id == 0) + { + gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_out_event", + GTK_SIGNAL_FUNC(focus_out_event), NULL); + gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_in_event", + GTK_SIGNAL_FUNC(focus_in_event), NULL); + } + else + { + gtk_signal_connect(GTK_OBJECT(gui.drawarea), "focus_out_event", + GTK_SIGNAL_FUNC(focus_out_event), NULL); + gtk_signal_connect(GTK_OBJECT(gui.drawarea), "focus_in_event", + GTK_SIGNAL_FUNC(focus_in_event), NULL); +#ifdef FEAT_GUI_TABLINE + gtk_signal_connect(GTK_OBJECT(gui.tabline), "focus_out_event", + GTK_SIGNAL_FUNC(focus_out_event), NULL); + gtk_signal_connect(GTK_OBJECT(gui.tabline), "focus_in_event", + GTK_SIGNAL_FUNC(focus_in_event), NULL); +#endif /* FEAT_GUI_TABLINE */ + } gtk_signal_connect(GTK_OBJECT(gui.drawarea), "motion_notify_event", GTK_SIGNAL_FUNC(motion_notify_event), NULL); @@ -3793,8 +3860,17 @@ gui_mch_new_colors(void) form_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data) { + int usable_height = event->height; + + /* When in a GtkPlug, we can't guarantee valid heights (as a round + * no. of char-heights), so we have to manually sanitise them. + * Widths seem to sort themselves out, don't ask me why. + */ + if (gtk_socket_id != 0) + usable_height -= (gui.char_height - (gui.char_height/2)); /* sic. */ + gtk_form_freeze(GTK_FORM(gui.formwin)); - gui_resize_shell(event->width, event->height); + gui_resize_shell(event->width, usable_height); gtk_form_thaw(GTK_FORM(gui.formwin)); return TRUE; @@ -3824,6 +3900,37 @@ mainwin_destroy_cb(GtkObject *object, gp } } + +/* + * Bit of a hack to ensure we start GtkPlug windows with the correct window + * hints (and thus the required size from -geom), but that after that we + * put the hints back to normal (the actual minimum size) so we may + * subsequently be resized smaller. GtkSocket (the parent end) uses the + * plug's window 'min hints to set *it's* minum size, but that's also the + * only way we have of making ourselves bigger (by set lines/columns). + * Thus set hints at start-up to ensure correct init. size, then a + * second after the final attempt to reset the real minimum hinst (done by + * scrollbar init.), actually do the sttandard hinst and stop the timer. + * We'll not let the default hints be set while this timer's active. + */ +/*ARGSUSED*/ + static gboolean +check_startup_plug_hints(gpointer data) +{ + if (init_window_hints_state == 1) + { + /* Safe to use normal hints now */ + init_window_hints_state = 0; + update_window_manager_hints(0, 0); + return FALSE; /* stop timer */ + } + + /* Keep on trying */ + init_window_hints_state = 1; + return TRUE; +} + + /* * Open the GUI window which was created by a call to gui_mch_init(). */ @@ -3887,12 +3994,32 @@ gui_mch_open(void) #endif vim_free(gui.geom); gui.geom = NULL; + + /* From now until everyone's stopped trying to set the window hints + * to their correct minimum values, stop them being set as we need + * them to remain at our required size for the parent GtkSocket to + * give us the right initial size. + */ + if (gtk_socket_id != 0 && (mask & WidthValue || mask & HeightValue)) + { + guint pixel_width = (guint)(gui_get_base_width() + Columns * gui.char_width); + guint pixel_height = (guint)(gui_get_base_height() + Rows * gui.char_height); + +#ifdef HAVE_GTK2 + pixel_width += get_menu_tool_width(); + pixel_height += get_menu_tool_height(); +#endif + + update_window_manager_hints(pixel_width, pixel_height); + init_window_hints_state = 1; + g_timeout_add(1000, check_startup_plug_hints, NULL); + } } gtk_form_set_size(GTK_FORM(gui.formwin), (guint)(gui_get_base_width() + Columns * gui.char_width), (guint)(gui_get_base_height() + Rows * gui.char_height)); - update_window_manager_hints(); + update_window_manager_hints(0, 0); if (foreground_argument != NULL) fg_pixel = gui_get_color((char_u *)foreground_argument); @@ -4125,17 +4252,25 @@ gui_mch_set_shellsize(int width, int hei /* give GTK+ a chance to put all widget's into place */ gui_mch_update(); +#ifndef HAVE_GTK2 /* this will cause the proper resizement to happen too */ - update_window_manager_hints(); - -#ifdef HAVE_GTK2 + update_window_manager_hints(0, 0); + +#else /* HAVE_GTK2 */ + /* this will cause the proper resizement to happen too */ + if (gtk_socket_id == 0) + update_window_manager_hints(0, 0); + /* With GTK+ 2, changing the size of the form widget doesn't resize - * the window. So lets do it the other way around and resize the + * the window. So let's do it the other way around and resize the * main window instead. */ width += get_menu_tool_width(); height += get_menu_tool_height(); - gtk_window_resize(GTK_WINDOW(gui.mainwin), width, height); + if (gtk_socket_id == 0) + gtk_window_resize(GTK_WINDOW(gui.mainwin), width, height); + else + update_window_manager_hints(width, height); #if 0 if (!resize_idle_installed) @@ -4231,7 +4366,7 @@ gui_mch_enable_menu(int showit) else gtk_widget_hide(widget); - update_window_manager_hints(); + update_window_manager_hints(0, 0); } } #endif /* FEAT_MENU */ @@ -4262,7 +4397,7 @@ gui_mch_show_toolbar(int showit) else gtk_widget_hide(widget); - update_window_manager_hints(); + update_window_manager_hints(0, 0); } } #endif /* FEAT_TOOLBAR */ @@ -4960,7 +5095,7 @@ gui_mch_init_font(char_u *font_name, int #endif /* !HAVE_GTK2 */ /* Preserve the logical dimensions of the screen. */ - update_window_manager_hints(); + update_window_manager_hints(0, 0); return OK; } @@ -6577,7 +6712,7 @@ gui_mch_enable_scrollbar(scrollbar_T *sb else gtk_widget_hide(sb->id); - update_window_manager_hints(); + update_window_manager_hints(0, 0); } diff --git a/src/menu.c b/src/menu.c --- a/src/menu.c +++ b/src/menu.c @@ -739,6 +739,7 @@ add_menu_path(menu_path, menuarg, pri_ta switch (1 << i) { case MENU_VISUAL_MODE: + case MENU_SELECT_MODE: case MENU_OP_PENDING_MODE: case MENU_CMDLINE_MODE: c = Ctrl_C; @@ -1464,8 +1465,14 @@ get_menu_cmd_modes(cmd, forceit, noremap switch (*cmd++) { case 'v': /* vmenu, vunmenu, vnoremenu */ + modes = MENU_VISUAL_MODE | MENU_SELECT_MODE; + break; + case 'x': /* xmenu, xunmenu, xnoremenu */ modes = MENU_VISUAL_MODE; break; + case 's': /* smenu, sunmenu, snoremenu */ + modes = MENU_SELECT_MODE; + break; case 'o': /* omenu */ modes = MENU_OP_PENDING_MODE; break; @@ -1480,7 +1487,8 @@ get_menu_cmd_modes(cmd, forceit, noremap break; case 'a': /* amenu */ modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE | MENU_NORMAL_MODE - | MENU_VISUAL_MODE | MENU_OP_PENDING_MODE; + | MENU_VISUAL_MODE | MENU_SELECT_MODE + | MENU_OP_PENDING_MODE; break; case 'n': if (*cmd != 'o') /* nmenu, not noremenu */ @@ -1494,7 +1502,7 @@ get_menu_cmd_modes(cmd, forceit, noremap if (forceit) /* menu!! */ modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE; else /* menu */ - modes = MENU_NORMAL_MODE | MENU_VISUAL_MODE + modes = MENU_NORMAL_MODE | MENU_VISUAL_MODE | MENU_SELECT_MODE | MENU_OP_PENDING_MODE; } @@ -1545,7 +1553,12 @@ get_menu_index(menu, state) idx = MENU_INDEX_CMDLINE; #ifdef FEAT_VISUAL else if (VIsual_active) - idx = MENU_INDEX_VISUAL; + { + if (VIsual_select) + idx = MENU_INDEX_SELECT; + else + idx = MENU_INDEX_VISUAL; + } #endif else if (state == HITRETURN || state == ASKMORE) idx = MENU_INDEX_CMDLINE; @@ -1712,7 +1725,11 @@ get_menu_mode() { #ifdef FEAT_VISUAL if (VIsual_active) + { + if (VIsual_select) + return MENU_INDEX_SELECT; return MENU_INDEX_VISUAL; + } #endif if (State & INSERT) return MENU_INDEX_INSERT; diff --git a/src/ui.c b/src/ui.c --- a/src/ui.c +++ b/src/ui.c @@ -139,7 +139,7 @@ ui_inchar(buf, maxlen, wtime, tb_change_ #endif #ifdef FEAT_PROFILE - if (do_profiling && wtime != 0) + if (do_profiling == PROF_YES && wtime != 0) prof_inchar_enter(); #endif @@ -199,7 +199,7 @@ ui_inchar(buf, maxlen, wtime, tb_change_ theend: #endif #ifdef FEAT_PROFILE - if (do_profiling && wtime != 0) + if (do_profiling == PROF_YES && wtime != 0) prof_inchar_exit(); #endif return retval; @@ -473,7 +473,8 @@ clip_own_selection(cbd) * selected area. There is no specific redraw command for this, * just redraw all windows on the current buffer. */ if (cbd->owned - && get_real_state() == VISUAL + && (get_real_state() == VISUAL + || get_real_state() == SELECTMODE) && clip_isautosel() && hl_attr(HLF_V) != hl_attr(HLF_VNC)) redraw_curbuf_later(INVERTED_ALL); @@ -503,7 +504,8 @@ clip_lose_selection(cbd) * area. There is no specific redraw command for this, just redraw all * windows on the current buffer. */ if (was_owned - && get_real_state() == VISUAL + && (get_real_state() == VISUAL + || get_real_state() == SELECTMODE) && clip_isautosel() && hl_attr(HLF_V) != hl_attr(HLF_VNC)) {