How to change autocompletes in VS Code? - visual-studio-code

Whenever I have a form, and I want to create an object or something, I use document.getElementById('example').value. Thing is, the first time I type 'value' in a new JS file and then enter my comma or semicolon, 'value' changes to ariaValueMax. I know this is a minor inconvenience at worst, but is there any way I can change this? This happens everytime I make a project with JavaScript.
Also, when I'm in my server.js file, sometimes I forget to create a variable before trying to do something with it in express. So if I type something like this:
const express = require('express');
app.listen.....
I end up with this:
const express = require('express');
const { appendFile } = require('fs');
appendFile.listen......
Is there any way I can change this settings as well? (the one where it auto creates the require('fs') line)

I can only answer your first question: You have to edit settings.json to tell Intellisense to not accept autocomplete on your "commit character" (in this instance, the semicolon). So first, you have to edit that file:
Windows %APPDATA%\Code\User\settings.json
MacOS $HOME/Library/Application Support/Code/User/settings.json
Linux $HOME/.config/Code/User/settings.json
Then, add the following JSON node:
"editor.acceptSuggestionOnCommitCharacter": false
Finally, restart your editor, and it should be good to go. Here is an example of my settings.json file:
{
"go.formatTool": "goimports",
"editor.acceptSuggestionOnCommitCharacter": false
}

Related

How to list all commands related to a specific extension in VS Code's command palette?

I'm writing an extension and I would like to know if there is a way to list all the commands that belong to my extension in the command palette.
I have added an item in the status bar that once clicked should ideally list all the commands available from my extension in the command palette, similar to when you click on the language, a list of languages shows up.
The closest thing I could get is this:
const statusBar = vscode.window.createStatusBarItem();
statusBar.text = 'Cloudflare';
statusBar.command = 'cloudflareDevTools.commands';
statusBar.show();
let commands = vscode.commands.registerCommand('cloudflareDevTools.commands', () => {
vscode.commands.executeCommand("workbench.action.quickOpen", ">Cloudflare");
});
Which results in this:
This way I'm basically filtering the commands in the command palette by providing a string that's part of the extension's name, and it kinda works as it shows all the commands from my extension, but you can see how it's not ideal in case multiple extensions have a similar name.
There's something similar when you go in the settings: you can provide #ext:kenhowardpdx.vscode-gist and this will list all the settings related to that specific extension. I would like something similar but for the commands I've registered in package.json and extension.js.
Thank you!
Not sure why I didn't think of this before. You can show a QuickPick, basically a mini-Command Palette, with only commands you have filtered.
const qpOptions = {title: "commands from the find-and-transform extension", canPickMany: false};
const allCommands = await vscode.commands.getCommands(true);
// filter by your extensionID
const findExtensionCommands = allCommands.filter(command => command.startsWith('find-and-transform'));
const selectedCommand = await vscode.window.showQuickPick(findExtensionCommands, qpOptions);
if (selectedCommand) {
// do whatever you are going to do if the user makes a selection, like
// vscode.commands.executeCommand(selectedCommand);
console.log(selectedCommand);
}
You can also make QuickPickItems out of the commands, so that you can add descriptions to them for example.

Is there anyway to check inactive terminalEditors in when arg in keybindings.json in VScode?

I want to createTerminalEditor if there is no terminalEditor opened yet.
Note: I'm talking about terminalEditor and not terminal.
So, I'm looking for a when arg which says something like editorAlreadyExists != terminalEditor, just like there is activeEditor which aceepts string of terminalEditor.
Is there anyway to achieve this?
Here is activeEditor example for reference, but I want to check if terminalEditor exists in all the already opened editors, not just a activeEditor.
{
"key": "ctrl+`",
"command": "workbench.action.createTerminalEditor",
"when": "activeEditor != terminalEditor"
},
I see that there is a when clause for:
terminalEditorFocus: true/false
which doesn't look like it would help except for the fact that it isn't in the list (via Developer: Inspect Context Keys) at all when there is no terminal editor open. So I thought maybe there was a keybinding when clause that could exploit this. But I tried all kinds of thing, like whether it was null or undefined or the empty string or neither true nor false, etc. but nothing worked. I think if the key terminalEditorFocus doesn't exist, then nothing at all is delivered to the keybinding resolver and it always fails.
You could file an issue asking for a specific terminalEditorExists sort of when clause.
There will be another way. There is a presently experimental api to access all the open tabs. See proposed api. So you could write an extension that checks all the open tabs and fires the workbench.action.createTerminalEditor command if none are a terminalEditor. It works right now in the Insiders Build, but when it will go final I don't know - it seems pretty solid now. Issue: Tab Model API.
const tabs = vscode.window.tabs;
const openTerminalEditor = tabs.some(tab => tab.viewId === 'terminalEditor'); // true/false
Then you could either set your own context key with setContext or run the command.

How can I configure multiple formatters to run in a sequence on save in VSCode?

