Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ That said, these are more guidelines rather than hard rules, though the project

## [0.12.4]/[0.13.0] - Unreleased

### Bug Fixes

- [#2035](https://github.com/ClementTsang/bottom/pull/2035): Fix panic when deleting unicode words in search.

### Features

- [#1938](https://github.com/ClementTsang/bottom/pull/1938), [#1980](https://github.com/ClementTsang/bottom/pull/1980): Report average packet size and packet rate.
Expand Down
199 changes: 34 additions & 165 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ pub mod states;

use std::time::Instant;

use concat_string::concat_string;
use data::*;
use filter::*;
use layout_manager::*;
use rustc_hash::FxHashMap as HashMap;
pub use states::*;
use unicode_segmentation::{GraphemeCursor, UnicodeSegmentation};

use crate::{
canvas::{
Expand Down Expand Up @@ -499,34 +497,13 @@ impl App {
.widget_states
.get_mut(&(self.current_widget.widget_id - 1))
{
if is_in_search_widget
&& proc_widget_state.proc_search.search_state.is_enabled
&& proc_widget_state.cursor_char_index()
< proc_widget_state
.proc_search
.search_state
.current_search_query
.len()
if is_in_search_widget && proc_widget_state.proc_search.search_state.is_enabled
{
let current_cursor = proc_widget_state.cursor_char_index();
proc_widget_state.search_walk_forward();

let _ = proc_widget_state
proc_widget_state
.proc_search
.search_state
.current_search_query
.drain(current_cursor..proc_widget_state.cursor_char_index());

proc_widget_state.proc_search.search_state.grapheme_cursor =
GraphemeCursor::new(
current_cursor,
proc_widget_state
.proc_search
.search_state
.current_search_query
.len(),
true,
);
.input_field_state
.delete_at_cursor();

proc_widget_state.update_query();
}
Expand All @@ -548,33 +525,12 @@ impl App {
.widget_states
.get_mut(&(self.current_widget.widget_id - 1))
{
if is_in_search_widget
&& proc_widget_state.proc_search.search_state.is_enabled
&& proc_widget_state.cursor_char_index() > 0
{
let current_cursor = proc_widget_state.cursor_char_index();
proc_widget_state.search_walk_back();

// Remove the indices in between.
let _ = proc_widget_state
if is_in_search_widget && proc_widget_state.proc_search.search_state.is_enabled {
proc_widget_state
.proc_search
.search_state
.current_search_query
.drain(proc_widget_state.cursor_char_index()..current_cursor);

proc_widget_state.proc_search.search_state.grapheme_cursor =
GraphemeCursor::new(
proc_widget_state.cursor_char_index(),
proc_widget_state
.proc_search
.search_state
.current_search_query
.len(),
true,
);

proc_widget_state.proc_search.search_state.cursor_direction =
CursorDirection::Left;
.input_field_state
.delete_behind_cursor();

proc_widget_state.update_query();
}
Expand Down Expand Up @@ -626,12 +582,11 @@ impl App {
.get_mut_widget_state(self.current_widget.widget_id - 1)
{
if is_in_search_widget {
let prev_cursor = proc_widget_state.cursor_char_index();
proc_widget_state.search_walk_back();
if proc_widget_state.cursor_char_index() < prev_cursor {
proc_widget_state.proc_search.search_state.cursor_direction =
CursorDirection::Left;
}
proc_widget_state
.proc_search
.search_state
.input_field_state
.move_left();
}
}
}
Expand Down Expand Up @@ -674,12 +629,11 @@ impl App {
.get_mut_widget_state(self.current_widget.widget_id - 1)
{
if is_in_search_widget {
let prev_cursor = proc_widget_state.cursor_char_index();
proc_widget_state.search_walk_forward();
if proc_widget_state.cursor_char_index() > prev_cursor {
proc_widget_state.proc_search.search_state.cursor_direction =
CursorDirection::Right;
}
proc_widget_state
.proc_search
.search_state
.input_field_state
.move_right();
}
}
}
Expand Down Expand Up @@ -816,19 +770,11 @@ impl App {
.get_mut(&(self.current_widget.widget_id - 1))
{
if is_in_search_widget {
proc_widget_state.proc_search.search_state.grapheme_cursor =
GraphemeCursor::new(
0,
proc_widget_state
.proc_search
.search_state
.current_search_query
.len(),
true,
);

proc_widget_state.proc_search.search_state.cursor_direction =
CursorDirection::Left;
proc_widget_state
.proc_search
.search_state
.input_field_state
.skip_to_beginning();
}
}
}
Expand All @@ -846,16 +792,11 @@ impl App {
.get_mut(&(self.current_widget.widget_id - 1))
{
if is_in_search_widget {
let query_len = proc_widget_state
proc_widget_state
.proc_search
.search_state
.current_search_query
.len();

proc_widget_state.proc_search.search_state.grapheme_cursor =
GraphemeCursor::new(query_len, query_len, true);
proc_widget_state.proc_search.search_state.cursor_direction =
CursorDirection::Right;
.input_field_state
.skip_to_end();
}
}
}
Expand Down Expand Up @@ -883,52 +824,11 @@ impl App {
.widget_states
.get_mut(&(self.current_widget.widget_id - 1))
{
// Traverse backwards from the current cursor location until you hit
// non-whitespace characters, then continue to traverse (and
// delete) backwards until you hit a whitespace character. Halt.

// So... first, let's get our current cursor position in terms of char indices.
let end_index = proc_widget_state.cursor_char_index();

// Then, let's crawl backwards until we hit our location, and store the
// "head"...
let query = proc_widget_state.current_search_query();
let mut start_index = 0;
let mut saw_non_whitespace = false;

for (itx, c) in query
.chars()
.rev()
.enumerate()
.skip(query.len() - end_index)
{
if c.is_whitespace() {
if saw_non_whitespace {
start_index = query.len() - itx;
break;
}
} else {
saw_non_whitespace = true;
}
}

let _ = proc_widget_state
proc_widget_state
.proc_search
.search_state
.current_search_query
.drain(start_index..end_index);

proc_widget_state.proc_search.search_state.grapheme_cursor = GraphemeCursor::new(
start_index,
proc_widget_state
.proc_search
.search_state
.current_search_query
.len(),
true,
);

proc_widget_state.proc_search.search_state.cursor_direction = CursorDirection::Left;
.input_field_state
.delete_previous_word();

proc_widget_state.update_query();
}
Expand Down Expand Up @@ -967,24 +867,10 @@ impl App {
proc_widget_state
.proc_search
.search_state
.current_search_query
.insert(proc_widget_state.cursor_char_index(), caught_char);

proc_widget_state.proc_search.search_state.grapheme_cursor =
GraphemeCursor::new(
proc_widget_state.cursor_char_index(),
proc_widget_state
.proc_search
.search_state
.current_search_query
.len(),
true,
);
proc_widget_state.search_walk_forward();
.input_field_state
.insert_char(caught_char);

proc_widget_state.update_query();
proc_widget_state.proc_search.search_state.cursor_direction =
CursorDirection::Right;

return;
}
Expand Down Expand Up @@ -2618,38 +2504,21 @@ impl App {

/// A quick and dirty way to handle paste events.
pub fn handle_paste(&mut self, paste: String) {
// Partially copy-pasted from the single-char variant; should probably clean up
// this process in the future. In particular, encapsulate this entire
// logic and add some tests to make it less potentially error-prone.
let is_in_search_widget = self.is_in_search_widget();
if let Some(proc_widget_state) = self
.states
.proc_state
.widget_states
.get_mut(&(self.current_widget.widget_id - 1))
{
let num_runes = UnicodeSegmentation::graphemes(paste.as_str(), true).count();

if is_in_search_widget && proc_widget_state.is_search_enabled() {
let left_bound = proc_widget_state.cursor_char_index();

let curr_query = &mut proc_widget_state
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(left_bound, curr_query.len(), true);

for _ in 0..num_runes {
proc_widget_state.search_walk_forward();
}
.input_field_state
.insert_string(paste);

proc_widget_state.update_query();
proc_widget_state.proc_search.search_state.cursor_direction =
CursorDirection::Right;
}
}
}
Expand Down
Loading
Loading