{ pkgs, lib, ... }: let inherit (import ./const.nix) fontSize homedir gpgid; locale = "en_US.UTF-8"; in { nixpkgs.overlays = [ (import ../overlay.nix) ]; home = { stateVersion = "18.09"; sessionVariables = { GPGID = gpgid; EDITOR = "vim"; LANG = locale; # LC_ALL = locale; # bash prints an error when I try to set this LANGUAGE = locale; PATH = "${homedir}/bin:${homedir}/.local/bin:$PATH"; PAGER = "less"; # "bat --theme=ansi"; XTERM_LOCALE = locale; PYTHONSTARTUP = "${homedir}/.pythonrc"; FD_OPTIONS = "--follow --exclude .git"; BAT_PAGER = "less -R"; # FZF_DEFAULT_OPTS = "--bind='?:toggle-preview'"; # FZF_DEFAULT_COMMAND = "git ls-files --cached --others --exclude-standard | fd --type f --type l $FD_OPTIONS"; # FZF_CTRL_T_COMMAND = "fd $FD_OPTIONS"; # FZF_ALT_C_COMMAND = "fd --type d $FD_OPTIONS"; FORGIT_FZF_DEFAULT_OPTS = '' --exact --border --cycle --reverse ''; }; # From the command line: # setxkbmap -option caps:ctrl_modifier keyboard.options = [ "caps:ctrl_modifier" ]; file = { yubikeys = { source = ./authorized_yubikeys; target = ".yubico/authorized_yubikeys"; }; editorconfig = { source = ./editorconfig; target = ".editorconfig"; }; pythonrc = { source = ./pythonrc; target = ".pythonrc"; }; pdbrc = { source = ./pythonrc; target = ".pdbrc"; }; # Idk why this doesn't work, less says it can't use my lesskey file #less = { # source = ./lesskey; # target = ".less"; #}; userstyles = { source = ./userstyles.css; target = ".userstyles.css"; }; }; }; programs = { home-manager = { enable = true; }; readline = { enable = true; variables = { keyseq-timeout = 1200; colored-stats = true; colored-completion-prefix = true; expand-tilde = true; }; bindings = { # wrap a command in '$(...| fzf)' "\\C-xf" = ''"\C-e | fzf)\C-a(\C-a$\C-b\C-a"''; "\\e\\C-f" = "dump-functions"; # help "\\e\\C-o" = "dabbrev-expand"; # expand "\\e\\C-v" = "dump-variables"; # help "\\em" = "beginning-of-line"; # emacs-like history navigation "\\en" = "next-history"; "\\ep" = "previous-history"; }; extraConfig = '' $if Guile "\C-o": "()\C-b" $endif ''; }; fzf = { enable = true; enableBashIntegration = true; defaultCommand = "rg --files"; changeDirWidgetCommand = "fd --type d"; # M-c changeDirWidgetOptions = ["--preview 'tree -C {} | head -100'"]; fileWidgetCommand = "fd --type f"; fileWidgetOptions = ["--preview 'head -n100 {}'"]; historyWidgetOptions = ["--sort" "--exact"]; tmux.enableShellIntegration = true; tmux.shellIntegrationOptions = [ "-p 70%" ]; }; git = { enable = true; userName = "Ben Sima"; userEmail = "ben@bsima.me"; ignores = [ "*~" "*.swp" ]; package = pkgs.gitAndTools.gitFull; signing = { key = gpgid; # for some reason this fails... #gpgPath = # let # script = pkgs.writeScriptBin "my-ots-git-gpg-wrapper" '' # #!/usr/bin/env bash # set -euxo pipefail # ${pkgs.opentimestamps-client}/bin/ots-git-gpg-wrapper --gpg-program ${pkgs.gnupg}/bin/gpg $@ # ''; # in # "${script}/bin/my-ots-git-gpg-wrapper"; }; aliases = { authors = "shortlog -s -n"; slog = "log --stat"; glog = ''log --decorate --all --graph --pretty=format:"%Cred%h%Creset %an: %s - %Creset %C(yellow)%d%Creset %Cgreen(%cr)%Creset" --abbrev-commit --date=relative''; }; extraConfig = { commit.template = "${./git-commit-template}"; commit.verbose = "true"; fetch.showForcedUpdate = "false"; init.defaultBranch = "main"; log.date = "local"; merge.tool = "fugitive"; mergetool.fugitive.cmd = ''vim -f -c "Gvdiffsplit!" "$MERGED"''; pull.rebase = "true"; push.default = "current"; remote.pushDefault = "origin"; sendemail = { #smtpuser = "ben@bsima.me"; #smtpserverport = 587; smtpserver = "${homedir}/bin/sendmail"; chainreplyto = false; composeencoding = "UTF-8"; annotate = "yes"; cccmd = "git-contacts"; }; }; }; tmux = { enable = true; aggressiveResize = false; baseIndex = 0; clock24 = true; customPaneNavigationAndResize = false; disableConfirmationPrompt = false; escapeTime = 0; historyLimit = 10000; keyMode = "emacs"; newSession = false; resizeAmount = 5; reverseSplit = false; secureSocket = false; sensibleOnTop = true; #shell = "${pkgs.bash}/bin/bash"; shortcut = "a"; terminal = "xterm-256color"; tmuxinator.enable = false; tmuxp.enable = false; extraConfig = '' # Automatically set window title set-window-option -g automatic-rename on set-option -g set-titles on set -g xterm-keys on setw -g mouse on ## Panes # Split panes bind-key | split-window -h -c "#{pane_current_path}" bind-key - split-window -v -c "#{pane_current_path}" # Send/join panes bind-key j command-prompt -p "join pane from:" "join-pane -s '%%'" bind-key s command-prompt -p "send pane to:" "join-pane -t '%%'" # Use Alt-vim keys without prefix key to switch panes bind -n M-h select-pane -L bind -n M-j select-pane -D bind -n M-k select-pane -U bind -n M-l select-pane -R # Use Alt-vim capitalized keys without prefix key to resize panes bind -n M-H resize-pane -L bind -n M-J resize-pane -D bind -n M-K resize-pane -U bind -n M-L resize-pane -R # Shift arrow to switch windows bind -n S-Left previous-window bind -n S-Right next-window # Set current window pane to 80 columns bind-key E resize-pane -x 80 # cycle pane layout bind-key N next-layout bind-key P previous-layout # Toggle synchronizing panes bind-key y setw synchronize-panes ## Text manipulation # vim-like copy/paste setw -g mode-keys vi bind [ copy-mode bind ] paste-buffer # copy/paste with xclip bind-key -Tcopy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -sel clip -i' # select buffer to paste from bind Space choose-buffer # status line text set -g status-left-length 30 set -g status-left '#S | #(whoami)@#(hostname) | ' set -g status-right '~%Y.%m.%d..%H.%M' set -g renumber-windows on # white-ish background with dark-grey text set -g status-style bg=colour0,fg=colour13 # highlight current window set -g window-status-current-style fg=colour0,bg=colour13 set -g window-status-format '#I) #W ' set -g window-status-current-format '#I) #W ' # special thing for groq's SFT thing set -g update-environment "SFT_AUTH_SOCK SSH_AUTH_SOCK SSH_CONNECTION" ''; plugins = with pkgs.tmuxPlugins; [ extrakto tmux-fzf ]; }; urxvt = let font = size: "xft:Fira Mono:size=${toString size}:ant"; in { enable = true; fonts = [ (font (fontSize / 2)) "xft:Noto Emoji" ]; #keybindings = { # # why don't any of these work? # "Shift-Control-C" = "eval:selection_to_clipboard"; # "Shift-Control-V" = "eval:paste_clipboard"; # "Shift-Control-+" = "command:\033]710;${font 12}\007\033]711;${font 12}\007"; # "Shift-Control--" = "command:\033]710;${font 8}\007\033]711;${font 8}\007"; #}; iso14755 = true; # unicode chars #transparent = true; #shading = 10; }; direnv = { enable = true; enableBashIntegration = true; nix-direnv.enable = true; }; vim = { enable = true; #vimAlias = true; #viAlias = true; #vimdiffAlias = true; plugins = with pkgs.vimPlugins; [ base16-vim editorconfig-vim vim-sensible vim-fugitive vim-colors-solarized vim-sexp-mappings-for-regular-people # vim-ripgrep # not in nixpkgs :( rainbow_parentheses vim-plug # just in case vim-addon-local-vimrc fzf-vim (pkgs.vimUtils.buildVimPlugin { pname = "photon.vim"; version = "2022.03.14"; src = pkgs.fetchFromGitHub { owner = "axvr"; repo = "photon.vim"; rev = "32b42c8a12bf9588259b76f3df6807960e0d7386"; sha256 = "sha256-kM7WP03uE20yr0nCusB3ncHzgtEYxqNzoNoQGen9p+o="; }; meta.homepage = "https://github.com/axvr/photon.vim"; }) (pkgs.vimUtils.buildVimPlugin { pname = "skull-vim"; version = "2022.03.14"; src = pkgs.fetchFromGitHub { owner = "kadekillary"; repo = "skull-vim"; rev = "abb9d7120c63aad6f9acc26d31c948a93f352e94"; sha256 = "sha256-tu5aDRjHZtXKoyQBbMEhzjGrRl4GZD121ybs7oNylvs="; }; meta.homepage = "https://github.com/kadekillary/skull-vim"; }) ]; extraConfig = builtins.readFile ./vimrc; }; info.enable = true; man.enable = true; nix-index = { enable = true; enableBashIntegration = true; }; bash = { enable = true; initExtra = '' #DIR=~/.nix-profile/etc/profile.d #[[ -f "$DIR/nix.sh" ]] && . "$DIR/nix.sh" #[[ -f "$DIR/hm-session-vars.sh" ]] && . "$DIR/hm-session-vars.sh" [[ -f "${homedir}/.bashrc.local" ]] && . "${homedir}/.bashrc.local" source "${pkgs.forgit}/share/bash/forgit.plugin.zsh" function fcd() { local dir; echo "exit with ^D" while : do dir="$(ls -a1p | grep '/$' | grep -v '^./$' | fzf --height 40% --reverse --no-multi --preview 'pwd' --preview-window=up,1,border-none --no-info)" if [[ -z "$dir" ]]; then break else echo -n "$dir " cd "$dir" ls fi done } function up() { N=$1 P=$PWD for (( i=1; i<=$N; i++ )) do P+="/.." done cd "$P" } function regex() { gawk 'match($0,/'$1'/, ary) {print ary['\$\{2:-'0'}']}'; } export PS1='$(printf "%3.*s" $? $?)ϟ ' # kill a process with fzf fkill() { local pid pid=$(ps -ef | sed 1d | fzf -m --bind "ctrl-a:select-all"| awk '{print $2}') if [ "x$pid" != "x" ] then echo $pid | xargs kill -9 fi } # https://gist.github.com/junegunn/8b572b8d4b5eddd8b85e5f4d40f17236 is_in_git_repo() { git rev-parse HEAD > /dev/null 2>&1 } fzf_down() { fzf --height 50% --min-height 20 --border \ --bind 'ctrl-/:change-preview-window(hidden|90%|)' "$@" } _gf() { is_in_git_repo || return git -c color.status=always status --short | fzf_down -m --ansi --nth 2..,.. \ --preview '(git diff --color=always -- {-1} | sed 1,4d; cat {-1}) | head -500' | cut -c4- | sed 's/.* -> //' } _gb() { is_in_git_repo || return git branch -a --color=always | grep -v '/HEAD\s' | sort | fzf_down --ansi --multi --tac --preview-window right:70% \ --preview 'git log --oneline --graph --date=short --color=always --pretty="format:%C(auto)%cd %h%d %s" $(sed s/^..// <<< {} | cut -d" " -f1) | head -'$LINES | sed 's/^..//' | cut -d' ' -f1 | sed 's#^remotes/##' } _gt() { is_in_git_repo || return git tag --sort -version:refname | fzf_down --multi --preview-window right:70% \ --preview 'git show --color=always {} | head -'$LINES } _gh() { is_in_git_repo || return git log --date=short --format="%C(green)%C(bold)%cd %C(auto)%h%d %s (%an)" --graph --color=always --no-merges | fzf_down --ansi --no-sort --reverse --multi --exact \ --bind 'ctrl-s:toggle-sort' \ --header 'Press CTRL-S to toggle sort' \ --preview 'grep -o "[a-f0-9]\{7,\}" <<< {} | xargs git show --color=always | head -'$LINES | grep -o "[a-f0-9]\{7,\}" } _gr() { is_in_git_repo || return git remote -v | awk '{print $1 "\t" $2}' | uniq | fzf_down --tac \ --preview 'git log --oneline --graph --date=short --pretty="format:%C(auto)%cd %h%d %s" {1} | head -200' | cut -d$'\t' -f1 } bind '"\er": redraw-current-line' bind '"\C-g\C-f": "$(_gf)\e\C-e\er"' bind '"\C-g\C-b": "$(_gb)\e\C-e\er"' bind '"\C-g\C-t": "$(_gt)\e\C-e\er"' bind '"\C-g\C-h": "$(_gh)\e\C-e\er"' bind '"\C-g\C-r": "$(_gr)\e\C-e\er"' bind '"\C- ": "$(p)\e\C-e\er"' ''; shellAliases = { q = "que"; qd = ''que pub/bsnotify - <<< "done"''; ".." = "__HM_SESS_VARS_SOURCED= ."; day = "date +%a"; ddate = "date +%Y.%m.%d"; dday = "date +%A"; e = "emacsclient -nw"; # emacs in a terminal f = "fossil"; g = "git"; ga = "git add -A"; gb = "git branch"; gc = "git commit"; gca = "git commit -a"; gco = "git checkout"; gd = "git diff"; gl = "git pull --prune"; gp = "git push origin HEAD"; gs = "git status -sb"; hs = "NIX_PATH=$HOME/.nix-defexpr/channels$\{NIX_PATH:+:\}$NIX_PATH home-manager switch"; ll = "ls -lah"; rm = "rm -i"; s = '' INITIAL_QUERY="" && \ RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case " && \ FZF_DEFAULT_COMMAND="$RG_PREFIX '$INITIAL_QUERY'" && \ fzf --bind "change:reload:$RG_PREFIX {q} || true" \ --ansi --phony --query "$INITIAL_QUERY" \ --height=50% --layout=reverse ''; showpath = ''echo $PATH | sed "s/:/\n/g"''; tdate = "date +%Y.%m.%d..%H.%M"; ttime = "date +%H.%M"; typeless = "history | tail -n 20000 | sed 's/.* //' | sort | uniq -c | sort -g | tail -n 100"; v = "vim $(fzf --preview='bat --color=always {}' --preview-window right:70%)"; "v." = "vim ."; }; }; }; }