I am working on a Haskell project that must be formatted by both:
stylish-haskell (for import reordering)
brittany (for general formatting)
I can set the single default formatter for a language:
"[haskell]": {
"editor.defaultFormatter": "MaxGabriel.brittany"
}
or I can select one from a list using editor.action.formatDocument.multiple ("Format Document With... in the command palette).
But I need to run both of them, one after the other, on save. As of right now, I can only run the single default formatter on save. The order doesn't matter in this case, but it could in more general cases.
I've tried setting editor.defaultFormatter to a list of formatters (this didn't work, as expected) and built a local extension that calls editor.action.formatDocument.multiple with various arguments, which just brings up a drop-down list of available formatters to choose from.
How can I run both formatters sequentially on save?
I don't think this is really a use case that is officially supported, but you could possibly work around it by having an extension do the following:
disable "editor.formatOnSave" for Haskell
register a callback for vscode.workspace.onDidSaveTextDocument, in which you:
set "editor.defaultFormatter" to the first formatter using the WorkspaceConfiguration API
call "editor.action.formatDocument"
set "editor.defaultFormatter" to the second formatter
call "editor.action.formatDocument" again
Of course, this only covers formatOnSave formatting, not formatOnPaste or formatOnType.
It's a bit late but, for newcomers, you can also use one extension that is already created... and it's thanks to all the answers of this post, by the way.
See Multi Formatter
So you can just add the formatters you want to run in the settings.json or the *.code-workspace settings like this:
{
"[haskell]": {
"editor.defaultFormatter": "Jota0222.multi-formatter",
"editor.formatOnSave": true
"multiFormatter.formatterList": [
"vigoo.stylish-haskell",
"MaxGabriel.brittany"
],
}
}
With that configuration, stylish-haskell will run first and Britanny will run just after once you save the changes.
P.S.: I'm indeed the author of the solution. I'm not aiming to do any promotion, it's just an implementation of the answers above. So I'll like to thank the people that answered before me.
Also, the extension is open sourced, feel free to check the code and contribute on GitHub
Last thoughts: look at Run on Save extension and execute your formatters not as extensions but as scripts.
Previous edit:
If your formatter doesn't contribute a command (see discussion in comments for some that do) as it appears brittany does not, try something like this for its task:
{
"label": "brittany format step",
"type": "shell",
"command": "brittany ${file}",
"problemMatcher": []
}
From Gama11's answer of creating a VSCode extension:
The following code specifies the formatter and then formats the code.
const config = vscode.workspace.getConfiguration('editor', vscode.window.activeTextEditor?.document);
await config.update('defaultFormatter', 'MaxGabriel.brittany');
await vscode.commands.executeCommand('editor.action.formatDocument');
Therefore, the answer is:
const config = vscode.workspace.getConfiguration('editor', vscode.window.activeTextEditor?.document);
const formatters = ['MaxGabriel.brittany', 'ms-python.python'];
formatters.forEach(async formatter => {
await config.update('defaultFormatter', formatter);
await vscode.commands.executeCommand('editor.action.formatDocument');
});

How can I make VS Code take me to the JS file instead of the .d.ts file on clicking an imported/required symbol or import/require path?

When I want to reference a definition I press ctrl and left click on the variable, VSCode brings me to the definition. The problem is if a module has both index.js and index.d.ts, VS Code will bring me to the index.d.ts file which has no meaningful logic code. It's totally unusable to debug or to understand the implementation.
var cookieSession = require('cookie-session')
var express = require('express')
For example, ctrl + left click on the cookie-session VSCode brings me to ./node_modules/#types/cookie-session/index.d.ts:115 instead of ./node_modules/cookie-session/index.js where it shows:
declare module "cookie-session" {
import express = require('express');
function cookieSession(options?: CookieSessionInterfaces.CookieSessionOptions): express.RequestHandler;
export = cookieSession;
}

IPython/Jupyter Installing Extensions

I'm having troubles installing extensions in IPython. The problem is that i can't get the extensions load automatically, i have followed the instructions in the github page but it just doesn't work. According the the homepage i need to modify the custom.js file by adding some lines. I want to install the codefolding, hide_input_all and runtools extensions. This is how my custom.js file looks:
// activate extensions only after Notebook is initialized
require(["base/js/events"], function (events) {
$([IPython.events]).on("app_initialized.NotebookApp", function () {
/* load your extension here */
IPython.load_extensions('usability/codefolding/codefolding')
IPython.load_extensions('usability/runtools/runtools')
require(['/static/custom/hide_input_all.js'])
});
});
The extensions work well if i call them manually, for example, if i type
%%javascript
IPython.load_extensions('usability/runtools/runtools/main');
the runtools appear and works perfectly, but i want the extensions to be loaded automatically and not to have to call them manually every time. Could someone tell me where is my mistake?
There's been a little change to the syntax. Nowadays, $ might not be defined by the time your custom.js loads, so instead of something like
$([IPython.events]).on("app_initialized.NotebookApp", function () {
IPython.load_extensions("whatever");
});
you should do something like
require(['base/js/namespace', 'base/js/events'], function(IPython, events) {
events.on('app_initialized.NotebookApp', function(){
IPython.load_extensions("whatever");
})
});
with the appropriate changes to braces and parentheses. For me, the former will work more often than not, but certainly not always; it fails maybe ~1/3 of the time.
If that doesn't do it for you, open up Developer Tools (or whatever is relevant for your browser) and look at the javascript console for errors. That'll help figure out what's going wrong.