Compare commits

...

13 Commits

Author SHA1 Message Date
Bram Moolenaar
2459a5ecaa updated for version 7.4.609
Problem:    For complicated list and dict use the garbage collector can run
            out of stack space.
Solution:   Use a stack of dicts and lists to be marked, thus making it
            iterative instead of recursive. (Ben Fritz)
2015-02-03 12:55:18 +01:00
Bram Moolenaar
4ac163ae5f updated for version 7.4.608
Problem:    test_eval fails when the clipboard feature is missing.
Solution:   Skip part of the test. Reduce the text used.
2015-01-27 22:52:15 +01:00
Bram Moolenaar
73a156bf36 updated for version 7.4.607
Problem:    Compiler warnings for unused variables.
Solution:   Move them inside #ifdef. (Kazunobu Kuriyama)
2015-01-27 21:39:05 +01:00
Bram Moolenaar
7cc8ec4720 updated for version 7.4.606
Problem:    May crash when using a small window.
Solution:   Avoid dividing by zero. (Christian Brabandt)
2015-01-27 20:59:31 +01:00
Bram Moolenaar
3b3a9498d1 updated for version 7.4.605
Problem:    The # register is not writable, it cannot be restored after
            jumping around.
Solution:   Make the # register writable. (Marcin Szamotulski)
2015-01-27 18:44:16 +01:00
Bram Moolenaar
6bf7c523ad updated for version 7.4.604
Problem:    Running tests changes viminfo.
Solution:   Disable viminfo.
2015-01-27 17:12:00 +01:00
Bram Moolenaar
1c93429c48 updated for version 7.4.603
Problem:    'foldcolumn' may be set such that it fills the whole window, not
            leaving space for text.
Solution:   Reduce the foldcolumn width when there is not sufficient room.
            (idea by Christian Brabandt)
2015-01-27 16:39:29 +01:00
Bram Moolenaar
18400e6430 updated for version 7.4.602
Problem:    ":set" does not accept hex numbers as documented.
Solution:   Use vim_str2nr(). (ZyX)
2015-01-27 15:58:40 +01:00
Bram Moolenaar
0a988df731 updated for version 7.4.601
Problem:    It is not possible to have feedkeys() insert characters.
Solution:   Add the 'i' flag.
2015-01-27 15:19:24 +01:00
Bram Moolenaar
0cd040b96a updated for version 7.4.600
Problem:    Memory wasted in struct because of aligning.
Solution:   Split pos in lnum and col. (Dominique Pelle)
2015-01-27 14:54:11 +01:00
Bram Moolenaar
aaf3047de2 updated for version 7.4.599
Problem:    Out-of-memory error.
Solution:   Avoid trying to allocate a negative amount of memory, use size_t
            instead of int. (Dominique Pelle)
2015-01-27 14:40:00 +01:00
Bram Moolenaar
5c27fd100a updated for version 7.4.598
Problem:    ":tabdo windo echo 'hi'" causes "* register not to be changed.
            (Salman Halim)
Solution:   Change how clip_did_set_selection is used and add
            clipboard_needs_update and global_change_count.  (Christian
            Brabandt)
2015-01-27 14:09:37 +01:00
Bram Moolenaar
9a492d456d updated for version 7.4.597
Problem:    Cannot change the result of systemlist().
Solution:   Initialize v_lock. (Yukihiro Nakadaira)
2015-01-27 13:49:31 +01:00
26 changed files with 491 additions and 219 deletions

View File

@@ -1,4 +1,4 @@
*change.txt* For Vim version 7.4. Last change: 2014 Jun 26
*change.txt* For Vim version 7.4. Last change: 2015 Jan 27
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1103,11 +1103,12 @@ There are nine types of registers: *registers* *E354*
2. 10 numbered registers "0 to "9
3. The small delete register "-
4. 26 named registers "a to "z or "A to "Z
5. four read-only registers ":, "., "% and "#
6. the expression register "=
7. The selection and drop registers "*, "+ and "~
8. The black hole register "_
9. Last search pattern register "/
5. three read-only registers ":, "., "%
7. alternate buffer register "#
7. the expression register "=
8. The selection and drop registers "*, "+ and "~
9. The black hole register "_
10. Last search pattern register "/
1. Unnamed register "" *quote_quote* *quotequote*
Vim fills this register with text deleted with the "d", "c", "s", "x" commands
@@ -1153,7 +1154,7 @@ letters to replace their previous contents or as uppercase letters to append
to their previous contents. When the '>' flag is present in 'cpoptions' then
a line break is inserted before the appended text.
5. Read-only registers ":, "., "% and "#
5. Read-only registers ":, ". and "%
These are '%', '#', ':' and '.'. You can use them only with the "p", "P",
and ":put" commands and with CTRL-R. {not in Vi}
*quote_.* *quote.* *E29*
@@ -1164,8 +1165,6 @@ and ":put" commands and with CTRL-R. {not in Vi}
('textwidth' and other options affect what is inserted).
*quote_%* *quote%*
"% Contains the name of the current file.
*quote_#* *quote#*
"# Contains the name of the alternate file.
*quote_:* *quote:* *E30*
": Contains the most recent executed command-line. Example: Use
"@:" to repeat the previous command-line command.
@@ -1174,8 +1173,23 @@ and ":put" commands and with CTRL-R. {not in Vi}
the command was completely from a mapping.
{not available when compiled without the |+cmdline_hist|
feature}
*quote_#* *quote#*
6. Alternate file register "#
Contains the name of the alternate file for the current window. It will
change how the |CTRL-^| command works.
This register is writable, mainly to allow for restoring it after a plugin has
changed it. It accepts buffer number: >
let altbuf = bufnr(@#)
...
let @# = altbuf
It will give error |E86| if you pass buffer number and this buffer does not
exist.
It can also accept a match with an existing buffer name: >
let @# = 'buffer_name'
Error |E93| if there is more than one buffer matching the given name or |E94|
if none of buffers matches the given name.
6. Expression register "= *quote_=* *quote=* *@=*
7. Expression register "= *quote_=* *quote=* *@=*
This is not really a register that stores text, but is a way to use an
expression in commands which use a register. The expression register is
read-only; you cannot put text into it. After the '=', the cursor moves to
@@ -1196,7 +1210,7 @@ If the "= register is used for the "p" command, the String is split up at <NL>
characters. If the String ends in a <NL>, it is regarded as a linewise
register. {not in Vi}
7. Selection and drop registers "*, "+ and "~
8. Selection and drop registers "*, "+ and "~
Use these registers for storing and retrieving the selected text for the GUI.
See |quotestar| and |quoteplus|. When the clipboard is not available or not
working, the unnamed register is used instead. For Unix systems the clipboard
@@ -1218,12 +1232,12 @@ GTK GUI}
Note: The "~ register is only used when dropping plain text onto Vim.
Drag'n'drop of URI lists is handled internally.
8. Black hole register "_ *quote_*
9. Black hole register "_ *quote_*
When writing to this register, nothing happens. This can be used to delete
text without affecting the normal registers. When reading from this register,
nothing is returned. {not in Vi}
9. Last search pattern register "/ *quote_/* *quote/*
10. Last search pattern register "/ *quote_/* *quote/*
Contains the most recent search-pattern. This is used for "n" and 'hlsearch'.
It is writable with `:let`, you can change it to have 'hlsearch' highlight
other matches without actually searching. You can't yank or delete into this

