init
This commit is contained in:
12
.gitconfig
Normal file
12
.gitconfig
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[user]
|
||||||
|
name = syui
|
||||||
|
email = syui@syui.ai
|
||||||
|
signingkey = 5417CFEBAD92DF56
|
||||||
|
[commit]
|
||||||
|
gpgsign = true
|
||||||
|
[core]
|
||||||
|
editor = vim
|
||||||
|
[pull]
|
||||||
|
rebase = false
|
||||||
|
[init]
|
||||||
|
defaultBranch = main
|
||||||
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.DS_Store
|
||||||
|
.env
|
||||||
|
.claude
|
||||||
|
Cargo.lock
|
||||||
|
node_modules
|
||||||
|
package-lock.json
|
||||||
|
/target
|
||||||
|
/dist
|
||||||
|
/claude.md
|
||||||
|
/CLAUDE.md
|
||||||
|
/tmp
|
||||||
|
*.swp
|
||||||
0
.hushlogin
Normal file
0
.hushlogin
Normal file
10
.local/bin/git-ci
Executable file
10
.local/bin/git-ci
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
git commit -v
|
||||||
|
else
|
||||||
|
if [ "$1" = "--amend" ]; then
|
||||||
|
git commit -v --amend
|
||||||
|
else
|
||||||
|
git commit -m "$*"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
7
.local/bin/git-orphan
Executable file
7
.local/bin/git-orphan
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
git checkout --orphan temp
|
||||||
|
git add -A
|
||||||
|
git commit -m "init"
|
||||||
|
git branch -D main
|
||||||
|
git branch -m temp main
|
||||||
|
git push -f origin main
|
||||||
65
.local/bin/vren
Executable file
65
.local/bin/vren
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
# vren - rename files with vim
|
||||||
|
# usage: vren [dir]
|
||||||
|
|
||||||
|
dir="${1:-.}"
|
||||||
|
cd "$dir" || exit 1
|
||||||
|
|
||||||
|
# git init if no .git
|
||||||
|
has_git=0
|
||||||
|
if [ -d .git ]; then
|
||||||
|
has_git=1
|
||||||
|
else
|
||||||
|
git init -q
|
||||||
|
git add -A
|
||||||
|
git commit -q -m "before rename"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# list files
|
||||||
|
old=$(mktemp)
|
||||||
|
new=$(mktemp)
|
||||||
|
ls -1 > "$old"
|
||||||
|
cp "$old" "$new"
|
||||||
|
|
||||||
|
# edit
|
||||||
|
vim "$new"
|
||||||
|
|
||||||
|
# check
|
||||||
|
old_count=$(wc -l < "$old")
|
||||||
|
new_count=$(wc -l < "$new")
|
||||||
|
if [ "$old_count" -ne "$new_count" ]; then
|
||||||
|
echo "error: line count mismatch ($old_count -> $new_count)"
|
||||||
|
rm "$old" "$new"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# diff
|
||||||
|
changes=0
|
||||||
|
paste "$old" "$new" | while IFS=$'\t' read -r o n; do
|
||||||
|
[ "$o" != "$n" ] && echo " $o -> $n" && changes=$((changes+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if ! diff -q "$old" "$new" >/dev/null 2>&1; then
|
||||||
|
echo ""
|
||||||
|
printf "apply? (y/n): "
|
||||||
|
read -q ans
|
||||||
|
echo ""
|
||||||
|
if [ "$ans" = "y" ]; then
|
||||||
|
paste "$old" "$new" | while IFS=$'\t' read -r o n; do
|
||||||
|
[ "$o" != "$n" ] && mv -- "$o" "$n"
|
||||||
|
done
|
||||||
|
echo "done"
|
||||||
|
# restore point
|
||||||
|
if [ "$has_git" -eq 0 ]; then
|
||||||
|
git add -A
|
||||||
|
git commit -q -m "after rename"
|
||||||
|
echo "restore: git log / git checkout HEAD~1 -- ."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "cancelled"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "no changes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm "$old" "$new"
|
||||||
BIN
.local/share/fonts/aifont.ttf
Normal file
BIN
.local/share/fonts/aifont.ttf
Normal file
Binary file not shown.
52
.tmux.conf
Normal file
52
.tmux.conf
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# prefix
|
||||||
|
unbind C-b
|
||||||
|
set -g prefix ^T
|
||||||
|
bind t send-prefix
|
||||||
|
|
||||||
|
# general
|
||||||
|
set -s escape-time 0
|
||||||
|
set -g base-index 1
|
||||||
|
set -g pane-base-index 1
|
||||||
|
set -g renumber-windows on
|
||||||
|
set -g history-limit 10000
|
||||||
|
set -g default-terminal "xterm-256color"
|
||||||
|
set -g allow-passthrough on
|
||||||
|
set -g set-clipboard on
|
||||||
|
set-window-option -g mode-keys vi
|
||||||
|
set-window-option -g xterm-keys on
|
||||||
|
|
||||||
|
# pane/window
|
||||||
|
bind s split-window -v -c "#{pane_current_path}"
|
||||||
|
bind v split-window -h -c "#{pane_current_path}"
|
||||||
|
bind h select-pane -L
|
||||||
|
bind j select-pane -D
|
||||||
|
bind k select-pane -U
|
||||||
|
bind l select-pane -R
|
||||||
|
bind -r C-h resize-pane -L 5
|
||||||
|
bind -r C-j resize-pane -D 5
|
||||||
|
bind -r C-k resize-pane -U 5
|
||||||
|
bind -r C-l resize-pane -R 5
|
||||||
|
bind K kill-pane
|
||||||
|
bind c new-window
|
||||||
|
bind w choose-window
|
||||||
|
bind C-t run "tmux last-pane || tmux last-window || tmux new-window"
|
||||||
|
|
||||||
|
# copy
|
||||||
|
bind ^y copy-mode
|
||||||
|
bind -r ^"[" copy-mode
|
||||||
|
bind p paste-buffer
|
||||||
|
bind-key -T copy-mode-vi v send-keys -X begin-selection
|
||||||
|
bind-key -T copy-mode-vi Space send-keys -X begin-selection
|
||||||
|
if-shell "uname | grep -q Darwin" \
|
||||||
|
'bind-key -T copy-mode-vi y send -X copy-pipe-and-cancel "pbcopy"; bind-key -T copy-mode-vi Enter send -X copy-pipe-and-cancel "pbcopy"'
|
||||||
|
if-shell 'which xclip' \
|
||||||
|
'bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -i -sel c"; bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "xclip -i -sel c"'
|
||||||
|
|
||||||
|
# url open
|
||||||
|
bind u run-shell "~/.tmux/plugin/urlopen.zsh"
|
||||||
|
|
||||||
|
# plugins
|
||||||
|
run-shell "~/.tmux/plugin/ailog.zsh"
|
||||||
|
|
||||||
|
# reload
|
||||||
|
bind r source-file ~/.tmux.conf\; display-message "reloaded"
|
||||||
107
.tmux/plugin/ailog.zsh
Executable file
107
.tmux/plugin/ailog.zsh
Executable file
@@ -0,0 +1,107 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
# tmux plugin: ailog powerline status bar
|
||||||
|
# requires: aifont, ailog, jq
|
||||||
|
|
||||||
|
INTERVAL=60
|
||||||
|
SEP=$'\ue0b0'
|
||||||
|
RSEP=$'\ue0b2'
|
||||||
|
|
||||||
|
get_icon() {
|
||||||
|
local handle=$(ailog pds s 2>/dev/null | jq -r '.handle // empty' 2>/dev/null)
|
||||||
|
case "$handle" in
|
||||||
|
ai.*) echo $'\ue001' ;;
|
||||||
|
syui.*) echo $'\ue002' ;;
|
||||||
|
*) echo "❯" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
get_cfg() {
|
||||||
|
case "$(uname)" in
|
||||||
|
Darwin) echo "$HOME/Library/Application Support/ai.syui.log/config.json" ;;
|
||||||
|
*) echo "${XDG_CONFIG_HOME:-$HOME/.config}/ai.syui.log/config.json" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
has_aifont() {
|
||||||
|
[ -f "$HOME/Library/Fonts/aifont.ttf" ] || [ -f "$HOME/.local/share/fonts/aifont.ttf" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
can_run() {
|
||||||
|
local cfg=$(get_cfg)
|
||||||
|
command -v ailog &>/dev/null && command -v jq &>/dev/null && [ -f "$cfg" ] && has_aifont
|
||||||
|
}
|
||||||
|
|
||||||
|
get_handle() {
|
||||||
|
ailog pds s 2>/dev/null | jq -r '.handle // empty' 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
get_notify_count() {
|
||||||
|
ailog notify count 2>/dev/null | jq -r '.count // 0' 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
get_latest_post() {
|
||||||
|
local data=$(ailog f tl -l 1 2>/dev/null | tr -d '\t' | sed 's/\\n/ /g')
|
||||||
|
local handle=$(echo "$data" | jq -r '.feed[0].post.author.handle // empty' 2>/dev/null | cut -d. -f1)
|
||||||
|
local full=$(echo "$data" | jq -r '.feed[0].post.record.text // empty' 2>/dev/null | tr '\n' ' ')
|
||||||
|
local text="${full:0:20}"
|
||||||
|
[[ ${#full} -gt 20 ]] && text+="..."
|
||||||
|
[ -n "$text" ] && echo "@${handle} ${text}"
|
||||||
|
}
|
||||||
|
|
||||||
|
status_left() {
|
||||||
|
can_run || return
|
||||||
|
local handle=$(get_handle)
|
||||||
|
local count=$(get_notify_count)
|
||||||
|
local post=$(get_latest_post)
|
||||||
|
|
||||||
|
local icon=$(get_icon)
|
||||||
|
local out=""
|
||||||
|
out+="#[fg=yellow,bg=black] ${icon} "
|
||||||
|
out+="#[fg=black,bg=colour234]${SEP}"
|
||||||
|
out+="#[fg=yellow,bg=colour234] @${handle} "
|
||||||
|
if [ -n "$count" ] && [ "$count" != "0" ] && [ "$count" != "null" ]; then
|
||||||
|
out+="#[fg=colour234,bg=black]${SEP}"
|
||||||
|
out+="#[fg=yellow,bg=black] ${count} "
|
||||||
|
else
|
||||||
|
out+="#[fg=colour234,bg=black]${SEP}"
|
||||||
|
fi
|
||||||
|
if [ -n "$post" ]; then
|
||||||
|
out+="#[fg=white,bg=black] ${post} "
|
||||||
|
fi
|
||||||
|
out+="#[fg=black,bg=default]${SEP}#[default] "
|
||||||
|
echo -n "$out"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_pds() {
|
||||||
|
ailog pds s 2>/dev/null | jq -r '.issuer // empty' 2>/dev/null | sed 's|https://||'
|
||||||
|
}
|
||||||
|
|
||||||
|
status_right() {
|
||||||
|
local pds=$(get_pds)
|
||||||
|
local out=""
|
||||||
|
if [ -n "$pds" ]; then
|
||||||
|
out+="#[fg=colour236]${RSEP}#[fg=cyan,bg=colour236] ${pds} "
|
||||||
|
fi
|
||||||
|
out+="#[fg=colour234]${RSEP}#[fg=white,bg=colour234] #S "
|
||||||
|
echo -n "$out"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
left) status_left ;;
|
||||||
|
right) status_right ;;
|
||||||
|
notify) get_notify_count ;;
|
||||||
|
handle) get_handle ;;
|
||||||
|
latest) get_latest_post ;;
|
||||||
|
*)
|
||||||
|
if can_run; then
|
||||||
|
tmux set-option -g status-style "bg=default,fg=white"
|
||||||
|
tmux set-window-option -g window-status-format ""
|
||||||
|
tmux set-window-option -g window-status-current-format ""
|
||||||
|
tmux set-option -g status-left-length 100
|
||||||
|
tmux set-option -g status-right-length 50
|
||||||
|
tmux set-option -g status-left "#(~/.tmux/plugin/ailog.zsh left)"
|
||||||
|
tmux set-option -g status-right "#(~/.tmux/plugin/ailog.zsh right)#[fg=black,bg=colour234]${RSEP}#[fg=white,bg=black] %Y-%m-%dT%H:%M "
|
||||||
|
tmux set-option -g status-interval $INTERVAL
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
7
.tmux/plugin/urlopen.zsh
Executable file
7
.tmux/plugin/urlopen.zsh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
url=$(tmux capture-pane -pJ -S -100 | grep -oE 'https?://[^ ]+' | tail -1)
|
||||||
|
[ -z "$url" ] && exit 0
|
||||||
|
case "$(uname)" in
|
||||||
|
Darwin) open "$url" ;;
|
||||||
|
*) xdg-open "$url" ;;
|
||||||
|
esac
|
||||||
26
.vim/plugin/autosave.vim
Normal file
26
.vim/plugin/autosave.vim
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
if exists('g:loaded_autosave')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
let g:loaded_autosave = 1
|
||||||
|
|
||||||
|
let g:autosave = get(g:, 'autosave', 0)
|
||||||
|
|
||||||
|
fu! s:autosave_start()
|
||||||
|
aug autosave
|
||||||
|
au!
|
||||||
|
au TextChanged,CursorHold,InsertLeave * sil! update
|
||||||
|
aug END
|
||||||
|
echo 'autosave: on'
|
||||||
|
endf
|
||||||
|
|
||||||
|
fu! s:autosave_stop()
|
||||||
|
au! autosave
|
||||||
|
echo 'autosave: off'
|
||||||
|
endf
|
||||||
|
|
||||||
|
com! AirsaveOn call <SID>autosave_start()
|
||||||
|
com! AirsaveOff call <SID>autosave_stop()
|
||||||
|
|
||||||
|
if g:autosave
|
||||||
|
call <SID>autosave_start()
|
||||||
|
endif
|
||||||
37
.vimrc
Normal file
37
.vimrc
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
set nocompatible
|
||||||
|
set encoding=utf-8
|
||||||
|
set fileencoding=utf-8
|
||||||
|
set number
|
||||||
|
set ruler
|
||||||
|
set cursorline
|
||||||
|
set showmatch
|
||||||
|
set laststatus=2
|
||||||
|
set wildmenu
|
||||||
|
set showcmd
|
||||||
|
|
||||||
|
set tabstop=4
|
||||||
|
set shiftwidth=4
|
||||||
|
set softtabstop=4
|
||||||
|
set autoindent
|
||||||
|
set smartindent
|
||||||
|
|
||||||
|
set incsearch
|
||||||
|
set hlsearch
|
||||||
|
set ignorecase
|
||||||
|
set smartcase
|
||||||
|
set wrapscan
|
||||||
|
|
||||||
|
set backspace=indent,eol,start
|
||||||
|
set clipboard=unnamed
|
||||||
|
set mouse=a
|
||||||
|
set ttimeoutlen=10
|
||||||
|
|
||||||
|
let g:autosave = 1
|
||||||
|
nnoremap Q :q!<CR>
|
||||||
|
|
||||||
|
call plug#begin('~/.vim/plugged')
|
||||||
|
Plug 'github/copilot.vim'
|
||||||
|
call plug#end()
|
||||||
|
|
||||||
|
syntax on
|
||||||
|
filetype plugin indent on
|
||||||
57
.zsh/plugin/cdselect.zsh
Normal file
57
.zsh/plugin/cdselect.zsh
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
|
||||||
|
add-zsh-hook chpwd chpwd_recent_dirs
|
||||||
|
zstyle ':chpwd:*' recent-dirs-max 50
|
||||||
|
|
||||||
|
cdselect() {
|
||||||
|
local dirs=("${(@f)$(cdr -l 2>/dev/null | sed 's/^[0-9]* *//')}")
|
||||||
|
[[ ${#dirs} -eq 0 ]] && return
|
||||||
|
local query="" cursor=1 selected=""
|
||||||
|
while true; do
|
||||||
|
local filtered=()
|
||||||
|
for d in "${dirs[@]}"; do
|
||||||
|
local match=1
|
||||||
|
for word in ${(s: :)query}; do
|
||||||
|
[[ "${d:l}" != *"${word:l}"* ]] && match=0 && break
|
||||||
|
done
|
||||||
|
[[ $match -eq 1 ]] && filtered+=("$d")
|
||||||
|
done
|
||||||
|
# sort by path length (shortest first)
|
||||||
|
local sorted=()
|
||||||
|
for f in "${filtered[@]}"; do sorted+=("${#f} $f"); done
|
||||||
|
sorted=(${(n)sorted})
|
||||||
|
filtered=()
|
||||||
|
for s in "${sorted[@]}"; do filtered+=("${s#* }"); done
|
||||||
|
[[ $cursor -gt ${#filtered} ]] && cursor=${#filtered}
|
||||||
|
[[ $cursor -lt 1 ]] && cursor=1
|
||||||
|
clear
|
||||||
|
echo "cd> $query"
|
||||||
|
local i=1
|
||||||
|
for d in "${filtered[@]}"; do
|
||||||
|
if [[ $i -eq $cursor ]]; then
|
||||||
|
printf "\e[7m %s\e[0m\n" "$d"
|
||||||
|
else
|
||||||
|
printf " %s\n" "$d"
|
||||||
|
fi
|
||||||
|
((i++))
|
||||||
|
[[ $i -gt 20 ]] && break
|
||||||
|
done
|
||||||
|
read -k1 key 2>/dev/null
|
||||||
|
case "$key" in
|
||||||
|
$'\n'|$'\r') [[ ${#filtered} -gt 0 ]] && selected="${filtered[$cursor]}"; break ;;
|
||||||
|
$'\x0e') ((cursor++)) ;; # C-n
|
||||||
|
$'\x10') ((cursor--)) ;; # C-p
|
||||||
|
$'\x7f'|$'\b') query="${query%?}"; cursor=1 ;;
|
||||||
|
$'\x1b') break ;;
|
||||||
|
*) query+="$key"; cursor=1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
clear
|
||||||
|
if [[ -n "$selected" ]]; then
|
||||||
|
selected="${selected/#\~/$HOME}"
|
||||||
|
selected="${selected//\\ / }"
|
||||||
|
cd "$selected"
|
||||||
|
fi
|
||||||
|
zle reset-prompt
|
||||||
|
}
|
||||||
|
zle -N cdselect
|
||||||
|
bindkey '^j' cdselect
|
||||||
3
.zsh/plugin/cdup.zsh
Normal file
3
.zsh/plugin/cdup.zsh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
cdup() { [[ -z "$BUFFER" ]] && { cd ..; zle reset-prompt } || zle self-insert 'k' }
|
||||||
|
zle -N cdup
|
||||||
|
bindkey '^k' cdup
|
||||||
14
.zsh/plugin/clipcopy.zsh
Normal file
14
.zsh/plugin/clipcopy.zsh
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# copy prompt buffer to clipboard
|
||||||
|
# C-p C-p (chord)
|
||||||
|
|
||||||
|
clipcopy() {
|
||||||
|
if [[ -n "$BUFFER" ]]; then
|
||||||
|
case "$(uname)" in
|
||||||
|
Darwin) echo -n "$BUFFER" | pbcopy ;;
|
||||||
|
*) echo -n "$BUFFER" | xclip -sel c 2>/dev/null ;;
|
||||||
|
esac
|
||||||
|
zle -M "copied"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
zle -N clipcopy
|
||||||
|
bindkey '^p^p' clipcopy
|
||||||
49
.zsh/plugin/fileselect.zsh
Normal file
49
.zsh/plugin/fileselect.zsh
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# file select - search files and insert into prompt
|
||||||
|
# C-f: open file selector
|
||||||
|
|
||||||
|
fileselect() {
|
||||||
|
local files=("${(@f)$(find . -maxdepth 3 -not -path '*/\.git/*' -type f 2>/dev/null | sed 's|^\./||' | sort)}")
|
||||||
|
[[ ${#files} -eq 0 ]] && return
|
||||||
|
local query="" cursor=1 selected=""
|
||||||
|
while true; do
|
||||||
|
local filtered=()
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
local match=1
|
||||||
|
for word in ${(s: :)query}; do
|
||||||
|
[[ "${f:l}" != *"${word:l}"* ]] && match=0 && break
|
||||||
|
done
|
||||||
|
[[ $match -eq 1 ]] && filtered+=("$f")
|
||||||
|
done
|
||||||
|
[[ $cursor -gt ${#filtered} ]] && cursor=${#filtered}
|
||||||
|
[[ $cursor -lt 1 ]] && cursor=1
|
||||||
|
clear
|
||||||
|
echo "file> $query (${#filtered})"
|
||||||
|
local i=1
|
||||||
|
for f in "${filtered[@]}"; do
|
||||||
|
if [[ $i -eq $cursor ]]; then
|
||||||
|
printf "\e[7m %s\e[0m\n" "$f"
|
||||||
|
else
|
||||||
|
printf " %s\n" "$f"
|
||||||
|
fi
|
||||||
|
((i++))
|
||||||
|
[[ $i -gt 20 ]] && break
|
||||||
|
done
|
||||||
|
read -k1 key 2>/dev/null
|
||||||
|
case "$key" in
|
||||||
|
$'\n'|$'\r') [[ ${#filtered} -gt 0 ]] && selected="${filtered[$cursor]}"; break ;;
|
||||||
|
$'\x0e') ((cursor++)) ;; # C-n
|
||||||
|
$'\x10') ((cursor--)) ;; # C-p
|
||||||
|
$'\x7f'|$'\b') query="${query%?}"; cursor=1 ;;
|
||||||
|
$'\x1b') break ;;
|
||||||
|
*) query+="$key"; cursor=1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
clear
|
||||||
|
if [[ -n "$selected" ]]; then
|
||||||
|
BUFFER+="$selected"
|
||||||
|
CURSOR=${#BUFFER}
|
||||||
|
fi
|
||||||
|
zle reset-prompt
|
||||||
|
}
|
||||||
|
zle -N fileselect
|
||||||
|
bindkey '^f' fileselect
|
||||||
49
.zsh/plugin/histselect.zsh
Normal file
49
.zsh/plugin/histselect.zsh
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# history select - search history and insert into prompt
|
||||||
|
# C-r: open history selector, type to filter, C-n/C-p to move, Enter to insert
|
||||||
|
|
||||||
|
histselect() {
|
||||||
|
local lines=("${(@f)$(fc -l -n -r 1 | awk '!seen[$0]++')}")
|
||||||
|
[[ ${#lines} -eq 0 ]] && return
|
||||||
|
local query="" cursor=1 selected=""
|
||||||
|
while true; do
|
||||||
|
local filtered=()
|
||||||
|
for l in "${lines[@]}"; do
|
||||||
|
local match=1
|
||||||
|
for word in ${(s: :)query}; do
|
||||||
|
[[ "${l:l}" != *"${word:l}"* ]] && match=0 && break
|
||||||
|
done
|
||||||
|
[[ $match -eq 1 ]] && filtered+=("$l")
|
||||||
|
done
|
||||||
|
[[ $cursor -gt ${#filtered} ]] && cursor=${#filtered}
|
||||||
|
[[ $cursor -lt 1 ]] && cursor=1
|
||||||
|
clear
|
||||||
|
echo "hist> $query"
|
||||||
|
local i=1
|
||||||
|
for l in "${filtered[@]}"; do
|
||||||
|
if [[ $i -eq $cursor ]]; then
|
||||||
|
printf "\e[7m %s\e[0m\n" "$l"
|
||||||
|
else
|
||||||
|
printf " %s\n" "$l"
|
||||||
|
fi
|
||||||
|
((i++))
|
||||||
|
[[ $i -gt 20 ]] && break
|
||||||
|
done
|
||||||
|
read -k1 key 2>/dev/null
|
||||||
|
case "$key" in
|
||||||
|
$'\n'|$'\r') [[ ${#filtered} -gt 0 ]] && selected="${filtered[$cursor]}"; break ;;
|
||||||
|
$'\x0e') ((cursor++)) ;; # C-n
|
||||||
|
$'\x10') ((cursor--)) ;; # C-p
|
||||||
|
$'\x7f'|$'\b') query="${query%?}"; cursor=1 ;;
|
||||||
|
$'\x1b') break ;;
|
||||||
|
*) query+="$key"; cursor=1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
clear
|
||||||
|
if [[ -n "$selected" ]]; then
|
||||||
|
BUFFER="$selected"
|
||||||
|
CURSOR=${#BUFFER}
|
||||||
|
fi
|
||||||
|
zle reset-prompt
|
||||||
|
}
|
||||||
|
zle -N histselect
|
||||||
|
bindkey '^r' histselect
|
||||||
55
.zsh/plugin/powerline.zsh
Normal file
55
.zsh/plugin/powerline.zsh
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# powerline prompt
|
||||||
|
# requires: aifont (MesloLGS NF + ai/syui icons)
|
||||||
|
|
||||||
|
_has_aifont() {
|
||||||
|
[[ -f "$HOME/Library/Fonts/aifont.ttf" ]] || [[ -f "$HOME/.local/share/fonts/aifont.ttf" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
_powerline_git() {
|
||||||
|
local branch=$(git symbolic-ref --short HEAD 2>/dev/null) || return
|
||||||
|
local dirty=""
|
||||||
|
[[ -n $(git status --porcelain 2>/dev/null) ]] && dirty="*"
|
||||||
|
echo "${branch}${dirty}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_powerline_icon() {
|
||||||
|
case "$USER" in
|
||||||
|
syui) echo $'\ue002' ;;
|
||||||
|
ai) echo $'\ue001' ;;
|
||||||
|
*) echo "❯" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
_powerline_prompt() {
|
||||||
|
local icon=$(_powerline_icon)
|
||||||
|
local sep=$'\ue0b0'
|
||||||
|
local dir="${PWD/#$HOME/~}"
|
||||||
|
local git=$(_powerline_git)
|
||||||
|
|
||||||
|
local prompt=""
|
||||||
|
if [[ -n "$icon" ]]; then
|
||||||
|
prompt+="%F{yellow}%K{black} ${icon} %k%f"
|
||||||
|
prompt+="%F{black}%K{234}${sep}%f"
|
||||||
|
else
|
||||||
|
prompt+="%F{234}${sep}%f"
|
||||||
|
fi
|
||||||
|
prompt+="%F{yellow}%K{234} $USER %k%f"
|
||||||
|
prompt+="%F{234}%K{236}${sep}%f"
|
||||||
|
prompt+="%F{white}%K{236} ${dir} %k%f"
|
||||||
|
|
||||||
|
if [[ -n "$git" ]]; then
|
||||||
|
prompt+="%F{236}%K{234}${sep}%f"
|
||||||
|
prompt+="%F{cyan}%K{234} ${git} %k%f"
|
||||||
|
prompt+="%F{234}${sep}%f"
|
||||||
|
else
|
||||||
|
prompt+="%F{236}${sep}%f"
|
||||||
|
fi
|
||||||
|
prompt+="%k%f "
|
||||||
|
|
||||||
|
echo "$prompt"
|
||||||
|
}
|
||||||
|
|
||||||
|
if _has_aifont; then
|
||||||
|
setopt PROMPT_SUBST
|
||||||
|
PROMPT='$(_powerline_prompt)'
|
||||||
|
fi
|
||||||
64
.zshrc
Normal file
64
.zshrc
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
export CARGO_HOME="$HOME/.cargo"
|
||||||
|
export RUSTUP_HOME="$HOME/.rustup"
|
||||||
|
export PATH="$HOME/.cargo/bin:$HOME/.local/bin:$PATH"
|
||||||
|
|
||||||
|
if command -v tmux &>/dev/null && [ -z "$TMUX" ] && [ -z "$SSH_CONNECTION" ]; then
|
||||||
|
tmux new
|
||||||
|
fi
|
||||||
|
|
||||||
|
alias c="claude"
|
||||||
|
alias t="tmux"
|
||||||
|
alias v="vim"
|
||||||
|
alias ts="vim ~/.tmux.conf"
|
||||||
|
alias vs="vim ~/.vimrc"
|
||||||
|
alias zs="vim ~/.zshrc"
|
||||||
|
alias zr="exec $SHELL && . ~/.zshrc"
|
||||||
|
alias ll="ls -alh"
|
||||||
|
alias df="df -H"
|
||||||
|
alias f="vren"
|
||||||
|
|
||||||
|
zmodload zsh/complist
|
||||||
|
zstyle ':completion:*' menu select
|
||||||
|
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
|
||||||
|
autoload -Uz compinit
|
||||||
|
compinit
|
||||||
|
bindkey -M menuselect '^n' down-line-or-history
|
||||||
|
bindkey -M menuselect '^p' up-line-or-history
|
||||||
|
#bindkey -M menuselect '^j' accept-and-menu-complete
|
||||||
|
|
||||||
|
HISTSIZE=10000
|
||||||
|
SAVEHIST=10000
|
||||||
|
HISTFILE=~/.zsh_history
|
||||||
|
setopt SHARE_HISTORY
|
||||||
|
setopt HIST_IGNORE_DUPS
|
||||||
|
|
||||||
|
case $OSTYPE in
|
||||||
|
darwin*)
|
||||||
|
alias ls="ls -aG"
|
||||||
|
alias ll="ls -alhG"
|
||||||
|
alias date=/opt/homebrew/bin/gdate
|
||||||
|
alias u="brew update && brew upgrade && brew doctor"
|
||||||
|
export PATH="/opt/homebrew/bin:$PATH"
|
||||||
|
;;
|
||||||
|
linux*)
|
||||||
|
alias ls="ls -a --color=auto"
|
||||||
|
alias ll="ls -alh --color=auto"
|
||||||
|
alias u="sudo pacman -Syu --noconfirm"
|
||||||
|
fpath=(/usr/share/zsh/site-functions $fpath)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
for p in /opt/homebrew/share /usr/share/zsh/plugins; do
|
||||||
|
[ -f "$p/zsh-autosuggestions/zsh-autosuggestions.zsh" ] && source "$p/zsh-autosuggestions/zsh-autosuggestions.zsh"
|
||||||
|
[ -f "$p/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ] && source "$p/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
|
||||||
|
[ -f "$p/zsh-history-substring-search/zsh-history-substring-search.zsh" ] && source "$p/zsh-history-substring-search/zsh-history-substring-search.zsh"
|
||||||
|
done
|
||||||
|
|
||||||
|
bindkey '^[[A' history-substring-search-up
|
||||||
|
bindkey '^[[B' history-substring-search-down
|
||||||
|
|
||||||
|
chpwd() { ls }
|
||||||
|
|
||||||
|
for f in ~/.zsh/plugin/*.zsh; do source "$f"; done
|
||||||
|
|
||||||
|
|
||||||
51
install.zsh
Executable file
51
install.zsh
Executable file
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
# dotfiles installer
|
||||||
|
# usage: ./install.zsh [dotfiles_dir]
|
||||||
|
|
||||||
|
dotdir="${1:-$HOME/dotfiles}"
|
||||||
|
|
||||||
|
files=(.zshrc .vimrc .tmux.conf .gitconfig)
|
||||||
|
dirs=(.zsh .vim/plugin .tmux .local/bin .local/share/fonts)
|
||||||
|
|
||||||
|
# backup and symlink files
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
src="$dotdir/$f"
|
||||||
|
dst="$HOME/$f"
|
||||||
|
[ ! -f "$src" ] && continue
|
||||||
|
if [ -e "$dst" ] && [ ! -L "$dst" ]; then
|
||||||
|
mv "$dst" "${dst}.bak"
|
||||||
|
echo "backup: $dst -> ${dst}.bak"
|
||||||
|
fi
|
||||||
|
ln -sf "$src" "$dst"
|
||||||
|
echo "link: $dst -> $src"
|
||||||
|
done
|
||||||
|
|
||||||
|
# symlink directories
|
||||||
|
for d in "${dirs[@]}"; do
|
||||||
|
src="$dotdir/.${d#.}"
|
||||||
|
dst="$HOME/.${d#.}"
|
||||||
|
# handle nested dirs
|
||||||
|
if [[ "$d" == */* ]]; then
|
||||||
|
src="$dotdir/$d"
|
||||||
|
dst="$HOME/$d"
|
||||||
|
mkdir -p "$(dirname "$dst")"
|
||||||
|
else
|
||||||
|
src="$dotdir/$d"
|
||||||
|
dst="$HOME/$d"
|
||||||
|
fi
|
||||||
|
[ ! -d "$src" ] && continue
|
||||||
|
if [ -d "$dst" ] && [ ! -L "$dst" ]; then
|
||||||
|
mv "$dst" "${dst}.bak"
|
||||||
|
echo "backup: $dst -> ${dst}.bak"
|
||||||
|
fi
|
||||||
|
ln -sf "$src" "$dst"
|
||||||
|
echo "link: $dst -> $src"
|
||||||
|
done
|
||||||
|
|
||||||
|
# install font (mac only)
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ -f "$dotdir/.local/share/fonts/aifont.ttf" ]; then
|
||||||
|
cp -f "$dotdir/.local/share/fonts/aifont.ttf" ~/Library/Fonts/aifont.ttf
|
||||||
|
echo "font: aifont.ttf -> ~/Library/Fonts/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "done"
|
||||||
Reference in New Issue
Block a user