stuff
This commit is contained in:
25
.bashrc
25
.bashrc
@@ -70,19 +70,20 @@ alias gpe='gopass edit'
|
||||
#######################################################
|
||||
# ALIAS
|
||||
#######################################################
|
||||
# To temporarily bypass an alias, we preceed the command with a \
|
||||
# EG: the ls command is aliased, but to use the normal ls command you would type \ls
|
||||
|
||||
alias df='cd ~/code/opalfiles'
|
||||
alias ans='cd ~/code/ansible'
|
||||
|
||||
alias v='nvim'
|
||||
alias vim='nvim'
|
||||
alias vi='nvim'
|
||||
|
||||
# DNF
|
||||
alias dnf='dnf5'
|
||||
alias din='sudo dnf5 install'
|
||||
alias dre='sudo dnf5 remove'
|
||||
alias dup='sudo dnf5 update'
|
||||
alias dse='dnf5 search'
|
||||
alias dnf='dnf'
|
||||
alias din='sudo dnf install'
|
||||
alias dre='sudo dnf remove'
|
||||
alias dup='sudo dnf update'
|
||||
alias dse='dnf search'
|
||||
|
||||
# alias to show the date
|
||||
alias da='date "+%Y-%m-%d %A %T %Z"'
|
||||
@@ -137,6 +138,9 @@ alias wget='wget --hsts-file="$XDG_CACHE_HOME/wget-hsts"'
|
||||
# Translate
|
||||
alias tbr='trans :pt-BR'
|
||||
|
||||
# ncmpcpp
|
||||
alias ncmpcpp='ncmpcpp -b ~/.config/ncmpcpp/bindings'
|
||||
|
||||
|
||||
#######################################################
|
||||
# WORK
|
||||
@@ -165,8 +169,9 @@ mkdirg() {
|
||||
function parse_git_branch {
|
||||
git branch 2>/dev/null | grep -e '^*' | sed 's/^* \(.*\)/ (\1)/'
|
||||
}
|
||||
export RED='\[\033[0;31m\]'
|
||||
export BLUE='\[\033[0;34m\]'
|
||||
|
||||
RED='\[\033[0;31m\]'
|
||||
BLUE='\[\033[0;34m\]'
|
||||
GREEN='\[\033[0;32m\]'
|
||||
YELLOW='\[\033[0;33m\]'
|
||||
CYAN='\[\033[0;36m\]'
|
||||
@@ -188,5 +193,3 @@ keys()
|
||||
}
|
||||
|
||||
keys
|
||||
|
||||
todo ls
|
||||
|
||||
@@ -17,4 +17,4 @@ y = 0
|
||||
opacity = 0.9
|
||||
|
||||
[general]
|
||||
import = ["/home/opal/.config/alacritty/solarized-dark.toml"]
|
||||
import = ["/home/opal/.config/alacritty/theme.toml"]
|
||||
|
||||
4
.config/eww/eww.yuck
Normal file
4
.config/eww/eww.yuck
Normal file
@@ -0,0 +1,4 @@
|
||||
(widget my-panel
|
||||
(box :class "panel-container"
|
||||
(label :text "Hello, world!" :class "hello-label")))
|
||||
|
||||
16
.config/eww/style.css
Normal file
16
.config/eww/style.css
Normal file
@@ -0,0 +1,16 @@
|
||||
* {
|
||||
all: unset;
|
||||
font-family: "JetBrainsMono Nerd Font", "monospace";
|
||||
}
|
||||
|
||||
.panel-container {
|
||||
background-color: rgba(30, 30, 30, 0.9);
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.hello-label {
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
}
|
||||
14
.config/mpd/mpd.conf
Normal file
14
.config/mpd/mpd.conf
Normal file
@@ -0,0 +1,14 @@
|
||||
music_directory "~/music"
|
||||
playlist_directory "~/.local/share/mpd/playlists"
|
||||
db_file "~/.local/share/mpd/db"
|
||||
log_file "~/.local/share/mpd/log"
|
||||
pid_file "~/.local/share/mpd/pid"
|
||||
state_file "~/.local/share/mpd/state"
|
||||
sticker_file "~/.local/share/mpd/sticker.sql"
|
||||
bind_to_address "~/.local/share/mpd/socket"
|
||||
|
||||
audio_output {
|
||||
type "pulse"
|
||||
name "My Audio"
|
||||
}
|
||||
|
||||
479
.config/ncmpcpp/bindings
Normal file
479
.config/ncmpcpp/bindings
Normal file
@@ -0,0 +1,479 @@
|
||||
##############################################################
|
||||
## This is the example bindings file. Copy it to ##
|
||||
## ~/.ncmpcpp/bindings or $XDG_CONFIG_HOME/ncmpcpp/bindings ##
|
||||
## and set up your preferences ##
|
||||
##############################################################
|
||||
#
|
||||
#def_key "mouse"
|
||||
# mouse_event
|
||||
#
|
||||
#def_key "up"
|
||||
# scroll_up
|
||||
#
|
||||
#def_key "shift-up"
|
||||
# select_item
|
||||
# scroll_up
|
||||
#
|
||||
#def_key "down"
|
||||
# scroll_down
|
||||
#
|
||||
#def_key "shift-down"
|
||||
# select_item
|
||||
# scroll_down
|
||||
#
|
||||
#def_key "["
|
||||
# scroll_up_album
|
||||
#
|
||||
#def_key "]"
|
||||
# scroll_down_album
|
||||
#
|
||||
#def_key "{"
|
||||
# scroll_up_artist
|
||||
#
|
||||
#def_key "}"
|
||||
# scroll_down_artist
|
||||
#
|
||||
#def_key "page_up"
|
||||
# page_up
|
||||
#
|
||||
#def_key "page_down"
|
||||
# page_down
|
||||
#
|
||||
#def_key "home"
|
||||
# move_home
|
||||
#
|
||||
#def_key "end"
|
||||
# move_end
|
||||
#
|
||||
#def_key "insert"
|
||||
# select_item
|
||||
#
|
||||
#def_key "enter"
|
||||
# enter_directory
|
||||
#
|
||||
#def_key "enter"
|
||||
# toggle_output
|
||||
#
|
||||
#def_key "enter"
|
||||
# run_action
|
||||
#
|
||||
#def_key "enter"
|
||||
# play_item
|
||||
#
|
||||
#def_key "space"
|
||||
# add_item_to_playlist
|
||||
#
|
||||
#def_key "space"
|
||||
# toggle_lyrics_update_on_song_change
|
||||
#
|
||||
#def_key "space"
|
||||
# toggle_visualization_type
|
||||
#
|
||||
#def_key "delete"
|
||||
# delete_playlist_items
|
||||
#
|
||||
#def_key "delete"
|
||||
# delete_browser_items
|
||||
#
|
||||
#def_key "delete"
|
||||
# delete_stored_playlist
|
||||
#
|
||||
#def_key "right"
|
||||
# next_column
|
||||
#
|
||||
#def_key "right"
|
||||
# slave_screen
|
||||
#
|
||||
#def_key "right"
|
||||
# volume_up
|
||||
#
|
||||
#def_key "+"
|
||||
# volume_up
|
||||
#
|
||||
#def_key "left"
|
||||
# previous_column
|
||||
#
|
||||
#def_key "left"
|
||||
# master_screen
|
||||
#
|
||||
#def_key "left"
|
||||
# volume_down
|
||||
#
|
||||
#def_key "-"
|
||||
# volume_down
|
||||
#
|
||||
#def_key ":"
|
||||
# execute_command
|
||||
#
|
||||
#def_key "tab"
|
||||
# next_screen
|
||||
#
|
||||
#def_key "shift-tab"
|
||||
# previous_screen
|
||||
#
|
||||
#def_key "f1"
|
||||
# show_help
|
||||
#
|
||||
#def_key "1"
|
||||
# show_playlist
|
||||
#
|
||||
#def_key "2"
|
||||
# show_browser
|
||||
#
|
||||
#def_key "2"
|
||||
# change_browse_mode
|
||||
#
|
||||
#def_key "3"
|
||||
# show_search_engine
|
||||
#
|
||||
#def_key "3"
|
||||
# reset_search_engine
|
||||
#
|
||||
#def_key "4"
|
||||
# show_media_library
|
||||
#
|
||||
#def_key "4"
|
||||
# toggle_media_library_columns_mode
|
||||
#
|
||||
#def_key "5"
|
||||
# show_playlist_editor
|
||||
#
|
||||
#def_key "6"
|
||||
# show_tag_editor
|
||||
#
|
||||
#def_key "7"
|
||||
# show_outputs
|
||||
#
|
||||
#def_key "8"
|
||||
# show_visualizer
|
||||
#
|
||||
#def_key "="
|
||||
# show_clock
|
||||
#
|
||||
#def_key "@"
|
||||
# show_server_info
|
||||
#
|
||||
#def_key "s"
|
||||
# stop
|
||||
#
|
||||
#def_key "p"
|
||||
# pause
|
||||
#
|
||||
#def_key ">"
|
||||
# next
|
||||
#
|
||||
#def_key "<"
|
||||
# previous
|
||||
#
|
||||
#def_key "ctrl-h"
|
||||
# jump_to_parent_directory
|
||||
#
|
||||
#def_key "ctrl-h"
|
||||
# replay_song
|
||||
#
|
||||
#def_key "backspace"
|
||||
# jump_to_parent_directory
|
||||
#
|
||||
#def_key "backspace"
|
||||
# replay_song
|
||||
#
|
||||
#def_key "f"
|
||||
# seek_forward
|
||||
#
|
||||
#def_key "b"
|
||||
# seek_backward
|
||||
#
|
||||
#def_key "r"
|
||||
# toggle_repeat
|
||||
#
|
||||
#def_key "z"
|
||||
# toggle_random
|
||||
#
|
||||
#def_key "y"
|
||||
# save_tag_changes
|
||||
#
|
||||
#def_key "y"
|
||||
# start_searching
|
||||
#
|
||||
#def_key "y"
|
||||
# toggle_single
|
||||
#
|
||||
#def_key "R"
|
||||
# toggle_consume
|
||||
#
|
||||
#def_key "Y"
|
||||
# toggle_replay_gain_mode
|
||||
#
|
||||
#def_key "T"
|
||||
# toggle_add_mode
|
||||
#
|
||||
#def_key "|"
|
||||
# toggle_mouse
|
||||
#
|
||||
#def_key "#"
|
||||
# toggle_bitrate_visibility
|
||||
#
|
||||
#def_key "Z"
|
||||
# shuffle
|
||||
#
|
||||
#def_key "x"
|
||||
# toggle_crossfade
|
||||
#
|
||||
#def_key "X"
|
||||
# set_crossfade
|
||||
#
|
||||
#def_key "u"
|
||||
# update_database
|
||||
#
|
||||
#def_key "ctrl-s"
|
||||
# sort_playlist
|
||||
#
|
||||
#def_key "ctrl-s"
|
||||
# toggle_browser_sort_mode
|
||||
#
|
||||
#def_key "ctrl-s"
|
||||
# toggle_media_library_sort_mode
|
||||
#
|
||||
#def_key "ctrl-r"
|
||||
# reverse_playlist
|
||||
#
|
||||
#def_key "ctrl-f"
|
||||
# apply_filter
|
||||
#
|
||||
#def_key "ctrl-_"
|
||||
# select_found_items
|
||||
#
|
||||
#def_key "/"
|
||||
# find
|
||||
#
|
||||
#def_key "/"
|
||||
# find_item_forward
|
||||
#
|
||||
#def_key "?"
|
||||
# find
|
||||
#
|
||||
#def_key "?"
|
||||
# find_item_backward
|
||||
#
|
||||
#def_key "."
|
||||
# next_found_item
|
||||
#
|
||||
#def_key ","
|
||||
# previous_found_item
|
||||
#
|
||||
#def_key "w"
|
||||
# toggle_find_mode
|
||||
#
|
||||
#def_key "e"
|
||||
# edit_song
|
||||
#
|
||||
#def_key "e"
|
||||
# edit_library_tag
|
||||
#
|
||||
#def_key "e"
|
||||
# edit_library_album
|
||||
#
|
||||
#def_key "e"
|
||||
# edit_directory_name
|
||||
#
|
||||
#def_key "e"
|
||||
# edit_playlist_name
|
||||
#
|
||||
#def_key "e"
|
||||
# edit_lyrics
|
||||
#
|
||||
#def_key "i"
|
||||
# show_song_info
|
||||
#
|
||||
#def_key "I"
|
||||
# show_artist_info
|
||||
#
|
||||
#def_key "g"
|
||||
# jump_to_position_in_song
|
||||
#
|
||||
#def_key "l"
|
||||
# show_lyrics
|
||||
#
|
||||
#def_key "ctrl-v"
|
||||
# select_range
|
||||
#
|
||||
#def_key "v"
|
||||
# reverse_selection
|
||||
#
|
||||
#def_key "V"
|
||||
# remove_selection
|
||||
#
|
||||
#def_key "B"
|
||||
# select_album
|
||||
#
|
||||
#def_key "a"
|
||||
# add_selected_items
|
||||
#
|
||||
#def_key "c"
|
||||
# clear_playlist
|
||||
#
|
||||
#def_key "c"
|
||||
# clear_main_playlist
|
||||
#
|
||||
#def_key "C"
|
||||
# crop_playlist
|
||||
#
|
||||
#def_key "C"
|
||||
# crop_main_playlist
|
||||
#
|
||||
#def_key "m"
|
||||
# move_sort_order_up
|
||||
#
|
||||
#def_key "m"
|
||||
# move_selected_items_up
|
||||
#
|
||||
#def_key "n"
|
||||
# move_sort_order_down
|
||||
#
|
||||
#def_key "n"
|
||||
# move_selected_items_down
|
||||
#
|
||||
#def_key "M"
|
||||
# move_selected_items_to
|
||||
#
|
||||
#def_key "A"
|
||||
# add
|
||||
#
|
||||
#def_key "S"
|
||||
# save_playlist
|
||||
#
|
||||
#def_key "o"
|
||||
# jump_to_playing_song
|
||||
#
|
||||
#def_key "G"
|
||||
# jump_to_browser
|
||||
#
|
||||
#def_key "G"
|
||||
# jump_to_playlist_editor
|
||||
#
|
||||
#def_key "~"
|
||||
# jump_to_media_library
|
||||
#
|
||||
#def_key "E"
|
||||
# jump_to_tag_editor
|
||||
#
|
||||
#def_key "U"
|
||||
# toggle_playing_song_centering
|
||||
#
|
||||
#def_key "P"
|
||||
# toggle_display_mode
|
||||
#
|
||||
#def_key "\\"
|
||||
# toggle_interface
|
||||
#
|
||||
#def_key "!"
|
||||
# toggle_separators_between_albums
|
||||
#
|
||||
#def_key "L"
|
||||
# toggle_lyrics_fetcher
|
||||
#
|
||||
#def_key "F"
|
||||
# fetch_lyrics_in_background
|
||||
#
|
||||
#def_key "alt-l"
|
||||
# toggle_fetching_lyrics_in_background
|
||||
#
|
||||
#def_key "ctrl-l"
|
||||
# toggle_screen_lock
|
||||
#
|
||||
#def_key "`"
|
||||
# toggle_library_tag_type
|
||||
#
|
||||
#def_key "`"
|
||||
# refetch_lyrics
|
||||
#
|
||||
#def_key "`"
|
||||
# add_random_items
|
||||
#
|
||||
#def_key "ctrl-p"
|
||||
# set_selected_items_priority
|
||||
#
|
||||
#def_key "q"
|
||||
# quit
|
||||
#
|
||||
#
|
||||
#def_key "f"
|
||||
# find
|
||||
#def_key "f"
|
||||
# find_item_forward
|
||||
|
||||
def_key "+"
|
||||
show_clock
|
||||
def_key "="
|
||||
volume_up
|
||||
|
||||
def_key "j"
|
||||
scroll_down
|
||||
def_key "k"
|
||||
scroll_up
|
||||
|
||||
def_key "ctrl-u"
|
||||
page_up
|
||||
#push_characters "kkkkkkkkkkkkkkk"
|
||||
def_key "ctrl-d"
|
||||
page_down
|
||||
#push_characters "jjjjjjjjjjjjjjj"
|
||||
def_key "u"
|
||||
page_up
|
||||
#push_characters "kkkkkkkkkkkkkkk"
|
||||
def_key "d"
|
||||
page_down
|
||||
#push_characters "jjjjjjjjjjjjjjj"
|
||||
def_key "h"
|
||||
previous_column
|
||||
def_key "l"
|
||||
next_column
|
||||
|
||||
def_key "."
|
||||
show_lyrics
|
||||
|
||||
def_key "n"
|
||||
next_found_item
|
||||
def_key "N"
|
||||
previous_found_item
|
||||
|
||||
# not used but bound
|
||||
def_key "J"
|
||||
move_sort_order_down
|
||||
def_key "K"
|
||||
move_sort_order_up
|
||||
def_key "h"
|
||||
jump_to_parent_directory
|
||||
def_key "l"
|
||||
enter_directory
|
||||
def_key "l"
|
||||
run_action
|
||||
def_key "l"
|
||||
play_item
|
||||
def_key "m"
|
||||
show_media_library
|
||||
def_key "m"
|
||||
toggle_media_library_columns_mode
|
||||
def_key "t"
|
||||
show_tag_editor
|
||||
def_key "v"
|
||||
show_visualizer
|
||||
def_key "G"
|
||||
move_end
|
||||
def_key "g"
|
||||
move_home
|
||||
#jump_to_position_in_song
|
||||
def_key "U"
|
||||
update_database
|
||||
def_key "s"
|
||||
reset_search_engine
|
||||
def_key "s"
|
||||
show_search_engine
|
||||
def_key "f"
|
||||
show_browser
|
||||
def_key "f"
|
||||
change_browse_mode
|
||||
def_key "x"
|
||||
delete_playlist_items
|
||||
def_key "P"
|
||||
show_playlist
|
||||
9
.config/ncmpcpp/config
Normal file
9
.config/ncmpcpp/config
Normal file
@@ -0,0 +1,9 @@
|
||||
mpd_music_dir = "~/music"
|
||||
|
||||
mpd_host = "/home/opal/.local/share/mpd/socket"
|
||||
mpd_port = "6600" # Ignored when using a socket
|
||||
|
||||
ncmpcpp_directory = "~/.config/ncmpcpp"
|
||||
lyrics_directory = "~/.config/ncmpcpp/lyrics"
|
||||
visualizer_type = "spectrum"
|
||||
|
||||
@@ -151,6 +151,7 @@ settings:
|
||||
'*://archive.org/*': true
|
||||
'*://auth.openai.com/*': true
|
||||
'*://chatgpt.com/*': true
|
||||
'*://copr.fedorainfracloud.org/*': true
|
||||
'*://damonacy.bandcamp.com/*': true
|
||||
'*://digital.fidelity.com/*': true
|
||||
'*://distrowatch.com/*': true
|
||||
|
||||
@@ -299,7 +299,7 @@ output HDMI-A-1 pos 0 402 scale 1.5
|
||||
output DP-2 scale 1.5
|
||||
|
||||
# Wallpaper
|
||||
output * bg ~/.config/wallpapers/foggy-forest.png fill #0D0703
|
||||
output * bg ~/.config/wallpapers/wall.jpg fill #0D0703
|
||||
|
||||
# Enable/Disable extra HDMI screens
|
||||
bindsym $mod+Shift+m output "HDMI-A-1" enable
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Image
|
||||
image=~/.config/wallpapers/foggy-forest.png
|
||||
image=~/.config/wallpapers/wall.jpg
|
||||
scaling=fill
|
||||
|
||||
# Indicator
|
||||
|
||||
BIN
.config/wallpapers/wall.jpg
Normal file
BIN
.config/wallpapers/wall.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.3 MiB |
224
.local/bin/todo
224
.local/bin/todo
@@ -1,45 +1,185 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env python3
|
||||
|
||||
TODO_FILE="$HOME/sync/todo/todo.txt"
|
||||
ARCHIVE_FILE="$HOME/sync/todo/todo-archive.txt"
|
||||
TODAY="$(date +%Y-%m-%d)"
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import re
|
||||
from datetime import date
|
||||
from pathlib import Path
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
from rich.prompt import Prompt, IntPrompt
|
||||
|
||||
case "$1" in
|
||||
add)
|
||||
shift
|
||||
echo "($TODAY) $*" >> "$TODO_FILE"
|
||||
echo "Added: ($TODAY) $*"
|
||||
;;
|
||||
lsa)
|
||||
nl -w2 -s'. ' "$TODO_FILE"
|
||||
;;
|
||||
ls)
|
||||
grep -v '^x ' "$TODO_FILE" | nl -w2 -s'. '
|
||||
;;
|
||||
done)
|
||||
if [ -z "$2" ]; then
|
||||
echo "Usage: $0 done <task-number>"
|
||||
exit 1
|
||||
fi
|
||||
TASK=$(sed -n "${2}p" "$TODO_FILE")
|
||||
[ -z "$TASK" ] && { echo "Invalid task number."; exit 1; }
|
||||
sed -i "${2}s/^/x ($TODAY) /" "$TODO_FILE"
|
||||
echo "Marked done: $TASK"
|
||||
;;
|
||||
archive)
|
||||
grep '^x ' "$TODO_FILE" >> "$ARCHIVE_FILE"
|
||||
sed -i '/^x /d' "$TODO_FILE"
|
||||
echo "Archived completed tasks to $ARCHIVE_FILE"
|
||||
;;
|
||||
tags)
|
||||
if [ -z "$2" ]; then
|
||||
echo "Usage: $0 tags <+tag|@context>"
|
||||
exit 1
|
||||
fi
|
||||
grep "$2" "$TODO_FILE" | grep -v '^x ' | nl -w2 -s'. '
|
||||
;;
|
||||
help|*)
|
||||
echo "Usage: $0 {add <task> | list | done <number> | archive}"
|
||||
;;
|
||||
esac
|
||||
TODAY = date.today().isoformat()
|
||||
TODO_FILE = Path.home() / "sync/todo/todo.txt"
|
||||
ARCHIVE_FILE = Path.home() / "sync/todo/todo-archive.txt"
|
||||
console = Console()
|
||||
|
||||
RE_DONE = re.compile(r"^x \((?P<done>[^)]+)\) \((?P<created>[^)]+)\) (?P<text>.+)$")
|
||||
RE_ACTIVE = re.compile(r"^\((?P<created>[^)]+)\) (?P<text>.+)$")
|
||||
|
||||
def read_tasks():
|
||||
return TODO_FILE.read_text().splitlines() if TODO_FILE.exists() else []
|
||||
|
||||
def write_tasks(tasks):
|
||||
TODO_FILE.write_text("\n".join(tasks) + "\n")
|
||||
|
||||
def parse_task(line):
|
||||
m = RE_DONE.match(line)
|
||||
if m:
|
||||
return m.group("created"), m.group("done"), m.group("text")
|
||||
m = RE_ACTIVE.match(line)
|
||||
if m:
|
||||
return m.group("created"), None, m.group("text")
|
||||
return None, None, line
|
||||
|
||||
def extract_tags(text):
|
||||
return " ".join(tok for tok in text.split() if tok.startswith("@"))
|
||||
|
||||
def show_tasks(all=False):
|
||||
table = Table(title="TODOs")
|
||||
table.add_column("#", style="bold", justify="right")
|
||||
table.add_column("Created", style="green")
|
||||
table.add_column("Done", style="magenta")
|
||||
table.add_column("Tags", style="yellow")
|
||||
table.add_column("Task", style="cyan")
|
||||
|
||||
for i, line in enumerate(read_tasks(), start=1):
|
||||
created, done, text = parse_task(line)
|
||||
if not all and done is not None:
|
||||
continue
|
||||
tags = extract_tags(text)
|
||||
table.add_row(str(i), created or "", done or "", tags, text)
|
||||
|
||||
console.print(table)
|
||||
|
||||
def add_task(text):
|
||||
line = f"({TODAY}) {text}"
|
||||
with TODO_FILE.open("a") as f:
|
||||
f.write(line + "\n")
|
||||
console.print(f"[green]Added:[/] {line}")
|
||||
|
||||
def mark_done(index):
|
||||
tasks = read_tasks()
|
||||
try:
|
||||
i = index - 1
|
||||
if i < 0 or i >= len(tasks):
|
||||
raise IndexError
|
||||
created, done, text = parse_task(tasks[i])
|
||||
if done is not None:
|
||||
console.print("[yellow]Task already marked as done.[/]")
|
||||
return
|
||||
tasks[i] = f"x ({TODAY}) ({created}) {text}"
|
||||
write_tasks(tasks)
|
||||
console.print(f"[green]Marked done:[/] {text}")
|
||||
except Exception:
|
||||
console.print("[red]Invalid task number.[/]")
|
||||
|
||||
def archive_tasks():
|
||||
tasks = read_tasks()
|
||||
done_tasks = [t for t in tasks if RE_DONE.match(t)]
|
||||
remaining = [t for t in tasks if not RE_DONE.match(t)]
|
||||
if not done_tasks:
|
||||
console.print("[yellow]No tasks to archive.[/]")
|
||||
return
|
||||
with ARCHIVE_FILE.open("a") as f:
|
||||
for t in done_tasks:
|
||||
f.write(t + "\n")
|
||||
write_tasks(remaining)
|
||||
console.print(f"[green]Archived {len(done_tasks)} completed tasks.[/]")
|
||||
|
||||
def filter_tags(tag):
|
||||
table = Table(title=f"Tasks tagged {tag}")
|
||||
table.add_column("#", justify="right")
|
||||
table.add_column("Created", style="green")
|
||||
table.add_column("Done", style="magenta")
|
||||
table.add_column("Tags", style="yellow")
|
||||
table.add_column("Task", style="cyan")
|
||||
for i, line in enumerate(read_tasks(), start=1):
|
||||
created, done, text = parse_task(line)
|
||||
if done is None and tag in text:
|
||||
tags = extract_tags(text)
|
||||
table.add_row(str(i), created or "", "", tags, text)
|
||||
console.print(table)
|
||||
|
||||
def done_interactive():
|
||||
choices = [(i, l) for i, l in enumerate(read_tasks(), start=1) if RE_ACTIVE.match(l)]
|
||||
if not choices:
|
||||
console.print("[yellow]No active tasks.[/]")
|
||||
return
|
||||
table = Table(title="Select a task to mark as done")
|
||||
table.add_column("#", justify="right")
|
||||
table.add_column("Created", style="green")
|
||||
table.add_column("Tags", style="yellow")
|
||||
table.add_column("Task", style="cyan")
|
||||
for i, line in choices:
|
||||
created, _, text = parse_task(line)
|
||||
tags = extract_tags(text)
|
||||
table.add_row(str(i), created or "", tags, text)
|
||||
console.print(table)
|
||||
try:
|
||||
choice = IntPrompt.ask("Task # to mark done")
|
||||
mark_done(choice)
|
||||
except KeyboardInterrupt:
|
||||
console.print("\n[red]^C Aborted.[/]")
|
||||
sys.exit(130)
|
||||
except Exception:
|
||||
console.print("[red]Invalid input or cancelled.[/]")
|
||||
|
||||
def edit_file():
|
||||
editor = os.getenv("EDITOR", "nano")
|
||||
os.execvp(editor, [editor, str(TODO_FILE)])
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(prog="todo")
|
||||
sub = parser.add_subparsers(dest="cmd", required=True)
|
||||
|
||||
sub.add_parser("ls", help="List active tasks")
|
||||
sub.add_parser("lsa", help="List all tasks")
|
||||
sub.add_parser("archive", help="Archive completed tasks")
|
||||
|
||||
p_done = sub.add_parser("done", help="Mark a task as done")
|
||||
p_done.add_argument("n", type=int, help="Task number")
|
||||
|
||||
sub.add_parser("donei", help="Interactive task picker")
|
||||
|
||||
p_tags = sub.add_parser("tags", help="Show tasks by tag")
|
||||
p_tags.add_argument("tag", help="+tag or @context")
|
||||
|
||||
sub.add_parser("edit", help="Edit the todo file")
|
||||
|
||||
p_add = sub.add_parser("add", help="Add a new task")
|
||||
p_add.add_argument("text", nargs=argparse.REMAINDER, help="Task description (falls back to prompt)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.cmd == "ls":
|
||||
show_tasks()
|
||||
elif args.cmd == "lsa":
|
||||
show_tasks(all=True)
|
||||
elif args.cmd == "add":
|
||||
if args.text:
|
||||
desc = " ".join(args.text).strip()
|
||||
else:
|
||||
desc = Prompt.ask("Task description")
|
||||
tags = Prompt.ask("Tags (e.g. @home @work)", default="")
|
||||
desc = f"{desc} {tags}".strip() if tags else desc
|
||||
if desc:
|
||||
add_task(desc)
|
||||
elif args.cmd == "done":
|
||||
mark_done(args.n)
|
||||
elif args.cmd == "donei":
|
||||
done_interactive()
|
||||
elif args.cmd == "archive":
|
||||
archive_tasks()
|
||||
elif args.cmd == "tags":
|
||||
filter_tags(args.tag)
|
||||
elif args.cmd == "edit":
|
||||
edit_file()
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
console.print("\n[red]^C Aborted.[/]")
|
||||
sys.exit(130)
|
||||
|
||||
Reference in New Issue
Block a user