From 07a619060ab1503de69e4a0b8c85f188211af28e Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Thu, 6 Mar 2025 21:16:58 +0100 Subject: [PATCH 01/10] nvim: Disable history when editing jrnl files --- nvim/.config/nvim/lua/core/commands.lua | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/nvim/.config/nvim/lua/core/commands.lua b/nvim/.config/nvim/lua/core/commands.lua index ef17d87..70f9365 100644 --- a/nvim/.config/nvim/lua/core/commands.lua +++ b/nvim/.config/nvim/lua/core/commands.lua @@ -5,18 +5,35 @@ vim.api.nvim_create_autocmd({ "TextYankPost" }, { group = vim.api.nvim_create_augroup("highlightyanks", { clear = true }), }) +local private_mode = function() + vim.o.shada = "" + vim.o.swapfile = false + vim.o.undofile = false + vim.o.backup = false + vim.o.writebackup = false + vim.o.shelltemp = false + vim.o.history = 0 + vim.o.modeline = false + vim.o.secure = true +end -- Special setting for editing gopass files - make sure nothing leaks outside the directories it -- is supposed to vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { + group = vim.api.nvim_create_augroup("passnoleak", { clear = true }), pattern = { "/dev/shm/gopass.*", "/dev/shm/pass.?*/?*.txt", "$TMPDIR/pass.?*/?*.txt", "/tmp/pass.?*/?*.txt", }, - command = "setlocal noswapfile nobackup noundofile nowritebackup viminfo=", desc = "Don't leak any information when editing potential password files", - group = vim.api.nvim_create_augroup("passnoleak", { clear = true }), + callback = private_mode, +}) +vim.api.nvim_create_autocmd({ "BufNewFile", "BufReadPre" }, { + group = vim.api.nvim_create_augroup("PrivateJrnl", {}), + pattern = "*.jrnl", + desc = "Don't leak information when editing jrnl files", + callback = private_mode, }) -- remove line numbers from terminal buffers From 554e13cd366b307e115626e992a3ad777e1ecb4a Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Thu, 6 Mar 2025 21:16:58 +0100 Subject: [PATCH 02/10] river: Fix pass-pick invocation Running pass-pick (or other gpg requiring software) through river was not correctly accessing the gpg agent since being managed by runit user service did not point them to the correct gpg agent socket. This commit fixes it using keychain as auxiliary software to manage a session-long gpg agent process which is also exported into the turnstile environment so other runit services can make use of it. --- desktop/.config/river/init | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/desktop/.config/river/init b/desktop/.config/river/init index 1f142af..21dd169 100755 --- a/desktop/.config/river/init +++ b/desktop/.config/river/init @@ -4,6 +4,12 @@ if [ -d "$TURNSTILE_ENV_DIR" ]; then echo "$DISPLAY" >"$TURNSTILE_ENV_DIR/DISPLAY" echo "$WAYLAND_DISPLAY" >"$TURNSTILE_ENV_DIR/WAYLAND_DISPLAY" + echo "ADDING KEYCHAIN TO ENV" + keychain --eval --quiet --agents ssh,gpg C414FF88A557F29AFEF76C7E73BA40D5AFAF49C9 + echo "$SSH_AUTH_SOCK">"$TURNSTILE_ENV_DIR/SSH_AUTH_SOCK" + echo "$SSH_AGENT_PID">"$TURNSTILE_ENV_DIR/SSH_AGENT_PID" + echo "$GPG_AGENT_INFO">"$TURNSTILE_ENV_DIR/GPG_AGENT_INFO" + echo "DONE ADDING KEYCHAIN TO ENV" fi mod="Mod4" From 47a96a2d42518e28daa78166318de3721478f720 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Fri, 7 Mar 2025 14:20:01 +0100 Subject: [PATCH 03/10] scripts: Fix powermenu log out without elogind On my current voidlinux system I have no access to elogind and riverwm will just be restarted when I exit it (since it is watched over by a user service). My session is started by the display manager 'greetd' (which in turn runs tuigreet but that is not important here). So, to log out of the session - we do a search for the 'greetd' process and if we find it we search its _child_ processes which are the ones that we can kill without being a super user. If we kill the right process here, the session will close (since the 'watched' process exits and greetd just takes over again). This would be a little easier if we started riverwm through greetd directly but I like this indirection for stability (automatic service restarts), flexibility (I can stop the riverwm service independent of my session), and adaption (we can use Turnstile environment variables between my session services). So we just close all the processes that are children of greetd -- perhaps we accidentally catch a process which is _not_ the root session process run by greetd but we'll kill it nevertheless since all child processes might stop greetd from taking over (and they would be closed anyway when ending the session afaik). I have no linger enabled on my system so far (user processes staying enabled after log-out) and I do not know how that would interact with this method. --- scripts/.local/bin/powermenu | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/.local/bin/powermenu b/scripts/.local/bin/powermenu index 64f3cdf..71495c1 100755 --- a/scripts/.local/bin/powermenu +++ b/scripts/.local/bin/powermenu @@ -85,6 +85,11 @@ case "$result" in if [ -n "$POWERMENU_LOGOUT_CMD" ]; then eval "$POWERMENU_LOGOUT_CMD"; else command -v i3 >/dev/null 2>&1 && i3-msg exit command -v riverctl >/dev/null 2>&1 && riverctl exit + # Try to heuristically find the program started by greetd and shut it down. + # Generally this will just be a 'pause' program on my system. + if command -v pgrep >/dev/null 2>&1 && pgrep greetd; then + kill $(pgrep -P "$(pgrep greetd | tr '\n' ',')" pause) + fi fi ;; "Suspend" | "$suspend_btn") From ea066eebb5d16dc0b0c81fa741e516d292e1be1c Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Sat, 8 Mar 2025 08:41:53 +0100 Subject: [PATCH 04/10] waybar: Fix event module spacing Added a new state which should fix the icon spacing issues: When we have no upcoming events or upcoming events but none today, we only display the icon and so we do not add any additional spacing. (This is alt state `event` or `no-event`) Only if we have an upcoming event today (alt state `event-today`) are we printing it directly on the status bar and only then should be have additional spacing. So we have an icon (the same as for event) with the correct spacing so that whether there is text on the statusbar or not, we space correctly. --- desktop/.config/waybar/config | 1 + desktop/.config/waybar/modules/khal.py | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/desktop/.config/waybar/config b/desktop/.config/waybar/config index 0d72df1..8b3dcf2 100644 --- a/desktop/.config/waybar/config +++ b/desktop/.config/waybar/config @@ -64,6 +64,7 @@ "format": "{icon}{0}", // issue tracked here https://github.com/Alexays/Waybar/issues/3623 "format-icons": { "event": "", + "event-today": " ", "no-event": "", }, }, diff --git a/desktop/.config/waybar/modules/khal.py b/desktop/.config/waybar/modules/khal.py index 6dc3971..76f4280 100755 --- a/desktop/.config/waybar/modules/khal.py +++ b/desktop/.config/waybar/modules/khal.py @@ -27,13 +27,16 @@ for line in lines: if len(clean_line) and clean_line[0] not in ["0", "1", "2"]: clean_line = "\n" + clean_line + "" new_lines.append(clean_line) + output = "\n".join(new_lines).strip() -data["alt"] = "no-event" -data["tooltip"] = output - -if today in output: +if today in output: # an event today! + data["alt"] = "event-today" data["text"] = output.split("\n")[1] +elif output: # an event in the week! data["alt"] = "event" + data["tooltip"] = output +else: # no events + data["alt"] = "no-event" print(json.dumps(data)) From a01431609f9f3949dad157d375fcb5157c999e15 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Sat, 8 Mar 2025 08:41:53 +0100 Subject: [PATCH 05/10] zk: Set working dir to wiki for aliases Instead of finding the notebook at the wikiroot, we directly change the current working dir to the notebook for the runtime of the zk command. This has a couple advantages: Any other commands executed will also pick up the correct directory, and creating notes in a specific directory also just _works_ by giving a directory in the notes dir even if we are somewhere else. --- writing/zk/config/sh/alias.d/zk.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/writing/zk/config/sh/alias.d/zk.sh b/writing/zk/config/sh/alias.d/zk.sh index 344b589..78a57b5 100644 --- a/writing/zk/config/sh/alias.d/zk.sh +++ b/writing/zk/config/sh/alias.d/zk.sh @@ -2,7 +2,7 @@ # _zk_wiki() { - zk --notebook-dir="$WIKIROOT" "$@" + zk --working-dir="$WIKIROOT" "$@" } n() { From 0ce49d758abdaef69aa9f4ab2ce81ec50833e7b4 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Sat, 8 Mar 2025 08:41:53 +0100 Subject: [PATCH 06/10] zk: Add new inbox note function Add simple alias function which allows quickly creating a note destined for the inbox by typing `nni`. --- writing/zk/config/sh/alias.d/zk.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/writing/zk/config/sh/alias.d/zk.sh b/writing/zk/config/sh/alias.d/zk.sh index 78a57b5..debc673 100644 --- a/writing/zk/config/sh/alias.d/zk.sh +++ b/writing/zk/config/sh/alias.d/zk.sh @@ -26,6 +26,9 @@ if [ -n "${WIKIROOT}" ]; then nn() { # 'new note' _zk_wiki new "$@" } + nni() { # 'new note inbox' + _zk_wiki new -t "${*}" inbox + } nnl() { # 'new note log' _zk_wiki log "$@" } From 2eebe047f6030447bb9582ef66a5047f0658f9c7 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Sat, 8 Mar 2025 19:32:50 +0100 Subject: [PATCH 07/10] nvim: Remove fzf select one option Removed the default option select one, it did not do anything. Now trying with a 'default' opt for the actual plugin. --- nvim/.config/nvim/lua/plugins/pickers.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nvim/.config/nvim/lua/plugins/pickers.lua b/nvim/.config/nvim/lua/plugins/pickers.lua index 8072d32..3682999 100644 --- a/nvim/.config/nvim/lua/plugins/pickers.lua +++ b/nvim/.config/nvim/lua/plugins/pickers.lua @@ -56,7 +56,6 @@ return { -- file/item pickers and managers end end, opts = { - fzf_opts = { ["--select-1"] = false }, keymap = { builtin = { true, @@ -78,7 +77,10 @@ return { -- file/item pickers and managers }, }, }, - }, -- FIXME: Does not seem to work with single result and still closes instantly? + defaults = { -- FIXME: Does not seem to work with single result and still closes instantly? + jump1 = false, + }, + }, config = function(_, opts) opts.actions = opts.actions or { true } opts.actions["ctrl-q"] = require("fzf-lua").actions.file_sel_to_qf From 15cf9b192b0a294594ccdcf1f246821386b24018 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Sat, 8 Mar 2025 19:32:50 +0100 Subject: [PATCH 08/10] nvim: Fix zk commands always being created They were under a conditional which would only have them be created if which-key plugin was found beforehand. --- nvim/.config/nvim/lua/plugins/prose.lua | 56 +++++++++++++++---------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/nvim/.config/nvim/lua/plugins/prose.lua b/nvim/.config/nvim/lua/plugins/prose.lua index a38a2d6..04a0844 100644 --- a/nvim/.config/nvim/lua/plugins/prose.lua +++ b/nvim/.config/nvim/lua/plugins/prose.lua @@ -168,39 +168,49 @@ local prose_plugs = { -- bring zettelkasten commands { "zk-org/zk-nvim", - config = function() + opts = function() if require("core.util").is_available("which-key") then require("which-key").add({ { "n", group = "notes" }, { "n", group = "note" }, { "n", group = "note", mode = "v" }, }) + end - require("zk.commands").add("ZkOrphans", function(opts) - opts = vim.tbl_extend("force", { orphan = true }, opts or {}) - require("zk").edit(opts, { title = "Zk Orphans" }) - end) - require("zk.commands").add("ZkGrep", function(opts) - local collection = {} - local list_opts = { select = { "title", "path", "absPath" } } - require("zk.api").list(vim.env.ZK_NOTEBOOK_DIR, list_opts, function(_, notes) - for _, note in ipairs(notes) do - collection[note.absPath] = note.title or note.path - end - end) - local options = vim.tbl_deep_extend("force", { - prompt_title = "Notes", - search_dirs = { vim.env.ZK_NOTEBOOK_DIR }, - disable_coordinates = true, - path_display = function(_, path) - return collection[path] - end, - }, opts or {}) - require("telescope.builtin").live_grep(options) + require("zk.commands").add("ZkOrphans", function(opts) + opts = vim.tbl_extend("force", { orphan = true }, opts or {}) + require("zk").edit(opts, { title = "Zk Orphans" }) + end) + require("zk.commands").add("ZkGrep", function(opts) + local collection = {} + local list_opts = { select = { "title", "path", "absPath" } } + require("zk.api").list(vim.env.ZK_NOTEBOOK_DIR, list_opts, function(_, notes) + for _, note in ipairs(notes) do + collection[note.absPath] = note.title or note.path + end end) + local search_dir = vim.env.ZK_NOTEBOOK_DIR + local options = vim.tbl_deep_extend("force", { + prompt = "Note Grep❯ ", + -- cmd = "cd " .. search_dir .. "; rg --vimgrep", + cwd = search_dir, + disable_coordinates = true, + path_display = function(_, path) + return collection[path] + end, + }, opts or {}) + -- FIXME: Don't hard-code this so much? + -- require("telescope.builtin").live_grep(options) + require("fzf-lua").live_grep(options) + end) + local picker = "select" + if require("core.util").is_available("fzf-lua") then + picker = "fzf_lua" + elseif require("core.util").is_available("telescope") then + picker = "telescope" end require("zk").setup({ - picker = "telescope", + picker = picker, lsp = { auto_attach = { enabled = true, From 41754c5d247a90c27b67bde9d21883ec22d9dd47 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Sat, 8 Mar 2025 19:32:50 +0100 Subject: [PATCH 09/10] qutebrowser: Fallback to wezterm terminal by default Since the starting parameters are fairly hardwired for wezterm anyway I don't see this making much sense with e.g. xterm. However, long-term, we should rather change the hard-dependency instead of doing it this way. --- qutebrowser/config/config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 6697977..058d0b4 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -1,12 +1,12 @@ import os from typing import cast +from freedirect.freedirect import Redirects + # pylint: disable=C0111 from qutebrowser.config.config import ConfigContainer # noqa: F401 from qutebrowser.config.configfiles import ConfigAPI -from freedirect.freedirect import Redirects - config: ConfigAPI = cast(ConfigAPI, config) # noqa: F821 pylint: disable=E0602,C0103 c: ConfigContainer = cast(ConfigContainer, c) # noqa: F821 pylint: disable=E0602,C0103 @@ -25,7 +25,7 @@ c.content.javascript.log_message.excludes = { "userscript:_qute_js": ["*TrustedHTML*"], } -term = os.getenv("TERMINAL", "xterm") +term = os.getenv("TERMINAL", "wezterm") c.completion.web_history.max_items = 1000 c.hints.uppercase = True From c6de9b068611de3d81ce524e9cdb2c487dfc0851 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Mon, 10 Mar 2025 20:17:42 +0100 Subject: [PATCH 10/10] task: Add new git backup hook for version 3 First exports tasks to plaintext before backing them up with git. --- .../DISABLED.on-exit.sync-to-server-silent.py | 29 --------- .../share/task/hooks/on-exit.git-backup | 65 +++++++++++++++++++ .../.local/share/task/hooks/on-exit.git-sync | 39 ----------- 3 files changed, 65 insertions(+), 68 deletions(-) delete mode 100755 office/.local/share/task/hooks/DISABLED.on-exit.sync-to-server-silent.py create mode 100755 office/.local/share/task/hooks/on-exit.git-backup delete mode 100755 office/.local/share/task/hooks/on-exit.git-sync diff --git a/office/.local/share/task/hooks/DISABLED.on-exit.sync-to-server-silent.py b/office/.local/share/task/hooks/DISABLED.on-exit.sync-to-server-silent.py deleted file mode 100755 index f444c69..0000000 --- a/office/.local/share/task/hooks/DISABLED.on-exit.sync-to-server-silent.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python3 - -# From: https://gist.github.com/varunagrawal/2b93c5dc721520ff6876e940c420ab05 -# This hooks script syncs task warrior to the configured task server. -# The on-exit event is triggered once, after all processing is complete. - -# Make sure hooks are enabled and this hook script is executable. -# Run `task diag` for diagnostics on the hook. - -import sys -import json -import subprocess - -try: - tasks = json.loads(sys.stdin.readline()) -except: - # No input - sys.exit(0) - -# no tasks to work through, don't error -if len(tasks) <= 0: - sys.exit(0) - -# Call the `sync` command -# hooks=0 ensures that the sync command doesn't call the on-exit hook -# verbose=nothing sets the verbosity to print nothing at all -subprocess.Popen(["task", "rc.verbose=nothing", "rc.hooks=0", "sync"], close_fds=True) - -sys.exit(0) diff --git a/office/.local/share/task/hooks/on-exit.git-backup b/office/.local/share/task/hooks/on-exit.git-backup new file mode 100755 index 0000000..eb4d96b --- /dev/null +++ b/office/.local/share/task/hooks/on-exit.git-backup @@ -0,0 +1,65 @@ +#!/bin/sh +# Automatically git commits, pushes and pulls if doable in the taskwarrior data directory +# +# Much of this taken from: https://github.com/mrschyte/taskwarrior-hooks/ +# with much gratitude +# +# The minimum amount of time required between 2 commits in seconds. +# So only if the last commit is at least x seconds old will a new one +# be created. Set to 0 to sync each taskwarrior change. +MINIMUM_WAIT_TIME=600 + +# Do not display status information. +QUIET=true + +# Removes the tasks.json file after each run, keeping the +# task directory clean. +REMOVE_JSON=false + +if [ "${DISABLE_HOOKS}" = "true" ] || ! command -v git >/dev/null 2>&1; then + exit 0; +fi + +if [ "$1" != "api:2" ]; then + printf "Taskwarrior uses different data API version than git plugin. Aborting!" 1>&2 + exit 1 +fi + + +data_dir="$(echo "$5" | cut -f2 -d:)" +command_run="$(echo "$3" | cut -f2 -d:)" + +if [ "$command_run" = "synchronize" ]; then + DISABLE_HOOKS=true env task sync + + git -C "$data_dir" pull >/dev/null 2>&1 + pull_ret="$?" + git -C "$data_dir" push >/dev/null 2>&1 + push_ret="$?" + if [ "$pull_ret" -eq 0 ] && [ "$push_ret" -eq 0 ]; then + [ $QUIET = "true" ] || echo "Git upstream synchronized." + fi +fi + +last_commit=$(git -C "$data_dir" log -1 --format="%at") +# if now is not yet greater than last commit + wait time do nothing +if [ "$(date "+%s")" -lt $((last_commit + MINIMUM_WAIT_TIME)) ]; then + # TODO: Implement DEBUG msg level (info/debug) system + # echo "Too early to check for changes, exiting." + exit 0 +fi + +# echo "EXPORTING TASKS" +DISABLE_HOOKS=true env task export > "$data_dir/tasks.json" +# after any command, if there's changes add and commit +if ! git -C "$data_dir" diff --exit-code >/dev/null 2>&1; then + # echo "found changes" + # need to run to fully update tasks that just got done + DISABLE_HOOKS=true env task next >/dev/null 2>&1 + + header="auto: ${2##* }" + msg="full command: $2" + git -C "$data_dir" commit "$data_dir/tasks.json" -m "$header" -m "$msg" --no-gpg-sign >/dev/null 2>&1 + [ $QUIET = "true" ] || echo "Backup up to git." +fi +[ "$REMOVE_JSON" = true ] && rm "$data_dir/tasks.json" >/dev/null 2>&1 diff --git a/office/.local/share/task/hooks/on-exit.git-sync b/office/.local/share/task/hooks/on-exit.git-sync deleted file mode 100755 index 9de25c4..0000000 --- a/office/.local/share/task/hooks/on-exit.git-sync +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -# Automatically git commits, pushes and pulls if doable in the taskwarrior data directory -# -# Much of this taken from: https://github.com/mrschyte/taskwarrior-hooks/ -# with much gratitude - -if [ "${DISABLE_HOOKS}" = "true" ] || ! command -v git >/dev/null 2>&1; then - exit 0; -fi - -if [ "$1" != "api:2" ]; then - printf "Taskwarrior uses different data API version than git plugin. Aborting!" 1>&2 - exit 1 -fi - -data_dir="$(echo "$5" | cut -f2 -d:)" -command_run="$(echo "$3" | cut -f2 -d:)" - -# after any command, if there's changes add and commit -if ! git -C "$data_dir" diff --exit-code >/dev/null 2>&1; then - # need to run to fully update tasks that just got done - DISABLE_HOOKS=true env task next >/dev/null 2>&1 - - header="auto: ${2##* }" - msg="full command: $2" - git -C "$data_dir" commit -a -m "$header" -m "$msg" --no-gpg-sign >/dev/null 2>&1 -fi - -if [ "$command_run" = "synchronize" ]; then - DISABLE_HOOKS=true env task sync - - git -C "$data_dir" pull >/dev/null 2>&1 - pull_ret="$?" - git -C "$data_dir" push >/dev/null 2>&1 - push_ret="$?" - if [ "$pull_ret" -eq 0 ] && [ "$push_ret" -eq 0 ]; then - echo Git upstream synchronized. - fi -fi