Added 'colorcolumn' option. Partly by Gregor Uhlenheuer.
diff --git a/src/option.c b/src/option.c
index ac16d79..2dfb6d9 100644
--- a/src/option.c
+++ b/src/option.c
@@ -232,6 +232,7 @@
#ifdef FEAT_SYN_HL
# define PV_CUC OPT_WIN(WV_CUC)
# define PV_CUL OPT_WIN(WV_CUL)
+# define PV_CC OPT_WIN(WV_CC)
#endif
#ifdef FEAT_STL_OPT
# define PV_STL OPT_BOTH(OPT_WIN(WV_STL))
@@ -466,7 +467,7 @@
#if defined(FEAT_DIFF) || defined(FEAT_FOLDING) || defined(FEAT_SPELL) \
|| defined(FEAT_VERTSPLIT) || defined(FEAT_CLIPBOARD) \
|| defined(FEAT_INS_EXPAND) || defined(FEAT_SYN_HL) || defined(FEAT_CONCEAL)
-# define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine"
+# define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn"
#else
# define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,t:Title,v:Visual,w:WarningMsg,W:WildMenu,>:SignColumn,*:TabLine,#:TabLineSel,_:TabLineFill"
#endif
@@ -774,6 +775,13 @@
(char_u *)NULL, PV_NONE,
#endif
{(char_u *)7L, (char_u *)0L} SCRIPTID_INIT},
+ {"colorcolumn", "cc", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_RWIN,
+#ifdef FEAT_SYN_HL
+ (char_u *)VAR_WIN, PV_CC,
+#else
+ (char_u *)NULL, PV_NONE,
+#endif
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
{"columns", "co", P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR,
(char_u *)&Columns, PV_NONE,
{(char_u *)80L, (char_u *)0L} SCRIPTID_INIT},
@@ -2526,7 +2534,7 @@
(char_u *)FALSE,
#endif
(char_u *)0L} SCRIPTID_INIT},
- {"textwidth", "tw", P_NUM|P_VI_DEF|P_VIM,
+ {"textwidth", "tw", P_NUM|P_VI_DEF|P_VIM|P_RBUF,
(char_u *)&p_tw, PV_TW,
{(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
{"thesaurus", "tsr", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
@@ -2975,6 +2983,9 @@
static void set_string_option __ARGS((int opt_idx, char_u *value, int opt_flags));
static char_u *did_set_string_option __ARGS((int opt_idx, char_u **varp, int new_value_alloced, char_u *oldval, char_u *errbuf, int opt_flags));
static char_u *set_chars_option __ARGS((char_u **varp));
+#ifdef FEAT_SYN_HL
+static int int_cmp __ARGS((const void *a, const void *b));
+#endif
#ifdef FEAT_CLIPBOARD
static char_u *check_clipboard_option __ARGS((void));
#endif
@@ -5638,6 +5649,12 @@
}
}
+#ifdef FEAT_SYN_HL
+ /* 'colorcolumn' */
+ else if (varp == &curwin->w_p_cc)
+ errmsg = check_colorcolumn(curwin);
+#endif
+
#ifdef FEAT_MULTI_LANG
/* 'helplang' */
else if (varp == &p_hlg)
@@ -6911,6 +6928,85 @@
return errmsg;
}
+#ifdef FEAT_SYN_HL
+/*
+ * Simple int comparison function for use with qsort()
+ */
+ static int
+int_cmp(a, b)
+ const void *a;
+ const void *b;
+{
+ return *(const int *)a - *(const int *)b;
+}
+
+/*
+ * Handle setting 'colorcolumn' or 'textwidth' in window "wp".
+ * Returns error message, NULL if it's OK.
+ */
+ char_u *
+check_colorcolumn(wp)
+ win_T *wp;
+{
+ char_u *s;
+ int col;
+ int count = 0;
+ int color_cols[256];
+ int i;
+ int j = 0;
+
+ for (s = wp->w_p_cc; *s != NUL && count < 255; ++s)
+ {
+ if (*s == '-' || *s == '+')
+ {
+ /* -N and +N: add to 'textwidth' */
+ col = (*s == '-') ? -1 : 1;
+ ++s;
+ if (!VIM_ISDIGIT(*s))
+ return e_invarg;
+ col = col * getdigits(&s);
+ if (wp->w_buffer->b_p_tw == 0)
+ continue; /* 'textwidth' not set, skip this item */
+ col += wp->w_buffer->b_p_tw;
+ if (col < 0)
+ continue;
+ }
+ else if (VIM_ISDIGIT(*s))
+ col = getdigits(&s);
+ else
+ return e_invarg;
+ color_cols[count++] = col - 1; /* 1-based to 0-based */
+
+ if (*s == NUL)
+ break;
+ if (*s != ',')
+ return e_invarg;
+ }
+
+ vim_free(wp->w_p_cc_cols);
+ if (count == 0)
+ wp->w_p_cc_cols = NULL;
+ else
+ {
+ wp->w_p_cc_cols = (int *)alloc((unsigned)sizeof(int) * (count + 1));
+ if (wp->w_p_cc_cols != NULL)
+ {
+ /* sort the columns for faster usage on screen redraw inside
+ * win_line() */
+ qsort(color_cols, count, sizeof(int), int_cmp);
+
+ for (i = 0; i < count; ++i)
+ /* skip duplicates */
+ if (j == 0 || wp->w_p_cc_cols[j - 1] != color_cols[i])
+ wp->w_p_cc_cols[j++] = color_cols[i];
+ wp->w_p_cc_cols[j] = -1; /* end marker */
+ }
+ }
+
+ return NULL; /* no error */
+}
+#endif
+
/*
* Handle setting 'listchars' or 'fillchars'.
* Returns error message, NULL if it's OK.
@@ -8179,6 +8275,28 @@
}
#endif
+ else if (pp == &curbuf->b_p_tw)
+ {
+ if (curbuf->b_p_tw < 0)
+ {
+ errmsg = e_positive;
+ curbuf->b_p_tw = 0;
+ }
+#ifdef FEAT_SYN_HL
+# ifdef FEAT_WINDOWS
+ {
+ win_T *wp;
+ tabpage_T *tp;
+
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ check_colorcolumn(wp);
+ }
+# else
+ check_colorcolumn(curwin);
+# endif
+#endif
+ }
+
/*
* Check the bounds for numeric options here
*/
@@ -8251,11 +8369,6 @@
errmsg = e_positive;
curbuf->b_p_ts = 8;
}
- if (curbuf->b_p_tw < 0)
- {
- errmsg = e_positive;
- curbuf->b_p_tw = 0;
- }
if (p_tm < 0)
{
errmsg = e_positive;
@@ -9341,6 +9454,7 @@
#ifdef FEAT_SYN_HL
case PV_CUC: return (char_u *)&(curwin->w_p_cuc);
case PV_CUL: return (char_u *)&(curwin->w_p_cul);
+ case PV_CC: return (char_u *)&(curwin->w_p_cc);
#endif
#ifdef FEAT_DIFF
case PV_DIFF: return (char_u *)&(curwin->w_p_diff);
@@ -9582,6 +9696,7 @@
#ifdef FEAT_SYN_HL
to->wo_cuc = from->wo_cuc;
to->wo_cul = from->wo_cul;
+ to->wo_cc = vim_strsave(from->wo_cc);
#endif
#ifdef FEAT_DIFF
to->wo_diff = from->wo_diff;
@@ -9636,6 +9751,9 @@
#ifdef FEAT_STL_OPT
check_string_option(&wop->wo_stl);
#endif
+#ifdef FEAT_SYN_HL
+ check_string_option(&wop->wo_cc);
+#endif
}
/*
@@ -9660,6 +9778,9 @@
#ifdef FEAT_STL_OPT
clear_string_option(&wop->wo_stl);
#endif
+#ifdef FEAT_SYN_HL
+ clear_string_option(&wop->wo_cc);
+#endif
}
/*
@@ -9682,7 +9803,7 @@
int did_isk = FALSE;
/*
- * Don't do anything of the buffer is invalid.
+ * Don't do anything if the buffer is invalid.
*/
if (buf == NULL || !buf_valid(buf))
return;
diff --git a/src/option.h b/src/option.h
index 08f1f4b..1693622 100644
--- a/src/option.h
+++ b/src/option.h
@@ -589,6 +589,10 @@
EXTERN char_u *p_mef; /* 'makeef' */
EXTERN char_u *p_mp; /* 'makeprg' */
#endif
+#ifdef FEAT_SYN_HL
+EXTERN char_u *p_cc; /* 'colorcolumn' */
+EXTERN int p_cc_cols[256]; /* array for 'colorcolumn' columns */
+#endif
EXTERN long p_mat; /* 'matchtime' */
#ifdef FEAT_MBYTE
EXTERN long p_mco; /* 'maxcombine' */
@@ -1069,6 +1073,7 @@
#ifdef FEAT_SYN_HL
, WV_CUC
, WV_CUL
+ , WV_CC
#endif
#ifdef FEAT_STL_OPT
, WV_STL
diff --git a/src/os_macosx.m b/src/os_macosx.m
index dcde551..619e86d 100644
--- a/src/os_macosx.m
+++ b/src/os_macosx.m
@@ -544,75 +544,6 @@
}
#endif /* MACOS_X_ICONVEMU */
-#ifdef USE_MCH_GETTEXT
-
-#define GETTEXT_BUFNUM 64
-#define GETTEXT_BUFSIZE 256
-
- char *
-mch_gettext(const char *msgid)
-{
- static char buf[GETTEXT_BUFNUM][GETTEXT_BUFSIZE];
- static int bufnum = 0;
- const char *msg = NULL;
- CFStringRef strkey = NULL, strmsg = NULL;
- CFStringEncoding enc;
-
- if (!msgid)
- goto MCH_GETTEXT_FINISH;
- enc = CFStringGetSystemEncoding();
- TRACE("mch_gettext(%s)\n", msgid);
-
- strkey = CFStringCreateWithCString(NULL, msgid, enc);
- if (!strkey)
- {
- TRACE(" Can't create a CFString for msgid.\n");
- goto MCH_GETTEXT_FINISH;
- }
-
- strmsg = CFCopyLocalizedString(strkey, NULL);
- if (!strmsg)
- {
- TRACE(" No localized strings for msgid.\n");
- goto MCH_GETTEXT_FINISH;
- }
-
- msg = CFStringGetCStringPtr(strmsg, enc);
- if (!msg)
- {
- /* This is as backup when CFStringGetCStringPtr was failed */
- CFStringGetCString(strmsg, buf[bufnum], GETTEXT_BUFSIZE, enc);
- msg = buf[bufnum];
- if (++bufnum >= GETTEXT_BUFNUM)
- bufnum = 0;
- }
- TRACE(" Localized to: %s\n", msg);
-
-MCH_GETTEXT_FINISH:
- if (strkey)
- CFRelease(strkey);
- if (strmsg)
- CFRelease(strmsg);
- return (char *)(msg ? msg : msgid);
-}
-
- char *
-mch_bindtextdomain(const char *domain, const char *dirname)
-{
- TRACE("mch_bindtextdomain(%s, %s)\n", domain, dirname);
- return (char*)dirname;
-}
-
- char *
-mch_textdomain(const char *domain)
-{
- TRACE("mch_textdomain(%s)\n", domain);
- return (char*)domain;
-}
-#endif
-
-
-
#ifdef FEAT_CLIPBOARD
void
diff --git a/src/proto/option.pro b/src/proto/option.pro
index 9c58c3e..d14c89b 100644
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -19,6 +19,7 @@
void set_term_option_alloced __ARGS((char_u **p));
int was_set_insecurely __ARGS((char_u *opt, int opt_flags));
void set_string_option_direct __ARGS((char_u *name, int opt_idx, char_u *val, int opt_flags, int set_sid));
+char_u *check_colorcolumn __ARGS((win_T *wp));
char_u *check_stl_option __ARGS((char_u *s));
int get_option_value __ARGS((char_u *name, long *numval, char_u **stringval, int opt_flags));
void set_option_value __ARGS((char_u *name, long number, char_u *string, int opt_flags));
diff --git a/src/screen.c b/src/screen.c
index 3df7f66..0a2b9a9 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -2126,6 +2126,23 @@
set_empty_rows(wp, row);
}
+#ifdef FEAT_SYN_HL
+static int advance_color_col __ARGS((int vcol, int **color_cols));
+
+/*
+ * Advance **color_cols and return TRUE when there are columns to draw.
+ */
+ static int
+advance_color_col(vcol, color_cols)
+ int vcol;
+ int **color_cols;
+{
+ while (**color_cols >= 0 && vcol > **color_cols)
+ ++*color_cols;
+ return (**color_cols >= 0);
+}
+#endif
+
#ifdef FEAT_FOLDING
/*
* Display one folded line.
@@ -2666,6 +2683,8 @@
int has_syntax = FALSE; /* this buffer has syntax highl. */
int save_did_emsg;
int eol_hl_off = 0; /* 1 if highlighted char after EOL */
+ int draw_color_col = FALSE; /* highlight colorcolumn */
+ int *color_cols = NULL; /* pointer to according columns array */
#endif
#ifdef FEAT_SPELL
int has_spell = FALSE; /* this buffer has spell checking */
@@ -2795,6 +2814,11 @@
extra_check = TRUE;
}
}
+
+ /* Check for columns to display for 'colorcolumn'. */
+ color_cols = wp->w_p_cc_cols;
+ if (color_cols != NULL)
+ draw_color_col = advance_color_col(vcol, &color_cols);
#endif
#ifdef FEAT_SPELL
@@ -3073,6 +3097,7 @@
#if defined(FEAT_SYN_HL) || defined(FEAT_VIRTUALEDIT) || defined(FEAT_VISUAL)
/* When:
* - 'cuc' is set, or
+ * - 'colorcolumn' is set, or
* - 'virtualedit' is set, or
* - the visual mode is active,
* the end of the line may be before the start of the displayed part.
@@ -3080,6 +3105,7 @@
if (vcol < v && (
# ifdef FEAT_SYN_HL
wp->w_p_cuc
+ || draw_color_col
# if defined(FEAT_VIRTUALEDIT) || defined(FEAT_VISUAL)
||
# endif
@@ -4641,25 +4667,41 @@
--vcol;
}
- /* Highlight 'cursorcolumn' past end of the line. */
+ /* Highlight 'cursorcolumn' & 'colorcolumn' past end of the line. */
if (wp->w_p_wrap)
v = wp->w_skipcol;
else
v = wp->w_leftcol;
+
/* check if line ends before left margin */
if (vcol < v + col - win_col_off(wp))
-
vcol = v + col - win_col_off(wp);
- if (wp->w_p_cuc
- && (int)wp->w_virtcol >= vcol - eol_hl_off
- && (int)wp->w_virtcol < W_WIDTH(wp) * (row - startrow + 1)
+
+ if (draw_color_col)
+ draw_color_col = advance_color_col(vcol, &color_cols);
+
+ if (((wp->w_p_cuc
+ && (int)wp->w_virtcol >= vcol - eol_hl_off
+ && (int)wp->w_virtcol < W_WIDTH(wp) * (row - startrow + 1)
+ v
- && lnum != wp->w_cursor.lnum
+ && lnum != wp->w_cursor.lnum)
+ || draw_color_col)
# ifdef FEAT_RIGHTLEFT
&& !wp->w_p_rl
# endif
)
{
+ int rightmost_vcol = 0;
+ int i;
+
+ if (wp->w_p_cuc)
+ rightmost_vcol = wp->w_virtcol;
+ if (draw_color_col)
+ /* determine rightmost colorcolumn to possibly draw */
+ for (i = 0; color_cols[i] >= 0; ++i)
+ if (rightmost_vcol < color_cols[i])
+ rightmost_vcol = color_cols[i];
+
while (col < W_WIDTH(wp))
{
ScreenLines[off] = ' ';
@@ -4668,12 +4710,19 @@
ScreenLinesUC[off] = 0;
#endif
++col;
- if (vcol == (long)wp->w_virtcol)
- {
- ScreenAttrs[off] = hl_attr(HLF_CUC);
+ if (wp->w_p_cuc && vcol == (long)wp->w_virtcol)
+ ScreenAttrs[off++] = hl_attr(HLF_CUC);
+ else if (draw_color_col && vcol == *color_cols)
+ ScreenAttrs[off++] = hl_attr(HLF_MC);
+ else
+ ScreenAttrs[off++] = 0;
+
+ if (vcol >= rightmost_vcol)
break;
- }
- ScreenAttrs[off++] = 0;
+
+ if (draw_color_col)
+ draw_color_col = advance_color_col(vcol, &color_cols);
+
++vcol;
}
}
@@ -4737,18 +4786,29 @@
}
#ifdef FEAT_SYN_HL
+ /* advance to the next 'colorcolumn' */
+ if (draw_color_col)
+ draw_color_col = advance_color_col(vcol, &color_cols);
+
/* Highlight the cursor column if 'cursorcolumn' is set. But don't
- * highlight the cursor position itself. */
- if (wp->w_p_cuc && vcol == (long)wp->w_virtcol
- && lnum != wp->w_cursor.lnum
- && draw_state == WL_LINE
- && !lnum_in_visual_area)
+ * highlight the cursor position itself.
+ * Also highlight the 'colorcolumn' if it is different than
+ * 'cursorcolumn' */
+ vcol_save_attr = -1;
+ if (draw_state == WL_LINE && !lnum_in_visual_area)
{
- vcol_save_attr = char_attr;
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC));
+ if (wp->w_p_cuc && vcol == (long)wp->w_virtcol
+ && lnum != wp->w_cursor.lnum)
+ {
+ vcol_save_attr = char_attr;
+ char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC));
+ }
+ else if (draw_color_col && vcol == *color_cols)
+ {
+ vcol_save_attr = char_attr;
+ char_attr = hl_combine_attr(char_attr, hl_attr(HLF_MC));
+ }
}
- else
- vcol_save_attr = -1;
#endif
/*
diff --git a/src/structs.h b/src/structs.h
index a95e1ba..c0e31c0 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -202,6 +202,8 @@
# define w_p_cuc w_onebuf_opt.wo_cuc /* 'cursorcolumn' */
int wo_cul;
# define w_p_cul w_onebuf_opt.wo_cul /* 'cursorline' */
+ char_u *wo_cc;
+# define w_p_cc w_onebuf_opt.wo_cc /* 'colorcolumn' */
#endif
#ifdef FEAT_STL_OPT
char_u *wo_stl;
@@ -2010,6 +2012,9 @@
long_u w_p_fde_flags; /* flags for 'foldexpr' */
long_u w_p_fdt_flags; /* flags for 'foldtext' */
#endif
+#ifdef FEAT_SYN_HL
+ int *w_p_cc_cols; /* array of columns to highlight or NULL */
+#endif
/* transform a pointer to a "onebuf" option into a "allbuf" option */
#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))
diff --git a/src/syntax.c b/src/syntax.c
index 3278810..0e113f0 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -6531,6 +6531,8 @@
"CursorColumn term=reverse ctermbg=LightGrey guibg=Grey90"),
CENT("CursorLine term=underline cterm=underline",
"CursorLine term=underline cterm=underline guibg=Grey90"),
+ CENT("ColorColumn term=reverse ctermbg=LightRed",
+ "ColorColumn term=reverse ctermbg=LightRed guibg=LightRed"),
#endif
#ifdef FEAT_CONCEAL
CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey",
@@ -6615,6 +6617,8 @@
"CursorColumn term=reverse ctermbg=DarkGrey guibg=Grey40"),
CENT("CursorLine term=underline cterm=underline",
"CursorLine term=underline cterm=underline guibg=Grey40"),
+ CENT("ColorColumn term=reverse ctermbg=DarkRed",
+ "ColorColumn term=reverse ctermbg=DarkRed guibg=DarkRed"),
#endif
#ifdef FEAT_AUTOCMD
CENT("MatchParen term=reverse ctermbg=DarkCyan",
diff --git a/src/vim.h b/src/vim.h
index e7d74ed..bbddbbf 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1334,6 +1334,7 @@
, HLF_TPF /* tabpage line filler */
, HLF_CUC /* 'cursurcolumn' */
, HLF_CUL /* 'cursurline' */
+ , HLF_MC /* 'colorcolumn' */
, HLF_COUNT /* MUST be the last one */
} hlf_T;
@@ -1343,7 +1344,7 @@
'n', 'r', 's', 'S', 'c', 't', 'v', 'V', 'w', 'W', \
'f', 'F', 'A', 'C', 'D', 'T', '-', '>', \
'B', 'P', 'R', 'L', \
- '+', '=', 'x', 'X', '*', '#', '_', '!', '.'}
+ '+', '=', 'x', 'X', '*', '#', '_', '!', '.', 'o'}
/*
* Boolean constants
diff --git a/src/window.c b/src/window.c
index c2590e5..2c780df 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1225,6 +1225,10 @@
# endif
win_init_some(newp, oldp);
+
+# ifdef FEAT_SYN_HL
+ check_colorcolumn(newp);
+# endif
}
/*
@@ -4413,6 +4417,7 @@
#ifdef FEAT_SYN_HL
reset_synblock(wp); /* free independent synblock */
+ vim_free(wp->w_p_cc_cols);
#endif
#ifdef FEAT_AUTOCMD