e fixed
This commit is contained in:
@@ -319,11 +319,20 @@ async fn execute_edit_action<S: CanvasState>(
|
||||
"move_word_end" => {
|
||||
let current_input = state.get_current_input();
|
||||
if !current_input.is_empty() {
|
||||
let new_pos =
|
||||
find_word_end(current_input, state.current_cursor_pos());
|
||||
let final_pos = new_pos.min(current_input.len());
|
||||
state.set_current_cursor_pos(final_pos);
|
||||
*ideal_cursor_column = final_pos;
|
||||
let current_pos = state.current_cursor_pos();
|
||||
let new_pos = find_word_end(current_input, current_pos);
|
||||
|
||||
// If already at word end, jump to next word's end
|
||||
let final_pos = if new_pos == current_pos {
|
||||
find_word_end(current_input, new_pos + 1)
|
||||
} else {
|
||||
new_pos
|
||||
};
|
||||
|
||||
let max_valid_index = current_input.len().saturating_sub(1);
|
||||
let clamped_pos = final_pos.min(max_valid_index);
|
||||
state.set_current_cursor_pos(clamped_pos);
|
||||
*ideal_cursor_column = clamped_pos;
|
||||
}
|
||||
Ok("".to_string())
|
||||
}
|
||||
@@ -400,19 +409,17 @@ fn find_word_end(text: &str, current_pos: usize) -> usize {
|
||||
if len == 0 {
|
||||
return 0;
|
||||
}
|
||||
if current_pos >= len {
|
||||
return len;
|
||||
|
||||
let mut pos = current_pos.min(len - 1);
|
||||
|
||||
// If already at whitespace, find next word first
|
||||
if get_char_type(chars[pos]) == CharType::Whitespace {
|
||||
pos = find_next_word_start(text, pos);
|
||||
}
|
||||
|
||||
let mut pos = current_pos;
|
||||
|
||||
if get_char_type(chars[pos]) == CharType::Whitespace {
|
||||
while pos < len && get_char_type(chars[pos]) == CharType::Whitespace {
|
||||
pos += 1;
|
||||
}
|
||||
if pos == len {
|
||||
return len;
|
||||
}
|
||||
// Now find end of current/next word
|
||||
if pos >= len {
|
||||
return len.saturating_sub(1);
|
||||
}
|
||||
|
||||
let word_type = get_char_type(chars[pos]);
|
||||
@@ -420,11 +427,8 @@ fn find_word_end(text: &str, current_pos: usize) -> usize {
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
if pos > current_pos && pos > 0 {
|
||||
pos - 1
|
||||
} else {
|
||||
current_pos.min(len.saturating_sub(1))
|
||||
}
|
||||
// Return last character of the word
|
||||
pos.saturating_sub(1).min(len.saturating_sub(1))
|
||||
}
|
||||
|
||||
fn find_prev_word_start(text: &str, current_pos: usize) -> usize {
|
||||
|
||||
@@ -296,18 +296,21 @@ async fn execute_action<S: CanvasState>(
|
||||
"move_word_end" => {
|
||||
let current_input = state.get_current_input();
|
||||
if !current_input.is_empty() {
|
||||
// 1. Find the index of the last character of the target word
|
||||
let new_pos =
|
||||
find_word_end(current_input, state.current_cursor_pos());
|
||||
let current_pos = state.current_cursor_pos();
|
||||
let new_pos = find_word_end(current_input, current_pos);
|
||||
|
||||
// Only move if we're not already at the found position
|
||||
let final_pos = if new_pos != current_pos {
|
||||
new_pos
|
||||
} else {
|
||||
// If already at a word end, jump to next word's end
|
||||
find_word_end(current_input, new_pos + 1)
|
||||
};
|
||||
|
||||
// 2. Clamp the position for Read-Only mode
|
||||
// max_valid_index is the index of the VERY LAST character in the input string
|
||||
let max_valid_index = current_input.len().saturating_sub(1);
|
||||
let final_pos = new_pos.min(max_valid_index);
|
||||
|
||||
// 3. Set the cursor
|
||||
state.set_current_cursor_pos(final_pos);
|
||||
*ideal_cursor_column = final_pos;
|
||||
let clamped_pos = final_pos.min(max_valid_index);
|
||||
state.set_current_cursor_pos(clamped_pos);
|
||||
*ideal_cursor_column = clamped_pos;
|
||||
}
|
||||
Ok("".to_string())
|
||||
}
|
||||
@@ -394,29 +397,62 @@ fn find_next_word_start(text: &str, current_pos: usize) -> usize {
|
||||
pos
|
||||
}
|
||||
|
||||
fn find_word_end(text: &str, current_pos: usize) -> usize {
|
||||
fn find_next_word_end(text: &str, current_pos: usize) -> usize {
|
||||
let chars: Vec<char> = text.chars().collect();
|
||||
if chars.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
let mut pos = current_pos.min(chars.len().saturating_sub(1));
|
||||
|
||||
if get_char_type(chars[pos]) == CharType::Whitespace {
|
||||
while pos + 1 < chars.len() && get_char_type(chars[pos + 1]) == CharType::Whitespace {
|
||||
// Find start of next word
|
||||
let next_start = find_next_word_start(text, current_pos);
|
||||
|
||||
// Find end of that word
|
||||
if next_start >= chars.len() {
|
||||
return chars.len().saturating_sub(1);
|
||||
}
|
||||
|
||||
let mut pos = next_start;
|
||||
let word_type = get_char_type(chars[pos]);
|
||||
|
||||
while pos < chars.len() && get_char_type(chars[pos]) == word_type {
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
pos.saturating_sub(1).min(chars.len().saturating_sub(1))
|
||||
}
|
||||
|
||||
fn find_word_end(text: &str, current_pos: usize) -> usize {
|
||||
let chars: Vec<char> = text.chars().collect();
|
||||
let len = chars.len();
|
||||
if len == 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let mut pos = current_pos.min(len - 1);
|
||||
let original_pos = pos;
|
||||
|
||||
// First try to find end of current word
|
||||
let current_type = get_char_type(chars[pos]);
|
||||
if current_type != CharType::Whitespace {
|
||||
// Move forward to word end
|
||||
while pos < len && get_char_type(chars[pos]) == current_type {
|
||||
pos += 1;
|
||||
}
|
||||
if pos + 1 >= chars.len() || get_char_type(chars[pos + 1]) == CharType::Whitespace {
|
||||
return pos;
|
||||
}
|
||||
pos += 1;
|
||||
return pos.saturating_sub(1);
|
||||
}
|
||||
|
||||
// If in whitespace, find next word's end
|
||||
pos = find_next_word_start(text, pos);
|
||||
if pos >= len {
|
||||
return len.saturating_sub(1);
|
||||
}
|
||||
|
||||
let word_type = get_char_type(chars[pos]);
|
||||
while pos + 1 < chars.len() && get_char_type(chars[pos + 1]) == word_type {
|
||||
while pos < len && get_char_type(chars[pos]) == word_type {
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
pos
|
||||
pos.saturating_sub(1).min(len.saturating_sub(1))
|
||||
}
|
||||
|
||||
fn find_prev_word_start(text: &str, current_pos: usize) -> usize {
|
||||
|
||||
Reference in New Issue
Block a user