diff --git a/.github/labeler.yml b/.github/labeler.yml index 9abc870b08..6eef8d2cdd 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -55,6 +55,6 @@ runtime: termdebug: runtime/pack/dist/opt/termdebug/plugin/termdebug.vim -netrw: +plugin-netrw: - any: ['runtime/plugin/netrwPlugin.vim'] - any: ['runtime/autoload/netrw*'] diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 3f0f98f5b3..e02b126122 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -6832,55 +6832,55 @@ printf({fmt}, {expr1} ...) *printf()* echo printf("%1$*2$.*3$f", 1.4142135, 6, 2) < 1.41 - *E1400* + *E1500* You cannot mix positional and non-positional arguments: > echo printf("%s%1$s", "One", "Two") -< E1400: Cannot mix positional and non-positional +< E1500: Cannot mix positional and non-positional arguments: %s%1$s - *E1401* + *E1501* You cannot skip a positional argument in a format string: > echo printf("%3$s%1$s", "One", "Two", "Three") -< E1401: format argument 2 unused in $-style +< E1501: format argument 2 unused in $-style format: %3$s%1$s - *E1402* + *E1502* You can re-use a [field-width] (or [precision]) argument: > echo printf("%1$d at width %2$d is: %01$*2$d", 1, 2) < 1 at width 2 is: 01 However, you can't use it as a different type: > echo printf("%1$d at width %2$ld is: %01$*2$d", 1, 2) -< E1402: Positional argument 2 used as field +< E1502: Positional argument 2 used as field width reused as different type: long int/int - *E1403* + *E1503* When a positional argument is used, but not the correct number or arguments is given, an error is raised: > echo printf("%1$d at width %2$d is: %01$*2$.*3$d", 1, 2) -< E1403: Positional argument 3 out of bounds: +< E1503: Positional argument 3 out of bounds: %1$d at width %2$d is: %01$*2$.*3$d Only the first error is reported: > echo printf("%01$*2$.*3$d %4$d", 1, 2) -< E1403: Positional argument 3 out of bounds: +< E1503: Positional argument 3 out of bounds: %01$*2$.*3$d %4$d - *E1404* + *E1504* A positional argument can be used more than once: > echo printf("%1$s %2$s %1$s", "One", "Two") < One Two One However, you can't use a different type the second time: > echo printf("%1$s %2$s %1$d", "One", "Two") -< E1404: Positional argument 1 type used +< E1504: Positional argument 1 type used inconsistently: int/string - *E1405* + *E1505* Various other errors that lead to a format string being wrongly formatted lead to: > echo printf("%1$d at width %2$d is: %01$*2$.3$d", 1, 2) -< E1405: Invalid format specifier: +< E1505: Invalid format specifier: %1$d at width %2$d is: %01$*2$.3$d prompt_getprompt({buf}) *prompt_getprompt()* diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index d2e476f006..3d63b1964b 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -517,16 +517,26 @@ example, to match only files that end in ".c": > :e *.c$ This will not match a file ending in ".cpp". Without the "$" it does match. -The old value of an option can be obtained by hitting 'wildchar' just after -the '='. For example, typing 'wildchar' after ":set dir=" will insert the -current value of 'dir'. This overrules file name completion for the options -that take a file name. - If you would like using for CTRL-P in an xterm, put this command in your .cshrc: > xmodmap -e "keysym Tab = Tab Find" And this in your .vimrc: > :cmap [1~ +< *complete-set-option* +When setting an option using |:set=|, the old value of an option can be +obtained by hitting 'wildchar' just after the '='. For example, typing +'wildchar' after ":set dir=" will insert the current value of 'dir'. This +overrules file name completion for the options that take a file name. + +When using |:set=|, |:set+=|, or |:set^=|, string options that have +pre-defined names or syntax (e.g. 'diffopt', 'listchars') or are a list of +single-character flags (e.g. 'shortmess') will also present a list of possible +values for completion when using 'wildchar'. + +When using |:set-=|, comma-separated options like 'diffopt' or 'backupdir' +will show each item separately. Flag list options like 'shortmess' will show +both the entire old value and the individual flags. Otherwise completion will +just fill in with the entire old value. ============================================================================== 3. Ex command-lines *cmdline-lines* diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index da9aeb7fea..46279110a7 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1,4 +1,4 @@ -*editing.txt* For Vim version 9.0. Last change: 2023 Apr 23 +*editing.txt* For Vim version 9.0. Last change: 2023 Sep 22 VIM REFERENCE MANUAL by Bram Moolenaar @@ -385,7 +385,9 @@ as a wildcard when "[" is in the 'isfname' option. A simple way to avoid this is to use "path\[[]abc]", this matches the file "path\[abc]". *starstar-wildcard* -Expanding "**" is possible on Unix, Win32, macOS and a few other systems. +Expanding "**" is possible on Unix, Win32, macOS and a few other systems (but +it may depend on your 'shell' setting. It's known to work correctly for zsh; for +bash this requires at least bash version >= 4.X). This allows searching a directory tree. This goes up to 100 directories deep. Note there are some commands where this works slightly differently, see |file-searching|. diff --git a/runtime/doc/motion.txt b/runtime/doc/motion.txt index 73fc9a8171..403ef4f307 100644 --- a/runtime/doc/motion.txt +++ b/runtime/doc/motion.txt @@ -1,4 +1,4 @@ -*motion.txt* For Vim version 9.0. Last change: 2023 Sep 18 +*motion.txt* For Vim version 9.0. Last change: 2023 Sep 28 VIM REFERENCE MANUAL by Bram Moolenaar @@ -592,14 +592,16 @@ a] *v_a]* *v_a[* *a]* *a[* a[ "a [] block", select [count] '[' ']' blocks. This goes backwards to the [count] unclosed '[', and finds the matching ']'. The enclosed text is selected, - including the '[' and ']'. + including the '[' and ']'. The |cpo-M| option flag + is used to handle escaped brackets. When used in Visual mode it is made characterwise. i] *v_i]* *v_i[* *i]* *i[* i[ "inner [] block", select [count] '[' ']' blocks. This goes backwards to the [count] unclosed '[', and finds the matching ']'. The enclosed text is selected, - excluding the '[' and ']'. + excluding the '[' and ']'. The |cpo-M| option flag + is used to handle escaped brackets. When used in Visual mode it is made characterwise. a) *v_a)* *a)* *a(* @@ -607,7 +609,8 @@ a( *vab* *v_ab* *v_a(* *ab* ab "a block", select [count] blocks, from "[count] [(" to the matching ')', including the '(' and ')' (see |[(|). Does not include white space outside of the - parenthesis. + parenthesis. The |cpo-M| option flag is used to + handle escaped parenthesis. When used in Visual mode it is made characterwise. i) *v_i)* *i)* *i(* @@ -615,19 +618,22 @@ i( *vib* *v_ib* *v_i(* *ib* ib "inner block", select [count] blocks, from "[count] [(" to the matching ')', excluding the '(' and ')' (see |[(|). If the cursor is not inside a () block, then - find the next "(". + find the next "(". The |cpo-M| option flag + is used to handle escaped parenthesis. When used in Visual mode it is made characterwise. a> *v_a>* *v_a<* *a>* *a<* a< "a <> block", select [count] <> blocks, from the [count]'th unmatched '<' backwards to the matching - '>', including the '<' and '>'. + '>', including the '<' and '>'. The |cpo-M| option flag + is used to handle escaped '<' and '>'. When used in Visual mode it is made characterwise. i> *v_i>* *v_i<* *i>* *i<* i< "inner <> block", select [count] <> blocks, from the [count]'th unmatched '<' backwards to the matching - '>', excluding the '<' and '>'. + '>', excluding the '<' and '>'. The |cpo-M| option flag + is used to handle escaped '<' and '>'. When used in Visual mode it is made characterwise. *v_at* *at* @@ -649,14 +655,16 @@ a} *v_a}* *a}* *a{* a{ *v_aB* *v_a{* *aB* aB "a Block", select [count] Blocks, from "[count] [{" to the matching '}', including the '{' and '}' (see - |[{|). + |[{|). The |cpo-M| option flag is used to handle + escaped braces. When used in Visual mode it is made characterwise. i} *v_i}* *i}* *i{* i{ *v_iB* *v_i{* *iB* iB "inner Block", select [count] Blocks, from "[count] [{" to the matching '}', excluding the '{' and '}' (see - |[{|). + |[{|). The |cpo-M| option flag is used to handle + escaped braces. When used in Visual mode it is made characterwise. a" *v_aquote* *aquote* diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 517202258d..20aee61a58 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -71,7 +71,7 @@ achieve special effects. These options come in three forms: 'ttytype' Warning: This may have a lot of side effects. - *:set-args* *E487* *E521* + *:set-args* *:set=* *E487* *E521* :se[t] {option}={value} or :se[t] {option}:{value} Set string or number option to {value}. @@ -79,7 +79,9 @@ achieve special effects. These options come in three forms: hex (preceded with 0x) or octal (preceded with '0'). The old value can be inserted by typing 'wildchar' (by default this is a or CTRL-E if 'compatible' is - set). See |cmdline-completion|. + set). Many string options with fixed syntax and names + also support completing known values. See + |cmdline-completion| and |complete-set-option|. White space between {option} and '=' is allowed and will be ignored. White space between '=' and {value} is not allowed. @@ -113,6 +115,9 @@ achieve special effects. These options come in three forms: When the option is a list of flags, {value} must be exactly as they appear in the option. Remove flags one by one to avoid problems. + The individual values from a comma separated list or + list of flags can be inserted by typing 'wildchar'. + See |complete-set-option|. Also see |:set-args| above. The {option} arguments to ":set" may be repeated. For example: > @@ -6886,9 +6891,9 @@ A jump table for the options with a short description can be found at |Q_op|. *'scrollbind'* *'scb'* *'noscrollbind'* *'noscb'* 'scrollbind' 'scb' boolean (default off) local to window - See also |scroll-binding|. When this option is set, the current - window scrolls as other scrollbind windows (windows that also have - this option set) scroll. This option is useful for viewing the + See also |scroll-binding|. When this option is set, scrolling the + current window also scrolls other scrollbind windows (windows that + also have this option set). This option is useful for viewing the differences between two versions of a file, see 'diff'. See |'scrollopt'| for options that determine how this option should be interpreted. diff --git a/runtime/doc/scroll.txt b/runtime/doc/scroll.txt index 8e57be441c..91fa22824f 100644 --- a/runtime/doc/scroll.txt +++ b/runtime/doc/scroll.txt @@ -191,16 +191,16 @@ windows can be given this behavior by setting the (window-specific) other 'scrollbind' windows are scrolled the same amount, if possible. The behavior of 'scrollbind' can be modified by the 'scrollopt' option. -When using the scrollbars, the binding only happens when scrolling the window -with focus (where the cursor is). You can use this to avoid scroll-binding -for a moment without resetting options. +When using the scrollbars or the mouse wheel, the binding only happens when +scrolling the window with focus (where the cursor is). You can use this to +avoid scroll-binding for a moment without resetting options. When a window also has the 'diff' option set, the scroll-binding uses the differences between the two buffers to synchronize the position precisely. Otherwise the following method is used. *scrollbind-relative* -Each 'scrollbind' window keeps track of its "relative offset," which can be +Each 'scrollbind' window keeps track of its "relative offset", which can be thought of as the difference between the current window's vertical scroll position and the other window's vertical scroll position. When one of the 'scrollbind' windows is asked to vertically scroll past the beginning or end @@ -224,9 +224,10 @@ option. *scrollbind-quickadj* The 'scrollbind' flag is meaningful when using keyboard commands to vertically -scroll a window, and also meaningful when using the vertical scrollbar of the -window which has the cursor focus. However, when using the vertical scrollbar -of a window which doesn't have the cursor focus, 'scrollbind' is ignored. +scroll a window, and is also meaningful when using the vertical scrollbar or +the mouse wheel in the window which has the cursor focus. However, when using +the vertical scrollbar or the mouse wheel in a window which doesn't have the +cursor focus, 'scrollbind' is ignored. This allows quick adjustment of the relative offset of 'scrollbind' windows. ============================================================================== diff --git a/runtime/doc/tags b/runtime/doc/tags index 40b97db5be..894c156cb3 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -3235,6 +3235,7 @@ $quote eval.txt /*$quote* :set-inv options.txt /*:set-inv* :set-termcap options.txt /*:set-termcap* :set-verbose options.txt /*:set-verbose* +:set= options.txt /*:set=* :set^= options.txt /*:set^=* :set_env options.txt /*:set_env* :setf options.txt /*:setf* @@ -4533,14 +4534,15 @@ E1380 vim9class.txt /*E1380* E1381 vim9class.txt /*E1381* E1382 vim9class.txt /*E1382* E1383 vim9class.txt /*E1383* +E1384 vim9class.txt /*E1384* +E1385 vim9class.txt /*E1385* +E1386 vim9class.txt /*E1386* +E1387 vim9class.txt /*E1387* +E1388 vim9class.txt /*E1388* +E1389 vim9class.txt /*E1389* E139 message.txt /*E139* +E1390 vim9class.txt /*E1390* E140 message.txt /*E140* -E1400 builtin.txt /*E1400* -E1401 builtin.txt /*E1401* -E1402 builtin.txt /*E1402* -E1403 builtin.txt /*E1403* -E1404 builtin.txt /*E1404* -E1405 builtin.txt /*E1405* E141 message.txt /*E141* E142 message.txt /*E142* E143 autocmd.txt /*E143* @@ -4552,6 +4554,12 @@ E148 repeat.txt /*E148* E149 helphelp.txt /*E149* E15 eval.txt /*E15* E150 helphelp.txt /*E150* +E1500 builtin.txt /*E1500* +E1501 builtin.txt /*E1501* +E1502 builtin.txt /*E1502* +E1503 builtin.txt /*E1503* +E1504 builtin.txt /*E1504* +E1505 builtin.txt /*E1505* E151 helphelp.txt /*E151* E152 helphelp.txt /*E152* E153 helphelp.txt /*E153* @@ -6575,6 +6583,7 @@ complete-items insert.txt /*complete-items* complete-popup insert.txt /*complete-popup* complete-popuphidden insert.txt /*complete-popuphidden* complete-script-local-functions cmdline.txt /*complete-script-local-functions* +complete-set-option cmdline.txt /*complete-set-option* complete_CTRL-E insert.txt /*complete_CTRL-E* complete_CTRL-Y insert.txt /*complete_CTRL-Y* complete_add() builtin.txt /*complete_add()* @@ -6590,6 +6599,7 @@ conceal syntax.txt /*conceal* confirm() builtin.txt /*confirm()* connection-refused message.txt /*connection-refused* console-menus gui.txt /*console-menus* +constructor vim9class.txt /*constructor* context.vim ft_context.txt /*context.vim* control intro.txt /*control* conversion-server mbyte.txt /*conversion-server* @@ -6763,6 +6773,7 @@ debugger.txt debugger.txt /*debugger.txt* dec-mouse options.txt /*dec-mouse* decada_members ft_ada.txt /*decada_members* deepcopy() builtin.txt /*deepcopy()* +default-constructor vim9class.txt /*default-constructor* defaults.vim starting.txt /*defaults.vim* defaults.vim-explained usr_05.txt /*defaults.vim-explained* define-function userfunc.txt /*define-function* @@ -9078,6 +9089,7 @@ netrw.vim pi_netrw.txt /*netrw.vim* netrw_filehandler pi_netrw.txt /*netrw_filehandler* netterm-mouse options.txt /*netterm-mouse* network pi_netrw.txt /*network* +new() vim9class.txt /*new()* new-5 version5.txt /*new-5* new-6 version6.txt /*new-6* new-7 version7.txt /*new-7* @@ -9471,6 +9483,8 @@ printf-s builtin.txt /*printf-s* printf-x builtin.txt /*printf-x* printing print.txt /*printing* printing-formfeed print.txt /*printing-formfeed* +private-method vim9class.txt /*private-method* +private-variable vim9class.txt /*private-variable* profile repeat.txt /*profile* profiling repeat.txt /*profiling* profiling-variable eval.txt /*profiling-variable* diff --git a/runtime/doc/vim9class.txt b/runtime/doc/vim9class.txt index a27f7319a7..0660254696 100644 --- a/runtime/doc/vim9class.txt +++ b/runtime/doc/vim9class.txt @@ -150,7 +150,7 @@ If you try to set an object variable that doesn't exist you get an error: > A object variable cannot be accessed using the class name. Private variables ~ - *E1332* *E1333* + *private-variable* *E1332* *E1333* On the other hand, if you do not want the object variables to be read directly, you can make them private. This is done by prefixing an underscore to the name: > @@ -182,7 +182,7 @@ number to the total number of lines: > enddef < Private methods ~ - *E1366* + *private-method* *E1366* If you want object methods to be accessible only from other methods of the same class and not used from outside the class, then you can make them private. This is done by prefixing the method name with an underscore: > @@ -203,7 +203,7 @@ the above class): > a._Foo() < Simplifying the new() method ~ - + *new()* *constructor* Many constructors take values for the object variables. Thus you very often see this pattern: > @@ -216,7 +216,8 @@ see this pattern: > this.col = col enddef endclass - +< + *E1390* Not only is this text you need to write, it also has the type of each variables twice. Since this is so common a shorter way to write new() is provided: > @@ -257,10 +258,15 @@ If the class extends a parent class, the same thing happens. In the second step the object variables of the parent class are initialized first. There is no need to call "super()" or "new()" on the parent. - *E1365* + *E1365* When defining the new() method the return type should not be specified. It always returns an object of the class. + *E1386* +When invoking an object method, the method name should be preceded by the +object variable name. A object method cannot be invoked using the class +name. + ============================================================================== 3. Class Variables and Methods *Vim9-class-member* @@ -281,7 +287,7 @@ prefix in the class where they are defined: > Since the name is used as-is, shadowing the name by a method argument name or local variable name is not allowed. - *E1374* *E1375* + *E1374* *E1375* *E1384* *E1385* To access a class member outside of the class where it is defined, the class name prefix must be used. A class member cannot be accessed using an object. @@ -464,10 +470,10 @@ The interface name can be used as a type: > echo $'the surface is {shape.Surface()}' endfor < - *E1378* *E1379* *E1380* -An interface can have only instance variables (read-only and read-write -access) and methods. An interface cannot contain private variables, private -methods, class variables and class methods. + *E1378* *E1379* *E1380* *E1387* +An interface can contain only object methods and read-only object variables. +An interface cannot contain read-write and private object variables, private +object methods, class variables and class methods. An interface can extend another interface using "extends". The sub-interface inherits all the instance variables and methods from the super interface. @@ -524,6 +530,10 @@ If the type of a variable is not explicitly specified in a class, then it is set to "any" during class definition. When an object is instantiated from the class, then the type of the variable is set. +The following reserved keyword names cannot be used as an object or class +variable name: "super", "this", "true", "false", "null", "null_blob", +"null_dict", "null_function", "null_list", "null_partial", "null_string", +"null_channel" and "null_job". Extending a class ~ *extends* @@ -537,9 +547,11 @@ Object variables from the base class are all taken over by the child class. It is not possible to override them (unlike some other languages). *E1356* *E1357* *E1358* -Object methods of the base class can be overruled. The signature (arguments, -argument types and return type) must be exactly the same. The method of the -base class can be called by prefixing "super.". +Object methods of the base class can be overruled. The number of arguments +must be exactly the same. The method argument type can be a contra-variant +type of the base class method argument type. The method return value type can +be a covariant type of the base class method return value type. The method of +the base class can be called by prefixing "super.". *E1377* The access level of a method (public or private) in a child class should be @@ -563,7 +575,7 @@ will be added automatically. A class implementing an interface ~ - *implements* *E1346* *E1347* + *implements* *E1346* *E1347* *E1389* A class can implement one or more interfaces. The "implements" keyword can only appear once *E1350* . Multiple interfaces can be specified, separated by commas. Each interface name can appear only once. *E1351* @@ -577,7 +589,7 @@ interface, which is often done in many languages, especially Java. Items in a class ~ - *E1318* *E1325* + *E1318* *E1325* *E1388* Inside a class, in between `:class` and `:endclass`, these items can appear: - An object variable declaration: > this._privateVariableName: memberType @@ -650,7 +662,7 @@ even when the variable name is invalid. *E1360* *E1362* *E1363* Default constructor ~ - + *default-constructor* In case you define a class without a new() method, one will be automatically defined. This default constructor will have arguments for all the object variables, in the order they were specified. Thus if your class looks like: > diff --git a/runtime/doc/xxd.man b/runtime/doc/xxd.man index 3eae32ab67..26077265aa 100644 --- a/runtime/doc/xxd.man +++ b/runtime/doc/xxd.man @@ -3,7 +3,7 @@ XXD(1) General Commands Manual XXD(1) NAME - xxd - make a hexdump or do the reverse. + xxd - make a hex dump or do the reverse. SYNOPSIS xxd -h[elp] @@ -30,19 +30,19 @@ OPTIONS notation. Thus -c8, -c 8, -c 010 and -cols 8 are all equivalent. -a | -autoskip - Toggle autoskip: A single '*' replaces nul-lines. Default off. + Toggle autoskip: A single '*' replaces NUL-lines. Default off. -b | -bits - Switch to bits (binary digits) dump, rather than hexdump. This + Switch to bits (binary digits) dump, rather than hex dump. This option writes octets as eight digits "1"s and "0"s instead of a normal hexadecimal dump. Each line is preceded by a line number - in hexadecimal and followed by an ascii (or ebcdic) representa‐ + in hexadecimal and followed by an ASCII (or EBCDIC) representa‐ tion. The command line switches -r, -p, -i do not work with this mode. -c cols | -cols cols Format octets per line. Default 16 (-i: 12, -ps: 30, -b: - 6). Max 256. No maxmimum for -ps. With -ps, 0 results in one + 6). Max 256. No maximum for -ps. With -ps, 0 results in one long line of output. -C | -capitalize @@ -54,53 +54,60 @@ OPTIONS to EBCDIC. This does not change the hexadecimal representation. The option is meaningless in combinations with -r, -p or -i. - -e Switch to little-endian hexdump. This option treats byte groups - as words in little-endian byte order. The default grouping of 4 - bytes may be changed using -g. This option only applies to hex‐ - dump, leaving the ASCII (or EBCDIC) representation unchanged. - The command line switches -r, -p, -i do not work with this mode. + -e Switch to little-endian hex dump. This option treats byte + groups as words in little-endian byte order. The default group‐ + ing of 4 bytes may be changed using -g. This option only ap‐ + plies to the hex dump, leaving the ASCII (or EBCDIC) representa‐ + tion unchanged. The command line switches -r, -p, -i do not + work with this mode. -g bytes | -groupsize bytes - Separate the output of every bytes (two hex characters - or eight bit-digits each) by a whitespace. Specify -g 0 to sup‐ + Separate the output of every bytes (two hex characters + or eight bit digits each) by a whitespace. Specify -g 0 to sup‐ press grouping. defaults to 2 in normal mode, 4 in lit‐ - tle-endian mode and 1 in bits mode. Grouping does not apply to - postscript or include style. + tle-endian mode and 1 in bits mode. Grouping does not apply to + PostScript or include style. -h | -help - Print a summary of available commands and exit. No hex dumping + Print a summary of available commands and exit. No hex dumping is performed. -i | -include - Output in C include file style. A complete static array defini‐ - tion is written (named after the input file), unless xxd reads + Output in C include file style. A complete static array defini‐ + tion is written (named after the input file), unless xxd reads from stdin. -l len | -len len Stop after writing octets. -n name | -name name - Override the variable name output when -i is used. The array is + Override the variable name output when -i is used. The array is named name and the length is named name_len. -o offset Add to the displayed file position. -p | -ps | -postscript | -plain - Output in postscript continuous hexdump style. Also known as - plain hexdump style. + Output in PostScript continuous hex dump style. Also known as + plain hex dump style. -r | -revert - Reverse operation: convert (or patch) hexdump into binary. If - not writing to stdout, xxd writes into its output file without + Reverse operation: convert (or patch) hex dump into binary. If + not writing to stdout, xxd writes into its output file without truncating it. Use the combination -r -p to read plain hexadeci‐ mal dumps without line number information and without a particu‐ - lar column layout. Additional Whitespace and line-breaks are al‐ + lar column layout. Additional whitespace and line breaks are al‐ lowed anywhere. + -R when + In output the hex-value and the value are both colored with the + same color depending on the hex-value. Mostly helping to differ‐ + entiate printable and non-printable characters. when is never, + always, or auto. + -seek offset When used after -r: revert with added to file positions - found in hexdump. + found in hex dump. -s [+][-]seek Start at bytes abs. (or rel.) infile offset. + indicates @@ -110,56 +117,55 @@ OPTIONS (or if combined with +: before the current stdin file position). Without -s option, xxd starts at the current file position. - -u Use upper case hex letters. Default is lower case. + -u Use upper-case hex letters. Default is lower-case. -v | -version Show version string. CAVEATS - xxd -r has some builtin magic while evaluating line number information. - If the output file is seekable, then the linenumbers at the start of - each hexdump line may be out of order, lines may be missing, or over‐ - lapping. In these cases xxd will lseek(2) to the next position. If the - output file is not seekable, only gaps are allowed, which will be - filled by null-bytes. + xxd -r has some built-in magic while evaluating line number informa‐ + tion. If the output file is seekable, then the line numbers at the + start of each hex dump line may be out of order, lines may be missing, + or overlapping. In these cases xxd will lseek(2) to the next position. + If the output file is not seekable, only gaps are allowed, which will + be filled by null-bytes. xxd -r never generates parse errors. Garbage is silently skipped. - When editing hexdumps, please note that xxd -r skips everything on the + When editing hex dumps, please note that xxd -r skips everything on the input line after reading enough columns of hexadecimal data (see option - -c). This also means, that changes to the printable ascii (or ebcdic) - columns are always ignored. Reverting a plain (or postscript) style - hexdump with xxd -r -p does not depend on the correct number of col‐ - umns. Here anything that looks like a pair of hex-digits is inter‐ - preted. + -c). This also means that changes to the printable ASCII (or EBCDIC) + columns are always ignored. Reverting a plain (or PostScript) style hex + dump with xxd -r -p does not depend on the correct number of columns. + Here, anything that looks like a pair of hex digits is interpreted. Note the difference between % xxd -i file and % xxd -i < file - xxd -s +seek may be different from xxd -s seek, as lseek(2) is used to + xxd -s +seek may be different from xxd -s seek, as lseek(2) is used to "rewind" input. A '+' makes a difference if the input source is stdin, - and if stdin's file position is not at the start of the file by the - time xxd is started and given its input. The following examples may - help to clarify (or further confuse!)... + and if stdin's file position is not at the start of the file by the + time xxd is started and given its input. The following examples may + help to clarify (or further confuse!): - Rewind stdin before reading; needed because the `cat' has already read + Rewind stdin before reading; needed because the `cat' has already read to the end of stdin. % sh -c "cat > plain_copy; xxd -s 0 > hex_copy" < file - Hexdump from file position 0x480 (=1024+128) onwards. The `+' sign + Hex dump from file position 0x480 (=1024+128) onwards. The `+' sign means "relative to the current position", thus the `128' adds to the 1k where dd left off. - % sh -c "dd of=plain_snippet bs=1k count=1; xxd -s +128 > hex_snippet" + % sh -c "dd of=plain_snippet bs=1k count=1; xxd -s +128 > hex_snippet" < file - Hexdump from file position 0x100 ( = 1024-768) on. + Hex dump from file position 0x100 (=1024-768) onwards. % sh -c "dd of=plain_snippet bs=1k count=1; xxd -s +-768 > hex_snippet" < file - However, this is a rare situation and the use of `+' is rarely needed. - The author prefers to monitor the effect of xxd with strace(1) or + However, this is a rare situation and the use of `+' is rarely needed. + The author prefers to monitor the effect of xxd with strace(1) or truss(1), whenever -s is used. EXAMPLES @@ -169,7 +175,7 @@ EXAMPLES Print 3 lines (hex 0x30 bytes) from the end of file. % xxd -s -0x30 file - Print 120 bytes as continuous hexdump with 20 octets per line. + Print 120 bytes as a continuous hex dump with 20 octets per line. % xxd -l 120 -ps -c 20 xxd.1 2e54482058584420312022417567757374203139 39362220224d616e75616c207061676520666f72 @@ -178,7 +184,7 @@ EXAMPLES 20617574686f723a0a2e5c2220202020546f6e79 204e7567656e74203c746f6e79407363746e7567 - Hexdump the first 120 bytes of this man page with 12 octets per line. + Hex dump the first 120 bytes of this man page with 12 octets per line. % xxd -l 120 -c 12 xxd.1 0000000: 2e54 4820 5858 4420 3120 2241 .TH XXD 1 "A 000000c: 7567 7573 7420 3139 3936 2220 ugust 1996" @@ -203,31 +209,31 @@ EXAMPLES % xxd -s 0x36 -l 13 -c 13 xxd.1 0000036: 3235 7468 204d 6179 2031 3939 36 25th May 1996 - Create a 65537 byte file with all bytes 0x00, except for the last one + Create a 65537 byte file with all bytes 0x00, except for the last one which is 'A' (hex 0x41). % echo "010000: 41" | xxd -r > file - Hexdump this file with autoskip. + Hex dump this file with autoskip. % xxd -a -c 12 file 0000000: 0000 0000 0000 0000 0000 0000 ............ * 000fffc: 0000 0000 40 ....A Create a 1 byte file containing a single 'A' character. The number af‐ - ter '-r -s' adds to the linenumbers found in the file; in effect, the + ter '-r -s' adds to the line numbers found in the file; in effect, the leading bytes are suppressed. % echo "010000: 41" | xxd -r -s -0x10000 > file - Use xxd as a filter within an editor such as vim(1) to hexdump a region - marked between `a' and `z'. + Use xxd as a filter within an editor such as vim(1) to hex dump a re‐ + gion marked between `a' and `z'. :'a,'z!xxd Use xxd as a filter within an editor such as vim(1) to recover a binary - hexdump marked between `a' and `z'. + hex dump marked between `a' and `z'. :'a,'z!xxd -r Use xxd as a filter within an editor such as vim(1) to recover one line - of a hexdump. Move the cursor over the line and type: + of a hex dump. Move the cursor over the line and type: !!xxd -r Read single characters from a serial line @@ -240,7 +246,7 @@ RETURN VALUES 0 no errors encountered. - -1 operation not supported ( xxd -r -i still impossible). + -1 operation not supported (xxd -r -i still impossible). 1 error while parsing options. @@ -254,7 +260,7 @@ SEE ALSO uuencode(1), uudecode(1), patch(1) WARNINGS - The tools weirdness matches its creators brain. Use entirely at your + The tool's weirdness matches its creator's brain. Use entirely at your own risk. Copy files. Trace it. Become a wizard. VERSION diff --git a/runtime/ftplugin/rmd.vim b/runtime/ftplugin/rmd.vim index be6ab7335b..a407c236dd 100644 --- a/runtime/ftplugin/rmd.vim +++ b/runtime/ftplugin/rmd.vim @@ -2,7 +2,7 @@ " Language: R Markdown file " Maintainer: Jakson Alves de Aquino " Homepage: https://github.com/jalvesaq/R-Vim-runtime -" Last Change: Mon Feb 27, 2023 07:15PM +" Last Change: Mon May 29, 2023 06:31AM " Original work by Alex Zvoleff (adjusted from R help for rmd by Michel Kuhlmann) " Only do this when not yet done for this buffer @@ -32,12 +32,18 @@ function FormatRmd() return 1 endfunction +let s:last_line = 0 function SetRmdCommentStr() - if (search("^[ \t]*```[ ]*{r", "bncW") > search("^[ \t]*```$", "bncW")) || ((search('^---$', 'Wn') || search('^\.\.\.$', 'Wn')) && search('^---$', 'bnW')) - set commentstring=#\ %s - else - set commentstring= - endif + if line('.') == s:last_line + return + endif + let s:last_line = line('.') + + if (search("^[ \t]*```[ ]*{r", "bncW") > search("^[ \t]*```$", "bncW")) || ((search('^---$', 'Wn') || search('^\.\.\.$', 'Wn')) && search('^---$', 'bnW')) + set commentstring=#\ %s + else + set commentstring= + endif endfunction " If you do not want both 'comments' and 'commentstring' dynamically defined, diff --git a/runtime/ftplugin/sh.vim b/runtime/ftplugin/sh.vim index 4409f3f90c..c227838d18 100644 --- a/runtime/ftplugin/sh.vim +++ b/runtime/ftplugin/sh.vim @@ -39,8 +39,7 @@ if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") let b:undo_ftplugin ..= " | unlet! b:browsefilter" endif -if (exists("b:is_bash") && (b:is_bash == 1)) || - \ (exists("b:is_sh") && (b:is_sh == 1)) +if (exists("b:is_bash") && (b:is_bash == 1)) if !has("gui_running") && executable("less") command! -buffer -nargs=1 Help silent exe '!bash -c "{ help "" 2>/dev/null || man ""; } | LESS= less"' | redraw! elseif has('terminal') diff --git a/runtime/syntax/i3config.vim b/runtime/syntax/i3config.vim index 8bc2a6e03c..3b4765153a 100644 --- a/runtime/syntax/i3config.vim +++ b/runtime/syntax/i3config.vim @@ -1,10 +1,9 @@ " Vim syntax file " Language: i3 config file -" Original Author: Mohamed Boughaba +" Original Author: Josef Litos (JosefLitos/i3config.vim) " Maintainer: Quentin Hibon (github user hiqua) -" Version: 0.4.22 -" Reference version (JosefLitos/i3config.vim): 4.22 -" Last Change: 2023-09-12 +" Version: 1.0.0 +" Last Change: 2023-09-14 " References: " http://i3wm.org/docs/userguide.html#configuring @@ -25,18 +24,18 @@ syn match i3ConfigError /.\+/ syn keyword i3ConfigTodo TODO FIXME XXX contained " Helper type definitions -syn match i3ConfigSeparator /[,;]/ contained +syn match i3ConfigSeparator /[,;\\]/ contained syn match i3ConfigParen /[{}]/ contained syn keyword i3ConfigBoolean yes no enabled disabled on off true false contained -syn region i3ConfigString start=/\W\@<="/ skip=/\\"/ end=/"/ contained contains=i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigVariable,i3ConfigExecAction keepend extend -syn region i3ConfigString start=/\W\@<='/ end=/'/ contained contains=i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigVariable,i3ConfigExecAction keepend extend -syn match i3ConfigColor /#\w\{3,8}/ contained -syn match i3ConfigNumber /[a-zA-Z_$-]\@&|+=~^*!.?]\+/ contained -syn match i3ConfigShParam /\<-[a-zA-Z0-9_-]\+\>/ contained containedin=i3ConfigVar +syn match i3ConfigShParam /\<-[0-9A-Za-z_-]\+\>/ contained containedin=i3ConfigVar syn region i3ConfigExec start=/^\s*exec\(_always\)\?\( --no-startup-id\)\? [^{]/ skip=/\\$/ end=/$/ contains=i3ConfigExecKeyword,i3ConfigExecAlwaysKeyword,i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigString,i3ConfigVariable,i3ConfigExecAction keepend " 4.21 Workspaces per output syn keyword i3ConfigWorkspaceKeyword workspace contained syn keyword i3ConfigWorkspaceOutput output contained -syn keyword i3ConfigWorkspaceDir prev next back_and_forth contained +syn keyword i3ConfigWorkspaceDir prev next back_and_forth number contained syn region i3ConfigWorkspaceLine start=/^workspace / skip=/\\$/ end=/$/ contains=i3ConfigWorkspaceKeyword,i3ConfigNumber,i3ConfigString,i3ConfigGaps,i3ConfigWorkspaceOutput,i3ConfigVariable,i3ConfigBoolean,i3ConfigSeparator keepend " 4.22 Changing colors @@ -136,121 +134,126 @@ syn match i3ConfigKeyword /^client\..*$/ contains=i3ConfigDotOperator,i3ConfigCl " 4.23 Interprocess communication syn match i3ConfigIpcKeyword /ipc-socket/ contained -syn match i3ConfigIpc /^ipc-socket .*$/ contains=i3ConfigIpcKeyword +syn match i3ConfigParamLine /^ipc-socket .*$/ contains=i3ConfigIpcKeyword " 4.24 Focus follows mouse syn keyword i3ConfigFocusFollowsMouseOpts always contained -syn match i3ConfigFocusFollowsMouse /^focus_follows_mouse \(yes\|no\|always\)$/ contains=i3ConfigBoolean,i3ConfigFocusFollowsMouseOpts +syn match i3ConfigKeyword /^focus_follows_mouse \(yes\|no\|always\)$/ contains=i3ConfigBoolean,i3ConfigFocusFollowsMouseOpts " 4.25 Mouse warping syn keyword i3ConfigMouseWarpingOpts output container none contained -syn match i3ConfigMouseWarping /^mouse_warping \w*$/ contains=i3ConfigMouseWarpingOpts +syn match i3ConfigKeyword /^mouse_warping \w*$/ contains=i3ConfigMouseWarpingOpts " 4.26 Popups while fullscreen syn keyword i3ConfigPopupFullscreenOpts smart ignore leave_fullscreen contained -syn match i3ConfigPopupFullscreen /^popup_during_fullscreen \w*$/ contains=i3ConfigPopupFullscreenOpts +syn match i3ConfigKeyword /^popup_during_fullscreen \w*$/ contains=i3ConfigPopupFullscreenOpts " 4.27 Focus wrapping syn keyword i3ConfigFocusWrappingOpts force workspace contained -syn match i3ConfigFocusWrapping /^focus_wrapping \(yes\|no\|force\|workspace\)$/ contains=i3ConfigBoolean,i3ConfigFocusWrappingOpts +syn match i3ConfigKeyword /^focus_wrapping \(yes\|no\|force\|workspace\)$/ contains=i3ConfigBoolean,i3ConfigFocusWrappingOpts " 4.28 Forcing Xinerama -syn match i3ConfigForceXinerama /^force_xinerama \(yes\|no\)$/ contains=i3ConfigBoolean +syn match i3ConfigKeyword /^force_xinerama \(yes\|no\)$/ contains=i3ConfigBoolean " 4.29 Automatic workspace back-and-forth -syn match i3ConfigAutomaticSwitch /^workspace_auto_back_and_forth \(yes\|no\)$/ contains=i3ConfigBoolean +syn match i3ConfigKeyword /^workspace_auto_back_and_forth \(yes\|no\)$/ contains=i3ConfigBoolean " 4.30 Delay urgency hint syn keyword i3ConfigTimeUnit ms contained -syn match i3ConfigDelayUrgency /^force_display_urgency_hint \d\+ ms$/ contains=i3ConfigBoolean,i3ConfigNumber,i3ConfigTimeUnit +syn match i3ConfigKeyword /^force_display_urgency_hint \d\+\( ms\)\?$/ contains=i3ConfigNumber,i3ConfigTimeUnit " 4.31 Focus on window activation syn keyword i3ConfigFocusOnActivationOpts smart urgent focus none contained -syn match i3ConfigFocusOnActivation /^focus_on_window_activation .*$/ contains=i3ConfigFocusOnActivationKeyword +syn match i3ConfigKeyword /^focus_on_window_activation \w*$/ contains=i3ConfigFocusOnActivationOpts " 4.32 Show marks in title syn match i3ConfigShowMarks /^show_marks \(yes\|no\)$/ contains=i3ConfigBoolean " 4.34 Tiling drag syn keyword i3ConfigTilingDragOpts modifier titlebar contained -syn match i3ConfigTilingDrag /^tiling_drag\( off\|\( modifier\| titlebar\)\{1,2\}\)$/ contains=i3ConfigTilingOpts,i3ConfigBoolean +syn match i3ConfigKeyword /^tiling_drag\( off\|\( modifier\| titlebar\)\{1,2\}\)$/ contains=i3ConfigTilingDragOpts,i3ConfigBoolean " 4.35 Gaps syn keyword i3ConfigGapsOpts inner outer horizontal vertical left right top bottom current all set plus minus toggle contained -syn region i3ConfigGaps start=/gaps/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigGapsOpts,i3ConfigNumber,i3ConfigVariable,i3ConfigSeparator keepend -syn match i3ConfigGapStyleLine /^gaps .*$/ contains=i3ConfigGaps +syn region i3ConfigGaps start=/gaps/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigGapsOpts,i3ConfigNumber,i3ConfigVariable,i3ConfigSeparator keepend +syn match i3ConfigGapsLine /^gaps .*$/ contains=i3ConfigGaps syn keyword i3ConfigSmartGapOpts inverse_outer contained -syn match i3ConfigSmartGap /^smart_gaps \(on\|off\|inverse_outer\)$/ contains=i3ConfigSmartGapOpts,i3ConfigBoolean +syn match i3ConfigKeyword /^smart_gaps \(on\|off\|inverse_outer\)$/ contains=i3ConfigSmartGapOpts,i3ConfigBoolean " 5 Configuring bar -syn match i3ConfigBarModifier /^\s\+modifier [^ ]\+$/ contained contains=i3ConfigBindModifier,i3ConfigVariable,i3ConfigBindModkey -syn keyword i3ConfigBarOpts bar i3bar_command status_command mode hidden_state id position output tray_output tray_padding font separator_symbol workspace_buttons workspace_min_width strip_workspace_numbers strip_workspace_name binding_mode_indicator padding contained -syn region i3ConfigBarBlock start=/^bar {$/ end=/^}$/ contains=i3ConfigBarOpts,i3ConfigBarModifier,i3ConfigBind,i3ConfigString,i3ConfigComment,i3ConfigFont,i3ConfigBoolean,i3ConfigNumber,i3ConfigParen,i3ConfigColor,i3ConfigVariable,i3ConfigColorsBlock fold keepend extend +syn match i3ConfigBarModifier /^\s\+modifier \S\+$/ contained contains=i3ConfigBindModifier,i3ConfigVariable,i3ConfigBindModkey,i3ConfigBarOptVals +syn keyword i3ConfigBarOpts bar i3bar_command status_command mode hidden_state id position output tray_output tray_padding separator_symbol workspace_buttons workspace_min_width strip_workspace_numbers strip_workspace_name binding_mode_indicator padding contained +syn keyword i3ConfigBarOptVals dock hide invisible show none top bottom primary nonprimary contained +syn region i3ConfigBarBlock start=/^bar {$/ end=/^}$/ contains=i3ConfigBarOpts,i3ConfigBarOptVals,i3ConfigBarModifier,i3ConfigBind,i3ConfigString,i3ConfigComment,i3ConfigFont,i3ConfigBoolean,i3ConfigNumber,i3ConfigParen,i3ConfigColor,i3ConfigVariable,i3ConfigColorsBlock,i3ConfigShOper,i3ConfigShCommand fold keepend extend " 5.16 Color block +syn keyword i3ConfigColorsKeyword colors contained syn match i3ConfigColorsOpts /\(focused_\)\?\(background\|statusline\|separator\)\|\(focused\|active\|inactive\|urgent\)_workspace\|binding_mode/ contained -syn region i3ConfigColorsBlock start=/^\s\+colors {$/ end=/^\s\+}$/ contained contains=i3ConfigColorsOpts,i3ConfigColor,i3ConfigVariable,i3ConfigComment,i3ConfigParen fold keepend extend +syn region i3ConfigColorsBlock start=/^\s\+colors {$/ end=/^\s\+}$/ contained contains=i3ConfigColorsKeyword,i3ConfigColorsOpts,i3ConfigColor,i3ConfigVariable,i3ConfigComment,i3ConfigParen fold keepend extend -" 6.0 Criteria-based commands -syn match i3ConfigConditionProp /\w\+\(-\w\+\)*/ contained -syn match i3ConfigConditionText /[^[ ]\+=/ contained contains=i3ConfigConditionProp,i3ConfigShOper -syn keyword i3ConfigConditionFocused __focused__ contained -syn region i3ConfigCondition start=/\[/ end=/\]/ contained contains=i3ConfigConditionText,i3ConfigShDelim,i3ConfigNumber,i3ConfigString,i3ConfigConditionFocused keepend extend -syn region i3ConfigCriteria start=/\[/ skip=/\\$/ end=/\(;\|$\)/ contained contains=i3ConfigCondition,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigBoolean,i3ConfigNumber,i3ConfigVariable,i3ConfigSeparator keepend +" 6.0 Command criteria +syn keyword i3ConfigConditionProp class instance window_role window_type machine id title urgent workspace con_mark con_id floating_from tiling_from contained +syn keyword i3ConfigConditionSpecial __focused__ all floating tiling contained +syn region i3ConfigCondition start=/\[/ end=/\]/ contained contains=i3ConfigShDelim,i3ConfigConditionProp,i3ConfigShOper,i3ConfigConditionSpecial,i3ConfigNumber,i3ConfigString keepend extend +syn region i3ConfigCriteria start=/\[/ skip=/\\$/ end=/\(;\|$\)/ contained contains=i3ConfigCondition,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigBoolean,i3ConfigNumber,i3ConfigVariable,i3ConfigSeparator keepend transparent " 6.1 Actions through shell syn match i3ConfigExecActionKeyword /i3-msg/ contained -syn region i3ConfigExecAction start=/[a-z3-]\+msg '/ skip=/\\$\| '/ end=/'/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend extend -syn region i3ConfigExecAction start=/[a-z3-]\+msg "/ skip=/\\$\| "/ end=/"/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend extend -syn region i3ConfigExecAction start=/[a-z3-]\+msg\( ['"-]\)\@!/ skip=/\\$/ end=/\([&|;})'"]\|$\)/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend +syn region i3ConfigExecAction start=/[a-z3-]\+msg "/ skip=/ "\|\\$/ end=/"\|$/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend extend +syn region i3ConfigExecAction start=/[a-z3-]\+msg '/ skip=/ '\|\\$/ end=/'\|$/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend extend +syn region i3ConfigExecAction start=/[a-z3-]\+msg ['"-]\@!/ skip=/\\$/ end=/[&|;})'"]\@=\|$/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend extend " 6.1 Executing applications (4.20) -syn region i3ConfigAction start=/exec/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigExecKeyword,i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigString,i3ConfigVariable,i3ConfigSeparator keepend +syn region i3ConfigAction start=/exec/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigExecKeyword,i3ConfigExecAction,i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigString,i3ConfigVariable,i3ConfigSeparator keepend " 6.3 Manipulating layout syn keyword i3ConfigLayoutKeyword layout contained syn keyword i3ConfigLayoutOpts default tabbed stacking splitv splith toggle split all contained -syn region i3ConfigAction start=/layout/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigLayoutKeyword,i3ConfigLayoutOpts,i3ConfigSeparator keepend +syn region i3ConfigAction start=/layout/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigLayoutKeyword,i3ConfigLayoutOpts,i3ConfigSeparator keepend transparent " 6.4 Focusing containers syn keyword i3ConfigFocusKeyword focus contained syn keyword i3ConfigFocusOpts left right up down parent child next prev sibling floating tiling mode_toggle contained syn keyword i3ConfigFocusOutputOpts left right down up current primary nonprimary next prev contained -syn region i3ConfigFocusOutput start=/ output / skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigMoveType,i3ConfigWorkspaceOutput,i3ConfigFocusOutputOpts,i3ConfigString,i3ConfigNumber,i3ConfigSeparator keepend +syn region i3ConfigFocusOutput start=/ output / skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigWorkspaceOutput,i3ConfigFocusOutputOpts,i3ConfigString,i3ConfigNumber,i3ConfigSeparator keepend syn match i3ConfigFocusOutputLine /^focus output .*$/ contains=i3ConfigFocusKeyword,i3ConfigFocusOutput -syn region i3ConfigAction start=/focus/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigFocusKeyword,i3ConfigFocusOpts,i3ConfigFocusOutput,i3ConfigString,i3ConfigSeparator keepend +syn region i3ConfigAction start=/focus/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigFocusKeyword,i3ConfigFocusOpts,i3ConfigFocusOutput,i3ConfigString,i3ConfigSeparator keepend transparent " 6.8 Focusing workspaces (4.21) -syn region i3ConfigAction start=/workspace / skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigWorkspaceKeyword,i3ConfigWorkspaceDir,i3ConfigNumber,i3ConfigString,i3ConfigGaps,i3ConfigWorkspaceOutput,i3ConfigVariable,i3ConfigBoolean,i3ConfigSeparator keepend +syn region i3ConfigAction start=/workspace / skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigWorkspaceKeyword,i3ConfigWorkspaceDir,i3ConfigNumber,i3ConfigString,i3ConfigGaps,i3ConfigWorkspaceOutput,i3ConfigVariable,i3ConfigBoolean,i3ConfigSeparator keepend transparent -" 6.9-6.11 Moving containers +" 6.8.2 Renaming workspaces +syn keyword i3ConfigRenameKeyword rename contained +syn region i3ConfigAction start=/rename workspace/ end=/[,;]\|$/ contained contains=i3ConfigRenameKeyword,i3ConfigMoveDir,i3ConfigMoveType,i3ConfigNumber,i3ConfigVariable,i3ConfigString keepend transparent + +" 6.5,6.9-6.11 Moving containers syn keyword i3ConfigMoveKeyword move contained -syn keyword i3ConfigMoveDir left right down up position absolute center to contained +syn keyword i3ConfigMoveDir left right down up position absolute center to current contained syn keyword i3ConfigMoveType window container workspace output mark mouse scratchpad contained syn match i3ConfigUnit / px\| ppt/ contained -syn region i3ConfigAction start=/move/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigMoveKeyword,i3ConfigMoveDir,i3ConfigMoveType,i3ConfigWorkspaceDir,i3ConfigUnit,i3ConfigNumber,i3ConfigVariable,i3ConfigSeparator keepend +syn region i3ConfigAction start=/move/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigMoveKeyword,i3ConfigMoveDir,i3ConfigMoveType,i3ConfigWorkspaceDir,i3ConfigUnit,i3ConfigNumber,i3ConfigVariable,i3ConfigString,i3ConfigSeparator,i3ConfigShParam keepend transparent " 6.12 Resizing containers/windows syn keyword i3ConfigResizeKeyword resize contained syn keyword i3ConfigResizeOpts grow shrink up down left right set width height or contained -syn region i3ConfigAction start=/resize/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigResizeKeyword,i3ConfigResizeOpts,i3ConfigNumber,i3ConfigUnit,i3ConfigSeparator keepend +syn region i3ConfigAction start=/resize/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigResizeKeyword,i3ConfigResizeOpts,i3ConfigNumber,i3ConfigUnit,i3ConfigSeparator keepend transparent " 6.14 VIM-like marks -syn keyword i3ConfigMarkKeyword mark contained -syn match i3ConfigMark /mark\( --\(add\|replace\)\( --toggle\)\?\)\?/ contained contains=i3ConfigMarkKeyword -syn region i3ConfigAction start=/\ " Homepage: https://github.com/jalvesaq/R-Vim-runtime -" Last Change: Fri Feb 24, 2023 08:28AM +" Last Change: Wed May 17, 2023 06:34AM " " For highlighting pandoc extensions to markdown like citations and TeX and " many other advanced features like folding of markdown sections, it is @@ -26,6 +26,8 @@ let g:rmd_syn_hl_chunk = get(g:, 'rmd_syn_hl_chunk', 0) let s:save_pandoc_lngs = get(g:, 'pandoc#syntax#codeblocks#embeds#langs', []) let g:pandoc#syntax#codeblocks#embeds#langs = [] +let g:rmd_dynamic_fenced_languages = get(g:, 'rmd_dynamic_fenced_languages', v:true) + " Step_1: Source pandoc.vim if it is installed: runtime syntax/pandoc.vim if exists("b:current_syntax") @@ -95,6 +97,11 @@ else hi def link yamlColonError Error endif + " Conceal char for manual line break + if &encoding ==# 'utf-8' + syn match rmdNewLine ' $' conceal cchar=↵ + endif + " You don't need this if either your markdown/syntax.vim already highlights " citations or you are writing standard markdown if g:rmd_syn_hl_citations @@ -127,32 +134,78 @@ syn match knitrBodyValue ': \zs.*\ze$' keepend contained containedin=knitrBodyOp syn match knitrBodyVar '| \zs\S\{-}\ze:' contained containedin=knitrBodyOptions let g:rmd_fenced_languages = get(g:, 'rmd_fenced_languages', ['r']) -for s:type in g:rmd_fenced_languages - if s:type =~ '=' - let s:ft = substitute(s:type, '.*=', '', '') - let s:nm = substitute(s:type, '=.*', '', '') + +let s:no_syntax_vim = [] +function IncludeLanguage(lng) + if a:lng =~ '=' + let ftpy = substitute(a:lng, '.*=', '', '') + let lnm = substitute(a:lng, '=.*', '', '') else - let s:ft = s:type - let s:nm = s:type + let ftpy = a:lng + let lnm = a:lng + endif + if index(s:no_syntax_vim, ftpy) >= 0 + return endif - unlet! b:current_syntax - exe 'syn include @Rmd'.s:nm.' syntax/'.s:ft.'.vim' - if g:rmd_syn_hl_chunk - exe 'syn match knitrChunkDelim /```\s*{\s*'.s:nm.'/ contained containedin=knitrChunkBrace contains=knitrChunkLabel' - exe 'syn match knitrChunkLabelDelim /```\s*{\s*'.s:nm.',\=\s*[-[:alnum:]]\{-1,}[,}]/ contained containedin=knitrChunkBrace' - syn match knitrChunkDelim /}\s*$/ contained containedin=knitrChunkBrace - exe 'syn match knitrChunkBrace /```\s*{\s*'.s:nm.'.*$/ contained containedin=rmd'.s:nm.'Chunk contains=knitrChunkDelim,knitrChunkLabelDelim,@Rmd'.s:nm - exe 'syn region rmd'.s:nm.'Chunk start="^\s*```\s*{\s*=\?'.s:nm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=knitrChunkBrace,@Rmd'.s:nm - - hi link knitrChunkLabel Identifier - hi link knitrChunkDelim rmdCodeDelim - hi link knitrChunkLabelDelim rmdCodeDelim + if len(globpath(&rtp, "syntax/" . ftpy . ".vim")) + unlet! b:current_syntax + exe 'syn include @Rmd'.lnm.' syntax/'.ftpy.'.vim' + let b:current_syntax = "rmd" + if g:rmd_syn_hl_chunk + exe 'syn match knitrChunkDelim /```\s*{\s*'.lnm.'/ contained containedin=knitrChunkBrace contains=knitrChunkLabel' + exe 'syn match knitrChunkLabelDelim /```\s*{\s*'.lnm.',\=\s*[-[:alnum:]]\{-1,}[,}]/ contained containedin=knitrChunkBrace' + syn match knitrChunkDelim /}\s*$/ contained containedin=knitrChunkBrace + exe 'syn match knitrChunkBrace /```\s*{\s*'.lnm.'.*$/ contained containedin=rmd'.lnm.'Chunk contains=knitrChunkDelim,knitrChunkLabelDelim,@Rmd'.lnm + exe 'syn region rmd'.lnm.'Chunk start="^\s*```\s*{\s*=\?'.lnm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=knitrChunkBrace,@Rmd'.lnm + + hi link knitrChunkLabel Identifier + hi link knitrChunkDelim rmdCodeDelim + hi link knitrChunkLabelDelim rmdCodeDelim + else + exe 'syn region rmd'.lnm.'Chunk matchgroup=rmdCodeDelim start="^\s*```\s*{\s*=\?'.lnm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=@Rmd'.lnm + endif else - exe 'syn region rmd'.s:nm.'Chunk matchgroup=rmdCodeDelim start="^\s*```\s*{\s*=\?'.s:nm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=@Rmd'.s:nm + " Avoid the cost of running globpath() whenever the buffer is saved + let s:no_syntax_vim += [ftpy] endif +endfunction + +for s:type in g:rmd_fenced_languages + call IncludeLanguage(s:type) endfor unlet! s:type +function CheckRmdFencedLanguages() + let alines = getline(1, '$') + call filter(alines, "v:val =~ '^```{'") + call map(alines, "substitute(v:val, '^```{', '', '')") + call map(alines, "substitute(v:val, '\\W.*', '', '')") + for tpy in alines + if len(tpy) == 0 + continue + endif + let has_lng = 0 + for lng in g:rmd_fenced_languages + if tpy == lng + let has_lng = 1 + continue + endif + endfor + if has_lng == 0 + let g:rmd_fenced_languages += [tpy] + call IncludeLanguage(tpy) + endif + endfor +endfunction + +if g:rmd_dynamic_fenced_languages + call CheckRmdFencedLanguages() + augroup RmdSyntax + autocmd! + autocmd BufWritePost call CheckRmdFencedLanguages() + augroup END +endif + " Step_4: Highlight code recognized by pandoc but not defined in pandoc.vim yet: syn match pandocDivBegin '^:::\+ {.\{-}}' contains=pandocHeaderAttr syn match pandocDivEnd '^:::\+$' diff --git a/runtime/syntax/swayconfig.vim b/runtime/syntax/swayconfig.vim index 290e8cc1ac..7b1c889d6d 100644 --- a/runtime/syntax/swayconfig.vim +++ b/runtime/syntax/swayconfig.vim @@ -1,10 +1,9 @@ " Vim syntax file -" Language: sway window manager config -" Original Author: Josef Litos +" Language: sway config file +" Original Author: Josef Litos (JosefLitos/i3config.vim) " Maintainer: James Eapen -" Version: 0.2.2 -" Reference version (JosefLitos/i3config.vim): 1.8.1 -" Last Change: 2023-09-12 +" Version: 1.0.0 +" Last Change: 2023-09-14 " References: " http://i3wm.org/docs/userguide.html#configuring @@ -20,9 +19,12 @@ endif runtime! syntax/i3config.vim " i3 extensions -syn match i3ConfigSet /^\s*set \$\w\+ .*$/ contains=i3ConfigVariable,i3ConfigSetKeyword,i3ConfigColor,i3ConfigString,i3ConfigNoStartupId,i3ConfigNumber,swayConfigOutputCommand,i3ConfigShCommand,i3ConfigShDelim,i3ConfigShParam,i3ConfigShOper +syn keyword i3ConfigActionKeyword opacity urgent shortcuts_inhibitor splitv splith splitt contained +syn keyword i3ConfigOption set plus minus allow deny csd v h t contained -syn keyword i3ConfigActionKeyword opacity contained +syn keyword i3ConfigConditionProp app_id pid shell contained + +syn keyword i3ConfigWorkspaceDir prev_on_output next_on_output contained syn keyword swayConfigBindKeyword bindswitch bindgesture contained syn match i3ConfigBindArgument /--\(locked\|to-code\|no-repeat\|input-device=[:0-9a-zA-Z_/-]\+\|no-warn\)/ contained @@ -31,6 +33,8 @@ syn region i3ConfigBind start=/^\s*bind\(switch\|gesture\) / skip=/\\$/ end=/$/ syn match swayConfigBindBlockHeader /^\s*bind\(sym\|code\) .*{$/ contained contains=i3ConfigBindKeyword,i3ConfigBindArgument,i3ConfigParen syn match swayConfigBindBlockCombo /^\s\+\(--[a-z-]\+ \)*[$a-zA-Z0-9_+]\+ [a-z[]\@=/ contained contains=i3ConfigBindArgument,i3ConfigBindCombo syn region i3ConfigBind start=/^\s*bind\(sym\|code\) .*{$/ end=/^\s*}$/ contains=swayConfigBindBlockHeader,swayConfigBindBlockCombo,i3ConfigCriteria,i3ConfigAction,i3ConfigSeparator,i3ConfigActionKeyword,i3ConfigOption,i3ConfigString,i3ConfigNumber,i3ConfigVariable,i3ConfigBoolean,i3ConfigComment,i3ConfigParen fold keepend extend +" fix for extra long bindsym blocks that would be parsed incorrectly when scrolling up +syn region i3ConfigBlockOrphan start=/^\s\+\S/ skip=/^\s\|^$/ end=/^}\?/ contains=swayConfigBindBlockCombo,i3ConfigCriteria,i3ConfigAction,i3ConfigSeparator,i3ConfigActionKeyword,i3ConfigOption,i3ConfigString,i3ConfigNumber,i3ConfigVariable,i3ConfigBoolean,i3ConfigComment,i3ConfigParen keepend extend syn keyword i3ConfigClientOpts focused_tab_title contained @@ -39,16 +43,22 @@ syn region swayConfigExecBlock start=/exec\(_always\)\? {/ end=/^}$/ contains=i3 syn keyword swayConfigFloatingModifierOpts normal inverse contained syn match i3ConfigKeyword /^floating_modifier [$a-zA-Z0-9+]\+ \(normal\|inverse\)$/ contains=i3ConfigVariable,i3ConfigBindModkey,swayConfigFloatingModifierOpts -syn match i3ConfigEdge /^hide_edge_borders\( --i3\)\? \(none\|vertical\|horizontal\|both\|smart\|smart_no_gaps\)\s\?$/ contains=i3ConfigEdgeKeyword,i3ConfigShParam +syn match i3ConfigKeyword /^hide_edge_borders --i3 \w*$/ contains=i3ConfigEdgeKeyword,i3ConfigShParam -syn keyword i3ConfigBarBlockKeyword swaybar_command gaps height pango_markup status_edge_padding status_padding wrap_scroll tray_bindcode tray_bindsym icon_theme contained +syn keyword i3ConfigBarOpts swaybar_command gaps height pango_markup status_edge_padding status_padding wrap_scroll tray_bindcode tray_bindsym icon_theme contained +syn keyword i3ConfigBarOptVals overlay contained syn keyword i3ConfigExecActionKeyword swaymsg contained " Sway-only options " Xwayland syn keyword swayConfigXOpt enable disable force contained -syn match i3ConfigKeyword /^xwayland .*$/ contains=swayConfigXOpt +syn match i3ConfigKeyword /^xwayland \w*$/ contains=swayConfigXOpt + +" Inhibit idle +syn keyword swayConfigInhibitKeyword inhibit_idle contained +syn keyword swayConfigInhibitOpts focus fullscreen open none visible contained +syn match i3ConfigAction /inhibit_idle \w*/ contained contains=swayConfigInhibitKeyword,swayConfigInhibitOpts " Bindswitch syn match swayConfigBindswitchArgument /--\(locked\|no-warn\|reload\)/ contained @@ -64,65 +74,77 @@ syn keyword swayConfigBindgestureDir up down left right inward outward clockwise syn match swayConfigBindgesture /\(hold\(:[1-5]\)\?\|swipe\(:[3-5]\)\?\(:up\|:down\|:left\|:right\)\?\|pinch\(:[2-5]\)\?:\(+\?\(inward\|outward\|clockwise\|counterclockwise\|up\|down\|left\|right\)\)\+\) / contained contains=i3ConfigNumber,swayConfigBindgestureType,i3ConfigColonOperator,swayConfigBindgestureDir,i3ConfigBindModifier syn region i3ConfigBind start=/^\s*bindgesture\s\+.*{$/ end=/^\s*}$/ contains=swayConfigBindKeyword,swayConfigBindgesture,swayConfigBindgestureArgument,i3ConfigCriteria,i3ConfigAction,i3ConfigSeparator,i3ConfigActionKeyword,i3ConfigOption,i3ConfigString,i3ConfigNumber,i3ConfigVariable,i3ConfigBoolean,i3ConfigParen fold keepend extend +" Tiling drag threshold +syn match i3ConfigKeyword /^tiling_drag_threshold \d\+$/ contains=i3ConfigNumber + " Titlebar commands syn match i3ConfigKeyword /^titlebar_border_thickness \(\d\+\|\$\S\+\)$/ contains=i3ConfigNumber,i3ConfigVariable syn match i3ConfigKeyword /^titlebar_padding \(\d\+\|\$\S\+\)\( \d\+\)\?$/ contains=i3ConfigNumber,i3ConfigVariable syn match swayConfigDeviceOps /[*,:;]/ contained -" Output monitors -syn keyword swayConfigOutputKeyword output contained -syn keyword swayConfigOutputOpts mode resolution res modeline position pos scale scale_filter subpixel background bg transform disable enable power dpms max_render_time adaptive_sync render_bit_depth contained -syn keyword swayConfigOutputOptVals linear nearest smart rgb bgr vrgb vbgr none normal flipped fill stretch fit center tile solid_color clockwise anticlockwise toggle contained -syn match swayConfigOutputFPS /@[0-9.]\+Hz/ contained -syn match swayConfigOutputMode / [0-9]\+x[0-9]\+\(@[0-9.]\+Hz\)\?/ contained contains=swayConfigOutputFPS,i3ConfigNumber -syn region i3ConfigAction start=/output/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps keepend -syn region swayConfigOutput start=/^output/ skip=/\\$/ end=/$/ contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps keepend -syn region swayConfigOutput start=/^output .* {$/ end=/}$/ contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps,i3ConfigParen keepend extend - " Input devices syn keyword swayConfigInputKeyword input contained +syn keyword swayConfigInputType touchpad pointer keyboard touch tablet_tool tablet_pad switch contained +syn match swayConfigInputTypePair /\/ contained contains=i3ConfigColonOperator,swayConfigInputType +syn region swayConfigInputStart start=/^input / end=/\s/ contained contains=swayConfigInputKeyword,swayConfigInputTypePair,i3ConfigString keepend extend syn keyword swayConfigInputOpts xkb_layout xkb_variant xkb_rules xkb_switch_layout xkb_numlock xkb_file xkb_capslock xkb_model repeat_delay repeat_rate map_to_output map_to_region map_from_region tool_mode accel_profile dwt dwtp drag_lock drag click_method middle_emulation tap events calibration_matrix natural_scroll left_handed pointer_accel scroll_button scroll_factor scroll_method tap_button_map contained -syn keyword swayConfigInputOptVals absolute relative adaptive flat none button_areas clickfinger toggle two_finger edge on_button_down lrm lmr contained -syn match swayConfigColonPairVal /:[0-9a-z_-]\+/ contained contains=i3ConfigColonOperator -syn match swayConfigColonPair /[a-z]\+:[0-9a-z_-]\+/ contained contains=swayConfigColonPairVal -syn match swayConfigInputXkbOpts /xkb_options \([a-z]\+:[0-9a-z_-]\+,\?\)\+/ contained contains=swayConfigColonPair,swayConfigDeviceOps -syn region i3ConfigAction start=/input/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigInputKeyword,swayConfigColonPair,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigBoolean,swayConfigDeviceOps keepend -syn region i3ConfigInput start=/^input/ skip=/\\$/ end=/$/ contains=swayConfigInputKeyword,swayConfigColonPair,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigBoolean,swayConfigDeviceOps keepend -syn region i3ConfigInput start=/^input .* {/ end=/}$/ contains=swayConfigInputKeyword,swayConfigColonPair,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigBoolean,swayConfigDeviceOps,i3ConfigParen keepend extend +syn keyword swayConfigInputOptVals absolute relative adaptive flat none button_areas clickfinger toggle two_finger edge on_button_down lrm lmr next prev pen eraser brush pencil airbrush disabled_on_external_mouse disable contained +syn match swayConfigXkbOptsPairVal /:[0-9a-z_-]\+/ contained contains=i3ConfigColonOperator +syn match swayConfigXkbOptsPair /[a-z]\+:[0-9a-z_-]\+/ contained contains=swayConfigXkbOptsPairVal +syn match swayConfigInputXkbOpts /xkb_options \([a-z]\+:[0-9a-z_-]\+,\?\)\+/ contained contains=swayConfigXkbOptsPair,swayConfigDeviceOps +syn region i3ConfigAction start=/input/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigInputStart,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigBoolean,swayConfigDeviceOps keepend transparent +syn region i3ConfigInput start=/^input/ skip=/\\$/ end=/$/ contains=swayConfigInputStart,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigBoolean,swayConfigDeviceOps keepend +syn region i3ConfigInput start=/^input .* {/ end=/}$/ contains=swayConfigInputStart,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigBoolean,swayConfigDeviceOps,i3ConfigParen keepend extend " Seat syn keyword swayConfigSeatKeyword seat contained syn keyword swayConfigSeatOpts attach cursor fallback hide_cursor idle_inhibit idle_wake keyboard_grouping shortcuts_inhibitor pointer_constraint xcursor_theme contained syn match swayConfigSeatOptVals /when-typing/ contained syn keyword swayConfigSeatOptVals move set press release none smart activate deactivate toggle escape enable disable contained -syn region i3ConfigAction start=/seat/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps keepend -syn region swayConfigSeat start=/seat/ skip=/\\$/ end=/$/ contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps keepend -syn region swayConfigSeat start=/seat .* {$/ end=/}$/ contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps,i3ConfigParen keepend extend +syn region i3ConfigAction start=/seat/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps,swayConfigInputType keepend transparent +syn region swayConfigSeat start=/seat/ skip=/\\$/ end=/$/ contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps,swayConfigInputType keepend +syn region swayConfigSeat start=/seat .* {$/ end=/}$/ contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps,i3ConfigParen,swayConfigInputType keepend extend + +" Output monitors +syn keyword swayConfigOutputKeyword output contained +syn keyword swayConfigOutputOpts mode resolution res modeline position pos scale scale_filter subpixel background bg transform disable enable power dpms max_render_time adaptive_sync render_bit_depth contained +syn keyword swayConfigOutputOptVals linear nearest smart rgb bgr vrgb vbgr none normal flipped fill stretch fit center tile solid_color clockwise anticlockwise toggle contained +syn match swayConfigOutputOptVals /--custom\|flipped-\(90\|180\|270\)/ contained +syn match swayConfigOutputFPS /@[0-9.]\+Hz/ contained +syn match swayConfigOutputMode / [0-9]\+x[0-9]\+\(@[0-9.]\+Hz\)\?/ contained contains=swayConfigOutputFPS +syn region i3ConfigAction start=/output/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps keepend transparent +syn region swayConfigOutput start=/^output/ skip=/\\$/ end=/$/ contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps keepend +syn region swayConfigOutput start=/^output .* {$/ end=/}$/ contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps,i3ConfigParen keepend extend " Define the highlighting. -hi def link swayConfigFloatingModifierOpts i3ConfigOption -hi def link swayConfigBindKeyword i3ConfigBindKeyword -hi def link swayConfigXOpt i3ConfigOption -hi def link swayConfigBindswitchArgument i3ConfigBindArgument -hi def link swayConfigBindswitchType i3ConfigMoveType -hi def link swayConfigBindswitchState i3ConfigMoveDir -hi def link swayConfigBindgestureArgument i3ConfigBindArgument -hi def link swayConfigBindgestureType i3ConfigMoveType -hi def link swayConfigBindgestureDir i3ConfigMoveDir -hi def link swayConfigDeviceOps i3ConfigOperator -hi def link swayConfigOutputKeyword i3ConfigCommand -hi def link swayConfigOutputOptVals i3ConfigOption -hi def link swayConfigOutputOpts i3ConfigOption -hi def link swayConfigOutputFPS Constant -hi def link swayConfigInputKeyword i3ConfigCommand -hi def link swayConfigInputOptVals i3ConfigShParam -hi def link swayConfigInputOpts i3ConfigOption -hi def link swayConfigInputXkbOpts i3ConfigOption -hi def link swayConfigColonPairVal i3ConfigString -hi def link swayConfigColonPair i3ConfigShParam -hi def link swayConfigSeatKeyword i3ConfigCommand -hi def link swayConfigSeatOptVals i3ConfigOption -hi def link swayConfigSeatOpts i3ConfigOption +hi def link swayConfigFloatingModifierOpts i3ConfigOption +hi def link swayConfigBindKeyword i3ConfigBindKeyword +hi def link swayConfigXOpt i3ConfigOption +hi def link swayConfigInhibitKeyword i3ConfigCommand +hi def link swayConfigInhibitOpts i3ConfigOption +hi def link swayConfigBindswitchArgument i3ConfigBindArgument +hi def link swayConfigBindswitchType i3ConfigMoveType +hi def link swayConfigBindswitchState i3ConfigMoveDir +hi def link swayConfigBindgestureArgument i3ConfigBindArgument +hi def link swayConfigBindgestureType i3ConfigMoveType +hi def link swayConfigBindgestureDir i3ConfigMoveDir +hi def link swayConfigDeviceOps i3ConfigOperator +hi def link swayConfigInputKeyword i3ConfigCommand +hi def link swayConfigInputType i3ConfigMoveType +hi def link swayConfigInputTypePair i3ConfigMoveDir +hi def link swayConfigInputOptVals i3ConfigShParam +hi def link swayConfigInputOpts i3ConfigOption +hi def link swayConfigXkbOptsPairVal i3ConfigString +hi def link swayConfigXkbOptsPair i3ConfigShParam +hi def link swayConfigInputXkbOpts i3ConfigOption +hi def link swayConfigSeatKeyword i3ConfigCommand +hi def link swayConfigSeatOptVals swayConfigInputOptVals +hi def link swayConfigSeatOpts swayConfigInputOpts +hi def link swayConfigOutputKeyword i3ConfigCommand +hi def link swayConfigOutputOptVals swayConfigInputOptVals +hi def link swayConfigOutputOpts swayConfigInputOpts +hi def link swayConfigOutputFPS Constant +hi def link swayConfigOutputMode i3ConfigNumber let b:current_syntax = "swayconfig" diff --git a/src/autocmd.c b/src/autocmd.c index 08cbdaf3aa..e9cf71857f 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -2738,6 +2738,16 @@ get_event_name(expand_T *xp UNUSED, int idx) return (char_u *)event_names[idx - augroups.ga_len].name; } +/* + * Function given to ExpandGeneric() to obtain the list of event names. Don't + * include groups. + */ + char_u * +get_event_name_no_group(expand_T *xp UNUSED, int idx) +{ + return (char_u *)event_names[idx].name; +} + #if defined(FEAT_EVAL) || defined(PROTO) /* diff --git a/src/clipboard.c b/src/clipboard.c index 15c738939a..c8de3d028c 100644 --- a/src/clipboard.c +++ b/src/clipboard.c @@ -1270,6 +1270,7 @@ did_set_clipboard(optset_T *args UNUSED) for (p = p_cb; *p != NUL; ) { + // Note: Keep this in sync with p_cb_values. if (STRNCMP(p, "unnamed", 7) == 0 && (p[7] == ',' || p[7] == NUL)) { new_unnamed |= CLIP_UNNAMED; diff --git a/src/cmdexpand.c b/src/cmdexpand.c index 0472dde9e5..292df793dc 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -15,9 +15,6 @@ static int cmd_showtail; // Only show path tail in lists ? -static int ExpandGeneric(char_u *pat, expand_T *xp, regmatch_T *regmatch, - char_u ***matches, int *numMatches, - char_u *((*func)(expand_T *, int)), int escaped); static int ExpandFromContext(expand_T *xp, char_u *, char_u ***, int *, int); static char_u *showmatches_gettail(char_u *s); static int expand_showtail(expand_T *xp); @@ -54,6 +51,8 @@ cmdline_fuzzy_completion_supported(expand_T *xp) && xp->xp_context != EXPAND_FILETYPE && xp->xp_context != EXPAND_HELP && xp->xp_context != EXPAND_OLD_SETTING + && xp->xp_context != EXPAND_STRING_SETTING + && xp->xp_context != EXPAND_SETTING_SUBTRACT && xp->xp_context != EXPAND_OWNSYNTAX && xp->xp_context != EXPAND_PACKADD && xp->xp_context != EXPAND_RUNTIME @@ -696,8 +695,7 @@ win_redr_status_matches( static char_u * get_next_or_prev_match( int mode, - expand_T *xp, - char_u *orig_save) + expand_T *xp) { int findex = xp->xp_selected; int ht; @@ -757,14 +755,14 @@ get_next_or_prev_match( // When wrapping around, return the original string, set findex to -1. if (findex < 0) { - if (orig_save == NULL) + if (xp->xp_orig == NULL) findex = xp->xp_numfiles - 1; else findex = -1; } if (findex >= xp->xp_numfiles) { - if (orig_save == NULL) + if (xp->xp_orig == NULL) findex = 0; else findex = -1; @@ -780,7 +778,7 @@ get_next_or_prev_match( xp->xp_selected = findex; if (findex == -1) - return vim_strsave(orig_save); + return vim_strsave(xp->xp_orig); return vim_strsave(xp->xp_files[findex]); } @@ -915,8 +913,8 @@ find_longest_match(expand_T *xp, int options) * Return NULL for failure. * * "orig" is the originally expanded string, copied to allocated memory. It - * should either be kept in orig_save or freed. When "mode" is WILD_NEXT or - * WILD_PREV "orig" should be NULL. + * should either be kept in "xp->xp_orig" or freed. When "mode" is WILD_NEXT + * or WILD_PREV "orig" should be NULL. * * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode" * is WILD_EXPAND_FREE or WILD_ALL. @@ -956,7 +954,6 @@ ExpandOne( int mode) { char_u *ss = NULL; - static char_u *orig_save = NULL; // kept value of orig int orig_saved = FALSE; int i; long_u len; @@ -964,13 +961,13 @@ ExpandOne( // first handle the case of using an old match if (mode == WILD_NEXT || mode == WILD_PREV || mode == WILD_PAGEUP || mode == WILD_PAGEDOWN) - return get_next_or_prev_match(mode, xp, orig_save); + return get_next_or_prev_match(mode, xp); if (mode == WILD_CANCEL) - ss = vim_strsave(orig_save ? orig_save : (char_u *)""); + ss = vim_strsave(xp->xp_orig ? xp->xp_orig : (char_u *)""); else if (mode == WILD_APPLY) ss = vim_strsave(xp->xp_selected == -1 - ? (orig_save ? orig_save : (char_u *)"") + ? (xp->xp_orig ? xp->xp_orig : (char_u *)"") : xp->xp_files[xp->xp_selected]); // free old names @@ -978,7 +975,7 @@ ExpandOne( { FreeWild(xp->xp_numfiles, xp->xp_files); xp->xp_numfiles = -1; - VIM_CLEAR(orig_save); + VIM_CLEAR(xp->xp_orig); // The entries from xp_files may be used in the PUM, remove it. if (compl_match_array != NULL) @@ -991,8 +988,8 @@ ExpandOne( if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL) { - vim_free(orig_save); - orig_save = orig; + vim_free(xp->xp_orig); + xp->xp_orig = orig; orig_saved = TRUE; ss = ExpandOne_start(mode, xp, str, options); @@ -1045,7 +1042,7 @@ ExpandOne( if (mode == WILD_EXPAND_FREE || mode == WILD_ALL) ExpandCleanup(xp); - // Free "orig" if it wasn't stored in "orig_save". + // Free "orig" if it wasn't stored in "xp->xp_orig". if (!orig_saved) vim_free(orig); @@ -1075,6 +1072,7 @@ ExpandCleanup(expand_T *xp) FreeWild(xp->xp_numfiles, xp->xp_files); xp->xp_numfiles = -1; } + VIM_CLEAR(xp->xp_orig); } /* @@ -3106,6 +3104,10 @@ ExpandFromContext( if (xp->xp_context == EXPAND_SETTINGS || xp->xp_context == EXPAND_BOOL_SETTINGS) ret = ExpandSettings(xp, ®match, pat, numMatches, matches, fuzzy); + else if (xp->xp_context == EXPAND_STRING_SETTING) + ret = ExpandStringSetting(xp, ®match, numMatches, matches); + else if (xp->xp_context == EXPAND_SETTING_SUBTRACT) + ret = ExpandSettingSubtract(xp, ®match, numMatches, matches); else if (xp->xp_context == EXPAND_MAPPINGS) ret = ExpandMappings(pat, ®match, numMatches, matches); #if defined(FEAT_EVAL) @@ -3134,7 +3136,7 @@ ExpandFromContext( * * Returns OK when no problems encountered, FAIL for error (out of memory). */ - static int + int ExpandGeneric( char_u *pat, expand_T *xp, @@ -3239,6 +3241,7 @@ ExpandGeneric( // applies to the completion context. Menus and scriptnames should be kept // in the specified order. if (!fuzzy && xp->xp_context != EXPAND_MENUNAMES + && xp->xp_context != EXPAND_STRING_SETTING && xp->xp_context != EXPAND_MENUS && xp->xp_context != EXPAND_SCRIPTNAMES) sort_matches = TRUE; diff --git a/src/diff.c b/src/diff.c index 1873767106..158870402b 100644 --- a/src/diff.c +++ b/src/diff.c @@ -2266,6 +2266,7 @@ diffopt_changed(void) p = p_dip; while (*p != NUL) { + // Note: Keep this in sync with p_dip_values if (STRNCMP(p, "filler", 6) == 0) { p += 6; @@ -2343,6 +2344,7 @@ diffopt_changed(void) } else if (STRNCMP(p, "algorithm:", 10) == 0) { + // Note: Keep this in sync with p_dip_algorithm_values. p += 10; if (STRNCMP(p, "myers", 5) == 0) { diff --git a/src/errors.h b/src/errors.h index 6b1626d85e..675ec145ec 100644 --- a/src/errors.h +++ b/src/errors.h @@ -2401,6 +2401,7 @@ EXTERN char e_io_file_requires_name_to_be_set[] #ifdef FEAT_EVAL EXTERN char e_invalid_callback_argument[] INIT(= N_("E921: Invalid callback argument")); +// E922 unused EXTERN char e_second_argument_of_function_must_be_list_or_dict[] INIT(= N_("E923: Second argument of function() must be a list or a dict")); #endif @@ -2795,7 +2796,7 @@ EXTERN char e_no_white_space_allowed_after_dot[] INIT(= N_("E1074: No white space allowed after dot")); EXTERN char e_namespace_not_supported_str[] INIT(= N_("E1075: Namespace not supported: %s")); -// E1076 was deleted +// E1076 unused (was deleted) EXTERN char e_missing_argument_type_for_str[] INIT(= N_("E1077: Missing argument type for %s")); #endif @@ -2863,6 +2864,7 @@ PLURAL_MSG(e_one_argument_too_many, "E1106: One argument too many", EXTERN char e_string_list_dict_or_blob_required[] INIT(= N_("E1107: String, List, Dict or Blob required")); +// E1108 unused EXTERN char e_list_item_nr_is_not_list[] INIT(= N_("E1109: List item %d is not a List")); EXTERN char e_list_item_nr_does_not_contain_3_numbers[] @@ -3215,6 +3217,7 @@ EXTERN char e_list_dict_blob_or_string_required_for_argument_nr[] INIT(= N_("E1251: List, Dictionary, Blob or String required for argument %d")); EXTERN char e_string_list_or_blob_required_for_argument_nr[] INIT(= N_("E1252: String, List or Blob required for argument %d")); +// E1253 unused EXTERN char e_cannot_use_script_variable_in_for_loop[] INIT(= N_("E1254: Cannot use script variable in for loop")); #endif @@ -3528,19 +3531,32 @@ EXTERN char e_class_method_str_accessible_only_using_class_str[] INIT(= N_("E1385: Class method \"%s\" accessible only using class \"%s\"")); EXTERN char e_object_method_str_accessible_only_using_object_str[] INIT(= N_("E1386: Object method \"%s\" accessible only using class \"%s\" object")); -#endif +EXTERN char e_public_variable_not_supported_in_interface[] + INIT(= N_("E1387: Public variable not supported in an interface")); +EXTERN char e_public_keyword_not_supported_for_method[] + INIT(= N_("E1388: Public keyword not supported for a method")); +EXTERN char e_missing_name_after_implements[] + INIT(= N_("E1389: Missing name after implements")); +EXTERN char e_cannot_use_an_object_variable_except_with_the_new_method_str[] + INIT(= N_("E1390: Cannot use an object variable \"this.%s\" except with the \"new\" method")); +EXTERN char e_cannot_lock_object_variable_str[] + INIT(= N_("E1391: Cannot (un)lock variable \"%s\" in class \"%s\"")); +EXTERN char e_cannot_lock_class_variable_str[] + INIT(= N_("E1392: Cannot (un)lock class variable \"%s\" in class \"%s\"")); +#endif +// E1393 - E1499 unused (reserved for Vim9 class support) EXTERN char e_cannot_mix_positional_and_non_positional_str[] - INIT(= N_("E1400: Cannot mix positional and non-positional arguments: %s")); + INIT(= N_("E1500: Cannot mix positional and non-positional arguments: %s")); EXTERN char e_fmt_arg_nr_unused_str[] - INIT(= N_("E1401: format argument %d unused in $-style format: %s")); + INIT(= N_("E1501: format argument %d unused in $-style format: %s")); EXTERN char e_positional_num_field_spec_reused_str_str[] - INIT(= N_("E1402: Positional argument %d used as field width reused as different type: %s/%s")); + INIT(= N_("E1502: Positional argument %d used as field width reused as different type: %s/%s")); EXTERN char e_positional_nr_out_of_bounds_str[] - INIT(= N_("E1403: Positional argument %d out of bounds: %s")); + INIT(= N_("E1503: Positional argument %d out of bounds: %s")); EXTERN char e_positional_arg_num_type_inconsistent_str_str[] - INIT(= N_("E1404: Positional argument %d type used inconsistently: %s/%s")); + INIT(= N_("E1504: Positional argument %d type used inconsistently: %s/%s")); EXTERN char e_invalid_format_specifier_str[] - INIT(= N_("E1405: Invalid format specifier: %s")); + INIT(= N_("E1505: Invalid format specifier: %s")); +// E1506 - E1519 unused EXTERN char e_aptypes_is_null_nr_str[] - INIT(= "E1408: Internal error: ap_types or ap_types[idx] is NULL: %d: %s"); -// E1387 - E1399 unused + INIT(= "E1520: Internal error: ap_types or ap_types[idx] is NULL: %d: %s"); diff --git a/src/eval.c b/src/eval.c index eaca2f5fa0..ae48a6085d 100644 --- a/src/eval.c +++ b/src/eval.c @@ -985,6 +985,62 @@ eval_foldexpr(win_T *wp, int *cp) } #endif +/* + * Fill in "lp" using "root". This is used in a special case when + * "get_lval()" parses a bare word when "lval_root" is not NULL. + * + * This is typically called with "lval_root" as "root". For a class, find + * the name from lp in the class from root, fill in lval_T if found. For a + * complex type, list/dict use it as the result; just put the root into + * ll_tv. + * + * "lval_root" is a hack used during run-time/instr-execution to provide the + * starting point for "get_lval()" to traverse a chain of indexes. In some + * cases get_lval sees a bare name and uses this function to populate the + * lval_T. + * + * For setting up "lval_root" (currently only used with lockvar) + * compile_lock_unlock - pushes object on stack (which becomes lval_root) + * execute_instructions: ISN_LOCKUNLOCK - sets lval_root from stack. + */ + static void +get_lval_root(lval_T *lp, typval_T *root, int is_arg) +{ +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: get_lvalroot(): name %s", lp->ll_name); +#endif + if (!is_arg && root->v_type == VAR_CLASS) + { + if (root->vval.v_class != NULL) + { + // Special special case. Look for a bare class variable reference. + class_T *cl = root->vval.v_class; + int m_idx; + ocmember_T *m = class_member_lookup(cl, lp->ll_name, + lp->ll_name_end - lp->ll_name, &m_idx); + if (m != NULL) + { + // Assuming "inside class" since bare reference. + lp->ll_class = root->vval.v_class; + lp->ll_oi = m_idx; + lp->ll_valtype = m->ocm_type; + lp->ll_tv = &lp->ll_class->class_members_tv[m_idx]; +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: get_lvalroot() class member: name %s", + lp->ll_name); +#endif + return; + } + } + } + +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: get_lvalroot() any type"); +#endif + lp->ll_tv = root; + lp->ll_is_root = TRUE; +} + /* * Get an lval: variable, Dict item or List item that can be assigned a value * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", @@ -1028,6 +1084,11 @@ get_lval( int writing = 0; int vim9script = in_vim9script(); +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: get_lval(): name %s, lval_root %p", + name, (void*)lval_root); +#endif + // Clear everything in "lp". CLEAR_POINTER(lp); @@ -1122,6 +1183,7 @@ get_lval( return NULL; lp->ll_name_end = tp; } + // TODO: check inside class? } } if (lp->ll_name == NULL) @@ -1157,7 +1219,11 @@ get_lval( // Without [idx] or .key we are done. if ((*p != '[' && *p != '.')) + { + if (lval_root != NULL) + get_lval_root(lp, lval_root, lval_root_is_arg); return p; + } if (vim9script && lval_root != NULL) { @@ -1220,8 +1286,7 @@ get_lval( int r = OK; if (v_type == VAR_LIST && lp->ll_tv->vval.v_list == NULL) r = rettv_list_alloc(lp->ll_tv); - else if (v_type == VAR_BLOB - && lp->ll_tv->vval.v_blob == NULL) + else if (v_type == VAR_BLOB && lp->ll_tv->vval.v_blob == NULL) r = rettv_blob_alloc(lp->ll_tv); if (r == FAIL) return NULL; @@ -1351,6 +1416,8 @@ get_lval( } } lp->ll_list = NULL; + lp->ll_object = NULL; + lp->ll_class = NULL; // a NULL dict is equivalent with an empty dict if (lp->ll_tv->vval.v_dict == NULL) @@ -1483,6 +1550,8 @@ get_lval( clear_tv(&var1); lp->ll_dict = NULL; + lp->ll_object = NULL; + lp->ll_class = NULL; lp->ll_list = lp->ll_tv->vval.v_list; lp->ll_li = check_range_index_one(lp->ll_list, &lp->ll_n1, (flags & GLV_ASSIGN_WITH_OP) == 0, quiet); @@ -1517,10 +1586,22 @@ get_lval( } else // v_type == VAR_CLASS || v_type == VAR_OBJECT { - class_T *cl = (v_type == VAR_OBJECT - && lp->ll_tv->vval.v_object != NULL) - ? lp->ll_tv->vval.v_object->obj_class - : lp->ll_tv->vval.v_class; + lp->ll_dict = NULL; + lp->ll_list = NULL; + + class_T *cl; + if (v_type == VAR_OBJECT && lp->ll_tv->vval.v_object != NULL) + { + cl = lp->ll_tv->vval.v_object->obj_class; + lp->ll_object = lp->ll_tv->vval.v_object; + } + else + { + cl = lp->ll_tv->vval.v_class; + lp->ll_object = NULL; + } + lp->ll_class = cl; + // TODO: what if class is NULL? if (cl != NULL) { @@ -1540,6 +1621,7 @@ get_lval( fp = method_lookup(cl, round == 1 ? VAR_CLASS : VAR_OBJECT, key, p - key, &m_idx); + lp->ll_oi = m_idx; if (fp != NULL) { lp->ll_ufunc = fp; @@ -1549,12 +1631,16 @@ get_lval( } } + // TODO: dont' check access if inside class + // TODO: is GLV_READ_ONLY the right thing to use + // for class/object member access? + // Probably in some cases. Need inside class check if (lp->ll_valtype == NULL) { int m_idx; - ocmember_T *om; - - om = member_lookup(cl, v_type, key, p - key, &m_idx); + ocmember_T *om + = member_lookup(cl, v_type, key, p - key, &m_idx); + lp->ll_oi = m_idx; if (om != NULL) { switch (om->ocm_access) diff --git a/src/evalvars.c b/src/evalvars.c index e1e00631c9..780953b2bb 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -2125,6 +2125,30 @@ do_unlet(char_u *name, int forceit) return FAIL; } + static void +report_lockvar_member(char *msg, lval_T *lp) +{ + int did_alloc = FALSE; + char_u *vname = (char_u *)""; + char_u *class_name = lp->ll_class != NULL + ? lp->ll_class->class_name : (char_u *)""; + if (lp->ll_name != NULL) + { + if (lp->ll_name_end == NULL) + vname = lp->ll_name; + else + { + vname = vim_strnsave(lp->ll_name, lp->ll_name_end - lp->ll_name); + if (vname == NULL) + return; + did_alloc = TRUE; + } + } + semsg(_(msg), vname, class_name); + if (did_alloc) + vim_free(vname); +} + /* * Lock or unlock variable indicated by "lp". * "deep" is the levels to go (-1 for unlimited); @@ -2143,6 +2167,10 @@ do_lock_var( int cc; dictitem_T *di; +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: do_lock_var(): name %s, is_root %d", lp->ll_name, lp->ll_is_root); +#endif + if (lp->ll_tv == NULL) { cc = *name_end; @@ -2203,10 +2231,13 @@ do_lock_var( } *name_end = cc; } - else if (deep == 0) + else if (deep == 0 && lp->ll_object == NULL && lp->ll_class == NULL) { // nothing to do } + else if (lp->ll_is_root) + // (un)lock the item. + item_lock(lp->ll_tv, deep, lock, FALSE); else if (lp->ll_range) { listitem_T *li = lp->ll_li; @@ -2222,13 +2253,57 @@ do_lock_var( else if (lp->ll_list != NULL) // (un)lock a List item. item_lock(&lp->ll_li->li_tv, deep, lock, FALSE); + else if (lp->ll_object != NULL) // This check must be before ll_class. + { + // (un)lock an object variable. + report_lockvar_member(e_cannot_lock_object_variable_str, lp); + ret = FAIL; + } + else if (lp->ll_class != NULL) + { + // (un)lock a class variable. + report_lockvar_member(e_cannot_lock_class_variable_str, lp); + ret = FAIL; + } else + { // (un)lock a Dictionary item. - item_lock(&lp->ll_di->di_tv, deep, lock, FALSE); + if (lp->ll_di == NULL) + { + emsg(_(e_dictionary_required)); + ret = FAIL; + } + else + item_lock(&lp->ll_di->di_tv, deep, lock, FALSE); + } return ret; } +#ifdef LOG_LOCKVAR + static char * +vartype_tostring(vartype_T vartype) +{ + return + vartype == VAR_BOOL ? "v_number" + : vartype == VAR_SPECIAL ? "v_number" + : vartype == VAR_NUMBER ? "v_number" + : vartype == VAR_FLOAT ? "v_float" + : vartype == VAR_STRING ? "v_string" + : vartype == VAR_BLOB ? "v_blob" + : vartype == VAR_FUNC ? "v_string" + : vartype == VAR_PARTIAL ? "v_partial" + : vartype == VAR_LIST ? "v_list" + : vartype == VAR_DICT ? "v_dict" + : vartype == VAR_JOB ? "v_job" + : vartype == VAR_CHANNEL ? "v_channel" + : vartype == VAR_INSTR ? "v_instr" + : vartype == VAR_CLASS ? "v_class" + : vartype == VAR_OBJECT ? "v_object" + : ""; +} +#endif + /* * Lock or unlock an item. "deep" is nr of levels to go. * When "check_refcount" is TRUE do not lock a list or dict with a reference @@ -2245,6 +2320,10 @@ item_lock(typval_T *tv, int deep, int lock, int check_refcount) hashitem_T *hi; int todo; +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: item_lock(): type %s", vartype_tostring(tv->v_type)); +#endif + if (recurse >= DICT_MAXNEST) { emsg(_(e_variable_nested_too_deep_for_unlock)); diff --git a/src/ex_getln.c b/src/ex_getln.c index 9486d33ed9..4f247002f2 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -2659,6 +2659,7 @@ check_opt_wim(void) for (p = p_wim; *p; ++p) { + // Note: Keep this in sync with p_wim_values. for (i = 0; ASCII_ISALPHA(p[i]); ++i) ; if (p[i] != NUL && p[i] != ',' && p[i] != ':') diff --git a/src/globals.h b/src/globals.h index a340a8623f..46c3c552a6 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1958,6 +1958,7 @@ EXTERN int timer_busy INIT(= 0); // when timer is inside vgetc() then > 0 EXTERN int input_busy INIT(= 0); // when inside get_user_input() then > 0 EXTERN typval_T *lval_root INIT(= NULL); +EXTERN int lval_root_is_arg INIT(= 0); #endif #ifdef FEAT_BEVAL_TERM diff --git a/src/highlight.c b/src/highlight.c index 626aeeff0a..547f382f83 100644 --- a/src/highlight.c +++ b/src/highlight.c @@ -3814,6 +3814,7 @@ highlight_changed(void) if (attr > HL_ALL) // Combination with ':' is not allowed. return FAIL; + // Note: Keep this in sync with expand_set_highlight(). switch (*p) { case 'b': attr |= HL_BOLD; diff --git a/src/indent.c b/src/indent.c index 3c38b4ec37..1858ecf8f3 100644 --- a/src/indent.c +++ b/src/indent.c @@ -871,6 +871,7 @@ briopt_check(win_T *wp) p = wp->w_p_briopt; while (*p != NUL) { + // Note: Keep this in sync with p_briopt_values if (STRNCMP(p, "shift:", 6) == 0 && ((p[6] == '-' && VIM_ISDIGIT(p[7])) || VIM_ISDIGIT(p[6]))) { diff --git a/src/mbyte.c b/src/mbyte.c index c4d1ddb3b8..4951f78323 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -5782,3 +5782,16 @@ f_charclass(typval_T *argvars, typval_T *rettv UNUSED) rettv->vval.v_number = mb_get_class(argvars[0].vval.v_string); } #endif + +/* + * Function given to ExpandGeneric() to obtain the possible arguments of the + * encoding options. + */ + char_u * +get_encoding_name(expand_T *xp UNUSED, int idx) +{ + if (idx >= (int)(sizeof(enc_canon_table) / sizeof(enc_canon_table[0]))) + return NULL; + + return (char_u*)enc_canon_table[idx].name; +} diff --git a/src/option.c b/src/option.c index d24da40b4c..e1e7c0c8e6 100644 --- a/src/option.c +++ b/src/option.c @@ -1650,7 +1650,7 @@ stropt_copy_value( // For MS-DOS and WIN32 backslashes before normal file name characters // are not removed, and keep backslash at start, for "\\machine\path", // but do remove it for "\\\\machine\\path". - // The reverse is found in ExpandOldSetting(). + // The reverse is found in escape_option_str_cmdline(). while (*arg != NUL && !VIM_ISWHITE(*arg)) { int i; @@ -1855,7 +1855,7 @@ stropt_get_newval( &(options[opt_idx]), OPT_GLOBAL)); else { - ++arg; // jump to after the '=' or ':' + ++arg; // joption_value2stringump to after the '=' or ':' // Set 'keywordprg' to ":help" if an empty // value was passed to :set by the user. @@ -7392,8 +7392,10 @@ set_imsearch_global(void) } static int expand_option_idx = -1; +static int expand_option_start_col = 0; static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL}; static int expand_option_flags = 0; +static int expand_option_append = FALSE; void set_context_in_set_cmd( @@ -7508,8 +7510,14 @@ set_context_in_set_cmd( } } // handle "-=" and "+=" + expand_option_append = FALSE; + int expand_option_subtract = FALSE; if ((nextchar == '-' || nextchar == '+' || nextchar == '^') && p[1] == '=') { + if (nextchar == '-') + expand_option_subtract = TRUE; + if (nextchar == '+' || nextchar == '^') + expand_option_append = TRUE; ++p; nextchar = '='; } @@ -7519,22 +7527,20 @@ set_context_in_set_cmd( xp->xp_context = EXPAND_UNSUCCESSFUL; return; } - if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL) - { - xp->xp_context = EXPAND_OLD_SETTING; - if (is_term_option) - expand_option_idx = -1; - else - expand_option_idx = opt_idx; - xp->xp_pattern = p + 1; - return; - } - xp->xp_context = EXPAND_NOTHING; - if (is_term_option || (flags & P_NUM)) - return; + + // Below are for handling expanding a specific option's value after the '=' + // or ':' + + if (is_term_option) + expand_option_idx = -1; + else + expand_option_idx = opt_idx; xp->xp_pattern = p + 1; + expand_option_start_col = (int)(p + 1 - xp->xp_line); + // Certain options currently have special case handling to reuse the + // expansion logic with other commands. #ifdef FEAT_SYN_HL if (options[opt_idx].var == (char_u *)&p_syn) { @@ -7542,7 +7548,38 @@ set_context_in_set_cmd( return; } #endif + if (options[opt_idx].var == (char_u *)&p_ft) + { + xp->xp_context = EXPAND_FILETYPE; + return; + } + // Now pick. If the option has a custom expander, use that. Otherwise, just + // fill with the existing option value. + if (expand_option_subtract) + { + xp->xp_context = EXPAND_SETTING_SUBTRACT; + return; + } + else if (expand_option_idx >= 0 && + options[expand_option_idx].opt_expand_cb != NULL) + { + xp->xp_context = EXPAND_STRING_SETTING; + } + else if (*xp->xp_pattern == NUL) + { + xp->xp_context = EXPAND_OLD_SETTING; + return; + } + else + xp->xp_context = EXPAND_NOTHING; + + if (is_term_option || (flags & P_NUM)) + return; + + // Only string options below + + // Options that have P_EXPAND are considered to all use file/dir expansion. if (flags & P_EXPAND) { p = options[opt_idx].var; @@ -7563,10 +7600,6 @@ set_context_in_set_cmd( else xp->xp_backslash = XP_BS_ONE; } - else if (p == (char_u *)&p_ft) - { - xp->xp_context = EXPAND_FILETYPE; - } else { xp->xp_context = EXPAND_FILES; @@ -7578,34 +7611,55 @@ set_context_in_set_cmd( } } - // For an option that is a list of file names, find the start of the - // last file name. - for (p = arg + STRLEN(arg) - 1; p > xp->xp_pattern; --p) + // For an option that is a list of file names, or comma/colon-separated + // values, split it by the delimiter and find the start of the current + // pattern, while accounting for backslash-escaped space/commas/colons. + // Triple-backslashed escaped file names (e.g. 'path') can also be + // delimited by space. + if ((flags & P_EXPAND) || (flags & P_COMMA) || (flags & P_COLON)) { - // count number of backslashes before ' ' or ',' - if (*p == ' ' || *p == ',') + for (p = arg + STRLEN(arg) - 1; p >= xp->xp_pattern; --p) { - s = p; - while (s > xp->xp_pattern && *(s - 1) == '\\') - --s; - if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3)) - || (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0)) + // count number of backslashes before ' ' or ',' or ':' + if (*p == ' ' || *p == ',' || + (*p == ':' && (flags & P_COLON))) { - xp->xp_pattern = p + 1; - break; + s = p; + while (s > xp->xp_pattern && *(s - 1) == '\\') + --s; + if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3)) + || (*p == ',' && (flags & P_COMMA) && ((p - s) % 1) == 0) + || (*p == ':' && (flags & P_COLON))) + { + xp->xp_pattern = p + 1; + break; + } } } + } + + // An option that is a list of single-character flags should always start + // at the end as we don't complete words. + if (flags & P_FLAGLIST) + xp->xp_pattern = arg + STRLEN(arg); + // Some options can either be using file/dir expansions, or custom value + // expansion depending on what the user typed. Unfortunately we have to + // manually handle it here to make sure we have the correct xp_context set. #ifdef FEAT_SPELL - // for 'spellsuggest' start at "file:" - if (options[opt_idx].var == (char_u *)&p_sps - && STRNCMP(p, "file:", 5) == 0) + if (options[opt_idx].var == (char_u *)&p_sps) + { + if (STRNCMP(xp->xp_pattern, "file:", 5) == 0) { - xp->xp_pattern = p + 5; - break; + xp->xp_pattern += 5; + return; + } + else if (options[expand_option_idx].opt_expand_cb != NULL) + { + xp->xp_context = EXPAND_STRING_SETTING; } -#endif } +#endif } /* @@ -7624,7 +7678,7 @@ set_context_in_set_cmd( * If 'test_only' is FALSE and 'fuzzy' is TRUE and if 'str' fuzzy matches * 'fuzzystr', then stores the match details in fuzmatch[idx] and returns TRUE. */ - static int + int match_str( char_u *str, regmatch_T *regmatch, @@ -7871,6 +7925,37 @@ ExpandSettings( return OK; } +// Escape an option value that can be used on the command-line with :set. +// Caller needs to free the returned string, unless NULL is returned. + static char_u* +escape_option_str_cmdline(char_u *var) +{ + char_u *buf; + + // A backslash is required before some characters. This is the reverse of + // what happens in do_set(). + buf = vim_strsave_escaped(var, escape_chars); + if (buf == NULL) + return NULL; + +#ifdef BACKSLASH_IN_FILENAME + // For MS-Windows et al. we don't double backslashes at the start and + // before a file name character. + // The reverse is found at stropt_copy_value(). + for (var = buf; *var != NUL; MB_PTR_ADV(var)) + if (var[0] == '\\' && var[1] == '\\' + && expand_option_idx >= 0 + && (options[expand_option_idx].flags & P_EXPAND) + && vim_isfilec(var[2]) + && (var[2] != '\\' || (var == buf && var[4] != '\\'))) + STRMOVE(var, var + 1); +#endif + return buf; +} + +/* + * Expansion handler for :set= when we just want to fill in with the existing value. + */ int ExpandOldSetting(int *numMatches, char_u ***matches) { @@ -7878,7 +7963,7 @@ ExpandOldSetting(int *numMatches, char_u ***matches) char_u *buf; *numMatches = 0; - *matches = ALLOC_ONE(char_u *); + *matches = ALLOC_MULT(char_u *, 1); if (*matches == NULL) return FAIL; @@ -7899,33 +7984,210 @@ ExpandOldSetting(int *numMatches, char_u ***matches) else if (var == NULL) var = (char_u *)""; - // A backslash is required before some characters. This is the reverse of - // what happens in do_set(). - buf = vim_strsave_escaped(var, escape_chars); - + buf = escape_option_str_cmdline(var); if (buf == NULL) { VIM_CLEAR(*matches); return FAIL; } -#ifdef BACKSLASH_IN_FILENAME - // For MS-Windows et al. we don't double backslashes at the start and - // before a file name character. - for (var = buf; *var != NUL; MB_PTR_ADV(var)) - if (var[0] == '\\' && var[1] == '\\' - && expand_option_idx >= 0 - && (options[expand_option_idx].flags & P_EXPAND) - && vim_isfilec(var[2]) - && (var[2] != '\\' || (var == buf && var[4] != '\\'))) - STRMOVE(var, var + 1); -#endif - - *matches[0] = buf; + (*matches)[0] = buf; *numMatches = 1; return OK; } +/* + * Expansion handler for :set=/:set+= when the option has a custom expansion handler. + */ + int +ExpandStringSetting( + expand_T *xp, + regmatch_T *regmatch, + int *numMatches, + char_u ***matches) +{ + char_u *var = NULL; // init for GCC + char_u *buf; + + if (expand_option_idx < 0 || + options[expand_option_idx].opt_expand_cb == NULL) + { + // Not supposed to reach this. This function is only for options with + // custom expansion callbacks. + return FAIL; + } + + optexpand_T args; + args.oe_varp = get_varp_scope(&options[expand_option_idx], expand_option_flags); + args.oe_append = expand_option_append; + args.oe_regmatch = regmatch; + args.oe_xp = xp; + args.oe_set_arg = xp->xp_line + expand_option_start_col; + args.oe_include_orig_val = + !expand_option_append && + (*args.oe_set_arg == NUL); + + // Retrieve the existing value, but escape it as a reverse of setting it. + // We technically only need to do this when oe_append or + // oe_include_orig_val is true. + option_value2string(&options[expand_option_idx], expand_option_flags); + var = NameBuff; + buf = escape_option_str_cmdline(var); + if (buf == NULL) + return FAIL; + + args.oe_opt_value = buf; + + int num_ret = options[expand_option_idx].opt_expand_cb(&args, numMatches, matches); + + vim_free(buf); + return num_ret; +} + +/* + * Expansion handler for :set-= + */ + int +ExpandSettingSubtract( + expand_T *xp, + regmatch_T *regmatch, + int *numMatches, + char_u ***matches) +{ + if (expand_option_idx < 0) + // term option + return ExpandOldSetting(numMatches, matches); + + char_u *option_val = *(char_u**)get_option_varp_scope( + expand_option_idx, expand_option_flags); + + long_u option_flags = options[expand_option_idx].flags; + + if (option_flags & P_NUM) + return ExpandOldSetting(numMatches, matches); + else if (option_flags & P_COMMA) + { + // Split the option by comma, then present each option to the user if + // it matches the pattern. + // This condition needs to go first, because 'whichwrap' has both + // P_COMMA and P_FLAGLIST. + garray_T ga; + + char_u *item; + char_u *option_copy; + char_u *next_val; + char_u *comma; + + if (*option_val == NUL) + return FAIL; + + // Make a copy as we need to inject null characters destructively. + option_copy = vim_strsave(option_val); + if (option_copy == NULL) + return FAIL; + next_val = option_copy; + + ga_init2(&ga, sizeof(char_u *), 10); + + do + { + item = next_val; + comma = vim_strchr(next_val, ','); + while (comma != NULL && comma != next_val && *(comma - 1) == '\\') + { + // "\," is interpreted as a literal comma rather than option + // separator when reading options in copy_option_part(). Skip + // it. + comma = vim_strchr(comma + 1, ','); + } + if (comma != NULL) + { + *comma = NUL; // null-terminate this value, required by later functions + next_val = comma + 1; + } + else + next_val = NULL; + + if (*item == NUL) + // empty value, don't add to list + continue; + + if (!vim_regexec(regmatch, item, (colnr_T)0)) + continue; + + char_u *buf = escape_option_str_cmdline(item); + if (buf == NULL) + { + vim_free(option_copy); + ga_clear_strings(&ga); + return FAIL; + } + if (ga_add_string(&ga, buf) != OK) + { + vim_free(buf); + break; + } + } while (next_val != NULL); + + vim_free(option_copy); + + *matches = ga.ga_data; + *numMatches = ga.ga_len; + return OK; + } + else if (option_flags & P_FLAGLIST) + { + // Only present the flags that are set on the option as the other flags + // are not meaningful to do set-= on. + + if (*xp->xp_pattern != NUL) + { + // Don't suggest anything if cmdline is non-empty. Vim's set-= + // behavior requires consecutive strings and it's usually + // unintuitive to users if ther try to subtract multiple flags at + // once. + return FAIL; + } + + int num_flags = STRLEN(option_val); + if (num_flags == 0) + return FAIL; + + *matches = ALLOC_MULT(char_u *, num_flags + 1); + if (*matches == NULL) + return FAIL; + + int count = 0; + char_u *p; + + p = vim_strsave(option_val); + if (p == NULL) + { + VIM_CLEAR(*matches); + return FAIL; + } + (*matches)[count++] = p; + + if (num_flags > 1) + { + // If more than one flags, split the flags up and expose each + // character as individual choice. + for (char_u *flag = option_val; *flag != NUL; flag++) + { + char_u *p = vim_strnsave(flag, 1); + if (p == NULL) + break; + (*matches)[count++] = p; + } + } + + *numMatches = count; + return OK; + } + + return ExpandOldSetting(numMatches, matches); +} + /* * Get the value for the numeric or string option *opp in a nice format into * NameBuff[]. Must not be called with a hidden option! @@ -8257,6 +8519,7 @@ fill_culopt_flags(char_u *val, win_T *wp) p = val; while (*p != NUL) { + // Note: Keep this in sync with p_culopt_values. if (STRNCMP(p, "line", 4) == 0) { p += 4; diff --git a/src/option.h b/src/option.h index db930fbe0e..bcccff16d4 100644 --- a/src/option.h +++ b/src/option.h @@ -60,6 +60,7 @@ #define P_RWINONLY 0x10000000L // only redraw current window #define P_MLE 0x20000000L // under control of 'modelineexpr' #define P_FUNC 0x40000000L // accept a function reference or a lambda +#define P_COLON 0x80000000L // values use colons to create sublists // Returned by get_option_value(). typedef enum { @@ -230,7 +231,7 @@ typedef enum { #define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\\.;" // characters for p_ww option: -#define WW_ALL "bshl<>[],~" +#define WW_ALL "bshl<>[]~" // characters for p_mouse option: #define MOUSE_NORMAL 'n' // use mouse in Normal mode diff --git a/src/optiondefs.h b/src/optiondefs.h index 25b38f734a..7ff44daf4b 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -275,6 +275,11 @@ struct vimoption // callback function to invoke after an option is modified to validate and // apply the new value. opt_did_set_cb_T opt_did_set_cb; + + // callback function to invoke when expanding possible values on the + // cmdline. Only useful for string options. + opt_expand_cb_T opt_expand_cb; + char_u *def_val[2]; // default values for variable (vi and vim) #ifdef FEAT_EVAL sctx_T script_ctx; // script context where the option was last set @@ -357,7 +362,7 @@ static struct vimoption options[] = #else (char_u *)NULL, PV_NONE, #endif - NULL, + NULL, NULL, { #if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) (char_u *)128L, @@ -367,9 +372,9 @@ static struct vimoption options[] = (char_u *)0L} SCTX_INIT}, {"antialias", "anti", P_BOOL|P_VI_DEF|P_VIM|P_RCLR, #ifdef FEAT_ANTIALIAS - (char_u *)&p_antialias, PV_NONE, did_set_antialias, + (char_u *)&p_antialias, PV_NONE, did_set_antialias, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL #endif #ifdef FEAT_GUI_MACVIM {(char_u *)TRUE, (char_u *)FALSE} @@ -379,67 +384,67 @@ static struct vimoption options[] = SCTX_INIT}, {"arabic", "arab", P_BOOL|P_VI_DEF|P_VIM|P_CURSWANT, #ifdef FEAT_ARABIC - (char_u *)VAR_WIN, PV_ARAB, did_set_arabic, + (char_u *)VAR_WIN, PV_ARAB, did_set_arabic, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"arabicshape", "arshape", P_BOOL|P_VI_DEF|P_VIM|P_RCLR, #ifdef FEAT_ARABIC - (char_u *)&p_arshape, PV_NONE, NULL, + (char_u *)&p_arshape, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"allowrevins", "ari", P_BOOL|P_VI_DEF|P_VIM, #ifdef FEAT_RIGHTLEFT - (char_u *)&p_ari, PV_NONE, NULL, + (char_u *)&p_ari, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"altkeymap", "akm", P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"ambiwidth", "ambw", P_STRING|P_VI_DEF|P_RCLR, - (char_u *)&p_ambw, PV_NONE, did_set_ambiwidth, + (char_u *)&p_ambw, PV_NONE, did_set_ambiwidth, expand_set_ambiwidth, {(char_u *)"single", (char_u *)0L} SCTX_INIT}, {"autochdir", "acd", P_BOOL|P_VI_DEF, #ifdef FEAT_AUTOCHDIR - (char_u *)&p_acd, PV_NONE, did_set_autochdir, + (char_u *)&p_acd, PV_NONE, did_set_autochdir, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"autoshelldir", "asd", P_BOOL|P_VI_DEF, #ifdef FEAT_AUTOSHELLDIR - (char_u *)&p_asd, PV_NONE, NULL, + (char_u *)&p_asd, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"autoindent", "ai", P_BOOL|P_VI_DEF, - (char_u *)&p_ai, PV_AI, NULL, + (char_u *)&p_ai, PV_AI, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"autoprint", "ap", P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"autoread", "ar", P_BOOL|P_VI_DEF, - (char_u *)&p_ar, PV_AR, NULL, + (char_u *)&p_ar, PV_AR, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"autowrite", "aw", P_BOOL|P_VI_DEF, - (char_u *)&p_aw, PV_NONE, NULL, + (char_u *)&p_aw, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"autowriteall","awa", P_BOOL|P_VI_DEF, - (char_u *)&p_awa, PV_NONE, NULL, + (char_u *)&p_awa, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"background", "bg", P_STRING|P_VI_DEF|P_RCLR, - (char_u *)&p_bg, PV_NONE, did_set_background, + (char_u *)&p_bg, PV_NONE, did_set_background, expand_set_background, { #if (defined(MSWIN)) && !defined(FEAT_GUI) (char_u *)"dark", @@ -448,13 +453,13 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"backspace", "bs", P_STRING|P_VI_DEF|P_VIM|P_ONECOMMA|P_NODUP, - (char_u *)&p_bs, PV_NONE, did_set_backspace, + (char_u *)&p_bs, PV_NONE, did_set_backspace, expand_set_backspace, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"backup", "bk", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_bk, PV_NONE, NULL, + (char_u *)&p_bk, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"backupcopy", "bkc", P_STRING|P_VIM|P_ONECOMMA|P_NODUP, - (char_u *)&p_bkc, PV_BKC, did_set_backupcopy, + (char_u *)&p_bkc, PV_BKC, did_set_backupcopy, expand_set_backupcopy, #ifdef UNIX {(char_u *)"yes", (char_u *)"auto"} #else @@ -463,11 +468,11 @@ static struct vimoption options[] = SCTX_INIT}, {"backupdir", "bdir", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA |P_NODUP|P_SECURE, - (char_u *)&p_bdir, PV_NONE, NULL, + (char_u *)&p_bdir, PV_NONE, NULL, NULL, {(char_u *)DFLT_BDIR, (char_u *)0L} SCTX_INIT}, {"backupext", "bex", P_STRING|P_VI_DEF|P_NFNAME, (char_u *)&p_bex, PV_NONE, - did_set_backupext_or_patchmode, + did_set_backupext_or_patchmode, NULL, { #ifdef VMS (char_u *)"_", @@ -476,84 +481,84 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"backupskip", "bsk", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_bsk, PV_NONE, NULL, + (char_u *)&p_bsk, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"balloondelay","bdlay",P_NUM|P_VI_DEF, #ifdef FEAT_BEVAL - (char_u *)&p_bdlay, PV_NONE, NULL, + (char_u *)&p_bdlay, PV_NONE, NULL, NULL, {(char_u *)600L, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"ballooneval", "beval",P_BOOL|P_VI_DEF|P_NO_MKRC, #ifdef FEAT_BEVAL_GUI - (char_u *)&p_beval, PV_NONE, did_set_ballooneval, + (char_u *)&p_beval, PV_NONE, did_set_ballooneval, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"balloonevalterm", "bevalterm",P_BOOL|P_VI_DEF|P_NO_MKRC, #ifdef FEAT_BEVAL_TERM (char_u *)&p_bevalterm, PV_NONE, - did_set_balloonevalterm, + did_set_balloonevalterm, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"balloonexpr", "bexpr", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_MLE, #if defined(FEAT_BEVAL) && defined(FEAT_EVAL) - (char_u *)&p_bexpr, PV_BEXPR, did_set_optexpr, + (char_u *)&p_bexpr, PV_BEXPR, did_set_optexpr, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"beautify", "bf", P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"belloff", "bo", P_STRING|P_VI_DEF|P_COMMA|P_NODUP, - (char_u *)&p_bo, PV_NONE, did_set_belloff, + (char_u *)&p_bo, PV_NONE, did_set_belloff, expand_set_belloff, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"binary", "bin", P_BOOL|P_VI_DEF|P_RSTAT, - (char_u *)&p_bin, PV_BIN, did_set_binary, + (char_u *)&p_bin, PV_BIN, did_set_binary, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"bioskey", "biosk",P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"blurradius", "blur", P_NUM|P_VIM, #ifdef FEAT_GUI_MACVIM - (char_u *)&p_blur, PV_NONE, did_set_blur, + (char_u *)&p_blur, PV_NONE, did_set_blur, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"bomb", NULL, P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT, (char_u *)&p_bomb, PV_BOMB, - did_set_eof_eol_fixeol_bomb, + did_set_eof_eol_fixeol_bomb, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"breakat", "brk", P_STRING|P_VI_DEF|P_RALL|P_FLAGLIST, #ifdef FEAT_LINEBREAK - (char_u *)&p_breakat, PV_NONE, did_set_breakat, + (char_u *)&p_breakat, PV_NONE, did_set_breakat, NULL, {(char_u *)" \t!@*-+;:,./?", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"breakindent", "bri", P_BOOL|P_VI_DEF|P_VIM|P_RWIN, #ifdef FEAT_LINEBREAK - (char_u *)VAR_WIN, PV_BRI, NULL, + (char_u *)VAR_WIN, PV_BRI, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, @@ -561,80 +566,80 @@ static struct vimoption options[] = |P_ONECOMMA|P_NODUP, #ifdef FEAT_LINEBREAK (char_u *)VAR_WIN, PV_BRIOPT, - did_set_breakindentopt, + did_set_breakindentopt, expand_set_breakindentopt, {(char_u *)"", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)NULL} #endif SCTX_INIT}, {"browsedir", "bsdir",P_STRING|P_VI_DEF, #ifdef FEAT_BROWSE - (char_u *)&p_bsdir, PV_NONE, did_set_browsedir, + (char_u *)&p_bsdir, PV_NONE, did_set_browsedir, expand_set_browsedir, {(char_u *)"last", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"bufhidden", "bh", P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB, - (char_u *)&p_bh, PV_BH, did_set_bufhidden, + (char_u *)&p_bh, PV_BH, did_set_bufhidden, expand_set_bufhidden, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"buflisted", "bl", P_BOOL|P_VI_DEF|P_NOGLOB, - (char_u *)&p_bl, PV_BL, did_set_buflisted, + (char_u *)&p_bl, PV_BL, did_set_buflisted, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"buftype", "bt", P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB, - (char_u *)&p_bt, PV_BT, did_set_buftype, + (char_u *)&p_bt, PV_BT, did_set_buftype, expand_set_buftype, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"casemap", "cmp", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_cmp, PV_NONE, did_set_casemap, + (char_u *)&p_cmp, PV_NONE, did_set_casemap, expand_set_casemap, {(char_u *)"internal,keepascii", (char_u *)0L} SCTX_INIT}, {"cdhome", "cdh", P_BOOL|P_VI_DEF|P_VIM|P_SECURE, - (char_u *)&p_cdh, PV_NONE, NULL, + (char_u *)&p_cdh, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"cdpath", "cd", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE|P_COMMA|P_NODUP, - (char_u *)&p_cdpath, PV_NONE, NULL, + (char_u *)&p_cdpath, PV_NONE, NULL, NULL, {(char_u *)",,", (char_u *)0L} SCTX_INIT}, {"cedit", NULL, P_STRING, - (char_u *)&p_cedit, PV_NONE, did_set_cedit, + (char_u *)&p_cedit, PV_NONE, did_set_cedit, NULL, {(char_u *)"", (char_u *)CTRL_F_STR} SCTX_INIT}, {"charconvert", "ccv", P_STRING|P_VI_DEF|P_SECURE, #if defined(FEAT_EVAL) - (char_u *)&p_ccv, PV_NONE, did_set_optexpr, + (char_u *)&p_ccv, PV_NONE, did_set_optexpr, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"cindent", "cin", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_cin, PV_CIN, NULL, + (char_u *)&p_cin, PV_CIN, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"cinkeys", "cink", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_cink, PV_CINK, NULL, + (char_u *)&p_cink, PV_CINK, NULL, NULL, {INDENTKEYS_DEFAULT, (char_u *)0L} SCTX_INIT}, {"cinoptions", "cino", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_cino, PV_CINO, did_set_cinoptions, + (char_u *)&p_cino, PV_CINO, did_set_cinoptions, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"cinscopedecls", "cinsd", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_cinsd, PV_CINSD, NULL, + (char_u *)&p_cinsd, PV_CINSD, NULL, NULL, {(char_u *)"public,protected,private", (char_u *)0L} SCTX_INIT}, {"cinwords", "cinw", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_cinw, PV_CINW, NULL, + (char_u *)&p_cinw, PV_CINW, NULL, NULL, {(char_u *)"if,else,while,do,for,switch", (char_u *)0L} SCTX_INIT}, {"clipboard", "cb", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, #ifdef FEAT_CLIPBOARD - (char_u *)&p_cb, PV_NONE, did_set_clipboard, + (char_u *)&p_cb, PV_NONE, did_set_clipboard, expand_set_clipboard, # ifdef FEAT_XCLIPBOARD {(char_u *)"autoselect,exclude:cons\\|linux", (char_u *)0L} @@ -642,350 +647,350 @@ static struct vimoption options[] = {(char_u *)"", (char_u *)0L} # endif #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #endif SCTX_INIT}, {"cmdheight", "ch", P_NUM|P_VI_DEF|P_RALL, - (char_u *)&p_ch, PV_NONE, did_set_cmdheight, + (char_u *)&p_ch, PV_NONE, did_set_cmdheight, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"cmdwinheight", "cwh", P_NUM|P_VI_DEF, - (char_u *)&p_cwh, PV_NONE, NULL, + (char_u *)&p_cwh, PV_NONE, NULL, NULL, {(char_u *)7L, (char_u *)0L} SCTX_INIT}, {"colorcolumn", "cc", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP|P_RWIN, #ifdef FEAT_SYN_HL - (char_u *)VAR_WIN, PV_CC, did_set_colorcolumn, + (char_u *)VAR_WIN, PV_CC, did_set_colorcolumn, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"columns", "co", P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR, - (char_u *)&Columns, PV_NONE, NULL, + (char_u *)&Columns, PV_NONE, NULL, NULL, {(char_u *)80L, (char_u *)0L} SCTX_INIT}, {"columnspace", "csp", P_NUM|P_VI_DEF|P_RCLR, #ifdef FEAT_GUI_MACVIM - (char_u *)&p_columnspace, PV_NONE, did_set_columnspace, + (char_u *)&p_columnspace, PV_NONE, did_set_columnspace, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"comments", "com", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA |P_NODUP|P_CURSWANT, - (char_u *)&p_com, PV_COM, did_set_comments, + (char_u *)&p_com, PV_COM, did_set_comments, NULL, {(char_u *)"s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-", (char_u *)0L} SCTX_INIT}, {"commentstring", "cms", P_STRING|P_ALLOCED|P_VI_DEF|P_CURSWANT, #ifdef FEAT_FOLDING - (char_u *)&p_cms, PV_CMS, did_set_commentstring, + (char_u *)&p_cms, PV_CMS, did_set_commentstring, NULL, {(char_u *)"/*%s*/", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, // P_PRI_MKRC isn't needed here, optval_default() // always returns TRUE for 'compatible' {"compatible", "cp", P_BOOL|P_RALL, - (char_u *)&p_cp, PV_NONE, did_set_compatible, + (char_u *)&p_cp, PV_NONE, did_set_compatible, NULL, {(char_u *)TRUE, (char_u *)FALSE} SCTX_INIT}, {"complete", "cpt", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_cpt, PV_CPT, did_set_complete, + (char_u *)&p_cpt, PV_CPT, did_set_complete, expand_set_complete, {(char_u *)".,w,b,u,t,i", (char_u *)0L} SCTX_INIT}, - {"concealcursor","cocu", P_STRING|P_ALLOCED|P_RWIN|P_VI_DEF, + {"concealcursor","cocu", P_STRING|P_ALLOCED|P_RWIN|P_VI_DEF|P_FLAGLIST, #ifdef FEAT_CONCEAL - (char_u *)VAR_WIN, PV_COCU, did_set_concealcursor, + (char_u *)VAR_WIN, PV_COCU, did_set_concealcursor, expand_set_concealcursor, {(char_u *)"", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"conceallevel","cole", P_NUM|P_RWIN|P_VI_DEF, #ifdef FEAT_CONCEAL - (char_u *)VAR_WIN, PV_COLE, did_set_conceallevel, + (char_u *)VAR_WIN, PV_COLE, did_set_conceallevel, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"completefunc", "cfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE|P_FUNC, #ifdef FEAT_COMPL_FUNC - (char_u *)&p_cfu, PV_CFU, did_set_completefunc, + (char_u *)&p_cfu, PV_CFU, did_set_completefunc, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"completeopt", "cot", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_cot, PV_NONE, did_set_completeopt, + (char_u *)&p_cot, PV_NONE, did_set_completeopt, expand_set_completeopt, {(char_u *)"menu,preview", (char_u *)0L} SCTX_INIT}, - {"completepopup", "cpp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP, + {"completepopup", "cpp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_COLON, #if defined(FEAT_PROP_POPUP) && defined(FEAT_QUICKFIX) - (char_u *)&p_cpp, PV_NONE, did_set_completepopup, + (char_u *)&p_cpp, PV_NONE, did_set_completepopup, expand_set_popupoption, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"completeslash", "csl", P_STRING|P_VI_DEF|P_VIM, #if defined(BACKSLASH_IN_FILENAME) - (char_u *)&p_csl, PV_CSL, did_set_completeslash, + (char_u *)&p_csl, PV_CSL, did_set_completeslash, expand_set_completeslash, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"confirm", "cf", P_BOOL|P_VI_DEF, #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) - (char_u *)&p_confirm, PV_NONE, NULL, + (char_u *)&p_confirm, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"conskey", "consk",P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"copyindent", "ci", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_ci, PV_CI, NULL, + (char_u *)&p_ci, PV_CI, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"cpoptions", "cpo", P_STRING|P_VIM|P_RALL|P_FLAGLIST, - (char_u *)&p_cpo, PV_NONE, did_set_cpoptions, + (char_u *)&p_cpo, PV_NONE, did_set_cpoptions, expand_set_cpoptions, {(char_u *)CPO_VI, (char_u *)CPO_VIM} SCTX_INIT}, {"cryptmethod", "cm", P_STRING|P_ALLOCED|P_VI_DEF, #ifdef FEAT_CRYPT - (char_u *)&p_cm, PV_CM, did_set_cryptmethod, + (char_u *)&p_cm, PV_CM, did_set_cryptmethod, expand_set_cryptmethod, {(char_u *)"blowfish2", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"cscopepathcomp", "cspc", P_NUM|P_VI_DEF|P_VIM, #ifdef FEAT_CSCOPE - (char_u *)&p_cspc, PV_NONE, NULL, + (char_u *)&p_cspc, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"cscopeprg", "csprg", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #ifdef FEAT_CSCOPE - (char_u *)&p_csprg, PV_NONE, NULL, + (char_u *)&p_csprg, PV_NONE, NULL, NULL, {(char_u *)"cscope", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"cscopequickfix", "csqf", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, #if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX) (char_u *)&p_csqf, PV_NONE, - did_set_cscopequickfix, + did_set_cscopequickfix, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"cscoperelative", "csre", P_BOOL|P_VI_DEF|P_VIM, #ifdef FEAT_CSCOPE - (char_u *)&p_csre, PV_NONE, NULL, + (char_u *)&p_csre, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"cscopetag", "cst", P_BOOL|P_VI_DEF|P_VIM, #ifdef FEAT_CSCOPE - (char_u *)&p_cst, PV_NONE, NULL, + (char_u *)&p_cst, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"cscopetagorder", "csto", P_NUM|P_VI_DEF|P_VIM, #ifdef FEAT_CSCOPE - (char_u *)&p_csto, PV_NONE, NULL, + (char_u *)&p_csto, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"cscopeverbose", "csverb", P_BOOL|P_VI_DEF|P_VIM, #ifdef FEAT_CSCOPE - (char_u *)&p_csverbose, PV_NONE, NULL, + (char_u *)&p_csverbose, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"cursorbind", "crb", P_BOOL|P_VI_DEF, - (char_u *)VAR_WIN, PV_CRBIND, NULL, + (char_u *)VAR_WIN, PV_CRBIND, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"cursorcolumn", "cuc", P_BOOL|P_VI_DEF|P_RWINONLY, #ifdef FEAT_SYN_HL - (char_u *)VAR_WIN, PV_CUC, NULL, + (char_u *)VAR_WIN, PV_CUC, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"cursorline", "cul", P_BOOL|P_VI_DEF|P_RWINONLY, #ifdef FEAT_SYN_HL - (char_u *)VAR_WIN, PV_CUL, NULL, + (char_u *)VAR_WIN, PV_CUL, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"cursorlineopt", "culopt", P_STRING|P_VI_DEF|P_RWIN|P_ONECOMMA|P_NODUP, #ifdef FEAT_SYN_HL (char_u *)VAR_WIN, PV_CULOPT, - did_set_cursorlineopt, + did_set_cursorlineopt, expand_set_cursorlineopt, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)"both", (char_u *)0L} SCTX_INIT}, {"debug", NULL, P_STRING|P_VI_DEF, - (char_u *)&p_debug, PV_NONE, did_set_debug, + (char_u *)&p_debug, PV_NONE, did_set_debug, expand_set_debug, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"define", "def", P_STRING|P_ALLOCED|P_VI_DEF|P_CURSWANT, #ifdef FEAT_FIND_ID - (char_u *)&p_def, PV_DEF, NULL, + (char_u *)&p_def, PV_DEF, NULL, NULL, {(char_u *)"^\\s*#\\s*define", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"delcombine", "deco", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_deco, PV_NONE, NULL, + (char_u *)&p_deco, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"dictionary", "dict", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME, - (char_u *)&p_dict, PV_DICT, NULL, + (char_u *)&p_dict, PV_DICT, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"diff", NULL, P_BOOL|P_VI_DEF|P_RWIN|P_NOGLOB, #ifdef FEAT_DIFF - (char_u *)VAR_WIN, PV_DIFF, did_set_diff, + (char_u *)VAR_WIN, PV_DIFF, did_set_diff, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"diffexpr", "dex", P_STRING|P_VI_DEF|P_SECURE|P_CURSWANT, #if defined(FEAT_DIFF) && defined(FEAT_EVAL) - (char_u *)&p_dex, PV_NONE, did_set_optexpr, + (char_u *)&p_dex, PV_NONE, did_set_optexpr, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, - {"diffopt", "dip", P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN|P_ONECOMMA + {"diffopt", "dip", P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN|P_ONECOMMA|P_COLON |P_NODUP, #ifdef FEAT_DIFF - (char_u *)&p_dip, PV_NONE, did_set_diffopt, + (char_u *)&p_dip, PV_NONE, did_set_diffopt, expand_set_diffopt, {(char_u *)"internal,filler,closeoff", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)NULL} #endif SCTX_INIT}, {"digraph", "dg", P_BOOL|P_VI_DEF|P_VIM, #ifdef FEAT_DIGRAPHS - (char_u *)&p_dg, PV_NONE, NULL, + (char_u *)&p_dg, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"directory", "dir", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA |P_NODUP|P_SECURE, - (char_u *)&p_dir, PV_NONE, NULL, + (char_u *)&p_dir, PV_NONE, NULL, NULL, {(char_u *)DFLT_DIR, (char_u *)0L} SCTX_INIT}, {"display", "dy", P_STRING|P_VI_DEF|P_ONECOMMA|P_RALL|P_NODUP, - (char_u *)&p_dy, PV_NONE, did_set_display, + (char_u *)&p_dy, PV_NONE, did_set_display, expand_set_display, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"eadirection", "ead", P_STRING|P_VI_DEF, - (char_u *)&p_ead, PV_NONE, did_set_eadirection, + (char_u *)&p_ead, PV_NONE, did_set_eadirection, expand_set_eadirection, {(char_u *)"both", (char_u *)0L} SCTX_INIT}, {"edcompatible","ed", P_BOOL|P_VI_DEF, - (char_u *)&p_ed, PV_NONE, NULL, + (char_u *)&p_ed, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"emoji", "emo", P_BOOL|P_VI_DEF|P_RCLR, - (char_u *)&p_emoji, PV_NONE, did_set_ambiwidth, + (char_u *)&p_emoji, PV_NONE, did_set_ambiwidth, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"encoding", "enc", P_STRING|P_VI_DEF|P_RCLR|P_NO_ML, - (char_u *)&p_enc, PV_NONE, did_set_encoding, + (char_u *)&p_enc, PV_NONE, did_set_encoding, expand_set_encoding, {(char_u *)ENC_DFLT, (char_u *)0L} SCTX_INIT}, {"endoffile", "eof", P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT, (char_u *)&p_eof, PV_EOF, - did_set_eof_eol_fixeol_bomb, + did_set_eof_eol_fixeol_bomb, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"endofline", "eol", P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT, (char_u *)&p_eol, PV_EOL, - did_set_eof_eol_fixeol_bomb, + did_set_eof_eol_fixeol_bomb, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"equalalways", "ea", P_BOOL|P_VI_DEF|P_RALL, - (char_u *)&p_ea, PV_NONE, did_set_equalalways, + (char_u *)&p_ea, PV_NONE, did_set_equalalways, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"equalprg", "ep", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, - (char_u *)&p_ep, PV_EP, NULL, + (char_u *)&p_ep, PV_EP, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"errorbells", "eb", P_BOOL|P_VI_DEF, - (char_u *)&p_eb, PV_NONE, NULL, + (char_u *)&p_eb, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"errorfile", "ef", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #ifdef FEAT_QUICKFIX - (char_u *)&p_ef, PV_NONE, NULL, + (char_u *)&p_ef, PV_NONE, NULL, NULL, {(char_u *)DFLT_ERRORFILE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"errorformat", "efm", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, #ifdef FEAT_QUICKFIX - (char_u *)&p_efm, PV_EFM, NULL, + (char_u *)&p_efm, PV_EFM, NULL, NULL, {(char_u *)DFLT_EFM, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"esckeys", "ek", P_BOOL|P_VIM, - (char_u *)&p_ek, PV_NONE, NULL, + (char_u *)&p_ek, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)TRUE} SCTX_INIT}, {"eventignore", "ei", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_ei, PV_NONE, did_set_eventignore, + (char_u *)&p_ei, PV_NONE, did_set_eventignore, expand_set_eventignore, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"expandtab", "et", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_et, PV_ET, NULL, + (char_u *)&p_et, PV_ET, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"exrc", "ex", P_BOOL|P_VI_DEF|P_SECURE, - (char_u *)&p_exrc, PV_NONE, NULL, + (char_u *)&p_exrc, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"fileencoding","fenc", P_STRING|P_ALLOCED|P_VI_DEF|P_RSTAT|P_RBUF |P_NO_MKRC, - (char_u *)&p_fenc, PV_FENC, did_set_encoding, + (char_u *)&p_fenc, PV_FENC, did_set_encoding, expand_set_encoding, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"fileencodings","fencs", P_STRING|P_VI_DEF|P_ONECOMMA, - (char_u *)&p_fencs, PV_NONE, NULL, + (char_u *)&p_fencs, PV_NONE, NULL, expand_set_encoding, {(char_u *)"ucs-bom", (char_u *)0L} SCTX_INIT}, {"fileformat", "ff", P_STRING|P_ALLOCED|P_VI_DEF|P_RSTAT|P_NO_MKRC |P_CURSWANT, - (char_u *)&p_ff, PV_FF, did_set_fileformat, + (char_u *)&p_ff, PV_FF, did_set_fileformat, expand_set_fileformat, {(char_u *)DFLT_FF, (char_u *)0L} SCTX_INIT}, {"fileformats", "ffs", P_STRING|P_VIM|P_ONECOMMA|P_NODUP, - (char_u *)&p_ffs, PV_NONE, did_set_fileformats, + (char_u *)&p_ffs, PV_NONE, did_set_fileformats, expand_set_fileformat, {(char_u *)DFLT_FFS_VI, (char_u *)DFLT_FFS_VIM} SCTX_INIT}, {"fileignorecase", "fic", P_BOOL|P_VI_DEF, - (char_u *)&p_fic, PV_NONE, NULL, + (char_u *)&p_fic, PV_NONE, NULL, NULL, { #ifdef CASE_INSENSITIVE_FILENAME (char_u *)TRUE, @@ -995,208 +1000,208 @@ static struct vimoption options[] = (char_u *)0L} SCTX_INIT}, {"filetype", "ft", P_STRING|P_EXPAND|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME, (char_u *)&p_ft, PV_FT, - did_set_filetype_or_syntax, + did_set_filetype_or_syntax, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"fillchars", "fcs", P_STRING|P_VI_DEF|P_RALL|P_ONECOMMA|P_NODUP, - (char_u *)&p_fcs, PV_FCS, did_set_chars_option, + (char_u *)&p_fcs, PV_FCS, did_set_chars_option, expand_set_chars_option, {(char_u *)"vert:|,fold:-,eob:~,lastline:@", (char_u *)0L} SCTX_INIT}, {"fixendofline", "fixeol", P_BOOL|P_VI_DEF|P_RSTAT, (char_u *)&p_fixeol, PV_FIXEOL, - did_set_eof_eol_fixeol_bomb, + did_set_eof_eol_fixeol_bomb, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"fkmap", "fk", P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"flash", "fl", P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"foldclose", "fcl", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP|P_RWIN, #ifdef FEAT_FOLDING - (char_u *)&p_fcl, PV_NONE, did_set_foldclose, + (char_u *)&p_fcl, PV_NONE, did_set_foldclose, expand_set_foldclose, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldcolumn", "fdc", P_NUM|P_VI_DEF|P_RWIN, #ifdef FEAT_FOLDING - (char_u *)VAR_WIN, PV_FDC, did_set_foldcolumn, + (char_u *)VAR_WIN, PV_FDC, did_set_foldcolumn, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldenable", "fen", P_BOOL|P_VI_DEF|P_RWIN, #ifdef FEAT_FOLDING - (char_u *)VAR_WIN, PV_FEN, NULL, + (char_u *)VAR_WIN, PV_FEN, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldexpr", "fde", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN|P_MLE, #if defined(FEAT_FOLDING) && defined(FEAT_EVAL) - (char_u *)VAR_WIN, PV_FDE, did_set_foldexpr, + (char_u *)VAR_WIN, PV_FDE, did_set_foldexpr, NULL, {(char_u *)"0", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldignore", "fdi", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN, #ifdef FEAT_FOLDING - (char_u *)VAR_WIN, PV_FDI, did_set_foldignore, + (char_u *)VAR_WIN, PV_FDI, did_set_foldignore, NULL, {(char_u *)"#", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldlevel", "fdl", P_NUM|P_VI_DEF|P_RWIN, #ifdef FEAT_FOLDING - (char_u *)VAR_WIN, PV_FDL, did_set_foldlevel, + (char_u *)VAR_WIN, PV_FDL, did_set_foldlevel, NULL, {(char_u *)0L, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldlevelstart","fdls", P_NUM|P_VI_DEF|P_CURSWANT, #ifdef FEAT_FOLDING - (char_u *)&p_fdls, PV_NONE, NULL, + (char_u *)&p_fdls, PV_NONE, NULL, NULL, {(char_u *)-1L, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldmarker", "fmr", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF| P_RWIN|P_ONECOMMA|P_NODUP, #ifdef FEAT_FOLDING - (char_u *)VAR_WIN, PV_FMR, did_set_foldmarker, + (char_u *)VAR_WIN, PV_FMR, did_set_foldmarker, NULL, {(char_u *)"{{{,}}}", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldmethod", "fdm", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN, #ifdef FEAT_FOLDING - (char_u *)VAR_WIN, PV_FDM, did_set_foldmethod, + (char_u *)VAR_WIN, PV_FDM, did_set_foldmethod, expand_set_foldmethod, {(char_u *)"manual", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldminlines","fml", P_NUM|P_VI_DEF|P_RWIN, #ifdef FEAT_FOLDING - (char_u *)VAR_WIN, PV_FML, did_set_foldminlines, + (char_u *)VAR_WIN, PV_FML, did_set_foldminlines, NULL, {(char_u *)1L, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldnestmax", "fdn", P_NUM|P_VI_DEF|P_RWIN, #ifdef FEAT_FOLDING - (char_u *)VAR_WIN, PV_FDN, did_set_foldnestmax, + (char_u *)VAR_WIN, PV_FDN, did_set_foldnestmax, NULL, {(char_u *)20L, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldopen", "fdo", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP|P_CURSWANT, #ifdef FEAT_FOLDING - (char_u *)&p_fdo, PV_NONE, did_set_foldopen, + (char_u *)&p_fdo, PV_NONE, did_set_foldopen, expand_set_foldopen, {(char_u *)"block,hor,mark,percent,quickfix,search,tag,undo", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"foldtext", "fdt", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN|P_MLE, #if defined(FEAT_FOLDING) && defined(FEAT_EVAL) - (char_u *)VAR_WIN, PV_FDT, did_set_optexpr, + (char_u *)VAR_WIN, PV_FDT, did_set_optexpr, NULL, {(char_u *)"foldtext()", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"formatexpr", "fex", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_MLE, #ifdef FEAT_EVAL - (char_u *)&p_fex, PV_FEX, did_set_optexpr, + (char_u *)&p_fex, PV_FEX, did_set_optexpr, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"formatoptions","fo", P_STRING|P_ALLOCED|P_VIM|P_FLAGLIST, - (char_u *)&p_fo, PV_FO, did_set_formatoptions, + (char_u *)&p_fo, PV_FO, did_set_formatoptions, expand_set_formatoptions, {(char_u *)DFLT_FO_VI, (char_u *)DFLT_FO_VIM} SCTX_INIT}, {"formatlistpat","flp", P_STRING|P_ALLOCED|P_VI_DEF, - (char_u *)&p_flp, PV_FLP, NULL, + (char_u *)&p_flp, PV_FLP, NULL, NULL, {(char_u *)"^\\s*\\d\\+[\\]:.)}\\t ]\\s*", (char_u *)0L} SCTX_INIT}, {"formatprg", "fp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, - (char_u *)&p_fp, PV_FP, NULL, + (char_u *)&p_fp, PV_FP, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"fsync", "fs", P_BOOL|P_SECURE|P_VI_DEF, #ifdef HAVE_FSYNC - (char_u *)&p_fs, PV_NONE, NULL, + (char_u *)&p_fs, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} #endif SCTX_INIT}, {"fullscreen", "fu", P_BOOL|P_NO_MKRC, #ifdef FEAT_FULLSCREEN - (char_u *)&p_fullscreen, PV_NONE, did_set_fullscreen, + (char_u *)&p_fullscreen, PV_NONE, did_set_fullscreen, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"fuoptions", "fuopt", P_STRING|P_COMMA|P_NODUP|P_VI_DEF, #ifdef FEAT_FULLSCREEN - (char_u *)&p_fuoptions, PV_NONE, did_set_fuoptions, + (char_u *)&p_fuoptions, PV_NONE, did_set_fuoptions, NULL, {(char_u *)"maxvert,maxhorz", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"gdefault", "gd", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_gd, PV_NONE, NULL, + (char_u *)&p_gd, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"graphic", "gr", P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"grepformat", "gfm", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, #ifdef FEAT_QUICKFIX - (char_u *)&p_gefm, PV_NONE, NULL, + (char_u *)&p_gefm, PV_NONE, NULL, NULL, {(char_u *)DFLT_GREPFORMAT, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"grepprg", "gp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #ifdef FEAT_QUICKFIX - (char_u *)&p_gp, PV_GP, NULL, + (char_u *)&p_gp, PV_GP, NULL, NULL, { # if defined(MSWIN) // may be changed to "grep -n" in os_win32.c @@ -1212,14 +1217,14 @@ static struct vimoption options[] = # endif (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"guicursor", "gcr", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, #ifdef CURSOR_SHAPE (char_u *)&p_guicursor, PV_NONE, - did_set_guicursor, + did_set_guicursor, NULL, { # ifdef FEAT_GUI (char_u *)"n-v-c:block-Cursor/lCursor,ve:ver35-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor/lCursor,r-cr:hor20-Cursor/lCursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175", @@ -1228,36 +1233,36 @@ static struct vimoption options[] = # endif (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"guifont", "gfn", P_STRING|P_VI_DEF|P_RCLR|P_ONECOMMA|P_NODUP, #ifdef FEAT_GUI - (char_u *)&p_guifont, PV_NONE, did_set_guifont, + (char_u *)&p_guifont, PV_NONE, did_set_guifont, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"guifontset", "gfs", P_STRING|P_VI_DEF|P_RCLR|P_ONECOMMA, #if defined(FEAT_GUI) && defined(FEAT_XFONTSET) (char_u *)&p_guifontset, PV_NONE, - did_set_guifontset, + did_set_guifontset, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"guifontwide", "gfw", P_STRING|P_VI_DEF|P_RCLR|P_ONECOMMA|P_NODUP, #if defined(FEAT_GUI) (char_u *)&p_guifontwide, PV_NONE, - did_set_guifontwide, + did_set_guifontwide, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, @@ -1266,10 +1271,10 @@ static struct vimoption options[] = {"guiligatures", "gli", P_STRING|P_VI_DEF|P_RCLR|P_ONECOMMA|P_NODUP, #if defined(FEAT_GUI_GTK) (char_u *)&p_guiligatures, PV_NONE, - did_set_guiligatures, + did_set_guiligatures, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, @@ -1277,14 +1282,14 @@ static struct vimoption options[] = {"guiheadroom", "ghr", P_NUM|P_VI_DEF, #if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11) - (char_u *)&p_ghr, PV_NONE, NULL, + (char_u *)&p_ghr, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)50L, (char_u *)0L} SCTX_INIT}, {"guioptions", "go", P_STRING|P_VI_DEF|P_RALL|P_FLAGLIST, #if defined(FEAT_GUI) - (char_u *)&p_go, PV_NONE, did_set_guioptions, + (char_u *)&p_go, PV_NONE, did_set_guioptions, expand_set_guioptions, # ifdef FEAT_GUI_MACVIM {(char_u *)"egmrL", (char_u *)0L} # elif defined(UNIX) @@ -1293,124 +1298,124 @@ static struct vimoption options[] = {(char_u *)"egmrLtT", (char_u *)0L} # endif #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"guipty", NULL, P_BOOL|P_VI_DEF, #if defined(FEAT_GUI) - (char_u *)&p_guipty, PV_NONE, NULL, + (char_u *)&p_guipty, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"guitablabel", "gtl", P_STRING|P_VI_DEF|P_RWIN|P_MLE, #if defined(FEAT_GUI_TABLINE) - (char_u *)&p_gtl, PV_NONE, did_set_guitablabel, + (char_u *)&p_gtl, PV_NONE, did_set_guitablabel, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"guitabtooltip", "gtt", P_STRING|P_VI_DEF|P_RWIN, #if defined(FEAT_GUI_TABLINE) - (char_u *)&p_gtt, PV_NONE, NULL, + (char_u *)&p_gtt, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"hardtabs", "ht", P_NUM|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"helpfile", "hf", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, - (char_u *)&p_hf, PV_NONE, did_set_helpfile, + (char_u *)&p_hf, PV_NONE, did_set_helpfile, NULL, {(char_u *)DFLT_HELPFILE, (char_u *)0L} SCTX_INIT}, {"helpheight", "hh", P_NUM|P_VI_DEF, (char_u *)&p_hh, PV_NONE, - did_set_winheight_helpheight, + did_set_winheight_helpheight, NULL, {(char_u *)20L, (char_u *)0L} SCTX_INIT}, {"helplang", "hlg", P_STRING|P_VI_DEF|P_ONECOMMA, #ifdef FEAT_MULTI_LANG - (char_u *)&p_hlg, PV_NONE, did_set_helplang, + (char_u *)&p_hlg, PV_NONE, did_set_helplang, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"hidden", "hid", P_BOOL|P_VI_DEF, - (char_u *)&p_hid, PV_NONE, NULL, + (char_u *)&p_hid, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, - {"highlight", "hl", P_STRING|P_VI_DEF|P_RCLR|P_ONECOMMA|P_NODUP, - (char_u *)&p_hl, PV_NONE, did_set_highlight, + {"highlight", "hl", P_STRING|P_VI_DEF|P_RCLR|P_ONECOMMA|P_NODUP|P_COLON, + (char_u *)&p_hl, PV_NONE, did_set_highlight, expand_set_highlight, {(char_u *)HIGHLIGHT_INIT, (char_u *)0L} SCTX_INIT}, {"history", "hi", P_NUM|P_VIM, - (char_u *)&p_hi, PV_NONE, NULL, + (char_u *)&p_hi, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)50L} SCTX_INIT}, {"hkmap", "hk", P_BOOL|P_VI_DEF|P_VIM, #ifdef FEAT_RIGHTLEFT - (char_u *)&p_hkmap, PV_NONE, NULL, + (char_u *)&p_hkmap, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"hkmapp", "hkp", P_BOOL|P_VI_DEF|P_VIM, #ifdef FEAT_RIGHTLEFT - (char_u *)&p_hkmapp, PV_NONE, NULL, + (char_u *)&p_hkmapp, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"hlsearch", "hls", P_BOOL|P_VI_DEF|P_VIM|P_RALL, #if defined(FEAT_SEARCH_EXTRA) - (char_u *)&p_hls, PV_NONE, did_set_hlsearch, + (char_u *)&p_hls, PV_NONE, did_set_hlsearch, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"icon", NULL, P_BOOL|P_VI_DEF, - (char_u *)&p_icon, PV_NONE, did_set_title_icon, + (char_u *)&p_icon, PV_NONE, did_set_title_icon, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"iconstring", NULL, P_STRING|P_VI_DEF|P_MLE, (char_u *)&p_iconstring, PV_NONE, - did_set_iconstring, + did_set_iconstring, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"ignorecase", "ic", P_BOOL|P_VI_DEF, - (char_u *)&p_ic, PV_NONE, did_set_ignorecase, + (char_u *)&p_ic, PV_NONE, did_set_ignorecase, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"imactivatefunc","imaf",P_STRING|P_VI_DEF|P_SECURE|P_FUNC, #if defined(FEAT_EVAL) && \ (defined(FEAT_XIM) || defined(IME_WITHOUT_XIM) || defined(VIMDLL)) (char_u *)&p_imaf, PV_NONE, - did_set_imactivatefunc, + did_set_imactivatefunc, NULL, {(char_u *)"", (char_u *)NULL} # else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} # endif SCTX_INIT}, {"imactivatekey","imak",P_STRING|P_VI_DEF, #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) (char_u *)&p_imak, PV_NONE, - did_set_imactivatekey, + did_set_imactivatekey, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"imcmdline", "imc", P_BOOL|P_VI_DEF, - (char_u *)&p_imcmdline, PV_NONE, NULL, + (char_u *)&p_imcmdline, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"imdisable", "imd", P_BOOL|P_VI_DEF, #if defined(HAVE_INPUT_METHOD) (char_u *)&p_imdisable, PV_NONE, - did_set_imdisable, + did_set_imdisable, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif #ifdef FEAT_GUI_MACVIM {(char_u *)TRUE, (char_u *)0L} @@ -1419,83 +1424,83 @@ static struct vimoption options[] = #endif SCTX_INIT}, {"iminsert", "imi", P_NUM|P_VI_DEF, - (char_u *)&p_iminsert, PV_IMI, did_set_iminsert, + (char_u *)&p_iminsert, PV_IMI, did_set_iminsert, NULL, {(char_u *)B_IMODE_NONE, (char_u *)0L} SCTX_INIT}, {"imsearch", "ims", P_NUM|P_VI_DEF, - (char_u *)&p_imsearch, PV_IMS, did_set_imsearch, + (char_u *)&p_imsearch, PV_IMS, did_set_imsearch, NULL, {(char_u *)B_IMODE_USE_INSERT, (char_u *)0L} SCTX_INIT}, {"imstatusfunc","imsf",P_STRING|P_VI_DEF|P_SECURE|P_FUNC, #if defined(FEAT_EVAL) && \ (defined(FEAT_XIM) || defined(IME_WITHOUT_XIM) || defined(VIMDLL)) - (char_u *)&p_imsf, PV_NONE, did_set_imstatusfunc, + (char_u *)&p_imsf, PV_NONE, did_set_imstatusfunc, NULL, {(char_u *)"", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"imstyle", "imst", P_NUM|P_VI_DEF|P_SECURE, #if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) || defined(FEAT_GUI_MACVIM) - (char_u *)&p_imst, PV_NONE, did_set_imstyle, + (char_u *)&p_imst, PV_NONE, did_set_imstyle, NULL, # ifdef FEAT_GUI_MACVIM {(char_u *)IM_ON_THE_SPOT, (char_u *)0L} # else {(char_u *)IM_OVER_THE_SPOT, (char_u *)0L} # endif #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"include", "inc", P_STRING|P_ALLOCED|P_VI_DEF, #ifdef FEAT_FIND_ID - (char_u *)&p_inc, PV_INC, NULL, + (char_u *)&p_inc, PV_INC, NULL, NULL, {(char_u *)"^\\s*#\\s*include", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"includeexpr", "inex", P_STRING|P_ALLOCED|P_VI_DEF|P_MLE, #if defined(FEAT_FIND_ID) && defined(FEAT_EVAL) - (char_u *)&p_inex, PV_INEX, did_set_optexpr, + (char_u *)&p_inex, PV_INEX, did_set_optexpr, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"incsearch", "is", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_is, PV_NONE, NULL, + (char_u *)&p_is, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"indentexpr", "inde", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_MLE, #if defined(FEAT_EVAL) - (char_u *)&p_inde, PV_INDE, did_set_optexpr, + (char_u *)&p_inde, PV_INDE, did_set_optexpr, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"indentkeys", "indk", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, #if defined(FEAT_EVAL) - (char_u *)&p_indk, PV_INDK, NULL, + (char_u *)&p_indk, PV_INDK, NULL, NULL, {INDENTKEYS_DEFAULT, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"infercase", "inf", P_BOOL|P_VI_DEF, - (char_u *)&p_inf, PV_INF, NULL, + (char_u *)&p_inf, PV_INF, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"insertmode", "im", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_im, PV_NONE, did_set_insertmode, + (char_u *)&p_im, PV_NONE, did_set_insertmode, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"isfname", "isf", P_STRING|P_VI_DEF|P_COMMA|P_NODUP, - (char_u *)&p_isf, PV_NONE, did_set_isopt, + (char_u *)&p_isf, PV_NONE, did_set_isopt, NULL, { #ifdef BACKSLASH_IN_FILENAME // Excluded are: & and ^ are special in cmd.exe @@ -1512,7 +1517,7 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"isident", "isi", P_STRING|P_VI_DEF|P_COMMA|P_NODUP, - (char_u *)&p_isi, PV_NONE, did_set_isopt, + (char_u *)&p_isi, PV_NONE, did_set_isopt, NULL, { #if defined(MSWIN) (char_u *)"@,48-57,_,128-167,224-235", @@ -1521,7 +1526,7 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"iskeyword", "isk", P_STRING|P_ALLOCED|P_VIM|P_COMMA|P_NODUP, - (char_u *)&p_isk, PV_ISK, did_set_isopt, + (char_u *)&p_isk, PV_ISK, did_set_isopt, NULL, { (char_u *)"@,48-57,_", #if defined(MSWIN) @@ -1531,7 +1536,7 @@ static struct vimoption options[] = #endif } SCTX_INIT}, {"isprint", "isp", P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP, - (char_u *)&p_isp, PV_NONE, did_set_isopt, + (char_u *)&p_isp, PV_NONE, did_set_isopt, NULL, { #if defined(MSWIN) || defined(VMS) (char_u *)"@,~-255", @@ -1540,38 +1545,38 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"joinspaces", "js", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_js, PV_NONE, NULL, + (char_u *)&p_js, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"jumpoptions", "jop", P_STRING|P_VI_DEF|P_VIM|P_ONECOMMA|P_NODUP, - (char_u *)&p_jop, PV_NONE, did_set_jumpoptions, + (char_u *)&p_jop, PV_NONE, did_set_jumpoptions, expand_set_jumpoptions, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"key", NULL, P_STRING|P_ALLOCED|P_VI_DEF|P_NO_MKRC, #ifdef FEAT_CRYPT - (char_u *)&p_key, PV_KEY, did_set_cryptkey, + (char_u *)&p_key, PV_KEY, did_set_cryptkey, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"keymap", "kmp", P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME|P_PRI_MKRC, #ifdef FEAT_KEYMAP - (char_u *)&p_keymap, PV_KMAP, did_set_keymap, + (char_u *)&p_keymap, PV_KMAP, did_set_keymap, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #endif SCTX_INIT}, {"keymodel", "km", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_km, PV_NONE, did_set_keymodel, + (char_u *)&p_km, PV_NONE, did_set_keymodel, expand_set_keymodel, {(char_u *)"", (char_u *)0L} SCTX_INIT}, - {"keyprotocol", "kpc", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_kpc, PV_NONE, did_set_keyprotocol, + {"keyprotocol", "kpc", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP|P_COLON, + (char_u *)&p_kpc, PV_NONE, did_set_keyprotocol, expand_set_keyprotocol, {(char_u *)"kitty:kitty,foot:kitty,wezterm:kitty,xterm:mok2", (char_u *)0L} SCTX_INIT}, {"keywordprg", "kp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, - (char_u *)&p_kp, PV_KP, NULL, + (char_u *)&p_kp, PV_KP, NULL, NULL, { #if defined(MSWIN) (char_u *)":help", @@ -1585,49 +1590,49 @@ static struct vimoption options[] = (char_u *)0L} SCTX_INIT}, {"langmap", "lmap", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP|P_SECURE, #ifdef FEAT_LANGMAP - (char_u *)&p_langmap, PV_NONE, did_set_langmap, + (char_u *)&p_langmap, PV_NONE, did_set_langmap, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"langmenu", "lm", P_STRING|P_VI_DEF|P_NFNAME, #if defined(FEAT_MENU) && defined(FEAT_MULTI_LANG) - (char_u *)&p_lm, PV_NONE, NULL, + (char_u *)&p_lm, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"langnoremap", "lnr", P_BOOL|P_VI_DEF, #ifdef FEAT_LANGMAP - (char_u *)&p_lnr, PV_NONE, did_set_langnoremap, + (char_u *)&p_lnr, PV_NONE, did_set_langnoremap, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"langremap", "lrm", P_BOOL|P_VI_DEF, #ifdef FEAT_LANGMAP - (char_u *)&p_lrm, PV_NONE, did_set_langremap, + (char_u *)&p_lrm, PV_NONE, did_set_langremap, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"laststatus", "ls", P_NUM|P_VI_DEF|P_RALL, - (char_u *)&p_ls, PV_NONE, did_set_laststatus, + (char_u *)&p_ls, PV_NONE, did_set_laststatus, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"lazyredraw", "lz", P_BOOL|P_VI_DEF, - (char_u *)&p_lz, PV_NONE, NULL, + (char_u *)&p_lz, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"linebreak", "lbr", P_BOOL|P_VI_DEF|P_RWIN, #ifdef FEAT_LINEBREAK - (char_u *)VAR_WIN, PV_LBR, NULL, + (char_u *)VAR_WIN, PV_LBR, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"lines", NULL, P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR, - (char_u *)&Rows, PV_NONE, NULL, + (char_u *)&Rows, PV_NONE, NULL, NULL, { #if defined(MSWIN) (char_u *)25L, @@ -1638,9 +1643,9 @@ static struct vimoption options[] = {"linespace", "lsp", P_NUM|P_VI_DEF|P_RCLR, #ifdef FEAT_GUI (char_u *)&p_linespace, PV_NONE, - did_set_linespace, + did_set_linespace, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif #ifdef FEAT_GUI_MSWIN {(char_u *)1L, (char_u *)0L} @@ -1649,162 +1654,162 @@ static struct vimoption options[] = #endif SCTX_INIT}, {"lisp", NULL, P_BOOL|P_VI_DEF, - (char_u *)&p_lisp, PV_LISP, did_set_lisp, + (char_u *)&p_lisp, PV_LISP, did_set_lisp, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"lispoptions", "lop", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_lop, PV_LOP, did_set_lispoptions, + (char_u *)&p_lop, PV_LOP, did_set_lispoptions, expand_set_lispoptions, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"lispwords", "lw", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_lispwords, PV_LW, NULL, + (char_u *)&p_lispwords, PV_LW, NULL, NULL, {(char_u *)LISPWORD_VALUE, (char_u *)0L} SCTX_INIT}, {"list", NULL, P_BOOL|P_VI_DEF|P_RWIN, - (char_u *)VAR_WIN, PV_LIST, NULL, + (char_u *)VAR_WIN, PV_LIST, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"listchars", "lcs", P_STRING|P_VI_DEF|P_RALL|P_ONECOMMA|P_NODUP, - (char_u *)&p_lcs, PV_LCS, did_set_chars_option, + (char_u *)&p_lcs, PV_LCS, did_set_chars_option, expand_set_chars_option, {(char_u *)"eol:$", (char_u *)0L} SCTX_INIT}, {"loadplugins", "lpl", P_BOOL|P_VI_DEF, - (char_u *)&p_lpl, PV_NONE, NULL, + (char_u *)&p_lpl, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"luadll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(DYNAMIC_LUA) - (char_u *)&p_luadll, PV_NONE, NULL, + (char_u *)&p_luadll, PV_NONE, NULL, NULL, {(char_u *)DYNAMIC_LUA_DLL, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #endif SCTX_INIT}, {"macatsui", NULL, P_BOOL|P_VI_DEF|P_RCLR, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"macligatures", NULL, P_BOOL|P_VI_DEF|P_RCLR, #ifdef FEAT_GUI_MACVIM - (char_u *)&p_macligatures, PV_NONE, did_set_macligatures, + (char_u *)&p_macligatures, PV_NONE, did_set_macligatures, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"macmeta", "mmta", P_BOOL|P_VI_DEF, #ifdef FEAT_GUI_MACVIM - (char_u *)&p_mmta, PV_MMTA, NULL, + (char_u *)&p_mmta, PV_MMTA, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"macthinstrokes", NULL, P_BOOL|P_VI_DEF|P_RCLR, #ifdef FEAT_GUI_MACVIM - (char_u *)&p_macthinstrokes, PV_NONE, did_set_macthinstrokes, + (char_u *)&p_macthinstrokes, PV_NONE, did_set_macthinstrokes, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"magic", NULL, P_BOOL|P_VI_DEF, - (char_u *)&p_magic, PV_NONE, NULL, + (char_u *)&p_magic, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"makeef", "mef", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #ifdef FEAT_QUICKFIX - (char_u *)&p_mef, PV_NONE, NULL, + (char_u *)&p_mef, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"makeencoding","menc", P_STRING|P_VI_DEF, - (char_u *)&p_menc, PV_MENC, did_set_encoding, + (char_u *)&p_menc, PV_MENC, did_set_encoding, expand_set_encoding, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"makeprg", "mp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #ifdef FEAT_QUICKFIX - (char_u *)&p_mp, PV_MP, NULL, + (char_u *)&p_mp, PV_MP, NULL, NULL, # ifdef VMS {(char_u *)"MMS", (char_u *)0L} # else {(char_u *)"make", (char_u *)0L} # endif #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"matchpairs", "mps", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_mps, PV_MPS, did_set_matchpairs, + (char_u *)&p_mps, PV_MPS, did_set_matchpairs, NULL, {(char_u *)"(:),{:},[:]", (char_u *)0L} SCTX_INIT}, {"matchtime", "mat", P_NUM|P_VI_DEF, - (char_u *)&p_mat, PV_NONE, NULL, + (char_u *)&p_mat, PV_NONE, NULL, NULL, {(char_u *)5L, (char_u *)0L} SCTX_INIT}, {"maxcombine", "mco", P_NUM|P_VI_DEF|P_CURSWANT, - (char_u *)&p_mco, PV_NONE, did_set_maxcombine, + (char_u *)&p_mco, PV_NONE, did_set_maxcombine, NULL, {(char_u *)2, (char_u *)0L} SCTX_INIT}, {"maxfuncdepth", "mfd", P_NUM|P_VI_DEF, #ifdef FEAT_EVAL - (char_u *)&p_mfd, PV_NONE, NULL, + (char_u *)&p_mfd, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)100L, (char_u *)0L} SCTX_INIT}, {"maxmapdepth", "mmd", P_NUM|P_VI_DEF, - (char_u *)&p_mmd, PV_NONE, NULL, + (char_u *)&p_mmd, PV_NONE, NULL, NULL, {(char_u *)1000L, (char_u *)0L} SCTX_INIT}, {"maxmem", "mm", P_NUM|P_VI_DEF, - (char_u *)&p_mm, PV_NONE, NULL, + (char_u *)&p_mm, PV_NONE, NULL, NULL, {(char_u *)DFLT_MAXMEM, (char_u *)0L} SCTX_INIT}, {"maxmempattern","mmp", P_NUM|P_VI_DEF, - (char_u *)&p_mmp, PV_NONE, NULL, + (char_u *)&p_mmp, PV_NONE, NULL, NULL, {(char_u *)1000L, (char_u *)0L} SCTX_INIT}, {"maxmemtot", "mmt", P_NUM|P_VI_DEF, - (char_u *)&p_mmt, PV_NONE, NULL, + (char_u *)&p_mmt, PV_NONE, NULL, NULL, {(char_u *)DFLT_MAXMEMTOT, (char_u *)0L} SCTX_INIT}, {"menuitems", "mis", P_NUM|P_VI_DEF, #ifdef FEAT_MENU - (char_u *)&p_mis, PV_NONE, NULL, + (char_u *)&p_mis, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)25L, (char_u *)0L} SCTX_INIT}, {"mesg", NULL, P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"mkspellmem", "msm", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE, #ifdef FEAT_SPELL - (char_u *)&p_msm, PV_NONE, did_set_mkspellmem, + (char_u *)&p_msm, PV_NONE, did_set_mkspellmem, NULL, {(char_u *)"460000,2000,500", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"modeline", "ml", P_BOOL|P_VIM, - (char_u *)&p_ml, PV_ML, NULL, + (char_u *)&p_ml, PV_ML, NULL, NULL, {(char_u *)FALSE, (char_u *)TRUE} SCTX_INIT}, {"modelineexpr", "mle", P_BOOL|P_VI_DEF|P_SECURE, - (char_u *)&p_mle, PV_NONE, NULL, + (char_u *)&p_mle, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"modelines", "mls", P_NUM|P_VI_DEF, - (char_u *)&p_mls, PV_NONE, NULL, + (char_u *)&p_mls, PV_NONE, NULL, NULL, {(char_u *)5L, (char_u *)0L} SCTX_INIT}, {"modifiable", "ma", P_BOOL|P_VI_DEF|P_NOGLOB, - (char_u *)&p_ma, PV_MA, did_set_modifiable, + (char_u *)&p_ma, PV_MA, did_set_modifiable, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"modified", "mod", P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT, - (char_u *)&p_mod, PV_MOD, did_set_modified, + (char_u *)&p_mod, PV_MOD, did_set_modified, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"more", NULL, P_BOOL|P_VIM, - (char_u *)&p_more, PV_NONE, NULL, + (char_u *)&p_more, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)TRUE} SCTX_INIT}, {"mouse", NULL, P_STRING|P_VI_DEF|P_FLAGLIST, - (char_u *)&p_mouse, PV_NONE, did_set_mouse, + (char_u *)&p_mouse, PV_NONE, did_set_mouse, expand_set_mouse, { #if defined(MSWIN) (char_u *)"a", @@ -1814,20 +1819,20 @@ static struct vimoption options[] = (char_u *)0L} SCTX_INIT}, {"mousefocus", "mousef", P_BOOL|P_VI_DEF, #ifdef FEAT_GUI - (char_u *)&p_mousef, PV_NONE, NULL, + (char_u *)&p_mousef, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"mousehide", "mh", P_BOOL|P_VI_DEF, #ifdef FEAT_GUI - (char_u *)&p_mh, PV_NONE, did_set_mousehide, + (char_u *)&p_mh, PV_NONE, did_set_mousehide, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"mousemodel", "mousem", P_STRING|P_VI_DEF, - (char_u *)&p_mousem, PV_NONE, did_set_mousemodel, + (char_u *)&p_mousem, PV_NONE, did_set_mousemodel, expand_set_mousemodel, { #if defined(MSWIN) (char_u *)"popup", @@ -1841,127 +1846,127 @@ static struct vimoption options[] = (char_u *)0L} SCTX_INIT}, {"mousemoveevent", "mousemev", P_BOOL|P_VI_DEF, #ifdef FEAT_GUI - (char_u *)&p_mousemev, PV_NONE, NULL, + (char_u *)&p_mousemev, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"mouseshape", "mouses", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, #ifdef FEAT_MOUSESHAPE (char_u *)&p_mouseshape, PV_NONE, - did_set_mouseshape, + did_set_mouseshape, NULL, {(char_u *)"i-r:beam,s:updown,sd:udsizing,vs:leftright,vd:lrsizing,m:no,ml:up-arrow,v:rightup-arrow", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"mousetime", "mouset", P_NUM|P_VI_DEF, - (char_u *)&p_mouset, PV_NONE, NULL, + (char_u *)&p_mouset, PV_NONE, NULL, NULL, {(char_u *)500L, (char_u *)0L} SCTX_INIT}, {"mzschemedll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(DYNAMIC_MZSCHEME) - (char_u *)&p_mzschemedll, PV_NONE, NULL, + (char_u *)&p_mzschemedll, PV_NONE, NULL, NULL, {(char_u *)DYNAMIC_MZSCH_DLL, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #endif SCTX_INIT}, {"mzschemegcdll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(DYNAMIC_MZSCHEME) - (char_u *)&p_mzschemegcdll, PV_NONE, NULL, + (char_u *)&p_mzschemegcdll, PV_NONE, NULL, NULL, {(char_u *)DYNAMIC_MZGC_DLL, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #endif SCTX_INIT}, {"mzquantum", "mzq", P_NUM, #ifdef FEAT_MZSCHEME - (char_u *)&p_mzq, PV_NONE, did_set_mzquantum, + (char_u *)&p_mzq, PV_NONE, did_set_mzquantum, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)100L, (char_u *)100L} SCTX_INIT}, {"novice", NULL, P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"nrformats", "nf", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_nf, PV_NF, did_set_nrformats, + (char_u *)&p_nf, PV_NF, did_set_nrformats, expand_set_nrformats, {(char_u *)"bin,octal,hex", (char_u *)0L} SCTX_INIT}, {"number", "nu", P_BOOL|P_VI_DEF|P_RWIN, (char_u *)VAR_WIN, PV_NU, - did_set_number_relativenumber, + did_set_number_relativenumber, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"numberwidth", "nuw", P_NUM|P_RWIN|P_VIM, #ifdef FEAT_LINEBREAK - (char_u *)VAR_WIN, PV_NUW, did_set_numberwidth, + (char_u *)VAR_WIN, PV_NUW, did_set_numberwidth, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)8L, (char_u *)4L} SCTX_INIT}, {"omnifunc", "ofu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE|P_FUNC, #ifdef FEAT_COMPL_FUNC - (char_u *)&p_ofu, PV_OFU, did_set_omnifunc, + (char_u *)&p_ofu, PV_OFU, did_set_omnifunc, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"open", NULL, P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"opendevice", "odev", P_BOOL|P_VI_DEF, #if defined(MSWIN) - (char_u *)&p_odev, PV_NONE, NULL, + (char_u *)&p_odev, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)FALSE} SCTX_INIT}, {"operatorfunc", "opfunc", P_STRING|P_VI_DEF|P_SECURE|P_FUNC, (char_u *)&p_opfunc, PV_NONE, - did_set_operatorfunc, + did_set_operatorfunc, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"optimize", "opt", P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"osfiletype", "oft", P_STRING|P_ALLOCED|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"packpath", "pp", P_STRING|P_VI_DEF|P_EXPAND|P_ONECOMMA|P_NODUP |P_SECURE, - (char_u *)&p_pp, PV_NONE, NULL, + (char_u *)&p_pp, PV_NONE, NULL, NULL, {(char_u *)DFLT_RUNTIMEPATH, (char_u *)0L} SCTX_INIT}, {"paragraphs", "para", P_STRING|P_VI_DEF, - (char_u *)&p_para, PV_NONE, NULL, + (char_u *)&p_para, PV_NONE, NULL, NULL, {(char_u *)"IPLPPPQPP TPHPLIPpLpItpplpipbp", (char_u *)0L} SCTX_INIT}, {"paste", NULL, P_BOOL|P_VI_DEF|P_PRI_MKRC, - (char_u *)&p_paste, PV_NONE, did_set_paste, + (char_u *)&p_paste, PV_NONE, did_set_paste, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"pastetoggle", "pt", P_STRING|P_VI_DEF, - (char_u *)&p_pt, PV_NONE, did_set_pastetoggle, + (char_u *)&p_pt, PV_NONE, did_set_pastetoggle, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"patchexpr", "pex", P_STRING|P_VI_DEF|P_SECURE, #if defined(FEAT_DIFF) && defined(FEAT_EVAL) - (char_u *)&p_pex, PV_NONE, did_set_optexpr, + (char_u *)&p_pex, PV_NONE, did_set_optexpr, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"patchmode", "pm", P_STRING|P_VI_DEF|P_NFNAME, (char_u *)&p_pm, PV_NONE, - did_set_backupext_or_patchmode, + did_set_backupext_or_patchmode, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"path", "pa", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP, - (char_u *)&p_path, PV_PATH, NULL, + (char_u *)&p_path, PV_PATH, NULL, NULL, { #if defined(AMIGA) || defined(MSWIN) (char_u *)".,,", @@ -1971,70 +1976,70 @@ static struct vimoption options[] = (char_u *)0L} SCTX_INIT}, {"perldll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(DYNAMIC_PERL) - (char_u *)&p_perldll, PV_NONE, NULL, + (char_u *)&p_perldll, PV_NONE, NULL, NULL, {(char_u *)DYNAMIC_PERL_DLL, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"preserveindent", "pi", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_pi, PV_PI, NULL, + (char_u *)&p_pi, PV_PI, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"previewheight", "pvh", P_NUM|P_VI_DEF, #if defined(FEAT_QUICKFIX) - (char_u *)&p_pvh, PV_NONE, NULL, + (char_u *)&p_pvh, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)12L, (char_u *)0L} SCTX_INIT}, - {"previewpopup", "pvp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP, + {"previewpopup", "pvp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_COLON, #ifdef FEAT_PROP_POPUP - (char_u *)&p_pvp, PV_NONE, did_set_previewpopup, + (char_u *)&p_pvp, PV_NONE, did_set_previewpopup, expand_set_popupoption, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"previewwindow", "pvw", P_BOOL|P_VI_DEF|P_RSTAT|P_NOGLOB, #if defined(FEAT_QUICKFIX) - (char_u *)VAR_WIN, PV_PVW, did_set_previewwindow, + (char_u *)VAR_WIN, PV_PVW, did_set_previewwindow, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"printdevice", "pdev", P_STRING|P_VI_DEF|P_SECURE, #ifdef FEAT_PRINTER - (char_u *)&p_pdev, PV_NONE, NULL, + (char_u *)&p_pdev, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"printencoding", "penc", P_STRING|P_VI_DEF, #ifdef FEAT_POSTSCRIPT (char_u *)&p_penc, PV_NONE, - did_set_printencoding, + did_set_printencoding, expand_set_encoding, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"printexpr", "pexpr", P_STRING|P_VI_DEF|P_SECURE, #ifdef FEAT_POSTSCRIPT - (char_u *)&p_pexpr, PV_NONE, did_set_optexpr, + (char_u *)&p_pexpr, PV_NONE, did_set_optexpr, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"printfont", "pfn", P_STRING|P_VI_DEF, #ifdef FEAT_PRINTER - (char_u *)&p_pfn, PV_NONE, NULL, + (char_u *)&p_pfn, PV_NONE, NULL, NULL, { # ifdef MSWIN (char_u *)"Courier_New:h10", @@ -2043,253 +2048,253 @@ static struct vimoption options[] = # endif (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"printheader", "pheader", P_STRING|P_VI_DEF|P_GETTEXT, #ifdef FEAT_PRINTER - (char_u *)&p_header, PV_NONE, NULL, + (char_u *)&p_header, PV_NONE, NULL, NULL, // untranslated to avoid problems when 'encoding' // is changed {(char_u *)"%<%f%h%m%=Page %N", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, - {"printmbcharset", "pmbcs", P_STRING|P_VI_DEF, + {"printmbcharset", "pmbcs", P_STRING|P_VI_DEF, #if defined(FEAT_POSTSCRIPT) - (char_u *)&p_pmcs, PV_NONE, NULL, + (char_u *)&p_pmcs, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"printmbfont", "pmbfn", P_STRING|P_VI_DEF, #if defined(FEAT_POSTSCRIPT) - (char_u *)&p_pmfn, PV_NONE, parse_printmbfont, + (char_u *)&p_pmfn, PV_NONE, parse_printmbfont, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"printoptions", "popt", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, #ifdef FEAT_PRINTER - (char_u *)&p_popt, PV_NONE, parse_printoptions, + (char_u *)&p_popt, PV_NONE, parse_printoptions, expand_set_printoptions, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"prompt", NULL, P_BOOL|P_VI_DEF, - (char_u *)&p_prompt, PV_NONE, NULL, + (char_u *)&p_prompt, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"pumheight", "ph", P_NUM|P_VI_DEF, - (char_u *)&p_ph, PV_NONE, NULL, + (char_u *)&p_ph, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"pumwidth", "pw", P_NUM|P_VI_DEF, - (char_u *)&p_pw, PV_NONE, NULL, + (char_u *)&p_pw, PV_NONE, NULL, NULL, {(char_u *)15L, (char_u *)15L} SCTX_INIT}, {"pythonthreedll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(DYNAMIC_PYTHON3) - (char_u *)&p_py3dll, PV_NONE, NULL, + (char_u *)&p_py3dll, PV_NONE, NULL, NULL, {(char_u *)DYNAMIC_PYTHON3_DLL, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"pythonthreehome", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(FEAT_PYTHON3) - (char_u *)&p_py3home, PV_NONE, NULL, + (char_u *)&p_py3home, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"pythondll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(DYNAMIC_PYTHON) - (char_u *)&p_pydll, PV_NONE, NULL, + (char_u *)&p_pydll, PV_NONE, NULL, NULL, {(char_u *)DYNAMIC_PYTHON_DLL, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"pythonhome", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(FEAT_PYTHON) - (char_u *)&p_pyhome, PV_NONE, NULL, + (char_u *)&p_pyhome, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"pyxversion", "pyx", P_NUM|P_VI_DEF|P_SECURE, #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) - (char_u *)&p_pyx, PV_NONE, did_set_pyxversion, + (char_u *)&p_pyx, PV_NONE, did_set_pyxversion, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)DEFAULT_PYTHON_VER, (char_u *)0L} SCTX_INIT}, {"quickfixtextfunc", "qftf", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_SECURE|P_FUNC, #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) (char_u *)&p_qftf, PV_NONE, - did_set_quickfixtextfunc, + did_set_quickfixtextfunc, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)NULL} #endif SCTX_INIT}, {"quoteescape", "qe", P_STRING|P_ALLOCED|P_VI_DEF, - (char_u *)&p_qe, PV_QE, NULL, + (char_u *)&p_qe, PV_QE, NULL, NULL, {(char_u *)"\\", (char_u *)0L} SCTX_INIT}, {"readonly", "ro", P_BOOL|P_VI_DEF|P_RSTAT|P_NOGLOB, - (char_u *)&p_ro, PV_RO, did_set_readonly, + (char_u *)&p_ro, PV_RO, did_set_readonly, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"redraw", NULL, P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"redrawtime", "rdt", P_NUM|P_VI_DEF, #ifdef FEAT_RELTIME - (char_u *)&p_rdt, PV_NONE, NULL, + (char_u *)&p_rdt, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)2000L, (char_u *)0L} SCTX_INIT}, {"regexpengine", "re", P_NUM|P_VI_DEF, - (char_u *)&p_re, PV_NONE, NULL, + (char_u *)&p_re, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"relativenumber", "rnu", P_BOOL|P_VI_DEF|P_RWIN, (char_u *)VAR_WIN, PV_RNU, - did_set_number_relativenumber, + did_set_number_relativenumber, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"remap", NULL, P_BOOL|P_VI_DEF, - (char_u *)&p_remap, PV_NONE, NULL, + (char_u *)&p_remap, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"renderoptions", "rop", P_STRING|P_ONECOMMA|P_RCLR|P_VI_DEF, #ifdef FEAT_RENDER_OPTIONS - (char_u *)&p_rop, PV_NONE, did_set_renderoptions, + (char_u *)&p_rop, PV_NONE, did_set_renderoptions, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"report", NULL, P_NUM|P_VI_DEF, - (char_u *)&p_report, PV_NONE, NULL, + (char_u *)&p_report, PV_NONE, NULL, NULL, {(char_u *)2L, (char_u *)0L} SCTX_INIT}, {"restorescreen", "rs", P_BOOL|P_VI_DEF, #ifdef MSWIN - (char_u *)&p_rs, PV_NONE, NULL, + (char_u *)&p_rs, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"revins", "ri", P_BOOL|P_VI_DEF|P_VIM, #ifdef FEAT_RIGHTLEFT - (char_u *)&p_ri, PV_NONE, NULL, + (char_u *)&p_ri, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"rightleft", "rl", P_BOOL|P_VI_DEF|P_RWIN, #ifdef FEAT_RIGHTLEFT - (char_u *)VAR_WIN, PV_RL, NULL, + (char_u *)VAR_WIN, PV_RL, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"rightleftcmd", "rlc", P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN, #ifdef FEAT_RIGHTLEFT - (char_u *)VAR_WIN, PV_RLC, did_set_rightleftcmd, + (char_u *)VAR_WIN, PV_RLC, did_set_rightleftcmd, expand_set_rightleftcmd, {(char_u *)"search", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"rubydll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(DYNAMIC_RUBY) - (char_u *)&p_rubydll, PV_NONE, NULL, + (char_u *)&p_rubydll, PV_NONE, NULL, NULL, {(char_u *)DYNAMIC_RUBY_DLL, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"ruler", "ru", P_BOOL|P_VI_DEF|P_VIM|P_RSTAT, - (char_u *)&p_ru, PV_NONE, NULL, + (char_u *)&p_ru, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"rulerformat", "ruf", P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT|P_MLE, #ifdef FEAT_STL_OPT - (char_u *)&p_ruf, PV_NONE, did_set_rulerformat, + (char_u *)&p_ruf, PV_NONE, did_set_rulerformat, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"runtimepath", "rtp", P_STRING|P_VI_DEF|P_EXPAND|P_ONECOMMA|P_NODUP |P_SECURE, - (char_u *)&p_rtp, PV_NONE, NULL, + (char_u *)&p_rtp, PV_NONE, NULL, NULL, {(char_u *)DFLT_RUNTIMEPATH, (char_u *)0L} SCTX_INIT}, {"scroll", "scr", P_NUM|P_NO_MKRC|P_VI_DEF, - (char_u *)VAR_WIN, PV_SCROLL, NULL, + (char_u *)VAR_WIN, PV_SCROLL, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"scrollbind", "scb", P_BOOL|P_VI_DEF, - (char_u *)VAR_WIN, PV_SCBIND, did_set_scrollbind, + (char_u *)VAR_WIN, PV_SCBIND, did_set_scrollbind, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"scrollfocus", "scf", P_BOOL|P_VI_DEF, #if defined(MSWIN) && defined(FEAT_GUI) - (char_u *)&p_scf, PV_NONE, NULL, + (char_u *)&p_scf, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"scrolljump", "sj", P_NUM|P_VI_DEF|P_VIM, - (char_u *)&p_sj, PV_NONE, NULL, + (char_u *)&p_sj, PV_NONE, NULL, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"scrolloff", "so", P_NUM|P_VI_DEF|P_VIM|P_RALL, - (char_u *)&p_so, PV_SO, NULL, + (char_u *)&p_so, PV_SO, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"scrollopt", "sbo", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_sbo, PV_NONE, did_set_scrollopt, + (char_u *)&p_sbo, PV_NONE, did_set_scrollopt, expand_set_scrollopt, {(char_u *)"ver,jump", (char_u *)0L} SCTX_INIT}, {"sections", "sect", P_STRING|P_VI_DEF, - (char_u *)&p_sections, PV_NONE, NULL, + (char_u *)&p_sections, PV_NONE, NULL, NULL, {(char_u *)"SHNHH HUnhsh", (char_u *)0L} SCTX_INIT}, {"secure", NULL, P_BOOL|P_VI_DEF|P_SECURE, - (char_u *)&p_secure, PV_NONE, NULL, + (char_u *)&p_secure, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"selection", "sel", P_STRING|P_VI_DEF, - (char_u *)&p_sel, PV_NONE, did_set_selection, + (char_u *)&p_sel, PV_NONE, did_set_selection, expand_set_selection, {(char_u *)"inclusive", (char_u *)0L} SCTX_INIT}, {"selectmode", "slm", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_slm, PV_NONE, did_set_selectmode, + (char_u *)&p_slm, PV_NONE, did_set_selectmode, expand_set_selectmode, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"sessionoptions", "ssop", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, #ifdef FEAT_SESSION (char_u *)&p_ssop, PV_NONE, - did_set_sessionoptions, + did_set_sessionoptions, expand_set_sessionoptions, {(char_u *)"blank,buffers,curdir,folds,help,options,tabpages,winsize,terminal", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"shell", "sh", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, - (char_u *)&p_sh, PV_NONE, NULL, + (char_u *)&p_sh, PV_NONE, NULL, NULL, { #ifdef VMS (char_u *)"-", @@ -2302,7 +2307,7 @@ static struct vimoption options[] = #endif // VMS (char_u *)0L} SCTX_INIT}, {"shellcmdflag","shcf", P_STRING|P_VI_DEF|P_SECURE, - (char_u *)&p_shcf, PV_NONE, NULL, + (char_u *)&p_shcf, PV_NONE, NULL, NULL, { #if defined(MSWIN) (char_u *)"/c", @@ -2312,7 +2317,7 @@ static struct vimoption options[] = (char_u *)0L} SCTX_INIT}, {"shellpipe", "sp", P_STRING|P_VI_DEF|P_SECURE, #ifdef FEAT_QUICKFIX - (char_u *)&p_sp, PV_NONE, NULL, + (char_u *)&p_sp, PV_NONE, NULL, NULL, { #if defined(UNIX) (char_u *)"| tee", @@ -2321,35 +2326,35 @@ static struct vimoption options[] = #endif (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"shellquote", "shq", P_STRING|P_VI_DEF|P_SECURE, - (char_u *)&p_shq, PV_NONE, NULL, + (char_u *)&p_shq, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"shellredir", "srr", P_STRING|P_VI_DEF|P_SECURE, - (char_u *)&p_srr, PV_NONE, NULL, + (char_u *)&p_srr, PV_NONE, NULL, NULL, {(char_u *)">", (char_u *)0L} SCTX_INIT}, {"shellslash", "ssl", P_BOOL|P_VI_DEF, #ifdef BACKSLASH_IN_FILENAME - (char_u *)&p_ssl, PV_NONE, did_set_shellslash, + (char_u *)&p_ssl, PV_NONE, did_set_shellslash, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"shelltemp", "stmp", P_BOOL, - (char_u *)&p_stmp, PV_NONE, NULL, + (char_u *)&p_stmp, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)TRUE} SCTX_INIT}, {"shelltype", "st", P_NUM|P_VI_DEF, #ifdef AMIGA - (char_u *)&p_st, PV_NONE, NULL, + (char_u *)&p_st, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"shellxquote", "sxq", P_STRING|P_VI_DEF|P_SECURE, - (char_u *)&p_sxq, PV_NONE, NULL, + (char_u *)&p_sxq, PV_NONE, NULL, NULL, { #if defined(UNIX) && defined(USE_SYSTEM) (char_u *)"\"", @@ -2358,7 +2363,7 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"shellxescape", "sxe", P_STRING|P_VI_DEF|P_SECURE, - (char_u *)&p_sxe, PV_NONE, NULL, + (char_u *)&p_sxe, PV_NONE, NULL, NULL, { #if defined(MSWIN) (char_u *)"\"&|<>()@^", @@ -2367,28 +2372,28 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"shiftround", "sr", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_sr, PV_NONE, NULL, + (char_u *)&p_sr, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"shiftwidth", "sw", P_NUM|P_VI_DEF, (char_u *)&p_sw, PV_SW, - did_set_shiftwidth_tabstop, + did_set_shiftwidth_tabstop, NULL, {(char_u *)8L, (char_u *)0L} SCTX_INIT}, {"shortmess", "shm", P_STRING|P_VIM|P_FLAGLIST, - (char_u *)&p_shm, PV_NONE, did_set_shortmess, + (char_u *)&p_shm, PV_NONE, did_set_shortmess, expand_set_shortmess, {(char_u *)"S", (char_u *)"filnxtToOS"} SCTX_INIT}, {"shortname", "sn", P_BOOL|P_VI_DEF, - (char_u *)&p_sn, PV_SN, NULL, + (char_u *)&p_sn, PV_SN, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"showbreak", "sbr", P_STRING|P_VI_DEF|P_RALL, #ifdef FEAT_LINEBREAK - (char_u *)&p_sbr, PV_SBR, did_set_showbreak, + (char_u *)&p_sbr, PV_SBR, did_set_showbreak, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"showcmd", "sc", P_BOOL|P_VIM, - (char_u *)&p_sc, PV_NONE, NULL, + (char_u *)&p_sc, PV_NONE, NULL, NULL, {(char_u *)FALSE, #ifdef UNIX (char_u *)FALSE @@ -2397,182 +2402,182 @@ static struct vimoption options[] = #endif } SCTX_INIT}, {"showcmdloc", "sloc", P_STRING|P_RSTAT, - (char_u *)&p_sloc, PV_NONE, did_set_showcmdloc, + (char_u *)&p_sloc, PV_NONE, did_set_showcmdloc, expand_set_showcmdloc, {(char_u *)"last", (char_u *)"last"} SCTX_INIT}, {"showfulltag", "sft", P_BOOL|P_VI_DEF, - (char_u *)&p_sft, PV_NONE, NULL, + (char_u *)&p_sft, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"showmatch", "sm", P_BOOL|P_VI_DEF, - (char_u *)&p_sm, PV_NONE, NULL, + (char_u *)&p_sm, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"showmode", "smd", P_BOOL|P_VIM, - (char_u *)&p_smd, PV_NONE, NULL, + (char_u *)&p_smd, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)TRUE} SCTX_INIT}, {"showtabline", "stal", P_NUM|P_VI_DEF|P_RALL, - (char_u *)&p_stal, PV_NONE, did_set_showtabline, + (char_u *)&p_stal, PV_NONE, did_set_showtabline, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"sidescroll", "ss", P_NUM|P_VI_DEF, - (char_u *)&p_ss, PV_NONE, NULL, + (char_u *)&p_ss, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"sidescrolloff", "siso", P_NUM|P_VI_DEF|P_VIM|P_RBUF, - (char_u *)&p_siso, PV_SISO, NULL, + (char_u *)&p_siso, PV_SISO, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"signcolumn", "scl", P_STRING|P_ALLOCED|P_VI_DEF|P_RCLR, #ifdef FEAT_SIGNS - (char_u *)VAR_WIN, PV_SCL, did_set_signcolumn, + (char_u *)VAR_WIN, PV_SCL, did_set_signcolumn, expand_set_signcolumn, {(char_u *)"auto", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"slowopen", "slow", P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"smartcase", "scs", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_scs, PV_NONE, NULL, + (char_u *)&p_scs, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"smartindent", "si", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_si, PV_SI, NULL, + (char_u *)&p_si, PV_SI, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"smarttab", "sta", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_sta, PV_NONE, NULL, + (char_u *)&p_sta, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"smoothscroll", "sms", P_BOOL|P_VI_DEF|P_RWIN, - (char_u *)VAR_WIN, PV_SMS, did_set_smoothscroll, + (char_u *)VAR_WIN, PV_SMS, did_set_smoothscroll, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"softtabstop", "sts", P_NUM|P_VI_DEF|P_VIM, - (char_u *)&p_sts, PV_STS, NULL, + (char_u *)&p_sts, PV_STS, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"sourceany", NULL, P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"spell", NULL, P_BOOL|P_VI_DEF|P_RWIN, #ifdef FEAT_SPELL - (char_u *)VAR_WIN, PV_SPELL, did_set_spell, + (char_u *)VAR_WIN, PV_SPELL, did_set_spell, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"spellcapcheck", "spc", P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF, #ifdef FEAT_SPELL - (char_u *)&p_spc, PV_SPC, did_set_spellcapcheck, + (char_u *)&p_spc, PV_SPC, did_set_spellcapcheck, NULL, {(char_u *)"[.?!]\\_[\\])'\" ]\\+", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"spellfile", "spf", P_STRING|P_EXPAND|P_ALLOCED|P_VI_DEF|P_SECURE |P_ONECOMMA, #ifdef FEAT_SPELL - (char_u *)&p_spf, PV_SPF, did_set_spellfile, + (char_u *)&p_spf, PV_SPF, did_set_spellfile, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"spelllang", "spl", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA |P_RBUF|P_EXPAND, #ifdef FEAT_SPELL - (char_u *)&p_spl, PV_SPL, did_set_spelllang, + (char_u *)&p_spl, PV_SPL, did_set_spelllang, NULL, {(char_u *)"en", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"spelloptions", "spo", P_STRING|P_ALLOCED|P_VI_DEF |P_ONECOMMA|P_NODUP|P_RBUF, #ifdef FEAT_SPELL - (char_u *)&p_spo, PV_SPO, did_set_spelloptions, + (char_u *)&p_spo, PV_SPO, did_set_spelloptions, expand_set_spelloptions, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"spellsuggest", "sps", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE|P_ONECOMMA, #ifdef FEAT_SPELL - (char_u *)&p_sps, PV_NONE, did_set_spellsuggest, + (char_u *)&p_sps, PV_NONE, did_set_spellsuggest, expand_set_spellsuggest, {(char_u *)"best", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"splitbelow", "sb", P_BOOL|P_VI_DEF, - (char_u *)&p_sb, PV_NONE, NULL, + (char_u *)&p_sb, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"splitkeep", "spk", P_STRING, - (char_u *)&p_spk, PV_NONE, did_set_splitkeep, + (char_u *)&p_spk, PV_NONE, did_set_splitkeep, expand_set_splitkeep, {(char_u *)"cursor", (char_u *)"cursor"} SCTX_INIT}, {"splitright", "spr", P_BOOL|P_VI_DEF, - (char_u *)&p_spr, PV_NONE, NULL, + (char_u *)&p_spr, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"startofline", "sol", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_sol, PV_NONE, NULL, + (char_u *)&p_sol, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"statusline" ,"stl", P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT|P_MLE, #ifdef FEAT_STL_OPT - (char_u *)&p_stl, PV_STL, did_set_statusline, + (char_u *)&p_stl, PV_STL, did_set_statusline, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"suffixes", "su", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_su, PV_NONE, NULL, + (char_u *)&p_su, PV_NONE, NULL, NULL, {(char_u *)".bak,~,.o,.h,.info,.swp,.obj", (char_u *)0L} SCTX_INIT}, {"suffixesadd", "sua", P_STRING|P_VI_DEF|P_ALLOCED|P_ONECOMMA|P_NODUP, - (char_u *)&p_sua, PV_SUA, NULL, + (char_u *)&p_sua, PV_SUA, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"swapfile", "swf", P_BOOL|P_VI_DEF|P_RSTAT, - (char_u *)&p_swf, PV_SWF, did_set_swapfile, + (char_u *)&p_swf, PV_SWF, did_set_swapfile, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"swapsync", "sws", P_STRING|P_VI_DEF, - (char_u *)&p_sws, PV_NONE, did_set_swapsync, + (char_u *)&p_sws, PV_NONE, did_set_swapsync, expand_set_swapsync, {(char_u *)"fsync", (char_u *)0L} SCTX_INIT}, {"switchbuf", "swb", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_swb, PV_NONE, did_set_switchbuf, + (char_u *)&p_swb, PV_NONE, did_set_switchbuf, expand_set_switchbuf, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"synmaxcol", "smc", P_NUM|P_VI_DEF|P_RBUF, #ifdef FEAT_SYN_HL - (char_u *)&p_smc, PV_SMC, NULL, + (char_u *)&p_smc, PV_SMC, NULL, NULL, {(char_u *)3000L, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"syntax", "syn", P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME, #ifdef FEAT_SYN_HL (char_u *)&p_syn, PV_SYN, - did_set_filetype_or_syntax, + did_set_filetype_or_syntax, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"tabline", "tal", P_STRING|P_VI_DEF|P_RALL|P_MLE, #ifdef FEAT_STL_OPT - (char_u *)&p_tal, PV_NONE, did_set_tabline, + (char_u *)&p_tal, PV_NONE, did_set_tabline, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"tabpagemax", "tpm", P_NUM|P_VI_DEF, - (char_u *)&p_tpm, PV_NONE, NULL, + (char_u *)&p_tpm, PV_NONE, NULL, NULL, {(char_u *)10L, (char_u *)0L} SCTX_INIT}, {"tabstop", "ts", P_NUM|P_VI_DEF|P_RBUF, (char_u *)&p_ts, PV_TS, - did_set_shiftwidth_tabstop, + did_set_shiftwidth_tabstop, NULL, {(char_u *)8L, (char_u *)0L} SCTX_INIT}, {"tagbsearch", "tbs", P_BOOL|P_VI_DEF, - (char_u *)&p_tbs, PV_NONE, NULL, + (char_u *)&p_tbs, PV_NONE, NULL, NULL, #ifdef VMS // binary searching doesn't appear to work on VMS {(char_u *)0L, (char_u *)0L} #else @@ -2580,25 +2585,25 @@ static struct vimoption options[] = #endif SCTX_INIT}, {"tagcase", "tc", P_STRING|P_VIM, - (char_u *)&p_tc, PV_TC, did_set_tagcase, + (char_u *)&p_tc, PV_TC, did_set_tagcase, expand_set_tagcase, {(char_u *)"followic", (char_u *)"followic"} SCTX_INIT}, {"tagfunc", "tfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE|P_FUNC, #ifdef FEAT_EVAL - (char_u *)&p_tfu, PV_TFU, did_set_tagfunc, + (char_u *)&p_tfu, PV_TFU, did_set_tagfunc, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"taglength", "tl", P_NUM|P_VI_DEF, - (char_u *)&p_tl, PV_NONE, NULL, + (char_u *)&p_tl, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"tagrelative", "tr", P_BOOL|P_VIM, - (char_u *)&p_tr, PV_NONE, NULL, + (char_u *)&p_tr, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)TRUE} SCTX_INIT}, {"tags", "tag", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_tags, PV_TAGS, NULL, + (char_u *)&p_tags, PV_TAGS, NULL, NULL, { #if defined(FEAT_EMACS_TAGS) && !defined(CASE_INSENSITIVE_FILENAME) (char_u *)"./tags,./TAGS,tags,TAGS", @@ -2607,85 +2612,85 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"tagstack", "tgst", P_BOOL|P_VI_DEF, - (char_u *)&p_tgst, PV_NONE, NULL, + (char_u *)&p_tgst, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"tcldll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(DYNAMIC_TCL) - (char_u *)&p_tcldll, PV_NONE, NULL, + (char_u *)&p_tcldll, PV_NONE, NULL, NULL, {(char_u *)DYNAMIC_TCL_DLL, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"term", NULL, P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL, - (char_u *)&T_NAME, PV_NONE, did_set_term, + (char_u *)&T_NAME, PV_NONE, did_set_term, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"termbidi", "tbidi", P_BOOL|P_VI_DEF, #ifdef FEAT_ARABIC - (char_u *)&p_tbidi, PV_NONE, NULL, + (char_u *)&p_tbidi, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"termencoding", "tenc", P_STRING|P_VI_DEF|P_RCLR, - (char_u *)&p_tenc, PV_NONE, did_set_encoding, + (char_u *)&p_tenc, PV_NONE, did_set_encoding, expand_set_encoding, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"termguicolors", "tgc", P_BOOL|P_VI_DEF|P_VIM|P_RCLR, #ifdef FEAT_TERMGUICOLORS - (char_u *)&p_tgc, PV_NONE, did_set_termguicolors, + (char_u *)&p_tgc, PV_NONE, did_set_termguicolors, NULL, {(char_u *)FALSE, (char_u *)FALSE} #else - (char_u*)NULL, PV_NONE, NULL, + (char_u*)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)FALSE} #endif SCTX_INIT}, {"termwinkey", "twk", P_STRING|P_ALLOCED|P_RWIN|P_VI_DEF, #ifdef FEAT_TERMINAL - (char_u *)VAR_WIN, PV_TWK, did_set_termwinkey, + (char_u *)VAR_WIN, PV_TWK, did_set_termwinkey, NULL, {(char_u *)"", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"termwinscroll", "twsl", P_NUM|P_VI_DEF|P_VIM|P_RBUF, #ifdef FEAT_TERMINAL - (char_u *)&p_twsl, PV_TWSL, NULL, + (char_u *)&p_twsl, PV_TWSL, NULL, NULL, {(char_u *)10000L, (char_u *)10000L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"termwinsize", "tws", P_STRING|P_ALLOCED|P_RWIN|P_VI_DEF, #ifdef FEAT_TERMINAL - (char_u *)VAR_WIN, PV_TWS, did_set_termwinsize, + (char_u *)VAR_WIN, PV_TWS, did_set_termwinsize, NULL, {(char_u *)"", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"termwintype", "twt", P_STRING|P_ALLOCED|P_VI_DEF, #if defined(MSWIN) && defined(FEAT_TERMINAL) - (char_u *)&p_twt, PV_NONE, did_set_termwintype, + (char_u *)&p_twt, PV_NONE, did_set_termwintype, expand_set_termwintype, {(char_u *)"", (char_u *)NULL} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"terse", NULL, P_BOOL|P_VI_DEF, - (char_u *)&p_terse, PV_NONE, did_set_terse, + (char_u *)&p_terse, PV_NONE, did_set_terse, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"textauto", "ta", P_BOOL|P_VIM, - (char_u *)&p_ta, PV_NONE, did_set_textauto, + (char_u *)&p_ta, PV_NONE, did_set_textauto, NULL, {(char_u *)DFLT_TEXTAUTO, (char_u *)TRUE} SCTX_INIT}, {"textmode", "tx", P_BOOL|P_VI_DEF|P_NO_MKRC, - (char_u *)&p_tx, PV_TX, did_set_textmode, + (char_u *)&p_tx, PV_TX, did_set_textmode, NULL, { #ifdef USE_CRNL (char_u *)TRUE, @@ -2694,115 +2699,115 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"textwidth", "tw", P_NUM|P_VI_DEF|P_VIM|P_RBUF, - (char_u *)&p_tw, PV_TW, did_set_textwidth, + (char_u *)&p_tw, PV_TW, did_set_textwidth, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"thesaurus", "tsr", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME, - (char_u *)&p_tsr, PV_TSR, NULL, + (char_u *)&p_tsr, PV_TSR, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"thesaurusfunc", "tsrfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE|P_FUNC, #ifdef FEAT_COMPL_FUNC (char_u *)&p_tsrfu, PV_TSRFU, - did_set_thesaurusfunc, + did_set_thesaurusfunc, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"tildeop", "top", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_to, PV_NONE, NULL, + (char_u *)&p_to, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"timeout", "to", P_BOOL|P_VI_DEF, - (char_u *)&p_timeout, PV_NONE, NULL, + (char_u *)&p_timeout, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"timeoutlen", "tm", P_NUM|P_VI_DEF, - (char_u *)&p_tm, PV_NONE, NULL, + (char_u *)&p_tm, PV_NONE, NULL, NULL, {(char_u *)1000L, (char_u *)0L} SCTX_INIT}, {"title", NULL, P_BOOL|P_VI_DEF, - (char_u *)&p_title, PV_NONE, did_set_title_icon, + (char_u *)&p_title, PV_NONE, did_set_title_icon, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"titlelen", NULL, P_NUM|P_VI_DEF, - (char_u *)&p_titlelen, PV_NONE, did_set_titlelen, + (char_u *)&p_titlelen, PV_NONE, did_set_titlelen, NULL, {(char_u *)85L, (char_u *)0L} SCTX_INIT}, {"titleold", NULL, P_STRING|P_VI_DEF|P_GETTEXT|P_SECURE|P_NO_MKRC, - (char_u *)&p_titleold, PV_NONE, NULL, + (char_u *)&p_titleold, PV_NONE, NULL, NULL, {(char_u *)N_("Thanks for flying Vim"), (char_u *)0L} SCTX_INIT}, {"titlestring", NULL, P_STRING|P_VI_DEF|P_MLE, (char_u *)&p_titlestring, PV_NONE, - did_set_titlestring, + did_set_titlestring, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"toolbar", "tb", P_STRING|P_ONECOMMA|P_VI_DEF|P_NODUP, #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN) - (char_u *)&p_toolbar, PV_NONE, did_set_toolbar, + (char_u *)&p_toolbar, PV_NONE, did_set_toolbar, expand_set_toolbar, {(char_u *)"icons,tooltips", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"toolbariconsize", "tbis", P_STRING|P_VI_DEF, #if defined(FEAT_TOOLBAR) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM)) (char_u *)&p_tbis, PV_NONE, - did_set_toolbariconsize, + did_set_toolbariconsize, expand_set_toolbariconsize, {(char_u *)"small", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"transparency", "transp", P_NUM|P_VIM|P_RCLR, #ifdef FEAT_TRANSPARENCY - (char_u *)&p_transp, PV_NONE, did_set_transparency, + (char_u *)&p_transp, PV_NONE, did_set_transparency, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"ttimeout", NULL, P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_ttimeout, PV_NONE, NULL, + (char_u *)&p_ttimeout, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"ttimeoutlen", "ttm", P_NUM|P_VI_DEF, - (char_u *)&p_ttm, PV_NONE, NULL, + (char_u *)&p_ttm, PV_NONE, NULL, NULL, {(char_u *)-1L, (char_u *)0L} SCTX_INIT}, {"ttybuiltin", "tbi", P_BOOL|P_VI_DEF, - (char_u *)&p_tbi, PV_NONE, NULL, + (char_u *)&p_tbi, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"ttyfast", "tf", P_BOOL|P_NO_MKRC|P_VI_DEF, - (char_u *)&p_tf, PV_NONE, NULL, + (char_u *)&p_tf, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"ttymouse", "ttym", P_STRING|P_NODEFAULT|P_NO_MKRC|P_VI_DEF, #if defined(UNIX) || defined(VMS) - (char_u *)&p_ttym, PV_NONE, did_set_ttymouse, + (char_u *)&p_ttym, PV_NONE, did_set_ttymouse, expand_set_ttymouse, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"ttyscroll", "tsl", P_NUM|P_VI_DEF, - (char_u *)&p_ttyscroll, PV_NONE, NULL, + (char_u *)&p_ttyscroll, PV_NONE, NULL, NULL, {(char_u *)999L, (char_u *)0L} SCTX_INIT}, {"ttytype", "tty", P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL, - (char_u *)&T_NAME, PV_NONE, did_set_term, + (char_u *)&T_NAME, PV_NONE, did_set_term, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"undodir", "udir", P_STRING|P_EXPAND|P_ONECOMMA|P_NODUP|P_SECURE |P_VI_DEF, #ifdef FEAT_PERSISTENT_UNDO - (char_u *)&p_udir, PV_NONE, NULL, + (char_u *)&p_udir, PV_NONE, NULL, NULL, {(char_u *)".", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"undofile", "udf", P_BOOL|P_VI_DEF|P_VIM, #ifdef FEAT_PERSISTENT_UNDO - (char_u *)&p_udf, PV_UDF, did_set_undofile, + (char_u *)&p_udf, PV_UDF, did_set_undofile, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"undolevels", "ul", P_NUM|P_VI_DEF, - (char_u *)&p_ul, PV_UL, did_set_undolevels, + (char_u *)&p_ul, PV_UL, did_set_undolevels, NULL, { #if defined(UNIX) || defined(MSWIN) || defined(VMS) (char_u *)1000L, @@ -2811,61 +2816,61 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"undoreload", "ur", P_NUM|P_VI_DEF, - (char_u *)&p_ur, PV_NONE, NULL, + (char_u *)&p_ur, PV_NONE, NULL, NULL, { (char_u *)10000L, (char_u *)0L} SCTX_INIT}, {"updatecount", "uc", P_NUM|P_VI_DEF, - (char_u *)&p_uc, PV_NONE, did_set_updatecount, + (char_u *)&p_uc, PV_NONE, did_set_updatecount, NULL, {(char_u *)200L, (char_u *)0L} SCTX_INIT}, {"updatetime", "ut", P_NUM|P_VI_DEF, - (char_u *)&p_ut, PV_NONE, NULL, + (char_u *)&p_ut, PV_NONE, NULL, NULL, {(char_u *)4000L, (char_u *)0L} SCTX_INIT}, {"varsofttabstop", "vsts", P_STRING|P_VI_DEF|P_VIM|P_COMMA, #ifdef FEAT_VARTABS (char_u *)&p_vsts, PV_VSTS, - did_set_varsofttabstop, + did_set_varsofttabstop, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)NULL} #endif SCTX_INIT}, {"vartabstop", "vts", P_STRING|P_VI_DEF|P_VIM|P_RBUF|P_COMMA, #ifdef FEAT_VARTABS - (char_u *)&p_vts, PV_VTS, did_set_vartabstop, + (char_u *)&p_vts, PV_VTS, did_set_vartabstop, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)NULL} #endif SCTX_INIT}, {"verbose", "vbs", P_NUM|P_VI_DEF, - (char_u *)&p_verbose, PV_NONE, NULL, + (char_u *)&p_verbose, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"verbosefile", "vfile", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, - (char_u *)&p_vfile, PV_NONE, did_set_verbosefile, + (char_u *)&p_vfile, PV_NONE, did_set_verbosefile, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"viewdir", "vdir", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #ifdef FEAT_SESSION - (char_u *)&p_vdir, PV_NONE, NULL, + (char_u *)&p_vdir, PV_NONE, NULL, NULL, {(char_u *)DFLT_VDIR, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"viewoptions", "vop", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, #ifdef FEAT_SESSION - (char_u *)&p_vop, PV_NONE, did_set_viewoptions, + (char_u *)&p_vop, PV_NONE, did_set_viewoptions, expand_set_sessionoptions, {(char_u *)"folds,options,cursor,curdir", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"viminfo", "vi", P_STRING|P_ONECOMMA|P_NODUP|P_SECURE, #ifdef FEAT_VIMINFO - (char_u *)&p_viminfo, PV_NONE, did_set_viminfo, + (char_u *)&p_viminfo, PV_NONE, did_set_viminfo, NULL, #if defined(MSWIN) {(char_u *)"", (char_u *)"'100,<50,s10,h,rA:,rB:"} #elif defined(AMIGA) @@ -2875,104 +2880,104 @@ static struct vimoption options[] = {(char_u *)"", (char_u *)"'100,<50,s10,h"} #endif #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"viminfofile", "vif", P_STRING|P_EXPAND|P_ONECOMMA|P_NODUP |P_SECURE|P_VI_DEF, #ifdef FEAT_VIMINFO - (char_u *)&p_viminfofile, PV_NONE, NULL, + (char_u *)&p_viminfofile, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"virtualedit", "ve", P_STRING|P_ONECOMMA|P_NODUP|P_VI_DEF |P_VIM|P_CURSWANT, - (char_u *)&p_ve, PV_VE, did_set_virtualedit, + (char_u *)&p_ve, PV_VE, did_set_virtualedit, expand_set_virtualedit, {(char_u *)"", (char_u *)""} SCTX_INIT}, {"visualbell", "vb", P_BOOL|P_VI_DEF, - (char_u *)&p_vb, PV_NONE, NULL, + (char_u *)&p_vb, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"w300", NULL, P_NUM|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"w1200", NULL, P_NUM|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"w9600", NULL, P_NUM|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"warn", NULL, P_BOOL|P_VI_DEF, - (char_u *)&p_warn, PV_NONE, NULL, + (char_u *)&p_warn, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"weirdinvert", "wiv", P_BOOL|P_VI_DEF|P_RCLR, - (char_u *)&p_wiv, PV_NONE, did_set_weirdinvert, + (char_u *)&p_wiv, PV_NONE, did_set_weirdinvert, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"whichwrap", "ww", P_STRING|P_VIM|P_ONECOMMA|P_FLAGLIST, - (char_u *)&p_ww, PV_NONE, did_set_whichwrap, + (char_u *)&p_ww, PV_NONE, did_set_whichwrap, expand_set_whichwrap, {(char_u *)"", (char_u *)"b,s"} SCTX_INIT}, {"wildchar", "wc", P_NUM|P_VIM, - (char_u *)&p_wc, PV_NONE, NULL, + (char_u *)&p_wc, PV_NONE, NULL, NULL, {(char_u *)(long)Ctrl_E, (char_u *)(long)TAB} SCTX_INIT}, {"wildcharm", "wcm", P_NUM|P_VI_DEF, - (char_u *)&p_wcm, PV_NONE, NULL, + (char_u *)&p_wcm, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"wildignore", "wig", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_wig, PV_NONE, NULL, + (char_u *)&p_wig, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"wildignorecase", "wic", P_BOOL|P_VI_DEF, - (char_u *)&p_wic, PV_NONE, NULL, + (char_u *)&p_wic, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"wildmenu", "wmnu", P_BOOL|P_VI_DEF, - (char_u *)&p_wmnu, PV_NONE, NULL, + (char_u *)&p_wmnu, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, - {"wildmode", "wim", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_wim, PV_NONE, did_set_wildmode, + {"wildmode", "wim", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP|P_COLON, + (char_u *)&p_wim, PV_NONE, did_set_wildmode, expand_set_wildmode, {(char_u *)"full", (char_u *)0L} SCTX_INIT}, {"wildoptions", "wop", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_wop, PV_NONE, did_set_wildoptions, + (char_u *)&p_wop, PV_NONE, did_set_wildoptions, expand_set_wildoptions, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"winaltkeys", "wak", P_STRING|P_VI_DEF, #ifdef FEAT_WAK - (char_u *)&p_wak, PV_NONE, did_set_winaltkeys, + (char_u *)&p_wak, PV_NONE, did_set_winaltkeys, expand_set_winaltkeys, {(char_u *)"menu", (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, {"wincolor", "wcr", P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN, - (char_u *)VAR_WIN, PV_WCR, did_set_wincolor, + (char_u *)VAR_WIN, PV_WCR, did_set_wincolor, expand_set_wincolor, {(char_u *)"", (char_u *)NULL} SCTX_INIT}, {"window", "wi", P_NUM|P_VI_DEF, - (char_u *)&p_window, PV_NONE, did_set_window, + (char_u *)&p_window, PV_NONE, did_set_window, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"winheight", "wh", P_NUM|P_VI_DEF, (char_u *)&p_wh, PV_NONE, - did_set_winheight_helpheight, + did_set_winheight_helpheight, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"winfixheight", "wfh", P_BOOL|P_VI_DEF|P_RSTAT, - (char_u *)VAR_WIN, PV_WFH, NULL, + (char_u *)VAR_WIN, PV_WFH, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT, - (char_u *)VAR_WIN, PV_WFW, NULL, + (char_u *)VAR_WIN, PV_WFW, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"winminheight", "wmh", P_NUM|P_VI_DEF, - (char_u *)&p_wmh, PV_NONE, did_set_winminheight, + (char_u *)&p_wmh, PV_NONE, did_set_winminheight, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"winminwidth", "wmw", P_NUM|P_VI_DEF, - (char_u *)&p_wmw, PV_NONE, did_set_winminwidth, + (char_u *)&p_wmw, PV_NONE, did_set_winminwidth, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"winptydll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, #if defined(MSWIN) && defined(FEAT_TERMINAL) - (char_u *)&p_winptydll, PV_NONE, NULL, { + (char_u *)&p_winptydll, PV_NONE, NULL, NULL, { # ifdef _WIN64 (char_u *)"winpty64.dll", # else @@ -2980,30 +2985,30 @@ static struct vimoption options[] = # endif (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"winwidth", "wiw", P_NUM|P_VI_DEF, - (char_u *)&p_wiw, PV_NONE, did_set_winwidth, + (char_u *)&p_wiw, PV_NONE, did_set_winwidth, NULL, {(char_u *)20L, (char_u *)0L} SCTX_INIT}, {"wrap", NULL, P_BOOL|P_VI_DEF|P_RWIN, - (char_u *)VAR_WIN, PV_WRAP, did_set_wrap, + (char_u *)VAR_WIN, PV_WRAP, did_set_wrap, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"wrapmargin", "wm", P_NUM|P_VI_DEF, - (char_u *)&p_wm, PV_WM, NULL, + (char_u *)&p_wm, PV_WM, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"wrapscan", "ws", P_BOOL|P_VI_DEF, - (char_u *)&p_ws, PV_NONE, NULL, + (char_u *)&p_ws, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"write", NULL, P_BOOL|P_VI_DEF, - (char_u *)&p_write, PV_NONE, NULL, + (char_u *)&p_write, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"writeany", "wa", P_BOOL|P_VI_DEF, - (char_u *)&p_wa, PV_NONE, NULL, + (char_u *)&p_wa, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"writebackup", "wb", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_wb, PV_NONE, NULL, + (char_u *)&p_wb, PV_NONE, NULL, NULL, { #ifdef FEAT_WRITEBACKUP (char_u *)TRUE, @@ -3012,16 +3017,16 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"writedelay", "wd", P_NUM|P_VI_DEF, - (char_u *)&p_wd, PV_NONE, NULL, + (char_u *)&p_wd, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"xtermcodes", NULL, P_BOOL|P_VI_DEF, - (char_u *)&p_xtermcodes, PV_NONE, NULL, + (char_u *)&p_xtermcodes, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, // terminal output codes #define p_term(sss, vvv) \ {sss, NULL, P_STRING|P_VI_DEF|P_RALL|P_SECURE, \ - (char_u *)&vvv, PV_NONE, did_set_term_option, \ + (char_u *)&vvv, PV_NONE, did_set_term_option, NULL, \ {(char_u *)"", (char_u *)0L} SCTX_INIT}, p_term("t_AB", T_CAB) @@ -3117,7 +3122,7 @@ static struct vimoption options[] = // terminal key codes are not in here // end marker - {NULL, NULL, 0, NULL, PV_NONE, NULL, {NULL, NULL} SCTX_INIT} + {NULL, NULL, 0, NULL, PV_NONE, NULL, NULL, {NULL, NULL} SCTX_INIT} }; #define OPTION_COUNT ARRAY_LENGTH(options) diff --git a/src/optionstr.c b/src/optionstr.c index 2b85004830..d0f9d736a9 100644 --- a/src/optionstr.c +++ b/src/optionstr.c @@ -24,8 +24,21 @@ static char *(p_bo_values[]) = {"all", "backspace", "cursor", "complete", "hangul", "insertmode", "lang", "mess", "showmatch", "operator", "register", "shell", "spell", "term", "wildmode", NULL}; +#if defined(FEAT_LINEBREAK) +// Note: Keep this in sync with briopt_check() +static char *(p_briopt_values[]) = {"shift:", "min:", "sbr", "list:", "column:", NULL}; +#endif +#if defined(FEAT_DIFF) +// Note: Keep this in sync with diffopt_changed() +static char *(p_dip_values[]) = {"filler", "context:", "iblank", "icase", "iwhite", "iwhiteall", "iwhiteeol", "horizontal", "vertical", "closeoff", "hiddenoff", "foldcolumn:", "followwrap", "internal", "indent-heuristic", "algorithm:", NULL}; +static char *(p_dip_algorithm_values[]) = {"myers", "minimal", "patience", "histogram", NULL}; +#endif static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", NULL}; static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL}; +#ifdef FEAT_CLIPBOARD +// Note: Keep this in sync with did_set_clipboard() +static char *(p_cb_values[]) = {"unnamed", "unnamedplus", "autoselect", "autoselectplus", "autoselectml", "html", "exclude:", NULL}; +#endif #ifdef FEAT_CRYPT static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", # ifdef FEAT_SODIUM @@ -34,6 +47,10 @@ static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", NULL}; #endif static char *(p_cmp_values[]) = {"internal", "keepascii", NULL}; +#ifdef FEAT_SYN_HL +// Note: Keep this in sync with fill_culopt_flags() +static char *(p_culopt_values[]) = {"line", "screenline", "number", "both", NULL}; +#endif static char *(p_dy_values[]) = {"lastline", "truncate", "uhex", NULL}; static char *(p_jop_values[]) = {"stack", NULL}; #ifdef FEAT_FOLDING @@ -41,6 +58,18 @@ static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent", "quickfix", "search", "tag", "insert", "undo", "jump", NULL}; #endif +// Note: Keep this in sync with match_keyprotocol() +static char *(p_kpc_protocol_values[]) = {"none", "mok2", "kitty", NULL}; +#ifdef FEAT_PROP_POPUP +// Note: Keep this in sync with parse_popup_option() +static char *(p_popup_option_values[]) = {"height:", "width:", "highlight:", "border:", "align:", NULL}; +static char *(p_popup_option_border_values[]) = {"on", "off", NULL}; +static char *(p_popup_option_align_values[]) = {"item", "menu", NULL}; +#endif +#if defined(FEAT_SPELL) +// Note: Keep this in sync with spell_check_sps() +static char *(p_sps_values[]) = {"best", "fast", "double", "expr:", "file:", "timeout:", NULL}; +#endif #ifdef FEAT_SESSION // Also used for 'viewoptions'! Keep in sync with SSOP_ flags. static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize", @@ -62,6 +91,8 @@ static char *(p_tbis_values[]) = {"tiny", "small", "medium", "large", "huge", "g static char *(p_ttym_values[]) = {"xterm", "xterm2", "dec", "netterm", "jsbterm", "pterm", "urxvt", "sgr", NULL}; #endif static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", "none", "NONE", NULL}; +// Note: Keep this in sync with check_opt_wim() +static char *(p_wim_values[]) = {"full", "longest", "list", "lastused", NULL}; static char *(p_wop_values[]) = {"fuzzy", "tagfile", "pum", NULL}; #ifdef FEAT_WAK static char *(p_wak_values[]) = {"yes", "menu", "no", NULL}; @@ -699,6 +730,198 @@ did_set_option_listflag(char_u *val, char_u *flags, char *errbuf) return NULL; } +/* + * Expand an option that accepts a list of string values. + */ + int +expand_set_opt_string( + optexpand_T *args, + char **values, + int numValues, + int *numMatches, + char_u ***matches) +{ + char_u *p; + regmatch_T *regmatch = args->oe_regmatch; + int include_orig_val = args->oe_include_orig_val; + char_u *option_val = args->oe_opt_value; + + // Assume numValues is small since they are fixed enums, so just allocate + // upfront instead of needing two passes to calculate output size. + *matches = ALLOC_MULT(char_u *, numValues + 1); + if (*matches == NULL) + return FAIL; + + int count = 0; + + if (include_orig_val && *option_val != NUL) + { + p = vim_strsave(option_val); + if (p == NULL) + { + VIM_CLEAR(*matches); + return FAIL; + } + (*matches)[count++] = p; + } + + for (char **val = values; *val != NULL; val++) + { + if (include_orig_val && *option_val != NUL) + { + if (STRCMP((char_u*)*val, option_val) == 0) + continue; + } + if (vim_regexec(regmatch, (char_u*)(*val), (colnr_T)0)) + { + p = vim_strsave((char_u*)*val); + if (p == NULL) + { + if (count == 0) + { + VIM_CLEAR(*matches); + return FAIL; + } + else + break; + } + (*matches)[count++] = p; + } + } + if (count == 0) + { + VIM_CLEAR(*matches); + return FAIL; + } + *numMatches = count; + return OK; +} + +static char_u *set_opt_callback_orig_option = NULL; +static char_u *((*set_opt_callback_func)(expand_T *, int)); + +/* + * Callback used by expand_set_opt_generic to also include the original value. + */ + static char_u * +expand_set_opt_callback(expand_T *xp, int idx) +{ + if (idx == 0) + { + if (set_opt_callback_orig_option != NULL) + return set_opt_callback_orig_option; + else + return (char_u *)""; // empty strings are ignored + } + return set_opt_callback_func(xp, idx - 1); +} + +/* + * Expand an option with a callback that iterates through a list of possible names. + */ + int +expand_set_opt_generic( + optexpand_T *args, + char_u *((*func)(expand_T *, int)), + int *numMatches, + char_u ***matches) +{ + int ret; + + set_opt_callback_orig_option = args->oe_include_orig_val ? + args->oe_opt_value : NULL; + set_opt_callback_func = func; + + ret = ExpandGeneric( + (char_u*)"", // not using fuzzy as currently EXPAND_STRING_SETTING doesn't use it + args->oe_xp, + args->oe_regmatch, + matches, + numMatches, + expand_set_opt_callback, + FALSE); + + set_opt_callback_orig_option = NULL; + set_opt_callback_func = NULL; + return ret; +} + + +/* + * Expand an option which is a list of flags. + */ + int +expand_set_opt_listflag( + optexpand_T *args, + char_u *flags, + int *numMatches, + char_u ***matches) +{ + char_u *p; + char_u *option_val = args->oe_opt_value; + char_u *cmdline_val = args->oe_set_arg; + int append = args->oe_append; + int include_orig_val = args->oe_include_orig_val && (*option_val != NUL); + + int num_flags = STRLEN(flags); + + // Assume we only have small number of flags, so just allocate max size. + *matches = ALLOC_MULT(char_u *, num_flags + 1); + if (*matches == NULL) + return FAIL; + + int count = 0; + + if (include_orig_val) + { + p = vim_strsave(option_val); + if (p == NULL) + { + VIM_CLEAR(*matches); + return FAIL; + } + (*matches)[count++] = p; + } + + for (char_u *flag = flags; *flag != NUL; flag++) + { + if (append && vim_strchr(option_val, *flag) != NULL) + continue; + + if (vim_strchr(cmdline_val, *flag) == NULL) + { + if (include_orig_val + && option_val[1] == NUL + && *flag == option_val[0]) + { + // This value is already used as the first choice as it's the + // existing flag. Just skip it to avoid duplicate. + continue; + } + p = vim_strnsave(flag, 1); + if (p == NULL) + { + if (count == 0) + { + VIM_CLEAR(*matches); + return FAIL; + } + else + break; + } + (*matches)[count++] = p; + } + } + + if (count == 0) + { + VIM_CLEAR(*matches); + return FAIL; + } + *numMatches = count; + return OK; +} + /* * The 'ambiwidth' option is changed. */ @@ -711,6 +934,17 @@ did_set_ambiwidth(optset_T *args UNUSED) return check_chars_options(); } + int +expand_set_ambiwidth(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_ambw_values, + sizeof(p_ambw_values) / sizeof(p_ambw_values[0]) - 1, + numMatches, + matches); +} + /* * The 'background' option is changed. */ @@ -753,6 +987,17 @@ did_set_background(optset_T *args UNUSED) return NULL; } + int +expand_set_background(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_bg_values, + sizeof(p_bg_values) / sizeof(p_bg_values[0]) - 1, + numMatches, + matches); +} + /* * The 'backspace' option is changed. */ @@ -770,6 +1015,17 @@ did_set_backspace(optset_T *args UNUSED) return NULL; } + int +expand_set_backspace(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_bs_values, + sizeof(p_bs_values) / sizeof(p_bs_values[0]) - 1, + numMatches, + matches); +} + /* * The 'backupcopy' option is changed. */ @@ -807,6 +1063,17 @@ did_set_backupcopy(optset_T *args) return errmsg; } + int +expand_set_backupcopy(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_bkc_values, + sizeof(p_bkc_values) / sizeof(p_bkc_values[0]) - 1, + numMatches, + matches); +} + /* * The 'backupext' or the 'patchmode' option is changed. */ @@ -829,6 +1096,17 @@ did_set_belloff(optset_T *args UNUSED) return did_set_opt_flags(p_bo, p_bo_values, &bo_flags, TRUE); } + int +expand_set_belloff(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_bo_values, + sizeof(p_bo_values) / sizeof(p_bo_values[0]) - 1, + numMatches, + matches); +} + #if defined(FEAT_LINEBREAK) || defined(PROTO) /* * The 'breakindentopt' option is changed. @@ -846,6 +1124,17 @@ did_set_breakindentopt(optset_T *args UNUSED) return errmsg; } + + int +expand_set_breakindentopt(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_briopt_values, + sizeof(p_briopt_values) / sizeof(p_briopt_values[0]) - 1, + numMatches, + matches); +} #endif #if defined(FEAT_BROWSE) || defined(PROTO) @@ -861,6 +1150,17 @@ did_set_browsedir(optset_T *args UNUSED) return NULL; } + + int +expand_set_browsedir(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_bsdir_values, + sizeof(p_bsdir_values) / sizeof(p_bsdir_values[0]) - 1, + numMatches, + matches); +} #endif /* @@ -872,6 +1172,17 @@ did_set_bufhidden(optset_T *args UNUSED) return did_set_opt_strings(curbuf->b_p_bh, p_bufhidden_values, FALSE); } + int +expand_set_bufhidden(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_bufhidden_values, + sizeof(p_bufhidden_values) / sizeof(p_bufhidden_values[0]) - 1, + numMatches, + matches); +} + /* * The 'buftype' option is changed. */ @@ -892,6 +1203,17 @@ did_set_buftype(optset_T *args UNUSED) return NULL; } + int +expand_set_buftype(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_buftype_values, + sizeof(p_buftype_values) / sizeof(p_buftype_values[0]) - 1, + numMatches, + matches); +} + /* * The 'casemap' option is changed. */ @@ -901,6 +1223,30 @@ did_set_casemap(optset_T *args UNUSED) return did_set_opt_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE); } + int +expand_set_casemap(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_cmp_values, + sizeof(p_cmp_values) / sizeof(p_cmp_values[0]) - 1, + numMatches, + matches); +} + +#if defined(FEAT_CLIPBOARD) || defined(PROTO) + int +expand_set_clipboard(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_cb_values, + sizeof(p_cb_values) / sizeof(p_cb_values[0]) - 1, + numMatches, + matches); +} +#endif + /* * The global 'listchars' or 'fillchars' option is changed. */ @@ -972,6 +1318,21 @@ did_set_chars_option(optset_T *args) return errmsg; } +/* + * Expand 'fillchars' or 'listchars' option value. + */ + int +expand_set_chars_option(optexpand_T *args, int *numMatches, char_u ***matches) +{ + char_u **varp = (char_u **)args->oe_varp; + int is_lcs = (varp == &p_lcs || varp == &curwin->w_p_lcs); + return expand_set_opt_generic( + args, + is_lcs ? get_listchars_name : get_fillchars_name, + numMatches, + matches); +} + /* * The 'cinoptions' option is changed. */ @@ -1097,6 +1458,20 @@ did_set_complete(optset_T *args) return NULL; } + int +expand_set_complete(optexpand_T *args, int *numMatches, char_u ***matches) +{ + static char *(p_cpt_values[]) = { + ".", "w", "b", "u", "k", "kspell", "s", "i", "d", "]", "t", "U", + NULL}; + return expand_set_opt_string( + args, + p_cpt_values, + sizeof(p_cpt_values) / sizeof(p_cpt_values[0]) - 1, + numMatches, + matches); +} + /* * The 'completeopt' option is changed. */ @@ -1110,6 +1485,17 @@ did_set_completeopt(optset_T *args UNUSED) return NULL; } + int +expand_set_completeopt(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_cot_values, + sizeof(p_cot_values) / sizeof(p_cot_values[0]) - 1, + numMatches, + matches); +} + #if (defined(FEAT_PROP_POPUP) && defined(FEAT_QUICKFIX)) || defined(PROTO) /* * The 'completepopup' option is changed. @@ -1138,6 +1524,17 @@ did_set_completeslash(optset_T *args UNUSED) return NULL; } + + int +expand_set_completeslash(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_csl_values, + sizeof(p_csl_values) / sizeof(p_csl_values[0]) - 1, + numMatches, + matches); +} #endif #if defined(FEAT_CONCEAL) || defined(PROTO) @@ -1151,6 +1548,12 @@ did_set_concealcursor(optset_T *args) return did_set_option_listflag(*varp, (char_u *)COCU_ALL, args->os_errbuf); } + + int +expand_set_concealcursor(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_listflag(args, (char_u*)COCU_ALL, numMatches, matches); +} #endif /* @@ -1164,6 +1567,12 @@ did_set_cpoptions(optset_T *args) return did_set_option_listflag(*varp, (char_u *)CPO_ALL, args->os_errbuf); } + int +expand_set_cpoptions(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_listflag(args, (char_u*)CPO_ALL, numMatches, matches); +} + #if defined(FEAT_CRYPT) || defined(PROTO) /* * The 'cryptkey' option is changed. @@ -1250,6 +1659,17 @@ did_set_cryptmethod(optset_T *args) } return NULL; } + + int +expand_set_cryptmethod(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_cm_values, + sizeof(p_cm_values) / sizeof(p_cm_values[0]) - 1, + numMatches, + matches); +} #endif #if (defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)) || defined(PROTO) @@ -1291,11 +1711,23 @@ did_set_cursorlineopt(optset_T *args) { char_u **varp = (char_u **)args->os_varp; + // This could be changed to use opt_strings_flags() instead. if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK) return e_invalid_argument; return NULL; } + + int +expand_set_cursorlineopt(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_culopt_values, + sizeof(p_culopt_values) / sizeof(p_culopt_values[0]) - 1, + numMatches, + matches); +} #endif /* @@ -1307,6 +1739,17 @@ did_set_debug(optset_T *args UNUSED) return did_set_opt_strings(p_debug, p_debug_values, TRUE); } + int +expand_set_debug(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_debug_values, + sizeof(p_debug_values) / sizeof(p_debug_values[0]) - 1, + numMatches, + matches); +} + #if defined(FEAT_DIFF) || defined(PROTO) /* * The 'diffopt' option is changed. @@ -1319,6 +1762,36 @@ did_set_diffopt(optset_T *args UNUSED) return NULL; } + + int +expand_set_diffopt(optexpand_T *args, int *numMatches, char_u ***matches) +{ + expand_T *xp = args->oe_xp; + + if (xp->xp_pattern > args->oe_set_arg && *(xp->xp_pattern-1) == ':') + { + // Within "algorithm:", we have a subgroup of possible options. + int algo_len = STRLEN("algorithm:"); + if (xp->xp_pattern - args->oe_set_arg >= algo_len && + STRNCMP(xp->xp_pattern - algo_len, "algorithm:", algo_len) == 0) + { + return expand_set_opt_string( + args, + p_dip_algorithm_values, + sizeof(p_dip_algorithm_values) / sizeof(p_dip_algorithm_values[0]) - 1, + numMatches, + matches); + } + return FAIL; + } + + return expand_set_opt_string( + args, + p_dip_values, + sizeof(p_dip_values) / sizeof(p_dip_values[0]) - 1, + numMatches, + matches); +} #endif /* @@ -1334,6 +1807,17 @@ did_set_display(optset_T *args UNUSED) return NULL; } + int +expand_set_display(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_dy_values, + sizeof(p_dy_values) / sizeof(p_dy_values[0]) - 1, + numMatches, + matches); +} + /* * The 'eadirection' option is changed. */ @@ -1343,6 +1827,17 @@ did_set_eadirection(optset_T *args UNUSED) return did_set_opt_strings(p_ead, p_ead_values, FALSE); } + int +expand_set_eadirection(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_ead_values, + sizeof(p_ead_values) / sizeof(p_ead_values[0]) - 1, + numMatches, + matches); +} + /* * One of the 'encoding', 'fileencoding', 'termencoding' or 'makeencoding' * options is changed. @@ -1440,6 +1935,16 @@ did_set_encoding(optset_T *args) return errmsg; } + int +expand_set_encoding(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_generic( + args, + get_encoding_name, + numMatches, + matches); +} + /* * The 'eventignore' option is changed. */ @@ -1451,6 +1956,26 @@ did_set_eventignore(optset_T *args UNUSED) return NULL; } + static char_u * +get_eventignore_name(expand_T *xp, int idx) +{ + // 'eventignore' allows special keyword "all" in addition to + // all event names. + if (idx == 0) + return (char_u *)"all"; + return get_event_name_no_group(xp, idx - 1); +} + + int +expand_set_eventignore(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_generic( + args, + get_eventignore_name, + numMatches, + matches); +} + /* * The 'fileformat' option is changed. */ @@ -1480,6 +2005,17 @@ did_set_fileformat(optset_T *args) return NULL; } + int +expand_set_fileformat(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_ff_values, + sizeof(p_ff_values) / sizeof(p_ff_values[0]) - 1, + numMatches, + matches); +} + /* * The 'fileformats' option is changed. */ @@ -1527,6 +2063,17 @@ did_set_foldclose(optset_T *args UNUSED) { return did_set_opt_strings(p_fcl, p_fcl_values, TRUE); } + + int +expand_set_foldclose(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_fcl_values, + sizeof(p_fcl_values) / sizeof(p_fcl_values[0]) - 1, + numMatches, + matches); +} #endif #if (defined(FEAT_EVAL) && defined(FEAT_FOLDING)) || defined(PROTO) @@ -1593,6 +2140,17 @@ did_set_foldmethod(optset_T *args) return NULL; } + int +expand_set_foldmethod(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_fdm_values, + sizeof(p_fdm_values) / sizeof(p_fdm_values[0]) - 1, + numMatches, + matches); +} + /* * The 'foldopen' option is changed. */ @@ -1601,6 +2159,17 @@ did_set_foldopen(optset_T *args UNUSED) { return did_set_opt_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE); } + + int +expand_set_foldopen(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_fdo_values, + sizeof(p_fdo_values) / sizeof(p_fdo_values[0]) - 1, + numMatches, + matches); +} #endif /* @@ -1614,6 +2183,12 @@ did_set_formatoptions(optset_T *args) return did_set_option_listflag(*varp, (char_u *)FO_ALL, args->os_errbuf); } + int +expand_set_formatoptions(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_listflag(args, (char_u*)FO_ALL, numMatches, matches); +} + #if defined(CURSOR_SHAPE) || defined(PROTO) /* * The 'guicursor' option is changed. @@ -1732,6 +2307,12 @@ did_set_guioptions(optset_T *args) gui_init_which_components(args->os_oldval.string); return NULL; } + + int +expand_set_guioptions(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_listflag(args, (char_u*)GO_ALL, numMatches, matches); +} #endif #if defined(FEAT_GUI_TABLINE) || defined(PROTO) @@ -1797,6 +2378,125 @@ did_set_highlight(optset_T *args UNUSED) return NULL; } +/* + * Expand 'highlight' option. + */ + int +expand_set_highlight(optexpand_T *args, int *numMatches, char_u ***matches) +{ + char_u *p; + expand_T *xp = args->oe_xp; + static char_u hl_flags[HLF_COUNT] = HL_FLAGS; + int i; + int count = 0; + + if (xp->xp_pattern > args->oe_set_arg && *(xp->xp_pattern-1) == ':') + { + // Right after a ':', meaning we just return all highlight names. + return expand_set_opt_generic( + args, + get_highlight_name, + numMatches, + matches); + } + + if (*xp->xp_pattern == NUL) + { + // At beginning of a comma-separated list. Return the specific list of + // supported occasions. + *matches = ALLOC_MULT(char_u *, HLF_COUNT + 1); + if (*matches == NULL) + return FAIL; + + // We still want to return the full option if it's requested. + if (args->oe_include_orig_val) + { + p = vim_strsave(args->oe_opt_value); + if (p == NULL) + { + VIM_CLEAR(*matches); + return FAIL; + } + (*matches)[count++] = p; + } + + for (i = 0; i < HLF_COUNT; i++) + { + p = vim_strnsave(&hl_flags[i], 1); + if (p == NULL) + { + if (count == 0) + { + VIM_CLEAR(*matches); + return FAIL; + } + else + break; + } + (*matches)[count++] = p; + } + + if (count == 0) + { + VIM_CLEAR(*matches); + return FAIL; + } + *numMatches = count; + return OK; + } + + // We are after the initial character (which indicates the occasion). We + // already made sure we are not matching after a ':' above, so now we want + // to match against display mode modifiers. + // Since the xp_pattern starts from the beginning, we need to include it in + // the returned match. + + // Note: Keep this in sync with highlight_changed() + static char p_hl_mode_values[] = + {':', 'b', 'i', '-', 'n', 'r', 's', 'u', 'c', '2', 'd', '=', 't'}; + int num_hl_modes = sizeof(p_hl_mode_values) / sizeof(p_hl_mode_values[0]); + + *matches = ALLOC_MULT(char_u *, num_hl_modes); + if (*matches == NULL) + return FAIL; + + int pattern_len = STRLEN(xp->xp_pattern); + + for (i = 0; i < num_hl_modes; i++) + { + // Don't allow duplicates as these are unique flags + if (vim_strchr(xp->xp_pattern + 1, p_hl_mode_values[i]) != NULL) + continue; + + // ':' only works by itself, not with other flags. + if (pattern_len > 1 && p_hl_mode_values[i] == ':') + continue; + + p = vim_strnsave(xp->xp_pattern, pattern_len + 1); + if (p == NULL) + { + if (i == 0) + { + VIM_CLEAR(*matches); + return FAIL; + } + else + break; + } + p[pattern_len] = p_hl_mode_values[i]; + p[pattern_len + 1] = NUL; + (*matches)[count++] = p; + } + if (count == 0) + { + VIM_CLEAR(*matches); + return FAIL; + } + *numMatches = count; + + return OK; +} + /* * The 'titlestring' or the 'iconstring' option is changed. */ @@ -1876,6 +2576,17 @@ did_set_jumpoptions(optset_T *args UNUSED) return NULL; } + int +expand_set_jumpoptions(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_jop_values, + sizeof(p_jop_values) / sizeof(p_jop_values[0]) - 1, + numMatches, + matches); +} + #if defined(FEAT_KEYMAP) || defined(PROTO) /* * The 'keymap' option is changed. @@ -1949,18 +2660,54 @@ did_set_keymodel(optset_T *args UNUSED) return NULL; } + int +expand_set_keymodel(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_km_values, + sizeof(p_km_values) / sizeof(p_km_values[0]) - 1, + numMatches, + matches); +} + /* * The 'keyprotocol' option is changed. */ char * did_set_keyprotocol(optset_T *args UNUSED) { - if (match_keyprotocol(NULL) == KEYPROTOCOL_FAIL) + char_u *term = T_NAME; + keyprot_T kpc = match_keyprotocol(term); + if (kpc == KEYPROTOCOL_FAIL) return e_invalid_argument; + apply_keyprotocol(term, kpc); + return NULL; } + int +expand_set_keyprotocol(optexpand_T *args, int *numMatches, char_u ***matches) +{ + expand_T *xp = args->oe_xp; + if (xp->xp_pattern > args->oe_set_arg && *(xp->xp_pattern-1) == ':') + { + // 'keyprotocol' only has well-defined terms for completion for the + // protocol part after the colon. + return expand_set_opt_string( + args, + p_kpc_protocol_values, + sizeof(p_kpc_protocol_values) / sizeof(p_kpc_protocol_values[0]) - 1, + numMatches, + matches); + } + // Use expand_set_opt_string instead of returning FAIL so that we can + // include the original value if args->oe_include_orig_val is set. + static char *(empty[]) = {NULL}; + return expand_set_opt_string(args, empty, 0, numMatches, matches); +} + /* * The 'lispoptions' option is changed. */ @@ -1977,6 +2724,18 @@ did_set_lispoptions(optset_T *args) return NULL; } + int +expand_set_lispoptions(optexpand_T *args, int *numMatches, char_u ***matches) +{ + static char *(p_lop_values[]) = {"expr:0", "expr:1", NULL}; + return expand_set_opt_string( + args, + p_lop_values, + sizeof(p_lop_values) / sizeof(p_lop_values[0]) - 1, + numMatches, + matches); +} + /* * The 'matchpairs' option is changed. */ @@ -2048,6 +2807,12 @@ did_set_mouse(optset_T *args) args->os_errbuf); } + int +expand_set_mouse(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_listflag(args, (char_u*)MOUSE_ALL, numMatches, matches); +} + /* * The 'mousemodel' option is changed. */ @@ -2066,6 +2831,17 @@ did_set_mousemodel(optset_T *args UNUSED) return NULL; } + int +expand_set_mousemodel(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_mousem_values, + sizeof(p_mousem_values) / sizeof(p_mousem_values[0]) - 1, + numMatches, + matches); +} + #if defined(FEAT_MOUSESHAPE) || defined(PROTO) char * did_set_mouseshape(optset_T *args UNUSED) @@ -2090,6 +2866,17 @@ did_set_nrformats(optset_T *args) return did_set_opt_strings(*varp, p_nf_values, TRUE); } + int +expand_set_nrformats(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_nf_values, + sizeof(p_nf_values) / sizeof(p_nf_values[0]) - 1, + numMatches, + matches); +} + #if defined(FEAT_EVAL) || defined(PROTO) /* * One of the '*expr' options is changed: 'balloonexpr', 'diffexpr', @@ -2150,6 +2937,58 @@ did_set_previewpopup(optset_T *args UNUSED) return NULL; } + + int +expand_set_popupoption(optexpand_T *args, int *numMatches, char_u ***matches) +{ + expand_T *xp = args->oe_xp; + + if (xp->xp_pattern > args->oe_set_arg && *(xp->xp_pattern-1) == ':') + { + // Within "highlight:"/"border:"/"align:", we have a subgroup of possible options. + int border_len = STRLEN("border:"); + if (xp->xp_pattern - args->oe_set_arg >= border_len && + STRNCMP(xp->xp_pattern - border_len, "border:", border_len) == 0) + { + return expand_set_opt_string( + args, + p_popup_option_border_values, + sizeof(p_popup_option_border_values) / sizeof(p_popup_option_border_values[0]) - 1, + numMatches, + matches); + } + int align_len = STRLEN("align:"); + if (xp->xp_pattern - args->oe_set_arg >= align_len && + STRNCMP(xp->xp_pattern - align_len, "align:", align_len) == 0) + { + return expand_set_opt_string( + args, + p_popup_option_align_values, + sizeof(p_popup_option_align_values) / sizeof(p_popup_option_align_values[0]) - 1, + numMatches, + matches); + } + int highlight_len = STRLEN("highlight:"); + if (xp->xp_pattern - args->oe_set_arg >= highlight_len && + STRNCMP(xp->xp_pattern - highlight_len, "highlight:", highlight_len) == 0) + { + // Return the list of all highlight names + return expand_set_opt_generic( + args, + get_highlight_name, + numMatches, + matches); + } + return FAIL; + } + + return expand_set_opt_string( + args, + p_popup_option_values, + sizeof(p_popup_option_values) / sizeof(p_popup_option_values[0]) - 1, + numMatches, + matches); +} #endif #if defined(FEAT_POSTSCRIPT) || defined(PROTO) @@ -2184,6 +3023,30 @@ did_set_printencoding(optset_T *args UNUSED) } #endif +#if defined(FEAT_PRINTER) || defined(PROTO) + + static char_u * +get_printoptions_names(expand_T *xp UNUSED, int idx) +{ + if (idx >= (int)(sizeof(printer_opts) / sizeof(printer_opts[0]))) + return NULL; + return (char_u*)printer_opts[idx].name; +} + +/* + * Expand 'printoptions' option + */ + int +expand_set_printoptions(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_generic( + args, + get_printoptions_names, + numMatches, + matches); +} +#endif + #if defined(FEAT_STL_OPT) || defined(PROTO) /* * The 'statusline' or the 'tabline' or the 'rulerformat' option is changed. @@ -2250,6 +3113,18 @@ did_set_rightleftcmd(optset_T *args) return NULL; } + + int +expand_set_rightleftcmd(optexpand_T *args, int *numMatches, char_u ***matches) +{ + static char *(p_rlc_values[]) = {"search", NULL}; + return expand_set_opt_string( + args, + p_rlc_values, + sizeof(p_rlc_values) / sizeof(p_rlc_values[0]) - 1, + numMatches, + matches); +} #endif #if defined(FEAT_STL_OPT) || defined(PROTO) @@ -2272,6 +3147,17 @@ did_set_scrollopt(optset_T *args UNUSED) return did_set_opt_strings(p_sbo, p_scbopt_values, TRUE); } + int +expand_set_scrollopt(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_scbopt_values, + sizeof(p_scbopt_values) / sizeof(p_scbopt_values[0]) - 1, + numMatches, + matches); +} + /* * The 'selection' option is changed. */ @@ -2284,6 +3170,17 @@ did_set_selection(optset_T *args UNUSED) return NULL; } + int +expand_set_selection(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_sel_values, + sizeof(p_sel_values) / sizeof(p_sel_values[0]) - 1, + numMatches, + matches); +} + /* * The 'selectmode' option is changed. */ @@ -2293,6 +3190,17 @@ did_set_selectmode(optset_T *args UNUSED) return did_set_opt_strings(p_slm, p_slm_values, TRUE); } + int +expand_set_selectmode(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_slm_values, + sizeof(p_slm_values) / sizeof(p_slm_values[0]) - 1, + numMatches, + matches); +} + #if defined(FEAT_SESSION) || defined(PROTO) /* * The 'sessionoptions' option is changed. @@ -2312,6 +3220,17 @@ did_set_sessionoptions(optset_T *args) return NULL; } + + int +expand_set_sessionoptions(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_ssop_values, + sizeof(p_ssop_values) / sizeof(p_ssop_values[0]) - 1, + numMatches, + matches); +} #endif /* @@ -2325,6 +3244,12 @@ did_set_shortmess(optset_T *args) return did_set_option_listflag(*varp, (char_u *)SHM_ALL, args->os_errbuf); } + int +expand_set_shortmess(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_listflag(args, (char_u*)SHM_ALL, numMatches, matches); +} + #if defined(FEAT_LINEBREAK) || defined(PROTO) /* * The 'showbreak' option is changed. @@ -2355,6 +3280,17 @@ did_set_showcmdloc(optset_T *args UNUSED) return did_set_opt_strings(p_sloc, p_sloc_values, FALSE); } + int +expand_set_showcmdloc(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_sloc_values, + sizeof(p_sloc_values) / sizeof(p_sloc_values[0]) - 1, + numMatches, + matches); +} + #if defined(FEAT_SIGNS) || defined(PROTO) /* * The 'signcolumn' option is changed. @@ -2375,6 +3311,17 @@ did_set_signcolumn(optset_T *args) return NULL; } + + int +expand_set_signcolumn(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_scl_values, + sizeof(p_scl_values) / sizeof(p_scl_values[0]) - 1, + numMatches, + matches); +} #endif #if defined(FEAT_SPELL) || defined(PROTO) @@ -2434,6 +3381,18 @@ did_set_spelloptions(optset_T *args) return NULL; } + int +expand_set_spelloptions(optexpand_T *args, int *numMatches, char_u ***matches) +{ + static char *(p_spo_values[]) = {"camel", NULL}; + return expand_set_opt_string( + args, + p_spo_values, + sizeof(p_spo_values) / sizeof(p_spo_values[0]) - 1, + numMatches, + matches); +} + /* * The 'spellsuggest' option is changed. */ @@ -2445,6 +3404,17 @@ did_set_spellsuggest(optset_T *args UNUSED) return NULL; } + + int +expand_set_spellsuggest(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_sps_values, + sizeof(p_sps_values) / sizeof(p_sps_values[0]) - 1, + numMatches, + matches); +} #endif /* @@ -2456,6 +3426,17 @@ did_set_splitkeep(optset_T *args UNUSED) return did_set_opt_strings(p_spk, p_spk_values, FALSE); } + int +expand_set_splitkeep(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_spk_values, + sizeof(p_spk_values) / sizeof(p_spk_values[0]) - 1, + numMatches, + matches); +} + #if defined(FEAT_STL_OPT) || defined(PROTO) /* * The 'statusline' option is changed. @@ -2476,6 +3457,17 @@ did_set_swapsync(optset_T *args UNUSED) return did_set_opt_strings(p_sws, p_sws_values, FALSE); } + int +expand_set_swapsync(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_sws_values, + sizeof(p_sws_values) / sizeof(p_sws_values[0]) - 1, + numMatches, + matches); +} + /* * The 'switchbuf' option is changed. */ @@ -2485,6 +3477,17 @@ did_set_switchbuf(optset_T *args UNUSED) return did_set_opt_flags(p_swb, p_swb_values, &swb_flags, TRUE); } + int +expand_set_switchbuf(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_swb_values, + sizeof(p_swb_values) / sizeof(p_swb_values[0]) - 1, + numMatches, + matches); +} + #if defined(FEAT_STL_OPT) || defined(PROTO) /* * The 'tabline' option is changed. @@ -2526,6 +3529,17 @@ did_set_tagcase(optset_T *args) return NULL; } + int +expand_set_tagcase(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_tc_values, + sizeof(p_tc_values) / sizeof(p_tc_values[0]) - 1, + numMatches, + matches); +} + /* * The 'term' option is changed. */ @@ -2659,6 +3673,17 @@ did_set_termwintype(optset_T *args UNUSED) { return did_set_opt_strings(p_twt, p_twt_values, FALSE); } + + int +expand_set_termwintype(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_twt_values, + sizeof(p_twt_values) / sizeof(p_twt_values[0]) - 1, + numMatches, + matches); +} # endif #endif @@ -2692,6 +3717,17 @@ did_set_toolbar(optset_T *args UNUSED) (TOOLBAR_TEXT | TOOLBAR_ICONS)) != 0); return NULL; } + + int +expand_set_toolbar(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_toolbar_values, + sizeof(p_toolbar_values) / sizeof(p_toolbar_values[0]) - 1, + numMatches, + matches); +} #endif #if (defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)) || defined(FEAT_GUI_MACVIM) || defined(PROTO) @@ -2709,6 +3745,17 @@ did_set_toolbariconsize(optset_T *args UNUSED) (TOOLBAR_TEXT | TOOLBAR_ICONS)) != 0); return NULL; } + + int +expand_set_toolbariconsize(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_tbis_values, + sizeof(p_tbis_values) / sizeof(p_tbis_values[0]) - 1, + numMatches, + matches); +} #endif #if defined(UNIX) || defined(VMS) || defined(PROTO) @@ -2732,6 +3779,17 @@ did_set_ttymouse(optset_T *args UNUSED) return errmsg; } + + int +expand_set_ttymouse(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_ttym_values, + sizeof(p_ttym_values) / sizeof(p_ttym_values[0]) - 1, + numMatches, + matches); +} #endif #if defined(FEAT_VARTABS) || defined(PROTO) @@ -2938,6 +3996,17 @@ did_set_virtualedit(optset_T *args) return NULL; } + int +expand_set_virtualedit(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_ve_values, + sizeof(p_ve_values) / sizeof(p_ve_values[0]) - 1, + numMatches, + matches); +} + /* * The 'whichwrap' option is changed. */ @@ -2946,7 +4015,15 @@ did_set_whichwrap(optset_T *args) { char_u **varp = (char_u **)args->os_varp; - return did_set_option_listflag(*varp, (char_u *)WW_ALL, args->os_errbuf); + // Add ',' to the list flags because 'whichwrap' is a flag + // list that is comma-separated. + return did_set_option_listflag(*varp, (char_u *)(WW_ALL ","), args->os_errbuf); +} + + int +expand_set_whichwrap(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_listflag(args, (char_u*)WW_ALL, numMatches, matches); } /* @@ -2960,6 +4037,17 @@ did_set_wildmode(optset_T *args UNUSED) return NULL; } + int +expand_set_wildmode(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_wim_values, + sizeof(p_wim_values) / sizeof(p_wim_values[0]) - 1, + numMatches, + matches); +} + /* * The 'wildoptions' option is changed. */ @@ -2969,6 +4057,17 @@ did_set_wildoptions(optset_T *args UNUSED) return did_set_opt_strings(p_wop, p_wop_values, TRUE); } + int +expand_set_wildoptions(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_wop_values, + sizeof(p_wop_values) / sizeof(p_wop_values[0]) - 1, + numMatches, + matches); +} + #if defined(FEAT_WAK) || defined(PROTO) /* * The 'winaltkeys' option is changed. @@ -2991,6 +4090,17 @@ did_set_winaltkeys(optset_T *args UNUSED) # endif return errmsg; } + + int +expand_set_winaltkeys(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_wak_values, + sizeof(p_wak_values) / sizeof(p_wak_values[0]) - 1, + numMatches, + matches); +} #endif /* @@ -3005,6 +4115,16 @@ did_set_wincolor(optset_T *args UNUSED) return NULL; } + int +expand_set_wincolor(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_generic( + args, + get_highlight_name, + numMatches, + matches); +} + #pragma region MacVim specific options // MacVim-specific option handlers go here. This helps resolve merge conflicts // easier than if sorting them alphabetically with the rest. diff --git a/src/os_unix.c b/src/os_unix.c index fd4fb5c9ba..3cb1c8e91a 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -6723,14 +6723,17 @@ mch_expand_wildcards( #define STYLE_GLOB 1 // use "glob", for csh #define STYLE_VIMGLOB 2 // use "vimglob", for Posix sh #define STYLE_PRINT 3 // use "print -N", for zsh -#define STYLE_BT 4 // `cmd` expansion, execute the pattern - // directly +#define STYLE_BT 4 // `cmd` expansion, execute the pattern directly +#define STYLE_GLOBSTAR 5 // use extended shell glob for bash (this uses extended + // globbing functionality using globstar, needs bash > 4) int shell_style = STYLE_ECHO; int check_spaces; static int did_find_nul = FALSE; int ampersand = FALSE; // vimglob() function to define for Posix shell static char *sh_vimglob_func = "vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >"; + // vimglob() function with globstar setting enabled, only for bash >= 4.X + static char *sh_globstar_opt = "[[ ${BASH_VERSINFO[0]} -ge 4 ]] && shopt -s globstar; "; *num_file = 0; // default: no files found *file = NULL; @@ -6777,6 +6780,8 @@ mch_expand_wildcards( * If we use *zsh, "print -N" will work better than "glob". * STYLE_VIMGLOB: NL separated * If we use *sh*, we define "vimglob()". + * STYLE_GLOBSTAR: NL separated + * If we use *bash*, we define "vimglob() and enable globstar option". * STYLE_ECHO: space separated. * A shell we don't know, stay safe and use "echo". */ @@ -6791,9 +6796,13 @@ mch_expand_wildcards( else if (STRCMP(p_sh + len - 3, "zsh") == 0) shell_style = STYLE_PRINT; } - if (shell_style == STYLE_ECHO && strstr((char *)gettail(p_sh), - "sh") != NULL) - shell_style = STYLE_VIMGLOB; + if (shell_style == STYLE_ECHO) + { + if (strstr((char *)gettail(p_sh), "bash") != NULL) + shell_style = STYLE_GLOBSTAR; + else if (strstr((char *)gettail(p_sh), "sh") != NULL) + shell_style = STYLE_VIMGLOB; + } // Compute the length of the command. We need 2 extra bytes: for the // optional '&' and for the NUL. @@ -6801,6 +6810,9 @@ mch_expand_wildcards( len = STRLEN(tempname) + 29; if (shell_style == STYLE_VIMGLOB) len += STRLEN(sh_vimglob_func); + else if (shell_style == STYLE_GLOBSTAR) + len += STRLEN(sh_vimglob_func) + + STRLEN(sh_globstar_opt); for (i = 0; i < num_pat; ++i) { @@ -6869,6 +6881,11 @@ mch_expand_wildcards( STRCAT(command, "print -N >"); else if (shell_style == STYLE_VIMGLOB) STRCAT(command, sh_vimglob_func); + else if (shell_style == STYLE_GLOBSTAR) + { + STRCAT(command, sh_globstar_opt); + STRCAT(command, sh_vimglob_func); + } else STRCAT(command, "echo >"); } @@ -7053,7 +7070,9 @@ mch_expand_wildcards( } } // file names are separated with NL - else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) + else if (shell_style == STYLE_BT || + shell_style == STYLE_VIMGLOB || + shell_style == STYLE_GLOBSTAR) { buffer[len] = NUL; // make sure the buffer ends in NUL p = buffer; @@ -7134,7 +7153,7 @@ mch_expand_wildcards( (*file)[i] = p; // Space or NL separates if (shell_style == STYLE_ECHO || shell_style == STYLE_BT - || shell_style == STYLE_VIMGLOB) + || shell_style == STYLE_VIMGLOB || shell_style == STYLE_GLOBSTAR) { while (!(shell_style == STYLE_ECHO && *p == ' ') && *p != '\n' && *p != NUL) diff --git a/src/po/sr.po b/src/po/sr.po index 885bf39884..32242ccfb2 100644 --- a/src/po/sr.po +++ b/src/po/sr.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: Vim(Serbian)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-04 10:49+0400\n" -"PO-Revision-Date: 2023-09-04 13:00+0400\n" +"POT-Creation-Date: 2023-09-27 10:56+0400\n" +"PO-Revision-Date: 2023-09-27 11:45+0400\n" "Last-Translator: Ivan Pešić \n" "Language-Team: Serbian\n" "Language: sr\n" @@ -5929,9 +5929,6 @@ msgstr "E613: Непознат фонт штампача: %s" msgid "E614: Class required" msgstr "E614: Потребна је класа" -msgid "E615: Object required" -msgstr "E615: Потребан је објекат" - #, c-format msgid "E616: Object required for argument %d" msgstr "E616: За аргумент %d је потребан објекат" @@ -7131,8 +7128,8 @@ msgid "E962: Invalid action: '%s'" msgstr "E962: Неисправна акција: ’%s’" #, c-format -msgid "E963: Setting %s to value with wrong type" -msgstr "E963: Постављање %s на вредност погрешног типа" +msgid "E963: Setting v:%s to value with wrong type" +msgstr "E963: Постављање v:%s на вредност погрешног типа" #, c-format msgid "E964: Invalid column number: %ld" @@ -8402,8 +8399,8 @@ msgid "E1316: Class can only be defined in Vim9 script" msgstr "E1316: Класа може да се дефинише само у Vim9 скрипти" #, c-format -msgid "E1317: Invalid object member declaration: %s" -msgstr "E1317: Неисправна декларација члана објекта: %s" +msgid "E1317: Invalid object variable declaration: %s" +msgstr "E1317: Неисправна декларација променљиве објекта: %s" #, c-format msgid "E1318: Not a valid command in a class: %s" @@ -8432,8 +8429,8 @@ msgid "E1325: Method not found on class \"%s\": %s" msgstr "E1325: Није пронађена метода класе „%s”: %s" #, c-format -msgid "E1326: Member not found on object \"%s\": %s" -msgstr "E1326: Члан није пронађен у објекту „%s”: %s" +msgid "E1326: Variable not found on object \"%s\": %s" +msgstr "E1326: Променљива није пронађена у објекту „%s”: %s" #, c-format msgid "E1327: Object required, found %s" @@ -8444,39 +8441,27 @@ msgid "E1328: Constructor default value must be v:none: %s" msgstr "E1328: Подразумевана вредност конструктора мора бити v:none: %s" #, c-format -msgid "E1329: Cannot get object member type from initializer: %s" -msgstr "E1329: Тип члана објекта не може да се одреди из иницијализатора: %s" - -#, c-format -msgid "E1330: Invalid type for object member: %s" -msgstr "E1330: Неисправан тип члана објекта: %s" +msgid "E1330: Invalid type for object variable: %s" +msgstr "E1330: Неисправан тип променљиве објекта: %s" msgid "E1331: Public must be followed by \"this\" or \"static\"" msgstr "E1331: Након Public мора да следи „this” или „static”" #, c-format -msgid "E1332: Public member name cannot start with underscore: %s" -msgstr "E1332: Име Public члана не може почети доњом цртом: %s" - -#, c-format -msgid "E1333: Cannot access private member: %s" -msgstr "E1333: Не може да се приступи приватном члану: %s" +msgid "E1332: Public variable name cannot start with underscore: %s" +msgstr "E1332: Име Public променљиве не може почети доњом цртом: %s" #, c-format -msgid "E1334: Object member not found: %s" -msgstr "E1334: Члан објекта није пронађен: %s" +msgid "E1333: Cannot access private variable: %s" +msgstr "E1333: Не може да се приступи приватној променљивој: %s" #, c-format -msgid "E1335: Member is not writable: %s" -msgstr "E1335: У члан не може да се уписује: %s" +msgid "E1335: Variable \"%s\" in class \"%s\" is not writable" +msgstr "E1335: У променљиву „%s” у класи „%s” не може да се упише" #, c-format -msgid "E1337: Class member not found: %s" -msgstr "E1337: Није пронађен члан класе: %s" - -#, c-format -msgid "E1338: Member not found on class \"%s\": %s" -msgstr "E1338: Није пронађен члан класе „%s”: %s" +msgid "E1337: Class variable \"%s\" not found in class \"%s\"" +msgstr "E1337: Променљива класе „%s” није пронађена у класи „%s”" msgid "" "E1339: Cannot add a textprop with text after using a textprop with a " @@ -8500,8 +8485,8 @@ msgstr "E1342: Интерфејс може да се дефинише само msgid "E1343: Interface name must start with an uppercase letter: %s" msgstr "E1343: Име интерфејса мора да почне великим словом: %s" -msgid "E1344: Cannot initialize a member in an interface" -msgstr "E1344: Члан не може да се иницијализује у интерфејсу" +msgid "E1344: Cannot initialize a variable in an interface" +msgstr "E1344: Не може да се иницијализује променљива у интерфејсу" #, c-format msgid "E1345: Not a valid command in an interface: %s" @@ -8516,12 +8501,12 @@ msgid "E1347: Not a valid interface: %s" msgstr "E1347: Неважећи интерфејс: %s" #, c-format -msgid "E1348: Member \"%s\" of interface \"%s\" not implemented" -msgstr "E1348: Члан „%s” интерфејса „%s” није имплементиран" +msgid "E1348: Variable \"%s\" of interface \"%s\" is not implemented" +msgstr "E1348: Није имплементирана променљива „%s” интерфејса „%s”" #, c-format -msgid "E1349: Function \"%s\" of interface \"%s\" not implemented" -msgstr "E1349: Функција „%s” интерфејса „%s” није имплементирана" +msgid "E1349: Method \"%s\" of interface \"%s\" is not implemented" +msgstr "E1349: Није имплементирана функција „%s” интерфејса „%s”" msgid "E1350: Duplicate \"implements\"" msgstr "E1350: Дупликат „implements”" @@ -8548,14 +8533,14 @@ msgstr "E1355: Дуплирана функција: %s" msgid "E1356: \"super\" must be followed by a dot" msgstr "E1356: Након „super” мора да следи тачка" -msgid "E1357: Using \"super\" not in a class function" -msgstr "E1357:„super” се користи ван функције класе" +msgid "E1357: Using \"super\" not in a class method" +msgstr "E1357: „super” се користи ван методе класе" msgid "E1358: Using \"super\" not in a child class" msgstr "E1358: „super” се не користи у изведеној класи" -msgid "E1359: Cannot define a \"new\" function in an abstract class" -msgstr "E1359: Функција „new” не може да се дефинише у апстрактној класи" +msgid "E1359: Cannot define a \"new\" method in an abstract class" +msgstr "E1359: Метода „new” не може да се дефинише у апстрактној класи" msgid "E1360: Using a null object" msgstr "E1360: Користи се null објекат" @@ -8572,26 +8557,85 @@ msgstr "E1363: Тип није комплетан" msgid "E1364: Warning: Pointer block corrupted" msgstr "E1364: Упозорење: Блок показивача је покварен" -msgid "E1365: Cannot use a return type with the \"new\" function" -msgstr "E1365: Повратни тип не може да се користи са функцијом „new”" +msgid "E1365: Cannot use a return type with the \"new\" method" +msgstr "E1365: Повратни тип не може да се користи са методом „new”" #, c-format msgid "E1366: Cannot access private method: %s" msgstr "E1366: Не може да се приступи приватној методи: %s" #, c-format -msgid "E1367: Access level of member \"%s\" of interface \"%s\" is different" -msgstr "E1367: Ниво приступа члана „%s” интерфејса „%s” се разликује" +msgid "E1367: Access level of variable \"%s\" of interface \"%s\" is different" +msgstr "E1367: Ниво приступа променљиве „%s” интерфејса „%s” се разликује" + +msgid "E1368: Static cannot be followed by \"this\" in a variable name" +msgstr "E1368: У имену променљиве након static не може да следи „this”" + +#, c-format +msgid "E1369: Duplicate variable: %s" +msgstr "E1369: Дуплирана променљива: %s" + +msgid "E1370: Cannot define a \"new\" method as static" +msgstr "E1370: Метода „new” не може да се дефинише као static" + +msgid "E1371: Abstract must be followed by \"def\" or \"static\"" +msgstr "E1371: Након abstract мора да следи „def” или „static”" + +#, c-format +msgid "E1372: Abstract method \"%s\" cannot be defined in a concrete class" +msgstr "E1372: Апстрактна метода „%s” не може да се дефинише у конкретној класи" + +#, c-format +msgid "E1373: Abstract method \"%s\" is not implemented" +msgstr "E1373: Није имплементирана апстрактна метода „%s”" + +#, c-format +msgid "E1374: Class variable \"%s\" accessible only inside class \"%s\"" +msgstr "E1374: Променљивој класе „%s” може да се приступи само унутар класе „%s”" + +#, c-format +msgid "E1375: Class variable \"%s\" accessible only using class \"%s\"" +msgstr "E1375: Променљивој класе „%s” може да се приступи само употребом класе „%s”" + +#, c-format +msgid "E1376: Object variable \"%s\" accessible only using class \"%s\" object" +msgstr "E1376: Променљивој објекта „%s” може да се приступи само употребом објекта класе „%s”" + +#, c-format +msgid "E1377: Access level of method \"%s\" is different in class \"%s\"" +msgstr "E1377: Ниво приступа методе „%s” у класи „%s” је другачији" -msgid "E1368: Static cannot be followed by \"this\" in a member name" -msgstr "E1368: У имену члана након static не може да следи „this”" +msgid "E1378: Static member not supported in an interface" +msgstr "E1378: У интерфејсу се не подржава статички члан" + +msgid "E1379: Private variable not supported in an interface" +msgstr "E1379: У интерфејсу се не подржава приватна променљива" + +msgid "E1380: Private method not supported in an interface" +msgstr "E1380: У интерфејсу се не подржава приватна метода" + +msgid "E1381: Interface cannot use \"implements\"" +msgstr "E1381: Интерфејс не може да користи „implements”" #, c-format -msgid "E1369: Duplicate member: %s" -msgstr "E1369: Дуплирани члан: %s" +msgid "E1382: Variable \"%s\": type mismatch, expected %s but got %s" +msgstr "E1382: Променљива „%s”: грешка типа, очекивао се %s али је наведен %s" -msgid "E1370: Cannot define a \"new\" function as static" -msgstr "E1370: Функција „new” не може да се дефинише као static" +#, c-format +msgid "E1383: Method \"%s\": type mismatch, expected %s but got %s" +msgstr "E1383: Метода „%s”: грешка типа, очекивао се %s али је наведен %s" + +#, c-format +msgid "E1384: Class method \"%s\" accessible only inside class \"%s\"" +msgstr "E1384: Методи класе „%s” може да се приступи само унутар класе „%s”" + +#, c-format +msgid "E1385: Class method \"%s\" accessible only using class \"%s\"" +msgstr "E1385: Методи класе „%s” може да се приступи само користећи класу „%s”" + +#, c-format +msgid "E1386: Object method \"%s\" accessible only using class \"%s\" object" +msgstr "E1386: Методи објекта „%s” може да се приступи само користећи објекат класе „%s”" #, c-format msgid "E1400: Cannot mix positional and non-positional arguments: %s" @@ -8621,14 +8665,6 @@ msgstr "E1404: Позициони аргумент %d тип се не упот msgid "E1405: Invalid format specifier: %s" msgstr "E1405: Неисправни спецификатор формата: %s" -#, c-format -msgid "E1406: Member \"%s\": type mismatch, expected %s but got %s" -msgstr "E1406: Члан „%s”: неодговарајући тип, очекује се %s али је наведено %s" - -#, c-format -msgid "E1407: Member \"%s\": type mismatch, expected %s but got %s" -msgstr "E1407: Члан „%s”: неодговарајући тип, очекује се %s али је наведено %s" - msgid "--No lines in buffer--" msgstr "--У баферу нема линија--" @@ -8978,7 +9014,7 @@ msgid "GVim" msgstr "GVim" msgid "Text Editor" -msgstr "Едитор текст" +msgstr "Едитор текста" msgid "Edit text files" msgstr "Уређујте текст фајлове" diff --git a/src/popupwin.c b/src/popupwin.c index a8ac39d27f..de604858c4 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -1803,6 +1803,7 @@ parse_popup_option(win_T *wp, int is_preview) dig = e + 1; x = getdigits(&dig); + // Note: Keep this in sync with p_popup_option_values. if (STRNCMP(s, "height:", 7) == 0) { if (dig != p) @@ -1840,6 +1841,7 @@ parse_popup_option(win_T *wp, int is_preview) } else if (STRNCMP(s, "border:", 7) == 0) { + // Note: Keep this in sync with p_popup_option_border_values. char_u *arg = s + 7; int on = STRNCMP(arg, "on", 2) == 0 && arg + 2 == p; int off = STRNCMP(arg, "off", 3) == 0 && arg + 3 == p; @@ -1858,6 +1860,7 @@ parse_popup_option(win_T *wp, int is_preview) } else if (STRNCMP(s, "align:", 6) == 0) { + // Note: Keep this in sync with p_popup_option_align_values. char_u *arg = s + 6; int item = STRNCMP(arg, "item", 4) == 0 && arg + 4 == p; int menu = STRNCMP(arg, "menu", 4) == 0 && arg + 4 == p; diff --git a/src/proto/autocmd.pro b/src/proto/autocmd.pro index 0b61989c06..4a502da625 100644 --- a/src/proto/autocmd.pro +++ b/src/proto/autocmd.pro @@ -39,6 +39,7 @@ int has_autocmd(event_T event, char_u *sfname, buf_T *buf); char_u *get_augroup_name(expand_T *xp, int idx); char_u *set_context_in_autocmd(expand_T *xp, char_u *arg, int doautocmd); char_u *get_event_name(expand_T *xp, int idx); +char_u *get_event_name_no_group(expand_T *xp, int idx); int autocmd_supported(char_u *name); int au_exists(char_u *arg); void f_autocmd_add(typval_T *argvars, typval_T *rettv); diff --git a/src/proto/cmdexpand.pro b/src/proto/cmdexpand.pro index 1e2b148747..395eaa6cd4 100644 --- a/src/proto/cmdexpand.pro +++ b/src/proto/cmdexpand.pro @@ -9,6 +9,7 @@ int cmdline_compl_startcol(void); char_u *ExpandOne(expand_T *xp, char_u *str, char_u *orig, int options, int mode); void ExpandInit(expand_T *xp); void ExpandCleanup(expand_T *xp); +int ExpandGeneric(char_u *pat, expand_T *xp, regmatch_T *regmatch, char_u ***matches, int *numMatches, char_u *((*func)(expand_T *, int)), int escaped); int showmatches(expand_T *xp, int wildmenu); char_u *addstar(char_u *fname, int len, int context); void set_expand_context(expand_T *xp); diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro index 1bd3aa0bbe..7883b3b4c7 100644 --- a/src/proto/mbyte.pro +++ b/src/proto/mbyte.pro @@ -88,4 +88,5 @@ char_u *string_convert_ext(vimconv_T *vcp, char_u *ptr, int *lenp, int *unconvle void f_setcellwidths(typval_T *argvars, typval_T *rettv); void f_getcellwidths(typval_T *argvars, typval_T *rettv); void f_charclass(typval_T *argvars, typval_T *rettv); +char_u *get_encoding_name(expand_T *xp, int idx); /* vim: set ft=c : */ diff --git a/src/proto/option.pro b/src/proto/option.pro index 0df3478207..49646d2c4e 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -139,6 +139,8 @@ void set_imsearch_global(void); void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags); int ExpandSettings(expand_T *xp, regmatch_T *regmatch, char_u *fuzzystr, int *numMatches, char_u ***matches, int can_fuzzy); int ExpandOldSetting(int *numMatches, char_u ***matches); +int ExpandStringSetting(expand_T *xp, regmatch_T *regmatch, int *numMatches, char_u ***matches); +int ExpandSettingSubtract(expand_T *xp, regmatch_T *regmatch, int *numMatches, char_u ***matches); int shortmess(int x); void vimrc_found(char_u *fname, char_u *envname); void change_compatible(int on); diff --git a/src/proto/optionstr.pro b/src/proto/optionstr.pro index b12041b2b9..f9420dc019 100644 --- a/src/proto/optionstr.pro +++ b/src/proto/optionstr.pro @@ -126,6 +126,71 @@ char *did_set_wincolor(optset_T *args); char *did_set_fuoptions(optset_T *args); char *did_set_string_option(int opt_idx, char_u **varp, char_u *oldval, char_u *value, char *errbuf, int opt_flags, int *value_checked); +int expand_set_ambiwidth(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_background(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_backspace(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_backupcopy(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_belloff(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_breakindentopt(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_browsedir(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_bufhidden(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_buftype(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_casemap(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_chars_option(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_clipboard(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_complete(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_completeopt(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_completeslash(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_concealcursor(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_cpoptions(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_cryptmethod(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_cursorlineopt(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_debug(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_diffopt(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_display(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_eadirection(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_encoding(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_eventignore(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_fileformat(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_foldclose(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_foldmethod(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_foldopen(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_formatoptions(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_guioptions(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_highlight(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_jumpoptions(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_keymodel(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_keyprotocol(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_lispoptions(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_mouse(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_mousemodel(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_nrformats(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_popupoption(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_printoptions(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_rightleftcmd(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_scrollopt(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_selection(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_selectmode(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_sessionoptions(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_shortmess(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_showcmdloc(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_signcolumn(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_spelloptions(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_spellsuggest(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_splitkeep(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_swapsync(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_switchbuf(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_tagcase(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_termwintype(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_toolbar(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_toolbariconsize(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_ttymouse(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_virtualedit(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_whichwrap(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_wildmode(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_wildoptions(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_winaltkeys(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_wincolor(optexpand_T *args, int *numMatches, char_u ***matches); int check_ff_value(char_u *p); int check_fuoptions(void); void save_clear_shm_value(void); diff --git a/src/proto/screen.pro b/src/proto/screen.pro index 84b404d602..d5792fa396 100644 --- a/src/proto/screen.pro +++ b/src/proto/screen.pro @@ -57,5 +57,7 @@ int screen_screencol(void); int screen_screenrow(void); char *set_fillchars_option(win_T *wp, char_u *val, int apply); char *set_listchars_option(win_T *wp, char_u *val, int apply); +char_u * get_fillchars_name(expand_T *xp, int idx); +char_u * get_listchars_name(expand_T *xp, int idx); char *check_chars_options(void); /* vim: set ft=c : */ diff --git a/src/proto/term.pro b/src/proto/term.pro index 4150cbe000..e95befef5c 100644 --- a/src/proto/term.pro +++ b/src/proto/term.pro @@ -5,6 +5,7 @@ void init_term_props(int all); void f_terminalprops(typval_T *argvars, typval_T *rettv); void set_color_count(int nr); keyprot_T match_keyprotocol(char_u *term); +void apply_keyprotocol(char_u *term, keyprot_T prot); int set_termname(char_u *term); void free_cur_term(void); void getlinecol(long *cp, long *rp); diff --git a/src/proto/vim9class.pro b/src/proto/vim9class.pro index d09f654570..31e2be70f4 100644 --- a/src/proto/vim9class.pro +++ b/src/proto/vim9class.pro @@ -1,5 +1,5 @@ /* vim9class.c */ -int object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl, int is_static); +int object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl); void ex_class(exarg_T *eap); type_T *class_member_type(class_T *cl, int is_object, char_u *name, char_u *name_end, int *member_idx); void ex_enum(exarg_T *eap); @@ -29,5 +29,5 @@ int object_free_nonref(int copyID); void method_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len); void member_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len); void f_instanceof(typval_T *argvars, typval_T *rettv); -int class_instance_of(class_T *cl, class_T *other_cl); +int class_instance_of(class_T *cl, class_T *other_cl, int covariance_check); /* vim: set ft=c : */ diff --git a/src/proto/vim9instr.pro b/src/proto/vim9instr.pro index aef934f572..898eb9751c 100644 --- a/src/proto/vim9instr.pro +++ b/src/proto/vim9instr.pro @@ -4,8 +4,8 @@ isn_T *generate_instr_drop(cctx_T *cctx, isntype_T isn_type, int drop); isn_T *generate_instr_type(cctx_T *cctx, isntype_T isn_type, type_T *type); isn_T *generate_instr_debug(cctx_T *cctx); int generate_CONSTRUCT(cctx_T *cctx, class_T *cl); -int generate_GET_OBJ_MEMBER(cctx_T *cctx, int idx, type_T *type, int is_static); -int generate_GET_ITF_MEMBER(cctx_T *cctx, class_T *itf, int idx, type_T *type, int is_static); +int generate_GET_OBJ_MEMBER(cctx_T *cctx, int idx, type_T *type); +int generate_GET_ITF_MEMBER(cctx_T *cctx, class_T *itf, int idx, type_T *type); int generate_STORE_THIS(cctx_T *cctx, int idx); int may_generate_2STRING(int offset, int tolerant, cctx_T *cctx); int generate_add_instr(cctx_T *cctx, vartype_T vartype, type_T *type1, type_T *type2, exprtype_T expr_type); @@ -45,7 +45,7 @@ int generate_OLDSCRIPT(cctx_T *cctx, isntype_T isn_type, char_u *name, int sid, int generate_VIM9SCRIPT(cctx_T *cctx, isntype_T isn_type, int sid, int idx, type_T *type); int generate_NEWLIST(cctx_T *cctx, int count, int use_null); int generate_NEWDICT(cctx_T *cctx, int count, int use_null); -int generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc, class_T *cl, int fi, isn_T **isnp); +int generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc, class_T *cl, int fi, int *isn_idx); int generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name); int generate_DEF(cctx_T *cctx, char_u *name, size_t len); int generate_JUMP(cctx_T *cctx, jumpwhen_T when, int where); @@ -69,6 +69,7 @@ int generate_MULT_EXPR(cctx_T *cctx, isntype_T isn_type, int count); int generate_ECHOWINDOW(cctx_T *cctx, int count, long time); int generate_SOURCE(cctx_T *cctx, int sid); int generate_PUT(cctx_T *cctx, int regname, linenr_T lnum); +int generate_LOCKUNLOCK(cctx_T *cctx, char_u *line, int is_arg); int generate_EXEC_copy(cctx_T *cctx, isntype_T isntype, char_u *line); int generate_EXEC(cctx_T *cctx, isntype_T isntype, char_u *str); int generate_LEGACY_EVAL(cctx_T *cctx, char_u *line); diff --git a/src/screen.c b/src/screen.c index e684db64b2..c29f6590a6 100644 --- a/src/screen.c +++ b/src/screen.c @@ -4695,6 +4695,43 @@ get_encoded_char_adv(char_u **p) return mb_ptr2char_adv(p); } +struct charstab +{ + int *cp; + char *name; +}; +static fill_chars_T fill_chars; +static struct charstab filltab[] = +{ + {&fill_chars.stl, "stl"}, + {&fill_chars.stlnc, "stlnc"}, + {&fill_chars.vert, "vert"}, + {&fill_chars.fold, "fold"}, + {&fill_chars.foldopen, "foldopen"}, + {&fill_chars.foldclosed, "foldclose"}, + {&fill_chars.foldsep, "foldsep"}, + {&fill_chars.diff, "diff"}, + {&fill_chars.eob, "eob"}, + {&fill_chars.lastline, "lastline"}, +}; +static lcs_chars_T lcs_chars; +static struct charstab lcstab[] = +{ + {&lcs_chars.eol, "eol"}, + {&lcs_chars.ext, "extends"}, + {&lcs_chars.nbsp, "nbsp"}, + {&lcs_chars.prec, "precedes"}, + {&lcs_chars.space, "space"}, + {&lcs_chars.tab2, "tab"}, + {&lcs_chars.trail, "trail"}, + {&lcs_chars.lead, "lead"}, +#ifdef FEAT_CONCEAL + {&lcs_chars.conceal, "conceal"}, +#else + {NULL, "conceal"}, +#endif +}; + /* * Handle setting 'listchars' or 'fillchars'. * "value" points to either the global or the window-local value. @@ -4714,46 +4751,8 @@ set_chars_option(win_T *wp, char_u *value, int is_listchars, int apply) int multispace_len = 0; // Length of lcs-multispace string int lead_multispace_len = 0; // Length of lcs-leadmultispace string - struct charstab - { - int *cp; - char *name; - }; struct charstab *tab; - static fill_chars_T fill_chars; - static struct charstab filltab[] = - { - {&fill_chars.stl, "stl"}, - {&fill_chars.stlnc, "stlnc"}, - {&fill_chars.vert, "vert"}, - {&fill_chars.fold, "fold"}, - {&fill_chars.foldopen, "foldopen"}, - {&fill_chars.foldclosed, "foldclose"}, - {&fill_chars.foldsep, "foldsep"}, - {&fill_chars.diff, "diff"}, - {&fill_chars.eob, "eob"}, - {&fill_chars.lastline, "lastline"}, - }; - - static lcs_chars_T lcs_chars; - struct charstab lcstab[] = - { - {&lcs_chars.eol, "eol"}, - {&lcs_chars.ext, "extends"}, - {&lcs_chars.nbsp, "nbsp"}, - {&lcs_chars.prec, "precedes"}, - {&lcs_chars.space, "space"}, - {&lcs_chars.tab2, "tab"}, - {&lcs_chars.trail, "trail"}, - {&lcs_chars.lead, "lead"}, -#ifdef FEAT_CONCEAL - {&lcs_chars.conceal, "conceal"}, -#else - {NULL, "conceal"}, -#endif - }; - if (is_listchars) { tab = lcstab; @@ -4993,6 +4992,32 @@ set_listchars_option(win_T *wp, char_u *val, int apply) return set_chars_option(wp, val, TRUE, apply); } +/* + * Function given to ExpandGeneric() to obtain possible arguments of the + * 'fillchars' option. + */ + char_u * +get_fillchars_name(expand_T *xp UNUSED, int idx) +{ + if (idx >= (int)(sizeof(filltab) / sizeof(filltab[0]))) + return NULL; + + return (char_u*)filltab[idx].name; +} + +/* + * Function given to ExpandGeneric() to obtain possible arguments of the + * 'listchars' option. + */ + char_u * +get_listchars_name(expand_T *xp UNUSED, int idx) +{ + if (idx >= (int)(sizeof(lcstab) / sizeof(lcstab[0]))) + return NULL; + + return (char_u*)lcstab[idx].name; +} + /* * Check all global and local values of 'listchars' and 'fillchars'. * Return an untranslated error messages if any of them is invalid, NULL diff --git a/src/spellsuggest.c b/src/spellsuggest.c index 42eb434ad6..e1c303a0ab 100644 --- a/src/spellsuggest.c +++ b/src/spellsuggest.c @@ -424,6 +424,7 @@ spell_check_sps(void) if (*s != NUL && !VIM_ISDIGIT(*s)) f = -1; } + // Note: Keep this in sync with p_sps_values. else if (STRCMP(buf, "best") == 0) f = SPS_BEST; else if (STRCMP(buf, "fast") == 0) diff --git a/src/structs.h b/src/structs.h index dd1f9bf3c3..939c8581b6 100644 --- a/src/structs.h +++ b/src/structs.h @@ -610,6 +610,7 @@ typedef struct expand // file name completion int xp_col; // cursor position in line int xp_selected; // selected index in completion + char_u *xp_orig; // originally expanded string char_u **xp_files; // list of files char_u *xp_line; // text being completed #define EXPAND_BUF_LEN 256 @@ -4554,6 +4555,11 @@ typedef struct * "tv" points to the (first) list item value * "li" points to the (first) list item * "range", "n1", "n2" and "empty2" indicate what items are used. + * For a member in a class/object: TODO: verify fields + * "name" points to the (expanded) variable name. + * "exp_name" NULL or non-NULL, to be freed later. + * "tv" points to the (first) list item value + * "oi" index into member array, see _type to determine which array * For an existing Dict item: * "name" points to the (expanded) variable name. * "exp_name" NULL or non-NULL, to be freed later. @@ -4590,6 +4596,11 @@ typedef struct lval_S type_T *ll_valtype; // type expected for the value or NULL blob_T *ll_blob; // The Blob or NULL ufunc_T *ll_ufunc; // The function or NULL + object_T *ll_object; // The object or NULL, class is not NULL + class_T *ll_class; // The class or NULL, object may be NULL + int ll_oi; // The object/class member index + int ll_is_root; // Special case. ll_tv is lval_root, + // ignore the rest. } lval_T; // Structure used to save the current state. Used when executing Normal mode @@ -4806,14 +4817,19 @@ typedef enum { WT_ARGUMENT, WT_VARIABLE, WT_MEMBER, - WT_METHOD, + WT_METHOD, // object method + WT_METHOD_ARG, // object method argument type + WT_METHOD_RETURN // object method return type } wherekind_T; -// Struct used to pass to error messages about where the error happened. +// Struct used to pass the location of a type check. Used in error messages to +// indicate where the error happened. Also used for doing covariance type +// check for object method return type and contra-variance type check for +// object method arguments. typedef struct { char *wt_func_name; // function name or NULL char wt_index; // argument or variable index, 0 means unknown - wherekind_T wt_kind; // "variable" when TRUE, "argument" otherwise + wherekind_T wt_kind; // type check location } where_T; #define WHERE_INIT {NULL, 0, WT_UNKNOWN} @@ -4922,6 +4938,34 @@ typedef struct char *os_errbuf; } optset_T; +/* + * Argument for the callback function (opt_expand_cb_T) invoked after a string + * option value is expanded for cmdline completion. + */ +typedef struct +{ + // Pointer to the option variable. It's always a string. + char_u *oe_varp; + // The original option value, escaped. + char_u *oe_opt_value; + + // TRUE if using set+= instead of set= + int oe_append; + // TRUE if we would like to add the original option value as the first + // choice. + int oe_include_orig_val; + + // Regex from the cmdline, for matching potential options against. + regmatch_T *oe_regmatch; + // The expansion context. + expand_T *oe_xp; + + // The full argument passed to :set. For example, if the user inputs + // ':set dip=icase,algorithm:my', oe_xp->xp_pattern will only have + // 'my', but oe_set_arg will contain the whole 'icase,algorithm:my'. + char_u *oe_set_arg; +} optexpand_T; + /* * Spell checking variables passed from win_update() to win_line(). */ diff --git a/src/term.c b/src/term.c index 8005e94759..a2c3cbbed8 100644 --- a/src/term.c +++ b/src/term.c @@ -1613,6 +1613,23 @@ apply_builtin_tcap(char_u *term, tcap_entry_T *entries, int overwrite) } } +/* + * Apply builtin termcap entries for a given keyprotocol. + */ + void +apply_keyprotocol(char_u *term, keyprot_T prot) +{ + if (prot == KEYPROTOCOL_KITTY) + apply_builtin_tcap(term, builtin_kitty, TRUE); + if (prot == KEYPROTOCOL_MOK2) + apply_builtin_tcap(term, builtin_mok2, TRUE); + + if (prot != KEYPROTOCOL_NONE) + // Some function keys may accept modifiers even though the + // terminfo/termcap entry does not indicate this. + accept_modifiers_for_function_keys(); +} + /* * Parsing of the builtin termcap entries. * Caller should check if "term" is a valid builtin terminal name. @@ -1902,6 +1919,7 @@ match_keyprotocol(char_u *term) *colon = NUL; keyprot_T prot; + // Note: Keep this in sync with p_kpc_protocol_values. if (STRCMP(colon + 1, "none") == 0) prot = KEYPROTOCOL_NONE; else if (STRCMP(colon + 1, "mok2") == 0) @@ -2089,10 +2107,7 @@ set_termname(char_u *term) // Use the 'keyprotocol' option to adjust the t_TE and t_TI // termcap entries if there is an entry matching "term". keyprot_T kpc = match_keyprotocol(term); - if (kpc == KEYPROTOCOL_KITTY) - apply_builtin_tcap(term, builtin_kitty, TRUE); - else if (kpc == KEYPROTOCOL_MOK2) - apply_builtin_tcap(term, builtin_mok2, TRUE); + apply_keyprotocol(term, kpc); #ifdef FEAT_TERMGUICOLORS // There is no good way to detect that the terminal supports RGB @@ -2104,11 +2119,6 @@ set_termname(char_u *term) && term_strings_not_set(KS_8U)) apply_builtin_tcap(term, builtin_rgb, TRUE); #endif - - if (kpc != KEYPROTOCOL_NONE) - // Some function keys may accept modifiers even though the - // terminfo/termcap entry does not indicate this. - accept_modifiers_for_function_keys(); } /* diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index b2566cdfb1..a54c507387 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -3549,4 +3549,20 @@ func Test_custom_completion() delfunc Check_customlist_completion endfunc +func Test_custom_completion_with_glob() + func TestGlobComplete(A, L, P) + return split(glob('Xglob*'), "\n") + endfunc + + command -nargs=* -complete=customlist,TestGlobComplete TestGlobComplete : + call writefile([], 'Xglob1', 'D') + call writefile([], 'Xglob2', 'D') + + call feedkeys(":TestGlobComplete \ \\ \\;\\"\", 'xt') + call assert_equal('"TestGlobComplete Xglob1 Xglob2 ;', @:) + + delcommand TestGlobComplete + delfunc TestGlobComplete +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_format.vim b/src/testdir/test_format.vim index f665d15a9b..af364c2a15 100644 --- a/src/testdir/test_format.vim +++ b/src/testdir/test_format.vim @@ -107,65 +107,65 @@ func Test_printf_pos_misc() call v9.CheckLegacyAndVim9Failure(["call printf('%1$d%2$d', 1, 3, 4)"], "E767:") - call v9.CheckLegacyAndVim9Failure(["call printf('%2$d%d', 1, 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%d%2$d', 1, 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%2$*1$d%d', 1, 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%d%2$*1$d', 1, 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%2$.*1$d%d', 1, 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%d%2$.*1$d', 1, 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$%')"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$')"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$_')"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$*3$.*d', 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$*.*2$d', 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$*.*d', 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%*.*1$d', 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%*1$.*d', 3)"], "E1400:") - call v9.CheckLegacyAndVim9Failure(["call printf('%*1$.*1$d', 3)"], "E1400:") - - call v9.CheckLegacyAndVim9Failure(["call printf('%2$d', 3, 3)"], "E1401:") - - call v9.CheckLegacyAndVim9Failure(["call printf('%2$*1$d %1$ld', 3, 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$s %1$*1$d', 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$p %1$*1$d', 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$f %1$*1$d', 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$lud %1$*1$d', 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$llud %1$*1$d', 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$lld %1$*1$d', 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$s %1$*1$d', 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$c %1$*1$d', 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$ld %1$*1$d', 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$ld %2$*1$d', 3, 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$*1$ld', 3)"], "E1402:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$*1$.*1$ld', 3)"], "E1402:") - - call v9.CheckLegacyAndVim9Failure(["call printf('%1$d%2$d', 3)"], "E1403:") - - call v9.CheckLegacyAndVim9Failure(["call printf('%1$d %1$s', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$ld %1$s', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$ud %1$d', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$s %1$f', 3.0)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$*1$d %1$ld', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$s %1$d', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$p %1$d', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$f %1$d', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$lud %1$d', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$llud %1$d', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$lld %1$d', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$s %1$d', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$c %1$d', 3)"], "E1404:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$ld %1$d', 3)"], "E1404:") - - call v9.CheckLegacyAndVim9Failure(["call printf('%1$.2$d', 3)"], "E1405:") - call v9.CheckLegacyAndVim9Failure(["call printf('%01$d', 3)"], "E1405:") - call v9.CheckLegacyAndVim9Failure(["call printf('%01$0d', 3)"], "E1405:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$*2d', 3)"], "E1405:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$*3.*2$d', 3)"], "E1405:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$*3$.2$d', 3)"], "E1405:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$*3$.*2d', 3)"], "E1405:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$1$.5d', 5)"], "E1405:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$5.1$d', 5)"], "E1405:") - call v9.CheckLegacyAndVim9Failure(["call printf('%1$1$.1$d', 5)"], "E1405:") + call v9.CheckLegacyAndVim9Failure(["call printf('%2$d%d', 1, 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%d%2$d', 1, 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%2$*1$d%d', 1, 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%d%2$*1$d', 1, 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%2$.*1$d%d', 1, 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%d%2$.*1$d', 1, 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$%')"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$')"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$_')"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$*3$.*d', 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$*.*2$d', 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$*.*d', 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%*.*1$d', 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%*1$.*d', 3)"], "E1500:") + call v9.CheckLegacyAndVim9Failure(["call printf('%*1$.*1$d', 3)"], "E1500:") + + call v9.CheckLegacyAndVim9Failure(["call printf('%2$d', 3, 3)"], "E1501:") + + call v9.CheckLegacyAndVim9Failure(["call printf('%2$*1$d %1$ld', 3, 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$s %1$*1$d', 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$p %1$*1$d', 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$f %1$*1$d', 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$lud %1$*1$d', 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$llud %1$*1$d', 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$lld %1$*1$d', 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$s %1$*1$d', 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$c %1$*1$d', 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$ld %1$*1$d', 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$ld %2$*1$d', 3, 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$*1$ld', 3)"], "E1502:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$*1$.*1$ld', 3)"], "E1502:") + + call v9.CheckLegacyAndVim9Failure(["call printf('%1$d%2$d', 3)"], "E1503:") + + call v9.CheckLegacyAndVim9Failure(["call printf('%1$d %1$s', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$ld %1$s', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$ud %1$d', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$s %1$f', 3.0)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$*1$d %1$ld', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$s %1$d', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$p %1$d', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$f %1$d', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$lud %1$d', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$llud %1$d', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$lld %1$d', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$s %1$d', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$c %1$d', 3)"], "E1504:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$ld %1$d', 3)"], "E1504:") + + call v9.CheckLegacyAndVim9Failure(["call printf('%1$.2$d', 3)"], "E1505:") + call v9.CheckLegacyAndVim9Failure(["call printf('%01$d', 3)"], "E1505:") + call v9.CheckLegacyAndVim9Failure(["call printf('%01$0d', 3)"], "E1505:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$*2d', 3)"], "E1505:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$*3.*2$d', 3)"], "E1505:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$*3$.2$d', 3)"], "E1505:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$*3$.*2d', 3)"], "E1505:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$1$.5d', 5)"], "E1505:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$5.1$d', 5)"], "E1505:") + call v9.CheckLegacyAndVim9Failure(["call printf('%1$1$.1$d', 5)"], "E1505:") endfunc func Test_printf_pos_float() @@ -296,9 +296,9 @@ func Test_printf_pos_errors() call v9.CheckLegacyAndVim9Failure(['echo printf("%1$d", [])'], 'E745:') call v9.CheckLegacyAndVim9Failure(['echo printf("%1$d", 1, 2)'], 'E767:') call v9.CheckLegacyAndVim9Failure(['echo printf("%*d", 1)'], 'E766:') - call v9.CheckLegacyAndVim9Failure(['echo printf("%1$s")'], 'E1403:') + call v9.CheckLegacyAndVim9Failure(['echo printf("%1$s")'], 'E1503:') call v9.CheckLegacyAndVim9Failure(['echo printf("%1$d", 1.2)'], 'E805:') - call v9.CheckLegacyAndVim9Failure(['echo printf("%1$f")'], 'E1403:') + call v9.CheckLegacyAndVim9Failure(['echo printf("%1$f")'], 'E1503:') endfunc func Test_printf_pos_64bit() diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index 2cc57163dd..a467e3dc4b 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -3625,4 +3625,26 @@ func Test_fullcommand() call assert_equal('', fullcommand(10)) endfunc +" Test for glob() with shell special patterns +func Test_glob_extended_bash() + CheckExecutable bash + CheckNotMSWindows + CheckNotMac " The default version of bash is old on macOS. + + let _shell = &shell + set shell=bash + + call mkdir('Xtestglob/foo/bar/src', 'p') + call writefile([], 'Xtestglob/foo/bar/src/foo.sh') + call writefile([], 'Xtestglob/foo/bar/src/foo.h') + call writefile([], 'Xtestglob/foo/bar/src/foo.cpp') + + " Sort output of glob() otherwise we end up with different + " ordering depending on whether file system is case-sensitive. + let expected = ['Xtestglob/foo/bar/src/foo.cpp', 'Xtestglob/foo/bar/src/foo.h'] + call assert_equal(expected, sort(glob('Xtestglob/**/foo.{h,cpp}', 0, 1))) + call delete('Xtestglob', 'rf') + let &shell=_shell +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim index 17d51d26fc..989a569195 100644 --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -295,11 +295,11 @@ func Test_set_completion() call assert_equal('"set tabstop thesaurus thesaurusfunc ttyscroll', @:) " Expand current value - call feedkeys(":set fileencodings=\\\"\", 'tx') - call assert_equal('"set fileencodings=ucs-bom,utf-8,default,latin1', @:) + call feedkeys(":set suffixes=\\\"\", 'tx') + call assert_equal('"set suffixes=.bak,~,.o,.h,.info,.swp,.obj', @:) - call feedkeys(":set fileencodings:\\\"\", 'tx') - call assert_equal('"set fileencodings:ucs-bom,utf-8,default,latin1', @:) + call feedkeys(":set suffixes:\\\"\", 'tx') + call assert_equal('"set suffixes:.bak,~,.o,.h,.info,.swp,.obj', @:) " Expand key codes. call feedkeys(":set \\"\", 'tx') @@ -360,13 +360,17 @@ func Test_set_completion() call assert_equal("\"set invtabstop=", @:) " Expand options for 'spellsuggest' - call feedkeys(":set spellsuggest=best,file:xyz\\\"\", 'xt') - call assert_equal("\"set spellsuggest=best,file:xyz", @:) + call feedkeys(":set spellsuggest=file:test_options.v\\\"\", 'xt') + call assert_equal("\"set spellsuggest=file:test_options.vim", @:) + call feedkeys(":set spellsuggest=best,file:test_options.v\\\"\", 'xt') + call assert_equal("\"set spellsuggest=best,file:test_options.vim", @:) " Expand value for 'key' set key=abcd call feedkeys(":set key=\\\"\", 'xt') call assert_equal('"set key=*****', @:) + call feedkeys(":set key-=\\\"\", 'xt') + call assert_equal('"set key-=*****', @:) set key= " Expand values for 'filetype' @@ -382,6 +386,278 @@ func Test_set_completion() call assert_equal('"set syntax=' .. getcompletion('a*', 'syntax')->join(), @:) endfunc +" Test handling of expanding individual string option values +func Test_set_completion_string_values() + " + " Test basic enum string options that have well-defined enum names + " + + call assert_equal(getcompletion('set display=', 'cmdline'), ['lastline', 'truncate', 'uhex']) + call assert_equal(getcompletion('set display=t', 'cmdline'), ['truncate']) + call assert_equal(getcompletion('set display=*ex*', 'cmdline'), ['uhex']) + + " Test that if a value is set, it will populate the results, but only if + " typed value is empty. + set display=uhex,lastline + call assert_equal(getcompletion('set display=', 'cmdline'), ['uhex,lastline', 'lastline', 'truncate', 'uhex']) + call assert_equal(getcompletion('set display=u', 'cmdline'), ['uhex']) + " If the set value is part of the enum list, it will show as the first + " result with no duplicate. + set display=uhex + call assert_equal(getcompletion('set display=', 'cmdline'), ['uhex', 'lastline', 'truncate']) + " If empty value, will just show the normal list without an empty item + set display= + call assert_equal(getcompletion('set display=', 'cmdline'), ['lastline', 'truncate', 'uhex']) + " Test escaping of the values + call assert_equal(getcompletion('set fillchars=', 'cmdline')[0], 'vert:\|,fold:-,eob:~,lastline:@') + + " Test comma-separated lists will expand after a comma. + call assert_equal(getcompletion('set display=truncate,*ex*', 'cmdline'), ['uhex']) + " Also test the positioning of the expansion is correct + call feedkeys(":set display=truncate,l\\\"\", 'xt') + call assert_equal('"set display=truncate,lastline', @:) + set display& + + " Test single-value options will not expand after a comma + call assert_equal(getcompletion('set ambw=single,', 'cmdline'), []) + + " Test the other simple options to make sure they have basic auto-complete, + " but don't exhaustively validate their results. + call assert_equal(getcompletion('set ambw=', 'cmdline')[0], 'single') + call assert_match('light\|dark', getcompletion('set bg=', 'cmdline')[1]) + call assert_equal(getcompletion('set backspace=', 'cmdline')[0], 'indent') + call assert_equal(getcompletion('set backupcopy=', 'cmdline')[1], 'yes') + call assert_equal(getcompletion('set belloff=', 'cmdline')[1], 'backspace') + call assert_equal(getcompletion('set briopt=', 'cmdline')[1], 'min:') + if exists('+browsedir') + call assert_equal(getcompletion('set browsedir=', 'cmdline')[1], 'current') + endif + call assert_equal(getcompletion('set bufhidden=', 'cmdline')[1], 'unload') + call assert_equal(getcompletion('set buftype=', 'cmdline')[1], 'nowrite') + call assert_equal(getcompletion('set casemap=', 'cmdline')[1], 'internal') + if exists('+clipboard') + call assert_match('unnamed', getcompletion('set clipboard=', 'cmdline')[1]) + endif + call assert_equal(getcompletion('set complete=', 'cmdline')[1], '.') + call assert_equal(getcompletion('set completeopt=', 'cmdline')[1], 'menu') + if exists('+completeslash') + call assert_equal(getcompletion('set completeslash=', 'cmdline')[1], 'backslash') + endif + if exists('+cryptmethod') + call assert_equal(getcompletion('set cryptmethod=', 'cmdline')[1], 'zip') + endif + if exists('+cursorlineopt') + call assert_equal(getcompletion('set cursorlineopt=', 'cmdline')[1], 'line') + endif + call assert_equal(getcompletion('set debug=', 'cmdline')[1], 'throw') + call assert_equal(getcompletion('set eadirection=', 'cmdline')[1], 'ver') + call assert_equal(getcompletion('set fileformat=', 'cmdline')[2], 'mac') + if exists('+foldclose') + call assert_equal(getcompletion('set foldclose=', 'cmdline')[0], 'all') + endif + if exists('+foldmethod') + call assert_equal(getcompletion('set foldmethod=', 'cmdline')[1], 'expr') + endif + if exists('+foldopen') + call assert_equal(getcompletion('set foldopen=', 'cmdline')[1], 'all') + endif + call assert_equal(getcompletion('set jumpoptions=', 'cmdline')[0], 'stack') + call assert_equal(getcompletion('set keymodel=', 'cmdline')[1], 'stopsel') + call assert_equal(getcompletion('set lispoptions=', 'cmdline')[1], 'expr:1') + call assert_match('popup', getcompletion('set mousemodel=', 'cmdline')[2]) + call assert_equal(getcompletion('set nrformats=', 'cmdline')[1], 'bin') + if exists('+rightleftcmd') + call assert_equal(getcompletion('set rightleftcmd=', 'cmdline')[0], 'search') + endif + call assert_equal(getcompletion('set scrollopt=', 'cmdline')[1], 'ver') + call assert_equal(getcompletion('set selection=', 'cmdline')[1], 'exclusive') + call assert_equal(getcompletion('set selectmode=', 'cmdline')[1], 'key') + if exists('+ssop') + call assert_equal(getcompletion('set ssop=', 'cmdline')[1], 'buffers') + endif + call assert_equal(getcompletion('set showcmdloc=', 'cmdline')[1], 'statusline') + if exists('+signcolumn') + call assert_equal(getcompletion('set signcolumn=', 'cmdline')[1], 'yes') + endif + if exists('+spelloptions') + call assert_equal(getcompletion('set spelloptions=', 'cmdline')[0], 'camel') + endif + if exists('+spellsuggest') + call assert_equal(getcompletion('set spellsuggest+=', 'cmdline')[0], 'best') + endif + call assert_equal(getcompletion('set splitkeep=', 'cmdline')[1], 'screen') + call assert_equal(getcompletion('set swapsync=', 'cmdline')[1], 'sync') + call assert_equal(getcompletion('set switchbuf=', 'cmdline')[1], 'usetab') + call assert_equal(getcompletion('set tagcase=', 'cmdline')[1], 'ignore') + if exists('+termwintype') + call assert_equal(getcompletion('set termwintype=', 'cmdline')[1], 'conpty') + endif + if exists('+toolbar') + call assert_equal(getcompletion('set toolbar=', 'cmdline')[1], 'text') + endif + if exists('+tbis') + call assert_equal(getcompletion('set tbis=', 'cmdline')[2], 'medium') + endif + if exists('+ttymouse') + set ttymouse= + call assert_equal(getcompletion('set ttymouse=', 'cmdline')[1], 'xterm2') + set ttymouse& + endif + call assert_equal(getcompletion('set virtualedit=', 'cmdline')[1], 'insert') + call assert_equal(getcompletion('set wildmode=', 'cmdline')[1], 'longest') + call assert_equal(getcompletion('set wildmode=list,longest:', 'cmdline')[0], 'full') + call assert_equal(getcompletion('set wildoptions=', 'cmdline')[1], 'tagfile') + if exists('+winaltkeys') + call assert_equal(getcompletion('set winaltkeys=', 'cmdline')[1], 'yes') + endif + + " Other string options that queries the system rather than fixed enum names + call assert_equal(getcompletion('set eventignore=', 'cmdline')[0:1], ['all', 'BufAdd']) + call assert_equal(getcompletion('set fileencodings=', 'cmdline')[1], 'latin1') + call assert_equal(getcompletion('set printoptions=', 'cmdline')[0], 'top') + call assert_equal(getcompletion('set wincolor=', 'cmdline')[0], 'SpecialKey') + + call assert_equal(getcompletion('set listchars+=', 'cmdline')[0], 'eol') + call assert_equal(getcompletion('setl listchars+=', 'cmdline')[0], 'eol') + call assert_equal(getcompletion('set fillchars+=', 'cmdline')[0], 'stl') + call assert_equal(getcompletion('setl fillchars+=', 'cmdline')[0], 'stl') + + " + " Unique string options below + " + + " keyprotocol: only auto-complete when after ':' with known protocol types + call assert_equal(getcompletion('set keyprotocol=', 'cmdline'), [&keyprotocol]) + call feedkeys(":set keyprotocol+=someterm:m\\\"\", 'xt') + call assert_equal('"set keyprotocol+=someterm:mok2', @:) + set keyprotocol& + + " previewpopup / completepopup + call assert_equal(getcompletion('set previewpopup=', 'cmdline')[0], 'height:') + call assert_equal(getcompletion('set previewpopup=highlight:End*Buffer', 'cmdline')[0], 'EndOfBuffer') + call feedkeys(":set previewpopup+=border:\\\"\", 'xt') + call assert_equal('"set previewpopup+=border:on', @:) + call feedkeys(":set completepopup=height:10,align:\\\"\", 'xt') + call assert_equal('"set completepopup=height:10,align:item', @:) + call assert_equal(getcompletion('set completepopup=bogusname:', 'cmdline'), []) + set previewpopup& completepopup& + + " diffopt: special handling of algorithm: + call assert_equal(getcompletion('set diffopt+=', 'cmdline')[0], 'filler') + call assert_equal(getcompletion('set diffopt+=iblank,foldcolumn:', 'cmdline'), []) + call assert_equal(getcompletion('set diffopt+=iblank,algorithm:pat*', 'cmdline')[0], 'patience') + + " highlight: special parsing, including auto-completing highlight groups + " after ':' + call assert_equal(getcompletion('set hl=', 'cmdline')[0:1], [&hl, '8']) + call assert_equal(getcompletion('set hl+=', 'cmdline')[0], '8') + call assert_equal(getcompletion('set hl+=8', 'cmdline')[0:2], ['8:', '8b', '8i']) + call assert_equal(getcompletion('set hl+=8b', 'cmdline')[0], '8bi') + call assert_equal(getcompletion('set hl+=8:No*ext', 'cmdline')[0], 'NonText') + " If all the display modes are used up we should be suggesting nothing. Make + " a hl typed option with all the modes which will look like '8bi-nrsuc2d=t', + " and make sure nothing is suggested from that. + let hl_display_modes = join( + \ filter(map(getcompletion('set hl+=8', 'cmdline'), + \ {idx, val -> val[1]}), + \ {idx, val -> val != ':'}), + \ '') + call assert_equal(getcompletion('set hl+=8'..hl_display_modes, 'cmdline'), []) + + " + " Test flag lists + " + + " Test set=. Show the original value if nothing is typed after '='. + " Otherwise, the list should avoid showing what's already typed. + set mouse=v + call assert_equal(getcompletion('set mouse=', 'cmdline'), ['v','a','n','i','c','h','r']) + set mouse=nvi + call assert_equal(getcompletion('set mouse=', 'cmdline'), ['nvi','a','n','v','i','c','h','r']) + call assert_equal(getcompletion('set mouse=hn', 'cmdline'), ['a','v','i','c','r']) + + " Test set+=. Never show original value, and it also tries to avoid listing + " flags that's already in the option value. + call assert_equal(getcompletion('set mouse+=', 'cmdline'), ['a','c','h','r']) + call assert_equal(getcompletion('set mouse+=hn', 'cmdline'), ['a','c','r']) + call assert_equal(getcompletion('set mouse+=acrhn', 'cmdline'), []) + + " Test that the position of the expansion is correct (even if there are + " additional values after the current cursor) + call feedkeys(":set mouse=hn\\\\"\", 'xt') + call assert_equal('"set mouse=han', @:) + set mouse& + + " Test that other flag list options have auto-complete, but don't + " exhaustively validate their results. + if exists('+concealcursor') + call assert_equal(getcompletion('set cocu=', 'cmdline')[0], 'n') + endif + call assert_equal(getcompletion('set cpo=', 'cmdline')[1], 'a') + call assert_equal(getcompletion('set fo=', 'cmdline')[1], 't') + if exists('+guioptions') + call assert_equal(getcompletion('set go=', 'cmdline')[1], '!') + endif + call assert_equal(getcompletion('set shortmess=', 'cmdline')[1], 'r') + call assert_equal(getcompletion('set whichwrap=', 'cmdline')[1], 'b') + + " + "Test set-= + " + + " Normal single-value option just shows the existing value + set ambiwidth=double + call assert_equal(getcompletion('set ambw-=', 'cmdline'), ['double']) + set ambiwidth& + + " Works on numbers and term options as well + call assert_equal(getcompletion('set laststatus-=', 'cmdline'), [string(&laststatus)]) + set t_Ce=testCe + call assert_equal(getcompletion('set t_Ce-=', 'cmdline'), ['testCe']) + set t_Ce& + + " Comma-separated lists should present each option + set diffopt=context:123,,,,,iblank,iwhiteall + call assert_equal(getcompletion('set diffopt-=', 'cmdline'), ['context:123', 'iblank', 'iwhiteall']) + call assert_equal(getcompletion('set diffopt-=*n*', 'cmdline'), ['context:123', 'iblank']) + call assert_equal(getcompletion('set diffopt-=i', 'cmdline'), ['iblank', 'iwhiteall']) + " Don't present more than one option as it doesn't make sense in set-= + call assert_equal(getcompletion('set diffopt-=iblank,', 'cmdline'), []) + " Test empty option + set diffopt= + call assert_equal(getcompletion('set diffopt-=', 'cmdline'), []) + set diffopt& + + " Test escaping output + call assert_equal(getcompletion('set fillchars-=', 'cmdline')[0], 'vert:\|') + + " Test files with commas in name are being parsed and escaped properly + set path=has\\\ space,file\\,with\\,comma,normal_file + if exists('+completeslash') + call assert_equal(getcompletion('set path-=', 'cmdline'), ['has\\\ space', 'file\,with\,comma', 'normal_file']) + else + call assert_equal(getcompletion('set path-=', 'cmdline'), ['has\\\ space', 'file\\,with\\,comma', 'normal_file']) + endif + set path& + + " Flag list should present orig value, then individual flags + set mouse=v + call assert_equal(getcompletion('set mouse-=', 'cmdline'), ['v']) + set mouse=avn + call assert_equal(getcompletion('set mouse-=', 'cmdline'), ['avn','a','v','n']) + " Don't auto-complete when we have at least one flags already + call assert_equal(getcompletion('set mouse-=n', 'cmdline'), []) + " Test empty option + set mouse= + call assert_equal(getcompletion('set mouse-=', 'cmdline'), []) + set mouse& + + " 'whichwrap' is an odd case where it's both flag list and comma-separated + set ww=b,h + call assert_equal(getcompletion('set ww-=', 'cmdline'), ['b','h']) + set ww& +endfunc + func Test_set_option_errors() call assert_fails('set scroll=-1', 'E49:') call assert_fails('set backupcopy=', 'E474:') @@ -1452,7 +1728,7 @@ func Test_opt_cdhome() set cdhome& endfunc -func Test_set_completion_2() +func Test_set_completion_fuzzy() CheckOption termguicolors " Test default option completion @@ -1866,4 +2142,18 @@ func Test_binary_depending_options() call delete('Xoutput_bin') endfunc +func Test_set_keyprotocol() + CheckNotGui + + let term = &term + set term=ansi + call assert_equal('', &t_TI) + + " Setting 'keyprotocol' should affect terminal codes without needing to + " reset 'term' + set keyprotocol+=ansi:kitty + call assert_equal("\[=1;1u", &t_TI) + let &term = term +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 37303297c0..856ee03108 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -6,151 +6,151 @@ import './vim9.vim' as v9 def Test_class_basic() # Class supported only in "vim9script" var lines =<< trim END - class NotWorking - endclass + class NotWorking + endclass END - v9.CheckSourceFailure(lines, 'E1316:') + v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1) # First character in a class name should be capitalized. lines =<< trim END - vim9script - class notWorking - endclass + vim9script + class notWorking + endclass END - v9.CheckSourceFailure(lines, 'E1314:') + v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2) # Only alphanumeric characters are supported in a class name lines =<< trim END - vim9script - class Not@working - endclass + vim9script + class Not@working + endclass END - v9.CheckSourceFailure(lines, 'E1315:') + v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2) # Unsupported keyword (instead of class) lines =<< trim END - vim9script - abstract noclass Something - endclass + vim9script + abstract noclass Something + endclass END - v9.CheckSourceFailure(lines, 'E475:') + v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2) # Only the completed word "class" should be recognized lines =<< trim END - vim9script - abstract classy Something - endclass + vim9script + abstract classy Something + endclass END - v9.CheckSourceFailure(lines, 'E475:') + v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2) # The complete "endclass" should be specified. lines =<< trim END - vim9script - class Something - endcl + vim9script + class Something + endcl END - v9.CheckSourceFailure(lines, 'E1065:') + v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3) # Additional words after "endclass" lines =<< trim END - vim9script - class Something - endclass school's out + vim9script + class Something + endclass school's out END - v9.CheckSourceFailure(lines, 'E488:') + v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3) # Additional commands after "endclass" lines =<< trim END - vim9script - class Something - endclass | echo 'done' + vim9script + class Something + endclass | echo 'done' END - v9.CheckSourceFailure(lines, 'E488:') + v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3) # Use "this" without any member variable name lines =<< trim END - vim9script - class Something - this - endclass + vim9script + class Something + this + endclass END - v9.CheckSourceFailure(lines, 'E1317:') + v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this', 3) # Use "this." without any member variable name lines =<< trim END - vim9script - class Something - this. - endclass + vim9script + class Something + this. + endclass END - v9.CheckSourceFailure(lines, 'E1317:') + v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this.', 3) # Space between "this" and "." lines =<< trim END - vim9script - class Something - this .count - endclass + vim9script + class Something + this .count + endclass END - v9.CheckSourceFailure(lines, 'E1317:') + v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this .count', 3) # Space between "this." and the member variable name lines =<< trim END - vim9script - class Something - this. count - endclass + vim9script + class Something + this. count + endclass END - v9.CheckSourceFailure(lines, 'E1317:') + v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this. count', 3) # Use "that" instead of "this" lines =<< trim END - vim9script - class Something - this.count: number - that.count - endclass + vim9script + class Something + this.count: number + that.count + endclass END - v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count') + v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4) # Member variable without a type or initialization lines =<< trim END - vim9script - class Something - this.count - endclass + vim9script + class Something + this.count + endclass END - v9.CheckSourceFailure(lines, 'E1022:') + v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3) # Use a non-existing member variable in new() lines =<< trim END - vim9script - class Something - def new() - this.state = 0 - enddef - endclass - var obj = Something.new() + vim9script + class Something + def new() + this.state = 0 + enddef + endclass + var obj = Something.new() END - v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "Something": state') + v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "Something": state', 1) # Space before ":" in a member variable declaration lines =<< trim END - vim9script - class Something - this.count : number - endclass + vim9script + class Something + this.count : number + endclass END - v9.CheckSourceFailure(lines, 'E1059:') + v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3) # No space after ":" in a member variable declaration lines =<< trim END - vim9script - class Something - this.count:number - endclass + vim9script + class Something + this.count:number + endclass END - v9.CheckSourceFailure(lines, 'E1069:') + v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3) # Test for unsupported comment specifier lines =<< trim END @@ -160,7 +160,7 @@ def Test_class_basic() #{ endclass END - v9.CheckSourceFailure(lines, 'E1170:') + v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3) # Test for using class as a bool lines =<< trim END @@ -170,7 +170,7 @@ def Test_class_basic() if A endif END - v9.CheckSourceFailure(lines, 'E1319: Using a class as a Number') + v9.CheckSourceFailure(lines, 'E1319: Using a class as a Number', 4) # Test for using object as a bool lines =<< trim END @@ -181,7 +181,7 @@ def Test_class_basic() if a endif END - v9.CheckSourceFailure(lines, 'E1320: Using an object as a Number') + v9.CheckSourceFailure(lines, 'E1320: Using an object as a Number', 5) # Test for using class as a float lines =<< trim END @@ -190,7 +190,7 @@ def Test_class_basic() endclass sort([1.1, A], 'f') END - v9.CheckSourceFailure(lines, 'E1321: Using a class as a Float') + v9.CheckSourceFailure(lines, 'E1321: Using a class as a Float', 4) # Test for using object as a float lines =<< trim END @@ -200,7 +200,7 @@ def Test_class_basic() var a = A.new() sort([1.1, a], 'f') END - v9.CheckSourceFailure(lines, 'E1322: Using an object as a Float') + v9.CheckSourceFailure(lines, 'E1322: Using an object as a Float', 5) # Test for using class as a string lines =<< trim END @@ -209,7 +209,7 @@ def Test_class_basic() endclass :exe 'call ' .. A END - v9.CheckSourceFailure(lines, 'E1323: Using a class as a String') + v9.CheckSourceFailure(lines, 'E1323: Using a class as a String', 4) # Test for using object as a string lines =<< trim END @@ -219,35 +219,35 @@ def Test_class_basic() var a = A.new() :exe 'call ' .. a END - v9.CheckSourceFailure(lines, 'E1324: Using an object as a String') + v9.CheckSourceFailure(lines, 'E1324: Using an object as a String', 5) # Test creating a class with member variables and methods, calling a object # method. Check for using type() and typename() with a class and an object. lines =<< trim END - vim9script + vim9script - class TextPosition - this.lnum: number - this.col: number + class TextPosition + this.lnum: number + this.col: number - # make a nicely formatted string - def ToString(): string - return $'({this.lnum}, {this.col})' - enddef - endclass + # make a nicely formatted string + def ToString(): string + return $'({this.lnum}, {this.col})' + enddef + endclass - # use the automatically generated new() method - var pos = TextPosition.new(2, 12) - assert_equal(2, pos.lnum) - assert_equal(12, pos.col) + # use the automatically generated new() method + var pos = TextPosition.new(2, 12) + assert_equal(2, pos.lnum) + assert_equal(12, pos.col) - # call an object method - assert_equal('(2, 12)', pos.ToString()) + # call an object method + assert_equal('(2, 12)', pos.ToString()) - assert_equal(v:t_class, type(TextPosition)) - assert_equal(v:t_object, type(pos)) - assert_equal('class', typename(TextPosition)) - assert_equal('object', typename(pos)) + assert_equal(v:t_class, type(TextPosition)) + assert_equal(v:t_object, type(pos)) + assert_equal('class', typename(TextPosition)) + assert_equal('object', typename(pos)) END v9.CheckSourceSuccess(lines) @@ -262,7 +262,7 @@ def Test_class_basic() var a = A.new() var v = a. Foo() END - v9.CheckSourceFailure(lines, 'E1202:') + v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8) # Using an object without specifying a method or a member variable lines =<< trim END @@ -275,7 +275,7 @@ def Test_class_basic() var a = A.new() var v = a. END - v9.CheckSourceFailure(lines, 'E15:') + v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8) # Error when parsing the arguments of an object method. lines =<< trim END @@ -287,37 +287,100 @@ def Test_class_basic() var a = A.new() var v = a.Foo(,) END - v9.CheckSourceFailure(lines, 'E15:') + v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7) # Use a multi-line initialization for a member variable lines =<< trim END - vim9script - class A - this.y = { - X: 1 - } - endclass - var a = A.new() + vim9script + class A + this.y = { + X: 1 + } + endclass + var a = A.new() END v9.CheckSourceSuccess(lines) enddef +" Tests for object/class methods in a class +def Test_class_def_method() + # Using the "public" keyword when defining an object method + var lines =<< trim END + vim9script + class A + public def Foo() + enddef + endclass + END + v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3) + + # Using the "public" keyword when defining a class method + lines =<< trim END + vim9script + class A + public static def Foo() + enddef + endclass + END + v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3) + + # Using the "public" keyword when defining an object private method + lines =<< trim END + vim9script + class A + public def _Foo() + enddef + endclass + END + v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3) + + # Using the "public" keyword when defining a class private method + lines =<< trim END + vim9script + class A + public static def _Foo() + enddef + endclass + END + v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3) + + # Using a "def" keyword without an object method name + lines =<< trim END + vim9script + class A + def + enddef + endclass + END + v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3) + + # Using a "def" keyword without a class method name + lines =<< trim END + vim9script + class A + static def + enddef + endclass + END + v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3) +enddef + def Test_class_defined_twice() # class defined twice should fail var lines =<< trim END - vim9script - class There - endclass - class There - endclass + vim9script + class There + endclass + class There + endclass END - v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"') + v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4) # one class, reload same script twice is OK lines =<< trim END - vim9script - class There - endclass + vim9script + class There + endclass END writefile(lines, 'XclassTwice.vim', 'D') source XclassTwice.vim @@ -327,119 +390,119 @@ enddef def Test_returning_null_object() # this was causing an internal error var lines =<< trim END - vim9script + vim9script - class BufferList - def Current(): any - return null_object - enddef - endclass + class BufferList + def Current(): any + return null_object + enddef + endclass - var buffers = BufferList.new() - echo buffers.Current() + var buffers = BufferList.new() + echo buffers.Current() END v9.CheckSourceSuccess(lines) enddef def Test_using_null_class() var lines =<< trim END - @_ = null_class.member + @_ = null_class.member END - v9.CheckDefExecAndScriptFailure(lines, ['E715:', 'E1363:']) + v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type']) enddef def Test_class_interface_wrong_end() var lines =<< trim END - vim9script - abstract class SomeName - this.member = 'text' - endinterface + vim9script + abstract class SomeName + this.member = 'text' + endinterface END - v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass') + v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4) lines =<< trim END - vim9script - export interface AnotherName - this.member: string - endclass + vim9script + export interface AnotherName + this.member: string + endclass END - v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface') + v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4) enddef def Test_object_not_set() # Use an uninitialized object in script context var lines =<< trim END - vim9script + vim9script - class State - this.value = 'xyz' - endclass + class State + this.value = 'xyz' + endclass - var state: State - var db = {'xyz': 789} - echo db[state.value] + var state: State + var db = {'xyz': 789} + echo db[state.value] END - v9.CheckSourceFailure(lines, 'E1360:') + v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9) # Use an uninitialized object from a def function lines =<< trim END - vim9script - - class Class - this.id: string - def Method1() - echo 'Method1' .. this.id - enddef - endclass + vim9script - var obj: Class - def Func() - obj.Method1() + class Class + this.id: string + def Method1() + echo 'Method1' .. this.id enddef - Func() + endclass + + var obj: Class + def Func() + obj.Method1() + enddef + Func() END - v9.CheckSourceFailure(lines, 'E1360:') + v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1) # Pass an uninitialized object variable to a "new" function and try to call an # object method. lines =<< trim END - vim9script + vim9script - class Background - this.background = 'dark' - endclass + class Background + this.background = 'dark' + endclass - class Colorscheme - this._bg: Background + class Colorscheme + this._bg: Background - def GetBackground(): string - return this._bg.background - enddef - endclass + def GetBackground(): string + return this._bg.background + enddef + endclass - var bg: Background # UNINITIALIZED - echo Colorscheme.new(bg).GetBackground() + var bg: Background # UNINITIALIZED + echo Colorscheme.new(bg).GetBackground() END - v9.CheckSourceFailure(lines, 'E1360:') + v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1) # TODO: this should not give an error but be handled at runtime lines =<< trim END - vim9script - - class Class - this.id: string - def Method1() - echo 'Method1' .. this.id - enddef - endclass + vim9script - var obj = null_object - def Func() - obj.Method1() + class Class + this.id: string + def Method1() + echo 'Method1' .. this.id enddef - Func() + endclass + + var obj = null_object + def Func() + obj.Method1() + enddef + Func() END - v9.CheckSourceFailure(lines, 'E1363:') + v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1) enddef " Null object assignment and comparison @@ -486,60 +549,60 @@ enddef " Test for object member initialization and disassembly def Test_class_member_initializer() var lines =<< trim END - vim9script + vim9script - class TextPosition - this.lnum: number = 1 - this.col: number = 1 + class TextPosition + this.lnum: number = 1 + this.col: number = 1 - # constructor with only the line number - def new(lnum: number) - this.lnum = lnum - enddef - endclass + # constructor with only the line number + def new(lnum: number) + this.lnum = lnum + enddef + endclass - var pos = TextPosition.new(3) - assert_equal(3, pos.lnum) - assert_equal(1, pos.col) - - var instr = execute('disassemble TextPosition.new') - assert_match('new\_s*' .. - '0 NEW TextPosition size \d\+\_s*' .. - '\d PUSHNR 1\_s*' .. - '\d STORE_THIS 0\_s*' .. - '\d PUSHNR 1\_s*' .. - '\d STORE_THIS 1\_s*' .. - 'this.lnum = lnum\_s*' .. - '\d LOAD arg\[-1]\_s*' .. - '\d PUSHNR 0\_s*' .. - '\d LOAD $0\_s*' .. - '\d\+ STOREINDEX object\_s*' .. - '\d\+ RETURN object.*', - instr) + var pos = TextPosition.new(3) + assert_equal(3, pos.lnum) + assert_equal(1, pos.col) + + var instr = execute('disassemble TextPosition.new') + assert_match('new\_s*' .. + '0 NEW TextPosition size \d\+\_s*' .. + '\d PUSHNR 1\_s*' .. + '\d STORE_THIS 0\_s*' .. + '\d PUSHNR 1\_s*' .. + '\d STORE_THIS 1\_s*' .. + 'this.lnum = lnum\_s*' .. + '\d LOAD arg\[-1]\_s*' .. + '\d PUSHNR 0\_s*' .. + '\d LOAD $0\_s*' .. + '\d\+ STOREINDEX object\_s*' .. + '\d\+ RETURN object.*', + instr) END v9.CheckSourceSuccess(lines) enddef def Test_member_any_used_as_object() var lines =<< trim END - vim9script + vim9script - class Inner - this.value: number = 0 - endclass + class Inner + this.value: number = 0 + endclass - class Outer - this.inner: any - endclass + class Outer + this.inner: any + endclass - def F(outer: Outer) - outer.inner.value = 1 - enddef + def F(outer: Outer) + outer.inner.value = 1 + enddef - var inner_obj = Inner.new(0) - var outer_obj = Outer.new(inner_obj) - F(outer_obj) - assert_equal(1, inner_obj.value) + var inner_obj = Inner.new(0) + var outer_obj = Outer.new(inner_obj) + F(outer_obj) + assert_equal(1, inner_obj.value) END v9.CheckSourceSuccess(lines) @@ -563,7 +626,7 @@ def Test_member_any_used_as_object() var outer_obj = Outer.new(inner_obj) F(outer_obj) END - v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _value') + v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _value', 1) # Try modifying a non-existing variable using an "any" object lines =<< trim END @@ -585,7 +648,7 @@ def Test_member_any_used_as_object() var outer_obj = Outer.new(inner_obj) F(outer_obj) END - v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "Inner": someval') + v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "Inner": someval', 1) enddef " Nested assignment to a object variable which is of another class type @@ -646,7 +709,7 @@ def Test_assignment_nested_type() Test_assign_to_nested_typed_member() END - v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable') + v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1) # Assignment where target item is read only script level lines =<< trim END @@ -669,326 +732,296 @@ def Test_assignment_nested_type() script_outer.inner.value = 1 assert_equal(1, script_inner.value) END - v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable') + v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17) enddef def Test_assignment_with_operator() # Use "+=" to assign to a object variable var lines =<< trim END - vim9script - - class Foo - public this.x: number - - def Add(n: number) - this.x += n - enddef - endclass + vim9script - var f = Foo.new(3) - f.Add(17) - assert_equal(20, f.x) + class Foo + public this.x: number - def AddToFoo(obj: Foo) - obj.x += 3 + def Add(n: number) + this.x += n enddef + endclass - AddToFoo(f) - assert_equal(23, f.x) - END - v9.CheckSourceSuccess(lines) - - # do the same thing, but through an interface - lines =<< trim END - vim9script - - interface I - public this.x: number - endinterface - - class Foo implements I - public this.x: number - - def Add(n: number) - var i: I = this - i.x += n - enddef - endclass - - var f = Foo.new(3) - f.Add(17) - assert_equal(20, f.x) + var f = Foo.new(3) + f.Add(17) + assert_equal(20, f.x) - def AddToFoo(i: I) - i.x += 3 - enddef + def AddToFoo(obj: Foo) + obj.x += 3 + enddef - AddToFoo(f) - assert_equal(23, f.x) + AddToFoo(f) + assert_equal(23, f.x) END v9.CheckSourceSuccess(lines) enddef def Test_list_of_objects() var lines =<< trim END - vim9script - - class Foo - def Add() - enddef - endclass + vim9script - def ProcessList(fooList: list) - for foo in fooList - foo.Add() - endfor + class Foo + def Add() enddef + endclass + + def ProcessList(fooList: list) + for foo in fooList + foo.Add() + endfor + enddef - var l: list = [Foo.new()] - ProcessList(l) + var l: list = [Foo.new()] + ProcessList(l) END v9.CheckSourceSuccess(lines) enddef def Test_expr_after_using_object() var lines =<< trim END - vim9script + vim9script - class Something - this.label: string = '' - endclass + class Something + this.label: string = '' + endclass - def Foo(): Something - var v = Something.new() - echo 'in Foo(): ' .. typename(v) - return v - enddef + def Foo(): Something + var v = Something.new() + echo 'in Foo(): ' .. typename(v) + return v + enddef - Foo() + Foo() END v9.CheckSourceSuccess(lines) enddef def Test_class_default_new() var lines =<< trim END - vim9script + vim9script - class TextPosition - this.lnum: number = 1 - this.col: number = 1 - endclass + class TextPosition + this.lnum: number = 1 + this.col: number = 1 + endclass - var pos = TextPosition.new() - assert_equal(1, pos.lnum) - assert_equal(1, pos.col) + var pos = TextPosition.new() + assert_equal(1, pos.lnum) + assert_equal(1, pos.col) - pos = TextPosition.new(v:none, v:none) - assert_equal(1, pos.lnum) - assert_equal(1, pos.col) + pos = TextPosition.new(v:none, v:none) + assert_equal(1, pos.lnum) + assert_equal(1, pos.col) - pos = TextPosition.new(3, 22) - assert_equal(3, pos.lnum) - assert_equal(22, pos.col) + pos = TextPosition.new(3, 22) + assert_equal(3, pos.lnum) + assert_equal(22, pos.col) - pos = TextPosition.new(v:none, 33) - assert_equal(1, pos.lnum) - assert_equal(33, pos.col) + pos = TextPosition.new(v:none, 33) + assert_equal(1, pos.lnum) + assert_equal(33, pos.col) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script - class Person - this.name: string - this.age: number = 42 - this.education: string = "unknown" + vim9script + class Person + this.name: string + this.age: number = 42 + this.education: string = "unknown" - def new(this.name, this.age = v:none, this.education = v:none) - enddef - endclass + def new(this.name, this.age = v:none, this.education = v:none) + enddef + endclass - var piet = Person.new("Piet") - assert_equal("Piet", piet.name) - assert_equal(42, piet.age) - assert_equal("unknown", piet.education) + var piet = Person.new("Piet") + assert_equal("Piet", piet.name) + assert_equal(42, piet.age) + assert_equal("unknown", piet.education) - var chris = Person.new("Chris", 4, "none") - assert_equal("Chris", chris.name) - assert_equal(4, chris.age) - assert_equal("none", chris.education) + var chris = Person.new("Chris", 4, "none") + assert_equal("Chris", chris.name) + assert_equal(4, chris.age) + assert_equal("none", chris.education) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script - class Person - this.name: string - this.age: number = 42 - this.education: string = "unknown" + vim9script + class Person + this.name: string + this.age: number = 42 + this.education: string = "unknown" - def new(this.name, this.age = v:none, this.education = v:none) - enddef - endclass + def new(this.name, this.age = v:none, this.education = v:none) + enddef + endclass - var missing = Person.new() + var missing = Person.new() END - v9.CheckSourceFailure(lines, 'E119:') + v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11) # Using a specific value to initialize an instance variable in the new() # method. lines =<< trim END - vim9script - class A - this.val: string - def new(this.val = 'a') - enddef - endclass + vim9script + class A + this.val: string + def new(this.val = 'a') + enddef + endclass END - v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'") + v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4) enddef def Test_class_new_with_object_member() var lines =<< trim END - vim9script + vim9script - class C - this.str: string - this.num: number - def new(this.str, this.num) - enddef - def newVals(this.str, this.num) - enddef - endclass + class C + this.str: string + this.num: number + def new(this.str, this.num) + enddef + def newVals(this.str, this.num) + enddef + endclass - def Check() - try - var c = C.new('cats', 2) - assert_equal('cats', c.str) - assert_equal(2, c.num) + def Check() + try + var c = C.new('cats', 2) + assert_equal('cats', c.str) + assert_equal(2, c.num) - c = C.newVals('dogs', 4) - assert_equal('dogs', c.str) - assert_equal(4, c.num) - catch - assert_report($'Unexpected exception was caught: {v:exception}') - endtry - enddef + c = C.newVals('dogs', 4) + assert_equal('dogs', c.str) + assert_equal(4, c.num) + catch + assert_report($'Unexpected exception was caught: {v:exception}') + endtry + enddef - Check() + Check() END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script - - class C - this.str: string - this.num: number - def new(this.str, this.num) - enddef - endclass + vim9script - def Check() - try - var c = C.new(1, 2) - catch - assert_report($'Unexpected exception was caught: {v:exception}') - endtry + class C + this.str: string + this.num: number + def new(this.str, this.num) enddef + endclass + + def Check() + try + var c = C.new(1, 2) + catch + assert_report($'Unexpected exception was caught: {v:exception}') + endtry + enddef - Check() + Check() END - v9.CheckSourceFailure(lines, 'E1013:') + v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2) lines =<< trim END - vim9script - - class C - this.str: string - this.num: number - def newVals(this.str, this.num) - enddef - endclass + vim9script - def Check() - try - var c = C.newVals('dogs', 'apes') - catch - assert_report($'Unexpected exception was caught: {v:exception}') - endtry + class C + this.str: string + this.num: number + def newVals(this.str, this.num) enddef + endclass + + def Check() + try + var c = C.newVals('dogs', 'apes') + catch + assert_report($'Unexpected exception was caught: {v:exception}') + endtry + enddef - Check() + Check() END - v9.CheckSourceFailure(lines, 'E1013:') + v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2) lines =<< trim END - vim9script - - class C - this.str: string - def new(str: any) - enddef - endclass + vim9script - def Check() - try - var c = C.new(1) - catch - assert_report($'Unexpected exception was caught: {v:exception}') - endtry + class C + this.str: string + def new(str: any) enddef + endclass + + def Check() + try + var c = C.new(1) + catch + assert_report($'Unexpected exception was caught: {v:exception}') + endtry + enddef - Check() + Check() END v9.CheckSourceSuccess(lines) enddef def Test_class_object_member_inits() var lines =<< trim END - vim9script - class TextPosition - this.lnum: number - this.col = 1 - this.addcol: number = 2 - endclass + vim9script + class TextPosition + this.lnum: number + this.col = 1 + this.addcol: number = 2 + endclass - var pos = TextPosition.new() - assert_equal(0, pos.lnum) - assert_equal(1, pos.col) - assert_equal(2, pos.addcol) + var pos = TextPosition.new() + assert_equal(0, pos.lnum) + assert_equal(1, pos.col) + assert_equal(2, pos.addcol) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script - class TextPosition - this.lnum - this.col = 1 - endclass + vim9script + class TextPosition + this.lnum + this.col = 1 + endclass END - v9.CheckSourceFailure(lines, 'E1022:') + v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3) # If the type is not specified for a member, then it should be set during # object creation and not when defining the class. lines =<< trim END - vim9script + vim9script - var init_count = 0 - def Init(): string - init_count += 1 - return 'foo' - enddef + var init_count = 0 + def Init(): string + init_count += 1 + return 'foo' + enddef - class A - this.str1 = Init() - this.str2: string = Init() - this.col = 1 - endclass + class A + this.str1 = Init() + this.str2: string = Init() + this.col = 1 + endclass - assert_equal(init_count, 0) - var a = A.new() - assert_equal(init_count, 2) + assert_equal(init_count, 0) + var a = A.new() + assert_equal(init_count, 2) END v9.CheckSourceSuccess(lines) @@ -1000,7 +1033,7 @@ def Test_class_object_member_inits() endclass var a = A.new() END - v9.CheckSourceFailure(lines, 'E1001:') + v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1) # Test for initializing an object member with an special type lines =<< trim END @@ -1009,35 +1042,35 @@ def Test_class_object_member_inits() this.value: void endclass END - v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void') + v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3) enddef " Test for instance variable access def Test_instance_variable_access() var lines =<< trim END - vim9script - class Triple - this._one = 1 - this.two = 2 - public this.three = 3 - - def GetOne(): number - return this._one - enddef - endclass + vim9script + class Triple + this._one = 1 + this.two = 2 + public this.three = 3 + + def GetOne(): number + return this._one + enddef + endclass - var trip = Triple.new() - assert_equal(1, trip.GetOne()) - assert_equal(2, trip.two) - assert_equal(3, trip.three) - assert_fails('echo trip._one', 'E1333') + var trip = Triple.new() + assert_equal(1, trip.GetOne()) + assert_equal(2, trip.two) + assert_equal(3, trip.three) + assert_fails('echo trip._one', 'E1333: Cannot access private variable: _one') - assert_fails('trip._one = 11', 'E1333') - assert_fails('trip.two = 22', 'E1335') - trip.three = 33 - assert_equal(33, trip.three) + assert_fails('trip._one = 11', 'E1333: Cannot access private variable: _one') + assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable') + trip.three = 33 + assert_equal(33, trip.three) - assert_fails('trip.four = 4', 'E1326') + assert_fails('trip.four = 4', 'E1326: Variable not found on object "Triple": four') END v9.CheckSourceSuccess(lines) @@ -1048,83 +1081,83 @@ def Test_instance_variable_access() public this._val = 10 endclass END - v9.CheckSourceFailure(lines, 'E1332:') + v9.CheckSourceFailure(lines, 'E1332: Public variable name cannot start with underscore: public this._val = 10', 3) lines =<< trim END - vim9script + vim9script - class MyCar - this.make: string - this.age = 5 + class MyCar + this.make: string + this.age = 5 - def new(make_arg: string) - this.make = make_arg - enddef + def new(make_arg: string) + this.make = make_arg + enddef - def GetMake(): string - return $"make = {this.make}" - enddef - def GetAge(): number - return this.age - enddef - endclass + def GetMake(): string + return $"make = {this.make}" + enddef + def GetAge(): number + return this.age + enddef + endclass - var c = MyCar.new("abc") - assert_equal('make = abc', c.GetMake()) + var c = MyCar.new("abc") + assert_equal('make = abc', c.GetMake()) - c = MyCar.new("def") - assert_equal('make = def', c.GetMake()) + c = MyCar.new("def") + assert_equal('make = def', c.GetMake()) - var c2 = MyCar.new("123") - assert_equal('make = 123', c2.GetMake()) + var c2 = MyCar.new("123") + assert_equal('make = 123', c2.GetMake()) - def CheckCar() - assert_equal("make = def", c.GetMake()) - assert_equal(5, c.GetAge()) - enddef - CheckCar() + def CheckCar() + assert_equal("make = def", c.GetMake()) + assert_equal(5, c.GetAge()) + enddef + CheckCar() END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script + vim9script - class MyCar - this.make: string + class MyCar + this.make: string - def new(make_arg: string) - this.make = make_arg - enddef - endclass + def new(make_arg: string) + this.make = make_arg + enddef + endclass - var c = MyCar.new("abc") - var c = MyCar.new("def") + var c = MyCar.new("abc") + var c = MyCar.new("def") END - v9.CheckSourceFailure(lines, 'E1041:') + v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12) lines =<< trim END - vim9script + vim9script - class Foo - this.x: list = [] + class Foo + this.x: list = [] - def Add(n: number): any - this.x->add(n) - return this - enddef - endclass + def Add(n: number): any + this.x->add(n) + return this + enddef + endclass - echo Foo.new().Add(1).Add(2).x - echo Foo.new().Add(1).Add(2) - .x - echo Foo.new().Add(1) - .Add(2).x - echo Foo.new() - .Add(1).Add(2).x - echo Foo.new() - .Add(1) - .Add(2) - .x + echo Foo.new().Add(1).Add(2).x + echo Foo.new().Add(1).Add(2) + .x + echo Foo.new().Add(1) + .Add(2).x + echo Foo.new() + .Add(1).Add(2).x + echo Foo.new() + .Add(1) + .Add(2) + .x END v9.CheckSourceSuccess(lines) @@ -1135,7 +1168,7 @@ def Test_instance_variable_access() pub this.val = 1 endclass END - v9.CheckSourceFailure(lines, 'E1065:') + v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub this.val = 1', 3) # Test for "public" keyword must be followed by "this" or "static". lines =<< trim END @@ -1144,7 +1177,7 @@ def Test_instance_variable_access() public val = 1 endclass END - v9.CheckSourceFailure(lines, 'E1331:') + v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3) # Modify a instance variable using the class name in the script context lines =<< trim END @@ -1154,7 +1187,7 @@ def Test_instance_variable_access() endclass A.val = 1 END - v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object') + v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5) # Read a instance variable using the class name in the script context lines =<< trim END @@ -1164,7 +1197,7 @@ def Test_instance_variable_access() endclass var i = A.val END - v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object') + v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5) # Modify a instance variable using the class name in a def function lines =<< trim END @@ -1177,7 +1210,7 @@ def Test_instance_variable_access() enddef T() END - v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object') + v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1) # Read a instance variable using the class name in a def function lines =<< trim END @@ -1190,31 +1223,31 @@ def Test_instance_variable_access() enddef T() END - v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object') + v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1) # Access from child class extending a class: lines =<< trim END - vim9script - class A - this.ro_obj_var = 10 - public this.rw_obj_var = 20 - this._priv_obj_var = 30 - endclass + vim9script + class A + this.ro_obj_var = 10 + public this.rw_obj_var = 20 + this._priv_obj_var = 30 + endclass - class B extends A - def Foo() - var x: number - x = this.ro_obj_var - this.ro_obj_var = 0 - x = this.rw_obj_var - this.rw_obj_var = 0 - x = this._priv_obj_var - this._priv_obj_var = 0 - enddef - endclass + class B extends A + def Foo() + var x: number + x = this.ro_obj_var + this.ro_obj_var = 0 + x = this.rw_obj_var + this.rw_obj_var = 0 + x = this._priv_obj_var + this._priv_obj_var = 0 + enddef + endclass - var b = B.new() - b.Foo() + var b = B.new() + b.Foo() END v9.CheckSourceSuccess(lines) enddef @@ -1228,7 +1261,7 @@ def Test_class_variable_access() stat this.val = 1 endclass END - v9.CheckSourceFailure(lines, 'E1065:') + v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat this.val = 1', 3) # Test for "static" cannot be followed by "this". lines =<< trim END @@ -1237,7 +1270,7 @@ def Test_class_variable_access() static this.val = 1 endclass END - v9.CheckSourceFailure(lines, 'E1368: Static cannot be followed by "this" in a variable name') + v9.CheckSourceFailure(lines, 'E1368: Static cannot be followed by "this" in a variable name', 3) # Test for "static" cannot be followed by "public". lines =<< trim END @@ -1246,122 +1279,122 @@ def Test_class_variable_access() static public val = 1 endclass END - v9.CheckSourceFailure(lines, 'E1022: Type or initialization required') + v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3) # A readonly class variable cannot be modified from a child class lines =<< trim END - vim9script - class A - static ro_class_var = 40 - endclass + vim9script + class A + static ro_class_var = 40 + endclass - class B extends A - def Foo() - A.ro_class_var = 50 - enddef - endclass + class B extends A + def Foo() + A.ro_class_var = 50 + enddef + endclass - var b = B.new() - b.Foo() + var b = B.new() + b.Foo() END - v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable') + v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1) # A private class variable cannot be accessed from a child class lines =<< trim END - vim9script - class A - static _priv_class_var = 60 - endclass + vim9script + class A + static _priv_class_var = 60 + endclass - class B extends A - def Foo() - var i = A._priv_class_var - enddef - endclass + class B extends A + def Foo() + var i = A._priv_class_var + enddef + endclass - var b = B.new() - b.Foo() + var b = B.new() + b.Foo() END - v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _priv_class_var') + v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _priv_class_var', 1) # A private class variable cannot be modified from a child class lines =<< trim END - vim9script - class A - static _priv_class_var = 60 - endclass + vim9script + class A + static _priv_class_var = 60 + endclass - class B extends A - def Foo() - A._priv_class_var = 0 - enddef - endclass + class B extends A + def Foo() + A._priv_class_var = 0 + enddef + endclass - var b = B.new() - b.Foo() + var b = B.new() + b.Foo() END - v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _priv_class_var') + v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _priv_class_var', 1) # Access from child class extending a class and from script context lines =<< trim END - vim9script - class A - static ro_class_var = 10 - public static rw_class_var = 20 - static _priv_class_var = 30 - endclass + vim9script + class A + static ro_class_var = 10 + public static rw_class_var = 20 + static _priv_class_var = 30 + endclass - class B extends A - def Foo() - var x: number - x = A.ro_class_var - assert_equal(10, x) - x = A.rw_class_var - assert_equal(25, x) - A.rw_class_var = 20 - assert_equal(20, A.rw_class_var) - enddef - endclass + class B extends A + def Foo() + var x: number + x = A.ro_class_var + assert_equal(10, x) + x = A.rw_class_var + assert_equal(25, x) + A.rw_class_var = 20 + assert_equal(20, A.rw_class_var) + enddef + endclass - assert_equal(10, A.ro_class_var) - assert_equal(20, A.rw_class_var) - A.rw_class_var = 25 - assert_equal(25, A.rw_class_var) - var b = B.new() - b.Foo() + assert_equal(10, A.ro_class_var) + assert_equal(20, A.rw_class_var) + A.rw_class_var = 25 + assert_equal(25, A.rw_class_var) + var b = B.new() + b.Foo() END v9.CheckSourceSuccess(lines) enddef def Test_class_object_compare() var class_lines =<< trim END - vim9script - class Item - this.nr = 0 - this.name = 'xx' - endclass + vim9script + class Item + this.nr = 0 + this.name = 'xx' + endclass END # used at the script level and in a compiled function var test_lines =<< trim END - var i1 = Item.new() - assert_equal(i1, i1) - assert_true(i1 is i1) - var i2 = Item.new() - assert_equal(i1, i2) - assert_false(i1 is i2) - var i3 = Item.new(0, 'xx') - assert_equal(i1, i3) + var i1 = Item.new() + assert_equal(i1, i1) + assert_true(i1 is i1) + var i2 = Item.new() + assert_equal(i1, i2) + assert_false(i1 is i2) + var i3 = Item.new(0, 'xx') + assert_equal(i1, i3) - var io1 = Item.new(1, 'xx') - assert_notequal(i1, io1) - var io2 = Item.new(0, 'yy') - assert_notequal(i1, io2) + var io1 = Item.new(1, 'xx') + assert_notequal(i1, io1) + var io2 = Item.new(0, 'yy') + assert_notequal(i1, io2) END v9.CheckSourceSuccess(class_lines + test_lines) v9.CheckSourceSuccess( - class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()']) + class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()']) for op in ['>', '>=', '<', '<=', '=~', '!~'] var op_lines = [ @@ -1369,7 +1402,7 @@ def Test_class_object_compare() 'var i2 = Item.new()', 'echo i1 ' .. op .. ' i2', ] - v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object') + v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8) v9.CheckSourceFailure(class_lines + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object') endfor @@ -1377,76 +1410,76 @@ enddef def Test_object_type() var lines =<< trim END - vim9script + vim9script - class One - this.one = 1 - endclass - class Two - this.two = 2 - endclass - class TwoMore extends Two - this.more = 9 - endclass + class One + this.one = 1 + endclass + class Two + this.two = 2 + endclass + class TwoMore extends Two + this.more = 9 + endclass - var o: One = One.new() - var t: Two = Two.new() - var m: TwoMore = TwoMore.new() - var tm: Two = TwoMore.new() + var o: One = One.new() + var t: Two = Two.new() + var m: TwoMore = TwoMore.new() + var tm: Two = TwoMore.new() - t = m + t = m END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script + vim9script - class One - this.one = 1 - endclass - class Two - this.two = 2 - endclass + class One + this.one = 1 + endclass + class Two + this.two = 2 + endclass - var o: One = Two.new() + var o: One = Two.new() END - v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object but got object') + v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object but got object', 10) lines =<< trim END - vim9script + vim9script - interface One - def GetMember(): number - endinterface - class Two implements One - this.one = 1 - def GetMember(): number - return this.one - enddef - endclass + interface One + def GetMember(): number + endinterface + class Two implements One + this.one = 1 + def GetMember(): number + return this.one + enddef + endclass - var o: One = Two.new(5) - assert_equal(5, o.GetMember()) + var o: One = Two.new(5) + assert_equal(5, o.GetMember()) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script + vim9script - class Num - this.n: number = 0 - endclass + class Num + this.n: number = 0 + endclass - def Ref(name: string): func(Num): Num - return (arg: Num): Num => { - return eval(name)(arg) - } - enddef + def Ref(name: string): func(Num): Num + return (arg: Num): Num => { + return eval(name)(arg) + } + enddef - const Fn = Ref('Double') - var Double = (m: Num): Num => Num.new(m.n * 2) + const Fn = Ref('Double') + var Double = (m: Num): Num => Num.new(m.n * 2) - echo Fn(Num.new(4)) + echo Fn(Num.new(4)) END v9.CheckSourceSuccess(lines) enddef @@ -1454,151 +1487,151 @@ enddef def Test_class_member() # check access rules var lines =<< trim END - vim9script - class TextPos - this.lnum = 1 - this.col = 1 - static counter = 0 - static _secret = 7 - public static anybody = 42 - - static def AddToCounter(nr: number) - counter += nr - enddef - endclass + vim9script + class TextPos + this.lnum = 1 + this.col = 1 + static counter = 0 + static _secret = 7 + public static anybody = 42 - assert_equal(0, TextPos.counter) - TextPos.AddToCounter(3) - assert_equal(3, TextPos.counter) - assert_fails('echo TextPos.noSuchMember', 'E1337:') + static def AddToCounter(nr: number) + counter += nr + enddef + endclass - def GetCounter(): number - return TextPos.counter - enddef - assert_equal(3, GetCounter()) + assert_equal(0, TextPos.counter) + TextPos.AddToCounter(3) + assert_equal(3, TextPos.counter) + assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"') - assert_fails('TextPos.noSuchMember = 2', 'E1337:') - assert_fails('TextPos.counter = 5', 'E1335:') - assert_fails('TextPos.counter += 5', 'E1335:') + def GetCounter(): number + return TextPos.counter + enddef + assert_equal(3, GetCounter()) + + assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"') + assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable') + assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable') - assert_fails('echo TextPos._secret', 'E1333:') - assert_fails('TextPos._secret = 8', 'E1333:') + assert_fails('echo TextPos._secret', 'E1333: Cannot access private variable: _secret') + assert_fails('TextPos._secret = 8', 'E1333: Cannot access private variable: _secret') - assert_equal(42, TextPos.anybody) - TextPos.anybody = 12 - assert_equal(12, TextPos.anybody) - TextPos.anybody += 5 - assert_equal(17, TextPos.anybody) + assert_equal(42, TextPos.anybody) + TextPos.anybody = 12 + assert_equal(12, TextPos.anybody) + TextPos.anybody += 5 + assert_equal(17, TextPos.anybody) END v9.CheckSourceSuccess(lines) # example in the help lines =<< trim END - vim9script - class OtherThing - this.size: number - static totalSize: number - - def new(this.size) - totalSize += this.size - enddef - endclass - assert_equal(0, OtherThing.totalSize) - var to3 = OtherThing.new(3) - assert_equal(3, OtherThing.totalSize) - var to7 = OtherThing.new(7) - assert_equal(10, OtherThing.totalSize) + vim9script + class OtherThing + this.size: number + static totalSize: number + + def new(this.size) + totalSize += this.size + enddef + endclass + assert_equal(0, OtherThing.totalSize) + var to3 = OtherThing.new(3) + assert_equal(3, OtherThing.totalSize) + var to7 = OtherThing.new(7) + assert_equal(10, OtherThing.totalSize) END v9.CheckSourceSuccess(lines) # using static class member twice lines =<< trim END - vim9script + vim9script - class HTML - static author: string = 'John Doe' + class HTML + static author: string = 'John Doe' - static def MacroSubstitute(s: string): string - return substitute(s, '{{author}}', author, 'gi') - enddef - endclass + static def MacroSubstitute(s: string): string + return substitute(s, '{{author}}', author, 'gi') + enddef + endclass - assert_equal('some text', HTML.MacroSubstitute('some text')) - assert_equal('some text', HTML.MacroSubstitute('some text')) + assert_equal('some text', HTML.MacroSubstitute('some text')) + assert_equal('some text', HTML.MacroSubstitute('some text')) END v9.CheckSourceSuccess(lines) # access private member in lambda lines =<< trim END - vim9script + vim9script - class Foo - this._x: number = 0 + class Foo + this._x: number = 0 - def Add(n: number): number - const F = (): number => this._x + n - return F() - enddef - endclass + def Add(n: number): number + const F = (): number => this._x + n + return F() + enddef + endclass - var foo = Foo.new() - assert_equal(5, foo.Add(5)) + var foo = Foo.new() + assert_equal(5, foo.Add(5)) END v9.CheckSourceSuccess(lines) # access private member in lambda body lines =<< trim END - vim9script + vim9script - class Foo - this._x: number = 6 + class Foo + this._x: number = 6 - def Add(n: number): number - var Lam = () => { - this._x = this._x + n - } - Lam() - return this._x - enddef - endclass + def Add(n: number): number + var Lam = () => { + this._x = this._x + n + } + Lam() + return this._x + enddef + endclass - var foo = Foo.new() - assert_equal(13, foo.Add(7)) + var foo = Foo.new() + assert_equal(13, foo.Add(7)) END v9.CheckSourceSuccess(lines) # check shadowing lines =<< trim END - vim9script + vim9script - class Some - static count = 0 - def Method(count: number) - echo count - enddef - endclass + class Some + static count = 0 + def Method(count: number) + echo count + enddef + endclass - var s = Some.new() - s.Method(7) + var s = Some.new() + s.Method(7) END - v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count') + v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5) # Use a local variable in a method with the same name as a class variable lines =<< trim END - vim9script + vim9script - class Some - static count = 0 - def Method(arg: number) - var count = 3 - echo arg count - enddef - endclass + class Some + static count = 0 + def Method(arg: number) + var count = 3 + echo arg count + enddef + endclass - var s = Some.new() - s.Method(7) + var s = Some.new() + s.Method(7) END - v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count') + v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1) # Test for using an invalid type for a member variable lines =<< trim END @@ -1607,62 +1640,62 @@ def Test_class_member() this.val: xxx endclass END - v9.CheckSourceFailure(lines, 'E1010:') + v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3) # Test for setting a member on a null object lines =<< trim END vim9script class A - public this.val: string + public this.val: string endclass def F() - var obj: A - obj.val = "" + var obj: A + obj.val = "" enddef F() END - v9.CheckSourceFailure(lines, 'E1360: Using a null object') + v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2) # Test for accessing a member on a null object lines =<< trim END vim9script class A - this.val: string + this.val: string endclass def F() - var obj: A - echo obj.val + var obj: A + echo obj.val enddef F() END - v9.CheckSourceFailure(lines, 'E1360: Using a null object') + v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2) # Test for setting a member on a null object, at script level lines =<< trim END vim9script class A - public this.val: string + public this.val: string endclass var obj: A obj.val = "" END # FIXME(in source): this should give E1360 as well! - v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object but got string') + v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object but got string', 7) # Test for accessing a member on a null object, at script level lines =<< trim END vim9script class A - this.val: string + this.val: string endclass var obj: A echo obj.val END - v9.CheckSourceFailure(lines, 'E1360: Using a null object') + v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7) # Test for no space before or after the '=' when initializing a member # variable @@ -1672,14 +1705,14 @@ def Test_class_member() this.val: number= 10 endclass END - v9.CheckSourceFailure(lines, 'E1004:') + v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3) lines =<< trim END vim9script class A this.val: number =10 endclass END - v9.CheckSourceFailure(lines, 'E1004:') + v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3) # Access a non-existing member lines =<< trim END @@ -1689,49 +1722,49 @@ def Test_class_member() var a = A.new() var v = a.bar END - v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": bar') + v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": bar', 5) enddef func Test_class_garbagecollect() let lines =<< trim END - vim9script + vim9script - class Point - this.p = [2, 3] - static pl = ['a', 'b'] - static pd = {a: 'a', b: 'b'} - endclass + class Point + this.p = [2, 3] + static pl = ['a', 'b'] + static pd = {a: 'a', b: 'b'} + endclass - echo Point.pl Point.pd - call test_garbagecollect_now() - echo Point.pl Point.pd + echo Point.pl Point.pd + call test_garbagecollect_now() + echo Point.pl Point.pd END call v9.CheckSourceSuccess(lines) let lines =<< trim END - vim9script + vim9script - interface View - endinterface + interface View + endinterface - class Widget - this.view: View - endclass + class Widget + this.view: View + endclass - class MyView implements View - this.widget: Widget + class MyView implements View + this.widget: Widget - def new() - # this will result in a circular reference to this object - this.widget = Widget.new(this) - enddef - endclass + def new() + # this will result in a circular reference to this object + this.widget = Widget.new(this) + enddef + endclass - var view = MyView.new() + var view = MyView.new() - # overwrite "view", will be garbage-collected next - view = MyView.new() - test_garbagecollect_now() + # overwrite "view", will be garbage-collected next + view = MyView.new() + test_garbagecollect_now() END call v9.CheckSourceSuccess(lines) endfunc @@ -1743,7 +1776,6 @@ func Test_interface_garbagecollect() interface I this.ro_obj_var: number - public this.rw_obj_var: number def ObjFoo(): number endinterface @@ -1753,7 +1785,6 @@ func Test_interface_garbagecollect() public static rw_class_var: number = 20 static _priv_class_var: number = 30 this.ro_obj_var: number = 40 - public this.rw_obj_var: number = 50 this._priv_obj_var: number = 60 static def _ClassBar(): number @@ -1769,42 +1800,42 @@ func Test_interface_garbagecollect() enddef def ObjFoo(): number - return this.ro_obj_var + this.rw_obj_var + this._ObjBar() + return this.ro_obj_var + this._ObjBar() enddef endclass assert_equal(60, A.ClassFoo()) var o = A.new() - assert_equal(150, o.ObjFoo()) + assert_equal(100, o.ObjFoo()) test_garbagecollect_now() assert_equal(60, A.ClassFoo()) - assert_equal(150, o.ObjFoo()) + assert_equal(100, o.ObjFoo()) END call v9.CheckSourceSuccess(lines) endfunc def Test_class_method() var lines =<< trim END - vim9script - class Value - this.value = 0 - static objects = 0 + vim9script + class Value + this.value = 0 + static objects = 0 - def new(v: number) - this.value = v - ++objects - enddef + def new(v: number) + this.value = v + ++objects + enddef - static def GetCount(): number - return objects - enddef - endclass + static def GetCount(): number + return objects + enddef + endclass - assert_equal(0, Value.GetCount()) - var v1 = Value.new(2) - assert_equal(1, Value.GetCount()) - var v2 = Value.new(7) - assert_equal(2, Value.GetCount()) + assert_equal(0, Value.GetCount()) + var v1 = Value.new(2) + assert_equal(1, Value.GetCount()) + var v2 = Value.new(7) + assert_equal(2, Value.GetCount()) END v9.CheckSourceSuccess(lines) @@ -1818,7 +1849,7 @@ def Test_class_method() aaa endclass END - v9.CheckSourceFailure(lines, 'E1318:') + v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5) # Test for calling a class method from another class method without the class # name prefix. @@ -1846,49 +1877,49 @@ enddef def Test_class_defcompile() var lines =<< trim END - vim9script + vim9script - class C - def Fo(i: number): string - return i - enddef - endclass + class C + def Fo(i: number): string + return i + enddef + endclass - defcompile C.Fo + defcompile C.Fo END - v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number') + v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1) lines =<< trim END - vim9script + vim9script - class C - static def Fc(): number - return 'x' - enddef - endclass + class C + static def Fc(): number + return 'x' + enddef + endclass - defcompile C.Fc + defcompile C.Fc END - v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string') + v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1) lines =<< trim END - vim9script + vim9script - class C - static def new() - enddef - endclass + class C + static def new() + enddef + endclass - defcompile C.new + defcompile C.new END - v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static') + v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5) # Trying to compile a function using a non-existing class variable lines =<< trim END vim9script defcompile x.Foo() END - v9.CheckSourceFailure(lines, 'E475:') + v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2) # Trying to compile a function using a variable which is not a class lines =<< trim END @@ -1896,7 +1927,7 @@ def Test_class_defcompile() var x: number defcompile x.Foo() END - v9.CheckSourceFailure(lines, 'E475:') + v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3) # Trying to compile a function without specifying the name lines =<< trim END @@ -1905,7 +1936,7 @@ def Test_class_defcompile() endclass defcompile A. END - v9.CheckSourceFailure(lines, 'E475:') + v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4) # Trying to compile a non-existing class object member function lines =<< trim END @@ -1915,116 +1946,115 @@ def Test_class_defcompile() var a = A.new() defcompile a.Foo() END - v9.CheckSourceFailureList(lines, ['E1326:', 'E475:']) + v9.CheckSourceFailureList(lines, ['E1326: Variable not found on object "A": Foo', 'E475: Invalid argument: a.Foo()']) enddef def Test_class_object_to_string() var lines =<< trim END - vim9script - class TextPosition - this.lnum = 1 - this.col = 22 - endclass + vim9script + class TextPosition + this.lnum = 1 + this.col = 22 + endclass - assert_equal("class TextPosition", string(TextPosition)) + assert_equal("class TextPosition", string(TextPosition)) - var pos = TextPosition.new() - assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos)) + var pos = TextPosition.new() + assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos)) END v9.CheckSourceSuccess(lines) enddef def Test_interface_basics() var lines =<< trim END - vim9script - interface Something - this.ro_var: string - public this.rw_var: list - def GetCount(): number - endinterface + vim9script + interface Something + this.ro_var: list + def GetCount(): number + endinterface END v9.CheckSourceSuccess(lines) lines =<< trim END - interface SomethingWrong - static count = 7 - endinterface + interface SomethingWrong + static count = 7 + endinterface END - v9.CheckSourceFailure(lines, 'E1342:') + v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1) lines =<< trim END - vim9script + vim9script - interface Some - this.value: number - def Method(value: number) - endinterface + interface Some + this.value: number + def Method(value: number) + endinterface END # The argument name and the object member name are the same, but this is not a # problem because object members are always accessed with the "this." prefix. v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script - interface somethingWrong - static count = 7 - endinterface + vim9script + interface somethingWrong + static count = 7 + endinterface END - v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong') + v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2) lines =<< trim END - vim9script - interface SomethingWrong - this.value: string - this.count = 7 - def GetCount(): number - endinterface + vim9script + interface SomethingWrong + this.value: string + this.count = 7 + def GetCount(): number + endinterface END - v9.CheckSourceFailure(lines, 'E1344:') + v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4) lines =<< trim END - vim9script - interface SomethingWrong - this.value: string - this.count: number - def GetCount(): number - return 5 - enddef - endinterface + vim9script + interface SomethingWrong + this.value: string + this.count: number + def GetCount(): number + return 5 + enddef + endinterface END - v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5') + v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6) lines =<< trim END - vim9script - export interface EnterExit - def Enter(): void - def Exit(): void - endinterface + vim9script + export interface EnterExit + def Enter(): void + def Exit(): void + endinterface END writefile(lines, 'XdefIntf.vim', 'D') lines =<< trim END - vim9script - import './XdefIntf.vim' as defIntf - export def With(ee: defIntf.EnterExit, F: func) - ee.Enter() - try - F() - finally - ee.Exit() - endtry - enddef + vim9script + import './XdefIntf.vim' as defIntf + export def With(ee: defIntf.EnterExit, F: func) + ee.Enter() + try + F() + finally + ee.Exit() + endtry + enddef END v9.CheckScriptSuccess(lines) var imported =<< trim END - vim9script - export abstract class EnterExit - def Enter(): void - enddef - def Exit(): void - enddef - endclass + vim9script + export abstract class EnterExit + def Enter(): void + enddef + def Exit(): void + enddef + endclass END writefile(imported, 'XdefIntf2.vim', 'D') @@ -2034,121 +2064,118 @@ enddef def Test_class_implements_interface() var lines =<< trim END - vim9script + vim9script - interface Some - this.count: number - def Method(nr: number) - endinterface + interface Some + this.count: number + def Method(nr: number) + endinterface - class SomeImpl implements Some - this.count: number - def Method(nr: number) - echo nr - enddef - endclass + class SomeImpl implements Some + this.count: number + def Method(nr: number) + echo nr + enddef + endclass - interface Another - this.member: string - endinterface + interface Another + this.member: string + endinterface - class AnotherImpl implements Some, Another - this.member = 'abc' - this.count = 20 - def Method(nr: number) - echo nr - enddef - endclass + class AnotherImpl implements Some, Another + this.member = 'abc' + this.count = 20 + def Method(nr: number) + echo nr + enddef + endclass END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script + vim9script - interface Some - this.count: number - endinterface + interface Some + this.count: number + endinterface - class SomeImpl implements Some implements Some - this.count: number - endclass + class SomeImpl implements Some implements Some + this.count: number + endclass END - v9.CheckSourceFailure(lines, 'E1350:') + v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7) lines =<< trim END - vim9script + vim9script - interface Some - this.count: number - endinterface + interface Some + this.count: number + endinterface - class SomeImpl implements Some, Some - this.count: number - endclass + class SomeImpl implements Some, Some + this.count: number + endclass END - v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some') + v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7) lines =<< trim END - vim9script + vim9script - interface Some - this.counter: number - def Method(nr: number) - endinterface + interface Some + this.counter: number + def Method(nr: number) + endinterface - class SomeImpl implements Some - this.count: number - def Method(nr: number) - echo nr - enddef - endclass + class SomeImpl implements Some + this.count: number + def Method(nr: number) + echo nr + enddef + endclass END - v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented') + v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13) lines =<< trim END - vim9script + vim9script - interface Some - this.count: number - def Methods(nr: number) - endinterface + interface Some + this.count: number + def Methods(nr: number) + endinterface - class SomeImpl implements Some - this.count: number - def Method(nr: number) - echo nr - enddef - endclass + class SomeImpl implements Some + this.count: number + def Method(nr: number) + echo nr + enddef + endclass END - v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented') + v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13) # Check different order of members in class and interface works. lines =<< trim END - vim9script + vim9script interface Result - public this.label: string + this.label: string this.errpos: number endinterface # order of members is opposite of interface class Failure implements Result + public this.lnum: number = 5 this.errpos: number = 42 - public this.label: string = 'label' + this.label: string = 'label' endclass - def Test() - var result: Result = Failure.new() + def Test() + var result: Result = Failure.new() assert_equal('label', result.label) assert_equal(42, result.errpos) - - result.label = 'different' - assert_equal('different', result.label) - assert_equal(42, result.errpos) enddef - Test() + Test() END v9.CheckSourceSuccess(lines) @@ -2160,7 +2187,7 @@ def Test_class_implements_interface() class B extends A" endclass END - v9.CheckSourceFailure(lines, 'E1315:') + v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4) # Trailing characters after a class name lines =<< trim END @@ -2168,7 +2195,7 @@ def Test_class_implements_interface() class A bbb endclass END - v9.CheckSourceFailure(lines, 'E488:') + v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2) # using "implements" with a non-existing class lines =<< trim END @@ -2176,7 +2203,7 @@ def Test_class_implements_interface() class A implements B endclass END - v9.CheckSourceFailure(lines, 'E1346:') + v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3) # using "implements" with a regular class lines =<< trim END @@ -2186,7 +2213,7 @@ def Test_class_implements_interface() class B implements A endclass END - v9.CheckSourceFailure(lines, 'E1347:') + v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5) # using "implements" with a variable lines =<< trim END @@ -2195,7 +2222,7 @@ def Test_class_implements_interface() class A implements T endclass END - v9.CheckSourceFailure(lines, 'E1347:') + v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4) # implements should be followed by a white space lines =<< trim END @@ -2205,86 +2232,86 @@ def Test_class_implements_interface() class B implements A; endclass END - v9.CheckSourceFailure(lines, 'E1315:') + v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4) lines =<< trim END - vim9script + vim9script - interface One - def IsEven(nr: number): bool - endinterface - class Two implements One - def IsEven(nr: number): string - enddef - endclass + interface One + def IsEven(nr: number): bool + endinterface + class Two implements One + def IsEven(nr: number): string + enddef + endclass END - v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string') + v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9) lines =<< trim END - vim9script + vim9script - interface One - def IsEven(nr: number): bool - endinterface - class Two implements One - def IsEven(nr: bool): bool - enddef - endclass + interface One + def IsEven(nr: number): bool + endinterface + class Two implements One + def IsEven(nr: bool): bool + enddef + endclass END - v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool') + v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9) lines =<< trim END - vim9script + vim9script - interface One - def IsEven(nr: number): bool - endinterface - class Two implements One - def IsEven(nr: number, ...extra: list): bool - enddef - endclass + interface One + def IsEven(nr: number): bool + endinterface + class Two implements One + def IsEven(nr: number, ...extra: list): bool + enddef + endclass END - v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list): bool') + v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list): bool', 9) # access superclass interface members from subclass, mix variable order lines =<< trim END vim9script interface I1 - public this.mvar1: number - public this.mvar2: number + this.mvar1: number + this.mvar2: number endinterface # NOTE: the order is swapped class A implements I1 - public this.mvar2: number - public this.mvar1: number - public static svar2: number - public static svar1: number - def new() - svar1 = 11 - svar2 = 12 - this.mvar1 = 111 - this.mvar2 = 112 - enddef + this.mvar2: number + this.mvar1: number + public static svar2: number + public static svar1: number + def new() + svar1 = 11 + svar2 = 12 + this.mvar1 = 111 + this.mvar2 = 112 + enddef endclass class B extends A - def new() - this.mvar1 = 121 - this.mvar2 = 122 - enddef + def new() + this.mvar1 = 121 + this.mvar2 = 122 + enddef endclass class C extends B - def new() - this.mvar1 = 131 - this.mvar2 = 132 - enddef + def new() + this.mvar1 = 131 + this.mvar2 = 132 + enddef endclass def F2(i: I1): list - return [ i.mvar1, i.mvar2 ] + return [ i.mvar1, i.mvar2 ] enddef var oa = A.new() @@ -2303,60 +2330,60 @@ def Test_class_implements_interface() vim9script interface I1 - public this.mvar1: number - public this.mvar2: number + this.mvar1: number + this.mvar2: number endinterface interface I2 - public this.mvar3: number - public this.mvar4: number + this.mvar3: number + this.mvar4: number endinterface class A implements I1 - public static svar1: number - public static svar2: number - public this.mvar1: number - public this.mvar2: number - def new() - svar1 = 11 - svar2 = 12 - this.mvar1 = 111 - this.mvar2 = 112 - enddef + public static svar1: number + public static svar2: number + this.mvar1: number + this.mvar2: number + def new() + svar1 = 11 + svar2 = 12 + this.mvar1 = 111 + this.mvar2 = 112 + enddef endclass class B extends A implements I2 - public static svar3: number - public static svar4: number - public this.mvar3: number - public this.mvar4: number - def new() - svar3 = 23 - svar4 = 24 - this.mvar1 = 121 - this.mvar2 = 122 - this.mvar3 = 123 - this.mvar4 = 124 - enddef + static svar3: number + static svar4: number + this.mvar3: number + this.mvar4: number + def new() + svar3 = 23 + svar4 = 24 + this.mvar1 = 121 + this.mvar2 = 122 + this.mvar3 = 123 + this.mvar4 = 124 + enddef endclass class C extends B - public static svar5: number - def new() - svar5 = 1001 - this.mvar1 = 131 - this.mvar2 = 132 - this.mvar3 = 133 - this.mvar4 = 134 - enddef + public static svar5: number + def new() + svar5 = 1001 + this.mvar1 = 131 + this.mvar2 = 132 + this.mvar3 = 133 + this.mvar4 = 134 + enddef endclass def F2(i: I1): list - return [ i.mvar1, i.mvar2 ] + return [ i.mvar1, i.mvar2 ] enddef def F4(i: I2): list - return [ i.mvar3, i.mvar4 ] + return [ i.mvar3, i.mvar4 ] enddef var oa = A.new() @@ -2368,6 +2395,36 @@ def Test_class_implements_interface() assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)]) END v9.CheckSourceSuccess(lines) + + # Using two interface names without a space after the "," + lines =<< trim END + vim9script + interface A + endinterface + interface B + endinterface + class C implements A,B + endclass + END + v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6) + + # No interface name after a comma + lines =<< trim END + vim9script + interface A + endinterface + class B implements A, + endclass + END + v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4) + + # No interface name after implements + lines =<< trim END + vim9script + class A implements + endclass + END + v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2) enddef def Test_call_interface_method() @@ -2474,269 +2531,269 @@ def Test_call_interface_method() # No class that implements the interface. lines =<< trim END - vim9script + vim9script - interface IWithEE - def Enter(): any - def Exit(): void - endinterface + interface IWithEE + def Enter(): any + def Exit(): void + endinterface - def With1(ee: IWithEE, F: func) - var r = ee.Enter() - enddef + def With1(ee: IWithEE, F: func) + var r = ee.Enter() + enddef - defcompile + defcompile END v9.CheckSourceSuccess(lines) enddef def Test_class_used_as_type() var lines =<< trim END - vim9script + vim9script - class Point - this.x = 0 - this.y = 0 - endclass + class Point + this.x = 0 + this.y = 0 + endclass - var p: Point - p = Point.new(2, 33) - assert_equal(2, p.x) - assert_equal(33, p.y) + var p: Point + p = Point.new(2, 33) + assert_equal(2, p.x) + assert_equal(33, p.y) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script + vim9script - interface HasX - this.x: number - endinterface + interface HasX + this.x: number + endinterface - class Point implements HasX - this.x = 0 - this.y = 0 - endclass + class Point implements HasX + this.x = 0 + this.y = 0 + endclass - var p: Point - p = Point.new(2, 33) - var hx = p - assert_equal(2, hx.x) + var p: Point + p = Point.new(2, 33) + var hx = p + assert_equal(2, hx.x) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script + vim9script - class Point - this.x = 0 - this.y = 0 - endclass + class Point + this.x = 0 + this.y = 0 + endclass - var p: Point - p = 'text' + var p: Point + p = 'text' END - v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object but got string') + v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object but got string', 9) enddef def Test_class_extends() var lines =<< trim END - vim9script - class Base - this.one = 1 - def GetOne(): number - return this.one - enddef - endclass - class Child extends Base - this.two = 2 - def GetTotal(): number - return this.one + this.two - enddef - endclass - var o = Child.new() - assert_equal(1, o.one) - assert_equal(2, o.two) - assert_equal(1, o.GetOne()) - assert_equal(3, o.GetTotal()) + vim9script + class Base + this.one = 1 + def GetOne(): number + return this.one + enddef + endclass + class Child extends Base + this.two = 2 + def GetTotal(): number + return this.one + this.two + enddef + endclass + var o = Child.new() + assert_equal(1, o.one) + assert_equal(2, o.two) + assert_equal(1, o.GetOne()) + assert_equal(3, o.GetTotal()) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script - class Base - this.one = 1 - endclass - class Child extends Base - this.two = 2 - endclass - var o = Child.new(3, 44) - assert_equal(3, o.one) - assert_equal(44, o.two) + vim9script + class Base + this.one = 1 + endclass + class Child extends Base + this.two = 2 + endclass + var o = Child.new(3, 44) + assert_equal(3, o.one) + assert_equal(44, o.two) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script - class Base - this.one = 1 - endclass - class Child extends Base extends Base - this.two = 2 - endclass + vim9script + class Base + this.one = 1 + endclass + class Child extends Base extends Base + this.two = 2 + endclass END - v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"') + v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5) lines =<< trim END - vim9script - class Child extends BaseClass - this.two = 2 - endclass + vim9script + class Child extends BaseClass + this.two = 2 + endclass END - v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass') + v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4) lines =<< trim END - vim9script - var SomeVar = 99 - class Child extends SomeVar - this.two = 2 - endclass + vim9script + var SomeVar = 99 + class Child extends SomeVar + this.two = 2 + endclass END - v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar') + v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5) lines =<< trim END - vim9script - class Base - this.name: string - def ToString(): string - return this.name - enddef - endclass + vim9script + class Base + this.name: string + def ToString(): string + return this.name + enddef + endclass - class Child extends Base - this.age: number - def ToString(): string - return super.ToString() .. ': ' .. this.age - enddef - endclass + class Child extends Base + this.age: number + def ToString(): string + return super.ToString() .. ': ' .. this.age + enddef + endclass - var o = Child.new('John', 42) - assert_equal('John: 42', o.ToString()) + var o = Child.new('John', 42) + assert_equal('John: 42', o.ToString()) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script - class Child - this.age: number - def ToString(): number - return this.age - enddef - def ToString(): string - return this.age - enddef - endclass + vim9script + class Child + this.age: number + def ToString(): number + return this.age + enddef + def ToString(): string + return this.age + enddef + endclass END - v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString') + v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9) lines =<< trim END - vim9script - class Child - this.age: number - def ToString(): string - return super .ToString() .. ': ' .. this.age - enddef - endclass - var o = Child.new(42) - echo o.ToString() + vim9script + class Child + this.age: number + def ToString(): string + return super .ToString() .. ': ' .. this.age + enddef + endclass + var o = Child.new(42) + echo o.ToString() END - v9.CheckSourceFailure(lines, 'E1356:') + v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1) lines =<< trim END - vim9script - class Base - this.name: string - def ToString(): string - return this.name - enddef - endclass - - var age = 42 + vim9script + class Base + this.name: string def ToString(): string - return super.ToString() .. ': ' .. age + return this.name enddef - echo ToString() + endclass + + var age = 42 + def ToString(): string + return super.ToString() .. ': ' .. age + enddef + echo ToString() END - v9.CheckSourceFailure(lines, 'E1357:') + v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1) lines =<< trim END - vim9script - class Child - this.age: number - def ToString(): string - return super.ToString() .. ': ' .. this.age - enddef - endclass - var o = Child.new(42) - echo o.ToString() + vim9script + class Child + this.age: number + def ToString(): string + return super.ToString() .. ': ' .. this.age + enddef + endclass + var o = Child.new(42) + echo o.ToString() END - v9.CheckSourceFailure(lines, 'E1358:') + v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1) lines =<< trim END - vim9script - class Base - this.name: string - static def ToString(): string - return 'Base class' - enddef - endclass + vim9script + class Base + this.name: string + static def ToString(): string + return 'Base class' + enddef + endclass - class Child extends Base - this.age: number - def ToString(): string - return Base.ToString() .. ': ' .. this.age - enddef - endclass + class Child extends Base + this.age: number + def ToString(): string + return Base.ToString() .. ': ' .. this.age + enddef + endclass - var o = Child.new('John', 42) - assert_equal('Base class: 42', o.ToString()) + var o = Child.new('John', 42) + assert_equal('Base class: 42', o.ToString()) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script - class Base - this.value = 1 - def new(init: number) - this.value = number + 1 - enddef - endclass - class Child extends Base - def new() - this.new(3) - enddef - endclass - var c = Child.new() + vim9script + class Base + this.value = 1 + def new(init: number) + this.value = number + 1 + enddef + endclass + class Child extends Base + def new() + this.new(3) + enddef + endclass + var c = Child.new() END - v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"') + v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1) # base class with more than one object member lines =<< trim END - vim9script + vim9script - class Result - this.success: bool - this.value: any = null - endclass + class Result + this.success: bool + this.value: any = null + endclass - class Success extends Result - def new(this.value = v:none) - this.success = true - enddef - endclass + class Success extends Result + def new(this.value = v:none) + this.success = true + enddef + endclass - var v = Success.new('asdf') - assert_equal("object of Success {success: true, value: 'asdf'}", string(v)) + var v = Success.new('asdf') + assert_equal("object of Success {success: true, value: 'asdf'}", string(v)) END v9.CheckSourceSuccess(lines) @@ -2748,7 +2805,7 @@ def Test_class_extends() class B extends A" endclass END - v9.CheckSourceFailure(lines, 'E1315:') + v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4) enddef def Test_using_base_class() @@ -2756,31 +2813,31 @@ def Test_using_base_class() vim9script class BaseEE - def Enter(): any - return null - enddef - def Exit(resource: any): void - enddef + def Enter(): any + return null + enddef + def Exit(resource: any): void + enddef endclass class ChildEE extends BaseEE - def Enter(): any - return 42 - enddef + def Enter(): any + return 42 + enddef - def Exit(resource: number): void - g:result ..= '/exit' - enddef + def Exit(resource: number): void + g:result ..= '/exit' + enddef endclass def With(ee: BaseEE) - var r = ee.Enter() - try - g:result ..= r - finally - g:result ..= '/finally' - ee.Exit(r) - endtry + var r = ee.Enter() + try + g:result ..= r + finally + g:result ..= '/finally' + ee.Exit(r) + endtry enddef g:result = '' @@ -2795,16 +2852,16 @@ def Test_using_base_class() vim9script class Base - this.success: bool = false - def Method(arg = 0) - this.success = true - enddef + this.success: bool = false + def Method(arg = 0) + this.success = true + enddef endclass class Child extends Base - def new() - super.Method() - enddef + def new() + super.Method() + enddef endclass var obj = Child.new() @@ -2815,63 +2872,63 @@ enddef def Test_class_import() var lines =<< trim END - vim9script - export class Animal - this.kind: string - this.name: string - endclass + vim9script + export class Animal + this.kind: string + this.name: string + endclass END writefile(lines, 'Xanimal.vim', 'D') lines =<< trim END - vim9script - import './Xanimal.vim' as animal + vim9script + import './Xanimal.vim' as animal - var a: animal.Animal - a = animal.Animal.new('fish', 'Eric') - assert_equal('fish', a.kind) - assert_equal('Eric', a.name) + var a: animal.Animal + a = animal.Animal.new('fish', 'Eric') + assert_equal('fish', a.kind) + assert_equal('Eric', a.name) - var b: animal.Animal = animal.Animal.new('cat', 'Garfield') - assert_equal('cat', b.kind) - assert_equal('Garfield', b.name) + var b: animal.Animal = animal.Animal.new('cat', 'Garfield') + assert_equal('cat', b.kind) + assert_equal('Garfield', b.name) END v9.CheckScriptSuccess(lines) enddef def Test_abstract_class() var lines =<< trim END - vim9script - abstract class Base - this.name: string - endclass - class Person extends Base - this.age: number - endclass - var p: Base = Person.new('Peter', 42) - assert_equal('Peter', p.name) - assert_equal(42, p.age) + vim9script + abstract class Base + this.name: string + endclass + class Person extends Base + this.age: number + endclass + var p: Base = Person.new('Peter', 42) + assert_equal('Peter', p.name) + assert_equal(42, p.age) END v9.CheckSourceSuccess(lines) lines =<< trim END - vim9script - abstract class Base - this.name: string - endclass - class Person extends Base - this.age: number - endclass - var p = Base.new('Peter') + vim9script + abstract class Base + this.name: string + endclass + class Person extends Base + this.age: number + endclass + var p = Base.new('Peter') END - v9.CheckSourceFailure(lines, 'E1325: Method not found on class "Base": new') + v9.CheckSourceFailure(lines, 'E1325: Method not found on class "Base": new', 8) lines =<< trim END - abstract class Base - this.name: string - endclass + abstract class Base + this.name: string + endclass END - v9.CheckSourceFailure(lines, 'E1316:') + v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1) # Abstract class cannot have a "new" function lines =<< trim END @@ -2881,112 +2938,112 @@ def Test_abstract_class() enddef endclass END - v9.CheckSourceFailure(lines, 'E1359:') + v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4) enddef def Test_closure_in_class() var lines =<< trim END - vim9script + vim9script - class Foo - this.y: list = ['B'] + class Foo + this.y: list = ['B'] - def new() - g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1) - enddef - endclass + def new() + g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1) + enddef + endclass - Foo.new() - assert_equal(['A'], g:result) + Foo.new() + assert_equal(['A'], g:result) END v9.CheckSourceSuccess(lines) enddef def Test_call_constructor_from_legacy() var lines =<< trim END - vim9script + vim9script - var newCalled = 'false' + var newCalled = 'false' - class A - def new() - newCalled = 'true' - enddef - endclass - - export def F(options = {}): any - return A + class A + def new() + newCalled = 'true' enddef + endclass - g:p = F() - legacy call p.new() - assert_equal('true', newCalled) + export def F(options = {}): any + return A + enddef + + g:p = F() + legacy call p.new() + assert_equal('true', newCalled) END v9.CheckSourceSuccess(lines) enddef def Test_defer_with_object() var lines =<< trim END - vim9script - - class CWithEE - def Enter() - g:result ..= "entered/" - enddef - def Exit() - g:result ..= "exited" - enddef - endclass + vim9script - def With(ee: CWithEE, F: func) - ee.Enter() - defer ee.Exit() - F() + class CWithEE + def Enter() + g:result ..= "entered/" + enddef + def Exit() + g:result ..= "exited" enddef + endclass - g:result = '' - var obj = CWithEE.new() - obj->With(() => { - g:result ..= "called/" - }) - assert_equal('entered/called/exited', g:result) + def With(ee: CWithEE, F: func) + ee.Enter() + defer ee.Exit() + F() + enddef + + g:result = '' + var obj = CWithEE.new() + obj->With(() => { + g:result ..= "called/" + }) + assert_equal('entered/called/exited', g:result) END v9.CheckSourceSuccess(lines) unlet g:result lines =<< trim END - vim9script - - class BaseWithEE - def Enter() - g:result ..= "entered-base/" - enddef - def Exit() - g:result ..= "exited-base" - enddef - endclass + vim9script - class CWithEE extends BaseWithEE - def Enter() - g:result ..= "entered-child/" - enddef - def Exit() - g:result ..= "exited-child" - enddef - endclass + class BaseWithEE + def Enter() + g:result ..= "entered-base/" + enddef + def Exit() + g:result ..= "exited-base" + enddef + endclass - def With(ee: BaseWithEE, F: func) - ee.Enter() - defer ee.Exit() - F() + class CWithEE extends BaseWithEE + def Enter() + g:result ..= "entered-child/" + enddef + def Exit() + g:result ..= "exited-child" enddef + endclass - g:result = '' - var obj = CWithEE.new() - obj->With(() => { - g:result ..= "called/" - }) - assert_equal('entered-child/called/exited-child', g:result) + def With(ee: BaseWithEE, F: func) + ee.Enter() + defer ee.Exit() + F() + enddef + + g:result = '' + var obj = CWithEE.new() + obj->With(() => { + g:result ..= "called/" + }) + assert_equal('entered-child/called/exited-child', g:result) END v9.CheckSourceSuccess(lines) unlet g:result @@ -3278,9 +3335,9 @@ def Test_stack_expansion_with_methods() vim9script class C - def M1() - F0() - enddef + def M1() + F0() + enddef endclass def F0() @@ -3288,7 +3345,7 @@ def Test_stack_expansion_with_methods() enddef def F() - C.new().M1() + C.new().M1() enddef F() @@ -3315,145 +3372,619 @@ def Test_new_return_type() var c = C.new(12345) assert_equal('object', typename(c)) - var v1: C - v1 = C.new(12345) - assert_equal('object', typename(v1)) + var v1: C + v1 = C.new(12345) + assert_equal('object', typename(v1)) + + def F() + var v2: C + v2 = C.new(12345) + assert_equal('object', typename(v2)) + enddef + F() + END + v9.CheckSourceSuccess(lines) + + # new() uses the default return type and an empty 'return' statement + lines =<< trim END + vim9script + + class C + this._bufnr: number + + def new(this._bufnr) + if !bufexists(this._bufnr) + this._bufnr = -1 + return + endif + enddef + endclass + + var c = C.new(12345) + assert_equal('object', typename(c)) + + var v1: C + v1 = C.new(12345) + assert_equal('object', typename(v1)) + + def F() + var v2: C + v2 = C.new(12345) + assert_equal('object', typename(v2)) + enddef + F() + END + v9.CheckSourceSuccess(lines) + + # new() uses "any" return type and returns "this" + lines =<< trim END + vim9script + + class C + this._bufnr: number + + def new(this._bufnr): any + if !bufexists(this._bufnr) + this._bufnr = -1 + return this + endif + enddef + endclass + END + v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11) + + # new() uses 'Dict' return type and returns a Dict + lines =<< trim END + vim9script + + class C + this._state: dict + + def new(): dict + this._state = {} + return this._state + enddef + endclass + + var c = C.new() + assert_equal('object', typename(c)) + END + v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9) +enddef + +" Test for checking a member initialization type at run time. +def Test_runtime_type_check_for_member_init() + var lines =<< trim END + vim9script + + var retnum: bool = false + + def F(): any + retnum = !retnum + if retnum + return 1 + else + return "hello" + endif + enddef + + class C + this._foo: bool = F() + endclass + + var c1 = C.new() + var c2 = C.new() + END + v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0) +enddef + +" Test for locking a variable referring to an object and reassigning to another +" object. +def Test_lockvar_object() + var lines =<< trim END + vim9script + + class C + this.val: number + def new(this.val) + enddef + endclass + + var some_dict: dict = { a: C.new(1), b: C.new(2), c: C.new(3), } + lockvar 2 some_dict + + var current: C + current = some_dict['c'] + assert_equal(3, current.val) + current = some_dict['b'] + assert_equal(2, current.val) + + def F() + current = some_dict['c'] + enddef + + def G() + current = some_dict['b'] + enddef + + F() + assert_equal(3, current.val) + G() + assert_equal(2, current.val) + END + v9.CheckSourceSuccess(lines) +enddef + +" Test trying to lock an object variable from various places +def Test_lockvar_object_variable() + # An object variable lockvar has several cases: + # object method, scriptlevel, scriplevel from :def, :def arg + # method arg, static method arg. + # Also different depths + + # TODO: handle inside_class in vim9class + # lockvar of a read-only currently fails even if inside + + # + # lockvar of read-only object variable + # + + # read-only lockvar from object method + var lines =<< trim END + vim9script + + class C + this.val1: number + def Lock() + lockvar this.val1 + enddef + endclass + var o = C.new(3) + o.Lock() + END + # TODO: wrong error + v9.CheckSourceFailure(lines, 'E1335: Variable "val1" in class "C" is not writable') + + # read-only lockvar from scriptlevel + lines =<< trim END + vim9script + + class C + this.val2: number + endclass + var o = C.new(3) + lockvar o.val2 + END + v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable') + + # read-only lockvar of scriptlevel variable from def + lines =<< trim END + vim9script + + class C + this.val3: number + endclass + var o = C.new(3) + def Lock() + lockvar o.val3 + enddef + Lock() + END + v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable') + + # read-only lockvar of def argument variable + lines =<< trim END + vim9script + + class C + this.val4: number + endclass + def Lock(o: C) + lockvar o.val4 + enddef + Lock(C.new(3)) + END + v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable') + + # TODO: the following tests use type "any" for argument. Need a run time + # check for access. Probably OK as is for now. + + # read-only lockvar from object method arg + lines =<< trim END + vim9script + + class C + this.val5: number + def Lock(o_any: any) + lockvar o_any.val5 + enddef + endclass + var o = C.new(3) + o.Lock(C.new(5)) + END + # TODO: wrong error, tricky since type "any" + v9.CheckSourceFailure(lines, 'E1335: Variable "val5" in class "C" is not writable') + + # read-only lockvar from class method arg + lines =<< trim END + vim9script + + class C + this.val6: number + static def Lock(o_any: any) + lockvar o_any.val6 + enddef + endclass + var o = C.new(3) + C.Lock(o) + END + # TODO: wrong error, tricky since type "any" + v9.CheckSourceFailure(lines, 'E1335: Variable "val6" in class "C" is not writable') + + # + # lockvar of public object variable + # + + # lockvar from object method + lines =<< trim END + vim9script + + class C + public this.val1: number + def Lock() + lockvar this.val1 + enddef + endclass + var o = C.new(3) + o.Lock() + END + v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1) + + # lockvar from scriptlevel + lines =<< trim END + vim9script + + class C + public this.val2: number + endclass + var o = C.new(3) + lockvar o.val2 + END + v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7) + + # lockvar of scriptlevel variable from def + lines =<< trim END + vim9script + + class C + public this.val3: number + endclass + var o = C.new(3) + def Lock() + lockvar o.val3 + enddef + Lock() + END + v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1) + + # lockvar of def argument variable + lines =<< trim END + vim9script + + class C + public this.val4: number + endclass + def Lock(o: C) + lockvar o.val4 + enddef + Lock(C.new(3)) + END + v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1) + + # lockvar from object method arg + lines =<< trim END + vim9script + + class C + public this.val5: number + def Lock(o_any: any) + lockvar o_any.val5 + enddef + endclass + var o = C.new(3) + o.Lock(C.new(5)) + END + v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1) + + # lockvar from class method arg + lines =<< trim END + vim9script + + class C + public this.val6: number + static def Lock(o_any: any) + lockvar o_any.val6 + enddef + endclass + var o = C.new(3) + C.Lock(o) + END + v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1) +enddef + +" Test trying to lock a class variable from various places +def Test_lockvar_class_variable() + + # lockvar bare static from object method + var lines =<< trim END + vim9script + + class C + public static sval1: number + def Lock() + lockvar sval1 + enddef + endclass + var o = C.new() + o.Lock() + END + v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1) + + # lockvar C.static from object method + lines =<< trim END + vim9script + + class C + public static sval2: number + def Lock() + lockvar C.sval2 + enddef + endclass + var o = C.new() + o.Lock() + END + v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1) + + # lockvar bare static from class method + lines =<< trim END + vim9script + + class C + public static sval3: number + static def Lock() + lockvar sval3 + enddef + endclass + C.Lock() + END + v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1) + + # lockvar C.static from class method + lines =<< trim END + vim9script + + class C + public static sval4: number + static def Lock() + lockvar C.sval4 + enddef + endclass + C.Lock() + END + v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1) + + # lockvar C.static from script level + lines =<< trim END + vim9script + + class C + public static sval5: number + endclass + lockvar C.sval5 + END + v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6) + + # lockvar o.static from script level + lines =<< trim END + vim9script + + class C + public static sval6: number + endclass + var o = C.new() + lockvar o.sval6 + END + v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7) +enddef + +" Test locking an argument to :def +def Test_lockvar_argument() + # Lockvar a function arg + var lines =<< trim END + vim9script + + def Lock(val: any) + lockvar val + enddef + + var d = {a: 1, b: 2} + Lock(d) + + d->extend({c: 3}) + END + v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument') + + # Lockvar a function arg. Verify "sval" is interpreted as argument and not a + # class member in "C". This tests lval_root_is_arg. + lines =<< trim END + vim9script + + class C + public static sval: list + endclass - def F() - var v2: C - v2 = C.new(12345) - assert_equal('object', typename(v2)) + def Lock2(sval: any) + lockvar sval enddef - F() + + var o = C.new() + Lock2(o) END v9.CheckSourceSuccess(lines) - # new() uses the default return type and an empty 'return' statement + # Lock a class. lines =<< trim END vim9script class C - this._bufnr: number - - def new(this._bufnr) - if !bufexists(this._bufnr) - this._bufnr = -1 - return - endif - enddef + public static sval: list endclass - var c = C.new(12345) - assert_equal('object', typename(c)) - - var v1: C - v1 = C.new(12345) - assert_equal('object', typename(v1)) - - def F() - var v2: C - v2 = C.new(12345) - assert_equal('object', typename(v2)) + def Lock2(sval: any) + lockvar sval enddef - F() + + Lock2(C) END v9.CheckSourceSuccess(lines) - # new() uses "any" return type and returns "this" + # Lock an object. lines =<< trim END vim9script class C - this._bufnr: number - - def new(this._bufnr): any - if !bufexists(this._bufnr) - this._bufnr = -1 - return this - endif - enddef + public static sval: list endclass + + def Lock2(sval: any) + lockvar sval + enddef + + Lock2(C.new()) END - v9.CheckSourceFailure(lines, 'E1365:') + v9.CheckSourceSuccess(lines) - # new() uses 'Dict' return type and returns a Dict + # In this case (unlike previous) "lockvar sval" is a class member. lines =<< trim END vim9script class C - this._state: dict - - def new(): dict - this._state = {} - return this._state + public static sval: list + def Lock2() + lockvar sval enddef endclass - var c = C.new() - assert_equal('object', typename(c)) + + var o = C.new() + o.Lock2() END - v9.CheckSourceFailure(lines, 'E1365:') + v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1) enddef -" Test for checking a member initialization type at run time. -def Test_runtime_type_check_for_member_init() +" Test that this can be locked without error +def Test_lockvar_this() + # lockvar this var lines =<< trim END vim9script + class C + def TLock() + lockvar this + enddef + endclass + var o = C.new() + o.TLock() + END + v9.CheckSourceSuccess(lines) - var retnum: bool = false - - def F(): any - retnum = !retnum - if retnum - return 1 - else - return "hello" - endif - enddef - + # lockvar four (four letter word, but not this) + lines =<< trim END + vim9script class C - this._foo: bool = F() + def TLock4() + var four: number + lockvar four + enddef endclass + var o = C.new() + o.TLock4() + END + v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable') - var c1 = C.new() - var c2 = C.new() + # lockvar this5; "this" + one char, 5 letter word, starting with "this" + lines =<< trim END + vim9script + class C + def TLock5() + var this5: number + lockvar this5 + enddef + endclass + var o = C.new() + o.TLock5() END - v9.CheckSourceFailure(lines, 'E1012:') + v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable') enddef -" Test for locking a variable referring to an object and reassigning to another -" object. -def Test_object_lockvar() +" Test some general lockvar cases +def Test_lockvar_general() + # lockvar an object and a class. It does nothing var lines =<< trim END vim9script - class C - this.val: number - def new(this.val) - enddef endclass + var o = C.new() + lockvar o + lockvar C + END + v9.CheckSourceSuccess(lines) - var some_dict: dict = { a: C.new(1), b: C.new(2), c: C.new(3), } - lockvar 2 some_dict - - var current: C - current = some_dict['c'] - assert_equal(3, current.val) - current = some_dict['b'] - assert_equal(2, current.val) + # Lock a list element that's nested in an object variable from a :def + lines =<< trim END + vim9script - def F() - current = some_dict['c'] + class C + public this.val: list> = [ [1], [2], [3] ] + endclass + def Lock2(obj: any) + lockvar obj.val[1] enddef - def G() - current = some_dict['b'] - enddef + var o = C.new() + Lock2(o) + o.val[0] = [9] + assert_equal([ [9], [2], [3] ], o.val) + try + o.val[1] = [999] + call assert_false(true, 'assign should have failed') + catch + assert_exception('E741:') + endtry + o.val[2] = [8] + assert_equal([ [9], [2], [8] ], o.val) + END + v9.CheckSourceSuccess(lines) - F() - assert_equal(3, current.val) - G() - assert_equal(2, current.val) + # Lock a list element that's nested in an object variable from scriptlevel + lines =<< trim END + vim9script + + class C + public this.val: list> = [ [1], [2], [3] ] + endclass + + var o = C.new() + lockvar o.val[1] + o.val[0] = [9] + assert_equal([ [9], [2], [3] ], o.val) + try + o.val[1] = [999] + call assert_false(true, 'assign should have failed') + catch + assert_exception('E741:') + endtry + o.val[2] = [8] + assert_equal([ [9], [2], [8] ], o.val) END v9.CheckSourceSuccess(lines) enddef @@ -3472,7 +4003,7 @@ def Test_private_object_method() var a = A.new() a._Foo() END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 9) # Try calling a private method using an object (from a def function) lines =<< trim END @@ -3489,7 +4020,7 @@ def Test_private_object_method() enddef T() END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2) # Use a private method from another object method (in script context) lines =<< trim END @@ -3543,7 +4074,7 @@ def Test_private_object_method() var a = A.new() a.Bar() END - v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo') + v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1) # Try calling a private method using the class name lines =<< trim END @@ -3556,20 +4087,7 @@ def Test_private_object_method() endclass A._Foo() END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo') - - # Try to use "public" keyword when defining a private method - lines =<< trim END - vim9script - - class A - public def _Foo() - enddef - endclass - var a = A.new() - a._Foo() - END - v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 8) # Define two private methods with the same name lines =<< trim END @@ -3583,7 +4101,7 @@ def Test_private_object_method() endclass var a = A.new() END - v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo') + v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7) # Define a private method and a object method with the same name lines =<< trim END @@ -3597,7 +4115,7 @@ def Test_private_object_method() endclass var a = A.new() END - v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo') + v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7) # Define an object method and a private method with the same name lines =<< trim END @@ -3611,7 +4129,7 @@ def Test_private_object_method() endclass var a = A.new() END - v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo') + v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7) # Call a public method and a private method from a private method lines =<< trim END @@ -3655,7 +4173,7 @@ def Test_private_object_method() var b = B.new() b.Foo() END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2) # Call a private object method from a child class object method lines =<< trim END @@ -3698,7 +4216,7 @@ def Test_private_object_method() var c = C.new() assert_equal(1234, c._Foo()) END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 16) # Using "_" prefix in a method name should fail outside of a class lines =<< trim END @@ -3708,7 +4226,7 @@ def Test_private_object_method() enddef var a = _Foo() END - v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number') + v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2) enddef " Test for an private class method @@ -3724,7 +4242,7 @@ def Test_private_class_method() endclass A._Foo() END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 8) # Try calling a class private method (from a def function) lines =<< trim END @@ -3740,7 +4258,7 @@ def Test_private_class_method() enddef T() END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1) # Try calling a class private method using an object (at the script level) lines =<< trim END @@ -3754,7 +4272,7 @@ def Test_private_class_method() var a = A.new() a._Foo() END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 9) # Try calling a class private method using an object (from a def function) lines =<< trim END @@ -3771,7 +4289,7 @@ def Test_private_class_method() enddef T() END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 2) # Use a class private method from an object method lines =<< trim END @@ -3823,7 +4341,7 @@ def Test_private_class_method() endclass var a = A.new() END - v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo') + v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7) # Try calling a class private method from another class lines =<< trim END @@ -3842,7 +4360,7 @@ def Test_private_class_method() var b = B.new() assert_equal(1234, b.Foo()) END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1) # Call a private class method from a child class object method lines =<< trim END @@ -3864,7 +4382,7 @@ def Test_private_class_method() var c = C.new() assert_equal(1234, c.Baz()) END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1) # Call a private class method from a child class private class method lines =<< trim END @@ -3885,7 +4403,7 @@ def Test_private_class_method() endclass assert_equal(1234, C.Baz()) END - v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()') + v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1) # Call a private class method from a child class object lines =<< trim END @@ -3906,7 +4424,7 @@ def Test_private_class_method() var c = C.new() assert_equal(1234, C._Foo()) END - v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo') + v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo', 16) enddef " Test for using the return value of a class/object method as a function @@ -3962,35 +4480,35 @@ def Test_static_inheritence() vim9script class A - static _svar: number - this._mvar: number - def new() - _svar = 1 - this._mvar = 101 - enddef - def AccessObject(): number - return this._mvar - enddef - def AccessStaticThroughObject(): number - return _svar - enddef + static _svar: number + this._mvar: number + def new() + _svar = 1 + this._mvar = 101 + enddef + def AccessObject(): number + return this._mvar + enddef + def AccessStaticThroughObject(): number + return _svar + enddef endclass class B extends A - def new() - this._mvar = 102 - enddef + def new() + this._mvar = 102 + enddef endclass class C extends B - def new() - this._mvar = 103 - enddef + def new() + this._mvar = 103 + enddef - def AccessPrivateStaticThroughClassName(): number - assert_equal(1, A._svar) - return 444 - enddef + def AccessPrivateStaticThroughClassName(): number + assert_equal(1, A._svar) + return 444 + enddef endclass var oa = A.new() @@ -4020,7 +4538,7 @@ def Test_dup_member_variable() this.val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4) # Duplicate private member variable lines =<< trim END @@ -4030,7 +4548,7 @@ def Test_dup_member_variable() this._val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4) # Duplicate public member variable lines =<< trim END @@ -4040,7 +4558,7 @@ def Test_dup_member_variable() public this.val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4) # Duplicate private member variable lines =<< trim END @@ -4050,7 +4568,7 @@ def Test_dup_member_variable() this._val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4) # Duplicate public and private member variable lines =<< trim END @@ -4060,7 +4578,7 @@ def Test_dup_member_variable() public this.val = 10 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4) # Duplicate class member variable lines =<< trim END @@ -4070,7 +4588,7 @@ def Test_dup_member_variable() static _s: string = "def" endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4) # Duplicate public and private class member variable lines =<< trim END @@ -4080,7 +4598,7 @@ def Test_dup_member_variable() static _s: string = "def" endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4) # Duplicate class and object member variable lines =<< trim END @@ -4095,7 +4613,7 @@ def Test_dup_member_variable() assert_equal(10, C.val) assert_equal(20, c.val) END - v9.CheckSourceSuccess(lines) + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4) # Duplicate object member variable in a derived class lines =<< trim END @@ -4109,7 +4627,7 @@ def Test_dup_member_variable() this.val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9) # Duplicate object private member variable in a derived class lines =<< trim END @@ -4123,7 +4641,7 @@ def Test_dup_member_variable() this._val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9) # Duplicate object private member variable in a derived class lines =<< trim END @@ -4137,7 +4655,7 @@ def Test_dup_member_variable() this._val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9) # Duplicate object member variable in a derived class lines =<< trim END @@ -4151,7 +4669,7 @@ def Test_dup_member_variable() this.val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val') + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9) # Two member variables with a common prefix lines =<< trim END @@ -4181,7 +4699,7 @@ def Test_private_member_access_outside_class() enddef T() END - v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val') + v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val', 2) # access a non-existing private object member variable lines =<< trim END @@ -4195,7 +4713,7 @@ def Test_private_member_access_outside_class() enddef T() END - v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": _a') + v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": _a', 2) # private static member variable lines =<< trim END @@ -4209,7 +4727,7 @@ def Test_private_member_access_outside_class() enddef T() END - v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2) # private static member variable lines =<< trim END @@ -4223,7 +4741,7 @@ def Test_private_member_access_outside_class() enddef T() END - v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2) # private static class variable lines =<< trim END @@ -4236,7 +4754,7 @@ def Test_private_member_access_outside_class() enddef T() END - v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val') + v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val', 1) # private static class variable lines =<< trim END @@ -4249,7 +4767,7 @@ def Test_private_member_access_outside_class() enddef T() END - v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val') + v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val', 1) enddef " Test for changing the member access of an interface in a implementation class @@ -4257,13 +4775,13 @@ def Test_change_interface_member_access() var lines =<< trim END vim9script interface A - public this.val: number + this.val: number endinterface class B implements A - this.val = 10 + public this.val = 10 endclass END - v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different') + v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7) lines =<< trim END vim9script @@ -4274,7 +4792,7 @@ def Test_change_interface_member_access() public this.val = 10 endclass END - v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different') + v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7) enddef " Test for trying to change a readonly member from a def function @@ -4290,7 +4808,7 @@ def Test_readonly_member_change_in_def_func() enddef T() END - v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable') + v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2) enddef " Test for reading and writing a class member from a def function @@ -4352,7 +4870,7 @@ def Test_class_variable_access_using_object() var a = A.new() echo a.svar2 END - v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8) # Cannot write to a class variable using an object in script context lines =<< trim END @@ -4365,7 +4883,7 @@ def Test_class_variable_access_using_object() var a = A.new() a.svar2 = [2] END - v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8) # Cannot read from a class variable using an object in def method context lines =<< trim END @@ -4381,7 +4899,7 @@ def Test_class_variable_access_using_object() enddef T() END - v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2) # Cannot write to a class variable using an object in def method context lines =<< trim END @@ -4397,7 +4915,7 @@ def Test_class_variable_access_using_object() enddef T() END - v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2) enddef " Test for using a interface method using a child object @@ -4511,7 +5029,7 @@ def Test_abstract_method() class B extends A endclass END - v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented') + v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6) # Use abstract method in a concrete class lines =<< trim END @@ -4522,7 +5040,7 @@ def Test_abstract_method() class B extends A endclass END - v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class') + v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3) # Use abstract method in an interface lines =<< trim END @@ -4544,7 +5062,7 @@ def Test_abstract_method() abs def Foo() endclass END - v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()') + v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3) # Use "abstract" with a member variable lines =<< trim END @@ -4553,7 +5071,7 @@ def Test_abstract_method() abstract this.val = 10 endclass END - v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"') + v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"', 3) # Use a static abstract method lines =<< trim END @@ -4582,7 +5100,7 @@ def Test_abstract_method() enddef endclass END - v9.CheckSourceFailure(lines, 'E1383: Method "Foo": type mismatch, expected func(string, number): list but got func(number, string): list') + v9.CheckSourceFailure(lines, 'E1383: Method "Foo": type mismatch, expected func(string, number): list but got func(number, string): list', 9) # Use an abstract class to invoke an abstract method # FIXME: This should fail @@ -4636,7 +5154,7 @@ def Test_class_method_call_from_subclass() var b = B.new() b.Bar() END - v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"') + v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1) enddef " Test for calling a class method using an object in a def function context and @@ -4680,7 +5198,7 @@ def Test_class_method_call_using_object() var a = A.new() assert_equal('foo', a.Foo()) END - v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9) # def function context lines =<< trim END @@ -4697,7 +5215,7 @@ def Test_class_method_call_using_object() enddef T() END - v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2) enddef def Test_class_variable() @@ -4750,7 +5268,7 @@ def Test_class_variable() endclass B.ClassFunc() END - v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"') + v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1) # Reading a parent class variable from a child class method lines =<< trim END @@ -4767,7 +5285,7 @@ def Test_class_variable() endclass B.ClassFunc() END - v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"') + v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1) # Modifying a parent class variable from a child object method lines =<< trim END @@ -4785,7 +5303,7 @@ def Test_class_variable() var b = B.new() b.ObjFunc() END - v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"') + v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1) # Reading a parent class variable from a child object method lines =<< trim END @@ -4803,7 +5321,7 @@ def Test_class_variable() var b = B.new() b.ObjFunc() END - v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"') + v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1) # Modifying a class variable using an object at script level lines =<< trim END @@ -4815,7 +5333,7 @@ def Test_class_variable() var a = A.new() a.val = 20 END - v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7) # Reading a class variable using an object at script level lines =<< trim END @@ -4827,7 +5345,7 @@ def Test_class_variable() var a = A.new() var i = a.val END - v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7) # Modifying a class variable using an object at function level lines =<< trim END @@ -4843,7 +5361,7 @@ def Test_class_variable() enddef T() END - v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2) # Reading a class variable using an object at function level lines =<< trim END @@ -4858,7 +5376,7 @@ def Test_class_variable() enddef T() END - v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"') + v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2) enddef " Test for using a duplicate class method and class variable in a child class @@ -4957,7 +5475,7 @@ def Test_instance_method_call_using_class() endclass A.Foo() END - v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object') + v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7) # Invoke an object method using a class in def function context lines =<< trim END @@ -4972,7 +5490,7 @@ def Test_instance_method_call_using_class() enddef T() END - v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object') + v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1) enddef " Test for duplicate class method and instance method @@ -4987,7 +5505,7 @@ def Test_dup_classmethod_objmethod() enddef endclass END - v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo') + v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6) # Duplicate private instance method lines =<< trim END @@ -4999,7 +5517,7 @@ def Test_dup_classmethod_objmethod() enddef endclass END - v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo') + v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6) # Duplicate class method lines =<< trim END @@ -5011,7 +5529,7 @@ def Test_dup_classmethod_objmethod() enddef endclass END - v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo') + v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6) # Duplicate private class method lines =<< trim END @@ -5023,7 +5541,7 @@ def Test_dup_classmethod_objmethod() enddef endclass END - v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo') + v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6) # Duplicate private class and object method lines =<< trim END @@ -5035,7 +5553,7 @@ def Test_dup_classmethod_objmethod() enddef endclass END - v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo') + v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6) enddef " Test for an instance method access level comparison with parent instance @@ -5055,7 +5573,7 @@ def Test_instance_method_access_level() enddef endclass END - v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"') + v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11) # Public method in subclass lines =<< trim END @@ -5071,7 +5589,7 @@ def Test_instance_method_access_level() enddef endclass END - v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"') + v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11) enddef def Test_extend_empty_class() @@ -5101,7 +5619,7 @@ def Test_extend_empty_class() enddef " A interface cannot have a static variable or a static method or a private -" variable or a private method +" variable or a private method or a public variable def Test_interface_with_unsupported_members() var lines =<< trim END vim9script @@ -5109,7 +5627,7 @@ def Test_interface_with_unsupported_members() static num: number endinterface END - v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface') + v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3) lines =<< trim END vim9script @@ -5117,7 +5635,15 @@ def Test_interface_with_unsupported_members() static _num: number endinterface END - v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface') + v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3) + + lines =<< trim END + vim9script + interface A + public static num: number + endinterface + END + v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3) lines =<< trim END vim9script @@ -5125,15 +5651,15 @@ def Test_interface_with_unsupported_members() public static num: number endinterface END - v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface') + v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3) lines =<< trim END vim9script interface A - public static _num: number + static _num: number endinterface END - v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface') + v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3) lines =<< trim END vim9script @@ -5141,7 +5667,7 @@ def Test_interface_with_unsupported_members() static def Foo(d: dict): list endinterface END - v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface') + v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3) lines =<< trim END vim9script @@ -5149,7 +5675,7 @@ def Test_interface_with_unsupported_members() static def _Foo(d: dict): list endinterface END - v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface') + v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3) lines =<< trim END vim9script @@ -5157,7 +5683,7 @@ def Test_interface_with_unsupported_members() this._Foo: list endinterface END - v9.CheckSourceFailure(lines, 'E1379: Private variable not supported in an interface') + v9.CheckSourceFailure(lines, 'E1379: Private variable not supported in an interface', 3) lines =<< trim END vim9script @@ -5165,7 +5691,7 @@ def Test_interface_with_unsupported_members() def _Foo(d: dict): list endinterface END - v9.CheckSourceFailure(lines, 'E1380: Private method not supported in an interface') + v9.CheckSourceFailure(lines, 'E1380: Private method not supported in an interface', 3) enddef " Test for extending an interface @@ -5177,14 +5703,14 @@ def Test_extend_interface() def Foo() endinterface interface B extends A - public this.var2: dict + this.var2: dict def Bar() endinterface class C implements A, B this.var1 = [1, 2] def Foo() enddef - public this.var2 = {a: '1'} + this.var2 = {a: '1'} def Bar() enddef endclass @@ -5197,13 +5723,13 @@ def Test_extend_interface() def Foo() endinterface interface B extends A - public this.var2: dict + this.var2: dict endinterface class C implements A, B - public this.var2 = {a: '1'} + this.var2 = {a: '1'} endclass END - v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented') + v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10) lines =<< trim END vim9script @@ -5211,14 +5737,14 @@ def Test_extend_interface() def Foo() endinterface interface B extends A - public this.var2: dict + this.var2: dict endinterface class C implements A, B def Foo() enddef endclass END - v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented') + v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11) # interface cannot extend a class lines =<< trim END @@ -5228,7 +5754,7 @@ def Test_extend_interface() interface B extends A endinterface END - v9.CheckSourceFailure(lines, 'E1354: Cannot extend A') + v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5) # class cannot extend an interface lines =<< trim END @@ -5238,7 +5764,7 @@ def Test_extend_interface() class B extends A endclass END - v9.CheckSourceFailure(lines, 'E1354: Cannot extend A') + v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5) # interface cannot implement another interface lines =<< trim END @@ -5248,7 +5774,7 @@ def Test_extend_interface() interface B implements A endinterface END - v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"') + v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4) # interface cannot extend multiple interfaces lines =<< trim END @@ -5260,7 +5786,7 @@ def Test_extend_interface() interface C extends A, B endinterface END - v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B') + v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6) # Variable type in an extended interface is of different type lines =<< trim END @@ -5276,7 +5802,7 @@ def Test_extend_interface() this.val2: number endinterface END - v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string') + v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11) enddef " Test for a child class implementing an interface when some of the methods are @@ -5373,7 +5899,7 @@ def Test_child_class_implements_interface() enddef endclass END - v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented') + v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26) # One of the interface methods is of different type lines =<< trim END @@ -5407,7 +5933,7 @@ def Test_child_class_implements_interface() enddef endclass END - v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number') + v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29) # One of the interface variables is not present lines =<< trim END @@ -5433,7 +5959,7 @@ def Test_child_class_implements_interface() this.var1 = [{a: 10}] endclass END - v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented') + v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21) # One of the interface variables is of different type lines =<< trim END @@ -5460,7 +5986,7 @@ def Test_child_class_implements_interface() this.var1 = [{a: 10}] endclass END - v9.CheckSourceFailure(lines, 'E1382: Variable "var3": type mismatch, expected list> but got list>') + v9.CheckSourceFailure(lines, 'E1382: Variable "var3": type mismatch, expected list> but got list>', 22) enddef " Test for extending an interface with duplicate variables and methods @@ -5531,7 +6057,7 @@ def Test_implements_using_var_type_any() endclass var b = B.new() END - v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list> but got dict') + v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list> but got dict', 1) enddef " Test for assigning to a member variable in a nested class @@ -5540,29 +6066,29 @@ def Test_nested_object_assignment() vim9script class A - this.value: number + this.value: number endclass class B - this.a: A = A.new() + this.a: A = A.new() endclass class C - this.b: B = B.new() + this.b: B = B.new() endclass class D - this.c: C = C.new() + this.c: C = C.new() endclass def T(da: D) - da.c.b.a.value = 10 + da.c.b.a.value = 10 enddef var d = D.new() T(d) END - v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable') + v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1) enddef " Test for calling methods using a null object @@ -5705,4 +6231,167 @@ def Test_freed_object_from_previous_method_call() v9.CheckSourceSuccess(lines) enddef +" Test for duplicate object and class variable +def Test_duplicate_variable() + # Object variable name is same as the class variable name + var lines =<< trim END + vim9script + class A + public static sval: number + public this.sval: number + endclass + var a = A.new() + END + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4) + + # Duplicate variable name and calling a class method + lines =<< trim END + vim9script + class A + public static sval: number + public this.sval: number + def F1() + echo this.sval + enddef + static def F2() + echo sval + enddef + endclass + A.F2() + END + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4) + + # Duplicate variable with an empty constructor + lines =<< trim END + vim9script + class A + public static sval: number + public this.sval: number + def new() + enddef + endclass + var a = A.new() + END + v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4) +enddef + +" Test for using a reserved keyword as a variable name +def Test_reserved_varname() + for kword in ['true', 'false', 'null', 'null_blob', 'null_dict', + 'null_function', 'null_list', 'null_partial', 'null_string', + 'null_channel', 'null_job', 'super', 'this'] + + var lines =<< trim eval END + vim9script + class C + public this.{kword}: list = [1, 2, 3] + endclass + var o = C.new() + END + v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3) + + lines =<< trim eval END + vim9script + class C + public this.{kword}: list = [1, 2, 3] + def new() + enddef + endclass + var o = C.new() + END + v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3) + + lines =<< trim eval END + vim9script + class C + public this.{kword}: list = [1, 2, 3] + def new() + enddef + def F() + echo this.{kword} + enddef + endclass + var o = C.new() + o.F() + END + v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3) + endfor +enddef + +" Test for checking the type of the arguments and the return value of a object +" method in an extended class. +def Test_extended_obj_method_type_check() + var lines =<< trim END + vim9script + + class A + endclass + class B extends A + endclass + class C extends B + endclass + + class Foo + def Doit(p: B): B + return B.new() + enddef + endclass + + class Bar extends Foo + def Doit(p: A): C + return C.new() + enddef + endclass + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + + class A + endclass + class B extends A + endclass + class C extends B + endclass + + class Foo + def Doit(p: B): B + return B.new() + enddef + endclass + + class Bar extends Foo + def Doit(p: C): B + return B.new() + enddef + endclass + END + v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object): object but got func(object): object', 20) + + lines =<< trim END + vim9script + + class A + endclass + class B extends A + endclass + class C extends B + endclass + + class Foo + def Doit(p: B): B + return B.new() + enddef + endclass + + class Bar extends Foo + def Doit(p: B): A + return A.new() + enddef + endclass + END + v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object): object but got func(object): object', 20) +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 4cf4dfe5b0..206908b79c 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -3052,15 +3052,15 @@ def Test_disassemble_interface_static_member() var lines =<< trim END vim9script interface I - public this.o_var: number - public this.o_var2: number + this.o_var: number + this.o_var2: number endinterface class C implements I public static s_var: number - public this.o_var: number + this.o_var: number public static s_var2: number - public this.o_var2: number + this.o_var2: number endclass def F1(i: I) diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index 656185adad..a16c5ae198 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -4636,6 +4636,56 @@ def Test_free_type_before_use() v9.CheckScriptSuccess(lines) enddef +" The following complicated script used to cause an internal error (E340) +" because the funcref instruction memory was referenced after the instruction +" memory was reallocated (Github issue #13178) +def Test_refer_funcref_instr_after_realloc() + var lines =<< trim END + vim9script + def A(d: bool) + var e = abs(0) + var f = &emoji + &emoji = true + if ['', '', '']->index('xxx') == 0 + eval 0 + 0 + endif + if &filetype == 'xxx' + var g = abs(0) + while g > 0 + if getline(g) == '' + break + endif + --g + endwhile + if g == 0 + return + endif + if d + feedkeys($'{g}G') + g = abs(0) + endif + var h = abs(0) + var i = abs(0) + var j = abs(0) + while j < 0 + if abs(0) < h && getline(j) != '' + break + endif + ++j + endwhile + feedkeys($'{g}G{j}G') + return + endif + def B() + enddef + def C() + enddef + enddef + A(false) + END + v9.CheckScriptSuccess(lines) +enddef + " Keep this last, it messes up highlighting. def Test_substitute_cmd() new diff --git a/src/userfunc.c b/src/userfunc.c index e0c1d5f919..0f487fc120 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -320,6 +320,16 @@ get_function_args( ++p; char_u *argend = p; + // object variable this. can be used only in a constructor + if (STRNCMP(eap->arg, "new", 3) != 0) + { + c = *argend; + *argend = NUL; + semsg(_(e_cannot_use_an_object_variable_except_with_the_new_method_str), arg); + *argend = c; + break; + } + if (*skipwhite(p) == '=') { char_u *defval = skipwhite(skipwhite(p) + 1); diff --git a/src/version.c b/src/version.c index b67da4e7b1..bd44c48162 100644 --- a/src/version.c +++ b/src/version.c @@ -714,6 +714,42 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1959, +/**/ + 1958, +/**/ + 1957, +/**/ + 1956, +/**/ + 1955, +/**/ + 1954, +/**/ + 1953, +/**/ + 1952, +/**/ + 1951, +/**/ + 1950, +/**/ + 1949, +/**/ + 1948, +/**/ + 1947, +/**/ + 1946, +/**/ + 1945, +/**/ + 1944, +/**/ + 1943, +/**/ + 1942, /**/ 1941, /**/ diff --git a/src/vim.h b/src/vim.h index 9c06b06fe3..a75353b007 100644 --- a/src/vim.h +++ b/src/vim.h @@ -825,7 +825,9 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define EXPAND_BREAKPOINT 51 #define EXPAND_SCRIPTNAMES 52 #define EXPAND_RUNTIME 53 -#define EXPAND_MACACTION 54 +#define EXPAND_STRING_SETTING 54 +#define EXPAND_SETTING_SUBTRACT 55 +#define EXPAND_MACACTION 56 // Values for exmode_active (0 is no exmode) #define EXMODE_NORMAL 1 @@ -2337,6 +2339,20 @@ typedef enum { */ typedef char *(*opt_did_set_cb_T)(optset_T *args); +/* + * Type for the callback function that is invoked when expanding possible + * string option values during cmdline completion. + * + * Strings in returned matches will be managed and freed by caller. + * + * Returns OK if the expansion succeeded (numMatches and matches have to be + * set). Otherwise returns FAIL. + * + * Note: If returned FAIL or *numMatches is 0, *matches will NOT be freed by + * caller. + */ +typedef int (*opt_expand_cb_T)(optexpand_T *args, int *numMatches, char_u ***matches); + // Flags for assignment functions. #define ASSIGN_VAR 0 // ":var" (nothing special) #define ASSIGN_FINAL 0x01 // ":final" diff --git a/src/vim9.h b/src/vim9.h index bafff94fde..320e35bde0 100644 --- a/src/vim9.h +++ b/src/vim9.h @@ -498,14 +498,20 @@ typedef struct { typedef struct { class_T *cm_class; int cm_idx; - int cm_static; } classmember_T; + // arguments to ISN_STOREINDEX typedef struct { vartype_T si_vartype; class_T *si_class; } storeindex_T; +// arguments to ISN_LOCKUNLOCK +typedef struct { + char_u *string; // for exec_command + int is_arg; // is lval_root a function arg +} lockunlock_T; + /* * Instruction */ @@ -562,6 +568,7 @@ struct isn_S { construct_T construct; classmember_T classmember; storeindex_T storeindex; + lockunlock_T lockunlock; } isn_arg; }; diff --git a/src/vim9class.c b/src/vim9class.c index b5e11ca7fb..790c2c36f6 100644 --- a/src/vim9class.c +++ b/src/vim9class.c @@ -220,12 +220,10 @@ add_members_to_class( * "cl" implementing that interface. */ int -object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl, - int is_static) +object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl) { if (idx >= (is_method ? itf->class_obj_method_count - : is_static ? itf->class_class_member_count - : itf->class_obj_member_count)) + : itf->class_obj_member_count)) { siemsg("index %d out of range for interface %s", idx, itf->class_name); return 0; @@ -255,9 +253,7 @@ object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl, if (searching && is_method) // The parent class methods are stored after the current class // methods. - method_offset += is_static - ? super->class_class_function_count_child - : super->class_obj_method_count_child; + method_offset += super->class_obj_method_count_child; } if (i2c == NULL) { @@ -265,26 +261,12 @@ object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl, cl->class_name, itf->class_name); return 0; } - if (is_static) - { - // TODO: Need a table for fast lookup? - char_u *name = itf->class_class_members[idx].ocm_name; - int m_idx = class_member_idx(i2c->i2c_class, name, 0); - if (m_idx >= 0) - return m_idx; - siemsg("class %s, interface %s, static %s not found", - cl->class_name, itf->class_name, name); - return 0; - } - else - { - // A table follows the i2c for the class - int *table = (int *)(i2c + 1); - // "method_offset" is 0, if method is in the current class. If method - // is in a parent class, then it is non-zero. - return table[idx] + method_offset; - } + // A table follows the i2c for the class + int *table = (int *)(i2c + 1); + // "method_offset" is 0, if method is in the current class. If method + // is in a parent class, then it is non-zero. + return table[idx] + method_offset; } /* @@ -893,24 +875,52 @@ check_func_arg_names( } /* - * Returns TRUE if the member "varname" is already defined. + * Returns TRUE if 'varname' is a reserved keyword name */ static int -is_duplicate_member(garray_T *mgap, char_u *varname, char_u *varname_end) +is_reserved_varname(char_u *varname, char_u *varname_end) +{ + int reserved = FALSE; + char_u save_varname_end = *varname_end; + *varname_end = NUL; + + reserved = check_reserved_name(varname, FALSE) == FAIL; + + *varname_end = save_varname_end; + + return reserved; +} + +/* + * Returns TRUE if the variable "varname" is already defined either as a class + * variable or as an object variable. + */ + static int +is_duplicate_variable( + garray_T *class_members, + garray_T *obj_members, + char_u *varname, + char_u *varname_end) { char_u *name = vim_strnsave(varname, varname_end - varname); char_u *pstr = (*name == '_') ? name + 1 : name; int dup = FALSE; - for (int i = 0; i < mgap->ga_len; ++i) + for (int loop = 1; loop <= 2; loop++) { - ocmember_T *m = ((ocmember_T *)mgap->ga_data) + i; - char_u *qstr = *m->ocm_name == '_' ? m->ocm_name + 1 : m->ocm_name; - if (STRCMP(pstr, qstr) == 0) + // loop == 1: class variables, loop == 2: object variables + garray_T *vgap = (loop == 1) ? class_members : obj_members; + for (int i = 0; i < vgap->ga_len; ++i) { - semsg(_(e_duplicate_variable_str), name); - dup = TRUE; - break; + ocmember_T *m = ((ocmember_T *)vgap->ga_data) + i; + char_u *qstr = *m->ocm_name == '_' ? m->ocm_name + 1 + : m->ocm_name; + if (STRCMP(pstr, qstr) == 0) + { + semsg(_(e_duplicate_variable_str), name); + dup = TRUE; + break; + } } } @@ -1430,11 +1440,19 @@ ex_class(exarg_T *eap) { char_u *impl_end = find_name_end(arg, NULL, NULL, FNE_CHECK_START); - if (!IS_WHITE_OR_NUL(*impl_end) && *impl_end != ',') + if ((!IS_WHITE_OR_NUL(*impl_end) && *impl_end != ',') + || (*impl_end == ',' + && !IS_WHITE_OR_NUL(*(impl_end + 1)))) { semsg(_(e_white_space_required_after_name_str), arg); goto early_ret; } + if (impl_end - arg == 0) + { + emsg(_(e_missing_name_after_implements)); + goto early_ret; + } + char_u *iname = vim_strnsave(arg, impl_end - arg); if (iname == NULL) goto early_ret; @@ -1539,6 +1557,11 @@ ex_class(exarg_T *eap) semsg(_(e_command_cannot_be_shortened_str), line); break; } + if (!is_class) + { + emsg(_(e_public_variable_not_supported_in_interface)); + break; + } has_public = TRUE; p = skipwhite(line + 6); @@ -1633,7 +1656,13 @@ ex_class(exarg_T *eap) &varname_end, &type_list, &type, is_class ? &init_expr: NULL) == FAIL) break; - if (is_duplicate_member(&objmembers, varname, varname_end)) + if (is_reserved_varname(varname, varname_end)) + { + vim_free(init_expr); + break; + } + if (is_duplicate_variable(&classmembers, &objmembers, varname, + varname_end)) { vim_free(init_expr); break; @@ -1664,7 +1693,20 @@ ex_class(exarg_T *eap) exarg_T ea; garray_T lines_to_free; - // TODO: error for "public static def Func()"? + if (has_public) + { + // "public" keyword is not supported when defining an object or + // class method + emsg(_(e_public_keyword_not_supported_for_method)); + break; + } + + if (*p == NUL) + { + // No method name following def + semsg(_(e_not_valid_command_in_class_str), line); + break; + } CLEAR_FIELD(ea); ea.cmd = line; @@ -1742,7 +1784,13 @@ ex_class(exarg_T *eap) &varname_end, &type_list, &type, is_class ? &init_expr : NULL) == FAIL) break; - if (is_duplicate_member(&classmembers, varname, varname_end)) + if (is_reserved_varname(varname, varname_end)) + { + vim_free(init_expr); + break; + } + if (is_duplicate_variable(&classmembers, &objmembers, varname, + varname_end)) { vim_free(init_expr); break; @@ -2513,7 +2561,7 @@ inside_class(cctx_T *cctx_arg, class_T *cl) { for (cctx_T *cctx = cctx_arg; cctx != NULL; cctx = cctx->ctx_outer) if (cctx->ctx_ufunc != NULL - && class_instance_of(cctx->ctx_ufunc->uf_class, cl)) + && class_instance_of(cctx->ctx_ufunc->uf_class, cl, TRUE)) return TRUE; return FALSE; } @@ -2823,29 +2871,39 @@ member_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len) * interfaces matches the class "other_cl". */ int -class_instance_of(class_T *cl, class_T *other_cl) +class_instance_of(class_T *cl, class_T *other_cl, int covariance_check) { if (cl == other_cl) return TRUE; - // Recursively check the base classes. - for (; cl != NULL; cl = cl->class_extends) + if (covariance_check) { - if (cl == other_cl) - return TRUE; - // Check the implemented interfaces and the super interfaces - for (int i = cl->class_interface_count - 1; i >= 0; --i) + // Recursively check the base classes. + for (; cl != NULL; cl = cl->class_extends) { - class_T *intf = cl->class_interfaces_cl[i]; - while (intf != NULL) + if (cl == other_cl) + return TRUE; + // Check the implemented interfaces and the super interfaces + for (int i = cl->class_interface_count - 1; i >= 0; --i) { - if (intf == other_cl) - return TRUE; - // check the super interfaces - intf = intf->class_extends; + class_T *intf = cl->class_interfaces_cl[i]; + while (intf != NULL) + { + if (intf == other_cl) + return TRUE; + // check the super interfaces + intf = intf->class_extends; + } } } } + else + { + // contra-variance + for (; other_cl != NULL; other_cl = other_cl->class_extends) + if (cl == other_cl) + return TRUE; + } return FALSE; } @@ -2880,7 +2938,7 @@ f_instanceof(typval_T *argvars, typval_T *rettv) } if (class_instance_of(object_tv->vval.v_object->obj_class, - li->li_tv.vval.v_class) == TRUE) + li->li_tv.vval.v_class, TRUE) == TRUE) { rettv->vval.v_number = VVAL_TRUE; return; @@ -2889,8 +2947,9 @@ f_instanceof(typval_T *argvars, typval_T *rettv) } else if (classinfo_tv->v_type == VAR_CLASS) { - rettv->vval.v_number = class_instance_of(object_tv->vval.v_object->obj_class, - classinfo_tv->vval.v_class); + rettv->vval.v_number = class_instance_of( + object_tv->vval.v_object->obj_class, + classinfo_tv->vval.v_class, TRUE); } } diff --git a/src/vim9cmds.c b/src/vim9cmds.c index 0ca3be11a8..0d6dc01f9f 100644 --- a/src/vim9cmds.c +++ b/src/vim9cmds.c @@ -189,10 +189,15 @@ compile_lock_unlock( int cc = *name_end; char_u *p = lvp->ll_name; int ret = OK; - size_t len; char_u *buf; isntype_T isn = ISN_EXEC; char *cmd = eap->cmdidx == CMD_lockvar ? "lockvar" : "unlockvar"; + int is_arg = FALSE; + +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: compile_lock_unlock(): cookie %p, name %s", + coookie, p); +#endif if (cctx->ctx_skip == SKIP_YES) return OK; @@ -207,20 +212,68 @@ compile_lock_unlock( if (p[1] != ':') { char_u *end = find_name_end(p, NULL, NULL, FNE_CHECK_START); + // If name is is locally accessible, except for local var, + // then put it on the stack to use with ISN_LOCKUNLOCK. + // This could be v.memb, v[idx_key]; bare class variable, + // function arg. The local variable on the stack, will be passed + // to ex_lockvar() indirectly. - if (lookup_local(p, end - p, NULL, cctx) == OK) - { - char_u *s = p; + char_u *name = NULL; + int len = end - p; - if (*end != '.' && *end != '[') + if (lookup_local(p, len, NULL, cctx) == OK) + { + // Handle "this", "this.val", "anyvar[idx]" + if (*end != '.' && *end != '[' + && (len != 4 || STRNCMP("this", p, len) != 0)) { emsg(_(e_cannot_lock_unlock_local_variable)); return FAIL; } - - // For "d.member" put the local variable on the stack, it will be - // passed to ex_lockvar() indirectly. - if (compile_load(&s, end, cctx, FALSE, FALSE) == FAIL) + // Push the local on the stack, could be "this". + name = p; +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: compile... lookup_local: name %s", name); +#endif + } + if (name == NULL) + { + class_T *cl; + if (cctx_class_member_idx(cctx, p, len, &cl) >= 0) + { + if (*end != '.' && *end != '[') + { + // Push the class of the bare class variable name + name = cl->class_name; + len = STRLEN(name); +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: compile... cctx_class_member: name %s", + name); +#endif + } + } + } + if (name == NULL) + { + int idx; + type_T *type; + // Can lockvar any function arg. + // TODO: test arg[idx]/arg.member + if (arg_exists(p, len, &idx, &type, NULL, cctx) == OK) + { + name = p; + is_arg = TRUE; +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: compile... arg_exists: name %s", name); +#endif + } + } + if (name != NULL) + { +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: compile... INS_LOCKUNLOCK %s", name); +#endif + if (compile_load(&name, name + len, cctx, FALSE, FALSE) == FAIL) return FAIL; isn = ISN_LOCKUNLOCK; } @@ -228,7 +281,7 @@ compile_lock_unlock( // Checking is done at runtime. *name_end = NUL; - len = name_end - p + 20; + size_t len = name_end - p + 20; buf = alloc(len); if (buf == NULL) ret = FAIL; @@ -238,7 +291,13 @@ compile_lock_unlock( vim_snprintf((char *)buf, len, "%s! %s", cmd, p); else vim_snprintf((char *)buf, len, "%s %d %s", cmd, deep, p); - ret = generate_EXEC_copy(cctx, isn, buf); +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: compile... buf %s", buf); +#endif + if (isn == ISN_LOCKUNLOCK) + ret = generate_LOCKUNLOCK(cctx, buf, is_arg); + else + ret = generate_EXEC_copy(cctx, isn, buf); vim_free(buf); *name_end = cc; diff --git a/src/vim9compile.c b/src/vim9compile.c index 269d8013bb..086a322caa 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1029,7 +1029,7 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free) ufunc_T *ufunc; int r = FAIL; compiletype_T compile_type; - isn_T *funcref_isn = NULL; + int funcref_isn_idx = -1; lvar_T *lvar = NULL; if (eap->forceit) @@ -1148,7 +1148,7 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free) ASSIGN_CONST, ufunc->uf_func_type); if (lvar == NULL) goto theend; - if (generate_FUNCREF(cctx, ufunc, NULL, 0, &funcref_isn) == FAIL) + if (generate_FUNCREF(cctx, ufunc, NULL, 0, &funcref_isn_idx) == FAIL) goto theend; r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); } @@ -1178,8 +1178,12 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free) #endif // If a FUNCREF instruction was generated, set the index after compiling. - if (funcref_isn != NULL && ufunc->uf_def_status == UF_COMPILED) + if (funcref_isn_idx != -1 && ufunc->uf_def_status == UF_COMPILED) + { + isn_T *funcref_isn = ((isn_T *)cctx->ctx_instr.ga_data) + + funcref_isn_idx; funcref_isn->isn_arg.funcref.fr_dfunc_idx = ufunc->uf_dfunc_idx; + } theend: vim_free(lambda_name); @@ -2245,9 +2249,8 @@ compile_load_lhs_with_index(lhs_T *lhs, char_u *var_start, cctx_T *cctx) return FAIL; } if (cl->class_flags & CLASS_INTERFACE) - return generate_GET_ITF_MEMBER(cctx, cl, lhs->lhs_member_idx, type, - FALSE); - return generate_GET_OBJ_MEMBER(cctx, lhs->lhs_member_idx, type, FALSE); + return generate_GET_ITF_MEMBER(cctx, cl, lhs->lhs_member_idx, type); + return generate_GET_OBJ_MEMBER(cctx, lhs->lhs_member_idx, type); } compile_load_lhs(lhs, var_start, NULL, cctx); diff --git a/src/vim9execute.c b/src/vim9execute.c index 02a37e8bfb..209f86fb53 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -535,6 +535,15 @@ call_dfunc( // If this is an object method, the object is just before the arguments. typval_T *obj = STACK_TV_BOT(0) - argcount - vararg_count - 1; + if (IS_OBJECT_METHOD(ufunc) && !IS_CONSTRUCTOR_METHOD(ufunc) + && obj->v_type == VAR_OBJECT && obj->vval.v_object == NULL) + { + // If this is not a constructor method, then a valid object is + // needed. + emsg(_(e_using_null_object)); + return FAIL; + } + // Check the argument types. if (check_ufunc_arg_types(ufunc, argcount, vararg_count, ectx) == FAIL) return FAIL; @@ -601,15 +610,6 @@ call_dfunc( // the first local variable. if (IS_OBJECT_METHOD(ufunc)) { - if (obj->v_type == VAR_OBJECT && obj->vval.v_object == NULL - && !IS_CONSTRUCTOR_METHOD(ufunc)) - { - // If this is not a constructor method, then a valid object is - // needed. - emsg(_(e_using_null_object)); - return FAIL; - } - *STACK_TV_VAR(0) = *obj; obj->v_type = VAR_UNKNOWN; } @@ -1957,7 +1957,7 @@ fill_partial_and_closure( * Execute iptr->isn_arg.string as an Ex command. */ static int -exec_command(isn_T *iptr) +exec_command(isn_T *iptr, char_u *cmd_string) { source_cookie_T cookie; @@ -1965,8 +1965,7 @@ exec_command(isn_T *iptr) // Pass getsourceline to get an error for a missing ":end" command. CLEAR_FIELD(cookie); cookie.sourcing_lnum = iptr->isn_lnum - 1; - if (do_cmdline(iptr->isn_arg.string, - getsourceline, &cookie, + if (do_cmdline(cmd_string, getsourceline, &cookie, DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED) == FAIL || did_emsg) return FAIL; @@ -2318,7 +2317,7 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx) if (itf != NULL) // convert interface member index to class member index lidx = object_index_from_itf_index(itf, FALSE, lidx, - obj->obj_class, FALSE); + obj->obj_class); } else { @@ -3182,7 +3181,7 @@ exec_instructions(ectx_T *ectx) // execute Ex command line case ISN_EXEC: - if (exec_command(iptr) == FAIL) + if (exec_command(iptr, iptr->isn_arg.string) == FAIL) goto on_error; break; @@ -4179,16 +4178,24 @@ exec_instructions(ectx_T *ectx) case ISN_LOCKUNLOCK: { + // TODO: could put lval_root info in struct typval_T *lval_root_save = lval_root; + int lval_root_is_arg_save = lval_root_is_arg; int res; +#ifdef LOG_LOCKVAR + ch_log(NULL, "LKVAR: execute INS_LOCKUNLOCK isn_arg %s", + iptr->isn_arg.string); +#endif // Stack has the local variable, argument the whole :lock // or :unlock command, like ISN_EXEC. --ectx->ec_stack.ga_len; lval_root = STACK_TV_BOT(0); - res = exec_command(iptr); + lval_root_is_arg = iptr->isn_arg.lockunlock.is_arg; + res = exec_command(iptr, iptr->isn_arg.lockunlock.string); clear_tv(lval_root); lval_root = lval_root_save; + lval_root_is_arg = lval_root_is_arg_save; if (res == FAIL) goto on_error; } @@ -4262,8 +4269,7 @@ exec_instructions(ectx_T *ectx) // convert the interface index to the object index int idx = object_index_from_itf_index(mfunc->cmf_itf, - TRUE, mfunc->cmf_idx, cl, - FALSE); + TRUE, mfunc->cmf_idx, cl); if (call_ufunc(cl->class_obj_methods[idx], NULL, mfunc->cmf_argcount, ectx, NULL, NULL) == FAIL) @@ -4412,8 +4418,7 @@ exec_instructions(ectx_T *ectx) // convert the interface index to the object index int idx = object_index_from_itf_index(extra->fre_class, - TRUE, extra->fre_method_idx, cl, - FALSE); + TRUE, extra->fre_method_idx, cl); ufunc = cl->class_obj_methods[idx]; } else if (extra == NULL || extra->fre_func_name == NULL) @@ -5392,7 +5397,6 @@ exec_instructions(ectx_T *ectx) goto on_error; } - int is_static = iptr->isn_arg.classmember.cm_static; int idx; if (iptr->isn_type == ISN_GET_OBJ_MEMBER) idx = iptr->isn_arg.classmember.cm_idx; @@ -5402,15 +5406,11 @@ exec_instructions(ectx_T *ectx) // convert the interface index to the object index idx = object_index_from_itf_index( iptr->isn_arg.classmember.cm_class, - FALSE, idx, obj->obj_class, is_static); + FALSE, idx, obj->obj_class); } // The members are located right after the object struct. - typval_T *mtv; - if (is_static) - mtv = &obj->obj_class->class_members_tv[idx]; - else - mtv = ((typval_T *)(obj + 1)) + idx; + typval_T *mtv = ((typval_T *)(obj + 1)) + idx; copy_tv(mtv, tv); // Unreference the object after getting the member, it may @@ -7157,17 +7157,13 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc) case ISN_MEMBER: smsg("%s%4d MEMBER", pfx, current); break; case ISN_STRINGMEMBER: smsg("%s%4d MEMBER %s", pfx, current, iptr->isn_arg.string); break; - case ISN_GET_OBJ_MEMBER: smsg("%s%4d OBJ_MEMBER %d%s", pfx, current, - (int)iptr->isn_arg.classmember.cm_idx, - iptr->isn_arg.classmember.cm_static - ? " [STATIC]" : ""); + case ISN_GET_OBJ_MEMBER: smsg("%s%4d OBJ_MEMBER %d", pfx, current, + (int)iptr->isn_arg.classmember.cm_idx); break; - case ISN_GET_ITF_MEMBER: smsg("%s%4d ITF_MEMBER %d on %s%s", + case ISN_GET_ITF_MEMBER: smsg("%s%4d ITF_MEMBER %d on %s", pfx, current, (int)iptr->isn_arg.classmember.cm_idx, - iptr->isn_arg.classmember.cm_class->class_name, - iptr->isn_arg.classmember.cm_static - ? " [STATIC]" : ""); + iptr->isn_arg.classmember.cm_class->class_name); break; case ISN_STORE_THIS: smsg("%s%4d STORE_THIS %d", pfx, current, (int)iptr->isn_arg.number); break; diff --git a/src/vim9expr.c b/src/vim9expr.c index 7abd0a4d37..5a302d6884 100644 --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -413,9 +413,8 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type) *arg = name_end; if (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED)) - return generate_GET_ITF_MEMBER(cctx, cl, m_idx, m->ocm_type, - FALSE); - return generate_GET_OBJ_MEMBER(cctx, m_idx, m->ocm_type, FALSE); + return generate_GET_ITF_MEMBER(cctx, cl, m_idx, m->ocm_type); + return generate_GET_OBJ_MEMBER(cctx, m_idx, m->ocm_type); } // Could be a function reference: "obj.Func". diff --git a/src/vim9instr.c b/src/vim9instr.c index 96c02de7ca..697c83d8ae 100644 --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -136,7 +136,7 @@ generate_CONSTRUCT(cctx_T *cctx, class_T *cl) * index. */ int -generate_GET_OBJ_MEMBER(cctx_T *cctx, int idx, type_T *type, int is_static) +generate_GET_OBJ_MEMBER(cctx_T *cctx, int idx, type_T *type) { RETURN_OK_IF_SKIP(cctx); @@ -147,7 +147,6 @@ generate_GET_OBJ_MEMBER(cctx_T *cctx, int idx, type_T *type, int is_static) isn->isn_arg.classmember.cm_class = NULL; isn->isn_arg.classmember.cm_idx = idx; - isn->isn_arg.classmember.cm_static = is_static; return push_type_stack2(cctx, type, &t_any); } @@ -156,8 +155,7 @@ generate_GET_OBJ_MEMBER(cctx_T *cctx, int idx, type_T *type, int is_static) * by index. */ int -generate_GET_ITF_MEMBER(cctx_T *cctx, class_T *itf, int idx, type_T *type, - int is_static) +generate_GET_ITF_MEMBER(cctx_T *cctx, class_T *itf, int idx, type_T *type) { RETURN_OK_IF_SKIP(cctx); @@ -169,7 +167,6 @@ generate_GET_ITF_MEMBER(cctx_T *cctx, class_T *itf, int idx, type_T *type, isn->isn_arg.classmember.cm_class = itf; ++itf->class_refcount; isn->isn_arg.classmember.cm_idx = idx; - isn->isn_arg.classmember.cm_static = is_static; return push_type_stack2(cctx, type, &t_any); } @@ -1378,7 +1375,9 @@ generate_NEWDICT(cctx_T *cctx, int count, int use_null) * Generate an ISN_FUNCREF instruction. * For "obj.Method" "cl" is the class of the object (can be an interface or a * base class) and "fi" the index of the method on that class. - * "isnp" is set to the instruction, so that fr_dfunc_idx can be set later. + * "isn_idx" is set to the index of the instruction, so that fr_dfunc_idx can + * be set later. The index is used instead of a pointer to the instruction + * because the instruction memory can be reallocated. */ int generate_FUNCREF( @@ -1386,7 +1385,7 @@ generate_FUNCREF( ufunc_T *ufunc, class_T *cl, int fi, - isn_T **isnp) + int *isn_idx) { isn_T *isn; type_T *type; @@ -1397,8 +1396,9 @@ generate_FUNCREF( RETURN_OK_IF_SKIP(cctx); if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) return FAIL; - if (isnp != NULL) - *isnp = isn; + if (isn_idx != NULL) + // save the index of the new instruction + *isn_idx = cctx->ctx_instr.ga_len - 1; has_vars = get_loop_var_info(cctx, &loopinfo); if (ufunc->uf_def_status == UF_NOT_COMPILED || has_vars || cl != NULL) @@ -1419,7 +1419,7 @@ generate_FUNCREF( extra->fre_func_name = vim_strsave(ufunc->uf_name); if (ufunc->uf_def_status != UF_NOT_COMPILED && cl == NULL) { - if (isnp == NULL && ufunc->uf_def_status == UF_TO_BE_COMPILED) + if (isn_idx == NULL && ufunc->uf_def_status == UF_TO_BE_COMPILED) // compile the function now, we need the uf_dfunc_idx value (void)compile_def_function(ufunc, FALSE, CT_NONE, NULL); isn->isn_arg.funcref.fr_dfunc_idx = ufunc->uf_dfunc_idx; @@ -2169,6 +2169,23 @@ generate_PUT(cctx_T *cctx, int regname, linenr_T lnum) return OK; } +/* + * Generate an EXEC instruction that takes a string argument. + * A copy is made of "line". + */ + int +generate_LOCKUNLOCK(cctx_T *cctx, char_u *line, int is_arg) +{ + isn_T *isn; + + RETURN_OK_IF_SKIP(cctx); + if ((isn = generate_instr(cctx, ISN_LOCKUNLOCK)) == NULL) + return FAIL; + isn->isn_arg.lockunlock.string = vim_strsave(line); + isn->isn_arg.lockunlock.is_arg = is_arg; + return OK; +} + /* * Generate an EXEC instruction that takes a string argument. * A copy is made of "line". diff --git a/src/vim9type.c b/src/vim9type.c index 6ca4b292e6..4b8064df1b 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -759,6 +759,8 @@ type_mismatch_where(type_T *expected, type_T *actual, where_T where) where.wt_func_name, typename1, typename2); break; case WT_METHOD: + case WT_METHOD_ARG: + case WT_METHOD_RETURN: semsg(_(e_method_str_type_mismatch_expected_str_but_got_str), where.wt_func_name, typename1, typename2); break; @@ -869,8 +871,15 @@ check_type_maybe( { if (actual->tt_member != NULL && actual->tt_member != &t_unknown) + { + where_T func_where = where; + + if (where.wt_kind == WT_METHOD) + func_where.wt_kind = WT_METHOD_RETURN; ret = check_type_maybe(expected->tt_member, - actual->tt_member, FALSE, where); + actual->tt_member, FALSE, + func_where); + } else ret = MAYBE; } @@ -887,14 +896,20 @@ check_type_maybe( for (i = 0; i < expected->tt_argcount && i < actual->tt_argcount; ++i) + { + where_T func_where = where; + if (where.wt_kind == WT_METHOD) + func_where.wt_kind = WT_METHOD_ARG; + // Allow for using "any" argument type, lambda's have them. if (actual->tt_args[i] != &t_any && check_type( expected->tt_args[i], actual->tt_args[i], FALSE, - where) == FAIL) + func_where) == FAIL) { ret = FAIL; break; } + } } if (ret == OK && expected->tt_argcount >= 0 && actual->tt_argcount == -1) @@ -910,7 +925,10 @@ check_type_maybe( if (actual->tt_class == NULL) return OK; // A null object matches - if (class_instance_of(actual->tt_class, expected->tt_class) == FALSE) + // For object method arguments, do a contra-variance type check in + // an extended class. For all others, do a co-variance type check. + if (class_instance_of(actual->tt_class, expected->tt_class, + where.wt_kind != WT_METHOD_ARG) == FALSE) ret = FAIL; }