Compare commits

...

20 Commits

Author SHA1 Message Date
Bram Moolenaar
447bfba24b patch 8.2.1237: changing 'completepopup' after opening popup has no effect
Problem:    Changing 'completepopup' after opening a popup has no effect. (Jay
            Sitter)
Solution:   Close the popup when the options are changed. (closes #6471)
2020-07-18 16:07:16 +02:00
Bram Moolenaar
e859312e74 patch 8.2.1236: Vim9: a few errors not caught by try/catch
Problem:    Vim9: a few errors not caught by try/catch.
Solution:   Do not bail out if an error is inside try/catch.  Fix that a not
            matching catch doesn't jump to :endtry.
2020-07-18 15:17:02 +02:00
Bram Moolenaar
2764d06ab7 patch 8.2.1235: Not all mouse codes covered by tests
Problem:    Not all mouse codes covered by tests.
Solution:   Add more tests for the mouse. (Yegappan Lakshmanan, closes #6472)
2020-07-18 12:59:19 +02:00
Bram Moolenaar
066e7da3cd patch 8.2.1234: Lua build problem with old compiler
Problem:    Lua build problem with old compiler.
Solution:   Move declarations to start of the block. (Taro Muraoka,
            closes #6477)
2020-07-18 12:50:35 +02:00
Bram Moolenaar
f0b9f43c31 patch 8.2.1233: Vim9: various errors not caught by try/catch
Problem:    Vim9: various errors not caught by try/catch.
Solution:   Do not bail out if an error is inside try/catch.
2020-07-17 23:03:17 +02:00
Bram Moolenaar
b68ced5f07 patch 8.2.1232: MS-Windows GUI: Snap cancelled by split command
Problem:    MS-Windows GUI: Snap cancelled by split command.
Solution:   Do not cancel Snap when splitting a window. (Ken Takata,
            closes #6467)
2020-07-17 22:26:53 +02:00
Bram Moolenaar
945c857844 patch 8.2.1231: MS-Windows: GUI code can be cleaned up
Problem:    MS-Windows: GUI code can be cleaned up.
Solution:   Do a bit of cleaning up. (Ken Takata, closes #6465)
2020-07-17 22:17:03 +02:00
Bram Moolenaar
68d130c618 patch 8.2.1230: Vim9: list index error not caught by try/catch
Problem:    Vim9: list index error not caught by try/catch.
Solution:   Do not bail out if an error is inside try/catch. (closes #6462)
2020-07-17 22:06:44 +02:00
Bram Moolenaar
6e36b1c18e patch 8.2.1229: build error without the eval feature
Problem:    Build error without the eval feature.
Solution:   Declare starts_with_colon. Make function local.
2020-07-17 20:47:51 +02:00
Bram Moolenaar
203ec7760d patch 8.2.1228: scrollbars not flush against the window edges when maximised
Problem:    Scrollbars not flush against the window edges when maximised.
Solution:   Add padding. (Ken Takata, closes #5602, closes #6466)
2020-07-17 20:43:43 +02:00
Bram Moolenaar
f5be8cdb77 patch 8.2.1227: Vim9: allowing both quoted and # comments is confusing
Problem:    Vim9: allowing both quoted and # comments is confusing.
Solution:   Only support # comments in Vim9 script.
2020-07-17 20:36:00 +02:00
Bram Moolenaar
98af99f2d7 patch 8.2.1226: MS-Windows: windows positioning wrong depending on taskbar
Problem:    MS-Windows: windows positioning wrong when the taskbar is placed
            at the top or left of the screen.
Solution:   Use GetWindowRect and MoveWindow APIs. (Yukihiro Nakadaira,
            Ken Takata, closes #6455)
2020-07-16 22:30:31 +02:00
Bram Moolenaar
ee1b93169d patch 8.2.1225: linker errors when building with dynamic Python 3.9
Problem:    Linker errors when building with dynamic Python 3.9.
Solution:   Add #defined items. (closes #6461)
2020-07-16 22:15:53 +02:00
Bram Moolenaar
a90afb9a59 patch 8.2.1224: Vim9: arguments from partial are not used
Problem:    Vim9: arguments from partial are not used.
Solution:   Put the partial arguments on the stack. (closes #6460)
2020-07-15 22:38:56 +02:00
Bram Moolenaar
e30f64b4b5 patch 8.2.1223: Vim9: invalid type error for function default value
Problem:    Vim9: invalid type error for function default value.
Solution:   Use right argument index. (closes #6458)
2020-07-15 19:48:20 +02:00
Bram Moolenaar
657a826c07 patch 8.2.1222: using valgrind in Vim command started by test doesn't work
Problem:    When using valgrind a Vim command started by a test uses the same
            log file name which gets overwritten.
Solution:   Fix regexp to rename the log file.
2020-07-15 18:29:18 +02:00
Bram Moolenaar
02f9e6a60f patch 8.2.1221: memory leak when updating popup window
Problem:    Memory leak when updating popup window.
Solution:   Clear search highlighting.
2020-07-15 18:27:08 +02:00
Bram Moolenaar
452143c6bf patch 8.2.1220: memory access error when dragging a popup window
Problem:    memory access error when dragging a popup window over a buffer
            with folding.
Solution:   Avoid going over the end of the cache. (closes #6438)
2020-07-15 17:38:21 +02:00
Bram Moolenaar
5966ea105e patch 8.2.1219: symlink not followed if dirname ends in //
Problem:    Symlink not followed if dirname ends in //.
Solution:   Resolve symlink earlier. (Tomáš Janoušek, closes #6454)
2020-07-15 15:30:05 +02:00
Bram Moolenaar
3d48e25dcb patch 8.2.1218: Vim9: cannot use 'text'->func()
Problem:    Vim9: cannot use 'text'->func().
Solution:   Recognize string at start of command.
2020-07-15 14:15:52 +02:00
42 changed files with 1187 additions and 298 deletions

View File

@@ -1951,9 +1951,11 @@ A jump table for the options with a short description can be found at |Q_op|.
{not available when compiled without the |+textprop|
or |+quickfix| feature}
When 'completeopt' contains "popup" then this option is used for the
properties of the info popup when it is created. You can also use
|popup_findinfo()| and then set properties for an existing info popup
with |popup_setoptions()|. See |complete-popup|.
properties of the info popup when it is created. If an info popup
window already exists it is closed, so that the option value is
applied when it is created again.
You can also use |popup_findinfo()| and then set properties for an
existing info popup with |popup_setoptions()|. See |complete-popup|.
*'concealcursor'* *'cocu'*

View File

@@ -1,4 +1,4 @@
*vim9.txt* For Vim version 8.2. Last change: 2020 Jul 10
*vim9.txt* For Vim version 8.2. Last change: 2020 Jul 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -64,20 +64,24 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
Comments starting with # ~
In Vim script comments start with double quote. That can also be the start of
a string, thus in many places it cannot be used. In Vim9 script a comment
normally starts with #. In Vi this is a command to list text with numbers,
but you can also use `:number` for that. >
In legacy Vim script comments start with double quote. In Vim9 script
comments start with #. >
# declarations
let count = 0 # number of occurrences
To improve readability there must be a space between the command and the #
The reason is that a double quote can also be the start of a string. In many
places, especially halfway an expression with a line break, it's hard to tell
what the meaning is. To avoid confusion only # comments are recognized.
This is the same as in shell scripts and Python programs.
In Vi # is a command to list text with numbers. In Vim9 script you can use
`:number` for that. >
101number
To improve readability there must be a space between a command and the #
that starts a comment. Note that #{ is the start of a dictionary, therefore
it cannot start a comment.
Since Vim9 script allows for line breaks in many places, the double quoted
comment also cannot be used at the start of a line after an expression. To
avoid confusion it is best to only use # comments.
Vim9 functions ~
@@ -400,6 +404,7 @@ The boolean operators "||" and "&&" do not change the value: >
0 || '' == ''
8 && 2 == 2
0 && 2 == 0
2 && 0 == 0
[] && 2 == []
When using `..` for string concatenation the arguments are always converted to
@@ -418,13 +423,15 @@ be made. Here is a summary of what might be unexpected.
Ex command ranges need to be prefixed with a colon. >
-> " legacy Vim: shifts the previous line to the right
->func() " Vim9: method call
->func() " Vim9: method call in continuation line
:-> " Vim9: shifts the previous line to the right
%s/a/b " legacy Vim: substitute on all lines
x = alongname
% another " Vim9: line continuation without a backslash
:%s/a/b " Vim9: substitute on all lines
'text'->func() " Vim9: method call
:'t " legacy Vim: jump to mark m
Functions defined with `:def` compile the whole function. Legacy functions
can bail out, and the following lines are not parsed: >

View File

@@ -1649,6 +1649,16 @@ current_tab_nr(tabpage_T *tab)
return nr;
}
static int
comment_start(char_u *p, int starts_with_colon UNUSED)
{
#ifdef FEAT_EVAL
if (in_vim9script())
return p[0] == '#' && p[1] != '{' && !starts_with_colon;
#endif
return *p == '"';
}
# define CURRENT_WIN_NR current_win_nr(curwin)
# define LAST_WIN_NR current_win_nr(NULL)
# define CURRENT_TAB_NR current_tab_nr(curtab)
@@ -1698,8 +1708,10 @@ do_one_cmd(
int save_reg_executing = reg_executing;
int ni; // set when Not Implemented
char_u *cmd;
int starts_with_colon = FALSE;
#ifdef FEAT_EVAL
int starts_with_colon;
int starts_with_quote;
int vim9script = in_vim9script();
#endif
CLEAR_FIELD(ea);
@@ -1760,12 +1772,16 @@ do_one_cmd(
* We need the command to know what kind of range it uses.
*/
cmd = ea.cmd;
ea.cmd = skip_range(ea.cmd, NULL);
#ifdef FEAT_EVAL
starts_with_quote = vim9script && *ea.cmd == '\'';
if (!starts_with_quote)
#endif
ea.cmd = skip_range(ea.cmd, NULL);
if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
ea.cmd = skipwhite(ea.cmd + 1);
#ifdef FEAT_EVAL
if (in_vim9script() && !starts_with_colon)
if (vim9script && !starts_with_colon)
{
if (ea.cmd > cmd)
{
@@ -1859,8 +1875,11 @@ do_one_cmd(
}
ea.cmd = cmd;
if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL)
goto doend;
#ifdef FEAT_EVAL
if (!starts_with_quote)
#endif
if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL)
goto doend;
/*
* 5. Parse the command.
@@ -1877,12 +1896,8 @@ do_one_cmd(
* If we got a line, but no command, then go to the line.
* If we find a '|' or '\n' we set ea.nextcmd.
*/
if (*ea.cmd == NUL || *ea.cmd == '"'
#ifdef FEAT_EVAL
|| (*ea.cmd == '#' && ea.cmd[1] != '{'
&& !starts_with_colon && in_vim9script())
#endif
|| (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL)
if (*ea.cmd == NUL || comment_start(ea.cmd, starts_with_colon)
|| (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL)
{
/*
* strange vi behaviour:
@@ -2216,7 +2231,7 @@ do_one_cmd(
ea.do_ecmd_cmd = getargcmd(&ea.arg);
/*
* Check for '|' to separate commands and '"' to start comments.
* Check for '|' to separate commands and '"' or '#' to start comments.
* Don't do this for ":read !cmd" and ":write !cmd".
*/
if ((ea.argt & EX_TRLBAR) && !ea.usefilter)
@@ -2650,7 +2665,8 @@ doend:
int
parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only)
{
char_u *p;
char_u *p;
int starts_with_colon = FALSE;
CLEAR_FIELD(cmdmod);
eap->verbose_save = -1;
@@ -2660,7 +2676,11 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only)
for (;;)
{
while (*eap->cmd == ' ' || *eap->cmd == '\t' || *eap->cmd == ':')
{
if (*eap->cmd == ':')
starts_with_colon = TRUE;
++eap->cmd;
}
// in ex mode, an empty line works like :+
if (*eap->cmd == NUL && exmode_active
@@ -2674,7 +2694,7 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only)
}
// ignore comment and empty lines
if (*eap->cmd == '"')
if (comment_start(eap->cmd, starts_with_colon))
return FAIL;
if (*eap->cmd == NUL)
{
@@ -3223,26 +3243,34 @@ find_ex_command(
* "lvar = value", "lvar(arg)", "[1, 2 3]->Func()"
*/
p = eap->cmd;
if (lookup != NULL && (*p == '(' || *p == '{'
|| ((p = to_name_const_end(eap->cmd)) > eap->cmd && *p != NUL)
|| *p == '['))
if (lookup != NULL && (vim_strchr((char_u *)"{('[", *p) != NULL
|| ((p = to_name_const_end(eap->cmd)) > eap->cmd
&& *p != NUL)))
{
int oplen;
int heredoc;
// "funcname(" is always a function call.
// "varname[]" is an expression.
// "g:varname" is an expression.
// "varname->expr" is an expression.
// "varname.expr" is an expression.
// "(..." is an expression.
// "{..." is an dict expression.
if (*p == '('
|| *p == '{'
|| (*p == '[' && p > eap->cmd)
|| p[1] == ':'
|| (*p == '-' && p[1] == '>')
|| (*p == '.' && ASCII_ISALPHA(p[1])))
if (
// "(..." is an expression.
// "funcname(" is always a function call.
*p == '('
|| (p == eap->cmd
? (
// "{..." is an dict expression.
*eap->cmd == '{'
// "'string'->func()" is an expression.
|| *eap->cmd == '\''
// "g:varname" is an expression.
|| eap->cmd[1] == ':'
)
: (
// "varname[]" is an expression.
*p == '['
// "varname->func()" is an expression.
|| (*p == '-' && p[1] == '>')
// "varname.expr" is an expression.
|| (*p == '.' && ASCII_ISALPHA(p[1]))
)))
{
eap->cmdidx = CMD_eval;
return eap->cmd;
@@ -4504,14 +4532,20 @@ separate_nextcmd(exarg_T *eap)
// Check for '"': start of comment or '|': next command
// :@" and :*" do not start a comment!
// :redir @" doesn't either.
else if ((*p == '"' && !(eap->argt & EX_NOTRLCOM)
&& ((eap->cmdidx != CMD_at && eap->cmdidx != CMD_star)
|| p != eap->arg)
&& (eap->cmdidx != CMD_redir
|| p != eap->arg + 1 || p[-1] != '@'))
else if ((*p == '"'
#ifdef FEAT_EVAL
|| (*p == '#' && in_vim9script()
&& p[1] != '{' && p > eap->cmd && VIM_ISWHITE(p[-1]))
&& !in_vim9script()
#endif
&& !(eap->argt & EX_NOTRLCOM)
&& ((eap->cmdidx != CMD_at && eap->cmdidx != CMD_star)
|| p != eap->arg)
&& (eap->cmdidx != CMD_redir
|| p != eap->arg + 1 || p[-1] != '@'))
#ifdef FEAT_EVAL
|| (*p == '#'
&& in_vim9script()
&& p[1] != '{'
&& p > eap->cmd && VIM_ISWHITE(p[-1]))
#endif
|| *p == '|' || *p == '\n')
{
@@ -4850,11 +4884,13 @@ ex_blast(exarg_T *eap)
int
ends_excmd(int c)
{
int comment_char = '"';
#ifdef FEAT_EVAL
if (c == '#')
return in_vim9script();
if (in_vim9script())
comment_char = '#';
#endif
return (c == NUL || c == '|' || c == '"' || c == '\n');
return (c == NUL || c == '|' || c == comment_char || c == '\n');
}
/*
@@ -4866,11 +4902,14 @@ ends_excmd2(char_u *cmd_start UNUSED, char_u *cmd)
{
int c = *cmd;
if (c == NUL || c == '|' || c == '\n')
return TRUE;
#ifdef FEAT_EVAL
if (c == '#' && cmd[1] != '{' && (cmd == cmd_start || VIM_ISWHITE(cmd[-1])))
return in_vim9script();
if (in_vim9script())
return c == '#' && cmd[1] != '{'
&& (cmd == cmd_start || VIM_ISWHITE(cmd[-1]));
#endif
return (c == NUL || c == '|' || c == '"' || c == '\n');
return c == '"';
}
#if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) || defined(FEAT_EVAL) \
@@ -7012,7 +7051,12 @@ ex_wincmd(exarg_T *eap)
eap->nextcmd = check_nextcmd(p);
p = skipwhite(p);
if (*p != NUL && *p != '"' && eap->nextcmd == NULL)
if (*p != NUL && *p != (
#ifdef FEAT_EVAL
in_vim9script() ? '#' :
#endif
'"')
&& eap->nextcmd == NULL)
emsg(_(e_invarg));
else if (!eap->skip)
{

View File

@@ -1418,11 +1418,13 @@ gui_position_components(int total_width UNUSED)
if (gui.which_scrollbars[SBAR_BOTTOM])
gui_mch_set_scrollbar_pos(&gui.bottom_sbar,
text_area_x,
text_area_y + text_area_height,
text_area_y + text_area_height
+ gui_mch_get_scrollbar_ypadding(),
text_area_width,
gui.scrollbar_height);
gui.left_sbar_x = 0;
gui.right_sbar_x = text_area_x + text_area_width;
gui.right_sbar_x = text_area_x + text_area_width
+ gui_mch_get_scrollbar_xpadding();
--hold_gui_events;
}

View File

@@ -1889,6 +1889,22 @@ gui_mch_set_scrollbar_pos(
XtManageChild(sb->id);
}
int
gui_mch_get_scrollbar_xpadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
int
gui_mch_get_scrollbar_ypadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
void
gui_mch_enable_scrollbar(scrollbar_T *sb, int flag)
{

View File

@@ -1008,6 +1008,22 @@ gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h)
gtk_form_move_resize(GTK_FORM(gui.formwin), sb->id, x, y, w, h);
}
int
gui_mch_get_scrollbar_xpadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
int
gui_mch_get_scrollbar_ypadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
/*
* Take action upon scrollbar dragging.
*/

View File

@@ -3665,6 +3665,22 @@ gui_mch_set_scrollbar_pos(
}
}
int
gui_mch_get_scrollbar_xpadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
int
gui_mch_get_scrollbar_ypadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
void
gui_mch_create_scrollbar(
scrollbar_T *sb,

View File

@@ -4992,6 +4992,22 @@ gui_mch_set_scrollbar_pos(
#endif
}
int
gui_mch_get_scrollbar_xpadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
int
gui_mch_get_scrollbar_ypadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
void
gui_mch_create_scrollbar(
scrollbar_T *sb,

View File

@@ -1743,6 +1743,22 @@ gui_mch_set_scrollbar_pos(
}
}
int
gui_mch_get_scrollbar_xpadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
int
gui_mch_get_scrollbar_ypadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
void
gui_mch_enable_scrollbar(scrollbar_T *sb, int flag)
{

View File

@@ -1758,6 +1758,22 @@ gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h)
PtSetResource(sb->id, Pt_ARG_AREA, &area, 0);
}
int
gui_mch_get_scrollbar_xpadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
int
gui_mch_get_scrollbar_ypadding(void)
{
// TODO: Calculate the padding for adjust scrollbar position when the
// Window is maximized.
return 0;
}
void
gui_mch_create_scrollbar(scrollbar_T *sb, int orient)
{

View File

@@ -240,6 +240,7 @@ gui_mch_set_rendering_options(char_u *s)
# define CONST
# define FAR
# define NEAR
# define WINAPI
# undef _cdecl
# define _cdecl
typedef int BOOL;
@@ -320,9 +321,6 @@ static int s_findrep_is_find; // TRUE for find dialog, FALSE
// for find/replace dialog
#endif
#if !defined(FEAT_GUI)
static
#endif
HWND s_hwnd = NULL;
static HDC s_hdc = NULL;
static HBRUSH s_brush = NULL;
@@ -389,7 +387,7 @@ directx_binddc(void)
#endif
// use of WindowProc depends on Global IME
#define MyWindowProc vim_WindowProc
static LRESULT WINAPI MyWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
extern int current_font_height; // this is in os_mswin.c
@@ -1259,12 +1257,8 @@ _TextAreaWndProc(
}
}
#ifdef PROTO
typedef int WINAPI;
#endif
LRESULT WINAPI
vim_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
static LRESULT WINAPI
MyWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
#ifdef GLOBAL_IME
return global_ime_DefWindowProc(hwnd, message, wParam, lParam);
@@ -1412,6 +1406,34 @@ gui_mch_set_scrollbar_pos(
SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
}
int
gui_mch_get_scrollbar_xpadding(void)
{
RECT rcTxt, rcWnd;
int xpad;
GetWindowRect(s_textArea, &rcTxt);
GetWindowRect(s_hwnd, &rcWnd);
xpad = rcWnd.right - rcTxt.right - gui.scrollbar_width
- GetSystemMetrics(SM_CXFRAME)
- GetSystemMetrics(SM_CXPADDEDBORDER);
return (xpad < 0) ? 0 : xpad;
}
int
gui_mch_get_scrollbar_ypadding(void)
{
RECT rcTxt, rcWnd;
int ypad;
GetWindowRect(s_textArea, &rcTxt);
GetWindowRect(s_hwnd, &rcWnd);
ypad = rcWnd.bottom - rcTxt.bottom - gui.scrollbar_height
- GetSystemMetrics(SM_CYFRAME)
- GetSystemMetrics(SM_CXPADDEDBORDER);
return (ypad < 0) ? 0 : ypad;
}
void
gui_mch_create_scrollbar(
scrollbar_T *sb,
@@ -1429,7 +1451,7 @@ gui_mch_create_scrollbar(
/*
* Find the scrollbar with the given hwnd.
*/
static scrollbar_T *
static scrollbar_T *
gui_mswin_find_scrollbar(HWND hwnd)
{
win_T *wp;
@@ -3320,19 +3342,33 @@ gui_mch_init_font(char_u *font_name, int fontset UNUSED)
/*
* Return TRUE if the GUI window is maximized, filling the whole screen.
* Also return TRUE if the window is snapped.
*/
int
gui_mch_maximized(void)
{
WINDOWPLACEMENT wp;
RECT rc;
wp.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(s_hwnd, &wp))
return wp.showCmd == SW_SHOWMAXIMIZED
{
if (wp.showCmd == SW_SHOWMAXIMIZED
|| (wp.showCmd == SW_SHOWMINIMIZED
&& wp.flags == WPF_RESTORETOMAXIMIZED);
&& wp.flags == WPF_RESTORETOMAXIMIZED))
return TRUE;
if (wp.showCmd == SW_SHOWMINIMIZED)
return FALSE;
return 0;
// Assume the window is snapped when the sizes from two APIs differ.
GetWindowRect(s_hwnd, &rc);
if ((rc.right - rc.left !=
wp.rcNormalPosition.right - wp.rcNormalPosition.left)
|| (rc.bottom - rc.top !=
wp.rcNormalPosition.bottom - wp.rcNormalPosition.top))
return TRUE;
}
return FALSE;
}
/*
@@ -3796,10 +3832,6 @@ _OnScroll(
# include "xpm_w32.h"
#endif
#ifdef PROTO
# define WINAPI
#endif
#ifdef __MINGW32__
/*
* Add a lot of missing defines.
@@ -5395,28 +5427,21 @@ gui_mch_set_shellsize(
int direction)
{
RECT workarea_rect;
RECT window_rect;
int win_width, win_height;
WINDOWPLACEMENT wndpl;
// Try to keep window completely on screen.
// Get position of the screen work area. This is the part that is not
// used by the taskbar or appbars.
get_work_area(&workarea_rect);
// Get current position of our window. Note that the .left and .top are
// relative to the work area.
wndpl.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(s_hwnd, &wndpl);
// Resizing a maximized window looks very strange, unzoom it first.
// But don't do it when still starting up, it may have been requested in
// the shortcut.
if (wndpl.showCmd == SW_SHOWMAXIMIZED && starting == 0)
{
if (IsZoomed(s_hwnd) && starting == 0)
ShowWindow(s_hwnd, SW_SHOWNORMAL);
// Need to get the settings of the normal window.
GetWindowPlacement(s_hwnd, &wndpl);
}
GetWindowRect(s_hwnd, &window_rect);
// compute the size of the outside of the window
win_width = width + (GetSystemMetrics(SM_CXFRAME) +
@@ -5432,34 +5457,24 @@ gui_mch_set_shellsize(
// The following should take care of keeping Vim on the same monitor, no
// matter if the secondary monitor is left or right of the primary
// monitor.
wndpl.rcNormalPosition.right = wndpl.rcNormalPosition.left + win_width;
wndpl.rcNormalPosition.bottom = wndpl.rcNormalPosition.top + win_height;
window_rect.right = window_rect.left + win_width;
window_rect.bottom = window_rect.top + win_height;
// If the window is going off the screen, move it on to the screen.
if ((direction & RESIZE_HOR)
&& wndpl.rcNormalPosition.right > workarea_rect.right)
OffsetRect(&wndpl.rcNormalPosition,
workarea_rect.right - wndpl.rcNormalPosition.right, 0);
if ((direction & RESIZE_HOR) && window_rect.right > workarea_rect.right)
OffsetRect(&window_rect, workarea_rect.right - window_rect.right, 0);
if ((direction & RESIZE_HOR)
&& wndpl.rcNormalPosition.left < workarea_rect.left)
OffsetRect(&wndpl.rcNormalPosition,
workarea_rect.left - wndpl.rcNormalPosition.left, 0);
if ((direction & RESIZE_HOR) && window_rect.left < workarea_rect.left)
OffsetRect(&window_rect, workarea_rect.left - window_rect.left, 0);
if ((direction & RESIZE_VERT)
&& wndpl.rcNormalPosition.bottom > workarea_rect.bottom)
OffsetRect(&wndpl.rcNormalPosition,
0, workarea_rect.bottom - wndpl.rcNormalPosition.bottom);
if ((direction & RESIZE_VERT) && window_rect.bottom > workarea_rect.bottom)
OffsetRect(&window_rect, 0, workarea_rect.bottom - window_rect.bottom);
if ((direction & RESIZE_VERT)
&& wndpl.rcNormalPosition.top < workarea_rect.top)
OffsetRect(&wndpl.rcNormalPosition,
0, workarea_rect.top - wndpl.rcNormalPosition.top);
if ((direction & RESIZE_VERT) && window_rect.top < workarea_rect.top)
OffsetRect(&window_rect, 0, workarea_rect.top - window_rect.top);
// set window position - we should use SetWindowPlacement rather than
// SetWindowPos as the MSDN docs say the coord systems returned by
// these two are not compatible.
SetWindowPlacement(s_hwnd, &wndpl);
MoveWindow(s_hwnd, window_rect.left, window_rect.top,
win_width, win_height, TRUE);
SetActiveWindow(s_hwnd);
SetFocus(s_hwnd);

View File

@@ -626,8 +626,10 @@ luaV_totypval(lua_State *L, int pos, typval_T *tv)
case LUA_TFUNCTION:
{
char_u *name;
luaV_CFuncState *state;
lua_pushvalue(L, pos);
luaV_CFuncState *state = ALLOC_CLEAR_ONE(luaV_CFuncState);
state = ALLOC_CLEAR_ONE(luaV_CFuncState);
state->lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX);
state->L = L;
state->lua_tableref = LUA_NOREF;
@@ -639,14 +641,17 @@ luaV_totypval(lua_State *L, int pos, typval_T *tv)
}
case LUA_TTABLE:
{
int lua_tableref;
lua_pushvalue(L, pos);
int lua_tableref = luaL_ref(L, LUA_REGISTRYINDEX);
lua_tableref = luaL_ref(L, LUA_REGISTRYINDEX);
if (lua_getmetatable(L, pos)) {
lua_getfield(L, -1, LUA___CALL);
if (lua_isfunction(L, -1)) {
char_u *name;
int lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX);
luaV_CFuncState *state = ALLOC_CLEAR_ONE(luaV_CFuncState);
state->lua_funcref = lua_funcref;
state->L = L;
state->lua_tableref = lua_tableref;
@@ -703,6 +708,7 @@ luaV_totypval(lua_State *L, int pos, typval_T *tv)
if (lua_rawequal(L, -1, -5))
{
luaV_Funcref *f = (luaV_Funcref *) p;
func_ref(f->name);
tv->v_type = VAR_FUNC;
tv->vval.v_string = vim_strsave(f->name);

View File

@@ -203,6 +203,9 @@ typedef PySliceObject PySliceObject_T;
# define PySys_GetObject py3_PySys_GetObject
# define PySys_SetArgv py3_PySys_SetArgv
# define PyType_Ready py3_PyType_Ready
# if PY_VERSION_HEX >= 0x030900b0
# define PyType_GetFlags py3_PyType_GetFlags
# endif
#undef Py_BuildValue
# define Py_BuildValue py3_Py_BuildValue
# define Py_SetPythonHome py3_Py_SetPythonHome
@@ -233,6 +236,9 @@ typedef PySliceObject PySliceObject_T;
# define PyBytes_FromString py3_PyBytes_FromString
# undef PyBytes_FromStringAndSize
# define PyBytes_FromStringAndSize py3_PyBytes_FromStringAndSize
# if defined(Py_DEBUG) || PY_VERSION_HEX >= 0x030900b0
# define _Py_Dealloc py3__Py_Dealloc
# endif
# define PyFloat_FromDouble py3_PyFloat_FromDouble
# define PyFloat_AsDouble py3_PyFloat_AsDouble
# define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr
@@ -247,7 +253,6 @@ typedef PySliceObject PySliceObject_T;
# ifdef Py_DEBUG
# define _Py_NegativeRefcount py3__Py_NegativeRefcount
# define _Py_RefTotal (*py3__Py_RefTotal)
# define _Py_Dealloc py3__Py_Dealloc
# define PyModule_Create2TraceRefs py3_PyModule_Create2TraceRefs
# else
# define PyModule_Create2 py3_PyModule_Create2
@@ -287,6 +292,10 @@ typedef PySliceObject PySliceObject_T;
# define PyObject_NEW(type, typeobj) \
( (type *) PyObject_Init( \
(PyObject *) _PyObject_DebugMalloc( _PyObject_SIZE(typeobj) ), (typeobj)) )
# elif PY_VERSION_HEX >= 0x030900b0
# undef PyObject_NEW
# define PyObject_NEW(type, typeobj) \
((type *)py3__PyObject_New(typeobj))
# endif
/*
@@ -352,6 +361,9 @@ static PyObject* (*py3_PyObject_Repr)(PyObject *);
static PyObject* (*py3_PyObject_GetItem)(PyObject *, PyObject *);
static int (*py3_PyObject_IsTrue)(PyObject *);
static PyObject* (*py3_Py_BuildValue)(char *, ...);
# if PY_VERSION_HEX >= 0x030900b0
static int (*py3_PyType_GetFlags)(PyTypeObject *o);
# endif
static int (*py3_PyType_Ready)(PyTypeObject *type);
static int (*py3_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
static PyObject* (*py3_PyUnicode_FromString)(const char *u);
@@ -396,6 +408,12 @@ static char* (*py3_PyBytes_AsString)(PyObject *bytes);
static int (*py3_PyBytes_AsStringAndSize)(PyObject *bytes, char **buffer, Py_ssize_t *length);
static PyObject* (*py3_PyBytes_FromString)(char *str);
static PyObject* (*py3_PyBytes_FromStringAndSize)(char *str, Py_ssize_t length);
# if defined(Py_DEBUG) || PY_VERSION_HEX >= 0x030900b0
static void (*py3__Py_Dealloc)(PyObject *obj);
# endif
# if PY_VERSION_HEX >= 0x030900b0
static PyObject* (*py3__PyObject_New)(PyTypeObject *);
# endif
static PyObject* (*py3_PyFloat_FromDouble)(double num);
static double (*py3_PyFloat_AsDouble)(PyObject *);
static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name);
@@ -414,7 +432,6 @@ static void* (*py3_PyCapsule_GetPointer)(PyObject *, char *);
# ifdef Py_DEBUG
static void (*py3__Py_NegativeRefcount)(const char *fname, int lineno, PyObject *op);
static Py_ssize_t* py3__Py_RefTotal;
static void (*py3__Py_Dealloc)(PyObject *obj);
static PyObject* (*py3_PyModule_Create2TraceRefs)(struct PyModuleDef* module, int module_api_version);
# else
static PyObject* (*py3_PyModule_Create2)(struct PyModuleDef* module, int module_api_version);
@@ -525,6 +542,9 @@ static struct
{"PyObject_IsTrue", (PYTHON_PROC*)&py3_PyObject_IsTrue},
{"PyLong_FromLong", (PYTHON_PROC*)&py3_PyLong_FromLong},
{"PyDict_New", (PYTHON_PROC*)&py3_PyDict_New},
# if PY_VERSION_HEX >= 0x030900b0
{"PyType_GetFlags", (PYTHON_PROC*)&py3_PyType_GetFlags},
# endif
{"PyType_Ready", (PYTHON_PROC*)&py3_PyType_Ready},
{"PyDict_SetItemString", (PYTHON_PROC*)&py3_PyDict_SetItemString},
{"PyLong_AsLong", (PYTHON_PROC*)&py3_PyLong_AsLong},
@@ -562,6 +582,12 @@ static struct
{"PyBytes_AsStringAndSize", (PYTHON_PROC*)&py3_PyBytes_AsStringAndSize},
{"PyBytes_FromString", (PYTHON_PROC*)&py3_PyBytes_FromString},
{"PyBytes_FromStringAndSize", (PYTHON_PROC*)&py3_PyBytes_FromStringAndSize},
# if defined(Py_DEBUG) || PY_VERSION_HEX >= 0x030900b0
{"_Py_Dealloc", (PYTHON_PROC*)&py3__Py_Dealloc},
# endif
# if PY_VERSION_HEX >= 0x030900b0
{"_PyObject_New", (PYTHON_PROC*)&py3__PyObject_New},
# endif
{"PyFloat_FromDouble", (PYTHON_PROC*)&py3_PyFloat_FromDouble},
{"PyFloat_AsDouble", (PYTHON_PROC*)&py3_PyFloat_AsDouble},
{"PyObject_GenericGetAttr", (PYTHON_PROC*)&py3_PyObject_GenericGetAttr},
@@ -578,7 +604,6 @@ static struct
# ifdef Py_DEBUG
{"_Py_NegativeRefcount", (PYTHON_PROC*)&py3__Py_NegativeRefcount},
{"_Py_RefTotal", (PYTHON_PROC*)&py3__Py_RefTotal},
{"_Py_Dealloc", (PYTHON_PROC*)&py3__Py_Dealloc},
{"PyModule_Create2TraceRefs", (PYTHON_PROC*)&py3_PyModule_Create2TraceRefs},
# else
{"PyModule_Create2", (PYTHON_PROC*)&py3_PyModule_Create2},
@@ -634,6 +659,15 @@ py3__Py_XDECREF(PyObject *op)
# define Py_XDECREF(op) py3__Py_XDECREF(_PyObject_CAST(op))
# endif
# if PY_VERSION_HEX >= 0x030900b0
static inline int
py3_PyType_HasFeature(PyTypeObject *type, unsigned long feature)
{
return ((PyType_GetFlags(type) & feature) != 0);
}
# define PyType_HasFeature(t,f) py3_PyType_HasFeature(t,f)
# endif
/*
* Load library and get all pointers.
* Parameter 'libname' provides name of DLL.

View File

@@ -3287,10 +3287,12 @@ ml_append_buf(
#endif
/*
* Replace line lnum, with buffering, in current buffer.
* Replace line "lnum", with buffering, in current buffer.
*
* If "copy" is TRUE, make a copy of the line, otherwise the line has been
* copied to allocated memory already.
* If "copy" is FALSE the "line" may be freed to add text properties!
* Do not use it after calling ml_replace().
*
* Check: The caller of this function should probably also call
* changed_lines(), unless update_screen(NOT_VALID) is used.
@@ -4366,6 +4368,11 @@ makeswapname(
char_u *fname_res = fname;
#ifdef HAVE_READLINK
char_u fname_buf[MAXPATHL];
// Expand symlink in the file name, so that we put the swap file with the
// actual file instead of with the symlink.
if (resolve_symlink(fname, fname_buf) == OK)
fname_res = fname_buf;
#endif
#if defined(UNIX) || defined(MSWIN) // Need _very_ long file names
@@ -4375,7 +4382,7 @@ makeswapname(
if (after_pathsep(dir_name, s) && len > 1 && s[-1] == s[-2])
{ // Ends with '//', Use Full path
r = NULL;
if ((s = make_percent_swname(dir_name, fname)) != NULL)
if ((s = make_percent_swname(dir_name, fname_res)) != NULL)
{
r = modname(s, (char_u *)".swp", FALSE);
vim_free(s);
@@ -4384,13 +4391,6 @@ makeswapname(
}
#endif
#ifdef HAVE_READLINK
// Expand symlink in the file name, so that we put the swap file with the
// actual file instead of with the symlink.
if (resolve_symlink(fname, fname_buf) == OK)
fname_res = fname_buf;
#endif
r = buf_modname(
(buf->b_p_sn || buf->b_shortname),
fname_res,

View File

@@ -2839,10 +2839,10 @@ check_termcode_mouse(
/*
* Compute the buffer line position from the screen position "rowp" / "colp" in
* window "win".
* "plines_cache" can be NULL (no cache) or an array with "win->w_height"
* entries that caches the plines_win() result from a previous call. Entry is
* zero if not computed yet. There must be no text or setting changes since
* the entry is put in the cache.
* "plines_cache" can be NULL (no cache) or an array with "Rows" entries that
* caches the plines_win() result from a previous call. Entry is zero if not
* computed yet. There must be no text or setting changes since the entry is
* put in the cache.
* Returns TRUE if the position is below the last line.
*/
int
@@ -2871,7 +2871,10 @@ mouse_comp_pos(
{
int cache_idx = lnum - win->w_topline;
if (plines_cache != NULL && plines_cache[cache_idx] > 0)
// Only "Rows" lines are cached, with folding we'll run out of entries
// and use the slow way.
if (plines_cache != NULL && cache_idx < Rows
&& plines_cache[cache_idx] > 0)
count = plines_cache[cache_idx];
else
{
@@ -2892,7 +2895,7 @@ mouse_comp_pos(
else
#endif
count = plines_win(win, lnum, TRUE);
if (plines_cache != NULL)
if (plines_cache != NULL && cache_idx < Rows)
plines_cache[cache_idx] = count;
}
if (count > row)

View File

@@ -2249,6 +2249,8 @@ did_set_string_option(
{
if (parse_completepopup(NULL) == FAIL)
errmsg = e_invarg;
else
popup_close_info();
}
# endif
#endif

View File

@@ -3855,6 +3855,11 @@ update_popups(void (*win_update)(win_T *wp))
// Back to the normal zindex.
screen_zindex = 0;
}
#if defined(FEAT_SEARCH_EXTRA)
// In case win_update() called start_search_hl().
end_search_hl();
#endif
}
/*
@@ -4026,6 +4031,18 @@ popup_hide_info(void)
if (wp != NULL)
popup_hide(wp);
}
/*
* Close any info popup.
*/
void
popup_close_info(void)
{
win_T *wp = popup_find_info_window();
if (wp != NULL)
popup_close_with_retval(wp, -1);
}
#endif
/*

View File

@@ -21,6 +21,8 @@ void gui_mch_show_popupmenu(vimmenu_T *menu);
void gui_mch_def_colors(void);
void gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max);
void gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h);
int gui_mch_get_scrollbar_xpadding(void);
int gui_mch_get_scrollbar_ypadding(void);
void gui_mch_enable_scrollbar(scrollbar_T *sb, int flag);
void gui_mch_create_scrollbar(scrollbar_T *sb, int orient);
void gui_mch_destroy_scrollbar(scrollbar_T *sb);

View File

@@ -9,6 +9,8 @@ void gui_mch_menu_set_tip(vimmenu_T *menu);
void gui_mch_destroy_menu(vimmenu_T *menu);
void gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max);
void gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h);
int gui_mch_get_scrollbar_xpadding(void);
int gui_mch_get_scrollbar_ypadding(void);
void gui_mch_create_scrollbar(scrollbar_T *sb, int orient);
void gui_mch_destroy_scrollbar(scrollbar_T *sb);
char_u *gui_mch_browse(int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter);

View File

@@ -33,6 +33,8 @@ void gui_mch_enable_scrollbar(scrollbar_T *sb, int flag);
void gui_mch_set_scrollbar_thumb(scrollbar_T *sb, int val, int size, int max);
void gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h);
int gui_mch_get_scrollbar_xpadding(void);
int gui_mch_get_scrollbar_ypadding(void);
void gui_mch_create_scrollbar(scrollbar_T *sb, int orient);
void gui_mch_destroy_scrollbar(scrollbar_T *sb);

View File

@@ -36,6 +36,8 @@ void gui_mch_set_text_area_pos(int x, int y, int w, int h);
void gui_mch_enable_scrollbar(scrollbar_T *sb, int flag);
void gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max);
void gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h);
int gui_mch_get_scrollbar_xpadding(void);
int gui_mch_get_scrollbar_ypadding(void);
void gui_mch_create_scrollbar(scrollbar_T *sb, int orient);
void gui_mch_destroy_scrollbar(scrollbar_T *sb);
int gui_mch_adjust_charheight(void);

View File

@@ -23,6 +23,8 @@ void gui_mch_show_popupmenu(vimmenu_T *menu);
void gui_mch_def_colors(void);
void gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max);
void gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h);
int gui_mch_get_scrollbar_xpadding(void);
int gui_mch_get_scrollbar_ypadding(void);
void gui_mch_enable_scrollbar(scrollbar_T *sb, int flag);
void gui_mch_create_scrollbar(scrollbar_T *sb, int orient);
void gui_mch_destroy_scrollbar(scrollbar_T *sb);

View File

@@ -18,6 +18,8 @@ void gui_mch_set_foreground(void);
void gui_mch_settitle(char_u *title, char_u *icon);
void gui_mch_set_scrollbar_thumb(scrollbar_T *sb, int val, int size, int max);
void gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h);
int gui_mch_get_scrollbar_xpadding(void);
int gui_mch_get_scrollbar_ypadding(void);
void gui_mch_create_scrollbar(scrollbar_T *sb, int orient);
void gui_mch_enable_scrollbar(scrollbar_T *sb, int flag);
void gui_mch_destroy_scrollbar(scrollbar_T *sb);

View File

@@ -5,7 +5,6 @@ int gui_mch_is_blink_off(void);
void gui_mch_set_blinking(long wait, long on, long off);
void gui_mch_stop_blink(int may_call_gui_update_cursor);
void gui_mch_start_blink(void);
LRESULT WINAPI vim_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
void gui_mch_new_colors(void);
void gui_mch_def_colors(void);
int gui_mch_open(void);
@@ -14,6 +13,8 @@ void gui_mch_set_winpos(int x, int y);
void gui_mch_set_text_area_pos(int x, int y, int w, int h);
void gui_mch_enable_scrollbar(scrollbar_T *sb, int flag);
void gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h);
int gui_mch_get_scrollbar_xpadding(void);
int gui_mch_get_scrollbar_ypadding(void);
void gui_mch_create_scrollbar(scrollbar_T *sb, int orient);
int gui_mch_adjust_charheight(void);
GuiFont gui_mch_get_font(char_u *name, int giveErrorIfMissing);

View File

@@ -60,6 +60,7 @@ void f_popup_findpreview(typval_T *argvars, typval_T *rettv);
int popup_create_preview_window(int info);
void popup_close_preview(void);
void popup_hide_info(void);
void popup_close_info(void);
int popup_win_closed(win_T *win);
void popup_set_title(win_T *wp);
void popup_update_preview_title(void);

View File

@@ -0,0 +1,14 @@
|a+0&#ffffff0|w|o|r|d| @69
|t|e|s|t| |t|a|w|o|r|d> @63
|~+0#4040ff13&| @3| +0#0000001#e0e0e08|w|r|d| @4|W| |e|x|t|r|a| |t|e|x|t| @1| +0#0000000#0000001| +0#0000001#e0e0e08|w|o|r|d|s| |a|r|e| |c|o@1|l| | +0#4040ff13#ffffff0@29
|~| @3| +0#0000001#ffd7ff255|a|n|o|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| @1| +0#0000000#0000001| +0#4040ff13#ffffff0@45
|~| @3| +0#0000001#ffd7ff255|n|o|a|w|r|d| @1|W| |e|x|t|r|a| |t|e|x|t| @1| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@45
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |4| +0#0000000&@26

View File

@@ -3,8 +3,14 @@
@34|╔+0#0000001#ffd7ff255|═@3|╗| +0#0000000#ffffff0@34
@34|║+0#0000001#ffd7ff255|1@3|║| +0#0000000#ffffff0@34
|!+0#ffffff16#00e0003|/|b|i|n|/|s|h| |[|r|u|n@1|i|n|g|]| @15|║+0#0000001#ffd7ff255|2@3|║| +0#ffffff16#00e0003@34
> +0#0000000#ffffff0@33|╚+0#0000001#ffd7ff255|═@3|⇲| +0#0000000#ffffff0@34
|~+0#4040ff13&| @73
|~| @73
|[+3#0000000&|N|o| |N|a|m|e|]| @65
>++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@14|╚+0#0000001#ffd7ff255|═@3|⇲|-+0#0000e05#a8a8a8255@34
|1+0#0000000#ffffff0@1| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|2+0#0000000#ffffff0|3| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|3+0#0000000#ffffff0|5| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|4+0#0000000#ffffff0|7| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|[+3#0000000#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @61
| +0&&@74

View File

@@ -3,8 +3,14 @@
@14|╔+0#0000001#ffd7ff255|═@3|╗| +0#0000000#ffffff0@54
@14|║+0#0000001#ffd7ff255|1@3|║| +0#0000000#ffffff0@54
|!+0#ffffff16#00e0003|/|b|i|n|/|s|h| |[|r|u|n@1|║+0#0000001#ffd7ff255|2@3|║| +0#ffffff16#00e0003@54
> +0#0000000#ffffff0@13|╚+0#0000001#ffd7ff255|═@3|⇲| +0#0000000#ffffff0@54
|~+0#4040ff13&| @73
|~| @73
|[+3#0000000&|N|o| |N|a|m|e|]| @65
|:+0&&|c|a|l@1| |D|r|a|g|i|t|(|)| @60
>++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |╚+0#0000001#ffd7ff255|═@3|⇲|-+0#0000e05#a8a8a8255@54
|1+0#0000000#ffffff0@1| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|2+0#0000000#ffffff0|3| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|3+0#0000000#ffffff0|5| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|4+0#0000000#ffffff0|7| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|[+3#0000000#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @61
|:+0&&|c|a|l@1| |D|r|a|g|i|t|L|e|f|t|(|)| @56

View File

@@ -0,0 +1,16 @@
|v+0&#ffffff0|i|m|>| @70
@75
@75
@75
|!+0#ffffff16#00e0003|/|b|i|n|/|s|h| |[|r|u|n@1|i|n|g|]| @56
>++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|1+0#0000000#ffffff0@1| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|2+0#0000000#ffffff0|3| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|3+0#0000000#ffffff0|5| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@14|╔+0#0000001#ffd7ff255|═@3|╗|-+0#0000e05#a8a8a8255@34
|4+0#0000000#ffffff0|7| @31|║+0#0000001#ffd7ff255|1@3|║| +0#0000000#ffffff0@34
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@14|║+0#0000001#ffd7ff255|2@3|║|-+0#0000e05#a8a8a8255@34
|[+3#0000000#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @20|╚+0#0000001#ffd7ff255|═@3|⇲| +3#0000000#ffffff0@34
|:+0&&|c|a|l@1| |D|r|a|g|i|t|D|o|w|n|(|)| @56

View File

@@ -0,0 +1,16 @@
|v+0&#ffffff0|i|m|>| @70
@75
@75
@75
|!+0#ffffff16#00e0003|/|b|i|n|/|s|h| |[|r|u|n@1|i|n|g|]| @56
>++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|1+0#0000000#ffffff0@1| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|2+0#0000000#ffffff0|3| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |f|o|l|d| |-@55
|3+0#0000000#ffffff0|5| @72
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |╔+0#0000001#ffd7ff255|═@3|╗|-+0#0000e05#a8a8a8255@54
|4+0#0000000#ffffff0|7| @11|║+0#0000001#ffd7ff255|1@3|║| +0#0000000#ffffff0@54
|++0#0000e05#a8a8a8255|-@1| |1@1| |l|i|n|e|s|:| |║+0#0000001#ffd7ff255|2@3|║|-+0#0000e05#a8a8a8255@54
|[+3#0000000#ffffff0|N|o| |N|a|m|e|]| |[|+|]| |╚+0#0000001#ffd7ff255|═@3|⇲| +3#0000000#ffffff0@54
|:+0&&|c|a|l@1| |D|r|a|g|i|t|D|o|w|n|L|e|f|t|(|)| @52

View File

@@ -103,6 +103,24 @@ func MouseCtrlRightClick(row, col)
call feedkeys(MouseCtrlRightClickCode(a:row, a:col), 'Lx!')
endfunc
func MouseAltLeftClickCode(row, col)
let alt = 0x8
return TerminalEscapeCode(0 + alt, a:row, a:col, 'M')
endfunc
func MouseAltLeftClick(row, col)
call feedkeys(MouseAltLeftClickCode(a:row, a:col), 'Lx!')
endfunc
func MouseAltRightClickCode(row, col)
let alt = 0x8
return TerminalEscapeCode(2 + alt, a:row, a:col, 'M')
endfunc
func MouseAltRightClick(row, col)
call feedkeys(MouseAltRightClickCode(a:row, a:col), 'Lx!')
endfunc
func MouseLeftReleaseCode(row, col)
if &ttymouse ==# 'dec'
return DecEscapeCode(3, 0, a:row, a:col)

View File

@@ -268,7 +268,7 @@ func GetVimCommand(...)
" If using valgrind, make sure every run uses a different log file.
if cmd =~ 'valgrind.*--log-file='
let cmd = substitute(cmd, '--log-file=\(^\s*\)', '--log-file=\1.' . g:valgrind_cnt, '')
let cmd = substitute(cmd, '--log-file=\(\S*\)', '--log-file=\1.' . g:valgrind_cnt, '')
let g:valgrind_cnt += 1
endif

View File

@@ -584,9 +584,16 @@ func Test_popup_drag_termwin()
" create a popup that covers the terminal window
let lines =<< trim END
set foldmethod=marker
call setline(1, range(100))
for nr in range(7)
call setline(nr * 12 + 1, "fold {{{")
call setline(nr * 12 + 11 , "end }}}")
endfor
%foldclose
set shell=/bin/sh noruler
let $PS1 = 'vim> '
terminal
terminal ++rows=4
$wincmd w
let winid = popup_create(['1111', '2222'], #{
\ drag: 1,
@@ -594,19 +601,33 @@ func Test_popup_drag_termwin()
\ border: [],
\ line: 3,
\ })
func Dragit()
func DragitLeft()
call feedkeys("\<F3>\<LeftMouse>\<F4>\<LeftDrag>\<LeftRelease>", "xt")
endfunc
func DragitDown()
call feedkeys("\<F4>\<LeftMouse>\<F5>\<LeftDrag>\<LeftRelease>", "xt")
endfunc
func DragitDownLeft()
call feedkeys("\<F5>\<LeftMouse>\<F6>\<LeftDrag>\<LeftRelease>", "xt")
endfunc
map <silent> <F3> :call test_setmouse(3, &columns / 2)<CR>
map <silent> <F4> :call test_setmouse(3, &columns / 2 - 20)<CR>
map <silent> <F5> :call test_setmouse(12, &columns / 2)<CR>
map <silent> <F6> :call test_setmouse(12, &columns / 2 - 20)<CR>
END
call writefile(lines, 'XtestPopupTerm')
let buf = RunVimInTerminal('-S XtestPopupTerm', #{rows: 10})
let buf = RunVimInTerminal('-S XtestPopupTerm', #{rows: 16})
call VerifyScreenDump(buf, 'Test_popupwin_term_01', {})
call term_sendkeys(buf, ":call Dragit()\<CR>")
call term_sendkeys(buf, ":call DragitLeft()\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_term_02', {})
call term_sendkeys(buf, ":call DragitDown()\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_term_03', {})
call term_sendkeys(buf, ":call DragitDownLeft()\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_term_04', {})
" clean up
call StopVimInTerminal(buf)
call delete('XtestPopupTerm')
@@ -3088,6 +3109,12 @@ func Test_popupmenu_info_border()
call term_sendkeys(buf, "otest text test text\<C-X>\<C-U>")
call VerifyScreenDump(buf, 'Test_popupwin_infopopup_7', {})
" Test that when the option is changed the popup changes.
call term_sendkeys(buf, "\<Esc>")
call term_sendkeys(buf, ":set completepopup=border:off\<CR>")
call term_sendkeys(buf, "a\<C-X>\<C-U>")
call VerifyScreenDump(buf, 'Test_popupwin_infopopup_8', {})
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf)
call delete('XtestInfoPopup')

View File

@@ -377,4 +377,34 @@ func Test_swap_prompt_splitwin()
call delete('Xfile1')
endfunc
func Test_swap_symlink()
if !has("unix")
return
endif
call writefile(['text'], 'Xtestfile')
silent !ln -s -f Xtestfile Xtestlink
set dir=.
" Test that swap file uses the name of the file when editing through a
" symbolic link (so that editing the file twice is detected)
edit Xtestlink
call assert_match('Xtestfile\.swp$', s:swapname())
bwipe!
call mkdir('Xswapdir')
exe 'set dir=' . getcwd() . '/Xswapdir//'
" Check that this also works when 'directory' ends with '//'
edit Xtestlink
call assert_match('Xtestfile\.swp$', s:swapname())
bwipe!
set dir&
call delete('Xtestfile')
call delete('Xtestlink')
call delete('Xswapdir', 'rf')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -147,13 +147,13 @@ func Test_xterm_mouse_tagjump()
new
let str = 'iHello' .. MouseCtrlRightClickCode(row, col)
\ .. MouseRightReleaseCode(row, col) .. "\<C-C>"
call assert_fails('call feedkeys(str, "Lx!")', 'E37:')
call assert_fails('call feedkeys(str, "Lx!")', 'E37:', msg)
close!
" CTRL-right click with a count
let str = "4" .. MouseCtrlRightClickCode(row, col)
\ .. MouseRightReleaseCode(row, col)
call assert_fails('call feedkeys(str, "Lx!")', 'E555:')
call assert_fails('call feedkeys(str, "Lx!")', 'E555:', msg)
call assert_match('help.txt$', bufname('%'), msg)
call assert_equal(1, line('.'), msg)
@@ -230,7 +230,7 @@ func Test_term_mouse_middle_click()
\ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!')
call assert_equal(['12345abc6789abc', '12abc3abc456789'],
\ getline(1, '$'), msg)
call assert_equal('1234', @")
call assert_equal('1234', @", msg)
let &clipboard = save_clipboard
" Clicking middle mouse in select mode, replaces the selected text with
@@ -240,6 +240,18 @@ func Test_term_mouse_middle_click()
exe "normal gh\<Right>\<Right>\<MiddleMouse>"
call assert_equal(['12xyzabc6789abc', '12abc3abc456789'],
\ getline(1, '$'), msg)
" Prefixing middle click with [ or ] fixes the indent after pasting.
%d
call setline(1, " one two")
call setreg('r', 'red blue', 'l')
call test_setmouse(1, 5)
exe "normal \"r[\<MiddleMouse>"
call assert_equal(' red blue', getline(1), msg)
call test_setmouse(2, 5)
exe "normal \"r]\<MiddleMouse>"
call assert_equal(' red blue', getline(3), msg)
%d
endfor
let &mouse = save_mouse
@@ -309,7 +321,7 @@ func Test_term_mouse_middle_click_insert_mode()
\ "\<C-C>", 'Lx!')
call assert_equal(['123abc456789', '123456789'],
\ getline(1, '$'), msg)
call assert_equal([1, 6], [line('.'), col('.')])
call assert_equal([1, 6], [line('.'), col('.')], msg)
" Middle-click in replace mode
call cursor(1, 1)
@@ -318,7 +330,7 @@ func Test_term_mouse_middle_click_insert_mode()
\ "\<C-C>", 'Lx!')
call assert_equal(['123abc45678abc', '123456789'],
\ getline(1, '$'), msg)
call assert_equal([1, 14], [line('.'), col('.')])
call assert_equal([1, 14], [line('.'), col('.')], msg)
endfor
let &mouse = save_mouse
@@ -899,6 +911,53 @@ func Test_term_mouse_multiple_clicks_to_visually_select()
call assert_equal("\<c-v>", mode(), msg)
norm! r4
call assert_equal(['34333333333333333', 'foo'], getline(1, '$'), msg)
" Double-click on a space character should visually select all the
" consecutive space characters.
%d
call setline(1, ' one two')
call MouseLeftClick(1, 2)
call MouseLeftRelease(1, 2)
call MouseLeftClick(1, 2)
call MouseLeftRelease(1, 2)
call assert_equal('v', mode(), msg)
norm! r1
call assert_equal(['1111one two'], getline(1, '$'), msg)
" Double-click on a word with exclusive selection
set selection=exclusive
let @" = ''
call MouseLeftClick(1, 10)
call MouseLeftRelease(1, 10)
call MouseLeftClick(1, 10)
call MouseLeftRelease(1, 10)
norm! y
call assert_equal('two', @", msg)
" Double click to select a block of text with exclusive selection
%d
call setline(1, 'one (two) three')
call MouseLeftClick(1, 5)
call MouseLeftRelease(1, 5)
call MouseLeftClick(1, 5)
call MouseLeftRelease(1, 5)
norm! y
call assert_equal(5, col("'<"), msg)
call assert_equal(10, col("'>"), msg)
call MouseLeftClick(1, 9)
call MouseLeftRelease(1, 9)
call MouseLeftClick(1, 9)
call MouseLeftRelease(1, 9)
norm! y
call assert_equal(5, col("'<"), msg)
call assert_equal(10, col("'>"), msg)
set selection&
" Click somewhere else so that the clicks above is not combined with the
" clicks in the next iteration.
call MouseRightClick(3, 10)
call MouseRightRelease(3, 10)
endfor
let &mouse = save_mouse
@@ -909,6 +968,41 @@ func Test_term_mouse_multiple_clicks_to_visually_select()
bwipe!
endfunc
" Test for selecting text in visual blockwise mode using Alt-LeftClick
func Test_mouse_alt_leftclick()
let save_mouse = &mouse
let save_term = &term
let save_ttymouse = &ttymouse
call test_override('no_query_mouse', 1)
set mouse=a term=xterm mousetime=200
set mousemodel=popup
new
call setline(1, 'one (two) three')
for ttymouse_val in g:Ttymouse_values
let msg = 'ttymouse=' .. ttymouse_val
exe 'set ttymouse=' .. ttymouse_val
" Left click with the Alt modifier key should extend the selection in
" blockwise visual mode.
let @" = ''
call MouseLeftClick(1, 3)
call MouseLeftRelease(1, 3)
call MouseAltLeftClick(1, 11)
call MouseLeftRelease(1, 11)
call assert_equal("\<C-V>", mode(), msg)
normal! y
call assert_equal('e (two) t', @")
endfor
let &mouse = save_mouse
let &term = save_term
let &ttymouse = save_ttymouse
set mousetime& mousemodel&
call test_override('no_query_mouse', 0)
close!
endfunc
func Test_xterm_mouse_click_in_fold_columns()
new
let save_mouse = &mouse
@@ -1086,13 +1180,37 @@ func Test_term_mouse_visual_mode()
call assert_equal('three four', @")
call assert_equal(9, col('.'))
" Multi-line selection. Right click in the middle of thse selection
call setline(1, ["one", "two", "three", "four", "five", "six"])
" Right click inside the selection closer to the start of the selection
call test_setmouse(1, 7)
exe "normal 5|vee\<RightMouse>lly"
call assert_equal('three', @")
call assert_equal(9, col('.'))
call assert_equal(9, col("'<"))
call assert_equal(13, col("'>"))
" Right click inside the selection closer to the end of the selection
call test_setmouse(1, 11)
exe "normal 5|vee\<RightMouse>ly"
call assert_equal('two thre', @")
call assert_equal(5, col('.'))
call assert_equal(5, col("'<"))
call assert_equal(12, col("'>"))
" Multi-line selection. Right click inside thse selection.
call setline(1, repeat(['aaaaaa'], 7))
call test_setmouse(3, 1)
exe "normal ggVG\<RightMouse>y"
call assert_equal(3, line("'<"))
call test_setmouse(4, 1)
call test_setmouse(5, 1)
exe "normal ggVG\<RightMouse>y"
call assert_equal(5, line("'>"))
" Click right in the middle line of the selection
call test_setmouse(4, 3)
exe "normal ggVG$\<RightMouse>y"
call assert_equal(4, line("'<"))
call test_setmouse(4, 4)
exe "normal ggVG$\<RightMouse>y"
call assert_equal(4, line("'>"))
set mousemodel&
@@ -1120,11 +1238,12 @@ func Test_term_mouse_popup_menu()
menu PopUp.baz :let g:menustr = 'baz'<CR>
for ttymouse_val in g:Ttymouse_values
let msg = 'ttymouse=' .. ttymouse_val
exe 'set ttymouse=' .. ttymouse_val
let g:menustr = ''
call feedkeys(MouseRightClickCode(1, 4)
\ .. MouseRightReleaseCode(1, 4) .. "\<Down>\<Down>\<CR>", "x")
call assert_equal('bar', g:menustr)
call assert_equal('bar', g:menustr, msg)
endfor
unmenu PopUp
@@ -1158,70 +1277,71 @@ func Test_term_mouse_popup_menu_setpos()
vmenu PopUp.baz y:<C-U>let g:menustr = 'baz'<CR>
for ttymouse_val in g:Ttymouse_values
let msg = 'ttymouse=' .. ttymouse_val
exe 'set ttymouse=' .. ttymouse_val
let g:menustr = ''
call cursor(1, 1)
call feedkeys(MouseRightClickCode(1, 5)
\ .. MouseRightReleaseCode(1, 5) .. "\<Down>\<Down>\<CR>", "x")
call assert_equal('bar', g:menustr)
call assert_equal([1, 5], [line('.'), col('.')])
call assert_equal('bar', g:menustr, msg)
call assert_equal([1, 5], [line('.'), col('.')], msg)
" Test for right click in visual mode inside the selection
let @" = ''
call cursor(1, 10)
call feedkeys('vee' .. MouseRightClickCode(1, 12)
\ .. MouseRightReleaseCode(1, 12) .. "\<Down>\<CR>", "x")
call assert_equal([1, 10], [line('.'), col('.')])
call assert_equal('ran away', @")
call assert_equal([1, 10], [line('.'), col('.')], msg)
call assert_equal('ran away', @", msg)
" Test for right click in visual mode before the selection
let @" = ''
call cursor(1, 10)
call feedkeys('vee' .. MouseRightClickCode(1, 2)
\ .. MouseRightReleaseCode(1, 2) .. "\<Down>\<CR>", "x")
call assert_equal([1, 2], [line('.'), col('.')])
call assert_equal('', @")
call assert_equal([1, 2], [line('.'), col('.')], msg)
call assert_equal('', @", msg)
" Test for right click in visual mode after the selection
let @" = ''
call cursor(1, 10)
call feedkeys('vee' .. MouseRightClickCode(1, 20)
\ .. MouseRightReleaseCode(1, 20) .. "\<Down>\<CR>", "x")
call assert_equal([1, 20], [line('.'), col('.')])
call assert_equal('', @")
call assert_equal([1, 20], [line('.'), col('.')], msg)
call assert_equal('', @", msg)
" Test for right click in block-wise visual mode inside the selection
let @" = ''
call cursor(1, 16)
call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 17)
\ .. MouseRightReleaseCode(2, 17) .. "\<Down>\<CR>", "x")
call assert_equal([1, 16], [line('.'), col('.')])
call assert_equal("\<C-V>4", getregtype('"'))
call assert_equal([1, 16], [line('.'), col('.')], msg)
call assert_equal("\<C-V>4", getregtype('"'), msg)
" Test for right click in block-wise visual mode outside the selection
let @" = ''
call cursor(1, 16)
call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 2)
\ .. MouseRightReleaseCode(2, 2) .. "\<Down>\<CR>", "x")
call assert_equal([2, 2], [line('.'), col('.')])
call assert_equal('v', getregtype('"'))
call assert_equal('', @")
call assert_equal([2, 2], [line('.'), col('.')], msg)
call assert_equal('v', getregtype('"'), msg)
call assert_equal('', @", msg)
" Try clicking on the status line
let @" = ''
call cursor(1, 10)
call feedkeys('vee' .. MouseRightClickCode(6, 2)
\ .. MouseRightReleaseCode(6, 2) .. "\<Down>\<CR>", "x")
call assert_equal([1, 10], [line('.'), col('.')])
call assert_equal('ran away', @")
call assert_equal([1, 10], [line('.'), col('.')], msg)
call assert_equal('ran away', @", msg)
" Try clicking outside the window
let @" = ''
call cursor(7, 2)
call feedkeys('vee' .. MouseRightClickCode(7, 2)
\ .. MouseRightReleaseCode(7, 2) .. "\<Down>\<CR>", "x")
call assert_equal(2, winnr())
call assert_equal('', @")
call assert_equal(2, winnr(), msg)
call assert_equal('', @", msg)
wincmd w
endfor
@@ -1303,6 +1423,111 @@ func Test_term_mouse_quickfix_window()
call test_override('no_query_mouse', 0)
endfunc
" Test for the 'h' flag in the 'mouse' option. Using mouse in the help window.
func Test_term_mouse_help_window()
let save_mouse = &mouse
let save_term = &term
let save_ttymouse = &ttymouse
call test_override('no_query_mouse', 1)
set mouse=h term=xterm mousetime=200
for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
let msg = 'ttymouse=' .. ttymouse_val
exe 'set ttymouse=' .. ttymouse_val
help
let @" = ''
call MouseLeftClick(2, 5)
call MouseLeftRelease(2, 5)
call MouseLeftClick(1, 1)
call MouseLeftDrag(1, 10)
call MouseLeftRelease(1, 10)
norm! y
call assert_equal('*help.txt*', @", msg)
helpclose
" Click somewhere else to make sure the left click above is not combined
" with the next left click and treated as a double click
call MouseRightClick(5, 10)
call MouseRightRelease(5, 10)
endfor
let &mouse = save_mouse
let &term = save_term
let &ttymouse = save_ttymouse
set mousetime&
call test_override('no_query_mouse', 0)
%bw!
endfunc
" Test for the translation of various mouse terminal codes
func Test_mouse_termcodes()
let save_mouse = &mouse
let save_term = &term
let save_ttymouse = &ttymouse
call test_override('no_query_mouse', 1)
set mouse=a term=xterm mousetime=200
new
for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
let msg = 'ttymouse=' .. ttymouse_val
exe 'set ttymouse=' .. ttymouse_val
let mouse_codes = [
\ ["\<LeftMouse>", "<LeftMouse>"],
\ ["\<MiddleMouse>", "<MiddleMouse>"],
\ ["\<RightMouse>", "<RightMouse>"],
\ ["\<S-LeftMouse>", "<S-LeftMouse>"],
\ ["\<S-MiddleMouse>", "<S-MiddleMouse>"],
\ ["\<S-RightMouse>", "<S-RightMouse>"],
\ ["\<C-LeftMouse>", "<C-LeftMouse>"],
\ ["\<C-MiddleMouse>", "<C-MiddleMouse>"],
\ ["\<C-RightMouse>", "<C-RightMouse>"],
\ ["\<M-LeftMouse>", "<M-LeftMouse>"],
\ ["\<M-MiddleMouse>", "<M-MiddleMouse>"],
\ ["\<M-RightMouse>", "<M-RightMouse>"],
\ ["\<2-LeftMouse>", "<2-LeftMouse>"],
\ ["\<2-MiddleMouse>", "<2-MiddleMouse>"],
\ ["\<2-RightMouse>", "<2-RightMouse>"],
\ ["\<3-LeftMouse>", "<3-LeftMouse>"],
\ ["\<3-MiddleMouse>", "<3-MiddleMouse>"],
\ ["\<3-RightMouse>", "<3-RightMouse>"],
\ ["\<4-LeftMouse>", "<4-LeftMouse>"],
\ ["\<4-MiddleMouse>", "<4-MiddleMouse>"],
\ ["\<4-RightMouse>", "<4-RightMouse>"],
\ ["\<LeftDrag>", "<LeftDrag>"],
\ ["\<MiddleDrag>", "<MiddleDrag>"],
\ ["\<RightDrag>", "<RightDrag>"],
\ ["\<LeftRelease>", "<LeftRelease>"],
\ ["\<MiddleRelease>", "<MiddleRelease>"],
\ ["\<RightRelease>", "<RightRelease>"],
\ ["\<ScrollWheelUp>", "<ScrollWheelUp>"],
\ ["\<S-ScrollWheelUp>", "<S-ScrollWheelUp>"],
\ ["\<C-ScrollWheelUp>", "<C-ScrollWheelUp>"],
\ ["\<ScrollWheelDown>", "<ScrollWheelDown>"],
\ ["\<S-ScrollWheelDown>", "<S-ScrollWheelDown>"],
\ ["\<C-ScrollWheelDown>", "<C-ScrollWheelDown>"],
\ ["\<ScrollWheelLeft>", "<ScrollWheelLeft>"],
\ ["\<S-ScrollWheelLeft>", "<S-ScrollWheelLeft>"],
\ ["\<C-ScrollWheelLeft>", "<C-ScrollWheelLeft>"],
\ ["\<ScrollWheelRight>", "<ScrollWheelRight>"],
\ ["\<S-ScrollWheelRight>", "<S-ScrollWheelRight>"],
\ ["\<C-ScrollWheelRight>", "<C-ScrollWheelRight>"]
\ ]
for [code, outstr] in mouse_codes
exe "normal ggC\<C-K>" . code
call assert_equal(outstr, getline(1), msg)
endfor
endfor
let &mouse = save_mouse
let &term = save_term
let &ttymouse = save_ttymouse
set mousetime&
call test_override('no_query_mouse', 0)
%bw!
endfunc
" This only checks if the sequence is recognized.
func Test_term_rgb_response()
set t_RF=x

View File

@@ -463,7 +463,7 @@ def Test_disassemble_update_instr()
'\d RETURN',
res)
" Calling the function will change UCALL into the faster DCALL
# Calling the function will change UCALL into the faster DCALL
assert_equal('yes', FuncWithForwardCall())
res = execute('disass s:FuncWithForwardCall')
@@ -1073,7 +1073,7 @@ def Test_disassemble_compare()
let nr = 1
for case in cases
" declare local variables to get a non-constant with the right type
# declare local variables to get a non-constant with the right type
writefile(['def TestCase' .. nr .. '()',
' let isFalse = false',
' let isNull = v:null',
@@ -1121,7 +1121,7 @@ def Test_disassemble_compare_const()
source Xdisassemble
let instr = execute('disassemble TestCase' .. nr)
if case[1]
" condition true, "echo 42" executed
# condition true, "echo 42" executed
assert_match('TestCase' .. nr .. '.*' ..
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
'\d PUSHNR 42.*' ..
@@ -1130,7 +1130,7 @@ def Test_disassemble_compare_const()
'\d RETURN.*',
instr)
else
" condition false, function just returns
# condition false, function just returns
assert_match('TestCase' .. nr .. '.*' ..
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
'echo 42[ \n]*' ..
@@ -1245,7 +1245,7 @@ def Test_vim9script_forward_func()
writefile(lines, 'Xdisassemble')
source Xdisassemble
" check that the first function calls the second with DCALL
# check that the first function calls the second with DCALL
assert_match('\<SNR>\d*_FuncOne\_s*' ..
'return FuncTwo()\_s*' ..
'\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..

View File

@@ -46,7 +46,7 @@ def Test_expr1()
enddef
def Test_expr1_vimscript()
" only checks line continuation
# only checks line continuation
let lines =<< trim END
vim9script
let var = 1
@@ -127,7 +127,7 @@ def Test_expr2()
enddef
def Test_expr2_vimscript()
" check line continuation
# check line continuation
let lines =<< trim END
vim9script
let var = 0
@@ -154,7 +154,7 @@ def Test_expr2_vimscript()
END
CheckScriptSuccess(lines)
" check keeping the value
# check keeping the value
lines =<< trim END
vim9script
assert_equal(2, 2 || 0)
@@ -231,7 +231,7 @@ def Test_expr3()
enddef
def Test_expr3_vimscript()
" check line continuation
# check line continuation
let lines =<< trim END
vim9script
let var = 0
@@ -258,7 +258,7 @@ def Test_expr3_vimscript()
END
CheckScriptSuccess(lines)
" check keeping the value
# check keeping the value
lines =<< trim END
vim9script
assert_equal(0, 2 && 0)
@@ -625,7 +625,7 @@ def RetVoid()
enddef
def Test_expr4_vimscript()
" check line continuation
# check line continuation
let lines =<< trim END
vim9script
let var = 0
@@ -668,7 +668,7 @@ def Test_expr4_vimscript()
END
CheckScriptSuccess(lines)
" spot check mismatching types
# spot check mismatching types
lines =<< trim END
vim9script
echo '' == 0
@@ -791,7 +791,7 @@ def Test_expr5()
enddef
def Test_expr5_vim9script()
" only checks line continuation
# only checks line continuation
let lines =<< trim END
vim9script
let var = 11
@@ -902,7 +902,7 @@ def Test_expr6()
enddef
def Test_expr6_vim9script()
" only checks line continuation
# only checks line continuation
let lines =<< trim END
vim9script
let var = 11
@@ -1024,7 +1024,7 @@ let $TESTVAR = 'testvar'
" test low level expression
def Test_expr7_number()
" number constant
# number constant
assert_equal(0, 0)
assert_equal(654, 0654)
@@ -1034,7 +1034,7 @@ def Test_expr7_number()
enddef
def Test_expr7_float()
" float constant
# float constant
if !has('float')
MissingFeature 'float'
else
@@ -1046,7 +1046,7 @@ def Test_expr7_float()
enddef
def Test_expr7_blob()
" blob constant
# blob constant
assert_equal(g:blob_empty, 0z)
assert_equal(g:blob_one, 0z01)
assert_equal(g:blob_long, 0z0102.0304)
@@ -1055,7 +1055,7 @@ def Test_expr7_blob()
enddef
def Test_expr7_string()
" string constant
# string constant
assert_equal(g:string_empty, '')
assert_equal(g:string_empty, "")
assert_equal(g:string_short, 'x')
@@ -1077,7 +1077,7 @@ def Test_expr7_vimvar()
enddef
def Test_expr7_special()
" special constant
# special constant
assert_equal(g:special_true, true)
assert_equal(g:special_false, false)
assert_equal(g:special_true, v:true)
@@ -1106,7 +1106,7 @@ def Test_expr7_special_vim9script()
enddef
def Test_expr7_list()
" list
# list
assert_equal(g:list_empty, [])
assert_equal(g:list_empty, [ ])
assert_equal(g:list_mixed, [1, 'b', false,])
@@ -1152,7 +1152,7 @@ def Test_expr7_lambda()
assert_equal('result', La())
assert_equal([1, 3, 5], [1, 2, 3]->map({key, val -> key + val}))
" line continuation inside lambda with "cond ? expr : expr" works
# line continuation inside lambda with "cond ? expr : expr" works
let ll = range(3)
map(ll, {k, v -> v % 2 ? {
'111': 111 } : {}
@@ -1189,7 +1189,7 @@ def Test_expr7_lambda_vim9script()
enddef
def Test_expr7_dict()
" dictionary
# dictionary
assert_equal(g:dict_empty, {})
assert_equal(g:dict_empty, { })
assert_equal(g:dict_one, {'one': 1})
@@ -1316,7 +1316,7 @@ def Test_expr_member_vim9script()
enddef
def Test_expr7_option()
" option
# option
set ts=11
assert_equal(11, &ts)
&ts = 9
@@ -1330,7 +1330,7 @@ def Test_expr7_option()
enddef
def Test_expr7_environment()
" environment variable
# environment variable
assert_equal('testvar', $TESTVAR)
assert_equal('', $ASDF_ASD_XXX)
@@ -1343,7 +1343,7 @@ def Test_expr7_register()
enddef
def Test_expr7_parens()
" (expr)
# (expr)
assert_equal(4, (6 * 4) / 6)
assert_equal(0, 6 * ( 4 / 6 ))
@@ -1474,7 +1474,7 @@ func CallMe2(one, two)
endfunc
def Test_expr7_trailing()
" user function call
# user function call
assert_equal(123, g:CallMe(123))
assert_equal(123, g:CallMe( 123))
assert_equal(123, g:CallMe(123 ))
@@ -1482,26 +1482,26 @@ def Test_expr7_trailing()
assert_equal('yesno', g:CallMe2( 'yes', 'no' ))
assert_equal('nothing', g:CallMe('nothing'))
" partial call
# partial call
let Part = function('g:CallMe')
assert_equal('yes', Part('yes'))
" funcref call, using list index
# funcref call, using list index
let l = []
g:Funcrefs[0](l, 2)
assert_equal([2], l)
" method call
# method call
l = [2, 5, 6]
l->map({k, v -> k + v})
assert_equal([2, 6, 8], l)
" lambda method call
# lambda method call
l = [2, 5]
l->{l -> add(l, 8)}()
assert_equal([2, 5, 8], l)
" dict member
# dict member
let d = #{key: 123}
assert_equal(123, d.key)
enddef

View File

@@ -80,7 +80,7 @@ def Test_call_ufunc_count()
Increment()
Increment()
Increment()
" works with and without :call
# works with and without :call
assert_equal(4, g:counter)
call assert_equal(4, g:counter)
unlet g:counter
@@ -104,11 +104,19 @@ def MyDefaultArgs(name = 'string'): string
return name
enddef
def MyDefaultSecond(name: string, second: bool = true): string
return second ? name : 'none'
enddef
def Test_call_default_args()
assert_equal('string', MyDefaultArgs())
assert_equal('one', MyDefaultArgs('one'))
assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
assert_equal('test', MyDefaultSecond('test'))
assert_equal('test', MyDefaultSecond('test', true))
assert_equal('none', MyDefaultSecond('test', false))
CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: argument 1: type mismatch, expected number but got string')
enddef
@@ -228,7 +236,7 @@ def ListArg(arg: list<string>)
enddef
def Test_assign_to_argument()
" works for dict and list
# works for dict and list
let d: dict<string> = {}
DictArg(d)
assert_equal('value', d['key'])
@@ -258,19 +266,19 @@ let SomeFunc = function('len')
let NotAFunc = 'text'
def CombineFuncrefTypes()
" same arguments, different return type
# same arguments, different return type
let Ref1: func(bool): string
let Ref2: func(bool): number
let Ref3: func(bool): any
Ref3 = g:cond ? Ref1 : Ref2
" different number of arguments
# different number of arguments
let Refa1: func(bool): number
let Refa2: func(bool, number): number
let Refa3: func: number
Refa3 = g:cond ? Refa1 : Refa2
" different argument types
# different argument types
let Refb1: func(bool, string): number
let Refb2: func(string, number): number
let Refb3: func(any, any): number
@@ -286,7 +294,7 @@ def DefinedEvenLater(arg: string): string
enddef
def Test_error_in_nested_function()
" Error in called function requires unwinding the call stack.
# Error in called function requires unwinding the call stack.
assert_fails('call FuncWithForwardCall()', 'E1096')
enddef
@@ -355,6 +363,15 @@ def Test_vim9script_call()
("some")->MyFunc()
assert_equal('some', var)
'asdfasdf'->MyFunc()
assert_equal('asdfasdf', var)
def UseString()
'xyork'->MyFunc()
enddef
UseString()
assert_equal('xyork', var)
MyFunc(
'continued'
)
@@ -1038,5 +1055,23 @@ def Test_closure_in_map()
delete('XclosureDir', 'rf')
enddef
def Test_partial_call()
let Xsetlist = function('setloclist', [0])
Xsetlist([], ' ', {'title': 'test'})
assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
Xsetlist = function('setloclist', [0, [], ' '])
Xsetlist({'title': 'test'})
assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
Xsetlist = function('setqflist')
Xsetlist([], ' ', {'title': 'test'})
assert_equal({'title': 'test'}, getqflist({'title': 1}))
Xsetlist = function('setqflist', [[], ' '])
Xsetlist({'title': 'test'})
assert_equal({'title': 'test'}, getqflist({'title': 1}))
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

View File

@@ -17,6 +17,7 @@ let g:inc_counter = 1
let $SOME_ENV_VAR = 'some'
let g:alist = [7]
let g:astring = 'text'
let g:anumber = 123
def Test_assignment()
let bool1: bool = true
@@ -113,7 +114,7 @@ def Test_vim9_single_char_vars()
let lines =<< trim END
vim9script
" single character variable declarations work
# single character variable declarations work
let a: string
let b: number
let l: list<any>
@@ -122,7 +123,7 @@ def Test_vim9_single_char_vars()
let v: number
let w: number
" script-local variables can be used without s: prefix
# script-local variables can be used without s: prefix
a = 'script-a'
b = 111
l = [1, 2, 3]
@@ -175,7 +176,7 @@ def Test_assignment_dict()
let dict4: dict<any> = #{one: 1, two: '2'}
let dict5: dict<blob> = #{one: 0z01, two: 0z02}
" overwrite
# overwrite
dict3['key'] = 'another'
call CheckDefExecFailure(['let dd = {}', 'dd[""] = 6'], 'E713:')
@@ -185,8 +186,8 @@ def Test_assignment_dict()
enddef
def Test_assignment_local()
" Test in a separated file in order not to the current buffer/window/tab is
" changed.
# Test in a separated file in order not to the current buffer/window/tab is
# changed.
let script_lines: list<string> =<< trim END
let b:existing = 'yes'
let w:existing = 'yes'
@@ -259,7 +260,7 @@ def Test_assignment_default()
assert_equal(test_null_channel(), thechannel)
if has('unix') && executable('cat')
" check with non-null job and channel, types must match
# check with non-null job and channel, types must match
thejob = job_start("cat ", #{})
thechannel = job_getchannel(thejob)
job_stop(thejob, 'kill')
@@ -394,7 +395,7 @@ def Test_unlet()
enddef
def Test_delfunction()
" Check function is defined in script namespace
# Check function is defined in script namespace
CheckScriptSuccess([
'vim9script',
'func CheckMe()',
@@ -403,7 +404,7 @@ def Test_delfunction()
'assert_equal(123, s:CheckMe())',
])
" Check function in script namespace cannot be deleted
# Check function in script namespace cannot be deleted
CheckScriptFailure([
'vim9script',
'func DeleteMe1()',
@@ -509,8 +510,160 @@ def Test_try_catch()
add(l, '3')
endtry # comment
assert_equal(['1', 'wrong', '3'], l)
l = []
try
try
add(l, '1')
throw 'wrong'
add(l, '2')
catch /right/
add(l, v:exception)
endtry
catch /wrong/
add(l, 'caught')
finally
add(l, 'finally')
endtry
assert_equal(['1', 'caught', 'finally'], l)
let n: number
try
n = l[3]
catch /E684:/
n = 99
endtry
assert_equal(99, n)
try
n = g:astring[3]
catch /E714:/
n = 77
endtry
assert_equal(77, n)
try
n = l[g:astring]
catch /E39:/
n = 77
endtry
assert_equal(77, n)
try
n = s:does_not_exist
catch /E121:/
n = 111
endtry
assert_equal(111, n)
try
n = g:does_not_exist
catch /E121:/
n = 121
endtry
assert_equal(121, n)
let d = #{one: 1}
try
n = d[g:astring]
catch /E716:/
n = 222
endtry
assert_equal(222, n)
try
n = -g:astring
catch /E39:/
n = 233
endtry
assert_equal(233, n)
try
n = +g:astring
catch /E1030:/
n = 244
endtry
assert_equal(244, n)
try
n = +g:alist
catch /E745:/
n = 255
endtry
assert_equal(255, n)
let nd: dict<any>
try
nd = {g:anumber: 1}
catch /E1029:/
n = 266
endtry
assert_equal(266, n)
try
[n] = [1, 2, 3]
catch /E1093:/
n = 277
endtry
assert_equal(277, n)
try
&ts = g:astring
catch /E1029:/
n = 288
endtry
assert_equal(288, n)
try
&backspace = 'asdf'
catch /E474:/
n = 299
endtry
assert_equal(299, n)
l = [1]
try
l[3] = 3
catch /E684:/
n = 300
endtry
assert_equal(300, n)
try
d[''] = 3
catch /E713:/
n = 311
endtry
assert_equal(311, n)
try
unlet g:does_not_exist
catch /E108:/
n = 322
endtry
assert_equal(322, n)
try
d = {'text': 1, g:astring: 2}
catch /E721:/
n = 333
endtry
assert_equal(333, n)
try
l = DeletedFunc()
catch /E933:/
n = 344
endtry
assert_equal(344, n)
enddef
def DeletedFunc(): list<any>
return ['delete me']
enddef
defcompile
delfunc DeletedFunc
def ThrowFromDef()
throw "getout" # comment
enddef
@@ -586,7 +739,7 @@ def Test_try_catch_fails()
enddef
def Test_throw_vimscript()
" only checks line continuation
# only checks line continuation
let lines =<< trim END
vim9script
try
@@ -600,7 +753,7 @@ def Test_throw_vimscript()
enddef
def Test_cexpr_vimscript()
" only checks line continuation
# only checks line continuation
set errorformat=File\ %f\ line\ %l
let lines =<< trim END
vim9script
@@ -727,7 +880,7 @@ def Test_vim9_import_export()
END
writefile(import_in_def_lines, 'Ximport2.vim')
source Ximport2.vim
" TODO: this should be 9879
# TODO: this should be 9879
assert_equal(9876, g:imported)
assert_equal(9883, g:imported_added)
unlet g:imported
@@ -802,7 +955,7 @@ def Test_vim9_import_export()
writefile(import_star_lines, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1045:')
" try to import something that exists but is not exported
# try to import something that exists but is not exported
let import_not_exported_lines =<< trim END
vim9script
import name from './Xexport.vim'
@@ -810,7 +963,7 @@ def Test_vim9_import_export()
writefile(import_not_exported_lines, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1049:')
" try to import something that is already defined
# try to import something that is already defined
let import_already_defined =<< trim END
vim9script
let exported = 'something'
@@ -819,7 +972,7 @@ def Test_vim9_import_export()
writefile(import_already_defined, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1073:')
" try to import something that is already defined
# try to import something that is already defined
import_already_defined =<< trim END
vim9script
let exported = 'something'
@@ -828,7 +981,7 @@ def Test_vim9_import_export()
writefile(import_already_defined, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1073:')
" try to import something that is already defined
# try to import something that is already defined
import_already_defined =<< trim END
vim9script
let exported = 'something'
@@ -837,7 +990,7 @@ def Test_vim9_import_export()
writefile(import_already_defined, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1073:')
" import a very long name, requires making a copy
# import a very long name, requires making a copy
let import_long_name_lines =<< trim END
vim9script
import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
@@ -877,7 +1030,7 @@ def Test_vim9_import_export()
delete('Ximport3.vim')
delete('Xexport.vim')
" Check that in a Vim9 script 'cpo' is set to the Vim default.
# Check that in a Vim9 script 'cpo' is set to the Vim default.
set cpo&vi
let cpo_before = &cpo
let lines =<< trim END
@@ -962,12 +1115,12 @@ def Test_vim9script_reload_import()
writefile(testlines, 'Ximport.vim')
source Ximport.vim
" Test that when not using "morelines" GetValtwo() and valtwo are still
" defined, because import doesn't reload a script.
# Test that when not using "morelines" GetValtwo() and valtwo are still
# defined, because import doesn't reload a script.
writefile(lines, 'Xreload.vim')
source Ximport.vim
" cannot declare a var twice
# cannot declare a var twice
lines =<< trim END
vim9script
let valone = 1234
@@ -1185,7 +1338,7 @@ def Test_import_compile_error()
try
source Ximport.vim
catch /E1001/
" Error should be fore the Xexported.vim file.
# Error should be fore the Xexported.vim file.
assert_match('E1001: variable not found: notDefined', v:exception)
assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
endtry
@@ -1195,7 +1348,7 @@ def Test_import_compile_error()
enddef
def Test_fixed_size_list()
" will be allocated as one piece of memory, check that changes work
# will be allocated as one piece of memory, check that changes work
let l = [1, 2, 3, 4]
l->remove(0)
l->add(5)
@@ -1357,9 +1510,9 @@ def RunNested(i: number): number
let x: number = 0
if i % 2
if 1
" comment
# comment
else
" comment
# comment
endif
x += 1
else
@@ -1401,7 +1554,7 @@ def Test_execute_cmd()
enddef
def Test_execute_cmd_vimscript()
" only checks line continuation
# only checks line continuation
let lines =<< trim END
vim9script
execute 'g:someVar'
@@ -1441,7 +1594,7 @@ def Test_echomsg_cmd()
enddef
def Test_echomsg_cmd_vimscript()
" only checks line continuation
# only checks line continuation
let lines =<< trim END
vim9script
echomsg 'here'
@@ -1461,7 +1614,7 @@ def Test_echoerr_cmd()
enddef
def Test_echoerr_cmd_vimscript()
" only checks line continuation
# only checks line continuation
let lines =<< trim END
vim9script
try
@@ -1569,7 +1722,7 @@ def Test_automatic_line_continuation()
'one',
'two',
'three',
] " comment
] # comment
assert_equal(['one', 'two', 'three'], mylist)
let mydict = {
@@ -1577,7 +1730,7 @@ def Test_automatic_line_continuation()
'two': 2,
'three':
3,
} " comment
} # comment
assert_equal({'one': 1, 'two': 2, 'three': 3}, mydict)
mydict = #{
one: 1, # comment
@@ -1754,8 +1907,8 @@ def Test_vim9_comment()
'hi clear This # comment',
'hi clear # comment',
])
" not tested, because it doesn't give an error but a warning:
" hi clear This# comment',
# not tested, because it doesn't give an error but a warning:
# hi clear This# comment',
CheckScriptFailure([
'vim9script',
'hi clear# comment',
@@ -2091,19 +2244,19 @@ def Test_vim9_comment_not_compiled()
'bwipe!',
])
" CheckScriptFailure([
" 'vim9script',
" 'new'
" 'call setline(1, ["# define pat", "last"])',
" ':$',
" 'dsearch /pat/#comment',
" 'bwipe!',
" ], 'E488:')
"
" CheckScriptFailure([
" 'vim9script',
" 'func! SomeFunc()',
" ], 'E477:')
CheckScriptFailure([
'vim9script',
'new'
'call setline(1, ["# define pat", "last"])',
':$',
'dsearch /pat/#comment',
'bwipe!',
], 'E488:')
CheckScriptFailure([
'vim9script',
'func! SomeFunc()',
], 'E477:')
enddef
def Test_finish()
@@ -2135,12 +2288,12 @@ def Test_let_func_call()
return 'this'
endfunc
let val: string = GetValue()
" env var is always a string
# env var is always a string
let env = $TERM
END
writefile(lines, 'Xfinished')
source Xfinished
" GetValue() is not called during discovery phase
# GetValue() is not called during discovery phase
assert_equal(1, g:count)
unlet g:count
@@ -2169,7 +2322,7 @@ def Test_let_declaration()
g:var_uninit = var
var = 'text'
g:var_test = var
" prefixing s: is optional
# prefixing s: is optional
s:var = 'prefixed'
g:var_prefixed = s:var
@@ -2281,7 +2434,7 @@ def Test_source_vim9_from_legacy()
source Xlegacy_script.vim
assert_equal('global', g:global)
" unlet g:global
unlet g:global
delete('Xlegacy_script.vim')
delete('Xvim9_script.vim')
@@ -2301,7 +2454,7 @@ def Test_substitute_cmd()
assert_equal('otherthing', getline(1))
bwipe!
" also when the context is Vim9 script
# also when the context is Vim9 script
let lines =<< trim END
vim9script
new

View File

@@ -754,6 +754,46 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1237,
/**/
1236,
/**/
1235,
/**/
1234,
/**/
1233,
/**/
1232,
/**/
1231,
/**/
1230,
/**/
1229,
/**/
1228,
/**/
1227,
/**/
1226,
/**/
1225,
/**/
1224,
/**/
1223,
/**/
1222,
/**/
1221,
/**/
1220,
/**/
1219,
/**/
1218,
/**/
1217,
/**/

View File

@@ -2420,7 +2420,7 @@ free_imported(cctx_T *cctx)
* Return TRUE if "p" points at a "#" but not at "#{".
*/
static int
comment_start(char_u *p)
vim9_comment_start(char_u *p)
{
return p[0] == '#' && p[1] != '{';
}
@@ -2443,7 +2443,7 @@ peek_next_line_from_context(cctx_T *cctx)
if (line == NULL)
break;
p = skipwhite(line);
if (*p != NUL && !comment_start(p))
if (*p != NUL && !vim9_comment_start(p))
return p;
}
return NULL;
@@ -2461,7 +2461,7 @@ may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp)
char_u *p = skipwhite(arg);
*nextp = NULL;
if (*p == NUL || (VIM_ISWHITE(*arg) && comment_start(p)))
if (*p == NUL || (VIM_ISWHITE(*arg) && vim9_comment_start(p)))
{
*nextp = peek_next_line_from_context(cctx);
if (*nextp != NULL)
@@ -2492,7 +2492,7 @@ next_line_from_context(cctx_T *cctx, int skip_comment)
cctx->ctx_line_start = line;
SOURCING_LNUM = cctx->ctx_lnum + 1;
} while (line == NULL || *skipwhite(line) == NUL
|| (skip_comment && comment_start(skipwhite(line))));
|| (skip_comment && vim9_comment_start(skipwhite(line))));
return line;
}
@@ -2504,7 +2504,7 @@ next_line_from_context(cctx_T *cctx, int skip_comment)
static int
may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx)
{
if (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg)))
if (**arg == NUL || (VIM_ISWHITE(*whitep) && vim9_comment_start(*arg)))
{
char_u *next = next_line_from_context(cctx, TRUE);
@@ -3100,7 +3100,7 @@ compile_list(char_u **arg, cctx_T *cctx)
{
++p;
// Allow for following comment, after at least one space.
if (VIM_ISWHITE(*p) && *skipwhite(p) == '"')
if (VIM_ISWHITE(*p) && *skipwhite(p) == '#')
p += STRLEN(p);
break;
}
@@ -3157,6 +3157,8 @@ compile_lambda(char_u **arg, cctx_T *cctx)
if (ufunc->uf_def_status == UF_COMPILED)
return generate_FUNCREF(cctx, ufunc->uf_dfunc_idx);
func_ptr_unref(ufunc);
return FAIL;
}
@@ -3201,6 +3203,8 @@ compile_lambda_call(char_u **arg, cctx_T *cctx)
// call the compiled function
ret = generate_CALL(cctx, ufunc, argcount);
if (ret == FAIL)
func_ptr_unref(ufunc);
return ret;
}
@@ -3327,7 +3331,7 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
// Allow for following comment, after at least one space.
p = skipwhite(*arg);
if (VIM_ISWHITE(**arg) && (*p == '"' || comment_start(p)))
if (VIM_ISWHITE(**arg) && vim9_comment_start(p))
*arg += STRLEN(*arg);
dict_unref(d);
@@ -3618,7 +3622,7 @@ compile_subscript(
{
char_u *p = skipwhite(*arg);
if (*p == NUL || (VIM_ISWHITE(**arg) && comment_start(p)))
if (*p == NUL || (VIM_ISWHITE(**arg) && vim9_comment_start(p)))
{
char_u *next = peek_next_line_from_context(cctx);
@@ -4957,6 +4961,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
}
if (need_type(stacktype, &t_list_any, -1, cctx, FALSE) == FAIL)
goto theend;
// TODO: check the length of a constant list here
generate_CHECKLEN(cctx, semicolon ? var_count - 1 : var_count,
semicolon);
}
@@ -6535,6 +6540,7 @@ compile_finally(char_u *arg, cctx_T *cctx)
// Previous catch without match jumps here
isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
isn->isn_arg.jump.jump_where = instr->ga_len;
scope->se_u.se_try.ts_catch_label = 0;
}
// TODO: set index in ts_finally_label jumps
@@ -6580,8 +6586,18 @@ compile_endtry(char_u *arg, cctx_T *cctx)
compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx);
// End :catch or :finally scope: set value in ISN_TRY instruction
if (isn->isn_arg.try.try_catch == 0)
isn->isn_arg.try.try_catch = instr->ga_len;
if (isn->isn_arg.try.try_finally == 0)
isn->isn_arg.try.try_finally = instr->ga_len;
if (scope->se_u.se_try.ts_catch_label != 0)
{
// Last catch without match jumps here
isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
isn->isn_arg.jump.jump_where = instr->ga_len;
}
compile_endblock(cctx);
if (generate_instr(cctx, ISN_ENDTRY) == NULL)
@@ -6865,7 +6881,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
val_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
if (ufunc->uf_arg_types[arg_idx] == &t_unknown)
ufunc->uf_arg_types[arg_idx] = val_type;
else if (check_type(ufunc->uf_arg_types[i], val_type, FALSE)
else if (check_type(ufunc->uf_arg_types[arg_idx], val_type, FALSE)
== FAIL)
{
arg_type_mismatch(ufunc->uf_arg_types[arg_idx], val_type,
@@ -7048,13 +7064,17 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
/*
* COMMAND after range
* 'text'->func() should not be confused with 'a mark
*/
cmd = ea.cmd;
ea.cmd = skip_range(ea.cmd, NULL);
if (ea.cmd > cmd && !starts_with_colon)
if (*cmd != '\'')
{
emsg(_(e_colon_required));
goto erret;
ea.cmd = skip_range(ea.cmd, NULL);
if (ea.cmd > cmd && !starts_with_colon)
{
emsg(_(e_colon_required));
goto erret;
}
}
p = find_ex_command(&ea, NULL, starts_with_colon ? NULL
: (void *(*)(char_u *, size_t, cctx_T *))lookup_local,

View File

@@ -575,14 +575,32 @@ call_by_name(char_u *name, int argcount, ectx_T *ectx, isn_T *iptr)
}
static int
call_partial(typval_T *tv, int argcount, ectx_T *ectx)
call_partial(typval_T *tv, int argcount_arg, ectx_T *ectx)
{
int argcount = argcount_arg;
char_u *name = NULL;
int called_emsg_before = called_emsg;
if (tv->v_type == VAR_PARTIAL)
{
partial_T *pt = tv->vval.v_partial;
partial_T *pt = tv->vval.v_partial;
int i;
if (pt->pt_argc > 0)
{
// Make space for arguments from the partial, shift the "argcount"
// arguments up.
if (ga_grow(&ectx->ec_stack, pt->pt_argc) == FAIL)
return FAIL;
for (i = 1; i <= argcount; ++i)
*STACK_TV_BOT(-i + pt->pt_argc) = *STACK_TV_BOT(-i);
ectx->ec_stack.ga_len += pt->pt_argc;
argcount += pt->pt_argc;
// copy the arguments from the partial onto the stack
for (i = 0; i < pt->pt_argc; ++i)
copy_tv(&pt->pt_argv[i], STACK_TV_BOT(-argcount + i));
}
if (pt->pt_func != NULL)
{
@@ -1047,7 +1065,7 @@ call_def_function(
if (di == NULL)
{
semsg(_(e_undefvar), name);
goto failed;
goto on_error;
}
else
{
@@ -1095,7 +1113,7 @@ call_def_function(
{
semsg(_("E121: Undefined variable: %c:%s"),
namespace, iptr->isn_arg.string);
goto failed;
goto on_error;
}
else
{
@@ -1223,7 +1241,7 @@ call_def_function(
if (msg != NULL)
{
emsg(_(msg));
goto failed;
goto on_error;
}
}
break;
@@ -1254,7 +1272,8 @@ call_def_function(
--ectx.ec_stack.ga_len;
if (set_vim_var_tv(iptr->isn_arg.number, STACK_TV_BOT(0))
== FAIL)
goto failed;
// should not happen, type is checked when compiling
goto on_error;
break;
// store g:/b:/w:/t: variable
@@ -1317,7 +1336,7 @@ call_def_function(
if (lidx < 0 || lidx > list->lv_len)
{
semsg(_(e_listidx), lidx);
goto failed;
goto on_error;
}
tv = STACK_TV_BOT(-3);
if (lidx < list->lv_len)
@@ -1330,7 +1349,7 @@ call_def_function(
}
else
{
// append to list
// append to list, only fails when out of memory
if (list_append_tv(list, tv) == FAIL)
goto failed;
clear_tv(tv);
@@ -1353,18 +1372,19 @@ call_def_function(
if (key == NULL || *key == NUL)
{
emsg(_(e_emptykey));
goto failed;
goto on_error;
}
tv = STACK_TV_BOT(-3);
di = dict_find(dict, key, -1);
if (di != NULL)
{
// overwrite existing value
clear_tv(&di->di_tv);
di->di_tv = *tv;
}
else
{
// add to dict
// add to dict, only fails when out of memory
if (dict_add_tv(dict, (char *)key, tv) == FAIL)
goto failed;
clear_tv(tv);
@@ -1447,7 +1467,7 @@ call_def_function(
case ISN_UNLET:
if (do_unlet(iptr->isn_arg.unlet.ul_name,
iptr->isn_arg.unlet.ul_forceit) == FAIL)
goto failed;
goto on_error;
break;
case ISN_UNLETENV:
vim_unsetenv(iptr->isn_arg.unlet.ul_name);
@@ -1463,24 +1483,38 @@ call_def_function(
// create a dict from items on the stack
case ISN_NEWDICT:
{
int count = iptr->isn_arg.number;
dict_T *dict = dict_alloc();
dictitem_T *item;
int count = iptr->isn_arg.number;
dict_T *dict = dict_alloc();
dictitem_T *item;
if (dict == NULL)
goto failed;
for (idx = 0; idx < count; ++idx)
{
// check key type is VAR_STRING
// have already checked key type is VAR_STRING
tv = STACK_TV_BOT(2 * (idx - count));
// check key is unique
item = dict_find(dict, tv->vval.v_string, -1);
if (item != NULL)
{
semsg(_(e_duplicate_key), tv->vval.v_string);
dict_unref(dict);
goto on_error;
}
item = dictitem_alloc(tv->vval.v_string);
clear_tv(tv);
if (item == NULL)
{
dict_unref(dict);
goto failed;
}
item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1);
item->di_tv.v_lock = 0;
if (dict_add(dict, item) == FAIL)
{
dict_unref(dict);
goto failed;
}
}
if (count > 0)
@@ -1501,7 +1535,7 @@ call_def_function(
if (call_dfunc(iptr->isn_arg.dfunc.cdf_idx,
iptr->isn_arg.dfunc.cdf_argcount,
&ectx) == FAIL)
goto failed;
goto on_error;
break;
// call a builtin function
@@ -1768,6 +1802,7 @@ call_def_function(
--trystack->ga_len;
--trylevel;
ectx.ec_in_catch = FALSE;
trycmd = ((trycmd_T *)trystack->ga_data)
+ trystack->ga_len;
if (trycmd->tcd_caught && current_exception != NULL)
@@ -2066,7 +2101,8 @@ call_def_function(
case EXPR_DIV: f1 = f1 / f2; break;
case EXPR_SUB: f1 = f1 - f2; break;
case EXPR_ADD: f1 = f1 + f2; break;
default: emsg(_(e_modulus)); goto failed;
default: emsg(_(e_modulus));
goto on_error;
}
clear_tv(tv1);
clear_tv(tv2);
@@ -2120,7 +2156,7 @@ call_def_function(
if (tv->v_type != VAR_LIST)
{
emsg(_(e_listreq));
goto failed;
goto on_error;
}
list = tv->vval.v_list;
@@ -2128,18 +2164,18 @@ call_def_function(
if (tv->v_type != VAR_NUMBER)
{
emsg(_(e_number_exp));
goto failed;
goto on_error;
}
n = tv->vval.v_number;
clear_tv(tv);
if ((li = list_find(list, n)) == NULL)
{
semsg(_(e_listidx), n);
goto failed;
goto on_error;
}
--ectx.ec_stack.ga_len;
// Clear the list after getting the item, to avoid that it
// make the item invalid.
// makes the item invalid.
tv = STACK_TV_BOT(-1);
temp_tv = *tv;
copy_tv(&li->li_tv, tv);
@@ -2208,7 +2244,7 @@ call_def_function(
if ((di = dict_find(dict, key, -1)) == NULL)
{
semsg(_(e_dictkey), key);
goto failed;
goto on_error;
}
clear_tv(tv);
--ectx.ec_stack.ga_len;
@@ -2259,7 +2295,7 @@ call_def_function(
)
{
emsg(_(e_number_exp));
goto failed;
goto on_error;
}
#ifdef FEAT_FLOAT
if (tv->v_type == VAR_FLOAT)
@@ -2275,10 +2311,10 @@ call_def_function(
tv = STACK_TV_BOT(-1);
if (check_not_string(tv) == FAIL)
goto failed;
goto on_error;
(void)tv_get_number_chk(tv, &error);
if (error)
goto failed;
goto on_error;
}
break;
@@ -2297,7 +2333,7 @@ call_def_function(
semsg(_("E1029: Expected %s but got %s"),
vartype_name(ct->ct_type),
vartype_name(tv->v_type));
goto failed;
goto on_error;
}
}
break;
@@ -2316,7 +2352,7 @@ call_def_function(
{
semsg(_("E1093: Expected %d items but got %d"),
min_len, list == NULL ? 0 : list->lv_len);
goto failed;
goto on_error;
}
}
break;
@@ -2371,6 +2407,11 @@ call_def_function(
clear_tv(STACK_TV_BOT(0));
break;
}
continue;
on_error:
if (trylevel == 0)
goto failed;
}
done: