]> granicus.if.org Git - vim/commitdiff
updated for version 7.0197 v7.0197
authorBram Moolenaar <Bram@vim.org>
Tue, 14 Feb 2006 22:29:30 +0000 (22:29 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 14 Feb 2006 22:29:30 +0000 (22:29 +0000)
47 files changed:
runtime/autoload/htmlcomplete.vim
runtime/autoload/javascriptcomplete.vim
runtime/autoload/xmlcomplete.vim
runtime/doc/autocmd.txt
runtime/doc/change.txt
runtime/doc/eval.txt
runtime/doc/gui.txt
runtime/doc/insert.txt
runtime/doc/options.txt
runtime/doc/os_dos.txt
runtime/doc/pattern.txt
runtime/doc/quickref.txt
runtime/doc/starting.txt
runtime/doc/tags
runtime/doc/term.txt
runtime/doc/tips.txt
runtime/doc/todo.txt
runtime/doc/usr_41.txt
runtime/doc/version7.txt
runtime/indent/vhdl.vim
src/buffer.c
src/edit.c
src/eval.c
src/ex_cmds.h
src/ex_docmd.c
src/globals.h
src/gui.h
src/gui_beval.c
src/if_mzsch.c
src/main.c
src/netbeans.c
src/normal.c
src/ops.c
src/option.c
src/proto/eval.pro
src/proto/ex_docmd.pro
src/proto/ops.pro
src/proto/window.pro
src/screen.c
src/search.c
src/structs.h
src/syntax.c
src/term.c
src/ui.c
src/version.h
src/vim.h
src/window.c

index a6295373ed7c6ffd24fc0f3f33656b293834c317..0b4bc5fd88be40db874556f38609dae0c7e4aa85 100644 (file)
@@ -41,7 +41,7 @@ function! htmlcomplete#CompleteTags(findstart, base)
                        let start = col('.') - 1
                        let b:jscompl = 1
                        let b:jsrange = [scriptstart, scriptend]
-                       while start >= 0 && line[start - 1] =~ '\w'
+                       while start >= 0 && line[start - 1] =~ '\k'
                                let start -= 1
                        endwhile
                        " We are inside of <script> tag. But we should also get contents
@@ -102,7 +102,7 @@ function! htmlcomplete#CompleteTags(findstart, base)
                " completion will be badly reported
                if b:compl_context =~? 'on[a-z]*\s*=\s*\(''[^'']*\|"[^"]*\)$'
                        let start = col('.') - 1
-                       while start >= 0 && line[start - 1] =~ '\w'
+                       while start >= 0 && line[start - 1] =~ '\k'
                                let start -= 1
                        endwhile
                endif
@@ -178,13 +178,6 @@ function! htmlcomplete#CompleteTags(findstart, base)
                endif
        endif
 
-       " Set attribute groups
-    let coreattrs = ["id", "class", "style", "title"] 
-    let i18n = ["lang", "xml:lang", "dir=\"ltr\" ", "dir=\"rtl\" "]
-    let events = ["onclick", "ondblclick", "onmousedown", "onmouseup", "onmousemove",
-                       \ "onmouseover", "onmouseout", "onkeypress", "onkeydown", "onkeyup"]
-    let focus = ["accesskey", "tabindex", "onfocus", "onblur"]
-    let coregroup = coreattrs + i18n + events
        " If context contains > it means we are already outside of tag and we
        " should abandon action
        " If context contains white space it is attribute. 
@@ -403,12 +396,11 @@ function! htmlcomplete#CompleteTags(findstart, base)
 
                                " 3. Proper call for javascriptcomplete#CompleteJS
                                call cursor(l,c)
-                               let js_context = matchstr(a:base, '\w\+$')
+                               let js_context = matchstr(a:base, '\k\+$')
                                let js_shortcontext = substitute(a:base, js_context.'$', '', '')
                                let b:compl_context = context
                                let b:jsrange = [l, l]
                                unlet! l c
-                               "return map(javascriptcomplete#CompleteJS(0, js_context), 'js_shortcontext.v:val')
                                return javascriptcomplete#CompleteJS(0, js_context)
 
                        endif
@@ -501,95 +493,44 @@ function! htmlcomplete#CompleteTags(findstart, base)
                " Attribute completion {{{
                " Shorten context to not include last word
                let sbase = matchstr(context, '.*\ze\s.*')
-               if tag =~ '^\(abbr\|acronym\|address\|b\|bdo\|big\|caption\|cite\|code\|dd\|dfn\|div\|dl\|dt\|em\|fieldset\|h\d\|hr\|i\|kbd\|li\|noscript\|ol\|p\|samp\|small\|span\|strong\|sub\|sup\|tt\|ul\|var\)$'
-                       let attrs = coregroup
-               elseif tag == 'a'
-                       let attrs = coregroup + focus + ["charset", "type", "name", "href", "hreflang", "rel", "rev", "shape", "coords"]
-               elseif tag == 'area'
-                       let attrs = coregroup + focus + ["shape", "coords", "href", "nohref", "alt"]
-               elseif tag == 'base'
-                       let attrs = ["href", "id"]
-               elseif tag == 'blockquote'
-                       let attrs = coregroup + ["cite"]
-               elseif tag == 'body'
-                       let attrs = coregroup + ["onload", "onunload"]
-               elseif tag == 'br'
-                       let attrs = coreattrs
-               elseif tag == 'button'
-                       let attrs = coregroup + focus + ["name", "value", "type"]
-               elseif tag == '^\(col\|colgroup\)$'
-                       let attrs = coregroup + ["span", "width", "align", "char", "charoff", "valign"]
-               elseif tag =~ '^\(del\|ins\)$'
-                       let attrs = coregroup + ["cite", "datetime"]
-               elseif tag == 'form'
-                       let attrs = coregroup + ["action", "method=\"get\" ", "method=\"post\" ", "enctype", "onsubmit", "onreset", "accept", "accept-charset"]
-               elseif tag == 'head'
-                       let attrs = i18n + ["id", "profile"]
-               elseif tag == 'html'
-                       let attrs = i18n + ["id", "xmlns"]
-               elseif tag == 'img'
-                       let attrs = coregroup + ["src", "alt", "longdesc", "height", "width", "usemap", "ismap"]
-               elseif tag == 'input'
-                       let attrs = coregroup + ["type", "name", "value", "checked", "disabled", "readonly", "size", "maxlength", "src", "alt", "usemap", "onselect", "onchange", "accept"]
-               elseif tag == 'label'
-                       let attrs = coregroup + ["for", "accesskey", "onfocus", "onblur"]
-               elseif tag == 'legend'
-                       let attrs = coregroup + ["accesskey"]
-               elseif tag == 'link'
-                       let attrs = coregroup + ["charset", "href", "hreflang", "type", "rel", "rev", "media"]
-               elseif tag == 'map'
-                       let attrs = i18n + events + ["id", "class", "style", "title", "name"]
-               elseif tag == 'meta'
-                       let attrs = i18n + ["id", "http-equiv", "content", "scheme", "name"]
-               elseif tag == 'title'
-                       let attrs = i18n + ["id"]
-               elseif tag == 'object'
-                       let attrs = coregroup + ["declare", "classid", "codebase", "data", "type", "codetype", "archive", "standby", "height", "width", "usemap", "name", "tabindex"]
-               elseif tag == 'optgroup'
-                       let attrs = coregroup + ["disbled", "label"]
-               elseif tag == 'option'
-                       let attrs = coregroup + ["disbled", "selected", "value", "label"]
-               elseif tag == 'param'
-                       let attrs = ["id", "name", "value", "valuetype", "type"]
-               elseif tag == 'pre'
-                       let attrs = coregroup + ["xml:space"]
-               elseif tag == 'q'
-                       let attrs = coregroup + ["cite"]
-               elseif tag == 'script'
-                       let attrs = ["id", "charset", "type=\"text/javascript\"", "type", "src", "defer", "xml:space"]
-               elseif tag == 'select'
-                       let attrs = coregroup + ["name", "size", "multiple", "disabled", "tabindex", "onfocus", "onblur", "onchange"]
-               elseif tag == 'style'
-                       let attrs = coreattrs + ["id", "type=\"text/css\"", "type", "media", "title", "xml:space"]
-               elseif tag == 'table'
-                       let attrs = coregroup + ["summary", "width", "border", "frame", "rules", "cellspacing", "cellpadding"]
-               elseif tag =~ '^\(thead\|tfoot\|tbody\|tr\)$'
-                       let attrs = coregroup + ["align", "char", "charoff", "valign"]
-               elseif tag == 'textarea'
-                       let attrs = coregroup + ["name", "rows", "cols", "disabled", "readonly", "onselect", "onchange"]
-               elseif tag =~ '^\(th\|td\)$'
-                       let attrs = coregroup + ["abbr", "headers", "scope", "rowspan", "colspan", "align", "char", "charoff", "valign"]
-               else
-                       return []
+
+               " Load data {{{
+               if !exists("g:xmldata_xhtml10s")
+                       runtime! autoload/xml/xhtml10s.vim
                endif
+               " }}}
+               "
+               let attrs = keys(g:xmldata_xhtml10s[tag][1])
 
                for m in sort(attrs)
                        if m =~ '^'.attr
-                               if m =~ '^\(ismap\|defer\|declare\|nohref\|checked\|disabled\|selected\|readonly\)$' || m =~ '='
-                                       call add(res, m)
-                               else
-                                       call add(res, m.'="')
-                               endif
+                               call add(res, m)
                        elseif m =~ attr
-                               if m =~ '^\(ismap\|defer\|declare\|nohref\|checked\|disabled\|selected\|readonly\)$' || m =~ '='
-                                       call add(res2, m)
-                               else
-                                       call add(res2, m.'="')
-                               endif
+                               call add(res2, m)
                        endif
                endfor
-
-               return res + res2
+               let menu = res + res2
+               if has_key(g:xmldata_xhtml10s, 'vimxmlattrinfo')
+                       let final_menu = []
+                       for i in range(len(menu))
+                               let item = menu[i]
+                               if has_key(g:xmldata_xhtml10s['vimxmlattrinfo'], item)
+                                       let m_menu = g:xmldata_xhtml10s['vimxmlattrinfo'][item][0]
+                                       let m_info = g:xmldata_xhtml10s['vimxmlattrinfo'][item][1]
+                                       if m_menu !~ 'Bool'
+                                               let item .= '="'
+                                       endif
+                               else
+                                       let m_menu = ''
+                                       let m_info = ''
+                                       let item .= '="'
+                               endif
+                               let final_menu += [{'word':item, 'menu':m_menu, 'info':m_info}]
+                       endfor
+               else
+                       let final_menu = map(menu, 'v:val."=\""')
+               endif
+               return final_menu
 
        endif
        " }}}
@@ -625,8 +566,25 @@ function! htmlcomplete#CompleteTags(findstart, base)
                        call add(res2, m)
                endif
        endfor
+       let menu = res + res2
+       if has_key(g:xmldata_xhtml10s, 'vimxmltaginfo')
+               let final_menu = []
+               for i in range(len(menu))
+                       let item = menu[i]
+                       if has_key(g:xmldata_xhtml10s['vimxmltaginfo'], item)
+                               let m_menu = g:xmldata_xhtml10s['vimxmltaginfo'][item][0]
+                               let m_info = g:xmldata_xhtml10s['vimxmltaginfo'][item][1]
+                       else
+                               let m_menu = ''
+                               let m_info = ''
+                       endif
+                       let final_menu += [{'word':item, 'menu':m_menu, 'info':m_info}]
+               endfor
+       else
+               let final_menu = menu
+       endif
+       return final_menu
 
-       return res + res2
 
        " }}}
   endif
index 0163fd9b7e12df045d7860a01e93148e4cbc248e..87e40f36d3ab675abbeea241dd12e024c1d267a4 100644 (file)
@@ -12,7 +12,7 @@ function! javascriptcomplete#CompleteJS(findstart, base)
        let compl_begin = col('.') - 2
        " Bit risky but JS is rather limited language and local chars shouldn't
        " fint way into names
-       while start >= 0 && line[start - 1] =~ '\w'
+       while start >= 0 && line[start - 1] =~ '\k'
                let start -= 1
        endwhile
        let b:compl_context = getline('.')[0:compl_begin]
@@ -120,17 +120,17 @@ function! javascriptcomplete#CompleteJS(findstart, base)
                let stris = striprop + strimeth
 
                " User created properties
-               let user_props1 = filter(copy(file), 'v:val =~ "this\\.\\w"')
+               let user_props1 = filter(copy(file), 'v:val =~ "this\\.\\k"')
                let juser_props1 = join(user_props1, ' ')
                let user_props1 = split(juser_props1, '\zethis\.')
                unlet! juser_props1
-               call map(user_props1, 'matchstr(v:val, "this\\.\\zs\\w\\+\\ze")')
+               call map(user_props1, 'matchstr(v:val, "this\\.\\zs\\k\\+\\ze")')
 
-               let user_props2 = filter(copy(file), 'v:val =~ "\\.prototype\\.\\w"')
+               let user_props2 = filter(copy(file), 'v:val =~ "\\.prototype\\.\\k"')
                let juser_props2 = join(user_props2, ' ')
                let user_props2 = split(juser_props2, '\zeprototype\.')
                unlet! juser_props2
-               call map(user_props2, 'matchstr(v:val, "prototype\\.\\zs\\w\\+\\ze")')
+               call map(user_props2, 'matchstr(v:val, "prototype\\.\\zs\\k\\+\\ze")')
                let user_props = user_props1 + user_props2
 
                " HTML DOM properties
@@ -394,11 +394,11 @@ function! javascriptcomplete#CompleteJS(findstart, base)
                "    for regexp "= /re/"
                " 4. Make correction for Microsoft.XMLHTTP ActiveXObject
                " 5. Repeat for external files
-               let object = matchstr(shortcontext, '\zs\w\+\ze\(\[.\{-}\]\)\?\.$')
+               let object = matchstr(shortcontext, '\zs\k\+\ze\(\[.\{-}\]\)\?\.$')
                if len(object) > 0
                        let decl_line = search(object.'.\{-}=\s*new\s*', 'bn')
                        if decl_line > 0
-                               let object_type = matchstr(getline(decl_line), object.'.\{-}=\s*new\s*\zs\w\+\ze')
+                               let object_type = matchstr(getline(decl_line), object.'.\{-}=\s*new\s*\zs\k\+\ze')
                                if object_type == 'ActiveXObject' && matchstr(getline(decl_line), object.'.\{-}=\s*new\s*ActiveXObject\s*(.Microsoft\.XMLHTTP.)') != ''
                                                let object_type = 'XMLHttpRequest'
                                endif
@@ -413,7 +413,7 @@ function! javascriptcomplete#CompleteJS(findstart, base)
                        if decl_line == 0 && exists("b:js_extfiles")
                                let dext_line = filter(copy(b:js_extfiles), 'v:val =~ "'.object.'.\\{-}=\\s*new\\s*"')
                                if len(dext_line) > 0
-                                       let object_type = matchstr(dext_line[-1], object.'.\{-}=\s*new\s*\zs\w\+\ze')
+                                       let object_type = matchstr(dext_line[-1], object.'.\{-}=\s*new\s*\zs\k\+\ze')
                                        if object_type == 'ActiveXObject' && matchstr(dext_line[-1], object.'.\{-}=\s*new\s*ActiveXObject\s*(.Microsoft\.XMLHTTP.)') != ''
                                                        let object_type = 'XMLHttpRequest'
                                        endif
@@ -532,7 +532,7 @@ function! javascriptcomplete#CompleteJS(findstart, base)
        " constructs like: var var1, var2, var3 = "something";
        for i in range(len(variables))
                let comma_separated = split(variables[i], ',\s*')
-               call map(comma_separated, 'matchstr(v:val, "\\w\\+")')
+               call map(comma_separated, 'matchstr(v:val, "\\k\\+")')
                let vars += comma_separated
        endfor
 
@@ -540,11 +540,11 @@ function! javascriptcomplete#CompleteJS(findstart, base)
        unlet! vars
 
        " Add "no var" variables.
-       let undeclared_variables = filter(copy(file), 'v:val =~ "^\\s*\\w\\+\\s*="')
+       let undeclared_variables = filter(copy(file), 'v:val =~ "^\\s*\\k\\+\\s*="')
        let u_vars = []
        for i in range(len(undeclared_variables))
                let  split_equal = split(undeclared_variables[i], '\s*=')
-               call map(split_equal, 'matchstr(v:val, "\\w\\+$")')
+               call map(split_equal, 'matchstr(v:val, "\\k\\+$")')
                let u_vars += split_equal
        endfor
 
@@ -554,10 +554,20 @@ function! javascriptcomplete#CompleteJS(findstart, base)
        " Get functions
        let functions = filter(copy(file), 'v:val =~ "^\\s*function\\s"')
        let arguments = copy(functions)
-       call map(functions, 'matchstr(v:val, "^\\s*function\\s\\+\\zs\\w\\+")')
+       call map(functions, 'matchstr(v:val, "^\\s*function\\s\\+\\zs\\k\\+")')
        call map(functions, 'v:val."("')
        let functions = sort(functions)
 
+       " Create table to keep arguments for additional 'menu' info
+       let b:js_menuinfo = {}
+       for i in arguments
+               let g:ia = i
+               let f_elements = matchlist(i, 'function\s\+\(\k\+\)\s*(\(.\{-}\))')
+               if len(f_elements) == 3
+                       let b:js_menuinfo[f_elements[1].'('] = f_elements[2]
+               endif
+       endfor
+
        " Get functions arguments
        call map(arguments, 'matchstr(v:val, "function.\\{-}(\\zs.\\{-}\\ze)")')
        let jargs = join(arguments, ',')
@@ -590,7 +600,26 @@ function! javascriptcomplete#CompleteJS(findstart, base)
                endif
        endfor
 
-       return res + res2
+       let menu = res + res2
+       let final_menu = []
+       for i in range(len(menu))
+               let item = menu[i]
+               if item =~ '($'
+                       let kind = 'f'
+                       if has_key(b:js_menuinfo, item)
+                               let m_info = b:js_menuinfo[item]
+                       else
+                               let m_info = ''
+                       endif
+               else
+                       let kind = 'v'
+                       let m_info = ''
+               endif
+               let final_menu += [{'word':item, 'menu':m_info, 'kind':kind}]
+       endfor
+       let g:fm = final_menu
+       return final_menu
+
 endfunction
 
 " vim:set foldmethod=marker:
index 0d104a0e9a1d2f6c1602af4bd31636be60eaae83..22e81a4d9346423df1736260e99be827d9b60fdb 100644 (file)
@@ -230,25 +230,42 @@ function! xmlcomplete#CompleteTags(findstart, base)
 
                for m in sort(attrs)
                        if m =~ '^'.attr
-                               if tag !~ '^[?!]' && len(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][m]) > 0 && g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][m][0] =~ '^BOOL$'
-                                       call add(res, m)
-                               elseif m =~ '='
-                                       call add(res, m)
+                               call add(res, m)
+                       elseif m =~ attr
+                               call add(res2, m)
+                       endif
+               endfor
+               let menu = res + res2
+               let final_menu = []
+               if has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}, 'vimxmlattrinfo')
+                       for i in range(len(menu))
+                               let item = menu[i]
+                               if has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmlattrinfo'], item)
+                                       let m_menu = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmlattrinfo'][item][0]
+                                       let m_info = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmlattrinfo'][item][1]
                                else
-                                       call add(res, m.'="')
+                                       let m_menu = ''
+                                       let m_info = ''
                                endif
-                       elseif m =~ attr
-                               if tag !~ '^[?!]' && len(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][m]) > 0 && g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][m][0] =~ '^BOOL$'
-                                       call add(res, m)
-                               elseif m =~ '='
-                                       call add(res, m)
+                               if tag !~ '^[?!]' && len(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][item]) > 0 && g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][item][0] =~ '^\(BOOL\|'.item.'\)$'
+                                       let item = item
                                else
-                                       call add(res2, m.'="')
+                                       let item .= '="'
                                endif
-                       endif
-               endfor
-
-               return res + res2
+                               let final_menu += [{'word':item, 'menu':m_menu, 'info':m_info}]
+                       endfor
+               else
+                       for i in range(len(menu))
+                               let item = menu[i]
+                               if tag !~ '^[?!]' && len(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][item]) > 0 && g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[tag][1][item][0] =~ '^\(BOOL\|'.item.'\)$'
+                                       let item = item
+                               else
+                                       let item .= '="'
+                               endif
+                               let final_menu += [item]
+                       endfor
+               endif
+               return final_menu
 
        endif
        " Close tag
