From 64139791fd992d896d7877f5f002c116b35ed747 Mon Sep 17 00:00:00 2001 From: Ray Andrew Date: Thu, 31 Oct 2024 18:26:07 -0500 Subject: [PATCH] add shell custom --- src/home/shell/bash.nix | 21 +++- src/home/shell/custom.sh | 99 +++++++++++++++++ src/home/shell/default.nix | 2 + src/home/shell/lazygit.nix | 7 ++ src/home/shell/shell.nix | 19 +++- src/home/shell/tmux/default.nix | 17 +++ src/home/shell/tmux/tmux.conf | 184 ++++++++++++++++++++++++++++++++ 7 files changed, 343 insertions(+), 6 deletions(-) create mode 100644 src/home/shell/custom.sh create mode 100644 src/home/shell/lazygit.nix create mode 100644 src/home/shell/tmux/default.nix create mode 100644 src/home/shell/tmux/tmux.conf diff --git a/src/home/shell/bash.nix b/src/home/shell/bash.nix index cfdf7e4..ca733a3 100644 --- a/src/home/shell/bash.nix +++ b/src/home/shell/bash.nix @@ -2,11 +2,22 @@ { programs.bash.enable = true; - # programs.bash.profileExtra = lib.mkAfter '' - # rm -rf ${config.home.homeDirectory}/.local/share/applications/home-manager - # rm -rf ${config.home.homeDirectory}/.icons/nix-icons - # ls ${config.home.homeDirectory}/.nix-profile/share/applications/*.desktop > ${config.home.homeDirectory}/.cache/current_desktop_files.txt - # ''; + programs.bash.enableVteIntegration = true; + programs.bash.bashrcExtra = lib.mkAfter '' +if [ "$term" != "dumb" ] || [ -n "$inside_emacs" ]; then + prompt_color="1;32m" + if [ -n "$inside_emacs" ]; then + # emacs term mode doesn't support xterm title escape sequence (\e]0;) + PS1="\n\[\033[$prompt_color\][\h \w]\\$\[\033[0m\] " + else + PS1="\[\e[32m\][\[\e[m\]\[\e[31m\]\u\[\e[m\]\[\e[33m\]@\[\e[m\]\[\e[32m\]\h\[\e[m\]:\[\e[36m\]\w\[\e[m\]\[\e[32m\]]\[\e[m\]\[\e[33m\]\\$\[\e[m\] " + # PS1="\n\[\033[$prompt_color\][\[\e]0;\h: \w\a\]\u@\h:\w]\\$\[\033[0m\] " + fi + if test "$term" = "xterm"; then + PS1="\[\033]2;\h:\u:\w\007\]$PS1" + fi +fi +''; custom.persist = { home.files = [ diff --git a/src/home/shell/custom.sh b/src/home/shell/custom.sh new file mode 100644 index 0000000..129da71 --- /dev/null +++ b/src/home/shell/custom.sh @@ -0,0 +1,99 @@ +# Paths + +export PATH="$HOME/.bin:$PATH" +export PATH="$HOME/bin:$PATH" +export PATH="$HOME/.local/bin:$PATH" + +export EDITOR="nvim" +# export EDITOR="emacs -nw" +export ZINIT_INSTALL_BINARY=0 + +{ eval `ssh-agent`; } &>/dev/null + +# Aliases +alias ..='cd ..' +alias :q='exit' +alias cat='bat' +alias du='dust' +alias eza='eza ' +alias g='git status -sb' +alias ga='git add' +alias gb='git branch -v' +alias gba='git for-each-ref --sort=committerdate refs/heads/ --format="%(authordate:short) %(color:red)%(objectname:short) '\'''\''%(color:yellow)%(refname:short)%(color:reset) (%(color:green)%(committerdate:relative)%(color:reset))"' +alias gbd='git for-each-ref --sort=-committerdate refs/heads/ --format="%(authordate:short) %(color:red)%(objectname:short) %(color:yellow)%(refname:short)%(color:reset) (%(color:green)%(committerdate:relative)%(color:reset))"' +alias gc='git commit' +alias gca='git commit --amend' +alias gcheck='git checkout' +alias gcm='git commit -m' +alias gcod='git checkout develop' +alias gcom='git checkout main' +alias gcos='git checkout staging' +alias gd='git diff --color-words' +alias gf='git fetch' +alias gfa='git fetch --all' +alias gl='git log --oneline --decorate' +alias gp='git push' +alias gpl='git pull --rebase' +alias gpod='git push origin develop' +alias gpofl='git push --force-with-lease origin' +alias gpom='git push origin main' +alias gpos='git push origin staging' +alias gprod='git pull --rebase origin develop' +alias gprom='git pull --rebase origin main' +alias gpros='git pull --rebase origin staging' +alias gprud='git pull --rebase upstream develop' +alias gprum='git pull --rebase upstream main' +alias gprus='git pull --rebase upstream staging' +alias gpud='git push upstream develop' +alias gpufl='git push --force-with-lease upstream' +alias gpum='git push upstream main' +alias gpus='git push upstream staging' +alias gr='git rm' +alias gra='git rebase --abort' +alias grc='git rebase --continue' +alias grd='git rebase develop' +alias gri='git rebase -i' +alias grm='git rebase main' +alias grs='git rebase staging' +alias gsl='git stash list' +alias gslog='git log --graph --abbrev-commit --decorate --date=relative --format=format:"%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)" --all' +alias gsp='git stash pop' +alias gss='git stash save' +alias gst='git status -sb' +alias nxb='nix build' +alias nxd='nix develop' +alias nxf='nix flake' +alias nxpu='nix-prefetch-url --unpack' +alias nxr='nix run' +alias nxs='nix search' +alias tb='toggle-background' + +alias ls='ls --color=auto' +alias l='lla' +alias lla='ll -a' +alias llt='ll --tree' +alias la='ls -a' +alias ll='ls -l' +alias lt='ls --tree' + +# alias e='nvim' +alias e='emacs -nw' + +# Teaching +export CS144_ADMIN="${HOME}/TA/cs144/cs144-win-24-admin" +export CS144_GRADERS="${HOME}/TA/cs144/cs144-win-24-graders" +export CS144_GIT_ADMIN="${HOME}/TA/cs144/cs144-win-24-admin-repo" + +# Personal +export DIRPAPERS="$HOME/Ucare/DIR-PAPERS" +export ALL_PDF_FILES="$HOME/PDFs" +export RS_PERSONAL_DIR="$HOME/Personal" +export RS_BOOKMARKS_FILE="$RS_PERSONAL_DIR/bookmarks.md" +export RS_BLOG_NOTES="$RS_PERSONAL_DIR/blogs" +export RS_MEETING_NOTES="$RS_PERSONAL_DIR/meetings" +export RS_PROJECT_NOTES="$RS_PERSONAL_DIR/projects" +export RS_NOTES_DIRS="${RS_BLOG_NOTES} ${RS_PROJECT_NOTES} ${RS_MEETING_NOTES}" +export RS_NOTES_EXTS="md txt" +export RS_TODO_FILE="$RS_PERSONAL_DIR/todo.md" +export PYTHONPATH="$HOME/libs/python:$PYTHONPATH" +alias ep='e -nw $RS_PERSONAL_DIR' diff --git a/src/home/shell/default.nix b/src/home/shell/default.nix index 95a65a1..53aa886 100644 --- a/src/home/shell/default.nix +++ b/src/home/shell/default.nix @@ -5,8 +5,10 @@ ./bash.nix ./direnv.nix ./fzf.nix + ./lazygit.nix ./ripgrep.nix ./shell.nix + ./tmux ./zoxide.nix ]; } diff --git a/src/home/shell/lazygit.nix b/src/home/shell/lazygit.nix new file mode 100644 index 0000000..681cbbf --- /dev/null +++ b/src/home/shell/lazygit.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: + +{ + programs.lazygit = { + enable = true; + }; +} diff --git a/src/home/shell/shell.nix b/src/home/shell/shell.nix index c0abe57..6d51bd6 100644 --- a/src/home/shell/shell.nix +++ b/src/home/shell/shell.nix @@ -1,4 +1,4 @@ -{ lib, pkgs, ... }: +{ config, lib, pkgs, ... }: { options.custom = with lib; { @@ -27,6 +27,23 @@ } ''; }; + additionalSourceFile = mkOption { + type = types.nullOr types.path; + default = ./custom.sh; + }; + }; + }; + + config = { + programs.bash = lib.mkIf (config.custom.shell.additionalSourceFile != null) { + bashrcExtra = lib.mkAfter '' + source ${config.custom.shell.additionalSourceFile} + ''; + }; + programs.zsh = lib.mkIf (config.custom.shell.additionalSourceFile != null) { + initExtra = lib.mkAfter '' + source ${config.custom.shell.additionalSourceFile} + ''; }; }; } diff --git a/src/home/shell/tmux/default.nix b/src/home/shell/tmux/default.nix new file mode 100644 index 0000000..57df3d8 --- /dev/null +++ b/src/home/shell/tmux/default.nix @@ -0,0 +1,17 @@ +{ pkgs, ... }: + +{ + home.packages = with pkgs; [ + tmux + ]; + + xdg.configFile."tmux/tmux.conf" = { + source = ./tmux.conf; + }; + + custom.persist = { + home.directories = [ + ".tmux" + ]; + }; +} diff --git a/src/home/shell/tmux/tmux.conf b/src/home/shell/tmux/tmux.conf new file mode 100644 index 0000000..6b0ceff --- /dev/null +++ b/src/home/shell/tmux/tmux.conf @@ -0,0 +1,184 @@ +set -g base-index 1 +setw -g pane-base-index 1 +set -g default-shell "$SHELL" + +set -g status-keys vi +set -g mode-keys vi + +# rebind main key: C-Space +unbind C-b +unbind C-Space +set -g prefix "C-Space" +bind -N "Send the prefix key through to the application" \ + "C-Space" send-prefix + +set -g mouse on +setw -g aggressive-resize off +setw -g clock-mode-style 12 +set -s escape-time 500 +set -g history-limit 2000 + +set-option -g detach-on-destroy on +set-option -g status-position bottom # top + +set-option -g default-terminal 'screen-256color' +set-option -sa terminal-features ',xterm-kitty:RGB' +set -ga terminal-overrides ',xterm*:Tc' + +# https://github.com/folke/tokyonight.nvim#making-undercurls-work-properly-in-tmux +set -as terminal-overrides ',*:Smulx=\E[4::%p1%dm' # undercurl support +set -as terminal-overrides ',*:Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m' + +setw -g automatic-rename on # rename window to reflect current program +set -g renumber-windows on # renumber windows when a window is closed + +set -g set-titles on # set terminal title + +set -g display-panes-time 800 # slightly longer pane indicators display time +set -g display-time 1000 # slightly longer status messages display time + +# bind -n C-l send-keys C-l \; run 'sleep 1.1' \; clear-history + +set -gq allow-passthrough all +set -ga update-environment TERM +set -ga update-environment TERM_PROGRAM +set -ag update-environment "SSH_TTY" + +# activity +set -g monitor-activity on +set -g visual-activity off + +# create session +bind C-c command-prompt -p "New Session:" "new-session -A -s '%%'" + +# kill session +bind C-k confirm kill-session + +# reload tmux conf +bind r source-file "$HOME/.config/tmux/tmux.conf" + +# find session +bind C-f command-prompt -p find-session 'switch-client -t %%' + +# create new window +bind c new-window -c "#{pane_current_path}" + +# split current window horizontally +bind - split-window -v -c "#{pane_current_path}" + +# split current window vertically +bind _ split-window -h -c "#{pane_current_path}" + +# Zoxide integration +bind-key t run-shell "t" +bind-key T run-shell "tz" + +# pane navigation +bind -r h select-pane -L # move left +bind -r j select-pane -D # move down +bind -r k select-pane -U # move up +bind -r l select-pane -R # move right +bind > swap-pane -D # swap current pane with the next one +bind < swap-pane -U # swap current pane with the previous one + +# pane resizing +bind -r H resize-pane -L 2 +bind -r J resize-pane -D 2 +bind -r K resize-pane -U 2 +bind -r L resize-pane -R 2 + +# window navigation +unbind n +unbind p +bind -r C-h previous-window # select previous window +bind -r C-l next-window # select next window +bind Tab last-window # move to last active window + +# copy mode +set -g set-clipboard on +bind Enter copy-mode # enter copy mode + +run -b 'tmux bind -t vi-copy v begin-selection 2> /dev/null || true' + +run -b 'tmux bind -T copy-mode-vi v send -X begin-selection 2> /dev/null || true' +run -b 'tmux bind -t vi-copy C-v rectangle-toggle 2> /dev/null || true' +run -b 'tmux bind -T copy-mode-vi C-v send -X rectangle-toggle 2> /dev/null || true' +run -b 'tmux bind -t vi-copy y copy-selection 2> /dev/null || true' +# run -b 'tmux bind -T copy-mode-vi y send -X copy-selection-and-cancel 2> /dev/null || true' +run -b 'tmux bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard" 2> /dev/null || true' +run -b 'tmux bind -t vi-copy Escape cancel 2> /dev/null || true' +run -b 'tmux bind -T copy-mode-vi Escape send -X cancel 2> /dev/null || true' +run -b 'tmux bind -t vi-copy H start-of-line 2> /dev/null || true' +run -b 'tmux bind -T copy-mode-vi H send -X start-of-line 2> /dev/null || true' +run -b 'tmux bind -t vi-copy L end-of-line 2> /dev/null || true' +run -b 'tmux bind -T copy-mode-vi L send -X end-of-line 2> /dev/null || true' + +# copy to X11 clipboard +if -b 'command -v xsel > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | xsel -i -b"' +if -b '! command -v xsel > /dev/null 2>&1 && command -v xclip > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | xclip -i -selection clipboard >/dev/null 2>&1"' +# copy to macOS clipboard +if -b 'command -v pbcopy > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | pbcopy"' +if -b 'command -v reattach-to-user-namespace > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | reattach-to-user-namespace pbcopy"' +# copy to Windows clipboard +if -b 'command -v clip.exe > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | clip.exe"' +if -b '[ -c /dev/clipboard ]' 'bind y run -b "tmux save-buffer - > /dev/clipboard"' + +# status line +set -g status "on" +set -g status-justify "left" + +set -g status-left-length "100" +set -g status-right-length "100" + +set -g status-left-style NONE +set -g status-right-style NONE + +# set -g status-style bg=default +set -g status-right "#H" +# set -g status-interval 10 # redraw status line every 10 seconds + +# https://github.com/christoomey/vim-tmux-navigator +# disable wrapping +# is_vim="ps -o state= -o comm= -t '#{pane_tty}' \ +# | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?)(diff)?$'" +# bind-key -n 'C-h' if-shell "$is_vim" { send-keys C-h } { if-shell -F '#{pane_at_left}' {} { select-pane -L } } +# bind-key -n 'C-j' if-shell "$is_vim" { send-keys C-j } { if-shell -F '#{pane_at_bottom}' {} { select-pane -D } } +# bind-key -n 'C-k' if-shell "$is_vim" { send-keys C-k } { if-shell -F '#{pane_at_top}' {} { select-pane -U } } +# bind-key -n 'C-l' if-shell "$is_vim" { send-keys C-l } { if-shell -F '#{pane_at_right}' {} { select-pane -R } } + +# bind-key -T copy-mode-vi 'C-h' if-shell -F '#{pane_at_left}' {} { select-pane -L } +# bind-key -T copy-mode-vi 'C-j' if-shell -F '#{pane_at_bottom}' {} { select-pane -D } +# bind-key -T copy-mode-vi 'C-k' if-shell -F '#{pane_at_top}' {} { select-pane -U } +# bind-key -T copy-mode-vi 'C-l' if-shell -F '#{pane_at_right}' {} { select-pane -R } + +# https://github.com/laishulu/emacs-tmux-pane/blob/master/tmux-pane.tmux +version_pat='s/^tmux[^0-9]*([.0-9]+).*/\1/p' + +is_vim_emacs='echo "#{pane_current_command}" | \ + grep -iqE "((^|\/)g?(view|n?vim?x?)(diff)?$)|emacs"' + +# enable in root key table +bind-key -n C-h if-shell "$is_vim_emacs" "send-keys C-h" "select-pane -L" +bind-key -n C-j if-shell "$is_vim_emacs" "send-keys C-j" "select-pane -D" +bind-key -n C-k if-shell "$is_vim_emacs" "send-keys C-k" "select-pane -U" +bind-key -n C-l if-shell "$is_vim_emacs" "send-keys C-l" "select-pane -R" + +tmux_version="$(tmux -V | sed -En "$version_pat")" +setenv -g tmux_version "$tmux_version" + +#echo "{'version' : '${tmux_version}', 'sed_pat' : '${version_pat}' }" > ~/.tmux_version.json + +if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \ + "bind-key -n 'C-\\' if-shell \"$is_vim_emacs\" 'send-keys C-\\' 'select-pane -l'" +if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \ + "bind-key -n 'C-\\' if-shell \"$is_vim_emacs\" 'send-keys C-\\\\' 'select-pane -l'" + +bind-key -T copy-mode-vi 'C-h' if-shell "$is_vim_emacs" "send-keys C-h" "select-pane -L" +bind-key -T copy-mode-vi 'C-j' if-shell "$is_vim_emacs" "send-keys C-j" "select-pane -D" +bind-key -T copy-mode-vi 'C-k' if-shell "$is_vim_emacs" "send-keys C-k" "select-pane -U" +bind-key -T copy-mode-vi 'C-l' if-shell "$is_vim_emacs" "send-keys C-l" "select-pane -R" +bind-key -T copy-mode-vi 'C-\' if-shell "$is_vim_emacs" "send-keys C-\\\\" "select-pane -l" + +# Browse tmux pane in nvim +# bind [ run-shell 'kitty @ kitten ~/.local/share/nvim/lazy/kitty-scrollback.nvim/python/kitty_scrollback_nvim.py --env "TMUX=$TMUX" --env "TMUX_PANE=#{pane_id}"' +bind [ run-shell 'tmux-vim-pager'