summaryrefslogtreecommitdiff
path: root/tw/home/files/prompt.zsh
blob: e582eb9bf81a32b8d5638103ddf10b38c9a7ae2d (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# fast prompt theme
# MIT License
# Based on lean prompt theme by Miek Gieben: https://github.com/miekg/lean
# Based on Pure by Sindre Sorhus: https://github.com/sindresorhus/pure

: ${PROMPT_FAST_NOTITLE=0} ${PROMPT_FAST_VIMODE=y} ${PROMPT_FAST_VIMODE_FORMAT=%S} ${PROMPT_FAST_CMD_MAX_EXEC_TIME=5}

prompt_fast_help () {
  cat << EOF
This is a one line prompt that tries to stay out of your face. It utilizes the
left side prompt for most information, like the CWD. When the exit code of a
process isn't zero the prompt turns red and the exit code is displayed. If a
process takes more than 5 (default) seconds to run the total running time is
shown in the next prompt.

Configuration:

PROMPT_FAST_VIMODE: used to determine whether or not to display indicator (default on)
PROMPT_FAST_VIMODE_FORMAT: Defaults to "%S"
PROMPT_FAST_NOTITLE: used to determine whether or not to set the title, set to 0
 by default. Set it to your own condition, make it 1 when you don't want the
 title set.
PROMPT_FAST_CMD_MAX_EXEC_TIME: if a commands takes more than this many seconds,
 show how long it took
EOF
}

# fastest possible way to check if repo is dirty
prompt_fast_git_dirty () {
  # check if we're in a git repo
  git rev-parse --is-inside-work-tree &>/dev/null &&
    # check if it's dirty
    [ -n "$(git status --porcelain --ignore-submodules -uno 2>/dev/null | head -n 1)" ] &&
    echo ' +'
}

# displays the exec time of the last command if set threshold was exceeded
prompt_fast_cmd_exec_time () {
  [ -n "$cmd_timestamp" ] || return
  integer elapsed=$EPOCHSECONDS-$cmd_timestamp
  ((elapsed > PROMPT_FAST_CMD_MAX_EXEC_TIME)) || return
  # turns seconds into human readable time, 165392 => 1d 21h 56m 32s
  ((elapsed > 60 * 60 * 24)) && print -f '%dd ' $((elapsed / 60 / 60 / 24))
  ((elapsed > 60 * 60))      && print -f '%dh ' $((elapsed / 60 / 60 % 24))
  ((elapsed > 60))           && print -f '%dm ' $((elapsed / 60 % 60))
  ((elapsed > 0))            && print -f '%ds ' $((elapsed % 60))
}

prompt_fast_set_title () {
  # shows the current tty and dir and executed command in the title when a process is active
  print -Pn '\e]0;'
  tr -dc '[:print:]' <<< "$1"
  print -Pn ' - %~$prompt_fast_title_host\a'
}

prompt_fast_preexec () {
  cmd_timestamp=$EPOCHSECONDS
  ((PROMPT_FAST_NOTITLE != 1)) && prompt_fast_set_title "$1"
}

prompt_fast_pwd () {
  local fast_path=$(print -Pn '%~')
  local components=${#fast_path//[^\/]}  # this counts the initial /
  # Only abbreviate as /1/…/2/3 if we have something to cut out between 1 and 2!
  # /1/2/3 -> /1/…/2/3 makes no sense.
  if ((components > 3 && $#fast_path > ${PROMPT_FAST_PATH_FRACTION:-0.33} * COLUMNS)); then
    print -Pn '%-1~/…/%2/'
  else
    print "$fast_path"
  fi
}

prompt_fast_precmd () {
  ((PROMPT_FAST_NOTITLE != 1)) && print -Pn "\\e]0;%~$prompt_fast_title_host\a"

  vcs_info

  local a j jobs=()
  for a j (${(kv)jobstates}); do
    i=${${(@s,:,)j}[2]}
    jobs+=($a${i//[^+-]/})
  done
  # print with [ ] and space separated
  local prompt_fast_jobs=${jobs:+%F{8}[${(j: :)jobs}] }
  local vimode=${${KEYMAP/vicmd/${PROMPT_FAST_VIMODE:+$PROMPT_FAST_VIMODE_FORMAT}}/(main|viins)/}

  setopt promptsubst
  local vcs_info_str='$vcs_info_msg_0_' # avoid https://github.com/njhartwell/pw3nage
  local genv_short=${GUIX_ENVIRONMENT##*/}
  genv_short=${genv_short:0:5}
  local italic=$'\e[03m'
  PROMPT="${TMUX+%F{yellow\}t }${GUIX_ENVIRONMENT+%F{11\}${genv_short}%u }$prompt_fast_jobs$prompt_fast_host%F{blue}$(prompt_fast_pwd)%F{8}$vcs_info_str$(prompt_fast_git_dirty) %F{yellow}$(prompt_fast_cmd_exec_time)%(?..%B%F{red}%?%f%b )%(?.%F{blue}.%B%F{red})$vimode%#%s%u%f%k%b "

  unset cmd_timestamp # reset value since `preexec` isn't always triggered
}

zle-keymap-select () {
  prompt_fast_precmd
  zle reset-prompt
}

prompt_fast_setup () {
  prompt_opts=(cr percent sp subst)

  #zmodload zsh/datetime   # for strftime -- appears unused
  autoload -Uz add-zsh-hook
  autoload -Uz vcs_info

  [ -z "$PROMPT_FAST_VIMODE" ] && zle -N zle-keymap-select

  add-zsh-hook precmd prompt_fast_precmd
  add-zsh-hook preexec prompt_fast_preexec

  zstyle ':vcs_info:*' enable git
  zstyle ':vcs_info:git*' formats ' %b'
  zstyle ':vcs_info:git*' actionformats ' %b|%a'

  if [ -n "$SSH_CONNECTION" ]; then
    prompt_fast_title_host=' - %n@%m'
    prompt_fast_host='%(!.%F{red}.%F{green})%n@%m:'
  else
    prompt_fast_title_host='%(!. - %n@%m.)'
    prompt_fast_host='%(!.%F{red}%n@%m:.)'
  fi

  return 0
}

if [ "$TERM" = dumb ]; then
  # Emacs Tramp needs a simple prompt when connecting over SSH.
  PS1='$ '
else
  prompt_fast_setup "$@"
fi