@@ -308,21 +325,36 @@ function! xmlcomplete#CompleteTags(findstart, base)
        let tags = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[opentag][0]
        let context = substitute(context, '^\k*:', '', '')
 
-       if b:xml_namespace == 'DEFAULT'
-               let b:xml_namespace = ''
-       else
-               let b:xml_namespace .= ':'
-       endif
-
        for m in tags
                if m =~ '^'.context
-                       call add(res, b:xml_namespace.m)
+                       call add(res, m)
                elseif m =~ context
-                       call add(res2, b:xml_namespace.m)
+                       call add(res2, m)
                endif
        endfor
-
-       return res + res2
+       let menu = res + res2
+       if has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}, 'vimxmltaginfo')
+               let final_menu = []
+               for i in range(len(menu))
+                       let item = menu[i]
+                       if has_key(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmltaginfo'], item)
+                               let m_menu = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmltaginfo'][item][0]
+                               let m_info = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}['vimxmltaginfo'][item][1]
+                       else
+                               let m_menu = ''
+                               let m_info = ''
+                       endif
+                       if b:xml_namespace == 'DEFAULT'
+                               let xml_namespace = ''
+                       else
+                               let xml_namespace = b:xml_namespace.':'
+                       endif
+                       let final_menu += [{'word':xml_namespace.item, 'menu':m_menu, 'info':m_info}]
+               endfor
+       else
+               let final_menu = menu
+       endif
+       return final_menu
 
   endif
 endfunction
index f545fafdce6774e8de154cf215918a4d6fc7d36f..3688cdae37e2194c874e34ff4e39c7108d717920 100644 (file)
@@ -1,4 +1,4 @@
-*autocmd.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 09
+*autocmd.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 13
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -471,6 +471,7 @@ CursorHoldI                 Just like CursorHold, but in Insert mode.
 CursorMoved                    After the cursor was moved in Normal mode.
                                Not triggered when there is typeahead or when
                                an operator is pending.
+                               For an example see |match-parens|.
                                Careful: Don't do anything that the user does
                                not expect or that is slow.
                                                        *CursorMovedI*
index 676da4bf1910b1d62679bd9594a8df0cca192eeb..b5283bc1af18cc89dc36848715e4b4af3deb21bc 100644 (file)
@@ -1,4 +1,4 @@
-*change.txt*    For Vim version 7.0aa.  Last change: 2005 Dec 16
+*change.txt*    For Vim version 7.0aa.  Last change: 2006 Feb 13
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1168,12 +1168,18 @@ The next three commands always work on whole lines.
 
                                                        *gq*
 gq{motion}             Format the lines that {motion} moves over.
-                       If 'formatprg' is empty formatting is done internally
-                       and the 'textwidth' option controls the length of each
-                       formatted line (see below).
+                       Formatting is done with one of three methods:
+                       1. If 'formatexpr' is not empty the expression is
+                          evaluated.  This can differ for each buffer.
+                       2. If 'formatprg' is not mepty an external program
+                          is used.
+                       3. Otherise formatting is done internally.
+
+                       In the third case the 'textwidth' option controls the
+                       length of each formatted line (see below).
                        If the 'textwidth' option is 0, the formatted line
                        length is the screen width (with a maximum width of
-                       79).  {not in Vi}
+                       79).
                        The 'formatoptions' option controls the type of
                        formatting |fo-table|.
                        The cursor is left on the first non-blank of the last
@@ -1193,8 +1199,8 @@ gqq                       Format the current line.  {not in Vi}
                                                        *gw*
 gw{motion}             Format the lines that {motion} moves over.  Similar to
                        |gq| but puts the cursor back at the same position in
-                       the text.  However, 'formatprg' is not used.
-                       {not in Vi}
+                       the text.  However, 'formatprg' and 'formatexpr' are
+                       not used.  {not in Vi}
 
 gwgw                                                   *gwgw* *gww*
 gww                    Format the current line as with "gw".  {not in Vi}
@@ -1225,9 +1231,10 @@ white space!).
 
 The 'joinspaces' option is used when lines are joined together.
 
-You can set the 'formatprg' option to the name of an external program for Vim
-to use for text formatting.  The 'textwidth' and other options have no effect
-on formatting by an external program.
+You can set the 'formatexpr' option to an expression or the 'formatprg' option
+to the name of an external program for Vim to use for text formatting.  The
+'textwidth' and other options have no effect on formatting by an external
+program.
 
                                                        *right-justify*
 There is no command in Vim to right justify text.  You can do it with
index 5364f60b1abd44f00a4c9b758eca4cb26a44282c..0f339e1119017b5cb741cc5912efc538b00b0674 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 10
+*eval.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1203,6 +1203,7 @@ v:count           The count given for the last Normal mode command.  Can be used
        :map _x :<C-U>echo "the count is " . v:count<CR>
 <              Note: The <C-U> is required to remove the line range that you
                get when typing ':' after a count.
+               Also used for evaluating the 'formatexpr' option.
                "count" also works, for backwards compatibility.
 
                                        *v:count1* *count1-variable*
@@ -1624,6 +1625,7 @@ nextnonblank( {lnum})             Number  line nr of non-blank line >= {lnum}
 nr2char( {expr})               String  single char with ASCII value {expr}
 prevnonblank( {lnum})          Number  line nr of non-blank line <= {lnum}
 printf( {fmt}, {expr1}...)     String  format text
+pumvisible()                   Number  whether popup menu is visible
 range( {expr} [, {max} [, {stride}]])
                                List    items from {expr} to {max}
 readfile({fname} [, {binary} [, {max}]])
@@ -1647,6 +1649,10 @@ searchdecl({name} [, {global} [, {thisblock}]])
                                Number  search for variable declaration
 searchpair( {start}, {middle}, {end} [, {flags} [, {skip}]])
                                Number  search for other end of start/end pair
+searchpairpos( {start}, {middle}, {end} [, {flags} [, {skip}]])
+                               List    search for other end of start/end pair
+searchpos( {pattern} [, {flags}])
+                               List    search for {pattern}
 server2client( {clientid}, {string})
                                Number  send reply string
 serverlist()                   String  get a list of available servers
@@ -3471,6 +3477,15 @@ nr2char({expr})                                          *nr2char()*
                characters.  nr2char(0) is a real NUL and terminates the
                string, thus results in an empty string.
 
+prevnonblank({lnum})                                   *prevnonblank()*
+               Return the line number of the first line at or above {lnum}
+               that is not blank.  Example: >
+                       let ind = indent(prevnonblank(v:lnum - 1))
+<              When {lnum} is invalid or there is no non-blank line at or
+               above it, zero is returned.
+               Also see |nextnonblank()|.
+
+
 printf({fmt}, {expr1} ...)                             *printf()*
                Return a String with {fmt}, where "%" items are replaced by
                the formatted form of their respective arguments.  Example: >
@@ -3598,13 +3613,10 @@ printf({fmt}, {expr1} ...)                              *printf()*
                arguments an error is given.  Up to 18 arguments can be used.
 
 
-prevnonblank({lnum})                                   *prevnonblank()*
-               Return the line number of the first line at or above {lnum}
-               that is not blank.  Example: >
-                       let ind = indent(prevnonblank(v:lnum - 1))
-<              When {lnum} is invalid or there is no non-blank line at or
-               above it, zero is returned.
-               Also see |nextnonblank()|.
+pumvisible()                                           *pumvisible()*
+               Returns non-zero when the popup menu is visible, zero
+               otherwise.  See |ins-completion-menu|.
+
 
                                                        *E726* *E727*
 range({expr} [, {max} [, {stride}]])                           *range()*
@@ -3714,9 +3726,9 @@ remote_send({server}, {string} [, {idvar}])
                Send the {string} to {server}.  The string is sent as input
                keys and the function returns immediately.  At the Vim server
                the keys are not mapped |:map|.
-               If {idvar} is present, it is taken as the name of a
-               variable and a {serverid} for later use with
-               remote_read() is stored there.
+               If {idvar} is present, it is taken as the name of a variable
+               and a {serverid} for later use with remote_read() is stored
+               there.
                See also |clientserver| |RemoteReply|.
                This function is not available in the |sandbox|.
                {only available when compiled with the |+clientserver| feature}