View File

@@ -1,4 +1,4 @@
*eval.txt* For Vim version 7.4. Last change: 2014 Dec 07
*eval.txt* For Vim version 7.4. Last change: 2015 Jan 27
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -2965,9 +2965,12 @@ extend({expr1}, {expr2} [, {expr3}]) *extend()*
feedkeys({string} [, {mode}]) *feedkeys()*
Characters in {string} are queued for processing as if they
come from a mapping or were typed by the user. They are added
to the end of the typeahead buffer, thus if a mapping is still
being executed these characters come after them.
come from a mapping or were typed by the user.
By default the string is added to the end of the typeahead
buffer, thus if a mapping is still being executed the
characters come after them. Use the 'i' flag to insert before
other characters, they will be executed next, before any
characters from a mapping.
The function does not wait for processing of keys contained in
{string}.
To include special keys into {string}, use double-quotes
@@ -2981,6 +2984,7 @@ feedkeys({string} [, {mode}]) *feedkeys()*
't' Handle keys as if typed; otherwise they are handled as
if coming from a mapping. This matters for undo,
opening folds, etc.
'i' Insert the string instead of appending (see above).
Return value is always 0.
filereadable({file}) *filereadable()*

View File

@@ -59,9 +59,7 @@ achieve special effects. These options come in three forms:
:se[t] {option}:{value}
Set string or number option to {value}.
For numeric options the value can be given in decimal,
hex (preceded with 0x) or octal (preceded with '0')
(hex and octal are only available for machines which
have the strtol() function).
hex (preceded with 0x) or octal (preceded with '0').
The old value can be inserted by typing 'wildchar' (by
default this is a <Tab> or CTRL-E if 'compatible' is
set). See |cmdline-completion|.

View File

@@ -1150,7 +1150,7 @@ do_buffer(action, start, dir, count, forceit)
{
/* don't warn when deleting */
if (!unload)
EMSGN(_("E86: Buffer %ld does not exist"), count);
EMSGN(_(e_nobufnr), count);
}
else if (dir == FORWARD)
EMSG(_("E87: Cannot go beyond last buffer"));

View File

