Skip to content

Commit

Permalink
feature: add nord and nord-light colours (#406)
Browse files Browse the repository at this point in the history
Adds colour schemes for Nord, along with a light variant.
  • Loading branch information
ClementTsang authored Feb 15, 2021
1 parent f2e6b92 commit fb7b122
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 149 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Features

- [#263](https://github.com/ClementTsang/bottom/pull/263): Adds the option for fine-grained kill signals on Unix-like systems.

- [#333](https://github.com/ClementTsang/bottom/pull/333): Adds an "out of" indicator that can be enabled using `--show_table_scroll_position` (and its corresponding config option) to help keep track of scrolled position.

- [#379](https://github.com/ClementTsang/bottom/pull/379): Adds `--process_command` flag and corresponding config option to default to showing a process' command.

- [#381](https://github.com/ClementTsang/bottom/pull/381): Adds a filter in the config file for network interfaces.

## [0.5.8] - Unreleased
- [#406](https://github.com/ClementTsang/bottom/pull/406): Adds the Nord colour scheme, as well as a light variant.

## Changes

Expand Down
50 changes: 25 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -563,31 +563,31 @@ The following options can be set under `[flags]` to achieve the same effect as p

These are the following supported flag config values, which correspond to the flag of the same name described in [Flags](#flags):

| Field | Type | Functionality |
| ---------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `hide_avg_cpu` | Boolean | Hides the average CPU usage. |
| `dot_marker` | Boolean | Uses a dot marker for graphs. |
| `left_legend` | Boolean | Puts the CPU chart legend to the left side. |
| `current_usage` | Boolean | Sets process CPU% to be based on current CPU%. |
| `group_processes` | Boolean | Groups processes with the same name by default. |
| `case_sensitive` | Boolean | Enables case sensitivity by default. |
| `whole_word` | Boolean | Enables whole-word matching by default. |
| `regex` | Boolean | Enables regex by default. |
| `basic` | Boolean | Hides graphs and uses a more basic look. |
| `use_old_network_legend` | Boolean | DEPRECATED - uses the older network legend. |
| `battery` | Boolean | Shows the battery widget. |
| `rate` | Unsigned Int (represents milliseconds) | Sets a refresh rate in ms. |
| `default_time_value` | Unsigned Int (represents milliseconds) | Default time value for graphs in ms. |
| `time_delta` | Unsigned Int (represents milliseconds) | The amount in ms changed upon zooming. |
| `temperature_type` | String (one of ["k", "f", "c", "kelvin", "fahrenheit", "celsius"]) | Sets the temperature unit type. |
| `default_widget_type` | String (one of ["cpu", "proc", "net", "temp", "mem", "disk"], same as layout options) | Sets the default widget type, use --help for more info. |
| `default_widget_count` | Unsigned Int (represents which `default_widget_type`) | Sets the n'th selected widget type as the default. |
| `disable_click` | Boolean | Disables mouse clicks. |
| `color` | String (one of ["default", "default-light", "gruvbox", "gruvbox-light"]) | Use a color scheme, use --help for supported values. |
| `mem_as_value` | Boolean | Defaults to showing process memory usage by value. |
| `tree` | Boolean | Defaults to showing the process widget in tree mode. |
| `show_table_scroll_position` | Boolean | Shows the scroll position tracker in table widgets. |
| `process_command` | Boolean | Show processes as their commands by default. |
| Field | Type | Functionality |
| ---------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `hide_avg_cpu` | Boolean | Hides the average CPU usage. |
| `dot_marker` | Boolean | Uses a dot marker for graphs. |
| `left_legend` | Boolean | Puts the CPU chart legend to the left side. |
| `current_usage` | Boolean | Sets process CPU% to be based on current CPU%. |
| `group_processes` | Boolean | Groups processes with the same name by default. |
| `case_sensitive` | Boolean | Enables case sensitivity by default. |
| `whole_word` | Boolean | Enables whole-word matching by default. |
| `regex` | Boolean | Enables regex by default. |
| `basic` | Boolean | Hides graphs and uses a more basic look. |
| `use_old_network_legend` | Boolean | DEPRECATED - uses the older network legend. |
| `battery` | Boolean | Shows the battery widget. |
| `rate` | Unsigned Int (represents milliseconds) | Sets a refresh rate in ms. |
| `default_time_value` | Unsigned Int (represents milliseconds) | Default time value for graphs in ms. |
| `time_delta` | Unsigned Int (represents milliseconds) | The amount in ms changed upon zooming. |
| `temperature_type` | String (one of ["k", "f", "c", "kelvin", "fahrenheit", "celsius"]) | Sets the temperature unit type. |
| `default_widget_type` | String (one of ["cpu", "proc", "net", "temp", "mem", "disk"], same as layout options) | Sets the default widget type, use --help for more info. |
| `default_widget_count` | Unsigned Int (represents which `default_widget_type`) | Sets the n'th selected widget type as the default. |
| `disable_click` | Boolean | Disables mouse clicks. |
| `color` | String (one of ["default", "default-light", "gruvbox", "gruvbox-light", "nord", "nord-light"]) | Use a color scheme, use --help for supported values. |
| `mem_as_value` | Boolean | Defaults to showing process memory usage by value. |
| `tree` | Boolean | Defaults to showing the process widget in tree mode. |
| `show_table_scroll_position` | Boolean | Shows the scroll position tracker in table widgets. |
| `process_command` | Boolean | Show processes as their commands by default. |

#### Theming

Expand Down
48 changes: 24 additions & 24 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ impl App {
);
}

self.did_config_fail_to_save = self.update_config_file().is_err();
// self.did_config_fail_to_save = self.update_config_file().is_err();
}
}

Expand Down Expand Up @@ -586,7 +586,7 @@ impl App {
);
}

self.did_config_fail_to_save = self.update_config_file().is_err();
// self.did_config_fail_to_save = self.update_config_file().is_err();
}
}

Expand Down Expand Up @@ -642,7 +642,7 @@ impl App {
);
}

