VSCode Extension API showInputBox call producing unexpected behavior - visual-studio-code

According to the VSCode extension docs, the InputBoxOption ignoreFocusOut is described thusly:
Set to true to keep the input box open when focus moves to
another part of the editor or to another window.
This setting is ignored on iPad and is always false.
I am not using an iPad, so I can presumably ignore the second sentence.
When I do set this property to true, I see absolutely no behavior change. That is,
as soon as I click in some other window the VSCode input box closes. Am I misinterpreting what this property is supposed to do? Or is this behavior broken?
My typical use looks like this:
state.url = await input.showInputBox({
ignoreFocusOut: true,
title: this.title,
step: 1,
totalSteps: this.maxSteps,
value: state.url ?? '',
prompt: 'Enter remote Git URL',
validate: this.validateProtocol,
shouldResume: shouldResume,
});
If there is, in fact, no way to alter that undesirable behavior of the input closing (and thus the command terminating),
is there perhaps a way to resume the command? That is, I have a multi-step dialog of 5 steps. Upon restoring focus to the VSCode window can I continue with, say, step 3, where I left off? I have not seen any indication this is possible but thought I would ask while I am here.
(My system: VSCode/macOS version 1.74.2)

Found a more targeted site to post the same question and got an answer there:
https://github.com/microsoft/vscode-discussions/discussions/407

Related

Error handling in Sublime Text Plugin API

I'm creating my first sublime plugin to be used internally and was wondering if there's a way to stop the plugin from executing and display an error message on screen like an alert?
I took a look at view#show_popup() but this didn't render for me. Below is how I attempted to show it:
if "WebContent" in subdirectories:
directory = ROOT_DIR + "/WebContent"
elif "Content" in subdirectories:
directory = ROOT_DIR + "/Content"
else:
self.view.show_popup('Directory not found', location=-1)
Working Principle:
The plugin takes some data from one view and then pastes them in another view. The plugin has two TextCommands. One command takes the data from the first view, opens a new view and then executes the 2nd command on the new view. The above snippet is in the 2nd command.
I was unable to find any resources to help with show_popup() or any other error handling.
Does any one have possible ideas?
view.show_popup() is for showing things like hover popups next to the cursor; it's used for things like the built in functionality for going to references/definitions for functions:
While you could in theory use this for error messages, it may not be the sort of user experience that anyone would expect.
Your code above is technically valid, but since the content is expected to be minihtml it may be hard to see because as just a single string all you're going to see is just the text (i.e. you have no font style, padding, etc):
Perhaps more importantly, when location is -1, the popup appears at the point in the buffer closest to the first cursor position, so depending on your circumstance it may be appearing in a place you don't expect, and then vanishing away before you can scroll to see it, etc.
What you want here is sublime.error_message(); given a string, it will display that string in a dialog for the user to interact with, and it also logs the error into the Sublime console as well so that there's an additional trace.

VSCode API: Anticipate or combine document text changes

Let's say I want to make an extension that listens for document changes and always applies them twice. If the user types 'w' it will turn out as 'ww', if the user backspaces once, it should actually backspace twice. If the user pastes something, it should be pasted twice. (My real use case is more complicated, but it is similar to this)
I could listen for document changes using
vscode.workspace.onDidChangeTextDocument(event => {
// Do something
});
and use event.contentChanges to see what changes were made and then use
activeEditor.edit((editBuilder: vscode.TextEditorEdit) => {
// Do something
});
to make the same edit to the document again.
The problem is that this effectively makes two changes to the document so the user will need to ctrl+z twice to undo what is seen as a single action from the user's perspective.
What would be great is if I could anticipate text changes (and then just append more changes) through some method like vscode.workspace.onWillChangeTextDocument but this does not exist (vscode issue #74381, #44771). I also described my problem there.
I see that some people override the 'type' command in vscode to execute before any edit is made (example). But this does not give me access to the edit I want to alter, nor does it capture backspaces or copy/paste commands.
I also tried uding a formatter but this will seemingly override other formatters and users will need to enable "formatting on type" (manually?) for it to update as often as I want. That will also mess with unnecessary user settings/workflows/extensions.
Any idea of how I can achieve this?
The undesired behavior with undo/redo can be mitigated by passing an options object to activeEditor.edit that prevents an "undo stop" to be added before my 2nd edit/change/action. Like this:
activeEditor.edit((editBuilder: vscode.TextEditorEdit) => {
// Do something
}, {undoStopBefore: false, undoStopAfter: false});
undoStopAfter seems like it could be either true or false, producing identical behavior for now.

Is there a way to make my own save command that overrides the standard file save keybind?

I'm contributing to an open issue regarding keybindings and custom editors. More specifically, if one were to edit a Markdown file in the standard .md text editor then hit CMD+S, not only does VSCode save the edits on the open file, but it also toggles to the Markdown's preview mode.
Right now, I have a custom editor save command in the works, and the constructor/keybindings is as follows (in TypeScript):
(new class SaveCustomEditorCommand extends Command {
public static readonly ID = 'editor.action.customEditor.save';
constructor() {
super({
id: SaveCustomEditorCommand.ID,
precondition: CONTEXT_HAS_CUSTOM_EDITORS,
kbOpts: {
primary: KeyMod.CtrlCmd | KeyCode.KEY_S,
weight: KeybindingWeight.EditorContrib
}
});
}
... // fully implemented runCommand function
}).register();
As the command is, hitting CMD+S simply saves the changes and nothing more. However, if I were to change the KeyCode from KEY_S to KEY_Y (since CMD+Y isn't an already existing keybinding command), the save-to-preview command works as intended. Setting the weight property inside kbOpts to higher enums does not change anything.
I'm certain that somewhere in VSCode source, the File/Save CMD+S command takes total precedence, but given that my command should be running only under the precondition that the context has custom editors, I was wondering if I can somehow force my "Save and Preview" command to run instead of the simple, universal "Save" command.
Any pointers or guidance would be much appreciated; this is my first contribution to anything open-source!
If keeping CMD+Y is the more feasible course of action for a "Save and Preview" keybinding, then that works for me, but I would like to least try with CMD+S if possible.

vscode.workspace.openTextDocument fails silently

With the same value for Uri, openTextDocument fails to have any discernible effect yet executeCommand successfully opens the document.
vscode.workspace.openTextDocument(uri);
vscode.commands.executeCommand("vscode.open", uri);
Are there any known problems with vscode.workspace.openTextDocument?
This might simply be a misunderstanding of what openTextDocument() does. It just creates a vscode.TextDocument instance, actually showing it in the UI is independent of that. That's why it's in the vscode.workspace namespace rather than vscode.window.
vscode.window.showTextDocument is used for actually showing a document:
Show the given document in a text editor. A column can be provided
to control where the editor is being shown. Might change the active editor.
vscode.workspace.openTextDocument(...).then(
document => vscode.window.showTextDocument(document));

javascript turn off code formatting

vscode is great, but it oversteps boundaries. I'd like to maintain my coding style but seem to be constantly forced into some invisible 'standard', defined by MSoft, I suppose. At any rate, I have "javascript.format.enable": false set and yet it still insists on changing my code.
Take something simple, like dothis(y+2), gets converted to dothis(y + 2) on Save (Ctrl-S). There are many times when I just want what I typed in. How can I get vscode to help me out instead of imposing its own 'standard'?
Do you have "editor.formatOnSave": true in user settings or folder settings? Or, an extension installed that may be doing this?