microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
163.44k stars 28.95k forks source link

[rename on type] API for languages beyond HTML #94316

Closed octref closed 3 years ago

octref commented 4 years ago

Continuing microsoft/vscode#88424, which implements the Synced Region feature for HTML.

We could offer an API and I can try doing it for JSX (#85707).

I tried running this feature in real programming languages such as TypeScript, but automatic mode creates a lot of confusion. For example:

const a = { b: 1, c: 2 }
a.b|

In automatic mode, when I'm deleting b and entering c to change from a.b to a.c, b: 1 would also be changed. This is undesirable.

Nevertheless, having Cmd+Shift+F2 to live-rename in a for-loop etc would be very helpful.

This issue tracks the API proposal below:

/**
 * The rename provider interface defines the contract between extensions and
 * the live-rename feature.
 */
export interface OnTypeRenameProvider {
    /**
     * Provide a list of ranges that can be live renamed together.
     *
     * @param document The document in which the command was invoked.
     * @param position The position at which the command was invoked.
     * @param token A cancellation token.
     * @return A list of ranges that can be live-renamed togehter. The ranges must have
     * identical length and contain identical text content. The ranges cannot overlap.
     */
    provideOnTypeRenameRanges(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Range[]>;
}

namespace languages {
    /**
     * Register a rename provider that works on type.
     *
     * Multiple providers can be registered for a language. In that case providers are sorted
     * by their [score](#languages.match) and the best-matching provider is used. Failure
     * of the selected provider will cause a failure of the whole operation.
     *
     * @param selector A selector that defines the documents this provider is applicable to.
     * @param provider An on type rename provider.
     * @param stopPattern Stop on type renaming when input text matches the regular expression. Defaults to `^\s`.
     * @return A [disposable](#Disposable) that unregisters this provider when being disposed.
     */
    export function registerOnTypeRenameProvider(selector: DocumentSelector, provider: OnTypeRenameProvider, stopPattern?: RegExp): Disposable;
}
Matelasse commented 4 years ago

@octref Would you be able to implement this for jsx please? @mattbierner this really is a huge quality of life improvement for relatively marginal effort. It deserves to be in the Iteration for this/next month imho

pgfearo commented 4 years ago

I would have been very interested in this API for the XML/XSLT editor extension I’m developing. However, I’m concerned about synced regions being ‘opt in’ and also requiring other user intervention (when the command is invoked), so for the time being at least, the extension will provide its own synced XML tag renaming. People writing XML/XSLT in other editors are used to synced tag renaming just working by default and with no intervention on their part.

An API feature that would be useful for this would be if workspace.applyEdit had a mode that prevented any change to the undo stack. Currently, in this extension, to undo a tag rename, the user has to select ‘undo’ twice, once for the end tag and once for the start tag.

Note that start tag edits are synced with end tags, but not the other way round. This follows the convention of other XML editors and helps reduce CPU load (or parsing the XML backwards which I would not relish)

ToddGrun commented 4 years ago

Could you better clarify what stopPattern means? Does it mean the following:

If the modified range doesn't contain stopPattern, all other ranges are modified to have the same value as it. If the modified range does contain stopPattern, all other ranges are modified to have it's value up to the point where stopPattern was encountered?

KamasamaK commented 3 years ago

This looks to have been finalized in microsoft/vscode#109923

aeschli commented 3 years ago

Yes, correct. Closing as dup of microsoft/vscode#109923

Ares9323 commented 3 years ago

This looks to have been finalized in microsoft/vscode#109923

Can you please explain how to add more supported languages to this setting? I tried to look at the changelog you posted and at the documentation but there is no example.

The setting recently changed from "editor.renameOnType" to "editor.linkedEditing" and I looked for both with no success.

I tried several parameters with "languages.registerLinkedEditingRangeProvider" from this comment but none worked and I can't seem to find the correct syntax (I have version 1.52.1 as suggested but in the settings.json I see "Unknown Configuration Setting")

aeschli commented 3 years ago

Yes, you have to write an extension that registers a new LinkedEditingRangeProvider for a given language selector. That's done with the API registerLinkedEditingRangeProvider.

If the user settings editor.linkedEditing is enabled, the editor will ask your LinkedEditingRangeProvide for linked ranges. Changes to one linked range will be automatically applied to all linked ranges.