Skip to content

Commit 0f6562e

Browse files
committed
patch 7.4.941
Problem: There is no way to ignore case only for tag searches. Solution: Add the 'tagcase' option. (Gary Johnson)
1 parent 2a1b474 commit 0f6562e

20 files changed

Lines changed: 254 additions & 24 deletions

runtime/doc/options.txt

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4109,7 +4109,7 @@ A jump table for the options with a short description can be found at |Q_op|.
41094109
global
41104110
Ignore case in search patterns. Also used when searching in the tags
41114111
file.
4112-
Also see 'smartcase'.
4112+
Also see 'smartcase' and 'tagcase'.
41134113
Can be overruled by using "\c" or "\C" in the pattern, see
41144114
|/ignorecase|.
41154115

@@ -7339,19 +7339,22 @@ A jump table for the options with a short description can be found at |Q_op|.
73397339
< [The whitespace before and after the '0' must be a single <Tab>]
73407340

73417341
When a binary search was done and no match was found in any of the
7342-
files listed in 'tags', and 'ignorecase' is set or a pattern is used
7342+
files listed in 'tags', and case is ignored or a pattern is used
73437343
instead of a normal tag name, a retry is done with a linear search.
73447344
Tags in unsorted tags files, and matches with different case will only
73457345
be found in the retry.
73467346

73477347
If a tag file indicates that it is case-fold sorted, the second,
7348-
linear search can be avoided for the 'ignorecase' case. Use a value
7349-
of '2' in the "!_TAG_FILE_SORTED" line for this. A tag file can be
7350-
case-fold sorted with the -f switch to "sort" in most unices, as in
7351-
the command: "sort -f -o tags tags". For "Exuberant ctags" version
7352-
5.x or higher (at least 5.5) the --sort=foldcase switch can be used
7353-
for this as well. Note that case must be folded to uppercase for this
7354-
to work.
7348+
linear search can be avoided when case is ignored. Use a value of '2'
7349+
in the "!_TAG_FILE_SORTED" line for this. A tag file can be case-fold
7350+
sorted with the -f switch to "sort" in most unices, as in the command:
7351+
"sort -f -o tags tags". For "Exuberant ctags" version 5.x or higher
7352+
(at least 5.5) the --sort=foldcase switch can be used for this as
7353+
well. Note that case must be folded to uppercase for this to work.
7354+
7355+
By default, tag searches are case-sensitive. Case is ignored when
7356+
'ignorecase' is set and 'tagcase' is "followic", or when 'tagcase' is
7357+
"ignore".
73557358

73567359
When 'tagbsearch' is off, tags searching is slower when a full match
73577360
exists, but faster when no full match exists. Tags in unsorted tags
@@ -7363,6 +7366,16 @@ A jump table for the options with a short description can be found at |Q_op|.
73637366
command-line completion and ":help").
73647367
{Vi: always uses binary search in some versions}
73657368

7369+
*'tagcase'* *'tc'*
7370+
'tagcase' 'tc' string (default "followic")
7371+
global or local to buffer |global-local|
7372+
{not in Vi}
7373+
This option specifies how case is handled when searching the tags
7374+
file:
7375+
followic Follow the 'ignorecase' option
7376+
ignore Ignore case
7377+
match Match case
7378+
73667379
*'taglength'* *'tl'*
73677380
'taglength' 'tl' number (default 0)
73687381
global

runtime/doc/quickref.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@ Short explanation of each option: *option-list*
904904
'tabpagemax' 'tpm' maximum number of tab pages for |-p| and "tab all"
905905
'tabstop' 'ts' number of spaces that <Tab> in file uses
906906
'tagbsearch' 'tbs' use binary searching in tags files
907+
'tagcase' 'tc' how to handle case when searching in tags files
907908
'taglength' 'tl' number of significant characters for a tag
908909
'tagrelative' 'tr' file names in tag file are relative
909910
'tags' 'tag' list of file names used by the tag command

runtime/doc/tagsrch.txt

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ changed, to avoid confusion when using ":tnext". It is changed when using
8585
":tag {ident}".
8686

