terminal: Create module to consolidate term utils

Terminal application, a variety of shell configurations, terminal file
and session management all consolidated in one place.
This commit is contained in:
Marty Oehme 2023-01-07 16:11:40 +01:00
parent 2e0c992a54
commit 9781b26b22
Signed by: Marty
GPG key ID: 73BA40D5AFAF49C9
31 changed files with 0 additions and 0 deletions

43
terminal/.bash_profile Normal file
View file

@ -0,0 +1,43 @@
#!/usr/bin/env bash
#
# ~/.bash_profile
#
# shellcheck disable=SC1090
# ensure bash is set up for its initial sourcing
export XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-"$HOME/.config"}
# load global sh env vars
[ -f "$XDG_CONFIG_HOME/sh/env" ] && source "$XDG_CONFIG_HOME/sh/env"
if [ -d "$XDG_CONFIG_HOME/sh/env.d" ]; then
for _env in "$XDG_CONFIG_HOME/sh/env.d"/*.sh; do
. "$_env"
done
unset _env
fi
[ -f "$XDG_CONFIG_HOME/bash/env" ] && source "$XDG_CONFIG_HOME/bash/env"
if [ -d "$XDG_CONFIG_HOME/bash/env.d" ]; then
for _env in "$XDG_CONFIG_HOME/bash/env.d"/*.sh; do
. "$_env"
done
unset _env
fi
# load profile files vars
[ -f "$XDG_CONFIG_HOME/sh/profile" ] && source "$XDG_CONFIG_HOME/sh/profile"
if [ -d "$XDG_CONFIG_HOME/sh/profile.d" ]; then
for _profile in "$XDG_CONFIG_HOME/sh/profile.d"/*.sh; do
. "$_profile"
done
unset _profile
fi
[ -f "$XDG_CONFIG_HOME/bash/profile" ] && source "$XDG_CONFIG_HOME/bash/profile"
if [ -d "$XDG_CONFIG_HOME/bash/profile.d" ]; then
for _profile in "$XDG_CONFIG_HOME/bash/profile.d"/*.sh; do
. "$_profile"
done
unset _profile
fi
# shellcheck disable=SC1090
[[ -f ~/.bashrc ]] && . ~/.bashrc

28
terminal/.bashrc Normal file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env bash
#
# ~/.bashrc
#
# shellcheck disable=SC1090
CONFDIR="${XDG_CONFIG_HOME:-$HOME/.config}"
# If not running interactively, don't do anything
[[ $- != *i* ]] && return
[ -f "$CONFDIR/sh/alias" ] && source "$CONFDIR/sh/alias"
# load additional aliases
if [ -d "$CONFDIR/sh/alias.d" ]; then
for _alias in "$CONFDIR/sh/alias.d"/*.sh; do
. "$_alias"
done
unset _alias
fi
if [ -d "$CONFDIR/bash/alias.d" ]; then
for _alias in "$CONFDIR/bash/alias.d"/*.sh; do
. "$_alias"
done
unset _alias
fi
alias ls='ls --color=auto'
PS1='[\u@\h \W]\$ '

View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
export HISTFILE="${XDG_STATE_HOME}/bash/history"
# bashrc, bash_profile, bash_logout currently unsupported
# see https://savannah.gnu.org/support/?108134

View file

@ -0,0 +1,57 @@
#!/usr/bin/env sh
exist() { type "$1" >/dev/null 2>&1; }
# alias tmux to follow xdg-specification
# shellcheck disable=2139
alias tmux="tmux -f ${XDG_CONFIG_HOME:-$HOME/.config}/tmux/tmux.conf"
# fzf
if exist fzf; then
# fzf select a tmux session to connect to, with pane preview
alias tm='_fzf_tmux_attach_start_session'
alias tl=tm
else
alias tm='tmux_attach_start'
# show a list of running tmux sessions
alias tl='tmux list-sessions -F "#{session_name}" 2>/dev/null '
fi
_fzf_tmux_list_sessions() {
tmux list-sessions -F "#{session_name}" 2>/dev/null | fzf \
--layout=reverse \
--height=50% \
--border \
--prompt="Session> " \
--preview="tmux_pane_tree {}" \
--preview-window=right:80% \
--print-query
}
_fzf_tmux_attach_start_session() {
if [ -z "$1" ]; then
result=$(_fzf_tmux_list_sessions)
case "$?" in
0)
# found a session, attaching
tmux_attach_start "$(echo "$result" | tail --lines=1)"
;;
1)
# did not find a session, creating
result=$(echo "$result" | head --lines=1)
# if . was only thing entered, create one for current dir
if [ "$result" = "." ]; then
tmux_attach_start
# create for query name
else
tmux_attach_start "$result"
fi
;;
esac
else
tmux_attach_start "$1"
fi
}
unset choice
unset -f exist

View file

@ -0,0 +1,13 @@
rename-window dot-git
send-keys "cd ~/.dotfiles; while true; do [[ -z $(git status -s) ]] && { fd -t f --hidden | entr -cd tea issue ;} || { fd -t f --hidden | entr -cd git -c color.ui=always diff ;} ; done"
split-window -h "cd ~/.dotfiles; while true; do fd -t f --hidden --exclude .git/objects | entr -cd git -c color.ui=always status; done"
split-window -v
send-keys "cd ~/.dotfiles; clear" C-m L C-m
select-pane -t 1
split-window -v "cd ~/.dotfiles; while true; do fd -t f --hidden --exclude .git/objects | entr -cd git -c color.ui=always log --graph --date=short --decorate --oneline --all --remotes; done"
select-pane -t 4
new-window -n code
send-keys "cd ~/.dotfiles; v ." C-m zo
new-window -n test
select-window -t 1
attach-session -t . -c ~/.dotfiles

View file

@ -0,0 +1,9 @@
rename-window server
send-keys "mopidy" C-m
new-window -n player
send-keys "ncmpcpp" C-m
new-window -n mixer
send-keys "pulsemixer" C-m
new-window -n bluetooth
send-keys "bluetoothctl" C-m
select-window -t 2

View file

@ -0,0 +1,7 @@
rename-window notes
send-keys vm Space $WIKIROOT Space $LIBRARY C-m
new-window -n notepad
send-keys cd Space $WIKIROOT C-m
send-keys v C-m
send-keys Space w w
attach-session -t . -c $WIKIROOT

View file

@ -0,0 +1,10 @@
rename-window mail
send-keys "neomutt" C-m
new-window -n news
send-keys "newsboat" C-m
split-window -h
send-keys "tut" C-m
new-window -n matrix
send-keys "gomuks" C-m
new-window -n signal
send-keys "siggo" C-m

View file

@ -0,0 +1,4 @@
rename-window stats
send-keys "cd ~/documents/records; v workout.md" C-m
new-window -n routine
send-keys "cd ~/documents/records; sc-im workout.csv" C-m

View file

@ -0,0 +1,15 @@
rename-window focus
send-keys tasksh C-m "+TODAY" C-m
new-window -n dash
send-keys "cd ${XDG_DATA_HOME:-~/.local/share}/task/; fd . | entr -c task next" C-m
split-window -h -l 71
send-keys "cd ${XDG_DATA_HOME:-~/.local/share}/task/; fd . | entr -c task summary" C-m
split-window -v "cd ${XDG_DATA_HOME:-~/.local/share}/task/; fd . | entr -c task status:pending or +ACTIVE burndown"
select-pane -t 1
split-window -v -l 5
send-keys "t" Space
new-window -n journal
send-keys "calcurse" C-m
split-window -h -l 35% "ls ~/documents/records/jrnl.md | entr -c jrnl -5"
split-window -v -l 10%
select-window -t 2

View file

@ -0,0 +1,183 @@
# Layout of this conf file:
# 1. Global Settings
# 2. Plugins
# 3. Keybinds
# 4. Theme
# For rapid change prototyping, disabled normally:
# bind-key r source-file ~/.config/tmux/tmux.conf \; display-message "config reloaded."
######################
### 1. GLOBAL SETTINGS
######################
# show that activity happens but don't display a huge 'activity happening' notification
setw -g monitor-activity on
set -g visual-activity off
# Start counting windows and panes at 1
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
# Terminal improvements
set-window-option -g automatic-rename on
set-option -g set-titles on
set -g mouse on
# allow truecolor support
set -g default-terminal 'xterm-256color'
set -ga terminal-overrides ',xterm-256color:Tc'
set -g status-keys vi
set-window-option -g mode-keys vi
set -g history-limit 10000
# Screen size is based on the smallest client looking at the current windows, not the smallest
# client connected to the overall session. If two clients are connected to the same session but not
# looking at the same window, why would they care about each others screen size?
setw -g aggressive-resize on
# No delay for escape key press
set -sg escape-time 0
# to enable autoread option in neovim
set-option -g focus-events on
####################
## 2. PLUGINS ##
####################
set -g @tpm_plugins ' \
tmux-plugins/tpm \
tmux-plugins/tmux-sensible \
christoomey/vim-tmux-navigator \
Morantron/tmux-fingers \
'
set -g @fingers-key F
# make sure tpm is installed
if-shell "test ! -d $TMUX_PLUGIN_MANAGER_PATH/tpm" \
"run 'git clone https://github.com/tmux-plugins/tpm $TMUX_PLUGIN_MANAGER_PATH/tpm && $TMUX_PLUGIN_MANAGER_PATH/tpm/bin/install_plugins'" \
# optinally add this to install plugins on each start -- adds small lag to startup
# "run-shell $TMUX_PLUGIN_MANAGER_PATH/tpm/bin/install_plugins"
#####################
## 3. KEYBINDINGS ##
#####################
# Unbind some defaults
unbind '"'
unbind %
# Custom modifier key
set -g prefix C-a
unbind-key C-b
bind-key -r C-a send-prefix
# Window Navigation - Prefix + Vim Keys
bind-key -r C-h select-window -t :-
bind-key -r C-l select-window -t :+
# Resize Panes
bind-key -r H resize-pane -L 3
bind-key -r J resize-pane -D 1
bind-key -r K resize-pane -U 1
bind-key -r L resize-pane -R 3
bind-key -r C-H resize-pane -L 10
bind-key -r C-J resize-pane -D 5
bind-key -r C-K resize-pane -U 5
bind-key -r C-L resize-pane -R 10
# Send Pane to a new window (but stay on current window), join it back into the current window
bind-key B break-pane -d
bind-key C-b command-prompt -p "join pane from: " "join-pane -h -s '%%'"
# Swap panes within the current window (swaps pane # entered with currently selected pane)
bind-key b display-panes\; command-prompt -p "pane #: " "swap-pane -t '%%'"
# Kill tabs quicker
bind-key x kill-pane
bind-key C-x kill-window
# Split Window into panes - automatically handled by plugin
bind-key '\' split-window -h -c '#{pane_current_path}'
bind-key '-' split-window -v -c '#{pane_current_path}'
# Open a sessions chooser
bind C-s split-window -v "tmux list-sessions | sed -E 's/:.*$//' | grep -v \"^$(tmux display-message -p '#S')\$\" | fzf --reverse | xargs tmux switch-client -t"
# Make visual selections act a little more like vim
bind-key -T copy-mode-vi v send -X begin-selection
bind-key -T copy-mode-vi V send -X select-line
bind-key -T copy-mode-vi y send -X copy-pipe-and-cancel 'wl-copy' \; send -X rectangle-off
bind-key -T copy-mode-vi 'C-v' send -X begin-selection \; send -X rectangle-on
#####################
## 4. THEME ##
#####################
# Status update interval
set -g status-interval 1
# Clock mode
set -g clock-mode-colour colour24
set -g clock-mode-style 24
# This tmux statusbar config was created by tmuxline.vim
# on Wed, 13 Mar 2019
set -g message-command-style bg="#2e2e2e",fg="#c8c8c8"
set -g message-style bg="#2e2e2e",fg="#c8c8c8"
set -g pane-active-border-style fg="#2e2e2e"
set -g pane-border-style fg="#2e2e2e"
set -g status-justify "centre"
set -g status "on"
set -g status-style "none"
set -g status-style "none"
set -g status-left-length "100"
set -g status-right-length "100"
setw -g window-status-style fg="#c8c8c8",bg="#2e2e2e","none"
setw -g window-status-activity-style bg="#2e2e2e",fg="#c8c8c8","underscore"
setw -g window-status-separator ""
set -g status-left "#[fg=#c8c8c8,bg=#2e2e2e] #S #[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]#[fg=#c8c8c8,bg=#2e2e2e] #I:#P #[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]#[fg=#c8c8c8,bg=#2e2e2e] #[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]"
set -g status-right "#[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics] #[fg=#c8c8c8,bg=#2e2e2e] #{?client_prefix,#[fg=colour232]#[bg=brightblue],} #(whoami) #[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]#[fg=#c8c8c8,bg=#2e2e2e] %d-%b-%y #[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]#[fg=#c8c8c8,bg=#2e2e2e] #H "
setw -g window-status-format "#[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]#[default] #I #W #[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]"
setw -g window-status-current-format "#[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]#[fg=#c8c8c8,bg=#2e2e2e]  #I #W #[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]"
########################
## 5. Nested Sessions ##
########################
# from: https://github.com/samoshkin/tmux-config/blob/master/tmux/tmux.conf
# all credit to samoshkin
# Session is considered to be remote when we ssh into host
if-shell 'test -n "$SSH_CLIENT"' \
'source-file $XDG_CONFIG_HOME/tmux/tmux.remote.conf'
# We want to have single prefix key "C-a", usable both for local and remote session
# we don't want to "C-a" + "a" approach either
# Idea is to turn off all key bindings and prefix handling on local session,
# so that all keystrokes are passed to inner/remote session
# see: toggle on/off all keybindings · Issue #237 · tmux/tmux - https://github.com/tmux/tmux/issues/237
# Also, change some visual styles when window keys are off
bind -T root F12 \
set prefix None \;\
set key-table off \;\
set status-style fg="colour245",bg="colour238" \;\
set window-status-current-format "#[fg=$color_window_off_status_bg,bg=$color_window_off_status_current_bg]$separator_powerline_right#[default] #I:#W# #[fg=$color_window_off_status_current_bg,bg=$color_window_off_status_bg]$separator_powerline_right#[default]" \;\
set window-status-current-style fg="colour232",bg="colour254","bold" \;\
if -F '#{pane_in_mode}' 'send-keys -X cancel' \;\
refresh-client -S \;\
bind -T off F12 \
set -u prefix \;\
set -u key-table \;\
set -u status-style \;\
set -u window-status-current-style \;\
set -u window-status-current-format \;\
refresh-client -S
run -b "$TMUX_PLUGIN_MANAGER_PATH/tpm/tpm"

View file

@ -0,0 +1,10 @@
# show status bar at bottom for remote session,
set -g status-position bottom
# Set port of SSH remote tunnel, where tmux will pipe buffers to transfer on local machine for copy
set -g @copy_backend_remote_tunnel_port 11988
# In remote mode we don't show "clock" and "battery status" widgets
set -g status-left "#[fg=#c8c8c8,bg=#2e2e2e][SSH]#S #[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]#[fg=#c8c8c8,bg=#2e2e2e] #(whoami) #[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]#[fg=#c8c8c8,bg=#2e2e2e] #I:#P #[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]"
set -g status-right "#{prefix_highlight} $wg_is_keys_off $wg_is_zoomed #{sysstat_cpu} | #{sysstat_mem} | #{sysstat_loadavg} | $wg_user_host | #{online_status}"
set -g status-right "#[fg=#2e2e2e,bg=#2e2e2e,nobold,nounderscore,noitalics]#{prefix_highlight} #H "

View file

@ -0,0 +1,80 @@
" You can edit this file by hand.
" The " character at the beginning of a line comments out the line.
" Blank lines are ignored.
" The Default color scheme is used for any directory that does not have
" a specified scheme and for parts of user interface like menus. A
" color scheme set for a base directory will also
" be used for the sub directories.
" The standard ncurses colors are:
" Default = -1 = None, can be used for transparency or default color
" Black = 0
" Red = 1
" Green = 2
" Yellow = 3
" Blue = 4
" Magenta = 5
" Cyan = 6
" White = 7
" Light versions of colors are also available (set bold attribute):
" LightBlack
" LightRed
" LightGreen
" LightYellow
" LightBlue
" LightMagenta
" LightCyan
" LightWhite
" Available attributes (some of them can be combined):
" bold
" underline
" reverse or inverse
" standout
" italic (on unsupported systems becomes reverse)
" none
" Vifm supports 256 colors you can use color numbers 0-255
" (requires properly set up terminal: set your TERM environment variable
" (directly or using resources) to some color terminal name (e.g.
" xterm-256color) from /usr/lib/terminfo/; you can check current number
" of colors in your terminal with tput colors command)
" highlight group cterm=attrs ctermfg=foreground_color ctermbg=background_color
highlight clear
highlight Win cterm=none ctermfg=white ctermbg=black
highlight Directory cterm=bold ctermfg=cyan ctermbg=default
highlight Link cterm=bold ctermfg=yellow ctermbg=default
highlight BrokenLink cterm=bold ctermfg=red ctermbg=default
highlight Socket cterm=bold ctermfg=magenta ctermbg=default
highlight Device cterm=bold ctermfg=red ctermbg=default
highlight Fifo cterm=bold ctermfg=cyan ctermbg=default
highlight Executable cterm=bold ctermfg=green ctermbg=default
highlight Selected cterm=bold ctermfg=magenta ctermbg=default
highlight CurrLine cterm=bold,reverse ctermfg=default ctermbg=default
highlight TopLine cterm=none ctermfg=black ctermbg=white
highlight TopLineSel cterm=bold ctermfg=black ctermbg=default
highlight StatusLine cterm=bold ctermfg=black ctermbg=white
highlight WildMenu cterm=underline,reverse ctermfg=white ctermbg=black
highlight CmdLine cterm=none ctermfg=white ctermbg=black
highlight ErrorMsg cterm=none ctermfg=red ctermbg=black
highlight Border cterm=none ctermfg=black ctermbg=white
highlight JobLine cterm=bold,reverse ctermfg=black ctermbg=white
highlight SuggestBox cterm=bold ctermfg=default ctermbg=default
highlight CmpMismatch cterm=bold ctermfg=white ctermbg=red
highlight AuxWin cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default
highlight TabLine cterm=none ctermfg=white ctermbg=black
highlight TabLineSel cterm=bold,reverse ctermfg=default ctermbg=default
highlight User1 cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default
highlight User2 cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default
highlight User3 cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default
highlight User4 cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default
highlight User5 cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default
highlight User6 cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default
highlight User7 cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default
highlight User8 cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default
highlight User9 cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default

View file

@ -0,0 +1,21 @@
set tuioptions=p
highlight Win cterm=none ctermfg=default ctermbg=default
highlight Border cterm=none ctermfg=default ctermbg=default
highlight TopLine cterm=none ctermfg=48 ctermbg=235
highlight TopLineSel cterm=bold ctermfg=default ctermbg=default
highlight StatusLine cterm=none ctermfg=48 ctermbg=235
highlight CmdLine cterm=none ctermfg=default ctermbg=default
highlight Selected cterm=none ctermfg=yellow ctermbg=234
highlight CurrLine cterm=bold,reverse ctermfg=default ctermbg=default
highlight WildMenu cterm=bold,reverse ctermfg=default ctermbg=default
highlight ErrorMsg cterm=none ctermfg=red ctermbg=default
highlight Directory cterm=bold ctermfg=blue ctermbg=default
highlight Link cterm=underline ctermfg=cyan ctermbg=default
highlight BrokenLink cterm=underline ctermfg=red ctermbg=default
highlight Socket cterm=none ctermfg=magenta ctermbg=default
highlight Device cterm=bold ctermfg=cyan ctermbg=default
highlight Fifo cterm=none ctermfg=blue ctermbg=default
highlight Executable cterm=none ctermfg=green ctermbg=default

View file

@ -0,0 +1,6 @@
This directory is dedicated for user-supplied scripts/executables.
vifm modifies its PATH environment variable to let user run those
scripts without specifying full path. All subdirectories are added
as well. File in a subdirectory overrules file with the same name
in parent directories. Restart might be needed to recognize files
in newly created or renamed subdirectories.

View file

@ -0,0 +1,25 @@
#!/bin/bash
if [ "$#" -ne 1 ]; then
echo "Usage: $0 filename"
exit 1
fi
# upper limit of lines to display for text files
nlines=250
# upper limit of bytes to display for binary files
nbytes=2048
# language of text files
language=russian
# output encoding for text files
encoding=utf-8
info=$(head -$nlines "$1" | file --mime -)
charset=${info#*=}
# shellcheck disable=2268
if [ "x$charset" == "xbinary" ]; then
hexdump -e '"%08_ax: "' -e '8/1 "%02x " " " 8/1 "%02x "' -e '" |" 16/1 "%_p"' -e '"\n"' -v -n $nbytes "$1"
else
head -$nlines "$1" | enconv -g -L $language -x $encoding
fi

View file

@ -0,0 +1,62 @@
#!/bin/sh
[ -d "$HOME/.cache/vifm" ] || mkdir -p "$HOME/.cache/vifm"
# $1 action
action="$1"
# $2 panel width
panel_width=$(($2 * 6))
# $3 panel height
panel_height=$(($3 * 14))
# $4 image path
image_file="$4"
PCACHE="$HOME/.cache/vifm/thumbnail.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$PWD/$image_file")" | sha256sum | awk '{print $1}')"
cleanup() {
printf '\33[s\33[5A\33[2K\33[u'
clear
exit 0
}
# recieves image with height
image() {
montage "$1" -geometry "${2}x${3}" sixel:-
}
case "$action" in
"clear")
cleanup
;;
"draw")
[ ! -f "${PCACHE}.jpg" ] && convert "$image_file"'[0]' "${PCACHE}.jpg"
# FILE="$PWD/$image_file"
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
;;
"video")
[ ! -f "${PCACHE}.jpg" ] &&
ffmpegthumbnailer -i "$4" -o "${PCACHE}.jpg" -s 0 -q 5
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
;;
"epub")
[ ! -f "${PCACHE}.jpg" ] &&
epub-thumbnailer "$image_file" "$PCACHE" 1024
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
;;
"pdf")
[ ! -f "${PCACHE}.jpg" ] &&
pdftoppm -jpeg -f 1 -singlefile "$image_file" "$PCACHE"
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
;;
"audio")
[ ! -f "${PCACHE}.jpg" ] &&
ffmpeg -i "$image_file" "${PCACHE}.jpg" -y >/dev/null
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
;;
"font")
[ ! -f "${PCACHE}.jpg" ] &&
fontpreview -i "$image_file" -o "${PCACHE}.jpg"
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
;;
*) ;;
esac

View file

@ -0,0 +1,115 @@
#!/usr/bin/env bash
show_help() {
printf """
vifm-thumbnailer
Easily show images/thumbnails from the vifm file manager.
Usage: vifm-thumbnailer <current file>
Point it to a file whose directory you want thumbnailed.
If you point it to a directory itself, it will list its contents.
Options:
-h Display this help.
-r Show images recursively from current folder.
-t Open viewer in thumbnail mode.
-m Show thumbnails for video files in addition to image files.
Will take longer to load up and requires ffmpeg utilities.
Vifm:
If the file is on your path (e.g. in ~/.vifm/scripts) from within
vifm you can run the script by invoking it with:
\`:!vifm-thumbnailer \%%c\`
which will show all directory thumbnails with the current file
initially shown.
If you want to have vifm show a filtered view for selected files
afterwards add a \%%u to the command.
"""
}
TMPDIR="$(mktemp -d)"
valid_files_tmp="$TMPDIR/nsxiv_rifle_$$"
# get all files in directory
list_img_files() {
if exist fd; then
fd --max-depth="$maxdepth" -tf . "${1%/*}" | is_img_extension | sort | tee -a "$valid_files_tmp"
else
find -L "${1%/*}" -maxdepth "$maxdepth" -type f -print | is_img_extension | sort | tee -a "$valid_files_tmp"
fi
}
list_vid_files() {
# shellcheck disable=2016
find "${1%/*}" -mindepth 1 -maxdepth "$maxdepth" \( -type f -o -type l \) -printf "%P\0" |
xargs -r0 -n 20 -P 64 file -00 -L --mime-type -- |
xargs -r0 -n 2 sh -c '
case "$2" in
video/*) printf "%s\0" "$1";;
esac
' -- |
sort -z |
xargs -r0 -I FILE ffmpegthumbnailer -i FILE -o "$TMPDIR/FILE.jpg" -m -s 384
find -L "$TMPDIR/" -maxdepth "$maxdepth" -type f -print | sort | tee -a "$valid_files_tmp"
}
img_ext="jpe?g|png|gif|svg|webp|tiff|heif|avif|ico|bmp"
is_img_extension() {
grep -iE "\.($img_ext)$"
}
# TODO if marking video thumbnail - will use wrong temporary path on output, makes e.g. vifm %u not work
open() {
trap 'rm -rf -- $TMPDIR' TERM INT EXIT
current="$(list_img_files "$1" | grep -nF "$1")"
if [ "$videos" = true ]; then
list_vid_files "$1"
fi
[ "$thumbnails" = true ] && nsxiv_args="-t"
if [ -n "$current" ]; then
nsxiv "$nsxiv_args" -i -n "${current%%:*}" -o -- <"$valid_files_tmp"
else
# fallback incase file didn't have a valid extension, or we couldn't
# find it inside the list
nsxiv -o -i -- <"$valid_files_tmp"
fi
}
maxdepth=1
while getopts "mrt?h" opt; do
case "$opt" in
r)
maxdepth=100
;;
m)
videos=true
;;
t)
thumbnails=true
;;
h | \? | *)
show_help
exit 0
;;
esac
done
shift $((OPTIND - 1))
[ "$1" = '--' ] && shift
case "$1" in
"")
echo "Usage: ${0##*/} PICTURES" >&2
exit 1
;;
/*) open "$1" ;;
"~"/*) open "$HOME/${1#"~"/}" ;;
*) open "$PWD/$1" ;;
esac

View file

@ -0,0 +1,637 @@
" vim: filetype=vifm : set foldmethod=marker foldlevel=0 nomodeline:
" Sample configuration file for vifm (last updated: 20 July, 2018)
" You can edit this file by hand.
" The " character at the beginning of a line comments out the line.
" Blank lines are ignored.
" The basic format for each item is shown with an example.
" ------------------------------------------------------------------------------
" Options {{{
" ==============================================================================
" This is the actual command used to start vi. The default is vim.
" If you would like to use another vi clone such as Elvis or Vile
" you will need to change this setting.
" switched to neovim
set vicmd=nvim
" set vicmd=elvis\ -G\ termcap
" set vicmd=vile
" This makes vifm perform file operations on its own instead of relying on
" standard utilities like `cp`. While using `cp` and alike is a more universal
" solution, it's also much slower when processing large amounts of files and
" doesn't support progress measuring.
set syscalls
" Trash Directory
" The default is to move files that are deleted with dd or :d to
" the trash directory. If you change this you will not be able to move
" files by deleting them and then using p to put the file in the new location.
" I recommend not changing this until you are familiar with vifm.
" This probably shouldn't be an option.
set trash
set trashdir=$XDG_DATA_HOME/Trash
" This is how many directories to store in the directory history.
set history=100
" Automatically resolve symbolic links on l or Enter.
set nofollowlinks
" With this option turned on you can run partially entered commands with
" unambiguous beginning using :! (e.g. :!Te instead of :!Terminal or :!Te<tab>).
set fastrun
" Natural sort of (version) numbers within text.
set sortnumbers
" Maximum number of changes that can be undone.
set undolevels=100
" If you installed the vim.txt help file set vimhelp.
" If would rather use a plain text help file set novimhelp.
set vimhelp
" If you would like to run an executable file when you
" press return on the file name set this.
set norunexec
" Selected color scheme
colorscheme cfillion.vifm
" Format for displaying time in file list. For example:
" TIME_STAMP_FORMAT=%m/%d-%H:%M
" See man date or man strftime for details.
set timefmt=%Y-%m-%d\ %H:%M
" Show list of matches on tab completion in command-line mode
set wildmenu
" Display completions in a form of popup with descriptions of the matches
set wildstyle=popup
" Display suggestions in normal, visual and view modes for keys, marks and
" registers (at most 5 files). In other view, when available.
set suggestoptions=normal,visual,view,otherpane,keys,marks,registers
" Ignore case in search patterns unless it contains at least one uppercase
" letter
set ignorecase
set smartcase
" Don't highlight search results automatically
set nohlsearch
" Use increment searching (search while typing)
set incsearch
" Try to leave some space from cursor to upper/lower border in lists
set scrolloff=4
" Don't do too many requests to slow file systems
if !has('win')
set slowfs=curlftpfs
endif
" Set custom status line look
set statusline="%A %10u:%-7g %10E / %-a %20d"
" Set ruler look (below statusline, showing directory info)
" set to show current file number, and overall number of files in dir
" with optional display of not-shown files if any are filtered out.
set rulerformat="%2l/%S %[[+%x]%]"
" decrease waiting time between input polling
set mintimeoutlen=50
" set the pre-key timeout really high, see https://git.io/fNm1d
set timeoutlen=5000
" use fd instead of default find to make searching faster and more flexible
set findprg='fd %A --hidden --exclude .git --exclude node_modules'
" }}}
" Marks {{{
" ------------------------------------------------------------------------------
" :mark mark /full/directory/path [filename]
mark h ~/
mark d ~/downloads/
mark p ~/projects/
mark i ~/pictures/
mark v ~/videos/
mark a ~/media/audio/
mark n ~/documents/notes/
mark N ~/Nextcloud/
mark l ~/documents/library/academia/pdf/
mark t ~/.local/share/Trash/
mark M ~/media/
mark M /run/media/
" }}}
" Commands {{{
" ------------------------------------------------------------------------------
" :com[mand][!] command_name action
" The following macros can be used in a command
" %a is replaced with the user arguments.
" %c the current file under the cursor.
" %C the current file under the cursor in the other directory.
" %f the current selected file, or files.
" %F the current selected file, or files in the other directory.
" %b same as %f %F.
" %d the current directory name.
" %D the other window directory name.
" %m run the command in a menu window
command! df df -h %m 2> /dev/null
command! diff nvim -d %f %F
command! zip zip -r %f.zip %f
command! run !! ./%f
command! make !!make %a
command! mkcd :mkdir %a | cd %a
" command! vgrep nvim "+grep %a"
command! syncme :cd %D
command! fzfhome : set noquickview
\| let $FZF_PICK = term('locate $HOME | fzf 2>/dev/tty')
\| if $FZF_PICK != ''
\| execute 'goto' fnameescape($FZF_PICK)
\| endif
command! fzf : set noquickview
\| let $FZF_PICK = term('find | fzf 2>/dev/tty')
\| if $FZF_PICK != ''
\| execute 'goto' fnameescape($FZF_PICK)
\| endif
command! fzfcd : set noquickview
\| let $FZF_PICK = term('find -type d | fzf 2>/dev/tty')
\| if $FZF_PICK != ''
\| execute 'cd' fnameescape($FZF_PICK)
\| endif
" }}}
" vifminfo {{{
" ------------------------------------------------------------------------------
" What should be saved automatically between vifm runs
" Like in previous versions of vifm
" set vifminfo=options,filetypes,commands,bookmarks,dhistory,state,cs
" Like in vi
set vifminfo=dhistory,savedirs,chistory,state,tui,shistory,
\phistory,fhistory,dirstack,registers,bookmarks,bmarks
" ------------------------------------------------------------------------------
" Examples of configuring both panels
" Customize view columns a bit (enable ellipsis for truncated file names)
"
" set viewcolumns=-{name}..,6{}.
" Filter-out build and temporary files
"
" filter! /^.*\.(lo|o|d|class|py[co])$|.*~$/
" }}}
" Mappings {{{
" ------------------------------------------------------------------------------
" make quitting simpler
nmap Q :q<cr>
" Sample mappings
" for now they use space for my leader key - so we can't switch panels with
" space, use tab for that
nnoremap <space> <nop>
nnoremap <space><space> t
" quick find mirroring my vim filefinder
nnoremap <space>f :FZFfind<cr>
" Start shell in current directory
nnoremap s :shell<cr>
" Display sorting dialog
nnoremap S :sort<cr>
" Toggle visibility of preview window
nnoremap w :view<cr>
vnoremap w :view<cr>gv
" Open file in existing instance of nvim
nnoremap e :!nvim %f<cr>
" Open file in the background using its default program
nnoremap gb :file &<cr>l
" yank current directory path into the clipboard
" clip is universal clipper from `sh` module
nnoremap yd :!echo -n %d | clip %i<cr>
" yank current file path into the clipboard
nnoremap yf :!echo -n %c:p | clip %i<cr>
" yank current filename without path into the clipboard
nnoremap yt :!echo -n %c | clip %i<cr>
" yank root of current file's name into the clipboard
nnoremap yr :!echo -n %c:r | clip %i<cr>
" Mappings for faster renaming
nnoremap I cw<c-a>
nnoremap cc cw<c-u>
nnoremap A cw
" More logical renaming, cw renames just the name, cW with extension
nnoremap cw cW
nnoremap cW cw
" Open editor to edit vifmrc and apply settings after returning to vifm
nnoremap <space>V :write | edit $MYVIFMRC | restart<cr>
" esc quits out of preview mode (it does in vim, why not here?)
qnoremap <esc> q
" Select file and jump in the indicated direction
nnoremap J tj
nnoremap K tk
" toggle options
command! toggle :execute 'set %a! | echo "%a" &%a'
nnoremap tw :toggle wrap<cr>
nnoremap tm :toggle millerview<cr>
nnoremap tl :toggle lsview<cr>
nnoremap tn :toggle number<cr>
nnoremap tr :toggle relativenumber<cr>
nnoremap tN :windo toggle number<cr>
nnoremap tR :windo toggle relativenumber<cr>
nnoremap te :execute ':tree! | echo ":tree"'<cr>
nnoremap t <nop>
nnoremap tt t
" zo shows hidden files, mimicking fold open in vim -- why does zc not close
" again?
nnoremap zc zm
" external commands
" extract currently selected file(s)
nnoremap xx :!atool -x %f<cr>
" compress currently selected file(s)
nnoremap xc :!atool -a %c:r.tar.gz %f<cr>
" archive currently selected file(s)
nnoremap xa :!atool -a %c:r.tar %f<cr>
" archive currently selected file(s)
nnoremap xz :!atool -a %c:r.zip %f<cr>
" combine selected PDFs into single one (named output.pdf)
noremap gc :!pdftk %f cat output output.pdf
" fzf movements
nnoremap <space>f :fzf<cr>
nnoremap <space>c :fzfcd<cr>
nnoremap <space>F :grep<space>
" preview thumbnails of current folder
" select thumbnails with m/M in nsxiv
" to generate a filtered view on them
nnoremap <space>t :!vifm-thumbnailer -t %u %c<cr>
nnoremap <space>T :!vifm-thumbnailer -r -t %u %c<cr>
" allows preview to work for normal view and single pane view
noremap <silent> w : if &quickview && !layoutis('only')
\| view
\| else
\| if layoutis('only')
\| if &lines + 50 < &columns | vsplit | else | split | endif
\| endif
\| view!
\| execute 'qnoremap w q:view|only|qunmap w<lt>cr>'
\| execute 'wincmd w'
\| endif
\| <cr>
" }}}
" Classify (Icons) {{{
" file types
set classify=' :dir:/, :exe:, :reg:, :link:'
" various file names
set classify+=' ::../::, ::*.sh::, ::*.[hc]pp::, ::*.[hc]::, ::/^copying|license$/::, ::.git/,,*.git/::, ::*.epub,,*.fb2,,*.djvu::, ::*.pdf::, ::*.htm,,*.html,,**.[sx]html,,*.xml::'
" archives
set classify+=' ::*.7z,,*.ace,,*.arj,,*.bz2,,*.cpio,,*.deb,,*.dz,,*.gz,,*.jar,,*.lzh,,*.lzma,,*.rar,,*.rpm,,*.rz,,*.tar,,*.taz,,*.tb2,,*.tbz,,*.tbz2,,*.tgz,,*.tlz,,*.trz,,*.txz,,*.tz,,*.tz2,,*.xz,,*.z,,*.zip,,*.zoo::'
" images
set classify+=' ::*.bmp,,*.gif,,*.jpeg,,*.jpg,,*.ico,,*.png,,*.ppm,,*.svg,,*.svgz,,*.tga,,*.tif,,*.tiff,,*.xbm,,*.xcf,,*.xpm,,*.xspf,,*.xwd::'
" audio
set classify+=' ::*.aac,,*.anx,,*.asf,,*.au,,*.axa,,*.flac,,*.m2a,,*.m4a,,*.mid,,*.midi,,*.mp3,,*.mpc,,*.oga,,*.ogg,,*.ogx,,*.ra,,*.ram,,*.rm,,*.spx,,*.wav,,*.wma,,*.ac3::'
" media
set classify+=' ::*.avi,,*.ts,,*.axv,,*.divx,,*.m2v,,*.m4p,,*.m4v,,*.mka,,*.mkv,,*.mov,,*.mp4,,*.flv,,*.mp4v,,*.mpeg,,*.mpg,,*.nuv,,*.ogv,,*.pbm,,*.pgm,,*.qt,,*.vob,,*.wmv,,*.xvid::'
" office files
set classify+=' ::*.doc,,*.docx::, ::*.xls,,*.xls[mx]::, ::*.pptx,,*.ppt::'
" }}}
"
" ------------------------------------------------------------------------------
" Filetypes {{{
" ------------------------------------------------------------------------------
" The file type is for the default programs to be used with
" a file extension.
" :filetype pattern1,pattern2 defaultprogram,program2
" :fileviewer pattern1,pattern2 consoleviewer
" The other programs for the file type can be accessed with the :file command
" The command macros %f, %F, %d, %F may be used in the commands.
" The %a macro is ignored. To use a % you must put %%.
" For automated FUSE mounts, you must register an extension with :file[x]type
" in one of following formats:
"
" :filetype extensions FUSE_MOUNT|some_mount_command using %SOURCE_FILE and %DESTINATION_DIR variables
" %SOURCE_FILE and %DESTINATION_DIR are filled in by vifm at runtime.
" A sample line might look like this:
" :filetype *.zip,*.jar,*.war,*.ear FUSE_MOUNT|fuse-zip %SOURCE_FILE %DESTINATION_DIR
"
" :filetype extensions FUSE_MOUNT2|some_mount_command using %PARAM and %DESTINATION_DIR variables
" %PARAM and %DESTINATION_DIR are filled in by vifm at runtime.
" A sample line might look like this:
" :filetype *.ssh FUSE_MOUNT2|sshfs %PARAM %DESTINATION_DIR
" %PARAM value is filled from the first line of file (whole line).
" Example first line for SshMount filetype: root@127.0.0.1:/
"
" You can also add %CLEAR if you want to clear screen before running FUSE
" program.
" Pdf
filextype *.pdf
\ { view as rich file }
\ zathura %c %i &, apvlv %c, xpdf %c,
\ { edit text content }
\ pdftotext -nopgbrk %c - | nvim
fileviewer *.pdf pdftotext -nopgbrk %c -
" PostScript
filextype *.ps,*.eps,*.ps.gz
\ {View in zathura}
\ zathura %f,
\ {View in gv}
\ gv %c %i &,
" Djvu
filextype *.djvu,*.epub
\ {View in zathura}
\ zathura %f,
\ {View in apvlv}
\ apvlv %f,
" Audio
filetype *.wav,*.mp3,*.flac,*.m4a,*.wma,*.ape,*.ac3,*.og[agx],*.spx,*.opus
\ {Play using ffplay}
\ ffplay -nodisp -autoexit %c,
\ {Play using MPlayer}
\ mpv %f,
fileviewer *.mp3 mp3info
fileviewer *.flac soxi
" Video
filextype *.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,
\*.fl[icv],*.m2v,*.mov,*.webm,*.ts,*.mts,*.m4v,*.r[am],*.qt,*.divx,
\*.as[fx]
\ {View using unique mplayer instance}
\ umpv %f &,
\ {View in timg}
\ timg --title --center --clear %f; read -k 1 -s -r,
\ {View using ffplay}
\ ffplay -fs -autoexit %f,
\ {View using Dragon}
\ dragon %f:p,
fileviewer *.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,
\*.fl[icv],*.m2v,*.mov,*.webm,*.ts,*.mts,*.m4v,*.r[am],*.qt,*.divx,
\*.as[fx]
\ tput cup %py %px > /dev/tty && ffmpeg -y -hide_banner -loglevel panic -i %c -ss 00:00:01.000 -vframes 1 /tmp/tempfile.jpg > /dev/null && kitty +kitten icat --transfer-mode=file --place=%pwx%ph@%pxx%py /tmp/tempfile.jpg %N
\ %pc
\ kitty +kitten icat --transfer-mode=file --place=%pwx%ph@%pxx%py --clear %N,
\ ffprobe -pretty %c 2>&1
" Web
filextype *.html,*.htm
\ {Open with dwb}
\ qutebrowser %f %i &,
\ {Open with firefox}
\ chromium %f &,
\ {Open with uzbl}
\ google-chrome %f %i &,
fileviewer *.html,*.htm
\ lynx -dump %c
filetype *.html,*.htm links, lynx
" Object
filetype *.o nm %f | less
" Man page
filetype *.[1-8] man ./%c
fileviewer *.[1-8] man ./%c | col -b
" Gif
filextype *.gif
\ {View in timg}
\ timg --loops=2 --title --center --clear %f; read -k 1 -s -r,
\ {Loop}
\ mpv --loop=inf %f %i &,
fileviewer *.gif
\ kitty +kitten icat --silent --transfer-mode=stream --place=%pwx%ph@%pxx%py %c %N
\ %pc
\ kitty +kitten icat --clear --silent %pd
" Images
filextype *.bmp,*.jpg,*.jpeg,*.png,*.gif,*.xpm
\ {View in timg}
\ timg --title --center --clear %f; read -k 1 -s -r,
\ {View in nsxiv directory viewer}
\ vifm-thumbnailer %c,
\ {View in imv}
\ imv %f,
\ {View in nsxiv}
\ nsxiv %f,
\ {View in vimiv}
\ vimiv %f,
\ {View in sxiv}
\ sxiv %f,
\ {View in feh}
\ feh -FZ %d --start-at %d/%c 2>/dev/null
\ {View in gpicview}
\ gpicview %c,
fileviewer *.bmp,*.jpg,*.jpeg,*.png,*.gif,*.xpm
\ timg -g%pwx%ph -pq %c
" OpenRaster
filextype *.ora
\ {Edit in MyPaint}
\ mypaint %f,
" tabular data
filextype *.csv
\ {Open with visidata}
\ vd %f,
fileviewer *.csv
\ xsv sample 100 %c | xsv table -c8 -p1 -w1,
" \ {cat %c | sed -e 's/,,/, ,/g' | column -s, -t | less -#5 -N -S; }
" Mindmap
filextype *.vym
\ {Open with VYM}
\ vym %f &,
" MD5
filetype *.md5
\ {Check MD5 hash sum}
\ md5sum -c %f %S,
" SHA1
filetype *.sha1
\ {Check SHA1 hash sum}
\ sha1sum -c %f %S,
" SHA256
filetype *.sha256
\ {Check SHA256 hash sum}
\ sha256sum -c %f %S,
" SHA512
filetype *.sha512
\ {Check SHA512 hash sum}
\ sha512sum -c %f %S,
" GPG signature
filetype *.asc
\ {Check signature}
\ !!gpg --verify %c,
" Torrent
filetype *.torrent ktorrent %f &
fileviewer *.torrent dumptorrent -v %c
" FuseZipMount
filetype *.zip,*.jar,*.war,*.ear,*.oxt,*.apkg
\ {Mount with fuse-zip}
\ FUSE_MOUNT|fuse-zip %SOURCE_FILE %DESTINATION_DIR,
\ {View contents}
\ zip -sf %c | less,
\ {Extract here}
\ tar -xf %c,
fileviewer *.zip,*.jar,*.war,*.ear,*.oxt zip -sf %c
" ArchiveMount
filetype *.tar,*.tar.bz2,*.tbz2,*.tgz,*.tar.gz,*.tar.xz,*.txz
\ {Mount with archivemount}
\ FUSE_MOUNT|archivemount %SOURCE_FILE %DESTINATION_DIR,
fileviewer *.tgz,*.tar.gz tar -tzf %c
fileviewer *.tar.bz2,*.tbz2 tar -tjf %c
fileviewer *.tar.txz,*.txz xz --list %c
fileviewer *.tar tar -tf %c
" Rar2FsMount and rar archives
filetype *.rar
\ {Mount with rar2fs}
\ FUSE_MOUNT|rar2fs %SOURCE_FILE %DESTINATION_DIR,
fileviewer *.rar unrar v %c
" IsoMount
filetype *.iso
\ {Mount with fuseiso}
\ FUSE_MOUNT|fuseiso %SOURCE_FILE %DESTINATION_DIR,
" SshMount
filetype *.ssh
\ {Mount with sshfs}
\ FUSE_MOUNT2|sshfs %PARAM %DESTINATION_DIR %FOREGROUND,
" FtpMount
filetype *.ftp
\ {Mount with curlftpfs}
\ FUSE_MOUNT2|curlftpfs -o ftp_port=-,,disable_eprt %PARAM %DESTINATION_DIR %FOREGROUND,
" Fuse7z and 7z archives
filetype *.7z
\ {Mount with fuse-7z}
\ FUSE_MOUNT|fuse-7z %SOURCE_FILE %DESTINATION_DIR,
fileviewer *.7z 7z l %c
" Office files
filextype *.odt,*.doc,*.docx,*.xls,*.xlsx,*.odp,*.pptx libreoffice %f &
filetype *.doc catdoc %c | nvim
fileviewer *.doc catdoc %c
filetype *.docx
\ pandoc -s -t markdown %f | nvim,
\ docx2txt %f - | nvim
fileviewer *.docx
\ pandoc -s -t markdown %f,
\ docx2txt %f -
" TuDu files
filetype *.tudu tudu -f %c
" Qt projects
filextype *.pro qtcreator %f &
" Directories
filextype */
\ {View in thunar}
\ Thunar %f &,
fileviewer */
\ exa --color always --tree -L2,
\ tree -L 2,
" use custom viewer script for rest
fileviewer * vifm-default-viewer %c
" Syntax highlighting in preview
"
" Explicitly set highlight type for some extensions
"
" 256-color terminal
" fileviewer *.[ch],*.[ch]pp highlight -O xterm256 -s dante --syntax c %c
" fileviewer Makefile,Makefile.* highlight -O xterm256 -s dante --syntax make %c
"
" 16-color terminal
" fileviewer *.c,*.h highlight -O ansi -s dante %c
"
" Or leave it for automatic detection
"
" fileviewer *[^/] pygmentize -O style=monokai -f console256 -g
" Displaying pictures in terminal
"
" fileviewer *.jpg,*.png shellpic %c
" Open all other files with default system programs (you can also remove all
" :file[x]type commands above to ensure they don't interfere with system-wide
" settings). By default all unknown files are opened with 'vi[x]cmd'
" uncommenting one of lines below will result in ignoring 'vi[x]cmd' option
" for unknown file types.
" For *nix:
" filetype * xdg-open
" For OS X:
" filetype * open
" For Windows:
" filetype * start, explorer
" }}}
" Various customization examples
" Use ag (the silver searcher) instead of grep
"
" set grepprg='ag --line-numbers %i %a %s'
" Add additional place to look for executables
"
" let $PATH = $HOME.'/bin/fuse:'.$PATH
" Block particular shortcut
"
" nnoremap <left> <nop>
" Export IPC name of current instance as environment variable and use it to
" communicate with the instance later.
"
" It can be used in some shell script that gets run from inside vifm, for
" example, like this:
" vifm --server-name "$VIFM_SERVER_NAME" --remote +"cd '$PWD'"
"
" let $VIFM_SERVER_NAME = v:servername

