Skip to content

Commit

Permalink
feature: Beginnings of in-app config (#231)
Browse files Browse the repository at this point in the history
Initial refactorings and additions to support in-app config.

- Refactor our current options logic to support in-app configs.  That is, we can write to a config file with our changes now.
- The default action when creating a new config file is to leave it blank. (TBD and for now, not sure on this one)
- Previously, we would set everything in a config file on startup; now we need to read from the config TOML struct whenever.
- `C` keybind is now occupied for configs.
- `no_write` option to never write to a config file.
  • Loading branch information
ClementTsang committed Sep 22, 2020
1 parent b0b174e commit 6db7602
Show file tree
Hide file tree
Showing 20 changed files with 472 additions and 394 deletions.
4 changes: 2 additions & 2 deletions .cargo-husky/hooks/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ echo "Running pre-push hook:"
echo "Executing: cargo +nightly clippy -- -D clippy::all"
cargo +nightly clippy -- -D clippy::all

echo "Executing: cargo test"
cargo test
# echo "Executing: cargo test"
# cargo test
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"hjkl",
"htop",
"indexmap",
"keybinds",
"libc",
"markdownlint",
"memb",
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- [#223](https://github.com/ClementTsang/bottom/pull/223): Add tree mode for processes.

- [](): Add in-app configuration.

### Changes

- [#213](https://github.com/ClementTsang/bottom/pull/213), [#214](https://github.com/ClementTsang/bottom/pull/214): Updated help descriptions, added auto-complete generation.
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ If you want to help contribute by submitting a PR, by all means, I'm open! In re

- You can check clippy using `cargo clippy`.

- I use [cargo-husky](https://github.com/rhysd/cargo-husky) to automatically run a `cargo clippy` and `cargo test` check.
- I use [cargo-husky](https://github.com/rhysd/cargo-husky) to automatically run a `cargo clippy` check.

- You may notice that I have fern and log as dependencies; this is mostly for easy debugging via the `debug!()` macro. It writes to the `debug.log` file that will automatically be created if you run in debug mode (so `cargo run`).

Expand Down
99 changes: 80 additions & 19 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, time::Instant};
use std::{collections::HashMap, io::Write, path::PathBuf, time::Instant};

use unicode_segmentation::GraphemeCursor;
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
Expand All @@ -12,6 +12,7 @@ pub use states::*;

use crate::{
canvas, constants,
options::Config,
utils::error::{BottomError, Result},
Pid,
};
Expand Down Expand Up @@ -42,6 +43,7 @@ pub struct AppConfigFields {
pub use_old_network_legend: bool,
pub table_gap: u16,
pub disable_click: bool,
pub no_write: bool,
}

/// For filtering out information
Expand Down Expand Up @@ -100,6 +102,9 @@ pub struct App {
#[builder(default = false, setter(skip))]
pub basic_mode_use_percent: bool,

#[builder(default = false, setter(skip))]
pub is_config_open: bool,

pub cpu_state: CpuState,
pub mem_state: MemState,
pub net_state: NetState,
Expand All @@ -113,6 +118,8 @@ pub struct App {
pub current_widget: BottomWidget,
pub used_widgets: UsedWidgets,
pub filters: DataFilters,
pub config: Config,
pub config_path: Option<PathBuf>,
}

impl App {
Expand Down Expand Up @@ -171,6 +178,8 @@ impl App {
}

self.is_force_redraw = true;
} else if self.is_config_open {
self.close_config();
} else {
match self.current_widget.widget_type {
BottomWidgetType::Proc => {
Expand Down Expand Up @@ -247,10 +256,14 @@ impl App {
self.help_dialog_state.is_showing_help || self.delete_dialog_state.is_showing_dd
}

fn ignore_normal_keybinds(&self) -> bool {
self.is_config_open || self.is_in_dialog()
}

pub fn on_tab(&mut self) {
// Disallow usage whilst in a dialog and only in processes
// Allow usage whilst only in processes

if !self.is_in_dialog() {
if !self.ignore_normal_keybinds() {
match self.current_widget.widget_type {
BottomWidgetType::Cpu => {
if let Some(cpu_widget_state) = self
Expand Down Expand Up @@ -319,7 +332,7 @@ impl App {
}

pub fn on_slash(&mut self) {
if !self.is_in_dialog() {
if !self.ignore_normal_keybinds() {
match &self.current_widget.widget_type {
BottomWidgetType::Proc | BottomWidgetType::ProcSort => {
// Toggle on
Expand Down Expand Up @@ -452,6 +465,8 @@ impl App {
.search_toggle_ignore_case();
proc_widget_state.update_query();
self.proc_state.force_update = Some(self.current_widget.widget_id - 1);

// Also toggle it in the config file.
}
}
}
Expand Down Expand Up @@ -653,7 +668,8 @@ impl App {
}

pub fn on_up_key(&mut self) {
if !self.is_in_dialog() {
if self.is_config_open {
} else if !self.is_in_dialog() {
self.decrement_position_count();
} else if self.help_dialog_state.is_showing_help {
self.help_scroll_up();
Expand All @@ -662,7 +678,8 @@ impl App {
}

pub fn on_down_key(&mut self) {
if !self.is_in_dialog() {
if self.is_config_open {
} else if !self.is_in_dialog() {
self.increment_position_count();
} else if self.help_dialog_state.is_showing_help {
self.help_scroll_down();
Expand All @@ -671,7 +688,8 @@ impl App {
}

pub fn on_left_key(&mut self) {
if !self.is_in_dialog() {
if self.is_config_open {
} else if !self.is_in_dialog() {
match self.current_widget.widget_type {
BottomWidgetType::Proc => {
// if let Some(proc_widget_state) = self
Expand Down Expand Up @@ -735,7 +753,8 @@ impl App {
}

pub fn on_right_key(&mut self) {
if !self.is_in_dialog() {
if self.is_config_open {
} else if !self.is_in_dialog() {
match self.current_widget.widget_type {
BottomWidgetType::Proc => {
// if let Some(proc_widget_state) = self
Expand Down Expand Up @@ -804,7 +823,7 @@ impl App {
}

pub fn skip_cursor_beginning(&mut self) {
if !self.is_in_dialog() {
if !self.ignore_normal_keybinds() {
if let BottomWidgetType::ProcSearch = self.current_widget.widget_type {
let is_in_search_widget = self.is_in_search_widget();
if let Some(proc_widget_state) = self
Expand Down Expand Up @@ -836,11 +855,12 @@ impl App {
}
}
}
} else if self.is_config_open {
}
}

pub fn skip_cursor_end(&mut self) {
if !self.is_in_dialog() {
if !self.ignore_normal_keybinds() {
if let BottomWidgetType::ProcSearch = self.current_widget.widget_type {
let is_in_search_widget = self.is_in_search_widget();
if let Some(proc_widget_state) = self
Expand Down Expand Up @@ -882,6 +902,7 @@ impl App {
}
}
}
} else if self.is_config_open {
}
}

Expand Down Expand Up @@ -945,7 +966,7 @@ impl App {
}

// Forbid any char key presses when showing a dialog box...
if !self.is_in_dialog() {
if !self.ignore_normal_keybinds() {
let current_key_press_inst = Instant::now();
if current_key_press_inst
.duration_since(self.last_key_press)
Expand Down Expand Up @@ -1034,6 +1055,7 @@ impl App {
'k' | 'l' => self.on_right_key(),
_ => {}
}
} else if self.is_config_open {
}
}

Expand Down Expand Up @@ -1086,6 +1108,9 @@ impl App {
self.data_collection.set_frozen_time();
}
}
'C' => {
// self.open_config(),
}
'c' => {
if let BottomWidgetType::Proc = self.current_widget.widget_type {
if let Some(proc_widget_state) = self
Expand Down Expand Up @@ -1227,6 +1252,7 @@ impl App {
's' => self.toggle_sort(),
'I' => self.invert_sort(),
'%' => self.toggle_percentages(),
' ' => self.on_space(),
_ => {}
}

Expand All @@ -1237,6 +1263,38 @@ impl App {
}
}

pub fn on_space(&mut self) {}

pub fn open_config(&mut self) {
self.is_config_open = true;
self.is_force_redraw = true;
}

pub fn close_config(&mut self) {
self.is_config_open = false;
self.is_force_redraw = true;
}

/// Call this whenever the config value is updated!
fn update_config_file(&mut self) -> anyhow::Result<()> {
if self.app_config_fields.no_write {
// Don't write!
// FIXME: [CONFIG] This should be made VERY clear to the user... make a thing saying "it will not write due to no_write option"
Ok(())
} else if let Some(config_path) = &self.config_path {
// Update
std::fs::File::open(config_path)?
.write_all(toml::to_string(&self.config)?.as_bytes())?;

Ok(())
} else {
// FIXME: [CONFIG] Put an actual error message?
Err(anyhow::anyhow!(
"Config path was missing, please try restarting bottom..."
))
}
}

pub fn kill_highlighted_process(&mut self) -> Result<()> {
if let BottomWidgetType::Proc = self.current_widget.widget_type {
if let Some(current_selected_processes) = &self.to_delete_process_list {
Expand Down Expand Up @@ -1268,7 +1326,8 @@ impl App {
}

fn expand_widget(&mut self) {
if !self.is_in_dialog() && !self.app_config_fields.use_basic_mode {
// TODO: [BASIC] Expansion in basic mode.
if !self.ignore_normal_keybinds() && !self.app_config_fields.use_basic_mode {
// Pop-out mode. We ignore if in process search.

match self.current_widget.widget_type {
Expand Down Expand Up @@ -1300,7 +1359,7 @@ impl App {
- Reflection direction.
*/

if !self.is_in_dialog() && !self.is_expanded {
if !self.ignore_normal_keybinds() && !self.is_expanded {
if let Some(new_widget_id) = &(match direction {
WidgetDirection::Left => self.current_widget.left_neighbour,
WidgetDirection::Right => self.current_widget.right_neighbour,
Expand Down Expand Up @@ -1731,7 +1790,7 @@ impl App {
}

pub fn skip_to_first(&mut self) {
if !self.is_in_dialog() {
if !self.ignore_normal_keybinds() {
match self.current_widget.widget_type {
BottomWidgetType::Proc => {
if let Some(proc_widget_state) = self
Expand Down Expand Up @@ -1782,13 +1841,14 @@ impl App {
_ => {}
}
self.reset_multi_tap_keys();
} else {
} else if self.is_config_open {
} else if self.help_dialog_state.is_showing_help {
self.help_dialog_state.scroll_state.current_scroll_index = 0;
}
}

pub fn skip_to_last(&mut self) {
if !self.is_in_dialog() {
if !self.ignore_normal_keybinds() {
match self.current_widget.widget_type {
BottomWidgetType::Proc => {
if let Some(proc_widget_state) = self
Expand Down Expand Up @@ -1858,7 +1918,8 @@ impl App {
_ => {}
}
self.reset_multi_tap_keys();
} else {
} else if self.is_config_open {
} else if self.help_dialog_state.is_showing_help {
self.help_dialog_state.scroll_state.current_scroll_index = self
.help_dialog_state
.scroll_state
Expand All @@ -1868,7 +1929,7 @@ impl App {
}

pub fn decrement_position_count(&mut self) {
if !self.is_in_dialog() {
if !self.ignore_normal_keybinds() {
match self.current_widget.widget_type {
BottomWidgetType::Proc => self.increment_process_position(-1),
BottomWidgetType::ProcSort => self.increment_process_sort_position(-1),
Expand All @@ -1881,7 +1942,7 @@ impl App {
}

pub fn increment_position_count(&mut self) {
if !self.is_in_dialog() {
if !self.ignore_normal_keybinds() {
match self.current_widget.widget_type {
BottomWidgetType::Proc => self.increment_process_position(1),
BottomWidgetType::ProcSort => self.increment_process_sort_position(1),
Expand Down
6 changes: 5 additions & 1 deletion src/app/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@ impl ProcessQuery for ProcWidgetState {
let initial_or = Or {
lhs: And {
lhs: Prefix {
or: Some(Box::new(list_of_ors.pop_front().unwrap())),
or: if let Some(or) = list_of_ors.pop_front() {
Some(Box::new(or))
} else {
None
},
compare_prefix: None,
regex_prefix: None,
},
Expand Down
Loading

0 comments on commit 6db7602

Please sign in to comment.