diff options
40 files changed, 1092 insertions, 481 deletions
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index dc22930bf..391220d00 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1,4 +1,4 @@ -*editing.txt* For Vim version 7.0aa. Last change: 2006 Feb 18 +*editing.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -819,7 +819,7 @@ USING THE ARGUMENT LIST each file. {not in Vi} {not available when compiled without the |+listcmds| feature} - Also see |:windo| and |:bufdo|. + Also see |:windo|, |:tabdo| and |:bufdo|. Example: > :args *.c diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index adcd6f341..edb2fc334 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.0aa. Last change: 2006 Feb 22 +*eval.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -577,8 +577,8 @@ Expression syntax summary, from least to most significant: etc. As above, append ? for ignoring case, # for matching case - expr5 is expr5 same List instance - expr5 isnot expr5 different List instance + expr5 is expr5 same |List| instance + expr5 isnot expr5 different |List| instance |expr5| expr6 + expr6 .. number addition or list concatenation expr6 - expr6 .. number subtraction @@ -593,16 +593,16 @@ Expression syntax summary, from least to most significant: + expr7 unary plus -|expr8| expr8[expr1] byte of a String or item of a List - expr8[expr1 : expr1] substring of a String or sublist of a List - expr8.name entry in a Dictionary - expr8(expr1, ...) function call with Funcref variable +|expr8| expr8[expr1] byte of a String or item of a |List| + expr8[expr1 : expr1] substring of a String or sublist of a |List| + expr8.name entry in a |Dictionary| + expr8(expr1, ...) function call with |Funcref| variable |expr9| number number constant "string" string constant, backslash is special 'string' string constant, ' is doubled - [expr1, ...] List - {expr1: expr1, ...} Dictionary + [expr1, ...] |List| + {expr1: expr1, ...} |Dictionary| &option option value (expr1) nested expression variable internal variable @@ -714,23 +714,23 @@ Examples: "abc" == "Abc" evaluates to 1 if 'ignorecase' is set, 0 otherwise *E691* *E692* -A List can only be compared with a List and only "equal", "not equal" and "is" -can be used. This compares the values of the list, recursively. Ignoring -case means case is ignored when comparing item values. +A |List| can only be compared with a |List| and only "equal", "not equal" and +"is" can be used. This compares the values of the list, recursively. +Ignoring case means case is ignored when comparing item values. *E735* *E736* -A Dictionary can only be compared with a Dictionary and only "equal", "not -equal" and "is" can be used. This compares the key/values of the Dictionary, +A |Dictionary| can only be compared with a |Dictionary| and only "equal", "not +equal" and "is" can be used. This compares the key/values of the |Dictionary| recursively. Ignoring case means case is ignored when comparing item values. *E693* *E694* -A Funcref can only be compared with a Funcref and only "equal" and "not equal" -can be used. Case is never ignored. +A |Funcref| can only be compared with a |Funcref| and only "equal" and "not +equal" can be used. Case is never ignored. -When using "is" or "isnot" with a List this checks if the expressions are -referring to the same List instance. A copy of a List is different from the -original List. When using "is" without a List it is equivalent to using -"equal", using "isnot" equivalent to using "not equal". Except that a +When using "is" or "isnot" with a |List| this checks if the expressions are +referring to the same |List| instance. A copy of a |List| is different from +the original |List|. When using "is" without a |List| it is equivalent to +using "equal", using "isnot" equivalent to using "not equal". Except that a different type means the values are different. "4 == '4'" is true, "4 is '4'" is false. @@ -763,12 +763,12 @@ can be matched like an ordinary character. Examples: expr5 and expr6 *expr5* *expr6* --------------- -expr6 + expr6 .. Number addition or List concatenation *expr-+* +expr6 + expr6 .. Number addition or |List| concatenation *expr-+* expr6 - expr6 .. Number subtraction *expr--* expr6 . expr6 .. String concatenation *expr-.* -For Lists only "+" is possible and then both expr6 must be a list. The result -is a new list with the two lists Concatenated. +For |List|s only "+" is possible and then both expr6 must be a list. The +result is a new list with the two lists Concatenated. expr7 * expr7 .. number multiplication *expr-star* expr7 / expr7 .. number division *expr-/* @@ -783,7 +783,7 @@ Note the difference between "+" and ".": When the righthand side of '/' is zero, the result is 0x7fffffff. When the righthand side of '%' is zero, the result is 0. -None of these work for Funcrefs. +None of these work for |Funcref|s. expr7 *expr7* @@ -806,7 +806,7 @@ These three can be repeated and mixed. Examples: expr8 *expr8* ----- -expr8[expr1] item of String or List *expr-[]* *E111* +expr8[expr1] item of String or |List| *expr-[]* *E111* If expr8 is a Number or String this results in a String that contains the expr1'th single byte from expr8. expr8 is used as a String, expr1 as a @@ -821,13 +821,14 @@ If the length of the String is less than the index, the result is an empty String. A negative index always results in an empty string (reason: backwards compatibility). Use [-1:] to get the last byte. -If expr8 is a List then it results the item at index expr1. See |list-index| +If expr8 is a |List| then it results the item at index expr1. See |list-index| for possible index values. If the index is out of range this results in an error. Example: > :let item = mylist[-1] " get last item -Generally, if a List index is equal to or higher than the length of the List, -or more negative than the length of the List, this results in an error. +Generally, if a |List| index is equal to or higher than the length of the +|List|, or more negative than the length of the |List|, this results in an +error. expr8[expr1a : expr1b] substring or sublist *expr-[:]* @@ -852,20 +853,22 @@ Examples: > :let s = line(".")[4:] " from the fifth byte to the end :let s = s[:-3] " remove last two bytes -If expr8 is a List this results in a new List with the items indicated by the -indexes expr1a and expr1b. This works like with a String, as explained just -above, except that indexes out of range cause an error. Examples: > +If expr8 is a |List| this results in a new |List| with the items indicated by +the indexes expr1a and expr1b. This works like with a String, as explained +just above, except that indexes out of range cause an error. Examples: > :let l = mylist[:3] " first four items :let l = mylist[4:4] " List with one item :let l = mylist[:] " shallow copy of a List -Using expr8[expr1] or expr8[expr1a : expr1b] on a Funcref results in an error. +Using expr8[expr1] or expr8[expr1a : expr1b] on a |Funcref| results in an +error. -expr8.name entry in a Dictionary *expr-entry* +expr8.name entry in a |Dictionary| *expr-entry* -If expr8 is a Dictionary and it is followed by a dot, then the following name -will be used as a key in the Dictionary. This is just like: expr8[name]. +If expr8 is a |Dictionary| and it is followed by a dot, then the following +name will be used as a key in the |Dictionary|. This is just like: +expr8[name]. The name must consist of alphanumeric characters, just like a variable name, but it may start with a number. Curly braces cannot be used. @@ -881,7 +884,7 @@ Note that the dot is also used for String concatenation. To avoid confusion always put spaces around the dot for String concatenation. -expr8(expr1, ...) Funcref function call +expr8(expr1, ...) |Funcref| function call When expr8 is a |Funcref| type variable, invoke the function it refers to. @@ -1029,8 +1032,8 @@ specified by what is prepended: |function-argument| a: Function argument (only inside a function). |vim-variable| v: Global, predefined by Vim. -The scope name by itself can be used as a Dictionary. For example, to delete -all script-local variables: > +The scope name by itself can be used as a |Dictionary|. For example, to +delete all script-local variables: > :for k in keys(s:) : unlet s:[k] :endfor @@ -1327,7 +1330,7 @@ v:insertmode Used for the |InsertEnter| and |InsertChange| autocommand v Virtual Replace mode *v:key* *key-variable* -v:key Key of the current item of a Dictionary. Only valid while +v:key Key of the current item of a |Dictionary|. Only valid while evaluating the expression used with |map()| and |filter()|. Read-only. @@ -1459,8 +1462,8 @@ v:throwpoint The point where the exception most recently caught and not < Output: "Exception from test.vim, line 2" *v:val* *val-variable* -v:val Value of the current item of a List or Dictionary. Only valid - while evaluating the expression used with |map()| and +v:val Value of the current item of a |List| or |Dictionary|. Only + valid while evaluating the expression used with |map()| and |filter()|. Read-only. *v:version* *version-variable* @@ -1486,7 +1489,7 @@ See |function-list| for a list grouped by what the function is used for. USAGE RESULT DESCRIPTION ~ -add( {list}, {item}) List append {item} to List {list} +add( {list}, {item}) List append {item} to |List| {list} append( {lnum}, {string}) Number append {string} below line {lnum} append( {lnum}, {list}) Number append lines {list} below line {lnum} argc() Number number of files in the argument list @@ -1595,9 +1598,9 @@ inputsecret( {prompt} [, {text}]) String like input() but hiding the text insert( {list}, {item} [, {idx}]) List insert {item} in {list} [before {idx}] isdirectory( {directory}) Number TRUE if {directory} is a directory islocked( {expr}) Number TRUE if {expr} is locked -items( {dict}) List List of key-value pairs in {dict} +items( {dict}) List key-value pairs in {dict} join( {list} [, {sep}]) String join {list} items into one String -keys( {dict}) List List of keys in {dict} +keys( {dict}) List keys in {dict} len( {expr}) Number the length of {expr} libcall( {lib}, {func}, {arg}) String call {func} in library {lib} with {arg} libcallnr( {lib}, {func}, {arg}) Number idem, but return a Number @@ -1671,7 +1674,7 @@ spellbadword() String badly spelled word at cursor spellsuggest( {word} [, {max} [, {capital}]]) List spelling suggestions split( {expr} [, {pat} [, {keepempty}]]) - List make List from {pat} separated {expr} + List make |List| from {pat} separated {expr} strftime( {format}[, {time}]) String time in specified format stridx( {haystack}, {needle}[, {start}]) Number index of {needle} in {haystack} @@ -1702,7 +1705,7 @@ toupper( {expr}) String the String {expr} switched to uppercase tr( {src}, {fromstr}, {tostr}) String translate chars of {src} in {fromstr} to chars in {tostr} type( {name}) Number type of variable {name} -values( {dict}) List List of values in {dict} +values( {dict}) List values in {dict} virtcol( {expr}) Number screen column of cursor or mark visualmode( [expr]) String last visual mode used winbufnr( {nr}) Number buffer number of window {nr} @@ -1716,18 +1719,18 @@ writefile({list}, {fname} [, {binary}]) Number write list of lines to file {fname} add({list}, {expr}) *add()* - Append the item {expr} to List {list}. Returns the resulting - List. Examples: > + Append the item {expr} to |List| {list}. Returns the + resulting |List|. Examples: > :let alist = add([1, 2, 3], item) :call add(mylist, "woodstock") -< Note that when {expr} is a List it is appended as a single - item. Use |extend()| to concatenate Lists. +< Note that when {expr} is a |List| it is appended as a single + item. Use |extend()| to concatenate |List|s. Use |insert()| to add an item at another position. append({lnum}, {expr}) *append()* - When {expr} is a List: Append each item of the List as a text - line below line {lnum} in the current buffer. + When {expr} is a |List|: Append each item of the |List| as a + text line below line {lnum} in the current buffer. Otherwise append {expr} as one text line below line {lnum} in the current buffer. {lnum} can be zero to insert a line before the first one. @@ -1891,9 +1894,9 @@ byteidx({expr}, {nr}) *byteidx()* is returned. call({func}, {arglist} [, {dict}]) *call()* *E699* - Call function {func} with the items in List {arglist} as + Call function {func} with the items in |List| {arglist} as arguments. - {func} can either be a Funcref or the name of a function. + {func} can either be a |Funcref| or the name of a function. a:firstline and a:lastline are set to the cursor line. Returns the return value of the called function. {dict} is for functions with the "dict" attribute. It will be @@ -2009,17 +2012,17 @@ confirm({msg} [, {choices} [, {default} [, {type}]]]) *copy()* copy({expr}) Make a copy of {expr}. For Numbers and Strings this isn't different from using {expr} directly. - When {expr} is a List a shallow copy is created. This means - that the original List can be changed without changing the + When {expr} is a |List| a shallow copy is created. This means + that the original |List| can be changed without changing the copy, and vise versa. But the items are identical, thus - changing an item changes the contents of both Lists. Also see - |deepcopy()|. + changing an item changes the contents of both |List|s. Also + see |deepcopy()|. count({comp}, {expr} [, {ic} [, {start}]]) *count()* Return the number of times an item with value {expr} appears - in List or Dictionary {comp}. + in |List| or |Dictionary| {comp}. If {start} is given then start with the item with this index. - {start} can only be used with a List. + {start} can only be used with a |List|. When {ic} is given and it's non-zero then case is ignored. @@ -2080,16 +2083,16 @@ cursor({lnum}, {col}) *cursor()* deepcopy({expr}[, {noref}]) *deepcopy()* *E698* Make a copy of {expr}. For Numbers and Strings this isn't different from using {expr} directly. - When {expr} is a List a full copy is created. This means - that the original List can be changed without changing the - copy, and vise versa. When an item is a List, a copy for it + When {expr} is a |List| a full copy is created. This means + that the original |List| can be changed without changing the + copy, and vise versa. When an item is a |List|, a copy for it is made, recursively. Thus changing an item in the copy does - not change the contents of the original List. - When {noref} is omitted or zero a contained List or Dictionary - is only copied once. All references point to this single - copy. With {noref} set to 1 every occurrence of a List or - Dictionary results in a new copy. This also means that a - cyclic reference causes deepcopy() to fail. + not change the contents of the original |List|. + When {noref} is omitted or zero a contained |List| or + |Dictionary| is only copied once. All references point to + this single copy. With {noref} set to 1 every occurrence of a + |List| or |Dictionary| results in a new copy. This also means + that a cyclic reference causes deepcopy() to fail. *E724* Nesting is possible up to 100 levels. When there is an item that refers back to a higher level making a deep copy with @@ -2100,7 +2103,7 @@ delete({fname}) *delete()* Deletes the file by the name {fname}. The result is a Number, which is 0 if the file was deleted successfully, and non-zero when the deletion failed. - Use |remove()| to delete an item from a List. + Use |remove()| to delete an item from a |List|. *did_filetype()* did_filetype() Returns non-zero when autocommands are being executed and the @@ -2135,10 +2138,10 @@ diff_hlID({lnum}, {col}) *diff_hlID()* empty({expr}) *empty()* Return the Number 1 if {expr} is empty, zero otherwise. - A List or Dictionary is empty when it does not have any items. - A Number is empty when its value is zero. - For a long List this is much faster then comparing the length - with zero. + A |List| or |Dictionary| is empty when it does not have any + items. A Number is empty when its value is zero. + For a long |List| this is much faster then comparing the + length with zero. escape({string}, {chars}) *escape()* Escape the characters in {chars} that occur in {string} with a @@ -2151,7 +2154,7 @@ escape({string}, {chars}) *escape()* eval({string}) Evaluate {string} and return the result. Especially useful to turn the result of |string()| back into the original value. This works for Numbers, Strings and composites of them. - Also works for Funcrefs that refer to existing functions. + Also works for |Funcref|s that refer to existing functions. eventhandler() *eventhandler()* Returns 1 when inside an event handler. That is that Vim got @@ -2195,9 +2198,9 @@ exists({expr}) The result is a Number, which is non-zero if {expr} is |user-functions|). varname internal variable (see |internal-variables|). Also works - for |curly-braces-names|, Dictionary - entries, List items, etc. Beware that - this may cause functions to be + for |curly-braces-names|, |Dictionary| + entries, |List| items, etc. Beware + that this may cause functions to be invoked cause an error message for an invalid expression. :cmdname Ex command: built-in command, user @@ -2323,9 +2326,9 @@ expand({expr} [, {flag}]) *expand()* getting the raw output of an external command. extend({expr1}, {expr2} [, {expr3}]) *extend()* - {expr1} and {expr2} must be both Lists or both Dictionaries. + {expr1} and {expr2} must be both |List|s or both Dictionaries. - If they are Lists: Append {expr2} to {expr1}. + If they are |List|s: Append {expr2} to {expr1}. If {expr3} is given insert the items of {expr2} before item {expr3} in {expr1}. When {expr3} is zero insert before the first item. When {expr3} is equal to len({expr1}) then @@ -2362,28 +2365,28 @@ filereadable({file}) *filereadable()* filter({expr}, {string}) *filter()* - {expr} must be a List or a Dictionary. + {expr} must be a |List| or a |Dictionary|. For each item in {expr} evaluate {string} and when the result - is zero remove the item from the List or Dictionary. + is zero remove the item from the |List| or |Dictionary|. Inside {string} |v:val| has the value of the current item. - For a Dictionary |v:key| has the key of the current item. + For a |Dictionary| |v:key| has the key of the current item. Examples: > :call filter(mylist, 'v:val !~ "OLD"') < Removes the items where "OLD" appears. > :call filter(mydict, 'v:key >= 8') < Removes the items with a key below 8. > :call filter(var, 0) -< Removes all the items, thus clears the List or Dictionary. +< Removes all the items, thus clears the |List| or |Dictionary|. Note that {string} is the result of expression and is then used as an expression again. Often it is good to use a |literal-string| to avoid having to double backslashes. - The operation is done in-place. If you want a List or - Dictionary to remain unmodified make a copy first: > + The operation is done in-place. If you want a |List| or + |Dictionary| to remain unmodified make a copy first: > :let l = filter(copy(mylist), 'v:val =~ "KEEP"') -< Returns {expr}, the List or Dictionary that was filtered. +< Returns {expr}, the |List| or |Dictionary| that was filtered. When an error is encountered while evaluating {string} no further items in {expr} are processed. @@ -2477,35 +2480,35 @@ foreground() Move the Vim window to the foreground. Useful when sent from function({name}) *function()* *E700* - Return a Funcref variable that refers to function {name}. + Return a |Funcref| variable that refers to function {name}. {name} can be a user defined function or an internal function. garbagecollect() *garbagecollect()* - Cleanup unused Lists and Dictionaries that have circular + Cleanup unused |List|s and Dictionaries that have circular references. There is hardly ever a need to invoke this function, as it is automatically done when Vim runs out of memory or is waiting for the user to press a key after 'updatetime'. Items without circular references are always freed when they become unused. - This is useful if you have deleted a very big List and/or - Dictionary with circular references in a script that runs for - a long time. + This is useful if you have deleted a very big |List| and/or + |Dictionary| with circular references in a script that runs + for a long time. get({list}, {idx} [, {default}]) *get()* - Get item {idx} from List {list}. When this item is not + Get item {idx} from |List| {list}. When this item is not available return {default}. Return zero when {default} is omitted. get({dict}, {key} [, {default}]) - Get item with key {key} from Dictionary {dict}. When this + Get item with key {key} from |Dictionary| {dict}. When this item is not available return {default}. Return zero when {default} is omitted. *getbufline()* getbufline({expr}, {lnum} [, {end}]) - Return a List with the lines starting from {lnum} to {end} - (inclusive) in the buffer {expr}. If {end} is omitted, a List - with only the line {lnum} is returned. + Return a |List| with the lines starting from {lnum} to {end} + (inclusive) in the buffer {expr}. If {end} is omitted, a + |List| with only the line {lnum} is returned. For the use of {expr}, see |bufname()| above. @@ -2513,15 +2516,15 @@ getbufline({expr}, {lnum} [, {end}]) buffer. Otherwise a number must be used. When {lnum} is smaller than 1 or bigger than the number of - lines in the buffer, an empty List is returned. + lines in the buffer, an empty |List| is returned. When {end} is greater than the number of lines in the buffer, it is treated as {end} is set to the number of lines in the - buffer. When {end} is before {lnum} an empty List is + buffer. When {end} is before {lnum} an empty |List| is returned. This function works only for loaded buffers. For unloaded and - non-existing buffers, an empty List is returned. + non-existing buffers, an empty |List| is returned. Example: > :let lines = getbufline(bufnr("myfile"), 1, "$") @@ -2697,12 +2700,12 @@ getline({lnum} [, {end}]) < When {lnum} is smaller than 1 or bigger than the number of lines in the buffer, an empty string is returned. - When {end} is given the result is a List where each item is a - line from the current buffer in the range {lnum} to {end}, + When {end} is given the result is a |List| where each item is + a line from the current buffer in the range {lnum} to {end}, including line {end}. {end} is used in the same way as {lnum}. Non-existing lines are silently omitted. - When {end} is before {lnum} an empty List is returned. + When {end} is before {lnum} an empty |List| is returned. Example: > :let start = line('.') :let end = search("^$") - 1 @@ -2829,8 +2832,8 @@ has({feature}) The result is a Number, which is 1 if the feature {feature} is has_key({dict}, {key}) *has_key()* - The result is a Number, which is 1 if Dictionary {dict} has an - entry with key {key}. Zero otherwise. + The result is a Number, which is 1 if |Dictionary| {dict} has + an entry with key {key}. Zero otherwise. hasmapto({what} [, {mode}]) *hasmapto()* @@ -2982,7 +2985,7 @@ indent({lnum}) The result is a Number, which is indent of line {lnum} in the index({list}, {expr} [, {start} [, {ic}]]) *index()* - Return the lowest index in List {list} where the item has a + Return the lowest index in |List| {list} where the item has a value equal to {expr}. If {start} is given then start looking at the item with index {start} (may be negative for an item relative to the end). @@ -3093,18 +3096,18 @@ inputsecret({prompt} [, {text}]) *inputsecret()* NOTE: Command-line completion is not supported. insert({list}, {item} [, {idx}]) *insert()* - Insert {item} at the start of List {list}. + Insert {item} at the start of |List| {list}. If {idx} is specified insert {item} before the item with index {idx}. If {idx} is zero it goes before the first item, just like omitting {idx}. A negative {idx} is also possible, see |list-index|. -1 inserts just before the last item. - Returns the resulting List. Examples: > + Returns the resulting |List|. Examples: > :let mylist = insert([2, 3, 5], 1) :call insert(mylist, 4, -1) :call insert(mylist, 6, len(mylist)) < The last example can be done simpler with |add()|. - Note that when {item} is a List it is inserted as a single - item. Use |extend()| to concatenate Lists. + Note that when {item} is a |List| it is inserted as a single + item. Use |extend()| to concatenate |List|s. isdirectory({directory}) *isdirectory()* The result is a Number, which is non-zero when a directory @@ -3115,8 +3118,8 @@ isdirectory({directory}) *isdirectory()* islocked({expr}) *islocked()* The result is a Number, which is non-zero when {expr} is the name of a locked variable. - {expr} must be the name of a variable, List item or Dictionary - entry, not the variable itself! Example: > + {expr} must be the name of a variable, |List| item or + |Dictionary| entry, not the variable itself! Example: > :let alist = [0, ['a', 'b'], 2, 3] :lockvar 1 alist :echo islocked('alist') " 1 @@ -3126,9 +3129,10 @@ islocked({expr}) *islocked()* message. Use |exists()| to check for existance. items({dict}) *items()* - Return a List with all the key-value pairs of {dict}. Each - List item is a list with two items: the key of a {dict} entry - and the value of this entry. The List is in arbitrary order. + Return a |List| with all the key-value pairs of {dict}. Each + |List| item is a list with two items: the key of a {dict} + entry and the value of this entry. The |List| is in arbitrary + order. join({list} [, {sep}]) *join()* @@ -3138,22 +3142,22 @@ join({list} [, {sep}]) *join()* Note that {sep} is not added at the end. You might want to add it there too: > let lines = join(mylist, "\n") . "\n" -< String items are used as-is. Lists and Dictionaries are +< String items are used as-is. |List|s and Dictionaries are converted into a string like with |string()|. The opposite function is |split()|. keys({dict}) *keys()* - Return a List with all the keys of {dict}. The List is in + Return a |List| with all the keys of {dict}. The |List| is in arbitrary order. *len()* *E701* len({expr}) The result is a Number, which is the length of the argument. When {expr} is a String or a Number the length in bytes is used, as with |strlen()|. - When {expr} is a List the number of items in the List is + When {expr} is a |List| the number of items in the |List| is returned. - When {expr} is a Dictionary the number of entries in the - Dictionary is returned. + When {expr} is a |Dictionary| the number of entries in the + |Dictionary| is returned. Otherwise an error is given. *libcall()* *E364* *E368* @@ -3259,11 +3263,11 @@ localtime() *localtime()* map({expr}, {string}) *map()* - {expr} must be a List or a Dictionary. + {expr} must be a |List| or a |Dictionary|. Replace each item in {expr} with the result of evaluating {string}. Inside {string} |v:val| has the value of the current item. - For a Dictionary |v:key| has the key of the current item. + For a |Dictionary| |v:key| has the key of the current item. Example: > :call map(mylist, '"> " . v:val . " <"') < This puts "> " before and " <" after each item in "mylist". @@ -3273,11 +3277,11 @@ map({expr}, {string}) *map()* |literal-string| to avoid having to double backslashes. You still have to double ' quotes - The operation is done in-place. If you want a List or - Dictionary to remain unmodified make a copy first: > + The operation is done in-place. If you want a |List| or + |Dictionary| to remain unmodified make a copy first: > :let tlist = map(copy(mylist), ' & . "\t"') -< Returns {expr}, the List or Dictionary that was filtered. +< Returns {expr}, the |List| or |Dictionary| that was filtered. When an error is encountered while evaluating {string} no further items in {expr} are processed. @@ -3335,13 +3339,13 @@ mapcheck({name}[, {mode}]) *mapcheck()* mapping for "_v" or for "_vvv". match({expr}, {pat}[, {start}[, {count}]]) *match()* - When {expr} is a List then this returns the index of the first - item where {pat} matches. Each item is used as a String, - Lists and Dictionaries are used as echoed. + When {expr} is a |List| then this returns the index of the + first item where {pat} matches. Each item is used as a + String, |List|s and Dictionaries are used as echoed. Otherwise, {expr} is used as a String. The result is a Number, which gives the index (byte offset) in {expr} where {pat} matches. - A match at the first character or List item returns zero. + A match at the first character or |List| item returns zero. If there is no match -1 is returned. Example: > :echo match("testing", "ing") " results in 4 @@ -3359,10 +3363,10 @@ match({expr}, {pat}[, {start}[, {count}]]) *match()* is found in a String the search for the next one starts on character further. Thus this example results in 1: > echo match("testing", "..", 0, 2) -< In a List the search continues in the next item. +< In a |List| the search continues in the next item. If {start} is given, the search starts from byte index - {start} in a String or item {start} in a List. + {start} in a String or item {start} in a |List|. The result, however, is still the index counted from the first character/item. Example: > :echo match("testing", "ing", 2) @@ -3374,7 +3378,7 @@ match({expr}, {pat}[, {start}[, {count}]]) *match()* For a String, if {start} < 0, it will be set to 0. For a list the index is counted from the end. If {start} is out of range (> strlen({expr} for a String or - > len({expr} for a List) -1 is returned. + > len({expr} for a |List|) -1 is returned. See |pattern| for the patterns that are accepted. The 'ignorecase' option is used to set the ignore-caseness of @@ -3398,10 +3402,10 @@ matchend({expr}, {pat}[, {start}[, {count}]]) *matchend()* < results in "7". > :echo matchend("testing", "ing", 5) < result is "-1". - When {expr} is a List the result is equal to match(). + When {expr} is a |List| the result is equal to match(). matchlist({expr}, {pat}[, {start}[, {count}]]) *matchlist()* - Same as match(), but return a List. The first item in the + Same as match(), but return a |List|. The first item in the list is the matched string, same as what matchstr() would return. Following items are submatches, like "\1", "\2", etc. in |:substitute|. @@ -3417,20 +3421,20 @@ matchstr({expr}, {pat}[, {start}[, {count}]]) *matchstr()* < results in "ing". > :echo matchstr("testing", "ing", 5) < result is "". - When {expr} is a List then the matching item is returned. + When {expr} is a |List| then the matching item is returned. The type isn't changed, it's not necessarily a String. *max()* max({list}) Return the maximum value of all items in {list}. If {list} is not a list or one of the items in {list} cannot be used as a Number this results in an error. - An empty List results in zero. + An empty |List| results in zero. *min()* min({list}) Return the minumum value of all items in {list}. If {list} is not a list or one of the items in {list} cannot be used as a Number this results in an error. - An empty List results in zero. + An empty |List| results in zero. *mkdir()* *E749* mkdir({name} [, {path} [, {prot}]]) @@ -3624,7 +3628,7 @@ pumvisible() *pumvisible()* *E726* *E727* range({expr} [, {max} [, {stride}]]) *range()* - Returns a List with Numbers: + Returns a |List| with Numbers: - If only {expr} is specified: [0, 1, ..., {expr} - 1] - If {max} is specified: [{expr}, {expr} + 1, ..., {max}] - If {stride} is specified: [{expr}, {expr} + {stride}, ..., @@ -3643,8 +3647,8 @@ range({expr} [, {max} [, {stride}]]) *range()* < *readfile()* readfile({fname} [, {binary} [, {max}]]) - Read file {fname} and return a List, each line of the file as - an item. Lines broken at NL characters. Macintosh files + Read file {fname} and return a |List|, each line of the file + as an item. Lines broken at NL characters. Macintosh files separated with CR will result in a single long line (unless a NL appears somewhere). When {binary} is equal to "b" binary mode is used: @@ -3748,7 +3752,7 @@ remote_send({server}, {string} [, {idvar}]) \ 'server2client(expand("<client>"), "HELLO")<CR>') < remove({list}, {idx} [, {end}]) *remove()* - Without {end}: Remove the item at {idx} from List {list} and + Without {end}: Remove the item at {idx} from |List| {list} and return it. With {end}: Remove items from {idx} to {end} (inclusive) and return a list with these items. When {idx} points to the same @@ -3777,7 +3781,7 @@ repeat({expr}, {count}) *repeat()* result. Example: > :let seperator = repeat('-', 80) < When {count} is zero or negative the result is empty. - When {expr} is a List the result is {expr} concatenated + When {expr} is a |List| the result is {expr} concatenated {count} times. Example: > :let longlist = repeat(['a', 'b'], 3) < Results in ['a', 'b', 'a', 'b', 'a', 'b']. @@ -3940,9 +3944,9 @@ searchpair({start}, {middle}, {end} [, {flags} [, {skip}]]) < *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 + 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]. > @@ -3951,11 +3955,11 @@ searchpairpos({start}, {middle}, {end} [, {flags} [, {skip}]]) 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]. + 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') < @@ -4015,7 +4019,7 @@ setline({lnum}, {line}) *setline()* If this succeeds, 0 is returned. If this fails (most likely because {lnum} is invalid) 1 is returned. Example: > :call setline(5, strftime("%c")) -< When {line} is a List then line {lnum} and following lines +< When {line} is a |List| then line {lnum} and following lines will be set to the items in the list. Example: > :call setline(5, ['aaa', 'bbb', 'ccc']) < This is equivalent to: > @@ -4138,11 +4142,11 @@ sort({list} [, {func}]) *sort()* *E702* want a list to remain unmodified make a copy first: > :let sortedlist = sort(copy(mylist)) < Uses the string representation of each item to sort on. - Numbers sort after Strings, Lists after Numbers. + Numbers sort after Strings, |List|s after Numbers. For sorting text in the current buffer use |:sort|. When {func} is given and it is one then case is ignored. - When {func} is a Funcref or a function name, this function is - called to compare items. The function is invoked with two + When {func} is a |Funcref| or a function name, this function + is called to compare items. The function is invoked with two items as argument and must return zero if they are equal, 1 if the first one sorts after the second one, -1 if the first one sorts before the second one. Example: > @@ -4189,7 +4193,7 @@ spellbadword([{sentence}]) *spellsuggest()* spellsuggest({word} [, {max} [, {capital}]]) - Return a List with spelling suggestions to replace {word}. + Return a |List| with spelling suggestions to replace {word}. When {max} is given up to this number of suggestions are returned. Otherwise up to 25 suggestions are returned. @@ -4212,8 +4216,9 @@ spellsuggest({word} [, {max} [, {capital}]]) split({expr} [, {pattern} [, {keepempty}]]) *split()* - Make a List out of {expr}. When {pattern} is omitted or empty - each white-separated sequence of characters becomes an item. + Make a |List| out of {expr}. When {pattern} is omitted or + empty each white-separated sequence of characters becomes an + item. Otherwise the string is split where {pattern} matches, removing the matched characters. When the first or last item is empty it is omitted, unless the @@ -4454,7 +4459,7 @@ system({expr} [, {input}]) *system()* *E677* tabpagebuflist([{arg}]) *tabpagebuflist()* - The result is a List, where each item is the number of the + The result is a |List|, where each item is the number of the buffer associated with each window in the current tab page. {arg} specifies the number of tab page to be used. When omitted the current tab page is used. @@ -4525,8 +4530,8 @@ taglist({expr}) *taglist()* the tags file generated by the different ctags tools. *tagfiles()* -tagfiles() Returns a List with the file names used to search for tags for - the current buffer. This is the 'tags' option expanded. +tagfiles() Returns a |List| with the file names used to search for tags + for the current buffer. This is the 'tags' option expanded. tempname() *tempname()* *temp-file-name* @@ -4581,8 +4586,8 @@ type({expr}) The result is a Number, depending on the type of {expr}: :if type(myvar) == type({}) values({dict}) *values()* - Return a List with all the values of {dict}. The List is in - arbitrary order. + Return a |List| with all the values of {dict}. The |List| is + in arbitrary order. virtcol({expr}) *virtcol()* @@ -4593,6 +4598,8 @@ virtcol({expr}) *virtcol()* position, the returned Number will be the column at the end of the <Tab>. For example, for a <Tab> in column 1, with 'ts' set to 8, it returns 8. + For the use of {expr} see |col()|. Additionally you can use + [lnum, col]: a |List| with the line and column number. For the byte position use |col()|. When Virtual editing is active in the current mode, a position beyond the end of the line can be returned. |'virtualedit'| @@ -4688,7 +4695,7 @@ winwidth({nr}) *winwidth()* < *writefile()* writefile({list}, {fname} [, {binary}]) - Write List {list} to file {fname}. Each list item is + Write |List| {list} to file {fname}. Each list item is separated with a NL. Each list item must be a String or Number. When {binary} is equal to "b" binary mode is used: There will @@ -4930,8 +4937,8 @@ instead of "s:" when the mapping is expanded outside of the script. :fu[nction] List all functions and their arguments. :fu[nction] {name} List function {name}. - {name} can also be a Dictionary entry that is a - Funcref: > + {name} can also be a |Dictionary| entry that is a + |Funcref|: > :function dict.init :fu[nction] /{pattern} List functions with a name matching {pattern}. @@ -4954,8 +4961,8 @@ See |:verbose-cmd| for more information. must be made of alphanumeric characters and '_', and must start with a capital or "s:" (see above). - {name} can also be a Dictionary entry that is a - Funcref: > + {name} can also be a |Dictionary| entry that is a + |Funcref|: > :function dict.init(arg) < "dict" must be an existing dictionary. The entry "init" is added if it didn't exist yet. Otherwise [!] @@ -4983,7 +4990,7 @@ See |:verbose-cmd| for more information. abort as soon as an error is detected. When the [dict] argument is added, the function must - be invoked through an entry in a Dictionary. The + be invoked through an entry in a |Dictionary|. The local variable "self" will then be set to the dictionary. See |Dictionary-function|. @@ -4996,8 +5003,8 @@ See |:verbose-cmd| for more information. *:delf* *:delfunction* *E130* *E131* :delf[unction] {name} Delete function {name}. - {name} can also be a Dictionary entry that is a - Funcref: > + {name} can also be a |Dictionary| entry that is a + |Funcref|: > :delfunc dict.init < This will remove the "init" entry from "dict". The function is deleted if there are no more references to @@ -5026,14 +5033,14 @@ Up to 20 arguments can be given, separated by commas. After the named arguments an argument "..." can be specified, which means that more arguments may optionally be following. In the function the extra arguments can be used as "a:1", "a:2", etc. "a:0" is set to the number of extra arguments (which -can be 0). "a:000" is set to a List that contains these arguments. Note that -"a:1" is the same as "a:000[0]". +can be 0). "a:000" is set to a |List| that contains these arguments. Note +that "a:1" is the same as "a:000[0]". *E742* The a: scope and the variables in it cannot be changed, they are fixed. -However, if a List or Dictionary is used, you can changes their contents. -Thus you can pass a List to a function and have the function add an item to -it. If you want to make sure the function cannot change a List or Dictionary -use |:lockvar|. +However, if a |List| or |Dictionary| is used, you can changes their contents. +Thus you can pass a |List| to a function and have the function add an item to +it. If you want to make sure the function cannot change a |List| or +|Dictionary| use |:lockvar|. When not using "...", the number of arguments in a function call must be equal to the number of named arguments. When using "...", the number of arguments @@ -5269,8 +5276,8 @@ This would call the function "my_func_whizz(parameter)". *E711* *E719* :let {var-name}[{idx1}:{idx2}] = {expr1} *E708* *E709* *E710* - Set a sequence of items in a List to the result of the - expression {expr1}, which must be a list with the + Set a sequence of items in a |List| to the result of + the expression {expr1}, which must be a list with the correct number of items. {idx1} can be omitted, zero is used instead. {idx2} can be omitted, meaning the end of the list. @@ -5345,11 +5352,11 @@ This would call the function "my_func_whizz(parameter)". (if there is one). Works like |:setglobal|. :let [{name1}, {name2}, ...] = {expr1} *:let-unpack* *E687* *E688* - {expr1} must evaluate to a List. The first item in + {expr1} must evaluate to a |List|. The first item in the list is assigned to {name1}, the second item to {name2}, etc. The number of names must match the number of items in - the List. + the |List|. Each name can be one of the items of the ":let" command as mentioned above. Example: > @@ -5367,10 +5374,10 @@ This would call the function "my_func_whizz(parameter)". :let [{name1}, {name2}, ...] += {expr1} :let [{name1}, {name2}, ...] -= {expr1} Like above, but append/add/subtract the value for each - List item. + |List| item. :let [{name}, ..., ; {lastname}] = {expr1} - Like |:let-unpack| above, but the List may have more + Like |:let-unpack| above, but the |List| may have more items than there are names. A list of the remaining items is assigned to {lastname}. If there are no remaining items {lastname} is set to an empty list. @@ -5381,7 +5388,7 @@ This would call the function "my_func_whizz(parameter)". :let [{name}, ..., ; {lastname}] += {expr1} :let [{name}, ..., ; {lastname}] -= {expr1} Like above, but append/add/subtract the value for each - List item. + |List| item. *E106* :let {var-name} .. List the value of variable {var-name}. Multiple variable names may be given. Special names recognized @@ -5401,13 +5408,13 @@ This would call the function "my_func_whizz(parameter)". :unl[et][!] {name} ... *:unlet* *:unl* *E108* Remove the internal variable {name}. Several variable names can be given, they are all removed. The name - may also be a List or Dictionary item. + may also be a |List| or |Dictionary| item. With [!] no error message is given for non-existing variables. - One or more items from a List can be removed: > + One or more items from a |List| can be removed: > :unlet list[3] " remove fourth item :unlet list[3:] " remove fourth item to last -< One item from a Dictionary can be removed at a time: > +< One item from a |Dictionary| can be removed at a time: > :unlet dict['two'] :unlet dict.two @@ -5422,28 +5429,30 @@ This would call the function "my_func_whizz(parameter)". If you try to change a locked variable you get an error message: "E741: Value of {name} is locked" - [depth] is relevant when locking a List or Dictionary. - It specifies how deep the locking goes: - 1 Lock the List or Dictionary itself, + [depth] is relevant when locking a |List| or + |Dictionary|. It specifies how deep the locking goes: + 1 Lock the |List| or |Dictionary| itself, cannot add or remove items, but can still change their values. 2 Also lock the values, cannot change - the items. If an item is a List or - Dictionary, cannot add or remove + the items. If an item is a |List| or + |Dictionary|, cannot add or remove items, but can still change the values. - 3 Like 2 but for the List/Dictionary in - the List/Dictionary, one level deeper. - The default [depth] is 2, thus when {name} is a List - or Dictionary the values cannot be changed. + 3 Like 2 but for the |List| / + |Dictionary| in the |List| / + |Dictionary|, one level deeper. + The default [depth] is 2, thus when {name} is a |List| + or |Dictionary| the values cannot be changed. *E743* For unlimited depth use [!] and omit [depth]. However, there is a maximum depth of 100 to catch loops. - Note that when two variables refer to the same List - and you lock one of them, the List will also be locked - when used through the other variable. Example: > + Note that when two variables refer to the same |List| + and you lock one of them, the |List| will also be + locked when used through the other variable. Example: + > :let l = [0, 1, 2, 3] :let cl = l :lockvar l diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index f7d512553..2bc8af3ba 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -1,4 +1,4 @@ -*index.txt* For Vim version 7.0aa. Last change: 2006 Feb 23 +*index.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1446,11 +1446,14 @@ The commands are sorted on the non-optional part of their name. |:tabclose| :tabc[lose] close current tab page |:tabedit| :tabe[dit] edit a file in a new tab page |:tabfind| :tabf[ind] find file in 'path', edit it in a new tab page +|:tabfirst| :tabfir[st] got to first tab page +|:tablast| :tabl[ast] got to last tab page |:tabmove| :tabm[ove] move tab page to other position |:tabnew| :tabnew edit a file in a new tab page |:tabnext| :tabn[ext] go to next tab page |:tabonly| :tabo[nly] close all tab pages except the current one |:tabprevious| :tabp[revious] go to previous tab page +|:tabrewind| :tabr[ewind] got to first tab page |:tabs| :tabs list the tab pages and what they contain |:tab| :tab create new tab when opening new window |:tag| :ta[g] jump to tag diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt index 440effa6c..67872fb70 100644 --- a/runtime/doc/map.txt +++ b/runtime/doc/map.txt @@ -1,4 +1,4 @@ -*map.txt* For Vim version 7.0aa. Last change: 2006 Feb 10 +*map.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -778,7 +778,7 @@ This does not work if 'cpoptions' includes the '<' flag. |<>| You can even do more complicated things. For example, to consume the space typed after an abbreviation: > func Eatchar(pat) - let c = nr2char(getchar()) + let c = nr2char(getchar(0)) return (c =~ a:pat) ? '' : c endfunc iabbr <silent> if if ()<Left><C-R>=Eatchar('\s')<CR> diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index b8931aee3..122b26d5e 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 7.0aa. Last change: 2006 Feb 22 +*options.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -3249,6 +3249,9 @@ A jump table for the options with a short description can be found at |Q_op|. 'c' Use console dialogs instead of popup dialogs for simple choices. + 'e' Add tab pages when indicated with 'showtabpages'. When 'e' is + missing a non-GUI tab pages line may be used. + 'f' Foreground: Don't use fork() to detach the GUI from the shell where it was started. Use this for programs that wait for the editor to finish (e.g., an e-mail program). Alternatively you diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt index 5f394b398..7469869d8 100644 --- a/runtime/doc/tabpage.txt +++ b/runtime/doc/tabpage.txt @@ -1,4 +1,4 @@ -*tabpage.txt* For Vim version 7.0aa. Last change: 2006 Feb 23 +*tabpage.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -132,6 +132,12 @@ gT Go to the previous tab page. Wraps around from the first one {count}gT Go {count} tab pages back. Wraps around from the first one to the last one. +:tabr[ewind] *:tabfir* *:tabfirst* *:tabr* *:tabrewind* +:tabl[ast] Go to the first tab page. + + *:tabl* *:tablast* +:tabl[ast] Go to the last tab page. + Other commands: *:tabs* @@ -147,6 +153,28 @@ REORDERING TAB PAGES: make the current tab page the first one. Without N the tab page is made the last one. + +LOOPING OVER TAB PAGES: + + *:tabd* *:tabdo* +:tabd[o] {cmd} Execute {cmd} in each tab page. + It works like doing this: > + :tabfirst + :{cmd} + :tabnext + :{cmd} + etc. +< This only operates in the current window of each tab page. + When an error is detected on one tab page, further tab pages + will not be visited. + The last tab page (or where an error occurred) becomes the + current tab page. + {cmd} can contain '|' to concatenate several commands. + {cmd} must not open or close tab pages or reorder them. + {not in Vi} {not available when compiled without the + |+listcmds| feature} + Also see |:windo|, |:argdo| and |:bufdo|. + ============================================================================== 3. Other items *tab-page-other* diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt index f35f165ff..e6c2740f0 100644 --- a/runtime/doc/tagsrch.txt +++ b/runtime/doc/tagsrch.txt @@ -1,4 +1,4 @@ -*tagsrch.txt* For Vim version 7.0aa. Last change: 2005 Oct 15 +*tagsrch.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -36,19 +36,26 @@ An easy way back is with the CTRL-T command. Also read about the tag stack below. *:ta* *:tag* *E426* *E429* -:ta[g][!] {ident} Jump to the definition of {ident}, using the +:[count]ta[g][!] {ident} + Jump to the definition of {ident}, using the information in the tags file(s). Put {ident} in the tag stack. See |tag-!| for [!]. {ident} can be a regexp pattern, see |tag-regexp|. - When there are several matching tags for {ident}, the - first one is jumped to. |:tnext|. + When there are several matching tags for {ident}, jump + to the [count] one. When [count] is omitted the + first one is jumped to. See |tag-matchlist| for + jumping to other matching tags. g<LeftMouse> *g<LeftMouse>* <C-LeftMouse> *<C-LeftMouse>* *CTRL-]* CTRL-] Jump to the definition of the keyword under the cursor. Same as ":tag {ident}", where {ident} is the - keyword under or after cursor. {Vi: identifier after - the cursor} + keyword under or after cursor. + When there are several matching tags for {ident}, jump + to the [count] one. When no [count] is given the + first one is jumped to. See |tag-matchlist| for + jumping to other matching tags. + {Vi: identifier after the cursor} *v_CTRL-]* {Visual}CTRL-] Same as ":tag {ident}", where {ident} is the text that diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 93a92fd43..89370acdb 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 7.0aa. Last change: 2006 Feb 23 +*todo.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -30,17 +30,32 @@ be worked on, but only if you sponsor Vim development. See |sponsor|. *known-bugs* -------------------- Known bugs and current work ----------------------- -:tablast -:tabfirst -Also support: - :tabdup split the tab with all its windows. - :tab ball tab page for each buffer - :tab all tab page for each argument - :tabdo cmd ":tabdo windo cmd" should also work - -In GUI: right click can popup a menu to close a specific tab. -Option to put tab line at the left or right? Need an option to specify its -witdh. It's like a separate window with ":tabs" output. +Fix for hlsearch getting stuck on multibyte char also in 6.4. reportec by +Yukihiro Nakadaira. + + +Tab pages: +- GTK GUI implementation for the tab pages line: + /tmp/vim61_tab.patch.bz2 + Window height can be wrong: + :set go-=e + resize to fill screen + :set go+=e + Add 'guitabitem' option? +- GUI implementation for the tab pages line for other systems. +8 tab pages in the session file, if "tabpages" in 'sessionoptions' +7 :tabdup duplicate the tab with all its windows. +6 :tab ball tab page for each buffer +6 :tab all tab page for each argument +7 In GUI: right click can popup a menu to close a specific tab. +7 Option to put tab line at the left or right? Need an option to specify + its witdh. It's like a separate window with ":tabs" output. +7 Add local variables for each tab page? +8 Add local options for each tab page? E.g., 'diffopt' could differ between + tab pages. +7 Add local highlighting for a tab page? + +Spelling: m'n -> no suggestion for "mijn"? Add an argument to search functions to stop at a certain line number. search('{', 'b', line('w0')) @@ -49,15 +64,6 @@ Also start at a specified position? undo could remember the '< and '> marks. -Support WINDOW TABS. Works like several pages, each with their own split -windows. Let's call them "tab pages". - - line at top of frame with tabs. - Add 'tabtext' option, like 'statusline'. - - Need to be able to search the windows in inactive tabs, e.g. for the - quickfix window? - - docs: - Add info to the user manual somewhere. - Crash with X command server (Ciaran McCreesh). Make virtcol([lnum, col]) work? @@ -484,16 +490,6 @@ Patch for "paranoid mode" by Kevin Collins, March 7. Needs much more work. Check if file explorer can handle directory names and links with a single quote. (Nieko Maatjes, 2005 Jan 4) -Future enhancements for tab pages: - - Add GUI Tabs for all systems. - Patch for GTK 1.2 passed on by Christian Michon, 2004 Jan 6. - Simple patch for GTK by Luis M (nov 7). - - ":tabsplit" makes a copy of the current tab page. - - Add local variables for each tab page? - - Add local options for each tab page? E.g., 'diffopt' could differ - between tab pages. - - Add local highlighting for a tab page? - Vi incompatibility: 8 With undo/redo only marks in the changed lines should be changed. Other @@ -2074,7 +2070,6 @@ 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 to type the tag number directly. diff --git a/runtime/doc/usr_08.txt b/runtime/doc/usr_08.txt index cee90dca3..c4212ef10 100644 --- a/runtime/doc/usr_08.txt +++ b/runtime/doc/usr_08.txt @@ -1,4 +1,4 @@ -*usr_08.txt* For Vim version 7.0aa. Last change: 2005 Apr 01 +*usr_08.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM USER MANUAL - by Bram Moolenaar @@ -17,6 +17,7 @@ side by side. All this is possible with split windows. |08.6| Commands for all windows |08.7| Viewing differences with vimdiff |08.8| Various +|08.9| Tab pages Next chapter: |usr_09.txt| Using the GUI Previous chapter: |usr_07.txt| Editing more than one file @@ -504,6 +505,95 @@ window is to appear: :topleft {cmd} at the top or left of the Vim window :botright {cmd} at the bottom or right of the Vim window + +============================================================================== +*08.9* Tab pages + +You will have noticed that windows never overlap. That means you quickly run +out of screen space. The solution for this is called Tab pages. + +Assume you are editing "thisfile". To create a new tab page use this command: > + + :tabedit thatfile + +This will edit the file "thatfile" in a window that occupies the whole Vim +window. And you will notice a bar at the top with the two file names: + + +----------------------------------+ + |_thisfile_| thatfile ____________X| + |/* thatfile */ | + |that | + |that | + |~ | + |~ | + |~ | + | | + +----------------------------------+ + +You now have two tab pages. The first one has a window for "thisfile" and the +second one a window for "thatfile". It's like two pages that are on top of +eachother, with a tab sticking out of each page showing the file name. + +Now use the mouse to click on "thisfile" in the top line. The result is + + +----------------------------------+ + | thisfile |_thatfile_____________X| + |/* thisfile */ | + |this | + |this | + |~ | + |~ | + |~ | + | | + +----------------------------------+ + +Thus you can switch between tab pages by clicking on the label in the top +line. If you don't have a mouse or don't want to use it, you can use the "gt" +command. Mnemonic: Goto Tab. + +Now let's create another tab page with the command: > + + :tab split + +This makes a new tab page with one window that is editing the same buffer as +the window we were in: + + +-------------------------------------+ + |_thisfile_| thisfile | _thatfile____X| + |/* thisfile */ | + |this | + |this | + |~ | + |~ | + |~ | + | | + +-------------------------------------+ + +You can put ":tab" before any Ex command that opens a window. The window will +be opened in a new tab page. Another example: > + + :tab help gt + +Will show the help text for "gt" in a new tab page. + +A few more things you can do with tab pages: + +- click with the mouse in the space after the last label + The next tab page will be selected, like with "gt". + +- click with the mouse on the "X" in the top right corner + The current tab page will be closed. Unless there are unsaved + changes in the current tab page. + +- double click with the mouse in the top line + A new tab page will be created. + +- the "tabonly" command + Closes all tab pages except the current one. Unless there are unsaved + changes in other tab pages. + +For more information about tab pages see |tab-page|. + ============================================================================== Next chapter: |usr_09.txt| Using the GUI diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt index 6da26a0f9..465c02c44 100644 --- a/runtime/doc/version7.txt +++ b/runtime/doc/version7.txt @@ -1,4 +1,4 @@ -*version7.txt* For Vim version 7.0aa. Last change: 2006 Feb 23 +*version7.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1038,6 +1038,10 @@ made empty to avoid an endless redraw loop. Also for other options, such at 'tabline'. ":verbose set statusline" will mention that it was set in an error handler. +When there are several matching tags, the ":tag <name>" and CTRL-] commands +jump to the [count] matching tag. (Yegappan Lakshmanan) + + ============================================================================== COMPILE TIME CHANGES *compile-changes-7* @@ -1740,4 +1744,9 @@ For a color terminal: When the Normal HL uses bold, possibly to make the color lighter, and another HL group specifies a color it might become light as well. Now reset bold if a HL group doesn't specify bold itself. +When using 256 color xterm the color 255 would show up as color 0. Use a +short instead of a char to store the color number. + +ml_get errors when searching for "\n\zs" in an empty file. + vim:tw=78:ts=8:ft=help:norl: diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index cd57287f3..060408abb 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -1,4 +1,4 @@ -*windows.txt* For Vim version 7.0aa. Last change: 2006 Feb 23 +*windows.txt* For Vim version 7.0aa. Last change: 2006 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -629,7 +629,7 @@ can also get to them with the buffer list commands, like ":bnext". CTRL-W w :{cmd} etc. -< This only works in the current tab page. +< This only operates in the current tab page. When an error is detected on one window, further windows will not be visited. The last window (or where an error occurred) becomes @@ -638,7 +638,7 @@ can also get to them with the buffer list commands, like ":bnext". {cmd} must not open or close windows or reorder them. {not in Vi} {not available when compiled without the |+listcmds| feature} - Also see |:argdo| and |:bufdo|. + Also see |:tabdo|, |:argdo| and |:bufdo|. *:bufdo* :bufdo[!] {cmd} Execute {cmd} in each buffer in the buffer list. @@ -664,7 +664,7 @@ can also get to them with the buffer list commands, like ":bnext". each buffer. {not in Vi} {not available when compiled without the |+listcmds| feature} - Also see |:argdo| and |:windo|. + Also see |:tabdo|, |:argdo| and |:windo|. Examples: > diff --git a/src/Makefile b/src/Makefile index 1cdfd742d..8ff3e3b2e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -548,8 +548,8 @@ LINT_OPTIONS = -beprxzF #PROFILE_LIBS = -lccmalloc # MAC OS X platform -#MAC_OSX_ARCH = -arch ppc -MAC_OSX_ARCH = -arch i386 -arch ppc +MAC_OSX_ARCH = -arch ppc +#MAC_OSX_ARCH = -arch i386 ##################################################### ### Specific systems, check if yours is listed! ### {{{ diff --git a/src/auto/configure b/src/auto/configure index 05897e231..41245b578 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -2780,7 +2780,7 @@ if test -z "$CFLAGS"; then test "$GCC" = yes && CFLAGS="-O2 -fno-strength-reduce -Wall" fi if test "$GCC" = yes; then - gccversion=`"$CC" --version | sed -e '2,$d;s/^[^0-9]*\([0-9]\.[0-9.]*\).*$/\1/g'` + gccversion=`"$CC" --version | sed -e '2,$d;s/^[^0-9]*\(darwin.[^0-9]*\)*\([0-9]\.[0-9.]*\).*$/\2/g'` if test "$gccversion" = "3.0.1" -o "$gccversion" = "3.0.2" -o "$gccversion" = "4.0.1"; then echo 'GCC 34.0.12 has a bug in the optimizer, disabling "-O#"' CFLAGS=`echo "$CFLAGS" | sed 's/-O[23456789]/-O/'` @@ -2868,7 +2868,7 @@ echo "${ECHO_T}yes, Darwin support excluded" >&6 MACOSX=yes OS_EXTRA_SCR="os_macosx.c os_mac_conv.c"; OS_EXTRA_OBJ="objects/os_macosx.o objects/os_mac_conv.o" - CPPFLAGS="$CPPFLAGS -DMACOS_X_UNIX -I/Developer/Headers/FlatCarbon -no-cpp-precomp" + CPPFLAGS="$CPPFLAGS -DMACOS_X_UNIX -I/Developer/Headers/FlatCarbon -no-cpp-precomp -arch ppc" echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 @@ -15087,7 +15087,7 @@ echo "$as_me:$LINENO: checking for GCC 3 or later" >&5 echo $ECHO_N "checking for GCC 3 or later... $ECHO_C" >&6 DEPEND_CFLAGS_FILTER= if test "$GCC" = yes; then - gccmajor=`"$CC" --version | sed -e '2,$d;s/^[^0-9]*\([1-9]\)\.[0-9.]*.*$/\1/g'` + gccmajor=`"$CC" --version | sed -e '2,$d;s/^[^0-9]*\(darwin.[^0-9]*\)*\([1-9]\)\.[0-9].*$/\2/g'` if test "$gccmajor" -gt "2"; then DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'" fi diff --git a/src/configure.in b/src/configure.in index 913d3e9a4..382d1af16 100644 --- a/src/configure.in +++ b/src/configure.in @@ -29,7 +29,7 @@ if test -z "$CFLAGS"; then test "$GCC" = yes && CFLAGS="-O2 -fno-strength-reduce -Wall" fi if test "$GCC" = yes; then - gccversion=`"$CC" --version | sed -e '2,$d;s/^[[^0-9]]*\([[0-9]]\.[[0-9.]]*\).*$/\1/g'` + gccversion=`"$CC" --version | sed -e '2,$d;s/^[[^0-9]]*\(darwin.[[^0-9]]*\)*\([[0-9]]\.[[0-9.]]*\).*$/\2/g'` dnl version 4.0.1 was reported to cause trouble on Macintosh by Marcin Dalecki if test "$gccversion" = "3.0.1" -o "$gccversion" = "3.0.2" -o "$gccversion" = "4.0.1"; then echo 'GCC [34].0.[12] has a bug in the optimizer, disabling "-O#"' @@ -106,7 +106,8 @@ if test "`(uname) 2>/dev/null`" = Darwin; then MACOSX=yes OS_EXTRA_SCR="os_macosx.c os_mac_conv.c"; OS_EXTRA_OBJ="objects/os_macosx.o objects/os_mac_conv.o" - CPPFLAGS="$CPPFLAGS -DMACOS_X_UNIX -I/Developer/Headers/FlatCarbon -no-cpp-precomp -arch i386 -arch ppc" + dnl TODO: use -arch i386 on Intel machines + CPPFLAGS="$CPPFLAGS -DMACOS_X_UNIX -I/Developer/Headers/FlatCarbon -no-cpp-precomp -arch ppc" dnl If Carbon is found, assume we don't want X11 dnl unless it was specifically asked for (--with-x) @@ -2757,10 +2758,12 @@ fi dnl gcc 3.1 changed the meaning of -MM. The only solution appears to be to dnl use "-isystem" instead of "-I" for all non-Vim include dirs. dnl But only when making dependencies, cproto and lint don't take "-isystem". +dnl Mac gcc returns "powerpc-apple-darwin8-gcc-4.0.1 (GCC)...", need to allow +dnl the number before the version number. AC_MSG_CHECKING(for GCC 3 or later) DEPEND_CFLAGS_FILTER= if test "$GCC" = yes; then - gccmajor=`"$CC" --version | sed -e '2,$d;s/^[[^0-9]]*\([[1-9]]\)\.[[0-9.]]*.*$/\1/g'` + gccmajor=`"$CC" --version | sed -e '2,$d;s/^[[^0-9]]*\(darwin.[[^0-9]]*\)*\([[1-9]]\)\.[[0-9]].*$/\2/g'` if test "$gccmajor" -gt "2"; then DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'" fi diff --git a/src/eval.c b/src/eval.c index fef09d02f..52525e6c4 100644 --- a/src/eval.c +++ b/src/eval.c @@ -14934,7 +14934,6 @@ f_tabpagenr(argvars, rettv) { int nr = 1; #ifdef FEAT_WINDOWS - tabpage_T *tp; char_u *arg; if (argvars[0].v_type != VAR_UNKNOWN) @@ -14944,15 +14943,13 @@ f_tabpagenr(argvars, rettv) if (arg != NULL) { if (STRCMP(arg, "$") == 0) - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) - ++nr; + nr = tabpage_index(NULL); else EMSG2(_(e_invexpr2), arg); } } else - for (tp = first_tabpage; tp != curtab; tp = tp->tp_next) - ++nr; + nr = tabpage_index(curtab); #endif rettv->vval.v_number = nr; } @@ -15616,6 +15613,7 @@ f_writefile(argvars, rettv) /* * Translate a String variable into a position. + * Returns NULL when there is an error. */ static pos_T * var2fpos(varp, lnum) @@ -15626,6 +15624,39 @@ var2fpos(varp, lnum) static pos_T pos; pos_T *pp; + /* Argument can be [lnum, col]. */ + if (varp->v_type == VAR_LIST) + { + list_T *l; + listitem_T *li; + int len; + + l = varp->vval.v_list; + if (l == NULL) + return NULL; + + /* Get the line number */ + li = list_find(l, 0L); + if (li == NULL) + return NULL; + pos.lnum = get_tv_number(&li->li_tv); + if (pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) + return NULL; /* invalid line number */ + + /* Get the column number */ + li = list_find(l, 1L); + if (li == NULL) + return NULL; + pos.col = get_tv_number(&li->li_tv); + len = (long)STRLEN(ml_get(pos.lnum)); + if (pos.col <= 0 || ((len == 0 && pos.col > 1) + || (len > 0 && pos.col > len))) + return NULL; /* invalid column number */ + + pos.col--; + return &pos; + } + name = get_tv_string_chk(varp); if (name == NULL) return NULL; diff --git a/src/ex_cmds.h b/src/ex_cmds.h index 71a0e2afb..393f71494 100644 --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -881,22 +881,30 @@ EX(CMD_tab, "tab", ex_wrongmodifier, NEEDARG|EXTRA|NOTRLCOM), EX(CMD_tabclose, "tabclose", ex_tabclose, RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN), +EX(CMD_tabdo, "tabdo", ex_listdo, + NEEDARG|EXTRA|NOTRLCOM), EX(CMD_tabedit, "tabedit", ex_splitview, BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR), EX(CMD_tabfind, "tabfind", ex_splitview, BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|NEEDARG|TRLBAR), +EX(CMD_tabfirst, "tabfirst", ex_tabnext, + TRLBAR), EX(CMD_tabmove, "tabmove", ex_tabmove, RANGE|NOTADR|COUNT|TRLBAR|ZEROR), +EX(CMD_tablast, "tablast", ex_tabnext, + TRLBAR), EX(CMD_tabnext, "tabnext", ex_tabnext, RANGE|NOTADR|COUNT|TRLBAR), EX(CMD_tabnew, "tabnew", ex_splitview, BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR), EX(CMD_tabonly, "tabonly", ex_tabonly, TRLBAR|CMDWIN), -EX(CMD_tabprevious, "tabprevious", ex_tabprevious, +EX(CMD_tabprevious, "tabprevious", ex_tabnext, RANGE|NOTADR|COUNT|TRLBAR), -EX(CMD_tabNext, "tabNext", ex_tabprevious, +EX(CMD_tabNext, "tabNext", ex_tabnext, RANGE|NOTADR|COUNT|TRLBAR), +EX(CMD_tabrewind, "tabrewind", ex_tabnext, + TRLBAR), EX(CMD_tabs, "tabs", ex_tabs, TRLBAR|CMDWIN), EX(CMD_tcl, "tcl", ex_tcl, diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index 416fd3e35..0d7188ac1 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -2155,7 +2155,7 @@ ex_argdelete(eap) } /* - * ":argdo", ":windo", ":bufdo" + * ":argdo", ":windo", ":bufdo", ":tabdo" */ void ex_listdo(eap) @@ -2163,7 +2163,8 @@ ex_listdo(eap) { int i; #ifdef FEAT_WINDOWS - win_T *win; + win_T *wp; + tabpage_T *tp; #endif buf_T *buf; int next_fnum = 0; @@ -2188,13 +2189,15 @@ ex_listdo(eap) #endif if (eap->cmdidx == CMD_windo + || eap->cmdidx == CMD_tabdo || P_HID(curbuf) || !check_changed(curbuf, TRUE, FALSE, eap->forceit, FALSE)) { /* start at the first argument/window/buffer */ i = 0; #ifdef FEAT_WINDOWS - win = firstwin; + wp = firstwin; + tp = first_tabpage; #endif /* set pcmark now */ if (eap->cmdidx == CMD_bufdo) @@ -2229,11 +2232,19 @@ ex_listdo(eap) #ifdef FEAT_WINDOWS else if (eap->cmdidx == CMD_windo) { - /* go to window "win" */ - if (!win_valid(win)) + /* go to window "wp" */ + if (!win_valid(wp)) + break; + win_goto(wp); + wp = curwin->w_next; + } + else if (eap->cmdidx == CMD_tabdo) + { + /* go to window "tp" */ + if (!valid_tabpage(tp)) break; - win_goto(win); - win = curwin->w_next; + goto_tabpage_tp(tp); + tp = tp->tp_next; } #endif else if (eap->cmdidx == CMD_bufdo) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index df6273ffc..74998d93b 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -156,7 +156,6 @@ static void ex_stag __ARGS((exarg_T *eap)); static void ex_tabclose __ARGS((exarg_T *eap)); static void ex_tabonly __ARGS((exarg_T *eap)); static void ex_tabnext __ARGS((exarg_T *eap)); -static void ex_tabprevious __ARGS((exarg_T *eap)); static void ex_tabmove __ARGS((exarg_T *eap)); static void ex_tabs __ARGS((exarg_T *eap)); #else @@ -167,7 +166,6 @@ static void ex_tabs __ARGS((exarg_T *eap)); # define ex_splitview ex_ni # define ex_stag ex_ni # define ex_tabnext ex_ni -# define ex_tabprevious ex_ni # define ex_tabmove ex_ni # define ex_tabs ex_ni # define ex_tabclose ex_ni @@ -1865,17 +1863,10 @@ do_one_cmd(cmdlinep, sourcing, case 't': if (checkforcmd(&p, "tab", 3)) { #ifdef FEAT_WINDOWS - tabpage_T *tp; - if (vim_isdigit(*ea.cmd)) cmdmod.tab = atoi((char *)ea.cmd) + 1; else - { - cmdmod.tab = 2; - for (tp = first_tabpage; tp != curtab; - tp = tp->tp_next) - ++cmdmod.tab; - } + cmdmod.tab = tabpage_index(curtab) + 1; ea.cmd = p; #endif continue; @@ -6242,7 +6233,7 @@ ex_tabclose(eap) exarg_T *eap; { tabpage_T *tp; - int h = tabpageline_height(); + int h = tabline_height(); # ifdef FEAT_CMDWIN if (cmdwin_type != 0) @@ -6271,7 +6262,7 @@ ex_tabclose(eap) tabpage_close(eap->forceit); } - if (h != tabpageline_height()) + if (h != tabline_height()) shell_new_rows(); } @@ -6284,7 +6275,7 @@ ex_tabonly(eap) { tabpage_T *tp; int done; - int h = tabpageline_height(); + int h = tabline_height(); # ifdef FEAT_CMDWIN if (cmdwin_type != 0) @@ -6314,7 +6305,7 @@ ex_tabonly(eap) } } - if (h != tabpageline_height()) + if (h != tabline_height()) shell_new_rows(); } @@ -7042,17 +7033,23 @@ tabpage_new() ex_tabnext(eap) exarg_T *eap; { - goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2); -} - -/* - * :tabprevious and :tabNext command - */ - static void -ex_tabprevious(eap) - exarg_T *eap; -{ - goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2); + switch (eap->cmdidx) + { + case CMD_tabfirst: + case CMD_tabrewind: + goto_tabpage(1); + break; + case CMD_tablast: + goto_tabpage(9999); + break; + case CMD_tabprevious: + case CMD_tabNext: + goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2); + break; + default: /* CMD_tabnext */ + goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2); + break; + } } /* diff --git a/src/feature.h b/src/feature.h index efe791567..e2d90132f 100644 --- a/src/feature.h +++ b/src/feature.h @@ -730,6 +730,13 @@ #endif /* + * GUI tabline + */ +#if defined(FEAT_GUI_GTK) && defined(HAVE_GTK2) && defined(FEAT_WINDOWS) +# define FEAT_GUI_TABLINE +#endif + +/* * +browse ":browse" command. */ #if defined(FEAT_NORMAL) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)) diff --git a/src/globals.h b/src/globals.h index d46b10c3c..1263e8183 100644 --- a/src/globals.h +++ b/src/globals.h @@ -435,6 +435,10 @@ EXTERN vimmenu_T *current_menu; /* Set to TRUE after adding/removing menus to ensure they are updated */ EXTERN int force_menu_update INIT(= FALSE); # endif +# ifdef FEAT_GUI_TABLINE +/* Tab in tab pages line just selected, set by check_termcode() */ +EXTERN int current_tab; +# endif /* Scrollbar moved and new value, set by check_termcode() */ EXTERN int current_scrollbar; @@ -26,6 +26,9 @@ static int gui_screenstr __ARGS((int off, int len, int flags, guicolor_T fg, gui static void gui_delete_lines __ARGS((int row, int count)); static void gui_insert_lines __ARGS((int row, int count)); static void fill_mouse_coord __ARGS((char_u *p, int col, int row)); +#if defined(FEAT_GUI_TABLINE) || defined(PROTO) +static int gui_has_tabline __ARGS((void)); +#endif static void gui_do_scrollbar __ARGS((win_T *wp, int which, int enable)); static colnr_T scroll_line_len __ARGS((linenr_T lnum)); static void gui_update_horiz_scrollbar __ARGS((int)); @@ -1410,7 +1413,7 @@ gui_set_shellsize(mustset, fit_to_display) min_width = base_width + MIN_COLUMNS * gui.char_width; min_height = base_height + MIN_LINES * gui.char_height; # ifdef FEAT_WINDOWS - min_height += tabpageline_height() * gui.char_height; + min_height += tabline_height() * gui.char_height; # endif gui_mch_set_shellsize(width, height, min_width, min_height, @@ -3081,7 +3084,7 @@ static int prev_which_scrollbars[3] = {-1, -1, -1}; /* * Set which components are present. - * If "oldval" is not NULL, "oldval" is the previous value, the new * value is + * If "oldval" is not NULL, "oldval" is the previous value, the new value is * in p_go. */ /*ARGSUSED*/ @@ -3096,6 +3099,10 @@ gui_init_which_components(oldval) static int prev_toolbar = -1; int using_toolbar = FALSE; #endif +#ifdef FEAT_GUI_TABLINE + static int prev_has_tabline = FALSE; + int using_tabline; +#endif #ifdef FEAT_FOOTER static int prev_footer = -1; int using_footer = FALSE; @@ -3185,10 +3192,27 @@ gui_init_which_components(oldval) /* Ignore options that are not supported */ break; } + if (gui.in_use) { need_set_size = FALSE; fix_size = FALSE; + +#ifdef FEAT_GUI_TABLINE + /* Update the tab line, it may appear or disappear. */ + using_tabline = gui_has_tabline(); + if (prev_has_tabline != using_tabline) + { + prev_has_tabline = using_tabline; + gui_update_tabline(); + need_set_size = TRUE; + if (using_tabline) + fix_size = TRUE; + if (!gui_use_tabline()) + redraw_tabline = TRUE; /* may draw non-GUI tab line */ + } +#endif + for (i = 0; i < 3; i++) { if (gui.which_scrollbars[i] != prev_which_scrollbars[i]) @@ -3281,6 +3305,82 @@ gui_init_which_components(oldval) } } +#if defined(FEAT_GUI_TABLINE) || defined(PROTO) +/* + * Return TRUE if the GUI is taking care of the tabline. + * It may still be hidden if 'showtabline' is zero. + */ + int +gui_use_tabline() +{ + return gui.in_use && vim_strchr(p_go, GO_TABLINE) != NULL; +} + +/* + * Return TRUE if the GUI is showing the tabline. + * This uses 'showtabline'. + */ + static int +gui_has_tabline() +{ + if (!gui_use_tabline() + || p_stal == 0 + || (p_stal == 1 && first_tabpage->tp_next == NULL)) + return FALSE; + return TRUE; +} + +/* + * Update the tabline. + * This may display/undisplay the tabline and update the labels. + */ + void +gui_update_tabline() +{ + int showit = gui_has_tabline(); + + if (!gui.starting && starting == 0) + { + gui_mch_show_tabline(showit); + if (showit != 0) + gui_mch_update_tabline(); + } +} + +/* + * Get the label for tab page "tp" into NameBuff[]. + */ + void +get_tabline_label(tp) + tabpage_T *tp; +{ + int modified = FALSE; + char_u buf[40]; + int wincount; + win_T *wp; + + /* Get the buffer name into NameBuff[] */ + get_trans_bufname(tp == curtab ? curbuf : tp->tp_curwin->w_buffer); + + wp = (tp == curtab) ? firstwin : tp->tp_firstwin; + for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount) + if (bufIsChanged(wp->w_buffer)) + modified = TRUE; + if (modified || wincount > 1) + { + if (wincount > 1) + vim_snprintf((char *)buf, sizeof(buf), "%d", wincount); + else + buf[0] = NUL; + if (modified) + STRCAT(buf, "+"); + STRCAT(buf, " "); + mch_memmove(NameBuff + STRLEN(buf), NameBuff, STRLEN(NameBuff) + 1); + mch_memmove(NameBuff, buf, STRLEN(buf)); + } +} + +#endif /* * Scrollbar stuff: @@ -393,6 +393,7 @@ typedef struct Gui PangoContext *text_context; /* the context used for all text */ PangoFont *ascii_font; /* cached font for ASCII strings */ PangoGlyphString *ascii_glyphs; /* cached code point -> glyph map */ + GtkWidget *tabline; /* tab pages line handle */ # endif GtkAccelGroup *accel_group; diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index c608f9d4a..4cae9a173 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -2827,6 +2827,145 @@ delete_event_cb(GtkWidget *widget, GdkEventAny *event, gpointer data) return TRUE; } +#if defined(FEAT_MENU) || defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE) + static int +get_item_dimensions(GtkWidget *widget, GtkOrientation orientation) +{ + GtkOrientation item_orientation = GTK_ORIENTATION_HORIZONTAL; + +#ifdef FEAT_GUI_GNOME + if (using_gnome && widget != NULL) + { +# ifdef HAVE_GTK2 + BonoboDockItem *dockitem; + + widget = gtk_widget_get_parent(widget); + dockitem = BONOBO_DOCK_ITEM(widget); + + if (dockitem == NULL || dockitem->is_floating) + return 0; + item_orientation = bonobo_dock_item_get_orientation(dockitem); +# else + GnomeDockItem *dockitem; + + widget = widget->parent; + dockitem = GNOME_DOCK_ITEM(widget); + + if (dockitem == NULL || dockitem->is_floating) + return 0; + item_orientation = gnome_dock_item_get_orientation(dockitem); +# endif + } +#endif + if (widget != NULL + && item_orientation == orientation + && GTK_WIDGET_REALIZED(widget) + && GTK_WIDGET_VISIBLE(widget)) + { + if (orientation == GTK_ORIENTATION_HORIZONTAL) + return widget->allocation.height; + else + return widget->allocation.width; + } + return 0; +} +#endif + + static int +get_menu_tool_width(void) +{ + int width = 0; + +#ifdef FEAT_GUI_GNOME /* these are never vertical without GNOME */ +# ifdef FEAT_MENU + width += get_item_dimensions(gui.menubar, GTK_ORIENTATION_VERTICAL); +# endif +# ifdef FEAT_TOOLBAR + width += get_item_dimensions(gui.toolbar, GTK_ORIENTATION_VERTICAL); +# endif +# ifdef FEAT_GUI_TABLINE + width += get_item_dimensions(gui.tabline, GTK_ORIENTATION_VERTICAL); +# endif +#endif + + return width; +} + + static int +get_menu_tool_height(void) +{ + int height = 0; + +#ifdef FEAT_MENU + height += get_item_dimensions(gui.menubar, GTK_ORIENTATION_HORIZONTAL); +#endif +#ifdef FEAT_TOOLBAR + height += get_item_dimensions(gui.toolbar, GTK_ORIENTATION_HORIZONTAL); +#endif +#ifdef FEAT_GUI_TABLINE + height += get_item_dimensions(gui.tabline, GTK_ORIENTATION_HORIZONTAL); +#endif + + return height; +} + + static void +update_window_manager_hints(void) +{ + static int old_width = 0; + static int old_height = 0; + static int old_char_width = 0; + static int old_char_height = 0; + + int width; + int height; + + /* This also needs to be done when the main window isn't there yet, + * otherwise the hints don't work. */ + width = gui_get_base_width(); + height = gui_get_base_height(); +# ifdef FEAT_MENU + height += tabline_height() * gui.char_height; +# endif +# ifdef HAVE_GTK2 + width += get_menu_tool_width(); + height += get_menu_tool_height(); +# endif + + /* Avoid an expose event when the size didn't change. */ + if (width != old_width + || height != old_height + || gui.char_width != old_char_width + || gui.char_height != old_char_height) + { + GdkGeometry geometry; + GdkWindowHints geometry_mask; + + geometry.width_inc = gui.char_width; + geometry.height_inc = gui.char_height; + geometry.base_width = width; + geometry.base_height = height; + geometry.min_width = width + MIN_COLUMNS * gui.char_width; + geometry.min_height = height + MIN_LINES * gui.char_height; + geometry_mask = GDK_HINT_BASE_SIZE|GDK_HINT_RESIZE_INC + |GDK_HINT_MIN_SIZE; +# ifdef HAVE_GTK2 + /* Using gui.formwin as geometry widget doesn't work as expected + * with GTK+ 2 -- dunno why. Presumably all the resizing hacks + * in Vim confuse GTK+. */ + gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.mainwin, + &geometry, geometry_mask); +# else + gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.formwin, + &geometry, geometry_mask); +# endif + old_width = width; + old_height = height; + old_char_width = gui.char_width; + old_char_height = gui.char_height; + } +} + #ifdef FEAT_TOOLBAR # ifdef HAVE_GTK2 @@ -2920,6 +3059,122 @@ set_toolbar_style(GtkToolbar *toolbar) #endif /* FEAT_TOOLBAR */ +#if defined(FEAT_GUI_TABLINE) || defined(PROTO) +static int ignore_tabline_evt = FALSE; + +/* + * Handle selecting one of the tabs. + */ +/*ARGSUSED*/ + static void +on_select_tab( + GtkNotebook *notebook, + GtkNotebookPage *page, + gint index, + gpointer data) +{ + static char_u string[3]; + + if (!ignore_tabline_evt) + { + string[0] = CSI; + string[1] = KS_TABLINE; + string[2] = KE_FILLER; + add_to_input_buf(string, 3); + string[0] = index + 1; + add_to_input_buf_csi(string, 1); + + if (gtk_main_level() > 0) + gtk_main_quit(); + } +} + +/* + * Show or hide the tabline. + */ + void +gui_mch_show_tabline(int showit) +{ + if (gui.tabline == NULL) + return; + + if (!showit != !gtk_notebook_get_show_tabs(GTK_NOTEBOOK(gui.tabline))) + { + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), showit); + update_window_manager_hints(); + } +} + +/* + * Update the labels of the tabline. + */ + void +gui_mch_update_tabline(void) +{ + GtkWidget *page; + GtkWidget *label; + tabpage_T *tp; + int nr = 0; + int curtabidx = 0; + + if (gui.tabline == NULL) + return; + + ignore_tabline_evt = TRUE; + + /* Add a label for each tab page. They all contain the same text area. */ + for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr) + { + if (tp == curtab) + curtabidx = nr; + + page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr); + if (page == NULL) + { + /* Add notebook page */ + page = gtk_vbox_new(FALSE, 0); + gtk_widget_show(page); + label = gtk_label_new("-Empty-"); + gtk_widget_show(label); + gtk_notebook_insert_page(GTK_NOTEBOOK(gui.tabline), + page, + label, + nr++); + } + + get_tabline_label(tp); + gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(gui.tabline), page, + (const gchar *)NameBuff); + } + + /* Remove any old labels. */ + while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr) != NULL) + gtk_notebook_remove_page(GTK_NOTEBOOK(gui.tabline), nr); + + if (gtk_notebook_current_page(GTK_NOTEBOOK(gui.tabline)) != curtabidx) + gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline), curtabidx); + + ignore_tabline_evt = FALSE; +} + +/* + * Set the current tab to "nr". First tab is 1. + */ + void +gui_mch_set_curtab(nr) + int nr; +{ + if (gui.tabline == NULL) + return; + + ignore_tabline_evt = TRUE; + if (gtk_notebook_current_page(GTK_NOTEBOOK(gui.tabline)) != nr - 1) + gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline), nr - 1); + ignore_tabline_evt = FALSE; +} + +#endif /* FEAT_GUI_TABLINE */ + /* * Initialize the GUI. Create all the windows, set up all the callbacks etc. * Returns OK for success, FAIL when the GUI can't be started. @@ -3060,6 +3315,7 @@ gui_mch_init(void) gui.accel_group = gtk_accel_group_get_default(); #endif + /* A vertical box holds the menubar, toolbar and main text window. */ vbox = gtk_vbox_new(FALSE, 0); #ifdef FEAT_GUI_GNOME @@ -3194,6 +3450,30 @@ gui_mch_init(void) } #endif /* FEAT_TOOLBAR */ +#ifdef FEAT_GUI_TABLINE + /* Use a Notebook for the tab pages labels. The labels are hidden by + * default. */ + gui.tabline = gtk_notebook_new(); + gtk_widget_show(gui.tabline); + gtk_box_pack_start(GTK_BOX(vbox), gui.tabline, FALSE, FALSE, 0); + gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE); + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), FALSE); + + { + GtkWidget *page, *label; + + /* Add the first tab. */ + page = gtk_vbox_new(FALSE, 0); + gtk_widget_show(page); + gtk_container_add(GTK_CONTAINER(gui.tabline), page); + label = gtk_label_new("-Empty-"); + gtk_widget_show(label); + gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, label); + } + gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page", + GTK_SIGNAL_FUNC(on_select_tab), NULL); +#endif + gui.formwin = gtk_form_new(); gtk_container_border_width(GTK_CONTAINER(gui.formwin), 0); gtk_widget_set_events(gui.formwin, GDK_EXPOSURE_MASK); @@ -3365,139 +3645,6 @@ gui_mch_new_colors(void) } } -#if defined(FEAT_MENU) || defined(FEAT_TOOLBAR) - static int -get_item_dimensions(GtkWidget *widget, GtkOrientation orientation) -{ - GtkOrientation item_orientation = GTK_ORIENTATION_HORIZONTAL; - -#ifdef FEAT_GUI_GNOME - if (using_gnome && widget != NULL) - { -# ifdef HAVE_GTK2 - BonoboDockItem *dockitem; - - widget = gtk_widget_get_parent(widget); - dockitem = BONOBO_DOCK_ITEM(widget); - - if (dockitem == NULL || dockitem->is_floating) - return 0; - item_orientation = bonobo_dock_item_get_orientation(dockitem); -# else - GnomeDockItem *dockitem; - - widget = widget->parent; - dockitem = GNOME_DOCK_ITEM(widget); - - if (dockitem == NULL || dockitem->is_floating) - return 0; - item_orientation = gnome_dock_item_get_orientation(dockitem); -# endif - } -#endif - if (widget != NULL - && item_orientation == orientation - && GTK_WIDGET_REALIZED(widget) - && GTK_WIDGET_VISIBLE(widget)) - { - if (orientation == GTK_ORIENTATION_HORIZONTAL) - return widget->allocation.height; - else - return widget->allocation.width; - } - return 0; -} -#endif - - static int -get_menu_tool_width(void) -{ - int width = 0; - -#ifdef FEAT_GUI_GNOME /* these are never vertical without GNOME */ -# ifdef FEAT_MENU - width += get_item_dimensions(gui.menubar, GTK_ORIENTATION_VERTICAL); -# endif -# ifdef FEAT_TOOLBAR - width += get_item_dimensions(gui.toolbar, GTK_ORIENTATION_VERTICAL); -# endif -#endif - - return width; -} - - static int -get_menu_tool_height(void) -{ - int height = 0; - -#ifdef FEAT_MENU - height += get_item_dimensions(gui.menubar, GTK_ORIENTATION_HORIZONTAL); -#endif -#ifdef FEAT_TOOLBAR - height += get_item_dimensions(gui.toolbar, GTK_ORIENTATION_HORIZONTAL); -#endif - - return height; -} - - static void -update_window_manager_hints(void) -{ - static int old_width = 0; - static int old_height = 0; - static int old_char_width = 0; - static int old_char_height = 0; - - int width; - int height; - - /* This also needs to be done when the main window isn't there yet, - * otherwise the hints don't work. */ - width = gui_get_base_width(); - height = gui_get_base_height(); -# ifdef FEAT_MENU - height += tabpageline_height() * gui.char_height; -# endif -# ifdef HAVE_GTK2 - width += get_menu_tool_width(); - height += get_menu_tool_height(); -# endif - - /* Avoid an expose event when the size didn't change. */ - if (width != old_width - || height != old_height - || gui.char_width != old_char_width - || gui.char_height != old_char_height) - { - GdkGeometry geometry; - GdkWindowHints geometry_mask; - - geometry.width_inc = gui.char_width; - geometry.height_inc = gui.char_height; - geometry.base_width = width; - geometry.base_height = height; - geometry.min_width = width + MIN_COLUMNS * gui.char_width; - geometry.min_height = height + MIN_LINES * gui.char_height; - geometry_mask = GDK_HINT_BASE_SIZE|GDK_HINT_RESIZE_INC - |GDK_HINT_MIN_SIZE; -# ifdef HAVE_GTK2 - /* Using gui.formwin as geometry widget doesn't work as expected - * with GTK+ 2 -- dunno why. Presumably all the resizing hacks - * in Vim confuse GTK+. */ - gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.mainwin, - &geometry, geometry_mask); -# else - gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.formwin, - &geometry, geometry_mask); -# endif - old_width = width; - old_height = height; - old_char_width = gui.char_width; - old_char_height = gui.char_height; - } -} - /* * This signal informs us about the need to rearrange our sub-widgets. */ diff --git a/src/keymap.h b/src/keymap.h index 0aa447498..3ffea9319 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -101,6 +101,9 @@ /* Used for the qnx pterm mouse */ #define KS_PTERM_MOUSE 241 +/* Used for click in a tab pages label. */ +#define KS_TABLINE 240 + /* * Filler used after KS_SPECIAL and others */ @@ -399,6 +402,8 @@ enum key_extra #define K_SELECT TERMCAP2KEY(KS_SELECT, KE_FILLER) #define K_TEAROFF TERMCAP2KEY(KS_TEAROFF, KE_FILLER) +#define K_TABLINE TERMCAP2KEY(KS_TABLINE, KE_FILLER) + /* * Symbols for pseudo keys which are translated from the real key symbols * above. diff --git a/src/main.c b/src/main.c index 705acf5ef..413ca1f5c 100644 --- a/src/main.c +++ b/src/main.c @@ -880,6 +880,18 @@ main mch_set_winsize_now(); /* Allow winsize changes from now on */ #endif +#if defined(FEAT_GUI) && defined(FEAT_WINDOWS) + /* When tab pages were created, may need to update the tab pages line and + * scrollbars. This is skipped while creating them. */ + if (first_tabpage->tp_next != NULL) + { + out_flush(); + gui_init_which_components(NULL); + gui_update_scrollbars(TRUE); + } + need_mouse_correct = TRUE; +#endif + /* If ":startinsert" command used, stuff a dummy command to be able to * call normal_cmd(), which will then start Insert mode. */ if (restart_edit != 0) diff --git a/src/normal.c b/src/normal.c index 4f4ffa954..cc9d0d165 100644 --- a/src/normal.c +++ b/src/normal.c @@ -74,6 +74,9 @@ static void nv_zet __ARGS((cmdarg_T *cap)); static void nv_ver_scrollbar __ARGS((cmdarg_T *cap)); static void nv_hor_scrollbar __ARGS((cmdarg_T *cap)); #endif +#ifdef FEAT_GUI_TABLINE +static void nv_tabline __ARGS((cmdarg_T *cap)); +#endif static void nv_exmode __ARGS((cmdarg_T *cap)); static void nv_colon __ARGS((cmdarg_T *cap)); static void nv_ctrlg __ARGS((cmdarg_T *cap)); @@ -418,6 +421,9 @@ static const struct nv_cmd {K_VER_SCROLLBAR, nv_ver_scrollbar, 0, 0}, {K_HOR_SCROLLBAR, nv_hor_scrollbar, 0, 0}, #endif +#ifdef FEAT_GUI_TABLINE + {K_TABLINE, nv_tabline, 0, 0}, +#endif #ifdef FEAT_FKMAP {K_F8, farsi_fkey, 0, 0}, {K_F9, farsi_fkey, 0, 0}, @@ -4977,6 +4983,22 @@ nv_hor_scrollbar(cap) } #endif +#ifdef FEAT_GUI_TABLINE +/* + * Click in GUI tab. + */ + static void +nv_tabline(cap) + cmdarg_T *cap; +{ + if (cap->oap->op_type != OP_NOP) + clearopbeep(cap->oap); + + /* Even if an operator was pending, we still want to jump tabs. */ + goto_tabpage(current_tab); +} +#endif + /* * "Q" command. */ @@ -5329,7 +5351,7 @@ nv_ident(cap) else if (g_cmd) STRCPY(buf, "tj "); else - STRCPY(buf, "ta "); + sprintf((char *)buf, "%ldta ", cap->count0); } /* diff --git a/src/option.c b/src/option.c index 192500010..d32cf5e9d 100644 --- a/src/option.c +++ b/src/option.c @@ -1099,9 +1099,9 @@ static struct vimoption #if defined(FEAT_GUI) (char_u *)&p_go, PV_NONE, # if defined(UNIX) && !defined(MACOS) - {(char_u *)"agimrLtT", (char_u *)0L} + {(char_u *)"aegimrLtT", (char_u *)0L} # else - {(char_u *)"gmrLtT", (char_u *)0L} + {(char_u *)"egmrLtT", (char_u *)0L} # endif #else (char_u *)NULL, PV_NONE, diff --git a/src/option.h b/src/option.h index ebf154b5a..54ae88949 100644 --- a/src/option.h +++ b/src/option.h @@ -223,6 +223,7 @@ #define GO_ASELML 'A' /* autoselect modeless selection */ #define GO_BOT 'b' /* use bottom scrollbar */ #define GO_CONDIALOG 'c' /* use console dialog */ +#define GO_TABLINE 'e' /* may show tabline */ #define GO_FORG 'f' /* start GUI in foreground */ #define GO_GREY 'g' /* use grey menu items */ #define GO_HORSCROLL 'h' /* flexible horizontal scrolling */ @@ -238,7 +239,7 @@ #define GO_TOOLBAR 'T' /* add toolbar */ #define GO_FOOTER 'F' /* add footer */ #define GO_VERTICAL 'v' /* arrange dialog buttons vertically */ -#define GO_ALL "aAbcfFghilmMprtTv" /* all possible flags for 'go' */ +#define GO_ALL "aAbcefFghilmMprtTv" /* all possible flags for 'go' */ /* flags for 'comments' option */ #define COM_NEST 'n' /* comments strings nest */ diff --git a/src/proto/gui.pro b/src/proto/gui.pro index eacc2ac82..93c4f5cc3 100644 --- a/src/proto/gui.pro +++ b/src/proto/gui.pro @@ -34,6 +34,9 @@ void gui_send_mouse_event __ARGS((int button, int x, int y, int repeated_click, int gui_xy2colrow __ARGS((int x, int y, int *colp)); void gui_menu_cb __ARGS((vimmenu_T *menu)); void gui_init_which_components __ARGS((char_u *oldval)); +int gui_use_tabline __ARGS((void)); +void gui_update_tabline __ARGS((void)); +void get_tabline_label __ARGS((tabpage_T *tp)); void gui_remove_scrollbars __ARGS((void)); void gui_create_scrollbar __ARGS((scrollbar_T *sb, int type, win_T *wp)); scrollbar_T *gui_find_scrollbar __ARGS((long ident)); diff --git a/src/proto/gui_gtk_x11.pro b/src/proto/gui_gtk_x11.pro index a97a1ac85..30bde6a13 100644 --- a/src/proto/gui_gtk_x11.pro +++ b/src/proto/gui_gtk_x11.pro @@ -5,6 +5,9 @@ void gui_mch_set_blinking __ARGS((long waittime, long on, long off)); void gui_mch_stop_blink __ARGS((void)); void gui_mch_start_blink __ARGS((void)); int gui_mch_init_check __ARGS((void)); +void gui_mch_show_tabline __ARGS((int showit)); +void gui_mch_update_tabline __ARGS((void)); +void gui_mch_set_curtab __ARGS((int nr)); int gui_mch_init __ARGS((void)); void gui_mch_forked __ARGS((void)); void gui_mch_new_colors __ARGS((void)); diff --git a/src/proto/screen.pro b/src/proto/screen.pro index c2ce8d74c..c534a1f9e 100644 --- a/src/proto/screen.pro +++ b/src/proto/screen.pro @@ -42,6 +42,7 @@ int screen_ins_lines __ARGS((int off, int row, int line_count, int end, win_T *w int screen_del_lines __ARGS((int off, int row, int line_count, int end, int force, win_T *wp)); int showmode __ARGS((void)); void unshowmode __ARGS((int force)); +void get_trans_bufname __ARGS((buf_T *buf)); int redrawing __ARGS((void)); int messaging __ARGS((void)); void showruler __ARGS((int always)); diff --git a/src/proto/window.pro b/src/proto/window.pro index 1c56ab1c1..629ced385 100644 --- a/src/proto/window.pro +++ b/src/proto/window.pro @@ -19,7 +19,9 @@ int may_open_tabpage __ARGS((void)); int make_tabpages __ARGS((int maxcount)); int valid_tabpage __ARGS((tabpage_T *tpc)); tabpage_T *find_tabpage __ARGS((int n)); +int tabpage_index __ARGS((tabpage_T *ftp)); void goto_tabpage __ARGS((int n)); +void goto_tabpage_tp __ARGS((tabpage_T *tp)); void tabpage_move __ARGS((int nr)); void win_goto __ARGS((win_T *wp)); win_T *win_find_nr __ARGS((int winnr)); @@ -42,7 +44,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)); +int tabline_height __ARGS((void)); char_u *grab_file_name __ARGS((long count, linenr_T *file_lnum)); char_u *file_name_at_cursor __ARGS((int options, long count, linenr_T *file_lnum)); char_u *file_name_in_line __ARGS((char_u *line, int col, int options, long count, char_u *rel_fname, linenr_T *file_lnum)); diff --git a/src/regexp.c b/src/regexp.c index 69acb6987..48bad944f 100644 --- a/src/regexp.c +++ b/src/regexp.c @@ -3861,8 +3861,16 @@ regmatch(scan) } else { - top = curbuf->b_visual_start; - bot = curbuf->b_visual_end; + if (lt(curbuf->b_visual_start, curbuf->b_visual_end)) + { + top = curbuf->b_visual_start; + bot = curbuf->b_visual_end; + } + else + { + top = curbuf->b_visual_end; + bot = curbuf->b_visual_start; + } mode = curbuf->b_visual_mode; } lnum = reglnum + reg_firstlnum; @@ -5092,8 +5100,8 @@ regmatch(scan) /* Tried first position already, advance. */ if (rp->rs_state == RS_STAR_LONG) { - /* Trying for longest matc, but couldn't or didn't - * match -- back up one char. */ + /* Trying for longest match, but couldn't or + * didn't match -- back up one char. */ if (--rst->count < rst->minval) break; if (reginput == regline) @@ -5149,8 +5157,8 @@ regmatch(scan) break; } - /* If we want to continue the inner loop or didn't pop a state contine - * matching loop */ + /* If we want to continue the inner loop or didn't pop a state + * continue matching loop */ if (status == RA_CONT || rp == (regitem_T *) ((char *)regstack.ga_data + regstack.ga_len) - 1) break; diff --git a/src/screen.c b/src/screen.c index 07cf99145..692318c29 100644 --- a/src/screen.c +++ b/src/screen.c @@ -5344,12 +5344,7 @@ win_redr_status(wp) { fillchar = fillchar_status(&attr, wp == 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); + get_trans_bufname(wp->w_buffer); p = NameBuff; len = (int)STRLEN(p); @@ -6170,14 +6165,24 @@ next_search_hl(win, shl, lnum, mincol) matchcol = 0; else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL || (shl->rm.endpos[0].lnum == 0 - && shl->rm.endpos[0].col == shl->rm.startpos[0].col)) + && shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) { - matchcol = shl->rm.startpos[0].col + 1; - if (ml_get_buf(shl->buf, lnum, FALSE)[matchcol - 1] == NUL) + char_u *ml = ml_get_buf(shl->buf, lnum, FALSE); + + matchcol = shl->rm.startpos[0].col; + ml += matchcol; + if (*ml == NUL) { + ++matchcol; shl->lnum = 0; break; } +#ifdef FEAT_MBYTE + if (has_mbyte) + matchcol += mb_ptr2len(ml); + else +#endif + ++matchcol; } else matchcol = shl->rm.endpos[0].col; @@ -8577,7 +8582,16 @@ draw_tabline() redraw_tabline = FALSE; - if (tabpageline_height() < 1) +#ifdef FEAT_GUI_TABLINE + /* When the GUI has the tabline then this always returns zero. */ + if (gui_use_tabline()) + { + gui_update_tabline(); + return; + } +#endif + + if (tabline_height() < 1) return; #if defined(FEAT_STL_OPT) @@ -8670,12 +8684,8 @@ draw_tabline() room = scol - col + tabwidth - 1; if (room > 0) { - if (buf_spname(cwp->w_buffer) != NULL) - STRCPY(NameBuff, buf_spname(cwp->w_buffer)); - else - home_replace(cwp->w_buffer, cwp->w_buffer->b_fname, NameBuff, - MAXPATHL, TRUE); - trans_characters(NameBuff, MAXPATHL); + /* Get buffer name in NameBuff[] */ + get_trans_bufname(cwp->w_buffer); len = vim_strsize(NameBuff); p = NameBuff; #ifdef FEAT_MBYTE @@ -8719,6 +8729,21 @@ draw_tabline() } } } + +/* + * Get buffer name for "buf" into NameBuff[]. + * Takes care of special buffer names and translates special characters. + */ + void +get_trans_bufname(buf) + buf_T *buf; +{ + if (buf_spname(buf) != NULL) + STRCPY(NameBuff, buf_spname(buf)); + else + home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE); + trans_characters(NameBuff, MAXPATHL); +} #endif #if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT) diff --git a/src/search.c b/src/search.c index c0be23ba7..e92985a8c 100644 --- a/src/search.c +++ b/src/search.c @@ -602,7 +602,11 @@ searchit(win, buf, pos, dir, pat, count, options, pat_use) # ifdef FEAT_EVAL submatch = first_submatch(®match); # endif - ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE); + /* Line me be past end of buffer for "\n\zs". */ + if (lnum + matchpos.lnum > buf->b_ml.ml_line_count) + ptr = (char_u *)""; + else + ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE); /* * Forward search in the first line: match should be after @@ -886,6 +890,15 @@ searchit(win, buf, pos, dir, pat, count, options, pat_use) return FAIL; } + /* A pattern like "\n\zs" may go past the last line. */ + if (pos->lnum > buf->b_ml.ml_line_count) + { + pos->lnum = buf->b_ml.ml_line_count; + pos->col = STRLEN(ml_get_buf(buf, pos->lnum, FALSE)); + if (pos->col > 0) + --pos->col; + } + return submatch + 1; } diff --git a/src/structs.h b/src/structs.h index bb02a75ea..adbbdc07e 100644 --- a/src/structs.h +++ b/src/structs.h @@ -782,8 +782,9 @@ typedef struct attr_entry } term; struct { - char_u fg_color; /* foreground color number */ - char_u bg_color; /* background color number */ + /* These colors need to be > 8 bits to hold 256. */ + short_u fg_color; /* foreground color number */ + short_u bg_color; /* background color number */ } cterm; # ifdef FEAT_GUI struct @@ -509,6 +509,13 @@ do_tag(tag, type, count, forceit, verbose) tagmatchname = vim_strsave(name); } + /* + * If a count is supplied to the ":tag <name>" command, then + * jump to count'th matching tag. + */ + if (type == DT_TAG && count > 0) + cur_match = count - 1; + if (type == DT_SELECT || type == DT_JUMP) cur_match = MAXCOL - 1; max_num_matches = cur_match + 1; diff --git a/src/term.c b/src/term.c index 621d35ba2..596de514a 100644 --- a/src/term.c +++ b/src/term.c @@ -4766,6 +4766,9 @@ check_termcode(max_offset, buf, buflen) * four bytes which are to be taken as a pointer to the vimmenu_T * structure. * + * A tab line event is encodded as K_SPECIAL KS_TABLINE nr, where "nr" + * is one byte with the tab index. + * * A scrollbar event is K_SPECIAL, KS_VER_SCROLLBAR, KE_FILLER followed * by one byte representing the scrollbar number, and then four bytes * representing a long_u which is the new value of the scrollbar. @@ -4786,6 +4789,16 @@ check_termcode(max_offset, buf, buflen) slen += num_bytes; } # endif +# ifdef FEAT_GUI_TABLINE + else if (key_name[0] == (int)KS_TABLINE) + { + num_bytes = get_bytes_from_buf(tp + slen, bytes, 1); + if (num_bytes == -1) + return -1; + current_tab = (int)bytes[0]; + slen += num_bytes; + } +# endif # ifndef USE_ON_FLY_SCROLL else if (key_name[0] == (int)KS_VER_SCROLLBAR) { diff --git a/src/version.h b/src/version.h index 9838f1b90..1cffc094a 100644 --- a/src/version.h +++ b/src/version.h @@ -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 23)" -#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 23, compiled " +#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 24)" +#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 24, compiled " diff --git a/src/window.c b/src/window.c index c116dfc84..f0a4265b0 100644 --- a/src/window.c +++ b/src/window.c @@ -86,7 +86,7 @@ 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()) +# define ROWS_AVAIL (Rows - p_ch - tabline_height()) #else # define ROWS_AVAIL (Rows - p_ch) #endif @@ -908,7 +908,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 = tabpageline_height(); + wp->w_winrow = tabline_height(); wp->w_height = curfrp->fr_height - (p_ls > 0); wp->w_status_height = (p_ls > 0); } @@ -1543,7 +1543,7 @@ win_equal(next_curwin, current, dir) dir = 'b'; #endif win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current, - topframe, dir, 0, tabpageline_height(), + topframe, dir, 0, tabline_height(), (int)Columns, topframe->fr_height); } @@ -1830,7 +1830,7 @@ close_windows(buf, keep_curwin) { win_T *wp; tabpage_T *tp, *nexttp; - int h = tabpageline_height(); + int h = tabline_height(); ++RedrawingDisabled; @@ -1866,7 +1866,7 @@ close_windows(buf, keep_curwin) --RedrawingDisabled; - if (h != tabpageline_height()) + if (h != tabline_height()) shell_new_rows(); } @@ -3041,7 +3041,7 @@ win_new_tabpage(after) tp->tp_next = newtp; } win_init_size(); - firstwin->w_winrow = tabpageline_height(); + firstwin->w_winrow = tabline_height(); newtp->tp_topframe = topframe; last_status(FALSE); @@ -3142,6 +3142,22 @@ find_tabpage(n) } /* + * Get index of tab page "tp". First one has index 1. + * When not found returns number of tab pages. + */ + int +tabpage_index(ftp) + tabpage_T *ftp; +{ + int i = 1; + tabpage_T *tp; + + for (tp = first_tabpage; tp != NULL && tp != ftp; tp = tp->tp_next) + ++i; + return i; +} + +/* * Prepare for leaving the current tab page. * When autocomands change "curtab" we don't leave the tab page and return * FAIL. @@ -3223,7 +3239,11 @@ enter_tabpage(tp, old_curbuf) /* The tabpage line may have appeared or disappeared, may need to resize * the frames for that. When the Vim window was resized need to update * frame sizes too. */ - if (curtab->tp_old_Rows != Rows || old_off != firstwin->w_winrow) + if (curtab->tp_old_Rows != Rows || (old_off != firstwin->w_winrow +#ifdef FEAT_GUI_TABLINE + && !gui_use_tabline() +#endif + )) shell_new_rows(); #ifdef FEAT_VERTSPLIT if (curtab->tp_old_Columns != Columns && starting == 0) @@ -3233,12 +3253,8 @@ enter_tabpage(tp, old_curbuf) #if defined(FEAT_GUI) /* When 'guioptions' includes 'L' or 'R' may have to remove or add * scrollbars. Have to update them anyway. */ - if (gui.in_use) - { - out_flush(); - gui_init_which_components(NULL); + if (gui.in_use && starting == 0) gui_update_scrollbars(TRUE); - } need_mouse_correct = TRUE; #endif @@ -3247,6 +3263,7 @@ enter_tabpage(tp, old_curbuf) /* * Go to tab page "n". For ":tab N" and "Ngt". + * When "n" is 9999 go to the last tab page. */ void goto_tabpage(n) @@ -3285,12 +3302,16 @@ goto_tabpage(n) ttp = tp; } } + else if (n == 9999) + { + /* Go to last tab page. */ + for (tp = first_tabpage; tp->tp_next != NULL; tp = tp->tp_next) + ; + } else { /* Go to tab page "n". */ - i = 0; - for (tp = first_tabpage; ++i != n && tp != NULL; tp = tp->tp_next) - ; + tp = find_tabpage(n); if (tp == NULL) { beep_flush(); @@ -3298,6 +3319,22 @@ goto_tabpage(n) } } + goto_tabpage_tp(tp); + +#ifdef FEAT_GUI_TABLINE + if (gui_use_tabline()) + gui_mch_set_curtab(tabpage_index(tp)); +#endif +} + +/* + * Go to tabpage "tp". + * Note: doesn't update the GUI tab. + */ + void +goto_tabpage_tp(tp) + tabpage_T *tp; +{ if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer) == OK) { if (valid_tabpage(tp)) @@ -4071,7 +4108,7 @@ win_size_restore(gap) int win_comp_pos() { - int row = tabpageline_height(); + int row = tabline_height(); int col = 0; frame_comp_pos(topframe, &row, &col); @@ -5169,8 +5206,13 @@ last_status_rec(fr, statusline) * Return the number of lines used by the tab page line. */ int -tabpageline_height() +tabline_height() { +#ifdef FEAT_GUI_TABLINE + /* When the GUI has the tabline then this always returns zero. */ + if (gui_use_tabline()) + return 0; +#endif switch (p_stal) { case 0: return 0; @@ -5516,7 +5558,7 @@ min_rows() if (total < n) total = n; } - total += tabpageline_height(); + total += tabline_height(); #else total = 1; /* at least one window should have a line! */ #endif |