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;
}
/*
* Copy the indent from ptr to the current line (and fill to size)
* Leaves the cursor on the first non-blank in the line.
* Returns TRUE if the line was changed.
*/
static int
copy_indent(int size, char_u *src)
// 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;
#ifdef FEAT_VARTABS
int ind_col;
#endif
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;
#ifdef FEAT_VARTABS
ind_col = 0;
#endif
s = src;
// 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 && VIM_ISWHITE(*s))
{
if (*s == TAB)
{
#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;
}
// 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);
// Fill to next tabstop with a tab, if possible
#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
if (todo >= tab_pad && !curbuf->b_p_et)
{
todo -= tab_pad;
++ind_len;
#ifdef FEAT_VARTABS
ind_col += tab_pad;
#endif
if (p != NULL)
*p++ = TAB;
}
// 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++;
// Add tabs required for indent
if (!curbuf->b_p_et)
{
#ifdef FEAT_VARTABS
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;
}
if (p != NULL) {
*p++ = *s;
}
s++;
}
// Append the original line
mch_memmove(p, ml_get_curline(), (size_t)line_len);
// Fill to next tabstop with a tab, if possible.
tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
// Replace the line
ml_replace(curwin->w_cursor.lnum, line, FALSE);
if ((todo >= tab_pad) && !curbuf->b_p_et) {
todo -= tab_pad;
ind_len++;
// Put the cursor after the indent.
curwin->w_cursor.col = ind_len;
return TRUE;
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;
}
/*

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
// number was found. Used for 'n' in 'formatoptions': numbered list.
// Since a pattern is used it can actually handle more than numbers.