2017-07-24 05:47:59 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
cfg = config.programs.htop;
|
|
|
|
|
|
|
|
list = xs: concatMapStrings (x: "${toString x} ") xs;
|
|
|
|
|
|
|
|
bool = b: if b then "1" else "0";
|
|
|
|
|
|
|
|
fields = {
|
|
|
|
PID = 0;
|
|
|
|
COMM = 1;
|
|
|
|
STATE = 2;
|
|
|
|
PPID = 3;
|
|
|
|
PGRP = 4;
|
|
|
|
SESSION = 5;
|
|
|
|
TTY_NR = 6;
|
|
|
|
TPGID = 7;
|
|
|
|
MINFLT = 9;
|
|
|
|
MAJFLT = 11;
|
|
|
|
PRIORITY = 17;
|
|
|
|
NICE = 18;
|
|
|
|
STARTTIME = 20;
|
|
|
|
PROCESSOR = 37;
|
|
|
|
M_SIZE = 38;
|
|
|
|
M_RESIDENT = 39;
|
|
|
|
ST_UID = 45;
|
|
|
|
PERCENT_CPU = 46;
|
|
|
|
PERCENT_MEM = 47;
|
|
|
|
USER = 48;
|
|
|
|
TIME = 49;
|
|
|
|
NLWP = 50;
|
|
|
|
TGID = 51;
|
|
|
|
CMINFLT = 10;
|
|
|
|
CMAJFLT = 12;
|
|
|
|
UTIME = 13;
|
|
|
|
STIME = 14;
|
|
|
|
CUTIME = 15;
|
|
|
|
CSTIME = 16;
|
|
|
|
M_SHARE = 40;
|
|
|
|
M_TRS = 41;
|
|
|
|
M_DRS = 42;
|
|
|
|
M_LRS = 43;
|
|
|
|
M_DT = 44;
|
|
|
|
CTID = 99;
|
|
|
|
VPID = 100;
|
|
|
|
VXID = 102;
|
|
|
|
RCHAR = 102;
|
|
|
|
WCHAR = 103;
|
|
|
|
SYSCR = 104;
|
|
|
|
SYSCW = 105;
|
|
|
|
RBYTES = 106;
|
|
|
|
WBYTES = 107;
|
|
|
|
CNCLWB = 108;
|
|
|
|
IO_READ_RATE = 109;
|
|
|
|
IO_WRITE_RATE = 110;
|
|
|
|
IO_RATE = 111;
|
|
|
|
CGROUP = 112;
|
|
|
|
OOM = 113;
|
|
|
|
IO_PRIORITY = 114;
|
|
|
|
};
|
|
|
|
|
|
|
|
# Mapping from names to defaults
|
|
|
|
meters = {
|
|
|
|
Clock = 2;
|
|
|
|
LoadAverage = 2;
|
|
|
|
Load = 2;
|
|
|
|
Memory = 1;
|
|
|
|
Swap = 1;
|
|
|
|
Tasks = 2;
|
|
|
|
Uptime = 2;
|
|
|
|
Battery = 2;
|
|
|
|
Hostname = 2;
|
|
|
|
AllCPUs = 1;
|
|
|
|
AllCPUs2 = 1;
|
|
|
|
LeftCPUs = 1;
|
|
|
|
RightCPUs = 1;
|
|
|
|
LeftCPUs2 = 1;
|
|
|
|
RightCPUs2 = 1;
|
|
|
|
Blank = 2;
|
|
|
|
CPU = 1;
|
|
|
|
"CPU(1)"= 1;
|
|
|
|
"CPU(2)" = 1;
|
|
|
|
"CPU(3)" = 1;
|
|
|
|
"CPU(4)" = 1;
|
|
|
|
};
|
|
|
|
|
2017-07-24 18:44:58 +00:00
|
|
|
singleMeterType = types.coercedTo
|
|
|
|
(types.enum (attrNames meters))
|
|
|
|
(m: { kind = m; mode = meters.${m}; })
|
|
|
|
(types.submodule {
|
|
|
|
options = {
|
|
|
|
kind = mkOption {
|
|
|
|
type = types.enum (attrNames meters);
|
|
|
|
example = "AllCPUs";
|
|
|
|
description = "What kind of meter.";
|
|
|
|
};
|
|
|
|
|
|
|
|
mode = mkOption {
|
|
|
|
type = types.enum [ 1 2 3 4 ];
|
|
|
|
example = 2;
|
|
|
|
description = "Which mode the meter should use, one of 1(Bar) 2(Text) 3(Graph) 4(LED).";
|
|
|
|
};
|
2017-07-24 05:47:59 +00:00
|
|
|
};
|
2017-07-24 18:44:58 +00:00
|
|
|
});
|
2017-07-24 05:47:59 +00:00
|
|
|
|
|
|
|
meterType = types.submodule {
|
|
|
|
options = {
|
|
|
|
left = mkOption {
|
|
|
|
description = "Meters shown in the left header.";
|
|
|
|
default = [ "AllCPUs" "Memory" "Swap" ];
|
|
|
|
example = [
|
|
|
|
"Memory"
|
|
|
|
"LeftCPUs2"
|
|
|
|
"RightCPUs2"
|
|
|
|
{ kind = "CPU"; mode = 3; }
|
|
|
|
];
|
|
|
|
type = types.listOf singleMeterType;
|
|
|
|
};
|
|
|
|
right = mkOption {
|
|
|
|
description = "Meters shown in the right header.";
|
|
|
|
default = [ "Tasks" "LoadAverage" "Uptime" ];
|
|
|
|
example = [
|
|
|
|
{ kind = "Clock"; mode = 4; }
|
|
|
|
"Uptime"
|
|
|
|
"Tasks"
|
|
|
|
];
|
|
|
|
type = types.listOf singleMeterType;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
in
|
|
|
|
{
|
|
|
|
options.programs.htop = {
|
|
|
|
enable = mkEnableOption "htop";
|
|
|
|
|
|
|
|
fields = mkOption {
|
|
|
|
type = types.listOf (types.enum (attrNames fields));
|
|
|
|
default = [ "PID" "USER" "PRIORITY" "NICE" "M_SIZE" "M_RESIDENT" "M_SHARE" "STATE" "PERCENT_CPU" "PERCENT_MEM" "TIME" "COMM" ];
|
|
|
|
example = [ "PID" "USER" "PRIORITY" "PERCENT_CPU" "M_RESIDENT" "PERCENT_MEM" "TIME" "COMM" ];
|
|
|
|
description = "Active fields shown in the table.";
|
|
|
|
};
|
|
|
|
|
|
|
|
sortKey = mkOption {
|
|
|
|
type = types.enum (attrNames fields);
|
|
|
|
default = "PERCENT_CPU";
|
|
|
|
example = "TIME";
|
|
|
|
description = "Which field to use for sorting.";
|
|
|
|
};
|
|
|
|
|
|
|
|
sortDescending = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = "Whether to sort descending or not.";
|
|
|
|
};
|
|
|
|
|
|
|
|
hideThreads = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Hide threads.";
|
|
|
|
};
|
|
|
|
|
|
|
|
hideKernelThreads = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = "Hide kernel threads.";
|
|
|
|
};
|
|
|
|
|
|
|
|
hideUserlandThreads = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Hide userland process threads.";
|
|
|
|
};
|
|
|
|
|
|
|
|
shadowOtherUsers = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Shadow other users' processes.";
|
|
|
|
};
|
|
|
|
|
|
|
|
showThreadNames = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Show custom thread names.";
|
|
|
|
};
|
|
|
|
|
|
|
|
showProgramPath = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = "Show program path.";
|
|
|
|
};
|
|
|
|
|
|
|
|
highlightBaseName = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Highlight program <quote>basename</quote>.";
|
|
|
|
};
|
|
|
|
|
|
|
|
highlightMegabytes = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = "Highlight large numbers in memory counters.";
|
|
|
|
};
|
|
|
|
|
|
|
|
highlightThreads = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = "Display threads in a different color.";
|
|
|
|
};
|
|
|
|
|
|
|
|
treeView = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Tree view.";
|
|
|
|
};
|
|
|
|
|
|
|
|
headerMargin = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = "Leave a margin around header.";
|
|
|
|
};
|
|
|
|
|
|
|
|
detailedCpuTime = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest).";
|
|
|
|
};
|
|
|
|
|
|
|
|
cpuCountFromZero = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Count CPUs from 0 instead of 1.";
|
|
|
|
};
|
|
|
|
|
|
|
|
updateProcessNames = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Update process names on every refresh.";
|
|
|
|
};
|
|
|
|
|
|
|
|
accountGuestInCpuMeter = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Add guest time in CPU meter percentage.";
|
|
|
|
};
|
|
|
|
|
|
|
|
colorScheme = mkOption {
|
|
|
|
type = types.enum [ 0 1 2 3 4 5 6 ];
|
|
|
|
default = 0;
|
|
|
|
example = 6;
|
|
|
|
description = "Which color scheme to use.";
|
|
|
|
};
|
|
|
|
|
|
|
|
delay = mkOption {
|
|
|
|
type = types.int;
|
|
|
|
default = 15;
|
|
|
|
example = 2;
|
|
|
|
description = "Set the delay between updates, in tenths of seconds.";
|
|
|
|
};
|
|
|
|
|
|
|
|
meters = mkOption {
|
|
|
|
description = "Meters shown in the header.";
|
|
|
|
default = {
|
|
|
|
left = [ "AllCPUs" "Memory" "Swap" ];
|
|
|
|
right = [ "Tasks" "LoadAverage" "Uptime" ];
|
|
|
|
};
|
|
|
|
example = {
|
|
|
|
left = [
|
|
|
|
"Memory"
|
|
|
|
"CPU"
|
|
|
|
"LeftCPUs2"
|
|
|
|
"RightCPUs2"
|
|
|
|
{ kind = "CPU"; mode = 3; }
|
|
|
|
];
|
|
|
|
right = [
|
|
|
|
{ kind = "Clock"; mode = 4; }
|
|
|
|
"Uptime"
|
|
|
|
"Tasks"
|
|
|
|
"LoadAverage"
|
|
|
|
{ kind = "Battery"; mode = 1; }
|
|
|
|
];
|
|
|
|
};
|
|
|
|
type = meterType;
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
home.packages = [ pkgs.htop ];
|
|
|
|
|
2017-10-24 16:30:35 +00:00
|
|
|
xdg.configFile."htop/htoprc".text = let
|
2017-07-24 18:44:58 +00:00
|
|
|
leftMeters = map (m: m.kind) cfg.meters.left;
|
|
|
|
leftModes = map (m: m.mode) cfg.meters.left;
|
|
|
|
rightMeters = map (m: m.kind) cfg.meters.right;
|
|
|
|
rightModes = map (m: m.mode) cfg.meters.right;
|
2017-07-24 05:47:59 +00:00
|
|
|
in ''
|
|
|
|
# This file is regenerated by home-manager
|
|
|
|
# when options are changed in the config
|
|
|
|
fields=${list (map (n: fields.${n}) cfg.fields)}
|
|
|
|
sort_key=${toString (fields.${cfg.sortKey})}
|
|
|
|
sort_direction=${bool cfg.sortDescending}
|
|
|
|
hide_threads=${bool cfg.hideThreads}
|
|
|
|
hide_kernel_threads=${bool cfg.hideKernelThreads}
|
|
|
|
hide_userland_threads=${bool cfg.hideUserlandThreads}
|
|
|
|
shadow_other_users=${bool cfg.shadowOtherUsers}
|
|
|
|
show_thread_names=${bool cfg.showThreadNames}
|
|
|
|
show_program_path=${bool cfg.showProgramPath}
|
|
|
|
highlight_base_name=${bool cfg.highlightBaseName}
|
|
|
|
highlight_megabytes=${bool cfg.highlightMegabytes}
|
|
|
|
highlight_threads=${bool cfg.highlightThreads}
|
|
|
|
tree_view=${bool cfg.treeView}
|
|
|
|
header_margin=${bool cfg.headerMargin}
|
|
|
|
detailed_cpu_time=${bool cfg.detailedCpuTime}
|
|
|
|
cpu_count_from_zero=${bool cfg.cpuCountFromZero}
|
|
|
|
update_process_names=${bool cfg.updateProcessNames}
|
|
|
|
account_guest_in_cpu_meter=${bool cfg.accountGuestInCpuMeter}
|
|
|
|
color_scheme=${toString cfg.colorScheme}
|
|
|
|
delay=${toString cfg.delay}
|
|
|
|
left_meters=${list leftMeters}
|
|
|
|
left_meter_modes=${list leftModes}
|
|
|
|
right_meters=${list rightMeters}
|
|
|
|
right_meter_modes=${list rightModes}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
}
|