View file

@ -0,0 +1,77 @@
local wezterm = require 'wezterm'
local io = require 'io'
local os = require 'os'
local act = wezterm.action
local function setup()
local function isViProcess(pane)
local proc = pane:get_foreground_process_name()
if (proc:find('vim') or proc:find('nvim')) then return true end
return false
end
local function conditionalActivatePane(window, pane, pane_direction,
vim_direction)
if (isViProcess(pane)) then
window:perform_action(act.Multiple {
act.SendKey { key = 'w', mods = 'CTRL' },
act.SendKey { key = vim_direction }
}, pane)
else
window:perform_action(act.ActivatePaneDirection(pane_direction),
pane)
end
end
wezterm.on('ActivatePaneDirection-right', function(window, pane)
conditionalActivatePane(window, pane, 'Right', 'l')
end)
wezterm.on('ActivatePaneDirection-left', function(window, pane)
conditionalActivatePane(window, pane, 'Left', 'h')
end)
wezterm.on('ActivatePaneDirection-up', function(window, pane)
conditionalActivatePane(window, pane, 'Up', 'k')
end)
wezterm.on('ActivatePaneDirection-down', function(window, pane)
conditionalActivatePane(window, pane, 'Down', 'j')
end)
-- Retrieve the current scrollback text and send to editor
wezterm.on('edit-scrollback', function(window, pane)
local viewport_text = pane:get_lines_as_text(10000)
-- Create a temporary file to pass to vim
local name = os.tmpname()
local f = io.open(name, 'w+')
if f == nil then return false end
f:write(viewport_text)
f:flush()
f:close()
-- Open a new window running vim and tell it to open the file
window:perform_action(act.SpawnCommandInNewTab {
args = { (os.getenv('EDITOR') or 'vi'), name }
}, pane)
-- Wait time for vim to read the file before we remove it.
wezterm.sleep_ms(1000)
os.remove(name)
end)
wezterm.on("toggle-leader", function(window, pane)
wezterm.log_info("toggling the leader")
local overrides = window:get_config_overrides() or {}
if not overrides.leader then
wezterm.log_info("leader wasn't set")
overrides.leader = { key = "s", mods = "SUPER" };
else
wezterm.log_info("leader was set")
overrides.leader = nil
end
window:set_config_overrides(overrides)
end)
end
return { setup = setup }

