aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md5
m---------config/nvim0
-rw-r--r--config/qutebrowser/config.py5
-rw-r--r--config/qutebrowser/security.py4
-rwxr-xr-xconfig/qutebrowser/userscripts/bookmark3
-rw-r--r--config/zsh/aliases.zsh7
-rw-r--r--config/zsh/aliases/dev.zsh31
-rw-r--r--config/zsh/aliases/edit.zsh4
-rw-r--r--config/zsh/aliases/git.zsh14
-rw-r--r--config/zsh/aliases/ls.zsh24
-rw-r--r--config/zsh/config.zsh8
-rw-r--r--config/zsh/init.zsh10
-rw-r--r--config/zsh/plugins/fzf-cd.zsh4
-rw-r--r--config/zsh/plugins/timer.zsh1
-rw-r--r--config/zsh/theme.zsh1
-rw-r--r--config/zsh/zshrc1
-rw-r--r--configuration.nix34
-rw-r--r--modules/ai/default.nix51
-rw-r--r--modules/email.home/.gitignore1
-rw-r--r--modules/email.home/aerc.conf4
-rw-r--r--modules/kakoune/default.nix25
-rw-r--r--modules/kakoune/kak-tree-sitter.nix19
-rw-r--r--modules/xresources.home.nix2
-rw-r--r--overlays/neovim.nix2
-rw-r--r--packages.nix43
-rw-r--r--packages/sensible-apps/sensible-apps.nix2
-rwxr-xr-xscripts/bin/ai48
-rwxr-xr-xscripts/bin/cbedit2
-rwxr-xr-xscripts/bin/file-manager2
-rwxr-xr-xscripts/bin/kman3
-rwxr-xr-xscripts/bin/open2
-rwxr-xr-xscripts/bin/tts23
-rwxr-xr-xscripts/orgagenda.sh98
33 files changed, 361 insertions, 122 deletions
diff --git a/README.md b/README.md
index ce61758..639952d 100644
--- a/README.md
+++ b/README.md
@@ -8,15 +8,14 @@
* `qutebrowser` - Web browser
* `feh` - Wallpaper
* `pass` - Password manager
-* `nvim` - Text editor
+* `kakoune` - Text editor
* `zsh` - My shell
* `sxiv` - Image viewer
* `mpv` - Video player
-* `lf` - File manager
+* `daffm` - File manager
* `mpd` - Music daemon
* `ncmpcpp` + `mpc` - Music client
* `dwmblocks` - Status bar text ([My fork of dwmblocks](https://github.com/phenax/dwmblocks))
* `dmenu` - Application launcher / custom menu scripts ([My fork of dmenu](https://github.com/phenax/dmenu))
* `picom` - Compositor
* `zathura` - PDF reader
-
diff --git a/config/nvim b/config/nvim
-Subproject 21c7453e30c60a2b774b3ab374971a5ff45fc85
+Subproject d1f8db7c75e2fd02710031ff989b70083543a47
diff --git a/config/qutebrowser/config.py b/config/qutebrowser/config.py
index 0a560b7..8dd14dd 100644
--- a/config/qutebrowser/config.py
+++ b/config/qutebrowser/config.py
@@ -93,7 +93,7 @@ c.input.insert_mode.auto_load = True
c.input.insert_mode.leave_on_load = True
# File selector
-lf_file_picker = ['sensible-terminal', '-c', 'lf-selector', '-g', '170x40+50+50', '-e', 'lf', '-selection-path', '{}']
+lf_file_picker = ['st', '-i', '-g', '170x40+50+50', '-e', 'sh', '-c', 'DAFFM_SELECTIONS_OUT={} daffm -c @picker']
c.fileselect.handler = 'external'
c.fileselect.single_file.command = lf_file_picker
c.fileselect.multiple_files.command = lf_file_picker
@@ -301,7 +301,8 @@ c.url.searchengines = {
'd': 'https://lite.duckduckgo.com/lite?q={}',
'gg': 'https://lite.duckduckgo.com/lite?q={}',
'go': 'https://google.com/search?q={}',
- 'ai': 'https://chatgpt.com/?temporary-chat=true&q={}',
+ 'ai': 'http://localhost:9081/?q={}',
+ 'aio': 'https://chatgpt.com/?temporary-chat=true&q={}',
'aic': 'https://claude.ai/new?q={}',
'br': 'https://search.brave.com/search?q={}',
diff --git a/config/qutebrowser/security.py b/config/qutebrowser/security.py
index 8dbd1a0..54aa159 100644
--- a/config/qutebrowser/security.py
+++ b/config/qutebrowser/security.py
@@ -21,9 +21,9 @@ def random_version(a, b):
return rand_numstr(a, b) + '.' + rand_numstr(0, 100)
def random_useragent():
- chrome_version = random_version(135, 150)
+ chrome_version = random_version(140, 150)
# firefox_version = random_version(77, 80)
- build_version = random_version(1000, 3000)
+ build_version = random_version(1000, 5000)
agents = [
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML; like Gecko) Chromium/' + chrome_version + '.0.4044.138 Chrome/' + chrome_version + '.' + build_version + ' Safari/{webkit_version}',
diff --git a/config/qutebrowser/userscripts/bookmark b/config/qutebrowser/userscripts/bookmark
index 480aed9..dd0752d 100755
--- a/config/qutebrowser/userscripts/bookmark
+++ b/config/qutebrowser/userscripts/bookmark
@@ -13,8 +13,7 @@ case "$1" in
echo "$QUTE_URL" >> "$BOOKMARKS_PATH"
;;
resource)
- ~/dev/projects/nvim-ts-peek/bin/nvim-peek dmenu "$QUTE_URL" "$QUTE_TITLE" \
- && notify-send "Saved $QUTE_URL";
+ ~/.config/kak/scripts/logger.sh link "$QUTE_URL";
;;
esac || true
diff --git a/config/zsh/aliases.zsh b/config/zsh/aliases.zsh
index 9eb564a..9c0d1f8 100644
--- a/config/zsh/aliases.zsh
+++ b/config/zsh/aliases.zsh
@@ -6,7 +6,7 @@ alias grep="grep --color=auto";
# Application shortcuts
alias emedit="emacsclient -c -n";
alias e="sensible-editor";
-alias v="nvim";
+alias k="kak-tmux";
alias o='open $(fzf)';
alias j='just';
@@ -38,3 +38,8 @@ alias szathura="swallow zathura";
# Dictionary
dict() { curl dict://dict.org/d:$1; }
+countdown() {
+ date;
+ sleep "$1" && notify-send -u critical "${2:-"Timer done"}"
+}
+
diff --git a/config/zsh/aliases/dev.zsh b/config/zsh/aliases/dev.zsh
index 65922a1..fa0bf5c 100644
--- a/config/zsh/aliases/dev.zsh
+++ b/config/zsh/aliases/dev.zsh
@@ -23,19 +23,6 @@ far() {
fd "$file_r" | sad "$matcher_r" "$result" -p diff-so-fancy "$@";
}
-# :: FileType Filename
-calc() {
- local syntax="${1:-javascript}"
- shift
- nvim -c \
- "let g:startify_disable_at_vimenter = 1 |\
- set bt=nofile ls=0 |\
- hi ColorColumn ctermbg=NONE |\
- hi VertSplit ctermbg=NONE |\
- hi NonText ctermfg=0 |\
- Codi $syntax" "$@"
-}
-
get_node_script_runner() {
# TODO: Check .engines.*
# jq -r .engines.pnpm package.json
@@ -64,21 +51,3 @@ bindkey '^B' p__run_npm_script;
fix-interpreter() {
nix-shell -p patchelf --run "patchelf --set-interpreter \$(patchelf --print-interpreter \$(which mkdir)) $@"
}
-
-
-# Terminal through neovim
-vt() {
- nvim +term \
- +'norm i' \
- +"lua vim.fn.feedkeys([[$1]])" \
- +'lua vim.go.termguicolors = false' \
- +'set nonumber norelativenumber signcolumn=no' \
- +'autocmd TermClose * execute "qa"' \
- +'hi @_phenax.term-title guibg=#1a1824 guifg=#8e7ae3 gui=bold' \
- +'set winbar=%#@_phenax.term-title#%=nvim-term%=';
-}
-
-p__nvim_virtual_terminal() { vt "$BUFFER"; }
-zle -N p__nvim_virtual_terminal;
-bindkey '^T' p__nvim_virtual_terminal;
-
diff --git a/config/zsh/aliases/edit.zsh b/config/zsh/aliases/edit.zsh
index fe14d92..2111430 100644
--- a/config/zsh/aliases/edit.zsh
+++ b/config/zsh/aliases/edit.zsh
@@ -4,7 +4,7 @@ alias eemacs='gemacs && emedit Emacs.org';
alias eorg='gnotes && sensible-editor index.md';
alias ezsh='gzsh && sensible-editor zshrc';
alias edot='sensible-editor ~/nixos/scripts/dotfiles.sh';
-alias evim='gvim && sensible-editor init.lua';
+alias evim='gvim && sensible-editor';
alias edwm='gdwm && sensible-editor config.def.h';
alias ebar='gbar && sensible-editor blocks.h';
@@ -13,4 +13,4 @@ alias equte='gqute && sensible-editor config.py';
alias eas='sensible-editor ~/nixos/packages/dwm/autostart.sh';
alias emime="sensible-editor ~/nixos/scripts/bin/open";
-alias fedit='sensible-editor `fzf`'
+alias fe='sensible-editor `fzf`'
diff --git a/config/zsh/aliases/git.zsh b/config/zsh/aliases/git.zsh
index c33781d..9611a16 100644
--- a/config/zsh/aliases/git.zsh
+++ b/config/zsh/aliases/git.zsh
@@ -54,14 +54,14 @@ alias grc='git rebase --continue'
# egc : Open files in last commit
# egc HEAD~1 : Open files in commit before the last one
egc() {
- nvim $(git show --name-only --pretty="" "$@");
+ sensible-editor $(git show --name-only --pretty="" "$@");
}
# Open files in diff
# egd : Open files changed (HEAD)
# egd origin/main : Open files diff between origin/main
egd() {
- nvim $(git diff --name-only ${1:-HEAD});
+ sensible-editor $(git diff --name-only ${1:-HEAD});
}
grename() {
@@ -98,3 +98,13 @@ gco() {
fi
}
+ghpr() {
+ if [ -f '.github/pull_request_template.md' ]; then
+ gh pr create -e -a "@me" -T 'pull_request_template.md' "$@" || true
+ else
+ gh pr create -e -a "@me" "$@" || true
+ fi
+
+ xdg-open "$(gh pr view --json url -q .url)"
+}
+
diff --git a/config/zsh/aliases/ls.zsh b/config/zsh/aliases/ls.zsh
index a3a484a..4e763fd 100644
--- a/config/zsh/aliases/ls.zsh
+++ b/config/zsh/aliases/ls.zsh
@@ -1,28 +1,18 @@
-# Trash
-alias trash="ls \$TRASH_TMP_DIR";
-
# List files aliases
-alias l="ls -1";
-alias la='ls -a';
-alias ll='ls -alF';
-alias lt='ls --tree';
+alias ll="ls -lh --time-style=+ --group-directories-first --color=always";
alias la='ls -A';
alias lsize='du -h -d1';
-lc () { # lf with cd to navigated directory on quit
+alias l='daffm';
+alias lt='daffm';
+
+# cd to navigated directory on quit
+lc () {
tmp="$(mktemp)"
- lf -last-dir-path="$tmp" "$@"
+ DAFFM_LAST_DIR_PATH="$tmp" daffm -c @lastcd
if [ -f "$tmp" ]; then
dir="$(cat "$tmp")"
rm -f "$tmp"
[ -d "$dir" ] && [ "$dir" != "$(pwd)" ] && cd "$dir"
fi
}
-
-lfshow() {
- local TMP_F="$(mktemp)";
- lf -selection-path "$TMP_F" "$@" >/dev/null 2>&1;
- local res="$(< "$TMP_F")";
- rm -f "$TMP_F";
- echo "$res"
-}
diff --git a/config/zsh/config.zsh b/config/zsh/config.zsh
index eb409fa..2b3b1e9 100644
--- a/config/zsh/config.zsh
+++ b/config/zsh/config.zsh
@@ -1,14 +1,14 @@
-export VISUAL='nvim'
-export EDITOR="nvim"
+export VISUAL='kak-tmux'
+export EDITOR="kak-tmux"
export TERMINAL="st"
export BROWSER="qutebrowser"
export PRIVATE_BROWSER="$BROWSER ':open -p'";
export READER="zathura"
-export FILE="lf"
+export FILE="daffm"
export FZF_DEFAULT_OPTS="--layout=reverse --height 40%"
export HISTCONTROL=ignoreboth
-export LS_COLORS='di=35:ln=36:or=31:mi=31:ex=32:*.ts=36';
+export LS_COLORS='di=96:ln=36:or=31:mi=31:ex=32:*.gitignore=90';
diff --git a/config/zsh/init.zsh b/config/zsh/init.zsh
index 5fca111..8b13789 100644
--- a/config/zsh/init.zsh
+++ b/config/zsh/init.zsh
@@ -1,11 +1 @@
-export TRASH_TMP_DIR=/tmp/.trash-cache;
-
-# [[ ! -d "$TRASH_TMP_DR" ]] && mkdir -p $TRASH_TMP_DIR;
-
-#export rmrf() {
- #for var in "$@"; do
- #mv $var $TRASH_TMP_DIR;
- #done
-#}
-
diff --git a/config/zsh/plugins/fzf-cd.zsh b/config/zsh/plugins/fzf-cd.zsh
index 02b85e7..9d47e17 100644
--- a/config/zsh/plugins/fzf-cd.zsh
+++ b/config/zsh/plugins/fzf-cd.zsh
@@ -1,6 +1,6 @@
fzf-change-dir-cwd() { # fzf + cd in cwd
- selected=$(find . -maxdepth 1 -type d | fzf);
+ selected=$(fd --type d --maxdepth 1 --hidden --no-ignore | fzf);
if [ ! -z "$selected" ] && [ "$selected" != "$(pwd)" ]; then
cd $selected;
fi
@@ -11,7 +11,7 @@ zle -N fzf-change-dir-cwd;
bindkey '^O' fzf-change-dir-cwd;
fzf-change-dir() {
- local result=$(find -type d | fzf);
+ local result=$(fd --type d --hidden --no-ignore | fzf);
if ! [[ -z "$result" ]]; then
cd "$result"
fi
diff --git a/config/zsh/plugins/timer.zsh b/config/zsh/plugins/timer.zsh
index 3610877..5505657 100644
--- a/config/zsh/plugins/timer.zsh
+++ b/config/zsh/plugins/timer.zsh
@@ -1,5 +1,6 @@
function preexec() {
timer=$(($(date +%s%0N)/1000000))
+ echo -n "\\x1b]133;A\\x1b\\" # OSC 133 for marking prompt
}
function precmd() {
diff --git a/config/zsh/theme.zsh b/config/zsh/theme.zsh
index e2f476b..2f591a3 100644
--- a/config/zsh/theme.zsh
+++ b/config/zsh/theme.zsh
@@ -25,6 +25,7 @@ p_dir() {
# Prompt terminal status
p_status() {
[[ ! -z "$WITH_NIX_PREFIX" ]] && echo -n "$(segment "[NIX:$WITH_NIX_PREFIX] " black $COL_ACCENT)";
+ [[ "$TERM" = "tmux-256color" ]] && echo -n "$(segment "[tmux]" black $COL_ACCENT)";
echo -n "%(?..$(segment 'x' black $COL_STATUS_ERROR))"
echo -n "%(1j.$(segment '(jobs: %j)' black $COL_STATUS_BG).)"
}
diff --git a/config/zsh/zshrc b/config/zsh/zshrc
index 32392ab..806697d 100644
--- a/config/zsh/zshrc
+++ b/config/zsh/zshrc
@@ -3,6 +3,7 @@ setopt auto_cd;
setopt inc_append_history;
export LESS="-R --chop-long-lines" # less no wrapping
+export MANPAGER="nvim +Man\!" # man pager with nvim
export SAVEHIST=10000
# export HISTSIZE=50000
diff --git a/configuration.nix b/configuration.nix
index aaa6055..20299ec 100644
--- a/configuration.nix
+++ b/configuration.nix
@@ -14,6 +14,8 @@
./modules/lockscreen.nix
./modules/sound
./modules/notifications
+ ./modules/kakoune
+ ./modules/ai
];
nixpkgs.config = {
@@ -47,14 +49,14 @@
hostName = "smartfridge";
firewall = {
enable = true;
- allowedTCPPorts = [ 3000 3001 8081 ];
+ allowedTCPPorts = [ 3000 3001 ];
allowedUDPPorts = [ 41641 ];
};
nameservers = [ "100.100.100.100" "1.1.1.1" "8.8.8.8" ];
search = [ "resolve.construction" ];
networkmanager.enable = true;
hosts = {
- "127.0.0.1" = ["phenax.local" "field.shape-e2e.com"];
+ "127.0.0.1" = ["field.shape-e2e.com"];
};
};
@@ -65,14 +67,14 @@
docker = {
enable = true;
};
- lxd.enable = false;
+ # lxd.enable = false;
virtualbox.host.enable = false;
libvirtd = {
enable = true;
qemu = {
swtpm.enable = true;
- ovmf.enable = true;
- ovmf.packages = [ pkgs.OVMFFull.fd ];
+ # ovmf.enable = true;
+ # ovmf.packages = [ pkgs.OVMFFull.fd ];
};
};
spiceUSBRedirection.enable = true;
@@ -114,23 +116,21 @@
};
fonts.packages = with pkgs; [
nerd-fonts.jetbrains-mono
- nerd-fonts.fira-code
- nerd-fonts.fira-mono
cozette
- noto-fonts-emoji
+ noto-fonts-color-emoji
inter
roboto
- vistafonts
+ vista-fonts
];
- services.logind = {
- powerKey = "ignore";
- rebootKey = "ignore";
- lidSwitch = "ignore";
- lidSwitchDocked = "ignore";
- lidSwitchExternalPower = "ignore";
- hibernateKey = "ignore";
- suspendKey = "ignore";
+ services.logind.settings.Login = {
+ HandlePowerKey = "ignore";
+ HandleRebootKey = "ignore";
+ HandleLidSwitch = "ignore";
+ HandleLidSwitchDocked = "ignore";
+ HandleLidSwitchExternalPower = "ignore";
+ HandleHibernateKey = "ignore";
+ HandleSuspendKey = "ignore";
};
# Home manager
diff --git a/modules/ai/default.nix b/modules/ai/default.nix
new file mode 100644
index 0000000..034e33b
--- /dev/null
+++ b/modules/ai/default.nix
@@ -0,0 +1,51 @@
+{ lib, pkgs, ... }:
+let
+ llama-cpp-pkg = pkgs.llama-cpp-vulkan;
+ port = 9081;
+ ctx-size = 128; # 32
+ hf-file = "gemma-3-4b-it-Q4_K_M.gguf";
+ hf-repo =
+ "unsloth/gemma-3-4b-it-GGUF";
+ # "itlwas/Phi-4-mini-instruct-Q4_K_M-GGUF";
+ # "unsloth/gemma-3-4b-it-GGUF";
+ # "yasserrmd/DeepSeek-7B-1M-gguf";
+ # "unsloth/Seed-Coder-8B-Instruct-GGUF";
+ api-key = "foobar";
+
+ llama-start-server = pkgs.writeShellScriptBin "llama-start-server" ''
+ exec ${llama-cpp-pkg}/bin/llama-server --log-disable \
+ --port ${toString port} \
+ --hf-repo ${hf-repo} \
+ ${if hf-file != "" then "--hf-file ${hf-file}" else ""} \
+ --ctx-size ${toString (ctx-size * 1024)} \
+ --api-key ${api-key} \
+ --threads 12 --no-perf
+ '';
+ llama-start-server-background = pkgs.writeShellScriptBin "llama-start-server-background" ''
+ is_running() { ${pkgs.lsof}/bin/lsof -i ":${toString port}" >/dev/null 2>&1; }
+
+ if ! is_running; then
+ setsid -f ${llama-start-server}/bin/llama-start-server >"$HOME/.local/state/local-ai-logs" 2>&1
+
+ attempts=20;
+ while ! ([ "$attempts" == "0" ] || is_running); do
+ sleep 5;
+ attempts=$((attempts - 1));
+ done
+ fi
+ '';
+in
+{
+ environment.systemPackages = with pkgs; [
+ llama-cpp-pkg
+ llama-start-server
+ llama-start-server-background
+ aichat
+ piper-tts
+ ];
+
+ environment.variables = {
+ AI_API_URL = "http://localhost:${toString port}";
+ AI_API_KEY = api-key;
+ };
+}
diff --git a/modules/email.home/.gitignore b/modules/email.home/.gitignore
index a211cae..41d633b 100644
--- a/modules/email.home/.gitignore
+++ b/modules/email.home/.gitignore
@@ -1 +1,2 @@
private.nix
+*.private.*
diff --git a/modules/email.home/aerc.conf b/modules/email.home/aerc.conf
index e7dc011..656d4a1 100644
--- a/modules/email.home/aerc.conf
+++ b/modules/email.home/aerc.conf
@@ -9,8 +9,8 @@ auto-mark-read = true
parse-http-links = true
[compose]
-editor = nvim
-file-picker-cmd = lf -selection-path=%f
+editor = kak-tmux
+file-picker-cmd = sh -c "DAFFM_SELECTIONS_OUT=%f daffm -c @picker"
empty-subject-warning = true
no-attachment-warning = ^[^>]*attach(ed|ment)
edit-headers = true
diff --git a/modules/kakoune/default.nix b/modules/kakoune/default.nix
new file mode 100644
index 0000000..bacab15
--- /dev/null
+++ b/modules/kakoune/default.nix
@@ -0,0 +1,25 @@
+{ pkgs, lib, ... }:
+with pkgs;
+let
+ kak-tree-sitter-unstable = import ./kak-tree-sitter.nix { inherit pkgs lib; };
+ kak-tmux = pkgs.writeShellScriptBin "kak-tmux" ''
+ if [ -t 0 ] && [ -z "$TMUX" ]; then
+ exec </dev/tty; exec <&1; ${tmux}/bin/tmux new "${kakoune}/bin/kak$(printf ' %q' "$@")"
+ else
+ exec "${kakoune}/bin/kak" "$@"
+ fi
+ '';
+in {
+ environment.systemPackages = [
+ kakoune
+ kakoune-lsp
+ kakoune-cr
+ kak-tree-sitter-unstable
+ kak-tmux
+
+ ripgrep
+ tmux
+ gitu
+ moreutils
+ ];
+}
diff --git a/modules/kakoune/kak-tree-sitter.nix b/modules/kakoune/kak-tree-sitter.nix
new file mode 100644
index 0000000..8860d64
--- /dev/null
+++ b/modules/kakoune/kak-tree-sitter.nix
@@ -0,0 +1,19 @@
+{ lib, pkgs }:
+with pkgs;
+rustPlatform.buildRustPackage rec {
+ pname = "kak-tree-sitter";
+ version = "3.0.0-local";
+
+ src = fetchFromSourcehut {
+ owner = "~hadronized";
+ repo = "kak-tree-sitter";
+ rev = "cdcfb42da9affd9dd0db9e8df1173731c61e3d9f"; # 27 Oct 2025
+ hash = "sha256-Q8R++fEJMZFftiI9zGjwF7X8mek2oc40Yl9WMUtQWEA=";
+ };
+
+ cargoHash = "sha256-lZNM5HqICP6JfaMiBjACcUNRTTTIRhq2ou8cOLU0yOU=";
+
+ meta = {
+ mainProgram = "kak-tree-sitter";
+ };
+}
diff --git a/modules/xresources.home.nix b/modules/xresources.home.nix
index 4f83d45..9c99896 100644
--- a/modules/xresources.home.nix
+++ b/modules/xresources.home.nix
@@ -10,7 +10,7 @@
"*.cursorColor" = theme.foreground;
"*.accent" = theme.accent;
- "*.color0" = "#171717";
+ "*.color0" = "#222222";
"*.color8" = "#555555";
"*.color1" = "#e06c75";
diff --git a/overlays/neovim.nix b/overlays/neovim.nix
index 5e55257..3e8e6c5 100644
--- a/overlays/neovim.nix
+++ b/overlays/neovim.nix
@@ -1,5 +1,5 @@
let
- rev = "95727f7d4ebe43435c826ab618933198ab30effe"; # "master" (6th Aug 2025)
+ rev = "928308a20559523bb3898861a6f28e9589ab3a0e"; # (19 Sept 2025)
in
import (builtins.fetchTarball {
url = "https://github.com/nix-community/neovim-nightly-overlay/archive/${rev}.tar.gz";
diff --git a/packages.nix b/packages.nix
index 461d8cf..b6d993a 100644
--- a/packages.nix
+++ b/packages.nix
@@ -21,15 +21,19 @@ let
ripgrep
ast-grep
ctags
- fzf
docker-compose
direnv
w3m
ed
rlwrap
+ moreutils
+ gitu
# gh
just
difftastic
+ gemini-cli
+ yq-go
+ babashka
# hurl
# delta
# gibo
@@ -38,6 +42,7 @@ let
gnumake
nodejs_24
bun
+ marksman
# bspwm
# sxhkd
@@ -49,8 +54,8 @@ let
src = pkgs.fetchFromSourcehut {
owner = "~xerool";
repo = "fennel-ls";
- rev = "3c1e01da6f1423719229c830319a61dba7c2bb99";
- hash = "sha256-Jop1R/rm+K2sBufVs+JWB4INboLeU7xdviWgb2lXamA=";
+ rev = "cd9821cd80e7e4db8bbed388cbaf17473cd54ba3";
+ hash = "sha256-3qX77hZjO/rNOO58cG9yGFVFQDYaeJdDEhbjNTIIQys=";
};
}))
fnlfmt
@@ -67,21 +72,17 @@ let
luajit
luajitPackages.luarocks
luajitPackages.lua-curl
- luajitPackages.magick # lua51Packages.magick
+ luajitPackages.magick
+ luajitPackages.fennel
];
apps = with pkgs; [
# Browser
qutebrowser
brave
- # firefox
- # ungoogled-chromium
-
- # Comm
- # slack
+ ungoogled-chromium
# Media
- # spotify
sxiv
yt-dlp
imagemagick
@@ -89,12 +90,11 @@ let
feh
zathura
inkscape
- jellyfin-mpv-shim
# obs-studio
# krita
blender
- minetest
+ luanti
xonotic
openarena
# chiaki # PS remote play
@@ -110,11 +110,12 @@ let
dua
# newsboat
- (builtins.getFlake "github:phenax/chelleport/bf57e4968d059b207c036b57818a58ed8c54d141").packages.x86_64-linux.default
+ # (builtins.getFlake "github:phenax/daffm/b61d4cdc759e08eb7990aa7f3a67eb737cd7b930").packages.x86_64-linux.default
+ (pkgs.writeShellScriptBin "daffm" ''exec /home/imsohexy/dev/projects/daffm/result/bin/daffm "$@"'')
+
+ # (builtins.getFlake "github:phenax/chelleport/bf57e4968d059b207c036b57818a58ed8c54d141").packages.x86_64-linux.default
# (builtins.getFlake "github:phenax/draw-stuff-on-your-screen/6e0e1f6ee603045cac5bb5d9d75d80c9ddef6c6e").packages.x86_64-linux.default
- (pkgs.writeShellScriptBin
- "null-browser"
- ''exec /home/imsohexy/dev/projects/null-browser/result/bin/null-browser "$@"'')
+ (pkgs.writeShellScriptBin "null-browser" ''exec /home/imsohexy/dev/projects/null-browser/result/bin/null-browser "$@"'')
];
utils = with pkgs; [
@@ -136,9 +137,11 @@ let
kitty
figlet
fd
+ fzf
# sad
mediainfo
- poppler_utils
+ poppler-utils
+ epub2txt2
glow
pkgs.steam-run
flatpak
@@ -172,12 +175,13 @@ let
libdrm
pkg-config
+ lsof
virt-manager
virt-viewer
- spice
+ spice
spice-gtk
spice-protocol
- win-virtio
+ virtio-win
win-spice
adwaita-icon-theme
];
@@ -189,6 +193,7 @@ in
nixpkgs.config.permittedInsecurePackages = [
"ffmpeg-3.4.8"
"qtwebkit-5.212.0-alpha4"
+ "qtwebengine-5.15.19"
];
# environment.variables = {
diff --git a/packages/sensible-apps/sensible-apps.nix b/packages/sensible-apps/sensible-apps.nix
index 0518ce8..7c631b3 100644
--- a/packages/sensible-apps/sensible-apps.nix
+++ b/packages/sensible-apps/sensible-apps.nix
@@ -1,6 +1,6 @@
let
apps = {
- EDITOR = "nvim";
+ EDITOR = "kak-tmux";
TERMINAL = "st";
BROWSER = "qutebrowser";
PRIVATE_BROWSER = "qutebrowser ':open -p'";
diff --git a/scripts/bin/ai b/scripts/bin/ai
new file mode 100755
index 0000000..eb264ea
--- /dev/null
+++ b/scripts/bin/ai
@@ -0,0 +1,48 @@
+#!/usr/bin/env sh
+
+set -e -o pipefail
+
+AI_API_URL=${AI_API_URL:-"http://localhost:9081"}
+AI_API_KEY=${AI_API_KEY:-"no-key"}
+
+system_prompt="
+When responding with code, you are a senior software engineer, output only the raw code, without any enclosing markdown code blocks. Output only the final code. Do not include backticks, comments, or explanations.
+Do not include \`\`\` or any surrounding formatting. If you add anything other than code, you have failed.
+When responding with content, be concise.
+Do not hallucinate facts and respond with accurate information as much as possible.
+If you don't know, just say so. If you are not sure, ask for clarification.
+If the context appears unreadable or of poor quality, tell the user then answer as best as you can.
+"
+
+call_completion() {
+ local opts='"stream": true'
+ local payload="{\"messages\": $1, $opts }"
+ curl --silent --no-buffer \
+ -XPOST "$AI_API_URL/v1/chat/completions" \
+ -H "Content-Type: application/json" \
+ -H "Authorization: Bearer $AI_API_KEY" \
+ --data "$payload" \
+ | tee "$HOME/.local/state/local-ai-last-response" \
+ | stdbuf -oL sed -E 's/^data:\s*//; /^$/d' \
+ | while IFS= read -r line; do
+ printf "%s" "$line" | jq -rj '.choices[0].delta.content // ""' 2>/dev/null || true
+ done;
+}
+
+arg_prompt="$1"
+stdin=""
+if ! [ -t 0 ];
+ then stdin="$(cat)";
+fi
+
+# Start llama server if not started already
+# from: modules/ai/default.nix
+llama-start-server-background
+
+# Call completion api
+call_completion "$(jq -n \
+ --arg system "$system_prompt" \
+ --arg user "$arg_prompt" \
+ --arg user_supplement "$stdin" \
+ '[{ role: "system", content: $system }, { role: "user", content: $user }, { role: "user", content: $user_supplement }]')"
+
diff --git a/scripts/bin/cbedit b/scripts/bin/cbedit
index f4d88fd..b163ecb 100755
--- a/scripts/bin/cbedit
+++ b/scripts/bin/cbedit
@@ -4,7 +4,7 @@ set -e;
read_clipboard() { xclip -selection clipboard -o || echo -n ""; }
update_clipboard() { xclip -selection clipboard -i; }
-edit_file() { st -e nvim "$@"; }
+edit_file() { st -e sensible-editor "$@"; }
tmp_file=$(mktemp /tmp/cbedit-XXXXX);
read_clipboard > $tmp_file;
diff --git a/scripts/bin/file-manager b/scripts/bin/file-manager
index 467d346..016818e 100755
--- a/scripts/bin/file-manager
+++ b/scripts/bin/file-manager
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
-sensible-terminal -d "$1" -e lf
+sensible-terminal -d "$1" -e daffm
diff --git a/scripts/bin/kman b/scripts/bin/kman
new file mode 100755
index 0000000..052d410
--- /dev/null
+++ b/scripts/bin/kman
@@ -0,0 +1,3 @@
+#!/usr/bin/env sh
+
+kak -e "man $@; map global normal q :quit<ret>;"
diff --git a/scripts/bin/open b/scripts/bin/open
index 9daa34a..001d784 100755
--- a/scripts/bin/open
+++ b/scripts/bin/open
@@ -13,7 +13,7 @@ open_by_mimetype() {
echo "Opening $file ($mime)...";
case "$mime" in
- inode/directory) lf "$file" ;;
+ inode/directory) daffm "$file" ;;
application/x-bittorrent) ~/scripts/torrent.sh torrent "$file" ;;
diff --git a/scripts/bin/tts b/scripts/bin/tts
new file mode 100755
index 0000000..ecb4ee2
--- /dev/null
+++ b/scripts/bin/tts
@@ -0,0 +1,23 @@
+#!/usr/bin/env sh
+
+set -e -o pipefail
+
+TTS_MODELS_PATH="$HOME/.config/piper-models"
+
+playaudio() {
+ ffplay -nodisp -autoexit -f s16le -ar 22050 -
+}
+
+text2speech() {
+ # https://huggingface.co/rhasspy/piper-voices/tree/main/en/en_US
+ local tts_model="en_US-lessac-medium.onnx";
+ # local tts_model="en_US-ryan-high.onnx";
+ # local tts_model="en_US-bryce-medium.onnx";
+ local tts_model_path="$TTS_MODELS_PATH/$tts_model";
+ [ -f "$tts_model_path" ] || (echo "Model not found" && exit 1);
+
+ piper --model "$tts_model_path" --sentence_silence 0.4 --output-raw | playaudio
+}
+
+text2speech;
+
diff --git a/scripts/orgagenda.sh b/scripts/orgagenda.sh
new file mode 100755
index 0000000..9f46778
--- /dev/null
+++ b/scripts/orgagenda.sh
@@ -0,0 +1,98 @@
+#!/usr/bin/env sh
+
+set -eu -o pipefail
+
+CONFIG_ORG_DIRECTORY=${CONFIG_ORG_DIRECTORY:-"$HOME/nixos/extras/notes"}
+
+datefmt='%Y-%m-%d'
+datetimefmt='%Y-%m-%d %H:%M:%S'
+
+weekdaynum() { echo "$(($(date -d "$1" +%u) % 7))"; }
+
+today=$(date "+$datefmt")
+weekincrement="${1:-0}"
+target=$(date -d "$weekincrement weeks" "+$datefmt")
+weekstart=$(date -d "$target -$(weekdaynum "$target") days" "+$datefmt")
+nextweekstart=$(date -d "$target -$(weekdaynum "$target") days +1 week" "+$datefmt")
+
+fetch_schedule() {
+ # TODO: Exclude DONE tasks
+ rg -i -g '**/*.org' --vimgrep --multiline \
+ '^\*+\s+(?<heading>.+)\n(^[^*]*\n)*^((?<type>SCHEDULED|DEADLINE)\s*:)?\s*<(?<date>[^>]*)>(--<(?<enddate>[^>]*)>)?' \
+ --replace '§$heading§$type§$date§$enddate' \
+ "$CONFIG_ORG_DIRECTORY" \
+ | sed -E 's/:[0-9]+:[0-9]+://'
+}
+
+# :: Date -> Date
+parse_start_date() {
+ echo "$1" | sed -E 's/^([0-9]+-[0-9]+-[0-9]+)\s*.*/\1/'
+}
+
+# :: ScheduleType -> Date -> End Date -> [Date]
+parse_date_range() {
+ [ -z "$2" ] && return 0
+ parsed_date=$(parse_start_date "$2")
+ if [ "$1" = "DEADLINE" ]; then
+ for i in $(seq 1 2); do
+ local d=$(date -d "$parsed_date -$i days" "+$datefmt" || true)
+ if [ "$d" \> "$today" ] || [ "$d" = "$today" ]; then echo "$d"; fi
+ done
+ date -d "$parsed_date" "+$datefmt" || true
+ else
+ # TODO: Parse end date
+ # TODO: Parse repeat syntax +x as well
+ date -d "$parsed_date" "+$datefmt" || true
+ fi
+}
+
+date_between() {
+ ([ "$1" \> "$2" ] || [ "$1" = "$2" ]) && [ "$1" \< "$3" ]
+}
+
+weeks_events() {
+ fetch_schedule | while IFS=§ read file heading scheduletype original_date end_date; do
+ parse_date_range "$scheduletype" "$original_date" "$end_date" | while IFS= read applied_date; do
+ day_of_week=$(date -d "$applied_date" +%A 2>/dev/null || true)
+ if ! [ -z "$applied_date" ] && (date_between "$applied_date" "$weekstart" "$nextweekstart"); then
+ parsed_date="$(parse_start_date "$original_date")"
+ echo -e "$day_of_week§$heading§$scheduletype§$original_date§$parsed_date§$applied_date"
+ fi
+ done
+ done
+}
+
+date_from_day() {
+ date -d "$weekstart +$(weekdaynum "$1") days" +"$datefmt";
+}
+
+relative_date_diff() {
+ start_sec=$(date -d "$1" +%s)
+ end_sec=$(date -d "$2" +%s)
+ diff=$((end_sec - start_sec))
+ days=$((diff / 86400))
+ if [ $diff = 0 ]; then echo "today"
+ elif [ $diff -gt 0 ]; then echo "in $days days"
+ else echo "$((days * -1)) days ago"
+ fi
+}
+
+events=$(weeks_events)
+cols=$(tput cols)
+
+days_of_week="Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
+
+for day_of_week in ${days_of_week}; do
+ echo -e "\033[38;5;73m${day_of_week} \033[1m($(date_from_day "$day_of_week"))\033[0m"
+ (echo "$events" | grep "^$day_of_week" || true) | \
+ while IFS=§ read _ heading scheduletype original_date real_date date; do
+ eventstyle=""
+ if [ "$scheduletype" = "DEADLINE" ]; then
+ eventstyle=$([ "$date" = "$real_date" ] \
+ && echo "\033[38;5;160m" \
+ || echo "\033[38;5;172m")
+ fi
+ printf "\033[38;5;243m%${cols}s\033[0m" "($original_date) "
+ echo -e "\r ${eventstyle}\033[1m${heading}\033[0m ($(relative_date_diff "$today" "$real_date"))"
+ done
+done