diff --git a/src/textformat.c b/src/textformat.c
new file mode 100644
index 0000000..c50d70f
--- /dev/null
+++ b/src/textformat.c
@@ -0,0 +1,1088 @@
+/* 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)
+		cc = c;
+	    else
+		cc = gchar_cursor();
+	    if (WHITECHAR(cc))
+	    {
+		// remember position of blank just before text
+		end_col = curwin->w_cursor.col;
+
+		// find start of sequence of blanks
+		wcc = 0;
+		while (curwin->w_cursor.col > 0 && WHITECHAR(cc))
+		{
+		    dec_cursor();
+		    cc = gchar_cursor();
+
+		    // Increment count of how many whitespace chars in this
+		    // group; we only need to know if it's more than one.
+		    if (wcc < 2)
+		        wcc++;
+		}
+		if (curwin->w_cursor.col == 0 && WHITECHAR(cc))
+		    break;		// only spaces in front of text
+
+		// Don't break after a period when 'formatoptions' has 'p' and
+		// there are less than two spaces.
+		if (has_format_option(FO_PERIOD_ABBR) && cc == '.' && wcc < 2)
+		    continue;
+
+		// Don't break until after the comment leader
+		if (curwin->w_cursor.col < leader_len)
+		    break;
+		if (has_format_option(FO_ONE_LETTER))
+		{
+		    // do not break after one-letter words
+		    if (curwin->w_cursor.col == 0)
+			break;	// one-letter word at begin
+		    // do not break "#a b" when 'tw' is 2
+		    if (curwin->w_cursor.col <= leader_len)
+			break;
+		    col = curwin->w_cursor.col;
+		    dec_cursor();
+		    cc = gchar_cursor();
+
+		    if (WHITECHAR(cc))
+			continue;	// one-letter, continue
+		    curwin->w_cursor.col = col;
+		}
+
+		inc_cursor();
+
+		end_foundcol = end_col + 1;
+		foundcol = curwin->w_cursor.col;
+		if (curwin->w_cursor.col <= (colnr_T)wantcol)
+		    break;
+	    }
+	    else if (cc >= 0x100 && fo_multibyte)
+	    {
+		// Break after or before a multi-byte character.
+		if (curwin->w_cursor.col != startcol)
+		{
+		    // Don't break until after the comment leader
+		    if (curwin->w_cursor.col < leader_len)
+			break;
+		    col = curwin->w_cursor.col;
+		    inc_cursor();
+		    // Don't change end_foundcol if already set.
+		    if (foundcol != curwin->w_cursor.col)
+		    {
+			foundcol = curwin->w_cursor.col;
+			end_foundcol = foundcol;
+			if (curwin->w_cursor.col <= (colnr_T)wantcol)
+			    break;
+		    }
+		    curwin->w_cursor.col = col;
+		}
+
+		if (curwin->w_cursor.col == 0)
+		    break;
+
+		col = curwin->w_cursor.col;
+
+		dec_cursor();
+		cc = gchar_cursor();
+
+		if (WHITECHAR(cc))
+		    continue;		// break with space
+		// Don't break until after the comment leader
+		if (curwin->w_cursor.col < leader_len)
+		    break;
+
+		curwin->w_cursor.col = col;
+
+		foundcol = curwin->w_cursor.col;
+		end_foundcol = foundcol;
+		if (curwin->w_cursor.col <= (colnr_T)wantcol)
+		    break;
+	    }
+	    if (curwin->w_cursor.col == 0)
+		break;
+	    dec_cursor();
+	}
+
+	if (foundcol == 0)		// no spaces, cannot break line
+	{
+	    curwin->w_cursor.col = startcol;
+	    break;
+	}
+
+	// Going to break the line, remove any "$" now.
+	undisplay_dollar();
+
+	// Offset between cursor position and line break is used by replace
+	// stack functions.  VREPLACE does not use this, and backspaces
+	// over the text instead.
+	if (State & VREPLACE_FLAG)
+	    orig_col = startcol;	// Will start backspacing from here
+	else
+	    replace_offset = startcol - end_foundcol;
+
+	// adjust startcol for spaces that will be deleted and
+	// characters that will remain on top line
+	curwin->w_cursor.col = foundcol;
+	while ((cc = gchar_cursor(), WHITECHAR(cc))
+		    && (!fo_white_par || curwin->w_cursor.col < startcol))
+	    inc_cursor();
+	startcol -= curwin->w_cursor.col;
+	if (startcol < 0)
+	    startcol = 0;
+
+	if (State & VREPLACE_FLAG)
+	{
+	    // In VREPLACE mode, we will backspace over the text to be
+	    // wrapped, so save a copy now to put on the next line.
+	    saved_text = vim_strsave(ml_get_cursor());
+	    curwin->w_cursor.col = orig_col;
+	    if (saved_text == NULL)
+		break;	// Can't do it, out of memory
+	    saved_text[startcol] = NUL;
+
+	    // Backspace over characters that will move to the next line
+	    if (!fo_white_par)
+		backspace_until_column(foundcol);
+	}
+	else
+	{
+	    // put cursor after pos. to break line
+	    if (!fo_white_par)
+		curwin->w_cursor.col = foundcol;
+	}
+
+	// Split the line just before the margin.
+	// Only insert/delete lines, but don't really redraw the window.
+	open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX
+		+ (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
+		+ (do_comments ? OPENLINE_DO_COM : 0)
+		+ ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0)
+		, ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
+	if (!(flags & INSCHAR_COM_LIST))
+	    old_indent = 0;
+
+	replace_offset = 0;
+	if (first_line)
+	{
+	    if (!(flags & INSCHAR_COM_LIST))
+	    {
+		// This section is for auto-wrap of numeric lists.  When not
+		// in insert mode (i.e. format_lines()), the INSCHAR_COM_LIST
+		// flag will be set and open_line() will handle it (as seen
+		// above).  The code here (and in get_number_indent()) will
+		// recognize comments if needed...
+		if (second_indent < 0 && has_format_option(FO_Q_NUMBER))
+		    second_indent =
+				 get_number_indent(curwin->w_cursor.lnum - 1);
+		if (second_indent >= 0)
+		{
+		    if (State & VREPLACE_FLAG)
+			change_indent(INDENT_SET, second_indent,
+							    FALSE, NUL, TRUE);
+		    else
+			if (leader_len > 0 && second_indent - leader_len > 0)
+		    {
+			int i;
+			int padding = second_indent - leader_len;
+
+			// We started at the first_line of a numbered list
+			// that has a comment.  the open_line() function has
+			// inserted the proper comment leader and positioned
+			// the cursor at the end of the split line.  Now we
+			// add the additional whitespace needed after the
+			// comment leader for the numbered list.
+			for (i = 0; i < padding; i++)
+			    ins_str((char_u *)" ");
+		    }
+		    else
+		    {
+			(void)set_indent(second_indent, SIN_CHANGED);
+		    }
+		}
+	    }
+	    first_line = FALSE;
+	}
+
+	if (State & VREPLACE_FLAG)
+	{
+	    // In VREPLACE mode we have backspaced over the text to be
+	    // moved, now we re-insert it into the new line.
+	    ins_bytes(saved_text);
+	    vim_free(saved_text);
+	}
+	else
+	{
+	    // Check if cursor is not past the NUL off the line, cindent
+	    // may have added or removed indent.
+	    curwin->w_cursor.col += startcol;
+	    len = (colnr_T)STRLEN(ml_get_curline());
+	    if (curwin->w_cursor.col > len)
+		curwin->w_cursor.col = len;
+	}
+
+	haveto_redraw = TRUE;
+#ifdef FEAT_CINDENT
+	set_can_cindent(TRUE);
+#endif
+	// moved the cursor, don't autoindent or cindent now
+	did_ai = FALSE;
+#ifdef FEAT_SMARTINDENT
+	did_si = FALSE;
+	can_si = FALSE;
+	can_si_back = FALSE;
+#endif
+	line_breakcheck();
+    }
+
+    if (save_char != NUL)		// put back space after cursor
+	pchar_cursor(save_char);
+
+#ifdef FEAT_LINEBREAK
+    curwin->w_p_lbr = has_lbr;
+#endif
+    if (!format_only && haveto_redraw)
+    {
+	update_topline();
+	redraw_curbuf_later(VALID);
+    }
+}
+
+/*
+ * Blank lines, and lines containing only the comment leader, are left
+ * untouched by the formatting.  The function returns TRUE in this
+ * case.  It also returns TRUE when a line starts with the end of a comment
+ * ('e' in comment flags), so that this line is skipped, and not joined to the
+ * previous line.  A new paragraph starts after a blank line, or when the
+ * comment leader changes -- webb.
+ */
+    static int
+fmt_check_par(
+    linenr_T	lnum,
+    int		*leader_len,
+    char_u	**leader_flags,
+    int		do_comments)
+{
+    char_u	*flags = NULL;	    // init for GCC
+    char_u	*ptr;
+
+    ptr = ml_get(lnum);
+    if (do_comments)
+	*leader_len = get_leader_len(ptr, leader_flags, FALSE, TRUE);
+    else
+	*leader_len = 0;
+
+    if (*leader_len > 0)
+    {
+	// Search for 'e' flag in comment leader flags.
+	flags = *leader_flags;
+	while (*flags && *flags != ':' && *flags != COM_END)
+	    ++flags;
+    }
+
+    return (*skipwhite(ptr + *leader_len) == NUL
+	    || (*leader_len > 0 && *flags == COM_END)
+	    || startPS(lnum, NUL, FALSE));
+}
+
+/*
+ * Return TRUE if line "lnum" ends in a white character.
+ */
+    static int
+ends_in_white(linenr_T lnum)
+{
+    char_u	*s = ml_get(lnum);
+    size_t	l;
+
+    if (*s == NUL)
+	return FALSE;
+    // Don't use STRLEN() inside VIM_ISWHITE(), SAS/C complains: "macro
+    // invocation may call function multiple times".
+    l = STRLEN(s) - 1;
+    return VIM_ISWHITE(s[l]);
+}
+
+/*
+ * Return TRUE if the two comment leaders given are the same.  "lnum" is
+ * the first line.  White-space is ignored.  Note that the whole of
+ * 'leader1' must match 'leader2_len' characters from 'leader2' -- webb
+ */
+    static int
+same_leader(
+    linenr_T lnum,
+    int	    leader1_len,
+    char_u  *leader1_flags,
+    int	    leader2_len,
+    char_u  *leader2_flags)
+{
+    int	    idx1 = 0, idx2 = 0;
+    char_u  *p;
+    char_u  *line1;
+    char_u  *line2;
+
+    if (leader1_len == 0)
+	return (leader2_len == 0);
+
+    // If first leader has 'f' flag, the lines can be joined only if the
+    // second line does not have a leader.
+    // If first leader has 'e' flag, the lines can never be joined.
+    // If fist leader has 's' flag, the lines can only be joined if there is
+    // some text after it and the second line has the 'm' flag.
+    if (leader1_flags != NULL)
+    {
+	for (p = leader1_flags; *p && *p != ':'; ++p)
+	{
+	    if (*p == COM_FIRST)
+		return (leader2_len == 0);
+	    if (*p == COM_END)
+		return FALSE;
+	    if (*p == COM_START)
+	    {
+		if (*(ml_get(lnum) + leader1_len) == NUL)
+		    return FALSE;
+		if (leader2_flags == NULL || leader2_len == 0)
+		    return FALSE;
+		for (p = leader2_flags; *p && *p != ':'; ++p)
+		    if (*p == COM_MIDDLE)
+			return TRUE;
+		return FALSE;
+	    }
+	}
+    }
+
+    // Get current line and next line, compare the leaders.
+    // The first line has to be saved, only one line can be locked at a time.
+    line1 = vim_strsave(ml_get(lnum));
+    if (line1 != NULL)
+    {
+	for (idx1 = 0; VIM_ISWHITE(line1[idx1]); ++idx1)
+	    ;
+	line2 = ml_get(lnum + 1);
+	for (idx2 = 0; idx2 < leader2_len; ++idx2)
+	{
+	    if (!VIM_ISWHITE(line2[idx2]))
+	    {
+		if (line1[idx1++] != line2[idx2])
+		    break;
+	    }
+	    else
+		while (VIM_ISWHITE(line1[idx1]))
+		    ++idx1;
+	}
+	vim_free(line1);
+    }
+    return (idx2 == leader2_len && idx1 == leader1_len);
+}
+
+/*
+ * Return TRUE when a paragraph starts in line "lnum".  Return FALSE when the
+ * previous line is in the same paragraph.  Used for auto-formatting.
+ */
+    static int
+paragraph_start(linenr_T lnum)
+{
+    char_u	*p;
+    int		leader_len = 0;		// leader len of current line
+    char_u	*leader_flags = NULL;	// flags for leader of current line
+    int		next_leader_len;	// leader len of next line
+    char_u	*next_leader_flags;	// flags for leader of next line
+    int		do_comments;		// format comments
+
+    if (lnum <= 1)
+	return TRUE;		// start of the file
+
+    p = ml_get(lnum - 1);
+    if (*p == NUL)
+	return TRUE;		// after empty line
+
+    do_comments = has_format_option(FO_Q_COMS);
+    if (fmt_check_par(lnum - 1, &leader_len, &leader_flags, do_comments))
+	return TRUE;		// after non-paragraph line
+
+    if (fmt_check_par(lnum, &next_leader_len, &next_leader_flags, do_comments))
+	return TRUE;		// "lnum" is not a paragraph line
+
+    if (has_format_option(FO_WHITE_PAR) && !ends_in_white(lnum - 1))
+	return TRUE;		// missing trailing space in previous line.
+
+    if (has_format_option(FO_Q_NUMBER) && (get_number_indent(lnum) > 0))
+	return TRUE;		// numbered item starts in "lnum".
+
+    if (!same_leader(lnum - 1, leader_len, leader_flags,
+					  next_leader_len, next_leader_flags))
+	return TRUE;		// change of comment leader.
+
+    return FALSE;
+}
+
+/*
+ * Called after inserting or deleting text: When 'formatoptions' includes the
+ * 'a' flag format from the current line until the end of the paragraph.
+ * Keep the cursor at the same position relative to the text.
+ * The caller must have saved the cursor line for undo, following ones will be
+ * saved here.
+ */
+    void
+auto_format(
+    int		trailblank,	// when TRUE also format with trailing blank
+    int		prev_line)	// may start in previous line
+{
+    pos_T	pos;
+    colnr_T	len;
+    char_u	*old;
+    char_u	*new, *pnew;
+    int		wasatend;
+    int		cc;
+
+    if (!has_format_option(FO_AUTO))
+	return;
+
+    pos = curwin->w_cursor;
+    old = ml_get_curline();
+
+    // may remove added space
+    check_auto_format(FALSE);
+
+    // Don't format in Insert mode when the cursor is on a trailing blank, the
+    // user might insert normal text next.  Also skip formatting when "1" is
+    // in 'formatoptions' and there is a single character before the cursor.
+    // Otherwise the line would be broken and when typing another non-white
+    // next they are not joined back together.
+    wasatend = (pos.col == (colnr_T)STRLEN(old));
+    if (*old != NUL && !trailblank && wasatend)
+    {
+	dec_cursor();
+	cc = gchar_cursor();
+	if (!WHITECHAR(cc) && curwin->w_cursor.col > 0
+					  && has_format_option(FO_ONE_LETTER))
+	    dec_cursor();
+	cc = gchar_cursor();
+	if (WHITECHAR(cc))
+	{
+	    curwin->w_cursor = pos;
+	    return;
+	}
+	curwin->w_cursor = pos;
+    }
+
+    // With the 'c' flag in 'formatoptions' and 't' missing: only format
+    // comments.
+    if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP)
+				&& get_leader_len(old, NULL, FALSE, TRUE) == 0)
+	return;
+
+    // May start formatting in a previous line, so that after "x" a word is
+    // moved to the previous line if it fits there now.  Only when this is not
+    // the start of a paragraph.
+    if (prev_line && !paragraph_start(curwin->w_cursor.lnum))
+    {
+	--curwin->w_cursor.lnum;
+	if (u_save_cursor() == FAIL)
+	    return;
+    }
+
+    // Do the formatting and restore the cursor position.  "saved_cursor" will
+    // be adjusted for the text formatting.
+    saved_cursor = pos;
+    format_lines((linenr_T)-1, FALSE);
+    curwin->w_cursor = saved_cursor;
+    saved_cursor.lnum = 0;
+
+    if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+    {
+	// "cannot happen"
+	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+	coladvance((colnr_T)MAXCOL);
+    }
+    else
+	check_cursor_col();
+
+    // Insert mode: If the cursor is now after the end of the line while it
+    // previously wasn't, the line was broken.  Because of the rule above we
+    // need to add a space when 'w' is in 'formatoptions' to keep a paragraph
+    // formatted.
+    if (!wasatend && has_format_option(FO_WHITE_PAR))
+    {
+	new = ml_get_curline();
+	len = (colnr_T)STRLEN(new);
+	if (curwin->w_cursor.col == len)
+	{
+	    pnew = vim_strnsave(new, len + 2);
+	    pnew[len] = ' ';
+	    pnew[len + 1] = NUL;
+	    ml_replace(curwin->w_cursor.lnum, pnew, FALSE);
+	    // remove the space later
+	    did_add_space = TRUE;
+	}
+	else
+	    // may remove added space
+	    check_auto_format(FALSE);
+    }
+
+    check_cursor();
+}
+
+/*
+ * When an extra space was added to continue a paragraph for auto-formatting,
+ * delete it now.  The space must be under the cursor, just after the insert
+ * position.
+ */
+    void
+check_auto_format(
+    int		end_insert)	    // TRUE when ending Insert mode
+{
+    int		c = ' ';
+    int		cc;
+
+    if (did_add_space)
+    {
+	cc = gchar_cursor();
+	if (!WHITECHAR(cc))
+	    // Somehow the space was removed already.
+	    did_add_space = FALSE;
+	else
+	{
+	    if (!end_insert)
+	    {
+		inc_cursor();
+		c = gchar_cursor();
+		dec_cursor();
+	    }
+	    if (c != NUL)
+	    {
+		// The space is no longer at the end of the line, delete it.
+		del_char(FALSE);
+		did_add_space = FALSE;
+	    }
+	}
+    }
+}
+
+/*
+ * Find out textwidth to be used for formatting:
+ *	if 'textwidth' option is set, use it
+ *	else if 'wrapmargin' option is set, use curwin->w_width - 'wrapmargin'
+ *	if invalid value, use 0.
+ *	Set default to window width (maximum 79) for "gq" operator.
+ */
+    int
+comp_textwidth(
+    int		ff)	// force formatting (for "gq" command)
+{
+    int		textwidth;
+
+    textwidth = curbuf->b_p_tw;
+    if (textwidth == 0 && curbuf->b_p_wm)
+    {
+	// The width is the window width minus 'wrapmargin' minus all the
+	// things that add to the margin.
+	textwidth = curwin->w_width - curbuf->b_p_wm;
+#ifdef FEAT_CMDWIN
+	if (cmdwin_type != 0)
+	    textwidth -= 1;
+#endif
+#ifdef FEAT_FOLDING
+	textwidth -= curwin->w_p_fdc;
+#endif
+#ifdef FEAT_SIGNS
+	if (signcolumn_on(curwin))
+	    textwidth -= 1;
+#endif
+	if (curwin->w_p_nu || curwin->w_p_rnu)
+	    textwidth -= 8;
+    }
+    if (textwidth < 0)
+	textwidth = 0;
+    if (ff && textwidth == 0)
+    {
+	textwidth = curwin->w_width - 1;
+	if (textwidth > 79)
+	    textwidth = 79;
+    }
+    return textwidth;
+}
+
+/*
+ * Implementation of the format operator 'gq'.
+ */
+    void
+op_format(
+    oparg_T	*oap,
+    int		keep_cursor)		// keep cursor on same text char
+{
+    long	old_line_count = curbuf->b_ml.ml_line_count;
+
+    // Place the cursor where the "gq" or "gw" command was given, so that "u"
+    // can put it back there.
+    curwin->w_cursor = oap->cursor_start;
+
+    if (u_save((linenr_T)(oap->start.lnum - 1),
+				       (linenr_T)(oap->end.lnum + 1)) == FAIL)
+	return;
+    curwin->w_cursor = oap->start;
+
+    if (oap->is_VIsual)
+	// When there is no change: need to remove the Visual selection
+	redraw_curbuf_later(INVERTED);
+
+    if (!cmdmod.lockmarks)
+	// Set '[ mark at the start of the formatted area
+	curbuf->b_op_start = oap->start;
+
+    // For "gw" remember the cursor position and put it back below (adjusted
+    // for joined and split lines).
+    if (keep_cursor)
+	saved_cursor = oap->cursor_start;
+
+    format_lines(oap->line_count, keep_cursor);
+
+    // Leave the cursor at the first non-blank of the last formatted line.
+    // If the cursor was moved one line back (e.g. with "Q}") go to the next
+    // line, so "." will do the next lines.
+    if (oap->end_adjusted && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+	++curwin->w_cursor.lnum;
+    beginline(BL_WHITE | BL_FIX);
+    old_line_count = curbuf->b_ml.ml_line_count - old_line_count;
+    msgmore(old_line_count);
+
+    if (!cmdmod.lockmarks)
+	// put '] mark on the end of the formatted area
+	curbuf->b_op_end = curwin->w_cursor;
+
+    if (keep_cursor)
+    {
+	curwin->w_cursor = saved_cursor;
+	saved_cursor.lnum = 0;
+    }
+
+    if (oap->is_VIsual)
+    {
+	win_T	*wp;
+
+	FOR_ALL_WINDOWS(wp)
+	{
+	    if (wp->w_old_cursor_lnum != 0)
+	    {
+		// When lines have been inserted or deleted, adjust the end of
+		// the Visual area to be redrawn.
+		if (wp->w_old_cursor_lnum > wp->w_old_visual_lnum)
+		    wp->w_old_cursor_lnum += old_line_count;
+		else
+		    wp->w_old_visual_lnum += old_line_count;
+	    }
+	}
+    }
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Implementation of the format operator 'gq' for when using 'formatexpr'.
+ */
+    void
+op_formatexpr(oparg_T *oap)
+{
+    if (oap->is_VIsual)
+	// When there is no change: need to remove the Visual selection
+	redraw_curbuf_later(INVERTED);
+
+    if (fex_format(oap->start.lnum, oap->line_count, NUL) != 0)
+	// As documented: when 'formatexpr' returns non-zero fall back to
+	// internal formatting.
+	op_format(oap, FALSE);
+}
+
+    int
+fex_format(
+    linenr_T	lnum,
+    long	count,
+    int		c)	// character to be inserted
+{
+    int		use_sandbox = was_set_insecurely((char_u *)"formatexpr",
+								   OPT_LOCAL);
+    int		r;
+    char_u	*fex;
+
+    // Set v:lnum to the first line number and v:count to the number of lines.
+    // Set v:char to the character to be inserted (can be NUL).
+    set_vim_var_nr(VV_LNUM, lnum);
+    set_vim_var_nr(VV_COUNT, count);
+    set_vim_var_char(c);
+
+    // Make a copy, the option could be changed while calling it.
+    fex = vim_strsave(curbuf->b_p_fex);
+    if (fex == NULL)
+	return 0;
+
+    // Evaluate the function.
+    if (use_sandbox)
+	++sandbox;
+    r = (int)eval_to_number(fex);
+    if (use_sandbox)
+	--sandbox;
+
+    set_vim_var_string(VV_CHAR, NULL, -1);
+    vim_free(fex);
+
+    return r;
+}
+#endif
+
+/*
+ * Format "line_count" lines, starting at the cursor position.
+ * When "line_count" is negative, format until the end of the paragraph.
+ * Lines after the cursor line are saved for undo, caller must have saved the
+ * first line.
+ */
+    void
+format_lines(
+    linenr_T	line_count,
+    int		avoid_fex)		// don't use 'formatexpr'
+{
+    int		max_len;
+    int		is_not_par;		// current line not part of parag.
+    int		next_is_not_par;	// next line not part of paragraph
+    int		is_end_par;		// at end of paragraph
+    int		prev_is_end_par = FALSE;// prev. line not part of parag.
+    int		next_is_start_par = FALSE;
+    int		leader_len = 0;		// leader len of current line
+    int		next_leader_len;	// leader len of next line
+    char_u	*leader_flags = NULL;	// flags for leader of current line
+    char_u	*next_leader_flags;	// flags for leader of next line
+    int		do_comments;		// format comments
+    int		do_comments_list = 0;	// format comments with 'n' or '2'
+    int		advance = TRUE;
+    int		second_indent = -1;	// indent for second line (comment
+					// aware)
+    int		do_second_indent;
+    int		do_number_indent;
+    int		do_trail_white;
+    int		first_par_line = TRUE;
+    int		smd_save;
+    long	count;
+    int		need_set_indent = TRUE;	// set indent of next paragraph
+    int		force_format = FALSE;
+    int		old_State = State;
+
+    // length of a line to force formatting: 3 * 'tw'
+    max_len = comp_textwidth(TRUE) * 3;
+
+    // check for 'q', '2' and '1' in 'formatoptions'
+    do_comments = has_format_option(FO_Q_COMS);
+    do_second_indent = has_format_option(FO_Q_SECOND);
+    do_number_indent = has_format_option(FO_Q_NUMBER);
+    do_trail_white = has_format_option(FO_WHITE_PAR);
+
+    // Get info about the previous and current line.
+    if (curwin->w_cursor.lnum > 1)
+	is_not_par = fmt_check_par(curwin->w_cursor.lnum - 1
+				, &leader_len, &leader_flags, do_comments);
+    else
+	is_not_par = TRUE;
+    next_is_not_par = fmt_check_par(curwin->w_cursor.lnum
+			  , &next_leader_len, &next_leader_flags, do_comments);
+    is_end_par = (is_not_par || next_is_not_par);
+    if (!is_end_par && do_trail_white)
+	is_end_par = !ends_in_white(curwin->w_cursor.lnum - 1);
+
+    curwin->w_cursor.lnum--;
+    for (count = line_count; count != 0 && !got_int; --count)
+    {
+	// Advance to next paragraph.
+	if (advance)
+	{
+	    curwin->w_cursor.lnum++;
+	    prev_is_end_par = is_end_par;
+	    is_not_par = next_is_not_par;
+	    leader_len = next_leader_len;
+	    leader_flags = next_leader_flags;
+	}
+
+	// The last line to be formatted.
+	if (count == 1 || curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
+	{
+	    next_is_not_par = TRUE;
+	    next_leader_len = 0;
+	    next_leader_flags = NULL;
+	}
+	else
+	{
+	    next_is_not_par = fmt_check_par(curwin->w_cursor.lnum + 1
+			  , &next_leader_len, &next_leader_flags, do_comments);
+	    if (do_number_indent)
+		next_is_start_par =
+			   (get_number_indent(curwin->w_cursor.lnum + 1) > 0);
+	}
+	advance = TRUE;
+	is_end_par = (is_not_par || next_is_not_par || next_is_start_par);
+	if (!is_end_par && do_trail_white)
+	    is_end_par = !ends_in_white(curwin->w_cursor.lnum);
+
+	// Skip lines that are not in a paragraph.
+	if (is_not_par)
+	{
+	    if (line_count < 0)
+		break;
+	}
+	else
+	{
+	    // For the first line of a paragraph, check indent of second line.
+	    // Don't do this for comments and empty lines.
+	    if (first_par_line
+		    && (do_second_indent || do_number_indent)
+		    && prev_is_end_par
+		    && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+	    {
+		if (do_second_indent && !LINEEMPTY(curwin->w_cursor.lnum + 1))
+		{
+		    if (leader_len == 0 && next_leader_len == 0)
+		    {
+			// no comment found
+			second_indent =
+				   get_indent_lnum(curwin->w_cursor.lnum + 1);
+		    }
+		    else
+		    {
+			second_indent = next_leader_len;
+			do_comments_list = 1;
+		    }
+		}
+		else if (do_number_indent)
+		{
+		    if (leader_len == 0 && next_leader_len == 0)
+		    {
+			// no comment found
+			second_indent =
+				     get_number_indent(curwin->w_cursor.lnum);
+		    }
+		    else
+		    {
+			// get_number_indent() is now "comment aware"...
+			second_indent =
+				     get_number_indent(curwin->w_cursor.lnum);
+			do_comments_list = 1;
+		    }
+		}
+	    }
+
+	    // When the comment leader changes, it's the end of the paragraph.
+	    if (curwin->w_cursor.lnum >= curbuf->b_ml.ml_line_count
+		    || !same_leader(curwin->w_cursor.lnum,
+					leader_len, leader_flags,
+					   next_leader_len, next_leader_flags))
+		is_end_par = TRUE;
+
+	    // If we have got to the end of a paragraph, or the line is
+	    // getting long, format it.
+	    if (is_end_par || force_format)
+	    {
+		if (need_set_indent)
+		    // replace indent in first line with minimal number of
+		    // tabs and spaces, according to current options
+		    (void)set_indent(get_indent(), SIN_CHANGED);
+
+		// put cursor on last non-space
+		State = NORMAL;	// don't go past end-of-line
+		coladvance((colnr_T)MAXCOL);
+		while (curwin->w_cursor.col && vim_isspace(gchar_cursor()))
+		    dec_cursor();
+
+		// do the formatting, without 'showmode'
+		State = INSERT;	// for open_line()
+		smd_save = p_smd;
+		p_smd = FALSE;
+		insertchar(NUL, INSCHAR_FORMAT
+			+ (do_comments ? INSCHAR_DO_COM : 0)
+			+ (do_comments && do_comments_list
+						       ? INSCHAR_COM_LIST : 0)
+			+ (avoid_fex ? INSCHAR_NO_FEX : 0), second_indent);
+		State = old_State;
+		p_smd = smd_save;
+		second_indent = -1;
+		// at end of par.: need to set indent of next par.
+		need_set_indent = is_end_par;
+		if (is_end_par)
+		{
+		    // When called with a negative line count, break at the
+		    // end of the paragraph.
+		    if (line_count < 0)
+			break;
+		    first_par_line = TRUE;
+		}
+		force_format = FALSE;
+	    }
+
+	    // When still in same paragraph, join the lines together.  But
+	    // first delete the leader from the second line.
+	    if (!is_end_par)
+	    {
+		advance = FALSE;
+		curwin->w_cursor.lnum++;
+		curwin->w_cursor.col = 0;
+		if (line_count < 0 && u_save_cursor() == FAIL)
+		    break;
+		if (next_leader_len > 0)
+		{
+		    (void)del_bytes((long)next_leader_len, FALSE, FALSE);
+		    mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
+						    (long)-next_leader_len, 0);
+		}
+		else if (second_indent > 0)  // the "leader" for FO_Q_SECOND
+		{
+		    int indent = getwhitecols_curline();
+
+		    if (indent > 0)
+		    {
+			(void)del_bytes(indent, FALSE, FALSE);
+			mark_col_adjust(curwin->w_cursor.lnum,
+					       (colnr_T)0, 0L, (long)-indent, 0);
+		    }
+		}
+		curwin->w_cursor.lnum--;
+		if (do_join(2, TRUE, FALSE, FALSE, FALSE) == FAIL)
+		{
+		    beep_flush();
+		    break;
+		}
+		first_par_line = FALSE;
+		// If the line is getting long, format it next time
+		if (STRLEN(ml_get_curline()) > (size_t)max_len)
+		    force_format = TRUE;
+		else
+		    force_format = FALSE;
+	    }
+	}
+	line_breakcheck();
+    }
+}
