Skip to content

Commit b8060fe

Browse files
committed
patch 7.4.1142
Problem: Cannot define keyword characters for a syntax file. Solution: Add the ":syn iskeyword" command. (Christian Brabandt)
1 parent 6773a34 commit b8060fe

File tree

9 files changed

+202
-3
lines changed

9 files changed

+202
-3
lines changed

runtime/doc/options.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*options.txt* For Vim version 7.4. Last change: 2016 Jan 09
1+
*options.txt* For Vim version 7.4. Last change: 2016 Jan 19
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -4489,6 +4489,8 @@ A jump table for the options with a short description can be found at |Q_op|.
44894489
'*', '"' and '|' (so that CTRL-] on a command finds the help for that
44904490
command).
44914491
When the 'lisp' option is on the '-' character is always included.
4492+
This option also influences syntax highlighting, unless the syntax
4493+
uses |:syn-iskeyword|.
44924494
NOTE: This option is set to the Vi default value when 'compatible' is
44934495
set and to the Vim default value when 'compatible' is reset.
44944496

runtime/doc/syntax.txt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*syntax.txt* For Vim version 7.4. Last change: 2015 Dec 19
1+
*syntax.txt* For Vim version 7.4. Last change: 2016 Jan 19
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -3438,6 +3438,32 @@ SPELL CHECKING *:syn-spell*
34383438

34393439
To activate spell checking the 'spell' option must be set.
34403440

3441+
SYNTAX ISKEYWORD SETTING *:syn-iskeyword*
3442+
3443+
:sy[ntax] iskeyword [clear | {option}]
3444+
This defines the keyword characters. It's like the 'iskeyword' option
3445+
for but only applies to syntax highlighting.
3446+
3447+
clear: Syntax specific iskeyword setting is disabled and the
3448+
buffer-local 'iskeyword' setting is used.
3449+
{option} Set the syntax 'iskeyword' option to a new value.
3450+
3451+
Example: >
3452+
:syntax iskeyword @,48-57,192-255,$,_
3453+
<
3454+
This would set the syntax specific iskeyword option to include all
3455+
alphabetic characters, plus the numeric characters, all accented
3456+
characters and also includes the "_" and the "$".
3457+
3458+
If no argument is given, the current value will be output.
3459+
3460+
Setting this option influences what |/\k| matches in syntax patterns
3461+
and also determines where |:syn-keywords| will be checked for a new
3462+
match.
3463+
3464+
It is recommended when writing syntax files, to use this command
3465+
to the correct value for the specific syntax language and not change
3466+
the 'iskeyword' option.
34413467

34423468
DEFINING KEYWORDS *:syn-keyword*
34433469

@@ -3469,6 +3495,7 @@ DEFINING KEYWORDS *:syn-keyword*
34693495
isn't, the keyword will never be recognized.
34703496
Multi-byte characters can also be used. These do not have to be in
34713497
'iskeyword'.
3498+
See |:syn-iskeyword| for defining syntax specific iskeyword settings.
34723499

34733500
A keyword always has higher priority than a match or region, the
34743501
keyword is used if more than one item matches. Keywords do not nest

src/buffer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1955,6 +1955,7 @@ free_buf_options(buf, free_p_ff)
19551955
clear_string_option(&buf->b_p_nf);
19561956
#ifdef FEAT_SYN_HL
19571957
clear_string_option(&buf->b_p_syn);
1958+
clear_string_option(&buf->b_s.b_syn_isk);
19581959
#endif
19591960
#ifdef FEAT_SPELL
19601961
clear_string_option(&buf->b_s.b_p_spc);

src/option.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5494,6 +5494,7 @@ check_buf_options(buf)
54945494
#endif
54955495
#ifdef FEAT_SYN_HL
54965496
check_string_option(&buf->b_p_syn);
5497+
check_string_option(&buf->b_s.b_syn_isk);
54975498
#endif
54985499
#ifdef FEAT_SPELL
54995500
check_string_option(&buf->b_s.b_p_spc);
@@ -10821,6 +10822,7 @@ buf_copy_options(buf, flags)
1082110822
/* Don't copy 'syntax', it must be set */
1082210823
buf->b_p_syn = empty_option;
1082310824
buf->b_p_smc = p_smc;
10825+
buf->b_s.b_syn_isk = empty_option;
1082410826
#endif
1082510827
#ifdef FEAT_SPELL
1082610828
buf->b_s.b_p_spc = vim_strsave(p_spc);

