Submitted By: Jim Gifford (jim at linuxfromscratch dot org) Date: 12-05-2006 Initial Package Version: 7.0 Origin: Upstream Upstream Status: Applied Description: Contains all upstream patches up to 7.0.178 The following patches were skipped 005 027 028 032 045 057 065 074 108 130 131 132 138 156 161 170 171 diff -Naur vim70.orig/configure vim70/configure --- vim70.orig/configure 2004-07-05 02:02:24.000000000 -0700 +++ vim70/configure 2006-12-05 19:57:51.000000000 -0800 @@ -3,4 +3,4 @@ # This is just a stub for the Unix configure script, to provide support for # doing "./configure" in the top Vim directory. -cd src && ./configure "$@" +cd src && exec ./configure "$@" diff -Naur vim70.orig/runtime/autoload/ccomplete.vim vim70/runtime/autoload/ccomplete.vim --- vim70.orig/runtime/autoload/ccomplete.vim 2006-05-03 07:35:56.000000000 -0700 +++ vim70/runtime/autoload/ccomplete.vim 2006-12-05 19:57:40.000000000 -0800 @@ -1,7 +1,7 @@ " Vim completion script " Language: C " Maintainer: Bram Moolenaar -" Last Change: 2006 May 03 +" Last Change: 2006 May 08 " This function is used for the 'omnifunc' option. @@ -458,7 +458,7 @@ " member. function! s:StructMembers(typename, items, all) " Todo: What about local structures? - let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) + let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")')) if fnames == '' return [] endif diff -Naur vim70.orig/runtime/autoload/gzip.vim vim70/runtime/autoload/gzip.vim --- vim70.orig/runtime/autoload/gzip.vim 2006-03-31 07:12:15.000000000 -0800 +++ vim70/runtime/autoload/gzip.vim 2006-12-05 19:58:04.000000000 -0800 @@ -1,6 +1,6 @@ " Vim autoload file for editing compressed files. " Maintainer: Bram Moolenaar -" Last Change: 2006 Mar 31 +" Last Change: 2006 Oct 03 " These functions are used by the gzip plugin. @@ -68,9 +68,9 @@ let tmp = tempname() let tmpe = tmp . "." . expand(":e") " write the just read lines to a temp file "'[,']w tmp.gz" - execute "silent '[,']w " . tmpe + execute "silent '[,']w " . escape(tmpe, ' ') " uncompress the temp file: call system("gzip -dn tmp.gz") - call system(a:cmd . " " . tmpe) + call system(a:cmd . " " . s:escape(tmpe)) if !filereadable(tmp) " uncompress didn't work! Keep the compressed file then. echoerr "Error: Could not read uncompressed file" @@ -127,9 +127,9 @@ let nmt = s:tempname(nm) if rename(nm, nmt) == 0 if exists("b:gzip_comp_arg") - call system(a:cmd . " " . b:gzip_comp_arg . " " . nmt) + call system(a:cmd . " " . b:gzip_comp_arg . " " . s:escape(nmt)) else - call system(a:cmd . " " . nmt) + call system(a:cmd . " " . s:escape(nmt)) endif call rename(nmt . "." . expand(":e"), nm) endif @@ -154,10 +154,10 @@ if rename(nm, nmte) == 0 if &patchmode != "" && getfsize(nm . &patchmode) == -1 " Create patchmode file by creating the decompressed file new - call system(a:cmd . " -c " . nmte . " > " . nmt) + call system(a:cmd . " -c " . s:escape(nmte) . " > " . s:escape(nmt)) call rename(nmte, nm . &patchmode) else - call system(a:cmd . " " . nmte) + call system(a:cmd . " " . s:escape(nmte)) endif call rename(nmt, nm) endif @@ -175,4 +175,12 @@ return fnamemodify(a:name, ":p:h") . "/X~=@l9q5" endfun +fun s:escape(name) + " shellescape() was added by patch 7.0.111 + if v:version > 700 || (v:version == 700 && has('patch111')) + return shellescape(a:name) + endif + return "'" . a:name . "'" +endfun + " vim: set sw=2 : diff -Naur vim70.orig/runtime/autoload/paste.vim vim70/runtime/autoload/paste.vim --- vim70.orig/runtime/autoload/paste.vim 2006-04-21 11:31:01.000000000 -0700 +++ vim70/runtime/autoload/paste.vim 2006-12-05 19:57:46.000000000 -0800 @@ -1,6 +1,6 @@ " Vim support file to help with paste mappings and menus " Maintainer: Bram Moolenaar -" Last Change: 2006 Apr 21 +" Last Change: 2006 Jun 23 " Define the string to use for items that are present both in Edit, Popup and " Toolbar menu. Also used in mswin.vim and macmap.vim. @@ -12,7 +12,7 @@ if has("virtualedit") let paste#paste_cmd = {'n': ":call paste#Paste()"} let paste#paste_cmd['v'] = '"-c' . paste#paste_cmd['n'] - let paste#paste_cmd['i'] = '' . paste#paste_cmd['n'] . 'gi' + let paste#paste_cmd['i'] = 'x' . paste#paste_cmd['n'] . 'gi' func! paste#Paste() let ove = &ve diff -Naur vim70.orig/runtime/autoload/spellfile.vim vim70/runtime/autoload/spellfile.vim --- vim70.orig/runtime/autoload/spellfile.vim 2006-02-01 04:12:24.000000000 -0800 +++ vim70/runtime/autoload/spellfile.vim 2006-12-05 19:57:58.000000000 -0800 @@ -1,9 +1,9 @@ " Vim script to download a missing spell file " Maintainer: Bram Moolenaar -" Last Change: 2006 Feb 01 +" Last Change: 2006 Aug 29 if !exists('g:spellfile_URL') - let g:spellfile_URL = 'ftp://ftp.vim.org/pub/vim/unstable/runtime/spell' + let g:spellfile_URL = 'ftp://ftp.vim.org/pub/vim/runtime/spell' endif let s:spellfile_URL = '' " Start with nothing so that s:donedict is reset. @@ -61,13 +61,13 @@ new setlocal bin echo 'Downloading ' . fname . '...' - exe 'Nread ' g:spellfile_URL . '/' . fname + call spellfile#Nread(fname) if getline(2) !~ 'VIMspell' " Didn't work, perhaps there is an ASCII one. g/^/d let fname = a:lang . '.ascii.spl' echo 'Could not find it, trying ' . fname . '...' - exe 'Nread ' g:spellfile_URL . '/' . fname + call spellfile#Nread(fname) if getline(2) !~ 'VIMspell' echo 'Sorry, downloading failed' bwipe! @@ -95,7 +95,7 @@ g/^/d let fname = substitute(fname, '\.spl$', '.sug', '') echo 'Downloading ' . fname . '...' - exe 'Nread ' g:spellfile_URL . '/' . fname + call spellfile#Nread(fname) if getline(2) !~ 'VIMsug' echo 'Sorry, downloading failed' else @@ -109,3 +109,15 @@ bwipe endif endfunc + +" Read "fname" from the server. +function! spellfile#Nread(fname) + if g:spellfile_URL =~ '^ftp://' + " for an ftp server use a default login and password to avoid a prompt + let machine = substitute(g:spellfile_URL, 'ftp://\([^/]*\).*', '\1', '') + let dir = substitute(g:spellfile_URL, 'ftp://[^/]*/\(.*\)', '\1', '') + exe 'Nread "' . machine . ' anonymous vim7user ' . dir . '/' . a:fname . '"' + else + exe 'Nread ' g:spellfile_URL . '/' . a:fname + endif +endfunc diff -Naur vim70.orig/runtime/doc/eval.txt vim70/runtime/doc/eval.txt --- vim70.orig/runtime/doc/eval.txt 2006-05-07 05:16:44.000000000 -0700 +++ vim70/runtime/doc/eval.txt 2006-12-05 19:58:10.000000000 -0800 @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.0. Last change: 2006 May 06 +*eval.txt* For Vim version 7.0. Last change: 2006 Nov 01 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1374,6 +1374,21 @@ 'guitabtooltip'. Only valid while one of these expressions is being evaluated. Read-only when in the |sandbox|. + *v:mouse_win* *mouse_win-variable* +v:mouse_win Window number for a mouse click obtained with |getchar()|. + First window has number 1, like with |winnr()|. The value is + zero when there was no mouse button click. + + *v:mouse_lnum* *mouse_lnum-variable* +v:mouse_lnum Line number for a mouse click obtained with |getchar()|. + This is the text line number, not the screen line number. The + value is zero when there was no mouse button click. + + *v:mouse_col* *mouse_col-variable* +v:mouse_col Column number for a mouse click obtained with |getchar()|. + This is the screen column number, like with |virtcol()|. The + value is zero when there was no mouse button click. + *v:prevcount* *prevcount-variable* v:prevcount The count given for the last but one Normal mode command. This is the v:count value of the previous command. Useful if @@ -1709,6 +1724,8 @@ settabwinvar( {tabnr}, {winnr}, {varname}, {val}) set {varname} in window {winnr} in tab page {tabnr} to {val} setwinvar( {nr}, {varname}, {val}) set {varname} in window {nr} to {val} +shellescape( {string}) String escape {string} for use as shell + command argument simplify( {filename}) String simplify filename as much as possible sort( {list} [, {func}]) List sort {list}, using {func} to compare soundfold( {word}) String sound-fold {word} @@ -2700,6 +2717,17 @@ one-byte character it is the character itself as a number. Use nr2char() to convert it to a String. + When the user clicks a mouse button, the mouse event will be + returned. The position can then be found in |v:mouse_col|, + |v:mouse_lnum| and |v:mouse_win|. This example positions the + mouse as it would normally happen: > + let c = getchar() + if c == "\" && v:mouse_win > 0 + exe v:mouse_win . "wincmd w" + exe v:mouse_lnum + exe "normal " . v:mouse_col . "|" + endif +< There is no prompt, you will somehow have to make clear to the user that a character has to be typed. There is no mapping for the character. @@ -4434,6 +4462,21 @@ :call setwinvar(1, "&list", 0) :call setwinvar(2, "myvar", "foobar") +shellescape({string}) *shellescape()* + Escape {string} for use as shell command argument. + On MS-Windows and MS-DOS, when 'shellslash' is not set, it + will enclose {string} double quotes and double all double + quotes within {string}. + For other systems, it will enclose {string} in single quotes + and replace all "'" with "'\''". + Example: > + :echo shellescape('c:\program files\vim') +< results in: + "c:\program files\vim" ~ + Example usage: > + :call system("chmod +x -- " . shellescape(expand("%"))) + + simplify({filename}) *simplify()* Simplify the file name as much as possible without changing the meaning. Shortcuts (on MS-Windows) or symbolic links (on diff -Naur vim70.orig/runtime/doc/netbeans.txt vim70/runtime/doc/netbeans.txt --- vim70.orig/runtime/doc/netbeans.txt 2006-05-07 05:16:45.000000000 -0700 +++ vim70/runtime/doc/netbeans.txt 2006-12-05 19:58:11.000000000 -0800 @@ -1,4 +1,4 @@ -*netbeans.txt* For Vim version 7.0. Last change: 2006 Mar 09 +*netbeans.txt* For Vim version 7.0. Last change: 2006 Nov 14 VIM REFERENCE MANUAL by Gordon Prieur @@ -259,8 +259,8 @@ confusion happening again, netbeans_saved() has been renamed to netbeans_save_buffer(). -We are now at version 2.3. For the differences between 2.2 and 2.3 search for -"2.3" below. +We are now at version 2.4. For the differences between 2.3 and 2.4 search for +"2.4" below. The messages are currently sent over a socket. Since the messages are in plain UTF-8 text this protocol could also be used with any other communication @@ -605,6 +605,15 @@ getMark Not implemented. +getAnno serNum + Return the line number of the annotation in the buffer. + Argument: + serNum serial number of this placed annotation + The reply is: + 123 lnum line number of the annotation + 123 0 invalid annotation serial number + New in version 2.4. + getModified When a buffer is specified: Return zero if the buffer does not have changes, one if it does have changes. When no buffer is specified (buffer number zero): Return the diff -Naur vim70.orig/runtime/menu.vim vim70/runtime/menu.vim --- vim70.orig/runtime/menu.vim 2006-04-17 06:47:28.000000000 -0700 +++ vim70/runtime/menu.vim 2006-12-05 19:58:04.000000000 -0800 @@ -2,7 +2,7 @@ " You can also use this as a start for your own set of menus. " " Maintainer: Bram Moolenaar -" Last Change: 2006 Apr 17 +" Last Change: 2006 Sep 14 " Note that ":an" (short for ":anoremenu") is often used to make a menu work " in all modes and avoid side effects from mappings defined by the user. @@ -885,6 +885,8 @@ if exists("s:changeitem") && s:changeitem != '' call SpellDel() endif + + " Return quickly if spell checking is not enabled. if !&spell || &spelllang == '' return endif @@ -908,18 +910,18 @@ let s:fromword = w let pri = 1 for sug in s:suglist - exe 'amenu 1.5.' . pri . ' PopUp.' . s:changeitem . '.' . escape(sug, ' .') + exe 'anoremenu 1.5.' . pri . ' PopUp.' . s:changeitem . '.' . escape(sug, ' .') \ . ' :call SpellReplace(' . pri . ')' let pri += 1 endfor let s:additem = 'add\ "' . escape(w, ' .') . '"\ to\ word\ list' - exe 'amenu 1.6 PopUp.' . s:additem . ' :spellgood ' . w . '' + exe 'anoremenu 1.6 PopUp.' . s:additem . ' :spellgood ' . w . '' let s:ignoreitem = 'ignore\ "' . escape(w, ' .') . '"' - exe 'amenu 1.7 PopUp.' . s:ignoreitem . ' :spellgood! ' . w . '' + exe 'anoremenu 1.7 PopUp.' . s:ignoreitem . ' :spellgood! ' . w . '' - amenu 1.8 PopUp.-SpellSep- : + anoremenu 1.8 PopUp.-SpellSep- : endif endif endfunc @@ -938,7 +940,9 @@ let s:changeitem = '' endfun - au! MenuPopup * call SpellPopup() + augroup SpellPopupMenu + au! MenuPopup * call SpellPopup() + augroup END endif " The GUI toolbar (for MS-Windows and GTK) @@ -1013,9 +1017,9 @@ tmenu ToolBar.FindPrev Find Previous tmenu ToolBar.Replace Find / Replace... endif - tmenu ToolBar.LoadSesn Chose a session to load + tmenu ToolBar.LoadSesn Choose a session to load tmenu ToolBar.SaveSesn Save current session - tmenu ToolBar.RunScript Chose a Vim Script to run + tmenu ToolBar.RunScript Choose a Vim Script to run tmenu ToolBar.Make Make current project (:make) tmenu ToolBar.RunCtags Build tags in current directory tree (!ctags -R .) tmenu ToolBar.TagJump Jump to tag under cursor diff -Naur vim70.orig/runtime/plugin/matchparen.vim vim70/runtime/plugin/matchparen.vim --- vim70.orig/runtime/plugin/matchparen.vim 2006-04-27 06:31:26.000000000 -0700 +++ vim70/runtime/plugin/matchparen.vim 2006-12-05 19:58:01.000000000 -0800 @@ -1,6 +1,6 @@ " Vim plugin for showing matching parens " Maintainer: Bram Moolenaar -" Last Change: 2006 Apr 27 +" Last Change: 2006 Sep 09 " Exit quickly when: " - this plugin was already loaded (or disabled) @@ -44,7 +44,7 @@ let before = 0 let c = getline(c_lnum)[c_col - 1] - let plist = split(&matchpairs, ':\|,') + let plist = split(&matchpairs, '.\zs[:,]') let i = index(plist, c) if i < 0 " not found, in Insert mode try character before the cursor @@ -90,19 +90,19 @@ " Find the match. When it was just before the cursor move it there for a " moment. if before > 0 - let save_cursor = getpos('.') + let save_cursor = winsaveview() call cursor(c_lnum, c_col - before) endif " When not in a string or comment ignore matches inside them. let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' . - \ '=~? "string\\|comment"' + \ '=~? "string\\|character\\|singlequote\\|comment"' execute 'if' s_skip '| let s_skip = 0 | endif' let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline) if before > 0 - call setpos('.', save_cursor) + call winrestview(save_cursor) endif " If a match is found setup match highlighting. diff -Naur vim70.orig/runtime/scripts.vim vim70/runtime/scripts.vim --- vim70.orig/runtime/scripts.vim 2006-03-28 11:30:49.000000000 -0800 +++ vim70/runtime/scripts.vim 2006-12-05 19:57:51.000000000 -0800 @@ -1,7 +1,7 @@ " Vim support file to detect file types in scripts " " Maintainer: Bram Moolenaar -" Last change: 2006 Mar 28 +" Last change: 2006 Jul 08 " This file is called by an autocommand for every file that has just been " loaded into a buffer. It checks if the type of file can be recognized by @@ -54,6 +54,12 @@ let s:name = substitute(s:line1, '^#!\s*\S*[/\\]\(\i\+\).*', '\1', '') endif + " tcl scripts may have #!/bin/sh in the first line and "exec wish" in the + " third line. Suggested by Steven Atkinson. + if getline(3) =~ '^exec wish' + let s:name = 'wish' + endif + " Bourne-like shell scripts: bash bash2 ksh ksh93 sh if s:name =~ '^\(bash\d*\|\|ksh\d*\|sh\)\>' call SetFileTypeSH(s:line1) " defined in filetype.vim diff -Naur vim70.orig/runtime/tutor/Makefile vim70/runtime/tutor/Makefile --- vim70.orig/runtime/tutor/Makefile 2004-06-07 07:32:39.000000000 -0700 +++ vim70/runtime/tutor/Makefile 2006-12-05 19:58:01.000000000 -0800 @@ -2,8 +2,13 @@ # # The Japanese tutor exists in three encodings. Use the UTF-8 version as the # original and create the others with conversion. +# +# Similarly for Russian and Korean -all: tutor.ja.sjis tutor.ja.euc tutor.ko.euc +all: tutor.ja.sjis tutor.ja.euc \ + tutor.ko.euc \ + tutor.ru tutor.ru.cp1251 \ + tutor.gr tutor.gr.cp737 tutor.ja.sjis: tutor.ja.utf-8 nkf -WXs tutor.ja.utf-8 > tutor.ja.sjis @@ -13,3 +18,15 @@ tutor.ko.euc: tutor.ko.utf-8 iconv -f UTF-8 -t EUC-KR tutor.ko.utf-8 > tutor.ko.euc + +tutor.ru: tutor.ru.utf-8 + iconv -f UTF-8 -t KOI8-R tutor.ru.utf-8 > tutor.ru + +tutor.ru.cp1251: tutor.ru.utf-8 + iconv -f UTF-8 -t cp1251 tutor.ru.utf-8 > tutor.ru.cp1251 + +tutor.gr: tutor.gr.utf-8 + iconv -f UTF-8 -t ISO-8859-7 tutor.gr.utf-8 > tutor.gr + +tutor.gr.cp737: tutor.gr.utf-8 + iconv -f UTF-8 -t cp737 tutor.gr.utf-8 > tutor.gr.cp737 diff -Naur vim70.orig/runtime/tutor/tutor.gr.utf-8 vim70/runtime/tutor/tutor.gr.utf-8 --- vim70.orig/runtime/tutor/tutor.gr.utf-8 1969-12-31 16:00:00.000000000 -0800 +++ vim70/runtime/tutor/tutor.gr.utf-8 2006-12-05 19:58:01.000000000 -0800 @@ -0,0 +1,815 @@ +=============================================================================== += Κ αλ ω σ ή ρ θ α τ ε σ τ ο V I M T u t o r - Έκδοση 1.5 = +=============================================================================== + + Ο Vim είναι ένας πανίσχυρος συντάκτης που έχει πολλές εντολές, πάρα + πολλές για να εξηγήσουμε σε μία περιήγηση όπως αυτή. Αυτή η περιήγηση + σχεδιάστηκε για να περιγράψει ικανοποιητικά τις εντολές που θα σας + κάνουν να χρησιμοποιείτε εύκολα τον Vim σαν έναν γενικής χρήσης συντάκτη. + + Ο κατά προσέγγιση χρόνος που απαιτείται για να ολοκληρώσετε την περιήγηση + είναι 25-30 λεπτά, εξαρτώντας από το πόσο χρόνο θα ξοδέψετε για + πειραματισμούς. + + Οι εντολές στα μαθήματα θα τροποποιήσουν το κείμενο. Δημιουργήστε ένα + αντίγραφο αυτού του αρχείου για να εξασκηθείτε (αν ξεκινήσατε το + "Vimtutor" αυτό είναι ήδη ένα αντίγραφο). + + Είναι σημαντικό να θυμάστε ότι αυτή η περιήγηση είναι οργανωμένη έτσι + ώστε να διδάσκει μέσω της χρήσης. Αυτό σημαίνει ότι χρειάζεται να + εκτελείτε τις εντολές για να τις μάθετε σωστά. Αν διαβάζετε μόνο το + κείμενο, θα τις ξεχάσετε! + + Τώρα, βεβαιωθείτε ότι το πλήκτρο Shift-Lock ΔΕΝ είναι πατημένο και + πατήστε το πλήκτρο j αρκετές φορές για να μετακινήσετε τον δρομέα έτσι + ώστε το Μάθημα 1.1 να γεμίσει πλήρως την οθόνη. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 1.1: ΜΕΤΑΚΙΝΟΝΤΑΣ ΤΟΝ ΔΡΟΜΕΑ + + ** Για να κινήσετε τον δρομέα, πατήστε τα πλήκτρα h,j,k,l όπως δείχνεται. ** + ^ + k Hint: Το πλήκτρο h είναι αριστερά και κινεί στ' αριστερά. + < h l > Το πλήκτρο l είναι δεξιά και κινεί στα δεξιά. + j Το πλήκτρο j μοιάζει με βελάκι προς τα κάτω. + v + + 1. Μετακινείστε τον δρομέα τριγύρω στην οθόνη μέχρι να νοιώθετε άνετα. + + 2. Κρατήστε πατημένο το κάτω πλήκτρο (j) μέχρι να επαναληφθεί. +---> Τώρα ξέρετε πώς να μετακινηθείτε στο επόμενο μάθημα. + + 3. Χρησιμοποιώντας το κάτω πλήκτρο, μετακινηθείτε στο Μάθημα 1.2. + +Σημείωση: Αν αμφιβάλλετε για κάτι που πατήσατε, πατήστε για να βρεθείτε + στην Κανονική Κατάσταση. Μετά πατήστε ξανά την εντολή που θέλατε. + +Σημείωση: Τα πλήκτρα του δρομέα θα πρέπει επίσης να δουλεύουν. Αλλά με τα hjkl + θα μπορείτε να κινηθείτε πολύ γρηγορότερα, μόλις τα συνηθίσετε. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 1.2: ΜΠΑΙΝΟΝΤΑΣ ΚΑΙ ΒΓΑΙΝΟΝΤΑΣ ΣΤΟΝ VIM + + !! ΣΗΜΕΙΩΣΗ: Πριν εκτελέσετε κάποιο από τα βήματα, διαβάστε όλο το μάθημα!! + + 1. Πατήστε το πλήκτρο (για να είστε σίγουρα στην Κανονική Κατάσταση). + + 2. Πληκτρολογήστε: :q! . + +---> Αυτό εξέρχεται από τον συντάκτη ΧΩΡΙΣ να σώσει όποιες αλλαγές έχετε κάνει. + Αν θέλετε να σώσετε τις αλλαγές και να εξέρθετε πληκτρολογήστε: + :wq + + 3. Όταν δείτε την προτροπή του φλοιού, πληκτρολογήστε την εντολή με την οποία + μπήκατε σε αυτήν την περιήγηση. Μπορεί να είναι: vimtutor + Κανονικά θα χρησιμοποιούσατε: vim tutor + +---> 'vim' σημαίνει εισαγωγή στον συντάκτη vim, 'tutor' είναι το αρχείο που + θέλουμε να διορθώσουμε. + + 4. Αν έχετε απομνημονεύσει αυτά τα βήματα και έχετε αυτοπεποίθηση, εκτελέστε + τα βήματα 1 έως 3 για να βγείτε και να μπείτε ξανά στον συντάκτη. Μετά + μετακινήστε τον δρομέα κάτω στο Μάθημα 1.3. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 1.3: ΔΙΟΡΘΩΣΗ ΚΕΙΜΕΝΟΥ - ΔΙΑΓΡΑΦΗ + + ** Όσο είστε στην Κανονική Κατάσταση πατήστε x για να διαγράψετε τον + χαρακτήρα κάτω από τον δρομέα. ** + + 1. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με --->. + + 2. Για να διορθώσετε τα λάθη, κινείστε τον δρομέα μέχρι να είναι πάνω από + τον χαρακτήρα που θα διαγραφεί. + + 3. Πατήστε το πλήκτρο x για να διαγράψετε τον ανεπιθύμητο χαρακτήρα. + + 4. Επαναλάβετε τα βήματα 2 μέχρι 4 μέχρι η πρόταση να είναι σωστή. + +---> The ccow jumpedd ovverr thhe mooon. + + 5. Τώρα που η γραμμή είναι σωστή, πηγαίντε στο Μάθημα 1.4. + +ΣΗΜΕΙΩΣΗ: Καθώς διατρέχετε αυτήν την περιήγηση, προσπαθήστε να μην + απομνημονεύετε, μαθαίνετε με τη χρήση. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 1.4: ΔΙΟΡΘΩΣΗ ΚΕΙΜΕΝΟΥ - ΠΑΡΕΜΒΟΛΗ + + ** Όσο είστε σε Κανονική Κατάσταση πατήστε i για να παρεμβάλλετε κείμενο. ** + + 1. Μετακινείστε τον δρομέα μέχρι την πρώτη γραμμή παρακάτω σημειωμένη με --->. + + 2. Για να κάνετε την πρώτη γραμμή ίδια με την δεύτερη, μετακινείστε τον + δρομέα πάνω στον πρώτο χαρακτήρα ΜΕΤΑ από όπου θα παρεμβληθεί το κείμενο. + + 3. Πατήστε το i και πληκτρολογήστε τις απαραίτητες προσθήκες. + + 4. Καθώς διορθώνετε κάθε λάθος πατήστε για να επιστρέψετε στην + Κανονική Κατάσταση. Επαναλάβετε τα βήματα 2 μέχρι 4 για να διορθώσετε + την πρόταση. + +---> There is text misng this . +---> There is some text missing from this line. + + 5. Όταν είστε άνετοι με την παρεμβολή κειμένου μετακινηθείτε στην + παρακάτω περίληψη. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ΜΑΘΗΜΑ 1 ΠΕΡΙΛΗΨΗ + + + 1. Ο δρομέας κινείται χρησιμοποιώντας είτε τα πλήκτρα δρομέα ή τα hjkl. + h (αριστέρα) j (κάτω) k (πάνω) l (δεξιά) + + 2. Για να μπείτε στον Vim (από την προτροπή %) γράψτε: vim ΑΡΧΕΙΟ + + 3. Για να βγείτε γράψτε: :q! για απόρριψη των αλλαγών. + Ή γράψτε: :wq για αποθήκευση των αλλαγών. + + 4. Για να διαγράψετε έναν χαρακτήρα κάτω από τον δρομέα σε + Κανονική Κατάσταση πατήστε: x + + 5. Για να εισάγετε κείμενο στον δρομέα όσο είστε σε Κανονική Κατάσταση γράψτε: + i πληκτρολογήστε το κείμενο + +ΣΗΜΕΙΩΣΗ: Πατώντας θα τοποθετηθείτε στην Κανονική Κατάσταση ή θα + ακυρώσετε μία ανεπιθύμητη και μερικώς ολοκληρωμένη εντολή. + +Τώρα συνεχίστε με το Μάθημα 2. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 2.1: ΕΝΤΟΛΕΣ ΔΙΑΓΡΑΦΗΣ + + ** Γράψτε dw για να διαγράψετε μέχρι το τέλος μίας λέξης. ** + + 1. Πατήστε για να βεβαιωθείτε ότι είστε στην Κανονική Κατάσταση. + + 2. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με --->. + + 3. Πηγαίνετε τον δρομέα στην αρχή της λέξης που πρέπει να διαγραφεί. + + 4. Γράψτε dw για να κάνετε την λέξη να εξαφανιστεί. + +ΣΗΜΕΙΩΣΗ: Τα γράμματα dw θα εμφανιστούν στην τελευταία γραμμή της οθόνης όσο + τα πληκτρολογείτε. Αν γράψατε κάτι λάθος, πατήστε και + ξεκινήστε από την αρχή. + +---> There are a some words fun that don't belong paper in this sentence. + + 5. Επαναλάβετε τα βήματα 3 και 4 μέχρι η πρόταση να είναι σωστή και + πηγαίνετε στο Μάθημα 2.2. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 2.2: ΠΕΡΙΣΣΟΤΕΡΕΣ ΕΝΤΟΛΕΣ ΔΙΑΓΡΑΦΗΣ + + ** Πληκτρολογήστε d$ για να διαγράψετε μέχρι το τέλος της γραμμής. ** + + 1. Πατήστε για να βεβαιωθείτε ότι είστε στην Κανονική Κατάσταση. + + 2. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με --->. + + 3. Μετακινείστε τον δρομέα στο τέλος της σωστής γραμμής (ΜΕΤΑ την πρώτη . ). + + 4. Πατήστε d$ για να διαγράψετε μέχρι το τέλος της γραμμής. + +---> Somebody typed the end of this line twice. end of this line twice. + + 5. Πηγαίνετε στο Μάθημα 2.3 για να καταλάβετε τι συμβαίνει. + + + + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 2.3: ΠΕΡΙ ΕΝΤΟΛΩΝ ΚΑΙ ΑΝΤΙΚΕΙΜΕΝΩΝ + + +Η μορφή της εντολής διαγραφής d είναι ως εξής: + + [αριθμός] d αντικείμενο Ή d [αριθμός] αντικείμενο + Όπου: + αριθμός - πόσες φορές θα εκτελεστεί η εντολή (προαιρετικό, εξ' ορισμού=1). + d - η εντολή της διαγραφής. + αντικείμενο - πάνω σε τι θα λειτουργήσει η εντολή (παρακάτω λίστα). + + Μία μικρή λίστα από αντικείμενα: + w - από τον δρομέα μέχρι το τέλος της λέξης, περιλαμβάνοντας το διάστημα. + e - από τον δρομέα μέχρι το τέλος της λέξης, ΧΩΡΙΣ το διάστημα. + $ - από τον δρομέα μέχρι το τέλος της γραμμής. + +ΣΗΜΕΙΩΣΗ: Για τους τύπους της περιπέτειας, πατώντας απλώς το αντικείμενο όσο + είστε στην Κανονική Κατάσταση χωρίς κάποια εντολή θα μετακινήσετε + τον δρομέα όπως καθορίζεται στην λίστα αντικειμένων. + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 2.4: ΜΙΑ ΕΞΑΙΡΕΣΗ ΣΤΗΝ 'ΕΝΤΟΛΗ-ΑΝΤΙΚΕΙΜΕΝΟ' + + ** Πληκτρολογήστε dd για να διαγράψετε όλη τη γραμμή. ** + + Εξαιτίας της συχνότητας της διαγραφής ολόκληρης γραμμής, οι σχεδιαστές + του Vim αποφάσισαν ότι θα ήταν ευκολότερο να γράφετε απλώς δύο d στη + σειρά για να διαγράψετε μία γραμμή. + + 1. Μετακινείστε τον δρομέα στη δεύτερη γραμμή της παρακάτω φράσης. + 2. Γράψτε dd για να διαγράψετε τη γραμμή. + 3. Τώρα μετακινηθείτε στην τέταρτη γραμμή. + 4. Γράψτε 2dd (θυμηθείτε αριθμός-εντολή-αντικείμενο) για να + διαγράψετε δύο γραμμές. + + 1) Roses are red, + 2) Mud is fun, + 3) Violets are blue, + 4) I have a car, + 5) Clocks tell time, + 6) Sugar is sweet + 7) And so are you. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 2.5: Η ΕΝΤΟΛΗ ΑΝΑΙΡΕΣΗΣ + + ** Πατήστε u για να αναιρέσετε τις τελευταίες εντολές, + U για να διορθώσετε όλη τη γραμμή. ** + + 1. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με ---> και + τοποθετήστε τον πάνω στο πρώτο λάθος. + 2. Πατήστε x για να διαγράψετε τον πρώτο ανεπιθύμητο χαρακτήρα. + 3. Τώρα πατήστε u για να αναιρέσετε την τελευταία εκτελεσμένη εντολή. + 4. Αυτή τη φορά διορθώστε όλα τα λάθη στη γραμμή χρησιμοποιώντας την εντολή x. + 5. Τώρα πατήστε ένα κεφαλαίο U για να επιστρέψετε τη γραμμή στην αρχική + της κατάσταση. + 6. Τώρα πατήστε u μερικές φορές για να αναιρέσετε την U και + προηγούμενες εντολές. + 7. Τώρα πατήστε CTRL-R (κρατώντας πατημένο το πλήκτρο CTRL καθώς πατάτε το R) + μερικές φορές για να επαναφέρετε τις εντολές (αναίρεση των αναιρέσεων). + +---> Fiix the errors oon thhis line and reeplace them witth undo. + + 8. Αυτές είναι πολύ χρήσιμες εντολές. Τώρα πηγαίνετε στην + Περίληψη του Μαθήματος 2. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ΜΑΘΗΜΑ 2 ΠΕΡΙΛΗΨΗ + + + 1. Για να διαγράψετε από τον δρομέα μέχρι το τέλος λέξης γράψτε: dw + + 2. Για να διαγράψετε από τον δρομέα μέχρι το τέλος γραμμής γράψτε: d$ + + 3. Για να διαγράψετε ολόκληρη τη γραμμή γράψτε: dd + + 4. Η μορφή για μία εντολή στην Κανονική Κατάσταση είναι: + + [αριθμός] εντολή αντικείμενο Ή εντολή [αριθμός] αντικείμενο + όπου: + αριθμός - πόσες φορές να επαναληφθεί η εντολή + εντολή - τι να γίνει, όπως η d για διαγραφή + αντικείμενο - πάνω σε τι να ενεργήσει η εντολή, όπως w (λέξη), + $ (τέλος της γραμμής), κτλ. + + 5. Για να αναιρέσετε προηγούμενες ενέργειες, πατήστε: u (πεζό u) + Για να αναιρέσετε όλες τις αλλαγές στη γραμμή, πατήστε: U (κεφαλαίο U) + Για να αναιρέσετε τις αναιρέσεις, πατήστε: CTRL-R + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 3.1: Η ΕΝΤΟΛΗ ΤΟΠΟΘΕΤΗΣΗΣ + + + ** Πατήστε p για να τοποθετήσετε την τελευταία διαγραφή μετά τον δρομέα. ** + + 1. Μετακινείστε τον δρομέα στην πρώτη γραμμή της παρακάτω ομάδας. + + 2. Πατήστε dd για να διαγράψετε τη γραμμή και να την αποθηκεύσετε σε + προσωρινή μνήμη του Vim. + + 3. Μετακινείστε τον δρομέα στη γραμμή ΠΑΝΩ από εκεί που θα πρέπει να πάει + η διαγραμμένη γραμμή. + + 4. Όσο είστε σε Κανονική Κατάσταση, πατήστε p για να βάλετε τη γραμμή. + + 5. Επαναλάβετε τα βήματα 2 έως 4 για να βάλετε όλες τις γραμμές στη + σωστή σειρά. + + d) Can you learn too? + b) Violets are blue, + c) Intelligence is learned, + a) Roses are red, + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 3.2: Η ΕΝΤΟΛΗ ΑΝΤΙΚΑΤΑΣΤΑΣΗΣ + + + ** Πατήστε r και χαρακτήρα για να αλλάξετε αυτόν που είναι + κάτω από τον δρομέα. ** + + 1. Μετακινείστε τον δρομέα στην πρώτη γραμμή παρακάτω σημειωμένη με --->. + + 2. Μετακινείστε τον δρομέα έτσι ώστε να είναι πάνω στο πρώτο λάθος. + + 3. Πατήστε r και μετά τον χαρακτήρα ο οποίος διορθώνει το λάθος. + + 4. Επαναλάβετε τα βήματα 2 και 3 μέχρι να είναι σωστή η πρώτη γραμμή. + +---> Whan this lime was tuoed in, someone presswd some wrojg keys! +---> When this line was typed in, someone pressed some wrong keys! + + 5. Τώρα πηγαίνετε στο Μάθημα 3.2. + +ΣΗΜΕΙΩΣΗ: Να θυμάστε ότι πρέπει να μαθαίνετε με τη χρήση, και όχι με + την απομνημόνευση. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 3.3: Η ΕΝΤΟΛΗ ΑΛΛΑΓΗΣ + + ** Για να αλλάξετε τμήμα ή όλη τη λέξη, πατήστε cw . ** + + 1. Μετακινείστε τον δρομέα στην πρώτη γραμμή παρακάτω σημειωμένη με --->. + + 2. Τοποθετήστε τον δρομέα πάνω στο u της λέξης lubw. + + 3. Πατήστε cw και τη σωστή λέξη (στην περίπτωση αυτή, γράψτε 'ine'.) + + 4. Πατήστε και πηγαίνετε στο επόμενο λάθος (στον πρώτο + χαρακτήρα προς αλλαγή). + + 5. Επαναλάβετε τα βήματα 3 και 4 μέχρις ότου η πρώτη πρόταση να είναι + ίδια με τη δεύτερη. + +---> This lubw has a few wptfd that mrrf changing usf the change command. +---> This line has a few words that need changing using the change command. + +Παρατηρείστε ότι η cw όχι μόνο αντικαθιστάει τη λέξη, αλλά σας εισάγει +επίσης σε παρεμβολή. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 3.4: ΠΕΡΙΣΣΟΤΕΡΕΣ ΑΛΛΑΓΕΣ ΜΕ c + + + ** Η εντολή αλλαγής χρησιμοποιείται με τα ίδια αντικείμενα της διαγραφής. ** + + + 1. Η εντολή αλλαγής δουλεύει με τον ίδιο τρόπο όπως η διαγραφή. Η μορφή είναι: + + [αριθμός] c αντικείμενο Ή c [αριθμός] αντικείμενο + + 2. Τα αντικείμενα είναι πάλι τα ίδια, όπως w (λέξη), $ (τέλος γραμμής), κτλ. + + 3. Μετακινηθείτε στην πρώτη γραμμή παρακάτω σημειωμένη με --->. + + 4. Μετακινείστε τον δρομέα στο πρώτο λάθος. + + 5. Γράψτε c$ για να κάνετε το υπόλοιπο της γραμμής ίδιο με τη δεύτερη + και πατήστε . + +---> The end of this line needs some help to make it like the second. +---> The end of this line needs to be corrected using the c$ command. + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ΜΑΘΗΜΑ 3 ΠΕΡΙΛΗΨΗ + + + 1. Για να τοποθετήσετε κείμενο που μόλις έχει διαγραφεί, πατήστε p . + Αυτό τοποθετεί το διαγραμμένο κείμενο ΜΕΤΑ τον δρομέα (αν διαγράφτηκε + γραμμή θα πάει μετά στη γραμμή κάτω από τον δρομέα. + + 2. Για να αντικαταστήσετε τον χαρακτήρα κάτω από τον δρομέα, πατήστε r + και μετά τον χαρακτήρα που θα αντικαταστήσει τον αρχικό. + + 3. Η εντολή αλλαγής σας επιτρέπει να αλλάξετε το καθορισμένο αντικείμενο + από τον δρομέα μέχρι το τέλος του αντικείμενο. Π.χ. γράψτε cw για να + αλλάξετε από τον δρομέα μέχρι το τέλος της λέξης, c$ για να αλλάξετε + μέχρι το τέλος γραμμής. + + 4. Η μορφή για την αλλαγή είναι: + + [αριθμός] c αντικείμενο Ή c [αριθμός] αντικείμενο + +Τώρα συνεχίστε με το επόμενο μάθημα. + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 4.1: ΘΕΣΗ ΚΑΙ ΚΑΤΑΣΤΑΣΗ ΑΡΧΕΙΟΥ + + + ** Πατήστε CTRL-g για να εμφανιστεί η θέση σας στο αρχείο και η κατάστασή του. + Πατήστε SHIFT-G για να πάτε σε μία γραμμή στο αρχείο. ** + + Σημείωση: Διαβάστε ολόκληρο το μάθημα πριν εκτελέσετε κάποιο από τα βήματα!! + + 1. Κρατήστε πατημένο το πλήκτρο Ctrl και πατήστε g . Μία γραμμή κατάστασης + θα εμφανιστεί στο κάτω μέρος της σελίδας με το όνομα αρχείου και τη + γραμμή που είστε. Θυμηθείτε τον αριθμό γραμμής για το Βήμα 3. + + 2. Πατήστε shift-G για να μετακινηθείτε στο τέλος του αρχείου. + + 3. Πατήστε τον αριθμό της γραμμής που ήσασταν και μετά shift-G. Αυτό θα + σας επιστρέψει στη γραμμή που ήσασταν πριν πατήσετε για πρώτη φορά Ctrl-g. + (Όταν πληκτρολογείτε τους αριθμούς, ΔΕΝ θα εμφανίζονται στην οθόνη). + + 4. Αν νοιώθετε σίγουρος για αυτό, εκτελέστε τα βήματα 1 έως 3. + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 4.2: Η ΕΝΤΟΛΗ ΑΝΑΖΗΤΗΣΗΣ + + + ** Πατήστε / ακολουθούμενο από τη φράση που ψάχνετε. ** + + 1. Σε Κανονική Κατάσταση πατήστε τον χαρακτήρα / . Παρατηρήστε ότι αυτός και + ο δρομέας εμφανίζονται στο κάτω μέρος της οθόνης όπως με την εντολή : . + + 2. Τώρα γράψτε 'errroor' . Αυτή είναι η λέξη που θέλετε να ψάξετε. + + 3. Για να ψάξετε ξανά για την ίδια φράση, πατήστε απλώς n . + Για να ψάξετε την ίδια φράση στην αντίθετη κατεύθυνση, πατήστε Shift-N . + + 4. Αν θέλετε να ψάξετε για μία φράση προς τα πίσω, χρησιμοποιήστε την εντολή ? αντί της / . + +---> Όταν η αναζήτηση φτάσει στο τέλος του αρχείου θα συνεχίσει από την αρχή. + + "errroor" is not the way to spell error; errroor is an error. + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 4.3: ΕΥΡΕΣΗ ΤΑΙΡΙΑΣΤΩΝ ΠΑΡΕΝΘΕΣΕΩΝ + + + ** Πατήστε % για να βρείτε την αντίστοιχη ), ], ή } . ** + + 1. Τοποθετήστε τον δρομέα σε κάποια (, [, ή { στην παρακάτω γραμμή + σημειωμένη με --->. + + 2. Τώρα πατήστε τον χαρακτήρα % . + + 3. Ο δρομέας θα πρέπει να είναι στην αντίστοιχη παρένθεση ή αγκύλη. + + 4. Πατήστε % για να μετακινήσετε τον δρομέα πίσω στην πρώτη αγκύλη + (του ζευγαριού). + +---> This ( is a test line with ('s, ['s ] and {'s } in it. )) + +ΣΗΜΕΙΩΣΗ: Αυτό είναι πολύ χρήσιμο στην αποσφαλμάτωση ενός προγράμματος + με μη ταιριαστές παρενθέσεις! + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 4.4: ΕΝΑΣ ΤΡΟΠΟΣ ΓΙΑ ΑΛΛΑΓΗ ΛΑΘΩΝ + + + ** Γράψτε :s/old/new/g για να αλλάξετε το 'new' με το 'old'. ** + + 1. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με --->. + + 2. Γράψτε :s/thee/the . Σημειώστε ότι αυτή η εντολή αλλάζει μόνο + την πρώτη εμφάνιση στη γραμμή. + + 3. Τώρα γράψτε :s/thee/the/g εννοώντας γενική αντικατάσταση στη + γραμμή. Αυτό αλλάζει όλες τις εμφανίσεις επί της γραμμής. + +---> thee best time to see thee flowers is in thee spring. + + 4. Για να αλλάξετε κάθε εμφάνιση μίας συμβολοσειράς μεταξύ δύο γραμμών, + γράψτε :#,#s/old/new/g όπου #,# οι αριθμοί των δύο γραμμών. + Γράψτε :%s/old/new/g για να αλλάξετε κάθε εμφάνιση σε όλο το αρχείο. + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ΜΑΘΗΜΑ 4 ΠΕΡΙΛΗΨΗ + + + 1. Το Ctrl-g εμφανίζει τη θέση σας στο αρχείο και την κατάστασή του. + Το Shift-G πηγαίνει στο τέλος του αρχείου. Ένας αριθμός γραμμής + ακολουθούμενος από Shift-G πηγαίνει σε εκείνη τη γραμμή. + + 2. Γράφοντας / ακολουθούμενο από μία φράση ψάχνει προς τα ΜΠΡΟΣΤΑ για + τη φράση. Γράφοντας ? ακολουθούμενο από μία φράση ψάχνει προς τα ΠΙΣΩ + για τη φράση. Μετά από μία αναζήτηση πατήστε n για να βρείτε την + επόμενη εμφάνιση προς την ίδια κατεύθυνση ή Shift-N για να ψάξετε + προς την αντίθετη κατεύθυνση. + + 3. Πατώντας % όσο ο δρομέας είναι πάνω σε μία (,),[,],{, ή } εντοπίζει + το αντίστοιχο ταίρι του ζευγαριού. + + 4. Για αντικατάσταση με new του πρώτου old στη γραμμή γράψτε :s/old/new + Για αντικατάσταση με new όλων των 'old' στη γραμμή γράψτε :s/old/new/g + Για αντικατάσταση φράσεων μεταξύ δύο # γραμμών γράψτε :#,#s/old/new/g + Για αντικατάσταση όλων των εμφανίσεων στο αρχείο γράψτε :%s/old/new/g + Για ερώτηση επιβεβαίωσης κάθε φορά προσθέστε ένα 'c' "%s/old/new/gc + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 5.1: ΠΩΣ ΕΚΤΕΛΩ ΜΙΑ ΕΞΩΤΕΡΙΚΗ ΕΝΤΟΛΗ + + +** Γράψτε :! ακολουθούμενο από μία εξωτερική εντολή για να την εκτελέσετε. ** + + 1. Πατήστε την οικεία εντολή : για να θέσετε τον δρομέα στο κάτω μέρος + της οθόνης. Αυτό σας επιτρέπει να δώσετε μία εντολή. + + 2. Τώρα πατήστε το ! (θαυμαστικό). Αυτό σας επιτρέπει να εκτελέσετε + οποιαδήποτε εξωτερική εντολή του φλοιού. + + 3. Σαν παράδειγμα γράψτε ls μετά από το ! και πατήστε . Αυτό θα + σας εμφανίσει μία λίστα του καταλόγου σας, ακριβώς σαν να ήσασταν στην + προτροπή του φλοιού. Ή χρησιμοποιήστε :!dir αν το ls δεν δουλεύει. + +---> Σημείωση: Είναι δυνατόν να εκτελέσετε οποιαδήποτε εξωτερική εντολή + με αυτόν τον τρόπο. + +---> Σημείωση: Όλες οι εντολές : πρέπει να τερματίζονται πατώντας το . + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 5.2: ΠΕΡΙΣΣΟΤΕΡΑ ΠΕΡΙ ΕΓΓΡΑΦΗΣ ΑΡΧΕΙΩΝ + + + ** Για να σώσετε τις αλλάγες που κάνατε στο αρχείο, γράψτε :w ΑΡΧΕΙΟ. ** + + 1. Γράψτε :!dir ή :!ls για να πάρετε μία λίστα του καταλόγου σας. + Ήδη ξέρετε ότι πρέπει να πατήσετε μετά από αυτό. + + 2. Διαλέξτε ένα όνομα αρχείου που δεν υπάρχει ακόμα, όπως το TEST. + + 3. Τώρα γράψτε: :w TEST (όπου TEST είναι το όνομα αρχείου που διαλέξατε). + + 4. Αυτό σώζει όλο το αρχείο (vim Tutor) με το όνομα TEST. Για να το + επαληθεύσετε, γράψτε ξανά :!dir για να δείτε τον κατάλογό σας. + +---> Σημειώστε ότι αν βγαίνατε από τον Vim και μπαίνατε ξανά με το όνομα + αρχείου TEST, το αρχείο θα ήταν ακριβές αντίγραφο του tutor όταν το σώσατε. + + 5. Τώρα διαγράψτε το αρχείο γράφοντας (MS-DOS): :!del TEST + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 5.3: ΕΠΙΛΕΚΤΙΚΗ ΕΝΤΟΛΗ ΕΓΓΡΑΦΗΣ + + + ** Για να σώσετε τμήμα του αρχείου, γράψτε :#,# w ΑΡΧΕΙΟ ** + + 1. Άλλη μια φορά, γράψτε :!dir ή :!ls για να πάρετε μία λίστα από τον + κατάλογό σας και διαλέξτε ένα κατάλληλο όνομα αρχείου όπως το TEST. + + 2. Μετακινείστε τον δρομέα στο πάνω μέρος αυτής της σελίδας και πατήστε + Ctrl-g για να βρείτε τον αριθμό αυτής της γραμμής. + ΝΑ ΘΥΜΑΣΤΕ ΑΥΤΟΝ ΤΟΝ ΑΡΙΘΜΟ! + + 3. Τώρα πηγαίνετε στο κάτω μέρος της σελίδας και πατήστε Ctrl-g ξανά. + ΝΑ ΘΥΜΑΣΤΕ ΚΑΙ ΑΥΤΟΝ ΤΟΝ ΑΡΙΘΜΟ! + + 4. Για να σώσετε ΜΟΝΟ ένα τμήμα σε αρχείο, γράψτε :#,# w TEST + όπου #,# οι δύο αριθμοί που απομνημονεύσατε (πάνω,κάτω) και TEST το + όνομα του αρχείου σας. + + 5. Ξανά, δείτε ότι το αρχείο είναι εκεί με την :!dir αλλά ΜΗΝ το διαγράψετε. + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 5.4: ΑΝΑΚΤΩΝΤΑΣ ΚΑΙ ΕΝΩΝΟΝΤΑΣ ΑΡΧΕΙΑ + + + ** Για να εισάγετε τα περιεχόμενα ενός αρχείου, γράψτε :r ΑΡΧΕΙΟ ** + + 1. Γράψτε :!dir για να βεβαιωθείτε ότι το TEST υπάρχει από πριν. + + 2. Τοποθετήστε τον δρομέα στο πάνω μέρος της σελίδας. + +ΣΗΜΕΙΩΣΗ: Αφότου εκτελέσετε το Βήμα 3 θα δείτε το Μάθημα 5.3. + Μετά κινηθείτε ΚΑΤΩ ξανά προς το μάθημα αυτό. + + 3. Τώρα ανακτήστε το αρχείο σας TEST χρησιμοποιώντας την εντολή :r TEST + όπου TEST είναι το όνομα του αρχείου. + +ΣΗΜΕΙΩΣΗ: Το αρχείο που ανακτάτε τοποθετείται ξεκινώντας εκεί που βρίσκεται + ο δρομέας. + + 4. Για να επαληθεύσετε ότι το αρχείο ανακτήθηκε, πίσω τον δρομέα και + παρατηρήστε ότι υπάρχουν τώρα δύο αντίγραφα του Μαθήματος 5.3, το + αρχικό και η έκδοση του αρχείου. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ΜΑΘΗΜΑ 5 ΠΕΡΙΛΗΨΗ + + + 1. :!εντολή εκτελεί μία εξωτερική εντολή. + + Μερικά χρήσιμα παραδείγματα είναι (MS-DOS): + :!dir - εμφάνιση λίστας ενός καταλόγου. + :!del ΑΡΧΕΙΟ - διαγράφει το ΑΡΧΕΙΟ. + + 2. :w ΑΡΧΕΙΟ γράφει το τρέχων αρχείο του Vim στο δίσκο με όνομα ΑΡΧΕΙΟ. + + 3. :#,#w ΑΡΧΕΙΟ σώζει τις γραμμές από # μέχρι # στο ΑΡΧΕΙΟ. + + 4. :r ΑΡΧΕΙΟ ανακτεί το αρχείο δίσκου ΑΡΧΕΙΟ και το παρεμβάλλει μέσα + στο τρέχον αρχείο μετά από τη θέση του δρομέα. + + + + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 6.1: Η ΕΝΤΟΛΗ ΑΝΟΙΓΜΑΤΟΣ + + + ** Πατήστε o για να ανοίξετε μία γραμμή κάτω από τον δρομέα και να + βρεθείτε σε Κατάσταση Κειμένου. ** + + 1. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με --->. + + 2. Πατήστε o (πεζό) για να ανοίξετε μία γραμμή ΚΑΤΩ από τον δρομέα και να + βρεθείτε σε Κατάσταση Κειμένου. + + 3. Τώρα αντιγράψτε τη σημειωμένη με ---> γραμμή και πατήστε για να + βγείτε από την Κατάσταση Κειμένου. + +---> After typing o the cursor is placed on the open line in Insert mode. + + 4. Για να ανοίξετε μία γραμμή ΠΑΝΩ από τον δρομέα, πατήστε απλά ένα κεφαλαίο + O, αντί για ένα πεζό o. Δοκιμάστε το στην παρακάτω γραμμή. +Ανοίγετε γραμμή πάνω από αυτήν πατώντας Shift-O όσο ο δρομέας είναι στη γραμμή + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 6.2: Η ΕΝΤΟΛΗ ΠΡΟΣΘΗΚΗΣ + + ** Πατήστε a για να εισάγετε κείμενο ΜΕΤΑ τον δρομέα. ** + + 1. Μετακινείστε τον δρομέα στο τέλος της πρώτης γραμμής παρακάτω + σημειωμένη με ---> πατώντας $ στην Κανονική Κατάσταση. + + 2. Πατήστε ένα a (πεζό) για να προσθέσετε κείμενο ΜΕΤΑ από τον χαρακτήρα + που είναι κάτω από τον δρομέα. (Το κεφαλαίο A προσθέτει στο τέλος + της γραμμής). + +Σημείωση: Αυτό αποφεύγει το πάτημα του i , τον τελευταίο χαρακτήρα, το + κείμενο της εισαγωγής, , δρομέα-δεξιά, και τέλος, x, μόνο και + μόνο για να προσθέσετε στο τέλος της γραμμής! + + 3. Συμπληρώστε τώρα την πρώτη γραμμή. Σημειώστε επίσης ότι η προσθήκη είναι + ακριβώς ίδια στην Κατάσταση Κειμένου με την Κατάσταση Εισαγωγής, εκτός + από τη θέση που εισάγεται το κείμενο. + +---> This line will allow you to practice +---> This line will allow you to practice appending text to the end of a line. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 6.3: ΑΛΛΗ ΕΚΔΟΣΗ ΤΗΣ ΑΝΤΙΚΑΤΑΣΤΑΣΗΣ + + + ** Πατήστε κεφαλαίο R για να αλλάξετε περισσότερους από έναν χαρακτήρες. ** + + 1. Μετακινείστε τον δρομέα στην πρώτη γραμμή παρακάτω σημειωμένη με --->. + + 2. Τοποθετήστε τον δρομέα στην αρχή της πρώτης λέξης που είναι διαφορετική + από τη δεύτερη γραμμή σημειωμένη με ---> (η λέξη 'last'). + + 3. Πατήστε τώρα R και αλλάξτε το υπόλοιπο του κειμένου στην πρώτη γραμμή + γράφοντας πάνω από το παλιό κείμενο ώστε να κάνετε την πρώτη γραμμή ίδια + με τη δεύτερη. + +---> To make the first line the same as the last on this page use the keys. +---> To make the first line the same as the second, type R and the new text. + + 4. Σημειώστε ότι όταν πατάτε για να βγείτε, παραμένει οποιοδήποτε + αναλλοίωτο κείμενο. + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Μάθημα 6.4: ΡΥΘΜΙΣΗ ΕΠΙΛΟΓΗΣ + + + ** Ρυθμίστε μία επιλογή έτσι ώστε η αναζήτηση ή η αντικατάσταση να αγνοεί + τη διαφορά πεζών-κεφαλαίων ** + + 1. Ψάξτε για 'ignore' εισάγοντας: + /ignore + Συνεχίστε αρκετές φορές πατώντας το πλήκτρο n. + + 2. Θέστε την επιλογή 'ic' (Ignore case) γράφοντας: + :set ic + + 3. Ψάξτε τώρα ξανά για 'ignore' πατώντας: n + Συνεχίστε την αναζήτηση μερικές ακόμα φορές πατώντας το πλήκτρο n + + 4. Θέστε τις επιλογές 'hlsearch' και 'incsearch': + :set hls is + + 5. Εισάγετε τώρα ξανά την εντολή αναζήτησης, και δείτε τι συμβαίνει + /ignore + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ΜΑΘΗΜΑ 6 ΠΕΡΙΛΗΨΗ + + + 1. Πατώντας o ανοίγει μία γραμμή ΚΑΤΩ από τον δρομέα και τοποθετεί τον + δρομέα στην ανοιχτή γραμμή σε Κατάσταση Κειμένου. + + 2. Πατήστε a για να εισάγετε κείμενο ΜΕΤΑ τον χαρακτήρα στον οποίο είναι + ο δρομέας. Πατώντας κεφαλαίο A αυτόματα προσθέτει κείμενο στο τέλος + της γραμμής. + + 3. Πατώντας κεφαλαίο R εισέρχεται στην Κατάσταη Αντικατάστασης μέχρι να + πατηθεί το και να εξέλθει. + + 4. Γράφοντας ":set xxx" ρυθμίζει την επιλογή "xxx". + + + + + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ΜΑΘΗΜΑ 7: ON-LINE ΕΝΤΟΛΕΣ ΒΟΗΘΕΙΑΣ + + + ** Χρησιμοποιήστε το on-line σύστημα βοήθειας ** + + Ο Vim έχει ένα περιεκτικό on-line σύστημα βοήθειας. Για να ξεκινήσει, + δοκιμάστε κάποιο από τα τρία: + - πατήστε το πλήκτρο (αν έχετε κάποιο) + - πατήστε το πλήκτρο (αν έχετε κάποιο) + - γράψτε :help + + Γράψτε :q για να κλείσετε το παράθυρο της βοήθειας. + + Μπορείτε να βρείτε βοήθεια πάνω σε κάθε αντικείμενο, δίνοντας μία παράμετρο + στην εντολή ":help". Δοκιμάστε αυτά (μην ξεχνάτε να πατάτε ): + + :help w + :help c_ Клавиша l находится справа и перемещает вправо. + j Клавиша j похожа на стрелку `вниз'. + v + 1. Подвигайте курсор по экрану, пока не почувствуете себя уверенно. + + 2. Надавите клавишу `вниз' (j) пока она не начнет повторяться. +---> Теперь Вы знаете, как перейти к следующему уроку. + + 3. Используя клавишу `вниз' перейдите к Уроку 1.2. + +Замечание: Если вы пока не уверены в том, что набираете, нажмите для + перехода в обычный режим (Normal mode). После этого перенаберите + требуемую команду. + +Замечание: Обычные клавиши управления курсором (стрелки) также должны + работать. Однако, клавиши hjkl позволят Вам перемещаться + значительно быстрее, как только Вы научитесь ими пользоваться. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 1.2: ЗАПУСК И ЗАВЕРШЕНИЕ РАБОТЫ С VIM + +!! ВНИМАНИЕ! Прежде, чем выполнять любой из описанных ниже шагов, прочтите + урок целиком !! + + 1. Нажмите клавишу (для того, чтобы удостовериться, что Вы в обычном + режиме (Normal mode)). + + 2. Наберите: :q! . + +---> Это позволит Вам выйти из редактора БЕЗ СОХРАНЕНИЯ любых сделанных + изменений. Если Вы хотите сохранить изменения и выйти: + :wq + + 3. Когда Вы увидите приглашение командной оболочки, наберите команду, + которая привела Вас в этот учебник. Это может быть + vimtutor ru + Обычно можно использовать: vim tutor.ru + +---> 'vim' позволяет запустить редактор vim, 'tutor.ru' --- это файл, который + Вы будете редактировать. + + 4. Если Вы уверены в том, что запомнили эти шаги, выполните шаги от 1 до 3 + чтобы выйти снова запустить редактор. Затем переместите курсор вниз к + Уроку 1.3. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 1.3: РЕДАКТИРОВАНИЕ ТЕКСТА - УДАЛЕНИЕ + + +** Находясь в обычном режиме нажмите x, чтобы удалить символ под курсором. ** + + 1. Переместите курсор к строке внизу, помеченной --->. + + 2. Для исправления ошибок, переместите курсор, пока он не окажется над + удаляемым символом. + + 3. Нажмите клавишу x для удаления требуемого символа. + + 4. Повторите шаги 2--4 пока строка не будет исправлена. + +---> От тттопота копытт пппыль ппо ппполю леттитт. + + 5. Теперь, когда строка откорректирована, переходите к уроку 1.4. + +ЗАМЕЧАНИЕ: В ходе освоения этого учебника не пытайтесь запоминать, учите + в процессе использования. + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 1.4: РЕДАКТИРОВАНИЕ ТЕКСТА - ВСТАВКА + + + ** Находясь в обычном режиме (Normal mode), нажмите i для вставки текста. ** + + 1. Переместите курсор к первой строке внизу, помеченной --->. + + 2. Для того, чтобы сделать первую строку идентичной второй, поместите + курсор на символ ПЕРЕД которым следует вставить текст. + + 3. Нажмите i и наберите требуемые добавления. + + 4. После исправления всех ошибок нажмите для возврата в обычный режим. + Повторите шаги 2--4, пока фраза не будет исправлена полностью. + +---> Часть текста в строке беследно . +---> Часть текста в этой строке бесследно пропала. + + 5. Когда освоите вставку текста, переходите дальше к Резюме. + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + РЕЗЮМЕ УРОКА 1 + + 1. Курсор перемещается либо клавишами со стрелками, либо клавишами hjkl. + h (влево) j (вниз) k (вверх) l (вправо) + + 2. Для запуска Vim (из приглашения % командной оболочки) наберите: + vim ИМЯ_ФАЙЛА + + 3. Для завершения работы с Vim наберите: + :q! чтобы отказаться от сохранения изменений. + Или наберите: + :wq чтобы сохранить изменения. + + 4. Для удаления символа под курсором в обычном режиме, наберите: x + + 5. Чтобы вставить текст перед курсором в обычном режиме, наберите: + i вводите текст + +ЗАМЕЧАНИЕ: Нажатие переместит Вас в обычный режим (Normal mode) либо + прервет нежелательную и частично завершенную команду. + +Теперь переходим к Уроку 2. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 2.1: КОМАНДЫ УДАЛЕНИЯ + + + ** Наберите dw для удаления участка текста до конца слова. ** + + 1. Нажмите , чтобы перейти в обычный режим. + + 2. Переместите курсор вниз, к строке, помеченной --->. + + 3. Переместите курсор в начало слова, которое следует удалить. + + 4. Наберите dw , чтобы удалить это слово. + +ЗАМЕЧАНИЕ: Во время набора буквы dw появятся в последней строке экрана. Если + Вы что-то наберете неправильно, нажмите и начните сначала. + +---> Несколько слов рафинад в этом предложении автокран излишни. + + 5. Повторите шаги 3 и 4, пока не исправите все ошибки и переходите к + Уроку 2.2. + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 2.2: ДОПОЛНИТЕЛЬНЫЕ КОМАНДЫ УДАЛЕНИЯ + + + ** Наберите d$ для удаления текста до конца строки. ** + + 1. Нажмите , чтобы перейти в обычный режим. + + 2. Переместите курсор вниз, к строке, помеченной --->. + + 3. Переместите курсор к концу правильной строки (ПОСЛЕ первой . ). + + 4. Чтобы удалить остаток строки, наберите d$ . + +---> Кто-то набрал окончание этой строки дважды. окончание этой строки дважды. + + + 5.Чтобы лучше разобраться в этом, переходите к Уроку 2.3. + + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 2.3: КОМАНДЫ И ОБЪЕКТЫ + + + Формат команды `удаление' d таков: + + [число] d объект ИЛИ d [число] объект + Здесь: + число - сколько раз исполнить команду (необязательно, по умолчанию=1). + d - команда удаления. + объект - с чем команда должна быть выполнена (перечислено ниже). + + Краткий список объектов: + w - от курсора до конца слова, включая завершающий пробел. + e - от курсора до конца слова, НЕ включая завершающий пробел. + $ - от курсора до конца строки. + ^ - от курсора до начала строки. + +ЗАМЕЧАНИЕ: Простое нажатие на символ объекта в обычном режиме (Normal mode) + без дополнительных команд передвинет курсор так, как указано в + списке объектов. + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 2.4: ИСКЛЮЧЕНИЕ ИЗ ПРАВИЛА `КОМАНДА-ОБЪЕКТ' + + + ** Наберите dd для удаления всей строки. ** + + Вследствие частого применения операции удаления всей строки, разработчики + Vim решили, что для этого проще всего просто набрать d дважды. + + 1. Переместите курсор вниз, ко второй строке фразы. + 2. Наберите dd для удаления строки. + 3. Теперь переместитесь к четвертой строке. + 4. Наберите 2dd (вспомните правило `число-команда-объект'), чтобы удалить + две строки. + + 1) Летом я хожу на стадион, + 2) О, как внезапно кончился диван! + 3) Я болею за ``Зенит'', ``Зенит'' --- чемпион! + 4) Печально я гляжу на наше поколение! + 5) Его грядущее иль пусто иль темно... + 6) Я сижу на скамейке в ложе `Б' + 7) И играю на большой жестяной трубе. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 2.5: КОМАНДА `ОТКАТ' + + + ** Нажмите u для отмены результата работы предыдущей команды, U для отмены + исправлений во всей строке. ** + + 1. Переместите курсор вниз, к строке, помеченной ---> и установите его на + первую ошибку. + 2. Нажмите x для удаления первого неправильного символа. + 3. Теперь нажмите u для отмены (отката) последней выполненной команды. + 4. Исправьте все ошибки в строке, используя команду x . + 5. Теперь нажмите заглавную U для того, чтобы вернуть всю строку в исходное + состояние. + 6. Нажмите u несколько раз для отмены команды U и предыдущих команд. + 7. Нажмите теперь CTRL-R (удерживайте клавишу CTRL нажатой в момент нажатия + R) несколько раз для возврата команд (откат отката). + +---> Испрравьте оошибки в этойй строке и вернитте их сс помощьью `отката'. + + 8. Это были очень полезные команды. Далее переходите к Резюме Урока 2. + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + РЕЗЮМЕ УРОКА 2 + + + 1. Для удаления текста от курсора до конца слова наберите: dw + + 2. Для удаления текста от курсора до конца строки наберите: d$ + + 3. Для удаления всей строки наберите: dd + + 4. Формат команды в обычном режиме имеет вид: + + [число] команда объект ИЛИ команда [число] объект + где: + число - сколько раз повторить выполнение команды + команда - что выполнить, например d для удаления + объект - на что должна воздействовать команда, например w (слово), + $ (до конца строки), и т.д. + + 5. Для отмены (отката) предшествующих действий наберите: u (строчная u) + Для отмены (отката) всех изменений в строке наберите: U (прописная U) + Для отмены отката наберите: CTRL-R + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 3.1: КОМАНДА ВСТАВКИ + + + ** Наберите p для вставки последнего удаленного текста после курсора. ** + + 1. Переместите курсор вниз к последней строке из набора. + + 2. Наберите dd для удаления строки и ее сохранения в буфере Vim'а. + + 3. Переместите курсор к строке НАД тем местом, куда следует вставить + удаленную строку. + + 4. Находясь в обычном режиме наберите p для замены строки. + + 5. Повторите шаги 2--4, пока не расставите все строки в нужном порядке. + + г) И лучше выдумать не мог. + б) Когда не в шутку занемог, + в) Он уважать себя заставил + а) Мой дядя самых честных правил + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 3.2: КОМАНДА ЗАМЕНЫ + + + ** Наберите r и символ, заменяющий символ под курсором. ** + + 1. Переместите курсор вниз, к строке, помеченной --->. + + 2. Установите курсор так, чтобы он находился над первой ошибкой. + + 3. Наберите r и затем символ, исправляющий ошибку. + + 4. Повторите шаги 2 и 3, пока первая строка не будет исправлена. + +---> В момегт набтра этой чтроки кое0кто с трудом попвдал по клваишам! +---> В момент набора этой строки кое-кто с трудом попадал по клавишам! + + 5. Теперь переходите к Уроку 3.2. + +ЗАМЕЧАНИЕ: Помните, что вы должны учиться в процессе работы, а не просто + запоминая. + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 3.3: КОМАНДА ИЗМЕНЕНИЯ + + + ** Для изменения части слова наберите cw . ** + + 1. Переместите курсор вниз, к строке, помеченной --->. + + 2. Расположите курсор над буквой `o' в слове `сола'. + + 3. Наберите cw и исправьте слово (в данном случае, наберите `лов'.) + + 4. Нажмите и переходите к следующей ошибке (к первому символу, который + надо изменить.) + + 5. Повторите шаги 3--4 пока первое предложение не станет идентичным второму. + +---> Несколько сола в эьгц строке тпгшцбь редалзкуюиесвх. +---> Несколько слов в этой строке требуют редактирования. + +Обратите внимание, что cw не только заменяет слово, но и переводит вас в режим +вставки. + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 3.4: ПРОДОЛЖАЕМ ИЗМЕНЯТЬ С КОМАНДОЙ c + + +** Команда замены используется с теми же объектами, что и команда удаления. ** + + 1. Команда изменения применяется таким же образом, как и команда удаления. + Ее формат таков: + + [число] c объект ИЛИ c [число] объект + + 2. Объекты также совпадают: w (слово), $ (конец строки) и т.п. + + 3. Переместите курсор вниз, к строке, помеченной --->. + + 4. Перейдите к первой ошибке. + + 5. Наберите c$ и отредактируйте первую строку так, чтобы она совпадала со + второй, после чего нажмите . + +---> Конец этой строки нуждается в помощи, чтобы стать похожим на второй. +---> Конец этой строки нуждается в помощи команды c$ . + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + РЕЗЮМЕ УРОКА 3 + + + 1. Для вставки текста, который только что был удален, наберите p . Эта + команда вставит удаленный текст ПОСЛЕ курсора (если была удалена строка, + то она будет помещена в строке под курсором). + + 2. Для замены символа под курсором наберите r и затем заменяющий символ. + + 3. Команда изменения позволяет Вам изменить указанный объект от курсора до + конца этого объекта. Например, наберите cw для замены от курсора до + конца слова, c$ для изменения до конца строки. + + 4. Формат команды изменения таков: + + [число] c объект ИЛИ c [число] объект + +Теперь отправляйтесь к следующему уроку. + + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 4.1: ИНФОРМАЦИЯ О ФАЙЛЕ И РАСПОЛОЖЕНИЕ В НЕМ + + + ** Наберите CTRL-g чтобы увидеть Ваше месторасположение в файле и информацию + о нем. + Наберите SHIFT-G для перемещения к заданной строке в файле. ** + + Замечание: Прочитайте весь урок прежде чем выполнять любые команды!! + + 1. Удерживая клавишу Ctrl нажмите g . Внизу экрана появится строка статуса с + именем файла и номером строки, в которой Вы находитесь. Запомните номер + строки, он потребуется на Шаге 3. + + 2. Нажмите shift-G для перемещения к концу файла. + + 3. Наберите номер строки, в которой вы находились и затем shift-G. Это + вернет Вас к строке, в которой Вы были, когда в первый раз нажали Ctrl-g. + (Когда Вы будете набирать цифры, они НЕ отобразятся на экране.) + + 4. Если Вы запомнили все вышесказанное, выполните шаги 1--3. + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 4.2: КОМАНДА ПОИСКА + + ** Наберите / и затем введите искомую фразу. ** + + 1. В обычном режиме (Normal mode) наберите символ / . Обратите внимание, + что он вместе с курсором появится внизу экрана, как это происходит с + командой : . + + 2. Теперь наберите 'ошшшибка' . Это то слово, которое Вы будете + искать. + + 3. Для того, чтобы повторить поиск, просто нажмите n . + Для поиска этой фразы в обратном направлении, нажмите Shift-N . + + 4. Если Вы желаете сразу искать в обратном направлении, используйте + команду ? вместо / . + +---> Когда Вы при поиске достигнете конца файла, поиск будет продолжен с + начала. + + "ошшшибка" это не способ произнесения слова `ошибка'; ошшшибка это ошибка. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 4.3: ПОИСК ПАРНЫХ СКОБОК + + + ** Наберите % для поиска парных ),] или } . ** + + 1. Поместите курсор над любой из (, [ или { в строке внизу, помеченной --->. + + 2. Теперь наберите символ % . + + 3. Курсор должен перескочить на парную скобку. + + 4. Наберите % для возврата курсора назад к первой скобке. + +---> Это ( строка, содержащая такие (, такие [ ] и такие { } скобки. )) + +Замечание: Это очень удобно при отладке программ с пропущенными скобками! + + + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 4.4: СПОСОБ ИСПРАВЛЕНИЯ ОШИБОК + + + ** Наберите :s/было/стало/g для замены 'было' на 'стало'. ** + + 1. Переместите курсор вниз, к строке, помеченной --->. + + 2. Наберите :s/уводю/увожу . Обратите внимание на то, что эта команда + заменит только первое найденное вхождение в строке. + + 3. Теперь наберите :s/уводю/увожу/g , означающее подстановку глобально во + всей строке. Это заменит все найденные в строке вхождения. + +---> Я уводю к отверженным селеньям, я уводю сквозь вековечный стон, я уводю к + забытым поколеньям. + + 4. Для замены всех вхождений последовательности символов между двумя + строками, + наберите :#,#s/было/стало/g где #,# --- номера этих строк. + Наберите :%s/было/стало/g для замены всех вхождений во всем файле. + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + РЕЗЮМЕ УРОКА 4 + 1. Ctrl-g показывает ваше положение в файле и информацию о нем. + Shift-G перемещает Вас в конец файла. Номер, за которым следует Shift-G + позволяет перейти к строке с этим номером. + + 2. Нажатие / и затем ввод строки позволяет произвести поиск этой строки + ВПЕРЕД по тексту. + Нажатие ? и затем ввод строки позволяет произвести поиск этой строки + НАЗАД по тексту. + После поиска наберите n для перехода к следующему вхождению искомой + строки в том же направлении или Shift-N для перехода в противоположном + направлении. + + 3. Нажатие % , когда курсор находится на (,),[,],{, или } позволяет найти + парную скобку. + + 4. Для подстановки `стало' вместо первого `было' в строке, наберите + :s/old/new + Для подстановки `стало' вместо всех `было' в строке, наберите + :s/old/new/g + Для замены в интервале между двумя строками, наберите + :#,#s/old/new/g + Для замены всех вхождений `было' на `стало' в файле, наберите + :%s/old/new/g + Чтобы редактор каждый раз запрашивал подтверждение, добавьте 'c' + :%s/old/new/gc +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 5.1: КАК ВЫПОЛНИТЬ ВНЕШНЮЮ КОМАНДУ + + + ** Наберите :! и затем внешнюю команду, которую следует выполнить. ** + + 1. Наберите уже знакомую Вам команду : для установки курсора в командную + строку редактора. Это позволит Вам ввести команду. + + 2. Теперь наберите символ ! (восклицательный знак). Теперь можно исполнить + внешнюю команду, используя командную оболочку. + + 3. Для примера наберите ls после ! и нажмите . Эта команда выведет + список файлов в текущем каталоге, точно также, как если бы Вы ввели эту + команду в приглашении оболочки. Или попробуйте :!dir , если предыдущая + команда не сработала. + +---> Замечание: Таким способом можно выполнить любую внешнюю команду. + +---> Замечание: Все команды, начинающиеся с : , должны завершаться нажатием + . + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 5.2: КАК ЗАПИСАТЬ ФАЙЛ + + +** Для сохранения изменений, произведенных в файле, наберите :w ИМЯ_ФАЙЛА. ** + + 1. Наберите :!dir или :!ls для получения списка файлов в текущем каталоге. + Как Вам уже известно, Вы должны нажать после ввода этих команд. + + 2. Придумайте название для файла, которое еще не существует, например TEST. + + 3. Теперь наберите :w TEST (где TEST --- это имя файла, придуманное Вами.) + + 4. Эта команда сохранит весь файл (Учебник по Vim) под именем TEST. Чтобы + удостовериться в этом, снова наберите :!dir и просмотрите каталог. + +---> Заметьте, что если Вы выйдете из Vim и затем запустите его снова с + файлом TEST, этот файл будет точной копией учебника в тот момент, когда + Вы его сохранили. + + 5. Теперь удалите этот файл, набрав :!del TEST + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 5.3: ВЫБОРОЧНОЕ СОХРАНЕНИЕ + + + ** Для сохранения части файла, наберите :#,# w ИМЯ_ФАЙЛА ** + + 1. Еще раз наберите :!dir или :!ls для получения списка файлов в текущем + каталоге и выберите подходящее имя, например TEST. + + 2. Переместите курсор к началу этой страницы и нажмите Ctrl-g для нахождения + номера строкиto. ЗАПОМНИТЕ ЭТОТ НОМЕР! + + 3. Теперь переместитесь в конец страницы и вновь наберите Ctrl-g. ЗАПОМНИТЕ + И ЭТОТ НОМЕР ТОЖЕ! + + 4. Для сохранения ТОЛЬКО ЧАСТИ файла наберите :#,# w TEST , где #,# --- это + номера, которые Вы запомнили (начало, конец), а TEST --- имя вашего файла. + + 5. Как и прежде, убедитесь в наличии этого файла командой :!dir , но НЕ + УДАЛЯЙТЕ его. + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 5.4: ЧТЕНИЕ И ОБЪЕДИНЕНИЕ ФАЙЛОВ + + ** Для вставки содержимого файла, наберите :r FILENAME ** + + 1. Наберите :!dir для того, чтобы убедиться в том, что файл TEST все еще + существует. + + 2. Установите курсор в верхней части этой страницы. + +Замечание: После выполнения шага 3 Вы увидите Урок 5.3. После этого + перемещайтесь ВНИЗ, снова к этому уроку. + + 3. Теперь прочитайте Ваш файл TEST, используя команду :r TEST , где + TEST --- это имя файла. + +Замечание: Прочитанный Вами файл будет вставлен в том месте, где находится + курсор. + + 4. Чтобы убедиться в том, что файл прочитан, переместитесь немного назад по + тексту и заметьте, что теперь существуют две копии Урока 5.3, исходная + и полученная из файла. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + РЕЗЮМЕ УРОКА 5 + + + 1. :!команда исполняет внешнюю команду. + + Некоторые полезные примеры: + :!dir --- выводит список файлов в каталоге. + :!del FILENAME --- удаляет файл FILENAME. + + 2. :w FILENAME записывает текущий редактируемый файл на диск + под именем FILENAME. + + 3. :#,#w FILENAME сохраняет строки от # до # в файл FILENAME. + + 4. :r FILENAME считывает с диска файл FILENAME и помещает его в текущий + файл следом за позицией курсора. + + + + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 6.1: КОМАНДА СОЗДАНИЯ + + + ** Наберите o чтобы создать пустую строку под курсором и перейти в режим + вставки (Insert mode) ** + + 1. Переместите курсор вниз, к строке, помеченной --->. + + 2. Наберите o (в нижнем регистре) для того, чтобы создать пустую строку + НИЖЕ курсора и перейти в режим вставки (Insert mode). + + 3. Теперь скопируйте помеченную ---> строку и нажмите для выхода из + режима вставки. + +---> После нажатия o курсор перейдет на новую пустую строку в режиме вставки. + + 4. Для создания строки ВЫШЕ курсора, просто наберите заглавную O, вместо + строчной o. Попробуйте проделать это с нижеследующей строкой. +Создайте новую строку над этой, нажав Shift-O, поместив курсор на эту строку. + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 6.2: КОМАНДА ДОБАВЛЕНИЯ + + ** Наберите a , чтобы вставить текст ПОСЛЕ курсора. ** + + 1. Переместите курсор вниз, в конец первой строки, помеченной ---> , + набрав $ в обычном режиме (Normal mode). + + 2. Наберите a (в нижнем регистре) для добавления текста ПОСЛЕ символа, + находящегося под курсором. (Заглавная A позволяет добавить в конец + строки.) + +Замечание: Это позволяет избежать нажатия i , последнего символа, текста для + вставки, , курсор-вправо, и, наконец, x , просто для того, + чтобы добавить тест в конец строки! + + 3. Теперь завершите первую строку. Заметьте также, что добавление это в + точности то же самое, что и режим вставки, за исключением позиции, в + которую будет вставлен текст. + +---> Эта строчка позволит Вам попрактиковаться +---> Эта строчка позволит Вам попрактиковаться в добавлении текста в конец + строки. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 6.3: ЕЩЕ ОДИН СПОСОБ ЗАМЕНЫ + + + ** Наберите заглавную R для замены более, чем одного символа. ** + + 1. Переместите курсор вниз, к строке, помеченной --->. + + 2. Расположите курсор в начале первого слова, отличающегося от + соответствующего в следующей строке, помеченной ---> (слово 'последней'). + + 3. Теперь наберите R и замените остаток текста в первой строке, набрав + поверх старого текста так, чтобы обе строки стали одинаковыми. + +---> Первую строку можно сравнять с последней, используя клавиши. +---> Первую строку можно сравнять с второй, используя R и набрав новый текст. + + 4. Обратите внимание, что при нажатии для завершения, любой + не измененный текст сохранится. + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 6.4: УСТАНОВКА ПАРАМЕТРОВ + + +** Установим параметры так, чтобы игнорировать регистр при поиске или замене ** + + + 1. Поищите слово 'игнорировать', набрав: + /игнорировать + Повторите поиск несколько раз, нажимая клавишу n + + 2. Включите параметр 'ic' (Игнорировать регистр), набрав: + :set ic + + 3. Теперь снова сделайте поиск слова 'игнорировать', нажав: n + Повторите поиск несколько раз, нажимая клавишу n + + 4. Включите параметры 'hlsearch' и 'incsearch': + :set hls is + + 5. Теперь опять введите команду поиска и посмотрите, что получится: + /игнорировать + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + РЕЗЮМЕ УРОКА 6 + + + 1. Нажатие o создает строку НИЖЕ курсора и перемещает курсор в нее в режиме + вставки. + Нажатие заглавной O создает строку ВЫШЕ строки, в которой находится + курсор. + + 2. Наберите a для вставки текста ПОСЛЕ символа, на котором находится курсор. + Нажатие заглавной A автоматически перемещает Вас для добавления текста + в конец строки. + + 3. Нажатие заглавной R переводит Вас в режим замены до тех пор, пока не + будет нажата клавиша для завершения. + + 4. Набрав ":set xxx" вы сможете включить параметр "xxx" + + + + + + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Урок 7: КОМАНДЫ ПОЛУЧЕНИЯ ВСТРОЕННОЙ СПРАВКИ + + ** Используйте встроенную справочную систему ** + + Vim обладает мощной встроенной справочной системой. Для начала попробуйте + один из трех вариантов: + - нажмите клавишу (если таковая имеется на клавиатуре) + - нажмите клавишу (если таковая имеется на клавиатуре) + - наберите :help + + Наберите :q чтобы закрыть окно справки. + + Вы можете найти справку для любого понятия или команды, просто задав + соответствующий аргумент команде ":help". Попробуйте следующее (не забудьте + нажать ): + + :help w + :help c_, 2002. + Translator: Andrey Kiselev , 2002. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff -Naur vim70.orig/runtime/tutor/tutor.vim vim70/runtime/tutor/tutor.vim --- vim70.orig/runtime/tutor/tutor.vim 2006-03-18 12:20:36.000000000 -0800 +++ vim70/runtime/tutor/tutor.vim 2006-12-05 19:58:01.000000000 -0800 @@ -1,6 +1,6 @@ " Vim tutor support file " Author: Eduardo F. Amatria -" Last Change: 2006 Mar 18 +" Last Change: 2006 Sep 09 " This small source file is used for detecting if a translation of the " tutor file exist, i.e., a tutor.xx file, where xx is the language. @@ -93,9 +93,16 @@ endif endif -" The Greek tutor is available in two encodings, guess which one to use -if s:ext =~? '\.gr' && &enc =~ 737 - let s:ext = ".gr.cp737" +" The Greek tutor is available in three encodings, guess what to use. +" We used ".gr" (Greece) instead of ".el" (Greek); accept both. +if s:ext =~? '\.gr\|\.el' + if &enc == "iso-8859-7" + let s:ext = ".gr" + elseif &enc == "utf-8" + let s:ext = ".gr.utf-8" + elseif &enc =~ 737 + let s:ext = ".gr.cp737" + endif endif " The Slovak tutor is available in two encodings, guess which one to use @@ -103,11 +110,15 @@ let s:ext = ".sk.cp1250" endif -" The Russian tutor is available in two encodings, guess which one to use. -" This segment is from the above lines and modified by -" Alexey I. Froloff for Russian vim tutorial -if s:ext =~? '\.ru' && &enc =~ 1251 - let s:ext = ".ru.cp1251" +" The Russian tutor is available in three encodings, guess which one to use. +if s:ext =~? '\.ru' + if &enc == 'utf-8' + let s:ext = '.ru.utf-8' + elseif &enc =~ '1251' + let s:ext = '.ru.cp1251' + elseif &enc =~ 'koi8' + let s:ext = '.ru' + endif endif " Somehow ".ge" (Germany) is sometimes used for ".de" (Deutsch). diff -Naur vim70.orig/src/auto/configure vim70/src/auto/configure --- vim70.orig/src/auto/configure 2006-05-04 03:46:19.000000000 -0700 +++ vim70/src/auto/configure 2006-12-05 19:58:07.000000000 -0800 @@ -4014,7 +4014,7 @@ LDFLAGS=$ldflags_save if test $perl_ok = yes; then if test "X$perlcppflags" != "X"; then - PERL_CFLAGS="$perlcppflags" + PERL_CFLAGS=`echo "$perlcppflags" | sed 's/-pipe //'` fi if test "X$perlldflags" != "X"; then LDFLAGS="$perlldflags $LDFLAGS" @@ -4256,7 +4256,7 @@ echo $ECHO_N "checking if -pthread should be used... $ECHO_C" >&6 threadsafe_flag= thread_lib= - if test "x$MACOSX" != "xyes"; then + if test "`(uname) 2>/dev/null`" != Darwin; then test "$GCC" = yes && threadsafe_flag="-pthread" if test "`(uname) 2>/dev/null`" = FreeBSD; then threadsafe_flag="-D_THREAD_SAFE" @@ -11555,8 +11555,8 @@ else echo "$as_me:$LINENO: result: empty: automatic terminal library selection" >&5 echo "${ECHO_T}empty: automatic terminal library selection" >&6 - case "`uname -s 2>/dev/null`" in - OSF1) tlibs="ncurses curses termlib termcap";; + case "`uname -s 2>/dev/null`" in + OSF1|SCO_SV) tlibs="ncurses curses termlib termcap";; *) tlibs="ncurses termlib termcap curses";; esac for libname in $tlibs; do @@ -15302,7 +15302,7 @@ && test "x$GUITYPE" != "xCARBONGUI"; then echo "$as_me:$LINENO: checking whether we need -framework Carbon" >&5 echo $ECHO_N "checking whether we need -framework Carbon... $ECHO_C" >&6 - if test "x$enable_multibyte" = "xyes" || test "x$features" == "xbig" \ + if test "x$enable_multibyte" = "xyes" || test "x$features" = "xbig" \ || test "x$features" = "xhuge"; then LIBS="$LIBS -framework Carbon" echo "$as_me:$LINENO: result: yes" >&5 diff -Naur vim70.orig/src/buffer.c vim70/src/buffer.c --- vim70.orig/src/buffer.c 2006-04-26 14:37:23.000000000 -0700 +++ vim70/src/buffer.c 2006-12-05 19:58:11.000000000 -0800 @@ -434,12 +434,8 @@ if (usingNetbeans) netbeans_file_closed(buf); #endif -#ifdef FEAT_AUTOCHDIR - /* Change directories when the acd option is set on. */ - if (p_acd && curbuf->b_ffname != NULL - && vim_chdirfile(curbuf->b_ffname) == OK) - shorten_fnames(TRUE); -#endif + /* Change directories when the 'acd' option is set. */ + DO_AUTOCHDIR /* * Remove the buffer from the list. @@ -1212,11 +1208,11 @@ { # ifdef FEAT_WINDOWS /* jump to first window containing buf if one exists ("useopen") */ - if (vim_strchr(p_swb, 'o') && buf_jump_open_win(buf)) + if (vim_strchr(p_swb, 'o') != NULL && buf_jump_open_win(buf)) return OK; /* jump to first window in any tab page containing buf if one exists * ("usetab") */ - if (vim_strchr(p_swb, 'a') && buf_jump_open_tab(buf)) + if (vim_strchr(p_swb, 'a') != NULL && buf_jump_open_tab(buf)) return OK; if (win_split(0, 0) == FAIL) # endif @@ -1390,7 +1386,8 @@ } else { - need_fileinfo = TRUE; /* display file info after redraw */ + if (!msg_silent) + need_fileinfo = TRUE; /* display file info after redraw */ (void)buf_check_timestamp(curbuf, FALSE); /* check if file changed */ #ifdef FEAT_AUTOCMD curwin->w_topline = 1; @@ -1422,12 +1419,8 @@ netbeans_file_activated(curbuf); #endif -#ifdef FEAT_AUTOCHDIR - /* Change directories when the acd option is set on. */ - if (p_acd && curbuf->b_ffname != NULL - && vim_chdirfile(curbuf->b_ffname) == OK) - shorten_fnames(TRUE); -#endif + /* Change directories when the 'acd' option is set. */ + DO_AUTOCHDIR #ifdef FEAT_KEYMAP if (curbuf->b_kmap_state & KEYMAP_INIT) @@ -1436,6 +1429,18 @@ redraw_later(NOT_VALID); } +#if defined(FEAT_AUTOCHDIR) || defined(PROTO) +/* + * Change to the directory of the current buffer. + */ + void +do_autochdir() +{ + if (curbuf->b_ffname != NULL && vim_chdirfile(curbuf->b_ffname) == OK) + shorten_fnames(TRUE); +} +#endif + /* * functions for dealing with the buffer list */ @@ -1837,13 +1842,13 @@ if (options & GETF_SWITCH) { /* use existing open window for buffer if wanted */ - if (vim_strchr(p_swb, 'o')) /* useopen */ + if (vim_strchr(p_swb, 'o') != NULL) /* useopen */ wp = buf_jump_open_win(buf); /* use existing open window in any tab page for buffer if wanted */ - if (vim_strchr(p_swb, 'a')) /* usetab */ + if (vim_strchr(p_swb, 'a') != NULL) /* usetab */ wp = buf_jump_open_tab(buf); /* split window if wanted ("split") */ - if (wp == NULL && vim_strchr(p_swb, 't') && !bufempty()) + if (wp == NULL && vim_strchr(p_swb, 'l') != NULL && !bufempty()) { if (win_split(0, 0) == FAIL) return FAIL; @@ -3324,7 +3329,7 @@ { usefmt = eval_to_string_safe(fmt + 2, NULL, use_sandbox); if (usefmt == NULL) - usefmt = (char_u *)""; + usefmt = fmt; } #endif @@ -4215,7 +4220,7 @@ /* Use the name from the associated buffer if it exists. */ bp = buflist_findnr(aep->ae_fnum); - if (bp == NULL) + if (bp == NULL || bp->b_fname == NULL) return aep->ae_fname; return bp->b_fname; } @@ -5420,11 +5425,7 @@ buf_T *newbuf; int differ = TRUE; linenr_T lnum; -#ifdef FEAT_AUTOCMD aco_save_T aco; -#else - buf_T *old_curbuf = curbuf; -#endif exarg_T ea; /* Allocate a buffer without putting it in the buffer list. */ @@ -5439,13 +5440,8 @@ return TRUE; } -#ifdef FEAT_AUTOCMD /* set curwin/curbuf to buf and save a few things */ aucmd_prepbuf(&aco, newbuf); -#else - curbuf = newbuf; - curwin->w_buffer = newbuf; -#endif if (ml_open(curbuf) == OK && readfile(buf->b_ffname, buf->b_fname, @@ -5466,13 +5462,8 @@ } vim_free(ea.cmd); -#ifdef FEAT_AUTOCMD /* restore curwin/curbuf and a few other things */ aucmd_restbuf(&aco); -#else - curbuf = old_curbuf; - curwin->w_buffer = old_curbuf; -#endif if (curbuf != newbuf) /* safety check */ wipe_buffer(newbuf, FALSE); diff -Naur vim70.orig/src/configure vim70/src/configure --- vim70.orig/src/configure 2006-05-07 07:17:49.000000000 -0700 +++ vim70/src/configure 2006-12-05 19:57:51.000000000 -0800 @@ -2,5 +2,9 @@ # run the automatically generated configure script CONFIG_STATUS=auto/config.status \ auto/configure "$@" --srcdir="${srcdir:-.}" --cache-file=auto/config.cache +result=$? + # Stupid autoconf 2.5x causes this file to be left behind. if test -f configure.lineno; then rm -f configure.lineno; fi + +exit $result diff -Naur vim70.orig/src/configure.in vim70/src/configure.in --- vim70.orig/src/configure.in 2006-05-04 03:46:11.000000000 -0700 +++ vim70/src/configure.in 2006-12-05 19:58:07.000000000 -0800 @@ -508,7 +508,8 @@ LDFLAGS=$ldflags_save if test $perl_ok = yes; then if test "X$perlcppflags" != "X"; then - PERL_CFLAGS="$perlcppflags" + dnl remove -pipe, it confuses cproto + PERL_CFLAGS=`echo "$perlcppflags" | sed 's/-pipe //'` fi if test "X$perlldflags" != "X"; then LDFLAGS="$perlldflags $LDFLAGS" @@ -680,7 +681,8 @@ AC_MSG_CHECKING([if -pthread should be used]) threadsafe_flag= thread_lib= - if test "x$MACOSX" != "xyes"; then + dnl if test "x$MACOSX" != "xyes"; then + if test "`(uname) 2>/dev/null`" != Darwin; then test "$GCC" = yes && threadsafe_flag="-pthread" if test "`(uname) 2>/dev/null`" = FreeBSD; then threadsafe_flag="-D_THREAD_SAFE" @@ -2150,8 +2152,9 @@ dnl Newer versions of ncurses are preferred over anything. dnl Older versions of ncurses have bugs, get a new one! dnl Digital Unix (OSF1) should use curses (Ronald Schild). + dnl On SCO Openserver should prefer termlib (Roger Cornelius). case "`uname -s 2>/dev/null`" in - OSF1) tlibs="ncurses curses termlib termcap";; + OSF1|SCO_SV) tlibs="ncurses curses termlib termcap";; *) tlibs="ncurses termlib termcap curses";; esac for libname in $tlibs; do @@ -2835,7 +2838,7 @@ && test "x$GUITYPE" != "xCARBONGUI"; then AC_MSG_CHECKING(whether we need -framework Carbon) dnl check for MACOSX without Carbon GUI, but with FEAT_MBYTE - if test "x$enable_multibyte" = "xyes" || test "x$features" == "xbig" \ + if test "x$enable_multibyte" = "xyes" || test "x$features" = "xbig" \ || test "x$features" = "xhuge"; then LIBS="$LIBS -framework Carbon" AC_MSG_RESULT(yes) diff -Naur vim70.orig/src/edit.c vim70/src/edit.c --- vim70.orig/src/edit.c 2006-05-07 04:48:51.000000000 -0700 +++ vim70/src/edit.c 2006-12-05 19:58:11.000000000 -0800 @@ -129,7 +129,7 @@ static void ins_ctrl_x __ARGS((void)); static int has_compl_option __ARGS((int dict_opt)); -static int ins_compl_add __ARGS((char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int dup)); +static int ins_compl_add __ARGS((char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup)); static int ins_compl_equal __ARGS((compl_T *match, char_u *str, int len)); static void ins_compl_longest_match __ARGS((compl_T *match)); static void ins_compl_add_matches __ARGS((int num_matches, char_u **matches, int icase)); @@ -707,6 +707,11 @@ lastc = c; /* remember previous char for CTRL-D */ c = safe_vgetc(); +#ifdef FEAT_AUTOCMD + /* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */ + did_cursorhold = TRUE; +#endif + #ifdef FEAT_RIGHTLEFT if (p_hkmap && KeyTyped) c = hkmap(c); /* Hebrew mode mapping */ @@ -719,9 +724,14 @@ #ifdef FEAT_INS_EXPAND /* * Special handling of keys while the popup menu is visible or wanted - * and the cursor is still in the completed word. + * and the cursor is still in the completed word. Only when there is + * a match, skip this when no matches were found. */ - if (compl_started && pum_wanted() && curwin->w_cursor.col >= compl_col) + if (compl_started + && pum_wanted() + && curwin->w_cursor.col >= compl_col + && (compl_shown_match == NULL + || compl_shown_match != compl_shown_match->cp_next)) { /* BS: Delete one character from "compl_leader". */ if ((c == K_BS || c == Ctrl_H) @@ -751,7 +761,7 @@ continue; } - /* Pressing CTRL-Y selects the current match. Shen + /* Pressing CTRL-Y selects the current match. When * compl_enter_selects is set the Enter key does the same. */ if (c == Ctrl_Y || (compl_enter_selects && (c == CAR || c == K_KENTER || c == NL))) @@ -877,6 +887,7 @@ /* Close the cmdline window. */ cmdwin_result = K_IGNORE; got_int = FALSE; /* don't stop executing autocommands et al. */ + nomove = TRUE; goto doESCkey; } #endif @@ -912,6 +923,7 @@ if (cmdchar != 'r' && cmdchar != 'v') apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL, FALSE, curbuf); + did_cursorhold = FALSE; #endif return (c == Ctrl_O); } @@ -1383,6 +1395,12 @@ break; } /* end of switch (c) */ +#ifdef FEAT_AUTOCMD + /* If typed something may trigger CursorHoldI again. */ + if (c != K_CURSORHOLD) + did_cursorhold = FALSE; +#endif + /* If the cursor was moved we didn't just insert a space */ if (arrow_used) inserted_space = FALSE; @@ -2112,7 +2130,7 @@ * maybe because alloc() returns NULL, then FAIL is returned. */ static int -ins_compl_add(str, len, icase, fname, cptext, cdir, flags, dup) +ins_compl_add(str, len, icase, fname, cptext, cdir, flags, adup) char_u *str; int len; int icase; @@ -2120,7 +2138,7 @@ char_u **cptext; /* extra text for popup menu or NULL */ int cdir; int flags; - int dup; /* accept duplicate match */ + int adup; /* accept duplicate match */ { compl_T *match; int dir = (cdir == 0 ? compl_direction : cdir); @@ -2134,13 +2152,13 @@ /* * If the same match is already present, don't add it. */ - if (compl_first_match != NULL && !dup) + if (compl_first_match != NULL && !adup) { match = compl_first_match; do { if ( !(match->cp_flags & ORIGINAL_TEXT) - && ins_compl_equal(match, str, len) + && STRNCMP(match->cp_str, str, len) == 0 && match->cp_str[len] == NUL) return NOTDONE; match = match->cp_next; @@ -2399,7 +2417,7 @@ /* compl_pattern doesn't need to be set */ compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length); if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, - -1, FALSE, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) + -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) return; /* Handle like dictionary completion. */ @@ -2409,6 +2427,7 @@ compl_matches = ins_compl_make_cyclic(); compl_started = TRUE; compl_used_match = TRUE; + compl_cont_status = 0; compl_curr_match = compl_first_match; ins_complete(Ctrl_N); @@ -2753,6 +2772,7 @@ } else # endif + if (count > 0) /* avoid warning for using "files" uninit */ { ins_compl_files(count, files, thesaurus, flags, ®match, buf, &dir); @@ -2813,7 +2833,7 @@ ptr = find_word_end(ptr); add_r = ins_compl_add_infercase(regmatch->startp[0], (int)(ptr - regmatch->startp[0]), - FALSE, files[i], *dir, 0); + p_ic, files[i], *dir, 0); if (thesaurus) { char_u *wstart; @@ -2849,7 +2869,7 @@ ptr = find_word_end(ptr); add_r = ins_compl_add_infercase(wstart, (int)(ptr - wstart), - FALSE, files[i], *dir, 0); + p_ic, files[i], *dir, 0); } } if (add_r == OK) @@ -3015,9 +3035,6 @@ if ((int)(p - line) - (int)compl_col <= 0) return K_BS; - /* For redo we need to repeat this backspace. */ - AppendCharToRedobuff(K_BS); - /* Deleted more than what was used to find matches or didn't finish * finding all matches: need to look for matches all over again. */ if (curwin->w_cursor.col <= compl_col + compl_length @@ -3046,7 +3063,6 @@ ins_compl_delete(); ins_bytes(compl_leader + curwin->w_cursor.col - compl_col); compl_used_match = FALSE; - compl_enter_selects = FALSE; if (compl_started) ins_compl_set_original_text(compl_leader); @@ -3076,6 +3092,7 @@ compl_restarting = FALSE; } +#if 0 /* disabled, made CTRL-L, BS and typing char jump to original text. */ if (!compl_used_match) { /* Go to the original text, since none of the matches is inserted. */ @@ -3087,9 +3104,15 @@ compl_curr_match = compl_shown_match; compl_shows_dir = compl_direction; } +#endif + compl_enter_selects = !compl_used_match; /* Show the popup menu with a different set of matches. */ ins_compl_show_pum(); + + /* Don't let Enter select the original text when there is no popup menu. */ + if (compl_match_array == NULL) + compl_enter_selects = FALSE; } /* @@ -3115,10 +3138,6 @@ #endif ins_char(c); - /* For redo we need to count this character so that the number of - * backspaces is correct. */ - AppendCharToRedobuff(c); - /* If we didn't complete finding matches we must search again. */ if (compl_was_interrupted) ins_compl_restart(); @@ -3175,10 +3194,33 @@ char_u *p; int len = curwin->w_cursor.col - compl_col; int c; + compl_T *cp; p = compl_shown_match->cp_str; if ((int)STRLEN(p) <= len) /* the match is too short */ - return; + { + /* When still at the original match use the first entry that matches + * the leader. */ + if (compl_shown_match->cp_flags & ORIGINAL_TEXT) + { + p = NULL; + for (cp = compl_shown_match->cp_next; cp != NULL + && cp != compl_first_match; cp = cp->cp_next) + { + if (compl_leader == NULL + || ins_compl_equal(cp, compl_leader, + (int)STRLEN(compl_leader))) + { + p = cp->cp_str; + break; + } + } + if (p == NULL || (int)STRLEN(p) <= len) + return; + } + else + return; + } p += len; #ifdef FEAT_MBYTE c = mb_ptr2char(p); @@ -3198,7 +3240,6 @@ int c; { char_u *ptr; - int temp; int want_cindent; int retval = FALSE; @@ -3354,6 +3395,7 @@ if (compl_curr_match != NULL || compl_leader != NULL || c == Ctrl_E) { char_u *p; + int temp = 0; /* * If any of the original typed text has been changed, eg when @@ -3369,16 +3411,21 @@ ptr = compl_leader; else ptr = compl_orig_text; - p = compl_orig_text; - for (temp = 0; p[temp] != NUL && p[temp] == ptr[temp]; ++temp) - ; + if (compl_orig_text != NULL) + { + p = compl_orig_text; + for (temp = 0; p[temp] != NUL && p[temp] == ptr[temp]; + ++temp) + ; #ifdef FEAT_MBYTE - if (temp > 0) - temp -= (*mb_head_off)(compl_orig_text, p + temp); + if (temp > 0) + temp -= (*mb_head_off)(compl_orig_text, p + temp); #endif - for (p += temp; *p != NUL; mb_ptr_adv(p)) - AppendCharToRedobuff(K_BS); - AppendToRedobuffLit(ptr + temp, -1); + for (p += temp; *p != NUL; mb_ptr_adv(p)) + AppendCharToRedobuff(K_BS); + } + if (ptr != NULL) + AppendToRedobuffLit(ptr + temp, -1); } #ifdef FEAT_CINDENT @@ -3578,7 +3625,7 @@ { char_u *word; int icase = FALSE; - int dup = FALSE; + int adup = FALSE; char_u *(cptext[CPT_COUNT]); if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) @@ -3595,7 +3642,7 @@ if (get_dict_string(tv->vval.v_dict, (char_u *)"icase", FALSE) != NULL) icase = get_dict_number(tv->vval.v_dict, (char_u *)"icase"); if (get_dict_string(tv->vval.v_dict, (char_u *)"dup", FALSE) != NULL) - dup = get_dict_number(tv->vval.v_dict, (char_u *)"dup"); + adup = get_dict_number(tv->vval.v_dict, (char_u *)"dup"); } else { @@ -3604,7 +3651,7 @@ } if (word == NULL || *word == NUL) return FAIL; - return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, dup); + return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup); } #endif @@ -3796,7 +3843,7 @@ TAG_INS_COMP | (ctrl_x_mode ? TAG_VERBOSE : 0), TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) { - ins_compl_add_matches(num_matches, matches, FALSE); + ins_compl_add_matches(num_matches, matches, p_ic); } p_ic = save_p_ic; break; @@ -3837,7 +3884,7 @@ num_matches = expand_spelling(first_match_pos.lnum, first_match_pos.col, compl_pattern, &matches); if (num_matches > 0) - ins_compl_add_matches(num_matches, matches, FALSE); + ins_compl_add_matches(num_matches, matches, p_ic); #endif break; @@ -3862,6 +3909,8 @@ { int flags = 0; + ++msg_silent; /* Don't want messages for wrapscan. */ + /* ctrl_x_mode == CTRL_X_WHOLE_LINE || word-wise search that * has added a word that was at the beginning of the line */ if ( ctrl_x_mode == CTRL_X_WHOLE_LINE @@ -3873,6 +3922,7 @@ compl_direction, compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, (linenr_T)0); + --msg_silent; if (!compl_started) { /* set "compl_started" even on fail */ @@ -3971,7 +4021,7 @@ continue; } } - if (ins_compl_add_infercase(ptr, len, FALSE, + if (ins_compl_add_infercase(ptr, len, p_ic, ins_buf == curbuf ? NULL : ins_buf->b_sfname, 0, flags) != NOTDONE) { @@ -3996,7 +4046,7 @@ if (got_int) break; /* Fill the popup menu as soon as possible. */ - if (pum_wanted() && type != -1) + if (type != -1) ins_compl_check_keys(0); if ((ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE) @@ -4100,6 +4150,21 @@ && compl_shown_match->cp_next != NULL && compl_shown_match->cp_next != compl_first_match) compl_shown_match = compl_shown_match->cp_next; + + /* If we didn't find it searching forward, and compl_shows_dir is + * backward, find the last match. */ + if (compl_shows_dir == BACKWARD + && !ins_compl_equal(compl_shown_match, + compl_leader, (int)STRLEN(compl_leader)) + && (compl_shown_match->cp_next == NULL + || compl_shown_match->cp_next == compl_first_match)) + { + while (!ins_compl_equal(compl_shown_match, + compl_leader, (int)STRLEN(compl_leader)) + && compl_shown_match->cp_prev != NULL + && compl_shown_match->cp_prev != compl_first_match) + compl_shown_match = compl_shown_match->cp_prev; + } } if (allow_get_expansion && insert_match @@ -4124,8 +4189,6 @@ { if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL) { - if (compl_pending != 0) - --compl_pending; compl_shown_match = compl_shown_match->cp_next; found_end = (compl_first_match != NULL && (compl_shown_match->cp_next == compl_first_match @@ -4134,14 +4197,24 @@ else if (compl_shows_dir == BACKWARD && compl_shown_match->cp_prev != NULL) { - if (compl_pending != 0) - ++compl_pending; found_end = (compl_shown_match == compl_first_match); compl_shown_match = compl_shown_match->cp_prev; found_end |= (compl_shown_match == compl_first_match); } else { + if (!allow_get_expansion) + { + if (advance) + { + if (compl_shows_dir == BACKWARD) + compl_pending -= todo + 1; + else + compl_pending += todo + 1; + } + return -1; + } + if (advance) { if (compl_shows_dir == BACKWARD) @@ -4149,14 +4222,27 @@ else ++compl_pending; } - if (!allow_get_expansion) - return -1; /* Find matches. */ num_matches = ins_compl_get_exp(&compl_startpos); - if (compl_pending != 0 && compl_direction == compl_shows_dir + + /* handle any pending completions */ + while (compl_pending != 0 && compl_direction == compl_shows_dir && advance) - compl_shown_match = compl_curr_match; + { + if (compl_pending > 0 && compl_shown_match->cp_next != NULL) + { + compl_shown_match = compl_shown_match->cp_next; + --compl_pending; + } + if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) + { + compl_shown_match = compl_shown_match->cp_prev; + ++compl_pending; + } + else + break; + } found_end = FALSE; } if ((compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0 @@ -4265,9 +4351,9 @@ return; count = 0; - ++no_mapping; + /* Check for a typed key. Do use mappings, otherwise vim_is_ctrl_x_key() + * can't do its work correctly. */ c = vpeekc_any(); - --no_mapping; if (c != NUL) { if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R) @@ -4277,12 +4363,27 @@ (void)ins_compl_next(FALSE, ins_compl_key2count(c), c != K_UP && c != K_DOWN); } - else if (c != Ctrl_R) - compl_interrupted = TRUE; + else + { + /* Need to get the character to have KeyTyped set. We'll put it + * back with vungetc() below. */ + c = safe_vgetc(); + + /* Don't interrupt completion when the character wasn't typed, + * e.g., when doing @q to replay keys. */ + if (c != Ctrl_R && KeyTyped) + compl_interrupted = TRUE; + + vungetc(c); + } } if (compl_pending != 0 && !got_int) - (void)ins_compl_next(FALSE, compl_pending > 0 - ? compl_pending : -compl_pending, TRUE); + { + int todo = compl_pending > 0 ? compl_pending : -compl_pending; + + compl_pending = 0; + (void)ins_compl_next(FALSE, todo, TRUE); + } } /* @@ -4611,10 +4712,12 @@ (int)STRLEN(compl_pattern), curs_col); if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL || compl_xp.xp_context == EXPAND_NOTHING) - return FAIL; - startcol = (int)(compl_xp.xp_pattern - compl_pattern); - compl_col = startcol; - compl_length = curs_col - startcol; + /* No completion possible, use an empty pattern to get a + * "pattern not found" message. */ + compl_col = curs_col; + else + compl_col = (int)(compl_xp.xp_pattern - compl_pattern); + compl_length = curs_col - compl_col; } else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) { @@ -4668,11 +4771,17 @@ else compl_col = spell_word_start(startcol); if (compl_col >= (colnr_T)startcol) - return FAIL; - spell_expand_check_cap(compl_col); + { + compl_length = 0; + compl_col = curs_col; + } + else + { + spell_expand_check_cap(compl_col); + compl_length = (int)curs_col - compl_col; + } /* Need to obtain "line" again, it may have become invalid. */ line = ml_get(curwin->w_cursor.lnum); - compl_length = (int)curs_col - compl_col; compl_pattern = vim_strnsave(line + compl_col, compl_length); if (compl_pattern == NULL) #endif @@ -4720,7 +4829,7 @@ vim_free(compl_orig_text); compl_orig_text = vim_strnsave(line + compl_col, compl_length); if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, - -1, FALSE, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) + -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) { vim_free(compl_pattern); compl_pattern = NULL; @@ -5227,8 +5336,16 @@ /* Format with 'formatexpr' when it's set. Use internal formatting * when 'formatexpr' isn't set or it returns non-zero. */ #if defined(FEAT_EVAL) - if (*curbuf->b_p_fex == NUL - || fex_format(curwin->w_cursor.lnum, 1L, c) != 0) + int do_internal = TRUE; + + if (*curbuf->b_p_fex != NUL) + { + do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0); + /* It may be required to save for undo again, e.g. when setline() + * was called. */ + ins_need_undo = TRUE; + } + if (do_internal) #endif internal_format(textwidth, second_indent, flags, c == NUL); } @@ -8508,7 +8625,12 @@ tpos = curwin->w_cursor; if (oneleft() == OK) { - start_arrow(&tpos); +#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) + /* Only call start_arrow() when not busy with preediting, it will + * break undo. K_LEFT is inserted in im_correct_cursor(). */ + if (!im_is_preediting()) +#endif + start_arrow(&tpos); #ifdef FEAT_RIGHTLEFT /* If exit reversed string, position is fixed */ if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol) @@ -8700,7 +8822,11 @@ if (mod_mask & MOD_MASK_CTRL) { /* : tab page back */ - goto_tabpage(-1); + if (first_tabpage->tp_next != NULL) + { + start_arrow(&curwin->w_cursor); + goto_tabpage(-1); + } return; } #endif @@ -8759,7 +8885,11 @@ if (mod_mask & MOD_MASK_CTRL) { /* : tab page forward */ - goto_tabpage(0); + if (first_tabpage->tp_next != NULL) + { + start_arrow(&curwin->w_cursor); + goto_tabpage(0); + } return; } #endif @@ -9074,6 +9204,10 @@ #ifdef FEAT_CINDENT can_cindent = TRUE; #endif +#ifdef FEAT_FOLDING + /* When inserting a line the cursor line must never be in a closed fold. */ + foldOpenCursor(); +#endif return (!i); } diff -Naur vim70.orig/src/eval.c vim70/src/eval.c --- vim70.orig/src/eval.c 2006-05-05 10:15:26.000000000 -0700 +++ vim70/src/eval.c 2006-12-05 19:58:24.000000000 -0800 @@ -166,7 +166,6 @@ int uf_tm_count; /* nr of calls */ proftime_T uf_tm_total; /* time spend in function + children */ proftime_T uf_tm_self; /* time spend in function itself */ - proftime_T uf_tm_start; /* time at function call */ proftime_T uf_tm_children; /* time spent in children this call */ /* profiling the function per line */ int *uf_tml_count; /* nr of times line was executed */ @@ -191,8 +190,6 @@ #define FC_RANGE 2 /* function accepts range */ #define FC_DICT 4 /* Dict function, uses "self" */ -#define DEL_REFCOUNT 999999 /* list/dict is being deleted */ - /* * All user-defined functions are found in this hashtable. */ @@ -345,6 +342,9 @@ {VV_NAME("swapchoice", VAR_STRING), 0}, {VV_NAME("swapcommand", VAR_STRING), VV_RO}, {VV_NAME("char", VAR_STRING), VV_RO}, + {VV_NAME("mouse_win", VAR_NUMBER), 0}, + {VV_NAME("mouse_lnum", VAR_NUMBER), 0}, + {VV_NAME("mouse_col", VAR_NUMBER), 0}, }; /* shorthand */ @@ -435,7 +435,7 @@ static void set_ref_in_list __ARGS((list_T *l, int copyID)); static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); static void dict_unref __ARGS((dict_T *d)); -static void dict_free __ARGS((dict_T *d)); +static void dict_free __ARGS((dict_T *d, int recurse)); static dictitem_T *dictitem_alloc __ARGS((char_u *key)); static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); @@ -454,7 +454,7 @@ static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); -static void emsg_funcname __ARGS((char *msg, char_u *name)); +static void emsg_funcname __ARGS((char *ermsg, char_u *name)); static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); @@ -622,6 +622,7 @@ static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv)); static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); @@ -701,6 +702,7 @@ static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); static int var_check_ro __ARGS((int flags, char_u *name)); +static int var_check_fixed __ARGS((int flags, char_u *name)); static int tv_check_lock __ARGS((int lock, char_u *name)); static void copy_tv __ARGS((typval_T *from, typval_T *to)); static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); @@ -2260,7 +2262,7 @@ EMSG(_(e_letunexp)); else { - char_u *tofree = NULL; + char_u *ptofree = NULL; char_u *s; p = get_tv_string_chk(tv); @@ -2269,7 +2271,7 @@ s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); if (s != NULL) { - p = tofree = concat_str(s, p); + p = ptofree = concat_str(s, p); vim_free(s); } } @@ -2278,7 +2280,7 @@ write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); arg_end = arg + 1; } - vim_free(tofree); + vim_free(ptofree); } } @@ -3125,7 +3127,12 @@ funcdict_T fudi; tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); - vim_free(fudi.fd_newkey); + if (fudi.fd_newkey != NULL) + { + /* Still need to give an error message for missing key. */ + EMSG2(_(e_dictkey), fudi.fd_newkey); + vim_free(fudi.fd_newkey); + } if (tofree == NULL) return; @@ -3177,9 +3184,18 @@ failed = TRUE; break; } + + /* Handle a function returning a Funcref, Dictionary or List. */ + if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) + { + failed = TRUE; + break; + } + clear_tv(&rettv); if (doesrange || eap->skip) break; + /* Stop when immediately aborting on error, or when an interrupt * occurred or an exception was thrown but not caught. * get_func_tv() returned OK, so that the check for trailing @@ -3364,6 +3380,8 @@ hi = hash_find(ht, varname); if (!HASHITEM_EMPTY(hi)) { + if (var_check_fixed(HI2DI(hi)->di_flags, name)) + return FAIL; if (var_check_ro(HI2DI(hi)->di_flags, name)) return FAIL; delete_var(ht, hi); @@ -4895,7 +4913,7 @@ { if (list_append_tv(l, &item->li_tv) == FAIL) { - list_free(l); + list_free(l, TRUE); return FAIL; } item = item->li_next; @@ -5295,7 +5313,7 @@ EMSG2(_("E697: Missing end of List ']': %s"), *arg); failret: if (evaluate) - list_free(l); + list_free(l, TRUE); return FAIL; } @@ -5359,8 +5377,8 @@ list_unref(l) list_T *l; { - if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) - list_free(l); + if (l != NULL && --l->lv_refcount <= 0) + list_free(l, TRUE); } /* @@ -5368,14 +5386,12 @@ * Ignores the reference count. */ void -list_free(l) - list_T *l; +list_free(l, recurse) + list_T *l; + int recurse; /* Free Lists and Dictionaries recursively. */ { listitem_T *item; - /* Avoid that recursive reference to the list frees us again. */ - l->lv_refcount = DEL_REFCOUNT; - /* Remove the list from the list of lists for garbage collection. */ if (l->lv_used_prev == NULL) first_list = l->lv_used_next; @@ -5388,7 +5404,10 @@ { /* Remove the item before deleting it. */ l->lv_first = item->li_next; - listitem_free(item); + if (recurse || (item->li_tv.v_type != VAR_LIST + && item->li_tv.v_type != VAR_DICT)) + clear_tv(&item->li_tv); + vim_free(item); } vim_free(l); } @@ -5448,6 +5467,8 @@ { listitem_T *item1, *item2; + if (l1 == l2) + return TRUE; if (list_len(l1) != list_len(l2)) return FALSE; @@ -5484,6 +5505,8 @@ dictitem_T *item2; int todo; + if (d1 == d2) + return TRUE; if (dict_len(d1) != dict_len(d2)) return FALSE; @@ -5516,19 +5539,29 @@ { char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; char_u *s1, *s2; + static int recursive = 0; /* cach recursive loops */ + int r; if (tv1->v_type != tv2->v_type) return FALSE; + /* Catch lists and dicts that have an endless loop by limiting + * recursiveness to 1000. We guess they are equal then. */ + if (recursive >= 1000) + return TRUE; switch (tv1->v_type) { case VAR_LIST: - /* recursive! */ - return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); + ++recursive; + r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); + --recursive; + return r; case VAR_DICT: - /* recursive! */ - return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); + ++recursive; + r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); + --recursive; + return r; case VAR_FUNC: return (tv1->vval.v_string != NULL @@ -6059,6 +6092,10 @@ tabpage_T *tp; #endif + /* Only do this once. */ + want_garbage_collect = FALSE; + may_garbage_collect = FALSE; + /* * 1. Go through all accessible variables and mark all lists and dicts * with copyID. @@ -6097,7 +6134,10 @@ for (dd = first_dict; dd != NULL; ) if (dd->dv_copyID != copyID) { - dict_free(dd); + /* Free the Dictionary and ordinary items it contains, but don't + * recurse into Lists and Dictionaries, they will be in the list + * of dicts or list of lists. */ + dict_free(dd, FALSE); did_free = TRUE; /* restart, next dict may also have been freed */ @@ -6114,7 +6154,10 @@ for (ll = first_list; ll != NULL; ) if (ll->lv_copyID != copyID && ll->lv_watch == NULL) { - list_free(ll); + /* Free the List and ordinary items it contains, but don't recurse + * into Lists and Dictionaries, they will be in the list of dicts + * or list of lists. */ + list_free(ll, FALSE); did_free = TRUE; /* restart, next list may also have been freed */ @@ -6207,11 +6250,12 @@ d = (dict_T *)alloc(sizeof(dict_T)); if (d != NULL) { - /* Add the list to the hashtable for garbage collection. */ + /* Add the list to the list of dicts for garbage collection. */ if (first_dict != NULL) first_dict->dv_used_prev = d; d->dv_used_next = first_dict; d->dv_used_prev = NULL; + first_dict = d; hash_init(&d->dv_hashtab); d->dv_lock = 0; @@ -6229,8 +6273,8 @@ dict_unref(d) dict_T *d; { - if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) - dict_free(d); + if (d != NULL && --d->dv_refcount <= 0) + dict_free(d, TRUE); } /* @@ -6238,16 +6282,14 @@ * Ignores the reference count. */ static void -dict_free(d) - dict_T *d; +dict_free(d, recurse) + dict_T *d; + int recurse; /* Free Lists and Dictionaries recursively. */ { int todo; hashitem_T *hi; dictitem_T *di; - /* Avoid that recursive reference to the dict frees us again. */ - d->dv_refcount = DEL_REFCOUNT; - /* Remove the dict from the list of dicts for garbage collection. */ if (d->dv_used_prev == NULL) first_dict = d->dv_used_next; @@ -6267,7 +6309,10 @@ * something recursive causing trouble. */ di = HI2DI(hi); hash_remove(&d->dv_hashtab, hi); - dictitem_free(di); + if (recurse || (di->di_tv.v_type != VAR_LIST + && di->di_tv.v_type != VAR_DICT)) + clear_tv(&di->di_tv); + vim_free(di); --todo; } } @@ -6718,7 +6763,7 @@ EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); failret: if (evaluate) - dict_free(d); + dict_free(d, TRUE); return FAIL; } @@ -7139,6 +7184,7 @@ {"setreg", 2, 3, f_setreg}, {"settabwinvar", 4, 4, f_settabwinvar}, {"setwinvar", 3, 3, f_setwinvar}, + {"shellescape", 1, 1, f_shellescape}, {"simplify", 1, 1, f_simplify}, {"sort", 1, 2, f_sort}, {"soundfold", 1, 1, f_soundfold}, @@ -7595,8 +7641,8 @@ * Give an error message with a function name. Handle things. */ static void -emsg_funcname(msg, name) - char *msg; +emsg_funcname(ermsg, name) + char *ermsg; char_u *name; { char_u *p; @@ -7605,7 +7651,7 @@ p = concat_str((char_u *)"", name + 3); else p = name; - EMSG2(_(msg), p); + EMSG2(_(ermsg), p); if (p != name) vim_free(p); } @@ -8252,6 +8298,12 @@ EMSG(_("E785: complete() can only be used in Insert mode")); return; } + + /* Check for undo allowed here, because if something was already inserted + * the line was already saved for undo and this check isn't done. */ + if (!undo_allowed()) + return; + if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) { EMSG(_(e_invarg)); @@ -9173,25 +9225,25 @@ typval_T save_key; int rem; int todo; - char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; + char_u *ermsg = map ? (char_u *)"map()" : (char_u *)"filter()"; int save_did_emsg; rettv->vval.v_number = 0; if (argvars[0].v_type == VAR_LIST) { if ((l = argvars[0].vval.v_list) == NULL - || (map && tv_check_lock(l->lv_lock, msg))) + || (map && tv_check_lock(l->lv_lock, ermsg))) return; } else if (argvars[0].v_type == VAR_DICT) { if ((d = argvars[0].vval.v_dict) == NULL - || (map && tv_check_lock(d->dv_lock, msg))) + || (map && tv_check_lock(d->dv_lock, ermsg))) return; } else { - EMSG2(_(e_listdictarg), msg); + EMSG2(_(e_listdictarg), ermsg); return; } @@ -9223,7 +9275,7 @@ { --todo; di = HI2DI(hi); - if (tv_check_lock(di->di_tv.v_lock, msg)) + if (tv_check_lock(di->di_tv.v_lock, ermsg)) break; vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL @@ -9242,7 +9294,7 @@ { for (li = l->lv_first; li != NULL; li = nli) { - if (tv_check_lock(li->li_tv.v_lock, msg)) + if (tv_check_lock(li->li_tv.v_lock, ermsg)) break; nli = li->li_next; if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL @@ -9598,7 +9650,9 @@ typval_T *argvars; typval_T *rettv; { - garbage_collect(); + /* This is postponed until we are back at the toplevel, because we may be + * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */ + want_garbage_collect = TRUE; } /* @@ -9792,6 +9846,9 @@ varnumber_T n; int error = FALSE; + /* Position the cursor. Needed after a message that ends in a space. */ + windgoto(msg_row, msg_col); + ++no_mapping; ++allow_keys; if (argvars[0].v_type == VAR_UNKNOWN) @@ -9809,6 +9866,10 @@ --no_mapping; --allow_keys; + vimvars[VV_MOUSE_WIN].vv_nr = 0; + vimvars[VV_MOUSE_LNUM].vv_nr = 0; + vimvars[VV_MOUSE_COL].vv_nr = 0; + rettv->vval.v_number = n; if (IS_SPECIAL(n) || mod_mask != 0) { @@ -9837,6 +9898,53 @@ temp[i++] = NUL; rettv->v_type = VAR_STRING; rettv->vval.v_string = vim_strsave(temp); + +#ifdef FEAT_MOUSE + if (n == K_LEFTMOUSE + || n == K_LEFTMOUSE_NM + || n == K_LEFTDRAG + || n == K_LEFTRELEASE + || n == K_LEFTRELEASE_NM + || n == K_MIDDLEMOUSE + || n == K_MIDDLEDRAG + || n == K_MIDDLERELEASE + || n == K_RIGHTMOUSE + || n == K_RIGHTDRAG + || n == K_RIGHTRELEASE + || n == K_X1MOUSE + || n == K_X1DRAG + || n == K_X1RELEASE + || n == K_X2MOUSE + || n == K_X2DRAG + || n == K_X2RELEASE + || n == K_MOUSEDOWN + || n == K_MOUSEUP) + { + int row = mouse_row; + int col = mouse_col; + win_T *win; + linenr_T lnum; +# ifdef FEAT_WINDOWS + win_T *wp; +# endif + int n = 1; + + if (row >= 0 && col >= 0) + { + /* Find the window at the mouse coordinates and compute the + * text position. */ + win = mouse_find_win(&row, &col); + (void)mouse_comp_pos(win, &row, &col, &lnum); +# ifdef FEAT_WINDOWS + for (wp = firstwin; wp != win; wp = wp->w_next) + ++n; +# endif + vimvars[VV_MOUSE_WIN].vv_nr = n; + vimvars[VV_MOUSE_LNUM].vv_nr = lnum; + vimvars[VV_MOUSE_COL].vv_nr = col + 1; + } + } +#endif } } @@ -10412,20 +10520,14 @@ if (win != NULL && varname != NULL) { - if (*varname == '&') /* window-local-option */ - { - /* Set curwin to be our win, temporarily. Also set curbuf, so - * that we can get buffer-local options. */ - oldcurwin = curwin; - curwin = win; - curbuf = win->w_buffer; + /* Set curwin to be our win, temporarily. Also set curbuf, so + * that we can get buffer-local options. */ + oldcurwin = curwin; + curwin = win; + curbuf = win->w_buffer; + if (*varname == '&') /* window-local-option */ get_option_tv(&varname, rettv, 1); - - /* restore previous notion of curwin */ - curwin = oldcurwin; - curbuf = curwin->w_buffer; - } else { if (*varname == NUL) @@ -10438,6 +10540,10 @@ if (v != NULL) copy_tv(&v->di_tv, rettv); } + + /* restore previous notion of curwin */ + curwin = oldcurwin; + curbuf = curwin->w_buffer; } --emsg_off; @@ -11312,14 +11418,19 @@ static int inputsecret_flag = 0; +static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv, int inputdialog)); + /* - * "input()" function - * Also handles inputsecret() when inputsecret is set. + * This function is used by f_input() and f_inputdialog() functions. The third + * argument to f_input() specifies the type of completion to use at the + * prompt. The third argument to f_inputdialog() specifies the value to return + * when the user cancels the prompt. */ static void -f_input(argvars, rettv) +get_user_input(argvars, rettv, inputdialog) typval_T *argvars; typval_T *rettv; + int inputdialog; { char_u *prompt = get_tv_string_chk(&argvars[0]); char_u *p = NULL; @@ -11369,10 +11480,10 @@ if (defstr != NULL) stuffReadbuffSpec(defstr); - if (argvars[2].v_type != VAR_UNKNOWN) + if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) { char_u *xp_name; - int xp_namelen; + int xp_namelen; long argt; rettv->vval.v_string = NULL; @@ -11404,6 +11515,18 @@ } /* + * "input()" function + * Also handles inputsecret() when inputsecret is set. + */ + static void +f_input(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + get_user_input(argvars, rettv, FALSE); +} + +/* * "inputdialog()" function */ static void @@ -11443,7 +11566,7 @@ } else #endif - f_input(argvars, rettv); + get_user_input(argvars, rettv, TRUE); } /* @@ -11471,6 +11594,7 @@ } msg_start(); + msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ lines_left = Rows; /* avoid more prompt */ msg_scroll = TRUE; msg_clr_eos(); @@ -13250,7 +13374,7 @@ if (argvars[2].v_type != VAR_UNKNOWN) EMSG2(_(e_toomanyarg), "remove()"); else if ((d = argvars[0].vval.v_dict) != NULL - && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) + && !tv_check_lock(d->dv_lock, (char_u *)"remove() argument")) { key = get_tv_string_chk(&argvars[1]); if (key != NULL) @@ -13270,7 +13394,7 @@ else if (argvars[0].v_type != VAR_LIST) EMSG2(_(e_listdictarg), "remove()"); else if ((l = argvars[0].vval.v_list) != NULL - && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) + && !tv_check_lock(l->lv_lock, (char_u *)"remove() argument")) { int error = FALSE; @@ -14157,11 +14281,7 @@ typval_T *rettv; { buf_T *buf; -#ifdef FEAT_AUTOCMD aco_save_T aco; -#else - buf_T *save_curbuf; -#endif char_u *varname, *bufvarname; typval_T *varp; char_u nbuf[NUMBUFLEN]; @@ -14178,12 +14298,7 @@ if (buf != NULL && varname != NULL && varp != NULL) { /* set curbuf to be our buf, temporarily */ -#ifdef FEAT_AUTOCMD aucmd_prepbuf(&aco, buf); -#else - save_curbuf = curbuf; - curbuf = buf; -#endif if (*varname == '&') { @@ -14210,11 +14325,7 @@ } /* reset notion of buffer */ -#ifdef FEAT_AUTOCMD aucmd_restbuf(&aco); -#else - curbuf = save_curbuf; -#endif } } @@ -14582,6 +14693,18 @@ } /* + * "shellescape({string})" function + */ + static void +f_shellescape(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + rettv->vval.v_string = vim_strsave_shellescape(get_tv_string(&argvars[0])); + rettv->v_type = VAR_STRING; +} + +/* * "simplify()" function */ static void @@ -15950,6 +16073,10 @@ } } + /* add a terminating NUL */ + ga_grow(&ga, 1); + ga_append(&ga, NUL); + rettv->vval.v_string = ga.ga_data; } @@ -16173,7 +16300,7 @@ curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); curwin->w_set_curswant = FALSE; - curwin->w_topline = get_dict_number(dict, (char_u *)"topline"); + set_topline(curwin, get_dict_number(dict, (char_u *)"topline")); #ifdef FEAT_DIFF curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); #endif @@ -16218,6 +16345,7 @@ #ifdef FEAT_VIRTUALEDIT dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); #endif + update_curswant(); dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); @@ -16438,9 +16566,12 @@ long i = 0; long n; - /* List must be: [fnum, lnum, col, coladd] */ - if (arg->v_type != VAR_LIST || l == NULL - || l->lv_len != (fnump == NULL ? 3 : 4)) + /* List must be: [fnum, lnum, col, coladd], where "fnum" is only there + * when "fnump" isn't NULL and "coladd" is optional. */ + if (arg->v_type != VAR_LIST + || l == NULL + || l->lv_len < (fnump == NULL ? 2 : 3) + || l->lv_len > (fnump == NULL ? 3 : 4)) return FAIL; if (fnump != NULL) @@ -16466,8 +16597,9 @@ #ifdef FEAT_VIRTUALEDIT n = list_find_nr(l, i, NULL); if (n < 0) - return FAIL; - posp->coladd = n; + posp->coladd = 0; + else + posp->coladd = n; #endif return OK; @@ -17759,6 +17891,13 @@ } else /* add a new variable */ { + /* Can't add "v:" variable. */ + if (ht == &vimvarht) + { + EMSG2(_(e_illvar), name); + return; + } + /* Make sure the variable name is valid. */ for (p = varname; *p != NUL; ++p) if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) @@ -17792,7 +17931,7 @@ } /* - * Return TRUE if di_flags "flags" indicate read-only variable "name". + * Return TRUE if di_flags "flags" indicates variable "name" is read-only. * Also give an error message. */ static int @@ -17814,6 +17953,23 @@ } /* + * Return TRUE if di_flags "flags" indicates variable "name" is fixed. + * Also give an error message. + */ + static int +var_check_fixed(flags, name) + int flags; + char_u *name; +{ + if (flags & DI_FLAGS_FIX) + { + EMSG2(_("E795: Cannot delete variable %s"), name); + return TRUE; + } + return FALSE; +} + +/* * Return TRUE if typeval "tv" is set to be locked (immutable). * Also give an error message, using "name". */ @@ -18396,12 +18552,14 @@ if (!eap->skip) { - /* Check the name of the function. */ + /* Check the name of the function. Unless it's a dictionary function + * (that we are overwriting). */ if (name != NULL) arg = name; else arg = fudi.fd_newkey; - if (arg != NULL) + if (arg != NULL && (fudi.fd_di == NULL + || fudi.fd_di->di_tv.v_type != VAR_FUNC)) { if (*arg == K_SPECIAL) j = 3; @@ -18786,6 +18944,7 @@ if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) { vim_free(fudi.fd_di); + vim_free(fp); goto erret; } } @@ -18963,7 +19122,8 @@ else if (lead > 0) { lead = 3; - if (eval_fname_sid(lv.ll_exp_name != NULL ? lv.ll_exp_name : *pp)) + if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) + || eval_fname_sid(*pp)) { /* It's "s:" or "" */ if (current_SID <= 0) @@ -19618,6 +19778,7 @@ char_u *name; #ifdef FEAT_PROFILE proftime_T wait_start; + proftime_T call_start; #endif /* If depth of calling is getting too high, don't execute the function */ @@ -19685,6 +19846,7 @@ v->di_tv.vval.v_list = &fc.l_varlist; vim_memset(&fc.l_varlist, 0, sizeof(list_T)); fc.l_varlist.lv_refcount = 99999; + fc.l_varlist.lv_lock = VAR_FIXED; /* * Set a:firstline to "firstline" and a:lastline to "lastline". @@ -19761,7 +19923,7 @@ if (p_verbose >= 14) { char_u buf[MSG_BUF_LEN]; - char_u numbuf[NUMBUFLEN]; + char_u numbuf2[NUMBUFLEN]; char_u *tofree; msg_puts((char_u *)"("); @@ -19773,8 +19935,8 @@ msg_outnum((long)argvars[i].vval.v_number); else { - trunc_string(tv2string(&argvars[i], &tofree, numbuf, 0), - buf, MSG_BUF_CLEN); + trunc_string(tv2string(&argvars[i], &tofree, + numbuf2, 0), buf, MSG_BUF_CLEN); msg_puts(buf); vim_free(tofree); } @@ -19796,7 +19958,7 @@ || (fc.caller != NULL && &fc.caller->func->uf_profiling)) { ++fp->uf_tm_count; - profile_start(&fp->uf_tm_start); + profile_start(&call_start); profile_zero(&fp->uf_tm_children); } script_prof_save(&wait_start); @@ -19826,14 +19988,14 @@ 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); - profile_add(&fp->uf_tm_total, &fp->uf_tm_start); - profile_self(&fp->uf_tm_self, &fp->uf_tm_start, &fp->uf_tm_children); + profile_end(&call_start); + profile_sub_wait(&wait_start, &call_start); + profile_add(&fp->uf_tm_total, &call_start); + profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children); if (fc.caller != NULL && &fc.caller->func->uf_profiling) { - profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); - profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); + profile_add(&fc.caller->func->uf_tm_children, &call_start); + profile_add(&fc.caller->func->uf_tml_children, &call_start); } } #endif @@ -19852,13 +20014,13 @@ else { char_u buf[MSG_BUF_LEN]; - char_u numbuf[NUMBUFLEN]; + char_u numbuf2[NUMBUFLEN]; char_u *tofree; /* The value may be very long. Skip the middle part, so that we * have some idea how it starts and ends. smsg() would always * truncate it at the end. */ - trunc_string(tv2string(fc.rettv, &tofree, numbuf, 0), + trunc_string(tv2string(fc.rettv, &tofree, numbuf2, 0), buf, MSG_BUF_CLEN); smsg((char_u *)_("%s returning %s"), sourcing_name, buf); vim_free(tofree); diff -Naur vim70.orig/src/ex_cmds2.c vim70/src/ex_cmds2.c --- vim70.orig/src/ex_cmds2.c 2006-04-17 03:19:07.000000000 -0700 +++ vim70/src/ex_cmds2.c 2006-12-05 19:57:56.000000000 -0800 @@ -3648,13 +3648,13 @@ * Return FALSE when not sourcing a file. */ int -source_finished(getline, cookie) - char_u *(*getline) __ARGS((int, void *, int)); +source_finished(fgetline, cookie) + char_u *(*fgetline) __ARGS((int, void *, int)); void *cookie; { - return (getline_equal(getline, cookie, getsourceline) + return (getline_equal(fgetline, cookie, getsourceline) && ((struct source_cookie *)getline_cookie( - getline, cookie))->finished); + fgetline, cookie))->finished); } #endif diff -Naur vim70.orig/src/ex_cmds.c vim70/src/ex_cmds.c --- vim70.orig/src/ex_cmds.c 2006-04-22 11:56:56.000000000 -0700 +++ vim70/src/ex_cmds.c 2006-12-05 19:58:00.000000000 -0800 @@ -95,7 +95,10 @@ _("<%s>%s%s %d, Hex %02x, Octal %03o"), transchar(c), buf1, buf2, c, c, c); #ifdef FEAT_MBYTE - c = cc[ci++]; + if (enc_utf8) + c = cc[ci++]; + else + c = 0; #endif } @@ -108,7 +111,7 @@ if (len > 0) IObuff[len++] = ' '; IObuff[len++] = '<'; - if (utf_iscomposing(c) + if (enc_utf8 && utf_iscomposing(c) # ifdef USE_GUI && !gui.in_use # endif @@ -120,7 +123,10 @@ : _("> %d, Hex %08x, Octal %o"), c, c, c); if (ci == MAX_MCO) break; - c = cc[ci++]; + if (enc_utf8) + c = cc[ci++]; + else + c = 0; } #endif @@ -185,6 +191,7 @@ new_indent = indent; else { + has_tab = FALSE; /* avoid uninit warnings */ len = linelen(eap->cmdidx == CMD_right ? &has_tab : NULL) - get_indent(); @@ -1772,10 +1779,9 @@ ? (st_old.st_mode & 0020) : (st_old.st_mode & 0002)))) { - int tt; + int tt = msg_didany; /* avoid a wait_return for this message, it's annoying */ - tt = msg_didany; EMSG2(_("E137: Viminfo file is not writable: %s"), fname); msg_didany = tt; fclose(fp_in); @@ -2458,6 +2464,8 @@ #ifdef FEAT_AUTOCMD apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf); #endif + /* Change directories when the 'acd' option is set. */ + DO_AUTOCHDIR } /* print full file name if :cd used */ fileinfo(FALSE, FALSE, eap->forceit); @@ -2675,8 +2683,13 @@ eap, eap->append, eap->forceit, TRUE, FALSE); /* After ":saveas fname" reset 'readonly'. */ - if (eap->cmdidx == CMD_saveas && retval == OK) - curbuf->b_p_ro = FALSE; + if (eap->cmdidx == CMD_saveas) + { + if (retval == OK) + curbuf->b_p_ro = FALSE; + /* Change directories when the 'acd' option is set. */ + DO_AUTOCHDIR + } } theend: @@ -3547,11 +3560,9 @@ foldUpdateAll(curwin); #endif -#ifdef FEAT_AUTOCHDIR - if (p_acd && curbuf->b_ffname != NULL - && vim_chdirfile(curbuf->b_ffname) == OK) - shorten_fnames(TRUE); -#endif + /* Change directories when the 'acd' option is set. */ + DO_AUTOCHDIR + /* * Careful: open_buffer() and apply_autocmds() may change the current * buffer and window. @@ -3718,12 +3729,8 @@ if (p_im) need_start_insertmode = TRUE; -#ifdef FEAT_AUTOCHDIR - /* Change directories when the acd option is set on. */ - if (p_acd && curbuf->b_ffname != NULL - && vim_chdirfile(curbuf->b_ffname) == OK) - shorten_fnames(TRUE); -#endif + /* Change directories when the 'acd' option is set. */ + DO_AUTOCHDIR #if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) if (gui.in_use && curbuf->b_ffname != NULL) diff -Naur vim70.orig/src/ex_cmds.h vim70/src/ex_cmds.h --- vim70.orig/src/ex_cmds.h 2006-04-07 02:44:46.000000000 -0700 +++ vim70/src/ex_cmds.h 2006-12-05 19:57:46.000000000 -0800 @@ -262,7 +262,7 @@ EX(CMD_comclear, "comclear", ex_comclear, TRLBAR|CMDWIN), EX(CMD_compiler, "compiler", ex_compiler, - BANG|TRLBAR|WORD1), + BANG|TRLBAR|WORD1|CMDWIN), EX(CMD_continue, "continue", ex_continue, TRLBAR|SBOXOK|CMDWIN), EX(CMD_confirm, "confirm", ex_wrongmodifier, diff -Naur vim70.orig/src/ex_docmd.c vim70/src/ex_docmd.c --- vim70.orig/src/ex_docmd.c 2006-05-05 09:33:19.000000000 -0700 +++ vim70/src/ex_docmd.c 2006-12-05 19:58:21.000000000 -0800 @@ -58,9 +58,9 @@ #endif #ifdef FEAT_EVAL -static char_u *do_one_cmd __ARGS((char_u **, int, struct condstack *, char_u *(*getline)(int, void *, int), void *cookie)); +static char_u *do_one_cmd __ARGS((char_u **, int, struct condstack *, char_u *(*fgetline)(int, void *, int), void *cookie)); #else -static char_u *do_one_cmd __ARGS((char_u **, int, char_u *(*getline)(int, void *, int), void *cookie)); +static char_u *do_one_cmd __ARGS((char_u **, int, char_u *(*fgetline)(int, void *, int), void *cookie)); static int if_level = 0; /* depth in :if */ #endif static char_u *find_command __ARGS((exarg_T *eap, int *full)); @@ -831,10 +831,13 @@ /* * If requested, store and reset the global values controlling the - * exception handling (used when debugging). + * exception handling (used when debugging). Otherwise clear it to avoid + * a bogus compiler warning when the optimizer uses inline functions... */ - else if (flags & DOCMD_EXCRESET) + if (flags & DOCMD_EXCRESET) save_dbg_stuff(&debug_saved); + else + memset(&debug_saved, 0, 1); initial_trylevel = trylevel; @@ -1574,24 +1577,24 @@ #endif /* - * If "getline" is get_loop_line(), return TRUE if the getline it uses equals - * "func". * Otherwise return TRUE when "getline" equals "func". + * If "fgetline" is get_loop_line(), return TRUE if the getline it uses equals + * "func". * Otherwise return TRUE when "fgetline" equals "func". */ /*ARGSUSED*/ int -getline_equal(getline, cookie, func) - char_u *(*getline) __ARGS((int, void *, int)); - void *cookie; /* argument for getline() */ +getline_equal(fgetline, cookie, func) + char_u *(*fgetline) __ARGS((int, void *, int)); + void *cookie; /* argument for fgetline() */ char_u *(*func) __ARGS((int, void *, int)); { #ifdef FEAT_EVAL char_u *(*gp) __ARGS((int, void *, int)); struct loop_cookie *cp; - /* When "getline" is "get_loop_line()" use the "cookie" to find the + /* When "fgetline" is "get_loop_line()" use the "cookie" to find the * function that's orignally used to obtain the lines. This may be nested * several levels. */ - gp = getline; + gp = fgetline; cp = (struct loop_cookie *)cookie; while (gp == get_loop_line) { @@ -1600,29 +1603,29 @@ } return gp == func; #else - return getline == func; + return fgetline == func; #endif } #if defined(FEAT_EVAL) || defined(FEAT_MBYTE) || defined(PROTO) /* - * If "getline" is get_loop_line(), return the cookie used by the original + * If "fgetline" is get_loop_line(), return the cookie used by the original * getline function. Otherwise return "cookie". */ /*ARGSUSED*/ void * -getline_cookie(getline, cookie) - char_u *(*getline) __ARGS((int, void *, int)); - void *cookie; /* argument for getline() */ +getline_cookie(fgetline, cookie) + char_u *(*fgetline) __ARGS((int, void *, int)); + void *cookie; /* argument for fgetline() */ { # ifdef FEAT_EVAL char_u *(*gp) __ARGS((int, void *, int)); struct loop_cookie *cp; - /* When "getline" is "get_loop_line()" use the "cookie" to find the + /* When "fgetline" is "get_loop_line()" use the "cookie" to find the * cookie that's orignally used to obtain the lines. This may be nested * several levels. */ - gp = getline; + gp = fgetline; cp = (struct loop_cookie *)cookie; while (gp == get_loop_line) { @@ -1648,7 +1651,7 @@ * 5. parse arguments * 6. switch on command name * - * Note: "getline" can be NULL. + * Note: "fgetline" can be NULL. * * This function may be called recursively! */ @@ -1663,14 +1666,14 @@ #ifdef FEAT_EVAL cstack, #endif - getline, cookie) + fgetline, cookie) char_u **cmdlinep; int sourcing; #ifdef FEAT_EVAL struct condstack *cstack; #endif - char_u *(*getline) __ARGS((int, void *, int)); - void *cookie; /* argument for getline() */ + char_u *(*fgetline) __ARGS((int, void *, int)); + void *cookie; /* argument for fgetline() */ { char_u *p; linenr_T lnum; @@ -1698,7 +1701,7 @@ if (quitmore #ifdef FEAT_EVAL /* avoid that a function call in 'statusline' does this */ - && !getline_equal(getline, cookie, get_func_line) + && !getline_equal(fgetline, cookie, get_func_line) #endif ) --quitmore; @@ -1710,6 +1713,10 @@ save_cmdmod = cmdmod; vim_memset(&cmdmod, 0, sizeof(cmdmod)); + /* "#!anything" is handled like a comment. */ + if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!') + goto doend; + /* * Repeat until no more command modifiers are found. */ @@ -1724,8 +1731,8 @@ /* in ex mode, an empty line works like :+ */ if (*ea.cmd == NUL && exmode_active - && (getline_equal(getline, cookie, getexmodeline) - || getline_equal(getline, cookie, getexline)) + && (getline_equal(fgetline, cookie, getexmodeline) + || getline_equal(fgetline, cookie, getexline)) && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { ea.cmd = (char_u *)"+"; @@ -1914,9 +1921,9 @@ /* Count this line for profiling if ea.skip is FALSE. */ if (do_profiling == PROF_YES && !ea.skip) { - if (getline_equal(getline, cookie, get_func_line)) - func_line_exec(getline_cookie(getline, cookie)); - else if (getline_equal(getline, cookie, getsourceline)) + if (getline_equal(fgetline, cookie, get_func_line)) + func_line_exec(getline_cookie(fgetline, cookie)); + else if (getline_equal(fgetline, cookie, getsourceline)) script_line_exec(); } #endif @@ -2585,7 +2592,7 @@ * The "ea" structure holds the arguments that can be used. */ ea.cmdlinep = cmdlinep; - ea.getline = getline; + ea.getline = fgetline; ea.cookie = cookie; #ifdef FEAT_EVAL ea.cstack = cstack; @@ -2623,9 +2630,9 @@ do_throw(cstack); else if (check_cstack) { - if (source_finished(getline, cookie)) + if (source_finished(fgetline, cookie)) do_finish(&ea, TRUE); - else if (getline_equal(getline, cookie, get_func_line) + else if (getline_equal(fgetline, cookie, get_func_line) && current_func_returned()) do_return(&ea, TRUE, FALSE, NULL); } @@ -6289,7 +6296,6 @@ exarg_T *eap; { tabpage_T *tp; - int h = tabline_height(); # ifdef FEAT_CMDWIN if (cmdwin_type != 0) @@ -6321,9 +6327,6 @@ ) tabpage_close(eap->forceit); } - - if (h != tabline_height()) - shell_new_rows(); } /* @@ -6335,7 +6338,6 @@ { tabpage_T *tp; int done; - int h = tabline_height(); # ifdef FEAT_CMDWIN if (cmdwin_type != 0) @@ -6364,9 +6366,6 @@ break; } } - - if (h != tabline_height()) - shell_new_rows(); } /* @@ -6390,6 +6389,8 @@ /* * Close tab page "tp", which is not the current tab page. * Note that autocommands may make "tp" invalid. + * Also takes care of the tab pages line disappearing when closing the + * last-but-one tab page. */ void tabpage_close_other(tp, forceit) @@ -6398,6 +6399,7 @@ { int done = 0; win_T *wp; + int h = tabline_height(); /* Limit to 1000 windows, autocommands may add a window while we close * one. OK, so I'm paranoid... */ @@ -6411,7 +6413,10 @@ if (!valid_tabpage(tp) || tp->tp_firstwin == wp) break; } + redraw_tabline = TRUE; + if (h != tabline_height()) + shell_new_rows(); } /* @@ -8214,8 +8219,9 @@ c = *eap->arg; if (c == NUL || (c == '*' && *eap->cmd == '*')) c = '@'; - /* put the register in mapbuf */ - if (do_execreg(c, TRUE, vim_strchr(p_cpo, CPO_EXECBUF) != NULL) == FAIL) + /* Put the register in the typeahead buffer with the "silent" flag. */ + if (do_execreg(c, TRUE, vim_strchr(p_cpo, CPO_EXECBUF) != NULL, TRUE) + == FAIL) { beep_flush(); } @@ -8365,6 +8371,7 @@ if (ASCII_ISALPHA(*arg) # ifdef FEAT_CLIPBOARD || *arg == '*' + || *arg == '+' # endif || *arg == '"') { @@ -8375,6 +8382,7 @@ (islower(redir_reg) # ifdef FEAT_CLIPBOARD || redir_reg == '*' + || redir_reg == '+' # endif || redir_reg == '"')) { @@ -8417,6 +8425,15 @@ else EMSG2(_(e_invarg2), eap->arg); } + + /* Make sure redirection is not off. Can happen for cmdline completion + * that indirectly invokes a command to catch its output. */ + if (redir_fd != NULL +#ifdef FEAT_EVAL + || redir_reg || redir_vname +#endif + ) + redir_off = FALSE; } /* @@ -9629,7 +9646,8 @@ #endif #ifdef FEAT_SESSION -static int ses_winsizes __ARGS((FILE *fd, int restore_size)); +static int ses_winsizes __ARGS((FILE *fd, int restore_size, + win_T *tab_firstwin)); static int ses_win_rec __ARGS((FILE *fd, frame_T *fr)); static frame_T *ses_skipframe __ARGS((frame_T *fr)); static int ses_do_frame __ARGS((frame_T *fr)); @@ -9655,8 +9673,9 @@ win_T *wp; char_u *sname; win_T *edited_win = NULL; - tabpage_T *old_curtab = curtab; int tabnr; + win_T *tab_firstwin; + frame_T *tab_topframe; if (ssop_flags & SSOP_BUFFERS) only_save_windows = FALSE; /* Save ALL buffers */ @@ -9764,14 +9783,33 @@ /* * May repeat putting Windows for each tab, when "tabpages" is in * 'sessionoptions'. + * Don't use goto_tabpage(), it may change directory and trigger + * autocommands. */ + tab_firstwin = firstwin; /* first window in tab page "tabnr" */ + tab_topframe = topframe; for (tabnr = 1; ; ++tabnr) { + int need_tabnew = FALSE; + if ((ssop_flags & SSOP_TABPAGES)) { - goto_tabpage(tabnr); - if (tabnr > 1 && put_line(fd, "tabnew") == FAIL) - return FAIL; + tabpage_T *tp = find_tabpage(tabnr); + + if (tp == NULL) + break; /* done all tab pages */ + if (tp == curtab) + { + tab_firstwin = firstwin; + tab_topframe = topframe; + } + else + { + tab_firstwin = tp->tp_firstwin; + tab_topframe = tp->tp_topframe; + } + if (tabnr > 1) + need_tabnew = TRUE; } /* @@ -9779,7 +9817,7 @@ * is aborted we don't end up with a number of useless windows. * This may have side effects! (e.g., compressed or network file). */ - for (wp = firstwin; wp != NULL; wp = wp->w_next) + for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) { if (ses_do_win(wp) && wp->w_buffer->b_ffname != NULL @@ -9789,21 +9827,26 @@ #endif ) { - if (fputs("edit ", fd) < 0 + if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0 || ses_fname(fd, wp->w_buffer, &ssop_flags) == FAIL) return FAIL; + need_tabnew = FALSE; if (!wp->w_arg_idx_invalid) edited_win = wp; break; } } + /* If no file got edited create an empty tab page. */ + if (need_tabnew && put_line(fd, "tabnew") == FAIL) + return FAIL; + /* * Save current window layout. */ if (put_line(fd, "set splitbelow splitright") == FAIL) return FAIL; - if (ses_win_rec(fd, topframe) == FAIL) + if (ses_win_rec(fd, tab_topframe) == FAIL) return FAIL; if (!p_sb && put_line(fd, "set nosplitbelow") == FAIL) return FAIL; @@ -9815,7 +9858,7 @@ * Remember the window number of the current window after restoring. */ nr = 0; - for (wp = firstwin; wp != NULL; wp = W_NEXT(wp)) + for (wp = tab_firstwin; wp != NULL; wp = W_NEXT(wp)) { if (ses_do_win(wp)) ++nr; @@ -9838,13 +9881,13 @@ */ if (put_line(fd, "set winheight=1 winwidth=1") == FAIL) return FAIL; - if (nr > 1 && ses_winsizes(fd, restore_size) == FAIL) + if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL) return FAIL; /* * Restore the view of the window (options, file, cursor, etc.). */ - for (wp = firstwin; wp != NULL; wp = wp->w_next) + for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) { if (!ses_do_win(wp)) continue; @@ -9865,19 +9908,17 @@ * Restore window sizes again after jumping around in windows, because * the current window has a minimum size while others may not. */ - if (nr > 1 && ses_winsizes(fd, restore_size) == FAIL) + if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL) return FAIL; /* Don't continue in another tab page when doing only the current one * or when at the last tab page. */ - if (!(ssop_flags & SSOP_TABPAGES) || curtab->tp_next == NULL) + if (!(ssop_flags & SSOP_TABPAGES)) break; } if (ssop_flags & SSOP_TABPAGES) { - if (valid_tabpage(old_curtab)) - goto_tabpage_tp(old_curtab); if (fprintf(fd, "tabnext %d", tabpage_index(curtab)) < 0 || put_eol(fd) == FAIL) return FAIL; @@ -9913,16 +9954,17 @@ } static int -ses_winsizes(fd, restore_size) +ses_winsizes(fd, restore_size, tab_firstwin) FILE *fd; int restore_size; + win_T *tab_firstwin; { int n = 0; win_T *wp; if (restore_size && (ssop_flags & SSOP_WINSIZE)) { - for (wp = firstwin; wp != NULL; wp = wp->w_next) + for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) { if (!ses_do_win(wp)) continue; diff -Naur vim70.orig/src/ex_eval.c vim70/src/ex_eval.c --- vim70.orig/src/ex_eval.c 2006-04-22 12:22:27.000000000 -0700 +++ vim70/src/ex_eval.c 2006-12-05 19:58:21.000000000 -0800 @@ -340,7 +340,7 @@ /* If no exception is to be thrown or the conversion should be done after * returning to a previous invocation of do_one_cmd(), do nothing. */ - if (*msg_list == NULL) + if (msg_list == NULL || *msg_list == NULL) return; if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL) @@ -2026,8 +2026,11 @@ /* If an error was about to be converted to an exception when * enter_cleanup() was called, free the message list. */ - free_msglist(*msg_list); - *msg_list = NULL; + if (msg_list != NULL) + { + free_msglist(*msg_list); + *msg_list = NULL; + } } /* diff -Naur vim70.orig/src/ex_getln.c vim70/src/ex_getln.c --- vim70.orig/src/ex_getln.c 2006-04-30 08:32:01.000000000 -0700 +++ vim70/src/ex_getln.c 2006-12-05 19:58:12.000000000 -0800 @@ -34,7 +34,7 @@ int xp_context; /* type of expansion */ # ifdef FEAT_EVAL char_u *xp_arg; /* user-defined expansion arg */ - int input_fn; /* Invoked for input() function */ + int input_fn; /* when TRUE Invoked for input() function */ # endif }; @@ -86,7 +86,7 @@ static void draw_cmdline __ARGS((int start, int len)); static void save_cmdline __ARGS((struct cmdline_info *ccp)); static void restore_cmdline __ARGS((struct cmdline_info *ccp)); -static int cmdline_paste __ARGS((int regname, int literally)); +static int cmdline_paste __ARGS((int regname, int literally, int remcr)); #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) static void redrawcmd_preedit __ARGS((void)); #endif @@ -324,6 +324,9 @@ */ for (;;) { + redir_off = TRUE; /* Don't redirect the typed command. + Repeated, because a ":redir" inside + completion may switch it on. */ #ifdef USE_ON_FLY_SCROLL dont_scroll = FALSE; /* allow scrolling here */ #endif @@ -1113,7 +1116,7 @@ #endif if (c != ESC) /* use ESC to cancel inserting register */ { - cmdline_paste(c, i == Ctrl_R); + cmdline_paste(c, i == Ctrl_R, FALSE); #ifdef FEAT_EVAL /* When there was a serious error abort getting the @@ -1228,16 +1231,16 @@ goto cmdline_not_changed; /* Ignore mouse */ # ifdef FEAT_CLIPBOARD if (clip_star.available) - cmdline_paste('*', TRUE); + cmdline_paste('*', TRUE, TRUE); else # endif - cmdline_paste(0, TRUE); + cmdline_paste(0, TRUE, TRUE); redrawcmd(); goto cmdline_changed; # ifdef FEAT_DND case K_DROP: - cmdline_paste('~', TRUE); + cmdline_paste('~', TRUE, FALSE); redrawcmd(); goto cmdline_changed; # endif @@ -1387,7 +1390,17 @@ { c = gchar_cursor(); if (c != NUL) + { + if (c == firstc || vim_strchr((char_u *)( + p_magic ? "\\^$.*[" : "\\^$"), c) + != NULL) + { + /* put a backslash before special characters */ + stuffcharReadbuff(c); + c = '\\'; + } break; + } } goto cmdline_not_changed; } @@ -1753,6 +1766,11 @@ end_pos = curwin->w_cursor; /* shutup gcc 4 */ validate_cursor(); +# ifdef FEAT_WINDOWS + /* May redraw the status line to show the cursor position. */ + if (p_ru && curwin->w_status_height > 0) + curwin->w_redr_status = TRUE; +# endif save_cmdline(&save_ccline); update_screen(SOME_VALID); @@ -2360,7 +2378,7 @@ { if ((State & CMDLINE) && xic != NULL - && im_get_status() + /* && im_get_status() doesn't work when using SCIM */ && !p_imdisable && im_is_preediting()) { @@ -2882,9 +2900,10 @@ * return FAIL for failure, OK otherwise */ static int -cmdline_paste(regname, literally) +cmdline_paste(regname, literally, remcr) int regname; int literally; /* Insert text literally instead of "as typed" */ + int remcr; /* remove trailing CR */ { long i; char_u *arg; @@ -2960,7 +2979,7 @@ return OK; } - return cmdline_paste_reg(regname, literally); + return cmdline_paste_reg(regname, literally, remcr); } /* @@ -4521,7 +4540,9 @@ flags |= EW_FILE | EW_EXEC; /* For an absolute name we don't use $PATH. */ - if ((pat[0] == '.' && (vim_ispathsep(pat[1]) + if (mch_isFullName(pat)) + path = (char_u *)" "; + else if ((pat[0] == '.' && (vim_ispathsep(pat[1]) || (pat[1] == '.' && vim_ispathsep(pat[2]))))) path = (char_u *)"."; else @@ -4534,6 +4555,9 @@ ga_init2(&ga, (int)sizeof(char *), 10); for (s = path; *s != NUL; s = e) { + if (*s == ' ') + ++s; /* Skip space used for absolute path name. */ + #if defined(MSDOS) || defined(MSWIN) || defined(OS2) e = vim_strchr(s, ';'); #else @@ -5982,6 +6006,8 @@ typestr[0] = cmdwin_type; typestr[1] = NUL; apply_autocmds(EVENT_CMDWINENTER, typestr, typestr, FALSE, curbuf); + if (restart_edit != 0) /* autocmd with ":startinsert" */ + stuffcharReadbuff(K_NOP); # endif i = RedrawingDisabled; diff -Naur vim70.orig/src/fileio.c vim70/src/fileio.c --- vim70.orig/src/fileio.c 2006-04-30 08:28:57.000000000 -0700 +++ vim70/src/fileio.c 2006-12-05 19:58:02.000000000 -0800 @@ -316,6 +316,9 @@ * display the line. */ ex_no_reprint = TRUE; + /* don't display the file info for another buffer now */ + need_fileinfo = FALSE; + /* * For Unix: Use the short file name whenever possible. * Avoids problems with networks and when directory names are changed. @@ -6450,17 +6453,10 @@ int old_ro = buf->b_p_ro; buf_T *savebuf; int saved = OK; -#ifdef FEAT_AUTOCMD aco_save_T aco; /* set curwin/curbuf for "buf" and save some things */ aucmd_prepbuf(&aco, buf); -#else - buf_T *save_curbuf = curbuf; - - curbuf = buf; - curwin->w_buffer = buf; -#endif /* We only want to read the text from the file, not reset the syntax * highlighting, clear marks, diff status, etc. Force the fileformat @@ -6573,14 +6569,9 @@ curbuf->b_p_ro |= old_ro; } -#ifdef FEAT_AUTOCMD /* restore curwin/curbuf and a few other things */ aucmd_restbuf(&aco); /* Careful: autocommands may have made "buf" invalid! */ -#else - curwin->w_buffer = save_curbuf; - curbuf = save_curbuf; -#endif } /*ARGSUSED*/ @@ -6992,6 +6983,7 @@ {"FocusLost", EVENT_FOCUSLOST}, {"FuncUndefined", EVENT_FUNCUNDEFINED}, {"GUIEnter", EVENT_GUIENTER}, + {"GUIFailed", EVENT_GUIFAILED}, {"InsertChange", EVENT_INSERTCHANGE}, {"InsertEnter", EVENT_INSERTENTER}, {"InsertLeave", EVENT_INSERTLEAVE}, @@ -8088,6 +8080,7 @@ * Search a window for the current buffer. Save the cursor position and * screen offset. * Set "curbuf" and "curwin" to match "buf". + * When FEAT_AUTOCMD is not defined another version is used, see below. */ void aucmd_prepbuf(aco, buf) @@ -8151,6 +8144,7 @@ /* * Cleanup after executing autocommands for a (hidden) buffer. * Restore the window as it was (if possible). + * When FEAT_AUTOCMD is not defined another version is used, see below. */ void aucmd_restbuf(aco) @@ -8295,7 +8289,11 @@ { int state; - if (!did_cursorhold && has_cursorhold() && !Recording) + if (!did_cursorhold && has_cursorhold() && !Recording +#ifdef FEAT_INS_EXPAND + && !ins_compl_active() +#endif + ) { state = get_real_state(); if (state == NORMAL_BUSY || (state & INSERT) != 0) @@ -9063,8 +9061,38 @@ return retval; } +#else /* FEAT_AUTOCMD */ + +/* + * Prepare for executing commands for (hidden) buffer "buf". + * This is the non-autocommand version, it simply saves "curbuf" and sets + * "curbuf" and "curwin" to match "buf". + */ + void +aucmd_prepbuf(aco, buf) + aco_save_T *aco; /* structure to save values in */ + buf_T *buf; /* new curbuf */ +{ + aco->save_buf = buf; + curbuf = buf; + curwin->w_buffer = buf; +} + +/* + * Restore after executing commands for a (hidden) buffer. + * This is the non-autocommand version. + */ + void +aucmd_restbuf(aco) + aco_save_T *aco; /* structure holding saved values */ +{ + curbuf = aco->save_buf; + curwin->w_buffer = curbuf; +} + #endif /* FEAT_AUTOCMD */ + #if defined(FEAT_AUTOCMD) || defined(FEAT_WILDIGN) || defined(PROTO) /* * Try matching a filename with a "pattern" ("prog" is NULL), or use the diff -Naur vim70.orig/src/fold.c vim70/src/fold.c --- vim70.orig/src/fold.c 2006-04-22 12:35:56.000000000 -0700 +++ vim70/src/fold.c 2006-12-05 19:58:10.000000000 -0800 @@ -2971,7 +2971,11 @@ else flp->lvl = get_indent_buf(buf, lnum) / buf->b_p_sw; if (flp->lvl > flp->wp->w_p_fdn) + { flp->lvl = flp->wp->w_p_fdn; + if (flp->lvl < 0) + flp->lvl = 0; + } } /* foldlevelDiff() {{{2 */ diff -Naur vim70.orig/src/getchar.c vim70/src/getchar.c --- vim70.orig/src/getchar.c 2006-05-03 10:29:21.000000000 -0700 +++ vim70/src/getchar.c 2006-12-05 19:58:33.000000000 -0800 @@ -76,7 +76,7 @@ */ static mapblock_T *first_abbr = NULL; /* first entry in abbrlist */ -static int KeyNoremap = FALSE; /* remapping disabled */ +static int KeyNoremap = 0; /* remapping flags */ /* * variables used by vgetorpeek() and flush_buffers() @@ -1035,6 +1035,8 @@ /* * Put character "c" back into the typeahead buffer. * Can be used for a character obtained by vgetc() that needs to be put back. + * Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to + * the char. */ void ins_char_typebuf(c) @@ -1061,7 +1063,7 @@ buf[1] = NUL; #endif } - (void)ins_typebuf(buf, REMAP_YES, 0, !KeyTyped, FALSE); + (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent); } /* @@ -1451,7 +1453,8 @@ { updatescript(0); #ifdef FEAT_EVAL - garbage_collect(); + if (may_garbage_collect) + garbage_collect(); #endif } @@ -1502,6 +1505,13 @@ int i; #endif +#ifdef FEAT_EVAL + /* Do garbage collection when garbagecollect() was called previously and + * we are now at the toplevel. */ + if (may_garbage_collect && want_garbage_collect) + garbage_collect(); +#endif + /* * If a character was put back with vungetc, it was already processed. * Return it directly. @@ -1511,13 +1521,13 @@ c = old_char; old_char = -1; mod_mask = old_mod_mask; - return c; } - - mod_mask = 0x0; - last_recorded_len = 0; - for (;;) /* this is done twice if there are modifiers */ + else { + mod_mask = 0x0; + last_recorded_len = 0; + for (;;) /* this is done twice if there are modifiers */ + { if (mod_mask) /* no mapping after modifier has been read */ { ++no_mapping; @@ -1695,8 +1705,20 @@ } #endif - return c; + break; + } } + +#ifdef FEAT_EVAL + /* + * In the main loop "may_garbage_collect" can be set to do garbage + * collection in the first next vgetc(). It's disabled after that to + * avoid internally used Lists and Dicts to be freed. + */ + may_garbage_collect = FALSE; +#endif + + return c; } /* @@ -1940,10 +1962,13 @@ c = Ctrl_C; flush_buffers(TRUE); /* flush all typeahead */ - /* Also record this character, it might be needed to - * get out of Insert mode. */ - *typebuf.tb_buf = c; - gotchars(typebuf.tb_buf, 1); + if (advance) + { + /* Also record this character, it might be needed to + * get out of Insert mode. */ + *typebuf.tb_buf = c; + gotchars(typebuf.tb_buf, 1); + } cmd_silent = FALSE; break; @@ -2247,9 +2272,8 @@ gotchars(typebuf.tb_buf + typebuf.tb_off, 1); } - KeyNoremap = (typebuf.tb_noremap[ - typebuf.tb_off] - & (RM_NONE|RM_SCRIPT)); + KeyNoremap = typebuf.tb_noremap[ + typebuf.tb_off]; del_typebuf(1, 0); } break; /* got character, break for loop */ @@ -4173,7 +4197,8 @@ if (typebuf.tb_no_abbr_cnt) /* abbrev. are not recursive */ return FALSE; - if (KeyNoremap) /* no remapping implies no abbreviation */ + if ((KeyNoremap & (RM_NONE|RM_SCRIPT)) != 0) + /* no remapping implies no abbreviation */ return FALSE; /* diff -Naur vim70.orig/src/globals.h vim70/src/globals.h --- vim70.orig/src/globals.h 2006-04-30 06:16:23.000000000 -0700 +++ vim70/src/globals.h 2006-12-05 19:58:06.000000000 -0800 @@ -166,6 +166,7 @@ EXTERN int emsg_off INIT(= 0); /* don't display errors for now, unless 'debug' is set. */ EXTERN int info_message INIT(= FALSE); /* printing informative message */ +EXTERN int msg_hist_off INIT(= FALSE); /* don't add messages to history */ #ifdef FEAT_EVAL EXTERN int emsg_skip INIT(= 0); /* don't display errors for expression that is skipped */ @@ -300,9 +301,16 @@ #endif #ifdef FEAT_EVAL -EXTERN scid_T current_SID INIT(= 0); /* ID of script being sourced or - was sourced to define the - current function. */ +/* Garbage collection can only take place when we are sure there are no Lists + * or Dictionaries being used internally. This is flagged with + * "may_garbage_collect" when we are at the toplevel. + * "want_garbage_collect" is set by the garbagecollect() function, which means + * we do garbage collection before waiting for a char at the toplevel. */ +EXTERN int may_garbage_collect INIT(= FALSE); +EXTERN int want_garbage_collect INIT(= FALSE); + +/* ID of script being sourced or was sourced to define the current function. */ +EXTERN scid_T current_SID INIT(= 0); #endif #if defined(FEAT_EVAL) || defined(FEAT_SYN_HL) @@ -1441,7 +1449,7 @@ EXTERN char_u e_readonly[] INIT(= N_("E45: 'readonly' option is set (add ! to override)")); #ifdef FEAT_EVAL EXTERN char_u e_readonlyvar[] INIT(= N_("E46: Cannot change read-only variable \"%s\"")); -EXTERN char_u e_readonlysbx[] INIT(= N_("E46: Cannot set variable in the sandbox: \"%s\"")); +EXTERN char_u e_readonlysbx[] INIT(= N_("E794: Cannot set variable in the sandbox: \"%s\"")); #endif #ifdef FEAT_QUICKFIX EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile")); diff -Naur vim70.orig/src/gui_at_fs.c vim70/src/gui_at_fs.c --- vim70.orig/src/gui_at_fs.c 2005-07-09 04:30:17.000000000 -0700 +++ vim70/src/gui_at_fs.c 2006-12-05 19:57:43.000000000 -0800 @@ -1861,27 +1861,27 @@ XtPointer pnew; { SFDir *dir; - int nw; + int nw = (int)(long)pnew; dir = &(SFdirs[SFdirPtr + (int)(long)n]); #ifdef FEAT_GUI_NEXTAW - if ((int)(long)pnew < 0) + if (nw < 0) { - if ((int)(long)pnew > -SFvScrollHeight) - (int)(long)pnew = -1; + if (nw > -SFvScrollHeight) + nw = -1; else - (int)(long)pnew = -SFlistSize; + nw = -SFlistSize; } - else if ((int)(long)pnew > 0) + else if (nw > 0) { - if ((int)(long)pnew < SFvScrollHeight) - (int)(long)pnew = 1; + if (nw < SFvScrollHeight) + nw = 1; else - (int)(long)pnew = SFlistSize; + nw = SFlistSize; } #endif - nw = dir->vOrigin + (int)(long)pnew; + nw += dir->vOrigin; if (nw > dir->nEntries - SFlistSize) nw = dir->nEntries - SFlistSize; @@ -1941,27 +1941,27 @@ XtPointer pnew; { SFDir *dir; - int nw; + int nw = (int)(long)pnew; dir = &(SFdirs[SFdirPtr + (int)(long)n]); #ifdef FEAT_GUI_NEXTAW - if ((int)(long)pnew < 0) + if (nw < 0) { - if ((int)(long)pnew > -SFhScrollWidth) - (int)(long)pnew = -1; + if (nw > -SFhScrollWidth) + nw = -1; else - (int)(long)pnew = -SFcharsPerEntry; + nw = -SFcharsPerEntry; } - else if ((int)(long)pnew > 0) + else if (nw > 0) { - if ((int)(long)pnew < SFhScrollWidth) - (int)(long)pnew = 1; + if (nw < SFhScrollWidth) + nw = 1; else - (int)(long)pnew = SFcharsPerEntry; + nw = SFcharsPerEntry; } #endif - nw = dir->hOrigin + (int)(long)pnew; + nw += dir->hOrigin; if (nw > dir->nChars - SFcharsPerEntry) nw = dir->nChars - SFcharsPerEntry; @@ -2038,26 +2038,26 @@ XtPointer client_data; XtPointer pnew; { - int nw; + int nw = (int)(long)pnew; float f; #ifdef FEAT_GUI_NEXTAW - if ((int)(long)pnew < 0) + if (nw < 0) { - if ((int)(long)pnew > -SFpathScrollWidth) - (int)(long)pnew = -1; + if (nw > -SFpathScrollWidth) + nw = -1; else - (int)(long)pnew = -3; + nw = -3; } - else if ((int)(long)pnew > 0) + else if (nw > 0) { - if ((int)(long)pnew < SFpathScrollWidth) - (int)(long)pnew = 1; + if (nw < SFpathScrollWidth) + nw = 1; else - (int)(long)pnew = 3; + nw = 3; } #endif - nw = SFdirPtr + (int)(long)pnew; + nw += SFdirPtr; if (nw > SFdirEnd - 3) nw = SFdirEnd - 3; diff -Naur vim70.orig/src/gui_beval.c vim70/src/gui_beval.c --- vim70.orig/src/gui_beval.c 2006-05-04 12:29:51.000000000 -0700 +++ vim70/src/gui_beval.c 2006-12-05 19:57:56.000000000 -0800 @@ -926,7 +926,7 @@ # define IS_NONPRINTABLE(c) (((c) < 0x20 && (c) != TAB && (c) != NL) \ || (c) == DEL) static void -set_printable_label_text(GtkLabel *label, char_u *msg) +set_printable_label_text(GtkLabel *label, char_u *text) { char_u *convbuf = NULL; char_u *buf; @@ -940,14 +940,14 @@ /* Convert to UTF-8 if it isn't already */ if (output_conv.vc_type != CONV_NONE) { - convbuf = string_convert(&output_conv, msg, NULL); + convbuf = string_convert(&output_conv, text, NULL); if (convbuf != NULL) - msg = convbuf; + text = convbuf; } /* First let's see how much we need to allocate */ len = 0; - for (p = msg; *p != NUL; p += charlen) + for (p = text; *p != NUL; p += charlen) { if ((*p & 0x80) == 0) /* be quick for ASCII */ { @@ -992,7 +992,7 @@ (unsigned long)pixel, &color); pdest = buf; - p = msg; + p = text; while (*p != NUL) { /* Be quick for ASCII */ diff -Naur vim70.orig/src/gui.c vim70/src/gui.c --- vim70.orig/src/gui.c 2006-05-03 04:00:59.000000000 -0700 +++ vim70/src/gui.c 2006-12-05 19:58:06.000000000 -0800 @@ -187,9 +187,10 @@ #endif #ifdef FEAT_AUTOCMD - /* If the GUI started successfully, trigger the GUIEnter event */ - if (gui.in_use) - apply_autocmds(EVENT_GUIENTER, NULL, NULL, FALSE, curbuf); + /* If the GUI started successfully, trigger the GUIEnter event, otherwise + * the GUIFailed event. */ + apply_autocmds(gui.in_use ? EVENT_GUIENTER : EVENT_GUIFAILED, + NULL, NULL, FALSE, curbuf); #endif --recursive; @@ -636,6 +637,7 @@ #if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_MSWIN) \ || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(PROTO) +# define NEED_GUI_UPDATE_SCREEN 1 /* * Called when the GUI shell is closed by the user. If there are no changed * files Vim exits, otherwise there will be a dialog to ask the user what to @@ -664,8 +666,7 @@ exiting = FALSE; cmdmod = save_cmdmod; - setcursor(); /* position cursor */ - out_flush(); + gui_update_screen(); /* redraw, window may show changed buffer */ } #endif @@ -2872,6 +2873,9 @@ */ if ((State == NORMAL || State == NORMAL_BUSY || (State & INSERT)) && Y_2_ROW(y) >= topframe->fr_height +# ifdef FEAT_WINDOWS + + firstwin->w_winrow +# endif && button != MOUSE_DRAG # ifdef FEAT_MOUSESHAPE && !drag_status_line @@ -3733,6 +3737,12 @@ if (dont_scroll || input_available()) return; #endif +#ifdef FEAT_INS_EXPAND + /* Disallow scrolling the current window when the completion popup menu is + * visible. */ + if ((sb->wp == NULL || sb->wp == curwin) && pum_visible()) + return; +#endif #ifdef FEAT_RIGHTLEFT if (sb->wp == NULL && curwin->w_p_rl) @@ -4207,6 +4217,12 @@ updateWindow(wp); /* update window, status line, and cmdline */ } +#ifdef FEAT_INS_EXPAND + /* May need to redraw the popup menu. */ + if (pum_visible()) + pum_redraw(); +#endif + return (wp == curwin && !equalpos(curwin->w_cursor, old_cursor)); } @@ -4515,7 +4531,7 @@ int y; { win_T *wp; - char_u st[6]; + char_u st[8]; /* Ignore this while still starting up. */ if (!gui.in_use || gui.starting) @@ -4603,11 +4619,11 @@ /* Don't move the mouse when it's left or right of the Vim window */ if (x < 0 || x > Columns * gui.char_width) return; + if (y >= 0 # ifdef FEAT_WINDOWS - if (Y_2_ROW(y) >= tabline_height()) -# else - if (y >= 0) + && Y_2_ROW(y) >= tabline_height() # endif + ) wp = xy2win(x, y); if (wp != curwin && wp != NULL) /* If in other than current window */ { @@ -4807,6 +4823,7 @@ #endif #if defined(FIND_REPLACE_DIALOG) || defined(FEAT_SUN_WORKSHOP) \ + || defined(NEED_GUI_UPDATE_SCREEN) \ || defined(PROTO) /* * Update the current window and the screen. diff -Naur vim70.orig/src/gui_gtk.c vim70/src/gui_gtk.c --- vim70.orig/src/gui_gtk.c 2006-05-05 04:52:52.000000000 -0700 +++ vim70/src/gui_gtk.c 2006-12-05 19:58:10.000000000 -0800 @@ -957,15 +957,15 @@ get_menu_position(vimmenu_T *menu) { vimmenu_T *node; - int index = 0; + int idx = 0; for (node = menu->parent->children; node != menu; node = node->next) { g_return_val_if_fail(node != NULL, -1); - ++index; + ++idx; } - return index; + return idx; } #endif /* FEAT_TOOLBAR && HAVE_GTK2 */ @@ -1275,18 +1275,13 @@ title = CONVERT_TO_UTF8(title); # endif - /* Concatenate "initdir" and "dflt". */ + /* GTK has a bug, it only works with an absolute path. */ if (initdir == NULL || *initdir == NUL) mch_dirname(dirbuf, MAXPATHL); - else if (STRLEN(initdir) + 2 < MAXPATHL) - STRCPY(dirbuf, initdir); - else + else if (vim_FullName(initdir, dirbuf, MAXPATHL - 2, FALSE) == FAIL) dirbuf[0] = NUL; /* Always need a trailing slash for a directory. */ add_pathsep(dirbuf); - if (dflt != NULL && *dflt != NUL - && STRLEN(dirbuf) + 2 + STRLEN(dflt) < MAXPATHL) - STRCAT(dirbuf, dflt); /* If our pointer is currently hidden, then we should show it. */ gui_mch_mousehide(FALSE); @@ -1298,8 +1293,8 @@ GTK_WINDOW(gui.mainwin), saving ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN, - saving ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + saving ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fc), (const gchar *)dirbuf); @@ -1341,6 +1336,11 @@ else gtk_window_set_title(GTK_WINDOW(gui.filedlg), (const gchar *)title); + /* Concatenate "initdir" and "dflt". */ + if (dflt != NULL && *dflt != NUL + && STRLEN(dirbuf) + 2 + STRLEN(dflt) < MAXPATHL) + STRCAT(dirbuf, dflt); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(gui.filedlg), (const gchar *)dirbuf); # ifndef HAVE_GTK2 @@ -2127,7 +2127,7 @@ char **ync; /* "yes no cancel" */ char **buttons; int n_buttons = 0; - int index; + int idx; button_string = vim_strsave(button_string); /* must be writable */ if (button_string == NULL) @@ -2161,12 +2161,12 @@ * Well, apparently somebody changed his mind: with GTK 2.2.4 it works the * other way around... */ - for (index = 1; index <= n_buttons; ++index) + for (idx = 1; idx <= n_buttons; ++idx) { char *label; char_u *label8; - label = buttons[index - 1]; + label = buttons[idx - 1]; /* * Perform some guesswork to find appropriate stock items for the * buttons. We have to compare with a sample of the translated @@ -2188,7 +2188,7 @@ else if (button_equal(label, "Cancel")) label = GTK_STOCK_CANCEL; } label8 = CONVERT_TO_UTF8((char_u *)label); - gtk_dialog_add_button(dialog, (const gchar *)label8, index); + gtk_dialog_add_button(dialog, (const gchar *)label8, idx); CONVERT_TO_UTF8_FREE(label8); } diff -Naur vim70.orig/src/gui_gtk_x11.c vim70/src/gui_gtk_x11.c --- vim70.orig/src/gui_gtk_x11.c 2006-05-04 23:58:59.000000000 -0700 +++ vim70/src/gui_gtk_x11.c 2006-12-05 19:57:56.000000000 -0800 @@ -3233,12 +3233,12 @@ on_select_tab( GtkNotebook *notebook, GtkNotebookPage *page, - gint index, + gint idx, gpointer data) { if (!ignore_tabline_evt) { - if (send_tabline_event(index + 1) && gtk_main_level() > 0) + if (send_tabline_event(idx + 1) && gtk_main_level() > 0) gtk_main_quit(); } } @@ -5303,13 +5303,13 @@ # ifdef HAVE_GTK2 if (font != NOFONT) { - char *name = pango_font_description_to_string(font); + char *pangoname = pango_font_description_to_string(font); - if (name != NULL) + if (pangoname != NULL) { - char_u *s = vim_strsave((char_u *)name); + char_u *s = vim_strsave((char_u *)pangoname); - g_free(name); + g_free(pangoname); return s; } } @@ -6241,24 +6241,20 @@ { GdkGCValues values; GdkGC *invert_gc; - GdkColor foreground; - GdkColor background; if (gui.drawarea->window == NULL) return; - foreground.pixel = gui.norm_pixel ^ gui.back_pixel; - background.pixel = gui.norm_pixel ^ gui.back_pixel; - - values.foreground = foreground; - values.background = background; + values.foreground.pixel = gui.norm_pixel ^ gui.back_pixel; + values.background.pixel = gui.norm_pixel ^ gui.back_pixel; values.function = GDK_XOR; invert_gc = gdk_gc_new_with_values(gui.drawarea->window, &values, GDK_GC_FOREGROUND | GDK_GC_BACKGROUND | GDK_GC_FUNCTION); - gdk_gc_set_exposures(invert_gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED); + gdk_gc_set_exposures(invert_gc, gui.visibility != + GDK_VISIBILITY_UNOBSCURED); gdk_draw_rectangle(gui.drawarea->window, invert_gc, TRUE, FILL_X(c), FILL_Y(r), diff -Naur vim70.orig/src/gui_xmebw.c vim70/src/gui_xmebw.c --- vim70.orig/src/gui_xmebw.c 2006-04-30 08:32:32.000000000 -0700 +++ vim70/src/gui_xmebw.c 2006-12-05 19:58:10.000000000 -0800 @@ -47,13 +47,13 @@ #include "gui_xmebwp.h" /* Provide some missing wrappers, which are missed from the LessTif - * implementation. + * implementation. Also missing in Motif 1.2 and earlier. * * We neither use XmeGetPixmapData or _XmGetPixmapData, since with LessTif the * pixmap will not appear in it's caches properly. We cache the interresting * values in XmEnhancedButtonPart instead ourself. */ -#ifdef LESSTIF_VERSION +#if defined(LESSTIF_VERSION) || (XmVersion <= 1002) # ifndef Lab_IsMenupane # define Lab_IsMenupane(w) (Lab_MenuType(w) == (int)XmMENU_POPUP || \ Lab_MenuType(w) == (int)XmMENU_PULLDOWN) @@ -138,6 +138,19 @@ } }; +/* This is needed to work around a bug in Lesstif 2, leaving the extension + * NULL somehow results in getting it set to an invalid pointer. */ +XmPrimitiveClassExtRec xmEnhancedButtonPrimClassExtRec = +{ + /* next_extension */ NULL, + /* record_type */ NULLQUARK, + /* version */ XmPrimitiveClassExtVersion, + /* record_size */ sizeof(XmPrimitiveClassExtRec), + /* widget_baseline */ XmInheritBaselineProc, + /* widget_display_rect */ XmInheritDisplayRectProc, + /* widget_margins */ NULL +}; + XmEnhancedButtonClassRec xmEnhancedButtonClassRec = { { @@ -184,7 +197,7 @@ /* arm and activate */ XmInheritArmAndActivate, /* synthetic resources */ NULL, /* number of syn res */ 0, - /* extension */ NULL, + /* extension */ (XtPointer)&xmEnhancedButtonPrimClassExtRec, }, /* label_class fields */ @@ -480,7 +493,7 @@ || (eb->core.height <= 2 * eb->primitive.highlight_thickness)) return; -#ifndef LESSTIF_VERSION +#if !defined(LESSTIF_VERSION) && (XmVersion > 1002) { XmDisplay dpy; @@ -641,7 +654,7 @@ GC tmp_gc = NULL; Boolean replaceGC = False; Boolean deadjusted = False; -#ifndef LESSTIF_VERSION +#if !defined(LESSTIF_VERSION) && (XmVersion > 1002) XmDisplay dpy = (XmDisplay)XmGetXmDisplay(XtDisplay(eb)); Boolean etched_in = dpy->display.enable_etched_in_menu; #else @@ -726,7 +739,7 @@ if ((((ShellWidget) XtParent(XtParent(eb)))->shell.popped_up) && _XmGetInDragMode((Widget) eb)) { -#ifndef LESSTIF_VERSION +#if !defined(LESSTIF_VERSION) && (XmVersion > 1002) XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(wid)); Boolean etched_in = dpy->display.enable_etched_in_menu; #else @@ -810,7 +823,7 @@ if (Lab_IsMenupane(eb)) { -#ifndef LESSTIF_VERSION +#if !defined(LESSTIF_VERSION) && (XmVersion > 1002) XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(wid)); Boolean etched_in = dpy->display.enable_etched_in_menu; #else @@ -1150,7 +1163,7 @@ Redisplay(Widget w, XEvent *event, Region region) { XmEnhancedButtonWidget eb = (XmEnhancedButtonWidget) w; -#ifndef LESSTIF_VERSION +#if !defined(LESSTIF_VERSION) && (XmVersion > 1002) XmDisplay dpy; XtEnum default_button_emphasis; #endif @@ -1162,7 +1175,7 @@ if (!XtIsRealized((Widget)eb)) return; -#ifndef LESSTIF_VERSION +#if !defined(LESSTIF_VERSION) && (XmVersion > 1002) dpy = (XmDisplay)XmGetXmDisplay(XtDisplay(eb)); default_button_emphasis = dpy->display.default_button_emphasis; #endif @@ -1241,7 +1254,7 @@ { int adjust = 0; -#ifndef LESSTIF_VERSION +#if !defined(LESSTIF_VERSION) && (XmVersion > 1002) /* * NOTE: PushButton has two types of shadows: primitive-shadow and * default-button-shadow. If pushbutton is in a menu only primitive @@ -1289,7 +1302,7 @@ adjust, adjust, rectwidth, rectheight, borderwidth); } -#ifndef LESSTIF_VERSION +#if !defined(LESSTIF_VERSION) && (XmVersion > 1002) switch (default_button_emphasis) { case XmINTERNAL_HIGHLIGHT: @@ -1365,7 +1378,7 @@ default_button_shadow_thickness = eb->pushbutton.default_button_shadow_thickness; -#ifndef LESSTIF_VERSION +#if !defined(LESSTIF_VERSION) && (XmVersion > 1002) /* * Compute location of bounding box to contain the * defaultButtonShadow. diff -Naur vim70.orig/src/hardcopy.c vim70/src/hardcopy.c --- vim70.orig/src/hardcopy.c 2006-05-04 03:09:58.000000000 -0700 +++ vim70/src/hardcopy.c 2006-12-05 19:57:56.000000000 -0800 @@ -1794,29 +1794,27 @@ static int prt_resfile_next_line() { - int index; + int idx; /* Move to start of next line and then find end of line */ - index = prt_resfile.line_end + 1; - while (index < prt_resfile.len) + idx = prt_resfile.line_end + 1; + while (idx < prt_resfile.len) { - if (prt_resfile.buffer[index] != PSLF && prt_resfile.buffer[index] - != PSCR) + if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR) break; - index++; + idx++; } - prt_resfile.line_start = index; + prt_resfile.line_start = idx; - while (index < prt_resfile.len) + while (idx < prt_resfile.len) { - if (prt_resfile.buffer[index] == PSLF || prt_resfile.buffer[index] - == PSCR) + if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR) break; - index++; + idx++; } - prt_resfile.line_end = index; + prt_resfile.line_end = idx; - return (index < prt_resfile.len); + return (idx < prt_resfile.len); } static int @@ -1837,14 +1835,14 @@ prt_resfile_skip_nonws(offset) int offset; { - int index; + int idx; - index = prt_resfile.line_start + offset; - while (index < prt_resfile.line_end) + idx = prt_resfile.line_start + offset; + while (idx < prt_resfile.line_end) { - if (isspace(prt_resfile.buffer[index])) - return index - prt_resfile.line_start; - index++; + if (isspace(prt_resfile.buffer[idx])) + return idx - prt_resfile.line_start; + idx++; } return -1; } @@ -1853,14 +1851,14 @@ prt_resfile_skip_ws(offset) int offset; { - int index; + int idx; - index = prt_resfile.line_start + offset; - while (index < prt_resfile.line_end) + idx = prt_resfile.line_start + offset; + while (idx < prt_resfile.line_end) { - if (!isspace(prt_resfile.buffer[index])) - return index - prt_resfile.line_start; - index++; + if (!isspace(prt_resfile.buffer[idx])) + return idx - prt_resfile.line_start; + idx++; } return -1; } @@ -2478,7 +2476,7 @@ char_u *p_encoding; struct prt_ps_encoding_S *p_mbenc; struct prt_ps_encoding_S *p_mbenc_first; - struct prt_ps_charset_S *p_mbchar; + struct prt_ps_charset_S *p_mbchar = NULL; #endif #if 0 @@ -2516,7 +2514,6 @@ if (!(props & ENC_8BIT) && ((*p_pmcs != NUL) || !(props & ENC_UNICODE))) { p_mbenc_first = NULL; - p_mbchar = NULL; for (cmap = 0; cmap < NUM_ELEMENTS(prt_ps_mbfonts); cmap++) if (prt_match_encoding((char *)p_encoding, &prt_ps_mbfonts[cmap], &p_mbenc)) diff -Naur vim70.orig/src/if_cscope.c vim70/src/if_cscope.c --- vim70.orig/src/if_cscope.c 2006-04-18 01:54:15.000000000 -0700 +++ vim70/src/if_cscope.c 2006-12-05 19:58:12.000000000 -0800 @@ -989,8 +989,7 @@ { int i; char *cmd; - char **matches, **contexts; - int nummatches[CSCOPE_MAX_CONNECTIONS], totmatches, matched; + int nummatches[CSCOPE_MAX_CONNECTIONS], totmatches; #ifdef FEAT_QUICKFIX char cmdletter; char *qfpos; @@ -1009,7 +1008,7 @@ totmatches = 0; for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) { - if (csinfo[i].fname == NULL) + if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL) continue; /* send cmd to cscope */ @@ -1101,38 +1100,44 @@ if (qfpos != NULL && *qfpos != '0' && totmatches > 0) { /* fill error list */ - FILE *f; - char_u *tmp = vim_tempname('c'); + FILE *f; + char_u *tmp = vim_tempname('c'); qf_info_T *qi = NULL; win_T *wp = NULL; f = mch_fopen((char *)tmp, "w"); - cs_file_results(f, nummatches); - fclose(f); - if (use_ll) /* Use location list */ - wp = curwin; - /* '-' starts a new error list */ - if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m", *qfpos == '-') > 0) + if (f == NULL) + EMSG2(_(e_notopen), tmp); + else { -# ifdef FEAT_WINDOWS - if (postponed_split != 0) + cs_file_results(f, nummatches); + fclose(f); + if (use_ll) /* Use location list */ + wp = curwin; + /* '-' starts a new error list */ + if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m", + *qfpos == '-') > 0) { - win_split(postponed_split > 0 ? postponed_split : 0, +# ifdef FEAT_WINDOWS + if (postponed_split != 0) + { + win_split(postponed_split > 0 ? postponed_split : 0, postponed_split_flags); # ifdef FEAT_SCROLLBIND - curwin->w_p_scb = FALSE; + curwin->w_p_scb = FALSE; # endif - postponed_split = 0; - } + postponed_split = 0; + } # endif - if (use_ll) - /* - * In the location list window, use the displayed location - * list. Otherwise, use the location list for the window. - */ - qi = (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL) ? - wp->w_llist_ref : wp->w_llist; - qf_jump(qi, 0, 0, forceit); + if (use_ll) + /* + * In the location list window, use the displayed location + * list. Otherwise, use the location list for the window. + */ + qi = (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL) + ? wp->w_llist_ref : wp->w_llist; + qf_jump(qi, 0, 0, forceit); + } } mch_remove(tmp); vim_free(tmp); @@ -1141,6 +1146,9 @@ else #endif /* FEAT_QUICKFIX */ { + char **matches = NULL, **contexts = NULL; + int matched = 0; + /* read output */ cs_fill_results((char *)pat, totmatches, nummatches, &matches, &contexts, &matched); @@ -1721,7 +1729,7 @@ continue; context = (char *)alloc((unsigned)strlen(cntx)+5); - if (context==NULL) + if (context == NULL) continue; if (strcmp(cntx, "")==0) @@ -1729,7 +1737,7 @@ else sprintf(context, "<<%s>>", cntx); - if (search==NULL) + if (search == NULL) fprintf(f, "%s\t%s\t%s\n", fullname, slno, context); else fprintf(f, "%s\t%s\t%s %s\n", fullname, slno, context, search); diff -Naur vim70.orig/src/if_perl.xs vim70/src/if_perl.xs --- vim70.orig/src/if_perl.xs 2006-03-06 10:57:16.000000000 -0800 +++ vim70/src/if_perl.xs 2006-12-05 19:57:54.000000000 -0800 @@ -155,8 +155,8 @@ static int (*perl_run)(PerlInterpreter*); static int (*perl_parse)(PerlInterpreter*, XSINIT_t, int, char**, char**); static void* (*Perl_get_context)(void); -static void (*Perl_croak)(pTHX_ const char*, ...) __attribute__((noreturn)); -static void (*Perl_croak_nocontext)(const char*, ...) __attribute__((noreturn)); +static void (*Perl_croak)(pTHX_ const char*, ...); +static void (*Perl_croak_nocontext)(const char*, ...); static I32 (*Perl_dowantarray)(pTHX); static void (*Perl_free_tmps)(pTHX); static HV* (*Perl_gv_stashpv)(pTHX_ const char*, I32); @@ -1056,7 +1056,6 @@ int i; long lnum; char *line; - buf_T *savebuf; PPCODE: if (buf_valid(vimbuf)) { @@ -1069,14 +1068,20 @@ line = SvPV(ST(i),PL_na); if (lnum > 0 && lnum <= vimbuf->b_ml.ml_line_count && line != NULL) { - savebuf = curbuf; - curbuf = vimbuf; + aco_save_T aco; + + /* set curwin/curbuf for "vimbuf" and save some things */ + aucmd_prepbuf(&aco, vimbuf); + if (u_savesub(lnum) == OK) { ml_replace(lnum, (char_u *)line, TRUE); changed_bytes(lnum, 0); } - curbuf = savebuf; + + /* restore curwin/curbuf and a few other things */ + aucmd_restbuf(&aco); + /* Careful: autocommands may have made "vimbuf" invalid! */ } } } @@ -1087,7 +1092,6 @@ PREINIT: long i, lnum = 0, count = 0; - buf_T *savebuf; PPCODE: if (buf_valid(vimbuf)) { @@ -1114,16 +1118,23 @@ { if (lnum > 0 && lnum <= vimbuf->b_ml.ml_line_count) { - savebuf = curbuf; - curbuf = vimbuf; + aco_save_T aco; + + /* set curwin/curbuf for "vimbuf" and save some things */ + aucmd_prepbuf(&aco, vimbuf); + if (u_savedel(lnum, 1) == OK) { ml_delete(lnum, 0); deleted_lines_mark(lnum, 1L); - if (savebuf == curbuf) + if (aco.save_buf == curbuf) check_cursor(); } - curbuf = savebuf; + + /* restore curwin/curbuf and a few other things */ + aucmd_restbuf(&aco); + /* Careful: autocommands may have made "vimbuf" invalid! */ + update_curbuf(VALID); } } @@ -1138,7 +1149,6 @@ int i; long lnum; char *line; - buf_T *savebuf; PPCODE: if (buf_valid(vimbuf)) { @@ -1151,14 +1161,21 @@ line = SvPV(ST(i),PL_na); if (lnum >= 0 && lnum <= vimbuf->b_ml.ml_line_count && line != NULL) { - savebuf = curbuf; - curbuf = vimbuf; + aco_save_T aco; + + /* set curwin/curbuf for "vimbuf" and save some things */ + aucmd_prepbuf(&aco, vimbuf); + if (u_inssub(lnum + 1) == OK) { ml_append(lnum, (char_u *)line, (colnr_T)0, FALSE); appended_lines_mark(lnum, 1L); } - curbuf = savebuf; + + /* restore curwin/curbuf and a few other things */ + aucmd_restbuf(&aco); + /* Careful: autocommands may have made "vimbuf" invalid! */ + update_curbuf(VALID); } } diff -Naur vim70.orig/src/if_python.c vim70/src/if_python.c --- vim70.orig/src/if_python.c 2006-04-30 08:31:36.000000000 -0700 +++ vim70/src/if_python.c 2006-12-05 19:58:04.000000000 -0800 @@ -1463,7 +1463,7 @@ if (this->buf && this->buf != INVALID_BUFFER_VALUE) this->buf->b_python_ref = NULL; - PyMem_DEL(self); + Py_DECREF(self); } static PyObject * @@ -1674,7 +1674,7 @@ bufr = (BufferObject *)BufferNew(buf); if (bufr == NULL) { - PyMem_DEL(self); + Py_DECREF(self); return NULL; } Py_INCREF(bufr); @@ -1690,7 +1690,7 @@ RangeDestructor(PyObject *self) { Py_DECREF(((RangeObject *)(self))->buf); - PyMem_DEL(self); + Py_DECREF(self); } static PyObject * @@ -1944,7 +1944,7 @@ if (this->win && this->win != INVALID_WINDOW_VALUE) this->win->w_python_ref = NULL; - PyMem_DEL(self); + Py_DECREF(self); } static int diff -Naur vim70.orig/src/if_ruby.c vim70/src/if_ruby.c --- vim70.orig/src/if_ruby.c 2006-04-30 08:37:52.000000000 -0700 +++ vim70/src/if_ruby.c 2006-12-05 19:57:54.000000000 -0800 @@ -643,11 +643,14 @@ static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str) { - buf_T *savebuf = curbuf; - char *line = STR2CSTR(str); + char *line = STR2CSTR(str); + aco_save_T aco; + + if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL) + { + /* set curwin/curbuf for "buf" and save some things */ + aucmd_prepbuf(&aco, buf); - if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL) { - curbuf = buf; if (u_savesub(n) == OK) { ml_replace(n, (char_u *)line, TRUE); changed(); @@ -655,10 +658,15 @@ syn_changed(n); /* recompute syntax hl. for this line */ #endif } - curbuf = savebuf; + + /* restore curwin/curbuf and a few other things */ + aucmd_restbuf(&aco); + /* Careful: autocommands may have made "buf" invalid! */ + update_curbuf(NOT_VALID); } - else { + else + { rb_raise(rb_eIndexError, "index %d out of buffer", n); return Qnil; /* For stop warning */ } @@ -676,12 +684,15 @@ static VALUE buffer_delete(VALUE self, VALUE num) { - buf_T *buf = get_buf(self); - buf_T *savebuf = curbuf; - long n = NUM2LONG(num); + buf_T *buf = get_buf(self); + long n = NUM2LONG(num); + aco_save_T aco; + + if (n > 0 && n <= buf->b_ml.ml_line_count) + { + /* set curwin/curbuf for "buf" and save some things */ + aucmd_prepbuf(&aco, buf); - if (n > 0 && n <= buf->b_ml.ml_line_count) { - curbuf = buf; if (u_savedel(n, 1) == OK) { ml_delete(n, 0); @@ -691,10 +702,15 @@ changed(); } - curbuf = savebuf; + + /* restore curwin/curbuf and a few other things */ + aucmd_restbuf(&aco); + /* Careful: autocommands may have made "buf" invalid! */ + update_curbuf(NOT_VALID); } - else { + else + { rb_raise(rb_eIndexError, "index %d out of buffer", n); } return Qnil; @@ -702,13 +718,16 @@ static VALUE buffer_append(VALUE self, VALUE num, VALUE str) { - buf_T *buf = get_buf(self); - buf_T *savebuf = curbuf; - char *line = STR2CSTR(str); - long n = NUM2LONG(num); + buf_T *buf = get_buf(self); + char *line = STR2CSTR(str); + long n = NUM2LONG(num); + aco_save_T aco; + + if (n >= 0 && n <= buf->b_ml.ml_line_count && line != NULL) + { + /* set curwin/curbuf for "buf" and save some things */ + aucmd_prepbuf(&aco, buf); - if (n >= 0 && n <= buf->b_ml.ml_line_count && line != NULL) { - curbuf = buf; if (u_inssub(n + 1) == OK) { ml_append(n, (char_u *) line, (colnr_T) 0, FALSE); @@ -718,7 +737,11 @@ changed(); } - curbuf = savebuf; + + /* restore curwin/curbuf and a few other things */ + aucmd_restbuf(&aco); + /* Careful: autocommands may have made "buf" invalid! */ + update_curbuf(NOT_VALID); } else { diff -Naur vim70.orig/src/macros.h vim70/src/macros.h --- vim70.orig/src/macros.h 2006-03-01 04:01:10.000000000 -0800 +++ vim70/src/macros.h 2006-12-05 19:58:00.000000000 -0800 @@ -276,3 +276,9 @@ # define MB_CHARLEN(p) STRLEN(p) # define PTR2CHAR(p) ((int)*(p)) #endif + +#ifdef FEAT_AUTOCHDIR +# define DO_AUTOCHDIR if (p_acd) do_autochdir(); +#else +# define DO_AUTOCHDIR +#endif diff -Naur vim70.orig/src/main.c vim70/src/main.c --- vim70.orig/src/main.c 2006-05-03 10:36:44.000000000 -0700 +++ vim70/src/main.c 2006-12-05 19:58:11.000000000 -0800 @@ -564,7 +564,11 @@ */ if (p_lpl) { +# ifdef VMS /* Somehow VMS doesn't handle the "**". */ + source_runtime((char_u *)"plugin/*.vim", TRUE); +# else source_runtime((char_u *)"plugin/**/*.vim", TRUE); +# endif TIME_MSG("loading plugins"); } #endif @@ -1126,6 +1130,16 @@ */ update_curswant(); +#ifdef FEAT_EVAL + /* + * May perform garbage collection when waiting for a character, but + * only at the very toplevel. Otherwise we may be using a List or + * Dict internally somewhere. + * "may_garbage_collect" is reset in vgetc() which is invoked through + * do_exmode() and normal_cmd(). + */ + may_garbage_collect = (!cmdwin && !noexmode); +#endif /* * If we're invoked as ex, do a round of ex commands. * Otherwise, get and execute a normal mode command. @@ -2281,7 +2295,7 @@ mparm_T *parmp; { #ifdef FEAT_WINDOWS - int rewind; + int dorewind; int done = 0; /* @@ -2338,10 +2352,10 @@ ++autocmd_no_leave; #endif #ifdef FEAT_WINDOWS - rewind = TRUE; + dorewind = TRUE; while (done++ < 1000) { - if (rewind) + if (dorewind) { if (parmp->window_layout == WIN_TABS) goto_tabpage(1); @@ -2360,7 +2374,7 @@ break; curwin = curwin->w_next; } - rewind = FALSE; + dorewind = FALSE; #endif curbuf = curwin->w_buffer; if (curbuf->b_ml.ml_mfp == NULL) @@ -2378,10 +2392,26 @@ (void)open_buffer(FALSE, NULL); /* create memfile, read file */ #if defined(HAS_SWAP_EXISTS_ACTION) - check_swap_exists_action(); + if (swap_exists_action == SEA_QUIT) + { + if (got_int || only_one_window()) + { + /* abort selected or quit and only one window */ + did_emsg = FALSE; /* avoid hit-enter prompt */ + getout(1); + } + /* We can't close the window, it would disturb what + * happens next. Clear the file name and set the arg + * index to -1 to delete it later. */ + setfname(curbuf, NULL, NULL, FALSE); + curwin->w_arg_idx = -1; + swap_exists_action = SEA_NONE; + } + else + handle_swap_exists(NULL); #endif #ifdef FEAT_AUTOCMD - rewind = TRUE; /* start again */ + dorewind = TRUE; /* start again */ #endif } #ifdef FEAT_WINDOWS @@ -2418,6 +2448,8 @@ { int arg_idx; /* index in argument list */ int i; + int advance = TRUE; + buf_T *old_curbuf; # ifdef FEAT_AUTOCMD /* @@ -2426,31 +2458,65 @@ ++autocmd_no_enter; ++autocmd_no_leave; # endif + + /* When w_arg_idx is -1 remove the window (see create_windows()). */ + if (curwin->w_arg_idx == -1) + { + win_close(curwin, TRUE); + advance = FALSE; + } + arg_idx = 1; for (i = 1; i < parmp->window_count; ++i) { - if (parmp->window_layout == WIN_TABS) + /* When w_arg_idx is -1 remove the window (see create_windows()). */ + if (curwin->w_arg_idx == -1) { - if (curtab->tp_next == NULL) /* just checking */ - break; - goto_tabpage(0); + ++arg_idx; + win_close(curwin, TRUE); + advance = FALSE; + continue; } - else + + if (advance) { - if (curwin->w_next == NULL) /* just checking */ - break; - win_enter(curwin->w_next, FALSE); + if (parmp->window_layout == WIN_TABS) + { + if (curtab->tp_next == NULL) /* just checking */ + break; + goto_tabpage(0); + } + else + { + if (curwin->w_next == NULL) /* just checking */ + break; + win_enter(curwin->w_next, FALSE); + } } + advance = TRUE; /* Only open the file if there is no file in this window yet (that can - * happen when .vimrc contains ":sall") */ + * happen when .vimrc contains ":sall"). */ if (curbuf == firstwin->w_buffer || curbuf->b_ffname == NULL) { curwin->w_arg_idx = arg_idx; - /* edit file from arg list, if there is one */ + /* Edit file from arg list, if there is one. When "Quit" selected + * at the ATTENTION prompt close the window. */ + old_curbuf = curbuf; (void)do_ecmd(0, arg_idx < GARGCOUNT ? alist_name(&GARGLIST[arg_idx]) : NULL, NULL, NULL, ECMD_LASTL, ECMD_HIDE); + if (curbuf == old_curbuf) + { + if (got_int || only_one_window()) + { + /* abort selected or quit and only one window */ + did_emsg = FALSE; /* avoid hit-enter prompt */ + getout(1); + } + win_close(curwin, TRUE); + advance = FALSE; + } if (arg_idx == GARGCOUNT - 1) arg_had_last = TRUE; ++arg_idx; @@ -3208,10 +3274,15 @@ * Register for remote command execution with :serversend and --remote * unless there was a -X or a --servername '' on the command line. * Only register nongui-vim's with an explicit --servername argument. + * When running as root --servername is also required. */ if (X_DISPLAY != NULL && parmp->servername != NULL && ( # ifdef FEAT_GUI - gui.in_use || + (gui.in_use +# ifdef UNIX + && getuid() != 0 +# endif + ) || # endif parmp->serverName_arg != NULL)) { diff -Naur vim70.orig/src/Makefile vim70/src/Makefile --- vim70.orig/src/Makefile 2006-05-07 06:25:27.000000000 -0700 +++ vim70/src/Makefile 2006-12-05 19:57:59.000000000 -0800 @@ -2177,6 +2177,7 @@ cd $(SHADOWDIR)/xxd; ln -s ../../xxd/*.[ch] ../../xxd/Make* . if test -d $(RSRC_DIR); then \ cd $(SHADOWDIR); \ + ln -s ../infplist.xml .; \ ln -s ../$(RSRC_DIR) ../os_mac.rsr.hqx ../dehqx.py .; \ fi mkdir $(SHADOWDIR)/testdir @@ -2260,7 +2261,7 @@ auto/osdef.h: auto/config.h osdef.sh osdef1.h.in osdef2.h.in CC="$(CC) $(OSDEF_CFLAGS)" srcdir=$(srcdir) sh $(srcdir)/osdef.sh -QUOTESED = sed -e 's/"/\\"/g' -e 's/\\"/"/' -e 's/\\";$$/";/' +QUOTESED = sed -e 's/[\\"]/\\&/g' -e 's/\\"/"/' -e 's/\\";$$/";/' auto/pathdef.c: Makefile auto/config.mk -@echo creating $@ -@echo '/* pathdef.c */' > $@ diff -Naur vim70.orig/src/mbyte.c vim70/src/mbyte.c --- vim70.orig/src/mbyte.c 2006-04-30 04:51:01.000000000 -0700 +++ vim70/src/mbyte.c 2006-12-05 19:58:39.000000000 -0800 @@ -311,7 +311,11 @@ #define IDX_MACROMAN 57 {"macroman", ENC_8BIT + ENC_MACROMAN, 0}, /* Mac OS */ -#define IDX_COUNT 58 +#define IDX_DECMCS 58 + {"dec-mcs", ENC_8BIT, 0}, /* DEC MCS */ +#define IDX_HPROMAN8 59 + {"hp-roman8", ENC_8BIT, 0}, /* HP Roman8 */ +#define IDX_COUNT 60 }; /* @@ -359,6 +363,8 @@ {"932", IDX_CP932}, {"949", IDX_CP949}, {"936", IDX_CP936}, + {"gbk", IDX_CP936}, + {"gb18030", IDX_CP936}, /* only 99% the same */ {"950", IDX_CP950}, {"eucjp", IDX_EUC_JP}, {"unix-jis", IDX_EUC_JP}, @@ -386,6 +392,7 @@ {"950", IDX_BIG5}, #endif {"mac", IDX_MACROMAN}, + {"mac-roman", IDX_MACROMAN}, {NULL, 0} }; @@ -2287,8 +2294,14 @@ } /* Check directly first, it's faster. */ for (j = 0; j < l; ++j) + { if (s1[i + j] != s2[i + j]) break; + if (s1[i + j] == 0) + /* Both stings have the same bytes but are incomplete or + * have illegal bytes, accept them as equal. */ + l = j; + } if (j < l) { /* If one of the two characters is incomplete return -1. */ @@ -3507,6 +3520,11 @@ add_to_input_buf(delkey, (int)sizeof(delkey)); } +/* + * Move the cursor left by "num_move_back" characters. + * Note that ins_left() checks im_is_preediting() to avoid breaking undo for + * these K_LEFT keys. + */ static void im_correct_cursor(int num_move_back) { @@ -3734,8 +3752,7 @@ } else if (cursor_index == 0 && preedit_string[0] == '\0') { - if (preedit_start_col == MAXCOL) - xim_has_preediting = FALSE; + xim_has_preediting = FALSE; /* If at the start position (after typing backspace) * preedit_start_col must be reset. */ @@ -3850,13 +3867,13 @@ if (preedit_string != NULL && attr_list != NULL) { - int index; + int idx; /* Get the byte index as used by PangoAttrIterator */ - for (index = 0; col > 0 && preedit_string[index] != '\0'; --col) - index += utfc_ptr2len((char_u *)preedit_string + index); + for (idx = 0; col > 0 && preedit_string[idx] != '\0'; --col) + idx += utfc_ptr2len((char_u *)preedit_string + idx); - if (preedit_string[index] != '\0') + if (preedit_string[idx] != '\0') { PangoAttrIterator *iter; int start, end; @@ -3869,7 +3886,7 @@ { pango_attr_iterator_range(iter, &start, &end); - if (index >= start && index < end) + if (idx >= start && idx < end) char_attr |= translate_pango_attributes(iter); } while (pango_attr_iterator_next(iter)); diff -Naur vim70.orig/src/memfile.c vim70/src/memfile.c --- vim70.orig/src/memfile.c 2006-03-06 00:59:15.000000000 -0800 +++ vim70/src/memfile.c 2006-12-05 19:58:11.000000000 -0800 @@ -517,7 +517,7 @@ mf_ins_free(mfp, hp); /* put *hp in the free list */ } -#if defined(__MORPHOS__) +#if defined(__MORPHOS__) && defined(__libnix__) /* function is missing in MorphOS libnix version */ extern unsigned long *__stdfiledes; @@ -677,15 +677,19 @@ # else # if defined(_DCC) || defined(__GNUC__) || defined(__MORPHOS__) { -# if defined(__GNUC__) && !defined(__MORPHOS__) +# if defined(__GNUC__) && !defined(__MORPHOS__) && defined(__libnix__) /* Have function (in libnix at least), * but ain't got no prototype anywhere. */ extern unsigned long fdtofh(int filedescriptor); # endif +# if !defined(__libnix__) + fflush(NULL); +# else BPTR fh = (BPTR)fdtofh(mfp->mf_fd); if (fh != 0) Flush(fh); +# endif } # else /* assume Manx */ Flush(_devtab[mfp->mf_fd].fd); @@ -1024,12 +1028,12 @@ size = page_size * hp->bh_page_count; if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) { - EMSG(_("E294: Seek error in swap file read")); + PERROR(_("E294: Seek error in swap file read")); return FAIL; } if ((unsigned)vim_read(mfp->mf_fd, hp->bh_data, size) != size) { - EMSG(_("E295: Read error in swap file")); + PERROR(_("E295: Read error in swap file")); return FAIL; } return OK; @@ -1081,7 +1085,7 @@ offset = (off_t)page_size * nr; if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) { - EMSG(_("E296: Seek error in swap file write")); + PERROR(_("E296: Seek error in swap file write")); return FAIL; } if (hp2 == NULL) /* freed block, fill with dummy data */ diff -Naur vim70.orig/src/memline.c vim70/src/memline.c --- vim70.orig/src/memline.c 2006-04-20 14:00:21.000000000 -0700 +++ vim70/src/memline.c 2006-12-05 19:58:12.000000000 -0800 @@ -215,7 +215,7 @@ #define ML_FLUSH 0x02 /* flush locked block */ #define ML_SIMPLE(x) (x & 0x10) /* DEL, INS or FIND */ -static void ml_upd_block0 __ARGS((buf_T *buf, int setfname)); +static void ml_upd_block0 __ARGS((buf_T *buf, int set_fname)); static void set_b0_fname __ARGS((ZERO_BL *, buf_T *buf)); static void set_b0_dir_flag __ARGS((ZERO_BL *b0p, buf_T *buf)); #ifdef FEAT_MBYTE @@ -679,9 +679,9 @@ * Update the timestamp or the B0_SAME_DIR flag of the .swp file. */ static void -ml_upd_block0(buf, setfname) +ml_upd_block0(buf, set_fname) buf_T *buf; - int setfname; + int set_fname; { memfile_T *mfp; bhdr_T *hp; @@ -695,7 +695,7 @@ EMSG(_("E304: ml_upd_block0(): Didn't get block 0??")); else { - if (setfname) + if (set_fname) set_b0_fname(b0p, buf); else set_b0_dir_flag(b0p, buf); @@ -1325,6 +1325,7 @@ mf_put(mfp, hp, FALSE, FALSE); mf_close(mfp, FALSE); /* will also vim_free(mfp->mf_fname) */ } + vim_free(buf->b_ml.ml_stack); vim_free(buf); if (serious_error && called_from_main) ml_close(curbuf, TRUE); @@ -1633,6 +1634,7 @@ int fd; struct block0 b0; time_t x = (time_t)0; + char *p; #ifdef UNIX char_u uname[B0_UNAME_SIZE]; #endif @@ -1652,8 +1654,11 @@ #endif MSG_PUTS(_(" dated: ")); x = st.st_mtime; /* Manx C can't do &st.st_mtime */ - MSG_PUTS(ctime(&x)); /* includes '\n' */ - + p = ctime(&x); /* includes '\n' */ + if (p == NULL) + MSG_PUTS("(invalid)\n"); + else + MSG_PUTS(p); } /* @@ -3652,6 +3657,7 @@ { struct stat st; time_t x, sx; + char *p; ++no_wait_return; (void)EMSG(_("E325: ATTENTION")); @@ -3666,7 +3672,11 @@ { MSG_PUTS(_(" dated: ")); x = st.st_mtime; /* Manx C can't do &st.st_mtime */ - MSG_PUTS(ctime(&x)); + p = ctime(&x); /* includes '\n' */ + if (p == NULL) + MSG_PUTS("(invalid)\n"); + else + MSG_PUTS(p); if (sx != 0 && x > sx) MSG_PUTS(_(" NEWER than swap file!\n")); } diff -Naur vim70.orig/src/menu.c vim70/src/menu.c --- vim70.orig/src/menu.c 2006-05-03 10:30:48.000000000 -0700 +++ vim70/src/menu.c 2006-12-05 19:58:28.000000000 -0800 @@ -511,6 +511,14 @@ * name (without mnemonic and accelerator text). */ next_name = menu_name_skip(name); dname = menu_text(name, NULL, NULL); + if (dname == NULL) + goto erret; + if (*dname == NUL) + { + /* Only a mnemonic or accelerator is not valid. */ + EMSG(_("E792: Empty menu name")); + goto erret; + } /* See if it's already there */ lower_pri = menup; @@ -704,6 +712,7 @@ parent = menu; name = next_name; vim_free(dname); + dname = NULL; if (pri_tab[pri_idx + 1] != -1) ++pri_idx; } @@ -793,6 +802,22 @@ erret: vim_free(path_name); vim_free(dname); + + /* Delete any empty submenu we added before discovering the error. Repeat + * for higher levels. */ + while (parent != NULL && parent->children == NULL) + { + if (parent->parent == NULL) + menup = &root_menu; + else + menup = &parent->parent->children; + for ( ; *menup != NULL && *menup != parent; menup = &((*menup)->next)) + ; + if (*menup == NULL) /* safety check */ + break; + parent = parent->parent; + free_menu(menup); + } return FAIL; } @@ -1753,6 +1778,27 @@ } /* + * Check that a pointer appears in the menu tree. Used to protect from using + * a menu that was deleted after it was selected but before the event was + * handled. + * Return OK or FAIL. Used recursively. + */ + int +check_menu_pointer(root, menu_to_check) + vimmenu_T *root; + vimmenu_T *menu_to_check; +{ + vimmenu_T *p; + + for (p = root; p != NULL; p = p->next) + if (p == menu_to_check + || (p->children != NULL + && check_menu_pointer(p->children, menu_to_check) == OK)) + return OK; + return FAIL; +} + +/* * After we have started the GUI, then we can create any menus that have been * defined. This is done once here. add_menu_path() may have already been * called to define these menus, and may be called again. This function calls @@ -2200,7 +2246,7 @@ { /* When executing a script or function execute the commands right now. * Otherwise put them in the typeahead buffer. */ -#ifdef FEAT_En +#ifdef FEAT_EVAL if (current_SID != 0) exec_normal_cmd(menu->strings[idx], menu->noremap[idx], menu->silent[idx]); diff -Naur vim70.orig/src/message.c vim70/src/message.c --- vim70.orig/src/message.c 2006-05-06 13:07:37.000000000 -0700 +++ vim70/src/message.c 2006-12-05 19:58:06.000000000 -0800 @@ -53,7 +53,6 @@ static struct msg_hist *first_msg_hist = NULL; static struct msg_hist *last_msg_hist = NULL; static int msg_hist_len = 0; -static int msg_hist_off = FALSE; /* don't add messages to history */ /* * When writing messages to the screen, there are many different situations. @@ -1925,7 +1924,8 @@ * If screen is completely filled and 'more' is set then wait * for a character. */ - if (p_more && --lines_left == 0 && State != HITRETURN + --lines_left; + if (p_more && lines_left == 0 && State != HITRETURN && !msg_no_more && !exmode_active) { #ifdef FEAT_CON_DIALOG @@ -4123,8 +4123,6 @@ case 'c': case 's': length_modifier = '\0'; - zero_padding = 0; /* turn zero padding off for string - conversions */ str_arg_l = 1; switch (fmt_spec) { @@ -4175,15 +4173,16 @@ str_arg_l = 0; else { - /* memchr on HP does not like n > 2^31 !!! */ - char *q = memchr(str_arg, '\0', + /* Don't put the #if inside memchr(), it can be a + * macro. */ #if SIZEOF_INT <= 2 - precision + char *q = memchr(str_arg, '\0', precision); #else - precision <= (size_t)0x7fffffffL ? precision - : (size_t)0x7fffffffL + /* memchr on HP does not like n > 2^31 !!! */ + char *q = memchr(str_arg, '\0', + precision <= (size_t)0x7fffffffL ? precision + : (size_t)0x7fffffffL); #endif - ); str_arg_l = (q == NULL) ? precision : q - str_arg; } break; diff -Naur vim70.orig/src/misc1.c vim70/src/misc1.c --- vim70.orig/src/misc1.c 2006-04-30 08:30:02.000000000 -0700 +++ vim70/src/misc1.c 2006-12-05 19:58:10.000000000 -0800 @@ -1761,15 +1761,13 @@ * Add column offset for 'number', 'foldcolumn', etc. */ width = W_WIDTH(wp) - win_col_off(wp); - if (width > 0) - { - lines += 1; - if (col >= width) - lines += (col - width) / (width + win_col_off2(wp)); - if (lines <= wp->w_height) - return lines; - } - return (int)(wp->w_height); /* maximum length */ + if (width <= 0) + return 9999; + + lines += 1; + if (col > width) + lines += (col - width) / (width + win_col_off2(wp)) + 1; + return lines; } int @@ -2842,7 +2840,8 @@ #ifdef FEAT_AUTOCMD /* when the cursor line is changed always trigger CursorMoved */ - if (lnum <= curwin->w_cursor.lnum && lnume > curwin->w_cursor.lnum) + if (lnum <= curwin->w_cursor.lnum + && lnume + (xtra < 0 ? -xtra : xtra) > curwin->w_cursor.lnum) last_cursormoved.lnum = 0; #endif } @@ -3016,6 +3015,7 @@ int len = 0; int n; int save_mapped_ctrl_c = mapped_ctrl_c; + int waited = 0; mapped_ctrl_c = FALSE; /* mappings are not used here */ for (;;) @@ -3034,11 +3034,16 @@ /* Replace zero and CSI by a special key code. */ n = fix_input_buffer(buf + len, n, FALSE); len += n; + waited = 0; } + else if (len > 0) + ++waited; /* keep track of the waiting time */ - /* incomplete termcode: get more characters */ - if ((n = check_termcode(1, buf, len)) < 0) + /* Incomplete termcode and not timed out yet: get more characters */ + if ((n = check_termcode(1, buf, len)) < 0 + && (!p_ttimeout || waited * 100L < (p_ttm < 0 ? p_tm : p_ttm))) continue; + /* found a termcode: adjust length */ if (n > 0) len = n; @@ -3196,14 +3201,12 @@ else MSG_PUTS(_("Choice number ( cancels): ")); - /* Set the state such that text can be selected/copied/pasted. */ + /* Set the state such that text can be selected/copied/pasted and we still + * get mouse events. */ save_cmdline_row = cmdline_row; - cmdline_row = Rows - 1; + cmdline_row = 0; save_State = State; - if (mouse_used == NULL) - State = CMDLINE; - else - State = NORMAL; + State = CMDLINE; i = get_number(TRUE, mouse_used); if (KeyTyped) @@ -4492,7 +4495,7 @@ int l = mb_ptr2len(s); while (--l > 0) - *d++ = *s++; + *d++ = *++s; } # endif } @@ -8070,9 +8073,20 @@ } if (*that == '"' && *(that + 1) != NUL) { - that++; - while (*that && (*that != '"' || *(that - 1) == '\\')) - ++that; + while (*++that && *that != '"') + { + /* skipping escaped characters in the string */ + if (*that == '\\') + { + if (*++that == NUL) + break; + if (that[1] == NUL) + { + ++that; + break; + } + } + } } if (*that == '(' || *that == '[') ++parencount; diff -Naur vim70.orig/src/misc2.c vim70/src/misc2.c --- vim70.orig/src/misc2.c 2006-05-04 05:12:38.000000000 -0700 +++ vim70/src/misc2.c 2006-12-05 19:58:04.000000000 -0800 @@ -1229,6 +1229,94 @@ return escaped_string; } +#if defined(FEAT_EVAL) || defined(PROTO) +/* + * Escape "string" for use as a shell argument with system(). + * This uses single quotes, except when we know we need to use double qoutes + * (MS-DOS and MS-Windows without 'shellslash' set). + * Returns the result in allocated memory, NULL if we have run out. + */ + char_u * +vim_strsave_shellescape(string) + char_u *string; +{ + unsigned length; + char_u *p; + char_u *d; + char_u *escaped_string; + + /* First count the number of extra bytes required. */ + length = STRLEN(string) + 3; /* two quotes and the trailing NUL */ + for (p = string; *p != NUL; mb_ptr_adv(p)) + { +# if defined(WIN32) || defined(WIN16) || defined(DOS) + if (!p_ssl) + { + if (*p == '"') + ++length; /* " -> "" */ + } + else +# endif + if (*p == '\'') + length += 3; /* ' => '\'' */ + } + + /* Allocate memory for the result and fill it. */ + escaped_string = alloc(length); + if (escaped_string != NULL) + { + d = escaped_string; + + /* add opening quote */ +# if defined(WIN32) || defined(WIN16) || defined(DOS) + if (!p_ssl) + *d++ = '"'; + else +# endif + *d++ = '\''; + + for (p = string; *p != NUL; ) + { +# if defined(WIN32) || defined(WIN16) || defined(DOS) + if (!p_ssl) + { + if (*p == '"') + { + *d++ = '"'; + *d++ = '"'; + ++p; + continue; + } + } + else +# endif + if (*p == '\'') + { + *d++='\''; + *d++='\\'; + *d++='\''; + *d++='\''; + ++p; + continue; + } + + MB_COPY_CHAR(p, d); + } + + /* add terminating quote and finish with a NUL */ +# if defined(WIN32) || defined(WIN16) || defined(DOS) + if (!p_ssl) + *d++ = '"'; + else +# endif + *d++ = '\''; + *d = NUL; + } + + return escaped_string; +} +#endif + /* * Like vim_strsave(), but make all characters uppercase. * This uses ASCII lower-to-upper case translation, language independent. diff -Naur vim70.orig/src/netbeans.c vim70/src/netbeans.c --- vim70.orig/src/netbeans.c 2006-04-22 11:00:05.000000000 -0700 +++ vim70/src/netbeans.c 2006-12-05 19:58:11.000000000 -0800 @@ -61,7 +61,7 @@ /* The first implementation (working only with Netbeans) returned "1.1". The * protocol implemented here also supports A-A-P. */ -static char *ExtEdProtocolVersion = "2.3"; +static char *ExtEdProtocolVersion = "2.4"; static long pos2off __ARGS((buf_T *, pos_T *)); static pos_T *off2pos __ARGS((buf_T *, long)); @@ -103,7 +103,7 @@ static int inputHandler = -1; /* simply ret.value of WSAAsyncSelect() */ extern HWND s_hwnd; /* Gvim's Window handle */ #endif -static int cmdno; /* current command number for reply */ +static int r_cmdno; /* current command number for reply */ static int haveConnection = FALSE; /* socket is connected and initialization is done */ #ifdef FEAT_GUI_MOTIF @@ -832,11 +832,11 @@ return; } - cmdno = strtol(q, &q, 10); + r_cmdno = strtol(q, &q, 10); q = (char *)skipwhite((char_u *)q); - if (nb_do_cmd(bufno, (char_u *)verb, isfunc, cmdno, (char_u *)q) == FAIL) + if (nb_do_cmd(bufno, (char_u *)verb, isfunc, r_cmdno, (char_u *)q) == FAIL) { #ifdef NBDEBUG /* @@ -1008,11 +1008,11 @@ if (netbeansForcedQuit) { /* mark as unmodified so NetBeans won't put up dialog on "killed" */ - sprintf(buf, "%d:unmodified=%d\n", i, cmdno); + sprintf(buf, "%d:unmodified=%d\n", i, r_cmdno); nbdebug(("EVT: %s", buf)); nb_send(buf, "netbeans_end"); } - sprintf(buf, "%d:killed=%d\n", i, cmdno); + sprintf(buf, "%d:killed=%d\n", i, r_cmdno); nbdebug(("EVT: %s", buf)); /* nb_send(buf, "netbeans_end"); avoid "write failed" messages */ if (sd >= 0) @@ -1271,6 +1271,29 @@ nb_reply_text(cmdno, text); /* =====================================================================*/ } + else if (streq((char *)cmd, "getAnno")) + { + long linenum = 0; +#ifdef FEAT_SIGNS + if (buf == NULL || buf->bufp == NULL) + { + nbdebug((" null bufp in getAnno")); + EMSG("E652: null bufp in getAnno"); + retval = FAIL; + } + else + { + int serNum; + + cp = (char *)args; + serNum = strtol(cp, &cp, 10); + /* If the sign isn't found linenum will be zero. */ + linenum = (long)buf_findsign(buf->bufp, serNum); + } +#endif + nb_reply_nr(cmdno, linenum); +/* =====================================================================*/ + } else if (streq((char *)cmd, "getLength")) { long len = 0; @@ -1986,6 +2009,8 @@ if (buf->bufp != NULL) do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->bufp->b_fnum, TRUE); + buf->bufp = NULL; + buf->initDone = FALSE; doupdate = 1; /* =====================================================================*/ } @@ -2561,7 +2586,7 @@ if (p != NULL) { vim_snprintf(buf, sizeof(buf), - "0:balloonText=%d \"%s\"\n", cmdno, p); + "0:balloonText=%d \"%s\"\n", r_cmdno, p); vim_free(p); } nbdebug(("EVT: %s", buf)); @@ -2615,7 +2640,7 @@ if (haveConnection) { - sprintf(buf, "0:disconnect=%d\n", cmdno); + sprintf(buf, "0:disconnect=%d\n", r_cmdno); nbdebug(("EVT: %s", buf)); nb_send(buf, "netbeans_disconnect"); } @@ -2634,7 +2659,7 @@ return; sprintf(buf, "0:geometry=%d %d %d %d %d\n", - cmdno, (int)Columns, (int)Rows, new_x, new_y); + r_cmdno, (int)Columns, (int)Rows, new_x, new_y); /*nbdebug(("EVT: %s", buf)); happens too many times during a move */ nb_send(buf, "netbeans_frame_moved"); } @@ -2743,7 +2768,7 @@ if (bufno <= 0) return; - sprintf(buffer, "%d:killed=%d\n", bufno, cmdno); + sprintf(buffer, "%d:killed=%d\n", bufno, r_cmdno); nbdebug(("EVT: %s", buffer)); @@ -2817,7 +2842,8 @@ if (p != NULL) { buf = alloc(128 + 2*newlen); - sprintf((char *)buf, "%d:insert=%d %ld \"%s\"\n", bufno, cmdno, off, p); + sprintf((char *)buf, "%d:insert=%d %ld \"%s\"\n", + bufno, r_cmdno, off, p); nbdebug(("EVT: %s", buf)); nb_send((char *)buf, "netbeans_inserted"); vim_free(p); @@ -2859,7 +2885,7 @@ off = pos2off(bufp, &pos); - sprintf((char *)buf, "%d:remove=%d %ld %ld\n", bufno, cmdno, off, len); + sprintf((char *)buf, "%d:remove=%d %ld %ld\n", bufno, r_cmdno, off, len); nbdebug(("EVT: %s", buf)); nb_send((char *)buf, "netbeans_removed"); } @@ -2884,7 +2910,7 @@ nbbuf->modified = 0; - sprintf((char *)buf, "%d:unmodified=%d\n", bufno, cmdno); + sprintf((char *)buf, "%d:unmodified=%d\n", bufno, r_cmdno); nbdebug(("EVT: %s", buf)); nb_send((char *)buf, "netbeans_unmodified"); #endif @@ -2908,11 +2934,11 @@ long off = pos2off(curbuf, &curwin->w_cursor); /* sync the cursor position */ - sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, cmdno, off, off); + sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, r_cmdno, off, off); nbdebug(("EVT: %s", buf)); nb_send(buf, "netbeans_button_release[newDotAndMark]"); - sprintf(buf, "%d:buttonRelease=%d %d %ld %d\n", bufno, cmdno, + sprintf(buf, "%d:buttonRelease=%d %d %ld %d\n", bufno, r_cmdno, button, (long)curwin->w_cursor.lnum, col); nbdebug(("EVT: %s", buf)); nb_send(buf, "netbeans_button_release"); @@ -2973,7 +2999,7 @@ /* sync the cursor position */ off = pos2off(curbuf, &curwin->w_cursor); - sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, cmdno, off, off); + sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, r_cmdno, off, off); nbdebug(("EVT: %s", buf)); nb_send(buf, "netbeans_keycommand"); @@ -2984,13 +3010,13 @@ /* now send keyCommand event */ vim_snprintf(buf, sizeof(buf), "%d:keyCommand=%d \"%s\"\n", - bufno, cmdno, keyName); + bufno, r_cmdno, keyName); nbdebug(("EVT: %s", buf)); nb_send(buf, "netbeans_keycommand"); /* New: do both at once and include the lnum/col. */ vim_snprintf(buf, sizeof(buf), "%d:keyAtPos=%d \"%s\" %ld %ld/%ld\n", - bufno, cmdno, keyName, + bufno, r_cmdno, keyName, off, (long)curwin->w_cursor.lnum, (long)curwin->w_cursor.col); nbdebug(("EVT: %s", buf)); nb_send(buf, "netbeans_keycommand"); @@ -3013,7 +3039,7 @@ nbbuf->modified = 0; - sprintf((char *)buf, "%d:save=%d\n", bufno, cmdno); + sprintf((char *)buf, "%d:save=%d\n", bufno, r_cmdno); nbdebug(("EVT: %s", buf)); nb_send((char *)buf, "netbeans_save_buffer"); } @@ -3037,7 +3063,7 @@ if (nbbuf->insertDone) nbbuf->modified = 1; - sprintf((char *)buf, "%d:remove=%d 0 -1\n", bufno, cmdno); + sprintf((char *)buf, "%d:remove=%d 0 -1\n", bufno, r_cmdno); nbdebug(("EVT(suppressed): %s", buf)); /* nb_send(buf, "netbeans_deleted_all_lines"); */ } diff -Naur vim70.orig/src/normal.c vim70/src/normal.c --- vim70.orig/src/normal.c 2006-04-29 06:11:18.000000000 -0700 +++ vim70/src/normal.c 2006-12-05 19:58:33.000000000 -0800 @@ -651,9 +651,8 @@ /* Fake a "c"hange command. When "restart_edit" is set (e.g., because * 'insertmode' is set) fake a "d"elete command, Insert mode will * restart automatically. - * Insert the typed character in the typeahead buffer, so that it will - * be mapped in Insert mode. Required for ":lmap" to work. May cause - * mapping a character from ":vnoremap"... */ + * Insert the typed character in the typeahead buffer, so that it can + * be mapped in Insert mode. Required for ":lmap" to work. */ ins_char_typebuf(c); if (restart_edit != 0) c = 'd'; @@ -1477,14 +1476,17 @@ } else if (VIsual_active) { - /* Save the current VIsual area for '< and '> marks, and "gv" */ - curbuf->b_visual.vi_start = VIsual; - curbuf->b_visual.vi_end = curwin->w_cursor; - curbuf->b_visual.vi_mode = VIsual_mode; - curbuf->b_visual.vi_curswant = curwin->w_curswant; + if (!gui_yank) + { + /* Save the current VIsual area for '< and '> marks, and "gv" */ + curbuf->b_visual.vi_start = VIsual; + curbuf->b_visual.vi_end = curwin->w_cursor; + curbuf->b_visual.vi_mode = VIsual_mode; + curbuf->b_visual.vi_curswant = curwin->w_curswant; # ifdef FEAT_EVAL - curbuf->b_visual_mode_eval = VIsual_mode; + curbuf->b_visual_mode_eval = VIsual_mode; # endif + } /* In Select mode, a linewise selection is operated upon like a * characterwise selection. */ @@ -2377,11 +2379,20 @@ /* * If visual was active, yank the highlighted text and put it * before the mouse pointer position. + * In Select mode replace the highlighted text with the clipboard. */ if (VIsual_active) { - stuffcharReadbuff('y'); - stuffcharReadbuff(K_MIDDLEMOUSE); + if (VIsual_select) + { + stuffcharReadbuff(Ctrl_G); + stuffReadbuff((char_u *)"\"+p"); + } + else + { + stuffcharReadbuff('y'); + stuffcharReadbuff(K_MIDDLEMOUSE); + } do_always = TRUE; /* ignore 'mouse' setting next time */ return FALSE; } @@ -2504,7 +2515,8 @@ * NOTE: Ignore right button down and drag mouse events. * Windows only shows the popup menu on the button up event. */ -#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) +#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \ + || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) if (!is_click) return FALSE; #endif @@ -4126,7 +4138,7 @@ int save_p_ws; int save_p_scs; int retval = OK; - int incl; + int incll; if ((pat = alloc(len + 7)) == NULL) return FAIL; @@ -4146,7 +4158,7 @@ * With "gd" Search back for the start of the current function, then go * back until a blank line. If this fails go to line 1. */ - if (!locally || !findpar(&incl, BACKWARD, 1L, '{', FALSE)) + if (!locally || !findpar(&incll, BACKWARD, 1L, '{', FALSE)) { setpcmark(); /* Set in findpar() otherwise */ curwin->w_cursor.lnum = 1; @@ -8847,7 +8859,7 @@ #endif while (cap->count1-- && !got_int) { - if (do_execreg(cap->nchar, FALSE, FALSE) == FAIL) + if (do_execreg(cap->nchar, FALSE, FALSE, FALSE) == FAIL) { clearopbeep(cap->oap); break; diff -Naur vim70.orig/src/ops.c vim70/src/ops.c --- vim70.orig/src/ops.c 2006-04-30 08:13:44.000000000 -0700 +++ vim70/src/ops.c 2006-12-05 19:58:11.000000000 -0800 @@ -95,8 +95,8 @@ static void block_insert __ARGS((oparg_T *oap, char_u *s, int b_insert, struct block_def*bdp)); #endif static int stuff_yank __ARGS((int, char_u *)); -static void put_reedit_in_typebuf __ARGS((void)); -static int put_in_typebuf __ARGS((char_u *s, int colon)); +static void put_reedit_in_typebuf __ARGS((int silent)); +static int put_in_typebuf __ARGS((char_u *s, int colon, int silent)); static void stuffescaped __ARGS((char_u *arg, int literally)); #ifdef FEAT_MBYTE static void mb_adjust_opend __ARGS((oparg_T *oap)); @@ -770,6 +770,7 @@ { char_u *expr_copy; char_u *rv; + static int nested = 0; if (expr_line == NULL) return NULL; @@ -780,7 +781,14 @@ if (expr_copy == NULL) return NULL; + /* When we are invoked recursively limit the evaluation to 10 levels. + * Then return the string as-is. */ + if (nested >= 10) + return expr_copy; + + ++nested; rv = eval_to_string(expr_copy, NULL, TRUE); + --nested; vim_free(expr_copy); return rv; } @@ -1112,10 +1120,11 @@ * return FAIL for failure, OK otherwise */ int -do_execreg(regname, colon, addcr) +do_execreg(regname, colon, addcr, silent) int regname; int colon; /* insert ':' before each line */ int addcr; /* always add '\n' to end of line */ + int silent; /* set "silent" flag in typeahead buffer */ { static int lastc = NUL; long i; @@ -1165,9 +1174,9 @@ /* When in Visual mode "'<,'>" will be prepended to the command. * Remove it when it's already there. */ if (VIsual_active && STRNCMP(p, "'<,'>", 5) == 0) - retval = put_in_typebuf(p + 5, TRUE); + retval = put_in_typebuf(p + 5, TRUE, silent); else - retval = put_in_typebuf(p, TRUE); + retval = put_in_typebuf(p, TRUE, silent); } vim_free(p); } @@ -1178,7 +1187,7 @@ p = get_expr_line(); if (p == NULL) return FAIL; - retval = put_in_typebuf(p, colon); + retval = put_in_typebuf(p, colon, silent); vim_free(p); } #endif @@ -1190,7 +1199,7 @@ EMSG(_(e_noinstext)); return FAIL; } - retval = put_in_typebuf(p, colon); + retval = put_in_typebuf(p, colon, silent); vim_free(p); } else @@ -1205,20 +1214,20 @@ /* * Insert lines into typeahead buffer, from last one to first one. */ - put_reedit_in_typebuf(); + put_reedit_in_typebuf(silent); for (i = y_current->y_size; --i >= 0; ) { /* insert NL between lines and after last line if type is MLINE */ if (y_current->y_type == MLINE || i < y_current->y_size - 1 || addcr) { - if (ins_typebuf((char_u *)"\n", remap, 0, TRUE, FALSE) == FAIL) + if (ins_typebuf((char_u *)"\n", remap, 0, TRUE, silent) == FAIL) return FAIL; } - if (ins_typebuf(y_current->y_array[i], remap, 0, TRUE, FALSE) + if (ins_typebuf(y_current->y_array[i], remap, 0, TRUE, silent) == FAIL) return FAIL; - if (colon && ins_typebuf((char_u *)":", remap, 0, TRUE, FALSE) + if (colon && ins_typebuf((char_u *)":", remap, 0, TRUE, silent) == FAIL) return FAIL; } @@ -1232,7 +1241,8 @@ * used only after other typeahead has been processed. */ static void -put_reedit_in_typebuf() +put_reedit_in_typebuf(silent) + int silent; { char_u buf[3]; @@ -1249,25 +1259,26 @@ buf[0] = restart_edit == 'I' ? 'i' : restart_edit; buf[1] = NUL; } - if (ins_typebuf(buf, REMAP_NONE, 0, TRUE, FALSE) == OK) + if (ins_typebuf(buf, REMAP_NONE, 0, TRUE, silent) == OK) restart_edit = NUL; } } static int -put_in_typebuf(s, colon) +put_in_typebuf(s, colon, silent) char_u *s; int colon; /* add ':' before the line */ + int silent; { int retval = OK; - put_reedit_in_typebuf(); + put_reedit_in_typebuf(silent); if (colon) - retval = ins_typebuf((char_u *)"\n", REMAP_YES, 0, TRUE, FALSE); + retval = ins_typebuf((char_u *)"\n", REMAP_YES, 0, TRUE, silent); if (retval == OK) - retval = ins_typebuf(s, REMAP_YES, 0, TRUE, FALSE); + retval = ins_typebuf(s, REMAP_YES, 0, TRUE, silent); if (colon && retval == OK) - retval = ins_typebuf((char_u *)":", REMAP_YES, 0, TRUE, FALSE); + retval = ins_typebuf((char_u *)":", REMAP_YES, 0, TRUE, silent); return retval; } @@ -1472,9 +1483,10 @@ * return FAIL for failure, OK otherwise */ int -cmdline_paste_reg(regname, literally) +cmdline_paste_reg(regname, literally, remcr) int regname; int literally; /* Insert text literally instead of "as typed" */ + int remcr; /* don't add trailing CR */ { long i; @@ -1486,8 +1498,13 @@ { cmdline_paste_str(y_current->y_array[i], literally); - /* insert ^M between lines and after last line if type is MLINE */ - if (y_current->y_type == MLINE || i < y_current->y_size - 1) + /* Insert ^M between lines and after last line if type is MLINE. + * Don't do this when "remcr" is TRUE and the next line is empty. */ + if (y_current->y_type == MLINE + || (i < y_current->y_size - 1 + && !(remcr + && i == y_current->y_size - 2 + && *y_current->y_array[i + 1] == NUL))) cmdline_paste_str((char_u *)"\r", literally); /* Check for CTRL-C, in case someone tries to paste a few thousand @@ -2413,6 +2430,7 @@ else { curwin->w_cursor = oap->end; + check_cursor_col(); /* Works just like an 'i'nsert on the next character. */ if (!lineempty(curwin->w_cursor.lnum) @@ -3492,8 +3510,15 @@ # endif if (flags & PUT_CURSEND) { + colnr_T len; + curwin->w_cursor = curbuf->b_op_end; curwin->w_cursor.col++; + + /* in Insert mode we might be after the NUL, correct for that */ + len = (colnr_T)STRLEN(ml_get_curline()); + if (curwin->w_cursor.col > len) + curwin->w_cursor.col = len; } else curwin->w_cursor.lnum = lnum; diff -Naur vim70.orig/src/option.c vim70/src/option.c --- vim70.orig/src/option.c 2006-05-03 10:32:28.000000000 -0700 +++ vim70/src/option.c 2006-12-05 19:58:09.000000000 -0800 @@ -2294,7 +2294,7 @@ {(char_u *)0L, (char_u *)0L} #endif }, - {"spellsuggest", "sps", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE, + {"spellsuggest", "sps", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE|P_COMMA, #ifdef FEAT_SPELL (char_u *)&p_sps, PV_NONE, {(char_u *)"best", (char_u *)0L} @@ -3397,7 +3397,7 @@ } else if (flags & P_NUM) { - if (varp == (char_u *)PV_SCROLL) + if (options[opt_idx].indir == PV_SCROLL) win_comp_scroll(curwin); else { @@ -5227,13 +5227,13 @@ case PV_STL: return &curwin->w_p_stl_flags; #endif #ifdef FEAT_EVAL +# ifdef FEAT_FOLDING case PV_FDE: return &curwin->w_p_fde_flags; case PV_FDT: return &curwin->w_p_fdt_flags; +# endif # ifdef FEAT_BEVAL case PV_BEXPR: return &curbuf->b_p_bexpr_flags; # endif -#endif -#if defined(FEAT_EVAL) # if defined(FEAT_CINDENT) case PV_INDE: return &curbuf->b_p_inde_flags; # endif @@ -5268,45 +5268,46 @@ char_u *s; char_u **varp; int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; + int idx = opt_idx; - if (opt_idx == -1) /* use name */ + if (idx == -1) /* use name */ { - opt_idx = findoption(name); - if (opt_idx < 0) /* not found (should not happen) */ + idx = findoption(name); + if (idx < 0) /* not found (should not happen) */ { EMSG2(_(e_intern2), "set_string_option_direct()"); return; } } - if (options[opt_idx].var == NULL) /* can't set hidden option */ + if (options[idx].var == NULL) /* can't set hidden option */ return; s = vim_strsave(val); if (s != NULL) { - varp = (char_u **)get_varp_scope(&(options[opt_idx]), + varp = (char_u **)get_varp_scope(&(options[idx]), both ? OPT_LOCAL : opt_flags); - if ((opt_flags & OPT_FREE) && (options[opt_idx].flags & P_ALLOCED)) + if ((opt_flags & OPT_FREE) && (options[idx].flags & P_ALLOCED)) free_string_option(*varp); *varp = s; /* For buffer/window local option may also set the global value. */ if (both) - set_string_option_global(opt_idx, varp); + set_string_option_global(idx, varp); - options[opt_idx].flags |= P_ALLOCED; + options[idx].flags |= P_ALLOCED; /* When setting both values of a global option with a local value, * make the local value empty, so that the global value is used. */ - if (((int)options[opt_idx].indir & PV_BOTH) && both) + if (((int)options[idx].indir & PV_BOTH) && both) { free_string_option(*varp); *varp = empty_option; } # ifdef FEAT_EVAL if (set_sid != SID_NONE) - set_option_scriptID_idx(opt_idx, opt_flags, + set_option_scriptID_idx(idx, opt_flags, set_sid == 0 ? current_SID : set_sid); # endif } @@ -6325,7 +6326,8 @@ else errmsg = check_stl_option(p_ruf); } - else + /* check 'statusline' only if it doesn't start with "%!" */ + else if (varp != &p_stl || s[0] != '%' || s[1] != '!') errmsg = check_stl_option(s); if (varp == &p_ruf && errmsg == NULL) comp_col(); @@ -7324,9 +7326,8 @@ #ifdef FEAT_AUTOCHDIR else if ((int *)varp == &p_acd) { - if (p_acd && curbuf->b_ffname != NULL - && vim_chdirfile(curbuf->b_ffname) == OK) - shorten_fnames(TRUE); + /* Change directories when the 'acd' option is set now. */ + DO_AUTOCHDIR } #endif diff -Naur vim70.orig/src/os_unix.c vim70/src/os_unix.c --- vim70.orig/src/os_unix.c 2006-05-01 01:13:15.000000000 -0700 +++ vim70/src/os_unix.c 2006-12-05 19:57:56.000000000 -0800 @@ -3934,7 +3934,7 @@ { linenr_T lnum = curbuf->b_op_start.lnum; int written = 0; - char_u *p = ml_get(lnum); + char_u *lp = ml_get(lnum); char_u *s; size_t l; @@ -3942,17 +3942,17 @@ close(fromshell_fd); for (;;) { - l = STRLEN(p + written); + l = STRLEN(lp + written); if (l == 0) len = 0; - else if (p[written] == NL) + else if (lp[written] == NL) /* NL -> NUL translation */ len = write(toshell_fd, "", (size_t)1); else { - s = vim_strchr(p + written, NL); - len = write(toshell_fd, (char *)p + written, - s == NULL ? l : s - (p + written)); + s = vim_strchr(lp + written, NL); + len = write(toshell_fd, (char *)lp + written, + s == NULL ? l : s - (lp + written)); } if (len == l) { @@ -3973,7 +3973,7 @@ toshell_fd = -1; break; } - p = ml_get(lnum); + lp = ml_get(lnum); written = 0; } else if (len > 0) @@ -5757,8 +5757,13 @@ int retval_int = 0; int success = FALSE; - /* Get a handle to the DLL module. */ + /* + * Get a handle to the DLL module. + */ # if defined(USE_DLOPEN) + /* First clear any error, it's not cleared by the dlopen() call. */ + (void)dlerror(); + hinstLib = dlopen((char *)libname, RTLD_LAZY # ifdef RTLD_LOCAL | RTLD_LOCAL diff -Naur vim70.orig/src/popupmnu.c vim70/src/popupmnu.c --- vim70.orig/src/popupmnu.c 2006-04-20 13:18:37.000000000 -0700 +++ vim70/src/popupmnu.c 2006-12-05 19:57:54.000000000 -0800 @@ -552,6 +552,9 @@ { pum_array = NULL; redraw_all_later(SOME_VALID); +#ifdef FEAT_WINDOWS + redraw_tabline = TRUE; +#endif status_redraw_all(); } diff -Naur vim70.orig/src/proto/buffer.pro vim70/src/proto/buffer.pro --- vim70.orig/src/proto/buffer.pro 2006-05-07 06:08:29.000000000 -0700 +++ vim70/src/proto/buffer.pro 2006-12-05 19:58:00.000000000 -0800 @@ -10,6 +10,7 @@ extern int do_buffer __ARGS((int action, int start, int dir, int count, int forceit)); extern void set_curbuf __ARGS((buf_T *buf, int action)); extern void enter_buffer __ARGS((buf_T *buf)); +extern void do_autochdir __ARGS((void)); extern buf_T *buflist_new __ARGS((char_u *ffname, char_u *sfname, linenr_T lnum, int flags)); extern void free_buf_options __ARGS((buf_T *buf, int free_p_ff)); extern int buflist_getfile __ARGS((int n, linenr_T lnum, int options, int forceit)); diff -Naur vim70.orig/src/proto/eval.pro vim70/src/proto/eval.pro --- vim70.orig/src/proto/eval.pro 2006-05-07 06:08:33.000000000 -0700 +++ vim70/src/proto/eval.pro 2006-12-05 19:58:07.000000000 -0800 @@ -44,7 +44,7 @@ extern char_u *get_user_var_name __ARGS((expand_T *xp, int idx)); extern list_T *list_alloc __ARGS((void)); extern void list_unref __ARGS((list_T *l)); -extern void list_free __ARGS((list_T *l)); +extern void list_free __ARGS((list_T *l, int recurse)); extern dictitem_T *dict_lookup __ARGS((hashitem_T *hi)); extern int list_append_dict __ARGS((list_T *list, dict_T *dict)); extern int garbage_collect __ARGS((void)); diff -Naur vim70.orig/src/proto/menu.pro vim70/src/proto/menu.pro --- vim70.orig/src/proto/menu.pro 2006-05-07 06:08:51.000000000 -0700 +++ vim70/src/proto/menu.pro 2006-12-05 19:57:54.000000000 -0800 @@ -10,6 +10,7 @@ extern int menu_is_child_of_popup __ARGS((vimmenu_T *menu)); extern int menu_is_toolbar __ARGS((char_u *name)); extern int menu_is_separator __ARGS((char_u *name)); +extern int check_menu_pointer __ARGS((vimmenu_T *root, vimmenu_T *menu_to_check)); extern void gui_create_initial_menus __ARGS((vimmenu_T *menu)); extern void gui_update_menus __ARGS((int modes)); extern int gui_is_menu_shortcut __ARGS((int key)); diff -Naur vim70.orig/src/proto/misc2.pro vim70/src/proto/misc2.pro --- vim70.orig/src/proto/misc2.pro 2006-05-07 06:08:54.000000000 -0700 +++ vim70/src/proto/misc2.pro 2006-12-05 19:58:04.000000000 -0800 @@ -29,6 +29,7 @@ extern char_u *vim_strnsave __ARGS((char_u *string, int len)); extern char_u *vim_strsave_escaped __ARGS((char_u *string, char_u *esc_chars)); extern char_u *vim_strsave_escaped_ext __ARGS((char_u *string, char_u *esc_chars, int cc, int bsl)); +extern char_u *vim_strsave_shellescape __ARGS((char_u *string)); extern char_u *vim_strsave_up __ARGS((char_u *string)); extern char_u *vim_strnsave_up __ARGS((char_u *string, int len)); extern void vim_strup __ARGS((char_u *p)); diff -Naur vim70.orig/src/proto/ops.pro vim70/src/proto/ops.pro --- vim70.orig/src/proto/ops.pro 2006-05-07 06:08:58.000000000 -0700 +++ vim70/src/proto/ops.pro 2006-12-05 19:58:11.000000000 -0800 @@ -17,10 +17,10 @@ extern void put_register __ARGS((int name, void *reg)); extern int yank_register_mline __ARGS((int regname)); extern int do_record __ARGS((int c)); -extern int do_execreg __ARGS((int regname, int colon, int addcr)); +extern int do_execreg __ARGS((int regname, int colon, int addcr, int silent)); extern int insert_reg __ARGS((int regname, int literally)); extern int get_spec_reg __ARGS((int regname, char_u **argp, int *allocated, int errmsg)); -extern int cmdline_paste_reg __ARGS((int regname, int literally)); +extern int cmdline_paste_reg __ARGS((int regname, int literally, int remcr)); extern void adjust_clip_reg __ARGS((int *rp)); extern int op_delete __ARGS((oparg_T *oap)); extern int op_replace __ARGS((oparg_T *oap, int c)); diff -Naur vim70.orig/src/proto/undo.pro vim70/src/proto/undo.pro --- vim70.orig/src/proto/undo.pro 2006-05-07 06:09:11.000000000 -0700 +++ vim70/src/proto/undo.pro 2006-12-05 19:57:47.000000000 -0800 @@ -4,6 +4,7 @@ extern int u_savesub __ARGS((linenr_T lnum)); extern int u_inssub __ARGS((linenr_T lnum)); extern int u_savedel __ARGS((linenr_T lnum, long nlines)); +extern int undo_allowed __ARGS((void)); extern void u_undo __ARGS((int count)); extern void u_redo __ARGS((int count)); extern void undo_time __ARGS((long step, int sec, int absolute)); diff -Naur vim70.orig/src/quickfix.c vim70/src/quickfix.c --- vim70.orig/src/quickfix.c 2006-05-03 00:47:42.000000000 -0700 +++ vim70/src/quickfix.c 2006-12-05 19:58:09.000000000 -0800 @@ -500,8 +500,6 @@ { if (tv != NULL) { - int len; - if (tv->v_type == VAR_STRING) { /* Get the next line from the supplied string */ @@ -602,13 +600,19 @@ else type = 0; /* - * Extract error message data from matched line + * Extract error message data from matched line. + * We check for an actual submatch, because "\[" and "\]" in + * the 'errorformat' may cause the wrong submatch to be used. */ if ((i = (int)fmt_ptr->addr[0]) > 0) /* %f */ { - int c = *regmatch.endp[i]; + int c; + + if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) + continue; /* Expand ~/file and $HOME/file to full path. */ + c = *regmatch.endp[i]; *regmatch.endp[i] = NUL; expand_env(regmatch.startp[i], namebuf, CMDBUFFSIZE); *regmatch.endp[i] = c; @@ -618,35 +622,63 @@ continue; } if ((i = (int)fmt_ptr->addr[1]) > 0) /* %n */ + { + if (regmatch.startp[i] == NULL) + continue; enr = (int)atol((char *)regmatch.startp[i]); + } if ((i = (int)fmt_ptr->addr[2]) > 0) /* %l */ + { + if (regmatch.startp[i] == NULL) + continue; lnum = atol((char *)regmatch.startp[i]); + } if ((i = (int)fmt_ptr->addr[3]) > 0) /* %c */ + { + if (regmatch.startp[i] == NULL) + continue; col = (int)atol((char *)regmatch.startp[i]); + } if ((i = (int)fmt_ptr->addr[4]) > 0) /* %t */ + { + if (regmatch.startp[i] == NULL) + continue; type = *regmatch.startp[i]; + } if (fmt_ptr->flags == '+' && !multiscan) /* %+ */ STRCPY(errmsg, IObuff); else if ((i = (int)fmt_ptr->addr[5]) > 0) /* %m */ { + if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) + continue; len = (int)(regmatch.endp[i] - regmatch.startp[i]); vim_strncpy(errmsg, regmatch.startp[i], len); } if ((i = (int)fmt_ptr->addr[6]) > 0) /* %r */ + { + if (regmatch.startp[i] == NULL) + continue; tail = regmatch.startp[i]; + } if ((i = (int)fmt_ptr->addr[7]) > 0) /* %p */ { + if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) + continue; col = (int)(regmatch.endp[i] - regmatch.startp[i] + 1); if (*((char_u *)regmatch.startp[i]) != TAB) use_viscol = TRUE; } if ((i = (int)fmt_ptr->addr[8]) > 0) /* %v */ { + if (regmatch.startp[i] == NULL) + continue; col = (int)atol((char *)regmatch.startp[i]); use_viscol = TRUE; } if ((i = (int)fmt_ptr->addr[9]) > 0) /* %s */ { + if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) + continue; len = (int)(regmatch.endp[i] - regmatch.startp[i]); if (len > CMDBUFFSIZE - 5) len = CMDBUFFSIZE - 5; @@ -1554,10 +1586,30 @@ } /* - * If there is only one window, create a new one above the quickfix - * window. + * If no usable window is found and 'switchbuf' is set to 'usetab' + * then search in other tabs. */ - if (firstwin == lastwin || !usable_win) + if (!usable_win && vim_strchr(p_swb, 'a') != NULL) + { + tabpage_T *tp; + win_T *wp; + + FOR_ALL_TAB_WINDOWS(tp, wp) + { + if (wp->w_buffer->b_fnum == qf_ptr->qf_fnum) + { + goto_tabpage_win(tp, wp); + usable_win = 1; + break; + } + } + } + + /* + * If there is only one window and is the quickfix window, create a new + * one above the quickfix window. + */ + if (((firstwin == lastwin) && bt_quickfix(curbuf)) || !usable_win) { ll_ref = curwin->w_llist_ref; @@ -2429,32 +2481,19 @@ qf_info_T *qi; { buf_T *buf; -#ifdef FEAT_AUTOCMD aco_save_T aco; -#else - buf_T *save_curbuf; -#endif /* Check if a buffer for the quickfix list exists. Update it. */ buf = qf_find_buf(qi); if (buf != NULL) { -#ifdef FEAT_AUTOCMD /* set curwin/curbuf to buf and save a few things */ aucmd_prepbuf(&aco, buf); -#else - save_curbuf = curbuf; - curbuf = buf; -#endif qf_fill_buffer(qi); -#ifdef FEAT_AUTOCMD /* restore curwin/curbuf and a few other things */ aucmd_restbuf(&aco); -#else - curbuf = save_curbuf; -#endif (void)qf_win_pos_update(qi, 0); } @@ -2943,10 +2982,8 @@ #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL) char_u *save_ei = NULL; #endif -#ifndef FEAT_AUTOCMD - buf_T *save_curbuf; -#else aco_save_T aco; +#ifdef FEAT_AUTOCMD char_u *au_name = NULL; int flags = 0; colnr_T col; @@ -3167,24 +3204,13 @@ * need to be done now, in that buffer. And the modelines * need to be done (again). But not the window-local * options! */ -#if defined(FEAT_AUTOCMD) aucmd_prepbuf(&aco, buf); -#else - save_curbuf = curbuf; - curbuf = buf; - curwin->w_buffer = curbuf; -#endif #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL) apply_autocmds(EVENT_FILETYPE, buf->b_p_ft, buf->b_fname, TRUE, buf); #endif do_modelines(OPT_NOWIN); -#if defined(FEAT_AUTOCMD) aucmd_restbuf(&aco); -#else - curbuf = save_curbuf; - curwin->w_buffer = curbuf; -#endif } } } @@ -3285,11 +3311,7 @@ { buf_T *newbuf; int failed = TRUE; -#ifdef FEAT_AUTOCMD aco_save_T aco; -#else - buf_T *old_curbuf = curbuf; -#endif /* Allocate a buffer without putting it in the buffer list. */ newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY); @@ -3299,13 +3321,8 @@ /* Init the options. */ buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP); -#ifdef FEAT_AUTOCMD /* set curwin/curbuf to buf and save a few things */ aucmd_prepbuf(&aco, newbuf); -#else - curbuf = newbuf; - curwin->w_buffer = newbuf; -#endif /* Need to set the filename for autocommands. */ (void)setfname(curbuf, fname, NULL, FALSE); @@ -3336,13 +3353,8 @@ } } -#ifdef FEAT_AUTOCMD /* restore curwin/curbuf and a few other things */ aucmd_restbuf(&aco); -#else - curbuf = old_curbuf; - curwin->w_buffer = old_curbuf; -#endif if (!buf_valid(newbuf)) return NULL; @@ -3434,8 +3446,10 @@ || dict_add_nr_str(dict, "col", (long)qfp->qf_col, NULL) == FAIL || dict_add_nr_str(dict, "vcol", (long)qfp->qf_viscol, NULL) == FAIL || dict_add_nr_str(dict, "nr", (long)qfp->qf_nr, NULL) == FAIL - || dict_add_nr_str(dict, "pattern", 0L, qfp->qf_pattern) == FAIL - || dict_add_nr_str(dict, "text", 0L, qfp->qf_text) == FAIL + || dict_add_nr_str(dict, "pattern", 0L, + qfp->qf_pattern == NULL ? (char_u *)"" : qfp->qf_pattern) == FAIL + || dict_add_nr_str(dict, "text", 0L, + qfp->qf_text == NULL ? (char_u *)"" : qfp->qf_text) == FAIL || dict_add_nr_str(dict, "type", 0L, buf) == FAIL || dict_add_nr_str(dict, "valid", (long)qfp->qf_valid, NULL) == FAIL) return FAIL; diff -Naur vim70.orig/src/regexp.c vim70/src/regexp.c --- vim70.orig/src/regexp.c 2006-04-30 08:31:50.000000000 -0700 +++ vim70/src/regexp.c 2006-12-05 19:58:09.000000000 -0800 @@ -3777,8 +3777,8 @@ op = OP(scan); /* Check for character class with NL added. */ - if (!reg_line_lbr && WITH_NL(op) && *reginput == NUL - && reglnum <= reg_maxline) + if (!reg_line_lbr && WITH_NL(op) && REG_MULTI + && *reginput == NUL && reglnum <= reg_maxline) { reg_nextline(); } @@ -3912,7 +3912,7 @@ { colnr_T start, end; colnr_T start2, end2; - colnr_T col; + colnr_T cols; getvvcol(wp, &top, &start, NULL, &end); getvvcol(wp, &bot, &start2, NULL, &end2); @@ -3922,9 +3922,9 @@ end = end2; if (top.col == MAXCOL || bot.col == MAXCOL) end = MAXCOL; - col = win_linetabsize(wp, + cols = win_linetabsize(wp, regline, (colnr_T)(reginput - regline)); - if (col < start || col > end - (*p_sel == 'e')) + if (cols < start || cols > end - (*p_sel == 'e')) status = RA_NOMATCH; } } @@ -4253,7 +4253,7 @@ { int i, len; char_u *opnd; - int opndc, inpc; + int opndc = 0, inpc; opnd = OPERAND(scan); /* Safety check (just in case 'encoding' was changed since @@ -4855,8 +4855,8 @@ break; case NEWL: - if ((c != NUL || reglnum > reg_maxline || reg_line_lbr) - && (c != '\n' || !reg_line_lbr)) + if ((c != NUL || !REG_MULTI || reglnum > reg_maxline + || reg_line_lbr) && (c != '\n' || !reg_line_lbr)) status = RA_NOMATCH; else if (reg_line_lbr) ADVANCE_REGINPUT(); @@ -5316,8 +5316,8 @@ ++count; mb_ptr_adv(scan); } - if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr - || count == maxcount) + if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline + || reg_line_lbr || count == maxcount) break; ++count; /* count the line-break */ reg_nextline(); @@ -5341,7 +5341,8 @@ } else if (*scan == NUL) { - if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr) + if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline + || reg_line_lbr) break; reg_nextline(); scan = reginput; @@ -5370,7 +5371,8 @@ } else if (*scan == NUL) { - if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr) + if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline + || reg_line_lbr) break; reg_nextline(); scan = reginput; @@ -5399,7 +5401,8 @@ } else if (*scan == NUL) { - if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr) + if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline + || reg_line_lbr) break; reg_nextline(); scan = reginput; @@ -5424,7 +5427,8 @@ { if (*scan == NUL) { - if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr) + if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline + || reg_line_lbr) break; reg_nextline(); scan = reginput; @@ -5454,7 +5458,8 @@ #endif if (*scan == NUL) { - if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr) + if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline + || reg_line_lbr) break; reg_nextline(); scan = reginput; @@ -5617,7 +5622,8 @@ #endif if (*scan == NUL) { - if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr) + if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline + || reg_line_lbr) break; reg_nextline(); scan = reginput; @@ -5646,8 +5652,8 @@ case NEWL: while (count < maxcount - && ((*scan == NUL && reglnum <= reg_maxline && !reg_line_lbr) - || (*scan == '\n' && reg_line_lbr))) + && ((*scan == NUL && reglnum <= reg_maxline && !reg_line_lbr + && REG_MULTI) || (*scan == '\n' && reg_line_lbr))) { count++; if (reg_line_lbr) diff -Naur vim70.orig/src/screen.c vim70/src/screen.c --- vim70.orig/src/screen.c 2006-05-05 03:13:55.000000000 -0700 +++ vim70/src/screen.c 2006-12-05 19:58:12.000000000 -0800 @@ -455,6 +455,7 @@ && curwin->w_topline == curwin->w_lines[0].wl_lnum) #ifdef FEAT_VISUAL || (type == INVERTED + && VIsual_active && curwin->w_old_cursor_lnum == curwin->w_cursor.lnum && curwin->w_old_visual_mode == VIsual_mode && (curwin->w_valid & VALID_VIRTCOL) @@ -1228,7 +1229,14 @@ { mid_end = wp->w_height; if (lastwin == firstwin) + { screenclear(); +#ifdef FEAT_WINDOWS + /* The screen was cleared, redraw the tab pages line. */ + if (redraw_tabline) + draw_tabline(); +#endif + } } } else @@ -2612,7 +2620,8 @@ #ifdef FEAT_LINEBREAK int need_showbreak = FALSE; #endif -#if defined(FEAT_SIGNS) || (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)) +#if defined(FEAT_SIGNS) || (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)) \ + || defined(FEAT_SYN_HL) || defined(FEAT_DIFF) # define LINE_ATTR int line_attr = 0; /* atrribute for the whole line */ #endif @@ -2626,7 +2635,7 @@ int prev_c = 0; /* previous Arabic character */ int prev_c1 = 0; /* first composing char for prev_c */ #endif -#if defined(FEAT_DIFF) || defined(LINE_ATTR) +#if defined(LINE_ATTR) int did_line_attr = 0; #endif @@ -4116,17 +4125,12 @@ --ptr; /* put it back at the NUL */ } #endif -#if defined(FEAT_DIFF) || defined(LINE_ATTR) +#if defined(LINE_ATTR) else if (( # ifdef FEAT_DIFF - diff_hlf != (hlf_T)0 -# ifdef LINE_ATTR - || -# endif + diff_hlf != (hlf_T)0 || # endif -# ifdef LINE_ATTR line_attr != 0 -# endif ) && ( # ifdef FEAT_RIGHTLEFT wp->w_p_rl ? (col >= 0) : @@ -4237,7 +4241,7 @@ * At end of the text line or just after the last character. */ if (c == NUL -#if defined(FEAT_DIFF) || defined(LINE_ATTR) +#if defined(LINE_ATTR) || did_line_attr == 1 #endif ) @@ -4258,7 +4262,7 @@ || prevcol == (long)match_hl[0].startcol || prevcol == (long)match_hl[1].startcol || prevcol == (long)match_hl[2].startcol) -# if defined(FEAT_DIFF) || defined(LINE_ATTR) +# if defined(LINE_ATTR) && did_line_attr <= 1 # endif ) @@ -5076,15 +5080,38 @@ * character too. If we didn't skip any blanks above, then we * only redraw if the character wasn't already redrawn anyway. */ - if (gui.in_use && (col > startCol || !redraw_this) -# ifdef FEAT_MBYTE - && enc_dbcs == 0 -# endif - ) + if (gui.in_use && (col > startCol || !redraw_this)) { hl = ScreenAttrs[off_to]; if (hl > HL_ALL || (hl & HL_BOLD)) - screen_char(off_to - 1, row, col + coloff - 1); + { + int prev_cells = 1; +# ifdef FEAT_MBYTE + if (enc_utf8) + /* for utf-8, ScreenLines[char_offset + 1] == 0 means + * that its width is 2. */ + prev_cells = ScreenLines[off_to - 1] == 0 ? 2 : 1; + else if (enc_dbcs != 0) + { + /* find previous character by counting from first + * column and get its width. */ + unsigned off = LineOffset[row]; + + while (off < off_to) + { + prev_cells = (*mb_off2cells)(off); + off += prev_cells; + } + } + + if (enc_dbcs != 0 && prev_cells > 1) + screen_char_2(off_to - prev_cells, row, + col + coloff - prev_cells); + else +# endif + screen_char(off_to - prev_cells, row, + col + coloff - prev_cells); + } } #endif screen_fill(row, row + 1, col + coloff, clear_width + coloff, @@ -7103,7 +7130,7 @@ tabpage_T *tp; #endif static int entered = FALSE; /* avoid recursiveness */ - static int did_outofmem_msg = FALSE; /* did outofmem message */ + static int done_outofmem_msg = FALSE; /* did outofmem message */ /* * Allocation of the screen buffers is done only when the size changes and @@ -7133,6 +7160,12 @@ return; entered = TRUE; + /* + * Note that the window sizes are updated before reallocating the arrays, + * thus we must not redraw here! + */ + ++RedrawingDisabled; + win_new_shellsize(); /* fit the windows in the new sized shell */ comp_col(); /* recompute columns for shown command and ruler */ @@ -7205,14 +7238,14 @@ #endif || outofmem) { - if (ScreenLines != NULL || !did_outofmem_msg) + if (ScreenLines != NULL || !done_outofmem_msg) { /* guess the size */ do_outofmem_msg((long_u)((Rows + 1) * Columns)); /* Remember we did this to avoid getting outofmem messages over * and over again. */ - did_outofmem_msg = TRUE; + done_outofmem_msg = TRUE; } vim_free(new_ScreenLines); new_ScreenLines = NULL; @@ -7240,7 +7273,7 @@ } else { - did_outofmem_msg = FALSE; + done_outofmem_msg = FALSE; for (new_row = 0; new_row < Rows; ++new_row) { @@ -7367,6 +7400,7 @@ #endif entered = FALSE; + --RedrawingDisabled; #ifdef FEAT_AUTOCMD if (starting == 0) diff -Naur vim70.orig/src/search.c vim70/src/search.c --- vim70.orig/src/search.c 2006-05-05 05:12:13.000000000 -0700 +++ vim70/src/search.c 2006-12-05 19:58:06.000000000 -0800 @@ -1259,7 +1259,7 @@ /* * Add character and/or line offset */ - if (!(options & SEARCH_NOOF) || *pat == ';') + if (!(options & SEARCH_NOOF) || (pat != NULL && *pat == ';')) { if (spats[0].off.line) /* Add the offset to the line number. */ { @@ -4688,6 +4688,7 @@ #ifdef FEAT_INS_EXPAND if (action == ACTION_EXPAND) { + msg_hist_off = TRUE; /* reset in msg_trunc_attr() */ vim_snprintf((char*)IObuff, IOSIZE, _("Scanning included file: %s"), (char *)new_fname); @@ -4826,15 +4827,20 @@ if ((compl_cont_status & CONT_ADDING) && i == compl_length) { - /* get the next line */ /* IOSIZE > compl_length, so the STRNCPY works */ STRNCPY(IObuff, aux, i); - if (!( depth < 0 - && lnum < end_lnum - && (line = ml_get(++lnum)) != NULL) - && !( depth >= 0 - && !vim_fgets(line = file_line, - LSIZE, files[depth].fp))) + + /* Get the next line: when "depth" < 0 from the current + * buffer, otherwise from the included file. Jump to + * exit_matched when past the last line. */ + if (depth < 0) + { + if (lnum >= end_lnum) + goto exit_matched; + line = ml_get(++lnum); + } + else if (vim_fgets(line = file_line, + LSIZE, files[depth].fp)) goto exit_matched; /* we read a line, set "already" to check this "line" later @@ -4871,7 +4877,7 @@ goto exit_matched; } - add_r = ins_compl_add_infercase(aux, i, FALSE, + add_r = ins_compl_add_infercase(aux, i, p_ic, curr_fname == curbuf->b_fname ? NULL : curr_fname, dir, reuse); if (add_r == OK) diff -Naur vim70.orig/src/spell.c vim70/src/spell.c --- vim70.orig/src/spell.c 2006-05-05 00:49:58.000000000 -0700 +++ vim70/src/spell.c 2006-12-05 19:58:02.000000000 -0800 @@ -1483,7 +1483,7 @@ else if ((mode == FIND_COMPOUND || mode == FIND_KEEPCOMPOUND || !word_ends)) { - /* If there is no flag or the word is shorter than + /* If there is no compound flag or the word is shorter than * COMPOUNDMIN reject it quickly. * Makes you wonder why someone puts a compound flag on a word * that's too short... Myspell compatibility requires this @@ -2043,8 +2043,8 @@ int len; # ifdef FEAT_SYN_HL int has_syntax = syntax_present(wp->w_buffer); - int col; # endif + int col; int can_spell; char_u *buf = NULL; int buflen = 0; @@ -2093,9 +2093,8 @@ capcol = (int)(skipwhite(line) - line); else if (curline && wp == curwin) { - int col = (int)(skipwhite(line) - line); - /* For spellbadword(): check if first word needs a capital. */ + col = (int)(skipwhite(line) - line); if (check_need_cap(lnum, col)) capcol = col; @@ -2108,7 +2107,8 @@ * possible. */ STRCPY(buf, line); if (lnum < wp->w_buffer->b_ml.ml_line_count) - spell_cat_line(buf + STRLEN(buf), ml_get(lnum + 1), MAXWLEN); + spell_cat_line(buf + STRLEN(buf), + ml_get_buf(wp->w_buffer, lnum + 1, FALSE), MAXWLEN); p = buf + skip; endp = buf + len; @@ -5060,7 +5060,7 @@ int do_rep; int do_repsal; int do_sal; - int do_map; + int do_mapline; int found_map = FALSE; hashitem_T *hi; int l; @@ -5098,7 +5098,7 @@ do_sal = spin->si_sal.ga_len == 0; /* Only do MAP lines when not done in another .aff file already. */ - do_map = spin->si_map.ga_len == 0; + do_mapline = spin->si_map.ga_len == 0; /* * Allocate and init the afffile_T structure. @@ -5780,7 +5780,7 @@ smsg((char_u *)_("Expected MAP count in %s line %d"), fname, lnum); } - else if (do_map) + else if (do_mapline) { int c; @@ -7507,7 +7507,7 @@ { char_u *p = p_msm; long start = 0; - long inc = 0; + long incr = 0; long added = 0; if (!VIM_ISDIGIT(*p)) @@ -7519,7 +7519,7 @@ ++p; if (!VIM_ISDIGIT(*p)) return FAIL; - inc = (getdigits(&p) * 102) / (SBLOCKSIZE / 10); + incr = (getdigits(&p) * 102) / (SBLOCKSIZE / 10); if (*p != ',') return FAIL; ++p; @@ -7529,11 +7529,11 @@ if (*p != NUL) return FAIL; - if (start == 0 || inc == 0 || added == 0 || inc > start) + if (start == 0 || incr == 0 || added == 0 || incr > start) return FAIL; compress_start = start; - compress_inc = inc; + compress_inc = incr; compress_added = added; return OK; } @@ -8291,14 +8291,14 @@ * Returns the number of nodes used. */ static int -put_node(fd, node, index, regionmask, prefixtree) +put_node(fd, node, idx, regionmask, prefixtree) FILE *fd; /* NULL when only counting */ wordnode_T *node; - int index; + int idx; int regionmask; int prefixtree; /* TRUE for PREFIXTREE */ { - int newindex = index; + int newindex = idx; int siblingcount = 0; wordnode_T *np; int flags; @@ -8308,7 +8308,7 @@ return 0; /* Store the index where this node is written. */ - node->wn_u1.index = index; + node->wn_u1.index = idx; /* Count the number of siblings. */ for (np = node; np != NULL; np = np->wn_sibling) @@ -9243,15 +9243,15 @@ * Add "word[len]" to 'spellfile' as a good or bad word. */ void -spell_add_word(word, len, bad, index, undo) +spell_add_word(word, len, bad, idx, undo) char_u *word; int len; int bad; - int index; /* "zG" and "zW": zero, otherwise index in + int idx; /* "zG" and "zW": zero, otherwise index in 'spellfile' */ int undo; /* TRUE for "zug", "zuG", "zuw" and "zuW" */ { - FILE *fd; + FILE *fd = NULL; buf_T *buf = NULL; int new_spf = FALSE; char_u *fname; @@ -9261,7 +9261,7 @@ int i; char_u *spf; - if (index == 0) /* use internal wordlist */ + if (idx == 0) /* use internal wordlist */ { if (int_wordlist == NULL) { @@ -9289,11 +9289,11 @@ for (spf = curbuf->b_p_spf, i = 1; *spf != NUL; ++i) { copy_option_part(&spf, fnamebuf, MAXPATHL, ","); - if (i == index) + if (i == idx) break; if (*spf == NUL) { - EMSGN(_("E765: 'spellfile' does not have %ld entries"), index); + EMSGN(_("E765: 'spellfile' does not have %ld entries"), idx); return; } } @@ -9336,7 +9336,10 @@ { fputc('#', fd); if (undo) + { + home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE); smsg((char_u *)_("Word removed from %s"), NameBuff); + } } fseek(fd, fpos_next, SEEK_SET); } @@ -9344,20 +9347,27 @@ fclose(fd); } } - else + + if (!undo) { fd = mch_fopen((char *)fname, "a"); if (fd == NULL && new_spf) { + char_u *p; + /* We just initialized the 'spellfile' option and can't open the * file. We may need to create the "spell" directory first. We * already checked the runtime directory is writable in * init_spellfile(). */ - if (!dir_of_file_exists(fname)) + if (!dir_of_file_exists(fname) && (p = gettail_sep(fname)) != fname) { + int c = *p; + /* The directory doesn't exist. Try creating it and opening * the file again. */ - vim_mkdir(NameBuff, 0755); + *p = NUL; + vim_mkdir(fname, 0755); + *p = c; fd = mch_fopen((char *)fname, "a"); } } @@ -10070,6 +10080,7 @@ /* List the suggestions. */ msg_start(); + msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ lines_left = Rows; /* avoid more prompt */ vim_snprintf((char *)IObuff, IOSIZE, _("Change \"%.*s\" to:"), sug.su_badlen, sug.su_badptr); @@ -13579,53 +13590,58 @@ * the first "the" to itself. */ return; - /* Check if the word is already there. Also check the length that is - * being replaced "thes," -> "these" is a different suggestion from - * "thes" -> "these". */ - stp = &SUG(*gap, 0); - for (i = gap->ga_len; --i >= 0; ++stp) - if (stp->st_wordlen == goodlen - && stp->st_orglen == badlen - && STRNCMP(stp->st_word, goodword, goodlen) == 0) - { - /* - * Found it. Remember the word with the lowest score. - */ - if (stp->st_slang == NULL) - stp->st_slang = slang; + if (gap->ga_len == 0) + i = -1; + else + { + /* Check if the word is already there. Also check the length that is + * being replaced "thes," -> "these" is a different suggestion from + * "thes" -> "these". */ + stp = &SUG(*gap, 0); + for (i = gap->ga_len; --i >= 0; ++stp) + if (stp->st_wordlen == goodlen + && stp->st_orglen == badlen + && STRNCMP(stp->st_word, goodword, goodlen) == 0) + { + /* + * Found it. Remember the word with the lowest score. + */ + if (stp->st_slang == NULL) + stp->st_slang = slang; - new_sug.st_score = score; - new_sug.st_altscore = altscore; - new_sug.st_had_bonus = had_bonus; + new_sug.st_score = score; + new_sug.st_altscore = altscore; + new_sug.st_had_bonus = had_bonus; + + if (stp->st_had_bonus != had_bonus) + { + /* Only one of the two had the soundalike score computed. + * Need to do that for the other one now, otherwise the + * scores can't be compared. This happens because + * suggest_try_change() doesn't compute the soundalike + * word to keep it fast, while some special methods set + * the soundalike score to zero. */ + if (had_bonus) + rescore_one(su, stp); + else + { + new_sug.st_word = stp->st_word; + new_sug.st_wordlen = stp->st_wordlen; + new_sug.st_slang = stp->st_slang; + new_sug.st_orglen = badlen; + rescore_one(su, &new_sug); + } + } - if (stp->st_had_bonus != had_bonus) - { - /* Only one of the two had the soundalike score computed. - * Need to do that for the other one now, otherwise the - * scores can't be compared. This happens because - * suggest_try_change() doesn't compute the soundalike - * word to keep it fast, while some special methods set - * the soundalike score to zero. */ - if (had_bonus) - rescore_one(su, stp); - else + if (stp->st_score > new_sug.st_score) { - new_sug.st_word = stp->st_word; - new_sug.st_wordlen = stp->st_wordlen; - new_sug.st_slang = stp->st_slang; - new_sug.st_orglen = badlen; - rescore_one(su, &new_sug); + stp->st_score = new_sug.st_score; + stp->st_altscore = new_sug.st_altscore; + stp->st_had_bonus = new_sug.st_had_bonus; } + break; } - - if (stp->st_score > new_sug.st_score) - { - stp->st_score = new_sug.st_score; - stp->st_altscore = new_sug.st_altscore; - stp->st_had_bonus = new_sug.st_had_bonus; - } - break; - } + } if (i < 0 && ga_grow(gap, 1) == OK) { @@ -15656,7 +15672,7 @@ ? MB_STRNICMP(p, pat, STRLEN(pat)) == 0 : STRNCMP(p, pat, STRLEN(pat)) == 0) && ins_compl_add_infercase(p, (int)STRLEN(p), - FALSE, NULL, *dir, 0) == OK) + p_ic, NULL, *dir, 0) == OK) /* if dir was BACKWARD then honor it just once */ *dir = FORWARD; } diff -Naur vim70.orig/src/structs.h vim70/src/structs.h --- vim70.orig/src/structs.h 2006-04-09 10:57:46.000000000 -0700 +++ vim70/src/structs.h 2006-12-05 19:57:54.000000000 -0800 @@ -2213,18 +2213,20 @@ /* * Struct to save values in before executing autocommands for a buffer that is - * not the current buffer. + * not the current buffer. Without FEAT_AUTOCMD only "curbuf" is remembered. */ typedef struct { buf_T *save_buf; /* saved curbuf */ +#ifdef FEAT_AUTOCMD buf_T *new_curbuf; /* buffer to be used */ win_T *save_curwin; /* saved curwin, NULL if it didn't change */ win_T *new_curwin; /* new curwin if save_curwin != NULL */ pos_T save_cursor; /* saved cursor pos of save_curwin */ linenr_T save_topline; /* saved topline of save_curwin */ -#ifdef FEAT_DIFF +# ifdef FEAT_DIFF int save_topfill; /* saved topfill of save_curwin */ +# endif #endif } aco_save_T; diff -Naur vim70.orig/src/syntax.c vim70/src/syntax.c --- vim70.orig/src/syntax.c 2006-04-26 05:49:45.000000000 -0700 +++ vim70/src/syntax.c 2006-12-05 19:58:10.000000000 -0800 @@ -977,6 +977,7 @@ { stateitem_T *cur_si; int i; + int seen_keepend; if (startofline) { @@ -1002,7 +1003,10 @@ /* * Need to update the end of a start/skip/end that continues from the * previous line. And regions that have "keepend", because they may - * influence contained items. + * influence contained items. If we've just removed "extend" + * (startofline == 0) then we should update ends of normal regions + * contained inside "keepend" because "extend" could have extended + * these "keepend" regions as well as contained normal regions. * Then check for items ending in column 0. */ i = current_state.ga_len - 1; @@ -1010,10 +1014,13 @@ for ( ; i > keepend_level; --i) if (CUR_STATE(i).si_flags & HL_EXTEND) break; + + seen_keepend = FALSE; for ( ; i < current_state.ga_len; ++i) { cur_si = &CUR_STATE(i); if ((cur_si->si_flags & HL_KEEPEND) + || (seen_keepend && !startofline) || (i == current_state.ga_len - 1 && startofline)) { cur_si->si_h_startpos.col = 0; /* start highl. in col 0 */ @@ -1021,6 +1028,9 @@ if (!(cur_si->si_flags & HL_MATCHCONT)) update_si_end(cur_si, (int)current_col, !startofline); + + if (!startofline && (cur_si->si_flags & HL_KEEPEND)) + seen_keepend = TRUE; } } check_keepend(); @@ -2564,6 +2574,7 @@ { int i; lpos_T maxpos; + lpos_T maxpos_h; stateitem_T *sip; /* @@ -2583,23 +2594,30 @@ break; maxpos.lnum = 0; + maxpos_h.lnum = 0; for ( ; i < current_state.ga_len; ++i) { sip = &CUR_STATE(i); if (maxpos.lnum != 0) { limit_pos_zero(&sip->si_m_endpos, &maxpos); - limit_pos_zero(&sip->si_h_endpos, &maxpos); + limit_pos_zero(&sip->si_h_endpos, &maxpos_h); limit_pos_zero(&sip->si_eoe_pos, &maxpos); sip->si_ends = TRUE; } - if (sip->si_ends - && (sip->si_flags & HL_KEEPEND) - && (maxpos.lnum == 0 + if (sip->si_ends && (sip->si_flags & HL_KEEPEND)) + { + if (maxpos.lnum == 0 || maxpos.lnum > sip->si_m_endpos.lnum || (maxpos.lnum == sip->si_m_endpos.lnum - && maxpos.col > sip->si_m_endpos.col))) - maxpos = sip->si_m_endpos; + && maxpos.col > sip->si_m_endpos.col)) + maxpos = sip->si_m_endpos; + if (maxpos_h.lnum == 0 + || maxpos_h.lnum > sip->si_h_endpos.lnum + || (maxpos_h.lnum == sip->si_h_endpos.lnum + && maxpos_h.col > sip->si_h_endpos.col)) + maxpos_h = sip->si_h_endpos; + } } } @@ -6054,7 +6072,11 @@ ++level; } if (level > wp->w_p_fdn) + { level = wp->w_p_fdn; + if (level < 0) + level = 0; + } return level; } #endif diff -Naur vim70.orig/src/tag.c vim70/src/tag.c --- vim70.orig/src/tag.c 2006-04-27 06:11:21.000000000 -0700 +++ vim70/src/tag.c 2006-12-05 19:58:07.000000000 -0800 @@ -911,7 +911,7 @@ set_errorlist(curwin, list, ' '); - list_free(list); + list_free(list, TRUE); cur_match = 0; /* Jump to the first tag */ } @@ -3787,6 +3787,7 @@ { int num_matches, i, ret; char_u **matches, *p; + char_u *full_fname; dict_T *dict; tagptrs_T tp; long is_static; @@ -3809,9 +3810,10 @@ if (list_append_dict(list, dict) == FAIL) ret = FAIL; + full_fname = tag_full_fname(&tp); if (add_tag_field(dict, "name", tp.tagname, tp.tagname_end) == FAIL - || add_tag_field(dict, "filename", tp.fname, - tp.fname_end) == FAIL + || add_tag_field(dict, "filename", full_fname, + NULL) == FAIL || add_tag_field(dict, "cmd", tp.command, tp.command_end) == FAIL || add_tag_field(dict, "kind", tp.tagkind, @@ -3819,6 +3821,8 @@ || dict_add_nr_str(dict, "static", is_static, NULL) == FAIL) ret = FAIL; + vim_free(full_fname); + if (tp.command_end != NULL) { for (p = tp.command_end + 3; diff -Naur vim70.orig/src/term.c vim70/src/term.c --- vim70.orig/src/term.c 2006-05-03 10:34:57.000000000 -0700 +++ vim70/src/term.c 2006-12-05 19:58:10.000000000 -0800 @@ -3137,25 +3137,32 @@ screenalloc(FALSE); repeat_message(); } - else if (State & CMDLINE) - { - update_screen(NOT_VALID); - redrawcmdline(); - } else { - update_topline(); -#if defined(FEAT_INS_EXPAND) - if (pum_visible()) +#ifdef FEAT_SCROLLBIND + if (curwin->w_p_scb) + do_check_scrollbind(TRUE); +#endif + if (State & CMDLINE) { - redraw_later(NOT_VALID); - ins_compl_show_pum(); /* This includes the redraw. */ + update_screen(NOT_VALID); + redrawcmdline(); } else + { + update_topline(); +#if defined(FEAT_INS_EXPAND) + if (pum_visible()) + { + redraw_later(NOT_VALID); + ins_compl_show_pum(); /* This includes the redraw. */ + } + else #endif - update_screen(NOT_VALID); - if (redrawing()) - setcursor(); + update_screen(NOT_VALID); + if (redrawing()) + setcursor(); + } } cursor_on(); /* redrawing may have switched it off */ } @@ -4783,6 +4790,14 @@ return -1; current_menu = (vimmenu_T *)val; slen += num_bytes; + + /* The menu may have been deleted right after it was used, check + * for that. */ + if (check_menu_pointer(root_menu, current_menu) == FAIL) + { + key_name[0] = KS_EXTRA; + key_name[1] = (int)KE_IGNORE; + } } # endif # ifdef FEAT_GUI_TABLINE diff -Naur vim70.orig/src/testdir/test56.in vim70/src/testdir/test56.in --- vim70.orig/src/testdir/test56.in 2005-05-18 08:37:37.000000000 -0700 +++ vim70/src/testdir/test56.in 2006-12-05 19:58:00.000000000 -0800 @@ -3,7 +3,7 @@ STARTTEST :so small.vim :" -:set nocp +:set nocp viminfo+=nviminfo :/^start:/+1,/^end:/-1w! Xtest.vim :source Xtest.vim _x diff -Naur vim70.orig/src/ui.c vim70/src/ui.c --- vim70.orig/src/ui.c 2006-03-27 11:15:09.000000000 -0800 +++ vim70/src/ui.c 2006-12-05 19:57:56.000000000 -0800 @@ -1137,7 +1137,6 @@ int len; #ifdef FEAT_MBYTE char_u *p; - int i; #endif int row1 = clip_star.start.lnum; int col1 = clip_star.start.col; @@ -1218,6 +1217,8 @@ #ifdef FEAT_MBYTE if (enc_dbcs != 0) { + int i; + p = ScreenLines + LineOffset[row]; for (i = start_col; i < end_col; ++i) if (enc_dbcs == DBCS_JPNU && p[i] == 0x8e) diff -Naur vim70.orig/src/undo.c vim70/src/undo.c --- vim70.orig/src/undo.c 2006-04-21 02:30:59.000000000 -0700 +++ vim70/src/undo.c 2006-12-05 19:57:56.000000000 -0800 @@ -84,7 +84,6 @@ static void u_unch_branch __ARGS((u_header_T *uhp)); static u_entry_T *u_get_headentry __ARGS((void)); static void u_getbot __ARGS((void)); -static int undo_allowed __ARGS((void)); static int u_savecommon __ARGS((linenr_T, linenr_T, linenr_T)); static void u_doit __ARGS((int count)); static void u_undoredo __ARGS((int undo)); @@ -196,7 +195,7 @@ * Return TRUE when undo is allowed. Otherwise give an error message and * return FALSE. */ - static int + int undo_allowed() { /* Don't allow changes when 'modifiable' is off. */ @@ -1188,7 +1187,7 @@ int did_undo; /* just did an undo */ int absolute; /* used ":undo N" */ { - char *msg; + char *msgstr; u_header_T *uhp; char_u msgbuf[80]; @@ -1206,20 +1205,20 @@ u_oldcount -= u_newcount; if (u_oldcount == -1) - msg = N_("more line"); + msgstr = N_("more line"); else if (u_oldcount < 0) - msg = N_("more lines"); + msgstr = N_("more lines"); else if (u_oldcount == 1) - msg = N_("line less"); + msgstr = N_("line less"); else if (u_oldcount > 1) - msg = N_("fewer lines"); + msgstr = N_("fewer lines"); else { u_oldcount = u_newcount; if (u_newcount == 1) - msg = N_("change"); + msgstr = N_("change"); else - msg = N_("changes"); + msgstr = N_("changes"); } if (curbuf->b_u_curhead != NULL) @@ -1245,7 +1244,7 @@ smsg((char_u *)_("%ld %s; %s #%ld %s"), u_oldcount < 0 ? -u_oldcount : u_oldcount, - _(msg), + _(msgstr), did_undo ? _("before") : _("after"), uhp == NULL ? 0L : uhp->uh_seq, msgbuf); diff -Naur vim70.orig/src/version.c vim70/src/version.c --- vim70.orig/src/version.c 2006-05-03 00:50:42.000000000 -0700 +++ vim70/src/version.c 2006-12-05 19:58:39.000000000 -0800 @@ -667,6 +667,328 @@ static int included_patches[] = { /* Add new patch number below this line */ /**/ + 178, +/**/ + 177, +/**/ + 176, +/**/ + 175, +/**/ + 174, +/**/ + 173, +/**/ + 172, +/**/ + 169, +/**/ + 168, +/**/ + 167, +/**/ + 166, +/**/ + 165, +/**/ + 164, +/**/ + 163, +/**/ + 162, +/**/ + 160, +/**/ + 159, +/**/ + 158, +/**/ + 157, +/**/ + 155, +/**/ + 154, +/**/ + 153, +/**/ + 152, +/**/ + 151, +/**/ + 150, +/**/ + 149, +/**/ + 148, +/**/ + 147, +/**/ + 146, +/**/ + 145, +/**/ + 144, +/**/ + 143, +/**/ + 142, +/**/ + 141, +/**/ + 140, +/**/ + 139, +/**/ + 137, +/**/ + 136, +/**/ + 135, +/**/ + 134, +/**/ + 133, +/**/ + 129, +/**/ + 128, +/**/ + 127, +/**/ + 126, +/**/ + 125, +/**/ + 124, +/**/ + 123, +/**/ + 122, +/**/ + 121, +/**/ + 120, +/**/ + 119, +/**/ + 118, +/**/ + 117, +/**/ + 116, +/**/ + 115, +/**/ + 114, +/**/ + 113, +/**/ + 112, +/**/ + 111, +/**/ + 110, +/**/ + 109, +/**/ + 107, +/**/ + 106, +/**/ + 105, +/**/ + 104, +/**/ + 103, +/**/ + 102, +/**/ + 101, +/**/ + 100, +/**/ + 99, +/**/ + 98, +/**/ + 97, +/**/ + 96, +/**/ + 95, +/**/ + 94, +/**/ + 93, +/**/ + 92, +/**/ + 91, +/**/ + 90, +/**/ + 89, +/**/ + 88, +/**/ + 87, +/**/ + 86, +/**/ + 85, +/**/ + 84, +/**/ + 83, +/**/ + 82, +/**/ + 81, +/**/ + 80, +/**/ + 79, +/**/ + 78, +/**/ + 77, +/**/ + 76, +/**/ + 75, +/**/ + 73, +/**/ + 72, +/**/ + 71, +/**/ + 70, +/**/ + 69, +/**/ + 68, +/**/ + 67, +/**/ + 66, +/**/ + 64, +/**/ + 63, +/**/ + 62, +/**/ + 61, +/**/ + 60, +/**/ + 59, +/**/ + 58, +/**/ + 56, +/**/ + 55, +/**/ + 54, +/**/ + 53, +/**/ + 52, +/**/ + 51, +/**/ + 50, +/**/ + 49, +/**/ + 48, +/**/ + 47, +/**/ + 46, +/**/ + 44, +/**/ + 43, +/**/ + 42, +/**/ + 41, +/**/ + 40, +/**/ + 39, +/**/ + 38, +/**/ + 37, +/**/ + 36, +/**/ + 35, +/**/ + 34, +/**/ + 33, +/**/ + 31, +/**/ + 30, +/**/ + 29, +/**/ + 26, +/**/ + 25, +/**/ + 24, +/**/ + 23, +/**/ + 22, +/**/ + 21, +/**/ + 20, +/**/ + 19, +/**/ + 18, +/**/ + 17, +/**/ + 16, +/**/ + 15, +/**/ + 14, +/**/ + 13, +/**/ + 12, +/**/ + 11, +/**/ + 10, +/**/ + 9, +/**/ + 8, +/**/ + 7, +/**/ + 6, +/**/ + 4, +/**/ + 3, +/**/ + 2, +/**/ + 1, +/**/ 0 }; @@ -731,7 +1053,11 @@ /* Only MS VC 4.1 and earlier can do Win32s */ MSG_PUTS(_("\nMS-Windows 16/32 bit GUI version")); # else +# ifdef _WIN64 + MSG_PUTS(_("\nMS-Windows 64 bit GUI version")); +# else MSG_PUTS(_("\nMS-Windows 32 bit GUI version")); +# endif # endif if (gui_is_win32s()) MSG_PUTS(_(" in Win32s mode")); diff -Naur vim70.orig/src/vim.h vim70/src/vim.h --- vim70.orig/src/vim.h 2006-04-30 08:32:38.000000000 -0700 +++ vim70/src/vim.h 2006-12-05 19:58:11.000000000 -0800 @@ -585,7 +585,6 @@ #define INSERT 0x10 /* Insert mode */ #define LANGMAP 0x20 /* Language mapping, can be combined with INSERT and CMDLINE */ -#define MAP_ALL_MODES 0x3f /* all mode bits used for mapping */ #define REPLACE_FLAG 0x40 /* Replace mode flag */ #define REPLACE (REPLACE_FLAG + INSERT) @@ -605,6 +604,9 @@ #define CONFIRM 0x800 /* ":confirm" prompt */ #define SELECTMODE 0x1000 /* Select mode, only for mappings */ +#define MAP_ALL_MODES (0x3f | SELECTMODE) /* all mode bits used for + * mapping */ + /* directions */ #define FORWARD 1 #define BACKWARD (-1) @@ -1118,6 +1120,7 @@ EVENT_FOCUSGAINED, /* got the focus */ EVENT_FOCUSLOST, /* lost the focus to another app */ EVENT_GUIENTER, /* after starting the GUI */ + EVENT_GUIFAILED, /* after starting the GUI failed */ EVENT_INSERTCHANGE, /* when changing Insert/Replace mode */ EVENT_INSERTENTER, /* when entering Insert mode */ EVENT_INSERTLEAVE, /* when leaving Insert mode */ @@ -1666,7 +1669,10 @@ #define VV_SWAPCHOICE 46 #define VV_SWAPCOMMAND 47 #define VV_CHAR 48 -#define VV_LEN 49 /* number of v: vars */ +#define VV_MOUSE_WIN 49 +#define VV_MOUSE_LNUM 50 +#define VV_MOUSE_COL 51 +#define VV_LEN 52 /* number of v: vars */ #ifdef FEAT_CLIPBOARD diff -Naur vim70.orig/src/window.c vim70/src/window.c --- vim70.orig/src/window.c 2006-05-06 03:54:51.000000000 -0700 +++ vim70/src/window.c 2006-12-05 19:58:12.000000000 -0800 @@ -340,10 +340,10 @@ { tabpage_T *oldtab = curtab; tabpage_T *newtab; - win_T *wp = curwin; /* First create a new tab with the window, then go back to * the old tab and close the window there. */ + wp = curwin; if (win_new_tabpage((int)Prenum) == OK && valid_tabpage(oldtab)) { @@ -3954,13 +3954,8 @@ setmouse(); /* in case jumped to/from help buffer */ #endif -#ifdef FEAT_AUTOCHDIR - /* Change directories when the 'acd' option is set on and after - * switching windows. */ - if (p_acd && curbuf->b_ffname != NULL - && vim_chdirfile(curbuf->b_ffname) == OK) - shorten_fnames(TRUE); -#endif + /* Change directories when the 'acd' option is set. */ + DO_AUTOCHDIR } #endif /* FEAT_WINDOWS */ @@ -4278,7 +4273,7 @@ win_T *wp; { wp->w_lines_valid = 0; - wp->w_lines = (wline_T *)alloc((unsigned)(Rows * sizeof(wline_T))); + wp->w_lines = (wline_T *)alloc_clear((unsigned)(Rows * sizeof(wline_T))); if (wp->w_lines == NULL) return FAIL; return OK; @@ -5194,11 +5189,7 @@ int height; { linenr_T lnum; - linenr_T bot; int sline, line_size; - int space; - int did_below = FALSE; - int old_height = wp->w_height; #define FRACTION_MULT 16384L /* Don't want a negative height. Happens when splitting a tiny window. @@ -5233,54 +5224,44 @@ wp->w_wrow = ((long)wp->w_fraction * (long)height - 1L) / FRACTION_MULT; line_size = plines_win_col(wp, lnum, (long)(wp->w_cursor.col)) - 1; sline = wp->w_wrow - line_size; + + if (sline >= 0) + { + /* Make sure the whole cursor line is visible, if possible. */ + int rows = plines_win(wp, lnum, FALSE); + + if (sline > wp->w_height - rows) + { + sline = wp->w_height - rows; + wp->w_wrow -= rows - line_size; + } + } + if (sline < 0) { /* * Cursor line would go off top of screen if w_wrow was this high. + * Make cursor line the first line in the window. If not enough + * room use w_skipcol; */ wp->w_wrow = line_size; + if (wp->w_wrow >= wp->w_height + && (W_WIDTH(wp) - win_col_off(wp)) > 0) + { + wp->w_skipcol += W_WIDTH(wp) - win_col_off(wp); + --wp->w_wrow; + while (wp->w_wrow >= wp->w_height) + { + wp->w_skipcol += W_WIDTH(wp) - win_col_off(wp) + + win_col_off2(wp); + --wp->w_wrow; + } + } } else { - space = height - 1; - - while (lnum > 1) + while (sline > 0 && lnum > 1) { - /* When using "~" lines stop when at the old topline, don't - * scroll down. */ - if (did_below && height < old_height && lnum <= wp->w_topline) - sline = 0; - - space -= line_size; - if (space > 0 && sline <= 0 && !did_below) - { - /* Try to use "~" lines below the text to avoid that text - * is above the window while there are empty lines. - * Subtract the rows below the cursor from "space" and - * give the rest to "sline". */ - did_below = TRUE; - bot = wp->w_cursor.lnum; - while (space > 0) - { - if (wp->w_buffer->b_ml.ml_line_count - bot >= space) - space = 0; - else - { -#ifdef FEAT_FOLDING - hasFoldingWin(wp, bot, NULL, &bot, TRUE, NULL); -#endif - if (bot >= wp->w_buffer->b_ml.ml_line_count) - break; - ++bot; - space -= plines_win(wp, bot, TRUE); - } - } - if (bot == wp->w_buffer->b_ml.ml_line_count && space > 0) - sline += space; - } - if (sline <= 0) - break; - #ifdef FEAT_FOLDING hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL); if (lnum == 1)