aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/textformat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/textformat.c')
-rw-r--r--src/nvim/textformat.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c
index b69d438a59..bfe3ed5972 100644
--- a/src/nvim/textformat.c
+++ b/src/nvim/textformat.c
@@ -14,12 +14,10 @@
#include "nvim/eval.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
-#include "nvim/func_attr.h"
#include "nvim/getchar.h"
#include "nvim/globals.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
-#include "nvim/macros_defs.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
@@ -28,6 +26,7 @@
#include "nvim/move.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/option_defs.h"
#include "nvim/option_vars.h"
#include "nvim/os/input.h"
#include "nvim/pos_defs.h"
@@ -79,10 +78,10 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on
bool first_line = true;
colnr_T leader_len;
bool no_leader = false;
- int do_comments = (flags & INSCHAR_DO_COM);
+ bool do_comments = (flags & INSCHAR_DO_COM);
int has_lbr = curwin->w_p_lbr;
- // make sure win_lbr_chartabsize() counts correctly
+ // make sure win_charsize() counts correctly
curwin->w_p_lbr = false;
// When 'ai' is off we don't want a space under the cursor to be
@@ -102,17 +101,19 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on
int wantcol; // column at textwidth border
int foundcol; // column for start of spaces
int end_foundcol = 0; // column for start of word
- colnr_T virtcol;
int orig_col = 0;
char *saved_text = NULL;
colnr_T col;
- colnr_T end_col;
bool did_do_comment = false;
- virtcol = get_nolist_virtcol()
- + char2cells(c != NUL ? c : gchar_cursor());
- if (virtcol <= (colnr_T)textwidth) {
- break;
+ // Cursor is currently at the end of line. No need to format
+ // if line length is less than textwidth (8 * textwidth for
+ // utf safety)
+ if (curwin->w_cursor.col < 8 * textwidth) {
+ colnr_T virtcol = get_nolist_virtcol() + char2cells(c != NUL ? c : gchar_cursor());
+ if (virtcol <= (colnr_T)textwidth) {
+ break;
+ }
}
if (no_leader) {
@@ -160,9 +161,16 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on
coladvance((colnr_T)textwidth);
wantcol = curwin->w_cursor.col;
- curwin->w_cursor.col = startcol;
+ // If startcol is large (a long line), formatting takes too much
+ // time. The algorithm is O(n^2), it walks from the end of the
+ // line to textwidth border every time for each line break.
+ //
+ // Ceil to 8 * textwidth to optimize.
+ curwin->w_cursor.col = startcol < 8 * textwidth ? startcol : 8 * textwidth;
+
foundcol = 0;
int skip_pos = 0;
+ bool first_pass = true;
// Find position to break at.
// Stop at first entered white when 'formatoptions' has 'v'
@@ -170,14 +178,15 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on
|| (flags & INSCHAR_FORMAT)
|| curwin->w_cursor.lnum != Insstart.lnum
|| curwin->w_cursor.col >= Insstart.col) {
- if (curwin->w_cursor.col == startcol && c != NUL) {
+ if (first_pass && c != NUL) {
cc = c;
+ first_pass = false;
} else {
cc = gchar_cursor();
}
if (WHITECHAR(cc)) {
// remember position of blank just before text
- end_col = curwin->w_cursor.col;
+ colnr_T end_col = curwin->w_cursor.col;
// find start of sequence of blanks
int wcc = 0; // counter for whitespace chars
@@ -421,7 +430,7 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on
ins_str(" ");
}
} else {
- (void)set_indent(second_indent, SIN_CHANGED);
+ set_indent(second_indent, SIN_CHANGED);
}
}
}
@@ -474,9 +483,7 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on
static int fmt_check_par(linenr_T lnum, int *leader_len, char **leader_flags, bool do_comments)
{
char *flags = NULL; // init for GCC
- char *ptr;
-
- ptr = ml_get(lnum);
+ char *ptr = ml_get(lnum);
if (do_comments) {
*leader_len = get_leader_len(ptr, leader_flags, false, true);
} else {
@@ -626,8 +633,6 @@ static bool paragraph_start(linenr_T lnum)
/// @param prev_line may start in previous line
void auto_format(bool trailblank, bool prev_line)
{
- char *linep;
-
if (!has_format_option(FO_AUTO)) {
return;
}
@@ -679,7 +684,7 @@ void auto_format(bool trailblank, bool prev_line)
// 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);
+ format_lines(-1, false);
curwin->w_cursor = saved_cursor;
saved_cursor.lnum = 0;
@@ -696,7 +701,7 @@ void auto_format(bool trailblank, bool prev_line)
// need to add a space when 'w' is in 'formatoptions' to keep a paragraph
// formatted.
if (!wasatend && has_format_option(FO_WHITE_PAR)) {
- linep = get_cursor_line_ptr();
+ char *linep = get_cursor_line_ptr();
colnr_T len = (colnr_T)strlen(linep);
if (curwin->w_cursor.col == len) {
char *plinep = xstrnsave(linep, (size_t)len + 2);
@@ -758,11 +763,11 @@ int comp_textwidth(bool ff)
// The width is the window width minus 'wrapmargin' minus all the
// things that add to the margin.
textwidth = curwin->w_width_inner - (int)curbuf->b_p_wm;
- if (cmdwin_type != 0) {
+ if (curbuf == cmdwin_buf) {
textwidth -= 1;
}
textwidth -= win_fdccol_count(curwin);
- textwidth -= win_signcol_count(curwin);
+ textwidth -= curwin->w_scwidth;
if (curwin->w_p_nu || curwin->w_p_rnu) {
textwidth -= 8;
@@ -871,7 +876,7 @@ void op_formatexpr(oparg_T *oap)
/// @param c character to be inserted
int fex_format(linenr_T lnum, long count, int c)
{
- int use_sandbox = was_set_insecurely(curwin, "formatexpr", OPT_LOCAL);
+ bool use_sandbox = was_set_insecurely(curwin, kOptFormatexpr, OPT_LOCAL);
const sctx_T save_sctx = current_sctx;
// Set v:lnum to the first line number and v:count to the number of lines.
@@ -1054,7 +1059,7 @@ void format_lines(linenr_T line_count, bool avoid_fex)
indent = get_indent();
}
}
- (void)set_indent(indent, SIN_CHANGED);
+ set_indent(indent, SIN_CHANGED);
}
// put cursor on last non-space
@@ -1098,13 +1103,13 @@ void format_lines(linenr_T line_count, bool avoid_fex)
break;
}
if (next_leader_len > 0) {
- (void)del_bytes(next_leader_len, false, false);
+ del_bytes(next_leader_len, false, false);
mark_col_adjust(curwin->w_cursor.lnum, 0, 0, -next_leader_len, 0);
} else if (second_indent > 0) { // the "leader" for FO_Q_SECOND
int indent = (int)getwhitecols_curline();
if (indent > 0) {
- (void)del_bytes(indent, false, false);
+ del_bytes(indent, false, false);
mark_col_adjust(curwin->w_cursor.lnum, 0, 0, -indent, 0);
}
}