about summary refs log tree commit diff
path: root/home/shell
diff options
context:
space:
mode:
authorFranck Cuny <franck@fcuny.net>2022-06-19 15:57:45 -0700
committerFranck Cuny <franck@fcuny.net>2022-06-20 14:39:35 -0700
commitb5c428822468b9a2dfb00a673c39e809f4ac0651 (patch)
tree54e2190f9b20ce11827d0d5b10da2a96c135437a /home/shell
parentfeat(tools/seqstat): add a tool to report stats about a sequence (diff)
downloadworld-b5c428822468b9a2dfb00a673c39e809f4ac0651.tar.gz
ref(home/shell): make it easier to share common things between shells
I'm considering trying again fish, and there are a number of things that
should be common between zsh and fish (aliases, environment variables,
...).

Instead of duplicating these settings multiple time, I'm consolidating
the shell configurations under `home/shell`, and I can set the shell I
want to use with `my.home.shell.name`.

The first step is to move the modules for fish and zsh under
`home/shell`, add an interface to pick which one I want to use, and
modify the `host/home.nix` configuration to keep using zsh with the new
interface.

Change-Id: Idb66b1a6fcc11a6eeaf5fd2d32dd3698d2d85bdf
Reviewed-on: https://cl.fcuny.net/c/world/+/455
Tested-by: CI
Reviewed-by: Franck Cuny <franck@fcuny.net>
Diffstat (limited to 'home/shell')
-rw-r--r--home/shell/default.nix16
-rw-r--r--home/shell/fish/default.nix29
-rw-r--r--home/shell/zsh/completion-style.zsh34
-rw-r--r--home/shell/zsh/default.nix54
-rw-r--r--home/shell/zsh/gerrit.zsh5
-rw-r--r--home/shell/zsh/options.zsh27
-rw-r--r--home/shell/zsh/prompt.zsh11
-rw-r--r--home/shell/zsh/sway.zsh3
-rw-r--r--home/shell/zsh/tmux.zsh9
9 files changed, 188 insertions, 0 deletions
diff --git a/home/shell/default.nix b/home/shell/default.nix
new file mode 100644
index 0000000..35a6275
--- /dev/null
+++ b/home/shell/default.nix
@@ -0,0 +1,16 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let cfg = config.my.home.shell;
+in
+{
+  options.my.home.shell = {
+    name = mkOption {
+      default = "zsh";
+      type = types.enum [ "fish" "zsh" ];
+      example = "zsh";
+    };
+  };
+
+  imports = [ ./fish ./zsh ];
+}
diff --git a/home/shell/fish/default.nix b/home/shell/fish/default.nix
new file mode 100644
index 0000000..3a21b24
--- /dev/null
+++ b/home/shell/fish/default.nix
@@ -0,0 +1,29 @@
+{ config, lib, pkgs, ... }:
+let
+  cfg = config.my.home.shell;
+  swayEnabled = config.my.home.wm.windowManager == "sway";
+in
+{
+  config = lib.mkIf (cfg.name == "fish") {
+    programs.fish = {
+      enable = true;
+      interactiveShellInit = ''
+        set fish_greeting
+
+        # Tmux on terminal start, unless we're in a SSH connection
+        if status is-interactive
+          if test -z "$SSH_CONNECTION"
+            if not tmux has-session 2>/dev/null; or test -z "$TMUX"
+              exec tmux new-session -A -s 0
+            end
+          end
+        end
+      '';
+      loginShellInit = lib.mkIf swayEnabled ''
+        if test -z "$DISPLAY"; and test (tty) = "/dev/tty1"
+          exec sway
+        end
+      '';
+    };
+  };
+}
diff --git a/home/shell/zsh/completion-style.zsh b/home/shell/zsh/completion-style.zsh
new file mode 100644
index 0000000..32bd6f4
--- /dev/null
+++ b/home/shell/zsh/completion-style.zsh
@@ -0,0 +1,34 @@
+# Style the completion a bit
+zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
+
+# Show a prompt on selection
+zstyle ':completion:*' select-prompt '%SScrolling active: current selection at %p%s'
+
+# Use arrow keys in completion list
+zstyle ':completion:*' menu select
+
+# Group results by category
+zstyle ':completion:*' group-name ''
+
+# Keep directories and files separated
+zstyle ':completion:*' list-dirs-first true
+
+# Add colors to processes for kill completion
+zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
+
+# match uppercase from lowercase
+zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
+
+# Filename suffixes to ignore during completion (except after rm command)
+zstyle ':completion:*:*:(^rm):*:*files' ignored-patterns '*?.old'
+
+# command for process lists, the local web server details and host completion
+# on processes completion complete all user processes
+zstyle ':completion:*:processes' command 'ps -au$USER'
+
+# Completion formatting and messages
+zstyle ':completion:*' verbose yes
+zstyle ':completion:*:descriptions' format '%B%d%b'
+zstyle ':completion:*:messages' format '%d'
+zstyle ':completion:*:warnings' format 'No matches for: %d'
+zstyle ':completion:*:corrections' format '%B%d (errors: %e)%b'
diff --git a/home/shell/zsh/default.nix b/home/shell/zsh/default.nix
new file mode 100644
index 0000000..14ddd6c
--- /dev/null
+++ b/home/shell/zsh/default.nix
@@ -0,0 +1,54 @@
+{ config, pkgs, lib, ... }:
+let cfg = config.my.home.shell;
+in
+{
+  config = lib.mkIf (cfg.name == "zsh") {
+    home.packages = with pkgs; [ zsh-completions ];
+
+    programs.zsh = {
+      enable = true;
+      dotDir = ".config/zsh";
+      enableCompletion = true;
+
+      history = {
+        size = 500000;
+        save = 500000;
+        extended = false;
+        ignoreSpace = true;
+        ignoreDups = true;
+        share = false;
+        # see
+        # https://github.com/nix-community/home-manager/blob/32a7da69dc53c9eb5ad0675eb7fdc58f7fe35272/modules/programs/zsh.nix#L537
+        path = ".local/share/zsh/zsh_history";
+      };
+
+      localVariables = {
+        # Print timing statistics for everything which takes longer than 5 seconds of
+        # user + system time.
+        REPORTTIME = 5;
+      };
+
+      shellAliases = {
+        ll = "ls -l --color=auto";
+        lt = "ls -ltrh --color=auto";
+      };
+
+      defaultKeymap = "emacs";
+
+      # the order matters for sway.zsh: I want to load it first
+      # to start the session if I log on a machine where it's
+      # available.
+      # it can't be loaded with `initExtraFirst` because the session
+      # variables from home-manager are not set yet otherwise (and I
+      # need them for things like firefox or emacs).
+      initExtra = lib.concatMapStrings builtins.readFile [
+        ./sway.zsh
+        ./completion-style.zsh
+        ./gerrit.zsh
+        ./options.zsh
+        ./prompt.zsh
+        ./tmux.zsh
+      ];
+    };
+  };
+}
diff --git a/home/shell/zsh/gerrit.zsh b/home/shell/zsh/gerrit.zsh
new file mode 100644
index 0000000..9766b2f
--- /dev/null
+++ b/home/shell/zsh/gerrit.zsh
@@ -0,0 +1,5 @@
+function rgerrit() {
+  # gerrit runs on tahoe, and we ssh to it through its tailscale
+  # network interface.
+  ssh $(tailscale status --json | jq -r '.Peer | map(select(.HostName == "tahoe"))[0].TailscaleIPs[0]') -p 29418 gerrit $@
+}
diff --git a/home/shell/zsh/options.zsh b/home/shell/zsh/options.zsh
new file mode 100644
index 0000000..6d39bc1
--- /dev/null
+++ b/home/shell/zsh/options.zsh
@@ -0,0 +1,27 @@
+# Show an error when a globbing expansion doesn't find any match
+setopt nomatch
+
+# List on ambiguous completion and Insert first match immediately
+setopt autolist menucomplete
+
+# Use pushd when cd-ing around
+setopt autopushd pushdminus pushdsilent
+
+# Use single quotes in string without the weird escape tricks
+setopt rcquotes
+
+# Single word commands can resume an existing job
+setopt autoresume
+
+# Append commands to history as they are exectuted
+setopt inc_append_history_time
+
+# Remove useless whitespace from commands
+setopt hist_reduce_blanks
+
+# Those options aren't wanted
+unsetopt beep extendedglob notify
+
+# word select works like in bash
+autoload -U select-word-style
+select-word-style bash
diff --git a/home/shell/zsh/prompt.zsh b/home/shell/zsh/prompt.zsh
new file mode 100644
index 0000000..1c21d4b
--- /dev/null
+++ b/home/shell/zsh/prompt.zsh
@@ -0,0 +1,11 @@
+setopt prompt_subst
+
+PROMPT='%K{cyan}%F{black}%m%k%f %~ %% '
+
+# For tramp (emacs).
+if [ "$TERM" = "dumb" ]; then
+  unset PROMPT
+  PS1='$ '
+  unsetopt zle
+fi
+
diff --git a/home/shell/zsh/sway.zsh b/home/shell/zsh/sway.zsh
new file mode 100644
index 0000000..69d5103
--- /dev/null
+++ b/home/shell/zsh/sway.zsh
@@ -0,0 +1,3 @@
+if [ -z $DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
+    exec sway
+fi
diff --git a/home/shell/zsh/tmux.zsh b/home/shell/zsh/tmux.zsh
new file mode 100644
index 0000000..97944f5
--- /dev/null
+++ b/home/shell/zsh/tmux.zsh
@@ -0,0 +1,9 @@
+# If we're not in an ssh connection, and tmux is installed, and we're
+# not already in a tmux session, attach to the session named
+# 'default', and if the session does not exist, start one named
+# 'default'
+if [ -z "$SSH_CONNECTION" ]; then
+  if command -v tmux &> /dev/null && [ -z "$TMUX" ]; then
+    tmux attach -t default || tmux new -s default
+  fi
+fi