Compare commits

...

2 Commits

Author SHA1 Message Date
Smit Barmase
77cfef2164 fix 2025-04-04 19:45:17 +05:30
Smit Barmase
cd522e92ea draft 2025-04-04 19:11:47 +05:30
6 changed files with 87 additions and 31 deletions

View File

@@ -106,8 +106,8 @@ use itertools::Itertools;
use language::{
AutoindentMode, BracketMatch, BracketPair, Buffer, Capability, CharKind, CodeLabel,
CursorShape, Diagnostic, DiffOptions, EditPredictionsMode, EditPreview, HighlightedText,
IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection, SelectionGoal, TextObject,
TransactionId, TreeSitterOptions, WordsQuery,
IndentKind, IndentSize, Language, OffsetRangeExt, OriginalIndentColumn, Point, Selection,
SelectionGoal, TextObject, TransactionId, TreeSitterOptions, WordsQuery,
language_settings::{
self, InlayHintSettings, RewrapBehavior, WordsCompletionMode, all_language_settings,
language_settings,
@@ -1067,6 +1067,8 @@ pub struct ClipboardSelection {
pub is_entire_line: bool,
/// The indentation of the first line when this content was originally copied.
pub first_line_indent: u32,
/// The indentation of the second line when this content was originally copied.
pub second_line_indent: u32,
}
// selections, scroll behavior, was newest selection reversed
@@ -2572,7 +2574,7 @@ impl Editor {
pub fn edit_with_block_indent<I, S, T>(
&mut self,
edits: I,
original_indent_columns: Vec<Option<u32>>,
original_indent_columns: Vec<Option<OriginalIndentColumn>>,
cx: &mut Context<Self>,
) where
I: IntoIterator<Item = (Range<S>, T)>,
@@ -9816,6 +9818,9 @@ impl Editor {
first_line_indent: buffer
.indent_size_for_line(MultiBufferRow(selection.start.row))
.len,
second_line_indent: buffer
.indent_size_for_line(MultiBufferRow(selection.start.row + 1))
.len,
});
}
}
@@ -9939,6 +9944,9 @@ impl Editor {
first_line_indent: buffer
.indent_size_for_line(MultiBufferRow(trimmed_range.start.row))
.len,
second_line_indent: buffer
.indent_size_for_line(MultiBufferRow(trimmed_range.start.row + 1))
.len,
});
}
}
@@ -9970,7 +9978,10 @@ impl Editor {
let all_selections_were_entire_line =
clipboard_selections.iter().all(|s| s.is_entire_line);
let first_selection_indent_column =
clipboard_selections.first().map(|s| s.first_line_indent);
clipboard_selections.first().map(|s| OriginalIndentColumn {
first_line: s.first_line_indent,
second_line: s.second_line_indent,
});
if clipboard_selections.len() != old_selections.len() {
clipboard_selections.drain(..);
}
@@ -9995,7 +10006,10 @@ impl Editor {
to_insert = &clipboard_text[start_offset..end_offset];
entire_line = clipboard_selection.is_entire_line;
start_offset = end_offset + 1;
original_indent_column = Some(clipboard_selection.first_line_indent);
original_indent_column = Some(OriginalIndentColumn {
first_line: clipboard_selection.first_line_indent,
second_line: clipboard_selection.second_line_indent,
});
} else {
to_insert = clipboard_text.as_str();
entire_line = all_selections_were_entire_line;

View File

@@ -403,19 +403,26 @@ pub enum AutoindentMode {
/// Apply the same indentation adjustment to all of the lines
/// in a given insertion.
Block {
/// The original indentation column of the first line of each
/// The original indentation column of the first and second line of each
/// insertion, if it has been copied.
///
/// Knowing this makes it possible to preserve the relative indentation
/// of every line in the insertion from when it was copied.
///
/// If the original indent column is `a`, and the first line of insertion
/// is then auto-indented to column `b`, then every other line of
/// the insertion will be auto-indented to column `b - a`
original_indent_columns: Vec<Option<u32>>,
original_indent_columns: Vec<Option<OriginalIndentColumn>>,
},
}
#[derive(Copy, Clone, Debug)]
pub struct OriginalIndentColumn {
/// If the original indent column first line is `a`, and the first line of insertion
/// is then auto-indented to column `b`, then every other line of
/// the insertion will be auto-indented to column `b - a`
pub first_line: u32,
/// In certain cases like '\n' where we don't want to edit the indentation of first line,
/// we use the second line as a reference to find auto-indentation.
pub second_line: u32,
}
#[derive(Clone)]
struct AutoindentRequest {
before_edit: BufferSnapshot,
@@ -434,7 +441,7 @@ struct AutoindentRequestEntry {
/// since the edit was made.
first_line_is_new: bool,
indent_size: IndentSize,
original_indent_column: Option<u32>,
original_indent: Option<u32>,
}
#[derive(Debug)]
@@ -1616,7 +1623,7 @@ impl Buffer {
let old_row = position.to_point(&request.before_edit).row;
old_to_new_rows.insert(old_row, new_row);
}
row_ranges.push((new_row..new_end_row, entry.original_indent_column));
row_ranges.push((new_row..new_end_row, entry.original_indent));
}
// Build a map containing the suggested indentation for each of the edited lines
@@ -1668,7 +1675,7 @@ impl Buffer {
// if they differ from the old suggestion for that line.
let mut language_indent_sizes = language_indent_sizes_by_new_row.iter().peekable();
let mut language_indent_size = IndentSize::default();
for (row_range, original_indent_column) in row_ranges {
for (row_range, original_indent) in row_ranges {
let new_edited_row_range = if request.is_block_mode {
row_range.start..row_range.start + 1
} else {
@@ -1714,8 +1721,7 @@ impl Buffer {
}
}
if let (true, Some(original_indent_column)) =
(request.is_block_mode, original_indent_column)
if let (true, Some(original_indent)) = (request.is_block_mode, original_indent)
{
let new_indent =
if let Some((indent, _)) = indent_sizes.get(&row_range.start) {
@@ -1723,7 +1729,8 @@ impl Buffer {
} else {
snapshot.indent_size_for_line(row_range.start)
};
let delta = new_indent.len as i64 - original_indent_column as i64;
let delta = new_indent.len as i64 - original_indent as i64;
if delta != 0 {
for row in row_range.skip(1) {
indent_sizes.entry(row).or_insert_with(|| {
@@ -2245,16 +2252,23 @@ impl Buffer {
first_line_is_new = true;
}
let mut original_indent_column = None;
let mut original_indent = None;
if let AutoindentMode::Block {
original_indent_columns,
} = &mode
{
original_indent_column = Some(
original_indent = Some(
original_indent_columns
.get(ix)
.copied()
.flatten()
.map(|original_indent_column| {
if new_text.starts_with('\n') {
original_indent_column.second_line
} else {
original_indent_column.first_line
}
})
.unwrap_or_else(|| {
indent_size_for_text(
new_text[range_of_insertion_to_indent.clone()].chars(),
@@ -2271,7 +2285,7 @@ impl Buffer {
AutoindentRequestEntry {
first_line_is_new,
original_indent_column,
original_indent,
indent_size: before_edit.language_indent_size_at(range.start, cx),
range: self.anchor_before(new_start + range_of_insertion_to_indent.start)
..self.anchor_after(new_start + range_of_insertion_to_indent.end),
@@ -2319,7 +2333,7 @@ impl Buffer {
range: before_edit.anchor_before(range.start)..before_edit.anchor_after(range.end),
first_line_is_new: true,
indent_size: before_edit.language_indent_size_at(range.start, cx),
original_indent_column: None,
original_indent: None,
})
.collect();
self.autoindent_requests.push(Arc::new(AutoindentRequest {

View File

@@ -1646,7 +1646,10 @@ fn test_autoindent_block_mode(cx: &mut App) {
// indent level, but the indentation of the first line was not included in
// the copied text. This information is retained in the
// 'original_indent_columns' vector.
let original_indent_columns = vec![Some(4)];
let original_indent_columns = vec![Some(OriginalIndentColumn {
first_line: 4,
second_line: 8,
})];
let inserted_text = r#"
"
c
@@ -1825,7 +1828,20 @@ fn test_autoindent_block_mode_multiple_adjacent_ranges(cx: &mut App) {
(ranges_to_replace[2].clone(), "fn three() {\n 103\n}\n"),
],
Some(AutoindentMode::Block {
original_indent_columns: vec![Some(0), Some(0), Some(0)],
original_indent_columns: vec![
Some(OriginalIndentColumn {
first_line: 0,
second_line: 0,
}),
Some(OriginalIndentColumn {
first_line: 0,
second_line: 0,
}),
Some(OriginalIndentColumn {
first_line: 0,
second_line: 0,
}),
],
}),
cx,
);

View File

@@ -18,9 +18,9 @@ use itertools::Itertools;
use language::{
AutoindentMode, Buffer, BufferChunks, BufferRow, BufferSnapshot, Capability, CharClassifier,
CharKind, Chunk, CursorShape, DiagnosticEntry, DiskState, File, IndentSize, Language,
LanguageScope, OffsetRangeExt, OffsetUtf16, Outline, OutlineItem, Point, PointUtf16, Selection,
TextDimension, TextObject, ToOffset as _, ToPoint as _, TransactionId, TreeSitterOptions,
Unclipped,
LanguageScope, OffsetRangeExt, OffsetUtf16, OriginalIndentColumn, Outline, OutlineItem, Point,
PointUtf16, Selection, TextDimension, TextObject, ToOffset as _, ToPoint as _, TransactionId,
TreeSitterOptions, Unclipped,
language_settings::{IndentGuideSettings, LanguageSettings, language_settings},
};
@@ -535,7 +535,7 @@ struct BufferEdit {
range: Range<usize>,
new_text: Arc<str>,
is_insertion: bool,
original_indent_column: Option<u32>,
original_indent_column: Option<OriginalIndentColumn>,
excerpt_id: ExcerptId,
}
@@ -898,7 +898,7 @@ impl MultiBuffer {
&self,
edits: Vec<(Range<usize>, Arc<str>)>,
snapshot: &MultiBufferSnapshot,
original_indent_columns: &[Option<u32>],
original_indent_columns: &[Option<OriginalIndentColumn>],
) -> (HashMap<BufferId, Vec<BufferEdit>>, Vec<ExcerptId>) {
let mut buffer_edits: HashMap<BufferId, Vec<BufferEdit>> = Default::default();
let mut edited_excerpt_ids = Vec::new();

View File

@@ -1,6 +1,6 @@
use editor::{DisplayPoint, RowExt, display_map::ToDisplayPoint, movement, scroll::Autoscroll};
use gpui::{Context, Window, impl_actions};
use language::{Bias, SelectionGoal};
use language::{Bias, OriginalIndentColumn, SelectionGoal};
use schemars::JsonSchema;
use serde::Deserialize;
use std::cmp;
@@ -85,7 +85,10 @@ impl Vim {
clipboard_selections.as_ref().and_then(|zed_selections| {
zed_selections
.first()
.map(|selection| selection.first_line_indent)
.map(|selection| OriginalIndentColumn {
first_line: selection.first_line_indent,
second_line: selection.second_line_indent,
})
});
let before = action.before || vim.mode == Mode::VisualLine;
@@ -101,7 +104,13 @@ impl Vim {
let end_offset = start_offset + clipboard_selection.len;
let text = text[start_offset..end_offset].to_string();
start_offset = end_offset + 1;
(text, Some(clipboard_selection.first_line_indent))
(
text,
Some(OriginalIndentColumn {
first_line: clipboard_selection.first_line_indent,
second_line: clipboard_selection.second_line_indent,
}),
)
} else {
("".to_string(), first_selection_indent_column)
}

View File

@@ -185,6 +185,9 @@ impl Vim {
len: text.len() - initial_len,
is_entire_line: kind.linewise(),
first_line_indent: buffer.indent_size_for_line(MultiBufferRow(start.row)).len,
second_line_indent: buffer
.indent_size_for_line(MultiBufferRow(start.row + 1))
.len,
});
}
}