Add the 'undoreload' option to be able to undo a file reload.

This commit is contained in:
Bram Moolenaar
2010-07-24 20:27:03 +02:00
parent 72ada0f8c2
commit 59f931ef54
16 changed files with 167 additions and 79 deletions

View File

@@ -7361,6 +7361,8 @@ A jump table for the options with a short description can be found at |Q_op|.
file on buffer read. file on buffer read.
The directory where the undo file is stored is specified by 'undodir'. The directory where the undo file is stored is specified by 'undodir'.
For more information about this feature see |undo-persistence|. For more information about this feature see |undo-persistence|.
The undo file is not read when 'undoreload' causes the buffer from
before a reload to be saved for undo.
WARNING: this is a very new feature. Use at your own risk! WARNING: this is a very new feature. Use at your own risk!
*'undolevels'* *'ul'* *'undolevels'* *'ul'*
@@ -7382,6 +7384,22 @@ A jump table for the options with a short description can be found at |Q_op|.
< This helps when you run out of memory for a single change. < This helps when you run out of memory for a single change.
Also see |clear-undo|. Also see |clear-undo|.
*'undoreload'* *'ur'*
'undoreload' 'ur' number (default 10000)
global
{not in Vi}
Save the whole buffer for undo when reloading it. This applies to the
":e!" command and reloading for when the buffer changed outside of
Vim. |FileChangedShell|
The save only happens when this options is negative or when the number
of lines is smaller than the value of this option.
Set this option to zero to disable undo for a reload.
When saving undo for a reload, any undo file is not read.
Note that this causes the whole buffer to be stored in memory. Set
this option to a lower value if you run out of memory.
*'updatecount'* *'uc'* *'updatecount'* *'uc'*
'updatecount' 'uc' number (default: 200) 'updatecount' 'uc' number (default: 200)
global global

View File