@@ -3919,6 +3931,27 @@ searchpair({start}, {middle}, {end} [, {flags} [, {skip}]])
 
        :echo searchpair('{', '', '}', 'bW',
             \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string"')
+<
+                                                       *searchpairpos()*
+searchpairpos({start}, {middle}, {end} [, {flags} [, {skip}]])
+               Same as searchpair(), but returns a List with the line and
+               column position of the match. The first element of the List is
+               the line number and the second element is the byte index of
+               the column position of the match.  If no match is found,
+               returns [0, 0].
+>
+                       :let [lnum,col] = searchpairpos('{', '', '}', 'n')
+<
+               See |match-parens| for a bigger and more useful example.
+
+searchpos({pattern} [, {flags}])                       *searchpos()*
+               Same as search(), but returns a List with the line and column
+               position of the match. The first element of the List is the
+               line number and the second element is the byte index of the
+               column position of the match. If no match is found, returns
+               [0, 0].
+>
+                       :let [lnum,col] = searchpos('mypattern', 'n')
 <
 server2client( {clientid}, {string})                   *server2client()*
                Send a reply string to {clientid}.  The most recent {clientid}
index ea87249a1e607030a835291f4e95ed4994b86a4f..066cfd496c4f55e36d236fde9ef61105b83776ef 100644 (file)
@@ -1,4 +1,4 @@
-*gui.txt*       For Vim version 7.0aa.  Last change: 2005 Aug 07
+*gui.txt*       For Vim version 7.0aa.  Last change: 2006 Feb 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -37,7 +37,8 @@ The X11 version of Vim can run both in GUI and in non-GUI mode.  See
 
                                        *gui-init* *gvimrc* *.gvimrc* *_gvimrc*
 When the GUI starts up initializations are carried out, in this order:
-- The termcap options are reset to their default value for the GUI.
+- The 'term' option is set to "builgin_gui" and terminal options are reset to
+  their default value for the GUI |terminal-options|.
 - If the system menu file exists, it is sourced.  The name of this file is
   normally "$VIMRUNTIME/menu.vim".  You can check this with ":version".  Also
   see |$VIMRUNTIME|.  To skip loading the system menu include 'M' in
index 74c2c586193b7e4dc80b56c732a46b48090bb189..450f6670fd8822c41c36dcd340797c8c331a69e9 100644 (file)
@@ -1,4 +1,4 @@
-*insert.txt*    For Vim version 7.0aa.  Last change: 2006 Feb 10
+*insert.txt*    For Vim version 7.0aa.  Last change: 2006 Feb 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -126,8 +126,10 @@ CTRL-R {0-9a-z"%#*+:.-=}                                   *i_CTRL-R*
                        '='     the expression register: you are prompted to
                                enter an expression (see |expression|)
                                Note that 0x80 (128 decimal) is used for
-                               special keys, use CTRL-R CTRL-R to insert it
-                               literally.
+                               special keys.  E.g., you can use this to move
+                               the cursor up:
+                                       CTRL-R ="\<Up>"
+                               Use CTRL-R CTRL-R to insert text literally.
                See |registers| about registers.  {not in Vi}
 
 CTRL-R CTRL-R {0-9a-z"%#*+/:.-=}                       *i_CTRL-R_CTRL-R*
@@ -422,7 +424,7 @@ When 'textwidth' and 'wrapmargin' are both set, 'textwidth' is used.
 If you don't really want to break the line, but view the line wrapped at a
 convenient place, see the 'linebreak' option.
 
-The line is only broken automatically when using insert mode, or when
+The line is only broken automatically when using Insert mode, or when
 appending to a line.  When in replace mode and the line length is not
 changed, the line will not be broken.
 
@@ -438,6 +440,10 @@ characters to the 'formatoptions' option:
      current insert command.  Only differs from "l" when entering non-white
      characters while crossing the 'textwidth' boundary.
 
+Normally an internal function will be used to decide where to break the line.
+If you want to do it in a different way set the 'formatexpr' option to an
+expression that will take care of the line break.
+
 If you want to format a block of text, you can use the "gq" operator.  Type
 "gq" and a movement command to move the cursor to the end of the block.  In
 many cases, the command "gq}" will do what you want (format until the end of
@@ -622,8 +628,8 @@ CTRL-X CTRL-L               Search backwards for a line that starts with the
                        the cursor.  Indent is ignored.  The matching line is
                        inserted in front of the cursor.
                        The 'complete' option is used to decide which buffers
-                       are searched for a match.  Only loaded buffers are
-                       used.
+                       are searched for a match.  Both loaded and unloaded
+                       buffers are used.
        CTRL-L  or
        CTRL-P          Search backwards for next matching line.  This line
                        replaces the previous matching line.
@@ -1071,25 +1077,37 @@ The menu is used when:
 - The terminal supports at least 8 colors.
 - There are at least two matches.
 
-While the menu is displayed these keys have a special meaning:
-<CR> and <Enter>  Accept the currently selected match
+There are two states:
+1. A complete match has been inserted.
+2. Only part of a match has been inserted.
 
-<PageUp>         Select a match several entries back
-<PageDown>       Select a match several entries further
+When "longest" is in 'completeopt' and there is more than one match you start
+in the second state.
+
+In the first state these keys have a special meaning:
+<BS> and CTRL-H   Delete one character, find the matches for the word before
+                 the cursor.  This reduces the list of matches, often to one
+                 entry.  Switches to the second state.
 
+In the second state these keys have a special meaning:
 <BS> and CTRL-H   Delete one character, find the matches for the shorter word
                  before the cursor.  This may find more matches.
 CTRL-L           Add one character from the current match, may reduce the
-                 number of matches.  Does not work after selecting one of the
-                 matches with CTRL-N, <Up>, etc.
+                 number of matches.
+any printable character: Add this character and reduce the number of matches.
+
+In both states these can be used:
+<CR> and <Enter>  Accept the currently selected match
+<PageUp>         Select a match several entries back
+<PageDown>       Select a match several entries further
 <Up>             Select the previous match, as if CTRL-P was used, but don't
-                 insert it when editing the selection.
+                 insert the newly selected word.
 <Down>           Select the next match, as if CTRL-N was used, but don't
-                 insert it when editing the selection.
+                 insert the newly selected word.
+
+If you select another match, e.g., with CTRL-N or CTRL-P, you go back to the
+first state.  However, the list of matches doesn't change.
 
-The selection is being edited after typing <BS>, CTRL-L or when using the
-longest common match.  This stops when a match is inserted, as with CTRL-N or
-CTRL-P.
 
 The colors of the menu can be changed with these highlight groups:
 Pmenu          normal item  |hl-Pmenu|
@@ -1097,8 +1115,16 @@ PmenuSel selected item  |hl-PmenuSel|
 PmenuSbar      scrollbar  |hl-PmenuSbar|
 PmenuThumb     thumb of the scrollbar  |hl-PmenuThumb|
 
+There are no special mappings for when the popup menu is visible.  However,
+you can use an Insert mode mapping that checks the |pumvisible()| function to
+do something different.  Example: >
+       :inoremap <Down> <C-R>=pumvisible() ? "\<lt>C-N>" : "\<lt>Down>"<CR>
+
+
+FILETYPE-SPECIFIC REMARKS FOR OMNI COMPLETION      *compl-omni-filetypes*
 
-Filetype-specific remarks for omni completion      *compl-omni-filetypes*
+The file used for {filetype} should be autoload/{filetype}complete.vim
+in 'runtimepath'.  Thus for "java" it is autoload/javacomplete.vim.
 
 
 C                                                      *ft-c-omni*
@@ -1144,23 +1170,22 @@ specification.
 HTML and XHTML                                         *ft-html-omni*
                                                        *ft-xhtml-omni*
 
-CTRL-X CTRL-O provides completion of various elements of (X)HTML files.
-It is designed to support writing of XHTML 1.0 Strict files but will
-also works for other versions of HTML. Features:
+CTRL-X CTRL-O provides completion of various elements of (X)HTML files.  It is
+designed to support writing of XHTML 1.0 Strict files but will also works for
+other versions of HTML. Features:
 
-- after "<" complete tag name depending on context (no div suggestion
-  inside of an a tag)
-- inside of tag complete proper attributes (no width attribute for an
-  a tag)
-- when attribute has limited number of possible values help to complete
-  them
+- after "<" complete tag name depending on context (no div suggestion inside
+  of an a tag); '/>' indicates empty tags
+- inside of tag complete proper attributes (no width attribute for an a tag);
+  show also type of attribute; '*' indicates required attributes
+- when attribute has limited number of possible values help to complete them
 - complete names of entities
 - complete values of "class" and "id" attributes with data obtained from
-  style tag and included CSS files
+  <style> tag and included CSS files
 - when completing value of "style" attribute or working inside of "style" tag
   switch to |ft-css-omni| completion
-- when completing values of events attributes or working inside of "script" tag
-  switch to |ft-javascript-omni| completion
+- when completing values of events attributes or working inside of "script"
+  tag switch to |ft-javascript-omni| completion
 - when used after "</" CTRL-X CTRL-O will close the last opened tag
 
 Note: When used first time completion menu will be shown with little delay
@@ -1176,7 +1201,7 @@ Completion of most elements of JavaScript language and DOM elements.
 Complete:
 
 - variables
-- function name
+- function name; show function arguments
 - function arguments
 - properties of variables trying to detect type of variable
 - complete DOM objects and properties depending on context
@@ -1244,7 +1269,7 @@ Format of XML data file                                   *xml-omni-datafile*
 
 Vim distribution provides two data files as examples (xhtml10s.vim, xsl.vim)
 
-XML data files are stored in "autoload/xml" directory in 'runtimepath'. They
+XML data files are stored in "autoload/xml" directory in 'runtimepath'.  They
 have meaningful name which will be used in commands. It should be unique name
 which will not create conflicts in future. For example name xhtml10s.vim means
 it is data file for XHTML 1.0 Strict.
@@ -1258,9 +1283,9 @@ compound from two parts:
 Part two must be exactly the same as name of file.
 
 Variable is data structure in form of |Dictionary|. Keys are tag names and
-values are two element |List|. First element of List is also List with
-names of possible children, second element is |Dictionary| with names of
-attributes as keys and possible values of attributes as values. Example: >
+values are two element |List|. First element of List is also List with names
+of possible children, second element is |Dictionary| with names of attributes
+as keys and possible values of attributes as values. Example: >
 
     let g:xmldata_crippledhtml = {
     \ "html": 
@@ -1272,21 +1297,31 @@ attributes as keys and possible values of attributes as values. Example: >
     \ "meta": 
     \ [ [], {"id": [], "http-equiv": [], "name": [], "content": [], "scheme": 
     \ [], "lang": [], "xml:lang": [], "dir": ["ltr", "rtl"]}]
-    \ "vimxmlentities": ["amp", "lt", "gt", "apos", "quot"]}
+    \ "vimxmlentities": ["amp", "lt", "gt", "apos", "quot"]},
+    \ "vimxmltaginfo": {
+    \ 'meta': ['/>', '']},
+    \ "vimxmlattrinfo": {
+    \ 'http-equiv': ['ContentType', '']}
 
 This example should be put in "autoload/xml/crippledhtml.vim" file.
 
-In example are visible two special elements:
+In example are visible four special elements:
 
 1. "vimxmlentities" - special key with List containing entities of this XML
    dialect.
 2. "BOOL" - value of attribute key showing if attribute should be inserted
    bare ("defer" vs. 'defer="'). It can be the only element of List of
    attribute values.
+3. "vimxmltaginfo" - special key with dictionary containing as key tag names,
+   as value two element List for additional menu info and long description.
+4. "vimxmlattrinfo" - special key with dictionary containing as key attribute
+   names, as value two element List for additional menu info and long
+   description.
 
 Note: Tag names in data file MUST not contain namespace description. Check
 xsl.vim for example.
 
+
 Commands
 
 :XMLns {name} [{namespace}]                                    *:XMLns*
index 4cf0d3362cb169dbe1c6fbdb4c09c5f9843f1ad4..c9aa452f4892580572e71af6cd9460eb1be85f6f 100644 (file)
@@ -1,4 +1,4 @@
-*options.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 10
+*options.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -127,7 +127,7 @@ Note that an option may also have been set as a side effect of setting
 {not available when compiled without the +eval feature}
 
                                                        *:set-termcap* *E522*
-For {option} the form "t_xx" may be used to set a termcap option.  This will
+For {option} the form "t_xx" may be used to set a terminal option.  This will
 override the value from the termcap.  You can then use it in a mapping.  If
 the "xx" part contains special characters, use the <t_xx> form: >
        :set <t_#4>=^[Ot
@@ -2036,8 +2036,8 @@ A jump table for the options with a short description can be found at |Q_op|.
                        global
                        {not in Vi}
        When set to "msg", error messages that would otherwise be omitted will
-       be given anyway.  This is useful when debugging 'foldexpr' or
-       'indentexpr'.
+       be given anyway.  This is useful when debugging 'foldexpr',
+       'formatexpr' or 'indentexpr'.
        When set to "beep", a message will be given when otherwise only a beep
        would be produced.
        The values can be combined, separated by a comma.
@@ -2882,17 +2882,43 @@ A jump table for the options with a short description can be found at |Q_op|.
                        global
                        {not in Vi}
        The name of an external program that will be used to format the lines
-       selected with the "gq" command.  The program must take the input on
+       selected with the |gq| operator.  The program must take the input on
        stdin and produce the output on stdout.  The Unix program "fmt" is
        such a program.
-       If this option is an empty string, the internal format function will
-       be used |C-indenting|.
+       If the 'formatexpr' option is not empty it will be used instead.
+       Otherwise, if 'formatprg' option is an empty string, the internal
+       format function will be used |C-indenting|.
        Environment variables are expanded |:set_env|.  See |option-backslash|
        about including spaces and backslashes.
-       This option cannot be set from a |modeline| or in the |sandbox|, for
-       security reasons.
+       The expression may be evaluated in the |sandbox|, see
+       |sandbox-option|.
+
+                                               *'formatexpr'* *'fex'*
+'formatexpr' 'fex'     string (default "")
+                       local to buffer
+                       {not in Vi}
+                       {not available when compiled without the |+eval|
+                       feature}
+       Expression which is evaluated to format a range of lines for the |gq|
+       operator.  The |v:lnum| variable holds the first line to be formatted,
+       |v:count| the number of lines to be formatted.
+       When this option is empty 'formatprg' is used.
+       Example: >
+               :set formatexp=mylang#Format()
+<      This will invoke the mylang#Format() function in the
+       autoload/mylang.vim file in 'runtimepath'. |autoload|
+
+       The expression is also evaluated when 'textwidth' is set and adding
+       text beyond that limit.  This happens under the same conditions as
+       when internal formatting is used.  Make sure the cursor is kept in the
+       same spot relative to the text then!  The |mode()| function will
+       return "i" or "R" in this situation.  When the function returns
+       non-zero Vim will fall back to using the internal format mechanism.
+
+       The expression may be evaluated in the |sandbox|, see
+       |sandbox-option|.
 
-                                                       *'fsync'* *'fs'*
+                                               *'fsync'* *'fs'*
 'fsync' 'fs'           boolean (default on)
                        global
                        {not in Vi}
@@ -7016,7 +7042,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 'weirdinvert' 'wiv'    boolean (default off)
                        global
                        {not in Vi}
-       This option has the same effect as the 't_xs' termcap option.
+       This option has the same effect as the 't_xs' terminal option.
        It is provided for backwards compatibility with version 4.x.
        Setting 'weirdinvert' has the effect of making 't_xs' non-empty, and
        vice versa.  Has no effect when the GUI is running.
index 3c82f17fe06a8506efad1601707c7dc2820e419d..09f915d46ef332824d8804ec44e92b7e3a278a37 100644 (file)
@@ -1,4 +1,4 @@
-*os_dos.txt*    For Vim version 7.0aa.  Last change: 2003 Dec 20
+*os_dos.txt*    For Vim version 7.0aa.  Last change: 2006 Feb 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -126,8 +126,8 @@ text.  For example, to get grey text on a blue background: >
 See |highlight-groups| for other groups that are available.
 
 A DOS console does not support attributes like bold and underlining.  You can
-set the color used in five modes with nine termcap options.  Note that this is
-not necessary since you can set the color directly with the ":highlight"
+set the color used in five modes with nine terminal options.  Note that this
+is not necessary since you can set the color directly with the ":highlight"
 command; these options are for backward compatibility with older Vim versions.
 The |'highlight'| option specifies which of the five modes is used for which
 action. >
index 27804b02f717a1be9c9a5b76c39ad3dfbb0c96bc..2a1990908467dd021d1b8cff3f5055780752c96f 100644 (file)
@@ -1,4 +1,4 @@
-*pattern.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 01
+*pattern.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -161,7 +161,7 @@ The offset gives the cursor position relative to the found match:
     s[-num]    [num] characters to the left of the start of the match
     b[+num]    [num] identical to s[+num] above (mnemonic: begin)
     b[-num]    [num] identical to s[-num] above (mnemonic: begin)
-    ;{pattern}  perform another searcn, see |//;|
+    ;{pattern}  perform another search, see |//;|
 
 If a '-' or '+' is given but [num] is omitted, a count of one will be used.
 When including an offset with 'e', the search becomes inclusive (the
index ffa3b07fcdc0c287ad89dd02ac3fda5c0acd7d7a..192778c1dc144260fce89cf17893ae3e691511bc 100644 (file)
@@ -1,4 +1,4 @@
-*quickref.txt*  For Vim version 7.0aa.  Last change: 2006 Jan 11
+*quickref.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 13
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -692,6 +692,7 @@ Short explanation of each option:           *option-list*
 |'formatlistpat'| |'flp'|    pattern used to recognize a list header
 |'formatoptions'| |'fo'|     how automatic formatting is to be done
 |'formatprg'|    |'fp'|     name of external program used with "gq" command
+|'formatexpr'|   |'fex'|    expression used with "gq" command
 |'fsync'|        |'fs'|     whether to invoke fsync() after file write
 |'gdefault'|     |'gd'|     the ":substitute" flag 'g' is default on
 |'grepformat'|   |'gfm'|    format of 'grepprg' output
index 1579e214190f26427d97574f2ab6b86eeb658fc2..d21a52dc2acde4e53eab6bf4f3c3824e0917bbd9 100644 (file)
@@ -1,4 +1,4 @@
-*starting.txt*  For Vim version 7.0aa.  Last change: 2006 Jan 19
+*starting.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -706,7 +706,8 @@ accordingly.  Vim proceeds in this order:
        'shell' option.  On MS-DOS and Win32, the COMSPEC variable is used
        if SHELL is not set.
        The environment variable TERM, if it exists, is used to set the 'term'
-       option.
+       option.  However, 'term' will change later when starting the GUI (step
+       8 below).
 
 2. Process the arguments
        The options and file names from the command that start Vim are
index d2ab20bbb01130837a05498f010728c187752faf..9c49ee714e7d2484e1118b0acc156e34b7ac3c2b 100644 (file)
@@ -202,6 +202,7 @@ $VIMRUNTIME starting.txt    /*$VIMRUNTIME*
 'fen'  options.txt     /*'fen'*
 'fenc' options.txt     /*'fenc'*
 'fencs'        options.txt     /*'fencs'*
+'fex'  options.txt     /*'fex'*
 'ff'   options.txt     /*'ff'*
 'ffs'  options.txt     /*'ffs'*
 'fileencoding' options.txt     /*'fileencoding'*
@@ -231,6 +232,7 @@ $VIMRUNTIME starting.txt    /*$VIMRUNTIME*
 'foldnestmax'  options.txt     /*'foldnestmax'*
 'foldopen'     options.txt     /*'foldopen'*
 'foldtext'     options.txt     /*'foldtext'*
+'formatexpr'   options.txt     /*'formatexpr'*
 'formatlistpat'        options.txt     /*'formatlistpat'*
 'formatoptions'        options.txt     /*'formatoptions'*
 'formatprg'    options.txt     /*'formatprg'*
@@ -5870,6 +5872,7 @@ mark-motions      motion.txt      /*mark-motions*
 masm.vim       syntax.txt      /*masm.vim*
 match()        eval.txt        /*match()*
 match-highlight        pattern.txt     /*match-highlight*
+match-parens   tips.txt        /*match-parens*
 matchend()     eval.txt        /*matchend()*
 matchit-install        usr_05.txt      /*matchit-install*
 matchlist()    eval.txt        /*matchlist()*
@@ -6312,6 +6315,7 @@ progname-variable eval.txt        /*progname-variable*
 progress.vim   syntax.txt      /*progress.vim*
 ptcap.vim      syntax.txt      /*ptcap.vim*
 pterm-mouse    options.txt     /*pterm-mouse*
+pumvisible()   eval.txt        /*pumvisible()*
 put    change.txt      /*put*
 put-Visual-mode        change.txt      /*put-Visual-mode*
 python if_pyth.txt     /*python*
@@ -6532,6 +6536,8 @@ search-range      pattern.txt     /*search-range*
 search-replace change.txt      /*search-replace*
 searchdecl()   eval.txt        /*searchdecl()*
 searchpair()   eval.txt        /*searchpair()*
+searchpairpos()        eval.txt        /*searchpairpos()*
+searchpos()    eval.txt        /*searchpos()*
 section        motion.txt      /*section*
 sed.vim        syntax.txt      /*sed.vim*
 self   eval.txt        /*self*
@@ -7014,6 +7020,7 @@ termcap-changed   version4.txt    /*termcap-changed*
 termcap-colors term.txt        /*termcap-colors*
 termcap-cursor-color   term.txt        /*termcap-cursor-color*
 termcap-cursor-shape   term.txt        /*termcap-cursor-shape*
+termcap-options        term.txt        /*termcap-options*
 termcap-title  term.txt        /*termcap-title*
 terminal-colors        os_unix.txt     /*terminal-colors*
 terminal-info  term.txt        /*terminal-info*
index 49da29e77a14ac77904be90c42fb3d7dcdfbcc03..b0a4bd8869e98d319a132a9db6d6201d74a7335c 100644 (file)
@@ -1,4 +1,4 @@
-*term.txt*      For Vim version 7.0aa.  Last change: 2005 Dec 14
+*term.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -208,7 +208,7 @@ starts with CSI, it assumes that the terminal is in 8-bit mode and will
 convert all key sequences to their 8-bit variants.
 
 ==============================================================================
-2. Terminal options                            *terminal-options* *E436*
+2. Terminal options            *terminal-options* *termcap-options* *E436*
 
 The terminal options can be set just like normal options.  But they are not
 shown with the ":set all" command.  Instead use ":set termcap".
index d60ff14830ac0a32232596dceae63ae2e172d47e..5e40cdaf4af06056e9bd52ba8bf9074f8ea8c46a 100644 (file)
@@ -1,4 +1,4 @@
-*tips.txt*      For Vim version 7.0aa.  Last change: 2005 Apr 19
+*tips.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 13
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -24,6 +24,7 @@ Compressing the help files                    |gzip-helpfile|
 Hex editing                                    |hex-editing|
 Executing shell commands in a window           |shell-window|
 Using <> notation in autocommands              |autocmd-<>|
+Highlighting matching parens                   |match-parens|
 
 ==============================================================================
 Editing C programs                                     *C-editing*
@@ -443,4 +444,58 @@ forget to double the number of existing backslashes and put a backslash before
 For a real buffer menu, user functions should be used (see |:function|), but
 then the <> notation isn't used, which defeats using it as an example here.
 
+==============================================================================
+Highlighting matching parens                                   *match-parens*
+
+This example shows the use of a few advanced tricks:
+- using the |CursorMoved| autocommand event
+- using |searchpairpos()| to find a matching paren
+- using |:match| to highlight something
+- using a |pattern| to match a specific position in the file.
+
+This should be put in a Vim script file, since it uses script-local variables.
+Note that it doesn't recognize strings or comments in the text.
+>
+       let s:paren_hl_on = 0
+       function s:Highlight_Matching_Paren()
+         if s:paren_hl_on
+           match none
+           let s:paren_hl_on = 0
+         endif
+
+         let c_lnum = line('.')
+         let c_col = col('.')
+
+         let c = getline(c_lnum)[c_col - 1]
+         let plist = split(&matchpairs, ':\|,')
+         let i = index(plist, c)
+         if i < 0
+           return
+         endif
+         if i % 2 == 0
+           let s_flags = 'nW'
+           let c2 = plist[i + 1]
+         else
+           let s_flags = 'nbW'
+           let c2 = c
+           let c = plist[i - 1]
+         endif
+         if c == '['
+           let c = '\['
+           let c2 = '\]'
+         endif
+
+         let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags)
+
+         if m_lnum > 0 && m_lnum >= line('w0') && m_lnum <= line('w$')
+           exe 'match Search /\(\%' . c_lnum . 'l\%' . c_col .
+                 \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
+           let s:paren_hl_on = 1
+         endif
+       endfunction
+
+       autocmd CursorMoved * call s:Highlight_Matching_Paren()
+       autocmd InsertEnter * match none
+<
+
  vim:tw=78:ts=8:ft=help:norl:
index 23267a69d549f2549ff9896d362cde30954f722f..59bc24e1fef606f9fd51f208ce2463a25bb32a0e 100644 (file)
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 10
+*todo.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -30,19 +30,48 @@ be worked on, but only if you sponsor Vim development.  See |sponsor|.
                                                        *known-bugs*
 -------------------- Known bugs and current work -----------------------
 
+Support WINDOW TABS.  Works like several pages, each with their own split
+windows.  Let's call them "tab pages".
+
+    todo:
+    - ":qa"?
+    - "2gt" doesn't restore syntax HL.  GUI: scrollbars are wrong.
+    - line at top of frame with tabs.  'tabline' option 0/1/2 like 'laststatus'
+       Use the name of the first buffer in the tab (ignoring the help window,
+       unless it's the only one).  Add a number for the window count.
+       Add 'tabtext' option, like 'statusline'.
+       Select tab with mouse.
+    - When deleting a buffer also close windows in other tab pages.
+    - check all places where (firstwin == lastwin) is used (and vise versa)
+    - check all places wheren only_one_window() is used.
+    - When Vim window is resized all tabs must be resized.
+    - E999
+    - ":tabclose N" close tab N
+    docs:
+       :tabedit
+       :tabfind
+       :tab N
+       :tabs
+       {count}gt
+       :tabclose
+       :close and :quit (last window in tab)
+       "gt": Use "1gt" - "99gt" to switch to another tab.  "gt" goes to the
+            next one.  Hint in docs: To mess with another buffer, without
+            changing the window layout, do this in another tab.
+
+    add GUI Tabs for some systems.
+    Patch for GTK 1.2 passed on by Christian Michon, 2004 Jan 6.
+    Simple patch for GTK by Luis M (nov 7).
+
+    Don't forget to provide an "X" to close the current tab.
+
+    Need to be able to search the windows in inactive tabs, e.g. for the
+    quickfix window.
+
+
 Crash with X command server (Ciaran McCreesh).
 
-ccomplete / omnicomplete:
-- For C add tag "kind" field to each match?
-- Flickering because of syntax highlighting redrawing further lines.
-- Finding out if an item has members (to add '.' or '->') requires a grep in
-  the tags files, that is very slow.  Is there another solution?  At least
-  stop at the first match.
-  Could build the list of items for each structure in memory.  Is that faster?
-  Not using too much memory?
-- When a typedef or struct is local to a file only use it in that file?
-- Special mappings for when the popup menu is visible?  Would allow for making
-  a specific selection (e.g, methods vs variables).
+Ctags still hasn't included the patch...
 
 spelling:
 - Also use the spelling dictionary for dictionary completion.
@@ -87,13 +116,6 @@ spelling:
   adding a bad word like "zw" would.  Use "zuw" to undo "zw"?  (Antonio
   Colombo)
 
-7   Add plugins for formatting.  Should be able to make a choice depending on
-    the language of a file (English/Korean/Japanese/etc.).
-    Setting the 'langformat' option to "chinese" would load the
-    "format/chinese.vim" plugin.
-Edward L. Fox explains how it should be done for most Asian languages. (2005
-Nov 24)
-
 An error in a function uses a line number that doesn't take line continuation
 into account. (Mikolaj Machowski)  Store line count in an extra array?
 
@@ -113,7 +135,6 @@ Mac unicode patch (Da Woon Jung):
   (Alan Schmitt)
 
 Patch to add a few flags to search(). (Benji Fisher, Nov 29, doc update Dec 1)
-Also add search???() function that returns list with lnum and col.
 
 Win32: Use the free downloadable compiler 7.1 (2003).  Figure out how to do
 debugging (with Agide?) and describe it. (George Reilly)
@@ -125,9 +146,6 @@ Try using Visual C++ Express 2005. (Ilya Bobir Dec 20)
 Win32: Check that installer puts menu items in "all users" dir when possible,
 not administrator dir.
 
-CTRL-X CTRL-L only completes from loaded buffers.  Make it work for unloaded
-buffers too?
-
 Autoload:
 - Add a Vim script in $VIMRUNTIME/tools that takes a file with a list of
   script names and a help file and produces a script that can be sourced to
@@ -158,48 +176,30 @@ Awaiting response:
 
 CONSIDERED FOR VERSION 7.0:
 
--   Omni completion: Understands the programming language and finds matches
-    that make sense.  Esp. members of classes/structs.
-
-    It's not much different from other Insert-mode completion, use the same
-    mechanism.  Use CTRL-X CTRL-O and 'omnifunc'.  Set 'omnifunc' in the
-    filetype plugin, define the function in the autoload directory.
-    
-    Separately develop the completion logic and the UI.  When adding UI stuff
-    make it work for all completion methods.
+Omni completion:
+    ccomplete:
+    - Finding out if an item has members (to add '.' or '->') requires a grep
+      in the tags files, that is very slow.  Is there another solution?  At
+      least stop at the first match.
+      Could build the list of items for each structure in memory.  Is that
+      faster?  Not using too much memory?
+    - For C add tag "kind" field to each match?
+    - Flickering because of syntax highlighting redrawing further lines.
+    - When a typedef or struct is local to a file only use it in that file?
 
     UI:
-    - Complete longest common string first, like 'wildmode' "longest:full".
     - Add an "auto" mode: after typing a character (or string) completion is
       done for the longest common string.  plugin defines the possible
       characters/strings. (Martin Stubenschrott)
+      And/or: Provide a function to popup the menu, so that an insert mode
+      mapping can start it (with a specific selection).
     - GUI implementation of the popup menu.
-    - When using tags, show match in preview window (function prototype,
-      struct member, etc.).
+    - Show "info" from a match in preview window.
       Or use one window for matches, another for context/info (Doug Kearns,
       2005 Sep 13)
     - Ideas on: http://www.wholetomato.com/
 
-
     Completion logic:
-       Use runtime/autoload/{filetype}complete.vim files.
-
-       In function arguments suggest variables of expected type.
-       Tags file has "signature" field.
-
-       List of completions is a Dictionary with items:
-           complist[0]['text'] = completion text
-           complist[0]['type'] = type of completion (e.g. function, var, arg)
-           complist[0]['help'] = help text (e.g. function declaration)
-           complist[0]['helpfunc'] = function that shows help text
-           etc.
-
-       Can CTRL-] (jump to tag) include the "." and "->" to restrict the
-       number of possible matches? (Flemming Madsen)
-
-       In general: Besides completion, figure out the type of a variable
-       and use it for information.
-
        Ideas from others:
        http://www.vim.org/scripts/script.php?script_id=747
            http://sourceforge.net/projects/insenvim
@@ -212,10 +212,6 @@ CONSIDERED FOR VERSION 7.0:
            Uses ctags to find the info:
                ctags -f $allTagsFile --fields=+aiKmnsSz --language-force=C++ --C++-kinds=+cefgmnpsut-dlux -u $files
 
-           UI: popup menu with list of alternatives, icon to indicate type
-               optional popup window with info about selected alternative
-           Unrelated settings are changed (e.g. 'mousemodel').
-
        www.vim.org script 1213 (Java Development Environment) (Fuchuan Wang)
        IComplete: http://www.vim.org/scripts/script.php?script_id=1265
            and http://stud4.tuwien.ac.at/~e0125672/icomplete/
@@ -223,21 +219,15 @@ CONSIDERED FOR VERSION 7.0:
        Ivan Villanueva has something for Java.
        Emads: http://www.xref-tech.com/xrefactory/more_c_completion.html
        Ideas from the Vim 7 BOF at SANE:
-       - It's not possible to have one solution for all languages.  Design an
-         interface for completion plugins.  The matches can be done in a
-         Vim-script list.
        - For interpreted languages, use the interpreter to obtain information.
          Should work for Java (Eclipse does this), Python, Tcl, etc.
          Richard Emberson mentioned working on an interface to Java.
        - Check Readline for its completion interface.
        - Use ctags for other languages.  Writing a file could trigger running
          ctags, merging the tags of the changed file.
-       "Visual Assist" http://www.wholetomato.com/products:
        Completion in .NET framework SharpDevelop: http://www.icsharpcode.net
 
         - Pre-expand abbreviations, show which abbrevs would match?
-    - Provide a function to popup the menu, so that an insert mode mapping can
-      start it (with a specific selection).
 
 -   UNDO TREE: keep all states of the text, don't delete undo info.
     When making a change, instead of clearing any future undo (thus redo)
@@ -259,24 +249,6 @@ CONSIDERED FOR VERSION 7.0:
     before some time/date can be flushed. 'undopersist' gives maximum time to
     keep undo: "3h", "1d", "2w", "1y", etc.  For the file use dot and
     extension: ".filename.un~" (like swapfile but "un~" instead of "swp").
-7   Support WINDOW TABS.  Works like several pages, each with their own
-    split windows.
-    In Emacs these are called frames.  Could also call them "pages".
-    Use the name of the first buffer in the tab (ignoring the help window,
-    unless it's the only one).  Add a number for the window count.
-    First make it work on the console.  Use a line of text with highlighting.
-    Then add GUI Tabs for some systems.
-    Patch for GTK 1.2 passed on by Christian Michon, 2004 Jan 6.
-    Simple patch for GTK by Luis M (nov 7).
-    Don't forget to provide an "X" to close the current tab.
-    Implementation: keep the list of windows as-is.  When switching to another
-    tab make the buffers in the current windows hidden, save the window
-    layout, buildup the other window layout and fill with buffers.
-    Need to be able to search the windows in inactive tabs, e.g. for the
-    quickfix window.
-    Use "1gt" - "99gt" to switch to a tab?
-    Also hidden tabs? Useful for messing with a temp buffer without changing
-    the window layout.
 -   EMBEDDING: Make it possible to run Vim inside a window of another program.
     For Xwindows this can be done with XReparentWindow().
     For GTK Neil Bird has a patch to use Vim like a widget.
@@ -431,7 +403,7 @@ Awaiting updated patches:
     7   Completion of network shares, patch by Yasuhiro Matsumoto.
        Update 2004 Sep 6.
        How does this work?  Missing comments.
-       gettext()       Translate a message.  (Patch from Yasuhiro Matsumoto)
+    -  gettext()       Translate a message.  (Patch from Yasuhiro Matsumoto)
                        Update 2004 Sep 10
                        Another patch from Edward L. Fox (2005 Nov 24)
                        Search in 'runtimepath'?
@@ -2085,6 +2057,9 @@ Shared libraries:
 
 
 Tags:
+7   Can CTRL-] (jump to tag) include a following "." and "->" to restrict the
+    number of possible matches? Check tags file for an item that has members.
+    (Flemming Madsen)
 7   Count before CTRL-]: jump to N'th match
 8   Scope arguments for ":tag", e.g.: ":tag class:cPage open", like Elvis.
 8   When output of ":tselect" is long, getting the more-prompt, should be able
@@ -3288,6 +3263,13 @@ Debug mode:
 
 
 Various improvements:
+7   Add plugins for formatting?  Should be able to make a choice depending on
+    the language of a file (English/Korean/Japanese/etc.).
+    Setting the 'langformat' option to "chinese" would load the
+    "format/chinese.vim" plugin.
+    The plugin would set 'formatexpr' and define the function being called.
+    Edward L. Fox explains how it should be done for most Asian languages.
+    (2005 Nov 24)
 7   [t to move to previous xml/html tag (like "vatov"), ]t to move to next
     ("vatv").
 7   [< to move to previous xml/html tag, e.g., previous <li>. ]< to move to
@@ -3419,9 +3401,6 @@ Various improvements:
     paragraph. Both start a new paragraph on any indent change.
 7   Add a way to define an item list with a pattern in 'formatoptions'.  The
     'n' flag doesn't work for "6.3" or "6a.".
-8   Add 'formatexpr' option: Used for formatting operator "gq" instead of the
-    builtin formatting or 'formatprg'.  Or use a string that starts with "="
-    in 'formatprg': "=MyFormat()".
 8   Allow using a trailing space to signal a paragraph that continues on the
     next line (MIME text/plain; format=flowed, RFC 2646).  Can be used for
     continuous formatting.  Could use 'autoformat' option, which specifies a
index 2b73315603b867505ea22928256b426fe734aa33..62b6a917f96c09cd6a1699843540d26922388d08 100644 (file)
@@ -654,7 +654,9 @@ Working with text in the current buffer:
        nextnonblank()          find next non-blank line
        prevnonblank()          find previous non-blank line
        search()                find a match for a pattern
+       searchpos()             find a match for a pattern
        searchpair()            find the other end of a start/skip/end
+       searchpairpos()         find the other end of a start/skip/end
 
 System functions and manipulation of files:
        browse()                put up a file requester
index 14e378a52cbd798aa4ea5f87f8bb970a429ffad3..bbd3d04d09083d498141cce059ebe3870c07a36c 100644 (file)
@@ -1,4 +1,4 @@
-*version7.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 10
+*version7.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -414,6 +414,8 @@ Options: ~
                        (based on an idea from Yegappan Lakshmanan)
 'formatlistpat'                pattern to recognize a numbered list for formatting.
                        (idea by Hugo Haas)
+'formatexpr'           expression for formatting text with |gq| and when text
+                       goes over 'textwidth' in Insert mode.
 'spell'                        switch spell checking on/off
 'spelllang'            languages to check spelling for
 'spellsuggest'         methods for spell suggestions
@@ -558,6 +560,8 @@ New and extended functions: ~
 |repeat()|             repeat "expr" "count" times (Christophe Poucet)
 |reverse()|            reverse the order of a List
 |searchdecl()|         search for declaration of variable
+|searchpairpos()|      return a List with the position of the match
+|searchpos()|          return a List with the position of the match
 |setloclist()|         modify a location list (Yegappan Lakshmanan)
 |setqflist()|          modify a quickfix list (Yegappan Lakshmanan)
 |sort()|               sort a List
@@ -1004,6 +1008,7 @@ itself.
 ":saveas asdf.c" will set 'filetype' to c when it's empty.  Also for ":w
 asdf.c" when it sets the filename for the buffer.
 
+Insert mode completion for whole lines now also searches unloaded buffers.
 
 ==============================================================================
 COMPILE TIME CHANGES                                   *compile-changes-7*
@@ -1686,4 +1691,9 @@ Crashed when expanding a file name argument in backticks.
 In some situations the menu and scrollbar didn't work, when the value contains
 a CSI byte. (Yukihiro Nakadaira)
 
+GTK GUI: When drawing the balloon focus changes and we might get a key release
+event that removed the balloon again.  Ignore the key release event.
+
+'titleold' was included in ":mkexrc" and ":mksession" files.
+
  vim:tw=78:ts=8:ft=help:norl:
index e510f3c8f394aed5c744f0d1f0c8cb7385f6006e..82f0f834b0493680cac1a2214a1ddb5663efb301 100644 (file)
@@ -1,8 +1,8 @@
 " VHDL indent ('93 syntax)
 " Language:    VHDL
 " Maintainer:  Gerald Lai <laigera+vim?gmail.com>
-" Version:     1.3
-" Last Change: 2006 Jan 31
+" Version:     1.34
+" Last Change: 2006 Feb 11
 " URL:         http://www.vim.org/scripts/script.php?script_id=1450
 
 " only load this indent file when no other was loaded
@@ -17,13 +17,35 @@ setlocal indentkeys=!^F,o,O,e,0(,0)
 setlocal indentkeys+==~if,=~then,=~elsif,=~else
 setlocal indentkeys+==~begin,=~is,=~select,=~--
 
-" move around
+" count repeat
+function! <SID>CountWrapper(cmd)
+  let i = v:count1
+  if a:cmd[0] == ":"
+    while i > 0
+      execute a:cmd
+      let i = i - 1
+    endwhile
+  else
+    execute "normal! gv\<Esc>"
+    execute "normal ".i.a:cmd
+    let curcol = col(".")
+    let curline = line(".")
+    normal! gv
+    call cursor(curline, curcol)
+  endif
+endfunction
+
+" explore motion
 " keywords: "architecture", "block", "configuration", "component", "entity", "function", "package", "procedure", "process", "record", "units"
 let b:vhdl_explore = '\%(architecture\|block\|configuration\|component\|entity\|function\|package\|procedure\|process\|record\|units\)'
-nnoremap <silent><buffer>[[ :cal search('\%(\<end\s\+\)\@<!\<'.b:vhdl_explore.'\>\c','bW')<CR>
-nnoremap <silent><buffer>]] :cal search('\%(\<end\s\+\)\@<!\<'.b:vhdl_explore.'\>\c','W')<CR>
-nnoremap <silent><buffer>[] :cal search('\<end\s\+'.b:vhdl_explore.'\>\c','bW')<CR>
-nnoremap <silent><buffer>][ :cal search('\<end\s\+'.b:vhdl_explore.'\>\c','W')<CR>
+noremap  <buffer><silent>[[ :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\%(\\<end\\s\\+\\)\\@<!\\<".b:vhdl_explore."\\>\\c\\<Bar>\\%^","bW")')<CR>
+noremap  <buffer><silent>]] :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\%(\\<end\\s\\+\\)\\@<!\\<".b:vhdl_explore."\\>\\c\\<Bar>\\%$","W")')<CR>
+noremap  <buffer><silent>[] :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\<end\\s\\+".b:vhdl_explore."\\>\\c\\<Bar>\\%^","bW")')<CR>
+noremap  <buffer><silent>][ :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\<end\\s\\+".b:vhdl_explore."\\>\\c\\<Bar>\\%$","W")')<CR>
+vnoremap <buffer><silent>[[ :<C-u>cal <SID>CountWrapper('[[')<CR>
+vnoremap <buffer><silent>]] :<C-u>cal <SID>CountWrapper(']]')<CR>
+vnoremap <buffer><silent>[] :<C-u>cal <SID>CountWrapper('[]')<CR>
+vnoremap <buffer><silent>][ :<C-u>cal <SID>CountWrapper('][')<CR>
 
 " constants
 " not a comment
index 6d654b26a9c07ef345691f364d4ac7cb4f95f8ea..eb8799c5876c980f55dbf48619dc3e937f54b14e 100644 (file)
@@ -1700,6 +1700,9 @@ free_buf_options(buf, free_p_ff)
     clear_string_option(&buf->b_p_inde);
     clear_string_option(&buf->b_p_indk);
 #endif
+#if defined(FEAT_EVAL)
+    clear_string_option(&buf->b_p_fex);
+#endif
 #ifdef FEAT_CRYPT
     clear_string_option(&buf->b_p_key);
 #endif
@@ -2840,9 +2843,12 @@ buf_same_ino(buf, stp)
 }
 #endif
 
+/*
+ * Print info about the current buffer.
+ */
     void
 fileinfo(fullname, shorthelp, dont_truncate)
-    int fullname;
+    int fullname;          /* when non-zero print full path */
     int shorthelp;
     int        dont_truncate;
 {
@@ -3476,7 +3482,7 @@ build_stl_str_hl(wp, out, outlen, fmt, fillchar, maxwidth, hl)
            else
            {
                t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname
-                                       : wp->w_buffer->b_fname;
+                                         : wp->w_buffer->b_fname;
                home_replace(wp->w_buffer, t, NameBuff, MAXPATHL, TRUE);
            }
            trans_characters(NameBuff, MAXPATHL);
index 18a1cf15e478d1afda3cbf2dea3d66b2cf829e47..9224c58970293e668c6e3e6a037f788993ddc71e 100644 (file)
@@ -130,6 +130,7 @@ static void ins_compl_del_pum __ARGS((void));
 static int  pum_wanted __ARGS((void));
 static int  pum_two_or_more __ARGS((void));
 static void ins_compl_dictionaries __ARGS((char_u *dict, char_u *pat, int flags, int thesaurus));
+static char_u *find_line_end __ARGS((char_u *ptr));
 static void ins_compl_free __ARGS((void));
 static void ins_compl_clear __ARGS((void));
 static int  ins_compl_bs __ARGS((void));
@@ -157,6 +158,7 @@ static void ins_redraw __ARGS((int ready));
 static void ins_ctrl_v __ARGS((void));
 static void undisplay_dollar __ARGS((void));
 static void insert_special __ARGS((int, int, int));
+static void internal_format __ARGS((int textwidth, int second_indent, int flags, int format_only));
 static void check_auto_format __ARGS((int));
 static void redo_literal __ARGS((int c));
 static void start_arrow __ARGS((pos_T *end_insert_pos));
@@ -2184,13 +2186,13 @@ ins_compl_longest_match(match)
            if (has_mbyte)
            {
                l = mb_ptr2len(p);
-               if (STRNCMP(p, s, l) != 0)
+               if (STRNICMP(p, s, l) != 0)
                        break;
            }
            else
 #endif
            {
-               if (*p != *s)
+               if (MB_TOLOWER(*p) != MB_TOLOWER(*s))
                    break;
                l = 1;
            }
@@ -2471,7 +2473,7 @@ ins_compl_show_pum()
 ins_compl_dictionaries(dict, pat, flags, thesaurus)
     char_u     *dict;
     char_u     *pat;
-    int                flags;
+    int                flags;          /* DICT_FIRST and/or DICT_EXACT */
     int                thesaurus;
 {
     char_u     *ptr;
@@ -2490,7 +2492,23 @@ ins_compl_dictionaries(dict, pat, flags, thesaurus)
     save_p_scs = p_scs;
     if (curbuf->b_p_inf)
        p_scs = FALSE;
-    regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
+
+    /* When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern
+     * to only match at the start of a line.  Otherwise just match the
+     * pattern. */
+    if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+    {
+       i = STRLEN(pat) + 8;
+       ptr = alloc(i);
+       if (ptr == NULL)
+           return;
+       vim_snprintf((char *)ptr, i, "^\\s*\\zs%s", pat);
+       regmatch.regprog = vim_regcomp(ptr, p_magic ? RE_MAGIC : 0);
+       vim_free(ptr);
+    }
+    else
+       regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
+
     /* ignore case depends on 'ignorecase', 'smartcase' and "pat" */
     regmatch.rm_ic = ignorecase(pat);
     while (buf != NULL && regmatch.regprog != NULL && *dict != NUL
@@ -2537,7 +2555,10 @@ ins_compl_dictionaries(dict, pat, flags, thesaurus)
                    while (vim_regexec(&regmatch, buf, (colnr_T)(ptr - buf)))
                    {
                        ptr = regmatch.startp[0];
-                       ptr = find_word_end(ptr);
+                       if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+                           ptr = find_line_end(ptr);
+                       else
+                           ptr = find_word_end(ptr);
                        add_r = ins_compl_add_infercase(regmatch.startp[0],
                                              (int)(ptr - regmatch.startp[0]),
                                                            files[i], dir, 0);
@@ -2652,6 +2673,22 @@ find_word_end(ptr)
     return ptr;
 }
 
+/*
+ * Find the end of the line, omitting CR and NL at the end.
+ * Returns a pointer to just after the line.
+ */
+    static char_u *
+find_line_end(ptr)
+    char_u     *ptr;
+{
+    char_u     *s;
+
+    s = ptr + STRLEN(ptr);
+    while (s > ptr && (s[-1] == CAR || s[-1] == NL))
+       --s;
+    return s;
+}
+
 /*
  * Free the list of completions
  */
@@ -3102,9 +3139,7 @@ ins_compl_next_buf(buf, flag)
                        ? buf->b_p_bl
                        : (!buf->b_p_bl
                            || (buf->b_ml.ml_mfp == NULL) != (flag == 'u')))
-                   || buf->b_scanned
-                   || (buf->b_ml.ml_mfp == NULL
-                       && ctrl_x_mode == CTRL_X_WHOLE_LINE)))
+                   || buf->b_scanned))
            ;
     return buf;
 }
@@ -3176,8 +3211,8 @@ expand_by_function(type, base)
  * Get the next expansion(s), using "compl_pattern".
  * The search starts at position "ini" in curbuf and in the direction
  * compl_direction.
- * When "compl_started" is FALSE start at that position, otherwise
- * continue where we stopped searching before.
+ * When "compl_started" is FALSE start at that position, otherwise continue
+ * where we stopped searching before.
  * This may return before finding all the matches.
  * Return the total number of matches or -1 if still unknown -- Acevedo
  */
@@ -3432,7 +3467,7 @@ ins_compl_get_exp(ini)
                                                                     RE_LAST);
                if (!compl_started)
                {
-                   /* set compl_started even on fail */
+                   /* set "compl_started" even on fail */
                    compl_started = TRUE;
                    first_match_pos = *pos;
                    last_match_pos = *pos;
@@ -4242,8 +4277,7 @@ ins_complete(c)
     /*
      * Find next match (and following matches).
      */
-    n = ins_compl_next(TRUE, ins_compl_key2count(c),
-                                               c != K_UP && c != K_DOWN);
+    n = ins_compl_next(TRUE, ins_compl_key2count(c), c != K_UP && c != K_DOWN);
 
     /* may undisplay the popup menu */
     ins_compl_upd_pum();
@@ -4671,29 +4705,14 @@ insertchar(c, flags, second_indent)
     int                flags;                  /* INSCHAR_FORMAT, etc. */
     int                second_indent;          /* indent for second line if >= 0 */
 {
-    int                haveto_redraw = FALSE;
     int                textwidth;
 #ifdef FEAT_COMMENTS
-    colnr_T    leader_len;
     char_u     *p;
-    int                no_leader = FALSE;
-    int                do_comments = (flags & INSCHAR_DO_COM);
 #endif
-    int                fo_white_par;
-    int                first_line = TRUE;
     int                fo_ins_blank;
-#ifdef FEAT_MBYTE
-    int                fo_multibyte;
-#endif
-    int                save_char = NUL;
-    int                cc;
 
     textwidth = comp_textwidth(flags & INSCHAR_FORMAT);
     fo_ins_blank = has_format_option(FO_INS_BLANK);
-#ifdef FEAT_MBYTE
-    fo_multibyte = has_format_option(FO_MBYTE_BREAK);
-#endif
-    fo_white_par = has_format_option(FO_WHITE_PAR);
 
     /*
      * Try to break the line in two or more pieces when:
@@ -4710,7 +4729,7 @@ insertchar(c, flags, second_indent)
      *     - 'formatoptions' doesn't have 'b' or a blank was inserted at or
      *       before 'textwidth'
      */
-    if (textwidth
+    if (textwidth > 0
            && ((flags & INSCHAR_FORMAT)
                || (!vim_iswhite(c)
                    && !((State & REPLACE_FLAG)
@@ -4725,288 +4744,15 @@ insertchar(c, flags, second_indent)
                                || Insstart_blank_vcol <= (colnr_T)textwidth
                            ))))))
     {
-       /*
-        * When 'ai' is off we don't want a space under the cursor to be
-        * deleted.  Replace it with an 'x' temporarily.
-        */
-       if (!curbuf->b_p_ai)
-       {
-           cc = gchar_cursor();
-           if (vim_iswhite(cc))
-           {
-               save_char = cc;
-               pchar_cursor('x');
-           }
-       }
-
-       /*
-        * Repeat breaking lines, until the current line is not too long.
-        */
-       while (!got_int)
-       {
-           int         startcol;               /* Cursor column at entry */
-           int         wantcol;                /* column at textwidth border */
-           int         foundcol;               /* column for start of spaces */
-           int         end_foundcol = 0;       /* column for start of word */
-           colnr_T     len;
-           colnr_T     virtcol;
-#ifdef FEAT_VREPLACE
-           int         orig_col = 0;
-           char_u      *saved_text = NULL;
-#endif
-           colnr_T     col;
-
-           virtcol = get_nolist_virtcol();
-           if (virtcol < (colnr_T)textwidth)
-               break;
-
-#ifdef FEAT_COMMENTS
-           if (no_leader)
-               do_comments = FALSE;
-           else if (!(flags & INSCHAR_FORMAT)
-                                          && has_format_option(FO_WRAP_COMS))
-               do_comments = TRUE;
-
-           /* Don't break until after the comment leader */
-           if (do_comments)
-               leader_len = get_leader_len(ml_get_curline(), NULL, FALSE);
-           else
-               leader_len = 0;
-
-           /* If the line doesn't start with a comment leader, then don't
-            * start one in a following broken line.  Avoids that a %word
-            * moved to the start of the next line causes all following lines
-            * to start with %. */
-           if (leader_len == 0)
-               no_leader = TRUE;
-#endif
-           if (!(flags & INSCHAR_FORMAT)
-#ifdef FEAT_COMMENTS
-                   && leader_len == 0
-#endif
-                   && !has_format_option(FO_WRAP))
-
-           {
-               textwidth = 0;
-               break;
-           }
-           if ((startcol = curwin->w_cursor.col) == 0)
-               break;
-
-           /* find column of textwidth border */
-           coladvance((colnr_T)textwidth);
-           wantcol = curwin->w_cursor.col;
-
-           curwin->w_cursor.col = startcol - 1;
-#ifdef FEAT_MBYTE
-           /* Correct cursor for multi-byte character. */
-           if (has_mbyte)
-               mb_adjust_cursor();
-#endif
-           foundcol = 0;
-
-           /*
-            * Find position to break at.
-            * Stop at first entered white when 'formatoptions' has 'v'
-            */
-           while ((!fo_ins_blank && !has_format_option(FO_INS_VI))
-                       || curwin->w_cursor.lnum != Insstart.lnum
-                       || curwin->w_cursor.col >= Insstart.col)
-           {
-               cc = gchar_cursor();
-               if (WHITECHAR(cc))
-               {
-                   /* remember position of blank just before text */
-                   end_foundcol = curwin->w_cursor.col;
-
-                   /* find start of sequence of blanks */
-                   while (curwin->w_cursor.col > 0 && WHITECHAR(cc))
-                   {
-                       dec_cursor();
-                       cc = gchar_cursor();
-                   }
-                   if (curwin->w_cursor.col == 0 && WHITECHAR(cc))
-                       break;          /* only spaces in front of text */
-#ifdef FEAT_COMMENTS
-                   /* Don't break until after the comment leader */
-                   if (curwin->w_cursor.col < leader_len)
-                       break;
-#endif
-                   if (has_format_option(FO_ONE_LETTER))
-                   {
-                       /* do not break after one-letter words */
-                       if (curwin->w_cursor.col == 0)
-                           break;      /* one-letter word at begin */
-
-                       col = curwin->w_cursor.col;
-                       dec_cursor();
-                       cc = gchar_cursor();
-
-                       if (WHITECHAR(cc))
-                           continue;   /* one-letter, continue */
-                       curwin->w_cursor.col = col;
-                   }
-#ifdef FEAT_MBYTE
-                   if (has_mbyte)
-                       foundcol = curwin->w_cursor.col
-                                            + (*mb_ptr2len)(ml_get_cursor());
-                   else
-#endif
-                       foundcol = curwin->w_cursor.col + 1;
-                   if (curwin->w_cursor.col < (colnr_T)wantcol)
-                       break;
-               }
-#ifdef FEAT_MBYTE
-               else if (cc >= 0x100 && fo_multibyte
-                                 && curwin->w_cursor.col <= (colnr_T)wantcol)
-               {
-                   /* Break after or before a multi-byte character. */
-                   foundcol = curwin->w_cursor.col;
-                   if (curwin->w_cursor.col < (colnr_T)wantcol)
-                       foundcol += (*mb_char2len)(cc);
-                   end_foundcol = foundcol;
-                   break;
-               }
-#endif
-               if (curwin->w_cursor.col == 0)
-                   break;
-               dec_cursor();
-           }
-
-           if (foundcol == 0)          /* no spaces, cannot break line */
-           {
-               curwin->w_cursor.col = startcol;
-               break;
-           }
-
-           /* Going to break the line, remove any "$" now. */
-           undisplay_dollar();
-
-           /*
-            * Offset between cursor position and line break is used by replace
-            * stack functions.  VREPLACE does not use this, and backspaces
-            * over the text instead.
-            */
-#ifdef FEAT_VREPLACE
-           if (State & VREPLACE_FLAG)
-               orig_col = startcol;    /* Will start backspacing from here */
-           else
-#endif
-               replace_offset = startcol - end_foundcol - 1;
-
-           /*
-            * adjust startcol for spaces that will be deleted and
-            * characters that will remain on top line
-            */
-           curwin->w_cursor.col = foundcol;
-           while (cc = gchar_cursor(), WHITECHAR(cc))
-               inc_cursor();
-           startcol -= curwin->w_cursor.col;
-           if (startcol < 0)
-               startcol = 0;
-
-#ifdef FEAT_VREPLACE
-           if (State & VREPLACE_FLAG)
-           {
-               /*
-                * In VREPLACE mode, we will backspace over the text to be
-                * wrapped, so save a copy now to put on the next line.
-                */
-               saved_text = vim_strsave(ml_get_cursor());
-               curwin->w_cursor.col = orig_col;
-               if (saved_text == NULL)
-                   break;      /* Can't do it, out of memory */
-               saved_text[startcol] = NUL;
-
-               /* Backspace over characters that will move to the next line */
-               if (!fo_white_par)
-                   backspace_until_column(foundcol);
-           }
-           else
+       /* 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) != 0)
 #endif
-           {
-               /* put cursor after pos. to break line */
-               if (!fo_white_par)
-                   curwin->w_cursor.col = foundcol;
-           }
-
-           /*
-            * Split the line just before the margin.
-            * Only insert/delete lines, but don't really redraw the window.
-            */
-           open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX
-                   + (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
-#ifdef FEAT_COMMENTS
-                   + (do_comments ? OPENLINE_DO_COM : 0)
-#endif
-                   , old_indent);
-           old_indent = 0;
-
-           replace_offset = 0;
-           if (first_line)
-           {
-               if (second_indent < 0 && has_format_option(FO_Q_NUMBER))
-                   second_indent = get_number_indent(curwin->w_cursor.lnum -1);
-               if (second_indent >= 0)
-               {
-#ifdef FEAT_VREPLACE
-                   if (State & VREPLACE_FLAG)
-                       change_indent(INDENT_SET, second_indent, FALSE, NUL);
-                   else
-#endif
-                       (void)set_indent(second_indent, SIN_CHANGED);
-               }
-               first_line = FALSE;
-           }
-
-#ifdef FEAT_VREPLACE
-           if (State & VREPLACE_FLAG)
-           {
-               /*
-                * In VREPLACE mode we have backspaced over the text to be
-                * moved, now we re-insert it into the new line.
-                */
-               ins_bytes(saved_text);
-               vim_free(saved_text);
-           }
-           else
-#endif
-           {
-               /*
-                * Check if cursor is not past the NUL off the line, cindent
-                * may have added or removed indent.
-                */
-               curwin->w_cursor.col += startcol;
-               len = (colnr_T)STRLEN(ml_get_curline());
-               if (curwin->w_cursor.col > len)
-                   curwin->w_cursor.col = len;
-           }
-
-           haveto_redraw = TRUE;
-#ifdef FEAT_CINDENT
-           can_cindent = TRUE;
-#endif
-           /* moved the cursor, don't autoindent or cindent now */
-           did_ai = FALSE;
-#ifdef FEAT_SMARTINDENT
-           did_si = FALSE;
-           can_si = FALSE;
-           can_si_back = FALSE;
-#endif
-           line_breakcheck();
-       }
-
-       if (save_char)                  /* put back space after cursor */
-           pchar_cursor(save_char);
-
-       if (c == NUL)                   /* formatting only */
-           return;
-       if (haveto_redraw)
-       {
-           update_topline();
-           redraw_curbuf_later(VALID);
-       }
+           internal_format(textwidth, second_indent, flags, c == NUL);
     }