self.did_config_fail_to_save = self.update_config_file().is_err();
// self.did_config_fail_to_save = self.update_config_file().is_err();
}
}

Expand Down Expand Up @@ -1565,28 +1565,28 @@ impl App {
self.is_force_redraw = true;
}

/// TODO: Disabled.
/// Call this whenever the config value is updated!
fn update_config_file(&mut self) -> anyhow::Result<()> {
// TODO: Disabled.
// if self.app_config_fields.no_write {
// // debug!("No write enabled. Config will not be written.");
// // 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
// // debug!("Updating config file - writing to: {:?}", config_path);
// std::fs::File::create(config_path)?
// .write_all(self.config.get_config_as_bytes()?.as_ref())?;
// Ok(())
// } else {
// // FIXME: [CONFIG] Put an actual error message?
// Err(anyhow::anyhow!(
// "Config path was missing, please try restarting bottom..."
// ))
// }
Ok(())
}
// fn update_config_file(&mut self) -> anyhow::Result<()> {
// if self.app_config_fields.no_write {
// // debug!("No write enabled. Config will not be written.");
// // 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
// // debug!("Updating config file - writing to: {:?}", config_path);
// std::fs::File::create(config_path)?
// .write_all(self.config.get_config_as_bytes()?.as_ref())?;
// Ok(())
// } else {
// // FIXME: [CONFIG] Put an actual error message?
// Err(anyhow::anyhow!(
// "Config path was missing, please try restarting bottom..."
// ))
// }
// Ok(())
// }

