From c896c102a3eec105d6f9be82904a91f68e4a9fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Tue, 12 Mar 2024 14:00:04 +0100 Subject: [PATCH] Updates --- symlinks/bin/t | 125 +++++++++- symlinks/config/fish/completions/t.fish | 11 + .../config/nvim/lua/esensar/lsp/servers.lua | 10 +- .../sway/conf.d/15_workspace_assignment | 2 +- .../config/systemd/user/ra-multiplex.service | 9 + symlinks/config/waybar/config | 213 ------------------ symlinks/config/waybar/config.jsonc | 211 +++++++++++++++++ symlinks/config/waybar/style.css | 37 ++- 8 files changed, 388 insertions(+), 230 deletions(-) create mode 100644 symlinks/config/systemd/user/ra-multiplex.service delete mode 100644 symlinks/config/waybar/config create mode 100644 symlinks/config/waybar/config.jsonc diff --git a/symlinks/bin/t b/symlinks/bin/t index 4ac928d..acb6c24 100755 --- a/symlinks/bin/t +++ b/symlinks/bin/t @@ -20,9 +20,13 @@ usage () { echo "Generates input for ledger-cli time tracking" echo -e "\nUsage: time COMMAND [options] [arguments] \n" echo "Commands:" - echo " in - starts a new time entry" - echo " out - completes an old time entry" - echo " bal - outputs current timesheet" + echo " in - starts a new time entry" + echo " out - completes an old time entry" + echo " toggle - toggle current timer" + echo " bal - outputs current timesheet" + echo " invoice - generate an invoice from account balance" + echo " invoice_list - generate data for an invoice from account balance" + echo " waybar - generate output for waybar module" echo "" echo "Options:" echo " -h --help - prints this help message (if one of commands is passed, prints help message for that command)" @@ -44,9 +48,9 @@ usage_in () { echo " -h --help - prints this help message" echo " -v --verbose - enables verbose logging" echov "Examples:" - echov " > time in project:test" + echov " > t in project:test" echov "" - echov " > time in project:test parsing" + echov " > t in project:test parsing" } usage_out () { @@ -60,7 +64,7 @@ usage_out () { echo " -h --help - prints this help message" echo " -v --verbose - enables verbose logging" echov "Examples:" - echov " > time out project:test" + echov " > t out project:test" } usage_bal () { @@ -74,7 +78,7 @@ usage_bal () { echo " -h --help - prints this help message" echo " -v --verbose - enables verbose logging" echov "Examples:" - echov " > time bal project:test" + echov " > t bal project:test" } POSITIONAL=() @@ -145,6 +149,101 @@ time_bal () { ledger -f "$TIMESHEET_LEDGER_HOME/main.journal" bal $PROJECT $COMMENT } +time_bal () { + ledger -f "$TIMESHEET_LEDGER_HOME/main.journal" bal $PROJECT $COMMENT +} + +time_invoice () { + tail -n 1 $TIMESHEET_LEDGER_HOME/timesheets/$(date +%Y).journal | grep -Eq "^i.*\$" && echo "Please stop current timer before generating an invoice!" && exit 1 + if [ -z "$INVOICE_GENERATOR_HOME" ]; then + echo "INVOICE_GENERATOR_HOME variable not defined. It must point to a directory that hosts your invoice templates and stores invoices." + exit 1 + fi + if [ -z "$PROJECT" ]; then + echo "Project is required!" + exit 1 + fi + if [ -z "$COMMENT" ]; then + echo "Task is required!" + exit 1 + fi + echo "Please generate an invoice manually! This is the total" + t invoice_list "$PROJECT" "$COMMENT" + + echo "====" + echo "Please input amount to invoice" + read -p "Amount in EUR: " AMOUNT + + CLIENT=$(echo $PROJECT | cut -f3 -d ":") + echo "Please input a directory name for this invoice" + read -p "Directory name: " DIRECTORY_NAME + echo "Please input a title for this invoice" + read -p "Title: " INVOICE_TITLE + + INVOICE_DIR="$INVOICE_GENERATOR_HOME/invoices/$CLIENT/$DIRECTORY_NAME" + INVOICE_FILE="$INVOICE_DIR/invoice.tex" + mkdir "$INVOICE_DIR" + cp "$INVOICE_GENERATOR_HOME/invoices/$CLIENT/template.tex" "$INVOICE_DIR/invoice.tex" + sed -i "s/===INVOICETITLE===/$INVOICE_TITLE/" "$INVOICE_FILE" + + INVOICE_ITEMS="" + HOURLY_RATE="50" + + read -p "Would you like to customize entries? [Y/n]" CUSTOMIZE + + if [ "Y" == "$CUSTOMIZE" ]; then + while read -p "Enter name for invoice entry. Empty name ends input: " ENTRY_NAME; do + if [ -z "$ENTRY_NAME" ]; then + echo "Done with reading entries." + break + fi + + read -p "Enter number of hours for this entry ($ENTRY_NAME): " HOURS + INVOICE_ITEMS="$INVOICE_ITEMS \\\\invoiceitem{$ENTRY_NAME}{$HOURS}{$HOURLY_RATE}{}\n" + done + else + read -p "Enter number of hours for this invoice: " HOURS + INVOICE_ITEMS="$INVOICE_ITEMS \\\\invoiceitem{Development work (hourly)}{$HOURS}{$HOURLY_RATE}{}\n" + fi + + sed -i "s/===INVOICETABLE===/$INVOICE_ITEMS/" "$INVOICE_FILE" + LAST_PWD="$PWD" + + echo "" >> "$TIMESHEET_LEDGER_HOME/invoices/$(date +%Y).journal" + echo "$(date '+%Y-%m-%d') * $COMMENT" >> "$TIMESHEET_LEDGER_HOME/invoices/$(date +%Y).journal" + echo " ($PROJECT) -$(ledger -f "$TIMESHEET_LEDGER_HOME/main.journal" bal $PROJECT and @"$COMMENT" --format "%(total)")" >> "$TIMESHEET_LEDGER_HOME/invoices/$(date +%Y).journal" + echo " Invoiced:$(echo $PROJECT | sed "s/Project://") $AMOUNT€" >> "$TIMESHEET_LEDGER_HOME/invoices/$(date +%Y).journal" + echo " Magic" >> "$TIMESHEET_LEDGER_HOME/invoices/$(date +%Y).journal" + + echo "Generated an invoice in $INVOICE_DIR/invoice.tex" + echo "Please review it and use pdflatex to generate it!" +} + +time_invoice_list () { + if [ -z "$PROJECT" ]; then + echo "Project is required!" + exit 1 + fi + if [ -z "$COMMENT" ]; then + ledger -f "$TIMESHEET_LEDGER_HOME/main.journal" reg --by-payee "$PROJECT" + else + ledger -f "$TIMESHEET_LEDGER_HOME/main.journal" reg --by-payee "$PROJECT" and @"$COMMENT" + fi +} + +time_toggle () { + LAST_PROJECT=$(ledger reg -f $TIMESHEET_LEDGER_HOME/timesheets/$(date +%Y).journal --tail 1 --format "%(account)") + LAST_COMMENT=$(ledger reg -f $TIMESHEET_LEDGER_HOME/timesheets/$(date +%Y).journal --tail 1 --format "%(payee)") + tail -n 1 $TIMESHEET_LEDGER_HOME/timesheets/$(date +%Y).journal | grep -Eq "^i.*\$" && t out "$LAST_PROJECT" "$LAST_COMMENT" || t in "$LAST_PROJECT" "$LAST_COMMENT" +} + +time_waybar () { + TOOLTIP=$(ledger reg -f $TIMESHEET_LEDGER_HOME/main.journal --tail 1 --format "Current: %(account) -- %(payee) %(scrub(amount))") + CLASS=$(tail -n 1 $TIMESHEET_LEDGER_HOME/timesheets/$(date +%Y).journal | grep -Eq "^i.*\$" && echo "active" || echo "paused") + TEXT=$(tail -n 1 $TIMESHEET_LEDGER_HOME/timesheets/$(date +%Y).journal | grep -Eq "^i.*\$" && echo "󱎫" || echo "󱎬") + echo "{\"text\":\"$TEXT\", \"tooltip\":\"$TOOLTIP\", \"class\":\"$CLASS\",\"alt\":\"$CLASS\"}" +} + case $COMMAND in in) time_in @@ -155,6 +254,18 @@ case $COMMAND in bal) time_bal ;; + invoice) + time_invoice + ;; + invoice_list) + time_invoice_list + ;; + toggle) + time_toggle + ;; + waybar) + time_waybar + ;; *) usage $COMMAND; exit 1 ;; esac diff --git a/symlinks/config/fish/completions/t.fish b/symlinks/config/fish/completions/t.fish index 18a71b6..777ea50 100644 --- a/symlinks/config/fish/completions/t.fish +++ b/symlinks/config/fish/completions/t.fish @@ -19,7 +19,11 @@ complete -c t -x -l help -s h -d "print usage help" complete -c t -x -l verbose -s v -d "verbose output" complete -c t -x -n "__fish_use_subcommand" -a in -d "start tracking time for a project" complete -c t -x -n "__fish_use_subcommand" -a out -d "stop tracking time for a project" +complete -c t -x -n "__fish_use_subcommand" -a toggle -d "toggle tracking time" complete -c t -x -n "__fish_use_subcommand" -a bal -d "print current balance" +complete -c t -x -n "__fish_use_subcommand" -a invoice -d "generate an invoice" +complete -c t -x -n "__fish_use_subcommand" -a invoice_list -d "generate invoice data" +complete -c t -x -n "__fish_use_subcommand" -a waybar -d "generate data for waybar" # In complete -c t -x -n "__fish_seen_subcommand_from in" -n "__fish_timesheets_arg_number 2" -a '(__fish-timesheets-available-projects)' @@ -30,3 +34,10 @@ complete -c t -x -n "__fish_seen_subcommand_from out" -a '(__fish-timesheets-run # Bal complete -c t -x -n "__fish_seen_subcommand_from bal" -a '(__fish-timesheets-available-projects)' + +# Invoice +complete -c t -x -n "__fish_seen_subcommand_from invoice" -n "__fish_timesheets_arg_number 2" -a '(__fish-timesheets-available-projects)' +complete -c t -x -n "__fish_seen_subcommand_from invoice" -n "__fish_timesheets_arg_number 3" -a '(__fish-timesheets-existing-comments)' + +# Invoice list +complete -c t -x -n "__fish_seen_subcommand_from invoice_list" -a '(__fish-timesheets-available-projects)' diff --git a/symlinks/config/nvim/lua/esensar/lsp/servers.lua b/symlinks/config/nvim/lua/esensar/lsp/servers.lua index 032fc3e..3afde82 100644 --- a/symlinks/config/nvim/lua/esensar/lsp/servers.lua +++ b/symlinks/config/nvim/lua/esensar/lsp/servers.lua @@ -90,6 +90,14 @@ vim.g.rustaceanvim = { on_attach = function(client, bufnr) common_config.on_attach(client, bufnr) end, + cmd = {"ra-multiplex"}, + -- init_options = { + -- lspMux = { + -- version = "1", + -- method = "connect", + -- server = "rust-analyzer", + -- }, + -- }, settings = { ["rust-analyzer"] = { checkOnSave = { @@ -103,7 +111,7 @@ vim.g.rustaceanvim = { }, cargo = { loadOutDirsFromCheck = true, - features = "all" + features = "all", }, }, }, diff --git a/symlinks/config/sway/conf.d/15_workspace_assignment b/symlinks/config/sway/conf.d/15_workspace_assignment index d067c3d..6ebbf0f 100644 --- a/symlinks/config/sway/conf.d/15_workspace_assignment +++ b/symlinks/config/sway/conf.d/15_workspace_assignment @@ -3,7 +3,7 @@ assign [app_id="firefox"] $browser_workspace assign [class="Hexchat"] $chat_workspace assign [class="Slack"] $chat_workspace assign [class="discord"] $chat_workspace -assign [instance="element"] $chat_workspace +assign [instance="Element"] $chat_workspace assign [class="Gvim"] $editor_workspace assign [class="jetbrains-idea-ce"] $ide_workspace assign [class="jetbrains-idea"] $ide_workspace diff --git a/symlinks/config/systemd/user/ra-multiplex.service b/symlinks/config/systemd/user/ra-multiplex.service new file mode 100644 index 0000000..9c56c55 --- /dev/null +++ b/symlinks/config/systemd/user/ra-multiplex.service @@ -0,0 +1,9 @@ +[Unit] +Description=Rust analyzer multiplex server + +[Service] +Type=simple +ExecStart=%h/.asdf/shims/ra-multiplex-server + +[Install] +WantedBy=default.target diff --git a/symlinks/config/waybar/config b/symlinks/config/waybar/config deleted file mode 100644 index 64a6c64..0000000 --- a/symlinks/config/waybar/config +++ /dev/null @@ -1,213 +0,0 @@ -// ============================================================================= -// -// Waybar configuration -// -// Configuration reference: https://github.com/Alexays/Waybar/wiki/Configuration -// -// This configuration is based on: https://github.com/robertjk/dotfiles/ -// -// ============================================================================= - -{ - // ------------------------------------------------------------------------- - // Global configuration - // ------------------------------------------------------------------------- - - "layer": "top", - - "position": "top", - - // If height property would be not present, it'd be calculated dynamically - "height": 30, - - "modules-left": [ - "sway/workspaces", - "sway/mode" - ], - "modules-center": [ - "clock#date", - "clock#time", - "custom/notification" - ], - "modules-right": [ - "network", - "pulseaudio", - "backlight", - "memory", - "cpu", - "temperature", - "custom/keyboard-layout", - "battery", - "tray", - "idle_inhibitor", - "custom/power-menu" - ], - - - // ------------------------------------------------------------------------- - // Modules - // ------------------------------------------------------------------------- - - "battery": { - "interval": 10, - "states": { - "warning": 30, - "critical": 15 - }, - // Connected to AC - "format": " {icon} {capacity}%", // Icon: bolt - // Not connected to AC - "format-discharging": "{icon} {capacity}%", - "format-icons": [ - "", // Icon: battery-full - "", // Icon: battery-three-quarters - "", // Icon: battery-half - "", // Icon: battery-quarter - "" // Icon: battery-empty - ], - "tooltip": true - }, - - "clock#time": { - "interval": 1, - "format": "{:%H:%M}", - "tooltip": true - }, - - "clock#date": { - "interval": 10, - "format": " {:%e %b %Y}", // Icon: calendar-alt - "tooltip-format": "{:%e %B %Y}", - "on-click": "gnome-calendar" - }, - - "cpu": { - "interval": 5, - "format": " {usage}% ({load})", // Icon: microchip - "states": { - "warning": 70, - "critical": 90 - } - }, - - "custom/keyboard-layout": { - "exec": "swaymsg -t get_inputs | grep -m1 'xkb_active_layout_name' | cut -d '\"' -f4", - // Interval set only as a fallback, as the value is updated by signal - "interval": 30, - "format": " {}", // Icon: keyboard - // Signal sent by Sway key binding (~/.config/sway/key-bindings) - "signal": 1, // SIGHUP - "tooltip": false - }, - - "memory": { - "interval": 5, - "format": " {}%", // Icon: memory - "states": { - "warning": 70, - "critical": 90 - } - }, - - "network": { - "interval": 5, - "format-wifi": " {essid} ({signalStrength}%)", // Icon: wifi - "format-ethernet": " Connected", // Icon: ethernet - "format-disconnected": "⚠ Disconnected", - "tooltip-format": "{ifname}: {ipaddr}" - }, - - "sway/mode": { - "format": "{}", // Icon: expand-arrows-alt - "tooltip": false - }, - - "sway/workspaces": { - "all-outputs": false, - "disable-scroll": true, - "persistent-workspaces": { - "": [] - }, - "format": "{icon}{name}", - "format-icons": { - "urgent": "", - "focused": "", - "default": "" - } - }, - - "backlight": { - "device": "amdgpu_bl0", - "format": "{icon} {percent}%", - "format-icons": ["", ""], - "on-scroll-up": "brightnessctl set +1%", - "on-scroll-down": "brightnessctl set 1%-" - }, - - "pulseaudio": { - //"scroll-step": 1, - "format": "{icon} {volume}%", - "format-bluetooth": "{icon} {volume}%", - "format-muted": "", - "format-icons": { - "headphones": "", - "handsfree": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": ["", ""] - }, - "on-click": "pavucontrol" - }, - - "temperature": { - "critical-threshold": 80, - "interval": 5, - "format": "{icon} {temperatureC}°C", - "format-icons": [ - "", // Icon: temperature-empty - "", // Icon: temperature-quarter - "", // Icon: temperature-half - "", // Icon: temperature-three-quarters - "" // Icon: temperature-full - ], - "tooltip": true - }, - - "tray": { - "icon-size": 16, - "spacing": 5 - }, - - "idle_inhibitor": { - "format": "{icon}", - "format-icons": { - "activated": "", - "deactivated": "" - } - }, - - "custom/power-menu": { - "tooltip": false, - "format": "", - "on-click": "wlogout" - }, - - "custom/notification": { - "tooltip": false, - "format": "{icon}", - "format-icons": { - "notification": "", - "none": "", - "dnd-notification": "", - "dnd-none": "" - }, - "return-type": "json", - "exec-if": "which swaync-client", - "exec": "swaync-client -swb", - "on-click": "swaync-client -t -sw", - "on-click-right": "swaync-client -d -sw", - "escape": true - }, -} diff --git a/symlinks/config/waybar/config.jsonc b/symlinks/config/waybar/config.jsonc new file mode 100644 index 0000000..1099a70 --- /dev/null +++ b/symlinks/config/waybar/config.jsonc @@ -0,0 +1,211 @@ +// ============================================================================= +// +// Waybar configuration +// +// Configuration reference: https://github.com/Alexays/Waybar/wiki/Configuration +// +// This configuration is based on: https://github.com/robertjk/dotfiles/ +// +// ============================================================================= +[ + { + // ------------------------------------------------------------------------- + // Global configuration + // ------------------------------------------------------------------------- + "layer": "top", + "position": "top", + // If height property would be not present, it'd be calculated dynamically + "height": 30, + "modules-left": [ + "sway/workspaces", + "sway/mode" + ], + "modules-center": [ + "custom/current-task", + "clock#date", + "clock#time", + "custom/notification" + ], + "modules-right": [ + "network", + "pulseaudio", + "backlight", + "disk", + "memory", + "cpu", + "temperature", + "custom/keyboard-layout", + "battery", + "tray", + "idle_inhibitor", + "custom/power-menu" + ], + // ------------------------------------------------------------------------- + // Modules + // ------------------------------------------------------------------------- + "battery": { + "interval": 10, + "states": { + "warning": 30, + "critical": 15 + }, + // Connected to AC + "format": " {icon} {capacity}%", // Icon: bolt + // Not connected to AC + "format-discharging": "{icon} {capacity}%", + "format-icons": [ + "", // Icon: battery-full + "", // Icon: battery-three-quarters + "", // Icon: battery-half + "", // Icon: battery-quarter + "" // Icon: battery-empty + ], + "tooltip": true + }, + "clock#time": { + "interval": 1, + "format": "{:%H:%M}", + "tooltip": true + }, + "clock#date": { + "interval": 10, + "format": " {:%e %b %Y}", // Icon: calendar-alt + "tooltip-format": "{:%e %B %Y}", + "on-click": "gnome-calendar" + }, + "cpu": { + "interval": 5, + "format": " {usage}% ({load})", // Icon: microchip + "states": { + "warning": 70, + "critical": 90 + } + }, + "custom/keyboard-layout": { + "exec": "swaymsg -t get_inputs | grep -m1 'xkb_active_layout_name' | cut -d '\"' -f4", + // Interval set only as a fallback, as the value is updated by signal + "interval": 30, + "format": " {}", // Icon: keyboard + // Signal sent by Sway key binding (~/.config/sway/key-bindings) + "signal": 1, // SIGHUP + "tooltip": false + }, + "disk": { + "interval": 30, + "format": " {percentage_used}%" + }, + "memory": { + "interval": 5, + "format": "󰍛 {}%", // Icon: memory + "states": { + "warning": 70, + "critical": 90 + } + }, + "network": { + "interval": 5, + "format-wifi": " {essid} ({signalStrength}%)", // Icon: wifi + "format-ethernet": " Connected", // Icon: ethernet + "format-disconnected": "⚠ Disconnected", + "tooltip-format": "{ifname}: {ipaddr}" + }, + "sway/mode": { + "format": "{}", // Icon: expand-arrows-alt + "tooltip": false + }, + "sway/workspaces": { + "all-outputs": false, + "disable-scroll": true, + "persistent-workspaces": { + "": [] + }, + "format": "{icon}{name}", + "format-icons": { + "urgent": "", + "focused": "", + "default": "" + } + }, + "backlight": { + "device": "amdgpu_bl0", + "format": "{icon} {percent}%", + "format-icons": [ + "", + "" + ], + "on-scroll-up": "brightnessctl set +1%", + "on-scroll-down": "brightnessctl set 1%-" + }, + "pulseaudio": { + //"scroll-step": 1, + "format": "{icon} {volume}%", + "format-bluetooth": "{icon} {volume}%", + "format-muted": "", + "format-icons": { + "headphones": "󰋋", + "handsfree": "󰋎", + "headset": "󰋎", + "phone": "", + "portable": "", + "car": "", + "default": [ + "", + "" + ] + }, + "on-click": "pavucontrol" + }, + "temperature": { + "critical-threshold": 80, + "interval": 5, + "format": "{icon} {temperatureC}°C", + "format-icons": [ + "", // Icon: temperature-empty + "", // Icon: temperature-quarter + "", // Icon: temperature-half + "", // Icon: temperature-three-quarters + "" // Icon: temperature-full + ], + "tooltip": true + }, + "tray": { + "icon-size": 16, + "spacing": 5 + }, + "idle_inhibitor": { + "format": "{icon}", + "format-icons": { + "activated": "", + "deactivated": "" + } + }, + "custom/power-menu": { + "tooltip": false, + "format": "", + "on-click": "wlogout" + }, + "custom/notification": { + "tooltip": false, + "format": "{icon}", + "format-icons": { + "notification": "", + "none": "", + "dnd-notification": "", + "dnd-none": "" + }, + "return-type": "json", + "exec-if": "which swaync-client", + "exec": "swaync-client -swb", + "on-click": "swaync-client -t -sw", + "on-click-right": "swaync-client -d -sw", + "escape": true + }, + "custom/current-task": { + "interval": 10, + "exec": "source ~/.profile && exec t waybar", + "on-click": "source ~/.profile && exec t toggle", + "exec-on-event": true, + "return-type": "json" + } + } +] diff --git a/symlinks/config/waybar/style.css b/symlinks/config/waybar/style.css index 3921ea5..e55d9b5 100644 --- a/symlinks/config/waybar/style.css +++ b/symlinks/config/waybar/style.css @@ -50,16 +50,11 @@ /* The whole bar */ #waybar { - background: #323232; color: white; - font-family: Cantarell, Noto Sans, sans-serif; + font-family: SauceCodePro Nerd Font Propo; font-size: 14px; } -#workspaces { - font-family: SauceCodePro Nerd Font; -} - /* Each module */ #battery, #clock, @@ -70,9 +65,16 @@ #network, #pulseaudio, #temperature, +#custom-current-task, +#custom-apps-menu, +#custom-power-menu, +#custom-notification, +#idle_inhibitor, +#workspaces, +#backlight, #tray { - padding-left: 10px; - padding-right: 10px; + margin-left: 8px; + margin-right: 8px; } @@ -183,12 +185,14 @@ font-weight: bold; font-size: 18px; padding-right: 10px; + margin: 0px; } #custom-power-menu { font-weight: bold; font-size: 18px; padding-right: 10px; + margin: 0px; } #custom-apps-menu { @@ -197,6 +201,23 @@ padding-right: 10px; } +#custom-current-task { + font-weight: bold; + margin-left: 16px; +} + +#custom-current-task.active { + color: green; +} + +#custom-current-task.paused { + color: gray; +} + +#workspaces { + margin: 0px; +} + #workspaces button { border-top: 2px solid transparent; /* To compensate for the top border and still have vertical centering */