+
     if (c == NUL)          /* only formatting was wanted */
        return;
 
@@ -5104,7 +4850,7 @@ insertchar(c, flags, second_indent)
 
        buf[0] = c;
        i = 1;
-       if (textwidth)
+       if (textwidth > 0)
            virtcol = get_nolist_virtcol();
        /*
         * Stop the string when:
@@ -5157,6 +4903,8 @@ insertchar(c, flags, second_indent)
     else
     {
 #ifdef FEAT_MBYTE
+       int             cc;
+
        if (has_mbyte && (cc = (*mb_char2len)(c)) > 1)
        {
            char_u      buf[MB_MAXBYTES + 1];
@@ -5178,6 +4926,312 @@ insertchar(c, flags, second_indent)
     }
 }
 
+/*
+ * Format text at the current insert position.
+ */
+    static void
+internal_format(textwidth, second_indent, flags, format_only)
+    int                textwidth;
+    int                second_indent;
+    int                flags;
+    int                format_only;
+{
+    int                cc;
+    int                save_char = NUL;
+    int                haveto_redraw = FALSE;
+    int                fo_ins_blank = has_format_option(FO_INS_BLANK);
+#ifdef FEAT_MBYTE
+    int                fo_multibyte = has_format_option(FO_MBYTE_BREAK);
+#endif
+    int                fo_white_par = has_format_option(FO_WHITE_PAR);
+    int                first_line = TRUE;
+#ifdef FEAT_COMMENTS
+    colnr_T    leader_len;
+    int                no_leader = FALSE;
+    int                do_comments = (flags & INSCHAR_DO_COM);
+#endif
+
+    /*
+     * When 'ai' is off we don't want a space under the cursor to be
+     * deleted.  Replace it with an 'x' temporarily.
+     */
+    if (!curbuf->b_p_ai)
+    {
+       cc = gchar_cursor();
+       if (vim_iswhite(cc))
+       {
+           save_char = cc;
+           pchar_cursor('x');
+       }
+    }
+
+    /*
+     * Repeat breaking lines, until the current line is not too long.
+     */
+    while (!got_int)
+    {
+       int     startcol;               /* Cursor column at entry */
+       int     wantcol;                /* column at textwidth border */
+       int     foundcol;               /* column for start of spaces */
+       int     end_foundcol = 0;       /* column for start of word */
+       colnr_T len;
+       colnr_T virtcol;
+#ifdef FEAT_VREPLACE
+       int     orig_col = 0;
+       char_u  *saved_text = NULL;
+#endif
+       colnr_T col;
+
+       virtcol = get_nolist_virtcol();
+       if (virtcol < (colnr_T)textwidth)
+           break;
+
+#ifdef FEAT_COMMENTS
+       if (no_leader)
+           do_comments = FALSE;
+       else if (!(flags & INSCHAR_FORMAT)
+                                      && has_format_option(FO_WRAP_COMS))
+           do_comments = TRUE;
+
+       /* Don't break until after the comment leader */
+       if (do_comments)
+           leader_len = get_leader_len(ml_get_curline(), NULL, FALSE);
+       else
+           leader_len = 0;
+
+       /* If the line doesn't start with a comment leader, then don't
+        * start one in a following broken line.  Avoids that a %word
+        * moved to the start of the next line causes all following lines
+        * to start with %. */
+       if (leader_len == 0)
+           no_leader = TRUE;
+#endif
+       if (!(flags & INSCHAR_FORMAT)
+#ifdef FEAT_COMMENTS
+               && leader_len == 0
+#endif
+               && !has_format_option(FO_WRAP))
+
+       {
+           textwidth = 0;
+           break;
+       }
+       if ((startcol = curwin->w_cursor.col) == 0)
+           break;
+
+       /* find column of textwidth border */
+       coladvance((colnr_T)textwidth);
+       wantcol = curwin->w_cursor.col;
+
+       curwin->w_cursor.col = startcol - 1;
+#ifdef FEAT_MBYTE
+       /* Correct cursor for multi-byte character. */
+       if (has_mbyte)
+           mb_adjust_cursor();
+#endif
+       foundcol = 0;
+
+       /*
+        * Find position to break at.
+        * Stop at first entered white when 'formatoptions' has 'v'
+        */
+       while ((!fo_ins_blank && !has_format_option(FO_INS_VI))
+                   || curwin->w_cursor.lnum != Insstart.lnum
+                   || curwin->w_cursor.col >= Insstart.col)
+       {
+           cc = gchar_cursor();
+           if (WHITECHAR(cc))
+           {
+               /* remember position of blank just before text */
+               end_foundcol = curwin->w_cursor.col;
+
+               /* find start of sequence of blanks */
+               while (curwin->w_cursor.col > 0 && WHITECHAR(cc))
+               {
+                   dec_cursor();
+                   cc = gchar_cursor();
+               }
+               if (curwin->w_cursor.col == 0 && WHITECHAR(cc))
+                   break;              /* only spaces in front of text */
+#ifdef FEAT_COMMENTS
+               /* Don't break until after the comment leader */
+               if (curwin->w_cursor.col < leader_len)
+                   break;
+#endif
+               if (has_format_option(FO_ONE_LETTER))
+               {
+                   /* do not break after one-letter words */
+                   if (curwin->w_cursor.col == 0)
+                       break;  /* one-letter word at begin */
+
+                   col = curwin->w_cursor.col;
+                   dec_cursor();
+                   cc = gchar_cursor();
+
+                   if (WHITECHAR(cc))
+                       continue;       /* one-letter, continue */
+                   curwin->w_cursor.col = col;
+               }
+#ifdef FEAT_MBYTE
+               if (has_mbyte)
+                   foundcol = curwin->w_cursor.col
+                                        + (*mb_ptr2len)(ml_get_cursor());
+               else
+#endif
+                   foundcol = curwin->w_cursor.col + 1;
+               if (curwin->w_cursor.col < (colnr_T)wantcol)
+                   break;
+           }
+#ifdef FEAT_MBYTE
+           else if (cc >= 0x100 && fo_multibyte
+                             && curwin->w_cursor.col <= (colnr_T)wantcol)
+           {
+               /* Break after or before a multi-byte character. */
+               foundcol = curwin->w_cursor.col;
+               if (curwin->w_cursor.col < (colnr_T)wantcol)
+                   foundcol += (*mb_char2len)(cc);
+               end_foundcol = foundcol;
+               break;
+           }
+#endif
+           if (curwin->w_cursor.col == 0)
+               break;
+           dec_cursor();
+       }
+
+       if (foundcol == 0)              /* no spaces, cannot break line */
+       {
+           curwin->w_cursor.col = startcol;
+           break;
+       }
+
+       /* Going to break the line, remove any "$" now. */
+       undisplay_dollar();
+
+       /*
+        * Offset between cursor position and line break is used by replace
+        * stack functions.  VREPLACE does not use this, and backspaces
+        * over the text instead.
+        */
+#ifdef FEAT_VREPLACE
+       if (State & VREPLACE_FLAG)
+           orig_col = startcol;        /* Will start backspacing from here */
+       else
+#endif
+           replace_offset = startcol - end_foundcol - 1;
+
+       /*
+        * adjust startcol for spaces that will be deleted and
+        * characters that will remain on top line
+        */
+       curwin->w_cursor.col = foundcol;
+       while (cc = gchar_cursor(), WHITECHAR(cc))
+           inc_cursor();
+       startcol -= curwin->w_cursor.col;
+       if (startcol < 0)
+           startcol = 0;
+
+#ifdef FEAT_VREPLACE
+       if (State & VREPLACE_FLAG)
+       {
+           /*
+            * In VREPLACE mode, we will backspace over the text to be
+            * wrapped, so save a copy now to put on the next line.
+            */
+           saved_text = vim_strsave(ml_get_cursor());
+           curwin->w_cursor.col = orig_col;
+           if (saved_text == NULL)
+               break;  /* Can't do it, out of memory */
+           saved_text[startcol] = NUL;
+
+           /* Backspace over characters that will move to the next line */
+           if (!fo_white_par)
+               backspace_until_column(foundcol);
+       }
+       else
+#endif
+       {
+           /* put cursor after pos. to break line */
+           if (!fo_white_par)
+               curwin->w_cursor.col = foundcol;
+       }
+
+       /*
+        * Split the line just before the margin.
+        * Only insert/delete lines, but don't really redraw the window.
+        */
+       open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX
+               + (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
+#ifdef FEAT_COMMENTS
+               + (do_comments ? OPENLINE_DO_COM : 0)
+#endif
+               , old_indent);
+       old_indent = 0;
+
+       replace_offset = 0;
+       if (first_line)
+       {
+           if (second_indent < 0 && has_format_option(FO_Q_NUMBER))
+               second_indent = get_number_indent(curwin->w_cursor.lnum -1);
+           if (second_indent >= 0)
+           {
+#ifdef FEAT_VREPLACE
+               if (State & VREPLACE_FLAG)
+                   change_indent(INDENT_SET, second_indent, FALSE, NUL);
+               else
+#endif
+                   (void)set_indent(second_indent, SIN_CHANGED);
+           }
+           first_line = FALSE;
+       }
+
+#ifdef FEAT_VREPLACE
+       if (State & VREPLACE_FLAG)
+       {
+           /*
+            * In VREPLACE mode we have backspaced over the text to be
+            * moved, now we re-insert it into the new line.
+            */
+           ins_bytes(saved_text);
+           vim_free(saved_text);
+       }
+       else
+#endif
+       {
+           /*
+            * Check if cursor is not past the NUL off the line, cindent
+            * may have added or removed indent.
+            */
+           curwin->w_cursor.col += startcol;
+           len = (colnr_T)STRLEN(ml_get_curline());
+           if (curwin->w_cursor.col > len)
+               curwin->w_cursor.col = len;
+       }
+
+       haveto_redraw = TRUE;
+#ifdef FEAT_CINDENT
+       can_cindent = TRUE;
+#endif
+       /* moved the cursor, don't autoindent or cindent now */
+       did_ai = FALSE;
+#ifdef FEAT_SMARTINDENT
+       did_si = FALSE;
+       can_si = FALSE;
+       can_si_back = FALSE;
+#endif
+       line_breakcheck();
+    }
+
+    if (save_char != NUL)              /* put back space after cursor */
+       pchar_cursor(save_char);
+
+    if (!format_only && haveto_redraw)
+    {
+       update_topline();
+       redraw_curbuf_later(VALID);
+    }
+}
+
 /*
  * Called after inserting or deleting text: When 'formatoptions' includes the
  * 'a' flag format from the current line until the end of the paragraph.
@@ -7254,7 +7308,10 @@ ins_insert(replaceState)
 # ifdef FEAT_EVAL
     set_vim_var_string(VV_INSERTMODE,
                   (char_u *)((State & REPLACE_FLAG) ? "i" :
-                           replaceState == VREPLACE ? "v" : "r"), 1);
+#  ifdef FEAT_VREPLACE
+                           replaceState == VREPLACE ? "v" :
+#  endif
+                           "r"), 1);
 # endif
     apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, FALSE, curbuf);
 #endif
index 50f688a76121a9a11b0d40ea0e12e2daa52658be..6ec0975d73352190083178861763b019a7c72a99 100644 (file)
@@ -573,6 +573,7 @@ static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_range __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv));
@@ -588,6 +589,8 @@ static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_search __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv));
@@ -704,6 +707,8 @@ static void func_ref __ARGS((char_u *name));
 static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict));
 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr));
 static win_T *find_win_by_nr __ARGS((typval_T *vp));
+static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos));
+static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos));
 
 /* Character used as separated in autoload function/variable names. */
 #define AUTOLOAD_CHAR '#'
