htop: replace individual option with 'settings' (#1844)

* htop: add some missing meters
* htop: replace individual options with 'settings'
Deprecate all options and introduce `settings` for setting htop configuration
values in Nix configuration.

Use `lib.htop` to provide `fields` and `modes` for easy access to htop's integer
configuration. And `leftMeters` and `rightMeters` functions for building the
separate `*_meters` and `*_meter_modes` attributes.

* htop: add release-notes 21.05 entry
* htop: improve deprecation warnings

Move default configuration into `settings` and make deprecated options default
to `null`. Print deprecation warnings for any option that is non-null --
i.e. only show warnings for explicitly specified deprecated options.

* htop: make self code owner of module
* release notes: fix invalid programs.htop xref
This commit is contained in:
Bart Bakker 2021-05-18 23:36:08 +00:00 committed by GitHub
parent ff616b2734
commit 91450f23ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 450 additions and 130 deletions

2
.github/CODEOWNERS vendored
View file

@ -78,6 +78,8 @@
/modules/programs/home-manager.nix @rycee /modules/programs/home-manager.nix @rycee
/modules/programs/htop.nix @bjpbakker
/modules/programs/i3status.nix @JustinLovinger /modules/programs/i3status.nix @JustinLovinger
/modules/programs/i3status-rust.nix @workflow /modules/programs/i3status-rust.nix @workflow

View file

@ -172,6 +172,24 @@ font = {
}; };
---- ----
* The <<opt-programs.htop.settings>> option is introduced to replace individual
options in `programs.htop`. To migrate, set the htop options directly in
<<opt-programs.htop.settings>>. For example:
+
[source,nix]
----
programs.htop = {
enabled = true;
settings = {
color_scheme = 5;
delay = 15;
highlight_base_name = 1;
highlight_megabytes = 1;
highlight_threads = 1;
};
};
----
[[sec-release-21.05-state-version-changes]] [[sec-release-21.05-state-version-changes]]
=== State Version Changes === State Version Changes

View file

@ -6,9 +6,16 @@ let
cfg = config.programs.htop; cfg = config.programs.htop;
list = xs: concatMapStrings (x: "${toString x} ") xs; formatOption = n: v:
let v' = if isBool v then (if v then "1" else "0") else toString v;
in "${n}=${v'}";
bool = b: if b then "1" else "0"; formatMeters = side: meters: {
"${side}_meters" = mapAttrsToList (x: _: x) meters;
"${side}_meter_modes" = mapAttrsToList (_: y: y) meters;
};
leftMeters = formatMeters "left";
rightMeters = formatMeters "right";
fields = { fields = {
PID = 0; PID = 0;
@ -66,13 +73,24 @@ let
M_PSSWP = 120; M_PSSWP = 120;
}; };
modes = {
Bar = 1;
Text = 2;
Graph = 3;
LED = 4;
};
# Mapping from names to defaults # Mapping from names to defaults
meters = { meters = {
Clock = 2; Clock = 2;
Date = 2;
DateTime = 2;
LoadAverage = 2; LoadAverage = 2;
Load = 2; Load = 2;
Memory = 1; Memory = 1;
Swap = 1; Swap = 1;
Zram = 2;
HugePages = 2;
Tasks = 2; Tasks = 2;
Uptime = 2; Uptime = 2;
Battery = 2; Battery = 2;
@ -80,6 +98,7 @@ let
AllCPUs = 1; AllCPUs = 1;
AllCPUs2 = 1; AllCPUs2 = 1;
AllCPUs4 = 1; AllCPUs4 = 1;
AllCPUs8 = 1;
LeftCPUs = 1; LeftCPUs = 1;
RightCPUs = 1; RightCPUs = 1;
Right = 1; Right = 1;
@ -88,6 +107,8 @@ let
RightCPUs2 = 1; RightCPUs2 = 1;
LeftCPUs4 = 1; LeftCPUs4 = 1;
RightCPUs4 = 1; RightCPUs4 = 1;
LeftCPUs8 = 1;
RightCPUs8 = 1;
Blank = 2; Blank = 2;
PressureStallCPUSome = 2; PressureStallCPUSome = 2;
PressureStallIOSome = 2; PressureStallIOSome = 2;
@ -105,6 +126,10 @@ let
"CPU(6)" = 1; "CPU(6)" = 1;
"CPU(7)" = 1; "CPU(7)" = 1;
"CPU(8)" = 1; "CPU(8)" = 1;
SELinux = 2;
Systemd = 2;
DiskIO = 2;
NetworkIO = 2;
}; };
singleMeterType = let singleMeterType = let
@ -166,22 +191,100 @@ in {
options.programs.htop = { options.programs.htop = {
enable = mkEnableOption "htop"; enable = mkEnableOption "htop";
settings = mkOption {
type = types.attrs;
default = {
account_guest_in_cpu_meter = false;
color_scheme = 0;
cpu_count_from_zero = false;
delay = 15;
detailed_cpu_time = false;
enable_mouse = true;
fields = with fields; [
PID
USER
PRIORITY
NICE
M_SIZE
M_RESIDENT
M_SHARE
STATE
PERCENT_CPU
PERCENT_MEM
TIME
COMM
];
header_margin = true;
hide_kernel_threads = true;
hide_threads = false;
hide_userland_threads = false;
highlight_base_name = false;
highlight_megabytes = true;
highlight_threads = true;
shadow_other_users = false;
show_cpu_frequency = false;
show_cpu_usage = false;
show_program_path = true;
show_thread_names = false;
sort_direction = 1;
sort_key = fields.PERCENT_CPU;
tree_view = false;
update_process_names = false;
vim_mode = false;
} // (leftMeters {
AllCPUs = modes.Bar;
Memory = modes.Bar;
Swap = modes.Bar;
}) // (rightMeters {
Tasks = modes.Text;
LoadAverage = modes.Text;
Uptime = modes.Text;
});
example = literalExample ''
{
color_scheme = 6;
cpu_count_from_one = 0;
delay = 15;
fields = with config.lib.htop.fields; [
PID
USER
PRIORITY
NICE
M_SIZE
M_RESIDENT
M_SHARE
STATE
PERCENT_CPU
PERCENT_MEM
TIME
COMM
];
highlight_base_name = 1;
highlight_megabytes = 1;
highlight_threads = 1;
} // (with config.lib.htop; leftMeters {
AllCPUs2 = modes.Bar;
Memory = modes.Bar;
Swap = modes.Bar;
Zram = modes.Text;
}) // (with config.lib.htop; rightMeters {
Tasks = modes.Text;
LoadAverage = modes.Text;
Uptime = modes.Text;
Systemd = modes.Text;
})
'';
description = ''
Configuration options to add to
<filename>~/.config/htop/htoprc</filename>.
This superseedes any other (deprecated) settings in this module.
'';
};
fields = mkOption { fields = mkOption {
type = types.listOf (types.enum (attrNames fields)); type = types.nullOr (types.listOf (types.enum (attrNames fields)));
default = [ default = null;
"PID"
"USER"
"PRIORITY"
"NICE"
"M_SIZE"
"M_RESIDENT"
"M_SHARE"
"STATE"
"PERCENT_CPU"
"PERCENT_MEM"
"TIME"
"COMM"
];
example = [ example = [
"PID" "PID"
"USER" "USER"
@ -192,151 +295,247 @@ in {
"TIME" "TIME"
"COMM" "COMM"
]; ];
description = "Active fields shown in the table."; description = ''
Deprecated. Please use programs.htop.settings.fields instead.
Active fields shown in the table.
'';
}; };
sortKey = mkOption { sortKey = mkOption {
type = types.enum (attrNames fields); type = types.nullOr (types.enum (attrNames fields));
default = "PERCENT_CPU"; default = null;
example = "TIME"; example = "TIME";
description = "Which field to use for sorting."; description = ''
Deprecated. Please use programs.htop.settings.sort_key instead.
Which field to use for sorting.
'';
}; };
sortDescending = mkOption { sortDescending = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = true; default = null;
description = "Whether to sort descending or not."; description = ''
Deprecated. Please use programs.htop.settings.sort_direction instead.
Whether to sort descending or not.
'';
}; };
hideThreads = mkOption { hideThreads = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Hide threads."; description = ''
Deprecated. Please use programs.htop.settings.hide_threads instead.
Hide threads.
'';
}; };
hideKernelThreads = mkOption { hideKernelThreads = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = true; default = null;
description = "Hide kernel threads."; description = ''
Deprecated. Please use programs.htop.settings.hide_kernel_threads instead.
Hide kernel threads.
'';
}; };
hideUserlandThreads = mkOption { hideUserlandThreads = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Hide userland process threads."; description = ''
Deprecated. Please use programs.htop.settings.hide_userland_threads instead.
Hide userland process threads.
'';
}; };
shadowOtherUsers = mkOption { shadowOtherUsers = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Shadow other users' processes."; description = ''
Deprecated. Please use programs.htop.settings.shadow_other_users instead.
Shadow other users' processes.
'';
}; };
showThreadNames = mkOption { showThreadNames = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Show custom thread names."; description = ''
Deprecated. Please use programs.htop.settings.show_thread_names instead.
Show custom thread names.
'';
}; };
showProgramPath = mkOption { showProgramPath = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = true; default = null;
description = "Show program path."; description = ''
Deprecated. Please use programs.htop.settings.show_program_path instead.
Show program path.
'';
}; };
highlightBaseName = mkOption { highlightBaseName = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Highlight program <quote>basename</quote>."; description = ''
Deprecated. Please use programs.htop.settings.highlight_base_name instead.
Highlight program <quote>basename</quote>.
'';
}; };
highlightMegabytes = mkOption { highlightMegabytes = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = true; default = null;
description = "Highlight large numbers in memory counters."; description = ''
Deprecated. Please use programs.htop.settings.highlight_megabytes instead.
Highlight large numbers in memory counters.
'';
}; };
highlightThreads = mkOption { highlightThreads = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = true; default = null;
description = "Display threads in a different color."; description = ''
Deprecated. Please use programs.htop.settings.highlight_threads instead.
Display threads in a different color.
'';
}; };
treeView = mkOption { treeView = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Tree view."; description = ''
Deprecated. Please use programs.htop.settings.tree_view instead.
Tree view.
'';
}; };
headerMargin = mkOption { headerMargin = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = true; default = null;
description = "Leave a margin around header."; description = ''
Deprecated. Please use programs.htop.settings.header_margin instead.
Leave a margin around header.
'';
}; };
detailedCpuTime = mkOption { detailedCpuTime = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = description = ''
"Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest)."; Deprecated. Please use programs.htop.settings.detailed_cpu_time instead.
Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest).
'';
}; };
cpuCountFromZero = mkOption { cpuCountFromZero = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Count CPUs from 0 instead of 1."; description = ''
Deprecated. Please use programs.htop.settings.cpu_count_from_zero instead.
Count CPUs from 0 instead of 1.
'';
}; };
showCpuUsage = mkOption { showCpuUsage = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Show CPU usage frequency."; description = ''
Deprecated. Please use programs.htop.settings.show_cpu_usage instead.
Show CPU usage frequency.
'';
}; };
showCpuFrequency = mkOption { showCpuFrequency = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Show CPU frequency."; description = ''
Deprecated. Please use programs.htop.settings.show_cpu_frequency instead.
Show CPU frequency.
'';
}; };
updateProcessNames = mkOption { updateProcessNames = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Update process names on every refresh."; description = ''
Deprecated. Please use programs.htop.settings.update_process_names instead.
Update process names on every refresh.
'';
}; };
accountGuestInCpuMeter = mkOption { accountGuestInCpuMeter = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Add guest time in CPU meter percentage."; description = ''
Deprecated. Please use programs.htop.settings.account_guest_in_cpu_meter instead.
Add guest time in CPU meter percentage.
'';
}; };
colorScheme = mkOption { colorScheme = mkOption {
type = types.enum [ 0 1 2 3 4 5 6 ]; type = types.nullOr (types.enum [ 0 1 2 3 4 5 6 ]);
default = 0; default = null;
example = 6; example = 6;
description = "Which color scheme to use."; description = ''
Deprecated. Please use programs.htop.settings.color_scheme instead.
Which color scheme to use.
'';
}; };
enableMouse = mkOption { enableMouse = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = true; default = null;
description = "Enable mouse support."; description = ''
Deprecated. Please use programs.htop.settings.enable_mouse instead.
Enable mouse support.
'';
}; };
delay = mkOption { delay = mkOption {
type = types.int; type = types.nullOr types.int;
default = 15; default = null;
example = 2; example = 2;
description = "Set the delay between updates, in tenths of seconds."; description = ''
Deprecated. Please use programs.htop.settings.delay instead.
Set the delay between updates, in tenths of seconds.
'';
}; };
meters = mkOption { meters = mkOption {
description = "Meters shown in the header."; description = ''
default = { Deprecated. Please use programs.htop.settings.left_meters,
left = [ "AllCPUs" "Memory" "Swap" ]; programs.htop.settings.left_meter_modes,
right = [ "Tasks" "LoadAverage" "Uptime" ]; programs.htop.settings.right_meters and
}; programs.htop.settings.right_meter_modes instead. Or consider using
lib.htop.leftMeters and lib.htop.rightMeters.
Meters shown in the header.
'';
default = null;
example = { example = {
left = [ left = [
"Memory" "Memory"
@ -362,55 +561,91 @@ in {
} }
]; ];
}; };
type = meterType; type = types.nullOr meterType;
}; };
vimMode = mkOption { vimMode = mkOption {
type = types.bool; type = types.nullOr types.bool;
default = false; default = null;
description = "Vim key bindings."; description = ''
Deprecated. Please use programs.htop.settings.vim_mode instead.
Vim key bindings.
'';
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
lib.htop = { inherit fields modes leftMeters rightMeters; };
home.packages = [ pkgs.htop ]; home.packages = [ pkgs.htop ];
xdg.configFile."htop/htoprc".text = let xdg.configFile."htop/htoprc".text = let
leftMeters = map (m: m.kind) cfg.meters.left;
leftModes = map (m: m.mode) cfg.meters.left; deprecate = settingsKey: optionKey: optionValue:
rightMeters = map (m: m.kind) cfg.meters.right; let
rightModes = map (m: m.mode) cfg.meters.right; warn' = warn
in '' "htop: programs.htop.${optionKey} is deprecated; please is programs.htop.settings.${settingsKey} instead";
# This file is regenerated by home-manager in if !isNull optionValue then
# when options are changed in the config warn' settingsKey optionKey optionValue
fields=${list (map (n: fields.${n}) cfg.fields)} else if hasAttr settingsKey cfg.settings then
sort_key=${toString (fields.${cfg.sortKey})} cfg.settings.${settingsKey}
sort_direction=${bool cfg.sortDescending} else
hide_threads=${bool cfg.hideThreads} null;
hide_kernel_threads=${bool cfg.hideKernelThreads}
hide_userland_threads=${bool cfg.hideUserlandThreads} deprecate' = settingsKey: optionKey:
shadow_other_users=${bool cfg.shadowOtherUsers} deprecate settingsKey optionKey cfg.${optionKey};
show_thread_names=${bool cfg.showThreadNames}
show_program_path=${bool cfg.showProgramPath} ifNonNull = x: y: if isNull x then null else y;
highlight_base_name=${bool cfg.highlightBaseName}
highlight_megabytes=${bool cfg.highlightMegabytes} leftMeters = deprecate "left_meters" "meters.left"
highlight_threads=${bool cfg.highlightThreads} (ifNonNull cfg.meters (map (m: m.kind) cfg.meters.left));
tree_view=${bool cfg.treeView} leftModes = deprecate "left_meter_modes" "meters.left"
header_margin=${bool cfg.headerMargin} (ifNonNull cfg.meters (map (m: m.mode) cfg.meters.left));
detailed_cpu_time=${bool cfg.detailedCpuTime} rightMeters = deprecate "right_meters" "meters.right"
cpu_count_from_zero=${bool cfg.cpuCountFromZero} (ifNonNull cfg.meters (map (m: m.kind) cfg.meters.right));
show_cpu_usage=${bool cfg.showCpuUsage} rightModes = deprecate "right_meter_modes" "meters.right"
show_cpu_frequency=${bool cfg.showCpuFrequency} (ifNonNull cfg.meters (map (m: m.mode) cfg.meters.right));
update_process_names=${bool cfg.updateProcessNames}
account_guest_in_cpu_meter=${bool cfg.accountGuestInCpuMeter} settings' = cfg.settings // (filterAttrs (_: v: !isNull v) {
color_scheme=${toString cfg.colorScheme} fields = deprecate "fields" "fields"
enable_mouse=${bool cfg.enableMouse} (ifNonNull cfg.fields (map (n: fields.${n}) cfg.fields));
delay=${toString cfg.delay} sort_key = deprecate "sort_key" "sortKey"
left_meters=${list leftMeters} (ifNonNull cfg.sortKey fields.${cfg.sortKey});
left_meter_modes=${list leftModes} sort_direction = deprecate' "sort_direction" "sortDescending";
right_meters=${list rightMeters} hide_threads = deprecate' "hide_threads" "hideThreads";
right_meter_modes=${list rightModes} hide_kernel_threads =
vim_mode=${bool cfg.vimMode} deprecate' "hide_kernel_threads" "hideKernelThreads";
''; hide_userland_threads =
deprecate' "hide_userland_threads" "hideUserlandThreads";
shadow_other_users = deprecate' "shadow_other_users" "shadowOtherUsers";
show_thread_names = deprecate' "show_thread_names" "showThreadNames";
show_program_path = deprecate' "show_program_path" "showProgramPath";
highlight_base_name =
deprecate' "highlight_base_name" "highlightBaseName";
highlight_megabytes =
deprecate' "highlight_megabytes" "highlightMegabytes";
highlight_threads = deprecate' "highlight_threads" "highlightThreads";
tree_view = deprecate' "tree_view" "treeView";
header_margin = deprecate' "header_margin" "headerMargin";
detailed_cpu_time = deprecate' "detailed_cpu_time" "detailedCpuTime";
cpu_count_from_zero =
deprecate' "cpu_count_from_zero" "cpuCountFromZero";
show_cpu_usage = deprecate' "show_cpu_usage" "showCpuUsage";
show_cpu_frequency = deprecate' "show_cpu_frequency" "showCpuFrequency";
update_process_names =
deprecate' "update_process_names" "updateProcessNames";
account_guest_in_cpu_meter =
deprecate' "account_guest_in_cpu_meter" "accountGuestInCpuMeter";
color_scheme = deprecate' "color_scheme" "colorScheme";
enable_mouse = deprecate' "enable_mouse" "enableMouse";
delay = deprecate' "delay" "delay";
left_meters = leftMeters;
left_meter_modes = leftModes;
right_meters = rightMeters;
right_meter_modes = rightModes;
vim_mode = deprecate' "vim_mode" "vimMode";
});
in concatStringsSep "\n" (mapAttrsToList formatOption settings');
}; };
} }

