Add `ChangeEditorContents` event

finchie
Jan 2, 2026, 1:43 AM
QY4DF3NMDBZQ4IJQJIYRWKQ66FWMFQUSASMEBNG5ROXDHTWI2J4QC

Dependencies

  • [2] WFWTKCJN Create initial Visual Studio Code extension
  • [3] 6AUGQLIK Add basic panic handling
  • [4] 3YGYMEXV Create `event_loop` module
  • [5] TDTLSDFG Create macro for defining `ThreadsafeFunction`s
  • [6] NB2MF3MY Add `OpenWorkspaceFolder` event
  • [7] 2ZAM5V35 Move event handling into modules
  • [8] IDY5SNLO Update source control resource states in event loop
  • [9] 3RNQI5RX Refactor `provide_file_decoration` to return a `Promise` resolved by `event_loop`
  • [10] M5RW5PN4 Add `OpenTextEditor` event
  • [11] GQ52YLWH Remove unnecessary debug logs
  • [12] OUADGWKR Create fully-initialized `SourceControl` object in `event_loop`

Change contents

  • replacement in editors/vscode/src/lib.rs at line 130
    [2.114107][2.114107:114186]()
    // Ignore any messages printed to the `Output` channel (used by `tracing`)
    [2.114107]
    [2.114186]
    // Ignore any messages printed to the `Output` channel (used by `tracing`).
    // Since the output view is a text document, any logging calls will trigger this function,
    // so make sure to return before it sends itself into an infinite loop.
  • edit in editors/vscode/src/lib.rs at line 135
    [2.114257]
    [2.114257]
    }
    let uri = UriAbsoluteString::try_from(document_uri.to_string()?)
    .map_err(|error| napi::Error::from_reason(format!("Failed to parse URI: {error}")))?;
    let change_events = event.get_content_changes()?;
    let mut changes = Vec::with_capacity(change_events.len());
    for change_event in &change_events {
    changes.push(event_loop::EditorContentsChange {
    character_offset: change_event.get_range_offset()?,
    characters_replaced: change_event.get_range_length()?,
    replacement_text: change_event.get_text()?,
    })
  • edit in editors/vscode/src/lib.rs at line 151
    [3.2630]
    [3.2630]
    event_loop::send(Event::ChangeEditorContents { uri, changes });
  • edit in editors/vscode/src/lib.rs at line 166
    [2.114804][2.114804:114863]()
    let change_events = event.get_content_changes()?;
  • replacement in editors/vscode/src/event_loop/mod.rs at line 6
    [9.538][10.383:443]()
    use iri_string::types::{UriAbsoluteStr, UriAbsoluteString};
    [9.538]
    [4.198]
    use iri_string::types::UriAbsoluteStr;
  • replacement in editors/vscode/src/event_loop/mod.rs at line 11
    [7.1][7.1:71]()
    // Re-export Event so it can be used by callers
    pub use event::Event;
    [7.1]
    [5.1732]
    // Re-export Event types so it can be used by callers
    pub use event::{EditorContentsChange, Event};
  • edit in editors/vscode/src/event_loop/mod.rs at line 126
    [8.638]
    [6.2519]
    }
    Event::ChangeEditorContents { uri, changes } => {
    event::change_editor_contents::handle(uri, changes, &mut extension_state).await
  • edit in editors/vscode/src/event_loop/event/mod.rs at line 6
    [8.5706]
    [10.5913]
    pub mod change_editor_contents;
  • edit in editors/vscode/src/event_loop/event/mod.rs at line 11
    [8.5739]
    [7.3099]
    #[derive(Debug)]
    pub struct EditorContentsChange {
    pub character_offset: u32,
    pub characters_replaced: u32,
    pub replacement_text: String,
    }
  • edit in editors/vscode/src/event_loop/event/mod.rs at line 26
    [10.6052]
    [10.6052]
    },
    ChangeEditorContents {
    uri: UriAbsoluteString,
    changes: Vec<EditorContentsChange>,
  • file addition: change_editor_contents.rs (----------)
    [7.332]
    use iri_string::types::UriAbsoluteString;
    use crate::event_loop::{EditorContentsChange, ExtensionState};
    #[tracing::instrument(skip(extension_state))]
    pub async fn handle(
    uri: UriAbsoluteString,
    changes: Vec<EditorContentsChange>,
    extension_state: &mut ExtensionState,
    ) {
    let Some((_repository_path, relative_path, repository)) =
    extension_state.get_repository_mut(&uri)
    else {
    tracing::info!(message = "Ignoring text content changes");
    return;
    };
    for change in changes {
    let EditorContentsChange {
    character_offset,
    characters_replaced,
    replacement_text,
    } = change;
    if let Err(error) = repository.repository.update_open_file(
    relative_path,
    character_offset as usize,
    characters_replaced as usize,
    &replacement_text,
    ) {
    tracing::error!(message = "Failed to update open file", ?error);
    return;
    }
    tracing::info!(message = "Updated open file");
    }
    }