@@ -6930,6 +6935,7 @@ static struct fst
     {"nr2char",                1, 1, f_nr2char},
     {"prevnonblank",   1, 1, f_prevnonblank},
     {"printf",         2, 19, f_printf},
+    {"pumvisible",     0, 0, f_pumvisible},
     {"range",          1, 3, f_range},
     {"readfile",       1, 3, f_readfile},
     {"remote_expr",    2, 3, f_remote_expr},
@@ -6945,6 +6951,8 @@ static struct fst
     {"search",         1, 2, f_search},
     {"searchdecl",     1, 3, f_searchdecl},
     {"searchpair",     3, 5, f_searchpair},
+    {"searchpairpos",  3, 5, f_searchpairpos},
+    {"searchpos",      1, 2, f_searchpos},
     {"server2client",  2, 2, f_server2client},
     {"serverlist",     0, 0, f_serverlist},
     {"setbufvar",      3, 3, f_setbufvar},
@@ -12213,6 +12221,22 @@ f_printf(argvars, rettv)
 #endif
 }
 
+/*
+ * "pumvisible()" function
+ */
+/*ARGSUSED*/
+    static void
+f_pumvisible(argvars, rettv)
+    typval_T   *argvars;
+    typval_T   *rettv;
+{
+    rettv->vval.v_number = 0;
+#ifdef FEAT_INS_EXPAND
+    if (pum_visible())
+       rettv->vval.v_number = 1;
+#endif
+}
+
 /*
  * "range()" function
  */
@@ -13135,12 +13159,12 @@ get_search_arg(varp, flagsp)
 }
 
 /*
- * "search()" function
+ * Shared by search() and searchpos() functions
  */
-    static void
-f_search(argvars, rettv)
+    static int
+search_cmn(argvars, match_pos)
     typval_T   *argvars;
-    typval_T   *rettv;
+    pos_T      *match_pos;
 {
     char_u     *pat;
     pos_T      pos;
@@ -13148,8 +13172,7 @@ f_search(argvars, rettv)
     int                save_p_ws = p_ws;
     int                dir;
     int                flags = 0;
-
-    rettv->vval.v_number = 0;  /* default: FAIL */
+    int                retval = 0;     /* default: FAIL */
 
     pat = get_tv_string(&argvars[0]);
     dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */
@@ -13172,10 +13195,16 @@ f_search(argvars, rettv)
     if (searchit(curwin, curbuf, &pos, dir, pat, 1L,
                                              SEARCH_KEEP, RE_SEARCH) != FAIL)
     {
-       rettv->vval.v_number = pos.lnum;
+       retval = pos.lnum;
        if (flags & SP_SETPCMARK)
            setpcmark();
        curwin->w_cursor = pos;
+       if (match_pos != NULL)
+       {
+           /* Store the match cursor position */
+           match_pos->lnum = pos.lnum;
+           match_pos->col = pos.col + 1;
+       }
        /* "/$" will put the cursor after the end of the line, may need to
         * correct that here */
        check_cursor();
@@ -13186,6 +13215,19 @@ f_search(argvars, rettv)
        curwin->w_cursor = save_cursor;
 theend:
     p_ws = save_p_ws;
+
+    return retval;
+}
+
+/*
+ * "search()" function
+ */
+    static void
+f_search(argvars, rettv)
+    typval_T   *argvars;
+    typval_T   *rettv;
+{
+    rettv->vval.v_number = search_cmn(argvars, NULL);
 }
 
 /*
@@ -13216,12 +13258,12 @@ f_searchdecl(argvars, rettv)
 }
 
 /*
- * "searchpair()" function
+ * Used by searchpair() and searchpairpos()
  */
-    static void
-f_searchpair(argvars, rettv)
+    static int
+searchpair_cmn(argvars, match_pos)
     typval_T   *argvars;
-    typval_T   *rettv;
+    pos_T      *match_pos;
 {
     char_u     *spat, *mpat, *epat;
     char_u     *skip;
@@ -13231,8 +13273,7 @@ f_searchpair(argvars, rettv)
     char_u     nbuf1[NUMBUFLEN];
     char_u     nbuf2[NUMBUFLEN];
     char_u     nbuf3[NUMBUFLEN];
-
-    rettv->vval.v_number = 0;  /* default: FAIL */
+    int                retval = 0;             /* default: FAIL */
 
     /* Get the three pattern arguments: start, middle, end. */
     spat = get_tv_string_chk(&argvars[0]);
@@ -13254,7 +13295,7 @@ f_searchpair(argvars, rettv)
        goto theend;
     }
 
-    /* Optional fifth argument: skip expresion */
+    /* Optional fifth argument: skip expression */
     if (argvars[3].v_type == VAR_UNKNOWN
            || argvars[4].v_type == VAR_UNKNOWN)
        skip = (char_u *)"";
@@ -13263,10 +13304,55 @@ f_searchpair(argvars, rettv)
     if (skip == NULL)
        goto theend;        /* type error */
 
-    rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags);
+    retval = do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos);
 
 theend:
     p_ws = save_p_ws;
+
+    return retval;
+}
+
+/*
+ * "searchpair()" function
+ */
+    static void
+f_searchpair(argvars, rettv)
+    typval_T   *argvars;
+    typval_T   *rettv;
+{
+    rettv->vval.v_number = searchpair_cmn(argvars, NULL);
+}
+
+/*
+ * "searchpairpos()" function
+ */
+    static void
+f_searchpairpos(argvars, rettv)
+    typval_T   *argvars;
+    typval_T   *rettv;
+{
+    list_T     *l;
+    pos_T      match_pos;
+    int                lnum = 0;
+    int                col = 0;
+
+    rettv->vval.v_number = 0;
+
+    l = list_alloc();
+    if (l == NULL)
+       return;
+    rettv->v_type = VAR_LIST;
+    rettv->vval.v_list = l;
+    ++l->lv_refcount;
+
+    if (searchpair_cmn(argvars, &match_pos) > 0)
+    {
+       lnum = match_pos.lnum;
+       col = match_pos.col;
+    }
+
+    list_append_number(l, (varnumber_T)lnum);
+    list_append_number(l, (varnumber_T)col);
 }
 
 /*
@@ -13275,13 +13361,14 @@ theend:
  * Returns 0 or -1 for no match,
  */
     long
-do_searchpair(spat, mpat, epat, dir, skip, flags)
+do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos)
     char_u     *spat;      /* start pattern */
     char_u     *mpat;      /* middle pattern */
     char_u     *epat;      /* end pattern */
     int                dir;        /* BACKWARD or FORWARD */
     char_u     *skip;      /* skip expression */
     int                flags;      /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */
+    pos_T      *match_pos;
 {
     char_u     *save_cpo;
     char_u     *pat, *pat2 = NULL, *pat3 = NULL;
@@ -13389,6 +13476,13 @@ do_searchpair(spat, mpat, epat, dir, skip, flags)
        }
     }
 
+    if (match_pos != NULL)
+    {
+       /* Store the match cursor position */
+       match_pos->lnum = curwin->w_cursor.lnum;
+       match_pos->col = curwin->w_cursor.col + 1;
+    }
+
     /* If 'n' flag is used or search failed: restore cursor position. */
     if ((flags & SP_NOMOVE) || retval == 0)
        curwin->w_cursor = save_cursor;
@@ -13401,6 +13495,40 @@ theend:
     return retval;
 }
 
+/*
+ * "searchpos()" function
+ */
+    static void
+f_searchpos(argvars, rettv)
+    typval_T   *argvars;
+    typval_T   *rettv;
+{
+    list_T     *l;
+    pos_T      match_pos;
+    int                lnum = 0;
+    int                col = 0;
+
+    rettv->vval.v_number = 0;
+
+    l = list_alloc();
+    if (l == NULL)
+       return;
+    rettv->v_type = VAR_LIST;
+    rettv->vval.v_list = l;
+    ++l->lv_refcount;
+
+    if (search_cmn(argvars, &match_pos) > 0)
+    {
+       lnum = match_pos.lnum;
+       col = match_pos.col;
+    }
+
+    list_append_number(l, (varnumber_T)lnum);
+    list_append_number(l, (varnumber_T)col);
+
+}
+
+
 /*ARGSUSED*/
     static void
 f_server2client(argvars, rettv)
@@ -14027,11 +14155,9 @@ f_spellbadword(argvars, rettv)
     typval_T   *rettv;
 {
     char_u     *word = (char_u *)"";
-#ifdef FEAT_SYN_HL
-    int                len = 0;
     hlf_T      attr = HLF_COUNT;
+    int                len = 0;
     list_T     *l;
-#endif
 
     l = list_alloc();
     if (l == NULL)
index ca3bed0c333bd8f5d7ca3ee8b739265f22595d65..6571ccef30a3dc7333034ac8355c29e25aaa202c 100644 (file)
@@ -877,6 +877,16 @@ EX(CMD_tag,                "tag",          ex_tag,
                        RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
 EX(CMD_tags,           "tags",         do_tags,
                        TRLBAR|CMDWIN),
+EX(CMD_tab,            "tab",          ex_tab,
+                       RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_tabclose,       "tabclose",     ex_tabclose,
+                       BANG|TRLBAR|CMDWIN),
+EX(CMD_tabedit,                "tabedit",      ex_tabedit,
+                       BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_tabfind,                "tabfind",      ex_tabedit,
+                       BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_tabs,           "tabs",         ex_tabs,
+                       TRLBAR|CMDWIN),
 EX(CMD_tcl,            "tcl",          ex_tcl,
                        RANGE|EXTRA|NEEDARG|CMDWIN),
 EX(CMD_tcldo,          "tcldo",        ex_tcldo,
index 098f42ca897d315d2251a21106ebf1416495a9fc..e87bb6f6f27ee540065ab1071137cbb4efee3503 100644 (file)
@@ -148,11 +148,13 @@ static void       ex_cquit __ARGS((exarg_T *eap));
 static void    ex_quit_all __ARGS((exarg_T *eap));
 #ifdef FEAT_WINDOWS
 static void    ex_close __ARGS((exarg_T *eap));
-static void    ex_win_close __ARGS((exarg_T *eap, win_T *win));
+static void    ex_win_close __ARGS((int forceit, win_T *win));
 static void    ex_only __ARGS((exarg_T *eap));
 static void    ex_all __ARGS((exarg_T *eap));
 static void    ex_resize __ARGS((exarg_T *eap));
 static void    ex_stag __ARGS((exarg_T *eap));
+static void    ex_tabclose __ARGS((exarg_T *eap));
+static void    ex_tabs __ARGS((exarg_T *eap));
 #else
 # define ex_close              ex_ni
 # define ex_only               ex_ni
@@ -160,6 +162,10 @@ static void        ex_stag __ARGS((exarg_T *eap));
 # define ex_resize             ex_ni
 # define ex_splitview          ex_ni
 # define ex_stag               ex_ni
+# define ex_tabedit            ex_ni
+# define ex_tab                        ex_ni
+# define ex_tabs               ex_ni
+# define ex_tabclose           ex_ni
 #endif
 #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
 static void    ex_pclose __ARGS((exarg_T *eap));
@@ -6138,19 +6144,38 @@ ex_close(eap)
     else
 # endif
        if (!text_locked())
-           ex_win_close(eap, curwin);
+           ex_win_close(eap->forceit, curwin);
 }
 
+#ifdef FEAT_QUICKFIX
+/*
+ * ":pclose": Close any preview window.
+ */
     static void
-ex_win_close(eap, win)
+ex_pclose(eap)
     exarg_T    *eap;
+{
+    win_T      *win;
+
+    for (win = firstwin; win != NULL; win = win->w_next)
+       if (win->w_p_pvw)
+       {
+           ex_win_close(eap->forceit, win);
+           break;
+       }
+}
+#endif
+
+    static void
+ex_win_close(forceit, win)
+    int                forceit;
     win_T      *win;
 {
     int                need_hide;
     buf_T      *buf = win->w_buffer;
 
     need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
-    if (need_hide && !P_HID(buf) && !eap->forceit)
+    if (need_hide && !P_HID(buf) && !forceit)
     {
 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
        if ((p_confirm || cmdmod.confirm) && p_write)
@@ -6175,24 +6200,33 @@ ex_win_close(eap, win)
     win_close(win, !need_hide && !P_HID(buf));
 }
 
-#ifdef FEAT_QUICKFIX
 /*
- * ":pclose": Close any preview window.
+ * ":tabclose": close current tab page, unless it is the last one
  */
     static void
-ex_pclose(eap)
+ex_tabclose(eap)
     exarg_T    *eap;
 {
-    win_T      *win;
-
-    for (win = firstwin; win != NULL; win = win->w_next)
-       if (win->w_p_pvw)
+# ifdef FEAT_CMDWIN
+    if (cmdwin_type != 0)
+       cmdwin_result = K_IGNORE;
+    else
+# endif
+       if (!text_locked())
        {
-           ex_win_close(eap, win);
-           break;
+           if (first_tabpage->tp_next == NULL)
+               EMSG(_("E999: Cannot close last tab page"));
+           else
+           {
+               /* First close all the windows but the current one.  If that
+                * worked then close the last window in this tab, that will
+                * close it. */
+               ex_only(eap);
+               if (lastwin == firstwin)
+                   ex_win_close(eap->forceit, curwin);
+           }
        }
 }
-#endif
 
 /*
  * ":only".
@@ -6722,41 +6756,41 @@ ex_splitview(eap)
     exarg_T    *eap;
 {
     win_T      *old_curwin;
-#if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
+# if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
     char_u     *fname = NULL;
-#endif
-#ifdef FEAT_BROWSE
+# endif
+# ifdef FEAT_BROWSE
     int                browse_flag = cmdmod.browse;
-#endif
+# endif
 
-#ifndef FEAT_VERTSPLIT
+# ifndef FEAT_VERTSPLIT
     if (eap->cmdidx == CMD_vsplit || eap->cmdidx == CMD_vnew)
     {
        ex_ni(eap);
        return;
     }
-#endif
+# endif
 
     old_curwin = curwin;
-#ifdef FEAT_GUI
+# ifdef FEAT_GUI
     need_mouse_correct = TRUE;
-#endif
+# endif
 
-#ifdef FEAT_QUICKFIX
+# ifdef FEAT_QUICKFIX
     /* A ":split" in the quickfix window works like ":new".  Don't want two
      * quickfix windows. */
     if (bt_quickfix(curbuf))
     {
        if (eap->cmdidx == CMD_split)
            eap->cmdidx = CMD_new;
-# ifdef FEAT_VERTSPLIT
+#  ifdef FEAT_VERTSPLIT
        if (eap->cmdidx == CMD_vsplit)
            eap->cmdidx = CMD_vnew;
-# endif
+#  endif
     }
-#endif
+# endif
 
-#ifdef FEAT_SEARCHPATH
+# ifdef FEAT_SEARCHPATH
     if (eap->cmdidx == CMD_sfind)
     {
        fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg),
@@ -6765,15 +6799,15 @@ ex_splitview(eap)
            goto theend;
        eap->arg = fname;
     }
-# ifdef FEAT_BROWSE
+#  ifdef FEAT_BROWSE
     else
+#  endif
 # endif
-#endif
-#ifdef FEAT_BROWSE
+# ifdef FEAT_BROWSE
     if (cmdmod.browse
-# ifdef FEAT_VERTSPLIT
+#  ifdef FEAT_VERTSPLIT
            && eap->cmdidx != CMD_vnew
-#endif
+# endif
            && eap->cmdidx != CMD_new)
     {
        if (
@@ -6797,36 +6831,165 @@ ex_splitview(eap)
        }
     }
     cmdmod.browse = FALSE;     /* Don't browse again in do_ecmd(). */
-#endif
+# endif
 
     if (win_split(eap->addr_count > 0 ? (int)eap->line2 : 0,
                                     *eap->cmd == 'v' ? WSP_VERT : 0) != FAIL)
     {
-#ifdef FEAT_SCROLLBIND
+# ifdef FEAT_SCROLLBIND
        /* Reset 'scrollbind' when editing another file, but keep it when
         * doing ":split" without arguments. */
        if (*eap->arg != NUL
-#ifdef FEAT_BROWSE
+#  ifdef FEAT_BROWSE
                || cmdmod.browse
-#endif
+#  endif
           )
            curwin->w_p_scb = FALSE;
        else
            do_check_scrollbind(FALSE);
-#endif
+# endif
        do_exedit(eap, old_curwin);
     }
 
-#ifdef FEAT_BROWSE
+# ifdef FEAT_BROWSE
     cmdmod.browse = browse_flag;
-#endif
+# endif
 
-#if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
+# if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
 theend:
     vim_free(fname);
-#endif
+# endif
 }
-#endif
+
+/*
+ * :tabedit [[+command] file]  open new Tab page with empty window
+ * :tabedit [[+command] file]  open new Tab page and edit "file"
+ * :tabfind [[+command] file]  open new Tab page and find "file"
+ */
+    void
+ex_tabedit(eap)
+    exarg_T    *eap;
+{
+# if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
+    char_u     *fname = NULL;
+# endif
+# ifdef FEAT_BROWSE
+    int                browse_flag = cmdmod.browse;
+# endif
+
+# ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+# endif
+
+# ifdef FEAT_SEARCHPATH
+    if (eap->cmdidx == CMD_tabfind)
+    {
+       fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg),
+                                         FNAME_MESS, TRUE, curbuf->b_ffname);
+       if (fname == NULL)
+           goto theend;
+       eap->arg = fname;
+    }
+#  ifdef FEAT_BROWSE
+    else
+#  endif
+# endif
+# ifdef FEAT_BROWSE
+    if (cmdmod.browse)
+    {
+       if (
+#  ifdef FEAT_GUI
+           !gui.in_use &&
+#  endif
+               au_has_group((char_u *)"FileExplorer"))
+       {
+           /* No browsing supported but we do have the file explorer:
+            * Edit the directory. */
+           if (*eap->arg == NUL || !mch_isdir(eap->arg))
+               eap->arg = (char_u *)".";
+       }
+       else
+       {
+           fname = do_browse(0, (char_u *)_("Edit File in new tab page"),
+                                         eap->arg, NULL, NULL, NULL, curbuf);
+           if (fname == NULL)
+               goto theend;
+           eap->arg = fname;
+       }
+    }
+    cmdmod.browse = FALSE;     /* Don't browse again in do_ecmd(). */
+# endif
+
+    if (win_new_tabpage() != FAIL)
+    {
+# ifdef FEAT_SCROLLBIND
+       curwin->w_p_scb = FALSE;
+# endif
+       do_exedit(eap, NULL);
+    }
+
+# ifdef FEAT_BROWSE
+    cmdmod.browse = browse_flag;
+# endif
+
+# if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
+theend:
+    vim_free(fname);
+# endif
+}
+
+/*
+ * :tab command
+ */
+    void
+ex_tab(eap)
+    exarg_T    *eap;
+{
+    goto_tabpage((int)eap->line2);
+}
+
+/*
+ * :tabs command: List tabs and their contents.
+ */
+/*ARGSUSED*/
+    static void
+ex_tabs(eap)
+    exarg_T    *eap;
+{
+    tabpage_T  *tp;
+    win_T      *wp;
+    int                tabcount = 1;
+
+    msg_start();
+    msg_scroll = TRUE;
+    for (tp = first_tabpage; tp != NULL && !got_int; tp = tp->tp_next)
+    {
+       msg_putchar('\n');
+       vim_snprintf((char *)IObuff, IOSIZE, _("Tab page %d"), tabcount++);
+       msg_outtrans_attr(IObuff, hl_attr(HLF_T));
+       out_flush();        /* output one line at a time */
+       ui_breakcheck();
+
+       if (tp->tp_topframe == topframe)
+           wp = firstwin;
+       else
+           wp = tp->tp_firstwin;
+       for ( ; wp != NULL && !got_int; wp = wp->w_next)
+       {
+           msg_puts((char_u *)"\n    ");
+           if (buf_spname(wp->w_buffer) != NULL)
+               STRCPY(IObuff, buf_spname(wp->w_buffer));
+           else
+               home_replace(wp->w_buffer, wp->w_buffer->b_fname,
+                                                       IObuff, IOSIZE, TRUE);
+           msg_outtrans(IObuff);
+           out_flush();            /* output one line at a time */
+           ui_breakcheck();
+       }
+    }
+}
+
+#endif /* FEAT_WINDOWS */
 
 /*
  * ":mode": Set screen mode.
index 85aeeb95b54fa2645f6655b25b5b15fb5151bd40..57d7d092287f309fbfe078a9f3aa5a5755b53320 100644 (file)
@@ -488,6 +488,7 @@ EXTERN win_T        *prevwin INIT(= NULL);  /* previous window */
 # define W_NEXT(wp) NULL
 # define FOR_ALL_WINDOWS(wp) wp = curwin;
 #endif
+
 EXTERN win_T   *curwin;        /* currently active window */
 
 /*
@@ -496,6 +497,15 @@ EXTERN win_T       *curwin;        /* currently active window */
  */
 EXTERN frame_T *topframe;      /* top of the window frame tree */
 