@@ -93,7 +93,6 @@ typedef struct lval_S
char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */
} lval_T;
static char *e_letunexp = N_("E18: Unexpected characters in :let");
static char *e_listidx = N_("E684: list index out of range: %ld");
static char *e_undefvar = N_("E121: Undefined variable: %s");
@@ -6007,6 +6006,7 @@ list_free(l, recurse)
/*
* Allocate a list item.
* It is not initialized, don't forget to set v_lock.
*/
listitem_T *
listitem_alloc()
@@ -6810,6 +6810,7 @@ list_join(gap, l, sep, echo_style, copyID)
garbage_collect()
{
int copyID;
int abort = FALSE;
buf_T *buf;
win_T *wp;
int i;
@@ -6840,82 +6841,95 @@ garbage_collect()
* the item is referenced elsewhere the funccal must not be freed. */
for (fc = previous_funccal; fc != NULL; fc = fc->caller)
{
set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1);
set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1);
abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1,
NULL);
abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1,
NULL);
}
/* script-local variables */
for (i = 1; i <= ga_scripts.ga_len; ++i)
set_ref_in_ht(&SCRIPT_VARS(i), copyID);
abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL);
/* buffer-local variables */
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
set_ref_in_item(&buf->b_bufvar.di_tv, copyID);
abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID,
NULL, NULL);
/* window-local variables */
FOR_ALL_TAB_WINDOWS(tp, wp)
set_ref_in_item(&wp->w_winvar.di_tv, copyID);
abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
NULL, NULL);
#ifdef FEAT_AUTOCMD
if (aucmd_win != NULL)
set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID);
abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID,
NULL, NULL);
#endif
#ifdef FEAT_WINDOWS
/* tabpage-local variables */
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
set_ref_in_item(&tp->tp_winvar.di_tv, copyID);
abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID,
NULL, NULL);
#endif
/* global variables */
set_ref_in_ht(&globvarht, copyID);
abort = abort || set_ref_in_ht(&globvarht, copyID, NULL);
/* function-local variables */
for (fc = current_funccal; fc != NULL; fc = fc->caller)
{
set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID);
set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID);
abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL);
abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL);
}
/* v: vars */
set_ref_in_ht(&vimvarht, copyID);
abort = abort || set_ref_in_ht(&vimvarht, copyID, NULL);
#ifdef FEAT_LUA
set_ref_in_lua(copyID);
abort = abort || set_ref_in_lua(copyID);
#endif
#ifdef FEAT_PYTHON
set_ref_in_python(copyID);
abort = abort || set_ref_in_python(copyID);
#endif
#ifdef FEAT_PYTHON3
set_ref_in_python3(copyID);
abort = abort || set_ref_in_python3(copyID);
#endif
/*
* 2. Free lists and dictionaries that are not referenced.
*/
did_free = free_unref_items(copyID);
/*
* 3. Check if any funccal can be freed now.
*/
for (pfc = &previous_funccal; *pfc != NULL; )
if (!abort)
{
if (can_free_funccal(*pfc, copyID))
/*
* 2. Free lists and dictionaries that are not referenced.
*/
did_free = free_unref_items(copyID);
/*
* 3. Check if any funccal can be freed now.
*/
for (pfc = &previous_funccal; *pfc != NULL; )
{
fc = *pfc;
*pfc = fc->caller;
free_funccal(fc, TRUE);
did_free = TRUE;
did_free_funccal = TRUE;
if (can_free_funccal(*pfc, copyID))
{
fc = *pfc;
*pfc = fc->caller;
free_funccal(fc, TRUE);
did_free = TRUE;
did_free_funccal = TRUE;
}
else
pfc = &(*pfc)->caller;
}
else
pfc = &(*pfc)->caller;
if (did_free_funccal)
/* When a funccal was freed some more items might be garbage
* collected, so run again. */
(void)garbage_collect();
}
else if (p_verbose > 0)
{
verb_msg((char_u *)_("Not enough memory to set references, garbage collection aborted!"));
}
if (did_free_funccal)
/* When a funccal was freed some more items might be garbage
* collected, so run again. */
(void)garbage_collect();
return did_free;
}
@@ -6975,48 +6989,112 @@ free_unref_items(copyID)
/*
* Mark all lists and dicts referenced through hashtab "ht" with "copyID".
* "list_stack" is used to add lists to be marked. Can be NULL.
*
* Returns TRUE if setting references failed somehow.
*/
void
set_ref_in_ht(ht, copyID)
hashtab_T *ht;
int copyID;
int
set_ref_in_ht(ht, copyID, list_stack)
hashtab_T *ht;
int copyID;
list_stack_T **list_stack;
{
int todo;
int abort = FALSE;
hashitem_T *hi;
hashtab_T *cur_ht;
ht_stack_T *ht_stack = NULL;
ht_stack_T *tempitem;
todo = (int)ht->ht_used;
for (hi = ht->ht_array; todo > 0; ++hi)
if (!HASHITEM_EMPTY(hi))
cur_ht = ht;
for (;;)
{
if (!abort)
{
--todo;
set_ref_in_item(&HI2DI(hi)->di_tv, copyID);
/* Mark each item in the hashtab. If the item contains a hashtab
* it is added to ht_stack, if it contains a list it is added to
* list_stack. */
todo = (int)cur_ht->ht_used;
for (hi = cur_ht->ht_array; todo > 0; ++hi)
if (!HASHITEM_EMPTY(hi))
{
--todo;
abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID,
&ht_stack, list_stack);
}
}
if (ht_stack == NULL)
break;
/* take an item from the stack */
cur_ht = ht_stack->ht;
tempitem = ht_stack;
ht_stack = ht_stack->prev;
free(tempitem);
}
return abort;
}
/*
* Mark all lists and dicts referenced through list "l" with "copyID".
* "ht_stack" is used to add hashtabs to be marked. Can be NULL.
*
* Returns TRUE if setting references failed somehow.
*/
void
set_ref_in_list(l, copyID)
int
set_ref_in_list(l, copyID, ht_stack)
list_T *l;
int copyID;
ht_stack_T **ht_stack;
{
listitem_T *li;
listitem_T *li;
int abort = FALSE;
list_T *cur_l;
list_stack_T *list_stack = NULL;
list_stack_T *tempitem;
for (li = l->lv_first; li != NULL; li = li->li_next)
set_ref_in_item(&li->li_tv, copyID);
cur_l = l;
for (;;)
{
if (!abort)
/* Mark each item in the list. If the item contains a hashtab
* it is added to ht_stack, if it contains a list it is added to
* list_stack. */
for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next)
abort = abort || set_ref_in_item(&li->li_tv, copyID,
ht_stack, &list_stack);
if (list_stack == NULL)
break;
/* take an item from the stack */
cur_l = list_stack->list;
tempitem = list_stack;
list_stack = list_stack->prev;
free(tempitem);
}
return abort;
}
/*
* Mark all lists and dicts referenced through typval "tv" with "copyID".
* "list_stack" is used to add lists to be marked. Can be NULL.
* "ht_stack" is used to add hashtabs to be marked. Can be NULL.
*
* Returns TRUE if setting references failed somehow.
*/
void
set_ref_in_item(tv, copyID)
typval_T *tv;
int copyID;
int
set_ref_in_item(tv, copyID, ht_stack, list_stack)
typval_T *tv;
int copyID;
ht_stack_T **ht_stack;
list_stack_T **list_stack;
{
dict_T *dd;
list_T *ll;
int abort = FALSE;
switch (tv->v_type)
{
@@ -7026,7 +7104,23 @@ set_ref_in_item(tv, copyID)
{
/* Didn't see this dict yet. */
dd->dv_copyID = copyID;
set_ref_in_ht(&dd->dv_hashtab, copyID);
if (ht_stack == NULL)
{
abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
}
else
{
ht_stack_T *newitem = (ht_stack_T*)malloc(
sizeof(ht_stack_T));
if (newitem == NULL)
abort = TRUE;
else
{
newitem->ht = &dd->dv_hashtab;
newitem->prev = *ht_stack;
*ht_stack = newitem;
}
}
}
break;
@@ -7036,11 +7130,27 @@ set_ref_in_item(tv, copyID)
{
/* Didn't see this list yet. */
ll->lv_copyID = copyID;
set_ref_in_list(ll, copyID);
if (list_stack == NULL)
{
abort = set_ref_in_list(ll, copyID, ht_stack);
}
else
{
list_stack_T *newitem = (list_stack_T*)malloc(
sizeof(list_stack_T));
if (newitem == NULL)
abort = TRUE;
else
{
newitem->list = ll;
newitem->prev = *list_stack;
*list_stack = newitem;
}
}
}
break;
}
return;
return abort;
}
/*
@@ -10499,6 +10609,7 @@ f_feedkeys(argvars, rettv)
typval_T *rettv UNUSED;
{
int remap = TRUE;
int insert = FALSE;
char_u *keys, *flags;
char_u nbuf[NUMBUFLEN];
int typed = FALSE;
@@ -10523,6 +10634,7 @@ f_feedkeys(argvars, rettv)
case 'n': remap = FALSE; break;
case 'm': remap = TRUE; break;
case 't': typed = TRUE; break;
case 'i': insert = TRUE; break;
}
}
}
@@ -10533,7 +10645,7 @@ f_feedkeys(argvars, rettv)
if (keys_esc != NULL)
{
ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE),
typebuf.tb_len, !typed, FALSE);
insert ? 0 : typebuf.tb_len, !typed, FALSE);
vim_free(keys_esc);
if (vgetc_busy)
typebuf_was_filled = TRUE;
@@ -18713,6 +18825,7 @@ get_cmd_output_as_rettv(argvars, rettv, retlist)
goto errret;
}
li->li_tv.v_type = VAR_STRING;
li->li_tv.v_lock = 0;
li->li_tv.vval.v_string = s;
list_append(list, li);
}

View File

@@ -1571,6 +1571,7 @@ EXTERN char_u e_nbreadonly[] INIT(= N_("E744: NetBeans does not allow changes in
EXTERN char_u e_intern2[] INIT(= N_("E685: Internal error: %s"));
EXTERN char_u e_maxmempat[] INIT(= N_("E363: pattern uses more memory than 'maxmempattern'"));
EXTERN char_u e_emptybuf[] INIT(= N_("E749: empty buffer"));
EXTERN char_u e_nobufnr[] INIT(= N_("E86: Buffer %ld does not exist"));
#ifdef FEAT_EX_EXTRA
EXTERN char_u e_invalpat[] INIT(= N_("E682: Invalid search pattern or delimiter"));

View File

@@ -1523,12 +1523,14 @@ luaV_luaeval (lua_State *L)
static int
luaV_setref (lua_State *L)
{
int copyID = lua_tointeger(L, 1);
typval_T tv;
int copyID = lua_tointeger(L, 1);
int abort = FALSE;
typval_T tv;
luaV_getfield(L, LUAVIM_LIST);
luaV_getfield(L, LUAVIM_DICT);
lua_pushnil(L);
while (lua_next(L, lua_upvalueindex(1)) != 0) /* traverse cache table */
while (!abort && lua_next(L, lua_upvalueindex(1)) != 0) /* traverse cache table */
{
lua_getmetatable(L, -1);
if (lua_rawequal(L, -1, 2)) /* list? */
@@ -1542,9 +1544,9 @@ luaV_setref (lua_State *L)
tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */
}
lua_pop(L, 2); /* metatable and value */
set_ref_in_item(&tv, copyID);
abort = set_ref_in_item(&tv, copyID, NULL, NULL);
}
return 0;
lua_pushinteger(L, abort);
}
static int
@@ -1770,13 +1772,23 @@ do_luaeval (char_u *str, typval_T *arg, typval_T *rettv)
lua_call(L, 3, 0);
}
void
int
set_ref_in_lua (int copyID)
{
if (!lua_isopen()) return;
luaV_getfield(L, LUAVIM_SETREF);
lua_pushinteger(L, copyID);
lua_call(L, 1, 0);
int aborted = 0;
if (lua_isopen())
{
luaV_getfield(L, LUAVIM_SETREF);
/* call the function with 1 arg, getting 1 result back */
lua_pushinteger(L, copyID);
lua_call(L, 1, 1);
/* get the result */
aborted = lua_tointeger(L, -1);
/* pop result off the stack */
lua_pop(L, 1);
}
return aborted;
}
#endif

