Compare commits

...

15 Commits

Author SHA1 Message Date
Bram Moolenaar
5357552140 patch 8.1.1365: source command doesn't check for the sandbox
Problem:    Source command doesn't check for the sandbox. (Armin Razmjou)
Solution:   Check for the sandbox when sourcing a file.
2019-05-22 22:38:25 +02:00
Bram Moolenaar
5c017b2de2 patch 8.1.1364: design for popup window support needs more details
Problem:    Design for popup window support needs more details.
Solution:   Add details about using a window and buffer.  Rename popup_show()
            to popup_create() and add popup_show() and popup_hide().
2019-05-21 23:09:01 +02:00
Bram Moolenaar
e0b5949a3b patch 8.1.1363: ":vert options" does not make a vertical split
Problem:    ":vert options" does not make a vertical split.
Solution:   Pass the right modifiers in $OPTWIN_CMD. (Ken Takata,
            closes #4401)
2019-05-21 20:54:45 +02:00
Bram Moolenaar
c79745a82f patch 8.1.1362: code and data in tests can be hard to read
Problem:    Code and data in tests can be hard to read.
Solution:   Use the new heredoc style. (Yegappan Lakshmanan, closes #4400)
2019-05-20 22:12:34 +02:00
Bram Moolenaar
0b0ad35c33 patch 8.1.1361: Python setuptools don't work with Python 3
Problem:    Python setuptools don't work with Python 3.
Solution:   Add dummy implementation for find_module. (Joel Frederico,
            closes #4402, closes #3984
2019-05-20 21:52:45 +02:00
Bram Moolenaar
80341bcd89 patch 8.1.1360: buffer left 'nomodifiable' after :substitute
Problem:    Buffer left 'nomodifiable' after :substitute. (Ingo Karkat)
Solution:   Save the value of 'modifiable' earlier' (Christian Brabandt,
            closes #4403)
2019-05-20 20:34:51 +02:00
Bram Moolenaar
f3333b02f3 patch 8.1.1359: text property wrong after :substitute with backslash
Problem:    Text property wrong after :substitute with backslash.
Solution:   Adjust text property columns when removing backslashes.
            (closes #4397)
2019-05-19 22:53:40 +02:00
Bram Moolenaar
386b43e594 patch 8.1.1358: cannot enter character with a CSI byte
Problem:    Cannot enter character with a CSI byte.
Solution:   Only check "gui.in_use" when VIMDLL is defined. (Ken Takata,
            closes #4396)
2019-05-19 21:57:11 +02:00
Bram Moolenaar
999dc14644 patch 8.1.1357: test 37 is old style
Problem:    Test 37 is old style.
Solution:   Turn it into a new style test. (Yegappan Lakshmanan, closes #4398)
2019-05-19 21:44:08 +02:00
Bram Moolenaar
8471e57026 patch 8.1.1356: some text in heredoc assignment ends the text
Problem:    Some text in heredoc assignment ends the text. (Ozaki Kiichi)
Solution:   Recognize "let v =<<" and skip until the end.
2019-05-19 21:37:18 +02:00
Bram Moolenaar
16e9b85113 patch 8.1.1355: obvious mistakes are accepted as valid expressions
Problem:    Obvious mistakes are accepted as valid expressions.
Solution:   Be more strict about parsing numbers. (Yasuhiro Matsumoto,
            closes #3981)
2019-05-19 19:59:35 +02:00
Bram Moolenaar
f5842c5a53 patch 8.1.1354: getting a list of text lines is clumsy
Problem:    Getting a list of text lines is clumsy.
Solution:   Add the =<< assignment. (Yegappan Lakshmanan, closes #4386)
2019-05-19 18:41:26 +02:00
Bram Moolenaar
2b39d806f0 patch 8.1.1353: undo test fails on Mac
Problem:    Undo test fails on Mac.
Solution:   Expect "private" on the Mac.
2019-05-19 16:38:56 +02:00
Bram Moolenaar
e9ebc9a91c patch 8.1.1352: undofile() reports wrong name
Problem:    Undofile() reports wrong name. (Francisco Giordano)
Solution:   Clean up the name before changing path separators. (closes #4392,
            closes #4394)
2019-05-19 15:27:14 +02:00
Bram Moolenaar
338dfdad38 patch 8.1.1351: text property wrong after :substitute
Problem:    Text property wrong after :substitute.
Solution:   Save for undo before changing any text properties.
2019-05-19 15:19:57 +02:00
53 changed files with 1974 additions and 1096 deletions

View File

@@ -11416,6 +11416,44 @@ This does NOT work: >
Like above, but append/add/subtract the value for each
|List| item.
*:let=<<* *:let-heredoc* *E990* *E991*
:let {var-name} =<< [trim] {marker}
text...
text...
{marker}
Set internal variable {var-name} to a List containing
the lines of text bounded by the string {marker}.
{marker} must not contain white space.
The last line should end only with the {marker} string
without any other character. Watch out for white
space after {marker}!
If {marker} is not supplied, then "." is used as the
default marker.
Any white space characters in the lines of text are
preserved. If "trim" is specified before {marker},
then all the leading indentation exactly matching the
leading indentation before `let` is stripped from the
input lines and the line containing {marker}. Note
that the difference between space and tab matters
here.
If {var-name} didn't exist yet, it is created.
Cannot be followed by another command, but can be
followed by a comment.
Examples: >
let var1 =<< END
Sample text 1
Sample text 2
Sample text 3
END
let data =<< trim DATA
1 2 3 4
5 6 7 8
DATA
<
*E121*
:let {var-name} .. List the value of variable {var-name}. Multiple
variable names may be given. Special names recognized

View File

@@ -1,10 +1,10 @@
*popup.txt* For Vim version 8.1. Last change: 2019 May 12
*popup.txt* For Vim version 8.1. Last change: 2019 May 21
VIM REFERENCE MANUAL by Bram Moolenaar
Displaying text with properties attached. *popup* *popup-window*
Displaying text in floating window. *popup* *popup-window*
THIS IS UNDER DESIGN - ANYTHING MAY STILL CHANGE
@@ -13,18 +13,67 @@ THIS IS UNDER DESIGN - ANYTHING MAY STILL CHANGE
3. Examples |popup-examples|
{not able to use text properties when the |+textprop| feature was
disabled at compile time}
{not available if the |+eval| feature was disabled at compile time}
{not able to use text properties if the |+textprop| feature was disabled at
compile time}
==============================================================================
1. Introduction *popup-intro*
We are talking about popup windows here, text that goes on top of the buffer
text and is under control of a plugin. Other popup functionality:
We are talking about popup windows here, text that goes on top of the regular
windows and is under control of a plugin. You cannot edit the text in the
popup window like with regular windows.
A popup window can be used for such things as:
- briefly show a message without changing the command line
- prompt the user with a dialog
- display information while typing
- give extra information for auto-completion
The text in the popup window can be colored with |text-properties|. It is
also possible to use syntax highlighting.
A popup window has a window-ID like other windows, but behaves differently.
The size can be up to the whole Vim window and it overlaps other windows.
It contains a buffer, and that buffer is always associated with the popup
window. The window cannot be used in Normal, Visual or Insert mode, it does
not get keyboard focus. You can use functions like `setbufline()` to change
the text in the buffer. There are more differences from how this window and
buffer behave compared to regular windows and buffers, see |popup-buffer|.
If this is not what you are looking for, check out other popup functionality:
- popup menu, see |popup-menu|
- balloon, see |balloon-eval|
TODO
TODO:
Example how to use syntax highlighting of a code snippet.
Scrolling: When the screen scrolls up for output of an Ex command, what
happens with popups?
1. Stay where they are. Problem: listed text may go behind and can't be read.
2. Scroll with the page. What if they get updated? Either postpone, or take
the scroll offset into account.
Probably 2. is the best choice.
Positioning relative to the popup-menu to avoid overlapping with it; add a
function to get the position and size of the popup-menu.
IMPLEMENTATION:
- Put code in popupwin.c
- Use win_update() for displaying
- At first redraw all windows NOT_VALID when the popup moves or hides.
- At first always display the popup windows at the end of update_screen(),
lowest zindex first.
- Later make it more efficient and avoid flicker
- Use a separate list of windows, one for each tab and one global. Also put
"aucmd_win" in there.
- add optional {buf} command to execute(). Only works for a buffer that is
visible in a window in the current tab or in a popup window.
E.g. for execute('syntax enable', 'silent', bufnr)
==============================================================================
2. Functions *popup-functions*
@@ -33,56 +82,66 @@ THIS IS UNDER DESIGN - ANYTHING MAY STILL CHANGE
Proposal and discussion on issue #4063: https://github.com/vim/vim/issues/4063
[to be moved to eval.txt later]
popup_show({lines}, {options}) *popup_show()*
Open a popup window showing {lines}, which is a list of lines,
where each line has text and text properties.
[functions to be moved to eval.txt later, keep list of functions here]
popup_create({text}, {options}) *popup_create()*
Open a popup window showing {text}, which is either:
- a string
- a list of strings
- a list of text lines with text properties
{options} is a dictionary with many possible entries.
See |popup_create-usage| for details.
Returns a unique ID to be used with |popup_close()|.
See |popup_show-usage| for details.
Returns a window-ID, which can be used with other popup
functions. Use `winbufnr()` to get the number of the buffer
in the window: >
let winid = popup_create('hello', {})
let bufnr = winbufnr(winid)
call setbufline(bufnr, 2, 'second line')
popup_dialog({lines}, {options}) *popup_dialog()*
Just like |popup_show()| but with different default options:
pos "center"
zindex 200
border []
popup_dialog({text}, {options}) *popup_dialog()*
Just like |popup_create()| but with these default options: >
call popup_create({text}, {
\ 'pos': 'center',
\ 'zindex': 200,
\ 'border': [],
\})
< Use {options} to change the properties.
popup_notification({text}, {options}) *popup_notification()*
Show the string {text} for 3 seconds at the top of the Vim
window. This works like: >
call popup_show([{'text': {text}}], {
Show the {text} for 3 seconds at the top of the Vim window.
This works like: >
call popup_create({text}, {
\ 'line': 1,
\ 'col': 10,
\ 'time': 3000,
\ 'tab': -1,
\ 'zindex': 200,
\ 'highlight': 'WarningMsg',
\ 'border: [],
\ })
< Use {options} to change the properties.
popup_atcursor({text}, {options}) *popup_atcursor()*
Show the string {text} above the cursor, and close it when the
cursor moves. This works like: >
call popup_show([{'text': {text}}], {
Show the {text} above the cursor, and close it when the cursor
moves. This works like: >
call popup_create({text}, {
\ 'line': 'cursor-1',
\ 'col': 'cursor',
\ 'zindex': 50,
\ 'moved': 'WORD',
\ })
< Use {options} to change the properties.
popup_menu({lines}, {options}) *popup_atcursor()*
Show the {lines} near the cursor, handle selecting one of the
popup_menu({text}, {options}) *popup_menu()*
Show the {text} near the cursor, handle selecting one of the
items with cursorkeys, and close it an item is selected with
Space or Enter. This works like: >
call popup_show({lines}, {
Space or Enter. {text} should have multiple lines to make this
useful. This works like: >
call popup_create({text}, {
\ 'pos': 'center',
\ 'zindex': 200,
\ 'wrap': 0,
@@ -93,9 +152,17 @@ popup_menu({lines}, {options}) *popup_atcursor()*
"callback" to a function that handles the selected item.
popup_show({id}) *popup_show()*
If {id} is a hidden popup, show it now.
popup_hide({id}) *popup_hide()*
If {id} is a displayed popup, hide it now. If the popup has a
filter it will not be invoked for so long as the popup is
hidden.
popup_move({id}, {options}) *popup_move()*
Move popup {id} to the position speficied with {options}.
{options} may contain the items from |popup_show()| that
{options} may contain the items from |popup_create()| that
specify the popup position: "line", "col", "pos", "maxheight",
"minheight", "maxwidth" and "minwidth".
@@ -116,21 +183,6 @@ popup_filter_yesno({id}, {key}) *popup_filter_yesno()*
pressing 'n'.
popup_setlines({id}, {lnum}, {lines}) *popup_setlines()*
In popup {id} set line {lnum} and following to {lines}.
{lnum} is one-based and must be either an existing line or
just one below the last line, in which case the line gets
appended.
{lines} has the same format as one item in {lines} of
|popup_show()|. Existing lines are replaced. When {lines}
extends below the last line of the popup lines are appended.
popup_getlines({id}) *popup_getlines()*
Return the {lines} for popup {id}.
popup_setoptions({id}, {options}) *popup_setoptions()*
Override options in popup {id} with entries in {options}.
@@ -142,19 +194,46 @@ popup_getoptions({id}) *popup_getoptions()*
popup_close({id}) *popup_close()*
Close popup {id}.
*:popupclear* *:popupc*
:popupc[lear] Emergency solution to a misbehaving plugin: close all popup
windows.
POPUP_SHOW() ARGUMENTS *popup_show-usage*
The first argument of |popup_show()| is a list of text lines. Each item in
the list is a dictionary with these entries:
text The text to display.
POPUP BUFFER AND WINDOW *popup-buffer*
A new buffer is created to hold the text and text properties of the popup
window. The buffer is always associated with the popup window and
manipulation is restricted:
- the buffer has no name
- 'buftype' is "popup"
- 'swapfile' is off
- 'bufhidden' is "hide"
- 'buflisted' is off
TODO: more
The window does have a cursor position, but the cursor is not displayed.
Options can be set on the window with `setwinvar()`, e.g.: >
call setwinvar(winid, '&wrap', 0)
And options can be set on the buffer with `setbufvar()`, e.g.: >
call setbufvar(winbufnr(winid), '&filetype', 'java')
POPUP_CREATE() ARGUMENTS *popup_create-usage*
The first argument of |popup_create()| specifies the text to be displayed, and
optionally text properties. It is in one of three forms:
- a string
- a list of strings
- a list of dictionaries, where each dictionary has these entries:
text String with the text to display.
props A list of text properties. Optional.
Each entry is a dictionary, like the third argument of
|prop_add()|, but specifying the column in the
dictionary with a "col" entry, see below:
|popup-props|.
The second argument of |popup_show()| is a dictionary with options:
The second argument of |popup_create()| is a dictionary with options:
line screen line where to position the popup; can use
"cursor", "cursor+1" or "cursor-1" to use the line of
the cursor and add or subtract a number of lines;
@@ -168,10 +247,20 @@ The second argument of |popup_show()| is a dictionary with options:
used for. Default is "botleft". Alternatively
"center" can be used to position the popup somewhere
near the cursor.
flip when TRUE (the default) and the position is relative
to the cursor, flip to below or above the cursor to
avoid overlap with the |popupmenu-completion| or
another popup with a higher "zindex"
maxheight maximum height
minheight minimum height
maxwidth maximum width
minwidth minimum width
hidden when TRUE the popup exists but is not displayed; use
`popup_show()` to unhide it.
tab when -1: display the popup on all tabs; when 0 (the
default): display the popup on the current tab;
otherwise the number of the tab page the popup is
displayed on; when invalid the current tab is used
title text to be displayed above the first item in the
popup, on top of any border
wrap TRUE to make the lines wrap (default TRUE)
@@ -229,9 +318,11 @@ same, since they only apply to one line.
POPUP FILTER *popup-filter*
A callback that gets any typed keys while a popup is displayed. It can return
TRUE to indicate the key has been handled and is to be discarded, or FALSE to
let Vim handle the key as usual in the current state.
A callback that gets any typed keys while a popup is displayed. The filter is
not invoked for as long as the popup is hidden.
The filter can return TRUE to indicate the key has been handled and is to be
discarded, or FALSE to let Vim handle the key as usual in the current state.
The filter function is called with two arguments: the ID of the popup and the
key.
@@ -241,6 +332,10 @@ Some common key actions:
cursor keys select another entry
Tab accept current suggestion
A mouse click arrives as <LeftMouse>. The coordinates are in
v:mouse_popup_col and v:mouse_popup_row. The top-left screen cell of the
popup is col 1, row 1 (not counting the border).
Vim provides standard filters |popup_filter_menu()| and
|popup_filter_yesno()|.
@@ -265,7 +360,7 @@ Prompt the user to press y/Y or n/N: >
endif
endfunc
call popup_show([{'text': 'Continue? y/n'}], {
call popup_create(['Continue? y/n'], {
\ 'filter': 'popup_filter_yesno',
\ 'callback': 'MyDialogHandler',
\ })

View File

@@ -2179,7 +2179,7 @@ test_libvterm:
test1 \
test_eval \
test3 \
test30 test37 test39 \
test30 test39 \
test42 test44 test48 test49 \
test52 test59 \
test64 test69 \

View File

@@ -684,7 +684,7 @@ inserted_bytes(linenr_T lnum, colnr_T col, int added UNUSED)
{
#ifdef FEAT_TEXT_PROP
if (curbuf->b_has_textprop && added != 0)
adjust_prop_columns(lnum, col, added);
adjust_prop_columns(lnum, col, added, 0);
#endif
changed_bytes(lnum, col);

View File

@@ -1776,25 +1776,30 @@ vim_isblankline(char_u *lbuf)
* If "what" contains STR2NR_HEX recognize hex numbers
* If "what" contains STR2NR_FORCE always assume bin/oct/hex.
* If maxlen > 0, check at a maximum maxlen chars.
* If strict is TRUE, check the number strictly. return *len = 0 if fail.
*/
void
vim_str2nr(
char_u *start,
int *prep, /* return: type of number 0 = decimal, 'x'
or 'X' is hex, '0' = octal, 'b' or 'B'
is bin */
int *len, /* return: detected length of number */
int what, /* what numbers to recognize */
varnumber_T *nptr, /* return: signed result */
uvarnumber_T *unptr, /* return: unsigned result */
int maxlen) /* max length of string to check */
int *prep, // return: type of number 0 = decimal, 'x'
// or 'X' is hex, '0' = octal, 'b' or 'B'
// is bin
int *len, // return: detected length of number
int what, // what numbers to recognize
varnumber_T *nptr, // return: signed result
uvarnumber_T *unptr, // return: unsigned result
int maxlen, // max length of string to check
int strict) // check strictly
{
char_u *ptr = start;
int pre = 0; /* default is decimal */
int pre = 0; // default is decimal
int negative = FALSE;
uvarnumber_T un = 0;
int n;
if (len != NULL)
*len = 0;
if (ptr[0] == '-')
{
negative = TRUE;
@@ -1836,9 +1841,7 @@ vim_str2nr(
}
}
/*
* Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
*/
// Do the conversion manually to avoid sscanf() quirks.
n = 1;
if (pre == 'B' || pre == 'b' || what == STR2NR_BIN + STR2NR_FORCE)
{
@@ -1907,6 +1910,10 @@ vim_str2nr(
break;
}
}
// Check for an alpha-numeric character immediately following, that is
// most likely a typo.
if (strict && n - 1 != maxlen && ASCII_ISALNUM(*ptr))
return;
if (prep != NULL)
*prep = pre;

View File

@@ -4104,7 +4104,7 @@ replace_do_bs(int limit_col)
--text_prop_frozen;
adjust_prop_columns(curwin->w_cursor.lnum, curwin->w_cursor.col,
(int)(len_now - len_before));
(int)(len_now - len_before), 0);
}
#endif
}

View File

@@ -1224,6 +1224,102 @@ eval_foldexpr(char_u *arg, int *cp)
}
#endif
/*
* Get a list of lines from a HERE document. The here document is a list of
* lines surrounded by a marker.
* cmd << {marker}
* {line1}
* {line2}
* ....
* {marker}
*
* 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.
* Returns a List with {lines} or NULL.
*/
static list_T *
heredoc_get(exarg_T *eap, char_u *cmd)
{
char_u *theline;
char_u *marker;
list_T *l;
char_u *p;
int indent_len = 0;
if (eap->getline == NULL)
{
emsg(_("E991: cannot use =<< here"));
return NULL;
}
// Check for the optional 'trim' word before the marker
cmd = skipwhite(cmd);
if (STRNCMP(cmd, "trim", 4) == 0 && (cmd[4] == NUL || VIM_ISWHITE(cmd[4])))
{
cmd = skipwhite(cmd + 4);
// Trim the indentation from all the lines in the here document
// The amount of indentation trimmed is the same as the indentation of
// the :let command line.
p = *eap->cmdlinep;
while (VIM_ISWHITE(*p))
{
p++;
indent_len++;
}
}
// The marker is the next word. Default marker is "."
if (*cmd != NUL && *cmd != '"')
{
marker = skipwhite(cmd);
p = skiptowhite(marker);
if (*skipwhite(p) != NUL && *skipwhite(p) != '"')
{
emsg(_(e_trailing));
return NULL;
}
*p = NUL;
}
else
marker = (char_u *)".";
l = list_alloc();
if (l == NULL)
return NULL;
for (;;)
{
int i = 0;
theline = eap->getline(NUL, eap->cookie, 0);
if (theline != NULL && indent_len > 0)
{
// trim the indent matching the first line
if (STRNCMP(theline, *eap->cmdlinep, indent_len) == 0)
i = indent_len;
}
if (theline == NULL)
{
semsg(_("E990: Missing end marker '%s'"), marker);
break;
}
if (STRCMP(marker, theline + i) == 0)
{
vim_free(theline);
break;
}
if (list_append_string(l, theline + i, -1) == FAIL)
break;
vim_free(theline);
}
return l;
}
/*
* ":let" list all variable values
* ":let var1 var2" list variable values
@@ -1286,6 +1382,22 @@ ex_let(exarg_T *eap)
}
eap->nextcmd = check_nextcmd(arg);
}
else if (expr[0] == '=' && expr[1] == '<' && expr[2] == '<')
{
list_T *l;
// HERE document
l = heredoc_get(eap, expr + 3);
if (l != NULL)
{
rettv_list_set(&rettv, l);
op[0] = '=';
op[1] = NUL;
(void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count,
op);
clear_tv(&rettv);
}
}
else
{
op[0] = '=';
@@ -4341,7 +4453,13 @@ eval7(
else
{
// decimal, hex or octal number
vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0);
vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0, TRUE);
if (len == 0)
{
semsg(_(e_invexpr2), *arg);
ret = FAIL;
break;
}
*arg += len;
if (evaluate)
{
@@ -7348,7 +7466,7 @@ tv_get_number_chk(typval_T *varp, int *denote)
case VAR_STRING:
if (varp->vval.v_string != NULL)
vim_str2nr(varp->vval.v_string, NULL, NULL,
STR2NR_ALL, &n, NULL, 0);
STR2NR_ALL, &n, NULL, 0, FALSE);
return n;
case VAR_LIST:
emsg(_("E745: Using a List as a Number"));

View File

@@ -13199,7 +13199,8 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
case 16: what = STR2NR_HEX + STR2NR_FORCE; break;
default: what = 0;
}
vim_str2nr(p, NULL, NULL, what, &n, NULL, 0);
vim_str2nr(p, NULL, NULL, what, &n, NULL, 0, FALSE);
// Text after the number is silently ignored.
if (isneg)
rettv->vval.v_number = -n;
else
@@ -15128,7 +15129,7 @@ f_undofile(typval_T *argvars UNUSED, typval_T *rettv)
}
else
{
char_u *ffname = FullName_save(fname, FALSE);
char_u *ffname = FullName_save(fname, TRUE);
if (ffname != NULL)
rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE);

View File

@@ -558,7 +558,8 @@ ex_sort(exarg_T *eap)
{
nrs[lnum - eap->line1].st_u.num.is_number = TRUE;
vim_str2nr(s, NULL, NULL, sort_what,
&nrs[lnum - eap->line1].st_u.num.value, NULL, 0);
&nrs[lnum - eap->line1].st_u.num.value,
NULL, 0, FALSE);
}
}
#ifdef FEAT_FLOAT
@@ -5187,6 +5188,9 @@ do_sub(exarg_T *eap)
int do_again; /* do it again after joining lines */
int skip_match = FALSE;
linenr_T sub_firstlnum; /* nr of first sub line */
#ifdef FEAT_TEXT_PROP
int apc_flags = APC_SAVE_FOR_UNDO | APC_SUBSTITUTE;
#endif
/*
* The new text is build up step by step, to avoid too much
@@ -5553,6 +5557,7 @@ do_sub(exarg_T *eap)
* 3. substitute the string.
*/
#ifdef FEAT_EVAL
save_ma = curbuf->b_p_ma;
if (subflags.do_count)
{
// prevent accidentally changing the buffer by a function
@@ -5562,7 +5567,6 @@ do_sub(exarg_T *eap)
// Save flags for recursion. They can change for e.g.
// :s/^/\=execute("s#^##gn")
subflags_save = subflags;
save_ma = curbuf->b_p_ma;
#endif
// get length of substitution part
sublen = vim_regsub_multi(&regmatch,
@@ -5603,9 +5607,15 @@ do_sub(exarg_T *eap)
p1 = sub_firstline;
#ifdef FEAT_TEXT_PROP
if (curbuf->b_has_textprop)
adjust_prop_columns(lnum, regmatch.startpos[0].col,
{
// When text properties are changed, need to save for
// undo first, unless done already.
if (adjust_prop_columns(lnum, regmatch.startpos[0].col,
sublen - 1 - (regmatch.endpos[0].col
- regmatch.startpos[0].col));
- regmatch.startpos[0].col),
apc_flags))
apc_flags &= ~APC_SAVE_FOR_UNDO;
}
#endif
}
else
@@ -5706,7 +5716,20 @@ do_sub(exarg_T *eap)
for (p1 = new_end; *p1; ++p1)
{
if (p1[0] == '\\' && p1[1] != NUL) /* remove backslash */
{
STRMOVE(p1, p1 + 1);
#ifdef FEAT_TEXT_PROP
if (curbuf->b_has_textprop)
{
// When text properties are changed, need to save
// for undo first, unless done already.
if (adjust_prop_columns(lnum,
(colnr_T)(p1 - new_start), -1,
apc_flags))
apc_flags &= ~APC_SAVE_FOR_UNDO;
}
#endif
}
else if (*p1 == CAR)
{
if (u_inssub(lnum) == OK) // prepare for undo

View File

@@ -3016,7 +3016,9 @@ ex_packadd(exarg_T *eap)
ex_options(
exarg_T *eap UNUSED)
{
vim_setenv((char_u *)"OPTWIN_CMD", (char_u *)(cmdmod.tab ? "tab" : ""));
vim_setenv((char_u *)"OPTWIN_CMD",
(char_u *)(cmdmod.tab ? "tab"
: (cmdmod.split & WSP_VERT) ? "vert" : ""));
cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
}
#endif

View File

@@ -6470,7 +6470,7 @@ get_list_range(char_u **str, int *num1, int *num2)
*str = skipwhite(*str);
if (**str == '-' || vim_isdigit(**str)) /* parse "from" part of range */
{
vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0);
vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, FALSE);
*str += len;
*num1 = (int)num;
first = TRUE;
@@ -6479,7 +6479,7 @@ get_list_range(char_u **str, int *num1, int *num2)
if (**str == ',') /* parse "to" part of range */
{
*str = skipwhite(*str + 1);
vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0);
vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, FALSE);
if (len > 0)
{
*num2 = (int)num;

View File

@@ -1407,6 +1407,12 @@ openscript(
emsg(_(e_nesting));
return;
}
// Disallow sourcing a file in the sandbox, the commands would be executed
// later, possibly outside of the sandbox.
if (check_secure())
return;
#ifdef FEAT_EVAL
if (ignore_script)
/* Not reading from script, also don't open one. Warning message? */
@@ -1453,9 +1459,9 @@ openscript(
oldcurscript = curscript;
do
{
update_topline_cursor(); /* update cursor position and topline */
normal_cmd(&oa, FALSE); /* execute one command */
vpeekc(); /* check for end of file */
update_topline_cursor(); // update cursor position and topline
normal_cmd(&oa, FALSE); // execute one command
vpeekc(); // check for end of file
}
while (scriptin[oldcurscript] != NULL);
@@ -1753,7 +1759,11 @@ vgetc(void)
buf[i] = vgetorpeek(TRUE);
if (buf[i] == K_SPECIAL
#ifdef FEAT_GUI
|| (gui.in_use && buf[i] == CSI)
|| (
# ifdef VIMDLL
gui.in_use &&
# endif
buf[i] == CSI)
#endif
)
{

View File

@@ -1222,6 +1222,14 @@ FinderFindSpec(PyObject *self, PyObject *args)
return spec;
}
static PyObject *
FinderFindModule(PyObject* self UNUSED, PyObject* args UNUSED)
{
// Apparently returning None works.
Py_INCREF(Py_None);
return Py_None;
}
#else
static PyObject *
call_load_module(char *name, int len, PyObject *find_module_result)
@@ -1400,9 +1408,8 @@ static struct PyMethodDef VimMethods[] = {
{"foreach_rtp", VimForeachRTP, METH_O, "Call given callable for each path in &rtp"},
#if PY_VERSION_HEX >= 0x030700f0
{"find_spec", FinderFindSpec, METH_VARARGS, "Internal use only, returns spec object for any input it receives"},
#else
{"find_module", FinderFindModule, METH_VARARGS, "Internal use only, returns loader object for any input it receives"},
#endif
{"find_module", FinderFindModule, METH_VARARGS, "Internal use only, returns loader object for any input it receives"},
{"path_hook", VimPathHook, METH_VARARGS, "Hook function to install in sys.path_hooks"},
{"_get_paths", (PyCFunction)Vim_GetPaths, METH_NOARGS, "Get &rtp-based additions to sys.path"},
{ NULL, NULL, 0, NULL}

View File

@@ -452,7 +452,12 @@ json_decode_string(js_read_T *reader, typval_T *res, int quote)
nr = 0;
len = 0;
vim_str2nr(p + 2, NULL, &len,
STR2NR_HEX + STR2NR_FORCE, &nr, NULL, 4);
STR2NR_HEX + STR2NR_FORCE, &nr, NULL, 4, TRUE);
if (len == 0)
{
ga_clear(&ga);
return FAIL;
}
p += len + 2;
if (0xd800 <= nr && nr <= 0xdfff
&& (int)(reader->js_end - p) >= 6
@@ -463,7 +468,12 @@ json_decode_string(js_read_T *reader, typval_T *res, int quote)
/* decode surrogate pair: \ud812\u3456 */
len = 0;
vim_str2nr(p + 2, NULL, &len,
STR2NR_HEX + STR2NR_FORCE, &nr2, NULL, 4);
STR2NR_HEX + STR2NR_FORCE, &nr2, NULL, 4, TRUE);
if (len == 0)
{
ga_clear(&ga);
return FAIL;
}
if (0xdc00 <= nr2 && nr2 <= 0xdfff)
{
p += len + 2;
@@ -783,7 +793,13 @@ json_decode_item(js_read_T *reader, typval_T *res, int options)
vim_str2nr(reader->js_buf + reader->js_used,
NULL, &len, 0, /* what */
&nr, NULL, 0);
&nr, NULL, 0, TRUE);
if (len == 0)
{
emsg(_(e_invarg));
retval = FAIL;
goto theend;
}
if (cur_item != NULL)
{
cur_item->v_type = VAR_NUMBER;

View File

@@ -441,7 +441,7 @@ set_indent(
// the old indent, when decreasing indent it behaves like spaces
// were deleted at the new indent.
adjust_prop_columns(curwin->w_cursor.lnum,
(colnr_T)(added > 0 ? (p - oldline) : ind_len), added);
(colnr_T)(added > 0 ? (p - oldline) : ind_len), added, 0);
}
#endif
retval = TRUE;

View File

@@ -2832,7 +2832,12 @@ find_special_key(
bp += 3; /* skip t_xx, xx may be '-' or '>' */
else if (STRNICMP(bp, "char-", 5) == 0)
{
vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0);
vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0, TRUE);
if (l == 0)
{
emsg(_(e_invarg));
return 0;
}
bp += l + 5;
break;
}
@@ -2864,7 +2869,12 @@ find_special_key(
&& VIM_ISDIGIT(last_dash[6]))
{
/* <Char-123> or <Char-033> or <Char-0x33> */
vim_str2nr(last_dash + 6, NULL, NULL, STR2NR_ALL, NULL, &n, 0);
vim_str2nr(last_dash + 6, NULL, &l, STR2NR_ALL, NULL, &n, 0, TRUE);
if (l == 0)
{
emsg(_(e_invarg));
return 0;
}
key = (int)n;
}
else

View File

@@ -1937,7 +1937,7 @@ op_delete(oparg_T *oap)
#ifdef FEAT_TEXT_PROP
if (curbuf->b_has_textprop && n != 0)
adjust_prop_columns(lnum, bd.textcol, -n);
adjust_prop_columns(lnum, bd.textcol, -n, 0);
#endif
}
@@ -5794,7 +5794,7 @@ do_addsub(
0 + (dobin ? STR2NR_BIN : 0)
+ (dooct ? STR2NR_OCT : 0)
+ (dohex ? STR2NR_HEX : 0),
NULL, &n, maxlen);
NULL, &n, maxlen, FALSE);
/* ignore leading '-' for hex and octal and bin numbers */
if (pre && negative)

View File

@@ -4762,10 +4762,10 @@ do_set(
/* Allow negative (for 'undolevels'), octal and
* hex numbers. */
vim_str2nr(arg, NULL, &i, STR2NR_ALL,
&value, NULL, 0);
if (arg[i] != NUL && !VIM_ISWHITE(arg[i]))
&value, NULL, 0, TRUE);
if (i == 0 || (arg[i] != NUL && !VIM_ISWHITE(arg[i])))
{
errmsg = e_invarg;
errmsg = N_("E521: Number required after =");
goto skip;
}
}

View File

@@ -54,7 +54,7 @@ char_u *skiptowhite(char_u *p);
char_u *skiptowhite_esc(char_u *p);
long getdigits(char_u **pp);
int vim_isblankline(char_u *lbuf);
void vim_str2nr(char_u *start, int *prep, int *len, int what, varnumber_T *nptr, uvarnumber_T *unptr, int maxlen);
void vim_str2nr(char_u *start, int *prep, int *len, int what, varnumber_T *nptr, uvarnumber_T *unptr, int maxlen, int strict);
int hex2nr(int c);
int hexhex2nr(char_u *p);
int rem_backslash(char_u *str);

View File

@@ -13,7 +13,7 @@ void f_prop_type_get(typval_T *argvars, typval_T *rettv);
void f_prop_type_list(typval_T *argvars, typval_T *rettv);
void clear_global_prop_types(void);
void clear_buf_prop_types(buf_T *buf);
void adjust_prop_columns(linenr_T lnum, colnr_T col, int bytes_added);
int adjust_prop_columns(linenr_T lnum, colnr_T col, int bytes_added, int flags);
void adjust_props_for_split(linenr_T lnum_props, linenr_T lnum_top, int kept, int deleted);
void adjust_props_for_join(linenr_T lnum, textprop_T **prop_line, int *prop_length, long col, int removed);
void join_prop_lines(linenr_T lnum, char_u *newp, textprop_T **prop_lines, int *prop_lengths, int count);

View File

@@ -14,7 +14,6 @@ SCRIPTS_FIRST = \
# Tests that run on all systems.
SCRIPTS_ALL = \
test3.out \
test37.out \
test39.out \
test42.out \
test44.out \

View File

@@ -74,7 +74,7 @@ VIMPROG = <->vim.exe
.SUFFIXES : .out .in
SCRIPT = test1.out test3.out \
test30.out test37.out test39.out \
test30.out test39.out \
test42.out test44.out test48.out test49.out \
test64.out test69.out \
test72.out test77a.out test88.out \

View File

@@ -1,116 +0,0 @@
Test for 'scrollbind'. <eralston@computer.org> Do not add a line below!
STARTTEST
:so small.vim
:set noscrollbind
:set scrollopt=ver,jump
:set scrolloff=2
:set nowrap
:set noequalalways
:set splitbelow
:" TEST using two windows open to one buffer, one extra empty window
:split
:new
t:
:resize 8
/^start of window 1$/
zt:
:set scrollbind
j:
:resize 7
/^start of window 2$/
zt:
:set scrollbind
:" -- start of tests --
:" TEST scrolling down
L5jHyybpr0tHyybpr1tL6jHyybpr2kHyybpr3:
:" TEST scrolling up
tH4kjHtHyybpr4kHyybpr5k3ktHjHyybpr6tHyybpr7:
:" TEST horizontal scrolling
:set scrollopt+=hor
gg"zyyG"zpGt015zly$bp"zpGky$bp"zpG:
k10jH7zhg0y$bp"zpGtHg0y$bp"zpG:
:set scrollopt-=hor
:" ****** tests using two different buffers *****
tj:
:close
t:
:set noscrollbind
:/^start of window 2$/,/^end of window 2$/y
:new
tj4"zpGp:
t/^start of window 1$/
zt:
:set scrollbind
j:
/^start of window 2$/
zt:
:set scrollbind
:" -- start of tests --
:" TEST scrolling down
L5jHyybpr0tHyybpr1tL6jHyybpr2kHyybpr3:
:" TEST scrolling up
tH4kjHtHyybpr4kHyybpr5k3ktHjHyybpr6tHyybpr7:
:" TEST horizontal scrolling
:set scrollopt+=hor
gg"zyyG"zpGt015zly$bp"zpGky$bp"zpG:
k10jH7zhg0y$bp"zpGtHg0y$bp"zpG:
:set scrollopt-=hor
:" TEST syncbind
t:set noscb
ggLj:set noscb
ggL:set scb
t:set scb
GjG:syncbind
HktHjHyybptyybp:
t:set noscb
ggLj:set noscb
ggL:set scb
t:set scb
tGjGt:syncbind
HkjHtHyybptjyybp:
tH3kjHtHyybptjyybp:
:" ***** done with tests *****
:w! test.out " Write contents of this file
:qa!
ENDTEST
start of window 1
. line 01 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 01
. line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
. line 03 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 03
. line 04 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 04
. line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05
. line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06
. line 07 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 07
. line 08 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 08
. line 09 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 09
. line 10 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 10
. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
. line 12 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 12
. line 13 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 13
. line 14 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 14
. line 15 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 15
end of window 1
start of window 2
. line 01 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 01
. line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02
. line 03 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 03
. line 04 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 04
. line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05
. line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06
. line 07 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 07
. line 08 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 08
. line 09 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 09
. line 10 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 10
. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12
. line 13 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 13
. line 14 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 14
. line 15 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 15
. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16
end of window 2
end of test37.in (please don't delete this line)

View File

@@ -1,33 +0,0 @@
0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05
1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05
2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06
5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06
6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02
7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
UTSRQPONMLKJIHGREDCBA9876543210 02
. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05
1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05
2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06
5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06
6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02
7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
UTSRQPONMLKJIHGREDCBA9876543210 02
. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16
:set scrollbind
:set scrollbind
. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16
j:
. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12

View File

@@ -423,18 +423,20 @@ func Test_autocmd_bufwipe_in_SessLoadPost()
set noswapfile
mksession!
let content = ['set nocp noswapfile',
\ 'let v:swapchoice="e"',
\ 'augroup test_autocmd_sessionload',
\ 'autocmd!',
\ 'autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!"',
\ 'augroup END',
\ '',
\ 'func WriteErrors()',
\ ' call writefile([execute("messages")], "Xerrors")',
\ 'endfunc',
\ 'au VimLeave * call WriteErrors()',
\ ]
let content =<< trim [CODE]
set nocp noswapfile
let v:swapchoice="e"
augroup test_autocmd_sessionload
autocmd!
autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!"
augroup END
func WriteErrors()
call writefile([execute("messages")], "Xerrors")
endfunc
au VimLeave * call WriteErrors()
[CODE]
call writefile(content, 'Xvimrc')
call system(v:progpath. ' -u Xvimrc --not-a-term --noplugins -S Session.vim -c cq')
let errors = join(readfile('Xerrors'))
@@ -452,27 +454,29 @@ func Test_autocmd_bufwipe_in_SessLoadPost2()
set noswapfile
mksession!
let content = ['set nocp noswapfile',
\ 'function! DeleteInactiveBufs()',
\ ' tabfirst',
\ ' let tabblist = []',
\ ' for i in range(1, tabpagenr(''$''))',
\ ' call extend(tabblist, tabpagebuflist(i))',
\ ' endfor',
\ ' for b in range(1, bufnr(''$''))',
\ ' if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')',
\ ' exec ''bwipeout '' . b',
\ ' endif',
\ ' endfor',
\ ' echomsg "SessionLoadPost DONE"',
\ 'endfunction',
\ 'au SessionLoadPost * call DeleteInactiveBufs()',
\ '',
\ 'func WriteErrors()',
\ ' call writefile([execute("messages")], "Xerrors")',
\ 'endfunc',
\ 'au VimLeave * call WriteErrors()',
\ ]
let content =<< trim [CODE]
set nocp noswapfile
function! DeleteInactiveBufs()
tabfirst
let tabblist = []
for i in range(1, tabpagenr(''$''))
call extend(tabblist, tabpagebuflist(i))
endfor
for b in range(1, bufnr(''$''))
if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')
exec ''bwipeout '' . b
endif
endfor
echomsg "SessionLoadPost DONE"
endfunction
au SessionLoadPost * call DeleteInactiveBufs()
func WriteErrors()
call writefile([execute("messages")], "Xerrors")
endfunc
au VimLeave * call WriteErrors()
[CODE]
call writefile(content, 'Xvimrc')
call system(v:progpath. ' -u Xvimrc --not-a-term --noplugins -S Session.vim -c cq')
let errors = join(readfile('Xerrors'))
@@ -933,21 +937,23 @@ func Test_bufunload_all()
call writefile(['Test file Xxx1'], 'Xxx1')"
call writefile(['Test file Xxx2'], 'Xxx2')"
let content = [
\ "func UnloadAllBufs()",
\ " let i = 1",
\ " while i <= bufnr('$')",
\ " if i != bufnr('%') && bufloaded(i)",
\ " exe i . 'bunload'",
\ " endif",
\ " let i += 1",
\ " endwhile",
\ "endfunc",
\ "au BufUnload * call UnloadAllBufs()",
\ "au VimLeave * call writefile(['Test Finished'], 'Xout')",
\ "edit Xxx1",
\ "split Xxx2",
\ "q"]
let content =<< trim [CODE]
func UnloadAllBufs()
let i = 1
while i <= bufnr('$')
if i != bufnr('%') && bufloaded(i)
exe i . 'bunload'
endif
let i += 1
endwhile
endfunc
au BufUnload * call UnloadAllBufs()
au VimLeave * call writefile(['Test Finished'], 'Xout')
edit Xxx1
split Xxx2
q
[CODE]
call writefile(content, 'Xtest')
call delete('Xout')

View File

@@ -8,14 +8,14 @@ if !CanRunVimInTerminal()
finish
endif
let s:common_script = [
\ 'call setline(1, ["one one one", "two tXo two", "three three three"])',
\ 'set balloonevalterm balloonexpr=MyBalloonExpr() balloondelay=100',
\ 'func MyBalloonExpr()',
\ ' return "line " .. v:beval_lnum .. " column " .. v:beval_col .. ": " .. v:beval_text',
\ 'endfun',
\ 'redraw',
\ ]
let s:common_script =<< [CODE]
call setline(1, ["one one one", "two tXo two", "three three three"])
set balloonevalterm balloonexpr=MyBalloonExpr() balloondelay=100
func MyBalloonExpr()
return "line " .. v:beval_lnum .. " column " .. v:beval_col .. ": " .. v:beval_text
endfun
redraw
[CODE]
func Test_balloon_eval_term()
" Use <Ignore> after <MouseMove> to return from vgetc() without removing

View File

@@ -93,23 +93,24 @@ func Test_appendbufline()
endfunc
func Test_appendbufline_no_E315()
let after = [
\ 'set stl=%f ls=2',
\ 'new',
\ 'let buf = bufnr("%")',
\ 'quit',
\ 'vsp',
\ 'exec "buffer" buf',
\ 'wincmd w',
\ 'call appendbufline(buf, 0, "abc")',
\ 'redraw',
\ 'while getbufline(buf, 1)[0] =~ "^\\s*$"',
\ ' sleep 10m',
\ 'endwhile',
\ 'au VimLeavePre * call writefile([v:errmsg], "Xerror")',
\ 'au VimLeavePre * call writefile(["done"], "Xdone")',
\ 'qall!',
\ ]
let after =<< trim [CODE]
set stl=%f ls=2
new
let buf = bufnr("%")
quit
vsp
exec "buffer" buf
wincmd w
call appendbufline(buf, 0, "abc")
redraw
while getbufline(buf, 1)[0] =~ "^\\s*$"
sleep 10m
endwhile
au VimLeavePre * call writefile([v:errmsg], "Xerror")
au VimLeavePre * call writefile(["done"], "Xdone")
qall!
[CODE]
if !RunVim([], after, '--clean')
return
endif

View File

@@ -18,25 +18,25 @@ endfunc
func Test_cino_extern_c()
" Test for cino-E
let without_ind = [
\ '#ifdef __cplusplus',
\ 'extern "C" {',
\ '#endif',
\ 'int func_a(void);',
\ '#ifdef __cplusplus',
\ '}',
\ '#endif'
\ ]
let without_ind =<< trim [CODE]
#ifdef __cplusplus
extern "C" {
#endif
int func_a(void);
#ifdef __cplusplus
}
#endif
[CODE]
let with_ind = [
\ '#ifdef __cplusplus',
\ 'extern "C" {',
\ '#endif',
\ "\tint func_a(void);",
\ '#ifdef __cplusplus',
\ '}',
\ '#endif'
\ ]
let with_ind =<< trim [CODE]
#ifdef __cplusplus
extern "C" {
#endif
int func_a(void);
#ifdef __cplusplus
}
#endif
[CODE]
new
setlocal cindent cinoptions=E0
call setline(1, without_ind)
@@ -89,16 +89,32 @@ func Test_cindent_expr()
return v:lnum == 1 ? shiftwidth() : 0
endfunc
setl expandtab sw=8 indentkeys+=; indentexpr=MyIndentFunction()
call setline(1, ['var_a = something()', 'b = something()'])
let testinput =<< trim [CODE]
var_a = something()
b = something()
[CODE]
call setline(1, testinput)
call cursor(1, 1)
call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
call assert_equal([' var_a = something();', 'b = something();'], getline(1, '$'))
let expected =<< trim [CODE]
var_a = something();
b = something();
[CODE]
call assert_equal(expected, getline(1, '$'))
%d
call setline(1, [' var_a = something()', ' b = something()'])
let testinput =<< trim [CODE]
var_a = something()
b = something()
[CODE]
call setline(1, testinput)
call cursor(1, 1)
call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
call assert_equal([' var_a = something();', ' b = something()'], getline(1, '$'))
let expected =<< trim [CODE]
var_a = something();
b = something()
[CODE]
call assert_equal(expected, getline(1, '$'))
bw!
endfunc

View File

@@ -11,21 +11,23 @@ if !CanRunVimInTerminal()
endif
func Test_conceal_two_windows()
call writefile([
\ 'let lines = ["one one one one one", "two |hidden| here", "three |hidden| three"]',
\ 'call setline(1, lines)',
\ 'syntax match test /|hidden|/ conceal',
\ 'set conceallevel=2',
\ 'set concealcursor=',
\ 'exe "normal /here\r"',
\ 'new',
\ 'call setline(1, lines)',
\ 'call setline(4, "Second window")',
\ 'syntax match test /|hidden|/ conceal',
\ 'set conceallevel=2',
\ 'set concealcursor=nc',
\ 'exe "normal /here\r"',
\ ], 'XTest_conceal')
let code =<< trim [CODE]
let lines = ["one one one one one", "two |hidden| here", "three |hidden| three"]
call setline(1, lines)
syntax match test /|hidden|/ conceal
set conceallevel=2
set concealcursor=
exe "normal /here\r"
new
call setline(1, lines)
call setline(4, "Second window")
syntax match test /|hidden|/ conceal
set conceallevel=2
set concealcursor=nc
exe "normal /here\r"
[CODE]
call writefile(code, 'XTest_conceal')
" Check that cursor line is concealed
let buf = RunVimInTerminal('-S XTest_conceal', {})
call VerifyScreenDump(buf, 'Test_conceal_two_windows_01', {})
@@ -113,14 +115,16 @@ endfunc
func Test_conceal_with_cursorline()
" Opens a help window, where 'conceal' is set, switches to the other window
" where 'cursorline' needs to be updated when the cursor moves.
call writefile([
\ 'set cursorline',
\ 'normal othis is a test',
\ 'new',
\ 'call setline(1, ["one", "two", "three", "four", "five"])',
\ 'set ft=help',
\ 'normal M',
\ ], 'XTest_conceal_cul')
let code =<< trim [CODE]
set cursorline
normal othis is a test
new
call setline(1, ["one", "two", "three", "four", "five"])
set ft=help
normal M
[CODE]
call writefile(code, 'XTest_conceal_cul')
let buf = RunVimInTerminal('-S XTest_conceal_cul', {})
call VerifyScreenDump(buf, 'Test_conceal_cul_01', {})

View File

@@ -3,52 +3,56 @@
source shared.vim
func Test_exiting()
let after = [
\ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")',
\ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
\ 'quit',
\ ]
let after =<< trim [CODE]
au QuitPre * call writefile(["QuitPre"], "Xtestout")
au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")
quit
[CODE]
if RunVim([], after, '')
call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
endif
call delete('Xtestout')
let after = [
\ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")',
\ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
\ 'help',
\ 'wincmd w',
\ 'quit',
\ ]
let after =<< trim [CODE]
au QuitPre * call writefile(["QuitPre"], "Xtestout")
au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")
help
wincmd w
quit
[CODE]
if RunVim([], after, '')
call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
endif
call delete('Xtestout')
let after = [
\ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")',
\ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
\ 'split',
\ 'new',
\ 'qall',
\ ]
let after =<< trim [CODE]
au QuitPre * call writefile(["QuitPre"], "Xtestout")
au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")
split
new
qall
[CODE]
if RunVim([], after, '')
call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
endif
call delete('Xtestout')
let after = [
\ 'au QuitPre * call writefile(["QuitPre"], "Xtestout", "a")',
\ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
\ 'augroup nasty',
\ ' au ExitPre * split',
\ 'augroup END',
\ 'quit',
\ 'augroup nasty',
\ ' au! ExitPre',
\ 'augroup END',
\ 'quit',
\ ]
let after =<< trim [CODE]
au QuitPre * call writefile(["QuitPre"], "Xtestout", "a")
au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")
augroup nasty
au ExitPre * split
augroup END
quit
augroup nasty
au! ExitPre
augroup END
quit
[CODE]
if RunVim([], after, '')
call assert_equal(['QuitPre', 'ExitPre', 'QuitPre', 'ExitPre'],
\ readfile('Xtestout'))

View File

@@ -512,3 +512,14 @@ func Test_empty_concatenate()
call assert_equal('b', 'a'[4:0] . 'b')
call assert_equal('b', 'b' . 'a'[4:0])
endfunc
func Test_broken_number()
let X = 'bad'
call assert_fails('echo 1X', 'E15:')
call assert_fails('echo 0b1X', 'E15:')
call assert_fails('echo 0b12', 'E15:')
call assert_fails('echo 0x1X', 'E15:')
call assert_fails('echo 011X', 'E15:')
call assert_equal(2, str2nr('2a'))
call assert_fails('inoremap <Char-0b1z> b', 'E474:')
endfunc

View File

@@ -513,17 +513,18 @@ func Test_fold_create_marker_in_C()
set fdm=marker fdl=9
set filetype=c
let content = [
\ '/*',
\ ' * comment',
\ ' * ',
\ ' *',
\ ' */',
\ 'int f(int* p) {',
\ ' *p = 3;',
\ ' return 0;',
\ '}'
\]
let content =<< trim [CODE]
/*
* comment
*
*
*/
int f(int* p) {
*p = 3;
return 0;
}
[CODE]
for c in range(len(content) - 1)
bw!
call append(0, content)

View File

@@ -15,262 +15,282 @@ func XTest_goto_decl(cmd, lines, line, col)
endfunc
func Test_gD()
let lines = [
\ 'int x;',
\ '',
\ 'int func(void)',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int x;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 1, 5)
endfunc
func Test_gD_too()
let lines = [
\ 'Filename x;',
\ '',
\ 'int Filename',
\ 'int func() {',
\ ' Filename x;',
\ ' return x;',
\ ]
let lines =<< trim [CODE]
Filename x;
int Filename
int func() {
Filename x;
return x;
[CODE]
call XTest_goto_decl('gD', lines, 1, 10)
endfunc
func Test_gD_comment()
let lines = [
\ '/* int x; */',
\ 'int x;',
\ '',
\ 'int func(void)',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
/* int x; */
int x;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 2, 5)
endfunc
func Test_gD_inline_comment()
let lines = [
\ 'int y /* , x */;',
\ 'int x;',
\ '',
\ 'int func(void)',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int y /* , x */;
int x;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 2, 5)
endfunc
func Test_gD_string()
let lines = [
\ 'char *s[] = "x";',
\ 'int x = 1;',
\ '',
\ 'int func(void)',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
char *s[] = "x";
int x = 1;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 2, 5)
endfunc
func Test_gD_string_same_line()
let lines = [
\ 'char *s[] = "x", int x = 1;',
\ '',
\ 'int func(void)',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
char *s[] = "x", int x = 1;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 1, 22)
endfunc
func Test_gD_char()
let lines = [
\ "char c = 'x';",
\ 'int x = 1;',
\ '',
\ 'int func(void)',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
char c = 'x';
int x = 1;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 2, 5)
endfunc
func Test_gd()
let lines = [
\ 'int x;',
\ '',
\ 'int func(int x)',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int x;
int func(int x)
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 3, 14)
endfunc
func Test_gd_not_local()
let lines = [
\ 'int func1(void)',
\ '{',
\ ' return x;',
\ '}',
\ '',
\ 'int func2(int x)',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int func1(void)
{
return x;
}
int func2(int x)
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 3, 10)
endfunc
func Test_gd_kr_style()
let lines = [
\ 'int func(x)',
\ ' int x;',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int func(x)
int x;
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 2, 7)
endfunc
func Test_gd_missing_braces()
let lines = [
\ 'def func1(a)',
\ ' a + 1',
\ 'end',
\ '',
\ 'a = 1',
\ '',
\ 'def func2()',
\ ' return a',
\ 'end',
\ ]
let lines =<< trim [CODE]
def func1(a)
a + 1
end
a = 1
def func2()
return a
end
[CODE]
call XTest_goto_decl('gd', lines, 1, 11)
endfunc
func Test_gd_comment()
let lines = [
\ 'int func(void)',
\ '{',
\ ' /* int x; */',
\ ' int x;',
\ ' return x;',
\ '}',
\]
let lines =<< trim [CODE]
int func(void)
{
/* int x; */
int x;
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 4, 7)
endfunc
func Test_gd_comment_in_string()
let lines = [
\ 'int func(void)',
\ '{',
\ ' char *s ="//"; int x;',
\ ' int x;',
\ ' return x;',
\ '}',
\]
let lines =<< trim [CODE]
int func(void)
{
char *s ="//"; int x;
int x;
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 3, 22)
endfunc
func Test_gd_string_in_comment()
set comments=
let lines = [
\ 'int func(void)',
\ '{',
\ ' /* " */ int x;',
\ ' int x;',
\ ' return x;',
\ '}',
\]
let lines =<< trim [CODE]
int func(void)
{
/* " */ int x;
int x;
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 3, 15)
set comments&
endfunc
func Test_gd_inline_comment()
let lines = [
\ 'int func(/* x is an int */ int x)',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int func(/* x is an int */ int x)
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 1, 32)
endfunc
func Test_gd_inline_comment_only()
let lines = [
\ 'int func(void) /* one lonely x */',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int func(void) /* one lonely x */
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 3, 10)
endfunc
func Test_gd_inline_comment_body()
let lines = [
\ 'int func(void)',
\ '{',
\ ' int y /* , x */;',
\ '',
\ ' for (/* int x = 0 */; y < 2; y++);',
\ '',
\ ' int x = 0;',
\ '',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int func(void)
{
int y /* , x */;
for (/* int x = 0 */; y < 2; y++);
int x = 0;
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 7, 7)
endfunc
func Test_gd_trailing_multiline_comment()
let lines = [
\ 'int func(int x) /* x is an int */',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int func(int x) /* x is an int */
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 1, 14)
endfunc
func Test_gd_trailing_comment()
let lines = [
\ 'int func(int x) // x is an int',
\ '{',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int func(int x) // x is an int
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 1, 14)
endfunc
func Test_gd_string()
let lines = [
\ 'int func(void)',
\ '{',
\ ' char *s = "x";',
\ ' int x = 1;',
\ '',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int func(void)
{
char *s = "x";
int x = 1;
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 4, 7)
endfunc
func Test_gd_string_only()
let lines = [
\ 'int func(void)',
\ '{',
\ ' char *s = "x";',
\ '',
\ ' return x;',
\ '}',
\ ]
let lines =<< trim [CODE]
int func(void)
{
char *s = "x";
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 5, 10)
endfunc
@@ -289,24 +309,25 @@ func Test_cursorline_keep_col()
endfunc
func Test_gd_local_block()
let lines = [
\ ' int main()',
\ '{',
\ ' char *a = "NOT NULL";',
\ ' if(a)',
\ ' {',
\ ' char *b = a;',
\ ' printf("%s\n", b);',
\ ' }',
\ ' else',
\ ' {',
\ ' char *b = "NULL";',
\ ' return b;',
\ ' }',
\ '',
\ ' return 0;',
\ '}',
\ ]
let lines =<< trim [CODE]
int main()
{
char *a = "NOT NULL";
if(a)
{
char *b = a;
printf("%s\n", b);
}
else
{
char *b = "NULL";
return b;
}
return 0;
}
[CODE]
call XTest_goto_decl('1gd', lines, 11, 11)
endfunc

View File

@@ -98,30 +98,27 @@ ert
normal `xyl$p
normal `yy2l$p
normal G
let last_line = line('$')
" Expected output
append
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
zx cvn. as dfg? hjkl iop! ert ernop
zx cvn. as dfg? hjkl iop! ert ernop
.
let expected =<< trim [DATA]
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
zx cvn. as dfg? hjkl iop! ert ernop
zx cvn. as dfg? hjkl iop! ert ernop
[DATA]
call assert_equal(getline(last_line + 1, '$'), getline(1, last_line))
call assert_equal(expected, getline(1, '$'))
enew!
call append(0, text)
@@ -143,31 +140,28 @@ zx cvn. as dfg? hjkl iop! ert ernop
normal `xyl$p
normal `yy2l$p
normal G
let last_line = line('$')
" Expected output
append
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
zx cvn. as dfg? hjkl iop! ert enop
zx cvn. as dfg? hjkl iop! ert ernop
let expected =<< trim [DATA]
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
zx cvn. as dfg? hjkl iop! ert enop
zx cvn. as dfg? hjkl iop! ert ernop
.
[DATA]
call assert_equal(getline(last_line + 1, '$'), getline(1, last_line))
call assert_equal(expected, getline(1, '$'))
enew!
call append(0, text)
@@ -180,29 +174,26 @@ zx cvn. as dfg? hjkl iop! ert ernop
normal JjJjJjJjJjJjJjJjJjJjJjJjJjJ
normal j4Jy3l$pjdG
normal G
let last_line = line('$')
" Expected output
append
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
zx cvn. as dfg? hjkl iop! ert a
.
let expected =<< trim [DATA]
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf. asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
asdfasdf asdf
zx cvn. as dfg? hjkl iop! ert a
[DATA]
call assert_equal(getline(last_line + 1, '$'), getline(1, last_line))
call assert_equal(expected, getline(1, '$'))
set nocompatible
set cpoptions&vim
@@ -262,11 +253,8 @@ action();
.,+2join
exe "normal jj3J\<CR>"
normal G
let last_line = line('$')
" Expected output
append
let expected =<< trim [CODE]
{
/* Make sure the previous comment leader is not removed. */
/* Make sure the previous comment leader is not removed. */
@@ -279,9 +267,9 @@ action();
if (condition) // Remove the next comment leader! OK, I will.
action();
}
.
[CODE]
call assert_equal(getline(last_line + 1, '$'), getline(1, last_line))
call assert_equal(expected, getline(1, '$'))
set comments&vim
set joinspaces&vim
@@ -389,11 +377,8 @@ int i = 7 /* foo *// 3
exe "normal j6J\<CR>"
exe "normal oSome code!\<CR>// Make sure backspacing does not remove this comment leader.\<Esc>0i\<C-H>\<Esc>"
normal G
let last_line = line('$')
" Expected output
append
let expected =<< [CODE]
{
/* Make sure the previous comment leader is not removed. */
/* Make sure the previous comment leader is not removed. */
@@ -416,8 +401,8 @@ int i = 7 /* foo *// 3 // comment
Some code!// Make sure backspacing does not remove this comment leader.
}
.
[CODE]
call assert_equal(getline(last_line + 1, '$'), getline(1, last_line))
call assert_equal(expected, getline(1, '$'))
close!
endfunc

View File

@@ -176,6 +176,10 @@ func Test_json_decode()
call assert_fails('call json_decode("{{}:42}")', "E474:")
call assert_fails('call json_decode("{[]:42}")', "E474:")
call assert_fails('call json_decode("\"\\u111Z\"")', 'E474:')
call assert_equal('[😂]', json_decode('"[\uD83D\uDE02]"'))
call assert_equal('a😂b', json_decode('"a\uD83D\uDE02b"'))
endfunc
let s:jsl5 = '[7,,,]'

View File

@@ -151,3 +151,109 @@ func Test_let_utf8_environment()
let $a = 'ĀĒĪŌŪあいうえお'
call assert_equal('ĀĒĪŌŪあいうえお', $a)
endfunc
func Test_let_heredoc_fails()
call assert_fails('let v =<< marker', 'E991:')
let text =<< trim END
func WrongSyntax()
let v =<< that there
endfunc
END
call writefile(text, 'XheredocFail')
call assert_fails('source XheredocFail', 'E126:')
call delete('XheredocFail')
let text =<< trim END
func MissingEnd()
let v =<< END
endfunc
END
call writefile(text, 'XheredocWrong')
call assert_fails('source XheredocWrong', 'E126:')
call delete('XheredocWrong')
endfunc
" Test for the setting a variable using the heredoc syntax
func Test_let_heredoc()
let var1 =<< END
Some sample text
Text with indent
!@#$%^&*()-+_={}|[]\~`:";'<>?,./
END
call assert_equal(["Some sample text", "\tText with indent", " !@#$%^&*()-+_={}|[]\\~`:\";'<>?,./"], var1)
let var2 =<<
Editor
.
call assert_equal(['Editor'], var2)
let var3 =<<END
END
call assert_equal([], var3)
let var3 =<<END
vim
end
END
END
END
call assert_equal(['vim', '', 'end', ' END', 'END '], var3)
let var1 =<< trim END
Line1
Line2
Line3
END
END
call assert_equal(['Line1', ' Line2', "\tLine3", ' END'], var1)
let var1 =<< trim
Line1
.
call assert_equal([' Line1'], var1)
" ignore "endfunc"
let var1 =<< END
something
endfunc
END
call assert_equal(['something', 'endfunc'], var1)
" ignore "endfunc" with trim
let var1 =<< trim END
something
endfunc
END
call assert_equal(['something', 'endfunc'], var1)
" ignore "python << xx"
let var1 =<<END
something
python << xx
END
call assert_equal(['something', 'python << xx'], var1)
" ignore "python << xx" with trim
let var1 =<< trim END
something
python << xx
END
call assert_equal(['something', 'python << xx'], var1)
" ignore "append"
let var1 =<<
something
app
.
call assert_equal(['something', 'app'], var1)
" ignore "append" with trim
let var1 =<< trim
something
app
.
call assert_equal(['something', 'app'], var1)
endfunc

View File

@@ -65,34 +65,35 @@ func Test_mksession_utf8()
call wincol()
mksession! test_mks.out
let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"')
let expected = [
\ 'normal! 016|',
\ 'normal! 016|',
\ 'normal! 016|',
\ 'normal! 08|',
\ 'normal! 08|',
\ 'normal! 016|',
\ 'normal! 016|',
\ 'normal! 016|',
\ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
\ " normal! 016|",
\ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
\ " normal! 016|",
\ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
\ " normal! 016|",
\ " exe 'normal! ' . s:c . '|zs' . 8 . '|'",
\ " normal! 08|",
\ " exe 'normal! ' . s:c . '|zs' . 8 . '|'",
\ " normal! 08|",
\ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
\ " normal! 016|",
\ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
\ " normal! 016|",
\ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
\ " normal! 016|",
\ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
\ " normal! 016|"
\ ]
let expected =<< trim [DATA]
normal! 016|
normal! 016|
normal! 016|
normal! 08|
normal! 08|
normal! 016|
normal! 016|
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 8 . '|'
normal! 08|
exe 'normal! ' . s:c . '|zs' . 8 . '|'
normal! 08|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
[DATA]
call assert_equal(expected, li)
tabclose!

View File

@@ -1555,73 +1555,158 @@ endfunc
fun! Test_normal29_brace()
" basic test for { and } movements
let text= ['A paragraph begins after each empty line, and also at each of a set of',
\ 'paragraph macros, specified by the pairs of characters in the ''paragraphs''',
\ 'option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to',
\ 'the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in',
\ 'the first column). A section boundary is also a paragraph boundary.',
\ 'Note that a blank line (only containing white space) is NOT a paragraph',
\ 'boundary.',
\ '',
\ '',
\ 'Also note that this does not include a ''{'' or ''}'' in the first column. When',
\ 'the ''{'' flag is in ''cpoptions'' then ''{'' in the first column is used as a',
\ 'paragraph boundary |posix|.',
\ '{',
\ 'This is no paragraph',
\ 'unless the ''{'' is set',
\ 'in ''cpoptions''',
\ '}',
\ '.IP',
\ 'The nroff macros IP separates a paragraph',
\ 'That means, it must be a ''.''',
\ 'followed by IP',
\ '.LPIt does not matter, if afterwards some',
\ 'more characters follow.',
\ '.SHAlso section boundaries from the nroff',
\ 'macros terminate a paragraph. That means',
\ 'a character like this:',
\ '.NH',
\ 'End of text here']
let text =<< trim [DATA]
A paragraph begins after each empty line, and also at each of a set of
paragraph macros, specified by the pairs of characters in the 'paragraphs'
option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
the first column). A section boundary is also a paragraph boundary.
Note that a blank line (only containing white space) is NOT a paragraph
boundary.
Also note that this does not include a '{' or '}' in the first column. When
the '{' flag is in 'cpoptions' then '{' in the first column is used as a
paragraph boundary |posix|.
{
This is no paragraph
unless the '{' is set
in 'cpoptions'
}
.IP
The nroff macros IP separates a paragraph
That means, it must be a '.'
followed by IP
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
[DATA]
new
call append(0, text)
1
norm! 0d2}
call assert_equal(['.IP',
\ 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''', 'followed by IP',
\ '.LPIt does not matter, if afterwards some', 'more characters follow.', '.SHAlso section boundaries from the nroff',
\ 'macros terminate a paragraph. That means', 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
let expected =<< trim [DATA]
.IP
The nroff macros IP separates a paragraph
That means, it must be a '.'
followed by IP
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
[DATA]
call assert_equal(expected, getline(1, '$'))
norm! 0d}
call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.',
\ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
\ 'a character like this:', '.NH', 'End of text here', ''], getline(1, '$'))
let expected =<< trim [DATA]
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
[DATA]
call assert_equal(expected, getline(1, '$'))
$
norm! d{
call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.',
\ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means', 'a character like this:', ''], getline(1, '$'))
let expected =<< trim [DATA]
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
[DATA]
call assert_equal(expected, getline(1, '$'))
norm! d{
call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.', ''], getline(1,'$'))
let expected =<< trim [DATA]
.LPIt does not matter, if afterwards some
more characters follow.
[DATA]
call assert_equal(expected, getline(1, '$'))
" Test with { in cpooptions
%d
call append(0, text)
set cpo+={
1
norm! 0d2}
call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
\ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''',
\ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
\ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
\ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
let expected =<< trim [DATA]
{
This is no paragraph
unless the '{' is set
in 'cpoptions'
}
.IP
The nroff macros IP separates a paragraph
That means, it must be a '.'
followed by IP
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
[DATA]
call assert_equal(expected, getline(1, '$'))
$
norm! d}
call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
\ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''',
\ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
\ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
\ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
let expected =<< trim [DATA]
{
This is no paragraph
unless the '{' is set
in 'cpoptions'
}
.IP
The nroff macros IP separates a paragraph
That means, it must be a '.'
followed by IP
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
[DATA]
call assert_equal(expected, getline(1, '$'))
norm! gg}
norm! d5}
call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$'))
let expected =<< trim [DATA]
{
This is no paragraph
unless the '{' is set
in 'cpoptions'
}
[DATA]
call assert_equal(expected, getline(1, '$'))
" clean up
set cpo-={

View File

@@ -51,6 +51,32 @@ func Test_options()
endtry
call assert_equal('ok', caught)
" Check if the option-window is opened horizontally.
wincmd j
call assert_notequal('option-window', bufname(''))
wincmd k
call assert_equal('option-window', bufname(''))
" close option-window
close
" Open the option-window vertically.
vert options
" Check if the option-window is opened vertically.
wincmd l
call assert_notequal('option-window', bufname(''))
wincmd h
call assert_equal('option-window', bufname(''))
" close option-window
close
" Open the option-window in a new tab.
tab options
" Check if the option-window is opened in a tab.
normal gT
call assert_notequal('option-window', bufname(''))
normal gt
call assert_equal('option-window', bufname(''))
" close option-window
close
endfunc

View File

@@ -4,34 +4,34 @@ if !has('profile')
endif
func Test_profile_func()
let lines = [
\ 'profile start Xprofile_func.log',
\ 'profile func Foo*"',
\ "func! Foo1()",
\ "endfunc",
\ "func! Foo2()",
\ " let l:count = 100",
\ " while l:count > 0",
\ " let l:count = l:count - 1",
\ " endwhile",
\ "endfunc",
\ "func! Foo3()",
\ "endfunc",
\ "func! Bar()",
\ "endfunc",
\ "call Foo1()",
\ "call Foo1()",
\ "profile pause",
\ "call Foo1()",
\ "profile continue",
\ "call Foo2()",
\ "call Foo3()",
\ "call Bar()",
\ "if !v:profiling",
\ " delfunc Foo2",
\ "endif",
\ "delfunc Foo3",
\ ]
let lines =<< trim [CODE]
profile start Xprofile_func.log
profile func Foo*
func! Foo1()
endfunc
func! Foo2()
let l:count = 100
while l:count > 0
let l:count = l:count - 1
endwhile
endfunc
func! Foo3()
endfunc
func! Bar()
endfunc
call Foo1()
call Foo1()
profile pause
call Foo1()
profile continue
call Foo2()
call Foo3()
call Bar()
if !v:profiling
delfunc Foo2
endif
delfunc Foo3
[CODE]
call writefile(lines, 'Xprofile_func.vim')
call system(v:progpath
@@ -86,38 +86,38 @@ func Test_profile_func()
endfunc
func Test_profile_func_with_ifelse()
let lines = [
\ "func! Foo1()",
\ " if 1",
\ " let x = 0",
\ " elseif 1",
\ " let x = 1",
\ " else",
\ " let x = 2",
\ " endif",
\ "endfunc",
\ "func! Foo2()",
\ " if 0",
\ " let x = 0",
\ " elseif 1",
\ " let x = 1",
\ " else",
\ " let x = 2",
\ " endif",
\ "endfunc",
\ "func! Foo3()",
\ " if 0",
\ " let x = 0",
\ " elseif 0",
\ " let x = 1",
\ " else",
\ " let x = 2",
\ " endif",
\ "endfunc",
\ "call Foo1()",
\ "call Foo2()",
\ "call Foo3()",
\ ]
let lines =<< trim [CODE]
func! Foo1()
if 1
let x = 0
elseif 1
let x = 1
else
let x = 2
endif
endfunc
func! Foo2()
if 0
let x = 0
elseif 1
let x = 1
else
let x = 2
endif
endfunc
func! Foo3()
if 0
let x = 0
elseif 0
let x = 1
else
let x = 2
endif
endfunc
call Foo1()
call Foo2()
call Foo3()
[CODE]
call writefile(lines, 'Xprofile_func.vim')
call system(v:progpath
@@ -196,41 +196,41 @@ func Test_profile_func_with_ifelse()
endfunc
func Test_profile_func_with_trycatch()
let lines = [
\ "func! Foo1()",
\ " try",
\ " let x = 0",
\ " catch",
\ " let x = 1",
\ " finally",
\ " let x = 2",
\ " endtry",
\ "endfunc",
\ "func! Foo2()",
\ " try",
\ " throw 0",
\ " catch",
\ " let x = 1",
\ " finally",
\ " let x = 2",
\ " endtry",
\ "endfunc",
\ "func! Foo3()",
\ " try",
\ " throw 0",
\ " catch",
\ " throw 1",
\ " finally",
\ " let x = 2",
\ " endtry",
\ "endfunc",
\ "call Foo1()",
\ "call Foo2()",
\ "try",
\ " call Foo3()",
\ "catch",
\ "endtry",
\ ]
let lines =<< trim [CODE]
func! Foo1()
try
let x = 0
catch
let x = 1
finally
let x = 2
endtry
endfunc
func! Foo2()
try
throw 0
catch
let x = 1
finally
let x = 2
endtry
endfunc
func! Foo3()
try
throw 0
catch
throw 1
finally
let x = 2
endtry
endfunc
call Foo1()
call Foo2()
try
call Foo3()
catch
endtry
[CODE]
call writefile(lines, 'Xprofile_func.vim')
call system(v:progpath
@@ -309,15 +309,15 @@ func Test_profile_func_with_trycatch()
endfunc
func Test_profile_file()
let lines = [
\ 'func! Foo()',
\ 'endfunc',
\ 'for i in range(10)',
\ ' " a comment',
\ ' call Foo()',
\ 'endfor',
\ 'call Foo()',
\ ]
let lines =<< trim [CODE]
func! Foo()
endfunc
for i in range(10)
" a comment
call Foo()
endfor
call Foo()
[CODE]
call writefile(lines, 'Xprofile_file.vim')
call system(v:progpath
@@ -448,26 +448,27 @@ func Test_profile_truncate_mbyte()
endfunc
func Test_profdel_func()
let lines = [
\ 'profile start Xprofile_file.log',
\ 'func! Foo1()',
\ 'endfunc',
\ 'func! Foo2()',
\ 'endfunc',
\ 'func! Foo3()',
\ 'endfunc',
\ '',
\ 'profile func Foo1',
\ 'profile func Foo2',
\ 'call Foo1()',
\ 'call Foo2()',
\ '',
\ 'profile func Foo3',
\ 'profdel func Foo2',
\ 'profdel func Foo3',
\ 'call Foo1()',
\ 'call Foo2()',
\ 'call Foo3()' ]
let lines =<< trim [CODE]
profile start Xprofile_file.log
func! Foo1()
endfunc
func! Foo2()
endfunc
func! Foo3()
endfunc
profile func Foo1
profile func Foo2
call Foo1()
call Foo2()
profile func Foo3
profdel func Foo2
profdel func Foo3
call Foo1()
call Foo2()
call Foo3()
[CODE]
call writefile(lines, 'Xprofile_file.vim')
call system(v:progpath . ' -es --clean -c "so Xprofile_file.vim" -c q')
call assert_equal(0, v:shell_error)
@@ -494,14 +495,15 @@ endfunc
func Test_profdel_star()
" Foo() is invoked once before and once after 'profdel *'.
" So profiling should report it only once.
let lines = [
\ 'profile start Xprofile_file.log',
\ 'func! Foo()',
\ 'endfunc',
\ 'profile func Foo',
\ 'call Foo()',
\ 'profdel *',
\ 'call Foo()' ]
let lines =<< trim [CODE]
profile start Xprofile_file.log
func! Foo()
endfunc
profile func Foo
call Foo()
profdel *
call Foo()
[CODE]
call writefile(lines, 'Xprofile_file.vim')
call system(v:progpath . ' -es --clean -c "so Xprofile_file.vim" -c q')
call assert_equal(0, v:shell_error)

View File

@@ -818,68 +818,68 @@ func Test_efm1()
return
endif
let l = [
\ '"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.',
\ '"Xtestfile", line 6 col 19; this is an error',
\ 'gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c',
\ 'Xtestfile:9: parse error before `asd''',
\ 'make: *** [vim] Error 1',
\ 'in file "Xtestfile" linenr 10: there is an error',
\ '',
\ '2 returned',
\ '"Xtestfile", line 11 col 1; this is an error',
\ '"Xtestfile", line 12 col 2; this is another error',
\ '"Xtestfile", line 14:10; this is an error in column 10',
\ '=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time',
\ '"Xtestfile", linenr 16: yet another problem',
\ 'Error in "Xtestfile" at line 17:',
\ 'x should be a dot',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17',
\ ' ^',
\ 'Error in "Xtestfile" at line 18:',
\ 'x should be a dot',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18',
\ '.............^',
\ 'Error in "Xtestfile" at line 19:',
\ 'x should be a dot',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19',
\ '--------------^',
\ 'Error in "Xtestfile" at line 20:',
\ 'x should be a dot',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20',
\ ' ^',
\ '',
\ 'Does anyone know what is the problem and how to correction it?',
\ '"Xtestfile", line 21 col 9: What is the title of the quickfix window?',
\ '"Xtestfile", line 22 col 9: What is the title of the quickfix window?'
\ ]
let l =<< trim [DATA]
"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
"Xtestfile", line 6 col 19; this is an error
gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
Xtestfile:9: parse error before `asd'
make: *** [vim] Error 1
in file "Xtestfile" linenr 10: there is an error
2 returned
"Xtestfile", line 11 col 1; this is an error
"Xtestfile", line 12 col 2; this is another error
"Xtestfile", line 14:10; this is an error in column 10
=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
"Xtestfile", linenr 16: yet another problem
Error in "Xtestfile" at line 17:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
^
Error in "Xtestfile" at line 18:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
.............^
Error in "Xtestfile" at line 19:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
--------------^
Error in "Xtestfile" at line 20:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
^
Does anyone know what is the problem and how to correction it?
"Xtestfile", line 21 col 9: What is the title of the quickfix window?
"Xtestfile", line 22 col 9: What is the title of the quickfix window?
[DATA]
call writefile(l, 'Xerrorfile1')
call writefile(l[:-2], 'Xerrorfile2')
let m = [
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21',
\ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22'
\ ]
let m =<< trim [DATA]
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
[DATA]
call writefile(m, 'Xtestfile')
let save_efm = &efm
@@ -1092,21 +1092,23 @@ func Test_efm2()
call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
" Test for %P, %Q and %t format specifiers
let lines=["[Xtestfile1]",
\ "(1,17) error: ';' missing",
\ "(21,2) warning: variable 'z' not defined",
\ "(67,3) error: end of file found before string ended",
\ "--",
\ "",
\ "[Xtestfile2]",
\ "--",
\ "",
\ "[Xtestfile3]",
\ "NEW compiler v1.1",
\ "(2,2) warning: variable 'x' not defined",
\ "(67,3) warning: 's' already defined",
\ "--"
\]
let lines =<< trim [DATA]
[Xtestfile1]
(1,17) error: ';' missing
(21,2) warning: variable 'z' not defined
(67,3) error: end of file found before string ended
--
[Xtestfile2]
--
[Xtestfile3]
NEW compiler v1.1
(2,2) warning: variable 'x' not defined
(67,3) warning: 's' already defined
--
[DATA]
set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
" To exercise the push/pop file functionality in quickfix, the test files
" need to be created.
@@ -1128,11 +1130,13 @@ func Test_efm2()
call delete('Xtestfile3')
" Tests for %E, %C and %Z format specifiers
let lines = ["Error 275",
\ "line 42",
\ "column 3",
\ "' ' expected after '--'"
\]
let lines =<< trim [DATA]
Error 275
line 42
column 3
' ' expected after '--'
[DATA]
set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
cgetexpr lines
let l = getqflist()
@@ -1143,9 +1147,11 @@ func Test_efm2()
call assert_equal("\n' ' expected after '--'", l[0].text)
" Test for %>
let lines = ["Error in line 147 of foo.c:",
\"unknown variable 'i'"
\]
let lines =<< trim [DATA]
Error in line 147 of foo.c:
unknown variable 'i'
[DATA]
set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
cgetexpr lines
let l = getqflist()
@@ -1154,21 +1160,22 @@ func Test_efm2()
call assert_equal("\nunknown variable 'i'", l[0].text)
" Test for %A, %C and other formats
let lines = [
\"==============================================================",
\"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)",
\"--------------------------------------------------------------",
\"Traceback (most recent call last):",
\' File "unittests/dbfacadeTest.py", line 89, in testFoo',
\" self.assertEquals(34, dtid)",
\' File "/usr/lib/python2.2/unittest.py", line 286, in',
\" failUnlessEqual",
\" raise self.failureException, \\",
\"AssertionError: 34 != 33",
\"",
\"--------------------------------------------------------------",
\"Ran 27 tests in 0.063s"
\]
let lines =<< trim [DATA]
==============================================================
FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
--------------------------------------------------------------
Traceback (most recent call last):
File "unittests/dbfacadeTest.py", line 89, in testFoo
self.assertEquals(34, dtid)
File "/usr/lib/python2.2/unittest.py", line 286, in
failUnlessEqual
raise self.failureException, \\
AssertionError: 34 != 33
--------------------------------------------------------------
Ran 27 tests in 0.063s
[DATA]
set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
cgetexpr lines
let l = getqflist()

View File

@@ -30,3 +30,243 @@ func Test_scrollbind()
setl noscrollbind
call assert_equal(0, topLineLeft - topLineRight)
endfunc
" Test for 'scrollbind'
func Test_scrollbind_opt()
new | only
set noscrollbind
set scrollopt=ver,jump scrolloff=2 nowrap noequalalways splitbelow
" Insert the text used for the test
append
start of window 1
. line 01 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 01
. line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
. line 03 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 03
. line 04 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 04
. line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05
. line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06
. line 07 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 07
. line 08 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 08
. line 09 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 09
. line 10 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 10
. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
. line 12 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 12
. line 13 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 13
. line 14 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 14
. line 15 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 15
end of window 1
start of window 2
. line 01 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 01
. line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02
. line 03 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 03
. line 04 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 04
. line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05
. line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06
. line 07 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 07
. line 08 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 08
. line 09 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 09
. line 10 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 10
. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12
. line 13 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 13
. line 14 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 14
. line 15 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 15
. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16
end of window 2
.
" Test using two windows open to one buffer, one extra empty window
split
new
wincmd t
resize 8
call search('^start of window 1$')
normal zt
set scrollbind
wincmd j
resize 7
call search('^start of window 2$')
normal zt
set scrollbind
" -- start of tests --
" Test scrolling down
normal L5jHyy
wincmd b | normal pr0
wincmd t | normal Hyy
wincmd b | normal pr1
wincmd t | normal L6jHyy
wincmd b | normal pr2
wincmd k | normal Hyy
wincmd b | normal pr3
" Test scrolling up
wincmd t | normal H4k
wincmd j | normal H
wincmd t | normal Hyy
wincmd b | normal pr4
wincmd k | normal Hyy
wincmd b | normal pr5
wincmd k | normal 3k
wincmd t | normal H
wincmd j | normal Hyy
wincmd b | normal pr6
wincmd t | normal Hyy
wincmd b | normal pr7
" Test horizontal scrolling
set scrollopt+=hor
normal gg"zyyG"zpG
wincmd t | normal 015zly$
wincmd b | normal p"zpG
wincmd k | normal y$
wincmd b | normal p"zpG
wincmd k | normal 10jH7zhg0y$
wincmd b | normal p"zpG
wincmd t | normal Hg0y$
wincmd b | normal p"zpG
set scrollopt-=hor
wincmd b
call assert_equal([
\ '',
\ '0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05',
\ '1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05',
\ '2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11',
\ '3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11',
\ '4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06',
\ '5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06',
\ '6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02',
\ '7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02',
\ '56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02',
\ 'UTSRQPONMLKJIHGREDCBA9876543210 02',
\ '. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11',
\ '. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11',
\ ''], getline(1, '$'))
enew!
" ****** tests using two different buffers *****
wincmd t | wincmd j | close
wincmd t | set noscrollbind
/start of window 2$/,/^end of window 2$/y
new
wincmd t | wincmd j | normal 4"zpGp
wincmd t
call search('^start of window 1$')
normal zt
set scrollbind
wincmd j
call search('^start of window 2$')
normal zt
set scrollbind
" -- start of tests --
" Test scrolling down
normal L5jHyy
wincmd b | normal pr0
wincmd t | normal Hyy
wincmd b | normal pr1
wincmd t | normal L6jHyy
wincmd b | normal pr2
wincmd k | normal Hyy
wincmd b | normal pr3
" Test scrolling up
wincmd t | normal H4k
wincmd j | normal H
wincmd t | normal Hyy
wincmd b | normal pr4
wincmd k | normal Hyy
wincmd b | normal pr5
wincmd k | normal 3k
wincmd t | normal H
wincmd j | normal Hyy
wincmd b | normal pr6
wincmd t | normal Hyy
wincmd b | normal pr7
" Test horizontal scrolling
set scrollopt+=hor
normal gg"zyyG"zpG
wincmd t | normal 015zly$
wincmd b | normal p"zpG
wincmd k | normal y$
wincmd b | normal p"zpG
wincmd k | normal 10jH7zhg0y$
wincmd b | normal p"zpG
wincmd t | normal Hg0y$
wincmd b | normal p"zpG
set scrollopt-=hor
wincmd b
call assert_equal([
\ '',
\ '0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05',
\ '1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05',
\ '2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11',
\ '3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11',
\ '4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06',
\ '5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06',
\ '6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02',
\ '7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02',
\ '56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02',
\ 'UTSRQPONMLKJIHGREDCBA9876543210 02',
\ '. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11',
\ '. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11',
\ ''], getline(1, '$'))
enew!
" Test 'syncbind'
wincmd t | set noscrollbind | normal ggL
wincmd j | set noscrollbind | normal ggL
set scrollbind
wincmd t | set scrollbind | normal G
wincmd j | normal G
syncbind
normal Hk
wincmd t | normal H
wincmd j | normal Hyy
wincmd b | normal p
wincmd t | normal yy
wincmd b | normal p
wincmd t | set noscrollbind | normal ggL
wincmd j | set noscrollbind
normal ggL
set scrollbind
wincmd t | set scrollbind
wincmd t | normal G
wincmd j | normal G
wincmd t | syncbind | normal Hk
wincmd j | normal H
wincmd t | normal Hyy
wincmd b | normal p
wincmd t | wincmd j | normal yy
wincmd b | normal p
wincmd t | normal H3k
wincmd j | normal H
wincmd t | normal Hyy
wincmd b | normal p
wincmd t | wincmd j | normal yy
wincmd b | normal p
wincmd b
call assert_equal([
\ '',
\ '. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16',
\ 'start of window 2',
\ 'start of window 2',
\ '. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16',
\ '. line 15 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 15',
\ '. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12',
\ ], getline(1, '$'))
enew!
new | only!
set scrollbind& scrollopt& scrolloff& wrap& equalalways& splitbelow&
endfunc

View File

@@ -36,3 +36,12 @@ func Test_source_cmd()
au! SourcePre
au! SourcePost
endfunc
func Test_source_sandbox()
new
call writefile(["Ohello\<Esc>"], 'Xsourcehello')
source! Xsourcehello | echo
call assert_equal('hello', getline(1))
call assert_fails('sandbox source! Xsourcehello', 'E48:')
bwipe!
endfunc

View File

@@ -19,25 +19,27 @@ func Test_after_comes_later()
if !has('packages')
return
endif
let before = [
\ 'set nocp viminfo+=nviminfo',
\ 'set guioptions+=M',
\ 'let $HOME = "/does/not/exist"',
\ 'set loadplugins',
\ 'set rtp=Xhere,Xafter,Xanother',
\ 'set packpath=Xhere,Xafter',
\ 'set nomore',
\ 'let g:sequence = ""',
\ ]
let after = [
\ 'redir! > Xtestout',
\ 'scriptnames',
\ 'redir END',
\ 'redir! > Xsequence',
\ 'echo g:sequence',
\ 'redir END',
\ 'quit',
\ ]
let before =<< trim [CODE]
set nocp viminfo+=nviminfo
set guioptions+=M
let $HOME = "/does/not/exist"
set loadplugins
set rtp=Xhere,Xafter,Xanother
set packpath=Xhere,Xafter
set nomore
let g:sequence = ""
[CODE]
let after =<< trim [CODE]
redir! > Xtestout
scriptnames
redir END
redir! > Xsequence
echo g:sequence
redir END
quit
[CODE]
call mkdir('Xhere/plugin', 'p')
call writefile(['let g:sequence .= "here "'], 'Xhere/plugin/here.vim')
call mkdir('Xanother/plugin', 'p')
@@ -76,15 +78,16 @@ func Test_pack_in_rtp_when_plugins_run()
if !has('packages')
return
endif
let before = [
\ 'set nocp viminfo+=nviminfo',
\ 'set guioptions+=M',
\ 'let $HOME = "/does/not/exist"',
\ 'set loadplugins',
\ 'set rtp=Xhere',
\ 'set packpath=Xhere',
\ 'set nomore',
\ ]
let before =<< trim [CODE]
set nocp viminfo+=nviminfo
set guioptions+=M
let $HOME = "/does/not/exist"
set loadplugins
set rtp=Xhere
set packpath=Xhere
set nomore
[CODE]
let after = [
\ 'quit',
\ ]
@@ -131,11 +134,12 @@ func Test_help_arg()
endfunc
func Test_compatible_args()
let after = [
\ 'call writefile([string(&compatible)], "Xtestout")',
\ 'set viminfo+=nviminfo',
\ 'quit',
\ ]
let after =<< trim [CODE]
call writefile([string(&compatible)], "Xtestout")
set viminfo+=nviminfo
quit
[CODE]
if RunVim([], after, '-C')
let lines = readfile('Xtestout')
call assert_equal('1', lines[0])
@@ -152,14 +156,15 @@ endfunc
" Test the -o[N] and -O[N] arguments to open N windows split
" horizontally or vertically.
func Test_o_arg()
let after = [
\ 'call writefile([winnr("$"),
\ winheight(1), winheight(2), &lines,
\ winwidth(1), winwidth(2), &columns,
\ bufname(winbufnr(1)), bufname(winbufnr(2))],
\ "Xtestout")',
\ 'qall',
\ ]
let after =<< trim [CODE]
call writefile([winnr("$"),
\ winheight(1), winheight(2), &lines,
\ winwidth(1), winwidth(2), &columns,
\ bufname(winbufnr(1)), bufname(winbufnr(2))],
\ "Xtestout")
qall
[CODE]
if RunVim([], after, '-o2')
" Open 2 windows split horizontally. Expect:
" - 2 windows
@@ -228,10 +233,11 @@ endfunc
" Test the -p[N] argument to open N tabpages.
func Test_p_arg()
let after = [
\ 'call writefile(split(execute("tabs"), "\n"), "Xtestout")',
\ 'qall',
\ ]
let after =<< trim [CODE]
call writefile(split(execute("tabs"), "\n"), "Xtestout")
qall
[CODE]
if RunVim([], after, '-p2')
let lines = readfile('Xtestout')
call assert_equal(4, len(lines))
@@ -273,12 +279,12 @@ endfunc
" Test the '-q [errorfile]' argument.
func Test_q_arg()
let source_file = has('win32') ? '..\memfile.c' : '../memfile.c'
let after = [
\ 'call writefile([&errorfile, string(getpos("."))], "Xtestout")',
\ 'copen',
\ 'w >> Xtestout',
\ 'qall'
\ ]
let after =<< trim [CODE]
call writefile([&errorfile, string(getpos("."))], "Xtestout")
copen
w >> Xtestout
qall
[CODE]
" Test with default argument '-q'.
call assert_equal('errors.err', &errorfile)
@@ -335,10 +341,11 @@ endfunc
" -M resets 'modifiable' and 'write'
" -R sets 'readonly'
func Test_m_M_R()
let after = [
\ 'call writefile([&write, &modifiable, &readonly, &updatecount], "Xtestout")',
\ 'qall',
\ ]
let after =<< trim [CODE]
call writefile([&write, &modifiable, &readonly, &updatecount], "Xtestout")
qall
[CODE]
if RunVim([], after, '')
let lines = readfile('Xtestout')
call assert_equal(['1', '1', '0', '200'], lines)
@@ -361,10 +368,11 @@ endfunc
" Test the -A, -F and -H arguments (Arabic, Farsi and Hebrew modes).
func Test_A_F_H_arg()
let after = [
\ 'call writefile([&rightleft, &arabic, &fkmap, &hkmap], "Xtestout")',
\ 'qall',
\ ]
let after =<< trim [CODE]
call writefile([&rightleft, &arabic, &fkmap, &hkmap], "Xtestout")
qall
[CODE]
" Use silent Ex mode to avoid the hit-Enter prompt for the warning that
" 'encoding' is not utf-8.
if has('arabic') && &encoding == 'utf-8' && RunVim([], after, '-e -s -A')
@@ -481,10 +489,11 @@ func Test_invalid_args()
endfunc
func Test_file_args()
let after = [
\ 'call writefile(argv(), "Xtestout")',
\ 'qall',
\ ]
let after =<< trim [CODE]
call writefile(argv(), "Xtestout")
qall
[CODE]
if RunVim([], after, '')
let lines = readfile('Xtestout')
call assert_equal(0, len(lines))
@@ -546,10 +555,11 @@ func Test_startuptime()
endfunc
func Test_read_stdin()
let after = [
\ 'write Xtestout',
\ 'quit!',
\ ]
let after =<< trim [CODE]
write Xtestout
quit!
[CODE]
if RunVimPiped([], after, '-', 'echo something | ')
let lines = readfile('Xtestout')
" MS-Windows adds a space after the word
@@ -559,10 +569,11 @@ func Test_read_stdin()
endfunc
func Test_set_shell()
let after = [
\ 'call writefile([&shell], "Xtestout")',
\ 'quit!',
\ ]
let after =<< trim [CODE]
call writefile([&shell], "Xtestout")
quit!
[CODE]
let $SHELL = '/bin/with space/sh'
if RunVimPiped([], after, '', '')
let lines = readfile('Xtestout')
@@ -613,20 +624,22 @@ endfunc
func Test_zzz_startinsert()
" Test :startinsert
call writefile(['123456'], 'Xtestout')
let after = [
\ ':startinsert',
\ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")'
\ ]
let after =<< trim [CODE]
:startinsert
call feedkeys("foobar\<c-o>:wq\<cr>","t")
[CODE]
if RunVim([], after, 'Xtestout')
let lines = readfile('Xtestout')
call assert_equal(['foobar123456'], lines)
endif
" Test :startinsert!
call writefile(['123456'], 'Xtestout')
let after = [
\ ':startinsert!',
\ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")'
\ ]
let after =<< trim [CODE]
:startinsert!
call feedkeys("foobar\<c-o>:wq\<cr>","t")
[CODE]
if RunVim([], after, 'Xtestout')
let lines = readfile('Xtestout')
call assert_equal(['123456foobar'], lines)

View File

@@ -611,9 +611,24 @@ func Test_sub_cmd_8()
set titlestring&
endfunc
func Test_sub_cmd_9()
new
let input = ['1 aaa', '2 aaa', '3 aaa']
call setline(1, input)
func Foo()
return submatch(0)
endfunc
%s/aaa/\=Foo()/gn
call assert_equal(input, getline(1, '$'))
call assert_equal(1, &modifiable)
delfunc Foo
bw!
endfunc
func Test_nocatch_sub_failure_handling()
" normal error results in all replacements
func! Foo()
func Foo()
foobar
endfunc
new
@@ -649,6 +664,7 @@ func Test_nocatch_sub_failure_handling()
call assert_equal(1, error_caught)
call assert_equal(['1 aaa', '2 aaa', '3 aaa'], getline(1, 3))
delfunc Foo
bwipe!
endfunc

View File

@@ -1012,18 +1012,19 @@ endfunc
" Run Vim, start a terminal in that Vim without the kill argument,
" check that :qall does not exit, :qall! does.
func Test_terminal_qall_exit()
let after = [
\ 'term',
\ 'let buf = bufnr("%")',
\ 'while term_getline(buf, 1) =~ "^\\s*$"',
\ ' sleep 10m',
\ 'endwhile',
\ 'set nomore',
\ 'au VimLeavePre * call writefile(["too early"], "Xdone")',
\ 'qall',
\ 'au! VimLeavePre * exe buf . "bwipe!" | call writefile(["done"], "Xdone")',
\ 'cquit',
\ ]
let after =<< trim [CODE]
term
let buf = bufnr("%")
while term_getline(buf, 1) =~ "^\\s*$"
sleep 10m
endwhile
set nomore
au VimLeavePre * call writefile(["too early"], "Xdone")
qall
au! VimLeavePre * exe buf . "bwipe!" | call writefile(["done"], "Xdone")
cquit
[CODE]
if !RunVim([], after, '')
return
endif

View File

@@ -608,6 +608,38 @@ func Test_prop_undo()
let expected[0].length = 2
call assert_equal(expected, prop_list(1))
" substitute a word, then undo
call setline(1, 'the number 123 is highlighted.')
call prop_add(1, 12, {'length': 3, 'type': 'comment'})
let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
call assert_equal(expected, prop_list(1))
set ul&
1s/number/foo
let expected[0].col = 9
call assert_equal(expected, prop_list(1))
undo
let expected[0].col = 12
call assert_equal(expected, prop_list(1))
call prop_clear(1)
" substitute with backslash
call setline(1, 'the number 123 is highlighted.')
call prop_add(1, 12, {'length': 3, 'type': 'comment'})
let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
call assert_equal(expected, prop_list(1))
1s/the/\The
call assert_equal(expected, prop_list(1))
1s/^/\\
let expected[0].col += 1
call assert_equal(expected, prop_list(1))
1s/^/\~
let expected[0].col += 1
call assert_equal(expected, prop_list(1))
1s/123/12\\3
let expected[0].length += 1
call assert_equal(expected, prop_list(1))
call prop_clear(1)
bwipe!
call prop_type_delete('comment')
endfunc

View File

@@ -440,5 +440,14 @@ funct Test_undofile()
" Test undofile() with 'undodir' set to a non-existing directory.
call assert_equal('', undofile('Xundofoo'))
if isdirectory('/tmp')
set undodir=/tmp
if has('osx')
call assert_equal('/tmp/%private%tmp%file', undofile('///tmp/file'))
else
call assert_equal('/tmp/%tmp%file', undofile('///tmp/file'))
endif
endif
set undodir&
endfunc

View File

@@ -95,9 +95,13 @@ func Test_xxd()
%d
exe '0r! ' . s:xxd_cmd . ' -i XXDfile'
$d
let expected = ['unsigned char XXDfile[] = {',
\ ' 0x54, 0x45, 0x53, 0x54, 0x61, 0x62, 0x63, 0x64, 0x30, 0x39, 0x0a', '};',
\ 'unsigned int XXDfile_len = 11;']
let expected =<< trim [CODE]
unsigned char XXDfile[] = {
0x54, 0x45, 0x53, 0x54, 0x61, 0x62, 0x63, 0x64, 0x30, 0x39, 0x0a
};
unsigned int XXDfile_len = 11;
[CODE]
call assert_equal(expected, getline(1,'$'), s:Mess(s:test))
" Test 8: Print C include capitalized
@@ -107,9 +111,12 @@ func Test_xxd()
%d
exe '0r! ' . s:xxd_cmd . ' -i ' . arg . ' XXDfile'
$d
let expected = ['unsigned char XXDFILE[] = {',
\ ' 0x54, 0x45, 0x53, 0x54, 0x61, 0x62, 0x63, 0x64, 0x30, 0x39, 0x0a', '};',
\ 'unsigned int XXDFILE_LEN = 11;']
let expected =<< trim [CODE]
unsigned char XXDFILE[] = {
0x54, 0x45, 0x53, 0x54, 0x61, 0x62, 0x63, 0x64, 0x30, 0x39, 0x0a
};
unsigned int XXDFILE_LEN = 11;
[CODE]
call assert_equal(expected, getline(1,'$'), s:Mess(s:test))
endfor

View File

@@ -957,13 +957,18 @@ clear_buf_prop_types(buf_T *buf)
* shift by "bytes_added" (can be negative).
* Note that "col" is zero-based, while tp_col is one-based.
* Only for the current buffer.
* "flags" can have:
* APC_SAVE_FOR_UNDO: Call u_savesub() before making changes to the line.
* APC_SUBSTITUTE: Text is replaced, not inserted.
* Caller is expected to check b_has_textprop and "bytes_added" being non-zero.
* Returns TRUE when props were changed.
*/
void
int
adjust_prop_columns(
linenr_T lnum,
colnr_T col,
int bytes_added)
int bytes_added,
int flags)
{
int proplen;
char_u *props;
@@ -974,25 +979,40 @@ adjust_prop_columns(
size_t textlen;
if (text_prop_frozen > 0)
return;
return FALSE;
proplen = get_text_props(curbuf, lnum, &props, TRUE);
if (proplen == 0)
return;
return FALSE;
textlen = curbuf->b_ml.ml_line_len - proplen * sizeof(textprop_T);
wi = 0; // write index
for (ri = 0; ri < proplen; ++ri)
{
int start_incl;
mch_memmove(&tmp_prop, props + ri * sizeof(textprop_T),
sizeof(textprop_T));
pt = text_prop_type_by_id(curbuf, tmp_prop.tp_type);
start_incl = (flags & APC_SUBSTITUTE) ||
(pt != NULL && (pt->pt_flags & PT_FLAG_INS_START_INCL));
if (bytes_added > 0
? (tmp_prop.tp_col >= col
+ (pt != NULL && (pt->pt_flags & PT_FLAG_INS_START_INCL)
? 2 : 1))
: (tmp_prop.tp_col > col + 1))
&& (tmp_prop.tp_col >= col + (start_incl ? 2 : 1)))
{
if (tmp_prop.tp_col < col + (start_incl ? 2 : 1))
{
tmp_prop.tp_len += (tmp_prop.tp_col - 1 - col) + bytes_added;
tmp_prop.tp_col = col + 1;
}
else
tmp_prop.tp_col += bytes_added;
// Save for undo if requested and not done yet.
if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
u_savesub(lnum);
dirty = TRUE;
}
else if (bytes_added <= 0 && (tmp_prop.tp_col > col + 1))
{
if (tmp_prop.tp_col + bytes_added < col + 1)
{
@@ -1001,6 +1021,9 @@ adjust_prop_columns(
}
else
tmp_prop.tp_col += bytes_added;
// Save for undo if requested and not done yet.
if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
u_savesub(lnum);
dirty = TRUE;
if (tmp_prop.tp_len <= 0)
continue; // drop this text property
@@ -1016,6 +1039,9 @@ adjust_prop_columns(
tmp_prop.tp_len += bytes_added + after;
else
tmp_prop.tp_len += bytes_added;
// Save for undo if requested and not done yet.
if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
u_savesub(lnum);
dirty = TRUE;
if (tmp_prop.tp_len <= 0)
continue; // drop this text property
@@ -1034,6 +1060,7 @@ adjust_prop_columns(
curbuf->b_ml.ml_flags |= ML_LINE_DIRTY;
curbuf->b_ml.ml_line_len = newlen;
}
return dirty;
}
/*

View File

@@ -1979,6 +1979,7 @@ ex_function(exarg_T *eap)
int indent;
int nesting;
char_u *skip_until = NULL;
char_u *trimmed = NULL;
dictitem_T *v;
funcdict_T fudi;
static int func_nr = 0; /* number for nameless function */
@@ -2303,10 +2304,18 @@ ex_function(exarg_T *eap)
if (skip_until != NULL)
{
/* between ":append" and "." and between ":python <<EOF" and "EOF"
* don't check for ":endfunc". */
if (STRCMP(theline, skip_until) == 0)
VIM_CLEAR(skip_until);
// Between ":append" and "." and between ":python <<EOF" and "EOF"
// don't check for ":endfunc".
if (trimmed == NULL
|| STRNCMP(theline, trimmed, STRLEN(trimmed)) == 0)
{
p = trimmed == NULL ? theline : theline + STRLEN(trimmed);
if (STRCMP(p, skip_until) == 0)
{
VIM_CLEAR(skip_until);
VIM_CLEAR(trimmed);
}
}
}
else
{
@@ -2406,6 +2415,30 @@ ex_function(exarg_T *eap)
else
skip_until = vim_strsave(p);
}
// Check for ":let v =<< [trim] EOF"
arg = skipwhite(skiptowhite(p));
arg = skipwhite(skiptowhite(arg));
if (arg[0] == '=' && arg[1] == '<' && arg[2] =='<'
&& ((p[0] == 'l'
&& p[1] == 'e'
&& (!ASCII_ISALNUM(p[2])
|| (p[2] == 't' && !ASCII_ISALNUM(p[3]))))))
{
// ":let v =<<" continues until a dot
p = skipwhite(arg + 3);
if (STRNCMP(p, "trim", 4) == 0)
{
// Ignore leading white space.
p = skipwhite(p + 4);
trimmed = vim_strnsave(theline,
(int)(skipwhite(theline) - theline));
}
if (*p == NUL)
skip_until = vim_strsave((char_u *)".");
else
skip_until = vim_strnsave(p, (int)(skiptowhite(p) - p));
}
}
/* Add the line to the function. */

View File

@@ -767,6 +767,36 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1365,
/**/
1364,
/**/
1363,
/**/
1362,
/**/
1361,
/**/
1360,
/**/
1359,
/**/
1358,
/**/
1357,
/**/
1356,
/**/
1355,
/**/
1354,
/**/
1353,
/**/
1352,
/**/
1351,
/**/
1350,
/**/

View File

@@ -2571,4 +2571,8 @@ long elapsed(DWORD start_tick);
#define SAVE_RESTORE_ICON 2
#define SAVE_RESTORE_BOTH (SAVE_RESTORE_TITLE | SAVE_RESTORE_ICON)
// Flags for adjust_prop_columns()
#define APC_SAVE_FOR_UNDO 1 // call u_savesub() before making changes
#define APC_SUBSTITUTE 2 // text is replaced, not inserted
#endif /* VIM__H */