mirror of
https://github.com/neovim/neovim.git
synced 2025-09-27 05:28:33 +00:00
move ins_char_bytes
This commit is contained in:
114
src/nvim/misc1.c
114
src/nvim/misc1.c
@@ -1398,120 +1398,6 @@ void ins_char(int c)
|
||||
ins_char_bytes(buf, n);
|
||||
}
|
||||
|
||||
void ins_char_bytes(char_u *buf, size_t charlen)
|
||||
{
|
||||
// Break tabs if needed.
|
||||
if (virtual_active() && curwin->w_cursor.coladd > 0) {
|
||||
coladvance_force(getviscol());
|
||||
}
|
||||
|
||||
size_t col = (size_t)curwin->w_cursor.col;
|
||||
linenr_T lnum = curwin->w_cursor.lnum;
|
||||
char_u *oldp = ml_get(lnum);
|
||||
size_t linelen = STRLEN(oldp) + 1; // length of old line including NUL
|
||||
|
||||
// The lengths default to the values for when not replacing.
|
||||
size_t oldlen = 0; // nr of bytes inserted
|
||||
size_t newlen = charlen; // nr of bytes deleted (0 when not replacing)
|
||||
|
||||
if (State & REPLACE_FLAG) {
|
||||
if (State & VREPLACE_FLAG) {
|
||||
// Disable 'list' temporarily, unless 'cpo' contains the 'L' flag.
|
||||
// Returns the old value of list, so when finished,
|
||||
// curwin->w_p_list should be set back to this.
|
||||
int old_list = curwin->w_p_list;
|
||||
if (old_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL) {
|
||||
curwin->w_p_list = false;
|
||||
}
|
||||
// In virtual replace mode each character may replace one or more
|
||||
// characters (zero if it's a TAB). Count the number of bytes to
|
||||
// be deleted to make room for the new character, counting screen
|
||||
// cells. May result in adding spaces to fill a gap.
|
||||
colnr_T vcol;
|
||||
getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL);
|
||||
colnr_T new_vcol = vcol + chartabsize(buf, vcol);
|
||||
while (oldp[col + oldlen] != NUL && vcol < new_vcol) {
|
||||
vcol += chartabsize(oldp + col + oldlen, vcol);
|
||||
// Don't need to remove a TAB that takes us to the right
|
||||
// position.
|
||||
if (vcol > new_vcol && oldp[col + oldlen] == TAB) {
|
||||
break;
|
||||
}
|
||||
oldlen += (size_t)(*mb_ptr2len)(oldp + col + oldlen);
|
||||
// Deleted a bit too much, insert spaces.
|
||||
if (vcol > new_vcol) {
|
||||
newlen += (size_t)(vcol - new_vcol);
|
||||
}
|
||||
}
|
||||
curwin->w_p_list = old_list;
|
||||
} else if (oldp[col] != NUL) {
|
||||
// normal replace
|
||||
oldlen = (size_t)(*mb_ptr2len)(oldp + col);
|
||||
}
|
||||
|
||||
|
||||
/* Push the replaced bytes onto the replace stack, so that they can be
|
||||
* put back when BS is used. The bytes of a multi-byte character are
|
||||
* done the other way around, so that the first byte is popped off
|
||||
* first (it tells the byte length of the character). */
|
||||
replace_push(NUL);
|
||||
for (size_t i = 0; i < oldlen; i++) {
|
||||
if (has_mbyte) {
|
||||
i += (size_t)replace_push_mb(oldp + col + i) - 1;
|
||||
} else {
|
||||
replace_push(oldp[col + i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char_u *newp = xmalloc((size_t)(linelen + newlen - oldlen));
|
||||
|
||||
// Copy bytes before the cursor.
|
||||
if (col > 0) {
|
||||
memmove(newp, oldp, (size_t)col);
|
||||
}
|
||||
|
||||
// Copy bytes after the changed character(s).
|
||||
char_u *p = newp + col;
|
||||
if (linelen > col + oldlen) {
|
||||
memmove(p + newlen, oldp + col + oldlen,
|
||||
(size_t)(linelen - col - oldlen));
|
||||
}
|
||||
|
||||
// Insert or overwrite the new character.
|
||||
memmove(p, buf, charlen);
|
||||
|
||||
// Fill with spaces when necessary.
|
||||
for (size_t i = charlen; i < newlen; i++) {
|
||||
p[i] = ' ';
|
||||
}
|
||||
|
||||
// Replace the line in the buffer.
|
||||
ml_replace(lnum, newp, false);
|
||||
|
||||
// mark the buffer as changed and prepare for displaying
|
||||
changed_bytes(lnum, (colnr_T)col);
|
||||
|
||||
/*
|
||||
* If we're in Insert or Replace mode and 'showmatch' is set, then briefly
|
||||
* show the match for right parens and braces.
|
||||
*/
|
||||
if (p_sm && (State & INSERT)
|
||||
&& msg_silent == 0
|
||||
&& !ins_compl_active()
|
||||
) {
|
||||
showmatch(utf_ptr2char(buf));
|
||||
}
|
||||
|
||||
if (!p_ri || (State & REPLACE_FLAG)) {
|
||||
// Normal insert: move cursor right
|
||||
curwin->w_cursor.col += (int)charlen;
|
||||
}
|
||||
/*
|
||||
* TODO: should try to update w_row here, to avoid recomputing it later.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a string at the cursor position.
|
||||
* Note: Does NOT handle Replace mode.
|
||||
|
Reference in New Issue
Block a user