8787
The ignore-case matches are not found for a ":tag" command when the
88-
'ignorecase' option is off. They are found when a pattern is used (starting
89-
with a "/") and for ":tselect", also when 'ignorecase' is off. Note that
90-
using ignore-case tag searching disables binary searching in the tags file,
91-
which causes a slowdown. This can be avoided by fold-case sorting the tag
92-
file. See the 'tagbsearch' option for an explanation.
88+
'ignorecase' option is off and 'tagcase' is "followic" or when 'tagcase' is
89+
"match". They are found when a pattern is used (starting with a "/") and for
90+
":tselect", also when 'ignorecase' is off and 'tagcase' is "followic" or when
91+
'tagcase' is "match". Note that using ignore-case tag searching disables
92+
binary searching in the tags file, which causes a slowdown. This can be
93+
avoided by fold-case sorting the tag file. See the 'tagbsearch' option for an
94+
explanation.
9395

9496
==============================================================================
9597
2. Tag stack *tag-stack* *tagstack* *E425*
@@ -440,12 +442,13 @@ file "tags". It can also be used to access a common tags file.
440442
The next file in the list is not used when:
441443
- A matching static tag for the current buffer has been found.
442444
- A matching global tag has been found.
443-
This also depends on the 'ignorecase' option. If it is off, and the tags file
444-
only has a match without matching case, the next tags file is searched for a
445-
match with matching case. If no tag with matching case is found, the first
446-
match without matching case is used. If 'ignorecase' is on, and a matching
447-
global tag with or without matching case is found, this one is used, no
448-
further tags files are searched.
445+
This also depends on whether case is ignored. Case is ignored when
446+
'ignorecase' is set and 'tagcase' is "followic", or when 'tagcase' is
447+
"ignore". If case is not ignored, and the tags file only has a match without
448+
matching case, the next tags file is searched for a match with matching case.
449+
If no tag with matching case is found, the first match without matching case
450+
is used. If case is ignored, and a matching global tag with or without
451+
matching case is found, this one is used, no further tags files are searched.
449452

450453
When a tag file name starts with "./", the '.' is replaced with the path of
451454
the current file. This makes it possible to use a tags file in the directory
@@ -579,8 +582,10 @@ that indicates if the file was sorted. When this line is found, Vim uses
579582
binary searching for the tags file:
580583
!_TAG_FILE_SORTED<Tab>1<Tab>{anything} ~
581584

582-
A tag file may be case-fold sorted to avoid a linear search when 'ignorecase'
583-
is on. See 'tagbsearch' for details. The value '2' should be used then:
585+
A tag file may be case-fold sorted to avoid a linear search when case is
586+
ignored. (Case is ignored when 'ignorecase' is set and 'tagcase' is
587+
"followic", or when 'tagcase' is "ignore".) See 'tagbsearch' for details.
588+
The value '2' should be used then:
584589
!_TAG_FILE_SORTED<Tab>2<Tab>{anything} ~
585590

586591
The other tag that Vim recognizes, but only when compiled with the

runtime/doc/usr_29.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,8 @@ function.
255255

256256
RELATED ITEMS
257257

258-
You can set 'ignorecase' to make case in tag names be ignored.
258+
To make case in tag names be ignored, you can set 'ignorecase' while leaving
259+
'tagcase' as "followic", or set 'tagcase' to "ignore".
259260

260261
The 'tagbsearch' option tells if the tags file is sorted or not. The default
261262
is to assume a sorted tags file, which makes a tags search a lot faster, but

runtime/optwin.vim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,10 @@ call append("$", " \tset tl=" . &tl)
289289
call append("$", "tags\tlist of file names to search for tags")
290290
call append("$", "\t(global or local to buffer)")
291291
call <SID>OptionG("tag", &tag)
292+
call append("$", "tagcase\thow to handle case when searching in tags files:")
293+
call append("$", "\t\"followic\" to follow 'ignorecase', \"ignore\" or \"match\"")
294+
call append("$", "\t(global or local to buffer)")
295+
call <SID>OptionG("tc", &tc)
292296
call append("$", "tagrelative\tfile names in a tags file are relative to the tags file")
293297
call <SID>BinOptionG("tr", &tr)
294298
call append("$", "tagstack\ta :tag command will use the tagstack")

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,6 +1930,7 @@ test1 \
19301930
test_search_mbyte \
19311931
test_set \
19321932
test_signs \
1933+
test_tagcase \
19331934
test_textobjects \
19341935
test_utf8 \
19351936
test_writefile \

