-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Implements vimgrep, #5991 #9630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 14 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
c793d57
pattern and file argument reading
AzimovParviz e771364
basic vimgrep functionality
AzimovParviz 29cfb70
removed assignment to grepResults, since this is unnecessary
AzimovParviz fc6aee0
update link to the reference documentation
AzimovParviz 8b0a5d6
adds focus on the search window
AzimovParviz 0791d2a
adds focus on the first search result when running vimgrep without th…
AzimovParviz f0b441b
fixed pattern separator being accidentally removed
AzimovParviz 09cbf5f
removed the console log and unneeded argument
AzimovParviz 48aa9f8
Basic grep test that checks if arguments are correctly parsed and whe…
AzimovParviz 910411f
Merge branch 'master' into master
J-Fields 7991c7d
remove eslint-disable
AzimovParviz 5c448b0
remove console.log from grep.ts
AzimovParviz dc00e9f
commit code review changes
AzimovParviz dc44f05
Merge branch 'master' into master
J-Fields d8702e6
Merge branch 'master' into master
AzimovParviz 7fe9546
Merge branch 'master' into master
AzimovParviz ff83245
removed unneeded grep command from the parse list
AzimovParviz 9d886be
added comments
AzimovParviz 7447634
vimgrep command parse test
AzimovParviz 5c4cdb6
wip on refactoring the grep test to use testutils
AzimovParviz 15bc1a3
reworked the grep test to use testUtils's createFile
AzimovParviz eea4d23
Merge branch 'master' into master
J-Fields File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import * as vscode from 'vscode'; | ||
|
||
import * as error from '../../error'; | ||
import { VimState } from '../../state/vimState'; | ||
import { Pattern, SearchDirection } from '../../vimscript/pattern'; | ||
import { ExCommand } from '../../vimscript/exCommand'; | ||
import { Parser, seq, optWhitespace, whitespace } from 'parsimmon'; | ||
import { fileNameParser } from '../../vimscript/parserUtils'; | ||
|
||
// Still missing: | ||
// When a number is put before the command this is used | ||
// as the maximum number of matches to find. Use | ||
// ":1vimgrep pattern file" to find only the first. | ||
// Useful if you only want to check if there is a match | ||
// and quit quickly when it's found. | ||
|
||
// Without the 'j' flag Vim jumps to the first match. | ||
// With 'j' only the quickfix list is updated. | ||
// With the [!] any changes in the current buffer are | ||
// abandoned. | ||
interface IGrepCommandArguments { | ||
pattern: Pattern; | ||
files: string[]; | ||
} | ||
|
||
// Implements :grep | ||
// https://vimdoc.sourceforge.net/htmldoc/quickfix.html#:vimgrep | ||
export class GrepCommand extends ExCommand { | ||
public static readonly argParser: Parser<GrepCommand> = optWhitespace.then( | ||
seq( | ||
Pattern.parser({ direction: SearchDirection.Backward, delimiter: ' ' }), | ||
fileNameParser.sepBy(whitespace), | ||
).map(([pattern, files]) => new GrepCommand({ pattern, files })), | ||
); | ||
|
||
public readonly arguments: IGrepCommandArguments; | ||
constructor(args: IGrepCommandArguments) { | ||
super(); | ||
this.arguments = args; | ||
} | ||
|
||
async execute(): Promise<void> { | ||
const { pattern, files } = this.arguments; | ||
if (files.length === 0) { | ||
throw error.VimError.fromCode(error.ErrorCode.NoFileName); | ||
} | ||
// There are other arguments that can be passed, but probably need to dig into the VSCode source code, since they are not listed in the API reference | ||
// https://code.visualstudio.com/api/references/commands | ||
// This link on the other hand has the commands and I used this as a reference | ||
// https://stackoverflow.com/questions/62251045/search-find-in-files-keybinding-can-take-arguments-workbench-view-search-can | ||
await vscode.commands.executeCommand('workbench.action.findInFiles', { | ||
query: pattern.patternString, | ||
filesToInclude: files.join(','), | ||
triggerSearch: true, | ||
isRegex: true, | ||
}); | ||
await vscode.commands.executeCommand('search.action.focusSearchList'); | ||
// Only if there's no [j] flag | ||
await vscode.commands.executeCommand('search.action.focusNextSearchResult'); | ||
// TODO: this will always throw an error, since the command returns nothing | ||
// if (!grepResults) { | ||
// throw error.VimError.fromCode(error.ErrorCode.PatternNotFound); | ||
// } | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import * as assert from 'assert'; | ||
import * as vscode from 'vscode'; | ||
|
||
import { getAndUpdateModeHandler } from '../../extension'; | ||
import * as t from '../testUtils'; | ||
import { GrepCommand } from '../../src/cmd_line/commands/grep'; | ||
import { Pattern, SearchDirection } from '../../src/vimscript/pattern'; | ||
import { Mode } from '../../src/mode/mode'; | ||
|
||
// This will go into the exCommandParse test | ||
// function exParseTest(input: string, parsed: ExCommand) { | ||
// test(input, () => { | ||
// const { command } = exCommandParser.tryParse(input); | ||
// assert.deepStrictEqual(command, parsed); | ||
// }); | ||
// } | ||
|
||
// suite('grep', () => { | ||
// const pattern = Pattern.parser({ direction: SearchDirection.Forward, delimiter: '/' }); | ||
// exParseTest(':vimgrep "t*st" foo.txt', | ||
// new GrepCommand({ | ||
// pattern: pattern.tryParse('t*st'), | ||
// files: ['foo.txt'], | ||
// }), | ||
// ); | ||
// }); | ||
AzimovParviz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
function grep(pattern: Pattern, files: string[]): GrepCommand { | ||
return new GrepCommand({ pattern, files }); | ||
} | ||
|
||
suite('Basic grep command', () => { | ||
setup(t.setupWorkspace); | ||
suiteTeardown(t.cleanUpWorkspace); | ||
test('GrepCommand parses correctly', async () => { | ||
await vscode.commands.executeCommand('workbench.action.files.newUntitledFile'); | ||
const pattern = Pattern.parser({ direction: SearchDirection.Backward, delimiter: '/' }); | ||
const command = grep(pattern.tryParse('t*st'), ['Untitled-1']); | ||
assert.deepStrictEqual(command.arguments, { | ||
pattern: pattern.tryParse('t*st'), | ||
files: ['Untitled-1'], | ||
}); | ||
}); | ||
AzimovParviz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// when you search.action.focusNextSearchResult , it will enter the file in visual mode for some reason, we can test whether it is in visual mode or not after running that command | ||
// that only happens if the search panel is not open already | ||
// if the search panel is open, it will be in normal mode | ||
// it will also be in normal mode if you run vimgrep from another file | ||
test('GrepCommand executes correctly', async () => { | ||
// Untitled-1 | ||
await vscode.commands.executeCommand('workbench.action.files.newUntitledFile'); | ||
AzimovParviz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const editor = vscode.window.activeTextEditor; | ||
if (editor) { | ||
await editor.edit((editBuilder) => { | ||
editBuilder.insert( | ||
new vscode.Position(0, 0), | ||
'this is a test\nanother t*st line\nno match here\n', | ||
); | ||
}); | ||
// Because of the save confirmation dialog, it will timeout | ||
// await editor.document.save() | ||
} | ||
// Untitled-2 | ||
await vscode.commands.executeCommand('workbench.action.files.newUntitledFile'); | ||
const modeHandler = await getAndUpdateModeHandler(); | ||
const pattern = Pattern.parser({ direction: SearchDirection.Backward, delimiter: '/' }); | ||
const command = grep(pattern.tryParse('t*st'), ['Untitled-1']); | ||
await command.execute(); | ||
await vscode.commands.executeCommand('search.action.focusNextSearchResult'); | ||
// Assert that the active editor is Untitled-1 | ||
const activeEditor = vscode.window.activeTextEditor; | ||
assert.ok(activeEditor, 'There should be an active editor'); | ||
assert.ok( | ||
activeEditor?.document.fileName.endsWith('Untitled-1'), | ||
'Active editor should be Untitled-1 after grep', | ||
); | ||
assert.ok(modeHandler, 'modeHandler should be defined'); | ||
assert.notStrictEqual( | ||
modeHandler.vimState, | ||
Mode.Visual, | ||
'Should not be in visual mode after grep', | ||
); | ||
}); | ||
}); |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.