mirror of
https://github.com/nix-community/home-manager
synced 2024-11-27 05:29:46 +01:00
htop: support screens configuration
`htop` has changed the singular fields list to a configuration of multiple screens. Each screen has a name and its own set of fields to show, plus some options to control sorting and view style (tree or flat). Screen names can be shown with the `screen_tabs` setting. Fields in screens are set with their names (as strings) rather than numbers. Extend the htop module to allow configuring screens with a defined set of options. Order the screens with dag topology. Configurations without screens are converted automatically by `htop` on load. This feature was requested in #3616.
This commit is contained in:
parent
e83414058e
commit
6cdbb1ace7
4 changed files with 178 additions and 32 deletions
|
@ -76,21 +76,6 @@ let
|
||||||
M_PSSWP = 120;
|
M_PSSWP = 120;
|
||||||
};
|
};
|
||||||
|
|
||||||
defaultFields = with fields; [
|
|
||||||
PID
|
|
||||||
USER
|
|
||||||
PRIORITY
|
|
||||||
NICE
|
|
||||||
M_SIZE
|
|
||||||
M_RESIDENT
|
|
||||||
M_SHARE
|
|
||||||
STATE
|
|
||||||
PERCENT_CPU
|
|
||||||
PERCENT_MEM
|
|
||||||
TIME
|
|
||||||
COMM
|
|
||||||
];
|
|
||||||
|
|
||||||
modes = {
|
modes = {
|
||||||
Bar = 1;
|
Bar = 1;
|
||||||
Text = 2;
|
Text = 2;
|
||||||
|
@ -106,6 +91,48 @@ let
|
||||||
led = meter modes.LED;
|
led = meter modes.LED;
|
||||||
blank = text "Blank";
|
blank = text "Blank";
|
||||||
|
|
||||||
|
screenOptions = {
|
||||||
|
name = mkOption { type = types.str; };
|
||||||
|
|
||||||
|
fields = mkOption {
|
||||||
|
type = types.oneOf [ types.str (types.listOf types.str) ];
|
||||||
|
default = "PID USER M_VIRT STATE PERCENT_CPU PERCENT_MEM TIME Command";
|
||||||
|
};
|
||||||
|
|
||||||
|
all_branches_collapsed = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
sort_direction = mkOption {
|
||||||
|
type = types.enum [ (-1) 1 ];
|
||||||
|
default = -1;
|
||||||
|
};
|
||||||
|
sort_key = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "PERCENT_MEM";
|
||||||
|
};
|
||||||
|
|
||||||
|
tree_sort_direction = mkOption {
|
||||||
|
type = types.enum [ (-1) 1 ];
|
||||||
|
default = -1;
|
||||||
|
};
|
||||||
|
tree_sort_key = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "PERCENT_MEM";
|
||||||
|
};
|
||||||
|
|
||||||
|
tree_view = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
tree_view_always_by_pid = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
in {
|
in {
|
||||||
meta.maintainers = [ hm.maintainers.bjpbakker ];
|
meta.maintainers = [ hm.maintainers.bjpbakker ];
|
||||||
|
|
||||||
|
@ -156,6 +183,38 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
screens = mkOption {
|
||||||
|
type = hm.types.dagOf (types.submodule ({ dagName, ... }: {
|
||||||
|
options = screenOptions;
|
||||||
|
config.name = mkDefault dagName;
|
||||||
|
}));
|
||||||
|
default = { };
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
"Main" = {
|
||||||
|
fields = "PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command";
|
||||||
|
sort_key = "PERCENT_MEM";
|
||||||
|
tree_sort_key = "PERCENT_MEM";
|
||||||
|
tree_view = false;
|
||||||
|
tree_view_always_by_pid = false;
|
||||||
|
sort_direction = -1;
|
||||||
|
tree_sort_direction = -1;
|
||||||
|
all_branches_collapsed = false;
|
||||||
|
};
|
||||||
|
"I/O" = lib.hm.dag.entryAfter ["Main"] {
|
||||||
|
fields = "PID STATE STARTTIME M_RESIDENT COMM EXE USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE";
|
||||||
|
sort_key = "IO_RATE";
|
||||||
|
tree_sort_key = "PID";
|
||||||
|
tree_view = false;
|
||||||
|
tree_view_always_by_pid = false;
|
||||||
|
sort_direction = -1;
|
||||||
|
tree_sort_direction = -1;
|
||||||
|
all_branches_collapsed = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.htop;
|
default = pkgs.htop;
|
||||||
|
@ -172,25 +231,55 @@ in {
|
||||||
home.packages = [ cfg.package ];
|
home.packages = [ cfg.package ];
|
||||||
|
|
||||||
xdg.configFile."htop/htoprc" = let
|
xdg.configFile."htop/htoprc" = let
|
||||||
defaults = {
|
formatOptions = mapAttrsToList formatOption;
|
||||||
fields = if isDarwin then
|
|
||||||
remove fields.M_SHARE defaultFields
|
|
||||||
else
|
|
||||||
defaultFields;
|
|
||||||
};
|
|
||||||
|
|
||||||
before = optionalAttrs (cfg.settings ? header_layout) {
|
hasScreens = cfg.screens != { };
|
||||||
|
|
||||||
|
settings = let
|
||||||
|
# old (no screen) configuration support
|
||||||
|
defaultFields = let
|
||||||
|
defaults = with fields; [
|
||||||
|
PID
|
||||||
|
USER
|
||||||
|
PRIORITY
|
||||||
|
NICE
|
||||||
|
M_SIZE
|
||||||
|
M_RESIDENT
|
||||||
|
M_SHARE
|
||||||
|
STATE
|
||||||
|
PERCENT_CPU
|
||||||
|
PERCENT_MEM
|
||||||
|
TIME
|
||||||
|
COMM
|
||||||
|
];
|
||||||
|
in if isDarwin then remove fields.M_SHARE defaults else defaults;
|
||||||
|
|
||||||
|
oldDefaults = optionalAttrs (!hasScreens) { fields = defaultFields; };
|
||||||
|
|
||||||
|
leading = optionalAttrs (cfg.settings ? header_layout) {
|
||||||
inherit (cfg.settings) header_layout;
|
inherit (cfg.settings) header_layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
settings = defaults // (removeAttrs cfg.settings (attrNames before));
|
settings' = oldDefaults
|
||||||
|
// (removeAttrs cfg.settings (attrNames leading));
|
||||||
|
in formatOptions leading ++ formatOptions settings';
|
||||||
|
|
||||||
formatOptions = mapAttrsToList formatOption;
|
screens = let
|
||||||
|
formatOption' = k: formatOption ".${k}";
|
||||||
|
formatScreen = { name, fields, ... }@screen:
|
||||||
|
let
|
||||||
|
options = removeAttrs screen [ "fields" "name" ];
|
||||||
|
newScreen = "screen:${formatOption name fields}";
|
||||||
|
in [ newScreen ] ++ mapAttrsToList formatOption' options;
|
||||||
|
|
||||||
in mkIf (cfg.settings != { }) {
|
screens' = let sorted = hm.dag.topoSort cfg.screens;
|
||||||
text =
|
in sorted.result or (abort
|
||||||
concatStringsSep "\n" (formatOptions before ++ formatOptions settings)
|
"Dependency cycle in htop screens: ${builtins.toJSON sorted}");
|
||||||
+ "\n";
|
|
||||||
|
in concatMap (x: formatScreen x.data) screens';
|
||||||
|
|
||||||
|
in mkIf (cfg.settings != { } || hasScreens) {
|
||||||
|
text = concatStringsSep "\n" (settings ++ screens) + "\n";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
htop-empty-settings = ./empty-settings.nix;
|
htop-empty-settings = ./empty-settings.nix;
|
||||||
htop-example-settings = ./example-settings.nix;
|
htop-example-settings = ./example-settings.nix;
|
||||||
htop-header_layout = ./header_layout.nix;
|
htop-header_layout = ./header_layout.nix;
|
||||||
|
htop-screens = ./screens.nix;
|
||||||
htop-settings-without-fields = ./settings-without-fields.nix;
|
htop-settings-without-fields = ./settings-without-fields.nix;
|
||||||
}
|
}
|
||||||
|
|
39
tests/modules/programs/htop/screens.nix
Normal file
39
tests/modules/programs/htop/screens.nix
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.htop.enable = true;
|
||||||
|
programs.htop.settings = { screen_tabs = true; };
|
||||||
|
programs.htop.screens = {
|
||||||
|
"Main" = {
|
||||||
|
fields =
|
||||||
|
"PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command";
|
||||||
|
sort_key = "PERCENT_MEM";
|
||||||
|
tree_sort_key = "PERCENT_MEM";
|
||||||
|
tree_view = false;
|
||||||
|
tree_view_always_by_pid = false;
|
||||||
|
sort_direction = -1;
|
||||||
|
tree_sort_direction = -1;
|
||||||
|
all_branches_collapsed = false;
|
||||||
|
};
|
||||||
|
"I/O" = lib.hm.dag.entryAfter [ "Main" ] {
|
||||||
|
fields =
|
||||||
|
"PID STATE STARTTIME M_RESIDENT COMM EXE USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE";
|
||||||
|
sort_key = "IO_RATE";
|
||||||
|
tree_sort_key = "PID";
|
||||||
|
tree_view = false;
|
||||||
|
tree_view_always_by_pid = false;
|
||||||
|
sort_direction = -1;
|
||||||
|
tree_sort_direction = -1;
|
||||||
|
all_branches_collapsed = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test.stubs.htop = { };
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
htoprc=home-files/.config/htop/htoprc
|
||||||
|
assertFileExists $htoprc
|
||||||
|
assertFileContent $htoprc ${./screens.txt}
|
||||||
|
'';
|
||||||
|
|
||||||
|
}
|
17
tests/modules/programs/htop/screens.txt
Normal file
17
tests/modules/programs/htop/screens.txt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
screen_tabs=1
|
||||||
|
screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command
|
||||||
|
.all_branches_collapsed=0
|
||||||
|
.sort_direction=-1
|
||||||
|
.sort_key=PERCENT_MEM
|
||||||
|
.tree_sort_direction=-1
|
||||||
|
.tree_sort_key=PERCENT_MEM
|
||||||
|
.tree_view=0
|
||||||
|
.tree_view_always_by_pid=0
|
||||||
|
screen:I/O=PID STATE STARTTIME M_RESIDENT COMM EXE USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE
|
||||||
|
.all_branches_collapsed=0
|
||||||
|
.sort_direction=-1
|
||||||
|
.sort_key=IO_RATE
|
||||||
|
.tree_sort_direction=-1
|
||||||
|
.tree_sort_key=PID
|
||||||
|
.tree_view=0
|
||||||
|
.tree_view_always_by_pid=0
|
Loading…
Reference in a new issue