diff --git a/runtime/autoload/dist/ft.vim b/runtime/autoload/dist/ft.vim index 3bf552a1a5..05a92bc224 100644 --- a/runtime/autoload/dist/ft.vim +++ b/runtime/autoload/dist/ft.vim @@ -769,6 +769,28 @@ export def SQL() endif enddef +# This function checks the first 25 lines of file extension "sc" to resolve +# detection between scala and SuperCollider +export def FTsc() + for lnum in range(1, min([line("$"), 25])) + if getline(lnum) =~# '[A-Za-z0-9]*\s:\s[A-Za-z0-9]\|var\s<\|classvar\s<\|\^this.*\||\w*|\|+\s\w*\s{\|\*ar\s' + setf supercollider + return + endif + endfor + setf scala +enddef + +# This function checks the first line of file extension "scd" to resolve +# detection between scdoc and SuperCollider +export def FTscd() + if getline(1) =~# '\%^\S\+(\d[0-9A-Za-z]*)\%(\s\+\"[^"]*\"\%(\s\+\"[^"]*\"\)\=\)\=$' + setf scdoc + else + setf supercollider + endif +enddef + # If the file has an extension of 't' and is in a directory 't' or 'xt' then # it is almost certainly a Perl test file. # If the first line starts with '#' and contains 'perl' it's probably a Perl @@ -797,7 +819,9 @@ export def FTperl(): number enddef export def FTsys() - if IsRapid() + if exists("g:filetype_sys") + exe "setf " .. g:filetype_sys + elseif IsRapid() setf rapid else setf bat @@ -965,20 +989,23 @@ export def FTtf() setf tf enddef +var ft_krl_header = '\&\w+' # Determine if a *.src file is Kuka Robot Language export def FTsrc() + var ft_krl_def_or_deffct = '%(global\s+)?def%(fct)?>' if exists("g:filetype_src") exe "setf " .. g:filetype_src - elseif getline(nextnonblank(1)) =~? '^\s*\%(&\w\+\|\%(global\s\+\)\?def\>\)' + elseif getline(nextnonblank(1)) =~? '\v^\s*%(' .. ft_krl_header .. '|' .. ft_krl_def_or_deffct .. ')' setf krl endif enddef # Determine if a *.dat file is Kuka Robot Language export def FTdat() + var ft_krl_defdat = 'defdat>' if exists("g:filetype_dat") exe "setf " .. g:filetype_dat - elseif getline(nextnonblank(1)) =~? '^\s*\%(&\w\+\|defdat\>\)' + elseif getline(nextnonblank(1)) =~? '\v^\s*%(' .. ft_krl_header .. '|' .. ft_krl_defdat .. ')' setf krl endif enddef diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index f6a791d9fa..e99a81302a 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -5581,7 +5581,7 @@ matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()* If {list} is a list of dictionaries, then the optional {dict} argument supports the following additional items: - key key of the item which is fuzzy matched against + key Key of the item which is fuzzy matched against {str}. The value of this item should be a string. text_cb |Funcref| that will be called for every item @@ -5589,6 +5589,8 @@ matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()* This should accept a dictionary item as the argument and return the text for that item to use for fuzzy matching. + limit Maximum number of matches in {list} to be + returned. Zero means no limit. {str} is treated as a literal string and regular expression matching is NOT supported. The maximum supported {str} length @@ -5601,6 +5603,9 @@ matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()* empty list is returned. If length of {str} is greater than 256, then returns an empty list. + When {limit} is given, matchfuzzy() will find up to this + number of matches in {list} and return them in sorted order. + Refer to |fuzzy-matching| for more information about fuzzy matching strings. diff --git a/runtime/doc/channel.txt b/runtime/doc/channel.txt index 01756f1458..ae90430509 100644 --- a/runtime/doc/channel.txt +++ b/runtime/doc/channel.txt @@ -25,6 +25,7 @@ The Netbeans interface also uses a channel. |netbeans| 12. Job options |job-options| 13. Controlling a job |job-control| 14. Using a prompt buffer |prompt-buffer| +15. Language Server Protocol |language-server-protocol| {only when compiled with the |+channel| feature for channel stuff} You can check this with: `has('channel')` @@ -424,6 +425,7 @@ To send a message, without expecting a response: > The process can send back a response, the channel handler will be called with it. + *channel-onetime-callback* To send a message and letting the response handled by a specific function, asynchronously: > call ch_sendraw(channel, {string}, {'callback': 'MyHandler'}) @@ -528,7 +530,8 @@ ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()* ch_evalexpr() waits for a response and returns the decoded expression. When there is an error or timeout it returns an - empty string. + empty |String| or, when using the "lsp" channel mode, returns an + empty |Dict|. Note that while waiting for the response, Vim handles other messages. You need to make sure this doesn't cause trouble. @@ -696,6 +699,16 @@ ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()* {handle} can be a Channel or a Job that has a Channel. When using the "lsp" channel mode, {expr} must be a |Dict|. + If the channel mode is "lsp", then returns a Dict. Otherwise + returns an empty String. If the "callback" item is present in + {options}, then the returned Dict contains the ID of the + request message. The ID can be used to send a cancellation + request to the LSP server (if needed). Returns an empty Dict + on error. + + If a response message is not expected for {expr}, then don't + specify the "callback" item in {options}. + Can also be used as a |method|: > GetChannel()->ch_sendexpr(expr) @@ -1383,7 +1396,7 @@ The same in |Vim9| script: > startinsert ============================================================================== -14. Language Server Protocol *language-server-protocol* +15. Language Server Protocol *language-server-protocol* The language server protocol specification is available at: @@ -1394,11 +1407,19 @@ payload encoded in JSON-RPC format. This is described in: https://www.jsonrpc.org/specification -For messages received on a channel with mode set to "lsp", Vim will process -the HTTP header and decode the payload into a Vim |Dict| type and call the -channel callback or the specified callback function. When sending messages on -a channel using |ch_evalexpr()| or |ch_sendexpr()|, Vim will add the HTTP -header and encode the Vim expression into JSON-RPC. +To encode and send a LSP request/notification message in a Vim |Dict| into a +LSP JSON-RPC message and to receive and decode a LSP JSON-RPC +response/notification message into a Vim |Dict|, connect to the LSP server +with the |channel-mode| set to "lsp". + +For messages received on a channel with |channel-mode| set to "lsp", Vim will +process the HTTP header and decode the JSON-RPC payload into a Vim |Dict| type +and call the |channel-callback| function or the specified +|channel-onetime-callback| function. When sending messages on a channel using +the |ch_evalexpr()| or |ch_sendexpr()| functions, Vim will add the HTTP header +and encode the Vim expression into JSON. Refer to |json_encode()| and +|json_decode()| for more information about how Vim encodes and decodes the +builtin types into JSON. To open a channel using the 'lsp' mode, set the 'mode' item in the |ch_open()| {options} argument to 'lsp'. Example: > @@ -1408,37 +1429,73 @@ To open a channel using the 'lsp' mode, set the 'mode' item in the |ch_open()| To open a channel using the 'lsp' mode with a job, set the 'in_mode' and 'out_mode' items in the |job_start()| {options} argument to 'lsp'. Example: > - let job = job_start(...., #{in_mode: 'lsp', out_mode: 'lsp'}) + let cmd = ['clangd', '--background-index', '--clang-tidy'] + let opts = {} + let opts.in_mode = 'lsp' + let opts.out_mode = 'lsp' + let opts.out_cb = function('LspOutCallback') + let opts.err_cb = function('LspErrCallback') + let opts.exit_cb = function('LspExitCallback') + let job = job_start(cmd, opts) -To synchronously send a JSON-RPC request to the server, use the |ch_evalexpr()| -function. This function will return the response from the server. You can use +To synchronously send a JSON-RPC request to the server, use the +|ch_evalexpr()| function. This function will wait and return the decoded +response message from the server. You can use either the |channel-timeout| or the 'timeout' field in the {options} argument to control the response wait -time. Example: > +time. If the request times out, then an empty |Dict| is returned. Example: > let req = {} let req.method = 'textDocument/definition' let req.params = {} let req.params.textDocument = #{uri: 'a.c'} let req.params.position = #{line: 10, character: 3} - let resp = ch_evalexpr(ch, req, #{timeout: 100}) + let defs = ch_evalexpr(ch, req, #{timeout: 100}) + if defs->empty() + ... + endif Note that in the request message the 'id' field should not be specified. If it is specified, then Vim will overwrite the value with an internally generated identifier. Vim currently supports only a number type for the 'id' field. +The callback function will be invoked for both a successful and a failed RPC +request. To send a JSON-RPC request to the server and asynchronously process the -response, use the |ch_sendexpr()| function and supply a callback function. -Example: > +response, use the |ch_sendexpr()| function and supply a callback function. If +the "id" field is present in the request message, then Vim will overwrite it +with an internally generated number. This function returns a Dict with the +identifier used for the message. This can be used to send cancellation +request to the LSP server (if needed). Example: > let req = {} let req.method = 'textDocument/hover' + let req.id = 200 let req.params = {} let req.params.textDocument = #{uri: 'a.c'} let req.params.position = #{line: 10, character: 3} - let resp = ch_sendexpr(ch, req, #{callback: 'MyFn'}) + let resp = ch_sendexpr(ch, req, #{callback: 'HoverFunc'}) + +To cancel an outstanding asynchronous LSP request sent to the server using the +|ch_sendexpr()| function, send a cancelation message to the server using the +|ch_sendexpr()| function with the ID returned by the |ch_sendexpr()| function +for the request. Example: > + + " send a completion request + let req = {} + let req.method = 'textDocument/completion' + let req.params = {} + let req.params.textDocument = #{uri: 'a.c'} + let req.params.position = #{line: 10, character: 3} + let reqstatus = ch_sendexpr(ch, req, #{callback: 'LspComplete'}) + " send a cancellation notification + let notif = {} + let notif.method = '$/cancelRequest' + let notif.id = reqstatus.id + call ch_sendexpr(ch, notif) To send a JSON-RPC notification message to the server, use the |ch_sendexpr()| -function. Example: > +function. As the server will not send a response message to the notification, +don't specify the "callback" item. Example: > call ch_sendexpr(ch, #{method: 'initialized'}) @@ -1454,4 +1511,68 @@ from the server request message. Example: > The JSON-RPC notification messages from the server are delivered through the |channel-callback| function. +Depending on the use case, you can use the ch_evalexpr(), ch_sendexpr() and +ch_sendraw() functions on the same channel. + +A LSP request message has the following format (expressed as a Vim Dict). The +"params" field is optional: > + + { + "jsonrpc": "2.0", + "id": , + "method": , + "params": + } + +A LSP reponse message has the following format (expressed as a Vim Dict). The +"result" and "error" fields are optional: > + + { + "jsonrpc": "2.0", + "id": , + "result": + "error": + } + +A LSP notification message has the following format (expressed as a Vim Dict). +The "params" field is optional: > + + { + "jsonrpc": "2.0", + "method": , + "params": + } + +Depending on the use case, you can use the ch_evalexpr(), ch_sendexpr() and +ch_sendraw() functions on the same channel. + +A LSP request message has the following format (expressed as a Vim Dict). The +"params" field is optional: > + + { + "jsonrpc": "2.0", + "id": , + "method": , + "params": + } + +A LSP reponse message has the following format (expressed as a Vim Dict). The +"result" and "error" fields are optional: > + + { + "jsonrpc": "2.0", + "id": , + "result": + "error": + } + +A LSP notification message has the following format (expressed as a Vim Dict). +The "params" field is optional: > + + { + "jsonrpc": "2.0", + "method": , + "params": + } + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index b921c3db08..f538329dfe 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -155,6 +155,7 @@ variables can be used to overrule the filetype used for certain extensions: *.pp g:filetype_pp |ft-pascal-syntax| *.prg g:filetype_prg *.src g:filetype_src + *.sys g:filetype_sys *.sh g:bash_is_sh |ft-sh-syntax| *.tex g:tex_flavor |ft-tex-plugin| *.w g:filetype_w |ft-cweb-syntax| diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 055bef1b77..c9aed07f07 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1262,6 +1262,7 @@ A jump table for the options with a short description can be found at |Q_op|. separated list of items. For each item that is present, the bell will be silenced. This is most useful to specify specific events in insert mode to be silenced. + You can also make it flash by using 'visualbell'. item meaning when present ~ all All events. @@ -1287,6 +1288,7 @@ A jump table for the options with a short description can be found at |Q_op|. register Unknown register after in |Insert-mode|. shell Bell from shell output |:!|. spell Error happened on spell suggest. + term Bell from |:terminal| output. wildmode More matches in |cmdline-completion| available (depends on the 'wildmode' setting). diff --git a/runtime/doc/vim9.txt b/runtime/doc/vim9.txt index 5020bcf90b..b30e5f3d4a 100644 --- a/runtime/doc/vim9.txt +++ b/runtime/doc/vim9.txt @@ -1720,7 +1720,15 @@ line, there can be no line break: > name # Error! echo that .name # Error! -< *:import-cycle* + +To refer to a function in an imported script in a mapping, || can be +used: > + noremap ,a :call name.Function() + +When the mapping is defined "name." will be replaced with and the +script ID of the imported script. + + *:import-cycle* The `import` commands are executed when encountered. If script A imports script B, and B (directly or indirectly) imports A, this will be skipped over. At this point items in A after "import B" will not have been processed and diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 62afb375cb..7432c82801 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -206,12 +206,12 @@ au BufNewFile,BufRead *.iba,*.ibi setf ibasic au BufNewFile,BufRead *.fb setf freebasic " Batch file for MSDOS. See dist#ft#FTsys for *.sys -au BufNewFile,BufRead *.bat setf dosbatch +au BufNewFile,BufRead *.bat setf dosbatch " *.cmd is close to a Batch file, but on OS/2 Rexx files also use *.cmd. au BufNewFile,BufRead *.cmd \ if getline(1) =~ '^/\*' | setf rexx | else | setf dosbatch | endif " ABB RAPID or Batch file for MSDOS. -au BufNewFile,BufRead *.sys\c call dist#ft#FTsys() +au BufNewFile,BufRead *.sys\c call dist#ft#FTsys() " Batch file for 4DOS au BufNewFile,BufRead *.btm call dist#ft#FTbtm() @@ -1144,7 +1144,7 @@ au BufNewFile,BufRead *.mms call dist#ft#FTmms() au BufNewFile,BufRead *.mmp setf mmp " ABB Rapid, Modula-2, Modsim III or LambdaProlog -au BufNewFile,BufRead *.mod\c call dist#ft#FTmod() +au BufNewFile,BufRead *.mod\c call dist#ft#FTmod() " Modula-2 (.md removed in favor of Markdown, see dist#ft#FTmod for *.MOD) au BufNewFile,BufRead *.m2,*.DEF,*.mi setf modula2 @@ -1275,6 +1275,9 @@ au BufNewFile,BufRead *.or setf openroad " OPL au BufNewFile,BufRead *.[Oo][Pp][Ll] setf opl +" OpenSCAD +au BufNewFile,BufRead *.scad setf openscad + " Oracle config file au BufNewFile,BufRead *.ora setf ora @@ -1634,16 +1637,22 @@ au BufNewFile,BufRead *.sass setf sass au BufNewFile,BufRead *.sa setf sather " Scala -au BufNewFile,BufRead *.scala,*.sc setf scala +au BufNewFile,BufRead *.scala setf scala " SBT - Scala Build Tool au BufNewFile,BufRead *.sbt setf sbt +" SuperCollider +au BufNewFile,BufRead *.sc call dist#ft#FTsc() + +au BufNewFile,BufRead *.quark setf supercollider + +" scdoc +au BufNewFile,BufRead *.scd call dist#ft#FTscd() + " Scilab au BufNewFile,BufRead *.sci,*.sce setf scilab -" scdoc -au BufNewFile,BufRead *.scd setf scdoc " SCSS au BufNewFile,BufRead *.scss setf scss diff --git a/src/autocmd.c b/src/autocmd.c index a6791eefcf..8a00bf20aa 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -55,7 +55,7 @@ typedef struct AutoCmd char once; // "One shot": removed after execution char nested; // If autocommands nest here. char last; // last command in list - sctx_T script_ctx; // script context where defined + sctx_T script_ctx; // script context where it is defined struct AutoCmd *next; // next AutoCmd in list } AutoCmd; @@ -235,12 +235,13 @@ struct AutoPatCmd_S char_u *sfname; // sfname to match with char_u *tail; // tail of fname event_T event; // current event + sctx_T script_ctx; // script context where it is defined int arg_bufnr; // Initially equal to , set to zero when // buf is deleted. - AutoPatCmd *next; // chain of active apc-s for auto-invalidation + AutoPatCmd_T *next; // chain of active apc-s for auto-invalidation }; -static AutoPatCmd *active_apc_list = NULL; // stack of active autocommands +static AutoPatCmd_T *active_apc_list = NULL; // stack of active autocommands // Macro to loop over all the patterns for an autocmd event #define FOR_ALL_AUTOCMD_PATTERNS(event, ap) \ @@ -265,7 +266,7 @@ static char_u *event_nr2name(event_T event); static int au_get_grouparg(char_u **argp); static int do_autocmd_event(event_T event, char_u *pat, int once, int nested, char_u *cmd, int forceit, int group, int flags); static int apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap); -static void auto_next_pat(AutoPatCmd *apc, int stop_at_last); +static void auto_next_pat(AutoPatCmd_T *apc, int stop_at_last); static int au_find_group(char_u *name); static event_T last_event; @@ -454,9 +455,9 @@ au_cleanup(void) void aubuflocal_remove(buf_T *buf) { - AutoPat *ap; - event_T event; - AutoPatCmd *apc; + AutoPat *ap; + event_T event; + AutoPatCmd_T *apc; // invalidate currently executing autocommands for (apc = active_apc_list; apc; apc = apc->next) @@ -1915,7 +1916,7 @@ apply_autocmds_group( int save_autocmd_busy; int save_autocmd_nested; static int nesting = 0; - AutoPatCmd patcmd; + AutoPatCmd_T patcmd; AutoPat *ap; sctx_T save_current_sctx; #ifdef FEAT_EVAL @@ -2174,15 +2175,14 @@ apply_autocmds_group( tail = gettail(fname); // Find first autocommand that matches + CLEAR_FIELD(patcmd); patcmd.curpat = first_autopat[(int)event]; - patcmd.nextcmd = NULL; patcmd.group = group; patcmd.fname = fname; patcmd.sfname = sfname; patcmd.tail = tail; patcmd.event = event; patcmd.arg_bufnr = autocmd_bufnr; - patcmd.next = NULL; auto_next_pat(&patcmd, FALSE); // found one, start executing the autocommands @@ -2364,16 +2364,21 @@ is_autocmd_blocked(void) */ static void auto_next_pat( - AutoPatCmd *apc, + AutoPatCmd_T *apc, int stop_at_last) // stop when 'last' flag is set { AutoPat *ap; AutoCmd *cp; char_u *name; char *s; - char_u **sourcing_namep = &SOURCING_NAME; + estack_T *entry; + char_u *namep; - VIM_CLEAR(*sourcing_namep); + entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1; + + // Clear the exestack entry for this ETYPE_AUCMD entry. + VIM_CLEAR(entry->es_name); + entry->es_info.aucmd = NULL; for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next) { @@ -2393,20 +2398,22 @@ auto_next_pat( { name = event_nr2name(apc->event); s = _("%s Autocommands for \"%s\""); - *sourcing_namep = alloc(STRLEN(s) - + STRLEN(name) + ap->patlen + 1); - if (*sourcing_namep != NULL) + namep = alloc(STRLEN(s) + STRLEN(name) + ap->patlen + 1); + if (namep != NULL) { - sprintf((char *)*sourcing_namep, s, - (char *)name, (char *)ap->pat); + sprintf((char *)namep, s, (char *)name, (char *)ap->pat); if (p_verbose >= 8) { verbose_enter(); - smsg(_("Executing %s"), *sourcing_namep); + smsg(_("Executing %s"), namep); verbose_leave(); } } + // Update the exestack entry for this autocmd. + entry->es_name = namep; + entry->es_info.aucmd = apc; + apc->curpat = ap; apc->nextcmd = ap->cmds; // mark last command @@ -2423,6 +2430,15 @@ auto_next_pat( } } +/* + * Get the script context where autocommand "acp" is defined. + */ + sctx_T * +acp_script_ctx(AutoPatCmd_T *acp) +{ + return &acp->script_ctx; +} + /* * Get next autocommand command. * Called by do_cmdline() to get the next line for ":if". @@ -2435,7 +2451,7 @@ getnextac( int indent UNUSED, getline_opt_T options UNUSED) { - AutoPatCmd *acp = (AutoPatCmd *)cookie; + AutoPatCmd_T *acp = (AutoPatCmd_T *)cookie; char_u *retval; AutoCmd *ac; @@ -2482,6 +2498,7 @@ getnextac( au_del_cmd(ac); autocmd_nested = ac->nested; current_sctx = ac->script_ctx; + acp->script_ctx = current_sctx; if (ac->last) acp->nextcmd = NULL; else diff --git a/src/channel.c b/src/channel.c index 1cd81fc157..5d1d2e7f9c 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1202,8 +1202,9 @@ prepare_buffer(buf_T *buf) buf_copy_options(buf, BCO_ENTER); curbuf = buf; #ifdef FEAT_QUICKFIX - set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL); - set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL); + set_option_value_give_err((char_u *)"bt", + 0L, (char_u *)"nofile", OPT_LOCAL); + set_option_value_give_err((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL); #endif if (curbuf->b_ml.ml_mfp == NULL) ml_open(curbuf); @@ -4582,6 +4583,7 @@ ch_expr_common(typval_T *argvars, typval_T *rettv, int eval) ch_part_T part_read; jobopt_T opt; int timeout; + int callback_present = FALSE; // return an empty string by default rettv->v_type = VAR_STRING; @@ -4608,7 +4610,9 @@ ch_expr_common(typval_T *argvars, typval_T *rettv, int eval) { dict_T *d; dictitem_T *di; - int callback_present = FALSE; + + // return an empty dict by default + rettv_dict_alloc(rettv); if (argvars[1].v_type != VAR_DICT) { @@ -4691,6 +4695,14 @@ ch_expr_common(typval_T *argvars, typval_T *rettv, int eval) } } free_job_options(&opt); + if (ch_mode == MODE_LSP && !eval && callback_present) + { + // if ch_sendexpr() is used to send a LSP message and a callback + // function is specified, then return the generated identifier for the + // message. The user can use this to cancel the request (if needed). + if (rettv->vval.v_dict != NULL) + dict_add_number(rettv->vval.v_dict, "id", id); + } } /* diff --git a/src/crypt.c b/src/crypt.c index 86f4846368..6a852fa1f9 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -752,7 +752,7 @@ crypt_check_swapfile_curbuf(void) // encryption uses padding and MAC, that does not work very well with // swap and undo files, so disable them mf_close_file(curbuf, TRUE); // remove the swap file - set_option_value((char_u *)"swf", 0, NULL, OPT_LOCAL); + set_option_value_give_err((char_u *)"swf", 0, NULL, OPT_LOCAL); msg_scroll = TRUE; msg(_("Note: Encryption of swapfile not supported, disabling swap file")); } @@ -807,7 +807,7 @@ crypt_get_key( if (store) { - set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL); + set_option_value_give_err((char_u *)"key", 0L, p1, OPT_LOCAL); crypt_free_key(p1); p1 = curbuf->b_p_key; #ifdef FEAT_SODIUM diff --git a/src/diff.c b/src/diff.c index 00ccdb611f..df3dea0a17 100644 --- a/src/diff.c +++ b/src/diff.c @@ -1466,7 +1466,7 @@ set_diff_option(win_T *wp, int value) curwin = wp; curbuf = curwin->w_buffer; ++curbuf_lock; - set_option_value((char_u *)"diff", (long)value, NULL, OPT_LOCAL); + set_option_value_give_err((char_u *)"diff", (long)value, NULL, OPT_LOCAL); --curbuf_lock; curwin = old_curwin; curbuf = curwin->w_buffer; diff --git a/src/edit.c b/src/edit.c index 33c75810cf..de2ab095e4 100644 --- a/src/edit.c +++ b/src/edit.c @@ -4416,7 +4416,7 @@ bracketed_paste(paste_mode_T mode, int drop, garray_T *gap) if (!p_paste) // Also have the side effects of setting 'paste' to make it work much // faster. - set_option_value((char_u *)"paste", TRUE, NULL, 0); + set_option_value_give_err((char_u *)"paste", TRUE, NULL, 0); for (;;) { @@ -4491,7 +4491,7 @@ bracketed_paste(paste_mode_T mode, int drop, garray_T *gap) --no_mapping; allow_keys = save_allow_keys; if (!save_paste) - set_option_value((char_u *)"paste", FALSE, NULL, 0); + set_option_value_give_err((char_u *)"paste", FALSE, NULL, 0); return ret_char; } diff --git a/src/eval.c b/src/eval.c index 793a5263dd..cad6887751 100644 --- a/src/eval.c +++ b/src/eval.c @@ -639,7 +639,15 @@ deref_function_name( ref.v_type = VAR_UNKNOWN; if (eval7(arg, &ref, evalarg, FALSE) == FAIL) - return NULL; + { + dictitem_T *v; + + // If VarName was used it would not be found, try another way. + v = find_var_also_in_script(name, NULL, FALSE); + if (v == NULL) + return NULL; + copy_tv(&v->di_tv, &ref); + } if (*skipwhite(*arg) != NUL) { if (verbose) @@ -6801,7 +6809,7 @@ do_string_sub( // If it's still empty it was changed and restored, need to restore in // the complicated way. if (*p_cpo == NUL) - set_option_value((char_u *)"cpo", 0L, save_cpo, 0); + set_option_value_give_err((char_u *)"cpo", 0L, save_cpo, 0); free_string_option(save_cpo); } diff --git a/src/evalfunc.c b/src/evalfunc.c index 4a6a3abff9..cfacf85e47 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -1660,7 +1660,7 @@ static funcentry_T global_functions[] = {"ch_readraw", 1, 2, FEARG_1, arg2_chan_or_job_dict, ret_string, JOB_FUNC(f_ch_readraw)}, {"ch_sendexpr", 2, 3, FEARG_1, arg23_chanexpr, - ret_void, JOB_FUNC(f_ch_sendexpr)}, + ret_any, JOB_FUNC(f_ch_sendexpr)}, {"ch_sendraw", 2, 3, FEARG_1, arg23_chanraw, ret_void, JOB_FUNC(f_ch_sendraw)}, {"ch_setoptions", 2, 2, FEARG_1, arg2_chan_or_job_dict, @@ -9095,7 +9095,7 @@ theend: // If it's still empty it was changed and restored, need to restore in // the complicated way. if (*p_cpo == NUL) - set_option_value((char_u *)"cpo", 0L, save_cpo, 0); + set_option_value_give_err((char_u *)"cpo", 0L, save_cpo, 0); free_string_option(save_cpo); } @@ -9258,9 +9258,9 @@ f_setenv(typval_T *argvars, typval_T *rettv UNUSED) name = tv_get_string_buf(&argvars[0], namebuf); if (argvars[1].v_type == VAR_SPECIAL && argvars[1].vval.v_number == VVAL_NULL) - vim_unsetenv(name); + vim_unsetenv_ext(name); else - vim_setenv(name, tv_get_string_buf(&argvars[1], valbuf)); + vim_setenv_ext(name, tv_get_string_buf(&argvars[1], valbuf)); } /* diff --git a/src/evalvars.c b/src/evalvars.c index a799f106e7..58acd73438 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -1797,7 +1797,7 @@ do_unlet_var( // Environment variable, normal name or expanded name. if (*lp->ll_name == '$') - vim_unsetenv(lp->ll_name + 1); + vim_unsetenv_ext(lp->ll_name + 1); else if (do_unlet(lp->ll_name, forceit) == FAIL) ret = FAIL; *name_end = cc; @@ -4016,7 +4016,7 @@ set_option_from_tv(char_u *varname, typval_T *varp) strval = tv_get_string_buf_chk(varp, nbuf); } if (!error && strval != NULL) - set_option_value(varname, numval, strval, OPT_LOCAL); + set_option_value_give_err(varname, numval, strval, OPT_LOCAL); } /* diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 50829be70b..9ea2fd6192 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -4960,8 +4960,7 @@ ex_global(exarg_T *eap) else { delim = *cmd; // get the delimiter - if (delim) - ++cmd; // skip delimiter if there is one + ++cmd; // skip delimiter if there is one pat = cmd; // remember start of pattern cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL, NULL); if (cmd[0] == delim) // end delimiter found diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index 077e5b159a..7106fdbd60 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -636,9 +636,11 @@ ex_listdo(exarg_T *eap) // Clear 'shm' to avoid that the file message overwrites // any output from the command. p_shm_save = vim_strsave(p_shm); - set_option_value((char_u *)"shm", 0L, (char_u *)"", 0); + set_option_value_give_err((char_u *)"shm", + 0L, (char_u *)"", 0); do_argfile(eap, i); - set_option_value((char_u *)"shm", 0L, p_shm_save, 0); + set_option_value_give_err((char_u *)"shm", + 0L, p_shm_save, 0); vim_free(p_shm_save); } if (curwin->w_arg_idx != i) @@ -696,9 +698,9 @@ ex_listdo(exarg_T *eap) // Go to the next buffer. Clear 'shm' to avoid that the file // message overwrites any output from the command. p_shm_save = vim_strsave(p_shm); - set_option_value((char_u *)"shm", 0L, (char_u *)"", 0); + set_option_value_give_err((char_u *)"shm", 0L, (char_u *)"", 0); goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum); - set_option_value((char_u *)"shm", 0L, p_shm_save, 0); + set_option_value_give_err((char_u *)"shm", 0L, p_shm_save, 0); vim_free(p_shm_save); // If autocommands took us elsewhere, quit here. @@ -718,9 +720,9 @@ ex_listdo(exarg_T *eap) // Clear 'shm' to avoid that the file message overwrites // any output from the command. p_shm_save = vim_strsave(p_shm); - set_option_value((char_u *)"shm", 0L, (char_u *)"", 0); + set_option_value_give_err((char_u *)"shm", 0L, (char_u *)"", 0); ex_cnext(eap); - set_option_value((char_u *)"shm", 0L, p_shm_save, 0); + set_option_value_give_err((char_u *)"shm", 0L, p_shm_save, 0); vim_free(p_shm_save); // If jumping to the next quickfix entry fails, quit here diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 3b02dd7e58..8d746a4bb2 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -2789,7 +2789,9 @@ parse_command_modifiers( cmdmod_T *cmod, int skip_only) { + char_u *orig_cmd = eap->cmd; char_u *cmd_start = NULL; + int did_plus_cmd = FALSE; char_u *p; int starts_with_colon = FALSE; int vim9script = in_vim9script(); @@ -2825,6 +2827,7 @@ parse_command_modifiers( && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { eap->cmd = (char_u *)"+"; + did_plus_cmd = TRUE; if (!skip_only) ex_pressedreturn = TRUE; } @@ -3111,13 +3114,29 @@ parse_command_modifiers( // Since the modifiers have been parsed put the colon on top of the // space: "'<,'>mod cmd" -> "mod:'<,'>cmd // Put eap->cmd after the colon. - mch_memmove(cmd_start - 5, cmd_start, eap->cmd - cmd_start); - eap->cmd -= 5; - mch_memmove(eap->cmd - 1, ":'<,'>", 6); + if (did_plus_cmd) + { + size_t len = STRLEN(cmd_start); + + // Special case: empty command may have been changed to "+": + // "'<,'>mod" -> "mod'<,'>+ + mch_memmove(orig_cmd, cmd_start, len); + STRCPY(orig_cmd + len, "'<,'>+"); + } + else + { + mch_memmove(cmd_start - 5, cmd_start, eap->cmd - cmd_start); + eap->cmd -= 5; + mch_memmove(eap->cmd - 1, ":'<,'>", 6); + } } else - // no modifiers, move the pointer back - eap->cmd -= 5; + // No modifiers, move the pointer back. + // Special case: empty command may have been changed to "+". + if (did_plus_cmd) + eap->cmd = (char_u *)"'<,'>+"; + else + eap->cmd = orig_cmd; } return OK; @@ -9439,18 +9458,23 @@ ex_behave(exarg_T *eap) { if (STRCMP(eap->arg, "mswin") == 0) { - set_option_value((char_u *)"selection", 0L, (char_u *)"exclusive", 0); - set_option_value((char_u *)"selectmode", 0L, (char_u *)"mouse,key", 0); - set_option_value((char_u *)"mousemodel", 0L, (char_u *)"popup", 0); - set_option_value((char_u *)"keymodel", 0L, - (char_u *)"startsel,stopsel", 0); + set_option_value_give_err((char_u *)"selection", + 0L, (char_u *)"exclusive", 0); + set_option_value_give_err((char_u *)"selectmode", + 0L, (char_u *)"mouse,key", 0); + set_option_value_give_err((char_u *)"mousemodel", + 0L, (char_u *)"popup", 0); + set_option_value_give_err((char_u *)"keymodel", + 0L, (char_u *)"startsel,stopsel", 0); } else if (STRCMP(eap->arg, "xterm") == 0) { - set_option_value((char_u *)"selection", 0L, (char_u *)"inclusive", 0); - set_option_value((char_u *)"selectmode", 0L, (char_u *)"", 0); - set_option_value((char_u *)"mousemodel", 0L, (char_u *)"extend", 0); - set_option_value((char_u *)"keymodel", 0L, (char_u *)"", 0); + set_option_value_give_err((char_u *)"selection", + 0L, (char_u *)"inclusive", 0); + set_option_value_give_err((char_u *)"selectmode", 0L, (char_u *)"", 0); + set_option_value_give_err((char_u *)"mousemodel", + 0L, (char_u *)"extend", 0); + set_option_value_give_err((char_u *)"keymodel", 0L, (char_u *)"", 0); } else semsg(_(e_invalid_argument_str), eap->arg); @@ -9564,7 +9588,7 @@ ex_setfiletype(exarg_T *eap) if (STRNCMP(arg, "FALLBACK ", 9) == 0) arg += 9; - set_option_value((char_u *)"filetype", 0L, arg, OPT_LOCAL); + set_option_value_give_err((char_u *)"filetype", 0L, arg, OPT_LOCAL); if (arg != eap->arg) did_filetype = FALSE; } diff --git a/src/ex_getln.c b/src/ex_getln.c index bd8ff7920d..8c088b7fd5 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -4379,7 +4379,8 @@ open_cmdwin(void) apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf); (void)setfname(curbuf, (char_u *)_("[Command Line]"), NULL, TRUE); apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf); - set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL); + set_option_value_give_err((char_u *)"bt", + 0L, (char_u *)"nofile", OPT_LOCAL); curbuf->b_p_ma = TRUE; #ifdef FEAT_FOLDING curwin->w_p_fen = FALSE; @@ -4404,7 +4405,8 @@ open_cmdwin(void) add_map((char_u *)" ", INSERT); add_map((char_u *)" a", NORMAL); } - set_option_value((char_u *)"ft", 0L, (char_u *)"vim", OPT_LOCAL); + set_option_value_give_err((char_u *)"ft", + 0L, (char_u *)"vim", OPT_LOCAL); } --curbuf_lock; diff --git a/src/getchar.c b/src/getchar.c index 5a27e02674..7fff417711 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -2658,7 +2658,8 @@ handle_mapping( mlen - typebuf.tb_maplen); del_typebuf(mlen, 0); // remove the chars - set_option_value((char_u *)"paste", (long)!p_paste, NULL, 0); + set_option_value_give_err((char_u *)"paste", + (long)!p_paste, NULL, 0); if (!(State & INSERT)) { msg_col = 0; diff --git a/src/gui.c b/src/gui.c index 105fe87880..25c13c9028 100644 --- a/src/gui.c +++ b/src/gui.c @@ -504,7 +504,7 @@ gui_init(void) * Reset 'paste'. It's useful in the terminal, but not in the GUI. It * breaks the Paste toolbar button. */ - set_option_value((char_u *)"paste", 0L, NULL, 0); + set_option_value_give_err((char_u *)"paste", 0L, NULL, 0); // Set t_Co to the number of colors: RGB. set_color_count(256 * 256 * 256); @@ -664,7 +664,8 @@ gui_init(void) * Set up the fonts. First use a font specified with "-fn" or "-font". */ if (font_argument != NULL) - set_option_value((char_u *)"gfn", 0L, (char_u *)font_argument, 0); + set_option_value_give_err((char_u *)"gfn", + 0L, (char_u *)font_argument, 0); if ( #ifdef FEAT_XFONTSET (*p_guifontset == NUL @@ -4854,7 +4855,7 @@ init_gui_options(void) // background color, unless the user has set it already. if (!option_was_set((char_u *)"bg") && STRCMP(p_bg, gui_bg_default()) != 0) { - set_option_value((char_u *)"bg", 0L, gui_bg_default(), 0); + set_option_value_give_err((char_u *)"bg", 0L, gui_bg_default(), 0); highlight_changed(); } } diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index acd36d3adf..d756f55294 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -3462,7 +3462,8 @@ gui_mch_init(void) * did_set_string_option() in option.c prohibits changing 'termencoding' * to something else than UTF-8 if the GUI is in use. */ - set_option_value((char_u *)"termencoding", 0L, (char_u *)"utf-8", 0); + set_option_value_give_err((char_u *)"termencoding", + 0L, (char_u *)"utf-8", 0); #ifdef FEAT_TOOLBAR gui_gtk_register_stock_icons(); diff --git a/src/gui_w32.c b/src/gui_w32.c index d1cc06d5b9..35cb2d26a2 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -1696,7 +1696,7 @@ gui_mch_haskey(char_u *name) void gui_mch_beep(void) { - MessageBeep(MB_OK); + MessageBeep((UINT)-1); } /* * Invert a rectangle from row r, column c, for nr rows and nc columns. diff --git a/src/help.c b/src/help.c index 48178fda3b..e58068020c 100644 --- a/src/help.c +++ b/src/help.c @@ -708,7 +708,8 @@ fix_help_buffer(void) if (STRCMP(curbuf->b_p_ft, "help") != 0) { ++curbuf_lock; - set_option_value((char_u *)"ft", 0L, (char_u *)"help", OPT_LOCAL); + set_option_value_give_err((char_u *)"ft", + 0L, (char_u *)"help", OPT_LOCAL); --curbuf_lock; } diff --git a/src/highlight.c b/src/highlight.c index ec5147a2b4..97f1ea03a5 100644 --- a/src/highlight.c +++ b/src/highlight.c @@ -974,8 +974,8 @@ highlight_set_ctermbg(int idx, int color, int is_normal_group) && dark != (*p_bg == 'd') && !option_was_set((char_u *)"bg")) { - set_option_value((char_u *)"bg", 0L, - (char_u *)(dark ? "dark" : "light"), 0); + set_option_value_give_err((char_u *)"bg", + 0L, (char_u *)(dark ? "dark" : "light"), 0); reset_option_was_set((char_u *)"bg"); } } diff --git a/src/if_tcl.c b/src/if_tcl.c index f66bfd3860..8a6af8db6b 100644 --- a/src/if_tcl.c +++ b/src/if_tcl.c @@ -1359,7 +1359,7 @@ tclsetoption( sval = (char_u *)Tcl_GetStringFromObj(objv[objn], NULL); if (err == TCL_OK) { - set_option_value(option, lval, sval, OPT_LOCAL); + set_option_value_give_err(option, lval, sval, OPT_LOCAL); err = vimerror(interp); } } diff --git a/src/main.c b/src/main.c index 2704bb01a5..6ba5647a9e 100644 --- a/src/main.c +++ b/src/main.c @@ -2112,7 +2112,8 @@ command_line_scan(mparm_T *parmp) use_gvimrc = (char_u *)"NONE"; #endif parmp->clean = TRUE; - set_option_value((char_u *)"vif", 0L, (char_u *)"NONE", 0); + set_option_value_give_err((char_u *)"vif", + 0L, (char_u *)"NONE", 0); } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) { @@ -2200,7 +2201,7 @@ command_line_scan(mparm_T *parmp) case 'A': // "-A" start in Arabic mode #ifdef FEAT_ARABIC - set_option_value((char_u *)"arabic", 1L, NULL, 0); + set_option_value_give_err((char_u *)"arabic", 1L, NULL, 0); #else mch_errmsg(_(e_arabic_cannot_be_used_not_enabled_at_compile_time)); mch_exit(2); @@ -2256,7 +2257,7 @@ command_line_scan(mparm_T *parmp) case 'H': // "-H" start in Hebrew mode: rl + hkmap set #ifdef FEAT_RIGHTLEFT p_hkmap = TRUE; - set_option_value((char_u *)"rl", 1L, NULL, 0); + set_option_value_give_err((char_u *)"rl", 1L, NULL, 0); #else mch_errmsg(_(e_hebrew_cannot_be_used_not_enabled_at_compile_time)); mch_exit(2); @@ -2265,7 +2266,7 @@ command_line_scan(mparm_T *parmp) case 'l': // "-l" lisp mode, 'lisp' and 'showmatch' on #ifdef FEAT_LISP - set_option_value((char_u *)"lisp", 1L, NULL, 0); + set_option_value_give_err((char_u *)"lisp", 1L, NULL, 0); p_sm = TRUE; #endif break; @@ -2401,8 +2402,8 @@ command_line_scan(mparm_T *parmp) p_verbose = get_number_arg((char_u *)argv[0], &argv_idx, 10); if (argv[0][argv_idx] != NUL) { - set_option_value((char_u *)"verbosefile", 0L, - (char_u *)argv[0] + argv_idx, 0); + set_option_value_give_err((char_u *)"verbosefile", + 0L, (char_u *)argv[0] + argv_idx, 0); argv_idx = (int)STRLEN(argv[0]); } break; @@ -2419,7 +2420,7 @@ command_line_scan(mparm_T *parmp) if (vim_isdigit(((char_u *)argv[0])[argv_idx])) { n = get_number_arg((char_u *)argv[0], &argv_idx, 10); - set_option_value((char_u *)"window", n, NULL, 0); + set_option_value_give_err((char_u *)"window", n, NULL, 0); break; } want_argument = TRUE; @@ -2548,7 +2549,8 @@ command_line_scan(mparm_T *parmp) #endif case 'i': // "-i {viminfo}" use for viminfo - set_option_value((char_u *)"vif", 0L, (char_u *)argv[0], 0); + set_option_value_give_err((char_u *)"vif", + 0L, (char_u *)argv[0], 0); break; case 's': // "-s {scriptin}" read from script file @@ -2607,7 +2609,8 @@ scripterror: { argv_idx = 0; n = get_number_arg((char_u *)argv[0], &argv_idx, 10); - set_option_value((char_u *)"window", n, NULL, 0); + set_option_value_give_err((char_u *)"window", + n, NULL, 0); argv_idx = -1; break; } @@ -3052,7 +3055,8 @@ edit_buffers( p_shm_save = vim_strsave(p_shm); vim_snprintf(buf, 100, "F%s", p_shm); - set_option_value((char_u *)"shm", 0L, (char_u *)buf, 0); + set_option_value_give_err((char_u *)"shm", + 0L, (char_u *)buf, 0); } } else @@ -3101,7 +3105,7 @@ edit_buffers( if (p_shm_save != NULL) { - set_option_value((char_u *)"shm", 0L, p_shm_save, 0); + set_option_value_give_err((char_u *)"shm", 0L, p_shm_save, 0); vim_free(p_shm_save); } diff --git a/src/match.c b/src/match.c index d74d8d73ff..9edba8d999 100644 --- a/src/match.c +++ b/src/match.c @@ -396,6 +396,7 @@ next_search_hl_pos( shl->rm.endpos[0].lnum = 0; shl->rm.endpos[0].col = end; shl->is_addpos = TRUE; + shl->has_cursor = FALSE; posmatch->cur = found + 1; return 1; } @@ -655,6 +656,7 @@ prepare_search_hl_line( shl->lines = 0; shl->attr_cur = 0; shl->is_addpos = FALSE; + shl->has_cursor = FALSE; if (cur != NULL) cur->pos.cur = 0; next_search_hl(wp, search_hl, shl, lnum, mincol, @@ -679,6 +681,17 @@ prepare_search_hl_line( shl->lines = shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum; else shl->lines = 1; + + // check if the cursor is in the match before changing the columns + if (wp->w_cursor.lnum >= shl->lnum + && wp->w_cursor.lnum + <= shl->lnum + shl->rm.endpos[0].lnum + && (wp->w_cursor.lnum > shl->lnum + || wp->w_cursor.col >= shl->rm.startpos[0].col) + && (wp->w_cursor.lnum < shl->lnum + shl->lines + || wp->w_cursor.col < shl->rm.endpos[0].col)) + shl->has_cursor = TRUE; + // Highlight one character for an empty match. if (shl->startcol == shl->endcol) { @@ -775,14 +788,8 @@ update_search_hl( # endif // Highlight the match were the cursor is using the CurSearch // group. - if (shl == search_hl - && wp->w_cursor.lnum >= shl->lnum - && wp->w_cursor.lnum < shl->lnum + shl->lines - && wp->w_cursor.col >= shl->startcol - && wp->w_cursor.col < shl->endcol) - { + if (shl == search_hl && shl->has_cursor) shl->attr_cur = HL_ATTR(HLF_LC); - } } else if (col == shl->endcol) diff --git a/src/memline.c b/src/memline.c index f38e029bd1..e098aef552 100644 --- a/src/memline.c +++ b/src/memline.c @@ -1482,7 +1482,7 @@ ml_recover(int checkext) set_fileformat(b0_ff - 1, OPT_LOCAL); if (b0_fenc != NULL) { - set_option_value((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL); + set_option_value_give_err((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL); vim_free(b0_fenc); } unchanged(curbuf, TRUE, TRUE); @@ -1759,7 +1759,7 @@ ml_recover(int checkext) if (*buf->b_p_key != NUL && STRCMP(curbuf->b_p_key, buf->b_p_key) != 0) { msg_puts(_("Using crypt key from swap file for the text file.\n")); - set_option_value((char_u *)"key", 0L, buf->b_p_key, OPT_LOCAL); + set_option_value_give_err((char_u *)"key", 0L, buf->b_p_key, OPT_LOCAL); } #endif redraw_curbuf_later(NOT_VALID); diff --git a/src/message_test.c b/src/message_test.c index 882b591e43..940c1cc0b0 100644 --- a/src/message_test.c +++ b/src/message_test.c @@ -314,13 +314,13 @@ main(int argc, char **argv) params.argv = argv; common_init(¶ms); - set_option_value((char_u *)"encoding", 0, (char_u *)"utf-8", 0); + set_option_value_give_err((char_u *)"encoding", 0, (char_u *)"utf-8", 0); init_chartab(); test_trunc_string(); test_trunc_string_mbyte(); test_vim_snprintf(); - set_option_value((char_u *)"encoding", 0, (char_u *)"latin1", 0); + set_option_value_give_err((char_u *)"encoding", 0, (char_u *)"latin1", 0); init_chartab(); test_trunc_string(); test_vim_snprintf(); diff --git a/src/misc1.c b/src/misc1.c index 2a48ff922d..dcc1e01404 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -1102,11 +1102,10 @@ beep_flush(void) } /* - * Give a warning for an error. + * Give a warning for an error. "val" is one of the BO_ values, e.g., BO_OPER. */ void -vim_beep( - unsigned val) // one of the BO_ values, e.g., BO_OPER +vim_beep(unsigned val) { #ifdef FEAT_EVAL called_vim_beep = TRUE; @@ -1584,7 +1583,7 @@ expand_env_esc( c = (int)STRLEN(var); // if var[] ends in a path separator and tail[] starts // with it, skip a character - if (*var != NUL && after_pathsep(dst, dst + c) + if (after_pathsep(dst, dst + c) #if defined(BACKSLASH_IN_FILENAME) || defined(AMIGA) && dst[-1] != ':' #endif @@ -1907,7 +1906,6 @@ vim_getenv(char_u *name, int *mustfree) return p; } -#if defined(FEAT_EVAL) || defined(PROTO) void vim_unsetenv(char_u *var) { @@ -1918,7 +1916,22 @@ vim_unsetenv(char_u *var) #endif } +/* + * Removes environment variable "name" and take care of side effects. + */ + void +vim_unsetenv_ext(char_u *var) +{ + vim_unsetenv(var); + // "homedir" is not cleared, keep using the old value until $HOME is set. + if (STRICMP(var, "VIM") == 0) + didset_vim = FALSE; + else if (STRICMP(var, "VIMRUNTIME") == 0) + didset_vimruntime = FALSE; +} + +#if defined(FEAT_EVAL) || defined(PROTO) /* * Set environment variable "name" and take care of side effects. */ @@ -1930,8 +1943,7 @@ vim_setenv_ext(char_u *name, char_u *val) init_homedir(); else if (didset_vim && STRICMP(name, "VIM") == 0) didset_vim = FALSE; - else if (didset_vimruntime - && STRICMP(name, "VIMRUNTIME") == 0) + else if (didset_vimruntime && STRICMP(name, "VIMRUNTIME") == 0) didset_vimruntime = FALSE; } #endif diff --git a/src/option.c b/src/option.c index 9e5ffd4c36..083ef312d8 100644 --- a/src/option.c +++ b/src/option.c @@ -334,7 +334,7 @@ set_init_1(int clean_arg) #ifdef FEAT_GUI if (found_reverse_arg) - set_option_value((char_u *)"bg", 0L, (char_u *)"dark", 0); + set_option_value_give_err((char_u *)"bg", 0L, (char_u *)"dark", 0); #endif curbuf->b_p_initialized = TRUE; @@ -392,7 +392,7 @@ set_init_1(int clean_arg) // NOTE: mlterm's author is being asked to 'set' a variable // instead of an environment variable due to inheritance. if (mch_getenv((char_u *)"MLTERM") != NULL) - set_option_value((char_u *)"tbidi", 1L, NULL, 0); + set_option_value_give_err((char_u *)"tbidi", 1L, NULL, 0); #endif didset_options2(); @@ -1424,7 +1424,7 @@ do_set( && vim_strchr((char_u *)"!&<", *arg) != NULL) errmsg = e_no_white_space_allowed_between_option_and; else - errmsg = N_(e_unknown_option); + errmsg = e_unknown_option; goto skip; } @@ -1437,7 +1437,7 @@ do_set( if (vim_strchr((char_u *)"=:!&<", nextchar) == NULL && (!(options[opt_idx].flags & P_BOOL) || nextchar == '?')) - errmsg = N_(e_option_not_supported); + errmsg = e_option_not_supported; goto skip; } @@ -1475,12 +1475,12 @@ do_set( { if (flags & (P_SECURE | P_NO_ML)) { - errmsg = N_(e_not_allowed_in_modeline); + errmsg = e_not_allowed_in_modeline; goto skip; } if ((flags & P_MLE) && !p_mle) { - errmsg = N_(e_not_allowed_in_modeline_when_modelineexpr_is_off); + errmsg = e_not_allowed_in_modeline_when_modelineexpr_is_off; goto skip; } #ifdef FEAT_DIFF @@ -1576,7 +1576,7 @@ do_set( p = find_termcode(key_name); if (p == NULL) { - errmsg = N_(e_key_code_not_set); + errmsg = e_key_code_not_set; goto skip; } else @@ -1700,13 +1700,13 @@ do_set( if (i == 0 || (arg[i] != NUL && !VIM_ISWHITE(arg[i]))) { - errmsg = N_(e_number_required_after_equal); + errmsg = e_number_required_after_equal; goto skip; } } else { - errmsg = N_(e_number_required_after_equal); + errmsg = e_number_required_after_equal; goto skip; } @@ -2158,7 +2158,7 @@ do_set( if (nextchar == '&') { if (add_termcap_entry(key_name, TRUE) == FAIL) - errmsg = N_(e_not_found_in_termcap); + errmsg = e_not_found_in_termcap; } else { @@ -2746,6 +2746,7 @@ set_bool_option( #if defined(FEAT_EVAL) int old_global_value = 0; #endif + char *errmsg = NULL; // Disallow changing some options from secure mode if ((secure @@ -2860,7 +2861,7 @@ set_bool_option( && curbuf->b_term != NULL && !term_is_finished(curbuf)))) { curbuf->b_p_ma = FALSE; - return N_(e_cannot_make_terminal_with_running_job_modifiable); + return e_cannot_make_terminal_with_running_job_modifiable; } # endif redraw_titles(); @@ -2988,7 +2989,7 @@ set_bool_option( if (win->w_p_pvw && win != curwin) { curwin->w_p_pvw = FALSE; - return N_(e_preview_window_already_exists); + return e_preview_window_already_exists; } } } @@ -3192,12 +3193,7 @@ set_bool_option( else if ((int *)varp == &curwin->w_p_spell) { if (curwin->w_p_spell) - { - char *errmsg = did_set_spelllang(curwin); - - if (errmsg != NULL) - emsg(_(errmsg)); - } + errmsg = did_set_spelllang(curwin); } #endif @@ -3244,8 +3240,8 @@ set_bool_option( # ifdef FEAT_KEYMAP // Force-set the necessary keymap for arabic - set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic", - OPT_LOCAL); + errmsg = set_option_value((char_u *)"keymap", + 0L, (char_u *)"arabic", OPT_LOCAL); # endif } else @@ -3310,7 +3306,7 @@ set_bool_option( !has_vtp_working()) { p_tgc = 0; - return N_(e_24_bit_colors_are_not_supported_on_this_environment); + return e_24_bit_colors_are_not_supported_on_this_environment; } if (is_term_win32()) swap_tcap(); @@ -3358,7 +3354,7 @@ set_bool_option( if ((opt_flags & OPT_NO_REDRAW) == 0) check_redraw(options[opt_idx].flags); - return NULL; + return errmsg; } /* @@ -4437,7 +4433,7 @@ is_crypt_key_option(int opt_idx) * Set the value of option "name". * Use "string" for string options, use "number" for other options. * - * Returns NULL on success or error message on error. + * Returns NULL on success or an untranslated error message on error. */ char * set_option_value( @@ -4526,6 +4522,22 @@ set_option_value( return NULL; } +/* + * Call set_option_value() and when an error is returned report it. + */ + void +set_option_value_give_err( + char_u *name, + long number, + char_u *string, + int opt_flags) // OPT_LOCAL or 0 (both) +{ + char *errmsg = set_option_value(name, number, string, opt_flags); + + if (errmsg != NULL) + emsg(_(errmsg)); +} + /* * Get the terminal code for a terminal option. * Returns NULL when not found. diff --git a/src/option.h b/src/option.h index 70596403a4..c860b519a5 100644 --- a/src/option.h +++ b/src/option.h @@ -451,7 +451,8 @@ EXTERN unsigned bo_flags; #define BO_REG 0x8000 #define BO_SH 0x10000 #define BO_SPELL 0x20000 -#define BO_WILD 0x40000 +#define BO_TERM 0x40000 +#define BO_WILD 0x80000 #ifdef FEAT_WILDIGN EXTERN char_u *p_bsk; // 'backupskip' diff --git a/src/optionstr.c b/src/optionstr.c index 6688eb51b5..3e3e25d111 100644 --- a/src/optionstr.c +++ b/src/optionstr.c @@ -20,7 +20,7 @@ static char *(p_bo_values[]) = {"all", "backspace", "cursor", "complete", "copy", "ctrlg", "error", "esc", "ex", "hangul", "insertmode", "lang", "mess", "showmatch", "operator", "register", "shell", - "spell", "wildmode", NULL}; + "spell", "term", "wildmode", NULL}; 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_CRYPT @@ -484,7 +484,7 @@ set_string_option_direct_in_buf( /* * Set a string option to a new value, and handle the effects. * - * Returns NULL on success or error message on error. + * Returns NULL on success or an untranslated error message on error. */ char * set_string_option( @@ -503,7 +503,7 @@ set_string_option( char_u *saved_oldval_g = NULL; char_u *saved_newval = NULL; #endif - char *r = NULL; + char *errmsg = NULL; int value_checked = FALSE; if (is_hidden_option(opt_idx)) // don't set hidden option @@ -542,13 +542,13 @@ set_string_option( saved_newval = vim_strsave(s); } #endif - if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL, + if ((errmsg = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL, opt_flags, &value_checked)) == NULL) did_set_option(opt_idx, opt_flags, TRUE, value_checked); #if defined(FEAT_EVAL) // call autocommand after handling side effects - if (r == NULL) + if (errmsg == NULL) trigger_optionsset_string(opt_idx, opt_flags, saved_oldval, saved_oldval_l, saved_oldval_g, saved_newval); @@ -558,7 +558,7 @@ set_string_option( vim_free(saved_newval); #endif } - return r; + return errmsg; } /* @@ -574,7 +574,7 @@ valid_filetype(char_u *val) #ifdef FEAT_STL_OPT /* * Check validity of options with the 'statusline' format. - * Return error message or NULL. + * Return an untranslated error message or NULL. */ static char * check_stl_option(char_u *s) @@ -625,24 +625,26 @@ check_stl_option(char_u *s) } if (*s == '{') { - int reevaluate = (*s == '%'); + int reevaluate = (*++s == '%'); - s++; + if (reevaluate && *++s == '}') + // "}" is not allowed immediately after "%{%" + return illegal_char(errbuf, '}'); while ((*s != '}' || (reevaluate && s[-1] != '%')) && *s) s++; if (*s != '}') - return N_(e_unclosed_expression_sequence); + return e_unclosed_expression_sequence; } } if (groupdepth != 0) - return N_(e_unbalanced_groups); + return e_unbalanced_groups; return NULL; } #endif /* * Handle string options that need some action to perform when changed. - * Returns NULL for success, or an error message for an error. + * Returns NULL for success, or an unstranslated error message for an error. */ char * did_set_string_option( @@ -751,7 +753,7 @@ did_set_string_option( { if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex, *p_pm == '.' ? p_pm + 1 : p_pm) == 0) - errmsg = N_(e_backupext_and_patchmode_are_equal); + errmsg = e_backupext_and_patchmode_are_equal; } #ifdef FEAT_LINEBREAK // 'breakindentopt' @@ -785,15 +787,9 @@ did_set_string_option( { // May compute new values for $VIM and $VIMRUNTIME if (didset_vim) - { - vim_setenv((char_u *)"VIM", (char_u *)""); - didset_vim = FALSE; - } + vim_unsetenv_ext((char_u *)"VIM"); if (didset_vimruntime) - { - vim_setenv((char_u *)"VIMRUNTIME", (char_u *)""); - didset_vimruntime = FALSE; - } + vim_unsetenv_ext((char_u *)"VIMRUNTIME"); } #ifdef FEAT_SYN_HL @@ -876,7 +872,7 @@ did_set_string_option( if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK) errmsg = e_invalid_argument; else if (set_chars_option(curwin, &p_fcs) != NULL) - errmsg = _(e_conflicts_with_value_of_fillchars); + errmsg = e_conflicts_with_value_of_fillchars; else { tabpage_T *tp; @@ -886,7 +882,7 @@ did_set_string_option( { if (set_chars_option(wp, &wp->w_p_lcs) != NULL) { - errmsg = _(e_conflicts_with_value_of_listchars); + errmsg = e_conflicts_with_value_of_listchars; goto ambw_end; } } @@ -1259,8 +1255,7 @@ ambw_end: int x2 = -1; int x3 = -1; - if (*p != NUL) - p += mb_ptr2len(p); + p += mb_ptr2len(p); if (*p != NUL) x2 = *p++; if (*p != NUL) @@ -1501,7 +1496,7 @@ ambw_end: for (s = *varp; *s; ) { if (ptr2cells(s) != 1) - errmsg = N_(e_showbreak_contains_unprintable_or_wide_character); + errmsg = e_showbreak_contains_unprintable_or_wide_character; MB_PTR_ADV(s); } } @@ -1543,7 +1538,7 @@ ambw_end: } else # endif - errmsg = N_(e_invalid_fonts); + errmsg = e_invalid_fonts; } } redraw_gui_only = TRUE; @@ -1552,9 +1547,9 @@ ambw_end: else if (varp == &p_guifontset) { if (STRCMP(p_guifontset, "*") == 0) - errmsg = N_(e_cant_select_fontset); + errmsg = e_cant_select_fontset; else if (gui.in_use && gui_init_font(p_guifontset, TRUE) != OK) - errmsg = N_(e_invalid_fontset); + errmsg = e_invalid_fontset; redraw_gui_only = TRUE; } # endif @@ -1816,8 +1811,8 @@ ambw_end: } #ifdef FEAT_STL_OPT - // 'statusline' or 'rulerformat' - else if (gvarp == &p_stl || varp == &p_ruf) + // 'statusline', 'tabline' or 'rulerformat' + else if (gvarp == &p_stl || varp == &p_tal || varp == &p_ruf) { int wid; @@ -1835,7 +1830,7 @@ ambw_end: else errmsg = check_stl_option(p_ruf); } - // check 'statusline' only if it doesn't start with "%!" + // check 'statusline' or 'tabline' only if it doesn't start with "%!" else if (varp == &p_ruf || s[0] != '%' || s[1] != '!') errmsg = check_stl_option(s); if (varp == &p_ruf && errmsg == NULL) diff --git a/src/popupmenu.c b/src/popupmenu.c index f05b7bd94d..9a9bfab1a9 100644 --- a/src/popupmenu.c +++ b/src/popupmenu.c @@ -876,14 +876,16 @@ pum_set_selected(int n, int repeat UNUSED) { // Edit a new, empty buffer. Set options for a "wipeout" // buffer. - set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL); - set_option_value((char_u *)"bl", 0L, NULL, OPT_LOCAL); - set_option_value((char_u *)"bt", 0L, - (char_u *)"nofile", OPT_LOCAL); - set_option_value((char_u *)"bh", 0L, - (char_u *)"wipe", OPT_LOCAL); - set_option_value((char_u *)"diff", 0L, - NULL, OPT_LOCAL); + set_option_value_give_err((char_u *)"swf", + 0L, NULL, OPT_LOCAL); + set_option_value_give_err((char_u *)"bl", + 0L, NULL, OPT_LOCAL); + set_option_value_give_err((char_u *)"bt", + 0L, (char_u *)"nofile", OPT_LOCAL); + set_option_value_give_err((char_u *)"bh", + 0L, (char_u *)"wipe", OPT_LOCAL); + set_option_value_give_err((char_u *)"diff", + 0L, NULL, OPT_LOCAL); } } if (res == OK) diff --git a/src/proto/autocmd.pro b/src/proto/autocmd.pro index 366d7aa4dc..ddf391516a 100644 --- a/src/proto/autocmd.pro +++ b/src/proto/autocmd.pro @@ -7,7 +7,7 @@ int check_ei(void); char_u *au_event_disable(char *what); void au_event_restore(char_u *old_ei); void do_autocmd(exarg_T *eap, char_u *arg_in, int forceit); -int do_doautocmd(char_u *arg, int do_msg, int *did_something); +int do_doautocmd(char_u *arg_start, int do_msg, int *did_something); void ex_doautoall(exarg_T *eap); int check_nomodeline(char_u **argp); void aucmd_prepbuf(aco_save_T *aco, buf_T *buf); @@ -16,6 +16,7 @@ int apply_autocmds(event_T event, char_u *fname, char_u *fname_io, int force, bu int apply_autocmds_exarg(event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, exarg_T *eap); int apply_autocmds_retval(event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, int *retval); int trigger_cursorhold(void); +int has_winscrolled(void); int has_cursormoved(void); int has_cursormovedI(void); int has_textchanged(void); @@ -26,10 +27,10 @@ int has_cmdundefined(void); int has_textyankpost(void); int has_completechanged(void); int has_modechanged(void); -int has_winscrolled(void); void block_autocmds(void); void unblock_autocmds(void); int is_autocmd_blocked(void); +sctx_T *acp_script_ctx(AutoPatCmd_T *acp); char_u *getnextac(int c, void *cookie, int indent, getline_opt_T options); int has_autocmd(event_T event, char_u *sfname, buf_T *buf); char_u *get_augroup_name(expand_T *xp, int idx); diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro index cc7e07a20c..167805bd52 100644 --- a/src/proto/misc1.pro +++ b/src/proto/misc1.pro @@ -32,6 +32,7 @@ void expand_env(char_u *src, char_u *dst, int dstlen); void expand_env_esc(char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr); char_u *vim_getenv(char_u *name, int *mustfree); void vim_unsetenv(char_u *var); +void vim_unsetenv_ext(char_u *var); void vim_setenv_ext(char_u *name, char_u *val); void vim_setenv(char_u *name, char_u *val); char_u *get_env_name(expand_T *xp, int idx); diff --git a/src/proto/option.pro b/src/proto/option.pro index 373a60ca0e..9425bc71d8 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -38,6 +38,7 @@ int is_window_local_option(int opt_idx); int is_hidden_option(int opt_idx); int is_crypt_key_option(int opt_idx); char *set_option_value(char_u *name, long number, char_u *string, int opt_flags); +void set_option_value_give_err(char_u *name, long number, char_u *string, int opt_flags); char_u *get_term_code(char_u *tname); char_u *get_highlight_default(void); char_u *get_encoding_default(void); @@ -63,7 +64,7 @@ void reset_modifiable(void); void set_iminsert_global(void); 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 *pat, int *numMatches, char_u ***matches); +int ExpandSettings(expand_T *xp, regmatch_T *regmatch, char_u *fuzzystr, int *numMatches, char_u ***matches); int ExpandOldSetting(int *num_file, char_u ***file); int shortmess(int x); void vimrc_found(char_u *fname, char_u *envname); diff --git a/src/proto/vim9execute.pro b/src/proto/vim9execute.pro index bd67092915..80afb8536a 100644 --- a/src/proto/vim9execute.pro +++ b/src/proto/vim9execute.pro @@ -6,6 +6,7 @@ int set_ref_in_funcstacks(int copyID); char_u *char_from_string(char_u *str, varnumber_T index); char_u *string_slice(char_u *str, varnumber_T first, varnumber_T last, int exclusive); int fill_partial_and_closure(partial_T *pt, ufunc_T *ufunc, ectx_T *ectx); +int may_load_script(int sid, int *loaded); typval_T *lookup_debug_var(char_u *name); int may_break_in_function(ufunc_T *ufunc); int exe_typval_instr(typval_T *tv, typval_T *rettv); diff --git a/src/quickfix.c b/src/quickfix.c index e38011bf5d..aab1683f32 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -85,7 +85,7 @@ typedef struct qf_list_S char_u *qf_title; // title derived from the command that created // the error list or set by setqflist typval_T *qf_ctx; // context set by setqflist/setloclist - callback_T qftf_cb; // 'quickfixtextfunc' callback function + callback_T qf_qftf_cb; // 'quickfixtextfunc' callback function struct dir_stack_T *qf_dir_stack; char_u *qf_directory; @@ -2337,10 +2337,10 @@ copy_loclist(qf_list_T *from_qfl, qf_list_T *to_qfl) } else to_qfl->qf_ctx = NULL; - if (from_qfl->qftf_cb.cb_name != NULL) - copy_callback(&to_qfl->qftf_cb, &from_qfl->qftf_cb); + if (from_qfl->qf_qftf_cb.cb_name != NULL) + copy_callback(&to_qfl->qf_qftf_cb, &from_qfl->qf_qftf_cb); else - to_qfl->qftf_cb.cb_name = NULL; + to_qfl->qf_qftf_cb.cb_name = NULL; if (from_qfl->qf_count) if (copy_loclist_entries(from_qfl, to_qfl) == FAIL) @@ -3938,7 +3938,7 @@ qf_free(qf_list_T *qfl) VIM_CLEAR(qfl->qf_title); free_tv(qfl->qf_ctx); qfl->qf_ctx = NULL; - free_callback(&qfl->qftf_cb); + free_callback(&qfl->qf_qftf_cb); qfl->qf_id = 0; qfl->qf_changedtick = 0L; } @@ -4173,16 +4173,16 @@ qf_goto_cwindow(qf_info_T *qi, int resize, int sz, int vertsplit) qf_set_cwindow_options(void) { // switch off 'swapfile' - set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL); - set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix", - OPT_LOCAL); - set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL); + set_option_value_give_err((char_u *)"swf", 0L, NULL, OPT_LOCAL); + set_option_value_give_err((char_u *)"bt", + 0L, (char_u *)"quickfix", OPT_LOCAL); + set_option_value_give_err((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL); RESET_BINDING(curwin); #ifdef FEAT_DIFF curwin->w_p_diff = FALSE; #endif #ifdef FEAT_FOLDING - set_option_value((char_u *)"fdm", 0L, (char_u *)"manual", + set_option_value_give_err((char_u *)"fdm", 0L, (char_u *)"manual", OPT_LOCAL); #endif } @@ -4660,9 +4660,9 @@ call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx) // If 'quickfixtextfunc' is set, then use the user-supplied function to get // the text to display. Use the local value of 'quickfixtextfunc' if it is // set. - if (qfl->qftf_cb.cb_name != NULL) - cb = &qfl->qftf_cb; - if (cb != NULL && cb->cb_name != NULL) + if (qfl->qf_qftf_cb.cb_name != NULL) + cb = &qfl->qf_qftf_cb; + if (cb->cb_name != NULL) { typval_T args[1]; dict_T *d; @@ -4796,7 +4796,8 @@ qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid) // This resembles reading a file into a buffer, it's more logical when // using autocommands. ++curbuf_lock; - set_option_value((char_u *)"ft", 0L, (char_u *)"qf", OPT_LOCAL); + set_option_value_give_err((char_u *)"ft", + 0L, (char_u *)"qf", OPT_LOCAL); curbuf->b_p_ma = FALSE; keep_filetype = TRUE; // don't detect 'filetype' @@ -7105,11 +7106,11 @@ qf_getprop_qftf(qf_list_T *qfl, dict_T *retdict) { int status; - if (qfl->qftf_cb.cb_name != NULL) + if (qfl->qf_qftf_cb.cb_name != NULL) { typval_T tv; - put_callback(&qfl->qftf_cb, &tv); + put_callback(&qfl->qf_qftf_cb, &tv); status = dict_add_tv(retdict, "quickfixtextfunc", &tv); clear_tv(&tv); } @@ -7551,10 +7552,10 @@ qf_setprop_qftf(qf_info_T *qi UNUSED, qf_list_T *qfl, dictitem_T *di) { callback_T cb; - free_callback(&qfl->qftf_cb); + free_callback(&qfl->qf_qftf_cb); cb = get_callback(&di->di_tv); if (cb.cb_name != NULL && *cb.cb_name != NUL) - set_callback(&qfl->qftf_cb, &cb); + set_callback(&qfl->qf_qftf_cb, &cb); return OK; } @@ -7737,7 +7738,7 @@ mark_quickfix_ctx(qf_info_T *qi, int copyID) && ctx->v_type != VAR_STRING && ctx->v_type != VAR_FLOAT) abort = abort || set_ref_in_item(ctx, copyID, NULL, NULL); - cb = &qi->qf_lists[i].qftf_cb; + cb = &qi->qf_lists[i].qf_qftf_cb; abort = abort || set_ref_in_callback(cb, copyID); } @@ -8312,7 +8313,7 @@ ex_helpgrep(exarg_T *eap) // Darn, some plugin changed the value. If it's still empty it was // changed and restored, need to restore in the complicated way. if (*p_cpo == NUL) - set_option_value((char_u *)"cpo", 0L, save_cpo, 0); + set_option_value_give_err((char_u *)"cpo", 0L, save_cpo, 0); if (save_cpo_allocated) free_string_option(save_cpo); } diff --git a/src/scriptfile.c b/src/scriptfile.c index 7e14cdc6e3..03c733d354 100644 --- a/src/scriptfile.c +++ b/src/scriptfile.c @@ -117,7 +117,7 @@ estack_pop(void) } /* - * Get the current value for in allocated memory. + * Get the current value for "which" in allocated memory. * "which" is ESTACK_SFILE for , ESTACK_STACK for or * ESTACK_SCRIPT for