aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonerover <pathfinder1644@yahoo.com>2017-02-25 22:42:25 +0800
committerJustin M. Keyes <justinkz@gmail.com>2017-02-25 15:42:25 +0100
commit0ef2b07d69c3f4da38219d8eef045232d18e9c37 (patch)
tree3ca4e0400bb279aef11678739f554c51f68d3261
parent039c7ab60758661132c9bade0a4674190fa9442b (diff)
downloadrneovim-0ef2b07d69c3f4da38219d8eef045232d18e9c37.tar.gz
rneovim-0ef2b07d69c3f4da38219d8eef045232d18e9c37.tar.bz2
rneovim-0ef2b07d69c3f4da38219d8eef045232d18e9c37.zip
vim-patch:7.4.2230 (#6080)
Problem: There is no equivalent of 'smartcase' for a tag search. Solution: Add value "followscs" and "smart" to 'tagcase'. (Christian Brabandt, closes vim/vim#712) Turn tagcase test into new style. https://github.com/vim/vim/commit/66e29d7112e437b2b50efe1f82c7e892736d23e4
-rw-r--r--runtime/doc/options.txt5
-rw-r--r--runtime/doc/tagsrch.txt44
-rw-r--r--src/nvim/option_defs.h5
-rw-r--r--src/nvim/search.c14
-rw-r--r--src/nvim/tag.c6
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_tagcase.vim73
-rw-r--r--src/nvim/version.c2
8 files changed, 129 insertions, 21 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 4ae4725617..cd257b7780 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -6273,6 +6273,9 @@ A jump table for the options with a short description can be found at |Q_op|.
By default, tag searches are case-sensitive. Case is ignored when
'ignorecase' is set and 'tagcase' is "followic", or when 'tagcase' is
"ignore".
+ Also when 'tagcase' is "followscs" and 'smartcase' is set, or
+ 'tagcase' is "smart", and the pattern contains only lowercase
+ characters.
When 'tagbsearch' is off, tags searching is slower when a full match
exists, but faster when no full match exists. Tags in unsorted tags
@@ -6290,8 +6293,10 @@ A jump table for the options with a short description can be found at |Q_op|.
This option specifies how case is handled when searching the tags
file:
followic Follow the 'ignorecase' option
+ followscs Follow the 'smartcase' and 'ignorecase' options
ignore Ignore case
match Match case
+ smart Ignore case unless an upper case letter is used
*'taglength'* *'tl'*
'taglength' 'tl' number (default 0)
diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt
index 75d820d072..047abb42cc 100644
--- a/runtime/doc/tagsrch.txt
+++ b/runtime/doc/tagsrch.txt
@@ -83,14 +83,23 @@ Note that when the current file changes, the priority list is mostly not
changed, to avoid confusion when using ":tnext". It is changed when using
":tag {ident}".
-The ignore-case matches are not found for a ":tag" command when the
-'ignorecase' option is off and 'tagcase' is "followic" or when 'tagcase' is
-"match". They are found when a pattern is used (starting with a "/") and for
-":tselect", also when 'ignorecase' is off and 'tagcase' is "followic" or when
-'tagcase' is "match". Note that using ignore-case tag searching disables
-binary searching in the tags file, which causes a slowdown. This can be
-avoided by fold-case sorting the tag file. See the 'tagbsearch' option for an
-explanation.
+The ignore-case matches are not found for a ":tag" command when:
+- the 'ignorecase' option is off and 'tagcase' is "followic"
+- 'tagcase' is "match"
+- 'tagcase' is "smart" and the pattern contains an upper case character.
+- 'tagcase' is "followscs" and 'smartcase' option is on and the pattern
+ contains an upper case character.
+
+The gnore-case matches are found when:
+- a pattern is used (starting with a "/")
+- for ":tselect"
+- when 'tagcase' is "followic" and 'ignorecase' is off
+- when 'tagcase' is "match"
+- when 'tagcase' is "followscs" and the 'smartcase' option is off
+
+Note that using ignore-case tag searching disables binary searching in the
+tags file, which causes a slowdown. This can be avoided by fold-case sorting
+the tag file. See the 'tagbsearch' option for an explanation.
==============================================================================
2. Tag stack *tag-stack* *tagstack* *E425*
@@ -420,13 +429,18 @@ file "tags". It can also be used to access a common tags file.
The next file in the list is not used when:
- A matching static tag for the current buffer has been found.
- A matching global tag has been found.
-This also depends on whether case is ignored. Case is ignored when
-'ignorecase' is set and 'tagcase' is "followic", or when 'tagcase' is
-"ignore". If case is not ignored, and the tags file only has a match without
-matching case, the next tags file is searched for a match with matching case.
-If no tag with matching case is found, the first match without matching case
-is used. If case is ignored, and a matching global tag with or without
-matching case is found, this one is used, no further tags files are searched.
+This also depends on whether case is ignored. Case is ignored when:
+- 'tagcase' is "followic" and 'ignorecase' is set
+- 'tagcase' is "ignore"
+- 'tagcase' is "smart" and and the pattern only contains lower case
+ characters.
+- 'tagcase' is "followscs" and 'smartcase' is set and and the pattern only
+ contains lower case characters.
+If case is not ignored, and the tags file only has a match without matching
+case, the next tags file is searched for a match with matching case. If no
+tag with matching case is found, the first match without matching case is
+used. If case is ignored, and a matching global tag with or without matching
+case is found, this one is used, no further tags files are searched.
When a tag file name starts with "./", the '.' is replaced with the path of
the current file. This makes it possible to use a tags file in the directory
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 602497461d..d077f5f2f7 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -601,11 +601,14 @@ EXTERN int p_tbs; ///< 'tagbsearch'
EXTERN char_u *p_tc; ///< 'tagcase'
EXTERN unsigned tc_flags; ///< flags from 'tagcase'
#ifdef IN_OPTION_C
-static char *(p_tc_values[]) = { "followic", "ignore", "match", NULL };
+static char *(p_tc_values[]) =
+ { "followic", "ignore", "match", "followscs", "smart", NULL };
#endif
#define TC_FOLLOWIC 0x01
#define TC_IGNORE 0x02
#define TC_MATCH 0x04
+#define TC_FOLLOWSCS 0x08
+#define TC_SMART 0x10
EXTERN long p_tl; ///< 'taglength'
EXTERN int p_tr; ///< 'tagrelative'
EXTERN char_u *p_tags; ///< 'tags'
diff --git a/src/nvim/search.c b/src/nvim/search.c
index a9766a406e..ba6c4e6548 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -308,13 +308,19 @@ void free_search_patterns(void)
*/
int ignorecase(char_u *pat)
{
- int ic = p_ic;
+ return ignorecase_opt(pat, p_ic, p_scs);
+}
- if (ic && !no_smartcase && p_scs
+/// As ignorecase() put pass the "ic" and "scs" flags.
+int ignorecase_opt(char_u *pat, int ic_in, int scs)
+{
+ int ic = ic_in;
+ if (ic && !no_smartcase && scs
&& !(ctrl_x_mode && curbuf->b_p_inf)
- )
+ ) {
ic = !pat_has_uppercase(pat);
- no_smartcase = FALSE;
+ }
+ no_smartcase = false;
return ic;
}
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index e723ea20c9..cc5aac6094 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -1164,6 +1164,12 @@ find_tags (
case TC_MATCH:
p_ic = false;
break;
+ case TC_FOLLOWSCS:
+ p_ic = ignorecase(pat);
+ break;
+ case TC_SMART:
+ p_ic = ignorecase_opt(pat, true, true);
+ break;
default:
assert(false);
}
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index 375d8219e6..04cc279619 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -25,6 +25,7 @@ source test_statusline.vim
source test_syn_attr.vim
source test_tabline.vim
source test_tabpage.vim
+source test_tagcase.vim
source test_tagjump.vim
source test_unlet.vim
source test_window_cmd.vim
diff --git a/src/nvim/testdir/test_tagcase.vim b/src/nvim/testdir/test_tagcase.vim
new file mode 100644
index 0000000000..833cb9f990
--- /dev/null
+++ b/src/nvim/testdir/test_tagcase.vim
@@ -0,0 +1,73 @@
+" test 'tagcase' option
+
+func Test_tagcase()
+ call writefile(["Bar\tXtext\t3", "Foo\tXtext\t2", "foo\tXtext\t4"], 'Xtags')
+ set tags=Xtags
+ e Xtext
+
+ for &ic in [0, 1]
+ for &scs in [0, 1]
+ for &g:tc in ["followic", "ignore", "match", "followscs", "smart"]
+ for &l:tc in ["", "followic", "ignore", "match", "followscs", "smart"]
+ let smart = 0
+ if &l:tc != ''
+ let tc = &l:tc
+ else
+ let tc = &g:tc
+ endif
+ if tc == 'followic'
+ let ic = &ic
+ elseif tc == 'ignore'
+ let ic = 1
+ elseif tc == 'followscs'
+ let ic = &ic
+ let smart = &scs
+ elseif tc == 'smart'
+ let ic = 1
+ let smart = 1
+ else
+ let ic = 0
+ endif
+ if ic && smart
+ call assert_equal(['foo', 'Foo'], map(taglist("^foo$"), {i, v -> v.name}))
+ call assert_equal(['Foo'], map(taglist("^Foo$"), {i, v -> v.name}))
+ elseif ic
+ call assert_equal(['foo', 'Foo'], map(taglist("^foo$"), {i, v -> v.name}))
+ call assert_equal(['Foo', 'foo'], map(taglist("^Foo$"), {i, v -> v.name}))
+ else
+ call assert_equal(['foo'], map(taglist("^foo$"), {i, v -> v.name}))
+ call assert_equal(['Foo'], map(taglist("^Foo$"), {i, v -> v.name}))
+ endif
+ endfor
+ endfor
+ endfor
+ endfor
+
+ call delete('Xtags')
+ set ic&
+ setg tc&
+ setl tc&
+ set scs&
+endfunc
+
+func Test_set_tagcase()
+ " Verify default values.
+ set ic&
+ setg tc&
+ setl tc&
+ call assert_equal(0, &ic)
+ call assert_equal('followic', &g:tc)
+ call assert_equal('followic', &l:tc)
+ call assert_equal('followic', &tc)
+
+ " Verify that the local setting accepts <empty> but that the global setting
+ " does not. The first of these (setting the local value to <empty>) should
+ " succeed; the other two should fail.
+ setl tc=
+ call assert_fails('setg tc=', 'E474:')
+ call assert_fails('set tc=', 'E474:')
+
+ set ic&
+ setg tc&
+ setl tc&
+endfunc
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 3787ba6908..fe443ce01f 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -210,7 +210,7 @@ static int included_patches[] = {
2233,
// 2232 NA
// 2231,
- // 2230,
+ 2230,
// 2229,
// 2228,
2227,