Skip to content

Commit 4af72c3

Browse files
authored
Merge pull request #196 from znz/fix/issue-194-special-variable-search
特殊変数を「$;」形式のクエリで検索できるようにする (#194)
2 parents 4dfaeb4 + 8b42025 commit 4af72c3

3 files changed

Lines changed: 66 additions & 2 deletions

File tree

lib/bitclust/search_index_generator.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,16 @@ def method_entries(db)
8989
next if seen[path]
9090

9191
seen[path] = true
92-
full_name = (tmark == '$' ? '' : cname) + tmark + mname
93-
result << { name: mname, full_name: full_name, type: type, path: path }
92+
if tmark == '$'
93+
# A special variable has no owning class to qualify it; its "$"
94+
# sigil is the only thing distinguishing it, so keep it in +name+
95+
# too (not just +full_name+) or a "$;"-style query can't match it.
96+
name = full_name = tmark + mname
97+
else
98+
name = mname
99+
full_name = cname + tmark + mname
100+
end
101+
result << { name: name, full_name: full_name, type: type, path: path }
94102
end
95103
end
96104
result

test/test_search_index_generator.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,36 @@ def test_constant_entry
7777
assert_equal 'method/-foo/c/-a-a-a.html', e[:path]
7878
end
7979

80+
def test_special_variable_keeps_its_sigil_in_name
81+
# A special variable's "$" is part of how it is written and is the only
82+
# thing distinguishing it (there is no owning class to qualify it), so it
83+
# must stay in +name+ for a "$;"-style query to match. See issue #194.
84+
#
85+
# The +name+/+type+ assertions below are what issue #194 is about. The
86+
# +path+ assertion is secondary and filesystem-dependent: @gen defaults to
87+
# fs_casesensitive: false, so the path is built by encodename_fs ("Kernel"
88+
# -> "-kernel", ";" -> "=3b"). It is fine to ignore ONLY the path failure if
89+
# it broke because the fs encoding scheme changed or a case-sensitive build
90+
# (fs_casesensitive: true, giving "method/Kernel/v/...") is in use -- as long
91+
# as name/type still hold. A name/type failure is a real regression.
92+
index = @gen.build_index(@db)
93+
e = find_entry(index, '$;')
94+
assert_not_nil e
95+
assert_equal '$;', e[:name]
96+
assert_equal 'variable', e[:type]
97+
assert_equal 'method/-kernel/v/=3b.html', e[:path],
98+
'filesystem-encoded path (fs_casesensitive: false); ' \
99+
'ignore only this failure if just the fs encoding/casing changed'
100+
end
101+
102+
def test_special_variable_word_name_keeps_its_sigil
103+
index = @gen.build_index(@db)
104+
e = find_entry(index, '$stdout')
105+
assert_not_nil e
106+
assert_equal '$stdout', e[:name]
107+
assert_equal 'variable', e[:type]
108+
end
109+
80110
def test_same_method_name_in_two_classes
81111
index = @gen.build_index(@db)
82112
assert_not_nil find_entry(index, 'Foo#foo')
@@ -135,6 +165,11 @@ def setup_files
135165
== Module Functions
136166
--- at_exit{ ... } -> Proc
137167
aaa
168+
== Special Variables
169+
--- $; -> String | nil
170+
区切り文字。
171+
--- $stdout -> IO
172+
標準出力。
138173
139174
HERE
140175
end

theme/default/js/search_init.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,27 @@
1313
* set inline in the page <head> by the layout template.
1414
*/
1515
(function() {
16+
// BitClust extension (the vendored Aliki files above are kept verbatim).
17+
//
18+
// RDoc's parseQuery() rewrites "." to "::" (its class-method separator) and
19+
// matches "::"/"."/"#" queries against full_name instead of name. Ruby's
20+
// special variables are indexed with their "$" sigil in full_name, and one of
21+
// them ($.) contains a literal "." — so a "$." query would become "$::" and
22+
// never match. Wrap parseQuery so that any "$"-prefixed (special variable)
23+
// query keeps its literal text and is matched against full_name.
24+
// See https://github.com/rurema/bitclust/issues/194
25+
if (typeof parseQuery === 'function') {
26+
var alikiParseQuery = parseQuery;
27+
parseQuery = function(query) {
28+
var q = alikiParseQuery(query);
29+
if (query.charAt(0) === '$') {
30+
q.normalized = query.toLowerCase(); // undo the "." -> "::" rewrite
31+
q.matchesFullName = true; // the "$" sigil lives in full_name
32+
}
33+
return q;
34+
};
35+
}
36+
1637
function createSearchInstance(input, result) {
1738
if (!input || !result) return null;
1839

0 commit comments

Comments
 (0)