Merge remote-tracking branch 'vim/master'

This commit is contained in:
ichizok
2022-04-17 09:11:58 +09:00
68 changed files with 1056 additions and 356 deletions
+30 -3
View File
@@ -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
+6 -1
View File
@@ -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.
+137 -16
View File
@@ -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()
... <handle failure>
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": <number>,
"method": <string>,
"params": <list|dict>
}
A LSP reponse message has the following format (expressed as a Vim Dict). The
"result" and "error" fields are optional: >
{
"jsonrpc": "2.0",
"id": <number>,
"result": <vim type>
"error": <dict>
}
A LSP notification message has the following format (expressed as a Vim Dict).
The "params" field is optional: >
{
"jsonrpc": "2.0",
"method": <string>,
"params": <list|dict>
}
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": <number>,
"method": <string>,
"params": <list|dict>
}
A LSP reponse message has the following format (expressed as a Vim Dict). The
"result" and "error" fields are optional: >
{
"jsonrpc": "2.0",
"id": <number>,
"result": <vim type>
"error": <dict>
}
A LSP notification message has the following format (expressed as a Vim Dict).
The "params" field is optional: >
{
"jsonrpc": "2.0",
"method": <string>,
"params": <list|dict>
}
vim:tw=78:ts=8:noet:ft=help:norl:
+1
View File
@@ -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|
+2
View File
@@ -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 <C-R> 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).
+9 -1
View File
@@ -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, |<SID>| can be
used: >
noremap <silent> ,a :call <SID>name.Function()<CR>
When the mapping is defined "<SID>name." will be replaced with <SNR> 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
+15 -6
View File
@@ -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
+37 -20
View File
@@ -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 <abuf>, 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
+15 -3
View File
@@ -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);
}
}
/*
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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;
}
+10 -2
View File
@@ -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 <SID>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);
}
+4 -4
View File
@@ -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));
}
/*
+2 -2
View File
@@ -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);
}
/*
+1 -2
View File
@@ -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
+8 -6
View File
@@ -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
+39 -15
View File
@@ -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;
}
+4 -2
View File
@@ -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 *)"<buffer> <Tab> <C-X><C-V>", INSERT);
add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", 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;
+2 -1
View File
@@ -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;
+4 -3
View File
@@ -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();
}
}
+2 -1
View File
@@ -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();
+1 -1
View File
@@ -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.
+2 -1
View File
@@ -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;
}
+2 -2
View File
@@ -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");
}
}
+1 -1
View File
@@ -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);
}
}
+15 -11
View File
@@ -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);
}
+14 -7
View File
@@ -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)
+2 -2
View File
@@ -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);
+2 -2
View File
@@ -314,13 +314,13 @@ main(int argc, char **argv)
params.argv = argv;
common_init(&params);
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();
+19 -7
View File
@@ -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
+35 -23
View File
@@ -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.
+2 -1
View File
@@ -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'
+27 -32
View File
@@ -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)
+10 -8
View File
@@ -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)
+3 -2
View File
@@ -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);
+1
View File
@@ -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);
+2 -1
View File
@@ -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);
+1
View File
@@ -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);
+21 -20
View File
@@ -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);
}
+40 -18
View File
@@ -117,7 +117,7 @@ estack_pop(void)
}
/*
* Get the current value for <sfile> in allocated memory.
* Get the current value for "which" in allocated memory.
* "which" is ESTACK_SFILE for <sfile>, ESTACK_STACK for <stack> or
* ESTACK_SCRIPT for <script>.
*/
@@ -157,27 +157,36 @@ estack_sfile(estack_arg_T which UNUSED)
return NULL;
}
// If evaluated in a function return the path of the script where the
// function is defined, at script level the current script path is returned
// If evaluated in a function or autocommand, return the path of the script
// where it is defined, at script level the current script path is returned
// instead.
if (which == ESTACK_SCRIPT)
{
if (entry->es_type == ETYPE_UFUNC)
entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
// Walk the stack backwards, starting from the current frame.
for (idx = exestack.ga_len - 1; idx >= 0; --idx, --entry)
{
sctx_T *def_ctx = &entry->es_info.ufunc->uf_script_ctx;
if (def_ctx->sc_sid > 0)
return vim_strsave(SCRIPT_ITEM(def_ctx->sc_sid)->sn_name);
}
else if (exestack.ga_len > 0)
{
// Walk the stack backwards, starting from the current frame.
for (idx = exestack.ga_len - 1; idx; --idx)
if (entry->es_type == ETYPE_UFUNC)
{
entry = ((estack_T *)exestack.ga_data) + idx;
sctx_T *def_ctx = &entry->es_info.ufunc->uf_script_ctx;
if (entry->es_type == ETYPE_SCRIPT)
return vim_strsave(entry->es_name);
if (def_ctx->sc_sid > 0)
return vim_strsave(SCRIPT_ITEM(def_ctx->sc_sid)->sn_name);
else
return NULL;
}
else if (entry->es_type == ETYPE_AUCMD)
{
sctx_T *def_ctx = acp_script_ctx(entry->es_info.aucmd);
if (def_ctx->sc_sid > 0)
return vim_strsave(SCRIPT_ITEM(def_ctx->sc_sid)->sn_name);
else
return NULL;
}
else if (entry->es_type == ETYPE_SCRIPT)
{
return vim_strsave(entry->es_name);
}
}
return NULL;
@@ -774,7 +783,7 @@ add_pack_dir_to_rtp(char_u *fname)
STRCAT(new_rtp, afterdir);
}
set_option_value((char_u *)"rtp", 0L, new_rtp, 0);
set_option_value_give_err((char_u *)"rtp", 0L, new_rtp, 0);
vim_free(new_rtp);
retval = OK;
@@ -1749,7 +1758,8 @@ almosttheend:
}
}
}
set_option_value((char_u *)"cpo", 0L, si->sn_save_cpo, OPT_NO_REDRAW);
set_option_value_give_err((char_u *)"cpo",
0L, si->sn_save_cpo, OPT_NO_REDRAW);
}
VIM_CLEAR(si->sn_save_cpo);
@@ -2468,6 +2478,18 @@ script_autoload(
int i;
int ret_sid;
// If the name starts with "<SNR>123_" then "123" is the script ID.
if (name[0] == K_SPECIAL && name[1] == KS_EXTRA && name[2] == KE_SNR)
{
p = name + 3;
ret_sid = (int)getdigits(&p);
if (*p == '_' && SCRIPT_ID_VALID(ret_sid))
{
may_load_script(ret_sid, &ret);
return ret;
}
}
// If there is no '#' after name[0] there is no package name.
p = vim_strchr(name, AUTOLOAD_CHAR);
if (p == NULL || p == name)
+55 -38
View File
@@ -4657,45 +4657,48 @@ fuzzy_match_item_compare(const void *s1, const void *s2)
*/
static void
fuzzy_match_in_list(
list_T *items,
list_T *l,
char_u *str,
int matchseq,
char_u *key,
callback_T *item_cb,
int retmatchpos,
list_T *fmatchlist)
list_T *fmatchlist,
long max_matches)
{
long len;
fuzzyItem_T *ptrs;
fuzzyItem_T *items;
listitem_T *li;
long i = 0;
int found_match = FALSE;
long match_count = 0;
int_u matches[MAX_FUZZY_MATCHES];
len = list_len(items);
len = list_len(l);
if (len == 0)
return;
if (max_matches > 0 && len > max_matches)
len = max_matches;
ptrs = ALLOC_CLEAR_MULT(fuzzyItem_T, len);
if (ptrs == NULL)
items = ALLOC_CLEAR_MULT(fuzzyItem_T, len);
if (items == NULL)
return;
// For all the string items in items, get the fuzzy matching score
FOR_ALL_LIST_ITEMS(items, li)
FOR_ALL_LIST_ITEMS(l, li)
{
int score;
char_u *itemstr;
typval_T rettv;
ptrs[i].idx = i;
ptrs[i].item = li;
ptrs[i].score = SCORE_NONE;
if (max_matches > 0 && match_count >= max_matches)
break;
itemstr = NULL;
rettv.v_type = VAR_UNKNOWN;
if (li->li_tv.v_type == VAR_STRING) // list of strings
itemstr = li->li_tv.vval.v_string;
else if (li->li_tv.v_type == VAR_DICT
&& (key != NULL || item_cb->cb_name != NULL))
&& (key != NULL || item_cb->cb_name != NULL))
{
// For a dict, either use the specified key to lookup the string or
// use the specified callback function to get the string.
@@ -4721,8 +4724,12 @@ fuzzy_match_in_list(
if (itemstr != NULL
&& fuzzy_match(itemstr, str, matchseq, &score, matches,
sizeof(matches) / sizeof(matches[0])))
MAX_FUZZY_MATCHES))
{
items[match_count].idx = match_count;
items[match_count].item = li;
items[match_count].score = score;
// Copy the list of matching positions in itemstr to a list, if
// 'retmatchpos' is set.
if (retmatchpos)
@@ -4730,8 +4737,8 @@ fuzzy_match_in_list(
int j = 0;
char_u *p;
ptrs[i].lmatchpos = list_alloc();
if (ptrs[i].lmatchpos == NULL)
items[match_count].lmatchpos = list_alloc();
if (items[match_count].lmatchpos == NULL)
goto done;
p = str;
@@ -4739,7 +4746,7 @@ fuzzy_match_in_list(
{
if (!VIM_ISWHITE(PTR2CHAR(p)))
{
if (list_append_number(ptrs[i].lmatchpos,
if (list_append_number(items[match_count].lmatchpos,
matches[j]) == FAIL)
goto done;
j++;
@@ -4750,19 +4757,17 @@ fuzzy_match_in_list(
++p;
}
}
ptrs[i].score = score;
found_match = TRUE;
++match_count;
}
++i;
clear_tv(&rettv);
}
if (found_match)
if (match_count > 0)
{
list_T *l;
list_T *retlist;
// Sort the list by the descending order of the match score
qsort((void *)ptrs, (size_t)len, sizeof(fuzzyItem_T),
qsort((void *)items, (size_t)match_count, sizeof(fuzzyItem_T),
fuzzy_match_item_compare);
// For matchfuzzy(), return a list of matched strings.
@@ -4777,17 +4782,17 @@ fuzzy_match_in_list(
li = list_find(fmatchlist, 0);
if (li == NULL || li->li_tv.vval.v_list == NULL)
goto done;
l = li->li_tv.vval.v_list;
retlist = li->li_tv.vval.v_list;
}
else
l = fmatchlist;
retlist = fmatchlist;
// Copy the matching strings with a valid score to the return list
for (i = 0; i < len; i++)
for (i = 0; i < match_count; i++)
{
if (ptrs[i].score == SCORE_NONE)
if (items[i].score == SCORE_NONE)
break;
list_append_tv(l, &ptrs[i].item->li_tv);
list_append_tv(retlist, &items[i].item->li_tv);
}
// next copy the list of matching positions
@@ -4796,14 +4801,15 @@ fuzzy_match_in_list(
li = list_find(fmatchlist, -2);
if (li == NULL || li->li_tv.vval.v_list == NULL)
goto done;
l = li->li_tv.vval.v_list;
retlist = li->li_tv.vval.v_list;
for (i = 0; i < len; i++)
for (i = 0; i < match_count; i++)
{
if (ptrs[i].score == SCORE_NONE)
if (items[i].score == SCORE_NONE)
break;
if (ptrs[i].lmatchpos != NULL
&& list_append_list(l, ptrs[i].lmatchpos) == FAIL)
if (items[i].lmatchpos != NULL
&& list_append_list(retlist, items[i].lmatchpos)
== FAIL)
goto done;
}
@@ -4811,19 +4817,19 @@ fuzzy_match_in_list(
li = list_find(fmatchlist, -1);
if (li == NULL || li->li_tv.vval.v_list == NULL)
goto done;
l = li->li_tv.vval.v_list;
for (i = 0; i < len; i++)
retlist = li->li_tv.vval.v_list;
for (i = 0; i < match_count; i++)
{
if (ptrs[i].score == SCORE_NONE)
if (items[i].score == SCORE_NONE)
break;
if (list_append_number(l, ptrs[i].score) == FAIL)
if (list_append_number(retlist, items[i].score) == FAIL)
goto done;
}
}
}
done:
vim_free(ptrs);
vim_free(items);
}
/*
@@ -4837,6 +4843,7 @@ do_fuzzymatch(typval_T *argvars, typval_T *rettv, int retmatchpos)
char_u *key = NULL;
int ret;
int matchseq = FALSE;
long max_matches = 0;
if (in_vim9script()
&& (check_for_list_arg(argvars, 0) == FAIL
@@ -4894,6 +4901,16 @@ do_fuzzymatch(typval_T *argvars, typval_T *rettv, int retmatchpos)
return;
}
}
else if ((di = dict_find(d, (char_u *)"limit", -1)) != NULL)
{
if (di->di_tv.v_type != VAR_NUMBER)
{
semsg(_(e_invalid_argument_str), tv_get_string(&di->di_tv));
return;
}
max_matches = (long)tv_get_number_chk(&di->di_tv, NULL);
}
if (dict_has_key(d, "matchseq"))
matchseq = TRUE;
}
@@ -4928,7 +4945,7 @@ do_fuzzymatch(typval_T *argvars, typval_T *rettv, int retmatchpos)
}
fuzzy_match_in_list(argvars[0].vval.v_list, tv_get_string(&argvars[1]),
matchseq, key, &cb, retmatchpos, rettv->vval.v_list);
matchseq, key, &cb, retmatchpos, rettv->vval.v_list, max_matches);
done:
free_callback(&cb);
+3 -3
View File
@@ -1965,7 +1965,7 @@ count_syllables(slang_T *slang, char_u *word)
/*
* Parse 'spelllang' and set w_s->b_langp accordingly.
* Returns NULL if it's OK, an error message otherwise.
* Returns NULL if it's OK, an untranslated error message otherwise.
*/
char *
did_set_spelllang(win_T *wp)
@@ -3834,8 +3834,8 @@ ex_spelldump(exarg_T *eap)
do_cmdline_cmd((char_u *)"new");
// enable spelling locally in the new window
set_option_value((char_u*)"spell", TRUE, (char_u*)"", OPT_LOCAL);
set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL);
set_option_value_give_err((char_u*)"spell", TRUE, (char_u*)"", OPT_LOCAL);
set_option_value_give_err((char_u*)"spl", dummy, spl, OPT_LOCAL);
vim_free(spl);
if (!BUFEMPTY())
+2 -1
View File
@@ -6414,7 +6414,8 @@ init_spellfile(void)
fname != NULL
&& strstr((char *)gettail(fname), ".ascii.") != NULL
? (char_u *)"ascii" : spell_enc());
set_option_value((char_u *)"spellfile", 0L, buf, OPT_LOCAL);
set_option_value_give_err((char_u *)"spellfile",
0L, buf, OPT_LOCAL);
break;
}
aspath = FALSE;
+5 -3
View File
@@ -2073,7 +2073,7 @@ struct partial_S
dict_T *pt_dict; // dict for "self"
};
typedef struct AutoPatCmd_S AutoPatCmd;
typedef struct AutoPatCmd_S AutoPatCmd_T;
/*
* Entry in the execution stack "exestack".
@@ -2100,7 +2100,7 @@ typedef struct {
#if defined(FEAT_EVAL)
ufunc_T *ufunc; // function info
#endif
AutoPatCmd *aucmd; // autocommand info
AutoPatCmd_T *aucmd; // autocommand info
except_T *except; // exception info
} es_info;
#if defined(FEAT_EVAL)
@@ -3349,8 +3349,10 @@ typedef struct
linenr_T first_lnum; // first lnum to search for multi-line pat
colnr_T startcol; // in win_line() points to char where HL starts
colnr_T endcol; // in win_line() points to char where HL ends
int is_addpos; // position specified directly by
char is_addpos; // position specified directly by
// matchaddpos(). TRUE/FALSE
char has_cursor; // TRUE if the cursor is inside the match, used for
// CurSearch
#ifdef FEAT_RELTIME
proftime_T tm; // for a time limit
#endif
+3 -2
View File
@@ -6486,8 +6486,9 @@ syn_get_id(
int keep_state) // keep state of char at "col"
{
// When the position is not after the current position and in the same
// line of the same buffer, need to restart parsing.
if (wp->w_buffer != syn_buf
// line of the same window with the same buffer, need to restart parsing.
if (wp != syn_win
|| wp->w_buffer != syn_buf
|| lnum != current_lnum
|| col < current_col)
syntax_start(wp, lnum);
+51 -13
View File
@@ -2035,7 +2035,7 @@ set_termname(char_u *term)
# endif
if (p != NULL)
{
set_option_value((char_u *)"ttym", 0L, p, 0);
set_option_value_give_err((char_u *)"ttym", 0L, p, 0);
// Reset the WAS_SET flag, 'ttymouse' can be set to "sgr" or
// "xterm2" in check_termcode().
reset_option_was_set((char_u *)"ttym");
@@ -4611,7 +4611,7 @@ handle_u7_response(int *arg, char_u *tp UNUSED, int csi_len UNUSED)
// Setting the option causes a screen redraw. Do
// that right away if possible, keeping any
// messages.
set_option_value((char_u *)"ambw", 0L, (char_u *)aw, 0);
set_option_value_give_err((char_u *)"ambw", 0L, (char_u *)aw, 0);
# ifdef DEBUG_TERMRESPONSE
{
int r = redraw_asap(CLEAR);
@@ -4822,7 +4822,7 @@ handle_version_response(int first, int *arg, int argc, char_u *tp)
&& (term_props[TPR_MOUSE].tpr_status == TPR_MOUSE_XTERM2
|| term_props[TPR_MOUSE].tpr_status == TPR_MOUSE_SGR))
{
set_option_value((char_u *)"ttym", 0L,
set_option_value_give_err((char_u *)"ttym", 0L,
term_props[TPR_MOUSE].tpr_status == TPR_MOUSE_SGR
? (char_u *)"sgr" : (char_u *)"xterm2", 0);
}
@@ -5146,8 +5146,8 @@ handle_osc(char_u *tp, char_u *argp, int len, char_u *key_name, int *slen)
&& STRCMP(p_bg, new_bg_val) != 0)
{
// value differs, apply it
set_option_value((char_u *)"bg", 0L,
(char_u *)new_bg_val, 0);
set_option_value_give_err((char_u *)"bg",
0L, (char_u *)new_bg_val, 0);
reset_option_was_set((char_u *)"bg");
redraw_asap(CLEAR);
}
@@ -5969,24 +5969,26 @@ replace_termcodes(
int do_special; // recognize <> key codes
int do_key_code; // recognize raw key codes
char_u *result; // buffer for resulting string
garray_T ga;
do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
do_special = (vim_strchr(p_cpo, CPO_SPECI) == NULL)
|| (flags & REPTERM_SPECIAL);
do_key_code = (vim_strchr(p_cpo, CPO_KEYCODE) == NULL);
src = from;
/*
* Allocate space for the translation. Worst case a single character is
* replaced by 6 bytes (shifted special key), plus a NUL at the end.
* In the rare case more might be needed ga_grow() must be called again.
*/
result = alloc(STRLEN(from) * 6 + 1);
if (result == NULL) // out of memory
ga_init2(&ga, 1L, 100);
if (ga_grow(&ga, STRLEN(src) * 6 + 1) == FAIL) // out of memory
{
*bufp = NULL;
return from;
}
src = from;
result = ga.ga_data;
/*
* Check for #n at start only: function key n
@@ -6016,8 +6018,11 @@ replace_termcodes(
{
#ifdef FEAT_EVAL
/*
* Replace <SID> by K_SNR <script-nr> _.
* Change <SID>Func to K_SNR <script-nr> _Func. This name is used
* for script-locla user functions.
* (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
* Also change <SID>name.Func to K_SNR <import-script-nr> _Func.
* Only if "name" is recognized as an import.
*/
if (STRNICMP(src, "<SID>", 5) == 0)
{
@@ -6025,19 +6030,52 @@ replace_termcodes(
emsg(_(e_using_sid_not_in_script_context));
else
{
char_u *dot;
long sid = current_sctx.sc_sid;
src += 5;
if (in_vim9script()
&& (dot = vim_strchr(src, '.')) != NULL)
{
imported_T *imp = find_imported(src, dot - src, FALSE);
if (imp != NULL)
{
scriptitem_T *si = SCRIPT_ITEM(imp->imp_sid);
size_t len;
src = dot + 1;
if (si->sn_autoload_prefix != NULL)
{
// Turn "<SID>name.Func"
// into "scriptname#Func".
len = STRLEN(si->sn_autoload_prefix);
if (ga_grow(&ga, STRLEN(src) * 6 + len + 1)
== FAIL)
{
ga_clear(&ga);
*bufp = NULL;
return from;
}
result = ga.ga_data;
STRCPY(result + dlen, si->sn_autoload_prefix);
dlen += len;
continue;
}
sid = imp->imp_sid;
}
}
result[dlen++] = K_SPECIAL;
result[dlen++] = (int)KS_EXTRA;
result[dlen++] = (int)KE_SNR;
sprintf((char *)result + dlen, "%ld",
(long)current_sctx.sc_sid);
sprintf((char *)result + dlen, "%ld", sid);
dlen += (int)STRLEN(result + dlen);
result[dlen++] = '_';
continue;
}
}
#endif
slen = trans_special(&src, result + dlen, FSK_KEYCODE
| ((flags & REPTERM_NO_SIMPLIFY) ? 0 : FSK_SIMPLIFY),
did_simplify);
+11 -1
View File
@@ -3390,12 +3390,22 @@ handle_postponed_scrollback(term_T *term)
limit_scrollback(term, &term->tl_scrollback, TRUE);
}
/*
* Called when the terminal wants to ring the system bell.
*/
static int
handle_bell(void *user UNUSED)
{
vim_beep(BO_TERM);
return 0;
}
static VTermScreenCallbacks screen_callbacks = {
handle_damage, // damage
handle_moverect, // moverect
handle_movecursor, // movecursor
handle_settermprop, // settermprop
NULL, // bell
handle_bell, // bell
handle_resize, // resize
handle_pushline, // sb_pushline
NULL // sb_popline
@@ -0,0 +1,9 @@
|-+0&#ffffff0@2| @56
|a|b|c|d>e+0&#4040ff13|f|g| | +0&#ffffff0@51
|h+0&#4040ff13|i|j|k+0&#ffffff0|l| @54
|-@2| @56
|a|b|c|d|e+0&#ffff4012|f|g| | +0&#ffffff0@51
|h+0&#ffff4012|i|j|k+0&#ffffff0|l| @54
|~+0#4040ff13&| @58
|~| @58
|/+0#0000000&|e|f|g|\|n|h|i|j| @32|2|,|5| @10|A|l@1|
@@ -0,0 +1,9 @@
|-+0&#ffffff0@2| @56
|a|b|c>d|e+0&#ffff4012|f|g| | +0&#ffffff0@51
|h+0&#ffff4012|i|j|k+0&#ffffff0|l| @54
|-@2| @56
|a|b|c|d|e+0&#ffff4012|f|g| | +0&#ffffff0@51
|h+0&#ffff4012|i|j|k+0&#ffffff0|l| @54
|~+0#4040ff13&| @58
|~| @58
| +0#0000000&@41|2|,|4| @10|A|l@1|
@@ -0,0 +1,9 @@
|-+0&#ffffff0@2| @56
|a|b|c|d|e+0&#ffff4012|f|g| | +0&#ffffff0@51
|h+0&#ffff4012|i|j>k+0&#ffffff0|l| @54
|-@2| @56
|a|b|c|d|e+0&#ffff4012|f|g| | +0&#ffffff0@51
|h+0&#ffff4012|i|j|k+0&#ffffff0|l| @54
|~+0#4040ff13&| @58
|~| @58
| +0#0000000&@41|3|,|4| @10|A|l@1|
@@ -0,0 +1,9 @@
|-+0&#ffffff0@2| @56
|a|b|c|d|e+0&#4040ff13|f|g| | +0&#ffffff0@51
|h+0&#4040ff13|i>j|k+0&#ffffff0|l| @54
|-@2| @56
|a|b|c|d|e+0&#ffff4012|f|g| | +0&#ffffff0@51
|h+0&#ffff4012|i|j|k+0&#ffffff0|l| @54
|~+0#4040ff13&| @58
|~| @58
| +0#0000000&@41|3|,|3| @10|A|l@1|
+2 -1
View File
@@ -1,10 +1,11 @@
# Suppress leaks from X libraries on Ubuntu bionic.
# Suppress leaks from X libraries on Ubuntu focal.
leak:libX11.so.6
leak:libXt.so.6
leak:libcairo.so.2
leak:libfontconfig.so.1
leak:libglib-2.0.so.0
leak:libtinfo.so.5
leak:libtinfo.so.6
# Suppress leaks from other language libraries.
leak:libperl.so.*
leak:libpython*.so.*
+25 -28
View File
@@ -2494,9 +2494,10 @@ func LspTests(port)
" Wrong payload notification test
let g:lspNotif = []
call ch_sendexpr(ch, #{method: 'wrong-payload', params: {}})
let r = ch_sendexpr(ch, #{method: 'wrong-payload', params: {}})
call assert_equal({}, r)
" Send a ping to wait for all the notification messages to arrive
call ch_evalexpr(ch, #{method: 'ping'})
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
call assert_equal([#{jsonrpc: '2.0', result: 'wrong-payload'}], g:lspNotif)
" Test for receiving a response with incorrect 'id' and additional
@@ -2516,14 +2517,14 @@ func LspTests(port)
let g:lspNotif = []
call ch_sendexpr(ch, #{method: 'simple-notif', params: [#{a: 10, b: []}]})
" Send a ping to wait for all the notification messages to arrive
call ch_evalexpr(ch, #{method: 'ping'})
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
call assert_equal([#{jsonrpc: '2.0', result: 'simple-notif'}], g:lspNotif)
" multiple notifications test
let g:lspNotif = []
call ch_sendexpr(ch, #{method: 'multi-notif', params: [#{a: {}, b: {}}]})
" Send a ping to wait for all the notification messages to arrive
call ch_evalexpr(ch, #{method: 'ping'})
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
call assert_equal([#{jsonrpc: '2.0', result: 'multi-notif1'},
\ #{jsonrpc: '2.0', result: 'multi-notif2'}], g:lspNotif)
@@ -2531,7 +2532,7 @@ func LspTests(port)
let g:lspNotif = []
call ch_sendexpr(ch, #{method: 'msg-with-id', id: 93, params: #{s: 'str'}})
" Send a ping to wait for all the notification messages to arrive
call ch_evalexpr(ch, #{method: 'ping'})
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
call assert_equal([#{jsonrpc: '2.0', id: 93, result: 'msg-with-id'}],
\ g:lspNotif)
@@ -2541,16 +2542,17 @@ func LspTests(port)
" Test for using a one time callback function to process a response
let g:lspOtMsgs = []
call ch_sendexpr(ch, #{method: 'msg-specifc-cb', params: {}},
let r = ch_sendexpr(ch, #{method: 'msg-specifc-cb', params: {}},
\ #{callback: 'LspOtCb'})
call ch_evalexpr(ch, #{method: 'ping'})
call assert_equal(9, r.id)
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
call assert_equal([#{id: 9, jsonrpc: '2.0', result: 'msg-specifc-cb'}],
\ g:lspOtMsgs)
" Test for generating a request message from the other end (server)
let g:lspNotif = []
call ch_sendexpr(ch, #{method: 'server-req', params: #{}})
call ch_evalexpr(ch, #{method: 'ping'})
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
call assert_equal([{'id': 201, 'jsonrpc': '2.0',
\ 'result': {'method': 'checkhealth', 'params': {'a': 20}}}],
\ g:lspNotif)
@@ -2559,7 +2561,7 @@ func LspTests(port)
let g:lspNotif = []
call ch_sendexpr(ch, #{method: 'echo', params: #{s: 'msg-without-id'}})
" Send a ping to wait for all the notification messages to arrive
call ch_evalexpr(ch, #{method: 'ping'})
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
call assert_equal([#{jsonrpc: '2.0', result:
\ #{method: 'echo', jsonrpc: '2.0', params: #{s: 'msg-without-id'}}}],
\ g:lspNotif)
@@ -2568,7 +2570,7 @@ func LspTests(port)
let g:lspNotif = []
call ch_sendexpr(ch, #{method: 'echo', id: 110, params: #{s: 'msg-with-id'}})
" Send a ping to wait for all the notification messages to arrive
call ch_evalexpr(ch, #{method: 'ping'})
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
call assert_equal([#{jsonrpc: '2.0', result:
\ #{method: 'echo', jsonrpc: '2.0', id: 110,
\ params: #{s: 'msg-with-id'}}}], g:lspNotif)
@@ -2581,46 +2583,41 @@ func LspTests(port)
" Test for processing a HTTP header without the Content-Length field
let resp = ch_evalexpr(ch, #{method: 'hdr-without-len', params: {}},
\ #{timeout: 200})
call assert_equal('', resp)
call assert_equal({}, resp)
" send a ping to make sure communication still works
let resp = ch_evalexpr(ch, #{method: 'ping'})
call assert_equal({'id': 16, 'jsonrpc': '2.0', 'result': 'alive'}, resp)
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
" Test for processing a HTTP header with wrong length
let resp = ch_evalexpr(ch, #{method: 'hdr-with-wrong-len', params: {}},
\ #{timeout: 200})
call assert_equal('', resp)
call assert_equal({}, resp)
" send a ping to make sure communication still works
let resp = ch_evalexpr(ch, #{method: 'ping'})
call assert_equal({'id': 18, 'jsonrpc': '2.0', 'result': 'alive'}, resp)
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
" Test for processing a HTTP header with negative length
let resp = ch_evalexpr(ch, #{method: 'hdr-with-negative-len', params: {}},
\ #{timeout: 200})
call assert_equal('', resp)
call assert_equal({}, resp)
" send a ping to make sure communication still works
let resp = ch_evalexpr(ch, #{method: 'ping'})
call assert_equal({'id': 20, 'jsonrpc': '2.0', 'result': 'alive'}, resp)
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
" Test for an empty header
let resp = ch_evalexpr(ch, #{method: 'empty-header', params: {}},
\ #{timeout: 200})
call assert_equal('', resp)
call assert_equal({}, resp)
" send a ping to make sure communication still works
let resp = ch_evalexpr(ch, #{method: 'ping'})
call assert_equal({'id': 22, 'jsonrpc': '2.0', 'result': 'alive'}, resp)
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
" Test for an empty payload
let resp = ch_evalexpr(ch, #{method: 'empty-payload', params: {}},
\ #{timeout: 200})
call assert_equal('', resp)
call assert_equal({}, resp)
" send a ping to make sure communication still works
let resp = ch_evalexpr(ch, #{method: 'ping'})
call assert_equal({'id': 24, 'jsonrpc': '2.0', 'result': 'alive'}, resp)
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
" Test for invoking an unsupported method
let resp = ch_evalexpr(ch, #{method: 'xyz', params: {}}, #{timeout: 200})
call assert_equal('', resp)
call assert_equal({}, resp)
" Test for sending a message without a callback function. Notification
" message should be dropped but RPC response should not be dropped.
@@ -2628,14 +2625,14 @@ func LspTests(port)
let g:lspNotif = []
call ch_sendexpr(ch, #{method: 'echo', params: #{s: 'no-callback'}})
" Send a ping to wait for all the notification messages to arrive
call ch_evalexpr(ch, #{method: 'ping'})
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
call assert_equal([], g:lspNotif)
" Restore the callback function
call ch_setoptions(ch, #{callback: 'LspCb'})
let g:lspNotif = []
call ch_sendexpr(ch, #{method: 'echo', params: #{s: 'no-callback'}})
" Send a ping to wait for all the notification messages to arrive
call ch_evalexpr(ch, #{method: 'ping'})
call assert_equal('alive', ch_evalexpr(ch, #{method: 'ping'}).result)
call assert_equal([#{jsonrpc: '2.0', result:
\ #{method: 'echo', jsonrpc: '2.0', params: #{s: 'no-callback'}}}],
\ g:lspNotif)
+20
View File
@@ -28,6 +28,26 @@ func Test_setenv()
call assert_equal(v:null, getenv('TEST ENV'))
endfunc
func Test_special_env()
" The value for $HOME is cached internally by Vim, ensure the value is up to
" date.
let orig_ENV = $HOME
let $HOME = 'foo'
call assert_equal('foo', expand('~'))
" old $HOME value is kept until a new one is set
unlet $HOME
call assert_equal('foo', expand('~'))
call setenv('HOME', 'bar')
call assert_equal('bar', expand('~'))
" old $HOME value is kept until a new one is set
call setenv('HOME', v:null)
call assert_equal('bar', expand('~'))
let $HOME = orig_ENV
endfunc
func Test_external_env()
call setenv('FOO', 'HelloWorld')
if has('win32')
+13
View File
@@ -250,5 +250,18 @@ func Test_ex_mode_large_indent()
bwipe!
endfunc
" This was accessing illegal memory when using "+" for eap->cmd.
func Test_empty_command_visual_mode()
let lines =<< trim END
r<sfile>
0norm0V:
:qall!
END
call writefile(lines, 'Xexmodescript')
call assert_equal(1, RunVim([], [], '-u NONE -e -s -S Xexmodescript'))
call delete('Xexmodescript')
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+18 -9
View File
@@ -169,43 +169,52 @@ endfunc
func Test_expand_script_source()
let lines0 =<< trim [SCRIPT]
let g:script_level[0] = expand('<script>:t')
call extend(g:script_level, [expand('<script>:t')])
so Xscript1
func F0()
let g:func_level[0] = expand('<script>:t')
call extend(g:func_level, [expand('<script>:t')])
endfunc
au User * call extend(g:au_level, [expand('<script>:t')])
[SCRIPT]
let lines1 =<< trim [SCRIPT]
let g:script_level[1] = expand('<script>:t')
call extend(g:script_level, [expand('<script>:t')])
so Xscript2
func F1()
let g:func_level[1] = expand('<script>:t')
call extend(g:func_level, [expand('<script>:t')])
endfunc
au User * call extend(g:au_level, [expand('<script>:t')])
[SCRIPT]
let lines2 =<< trim [SCRIPT]
let g:script_level[2] = expand('<script>:t')
call extend(g:script_level, [expand('<script>:t')])
func F2()
let g:func_level[2] = expand('<script>:t')
call extend(g:func_level, [expand('<script>:t')])
endfunc
au User * call extend(g:au_level, [expand('<script>:t')])
[SCRIPT]
call writefile(lines0, 'Xscript0')
call writefile(lines1, 'Xscript1')
call writefile(lines2, 'Xscript2')
" Check the expansion of <script> at script and function level.
let g:script_level = ['', '', '']
let g:func_level = ['', '', '']
" Check the expansion of <script> at different levels.
let g:script_level = []
let g:func_level = []
let g:au_level = []
so Xscript0
call F0()
call F1()
call F2()
doautocmd User
call assert_equal(['Xscript0', 'Xscript1', 'Xscript2'], g:script_level)
call assert_equal(['Xscript0', 'Xscript1', 'Xscript2'], g:func_level)
call assert_equal(['Xscript2', 'Xscript1', 'Xscript0'], g:au_level)
unlet g:script_level g:func_level
delfunc F0
+66 -8
View File
@@ -384,6 +384,7 @@ let s:filename_checks = {
\ 'omnimark': ['file.xom', 'file.xin'],
\ 'opam': ['opam', 'file.opam', 'file.opam.template'],
\ 'openroad': ['file.or'],
\ 'openscad': ['file.scad'],
\ 'ora': ['file.ora'],
\ 'org': ['file.org', 'file.org_archive'],
\ 'pamconf': ['/etc/pam.conf', '/etc/pam.d/file', 'any/etc/pam.conf', 'any/etc/pam.d/file'],
@@ -464,12 +465,11 @@ let s:filename_checks = {
\ 'sass': ['file.sass'],
\ 'sather': ['file.sa'],
\ 'sbt': ['file.sbt'],
\ 'scala': ['file.scala', 'file.sc'],
\ 'scala': ['file.scala'],
\ 'scheme': ['file.scm', 'file.ss', 'file.sld', 'file.rkt', 'file.rktd', 'file.rktl'],
\ 'scilab': ['file.sci', 'file.sce'],
\ 'screen': ['.screenrc', 'screenrc'],
\ 'sexplib': ['file.sexp'],
\ 'scdoc': ['file.scd'],
\ 'scss': ['file.scss'],
\ 'sd': ['file.sd'],
\ 'sdc': ['file.sdc'],
@@ -517,6 +517,7 @@ let s:filename_checks = {
\ 'stata': ['file.ado', 'file.do', 'file.imata', 'file.mata'],
\ 'stp': ['file.stp'],
\ 'sudoers': ['any/etc/sudoers', 'sudoers.tmp', '/etc/sudoers', 'any/etc/sudoers.d/file'],
\ 'supercollider': ['file.quark'],
\ 'surface': ['file.sface'],
\ 'svg': ['file.svg'],
\ 'svn': ['svn-commitfile.tmp', 'svn-commit-file.tmp', 'svn-commit.tmp'],
@@ -768,7 +769,7 @@ func Test_filetype_indent_off()
endfunc
"""""""""""""""""""""""""""""""""""""""""""""""""
" Tests for specific extentions and filetypes.
" Tests for specific extensions and filetypes.
" Keep sorted.
"""""""""""""""""""""""""""""""""""""""""""""""""
@@ -1497,6 +1498,54 @@ func Test_prg_file()
filetype off
endfunc
" Test dist#ft#FTsc()
func Test_sc_file()
filetype on
" SC file methods are defined 'Class : Method'
call writefile(['SCNvimDocRenderer : SCDocHTMLRenderer {'], 'srcfile.sc')
split srcfile.sc
call assert_equal('supercollider', &filetype)
bwipe!
call delete('srcfile.sc')
" SC classes are defined with '+ Class {}'
call writefile(['+ SCNvim {', '*methodArgs {|method|'], 'srcfile.sc')
split srcfile.sc
call assert_equal('supercollider', &filetype)
bwipe!
call delete('srcfile.sc')
" Some SC class files start with comment and define methods many lines later
call writefile(['// Query', '//Method','^this {'], 'srcfile.sc')
split srcfile.sc
call assert_equal('supercollider', &filetype)
bwipe!
call delete('srcfile.sc')
" Some SC class files put comments between method declaration after class
call writefile(['PingPong {', '//comment','*ar { arg'], 'srcfile.sc')
split srcfile.sc
call assert_equal('supercollider', &filetype)
bwipe!
call delete('srcfile.sc')
filetype off
endfunc
" Test dist#ft#FTscd()
func Test_scd_file()
filetype on
call writefile(['ijq(1)'], 'srcfile.scd')
split srcfile.scd
call assert_equal('scdoc', &filetype)
bwipe!
call delete('srcfile.scd')
filetype off
endfunc
func Test_src_file()
filetype on
@@ -1514,11 +1563,13 @@ func Test_src_file()
bwipe!
call delete('srcfile.Src')
" KRL global def with embedded spaces, file starts with empty line(s).
call writefile(['', 'global def srcfile()'], 'srcfile.SRC')
split srcfile.SRC
call assert_equal('krl', &filetype)
bwipe!
" KRL global deffct with embedded spaces, file starts with empty line(s).
for text in ['global def srcfile()', 'global deffct srcfile()']
call writefile(['', text], 'srcfile.SRC')
split srcfile.SRC
call assert_equal('krl', &filetype, text)
bwipe!
endfor
" User may overrule file inspection
let g:filetype_src = 'src'
@@ -1540,6 +1591,13 @@ func Test_sys_file()
call assert_equal('bat', &filetype)
bwipe!
" Users preference set by g:filetype_sys
let g:filetype_sys = 'sys'
split sysfile.sys
call assert_equal('sys', &filetype)
unlet g:filetype_sys
bwipe!
" RAPID header start with a line containing only "%%%",
" but is not always present.
call writefile(['%%%'], 'sysfile.sys')
+12
View File
@@ -230,4 +230,16 @@ func Test_matchfuzzypos_mbyte()
call assert_equal([['xффйд'], [[2, 3, 4]], [168]], matchfuzzypos(['xффйд'], 'фйд'))
endfunc
" Test for matchfuzzy() with limit
func Test_matchfuzzy_limit()
let x = ['1', '2', '3', '2']
call assert_equal(['2', '2'], x->matchfuzzy('2'))
call assert_equal(['2', '2'], x->matchfuzzy('2', #{}))
call assert_equal(['2', '2'], x->matchfuzzy('2', #{limit: 0}))
call assert_equal(['2'], x->matchfuzzy('2', #{limit: 1}))
call assert_equal(['2', '2'], x->matchfuzzy('2', #{limit: 2}))
call assert_equal(['2', '2'], x->matchfuzzy('2', #{limit: 3}))
call assert_fails("call matchfuzzy(x, '2', #{limit: '2'})", 'E475:')
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+8
View File
@@ -392,8 +392,16 @@ func Test_set_errors()
call assert_fails('set rulerformat=%15(%%', 'E542:')
call assert_fails('set statusline=%$', 'E539:')
call assert_fails('set statusline=%{', 'E540:')
call assert_fails('set statusline=%{%', 'E540:')
call assert_fails('set statusline=%{%}', 'E539:')
call assert_fails('set statusline=%(', 'E542:')
call assert_fails('set statusline=%)', 'E542:')
call assert_fails('set tabline=%$', 'E539:')
call assert_fails('set tabline=%{', 'E540:')
call assert_fails('set tabline=%{%', 'E540:')
call assert_fails('set tabline=%{%}', 'E539:')
call assert_fails('set tabline=%(', 'E542:')
call assert_fails('set tabline=%)', 'E542:')
if has('cursorshape')
" This invalid value for 'guicursor' used to cause Vim to crash.
+11 -1
View File
@@ -1060,7 +1060,17 @@ func Test_hlsearch_cursearch()
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_3', {})
call term_sendkeys(buf, "gg/foo\\nbar\<CR>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line', {})
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_1', {})
call term_sendkeys(buf, ":call setline(1, ['---', 'abcdefg', 'hijkl', '---', 'abcdefg', 'hijkl'])\<CR>")
call term_sendkeys(buf, "gg/efg\\nhij\<CR>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_2', {})
call term_sendkeys(buf, "h\<C-L>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_3', {})
call term_sendkeys(buf, "j\<C-L>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_4', {})
call term_sendkeys(buf, "h\<C-L>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_5', {})
call StopVimInTerminal(buf)
call delete('Xhlsearch_cursearch')
+13
View File
@@ -956,5 +956,18 @@ func Test_syn_include_contains_TOP()
bw!
endfunc
" This was using freed memory
func Test_WinEnter_synstack_synID()
autocmd WinEnter * call synstack(line("."), col("."))
autocmd WinEnter * call synID(line('.'), col('.') - 1, 1)
call setline(1, 'aaaaa')
normal! $
new
close
au! WinEnter
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+88 -3
View File
@@ -642,8 +642,8 @@ enddef
def Test_use_import_in_mapping()
var lines =<< trim END
vim9script
export def Funcx()
g:result = 42
export def Funcx(nr: number)
g:result = nr
enddef
END
writefile(lines, 'XsomeExport.vim')
@@ -651,18 +651,79 @@ def Test_use_import_in_mapping()
vim9script
import './XsomeExport.vim' as some
var Funcy = some.Funcx
nnoremap <F3> :call <sid>Funcy()<cr>
nnoremap <F3> :call <sid>Funcy(42)<cr>
nnoremap <F4> :call <sid>some.Funcx(44)<cr>
END
writefile(lines, 'Xmapscript.vim')
source Xmapscript.vim
feedkeys("\<F3>", "xt")
assert_equal(42, g:result)
feedkeys("\<F4>", "xt")
assert_equal(44, g:result)
unlet g:result
delete('XsomeExport.vim')
delete('Xmapscript.vim')
nunmap <F3>
nunmap <F4>
enddef
def Test_use_relative_autoload_import_in_mapping()
var lines =<< trim END
vim9script
export def Func()
g:result = 42
enddef
END
writefile(lines, 'XrelautoloadExport.vim')
lines =<< trim END
vim9script
import autoload './XrelautoloadExport.vim' as some
nnoremap <F3> :call <SID>some.Func()<CR>
END
writefile(lines, 'Xmapscript.vim')
source Xmapscript.vim
assert_match('\d\+ A: .*XrelautoloadExport.vim', execute('scriptnames')->split("\n")[-1])
feedkeys("\<F3>", "xt")
assert_equal(42, g:result)
unlet g:result
delete('XrelautoloadExport.vim')
delete('Xmapscript.vim')
nunmap <F3>
enddef
def Test_use_autoload_import_in_mapping()
var lines =<< trim END
vim9script
export def Func()
g:result = 49
enddef
END
mkdir('Xdir/autoload', 'p')
writefile(lines, 'Xdir/autoload/XautoloadExport.vim')
var save_rtp = &rtp
exe 'set rtp^=' .. getcwd() .. '/Xdir'
lines =<< trim END
vim9script
import autoload 'XautoloadExport.vim' as some
nnoremap <F3> :call <SID>some.Func()<CR>
END
writefile(lines, 'Xmapscript.vim')
source Xmapscript.vim
assert_match('\d\+ A: .*autoload/XautoloadExport.vim', execute('scriptnames')->split("\n")[-1])
feedkeys("\<F3>", "xt")
assert_equal(49, g:result)
unlet g:result
delete('Xmapscript.vim')
nunmap <F3>
delete('Xdir', 'rf')
&rtp = save_rtp
enddef
def Test_use_import_in_command_completion()
@@ -688,6 +749,30 @@ def Test_use_import_in_command_completion()
delete('Xscript.vim')
enddef
def Test_use_import_with_funcref_in_command_completion()
var lines =<< trim END
vim9script
export def Complete(..._): list<string>
return ['abcd']
enddef
END
writefile(lines, 'Xscript.vim')
lines =<< trim END
vim9script
import './Xscript.vim'
var Ref = Xscript.Complete
exe "command -nargs=1 -complete=customlist," .. expand('<SID>') .. "Ref Cmd echo 'ok'"
feedkeys(":Cmd ab\<Tab>\<C-B>#\<CR>", 'xnt')
assert_equal('#Cmd abcd', @:)
END
v9.CheckScriptSuccess(lines)
delcommand Cmd
delete('Xscript.vim')
enddef
def Test_use_autoload_import_in_insert_completion()
mkdir('Xdir/autoload', 'p')
var save_rtp = &rtp
+1 -1
View File
@@ -3693,7 +3693,7 @@ u_undofile_reset_and_delete(buf_T *buf)
vim_free(file_name);
}
set_option_value((char_u *)"undofile", 0L, NULL, OPT_LOCAL);
set_option_value_give_err((char_u *)"undofile", 0L, NULL, OPT_LOCAL);
}
#endif
+50
View File
@@ -761,6 +761,56 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4768,
/**/
4767,
/**/
4766,
/**/
4765,
/**/
4764,
/**/
4763,
/**/
4762,
/**/
4761,
/**/
4760,
/**/
4759,
/**/
4758,
/**/
4757,
/**/
4756,
/**/
4755,
/**/
4754,
/**/
4753,
/**/
4752,
/**/
4751,
/**/
4750,
/**/
4749,
/**/
4748,
/**/
4747,
/**/
4746,
/**/
4745,
/**/
4744,
/**/
4743,
/**/
+28 -11
View File
@@ -1658,6 +1658,29 @@ exec_command(isn_T *iptr)
return OK;
}
/*
* If script "sid" is not loaded yet then load it now.
* Caller must make sure "sid" is a valid script ID.
* "loaded" is set to TRUE if the script had to be loaded.
* Returns FAIL if loading fails, OK if already loaded or loaded now.
*/
int
may_load_script(int sid, int *loaded)
{
scriptitem_T *si = SCRIPT_ITEM(sid);
if (si->sn_state == SN_STATE_NOT_LOADED)
{
*loaded = TRUE;
if (do_source(si->sn_name, FALSE, DOSO_NONE, NULL) == FAIL)
{
semsg(_(e_cant_open_file_str), si->sn_name);
return FAIL;
}
}
return OK;
}
// used for v_instr of typval of VAR_INSTR
struct instr_S {
ectx_T *instr_ectx;
@@ -2632,18 +2655,12 @@ exec_instructions(ectx_T *ectx)
case ISN_SOURCE:
{
scriptitem_T *si = SCRIPT_ITEM(iptr->isn_arg.number);
int notused;
if (si->sn_state == SN_STATE_NOT_LOADED)
{
SOURCING_LNUM = iptr->isn_lnum;
if (do_source(si->sn_name, FALSE, DOSO_NONE, NULL)
SOURCING_LNUM = iptr->isn_lnum;
if (may_load_script((int)iptr->isn_arg.number, &notused)
== FAIL)
{
semsg(_(e_cant_open_file_str), si->sn_name);
goto on_error;
}
}
goto on_error;
}
break;
@@ -3474,7 +3491,7 @@ exec_instructions(ectx_T *ectx)
goto on_error;
break;
case ISN_UNLETENV:
vim_unsetenv(iptr->isn_arg.unlet.ul_name);
vim_unsetenv_ext(iptr->isn_arg.unlet.ul_name);
break;
case ISN_LOCKUNLOCK:
+2 -1
View File
@@ -136,7 +136,8 @@ ex_vim9script(exarg_T *eap UNUSED)
if (STRCMP(p_cpo, CPO_VIM) != 0)
{
si->sn_save_cpo = vim_strsave(p_cpo);
set_option_value((char_u *)"cpo", 0L, (char_u *)CPO_VIM, OPT_NO_REDRAW);
set_option_value_give_err((char_u *)"cpo",
0L, (char_u *)CPO_VIM, OPT_NO_REDRAW);
}
#else
// No check for this being the first command, it doesn't matter.