src/buffer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1991,6 +1991,7 @@ free_buf_options(buf, free_p_ff)
19911991
clear_string_option(&buf->b_p_ep);
19921992
clear_string_option(&buf->b_p_path);
19931993
clear_string_option(&buf->b_p_tags);
1994+
clear_string_option(&buf->b_p_tc);
19941995
#ifdef FEAT_INS_EXPAND
19951996
clear_string_option(&buf->b_p_dict);
19961997
clear_string_option(&buf->b_p_tsr);

src/option.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@
174174
#define PV_SW OPT_BUF(BV_SW)
175175
#define PV_SWF OPT_BUF(BV_SWF)
176176
#define PV_TAGS OPT_BOTH(OPT_BUF(BV_TAGS))
177+
#define PV_TC OPT_BOTH(OPT_BUF(BV_TC))
177178
#define PV_TS OPT_BUF(BV_TS)
178179
#define PV_TW OPT_BUF(BV_TW)
179180
#define PV_TX OPT_BUF(BV_TX)
@@ -2602,6 +2603,9 @@ static struct vimoption
26022603
{(char_u *)TRUE, (char_u *)0L}
26032604
#endif
26042605
SCRIPTID_INIT},
2606+
{"tagcase", "tc", P_STRING|P_VIM,
2607+
(char_u *)&p_tc, PV_TC,
2608+
{(char_u *)"followic", (char_u *)"followic"} SCRIPTID_INIT},
26052609
{"taglength", "tl", P_NUM|P_VI_DEF,
26062610
(char_u *)&p_tl, PV_NONE,
26072611
{(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
@@ -5363,6 +5367,7 @@ didset_options()
53635367
(void)opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE);
53645368
#endif
53655369
(void)opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE);
5370+
(void)opt_strings_flags(p_tc, p_tc_values, &tc_flags, FALSE);
53665371
#ifdef FEAT_VIRTUALEDIT
53675372
(void)opt_strings_flags(p_ve, p_ve_values, &ve_flags, TRUE);
53685373
#endif
@@ -5525,6 +5530,7 @@ check_buf_options(buf)
55255530
check_string_option(&buf->b_p_ep);
55265531
check_string_option(&buf->b_p_path);
55275532
check_string_option(&buf->b_p_tags);
5533+
check_string_option(&buf->b_p_tc);
55285534
#ifdef FEAT_INS_EXPAND
55295535
check_string_option(&buf->b_p_dict);
55305536
check_string_option(&buf->b_p_tsr);
@@ -7044,6 +7050,30 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
70447050
errmsg = e_invarg;
70457051
}
70467052

