Skip to content

Commit

Permalink
feat(search): optionally enable regex (onivim#3641)
Browse files Browse the repository at this point in the history
* Ripgrep: add enableRegex flag to findInFiles

* Ripgrep: conditionally enable --fixed-strings

* Service_Ripgrep: add enableRegex to findInFilesParams

* Feature_Search: add button to enable/disable regex

* Feature_Search: make Enable Regex button focusable

I also switched out the if statements in the Navigation updater for switch
statements. Not only is this cleaner from a Finite State Machine perspective
IMO, but it also (should be) faster since variants are backed by integers so
it can be a simple jump rather than a conditional jump.

* Minor tweaks - sneakable, tooltip, msg refactor

* Add to CHANGES

Co-authored-by: Bryan Phelps <[email protected]>
  • Loading branch information
zbaylin and bryphe authored Jun 3, 2021
1 parent 8e2bb1e commit 0722d93
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGES_CURRENT.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
### Features

- #3613 - Input: add Emoji & Symbols panel on macOS
- #3641 - Search: add button to enable RegEx

### Bug Fixes

Expand Down
17 changes: 7 additions & 10 deletions src/Core/Ripgrep.re
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ type t = {
~query: string,
~onUpdate: list(Match.t) => unit,
~onComplete: unit => unit,
~onError: string => unit
~onError: string => unit,
~enableRegex: bool=?,
unit
) =>
dispose,
}
Expand Down Expand Up @@ -282,22 +284,17 @@ let findInFiles =
~onUpdate,
~onComplete,
~onError,
~enableRegex=false,
(),
) => {
let excludeArgs =
searchExclude
|> List.filter(str => !StringEx.isEmpty(str))
|> List.concat_map(x => ["-g", "!" ++ x]);
let args =
excludeArgs
@ [
"--fixed-strings",
"--smart-case",
"--hidden",
"--json",
"--",
query,
directory,
];
@ (enableRegex ? [] : ["--fixed-strings"])
@ ["--smart-case", "--hidden", "--json", "--", query, directory];
process(
executablePath,
args,
Expand Down
4 changes: 3 additions & 1 deletion src/Core/Ripgrep.rei
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ type t = {
~query: string,
~onUpdate: list(Match.t) => unit,
~onComplete: unit => unit,
~onError: string => unit
~onError: string => unit,
~enableRegex: bool=?,
unit
) =>
dispose,
}
Expand Down
95 changes: 78 additions & 17 deletions src/Feature/Search/Feature_Search.re
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ open EditorCoreTypes;
open Oni_Core;
open Oni_Components;

module Constants = {
let optionIconSize = 14.;
};

// MODEL

type focus =
| FindInput
| ResultsPane;
| ResultsPane
| EnableRegexButton;

type model = {
findInput: Component_InputText.model,
enableRegex: bool,
query: string,
searchNonce: int,
hits: list(Ripgrep.Match.t),
Expand All @@ -33,6 +39,7 @@ let resetFocus = (~query: option(string), model) => {

let initial = {
findInput: Component_InputText.create(~placeholder="Search"),
enableRegex: false,
query: "",
searchNonce: 0,
hits: [],
Expand Down Expand Up @@ -91,7 +98,8 @@ type msg =
| SearchError(string)
| FindInput(Component_InputText.msg)
| VimWindowNav(Component_VimWindows.msg)
| ResultsList(Component_VimTree.msg);
| ResultsList(Component_VimTree.msg)
| ToggleRegexButtonClicked;

module Msg = {
let input = str => Input(str);
Expand Down Expand Up @@ -140,15 +148,21 @@ let update = (~previewEnabled, model, msg) => {
},
None,
)
| EnableRegexButton =>
switch (key) {
| "<CR>" => ({...model, enableRegex: !model.enableRegex}, None)
| _ => (model, None)
}
}

| Pasted(text) =>
switch (model.focus) {
| FindInput =>
let findInput = Component_InputText.paste(~text, model.findInput);
({...model, findInput}, None);
| EnableRegexButton
| ResultsPane =>
// Paste is a no-op in search pane
// Paste is a no-op in search pane and button
(model, None)
}

Expand All @@ -174,19 +188,26 @@ let update = (~previewEnabled, model, msg) => {
let model' = {...model, vimWindowNavigation: windowNav};
switch (outmsg) {
| Nothing => (model', None)
| FocusLeft => (model', Some(UnhandledWindowMovement(outmsg)))
| FocusRight => (model', Some(UnhandledWindowMovement(outmsg)))
| FocusLeft =>
switch (model'.focus) {
| EnableRegexButton => ({...model', focus: FindInput}, None)
| _ => (model', Some(UnhandledWindowMovement(outmsg)))
}
| FocusRight =>
switch (model'.focus) {
| FindInput => ({...model', focus: EnableRegexButton}, None)
| _ => (model', Some(UnhandledWindowMovement(outmsg)))
}
| FocusDown =>
if (model'.focus == FindInput) {
({...model', focus: ResultsPane}, None);
} else {
(model', Some(UnhandledWindowMovement(outmsg)));
switch (model'.focus) {
| FindInput
| EnableRegexButton => ({...model', focus: ResultsPane}, None)
| _ => (model', Some(UnhandledWindowMovement(outmsg)))
}
| FocusUp =>
if (model'.focus == ResultsPane) {
({...model', focus: FindInput}, None);
} else {
(model', Some(UnhandledWindowMovement(outmsg)));
switch (model'.focus) {
| ResultsPane => ({...model', focus: FindInput}, None)
| _ => (model', Some(UnhandledWindowMovement(outmsg)))
}
// TODO: What should tabs do for search? Toggle sidebar panes?
| PreviousTab
Expand Down Expand Up @@ -219,6 +240,17 @@ let update = (~previewEnabled, model, msg) => {
| Complete => (model, None)

| SearchError(_) => (model, None)

| ToggleRegexButtonClicked => (
{
...model,
enableRegex: !model.enableRegex,
searchNonce: model.searchNonce + 1,
focus: EnableRegexButton,
}
|> setHits([]),
None,
)
};
};

Expand Down Expand Up @@ -249,6 +281,7 @@ let sub = (~config, ~workingDirectory, ~setup, model) => {
~query=model.query,
~uniqueId=string_of_int(model.searchNonce),
~setup,
~enableRegex=model.enableRegex,
toMsg,
);
};
Expand All @@ -265,11 +298,12 @@ module Styles = {

let pane = [flexGrow(1), flexDirection(`Column)];

let focusColor = (~isFocused, ~theme) =>
isFocused
? Colors.focusBorder.from(theme) : Revery.Colors.transparentWhite;

let resultsPane = (~isFocused, ~theme) => {
let focusColor =
isFocused
? Colors.focusBorder.from(theme) : Revery.Colors.transparentWhite;
[flexGrow(1), border(~color=focusColor, ~width=1)];
[flexGrow(1), border(~color=focusColor(~isFocused, ~theme), ~width=1)];
};

let row = [
Expand All @@ -285,6 +319,12 @@ module Styles = {
];

let inputContainer = [width(150), flexShrink(0), flexGrow(1)];
let inputOptions = [paddingLeft(2)];
let inputOption = (~isFocused, ~theme) => [
cursor(Revery.MouseCursors.pointer),
padding(2),
border(~color=focusColor(~isFocused, ~theme), ~width=1),
];
};

let make =
Expand Down Expand Up @@ -321,6 +361,27 @@ let make =
theme
/>
</View>
<View style=Styles.inputOptions>
<Tooltip text="Toggle regular expression syntax">
<Feature_Sneak.View.Sneakable
sneakId="search.toggleRegex"
style={Styles.inputOption(
~isFocused=model.focus == EnableRegexButton,
~theme,
)}
onClick={_ => dispatch(ToggleRegexButtonClicked)}>
<Codicon
icon=Codicon.regex
fontSize=Constants.optionIconSize
color={
model.enableRegex
? Colors.PanelTitle.activeForeground.from(theme)
: Colors.PanelTitle.inactiveForeground.from(theme)
}
/>
</Feature_Sneak.View.Sneakable>
</Tooltip>
</View>
</View>
</View>
<View
Expand Down
2 changes: 1 addition & 1 deletion src/Feature/Search/dune
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
(name Feature_Search)
(public_name Oni2.feature.search)
(libraries Oni2.service.ripgrep Oni2.editor-core-types Oni2.core
Oni2.components Oni2.component.vimTree Oni2.service.font
Oni2.components Oni2.feature.sneak Oni2.component.vimTree Oni2.service.font
Oni2.component.inputText Oni2.component.vimList Oni2.component.vimWindows
Oni2.feature.theme Revery)
(preprocess
Expand Down
13 changes: 12 additions & 1 deletion src/Service/Ripgrep/Service_Ripgrep.re
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module Sub = {
query: string,
uniqueId: string,
setup: Setup.t,
enableRegex: bool,
};

module FindInFilesSub =
Expand Down Expand Up @@ -41,6 +42,8 @@ module Sub = {
~onUpdate=items => dispatch(GotMatches(items)),
~onComplete=() => {dispatch(Completed)},
~onError=msg => dispatch(Error(msg)),
~enableRegex=params.enableRegex,
(),
);
{dispose: dispose};
};
Expand All @@ -61,8 +64,16 @@ module Sub = {
~directory: string,
~query: string,
~setup: Setup.t,
~enableRegex=false,
toMsg,
) =>
FindInFilesSub.create({uniqueId, exclude, directory, query, setup})
FindInFilesSub.create({
uniqueId,
exclude,
directory,
query,
setup,
enableRegex,
})
|> Isolinear.Sub.map(toMsg);
};
1 change: 1 addition & 0 deletions src/Service/Ripgrep/Service_Ripgrep.rei
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module Sub: {
~directory: string,
~query: string,
~setup: Setup.t,
~enableRegex: bool=?,
findInFilesMsg => 'msg
) =>
Isolinear.Sub.t('msg);
Expand Down

0 comments on commit 0722d93

Please sign in to comment.