main
Ensar Sarajčić 2024-03-12 14:00:04 +01:00
parent a33e1b4786
commit c896c102a3
8 changed files with 388 additions and 230 deletions

View File

@ -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

View File

@ -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)'

View File

@ -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",
},
},
},

View File

@ -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

View File

@ -0,0 +1,9 @@
[Unit]
Description=Rust analyzer multiplex server
[Service]
Type=simple
ExecStart=%h/.asdf/shims/ra-multiplex-server
[Install]
WantedBy=default.target

View File

@ -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": "<span style=\"italic\">{}</span>", // 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": "<span foreground='red'><sup></sup></span>",
"none": "",
"dnd-notification": "<span foreground='red'><sup></sup></span>",
"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
},
}

View File

@ -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": "<span style=\"italic\">{}</span>", // 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": "<span foreground='red'><sup></sup></span>",
"none": "",
"dnd-notification": "<span foreground='red'><sup></sup></span>",
"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"
}
}
]

View File

@ -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 */