Skip to content

API Request: onDidChangeTextDocument - differentiate between user input and redo/undo #120617

@hediet

Description

@hediet

The extension API of VS Code 1.54.3 offers the event workspace.onDidChangeTextDocument that can be used to subscribe to text changes.

Currently, it does not seem to be possible to differentiate between text changes caused by user-input and those caused by redo/undo.

This is problematic if an extension wants to use the onDidChangeTextDocument event to modify the document when certain characters are typed by the user.

For example, the abbreviation rewrite feature of the Lean VS Code extension makes use of it (if the user types \alpha it gets replaced by α immediately).

However, if the user undoes and redoes their changes, onDidChangeTextDocument is also triggered. When undoing/redoing, new text edits are very harmful though, as they destroy the redo stack. Thus, extensions must not modify the document on redos/undos.

If redos cannot be differentiated from user input, this problem cannot be avoided if an extension wants to modify the document on certain text changes.

Proposal

It would be helpful if VS Code could provide a reason that caused the text change.
Reasons could be:

  • userInput: The user typed a character.
  • redo: Caused by redo
  • undo: Caused by undo
  • unknown: E.g. caused by liveshare or use of workspace.applyEdit

The reason could be provided by the TextDocumentChangeEvent:

export enum TextDocumentChangeReason {
    /** The text change is caused by extensions or other unknown sources. */
    unknown,

    /** The text change is caused by the user editing the document. */
    userInput,

    /** The text change is caused as part of an redo operation. */
    redo,

    /** The text change is caused as part of an undo operation. */
    undo,
}

/**
 * An event describing a transactional [document](#TextDocument) change.
 */
export interface TextDocumentChangeEvent {

    /**
     * The affected document.
     */
    readonly document: TextDocument;

    /**
     * An array of content changes.
     */
    readonly contentChanges: ReadonlyArray<TextDocumentContentChangeEvent>;

    // >>>>>>>>> NEW
    readonly reason: TextDocumentChangeReason;
    // <<<<<<<<<
}

Thank you!

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions