Skip to content

Commit

Permalink
Port vim's patch 7.4.388 ('breakindent')
Browse files Browse the repository at this point in the history
  • Loading branch information
fmoralesc committed Jun 26, 2014
1 parent 9f1b972 commit 76664d2
Show file tree
Hide file tree
Showing 14 changed files with 381 additions and 63 deletions.
7 changes: 7 additions & 0 deletions src/nvim/buffer_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ struct buffheader {
typedef struct {
int wo_arab;
# define w_p_arab w_onebuf_opt.wo_arab /* 'arabic' */
int wo_bri;
# define w_p_bri w_onebuf_opt.wo_bri /* 'breakindent' */
char_u *wo_briopt;
# define w_p_briopt w_onebuf_opt.wo_briopt /* 'breakindentopt' */
int wo_diff;
# define w_p_diff w_onebuf_opt.wo_diff /* 'diff' */
long wo_fdc;
Expand Down Expand Up @@ -1060,6 +1064,9 @@ struct window_S {
long_u w_p_fde_flags; /* flags for 'foldexpr' */
long_u w_p_fdt_flags; /* flags for 'foldtext' */
int *w_p_cc_cols; /* array of columns to highlight or NULL */
int w_p_brimin; /* minimum width for breakindent */
int w_p_brishift; /* additional shift for breakindent */
int w_p_brisbr; /* sbr in 'briopt' */

/* transform a pointer to a "onebuf" option into a "allbuf" option */
#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))
Expand Down
56 changes: 35 additions & 21 deletions src/nvim/charset.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "nvim/charset.h"
#include "nvim/farsi.h"
#include "nvim/func_attr.h"
#include "nvim/indent.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
Expand Down Expand Up @@ -778,27 +779,28 @@ int linetabsize(char_u *s)
int linetabsize_col(int startcol, char_u *s)
{
colnr_T col = startcol;
char_u *line = s; /* pointer to start of line, for breakindent */

while (*s != NUL) {
col += lbr_chartabsize_adv(&s, col);
col += lbr_chartabsize_adv(line, &s, col);
}
return (int)col;
}

/// Like linetabsize(), but for a given window instead of the current one.
///
/// @param wp
/// @param p
/// @param line
/// @param len
///
/// @return Number of characters the string will take on the screen.
int win_linetabsize(win_T *wp, char_u *p, colnr_T len)
int win_linetabsize(win_T *wp, char_u *line, colnr_T len)
{
colnr_T col = 0;
char_u *s;

for (s = p; *s != NUL && (len == MAXCOL || s < p + len); mb_ptr_adv(s)) {
col += win_lbr_chartabsize(wp, s, col, NULL);
for (s = line; *s != NUL && (len == MAXCOL || s < line + len); mb_ptr_adv(s)) {
col += win_lbr_chartabsize(wp, line, s, col, NULL);
}
return (int)col;
}
Expand Down Expand Up @@ -925,32 +927,34 @@ int vim_isprintc_strict(int c)

/// like chartabsize(), but also check for line breaks on the screen
///
/// @param line
/// @param s
/// @param col
///
/// @return The number of characters taken up on the screen.
int lbr_chartabsize(unsigned char *s, colnr_T col)
int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col)
{
if (!curwin->w_p_lbr && (*p_sbr == NUL)) {
if (!curwin->w_p_lbr && (*p_sbr == NUL) && !curwin->w_p_bri) {
if (curwin->w_p_wrap) {
return win_nolbr_chartabsize(curwin, s, col, NULL);
}
RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
}
return win_lbr_chartabsize(curwin, s, col, NULL);
return win_lbr_chartabsize(curwin, line == NULL ? s: line, s, col, NULL);
}

/// Call lbr_chartabsize() and advance the pointer.
///
/// @param line
/// @param s
/// @param col
///
/// @return The number of characters take up on the screen.
int lbr_chartabsize_adv(char_u **s, colnr_T col)
int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col)
{
int retval;

retval = lbr_chartabsize(*s, col);
retval = lbr_chartabsize(line, *s, col);
mb_ptr_adv(*s);
return retval;
}
Expand All @@ -962,12 +966,13 @@ int lbr_chartabsize_adv(char_u **s, colnr_T col)
/// value, init to 0 before calling.
///
/// @param wp
/// @param line
/// @param s
/// @param col
/// @param headp
///
/// @return The number of characters taken up on the screen.
int win_lbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *headp)
{
colnr_T col2;
colnr_T colmax;
Expand All @@ -978,8 +983,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
int tab_corr = (*s == TAB);
int n;

// No 'linebreak' and 'showbreak': return quickly.
if (!wp->w_p_lbr && (*p_sbr == NUL)) {
// No 'linebreak', 'showbreak' and 'breakindent': return quickly.
if (!wp->w_p_lbr && !wp->w_p_bri && (*p_sbr == NUL)) {
if (wp->w_p_wrap) {
return win_nolbr_chartabsize(wp, s, col, headp);
}
Expand Down Expand Up @@ -1042,11 +1047,12 @@ int win_lbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
mb_added = 1;
}

// May have to add something for 'showbreak' string at start of line
// May have to add something for 'breakindent' and/or 'showbreak'
// string at start of line.
// Set *headp to the size of what we add.
added = 0;

if ((*p_sbr != NUL) && wp->w_p_wrap && (col != 0)) {
if ((*p_sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && (col != 0)) {
numberextra = win_col_off(wp);
col += numberextra + mb_added;

Expand All @@ -1059,7 +1065,12 @@ int win_lbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
}

if ((col == 0) || (col + size > (colnr_T)wp->w_width)) {
added = vim_strsize(p_sbr);
added = 0;
if (*p_sbr != NUL)
added += vim_strsize(p_sbr);
if (wp->w_p_bri)
added += get_breakindent_win(wp, line);

if (tab_corr) {
size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
} else {
Expand Down Expand Up @@ -1160,13 +1171,14 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
colnr_T vcol;
char_u *ptr; // points to current char
char_u *posptr; // points to char at pos->col
char_u *line; // start of the line
int incr;
int head;
int ts = wp->w_buffer->b_p_ts;
int c;

vcol = 0;
ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);

if (pos->col == MAXCOL) {
// continue until the NUL
Expand All @@ -1176,11 +1188,13 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
}

// This function is used very often, do some speed optimizations.
// When 'list', 'linebreak' and 'showbreak' are not set use a simple loop.
// Also use this when 'list' is set but tabs take their normal size.
// When 'list', 'linebreak', 'showbreak' and 'breakindent' are not set
// use a simple loop.
// Also use this when 'list' is set but tabs take their normal size.
if ((!wp->w_p_list || (lcs_tab1 != NUL))
&& !wp->w_p_lbr
&& (*p_sbr == NUL)) {
&& (*p_sbr == NUL)
&& !wp->w_p_bri ) {
for (;;) {
head = 0;
c = *ptr;
Expand Down Expand Up @@ -1232,7 +1246,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
for (;;) {
// A tab gets expanded, depending on the current column
head = 0;
incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
incr = win_lbr_chartabsize(wp, line, ptr, vcol, &head);

// make sure we don't go past the end of the line
if (*ptr == NUL) {
Expand Down
2 changes: 1 addition & 1 deletion src/nvim/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ static int coladvance2(
ptr = line;
while (col <= wcol && *ptr != NUL) {
/* Count a tab for what it's worth (if list mode not on) */
csize = win_lbr_chartabsize(curwin, ptr, col, &head);
csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
mb_ptr_adv(ptr);
col += csize;
}
Expand Down
22 changes: 13 additions & 9 deletions src/nvim/edit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1546,7 +1546,7 @@ change_indent (
new_cursor_col += (*mb_ptr2len)(ptr + new_cursor_col);
else
++new_cursor_col;
vcol += lbr_chartabsize(ptr + new_cursor_col, (colnr_T)vcol);
vcol += lbr_chartabsize(ptr, ptr + new_cursor_col, (colnr_T)vcol);
}
vcol = last_vcol;

Expand Down Expand Up @@ -5884,9 +5884,11 @@ int oneleft(void)
width = 1;
for (;; ) {
coladvance(v - width);
/* getviscol() is slow, skip it when 'showbreak' is empty and
* there are no multi-byte characters */
/* getviscol() is slow, skip it when 'showbreak' is empty,
'breakindent' is not set and there are no multi-byte
characters */
if ((*p_sbr == NUL
&& !curwin->w_p_bri
&& !has_mbyte
) || getviscol() < v)
break;
Expand Down Expand Up @@ -7900,10 +7902,10 @@ static int ins_tab(void)
getvcol(curwin, &fpos, &vcol, NULL, NULL);
getvcol(curwin, cursor, &want_vcol, NULL, NULL);

/* Use as many TABs as possible. Beware of 'showbreak' and
* 'linebreak' adding extra virtual columns. */
/* Use as many TABs as possible. Beware of 'breakindent', 'showbreak'
and 'linebreak' adding extra virtual columns. */
while (vim_iswhite(*ptr)) {
i = lbr_chartabsize((char_u *)"\t", vcol);
i = lbr_chartabsize(NULL, (char_u *)"\t", vcol);
if (vcol + i > want_vcol)
break;
if (*ptr != TAB) {
Expand All @@ -7922,10 +7924,11 @@ static int ins_tab(void)

if (change_col >= 0) {
int repl_off = 0;
char_u *line = ptr;

/* Skip over the spaces we need. */
while (vcol < want_vcol && *ptr == ' ') {
vcol += lbr_chartabsize(ptr, vcol);
vcol += lbr_chartabsize(line, ptr, vcol);
++ptr;
++repl_off;
}
Expand Down Expand Up @@ -8112,6 +8115,7 @@ int ins_copychar(linenr_T lnum)
int c;
int temp;
char_u *ptr, *prev_ptr;
char_u *line;

if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) {
vim_beep();
Expand All @@ -8120,12 +8124,12 @@ int ins_copychar(linenr_T lnum)

/* try to advance to the cursor column */
temp = 0;
ptr = ml_get(lnum);
line = ptr = ml_get(lnum);
prev_ptr = ptr;
validate_virtcol();
while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL) {
prev_ptr = ptr;
temp += lbr_chartabsize_adv(&ptr, (colnr_T)temp);
temp += lbr_chartabsize_adv(line, &ptr, (colnr_T)temp);
}
if ((colnr_T)temp > curwin->w_virtcol)
ptr = prev_ptr;
Expand Down
8 changes: 4 additions & 4 deletions src/nvim/ex_getln.c
Original file line number Diff line number Diff line change
Expand Up @@ -1813,10 +1813,10 @@ getexmodeline (

p = (char_u *)line_ga.ga_data;
p[line_ga.ga_len] = NUL;
indent = get_indent_str(p, 8);
indent = get_indent_str(p, 8, FALSE);
indent += sw - indent % sw;
add_indent:
while (get_indent_str(p, 8) < indent) {
while (get_indent_str(p, 8, FALSE) < indent) {
char_u *s = skipwhite(p);

ga_grow(&line_ga, 1);
Expand Down Expand Up @@ -1854,11 +1854,11 @@ getexmodeline (
p[--line_ga.ga_len] = NUL;
} else {
p[line_ga.ga_len] = NUL;
indent = get_indent_str(p, 8);
indent = get_indent_str(p, 8, FALSE);
--indent;
indent -= indent % get_sw_value(curbuf);
}
while (get_indent_str(p, 8) > indent) {
while (get_indent_str(p, 8, FALSE) > indent) {
char_u *s = skipwhite(p);

memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
Expand Down
2 changes: 1 addition & 1 deletion src/nvim/getchar.c
Original file line number Diff line number Diff line change
Expand Up @@ -2161,7 +2161,7 @@ static int vgetorpeek(int advance)
while (col < curwin->w_cursor.col) {
if (!vim_iswhite(ptr[col]))
curwin->w_wcol = vcol;
vcol += lbr_chartabsize(ptr + col,
vcol += lbr_chartabsize(ptr, ptr + col,
(colnr_T)vcol);
if (has_mbyte)
col += (*mb_ptr2len)(ptr + col);
Expand Down

0 comments on commit 76664d2

Please sign in to comment.