From 119d348e4aadc95c57b50826d1db554267a0baf7 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Wed, 21 May 2025 22:37:07 +0800 Subject: [PATCH] input: Fix indent, outdent to consider `\r` on Windows. (#880) https://github.com/user-attachments/assets/c662c251-36e5-4a80-bad9-7438ba1b395c --- Cargo.lock | 24 +++++++++---------- crates/ui/src/input/state.rs | 45 +++++++++++++++--------------------- 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a0ed110..de6dfbf6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1185,7 +1185,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "indexmap 2.7.1", "rustc-hash 2.1.0", @@ -1692,7 +1692,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "proc-macro2", "quote", @@ -2710,7 +2710,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "anyhow", "as-raw-xcb-connection", @@ -2834,7 +2834,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "proc-macro2", "quote", @@ -3103,7 +3103,7 @@ dependencies = [ [[package]] name = "http_client" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "anyhow", "bytes", @@ -3120,7 +3120,7 @@ dependencies = [ [[package]] name = "http_client_tls" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "rustls", "rustls-platform-verifier", @@ -3881,7 +3881,7 @@ dependencies = [ [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "anyhow", "bindgen 0.71.1", @@ -5626,7 +5626,7 @@ dependencies = [ [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "derive_refineable", "workspace-hack", @@ -5721,7 +5721,7 @@ dependencies = [ [[package]] name = "reqwest_client" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "anyhow", "bytes", @@ -6241,7 +6241,7 @@ checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" [[package]] name = "semantic_version" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "anyhow", "serde", @@ -6709,7 +6709,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "arrayvec", "log", @@ -7547,7 +7547,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "util" version = "0.1.0" -source = "git+https://github.com/huacnlee/zed.git?branch=webview#431fa17bcca92294fa8c8b453ebdcb4069169489" +source = "git+https://github.com/huacnlee/zed.git?branch=webview#df7153e30716d90a3ab84c8c65143a97dd962d93" dependencies = [ "anyhow", "async-fs 2.1.2", diff --git a/crates/ui/src/input/state.rs b/crates/ui/src/input/state.rs index ee7b68ca..94cb4d6d 100644 --- a/crates/ui/src/input/state.rs +++ b/crates/ui/src/input/state.rs @@ -983,7 +983,12 @@ impl InputState { return 0; } - let offset = self.previous_boundary(self.selected_range.start.min(self.selected_range.end)); + let mut offset = + self.previous_boundary(self.selected_range.start.min(self.selected_range.end)); + if self.text.chars().nth(offset) == Some('\r') { + offset += 1; + } + let line = self .text_for_range(self.range_to_utf16(&(0..offset + 1)), &mut None, window, cx) .unwrap_or_default() @@ -1197,7 +1202,8 @@ impl InputState { let mut added_len = 0; if !self.selected_range.is_empty() { - let mut offset = self.start_of_line_of_selection(window, cx); + let start_offset = self.start_of_line_of_selection(window, cx); + let mut offset = start_offset; let selected_text = self .text_for_range( @@ -1208,9 +1214,7 @@ impl InputState { ) .unwrap_or("".into()); - let mut lines_count = 0; - for line in selected_text.lines() { - lines_count += 1; + for line in selected_text.split('\n') { self.replace_text_in_range( Some(self.range_to_utf16(&(offset..offset))), &tab_indent, @@ -1218,17 +1222,11 @@ impl InputState { cx, ); added_len += tab_indent.len(); - // +1 for "\n" + // +1 for "\n", the `\r` is included in the `line`. offset += line.len() + tab_indent.len() + 1; } - if lines_count > 1 { - self.selected_range = - selected_range.start + tab_indent.len()..selected_range.end + added_len; - } else { - self.selected_range = - selected_range.start + added_len..selected_range.end + added_len; - } + self.selected_range = start_offset..selected_range.end + added_len; } else { // Selected none let offset = self.selected_range.start; @@ -1254,7 +1252,8 @@ impl InputState { let mut removed_len = 0; if !self.selected_range.is_empty() { - let mut offset = self.start_of_line_of_selection(window, cx); + let start_offset = self.start_of_line_of_selection(window, cx); + let mut offset = start_offset; let selected_text = self .text_for_range( @@ -1265,9 +1264,7 @@ impl InputState { ) .unwrap_or("".into()); - let mut lines_count = 0; - for line in selected_text.lines() { - lines_count += 1; + for line in selected_text.split('\n') { if line.starts_with(tab_indent.as_ref()) { self.replace_text_in_range( Some(self.range_to_utf16(&(offset..offset + tab_indent.len()))), @@ -1281,15 +1278,10 @@ impl InputState { offset += line.len().saturating_sub(tab_indent.len()) + 1; } - if lines_count > 1 { - self.selected_range = selected_range.start.saturating_sub(tab_indent.len()) - ..selected_range.end.saturating_sub(removed_len); - } else { - self.selected_range = selected_range.start.saturating_sub(tab_indent.len()) - ..selected_range.end.saturating_sub(tab_indent.len()); - } + self.selected_range = start_offset..selected_range.end.saturating_sub(removed_len); } else { // Selected none + let start_offset = self.selected_range.start; let offset = self.start_of_line_of_selection(window, cx); if self.text[offset..].starts_with(tab_indent.as_ref()) { self.replace_text_in_range( @@ -1299,9 +1291,8 @@ impl InputState { cx, ); removed_len = tab_indent.len(); - - self.selected_range = selected_range.start.saturating_sub(removed_len) - ..selected_range.end.saturating_sub(removed_len); + let new_offset = start_offset.saturating_sub(removed_len); + self.selected_range = new_offset..new_offset; } } }