View file

@ -0,0 +1,115 @@
local wezterm = require('wezterm')
local act = wezterm.action
local keys = {
{ key = 'O', mods = 'CTRL', action = act.ShowDebugOverlay },
{ key = '[', mods = 'CTRL', action = act.ScrollToPrompt(-1) },
{ key = ']', mods = 'CTRL', action = act.ScrollToPrompt(1) },
{ -- vertical pane
key = '\\',
mods = 'LEADER',
action = act.SplitHorizontal { domain = 'CurrentPaneDomain' }
}, { -- horizontal pane
key = '-',
mods = 'LEADER',
action = act.SplitVertical { domain = 'CurrentPaneDomain' }
}, -- pane movement keys
{
key = 'h',
mods = 'CTRL',
action = act.EmitEvent 'ActivatePaneDirection-left'
},
{
key = 'j',
mods = 'CTRL',
action = act.EmitEvent 'ActivatePaneDirection-down'
},
{
key = 'k',
mods = 'CTRL',
action = act.EmitEvent 'ActivatePaneDirection-up'
}, {
key = 'l',
mods = 'CTRL',
action = act.EmitEvent 'ActivatePaneDirection-right'
}, { key = 'z', mods = 'LEADER', action = act.TogglePaneZoomState },
{ key = ' ', mods = 'LEADER', action = act.RotatePanes 'Clockwise' },
{ key = 'q', mods = 'LEADER', action = act.PaneSelect { mode = 'Activate' } },
{
key = 'Q',
mods = 'LEADER',
action = act.PaneSelect { mode = 'SwapWithActive' }
}, { key = 'c', mods = 'LEADER', action = act.SpawnTab 'CurrentPaneDomain' },
{ key = ',', mods = 'LEADER', action = act.MoveTabRelative(-1) },
{ key = '.', mods = 'LEADER', action = act.MoveTabRelative(1) }, -- workspace selection
{
key = 's',
mods = 'LEADER',
action = act.ShowLauncherArgs { flags = 'FUZZY|WORKSPACES' }
}, { key = 't', mods = 'LEADER', action = act.ShowTabNavigator },
{ key = '[', mods = 'LEADER', action = act.ActivateCopyMode }, {
key = 'r',
mods = 'LEADER',
action = act.ActivateKeyTable {
name = 'resize_pane',
one_shot = false,
timeout_milliseconds = 2000,
replace_current = true
}
}, { key = 'F', mods = 'LEADER', action = act.QuickSelect }, {
key = '/',
mods = 'LEADER',
action = act.Search('CurrentSelectionOrEmptyString')
}, {
key = 'f',
mods = 'LEADER',
action = act.ActivateKeyTable {
name = 'scroll_mode',
one_shot = false,
replace_current = true,
timeout_milliseconds = 15000,
}
}, { key = 'e', mods = 'LEADER', action = act.EmitEvent 'edit-scrollback' }, {
key = 'l',
mods = 'LEADER',
action = act.EmitEvent 'ActivatePaneDirection-Right'
},
{ key = 'a', mods = 'CTRL|ALT', action = act.EmitEvent 'toggle-leader' }
}
-- Leader + number to activate that tab
for i = 1, 8 do
table.insert(keys, {
key = tostring(i),
mods = 'LEADER',
action = act.ActivateTab(i - 1)
})
end
-- key table sub modes
local key_tables = {
-- mode to change size of any panes
resize_pane = {
{ key = 'h', action = act.AdjustPaneSize { 'Left', 1 } },
{ key = 'l', action = act.AdjustPaneSize { 'Right', 1 } },
{ key = 'k', action = act.AdjustPaneSize { 'Up', 1 } },
{ key = 'j', action = act.AdjustPaneSize { 'Down', 1 } },
{ key = 'H', action = act.AdjustPaneSize { 'Left', 10 } },
{ key = 'L', action = act.AdjustPaneSize { 'Right', 10 } },
{ key = 'K', action = act.AdjustPaneSize { 'Up', 10 } },
{ key = 'J', action = act.AdjustPaneSize { 'Down', 10 } },
{ key = 'Escape', action = 'PopKeyTable' }
},
scroll_mode = {
{ key = 'y', mods = 'CTRL', action = act.ScrollByLine(-1) },
{ key = 'e', mods = 'CTRL', action = act.ScrollByLine(1) },
{ key = 'f', mods = 'CTRL', action = act.ScrollByPage(1) },
{ key = 'b', mods = 'CTRL', action = act.ScrollByPage(-1) },
{ key = 'd', mods = 'CTRL', action = act.ScrollByPage(0.5) },
{ key = 'u', mods = 'CTRL', action = act.ScrollByPage(-0.5) },
{ key = 'g', mods = 'CTRL', action = act.ScrollToTop },
{ key = 'G', mods = 'CTRL', action = act.ScrollToBottom },
{ key = 'Escape', action = 'PopKeyTable' }
},
}
return { keys = keys, key_tables = key_tables }