@@ -1029,8 +1029,10 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
'undodir' options.txt /*'undodir'* 'undodir' options.txt /*'undodir'*
'undofile' options.txt /*'undofile'* 'undofile' options.txt /*'undofile'*
'undolevels' options.txt /*'undolevels'* 'undolevels' options.txt /*'undolevels'*
'undoreload' options.txt /*'undoreload'*
'updatecount' options.txt /*'updatecount'* 'updatecount' options.txt /*'updatecount'*
'updatetime' options.txt /*'updatetime'* 'updatetime' options.txt /*'updatetime'*
'ur' options.txt /*'ur'*
'ut' options.txt /*'ut'* 'ut' options.txt /*'ut'*
'vb' options.txt /*'vb'* 'vb' options.txt /*'vb'*
'vbs' options.txt /*'vbs'* 'vbs' options.txt /*'vbs'*
@@ -6081,6 +6083,7 @@ hl-Directory syntax.txt /*hl-Directory*
hl-ErrorMsg syntax.txt /*hl-ErrorMsg* hl-ErrorMsg syntax.txt /*hl-ErrorMsg*
hl-FoldColumn syntax.txt /*hl-FoldColumn* hl-FoldColumn syntax.txt /*hl-FoldColumn*
hl-Folded syntax.txt /*hl-Folded* hl-Folded syntax.txt /*hl-Folded*
hl-Ignore syntax.txt /*hl-Ignore*
hl-IncSearch syntax.txt /*hl-IncSearch* hl-IncSearch syntax.txt /*hl-IncSearch*
hl-LineNr syntax.txt /*hl-LineNr* hl-LineNr syntax.txt /*hl-LineNr*
hl-MatchParen syntax.txt /*hl-MatchParen* hl-MatchParen syntax.txt /*hl-MatchParen*

View File

@@ -40,9 +40,6 @@ Add documentation for Python 3 support.
New patch 2010 Jul 24 New patch 2010 Jul 24
Docs patch by Dominique Pelle, Mar 25 included? Docs patch by Dominique Pelle, Mar 25 included?
'undoreload' option: when fewer lines than these consider a reload as a change
action and save the text before the reload, don't clear undo info.
Patch for :find completion. (Nazri Ramliy) Patch for :find completion. (Nazri Ramliy)
But I prefer to keep term.h and include/term.h He will work on it. But I prefer to keep term.h and include/term.h He will work on it.

View File

@@ -1,4 +1,4 @@
*version7.txt* For Vim version 7.3b. Last change: 2010 Jul 20 *version7.txt* For Vim version 7.3b. Last change: 2010 Jul 24
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@@ -7171,6 +7171,9 @@ Added ":earlier 1f" and ":later 1f".
Add file save counter to undo information. Add file save counter to undo information.
Added the |undotree()| and |undofile()| functions. Added the |undotree()| and |undofile()| functions.
Also added the 'undoreload' option. This makes it possible to save the
current text when reloading the buffer, so that it can be undone.
More encryption *new-more-encryption* More encryption *new-more-encryption*
--------------- ---------------

View File

@@ -722,6 +722,8 @@ call <SID>OptionG("km", &km)
call <SID>Header("editing text") call <SID>Header("editing text")
call append("$", "undolevels\tmaximum number of changes that can be undone") call append("$", "undolevels\tmaximum number of changes that can be undone")
call append("$", " \tset ul=" . &ul) call append("$", " \tset ul=" . &ul)
call append("$", "undoreload\tmaximum number lines to save for undo on a buffer reload")
call append("$", " \tset ur=" . &ur)
call append("$", "modified\tchanges have been made and not written to a file") call append("$", "modified\tchanges have been made and not written to a file")
call append("$", "\t(local to buffer)") call append("$", "\t(local to buffer)")
call <SID>BinOptionL("mod") call <SID>BinOptionL("mod")

View File

@@ -66,9 +66,10 @@ static void buf_delete_signs __ARGS((buf_T *buf));
* Return FAIL for failure, OK otherwise. * Return FAIL for failure, OK otherwise.
*/ */
int int
open_buffer(read_stdin, eap) open_buffer(read_stdin, eap, flags)
int read_stdin; /* read file from stdin */ int read_stdin; /* read file from stdin */
exarg_T *eap; /* for forced 'ff' and 'fenc' or NULL */ exarg_T *eap; /* for forced 'ff' and 'fenc' or NULL */
int flags; /* extra flags for readfile() */
{ {
int retval = OK; int retval = OK;
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
@@ -130,7 +131,8 @@ open_buffer(read_stdin, eap)
netbeansFireChanges = 0; netbeansFireChanges = 0;
#endif #endif
retval = readfile(curbuf->b_ffname, curbuf->b_fname, retval = readfile(curbuf->b_ffname, curbuf->b_fname,
(linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap, READ_NEW); (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap,
flags | READ_NEW);
#ifdef FEAT_NETBEANS_INTG #ifdef FEAT_NETBEANS_INTG
netbeansFireChanges = oldFire; netbeansFireChanges = oldFire;
#endif #endif
@@ -151,13 +153,15 @@ open_buffer(read_stdin, eap)
*/ */
curbuf->b_p_bin = TRUE; curbuf->b_p_bin = TRUE;
retval = readfile(NULL, NULL, (linenr_T)0, retval = readfile(NULL, NULL, (linenr_T)0,
(linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW + READ_STDIN); (linenr_T)0, (linenr_T)MAXLNUM, NULL,
flags | (READ_NEW + READ_STDIN));
curbuf->b_p_bin = save_bin; curbuf->b_p_bin = save_bin;
if (retval == OK) if (retval == OK)
{ {
line_count = curbuf->b_ml.ml_line_count; line_count = curbuf->b_ml.ml_line_count;
retval = readfile(NULL, NULL, (linenr_T)line_count, retval = readfile(NULL, NULL, (linenr_T)line_count,
(linenr_T)0, (linenr_T)MAXLNUM, eap, READ_BUFFER); (linenr_T)0, (linenr_T)MAXLNUM, eap,
flags | READ_BUFFER);
if (retval == OK) if (retval == OK)
{ {
/* Delete the binary lines. */ /* Delete the binary lines. */
@@ -412,7 +416,7 @@ close_buffer(win, buf, action)
buf->b_nwindows = nwindows; buf->b_nwindows = nwindows;
#endif #endif
buf_freeall(buf, del_buf, wipe_buf); buf_freeall(buf, (del_buf ? BFA_DEL : 0) + (wipe_buf ? BFA_WIPE : 0));
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
/* Autocommands may have deleted the buffer. */ /* Autocommands may have deleted the buffer. */
@@ -511,13 +515,15 @@ buf_clear_file(buf)
/* /*
* buf_freeall() - free all things allocated for a buffer that are related to * buf_freeall() - free all things allocated for a buffer that are related to
* the file. * the file. flags:
* BFA_DEL buffer is going to be deleted
* BFA_WIPE buffer is going to be wiped out
* BFA_KEEP_UNDO do not free undo information
*/ */
void void
buf_freeall(buf, del_buf, wipe_buf) buf_freeall(buf, flags)
buf_T *buf; buf_T *buf;
int del_buf UNUSED; /* buffer is going to be deleted */ int flags;
int wipe_buf UNUSED; /* buffer is going to be wiped out */
{ {
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
int is_curbuf = (buf == curbuf); int is_curbuf = (buf == curbuf);
@@ -525,13 +531,13 @@ buf_freeall(buf, del_buf, wipe_buf)
apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf); apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf);
if (!buf_valid(buf)) /* autocommands may delete the buffer */ if (!buf_valid(buf)) /* autocommands may delete the buffer */
return; return;
if (del_buf && buf->b_p_bl) if ((flags & BFA_DEL) && buf->b_p_bl)
{ {
apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf); apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf);
if (!buf_valid(buf)) /* autocommands may delete the buffer */ if (!buf_valid(buf)) /* autocommands may delete the buffer */
return; return;
} }
if (wipe_buf) if (flags & BFA_WIPE)
{ {
apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname, apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
FALSE, buf); FALSE, buf);
@@ -576,10 +582,13 @@ buf_freeall(buf, del_buf, wipe_buf)
#ifdef FEAT_TCL #ifdef FEAT_TCL
tcl_buffer_free(buf); tcl_buffer_free(buf);
#endif #endif
u_blockfree(buf); /* free the memory allocated for undo */
ml_close(buf, TRUE); /* close and delete the memline/memfile */ ml_close(buf, TRUE); /* close and delete the memline/memfile */
buf->b_ml.ml_line_count = 0; /* no lines in buffer */ buf->b_ml.ml_line_count = 0; /* no lines in buffer */
u_clearall(buf); /* reset all undo information */ if ((flags & BFA_KEEP_UNDO) == 0)
{
u_blockfree(buf); /* free the memory allocated for undo */
u_clearall(buf); /* reset all undo information */
}
#ifdef FEAT_SYN_HL #ifdef FEAT_SYN_HL
syntax_clear(&buf->b_s); /* reset syntax info */ syntax_clear(&buf->b_s); /* reset syntax info */
#endif #endif
@@ -1423,7 +1432,7 @@ enter_buffer(buf)
did_filetype = FALSE; did_filetype = FALSE;
#endif #endif
open_buffer(FALSE, NULL); open_buffer(FALSE, NULL, 0);
} }
else else
{ {
@@ -1625,7 +1634,7 @@ buflist_new(ffname, sfname, lnum, flags)
if (buf == curbuf) if (buf == curbuf)
{ {
/* free all things allocated for this buffer */ /* free all things allocated for this buffer */
buf_freeall(buf, FALSE, FALSE); buf_freeall(buf, 0);
if (buf != curbuf) /* autocommands deleted the buffer! */ if (buf != curbuf) /* autocommands deleted the buffer! */
return NULL; return NULL;
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)

View File

@@ -3144,6 +3144,7 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
#ifdef FEAT_SPELL #ifdef FEAT_SPELL
int did_get_winopts = FALSE; int did_get_winopts = FALSE;
#endif #endif
int readfile_flags = 0;
if (eap != NULL) if (eap != NULL)
command = eap->do_ecmd_cmd; command = eap->do_ecmd_cmd;
@@ -3570,7 +3571,22 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
else else
new_name = NULL; new_name = NULL;
#endif #endif
buf_freeall(curbuf, FALSE, FALSE); /* free all things for buffer */ if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur)
{
/* Save all the text, so that the reload can be undone.
* Sync first so that this is a separate undo-able action. */
u_sync(FALSE);
if (u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE)
== FAIL)
goto theend;
u_unchanged(curbuf);
buf_freeall(curbuf, BFA_KEEP_UNDO);
/* tell readfile() not to clear or reload undo info */
readfile_flags = READ_KEEP_UNDO;
}
else
buf_freeall(curbuf, 0); /* free all things for buffer */
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
/* If autocommands deleted the buffer we were going to re-edit, give /* If autocommands deleted the buffer we were going to re-edit, give
* up and jump to the end. */ * up and jump to the end. */
@@ -3667,10 +3683,10 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
* Open the buffer and read the file. * Open the buffer and read the file.
*/ */
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
if (should_abort(open_buffer(FALSE, eap))) if (should_abort(open_buffer(FALSE, eap, readfile_flags)))
retval = FAIL; retval = FAIL;
#else #else
(void)open_buffer(FALSE, eap); (void)open_buffer(FALSE, eap, readfile_flags);
#endif #endif
#if defined(HAS_SWAP_EXISTS_ACTION) #if defined(HAS_SWAP_EXISTS_ACTION)

View File

@@ -219,6 +219,7 @@ filemess(buf, name, s, attr)
* READ_BUFFER read from curbuf instead of a file (converting after reading * READ_BUFFER read from curbuf instead of a file (converting after reading
* stdin) * stdin)
* READ_DUMMY read into a dummy buffer (to check if file contents changed) * READ_DUMMY read into a dummy buffer (to check if file contents changed)
* READ_KEEP_UNDO don't clear undo info or read it from a file
* *
* return FAIL for failure, OK otherwise * return FAIL for failure, OK otherwise
*/ */
@@ -1195,8 +1196,12 @@ retry:
conv_restlen = 0; conv_restlen = 0;
#endif #endif
#ifdef FEAT_PERSISTENT_UNDO #ifdef FEAT_PERSISTENT_UNDO
read_undo_file = (newfile && curbuf->b_ffname != NULL && curbuf->b_p_udf read_undo_file = (newfile && (flags & READ_KEEP_UNDO) == 0
&& !filtering && !read_stdin && !read_buffer); && curbuf->b_ffname != NULL
&& curbuf->b_p_udf
&& !filtering
&& !read_stdin
&& !read_buffer);
if (read_undo_file) if (read_undo_file)
sha256_start(&sha_ctx); sha256_start(&sha_ctx);
#endif #endif
@@ -7077,6 +7082,7 @@ buf_reload(buf, orig_mode)
buf_T *savebuf; buf_T *savebuf;
int saved = OK; int saved = OK;
aco_save_T aco; aco_save_T aco;
int flags = READ_NEW;
/* set curwin/curbuf for "buf" and save some things */ /* set curwin/curbuf for "buf" and save some things */
aucmd_prepbuf(&aco, buf); aucmd_prepbuf(&aco, buf);
@@ -7089,6 +7095,15 @@ buf_reload(buf, orig_mode)
old_cursor = curwin->w_cursor; old_cursor = curwin->w_cursor;
old_topline = curwin->w_topline; old_topline = curwin->w_topline;
if (saved == OK && (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur))
{
/* Save all the text, so that the reload can be undone.
* Sync first so that this is a separate undo-able action. */
u_sync(FALSE);
saved = u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE);
flags |= READ_KEEP_UNDO;
}
/* /*
* To behave like when a new file is edited (matters for * To behave like when a new file is edited (matters for
* BufReadPost autocommands) we first need to delete the current * BufReadPost autocommands) we first need to delete the current
@@ -7096,7 +7111,7 @@ buf_reload(buf, orig_mode)
* the old contents. Can't use memory only, the file might be * the old contents. Can't use memory only, the file might be
* too big. Use a hidden buffer to move the buffer contents to. * too big. Use a hidden buffer to move the buffer contents to.
*/ */
if (bufempty()) if (bufempty() || saved == FAIL)
savebuf = NULL; savebuf = NULL;
else else
{ {
@@ -7128,7 +7143,7 @@ buf_reload(buf, orig_mode)
#endif #endif
if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0, if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0,
(linenr_T)0, (linenr_T)0,
(linenr_T)MAXLNUM, &ea, READ_NEW) == FAIL) (linenr_T)MAXLNUM, &ea, flags) == FAIL)
{ {
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
if (!aborting()) if (!aborting())
@@ -7144,12 +7159,18 @@ buf_reload(buf, orig_mode)
(void)move_lines(savebuf, buf); (void)move_lines(savebuf, buf);
} }
} }
else if (buf == curbuf) else if (buf == curbuf) /* "buf" still valid */
{ {
/* Mark the buffer as unmodified and free undo info. */ /* Mark the buffer as unmodified and free undo info. */
unchanged(buf, TRUE); unchanged(buf, TRUE);
u_blockfree(buf); if ((flags & READ_KEEP_UNDO) == 0)
u_clearall(buf); {
u_blockfree(buf);
u_clearall(buf);
}
else
/* Mark all undo states as changed. */
u_unchanged(curbuf);
} }
} }
vim_free(ea.cmd); vim_free(ea.cmd);

