Compare commits

...

6 Commits

Author SHA1 Message Date
Bram Moolenaar
6f361c9912 patch 8.0.1446: acessing freed memory after window command in auto command
Problem:    Acessing freed memory after window command in auto command.
            (gy741)
Solution:   Adjust the pointer in the parent frame. (Christian Brabandt,
            closes #2467)
2018-01-31 19:06:50 +01:00
Bram Moolenaar
153b704e20 patch 8.0.1445: cannot act on edits in the command line
Problem:    Cannot act on edits in the command line.
Solution:   Add the CmdlineChanged autocommand event. (xtal8, closes #2603,
            closes #2524)
2018-01-31 15:48:32 +01:00
Bram Moolenaar
ec0557f08b patch 8.0.1444: missing -D_FILE_OFFSET_BITS=64 may cause problems
Problem:    Missing -D_FILE_OFFSET_BITS=64 may cause problems if a library is
            compiled with it.
Solution:   Include -D_FILE_OFFSET_BITS if some CFLAGS has it. (James McCoy,
            closes #2600)
2018-01-31 14:41:37 +01:00
Bram Moolenaar
059fd01021 patch 8.0.1443: compiler complains about uninitialized variable
Problem:    Compiler complains about uninitialized variable. (Tony Mechelynck)
Solution:   Assign a value to the variable.
2018-01-31 14:25:53 +01:00
Bram Moolenaar
a172b63ab8 patch 8.0.1442: using pointer before it is set
Problem:    Using pointer before it is set.
Solution:   Search in whole buffer instead of next token.
2018-01-30 22:52:06 +01:00
Bram Moolenaar
ce46d934af patch 8.0.1441: using ":undo 0" leaves undo in wrong state
Problem:    Using ":undo 0" leaves undo in wrong state.
Solution:   Instead of searching for state 1 and go above, just use the start.
            (Ozaki Kiichi, closes #2595)
2018-01-30 22:46:06 +01:00
13 changed files with 209 additions and 75 deletions

View File

@@ -1,4 +1,4 @@
*autocmd.txt* For Vim version 8.0. Last change: 2017 Dec 17
*autocmd.txt* For Vim version 8.0. Last change: 2018 Jan 31
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -500,6 +500,13 @@ CmdUndefined When a user command is used but it isn't
command is defined. An alternative is to
always define the user command and have it
invoke an autoloaded function. See |autoload|.
*CmdlineChanged*
CmdlineChanged After a change was made to the text inside
command line. Be careful not to mess up the
command line, it may cause Vim to lock up.
<afile> is set to a single character,
indicating the type of command-line.
|cmdwin-char|
*CmdlineEnter*
CmdlineEnter After moving the cursor to the command line,
where the user can type a command or search

12
src/auto/configure vendored
View File

@@ -14314,6 +14314,18 @@ $as_echo "no" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need to force -D_FILE_OFFSET_BITS=64" >&5
$as_echo_n "checking whether we need to force -D_FILE_OFFSET_BITS=64... " >&6; }
if echo "$CFLAGS $LUA_CFLAGS $MZSCHEME_CFLAGS $PERL_CFLAGS $PYTHON_GETPATH_CFLAGS $PYTHON_CFLAGS $PYTHON3_CFLAGS $TCL_CFLAGS $RUBY_CFLAGS $GTK_CFLAGS" | grep -q D_FILE_OFFSET_BITS 2>/dev/null; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define _FILE_OFFSET_BITS 64" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker --as-needed support" >&5
$as_echo_n "checking linker --as-needed support... " >&6; }
LINK_AS_NEEDED=

View File

@@ -4366,6 +4366,20 @@ if test "$GCC" = yes; then
fi
AC_SUBST(DEPEND_CFLAGS_FILTER)
dnl On some systems AC_SYS_LARGEFILE determines that -D_FILE_OFFSET_BITS=64
dnl isn't required, but the CFLAGS for some of the libraries we're using
dnl include the define. Since the define changes the size of some datatypes
dnl (e.g. ino_t and off_t), all of Vim's modules must be compiled with a
dnl consistent value. It's therefore safest to force the use of the define
dnl if it's present in any of the *_CFLAGS variables.
AC_MSG_CHECKING(whether we need to force -D_FILE_OFFSET_BITS=64)
if echo "$CFLAGS $LUA_CFLAGS $MZSCHEME_CFLAGS $PERL_CFLAGS $PYTHON_GETPATH_CFLAGS $PYTHON_CFLAGS $PYTHON3_CFLAGS $TCL_CFLAGS $RUBY_CFLAGS $GTK_CFLAGS" | grep -q D_FILE_OFFSET_BITS 2>/dev/null; then
AC_MSG_RESULT(yes)
AC_DEFINE(_FILE_OFFSET_BITS, 64)
else
AC_MSG_RESULT(no)
fi
dnl link.sh tries to avoid overlinking in a hackish way.
dnl At least GNU ld supports --as-needed which provides the same functionality
dnl at linker level. Let's use it.

View File

@@ -1951,6 +1951,11 @@ cmdline_not_changed:
#endif
cmdline_changed:
#ifdef FEAT_AUTOCMD
/* Trigger CmdlineChanged autocommands. */
trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED);
#endif
#ifdef FEAT_SEARCH_EXTRA
/*
* 'incsearch' highlighting.

View File

@@ -7786,6 +7786,7 @@ static struct event_name
{"BufWritePost", EVENT_BUFWRITEPOST},
{"BufWritePre", EVENT_BUFWRITEPRE},
{"BufWriteCmd", EVENT_BUFWRITECMD},
{"CmdlineChanged", EVENT_CMDLINECHANGED},
{"CmdlineEnter", EVENT_CMDLINEENTER},
{"CmdlineLeave", EVENT_CMDLINELEAVE},
{"CmdwinEnter", EVENT_CMDWINENTER},

View File

@@ -702,7 +702,7 @@ cs_cnt_matches(int idx)
* Accept "\S*cscope: X lines", also matches "mlcscope".
* Bail out for the "Unable to search" error.
*/
if (strstr((const char *)stok, "Unable to search database") != NULL)
if (strstr((const char *)buf, "Unable to search database") != NULL)
break;
if ((stok = strtok(buf, (const char *)" ")) == NULL)
continue;

View File

@@ -812,6 +812,18 @@ func Test_QuitPre()
endfunc
func Test_Cmdline()
au! CmdlineChanged : let g:text = getcmdline()
let g:text = 0
call feedkeys(":echom 'hello'\<CR>", 'xt')
call assert_equal("echom 'hello'", g:text)
au! CmdlineChanged
au! CmdlineChanged : let g:entered = expand('<afile>')
let g:entered = 0
call feedkeys(":echom 'hello'\<CR>", 'xt')
call assert_equal(':', g:entered)
au! CmdlineChanged
au! CmdlineEnter : let g:entered = expand('<afile>')
au! CmdlineLeave : let g:left = expand('<afile>')
let g:entered = 0

View File

@@ -359,3 +359,47 @@ func Test_undo_append()
norm o
quit
endfunc
func Test_undo_0()
new
set ul=100
normal i1
undo
normal i2
undo
normal i3
undo 0
let d = undotree()
call assert_equal('', getline(1))
call assert_equal(0, d.seq_cur)
redo
let d = undotree()
call assert_equal('3', getline(1))
call assert_equal(3, d.seq_cur)
undo 2
undo 0
let d = undotree()
call assert_equal('', getline(1))
call assert_equal(0, d.seq_cur)
redo
let d = undotree()
call assert_equal('2', getline(1))
call assert_equal(2, d.seq_cur)
undo 1
undo 0
let d = undotree()
call assert_equal('', getline(1))
call assert_equal(0, d.seq_cur)
redo
let d = undotree()
call assert_equal('1', getline(1))
call assert_equal(1, d.seq_cur)
bwipe!
endfunc

View File

@@ -472,4 +472,15 @@ func Test_window_colon_command()
exe "norm! v\<C-W>:\<C-U>echo v:version"
endfunc
func Test_access_freed_mem()
" This was accessing freed memory
au * 0 vs xxx
arg 0
argadd
all
all
au!
bwipe xxx
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -2272,7 +2272,7 @@ undo_time(
long closest_start;
long closest_seq = 0;
long val;
u_header_T *uhp;
u_header_T *uhp = NULL;
u_header_T *last;
int mark;
int nomark;
@@ -2295,14 +2295,7 @@ undo_time(
* Init "closest" to a value we can't reach. */
if (absolute)
{
if (step == 0)
{
/* target 0 does not exist, got to 1 and above it. */
target = 1;
above = TRUE;
}
else
target = step;
target = step;
closest = -1;
}
else
@@ -2369,6 +2362,13 @@ undo_time(
closest_start = closest;
closest_seq = curbuf->b_u_seq_cur;
/* When "target" is 0; Back to origin. */
if (target == 0)
{
mark = lastmark; /* avoid that GCC complains */
goto target_zero;
}
/*
* May do this twice:
* 1. Search for "target", update "closest" to the best match found.
@@ -2494,8 +2494,9 @@ undo_time(
above = TRUE; /* stop above the header */
}
target_zero:
/* If we found it: Follow the path to go to where we want to be. */
if (uhp != NULL)
if (uhp != NULL || target == 0)
{
/*
* First go up the tree as much as needed.
@@ -2510,87 +2511,93 @@ undo_time(
uhp = curbuf->b_u_newhead;
else
uhp = uhp->uh_next.ptr;
if (uhp == NULL || uhp->uh_walk != mark
if (uhp == NULL || (target > 0 && uhp->uh_walk != mark)
|| (uhp->uh_seq == target && !above))
break;
curbuf->b_u_curhead = uhp;
u_undoredo(TRUE);
uhp->uh_walk = nomark; /* don't go back down here */
if (target > 0)
uhp->uh_walk = nomark; /* don't go back down here */
}
/*
* And now go down the tree (redo), branching off where needed.
*/
while (!got_int)
/* When back to origin, redo is not needed. */
if (target > 0)
{
/* Do the change warning now, for the same reason as above. */
change_warning(0);
/*
* And now go down the tree (redo), branching off where needed.
*/
while (!got_int)
{
/* Do the change warning now, for the same reason as above. */
change_warning(0);
uhp = curbuf->b_u_curhead;
if (uhp == NULL)
break;
uhp = curbuf->b_u_curhead;
if (uhp == NULL)
break;
/* Go back to the first branch with a mark. */
while (uhp->uh_alt_prev.ptr != NULL
/* Go back to the first branch with a mark. */
while (uhp->uh_alt_prev.ptr != NULL
&& uhp->uh_alt_prev.ptr->uh_walk == mark)
uhp = uhp->uh_alt_prev.ptr;
/* Find the last branch with a mark, that's the one. */
last = uhp;
while (last->uh_alt_next.ptr != NULL
&& last->uh_alt_next.ptr->uh_walk == mark)
last = last->uh_alt_next.ptr;
if (last != uhp)
{
/* Make the used branch the first entry in the list of
* alternatives to make "u" and CTRL-R take this branch. */
while (uhp->uh_alt_prev.ptr != NULL)
uhp = uhp->uh_alt_prev.ptr;
if (last->uh_alt_next.ptr != NULL)
last->uh_alt_next.ptr->uh_alt_prev.ptr =
/* Find the last branch with a mark, that's the one. */
last = uhp;
while (last->uh_alt_next.ptr != NULL
&& last->uh_alt_next.ptr->uh_walk == mark)
last = last->uh_alt_next.ptr;
if (last != uhp)
{
/* Make the used branch the first entry in the list of
* alternatives to make "u" and CTRL-R take this branch. */
while (uhp->uh_alt_prev.ptr != NULL)
uhp = uhp->uh_alt_prev.ptr;
if (last->uh_alt_next.ptr != NULL)
last->uh_alt_next.ptr->uh_alt_prev.ptr =
last->uh_alt_prev.ptr;
last->uh_alt_prev.ptr->uh_alt_next.ptr = last->uh_alt_next.ptr;
last->uh_alt_prev.ptr = NULL;
last->uh_alt_next.ptr = uhp;
uhp->uh_alt_prev.ptr = last;
last->uh_alt_prev.ptr->uh_alt_next.ptr =
last->uh_alt_next.ptr;
last->uh_alt_prev.ptr = NULL;
last->uh_alt_next.ptr = uhp;
uhp->uh_alt_prev.ptr = last;
if (curbuf->b_u_oldhead == uhp)
curbuf->b_u_oldhead = last;
uhp = last;
if (uhp->uh_next.ptr != NULL)
uhp->uh_next.ptr->uh_prev.ptr = uhp;
}
curbuf->b_u_curhead = uhp;
if (curbuf->b_u_oldhead == uhp)
curbuf->b_u_oldhead = last;
uhp = last;
if (uhp->uh_next.ptr != NULL)
uhp->uh_next.ptr->uh_prev.ptr = uhp;
}
curbuf->b_u_curhead = uhp;
if (uhp->uh_walk != mark)
break; /* must have reached the target */
if (uhp->uh_walk != mark)
break; /* must have reached the target */
/* Stop when going backwards in time and didn't find the exact
* header we were looking for. */
if (uhp->uh_seq == target && above)
{
curbuf->b_u_seq_cur = target - 1;
break;
}
/* Stop when going backwards in time and didn't find the exact
* header we were looking for. */
if (uhp->uh_seq == target && above)
{
curbuf->b_u_seq_cur = target - 1;
break;
}
u_undoredo(FALSE);
u_undoredo(FALSE);
/* Advance "curhead" to below the header we last used. If it
* becomes NULL then we need to set "newhead" to this leaf. */
if (uhp->uh_prev.ptr == NULL)
curbuf->b_u_newhead = uhp;
curbuf->b_u_curhead = uhp->uh_prev.ptr;
did_undo = FALSE;
/* Advance "curhead" to below the header we last used. If it
* becomes NULL then we need to set "newhead" to this leaf. */
if (uhp->uh_prev.ptr == NULL)
curbuf->b_u_newhead = uhp;
curbuf->b_u_curhead = uhp->uh_prev.ptr;
did_undo = FALSE;
if (uhp->uh_seq == target) /* found it! */
break;
if (uhp->uh_seq == target) /* found it! */
break;
uhp = uhp->uh_prev.ptr;
if (uhp == NULL || uhp->uh_walk != mark)
{
/* Need to redo more but can't find it... */
internal_error("undo_time()");
break;
uhp = uhp->uh_prev.ptr;
if (uhp == NULL || uhp->uh_walk != mark)
{
/* Need to redo more but can't find it... */
internal_error("undo_time()");
break;
}
}
}
}

View File

@@ -771,6 +771,18 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1446,
/**/
1445,
/**/
1444,
/**/
1443,
/**/
1442,
/**/
1441,
/**/
1440,
/**/

View File

@@ -1269,6 +1269,7 @@ enum auto_event
EVENT_BUFWRITEPOST, /* after writing a buffer */
EVENT_BUFWRITEPRE, /* before writing a buffer */
EVENT_BUFWRITECMD, /* write buffer using command */
EVENT_CMDLINECHANGED, /* command line was modified*/
EVENT_CMDLINEENTER, /* after entering the command line */
EVENT_CMDLINELEAVE, /* before leaving the command line */
EVENT_CMDWINENTER, /* after entering the cmdline window */

View File

@@ -2731,6 +2731,8 @@ winframe_remove(
if (frp2->fr_win != NULL)
frp2->fr_win->w_frame = frp2->fr_parent;
frp = frp2->fr_parent;
if (topframe->fr_child == frp2)
topframe->fr_child = frp;
vim_free(frp2);
frp2 = frp->fr_parent;
@@ -2754,6 +2756,8 @@ winframe_remove(
break;
}
}
if (topframe->fr_child == frp)
topframe->fr_child = frp2;
vim_free(frp);
}
}
@@ -3499,7 +3503,6 @@ win_alloc_firstwin(win_T *oldwin)
topframe = curwin->w_frame;
topframe->fr_width = Columns;
topframe->fr_height = Rows - p_ch;
topframe->fr_win = curwin;
return OK;
}
@@ -4812,7 +4815,12 @@ frame_remove(frame_T *frp)
if (frp->fr_prev != NULL)
frp->fr_prev->fr_next = frp->fr_next;
else
{
frp->fr_parent->fr_child = frp->fr_next;
/* special case: topframe->fr_child == frp */
if (topframe->fr_child == frp)
topframe->fr_child = frp->fr_next;
}
if (frp->fr_next != NULL)
frp->fr_next->fr_prev = frp->fr_prev;
}