+#ifdef FEAT_WINDOWS
+/*
+ * Tab pages are nothing more than alternative topframes.  "first_tabpage"
+ * points to the first one in the list, "topframe" is the current one.
+ */
+EXTERN tabpage_T *first_tabpage;
+EXTERN int       redraw_tabpage INIT(= FALSE); /* redraw tab pages line */
+#endif
+
 /*
  * All buffers are linked in a list. 'firstbuf' points to the first entry,
  * 'lastbuf' to the last entry and 'curbuf' to the currently active buffer.
index 2f5275c106341f805ac198c8cb2b99b0a6e41e6e..c706302d4bcebfa18eb7515eb0715f2f6fb9a5a9 100644 (file)
--- a/src/gui.h
+++ b/src/gui.h
 typedef struct GuiScrollbar
 {
     long       ident;          /* Unique identifier for each scrollbar */
-    struct window *wp;         /* Scrollbar's window, NULL for bottom */
+    win_T      *wp;            /* Scrollbar's window, NULL for bottom */
     int                type;           /* one of SBAR_{LEFT,RIGHT,BOTTOM} */
     long       value;          /* Represents top line number visible */
 #ifdef FEAT_GUI_ATHENA
index bb26497fc6c16e85a35fc73359b834254062938f..6c628cda62d41fd75c95f65cd16df83040d59e89 100644 (file)
@@ -609,7 +609,10 @@ key_event(BalloonEval *beval, unsigned keyval, int is_keypress)
                                                 ? (int)GDK_CONTROL_MASK : 0);
                break;
            default:
-               cancelBalloon(beval);
+               /* Don't do this for key release, we apparently get these with
+                * focus changes in some GTK version. */
+               if (is_keypress)
+                   cancelBalloon(beval);
                break;
        }
     }
index 940c991fed85f854e3b512a3a03b9a8aa7c5175e..4d5bb32234359721f5845693b4da5ff5add26da7 100644 (file)
@@ -40,7 +40,7 @@ typedef struct
 typedef struct
 {
     Scheme_Type            tag;
-    struct window   *win;
+    win_T          *win;
 } vim_mz_window;
 
 #define INVALID_WINDOW_VALUE ((win_T *)(-1))
index 0b96d16ccea6a206c81cfc694e033aced6140f3f..81e41b692f144c690f63667ef10626a4000a018a 100644 (file)
@@ -297,9 +297,11 @@ main
     TIME_MSG("window checked");
 
     /*
-     * Allocate the first window and buffer. Can't do much without it.
+     * Allocate the first window and buffer.
+     * Can't do anything without it, exit when it fails.
      */
-    win_alloc_first();
+    if (win_alloc_first() == FAIL)
+       mch_exit(0);
 
     init_yank();               /* init yank buffers */
 
@@ -505,12 +507,7 @@ main
     if (usingNetbeans)
        Columns += 2;           /* leave room for glyph gutter */
 #endif
-    firstwin->w_height = Rows - p_ch;
-    topframe->fr_height = Rows - p_ch;
-#ifdef FEAT_VERTSPLIT
-    firstwin->w_width = Columns;
-    topframe->fr_width = Columns;
-#endif
+    win_init_size();
 #ifdef FEAT_DIFF
     /* Set the 'diff' option now, so that it can be checked for in a .vimrc
      * file.  There is no buffer yet though. */
index a2c57fc984ccd47672755a9abf6a551eab1ad4e4..d183e498eca97bd3d51e8cecaa66cda13d71fdc9 100644 (file)
@@ -3355,7 +3355,7 @@ get_off_or_lnum(buf_T *buf, char_u **argp)
 
 
 /*
- * Convert lnum,col to character offset
+ * Convert (lnum,col) to byte offset in the file.
  */
     static long
 pos2off(buf_T *buf, pos_T *pos)
index 09410f03087aaa942f3f931dee8db14e1400cb37..d4001b49404f2d9fd13b868d09ac7975a6711cd4 100644 (file)
@@ -1935,7 +1935,12 @@ do_pending_operator(cap, old_col, gui_yank)
            break;
 
        case OP_FORMAT:
-           if (*p_fp != NUL)
+#if defined(FEAT_EVAL)
+           if (*curbuf->b_p_fex != NUL)
+               op_formatexpr(oap);     /* use expression */
+           else
+#endif
+               if (*p_fp != NUL)
                op_colon(oap);          /* use external command */
            else
                op_format(oap, FALSE);  /* use internal function */
@@ -7832,6 +7837,12 @@ nv_g_cmd(cap)
        break;
 #endif
 
+#ifdef FEAT_WINDOWS
+    case 't':
+       goto_tabpage((int)cap->count0);
+       break;
+#endif
+
     default:
        clearopbeep(oap);
        break;
index 0c1e853de98eba2b26e8f3afa76681b3d33efd7d..a48b6be64c44fc9d13ee259eb420275ce0e6a871 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -4312,6 +4312,49 @@ op_format(oap, keep_cursor)
 #endif
 }
 
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Implementation of the format operator 'gq' for when using 'formatexpr'.
+ */
+    void
+op_formatexpr(oap)
+    oparg_T    *oap;
+{
+# ifdef FEAT_VISUAL
+    if (oap->is_VIsual)
+       /* When there is no change: need to remove the Visual selection */
+       redraw_curbuf_later(INVERTED);
+# endif
+
+    (void)fex_format(oap->start.lnum, oap->line_count);
+}
+
+    int
+fex_format(lnum, count)
+    linenr_T   lnum;
+    long       count;
+{
+    int                use_sandbox = was_set_insecurely((char_u *)"formatexpr");
+    int                r;
+
+    /*
+     * Set v:lnum to the first line number and v:count to the number of lines.
+     */
+    set_vim_var_nr(VV_LNUM, lnum);
+    set_vim_var_nr(VV_COUNT, count);
+
+    /*
+     * Evaluate the function.
+     */
+    if (use_sandbox)
+       ++sandbox;
+    r = eval_to_number(curbuf->b_p_fex);
+    if (use_sandbox)
+       --sandbox;
+    return r;
+}
+#endif
+
 /*
  * Format "line_count" lines, starting at the cursor position.
  * When "line_count" is negative, format until the end of the paragraph.
index 62cd0e789dfc65a3a9073ae1e1733039917f8cad..cca91cc5ddd87b8a75b748349474b8265e43df1c 100644 (file)
@@ -79,6 +79,7 @@ typedef enum
     , PV_FDT
     , PV_FEN
     , PV_FENC
+    , PV_FEX
     , PV_FF
     , PV_FML
     , PV_FMR
@@ -204,6 +205,9 @@ static char_u       *p_inex;
 static char_u  *p_inde;
 static char_u  *p_indk;
 #endif
+#if defined(FEAT_EVAL)
+static char_u  *p_fex;
+#endif
 static int     p_inf;
 static char_u  *p_isk;
 #ifdef FEAT_CRYPT
@@ -974,6 +978,15 @@ static struct vimoption
 # endif
                            },
 #endif
+    {"formatexpr", "fex",   P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
+#if defined(FEAT_EVAL)
+                           (char_u *)&p_fex, PV_FEX,
+                           {(char_u *)"", (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
+#endif
+                           },
     {"formatoptions","fo",  P_STRING|P_ALLOCED|P_VIM|P_FLAGLIST,
                            (char_u *)&p_fo, PV_FO,
                            {(char_u *)DFLT_FO_VI, (char_u *)DFLT_FO_VIM}},
@@ -1129,7 +1142,7 @@ static struct vimoption
                            {(char_u *)FALSE, (char_u *)0L}},
     {"highlight",   "hl",   P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
                            (char_u *)&p_hl, PV_NONE,
-                           {(char_u *)"8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb",
+                           {(char_u *)"8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb,*:TabPage,#:TabPageSel,_:TabPageFill",
                                (char_u *)0L}},
     {"history",            "hi",   P_NUM|P_VIM,
                            (char_u *)&p_hi, PV_NONE,
@@ -2264,7 +2277,7 @@ static struct vimoption
                            (char_u *)NULL, PV_NONE,
 #endif
                            {(char_u *)85L, (char_u *)0L}},
-    {"titleold",    NULL,   P_STRING|P_VI_DEF|P_GETTEXT|P_SECURE,
+    {"titleold",    NULL,   P_STRING|P_VI_DEF|P_GETTEXT|P_SECURE|P_NO_MKRC,
 #ifdef FEAT_TITLE
                            (char_u *)&p_titleold, PV_NONE,
                            {(char_u *)N_("Thanks for flying Vim"),
@@ -4755,6 +4768,9 @@ check_buf_options(buf)
     check_string_option(&buf->b_p_inde);
     check_string_option(&buf->b_p_indk);
 #endif
+#if defined(FEAT_EVAL)
+    check_string_option(&buf->b_p_fex);
+#endif
 #ifdef FEAT_CRYPT
     check_string_option(&buf->b_p_key);
 #endif
@@ -8583,6 +8599,9 @@ get_varp(p)
        case PV_INDE:   return (char_u *)&(curbuf->b_p_inde);
        case PV_INDK:   return (char_u *)&(curbuf->b_p_indk);
 #endif
+#if defined(FEAT_EVAL)
+       case PV_FEX:    return (char_u *)&(curbuf->b_p_fex);
+#endif
 #ifdef FEAT_CRYPT
        case PV_KEY:    return (char_u *)&(curbuf->b_p_key);
 #endif
@@ -8942,6 +8961,9 @@ buf_copy_options(buf, flags)
            buf->b_p_inde = vim_strsave(p_inde);
            buf->b_p_indk = vim_strsave(p_indk);
 #endif
+#if defined(FEAT_EVAL)
+           buf->b_p_fex = vim_strsave(p_fex);
+#endif
 #ifdef FEAT_CRYPT
            buf->b_p_key = vim_strsave(p_key);
 #endif
index b8ba21514e5cf48fe7b88482173d92998a9e7388..1c2942ce4a54f82892b235547808a03e3b900957 100644 (file)
@@ -54,7 +54,7 @@ char_u *get_dict_string __ARGS((dict_T *d, char_u *key, int save));
 long get_dict_number __ARGS((dict_T *d, char_u *key));
 char_u *get_function_name __ARGS((expand_T *xp, int idx));
 char_u *get_expr_name __ARGS((expand_T *xp, int idx));
-long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags));
+long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos));
 void set_vim_var_nr __ARGS((int idx, long val));
 long get_vim_var_nr __ARGS((int idx));
 char_u *get_vim_var_str __ARGS((int idx));
index 25601e1713e88e79d3113c757d79c33efe54c2a6..a6998cf50478a1ce0a28028e686e23d42ac95c0f 100644 (file)
@@ -33,6 +33,8 @@ void alist_set __ARGS((alist_T *al, int count, char_u **files, int use_curbuf, i
 void alist_add __ARGS((alist_T *al, char_u *fname, int set_fnum));
 void alist_slash_adjust __ARGS((void));
 void ex_splitview __ARGS((exarg_T *eap));
+void ex_tabedit __ARGS((exarg_T *eap));
+void ex_tab __ARGS((exarg_T *eap));
 void do_exedit __ARGS((exarg_T *eap, win_T *old_curwin));
 void free_cd_dir __ARGS((void));
 void do_sleep __ARGS((long msec));
index da9973bbe37f55caee4f9c144dec8539de67cca9..3b4c9c42369a2e935ade21685d0d3254f9146fac 100644 (file)
@@ -38,6 +38,8 @@ void ex_display __ARGS((exarg_T *eap));
 void do_do_join __ARGS((long count, int insert_space));
 int do_join __ARGS((int insert_space));
 void op_format __ARGS((oparg_T *oap, int keep_cursor));
+void op_formatexpr __ARGS((oparg_T *oap));
+int fex_format __ARGS((linenr_T lnum, long count));
 void format_lines __ARGS((linenr_T line_count));
 int paragraph_start __ARGS((linenr_T lnum));
 int do_addsub __ARGS((int command, linenr_T Prenum1));
index fd3d62f3774ac2f4cfae2438273d5a5832c63089..a1808bc692bd5012018b2084aa69183fd413f941 100644 (file)
@@ -7,11 +7,15 @@ int make_windows __ARGS((int count, int vertical));
 void win_move_after __ARGS((win_T *win1, win_T *win2));
 void win_equal __ARGS((win_T *next_curwin, int current, int dir));
 void close_windows __ARGS((buf_T *buf));
+int last_window __ARGS((void));
 void win_close __ARGS((win_T *win, int free_buf));
 void win_free_all __ARGS((void));
 void close_others __ARGS((int message, int forceit));
 void win_init __ARGS((win_T *wp));
-void win_alloc_first __ARGS((void));
+int win_alloc_first __ARGS((void));
+void win_init_size __ARGS((void));
+int win_new_tabpage __ARGS((void));
+void goto_tabpage __ARGS((int n));
 void win_goto __ARGS((win_T *wp));
 win_T *win_find_nr __ARGS((int winnr));
 void win_enter __ARGS((win_T *wp, int undo_sync));
@@ -32,6 +36,7 @@ void win_drag_vsep_line __ARGS((win_T *dragwin, int offset));
 void win_comp_scroll __ARGS((win_T *wp));
 void command_height __ARGS((long old_p_ch));
 void last_status __ARGS((int morewin));
+int tabpageline_height __ARGS((void));
 char_u *grab_file_name __ARGS((long count));
 char_u *file_name_at_cursor __ARGS((int options, long count));
 char_u *file_name_in_line __ARGS((char_u *line, int col, int options, long count, char_u *rel_fname));
index e2f10db82f52f85eda34e11d67f40459ea7242b4..ba5475b0d0220f70f55d563d134d8c3dcb1e13a8 100644 (file)
@@ -167,6 +167,9 @@ static void redraw_block __ARGS((int row, int end, win_T *wp));
 static int win_do_lines __ARGS((win_T *wp, int row, int line_count, int mayclear, int del));
 static void win_rest_invalid __ARGS((win_T *wp));
 static void msg_pos_mode __ARGS((void));
+#if defined(FEAT_WINDOWS)
+static void draw_tabpage __ARGS((void));
+#endif
 #if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT)
 static int fillchar_status __ARGS((int *attr, int is_curwin));
 #endif
@@ -390,6 +393,9 @@ update_screen(type)
                }
            }
            redraw_cmdline = TRUE;
+#ifdef FEAT_WINDOWS
+           redraw_tabpage = TRUE;
+#endif
        }
        msg_scrolled = 0;
        need_wait_return = FALSE;
@@ -468,6 +474,12 @@ update_screen(type)
     }
 #endif
 
+#ifdef FEAT_WINDOWS
+    /* Redraw the tab pages line if needed. */
+    if (redraw_tabpage || type >= NOT_VALID)
+       draw_tabpage();
+#endif
+
     /*
      * Go from top to bottom through the windows, redrawing the ones that need
      * it.
@@ -4947,6 +4959,8 @@ redraw_statuslines()
     for (wp = firstwin; wp; wp = wp->w_next)
        if (wp->w_redr_status)
            win_redr_status(wp);
+    if (redraw_tabpage)
+       draw_tabpage();
 }
 #endif
 
@@ -8409,6 +8423,79 @@ unshowmode(force)
     }
 }
 
+#if defined(FEAT_WINDOWS)
+/*
+ * Draw the tab pages line at the top of the Vim window.
+ */
+    static void
+draw_tabpage()
+{
+    int                tabcount = 0;
+    tabpage_T  *tp;
+    int                tabwidth;
+    int                col = 0;
+    int                had_current = FALSE;
+    int                attr;
+    win_T      *wp;
+    int                c;
+    int                len;
+    int                attr_sel = hl_attr(HLF_TPS);
+    int                attr_nosel = hl_attr(HLF_TP);
+    int                attr_fill = hl_attr(HLF_TPF);
+
+    redraw_tabpage = FALSE;
+
+    if (tabpageline_height() < 1)
+       return;
+
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+       ++tabcount;
+
+    tabwidth = Columns / tabcount;
+    if (tabwidth < 6)
+       tabwidth = 6;
+
+    attr = attr_nosel;
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    {
+       if (tp->tp_topframe == topframe)
+       {
+           c = '/';
+           had_current = TRUE;
+           attr = attr_sel;
+       }
+       else if (!had_current)
+           c = '/';
+       else
+           c = '\\';
+       screen_putchar(c, 0, col++, attr);
+
+       if (tp->tp_topframe != topframe)
+           attr = attr_nosel;
+
+       if (tp->tp_topframe == topframe)
+           wp = curwin;
+       else
+           wp = tp->tp_curwin;
+       if (buf_spname(wp->w_buffer) != NULL)
+           STRCPY(NameBuff, buf_spname(wp->w_buffer));
+       else
+           home_replace(wp->w_buffer, wp->w_buffer->b_fname, NameBuff,
+                                                             MAXPATHL, TRUE);
+       trans_characters(NameBuff, MAXPATHL);
+       len = STRLEN(NameBuff);
+       if (len > tabwidth) /* TODO: multi-byte chars */
+           len = tabwidth;
+       screen_puts_len(NameBuff, len, 0, col, attr);
+       col += len;
+    }
+
+    screen_putchar('\\', 0, col++, attr);
+    while (col < Columns)
+       screen_putchar('_', 0, col++, attr_fill);
+}
+#endif
+
 #if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT)
 /*
  * Get the character to use in a status line.  Get its attributes in "*attr".
index bcb23aa7e986c29f98fa2353cbf038c9acad696d..5531fb6c0874e2a160e0abe84c62e14ec4f504de 100644 (file)
@@ -3733,7 +3733,7 @@ again:
     {
        if (do_searchpair((char_u *)"<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)",
                    (char_u *)"",
-                   (char_u *)"</[^>]*>", BACKWARD, (char_u *)"", 0) <= 0)
+                   (char_u *)"</[^>]*>", BACKWARD, (char_u *)"", 0, NULL) <= 0)
        {
            curwin->w_cursor = old_pos;
            goto theend;
@@ -3766,7 +3766,7 @@ again:
     sprintf((char *)spat, "<%.*s\\%%(\\_[^>]\\{-}[^/]>\\|>\\)\\c", len, p);
     sprintf((char *)epat, "</%.*s>\\c", len, p);
 
-    r = do_searchpair(spat, (char_u *)"", epat, FORWARD, (char_u *)"", 0);
+    r = do_searchpair(spat, (char_u *)"", epat, FORWARD, (char_u *)"", 0, NULL);
 
     vim_free(spat);
     vim_free(epat);
index 462ee521c7177584625bf69531e3bdd777ab792a..a743a4f465f33852c94e0e04ce875efba11f88f7 100644 (file)
@@ -68,10 +68,10 @@ typedef struct growarray
  */
 #include "regexp.h"
 
-typedef struct window  win_T;
-typedef struct wininfo wininfo_T;
-typedef struct frame   frame_T;
-typedef int            scid_T;         /* script ID */
+typedef struct window_S                win_T;
+typedef struct wininfo_S       wininfo_T;
+typedef struct frame_S         frame_T;
+typedef int                    scid_T;         /* script ID */
 
 /*
  * This is here because gui.h needs the pos_T and win_T, and win_T needs gui.h
@@ -215,7 +215,7 @@ typedef struct
  * The window-info is kept in a list at b_wininfo.  It is kept in
  * most-recently-used order.
  */
-struct wininfo
+struct wininfo_S
 {
     wininfo_T  *wi_next;       /* next entry or NULL for last entry */
     wininfo_T  *wi_prev;       /* previous entry or NULL for first entry */
@@ -1330,6 +1330,9 @@ struct file_buffer
     char_u     *b_p_inde;      /* 'indentexpr' */
     char_u     *b_p_indk;      /* 'indentkeys' */
 #endif
+#if defined(FEAT_EVAL)
+    char_u     *b_p_fex;       /* 'formatexpr' */
+#endif
 #ifdef FEAT_CRYPT
     char_u     *b_p_key;       /* 'key' */
 #endif
@@ -1546,11 +1549,24 @@ typedef struct w_line
 #endif
 } wline_T;
 
+/*
+ * Tab pages point to the top frame of each tab page.
+ */
+typedef struct tabpage_S tabpage_T;
+struct tabpage_S
+{
+    tabpage_T      *tp_next;   /* next tabpage or NULL */
+    frame_T        *tp_topframe;
+    win_T          *tp_curwin; /* current window in this Tab page */
+    win_T          *tp_firstwin; /* first window in this Tab page */
+    win_T          *tp_lastwin;  /* last window in this Tab page */
+};
+
 /*
  * Windows are kept in a tree of frames.  Each frame has a column (FR_COL)
  * or row (FR_ROW) layout or is a leaf, which has a window.
  */
