Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Commit

Permalink
File search reducer (#4368)
Browse files Browse the repository at this point in the history
  • Loading branch information
codehag authored and jasonLaster committed Oct 13, 2017
1 parent c64c957 commit 4e4df33
Show file tree
Hide file tree
Showing 16 changed files with 370 additions and 307 deletions.
135 changes: 135 additions & 0 deletions src/actions/file-search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// @flow

import { find, findNext, findPrev, removeOverlay } from "../utils/editor";
import { getMatches } from "../workers/search";
import type { ThunkArgs } from "./types";

import {
getSelectedSource,
getFileSearchModifiers,
getFileSearchQuery,
getFileSearchResults
} from "../selectors";

import {
closeActiveSearch,
clearHighlightLineRange,
setActiveSearch
} from "./ui";
type Editor = Object;
type Match = Object;

export function doSearch(query: string, editor: Editor) {
return ({ getState, dispatch }: ThunkArgs) => {
const selectedSource = getSelectedSource(getState());
if (!selectedSource || !selectedSource.get("text")) {
return;
}

dispatch(setFileSearchQuery(query));
dispatch(searchContents(query, editor));
};
}

export function setFileSearchQuery(query: string) {
return {
type: "UPDATE_FILE_SEARCH_QUERY",
query
};
}

export function toggleFileSearchModifier(modifier: string) {
return { type: "TOGGLE_FILE_SEARCH_MODIFIER", modifier };
}

export function updateSearchResults(
characterIndex: number,
line: number,
matches: Match[]
) {
const matchIndex = matches.findIndex(
elm => elm.line === line && elm.ch === characterIndex
);

return {
type: "UPDATE_SEARCH_RESULTS",
results: {
matches,
matchIndex,
count: matches.length,
index: characterIndex
}
};
}

export function searchContents(query: string, editor: Object) {
return async ({ getState, dispatch }: ThunkArgs) => {
const modifiers = getFileSearchModifiers(getState());
const selectedSource = getSelectedSource(getState());

if (
!query ||
!editor ||
!selectedSource ||
!selectedSource.get("text") ||
!modifiers
) {
return;
}

const ctx = { ed: editor, cm: editor.codeMirror };
const _modifiers = modifiers.toJS();
const matches = await getMatches(
query,
selectedSource.get("text"),
_modifiers
);
const { ch, line } = find(ctx, query, true, _modifiers);

dispatch(updateSearchResults(ch, line, matches));
};
}

export function traverseResults(rev: boolean, editor: Editor) {
return async ({ getState, dispatch }: ThunkArgs) => {
if (!editor) {
return;
}

const ctx = { ed: editor, cm: editor.codeMirror };

const query = getFileSearchQuery(getState());
const modifiers = getFileSearchModifiers(getState());
const { matches } = getFileSearchResults(getState());

if (query === "") {
dispatch(setActiveSearch("file"));
}

if (modifiers) {
const matchedLocations = matches || [];
const { ch, line } = rev
? findPrev(ctx, query, true, modifiers.toJS())
: findNext(ctx, query, true, modifiers.toJS());

console.log(line);
dispatch(updateSearchResults(ch, line, matchedLocations));
}
};
}

export function closeFileSearch(editor: Editor) {
return ({ getState, dispatch }: ThunkArgs) => {
const modifiers = getFileSearchModifiers(getState());
const query = getFileSearchQuery(getState());

if (editor && modifiers) {
const ctx = { ed: editor, cm: editor.codeMirror };
removeOverlay(ctx, query, modifiers.toJS());
}

dispatch(setFileSearchQuery(""));
dispatch(closeActiveSearch());
dispatch(clearHighlightLineRange());
};
}
2 changes: 2 additions & 0 deletions src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as sources from "./sources";
import * as pause from "./pause";
import * as navigation from "./navigation";
import * as ui from "./ui";
import * as fileSearch from "./file-search";
import * as ast from "./ast";
import * as coverage from "./coverage";
import * as projectTextSearch from "./project-text-search";
Expand All @@ -25,6 +26,7 @@ export default Object.assign(
sources,
pause,
ui,
fileSearch,
ast,
coverage,
projectTextSearch,
Expand Down
47 changes: 47 additions & 0 deletions src/actions/tests/file-search.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { createStore, selectors, actions } from "../../utils/test-head";

const {
getFileSearchQuery,
getFileSearchModifiers,
getFileSearchResults
} = selectors;

describe("file text search", () => {
it("should update search results", () => {
const { dispatch, getState } = createStore();
expect(getFileSearchResults(getState())).toEqual({
matches: [],
matchIndex: -1,
index: -1,
count: 0
});

const matches = [{ line: 1, ch: 3 }, { line: 3, ch: 2 }];
dispatch(actions.updateSearchResults(2, 3, matches));

expect(getFileSearchResults(getState())).toEqual({
count: 2,
index: 2,
matchIndex: 1,
matches: matches
});
});

it("should update the file search query", () => {
const { dispatch, getState } = createStore();
let fileSearchQueryState = getFileSearchQuery(getState());
expect(fileSearchQueryState).toBe("");
dispatch(actions.setFileSearchQuery("foobar"));
fileSearchQueryState = getFileSearchQuery(getState());
expect(fileSearchQueryState).toBe("foobar");
});

it("should toggle a file search modifier", () => {
const { dispatch, getState } = createStore();
let fileSearchModState = getFileSearchModifiers(getState());
expect(fileSearchModState.get("caseSensitive")).toBe(false);
dispatch(actions.toggleFileSearchModifier("caseSensitive"));
fileSearchModState = getFileSearchModifiers(getState());
expect(fileSearchModState.get("caseSensitive")).toBe(true);
});
});
42 changes: 0 additions & 42 deletions src/actions/tests/ui.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import { createStore, selectors, actions } from "../../utils/test-head";

const {
getActiveSearch,
getFileSearchQueryState,
getFileSearchModifierState,
getFrameworkGroupingState,
getPaneCollapse,
getSymbolSearchType,
getHighlightedLineRange,
getSearchResults,
getProjectDirectoryRoot
} = selectors;

Expand All @@ -35,20 +32,6 @@ describe("ui", () => {
expect(getActiveSearch(getState())).toBe("file");
});

it("should update search results", () => {
const { dispatch, getState } = createStore();
expect(getSearchResults(getState())).toEqual({
matches: [],
matchIndex: -1,
index: -1,
count: 0
});

const results = { count: 3, index: 2 };
dispatch(actions.updateSearchResults(results));
expect(getSearchResults(getState())).toEqual(results);
});

it("should close file search", () => {
const { dispatch, getState } = createStore();
expect(getActiveSearch(getState())).toBe(null);
Expand All @@ -57,31 +40,6 @@ describe("ui", () => {
expect(getActiveSearch(getState())).toBe(null);
});

it("should update the file search query", () => {
const { dispatch, getState } = createStore();
let fileSearchQueryState = getFileSearchQueryState(getState());
expect(fileSearchQueryState).toBe("");
dispatch(actions.setFileSearchQuery("foobar"));
fileSearchQueryState = getFileSearchQueryState(getState());
expect(fileSearchQueryState).toBe("foobar");
});

it("should toggle a file search modifier", () => {
const { dispatch, getState } = createStore();
let fileSearchModState = getFileSearchModifierState(getState());
expect(fileSearchModState.get("caseSensitive")).toBe(false);
dispatch(actions.toggleFileSearchModifier("caseSensitive"));
fileSearchModState = getFileSearchModifierState(getState());
expect(fileSearchModState.get("caseSensitive")).toBe(true);
});

it("should toggle the symbol search state", () => {
const { dispatch, getState } = createStore();
expect(getActiveSearch(getState())).toBe(null);
dispatch(actions.setActiveSearch("symbol"));
expect(getActiveSearch(getState())).toBe("symbol");
});

it("should change the selected symbol type", () => {
const { dispatch, getState } = createStore();
dispatch(actions.setSelectedSymbolType("variables"));
Expand Down
26 changes: 21 additions & 5 deletions src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {

import type { State } from "../reducers/types";
import type { ActiveSearchType } from "../reducers/ui";
import type { MatchedLocations } from "../reducers/file-search";

import type { SymbolDeclaration, AstLocation } from "../workers/parser";

Expand Down Expand Up @@ -67,7 +68,7 @@ type AddBreakpointResult = {
type ProjectTextSearchResult = {
sourceId: string,
filepath: string,
matches: Array<any>
matches: MatchedLocations[]
};

type BreakpointAction =
Expand Down Expand Up @@ -148,10 +149,6 @@ type UIAction =
type: "TOGGLE_ACTIVE_SEARCH",
value: ?ActiveSearchType
}
| {
type: "TOGGLE_FILE_SEARCH_MODIFIER",
modifier: "caseSensitive" | "wholeWord" | "regexMatch"
}
| {
type: "TOGGLE_FRAMEWORK_GROUPING",
value: boolean
Expand Down Expand Up @@ -255,6 +252,25 @@ export type ProjectTextSearchAction = {
type: "CLEAR_QUERY"
};

export type FileTextSearchAction =
| {
type: "TOGGLE_FILE_SEARCH_MODIFIER",
modifier: "caseSensitive" | "wholeWord" | "regexMatch"
}
| {
type: "UPDATE_FILE_SEARCH_QUERY",
query: string
}
| {
type: "UPDATE_SEARCH_RESULTS",
results: {
matches: MatchedLocations[],
matchIndex: number,
count: number,
index: number
}
};

/**
* Actions: Source, Breakpoint, and Navigation
*
Expand Down
18 changes: 0 additions & 18 deletions src/actions/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,24 +57,6 @@ export function setSelectedSymbolType(symbolType: SymbolSearchType) {
};
}

export function setFileSearchQuery(query: string) {
return {
type: "UPDATE_FILE_SEARCH_QUERY",
query
};
}

export function updateSearchResults(results: Object) {
return {
type: "UPDATE_SEARCH_RESULTS",
results
};
}

export function toggleFileSearchModifier(modifier: string) {
return { type: "TOGGLE_FILE_SEARCH_MODIFIER", modifier };
}

export function showSource(sourceId: string) {
return ({ dispatch, getState }: ThunkArgs) => {
const source = getSource(getState(), sourceId);
Expand Down
Loading

0 comments on commit 4e4df33

Please sign in to comment.