View File

@@ -2470,7 +2470,7 @@ read_stdin()
no_wait_return = TRUE; no_wait_return = TRUE;
i = msg_didany; i = msg_didany;
set_buflisted(TRUE); set_buflisted(TRUE);
(void)open_buffer(TRUE, NULL); /* create memfile and read file */ (void)open_buffer(TRUE, NULL, 0); /* create memfile and read file */
no_wait_return = FALSE; no_wait_return = FALSE;
msg_didany = i; msg_didany = i;
TIME_MSG("reading stdin"); TIME_MSG("reading stdin");
@@ -2591,7 +2591,9 @@ create_windows(parmp)
swap_exists_action = SEA_DIALOG; swap_exists_action = SEA_DIALOG;
#endif #endif
set_buflisted(TRUE); set_buflisted(TRUE);
(void)open_buffer(FALSE, NULL); /* create memfile, read file */
/* create memfile, read file */
(void)open_buffer(FALSE, NULL, 0);
#if defined(HAS_SWAP_EXISTS_ACTION) #if defined(HAS_SWAP_EXISTS_ACTION)
if (swap_exists_action == SEA_QUIT) if (swap_exists_action == SEA_QUIT)

View File

@@ -2529,7 +2529,7 @@ ml_append(lnum, line, len, newfile)
int newfile; /* flag, see above */ int newfile; /* flag, see above */
{ {
/* When starting up, we might still need to create the memfile */ /* When starting up, we might still need to create the memfile */
if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL) == FAIL) if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
return FAIL; return FAIL;
if (curbuf->b_ml.ml_line_lnum != 0) if (curbuf->b_ml.ml_line_lnum != 0)
@@ -3078,7 +3078,7 @@ ml_replace(lnum, line, copy)
return FAIL; return FAIL;
/* When starting up, we might still need to create the memfile */ /* When starting up, we might still need to create the memfile */
if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL) == FAIL) if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
return FAIL; return FAIL;
if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */ if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */

