Skip to content

Instantly share code, notes, and snippets.

@wldcordeiro
Last active January 29, 2018 23:50
Show Gist options
  • Save wldcordeiro/8824d28e37a534f745be398285d73aed to your computer and use it in GitHub Desktop.
Save wldcordeiro/8824d28e37a534f745be398285d73aed to your computer and use it in GitHub Desktop.
diff --git a/src/components/QuickOpenModal.css b/src/components/QuickOpenModal.css
new file mode 100644
index 00000000..8de5a216
--- /dev/null
+++ b/src/components/QuickOpenModal.css
@@ -0,0 +1,3 @@
+.result-item .title .matching-character {
+ font-weight: bold;
+}
diff --git a/src/components/QuickOpenModal.js b/src/components/QuickOpenModal.js
index 1fde7423..341ed59b 100644
--- a/src/components/QuickOpenModal.js
+++ b/src/components/QuickOpenModal.js
@@ -22,7 +22,8 @@ import {
formatSymbols,
formatSources,
parseLineColumn,
- formatShortcutResults
+ formatShortcutResults,
+ groupSharedChars
} from "../utils/quick-open";
import Modal from "./shared/Modal";
import SearchInput from "./shared/SearchInput";
@@ -37,6 +38,8 @@ import type { Location } from "debugger-html";
import type { SourceRecord } from "../reducers/sources";
import type { QuickOpenType } from "../reducers/quick-open";
+import "./QuickOpenModal.css";
+
type Props = {
enabled: boolean,
sources: Array<Object>,
@@ -294,6 +297,33 @@ export class QuickOpenModal extends Component<Props, State> {
isGotoSourceQuery = () => this.props.searchType === "gotoSource";
isShortcutQuery = () => this.props.searchType === "shortcuts";
+ highlightMatching = (query: string, results: QuickOpenResult[]) => {
+ if (query === "") {
+ return results;
+ }
+ const queryLetters = query.toLowerCase().split("");
+ return results.map(result => {
+ const resultParts = result.title.toLowerCase().split("");
+ const title = groupSharedChars(resultParts, queryLetters);
+ return {
+ ...result,
+ title: title.map((part, i) => {
+ if (Array.isArray(part)) {
+ return (
+ <span
+ key={`${part.join("")}-${i}`}
+ className="matching-character"
+ >
+ {part.join("")}
+ </span>
+ );
+ }
+ return part;
+ })
+ };
+ });
+ };
+
render() {
const { enabled, query, searchType } = this.props;
const { selectedIndex, results } = this.state;
@@ -328,7 +358,7 @@ export class QuickOpenModal extends Component<Props, State> {
{newResults && (
<ResultList
key="results"
- items={newResults}
+ items={this.highlightMatching(query, newResults)}
selected={selectedIndex}
selectItem={this.selectResultItem}
ref="resultList"
diff --git a/src/utils/quick-open.js b/src/utils/quick-open.js
index d3e1a0cc..f2fe172c 100644
--- a/src/utils/quick-open.js
+++ b/src/utils/quick-open.js
@@ -125,3 +125,28 @@ export function formatSources(sources: SourcesMap): Array<QuickOpenResult> {
.filter(({ value }) => value != "")
.toJS();
}
+
+export function groupSharedChars(parts: string[], letters: string[]) {
+ const shared = parts.filter(char => letters.includes(char));
+ const title = [];
+ let matched;
+ parts.forEach((char, i) => {
+ if (shared.includes(char)) {
+ if (!matched) {
+ matched = [char];
+ title.push(matched);
+ return;
+ }
+ matched = title[title.length - 1];
+ if (Array.isArray(matched)) {
+ matched.push(char);
+ } else {
+ matched = [char];
+ title.push(matched);
+ }
+ return;
+ }
+ title.push(char);
+ });
+ return title;
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment