diff --git a/.vscode/settings.json b/.vscode/settings.json index eb755c66..1f96e429 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -41,6 +41,7 @@ "whitespaces", "winapi", "winnt", - "xzvf" + "xzvf", + "ytop" ] } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index b326bef7..80715eed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed to just support stable (and newer) Rust, due to library incompatibilities. +- For macOS, support `$HOME/Library/Application Support` instead of `$HOME/.config` for config files. For + backwards compatibility's sake, for macOS, this will still check `.config` if it exists first, + but otherwise, it will default to the new location. + ### Bug Fixes ## [0.4.5] - 2020-07-08 diff --git a/README.md b/README.md index cd827087..7797f8d0 100644 --- a/README.md +++ b/README.md @@ -377,7 +377,14 @@ Note custom layouts are currently not available when this is used. ### Config files -bottom supports reading from a config file to customize its behaviour and look. By default, bottom will look at `~/.config/bottom/bottom.toml` or `C:\Users\\AppData\Roaming\bottom\bottom.toml` on Unix and Windows systems respectively. +bottom supports reading from a config file to customize its behaviour and look. +By default, bottom will look at (based on [dirs](https://github.com/dirs-dev/dirs-rs#features)): + +| OS | Location | +| ----------------------------------------------------------------------- | -------- | +| `~/.config/bottom/bottom.toml` or `$XDG_CONFIG_HOME/bottom/bottom.toml` | Linux | +| `$HOME/Library/Application Support/bottom/bottom.toml` | macOS | +| `C:\Users\\AppData\Roaming\bottom\bottom.toml` | Windows | Note that if a config file does not exist at either the default location or the passed in location via `-C` or `--config`, one is automatically created with no settings applied. @@ -386,27 +393,28 @@ Note that if a config file does not exist at either the default location or the The following options can be set under `[flags]` to achieve the same effect as passing in a flag on runtime. Note that if a flag is given, it will override the config file. These are the following supported flag config values: -| Field | Type | -|------------------------|---------------------------------------------------------------------------------------| -| `hide_avg_cpu` | Boolean | -| `dot_marker` | Boolean | -| `left_legend` | Boolean | -| `current_usage` | Boolean | -| `group_processes` | Boolean | -| `case_sensitive` | Boolean | -| `whole_word` | Boolean | -| `regex` | Boolean | -| `show_disabled_data` | Boolean | -| `basic` | Boolean | -| `hide_table_count`| Boolean | -| `use_old_network_legend`| Boolean | -| `battery` | Boolean | -| `rate` | Unsigned Int (represents milliseconds) | -| `default_time_value` | Unsigned Int (represents milliseconds) | -| `time_delta` | Unsigned Int (represents milliseconds) | -| `temperature_type` | String (one of ["k", "f", "c", "kelvin", "fahrenheit", "celsius"]) | -| `default_widget_type` | String (one of ["cpu", "proc", "net", "temp", "mem", "disk"], same as layout options) | -| `default_widget_count` | Unsigned Int (represents which `default_widget_type`) | + +| Field | Type | +| ------------------------ | ------------------------------------------------------------------------------------- | +| `hide_avg_cpu` | Boolean | +| `dot_marker` | Boolean | +| `left_legend` | Boolean | +| `current_usage` | Boolean | +| `group_processes` | Boolean | +| `case_sensitive` | Boolean | +| `whole_word` | Boolean | +| `regex` | Boolean | +| `show_disabled_data` | Boolean | +| `basic` | Boolean | +| `hide_table_count` | Boolean | +| `use_old_network_legend` | Boolean | +| `battery` | Boolean | +| `rate` | Unsigned Int (represents milliseconds) | +| `default_time_value` | Unsigned Int (represents milliseconds) | +| `time_delta` | Unsigned Int (represents milliseconds) | +| `temperature_type` | String (one of ["k", "f", "c", "kelvin", "fahrenheit", "celsius"]) | +| `default_widget_type` | String (one of ["cpu", "proc", "net", "temp", "mem", "disk"], same as layout options) | +| `default_widget_count` | Unsigned Int (represents which `default_widget_type`) | #### Theming @@ -470,16 +478,17 @@ represents either a _column or a widget_. A column can have any number of `child represents a _widget_. A widget is represented by having a `type` field set to a string. The following `type` values are supported: -| | | -|---------|--------------------------| -| `"cpu"` | CPU chart and legend | -| `"mem", "memory"` | Memory chart | -| `"net", "network"` | Network chart and legend | + +| | | +| -------------------------------- | ------------------------ | +| `"cpu"` | CPU chart and legend | +| `"mem", "memory"` | Memory chart | +| `"net", "network"` | Network chart and legend | | `"proc", "process", "processes"` | Process table and search | -| `"temp", "temperature"` | Temperature table | -| `"disk"` | Disk table | -| `"empty"` | An empty space | -| `"batt", "battery"` | Battery statistics | +| `"temp", "temperature"` | Temperature table | +| `"disk"` | Disk table | +| `"empty"` | An empty space | +| `"batt", "battery"` | Battery statistics | Each component of the layout accepts a `ratio` value. If this is not set, it defaults to 1. @@ -564,7 +573,8 @@ Thanks to all contributors ([emoji key](https://allcontributors.org/docs/en/emoj ## Thanks - This project is very much inspired by both - [gotop](https://github.com/cjbassi/gotop) and [gtop](https://github.com/aksakalli/gtop). + [gotop](https://github.com/cjbassi/gotop), its successor + [ytop](https://github.com/cjbassi/ytop), and [gtop](https://github.com/aksakalli/gtop). - Basic mode is heavily inspired by [htop's](https://hisham.hm/htop/) design. diff --git a/src/constants.rs b/src/constants.rs index 26f97381..dcc1a93a 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -164,8 +164,7 @@ lazy_static! { } // Config and flags -pub const DEFAULT_UNIX_CONFIG_FILE_PATH: &str = ".config/bottom/bottom.toml"; -pub const DEFAULT_WINDOWS_CONFIG_FILE_PATH: &str = "bottom/bottom.toml"; +pub const DEFAULT_CONFIG_FILE_PATH: &str = "bottom/bottom.toml"; // Default config file pub const DEFAULT_CONFIG_CONTENT: &str = r##" diff --git a/src/main.rs b/src/main.rs index e8721bf0..29c7630e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -354,34 +354,50 @@ fn handle_key_event_or_break( fn create_config(flag_config_location: Option<&str>) -> error::Result { use std::{ffi::OsString, fs}; let config_path = if let Some(conf_loc) = flag_config_location { - OsString::from(conf_loc) + Some(OsString::from(conf_loc)) } else if cfg!(target_os = "windows") { if let Some(home_path) = dirs::config_dir() { let mut path = home_path; - path.push(DEFAULT_WINDOWS_CONFIG_FILE_PATH); - path.into_os_string() + path.push(DEFAULT_CONFIG_FILE_PATH); + Some(path.into_os_string()) } else { - OsString::new() + None } } else if let Some(home_path) = dirs::home_dir() { let mut path = home_path; - // TODO: This should not be done like this IMO... it should be based on the defaults set by dirs rather than home_dir - // This WILL cause breaking changes on macOS though, warning! - path.push(DEFAULT_UNIX_CONFIG_FILE_PATH); - path.into_os_string() + path.push(".config/"); + path.push(DEFAULT_CONFIG_FILE_PATH); + if path.exists() { + // If it already exists, use the old one. + Some(path.into_os_string()) + } else { + // If it does not, use the new one! + if let Some(config_path) = dirs::config_dir() { + let mut path = config_path; + path.push(DEFAULT_CONFIG_FILE_PATH); + Some(path.into_os_string()) + } else { + None + } + } } else { - OsString::new() + None }; - let path = std::path::Path::new(&config_path); + if let Some(config_path) = config_path { + let path = std::path::Path::new(&config_path); - if let Ok(config_string) = fs::read_to_string(path) { - Ok(toml::from_str(config_string.as_str())?) - } else { - if let Some(parent_path) = path.parent() { - fs::create_dir_all(parent_path)?; + if let Ok(config_string) = fs::read_to_string(path) { + Ok(toml::from_str(config_string.as_str())?) + } else { + if let Some(parent_path) = path.parent() { + fs::create_dir_all(parent_path)?; + } + fs::File::create(path)?.write_all(DEFAULT_CONFIG_CONTENT.as_bytes())?; + Ok(toml::from_str(DEFAULT_CONFIG_CONTENT)?) } - fs::File::create(path)?.write_all(DEFAULT_CONFIG_CONTENT.as_bytes())?; + } else { + // Don't write otherwise... Ok(toml::from_str(DEFAULT_CONFIG_CONTENT)?) } }