View file

@ -0,0 +1,46 @@
local wezterm = require 'wezterm'
local function basename(s) return string.gsub(s or '', '(.*[/\\])(.*)', '%2') end
local SEPARATOR = ' | '
local function setup()
-- STATUSBAR
-- show currently active key table in lower right status bar
-- mimicing Vim modes
wezterm.on('update-status', function(window, pane)
local displayed = { left = {}, right = {} }
local keytable = window:active_key_table()
if keytable then
displayed.left[#displayed.left + 1] = 'MODE: ' .. keytable
end
local workspace = window:active_workspace()
if workspace and workspace ~= 'default' then
displayed.left[#displayed.left + 1] = 'WORKSPACE: ' .. workspace
end
local bat = ''
for _, b in ipairs(wezterm.battery_info()) do
bat = '🔋 ' .. string.format('%.0f%%', b.state_of_charge * 100) ..
' ' .. b.state
end
displayed.right[#displayed.right + 1] = bat
local currentprogram = pane:get_foreground_process_name()
displayed.right[#displayed.right + 1] = basename(currentprogram)
local statusleft = ''
for _, v in ipairs(displayed.left) do
statusleft = statusleft .. v .. SEPARATOR
end
local statusright = ''
for _, v in ipairs(displayed.right) do
statusright = statusright .. v .. SEPARATOR
end
window:set_left_status(statusleft or '')
window:set_right_status(statusright or '')
end)
end
return { setup = setup }

View file

@ -0,0 +1,78 @@
local wezterm = require 'wezterm'
local mux = wezterm.mux
local maps = require 'maps'
require 'statusbar'.setup()
require 'events'.setup()
-- wezterm.on("set-up-dotfile-workspace", function(window, pane)
-- -- Set a workspace for coding on a current project
-- -- Top pane is for the editor, bottom pane is for the build tool
-- local project_dir = wezterm.home_dir .. '/projects/test/quarto/quarto-test'
-- local tab, build_pane, window = mux.spawn_window {
-- workspace = 'coding',
-- cwd = project_dir,
-- args = args
-- }
-- local editor_pane = build_pane:split{
-- direction = 'Top',
-- size = 0.6,
-- cwd = project_dir
-- }
-- build_pane:send_text 'quarto check'
-- mux.set_active_workspace 'coding'
-- end)
--
-- wezterm.on('gui-startup', function(cmd)
-- -- allow `wezterm start -- something` to affect what we spawn
-- -- in our initial window
-- local args = {}
-- if cmd then args = cmd.args end
--
-- -- Set a workspace for coding on a current project
-- -- Top pane is for the editor, bottom pane is for the build tool
-- local project_dir = wezterm.home_dir .. '/projects/test/quarto/quarto-test'
-- local tab, build_pane, window = mux.spawn_window {
-- workspace = 'coding',
-- cwd = project_dir,
-- args = args
-- }
-- local editor_pane = build_pane:split {
-- direction = 'Top',
-- size = 0.6,
-- cwd = project_dir
-- }
-- build_pane:send_text 'quarto check'
--
-- -- A workspace for interacting with a local machine that
-- -- runs some docker containners for home automation
-- local tab, pane, window = mux.spawn_window {
-- workspace = 'toppy',
-- args = { 'top' }
-- }
--
-- -- We want to startup in the coding workspace
-- mux.set_active_workspace 'coding'
-- end)
return {
enable_wayland = true,
hide_tab_bar_if_only_one_tab = true,
use_fancy_tab_bar = false,
tab_bar_at_bottom = true,
window_padding = { left = 0, right = 0, top = 0, bottom = 0 },
color_scheme = "Nord (base16)",
-- default_prog = {"nu"},
scrollback_lines = 10000,
font = wezterm.font('Iosevka'),
line_height = 1.0,
leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1500 },
keys = maps.keys,
key_tables = maps.key_tables
}

View file

@ -0,0 +1,19 @@
#!/usr/bin/env zsh
[ -f "$XDG_CONFIG_HOME/sh/profile" ] && . "$XDG_CONFIG_HOME/sh/profile"
# .zlogin
#
if [ -d "$XDG_CONFIG_HOME/sh/profile.d" ]; then
for file in "$XDG_CONFIG_HOME/sh/profile.d"/*.sh; do
# shellcheck disable=1090
source "$file"
done
unset file
fi
if [ -d "$XDG_CONFIG_HOME/zsh/profile.d" ]; then
for file in "$XDG_CONFIG_HOME/zsh/profile.d"/*.sh; do
# shellcheck disable=1090
source "$file"
done
unset file
fi

View file

@ -0,0 +1,24 @@
#!/usr/bin/env zsh
#
# load global sh env vars
[ -f "$XDG_CONFIG_HOME/sh/env" ] && source "$XDG_CONFIG_HOME/sh/env"
if [ -d "$XDG_CONFIG_HOME/sh/env.d" ]; then
for _env in "$XDG_CONFIG_HOME/sh/env.d"/*.sh; do
. "$_env"
done
unset _env
fi
# load zsh specific env vars
if [ -d "$XDG_CONFIG_HOME/zsh/env.d" ]; then
for _env in "$XDG_CONFIG_HOME/zsh/env.d"/*.zsh; do
. "$_env"
done
unset _env
fi
# add XDG_CONFIG_HOME/zsh/completions to fpath
# zsh uses it to look for completions; throw all
# completions in these dotfiles in there
fpath=("$XDG_CONFIG_HOME/zsh/completions" $fpath)

197
terminal/.config/zsh/.zshrc Normal file
View file

@ -0,0 +1,197 @@
#!/usr/bin/env zsh
#
CONFDIR="${XDG_CONFIG_HOME:-$HOME/.config}"
ZSHCONFDIR="$CONFDIR/zsh"
# load completion, extended zsh moving syntax, zle edit in vim (or other $EDITOR) possibility
autoload -Uz compinit zmv edit-command-line promptinit
# Set completion style
# The following lines were added by compinstall
zstyle ':completion:*' completer _complete _ignored _approximate
zstyle ':completion:*' matcher-list '' '+m:{[:lower:]}={[:upper:]} r:|[._-]=** r:|=**'
zstyle ':completion:*' menu select=1
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
zstyle :compinstall filename "$ZSHCONFDIR/.zshrc"
compinit
# End of lines added by compinstall
# load plugins
PLUG_FOLDER="/usr/share/zsh/plugins"
source /usr/share/oh-my-zsh/plugins/colored-man-pages/colored-man-pages.plugin.zsh
source /usr/share/oh-my-zsh/plugins/command-not-found/command-not-found.plugin.zsh
source /usr/share/fzf/key-bindings.zsh
#source /usr/share/nvm/init-nvm.sh
## find the correct installed tab-completion version
[ -e $PLUG_FOLDER/fzf-tab/fzf-tab.plugin.zsh ] && source $PLUG_FOLDER/fzf-tab/fzf-tab.plugin.zsh
[ -e $PLUG_FOLDER/fzf-tab-bin-git/fzf-tab.plugin.zsh ] && source $PLUG_FOLDER/fzf-tab-bin-git/fzf-tab.plugin.zsh
# these need to be sourced after fzf-tab
[ -e $PLUG_FOLDER/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh ] && source $PLUG_FOLDER/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
[ -e $PLUG_FOLDER/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh ] && source $PLUG_FOLDER/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
[ -e $PLUG_FOLDER/alias-tips/alias-tips.plugin.zsh ] && source $PLUG_FOLDER/alias-tips/alias-tips.plugin.zsh
[ -e $PLUG_FOLDER/zsh-autosuggestions/zsh-autosuggestions.plugin.zsh ] && source $PLUG_FOLDER/zsh-autosuggestions/zsh-autosuggestions.plugin.zsh
unset PLUG_FOLDER
# simple fzf-tab settings
zstyle ":fzf-tab:*" fzf-flags "--ansi" "--expect='$continuous_trigger,$print_query'" "--color=hl:$(($#headers == 0 ? 108 : 255))" "--nth=2,3" "--layout=reverse" "--height=${FZF_TMUX_HEIGHT:-75%}" "--tiebreak=begin" "-m" "--bind=tab:down,btab:up,change:top,ctrl-space:toggle" "--cycle" "--query=$query" "--header-lines=$#headers" "--print-query"
zstyle ':fzf-tab:*' fzf-command fzf
# format colorful groups for different completion actions
zstyle ':completion:*:descriptions' format '[%d]'
zstyle ':fzf-tab:*' show-group brief
# use input as query string when completing zlua
zstyle ':fzf-tab:complete:_zlua:*' query-string input
# (experimental, may change in the future)
# some boilerplate code to define the variable `extract` which will be used later
# please remember to copy them
local extract="
# trim input(what you select)
local in=\${\${\"\$(<{f})\"%\$'\0'*}#*\$'\0'}
# get ctxt for current completion(some thing before or after the current word)
local -A ctxt=(\"\${(@ps:\2:)CTXT}\")
# real path
local realpath=\${ctxt[IPREFIX]}\${ctxt[hpre]}\$in
realpath=\${(Qe)~realpath}
"
# give a preview of commandline arguments when completing `kill`
zstyle ':completion:*:*:*:*:processes' command "ps -u $USER -o pid,user,comm,cmd -w -w"
zstyle ':fzf-tab:complete:kill:argument-rest' extra-opts --preview=$extract'ps --pid=$in[(w)1] -o cmd --no-headers -w -w' --preview-window=down:3:wrap
# give a preview of directory by exa when completing cd
zstyle ':fzf-tab:complete:cd:*' extra-opts --preview=$extract'exa -1 --color=always $realpath'
# pure prompt init
promptinit
# make it single line
prompt_newline='%666v'
# show git stash status as a ≡
zstyle :prompt:pure:git:stash show yes
prompt pure
# shellcheck source=alias
[ -f "$CONFDIR/sh/alias" ] && source "$CONFDIR/sh/alias"
# load additional aliases
if [ -d "$CONFDIR/sh/alias.d" ]; then
for _alias in "$CONFDIR/sh/alias.d"/*.sh; do
source "$_alias"
done
unset _alias
fi
if [ -d "$ZSHCONFDIR/alias.d" ]; then
for _alias in "$ZSHCONFDIR/alias.d"/*.sh; do
source "$_alias"
done
unset _alias
fi
# Correct spelling for commands
setopt correct
# turn off the infernal correctall for filenames
unsetopt correctall
# Enable command auto-correction.
ENABLE_CORRECTION="true"
# allow moving through directories without prepending cd
setopt autocd
# Speed up autocomplete, force prefix mapping
zstyle ':completion:*' accept-exact '*(N)'
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path "${XDG_CACHE_HOME:-$HOME/.cache}/zshcompcache"
### history
## Set ZSH History defaults
setopt append_history
setopt extended_history # record command start time
setopt hist_ignore_dups
setopt hist_ignore_all_dups # do not put duplicated command into history list
setopt hist_save_no_dups # do not save duplicated command
setopt hist_expire_dups_first
setopt hist_ignore_space
setopt hist_reduce_blanks # remove unnecessary blanks
setopt hist_verify
setopt inc_append_history_time # append command to history file immediately after execution
setopt share_history # Share your history across all your terminal windows
setopt pushd_ignore_dups
#setopt pushd_silent
export HISTSIZE=1000000
export SAVEHIST=1000000
export HISTFILE="$XDG_DATA_HOME/zsh_history"
export HISTORY_IGNORE="(jrnl *|l *|ls *|z *|cd *|cd -|pwd|pwd *|exit|date)"
## Set ZSH History aliases
# Show the top 5 commands used in recent history
history_top() {
history | awk "{a[\$2]++} END{for(i in a){printf \"%5d\t%s\n\",a[i],i}}" | sort -rn | head
}
# Display timestamped recent command history
alias history="fc -l -d -D"
### Glob Alias expansion
# Expand aliases inline - see http://blog.patshead.com/2012/11/automatically-expaning-zsh-global-aliases---simplified.html
globalias() {
if [[ $LBUFFER =~ [A-Z0-9]+$ ]]; then
zle _expand_alias
zle expand-word
fi
zle self-insert
}
zle -N globalias
bindkey " " globalias
bindkey "^ " magic-space # control-space to bypass completion
bindkey -M isearch " " magic-space # normal space during searches
# allow inserting previous arguments in the current zle input
# see https://stackoverflow.com/a/34861762
bindkey "^[." insert-last-word
# VIM MODE for the shell
# enable vim mode on pressing escape
bindkey -v
# remove the delay for switching modes
export KEYTIMEOUT=1
# space puts a space, even in cmd mode
bindkey -a ' ' magic-space
# always allow backspace/delete to remove letters
bindkey '^?' backward-delete-char
bindkey -a '^?' backward-delete-char
bindkey '^h' backward-delete-char
bindkey -a '^h' backward-delete-char
# and forward with delete
bindkey '^[[3~' delete-char
bindkey -a '^[[3~' delete-char
# always allow removing words with <c-w>
bindkey -a '^w' backward-kill-word
# enable cycling through previous commands with <c-p/n>
bindkey '^P' history-beginning-search-backward
bindkey '^N' history-beginning-search-forward
# search history backwards <c-r>
bindkey '^o' history-incremental-search-backward
# cycle through history results
bindkey -M isearch '^P' history-incremental-search-backward
bindkey -M isearch '^N' history-incremental-search-forward
# Send command to editor and back for execution
zle -N edit-command-line
bindkey '^e' edit-command-line
bindkey -M vicmd '^e' edit-command-line
# Deduplicate PATH - remove any duplicate entries from PATH
# from: https://unix.stackexchange.com/questions/40749/remove-duplicate-path-entries-with-awk-command
get_var() {
eval 'printf "%s\n" "${'"$1"'}"'
}
set_var() {
eval "$1=\"\$2\""
}
dedup_pathvar() {
pathvar_name="$1"
pathvar_value="$(get_var "$pathvar_name")"
deduped_path="$(perl -e 'print join(":",grep { not $seen{$_}++ } split(/:/, $ARGV[0]))' "$pathvar_value")"
set_var "$pathvar_name" "$deduped_path"
}
dedup_pathvar PATH
dedup_pathvar MANPATH
unset CONFDIR
unset ZSHCONFDIR

View file

@ -0,0 +1,12 @@
#compdef _tmux_attach_start
#
# Requires tmux_attach_start script in path
#
# Enables completion for zsh of tmux_attach_start function
# with currently open sessions, or tmux options.
_tmux_attach_start() {
_alternative \
"sessions:user sessions:($(tmux list-sessions -F'#{session_name}' 2>/dev/null))"
}

View file

@ -0,0 +1,39 @@
setup() {
fut="$BATS_TEST_DIRNAME/../tmux_attach_start"
}
teardown() {
rm -rf $BATS_TMPDIR/xdg/*
}
@test "runs correctly if invoked without arguments" {
run $fut
echo "$BATS_TEST_DIRNAME/../tmux_attach_start"
[ "$status" -eq 0 ]
}
@test "Errors out if passed a non-existent session file (and some session name)" {
run $fut IDONT_EXIST_HERE.session sessionname
echo "STATUS: $output"
[ "$status" -eq 1 ]
echo "OUTPUT: $output"
[ "$output" = "can not source session file: 'IDONT_EXIST_HERE.session' does not exist." ]
}
@test "Runs without errors when session file exists in PWD" {
touch $PWD/exists.session
run $fut exists.session sessionname
rm $PWD/exists.session
[ "$status" -eq 0 ]
}
@test "Runs without errors when session file exists in XDG_CONFIG_HOME/tmux/sessions/" {
export XDG_CONFIG_HOME=$BATS_TMPDIR
mkdir -p $XDG_CONFIG_HOME/tmux/sessions
sesdir=$XDG_CONFIG_HOME/tmux/sessions
touch $sesdir/exists.session
run $fut exists.session sessionname
[ "$status" -eq 0 ]
}

View file

@ -0,0 +1,154 @@
#!/bin/sh
#
# Attach to a tmux session, or create it if it doesnt exist
if [ "$1" = '-h' ] || [ "$1" = '--help' ]; then
cat <<-EOF
Usage: $0 [FILE] [NAME]
Attach to an existing tmux session, or bootstrap a new session.
If no session exists which fits the criteria, this will create a new one and
load it up obeying the commands contained in the FILE argument passed in. It
must contain commands which are tmux-command compatible since they will be
passed to tmux unmodified. If a session exists and a valid configuration FILE is
passed, it will attach itself to the session and execute the session setup inside.
It will load the default tmux.conf in the following order:
- XDG_CONFIG_HOME/tmux/tmux.conf (usually ~/.config/tmux/tmux.conf)
- ~/.tmux.conf
- /etc/tmux.conf
Afterwards, it will apply the contents of the FILE argument passed into the command.
If no FILE argument is passed it will create an empty session, or attach itself to
the session specified.
If no NAME argument is passed it will automatically create a session name from the
FILE argument passed.
If creating a new session without passing in a FILE argument, and the current directory
contains a .tmux.session file, it will automatically use that to set up the session.
By default, it also looks for valid session files in XDG_CONFIG_HOME/tmux/sessions/
This path can be changed by setting the TM_SESSION_PATH environment variable.
EOF
exit 0
fi
# Make tmux obey the XDG specification on startup
if [ -e "$XDG_CONFIG_HOME/tmux/tmux.conf" ]; then
start="tmux -f $XDG_CONFIG_HOME/tmux/tmux.conf"
else
start=tmux
fi
_file_exists() {
if [ -f "$1" ]; then
true
else
false
fi
}
_not_in_tmux() {
[ -z "$TMUX" ]
}
_session_exists() {
if tmux has-session -t "$session_name" >/dev/null 2>&1; then
true
else
false
fi
}
_create_detached_session() {
($start new-session -d -s "$session_name")
}
_load_env_session_file() {
if [ -f ./.tmux.session ]; then
xargs -L1 tmux <./.tmux.session
fi
}
_load_session_file() {
if [ -f "$session_file" ]; then
xargs -L1 tmux <"$session_file"
fi
}
_set_session_file_path() {
# Prefer local dir if file exists there, fall back to root dir
if _file_exists "${1}"; then
session_file="${1}"
elif _file_exists "${session_dir}${1}"; then
session_file="${session_dir}${1}"
fi
}
_set_session_vars() {
session_dir=${TM_SESSION_DIR:-"$XDG_CONFIG_HOME/tmux/sessions/"}
# set up session name and config file - if passed in as arguments
if [ "$#" -eq 2 ]; then
if ! _file_exists "$1" && ! _file_exists "${session_dir}${1}"; then
echo >&2 "can not source session file: '${1}' does not exist."
exit 1
fi
_set_session_file_path "$1"
session_name=${2}
elif [ "$#" -eq 1 ]; then
_set_session_file_path "$1"
if ! _file_exists "$session_file"; then
session_name=${1}
fi
fi
# set default session name if none was passed
if [ -z "$session_name" ]; then
# only if we have a filename should we append it to the session name
if [ -n "$session_file" ]; then
fname=/$(basename "$session_file" .session)
fi
# default to parent directory name / config file name for the session
session_name=$(basename "$PWD" | sed 's/[^a-zA-Z0-9\-]//g' | tr . -)"$fname"
fi
}
_attach_or_create() {
# first create a new session if one doesn't exist
if ! _session_exists; then
_create_detached_session
# look for .tmux.session file if no file has been explicitly passed in
# session files always take precedence over environment files when specifically passed in
if ! _file_exists "$session_file"; then
_load_env_session_file
fi
fi
_load_session_file
# then attach or switch to the session
if _not_in_tmux; then
$start attach -t "$session_name"
else
$start switch-client -t "$session_name"
fi
_unset_functions
}
_unset_functions() {
unset _set_session_vars
unset _set_session_file_path
unset _attach_or_create
unset _load_session_file
unset _create_detached_session
unset _session_exists
unset _not_in_tmux
unset _file_exists
}
_set_session_vars "$@"
_attach_or_create
exit 0

View file

@ -0,0 +1,20 @@
#!/usr/bin/env bash
# create a tree-style view
# of all open tmux panes
# and the command they are currently running
tmux ls -F'#{session_id}' | while read -r s; do
S=$(tmux ls -F'#{session_id}#{session_name}: #{T:tree_mode_format}' | grep ^"$s")
session_info=${S##$s}
session_name=$(echo "$session_info" | cut -d ':' -f 1)
if [[ -n "$1" ]] && [[ "$1" == "$session_name" ]]; then
echo -e "\033[1;34m$session_info\033[0m"
tmux lsw -t"$s" -F'#{window_id}' | while read -r w; do
W=$(tmux lsw -t"$s" -F'#{window_id}#{T:tree_mode_format} - #{pane_current_command}' | grep ^"$w")
H=$(tmux lsw -t"$s" -F'#{window_id}#H' | grep ^"$w")
echo " ﬌ ${W##$w}" | sed "s/\"${H##$w}\" //"
done
else
echo -e "\033[1m$session_info\033[0m"
fi
done

6
terminal/.zshenv Normal file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env zsh
#
# make zsh source the correct directory
export XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-"$HOME/.config"}
ZDOTDIR="${XDG_CONFIG_HOME:-"$HOME/.config"}/zsh"