pub fn kill_highlighted_process(&mut self) -> Result<()> {
if let BottomWidgetType::Proc = self.current_widget.widget_type {
Expand Down
22 changes: 13 additions & 9 deletions src/app/layout_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,24 @@ pub struct BottomLayout {
pub total_row_height_ratio: u32,
}

type WidgetMappings = (u32, BTreeMap<(u32, u32), u64>);
type ColumnRowMappings = (u32, BTreeMap<(u32, u32), WidgetMappings>);
type ColumnMappings = (u32, BTreeMap<(u32, u32), ColumnRowMappings>);
// Represents a start and end coordinate in some dimension.
type LineSegment = (u32, u32);

type WidgetMappings = (u32, BTreeMap<LineSegment, u64>);
type ColumnRowMappings = (u32, BTreeMap<LineSegment, WidgetMappings>);
type ColumnMappings = (u32, BTreeMap<LineSegment, ColumnRowMappings>);

impl BottomLayout {
pub fn get_movement_mappings(&mut self) {
fn is_intersecting(a: (u32, u32), b: (u32, u32)) -> bool {
#[allow(clippy::suspicious_operation_groupings)] // Have to enable this, clippy really doesn't like me doing this with tuples...
fn is_intersecting(a: LineSegment, b: LineSegment) -> bool {
a.0 >= b.0 && a.1 <= b.1
|| a.1 >= b.1 && a.0 <= b.0
|| a.0 <= b.0 && a.1 >= b.0
|| a.0 >= b.0 && a.0 < b.1 && a.1 >= b.1
}

fn get_distance(target: (u32, u32), candidate: (u32, u32)) -> u32 {
fn get_distance(target: LineSegment, candidate: LineSegment) -> u32 {
if candidate.0 < target.0 {
candidate.1 - target.0
} else if candidate.1 < target.1 {
Expand All @@ -38,20 +42,20 @@ impl BottomLayout {
// Now we need to create the correct mapping for moving from a specific
// widget to another

let mut layout_mapping: BTreeMap<(u32, u32), ColumnMappings> = BTreeMap::new();
let mut layout_mapping: BTreeMap<LineSegment, ColumnMappings> = BTreeMap::new();
let mut total_height = 0;
for row in &self.rows {
let mut row_width = 0;
let mut row_mapping: BTreeMap<(u32, u32), ColumnRowMappings> = BTreeMap::new();
let mut row_mapping: BTreeMap<LineSegment, ColumnRowMappings> = BTreeMap::new();
let mut is_valid_row = false;
for col in &row.children {
let mut col_row_height = 0;
let mut col_mapping: BTreeMap<(u32, u32), WidgetMappings> = BTreeMap::new();
let mut col_mapping: BTreeMap<LineSegment, WidgetMappings> = BTreeMap::new();
let mut is_valid_col = false;

for col_row in &col.children {
let mut widget_width = 0;
let mut col_row_mapping: BTreeMap<(u32, u32), u64> = BTreeMap::new();
let mut col_row_mapping: BTreeMap<LineSegment, u64> = BTreeMap::new();
let mut is_valid_col_row = false;
for widget in &col_row.children {
match widget.widget_type {
Expand Down
6 changes: 5 additions & 1 deletion src/app/process_killer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ impl Process {
}

fn kill(self) -> Result<(), String> {
unsafe { TerminateProcess(self.0, 1) };
let result = unsafe { TerminateProcess(self.0, 1) };
if result == 0 {
return Err("Failed to kill process".to_string());
}

Ok(())
}
}
Expand Down
51 changes: 25 additions & 26 deletions src/app/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,34 +625,33 @@ impl Prefix {
is_ignoring_case,
is_searching_with_regex,
);
} else if let Some((prefix_type, query_content)) = &mut self.regex_prefix {
if let StringQuery::Value(regex_string) = query_content {
match prefix_type {
PrefixType::Pid | PrefixType::Name | PrefixType::State => {
let escaped_regex: String;
let final_regex_string = &format!(
"{}{}{}{}",
if is_searching_whole_word { "^" } else { "" },
if is_ignoring_case { "(?i)" } else { "" },
if !is_searching_with_regex {
escaped_regex = regex::escape(regex_string);
&escaped_regex
} else {
regex_string
},
if is_searching_whole_word { "$" } else { "" },
);

let taken_pwc = self.regex_prefix.take();
if let Some((taken_pt, _)) = taken_pwc {
self.regex_prefix = Some((
taken_pt,
StringQuery::Regex(regex::Regex::new(final_regex_string)?),
));
}
} else if let Some((prefix_type, StringQuery::Value(regex_string))) = &mut self.regex_prefix
{
match prefix_type {
PrefixType::Pid | PrefixType::Name | PrefixType::State => {
let escaped_regex: String;
let final_regex_string = &format!(
"{}{}{}{}",
if is_searching_whole_word { "^" } else { "" },
if is_ignoring_case { "(?i)" } else { "" },
if !is_searching_with_regex {
escaped_regex = regex::escape(regex_string);
&escaped_regex
} else {
regex_string
},
if is_searching_whole_word { "$" } else { "" },
);

let taken_pwc = self.regex_prefix.take();
if let Some((taken_pt, _)) = taken_pwc {
self.regex_prefix = Some((
taken_pt,
StringQuery::Regex(regex::Regex::new(final_regex_string)?),
));
}
_ => {}
}
_ => {}
}
}

Expand Down
Loading

0 comments on commit fb7b122

Please sign in to comment.