initial commit
This commit is contained in:
commit
beb5071a7a
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
|
22
LICENSE
Normal file
22
LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 George Kusayko [L-Nafaryus] <l.nafaryus@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
8
bin/autoclicker
Executable file
8
bin/autoclicker
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
while true; do
|
||||
xdotool mousedown 1
|
||||
sleep 0.01
|
||||
xdotool mouseup 1
|
||||
sleep 0.01
|
||||
done
|
9
bin/gitinfo
Executable file
9
bin/gitinfo
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env cached-nix-shell
|
||||
#! nix-shell -p nix-prefetch-git -i bash
|
||||
|
||||
for repo in $@; do
|
||||
if [[ "$repo" != https://* ]]; then
|
||||
repo="https://github.com/$repo"
|
||||
fi
|
||||
nix-prefetch-git --quiet "$repo"
|
||||
done
|
72
bin/mov2gif
Executable file
72
bin/mov2gif
Executable file
@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env cached-nix-shell
|
||||
#! nix-shell -i bash -p ffmpeg gifsicle
|
||||
|
||||
# Uses ffmpeg to convert a video file to a gif file. Optimizes the final result
|
||||
# with gifsicle.
|
||||
#
|
||||
# Requires: ffmpeg gifsicle
|
||||
#
|
||||
# Example:
|
||||
# mov2gif some-vid.mp4 output.gif
|
||||
# mov2gif -f 10 -s 00:00:10 -t 00:00:05 some-vid.mp4 output.gif
|
||||
|
||||
set -e
|
||||
PALETTE="/tmp/palette.png"
|
||||
|
||||
usage() {
|
||||
cat <<EOL
|
||||
Usage: ${0##*/} [-fsSth] SOURCE_FILE [destfile]
|
||||
|
||||
-f [FPS] set frames per second
|
||||
-s [hh:mm:ss] set starting time (like -ss in ffmpeg)
|
||||
-S [W:H] set width/height (either can be -1 for auto)
|
||||
-t [hh:mm:ss] set the duration to capture (like -t in ffmpeg)
|
||||
-h this help
|
||||
EOL
|
||||
}
|
||||
|
||||
cleanup() { rm -f "$PALETTE"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
#
|
||||
fps=30
|
||||
while getopts hf:s:t:S: opt; do
|
||||
case $opt in
|
||||
f) fps="$OPTARG" ;;
|
||||
s) start="-ss $OPTARG" ;;
|
||||
S) scale=",scale=$OPTARG:flags=lanczos" ;;
|
||||
t) duration="-t $OPTARG" ;;
|
||||
h) usage
|
||||
exit
|
||||
;;
|
||||
:) >&2 echo "$OPTARG requires an argument"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
*) >&2 echo "Not a valid arg: $opt"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
#
|
||||
if (($# == 0)); then
|
||||
>&2 echo "No movie file specified"
|
||||
exit
|
||||
elif [[ ! -f $1 ]]; then
|
||||
>&2 echo "$1 does not exist"
|
||||
exit
|
||||
fi
|
||||
|
||||
src="$1"
|
||||
dest="${2:-${src%.*}.gif}"
|
||||
flags="fps=${fps}$scale"
|
||||
|
||||
# stats_mode=full favors motion, causing the resulting palette to better
|
||||
# accomodate fades and transitions.
|
||||
ffmpeg -v warning $start $duration -i "file:$src" -vf "$flags,palettegen=stats_mode=full" -y "$PALETTE"
|
||||
ffmpeg -v warning $start $duration -i "file:$src" -i "$PALETTE" -lavfi "$flags [x]; [x][1:v] paletteuse" -y "$dest"
|
||||
|
||||
gifsicle -O3 "$dest" -o "$dest"
|
21
bin/myip
Executable file
21
bin/myip
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env zsh
|
||||
# Echos your local or WAN IP
|
||||
|
||||
if [[ $1 == -w ]]; then
|
||||
wan=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ -n $wan ]]; then
|
||||
dig +short myip.opendns.com @resolver1.opendns.com
|
||||
else
|
||||
IF=$(netstat -rn | awk '/^0.0.0.0/ {thif=substr($0,74,10); print thif;} /^default.*UG/ {thif=substr($0,65,10); print thif;}')
|
||||
if command -v ifconfig >/dev/null; then
|
||||
ifconfig ${NET_IF} | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'
|
||||
elif command -v ip >/dev/null; then
|
||||
ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'
|
||||
else
|
||||
>&2 echo "No easy way to grab your IP"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
86
bin/optimimg
Executable file
86
bin/optimimg
Executable file
@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
# Optimize image files (losslessly by default)
|
||||
#
|
||||
# Examples:
|
||||
# imgoptim image.jpg image.png image.gif
|
||||
# imgoptim directory_of_images/
|
||||
# imgoptim directory_of_images/*.png
|
||||
#
|
||||
# Requires:
|
||||
# PNGs: optipng, pngquant (lossy)
|
||||
# JPGs: jpegtran, jpegoptim (lossy)
|
||||
# GIFs: gifsicle
|
||||
#
|
||||
# Packages (same name on homebrew & arch linux)
|
||||
# optipng [pngquant] libjpeg-turbo [jpegoptim] gifsicle
|
||||
|
||||
set -e
|
||||
unset CDPATH
|
||||
|
||||
_usage() {
|
||||
cat <<EOL
|
||||
Usage: ${0:A:t} [-lh] IMAGE [IMAGE2 [IMAGE3 [...]]]
|
||||
|
||||
-l enable lossy compression
|
||||
-h this help
|
||||
EOL
|
||||
}
|
||||
|
||||
_filesize() {
|
||||
case $OSTYPE in
|
||||
darwin*) stat -c%s "$1" ;;
|
||||
*) stat --printf="%s" "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
#
|
||||
while getopts hl opt; do
|
||||
case $opt in
|
||||
h) _usage; exit;;
|
||||
l) lossy=1;;
|
||||
:) >&2 echo "$OPTARG requires an argument"; _usage; exit 1;;
|
||||
*) >&2 echo "Not a valid arg: $opt"; _usage; exit 1;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
cmds=( optipng jpegtran gifsicle )
|
||||
[[ -n $lossy ]] && cmds=( $cmds pngquant jpegoptim )
|
||||
for cmd in ${cmds[@]}; do
|
||||
if ! command -v $cmd >/dev/null; then
|
||||
>&2 echo "$cmd isn't installed"
|
||||
error=1
|
||||
fi
|
||||
done
|
||||
if [[ -n $error ]]; then
|
||||
>&2 echo "There were errors, aborting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for file in $@; do
|
||||
if [[ -d $file ]]; then
|
||||
imgoptim $file/*
|
||||
elif [[ -f $file ]]; then
|
||||
pre_size=$(_filesize "$file")
|
||||
case ${file##*.} in
|
||||
png)
|
||||
[[ -n $lossy ]] && pngquant $file
|
||||
optipng -nc -nb -o7 $file
|
||||
;;
|
||||
gif)
|
||||
gifsicle --batch --optimize=3 "$file"
|
||||
;;
|
||||
jpg|jpeg)
|
||||
[[ -n $lossy ]] && jpegoptim --max=90 "$file"
|
||||
jpegtran -copy none -optimize -progressive -outfile "$file" "$file"
|
||||
;;
|
||||
*)
|
||||
printf "Unrecognized file '$file': ignored"
|
||||
;;
|
||||
esac
|
||||
post_size=$(_filesize "$file")
|
||||
perc=$(echo "((${pre_size} - ${post_size}) / ${pre_size}) * 100" | bc -l)
|
||||
printf "* %s: %d => %d (%.2f%% reduction)\n" "$file" "${pre_size}" "${post_size}" "$perc"
|
||||
fi
|
||||
done
|
36
bin/optimpdf
Executable file
36
bin/optimpdf
Executable file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Compress pdf files using ghostscript.
|
||||
#
|
||||
# Defaults to 72 dpi.
|
||||
#
|
||||
# Usage:
|
||||
# pdfoptim SRC [TARGET] [DPI]
|
||||
#
|
||||
# Requires: ghostscript (gs)
|
||||
|
||||
optimize() {
|
||||
# Adapted from Alfred Klomp's shrinkpdf script
|
||||
# <http://alfredklomp.com/programming/shrinkpdf/>
|
||||
gs -q -dNOPAUSE -dBATCH -dSAFER \
|
||||
-sDEVICE=pdfwrite \
|
||||
-dPDFSETTINGS=/screen \
|
||||
-dCompatibilityLevel=1.3 \
|
||||
-dEmbedAllFonts=true \
|
||||
-dSubsetFonts=true \
|
||||
-dAutoRotatePages=/None \
|
||||
-dMonoImageResolution=$3 \
|
||||
-dMonoImageDownsampleType=/Bicubic \
|
||||
-dGrayImageResolution=$3 \
|
||||
-dGrayImageDownsampleType=/Bicubic \
|
||||
-dColorImageResolution=$3 \
|
||||
-dColorImageDownsampleType=/Bicubic \
|
||||
-sOutputFile="$2" \
|
||||
"$1"
|
||||
}
|
||||
|
||||
src="$1"
|
||||
dest="${2:--}"
|
||||
dpi="${3:-72}"
|
||||
|
||||
optimize "$src" "$dest" "$dpi" || exit $?
|
22
bin/zzz
Executable file
22
bin/zzz
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# If -f, then put computer to sleep.
|
||||
# Otherwise, lock screen and turn off monitor.
|
||||
|
||||
if [[ $1 == -h ]]; then
|
||||
bin=${0##*/}
|
||||
echo "Usage: $bin [-f]"
|
||||
echo
|
||||
echo " $bin # put display to sleep"
|
||||
echo " $bin -f # put computer to sleep"
|
||||
elif [[ $1 == -f ]]; then
|
||||
echo "Going to sleep..."
|
||||
systemctl suspend
|
||||
else
|
||||
echo "Shutting my eyes..."
|
||||
if command -v slock >/dev/null; then
|
||||
pgrep slock >/dev/null || slock &
|
||||
fi
|
||||
sleep 1
|
||||
xset dpms force off
|
||||
fi
|
6
config/emacs/aliases.zsh
Normal file
6
config/emacs/aliases.zsh
Normal file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
e() { pgrep emacs && emacsclient -n "$@" || emacs -nw "$@" }
|
||||
ediff() { emacs -nw --eval "(ediff-files \"$1\" \"$2\")"; }
|
||||
eman() { emacs -nw --eval "(switch-to-buffer (man \"$1\"))"; }
|
||||
ekill() { emacsclient --eval '(kill-emacs)'; }
|
140
config/emacs/doom-config/config.el
Normal file
140
config/emacs/doom-config/config.el
Normal file
@ -0,0 +1,140 @@
|
||||
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Place your private configuration here! Remember, you do not need to run 'doom
|
||||
;; sync' after modifying this file!
|
||||
|
||||
|
||||
;; Some functionality uses this to identify you, e.g. GPG configuration, email
|
||||
;; clients, file templates and snippets. It is optional.
|
||||
(setq user-full-name "L-Nafaryus"
|
||||
user-mail-address "l.nafaryus@gmail.com")
|
||||
|
||||
;; Doom exposes five (optional) variables for controlling fonts in Doom:
|
||||
;;
|
||||
;; - `doom-font' -- the primary font to use
|
||||
;; - `doom-variable-pitch-font' -- a non-monospace font (where applicable)
|
||||
;; - `doom-big-font' -- used for `doom-big-font-mode'; use this for
|
||||
;; presentations or streaming.
|
||||
;; - `doom-unicode-font' -- for unicode glyphs
|
||||
;; - `doom-serif-font' -- for the `fixed-pitch-serif' face
|
||||
;;
|
||||
;; See 'C-h v doom-font' for documentation and more examples of what they
|
||||
;; accept. For example:
|
||||
;;
|
||||
;;(setq doom-font (font-spec :family "Fira Code" :size 12 :weight 'semi-light)
|
||||
;; doom-variable-pitch-font (font-spec :family "Fira Sans" :size 13))
|
||||
;;
|
||||
;; If you or Emacs can't find your font, use 'M-x describe-font' to look them
|
||||
;; up, `M-x eval-region' to execute elisp code, and 'M-x doom/reload-font' to
|
||||
;; refresh your font settings. If Emacs still can't find your font, it likely
|
||||
;; wasn't installed correctly. Font issues are rarely Doom issues!
|
||||
|
||||
;; There are two ways to load a theme. Both assume the theme is installed and
|
||||
;; available. You can either set `doom-theme' or manually load a theme with the
|
||||
;; `load-theme' function. This is the default:
|
||||
(setq doom-theme 'doom-one)
|
||||
|
||||
;; This determines the style of line numbers in effect. If set to `nil', line
|
||||
;; numbers are disabled. For relative line numbers, set this to `relative'.
|
||||
(setq display-line-numbers-type t)
|
||||
|
||||
;; If you use `org' and don't want your org files in the default location below,
|
||||
;; change `org-directory'. It must be set before org loads!
|
||||
(setq org-directory "~/org/")
|
||||
|
||||
|
||||
;; Whenever you reconfigure a package, make sure to wrap your config in an
|
||||
;; `after!' block, otherwise Doom's defaults may override your settings. E.g.
|
||||
;;
|
||||
;; (after! PACKAGE
|
||||
;; (setq x y))
|
||||
;;
|
||||
;; The exceptions to this rule:
|
||||
;;
|
||||
;; - Setting file/directory variables (like `org-directory')
|
||||
;; - Setting variables which explicitly tell you to set them before their
|
||||
;; package is loaded (see 'C-h v VARIABLE' to look up their documentation).
|
||||
;; - Setting doom variables (which start with 'doom-' or '+').
|
||||
;;
|
||||
;; Here are some additional functions/macros that will help you configure Doom.
|
||||
;;
|
||||
;; - `load!' for loading external *.el files relative to this one
|
||||
;; - `use-package!' for configuring packages
|
||||
;; - `after!' for running code after a package has loaded
|
||||
;; - `add-load-path!' for adding directories to the `load-path', relative to
|
||||
;; this file. Emacs searches the `load-path' when you load packages with
|
||||
;; `require' or `use-package'.
|
||||
;; - `map!' for binding new keys
|
||||
;;
|
||||
;; To get information about any of these functions/macros, move the cursor over
|
||||
;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
|
||||
;; This will open documentation for it, including demos of how they are used.
|
||||
;; Alternatively, use `C-h o' to look up a symbol (functions, variables, faces,
|
||||
;; etc).
|
||||
;;
|
||||
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
|
||||
;; they are implemented.
|
||||
|
||||
(setq confirm-kill-emacs nil)
|
||||
|
||||
(after! mu4e
|
||||
(setq +mu4e-gmail-accounts '(("l.nafaryus@gmail.com" . "/gmail-main")))
|
||||
|
||||
(auth-source-pass-enable)
|
||||
(setq auth-source-debug t)
|
||||
(setq auth-source-do-cache nil)
|
||||
(setq auth-sources '(password-store))
|
||||
|
||||
;; don't need to run cleanup after indexing for gmail
|
||||
(setq mu4e-index-cleanup nil)
|
||||
;; because gmail uses labels as folders we can use lazy check since
|
||||
;; messages don't really "move"
|
||||
(setq mu4e-index-lazy-check t)
|
||||
|
||||
(set-email-account! "l.nafaryus@gmail.com"
|
||||
'((mu4e-sent-folder . "/gmail-main/[Gmail]/Sent Mail")
|
||||
(mu4e-drafts-folder . "/gmail-main/[Gmail]/Drafts")
|
||||
(mu4e-trash-folder . "/gmail-main/[Gmail]/Trash")
|
||||
(mu4e-refile-folder . "/gmail-main/[Gmail]/All Mail")
|
||||
(smtpmail-smtp-user . "l.nafaryus@gmail.com")
|
||||
(smtpmail-local-domain . "gmail.com")
|
||||
(smtpmail-default-smtp-server . "smtp.gmail.com")
|
||||
(smtpmail-smtp-server . "smtp.gmail.com")
|
||||
(smtpmail-smtp-service . 587)
|
||||
(mu4e-compose-signature . "---\nL-Nafaryus"))
|
||||
t)
|
||||
|
||||
(setq mu4e-context-policy 'ask-if-none)
|
||||
(setq mu4e-compose-context-policy 'always-ask)
|
||||
;; viewing options
|
||||
(setq mu4e-view-show-addresses t)
|
||||
;; Do not leave message open after it has been sent
|
||||
(setq message-kill-buffer-on-exit t)
|
||||
;; Don't ask for a 'context' upon opening mu4e
|
||||
(setq mu4e-context-policy 'pick-first)
|
||||
;; Don't ask to quit
|
||||
(setq mu4e-confirm-quit nil)
|
||||
(setq mu4e-attachment-dir "~/.mail/.attachments")
|
||||
|
||||
(require 'mu4e-alert)
|
||||
|
||||
(setq mu4e-alert-interesting-mail-query "flag:unread AND maildir:/gmail-main/Inbox")
|
||||
|
||||
(mu4e-alert-enable-mode-line-display)
|
||||
|
||||
(defun refresh-mu4e-alert-mode-line ()
|
||||
(interactive)
|
||||
(mu4e~proc-kill)
|
||||
(async-shell-command "mbsync -a")
|
||||
(mu4e-alert-enable-mode-line-display)
|
||||
(mu4e-alert-enable-notifications)
|
||||
)
|
||||
|
||||
(run-with-timer 0 60 'refresh-mu4e-alert-mode-line)
|
||||
)
|
||||
|
||||
(setq projectile-require-project-root nil)
|
||||
(setq projectile-project-search-path '("~/projects"))
|
||||
|
||||
(after! meson-mode
|
||||
(add-hook 'meson-mode-hook 'company-mode))
|
194
config/emacs/doom-config/init.el
Normal file
194
config/emacs/doom-config/init.el
Normal file
@ -0,0 +1,194 @@
|
||||
;;; init.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; This file controls what Doom modules are enabled and what order they load
|
||||
;; in. Remember to run 'doom sync' after modifying it!
|
||||
|
||||
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
|
||||
;; documentation. There you'll find a link to Doom's Module Index where all
|
||||
;; of our modules are listed, including what flags they support.
|
||||
|
||||
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
|
||||
;; 'C-c c k' for non-vim users) to view its documentation. This works on
|
||||
;; flags as well (those symbols that start with a plus).
|
||||
;;
|
||||
;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
|
||||
;; directory (for easy access to its source code).
|
||||
|
||||
(doom! :input
|
||||
;;bidi ; (tfel ot) thgir etirw uoy gnipleh
|
||||
;;chinese
|
||||
;;japanese
|
||||
;;layout ; auie,ctsrnm is the superior home row
|
||||
|
||||
:completion
|
||||
company ; the ultimate code completion backend
|
||||
;;helm ; the *other* search engine for love and life
|
||||
;;ido ; the other *other* search engine...
|
||||
;;ivy ; a search engine for love and life
|
||||
vertico ; the search engine of the future
|
||||
|
||||
:ui
|
||||
;;deft ; notational velocity for Emacs
|
||||
doom ; what makes DOOM look the way it does
|
||||
doom-dashboard ; a nifty splash screen for Emacs
|
||||
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
|
||||
(emoji +unicode) ; 🙂
|
||||
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
|
||||
;;hydra
|
||||
;;indent-guides ; highlighted indent columns
|
||||
ligatures ; ligatures and symbols to make your code pretty again
|
||||
;;minimap ; show a map of the code on the side
|
||||
modeline ; snazzy, Atom-inspired modeline, plus API
|
||||
;;nav-flash ; blink cursor line after big motions
|
||||
;;neotree ; a project drawer, like NERDTree for vim
|
||||
ophints ; highlight the region an operation acts on
|
||||
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
||||
;;tabs ; a tab bar for Emacs
|
||||
treemacs ; a project drawer, like neotree but cooler
|
||||
unicode ; extended unicode support for various languages
|
||||
(vc-gutter +pretty) ; vcs diff in the fringe
|
||||
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||
window-select ; visually switch windows
|
||||
workspaces ; tab emulation, persistence & separate workspaces
|
||||
;;zen ; distraction-free coding or writing
|
||||
|
||||
:editor
|
||||
(evil +everywhere); come to the dark side, we have cookies
|
||||
file-templates ; auto-snippets for empty files
|
||||
fold ; (nigh) universal code folding
|
||||
;;(format +onsave) ; automated prettiness
|
||||
;;god ; run Emacs commands without modifier keys
|
||||
;;lispy ; vim for lisp, for people who don't like vim
|
||||
;;multiple-cursors ; editing in many places at once
|
||||
;;objed ; text object editing for the innocent
|
||||
;;parinfer ; turn lisp into python, sort of
|
||||
;;rotate-text ; cycle region at point between text candidates
|
||||
snippets ; my elves. They type so I don't have to
|
||||
;;word-wrap ; soft wrapping with language-aware indent
|
||||
|
||||
:emacs
|
||||
dired ; making dired pretty [functional]
|
||||
electric ; smarter, keyword-based electric-indent
|
||||
;;ibuffer ; interactive buffer management
|
||||
undo ; persistent, smarter undo for your inevitable mistakes
|
||||
vc ; version-control and Emacs, sitting in a tree
|
||||
|
||||
:term
|
||||
;;eshell ; the elisp shell that works everywhere
|
||||
;;shell ; simple shell REPL for Emacs
|
||||
;;term ; basic terminal emulator for Emacs
|
||||
vterm ; the best terminal emulation in Emacs
|
||||
|
||||
:checkers
|
||||
syntax ; tasing you for every semicolon you forget
|
||||
(spell +flyspell) ; tasing you for misspelling mispelling
|
||||
grammar ; tasing grammar mistake every you make
|
||||
|
||||
:tools
|
||||
;;ansible
|
||||
biblio ; Writes a PhD for you (citation needed)
|
||||
;;debugger ; FIXME stepping through code, to help you add bugs
|
||||
;;direnv
|
||||
;;docker
|
||||
;;editorconfig ; let someone else argue about tabs vs spaces
|
||||
;;ein ; tame Jupyter notebooks with emacs
|
||||
(eval +overlay) ; run code, run (also, repls)
|
||||
;;gist ; interacting with github gists
|
||||
lookup ; navigate your code and its documentation
|
||||
lsp ; M-x vscode
|
||||
magit ; a git porcelain for Emacs
|
||||
make ; run make tasks from Emacs
|
||||
pass ; password manager for nerds
|
||||
pdf ; pdf enhancements
|
||||
;;prodigy ; FIXME managing external services & code builders
|
||||
;;rgb ; creating color strings
|
||||
;;taskrunner ; taskrunner for all your projects
|
||||
;;terraform ; infrastructure as code
|
||||
;;tmux ; an API for interacting with tmux
|
||||
;;tree-sitter ; syntax and parsing, sitting in a tree...
|
||||
;;upload ; map local to remote projects via ssh/ftp
|
||||
|
||||
:os
|
||||
(:if IS-MAC macos) ; improve compatibility with macOS
|
||||
;;tty ; improve the terminal Emacs experience
|
||||
|
||||
:lang
|
||||
;;agda ; types of types of types of types...
|
||||
;;beancount ; mind the GAAP
|
||||
(cc +lsp) ; C > C++ == 1
|
||||
;;clojure ; java with a lisp
|
||||
common-lisp ; if you've seen one lisp, you've seen them all
|
||||
;;coq ; proofs-as-programs
|
||||
;;crystal ; ruby at the speed of c
|
||||
;;csharp ; unity, .NET, and mono shenanigans
|
||||
;;data ; config/data formats
|
||||
;;(dart +flutter) ; paint ui and not much else
|
||||
;;dhall
|
||||
;;elixir ; erlang done right
|
||||
;;elm ; care for a cup of TEA?
|
||||
emacs-lisp ; drown in parentheses
|
||||
;;erlang ; an elegant language for a more civilized age
|
||||
;;ess ; emacs speaks statistics
|
||||
;;factor
|
||||
;;faust ; dsp, but you get to keep your soul
|
||||
;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER)
|
||||
;;fsharp ; ML stands for Microsoft's Language
|
||||
;;fstar ; (dependent) types and (monadic) effects and Z3
|
||||
;;gdscript ; the language you waited for
|
||||
;;(go +lsp) ; the hipster dialect
|
||||
;;(graphql +lsp) ; Give queries a REST
|
||||
;;(haskell +lsp) ; a language that's lazier than I am
|
||||
;;hy ; readability of scheme w/ speed of python
|
||||
;;idris ; a language you can depend on
|
||||
;;json ; At least it ain't XML
|
||||
;;(java +lsp) ; the poster child for carpal tunnel syndrome
|
||||
;;javascript ; all(hope(abandon(ye(who(enter(here))))))
|
||||
;;julia ; a better, faster MATLAB
|
||||
;;kotlin ; a better, slicker Java(Script)
|
||||
latex ; writing papers in Emacs has never been so fun
|
||||
;;lean ; for folks with too much to prove
|
||||
;;ledger ; be audit you can be
|
||||
;;lua ; one-based indices? one-based indices
|
||||
markdown ; writing docs for people to ignore
|
||||
;;nim ; python + lisp at the speed of c
|
||||
;;nix ; I hereby declare "nix geht mehr!"
|
||||
;;ocaml ; an objective camel
|
||||
org ; organize your plain life in plain text
|
||||
;;php ; perl's insecure younger brother
|
||||
;;plantuml ; diagrams for confusing people more
|
||||
;;purescript ; javascript, but functional
|
||||
python ; beautiful is better than ugly
|
||||
;;qt ; the 'cutest' gui framework ever
|
||||
;;racket ; a DSL for DSLs
|
||||
;;raku ; the artist formerly known as perl6
|
||||
;;rest ; Emacs as a REST client
|
||||
rst ; ReST in peace
|
||||
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
|
||||
(rust +lsp) ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
|
||||
;;scala ; java, but good
|
||||
;;(scheme +guile) ; a fully conniving family of lisps
|
||||
sh ; she sells {ba,z,fi}sh shells on the C xor
|
||||
;;sml
|
||||
;;solidity ; do you need a blockchain? No.
|
||||
;;swift ; who asked for emoji variables?
|
||||
;;terra ; Earth and Moon in alignment for performance.
|
||||
;;web ; the tubes
|
||||
yaml ; JSON, but readable
|
||||
;;zig ; C, but simpler
|
||||
|
||||
:email
|
||||
(mu4e +org +gmail)
|
||||
;;notmuch
|
||||
;;(wanderlust +gmail)
|
||||
|
||||
:app
|
||||
calendar
|
||||
;;emms
|
||||
;;everywhere ; *leave* Emacs!? You must be joking
|
||||
;;irc ; how neckbeards socialize
|
||||
;;(rss +org) ; emacs as an RSS reader
|
||||
;;twitter ; twitter client https://twitter.com/vnought
|
||||
|
||||
:config
|
||||
;;literate
|
||||
(default +bindings +smartparens))
|
52
config/emacs/doom-config/packages.el
Normal file
52
config/emacs/doom-config/packages.el
Normal file
@ -0,0 +1,52 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; $DOOMDIR/packages.el
|
||||
|
||||
;; To install a package with Doom you must declare them here and run 'doom sync'
|
||||
;; on the command line, then restart Emacs for the changes to take effect -- or
|
||||
;; use 'M-x doom/reload'.
|
||||
|
||||
|
||||
;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
|
||||
;(package! some-package)
|
||||
|
||||
;; To install a package directly from a remote git repo, you must specify a
|
||||
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
|
||||
;; https://github.com/radian-software/straight.el#the-recipe-format
|
||||
;(package! another-package
|
||||
; :recipe (:host github :repo "username/repo"))
|
||||
|
||||
;; If the package you are trying to install does not contain a PACKAGENAME.el
|
||||
;; file, or is located in a subdirectory of the repo, you'll need to specify
|
||||
;; `:files' in the `:recipe':
|
||||
;(package! this-package
|
||||
; :recipe (:host github :repo "username/repo"
|
||||
; :files ("some-file.el" "src/lisp/*.el")))
|
||||
|
||||
;; If you'd like to disable a package included with Doom, you can do so here
|
||||
;; with the `:disable' property:
|
||||
;(package! builtin-package :disable t)
|
||||
|
||||
;; You can override the recipe of a built in package without having to specify
|
||||
;; all the properties for `:recipe'. These will inherit the rest of its recipe
|
||||
;; from Doom or MELPA/ELPA/Emacsmirror:
|
||||
;(package! builtin-package :recipe (:nonrecursive t))
|
||||
;(package! builtin-package-2 :recipe (:repo "myfork/package"))
|
||||
|
||||
;; Specify a `:branch' to install a package from a particular branch or tag.
|
||||
;; This is required for some packages whose default branch isn't 'master' (which
|
||||
;; our package manager can't deal with; see radian-software/straight.el#279)
|
||||
;(package! builtin-package :recipe (:branch "develop"))
|
||||
|
||||
;; Use `:pin' to specify a particular commit to install.
|
||||
;(package! builtin-package :pin "1a2b3c4d5e")
|
||||
|
||||
|
||||
;; Doom's packages are pinned to a specific commit and updated from release to
|
||||
;; release. The `unpin!' macro allows you to unpin single packages...
|
||||
;(unpin! pinned-package)
|
||||
;; ...or multiple packages
|
||||
;(unpin! pinned-package another-pinned-package)
|
||||
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
|
||||
;(unpin! t)
|
||||
|
||||
(package! meson-mode)
|
68
config/git/aliases.zsh
Normal file
68
config/git/aliases.zsh
Normal file
@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
g() { [[ $# = 0 ]] && git status --short . || git $*; }
|
||||
|
||||
alias cdg='cd `git rev-parse --show-toplevel`'
|
||||
alias git='noglob git'
|
||||
alias ga='git add'
|
||||
alias gap='git add --patch'
|
||||
alias gb='git branch -av'
|
||||
alias gop='git open'
|
||||
alias gbl='git blame'
|
||||
alias gc='git commit'
|
||||
alias gcm='git commit -m'
|
||||
alias gca='git commit --amend'
|
||||
alias gcf='git commit --fixup'
|
||||
alias gcl='git clone'
|
||||
alias gco='git checkout'
|
||||
alias gcoo='git checkout --'
|
||||
alias gf='git fetch'
|
||||
alias gi='git init'
|
||||
alias gl='git log --graph --pretty="format:%C(yellow)%h%Creset %C(red)%G?%Creset%C(green)%d%Creset %s %Cblue(%cr) %C(bold blue)<%aN>%Creset"'
|
||||
alias gll='git log --pretty="format:%C(yellow)%h%Creset %C(red)%G?%Creset%C(green)%d%Creset %s %Cblue(%cr) %C(bold blue)<%aN>%Creset"'
|
||||
alias gL='gl --stat'
|
||||
alias gp='git push'
|
||||
alias gpl='git pull --rebase --autostash'
|
||||
alias gs='git status --short .'
|
||||
alias gss='git status'
|
||||
alias gst='git stash'
|
||||
alias gr='git reset HEAD'
|
||||
alias gv='git rev-parse'
|
||||
|
||||
# fzf
|
||||
if (( $+commands[fzf] )); then
|
||||
__git_log () {
|
||||
# format str implies:
|
||||
# --abbrev-commit
|
||||
# --decorate
|
||||
git log \
|
||||
--color=always \
|
||||
--graph \
|
||||
--all \
|
||||
--date=short \
|
||||
--format="%C(bold blue)%h%C(reset) %C(green)%ad%C(reset) | %C(white)%s %C(red)[%an] %C(bold yellow)%d"
|
||||
}
|
||||
|
||||
_fzf_complete_git() {
|
||||
ARGS="$@"
|
||||
|
||||
# these are commands I commonly call on commit hashes.
|
||||
# cp->cherry-pick, co->checkout
|
||||
|
||||
if [[ $ARGS == 'git cp'* || \
|
||||
$ARGS == 'git cherry-pick'* || \
|
||||
$ARGS == 'git co'* || \
|
||||
$ARGS == 'git checkout'* || \
|
||||
$ARGS == 'git reset'* || \
|
||||
$ARGS == 'git show'* || \
|
||||
$ARGS == 'git log'* ]]; then
|
||||
_fzf_complete "--reverse --multi" "$@" < <(__git_log)
|
||||
else
|
||||
eval "zle ${fzf_default_completion:-expand-or-complete}"
|
||||
fi
|
||||
}
|
||||
|
||||
_fzf_complete_git_post() {
|
||||
sed -e 's/^[^a-z0-9]*//' | awk '{print $1}'
|
||||
}
|
||||
fi
|
3
config/git/attributes
Normal file
3
config/git/attributes
Normal file
@ -0,0 +1,3 @@
|
||||
*.lisp diff=lisp
|
||||
*.el diff=lisp
|
||||
*.org diff=org
|
58
config/git/config
Normal file
58
config/git/config
Normal file
@ -0,0 +1,58 @@
|
||||
[user]
|
||||
name = Henrik Lissner
|
||||
email = git@henrik.io
|
||||
signingKey = FA1FADD9440B688CAA75A057B60957CA074D39A3
|
||||
[commit]
|
||||
gpgSign = true
|
||||
[tag]
|
||||
gpgSign = true
|
||||
[core]
|
||||
whitespace = trailing-space
|
||||
[init]
|
||||
defaultBranch = main
|
||||
[github]
|
||||
user = hlissner
|
||||
[gitlab]
|
||||
user = hlissner
|
||||
[push]
|
||||
autoSquash = true
|
||||
[push]
|
||||
default = current
|
||||
gpgSign = if-asked
|
||||
[pull]
|
||||
rebase = true
|
||||
[alias]
|
||||
unadd = reset HEAD
|
||||
# data analysis
|
||||
ranked-authors = !git authors | sort | uniq -c | sort -n
|
||||
emails = !git log --format="%aE" | sort -u
|
||||
email-domains = !git log --format="%aE" | awk -F'@' '{print $2}' | sort -u
|
||||
[filter "lfs"]
|
||||
required = true
|
||||
smudge = git-lfs smudge -- %f
|
||||
process = git-lfs filter-process
|
||||
clean = git-lfs clean -- %f
|
||||
[url "https://github.com/"]
|
||||
insteadOf = gh:
|
||||
[url "git@github.com:"]
|
||||
insteadOf = ssh+gh:
|
||||
[url "git@github.com:hlissner/"]
|
||||
insteadOf = gh:/
|
||||
[url "https://gitlab.com/"]
|
||||
insteadOf = gl:
|
||||
[url "https://gist.github.com/"]
|
||||
insteadOf = gist:
|
||||
[url "https://bitbucket.org/"]
|
||||
insteadOf = bb:
|
||||
[url "https://git.henrik.io"]
|
||||
insteadOf = my:
|
||||
[diff "lisp"]
|
||||
xfuncname = "^(((;;;+ )|\\(|([ \t]+\\(((cl-|el-patch-)?def(un|var|macro|method|custom)|gb/))).*)$"
|
||||
[diff "org"]
|
||||
xfuncname = "^(\\*+ +.*)$"
|
||||
[credential "https://github.com"]
|
||||
helper =
|
||||
helper = !gh auth git-credential
|
||||
[credential "https://gist.github.com"]
|
||||
helper =
|
||||
helper = !gh auth git-credential
|
36
config/git/ignore
Normal file
36
config/git/ignore
Normal file
@ -0,0 +1,36 @@
|
||||
# For emacs:
|
||||
*~
|
||||
*.*~
|
||||
\#*
|
||||
.\#*
|
||||
|
||||
# For vim:
|
||||
*.swp
|
||||
.*.sw[a-z]
|
||||
*.un~
|
||||
.netrwhist
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
.DS_Store?
|
||||
.DS_Store
|
||||
.CFUserTextEncoding
|
||||
.Trash
|
||||
.Xauthority
|
||||
thumbs.db
|
||||
Thumbs.db
|
||||
Icon?
|
||||
|
||||
# Code stuffs #
|
||||
###############
|
||||
.ccls-cache/
|
||||
.sass-cache/
|
||||
__pycache__/
|
||||
|
||||
# Compiled thangs #
|
||||
###################
|
||||
*.class
|
||||
*.exe
|
||||
*.o
|
||||
*.pyc
|
||||
*.elc
|
3
config/ncmpcpp/aliases.zsh
Normal file
3
config/ncmpcpp/aliases.zsh
Normal file
@ -0,0 +1,3 @@
|
||||
alias rate=mpd-rate
|
||||
alias mpcs='mpc search any'
|
||||
alias mpcsp='mpc searchplay any'
|
424
config/ncmpcpp/bindings
Normal file
424
config/ncmpcpp/bindings
Normal file
@ -0,0 +1,424 @@
|
||||
def_key "k"
|
||||
scroll_up
|
||||
|
||||
def_key "j"
|
||||
scroll_down
|
||||
|
||||
def_key "K"
|
||||
select_item
|
||||
scroll_up
|
||||
|
||||
def_key "J"
|
||||
select_item
|
||||
scroll_down
|
||||
|
||||
def_key "h"
|
||||
previous_column
|
||||
|
||||
def_key "l"
|
||||
next_column
|
||||
|
||||
def_key "L"
|
||||
show_lyrics
|
||||
|
||||
def_key "up"
|
||||
volume_up
|
||||
|
||||
def_key "down"
|
||||
volume_down
|
||||
|
||||
#def_key "right"
|
||||
# next_column
|
||||
#
|
||||
#def_key "left"
|
||||
# previous_column
|
||||
#
|
||||
#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-_"
|
||||
# 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 "m"
|
||||
# set_visualizer_sample_multiplier
|
||||
#
|
||||
#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"
|
||||
# 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
|
||||
#
|
433
config/ncmpcpp/config
Normal file
433
config/ncmpcpp/config
Normal file
@ -0,0 +1,433 @@
|
||||
##### directories ######
|
||||
ncmpcpp_directory = ~/.config/ncmpcpp
|
||||
|
||||
## Directory for storing downloaded lyrics.
|
||||
lyrics_directory = ~/music/.db/lyrics
|
||||
|
||||
##### connection settings #####
|
||||
mpd_host = "~/.config/mpd/mpd.sock"
|
||||
#mpd_host = "127.0.0.1"
|
||||
#mpd_port = 6600
|
||||
#mpd_connection_timeout = 5
|
||||
|
||||
## Needed for tag editor and file operations to work.
|
||||
mpd_music_dir = ~/music
|
||||
mpd_crossfade_time = 5
|
||||
|
||||
##### music visualizer #####
|
||||
##
|
||||
## Note: In order to make music visualizer work you'll
|
||||
## need to use mpd fifo output, whose format parameter
|
||||
## has to be set to 44100:16:1 for mono visualization
|
||||
## or 44100:16:2 for stereo visualization. Example
|
||||
## configuration (it has to be put into mpd.conf):
|
||||
##
|
||||
## audio_output {
|
||||
## type "fifo"
|
||||
## name "Visualizer feed"
|
||||
## path "/tmp/mpd.fifo"
|
||||
## format "44100:16:2"
|
||||
## }
|
||||
##
|
||||
#visualizer_fifo_path = /tmp/mpd.fifo
|
||||
|
||||
##
|
||||
## Note: Below parameter is needed for ncmpcpp
|
||||
## to determine which output provides data for
|
||||
## visualizer and thus allow syncing between
|
||||
## visualization and sound as currently there
|
||||
## are some problems with it.
|
||||
##
|
||||
#visualizer_output_name = Visualizer feed
|
||||
|
||||
##
|
||||
## If you set format to 44100:16:2, make it 'yes'.
|
||||
##
|
||||
visualizer_in_stereo = no
|
||||
|
||||
##
|
||||
## Multiply received samples by given value. Very
|
||||
## useful for proper visualization of quiet music.
|
||||
##
|
||||
#visualizer_sample_multiplier = 1.0
|
||||
|
||||
##
|
||||
## Note: Below parameter defines how often ncmpcpp
|
||||
## has to "synchronize" visualizer and audio outputs.
|
||||
## 30 seconds is optimal value, but if you experience
|
||||
## synchronization problems, set it to lower value.
|
||||
## Keep in mind that sane values start with >=10.
|
||||
##
|
||||
visualizer_sync_interval = 30
|
||||
|
||||
##
|
||||
## Note: To enable spectrum frequency visualization
|
||||
## you need to compile ncmpcpp with fftw3 support.
|
||||
##
|
||||
#
|
||||
## Available values: spectrum, wave, wave_filled, ellipse.
|
||||
visualizer_type = spectrum
|
||||
## Alternative subset of 256 colors for terminals that support it.
|
||||
#visualizer_color = 41, 83, 119, 155, 185, 215, 209, 203, 197, 161
|
||||
visualizer_color = blue, cyan, green, yellow, magenta, red
|
||||
#visualizer_look = ●▮
|
||||
#
|
||||
##### system encoding #####
|
||||
##
|
||||
## ncmpcpp should detect your charset encoding
|
||||
## but if it failed to do so, you can specify
|
||||
## charset encoding you are using here.
|
||||
##
|
||||
## Note: You can see whether your ncmpcpp build
|
||||
## supports charset detection by checking output
|
||||
## of `ncmpcpp --version`.
|
||||
##
|
||||
## Note: Since MPD uses UTF-8 by default, setting
|
||||
## this option makes sense only if your encoding
|
||||
## is different.
|
||||
##
|
||||
#system_encoding = ""
|
||||
#
|
||||
##### delays #####
|
||||
#
|
||||
## Time of inactivity (in seconds) after playlist
|
||||
## highlighting will be disabled (0 = always on).
|
||||
##
|
||||
#playlist_disable_highlight_delay = 5
|
||||
#
|
||||
## Defines how long messages are supposed to be visible.
|
||||
##
|
||||
message_delay_time = 2
|
||||
#
|
||||
##### song format #####
|
||||
##
|
||||
## For a song format you can use:
|
||||
##
|
||||
## %l - length
|
||||
## %f - filename
|
||||
## %D - directory
|
||||
## %a - artist
|
||||
## %A - album artist
|
||||
## %t - title
|
||||
## %b - album
|
||||
## %y - date
|
||||
## %n - track number (01/12 -> 01)
|
||||
## %N - full track info (01/12 -> 01/12)
|
||||
## %g - genre
|
||||
## %c - composer
|
||||
## %p - performer
|
||||
## %d - disc
|
||||
## %C - comment
|
||||
## %P - priority
|
||||
## $R - begin right alignment
|
||||
##
|
||||
## If you want to make sure that a part of the format is displayed
|
||||
## only when certain tags are present, you can archieve it by
|
||||
## grouping them with brackets, e.g. '{%a - %t}' will be evaluated
|
||||
## to 'ARTIST - TITLE' if both tags are present or '' otherwise.
|
||||
## It is also possible to define a list of alternatives by providing
|
||||
## several groups and separating them with '|', e.g. '{%t}|{%f}'
|
||||
## will be evaluated to 'TITLE' or 'FILENAME' if the former is not
|
||||
## present.
|
||||
##
|
||||
## Note: If you want to set limit on maximal length of a tag, just
|
||||
## put the appropriate number between % and character that defines
|
||||
## tag type, e.g. to make album take max. 20 terminal cells, use '%20b'.
|
||||
##
|
||||
## In addition, formats support markers used for text attributes.
|
||||
## They are followed by character '$'. After that you can put:
|
||||
##
|
||||
## - 0 - default window color (discards all other colors)
|
||||
## - 1 - black
|
||||
## - 2 - red
|
||||
## - 3 - green
|
||||
## - 4 - yellow
|
||||
## - 5 - blue
|
||||
## - 6 - magenta
|
||||
## - 7 - cyan
|
||||
## - 8 - white
|
||||
## - 9 - end of current color
|
||||
## - b - bold text
|
||||
## - u - underline text
|
||||
## - r - reverse colors
|
||||
## - a - use alternative character set
|
||||
##
|
||||
## If you don't want to use a non-color attribute anymore, just put it
|
||||
## again, but this time insert character '/' between '$' and attribute
|
||||
## character, e.g. {$b%t$/b}|{$r%f$/r} will display bolded title tag
|
||||
## or filename with reversed colors.
|
||||
##
|
||||
## If you want to use 256 colors and/or background colors in formats
|
||||
## (the naming scheme is described below in section about color
|
||||
## definitions), it can be done with the syntax $(COLOR), e.g. to set
|
||||
## the artist tag to one of the non-standard colors and make it have
|
||||
## yellow background, you need to write $(197_yellow)%a$(end). Note
|
||||
## that for standard colors this is interchangable with attributes
|
||||
## listed above.
|
||||
##
|
||||
## Note: colors can be nested.
|
||||
##
|
||||
#
|
||||
# song_list_format = {%a }$2%t$9 %C $R{%b }$2%25l$9
|
||||
#song_list_format = {{$5%a$9 }{$7%A$9 }}{%n }$(16)%t$(end) $R{$8%l$9}
|
||||
# song_status_format = {{%a{ $3%b{ (%y)}$9} }{$8%t$9}}|{%f}
|
||||
#song_library_format = {%n - }{%t}|{%f}
|
||||
song_list_format = "{$2%a$9} {$5%t$9} $R {$3%b$3} $9({$9%l$9})"
|
||||
song_library_format = "%n %t"
|
||||
song_status_format = "$b{$6%a$9 $1|$9} {$7%t$9} $1|$9 {$2%b$9} $1|$9 {$6%y$9} $1|$9"
|
||||
#
|
||||
#
|
||||
#alternative_header_first_line_format = $b$1$aqqu$/a$9 {%t}|{%f} $1$atqq$/a$9$/b
|
||||
#alternative_header_second_line_format = {{$4$b%a$/b$9}{ - $7%b$9}{ ($4%y$9)}}|{%D}
|
||||
#
|
||||
now_playing_prefix = "$(3_236)> "
|
||||
now_playing_suffix = $0
|
||||
#
|
||||
#browser_playlist_prefix = "$2playlist$9 "
|
||||
#
|
||||
selected_item_prefix = "$(6_237)+ "
|
||||
selected_item_suffix = $9
|
||||
#
|
||||
# modified_item_prefix = $3> $9
|
||||
#
|
||||
##
|
||||
## Note: attributes are not supported for the following variables.
|
||||
##
|
||||
#song_window_title_format = {%a - }{%t}|{%f}
|
||||
##
|
||||
## Note: Below variables are used for sorting songs in browser.
|
||||
## The sort mode determines how songs are sorted, and can be used
|
||||
## in combination with a sort format to specify a custom sorting format.
|
||||
## Available values for browser_sort_mode are "name", "mtime", "format"
|
||||
## and "noop".
|
||||
##
|
||||
#
|
||||
#browser_sort_mode = name
|
||||
#browser_sort_format = {%a - }{%t}|{%f} {(%l)}
|
||||
#
|
||||
##### columns settings #####
|
||||
##
|
||||
## syntax of song columns list format is "column column etc."
|
||||
##
|
||||
## - syntax for each column is:
|
||||
##
|
||||
## (width of the column)[color of the column]{displayed tag}
|
||||
##
|
||||
## Note: Width is by default in %, if you want a column to
|
||||
## have fixed size, add 'f' after the value, e.g. (10)[white]{a}
|
||||
## will be the column that take 10% of screen (so the real width
|
||||
## will depend on actual screen size), whereas (10f)[white]{a}
|
||||
## will take 10 terminal cells, no matter how wide the screen is.
|
||||
##
|
||||
## - color is optional (if you want the default one,
|
||||
## leave the field empty).
|
||||
##
|
||||
## Note: You can give a column additional attributes by putting appropriate
|
||||
## character after displayed tag character. Available attributes are:
|
||||
##
|
||||
## - r - column will be right aligned
|
||||
## - E - if tag is empty, empty tag marker won't be displayed
|
||||
##
|
||||
## You can also:
|
||||
##
|
||||
## - give a column custom name by putting it after attributes,
|
||||
## separated with character ':', e.g. {lr:Length} gives you
|
||||
## right aligned column of lengths named "Length".
|
||||
##
|
||||
## - define sequence of tags, that have to be displayed in case
|
||||
## predecessor is empty in a way similar to the one in classic
|
||||
## song format, i.e. using '|' character, e.g. {a|c|p:Owner}
|
||||
## creates column named "Owner" that tries to display artist
|
||||
## tag and then composer and performer if previous ones are
|
||||
## not available.
|
||||
##
|
||||
song_columns_list_format = (3f)[241]{NEr:#} (8f)[5]{l} (22)[6]{a|A:Artist} (40)[9]{t|f:Title} (30)[13]{b}
|
||||
#
|
||||
##### various settings #####
|
||||
#
|
||||
##
|
||||
## Note: Custom command that will be executed each
|
||||
## time song changes. Useful for notifications etc.
|
||||
##
|
||||
execute_on_song_change = "mpd-notify-song"
|
||||
#playlist_show_mpd_host = no
|
||||
playlist_show_remaining_time = yes
|
||||
playlist_shorten_total_times = yes
|
||||
#playlist_separate_albums = no
|
||||
#
|
||||
##
|
||||
## Note: Possible display modes: classic, columns.
|
||||
##
|
||||
playlist_display_mode = classic
|
||||
browser_display_mode = columns
|
||||
#search_engine_display_mode = classic
|
||||
#playlist_editor_display_mode = classic
|
||||
discard_colors_if_item_is_selected = yes
|
||||
incremental_seeking = yes
|
||||
seek_time = 2
|
||||
volume_change_step = 10
|
||||
#autocenter_mode = no
|
||||
#centered_cursor = no
|
||||
#
|
||||
##
|
||||
## Note: You can specify third character which will
|
||||
## be used to build 'empty' part of progressbar.
|
||||
##
|
||||
progressbar_look = "─╼ "
|
||||
#progressbar_boldness
|
||||
progressbar_color = 1
|
||||
progressbar_elapsed_color = 4
|
||||
#
|
||||
## Available values: database, playlist.
|
||||
##
|
||||
#default_place_to_search_in = database
|
||||
#
|
||||
## Available values: classic, alternative.
|
||||
##
|
||||
user_interface = alternative
|
||||
#data_fetching_delay = yes
|
||||
#
|
||||
## Available values: artist, album_artist, date, genre, composer, performer.
|
||||
##
|
||||
#media_library_primary_tag = artist
|
||||
#
|
||||
## Available values: wrapped, normal.
|
||||
##
|
||||
#default_find_mode = wrapped
|
||||
#default_tag_editor_pattern = %n - %t
|
||||
header_visibility = yes
|
||||
statusbar_visibility = yes
|
||||
titles_visibility = no
|
||||
#header_text_scrolling = yes
|
||||
#cyclic_scrolling = no
|
||||
#lines_scrolled = 2
|
||||
#follow_now_playing_lyrics = no
|
||||
#fetch_lyrics_for_current_song_in_background = no
|
||||
#store_lyrics_in_song_dir = no
|
||||
#generate_win32_compatible_filenames = yes
|
||||
allow_for_physical_item_deletion = yes
|
||||
#
|
||||
##
|
||||
## Note: If you set this variable, ncmpcpp will try to
|
||||
## get info from last.fm in language you set and if it
|
||||
## fails, it will fall back to english. Otherwise it will
|
||||
## use english the first time.
|
||||
##
|
||||
## Note: Language has to be expressed as an ISO 639 alpha-2 code.
|
||||
##
|
||||
#lastfm_preferred_language = en
|
||||
#show_hidden_files_in_local_browser = no
|
||||
#
|
||||
##
|
||||
## How shall screen switcher work?
|
||||
##
|
||||
## - "previous" - switch between the current and previous screen.
|
||||
## - "screen1,...,screenN" - switch between given sequence of screens.
|
||||
##
|
||||
## Screens available for use: help, playlist, browser, search_engine,
|
||||
## media_library, playlist_editor, tag_editor, outputs, visualizer, clock.
|
||||
##
|
||||
#screen_switcher_mode = playlist, browser
|
||||
#
|
||||
##
|
||||
## Note: You can define startup screen
|
||||
## by choosing screen from the list above.
|
||||
##
|
||||
#startup_screen = playlist
|
||||
#
|
||||
##
|
||||
## Note: You can define startup slave screen
|
||||
## by choosing screen from the list above or
|
||||
## an empty value for no slave screen.
|
||||
##
|
||||
#startup_slave_screen = ""
|
||||
#startup_slave_screen_focus = no
|
||||
#
|
||||
##
|
||||
## Default width of locked screen (in %).
|
||||
## Acceptable values are from 20 to 80.
|
||||
##
|
||||
#
|
||||
#locked_screen_width_part = 50
|
||||
#ask_for_locked_screen_width_part = yes
|
||||
jump_to_now_playing_song_at_start = yes
|
||||
#ask_before_clearing_playlists = yes
|
||||
#clock_display_seconds = no
|
||||
#display_volume_level = no
|
||||
#display_bitrate = yes
|
||||
display_remaining_time = no
|
||||
#
|
||||
## Available values: none, basic, extended, perl.
|
||||
##
|
||||
#regular_expressions = perl
|
||||
#
|
||||
##
|
||||
## Note: If below is enabled, ncmpcpp will ignore leading
|
||||
## "The" word while sorting items in browser, tags in
|
||||
## media library, etc.
|
||||
##
|
||||
#ignore_leading_the = no
|
||||
#block_search_constraints_change_if_items_found = yes
|
||||
#mouse_support = yes
|
||||
#mouse_list_scroll_whole_page = yes
|
||||
empty_tag_marker = <empty>
|
||||
#tags_separator = " | "
|
||||
tag_editor_extended_numeration = yes
|
||||
#media_library_sort_by_mtime = no
|
||||
enable_window_title = yes
|
||||
#
|
||||
##
|
||||
## Note: You can choose default search mode for search
|
||||
## engine. Available modes are:
|
||||
##
|
||||
## - 1 - use mpd built-in searching (no regexes, pattern matching)
|
||||
## - 2 - use ncmpcpp searching (pattern matching with support for regexes,
|
||||
## but if your mpd is on a remote machine, downloading big database
|
||||
## to process it can take a while
|
||||
## - 3 - match only exact values (this mode uses mpd function for searching
|
||||
## in database and local one for searching in current playlist)
|
||||
##
|
||||
search_engine_default_search_mode = 2
|
||||
external_editor = vim
|
||||
|
||||
## Note: set to yes if external editor is a console application.
|
||||
use_console_editor = yes
|
||||
|
||||
##### colors definitions #####
|
||||
##
|
||||
## It is possible to set a background color by setting a color
|
||||
## value "<foreground>_<background>", e.g. red_black will set
|
||||
## foregound color to red and background color to black.
|
||||
##
|
||||
## In addition, for terminals that support 256 colors it
|
||||
## is possible to set one of them by using a number in range
|
||||
## [1, 256] instead of color name, e.g. numerical value
|
||||
## corresponding to red_black is 2_1. To find out if the
|
||||
## terminal supports 256 colors, run ncmpcpp and check out
|
||||
## the bottom of the help screen for list of available colors
|
||||
## and their numerical values.
|
||||
##
|
||||
## Note: due to technical limitations of ncurses, if 256 colors
|
||||
## are used, it is possible to either use only the colors with
|
||||
## default background color, or all pairs from 1_1 up to 254_127,
|
||||
## depending on the ncurses version used.
|
||||
##
|
||||
colors_enabled = yes
|
||||
empty_tag_color = 13
|
||||
header_window_color = 241
|
||||
volume_color = 239
|
||||
state_line_color = 13
|
||||
state_flags_color = 13
|
||||
main_window_color = green
|
||||
color1 = white
|
||||
color2 = blue
|
||||
# main_window_highlight_color = yellow
|
||||
statusbar_color = 13
|
||||
statusbar_time_color = 6
|
||||
player_state_color = 14
|
||||
alternative_ui_separator_color = 2
|
||||
current_item_prefix = $(9_238)
|
||||
current_item_suffix = $(end)
|
||||
# active_column_color = red
|
||||
window_border_color = 13
|
||||
active_window_border = 13
|
27
config/tmux/aliases.zsh
Normal file
27
config/tmux/aliases.zsh
Normal file
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
alias ta='tmux attach'
|
||||
alias tl='tmux ls'
|
||||
|
||||
if [[ -n $TMUX ]]; then # From inside tmux
|
||||
alias tf='tmux find-window'
|
||||
# Detach all other clients to this session
|
||||
alias mine='tmux detach -a'
|
||||
# Send command to other tmux window
|
||||
tt() {
|
||||
tmux send-keys -t .+ C-u && \
|
||||
tmux set-buffer "$*" && \
|
||||
tmux paste-buffer -t .+ && \
|
||||
tmux send-keys -t .+ Enter;
|
||||
}
|
||||
# Create new session (from inside one)
|
||||
tn() {
|
||||
local name="${1:-`basename $PWD`}"
|
||||
TMUX= tmux new-session -d -s "$name"
|
||||
tmux switch-client -t "$name"
|
||||
tmux display-message "Session #S created"
|
||||
}
|
||||
else # From outside tmux
|
||||
# Start grouped session so I can be in two different windows in one session
|
||||
tdup() { tmux new-session -t "${1:-`tmux display-message -p '#S'`}"; }
|
||||
fi
|
23
config/tmux/swap-pane.sh
Executable file
23
config/tmux/swap-pane.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
CONF="$TMUX_PLUGINS_PATH/lastpane"
|
||||
swap() { tmux swap-pane -s"$1" -t"$2"; }
|
||||
|
||||
target=
|
||||
case $1 in
|
||||
up) target="U" ;;
|
||||
down) target="D" ;;
|
||||
left) target="L" ;;
|
||||
right) target="R" ;;
|
||||
master) target="M" ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
|
||||
src_pane=$(tmux display-message -p "#P")
|
||||
tmux select-pane -${target}
|
||||
|
||||
dst_pane=$(tmux display-message -p "#P")
|
||||
tmux select-pane -${src_pane}
|
||||
|
||||
[[ "$target" == M ]] && dst_pane=0
|
||||
swap "$src_pane" "$dst_pane"
|
||||
tmux select-pane -t"$dst_pane"
|
123
config/tmux/tmux.conf
Normal file
123
config/tmux/tmux.conf
Normal file
@ -0,0 +1,123 @@
|
||||
# tmux.conf
|
||||
########################################
|
||||
|
||||
set -s default-terminal "xterm-256color"
|
||||
|
||||
setw -g automatic-rename on # rename window after current program
|
||||
set -g renumber-windows on # renumber windows when one is closed
|
||||
# Zero-based indexing is fine in programming languages, but not so much in a
|
||||
# multiplexer when zero is on the other side of the keyboard.
|
||||
set -g base-index 1
|
||||
setw -g pane-base-index 1
|
||||
# display tmux messages longer
|
||||
set -g display-time 1500
|
||||
set -g display-panes-time 800
|
||||
# Address vim-mode switching delay (http://superuser.com/a/252717/65504)
|
||||
set -s escape-time 0
|
||||
set -sg repeat-time 600
|
||||
set -g history-limit 50000
|
||||
# Update status-{left,right} more often (default: 15)
|
||||
set -g status-interval 5
|
||||
# Rather than constraining window size to the maximum size of any client
|
||||
# connected to the *session*, constrain window size to the maximum size of any
|
||||
# client connected to *that window*. Much more reasonable.
|
||||
setw -g aggressive-resize off
|
||||
# For terminals that support them, propagate these events to programs that
|
||||
# understand them.
|
||||
set -s focus-events on
|
||||
# Enable mouse + mouse wheel
|
||||
set -g mouse on
|
||||
|
||||
########################################
|
||||
# Keybinds #
|
||||
########################################
|
||||
|
||||
# Rebind prefix to C-c. Press twice to send literal C-c.
|
||||
unbind C-b
|
||||
set -g prefix C-c
|
||||
bind C-c send-prefix
|
||||
|
||||
# Vi-style keybinds
|
||||
set -g status-keys vi
|
||||
set -g mode-keys vi
|
||||
|
||||
bind c new-window -c "#{pane_current_path}"
|
||||
bind v split-window -h -c "#{pane_current_path}"
|
||||
bind s split-window -v -c "#{pane_current_path}"
|
||||
|
||||
bind h select-pane -L
|
||||
bind j select-pane -D
|
||||
bind k select-pane -U
|
||||
bind l select-pane -R
|
||||
bind H run '$TMUX_HOME/swap-pane.sh left'
|
||||
bind J run '$TMUX_HOME/swap-pane.sh down'
|
||||
bind K run '$TMUX_HOME/swap-pane.sh up'
|
||||
bind L run '$TMUX_HOME/swap-pane.sh right'
|
||||
bind M run '$TMUX_HOME/swap-pane.sh master'
|
||||
|
||||
bind o resize-pane -Z
|
||||
bind S choose-session
|
||||
bind W choose-window
|
||||
bind / choose-session
|
||||
bind . choose-window
|
||||
|
||||
# bind = select-layout tiled
|
||||
bind | select-layout even-horizontal
|
||||
bind _ select-layout even-vertical
|
||||
|
||||
# Disable confirmation
|
||||
bind x kill-pane
|
||||
bind X kill-window
|
||||
bind q kill-session
|
||||
bind Q kill-server
|
||||
|
||||
# Smart pane switching with awareness of vim splits
|
||||
# See: https://github.com/christoomey/vim-tmux-navigator
|
||||
is_vim='echo "#{pane_current_command}" | grep -iqE "(^|\/)g?(view|n?vim?x?)(diff)?$"'
|
||||
bind -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L"
|
||||
bind -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D"
|
||||
bind -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U"
|
||||
bind -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R"
|
||||
bind -n C-\\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"
|
||||
bind C-w last-pane
|
||||
bind C-n next-window
|
||||
bind C-p previous-window
|
||||
|
||||
# break pane into a window
|
||||
bind = select-layout even-vertical
|
||||
bind + select-layout even-horizontal
|
||||
bind - break-pane
|
||||
bind _ join-pane
|
||||
|
||||
# reload config without killing server
|
||||
bind r source-file $DOTFILES/config/tmux/tmux.conf \; display-message " Config reloaded..".
|
||||
bind ^r refresh-client
|
||||
|
||||
|
||||
########################################
|
||||
# Copy mode #
|
||||
########################################
|
||||
|
||||
bind Enter copy-mode # enter copy mode
|
||||
bind b list-buffers # list paster buffers
|
||||
bind B choose-buffer # choose which buffer to paste from
|
||||
bind p paste-buffer # paste from the top paste buffer
|
||||
bind P run "xclip -selection clipboard -o | tmux load-buffer - ; tmux paste-buffer"
|
||||
|
||||
bind -T copy-mode-vi v send-keys -X begin-selection
|
||||
bind -T copy-mode-vi C-v send-keys -X rectangle-toggle
|
||||
bind -T copy-mode-vi Escape send-keys -X cancel
|
||||
bind -T copy-mode-vi C-g send-keys -X cancel
|
||||
bind -T copy-mode-vi H send-keys -X start-of-line
|
||||
bind -T copy-mode-vi L send-keys -X end-of-line
|
||||
|
||||
|
||||
########################################
|
||||
# Local config #
|
||||
########################################
|
||||
set -g @open-editor 'C-e'
|
||||
set -g @open-S 'https://www.duckduckgo.com/'
|
||||
set -g @resurrect-processes 'ssh sqlite3 "git log"'
|
||||
|
||||
run-shell $TMUX_HOME/extraInit
|
||||
if '[ -f ~/.tmux.conf ]' 'source-file ~/.tmux.conf'
|
34
config/zsh/.zshenv
Normal file
34
config/zsh/.zshenv
Normal file
@ -0,0 +1,34 @@
|
||||
function _cache {
|
||||
(( $+commands[$1] )) || return 1
|
||||
local cache_dir="$XDG_CACHE_HOME/${SHELL##*/}"
|
||||
local cache="$cache_dir/$1"
|
||||
if [[ ! -f $cache || ! -s $cache ]]; then
|
||||
echo "Caching $1"
|
||||
mkdir -p $cache_dir
|
||||
"$@" >$cache
|
||||
chmod 600 $cache
|
||||
fi
|
||||
if [[ -o interactive ]]; then
|
||||
source $cache || rm -f $cache
|
||||
fi
|
||||
}
|
||||
|
||||
function _source {
|
||||
for file in "$@"; do
|
||||
[ -r $file ] && source $file
|
||||
done
|
||||
}
|
||||
|
||||
# Be more restrictive with permissions; no one has any business reading things
|
||||
# that don't belong to them.
|
||||
if (( EUID != 0 )); then
|
||||
umask 027
|
||||
else
|
||||
# Be even less permissive if root.
|
||||
umask 077
|
||||
fi
|
||||
|
||||
# Auto-generated by my nix config
|
||||
_source ${0:a:h}/extra.zshenv
|
||||
# If you have host-local configuration, this is where you'd put it
|
||||
_source $ZDOTDIR/local.zshenv
|
52
config/zsh/.zshrc
Normal file
52
config/zsh/.zshrc
Normal file
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env zsh
|
||||
source $ZDOTDIR/config.zsh
|
||||
|
||||
# NOTE ZGEN_DIR and ZGEN_SOURCE are forward-declared in modules/shell/zsh.nix
|
||||
# NOTE Using zgenom because zgen is no longer maintained
|
||||
if [ ! -d "$ZGEN_DIR" ]; then
|
||||
echo "Installing jandamm/zgenom"
|
||||
git clone https://github.com/jandamm/zgenom "$ZGEN_DIR"
|
||||
fi
|
||||
source $ZGEN_DIR/zgenom.zsh
|
||||
|
||||
# Check for plugin and zgenom updates every 7 days
|
||||
# This does not increase the startup time.
|
||||
zgenom autoupdate
|
||||
|
||||
if ! zgenom saved; then
|
||||
echo "Initializing zgenom"
|
||||
rm -f $ZDOTDIR/*.zwc(N) \
|
||||
$XDG_CACHE_HOME/zsh/*(N) \
|
||||
$ZGEN_INIT.zwc
|
||||
|
||||
# NOTE Be extra careful about plugin load order, or subtle breakage can
|
||||
# emerge. This is the best order I've sussed out for these plugins.
|
||||
zgenom load junegunn/fzf shell
|
||||
zgenom load jeffreytse/zsh-vi-mode
|
||||
zgenom load zdharma-continuum/fast-syntax-highlighting
|
||||
zgenom load zsh-users/zsh-completions src
|
||||
zgenom load zsh-users/zsh-autosuggestions
|
||||
zgenom load zsh-users/zsh-history-substring-search
|
||||
zgenom load romkatv/powerlevel10k powerlevel10k
|
||||
zgenom load hlissner/zsh-autopair autopair.zsh
|
||||
|
||||
zgenom save
|
||||
zgenom compile $ZDOTDIR
|
||||
fi
|
||||
|
||||
## Bootstrap interactive sessions
|
||||
if [[ $TERM != dumb ]]; then
|
||||
autoload -Uz compinit && compinit -u -d $ZSH_CACHE/zcompdump
|
||||
|
||||
source $ZDOTDIR/keybinds.zsh
|
||||
source $ZDOTDIR/completion.zsh
|
||||
source $ZDOTDIR/aliases.zsh
|
||||
|
||||
# Auto-generated by nixos
|
||||
_source $ZDOTDIR/extra.zshrc
|
||||
# If you have host-local configuration, put it here
|
||||
_source $ZDOTDIR/local.zshrc
|
||||
|
||||
_cache fasd --init posix-alias zsh-{hook,{c,w}comp{,-install}}
|
||||
autopair-init
|
||||
fi
|
84
config/zsh/aliases.zsh
Normal file
84
config/zsh/aliases.zsh
Normal file
@ -0,0 +1,84 @@
|
||||
alias ..='cd ..'
|
||||
alias ...='cd ../..'
|
||||
alias ....='cd ../../..'
|
||||
alias -- -='cd -'
|
||||
|
||||
alias q=exit
|
||||
alias clr=clear
|
||||
alias sudo='sudo '
|
||||
alias rm='rm -i'
|
||||
alias cp='cp -i'
|
||||
alias mv='mv -i'
|
||||
alias mkdir='mkdir -pv'
|
||||
alias wget='wget -c'
|
||||
alias path='echo -e ${PATH//:/\\n}'
|
||||
alias ports='netstat -tulanp'
|
||||
|
||||
alias mk=make
|
||||
alias gurl='curl --compressed'
|
||||
|
||||
alias shutdown='sudo shutdown'
|
||||
alias reboot='sudo reboot'
|
||||
|
||||
# An rsync that respects gitignore
|
||||
rcp() {
|
||||
# -a = -rlptgoD
|
||||
# -r = recursive
|
||||
# -l = copy symlinks as symlinks
|
||||
# -p = preserve permissions
|
||||
# -t = preserve mtimes
|
||||
# -g = preserve owning group
|
||||
# -o = preserve owner
|
||||
# -z = use compression
|
||||
# -P = show progress on transferred file
|
||||
# -J = don't touch mtimes on symlinks (always errors)
|
||||
rsync -azPJ \
|
||||
--include=.git/ \
|
||||
--filter=':- .gitignore' \
|
||||
--filter=":- $XDG_CONFIG_HOME/git/ignore" \
|
||||
"$@"
|
||||
}; compdef rcp=rsync
|
||||
alias rcpd='rcp --delete --delete-after'
|
||||
alias rcpu='rcp --chmod=go='
|
||||
alias rcpdu='rcpd --chmod=go='
|
||||
|
||||
alias y='xclip -selection clipboard -in'
|
||||
alias p='xclip -selection clipboard -out'
|
||||
|
||||
alias jc='journalctl -xe'
|
||||
alias sc=systemctl
|
||||
alias ssc='sudo systemctl'
|
||||
|
||||
if (( $+commands[exa] )); then
|
||||
alias exa="exa --group-directories-first --git";
|
||||
alias l="exa -blF";
|
||||
alias ll="exa -abghilmu";
|
||||
alias llm='ll --sort=modified'
|
||||
alias la="LC_COLLATE=C exa -ablF";
|
||||
alias tree='exa --tree'
|
||||
fi
|
||||
|
||||
if (( $+commands[fasd] )); then
|
||||
# fuzzy completion with 'z' when called without args
|
||||
unalias z 2>/dev/null
|
||||
function z {
|
||||
[ $# -gt 0 ] && _z "$*" && return
|
||||
cd "$(_z -l 2>&1 | fzf --height 40% --nth 2.. --reverse --inline-info +s --tac --query "${*##-* }" | sed 's/^[0-9,.]* *//')"
|
||||
}
|
||||
fi
|
||||
|
||||
autoload -U zmv
|
||||
|
||||
function take {
|
||||
mkdir "$1" && cd "$1";
|
||||
}; compdef take=mkdir
|
||||
|
||||
function zman {
|
||||
PAGER="less -g -I -s '+/^ "$1"'" man zshall;
|
||||
}
|
||||
|
||||
# Create a reminder with human-readable durations, e.g. 15m, 1h, 40s, etc
|
||||
function r {
|
||||
local time=$1; shift
|
||||
sched "$time" "notify-send --urgency=critical 'Reminder' '$@'; ding";
|
||||
}; compdef r=sched
|
97
config/zsh/completion.zsh
Normal file
97
config/zsh/completion.zsh
Normal file
@ -0,0 +1,97 @@
|
||||
fpath+=( $ZDOTDIR/completions )
|
||||
|
||||
# Don't offer history completion; we have fzf, C-r, and
|
||||
# zsh-history-substring-search for that.
|
||||
ZSH_AUTOSUGGEST_STRATEGY=(completion)
|
||||
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=30
|
||||
|
||||
# Expand partial paths, e.g. cd f/b/z == cd foo/bar/baz (assuming no ambiguity)
|
||||
zstyle ':completion:*:paths' path-completion yes
|
||||
|
||||
# Fix slow one-by-one character pasting when bracketed-paste-magic is on. See
|
||||
# zsh-users/zsh-syntax-highlighting#295
|
||||
zstyle ':bracketed-paste-magic' active-widgets '.self-*'
|
||||
|
||||
# Options
|
||||
setopt COMPLETE_IN_WORD # Complete from both ends of a word.
|
||||
setopt PATH_DIRS # Perform path search even on command names with slashes.
|
||||
setopt AUTO_MENU # Show completion menu on a successive tab press.
|
||||
setopt AUTO_LIST # Automatically list choices on ambiguous completion.
|
||||
# setopt AUTO_PARAM_SLASH # If completed parameter is a directory, add a trailing slash.
|
||||
# setopt AUTO_PARAM_KEYS
|
||||
# setopt FLOW_CONTROL # Disable start/stop characters in shell editor.
|
||||
unsetopt MENU_COMPLETE # Do not autoselect the first completion entry.
|
||||
unsetopt COMPLETE_ALIASES # Completion for aliases
|
||||
# unsetopt ALWAYS_TO_END # Move cursor to the end of a completed word.
|
||||
unsetopt CASE_GLOB
|
||||
|
||||
# Fuzzy match mistyped completions.
|
||||
zstyle ':completion:*' completer _complete _list _match _approximate
|
||||
zstyle ':completion:*:match:*' original only
|
||||
zstyle ':completion:*:approximate:*' max-errors 1 numeric
|
||||
# Increase the number of errors based on the length of the typed word.
|
||||
zstyle -e ':completion:*:approximate:*' max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'
|
||||
# Don't complete unavailable commands.
|
||||
zstyle ':completion:*:functions' ignored-patterns '(_*|.*|pre(cmd|exec))'
|
||||
# Group matches and describe.
|
||||
zstyle ':completion:*:corrections' format '%B%F{green}%d (errors: %e)%f%b'
|
||||
zstyle ':completion:*:messages' format '%B%F{yellow}%d%f%b'
|
||||
zstyle ':completion:*:warnings' format '%B%F{red}No such %d%f%b'
|
||||
zstyle ':completion:*:errors' format '%B%F{red}No such %d%f%b'
|
||||
zstyle ':completion:*:descriptions' format $'%{\e[35;1m%}%d%{\e[0m%}'
|
||||
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
|
||||
# Omit parent and current directories from completion results when they are
|
||||
# already named in the input.
|
||||
zstyle ':completion:*:*:cd:*' ignore-parents parent pwd
|
||||
# Merge multiple, consecutive slashes in paths
|
||||
zstyle ':completion:*' squeeze-slashes true
|
||||
# Don't wrap around when navigating to either end of history
|
||||
zstyle ':completion:*:history-words' stop yes
|
||||
zstyle ':completion:*:history-words' remove-all-dups yes
|
||||
zstyle ':completion:*:history-words' list false
|
||||
zstyle ':completion:*:history-words' menu yes
|
||||
# Exclude internal/fake envvars
|
||||
zstyle ':completion::*:(-command-|export):*' fake-parameters ${${${_comps[(I)-value-*]#*,}%%,*}:#-*-}
|
||||
# Sory array completion candidates
|
||||
zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
|
||||
# Complete hostnames from ssh files too
|
||||
zstyle -e ':completion:*:hosts' hosts 'reply=(
|
||||
${=${=${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) 2>/dev/null)"}%%[#| ]*}//\]:[0-9]*/ }//,/ }//\[/ }
|
||||
${=${${${${(@M)${(f)"$(cat ~/.ssh/config 2>/dev/null)"}:#Host *}#Host }:#*\**}:#*\?*}}
|
||||
)'
|
||||
# Don't complete uninteresting users
|
||||
zstyle ':completion:*:users' ignored-patterns \
|
||||
adm amanda apache avahi beaglidx bin cacti canna clamav daemon \
|
||||
dbus distcache dovecot fax ftp games gdm gkrellmd gopher \
|
||||
hacluster haldaemon halt hsqldb ident junkbust ldap lp mail \
|
||||
mailman mailnull mldonkey mysql nagios \
|
||||
named netdump news nfsnobody nobody 'nixbld*' nscd ntp nut nx openvpn \
|
||||
operator pcap postfix postgres privoxy pulse pvm quagga radvd \
|
||||
rpc rpcuser rpm shutdown squid sshd sync 'systemd-*' uucp vcsa xfs '_*'
|
||||
# ... unless we really want to.
|
||||
zstyle '*' single-ignored show
|
||||
# Ignore multiple entries.
|
||||
zstyle ':completion:*:(rm|kill|diff):*' ignore-line other
|
||||
zstyle ':completion:*:rm:*' file-patterns '*:all-files'
|
||||
# PID completion for kill
|
||||
zstyle ':completion:*:*:*:*:processes' command 'ps -u $LOGNAME -o pid,user,command -w'
|
||||
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;36=0=01'
|
||||
zstyle ':completion:*:*:kill:*' menu yes select
|
||||
zstyle ':completion:*:*:kill:*' force-list always
|
||||
zstyle ':completion:*:*:kill:*' insert-ids single
|
||||
# Man
|
||||
zstyle ':completion:*:manuals' separate-sections true
|
||||
zstyle ':completion:*:manuals.(^1*)' insert-sections true
|
||||
# Media Players
|
||||
zstyle ':completion:*:*:mpg123:*' file-patterns '*.(mp3|MP3):mp3\ files *(-/):directories'
|
||||
zstyle ':completion:*:*:mpg321:*' file-patterns '*.(mp3|MP3):mp3\ files *(-/):directories'
|
||||
zstyle ':completion:*:*:ogg123:*' file-patterns '*.(ogg|OGG|flac):ogg\ files *(-/):directories'
|
||||
zstyle ':completion:*:*:mocp:*' file-patterns '*.(wav|WAV|mp3|MP3|ogg|OGG|flac):ogg\ files *(-/):directories'
|
||||
# SSH/SCP/RSYNC
|
||||
zstyle ':completion:*:(scp|rsync):*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *'
|
||||
zstyle ':completion:*:(scp|rsync):*' group-order users files all-files hosts-domain hosts-host hosts-ipaddr
|
||||
zstyle ':completion:*:ssh:*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *'
|
||||
zstyle ':completion:*:ssh:*' group-order users hosts-domain hosts-host users hosts-ipaddr
|
||||
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-host' ignored-patterns '*(.|:)*' loopback ip6-loopback localhost ip6-localhost broadcasthost
|
||||
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-domain' ignored-patterns '<->.<->.<->.<->' '^[-[:alnum:]]##(.[-[:alnum:]]##)##' '*@*'
|
||||
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-ipaddr' ignored-patterns '^(<->.<->.<->.<->|(|::)([[:xdigit:].]##:(#c,2))##(|%*))' '127.0.0.<->' '255.255.255.255' '::1' 'fe80::*'
|
36
config/zsh/completions/_hey
Executable file
36
config/zsh/completions/_hey
Executable file
@ -0,0 +1,36 @@
|
||||
#compdef hey
|
||||
|
||||
_hey_dispatch () {
|
||||
local cmd="$@"
|
||||
local offset=$#
|
||||
CURRENT=$((CURRENT-$offset))
|
||||
words=($cmd "${words[$((2 + offset)),-1]}")
|
||||
_$cmd
|
||||
}
|
||||
|
||||
_hey_command_list () {
|
||||
hey | sed '1,/Available commands:/d' | awk '{ print $1 }'
|
||||
}
|
||||
|
||||
_hey () {
|
||||
local -a commands
|
||||
IFS=$'\n' commands=($(_hey_command_list))
|
||||
|
||||
if (( CURRENT == 2 )); then
|
||||
_describe -t commands "hey commands" commands
|
||||
return
|
||||
fi
|
||||
integer ret=1
|
||||
case ${words[2]} in
|
||||
ch|channel) _hey_dispatch nix-channel ;;
|
||||
b|build) _hey_dispatch nix-build ;;
|
||||
ch|check) _hey_dispatch nix flake check ;;
|
||||
sh|show) _hey_dispatch nix flake show ;;
|
||||
s|search) _hey_dispatch nix search nixpkgs ;;
|
||||
-*) _hey_dispatch nix-env ;;
|
||||
*) _message "Command not found: ${words[2]}" ;;
|
||||
esac
|
||||
return ret
|
||||
}
|
||||
|
||||
_hey
|
84
config/zsh/config.zsh
Normal file
84
config/zsh/config.zsh
Normal file
@ -0,0 +1,84 @@
|
||||
# Stop TRAMP (in Emacs) from hanging or term/shell from echoing back commands
|
||||
if [[ $TERM == dumb || -n $INSIDE_EMACS ]]; then
|
||||
unsetopt zle prompt_cr prompt_subst
|
||||
whence -w precmd >/dev/null && unfunction precmd
|
||||
whence -w preexec >/dev/null && unfunction preexec
|
||||
PS1='$ '
|
||||
fi
|
||||
|
||||
## Plugins
|
||||
# zgen
|
||||
# we handle compinit ourselves...
|
||||
export ZGEN_AUTOLOAD_COMPINIT=0
|
||||
|
||||
# zsh-vi-mode
|
||||
export ZVM_INIT_MODE=sourcing
|
||||
export ZVM_VI_INSERT_ESCAPE_BINDKEY=jk
|
||||
|
||||
# fasd
|
||||
export _FASD_DATA="$XDG_CACHE_HOME/fasd"
|
||||
export _FASD_VIMINFO="$XDG_CACHE_HOME/viminfo"
|
||||
|
||||
# fzf
|
||||
if (( $+commands[fd] )); then
|
||||
export FZF_DEFAULT_OPTS="--reverse --ansi"
|
||||
export FZF_DEFAULT_COMMAND="fd ."
|
||||
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
|
||||
export FZF_ALT_C_COMMAND="fd -t d . $HOME"
|
||||
fi
|
||||
|
||||
|
||||
## ZSH configuration
|
||||
# Treat these characters as part of a word.
|
||||
WORDCHARS='_-*?[]~&.;!#$%^(){}<>'
|
||||
|
||||
unsetopt BRACE_CCL # Allow brace character class list expansion.
|
||||
setopt COMBINING_CHARS # Combine zero-length punc chars (accents) with base char
|
||||
setopt RC_QUOTES # Allow 'Henry''s Garage' instead of 'Henry'\''s Garage'
|
||||
setopt HASH_LIST_ALL
|
||||
unsetopt CORRECT_ALL
|
||||
unsetopt NOMATCH
|
||||
unsetopt MAIL_WARNING # Don't print a warning message if a mail file has been accessed.
|
||||
unsetopt BEEP # Hush now, quiet now.
|
||||
setopt IGNOREEOF
|
||||
|
||||
## Jobs
|
||||
setopt LONG_LIST_JOBS # List jobs in the long format by default.
|
||||
setopt AUTO_RESUME # Attempt to resume existing job before creating a new process.
|
||||
setopt NOTIFY # Report status of background jobs immediately.
|
||||
unsetopt BG_NICE # Don't run all background jobs at a lower priority.
|
||||
unsetopt HUP # Don't kill jobs on shell exit.
|
||||
unsetopt CHECK_JOBS # Don't report on jobs when shell exit.
|
||||
|
||||
## History
|
||||
HISTFILE="$XDG_CACHE_HOME/zhistory"
|
||||
HISTSIZE=100000 # Max events to store in internal history.
|
||||
SAVEHIST=100000 # Max events to store in history file.
|
||||
|
||||
setopt BANG_HIST # Don't treat '!' specially during expansion.
|
||||
setopt EXTENDED_HISTORY # Include start time in history records
|
||||
setopt APPEND_HISTORY # Appends history to history file on exit
|
||||
setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits.
|
||||
setopt SHARE_HISTORY # Share history between all sessions.
|
||||
setopt HIST_EXPIRE_DUPS_FIRST # Expire a duplicate event first when trimming history.
|
||||
setopt HIST_IGNORE_DUPS # Do not record an event that was just recorded again.
|
||||
setopt HIST_IGNORE_ALL_DUPS # Remove old events if new event is a duplicate
|
||||
setopt HIST_FIND_NO_DUPS # Do not display a previously found event.
|
||||
setopt HIST_IGNORE_SPACE # Do not record an event starting with a space.
|
||||
setopt HIST_SAVE_NO_DUPS # Do not write a duplicate event to the history file.
|
||||
setopt HIST_REDUCE_BLANKS # Minimize unnecessary whitespace
|
||||
setopt HIST_VERIFY # Do not execute immediately upon history expansion.
|
||||
setopt HIST_BEEP # Beep when accessing non-existent history.
|
||||
|
||||
## Directories
|
||||
DIRSTACKSIZE=9
|
||||
unsetopt AUTO_CD # Implicit CD slows down plugins
|
||||
setopt AUTO_PUSHD # Push the old directory onto the stack on cd.
|
||||
setopt PUSHD_IGNORE_DUPS # Do not store duplicates in the stack.
|
||||
setopt PUSHD_SILENT # Do not print the directory stack after pushd or popd.
|
||||
setopt PUSHD_TO_HOME # Push to home directory when no argument is given.
|
||||
setopt CDABLE_VARS # Change directory to a path stored in a variable.
|
||||
setopt MULTIOS # Write to multiple descriptors.
|
||||
setopt EXTENDED_GLOB # Use extended globbing syntax.
|
||||
unsetopt GLOB_DOTS
|
||||
unsetopt AUTO_NAME_DIRS # Don't add variable-stored paths to ~ list
|
65
config/zsh/keybinds.zsh
Normal file
65
config/zsh/keybinds.zsh
Normal file
@ -0,0 +1,65 @@
|
||||
# Other conveniences
|
||||
bindkey -M viins '^a' beginning-of-line
|
||||
bindkey -M viins '^d' push-line-or-edit
|
||||
|
||||
# Up arrow:
|
||||
bindkey '\e[A' history-substring-search-up
|
||||
bindkey '\eOA' history-substring-search-up
|
||||
# Down arrow:
|
||||
bindkey '\e[B' history-substring-search-down
|
||||
bindkey '\eOB' history-substring-search-down
|
||||
|
||||
# C-z to toggle current process (background/foreground)
|
||||
fancy-ctrl-z () {
|
||||
if [[ $#BUFFER -eq 0 ]]; then
|
||||
BUFFER="fg"
|
||||
zle accept-line
|
||||
else
|
||||
zle push-input
|
||||
zle clear-screen
|
||||
fi
|
||||
}
|
||||
zle -N fancy-ctrl-z
|
||||
bindkey '^Z' fancy-ctrl-z
|
||||
|
||||
if (( $+commands[fzf] )); then
|
||||
bindkey '^R' fzf-history-widget
|
||||
fi
|
||||
|
||||
# Omni-Completion
|
||||
if (( $+commands[fasd] )); then
|
||||
bindkey -M viins '^x^f' fasd-complete-f # C-x C-f to do fasd-complete-f (only files)
|
||||
bindkey -M viins '^x^d' fasd-complete-d # C-x C-d to do fasd-complete-d (only directories)
|
||||
fi
|
||||
|
||||
# Completing words in buffer in tmux
|
||||
if [ -n "$TMUX" ]; then
|
||||
_tmux_pane_words() {
|
||||
local expl
|
||||
local -a w
|
||||
if [[ -z "$TMUX_PANE" ]]; then
|
||||
_message "not running inside tmux!"
|
||||
return 1
|
||||
fi
|
||||
w=( ${(u)=$(tmux capture-pane \; show-buffer \; delete-buffer)} )
|
||||
_wanted values expl 'words from current tmux pane' compadd -a w
|
||||
}
|
||||
|
||||
zle -C tmux-pane-words-prefix complete-word _generic
|
||||
zle -C tmux-pane-words-anywhere complete-word _generic
|
||||
|
||||
bindkey -M viins '^x^n' tmux-pane-words-prefix
|
||||
bindkey -M viins '^x^o' tmux-pane-words-anywhere
|
||||
|
||||
zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' completer _tmux_pane_words
|
||||
zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' ignore-line current
|
||||
zstyle ':completion:tmux-pane-words-anywhere:*' matcher-list 'b:=* m:{A-Za-z}={a-zA-Z}'
|
||||
fi
|
||||
|
||||
# Vim's C-x C-l in zsh
|
||||
history-beginning-search-backward-then-append() {
|
||||
zle history-beginning-search-backward
|
||||
zle vi-add-eol
|
||||
}
|
||||
zle -N history-beginning-search-backward-then-append
|
||||
bindkey -M viins '^x^l' history-beginning-search-backward-then-append
|
80
default.nix
Normal file
80
default.nix
Normal file
@ -0,0 +1,80 @@
|
||||
{ inputs, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
{
|
||||
imports = [
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
] ++ (mapModulesRec' (toString ./modules) import);
|
||||
|
||||
# Common config for all nixos machines
|
||||
environment.variables = {
|
||||
DOTFILES = config.dotfiles.dir;
|
||||
DOTFILES_BIN = config.dotfiles.binDir;
|
||||
};
|
||||
|
||||
# Configure nix and nixpkgs
|
||||
environment.variables.NIXPKGS_ALLOW_UNFREE = "1";
|
||||
nix =
|
||||
let
|
||||
filteredInputs = filterAttrs (n: _: n != "self") inputs;
|
||||
nixPathInputs = mapAttrsToList (n: v: "${n}=${v}") filteredInputs;
|
||||
registryInputs = mapAttrs (_: v: { flake = v; }) filteredInputs;
|
||||
in {
|
||||
package = pkgs.nixFlakes;
|
||||
extraOptions = "experimental-features = nix-command flakes";
|
||||
nixPath = nixPathInputs ++ [
|
||||
"nixpkgs-overlays=${config.dotfiles.dir}/overlays"
|
||||
"dotfiles=${config.dotfiles.dir}"
|
||||
];
|
||||
registry = registryInputs // { dotfiles.flake = inputs.self; };
|
||||
settings = {
|
||||
substituters = [
|
||||
"https://nix-community.cachix.org"
|
||||
];
|
||||
trusted-public-keys = [
|
||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||
];
|
||||
auto-optimise-store = true;
|
||||
};
|
||||
gc = {
|
||||
automatic = mkDefault true;
|
||||
dates = mkDefault "weekly";
|
||||
options = mkDefault "--delete-older-than 14d";
|
||||
};
|
||||
};
|
||||
|
||||
system.configurationRevision = with inputs; mkIf (self ? rev) self.rev;
|
||||
system.stateVersion = "21.05";
|
||||
|
||||
## Some reasonable, global defaults
|
||||
# This is here to appease 'nix flake check' for generic hosts with no
|
||||
# hardware-configuration.nix or fileSystem config.
|
||||
fileSystems."/".device = mkDefault "/dev/disk/by-label/nixos";
|
||||
|
||||
# The global useDHCP flag is deprecated, therefore explicitly set to false
|
||||
# here. Per-interface useDHCP will be mandatory in the future, so we enforce
|
||||
# this default behavior here.
|
||||
networking.useDHCP = mkDefault false;
|
||||
|
||||
# Use the latest kernel
|
||||
boot = {
|
||||
kernelPackages = mkDefault pkgs.linuxPackages_latest;
|
||||
loader = {
|
||||
efi.canTouchEfiVariables = mkDefault true;
|
||||
systemd-boot.configurationLimit = 10;
|
||||
systemd-boot.enable = mkDefault true;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
bind
|
||||
cached-nix-shell
|
||||
coreutils
|
||||
git
|
||||
vim
|
||||
wget
|
||||
curl
|
||||
gnumake
|
||||
unzip
|
||||
];
|
||||
}
|
70
flake.nix
Normal file
70
flake.nix
Normal file
@ -0,0 +1,70 @@
|
||||
{
|
||||
description = "Who said nix-nix? It's a dotfiles!";
|
||||
|
||||
inputs = {
|
||||
# Core dependencies.
|
||||
nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||
nixpkgs-unstable.url = "nixpkgs/nixpkgs-unstable";
|
||||
home-manager = {
|
||||
url = "github:rycee/home-manager/master";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
nur = {
|
||||
url = "github:nix-community/NUR";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# Extras
|
||||
emacs-overlay.url = "github:nix-community/emacs-overlay";
|
||||
nixos-hardware.url = "github:nixos/nixos-hardware";
|
||||
devenv.url = "github:cachix/devenv/v0.6.2";
|
||||
};
|
||||
|
||||
outputs = inputs @ {
|
||||
self, nixpkgs, nixpkgs-unstable, nur,
|
||||
emacs-overlay, nixos-hardware, devenv,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (builtins) baseNameOf;
|
||||
inherit (lib) nixosSystem mkIf removeSuffix attrNames attrValues;
|
||||
inherit (lib.custom) mapModules mapModulesRec mapHosts;
|
||||
|
||||
system = "x86_64-linux";
|
||||
|
||||
lib = nixpkgs.lib.extend (self: super: {
|
||||
custom = import ./lib {
|
||||
inherit pkgs inputs; lib = self;
|
||||
};
|
||||
});
|
||||
|
||||
mkPkgs = pkgs: extraOverlays: import pkgs {
|
||||
inherit system;
|
||||
config.allowUnfree = true;
|
||||
overlays = extraOverlays ++ (lib.attrValues self.overlays);
|
||||
};
|
||||
|
||||
pkgs = mkPkgs nixpkgs [ self.overlay ];
|
||||
unstable = mkPkgs nixpkgs-unstable [];
|
||||
|
||||
in {
|
||||
lib = lib.custom;
|
||||
|
||||
overlay = final: prev: {
|
||||
inherit unstable;
|
||||
user = self.packages.${system};
|
||||
devenv = devenv.packages.${system}.devenv;
|
||||
};
|
||||
|
||||
overlays = mapModules ./overlays import;
|
||||
|
||||
packages.${system} = mapModules ./packages (p: pkgs.callPackage p {});
|
||||
|
||||
nixosModules = { dotfiles = import ./.; } // mapModulesRec ./modules import;
|
||||
|
||||
nixosConfigurations = mapHosts ./hosts { inherit system; };
|
||||
|
||||
devShell.${system} = import ./shell.nix { inherit pkgs; };
|
||||
|
||||
};
|
||||
}
|
32
hosts/common.nix
Normal file
32
hosts/common.nix
Normal file
@ -0,0 +1,32 @@
|
||||
{ config, lib, ... }:
|
||||
with builtins;
|
||||
with lib;
|
||||
let
|
||||
blocklist = fetchurl https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts;
|
||||
in {
|
||||
networking.extraHosts = ''
|
||||
192.168.156.1 router.home
|
||||
|
||||
# Hosts
|
||||
192.168.1156.28 elnafo.home
|
||||
|
||||
# Block garbage
|
||||
${optionalString config.services.xserver.enable (readFile blocklist)}
|
||||
'';
|
||||
|
||||
## Location config -- since Toronto is my 127.0.0.1
|
||||
time.timeZone = mkDefault "Asia/Yekaterinburg";
|
||||
|
||||
i18n.defaultLocale = mkDefault "en_US.UTF-8";
|
||||
i18n.extraLocaleSettings = {
|
||||
LC_ADDRESS = "en_US.UTF-8";
|
||||
LC_IDENTIFICATION = "en_US.UTF-8";
|
||||
LC_MEASUREMENT = "en_US.UTF-8";
|
||||
LC_MONETARY = "en_US.UTF-8";
|
||||
LC_NAME = "en_US.UTF-8";
|
||||
LC_NUMERIC = "en_US.UTF-8";
|
||||
LC_PAPER = "en_US.UTF-8";
|
||||
LC_TELEPHONE = "en_US.UTF-8";
|
||||
LC_TIME = "en_US.UTF-8";
|
||||
};
|
||||
}
|
78
hosts/elnafo/default.nix
Normal file
78
hosts/elnafo/default.nix
Normal file
@ -0,0 +1,78 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
imports = [
|
||||
../common.nix
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
## Modules
|
||||
modules = {
|
||||
desktop = {
|
||||
gnome.enable = true;
|
||||
audio.enable = true;
|
||||
browsers = {
|
||||
default = "firefox";
|
||||
firefox.enable = true;
|
||||
};
|
||||
gaming = {
|
||||
steam.enable = true;
|
||||
};
|
||||
graphics.enable = true;
|
||||
media = {
|
||||
recording.enable = true;
|
||||
};
|
||||
term = {
|
||||
default = "kgx";
|
||||
};
|
||||
vm = {
|
||||
qemu.enable = true;
|
||||
};
|
||||
};
|
||||
dev = {
|
||||
cc.enable = true;
|
||||
rust.enable = true;
|
||||
python.enable = true;
|
||||
};
|
||||
editors = {
|
||||
default = "nvim";
|
||||
emacs.enable = true;
|
||||
vim.enable = true;
|
||||
};
|
||||
shell = {
|
||||
direnv.enable = true;
|
||||
git.enable = true;
|
||||
gnupg.enable = true;
|
||||
tmux.enable = true;
|
||||
zsh.enable = true;
|
||||
};
|
||||
services = {
|
||||
ssh.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
networking = {
|
||||
networkmanager.enable = true;
|
||||
useDHCP = lib.mkDefault true;
|
||||
firewall.enable = true;
|
||||
};
|
||||
|
||||
## Local config
|
||||
programs = {
|
||||
dconf.enable = true;
|
||||
ssh.startAgent = true;
|
||||
};
|
||||
|
||||
## Services
|
||||
services.printing.enable = true;
|
||||
|
||||
services.xserver = {
|
||||
layout = "us";
|
||||
xkbVariant = "";
|
||||
videoDrivers = [ "nvidia" ];
|
||||
};
|
||||
|
||||
services.openssh.startWhenNeeded = true;
|
||||
|
||||
|
||||
system.stateVersion = "22.11";
|
||||
}
|
90
hosts/elnafo/hardware-configuration.nix
Normal file
90
hosts/elnafo/hardware-configuration.nix
Normal file
@ -0,0 +1,90 @@
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
{
|
||||
imports = [ "${modulesPath}/installer/scan/not-detected.nix" ];
|
||||
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
|
||||
kernelModules = [];
|
||||
};
|
||||
extraModulePackages = [];
|
||||
kernelModules = [ "kvm-amd" "coretemp" ];
|
||||
kernelParams = [];
|
||||
kernelPackages = pkgs.linuxPackages_latest;
|
||||
|
||||
# Refuse ICMP echo requests on my desktop/laptop; nobody has any business
|
||||
# pinging them, unlike my servers.
|
||||
kernel.sysctl."net.ipv4.icmp_echo_ignore_broadcasts" = 1;
|
||||
|
||||
loader = {
|
||||
systemd-boot.enable = false;
|
||||
efi = {
|
||||
canTouchEfiVariables = true;
|
||||
efiSysMountPoint = "/boot/efi";
|
||||
};
|
||||
grub = {
|
||||
devices = [ "nodev" ];
|
||||
enable = true;
|
||||
efiSupport = true;
|
||||
# version = 2;
|
||||
useOSProber = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Modules
|
||||
modules.hardware = {
|
||||
audio.enable = true;
|
||||
fs = {
|
||||
enable = true;
|
||||
ssd.enable = true;
|
||||
};
|
||||
nvidia.enable = true;
|
||||
sensors.enable = true;
|
||||
};
|
||||
|
||||
# CPU
|
||||
#nix.settings.max-jobs = lib.mkDefault 16;
|
||||
#powerManagement.cpuFreqGovernor = "performance";
|
||||
hardware.cpu.amd.updateMicrocode = true;
|
||||
|
||||
# Nvidia, OpenGL
|
||||
hardware = {
|
||||
nvidia.nvidiaSettings = true;
|
||||
nvidia.modesetting.enable = true;
|
||||
|
||||
opengl.enable = true;
|
||||
opengl.driSupport32Bit = true;
|
||||
};
|
||||
|
||||
# Storage
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/d53d2bcd-36c7-4273-b5b4-6563692ee16c";
|
||||
fsType = "ext4";
|
||||
options = [ "noatime" ];
|
||||
};
|
||||
|
||||
"/boot/efi" = {
|
||||
device = "/dev/disk/by-uuid/3117-8F91";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
"/home" = {
|
||||
device = "/dev/disk/by-uuid/b9e2a42a-4db9-4389-bf75-457bb4da2a30";
|
||||
fsType = "ext4";
|
||||
options = [ "noatime" ];
|
||||
};
|
||||
|
||||
"/mnt/vault" = {
|
||||
device = "/dev/disk/by-uuid/34cbaf1c-19c7-412f-8b51-41410f3fee2a";
|
||||
fsType = "btrfs";
|
||||
options = [
|
||||
"nofail" "noauto" "noatime" "x-systemd.automount" "x-systemd.idle-timeout=5min"
|
||||
"nodev" "nosuid" "noexec"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [];
|
||||
}
|
21
hosts/niximg.nix
Normal file
21
hosts/niximg.nix
Normal file
@ -0,0 +1,21 @@
|
||||
{ modulesPath, pkgs, config, ... }:
|
||||
{
|
||||
imports = [
|
||||
"${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
|
||||
];
|
||||
|
||||
# In case of proprietary wireless drivers
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
boot.kernelPackages = pkgs.linuxKernel.packages.linux_5_16;
|
||||
boot.kernelModules = [ "wl" ];
|
||||
boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
nixFlakes
|
||||
zsh
|
||||
git
|
||||
];
|
||||
}
|
||||
|
||||
# nix-build '<nixpkgs/nixos>' -A config.system.build.isoImage -I nixos-config=./default.nix
|
22
lib/attrs.nix
Normal file
22
lib/attrs.nix
Normal file
@ -0,0 +1,22 @@
|
||||
{ lib, ... }:
|
||||
with builtins;
|
||||
with lib;
|
||||
rec {
|
||||
# attrsToList
|
||||
attrsToList = attrs: mapAttrsToList (name: value: { inherit name value; }) attrs;
|
||||
|
||||
# mapFilterAttrs ::
|
||||
# (name -> value -> bool)
|
||||
# (name -> value -> { name = any; value = any; })
|
||||
# attrs
|
||||
mapFilterAttrs = pred: f: attrs: filterAttrs pred (mapAttrs' f attrs);
|
||||
|
||||
# Generate an attribute set by mapping a function over a list of values.
|
||||
genAttrs' = values: f: listToAttrs (map f values);
|
||||
|
||||
# anyAttrs :: (name -> value -> bool) attrs
|
||||
anyAttrs = pred: attrs: any (attr: pred attr.name attr.value) (attrsToList attrs);
|
||||
|
||||
# countAttrs :: (name -> value -> bool) attrs
|
||||
countAttrs = pred: attrs: count (attr: pred attr.name attr.value) (attrsToList attrs);
|
||||
}
|
15
lib/default.nix
Normal file
15
lib/default.nix
Normal file
@ -0,0 +1,15 @@
|
||||
{ inputs, lib, pkgs, ... }:
|
||||
let
|
||||
inherit (lib) makeExtensible attrValues foldr;
|
||||
inherit (modules) mapModules;
|
||||
|
||||
modules = import ./modules.nix {
|
||||
inherit lib;
|
||||
self.attrs = import ./attrs.nix { inherit lib; self = {}; };
|
||||
};
|
||||
|
||||
customlib = makeExtensible (self: with self;
|
||||
mapModules ./. (file: import file { inherit self lib pkgs inputs; })
|
||||
);
|
||||
in
|
||||
customlib.extend (self: super: foldr (a: b: a // b) {} (attrValues super))
|
52
lib/modules.nix
Normal file
52
lib/modules.nix
Normal file
@ -0,0 +1,52 @@
|
||||
{ self, lib, ... }:
|
||||
let
|
||||
inherit (builtins) attrValues readDir pathExists concatLists;
|
||||
inherit (lib) id mapAttrsToList filterAttrs hasPrefix hasSuffix nameValuePair removeSuffix;
|
||||
inherit (self.attrs) mapFilterAttrs;
|
||||
in
|
||||
rec {
|
||||
mapModules = dir: fn:
|
||||
mapFilterAttrs
|
||||
(n: v: v != null && !(hasPrefix "_" n))
|
||||
(n: v:
|
||||
let
|
||||
path = "${toString dir}/${n}";
|
||||
in
|
||||
if v == "directory" && pathExists "${path}/default.nix"
|
||||
then nameValuePair n (fn path)
|
||||
else
|
||||
if v == "regular" && n != "default.nix" && hasSuffix ".nix" n
|
||||
then nameValuePair (removeSuffix ".nix" n) (fn path)
|
||||
else nameValuePair "" null
|
||||
)
|
||||
(readDir dir);
|
||||
|
||||
mapModules' = dir: fn: attrValues (mapModules dir fn);
|
||||
|
||||
mapModulesRec = dir: fn:
|
||||
mapFilterAttrs
|
||||
(n: v: v != null && !(hasPrefix "_" n))
|
||||
(n: v:
|
||||
let
|
||||
path = "${toString dir}/${n}";
|
||||
in
|
||||
if v == "directory"
|
||||
then nameValuePair n (mapModulesRec path fn)
|
||||
else
|
||||
if v == "regular" && n != "default.nix" && hasSuffix ".nix" n
|
||||
then nameValuePair (removeSuffix ".nix" n) (fn path)
|
||||
else nameValuePair "" null
|
||||
)
|
||||
(readDir dir);
|
||||
|
||||
mapModulesRec' = dir: fn:
|
||||
let
|
||||
dirs = mapAttrsToList
|
||||
(k: _: "${dir}/${k}")
|
||||
(filterAttrs (n: v: v == "directory" && !(hasPrefix "_" n))
|
||||
(readDir dir));
|
||||
files = attrValues (mapModules dir id);
|
||||
paths = files ++ concatLists (map (d: mapModulesRec' d id) dirs);
|
||||
in
|
||||
map fn paths;
|
||||
}
|
23
lib/nixos.nix
Normal file
23
lib/nixos.nix
Normal file
@ -0,0 +1,23 @@
|
||||
{ inputs, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
sys = "x86_64-linux";
|
||||
in {
|
||||
mkHost = path: attrs @ { system ? sys, ... }:
|
||||
nixosSystem {
|
||||
inherit system;
|
||||
specialArgs = { inherit lib inputs system; };
|
||||
modules = [
|
||||
{
|
||||
nixpkgs.pkgs = pkgs;
|
||||
networking.hostName = mkDefault (removeSuffix ".nix" (baseNameOf path));
|
||||
}
|
||||
(filterAttrs (n: v: !elem n [ "system" ]) attrs)
|
||||
../. # /default.nix
|
||||
(import path)
|
||||
];
|
||||
};
|
||||
|
||||
mapHosts = dir: attrs @ { system ? system, ... }: mapModules dir (hostPath: mkHost hostPath attrs);
|
||||
}
|
15
lib/options.nix
Normal file
15
lib/options.nix
Normal file
@ -0,0 +1,15 @@
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
in
|
||||
rec {
|
||||
mkOpt = type: default: mkOption { inherit type default; };
|
||||
|
||||
mkOpt' = type: default: description: mkOption { inherit type default description; };
|
||||
|
||||
mkBoolOpt = default: mkOption {
|
||||
inherit default;
|
||||
type = types.bool;
|
||||
example = true;
|
||||
};
|
||||
}
|
16
modules/desktop/apps/godot.nix
Normal file
16
modules/desktop/apps/godot.nix
Normal file
@ -0,0 +1,16 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.apps.godot;
|
||||
in {
|
||||
options.modules.desktop.apps.godot = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
godot
|
||||
];
|
||||
};
|
||||
}
|
19
modules/desktop/audio/default.nix
Normal file
19
modules/desktop/audio/default.nix
Normal file
@ -0,0 +1,19 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.audio;
|
||||
in {
|
||||
options.modules.desktop.audio = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
lollypop
|
||||
vlc
|
||||
beets
|
||||
flacon
|
||||
];
|
||||
};
|
||||
}
|
14
modules/desktop/browsers/default.nix
Normal file
14
modules/desktop/browsers/default.nix
Normal file
@ -0,0 +1,14 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.browsers;
|
||||
in {
|
||||
options.modules.desktop.browsers = {
|
||||
default = mkOpt (with types; nullOr str) null;
|
||||
};
|
||||
|
||||
config = mkIf (cfg.default != null) {
|
||||
env.BROWSER = cfg.default;
|
||||
};
|
||||
}
|
226
modules/desktop/browsers/firefox.nix
Normal file
226
modules/desktop/browsers/firefox.nix
Normal file
@ -0,0 +1,226 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.browsers.firefox;
|
||||
in {
|
||||
options.modules.desktop.browsers.firefox = with types; {
|
||||
enable = mkBoolOpt false;
|
||||
profileName = mkOpt types.str config.user.name;
|
||||
|
||||
settings = mkOpt' (attrsOf (oneOf [ bool int str ])) {} ''
|
||||
Firefox preferences to set in <filename>user.js</filename>
|
||||
'';
|
||||
extraConfig = mkOpt' lines "" ''
|
||||
Extra lines to add to <filename>user.js</filename>
|
||||
'';
|
||||
|
||||
userChrome = mkOpt' lines "" "CSS Styles for Firefox's interface";
|
||||
userContent = mkOpt' lines "" "Global CSS Styles for websites";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [ {
|
||||
user.packages = with pkgs; [
|
||||
# firefox-wayland
|
||||
unstable.firefox-bin
|
||||
(makeDesktopItem {
|
||||
name = "firefox-private";
|
||||
desktopName = "Firefox (Private)";
|
||||
genericName = "Open a private Firefox window";
|
||||
icon = "firefox";
|
||||
exec = "${unstable.firefox-bin}/bin/firefox --private-window";
|
||||
categories = [ "Network" ];
|
||||
})
|
||||
];
|
||||
|
||||
# Prevent auto-creation of ~/Desktop. The trailing slash is necessary; see
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1082717
|
||||
env.XDG_DESKTOP_DIR = "$HOME/";
|
||||
|
||||
modules.desktop.browsers.firefox.settings = {
|
||||
# Default to dark theme in DevTools panel
|
||||
"devtools.theme" = "dark";
|
||||
# Enable ETP for decent security (makes firefox containers and many
|
||||
# common security/privacy add-ons redundant).
|
||||
"browser.contentblocking.category" = "strict";
|
||||
"privacy.donottrackheader.enabled" = true;
|
||||
"privacy.donottrackheader.value" = 1;
|
||||
"privacy.purge_trackers.enabled" = true;
|
||||
# Your customized toolbar settings are stored in
|
||||
# 'browser.uiCustomization.state'. This tells firefox to sync it between
|
||||
# machines. WARNING: This may not work across OSes. Since I use NixOS on
|
||||
# all the machines I use Firefox on, this is no concern to me.
|
||||
"services.sync.prefs.sync.browser.uiCustomization.state" = true;
|
||||
# Enable userContent.css and userChrome.css for our theme modules
|
||||
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
|
||||
# Stop creating ~/Downloads!
|
||||
"browser.download.dir" = "${config.user.home}/downloads";
|
||||
# Don't use the built-in password manager. A nixos user is more likely
|
||||
# using an external one (you are using one, right?).
|
||||
"signon.rememberSignons" = false;
|
||||
# Do not check if Firefox is the default browser
|
||||
"browser.shell.checkDefaultBrowser" = false;
|
||||
# Disable the "new tab page" feature and show a blank tab instead
|
||||
# https://wiki.mozilla.org/Privacy/Reviews/New_Tab
|
||||
# https://support.mozilla.org/en-US/kb/new-tab-page-show-hide-and-customize-top-sites#w_how-do-i-turn-the-new-tab-page-off
|
||||
"browser.newtabpage.enabled" = false;
|
||||
"browser.newtab.url" = "about:blank";
|
||||
# Disable Activity Stream
|
||||
# https://wiki.mozilla.org/Firefox/Activity_Stream
|
||||
"browser.newtabpage.activity-stream.enabled" = false;
|
||||
"browser.newtabpage.activity-stream.telemetry" = false;
|
||||
# Disable new tab tile ads & preload
|
||||
# http://www.thewindowsclub.com/disable-remove-ad-tiles-from-firefox
|
||||
# http://forums.mozillazine.org/viewtopic.php?p=13876331#p13876331
|
||||
# https://wiki.mozilla.org/Tiles/Technical_Documentation#Ping
|
||||
# https://gecko.readthedocs.org/en/latest/browser/browser/DirectoryLinksProvider.html#browser-newtabpage-directory-source
|
||||
# https://gecko.readthedocs.org/en/latest/browser/browser/DirectoryLinksProvider.html#browser-newtabpage-directory-ping
|
||||
"browser.newtabpage.enhanced" = false;
|
||||
"browser.newtabpage.introShown" = true;
|
||||
"browser.newtab.preload" = false;
|
||||
"browser.newtabpage.directory.ping" = "";
|
||||
"browser.newtabpage.directory.source" = "data:text/plain,{}";
|
||||
# Reduce search engine noise in the urlbar's completion window. The
|
||||
# shortcuts and suggestions will still work, but Firefox won't clutter
|
||||
# its UI with reminders that they exist.
|
||||
"browser.urlbar.suggest.searches" = false;
|
||||
"browser.urlbar.shortcuts.bookmarks" = false;
|
||||
"browser.urlbar.shortcuts.history" = false;
|
||||
"browser.urlbar.shortcuts.tabs" = false;
|
||||
"browser.urlbar.showSearchSuggestionsFirst" = false;
|
||||
"browser.urlbar.speculativeConnect.enabled" = false;
|
||||
# https://bugzilla.mozilla.org/1642623
|
||||
"browser.urlbar.dnsResolveSingleWordsAfterSearch" = 0;
|
||||
# https://blog.mozilla.org/data/2021/09/15/data-and-firefox-suggest/
|
||||
"browser.urlbar.suggest.quicksuggest.nonsponsored" = false;
|
||||
"browser.urlbar.suggest.quicksuggest.sponsored" = false;
|
||||
# Show whole URL in address bar
|
||||
"browser.urlbar.trimURLs" = false;
|
||||
# Disable some not so useful functionality.
|
||||
"browser.disableResetPrompt" = true; # "Looks like you haven't started Firefox in a while."
|
||||
"browser.onboarding.enabled" = false; # "New to Firefox? Let's get started!" tour
|
||||
"browser.aboutConfig.showWarning" = false; # Warning when opening about:config
|
||||
"media.videocontrols.picture-in-picture.video-toggle.enabled" = false;
|
||||
"extensions.pocket.enabled" = false;
|
||||
"extensions.shield-recipe-client.enabled" = false;
|
||||
"reader.parse-on-load.enabled" = false; # "reader view"
|
||||
|
||||
# Security-oriented defaults
|
||||
"security.family_safety.mode" = 0;
|
||||
# https://blog.mozilla.org/security/2016/10/18/phasing-out-sha-1-on-the-public-web/
|
||||
"security.pki.sha1_enforcement_level" = 1;
|
||||
# https://github.com/tlswg/tls13-spec/issues/1001
|
||||
"security.tls.enable_0rtt_data" = false;
|
||||
# Use Mozilla geolocation service instead of Google if given permission
|
||||
"geo.provider.network.url" = "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%";
|
||||
"geo.provider.use_gpsd" = false;
|
||||
# https://support.mozilla.org/en-US/kb/extension-recommendations
|
||||
"browser.newtabpage.activity-stream.asrouter.userprefs.cfr" = false;
|
||||
"browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons" = false;
|
||||
"browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features" = false;
|
||||
"extensions.htmlaboutaddons.recommendations.enabled" = false;
|
||||
"extensions.htmlaboutaddons.discover.enabled" = false;
|
||||
"extensions.getAddons.showPane" = false; # uses Google Analytics
|
||||
"browser.discovery.enabled" = false;
|
||||
# Reduce File IO / SSD abuse
|
||||
# Otherwise, Firefox bombards the HD with writes. Not so nice for SSDs.
|
||||
# This forces it to write every 30 minutes, rather than 15 seconds.
|
||||
"browser.sessionstore.interval" = "1800000";
|
||||
# Disable battery API
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/BatteryManager
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1313580
|
||||
"dom.battery.enabled" = false;
|
||||
# Disable "beacon" asynchronous HTTP transfers (used for analytics)
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/navigator.sendBeacon
|
||||
"beacon.enabled" = false;
|
||||
# Disable pinging URIs specified in HTML <a> ping= attributes
|
||||
# http://kb.mozillazine.org/Browser.send_pings
|
||||
"browser.send_pings" = false;
|
||||
# Disable gamepad API to prevent USB device enumeration
|
||||
# https://www.w3.org/TR/gamepad/
|
||||
# https://trac.torproject.org/projects/tor/ticket/13023
|
||||
"dom.gamepad.enabled" = false;
|
||||
# Don't try to guess domain names when entering an invalid domain name in URL bar
|
||||
# http://www-archive.mozilla.org/docs/end-user/domain-guessing.html
|
||||
"browser.fixup.alternate.enabled" = false;
|
||||
# Disable telemetry
|
||||
# https://wiki.mozilla.org/Platform/Features/Telemetry
|
||||
# https://wiki.mozilla.org/Privacy/Reviews/Telemetry
|
||||
# https://wiki.mozilla.org/Telemetry
|
||||
# https://www.mozilla.org/en-US/legal/privacy/firefox.html#telemetry
|
||||
# https://support.mozilla.org/t5/Firefox-crashes/Mozilla-Crash-Reporter/ta-p/1715
|
||||
# https://wiki.mozilla.org/Security/Reviews/Firefox6/ReviewNotes/telemetry
|
||||
# https://gecko.readthedocs.io/en/latest/browser/experiments/experiments/manifest.html
|
||||
# https://wiki.mozilla.org/Telemetry/Experiments
|
||||
# https://support.mozilla.org/en-US/questions/1197144
|
||||
# https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/internals/preferences.html#id1
|
||||
"toolkit.telemetry.unified" = false;
|
||||
"toolkit.telemetry.enabled" = false;
|
||||
"toolkit.telemetry.server" = "data:,";
|
||||
"toolkit.telemetry.archive.enabled" = false;
|
||||
"toolkit.telemetry.coverage.opt-out" = true;
|
||||
"toolkit.coverage.opt-out" = true;
|
||||
"toolkit.coverage.endpoint.base" = "";
|
||||
"experiments.supported" = false;
|
||||
"experiments.enabled" = false;
|
||||
"experiments.manifest.uri" = "";
|
||||
"browser.ping-centre.telemetry" = false;
|
||||
# https://mozilla.github.io/normandy/
|
||||
"app.normandy.enabled" = false;
|
||||
"app.normandy.api_url" = "";
|
||||
"app.shield.optoutstudies.enabled" = false;
|
||||
# Disable health reports (basically more telemetry)
|
||||
# https://support.mozilla.org/en-US/kb/firefox-health-report-understand-your-browser-perf
|
||||
# https://gecko.readthedocs.org/en/latest/toolkit/components/telemetry/telemetry/preferences.html
|
||||
"datareporting.healthreport.uploadEnabled" = false;
|
||||
"datareporting.healthreport.service.enabled" = false;
|
||||
"datareporting.policy.dataSubmissionEnabled" = false;
|
||||
|
||||
# Disable crash reports
|
||||
"breakpad.reportURL" = "";
|
||||
"browser.tabs.crashReporting.sendReport" = false;
|
||||
"browser.crashReports.unsubmittedCheck.autoSubmit2" = false; # don't submit backlogged reports
|
||||
|
||||
# Disable Form autofill
|
||||
# https://wiki.mozilla.org/Firefox/Features/Form_Autofill
|
||||
"browser.formfill.enable" = false;
|
||||
"extensions.formautofill.addresses.enabled" = false;
|
||||
"extensions.formautofill.available" = "off";
|
||||
"extensions.formautofill.creditCards.available" = false;
|
||||
"extensions.formautofill.creditCards.enabled" = false;
|
||||
"extensions.formautofill.heuristics.enabled" = false;
|
||||
};
|
||||
|
||||
# Use a stable profile name so we can target it in themes
|
||||
home.file = let cfgPath = ".mozilla/firefox"; in {
|
||||
"${cfgPath}/profiles.ini".text = ''
|
||||
[Profile0]
|
||||
Name=default
|
||||
IsRelative=1
|
||||
Path=${cfg.profileName}.default
|
||||
Default=1
|
||||
|
||||
[General]
|
||||
StartWithLastProfile=1
|
||||
Version=2
|
||||
'';
|
||||
|
||||
"${cfgPath}/${cfg.profileName}.default/user.js" = mkIf (cfg.settings != {} || cfg.extraConfig != "") {
|
||||
text = ''
|
||||
${concatStrings (mapAttrsToList (name: value: ''
|
||||
user_pref("${name}", ${builtins.toJSON value});
|
||||
'') cfg.settings)}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
"${cfgPath}/${cfg.profileName}.default/chrome/userChrome.css" = mkIf (cfg.userChrome != "") {
|
||||
text = cfg.userChrome;
|
||||
};
|
||||
|
||||
"${cfgPath}/${cfg.profileName}.default/chrome/userContent.css" = mkIf (cfg.userContent != "") {
|
||||
text = cfg.userContent;
|
||||
};
|
||||
};
|
||||
}]);
|
||||
}
|
62
modules/desktop/default.nix
Normal file
62
modules/desktop/default.nix
Normal file
@ -0,0 +1,62 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop;
|
||||
in {
|
||||
config = mkIf config.services.xserver.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = (countAttrs (n: v: n == "enable" && value) cfg) < 2;
|
||||
message = "Can't have more than one desktop environment enabled at a time";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
let
|
||||
srv = config.services;
|
||||
in
|
||||
srv.xserver.enable || srv.sway.enable ||
|
||||
!(anyAttrs (n: v: isAttrs v && anyAttrs (n: v: isAttrs v && v.enable)) cfg);
|
||||
message = "Can't enable a desktop app without a desktop environment";
|
||||
}
|
||||
];
|
||||
|
||||
user.packages = with pkgs; [
|
||||
xclip
|
||||
xdotool
|
||||
qgnomeplatform # QPlatformTheme for a better Qt application inclusion in GNOME
|
||||
libsForQt5.qtstyleplugin-kvantum # SVG-based Qt5 theme engine plus a config tool and extra theme
|
||||
];
|
||||
|
||||
fonts = {
|
||||
fontDir.enable = true;
|
||||
enableGhostscriptFonts = true;
|
||||
fonts = with pkgs; [
|
||||
ubuntu_font_family
|
||||
dejavu_fonts
|
||||
symbola
|
||||
nerdfonts
|
||||
];
|
||||
};
|
||||
|
||||
# Try really hard to get QT to respect my GTK theme.
|
||||
env = {
|
||||
GTK_DATA_PREFIX = [ "${config.system.path}" ];
|
||||
QT_QPA_PLATFORMTHEME = "gnome";
|
||||
QT_STYLE_OVERRIDE = "kvantum";
|
||||
}
|
||||
|
||||
services.xserver.displayManager.sessionCommands = ''
|
||||
# GTK2_RC_FILES must be available to the display manager.
|
||||
export GTK2_RC_FILES="$XDG_CONFIG_HOME/gtk-2.0/gtkrc"
|
||||
'';
|
||||
|
||||
# Clean up leftovers, as much as we can
|
||||
system.userActivationScripts.cleanupHome = ''
|
||||
pushd "${config.user.home}"
|
||||
rm -rf .compose-cache .nv .pki .dbus .fehbg
|
||||
[ -s .xsession-errors ] || rm -f .xsession-errors*
|
||||
popd
|
||||
'';
|
||||
};
|
||||
}
|
17
modules/desktop/documents/default.nix
Normal file
17
modules/desktop/documents/default.nix
Normal file
@ -0,0 +1,17 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.documents;
|
||||
in {
|
||||
options.modules.desktop.documents = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
onlyoffice-bin
|
||||
tectonic
|
||||
];
|
||||
};
|
||||
}
|
19
modules/desktop/gaming/lutris.nix
Normal file
19
modules/desktop/gaming/lutris.nix
Normal file
@ -0,0 +1,19 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.gaming.lutris;
|
||||
in {
|
||||
options.modules.desktop.gaming.lutris = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
lutris
|
||||
wine
|
||||
winetricks
|
||||
gamemode
|
||||
];
|
||||
};
|
||||
}
|
17
modules/desktop/gaming/steam.nix
Normal file
17
modules/desktop/gaming/steam.nix
Normal file
@ -0,0 +1,17 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.gaming.steam;
|
||||
in {
|
||||
options.modules.desktop.gaming.steam = with types; {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
programs.steam.enable = true;
|
||||
|
||||
# better for steam proton games
|
||||
systemd.extraConfig = "DefaultLimitNOFILE=1048576";
|
||||
};
|
||||
}
|
25
modules/desktop/gnome.nix
Normal file
25
modules/desktop/gnome.nix
Normal file
@ -0,0 +1,25 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with builtins;
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.gnome;
|
||||
in {
|
||||
options.modules.desktop.gnome = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [
|
||||
gnomeExtensions.containers
|
||||
gnomeExtensions.tray-icons-reloaded
|
||||
];
|
||||
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
displayManager.gdm.enable = true;
|
||||
desktopManager.gnome.enable = true;
|
||||
};
|
||||
|
||||
};
|
||||
}
|
50
modules/desktop/graphics/default.nix
Normal file
50
modules/desktop/graphics/default.nix
Normal file
@ -0,0 +1,50 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.media.graphics;
|
||||
configDir = config.dotfiles.configDir;
|
||||
in {
|
||||
options.modules.desktop.media.graphics = {
|
||||
enable = mkBoolOpt false;
|
||||
tools.enable = mkBoolOpt true;
|
||||
raster.enable = mkBoolOpt true;
|
||||
vector.enable = mkBoolOpt true;
|
||||
sprites.enable = mkBoolOpt false;
|
||||
models.enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = with pkgs;
|
||||
(if cfg.tools.enable then [
|
||||
font-manager
|
||||
imagemagick
|
||||
] else []) ++
|
||||
|
||||
# replaces illustrator & indesign
|
||||
(if cfg.vector.enable then [
|
||||
unstable.inkscape
|
||||
] else []) ++
|
||||
|
||||
# Replaces photoshop
|
||||
(if cfg.raster.enable then [
|
||||
krita
|
||||
gimp
|
||||
gimpPlugins.resynthesizer # content-aware scaling in gimp
|
||||
] else []) ++
|
||||
|
||||
# Sprite sheets & animation
|
||||
(if cfg.sprites.enable then [
|
||||
aseprite-unfree
|
||||
] else []) ++
|
||||
|
||||
# 3D modelling
|
||||
(if cfg.models.enable then [
|
||||
unstable.blender-hip
|
||||
] else []);
|
||||
|
||||
home.configFile = mkIf cfg.raster.enable {
|
||||
"GIMP/2.10" = { source = "${configDir}/gimp"; recursive = true; };
|
||||
};
|
||||
};
|
||||
}
|
27
modules/desktop/media/recording.nix
Normal file
27
modules/desktop/media/recording.nix
Normal file
@ -0,0 +1,27 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.media.recording;
|
||||
in {
|
||||
options.modules.desktop.media.recording = {
|
||||
enable = mkBoolOpt false;
|
||||
audio.enable = mkBoolOpt true;
|
||||
video.enable = mkBoolOpt true;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.pipewire.jack.enable = true;
|
||||
|
||||
user.packages = with pkgs;
|
||||
(if cfg.audio.enable then [
|
||||
unstable.audacity-gtk3
|
||||
] else []) ++
|
||||
|
||||
(if cfg.video.enable then [
|
||||
unstable.obs-studio
|
||||
unstable.handbrake
|
||||
ffmpeg
|
||||
] else []);
|
||||
};
|
||||
}
|
16
modules/desktop/term/default.nix
Normal file
16
modules/desktop/term/default.nix
Normal file
@ -0,0 +1,16 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.term;
|
||||
in {
|
||||
options.modules.desktop.term = {
|
||||
default = mkOpt types.str "xterm";
|
||||
};
|
||||
|
||||
config = {
|
||||
services.xserver.desktopManager.xterm.enable = mkDefault (cfg.default == "xterm");
|
||||
|
||||
env.TERMINAL = cfg.default;
|
||||
};
|
||||
}
|
21
modules/desktop/vm/qemu.nix
Normal file
21
modules/desktop/vm/qemu.nix
Normal file
@ -0,0 +1,21 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.desktop.vm.qemu;
|
||||
in {
|
||||
options.modules.desktop.vm.qemu = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [
|
||||
qemu
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
# Creating an image:
|
||||
# qemu-img create -f qcow2 disk.img
|
||||
# Creating a snapshot (don't tamper with disk.img):
|
||||
# qemu-img create -f qcow2 -b disk.img snapshot.img
|
29
modules/dev/cc.nix
Normal file
29
modules/dev/cc.nix
Normal file
@ -0,0 +1,29 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
devCfg = config.modules.dev;
|
||||
cfg = devCfg.cc;
|
||||
in {
|
||||
options.modules.dev.cc = {
|
||||
enable = mkBoolOpt false;
|
||||
xdg.enable = mkBoolOpt devCfg.xdg.enable;
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
clang
|
||||
gcc
|
||||
bear
|
||||
gdb
|
||||
cmake
|
||||
llvmPackages.libcxx
|
||||
];
|
||||
})
|
||||
|
||||
(mkIf cfg.xdg.enable {
|
||||
# TODO
|
||||
})
|
||||
];
|
||||
}
|
25
modules/dev/common-lisp.nix
Normal file
25
modules/dev/common-lisp.nix
Normal file
@ -0,0 +1,25 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
devCfg = config.modules.dev;
|
||||
cfg = devCfg.common-lisp;
|
||||
in {
|
||||
options.modules.dev.common-lisp = {
|
||||
enable = mkBoolOpt false;
|
||||
xdg.enable = mkBoolOpt devCfg.xdg.enable;
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
sbcl
|
||||
lispPackages.quicklisp
|
||||
];
|
||||
})
|
||||
|
||||
(mkIf cfg.xdg.enable {
|
||||
# TODO
|
||||
})
|
||||
];
|
||||
}
|
14
modules/dev/default.nix
Normal file
14
modules/dev/default.nix
Normal file
@ -0,0 +1,14 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.dev;
|
||||
in {
|
||||
options.modules.dev = {
|
||||
xdg.enable = mkBoolOpt true;
|
||||
};
|
||||
|
||||
config = mkIf cfg.xdg.enable {
|
||||
# TODO
|
||||
};
|
||||
}
|
25
modules/dev/lua.nix
Normal file
25
modules/dev/lua.nix
Normal file
@ -0,0 +1,25 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
devCfg = config.modules.dev;
|
||||
cfg = devCfg.lua;
|
||||
in {
|
||||
options.modules.dev.lua = {
|
||||
enable = mkBoolOpt false;
|
||||
xdg.enable = mkBoolOpt devCfg.enableXDG;
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
lua
|
||||
luaPackages.moonscript
|
||||
];
|
||||
})
|
||||
|
||||
(mkIf cfg.xdg.enable {
|
||||
# TODO
|
||||
})
|
||||
];
|
||||
}
|
41
modules/dev/python.nix
Normal file
41
modules/dev/python.nix
Normal file
@ -0,0 +1,41 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
devCfg = config.modules.dev;
|
||||
cfg = devCfg.python;
|
||||
in {
|
||||
options.modules.dev.python = {
|
||||
enable = mkBoolOpt false;
|
||||
xdg.enable = mkBoolOpt devCfg.xdg.enable;
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
python310
|
||||
python310Packages.pip
|
||||
python310Packages.ipython
|
||||
python310Packages.black
|
||||
python310Packages.setuptools
|
||||
python310Packages.pylint
|
||||
python310Packages.poetry
|
||||
];
|
||||
|
||||
environment.shellAliases = {
|
||||
py = "python";
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf cfg.xdg.enable {
|
||||
env.IPYTHONDIR = "$XDG_CONFIG_HOME/ipython";
|
||||
env.PIP_CONFIG_FILE = "$XDG_CONFIG_HOME/pip/pip.conf";
|
||||
env.PIP_LOG_FILE = "$XDG_DATA_HOME/pip/log";
|
||||
env.PYLINTHOME = "$XDG_DATA_HOME/pylint";
|
||||
env.PYLINTRC = "$XDG_CONFIG_HOME/pylint/pylintrc";
|
||||
env.PYTHONSTARTUP = "$XDG_CONFIG_HOME/python/pythonrc";
|
||||
env.PYTHON_EGG_CACHE = "$XDG_CACHE_HOME/python-eggs";
|
||||
env.JUPYTER_CONFIG_DIR = "$XDG_CONFIG_HOME/jupyter";
|
||||
})
|
||||
];
|
||||
}
|
31
modules/dev/rust.nix
Normal file
31
modules/dev/rust.nix
Normal file
@ -0,0 +1,31 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
devCfg = config.modules.dev;
|
||||
cfg = devCfg.rust;
|
||||
in {
|
||||
options.modules.dev.rust = {
|
||||
enable = mkBoolOpt false;
|
||||
xdg.enable = mkBoolOpt devCfg.xdg.enable;
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
user.packages = [
|
||||
pkgs.rustup
|
||||
];
|
||||
env.PATH = [ "$(${pkgs.yarn}/bin/yarn global bin)" ];
|
||||
environment.shellAliases = {
|
||||
rs = "rustc";
|
||||
rsp = "rustup";
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf cfg.xdg.enable {
|
||||
env.RUSTUP_HOME = "$XDG_DATA_HOME/rustup";
|
||||
env.CARGO_HOME = "$XDG_DATA_HOME/cargo";
|
||||
env.PATH = [ "$CARGO_HOME/bin" ];
|
||||
})
|
||||
];
|
||||
}
|
24
modules/dev/shell.nix
Normal file
24
modules/dev/shell.nix
Normal file
@ -0,0 +1,24 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
devCfg = config.modules.dev;
|
||||
cfg = devCfg.shell;
|
||||
in {
|
||||
options.modules.dev.shell = {
|
||||
enable = mkBoolOpt false;
|
||||
xdg.enable = mkBoolOpt devCfg.xdg.enable;
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
shellcheck
|
||||
];
|
||||
})
|
||||
|
||||
(mkIf cfg.xdg.enable {
|
||||
# TODO
|
||||
})
|
||||
];
|
||||
}
|
14
modules/editors/default.nix
Normal file
14
modules/editors/default.nix
Normal file
@ -0,0 +1,14 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.editors;
|
||||
in {
|
||||
options.modules.editors = {
|
||||
default = mkOpt types.str "vim";
|
||||
};
|
||||
|
||||
config = mkIf (cfg.default != null) {
|
||||
env.EDITOR = cfg.default;
|
||||
};
|
||||
}
|
64
modules/editors/emacs.nix
Normal file
64
modules/editors/emacs.nix
Normal file
@ -0,0 +1,64 @@
|
||||
{ config, lib, pkgs, inputs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.editors.emacs;
|
||||
configDir = config.dotfiles.configDir;
|
||||
in {
|
||||
options.modules.editors.emacs = {
|
||||
enable = mkBoolOpt false;
|
||||
doom = rec {
|
||||
enable = mkBoolOpt false;
|
||||
forgeUrl = mkOpt types.str "https://github.com";
|
||||
repoUrl = mkOpt types.str "${forgeUrl}/doomemacs/doomemacs";
|
||||
configRepoUrl = mkOpt types.str "${forgeUrl}/hlissner/doom-emacs-private";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
nixpkgs.overlays = [ inputs.emacs-overlay.overlay ];
|
||||
|
||||
user.packages = with pkgs; [
|
||||
## Emacs itself
|
||||
binutils # native-comp needs 'as', provided by this
|
||||
# 28.2 + native-comp
|
||||
((emacsPackagesFor emacsNativeComp).emacsWithPackages (epkgs: [ epkgs.vterm ]))
|
||||
|
||||
## Doom dependencies
|
||||
git
|
||||
(ripgrep.override {withPCRE2 = true;})
|
||||
gnutls # for TLS connectivity
|
||||
|
||||
## Optional dependencies
|
||||
fd # faster projectile indexing
|
||||
imagemagick # for image-dired
|
||||
(mkIf (config.programs.gnupg.agent.enable) pinentry_emacs) # in-emacs gnupg prompts
|
||||
zstd # for undo-fu-session/undo-tree compression
|
||||
|
||||
## Module dependencies
|
||||
# :checkers spell
|
||||
(aspellWithDicts (ds: with ds; [ en en-computers en-science ]))
|
||||
# :tools editorconfig
|
||||
editorconfig-core-c # per-project style config
|
||||
# :tools lookup & :lang org +roam
|
||||
sqlite
|
||||
# :lang latex & :lang org (latex previews)
|
||||
texlive.combined.scheme-medium
|
||||
];
|
||||
|
||||
env.PATH = [ "$XDG_CONFIG_HOME/emacs/bin" ];
|
||||
|
||||
modules.shell.zsh.rcFiles = [ "${configDir}/emacs/aliases.zsh" ];
|
||||
|
||||
fonts.fonts = [ pkgs.emacs-all-the-icons-fonts ];
|
||||
|
||||
system.userActivationScripts = mkIf cfg.doom.enable {
|
||||
installDoomEmacs = ''
|
||||
if [ ! -d "$XDG_CONFIG_HOME/emacs" ]; then
|
||||
git clone --depth=1 --single-branch "${cfg.doom.repoUrl}" "$XDG_CONFIG_HOME/emacs"
|
||||
git clone "${cfg.doom.configRepoUrl}" "$XDG_CONFIG_HOME/doom"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
23
modules/editors/vim.nix
Normal file
23
modules/editors/vim.nix
Normal file
@ -0,0 +1,23 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.editors.vim;
|
||||
in {
|
||||
options.modules.editors.vim = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
editorconfig-core-c
|
||||
unstable.neovim
|
||||
];
|
||||
|
||||
# env.VIMINIT = "let \\$MYVIMRC='\\$XDG_CONFIG_HOME/nvim/init.vim' | source \\$MYVIMRC";
|
||||
|
||||
environment.shellAliases = {
|
||||
vim = "nvim";
|
||||
};
|
||||
};
|
||||
}
|
41
modules/hardware/audio.nix
Normal file
41
modules/hardware/audio.nix
Normal file
@ -0,0 +1,41 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.hardware.audio;
|
||||
in {
|
||||
options.modules.hardware.audio = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
alsa.enable = true;
|
||||
alsa.support32Bit = true;
|
||||
pulse.enable = true;
|
||||
};
|
||||
|
||||
security.rtkit.enable = true;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
easyeffects
|
||||
];
|
||||
|
||||
# HACK Prevents ~/.esd_auth files by disabling the esound protocol module
|
||||
# for pulseaudio, which I likely don't need. Is there a better way?
|
||||
hardware.pulseaudio.configFile =
|
||||
let
|
||||
inherit (pkgs) runCommand pulseaudio;
|
||||
paConfigFile = runCommand "disablePulseaudioEsoundModule"
|
||||
{ buildInputs = [ pulseaudio ]; } ''
|
||||
mkdir "$out"
|
||||
cp ${pulseaudio}/etc/pulse/default.pa "$out/default.pa"
|
||||
sed -i -e 's|load-module module-esound-protocol-unix|# ...|' "$out/default.pa"
|
||||
'';
|
||||
in
|
||||
mkIf config.hardware.pulseaudio.enable "${paConfigFile}/default.pa";
|
||||
|
||||
user.extraGroups = [ "audio" ];
|
||||
};
|
||||
}
|
14
modules/hardware/bluetooth.nix
Normal file
14
modules/hardware/bluetooth.nix
Normal file
@ -0,0 +1,14 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.hardware.bluetooth;
|
||||
in {
|
||||
options.modules.hardware.bluetooth = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
hardware.bluetooth.enable = true;
|
||||
};
|
||||
}
|
45
modules/hardware/fs.nix
Normal file
45
modules/hardware/fs.nix
Normal file
@ -0,0 +1,45 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.hardware.fs;
|
||||
in {
|
||||
options.modules.hardware.fs = {
|
||||
enable = mkBoolOpt false;
|
||||
zfs.enable = mkBoolOpt false;
|
||||
ssd.enable = mkBoolOpt false;
|
||||
# TODO automount.enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
programs.udevil.enable = true;
|
||||
|
||||
# Support for more filesystems, mostly to support external drives
|
||||
environment.systemPackages = with pkgs; [
|
||||
sshfs
|
||||
exfat
|
||||
ntfs3g
|
||||
];
|
||||
}
|
||||
|
||||
(mkIf (!cfg.zfs.enable && cfg.ssd.enable) {
|
||||
services.fstrim.enable = true;
|
||||
})
|
||||
|
||||
(mkIf cfg.zfs.enable (mkMerge [
|
||||
{
|
||||
boot.loader.grub.copyKernels = true;
|
||||
boot.supportedFilesystems = [ "zfs" ];
|
||||
boot.zfs.devNodes = "/dev/disk/by-partuuid";
|
||||
services.zfs.autoScrub.enable = true;
|
||||
}
|
||||
|
||||
(mkIf cfg.ssd.enable {
|
||||
# Will only TRIM SSDs; skips over HDDs
|
||||
services.fstrim.enable = false;
|
||||
services.zfs.trim.enable = true;
|
||||
})
|
||||
]))
|
||||
]);
|
||||
}
|
29
modules/hardware/nvidia.nix
Normal file
29
modules/hardware/nvidia.nix
Normal file
@ -0,0 +1,29 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.hardware.nvidia;
|
||||
in {
|
||||
options.modules.hardware.nvidia = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
hardware.opengl = {
|
||||
enable = true;
|
||||
driSupport = true;
|
||||
driSupport32Bit = true;
|
||||
};
|
||||
|
||||
services.xserver.videoDrivers = [ "nvidia" ];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
# Respect XDG conventions, damn it!
|
||||
(writeScriptBin "nvidia-settings" ''
|
||||
#!${stdenv.shell}
|
||||
mkdir -p "$XDG_CONFIG_HOME/nvidia"
|
||||
exec ${config.boot.kernelPackages.nvidia_x11.settings}/bin/nvidia-settings --config="$XDG_CONFIG_HOME/nvidia/settings"
|
||||
'')
|
||||
];
|
||||
};
|
||||
}
|
16
modules/hardware/sensors.nix
Normal file
16
modules/hardware/sensors.nix
Normal file
@ -0,0 +1,16 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custon;
|
||||
let
|
||||
cfg = config.modules.hardware.sensors;
|
||||
in {
|
||||
options.modules.hardware.sensors = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = [
|
||||
pkgs.lm_sensors
|
||||
];
|
||||
};
|
||||
}
|
24
modules/hardware/wacom.nix
Normal file
24
modules/hardware/wacom.nix
Normal file
@ -0,0 +1,24 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.hardware.wacom;
|
||||
in
|
||||
{
|
||||
options.modules.hardware.wacom = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.xserver.wacom.enable = true;
|
||||
# TODO Move this to udev
|
||||
system.userActivationScripts.wacom = ''
|
||||
# lock tablet to main display
|
||||
if xinput list --id-only "Wacom Intuos Pro S Pen stylus" 2>&1 >/dev/null; then
|
||||
xinput map-to-output $(xinput list --id-only "Wacom Intuos Pro S Pen stylus") DVI-I-1
|
||||
xinput map-to-output $(xinput list --id-only "Wacom Intuos Pro S Pen eraser") DVI-I-1
|
||||
xinput map-to-output $(xinput list --id-only "Wacom Intuos Pro S Pen cursor") DVI-I-1
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
79
modules/options.nix
Normal file
79
modules/options.nix
Normal file
@ -0,0 +1,79 @@
|
||||
{ config, options, lib, home-manager, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
{
|
||||
options = with types; {
|
||||
user = mkOpt attrs {};
|
||||
|
||||
home = {
|
||||
file = mkOpt' attrs {} "Files to place directly in $HOME";
|
||||
configFile = mkOpt' attrs {} "Files to place in $XDG_CONFIG_HOME";
|
||||
dataFile = mkOpt' attrs {} "Files to place in $XDG_DATA_HOME";
|
||||
dconfSettings = mkOpt' attrs {} "Configuration of dconf settings";
|
||||
};
|
||||
|
||||
dotfiles = {
|
||||
dir = mkOpt path (removePrefix "/mnt" (findFirst pathExists (toString ../.) [
|
||||
"/mnt/etc/dotfiles"
|
||||
"/etc/dotfiles"
|
||||
]));
|
||||
binDir = mkOpt path "${config.dotfiles.dir}/bin";
|
||||
configDir = mkOpt path "${config.dotfiles.dir}/config";
|
||||
modulesDir = mkOpt path "${config.dotfiles.dir}/modules";
|
||||
themesDir = mkOpt path "${config.dotfiles.modulesDir}/themes";
|
||||
};
|
||||
|
||||
env = mkOption {
|
||||
type = attrsOf (oneOf [ str path (listOf (either str path)) ]);
|
||||
apply = mapAttrs (n: v: if isList v then concatMapStringsSep ":" (x: toString x) v else (toString v));
|
||||
default = {};
|
||||
description = "TODO";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
user = {
|
||||
name = let name = builtins.getEnv "USER"; in if elem user [ "" "root" ] then "nafaryus" else user;
|
||||
description = "L-Nafaryus";
|
||||
extraGroups = [ "wheel" ];
|
||||
isNormalUser = true;
|
||||
home = "/home/${name}";
|
||||
group = "users";
|
||||
uid = 1000;
|
||||
};
|
||||
|
||||
# Install user packages to /etc/profiles instead. Necessary for
|
||||
# nixos-rebuild build-vm to work.
|
||||
home-manager = {
|
||||
useUserPackages = true;
|
||||
users.${config.user.name} = {
|
||||
home = {
|
||||
file = mkAliasDefinitions options.home.file;
|
||||
# Necessary for home-manager to work with flakes, otherwise it will
|
||||
# look for a nixpkgs channel.
|
||||
stateVersion = config.system.stateVersion;
|
||||
};
|
||||
xdg = {
|
||||
configFile = mkAliasDefinitions options.home.configFile;
|
||||
dataFile = mkAliasDefinitions options.home.dataFile;
|
||||
};
|
||||
dconf = {
|
||||
settings = mkAliasDefinitions options.home.dconfSettings;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.users.${config.user.name} = mkAliasDefinitions options.user;
|
||||
|
||||
nix.settings = let users = [ "root" config.user.name ]; in {
|
||||
trusted-users = users;
|
||||
allowed-users = users;
|
||||
};
|
||||
|
||||
# must already begin with pre-existing PATH. Also, can't use binDir here,
|
||||
# because it contains a nix store path.
|
||||
env.PATH = [ "$DOTFILES_BIN" "$XDG_BIN_HOME" "$PATH" ];
|
||||
|
||||
environment.extraInit = concatStringsSep "\n" (mapAttrsToList (n: v: "export ${n}=\"${v}\"") config.env);
|
||||
};
|
||||
}
|
78
modules/security.nix
Normal file
78
modules/security.nix
Normal file
@ -0,0 +1,78 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
## System security tweaks
|
||||
# sets hidepid=2 on /proc (make process info visible only to owning user)
|
||||
# NOTE Was removed on nixpkgs-unstable because it doesn't do anything
|
||||
# security.hideProcessInformation = true;
|
||||
# Prevent replacing the running kernel w/o reboot
|
||||
security.protectKernelImage = true;
|
||||
|
||||
#
|
||||
boot.tmp.useTmpfs = true;
|
||||
|
||||
# tmpfs = /tmp is mounted in ram. Doing so makes temp file management speedy
|
||||
# on ssd systems, and volatile! Because it's wiped on reboot.
|
||||
boot.tmpOnTmpfs = lib.mkDefault true;
|
||||
|
||||
# If not using tmpfs, which is naturally purged on reboot, we must clean it
|
||||
# /tmp ourselves. /tmp should be volatile storage!
|
||||
boot.cleanTmpDir = lib.mkDefault (!config.boot.tmpOnTmpfs);
|
||||
|
||||
# Fix a security hole in place for backwards compatibility. See desc in
|
||||
# nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
|
||||
boot.loader.systemd-boot.editor = false;
|
||||
|
||||
boot.kernel.sysctl = {
|
||||
# The Magic SysRq key is a key combo that allows users connected to the
|
||||
# system console of a Linux kernel to perform some low-level commands.
|
||||
# Disable it, since we don't need it, and is a potential security concern.
|
||||
"kernel.sysrq" = 0;
|
||||
|
||||
## TCP hardening
|
||||
# Prevent bogus ICMP errors from filling up logs.
|
||||
"net.ipv4.icmp_ignore_bogus_error_responses" = 1;
|
||||
# Reverse path filtering causes the kernel to do source validation of
|
||||
# packets received from all interfaces. This can mitigate IP spoofing.
|
||||
"net.ipv4.conf.default.rp_filter" = 1;
|
||||
"net.ipv4.conf.all.rp_filter" = 1;
|
||||
# Do not accept IP source route packets (we're not a router)
|
||||
"net.ipv4.conf.all.accept_source_route" = 0;
|
||||
"net.ipv6.conf.all.accept_source_route" = 0;
|
||||
# Don't send ICMP redirects (again, we're on a router)
|
||||
"net.ipv4.conf.all.send_redirects" = 0;
|
||||
"net.ipv4.conf.default.send_redirects" = 0;
|
||||
# Refuse ICMP redirects (MITM mitigations)
|
||||
"net.ipv4.conf.all.accept_redirects" = 0;
|
||||
"net.ipv4.conf.default.accept_redirects" = 0;
|
||||
"net.ipv4.conf.all.secure_redirects" = 0;
|
||||
"net.ipv4.conf.default.secure_redirects" = 0;
|
||||
"net.ipv6.conf.all.accept_redirects" = 0;
|
||||
"net.ipv6.conf.default.accept_redirects" = 0;
|
||||
# Protects against SYN flood attacks
|
||||
"net.ipv4.tcp_syncookies" = 1;
|
||||
# Incomplete protection again TIME-WAIT assassination
|
||||
"net.ipv4.tcp_rfc1337" = 1;
|
||||
|
||||
## TCP optimization
|
||||
# TCP Fast Open is a TCP extension that reduces network latency by packing
|
||||
# data in the sender’s initial TCP SYN. Setting 3 = enable TCP Fast Open for
|
||||
# both incoming and outgoing connections:
|
||||
"net.ipv4.tcp_fastopen" = 3;
|
||||
# Bufferbloat mitigations + slight improvement in throughput & latency
|
||||
"net.ipv4.tcp_congestion_control" = "bbr";
|
||||
"net.core.default_qdisc" = "cake";
|
||||
};
|
||||
boot.kernelModules = [ "tcp_bbr" ];
|
||||
|
||||
# Change me later!
|
||||
user.initialPassword = "nixos";
|
||||
users.users.root.initialPassword = "nixos";
|
||||
|
||||
# So we don't have to do this later...
|
||||
security.acme.acceptTerms = true;
|
||||
|
||||
# Set sudo command timeout to 30 minutes
|
||||
security.sudo.extraConfig = ''
|
||||
Defaults timestamp_timeout=30
|
||||
'';
|
||||
}
|
16
modules/services/calibre.nix
Normal file
16
modules/services/calibre.nix
Normal file
@ -0,0 +1,16 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.services.calibre;
|
||||
in {
|
||||
options.modules.services.calibre = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.calibre-server.enable = true;
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 8080 ];
|
||||
};
|
||||
}
|
38
modules/services/fail2ban.nix
Normal file
38
modules/services/fail2ban.nix
Normal file
@ -0,0 +1,38 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.services.fail2ban;
|
||||
in {
|
||||
options.modules.services.fail2ban = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.fail2ban = {
|
||||
enable = true;
|
||||
ignoreIP = [ "127.0.0.1/16" "192.168.1.0/24" ];
|
||||
banaction-allports = "iptables-allports";
|
||||
bantime-increment = {
|
||||
enable = true;
|
||||
maxtime = "168h";
|
||||
factor = "4";
|
||||
};
|
||||
jails.DEFAULT = ''
|
||||
blocktype = DROP
|
||||
bantime = 1h
|
||||
findtime = 1h
|
||||
'';
|
||||
};
|
||||
|
||||
# Extra filters
|
||||
environment.etc = {
|
||||
"fail2ban/filter.d/gitea.conf".text = ''
|
||||
[Definition]
|
||||
failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
|
||||
ignoreregex =
|
||||
journalmatch = _SYSTEMD_UNIT=gitea.service
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
49
modules/services/gitea.nix
Normal file
49
modules/services/gitea.nix
Normal file
@ -0,0 +1,49 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.services.gitea;
|
||||
in {
|
||||
options.modules.services.gitea = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Allows git@... clone addresses rather than gitea@...
|
||||
users.users.git = {
|
||||
useDefaultShell = true;
|
||||
home = "/var/lib/gitea";
|
||||
group = "gitea";
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
user.extraGroups = [ "gitea" ];
|
||||
|
||||
services.gitea = {
|
||||
enable = true;
|
||||
lfs.enable = true;
|
||||
|
||||
user = "git";
|
||||
database.user = "git";
|
||||
|
||||
# We're assuming SSL-only connectivity
|
||||
cookieSecure = true;
|
||||
# Only log what's important, but Info is necessary for fail2ban to work
|
||||
log.level = "Info";
|
||||
settings = {
|
||||
server.DISABLE_ROUTER_LOG = true;
|
||||
database.LOG_SQL = false;
|
||||
service.ENABLE_BASIC_AUTHENTICATION = false;
|
||||
};
|
||||
|
||||
dump.interval = "daily";
|
||||
};
|
||||
|
||||
services.fail2ban.jails.gitea = ''
|
||||
enabled = true
|
||||
filter = gitea
|
||||
banaction = %(banaction_allports)s
|
||||
maxretry = 5
|
||||
'';
|
||||
};
|
||||
}
|
21
modules/services/jellyfin.nix
Normal file
21
modules/services/jellyfin.nix
Normal file
@ -0,0 +1,21 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.services.jellyfin;
|
||||
in {
|
||||
options.modules.services.jellyfin = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.jellyfin.enable = true;
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 8096 ];
|
||||
allowedUDPPorts = [ 8096 ];
|
||||
};
|
||||
|
||||
user.extraGroups = [ "jellyfin" ];
|
||||
};
|
||||
}
|
74
modules/services/nginx.nix
Normal file
74
modules/services/nginx.nix
Normal file
@ -0,0 +1,74 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with builtins;
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.services.nginx;
|
||||
in {
|
||||
options.modules.services.nginx = {
|
||||
enable = mkBoolOpt false;
|
||||
enableCloudflareSupport = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
|
||||
user.extraGroups = [ "nginx" ];
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
# Use recommended settings
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
||||
# Reduce the permitted size of client requests, to reduce the likelihood
|
||||
# of buffer overflow attacks. This can be tweaked on a per-vhost basis,
|
||||
# as needed.
|
||||
clientMaxBodySize = "256k"; # default 10m
|
||||
# Significantly speed up regex matchers
|
||||
appendConfig = ''pcre_jit on;'';
|
||||
commonHttpConfig = ''
|
||||
client_body_buffer_size 4k; # default: 8k
|
||||
large_client_header_buffers 2 4k; # default: 4 8k
|
||||
|
||||
map $sent_http_content_type $expires {
|
||||
default off;
|
||||
text/html 10m;
|
||||
text/css max;
|
||||
application/javascript max;
|
||||
application/pdf max;
|
||||
~image/ max;
|
||||
}
|
||||
'';
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf cfg.enableCloudflareSupport {
|
||||
services.nginx.commonHttpConfig = ''
|
||||
${concatMapStrings (ip: "set_real_ip_from ${ip};\n")
|
||||
(filter (line: line != "")
|
||||
(splitString "\n" ''
|
||||
${readFile (fetchurl "https://www.cloudflare.com/ips-v4/")}
|
||||
${readFile (fetchurl "https://www.cloudflare.com/ips-v6/")}
|
||||
''))}
|
||||
real_ip_header CF-Connecting-IP;
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
# Helpful nginx snippets
|
||||
#
|
||||
# Set expires headers for static files and turn off logging.
|
||||
# location ~* ^.+\.(js|css|swf|xml|txt|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|r ss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav |bmp|rtf)$ {
|
||||
# access_log off; log_not_found off; expires 30d;
|
||||
# }
|
||||
#
|
||||
# Deny all attempts to access PHP Files in the uploads directory
|
||||
# location ~* /(?:uploads|files)/.*\.php$ {
|
||||
# deny all;
|
||||
# }
|
23
modules/services/ssh.nix
Normal file
23
modules/services/ssh.nix
Normal file
@ -0,0 +1,23 @@
|
||||
{ options, config, lib, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.services.ssh;
|
||||
in {
|
||||
options.modules.services.ssh = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
kbdInteractiveAuthentication = false;
|
||||
passwordAuthentication = false;
|
||||
};
|
||||
|
||||
user.openssh.authorizedKeys.keys =
|
||||
if config.user.name == "nafaryus"
|
||||
then [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9pBG3Ak8hO4eQFA8roajDeZkKSPv2NsgZADQoV8bNEvsqNssqvpnoBKZCCKFv+Hqvf0tcTcdkRedUJh+9f/CI8dEuYiNzRyCFjYnfyFyUlEjNh/MaTonJEFEO4QsbapxQx+Buc+/jPCdwhUEbf1jvJV0oQy7TptXOn87cYQSuqqeubv+YwBqXUfMIFbsxH+ePZ9rX+N9sLdYpW2k9W1i8g2oNPrEpa3ICW2qhf/bshUhmDLB9te+vt1qMu0jmzpllnbaJJ57rDuL6XLaWqU/PD6uC0j1axf8AMxf00YvrLvMJ+T9hWlLe0mwNsgkhRzBE2/T+PYkUfvWvzqGLtIBZ nafaryus" ]
|
||||
else [];
|
||||
};
|
||||
}
|
20
modules/services/syncthing.nix
Normal file
20
modules/services/syncthing.nix
Normal file
@ -0,0 +1,20 @@
|
||||
{ config, options, pkgs, lib, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.services.syncthing;
|
||||
in {
|
||||
options.modules.services.syncthing = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.syncthing = rec {
|
||||
enable = true;
|
||||
openDefaultPorts = true;
|
||||
user = config.user.name;
|
||||
configDir = "${config.user.home}/.config/syncthing";
|
||||
dataDir = "${config.user.home}/.local/share/syncthing";
|
||||
};
|
||||
};
|
||||
}
|
32
modules/services/transmission.nix
Normal file
32
modules/services/transmission.nix
Normal file
@ -0,0 +1,32 @@
|
||||
{ config, options, pkgs, lib, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.services.transmission;
|
||||
in {
|
||||
options.modules.services.transmission = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.transmission = {
|
||||
enable = true;
|
||||
home = "${config.user.home}/torrents";
|
||||
settings = {
|
||||
incomplete-dir-enabled = true;
|
||||
rpc-whitelist = "127.0.0.1,192.168.*.*";
|
||||
rpc-host-whitelist = "*";
|
||||
rpc-host-whitelist-enabled = true;
|
||||
ratio-limit = 0;
|
||||
ratio-limit-enabled = true;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 51413 ];
|
||||
allowedUDPPorts = [ 51413 ];
|
||||
};
|
||||
|
||||
user.extraGroups = [ "transmission" ];
|
||||
};
|
||||
}
|
22
modules/services/wireguard.nix
Normal file
22
modules/services/wireguard.nix
Normal file
@ -0,0 +1,22 @@
|
||||
{ options, config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.services.wireguard;
|
||||
udpPorts = mapAttrs' (_: cfg: cfg.listenPort) config.networking.wireguard.interfaces;
|
||||
interfaces = elem 0 (mapAttrs' (n: _: n) config.networking.interfaces);
|
||||
wgInterfaces = elem 0 (mapAttrs' (n: _: n) config.networking.wireguard.interfaces);
|
||||
in {
|
||||
options.modules.services.wireguard = with types; {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
networking = {
|
||||
firewall.allowedUDPPorts = udpPorts;
|
||||
nat.enable = true;
|
||||
nat.externalInterface = mkDefault interfaces;
|
||||
nat.internalInterfaces = mkDefault wgInterfaces;
|
||||
};
|
||||
};
|
||||
}
|
15
modules/shell/direnv.nix
Normal file
15
modules/shell/direnv.nix
Normal file
@ -0,0 +1,15 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.shell.direnv;
|
||||
in {
|
||||
options.modules.shell.direnv = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = [ pkgs.direnv ];
|
||||
modules.shell.zsh.rcInit = ''eval "$(direnv hook zsh)"'';
|
||||
};
|
||||
}
|
30
modules/shell/git.nix
Normal file
30
modules/shell/git.nix
Normal file
@ -0,0 +1,30 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.shell.git;
|
||||
configDir = config.dotfiles.configDir;
|
||||
in {
|
||||
options.modules.shell.git = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
gitAndTools.git-annex
|
||||
unstable.gitAndTools.gh
|
||||
gitAndTools.git-open
|
||||
gitAndTools.diff-so-fancy
|
||||
(mkIf config.modules.shell.gnupg.enable gitAndTools.git-crypt)
|
||||
act
|
||||
];
|
||||
|
||||
home.configFile = {
|
||||
"git/config".source = "${configDir}/git/config";
|
||||
"git/ignore".source = "${configDir}/git/ignore";
|
||||
"git/attributes".source = "${configDir}/git/attributes";
|
||||
};
|
||||
|
||||
modules.shell.zsh.rcFiles = [ "${configDir}/git/aliases.zsh" ];
|
||||
};
|
||||
}
|
31
modules/shell/gnupg.nix
Normal file
31
modules/shell/gnupg.nix
Normal file
@ -0,0 +1,31 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.shell.gnupg;
|
||||
in {
|
||||
options.modules.shell.gnupg = with types; {
|
||||
enable = mkBoolOpt false;
|
||||
cacheTTL = mkOpt int 3600; # 1hr
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.variables.GNUPGHOME = "$XDG_CONFIG_HOME/gnupg";
|
||||
|
||||
programs.gnupg.agent.enable = true;
|
||||
|
||||
user.packages = [
|
||||
pkgs.tomb
|
||||
];
|
||||
|
||||
# HACK Without this config file you get "No pinentry program" on 20.03.
|
||||
# programs.gnupg.agent.pinentryFlavor doesn't appear to work, and this
|
||||
# is cleaner than overriding the systemd unit.
|
||||
home.configFile."gnupg/gpg-agent.conf" = {
|
||||
text = ''
|
||||
default-cache-ttl ${toString cfg.cacheTTL}
|
||||
pinentry-program ${pkgs.pinentry.gtk2}/bin/pinentry
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
24
modules/shell/pass.nix
Normal file
24
modules/shell/pass.nix
Normal file
@ -0,0 +1,24 @@
|
||||
{ config, options, pkgs, lib, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.shell.pass;
|
||||
in {
|
||||
options.modules.shell.pass = with types; {
|
||||
enable = mkBoolOpt false;
|
||||
passwordStoreDir = mkOpt str "$HOME/.secrets/password-store";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = with pkgs; [
|
||||
(pass.withExtensions (exts: [
|
||||
exts.pass-otp
|
||||
exts.pass-genphrase
|
||||
] ++
|
||||
(if config.modules.shell.gnupg.enable
|
||||
then [ exts.pass-tomb ]
|
||||
else [])))
|
||||
];
|
||||
env.PASSWORD_STORE_DIR = cfg.passwordStoreDir;
|
||||
};
|
||||
}
|
46
modules/shell/tmux.nix
Normal file
46
modules/shell/tmux.nix
Normal file
@ -0,0 +1,46 @@
|
||||
{ config, options, pkgs, lib, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.shell.tmux;
|
||||
configDir = config.dotfiles.configDir;
|
||||
in {
|
||||
options.modules.shell.tmux = with types; {
|
||||
enable = mkBoolOpt false;
|
||||
rcFiles = mkOpt (listOf (either str path)) [];
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
user.packages = with pkgs; [ tmux ];
|
||||
|
||||
modules.theme.onReload.tmux = "${pkgs.tmux}/bin/tmux source-file $TMUX_HOME/extraInit";
|
||||
|
||||
modules.shell.zsh = {
|
||||
rcInit = "_cache tmuxifier init -";
|
||||
rcFiles = [ "${configDir}/tmux/aliases.zsh" ];
|
||||
};
|
||||
|
||||
home.configFile = {
|
||||
"tmux" = { source = "${configDir}/tmux"; recursive = true; };
|
||||
"tmux/extraInit" = {
|
||||
text = ''
|
||||
#!/usr/bin/env bash
|
||||
# This file is auto-generated by nixos, don't edit by hand!
|
||||
${concatMapStrings (path: "tmux source-file '${path}'\n") cfg.rcFiles}
|
||||
tmux run-shell '${pkgs.tmuxPlugins.copycat}/share/tmux-plugins/copycat/copycat.tmux'
|
||||
tmux run-shell '${pkgs.tmuxPlugins.prefix-highlight}/share/tmux-plugins/prefix-highlight/prefix_highlight.tmux'
|
||||
tmux run-shell '${pkgs.tmuxPlugins.yank}/share/tmux-plugins/yank/yank.tmux'
|
||||
tmux run-shell '${pkgs.tmuxPlugins.resurrect}/share/tmux-plugins/resurrect/resurrect.tmux'
|
||||
'';
|
||||
executable = true;
|
||||
};
|
||||
};
|
||||
|
||||
env = {
|
||||
PATH = [ "$TMUXIFIER/bin" ];
|
||||
TMUX_HOME = "$XDG_CONFIG_HOME/tmux";
|
||||
TMUXIFIER = "$XDG_DATA_HOME/tmuxifier";
|
||||
TMUXIFIER_LAYOUT_PATH = "$XDG_DATA_HOME/tmuxifier";
|
||||
};
|
||||
};
|
||||
}
|
88
modules/shell/zsh.nix
Normal file
88
modules/shell/zsh.nix
Normal file
@ -0,0 +1,88 @@
|
||||
{ config, options, pkgs, lib, ... }:
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.shell.zsh;
|
||||
configDir = config.dotfiles.configDir;
|
||||
in {
|
||||
options.modules.shell.zsh = with types; {
|
||||
enable = mkBoolOpt false;
|
||||
|
||||
aliases = mkOpt (attrsOf (either str path)) {};
|
||||
|
||||
rcInit = mkOpt' lines "" ''
|
||||
Zsh lines to be written to $XDG_CONFIG_HOME/zsh/extra.zshrc and sourced by
|
||||
$XDG_CONFIG_HOME/zsh/.zshrc
|
||||
'';
|
||||
envInit = mkOpt' lines "" ''
|
||||
Zsh lines to be written to $XDG_CONFIG_HOME/zsh/extra.zshenv and sourced
|
||||
by $XDG_CONFIG_HOME/zsh/.zshenv
|
||||
'';
|
||||
|
||||
rcFiles = mkOpt (listOf (either str path)) [];
|
||||
envFiles = mkOpt (listOf (either str path)) [];
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.defaultUserShell = pkgs.zsh;
|
||||
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
enableCompletion = true;
|
||||
# I init completion myself, because enableGlobalCompInit initializes it
|
||||
# too soon, which means commands initialized later in my config won't get
|
||||
# completion, and running compinit twice is slow.
|
||||
enableGlobalCompInit = false;
|
||||
promptInit = "";
|
||||
};
|
||||
|
||||
user.packages = with pkgs; [
|
||||
zsh
|
||||
nix-zsh-completions
|
||||
bat
|
||||
exa
|
||||
fasd
|
||||
fd
|
||||
fzf
|
||||
jq
|
||||
ripgrep
|
||||
tldr
|
||||
];
|
||||
|
||||
env = {
|
||||
ZDOTDIR = "$XDG_CONFIG_HOME/zsh";
|
||||
ZSH_CACHE = "$XDG_CACHE_HOME/zsh";
|
||||
ZGEN_DIR = "$XDG_DATA_HOME/zgenom";
|
||||
};
|
||||
|
||||
home.configFile = {
|
||||
# Write it recursively so other modules can write files to it
|
||||
"zsh" = { source = "${configDir}/zsh"; recursive = true; };
|
||||
|
||||
# Why am I creating extra.zsh{rc,env} when I could be using extraInit?
|
||||
# Because extraInit generates those files in /etc/profile, and mine just
|
||||
# write the files to ~/.config/zsh; where it's easier to edit and tweak
|
||||
# them in case of issues or when experimenting.
|
||||
"zsh/extra.zshrc".text =
|
||||
let
|
||||
aliasLines = mapAttrsToList (n: v: "alias ${n}=\"${v}\"") cfg.aliases;
|
||||
in ''
|
||||
# This file was autogenerated, do not edit it!
|
||||
${concatStringsSep "\n" aliasLines}
|
||||
${concatMapStrings (path: "source '${path}'\n") cfg.rcFiles}
|
||||
${cfg.rcInit}
|
||||
'';
|
||||
|
||||
"zsh/extra.zshenv".text = ''
|
||||
# This file is autogenerated, do not edit it!
|
||||
${concatMapStrings (path: "source '${path}'\n") cfg.envFiles}
|
||||
${cfg.envInit}
|
||||
'';
|
||||
};
|
||||
|
||||
system.userActivationScripts.cleanupZgen = ''
|
||||
rm -rf $ZSH_CACHE
|
||||
rm -fv $ZGEN_DIR/init.zsh{,.zwc}
|
||||
'';
|
||||
};
|
||||
}
|
48
modules/xdg.nix
Normal file
48
modules/xdg.nix
Normal file
@ -0,0 +1,48 @@
|
||||
{ config, home-manager, pkgs, ... }:
|
||||
{
|
||||
home-manager.users.${config.user.name}.xdg ={
|
||||
enable = true;
|
||||
# Until https://github.com/rycee/home-manager/issues/1213 is solved.
|
||||
configFile."mimeapps.list".force = true;
|
||||
mime.enable = true;
|
||||
mimeApps = {
|
||||
enable = true;
|
||||
defaultApplications = {
|
||||
"text/html" = "firefox.desktop";
|
||||
"x-scheme-handler/http" = "firefox.desktop";
|
||||
"x-scheme-handler/https" = "firefox.desktop";
|
||||
"x-scheme-handler/about" = "firefox.desktop";
|
||||
"x-scheme-handler/unknown" = "firefox.desktop";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment = {
|
||||
sessionVariables = {
|
||||
# These are the defaults, and xdg.enable does set them, but due to load
|
||||
# order, they're not set before environment.variables are set, which could
|
||||
# cause race conditions.
|
||||
XDG_CACHE_HOME = "$HOME/.cache";
|
||||
XDG_CONFIG_HOME = "$HOME/.config";
|
||||
XDG_DATA_HOME = "$HOME/.local/share";
|
||||
XDG_BIN_HOME = "$HOME/.local/bin";
|
||||
# Firefox really wants a desktop directory to exist
|
||||
XDG_DESKTOP_DIR = "~/tmp";
|
||||
# Setting this for Electon apps that do not respect mime default apps
|
||||
DEFAULT_BROWSER = "${pkgs.firefox}/bin/firefox";
|
||||
};
|
||||
variables = {
|
||||
__GL_SHADER_DISK_CACHE_PATH = "$XDG_CACHE_HOME/nv";
|
||||
CUDA_CACHE_PATH = "$XDG_CACHE_HOME/nv";
|
||||
HISTFILE = "$XDG_DATA_HOME/bash/history";
|
||||
INPUTRC = "$XDG_CONFIG_HOME/readline/inputrc";
|
||||
LESSHISTFILE = "$XDG_CACHE_HOME/lesshst";
|
||||
WGETRC = "$XDG_CONFIG_HOME/wgetrc";
|
||||
};
|
||||
|
||||
extraInit = ''
|
||||
export XAUTHORITY=/tmp/Xauthority
|
||||
[ -e ~/.Xauthority ] && mv -f ~/.Xauthority "$XAUTHORITY"
|
||||
'';
|
||||
};
|
||||
}
|
0
overlays/.git-keep
Normal file
0
overlays/.git-keep
Normal file
0
packages/.git-keep
Normal file
0
packages/.git-keep
Normal file
17
shell.nix
Normal file
17
shell.nix
Normal file
@ -0,0 +1,17 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
with pkgs;
|
||||
let
|
||||
nixBin = writeShellScriptBin "nix" ''
|
||||
${nixFlakes}/bin/nix --option experimental-features "nix-command flakes" "$@"
|
||||
'';
|
||||
in
|
||||
mkShell {
|
||||
buildInputs = [
|
||||
git
|
||||
nix-zsh-completions
|
||||
];
|
||||
shellHook = ''
|
||||
export FLAKE="$(pwd)"
|
||||
export PATH="$FLAKE/bin:${nixBin}/bin:$PATH"
|
||||
'';
|
||||
}
|
7
templates/default.nix
Normal file
7
templates/default.nix
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
# Projects
|
||||
#project-nodejs = {
|
||||
# path = ./project/XYZ;
|
||||
# description = "";
|
||||
#};
|
||||
}
|
15
templates/module/default.nix
Normal file
15
templates/module/default.nix
Normal file
@ -0,0 +1,15 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
with builtins;
|
||||
with lib;
|
||||
with lib.custom;
|
||||
let
|
||||
cfg = config.modules.X.Y;
|
||||
in {
|
||||
options.modules.X.Y = {
|
||||
enable = mkBoolOpt false;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
};
|
||||
}
|
0
templates/project/.git-keep
Normal file
0
templates/project/.git-keep
Normal file
Loading…
Reference in New Issue
Block a user