Skip to content

Commit

Permalink
Rollup merge of rust-lang#49966 - GuillaumeGomez:comma-search, r=Quie…
Browse files Browse the repository at this point in the history
…tMisdreavus

Multiple query search

Part of rust-lang#49757.

r? @QuietMisdreavus
  • Loading branch information
GuillaumeGomez authored Apr 17, 2018
2 parents 7a39e90 + c83c7c9 commit 7a6fad3
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 131 deletions.
232 changes: 110 additions & 122 deletions src/librustdoc/html/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,128 +37,116 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
-> io::Result<()>
{
write!(dst,
r##"<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<meta name="description" content="{description}">
<meta name="keywords" content="{keywords}">
<title>{title}</title>
<link rel="stylesheet" type="text/css" href="{root_path}normalize{suffix}.css">
<link rel="stylesheet" type="text/css" href="{root_path}rustdoc{suffix}.css"
id="mainThemeStyle">
{themes}
<link rel="stylesheet" type="text/css" href="{root_path}dark{suffix}.css">
<link rel="stylesheet" type="text/css" href="{root_path}light{suffix}.css" id="themeStyle">
<script src="{root_path}storage{suffix}.js"></script>
{css_extension}
{favicon}
{in_header}
</head>
<body class="rustdoc {css_class}">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
{before_content}
<nav class="sidebar">
<div class="sidebar-menu">&#9776;</div>
{logo}
{sidebar}
</nav>
<div class="theme-picker">
<button id="theme-picker" aria-label="Pick another theme!">
<img src="{root_path}brush{suffix}.svg" width="18" alt="Pick another theme!">
</button>
<div id="theme-choices"></div>
</div>
<script src="{root_path}theme{suffix}.js"></script>
<nav class="sub">
<form class="search-form js-only">
<div class="search-container">
<input class="search-input" name="search"
autocomplete="off"
placeholder="Click or press ‘S’ to search, ‘?’ for more options…"
type="search">
</div>
</form>
</nav>
<section id='main' class="content">{content}</section>
<section id='search' class="content hidden"></section>
<section class="footer"></section>
<aside id="help" class="hidden">
<div>
<h1 class="hidden">Help</h1>
<div class="shortcuts">
<h2>Keyboard Shortcuts</h2>
<dl>
<dt><kbd>?</kbd></dt>
<dd>Show this help dialog</dd>
<dt><kbd>S</kbd></dt>
<dd>Focus the search field</dd>
<dt><kbd>↑</kbd></dt>
<dd>Move up in search results</dd>
<dt><kbd>↓</kbd></dt>
<dd>Move down in search results</dd>
<dt><kbd>↹</kbd></dt>
<dd>Switch tab</dd>
<dt><kbd>&#9166;</kbd></dt>
<dd>Go to active search result</dd>
<dt><kbd>+</kbd></dt>
<dd>Expand all sections</dd>
<dt><kbd>-</kbd></dt>
<dd>Collapse all sections</dd>
</dl>
</div>
<div class="infos">
<h2>Search Tricks</h2>
<p>
Prefix searches with a type followed by a colon (e.g.
<code>fn:</code>) to restrict the search to a given type.
</p>
<p>
Accepted types are: <code>fn</code>, <code>mod</code>,
<code>struct</code>, <code>enum</code>,
<code>trait</code>, <code>type</code>, <code>macro</code>,
and <code>const</code>.
</p>
<p>
Search functions by type signature (e.g.
<code>vec -> usize</code> or <code>* -> vec</code>)
</p>
</div>
</div>
</aside>
{after_content}
<script>
window.rootPath = "{root_path}";
window.currentCrate = "{krate}";
</script>
<script src="{root_path}main{suffix}.js"></script>
<script defer src="{root_path}search-index.js"></script>
</body>
</html>"##,
"<!DOCTYPE html>\
<html lang=\"en\">\
<head>\
<meta charset=\"utf-8\">\
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\
<meta name=\"generator\" content=\"rustdoc\">\
<meta name=\"description\" content=\"{description}\">\
<meta name=\"keywords\" content=\"{keywords}\">\
<title>{title}</title>\
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}normalize{suffix}.css\">\
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}rustdoc{suffix}.css\" \
id=\"mainThemeStyle\">\
{themes}\
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}dark{suffix}.css\">\
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}light{suffix}.css\" \
id=\"themeStyle\">\
<script src=\"{root_path}storage{suffix}.js\"></script>\
{css_extension}\
{favicon}\
{in_header}\
</head>\
<body class=\"rustdoc {css_class}\">\
<!--[if lte IE 8]>\
<div class=\"warning\">\
This old browser is unsupported and will most likely display funky \
things.\
</div>\
<![endif]-->\
{before_content}\
<nav class=\"sidebar\">\
<div class=\"sidebar-menu\">&#9776;</div>\
{logo}\
{sidebar}\
</nav>\
<div class=\"theme-picker\">\
<button id=\"theme-picker\" aria-label=\"Pick another theme!\">\
<img src=\"{root_path}brush{suffix}.svg\" width=\"18\" alt=\"Pick another theme!\">\
</button>\
<div id=\"theme-choices\"></div>\
</div>\
<script src=\"{root_path}theme{suffix}.js\"></script>\
<nav class=\"sub\">\
<form class=\"search-form js-only\">\
<div class=\"search-container\">\
<input class=\"search-input\" name=\"search\" \
autocomplete=\"off\" \
placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
type=\"search\">\
</div>\
</form>\
</nav>\
<section id=\"main\" class=\"content\">{content}</section>\
<section id=\"search\" class=\"content hidden\"></section>\
<section class=\"footer\"></section>\
<aside id=\"help\" class=\"hidden\">\
<div>\
<h1 class=\"hidden\">Help</h1>\
<div class=\"shortcuts\">\
<h2>Keyboard Shortcuts</h2>\
<dl>\
<dt><kbd>?</kbd></dt>\
<dd>Show this help dialog</dd>\
<dt><kbd>S</kbd></dt>\
<dd>Focus the search field</dd>\
<dt><kbd>↑</kbd></dt>\
<dd>Move up in search results</dd>\
<dt><kbd>↓</kbd></dt>\
<dd>Move down in search results</dd>\
<dt><kbd>↹</kbd></dt>\
<dd>Switch tab</dd>\
<dt><kbd>&#9166;</kbd></dt>\
<dd>Go to active search result</dd>\
<dt><kbd>+</kbd></dt>\
<dd>Expand all sections</dd>\
<dt><kbd>-</kbd></dt>\
<dd>Collapse all sections</dd>\
</dl>\
</div>\
<div class=\"infos\">\
<h2>Search Tricks</h2>\
<p>\
Prefix searches with a type followed by a colon (e.g. \
<code>fn:</code>) to restrict the search to a given type.\
</p>\
<p>\
Accepted types are: <code>fn</code>, <code>mod</code>, \
<code>struct</code>, <code>enum</code>, \
<code>trait</code>, <code>type</code>, <code>macro</code>, \
and <code>const</code>.\
</p>\
<p>\
Search functions by type signature (e.g. \
<code>vec -> usize</code> or <code>* -> vec</code>)\
</p>\
<p>\
Search multiple things at once by splitting your query with comma (e.g. \
<code>str,u8</code> or <code>String,struct:Vec,test</code>)\
</p>\
</div>\
</div>\
</aside>\
{after_content}\
<script>\
window.rootPath = \"{root_path}\";\
window.currentCrate = \"{krate}\";\
</script>\
<script src=\"{root_path}main{suffix}.js\"></script>\
<script defer src=\"{root_path}search-index.js\"></script>\
</body>\
</html>",
css_extension = if css_file_extension {
format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme{suffix}.css\">",
root_path = page.root_path,
Expand Down
77 changes: 70 additions & 7 deletions src/librustdoc/html/static/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1299,14 +1299,78 @@
printTab(currentTab);
}

function execSearch(query, searchWords) {
var queries = query.raw.split(",");
var results = {
'in_args': [],
'returned': [],
'others': [],
};

for (var i = 0; i < queries.length; ++i) {
var query = queries[i].trim();
if (query.length !== 0) {
var tmp = execQuery(getQuery(query), searchWords);

results['in_args'].push(tmp['in_args']);
results['returned'].push(tmp['returned']);
results['others'].push(tmp['others']);
}
}
if (queries.length > 1) {
function getSmallest(arrays, positions) {
var start = null;

for (var it = 0; it < positions.length; ++it) {
if (arrays[it].length > positions[it] &&
(start === null || start > arrays[it][positions[it]].lev)) {
start = arrays[it][positions[it]].lev;
}
}
return start;
}

function mergeArrays(arrays) {
var ret = [];
var positions = [];

for (var x = 0; x < arrays.length; ++x) {
positions.push(0);
}
while (ret.length < MAX_RESULTS) {
var smallest = getSmallest(arrays, positions);
if (smallest === null) {
break;
}
for (x = 0; x < arrays.length && ret.length < MAX_RESULTS; ++x) {
if (arrays[x].length > positions[x] &&
arrays[x][positions[x]].lev === smallest) {
ret.push(arrays[x][positions[x]]);
positions[x] += 1;
}
}
}
return ret;
}

return {
'in_args': mergeArrays(results['in_args']),
'returned': mergeArrays(results['returned']),
'others': mergeArrays(results['others']),
};
} else {
return {
'in_args': results['in_args'][0],
'returned': results['returned'][0],
'others': results['others'][0],
};
}
}

function search(e) {
var query,
obj, i, len,
results = {"in_args": [], "returned": [], "others": []},
resultIndex;
var params = getQueryStringParams();
var query = getQuery(document.getElementsByClassName('search-input')[0].value);

query = getQuery(document.getElementsByClassName('search-input')[0].value);
if (e) {
e.preventDefault();
}
Expand All @@ -1328,8 +1392,7 @@
}
}

results = execQuery(query, index);
showResults(results);
showResults(execSearch(query, index));
}

