Small fixes
parent
f27b815aa7
commit
91ae539de1
|
@ -839,7 +839,7 @@ fn add_path_to_index(
|
||||||
let hash = get_file_hash(path);
|
let hash = get_file_hash(path);
|
||||||
{
|
{
|
||||||
let mut map = hash_index.lock().unwrap();
|
let mut map = hash_index.lock().unwrap();
|
||||||
let map = map.entry(folder_hash).or_default();;
|
let map = map.entry(folder_hash).or_default();
|
||||||
map.insert(hash, path.to_path_buf().into());
|
map.insert(hash, path.to_path_buf().into());
|
||||||
debug!(
|
debug!(
|
||||||
"inserted {} in {} map, len={}",
|
"inserted {} in {} map, len={}",
|
||||||
|
|
|
@ -68,11 +68,10 @@ impl Address {
|
||||||
|
|
||||||
pub fn get_tags(&self, separator: char) -> Vec<String> {
|
pub fn get_tags(&self, separator: char) -> Vec<String> {
|
||||||
let mut ret = Vec::new();
|
let mut ret = Vec::new();
|
||||||
if let email = self.get_email() {
|
let email = self.get_email();
|
||||||
let at_pos = email.as_bytes().iter().position(|&b| b == b'@').unwrap();
|
let at_pos = email.as_bytes().iter().position(|&b| b == b'@').unwrap();
|
||||||
let email: &str = email[..at_pos].into();
|
let email: &str = email[..at_pos].into();
|
||||||
ret.extend(email.split(separator).skip(1).map(str::to_string));
|
ret.extend(email.split(separator).skip(1).map(str::to_string));
|
||||||
}
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,9 +86,7 @@ pub type ShortcutMaps = FnvHashMap<String, ShortcutMap>;
|
||||||
pub trait Component: Display + Debug + Send {
|
pub trait Component: Display + Debug + Send {
|
||||||
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context);
|
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context);
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool;
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool;
|
||||||
fn is_dirty(&self) -> bool {
|
fn is_dirty(&self) -> bool;
|
||||||
true
|
|
||||||
}
|
|
||||||
fn is_visible(&self) -> bool {
|
fn is_visible(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
|
@ -341,6 +341,7 @@ impl Component for MailView {
|
||||||
if !account.contains_key(self.coordinates.2) {
|
if !account.contains_key(self.coordinates.2) {
|
||||||
/* The envelope has been renamed or removed, so wait for the appropriate event to
|
/* The envelope has been renamed or removed, so wait for the appropriate event to
|
||||||
* arrive */
|
* arrive */
|
||||||
|
self.dirty = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (hash, is_seen) = {
|
let (hash, is_seen) = {
|
||||||
|
@ -638,7 +639,6 @@ impl Component for MailView {
|
||||||
self.subview = None;
|
self.subview = None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.dirty = false;
|
|
||||||
}
|
}
|
||||||
match self.mode {
|
match self.mode {
|
||||||
ViewMode::Subview if self.subview.is_some() => {
|
ViewMode::Subview if self.subview.is_some() => {
|
||||||
|
@ -656,6 +656,7 @@ impl Component for MailView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
|
|
|
@ -414,11 +414,14 @@ impl ThreadView {
|
||||||
let bottom_right = bottom_right!(area);
|
let bottom_right = bottom_right!(area);
|
||||||
let (width, height) = self.content.size();
|
let (width, height) = self.content.size();
|
||||||
if height == 0 {
|
if height == 0 {
|
||||||
clear_area(grid, area);
|
|
||||||
context.dirty_areas.push_back(area);
|
context.dirty_areas.push_back(area);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let rows = (get_y(bottom_right) - get_y(upper_left)).wrapping_div(2);
|
let rows = (get_y(bottom_right) - get_y(upper_left)).wrapping_div(2);
|
||||||
|
if rows == 0 {
|
||||||
|
context.dirty_areas.push_back(area);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if let Some(mvm) = self.movement.take() {
|
if let Some(mvm) = self.movement.take() {
|
||||||
match mvm {
|
match mvm {
|
||||||
PageMovement::PageUp => {
|
PageMovement::PageUp => {
|
||||||
|
@ -751,7 +754,10 @@ impl ThreadView {
|
||||||
let upper_left = upper_left!(area);
|
let upper_left = upper_left!(area);
|
||||||
let bottom_right = bottom_right!(area);
|
let bottom_right = bottom_right!(area);
|
||||||
|
|
||||||
let rows = (get_y(bottom_right) - get_y(upper_left) + 1) / 2;
|
let rows = (get_y(bottom_right).saturating_sub(get_y(upper_left) + 1)) / 2;
|
||||||
|
if rows == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let page_no = (self.new_cursor_pos).wrapping_div(rows);
|
let page_no = (self.new_cursor_pos).wrapping_div(rows);
|
||||||
let top_idx = page_no * rows;
|
let top_idx = page_no * rows;
|
||||||
|
|
||||||
|
@ -765,7 +771,10 @@ impl ThreadView {
|
||||||
let area = (set_y(upper_left, y), bottom_right);
|
let area = (set_y(upper_left, y), bottom_right);
|
||||||
let upper_left = upper_left!(area);
|
let upper_left = upper_left!(area);
|
||||||
|
|
||||||
let rows = (get_y(bottom_right) - get_y(upper_left) + 1) / 2;
|
let rows = (get_y(bottom_right).saturating_sub(get_y(upper_left) + 1)) / 2;
|
||||||
|
if rows == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let page_no = (self.new_cursor_pos).wrapping_div(rows);
|
let page_no = (self.new_cursor_pos).wrapping_div(rows);
|
||||||
let top_idx = page_no * rows;
|
let top_idx = page_no * rows;
|
||||||
copy_area(
|
copy_area(
|
||||||
|
@ -875,6 +884,7 @@ impl Component for ThreadView {
|
||||||
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
|
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
|
||||||
let total_cols = width!(area);
|
let total_cols = width!(area);
|
||||||
if self.entries.is_empty() {
|
if self.entries.is_empty() {
|
||||||
|
self.dirty = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,6 +901,7 @@ impl Component for ThreadView {
|
||||||
|
|
||||||
if self.entries.len() == 1 {
|
if self.entries.len() == 1 {
|
||||||
self.mailview.draw(grid, area, context);
|
self.mailview.draw(grid, area, context);
|
||||||
|
self.dirty = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -899,6 +910,7 @@ impl Component for ThreadView {
|
||||||
} else {
|
} else {
|
||||||
self.draw_horz(grid, area, context);
|
self.draw_horz(grid, area, context);
|
||||||
}
|
}
|
||||||
|
self.dirty = false;
|
||||||
}
|
}
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
match event {
|
match event {
|
||||||
|
@ -959,6 +971,7 @@ impl Component for ThreadView {
|
||||||
UIEvent::Input(Key::Up) => {
|
UIEvent::Input(Key::Up) => {
|
||||||
if self.cursor_pos > 0 {
|
if self.cursor_pos > 0 {
|
||||||
self.new_cursor_pos = self.new_cursor_pos.saturating_sub(1);
|
self.new_cursor_pos = self.new_cursor_pos.saturating_sub(1);
|
||||||
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -966,24 +979,25 @@ impl Component for ThreadView {
|
||||||
let height = self.visible_entries.iter().flat_map(|v| v.iter()).count();
|
let height = self.visible_entries.iter().flat_map(|v| v.iter()).count();
|
||||||
if height > 0 && self.new_cursor_pos + 1 < height {
|
if height > 0 && self.new_cursor_pos + 1 < height {
|
||||||
self.new_cursor_pos += 1;
|
self.new_cursor_pos += 1;
|
||||||
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
UIEvent::Input(ref key) if *key == shortcuts["prev_page"] => {
|
UIEvent::Input(ref key) if *key == shortcuts["prev_page"] => {
|
||||||
self.movement = Some(PageMovement::PageUp);
|
self.movement = Some(PageMovement::PageUp);
|
||||||
self.set_dirty();
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
UIEvent::Input(ref key) if *key == shortcuts["next_page"] => {
|
UIEvent::Input(ref key) if *key == shortcuts["next_page"] => {
|
||||||
self.movement = Some(PageMovement::PageDown);
|
self.movement = Some(PageMovement::PageDown);
|
||||||
self.set_dirty();
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
UIEvent::Input(ref key) if *key == Key::Home => {
|
UIEvent::Input(ref key) if *key == Key::Home => {
|
||||||
self.movement = Some(PageMovement::Home);
|
self.movement = Some(PageMovement::Home);
|
||||||
self.set_dirty();
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
UIEvent::Input(ref key) if *key == Key::End => {
|
UIEvent::Input(ref key) if *key == Key::End => {
|
||||||
self.movement = Some(PageMovement::End);
|
self.movement = Some(PageMovement::End);
|
||||||
self.set_dirty();
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
UIEvent::Input(Key::Char('\n')) => {
|
UIEvent::Input(Key::Char('\n')) => {
|
||||||
if self.entries.len() < 2 {
|
if self.entries.len() < 2 {
|
||||||
|
@ -1066,9 +1080,7 @@ impl Component for ThreadView {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
fn is_dirty(&self) -> bool {
|
fn is_dirty(&self) -> bool {
|
||||||
(self.cursor_pos != self.new_cursor_pos)
|
self.dirty || (self.show_mailview && self.mailview.is_dirty())
|
||||||
|| self.dirty
|
|
||||||
|| (self.show_mailview && self.mailview.is_dirty())
|
|
||||||
}
|
}
|
||||||
fn set_dirty(&mut self) {
|
fn set_dirty(&mut self) {
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
|
|
|
@ -73,6 +73,9 @@ impl Component for XDGNotifications {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
fn set_dirty(&mut self) {}
|
fn set_dirty(&mut self) {}
|
||||||
|
fn is_dirty(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn id(&self) -> ComponentId {
|
fn id(&self) -> ComponentId {
|
||||||
ComponentId::nil()
|
ComponentId::nil()
|
||||||
|
@ -174,6 +177,9 @@ impl Component for NotificationFilter {
|
||||||
fn id(&self) -> ComponentId {
|
fn id(&self) -> ComponentId {
|
||||||
ComponentId::nil()
|
ComponentId::nil()
|
||||||
}
|
}
|
||||||
|
fn is_dirty(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
fn set_dirty(&mut self) {}
|
fn set_dirty(&mut self) {}
|
||||||
fn set_id(&mut self, _id: ComponentId) {}
|
fn set_id(&mut self, _id: ComponentId) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -554,7 +554,7 @@ impl Component for Pager {
|
||||||
"Pager text piped to '{}{}{}'",
|
"Pager text piped to '{}{}{}'",
|
||||||
&bin,
|
&bin,
|
||||||
if args.is_empty() { "" } else { " " },
|
if args.is_empty() { "" } else { " " },
|
||||||
args.join(", ")
|
args.join(" ")
|
||||||
))));
|
))));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1121,6 +1121,9 @@ impl Component for Progress {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
fn set_dirty(&mut self) {}
|
fn set_dirty(&mut self) {}
|
||||||
|
fn is_dirty(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn id(&self) -> ComponentId {
|
fn id(&self) -> ComponentId {
|
||||||
self.id
|
self.id
|
||||||
|
|
|
@ -195,7 +195,7 @@ impl Component for Field {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
fn is_dirty(&self) -> bool {
|
fn is_dirty(&self) -> bool {
|
||||||
true
|
false
|
||||||
}
|
}
|
||||||
fn set_dirty(&mut self) {}
|
fn set_dirty(&mut self) {}
|
||||||
|
|
||||||
|
@ -477,6 +477,7 @@ where
|
||||||
|
|
||||||
result: Option<T>,
|
result: Option<T>,
|
||||||
cursor: usize,
|
cursor: usize,
|
||||||
|
dirty: bool,
|
||||||
id: ComponentId,
|
id: ComponentId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,6 +500,7 @@ where
|
||||||
buttons: vec![init_val].into_iter().collect(),
|
buttons: vec![init_val].into_iter().collect(),
|
||||||
result: None,
|
result: None,
|
||||||
cursor: 0,
|
cursor: 0,
|
||||||
|
dirty: true,
|
||||||
id: ComponentId::new_v4(),
|
id: ComponentId::new_v4(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,28 +520,31 @@ where
|
||||||
T: std::fmt::Debug + Default + Send,
|
T: std::fmt::Debug + Default + Send,
|
||||||
{
|
{
|
||||||
fn draw(&mut self, grid: &mut CellBuffer, area: Area, _context: &mut Context) {
|
fn draw(&mut self, grid: &mut CellBuffer, area: Area, _context: &mut Context) {
|
||||||
let upper_left = upper_left!(area);
|
if self.dirty {
|
||||||
|
let upper_left = upper_left!(area);
|
||||||
|
|
||||||
let mut len = 0;
|
let mut len = 0;
|
||||||
for (i, k) in self.layout.iter().enumerate() {
|
for (i, k) in self.layout.iter().enumerate() {
|
||||||
let cur_len = k.len();
|
let cur_len = k.len();
|
||||||
write_string_to_grid(
|
write_string_to_grid(
|
||||||
k.as_str(),
|
k.as_str(),
|
||||||
grid,
|
grid,
|
||||||
Color::Default,
|
Color::Default,
|
||||||
if i == self.cursor {
|
if i == self.cursor {
|
||||||
Color::Byte(246)
|
Color::Byte(246)
|
||||||
} else {
|
} else {
|
||||||
Color::Default
|
Color::Default
|
||||||
},
|
},
|
||||||
Attr::Default,
|
Attr::Default,
|
||||||
(
|
(
|
||||||
pos_inc(upper_left, (len, 0)),
|
pos_inc(upper_left, (len, 0)),
|
||||||
pos_inc(upper_left, (cur_len + len, 0)),
|
pos_inc(upper_left, (cur_len + len, 0)),
|
||||||
),
|
),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
len += cur_len + 3;
|
len += cur_len + 3;
|
||||||
|
}
|
||||||
|
self.dirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
|
||||||
|
@ -550,25 +555,26 @@ where
|
||||||
.remove(&self.layout[self.cursor])
|
.remove(&self.layout[self.cursor])
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
);
|
);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
UIEvent::Input(Key::Left) => {
|
UIEvent::Input(Key::Left) => {
|
||||||
self.cursor = self.cursor.saturating_sub(1);
|
self.cursor = self.cursor.saturating_sub(1);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
UIEvent::Input(Key::Right) if self.cursor < self.layout.len().saturating_sub(1) => {
|
UIEvent::Input(Key::Right) if self.cursor < self.layout.len().saturating_sub(1) => {
|
||||||
self.cursor += 1;
|
self.cursor += 1;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
self.set_dirty();
|
||||||
false
|
|
||||||
}
|
|
||||||
fn is_dirty(&self) -> bool {
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
fn set_dirty(&mut self) {}
|
fn is_dirty(&self) -> bool {
|
||||||
|
self.dirty
|
||||||
|
}
|
||||||
|
fn set_dirty(&mut self) {
|
||||||
|
self.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
fn id(&self) -> ComponentId {
|
fn id(&self) -> ComponentId {
|
||||||
self.id
|
self.id
|
||||||
|
@ -695,7 +701,7 @@ impl AutoComplete {
|
||||||
|
|
||||||
pub fn set_suggestions(&mut self, entries: Vec<AutoCompleteEntry>) -> bool {
|
pub fn set_suggestions(&mut self, entries: Vec<AutoCompleteEntry>) -> bool {
|
||||||
if entries.len() == self.entries.len() && entries == self.entries {
|
if entries.len() == self.entries.len() && entries == self.entries {
|
||||||
return false;;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut content = CellBuffer::new(
|
let mut content = CellBuffer::new(
|
||||||
|
|
|
@ -403,6 +403,9 @@ impl State {
|
||||||
self.draw_component(i);
|
self.draw_component(i);
|
||||||
}
|
}
|
||||||
let mut areas: Vec<Area> = self.context.dirty_areas.drain(0..).collect();
|
let mut areas: Vec<Area> = self.context.dirty_areas.drain(0..).collect();
|
||||||
|
if areas.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* Sort by x_start, ie upper_left corner's x coordinate */
|
/* Sort by x_start, ie upper_left corner's x coordinate */
|
||||||
areas.sort_by(|a, b| (a.0).0.partial_cmp(&(b.0).0).unwrap());
|
areas.sort_by(|a, b| (a.0).0.partial_cmp(&(b.0).0).unwrap());
|
||||||
/* draw each dirty area */
|
/* draw each dirty area */
|
||||||
|
@ -510,9 +513,11 @@ impl State {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_component(&mut self, component: Box<dyn Component>) {
|
pub fn register_component(&mut self, component: Box<dyn Component>) {
|
||||||
self.components.push(component);
|
self.components.push(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert user commands to actions/method calls.
|
/// Convert user commands to actions/method calls.
|
||||||
fn parse_command(&mut self, cmd: &str) {
|
fn parse_command(&mut self, cmd: &str) {
|
||||||
let result = parse_command(&cmd.as_bytes()).to_full_result();
|
let result = parse_command(&cmd.as_bytes()).to_full_result();
|
||||||
|
|
|
@ -243,7 +243,7 @@ impl WorkController {
|
||||||
} else if static_threads.contains_key(&thread_id) {
|
} else if static_threads.contains_key(&thread_id) {
|
||||||
static_threads.entry(thread_id).and_modify(|e| e.name = new_name);
|
static_threads.entry(thread_id).and_modify(|e| e.name = new_name);
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
static_threads.insert(thread_id, new_name.into());
|
||||||
}
|
}
|
||||||
pulse.send(ThreadEvent::Pulse).unwrap();
|
pulse.send(ThreadEvent::Pulse).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ impl WorkController {
|
||||||
static_threads.entry(thread_id).and_modify(|e| e.status = new_status);
|
static_threads.entry(thread_id).and_modify(|e| e.status = new_status);
|
||||||
debug!(&static_threads[&thread_id]);
|
debug!(&static_threads[&thread_id]);
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
static_threads.insert(thread_id, Worker { status: new_status, .. String::new().into() });
|
||||||
}
|
}
|
||||||
pulse.send(ThreadEvent::Pulse).unwrap();
|
pulse.send(ThreadEvent::Pulse).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ impl WorkController {
|
||||||
} else if static_threads.contains_key(&thread_id) {
|
} else if static_threads.contains_key(&thread_id) {
|
||||||
static_threads.remove(&thread_id);
|
static_threads.remove(&thread_id);
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
/* Nothing to do */
|
||||||
}
|
}
|
||||||
pulse.send(ThreadEvent::Pulse).unwrap();
|
pulse.send(ThreadEvent::Pulse).unwrap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue