mirror of
https://github.com/neovim/neovim.git
synced 2025-12-14 10:25:42 +00:00
Merge pull request #36290 from zeertzjq/backport
vim-patch:8.1.2008,v8.2.{844,853,3348,3795,4379}
This commit is contained in:
@@ -158,12 +158,12 @@ static int read_buffer(bool read_stdin, exarg_T *eap, int flags)
|
|||||||
if (retval == OK) {
|
if (retval == OK) {
|
||||||
// Delete the binary lines.
|
// Delete the binary lines.
|
||||||
while (--line_count >= 0) {
|
while (--line_count >= 0) {
|
||||||
ml_delete(1, false);
|
ml_delete(1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Delete the converted lines.
|
// Delete the converted lines.
|
||||||
while (curbuf->b_ml.ml_line_count > line_count) {
|
while (curbuf->b_ml.ml_line_count > line_count) {
|
||||||
ml_delete(line_count, false);
|
ml_delete(line_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Put the cursor on the first line.
|
// Put the cursor on the first line.
|
||||||
@@ -759,7 +759,7 @@ void buf_clear(void)
|
|||||||
linenr_T line_count = curbuf->b_ml.ml_line_count;
|
linenr_T line_count = curbuf->b_ml.ml_line_count;
|
||||||
extmark_free_all(curbuf); // delete any extmarks
|
extmark_free_all(curbuf); // delete any extmarks
|
||||||
while (!(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
while (!(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
||||||
ml_delete(1, false);
|
ml_delete(1);
|
||||||
}
|
}
|
||||||
deleted_lines_mark(1, line_count); // prepare for display
|
deleted_lines_mark(1, line_count); // prepare for display
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1981,7 +1981,7 @@ void del_lines(linenr_T nlines, bool undo)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ml_delete(first, true);
|
ml_delete_flags(first, ML_DEL_MESSAGE);
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
// If we delete the last line in the file, stop
|
// If we delete the last line in the file, stop
|
||||||
|
|||||||
@@ -3075,7 +3075,7 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr
|
|||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
// remember deleting the last line of the buffer
|
// remember deleting the last line of the buffer
|
||||||
buf_empty = curbuf->b_ml.ml_line_count == 1;
|
buf_empty = curbuf->b_ml.ml_line_count == 1;
|
||||||
if (ml_delete(lnum, false) == OK) {
|
if (ml_delete(lnum) == OK) {
|
||||||
added--;
|
added--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3096,7 +3096,7 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr
|
|||||||
// which results in inaccurate reporting of the byte count of
|
// which results in inaccurate reporting of the byte count of
|
||||||
// previous contents in buffer-update events.
|
// previous contents in buffer-update events.
|
||||||
buf_empty = false;
|
buf_empty = false;
|
||||||
ml_delete(2, false);
|
ml_delete(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
linenr_T new_count = dp->df_count[idx_to] + added;
|
linenr_T new_count = dp->df_count[idx_to] + added;
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ void f_deletebufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (linenr_T lnum = first; lnum <= last; lnum++) {
|
for (linenr_T lnum = first; lnum <= last; lnum++) {
|
||||||
ml_delete(first, true);
|
ml_delete_flags(first, ML_DEL_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
|
|||||||
@@ -659,7 +659,7 @@ void ex_sort(exarg_T *eap)
|
|||||||
// delete the original lines if appending worked
|
// delete the original lines if appending worked
|
||||||
if (i == count) {
|
if (i == count) {
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
ml_delete(eap->line1, false);
|
ml_delete(eap->line1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
count = 0;
|
count = 0;
|
||||||
@@ -806,7 +806,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (l = line1; l <= line2; l++) {
|
for (l = line1; l <= line2; l++) {
|
||||||
ml_delete(line1 + extra, true);
|
ml_delete_flags(line1 + extra, ML_DEL_MESSAGE);
|
||||||
}
|
}
|
||||||
if (!global_busy && num_lines > p_report) {
|
if (!global_busy && num_lines > p_report) {
|
||||||
smsg(0, NGETTEXT("%" PRId64 " line moved",
|
smsg(0, NGETTEXT("%" PRId64 " line moved",
|
||||||
@@ -2867,7 +2867,7 @@ void ex_append(exarg_T *eap)
|
|||||||
lnum++;
|
lnum++;
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
ml_delete(2, false);
|
ml_delete(2);
|
||||||
empty = false;
|
empty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2917,7 +2917,7 @@ void ex_change(exarg_T *eap)
|
|||||||
if (curbuf->b_ml.ml_flags & ML_EMPTY) { // nothing to delete
|
if (curbuf->b_ml.ml_flags & ML_EMPTY) { // nothing to delete
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ml_delete(eap->line1, false);
|
ml_delete(eap->line1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the cursor is not beyond the end of the file now
|
// make sure the cursor is not beyond the end of the file now
|
||||||
@@ -4107,7 +4107,7 @@ skip:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (i = 0; i < nmatch_tl; i++) {
|
for (i = 0; i < nmatch_tl; i++) {
|
||||||
ml_delete(lnum, false);
|
ml_delete(lnum);
|
||||||
}
|
}
|
||||||
mark_adjust(lnum, lnum + nmatch_tl - 1, MAXLNUM, -nmatch_tl, kExtmarkNOOP);
|
mark_adjust(lnum, lnum + nmatch_tl - 1, MAXLNUM, -nmatch_tl, kExtmarkNOOP);
|
||||||
if (subflags.do_ask) {
|
if (subflags.do_ask) {
|
||||||
|
|||||||
@@ -5934,7 +5934,7 @@ static void ex_read(exarg_T *eap)
|
|||||||
lnum = 1;
|
lnum = 1;
|
||||||
}
|
}
|
||||||
if (*ml_get(lnum) == NUL && u_savedel(lnum, 1) == OK) {
|
if (*ml_get(lnum) == NUL && u_savedel(lnum, 1) == OK) {
|
||||||
ml_delete(lnum, false);
|
ml_delete(lnum);
|
||||||
if (curwin->w_cursor.lnum > 1
|
if (curwin->w_cursor.lnum > 1
|
||||||
&& curwin->w_cursor.lnum >= lnum) {
|
&& curwin->w_cursor.lnum >= lnum) {
|
||||||
curwin->w_cursor.lnum--;
|
curwin->w_cursor.lnum--;
|
||||||
|
|||||||
@@ -733,7 +733,7 @@ retry:
|
|||||||
}
|
}
|
||||||
// Delete the previously read lines.
|
// Delete the previously read lines.
|
||||||
while (lnum > from) {
|
while (lnum > from) {
|
||||||
ml_delete(lnum--, false);
|
ml_delete(lnum--);
|
||||||
}
|
}
|
||||||
file_rewind = false;
|
file_rewind = false;
|
||||||
if (set_options) {
|
if (set_options) {
|
||||||
@@ -1660,7 +1660,7 @@ failed:
|
|||||||
if (!recoverymode) {
|
if (!recoverymode) {
|
||||||
// need to delete the last line, which comes from the empty buffer
|
// need to delete the last line, which comes from the empty buffer
|
||||||
if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
||||||
ml_delete(curbuf->b_ml.ml_line_count, false);
|
ml_delete(curbuf->b_ml.ml_line_count);
|
||||||
linecnt--;
|
linecnt--;
|
||||||
}
|
}
|
||||||
curbuf->deleted_bytes = 0;
|
curbuf->deleted_bytes = 0;
|
||||||
@@ -2836,7 +2836,7 @@ static int move_lines(buf_T *frombuf, buf_T *tobuf)
|
|||||||
if (retval != FAIL) {
|
if (retval != FAIL) {
|
||||||
curbuf = frombuf;
|
curbuf = frombuf;
|
||||||
for (linenr_T lnum = curbuf->b_ml.ml_line_count; lnum > 0; lnum--) {
|
for (linenr_T lnum = curbuf->b_ml.ml_line_count; lnum > 0; lnum--) {
|
||||||
if (ml_delete(lnum, false) == FAIL) {
|
if (ml_delete(lnum) == FAIL) {
|
||||||
// Oops! We could try putting back the saved lines, but that
|
// Oops! We could try putting back the saved lines, but that
|
||||||
// might fail again...
|
// might fail again...
|
||||||
retval = FAIL;
|
retval = FAIL;
|
||||||
@@ -3152,7 +3152,7 @@ void buf_reload(buf_T *buf, int orig_mode, bool reload_options)
|
|||||||
// Put the text back from the save buffer. First
|
// Put the text back from the save buffer. First
|
||||||
// delete any lines that readfile() added.
|
// delete any lines that readfile() added.
|
||||||
while (!buf_is_empty(curbuf)) {
|
while (!buf_is_empty(curbuf)) {
|
||||||
if (ml_delete(buf->b_ml.ml_line_count, false) == FAIL) {
|
if (ml_delete(buf->b_ml.ml_line_count) == FAIL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3809,7 +3809,7 @@ void ins_compl_delete(bool new_leader)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (curwin->w_cursor.lnum > compl_lnum) {
|
while (curwin->w_cursor.lnum > compl_lnum) {
|
||||||
if (ml_delete(curwin->w_cursor.lnum, false) == FAIL) {
|
if (ml_delete(curwin->w_cursor.lnum) == FAIL) {
|
||||||
if (remaining.data) {
|
if (remaining.data) {
|
||||||
xfree(remaining.data);
|
xfree(remaining.data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -961,7 +961,7 @@ void ml_recover(bool checkext)
|
|||||||
// Now that we are sure that the file is going to be recovered, clear the
|
// Now that we are sure that the file is going to be recovered, clear the
|
||||||
// contents of the current buffer.
|
// contents of the current buffer.
|
||||||
while (!(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
while (!(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
||||||
ml_delete(1, false);
|
ml_delete(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try reading the original file to obtain the values of 'fileformat',
|
// Try reading the original file to obtain the values of 'fileformat',
|
||||||
@@ -1185,7 +1185,7 @@ void ml_recover(bool checkext)
|
|||||||
// empty buffer. These will now be after the last line in the buffer.
|
// empty buffer. These will now be after the last line in the buffer.
|
||||||
while (curbuf->b_ml.ml_line_count > lnum
|
while (curbuf->b_ml.ml_line_count > lnum
|
||||||
&& !(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
&& !(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
||||||
ml_delete(curbuf->b_ml.ml_line_count, false);
|
ml_delete(curbuf->b_ml.ml_line_count);
|
||||||
}
|
}
|
||||||
curbuf->b_flags |= BF_RECOVERED;
|
curbuf->b_flags |= BF_RECOVERED;
|
||||||
check_cursor(curwin);
|
check_cursor(curwin);
|
||||||
@@ -1974,12 +1974,10 @@ int ml_line_alloced(void)
|
|||||||
/// @param lnum append after this line (can be 0)
|
/// @param lnum append after this line (can be 0)
|
||||||
/// @param line text of the new line
|
/// @param line text of the new line
|
||||||
/// @param len length of line, including NUL, or 0
|
/// @param len length of line, including NUL, or 0
|
||||||
/// @param newfile flag, see above
|
/// @param flags ML_APPEND_ flags
|
||||||
/// @param mark mark the new line
|
|
||||||
///
|
///
|
||||||
/// @return FAIL for failure, OK otherwise
|
/// @return FAIL for failure, OK otherwise
|
||||||
static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfile,
|
static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int flags)
|
||||||
bool mark)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
// lnum out of range
|
// lnum out of range
|
||||||
@@ -2076,13 +2074,13 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo
|
|||||||
|
|
||||||
// copy the text into the block
|
// copy the text into the block
|
||||||
memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
|
memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
|
||||||
if (mark) {
|
if (flags & ML_APPEND_MARK) {
|
||||||
dp->db_index[db_idx + 1] |= DB_MARKED;
|
dp->db_index[db_idx + 1] |= DB_MARKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the block dirty.
|
// Mark the block dirty.
|
||||||
buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
|
buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
|
||||||
if (!newfile) {
|
if (!(flags & ML_APPEND_NEW)) {
|
||||||
buf->b_ml.ml_flags |= ML_LOCKED_POS;
|
buf->b_ml.ml_flags |= ML_LOCKED_POS;
|
||||||
}
|
}
|
||||||
} else { // not enough space in data block
|
} else { // not enough space in data block
|
||||||
@@ -2136,7 +2134,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
int page_count = ((space_needed + (int)HEADER_SIZE) + page_size - 1) / page_size;
|
int page_count = ((space_needed + (int)HEADER_SIZE) + page_size - 1) / page_size;
|
||||||
hp_new = ml_new_data(mfp, newfile, page_count);
|
hp_new = ml_new_data(mfp, flags & ML_APPEND_NEW, page_count);
|
||||||
if (db_idx < 0) { // left block is new
|
if (db_idx < 0) { // left block is new
|
||||||
hp_left = hp_new;
|
hp_left = hp_new;
|
||||||
hp_right = hp;
|
hp_right = hp;
|
||||||
@@ -2160,7 +2158,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo
|
|||||||
dp_right->db_txt_start -= (unsigned)len;
|
dp_right->db_txt_start -= (unsigned)len;
|
||||||
dp_right->db_free -= (unsigned)len + (unsigned)INDEX_SIZE;
|
dp_right->db_free -= (unsigned)len + (unsigned)INDEX_SIZE;
|
||||||
dp_right->db_index[0] = dp_right->db_txt_start;
|
dp_right->db_index[0] = dp_right->db_txt_start;
|
||||||
if (mark) {
|
if (flags & ML_APPEND_MARK) {
|
||||||
dp_right->db_index[0] |= DB_MARKED;
|
dp_right->db_index[0] |= DB_MARKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2193,7 +2191,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo
|
|||||||
dp_left->db_txt_start -= (unsigned)len;
|
dp_left->db_txt_start -= (unsigned)len;
|
||||||
dp_left->db_free -= (unsigned)len + (unsigned)INDEX_SIZE;
|
dp_left->db_free -= (unsigned)len + (unsigned)INDEX_SIZE;
|
||||||
dp_left->db_index[line_count_left] = dp_left->db_txt_start;
|
dp_left->db_index[line_count_left] = dp_left->db_txt_start;
|
||||||
if (mark) {
|
if (flags & ML_APPEND_MARK) {
|
||||||
dp_left->db_index[line_count_left] |= DB_MARKED;
|
dp_left->db_index[line_count_left] |= DB_MARKED;
|
||||||
}
|
}
|
||||||
memmove((char *)dp_left + dp_left->db_txt_start,
|
memmove((char *)dp_left + dp_left->db_txt_start,
|
||||||
@@ -2222,7 +2220,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo
|
|||||||
if (lines_moved || in_left) {
|
if (lines_moved || in_left) {
|
||||||
buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
|
buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
|
||||||
}
|
}
|
||||||
if (!newfile && db_idx >= 0 && in_left) {
|
if (!(flags & ML_APPEND_NEW) && db_idx >= 0 && in_left) {
|
||||||
buf->b_ml.ml_flags |= ML_LOCKED_POS;
|
buf->b_ml.ml_flags |= ML_LOCKED_POS;
|
||||||
}
|
}
|
||||||
mf_put(mfp, hp_new, true, false);
|
mf_put(mfp, hp_new, true, false);
|
||||||
@@ -2387,10 +2385,10 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo
|
|||||||
/// @param lnum append after this line (can be 0)
|
/// @param lnum append after this line (can be 0)
|
||||||
/// @param line text of the new line
|
/// @param line text of the new line
|
||||||
/// @param len length of line, including NUL, or 0
|
/// @param len length of line, including NUL, or 0
|
||||||
/// @param newfile flag, see above
|
/// @param flags ML_APPEND_ flags
|
||||||
///
|
///
|
||||||
/// @return FAIL for failure, OK otherwise
|
/// @return FAIL for failure, OK otherwise
|
||||||
static int ml_append_flush(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfile)
|
static int ml_append_flush(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int flags)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
if (lnum > buf->b_ml.ml_line_count) {
|
if (lnum > buf->b_ml.ml_line_count) {
|
||||||
@@ -2401,14 +2399,14 @@ static int ml_append_flush(buf_T *buf, linenr_T lnum, char *line, colnr_T len, b
|
|||||||
ml_flush_line(buf, false);
|
ml_flush_line(buf, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ml_append_int(buf, lnum, line, len, newfile, false);
|
return ml_append_int(buf, lnum, line, len, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append a line after lnum (may be 0 to insert a line in front of the file).
|
/// Append a line after lnum (may be 0 to insert a line in front of the file).
|
||||||
/// "line" does not need to be allocated, but can't be another line in a
|
/// "line" does not need to be allocated, but can't be another line in a
|
||||||
/// buffer, unlocking may make it invalid.
|
/// buffer, unlocking may make it invalid.
|
||||||
///
|
///
|
||||||
/// newfile: true when starting to edit a new file, meaning that pe_old_lnum
|
/// "newfile": true when starting to edit a new file, meaning that pe_old_lnum
|
||||||
/// will be set for recovery
|
/// will be set for recovery
|
||||||
/// Check: The caller of this function should probably also call
|
/// Check: The caller of this function should probably also call
|
||||||
/// appended_lines().
|
/// appended_lines().
|
||||||
@@ -2420,13 +2418,24 @@ static int ml_append_flush(buf_T *buf, linenr_T lnum, char *line, colnr_T len, b
|
|||||||
///
|
///
|
||||||
/// @return FAIL for failure, OK otherwise
|
/// @return FAIL for failure, OK otherwise
|
||||||
int ml_append(linenr_T lnum, char *line, colnr_T len, bool newfile)
|
int ml_append(linenr_T lnum, char *line, colnr_T len, bool newfile)
|
||||||
|
{
|
||||||
|
return ml_append_flags(lnum, line, len, newfile ? ML_APPEND_NEW : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @param lnum append after this line (can be 0)
|
||||||
|
/// @param line text of the new line
|
||||||
|
/// @param len length of new line, including nul, or 0
|
||||||
|
/// @param flags ML_APPEND_ values
|
||||||
|
///
|
||||||
|
/// @return FAIL for failure, OK otherwise
|
||||||
|
int ml_append_flags(linenr_T lnum, char *line, colnr_T len, int flags)
|
||||||
{
|
{
|
||||||
// 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, 0) == FAIL) {
|
if (curbuf->b_ml.ml_mfp == NULL && open_buffer(false, NULL, 0) == FAIL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ml_append_flush(curbuf, lnum, line, len, newfile);
|
return ml_append_flush(curbuf, lnum, line, len, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like ml_append() but for an arbitrary buffer. The buffer must already have
|
/// Like ml_append() but for an arbitrary buffer. The buffer must already have
|
||||||
@@ -2443,7 +2452,7 @@ int ml_append_buf(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfi
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ml_append_flush(buf, lnum, line, len, newfile);
|
return ml_append_flush(buf, lnum, line, len, newfile ? ML_APPEND_NEW : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ml_add_deleted_len(char *ptr, ssize_t len)
|
void ml_add_deleted_len(char *ptr, ssize_t len)
|
||||||
@@ -2531,24 +2540,6 @@ int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy, bool noallo
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete line `lnum` in the current buffer.
|
|
||||||
///
|
|
||||||
/// @note The caller of this function should probably also call
|
|
||||||
/// deleted_lines() after this.
|
|
||||||
///
|
|
||||||
/// @param message Show "--No lines in buffer--" message.
|
|
||||||
///
|
|
||||||
/// @return FAIL for failure, OK otherwise
|
|
||||||
int ml_delete(linenr_T lnum, bool message)
|
|
||||||
{
|
|
||||||
ml_flush_line(curbuf, false);
|
|
||||||
if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ml_delete_int(curbuf, lnum, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Delete line `lnum` in buffer
|
/// Delete line `lnum` in buffer
|
||||||
///
|
///
|
||||||
/// @note The caller of this function should probably also call changed_lines() after this.
|
/// @note The caller of this function should probably also call changed_lines() after this.
|
||||||
@@ -2557,12 +2548,20 @@ int ml_delete(linenr_T lnum, bool message)
|
|||||||
///
|
///
|
||||||
/// @return FAIL for failure, OK otherwise
|
/// @return FAIL for failure, OK otherwise
|
||||||
int ml_delete_buf(buf_T *buf, linenr_T lnum, bool message)
|
int ml_delete_buf(buf_T *buf, linenr_T lnum, bool message)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
ml_flush_line(buf, false);
|
ml_flush_line(buf, false);
|
||||||
return ml_delete_int(buf, lnum, message);
|
return ml_delete_int(buf, lnum, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
|
/// Delete line `lnum` in the current buffer.
|
||||||
|
///
|
||||||
|
/// @param flags ML_DEL_MESSAGE may give a "No lines in buffer" message.
|
||||||
|
/// ML_DEL_UNDO this is called from undo.
|
||||||
|
///
|
||||||
|
/// @return FAIL for failure, OK otherwise
|
||||||
|
static int ml_delete_int(buf_T *buf, linenr_T lnum, int flags)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
if (lowest_marked && lowest_marked > lnum) {
|
if (lowest_marked && lowest_marked > lnum) {
|
||||||
lowest_marked--;
|
lowest_marked--;
|
||||||
@@ -2570,7 +2569,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
|
|||||||
|
|
||||||
// If the file becomes empty the last line is replaced by an empty line.
|
// If the file becomes empty the last line is replaced by an empty line.
|
||||||
if (buf->b_ml.ml_line_count == 1) { // file becomes empty
|
if (buf->b_ml.ml_line_count == 1) { // file becomes empty
|
||||||
if (message) {
|
if (flags & ML_DEL_MESSAGE) {
|
||||||
set_keep_msg(_(no_lines_msg), 0);
|
set_keep_msg(_(no_lines_msg), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2686,6 +2685,30 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete line "lnum" in the current buffer.
|
||||||
|
///
|
||||||
|
/// @note The caller of this function should probably also call
|
||||||
|
/// deleted_lines() after this.
|
||||||
|
///
|
||||||
|
/// @return FAIL for failure, OK otherwise
|
||||||
|
int ml_delete(linenr_T lnum)
|
||||||
|
{
|
||||||
|
return ml_delete_flags(lnum, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Like ml_delete() but using flags (see ml_delete_int()).
|
||||||
|
///
|
||||||
|
/// @return FAIL for failure, OK otherwise
|
||||||
|
int ml_delete_flags(linenr_T lnum, int flags)
|
||||||
|
{
|
||||||
|
ml_flush_line(curbuf, false);
|
||||||
|
if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ml_delete_int(curbuf, lnum, flags);
|
||||||
|
}
|
||||||
|
|
||||||
/// set the B_MARKED flag for line 'lnum'
|
/// set the B_MARKED flag for line 'lnum'
|
||||||
void ml_setmarked(linenr_T lnum)
|
void ml_setmarked(linenr_T lnum)
|
||||||
{
|
{
|
||||||
@@ -2846,7 +2869,9 @@ static void ml_flush_line(buf_T *buf, bool noalloc)
|
|||||||
memmove(old_line - extra, new_line, (size_t)new_len);
|
memmove(old_line - extra, new_line, (size_t)new_len);
|
||||||
buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
|
buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
|
||||||
// The else case is already covered by the insert and delete
|
// The else case is already covered by the insert and delete
|
||||||
ml_updatechunk(buf, lnum, extra, ML_CHNK_UPDLINE);
|
if (extra != 0) {
|
||||||
|
ml_updatechunk(buf, lnum, extra, ML_CHNK_UPDLINE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Cannot do it in one data block: Delete and append.
|
// Cannot do it in one data block: Delete and append.
|
||||||
// Append first, because ml_delete_int() cannot delete the
|
// Append first, because ml_delete_int() cannot delete the
|
||||||
@@ -2854,9 +2879,9 @@ static void ml_flush_line(buf_T *buf, bool noalloc)
|
|||||||
// that has only one line.
|
// that has only one line.
|
||||||
// Don't forget to copy the mark!
|
// Don't forget to copy the mark!
|
||||||
// How about handling errors???
|
// How about handling errors???
|
||||||
ml_append_int(buf, lnum, new_line, new_len, false,
|
(void)ml_append_int(buf, lnum, new_line, new_len,
|
||||||
(int)(dp->db_index[idx] & DB_MARKED));
|
(dp->db_index[idx] & DB_MARKED) ? ML_APPEND_MARK : 0);
|
||||||
ml_delete_int(buf, lnum, false);
|
(void)ml_delete_int(buf, lnum, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!noalloc) {
|
if (!noalloc) {
|
||||||
@@ -3978,7 +4003,7 @@ int ml_find_line_or_offset(buf_T *buf, linenr_T lnum, int *offp, bool no_ff)
|
|||||||
return 1; // Not a "find offset" and offset 0 _must_ be in line 1
|
return 1; // Not a "find offset" and offset 0 _must_ be in line 1
|
||||||
}
|
}
|
||||||
// Find the last chunk before the one containing our line. Last chunk is
|
// Find the last chunk before the one containing our line. Last chunk is
|
||||||
// special because it will never qualify
|
// special because it will never qualify.
|
||||||
linenr_T curline = 1;
|
linenr_T curline = 1;
|
||||||
int curix = 0;
|
int curix = 0;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|||||||
@@ -12,3 +12,16 @@
|
|||||||
|
|
||||||
/// LINEEMPTY() - return true if the line is empty
|
/// LINEEMPTY() - return true if the line is empty
|
||||||
#define LINEEMPTY(p) (*ml_get(p) == NUL)
|
#define LINEEMPTY(p) (*ml_get(p) == NUL)
|
||||||
|
|
||||||
|
// Values for the flags argument of ml_delete_flags().
|
||||||
|
enum {
|
||||||
|
ML_DEL_MESSAGE = 1, // may give a "No lines in buffer" message
|
||||||
|
// ML_DEL_UNDO = 2, // called from undo
|
||||||
|
};
|
||||||
|
|
||||||
|
// Values for the flags argument of ml_append_int().
|
||||||
|
enum {
|
||||||
|
ML_APPEND_NEW = 1, // starting to edit a new file
|
||||||
|
ML_APPEND_MARK = 2, // mark the new line
|
||||||
|
// ML_APPEND_UNDO = 4, // called from undo
|
||||||
|
};
|
||||||
|
|||||||
@@ -6598,7 +6598,7 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
|
|||||||
// When all lines were selected and deleted do_put() leaves an empty
|
// When all lines were selected and deleted do_put() leaves an empty
|
||||||
// line that needs to be deleted now.
|
// line that needs to be deleted now.
|
||||||
if (empty && *ml_get(curbuf->b_ml.ml_line_count) == NUL) {
|
if (empty && *ml_get(curbuf->b_ml.ml_line_count) == NUL) {
|
||||||
ml_delete(curbuf->b_ml.ml_line_count, true);
|
ml_delete_flags(curbuf->b_ml.ml_line_count, ML_DEL_MESSAGE);
|
||||||
deleted_lines(curbuf->b_ml.ml_line_count + 1, 1);
|
deleted_lines(curbuf->b_ml.ml_line_count + 1, 1);
|
||||||
|
|
||||||
// If the cursor was in that line, move it to the end of the last
|
// If the cursor was in that line, move it to the end of the last
|
||||||
|
|||||||
@@ -4180,7 +4180,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q
|
|||||||
while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0) {
|
while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0) {
|
||||||
// If deletion fails, this loop may run forever, so
|
// If deletion fails, this loop may run forever, so
|
||||||
// signal error and return.
|
// signal error and return.
|
||||||
if (ml_delete(1, false) == FAIL) {
|
if (ml_delete(1) == FAIL) {
|
||||||
internal_error("qf_fill_buffer()");
|
internal_error("qf_fill_buffer()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -4250,7 +4250,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q
|
|||||||
}
|
}
|
||||||
if (old_last == NULL) {
|
if (old_last == NULL) {
|
||||||
// Delete the empty line which is now at the end
|
// Delete the empty line which is now at the end
|
||||||
ml_delete(lnum + 1, false);
|
ml_delete(lnum + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
qfga_clear();
|
qfga_clear();
|
||||||
|
|||||||
@@ -3234,7 +3234,7 @@ void ex_spelldump(exarg_T *eap)
|
|||||||
|
|
||||||
// Delete the empty line that we started with.
|
// Delete the empty line that we started with.
|
||||||
if (curbuf->b_ml.ml_line_count > 1) {
|
if (curbuf->b_ml.ml_line_count > 1) {
|
||||||
ml_delete(curbuf->b_ml.ml_line_count, false);
|
ml_delete(curbuf->b_ml.ml_line_count);
|
||||||
}
|
}
|
||||||
redraw_later(curwin, UPD_NOT_VALID);
|
redraw_later(curwin, UPD_NOT_VALID);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2132,7 +2132,7 @@ static void adjust_scrollback(Terminal *term, buf_T *buf)
|
|||||||
if (scbk < term->sb_current) {
|
if (scbk < term->sb_current) {
|
||||||
size_t diff = term->sb_current - scbk;
|
size_t diff = term->sb_current - scbk;
|
||||||
for (size_t i = 0; i < diff; i++) {
|
for (size_t i = 0; i < diff; i++) {
|
||||||
ml_delete(1, false);
|
ml_delete(1);
|
||||||
term->sb_current--;
|
term->sb_current--;
|
||||||
xfree(term->sb_buffer[term->sb_current]);
|
xfree(term->sb_buffer[term->sb_current]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ int u_save_cursor(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Save the lines between "top" and "bot" for both the "u" and "U" command.
|
/// Save the lines between "top" and "bot" for both the "u" and "U" command.
|
||||||
/// "top" may be 0 and bot may be curbuf->b_ml.ml_line_count + 1.
|
/// "top" may be 0 and "bot" may be curbuf->b_ml.ml_line_count + 1.
|
||||||
/// 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.
|
||||||
int u_save(linenr_T top, linenr_T bot)
|
int u_save(linenr_T top, linenr_T bot)
|
||||||
@@ -2252,6 +2252,7 @@ static void u_undoredo(bool undo, bool do_buf_event)
|
|||||||
{
|
{
|
||||||
char **newarray = NULL;
|
char **newarray = NULL;
|
||||||
linenr_T newlnum = MAXLNUM;
|
linenr_T newlnum = MAXLNUM;
|
||||||
|
pos_T new_curpos = curwin->w_cursor;
|
||||||
u_entry_T *nuep;
|
u_entry_T *nuep;
|
||||||
u_entry_T *newlist = NULL;
|
u_entry_T *newlist = NULL;
|
||||||
fmark_T namedm[NMARKS];
|
fmark_T namedm[NMARKS];
|
||||||
@@ -2296,14 +2297,16 @@ static void u_undoredo(bool undo, bool do_buf_event)
|
|||||||
linenr_T oldsize = bot - top - 1; // number of lines before undo
|
linenr_T oldsize = bot - top - 1; // number of lines before undo
|
||||||
linenr_T newsize = uep->ue_size; // number of lines after undo
|
linenr_T newsize = uep->ue_size; // number of lines after undo
|
||||||
|
|
||||||
|
// Decide about the cursor position, depending on what text changed.
|
||||||
|
// Don't set it yet, it may be invalid if lines are going to be added.
|
||||||
if (top < newlnum) {
|
if (top < newlnum) {
|
||||||
// If the saved cursor is somewhere in this undo block, move it to
|
// If the saved cursor is somewhere in this undo block, move it to
|
||||||
// the remembered position. Makes "gwap" put the cursor back
|
// the remembered position. Makes "gwap" put the cursor back
|
||||||
// where it was.
|
// where it was.
|
||||||
linenr_T lnum = curhead->uh_cursor.lnum;
|
linenr_T lnum = curhead->uh_cursor.lnum;
|
||||||
if (lnum >= top && lnum <= top + newsize + 1) {
|
if (lnum >= top && lnum <= top + newsize + 1) {
|
||||||
curwin->w_cursor = curhead->uh_cursor;
|
new_curpos = curhead->uh_cursor;
|
||||||
newlnum = curwin->w_cursor.lnum - 1;
|
newlnum = new_curpos.lnum - 1;
|
||||||
} else {
|
} else {
|
||||||
// Use the first line that actually changed. Avoids that
|
// Use the first line that actually changed. Avoids that
|
||||||
// undoing auto-formatting puts the cursor in the previous
|
// undoing auto-formatting puts the cursor in the previous
|
||||||
@@ -2316,17 +2319,17 @@ static void u_undoredo(bool undo, bool do_buf_event)
|
|||||||
}
|
}
|
||||||
if (i == newsize && newlnum == MAXLNUM && uep->ue_next == NULL) {
|
if (i == newsize && newlnum == MAXLNUM && uep->ue_next == NULL) {
|
||||||
newlnum = top;
|
newlnum = top;
|
||||||
curwin->w_cursor.lnum = newlnum + 1;
|
new_curpos.lnum = newlnum + 1;
|
||||||
} else if (i < newsize) {
|
} else if (i < newsize) {
|
||||||
newlnum = top + (linenr_T)i;
|
newlnum = top + (linenr_T)i;
|
||||||
curwin->w_cursor.lnum = newlnum + 1;
|
new_curpos.lnum = newlnum + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty_buffer = false;
|
bool empty_buffer = false;
|
||||||
|
|
||||||
// delete the lines between top and bot and save them in newarray
|
// Delete the lines between top and bot and save them in newarray.
|
||||||
if (oldsize > 0) {
|
if (oldsize > 0) {
|
||||||
newarray = xmalloc(sizeof(char *) * (size_t)oldsize);
|
newarray = xmalloc(sizeof(char *) * (size_t)oldsize);
|
||||||
// delete backwards, it goes faster in most cases
|
// delete backwards, it goes faster in most cases
|
||||||
@@ -2340,13 +2343,16 @@ static void u_undoredo(bool undo, bool do_buf_event)
|
|||||||
if (curbuf->b_ml.ml_line_count == 1) {
|
if (curbuf->b_ml.ml_line_count == 1) {
|
||||||
empty_buffer = true;
|
empty_buffer = true;
|
||||||
}
|
}
|
||||||
ml_delete(lnum, false);
|
ml_delete(lnum); // ML_DEL_UNDO
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newarray = NULL;
|
newarray = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert the lines in u_array between top and bot
|
// make sure the cursor is on a valid line after the deletions
|
||||||
|
check_cursor_lnum(curwin);
|
||||||
|
|
||||||
|
// Insert the lines in u_array between top and bot.
|
||||||
if (newsize) {
|
if (newsize) {
|
||||||
int i;
|
int i;
|
||||||
linenr_T lnum;
|
linenr_T lnum;
|
||||||
@@ -2356,7 +2362,7 @@ static void u_undoredo(bool undo, bool do_buf_event)
|
|||||||
if (empty_buffer && lnum == 0) {
|
if (empty_buffer && lnum == 0) {
|
||||||
ml_replace(1, uep->ue_array[i], true);
|
ml_replace(1, uep->ue_array[i], true);
|
||||||
} else {
|
} else {
|
||||||
ml_append(lnum, uep->ue_array[i], 0, false);
|
ml_append_flags(lnum, uep->ue_array[i], 0, 0); // ML_APPEND_UNDO
|
||||||
}
|
}
|
||||||
xfree(uep->ue_array[i]);
|
xfree(uep->ue_array[i]);
|
||||||
}
|
}
|
||||||
@@ -2374,12 +2380,14 @@ static void u_undoredo(bool undo, bool do_buf_event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changed_lines(curbuf, top + 1, 0, bot, newsize - oldsize, do_buf_event);
|
if (oldsize > 0 || newsize > 0) {
|
||||||
// When text has been changed, possibly the start of the next line
|
changed_lines(curbuf, top + 1, 0, bot, newsize - oldsize, do_buf_event);
|
||||||
// may have SpellCap that should be removed or it needs to be
|
// When text has been changed, possibly the start of the next line
|
||||||
// displayed. Schedule the next line for redrawing just in case.
|
// may have SpellCap that should be removed or it needs to be
|
||||||
if (spell_check_window(curwin) && bot <= curbuf->b_ml.ml_line_count) {
|
// displayed. Schedule the next line for redrawing just in case.
|
||||||
redrawWinline(curwin, bot);
|
if (spell_check_window(curwin) && bot <= curbuf->b_ml.ml_line_count) {
|
||||||
|
redrawWinline(curwin, bot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the '[ mark.
|
// Set the '[ mark.
|
||||||
@@ -2425,6 +2433,10 @@ static void u_undoredo(bool undo, bool do_buf_event)
|
|||||||
}
|
}
|
||||||
// Finish adjusting extmarks
|
// Finish adjusting extmarks
|
||||||
|
|
||||||
|
// Set the cursor to the desired position. Check that the line is valid.
|
||||||
|
curwin->w_cursor = new_curpos;
|
||||||
|
check_cursor_lnum(curwin);
|
||||||
|
|
||||||
curhead->uh_entry = newlist;
|
curhead->uh_entry = newlist;
|
||||||
curhead->uh_flags = new_flags;
|
curhead->uh_flags = new_flags;
|
||||||
if ((old_flags & UH_EMPTYBUF) && buf_is_empty(curbuf)) {
|
if ((old_flags & UH_EMPTYBUF) && buf_is_empty(curbuf)) {
|
||||||
|
|||||||
@@ -2,10 +2,6 @@
|
|||||||
|
|
||||||
" Tests for the getjumplist() function
|
" Tests for the getjumplist() function
|
||||||
func Test_getjumplist()
|
func Test_getjumplist()
|
||||||
if !has("jumplist")
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
%bwipe
|
%bwipe
|
||||||
clearjumps
|
clearjumps
|
||||||
call assert_equal([[], 0], getjumplist())
|
call assert_equal([[], 0], getjumplist())
|
||||||
|
|||||||
Reference in New Issue
Block a user