src/structs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,8 @@ typedef struct {
13621362
#if !defined(FEAT_SYN_HL) && !defined(FEAT_SPELL)
13631363
int dummy;
13641364
#endif
1365+
char_u b_syn_chartab[32]; /* syntax iskeyword option */
1366+
char_u *b_syn_isk; /* iskeyword option */
13651367
} synblock_T;
13661368

13671369

src/syntax.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,8 @@ static int current_line_id = 0; /* unique number for current line */
376376
#define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx]
377377

378378
static void syn_sync __ARGS((win_T *wp, linenr_T lnum, synstate_T *last_valid));
379+
static void save_chartab(char_u *chartab);
380+
static void restore_chartab(char_u *chartab);
379381
static int syn_match_linecont __ARGS((linenr_T lnum));
380382
static void syn_start_line __ARGS((void));
381383
static void syn_update_ends __ARGS((int startofline));
@@ -458,6 +460,7 @@ static void add_keyword __ARGS((char_u *name, int id, int flags, short *cont_in_
458460
static char_u *get_group_name __ARGS((char_u *arg, char_u **name_end));
459461
static char_u *get_syn_options __ARGS((char_u *arg, syn_opt_arg_T *opt, int *conceal_char));
460462
static void syn_cmd_include __ARGS((exarg_T *eap, int syncing));
463+
static void syn_cmd_iskeyword __ARGS((exarg_T *eap, int syncing));
461464
static void syn_cmd_keyword __ARGS((exarg_T *eap, int syncing));
462465
static void syn_cmd_match __ARGS((exarg_T *eap, int syncing));
463466
static void syn_cmd_region __ARGS((exarg_T *eap, int syncing));
@@ -984,6 +987,24 @@ syn_sync(wp, start_lnum, last_valid)
984987
validate_current_state();
985988
}
986989

990+
static void
991+
save_chartab(char_u *chartab)
992+
{
993+
if (syn_block->b_syn_isk != empty_option)
994+
{
995+
mch_memmove(chartab, syn_buf->b_chartab, (size_t)32);
996+
mch_memmove(syn_buf->b_chartab, syn_win->w_s->b_syn_chartab,
997+
(size_t)32);
998+
}
999+
}
1000+
1001+
static void
1002+
restore_chartab(char_u *chartab)
1003+
{
1004+
if (syn_win->w_s->b_syn_isk != empty_option)
1005+
mch_memmove(syn_buf->b_chartab, chartab, (size_t)32);
1006+
}
1007+
9871008
/*
9881009
* Return TRUE if the line-continuation pattern matches in line "lnum".
9891010
*/
@@ -993,14 +1014,18 @@ syn_match_linecont(lnum)
9931014
{
9941015
regmmatch_T regmatch;
9951016
int r;
1017+
char_u buf_chartab[32]; /* chartab array for syn iskyeyword */
9961018

9971019
if (syn_block->b_syn_linecont_prog != NULL)
9981020
{
1021+
/* use syntax iskeyword option */
1022+
save_chartab(buf_chartab);
9991023
regmatch.rmm_ic = syn_block->b_syn_linecont_ic;
10001024
regmatch.regprog = syn_block->b_syn_linecont_prog;
10011025
r = syn_regexec(&regmatch, lnum, (colnr_T)0,
10021026
IF_SYN_TIME(&syn_block->b_syn_linecont_time));
10031027
syn_block->b_syn_linecont_prog = regmatch.regprog;
1028+
restore_chartab(buf_chartab);
10041029
return r;
10051030
}
10061031
return FALSE;
@@ -1891,6 +1916,7 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
18911916
lpos_T pos;
18921917
int lc_col;
18931918
reg_extmatch_T *cur_extmatch = NULL;
1919+
char_u buf_chartab[32]; /* chartab array for syn iskyeyword */
18941920
char_u *line; /* current line. NOTE: becomes invalid after
18951921
looking for a pattern match! */
18961922

@@ -1945,6 +1971,9 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
19451971
* avoid matching the same item in the same position twice. */
19461972
ga_init2(&zero_width_next_ga, (int)sizeof(int), 10);
19471973

1974+
/* use syntax iskeyword option */
1975+
save_chartab(buf_chartab);
1976+
19481977
/*
19491978
* Repeat matching keywords and patterns, to find contained items at the
19501979
* same column. This stops when there are no extra matches at the current
@@ -1956,6 +1985,7 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
19561985
keep_next_list = FALSE;
19571986
syn_id = 0;
19581987

1988+
19591989
/*
19601990
* 1. Check for a current state.
19611991
* Only when there is no current state, or if the current state may
@@ -2309,6 +2339,8 @@ syn_current_attr(syncing, displaying, can_spell, keep_state)
23092339

23102340
} while (found_match);
23112341

2342+
restore_chartab(buf_chartab);
2343+
23122344
/*
23132345
* Use attributes from the current state, if within its highlighting.
23142346
* If not, use attributes from the current-but-one state, etc.
@@ -2915,6 +2947,7 @@ find_endpos(idx, startpos, m_endpos, hl_endpos, flagsp, end_endpos,
29152947
lpos_T pos;
29162948
char_u *line;
29172949
int had_match = FALSE;
2950+
char_u buf_chartab[32]; /* chartab array for syn option iskyeyword */
29182951

29192952
/* just in case we are invoked for a keyword */
29202953
if (idx < 0)
@@ -2961,6 +2994,10 @@ find_endpos(idx, startpos, m_endpos, hl_endpos, flagsp, end_endpos,
29612994
matchcol = startpos->col; /* start looking for a match at sstart */
29622995
start_idx = idx; /* remember the first END pattern. */
29632996
best_regmatch.startpos[0].col = 0; /* avoid compiler warning */
2997+
2998+
/* use syntax iskeyword option */
2999+
save_chartab(buf_chartab);
3000+
29643001
for (;;)
29653002
{
29663003
/*
@@ -3117,6 +3154,8 @@ find_endpos(idx, startpos, m_endpos, hl_endpos, flagsp, end_endpos,
31173154
if (!had_match)
31183155
m_endpos->lnum = 0;
31193156

3157+
restore_chartab(buf_chartab);
3158+
31203159
/* Remove external matches. */
31213160
unref_extmatch(re_extmatch_in);
31223161
re_extmatch_in = NULL;
@@ -3481,6 +3520,57 @@ syn_cmd_spell(eap, syncing)
34813520
redraw_win_later(curwin, NOT_VALID);
34823521
}
34833522

3523+
/*
3524+
* Handle ":syntax iskeyword" command.
3525+
*/
3526+
static void
3527+
syn_cmd_iskeyword(eap, syncing)
3528+
exarg_T *eap;
3529+
int syncing UNUSED;
3530+
{
3531+
char_u *arg = eap->arg;
3532+
char_u save_chartab[32];
3533+
char_u *save_isk;
3534+
3535+
if (eap->skip)
3536+
return;
3537+
3538+
arg = skipwhite(arg);
3539+
if (*arg == NUL)
3540+
{
3541+
MSG_PUTS("\n");
3542+
MSG_PUTS(_("syntax iskeyword "));
3543+
if (curwin->w_s->b_syn_isk != empty_option)
3544+
msg_outtrans(curwin->w_s->b_syn_isk);
3545+
else
3546+
msg_outtrans((char_u *)"not set");
3547+
}
3548+
else
3549+
{
3550+
if (STRNICMP(arg, "clear", 5) == 0)
3551+
{
3552+
mch_memmove(curwin->w_s->b_syn_chartab, curbuf->b_chartab,
3553+
(size_t)32);
3554+
clear_string_option(&curwin->w_s->b_syn_isk);
3555+
}
3556+
else
3557+
{
3558+
mch_memmove(save_chartab, curbuf->b_chartab, (size_t)32);
3559+
save_isk = curbuf->b_p_isk;
3560+
curbuf->b_p_isk = vim_strsave(arg);
3561+
3562+
buf_init_chartab(curbuf, FALSE);
3563+
mch_memmove(curwin->w_s->b_syn_chartab, curbuf->b_chartab,
3564+
(size_t)32);
3565+
mch_memmove(curbuf->b_chartab, save_chartab, (size_t)32);
3566+
clear_string_option(&curwin->w_s->b_syn_isk);
3567+
curwin->w_s->b_syn_isk = curbuf->b_p_isk;
3568+
curbuf->b_p_isk = save_isk;
3569+
}
3570+
}
3571+
redraw_win_later(curwin, NOT_VALID);
3572+
}
3573+
34843574
/*
34853575
* Clear all syntax info for one buffer.
34863576
*/
@@ -3523,6 +3613,7 @@ syntax_clear(block)
35233613
#ifdef FEAT_FOLDING
35243614
block->b_syn_folditems = 0;
35253615
#endif
3616+
clear_string_option(&block->b_syn_isk);
35263617

35273618
/* free the stored states */
35283619
syn_stack_free_all(block);
@@ -3569,8 +3660,9 @@ syntax_sync_clear()
35693660
curwin->w_s->b_syn_linecont_prog = NULL;
35703661
vim_free(curwin->w_s->b_syn_linecont_pat);
35713662
curwin->w_s->b_syn_linecont_pat = NULL;
3663+
clear_string_option(&curwin->w_s->b_syn_isk);
35723664

3573-
syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
3665+
syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
35743666
}
35753667

35763668
/*
@@ -3777,6 +3869,7 @@ syn_cmd_reset(eap, syncing)
37773869
eap->nextcmd = check_nextcmd(eap->arg);
37783870
if (!eap->skip)
37793871
{
3872+
clear_string_option(&curwin->w_s->b_syn_isk);
37803873
set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"reset");
37813874
do_cmdline_cmd((char_u *)"runtime! syntax/syncolor.vim");
37823875
do_unlet((char_u *)"g:syntax_cmd", TRUE);
@@ -6253,6 +6346,7 @@ static struct subcommand subcommands[] =
62536346
{"conceal", syn_cmd_conceal},
62546347
{"enable", syn_cmd_enable},
62556348
{"include", syn_cmd_include},
6349+
{"iskeyword", syn_cmd_iskeyword},
62566350
{"keyword", syn_cmd_keyword},
62576351
{"list", syn_cmd_list},
62586352
{"manual", syn_cmd_manual},
@@ -6331,6 +6425,7 @@ ex_ownsyntax(eap)
63316425
clear_string_option(&curwin->w_s->b_p_spf);
63326426
clear_string_option(&curwin->w_s->b_p_spl);
63336427
#endif
6428+
clear_string_option(&curwin->w_s->b_syn_isk);
63346429
}
63356430

63366431
/* save value of b:current_syntax */

src/testdir/Make_all.mak

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ NEW_TESTS = test_arglist.res \
175175
test_increment.res \
176176
test_perl.res \
177177
test_quickfix.res \
178+
test_syntax.res \
178179
test_viminfo.res \
179180
test_viml.res \
180181
test_alot.res

src/testdir/test_syntax.vim

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
" Test for syntax and syntax iskeyword option
2+
3+
if !has("syntax")
4+
finish
5+
endif
6+
7+
func GetSyntaxItem(pat)
8+
let c = ''
9+
let a = ['a', getreg('a'), getregtype('a')]
10+
0
11+
redraw!
12+
call search(a:pat, 'W')
13+
let synid = synID(line('.'), col('.'), 1)
14+
while synid == synID(line('.'), col('.'), 1)
15+
norm! v"ay
16+
" stop at whitespace
17+
if @a =~# '\s'
18+
break
19+
endif
20+
let c .= @a
21+
norm! l
22+
endw
23+
call call('setreg', a)
24+
0
25+
return c
26+
endfunc
27+
28+
func Test_syn_iskeyword()
29+
new
30+
call setline(1, [
31+
\ 'CREATE TABLE FOOBAR(',
32+
\ ' DLTD_BY VARCHAR2(100)',
33+
\ ');',
34+
\ ''])
35+
36+
syntax on
37+
set ft=sql
38+
syn match SYN /C\k\+\>/
39+
hi link SYN ErrorMsg
40+
call assert_equal('DLTD_BY', GetSyntaxItem('DLTD'))
41+
/\<D\k\+\>/:norm! ygn
42+
call assert_equal('DLTD_BY', @0)
43+
redir @c
44+
syn iskeyword
45+
redir END
46+
call assert_equal("\nsyntax iskeyword not set", @c)
47+
48+
syn iskeyword @,48-57,_,192-255
49+
redir @c
50+
syn iskeyword
51+
redir END
52+
call assert_equal("\nsyntax iskeyword @,48-57,_,192-255", @c)
53+
54+
setlocal isk-=_
55+
call assert_equal('DLTD_BY', GetSyntaxItem('DLTD'))
56+
/\<D\k\+\>/:norm! ygn
57+
let b2=@0
58+
call assert_equal('DLTD', @0)
59+
60+
syn iskeyword clear
61+
redir @c
62+
syn iskeyword
63+
redir END
64+
call assert_equal("\nsyntax iskeyword not set", @c)
65+
66+
quit!
67+
endfunc

0 commit comments

Comments
 (0)