View File

@@ -2655,6 +2655,9 @@ static struct vimoption
(char_u *)100L, (char_u *)100L,
#endif #endif
(char_u *)0L} SCRIPTID_INIT}, (char_u *)0L} SCRIPTID_INIT},
{"undoreload", "ur", P_NUM|P_VI_DEF,
(char_u *)&p_ur, PV_NONE,
{ (char_u *)10000L, (char_u *)0L} SCRIPTID_INIT},
{"updatecount", "uc", P_NUM|P_VI_DEF, {"updatecount", "uc", P_NUM|P_VI_DEF,
(char_u *)&p_uc, PV_NONE, (char_u *)&p_uc, PV_NONE,
{(char_u *)200L, (char_u *)0L} SCRIPTID_INIT}, {(char_u *)200L, (char_u *)0L} SCRIPTID_INIT},

View File

@@ -826,6 +826,7 @@ static char *(p_ttym_values[]) = {"xterm", "xterm2", "dec", "netterm", "jsbterm"
#endif #endif
EXTERN char_u *p_udir; /* 'undodir' */ EXTERN char_u *p_udir; /* 'undodir' */
EXTERN long p_ul; /* 'undolevels' */ EXTERN long p_ul; /* 'undolevels' */
EXTERN long p_ur; /* 'undoreload' */
EXTERN long p_uc; /* 'updatecount' */ EXTERN long p_uc; /* 'updatecount' */
EXTERN long p_ut; /* 'updatetime' */ EXTERN long p_ut; /* 'updatetime' */
#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING) #if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)

View File

@@ -1,9 +1,9 @@
/* buffer.c */ /* buffer.c */
int open_buffer __ARGS((int read_stdin, exarg_T *eap)); int open_buffer __ARGS((int read_stdin, exarg_T *eap, int flags));
int buf_valid __ARGS((buf_T *buf)); int buf_valid __ARGS((buf_T *buf));
void close_buffer __ARGS((win_T *win, buf_T *buf, int action)); void close_buffer __ARGS((win_T *win, buf_T *buf, int action));
void buf_clear_file __ARGS((buf_T *buf)); void buf_clear_file __ARGS((buf_T *buf));
void buf_freeall __ARGS((buf_T *buf, int del_buf, int wipe_buf)); void buf_freeall __ARGS((buf_T *buf, int flags));
void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count)); void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
void handle_swap_exists __ARGS((buf_T *old_curbuf)); void handle_swap_exists __ARGS((buf_T *old_curbuf));
char_u *do_bufdel __ARGS((int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit)); char_u *do_bufdel __ARGS((int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit));

