Nonatomic
This commit is contained in:
parent
074a7f21ab
commit
d54d749a86
|
@ -6,6 +6,25 @@ if [[ -z "$TMUX" ]] {
|
||||||
exec tmux;
|
exec tmux;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Prompt
|
||||||
|
function default_host () {
|
||||||
|
H="${HOST}%{%}:"
|
||||||
|
REPLY=${H/apollo%{%}:/}
|
||||||
|
REPLY=${REPLY/.olymp.space/}
|
||||||
|
echo $REPLY
|
||||||
|
}
|
||||||
|
function default_user () {
|
||||||
|
U=${USER}@
|
||||||
|
REPLY=${U/maralorn@/}
|
||||||
|
echo $REPLY
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setopt prompt_subst
|
||||||
|
autoload -U colors && colors # Enable colors in prompt
|
||||||
|
PROMPT='%{%F{red}%}$(default_user)$(default_host)%{%F{blue}%}%~%{%}> %{%f%}'
|
||||||
|
|
||||||
precmd() {
|
precmd() {
|
||||||
local s=$? c=( $(fc -L -D -l -1) )
|
local s=$? c=( $(fc -L -D -l -1) )
|
||||||
if [[ $launched && "${c[2]}" != "0:00" ]] {
|
if [[ $launched && "${c[2]}" != "0:00" ]] {
|
||||||
|
@ -22,10 +41,14 @@ alias m=man
|
||||||
alias t="tmux attach"
|
alias t="tmux attach"
|
||||||
alias tn="tmux new-session"
|
alias tn="tmux new-session"
|
||||||
alias w="develop-here"
|
alias w="develop-here"
|
||||||
alias ls=exa
|
alias ls='exa -lh --git'
|
||||||
|
|
||||||
export BROWSER=qutebrowser
|
autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
|
||||||
export EDITOR=nvim
|
add-zsh-hook chpwd chpwd_recent_dirs
|
||||||
export MANPAGER="most -s"
|
zstyle ':chpwd:*' recent-dirs-max 25
|
||||||
|
|
||||||
|
if [[ $PWD == "$HOME" ]] {
|
||||||
|
cd "$(head -n1 ~/.chpwd-recent-dirs | sed s/\\$// | sed s/\'//g)"
|
||||||
|
}
|
||||||
|
|
||||||
bindkey '^R' history-incremental-pattern-search-backward
|
bindkey '^R' history-incremental-pattern-search-backward
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, config, ... }:
|
||||||
let
|
let
|
||||||
rust-scripts = with pkgs; callPackage ../packages/rust-scripts {};
|
rust-scripts = with pkgs; callPackage ../packages/rust-scripts {};
|
||||||
|
unstable-pkgs = import <unstable> {};
|
||||||
|
eventd = unstable-pkgs.callPackage ../packages/eventd {};
|
||||||
|
st = import graphical/st;
|
||||||
in {
|
in {
|
||||||
|
nixpkgs.config.packageOverrides = pkgs: {
|
||||||
|
eventd = eventd;
|
||||||
|
st = st pkgs config.common.colors;
|
||||||
|
};
|
||||||
|
home.file.".tmux.conf".text = ''
|
||||||
|
set -g default-terminal "st-256color"
|
||||||
|
set -ga terminal-overrides ",st-256color:Tc"
|
||||||
|
set -g history-limit 50000
|
||||||
|
set -g status off
|
||||||
|
set -g escape-time 1
|
||||||
|
'';
|
||||||
programs = {
|
programs = {
|
||||||
home-manager = {
|
home-manager = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -46,7 +60,7 @@ in {
|
||||||
treeView = true;
|
treeView = true;
|
||||||
};
|
};
|
||||||
ssh = {
|
ssh = {
|
||||||
controlMaster = "autoask";
|
controlMaster = "yes";
|
||||||
enable = true;
|
enable = true;
|
||||||
matchBlocks = let
|
matchBlocks = let
|
||||||
matheGwProxy = "ssh -q gw nc -q0 %h %p";
|
matheGwProxy = "ssh -q gw nc -q0 %h %p";
|
||||||
|
@ -55,16 +69,16 @@ in {
|
||||||
in [
|
in [
|
||||||
{ host = "charon"; hostname = "charon.olymp.space"; }
|
{ host = "charon"; hostname = "charon.olymp.space"; }
|
||||||
{ host = "*.olymp.space"; user = "maralorn"; }
|
{ host = "*.olymp.space"; user = "maralorn"; }
|
||||||
{ host = "ag-forward"; hostname = agHost; proxyCommand = matheGwProxy; }
|
{ host = "ag-forward"; hostname = agHost; proxyCommand = matheGwProxy;user="brandy";}
|
||||||
{ host = "ag"; hostname = agHost; }
|
{ host = "ag"; hostname = agHost;user="brandy";}
|
||||||
{ host = "kiva-forward"; hostname = kivaHost; proxyCommand = matheGwProxy; }
|
{ host = "kiva-forward"; hostname = kivaHost; proxyCommand = matheGwProxy;user="brandy";}
|
||||||
{ host = "kiva"; hostname = kivaHost; }
|
{ host = "kiva"; hostname = kivaHost;user="brandy";}
|
||||||
{ host = "gw"; hostname = "gwres4.mathematik.tu-darmstadt.de"; }
|
{ host = "gw"; hostname = "gwres4.mathematik.tu-darmstadt.de";user="brandy";}
|
||||||
{ host = "*.mathematik.tu-darmstadt.de"; user = "brandy"; }
|
|
||||||
{ host = "shells"; hostname = "shells.darmstadt.ccc.de"; }
|
{ host = "shells"; hostname = "shells.darmstadt.ccc.de"; }
|
||||||
{ host = "vorstand"; hostname = "vorstand.darmstadt.ccc.de"; }
|
{ host = "vorstand"; hostname = "vorstand.darmstadt.ccc.de"; }
|
||||||
{ host = "*.darmstadt.ccc.de"; user = "maralorn"; }
|
{ host = "*.darmstadt.ccc.de"; user = "maralorn"; }
|
||||||
{ host = "whisky"; hostname = "whisky.w17.io"; user = "chaos"; }
|
{ host = "whisky"; hostname = "whisky.w17.io"; user = "chaos"; }
|
||||||
|
{ host = "door.w17.io"; identityFile = "~/.ssh/door_rsa";}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
zsh = {
|
zsh = {
|
||||||
|
@ -76,9 +90,20 @@ in {
|
||||||
size = 100000;
|
size = 100000;
|
||||||
};
|
};
|
||||||
initExtra = builtins.readFile ./configs/zshrc;
|
initExtra = builtins.readFile ./configs/zshrc;
|
||||||
|
oh-my-zsh = {
|
||||||
|
enable = true;
|
||||||
|
plugins = [ "colored-man-pages" "git-prompt" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
BROWSER="${pkgs.firefox}/bin/firefox";
|
||||||
|
EDITOR="${pkgs.neovim}/bin/nvim";
|
||||||
|
TERMINAL=config.common.terminal;
|
||||||
|
};
|
||||||
systemd.user.startServices = true;
|
systemd.user.startServices = true;
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -101,6 +126,7 @@ in {
|
||||||
tig
|
tig
|
||||||
exa
|
exa
|
||||||
fzf
|
fzf
|
||||||
|
ag
|
||||||
|
|
||||||
pythonPackages.qrcode
|
pythonPackages.qrcode
|
||||||
ranger
|
ranger
|
||||||
|
|
|
@ -19,7 +19,7 @@ in {
|
||||||
"leisure"
|
"leisure"
|
||||||
"config"
|
"config"
|
||||||
];
|
];
|
||||||
terminal = "urxvt";
|
terminal = "${pkgs.st}/bin/st";
|
||||||
colors = {
|
colors = {
|
||||||
"foreground" = "#dddbff";
|
"foreground" = "#dddbff";
|
||||||
"background" = "#05004a";
|
"background" = "#05004a";
|
||||||
|
@ -44,6 +44,7 @@ in {
|
||||||
home = {
|
home = {
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
tasktree
|
tasktree
|
||||||
|
st
|
||||||
];
|
];
|
||||||
keyboard = {
|
keyboard = {
|
||||||
layout = "de";
|
layout = "de";
|
||||||
|
@ -73,7 +74,6 @@ in {
|
||||||
enable = true;
|
enable = true;
|
||||||
components = [
|
components = [
|
||||||
"secrets"
|
"secrets"
|
||||||
"ssh"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
random-background = {
|
random-background = {
|
||||||
|
@ -83,6 +83,9 @@ in {
|
||||||
};
|
};
|
||||||
gpg-agent = {
|
gpg-agent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
enableSshSupport = true;
|
||||||
|
defaultCacheTtl = 900;
|
||||||
|
defaultCacheTtlSsh = 900;
|
||||||
};
|
};
|
||||||
redshift = {
|
redshift = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
{ pkgs, lib, config, ... }:
|
{ pkgs, lib, config, ... }:
|
||||||
let
|
let
|
||||||
eventd-pkgs = import (fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/fe61c3b84e8e81a8ec2bf6b3ed2a0e8652cea190.tar.gz) {};
|
|
||||||
eventd = eventd-pkgs.callPackage ../../packages/eventd {};
|
|
||||||
colors = config.common.colors;
|
colors = config.common.colors;
|
||||||
in {
|
in {
|
||||||
home = {
|
home = {
|
||||||
|
@ -23,8 +21,8 @@ in {
|
||||||
Service = {
|
Service = {
|
||||||
Type="notify";
|
Type="notify";
|
||||||
Sockets="eventd-control.socket eventd.socket";
|
Sockets="eventd-control.socket eventd.socket";
|
||||||
ExecStart="${eventd}/bin/eventd --listen systemd";
|
ExecStart="${pkgs.eventd}/bin/eventd --listen systemd";
|
||||||
ExecReload="${eventd}/bin/eventdctl reload";
|
ExecReload="${pkgs.eventd}/bin/eventdctl reload";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -58,21 +56,6 @@ in {
|
||||||
Spacing = 2;
|
Spacing = 2;
|
||||||
Limit = 10;
|
Limit = 10;
|
||||||
};
|
};
|
||||||
"Queue mode" = {
|
|
||||||
Anchor = "top";
|
|
||||||
Margin = 300;
|
|
||||||
Limit = 1;
|
|
||||||
};
|
|
||||||
"Queue feedback" = {
|
|
||||||
Anchor = "top";
|
|
||||||
Margin = 450;
|
|
||||||
Limit = 1;
|
|
||||||
};
|
|
||||||
"Queue workspace" = {
|
|
||||||
Anchor = "bottom-left";
|
|
||||||
Margin = 10;
|
|
||||||
Limit = 1;
|
|
||||||
};
|
|
||||||
"Queue command" = {
|
"Queue command" = {
|
||||||
Anchor = "bottom-right";
|
Anchor = "bottom-right";
|
||||||
Margin = 10;
|
Margin = 10;
|
||||||
|
@ -81,20 +64,15 @@ in {
|
||||||
};
|
};
|
||||||
"Queue critical" = {
|
"Queue critical" = {
|
||||||
Anchor = "top";
|
Anchor = "top";
|
||||||
Margin = 10;
|
Margin = 450;
|
||||||
Spacing = 2;
|
Spacing = 2;
|
||||||
Limit = 10;
|
Limit = 10;
|
||||||
};
|
};
|
||||||
"Queue state" = {
|
"Queue tasks" = {
|
||||||
Anchor = "top-left";
|
|
||||||
Margin = 10;
|
|
||||||
Spacing = 2;
|
|
||||||
Limit = 10;
|
|
||||||
};
|
|
||||||
"Queue music" = {
|
|
||||||
Anchor = "bottom";
|
Anchor = "bottom";
|
||||||
Margin = 10;
|
Margin = 0;
|
||||||
Limit = 1;
|
Spacing = 1;
|
||||||
|
Limit = 20;
|
||||||
};
|
};
|
||||||
Notification = {
|
Notification = {
|
||||||
Text = "\${message}";
|
Text = "\${message}";
|
||||||
|
@ -113,17 +91,11 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"eventd/notification.event".text = lib.generators.toINI {} {
|
"eventd/notification.event".text = lib.generators.toINI {} {
|
||||||
"Event mode *" = {
|
|
||||||
Actions = "mode";
|
|
||||||
};
|
|
||||||
"Event notification *" = {
|
"Event notification *" = {
|
||||||
Actions = "notification";
|
Actions = "notification";
|
||||||
};
|
};
|
||||||
"Event feedback *" = {
|
"Event notification kassandra" = {
|
||||||
Actions = "feedback";
|
Actions = "kassandra";
|
||||||
};
|
|
||||||
"Event workspace *" = {
|
|
||||||
Actions = "workspace";
|
|
||||||
};
|
};
|
||||||
"Event command success" = {
|
"Event command success" = {
|
||||||
Actions = "command-success";
|
Actions = "command-success";
|
||||||
|
@ -134,25 +106,6 @@ in {
|
||||||
"Event critical *" = {
|
"Event critical *" = {
|
||||||
Actions = "critical";
|
Actions = "critical";
|
||||||
};
|
};
|
||||||
"Event state *" = {
|
|
||||||
Actions = "state";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"eventd/mode.action".text = lib.generators.toINI {} {
|
|
||||||
Action = {
|
|
||||||
Name = "mode";
|
|
||||||
};
|
|
||||||
Notification = {
|
|
||||||
};
|
|
||||||
NotificationBubble = {
|
|
||||||
Timeout = 0;
|
|
||||||
Queue = "mode";
|
|
||||||
Padding = 40;
|
|
||||||
MinWidth = 10;
|
|
||||||
};
|
|
||||||
NotificationText = {
|
|
||||||
Font = "Linux Libertine 40";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
"eventd/command-success.action".text = lib.generators.toINI {} {
|
"eventd/command-success.action".text = lib.generators.toINI {} {
|
||||||
Action = {
|
Action = {
|
||||||
|
@ -163,6 +116,7 @@ in {
|
||||||
};
|
};
|
||||||
NotificationBubble = {
|
NotificationBubble = {
|
||||||
Colour = colors.black;
|
Colour = colors.black;
|
||||||
|
Queue = "command";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"eventd/command-failure.action".text = lib.generators.toINI {} {
|
"eventd/command-failure.action".text = lib.generators.toINI {} {
|
||||||
|
@ -173,30 +127,31 @@ in {
|
||||||
Text="<b>\${command}</b>\\nfailed after \${time} @ \${host}";
|
Text="<b>\${command}</b>\\nfailed after \${time} @ \${host}";
|
||||||
};
|
};
|
||||||
NotificationBubble = {
|
NotificationBubble = {
|
||||||
|
Queue = "critical";
|
||||||
Colour = colors.red;
|
Colour = colors.red;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"eventd/workspace.action".text = lib.generators.toINI {} {
|
"eventd/critical.action".text = lib.generators.toINI {} {
|
||||||
Action = {
|
Action = {
|
||||||
Name = "workspace";
|
Name = "critical";
|
||||||
};
|
};
|
||||||
Notification = {
|
Notification = {
|
||||||
|
Text = "<b>\${title}</b>\${message/^/\\n}";
|
||||||
};
|
};
|
||||||
NotificationBubble = {
|
NotificationBubble = {
|
||||||
Queue = "workspace";
|
Queue = "critical";
|
||||||
MinWidth = 10;
|
Colour = colors.red;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"eventd/feedback.action".text = lib.generators.toINI {} {
|
"eventd/kassandra.action".text = lib.generators.toINI {} {
|
||||||
Action = {
|
Action = {
|
||||||
Name = "feedback";
|
Name = "kassandra";
|
||||||
};
|
};
|
||||||
Notification = {
|
Notification = {
|
||||||
|
Text = "<b>\${title}</b>\${message/^/\\n}";
|
||||||
};
|
};
|
||||||
NotificationBubble = {
|
NotificationBubble = {
|
||||||
Timeout = 500;
|
Queue = "critical";
|
||||||
Queue = "feedback";
|
|
||||||
Colour = colors.red;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"eventd/notification.action".text = lib.generators.toINI {} {
|
"eventd/notification.action".text = lib.generators.toINI {} {
|
||||||
|
|
|
@ -4,6 +4,18 @@ let
|
||||||
workspaces = config.common.workspaces;
|
workspaces = config.common.workspaces;
|
||||||
terminal = config.common.terminal;
|
terminal = config.common.terminal;
|
||||||
exec = "exec --no-startup-id";
|
exec = "exec --no-startup-id";
|
||||||
|
taskstatus = pkgs.writeShellScriptBin "taskstatus" ''
|
||||||
|
while true;
|
||||||
|
do
|
||||||
|
echo \
|
||||||
|
$(date "+%Y-%m-%d %a %H:%M") "|" \
|
||||||
|
$(cat ~/.kassandra_state | tail -n3 | sed "s/$/ | /") \
|
||||||
|
Inbox: $(task +PENDING -BLOCKED -TAGGED count) "|" \
|
||||||
|
Active Task: $(task rc.verbose=nothing active || echo "No task active") "|" \
|
||||||
|
Tags: $(task +PENDING -BLOCKED -project -optional -later rc.verbose=nothing tags | sed "s/\(.\)$/\1 |/" )
|
||||||
|
sleep 10s;
|
||||||
|
done
|
||||||
|
'';
|
||||||
addMods = oldbindings: builtins.foldl' (newbindings: key:
|
addMods = oldbindings: builtins.foldl' (newbindings: key:
|
||||||
newbindings // {
|
newbindings // {
|
||||||
"Mod4+${key}" = oldbindings.${key};
|
"Mod4+${key}" = oldbindings.${key};
|
||||||
|
@ -12,7 +24,7 @@ let
|
||||||
{}
|
{}
|
||||||
(builtins.attrNames oldbindings);
|
(builtins.attrNames oldbindings);
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./eventd.nix
|
./eventd.nix
|
||||||
./rofi
|
./rofi
|
||||||
./urxvt.nix
|
./urxvt.nix
|
||||||
|
@ -56,7 +68,18 @@ in {
|
||||||
text = colors.foreground;
|
text = colors.foreground;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
bars = [ {
|
bars = [
|
||||||
|
{
|
||||||
|
statusCommand = "${taskstatus}/bin/taskstatus";
|
||||||
|
position = "top";
|
||||||
|
mode = "dock";
|
||||||
|
workspaceButtons = false;
|
||||||
|
colors = {
|
||||||
|
separator = colors.white;
|
||||||
|
background = colors.background;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
mode = "hide";
|
mode = "hide";
|
||||||
colors = {
|
colors = {
|
||||||
separator = colors.white;
|
separator = colors.white;
|
||||||
|
@ -87,28 +110,32 @@ in {
|
||||||
titlebar = false;
|
titlebar = false;
|
||||||
border = 1;
|
border = 1;
|
||||||
};
|
};
|
||||||
gaps = {
|
# gaps = {
|
||||||
inner = 0;
|
# inner = 0;
|
||||||
outer = 0;
|
# outer = 0;
|
||||||
smartBorders = "off";
|
# smartBorders = "off";
|
||||||
smartGaps = false;
|
# smartGaps = false;
|
||||||
};
|
# };
|
||||||
keybindings = addMods ({
|
keybindings = {
|
||||||
|
"XF86AudioMute" = "exec pactl set-sink-mute '@DEFAULT_SINK@' toggle";
|
||||||
|
"XF86AudioLowerVolume" = "exec pactl set-sink-volume '@DEFAULT_SINK@' -5%";
|
||||||
|
"XF86AudioRaiseVolume" = "exec pactl set-sink-volume '@DEFAULT_SINK@' +5%";
|
||||||
|
"XF86AudioMicMute" = "exec pactl set-source-mute '@DEFAULT_SOURCE@' toggle";
|
||||||
|
"XF86MonBrightnessUp" = "exec xbacklight +5";
|
||||||
|
"XF86MonBrightnessDown" = "exec xbacklight -5";
|
||||||
|
"XF86Display" = "exec arandr";
|
||||||
|
"Ctrl+Escape" = "${exec} loginctl lock-session;";
|
||||||
|
} //
|
||||||
|
addMods ({
|
||||||
"Left" = "focus left";
|
"Left" = "focus left";
|
||||||
"Down" = "focus down";
|
"Down" = "focus down";
|
||||||
"Up" = "focus up";
|
"Up" = "focus up";
|
||||||
"Right" = "focus right";
|
"Right" = "focus right";
|
||||||
"Tab" = "${exec} rofi -show window";
|
"Tab" = "${exec} skippy-xd";
|
||||||
"w" = "${exec} skippy-xd";
|
|
||||||
"Prior" = "focus parent";
|
"Prior" = "focus parent";
|
||||||
"Next" = "focus child";
|
"Next" = "focus child";
|
||||||
"Ctrl+Escape" = "${exec} loginctl lock-session;";
|
|
||||||
"Return" = "${exec} ${terminal}";
|
"Return" = "${exec} ${terminal}";
|
||||||
"p" = "${exec} rofi-pass";
|
"p" = "${exec} rofi-pass";
|
||||||
"r" = "${exec} rofi -show combi";
|
|
||||||
"o" = "${exec} rofi -show web";
|
|
||||||
"n" = "${exec} rofi -show ssh";
|
|
||||||
"a" = "${exec} tasklauncher";
|
|
||||||
"shift+Left" = "move left";
|
"shift+Left" = "move left";
|
||||||
"shift+Down" = "move down";
|
"shift+Down" = "move down";
|
||||||
"shift+Up" = "move up";
|
"shift+Up" = "move up";
|
||||||
|
@ -118,8 +145,11 @@ in {
|
||||||
"t" = "layout tabbed";
|
"t" = "layout tabbed";
|
||||||
"s" = "layout toggle split";
|
"s" = "layout toggle split";
|
||||||
"q" = "kill";
|
"q" = "kill";
|
||||||
|
"m" = "move workspace to output up";
|
||||||
|
"n" = "move workspace to output right";
|
||||||
"shift+space" = "floating toggle";
|
"shift+space" = "floating toggle";
|
||||||
"shift+q" = "exec i3-nagbar -t warning -m 'do you want to exit i3?' -b 'yes' 'i3-msg exit'";
|
"shift+q" = "exec i3-nagbar -t warning -m 'do you want to exit i3?' -b 'yes' 'i3-msg exit'";
|
||||||
|
"space" = "exec ~/config/nixos/packages/rust-scripts/target/release/hotkeys";
|
||||||
} // builtins.foldl' (bindings: name: let
|
} // builtins.foldl' (bindings: name: let
|
||||||
number = toString ((builtins.length (builtins.attrNames bindings)) / 2);
|
number = toString ((builtins.length (builtins.attrNames bindings)) / 2);
|
||||||
in
|
in
|
||||||
|
|
|
@ -3,25 +3,25 @@ let
|
||||||
workspaces = config.common.workspaces;
|
workspaces = config.common.workspaces;
|
||||||
terminal = config.common.terminal;
|
terminal = config.common.terminal;
|
||||||
colors = config.common.colors;
|
colors = config.common.colors;
|
||||||
rofiScriptWeb = pkgs.writeShellScriptBin "rofi-script-web" ''
|
#rofiScriptWeb = pkgs.writeShellScriptBin "rofi-script-web" ''
|
||||||
if [[ -z $@ ]]; then
|
#if [[ -z $@ ]]; then
|
||||||
sed 's/^[0-9]*\(-r\)\? \?//;s/^\([^[:space:]]*\).*$/\1/' $HOME/.local/share/qutebrowser/history | tac
|
#sed 's/^[0-9]*\(-r\)\? \?//;s/^\([^[:space:]]*\).*$/\1/' $HOME/.local/share/qutebrowser/history | tac
|
||||||
else
|
#else
|
||||||
${pkgs.qutebrowser}/bin/qutebrowser "$1" > /dev/null &
|
#${pkgs.qutebrowser}/bin/qutebrowser "$1" > /dev/null &
|
||||||
fi
|
#fi
|
||||||
'';
|
#'';
|
||||||
rofiScriptI3 = pkgs.writeShellScriptBin "rofi-script-i3" ''
|
#rofiScriptI3 = pkgs.writeShellScriptBin "rofi-script-i3" ''
|
||||||
if [ -z $@ ]; then
|
#if [ -z $@ ]; then
|
||||||
(i3-msg -t get_workspaces | tr ',' '\n' | grep "name" | sed 's/"name":"\(.*\)"/\1/g';
|
#(i3-msg -t get_workspaces | tr ',' '\n' | grep "name" | sed 's/"name":"\(.*\)"/\1/g';
|
||||||
echo "${builtins.concatStringsSep "\n" (builtins.foldl' (labels: name: let
|
#echo "${builtins.concatStringsSep "\n" (builtins.foldl' (labels: name: let
|
||||||
number = toString (builtins.length labels);
|
#number = toString (builtins.length labels);
|
||||||
in
|
#in
|
||||||
labels ++ [ "${number}:${name}" ]
|
#labels ++ [ "${number}:${name}" ]
|
||||||
) [] workspaces)}") | sort -u
|
#) [] workspaces)}") | sort -u
|
||||||
else
|
#else
|
||||||
i3-msg workspace "$@" >/dev/null
|
#i3-msg workspace "$@" >/dev/null
|
||||||
fi
|
#fi
|
||||||
'';
|
#'';
|
||||||
rofiTask = pkgs.writeScriptBin "tasklauncher" (builtins.readFile ./tasklauncher.py);
|
rofiTask = pkgs.writeScriptBin "tasklauncher" (builtins.readFile ./tasklauncher.py);
|
||||||
# recollPython = pkgs.python2.withPackages (ps: [
|
# recollPython = pkgs.python2.withPackages (ps: [
|
||||||
# pkgs.recoll
|
# pkgs.recoll
|
||||||
|
@ -31,8 +31,8 @@ in {
|
||||||
home = {
|
home = {
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
rofi
|
rofi
|
||||||
rofiScriptWeb
|
#rofiScriptWeb
|
||||||
rofiScriptI3
|
#rofiScriptI3
|
||||||
rofiTask
|
rofiTask
|
||||||
# rofiFind
|
# rofiFind
|
||||||
rofi-pass
|
rofi-pass
|
||||||
|
@ -43,22 +43,22 @@ in {
|
||||||
rofi = {
|
rofi = {
|
||||||
enable = true;
|
enable = true;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
rofi.modi: combi,window,drun,run,ssh,keys,web:rofi-script-web,i3:rofi-script-i3
|
rofi.modi: combi,window,drun,run,ssh,keys
|
||||||
rofi.sidebar-mode: true
|
|
||||||
rofi.combi-modi: window,drun,run
|
rofi.combi-modi: window,drun,run
|
||||||
'';
|
'';
|
||||||
borderWidth = 0;
|
borderWidth = 0;
|
||||||
separator = "none";
|
separator = "none";
|
||||||
fullscreen = false;
|
fullscreen = false;
|
||||||
width = 1920;
|
|
||||||
terminal = terminal;
|
terminal = terminal;
|
||||||
location = "center";
|
yoffset = 19;
|
||||||
|
location = "top";
|
||||||
scrollbar = false;
|
scrollbar = false;
|
||||||
padding = 200;
|
padding = 10;
|
||||||
|
cycle = false;
|
||||||
lines = 30;
|
lines = 30;
|
||||||
colors = {
|
colors = {
|
||||||
window = {
|
window = {
|
||||||
background = "argb:a0${builtins.substring 1 6 colors.background}";
|
background = "argb:c0${builtins.substring 1 6 colors.background}";
|
||||||
border = colors.blue;
|
border = colors.blue;
|
||||||
separator = colors.blue;
|
separator = colors.blue;
|
||||||
};
|
};
|
||||||
|
|
453
home-common/graphical/st/config.h
Normal file
453
home-common/graphical/st/config.h
Normal file
|
@ -0,0 +1,453 @@
|
||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* appearance
|
||||||
|
*
|
||||||
|
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||||
|
*/
|
||||||
|
static char font[] = "Roboto Mono:pixelsize=12:antialias=true:autohint=true";
|
||||||
|
static int borderpx = 2;
|
||||||
|
#define histsize 20000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* What program is execed by st depends of these precedence rules:
|
||||||
|
* 1: program passed with -e
|
||||||
|
* 2: utmp option
|
||||||
|
* 3: SHELL environment variable
|
||||||
|
* 4: value of shell in /etc/passwd
|
||||||
|
* 5: value of shell in config.h
|
||||||
|
*/
|
||||||
|
static char shell[] = "/bin/sh";
|
||||||
|
static char *utmp = NULL;
|
||||||
|
static char stty_args[] = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
||||||
|
|
||||||
|
/* identification sequence returned in DA and DECID */
|
||||||
|
static char vtiden[] = "\033[?6c";
|
||||||
|
|
||||||
|
/* Kerning / character bounding-box multipliers */
|
||||||
|
static float cwscale = 1.0;
|
||||||
|
static float chscale = 1.0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* word delimiter string
|
||||||
|
*
|
||||||
|
* More advanced example: " `'\"()[]{}"
|
||||||
|
*/
|
||||||
|
static char worddelimiters[] = " ";
|
||||||
|
|
||||||
|
/* selection timeouts (in milliseconds) */
|
||||||
|
static unsigned int doubleclicktimeout = 300;
|
||||||
|
static unsigned int tripleclicktimeout = 600;
|
||||||
|
|
||||||
|
/* alt screens */
|
||||||
|
static int allowaltscreen = 1;
|
||||||
|
|
||||||
|
/* frames per second st should at maximum draw to the screen */
|
||||||
|
static unsigned int xfps = 120;
|
||||||
|
static unsigned int actionfps = 30;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* blinking timeout (set to 0 to disable blinking) for the terminal blinking
|
||||||
|
* attribute.
|
||||||
|
*/
|
||||||
|
static unsigned int blinktimeout = 800;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* thickness of underline and bar cursors
|
||||||
|
*/
|
||||||
|
static unsigned int cursorthickness = 2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
|
||||||
|
* it
|
||||||
|
*/
|
||||||
|
static int bellvolume = 0;
|
||||||
|
|
||||||
|
/* default TERM value */
|
||||||
|
static char termname[] = "st-256color";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* spaces per tab
|
||||||
|
*
|
||||||
|
* When you are changing this value, don't forget to adapt the »it« value in
|
||||||
|
* the st.info and appropriately install the st.info in the environment where
|
||||||
|
* you use this st version.
|
||||||
|
*
|
||||||
|
* it#$tabspaces,
|
||||||
|
*
|
||||||
|
* Secondly make sure your kernel is not expanding tabs. When running `stty
|
||||||
|
* -a` »tab0« should appear. You can tell the terminal to not expand tabs by
|
||||||
|
* running following command:
|
||||||
|
*
|
||||||
|
* stty tabs
|
||||||
|
*/
|
||||||
|
static unsigned int tabspaces = 3;
|
||||||
|
static const int alpha = 0xdd;
|
||||||
|
|
||||||
|
/* Terminal colors (16 first used in escape sequence) */
|
||||||
|
static const char *colorname[] = {
|
||||||
|
/* 8 normal colors */
|
||||||
|
"@black@",
|
||||||
|
"@red@",
|
||||||
|
"@green@",
|
||||||
|
"@yellow@",
|
||||||
|
"@blue@",
|
||||||
|
"@magenta@",
|
||||||
|
"@cyan@",
|
||||||
|
"@white@",
|
||||||
|
|
||||||
|
/* 8 bright colors */
|
||||||
|
"@brightBlack@",
|
||||||
|
"@brightRed@",
|
||||||
|
"@brightGreen@",
|
||||||
|
"@brightYellow@",
|
||||||
|
"@brightBlue@",
|
||||||
|
"@brightMagenta@",
|
||||||
|
"@brightCyan@",
|
||||||
|
"@brightWhite@",
|
||||||
|
|
||||||
|
[255] = 0,
|
||||||
|
|
||||||
|
/* more colors can be added after 255 to use with DefaultXX */
|
||||||
|
"@foreground@",
|
||||||
|
"@background@",
|
||||||
|
"@background@"
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default colors (colorname index)
|
||||||
|
* foreground, background, cursor, reverse cursor
|
||||||
|
*/
|
||||||
|
static unsigned int defaultfg = 256;
|
||||||
|
static unsigned int defaultbg = 258;
|
||||||
|
static unsigned int defaultcs = 256;
|
||||||
|
static unsigned int defaultrcs = 257;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default shape of cursor
|
||||||
|
* 2: Block ("█")
|
||||||
|
* 4: Underline ("_")
|
||||||
|
* 6: Bar ("|")
|
||||||
|
* 7: Snowman ("☃")
|
||||||
|
*/
|
||||||
|
static unsigned int cursorshape = 4;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default colour and shape of the mouse cursor
|
||||||
|
*/
|
||||||
|
static unsigned int mouseshape = XC_xterm;
|
||||||
|
static unsigned int mousefg = 7;
|
||||||
|
static unsigned int mousebg = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Colors used, when the specific fg == defaultfg. So in reverse mode this
|
||||||
|
* will reverse too. Another logic would only make the simple feature too
|
||||||
|
* complex.
|
||||||
|
*/
|
||||||
|
static unsigned int defaultitalic = 11;
|
||||||
|
static unsigned int defaultunderline = 7;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal mouse shortcuts.
|
||||||
|
* Beware that overloading Button1 will disable the selection.
|
||||||
|
*/
|
||||||
|
static MouseShortcut mshortcuts[] = {
|
||||||
|
/* button mask string */
|
||||||
|
{ Button4, XK_ANY_MOD, "\031" },
|
||||||
|
{ Button5, XK_ANY_MOD, "\005" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Internal keyboard shortcuts. */
|
||||||
|
#define MODKEY Mod1Mask
|
||||||
|
|
||||||
|
static char* openurlcmd[] = { "@openUrlCmd@", NULL };
|
||||||
|
|
||||||
|
static Shortcut shortcuts[] = {
|
||||||
|
/* mask keysym function argument */
|
||||||
|
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
||||||
|
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
|
||||||
|
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
|
||||||
|
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_Prior, xzoom, {.f = +1} },
|
||||||
|
{ MODKEY|ShiftMask, XK_Next, xzoom, {.f = -1} },
|
||||||
|
{ MODKEY|ShiftMask, XK_Home, xzoomreset, {.f = 0} },
|
||||||
|
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_Insert, clippaste, {.i = 0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} },
|
||||||
|
{ MODKEY, XK_Num_Lock, numlock, {.i = 0} },
|
||||||
|
// { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
|
||||||
|
// { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
|
||||||
|
{ MODKEY|ShiftMask, XK_U, externalpipe, {.v = openurlcmd } },
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special keys (change & recompile st.info accordingly)
|
||||||
|
*
|
||||||
|
* Mask value:
|
||||||
|
* * Use XK_ANY_MOD to match the key no matter modifiers state
|
||||||
|
* * Use XK_NO_MOD to match the key alone (no modifiers)
|
||||||
|
* appkey value:
|
||||||
|
* * 0: no value
|
||||||
|
* * > 0: keypad application mode enabled
|
||||||
|
* * = 2: term.numlock = 1
|
||||||
|
* * < 0: keypad application mode disabled
|
||||||
|
* appcursor value:
|
||||||
|
* * 0: no value
|
||||||
|
* * > 0: cursor application mode enabled
|
||||||
|
* * < 0: cursor application mode disabled
|
||||||
|
* crlf value
|
||||||
|
* * 0: no value
|
||||||
|
* * > 0: crlf mode is enabled
|
||||||
|
* * < 0: crlf mode is disabled
|
||||||
|
*
|
||||||
|
* Be careful with the order of the definitions because st searches in
|
||||||
|
* this table sequentially, so any XK_ANY_MOD must be in the last
|
||||||
|
* position for a key.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
|
||||||
|
* to be mapped below, add them to this array.
|
||||||
|
*/
|
||||||
|
static KeySym mappedkeys[] = { -1 };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* State bits to ignore when matching key or button events. By default,
|
||||||
|
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
|
||||||
|
*/
|
||||||
|
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Override mouse-select while mask is active (when MODE_MOUSE is set).
|
||||||
|
* Note that if you want to use ShiftMask with selmasks, set this to an other
|
||||||
|
* modifier, set to 0 to not use it.
|
||||||
|
*/
|
||||||
|
static uint forceselmod = ShiftMask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the huge key array which defines all compatibility to the Linux
|
||||||
|
* world. Please decide about changes wisely.
|
||||||
|
*/
|
||||||
|
static Key key[] = {
|
||||||
|
/* keysym mask string appkey appcursor crlf */
|
||||||
|
{ XK_KP_Home, ShiftMask, "\033[2J", 0, -1, 0},
|
||||||
|
{ XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1, 0},
|
||||||
|
{ XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1, 0},
|
||||||
|
{ XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1, 0},
|
||||||
|
{ XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0, 0},
|
||||||
|
{ XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1, 0},
|
||||||
|
{ XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1, 0},
|
||||||
|
{ XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0, 0},
|
||||||
|
{ XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1, 0},
|
||||||
|
{ XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1, 0},
|
||||||
|
{ XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0, 0},
|
||||||
|
{ XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1, 0},
|
||||||
|
{ XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1, 0},
|
||||||
|
{ XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0, 0},
|
||||||
|
{ XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1, 0},
|
||||||
|
{ XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1, 0},
|
||||||
|
{ XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0, 0},
|
||||||
|
{ XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0, 0},
|
||||||
|
{ XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0, 0},
|
||||||
|
{ XK_KP_End, ControlMask, "\033[J", -1, 0, 0},
|
||||||
|
{ XK_KP_End, ControlMask, "\033[1;5F", +1, 0, 0},
|
||||||
|
{ XK_KP_End, ShiftMask, "\033[K", -1, 0, 0},
|
||||||
|
{ XK_KP_End, ShiftMask, "\033[1;2F", +1, 0, 0},
|
||||||
|
{ XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0, 0},
|
||||||
|
{ XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0, 0},
|
||||||
|
{ XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0, 0},
|
||||||
|
{ XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0, 0},
|
||||||
|
{ XK_KP_Insert, ShiftMask, "\033[4l", -1, 0, 0},
|
||||||
|
{ XK_KP_Insert, ControlMask, "\033[L", -1, 0, 0},
|
||||||
|
{ XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0, 0},
|
||||||
|
{ XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0, 0},
|
||||||
|
{ XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0, 0},
|
||||||
|
{ XK_KP_Delete, ControlMask, "\033[M", -1, 0, 0},
|
||||||
|
{ XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0, 0},
|
||||||
|
{ XK_KP_Delete, ShiftMask, "\033[2K", -1, 0, 0},
|
||||||
|
{ XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0, 0},
|
||||||
|
{ XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0, 0},
|
||||||
|
{ XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0, 0},
|
||||||
|
{ XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0, 0},
|
||||||
|
{ XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0, 0},
|
||||||
|
{ XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0, 0},
|
||||||
|
{ XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0, -1},
|
||||||
|
{ XK_KP_Enter, XK_ANY_MOD, "\r\n", -1, 0, +1},
|
||||||
|
{ XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0, 0},
|
||||||
|
{ XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0, 0},
|
||||||
|
{ XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0, 0},
|
||||||
|
{ XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0, 0},
|
||||||
|
{ XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0, 0},
|
||||||
|
{ XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0, 0},
|
||||||
|
{ XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0, 0},
|
||||||
|
{ XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0, 0},
|
||||||
|
{ XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0, 0},
|
||||||
|
{ XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0, 0},
|
||||||
|
{ XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0, 0},
|
||||||
|
{ XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0, 0},
|
||||||
|
{ XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0, 0},
|
||||||
|
{ XK_Up, ShiftMask, "\033[1;2A", 0, 0, 0},
|
||||||
|
{ XK_Up, ControlMask, "\033[1;5A", 0, 0, 0},
|
||||||
|
{ XK_Up, Mod1Mask, "\033[1;3A", 0, 0, 0},
|
||||||
|
{ XK_Up, XK_ANY_MOD, "\033[A", 0, -1, 0},
|
||||||
|
{ XK_Up, XK_ANY_MOD, "\033OA", 0, +1, 0},
|
||||||
|
{ XK_Down, ShiftMask, "\033[1;2B", 0, 0, 0},
|
||||||
|
{ XK_Down, ControlMask, "\033[1;5B", 0, 0, 0},
|
||||||
|
{ XK_Down, Mod1Mask, "\033[1;3B", 0, 0, 0},
|
||||||
|
{ XK_Down, XK_ANY_MOD, "\033[B", 0, -1, 0},
|
||||||
|
{ XK_Down, XK_ANY_MOD, "\033OB", 0, +1, 0},
|
||||||
|
{ XK_Left, ShiftMask, "\033[1;2D", 0, 0, 0},
|
||||||
|
{ XK_Left, ControlMask, "\033[1;5D", 0, 0, 0},
|
||||||
|
{ XK_Left, Mod1Mask, "\033[1;3D", 0, 0, 0},
|
||||||
|
{ XK_Left, XK_ANY_MOD, "\033[D", 0, -1, 0},
|
||||||
|
{ XK_Left, XK_ANY_MOD, "\033OD", 0, +1, 0},
|
||||||
|
{ XK_Right, ShiftMask, "\033[1;2C", 0, 0, 0},
|
||||||
|
{ XK_Right, ControlMask, "\033[1;5C", 0, 0, 0},
|
||||||
|
{ XK_Right, Mod1Mask, "\033[1;3C", 0, 0, 0},
|
||||||
|
{ XK_Right, XK_ANY_MOD, "\033[C", 0, -1, 0},
|
||||||
|
{ XK_Right, XK_ANY_MOD, "\033OC", 0, +1, 0},
|
||||||
|
{ XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0, 0},
|
||||||
|
{ XK_Return, Mod1Mask, "\033\r", 0, 0, -1},
|
||||||
|
{ XK_Return, Mod1Mask, "\033\r\n", 0, 0, +1},
|
||||||
|
{ XK_Return, XK_ANY_MOD, "\r", 0, 0, -1},
|
||||||
|
{ XK_Return, XK_ANY_MOD, "\r\n", 0, 0, +1},
|
||||||
|
{ XK_Insert, ShiftMask, "\033[4l", -1, 0, 0},
|
||||||
|
{ XK_Insert, ShiftMask, "\033[2;2~", +1, 0, 0},
|
||||||
|
{ XK_Insert, ControlMask, "\033[L", -1, 0, 0},
|
||||||
|
{ XK_Insert, ControlMask, "\033[2;5~", +1, 0, 0},
|
||||||
|
{ XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0, 0},
|
||||||
|
{ XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0, 0},
|
||||||
|
{ XK_Delete, ControlMask, "\033[M", -1, 0, 0},
|
||||||
|
{ XK_Delete, ControlMask, "\033[3;5~", +1, 0, 0},
|
||||||
|
{ XK_Delete, ShiftMask, "\033[2K", -1, 0, 0},
|
||||||
|
{ XK_Delete, ShiftMask, "\033[3;2~", +1, 0, 0},
|
||||||
|
{ XK_Delete, XK_ANY_MOD, "\033[P", -1, 0, 0},
|
||||||
|
{ XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0, 0},
|
||||||
|
{ XK_BackSpace, XK_NO_MOD, "\177", 0, 0, 0},
|
||||||
|
{ XK_BackSpace, Mod1Mask, "\033\177", 0, 0, 0},
|
||||||
|
{ XK_Home, ShiftMask, "\033[2J", 0, -1, 0},
|
||||||
|
{ XK_Home, ShiftMask, "\033[1;2H", 0, +1, 0},
|
||||||
|
{ XK_Home, XK_ANY_MOD, "\033[H", 0, -1, 0},
|
||||||
|
{ XK_Home, XK_ANY_MOD, "\033[1~", 0, +1, 0},
|
||||||
|
{ XK_End, ControlMask, "\033[J", -1, 0, 0},
|
||||||
|
{ XK_End, ControlMask, "\033[1;5F", +1, 0, 0},
|
||||||
|
{ XK_End, ShiftMask, "\033[K", -1, 0, 0},
|
||||||
|
{ XK_End, ShiftMask, "\033[1;2F", +1, 0, 0},
|
||||||
|
{ XK_End, XK_ANY_MOD, "\033[4~", 0, 0, 0},
|
||||||
|
{ XK_Prior, ControlMask, "\033[5;5~", 0, 0, 0},
|
||||||
|
{ XK_Prior, ShiftMask, "\033[5;2~", 0, 0, 0},
|
||||||
|
{ XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0, 0},
|
||||||
|
{ XK_Next, ControlMask, "\033[6;5~", 0, 0, 0},
|
||||||
|
{ XK_Next, ShiftMask, "\033[6;2~", 0, 0, 0},
|
||||||
|
{ XK_Next, XK_ANY_MOD, "\033[6~", 0, 0, 0},
|
||||||
|
{ XK_F1, XK_NO_MOD, "\033OP" , 0, 0, 0},
|
||||||
|
{ XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0, 0},
|
||||||
|
{ XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0, 0},
|
||||||
|
{ XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0, 0},
|
||||||
|
{ XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0, 0},
|
||||||
|
{ XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0, 0},
|
||||||
|
{ XK_F2, XK_NO_MOD, "\033OQ" , 0, 0, 0},
|
||||||
|
{ XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0, 0},
|
||||||
|
{ XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0, 0},
|
||||||
|
{ XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0, 0},
|
||||||
|
{ XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0, 0},
|
||||||
|
{ XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0, 0},
|
||||||
|
{ XK_F3, XK_NO_MOD, "\033OR" , 0, 0, 0},
|
||||||
|
{ XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0, 0},
|
||||||
|
{ XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0, 0},
|
||||||
|
{ XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0, 0},
|
||||||
|
{ XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0, 0},
|
||||||
|
{ XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0, 0},
|
||||||
|
{ XK_F4, XK_NO_MOD, "\033OS" , 0, 0, 0},
|
||||||
|
{ XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0, 0},
|
||||||
|
{ XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0, 0},
|
||||||
|
{ XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0, 0},
|
||||||
|
{ XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0, 0},
|
||||||
|
{ XK_F5, XK_NO_MOD, "\033[15~", 0, 0, 0},
|
||||||
|
{ XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0, 0},
|
||||||
|
{ XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0, 0},
|
||||||
|
{ XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0, 0},
|
||||||
|
{ XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0, 0},
|
||||||
|
{ XK_F6, XK_NO_MOD, "\033[17~", 0, 0, 0},
|
||||||
|
{ XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0, 0},
|
||||||
|
{ XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0, 0},
|
||||||
|
{ XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0, 0},
|
||||||
|
{ XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0, 0},
|
||||||
|
{ XK_F7, XK_NO_MOD, "\033[18~", 0, 0, 0},
|
||||||
|
{ XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0, 0},
|
||||||
|
{ XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0, 0},
|
||||||
|
{ XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0, 0},
|
||||||
|
{ XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0, 0},
|
||||||
|
{ XK_F8, XK_NO_MOD, "\033[19~", 0, 0, 0},
|
||||||
|
{ XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0, 0},
|
||||||
|
{ XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0, 0},
|
||||||
|
{ XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0, 0},
|
||||||
|
{ XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0, 0},
|
||||||
|
{ XK_F9, XK_NO_MOD, "\033[20~", 0, 0, 0},
|
||||||
|
{ XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0, 0},
|
||||||
|
{ XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0, 0},
|
||||||
|
{ XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0, 0},
|
||||||
|
{ XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0, 0},
|
||||||
|
{ XK_F10, XK_NO_MOD, "\033[21~", 0, 0, 0},
|
||||||
|
{ XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0, 0},
|
||||||
|
{ XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0, 0},
|
||||||
|
{ XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0, 0},
|
||||||
|
{ XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0, 0},
|
||||||
|
{ XK_F11, XK_NO_MOD, "\033[23~", 0, 0, 0},
|
||||||
|
{ XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0, 0},
|
||||||
|
{ XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0, 0},
|
||||||
|
{ XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0, 0},
|
||||||
|
{ XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0, 0},
|
||||||
|
{ XK_F12, XK_NO_MOD, "\033[24~", 0, 0, 0},
|
||||||
|
{ XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0, 0},
|
||||||
|
{ XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0, 0},
|
||||||
|
{ XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0, 0},
|
||||||
|
{ XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0, 0},
|
||||||
|
{ XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0, 0},
|
||||||
|
{ XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0, 0},
|
||||||
|
{ XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0, 0},
|
||||||
|
{ XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0, 0},
|
||||||
|
{ XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0, 0},
|
||||||
|
{ XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0, 0},
|
||||||
|
{ XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0, 0},
|
||||||
|
{ XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0, 0},
|
||||||
|
{ XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0, 0},
|
||||||
|
{ XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0, 0},
|
||||||
|
{ XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0, 0},
|
||||||
|
{ XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0, 0},
|
||||||
|
{ XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0, 0},
|
||||||
|
{ XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0, 0},
|
||||||
|
{ XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0, 0},
|
||||||
|
{ XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0, 0},
|
||||||
|
{ XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0, 0},
|
||||||
|
{ XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0, 0},
|
||||||
|
{ XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0, 0},
|
||||||
|
{ XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0, 0},
|
||||||
|
{ XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0, 0},
|
||||||
|
{ XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0, 0},
|
||||||
|
{ XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Selection types' masks.
|
||||||
|
* Use the same masks as usual.
|
||||||
|
* Button1Mask is always unset, to make masks match between ButtonPress.
|
||||||
|
* ButtonRelease and MotionNotify.
|
||||||
|
* If no match is found, regular selection is used.
|
||||||
|
*/
|
||||||
|
static uint selmasks[] = {
|
||||||
|
[SEL_RECTANGULAR] = Mod1Mask,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Printable characters in ASCII, used to estimate the advance width
|
||||||
|
* of single wide characters.
|
||||||
|
*/
|
||||||
|
static char ascii_printable[] =
|
||||||
|
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||||
|
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||||
|
"`abcdefghijklmnopqrstuvwxyz{|}~";
|
18
home-common/graphical/st/default.nix
Normal file
18
home-common/graphical/st/default.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
pkgs: colors:
|
||||||
|
let
|
||||||
|
openUrlCmd = pkgs.writeScript "openUrlCmd" ''
|
||||||
|
${pkgs.xurls}/bin/xurls | ${pkgs.rofi}/bin/rofi -dmenu | xargs -r ${pkgs.firefox}/bin/firefox
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
pkgs.st.overrideDerivation (old: {
|
||||||
|
patches = old.patches ++ [
|
||||||
|
# scrollback patches from https://st.suckless.org/patches/scrollback/
|
||||||
|
# https://st.suckless.org/patches/scrollback/st-scrollback-0.7.diff
|
||||||
|
./st-alpha-0.7.diff
|
||||||
|
./st-externalpipe-0.7.diff
|
||||||
|
];
|
||||||
|
enableParallelBuilds = true;
|
||||||
|
prePatch = ''
|
||||||
|
cp ${(pkgs.substituteAll { src = ./config.h; inherit openUrlCmd; inherit (colors) black brightBlack red brightRed green brightGreen yellow brightYellow blue brightBlue magenta brightMagenta cyan brightCyan white brightWhite background foreground;})} config.h
|
||||||
|
'';
|
||||||
|
})
|
188
home-common/graphical/st/st-alpha-0.7.diff
Normal file
188
home-common/graphical/st/st-alpha-0.7.diff
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index b41747f..e22ebd2 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -82,6 +82,9 @@ static char termname[] = "st-256color";
|
||||||
|
*/
|
||||||
|
static unsigned int tabspaces = 8;
|
||||||
|
|
||||||
|
+/* bg opacity */
|
||||||
|
+static const int alpha = 0xdd;
|
||||||
|
+
|
||||||
|
/* Terminal colors (16 first used in escape sequence) */
|
||||||
|
static const char *colorname[] = {
|
||||||
|
/* 8 normal colors */
|
||||||
|
@@ -109,6 +112,7 @@ static const char *colorname[] = {
|
||||||
|
/* more colors can be added after 255 to use with DefaultXX */
|
||||||
|
"#cccccc",
|
||||||
|
"#555555",
|
||||||
|
+ "black",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -117,7 +121,7 @@ static const char *colorname[] = {
|
||||||
|
* foreground, background, cursor, reverse cursor
|
||||||
|
*/
|
||||||
|
static unsigned int defaultfg = 7;
|
||||||
|
-static unsigned int defaultbg = 0;
|
||||||
|
+static unsigned int defaultbg = 257;
|
||||||
|
static unsigned int defaultcs = 256;
|
||||||
|
static unsigned int defaultrcs = 257;
|
||||||
|
|
||||||
|
diff --git a/config.mk b/config.mk
|
||||||
|
index c84c5ee..19a03bb 100644
|
||||||
|
--- a/config.mk
|
||||||
|
+++ b/config.mk
|
||||||
|
@@ -14,7 +14,7 @@ X11LIB = /usr/X11R6/lib
|
||||||
|
INCS = -I. -I/usr/include -I${X11INC} \
|
||||||
|
`pkg-config --cflags fontconfig` \
|
||||||
|
`pkg-config --cflags freetype2`
|
||||||
|
-LIBS = -L/usr/lib -lc -L${X11LIB} -lm -lrt -lX11 -lutil -lXft \
|
||||||
|
+LIBS = -L/usr/lib -lc -L${X11LIB} -lm -lrt -lX11 -lutil -lXext -lXft -lXrender\
|
||||||
|
`pkg-config --libs fontconfig` \
|
||||||
|
`pkg-config --libs freetype2`
|
||||||
|
|
||||||
|
diff --git a/st.c b/st.c
|
||||||
|
index 2594c65..f9ba75b 100644
|
||||||
|
--- a/st.c
|
||||||
|
+++ b/st.c
|
||||||
|
@@ -61,6 +61,7 @@ char *argv0;
|
||||||
|
#define XK_ANY_MOD UINT_MAX
|
||||||
|
#define XK_NO_MOD 0
|
||||||
|
#define XK_SWITCH_MOD (1<<13)
|
||||||
|
+#define OPAQUE 0Xff
|
||||||
|
|
||||||
|
/* macros */
|
||||||
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
@@ -81,6 +82,8 @@ char *argv0;
|
||||||
|
(t1.tv_nsec-t2.tv_nsec)/1E6)
|
||||||
|
#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
|
||||||
|
|
||||||
|
+#define USE_ARGB (alpha != OPAQUE && opt_embed == NULL)
|
||||||
|
+
|
||||||
|
#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b))
|
||||||
|
#define IS_TRUECOL(x) (1 << 24 & (x))
|
||||||
|
#define TRUERED(x) (((x) & 0xff0000) >> 8)
|
||||||
|
@@ -268,6 +271,7 @@ typedef struct {
|
||||||
|
int w, h; /* window width and height */
|
||||||
|
int ch; /* char height */
|
||||||
|
int cw; /* char width */
|
||||||
|
+ int depth; /* bit depth */
|
||||||
|
char state; /* focus, redraw, visible */
|
||||||
|
int cursor; /* cursor style */
|
||||||
|
} XWindow;
|
||||||
|
@@ -3137,7 +3141,7 @@ xresize(int col, int row)
|
||||||
|
|
||||||
|
XFreePixmap(xw.dpy, xw.buf);
|
||||||
|
xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h,
|
||||||
|
- DefaultDepth(xw.dpy, xw.scr));
|
||||||
|
+ xw.depth);
|
||||||
|
XftDrawChange(xw.draw, xw.buf);
|
||||||
|
xclear(0, 0, xw.w, xw.h);
|
||||||
|
}
|
||||||
|
@@ -3191,6 +3195,14 @@ xloadcols(void)
|
||||||
|
else
|
||||||
|
die("Could not allocate color %d\n", i);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /* set alpha value of bg color */
|
||||||
|
+ if (USE_ARGB) {
|
||||||
|
+ dc.col[defaultbg].color.alpha = (0xffff * alpha) / OPAQUE; //0xcccc;
|
||||||
|
+ dc.col[defaultbg].pixel &= 0x00111111;
|
||||||
|
+ dc.col[defaultbg].pixel |= alpha << 24; // 0xcc000000;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
loaded = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3212,6 +3224,16 @@ xsetcolorname(int x, const char *name)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+xtermclear(int col1, int row1, int col2, int row2) {
|
||||||
|
+ XftDrawRect(xw.draw,
|
||||||
|
+ &dc.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg],
|
||||||
|
+ borderpx + col1 * xw.cw,
|
||||||
|
+ borderpx + row1 * xw.ch,
|
||||||
|
+ (col2-col1+1) * xw.cw,
|
||||||
|
+ (row2-row1+1) * xw.ch);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Absolute coordinates.
|
||||||
|
*/
|
||||||
|
@@ -3443,7 +3465,38 @@ xinit(void)
|
||||||
|
if (!(xw.dpy = XOpenDisplay(NULL)))
|
||||||
|
die("Can't open display\n");
|
||||||
|
xw.scr = XDefaultScreen(xw.dpy);
|
||||||
|
- xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
||||||
|
+ xw.depth = (USE_ARGB) ? 32: XDefaultDepth(xw.dpy, xw.scr);
|
||||||
|
+ if (! USE_ARGB)
|
||||||
|
+ xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
||||||
|
+ else {
|
||||||
|
+ XVisualInfo *vis;
|
||||||
|
+ XRenderPictFormat *fmt;
|
||||||
|
+ int nvi;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ XVisualInfo tpl = {
|
||||||
|
+ .screen = xw.scr,
|
||||||
|
+ .depth = 32,
|
||||||
|
+ .class = TrueColor
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ vis = XGetVisualInfo(xw.dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &tpl, &nvi);
|
||||||
|
+ xw.vis = NULL;
|
||||||
|
+ for(i = 0; i < nvi; i ++) {
|
||||||
|
+ fmt = XRenderFindVisualFormat(xw.dpy, vis[i].visual);
|
||||||
|
+ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
|
||||||
|
+ xw.vis = vis[i].visual;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ XFree(vis);
|
||||||
|
+
|
||||||
|
+ if (! xw.vis) {
|
||||||
|
+ fprintf(stderr, "Couldn't find ARGB visual.\n");
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* font */
|
||||||
|
if (!FcInit())
|
||||||
|
@@ -3453,7 +3506,10 @@ xinit(void)
|
||||||
|
xloadfonts(usedfont, 0);
|
||||||
|
|
||||||
|
/* colors */
|
||||||
|
- xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
|
||||||
|
+ if (! USE_ARGB)
|
||||||
|
+ xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
|
||||||
|
+ else
|
||||||
|
+ xw.cmap = XCreateColormap(xw.dpy, XRootWindow(xw.dpy, xw.scr), xw.vis, None);
|
||||||
|
xloadcols();
|
||||||
|
|
||||||
|
/* adjust fixed window geometry */
|
||||||
|
@@ -3476,16 +3532,17 @@ xinit(void)
|
||||||
|
if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
|
||||||
|
parent = XRootWindow(xw.dpy, xw.scr);
|
||||||
|
xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
|
||||||
|
- xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
|
||||||
|
+ xw.w, xw.h, 0, xw.depth, InputOutput,
|
||||||
|
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
||||||
|
| CWEventMask | CWColormap, &xw.attrs);
|
||||||
|
|
||||||
|
memset(&gcvalues, 0, sizeof(gcvalues));
|
||||||
|
gcvalues.graphics_exposures = False;
|
||||||
|
- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
|
||||||
|
+ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth);
|
||||||
|
+ dc.gc = XCreateGC(xw.dpy,
|
||||||
|
+ (USE_ARGB)? xw.buf: parent,
|
||||||
|
+ GCGraphicsExposures,
|
||||||
|
&gcvalues);
|
||||||
|
- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h,
|
||||||
|
- DefaultDepth(xw.dpy, xw.scr));
|
||||||
|
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
|
||||||
|
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h);
|
||||||
|
|
90
home-common/graphical/st/st-externalpipe-0.7.diff
Normal file
90
home-common/graphical/st/st-externalpipe-0.7.diff
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
diff --git a/st.c b/st.c
|
||||||
|
index 2594c65..ecd9bdc 100644
|
||||||
|
--- a/st.c
|
||||||
|
+++ b/st.c
|
||||||
|
@@ -329,6 +329,7 @@ static void clipcopy(const Arg *);
|
||||||
|
static void clippaste(const Arg *);
|
||||||
|
static void numlock(const Arg *);
|
||||||
|
static void selpaste(const Arg *);
|
||||||
|
+static void externalpipe(const Arg *);
|
||||||
|
static void xzoom(const Arg *);
|
||||||
|
static void xzoomabs(const Arg *);
|
||||||
|
static void xzoomreset(const Arg *);
|
||||||
|
@@ -337,6 +338,9 @@ static void printscreen(const Arg *) ;
|
||||||
|
static void toggleprinter(const Arg *);
|
||||||
|
static void sendbreak(const Arg *);
|
||||||
|
|
||||||
|
+/* variables used in config.h */
|
||||||
|
+static char winid[64];
|
||||||
|
+
|
||||||
|
/* Config.h for applying patches and the configuration. */
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
@@ -2922,6 +2926,59 @@ eschandle(uchar ascii)
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
+externalpipe(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ int to[2];
|
||||||
|
+ char buf[UTF_SIZ];
|
||||||
|
+ void (*oldsigpipe)(int);
|
||||||
|
+ Glyph *bp, *end;
|
||||||
|
+ int lastpos, n, newline;
|
||||||
|
+
|
||||||
|
+ if (pipe(to) == -1)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ switch (fork()) {
|
||||||
|
+ case -1:
|
||||||
|
+ close(to[0]);
|
||||||
|
+ close(to[1]);
|
||||||
|
+ return;
|
||||||
|
+ case 0:
|
||||||
|
+ dup2(to[0], STDIN_FILENO);
|
||||||
|
+ close(to[0]);
|
||||||
|
+ close(to[1]);
|
||||||
|
+ execvp(((char **)arg->v)[0], (char **)arg->v);
|
||||||
|
+ fprintf(stderr, "st: execvp %s ", ((char **)arg->v)[0]);
|
||||||
|
+ perror("failed");
|
||||||
|
+ exit(0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ close(to[0]);
|
||||||
|
+ /* ignore sigpipe for now, in case child exits early */
|
||||||
|
+ oldsigpipe = signal(SIGPIPE, SIG_IGN);
|
||||||
|
+ newline = 0;
|
||||||
|
+ for (n = 0; n < term.row; n++) {
|
||||||
|
+ bp = term.line[n];
|
||||||
|
+ lastpos = MIN(tlinelen(n) + 1, term.col) - 1;
|
||||||
|
+ if (lastpos < 0)
|
||||||
|
+ break;
|
||||||
|
+ end = &bp[lastpos + 1];
|
||||||
|
+ for (; bp < end; ++bp)
|
||||||
|
+ if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
|
||||||
|
+ break;
|
||||||
|
+ if ((newline = term.line[n][lastpos].mode & ATTR_WRAP))
|
||||||
|
+ continue;
|
||||||
|
+ if (xwrite(to[1], "\n", 1) < 0)
|
||||||
|
+ break;
|
||||||
|
+ newline = 0;
|
||||||
|
+ }
|
||||||
|
+ if (newline)
|
||||||
|
+ (void)xwrite(to[1], "\n", 1);
|
||||||
|
+ close(to[1]);
|
||||||
|
+ /* restore */
|
||||||
|
+ signal(SIGPIPE, oldsigpipe);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
tputc(Rune u)
|
||||||
|
{
|
||||||
|
char c[UTF_SIZ];
|
||||||
|
@@ -3479,6 +3536,7 @@ xinit(void)
|
||||||
|
xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
|
||||||
|
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
||||||
|
| CWEventMask | CWColormap, &xw.attrs);
|
||||||
|
+ snprintf(winid, LEN(winid), "%lu", (unsigned long)xw.win);
|
||||||
|
|
||||||
|
memset(&gcvalues, 0, sizeof(gcvalues));
|
||||||
|
gcvalues.graphics_exposures = False;
|
|
@ -60,6 +60,9 @@
|
||||||
Notification = {
|
Notification = {
|
||||||
Text = template;
|
Text = template;
|
||||||
};
|
};
|
||||||
|
NotificationBubble = {
|
||||||
|
Queue = "tasks";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
|
|
34
homes/apollo/battery.nix
Normal file
34
homes/apollo/battery.nix
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{pkgs, ... }:
|
||||||
|
let
|
||||||
|
battery-watch = pkgs.writeShellScriptBin "battery-watch" ''
|
||||||
|
critical_level=20 #percent
|
||||||
|
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
if [ "$(${pkgs.acpi}/bin/acpi -a | grep -o off)" == "off" ]; then
|
||||||
|
battery_level=`${pkgs.acpi}/bin/acpi -b | sed 's/.*[dg], //g;s/\%,.*//g'`
|
||||||
|
if [ $battery_level -le $critical_level ]; then
|
||||||
|
${pkgs.eventd}/bin/eventc critical battery -d "title='Battery level is low!'" -d "message='Only $battery_level% of the charge remains.'"
|
||||||
|
else
|
||||||
|
${pkgs.eventd}/bin/eventc notification battery -d "title='Battery is discharging!'" -d "message='Only $battery_level% of the charge remains.'"
|
||||||
|
sleep 18m
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
sleep 2m
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
systemd.user = {
|
||||||
|
services.battery = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Watch battery state and warn user";
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart="/bin/sh ${battery-watch}/bin/battery-watch";
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,4 +1,19 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
jali = with pkgs.python36Packages; buildPythonApplication rec {
|
||||||
|
name = "${pname}-${version}";
|
||||||
|
pname = "jali";
|
||||||
|
doCheck = false;
|
||||||
|
version = "1d1c5d0a";
|
||||||
|
src = pkgs.fetchgit {
|
||||||
|
url = "https://git.darmstadt.ccc.de/jali/jali.git";
|
||||||
|
rev = version;
|
||||||
|
sha256 = "1nzzangp7yr2gq66qz7wk2cqqwjlhrfaqmc85qigjv4vpfmlphl0";
|
||||||
|
};
|
||||||
|
propagatedBuildInputs = with pkgs; [ jinja2 pendulum GitPython aqbanking ];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -6,6 +21,8 @@
|
||||||
../../home-common/my-systems.nix
|
../../home-common/my-systems.nix
|
||||||
../../home-common/graphical
|
../../home-common/graphical
|
||||||
../../home-common/latex.nix
|
../../home-common/latex.nix
|
||||||
|
./battery.nix
|
||||||
|
./sleep-nag.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
|
@ -19,6 +36,9 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
home.sessionVariables = {
|
||||||
|
MOZ_USE_XINPUT2 = "1";
|
||||||
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
udiskie = {
|
udiskie = {
|
||||||
|
@ -32,14 +52,31 @@
|
||||||
] ++ (with pkgs; [
|
] ++ (with pkgs; [
|
||||||
# web
|
# web
|
||||||
chromium
|
chromium
|
||||||
|
signal-desktop
|
||||||
|
tdesktop
|
||||||
acpi
|
acpi
|
||||||
|
dino
|
||||||
|
|
||||||
|
rustracer
|
||||||
|
|
||||||
arandr
|
arandr
|
||||||
qutebrowser
|
qutebrowser
|
||||||
|
|
||||||
mumble
|
mumble
|
||||||
|
|
||||||
|
xorg.xev
|
||||||
|
xorg.xbacklight
|
||||||
|
meld
|
||||||
|
|
||||||
|
icedtea8_web
|
||||||
|
|
||||||
|
hledger
|
||||||
|
haskellPackages.hledger-ui
|
||||||
|
ledger
|
||||||
|
jali
|
||||||
|
|
||||||
# tools & office
|
# tools & office
|
||||||
|
feh
|
||||||
gimp
|
gimp
|
||||||
imagemagick
|
imagemagick
|
||||||
libreoffice-fresh
|
libreoffice-fresh
|
||||||
|
|
26
homes/apollo/sleep-nag.nix
Normal file
26
homes/apollo/sleep-nag.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{pkgs, ... }:
|
||||||
|
let
|
||||||
|
sleep-nag = pkgs.writeShellScriptBin "sleep-nag" ''
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
if [[ `date +%H` -ge 23 ]] || [[ `date +%H` -lt 6 ]]; then
|
||||||
|
${pkgs.eventd}/bin/eventc notification kassandra -d "title='Es ist $(date +%H:%M) Uhr: Zeit ins Bett zu gehen!'" -d "message='Du kannst das hier auch morgen tun!'"
|
||||||
|
fi
|
||||||
|
sleep 10m
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
systemd.user = {
|
||||||
|
services.sleep-nag = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Sleep nag";
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart="/bin/sh ${sleep-nag}/bin/sleep-nag";
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
83
homes/charon/dovecot.sieve
Normal file
83
homes/charon/dovecot.sieve
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
require ["vnd.dovecot.duplicate", "fileinto", "regex", "imap4flags", "mailbox"];
|
||||||
|
|
||||||
|
if header :regex "X-spamd-result" "st-ludwig-darmstadt.de" {
|
||||||
|
keep;
|
||||||
|
}
|
||||||
|
elsif anyof (
|
||||||
|
header :regex "X-spam" "^yes$",
|
||||||
|
header :contains "From" "paypal@mail.paypal.de",
|
||||||
|
header :contains "To" "lac@maralorn.de",
|
||||||
|
header :contains "To" "malte@maralorn.de",
|
||||||
|
header :contains "To" "maltemail@maralorn.de",
|
||||||
|
header :contains "To" "mail@maralorn.de",
|
||||||
|
header :contains "From" "promotion5@amazon.de")
|
||||||
|
{
|
||||||
|
setflag "\\Seen";
|
||||||
|
fileinto "Spam";
|
||||||
|
}
|
||||||
|
elsif anyof (
|
||||||
|
duplicate
|
||||||
|
) {
|
||||||
|
setflag "\\Seen";
|
||||||
|
fileinto "Trash";
|
||||||
|
}
|
||||||
|
elsif anyof (
|
||||||
|
address :domain :is "From" [
|
||||||
|
"maralorn.de",
|
||||||
|
"facebookmail.com"
|
||||||
|
],
|
||||||
|
address :domain :is "From" [
|
||||||
|
"tickets.darmstadt.ccc.de"
|
||||||
|
],
|
||||||
|
header :contains "List-Id" [
|
||||||
|
"hackspace.lists.darmstadt.ccc.de",
|
||||||
|
"members.lists.darmstadt.ccc.de",
|
||||||
|
"darmstadt.lists.darmstadt.ccc.de"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
{
|
||||||
|
setflag "\\Seen";
|
||||||
|
}
|
||||||
|
elsif anyof (
|
||||||
|
header :is "From" "vib@vereinsknowhow.de",
|
||||||
|
address :domain :is "From" [
|
||||||
|
"dpg-physik.de",
|
||||||
|
"physikstudenten.de"
|
||||||
|
],
|
||||||
|
header :contains "List-Id" [
|
||||||
|
"intern.lists.ccc.de",
|
||||||
|
"erfa.lists.ccc.de",
|
||||||
|
"ctf-announce.lists.cased.de",
|
||||||
|
"ctf-team.lists.cased.de",
|
||||||
|
"darmstadt-freifunk.net"
|
||||||
|
],
|
||||||
|
header :contains "Subject" "Moodle TU Darmstadt: Zusammenfassung des Forums"
|
||||||
|
)
|
||||||
|
{
|
||||||
|
setflag "\\Seen";
|
||||||
|
fileinto :create "Move.readlater";
|
||||||
|
}
|
||||||
|
elsif header :contains ["To", "From", "CC"] [
|
||||||
|
"noc@karlshof.de",
|
||||||
|
"karlshof@whm.stwda.de",
|
||||||
|
"noc-karlshof@maralorn.de"
|
||||||
|
]
|
||||||
|
{
|
||||||
|
setflag "\\Seen";
|
||||||
|
fileinto :create "Archiv.karlshof.noc";
|
||||||
|
}
|
||||||
|
|
||||||
|
elsif header :contains "List-Id" "chor.lists.tu-darmstadt.de" {
|
||||||
|
setflag "\\Seen";
|
||||||
|
fileinto :create "Archiv.tuchor";
|
||||||
|
}
|
||||||
|
elsif header :contains "From" "kdwachlin@web.de" {
|
||||||
|
setflag "\\Seen";
|
||||||
|
fileinto "Archiv.unsortiert";
|
||||||
|
}
|
||||||
|
elsif header :contains "Subject" "[VED-Wiki]" {
|
||||||
|
setflag "\\Seen";
|
||||||
|
fileinto :create "Archiv.ved.wiki";
|
||||||
|
} elsif header :regex "X-spamd-result" "[2-5]\.[0-9]\{2\} / 15\.00" {
|
||||||
|
setflag "\\Seen";
|
||||||
|
}
|
|
@ -1,9 +1,16 @@
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
../../snippets/everywhere.nix
|
../../home-common/default.nix
|
||||||
../../snippets/my-systems.nix
|
../../home-common/my-systems.nix
|
||||||
./morgenreport.nix
|
./morgenreport.nix
|
||||||
./sort-mail.nix
|
./sort-mail.nix
|
||||||
./habitask.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
home.forceCopies.paths = [ ".dovecot.sieve" ];
|
||||||
|
home.file = {
|
||||||
|
sieve-rules = {
|
||||||
|
target = ".dovecot.sieve";
|
||||||
|
text = builtins.readFile ./dovecot.sieve;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
let
|
||||||
|
morgenreport-script = pkgs.writeShellScriptBin "morgenreport" ''
|
||||||
|
cd $HOME/data/aktuell/media/ebooks/morgenreport/
|
||||||
|
DATE=`date +%Y-%m-%d`
|
||||||
|
PATH=$PATH:/run/wrappers/bin/
|
||||||
|
PATH=$PATH:${pkgs.imagemagickBig}/bin
|
||||||
|
PATH=$PATH:${pkgs.qt5.qtbase}/bin
|
||||||
|
PATH=$PATH:${pkgs.qt5.qtsvg}/bin
|
||||||
|
${pkgs.calibre}/bin/ebook-convert $HOME/data/aktuell/it/code/calibre-recipes/morgenreport.recipe morgenreport-$DATE.mobi --output-profile=kindle_pw3
|
||||||
|
echo "File created, sending to kindle now …"
|
||||||
|
echo 'Siehe Anhang' | ${pkgs.mutt}/bin/mutt -s "Morgenreport $DATE" -a morgenreport-$DATE.mobi -- maralorn@kindle.com
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
home.packages = [ morgenreport-script];
|
||||||
systemd.user = {
|
systemd.user = {
|
||||||
services.morgenreport =
|
services.morgenreport = {
|
||||||
let
|
|
||||||
morgenreport-script = pkgs.writeShellScriptBin "morgenreport" ''
|
|
||||||
cd $HOME/data/aktuell/media/ebooks/morgenreport/
|
|
||||||
DATE=`date +%Y-%m-%d`
|
|
||||||
${pkgs.calibre}/bin/ebook-convert $HOME/data/aktuell/it/code/calibre-recipes/morgenreport.recipe morgenreport-$DATE.mobi --output-profile=kindle_pw3
|
|
||||||
echo "File created, sending to kindle now …"
|
|
||||||
PATH=$PATH:/run/wrappers/bin/
|
|
||||||
echo 'Siehe Anhang' | ${pkgs.mutt}/bin/mutt -s "Morgenreport $DATE" -a morgenreport-$DATE.mobi -- maralorn@kindle.com
|
|
||||||
'';
|
|
||||||
in {
|
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = "Send morgenreport to kindle";
|
Description = "Send morgenreport to kindle";
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
automatic = true;
|
automatic = true;
|
||||||
options = "--delete-older-than 5d";
|
options = "--delete-older-than 5d";
|
||||||
};
|
};
|
||||||
package = pkgs.nixUnstable;
|
|
||||||
optimise.automatic = true;
|
optimise.automatic = true;
|
||||||
};
|
};
|
||||||
system.autoUpgrade.enable = true;
|
system.autoUpgrade.enable = true;
|
||||||
|
@ -32,6 +31,10 @@
|
||||||
mutableUsers = false;
|
mutableUsers = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
security.sudo.extraConfig = "
|
||||||
|
Defaults timestamp_type=global, timestamp_timeout=15
|
||||||
|
";
|
||||||
|
|
||||||
networking.firewall.allowPing = true;
|
networking.firewall.allowPing = true;
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
|
@ -44,7 +47,6 @@
|
||||||
gnumake
|
gnumake
|
||||||
python3
|
python3
|
||||||
python
|
python
|
||||||
pandoc
|
|
||||||
mkpasswd
|
mkpasswd
|
||||||
rxvt_unicode.terminfo
|
rxvt_unicode.terminfo
|
||||||
htop
|
htop
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
hostName = "charon.olymp.space";
|
hostName = "charon.olymp.space";
|
||||||
|
|
||||||
interfaces.ens3 = {
|
interfaces.ens3 = {
|
||||||
ip4 = [ { address = "45.32.154.139"; prefixLength = 22; } ];
|
ipv4.addresses = [{ address = "45.32.154.139"; prefixLength = 22; }];
|
||||||
ip6 = [ { address = "2001:19f0:6c01:b0d::1"; prefixLength = 64; } ];
|
ipv6.addresses = [{ address = "2001:19f0:6c01:b0d::1"; prefixLength = 64; }];
|
||||||
};
|
};
|
||||||
defaultGateway = "45.32.152.1";
|
defaultGateway = "45.32.152.1";
|
||||||
nameservers = [ "108.61.10.10" "2001:19f0:300:1704::6" ];
|
nameservers = [ "108.61.10.10" "2001:19f0:300:1704::6" ];
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
socketActivation = false;
|
socketActivation = false;
|
||||||
rspamd = {
|
rspamd = {
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
extended_spam_headers = yes;
|
extended_spam_headers = true;
|
||||||
'';
|
'';
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
@ -45,6 +45,8 @@
|
||||||
sslServerKey = "/var/lib/acme/charon.olymp.space/key.pem";
|
sslServerKey = "/var/lib/acme/charon.olymp.space/key.pem";
|
||||||
extraConfig =
|
extraConfig =
|
||||||
''
|
''
|
||||||
|
postmaster_address=postmaster@charon.olymp.space
|
||||||
|
|
||||||
ssl = required
|
ssl = required
|
||||||
service auth {
|
service auth {
|
||||||
unix_listener /var/lib/postfix/queue/private/auth {
|
unix_listener /var/lib/postfix/queue/private/auth {
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
server_name = "maralorn.de";
|
server_name = "maralorn.de";
|
||||||
database_type = "psycopg2";
|
database_type = "psycopg2";
|
||||||
max_upload_size = "30M";
|
max_upload_size = "30M";
|
||||||
|
create_local_database = false;
|
||||||
database_args = {
|
database_args = {
|
||||||
user = "matrix-synapse";
|
user = "matrix-synapse";
|
||||||
database = "matrix-synapse";
|
database = "matrix-synapse";
|
||||||
|
|
40
modules/mpd.nix
Normal file
40
modules/mpd.nix
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
mpd = {
|
||||||
|
mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.user = {
|
||||||
|
services.morgenreport =
|
||||||
|
let
|
||||||
|
morgenreport-script = pkgs.writeShellScriptBin "morgenreport" ''
|
||||||
|
cd $HOME/data/aktuell/media/ebooks/morgenreport/
|
||||||
|
DATE=`date +%Y-%m-%d`
|
||||||
|
${pkgs.calibre}/bin/ebook-convert $HOME/data/aktuell/it/code/calibre-recipes/morgenreport.recipe morgenreport-$DATE.mobi --output-profile=kindle_pw3
|
||||||
|
echo "File created, sending to kindle now …"
|
||||||
|
PATH=$PATH:/run/wrappers/bin/
|
||||||
|
echo 'Siehe Anhang' | ${pkgs.mutt}/bin/mutt -s "Morgenreport $DATE" -a morgenreport-$DATE.mobi -- maralorn@kindle.com
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
Unit = {
|
||||||
|
Description = "Send morgenreport to kindle";
|
||||||
|
};
|
||||||
|
|
||||||
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart="/bin/sh ${morgenreport-script}/bin/morgenreport";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
timers.morgenreport = {
|
||||||
|
Timer = {
|
||||||
|
OnCalendar = "20:00";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
{ fetchFromGitHub, stdenv, ninja, meson, pkgconfig, glib, cairo, gdk_pixbuf, glib_networking, pango, libudev, xorg, libxslt, docbook_xml_xslt, git, libuuid, dbus, libsoup, docbook_xml_dtd_45, docbook5_xsl, gettext, autoconf, libtool, utillinux, libxkbcommon }:
|
{ fetchFromGitHub, stdenv, ninja, meson, pkgconfig, glib, cairo, gdk_pixbuf, glib_networking, pango, libudev, xorg, libxslt, docbook_xml_xslt, git, libuuid, dbus, libsoup, docbook_xml_dtd_45, docbook5_xsl, gettext, autoconf, libtool, utillinux, libxkbcommon }:
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
name = "eventd";
|
name = "eventd";
|
||||||
version = "279d3c3";
|
version = "v0.24.1";
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "sardemff7";
|
owner = "sardemff7";
|
||||||
repo = "eventd";
|
repo = "eventd";
|
||||||
|
@ -9,9 +9,6 @@ stdenv.mkDerivation rec {
|
||||||
sha256 = "162gr3agmjn6d0wdj3lixv8qfvgfm9qg3wphbvwywdp4qcwvnjz8";
|
sha256 = "162gr3agmjn6d0wdj3lixv8qfvgfm9qg3wphbvwywdp4qcwvnjz8";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
patchPhase = ''
|
|
||||||
sed s/0.44.1/0.43.0/ -i meson.build
|
|
||||||
'';
|
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
ninja
|
ninja
|
||||||
meson
|
meson
|
||||||
|
|
193
packages/rust-scripts/Cargo.lock
generated
193
packages/rust-scripts/Cargo.lock
generated
|
@ -1,12 +1,12 @@
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.6"
|
version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ name = "backtrace-sys"
|
||||||
version = "0.1.16"
|
version = "0.1.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -26,17 +26,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.0.1"
|
version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.10"
|
version = "1.0.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -44,9 +44,9 @@ name = "chrono"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -71,7 +71,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dialog"
|
name = "dialog"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.darmstadt.ccc.de/maralorn/dialog-rs.git#f33f0c9ac4f4407899da55507147a8a808e2f521"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustyline 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustyline 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -93,7 +92,7 @@ name = "error-chain"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -101,7 +100,7 @@ name = "fuchsia-zircon"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -110,11 +109,30 @@ name = "fuchsia-zircon-sys"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iso8601"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kairos"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"iso8601 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel32-sys"
|
name = "kernel32-sys"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -124,17 +142,35 @@ dependencies = [
|
||||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.40"
|
version = "0.2.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked-hash-map"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -147,21 +183,29 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "nom"
|
||||||
version = "0.1.36"
|
version = "3.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.38"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.2"
|
version = "0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "0.3.6"
|
version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -177,7 +221,7 @@ name = "quote"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -199,13 +243,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
name = "rust-scripts"
|
name = "rust-scripts"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dialog 0.1.0 (git+https://git.darmstadt.ccc.de/maralorn/dialog-rs.git)",
|
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"task-hookrs 0.5.0 (git+https://github.com/maralorn/task-hookrs.git?branch=preview)",
|
"dialog 0.1.0",
|
||||||
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"kairos 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_derive 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_yaml 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"task-hookrs 0.5.0",
|
||||||
|
"uuid 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -223,37 +275,38 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.42"
|
version = "1.0.55"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.42"
|
version = "1.0.55"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.13.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_derive_internals"
|
|
||||||
version = "0.23.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.16"
|
version = "1.0.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_yaml"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -268,10 +321,10 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "0.13.1"
|
version = "0.13.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -287,15 +340,14 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "task-hookrs"
|
name = "task-hookrs"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/maralorn/task-hookrs.git?branch=preview#24a3ad5519a9bb26fcf0eeee368f8899211e47e1"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"uuid 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"uuid 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -309,7 +361,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.39"
|
version = "0.1.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -337,9 +389,9 @@ name = "uuid"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -371,46 +423,58 @@ name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e"
|
"checksum backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea58cd16fd6c9d120b5bcb01d63883ae4cc7ba2aed35c1841b862a3c7ef6639"
|
||||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
||||||
"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3"
|
"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3"
|
||||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
|
||||||
"checksum cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8b9d2900f78631a5876dc5d6c9033ede027253efcd33dd36b1309fc6cab97ee0"
|
"checksum cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebb87d1116151416c0cf66a0e3fb6430cccd120fd6300794b4dfaa050ac40ba"
|
||||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
|
||||||
"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
|
"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
|
||||||
"checksum derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c998e6ab02a828dd9735c18f154e14100e674ed08cb4e1938f0e4177543f439"
|
"checksum derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c998e6ab02a828dd9735c18f154e14100e674ed08cb4e1938f0e4177543f439"
|
||||||
"checksum derive_builder_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "735e24ee9e5fa8e16b86da5007856e97d592e11867e45d76e0c0d0a164a0b757"
|
"checksum derive_builder_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "735e24ee9e5fa8e16b86da5007856e97d592e11867e45d76e0c0d0a164a0b757"
|
||||||
"checksum dialog 0.1.0 (git+https://git.darmstadt.ccc.de/maralorn/dialog-rs.git)" = "<none>"
|
|
||||||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
||||||
"checksum encode_unicode 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "28d65f1f5841ef7c6792861294b72beda34c664deb8be27970f36c306b7da1ce"
|
"checksum encode_unicode 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "28d65f1f5841ef7c6792861294b72beda34c664deb8be27970f36c306b7da1ce"
|
||||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||||
|
"checksum iso8601 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83e03bd24a535789afdce1c8274f2f5dc1a265c39e937884426ecd5322285d1e"
|
||||||
"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
|
"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
|
||||||
|
"checksum kairos 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4eb20c83592f59719373e14ef037aea9b09e11bc8b02e2f0ca2e9c8eeac6ba6b"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
|
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
|
||||||
"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
|
"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
|
||||||
|
"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e"
|
||||||
"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
|
"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
|
||||||
|
"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
|
||||||
"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79"
|
"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79"
|
||||||
"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe"
|
"checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b"
|
||||||
"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364"
|
"checksum num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac0ea58d64a89d9d6b7688031b3be9358d6c919badcf7fbb0527ccfd891ee45"
|
||||||
"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
|
"checksum num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775393e285254d2f5004596d69bb8bc1149754570dcc08cf30cabeba67955e28"
|
||||||
|
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
|
||||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||||
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
|
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
|
||||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||||
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
|
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
|
||||||
"checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb"
|
"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
|
||||||
"checksum rustyline 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00b06ac9c8e8e3e83b33d175d39a9f7b6c2c930c82990593719c8e48788ae2d9"
|
"checksum rustyline 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00b06ac9c8e8e3e83b33d175d39a9f7b6c2c930c82990593719c8e48788ae2d9"
|
||||||
"checksum serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)" = "a73973861352c932ed1365ce22b32467ce260ac4c8db11cf750ce56334ff2dcf"
|
"checksum serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "97f6a6c3caba0cf8f883b53331791036404ce3c1bd895961cf8bb2f8cecfd84b"
|
||||||
"checksum serde_derive 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b392c5a0cebb98121454531c50e60e2ffe0fbeb1a44da277da2d681d08d7dc0b"
|
"checksum serde_derive 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "f51b0ef935cf8a41a77bce553da1f8751a739b7ad82dd73669475a22e6ecedb0"
|
||||||
"checksum serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d30c4596450fd7bbda79ef15559683f9a79ac0193ea819db90000d7e1cae794"
|
"checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1"
|
||||||
"checksum serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6c4e049dc657a99e394bd85c22acbf97356feeec6dbf44150f2dcf79fb3118"
|
"checksum serde_yaml 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "107bb818146aaf922e7bbcf6a940f1db2f0dcf381779b451e400331b2c6f86db"
|
||||||
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
||||||
"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
|
"checksum syn 0.13.10 (registry+https://github.com/rust-lang/crates.io-index)" = "77961dcdac942fa8bc033c16f3a790b311c8a27d00811b878ebd8cf9b7ba39d5"
|
||||||
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
||||||
"checksum task-hookrs 0.5.0 (git+https://github.com/maralorn/task-hookrs.git?branch=preview)" = "<none>"
|
|
||||||
"checksum termios 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70226acdf12d182df757d9fb07c0257a1558ec48c8059f607d6b38145ce4e2fa"
|
"checksum termios 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70226acdf12d182df757d9fb07c0257a1558ec48c8059f607d6b38145ce4e2fa"
|
||||||
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
|
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
|
||||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
|
@ -420,3 +484,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
"checksum yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57ab38ee1a4a266ed033496cf9af1828d8d6e6c1cfa5f643a2809effcae4d628"
|
||||||
|
|
|
@ -4,5 +4,14 @@ version = "0.1.0"
|
||||||
authors = ["Malte Brandy <malte.brandy@maralorn.de>"]
|
authors = ["Malte Brandy <malte.brandy@maralorn.de>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
task-hookrs = { git = "https://github.com/maralorn/task-hookrs.git", branch = "preview"}
|
#task-hookrs = { git = "https://github.com/maralorn/task-hookrs.git", branch = "preview"}
|
||||||
dialog = { git = "https://git.darmstadt.ccc.de/maralorn/dialog-rs.git" }
|
task-hookrs = { path = "/home/maralorn/code/task-hookrs"}
|
||||||
|
dialog = { path = "/home/maralorn/code/dialog-rs" }
|
||||||
|
lazy_static = "1.0.0"
|
||||||
|
uuid = "0.6"
|
||||||
|
kairos = "0.1.0"
|
||||||
|
chrono = "0.4.2"
|
||||||
|
error-chain = "0.11.0"
|
||||||
|
serde_derive = "1.0"
|
||||||
|
serde = "1.0"
|
||||||
|
serde_yaml = "0.7"
|
||||||
|
|
|
@ -1,74 +1,162 @@
|
||||||
extern crate rust_scripts;
|
extern crate rust_scripts;
|
||||||
use rust_scripts::hotkeys::*;
|
extern crate task_hookrs;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate error_chain;
|
||||||
|
|
||||||
fn main() {
|
use std::rc::Rc;
|
||||||
let state;
|
use rust_scripts::hotkeys::{run, term, holdterm, menu, main_loop, Next};
|
||||||
let location;
|
use rust_scripts::kassandra::{kassandra, change_state, new_tasks};
|
||||||
|
use rust_scripts::error::Result;
|
||||||
|
|
||||||
let volume_up = (
|
quick_main!(|| -> Result<()> {
|
||||||
c("Volume up"),
|
let w17menu = {
|
||||||
Fork(cmd(
|
let summer = holdterm("Summer", "ssh summer@door.w17.io");
|
||||||
vec!["pactl", "set-sink-volume", "@DEFAULT_SINK@", "+5%"],
|
let lock = holdterm("Lock", "ssh close@door.w17.io");
|
||||||
)),
|
let unlock = holdterm("Unlock", "ssh open@door.w17.io");
|
||||||
|
let mpd_whisky = term("MPD Whisky", "ncmpcpp -h whisky");
|
||||||
|
let hub = run("Hub", "firefox --new-window https://hub.w17.io");
|
||||||
|
let kitchen = run("Kitchen", "firefox --new-window http://kitchen.w17.io");
|
||||||
|
menu("w17", vec![lock, unlock, summer, hub, mpd_whisky, kitchen])
|
||||||
|
};
|
||||||
|
|
||||||
|
let powermenu = {
|
||||||
|
let inhibit = term(
|
||||||
|
"Inhibit Suspend",
|
||||||
|
"systemd-inhibit --what handle-lid-switch watch echo 'Lid switch inhibited'",
|
||||||
|
);
|
||||||
|
let logout = run("Logout", "i3-msg exit");
|
||||||
|
let shutdown = run("Shutdown", "systemctl poweroff");
|
||||||
|
let suspend = run("Suspend", "systemctl suspend");
|
||||||
|
let reboot = run("Reboot", "systemctl reboot");
|
||||||
|
let lock = run("Lock", "loginctl lock-session");
|
||||||
|
menu(
|
||||||
|
"Power",
|
||||||
|
vec![shutdown, suspend, reboot, lock, inhibit, logout],
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let soundmenu = {
|
||||||
|
let mpd = term("MPD", "ncmpcpp");
|
||||||
|
let grammofy = run("Grammofy", "firefox --new-window https://grammofy.com");
|
||||||
|
let pavucontrol = run("Lautstärke", "pavucontrol");
|
||||||
|
menu("Sound", vec![mpd, pavucontrol, grammofy])
|
||||||
|
};
|
||||||
|
let apps = {
|
||||||
|
menu(
|
||||||
|
"Apps",
|
||||||
|
vec![
|
||||||
|
run("Launch", "rofi -show combi"),
|
||||||
|
run("Private Browser", "firefox --private-window"),
|
||||||
|
run("Browser", "firefox --new-window"),
|
||||||
|
run("Deluge", "deluge"),
|
||||||
|
run("Filemanager", "nautilus"),
|
||||||
|
menu(
|
||||||
|
"Messaging",
|
||||||
|
vec![
|
||||||
|
run("Mails", "evolution"),
|
||||||
|
run("Riot", "firefox --new-window https://riot.im/app"),
|
||||||
|
run("WhatsApp", "firefox --new-window https://web.whatsapp.com"),
|
||||||
|
run("Telegram", "telegram-desktop"),
|
||||||
|
run("Signal", "signal-desktop"),
|
||||||
|
run("Jabber", "dino"),
|
||||||
|
run(
|
||||||
|
"Regiotelko",
|
||||||
|
"mumble mumble://maralorn@mumble.c3pb.de/CCC/Regiotelko"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
menu(
|
||||||
|
"Accounting",
|
||||||
|
vec![
|
||||||
|
holdterm("Jali", "jali -l ."),
|
||||||
|
run(
|
||||||
|
"Beschlüsse",
|
||||||
|
"firefox --new-window https://git.darmstadt.ccc.de/vorstand/beschluesse/raw/master/beschl%C3%BCsse"
|
||||||
|
),
|
||||||
|
term(
|
||||||
|
"Private Buchhaltung",
|
||||||
|
"hledger -f data/aktuell/lebenshaltung/buchhaltung/buchhaltung.ledger ui"
|
||||||
|
),
|
||||||
|
term(
|
||||||
|
"CDA Buchhaltung",
|
||||||
|
"hledger -f data/aktuell/ccc/cda/vorstand/buchhaltung/buchhaltung.ledger ui"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let maintenance = {
|
||||||
|
let keymenu = menu(
|
||||||
|
"Keymap",
|
||||||
|
vec![
|
||||||
|
run("neo", "setxkbmap de neo"),
|
||||||
|
run("qwertz", "setxkbmap de"),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
let monitor = term("Monitor", "htop");
|
||||||
|
let wifi = term("WLAN", "nmtui");
|
||||||
|
let update_home = holdterm("Update Home", "home-manager switch");
|
||||||
|
let update_sys = holdterm("Update Sys", "sudo nixos-rebuild switch");
|
||||||
|
let gc = holdterm("Collect Garbage", "nix-collect-garbage -d");
|
||||||
|
let optimise = holdterm("Optimise", "nix optimise-store");
|
||||||
|
menu(
|
||||||
|
"Maintenance",
|
||||||
|
vec![
|
||||||
|
wifi,
|
||||||
|
update_home,
|
||||||
|
update_sys,
|
||||||
|
gc,
|
||||||
|
optimise,
|
||||||
|
monitor,
|
||||||
|
keymenu,
|
||||||
|
run("Bildschirme", "arandr"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let ssh = menu(
|
||||||
|
"ssh",
|
||||||
|
vec![
|
||||||
|
("kiva", "brandy@kiva-forward"),
|
||||||
|
("ag", "brandy@ag-forward"),
|
||||||
|
("whisky", "whisky"),
|
||||||
|
("vorstand", "vorstand"),
|
||||||
|
("shells", "shells"),
|
||||||
|
("charon", "charon"),
|
||||||
|
].into_iter()
|
||||||
|
.map(|(name, login)| term(name, &format!("ssh {}", login)))
|
||||||
|
.collect(),
|
||||||
);
|
);
|
||||||
let volume_down = (
|
|
||||||
c("Volume down"),
|
// sshuttle
|
||||||
Fork(cmd(
|
// tinc
|
||||||
vec!["pactl", "set-sink-volume", "@DEFAULT_SINK@", "-5%"],
|
// routes
|
||||||
)),
|
|
||||||
);
|
|
||||||
let ncmpcpp = (c("Music"), Exec(cmd(vec!["urxvt", "-e", "ncmpcpp"])));
|
|
||||||
let wizard = (c("Magic"), Script);
|
|
||||||
let startmenu = Menu((c("Hauptmenü"), vec![wizard]))
|
|
||||||
// arandr?
|
|
||||||
// keymap
|
|
||||||
// shutdown options
|
|
||||||
// lautstärken micro, lautsprecher, regler zeigen
|
|
||||||
// zeige Buchhaltung
|
|
||||||
// mumble
|
|
||||||
// hub.w17.io
|
|
||||||
// select wifi
|
|
||||||
// debug network
|
// debug network
|
||||||
// grammofy
|
|
||||||
// browser + pm
|
|
||||||
// IM dienste
|
|
||||||
// evolution
|
|
||||||
// door options, music options, hub options
|
|
||||||
// lock inhibit
|
// lock inhibit
|
||||||
// suspend inhibit
|
let startmenu = menu(
|
||||||
// ssh kiva, ag, whisky, vorstand, shells, charon
|
"Hauptmenü",
|
||||||
let w17menu
|
vec![
|
||||||
main_loop(startmenu);
|
(
|
||||||
// Brightness -> i3
|
"New Task".into(),
|
||||||
// Basic Sound -> i3
|
Next::Do(Rc::new(|| new_tasks().map(|_| Next::Exit)))
|
||||||
}
|
),
|
||||||
|
(
|
||||||
fn wizard() -> Next {
|
"Kassandra".into(),
|
||||||
// states: work, research, normal, idle
|
Next::Do(Rc::new(|| kassandra().map(|_| Next::Exit)))
|
||||||
// enter new tasks
|
),
|
||||||
// always: add task/subtask
|
(
|
||||||
// what about running tasks?
|
"Change State".into(),
|
||||||
// check unread E-Mail + ak?
|
Next::Do(Rc::new(|| change_state().map(|_| Next::Exit)))
|
||||||
// update
|
),
|
||||||
// system
|
ssh,
|
||||||
// home
|
apps,
|
||||||
// inbox
|
run("Tasks", "tasklauncher"),
|
||||||
//
|
run("Tasktree", "tasktree"),
|
||||||
// treesort
|
term("Files", "ranger"),
|
||||||
// mails
|
soundmenu,
|
||||||
// sort inbox
|
w17menu,
|
||||||
// sort inboxkiva
|
powermenu,
|
||||||
// sort inboxak
|
maintenance,
|
||||||
// sort to sort
|
],
|
||||||
// go trough todo
|
).1;
|
||||||
// go trough toread
|
main_loop(startmenu)
|
||||||
// go trough readlater
|
});
|
||||||
// pick tasks
|
|
||||||
// optional, later
|
|
||||||
// await
|
|
||||||
// do accounting own, cda
|
|
||||||
// dirty gits
|
|
||||||
|
|
||||||
// task generator
|
|
||||||
// task completion helper
|
|
||||||
}
|
|
||||||
|
|
7
packages/rust-scripts/src/bin/kassandra.rs
Normal file
7
packages/rust-scripts/src/bin/kassandra.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
extern crate rust_scripts;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate error_chain;
|
||||||
|
|
||||||
|
use rust_scripts::kassandra::kassandra;
|
||||||
|
|
||||||
|
quick_main!(kassandra);
|
323
packages/rust-scripts/src/generate.rs
Normal file
323
packages/rust-scripts/src/generate.rs
Normal file
|
@ -0,0 +1,323 @@
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
//
|
||||||
|
|
||||||
|
//! This module contains the generate function and the GeneratedTask trait.
|
||||||
|
//! You can routinely generate GeneratedTasks which represent some external state,
|
||||||
|
//! like e-mails you need to read, tickets from an issue tracker, or updates you have to do on a
|
||||||
|
//! system. If you pass them to the generate function, it will update your taskwarrior accordingly.
|
||||||
|
//! Create new tasks, complete old ones and update once which have new information.
|
||||||
|
//! Fields which you don't set in a GeneratedTask can be set in taskwarrior and won't be
|
||||||
|
//! overwritten on calling generate again.
|
||||||
|
use task_hookrs::task::Task;
|
||||||
|
use task_hookrs::status::TaskStatus as TS;
|
||||||
|
use task_hookrs::uda::UDAValue as U;
|
||||||
|
use generate::OrphanBehavior as O;
|
||||||
|
use task_hookrs::cache::TaskCache;
|
||||||
|
use task_hookrs::error::{Result, ResultExt};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|
||||||
|
/// This trait contains additional methods for the Task struct, for representing programatically
|
||||||
|
/// generated tasks
|
||||||
|
pub trait GeneratedTask {
|
||||||
|
/// The name of this generator type. e.g. "mail"
|
||||||
|
fn gen_name(&self) -> Option<&String>;
|
||||||
|
/// The name of this generator type. e.g. "mail", mutable
|
||||||
|
fn gen_name_mut(&mut self) -> Option<&mut String>;
|
||||||
|
/// Set the name of this generator type. e.g. "mail"
|
||||||
|
fn set_gen_name<T>(&mut self, new: Option<T>)
|
||||||
|
where
|
||||||
|
T: Into<String>;
|
||||||
|
/// The id of the generator type, which should be unique for all generator Tasks with the same
|
||||||
|
/// name
|
||||||
|
fn gen_id(&self) -> Option<&String>;
|
||||||
|
/// The generator id, mutable
|
||||||
|
fn gen_id_mut(&mut self) -> Option<&mut String>;
|
||||||
|
/// Set the generator id
|
||||||
|
fn set_gen_id<T>(&mut self, new: Option<T>)
|
||||||
|
where
|
||||||
|
T: Into<String>;
|
||||||
|
/// What should happen with the task, when the generator is missing.
|
||||||
|
/// This is relevant, when the generate method is called with one or more tasks with a
|
||||||
|
/// generator name set, all existing tasks with that generator name will be dealt with
|
||||||
|
/// according to this field.
|
||||||
|
fn gen_orphan(&self) -> OrphanBehavior;
|
||||||
|
/// Set the OrphanBehavior
|
||||||
|
fn set_gen_orphan<T>(&mut self, new: OrphanBehavior);
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref DELETE: U = U::Str("delete".into());
|
||||||
|
static ref COMPLETE: U = U::Str("complete".into());
|
||||||
|
static ref EMPTY: U = U::Str(String::default());
|
||||||
|
}
|
||||||
|
static GEN_NAME: &str = "gen_name";
|
||||||
|
static GEN_ID: &str = "gen_id";
|
||||||
|
static GEN_ORPHAN: &str = "gen_orphan";
|
||||||
|
|
||||||
|
/// The behavior if a task with missing generator is encountered.
|
||||||
|
pub enum OrphanBehavior {
|
||||||
|
/// Complete generated tasks, with missing generator
|
||||||
|
CompleteOrphan,
|
||||||
|
/// Delete generated tasks, with missing generator
|
||||||
|
DeleteOrphan,
|
||||||
|
/// Don't do anything with generated tasks, with missing generator
|
||||||
|
KeepOrphan,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GeneratedTask for Task {
|
||||||
|
fn gen_name(&self) -> Option<&String> {
|
||||||
|
self.uda().get(GEN_NAME).and_then(
|
||||||
|
|x| if let &U::Str(ref x) = x {
|
||||||
|
Some(x)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_name_mut(&mut self) -> Option<&mut String> {
|
||||||
|
self.uda_mut().get_mut(GEN_NAME).and_then(|x| {
|
||||||
|
if let &mut U::Str(ref mut x) = x {
|
||||||
|
Some(x)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_gen_name<T>(&mut self, new: Option<T>)
|
||||||
|
where
|
||||||
|
T: Into<String>,
|
||||||
|
{
|
||||||
|
if let Some(new) = new {
|
||||||
|
self.uda_mut().insert(GEN_NAME.into(), U::Str(new.into()));
|
||||||
|
} else {
|
||||||
|
self.uda_mut().remove(GEN_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_id(&self) -> Option<&String> {
|
||||||
|
self.uda().get(GEN_ID).and_then(
|
||||||
|
|x| if let &U::Str(ref x) = x {
|
||||||
|
Some(x)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_id_mut(&mut self) -> Option<&mut String> {
|
||||||
|
self.uda_mut().get_mut(GEN_ID).and_then(|x| {
|
||||||
|
if let &mut U::Str(ref mut x) = x {
|
||||||
|
Some(x)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_gen_id<T>(&mut self, new: Option<T>)
|
||||||
|
where
|
||||||
|
T: Into<String>,
|
||||||
|
{
|
||||||
|
if let Some(new) = new {
|
||||||
|
self.uda_mut().insert(GEN_ID.into(), U::Str(new.into()));
|
||||||
|
} else {
|
||||||
|
self.uda_mut().remove(GEN_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_orphan(&self) -> OrphanBehavior {
|
||||||
|
let u = self.uda().get(GEN_ORPHAN).unwrap_or(&*EMPTY);
|
||||||
|
if *u == *COMPLETE {
|
||||||
|
O::CompleteOrphan
|
||||||
|
} else if *u == *DELETE {
|
||||||
|
O::DeleteOrphan
|
||||||
|
} else {
|
||||||
|
O::KeepOrphan
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_gen_orphan<T>(&mut self, new: OrphanBehavior) {
|
||||||
|
match new {
|
||||||
|
O::DeleteOrphan => self.uda_mut().insert(GEN_ORPHAN.into(), DELETE.clone()),
|
||||||
|
O::CompleteOrphan => self.uda_mut().insert(GEN_ORPHAN.into(), COMPLETE.clone()),
|
||||||
|
O::KeepOrphan => self.uda_mut().remove(GEN_ORPHAN),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_ignores(cache: &TaskCache) -> Result<()> {
|
||||||
|
if cache.ignore().len() > 0 {
|
||||||
|
return Err("Don't use generate with a TaskCache with ignores".into());
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_new(cache: &mut TaskCache, new: Vec<Task>) {
|
||||||
|
for task in new {
|
||||||
|
cache.set(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn r<'a>(c: &'a TaskCache, u: &Uuid) -> Result<&'a Task> {
|
||||||
|
c.get(u).chain_err(|| "Cache miss for changed task")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn w<'a>(c: &'a mut TaskCache, u: &Uuid) -> Result<&'a mut Task> {
|
||||||
|
c.get_mut(u).chain_err(|| "Cache miss for changed task")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_matches(cache: &mut TaskCache, matches: Vec<(Uuid, Task)>) -> Result<()> {
|
||||||
|
let c = cache;
|
||||||
|
for (u, new) in matches {
|
||||||
|
if r(c,&u)?.status() != new.status() {
|
||||||
|
*w(c,&u)?.status_mut() = new.status().clone();
|
||||||
|
}
|
||||||
|
if r(c,&u)?.description() != new.description() {
|
||||||
|
*w(c,&u)?.description_mut() = new.description().clone();
|
||||||
|
}
|
||||||
|
if let Some(ann) = new.annotations() {
|
||||||
|
if r(c,&u)?.annotations().map(|x| x != ann) == Some(true) {
|
||||||
|
w(c,&u)?.annotations_mut().map(|o| *o = ann.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(dep) = new.depends() {
|
||||||
|
if r(c,&u)?.depends().map(|x| x != dep) == Some(true) {
|
||||||
|
w(c,&u)?.depends_mut().map(|o| *o = dep.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(due) = new.due() {
|
||||||
|
if r(c,&u)?.due().map(|x| x != due) == Some(true) {
|
||||||
|
w(c,&u)?.due_mut().map(|o| *o = due.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(end) = new.end() {
|
||||||
|
if r(c,&u)?.end().map(|x| x != end) == Some(true) {
|
||||||
|
w(c,&u)?.end_mut().map(|o| *o = end.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(ann) = new.annotations() {
|
||||||
|
if r(c,&u)?.annotations().map(|x| x != ann) == Some(true) {
|
||||||
|
w(c,&u)?.annotations_mut().map(|o| *o = ann.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(recur) = new.recur() {
|
||||||
|
if r(c,&u)?.recur().map(|x| x != recur) == Some(true) {
|
||||||
|
w(c,&u)?.recur_mut().map(|o| *o = recur.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(scheduled) = new.scheduled() {
|
||||||
|
if r(c,&u)?.scheduled().map(|x| x != scheduled) == Some(true) {
|
||||||
|
w(c,&u)?.scheduled_mut().map(|o| *o = scheduled.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(start) = new.start() {
|
||||||
|
if r(c,&u)?.start().map(|x| x != start) == Some(true) {
|
||||||
|
w(c,&u)?.start_mut().map(|o| *o = start.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(tags) = new.tags() {
|
||||||
|
if r(c,&u)?.tags().map(|x| x != tags) == Some(true) {
|
||||||
|
w(c,&u)?.tags_mut().map(|o| *o = tags.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(until) = new.until() {
|
||||||
|
if r(c,&u)?.until().map(|x| x != until) == Some(true) {
|
||||||
|
w(c,&u)?.until_mut().map(|o| *o = until.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(wait) = new.wait() {
|
||||||
|
if r(c,&u)?.wait().map(|x| x != wait) == Some(true) {
|
||||||
|
w(c,&u)?.wait_mut().map(|o| *o = wait.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !(r(c,&u)?.uda() >= new.uda()) {
|
||||||
|
w(c,&u)?.uda_mut().append(&mut new.uda().clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_orphans(
|
||||||
|
cache: &mut TaskCache,
|
||||||
|
orphans: HashMap<String, HashMap<String, Uuid>>,
|
||||||
|
) -> Result<()> {
|
||||||
|
for uuid in orphans.values().flat_map(HashMap::values) {
|
||||||
|
match cache.get(uuid).chain_err(|| "Cache miss for orphan")?.gen_orphan() {
|
||||||
|
O::CompleteOrphan => if *cache.get(uuid).chain_err(|| "Cache miss for orphan")?.status() != TS::Completed {
|
||||||
|
*cache.get_mut(uuid).chain_err(|| "Cache miss for orphan")?.status_mut() = TS::Completed;
|
||||||
|
}
|
||||||
|
O::DeleteOrphan => if *cache.get(uuid).chain_err(|| "Cache miss for orphan")?.status() != TS::Deleted {
|
||||||
|
*cache.get_mut(uuid).chain_err(|| "Cache miss for orphan")?.status_mut() = TS::Deleted;
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Take a TaskCache (which should not ignore any task states) and make sure, that all given
|
||||||
|
/// generator tasks are represented in taskwarrior.
|
||||||
|
|
||||||
|
pub trait TaskGenerator {
|
||||||
|
fn get_by_gen(&self, generator: &Task) -> Option<&Task>;
|
||||||
|
fn get_by_gen_mut(&mut self, generator: &Task) -> Option<&mut Task>;
|
||||||
|
fn generate<T>(&mut self, generators: T) -> Result<()>
|
||||||
|
where
|
||||||
|
T: IntoIterator,
|
||||||
|
T::Item: Into<Task>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_match(a: &Task, b: &Task) -> bool {
|
||||||
|
a.gen_name() == b.gen_name() && a.gen_id() == b.gen_id()
|
||||||
|
}
|
||||||
|
impl TaskGenerator for TaskCache {
|
||||||
|
fn get_by_gen(&self, generator: &Task) -> Option<&Task> {
|
||||||
|
self.filter(|t| gen_match(t, generator)).into_iter().next()
|
||||||
|
}
|
||||||
|
fn get_by_gen_mut(&mut self, generator: &Task) -> Option<&mut Task> {
|
||||||
|
self.filter_mut(|t| gen_match(t, generator)).into_iter().next()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate<T>(&mut self, generators: T) -> Result<()>
|
||||||
|
where
|
||||||
|
T: IntoIterator,
|
||||||
|
T::Item: Into<Task>,
|
||||||
|
{
|
||||||
|
check_ignores(self)?;
|
||||||
|
let mut orphans = HashMap::<String, HashMap<String, Uuid>>::default();
|
||||||
|
let mut create = Vec::<Task>::default();
|
||||||
|
let mut changes = Vec::<(Uuid, Task)>::default();
|
||||||
|
for g in generators {
|
||||||
|
let new = g.into();
|
||||||
|
if let Some(old) = {
|
||||||
|
let name = new.gen_name().chain_err(|| "gen_name missing")?;
|
||||||
|
let id = new.gen_id().chain_err(|| "gen_id missing")?;
|
||||||
|
orphans
|
||||||
|
.entry(name.clone())
|
||||||
|
.or_insert_with(|| {
|
||||||
|
self
|
||||||
|
.filter(|t| t.gen_name() == Some(name))
|
||||||
|
.iter()
|
||||||
|
.filter_map(|t| t.gen_id().map(|id| (id.clone(), t.uuid().clone())))
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.remove(id)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
changes.push((old, new));
|
||||||
|
} else {
|
||||||
|
create.push(new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
process_new(self, create);
|
||||||
|
process_matches(self, changes)?;
|
||||||
|
process_orphans(self, orphans)
|
||||||
|
}
|
||||||
|
}
|
97
packages/rust-scripts/src/hotkeys.rs
Normal file
97
packages/rust-scripts/src/hotkeys.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
use std::rc::Rc;
|
||||||
|
use dialog::DialogProvider;
|
||||||
|
use dialog::errors::{Error, ErrorKind as EK};
|
||||||
|
use dialog::rofi::RofiDialogProvider;
|
||||||
|
use std::process::Command as StdCommand;
|
||||||
|
use std::os::unix::process::CommandExt;
|
||||||
|
use error::{Result, ResultExt};
|
||||||
|
|
||||||
|
use hotkeys::Next::*;
|
||||||
|
|
||||||
|
pub fn run<T: Into<String>>(name: T, command: &str) -> Item {
|
||||||
|
let command = command.to_owned();
|
||||||
|
(
|
||||||
|
name.into(),
|
||||||
|
Do(Rc::new(move || {
|
||||||
|
str2cmd(&command).exec();
|
||||||
|
Ok(Exit)
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn term<T: Into<String>>(name: T, command: &str) -> Item {
|
||||||
|
run(name, &format!("urxvt -e {}", command))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn holdterm<T: Into<String>>(name: T, command: &str) -> Item {
|
||||||
|
run(name, &format!("urxvt -hold -e {}", command))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn menu<T: Into<String>>(name: T, options: Vec<Item>) -> Item {
|
||||||
|
let name = name.into();
|
||||||
|
(name.clone(), Menu((name.clone(), options)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum Next {
|
||||||
|
Menu(Dialog),
|
||||||
|
Back,
|
||||||
|
Exit,
|
||||||
|
Stay,
|
||||||
|
Do(Rc<Fn() -> Result<Next>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
type Dialog = (String, Vec<Item>);
|
||||||
|
|
||||||
|
type Item = (String, Next);
|
||||||
|
|
||||||
|
type Command = Vec<String>;
|
||||||
|
|
||||||
|
fn show_menu<T: DialogProvider>(dialog_provider: &mut T, menu: Dialog) -> Result<Next> {
|
||||||
|
let (msg, mut options) = menu;
|
||||||
|
options.insert(0, (".Back".into(), Back));
|
||||||
|
match dialog_provider.select_option(msg, options) {
|
||||||
|
Ok(next) => Ok(next),
|
||||||
|
Err(Error(EK::InvalidUserInput, _)) => Ok(Stay),
|
||||||
|
err => err.chain_err(|| "User Input Error"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn str2cmd(cmd: &str) -> StdCommand {
|
||||||
|
mk_cmd(
|
||||||
|
cmd.split_whitespace()
|
||||||
|
.map(str::to_owned)
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mk_cmd(cmd: Command) -> StdCommand {
|
||||||
|
let mut cmd_iter = cmd.iter();
|
||||||
|
let mut prg = StdCommand::new(cmd_iter.next().expect("Called program without name"));
|
||||||
|
for arg in cmd_iter {
|
||||||
|
prg.arg(arg);
|
||||||
|
}
|
||||||
|
prg
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main_loop(startmenu: Next) -> Result<()> {
|
||||||
|
let mut dialog_provider = RofiDialogProvider;
|
||||||
|
let mut history = vec![];
|
||||||
|
let mut next = startmenu;
|
||||||
|
loop {
|
||||||
|
next = match next {
|
||||||
|
Exit => break,
|
||||||
|
Back => {
|
||||||
|
history.pop().chain_err(|| "Empty history")?;
|
||||||
|
Stay
|
||||||
|
}
|
||||||
|
Do(script) => script()?,
|
||||||
|
Menu(menu) => {
|
||||||
|
history.push(menu.clone());
|
||||||
|
show_menu(&mut dialog_provider, menu)?
|
||||||
|
}
|
||||||
|
Stay => Menu(history.pop().chain_err(|| "Empty history")?.clone()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
779
packages/rust-scripts/src/kassandra.rs
Normal file
779
packages/rust-scripts/src/kassandra.rs
Normal file
|
@ -0,0 +1,779 @@
|
||||||
|
use std::fs::File;
|
||||||
|
use std::env::home_dir;
|
||||||
|
use std::iter::once;
|
||||||
|
|
||||||
|
use serde_yaml::{from_reader, to_writer, to_string};
|
||||||
|
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use task_hookrs::cache::TaskCache;
|
||||||
|
use task_hookrs::task::{Task, TaskBuilder};
|
||||||
|
|
||||||
|
use dialog::rofi::RofiDialogProvider;
|
||||||
|
use dialog::DialogProvider;
|
||||||
|
use dialog::errors::ErrorKind as DEK;
|
||||||
|
|
||||||
|
use update::update_tasks;
|
||||||
|
use generate::GeneratedTask;
|
||||||
|
use error::{Result, ResultExt, ErrorKind as EK, Error};
|
||||||
|
use hotkeys::str2cmd;
|
||||||
|
use tasktree::{TreeCache, TaskNode};
|
||||||
|
|
||||||
|
fn print_task_short(task: &Task) -> String {
|
||||||
|
let mut info = vec![task.description().clone()];
|
||||||
|
if let Some(tags) = task.tags() {
|
||||||
|
info.push(format!("+{}", tags.join(",+")));
|
||||||
|
}
|
||||||
|
if let Some(project) = task.project() {
|
||||||
|
info.push(format!("({})", project));
|
||||||
|
}
|
||||||
|
info.join(" ")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_task(task: &Task) -> String {
|
||||||
|
let mut info = vec![task.description().clone()];
|
||||||
|
info.push(format!("status: {}", task.status()));
|
||||||
|
if let Some(project) = task.project() {
|
||||||
|
info.push(format!("project: {}", project));
|
||||||
|
}
|
||||||
|
if let Some(tags) = task.tags() {
|
||||||
|
info.push(format!("tags: {}", tags.join(", ")));
|
||||||
|
}
|
||||||
|
info.join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||||
|
enum Mode {
|
||||||
|
#[serde(rename = "work")]
|
||||||
|
Work,
|
||||||
|
#[serde(rename = "research")]
|
||||||
|
Research,
|
||||||
|
#[serde(rename = "orga")]
|
||||||
|
Orga,
|
||||||
|
#[serde(rename = "idle")]
|
||||||
|
Idle,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||||
|
enum Connectivity {
|
||||||
|
#[serde(rename = "online")]
|
||||||
|
Online,
|
||||||
|
#[serde(rename = "offline")]
|
||||||
|
Offline,
|
||||||
|
#[serde(rename = "limited")]
|
||||||
|
Limited,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||||
|
enum Location {
|
||||||
|
#[serde(rename = "home")]
|
||||||
|
Home,
|
||||||
|
#[serde(rename = "w17")]
|
||||||
|
W17,
|
||||||
|
#[serde(rename = "city")]
|
||||||
|
City,
|
||||||
|
#[serde(rename = "uni")]
|
||||||
|
Uni,
|
||||||
|
#[serde(rename = "anywhere")]
|
||||||
|
Anywhere,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||||
|
struct State {
|
||||||
|
mode: Mode,
|
||||||
|
location: Location,
|
||||||
|
connectivity: Connectivity,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn task_blocked(cache: &TaskCache, task: &Task) -> bool {
|
||||||
|
task.depends()
|
||||||
|
.map(|dependencies| {
|
||||||
|
for dependency in dependencies {
|
||||||
|
if cache.get(dependency).map(|t| !t.obsolete()).unwrap_or(
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn task_needs_sorting(cache: &TaskCache, uuid: &Uuid) -> Result<bool> {
|
||||||
|
Ok(!cache.is_project(&uuid) && cache.get_parent(&uuid)? == None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn task_inbox(cache: &TaskCache, task: &Task) -> bool {
|
||||||
|
task.pending() && !task.tagged() && !task_blocked(cache, task)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_state(state: &State) -> Result<()> {
|
||||||
|
let state_path = &{
|
||||||
|
let mut s = home_dir().chain_err(|| "No Home")?;
|
||||||
|
s.push(".kassandra_state");
|
||||||
|
s
|
||||||
|
};
|
||||||
|
let state_file = File::create(&state_path)?;
|
||||||
|
to_writer(state_file, &state)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_state() -> Result<State> {
|
||||||
|
let state_path = &{
|
||||||
|
let mut s = home_dir().chain_err(|| "No Home")?;
|
||||||
|
s.push(".kassandra_state");
|
||||||
|
s
|
||||||
|
};
|
||||||
|
Ok(if let Ok(state_file) = File::open(&state_path) {
|
||||||
|
from_reader(state_file)?
|
||||||
|
} else {
|
||||||
|
let state = State {
|
||||||
|
mode: Mode::Orga,
|
||||||
|
connectivity: Connectivity::Online,
|
||||||
|
location: Location::Anywhere,
|
||||||
|
};
|
||||||
|
save_state(&state)?;
|
||||||
|
state
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enter_new_task<T: DialogProvider, S: Into<String>>(dialog: &mut T, msg: S) -> Result<Task> {
|
||||||
|
Ok(TaskBuilder::default()
|
||||||
|
.description(dialog.input_line(msg, Vec::<String>::default())?)
|
||||||
|
.build()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Kassandra {
|
||||||
|
state: State,
|
||||||
|
dialog: RofiDialogProvider,
|
||||||
|
cache: TaskCache,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Kassandra {
|
||||||
|
fn new() -> Result<Self> {
|
||||||
|
Ok(Kassandra {
|
||||||
|
state: get_state()?,
|
||||||
|
dialog: RofiDialogProvider {},
|
||||||
|
cache: TaskCache::new(vec![]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn run(&mut self) -> Result<()> {
|
||||||
|
self.cache.load()?;
|
||||||
|
update_tasks(&mut self.cache)?;
|
||||||
|
self.cache.write()?;
|
||||||
|
self.handle_active_tasks()?;
|
||||||
|
self.clear_inbox()?;
|
||||||
|
self.assure_all_sorted()?;
|
||||||
|
|
||||||
|
// check unread E-Mail + ak?
|
||||||
|
// update
|
||||||
|
// system
|
||||||
|
// home
|
||||||
|
// mails
|
||||||
|
// sort inbox
|
||||||
|
// sort inboxkiva
|
||||||
|
// sort inboxak
|
||||||
|
// sort to sort
|
||||||
|
// go trough todo
|
||||||
|
// go trough toread
|
||||||
|
// go trough readlater
|
||||||
|
// pick tasks
|
||||||
|
// optional, later
|
||||||
|
// await
|
||||||
|
// dirty gits
|
||||||
|
|
||||||
|
// task generator
|
||||||
|
// task completion helper
|
||||||
|
self.update_accounting()?;
|
||||||
|
self.select_next_task()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_sorted_uuids<T: Fn(&Task) -> bool>(&self, filter: T) -> Vec<Uuid> {
|
||||||
|
self.get_sorted_tasks(filter)
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| x.uuid().clone())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_sorted_tasks<T: Fn(&Task) -> bool>(&self, filter: T) -> Vec<&Task> {
|
||||||
|
let mut tasks = self.cache.filter(filter);
|
||||||
|
tasks.sort_unstable_by_key(|t| t.entry().date());
|
||||||
|
tasks
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_notes(&mut self) -> Result<()> {
|
||||||
|
loop {
|
||||||
|
match enter_new_task(
|
||||||
|
&mut self.dialog,
|
||||||
|
"Do you have anything to note?
|
||||||
|
For example, what you are doing right now or still have to do today?",
|
||||||
|
) {
|
||||||
|
Ok(task) => {
|
||||||
|
self.cache.set(task);
|
||||||
|
self.cache.write()?;
|
||||||
|
}
|
||||||
|
Err(Error(EK::DialogError(DEK::InputCanceled), _)) => break Ok(()),
|
||||||
|
err => {
|
||||||
|
err?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn confirm_state(&mut self) -> Result<()> {
|
||||||
|
loop {
|
||||||
|
match self.dialog.select_option(
|
||||||
|
format!(
|
||||||
|
"State: {}
|
||||||
|
|
||||||
|
Do you want to change the state? (Esc to cancel)",
|
||||||
|
to_string(&self.state)?
|
||||||
|
),
|
||||||
|
vec![
|
||||||
|
("working: I am at work", "work"),
|
||||||
|
("researching: I am researching", "research"),
|
||||||
|
("orga: I am in normal mode", "orga"),
|
||||||
|
("home: I am at home", "home"),
|
||||||
|
("uni: I am at the Mathebau", "uni"),
|
||||||
|
("hackspace: I am in the hackspace", "w17"),
|
||||||
|
("city: I am in the city", "city"),
|
||||||
|
("anywhere: I'm nowhere special", "anywhere"),
|
||||||
|
(
|
||||||
|
"idle: I am not interested in doing anything",
|
||||||
|
"idle"
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)? {
|
||||||
|
"work" => self.state.mode = Mode::Work,
|
||||||
|
"research" => self.state.mode = Mode::Research,
|
||||||
|
"orga" => self.state.mode = Mode::Orga,
|
||||||
|
"home" => self.state.location = Location::Home,
|
||||||
|
"w17" => self.state.location = Location::W17,
|
||||||
|
"city" => self.state.location = Location::City,
|
||||||
|
"idle" => self.state.mode = Mode::Idle,
|
||||||
|
"uni" => self.state.location = Location::Uni,
|
||||||
|
"anywhere" => self.state.location = Location::Anywhere,
|
||||||
|
_ => (),
|
||||||
|
};
|
||||||
|
save_state(&self.state)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_active_tasks(&mut self) -> Result<()> {
|
||||||
|
while let Some(uuid) = self.get_sorted_uuids(|t| t.start().is_some() && t.pending())
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
{
|
||||||
|
match self.dialog.select_option(
|
||||||
|
format!(
|
||||||
|
"You are currently working on {}
|
||||||
|
What's the progress?",
|
||||||
|
print_task(
|
||||||
|
self.cache.get(&uuid).chain_err(|| "uuid miss")?,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
vec![
|
||||||
|
("Continue: I'll get back to it", "continue"),
|
||||||
|
("Done: I've done that!", "done"),
|
||||||
|
("Later: I'll do that later", "later"),
|
||||||
|
("Edit: I have changes to this task", "edit"),
|
||||||
|
],
|
||||||
|
)? {
|
||||||
|
"done" => {
|
||||||
|
{
|
||||||
|
let task = self.cache.get_mut(&uuid).chain_err(|| "missing uuid")?;
|
||||||
|
task.tw_stop();
|
||||||
|
task.tw_done();
|
||||||
|
}
|
||||||
|
self.cache.write()?;
|
||||||
|
}
|
||||||
|
"later" => {
|
||||||
|
self.cache
|
||||||
|
.get_mut(&uuid)
|
||||||
|
.chain_err(|| "missing uuid")?
|
||||||
|
.tw_stop();
|
||||||
|
self.cache.write()?;
|
||||||
|
}
|
||||||
|
"edit" => {
|
||||||
|
self.cache
|
||||||
|
.get_mut(&uuid)
|
||||||
|
.chain_err(|| "missing uuid")?
|
||||||
|
.tw_stop();
|
||||||
|
self.cache.write()?;
|
||||||
|
self.edit_task(&uuid)?;
|
||||||
|
}
|
||||||
|
_ => bail!("Continuing with task"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assure_all_sorted(&mut self) -> Result<()> {
|
||||||
|
if self.cache
|
||||||
|
.filter(|t| {
|
||||||
|
t.gen_name() == Some(&"Sortiere Tasktree".into()) && t.pending()
|
||||||
|
})
|
||||||
|
.len() > 0
|
||||||
|
{
|
||||||
|
while let Some(uuid) = self.get_sorted_uuids(|t| {
|
||||||
|
!t.obsolete() && task_needs_sorting(&self.cache, t.uuid()).unwrap_or(false)
|
||||||
|
}).into_iter()
|
||||||
|
.next()
|
||||||
|
{
|
||||||
|
self.sort(&uuid)?;
|
||||||
|
}
|
||||||
|
for task in self.cache.filter_mut(|t| {
|
||||||
|
t.gen_name() == Some(&"Sortiere Tasktree".into()) && t.pending()
|
||||||
|
})
|
||||||
|
{
|
||||||
|
task.tw_done()
|
||||||
|
}
|
||||||
|
self.cache.refresh_tree();
|
||||||
|
self.cache.write()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sort(&mut self, uuid: &Uuid) -> Result<()> {
|
||||||
|
let task_name = print_task(self.cache.get(uuid).chain_err(|| "mising uuid")?);
|
||||||
|
let partof = self.select_entry_point(
|
||||||
|
format!("Select Project for Task\n{}", task_name),
|
||||||
|
uuid,
|
||||||
|
)?;
|
||||||
|
self.cache
|
||||||
|
.get_mut(uuid)
|
||||||
|
.chain_err(|| "assure_sorted: missing uuid")?
|
||||||
|
.set_partof(partof);
|
||||||
|
update_tasks(&mut self.cache)?;
|
||||||
|
self.cache.write()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_entry_point<T: Into<String>>(
|
||||||
|
&mut self,
|
||||||
|
msg: T,
|
||||||
|
uuid: &Uuid,
|
||||||
|
) -> Result<Option<Uuid>> {
|
||||||
|
let msg = msg.into();
|
||||||
|
let format_msg = |cache: &TaskCache, uuid, text| -> Result<String> {
|
||||||
|
Ok(format!(
|
||||||
|
"{}\n{}: {}",
|
||||||
|
&msg,
|
||||||
|
text,
|
||||||
|
if let Some(uuid) = uuid {
|
||||||
|
cache.get_project_path(&uuid)?
|
||||||
|
} else {
|
||||||
|
String::default()
|
||||||
|
}
|
||||||
|
))
|
||||||
|
};
|
||||||
|
let mut parent = None;
|
||||||
|
loop {
|
||||||
|
match {
|
||||||
|
let mut options = self.cache.filter(|t| {
|
||||||
|
t.pending() && t.partof().map(|partof| partof == parent).unwrap_or(false) &&
|
||||||
|
(parent.is_some() || self.cache.is_project(t.uuid()))
|
||||||
|
});
|
||||||
|
options.sort_unstable_by_key(|t| t.entry().date());
|
||||||
|
match self.dialog.select_option(
|
||||||
|
format_msg(&self.cache, parent, "currently at")?,
|
||||||
|
vec![
|
||||||
|
("select this level".into(), Err(0)),
|
||||||
|
("insert new node".into(), Err(1)),
|
||||||
|
("go one level up".into(), Err(2)),
|
||||||
|
("edit task".into(), Err(4)),
|
||||||
|
].into_iter()
|
||||||
|
.chain(options.into_iter().map(|t| (print_task_short(t), Ok(t)))),
|
||||||
|
)? {
|
||||||
|
Ok(task) => {
|
||||||
|
parent = Some(task.uuid().clone());
|
||||||
|
3
|
||||||
|
}
|
||||||
|
Err(n) => n,
|
||||||
|
}
|
||||||
|
} {
|
||||||
|
|
||||||
|
0 => return Ok(parent),
|
||||||
|
1 => {
|
||||||
|
let mut task = enter_new_task(
|
||||||
|
&mut self.dialog,
|
||||||
|
format_msg(&self.cache, parent, "inserting new node at")?,
|
||||||
|
)?;
|
||||||
|
task.set_partof(parent);
|
||||||
|
parent = Some(task.uuid().clone());
|
||||||
|
self.cache.set(task);
|
||||||
|
self.cache.write()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
2 => {
|
||||||
|
parent = if let Some(parent) = parent {
|
||||||
|
if let Some(parent) = self.cache.get(&parent) {
|
||||||
|
parent.partof()?
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
3 => (),
|
||||||
|
4 => {
|
||||||
|
self.edit_task(uuid)?;
|
||||||
|
parent = None;
|
||||||
|
}
|
||||||
|
_ => bail!("Hö?"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn edit_task(&mut self, uuid: &Uuid) -> Result<()> {
|
||||||
|
loop {
|
||||||
|
let task_name = print_task(
|
||||||
|
self.cache.get(uuid).chain_err(|| "edit_task: missing uuid")?,
|
||||||
|
);
|
||||||
|
match self.dialog.select_option(
|
||||||
|
format!(
|
||||||
|
"Handling Task: {}\nDo you want to do this now? Can it be done in under 2 minutes?",
|
||||||
|
task_name
|
||||||
|
),
|
||||||
|
vec![
|
||||||
|
("Do it: I'll get to it", "do"),
|
||||||
|
("Done: I already did this", "done"),
|
||||||
|
("Delete: This does not need to be done anymore","delete"),
|
||||||
|
("Edit description: I want to change the description", "edit"),
|
||||||
|
("Move: Change position in tasktree", "move"),
|
||||||
|
("Split: Give this tasks subtasks", "split"),
|
||||||
|
("Depend: Set dependency", "depend"),
|
||||||
|
("Postpone: Set wait time", "postpone"),
|
||||||
|
("Tag: Add a tag", "tag"),
|
||||||
|
("Clear tags", "clear_tags"),
|
||||||
|
("Manual: I have to change something by hand", "manual"),
|
||||||
|
("Quit", "quit"),
|
||||||
|
],
|
||||||
|
)? {
|
||||||
|
"do" => {
|
||||||
|
self.cache.get_mut(uuid).chain_err(|| "BUG!")?.tw_start();
|
||||||
|
self.cache.write()?;
|
||||||
|
bail!("Work on Task now!");
|
||||||
|
}
|
||||||
|
"done" => {
|
||||||
|
self.cache.get_mut(uuid).chain_err(|| "BUG!")?.tw_done();
|
||||||
|
self.cache.write()?;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
"delete" => {
|
||||||
|
self.cache
|
||||||
|
.get_mut(uuid)
|
||||||
|
.chain_err(|| "missing uuid")?
|
||||||
|
.tw_delete();
|
||||||
|
self.cache.write()?;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
"edit" => {
|
||||||
|
*self.cache
|
||||||
|
.get_mut(uuid)
|
||||||
|
.chain_err(|| "missing uuid")?
|
||||||
|
.description_mut() = self.dialog.input_line(
|
||||||
|
format!(
|
||||||
|
"Enter new description for {}",
|
||||||
|
task_name
|
||||||
|
),
|
||||||
|
vec![
|
||||||
|
self.cache
|
||||||
|
.get_mut(uuid)
|
||||||
|
.chain_err(|| "missing uuid")?
|
||||||
|
.description()
|
||||||
|
.clone(),
|
||||||
|
],
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
"manual" => {
|
||||||
|
str2cmd("tasklauncher").output()?;
|
||||||
|
self.cache.refresh()?;
|
||||||
|
}
|
||||||
|
"move" => {
|
||||||
|
self.sort(uuid)?;
|
||||||
|
}
|
||||||
|
"quit" => {break;}
|
||||||
|
"split" => {self.make_project(uuid)?;}
|
||||||
|
"depend" => {
|
||||||
|
let query = format!(
|
||||||
|
"Selecting dependency for task\n{}",
|
||||||
|
print_task(self.cache.get(uuid).chain_err(|| "missing uuid")?)
|
||||||
|
);
|
||||||
|
if let Some(dependency) = self.select_entry_point(query, uuid)? {
|
||||||
|
let task = self.cache.get_mut(uuid).chain_err(|| "missing uuid")?;
|
||||||
|
if task.depends().is_some() {
|
||||||
|
task.depends_mut().unwrap().push(dependency);
|
||||||
|
} else {
|
||||||
|
task.set_depends(Some(Some(dependency)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.cache.write()?;
|
||||||
|
}
|
||||||
|
"tag" => {
|
||||||
|
let tag = self.dialog.input_line(
|
||||||
|
format!("Enter tag for {}", task_name),
|
||||||
|
vec![
|
||||||
|
"alber",
|
||||||
|
"await",
|
||||||
|
"city",
|
||||||
|
"home",
|
||||||
|
"pc",
|
||||||
|
"research",
|
||||||
|
"streicher",
|
||||||
|
"uni",
|
||||||
|
"work",
|
||||||
|
"claire",
|
||||||
|
"burkhard",
|
||||||
|
"cornelia",
|
||||||
|
"nathalie",
|
||||||
|
],
|
||||||
|
)?;
|
||||||
|
self.cache
|
||||||
|
.get_mut(uuid)
|
||||||
|
.chain_err(|| "missing uuid")?
|
||||||
|
.add_tag(tag);
|
||||||
|
self.cache.write()?;
|
||||||
|
}
|
||||||
|
"clear_tags" => {
|
||||||
|
self.cache
|
||||||
|
.get_mut(uuid)
|
||||||
|
.chain_err(|| "missing uuid")?
|
||||||
|
.set_tags(None as Option<Vec<String>>);
|
||||||
|
self.cache.write()?;
|
||||||
|
}
|
||||||
|
"postpone" => {
|
||||||
|
str2cmd(&format!(
|
||||||
|
"task {} mod wait:{}",
|
||||||
|
uuid,
|
||||||
|
self.dialog.input_line(
|
||||||
|
format!(
|
||||||
|
"How long do you want to postpone {}",
|
||||||
|
task_name
|
||||||
|
),
|
||||||
|
vec!["tomorrow"],
|
||||||
|
)?
|
||||||
|
)).output()?;
|
||||||
|
self.cache.refresh()?;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_inbox(&mut self) -> Result<()> {
|
||||||
|
if self.cache
|
||||||
|
.filter(|t| {
|
||||||
|
t.gen_name() == Some(&"Leere Inbox".into()) && t.pending()
|
||||||
|
})
|
||||||
|
.len() > 0
|
||||||
|
{
|
||||||
|
while let Some(uuid) = self.get_sorted_uuids(|t| task_inbox(&self.cache, t))
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
{
|
||||||
|
self.handle_task(&uuid)?;
|
||||||
|
}
|
||||||
|
for task in self.cache.filter_mut(|t| {
|
||||||
|
t.gen_name() == Some(&"Leere Inbox".into()) && t.pending()
|
||||||
|
})
|
||||||
|
{
|
||||||
|
task.tw_done()
|
||||||
|
}
|
||||||
|
self.cache.write()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_project(&mut self, uuid: &Uuid) -> Result<bool> {
|
||||||
|
let task_name = print_task(self.cache.get(uuid).chain_err(|| "missing uuid")?);
|
||||||
|
let mut new_tasks = vec![];
|
||||||
|
loop {
|
||||||
|
match enter_new_task(
|
||||||
|
&mut self.dialog,
|
||||||
|
format!("Adding sub tasks of {}\n\n(Esc to cancel)", task_name),
|
||||||
|
) {
|
||||||
|
Ok(mut task) => {
|
||||||
|
task.set_partof(Some(uuid.clone()));
|
||||||
|
new_tasks.push(task.uuid().clone());
|
||||||
|
self.cache.set(task);
|
||||||
|
self.cache.write()?;
|
||||||
|
}
|
||||||
|
Err(Error(EK::DialogError(DEK::InputCanceled), _)) => break,
|
||||||
|
err => {
|
||||||
|
err?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if new_tasks.len() > 0 {
|
||||||
|
for uuid in new_tasks {
|
||||||
|
self.handle_task(&uuid)?;
|
||||||
|
}
|
||||||
|
update_tasks(&mut self.cache)?;
|
||||||
|
self.cache.write()?;
|
||||||
|
return Ok(true);
|
||||||
|
} else {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_task(&mut self, uuid: &Uuid) -> Result<()> {
|
||||||
|
let task_name = print_task(self.cache.get(uuid).chain_err(
|
||||||
|
|| "handle_task: missing uuid",
|
||||||
|
)?);
|
||||||
|
match self.dialog.select_option(
|
||||||
|
format!(
|
||||||
|
"Handling Task: {}\nCan this be done in under 2 minutes?",
|
||||||
|
task_name
|
||||||
|
),
|
||||||
|
vec![
|
||||||
|
("Yes: I'll get to it", Some(true)),
|
||||||
|
(
|
||||||
|
"No: Do you know how short 2 minutes are?",
|
||||||
|
Some(false)
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Edit: I'll change that task on my own",
|
||||||
|
None
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)? {
|
||||||
|
Some(true) => {
|
||||||
|
self.cache.get_mut(uuid).chain_err(|| "BUG!")?.tw_start();
|
||||||
|
self.cache.write()?;
|
||||||
|
bail!("Work on Task now!");
|
||||||
|
}
|
||||||
|
Some(false) => (),
|
||||||
|
None => {
|
||||||
|
self.edit_task(uuid)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if task_needs_sorting(&self.cache, uuid)? {
|
||||||
|
self.sort(uuid)?;
|
||||||
|
}
|
||||||
|
if !self.make_project(uuid)? {
|
||||||
|
if let Some(tag) = self.dialog.select_option(
|
||||||
|
format!(
|
||||||
|
"Handling Task: {}\nWhen will you do this?",
|
||||||
|
print_task(
|
||||||
|
self.cache.get(uuid).chain_err(|| "missing uuid")?,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
vec![
|
||||||
|
("Optional: I might never", Some("optional")),
|
||||||
|
("Later: This has to wait", Some("later")),
|
||||||
|
(
|
||||||
|
"Await: Somebody else has to do this",
|
||||||
|
Some("await")
|
||||||
|
),
|
||||||
|
("PC: When I'm at my computer", Some("pc")),
|
||||||
|
("Work: While working", Some("work")),
|
||||||
|
(
|
||||||
|
"Research: While doing research",
|
||||||
|
Some("research")
|
||||||
|
),
|
||||||
|
("Home: When I'm at home", Some("home")),
|
||||||
|
("Edit: This task instead", None),
|
||||||
|
],
|
||||||
|
)?
|
||||||
|
{
|
||||||
|
self.cache
|
||||||
|
.get_mut(uuid)
|
||||||
|
.chain_err(|| "missing uuid")?
|
||||||
|
.add_tag(tag);
|
||||||
|
self.cache.write()?;
|
||||||
|
} else {
|
||||||
|
self.edit_task(uuid)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_accounting(&mut self) -> Result<()> {
|
||||||
|
if self.cache
|
||||||
|
.filter(|t| {
|
||||||
|
t.gen_name() == Some(&"Aktualisiere Buchhaltung".into()) && t.pending()
|
||||||
|
})
|
||||||
|
.len() > 0
|
||||||
|
{
|
||||||
|
str2cmd("urxvt -e sh -c")
|
||||||
|
.arg("jali -l. && task gen_id:'Aktualisiere Buchhaltung' done")
|
||||||
|
.output()?;
|
||||||
|
}
|
||||||
|
self.cache.write()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_next_task(&mut self) -> Result<()> {
|
||||||
|
while self.cache
|
||||||
|
.filter(|t| t.start().is_some() && t.pending())
|
||||||
|
.len() == 0 &&
|
||||||
|
self.cache
|
||||||
|
.filter(|t| {
|
||||||
|
t.pending() && self.is_relevant(t) && !task_blocked(&self.cache, t)
|
||||||
|
})
|
||||||
|
.len() > 0
|
||||||
|
{
|
||||||
|
if let Some(uuid) = {
|
||||||
|
let next_tasks = self.get_sorted_tasks(|t| {
|
||||||
|
t.pending() && self.is_relevant(t) && !task_blocked(&self.cache, t)
|
||||||
|
}).into_iter()
|
||||||
|
.map(|t| (print_task_short(t), Some(t.uuid().clone())))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
self.dialog.select_option(
|
||||||
|
"What are you going to do now?",
|
||||||
|
once(("Manual: Edit my tasks".into(), None))
|
||||||
|
.chain(next_tasks.into_iter()),
|
||||||
|
)?
|
||||||
|
}
|
||||||
|
{
|
||||||
|
self.edit_task(&uuid)?;
|
||||||
|
} else {
|
||||||
|
str2cmd("tasklauncher").output()?;
|
||||||
|
self.cache.refresh()?;
|
||||||
|
return self.select_next_task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn is_relevant(&self, task: &Task) -> bool {
|
||||||
|
let can_do_this_here = |location| match location {
|
||||||
|
Location::Home => task.has_tag("home"),
|
||||||
|
Location::City => task.has_tag("city"),
|
||||||
|
Location::Uni => task.has_tag("uni"),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
match self.state.mode {
|
||||||
|
Mode::Research => task.has_tag("research"),
|
||||||
|
Mode::Work => {
|
||||||
|
task.has_tag("work") || task.has_tag("pc") || can_do_this_here(self.state.location)
|
||||||
|
}
|
||||||
|
Mode::Orga => task.has_tag("pc") || can_do_this_here(self.state.location),
|
||||||
|
Mode::Idle => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn change_state() -> Result<()> {
|
||||||
|
Kassandra::new()?.confirm_state()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_tasks() -> Result<()> {
|
||||||
|
Kassandra::new()?.get_notes()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kassandra() -> Result<()> {
|
||||||
|
Kassandra::new()?.run()
|
||||||
|
}
|
|
@ -1,108 +1,36 @@
|
||||||
extern crate dialog;
|
extern crate dialog;
|
||||||
|
extern crate uuid;
|
||||||
extern crate task_hookrs;
|
extern crate task_hookrs;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
extern crate kairos;
|
||||||
|
extern crate chrono;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate error_chain;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
extern crate serde_yaml;
|
||||||
|
|
||||||
|
pub mod hotkeys;
|
||||||
|
pub mod generate;
|
||||||
|
pub mod refresh;
|
||||||
|
pub mod update;
|
||||||
|
pub mod kassandra;
|
||||||
|
pub mod tasktree;
|
||||||
|
|
||||||
pub mod hotkeys {
|
pub mod error {
|
||||||
use std::rc::Rc;
|
use task_hookrs::error as terror;
|
||||||
use dialog::DialogProvider;
|
use dialog::errors as derror;
|
||||||
use dialog::errors::Error;
|
use serde_yaml;
|
||||||
use dialog::errors::ErrorKind::*;
|
error_chain! {
|
||||||
use dialog::rofi::RofiDialogProvider;
|
links {
|
||||||
use std::process::Command as StdCommand;
|
TaskError(terror::Error, terror::ErrorKind);
|
||||||
use std::os::unix::process::CommandExt;
|
DialogError(derror::Error, derror::ErrorKind);
|
||||||
pub use hotkeys::Next::*;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum Next {
|
|
||||||
Menu(Dialog),
|
|
||||||
TmpMenu(Dialog),
|
|
||||||
Run(Command),
|
|
||||||
Fork(Command),
|
|
||||||
Exec(Command),
|
|
||||||
Back,
|
|
||||||
Exit,
|
|
||||||
Stay,
|
|
||||||
Script(Rc<Fn(State) -> Next>),
|
|
||||||
}
|
|
||||||
|
|
||||||
type Dialog = (String, Vec<Item>);
|
|
||||||
|
|
||||||
type Item = (String, Next);
|
|
||||||
|
|
||||||
type Command = Vec<String>;
|
|
||||||
|
|
||||||
type State = String;
|
|
||||||
|
|
||||||
pub fn c<T>(string: T) -> String
|
|
||||||
where
|
|
||||||
T: Into<String>,
|
|
||||||
{
|
|
||||||
string.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cmd<S, K>(argv: S) -> Command
|
|
||||||
where
|
|
||||||
S: IntoIterator<Item = K>,
|
|
||||||
K: Into<String>,
|
|
||||||
{
|
|
||||||
argv.into_iter().map(|x| x.into()).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn show_menu<T: DialogProvider>(dialog_provider: &mut T, menu: Dialog) -> Next {
|
|
||||||
let (msg, options) = menu;
|
|
||||||
match dialog_provider.select_option(msg, options) {
|
|
||||||
Ok(next) => next,
|
|
||||||
Err(Error(InputCanceled, _)) => Exit,
|
|
||||||
Err(Error(InvalidUserInput, _)) => Stay,
|
|
||||||
Err(err) => {
|
|
||||||
println!("DialogError: {}", err);
|
|
||||||
Stay
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
foreign_links {
|
||||||
|
Io(::std::io::Error);
|
||||||
|
Yaml(serde_yaml::Error);
|
||||||
fn build_command(cmd: Command) -> StdCommand {
|
PathError(::std::env::JoinPathsError);
|
||||||
let mut cmd_iter = cmd.iter();
|
|
||||||
let mut prg = StdCommand::new(cmd_iter.next().expect("Called program without name"));
|
|
||||||
for arg in cmd_iter {
|
|
||||||
prg.arg(arg);
|
|
||||||
}
|
|
||||||
prg
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main_loop(startmenu: Next) {
|
|
||||||
let mut dialog_provider = RofiDialogProvider;
|
|
||||||
let mut history = vec![];
|
|
||||||
let mut next = startmenu;
|
|
||||||
loop {
|
|
||||||
next = match next {
|
|
||||||
Exit => break,
|
|
||||||
Back => {
|
|
||||||
history.pop().expect("Empty history");
|
|
||||||
Stay
|
|
||||||
}
|
|
||||||
Script(script) => script(c("work")),
|
|
||||||
TmpMenu(menu) => show_menu(&mut dialog_provider, menu),
|
|
||||||
Menu(menu) => {
|
|
||||||
history.push(menu.clone());
|
|
||||||
show_menu(&mut dialog_provider, menu)
|
|
||||||
}
|
|
||||||
Fork(cmd) => {
|
|
||||||
build_command(cmd).spawn().is_ok();
|
|
||||||
Stay
|
|
||||||
}
|
|
||||||
Run(cmd) => {
|
|
||||||
build_command(cmd).output().is_ok();
|
|
||||||
Stay
|
|
||||||
}
|
|
||||||
Exec(cmd) => {
|
|
||||||
build_command(cmd).exec();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Stay => Menu(history.pop().expect("Empty history").clone()),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
74
packages/rust-scripts/src/refresh.rs
Normal file
74
packages/rust-scripts/src/refresh.rs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
use chrono::offset::{Local, TimeZone};
|
||||||
|
|
||||||
|
use kairos::timetype::TimeType as TT;
|
||||||
|
use kairos::iter::Iter;
|
||||||
|
use kairos::error::Result as KairosResult;
|
||||||
|
|
||||||
|
use task_hookrs::status::TaskStatus as TS;
|
||||||
|
use task_hookrs::task::Task;
|
||||||
|
use task_hookrs::cache::TaskCache;
|
||||||
|
use task_hookrs::error::{Result, ResultExt};
|
||||||
|
use task_hookrs::date::Date;
|
||||||
|
|
||||||
|
use generate::TaskGenerator;
|
||||||
|
use tasktree::TaskNode;
|
||||||
|
|
||||||
|
pub enum Timer {
|
||||||
|
DeadTime(TT),
|
||||||
|
Repetition(Iter),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TaskRefresher {
|
||||||
|
fn reactivate<T>(&mut self, tasks: T, recurrence: Timer) -> Result<()>
|
||||||
|
where
|
||||||
|
T: IntoIterator<Item = Task>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaskRefresher for TaskCache {
|
||||||
|
fn reactivate<T>(&mut self, tasks: T, recurrence: Timer) -> Result<()>
|
||||||
|
where
|
||||||
|
T: IntoIterator<Item = Task>,
|
||||||
|
{
|
||||||
|
let now = TT::Moment(Local::now().naive_local());
|
||||||
|
let recent = match recurrence {
|
||||||
|
Timer::DeadTime(time) => {
|
||||||
|
(now - time).calculate().chain_err(
|
||||||
|
|| "Failed to calculate recent from deadtime",
|
||||||
|
)?
|
||||||
|
}
|
||||||
|
Timer::Repetition(iter) => {
|
||||||
|
iter.filter_map(KairosResult::ok)
|
||||||
|
.take_while(|t| *t <= now)
|
||||||
|
.last()
|
||||||
|
.ok_or("Repetition starts in the future")?
|
||||||
|
.clone()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut uuids = vec![];
|
||||||
|
let changes = tasks
|
||||||
|
.into_iter()
|
||||||
|
.filter(|task| if let Some(old) = self.get_by_gen(&task) {
|
||||||
|
if old.obsolete() &&
|
||||||
|
TT::Moment(
|
||||||
|
Local
|
||||||
|
.from_utc_datetime(
|
||||||
|
&**old.end().expect("Ended tasks have to have an end date"),
|
||||||
|
)
|
||||||
|
.naive_local(),
|
||||||
|
) < recent
|
||||||
|
{
|
||||||
|
uuids.push(old.uuid().clone());
|
||||||
|
}
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
for uuid in uuids {
|
||||||
|
let old = self.get_mut(&uuid).expect("BUG!");
|
||||||
|
*old.status_mut() = TS::Pending;
|
||||||
|
old.set_end(None as Option<Date>);
|
||||||
|
}
|
||||||
|
self.generate(changes)
|
||||||
|
}
|
||||||
|
}
|
169
packages/rust-scripts/src/tasktree.rs
Normal file
169
packages/rust-scripts/src/tasktree.rs
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use task_hookrs::task::Task;
|
||||||
|
use task_hookrs::status::TaskStatus as TS;
|
||||||
|
use task_hookrs::cache::TaskCache;
|
||||||
|
use task_hookrs::uda::UDAValue;
|
||||||
|
|
||||||
|
use error::{Result, ResultExt};
|
||||||
|
|
||||||
|
pub trait TaskNode {
|
||||||
|
fn partof(&self) -> Result<Option<Uuid>>;
|
||||||
|
fn set_partof(&mut self, Option<Uuid>);
|
||||||
|
fn add_tag<T: Into<String>>(&mut self, T);
|
||||||
|
fn remove_tag<T: Into<String>>(&mut self, T);
|
||||||
|
fn has_tag<T: Into<String>>(&self, T) -> bool;
|
||||||
|
fn tagged(&self) -> bool;
|
||||||
|
fn pending(&self) -> bool;
|
||||||
|
fn obsolete(&self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaskNode for Task {
|
||||||
|
fn partof(&self) -> Result<Option<Uuid>> {
|
||||||
|
Ok(if let Some(uuid) = self.uda().get("partof".into()) {
|
||||||
|
if let &UDAValue::Str(ref uuid) = uuid {
|
||||||
|
Some(Uuid::parse_str(uuid).chain_err(|| "No uuid in partof uda")?)
|
||||||
|
} else {
|
||||||
|
Err("No String in partof uda")?
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_partof(&mut self, partof: Option<Uuid>) {
|
||||||
|
if let Some(uuid) = partof {
|
||||||
|
self.uda_mut().insert(
|
||||||
|
"partof".into(),
|
||||||
|
UDAValue::Str(uuid.to_string()),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.uda_mut().remove("partof".into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_tag<T: Into<String>>(&mut self, tag: T) {
|
||||||
|
let tag = tag.into();
|
||||||
|
if !self.has_tag(tag.clone()) {
|
||||||
|
if self.tags().is_some() {
|
||||||
|
self.tags_mut().unwrap().push(tag);
|
||||||
|
} else {
|
||||||
|
self.set_tags(Some(Some(tag)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_tag<T: Into<String>>(&mut self, tag: T) {
|
||||||
|
if let Some(tags) = self.tags_mut() {
|
||||||
|
let tag = tag.into();
|
||||||
|
tags.retain(|t| *t != tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_tag<T: Into<String>>(&self, tag: T) -> bool {
|
||||||
|
self.tags()
|
||||||
|
.map(|tags| tags.contains(&tag.into()))
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tagged(&self) -> bool {
|
||||||
|
self.tags().map(|t| t.len() > 0).unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pending(&self) -> bool {
|
||||||
|
*self.status() == TS::Pending
|
||||||
|
}
|
||||||
|
|
||||||
|
fn obsolete(&self) -> bool {
|
||||||
|
*self.status() == TS::Completed || *self.status() == TS::Deleted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TreeCache {
|
||||||
|
fn get_parent(&self, uuid: &Uuid) -> Result<Option<&Task>>;
|
||||||
|
fn get_parent_mut(&mut self, uuid: &Uuid) -> Result<Option<&mut Task>>;
|
||||||
|
fn get_children(&self, uuid: &Uuid) -> Vec<&Task>;
|
||||||
|
fn get_children_mut(&mut self, uuid: &Uuid) -> Vec<&mut Task>;
|
||||||
|
fn get_project_path(&self, uuid: &Uuid) -> Result<String>;
|
||||||
|
fn is_project(&self, uuid: &Uuid) -> bool;
|
||||||
|
fn refresh_tree(&mut self);
|
||||||
|
}
|
||||||
|
fn get_project_name(cache: &TaskCache, task: &Task) -> Result<Option<String>> {
|
||||||
|
Ok(if let Some(parent_uuid) = task.partof()? {
|
||||||
|
Some(cache.get_project_path(&parent_uuid)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TreeCache for TaskCache {
|
||||||
|
fn get_parent(&self, uuid: &Uuid) -> Result<Option<&Task>> {
|
||||||
|
let task = self.get(uuid).chain_err(|| "task uuid not found")?;
|
||||||
|
Ok(if let Some(uuid) = task.partof()? {
|
||||||
|
Some(self.get(&uuid).chain_err(|| "parent uuid not found")?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_parent_mut(&mut self, uuid: &Uuid) -> Result<Option<&mut Task>> {
|
||||||
|
let parent_option = self.get(uuid).chain_err(|| "task uuid not found")?.partof()?;
|
||||||
|
Ok(if let Some(uuid) = parent_option {
|
||||||
|
Some(self.get_mut(&uuid).chain_err(|| "parent uuid not found")?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_children(&self, uuid: &Uuid) -> Vec<&Task> {
|
||||||
|
self.filter(|t| t.partof().unwrap_or(None) == Some(*uuid))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_children_mut(&mut self, uuid: &Uuid) -> Vec<&mut Task> {
|
||||||
|
self.filter_mut(|t| t.partof().unwrap_or(None) == Some(*uuid))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_project_path(&self, uuid: &Uuid) -> Result<String> {
|
||||||
|
let task = self.get(uuid).chain_err(|| "Uuid not found in Cache")?;
|
||||||
|
let end = task.description().to_lowercase().replace(
|
||||||
|
char::is_whitespace,
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
Ok(if let Some(parent) = task.partof()? {
|
||||||
|
format!("{}.{}", self.get_project_path(&parent)?, end)
|
||||||
|
} else {
|
||||||
|
end
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_project(&self, uuid: &Uuid) -> bool {
|
||||||
|
self.get_children(uuid)
|
||||||
|
.iter()
|
||||||
|
.filter(|t| !t.obsolete())
|
||||||
|
.count() > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn refresh_tree(&mut self) {
|
||||||
|
let task_uuids = self.filter(|t| {
|
||||||
|
!t.obsolete() &&
|
||||||
|
(get_project_name(self, t)
|
||||||
|
.map(|path| path.as_ref() != t.project())
|
||||||
|
.unwrap_or(false) ||
|
||||||
|
(self.is_project(t.uuid()) != t.has_tag("project")))
|
||||||
|
}).iter()
|
||||||
|
.map(|t| t.uuid().clone())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
for task_uuid in task_uuids {
|
||||||
|
let new_project_name = get_project_name(self, self.get(&task_uuid).expect("Bug"))
|
||||||
|
.expect("Bug");
|
||||||
|
let is_project = self.is_project(&task_uuid);
|
||||||
|
let task = self.get_mut(&task_uuid).expect("Bug");
|
||||||
|
task.set_project(new_project_name);
|
||||||
|
if is_project {
|
||||||
|
task.add_tag("project");
|
||||||
|
} else {
|
||||||
|
task.remove_tag("project");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
106
packages/rust-scripts/src/update.rs
Normal file
106
packages/rust-scripts/src/update.rs
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
use task_hookrs::error::Result;
|
||||||
|
use task_hookrs::cache::TaskCache;
|
||||||
|
use task_hookrs::task::{Task, TaskBuilder};
|
||||||
|
use generate::GeneratedTask;
|
||||||
|
use refresh::{TaskRefresher, Timer};
|
||||||
|
use tasktree::TreeCache;
|
||||||
|
use chrono::NaiveDate;
|
||||||
|
use kairos::timetype::TimeType as TT;
|
||||||
|
use kairos::iter::extensions::{Weekly, Monthly, Daily};
|
||||||
|
|
||||||
|
fn simple_task(name: &str) -> Task {
|
||||||
|
let mut task = TaskBuilder::default().description(name).build().expect(
|
||||||
|
"TaskBuilding failed inspite of set description",
|
||||||
|
);
|
||||||
|
task.set_gen_name(Some(name));
|
||||||
|
task.set_gen_id(Some(name));
|
||||||
|
task
|
||||||
|
}
|
||||||
|
|
||||||
|
fn simple_tasks<'a, T>(names: T) -> Vec<Task>
|
||||||
|
where
|
||||||
|
T: IntoIterator<Item = &'a str>,
|
||||||
|
{
|
||||||
|
names.into_iter().map(simple_task).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_tasks(cache: &mut TaskCache) -> Result<()> {
|
||||||
|
let daily = || {
|
||||||
|
Timer::Repetition(
|
||||||
|
TT::moment(NaiveDate::from_ymd(2018, 5, 8).and_hms(20, 0, 0))
|
||||||
|
.daily(1)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let weekly = || {
|
||||||
|
Timer::Repetition(
|
||||||
|
TT::moment(NaiveDate::from_ymd(2018, 5, 8).and_hms(20, 0, 0))
|
||||||
|
.weekly(1)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let monthly = || {
|
||||||
|
Timer::Repetition(
|
||||||
|
TT::moment(NaiveDate::from_ymd(2018, 5, 3).and_hms(20, 0, 0))
|
||||||
|
.monthly(1)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
cache.reactivate(
|
||||||
|
simple_tasks(vec![
|
||||||
|
"Staubsaugen",
|
||||||
|
"Putze Waschbecken",
|
||||||
|
"Wäsche sortieren und entscheiden, welche Waschgänge notwendig sind",
|
||||||
|
]),
|
||||||
|
Timer::DeadTime(TT::weeks(2)),
|
||||||
|
)?;
|
||||||
|
cache.reactivate(
|
||||||
|
simple_tasks(
|
||||||
|
vec!["Reinige Toilette", "Zehennägel schneiden"],
|
||||||
|
),
|
||||||
|
Timer::DeadTime(TT::weeks(4)),
|
||||||
|
)?;
|
||||||
|
cache.reactivate(
|
||||||
|
simple_tasks(vec!["Friseurtermin machen"]),
|
||||||
|
Timer::DeadTime(TT::weeks(6)),
|
||||||
|
)?;
|
||||||
|
cache.reactivate(
|
||||||
|
simple_tasks(vec![
|
||||||
|
"Aktualisiere Buchhaltung",
|
||||||
|
"Leere Inbox",
|
||||||
|
"Sortiere Tasktree",
|
||||||
|
"Sortiere Inbox",
|
||||||
|
"Sortiere Inbox Auslandskoordination",
|
||||||
|
"Sortiere Inbox Kiva",
|
||||||
|
"Update nixos apollo",
|
||||||
|
"Update home apollo",
|
||||||
|
"Update home fb4",
|
||||||
|
"Update home hera",
|
||||||
|
"Update home charon",
|
||||||
|
"Klavier üben",
|
||||||
|
]),
|
||||||
|
daily(),
|
||||||
|
)?;
|
||||||
|
cache.reactivate(
|
||||||
|
simple_tasks(vec!["Verbuche Kontoauszüge"]),
|
||||||
|
monthly(),
|
||||||
|
)?;
|
||||||
|
cache.reactivate(
|
||||||
|
simple_tasks(vec![
|
||||||
|
"Kontrolliere Spam",
|
||||||
|
"Korrigiere Portemonnaiezählstand",
|
||||||
|
"Sortiere Archiv",
|
||||||
|
"Sortiere Archiv Kiva",
|
||||||
|
"Sortiere Archiv Auslandskoordination",
|
||||||
|
"Kontrolliere +later",
|
||||||
|
"Kontrolliere +optional",
|
||||||
|
"Kontrolliere +await",
|
||||||
|
"Block leeren und wegsortieren",
|
||||||
|
"Leere Kiva Fächer",
|
||||||
|
"Inbox zu Hause wegsortieren",
|
||||||
|
]),
|
||||||
|
weekly(),
|
||||||
|
)?;
|
||||||
|
cache.refresh_tree();
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in a new issue