-struct frame
+struct frame_S
 {
     char       fr_layout;      /* FR_LEAF, FR_COL or FR_ROW */
 #ifdef FEAT_VERTSPLIT
@@ -1577,7 +1593,7 @@ struct frame
  *
  * All row numbers are relative to the start of the window, except w_winrow.
  */
-struct window
+struct window_S
 {
     buf_T      *w_buffer;          /* buffer we are a window into (used
                                       often, keep it the first item!) */
index ab9bcced83d3b5643c4c3470143e95d2ab7df3b2..0db3a6e74ecfd39f1ed01e6255031341dcaa5c6a 100644 (file)
@@ -6079,6 +6079,9 @@ static char *(highlight_init_both[]) =
        "DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red",
        "PmenuThumb cterm=reverse gui=reverse",
        "PmenuSbar ctermbg=Grey guibg=Grey",
+       "TabPage term=underline cterm=underline ctermbg=grey gui=underline guibg=grey",
+       "TabPageSel term=reverse,bold cterm=reverse,bold gui=reverse,bold",
+       "TabPageFill term=underline cterm=underline ctermbg=grey gui=underline guibg=grey",
        NULL
     };
 
index e5f2c9a6d95387b502542c1a459f8ccde7c13f1d..37b84c74fd433d308ed99472a2504415adc93434 100644 (file)
@@ -2980,6 +2980,10 @@ get_bytes_from_buf(buf, bytes, num_bytes)
            ++len;      /* skip KE_FILLER */
            /* else it should be KS_SPECIAL, and c already equals K_SPECIAL */
        }
+       else if (c == CSI && buf[len] == KS_EXTRA && buf[len + 1] == (int)KE_CSI)
+           /* CSI is stored as CSI KS_SPECIAL KE_CSI to avoid confusion with
+            * the start of a special key, see add_to_input_buf_csi(). */
+           len += 2;
        bytes[i] = c;
     }
     return len;
index b638c0da5262b231e6bbe49205ac98a930c3d78a..d1013efb44041f6f61d37861ff48ab59431f8068 100644 (file)
--- a/src/ui.c
+++ b/src/ui.c
@@ -2897,6 +2897,7 @@ mouse_find_win(rowp, colp)
     frame_T    *fp;
 
     fp = topframe;
+    *rowp -= firstwin->w_winrow;
     for (;;)
     {
        if (fp->fr_layout == FR_LEAF)
index 8324c33494602269c021fe049c9b88aa00abbad3..6ff870f9fae506db4f511baebd2d025176b0813f 100644 (file)
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT      "vim70aa"
 #define VIM_VERSION_SHORT      "7.0aa"
 #define VIM_VERSION_MEDIUM     "7.0aa ALPHA"
-#define VIM_VERSION_LONG       "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 10)"
-#define VIM_VERSION_LONG_DATE  "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 10, compiled "
+#define VIM_VERSION_LONG       "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 14)"
+#define VIM_VERSION_LONG_DATE  "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 14, compiled "
index 07acb562af255a6efcd19f9f0036a605222a28ce..9af95140455496eab6a7237d7c2ba60df715ccd1 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -1157,6 +1157,9 @@ typedef enum
     , HLF_PSI      /* popup menu selected item */
     , HLF_PSB      /* popup menu scrollbar */
     , HLF_PST      /* popup menu scrollbar thumb */
+    , HLF_TP       /* tabpage line */
+    , HLF_TPS      /* tabpage line selected */
+    , HLF_TPF      /* tabpage line filler */
     , HLF_COUNT            /* MUST be the last one */
 } hlf_T;
 
@@ -1165,7 +1168,7 @@ typedef enum
                  'n', 'r', 's', 'S', 'c', 't', 'v', 'V', 'w', 'W', \
                  'f', 'F', 'A', 'C', 'D', 'T', '>', \
                  'B', 'P', 'R', 'L', \
-                 '+', '=', 'x', 'X'}
+                 '+', '=', 'x', 'X', '*', '#', '_'}
 
 /*
  * Boolean constants
index 6bb9c4674254349e81ebc4b3f615b2eacbcabc4f..4dc98854f17d8a81ec28bed378692343a7523bd0 100644 (file)
@@ -29,6 +29,7 @@ static void win_equal_rec __ARGS((win_T *next_curwin, int current, frame_T *topf
 static win_T *win_free_mem __ARGS((win_T *win, int *dirp));
 static win_T *winframe_remove __ARGS((win_T *win, int *dirp));
 static frame_T *win_altframe __ARGS((win_T *win));
+static tabpage_T *alt_tabpage __ARGS((void));
 static win_T *frame2win __ARGS((frame_T *frp));
 static int frame_has_win __ARGS((frame_T *frp, win_T *wp));
 static void frame_new_height __ARGS((frame_T *topfrp, int height, int topfirst, int wfh));
@@ -40,6 +41,12 @@ static void frame_add_vsep __ARGS((frame_T *frp));
 static int frame_minwidth __ARGS((frame_T *topfrp, win_T *next_curwin));
 static void frame_fix_width __ARGS((win_T *wp));
 #endif
+#endif
+static int win_alloc_firstwin __ARGS((void));
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+static tabpage_T *current_tabpage __ARGS((void));
+static void leave_tabpage __ARGS((tabpage_T *tp));
+static void enter_tabpage __ARGS((tabpage_T *tp, buf_T *old_curbuf));
 static void frame_fix_height __ARGS((win_T *wp));
 static int frame_minheight __ARGS((frame_T *topfrp, win_T *next_curwin));
 static void win_enter_ext __ARGS((win_T *wp, int undo_sync, int no_curwin));
@@ -77,6 +84,9 @@ static void win_new_height __ARGS((win_T *, int));
 #ifdef FEAT_WINDOWS
 static long p_ch_used = 1L;            /* value of 'cmdheight' when frame
                                           size was set */
+# define ROWS_AVAIL (Rows - p_ch - tabpageline_height())
+#else
+# define ROWS_AVAIL (Rows - p_ch)
 #endif
 
 #if defined(FEAT_WINDOWS) || defined(PROTO)
@@ -932,7 +942,7 @@ win_split_ins(size, flags, newwin, dir)
        if (flags & (WSP_TOP | WSP_BOT))
        {
            /* set height and row of new window to full height */
-           wp->w_winrow = 0;
+           wp->w_winrow = tabpageline_height();
            wp->w_height = curfrp->fr_height - (p_ls > 0);
            wp->w_status_height = (p_ls > 0);
        }
@@ -1507,7 +1517,8 @@ win_equal(next_curwin, current, dir)
        dir = 'b';
 #endif
     win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
-                     topframe, dir, 0, 0, (int)Columns, topframe->fr_height);
+                     topframe, dir, 0, tabpageline_height(),
+                                          (int)Columns, topframe->fr_height);
 }
 
 /*
@@ -1806,6 +1817,16 @@ close_windows(buf)
     --RedrawingDisabled;
 }
 
+/*
+ * Return TRUE if the current window is the only window that exists.
+ * Returns FALSE if there is a window in another tab page.
+ */
+    int
+last_window()
+{
+    return (lastwin == firstwin && first_tabpage->tp_next == NULL);
+}
+
 /*
  * close window "win"
  * If "free_buf" is TRUE related buffer may be unloaded.
@@ -1818,6 +1839,7 @@ win_close(win, free_buf)
     int                free_buf;
 {
     win_T      *wp;
+    buf_T      *old_curbuf = curbuf;
 #ifdef FEAT_AUTOCMD
     int                other_buffer = FALSE;
 #endif
@@ -1825,7 +1847,7 @@ win_close(win, free_buf)
     int                dir;
     int                help_window = FALSE;
 
-    if (lastwin == firstwin)
+    if (last_window())
     {
        EMSG(_("E444: Cannot close last window"));
        return;
@@ -1854,11 +1876,11 @@ win_close(win, free_buf)
        {
            other_buffer = TRUE;
            apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
-           if (!win_valid(win) || firstwin == lastwin)
+           if (!win_valid(win) || last_window())
                return;
        }
        apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
-       if (!win_valid(win) || firstwin == lastwin)
+       if (!win_valid(win) || last_window())
            return;
 # ifdef FEAT_EVAL
        /* autocmds may abort script processing */
@@ -1874,16 +1896,42 @@ win_close(win, free_buf)
     close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
     /* Autocommands may have closed the window already, or closed the only
      * other window. */
-    if (!win_valid(win) || firstwin == lastwin)
+    if (!win_valid(win) || last_window())
        return;
 
     /* Free the memory used for the window. */
     wp = win_free_mem(win, &dir);
 
+    /* When closing the last window in a tab page go to another tab page. */
+    if (wp == NULL)
+    {
+       tabpage_T   *ptp = NULL;
+       tabpage_T   *tp;
+       tabpage_T   *atp = alt_tabpage();
+
+       for (tp = first_tabpage; tp->tp_topframe != topframe; tp = tp->tp_next)
+           ptp = tp;
+       if (tp == NULL)
+       {
+           EMSG2(_(e_intern2), "win_close()");
+           return;
+       }
+       if (ptp == NULL)
+           first_tabpage = tp->tp_next;
+       else
+           ptp->tp_next = tp->tp_next;
+       vim_free(tp);
+
+       /* We don't do the window resizing stuff, let enter_tabpage() take
+        * care of entering a window in another tab page. */
+       enter_tabpage(atp, old_curbuf);
+       return;
+    }
+
     /* Make sure curwin isn't invalid.  It can cause severe trouble when
      * printing an error message.  For win_equal() curbuf needs to be valid
      * too. */
-    if (win == curwin)
+    else if (win == curwin)
     {
        curwin = wp;
 #ifdef FEAT_QUICKFIX
@@ -1937,8 +1985,8 @@ win_close(win, free_buf)
     }
 
     /*
-     * if last window has a status line now and we don't want one,
-     * remove the status line
+     * If last window has a status line now and we don't want one,
+     * remove the status line.
      */
     last_status(FALSE);
 
@@ -1975,9 +2023,13 @@ win_free_mem(win, dirp)
     /* reduce the reference count to the argument list. */
     alist_unlink(win->w_alist);
 
-    /* remove the window and its frame from the tree of frames. */
+    /* Remove the window and its frame from the tree of frames. */
     frp = win->w_frame;
-    wp = winframe_remove(win, dirp);
+    if (firstwin == lastwin)
+       /* Last window in a tab page. */
+       wp = NULL;
+    else
+       wp = winframe_remove(win, dirp);
     vim_free(frp);
     win_free(win);
 
@@ -2115,6 +2167,10 @@ win_altframe(win)
     frame_T    *frp;
     int                b;
 
+    if (firstwin == lastwin)
+       /* Last window in this tab page, will go to next tab page. */
+       return alt_tabpage()->tp_curwin->w_frame;
+
     frp = win->w_frame;
 #ifdef FEAT_VERTSPLIT
     if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW)
@@ -2127,6 +2183,28 @@ win_altframe(win)
     return frp->fr_prev;
 }
 
+/*
+ * Return the tabpage that will be used if the current one is closed.
+ */
+    static tabpage_T *
+alt_tabpage()
+{
+    tabpage_T  *tp = current_tabpage();
+
+    if (tp != NULL)
+    {
+       /* Use the next tab page if it exists. */
+       if (tp->tp_next != NULL)
+           return tp->tp_next;
+
+       /* Find the previous tab page. */
+       for (tp = first_tabpage; tp->tp_next != NULL; tp = tp->tp_next)
+           if (tp->tp_next == current_tabpage())
+               return tp;
+    }
+    return first_tabpage;
+}
+
 /*
  * Find the left-upper window in frame "frp".
  */
@@ -2640,11 +2718,7 @@ close_others(message, forceit)
        }
     }
 
-    /*
-     * If current window has a status line and we don't want one,
-     * remove the status line.
-     */
-    if (lastwin != firstwin)
+    if (message && lastwin != firstwin)
        EMSG(_("E445: Other window contains changes"));
 }
 
@@ -2686,15 +2760,36 @@ win_init(wp)
 /*
  * Allocate the first window and put an empty buffer in it.
  * Called from main().
- * When this fails we can't do anything: exit.
+ * Return FAIL when something goes wrong (out of memory).
  */
-    void
+    int
 win_alloc_first()
+{
+    if (win_alloc_firstwin() == FAIL)
+       return FAIL;
+
+#ifdef FEAT_WINDOWS
+    first_tabpage = (tabpage_T *)alloc((unsigned)sizeof(tabpage_T));
+    if (first_tabpage == NULL)
+       return FAIL;
+    first_tabpage->tp_topframe = topframe;
+    first_tabpage->tp_next = NULL;
+#endif
+    return OK;
+}
+
+/*
+ * Allocate one window and put an empty buffer in it.
+ * Called to create the first window in a new tab page.
+ * Return FAIL when something goes wrong (out of memory).
+ */
+    static int
+win_alloc_firstwin()
 {
     curwin = win_alloc(NULL);
     curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED);
     if (curwin == NULL || curbuf == NULL)
-       mch_exit(0);
+       return FAIL;
     curwin->w_buffer = curbuf;
     curbuf->b_nwindows = 1;    /* there is one window */
 #ifdef FEAT_WINDOWS
@@ -2704,7 +2799,7 @@ win_alloc_first()
 
     topframe = (frame_T *)alloc_clear((unsigned)sizeof(frame_T));
     if (topframe == NULL)
-       mch_exit(0);
+       return FAIL;
     topframe->fr_layout = FR_LEAF;
 #ifdef FEAT_VERTSPLIT
     topframe->fr_width = Columns;
@@ -2715,9 +2810,169 @@ win_alloc_first()
 #endif
     topframe->fr_win = curwin;
     curwin->w_frame = topframe;
+
+    return OK;
+}
+
+/*
+ * Initialize the window and frame size to the maximum.
+ */
+    void
+win_init_size()
+{
+    firstwin->w_height = ROWS_AVAIL;
+    topframe->fr_height = ROWS_AVAIL;
+#ifdef FEAT_VERTSPLIT
+    firstwin->w_width = Columns;
+    topframe->fr_width = Columns;
+#endif
 }
 
 #if defined(FEAT_WINDOWS) || defined(PROTO)
+/*
+ * Create a new Tab page with one empty window.
+ * Put it just after the current Tab page.
+ * Return FAIL or OK.
+ */
+    int
+win_new_tabpage()
+{
+    tabpage_T  *tp;
+    tabpage_T  *newtp;
+
+    newtp = (tabpage_T *)alloc((unsigned)sizeof(tabpage_T));
+    if (newtp == NULL)
+       return FAIL;
+
+    tp = current_tabpage();
+
+    /* Remember the current windows in this Tab page. */
+    leave_tabpage(tp);
+
+    /* Create a new empty window. */
+    if (win_alloc_firstwin() == OK)
+    {
+       /* copy options from previous to new curwin */
+       win_copy_options(tp->tp_curwin, curwin);
+
+       /* Make the new Tab page the new topframe. */
+       newtp->tp_next = tp->tp_next;
+       tp->tp_next = newtp;
+       win_init_size();
+       firstwin->w_winrow = tabpageline_height();
+
+       newtp->tp_topframe = topframe;
+       redraw_all_later(CLEAR);
+       return OK;
+    }
+
+    /* Failed, get back the previous Tab page */
+    topframe = tp->tp_topframe;
+    curwin = tp->tp_curwin;
+    firstwin = tp->tp_firstwin;
+    lastwin = tp->tp_lastwin;
+    return FAIL;
+}
+
+/*
+ * Return a pointer to the current tab page.
+ */
+    static tabpage_T *
+current_tabpage()
+{
+    tabpage_T  *tp;
+
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+       if (tp->tp_topframe == topframe)
+           break;
+    if (tp == NULL)
+       EMSG2(_(e_intern2), "current_tabpage()");
+    return tp;
+}
+
+/*
+ * Prepare for leaving the current tab page "tp".
+ */
+    static void
+leave_tabpage(tp)
+    tabpage_T  *tp;
+{
+    tp->tp_curwin = curwin;
+    tp->tp_firstwin = firstwin;
+    tp->tp_lastwin = lastwin;
+    firstwin = NULL;
+    lastwin = NULL;
+}
+
+/*
+ * Start using tab page "tp".
+ */
+/*ARGSUSED*/
+    static void
+enter_tabpage(tp, old_curbuf)
+    tabpage_T  *tp;
+    buf_T      *old_curbuf;
+{
+    firstwin = tp->tp_firstwin;
+    lastwin = tp->tp_lastwin;
+    topframe = tp->tp_topframe;
+    win_enter_ext(tp->tp_curwin, FALSE, TRUE);
+
+#ifdef FEAT_AUTOCMD
+    if (old_curbuf != curbuf)
+       apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+#endif
+
+    /* status line may appear or disappear */
+    last_status(FALSE);
+
+#if defined(FEAT_GUI) && defined(FEAT_VERTSPLIT)
+    /* When 'guioptions' includes 'L' or 'R' may have to add or remove
+     * scrollbars. */
+    if (gui.in_use && !win_hasvertsplit())
+       gui_init_which_components(NULL);
+#endif
+
+    redraw_all_later(CLEAR);
+}
+
+/*
+ * Go to tab page "n".  For ":tab N" and "Ngt".
+ */
+    void
+goto_tabpage(n)
+    int            n;
+{
+    tabpage_T  *otp = current_tabpage();
+    tabpage_T  *tp;
+    int                i;
+
+    if (otp == NULL)
+       return;
+
+    if (n == 0)
+    {
+       /* No count, go to next tab page, wrap around end. */
+       if (otp->tp_next == NULL)
+           tp = first_tabpage;
+       else
+           tp = otp->tp_next;
+    }
+    else
+    {
+       /* Go to tab page "n". */
+       i = 0;
+       for (tp = first_tabpage; ++i != n; tp = tp->tp_next)
+           if (tp == NULL)
+           {
+               beep_flush();
+               return;
+           }
+    }
+
+    leave_tabpage(otp);
+    enter_tabpage(tp, curbuf);
+}
 
 /*
  * Go to another window.
@@ -3007,6 +3262,7 @@ win_enter_ext(wp, undo_sync, curwin_invalid)
     maketitle();
 #endif
     curwin->w_redr_status = TRUE;
+    redraw_tabpage = TRUE;
     if (restart_edit)
        redraw_later(VALID);    /* causes status line redraw */
 
@@ -3325,7 +3581,7 @@ win_free_lsize(wp)
     void
 shell_new_rows()
 {
-    int                h = (int)(Rows - p_ch);
+    int                h = (int)ROWS_AVAIL;
 
     if (firstwin == NULL)      /* not initialized yet */
        return;
@@ -3430,7 +3686,7 @@ win_size_restore(gap)
     static int
 win_comp_pos()
 {
-    int                row = 0;
+    int                row = tabpageline_height();
     int                col = 0;
 
     frame_comp_pos(topframe, &row, &col);
@@ -3593,8 +3849,8 @@ frame_setheight(curfrp, height)
     if (curfrp->fr_parent == NULL)
     {
        /* topframe: can only change the command line */
-       if (height > Rows - p_ch)
-           height = Rows - p_ch;
+       if (height > ROWS_AVAIL)
+           height = ROWS_AVAIL;
        if (height > 0)
            frame_new_height(curfrp, height, FALSE, FALSE);
     }
@@ -3841,7 +4097,7 @@ frame_setwidth(curfrp, width)
 
            if (width <= room)
                break;
-           if (run == 2 || curfrp->fr_height >= Rows - p_ch)
+           if (run == 2 || curfrp->fr_height >= ROWS_AVAIL)
            {
                if (width > room)
                    width = room;
@@ -4524,6 +4780,18 @@ last_status_rec(fr, statusline)
     }
 }
 
+/*
+ * Return TRUE if the tab page line is to be drawn.
+ */
+    int
+tabpageline_height()
+{
+    /* TODO: option to tell when to show the tabs. */
+    if (first_tabpage->tp_next == NULL)
+       return 0;
+    return 1;
+}
+
 #endif /* FEAT_WINDOWS */
 
 #if defined(FEAT_SEARCHPATH) || defined(PROTO)
@@ -4846,6 +5114,10 @@ only_one_window()
     int                count = 0;
     win_T      *wp;
 
+    /* If there is another tab page there always is another window. */
+    if (first_tabpage->tp_next != NULL)
+       return FALSE;
+
     for (wp = firstwin; wp != NULL; wp = wp->w_next)
        if (!((wp->w_buffer->b_help && !curbuf->b_help)
 # ifdef FEAT_QUICKFIX