move copy_indent (from nvim's indent.c)

This commit is contained in:
Daniel Hahler 2019-06-09 19:16:47 +02:00
parent e454dce5e4
commit b706b1f049
2 changed files with 91 additions and 237 deletions

View File

@ -800,149 +800,106 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
return OK; return OK;
} }
/* // Copy the indent from ptr to the current line (and fill to size).
* Copy the indent from ptr to the current line (and fill to size) // Leaves the cursor on the first non-blank in the line.
* Leaves the cursor on the first non-blank in the line. // @return true if the line was changed.
* Returns TRUE if the line was changed. int copy_indent(int size, char_u *src)
*/
static int
copy_indent(int size, char_u *src)
{ {
char_u *p = NULL; char_u *p = NULL;
char_u *line = NULL; char_u *line = NULL;
char_u *s; char_u *s;
int todo; int todo;
int ind_len; int ind_len;
int line_len = 0; int line_len = 0;
int tab_pad; int tab_pad;
int ind_done; int ind_done;
int round; int round;
#ifdef FEAT_VARTABS
int ind_col;
#endif
// Round 1: compute the number of characters needed for the indent // Round 1: compute the number of characters needed for the indent
// Round 2: copy the characters. // Round 2: copy the characters.
for (round = 1; round <= 2; ++round) for (round = 1; round <= 2; ++round) {
{ todo = size;
todo = size; ind_len = 0;
ind_len = 0; ind_done = 0;
ind_done = 0; s = src;
#ifdef FEAT_VARTABS
ind_col = 0;
#endif
s = src;
// Count/copy the usable portion of the source line // Count/copy the usable portion of the source line.
while (todo > 0 && VIM_ISWHITE(*s)) while (todo > 0 && ascii_iswhite(*s)) {
{ if (*s == TAB) {
if (*s == TAB) tab_pad = (int)curbuf->b_p_ts
{ - (ind_done % (int)curbuf->b_p_ts);
#ifdef FEAT_VARTABS
tab_pad = tabstop_padding(ind_done, curbuf->b_p_ts,
curbuf->b_p_vts_array);
#else
tab_pad = (int)curbuf->b_p_ts
- (ind_done % (int)curbuf->b_p_ts);
#endif
// Stop if this tab will overshoot the target
if (todo < tab_pad)
break;
todo -= tab_pad;
ind_done += tab_pad;
#ifdef FEAT_VARTABS
ind_col += tab_pad;
#endif
}
else
{
--todo;
++ind_done;
#ifdef FEAT_VARTABS
++ind_col;
#endif
}
++ind_len;
if (p != NULL)
*p++ = *s;
++s;
}
// Fill to next tabstop with a tab, if possible // Stop if this tab will overshoot the target.
#ifdef FEAT_VARTABS if (todo < tab_pad) {
tab_pad = tabstop_padding(ind_done, curbuf->b_p_ts, break;
curbuf->b_p_vts_array); }
#else todo -= tab_pad;
tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts); ind_done += tab_pad;
#endif } else {
if (todo >= tab_pad && !curbuf->b_p_et) todo--;
{ ind_done++;
todo -= tab_pad; }
++ind_len; ind_len++;
#ifdef FEAT_VARTABS
ind_col += tab_pad;
#endif
if (p != NULL)
*p++ = TAB;
}
// Add tabs required for indent if (p != NULL) {
if (!curbuf->b_p_et) *p++ = *s;
{ }
#ifdef FEAT_VARTABS s++;
for (;;)
{
tab_pad = tabstop_padding(ind_col, curbuf->b_p_ts,
curbuf->b_p_vts_array);
if (todo < tab_pad)
break;
todo -= tab_pad;
++ind_len;
ind_col += tab_pad;
if (p != NULL)
*p++ = TAB;
}
#else
while (todo >= (int)curbuf->b_p_ts)
{
todo -= (int)curbuf->b_p_ts;
++ind_len;
if (p != NULL)
*p++ = TAB;
}
#endif
}
// Count/add spaces required for indent
while (todo > 0)
{
--todo;
++ind_len;
if (p != NULL)
*p++ = ' ';
}
if (p == NULL)
{
// Allocate memory for the result: the copied indent, new indent
// and the rest of the line.
line_len = (int)STRLEN(ml_get_curline()) + 1;
line = alloc(ind_len + line_len);
if (line == NULL)
return FALSE;
p = line;
}
} }
// Append the original line // Fill to next tabstop with a tab, if possible.
mch_memmove(p, ml_get_curline(), (size_t)line_len); tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
// Replace the line if ((todo >= tab_pad) && !curbuf->b_p_et) {
ml_replace(curwin->w_cursor.lnum, line, FALSE); todo -= tab_pad;
ind_len++;
// Put the cursor after the indent. if (p != NULL) {
curwin->w_cursor.col = ind_len; *p++ = TAB;
return TRUE; }
}
// Add tabs required for indent.
while (todo >= (int)curbuf->b_p_ts && !curbuf->b_p_et) {
todo -= (int)curbuf->b_p_ts;
ind_len++;
if (p != NULL) {
*p++ = TAB;
}
}
// Count/add spaces required for indent.
while (todo > 0) {
todo--;
ind_len++;
if (p != NULL) {
*p++ = ' ';
}
}
if (p == NULL) {
// Allocate memory for the result: the copied indent, new indent
// and the rest of the line.
line_len = (int)STRLEN(get_cursor_line_ptr()) + 1;
assert(ind_len + line_len >= 0);
size_t line_size;
STRICT_ADD(ind_len, line_len, &line_size, size_t);
line = xmalloc(line_size);
p = line;
}
}
// Append the original line
memmove(p, get_cursor_line_ptr(), (size_t)line_len);
// Replace the line
ml_replace(curwin->w_cursor.lnum, line, false);
// Put the cursor after the indent.
curwin->w_cursor.col = ind_len;
return true;
} }
/* /*

View File

@ -316,109 +316,6 @@ int set_indent(int size, int flags)
} }
// Copy the indent from ptr to the current line (and fill to size).
// Leaves the cursor on the first non-blank in the line.
// @return true if the line was changed.
int copy_indent(int size, char_u *src)
{
char_u *p = NULL;
char_u *line = NULL;
char_u *s;
int todo;
int ind_len;
int line_len = 0;
int tab_pad;
int ind_done;
int round;
// Round 1: compute the number of characters needed for the indent
// Round 2: copy the characters.
for (round = 1; round <= 2; ++round) {
todo = size;
ind_len = 0;
ind_done = 0;
s = src;
// Count/copy the usable portion of the source line.
while (todo > 0 && ascii_iswhite(*s)) {
if (*s == TAB) {
tab_pad = (int)curbuf->b_p_ts
- (ind_done % (int)curbuf->b_p_ts);
// Stop if this tab will overshoot the target.
if (todo < tab_pad) {
break;
}
todo -= tab_pad;
ind_done += tab_pad;
} else {
todo--;
ind_done++;
}
ind_len++;
if (p != NULL) {
*p++ = *s;
}
s++;
}
// Fill to next tabstop with a tab, if possible.
tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
if ((todo >= tab_pad) && !curbuf->b_p_et) {
todo -= tab_pad;
ind_len++;
if (p != NULL) {
*p++ = TAB;
}
}
// Add tabs required for indent.
while (todo >= (int)curbuf->b_p_ts && !curbuf->b_p_et) {
todo -= (int)curbuf->b_p_ts;
ind_len++;
if (p != NULL) {
*p++ = TAB;
}
}
// Count/add spaces required for indent.
while (todo > 0) {
todo--;
ind_len++;
if (p != NULL) {
*p++ = ' ';
}
}
if (p == NULL) {
// Allocate memory for the result: the copied indent, new indent
// and the rest of the line.
line_len = (int)STRLEN(get_cursor_line_ptr()) + 1;
assert(ind_len + line_len >= 0);
size_t line_size;
STRICT_ADD(ind_len, line_len, &line_size, size_t);
line = xmalloc(line_size);
p = line;
}
}
// Append the original line
memmove(p, get_cursor_line_ptr(), (size_t)line_len);
// Replace the line
ml_replace(curwin->w_cursor.lnum, line, false);
// Put the cursor after the indent.
curwin->w_cursor.col = ind_len;
return true;
}
// Return the indent of the current line after a number. Return -1 if no // Return the indent of the current line after a number. Return -1 if no
// number was found. Used for 'n' in 'formatoptions': numbered list. // number was found. Used for 'n' in 'formatoptions': numbered list.
// Since a pattern is used it can actually handle more than numbers. // Since a pattern is used it can actually handle more than numbers.