7053+
/* 'tagcase' */
7054+
else if (gvarp == &p_tc)
7055+
{
7056+
unsigned int *flags;
7057+
7058+
if (opt_flags & OPT_LOCAL)
7059+
{
7060+
p = curbuf->b_p_tc;
7061+
flags = &curbuf->b_tc_flags;
7062+
}
7063+
else
7064+
{
7065+
p = p_tc;
7066+
flags = &tc_flags;
7067+
}
7068+
7069+
if ((opt_flags & OPT_LOCAL) && *p == NUL)
7070+
/* make the local value empty: use the global value */
7071+
*flags = 0;
7072+
else if (*p == NUL
7073+
|| opt_strings_flags(p, p_tc_values, flags, FALSE) != OK)
7074+
errmsg = e_invarg;
7075+
}
7076+
70477077
#ifdef FEAT_MBYTE
70487078
/* 'casemap' */
70497079
else if (varp == &p_cmp)
@@ -10083,6 +10113,10 @@ unset_global_local_option(name, from)
1008310113
case PV_TAGS:
1008410114
clear_string_option(&buf->b_p_tags);
1008510115
break;
10116+
case PV_TC:
10117+
clear_string_option(&buf->b_p_tc);
10118+
buf->b_tc_flags = 0;
10119+
break;
1008610120
#ifdef FEAT_FIND_ID
1008710121
case PV_DEF:
1008810122
clear_string_option(&buf->b_p_def);
@@ -10164,6 +10198,7 @@ get_varp_scope(p, opt_flags)
1016410198
case PV_PATH: return (char_u *)&(curbuf->b_p_path);
1016510199
case PV_AR: return (char_u *)&(curbuf->b_p_ar);
1016610200
case PV_TAGS: return (char_u *)&(curbuf->b_p_tags);
10201+
case PV_TC: return (char_u *)&(curbuf->b_p_tc);
1016710202
#ifdef FEAT_FIND_ID
1016810203
case PV_DEF: return (char_u *)&(curbuf->b_p_def);
1016910204
case PV_INC: return (char_u *)&(curbuf->b_p_inc);
@@ -10218,6 +10253,8 @@ get_varp(p)
1021810253
? (char_u *)&(curbuf->b_p_ar) : p->var;
1021910254
case PV_TAGS: return *curbuf->b_p_tags != NUL
1022010255
? (char_u *)&(curbuf->b_p_tags) : p->var;
10256+
case PV_TC: return *curbuf->b_p_tc != NUL
10257+
? (char_u *)&(curbuf->b_p_tc) : p->var;
1022110258
case PV_BKC: return *curbuf->b_p_bkc != NUL
1022210259
? (char_u *)&(curbuf->b_p_bkc) : p->var;
1022310260
#ifdef FEAT_FIND_ID
@@ -10826,6 +10863,8 @@ buf_copy_options(buf, flags)
1082610863
buf->b_p_kp = empty_option;
1082710864
buf->b_p_path = empty_option;
1082810865
buf->b_p_tags = empty_option;
10866+
buf->b_p_tc = empty_option;
10867+
buf->b_tc_flags = 0;
1082910868
#ifdef FEAT_FIND_ID
1083010869
buf->b_p_def = empty_option;
1083110870
buf->b_p_inc = empty_option;

src/option.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,14 @@ static char *(p_swb_values[]) = {"useopen", "usetab", "split", "newtab", "vsplit
820820
#define SWB_NEWTAB 0x008
821821
#define SWB_VSPLIT 0x010
822822
EXTERN int p_tbs; /* 'tagbsearch' */
823+
EXTERN char_u *p_tc; /* 'tagcase' */
824+
EXTERN unsigned tc_flags; /* flags from 'tagcase' */
825+
#ifdef IN_OPTION_C
826+
static char *(p_tc_values[]) = {"followic", "ignore", "match", NULL};
827+
#endif
828+
#define TC_FOLLOWIC 0x01
829+
#define TC_IGNORE 0x02
830+
#define TC_MATCH 0x04
823831
EXTERN long p_tl; /* 'taglength' */
824832
EXTERN int p_tr; /* 'tagrelative' */
825833
EXTERN char_u *p_tags; /* 'tags' */
@@ -1081,6 +1089,7 @@ enum
10811089
, BV_SW
10821090
, BV_SWF
10831091
, BV_TAGS
1092+
, BV_TC
10841093
, BV_TS
10851094
, BV_TW
10861095
, BV_TX

src/structs.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1674,6 +1674,8 @@ struct file_buffer
16741674
char_u *b_p_path; /* 'path' local value */
16751675
int b_p_ar; /* 'autoread' local value */
16761676
char_u *b_p_tags; /* 'tags' local value */
1677+
char_u *b_p_tc; /* 'tagcase' local value */
1678+
unsigned b_tc_flags; /* flags for 'tagcase' */
16771679
#ifdef FEAT_INS_EXPAND
16781680
char_u *b_p_dict; /* 'dictionary' local value */
16791681
char_u *b_p_tsr; /* 'thesaurus' local value */
@@ -2063,7 +2065,7 @@ struct window_S
20632065
current virtual column */
20642066

20652067
/*
2066-
* the next six are used to update the visual part
2068+
* the next seven are used to update the visual part
20672069
*/
20682070
char w_old_visual_mode; /* last known VIsual_mode */
20692071
linenr_T w_old_cursor_lnum; /* last known end of visual part */

0 commit comments

Comments
 (0)