diff options
Diffstat (limited to 'src/nvim/undo.c')
-rw-r--r-- | src/nvim/undo.c | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/src/nvim/undo.c b/src/nvim/undo.c index d18f35a43a..8324db37c6 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -89,6 +89,7 @@ #include "nvim/change.h" #include "nvim/cursor.h" #include "nvim/edit.h" +#include "nvim/ex_getln.h" #include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" @@ -272,7 +273,7 @@ int u_inssub(linenr_T lnum) */ int u_savedel(linenr_T lnum, long nlines) { - return u_savecommon(curbuf, lnum - 1, lnum + nlines, + return u_savecommon(curbuf, lnum - 1, lnum + (linenr_T)nlines, nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, false); } @@ -297,7 +298,7 @@ bool undo_allowed(buf_T *buf) // Don't allow changes in the buffer while editing the cmdline. The // caller of getcmdline() may get confused. if (textlock != 0) { - emsg(_(e_secure)); + emsg(_(e_textlock)); return false; } @@ -611,7 +612,6 @@ int u_savecommon(buf_T *buf, linenr_T top, linenr_T bot, linenr_T newbot, int re return OK; } - // magic at start of undofile #define UF_START_MAGIC "Vim\237UnDo\345" #define UF_START_MAGIC_LEN 9 @@ -694,15 +694,14 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading) // When not reading use the first directory that exists or ".". dirp = (char *)p_udir; while (*dirp != NUL) { - size_t dir_len = copy_option_part((char_u **)&dirp, (char_u *)dir_name, - MAXPATHL, ","); + size_t dir_len = copy_option_part(&dirp, dir_name, MAXPATHL, ","); if (dir_len == 1 && dir_name[0] == '.') { // Use same directory as the ffname, // "dir/name" -> "dir/.name.un~" const size_t ffname_len = strlen(ffname); undo_file_name = xmalloc(ffname_len + 6); memmove(undo_file_name, ffname, ffname_len + 1); - char *const tail = (char *)path_tail((char_u *)undo_file_name); + char *const tail = path_tail(undo_file_name); const size_t tail_len = strlen(tail); memmove(tail + 1, tail, tail_len + 1); *tail = '.'; @@ -1187,7 +1186,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, bufinfo_T bi; if (name == NULL) { - file_name = u_get_undo_file_name((char *)buf->b_ffname, false); + file_name = u_get_undo_file_name(buf->b_ffname, false); if (file_name == NULL) { if (p_verbose > 0) { verbose_enter(); @@ -1292,7 +1291,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, FileInfo file_info_old; FileInfo file_info_new; if (buf->b_ffname != NULL - && os_fileinfo((char *)buf->b_ffname, &file_info_old) + && os_fileinfo(buf->b_ffname, &file_info_old) && os_fileinfo(file_name, &file_info_new) && file_info_old.stat.st_gid != file_info_new.stat.st_gid && os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) { @@ -1371,10 +1370,8 @@ write_error: #ifdef HAVE_ACL if (buf->b_ffname != NULL) { - vim_acl_T acl; - // For systems that support ACL: get the ACL from the original file. - acl = mch_get_acl(buf->b_ffname); + vim_acl_T acl = mch_get_acl((char_u *)buf->b_ffname); mch_set_acl((char_u *)file_name, acl); mch_free_acl(acl); } @@ -1399,7 +1396,7 @@ void u_read_undo(char *name, const char_u *hash, const char_u *orig_name FUNC_AT char *file_name; if (name == NULL) { - file_name = u_get_undo_file_name((char *)curbuf->b_ffname, true); + file_name = u_get_undo_file_name(curbuf->b_ffname, true); if (file_name == NULL) { return; } @@ -1469,8 +1466,7 @@ void u_read_undo(char *name, const char_u *hash, const char_u *orig_name FUNC_AT if (name == NULL) { verbose_enter(); } - give_warning((char_u *) - _("File contents changed, cannot use undo info"), true); + give_warning(_("File contents changed, cannot use undo info"), true); if (name == NULL) { verbose_leave(); } @@ -1959,6 +1955,11 @@ void undo_time(long step, bool sec, bool file, bool absolute) bool above = false; bool did_undo = true; + if (text_locked()) { + text_locked_msg(); + return; + } + // First make sure the current undoable change is synced. if (curbuf->b_u_synced == false) { u_sync(true); @@ -2338,7 +2339,7 @@ static void u_undoredo(int undo, bool do_buf_event) } oldsize = bot - top - 1; // number of lines before undo - newsize = uep->ue_size; // number of lines after undo + newsize = (linenr_T)uep->ue_size; // number of lines after undo if (top < newlnum) { /* If the saved cursor is somewhere in this undo block, move it to @@ -2352,8 +2353,8 @@ static void u_undoredo(int undo, bool do_buf_event) /* Use the first line that actually changed. Avoids that * undoing auto-formatting puts the cursor in the previous * line. */ - for (i = 0; i < newsize && i < oldsize; ++i) { - if (STRCMP(uep->ue_array[i], ml_get(top + 1 + i)) != 0) { + for (i = 0; i < newsize && i < oldsize; i++) { + if (STRCMP(uep->ue_array[i], ml_get(top + 1 + (linenr_T)i)) != 0) { break; } } @@ -2361,7 +2362,7 @@ static void u_undoredo(int undo, bool do_buf_event) newlnum = top; curwin->w_cursor.lnum = newlnum + 1; } else if (i < newsize) { - newlnum = top + i; + newlnum = top + (linenr_T)i; curwin->w_cursor.lnum = newlnum + 1; } } @@ -2395,9 +2396,9 @@ static void u_undoredo(int undo, bool do_buf_event) * should get rid of, by replacing it with the new line */ if (empty_buffer && lnum == 0) { - ml_replace((linenr_T)1, uep->ue_array[i], true); + ml_replace((linenr_T)1, (char *)uep->ue_array[i], true); } else { - ml_append(lnum, uep->ue_array[i], (colnr_T)0, false); + ml_append(lnum, (char *)uep->ue_array[i], (colnr_T)0, false); } xfree(uep->ue_array[i]); } @@ -2406,8 +2407,7 @@ static void u_undoredo(int undo, bool do_buf_event) // Adjust marks if (oldsize != newsize) { - mark_adjust(top + 1, top + oldsize, (long)MAXLNUM, - (long)newsize - (long)oldsize, kExtmarkNOOP); + mark_adjust(top + 1, top + oldsize, MAXLNUM, newsize - oldsize, kExtmarkNOOP); if (curbuf->b_op_start.lnum > top + oldsize) { curbuf->b_op_start.lnum += newsize - oldsize; } @@ -2418,10 +2418,11 @@ static void u_undoredo(int undo, bool do_buf_event) changed_lines(top + 1, 0, bot, newsize - oldsize, do_buf_event); - // set '[ and '] mark + // Set the '[ mark. if (top + 1 < curbuf->b_op_start.lnum) { curbuf->b_op_start.lnum = top + 1; } + // Set the '] mark. if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum) { curbuf->b_op_end.lnum = top + 1; } else if (top + newsize > curbuf->b_op_end.lnum) { @@ -2442,6 +2443,14 @@ static void u_undoredo(int undo, bool do_buf_event) newlist = uep; } + // Ensure the '[ and '] marks are within bounds. + if (curbuf->b_op_start.lnum > curbuf->b_ml.ml_line_count) { + curbuf->b_op_start.lnum = curbuf->b_ml.ml_line_count; + } + if (curbuf->b_op_end.lnum > curbuf->b_ml.ml_line_count) { + curbuf->b_op_end.lnum = curbuf->b_ml.ml_line_count; + } + // Adjust Extmarks ExtmarkUndoObject undo_info; if (undo) { @@ -2463,7 +2472,6 @@ static void u_undoredo(int undo, bool do_buf_event) } // finish Adjusting extmarks - curhead->uh_entry = newlist; curhead->uh_flags = new_flags; if ((old_flags & UH_EMPTYBUF) && buf_is_empty(curbuf)) { @@ -2633,6 +2641,10 @@ static void u_undo_end(bool did_undo, bool absolute, bool quiet) } } + if (VIsual_active) { + check_pos(curbuf, &VIsual); + } + smsg_attr_keep(0, _("%" PRId64 " %s; %s #%" PRId64 " %s"), u_oldcount < 0 ? (int64_t)-u_oldcount : (int64_t)u_oldcount, @@ -2905,7 +2917,7 @@ static void u_getbot(buf_T *buf) * old line count subtracted from the current line count. */ extra = buf->b_ml.ml_line_count - uep->ue_lcount; - uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra; + uep->ue_bot = uep->ue_top + (linenr_T)uep->ue_size + 1 + extra; if (uep->ue_bot < 1 || uep->ue_bot > buf->b_ml.ml_line_count) { iemsg(_("E440: undo line missing")); uep->ue_bot = uep->ue_top + 1; // assume all lines deleted, will @@ -3104,9 +3116,9 @@ void u_undoline(void) } oldp = u_save_line(curbuf->b_u_line_lnum); - ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true); + ml_replace(curbuf->b_u_line_lnum, (char *)curbuf->b_u_line_ptr, true); changed_bytes(curbuf->b_u_line_lnum, 0); - extmark_splice_cols(curbuf, (int)curbuf->b_u_line_lnum-1, 0, (colnr_T)STRLEN(oldp), + extmark_splice_cols(curbuf, (int)curbuf->b_u_line_lnum - 1, 0, (colnr_T)STRLEN(oldp), (colnr_T)STRLEN(curbuf->b_u_line_ptr), kExtmarkUndo); xfree(curbuf->b_u_line_ptr); curbuf->b_u_line_ptr = oldp; |