]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #49966 - GuillaumeGomez:comma-search, r=QuietMisdreavus
authorGuillaume Gomez <guillaume1.gomez@gmail.com>
Tue, 17 Apr 2018 16:43:15 +0000 (18:43 +0200)
committerGitHub <noreply@github.com>
Tue, 17 Apr 2018 16:43:15 +0000 (18:43 +0200)
Multiple query search

Part of #49757.

r? @QuietMisdreavus

src/librustdoc/html/layout.rs
src/librustdoc/html/static/main.js
src/test/rustdoc-js/multi-query.js [new file with mode: 0644]
src/tools/rustdoc-js/tester.js

index aac5d0d2601deca63ff43b781d06086a83a63a13..583c9f2b671441f0602e83887071add233727089 100644 (file)
@@ -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,
index 3a3fa833c238ba569da70ade3fa9444ee0dd9ec0..2546a9410a9f653a44fb12dc37aa80f9ab287a26 100644 (file)
             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();
             }
                 }
             }
 
-            results = execQuery(query, index);
-            showResults(results);
+            showResults(execSearch(query, index));
         }
 
         function buildIndex(rawSearchIndex) {
diff --git a/src/test/rustdoc-js/multi-query.js b/src/test/rustdoc-js/multi-query.js
new file mode 100644 (file)
index 0000000..3793ca6
--- /dev/null
@@ -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' },
+    ],
+};
index 7c9ee2a49430bee0e3d9eabf3976f743ac7a0295..1e6c4336a9e995cf054399bc5cef863d1f67471e 100644 (file)
@@ -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);
@@ -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) {