View File

@@ -5502,34 +5502,41 @@ run_eval(const char *cmd, typval_T *rettv
PyErr_Clear();
}
static void
static int
set_ref_in_py(const int copyID)
{
pylinkedlist_T *cur;
dict_T *dd;
list_T *ll;
int abort = FALSE;
if (lastdict != NULL)
for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
{
for(cur = lastdict ; !abort && cur != NULL ; cur = cur->pll_prev)
{
dd = ((DictionaryObject *) (cur->pll_obj))->dict;
if (dd->dv_copyID != copyID)
{
dd->dv_copyID = copyID;
set_ref_in_ht(&dd->dv_hashtab, copyID);
abort = abort || set_ref_in_ht(&dd->dv_hashtab, copyID, NULL);
}
}
}
if (lastlist != NULL)
for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
{
for(cur = lastlist ; !abort && cur != NULL ; cur = cur->pll_prev)
{
ll = ((ListObject *) (cur->pll_obj))->list;
if (ll->lv_copyID != copyID)
{
ll->lv_copyID = copyID;
set_ref_in_list(ll, copyID);
abort = abort || set_ref_in_list(ll, copyID, NULL);
}
}
}
return abort;
}
static int

View File

@@ -1567,8 +1567,8 @@ Py_GetProgramName(void)
}
#endif /* Python 1.4 */
void
int
set_ref_in_python (int copyID)
{
set_ref_in_py(copyID);
return set_ref_in_py(copyID);
}

View File

@@ -1649,8 +1649,8 @@ do_py3eval (char_u *str, typval_T *rettv)
}
}
void
int
set_ref_in_python3 (int copyID)
{
set_ref_in_py(copyID);
int set_ref_in_py(copyID);
}

View File

@@ -959,17 +959,8 @@ vim_main2(int argc UNUSED, char **argv UNUSED)
if (p_im)
need_start_insertmode = TRUE;
#ifdef FEAT_CLIPBOARD
if (clip_unnamed)
/* do not overwrite system clipboard while starting up */
clip_did_set_selection = -1;
#endif
#ifdef FEAT_AUTOCMD
apply_autocmds(EVENT_VIMENTER, NULL, NULL, FALSE, curbuf);
# ifdef FEAT_CLIPBOARD
if (clip_did_set_selection < 0)
clip_did_set_selection = TRUE;
# endif
TIME_MSG("VimEnter autocommands");
#endif

View File

@@ -4457,6 +4457,8 @@ nv_screengo(oap, dir, dist)
col_off2 = col_off1 - curwin_col_off2();
width1 = W_WIDTH(curwin) - col_off1;
width2 = W_WIDTH(curwin) - col_off2;
if (width2 == 0)
width2 = 1; /* avoid divide by zero */
#ifdef FEAT_VERTSPLIT
if (curwin->w_width != 0)

View File

