Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: search paste support #881

Merged
merged 7 commits into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fix issues with cjk/flag characters
  • Loading branch information
ClementTsang committed Nov 10, 2022
commit 17a6c122043083fcc6bb522ad56416023c18a312
25 changes: 12 additions & 13 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
};

use concat_string::concat_string;
use unicode_segmentation::GraphemeCursor;
use unicode_segmentation::{GraphemeCursor, UnicodeSegmentation};
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};

use typed_builder::*;
Expand Down Expand Up @@ -2734,35 +2734,34 @@ impl App {
.as_str(),
);
let paste_width = UnicodeWidthStr::width(paste.as_str());
let num_runes = UnicodeSegmentation::graphemes(paste.as_str(), true).count();

if is_in_search_widget
&& proc_widget_state.is_search_enabled()
&& curr_width + paste_width <= MAX_SEARCH_LENGTH
{
let paste_char_width = paste.len();
let left_bound = proc_widget_state.get_search_cursor_position();
let new_left_bound = (left_bound + paste_width).saturating_sub(1);

let curr_query = &mut proc_widget_state
.proc_search
.search_state
.current_search_query;
let (left, right) = curr_query.split_at(left_bound);
*curr_query = concat_string!(left, paste, right);

proc_widget_state.proc_search.search_state.grapheme_cursor = GraphemeCursor::new(
new_left_bound,
proc_widget_state
.proc_search
.search_state
.current_search_query
.len(),
true,
);
proc_widget_state.search_walk_forward(new_left_bound);
proc_widget_state.proc_search.search_state.grapheme_cursor =
GraphemeCursor::new(left_bound, curr_query.len(), true);

for _ in 0..num_runes {
let cursor = proc_widget_state.get_search_cursor_position();
proc_widget_state.search_walk_forward(cursor);
}

proc_widget_state
.proc_search
.search_state
.char_cursor_position += paste_width;
.char_cursor_position += paste_char_width;

proc_widget_state.update_query();
proc_widget_state.proc_search.search_state.cursor_direction =
Expand Down
68 changes: 56 additions & 12 deletions src/app/widgets/process_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub use proc_widget_data::*;

mod sort_table;
use sort_table::SortTableColumn;
use unicode_segmentation::GraphemeIncomplete;

/// ProcessSearchState only deals with process' search's current settings and state.
pub struct ProcessSearchState {
Expand Down Expand Up @@ -775,25 +776,68 @@ impl ProcWidget {
}

pub fn search_walk_forward(&mut self, start_position: usize) {
self.proc_search
// TODO: Add tests for this.
let chunk = &self.proc_search.search_state.current_search_query[start_position..];

match self
.proc_search
.search_state
.grapheme_cursor
.next_boundary(
&self.proc_search.search_state.current_search_query[start_position..],
start_position,
)
.unwrap();
.next_boundary(chunk, start_position)
{
Ok(_) => {}
Err(err) => match err {
GraphemeIncomplete::PreContext(ctx) => {
// Provide the entire string as context. Not efficient but should resolve failures.
self.proc_search
.search_state
.grapheme_cursor
.provide_context(
&self.proc_search.search_state.current_search_query[0..ctx],
0,
);

self.proc_search
.search_state
.grapheme_cursor
.next_boundary(chunk, start_position)
.unwrap();
}
_ => Err(err).unwrap(),
},
}
}

pub fn search_walk_back(&mut self, start_position: usize) {
self.proc_search
// TODO: Add tests for this.
let chunk = &self.proc_search.search_state.current_search_query[..start_position];
match self
.proc_search
.search_state
.grapheme_cursor
.prev_boundary(
&self.proc_search.search_state.current_search_query[..start_position],
0,
)
.unwrap();
.prev_boundary(chunk, 0)
{
Ok(_) => {}
Err(err) => match err {
GraphemeIncomplete::PreContext(ctx) => {
// Provide the entire string as context. Not efficient but should resolve failures.
self.proc_search
.search_state
.grapheme_cursor
.provide_context(
&self.proc_search.search_state.current_search_query[0..ctx],
0,
);

self.proc_search
.search_state
.grapheme_cursor
.prev_boundary(chunk, 0)
.unwrap();
}
_ => Err(err).unwrap(),
},
}
}

/// Returns the number of columns *enabled*. Note this differs from *visible* - a column may be enabled but not
Expand Down