@@ -2088,14 +2088,14 @@ impl ContextEditor {
command_range: Range<language::Anchor>,
name: &str,
arguments: &[String],
- insert_trailing_newline: bool,
+ ensure_trailing_newline: bool,
workspace: WeakView<Workspace>,
cx: &mut ViewContext<Self>,
) {
if let Some(command) = SlashCommandRegistry::global(cx).command(name) {
let output = command.run(arguments, workspace, self.lsp_adapter_delegate.clone(), cx);
self.context.update(cx, |context, cx| {
- context.insert_command_output(command_range, output, insert_trailing_newline, cx)
+ context.insert_command_output(command_range, output, ensure_trailing_newline, cx)
});
}
}
@@ -1395,7 +1395,7 @@ impl Context {
&mut self,
command_range: Range<language::Anchor>,
output: Task<Result<SlashCommandOutput>>,
- insert_trailing_newline: bool,
+ ensure_trailing_newline: bool,
cx: &mut ModelContext<Self>,
) {
self.reparse_slash_commands(cx);
@@ -1406,8 +1406,27 @@ impl Context {
let output = output.await;
this.update(&mut cx, |this, cx| match output {
Ok(mut output) => {
- if insert_trailing_newline {
- output.text.push('\n');
+ // Ensure section ranges are valid.
+ for section in &mut output.sections {
+ section.range.start = section.range.start.min(output.text.len());
+ section.range.end = section.range.end.min(output.text.len());
+ while !output.text.is_char_boundary(section.range.start) {
+ section.range.start -= 1;
+ }
+ while !output.text.is_char_boundary(section.range.end) {
+ section.range.end += 1;
+ }
+ }
+
+ // Ensure there is a newline after the last section.
+ if ensure_trailing_newline {
+ let has_newline_after_last_section =
+ output.sections.last().map_or(false, |last_section| {
+ output.text[last_section.range.end..].ends_with('\n')
+ });
+ if !has_newline_after_last_section {
+ output.text.push('\n');
+ }
}
let version = this.version.clone();