Skip to content

Commit

Permalink
Implement q/ and q? (VSCodeVim#3956)
Browse files Browse the repository at this point in the history
These show your search history via a QuickPick, allowing you to search through and re-do these.
Also implemented an alias for these, which is `<C-f>` while typing a search.
Refs VSCodeVim#3949
  • Loading branch information
J-Fields authored and stevenguh committed Aug 27, 2019
1 parent 5a19d6c commit 2c70826
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 1 deletion.
39 changes: 38 additions & 1 deletion src/actions/commands/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
ReportFileInfo,
ReportSearch,
} from '../../util/statusBarTextUtils';
import { globalState } from '../../state/globalState';

export class DocumentContentChangeAction extends BaseAction {
contentChanges: {
Expand Down Expand Up @@ -884,7 +885,7 @@ class CommandReplaceInReplaceMode extends BaseCommand {
@RegisterAction
class CommandInsertInSearchMode extends BaseCommand {
modes = [ModeName.SearchInProgressMode];
keys = [['<character>'], ['<up>'], ['<down>'], ['<C-h>']];
keys = [['<character>'], ['<up>'], ['<down>'], ['<C-h>'], ['<C-f>']];
isJump = true;

runsOnceForEveryCursor() {
Expand All @@ -909,6 +910,11 @@ class CommandInsertInSearchMode extends BaseCommand {
searchState.searchString.slice(0, vimState.statusBarCursorCharacterPos - 1) +
searchState.searchString.slice(vimState.statusBarCursorCharacterPos);
vimState.statusBarCursorCharacterPos = Math.max(vimState.statusBarCursorCharacterPos - 1, 0);
} else if (key === '<C-f>') {
return new CommandShowSearchHistory(vimState.globalState.searchState!.searchDirection).exec(
position,
vimState
);
} else if (key === '\n') {
await vimState.setCurrentMode(vimState.globalState.searchState!.previousMode);

Expand Down Expand Up @@ -2139,6 +2145,37 @@ class CommandShowCommandHistory extends BaseCommand {
}
}

@RegisterAction
class CommandShowSearchHistory extends BaseCommand {
modes = [ModeName.Normal, ModeName.Visual, ModeName.VisualLine, ModeName.VisualBlock];
keys = [['q', '/'], ['q', '?']];

private direction = SearchDirection.Forward;

runsOnceForEveryCursor() {
return false;
}

public constructor(direction = SearchDirection.Forward) {
super();
this.direction = direction;
}

public async exec(position: Position, vimState: VimState): Promise<VimState> {
if (vimState.recordedState.commandList.includes('?')) {
this.direction = SearchDirection.Backward;
}
vimState.recordedState.transformations.push({
type: 'showSearchHistory',
direction: this.direction,
});

await vimState.setCurrentMode(ModeName.Normal);

return vimState;
}
}

@RegisterAction
class CommandDot extends BaseCommand {
modes = [ModeName.Normal];
Expand Down
17 changes: 17 additions & 0 deletions src/mode/modeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import {
isTextTransformation,
TextTransformations,
} from './../transformations/transformations';
import { globalState } from '../state/globalState';
import { ReportSearch } from '../util/statusBarTextUtils';

export class ModeHandler implements vscode.Disposable {
private _disposables: vscode.Disposable[] = [];
Expand Down Expand Up @@ -909,6 +911,21 @@ export class ModeHandler implements vscode.Disposable {
}
break;

case 'showSearchHistory':
const searchState = await globalState.showSearchHistory();
if (searchState) {
globalState.searchState = searchState;
const nextMatch = searchState.getNextSearchMatchPosition(
vimState.cursorStartPosition,
command.direction
);

vimState.cursorStopPosition = nextMatch.pos;
this.updateView(this.vimState);
ReportSearch(nextMatch.index, searchState.matchRanges.length, vimState);
}
break;

case 'dot':
if (!vimState.globalState.previousFullAction) {
return vimState; // TODO(bell)
Expand Down
25 changes: 25 additions & 0 deletions src/state/globalState.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as vscode from 'vscode';
import { JumpTracker } from '../jumps/jumpTracker';
import { ModeName } from '../mode/mode';
import { Position } from '../common/motion/position';
Expand All @@ -6,6 +7,7 @@ import { SearchHistory } from '../history/historyFile';
import { SearchState, SearchDirection } from './searchState';
import { SubstituteState } from './substituteState';
import { configuration } from '../configuration/configuration';
import { VimState } from './vimState';

/**
* State which stores global state (across editors)
Expand Down Expand Up @@ -102,6 +104,29 @@ class GlobalState {
this.searchStateIndex = this.searchStatePrevious.length - 1;
}

public async showSearchHistory(): Promise<SearchState | undefined> {
if (!vscode.window.activeTextEditor) {
return undefined;
}

const items = this._searchStatePrevious
.slice()
.reverse()
.map(searchState => {
return {
label: searchState.searchString,
searchState: searchState,
};
});

const item = await vscode.window.showQuickPick(items, {
placeHolder: 'Vim search history',
ignoreFocusOut: false,
});

return item ? item.searchState : undefined;
}

public get jumpTracker(): JumpTracker {
return this._jumpTracker;
}
Expand Down
6 changes: 6 additions & 0 deletions src/transformations/transformations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ export interface ShowCommandHistory {
type: 'showCommandHistory';
}

export interface ShowSearchHistory {
type: 'showSearchHistory';
direction: number;
}

/**
* Represents pressing '.'
*/
Expand Down Expand Up @@ -247,6 +252,7 @@ export type Transformation =
| DeleteTextTransformation
| MoveCursorTransformation
| ShowCommandHistory
| ShowSearchHistory
| Dot
| Macro
| ContentChangeTransformation
Expand Down

0 comments on commit 2c70826

Please sign in to comment.