View File

@@ -5,6 +5,7 @@ int u_savesub __ARGS((linenr_T lnum));
int u_inssub __ARGS((linenr_T lnum)); int u_inssub __ARGS((linenr_T lnum));
int u_savedel __ARGS((linenr_T lnum, long nlines)); int u_savedel __ARGS((linenr_T lnum, long nlines));
int undo_allowed __ARGS((void)); int undo_allowed __ARGS((void));
int u_savecommon __ARGS((linenr_T top, linenr_T bot, linenr_T newbot, int reload));
void u_compute_hash __ARGS((char_u *hash)); void u_compute_hash __ARGS((char_u *hash));
char_u *u_get_undo_file_name __ARGS((char_u *buf_ffname, int reading)); char_u *u_get_undo_file_name __ARGS((char_u *buf_ffname, int reading));
void u_write_undo __ARGS((char_u *name, int forceit, buf_T *buf, char_u *hash)); void u_write_undo __ARGS((char_u *name, int forceit, buf_T *buf, char_u *hash));

View File

@@ -90,7 +90,6 @@
static void u_unch_branch __ARGS((u_header_T *uhp)); static void u_unch_branch __ARGS((u_header_T *uhp));
static u_entry_T *u_get_headentry __ARGS((void)); static u_entry_T *u_get_headentry __ARGS((void));
static void u_getbot __ARGS((void)); static void u_getbot __ARGS((void));
static int u_savecommon __ARGS((linenr_T, linenr_T, linenr_T));
static void u_doit __ARGS((int count)); static void u_doit __ARGS((int count));
static void u_undoredo __ARGS((int undo)); static void u_undoredo __ARGS((int undo));
static void u_undo_end __ARGS((int did_undo, int absolute)); static void u_undo_end __ARGS((int did_undo, int absolute));
@@ -250,7 +249,7 @@ u_save(top, bot)
if (top + 2 == bot) if (top + 2 == bot)
u_saveline((linenr_T)(top + 1)); u_saveline((linenr_T)(top + 1));
return (u_savecommon(top, bot, (linenr_T)0)); return (u_savecommon(top, bot, (linenr_T)0, FALSE));
} }
/* /*
@@ -266,7 +265,7 @@ u_savesub(lnum)
if (undo_off) if (undo_off)
return OK; return OK;
return (u_savecommon(lnum - 1, lnum + 1, lnum + 1)); return (u_savecommon(lnum - 1, lnum + 1, lnum + 1, FALSE));
} }
/* /*
@@ -282,7 +281,7 @@ u_inssub(lnum)
if (undo_off) if (undo_off)
return OK; return OK;
return (u_savecommon(lnum - 1, lnum, lnum + 1)); return (u_savecommon(lnum - 1, lnum, lnum + 1, FALSE));
} }
/* /*
@@ -301,7 +300,7 @@ u_savedel(lnum, nlines)
return OK; return OK;
return (u_savecommon(lnum - 1, lnum + nlines, return (u_savecommon(lnum - 1, lnum + nlines,
nlines == curbuf->b_ml.ml_line_count ? 2 : lnum)); nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, FALSE));
} }
/* /*
@@ -342,13 +341,16 @@ undo_allowed()
* Common code for various ways to save text before a change. * Common code for various ways to save text before a change.
* "top" is the line above the first changed line. * "top" is the line above the first changed line.
* "bot" is the line below the last changed line. * "bot" is the line below the last changed line.
* "newbot" is the new bottom line. Use zero when not known.
* "reload" is TRUE when saving for a buffer reload.
* Careful: may trigger autocommands that reload the buffer. * Careful: may trigger autocommands that reload the buffer.
* Returns FAIL when lines could not be saved, OK otherwise. * Returns FAIL when lines could not be saved, OK otherwise.
*/ */
static int int
u_savecommon(top, bot, newbot) u_savecommon(top, bot, newbot, reload)
linenr_T top, bot; linenr_T top, bot;
linenr_T newbot; linenr_T newbot;
int reload;
{ {
linenr_T lnum; linenr_T lnum;
long i; long i;
@@ -358,49 +360,53 @@ u_savecommon(top, bot, newbot)
u_entry_T *prev_uep; u_entry_T *prev_uep;
long size; long size;
/* When making changes is not allowed return FAIL. It's a crude way to if (!reload)
* make all change commands fail. */
if (!undo_allowed())
return FAIL;
#ifdef U_DEBUG
u_check(FALSE);
#endif
#ifdef FEAT_NETBEANS_INTG
/*
* Netbeans defines areas that cannot be modified. Bail out here when
* trying to change text in a guarded area.
*/
if (netbeans_active())
{ {
if (netbeans_is_guarded(top, bot)) /* When making changes is not allowed return FAIL. It's a crude way
{ * to make all change commands fail. */
EMSG(_(e_guarded)); if (!undo_allowed())
return FAIL; return FAIL;
}
if (curbuf->b_p_ro) #ifdef FEAT_NETBEANS_INTG
/*
* Netbeans defines areas that cannot be modified. Bail out here when
* trying to change text in a guarded area.
*/
if (netbeans_active())
{ {
EMSG(_(e_nbreadonly)); if (netbeans_is_guarded(top, bot))
return FAIL; {
EMSG(_(e_guarded));
return FAIL;
}
if (curbuf->b_p_ro)
{
EMSG(_(e_nbreadonly));
return FAIL;
}
} }
}
#endif #endif
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
/* /*
* Saving text for undo means we are going to make a change. Give a * Saving text for undo means we are going to make a change. Give a
* warning for a read-only file before making the change, so that the * warning for a read-only file before making the change, so that the
* FileChangedRO event can replace the buffer with a read-write version * FileChangedRO event can replace the buffer with a read-write version
* (e.g., obtained from a source control system). * (e.g., obtained from a source control system).
*/ */
change_warning(0); change_warning(0);
if (bot > curbuf->b_ml.ml_line_count + 1) if (bot > curbuf->b_ml.ml_line_count + 1)
{ {
/* This happens when the FileChangedRO autocommand changes the file in /* This happens when the FileChangedRO autocommand changes the
* a way it becomes shorter. */ * file in a way it becomes shorter. */
EMSG(_("E834: Line count changed unexpectedly")); EMSG(_("E834: Line count changed unexpectedly"));
return FAIL; return FAIL;
}
#endif
} }
#ifdef U_DEBUG
u_check(FALSE);
#endif #endif
size = bot - top - 1; size = bot - top - 1;
@@ -2905,7 +2911,7 @@ ex_undojoin(eap)
} }
/* /*
* Called after writing the file and setting b_changed to FALSE. * Called after writing or reloading the file and setting b_changed to FALSE.
* Now an undo means that the buffer is modified. * Now an undo means that the buffer is modified.
*/ */
void void
@@ -3197,7 +3203,7 @@ u_undoline()
/* first save the line for the 'u' command */ /* first save the line for the 'u' command */
if (u_savecommon(curbuf->b_u_line_lnum - 1, if (u_savecommon(curbuf->b_u_line_lnum - 1,
curbuf->b_u_line_lnum + 1, (linenr_T)0) == FAIL) curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL)
return; return;
oldp = u_save_line(curbuf->b_u_line_lnum); oldp = u_save_line(curbuf->b_u_line_lnum);
if (oldp == NULL) if (oldp == NULL)

View File

@@ -953,6 +953,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
#define READ_STDIN 0x04 /* read from stdin */ #define READ_STDIN 0x04 /* read from stdin */
#define READ_BUFFER 0x08 /* read from curbuf (converting stdin) */ #define READ_BUFFER 0x08 /* read from curbuf (converting stdin) */
#define READ_DUMMY 0x10 /* reading into a dummy buffer */ #define READ_DUMMY 0x10 /* reading into a dummy buffer */
#define READ_KEEP_UNDO 0x20 /* keep undo info*/
/* Values for change_indent() */ /* Values for change_indent() */
#define INDENT_SET 1 /* set indent */ #define INDENT_SET 1 /* set indent */
@@ -2174,4 +2175,9 @@ typedef int VimClipboard; /* This is required for the prototypes. */
#define VIF_FORCEIT 4 /* overwrite info already read */ #define VIF_FORCEIT 4 /* overwrite info already read */
#define VIF_GET_OLDFILES 8 /* load v:oldfiles */ #define VIF_GET_OLDFILES 8 /* load v:oldfiles */
/* flags for buf_freeall() */
#define BFA_DEL 1 /* buffer is going to be deleted */
#define BFA_WIPE 2 /* buffer is going to be wiped out */
#define BFA_KEEP_UNDO 4 /* do not free undo information */
#endif /* VIM__H */ #endif /* VIM__H */