View file

@ -53,6 +53,7 @@ import nmt {
./modules/programs/gh ./modules/programs/gh
./modules/programs/git ./modules/programs/git
./modules/programs/gpg ./modules/programs/gpg
./modules/programs/htop
./modules/programs/i3status ./modules/programs/i3status
./modules/programs/kakoune ./modules/programs/kakoune
./modules/programs/kitty ./modules/programs/kitty

View file

@ -0,0 +1,13 @@
{ config, lib, pkgs, ... }:
with lib;
{
config = {
programs.htop.enable = true;
nmt.script = ''
assertFileExists home-files/.config/htop/htoprc
'';
};
}

View file

@ -0,0 +1,4 @@
{
htop-default-settings = ./default-settings.nix;
htop-example-settings = ./example-settings.nix;
}

View file

@ -0,0 +1,47 @@
{ config, lib, pkgs, ... }:
with lib;
{
config = {
programs.htop.enable = true;
programs.htop.settings = {
color_scheme = 6;
cpu_count_from_one = 0;
delay = 15;
fields = with config.lib.htop.fields; [
PID
USER
PRIORITY
NICE
M_SIZE
M_RESIDENT
M_SHARE
STATE
PERCENT_CPU
PERCENT_MEM
TIME
COMM
];
highlight_base_name = 1;
highlight_megabytes = 1;
highlight_threads = 1;
} // (with config.lib.htop;
leftMeters {
AllCPUs2 = modes.Bar;
Memory = modes.Bar;
Swap = modes.Bar;
Zram = modes.Text;
}) // (with config.lib.htop;
rightMeters {
Tasks = modes.Text;
LoadAverage = modes.Text;
Uptime = modes.Text;
Systemd = modes.Text;
});
nmt.script = ''
assertFileExists home-files/.config/htop/htoprc
'';
};
}