aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/charset.c
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2014-08-20 12:24:34 -0400
committerJustin M. Keyes <justinkz@gmail.com>2014-08-20 12:24:34 -0400
commit118a31c24c7ce76da909026cd10a94feb88803bc (patch)
tree8bbd708d924ef68017949e4bf9b773d5d833b82d /src/nvim/charset.c
parentbbefc73c553d681f78f40df9d97ec89ae9b06520 (diff)
parent3b0f7fe59392138c886063b09e3cf41b25d53056 (diff)
downloadrneovim-118a31c24c7ce76da909026cd10a94feb88803bc.tar.gz
rneovim-118a31c24c7ce76da909026cd10a94feb88803bc.tar.bz2
rneovim-118a31c24c7ce76da909026cd10a94feb88803bc.zip
Merge pull request #691 from fmoralesc/master
Port vim's breakindent patch to neovim's codebase. (vim patches 7.4.338, 7.4.346, 7.4.352, 7.4.353, 7.4.370, 7.4.371, 7.4.388)
Diffstat (limited to 'src/nvim/charset.c')
-rw-r--r--src/nvim/charset.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index baf6895b4c..57c4aec395 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -13,6 +13,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"
@@ -775,9 +776,10 @@ 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;
}
@@ -785,17 +787,17 @@ int linetabsize_col(int startcol, char_u *s)
/// 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;
}
@@ -922,32 +924,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;
}
@@ -959,14 +963,16 @@ 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 col_adj = 0; /* col + screen size of tab */
colnr_T colmax;
int added;
int mb_added = 0;
@@ -975,8 +981,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);
}
@@ -986,26 +992,29 @@ int win_lbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
// First get normal size, without 'linebreak'
int size = win_chartabsize(wp, s, col);
int c = *s;
+ if (tab_corr) {
+ col_adj = size - 1;
+ }
// If 'linebreak' set check at a blank before a non-blank if the line
// needs a break here
if (wp->w_p_lbr
&& vim_isbreak(c)
&& !vim_isbreak(s[1])
- && !wp->w_p_list
&& wp->w_p_wrap
&& (wp->w_width != 0)) {
// Count all characters from first non-blank after a blank up to next
// non-blank after a blank.
numberextra = win_col_off(wp);
col2 = col;
- colmax = (colnr_T)(wp->w_width - numberextra);
+ colmax = (colnr_T)(wp->w_width - numberextra - col_adj);
if (col >= colmax) {
- n = colmax + win_col_off2(wp);
+ colmax += col_adj;
+ n = colmax + win_col_off2(wp);
if (n > 0) {
- colmax += (((col - colmax) / n) + 1) * n;
+ colmax += (((col - colmax) / n) + 1) * n - col_adj;
}
}
@@ -1024,7 +1033,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
col2 += win_chartabsize(wp, s, col2);
if (col2 >= colmax) { /* doesn't fit */
- size = colmax - col;
+ size = colmax - col + col_adj;
tab_corr = FALSE;
break;
}
@@ -1039,11 +1048,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;
@@ -1056,7 +1066,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 {
@@ -1157,13 +1172,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
@@ -1173,11 +1189,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;
@@ -1229,7 +1247,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) {