Compare commits

..

27 Commits

Author SHA1 Message Date
zeertzjq
a4e3332650 patch 8.2.4819: unmapping simplified keys also deletes other mapping
Problem:    Unmapping simplified keys also deletes other mapping.
Solution:   Only unmap a mapping with m_simplified set. (closes #10270)
2022-04-24 17:07:53 +01:00
zeertzjq
ac92ab7719 patch 8.2.4818: no test for what 8.2.4806 fixes
Problem:    No test for what 8.2.4806 fixes.
Solution:   Add a test. (closes #10727)
2022-04-24 15:58:30 +01:00
LemonBoy
45684c6ec4 patch 8.2.4817: Win32 GUI: modifiers are not always used
Problem:    Win32 GUI: modifiers are not always used.
Solution:   Handle more modifiers. (closes #10269)
2022-04-24 15:46:42 +01:00
Philip H
490ac3fe98 patch 8.2.4816: still using older codecov app in some places of CI
Problem:    Still using older codecov app in some places of CI.
Solution:   Use v3.1.0. (closes #10209)
2022-04-24 12:44:32 +01:00
Ernie Rael
d42b83942e patch 8.2.4815: cannot build with older GTK version
Problem:    Cannot build with older GTK version.
Solution:   Use gtk_window_get_size() instead of gdk_window_get_width() and
            gdk_window_get_height(). (Ernie Rael, closes #10257)
2022-04-23 19:52:23 +01:00
LemonBoy
4a392d2440 patch 8.2.4814: possible to leave a popup window with win_gotoid()
Problem:    Possible to leave a popup window with win_gotoid().
Solution:   Give an error when trying to leave a popup window with
            win_gotoid(). (closes #10253)
2022-04-23 14:07:56 +01:00
Brandon Simmons
2c40707baa patch 8.2.4813: pasting text while indent folding may mess up folds
Problem:    Pasting text while indent folding may mess up folds.
Solution:   Adjust the way folds are split. (Brandon Simmons, closes #10254)
2022-04-23 13:50:17 +01:00
zeertzjq
8279cfe499 patch 8.2.4812: unused struct item
Problem:    Unused struct item.
Solution:   Remove "lines" match_T.  Simplify the code. (closes #10256)
2022-04-23 12:05:51 +01:00
LemonBoy
0de7369fd4 patch 8.2.4811: Win32 GUI: caps lock doesn't work
Problem:    Win32 GUI: caps lock doesn't work.
Solution:   Handle VK_CAPITAL. (closes #10260, closes #10258)
2022-04-23 11:08:11 +01:00
Bram Moolenaar
56dba60216 patch 8.2.4810: missing changes in one file
Problem:    Missing changes in one file.
Solution:   Also change the struct initializers.
2022-04-23 11:03:58 +01:00
Yegappan Lakshmanan
885de449c0 patch 8.2.4809: various things no6 properly tested
Problem:    Various things no6 properly tested.
Solution:   Add various test cases. (Yegappan Lakshmanan, closes #10259)
2022-04-23 10:51:14 +01:00
Bram Moolenaar
33d3ce640c patch 8.2.4808: unused item in engine struct
Problem:    Unused item in engine struct.
Solution:   Remove "expr".  Add comment with tags.
2022-04-23 10:41:35 +01:00
LemonBoy
77fc0b02e5 patch 8.2.4807: processing key eveints in Win32 GUI is not ideal
Problem:    Processing key eveints in Win32 GUI is not ideal.
Solution:   Improve processing of key events. (closes #10155)
2022-04-22 22:45:52 +01:00
Bram Moolenaar
53ef573148 patch 8.2.4806: a mapping using <LeftDrag> does not start Select mode
Problem:    A mapping using <LeftDrag> does not start Select mode.
Solution:   When checking for starting select mode with the mouse also do this
            when there is typeahead. (closes #10249)
2022-04-22 21:20:26 +01:00
Bram Moolenaar
9b36750640 patch 8.2.4805: CurSearch used for all matches in current line
Problem:    CurSearch used for all matches in current line.
Solution:   Don't use the non-zero line count. (closes #10247)
2022-04-22 20:07:21 +01:00
Yegappan Lakshmanan
1fc6ea9bf3 patch 8.2.4804: expression in heredoc doesn't work for compiled function
Problem:    Expression in heredoc doesn't work for compiled function.
Solution:   Implement compiling the heredoc expressions. (Yegappan Lakshmanan,
            closes #10232)
2022-04-21 23:30:15 +01:00
LemonBoy
66e13aedc7 patch 8.2.4803: WinScrolled not always triggered when scrolling with mouse
Problem:    WinScrolled not always triggered when scrolling with the mouse.
Solution:   Add calls to may_trigger_winscrolled(). (closes #10246)
2022-04-21 22:52:11 +01:00
zeertzjq
7851c69a12 patch 8.2.4802: test is not cleaned up
Problem:    Test is not cleaned up.
Solution:   Make test clean up after itself.  Avoid NUL. (closes #10233)
2022-04-21 11:14:01 +01:00
Christian Brabandt
3fd7480cd2 patch 8.2.4801: fix for cursorbind fix not fully tested
Problem:    Fix for cursorbind fix not fully tested.
Solution:   Add another test case. (Christian Brabandt, closes #10240)
2022-04-20 22:07:41 +01:00
Bram Moolenaar
d0eaf675aa patch 8.2.4800: missing test update for adjusted t_8u behavior
Problem:    Missing test update for adjusted t_8u behavior.
Solution:   Update and extend the test.
2022-04-20 19:55:37 +01:00
LemonBoy
0044e5100a patch 8.2.4799: popup does not use correct topline
Problem:    Popup does not use correct topline.
Solution:   Also add one when firstline is negative. (closes #10229)
2022-04-20 19:47:37 +01:00
Bram Moolenaar
dbec26d789 patch 8.2.4798: t_8u option was reset even when set by the user
Problem:    t_8u option was reset even when set by the user.
Solution:   Only reset t_8u when using the default value. (closes #10239)
2022-04-20 19:08:50 +01:00
LemonBoy
8530b41fd3 patch 8.2.4797: getwininfo() may get oudated values
Problem:    getwininfo() may get oudated values.
Solution:   Make sure w_botline is up-to-date. (closes #10226)
2022-04-20 19:00:36 +01:00
Bram Moolenaar
da1050cd6f patch 8.2.4796: file left behind after running cursorline tests
Problem:    File left behind after running cursorline tests.
Solution:   Uncomment the line that deletes the file.
2022-04-20 18:41:49 +01:00
Christian Brabandt
2c645e8b00 patch 8.2.4795: 'cursorbind' scrolling depends on whether 'cursorline' is set
Problem:    'cursorbind' scrolling depends on whether 'cursorline' is set.
Solution:   Always call validate_cursor(). (Christian Brabandt, closes #10230,
            closes #10014)
2022-04-20 14:52:01 +01:00
Bram Moolenaar
4c84dd33ad patch 8.2.4794: compiler warning for not initialized variable
Problem:    Compiler warning for not initialized variable.
Solution:   Initialize the variable. (John Marriott)
2022-04-20 10:22:54 +01:00
Bram Moolenaar
928a131356 patch 8.2.4793: recognizing Maxima filetype even though it might be another
Problem:    Recognizing Maxima filetype even though it might be another.
Solution:   Remove *.mc and *.dem patterns from Maxima files
2022-04-19 19:38:38 +01:00
51 changed files with 872 additions and 235 deletions

View File

@@ -254,7 +254,7 @@ jobs:
- name: Codecov
if: matrix.coverage
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v3.1.0
with:
flags: linux,${{ matrix.features }}-${{ matrix.compiler }}-${{ matrix.extra }}
@@ -600,14 +600,14 @@ jobs:
- name: Codecov (gVim)
if: matrix.coverage
uses: codecov/codecov-action@v2
uses: codecov/codecov-action@v3.1.0
with:
directory: src
flags: windows,${{ matrix.toolchain }}-${{ matrix.arch }}-${{ matrix.features }}-gui
- name: Codecov (Vim)
if: matrix.coverage
uses: codecov/codecov-action@v2
uses: codecov/codecov-action@v3.1.0
with:
directory: src2
flags: windows,${{ matrix.toolchain }}-${{ matrix.arch }}-${{ matrix.features }}

View File

@@ -3247,8 +3247,6 @@ text...
expression evaluation fails, then the assignment fails.
once the "`=" has been found {expr} and a backtick
must follow. {expr} cannot be empty.
Currenty, in a compiled function {expr} is evaluated
when compiling the function, THIS WILL CHANGE.
{endmarker} must not contain white space.
{endmarker} cannot start with a lower case character.

View File

@@ -155,18 +155,21 @@ au BufNewFile,BufRead *.asp
\ setf aspvbs |
\ endif
" Grub (must be before catch *.lst)
" Grub (must be before pattern *.lst)
au BufNewFile,BufRead */boot/grub/menu.lst,*/boot/grub/grub.conf,*/etc/grub.conf setf grub
" Maxima, see:
" https://maxima.sourceforge.io/docs/manual/maxima_71.html#file_005ftype_005fmaxima
au BufNewFile,BufRead *.mc,*.demo,*.dem,*.dm{1,2,3,t},*.wxm,maxima-init.mac setf maxima
" Must be before the pattern *.mac.
" *.dem omitted - also used by gnuplot demos
" *.mc omitted - used by dist#ft#McSetf()
au BufNewFile,BufRead *.demo,*.dm{1,2,3,t},*.wxm,maxima-init.mac setf maxima
" Assembly (all kinds)
" *.lst is not pure assembly, it has two extra columns (address, byte codes)
au BufNewFile,BufRead *.asm,*.[sS],*.[aA],*.mac,*.lst call dist#ft#FTasm()
" Macro (VAX)
" Assembly - Macro (VAX)
au BufNewFile,BufRead *.mar setf vmasm
" Atlas
@@ -1682,7 +1685,8 @@ au BufNewFile,BufRead *.siv,*.sieve setf sieve
" Sendmail
au BufNewFile,BufRead sendmail.cf setf sm
" Sendmail .mc files are actually m4. Could also be MS Message text file.
" Sendmail .mc files are actually m4. Could also be MS Message text file or
" Maxima.
au BufNewFile,BufRead *.mc call dist#ft#McSetf()
" Services

View File

@@ -673,16 +673,21 @@ eval_all_expr_in_str(char_u *str)
*
* The {marker} is a string. If the optional 'trim' word is supplied before the
* marker, then the leading indentation before the lines (matching the
* indentation in the 'cmd' line) is stripped.
* indentation in the "cmd" line) is stripped.
*
* When getting lines for an embedded script (e.g. python, lua, perl, ruby,
* tcl, mzscheme), script_get is set to TRUE. In this case, if the marker is
* tcl, mzscheme), "script_get" is set to TRUE. In this case, if the marker is
* missing, then '.' is accepted as a marker.
*
* When compiling a heredoc assignment to a variable in a Vim9 def function,
* "vim9compile" is set to TRUE. In this case, instead of generating a list of
* string values from the heredoc, vim9 instructions are generated. On success
* the returned list will be empty.
*
* Returns a List with {lines} or NULL on failure.
*/
list_T *
heredoc_get(exarg_T *eap, char_u *cmd, int script_get)
heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
{
char_u *theline = NULL;
char_u *marker;
@@ -696,6 +701,8 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get)
int comment_char = in_vim9script() ? '#' : '"';
int evalstr = FALSE;
int eval_failed = FALSE;
cctx_T *cctx = vim9compile ? eap->cookie : NULL;
int count = 0;
if (eap->getline == NULL)
{
@@ -816,25 +823,41 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get)
break;
str = theline + ti;
if (evalstr)
if (vim9compile)
{
str = eval_all_expr_in_str(str);
if (str == NULL)
if (compile_heredoc_string(str, evalstr, cctx) == FAIL)
{
// expression evaluation failed
eval_failed = TRUE;
continue;
vim_free(theline);
vim_free(text_indent);
return FAIL;
}
vim_free(theline);
theline = str;
count++;
}
else
{
if (evalstr)
{
str = eval_all_expr_in_str(str);
if (str == NULL)
{
// expression evaluation failed
eval_failed = TRUE;
continue;
}
vim_free(theline);
theline = str;
}
if (list_append_string(l, str, -1) == FAIL)
break;
if (list_append_string(l, str, -1) == FAIL)
break;
}
}
vim_free(theline);
vim_free(text_indent);
if (vim9compile && cctx->ctx_skip != SKIP_YES && !eval_failed)
generate_NEWLIST(cctx, count, FALSE);
if (eval_failed)
{
// expression evaluation in the heredoc failed
@@ -986,7 +1009,7 @@ ex_let(exarg_T *eap)
long cur_lnum = SOURCING_LNUM;
// HERE document
l = heredoc_get(eap, expr + 3, FALSE);
l = heredoc_get(eap, expr + 3, FALSE, FALSE);
if (l != NULL)
{
rettv_list_set(&rettv, l);

View File

@@ -395,6 +395,9 @@ get_win_info(win_T *wp, short tpnr, short winnr)
if (dict == NULL)
return NULL;
// make sure w_botline is valid
validate_botline_win(wp);
dict_add_number(dict, "tabnr", tpnr);
dict_add_number(dict, "winnr", winnr);
dict_add_number(dict, "winid", wp->w_id);
@@ -813,6 +816,13 @@ f_win_gotoid(typval_T *argvars, typval_T *rettv)
emsg(_(e_invalid_in_cmdline_window));
return;
}
#endif
#if defined(FEAT_PROP_POPUP) && defined(FEAT_TERMINAL)
if (popup_is_popup(curwin) && curbuf->b_term != NULL)
{
emsg(_(e_not_allowed_for_terminal_in_popup_window));
return;
}
#endif
FOR_ALL_TAB_WINDOWS(tp, wp)
if (wp->w_id == id)

View File

@@ -4605,7 +4605,7 @@ script_get(exarg_T *eap UNUSED, char_u *cmd UNUSED)
return NULL;
cmd += 2;
l = heredoc_get(eap, cmd, TRUE);
l = heredoc_get(eap, cmd, TRUE, FALSE);
if (l == NULL)
return NULL;

View File

@@ -1128,7 +1128,7 @@ cloneFoldGrowArray(garray_T *from, garray_T *to)
// foldFind() {{{2
/*
* Search for line "lnum" in folds of growarray "gap".
* Set *fpp to the fold struct for the fold that contains "lnum" or
* Set "*fpp" to the fold struct for the fold that contains "lnum" or
* the first fold below it (careful: it can be beyond the end of the array!).
* Returns FALSE when there is no fold that contains "lnum".
*/
@@ -2911,7 +2911,8 @@ foldSplit(
// any between top and bot, they have been removed by the caller.
gap1 = &fp->fd_nested;
gap2 = &fp[1].fd_nested;
if (foldFind(gap1, bot + 1 - fp->fd_top, &fp2))
(void)foldFind(gap1, bot + 1 - fp->fd_top, &fp2);
if (fp2 != NULL)
{
len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2);
if (len > 0 && ga_grow(gap2, len) == OK)

View File

@@ -396,6 +396,9 @@ static int using_gnome = 0;
# define using_gnome 0
#endif
// Comment out the following line to ignore code for resize history tracking.
#define TRACK_RESIZE_HISTORY
#ifdef TRACK_RESIZE_HISTORY
/*
* Keep a short term resize history so that stale gtk responses can be
* discarded.
@@ -403,11 +406,11 @@ static int using_gnome = 0;
* the request is saved. Recent stale requests are kept around in a list.
* See https://github.com/vim/vim/issues/10123
*/
#if 0 // Change to 1 to enable ch_log() calls for debugging.
# ifdef FEAT_JOB_CHANNEL
# define ENABLE_RESIZE_HISTORY_LOG
# if 0 // Change to 1 to enable ch_log() calls for debugging.
# ifdef FEAT_JOB_CHANNEL
# define ENABLE_RESIZE_HISTORY_LOG
# endif
# endif
#endif
/*
* History item of a resize request.
@@ -417,9 +420,9 @@ typedef struct resize_history {
int used; // If true, can't match for discard. Only matches once.
int width;
int height;
#ifdef ENABLE_RESIZE_HISTORY_LOG
# ifdef ENABLE_RESIZE_HISTORY_LOG
int seq; // for ch_log messages
#endif
# endif
struct resize_history *next;
} resize_hist_T;
@@ -448,11 +451,11 @@ alloc_resize_hist(int width, int height)
prev_hist->next = old_resize_hists;
old_resize_hists = prev_hist;
#ifdef ENABLE_RESIZE_HISTORY_LOG
# ifdef ENABLE_RESIZE_HISTORY_LOG
new_hist->seq = prev_hist->seq + 1;
ch_log(NULL, "gui_gtk: New resize seq %d (%d, %d) [%d, %d]",
new_hist->seq, width, height, (int)Columns, (int)Rows);
#endif
# endif
}
/*
@@ -462,9 +465,9 @@ alloc_resize_hist(int width, int height)
static void
clear_resize_hists()
{
#ifdef ENABLE_RESIZE_HISTORY_LOG
# ifdef ENABLE_RESIZE_HISTORY_LOG
int i = 0;
#endif
# endif
if (latest_resize_hist)
latest_resize_hist->used = TRUE;
@@ -474,17 +477,17 @@ clear_resize_hists()
vim_free(old_resize_hists);
old_resize_hists = next_hist;
#ifdef ENABLE_RESIZE_HISTORY_LOG
# ifdef ENABLE_RESIZE_HISTORY_LOG
i++;
#endif
# endif
}
#ifdef ENABLE_RESIZE_HISTORY_LOG
# ifdef ENABLE_RESIZE_HISTORY_LOG
ch_log(NULL, "gui_gtk: free %d hists", i);
#endif
# endif
}
// true if hist item is unused and matches w,h
#define MATCH_WIDTH_HEIGHT(hist, w, h) \
# define MATCH_WIDTH_HEIGHT(hist, w, h) \
(!hist->used && hist->width == w && hist->height == h)
/*
@@ -501,23 +504,24 @@ match_stale_width_height(int width, int height)
for (hist = old_resize_hists; hist != NULL; hist = hist->next)
if (MATCH_WIDTH_HEIGHT(hist, width, height))
{
#ifdef ENABLE_RESIZE_HISTORY_LOG
# ifdef ENABLE_RESIZE_HISTORY_LOG
ch_log(NULL, "gui_gtk: discard seq %d, cur seq %d",
hist->seq, latest_resize_hist->seq);
#endif
# endif
hist->used = TRUE;
return TRUE;
}
return FALSE;
}
#if defined(EXITFREE)
# if defined(EXITFREE)
static void
free_all_resize_hist()
{
clear_resize_hists();
vim_free(latest_resize_hist);
}
# endif
#endif
/*
@@ -717,7 +721,9 @@ gui_mch_free_all(void)
#if defined(USE_GNOME_SESSION)
vim_free(abs_restart_command);
#endif
#ifdef TRACK_RESIZE_HISTORY
free_all_resize_hist();
#endif
}
#endif
@@ -4131,26 +4137,26 @@ form_configure_event(GtkWidget *widget UNUSED,
GdkEventConfigure *event,
gpointer data UNUSED)
{
int usable_height = event->height;
// Resize requests are made for gui.mainwin,
// get it's dimensions for searching if this event
int usable_height = event->height;
#ifdef TRACK_RESIZE_HISTORY
// Resize requests are made for gui.mainwin;
// get its dimensions for searching if this event
// is a response to a vim request.
GdkWindow *win = gtk_widget_get_window(gui.mainwin);
int w = gdk_window_get_width(win);
int h = gdk_window_get_height(win);
int w, h;
gtk_window_get_size(GTK_WINDOW(gui.mainwin), &w, &h);
#ifdef ENABLE_RESIZE_HISTORY_LOG
# ifdef ENABLE_RESIZE_HISTORY_LOG
ch_log(NULL, "gui_gtk: form_configure_event: (%d, %d) [%d, %d]",
w, h, (int)Columns, (int)Rows);
#endif
# endif
// Look through history of recent vim resize reqeusts.
// Look through history of recent vim resize requests.
// If this event matches:
// - "latest resize hist" We're caught up;
// clear the history and process this event.
// If history is, old to new, 100, 99, 100, 99. If this event is
// 99 for the stale, it is matched against the current. History
// is cleared, we my bounce, but no worse than before.
// is cleared, we may bounce, but no worse than before.
// - "older/stale hist" If match an unused event in history,
// then discard this event, and mark the matching event as used.
// - "no match" Figure it's a user resize event, clear history.
@@ -4161,6 +4167,7 @@ form_configure_event(GtkWidget *widget UNUSED,
// discard stale event
return TRUE;
clear_resize_hists();
#endif
#if GTK_CHECK_VERSION(3,22,2) && !GTK_CHECK_VERSION(3,22,4)
// As of 3.22.2, GdkWindows have started distributing configure events to
@@ -4483,7 +4490,9 @@ gui_mch_open(void)
* manager upon us and should not interfere with what VIM is requesting
* upon startup.
*/
#ifdef TRACK_RESIZE_HISTORY
latest_resize_hist = ALLOC_CLEAR_ONE(resize_hist_T);
#endif
g_signal_connect(G_OBJECT(gui.formwin), "configure-event",
G_CALLBACK(form_configure_event), NULL);
@@ -4671,7 +4680,9 @@ gui_mch_set_shellsize(int width, int height,
width += get_menu_tool_width();
height += get_menu_tool_height();
#ifdef TRACK_RESIZE_HISTORY
alloc_resize_hist(width, height); // track the resize request
#endif
if (gtk_socket_id == 0)
gtk_window_resize(GTK_WINDOW(gui.mainwin), width, height);
else

View File

@@ -818,20 +818,62 @@ char_to_string(int ch, char_u *string, int slen, int had_alt)
return len;
}
static int
get_active_modifiers(void)
{
int modifiers = 0;
if (GetKeyState(VK_CONTROL) & 0x8000)
modifiers |= MOD_MASK_CTRL;
if (GetKeyState(VK_SHIFT) & 0x8000)
modifiers |= MOD_MASK_SHIFT;
if (GetKeyState(VK_MENU) & 0x8000)
modifiers |= MOD_MASK_ALT;
// Windows handles Ctrl + Alt as AltGr, in that case no modifier is actually
// pressed.
if ((modifiers & (MOD_MASK_CTRL | MOD_MASK_ALT)) ==
(MOD_MASK_CTRL | MOD_MASK_ALT))
modifiers &= ~(MOD_MASK_CTRL | MOD_MASK_ALT);
return modifiers;
}
/*
* Key hit, add it to the input buffer.
*/
static void
_OnChar(
HWND hwnd UNUSED,
UINT ch,
UINT cch,
int cRepeat UNUSED)
{
char_u string[40];
int len = 0;
int modifiers;
int ch = cch; // special keys are negative
dead_key = 0;
modifiers = get_active_modifiers();
ch = simplify_key(ch, &modifiers);
// remove the SHIFT modifier for keys where it's already included, e.g.,
// '(' and '*'
modifiers = may_remove_shift_modifier(modifiers, ch);
// Unify modifiers somewhat. No longer use ALT to set the 8th bit.
ch = extract_modifiers(ch, &modifiers, FALSE, NULL);
if (ch == CSI)
ch = K_CSI;
if (modifiers)
{
string[0] = CSI;
string[1] = KS_MODIFIER;
string[2] = modifiers;
add_to_input_buf(string, 3);
}
len = char_to_string(ch, string, 40, FALSE);
if (len == 1 && string[0] == Ctrl_C && ctrl_c_interrupts)
{
@@ -858,18 +900,11 @@ _OnSysChar(
dead_key = 0;
// TRACE("OnSysChar(%d, %c)\n", ch, ch);
// OK, we have a character key (given by ch) which was entered with the
// ALT key pressed. Eg, if the user presses Alt-A, then ch == 'A'. Note
// that the system distinguishes Alt-a and Alt-A (Alt-Shift-a unless
// CAPSLOCK is pressed) at this point.
modifiers = MOD_MASK_ALT;
if (GetKeyState(VK_SHIFT) & 0x8000)
modifiers |= MOD_MASK_SHIFT;
if (GetKeyState(VK_CONTROL) & 0x8000)
modifiers |= MOD_MASK_CTRL;
modifiers = get_active_modifiers();
ch = simplify_key(ch, &modifiers);
// remove the SHIFT modifier for keys where it's already included, e.g.,
// '(' and '*'
@@ -1816,7 +1851,6 @@ outputDeadKey_rePost(MSG originalMsg)
originalMsg.lParam);
}
/*
* Process a single Windows message.
* If one is not available we hang until one is.
@@ -1833,6 +1867,7 @@ process_message(void)
#ifdef FEAT_MENU
static char_u k10[] = {K_SPECIAL, 'k', ';', 0};
#endif
BYTE keyboard_state[256];
GetMessageW(&msg, NULL, 0, 0);
@@ -1926,6 +1961,13 @@ process_message(void)
add_to_input_buf(string, 1);
}
// This is an IME event or a synthetic keystroke, let Windows handle it.
if (vk == VK_PROCESSKEY || vk == VK_PACKET)
{
TranslateMessage(&msg);
return;
}
for (i = 0; special_keys[i].key_sym != 0; i++)
{
// ignore VK_SPACE when ALT key pressed: system menu
@@ -1954,21 +1996,7 @@ process_message(void)
NULL, NULL) == NULL)
break;
#endif
if (GetKeyState(VK_SHIFT) & 0x8000)
modifiers |= MOD_MASK_SHIFT;
/*
* Don't use caps-lock as shift, because these are special keys
* being considered here, and we only want letters to get
* shifted -- webb
*/
/*
if (GetKeyState(VK_CAPITAL) & 0x0001)
modifiers ^= MOD_MASK_SHIFT;
*/
if (GetKeyState(VK_CONTROL) & 0x8000)
modifiers |= MOD_MASK_CTRL;
if (GetKeyState(VK_MENU) & 0x8000)
modifiers |= MOD_MASK_ALT;
modifiers = get_active_modifiers();
if (special_keys[i].vim_code1 == NUL)
key = special_keys[i].vim_code0;
@@ -2005,39 +2033,55 @@ process_message(void)
break;
}
}
// Not a special key.
if (special_keys[i].key_sym == 0)
{
// Some keys need C-S- where they should only need C-.
// Ignore 0xff, Windows XP sends it when NUMLOCK has changed since
// system startup (Helmut Stiegler, 2003 Oct 3).
if (vk != 0xff
&& (GetKeyState(VK_CONTROL) & 0x8000)
&& !(GetKeyState(VK_SHIFT) & 0x8000)
&& !(GetKeyState(VK_MENU) & 0x8000))
WCHAR ch[8];
int len;
int i;
UINT scan_code;
// Construct the state table with only a few modifiers, we don't
// really care about the presence of Ctrl/Alt as those modifiers are
// handled by Vim separately.
memset(keyboard_state, 0, 256);
if (GetKeyState(VK_SHIFT) & 0x8000)
keyboard_state[VK_SHIFT] = 0x80;
if (GetKeyState(VK_CAPITAL) & 0x0001)
keyboard_state[VK_CAPITAL] = 0x01;
// Alt-Gr is synthesized as Alt + Ctrl.
if ((GetKeyState(VK_MENU) & 0x8000) &&
(GetKeyState(VK_CONTROL) & 0x8000))
{
// CTRL-6 is '^'; Japanese keyboard maps '^' to vk == 0xDE
if (vk == '6' || MapVirtualKey(vk, 2) == (UINT)'^')
{
string[0] = Ctrl_HAT;
add_to_input_buf(string, 1);
}
// vk == 0xBD AZERTY for CTRL-'-', but CTRL-[ for * QWERTY!
else if (vk == 0xBD) // QWERTY for CTRL-'-'
{
string[0] = Ctrl__;
add_to_input_buf(string, 1);
}
// CTRL-2 is '@'; Japanese keyboard maps '@' to vk == 0xC0
else if (vk == '2' || MapVirtualKey(vk, 2) == (UINT)'@')
{
string[0] = Ctrl_AT;
add_to_input_buf(string, 1);
}
else
TranslateMessage(&msg);
keyboard_state[VK_MENU] = 0x80;
keyboard_state[VK_CONTROL] = 0x80;
}
// Translate the virtual key according to the current keyboard
// layout.
scan_code = MapVirtualKey(vk, MAPVK_VK_TO_VSC);
// Convert the scan-code into a sequence of zero or more unicode
// codepoints.
// If this is a dead key ToUnicode returns a negative value.
len = ToUnicode(vk, scan_code, keyboard_state, ch, ARRAY_LENGTH(ch),
0);
dead_key = len < 0;
if (len <= 0)
return;
// Post the message as TranslateMessage would do.
if (msg.message == WM_KEYDOWN)
{
for (i = 0; i < len; i++)
PostMessageW(msg.hwnd, WM_CHAR, ch[i], msg.lParam);
}
else
TranslateMessage(&msg);
{
for (i = 0; i < len; i++)
PostMessageW(msg.hwnd, WM_SYSCHAR, ch[i], msg.lParam);
}
}
}
#ifdef FEAT_MBYTE_IME
@@ -3728,8 +3772,6 @@ _OnDropFiles(
POINT pt;
int_u modifiers = 0;
// TRACE("_OnDropFiles: %d files dropped\n", cFiles);
// Obtain dropped position
DragQueryPoint(hDrop, &pt);
MapWindowPoints(s_hwnd, s_textArea, &pt, 1);
@@ -3754,11 +3796,13 @@ _OnDropFiles(
if (fnames != NULL)
{
if ((GetKeyState(VK_SHIFT) & 0x8000) != 0)
int kbd_modifiers = get_active_modifiers();
if ((kbd_modifiers & MOD_MASK_SHIFT) != 0)
modifiers |= MOUSE_SHIFT;
if ((GetKeyState(VK_CONTROL) & 0x8000) != 0)
if ((kbd_modifiers & MOD_MASK_CTRL) != 0)
modifiers |= MOUSE_CTRL;
if ((GetKeyState(VK_MENU) & 0x8000) != 0)
if ((kbd_modifiers & MOD_MASK_ALT) != 0)
modifiers |= MOUSE_ALT;
gui_handle_drop(pt.x, pt.y, modifiers, fnames, cFiles);
@@ -4580,10 +4624,8 @@ _WndProc(
WPARAM wParam,
LPARAM lParam)
{
/*
TRACE("WndProc: hwnd = %08x, msg = %x, wParam = %x, lParam = %x\n",
hwnd, uMsg, wParam, lParam);
*/
// TRACE("WndProc: hwnd = %08x, msg = %x, wParam = %x, lParam = %x\n",
// hwnd, uMsg, wParam, lParam);
HandleMouseHide(uMsg, lParam);
@@ -4635,20 +4677,6 @@ _WndProc(
}
break;
case WM_KEYUP:
// handle CTRL-/
if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 && wParam == 0xBF)
{
char_u string[4];
string[0] = CSI;
string[1] = KS_MODIFIER;
string[2] = MOD_MASK_CTRL;
string[3] = 0x2F;
add_to_input_buf(string, 4);
}
return 0L;
case WM_CHAR:
// Don't use HANDLE_MSG() for WM_CHAR, it truncates wParam to a single
// byte while we want the UTF-16 character value.

View File

@@ -1046,7 +1046,7 @@ inindent(int extra)
void
op_reindent(oparg_T *oap, int (*how)(void))
{
long i;
long i = 0;
char_u *l;
int amount;
linenr_T first_changed = 0;

View File

@@ -725,6 +725,9 @@ do_map(
mpp = &(mp->m_next);
continue;
}
if (did_simplify && keyround == 1
&& !mp->m_simplified)
break;
// We reset the indicated mode bits. If nothing
// is left the entry is deleted below.
mp->m_mode &= ~mode;
@@ -814,7 +817,10 @@ do_map(
{
// delete entry
if (!did_it)
retval = 2; // no match
{
if (!did_simplify || keyround == 2)
retval = 2; // no match
}
else if (*keys == Ctrl_C)
{
// If CTRL-C has been unmapped, reuse it for Interrupting.

View File

@@ -617,6 +617,26 @@ prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum)
}
}
/*
* Update "shl->has_cursor" based on the match in "shl" and the cursor
* position.
*/
static void
check_cur_search_hl(win_T *wp, match_T *shl)
{
linenr_T linecount = shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum;
if (wp->w_cursor.lnum >= shl->lnum
&& wp->w_cursor.lnum <= shl->lnum + linecount
&& (wp->w_cursor.lnum > shl->lnum
|| wp->w_cursor.col >= shl->rm.startpos[0].col)
&& (wp->w_cursor.lnum < shl->lnum + linecount
|| wp->w_cursor.col < shl->rm.endpos[0].col))
shl->has_cursor = TRUE;
else
shl->has_cursor = FALSE;
}
/*
* Prepare for 'hlsearch' and match highlighting in one window line.
* Return TRUE if there is such highlighting and set "search_attr" to the
@@ -653,7 +673,6 @@ prepare_search_hl_line(
shl = &cur->hl;
shl->startcol = MAXCOL;
shl->endcol = MAXCOL;
shl->lines = 0;
shl->attr_cur = 0;
shl->is_addpos = FALSE;
shl->has_cursor = FALSE;
@@ -677,20 +696,10 @@ prepare_search_hl_line(
shl->endcol = shl->rm.endpos[0].col;
else
shl->endcol = MAXCOL;
if (shl->rm.endpos[0].lnum != shl->rm.startpos[0].lnum)
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;
if (shl == search_hl)
check_cur_search_hl(wp, shl);
// Highlight one character for an empty match.
if (shl->startcol == shl->endcol)
@@ -811,6 +820,10 @@ update_search_hl(
else
shl->endcol = MAXCOL;
// check if the cursor is in the match
if (shl == search_hl)
check_cur_search_hl(wp, shl);
if (shl->startcol == shl->endcol)
{
// highlight empty match, try again after

View File

@@ -1127,6 +1127,7 @@ ins_mousescroll(int dir)
}
#endif
did_scroll = TRUE;
may_trigger_winscrolled();
}
curwin->w_redr_status = TRUE;
@@ -2087,6 +2088,7 @@ nv_mousescroll(cmdarg_T *cap)
if (curwin != old_curwin && curwin->w_p_cul)
redraw_for_cursorline(curwin);
# endif
may_trigger_winscrolled();
curwin->w_redr_status = TRUE;

View File

@@ -2918,10 +2918,7 @@ do_check_cursorbind(void)
restart_edit_save = restart_edit;
restart_edit = TRUE;
check_cursor();
# ifdef FEAT_SYN_HL
if (curwin->w_p_cul || curwin->w_p_cuc)
validate_cursor();
# endif
validate_cursor();
restart_edit = restart_edit_save;
// Correct cursor for multi-byte character.
if (has_mbyte)

View File

@@ -5527,12 +5527,13 @@ start_selection(void)
/*
* Start Select mode, if "c" is in 'selectmode' and not in a mapping or menu.
* When "c" is 'o' (checking for "mouse") then also when mapped.
*/
void
may_start_select(int c)
{
VIsual_select = (stuff_empty() && typebuf_typed()
&& (vim_strchr(p_slm, c) != NULL));
VIsual_select = (c == 'o' || (stuff_empty() && typebuf_typed()))
&& vim_strchr(p_slm, c) != NULL;
}
/*

View File

@@ -1414,7 +1414,7 @@ popup_adjust_position(win_T *wp)
}
if (wp->w_firstline < 0)
wp->w_topline = lnum > 0 ? lnum + 1 : lnum;
wp->w_topline = lnum + 1;
wp->w_has_scrollbar = wp->w_want_scrollbar
&& (wp->w_topline > 1 || lnum <= wp->w_buffer->b_ml.ml_line_count);

View File

@@ -13,7 +13,7 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr);
int get_spellword(list_T *list, char_u **pp);
void prepare_vimvar(int idx, typval_T *save_tv);
void restore_vimvar(int idx, typval_T *save_tv);
list_T *heredoc_get(exarg_T *eap, char_u *cmd, int script_get);
list_T *heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile);
void ex_var(exarg_T *eap);
void ex_let(exarg_T *eap);
int ex_let_vars(char_u *arg_start, typval_T *tv, int copy, int semicolon, int var_count, int flags, char_u *op);

View File

@@ -16,6 +16,7 @@ int may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx);
int may_get_next_line_error(char_u *whitep, char_u **arg, cctx_T *cctx);
void fill_exarg_from_cctx(exarg_T *eap, cctx_T *cctx);
int func_needs_compiling(ufunc_T *ufunc, compiletype_T compile_type);
int compile_heredoc_string(char_u *str, int evalstr, cctx_T *cctx);
int assignment_len(char_u *p, int *heredoc);
void vim9_declare_error(char_u *name);
int get_var_dest(char_u *name, assign_dest_T *dest, cmdidx_T cmdidx, int *option_scope, int *vimvaridx, type_T **type, cctx_T *cctx);

View File

@@ -2535,7 +2535,6 @@ static regengine_T bt_regengine =
bt_regfree,
bt_regexec_nl,
bt_regexec_multi,
(char_u *)""
};
#include "regexp_nfa.c"
@@ -2546,7 +2545,6 @@ static regengine_T nfa_regengine =
nfa_regfree,
nfa_regexec_nl,
nfa_regexec_multi,
(char_u *)""
};
// Which regexp engine to use? Needed for vim_regcomp().

View File

@@ -166,11 +166,15 @@ typedef struct
struct regengine
{
// bt_regcomp or nfa_regcomp
regprog_T *(*regcomp)(char_u*, int);
// bt_regfree or nfa_regfree
void (*regfree)(regprog_T *);
// bt_regexec_nl or nfa_regexec_nl
int (*regexec_nl)(regmatch_T *, char_u *, colnr_T, int);
// bt_regexec_mult or nfa_regexec_mult
long (*regexec_multi)(regmmatch_T *, win_T *, buf_T *, linenr_T, colnr_T, proftime_T *, int *);
char_u *expr;
//char_u *expr;
};
#endif // _REGEXP_H

View File

@@ -3331,7 +3331,6 @@ typedef struct
// found match (may continue in next line)
buf_T *buf; // the buffer to search for a match
linenr_T lnum; // the line to search for a match
linenr_T lines; // number of lines starting from lnum
int attr; // attributes to be used for a match
int attr_cur; // attributes currently active in win_line()
linenr_T first_lnum; // first lnum to search for multi-line pat

View File

@@ -4826,7 +4826,9 @@ handle_version_response(int first, int *arg, int argc, char_u *tp)
// This may cause some flicker. Alternative would be to set "t_8u"
// here if the terminal is expected to support it, but that might
// conflict with what was set in the .vimrc.
if (term_props[TPR_UNDERLINE_RGB].tpr_status != TPR_YES && *T_8U != NUL)
if (term_props[TPR_UNDERLINE_RGB].tpr_status != TPR_YES
&& *T_8U != NUL
&& !option_was_set((char_u *)"t_8u"))
{
set_string_option_direct((char_u *)"t_8u", -1, (char_u *)"",
OPT_FREE, 0);

View File

@@ -41,6 +41,21 @@ What you can use (see test_assert.vim for an example):
with "Skipped" so that it's clear this still needs work. E.g.: throw
"Skipped: Bug with <c-e> and popupmenu not fixed yet"
- The following environment variables are recognized and can be set to
influence the behavior of the test suite (see runtest.vim for details)
- $TEST_MAY_FAIL=Test_channel_one - ignore those failing tests
- $TEST_FILTER=Test_channel - only run test that match this pattern
- $TEST_SKIP_PAT=Test_channel - skip tests that match this pattern
- $TEST_NO_RETRY=yes - do not try to re-run failing tests
You can also set them in Vim:
:let $TEST_MAY_FAIL = 'Test_channel_one'
:let $TEST_FILTER = '_set_mode'
:let $TEST_SKIP_PAT = 'Test_loop_forever'
:let $TEST_NO_RETRY = 'yes'
Use an empty string to revert, e.g.:
:let $TEST_FILTER = ''
- See the start of runtest.vim for more help.
@@ -76,19 +91,24 @@ The file 'messages' contains the messages generated by the test script. If a
test fails, then the test.log file contains the error messages. If all the
tests are successful, then this file will be an empty file.
To run a single test function from a test script:
- To run a single test function from a test script:
$ ../vim -u NONE -S runtest.vim <test_file>.vim <function_name>
To run all the tests:
- To execute only specific test functions, add a second argument:
$ ../vim -u NONE -S runtest.vim test_channel.vim open_delay
- To run all the tests:
$ make
To run the test on MS-Windows using the MSVC nmake:
- To run the test on MS-Windows using the MSVC nmake:
> nmake -f Make_dos.mak
To run the tests with GUI Vim:
- To run the tests with GUI Vim:
$ make GUI_FLAG=-g
@@ -96,7 +116,6 @@ To run the tests with GUI Vim:
$ make VIMPROG=../gvim
To cleanup the temporary files after running the tests:
- To cleanup the temporary files after running the tests:
$ make clean

View File

@@ -2,7 +2,7 @@
>f+0&#4040ff13|o@1| +0&#ffffff0@56
|b|a|r| @56
|b|a|z| @56
|f+0&#ffff4012|o@1| +0&#ffffff0@56
|f+0&#ffff4012|o@1| +0&#ffffff0|t|h|e| |f+0&#ffff4012|o@1| +0&#ffffff0|a|n|d| |f+0&#ffff4012|o@1| +0&#ffffff0@40
|b|a|r| @56
|~+0#4040ff13&| @58
|~| @58

View File

@@ -2,7 +2,7 @@
|f+0&#ffff4012|o@1| +0&#ffffff0@56
|b|a|r| @56
|b|a|z| @56
>f+0&#4040ff13|o@1| +0&#ffffff0@56
>f+0&#4040ff13|o@1| +0&#ffffff0|t|h|e| |f+0&#ffff4012|o@1| +0&#ffffff0|a|n|d| |f+0&#ffff4012|o@1| +0&#ffffff0@40
|b|a|r| @56
|~+0#4040ff13&| @58
|~| @58

View File

@@ -0,0 +1,9 @@
|o+0&#ffffff0|n|e| @56
|f+0&#ffff4012|o@1| +0&#ffffff0@56
|b|a|r| @56
|b|a|z| @56
|f+0&#ffff4012|o@1| +0&#ffffff0|t|h|e| >f+0&#4040ff13|o@1| +0&#ffffff0|a|n|d| |f+0&#ffff4012|o@1| +0&#ffffff0@40
|b|a|r| @56
|~+0#4040ff13&| @58
|~| @58
|/+0#0000000&|f|o@1| @37|5|,|9| @10|A|l@1|

View File

@@ -0,0 +1,9 @@
|o+0&#ffffff0|n|e| @56
|f+0&#ffff4012|o@1| +0&#ffffff0@56
|b|a|r| @56
|b|a|z| @56
|f+0&#ffff4012|o@1| +0&#ffffff0|t|h|e| |f+0&#ffff4012|o@1| +0&#ffffff0|a|n|d| >f+0&#4040ff13|o@1| +0&#ffffff0@40
|b|a|r| @56
|~+0#4040ff13&| @58
|~| @58
|/+0#0000000&|f|o@1| @37|5|,|1|7| @9|A|l@1|

View File

@@ -0,0 +1,8 @@
|a+0&#ffffff0| |b@1| |c@1| |d@1| |e@1| |f@1| |g@1| ||+1&&|a+0&&@1| |b@1| |c@1| |d@1| |e@1| |f@1| |g@1> |h@1| |i@1| |j@1| |k@1| |l@1| |m@1| |n@1| |o@1| |p@1| |q@1| |r@1|
@19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32
@19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32
@19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32
@19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32
|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @52
|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|2|1| @2|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|2|1| @10|A|l@1
| +0&&@74

View File

@@ -0,0 +1,8 @@
| +0&#ffffff0|h@1| |i@1| |j@1| |k@1| |l@1| |m@1| |n||+1&&|a+0&&@1| |b@1| |c@1| |d@1| |e@1| |f@1| |g@1| |h@1| |i@1| |j@1| >k@1| |l@1| |m@1| |n@1| |o@1| |p@1| |q@1| |r@1|
@10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22
@10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22
@10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22
@10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22
|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @52
|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|3|1| @2|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|3|1| @10|A|l@1
| +0&&@74

View File

@@ -0,0 +1,8 @@
|a+8&#ffffff0| |b@1| |c@1| |d@1| |e@1| |f@1| |g@1| ||+1&&|a+8&&@1| |b@1| |c@1| |d@1| |e@1| |f@1| |g@1> |h@1| |i@1| |j@1| |k@1| |l@1| |m@1| |n@1| |o@1| |p@1| |q@1| |r@1|
| +0&&@18| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32
@19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32
@19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32
@19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32
|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @52
|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|2|1| @2|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|2|1| @10|A|l@1
|:+0&&|w|i|n|d|o| |:|s|e|t| |c|u|r|s|o|r|l|i|n|e| @52

View File

@@ -0,0 +1,8 @@
| +8&#ffffff0|h@1| |i@1| |j@1| |k@1| |l@1| |m@1| |n||+1&&|a+8&&@1| |b@1| |c@1| |d@1| |e@1| |f@1| |g@1| |h@1| |i@1| |j@1| >k@1| |l@1| |m@1| |n@1| |o@1| |p@1| |q@1| |r@1|
| +0&&@9| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22
@10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22
@10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22
@10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22
|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @52
|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|3|1| @2|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|3|1| @10|A|l@1
|:+0&&|w|i|n|d|o| |:|s|e|t| |c|u|r|s|o|r|l|i|n|e| @52

View File

@@ -0,0 +1,8 @@
|k+0&#ffffff0@1| |l@1| |m@1| |n@1| |o@1| |p@1| |q@1||+1&&|a+0&&@1| |b@1| |c@1| |d@1| |e@1| |f@1| |g@1| |h@1| |i@1| |j@1| |k@1| |l@1| |m@1| |n>n| |o@1| |p@1| |q@1| |r@1|
@20||+1&&| +0&&@53
@20||+1&&| +0&&@53
@20||+1&&| +0&&@53
@20||+1&&| +0&&@53
|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @52
|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|4|1| @2|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|4|1| @10|A|l@1
|:+0&&|w|i|n|d|o| |:|s|e|t| |n|o|c|u|r|s|o|r|l|i|n|e| |n|o|c|u|r|s|o|r|c|o|l|u|m|n| @35

View File

@@ -364,6 +364,37 @@ func Test_WinScrolled()
call delete('Xtest_winscrolled')
endfunc
func Test_WinScrolled_mouse()
CheckRunVimInTerminal
let lines =<< trim END
set nowrap scrolloff=0
set mouse=a term=xterm ttymouse=sgr mousetime=200 clipboard=
call setline(1, ['foo']->repeat(32))
split
let g:scrolled = 0
au WinScrolled * let g:scrolled += 1
END
call writefile(lines, 'Xtest_winscrolled_mouse')
let buf = RunVimInTerminal('-S Xtest_winscrolled_mouse', {'rows': 10})
" With the upper split focused, send a scroll-down event to the unfocused one.
call test_setmouse(7, 1)
call term_sendkeys(buf, "\<ScrollWheelDown>")
call TermWait(buf)
call term_sendkeys(buf, ":echo g:scrolled\<CR>")
call WaitForAssert({-> assert_match('^1', term_getline(buf, 10))}, 1000)
" Again, but this time while we're in insert mode.
call term_sendkeys(buf, "i\<ScrollWheelDown>\<Esc>")
call TermWait(buf)
call term_sendkeys(buf, ":echo g:scrolled\<CR>")
call WaitForAssert({-> assert_match('^2', term_getline(buf, 10))}, 1000)
call StopVimInTerminal(buf)
call delete('Xtest_winscrolled_mouse')
endfunc
func Test_WinScrolled_close_curwin()
CheckRunVimInTerminal
@@ -1572,7 +1603,7 @@ func Test_QuitPre()
" Close the other window, <afile> should be correct.
exe win_id2win(winid) . 'q'
call assert_equal('Xfoo', g:afile)
unlet g:afile
bwipe Xfoo
bwipe Xbar
@@ -3004,6 +3035,8 @@ func Test_autocmd_quit_psearch()
augroup aucmd_win_test
au!
augroup END
new
pclose
endfunc
" Fuzzer found some strange combination that caused a crash.
@@ -3037,12 +3070,10 @@ func Test_autocmd_closing_cmdwin()
endfunc
func Test_autocmd_vimgrep()
%bwipe!
augroup aucmd_vimgrep
au QuickfixCmdPre,BufNew,BufReadCmd * sb
au QuickfixCmdPre,BufNew,BufReadCmd * q9
au QuickfixCmdPre,BufNew,BufReadCmd * q9
augroup END
%bwipe!
call assert_fails('lv ?a? foo', 'E926:')
augroup aucmd_vimgrep

View File

@@ -118,6 +118,8 @@ func Test_blob_assign()
LET b[1 : 1] ..= 0z55
END
call v9.CheckLegacyAndVim9Failure(lines, ['E734:', 'E1183:', 'E734:'])
call assert_fails('let b = readblob("a1b2c3")', 'E484:')
endfunc
func Test_blob_get_range()
@@ -210,6 +212,8 @@ func Test_blob_compare()
call assert_true(b1 == b2)
call assert_false(b1 is b2)
call assert_true(b1 isnot b2)
call assert_true(0z != 0z10)
call assert_true(0z10 != 0z)
END
call v9.CheckLegacyAndVim9Success(lines)
@@ -266,7 +270,8 @@ func Test_blob_index_assign()
VAR b = 0z00
LET b[1] = 0x11
LET b[2] = 0x22
call assert_equal(0z001122, b)
LET b[0] = 0x33
call assert_equal(0z331122, b)
END
call v9.CheckLegacyAndVim9Success(lines)
@@ -281,6 +286,18 @@ func Test_blob_index_assign()
LET b[-2] = 0x33
END
call v9.CheckLegacyAndVim9Failure(lines, 'E979:')
let lines =<< trim END
VAR b = 0z00010203
LET b[0 : -1] = 0z33
END
call v9.CheckLegacyAndVim9Failure(lines, 'E979:')
let lines =<< trim END
VAR b = 0z00010203
LET b[3 : 4] = 0z3344
END
call v9.CheckLegacyAndVim9Failure(lines, 'E979:')
endfunc
func Test_blob_for_loop()
@@ -426,6 +443,12 @@ func Test_blob_func_remove()
END
call v9.CheckLegacyAndVim9Failure(lines, 'E979:')
let lines =<< trim END
VAR b = 0zDEADBEEF
call remove(b, -10)
END
call v9.CheckLegacyAndVim9Failure(lines, 'E979:')
let lines =<< trim END
VAR b = 0zDEADBEEF
call remove(b, 3, 2)

View File

@@ -172,4 +172,26 @@ func Test_getbufinfo_lines()
bw!
endfunc
func Test_getwininfo_au()
enew
call setline(1, range(1, 16))
let g:info = #{}
augroup T1
au!
au WinEnter * let g:info = getwininfo(win_getid())[0]
augroup END
4split
" Check that calling getwininfo() from WinEnter returns fresh values for
" topline and botline.
call assert_equal(1, g:info.topline)
call assert_equal(4, g:info.botline)
close
unlet g:info
augroup! T1
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -293,5 +293,41 @@ func Test_cursorline_screenline_update()
call delete('Xcul_screenline')
endfunc
func Test_cursorline_cursorbind_horizontal_scroll()
CheckScreendump
let lines =<< trim END
call setline(1, 'aa bb cc dd ee ff gg hh ii jj kk ll mm' ..
\ ' nn oo pp qq rr ss tt uu vv ww xx yy zz')
set nowrap
" The following makes the cursor apparent on the screen dump
set sidescroll=1 cursorcolumn
" add empty lines, required for cursorcolumn
call append(1, ['','','',''])
20vsp
windo :set cursorbind
END
call writefile(lines, 'Xhor_scroll')
let buf = RunVimInTerminal('-S Xhor_scroll', #{rows: 8})
call term_sendkeys(buf, "20l")
call VerifyScreenDump(buf, 'Test_hor_scroll_1', {})
call term_sendkeys(buf, "10l")
call VerifyScreenDump(buf, 'Test_hor_scroll_2', {})
call term_sendkeys(buf, ":windo :set cursorline\<cr>")
call term_sendkeys(buf, "0")
call term_sendkeys(buf, "20l")
call VerifyScreenDump(buf, 'Test_hor_scroll_3', {})
call term_sendkeys(buf, "10l")
call VerifyScreenDump(buf, 'Test_hor_scroll_4', {})
call term_sendkeys(buf, ":windo :set nocursorline nocursorcolumn\<cr>")
call term_sendkeys(buf, "0")
call term_sendkeys(buf, "40l")
call VerifyScreenDump(buf, 'Test_hor_scroll_5', {})
call StopVimInTerminal(buf)
call delete('Xhor_scroll')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -362,7 +362,39 @@ func Test_Debugger_breakadd()
call assert_fails('breakadd file Xtest.vim /\)/', 'E55:')
endfunc
def Test_Debugger_breakadd_expr()
" Test for expression breakpoint set using ":breakadd expr <expr>"
func Test_Debugger_breakadd_expr()
let lines =<< trim END
let g:Xtest_var += 1
END
call writefile(lines, 'Xtest.vim')
" Start Vim in a terminal
let buf = RunVimInTerminal('Xtest.vim', {})
call RunDbgCmd(buf, ':let g:Xtest_var = 10')
call RunDbgCmd(buf, ':breakadd expr g:Xtest_var')
call RunDbgCmd(buf, ':source %')
let expected =<< eval trim END
Oldval = "10"
Newval = "11"
`=fnamemodify('Xtest.vim', ':p')`
line 1: let g:Xtest_var += 1
END
call RunDbgCmd(buf, ':source %', expected)
call RunDbgCmd(buf, 'cont')
let expected =<< eval trim END
Oldval = "11"
Newval = "12"
`=fnamemodify('Xtest.vim', ':p')`
line 1: let g:Xtest_var += 1
END
call RunDbgCmd(buf, ':source %', expected)
call StopVimInTerminal(buf)
call delete('Xtest.vim')
endfunc
def Test_Debugger_breakadd_vim9_expr()
var lines =<< trim END
vim9script
func g:EarlyFunc()

View File

@@ -338,7 +338,7 @@ let s:filename_checks = {
\ 'markdown': ['file.markdown', 'file.mdown', 'file.mkd', 'file.mkdn', 'file.mdwn', 'file.md'],
\ 'mason': ['file.mason', 'file.mhtml', 'file.comp'],
\ 'master': ['file.mas', 'file.master'],
\ 'maxima': ['file.mc', 'file.demo', 'file.dem', 'file.dmt', 'file.dm1', 'file.dm2', 'file.dm3',
\ 'maxima': ['file.demo', 'file.dmt', 'file.dm1', 'file.dm2', 'file.dm3',
\ 'file.wxm', 'maxima-init.mac'],
\ 'mel': ['file.mel'],
\ 'meson': ['meson.build', 'meson_options.txt'],

View File

@@ -1439,4 +1439,24 @@ func Test_foldtext_scriptlocal_func()
delfunc s:FoldText
endfunc
" Make sure a fold containing a nested fold is split correctly when using
" foldmethod=indent
func Test_fold_split()
new
let lines =<< trim END
line 1
line 2
line 3
line 4
line 5
END
call setline(1, lines)
setlocal sw=2
setlocal foldmethod=indent foldenable
call assert_equal([0, 1, 1, 2, 2], range(1, 5)->map('foldlevel(v:val)'))
call append(2, 'line 2.5')
call assert_equal([0, 1, 0, 1, 2, 2], range(1, 6)->map('foldlevel(v:val)'))
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -1017,6 +1017,7 @@ func Test_reduce()
call assert_fails("call reduce([], { acc, val -> acc + val })", 'E998: Reduce of an empty List with no initial value')
call assert_fails("call reduce(0z, { acc, val -> acc + val })", 'E998: Reduce of an empty Blob with no initial value')
call assert_fails("call reduce(test_null_blob(), { acc, val -> acc + val })", 'E998: Reduce of an empty Blob with no initial value')
call assert_fails("call reduce('', { acc, val -> acc + val })", 'E998: Reduce of an empty String with no initial value')
call assert_fails("call reduce(test_null_string(), { acc, val -> acc + val })", 'E998: Reduce of an empty String with no initial value')
@@ -1034,8 +1035,8 @@ func Test_reduce()
call assert_fails("call reduce('', { acc, val -> acc + val }, 0.1)", 'E1253:')
call assert_fails("call reduce('', { acc, val -> acc + val }, function('tr'))", 'E1253:')
call assert_fails("call reduce('abc', { a, v -> a10}, '')", 'E121:')
call assert_fails("call reduce(0z01, { a, v -> a10}, 1)", 'E121:')
call assert_fails("call reduce([1], { a, v -> a10}, '')", 'E121:')
call assert_fails("call reduce(0z0102, { a, v -> a10}, 1)", 'E121:')
call assert_fails("call reduce([1, 2], { a, v -> a10}, '')", 'E121:')
let g:lut = [1, 2, 3, 4]
func EvilRemove()

View File

@@ -1566,6 +1566,34 @@ func Test_plug_remap()
%bw!
endfunc
func Test_mouse_drag_mapped_start_select()
set mouse=a
set selectmode=key,mouse
func ClickExpr()
call test_setmouse(1, 1)
return "\<LeftMouse>"
endfunc
func DragExpr()
call test_setmouse(1, 2)
return "\<LeftDrag>"
endfunc
nnoremap <expr> <F2> ClickExpr()
nmap <expr> <F3> DragExpr()
nnoremap <LeftDrag> <LeftDrag><Cmd><CR>
exe "normal \<F2>\<F3>"
call assert_equal('s', mode())
exe "normal! \<C-\>\<C-N>"
nunmap <LeftDrag>
nunmap <F2>
nunmap <F3>
delfunc ClickExpr
delfunc DragExpr
set selectmode&
set mouse&
endfunc
" Test for mapping <LeftDrag> in Insert mode
func Test_mouse_drag_insert_map()
set mouse=a
@@ -1599,4 +1627,15 @@ func Test_mouse_drag_insert_map()
set mouse&
endfunc
func Test_unmap_simplfied()
map <C-I> foo
map <Tab> bar
call assert_equal('foo', maparg('<C-I>'))
call assert_equal('bar', maparg('<Tab>'))
unmap <C-I>
call assert_equal('', maparg('<C-I>'))
call assert_equal('bar', maparg('<Tab>'))
unmap <Tab>
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -514,6 +514,19 @@ func Test_popup_firstline()
call assert_equal(5, popup_getpos(winid).firstline)
call popup_close(winid)
" Popup with less elements than the maximum height and negative firstline:
" check that the popup height is correctly computed.
let winid = popup_create(['xxx']->repeat(4), #{
\ firstline: -1,
\ maxheight: 6,
\ })
let pos = popup_getpos(winid)
call assert_equal(3, pos.width)
call assert_equal(4, pos.height)
call popup_close(winid)
endfunc
func Test_popup_firstline_cursorline()

View File

@@ -1043,7 +1043,7 @@ func Test_hlsearch_cursearch()
let lines =<< trim END
set hlsearch scrolloff=0
call setline(1, ['one', 'foo', 'bar', 'baz', 'foo', 'bar'])
call setline(1, ['one', 'foo', 'bar', 'baz', 'foo the foo and foo', 'bar'])
hi Search ctermbg=yellow
hi CurSearch ctermbg=blue
END
@@ -1056,7 +1056,14 @@ func Test_hlsearch_cursearch()
call term_sendkeys(buf, "n")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2', {})
call term_sendkeys(buf, "?\<CR>")
call term_sendkeys(buf, "n")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2a', {})
call term_sendkeys(buf, "n")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2b', {})
call term_sendkeys(buf, ":call setline(5, 'foo')\<CR>")
call term_sendkeys(buf, "0?\<CR>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_3', {})
call term_sendkeys(buf, "gg/foo\\nbar\<CR>")

View File

@@ -1783,6 +1783,28 @@ func Test_xx06_screen_response()
call test_override('term_props', 0)
endfunc
func Do_check_t_8u_set_reset(set_by_user)
set ttymouse=xterm
call test_option_not_set('ttymouse')
let default_value = "\<Esc>[58;2;%lu;%lu;%lum"
let &t_8u = default_value
if !a:set_by_user
call test_option_not_set('t_8u')
endif
let seq = "\<Esc>[>0;279;0c"
call feedkeys(seq, 'Lx!')
call assert_equal(seq, v:termresponse)
call assert_equal('sgr', &ttymouse)
call assert_equal(#{
\ cursor_style: 'u',
\ cursor_blink_mode: 'u',
\ underline_rgb: 'u',
\ mouse: 's'
\ }, terminalprops())
call assert_equal(a:set_by_user ? default_value : '', &t_8u)
endfunc
" This checks the xterm version response.
" This must be after other tests, because it has side effects to xterm
" properties.
@@ -1847,22 +1869,10 @@ func Test_xx07_xterm_response()
\ mouse: 's'
\ }, terminalprops())
" xterm >= 279: "sgr" and cursor_style not reset; also check t_8u reset
set ttymouse=xterm
call test_option_not_set('ttymouse')
let &t_8u = "\<Esc>[58;2;%lu;%lu;%lum"
let seq = "\<Esc>[>0;279;0c"
call feedkeys(seq, 'Lx!')
call assert_equal(seq, v:termresponse)
call assert_equal('sgr', &ttymouse)
call assert_equal(#{
\ cursor_style: 'u',
\ cursor_blink_mode: 'u',
\ underline_rgb: 'u',
\ mouse: 's'
\ }, terminalprops())
call assert_equal('', &t_8u)
" xterm >= 279: "sgr" and cursor_style not reset; also check t_8u reset,
" except when it was set by the user
call Do_check_t_8u_set_reset(0)
call Do_check_t_8u_set_reset(1)
set t_RV=
call test_override('term_props', 0)

View File

@@ -528,6 +528,18 @@ func Test_double_popup_terminal()
exe buf2 .. 'bwipe!'
endfunc
func Test_escape_popup_terminal()
set hidden
" Cannot escape a terminal popup window using win_gotoid
let prev_win = win_getid()
eval term_start('sh', #{hidden: 1, term_finish: 'close'})->popup_create({})
call assert_fails("call win_gotoid(" .. prev_win .. ")", 'E863:')
call popup_clear(1)
set hidden&
endfunc
func Test_issue_5607()
let wincount = winnr('$')
exe 'terminal' &shell &shellcmdflag 'exit'

View File

@@ -1821,10 +1821,31 @@ def Test_assign_lambda()
enddef
def Test_heredoc()
var lines =<< trim END # comment
text
# simple heredoc
var lines =<< trim END
var text =<< trim TEXT # comment
abc
TEXT
assert_equal(['abc'], text)
END
assert_equal(['text'], lines)
v9.CheckDefAndScriptSuccess(lines)
# empty heredoc
lines =<< trim END
var text =<< trim TEXT
TEXT
assert_equal([], text)
END
v9.CheckDefAndScriptSuccess(lines)
# heredoc with a single empty line
lines =<< trim END
var text =<< trim TEXT
TEXT
assert_equal([''], text)
END
v9.CheckDefAndScriptSuccess(lines)
v9.CheckDefFailure(['var lines =<< trim END X', 'END'], 'E488:')
v9.CheckDefFailure(['var lines =<< trim END " comment', 'END'], 'E488:')
@@ -2642,51 +2663,68 @@ let g:someVar = 'X'
" Test for heredoc with Vim expressions.
" This messes up highlighting, keep it near the end.
def Test_heredoc_expr()
var code =<< trim eval END
var a = `=5 + 10`
var b = `=min([10, 6])` + `=max([4, 6])`
END
assert_equal(['var a = 15', 'var b = 6 + 6'], code)
var lines =<< trim CODE
var s = "local"
var a1 = "1"
var a2 = "2"
var a3 = "3"
var a4 = ""
var code =<< trim eval END
var a = `=5 + 10`
var b = `=min([10, 6])` + `=max([4, 6])`
var c = "`=s`"
var d = x`=a1`x`=a2`x`=a3`x`=a4`
END
assert_equal(['var a = 15', 'var b = 6 + 6', 'var c = "local"', 'var d = x1x2x3x'], code)
CODE
v9.CheckDefAndScriptSuccess(lines)
code =<< eval trim END
var s = "`=$SOME_ENV_VAR`"
END
assert_equal(['var s = "somemore"'], code)
lines =<< trim CODE
var code =<< eval trim END
var s = "`=$SOME_ENV_VAR`"
END
assert_equal(['var s = "somemore"'], code)
CODE
v9.CheckDefAndScriptSuccess(lines)
code =<< eval END
var s = "`=$SOME_ENV_VAR`"
END
assert_equal([' var s = "somemore"'], code)
lines =<< trim CODE
var code =<< eval END
var s = "`=$SOME_ENV_VAR`"
END
assert_equal([' var s = "somemore"'], code)
CODE
v9.CheckDefAndScriptSuccess(lines)
code =<< eval trim END
let a = `abc`
let b = `=g:someVar`
let c = `
END
assert_equal(['let a = `abc`', 'let b = X', 'let c = `'], code)
lines =<< trim CODE
var code =<< eval trim END
let a = `abc`
let b = `=g:someVar`
let c = `
END
assert_equal(['let a = `abc`', 'let b = X', 'let c = `'], code)
CODE
v9.CheckDefAndScriptSuccess(lines)
var lines =<< trim LINES
lines =<< trim LINES
var text =<< eval trim END
let b = `=
END
LINES
v9.CheckDefAndScriptFailure(lines, 'E1083:')
v9.CheckDefAndScriptFailure(lines, ['E1143: Empty expression: ""', 'E1083: Missing backtick'])
lines =<< trim LINES
var text =<< eval trim END
let b = `=abc
END
LINES
v9.CheckDefAndScriptFailure(lines, 'E1083:')
v9.CheckDefAndScriptFailure(lines, ['E1001: Variable not found: abc', 'E1083: Missing backtick'])
lines =<< trim LINES
var text =<< eval trim END
let b = `=`
END
LINES
v9.CheckDefAndScriptFailure(lines, 'E15:')
v9.CheckDefAndScriptFailure(lines, ['E1015: Name expected: `', 'E15: Invalid expression: "`"'])
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

View File

@@ -1273,56 +1273,79 @@ def Test_float_funcs_args()
# acos()
v9.CheckDefAndScriptFailure(['acos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('1.570796', string(acos(0.0)))
# asin()
v9.CheckDefAndScriptFailure(['asin("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(asin(0.0)))
# atan()
v9.CheckDefAndScriptFailure(['atan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(atan(0.0)))
# atan2()
v9.CheckDefAndScriptFailure(['atan2("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('-2.356194', string(atan2(-1, -1)))
v9.CheckDefAndScriptFailure(['atan2(1.2, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
v9.CheckDefAndScriptFailure(['atan2(1.2)'], ['E119:', 'E119:'])
# ceil()
v9.CheckDefAndScriptFailure(['ceil("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('2.0', string(ceil(2.0)))
# cos()
v9.CheckDefAndScriptFailure(['cos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('1.0', string(cos(0.0)))
# cosh()
v9.CheckDefAndScriptFailure(['cosh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('1.0', string(cosh(0.0)))
# exp()
v9.CheckDefAndScriptFailure(['exp("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('1.0', string(exp(0.0)))
# float2nr()
v9.CheckDefAndScriptFailure(['float2nr("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal(1, float2nr(1.234))
# floor()
v9.CheckDefAndScriptFailure(['floor("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('2.0', string(floor(2.0)))
# fmod()
v9.CheckDefAndScriptFailure(['fmod(1.1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
v9.CheckDefAndScriptFailure(['fmod("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
v9.CheckDefAndScriptFailure(['fmod(1.1)'], ['E119:', 'E119:'])
assert_equal('0.13', string(fmod(12.33, 1.22)))
# isinf()
v9.CheckDefAndScriptFailure(['isinf("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal(1, isinf(1.0 / 0.0))
# isnan()
v9.CheckDefAndScriptFailure(['isnan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_true(isnan(0.0 / 0.0))
# log()
v9.CheckDefAndScriptFailure(['log("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(log(1.0)))
# log10()
v9.CheckDefAndScriptFailure(['log10("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(log10(1.0)))
# pow()
v9.CheckDefAndScriptFailure(['pow("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
v9.CheckDefAndScriptFailure(['pow(1.1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2'])
v9.CheckDefAndScriptFailure(['pow(1.1)'], ['E119:', 'E119:'])
assert_equal('1.0', string(pow(0.0, 0.0)))
# round()
v9.CheckDefAndScriptFailure(['round("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('2.0', string(round(2.1)))
# sin()
v9.CheckDefAndScriptFailure(['sin("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(sin(0.0)))
# sinh()
v9.CheckDefAndScriptFailure(['sinh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(sinh(0.0)))
# sqrt()
v9.CheckDefAndScriptFailure(['sqrt("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(sqrt(0.0)))
# tan()
v9.CheckDefAndScriptFailure(['tan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(tan(0.0)))
# tanh()
v9.CheckDefAndScriptFailure(['tanh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('0.0', string(tanh(0.0)))
# trunc()
v9.CheckDefAndScriptFailure(['trunc("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1'])
assert_equal('2.0', string(trunc(2.1)))
enddef
def Test_fnameescape()

View File

@@ -506,8 +506,6 @@ def Test_import_fails()
END
v9.CheckScriptFailure(lines, 'E1047:')
delete('Xfoo.vim')
lines =<< trim END
vim9script
def TheFunc()
@@ -576,7 +574,26 @@ def Test_import_fails()
END
v9.CheckScriptSuccess(lines)
new
setline(1, ['vim9script', 'import "" as abc'])
assert_fails('source', 'E1071: Invalid string for :import: "" as abc')
setline(2, 'import [] as abc')
assert_fails('source', 'E1071: Invalid string for :import: [] as abc')
setline(2, 'import test_null_string() as abc')
assert_fails('source', 'E1071: Invalid string for :import: test_null_string() as abc')
bw!
call writefile(['vim9script', "import './Xfoo.vim' ask expo"], 'Xbar.vim')
assert_fails('source Xbar.vim', 'E488: Trailing characters: ask expo')
writefile([], 'Xtemp')
call writefile(['vim9script', "import './Xtemp'"], 'Xbar.vim')
assert_fails('source Xbar.vim', 'E1257: Imported script must use "as" or end in .vim: Xtemp')
delete('Xtemp')
call writefile(['vim9script', "import './Xfoo.vim' as abc | foobar"], 'Xbar.vim')
assert_fails('source Xbar.vim', 'E492: Not an editor command: foobar')
call delete('Xbar.vim')
delete('Ximport', 'rf')
delete('Xfoo.vim')
enddef
func g:Trigger()
@@ -1404,6 +1421,7 @@ def Test_export_fails()
v9.CheckScriptFailure(['export var some = 123'], 'E1042:')
v9.CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
v9.CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
v9.CheckScriptFailure(['vim9script', 'export function /a1b2c3'], 'E1044:')
assert_fails('export something', 'E1043:')
enddef
@@ -2646,6 +2664,12 @@ def Test_vim9script_autoload_fails()
var n = 0
END
v9.CheckScriptFailure(lines, 'E983: Duplicate argument: noclear')
lines =<< trim END
vim9script noclears
var n = 0
END
v9.CheckScriptFailure(lines, 'E475: Invalid argument: noclears')
enddef
def Test_import_autoload_fails()

View File

@@ -3779,6 +3779,16 @@ def Test_unsupported_commands()
END
v9.CheckDefAndScriptFailure(lines, ['E476:', 'E492:'])
lines =<< trim END
:k a
END
v9.CheckDefAndScriptFailure(lines, 'E1100:')
lines =<< trim END
:1k a
END
v9.CheckDefAndScriptFailure(lines, 'E481:')
lines =<< trim END
t
END

View File

@@ -746,6 +746,60 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4819,
/**/
4818,
/**/
4817,
/**/
4816,
/**/
4815,
/**/
4814,
/**/
4813,
/**/
4812,
/**/
4811,
/**/
4810,
/**/
4809,
/**/
4808,
/**/
4807,
/**/
4806,
/**/
4805,
/**/
4804,
/**/
4803,
/**/
4802,
/**/
4801,
/**/
4800,
/**/
4799,
/**/
4798,
/**/
4797,
/**/
4796,
/**/
4795,
/**/
4794,
/**/
4793,
/**/
4792,
/**/

View File

@@ -595,6 +595,7 @@ find_imported_in_script(char_u *name, size_t len, int sid)
/*
* Find "name" in imported items of the current script.
* If "len" is 0 use any length that works.
* If "load" is TRUE and the script was not loaded yet, load it now.
*/
imported_T *
@@ -967,6 +968,83 @@ theend:
return r == FAIL ? NULL : (char_u *)"";
}
/*
* Compile a heredoc string "str" (either containing a literal string or a mix
* of literal strings and Vim expressions of the form `=<expr>`). This is used
* when compiling a heredoc assignment to a variable in a Vim9 def function.
* Vim9 instructions are generated to push strings, evaluate expressions,
* concatenate them and create a list of lines. When "evalstr" is TRUE, Vim
* expressions in "str" are evaluated.
*/
int
compile_heredoc_string(char_u *str, int evalstr, cctx_T *cctx)
{
char_u *p;
char_u *val;
if (cctx->ctx_skip == SKIP_YES)
return OK;
if (evalstr && (p = (char_u *)strstr((char *)str, "`=")) != NULL)
{
char_u *start = str;
// Need to evaluate expressions of the form `=<expr>` in the string.
// Split the string into literal strings and Vim expressions and
// generate instructions to concatenate the literal strings and the
// result of evaluating the Vim expressions.
val = vim_strsave((char_u *)"");
generate_PUSHS(cctx, &val);
for (;;)
{
if (p > start)
{
// literal string before the expression
val = vim_strnsave(start, p - start);
generate_PUSHS(cctx, &val);
generate_instr_drop(cctx, ISN_CONCAT, 1);
}
p += 2;
// evaluate the Vim expression and convert the result to string.
if (compile_expr0(&p, cctx) == FAIL)
return FAIL;
may_generate_2STRING(-1, TRUE, cctx);
generate_instr_drop(cctx, ISN_CONCAT, 1);
p = skipwhite(p);
if (*p != '`')
{
emsg(_(e_missing_backtick));
return FAIL;
}
start = p + 1;
p = (char_u *)strstr((char *)start, "`=");
if (p == NULL)
{
// no more Vim expressions left to process
if (*skipwhite(start) != NUL)
{
val = vim_strsave(start);
generate_PUSHS(cctx, &val);
generate_instr_drop(cctx, ISN_CONCAT, 1);
}
break;
}
}
}
else
{
// literal string
val = vim_strsave(str);
generate_PUSHS(cctx, &val);
}
return OK;
}
/*
* Return the length of an assignment operator, or zero if there isn't one.
*/
@@ -1946,25 +2024,14 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
if (heredoc)
{
list_T *l;
listitem_T *li;
// [let] varname =<< [trim] {end}
eap->getline = exarg_getline;
eap->cookie = cctx;
l = heredoc_get(eap, op + 3, FALSE);
l = heredoc_get(eap, op + 3, FALSE, TRUE);
if (l == NULL)
return NULL;
if (cctx->ctx_skip != SKIP_YES)
{
// Push each line and the create the list.
FOR_ALL_LIST_ITEMS(l, li)
{
generate_PUSHS(cctx, &li->li_tv.vval.v_string);
li->li_tv.vval.v_string = NULL;
}
generate_NEWLIST(cctx, l->lv_len, FALSE);
}
list_free(l);
p += STRLEN(p);
end = p;