/* vi:set ts=8 sts=4 sw=4 noet:
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
* See README.txt for an overview of the Vim source code.
*/
/*
* textformat.c: text formatting functions
*/
#include "vim.h"
static int did_add_space = FALSE; // auto_format() added an extra space
// under the cursor
#define WHITECHAR(cc) (VIM_ISWHITE(cc) && (!enc_utf8 || !utf_iscomposing(utf_ptr2char(ml_get_cursor() + 1))))
/*
* Return TRUE if format option 'x' is in effect.
* Take care of no formatting when 'paste' is set.
*/
int
has_format_option(int x)
{
if (p_paste)
return FALSE;
return (vim_strchr(curbuf->b_p_fo, x) != NULL);
}
/*
* Format text at the current insert position.
*
* If the INSCHAR_COM_LIST flag is present, then the value of second_indent
* will be the comment leader length sent to open_line().
*/
void
internal_format(
int textwidth,
int second_indent,
int flags,
int format_only,
int c) // character to be inserted (can be NUL)
{
int cc;
int save_char = NUL;
int haveto_redraw = FALSE;
int fo_ins_blank = has_format_option(FO_INS_BLANK);
int fo_multibyte = has_format_option(FO_MBYTE_BREAK);
int fo_white_par = has_format_option(FO_WHITE_PAR);
int first_line = TRUE;
colnr_T leader_len;
int no_leader = FALSE;
int do_comments = (flags & INSCHAR_DO_COM);
#ifdef FEAT_LINEBREAK
int has_lbr = curwin->w_p_lbr;
// make sure win_lbr_chartabsize() counts correctly
curwin->w_p_lbr = FALSE;
#endif
// When 'ai' is off we don't want a space under the cursor to be
// deleted. Replace it with an 'x' temporarily.
if (!curbuf->b_p_ai && !(State & VREPLACE_FLAG))
{
cc = gchar_cursor();
if (VIM_ISWHITE(cc))
{
save_char = cc;
pchar_cursor('x');
}
}
// Repeat breaking lines, until the current line is not too long.
while (!got_int)
{
int startcol; // Cursor column at entry
int wantcol; // column at textwidth border
int foundcol; // column for start of spaces
int end_foundcol = 0; // column for start of word
colnr_T len;
colnr_T virtcol;
int orig_col = 0;
char_u *saved_text = NULL;
colnr_T col;
colnr_T end_col;
int wcc; // counter for whitespace chars
virtcol = get_nolist_virtcol()
+ char2cells(c != NUL ? c : gchar_cursor());
if (virtcol <= (colnr_T)textwidth)
break;
if (no_leader)
do_comments = FALSE;
else if (!(flags & INSCHAR_FORMAT)
&& has_format_option(FO_WRAP_COMS))
do_comments = TRUE;
// Don't break until after the comment leader
if (do_comments)
leader_len = get_leader_len(ml_get_curline(), NULL, FALSE, TRUE);
else
leader_len = 0;
// If the line doesn't start with a comment leader, then don't
// start one in a following broken line. Avoids that a %word
// moved to the start of the next line causes all following lines
// to start with %.
if (leader_len == 0)
no_leader = TRUE;
if (!(flags & INSCHAR_FORMAT)
&& leader_len == 0
&& !has_format_option(FO_WRAP))
break;
if ((startcol = curwin->w_cursor.col) == 0)
break;
// find column of textwidth border
coladvance((colnr_T)textwidth);
wantcol = curwin->w_cursor.col;
curwin->w_cursor.col = startcol;
foundcol = 0;
// Find position to break at.
// Stop at first entered white when 'formatoptions' has 'v'
while ((!fo_ins_blank && !has_format_option(FO_INS_VI))
|| (flags & INSCHAR_FORMAT)
|| curwin->w_cursor.lnum != Insstart.lnum
|| curwin->w_cursor.col >= Insstart.col)
{
if (curwin->w_cursor.col == startcol && c != NUL