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