function buildIndex(rawSearchIndex) {
Expand Down
20 changes: 20 additions & 0 deletions src/test/rustdoc-js/multi-query.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

const QUERY = 'str,u8';

const EXPECTED = {
'others': [
{ 'path': 'std', 'name': 'str' },
{ 'path': 'std', 'name': 'u8' },
{ 'path': 'std::ffi', 'name': 'CStr' },
{ 'path': 'std::simd', 'name': 'u8x2' },
],
};
5 changes: 3 additions & 2 deletions src/tools/rustdoc-js/tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ function main(argv) {
// execQuery first parameter is built in getQuery (which takes in the search input).
// execQuery last parameter is built in buildIndex.
// buildIndex requires the hashmap from search-index.
var functionsToLoad = ["levenshtein", "validateResult", "getQuery", "buildIndex", "execQuery"];
var functionsToLoad = ["levenshtein", "validateResult", "getQuery", "buildIndex", "execQuery",
"execSearch"];

finalJS += 'window = { "currentCrate": "std" };\n';
finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
Expand All @@ -174,7 +175,7 @@ function main(argv) {
'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
const expected = loadedFile.EXPECTED;
const query = loadedFile.QUERY;
var results = loaded.execQuery(loaded.getQuery(query), index);
var results = loaded.execSearch(loaded.getQuery(query), index);
process.stdout.write('Checking "' + file + '" ... ');
var error_text = [];
for (var key in expected) {
Expand Down

0 comments on commit 7a6fad3

Please sign in to comment.