diff --git a/README.md b/README.md index 231cc43..d3afe78 100644 --- a/README.md +++ b/README.md @@ -1296,7 +1296,7 @@ Config and log files stored in `$XDG_CONFIG_HOME/btop` or `$HOME/.config/btop` f #### btop.conf: (auto generated if not found) ```bash -#? Config file for btop v. 1.2.2 +#? Config file for btop v.1.4.5 #* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes. #* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes" @@ -1325,6 +1325,9 @@ vim_keys = False #* Rounded corners on boxes, is ignored if TTY mode is ON. rounded_corners = True +#* Use terminal synchronized output sequences to reduce flickering on supported terminals. +terminal_sync = True + #* Default symbols to use for graph creation, "braille", "block" or "tty". #* "braille" offers the highest resolution but might not be included in all fonts. #* "block" has half the resolution of braille but uses more common characters. @@ -1345,10 +1348,10 @@ graph_symbol_net = "default" graph_symbol_proc = "default" #* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace. -shown_boxes = "proc cpu mem net" +shown_boxes = "cpu mem net proc" #* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs. -update_ms = 1500 +update_ms = 2000 #* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu direct", #* "cpu lazy" sorts top process over time (easier to follow), "cpu direct" updates top process directly. @@ -1367,13 +1370,13 @@ proc_colors = True proc_gradient = True #* If process cpu usage should be of the core it's running on or usage of the total available cpu power. -proc_per_core = True +proc_per_core = False #* Show process memory as bytes instead of percent. proc_mem_bytes = True -#* Choose to preserve last cpu and memory usage of dead processes for when paused. -keep_dead_proc_usage = False +#* Show cpu graph for each process. +proc_cpu_graphs = True #* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate) proc_info_smaps = False @@ -1381,13 +1384,22 @@ proc_info_smaps = False #* Show proc box on left side of screen instead of right. proc_left = False +#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop). +proc_filter_kernel = False + +#* In tree-view, always accumulate child process resources in the parent process. +proc_aggregate = False + +#* Should cpu and memory usage display be preserved for dead processes when paused. +keep_dead_proc_usage = False + #* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available. #* Select from a list of detected attributes from the options menu. -cpu_graph_upper = "total" +cpu_graph_upper = "Auto" #* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available. #* Select from a list of detected attributes from the options menu. -cpu_graph_lower = "total" +cpu_graph_lower = "Auto" #* Toggles if the lower CPU graph should be inverted. cpu_invert_lower = True @@ -1433,7 +1445,7 @@ freq_mode = "first" #* Draw a clock at top of screen, formatting according to strftime, empty string to disable. #* Special formatting: /host = hostname | /user = username | /uptime = system uptime -clock_format = "%H:%M" +clock_format = "%X" #* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort. background_update = True @@ -1442,8 +1454,8 @@ background_update = True custom_cpu_name = "" #* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ". -#* Begin line with "exclude=" to change to exclude filter, otherwise defaults to "most include" filter. Example: disks_filter="exclude=/boot /home/user". -disks_filter = "exclude=/boot" +#* Only disks matching the filter will be shown. Prepend exclude= to only show disks not matching the filter. Examples: disk_filter="/boot /home/user", disks_filter="exclude=/boot /home/user" +disks_filter = "" #* Show graphs instead of meters for memory values. mem_graphs = True @@ -1467,7 +1479,10 @@ show_disks = True only_physical = True #* Read disks list from /etc/fstab. This also disables only_physical. -use_fstab = False +use_fstab = True + +#* Setting this to True will hide all datasets, and only show ZFS pools. (IO stats will be calculated per-pool) +zfs_hide_datasets = False #* Set to true to show available disk space for privileged users. disk_free_priv = False @@ -1494,10 +1509,13 @@ net_upload = 100 net_auto = True #* Sync the auto scaling for download and upload to whichever currently has the highest scale. -net_sync = False +net_sync = True #* Starts with the Network Interface specified here. -net_iface = "br0" +net_iface = "" + +#* "True" shows bitrates in base 10 (Kbps, Mbps). "False" shows bitrates in binary sizes (Kibps, Mibps, etc.). "Auto" uses base_10_sizes. +base_10_bitrate = "Auto" #* Show battery stats in top right if battery is present. show_battery = True @@ -1505,9 +1523,13 @@ show_battery = True #* Which battery to use if multiple are present. "Auto" for auto detection. selected_battery = "Auto" +#* Show power stats of battery next to charge indicator. +show_battery_watts = True + #* Set loglevel for "~/.config/btop/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG". #* The level set includes all lower levels, i.e. "DEBUG" will show all logging info. -log_level = "DEBUG" +log_level = "WARNING" + ``` #### Command line options @@ -1525,6 +1547,7 @@ Options: -t, --tty Force tty mode with ANSI graph symbols and 16 colors only --no-tty Force disable tty mode -u, --update Set an initial update rate in milliseconds + --default-config Print default config to standard output -h, --help Show this help message and exit -V, --version Show a version message and exit (more with --version) ``` diff --git a/manpage.md b/manpage.md index 0e35ec7..56a3bd2 100644 --- a/manpage.md +++ b/manpage.md @@ -10,7 +10,7 @@ btop - Resource monitor that shows usage and stats for processor, memory, disks, **btop** [**-c**] [**-d**] [**-l**] [**-t**] [**-p** _id_] [**-u** _ms_] [**\-\-force-utf**] [**\-\-themes-dir** _dir_] -**btop** [{**-h** | **\-\-help**} | {**-V** | **\-\-version**}] +**btop** [**\-\-default-config** | {**-h** | **\-\-help**} | {**-V** | **\-\-version**}] # DESCRIPTION @@ -51,6 +51,9 @@ starting with two dashes ('-'). A summary of options is included below. **-u**, **\-\-update _ms_** : Set an initial update rate in milliseconds. +**\-\-default-config** +: Print default config to standard output. + **-h**, **\-\-help** : Show summary of options. diff --git a/src/btop_cli.cpp b/src/btop_cli.cpp index 4612675..a5f7f7c 100644 --- a/src/btop_cli.cpp +++ b/src/btop_cli.cpp @@ -5,15 +5,20 @@ #include #include #include +#include #include +#include #include #include #include #include +#include + #include #include +#include "btop_config.hpp" #include "btop_shared.hpp" #include "config.h" @@ -22,6 +27,9 @@ using namespace std::string_view_literals; static constexpr auto BOLD = "\033[1m"sv; static constexpr auto BOLD_UNDERLINE = "\033[1;4m"sv; static constexpr auto BOLD_RED = "\033[1;31m"sv; +static constexpr auto BOLD_GREEN = "\033[1;32m"sv; +static constexpr auto BOLD_YELLOW = "\033[1;33m"sv; +static constexpr auto BOLD_BRIGHT_BLACK = "\033[1;90m"sv; static constexpr auto YELLOW = "\033[33m"sv; static constexpr auto RESET = "\033[0m"sv; @@ -49,6 +57,9 @@ namespace Cli { for (auto it = args.begin(); it != args.end(); ++it) { auto arg = *it; + if (arg == "--default-config") { + return default_config(); + } if (arg == "-h" || arg == "--help") { usage(); help(); @@ -187,6 +198,50 @@ namespace Cli { return cli; } + auto default_config() noexcept -> Result { + // The idea of using `current_config` is that the CLI parser is run before loading the actual config and thus + // provides default values. + auto config = Config::current_config(); + + if (isatty(STDOUT_FILENO)) { + std::string buffer {}; + // The config buffer ends in `\n`. `std::views::split` will then create an empty element after the last + // newline, which we would write as an additional empty line at the very end. + auto trimmed_config = config.substr(0, config.length() - 1); + for (const auto line : std::views::split(trimmed_config, '\n')) { + auto line_view = std::string_view { line }; + if (line_view.starts_with("#")) { + fmt::format_to( + std::back_inserter(buffer), "{1}{0}{2}\n", line_view, BOLD_BRIGHT_BLACK, RESET + ); + } else if (!line_view.empty()) { + auto pos = line_view.find("="); + if (pos == line_view.npos) { + error("invalid default config: '=' not found"); + return std::unexpected { 1 }; + } + auto name = line_view.substr(0, pos); + auto value = line_view.substr(pos + 1); + fmt::format_to( + std::back_inserter(buffer), + "{2}{0}{4}={3}{1}{4}\n", + name, + value, + BOLD_YELLOW, + BOLD_GREEN, + RESET + ); + } else { + fmt::format_to(std::back_inserter(buffer), "\n"); + } + } + fmt::print("{}", buffer); + } else { + fmt::print("{}", config); + } + return std::unexpected { 0 }; + } + void usage() noexcept { fmt::println("{0}Usage:{1} {2}btop{1} [OPTIONS]\n", BOLD_UNDERLINE, RESET, BOLD); } @@ -204,6 +259,7 @@ namespace Cli { " {2} --themes-dir{1} Path to a custom themes directory\n" " {2} --no-tty{1} Force disable tty mode\n" " {2}-u, --update{1} Set an initial update rate in milliseconds\n" + " {2} --default-config{1} Print default config to standard output\n" " {2}-h, --help{1} Show this help message and exit\n" " {2}-V, --version{1} Show a version message and exit (more with --version)\n", BOLD_UNDERLINE, RESET, BOLD diff --git a/src/btop_cli.hpp b/src/btop_cli.hpp index 92d4fb9..69e1f9d 100644 --- a/src/btop_cli.hpp +++ b/src/btop_cli.hpp @@ -39,6 +39,9 @@ namespace Cli { // Parse the command line arguments [[nodiscard]] auto parse(std::span args) noexcept -> Result; + // Print default config to standard output + [[nodiscard]] auto default_config() noexcept -> Result; + // Print a usage header void usage() noexcept; diff --git a/src/btop_config.cpp b/src/btop_config.cpp index 1cdc009..17c093c 100644 --- a/src/btop_config.cpp +++ b/src/btop_config.cpp @@ -20,12 +20,14 @@ tab-size = 4 #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -782,20 +784,9 @@ namespace Config { Logger::debug("Writing new config file"); if (geteuid() != Global::real_uid and seteuid(Global::real_uid) != 0) return; std::ofstream cwrite(conf_file, std::ios::trunc); - cwrite.imbue(std::locale::classic()); + // TODO: Report error when stream is in a bad state. if (cwrite.good()) { - cwrite << "#? Config file for btop v. " << Global::Version << "\n"; - for (const auto& [name, description] : descriptions) { - cwrite << "\n" << (description.empty() ? "" : description + "\n") - << name << " = "; - if (strings.contains(name)) - cwrite << "\"" << strings.at(name) << "\""; - else if (ints.contains(name)) - cwrite << ints.at(name); - else if (bools.contains(name)) - cwrite << (bools.at(name) ? "True" : "False"); - cwrite << "\n"; - } + cwrite << current_config(); } } @@ -828,4 +819,29 @@ namespace Config { auto get_log_file() -> std::optional { return get_xdg_state_dir().transform([](auto&& state_home) -> auto { return state_home / "btop.log"; }); } + + auto current_config() -> std::string { + auto buffer = std::string {}; + fmt::format_to(std::back_inserter(buffer), "#? Config file for btop v.{}\n", Global::Version); + + for (const auto& [name, description] : descriptions) { + // Write a description comment if available. + fmt::format_to(std::back_inserter(buffer), "\n"); + if (!description.empty()) { + fmt::format_to(std::back_inserter(buffer), "{}\n", description); + } + + fmt::format_to(std::back_inserter(buffer), "{} = ", name); + // Lookup default value by name and write it out. + if (strings.contains(name)) { + fmt::format_to(std::back_inserter(buffer), R"("{}")", strings[name]); + } else if (ints.contains(name)) { + fmt::format_to(std::back_inserter(buffer), std::locale::classic(), "{:L}", ints[name]); + } else if (bools.contains(name)) { + fmt::format_to(std::back_inserter(buffer), "{}", bools[name] ? "True" : "False"); + } + fmt::format_to(std::back_inserter(buffer), "\n"); + } + return buffer; + } } diff --git a/src/btop_config.hpp b/src/btop_config.hpp index 4427762..1e0a8ad 100644 --- a/src/btop_config.hpp +++ b/src/btop_config.hpp @@ -132,4 +132,7 @@ namespace Config { void write(); auto get_log_file() -> std::optional; + + // Write default config to an in-memory buffer + [[nodiscard]] auto current_config() -> std::string; }