@@ -856,11 +856,12 @@ valid_yank_reg(regname, writing)
if ( (regname > 0 && ASCII_ISALNUM(regname))
|| (!writing && vim_strchr((char_u *)
#ifdef FEAT_EVAL
"/.%#:="
"/.%:="
#else
"/.%#:"
"/.%:"
#endif
, regname) != NULL)
|| regname == '#'
|| regname == '"'
|| regname == '-'
|| regname == '_'
@@ -6514,6 +6515,27 @@ write_reg_contents_ex(name, str, maxlen, must_append, yank_type, block_len)
return;
}
if (name == '#')
{
buf_T *buf;
if (VIM_ISDIGIT(*str))
{
int num = atoi((char *)str);
buf = buflist_findnr(num);
if (buf == NULL)
EMSGN(_(e_nobufnr), (long)num);
}
else
buf = buflist_findnr(buflist_findpat(str, str + STRLEN(str),
TRUE, FALSE, FALSE));
if (buf == NULL)
return;
curwin->w_alt_fnum = buf->b_fnum;
return;
}
#ifdef FEAT_EVAL
if (name == '=')
{

View File

@@ -4540,21 +4540,11 @@ do_set(arg, opt_flags)
goto skip;
}
}
/* allow negative numbers (for 'undolevels') */
else if (*arg == '-' || VIM_ISDIGIT(*arg))
{
i = 0;
if (*arg == '-')
i = 1;
#ifdef HAVE_STRTOL
value = strtol((char *)arg, NULL, 0);
if (arg[i] == '0' && TOLOWER_ASC(arg[i + 1]) == 'x')
i += 2;
#else
value = atol((char *)arg);
#endif
while (VIM_ISDIGIT(arg[i]))
++i;
/* Allow negative (for 'undolevels'), octal and
* hex numbers. */
vim_str2nr(arg, NULL, &i, TRUE, TRUE, &value, NULL);
if (arg[i] != NUL && !vim_iswhite(arg[i]))
{
errmsg = e_invarg;

View File

@@ -62,9 +62,9 @@ int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
void list_insert __ARGS((list_T *l, listitem_T *ni, listitem_T *item));
void vimlist_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
int garbage_collect __ARGS((void));
void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID));
void set_ref_in_list __ARGS((list_T *l, int copyID));
void set_ref_in_item __ARGS((typval_T *tv, int copyID));
int set_ref_in_ht __ARGS((hashtab_T *ht, int copyID, list_stack_T **list_stack));
int set_ref_in_list __ARGS((list_T *l, int copyID, ht_stack_T **ht_stack));
int set_ref_in_item __ARGS((typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack));
dict_T *dict_alloc __ARGS((void));
void dict_unref __ARGS((dict_T *d));
void dict_free __ARGS((dict_T *d, int recurse));

View File

@@ -7,5 +7,5 @@ void ex_luafile __ARGS((exarg_T *eap));
void lua_buffer_free __ARGS((buf_T *buf));
void lua_window_free __ARGS((win_T *win));
void do_luaeval __ARGS((char_u *str, typval_T *arg, typval_T *rettv));
void set_ref_in_lua __ARGS((int copyID));
int set_ref_in_lua __ARGS((int copyID));
/* vim: set ft=c : */

View File

@@ -9,5 +9,5 @@ void python_buffer_free __ARGS((buf_T *buf));
void python_window_free __ARGS((win_T *win));
void python_tabpage_free __ARGS((tabpage_T *tab));
void do_pyeval __ARGS((char_u *str, typval_T *rettv));
void set_ref_in_python __ARGS((int copyID));
int set_ref_in_python __ARGS((int copyID));
/* vim: set ft=c : */

View File

@@ -9,5 +9,5 @@ void python3_buffer_free __ARGS((buf_T *buf));
void python3_window_free __ARGS((win_T *win));
void python3_tabpage_free __ARGS((tabpage_T *tab));
void do_py3eval __ARGS((char_u *str, typval_T *rettv));
void set_ref_in_python3 __ARGS((int copyID));
int set_ref_in_python3 __ARGS((int copyID));
/* vim: set ft=c : */

View File

