kianenigma
kianenigma

Reputation: 1405

vscode: Extension to do simple global search

I want to create an extension that does a very simple task:

I invoke a command from the command pallet with:

> commandName: Query

And it should start a global search, in regex mode with:

SomeToken AnotherToken (some|regex*|prefix?|foo) Query

Where the point is that I don't want to type the SomeToken AnotherToken (some|regex*|prefix?|foo) prefix all the time.

This sounds like a very simple process and I expected it to be possible in vscode, but I haven't found anything yet about it in the VSCode API and relevant tutorials.

Upvotes: 0

Views: 1242

Answers (1)

Mark
Mark

Reputation: 182821

I have released an extension which does allow you to create and save pre-defined find/replaces or search/replaces: Find and Transform and call them via commands in the Command Palette or through keybindings. Sample settings:

    "findInCurrentFile": {
        "upcaseSwap2": {
            "title": "swap iif <==> hello",
            "find": "(iif) (hello)",
            "replace": "_\\u$2_ _\\U$1_",  // double-escaped case modifiers
            "restrictFind": "selections"
        },
        "upcaseSelectedKeywords": {
            "title": "Uppercase selected Keywords",
            "find": "(epsilon|alpha|beta)",
            "replace": "\\U$1",
            // "restrictFind": "selections"
        }
    },

    "runInSearchPanel": {
        "removeDigits": {
            "title": "Remove digits from Arturo",
            "find": "^(\\s*Arturo)\\d+",
            "replace": "$1",
            "isRegex": true,
            "triggerSearch": true,
            // "filesToInclude": "${file}"
            "filesToInclude": "${file}",
        }
    },

  • I don't think there is any way to invoke a command from the Command Palette with an argument as you seem to indicate you wish to do. You could open an InputBox and ask for that value (that is quite easy to do) or use the currently selected text. Below I showed both ways.

First with the currently selected text you can just try a simple keybinding and see if that is sufficient:

{
  "key": "ctrl+shift+g",                    // whatever keybinding you wish
  "command": "search.action.openNewEditor",
  "args": {

    "query": "(enum|struct|fn|trait|impl(<.*>)?|type) ${selectedText}",

    "isRegexp": true,

    // "includes": "${relativeFile}",  // works

    "showIncludesExcludes": true,
    "triggerSearch": true,
    "contextLines": 2,
    "focusResults": true,
  },
  "when": "editorTextFocus"
}

It opens up a search editor rather than using your Search view/panel. If you want it in the Search view/panel that isn't as easy. Unfortunately the workbench.action.findInFiles args do not support ${selectedText}. Nevertheless you can do this keybinding and simply type the rest of your query at the end.

  {
    "key": "ctrl+shift+f",
    "command": "workbench.action.findInFiles",
    "args": {

      "query": "(enum|struct|fn|trait|impl(<.*>)?|type) ",
      "isRegex": true,
      // "replace": "$1",
      "triggerSearch": true,                          // seems to be the default
      // "filesToInclude": "${relativeFileDirname}",  // no variables in findInFiles
      "preserveCase": true,
      "useExcludeSettingsAndIgnoreFiles": false,
      "isCaseSensitive": true,
      // "matchWholeWord": true,
      // "filesToExclude": ""
    }
  },

Here is the guts of extension code using the selected text that would be in your vscode.commands.registerCommand call:


let disposable = vscode.commands.registerCommand('myExtensionName.myCommandName', function () {

  // get selected text or open an InputBox here

  const selection = vscode.window.activeTextEditor.selection;
  const selectedText = vscode.window.activeTextEditor.document.getText(selection);

  const searchOptions = {
    query: "(enum|struct|fn|trait|impl(<.*>)?|type) " + selectedText,
    triggerSearch: true,
    isRegex: true
  };

  vscode.commands.executeCommand('workbench.action.findInFiles', searchOptions);
});

context.subscriptions.push(disposable);

And this opens an InputBox to get the query term from the user:


let disposable = vscode.commands.registerCommand('myExtensionName.myCommandName', function () {

  vscode.window.showInputBox({ prompt: "Enter a search query" }).then(query => {

    const searchOptions = {
      query: "(enum|struct|fn|trait|impl(<.*>)?|type) " + query,
      triggerSearch: true,
      isRegex: true
    };

    vscode.commands.executeCommand('workbench.action.findInFiles', searchOptions);
  })
});

context.subscriptions.push(disposable);

Obviously you'll have to add some error checking.

Upvotes: 1

Related Questions