@@ -1456,7 +1456,7 @@ nfa_regatom()
* matched an unlimited number of times. NFA_NOPEN is
* added only once at a position, while NFA_SPLIT is
* added multiple times. This is more efficient than
* not allowsing NFA_SPLIT multiple times, it is used
* not allowing NFA_SPLIT multiple times, it is used
* a lot. */
EMIT(NFA_NOPEN);
break;
@@ -3726,8 +3726,10 @@ typedef struct
{
struct multipos
{
lpos_T start;
lpos_T end;
linenr_T start_lnum;
linenr_T end_lnum;
colnr_T start_col;
colnr_T end_col;
} multi[NSUBEXP];
struct linepos
{
@@ -3812,10 +3814,10 @@ log_subexpr(sub)
if (REG_MULTI)
fprintf(log_fd, "*** group %d, start: c=%d, l=%d, end: c=%d, l=%d\n",
j,
sub->list.multi[j].start.col,
(int)sub->list.multi[j].start.lnum,
sub->list.multi[j].end.col,
(int)sub->list.multi[j].end.lnum);
sub->list.multi[j].start_col,
(int)sub->list.multi[j].start_lnum,
sub->list.multi[j].end_col,
(int)sub->list.multi[j].end_lnum);
else
{
char *s = (char *)sub->list.line[j].start;
@@ -3952,8 +3954,11 @@ copy_ze_off(to, from)
{
if (REG_MULTI)
{
if (from->list.multi[0].end.lnum >= 0)
to->list.multi[0].end = from->list.multi[0].end;
if (from->list.multi[0].end_lnum >= 0)
{
to->list.multi[0].end_lnum = from->list.multi[0].end_lnum;
to->list.multi[0].end_col = from->list.multi[0].end_col;
}
}
else
{
@@ -3985,33 +3990,33 @@ sub_equal(sub1, sub2)
for (i = 0; i < todo; ++i)
{
if (i < sub1->in_use)
s1 = sub1->list.multi[i].start.lnum;
s1 = sub1->list.multi[i].start_lnum;
else
s1 = -1;
if (i < sub2->in_use)
s2 = sub2->list.multi[i].start.lnum;
s2 = sub2->list.multi[i].start_lnum;
else
s2 = -1;
if (s1 != s2)
return FALSE;
if (s1 != -1 && sub1->list.multi[i].start.col
!= sub2->list.multi[i].start.col)
if (s1 != -1 && sub1->list.multi[i].start_col
!= sub2->list.multi[i].start_col)
return FALSE;
if (nfa_has_backref)
{
if (i < sub1->in_use)
s1 = sub1->list.multi[i].end.lnum;
s1 = sub1->list.multi[i].end_lnum;
else
s1 = -1;
if (i < sub2->in_use)
s2 = sub2->list.multi[i].end.lnum;
s2 = sub2->list.multi[i].end_lnum;
else
s2 = -1;
if (s1 != s2)
return FALSE;
if (s1 != -1 && sub1->list.multi[i].end.col
!= sub2->list.multi[i].end.col)
if (s1 != -1 && sub1->list.multi[i].end_col
!= sub2->list.multi[i].end_col)
return FALSE;
}
}
@@ -4062,7 +4067,7 @@ report_state(char *action,
if (sub->in_use <= 0)
col = -1;
else if (REG_MULTI)
col = sub->list.multi[0].start.col;
col = sub->list.multi[0].start_col;
else
col = (int)(sub->list.line[0].start - regline);
nfa_set_code(state->c);
@@ -4482,7 +4487,8 @@ skip_add:
{
if (subidx < sub->in_use)
{
save_lpos = sub->list.multi[subidx].start;
save_lpos.lnum = sub->list.multi[subidx].start_lnum;
save_lpos.col = sub->list.multi[subidx].start_col;
save_in_use = -1;
}
else
@@ -4490,20 +4496,20 @@ skip_add:
save_in_use = sub->in_use;
for (i = sub->in_use; i < subidx; ++i)
{
sub->list.multi[i].start.lnum = -1;
sub->list.multi[i].end.lnum = -1;
sub->list.multi[i].start_lnum = -1;
sub->list.multi[i].end_lnum = -1;
}
sub->in_use = subidx + 1;
}
if (off == -1)
{
sub->list.multi[subidx].start.lnum = reglnum + 1;
sub->list.multi[subidx].start.col = 0;
sub->list.multi[subidx].start_lnum = reglnum + 1;
sub->list.multi[subidx].start_col = 0;
}
else
{
sub->list.multi[subidx].start.lnum = reglnum;
sub->list.multi[subidx].start.col =
sub->list.multi[subidx].start_lnum = reglnum;
sub->list.multi[subidx].start_col =
(colnr_T)(reginput - regline + off);
}
}
@@ -4539,7 +4545,10 @@ skip_add:
if (save_in_use == -1)
{
if (REG_MULTI)
sub->list.multi[subidx].start = save_lpos;
{
sub->list.multi[subidx].start_lnum = save_lpos.lnum;
sub->list.multi[subidx].start_col = save_lpos.col;
}
else
sub->list.line[subidx].start = save_ptr;
}
@@ -4549,7 +4558,7 @@ skip_add:
case NFA_MCLOSE:
if (nfa_has_zend && (REG_MULTI
? subs->norm.list.multi[0].end.lnum >= 0
? subs->norm.list.multi[0].end_lnum >= 0
: subs->norm.list.line[0].end != NULL))
{
/* Do not overwrite the position set by \ze. */
@@ -4603,16 +4612,17 @@ skip_add:
sub->in_use = subidx + 1;
if (REG_MULTI)
{
save_lpos = sub->list.multi[subidx].end;
save_lpos.lnum = sub->list.multi[subidx].end_lnum;
save_lpos.col = sub->list.multi[subidx].end_col;
if (off == -1)
{
sub->list.multi[subidx].end.lnum = reglnum + 1;
sub->list.multi[subidx].end.col = 0;
sub->list.multi[subidx].end_lnum = reglnum + 1;
sub->list.multi[subidx].end_col = 0;
}
else
{
sub->list.multi[subidx].end.lnum = reglnum;
sub->list.multi[subidx].end.col =
sub->list.multi[subidx].end_lnum = reglnum;
sub->list.multi[subidx].end_col =
(colnr_T)(reginput - regline + off);
}
/* avoid compiler warnings */
@@ -4637,7 +4647,10 @@ skip_add:
sub = &subs->norm;
if (REG_MULTI)
sub->list.multi[subidx].end = save_lpos;
{
sub->list.multi[subidx].end_lnum = save_lpos.lnum;
sub->list.multi[subidx].end_col = save_lpos.col;
}
else
sub->list.line[subidx].end = save_ptr;
sub->in_use = save_in_use;
@@ -4825,15 +4838,15 @@ retempty:
if (REG_MULTI)
{
if (sub->list.multi[subidx].start.lnum < 0
|| sub->list.multi[subidx].end.lnum < 0)
if (sub->list.multi[subidx].start_lnum < 0
|| sub->list.multi[subidx].end_lnum < 0)
goto retempty;
if (sub->list.multi[subidx].start.lnum == reglnum
&& sub->list.multi[subidx].end.lnum == reglnum)
if (sub->list.multi[subidx].start_lnum == reglnum
&& sub->list.multi[subidx].end_lnum == reglnum)
{
len = sub->list.multi[subidx].end.col
- sub->list.multi[subidx].start.col;
if (cstrncmp(regline + sub->list.multi[subidx].start.col,
len = sub->list.multi[subidx].end_col
- sub->list.multi[subidx].start_col;
if (cstrncmp(regline + sub->list.multi[subidx].start_col,
reginput, &len) == 0)
{
*bytelen = len;
@@ -4843,10 +4856,10 @@ retempty:
else
{
if (match_with_backref(
sub->list.multi[subidx].start.lnum,
sub->list.multi[subidx].start.col,
sub->list.multi[subidx].end.lnum,
sub->list.multi[subidx].end.col,
sub->list.multi[subidx].start_lnum,
sub->list.multi[subidx].start_col,
sub->list.multi[subidx].end_lnum,
sub->list.multi[subidx].end_col,
bytelen) == RA_MATCH)
return TRUE;
}
@@ -5408,7 +5421,7 @@ nfa_regmatch(prog, start, submatch, m)
regsubs_T *m;
{
int result;
int size = 0;
size_t size = 0;
int flag = 0;
int go_to_nextline = FALSE;
nfa_thread_T *t;
@@ -5441,6 +5454,7 @@ nfa_regmatch(prog, start, submatch, m)
/* Allocate memory for the lists of nodes. */
size = (nstate + 1) * sizeof(nfa_thread_T);
list[0].t = (nfa_thread_T *)lalloc(size, TRUE);
list[0].len = nstate + 1;
list[1].t = (nfa_thread_T *)lalloc(size, TRUE);
@@ -5482,8 +5496,8 @@ nfa_regmatch(prog, start, submatch, m)
{
if (REG_MULTI)
{
m->norm.list.multi[0].start.lnum = reglnum;
m->norm.list.multi[0].start.col = (colnr_T)(reginput - regline);
m->norm.list.multi[0].start_lnum = reglnum;
m->norm.list.multi[0].start_col = (colnr_T)(reginput - regline);
}
else
m->norm.list.line[0].start = reginput;
@@ -5580,7 +5594,7 @@ nfa_regmatch(prog, start, submatch, m)
if (t->subs.norm.in_use <= 0)
col = -1;
else if (REG_MULTI)
col = t->subs.norm.list.multi[0].start.col;
col = t->subs.norm.list.multi[0].start_col;
else
col = (int)(t->subs.norm.list.line[0].start - regline);
nfa_set_code(t->state->c);
@@ -5861,7 +5875,7 @@ nfa_regmatch(prog, start, submatch, m)
* continue with what follows. */
if (REG_MULTI)
/* TODO: multi-line match */
bytelen = m->norm.list.multi[0].end.col
bytelen = m->norm.list.multi[0].end_col
- (int)(reginput - regline);
else
bytelen = (int)(m->norm.list.line[0].end - reginput);
@@ -6741,7 +6755,7 @@ nfa_regmatch(prog, start, submatch, m)
if (add)
{
if (REG_MULTI)
m->norm.list.multi[0].start.col =
m->norm.list.multi[0].start_col =
(colnr_T)(reginput - regline) + clen;
else
m->norm.list.line[0].start = reginput + clen;
@@ -6854,8 +6868,11 @@ nfa_regtry(prog, col)
{
for (i = 0; i < subs.norm.in_use; i++)
{
reg_startpos[i] = subs.norm.list.multi[i].start;
reg_endpos[i] = subs.norm.list.multi[i].end;
reg_startpos[i].lnum = subs.norm.list.multi[i].start_lnum;
reg_startpos[i].col = subs.norm.list.multi[i].start_col;
reg_endpos[i].lnum = subs.norm.list.multi[i].end_lnum;
reg_endpos[i].col = subs.norm.list.multi[i].end_col;
}
if (reg_startpos[0].lnum < 0)
@@ -6903,13 +6920,13 @@ nfa_regtry(prog, col)
struct multipos *mpos = &subs.synt.list.multi[i];
/* Only accept single line matches that are valid. */
if (mpos->start.lnum >= 0
&& mpos->start.lnum == mpos->end.lnum
&& mpos->end.col >= mpos->start.col)
if (mpos->start_lnum >= 0
&& mpos->start_lnum == mpos->end_lnum
&& mpos->end_col >= mpos->start_col)
re_extmatch_out->matches[i] =
vim_strnsave(reg_getline(mpos->start.lnum)
+ mpos->start.col,
mpos->end.col - mpos->start.col);
vim_strnsave(reg_getline(mpos->start_lnum)
+ mpos->start_col,
mpos->end_col - mpos->start_col);
}
else
{

View File

@@ -109,6 +109,7 @@ static match_T search_hl; /* used for 'hlsearch' highlight matching */
#ifdef FEAT_FOLDING
static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */
static int compute_foldcolumn __ARGS((win_T *wp, int col));
#endif
/*
@@ -1202,7 +1203,7 @@ win_update(wp)
lnumb = wp->w_lines[i].wl_lnum;
/* When there is a fold column it might need updating
* in the next line ("J" just above an open fold). */
if (wp->w_p_fdc > 0)
if (compute_foldcolumn(wp, 0) > 0)
++lnumb;
}
}
@@ -2238,13 +2239,16 @@ win_draw_end(wp, c1, c2, row, endrow, hl)
#else
# define FDC_OFF 0
#endif
#ifdef FEAT_FOLDING
int fdc = compute_foldcolumn(wp, 0);
#endif
#ifdef FEAT_RIGHTLEFT
if (wp->w_p_rl)
{
/* No check for cmdline window: should never be right-left. */
# ifdef FEAT_FOLDING
n = wp->w_p_fdc;
n = fdc;
if (n > 0)
{
@@ -2293,9 +2297,9 @@ win_draw_end(wp, c1, c2, row, endrow, hl)
}
#endif
#ifdef FEAT_FOLDING
if (wp->w_p_fdc > 0)
if (fdc > 0)
{
int nn = n + wp->w_p_fdc;
int nn = n + fdc;
/* draw the fold column at the left */
if (nn > W_WIDTH(wp))
@@ -2345,6 +2349,24 @@ advance_color_col(vcol, color_cols)
#endif
#ifdef FEAT_FOLDING
/*
* Compute the width of the foldcolumn. Based on 'foldcolumn' and how much
* space is available for window "wp", minus "col".
*/
static int
compute_foldcolumn(wp, col)
win_T *wp;
int col;
{
int fdc = wp->w_p_fdc;
int wmw = wp == curwin && p_wmw == 0 ? 1 : p_wmw;
int wwidth = W_WIDTH(wp);
if (fdc > wwidth - (col + wmw))
fdc = wwidth - (col + wmw);
return fdc;
}
/*
* Display one folded line.
*/
@@ -2396,10 +2418,9 @@ fold_line(wp, fold_count, foldinfo, lnum, row)
/*
* 2. Add the 'foldcolumn'
* Reduce the width when there is not enough space.
*/
fdc = wp->w_p_fdc;
if (fdc > W_WIDTH(wp) - col)
fdc = W_WIDTH(wp) - col;
fdc = compute_foldcolumn(wp, col);
if (fdc > 0)
{
fill_foldcolumn(buf, wp, TRUE, lnum);
@@ -2787,23 +2808,24 @@ fill_foldcolumn(p, wp, closed, lnum)
int level;
int first_level;
int empty;
int fdc = compute_foldcolumn(wp, 0);
/* Init to all spaces. */
copy_spaces(p, (size_t)wp->w_p_fdc);
copy_spaces(p, (size_t)fdc);
level = win_foldinfo.fi_level;
if (level > 0)
{
/* If there is only one column put more info in it. */
empty = (wp->w_p_fdc == 1) ? 0 : 1;
empty = (fdc == 1) ? 0 : 1;
/* If the column is too narrow, we start at the lowest level that
* fits and use numbers to indicated the depth. */
first_level = level - wp->w_p_fdc - closed + 1 + empty;
first_level = level - fdc - closed + 1 + empty;
if (first_level < 1)
first_level = 1;
for (i = 0; i + empty < wp->w_p_fdc; ++i)
for (i = 0; i + empty < fdc; ++i)
{
if (win_foldinfo.fi_lnum == lnum
&& first_level + i >= win_foldinfo.fi_low_level)
@@ -2819,7 +2841,7 @@ fill_foldcolumn(p, wp, closed, lnum)
}
}
if (closed)
p[i >= wp->w_p_fdc ? i - 1 : i] = '+';
p[i >= fdc ? i - 1 : i] = '+';
}
#endif /* FEAT_FOLDING */
@@ -3556,12 +3578,14 @@ win_line(wp, lnum, startrow, endrow, nochange)
#ifdef FEAT_FOLDING
if (draw_state == WL_FOLD - 1 && n_extra == 0)
{
int fdc = compute_foldcolumn(wp, 0);
draw_state = WL_FOLD;
if (wp->w_p_fdc > 0)
if (fdc > 0)
{
/* Draw the 'foldcolumn'. */
fill_foldcolumn(extra, wp, FALSE, lnum);
n_extra = wp->w_p_fdc;
n_extra = fdc;
p_extra = extra;
p_extra[n_extra] = NUL;
c_extra = NUL;

View File

@@ -1223,6 +1223,20 @@ struct dictvar_S
dict_T *dv_used_prev; /* previous dict in used dicts list */
};
/* structure used for explicit stack while garbage collecting hash tables */
typedef struct ht_stack_S
{
hashtab_T *ht;
struct ht_stack_S *prev;
} ht_stack_T;
/* structure used for explicit stack while garbage collecting lists */
typedef struct list_stack_S
{
list_T *list;
struct list_stack_S *prev;
} list_stack_T;
/* values for b_syn_spell: what to do with toplevel text */
#define SYNSPL_DEFAULT 0 /* spell check if @Spell not defined */
#define SYNSPL_TOP 1 /* spell check toplevel text */

View File

@@ -100,7 +100,7 @@ fygjyl:let line2 = @0
:$put =line2
:"
:let g:test="Test 14: breakindent + visual blockwise delete #1"
:set all& breakindent
:set all& breakindent viminfo+=nviminfo
:30vnew
:normal! 3a1234567890
:normal! a abcde

View File

@@ -1,7 +1,9 @@
Test for various eval features. vim: set ft=vim :
Note: system clipboard support is not tested. I do not think anybody will thank
me for messing with clipboard.
Note: system clipboard is saved, changed and restored.
clipboard contents
something else
STARTTEST
:so small.vim
@@ -9,7 +11,10 @@ STARTTEST
:set noswapfile
:lang C
:fun AppendRegContents(reg)
call append('$', printf('%s: type %s; value: %s (%s), expr: %s (%s)', a:reg, getregtype(a:reg), getreg(a:reg), string(getreg(a:reg, 0, 1)), getreg(a:reg, 1), string(getreg(a:reg, 1, 1))))
call AppendRegParts(a:reg, getregtype(a:reg), getreg(a:reg), string(getreg(a:reg, 0, 1)), getreg(a:reg, 1), string(getreg(a:reg, 1, 1)))
:endfun
:fun AppendRegParts(reg, type, cont, strcont, cont1, strcont1)
call append('$', printf('%s: type %s; value: %s (%s), expr: %s (%s)', a:reg, a:type, a:cont, a:strcont, a:cont1, a:strcont1))
endfun
:command -nargs=? AR :call AppendRegContents(<q-args>)
:fun SetReg(...)
@@ -122,7 +127,24 @@ call SetReg('/', ['abc/'])
call SetReg('/', ["abc/\n"])
call SetReg('=', ['"abc/"'])
call SetReg('=', ["\"abc/\n\""])
$put ='{{{1 System clipboard'
if has('clipboard')
" Save and restore system clipboard.
" If no connection to X-Server is possible, test should succeed.
let _clipreg = ['+', getreg('+'), getregtype('+')]
let _clipopt = &cb
let &cb='unnamedplus'
5y
AR +
tabdo :windo :echo "hi"
6y
AR +
let &cb=_clipopt
call call('setreg', _clipreg)
else
call AppendRegParts('+', 'V', "clipboard contents\n", "['clipboard contents']", "clipboard contents\n", "['clipboard contents']")
call AppendRegParts('+', 'V', "something else\n", "['something else']", "something else\n", "['something else']")
endif
$put ='{{{1 Errors'
call ErrExe('call setreg()')
call ErrExe('call setreg(1)')

Binary file not shown.

View File

@@ -562,6 +562,8 @@ clip_copy_selection(clip)
* prevents accessing the clipboard very often which might slow down Vim
* considerably.
*/
static int global_change_count = 0; /* if set, inside a start_global_changes */
static int clipboard_needs_update; /* clipboard needs to be updated */
/*
* Save clip_unnamed and reset it.
@@ -569,9 +571,12 @@ clip_copy_selection(clip)
void
start_global_changes()
{
if (++global_change_count > 1)
return;
clip_unnamed_saved = clip_unnamed;
clipboard_needs_update = FALSE;
if (clip_did_set_selection > 0)
if (clip_did_set_selection)
{
clip_unnamed = FALSE;
clip_did_set_selection = FALSE;
@@ -584,22 +589,30 @@ start_global_changes()
void
end_global_changes()
{
if (clip_did_set_selection == FALSE) /* not when -1 */
if (--global_change_count > 0)
/* recursive */
return;
if (!clip_did_set_selection)
{
clip_did_set_selection = TRUE;
clip_unnamed = clip_unnamed_saved;
if (clip_unnamed & CLIP_UNNAMED)
clip_unnamed_saved = FALSE;
if (clipboard_needs_update)
{
clip_own_selection(&clip_star);
clip_gen_set_selection(&clip_star);
}
if (clip_unnamed & CLIP_UNNAMED_PLUS)
{
clip_own_selection(&clip_plus);
clip_gen_set_selection(&clip_plus);
/* only store something in the clipboard,
* if we have yanked anything to it */
if (clip_unnamed & CLIP_UNNAMED)
{
clip_own_selection(&clip_star);
clip_gen_set_selection(&clip_star);
}
if (clip_unnamed & CLIP_UNNAMED_PLUS)
{
clip_own_selection(&clip_plus);
clip_gen_set_selection(&clip_plus);
}
}
}
clip_unnamed_saved = FALSE;
}
/*
@@ -1477,10 +1490,12 @@ clip_gen_set_selection(cbd)
{
/* Updating postponed, so that accessing the system clipboard won't
* hang Vim when accessing it many times (e.g. on a :g comand). */
if (cbd == &clip_plus && (clip_unnamed_saved & CLIP_UNNAMED_PLUS))
return;
else if (cbd == &clip_star && (clip_unnamed_saved & CLIP_UNNAMED))
if ((cbd == &clip_plus && (clip_unnamed_saved & CLIP_UNNAMED_PLUS))
|| (cbd == &clip_star && (clip_unnamed_saved & CLIP_UNNAMED)))
{
clipboard_needs_update = TRUE;
return;
}
}
#ifdef FEAT_XCLIPBOARD
# ifdef FEAT_GUI

View File

@@ -741,6 +741,32 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
609,
/**/
608,
/**/
607,
/**/
606,
/**/
605,
/**/
604,
/**/
603,
/**/
602,
/**/
601,
/**/
600,
/**/
599,
/**/
598,
/**/
597,
/**/
596,
/**/