Merge branch 'master' of http://192.168.0.144:3000/anon/dotfiles
This commit is contained in:
commit
a3b9ba5d92
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ vim/.vim/.netrwhist
|
||||
cache.db
|
||||
.cache/*
|
||||
tags.vim
|
||||
sigs.vim
|
||||
|
43
bash/.bashrc
43
bash/.bashrc
@ -48,7 +48,7 @@ export VISUAL="vim"
|
||||
export BROWSER="librewolf"
|
||||
export PAGER="less"
|
||||
export IMAGEVIEWER="nomacs"
|
||||
export MANPAGER='recursivelyExpandedAlias less'
|
||||
export MANPAGER='less --mouse'
|
||||
#pragma endregion
|
||||
### Quick Access ###
|
||||
#pragma region
|
||||
@ -252,16 +252,6 @@ alias bat='bat --italic-text always'
|
||||
alias hexedit='hexedit --color'
|
||||
alias less='less --use-color'
|
||||
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
|
||||
if [ -x /usr/bin/dircolors ]; then
|
||||
[ -n "$LS_COLORS" ] || (test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)")
|
||||
export LESS_TERMCAP_mb=$'\E[1;31m' # begin blink
|
||||
export LESS_TERMCAP_md=$'\E[1;36m' # begin bold
|
||||
export LESS_TERMCAP_me=$'\E[0m' # reset bold/blink
|
||||
export LESS_TERMCAP_so=$'\E[01;33m' # begin reverse video
|
||||
export LESS_TERMCAP_se=$'\E[0m' # reset reverse video
|
||||
export LESS_TERMCAP_us=$'\E[1;32m' # begin underline
|
||||
export LESS_TERMCAP_ue=$'\E[0m' # reset underline
|
||||
fi
|
||||
#pragma endregion
|
||||
### Safety ###
|
||||
#pragma region
|
||||
@ -280,7 +270,7 @@ alias mkdir='mkdir -p'
|
||||
alias lsblk='lsblk -o LABEL,NAME,SIZE,FSUSE%,RM,RO,TYPE,FSTYPE,MOUNTPOINTS'
|
||||
alias hgrep='\history | grep'
|
||||
alias history='history | tail -n 10'
|
||||
alias clear="clear; env echo -e \"${FAVCOLESC}###\033[0m\"; dirs"
|
||||
alias clear="\clear; env echo -e \"${FAVCOLESC}###\033[0m\"; dirs"
|
||||
alias cal='cal --monday'
|
||||
alias nmap='nmap --stats-every 5s'
|
||||
#pragma endregion
|
||||
@ -331,6 +321,7 @@ alias gpg='gpg -i --no-symkey-cache'
|
||||
##### Lynx ####
|
||||
export WWW_HOME="${HOME}/lynx_bookmarks.html"
|
||||
##### locate ####
|
||||
alias locate='locate --regexp'
|
||||
alias locatei='locate -i'
|
||||
##### figlet ####
|
||||
alias figlet="figlet -w 120 -d ${MM}/Fonts/figlet-fonts/"
|
||||
@ -338,6 +329,14 @@ alias figlet="figlet -w 120 -d ${MM}/Fonts/figlet-fonts/"
|
||||
export FZF_DEFAULT_OPTS='--multi --no-mouse --height=10 --layout=reverse'
|
||||
##### tmux ####
|
||||
alias tmux='tmux new-session -t '0' || tmux'
|
||||
##### stat ####
|
||||
function statAlias() {
|
||||
\stat $@ | perl -pe 's/(.*?): (.*)/\033[33;1m$1:\033[0m $2/'
|
||||
du -h -s "$1"
|
||||
}
|
||||
alias stat="statAlias"
|
||||
##### tgpt ####
|
||||
alias tgpt="\tmux resize-window -x 80; tgpt -m"
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
|
||||
@ -353,7 +352,8 @@ export PERL5LIB="$PERL5LIB:."
|
||||
#pragma endregion
|
||||
### Python ###
|
||||
#pragma region
|
||||
alias ipython="ipython -i ${MM}/Python/Pythonrc/init.py"
|
||||
export PYTHONSTARTUP="${HOME}/.pythonrc"
|
||||
alias ipython="ipython -i '${PYTHONSTARTUP}'"
|
||||
alias vsource='source ./venv/bin/activate'
|
||||
#pragma endregion
|
||||
### Java ###
|
||||
@ -374,13 +374,23 @@ export PATH="${PATH}:${HOME}/.cargo/bin/"
|
||||
# Custom Additions
|
||||
#pragma region
|
||||
function ffgrep() {
|
||||
fgrep "$1" ./**/* 2> /dev/null
|
||||
WHERE='.'
|
||||
[ "$2" != "" ] && WHERE="$2"
|
||||
[ -d "$WHERE" ] && WHERE="${WHERE}/**/*"
|
||||
fgrep "$1" ${WHERE} 2> /dev/null
|
||||
}
|
||||
function signin(){
|
||||
\sudo -u $1 bash
|
||||
}
|
||||
function testscript() {
|
||||
[ -n "$1" ] && SUFFIX=".$1"
|
||||
I=$(mktemp --tmpdir=$(realpath ~/Swap/tests/) --suffix="${SUFFIX}" XXXX)
|
||||
echo "\033[31;1m${I}\033[0m"
|
||||
$EDITOR $I
|
||||
}
|
||||
alias cbash='bash --norc --noprofile --init-file <(echo "unset HISTFILE")'
|
||||
alias resource='source ~/.bashrc'
|
||||
alias dmake='make --debug --trace --warn-undefined-variables'
|
||||
alias resource='unalias -a; source ~/.bashrc'
|
||||
alias xclip='xclip -selection clipboard'
|
||||
alias tt='tt_with_high_score.sh'
|
||||
#pragma endregion
|
||||
@ -392,7 +402,8 @@ source ${SRCF}/w.rc # watch (clock)
|
||||
source ${SRCF}/cd.rc
|
||||
source ${SRCF}/sudo.rc
|
||||
source ${SRCF}/fzfind.rc
|
||||
source ${SRCF}/ls_colors.rc
|
||||
[[ -f /usr/share/bash-completion/bash_completion ]] && \
|
||||
. /usr/share/bash-completion/bash_completion
|
||||
|
||||
|
||||
if [ "$USER" == "root" ]; then
|
||||
|
@ -1,87 +0,0 @@
|
||||
#!/bin/bash
|
||||
[ -z "$CTRLFMODE" ] && CTRLFMODE="path"
|
||||
[ -z "$CTRLFMETHOD" ] && CTRLFMETHOD="find"
|
||||
#CTRLCACHE="/home/anon/Desktop/"
|
||||
|
||||
function ctrl_f_mode(){
|
||||
read -n 1 M
|
||||
case $M in
|
||||
p) CTRLFMODE="path";;
|
||||
u) CTRLFMODE="user";;
|
||||
o) CTRLFMODE="opt";;
|
||||
c) CTRLFMODE="cmd" ;;
|
||||
v) CTRLFMODE="var" ;;
|
||||
*) CTRLFMODE="path";;
|
||||
esac
|
||||
env echo -e "\033[1mctrl-f mode: \"\033[0m${CTRLFMODE}\""
|
||||
}
|
||||
function echo_readline_line(){
|
||||
PS1_CLEANED="${PS1//\\\[/}"
|
||||
PS1_CLEANED="${PS1_CLEANED//\\\]/}"
|
||||
env echo -e "${PS1_CLEANED}${1:0:${2}}\033[45m \033[0m${1:${2}}"
|
||||
#env echo -e "${PS1}${1:0:${2}}\033[45m \033[0m${1:${2}}"
|
||||
}
|
||||
function ctrl_f(){
|
||||
# Show command and substitution position
|
||||
echo_readline_line "${READLINE_LINE}" "${READLINE_POINT}"
|
||||
# Get narrowing substring
|
||||
OPX=""
|
||||
if [ "${READLINE_LINE:$(expr $READLINE_POINT - 1):1}" != " " ]; then
|
||||
OPX=$(lastWord "${READLINE_LINE:0:${READLINE_POINT}}")
|
||||
fi
|
||||
#echo "'$PX'"
|
||||
# Decide possible completions and use fzf for selection
|
||||
case $CTRLFMODE in
|
||||
"path")
|
||||
if [ $CTRLFMETHOD == "find" ]; then
|
||||
PX="$OPX"
|
||||
STR=$(eval find ./"$PX/" 2> /dev/null | fzf --multi=1)
|
||||
elif [ $CTRLFMETHOD == "locate" ]; then
|
||||
PX="$(realpath $PWD/$OPX)"
|
||||
STR=$(eval locate --existing --regex $PX/'.*' 2> /dev/null | fzf --multi=1)
|
||||
else
|
||||
echo -e "\033[31;1mNonsensical \033[34;1m\${CTRLFMETHOD} \033[31;1mvalue.\033[0m"
|
||||
fi
|
||||
;;
|
||||
"opt")
|
||||
#get command
|
||||
#check catche
|
||||
#parse
|
||||
;;
|
||||
"user")
|
||||
if [ "$PX" != "" ]; then
|
||||
STR="$(compgen -u ${PX} | fzf --multi=1)"
|
||||
else
|
||||
STR="$(compgen -u | fzf --multi=1)"
|
||||
fi
|
||||
;;
|
||||
"cmd")
|
||||
if [ "$PX" != "" ]; then
|
||||
STR="$(compgen -c ${PX} | uniq | fzf --multi=1)"
|
||||
else
|
||||
STR="$(compgen -c | uniq | fzf --multi=1)"
|
||||
fi
|
||||
;;
|
||||
"var")
|
||||
if [ "$PX" != "" ]; then
|
||||
STR="$(compgen -v ${PX} | fzf --multi=1)"
|
||||
else
|
||||
STR="$(compgen -v | fzf --multi=1)"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
# Remove ${PX}
|
||||
STR="${STR/${PX}/}"
|
||||
# Write $READLINE_LINE
|
||||
[ -z "$STR" ] && return
|
||||
if [ "$CTRLFMODE" == "path" ]; then # quote paths
|
||||
READLINE_LINE="${READLINE_LINE:0:$(expr ${READLINE_POINT} - ${#OPX})}\"${OPX}${STR}\"${READLINE_LINE:${READLINE_POINT}}" # start_til_px + '"' + px + str '"' + rest
|
||||
READLINE_POINT=$(expr ${READLINE_POINT} + ${#OPX} + ${#STR} + 2) # +2 for the '"'s
|
||||
else
|
||||
READLINE_LINE="${READLINE_LINE:0:$(expr ${READLINE_POINT} - ${#OPX})}${OPX}${STR}${READLINE_LINE:${READLINE_POINT}}" # start_til_px + px + str + rest
|
||||
READLINE_POINT=$(expr ${READLINE_POINT} + ${#OPX} + ${#STR})
|
||||
fi
|
||||
}
|
||||
|
||||
bind -x '"\C-e": ctrl_f_mode'
|
||||
bind -x '"\C-f": ctrl_f'
|
@ -1 +0,0 @@
|
||||
alias bc="bc -l"
|
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
export PERL5LIB="$PERL5LIB:."
|
648
bash/.dir_colors
Normal file
648
bash/.dir_colors
Normal file
@ -0,0 +1,648 @@
|
||||
*.7z 38;5;40
|
||||
*.WARC 38;5;40
|
||||
*.a 38;5;40
|
||||
*.arj 38;5;40
|
||||
*.br 38;5;40
|
||||
*.bz2 38;5;40
|
||||
*.cpio 38;5;40
|
||||
*.gz 38;5;40
|
||||
*.lrz 38;5;40
|
||||
*.lz 38;5;40
|
||||
*.lzma 38;5;40
|
||||
*.lzo 38;5;40
|
||||
*.rar 38;5;40
|
||||
*.s7z 38;5;40
|
||||
*.sz 38;5;40
|
||||
*.tar 38;5;40
|
||||
*.tbz 38;5;40
|
||||
*.tgz 38;5;40
|
||||
*.warc 38;5;40
|
||||
*.xz 38;5;40
|
||||
*.z 38;5;40
|
||||
*.zip 38;5;40
|
||||
*.zipx 38;5;40
|
||||
*.zoo 38;5;40
|
||||
*.zpaq 38;5;40
|
||||
*.zst 38;5;40
|
||||
*.zstd 38;5;40
|
||||
*.zz 38;5;40
|
||||
*@.service 38;5;45
|
||||
*AUTHORS 38;5;220;1
|
||||
*CHANGELOG 38;5;220;1
|
||||
*CHANGELOG.md 38;5;220;1
|
||||
*CHANGES 38;5;220;1
|
||||
*CODEOWNERS 38;5;220;1
|
||||
*CONTRIBUTING 38;5;220;1
|
||||
*CONTRIBUTING.md 38;5;220;1
|
||||
*CONTRIBUTORS 38;5;220;1
|
||||
*COPYING 38;5;220;1
|
||||
*COPYRIGHT 38;5;220;1
|
||||
*CodeResources 38;5;239
|
||||
*Containerfile 38;5;155
|
||||
*Dockerfile 38;5;155
|
||||
*HISTORY 38;5;220;1
|
||||
*INSTALL 38;5;220;1
|
||||
*LICENSE 38;5;220;1
|
||||
*LICENSE.md 38;5;220;1
|
||||
*LS_COLORS 48;5;89;38;5;197;1;3;4;7
|
||||
*MANIFEST 38;5;243
|
||||
*Makefile 38;5;155
|
||||
*NOTICE 38;5;220;1
|
||||
*PATENTS 38;5;220;1
|
||||
*PkgInfo 38;5;239
|
||||
*README 38;5;220;1
|
||||
*README.md 38;5;220;1
|
||||
*README.rst 38;5;220;1
|
||||
*VERSION 38;5;220;1
|
||||
*authorized_keys 1
|
||||
*cfg 1
|
||||
*conf 1
|
||||
*config 1
|
||||
*core 38;5;241
|
||||
*id_dsa 38;5;192;3
|
||||
*id_ecdsa 38;5;192;3
|
||||
*id_ed25519 38;5;192;3
|
||||
*id_rsa 38;5;192;3
|
||||
*known_hosts 1
|
||||
*lock 38;5;248
|
||||
*lockfile 38;5;248
|
||||
*pm_to_blib 38;5;240
|
||||
*rc 1
|
||||
*.1p 38;5;7
|
||||
*.32x 38;5;213
|
||||
*.3g2 38;5;115
|
||||
*.3ga 38;5;137;1
|
||||
*.3gp 38;5;115
|
||||
*.3p 38;5;7
|
||||
*.82p 38;5;121
|
||||
*.83p 38;5;121
|
||||
*.8eu 38;5;121
|
||||
*.8xe 38;5;121
|
||||
*.8xp 38;5;121
|
||||
*.A64 38;5;213
|
||||
*.BAT 38;5;172
|
||||
*.BUP 38;5;241
|
||||
*.C 38;5;81
|
||||
*.CFUserTextEncoding 38;5;239
|
||||
*.DS_Store 38;5;239
|
||||
*.F 38;5;81
|
||||
*.F03 38;5;81
|
||||
*.F08 38;5;81
|
||||
*.F90 38;5;81
|
||||
*.F95 38;5;81
|
||||
*.H 38;5;110
|
||||
*.IFO 38;5;114
|
||||
*.JPG 38;5;97
|
||||
*.M 38;5;110
|
||||
*.MOV 38;5;114
|
||||
*.PDF 38;5;141
|
||||
*.PFA 38;5;66
|
||||
*.PL 38;5;160
|
||||
*.R 38;5;49
|
||||
*.RData 38;5;178
|
||||
*.Rproj 38;5;11
|
||||
*.S 38;5;110
|
||||
*.S3M 38;5;137;1
|
||||
*.SKIP 38;5;244
|
||||
*.TIFF 38;5;97
|
||||
*.VOB 38;5;115;1
|
||||
*.a00 38;5;213
|
||||
*.a52 38;5;213
|
||||
*.a64 38;5;213
|
||||
*.a78 38;5;213
|
||||
*.aac 38;5;137;1
|
||||
*.accdb 38;5;60
|
||||
*.accde 38;5;60
|
||||
*.accdr 38;5;60
|
||||
*.accdt 38;5;60
|
||||
*.adf 38;5;213
|
||||
*.adoc 38;5;184
|
||||
*.afm 38;5;66
|
||||
*.agda 38;5;81
|
||||
*.agdai 38;5;110
|
||||
*.ahk 38;5;41
|
||||
*.ai 38;5;99
|
||||
*.aiff 38;5;136;1
|
||||
*.alac 38;5;136;1
|
||||
*.allow 38;5;112
|
||||
*.am 38;5;242
|
||||
*.amr 38;5;137;1
|
||||
*.ape 38;5;136;1
|
||||
*.apk 38;5;215
|
||||
*.application 38;5;116
|
||||
*.aria2 38;5;241
|
||||
*.asc 38;5;192;3
|
||||
*.asciidoc 38;5;184
|
||||
*.asf 38;5;115
|
||||
*.asm 38;5;81
|
||||
*.ass 38;5;117
|
||||
*.astro 38;5;135;1
|
||||
*.atr 38;5;213
|
||||
*.au 38;5;137;1
|
||||
*.automount 38;5;45
|
||||
*.avi 38;5;114
|
||||
*.awk 38;5;172
|
||||
*.bak 38;5;241
|
||||
*.bash 38;5;172
|
||||
*.bash_login 1
|
||||
*.bash_logout 1
|
||||
*.bash_profile 1
|
||||
*.bat 38;5;172
|
||||
*.bfe 38;5;192;3
|
||||
*.bib 38;5;178
|
||||
*.bin 38;5;124
|
||||
*.bmp 38;5;97
|
||||
*.bsp 38;5;215
|
||||
*.c 38;5;81
|
||||
*.c++ 38;5;81
|
||||
*.cab 38;5;215
|
||||
*.caf 38;5;137;1
|
||||
*.cap 38;5;29
|
||||
*.car 38;5;57
|
||||
*.cbr 38;5;141
|
||||
*.cbz 38;5;141
|
||||
*.cc 38;5;81
|
||||
*.cda 38;5;136;1
|
||||
*.cdi 38;5;213
|
||||
*.cdr 38;5;97
|
||||
*.chm 38;5;141
|
||||
*.cjs 38;5;074;1
|
||||
*.cl 38;5;81
|
||||
*.clj 38;5;41
|
||||
*.cljc 38;5;41
|
||||
*.cljs 38;5;41
|
||||
*.cljw 38;5;41
|
||||
*.cnc 38;5;7
|
||||
*.coffee 38;5;079;1
|
||||
*.comp 38;5;136
|
||||
*.containerignore 38;5;240
|
||||
*.cp 38;5;81
|
||||
*.cpp 38;5;81
|
||||
*.cr 38;5;81
|
||||
*.crx 38;5;215
|
||||
*.cs 38;5;81
|
||||
*.css 38;5;105;1
|
||||
*.csv 38;5;78
|
||||
*.ctp 38;5;81
|
||||
*.cue 38;5;116
|
||||
*.cxx 38;5;81
|
||||
*.dart 38;5;51
|
||||
*.dat 38;5;137;1
|
||||
*.db 38;5;60
|
||||
*.deb 38;5;215
|
||||
*.def 38;5;7
|
||||
*.deny 38;5;196
|
||||
*.description 38;5;116
|
||||
*.device 38;5;45
|
||||
*.dhall 38;5;178
|
||||
*.dicom 38;5;97
|
||||
*.diff 48;5;197;38;5;232
|
||||
*.directory 38;5;116
|
||||
*.divx 38;5;114
|
||||
*.djvu 38;5;141
|
||||
*.dll 38;5;241
|
||||
*.dmg 38;5;215
|
||||
*.dmp 38;5;29
|
||||
*.doc 38;5;111
|
||||
*.dockerignore 38;5;240
|
||||
*.docm 38;5;111;4
|
||||
*.docx 38;5;111
|
||||
*.drw 38;5;99
|
||||
*.dtd 38;5;178
|
||||
*.dts 38;5;137;1
|
||||
*.dump 38;5;241
|
||||
*.dwg 38;5;216
|
||||
*.dylib 38;5;241
|
||||
*.ear 38;5;215
|
||||
*.ejs 38;5;135;1
|
||||
*.el 38;5;81
|
||||
*.elc 38;5;241
|
||||
*.eln 38;5;241
|
||||
*.eml 38;5;90;1
|
||||
*.enc 38;5;192;3
|
||||
*.entitlements 1
|
||||
*.epf 1
|
||||
*.eps 38;5;99
|
||||
*.epsf 38;5;99
|
||||
*.epub 38;5;141
|
||||
*.err 38;5;160;1
|
||||
*.error 38;5;160;1
|
||||
*.etx 38;5;184
|
||||
*.ex 38;5;7
|
||||
*.example 38;5;7
|
||||
*.f 38;5;81
|
||||
*.f03 38;5;81
|
||||
*.f08 38;5;81
|
||||
*.f4v 38;5;115
|
||||
*.f90 38;5;81
|
||||
*.f95 38;5;81
|
||||
*.fcm 38;5;137;1
|
||||
*.feature 38;5;7
|
||||
*.fish 38;5;172
|
||||
*.flac 38;5;136;1
|
||||
*.flif 38;5;97
|
||||
*.flv 38;5;115
|
||||
*.fm2 38;5;213
|
||||
*.fmp12 38;5;60
|
||||
*.fnt 38;5;66
|
||||
*.fon 38;5;66
|
||||
*.for 38;5;81
|
||||
*.fp7 38;5;60
|
||||
*.frag 38;5;136
|
||||
*.ftn 38;5;81
|
||||
*.fvd 38;5;124
|
||||
*.fxml 38;5;178
|
||||
*.gb 38;5;213
|
||||
*.gba 38;5;213
|
||||
*.gbc 38;5;213
|
||||
*.gbr 38;5;7
|
||||
*.gel 38;5;213
|
||||
*.gemspec 38;5;41
|
||||
*.ger 38;5;7
|
||||
*.gg 38;5;213
|
||||
*.ggl 38;5;213
|
||||
*.gif 38;5;97
|
||||
*.git 38;5;197
|
||||
*.gitattributes 38;5;240
|
||||
*.github 38;5;197
|
||||
*.gitignore 38;5;240
|
||||
*.gitmodules 38;5;240
|
||||
*.go 38;5;81
|
||||
*.gp3 38;5;115
|
||||
*.gp4 38;5;115
|
||||
*.gpg 38;5;192;3
|
||||
*.gs 38;5;81
|
||||
*.h 38;5;110
|
||||
*.h++ 38;5;110
|
||||
*.hi 38;5;110
|
||||
*.hidden-color-scheme 1
|
||||
*.hidden-tmTheme 1
|
||||
*.hin 38;5;242
|
||||
*.hjson 38;5;178
|
||||
*.hpp 38;5;110
|
||||
*.hs 38;5;81
|
||||
*.htm 38;5;125;1
|
||||
*.html 38;5;125;1
|
||||
*.http 38;5;90;1
|
||||
*.hxx 38;5;110
|
||||
*.icns 38;5;97
|
||||
*.ico 38;5;97
|
||||
*.ics 38;5;7
|
||||
*.ii 38;5;110
|
||||
*.img 38;5;124
|
||||
*.iml 38;5;166
|
||||
*.in 38;5;242
|
||||
*.info 38;5;184
|
||||
*.ini 1
|
||||
*.ipa 38;5;215
|
||||
*.ipk 38;5;213
|
||||
*.ipynb 38;5;41
|
||||
*.iso 38;5;124
|
||||
*.j64 38;5;213
|
||||
*.jad 38;5;215
|
||||
*.jar 38;5;215
|
||||
*.java 38;5;079;1
|
||||
*.jhtm 38;5;125;1
|
||||
*.jpeg 38;5;97
|
||||
*.jpg 38;5;97
|
||||
*.js 38;5;074;1
|
||||
*.jsm 38;5;079;1
|
||||
*.json 38;5;178
|
||||
*.json5 38;5;178
|
||||
*.jsonc 38;5;178
|
||||
*.jsonl 38;5;178
|
||||
*.jsonnet 38;5;178
|
||||
*.jsp 38;5;079;1
|
||||
*.jsx 38;5;074;1
|
||||
*.jxl 38;5;97
|
||||
*.kak 38;5;172
|
||||
*.key 38;5;166
|
||||
*.lagda 38;5;81
|
||||
*.lagda.md 38;5;81
|
||||
*.lagda.rst 38;5;81
|
||||
*.lagda.tex 38;5;81
|
||||
*.last-run 1
|
||||
*.less 38;5;105;1
|
||||
*.lhs 38;5;81
|
||||
*.libsonnet 38;5;142
|
||||
*.lisp 38;5;81
|
||||
*.lnk 38;5;39
|
||||
*.localized 38;5;239
|
||||
*.localstorage 38;5;60
|
||||
*.log 38;5;190
|
||||
*.lua 38;5;81
|
||||
*.m 38;5;110
|
||||
*.m2v 38;5;114
|
||||
*.m3u 38;5;116
|
||||
*.m3u8 38;5;116
|
||||
*.m4 38;5;242
|
||||
*.m4a 38;5;137;1
|
||||
*.m4v 38;5;114
|
||||
*.map 38;5;7
|
||||
*.markdown 38;5;184
|
||||
*.md 38;5;184
|
||||
*.md5 38;5;116
|
||||
*.mdb 38;5;60
|
||||
*.mde 38;5;60
|
||||
*.mdump 38;5;241
|
||||
*.mdx 38;5;184
|
||||
*.merged-ca-bundle 1
|
||||
*.mf 38;5;7
|
||||
*.mfasl 38;5;7
|
||||
*.mht 38;5;125;1
|
||||
*.mi 38;5;7
|
||||
*.mid 38;5;136;1
|
||||
*.midi 38;5;136;1
|
||||
*.mjs 38;5;074;1
|
||||
*.mkd 38;5;184
|
||||
*.mkv 38;5;114
|
||||
*.ml 38;5;81
|
||||
*.mm 38;5;7
|
||||
*.mobi 38;5;141
|
||||
*.mod 38;5;137;1
|
||||
*.moon 38;5;81
|
||||
*.mount 38;5;45
|
||||
*.mov 38;5;114
|
||||
*.mp3 38;5;137;1
|
||||
*.mp4 38;5;114
|
||||
*.mp4a 38;5;137;1
|
||||
*.mpeg 38;5;114
|
||||
*.mpg 38;5;114
|
||||
*.msg 38;5;178
|
||||
*.msql 38;5;222
|
||||
*.mtx 38;5;7
|
||||
*.mustache 38;5;135;1
|
||||
*.mysql 38;5;222
|
||||
*.nc 38;5;60
|
||||
*.ndjson 38;5;178
|
||||
*.nds 38;5;213
|
||||
*.nes 38;5;213
|
||||
*.nfo 38;5;184
|
||||
*.nib 38;5;57
|
||||
*.nim 38;5;81
|
||||
*.nimble 38;5;81
|
||||
*.nix 38;5;155
|
||||
*.norg 38;5;184
|
||||
*.nrg 38;5;124
|
||||
*.nth 38;5;97
|
||||
*.numbers 38;5;112
|
||||
*.o 38;5;241
|
||||
*.odb 38;5;111
|
||||
*.odp 38;5;166
|
||||
*.ods 38;5;112
|
||||
*.odt 38;5;111
|
||||
*.oga 38;5;137;1
|
||||
*.ogg 38;5;137;1
|
||||
*.ogm 38;5;114
|
||||
*.ogv 38;5;115
|
||||
*.old 38;5;242
|
||||
*.opus 38;5;137;1
|
||||
*.org 38;5;184
|
||||
*.orig 38;5;241
|
||||
*.otf 38;5;66
|
||||
*.out 38;5;242
|
||||
*.p12 38;5;192;3
|
||||
*.p7s 38;5;192;3
|
||||
*.pacnew 38;5;33
|
||||
*.pages 38;5;111
|
||||
*.pak 38;5;215
|
||||
*.part 38;5;239
|
||||
*.patch 48;5;197;38;5;232;1
|
||||
*.path 38;5;45
|
||||
*.pbxproj 1
|
||||
*.pc 38;5;7
|
||||
*.pcap 38;5;29
|
||||
*.pcb 38;5;7
|
||||
*.pcf 1
|
||||
*.pcm 38;5;136;1
|
||||
*.pdf 38;5;141
|
||||
*.pem 38;5;192;3
|
||||
*.pfa 38;5;66
|
||||
*.pfb 38;5;66
|
||||
*.pfm 38;5;66
|
||||
*.pgn 38;5;178
|
||||
*.pgp 38;5;192;3
|
||||
*.pgsql 38;5;222
|
||||
*.php 38;5;81
|
||||
*.pi 38;5;7
|
||||
*.pid 38;5;248
|
||||
*.pk3 38;5;215
|
||||
*.pl 38;5;208
|
||||
*.plist 1
|
||||
*.plt 38;5;7
|
||||
*.ply 38;5;216
|
||||
*.pm 38;5;203
|
||||
*.png 38;5;97
|
||||
*.pod 38;5;184
|
||||
*.pot 38;5;7
|
||||
*.pps 38;5;166
|
||||
*.ppt 38;5;166
|
||||
*.ppts 38;5;166
|
||||
*.pptsm 38;5;166;4
|
||||
*.pptx 38;5;166
|
||||
*.pptxm 38;5;166;4
|
||||
*.prisma 38;5;222
|
||||
*.profile 1
|
||||
*.properties 38;5;116
|
||||
*.prql 38;5;222
|
||||
*.ps 38;5;99
|
||||
*.psd 38;5;97
|
||||
*.psf 1
|
||||
*.pug 38;5;135;1
|
||||
*.pxd 38;5;97
|
||||
*.pxm 38;5;97
|
||||
*.py 38;5;41
|
||||
*.pyc 38;5;240
|
||||
*.qcow 38;5;124
|
||||
*.r 38;5;49
|
||||
*.r[0-9]{0,2} 38;5;239
|
||||
*.rake 38;5;155
|
||||
*.rb 38;5;41
|
||||
*.rdata 38;5;178
|
||||
*.rdf 38;5;7
|
||||
*.rkt 38;5;81
|
||||
*.rlib 38;5;241
|
||||
*.rmvb 38;5;114
|
||||
*.rnc 38;5;178
|
||||
*.rng 38;5;178
|
||||
*.rom 38;5;213
|
||||
*.rpm 38;5;215
|
||||
*.rs 38;5;81
|
||||
*.rss 38;5;178
|
||||
*.rst 38;5;184
|
||||
*.rstheme 1
|
||||
*.rtf 38;5;111
|
||||
*.ru 38;5;7
|
||||
*.s 38;5;110
|
||||
*.s3m 38;5;137;1
|
||||
*.sample 38;5;114
|
||||
*.sass 38;5;105;1
|
||||
*.sassc 38;5;244
|
||||
*.sav 38;5;213
|
||||
*.sc 38;5;41
|
||||
*.scala 38;5;41
|
||||
*.scan 38;5;242
|
||||
*.sch 38;5;7
|
||||
*.scm 38;5;7
|
||||
*.scpt 38;5;219
|
||||
*.scss 38;5;105;1
|
||||
*.sed 38;5;172
|
||||
*.service 38;5;45
|
||||
*.sfv 38;5;116
|
||||
*.sgml 38;5;178
|
||||
*.sh 38;5;172
|
||||
*.sid 38;5;137;1
|
||||
*.sig 38;5;192;3
|
||||
*.signature 38;5;192;3
|
||||
*.sis 38;5;7
|
||||
*.sms 38;5;213
|
||||
*.snapshot 38;5;45
|
||||
*.socket 38;5;45
|
||||
*.sparseimage 38;5;124
|
||||
*.spl 38;5;7
|
||||
*.spv 38;5;217
|
||||
*.sql 38;5;222
|
||||
*.sqlite 38;5;60
|
||||
*.srt 38;5;117
|
||||
*.ssa 38;5;117
|
||||
*.st 38;5;213
|
||||
*.stackdump 38;5;241
|
||||
*.state 38;5;248
|
||||
*.stderr 38;5;160;1
|
||||
*.stl 38;5;216
|
||||
*.storyboard 38;5;196
|
||||
*.strings 1
|
||||
*.sty 38;5;7
|
||||
*.sub 38;5;117
|
||||
*.sublime-build 1
|
||||
*.sublime-commands 1
|
||||
*.sublime-keymap 1
|
||||
*.sublime-project 1
|
||||
*.sublime-settings 1
|
||||
*.sublime-snippet 1
|
||||
*.sublime-workspace 1
|
||||
*.sug 38;5;7
|
||||
*.sup 38;5;117
|
||||
*.svelte 38;5;135;1
|
||||
*.svg 38;5;99
|
||||
*.swap 38;5;45
|
||||
*.swift 38;5;219
|
||||
*.swo 38;5;244
|
||||
*.swp 38;5;244
|
||||
*.sx 38;5;81
|
||||
*.t 38;5;114
|
||||
*.target 38;5;45
|
||||
*.tcc 38;5;110
|
||||
*.tcl 38;5;64;1
|
||||
*.tdy 38;5;7
|
||||
*.tex 38;5;184
|
||||
*.textile 38;5;184
|
||||
*.tf 38;5;168
|
||||
*.tfm 38;5;7
|
||||
*.tfnt 38;5;7
|
||||
*.tfstate 38;5;168
|
||||
*.tfvars 38;5;168
|
||||
*.tg 38;5;7
|
||||
*.theme 38;5;116
|
||||
*.tif 38;5;97
|
||||
*.tiff 38;5;97
|
||||
*.timer 38;5;45
|
||||
*.tmTheme 1
|
||||
*.tmp 38;5;244
|
||||
*.toast 38;5;124
|
||||
*.toml 38;5;178
|
||||
*.torrent 38;5;116
|
||||
*.ts 38;5;074;1
|
||||
*.tsv 38;5;78
|
||||
*.tsx 38;5;074;1
|
||||
*.ttf 38;5;66
|
||||
*.twig 38;5;81
|
||||
*.txt 38;5;253
|
||||
*.typelib 38;5;60
|
||||
*.un~ 38;5;241
|
||||
*.urlview 38;5;116
|
||||
*.user-ca-bundle 1
|
||||
*.v 38;5;81
|
||||
*.vala 38;5;81
|
||||
*.vapi 38;5;81
|
||||
*.vb 38;5;81
|
||||
*.vba 38;5;81
|
||||
*.vbs 38;5;81
|
||||
*.vcard 38;5;7
|
||||
*.vcd 38;5;124
|
||||
*.vcf 38;5;7
|
||||
*.vdf 38;5;215
|
||||
*.vdi 38;5;124
|
||||
*.vert 38;5;136
|
||||
*.vfd 38;5;124
|
||||
*.vhd 38;5;124
|
||||
*.vhdx 38;5;124
|
||||
*.vim 38;5;172
|
||||
*.viminfo 1
|
||||
*.vmdk 38;5;124
|
||||
*.vob 38;5;115;1
|
||||
*.vpk 38;5;215
|
||||
*.vtt 38;5;117
|
||||
*.vue 38;5;135;1
|
||||
*.war 38;5;215
|
||||
*.wav 38;5;136;1
|
||||
*.webloc 38;5;116
|
||||
*.webm 38;5;115
|
||||
*.webp 38;5;97
|
||||
*.wgsl 38;5;97
|
||||
*.wma 38;5;137;1
|
||||
*.wmv 38;5;114
|
||||
*.woff 38;5;66
|
||||
*.woff2 38;5;66
|
||||
*.wrl 38;5;216
|
||||
*.wv 38;5;136;1
|
||||
*.wvc 38;5;136;1
|
||||
*.xcconfig 1
|
||||
*.xcf 38;5;7
|
||||
*.xcsettings 1
|
||||
*.xcuserstate 1
|
||||
*.xcworkspacedata 1
|
||||
*.xib 38;5;208
|
||||
*.xla 38;5;76
|
||||
*.xln 38;5;7
|
||||
*.xls 38;5;112
|
||||
*.xlsx 38;5;112
|
||||
*.xlsxm 38;5;112;4
|
||||
*.xltm 38;5;73;4
|
||||
*.xltx 38;5;73
|
||||
*.xml 38;5;178
|
||||
*.xpi 38;5;215
|
||||
*.xpm 38;5;97
|
||||
*.xsd 38;5;178
|
||||
*.xsh 38;5;41
|
||||
*.yaml 38;5;178
|
||||
*.yml 38;5;178
|
||||
*.z[0-9]{0,2} 38;5;239
|
||||
*.zcompdump 38;5;241
|
||||
*.zig 38;5;81
|
||||
*.zlogin 1
|
||||
*.zlogout 1
|
||||
*.zprofile 1
|
||||
*.zsh 38;5;172
|
||||
*.zshenv 1
|
||||
*.zwc 38;5;241
|
||||
*.zx[0-9]{0,2} 38;5;239
|
||||
bd 38;5;68
|
||||
ca 38;5;17
|
||||
cd 38;5;113;1
|
||||
di 38;5;30
|
||||
do 38;5;127
|
||||
ex 38;5;208;1
|
||||
pi 38;5;126
|
||||
fi 0
|
||||
ln target
|
||||
mh 38;5;222;1
|
||||
no 0
|
||||
or 48;5;196;38;5;232;1
|
||||
ow 38;5;220;1
|
||||
sg 48;5;3;38;5;0
|
||||
su 38;5;220;1;3;100;1
|
||||
so 38;5;197
|
||||
st 38;5;86;48;5;234
|
||||
tw 48;5;235;38;5;139;3
|
||||
|
@ -3,6 +3,7 @@
|
||||
set echo-control-characters off
|
||||
# Color suggestions apropriate for filetype (see $LS_COLORS)
|
||||
set colored-stats on
|
||||
set colored-completion-prefix on
|
||||
# Briefly highlight matching parenthesies
|
||||
set blink-matching-paren on
|
||||
# Do not page completion suggestions
|
||||
@ -18,3 +19,6 @@
|
||||
set completion-ignore-case on
|
||||
# '-' == '_'
|
||||
set completion-map-case on
|
||||
# Show results AND cycle results
|
||||
"\e[Z":menu-complete
|
||||
set show-all-if-ambiguous on
|
||||
|
@ -2,3 +2,6 @@
|
||||
link-style=blue
|
||||
active-link-style=yellow,bold
|
||||
match-style=green
|
||||
|
||||
#info
|
||||
\r select-reference-this-line
|
||||
|
@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
xset r rate 180 40
|
||||
setxkbmap -option caps:swapescape
|
@ -1,14 +1,7 @@
|
||||
import os
|
||||
import atexit
|
||||
import readline
|
||||
from sys import *
|
||||
from subprocess import *
|
||||
from shlex import *
|
||||
from numpy import *
|
||||
from time import *
|
||||
import re
|
||||
|
||||
histfile = os.path.join(os.environ['HOME'], "mm/Python/Pythonrc", '.python_history')
|
||||
|
||||
try:
|
||||
readline.read_history_file(histfile)
|
||||
except IOError:
|
||||
print('I/O Error while reading history file "' + histfile + '"')
|
||||
|
||||
atexit.register(readline.write_history_file, histfile)
|
||||
|
||||
del os, histfile, readline
|
||||
|
@ -6,8 +6,8 @@ T: sudo rc-service tor restart
|
||||
n: nnn
|
||||
N: sudo rc-service NetworkManager restart
|
||||
p: git push
|
||||
4: ssh root@192.168.0.144
|
||||
6: ssh 192.168.0.206
|
||||
4: ssh root@${ROOK}
|
||||
6: ssh ${BTS}
|
||||
c: clifm
|
||||
D: export DEBUG=1
|
||||
b: newsboat
|
||||
|
211
vim/.vim/autoload/quickui/command.vim
Normal file
211
vim/.vim/autoload/quickui/command.vim
Normal file
@ -0,0 +1,211 @@
|
||||
"======================================================================
|
||||
"
|
||||
" main.vim -
|
||||
"
|
||||
" Created by skywind on 2022/08/24
|
||||
" Last Modified: 2022/08/24 20:24:47
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set ts=4 sw=4 tw=78 noet :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" extension map
|
||||
"----------------------------------------------------------------------
|
||||
let g:quickui = get(g:, 'quickui', {})
|
||||
let s:quickui = {}
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" internal
|
||||
"----------------------------------------------------------------------
|
||||
let s:private = {}
|
||||
let s:private.quickui = {}
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" initialize
|
||||
"----------------------------------------------------------------------
|
||||
function! s:init()
|
||||
let quickui = {}
|
||||
for key in keys(s:quickui)
|
||||
let quickui[key] = s:quickui[key]
|
||||
endfor
|
||||
for key in keys(g:quickui)
|
||||
let quickui[key] = g:quickui[key]
|
||||
endfor
|
||||
let names = keys(quickui)
|
||||
call sort(names)
|
||||
let s:private.quickui = quickui
|
||||
let s:private.names = names
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" help
|
||||
"----------------------------------------------------------------------
|
||||
function! s:help(opts, argv)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" list extension
|
||||
"----------------------------------------------------------------------
|
||||
function! s:list(opts, argv)
|
||||
let rows = []
|
||||
let highmap = {}
|
||||
let index = 1
|
||||
let rows += [['Extension', 'Help']]
|
||||
let highmap['0,0'] = 'Title'
|
||||
let highmap['0,1'] = 'Title'
|
||||
for name in s:private.names
|
||||
let help = get(s:private.quickui[name], 'help', '')
|
||||
let rows += [[name, help]]
|
||||
let highmap[index . ',0'] = 'Keyword'
|
||||
let highmap[index . ',1'] = 'Statement'
|
||||
let index += 1
|
||||
endfor
|
||||
call quickui#utils#print_table(rows, highmap)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" main cmd
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#command#run(bang, cmdline) abort
|
||||
let [cmdline, op1] = quickui#core#extract_opts(a:cmdline)
|
||||
let cmdline = quickui#core#string_strip(cmdline)
|
||||
let name = ''
|
||||
if cmdline =~# '^\w\+'
|
||||
let name = matchstr(cmdline, '^\w\+')
|
||||
let cmdline = substitute(cmdline, '^\w\+\s*', '', '')
|
||||
endif
|
||||
let name = quickui#core#string_strip(name)
|
||||
let [cmdline, op2] = quickui#core#extract_opts(cmdline)
|
||||
let op2.cmdline = quickui#core#string_strip(cmdline)
|
||||
let opts = deepcopy(op1)
|
||||
for k in keys(op2)
|
||||
let opts[k] = op2[k]
|
||||
endfor
|
||||
let argv = quickui#core#split_argv(cmdline)
|
||||
call s:init()
|
||||
if name == ''
|
||||
if has_key(op1, 'h')
|
||||
call s:help(opts, argv)
|
||||
elseif has_key(op1, 'l')
|
||||
call s:list(opts, argv)
|
||||
endif
|
||||
return 0
|
||||
endif
|
||||
if has_key(s:private.quickui, name) == 0
|
||||
call quickui#utils#errmsg('invalid extension name: ' . name)
|
||||
return -1
|
||||
endif
|
||||
let obj = s:private.quickui[name]
|
||||
if has_key(obj, 'run') == 0
|
||||
call quickui#utils#errmsg('not find "run" funcref in extension: ' . name)
|
||||
return -2
|
||||
endif
|
||||
let hr = call(obj.run, [opts, argv])
|
||||
return hr
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" command line completion
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#command#complete(ArgLead, CmdLine, CursorPos)
|
||||
let candidate = []
|
||||
call s:init()
|
||||
if a:ArgLead =~ '^-'
|
||||
let flags = ['-h', '-l']
|
||||
for flag in flags
|
||||
if stridx(flag, a:ArgLead) == 0
|
||||
let candidate += [flag]
|
||||
endif
|
||||
endfor
|
||||
return candidate
|
||||
endif
|
||||
for name in s:private.names
|
||||
if stridx(name, a:ArgLead) == 0
|
||||
let candidate += [name]
|
||||
endif
|
||||
endfor
|
||||
return candidate
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" sub: main menu
|
||||
"----------------------------------------------------------------------
|
||||
function! s:sub_menu(opts, argv) abort
|
||||
let argv = a:argv
|
||||
if len(argv) == 0
|
||||
call quickui#menu#open()
|
||||
else
|
||||
call quickui#menu#open(argv[0])
|
||||
endif
|
||||
endfunc
|
||||
|
||||
let s:quickui.menu = {
|
||||
\ 'run': function('s:sub_menu'),
|
||||
\ 'help': 'open main menu',
|
||||
\ }
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" sub: context menu
|
||||
"----------------------------------------------------------------------
|
||||
function! s:sub_context(opts, argv) abort
|
||||
let context = []
|
||||
if exists('g:quickui_context')
|
||||
for item in g:quickui_context
|
||||
let context += [item]
|
||||
endfor
|
||||
endif
|
||||
if exists('b:quickui_context')
|
||||
if !empty(context)
|
||||
let context += ['--']
|
||||
endif
|
||||
for item in b:quickui_context
|
||||
let context += [item]
|
||||
endfor
|
||||
endif
|
||||
if exists('g:quickui_context_foot')
|
||||
if !empty(context)
|
||||
let context += ['--']
|
||||
endif
|
||||
for item in g:quickui_context_foot
|
||||
let context += [item]
|
||||
endfor
|
||||
endif
|
||||
let opts = {}
|
||||
if !empty(context)
|
||||
call quickui#tools#clever_context('_', context, opts)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
let s:quickui.context = {
|
||||
\ 'run': function('s:sub_context'),
|
||||
\ 'help': 'open context menu',
|
||||
\ }
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" sub: terminal
|
||||
"----------------------------------------------------------------------
|
||||
function! s:sub_terminal(opts, argv) abort
|
||||
let cmd = a:opts.cmdline
|
||||
" echom printf("cmd is '%s', type: %d", cmd, type(cmd))
|
||||
" echom a:opts
|
||||
return quickui#terminal#open(cmd, a:opts)
|
||||
endfunc
|
||||
|
||||
let s:quickui.terminal = {
|
||||
\ 'run': function('s:sub_terminal'),
|
||||
\ 'help': 'open terminal window',
|
||||
\ }
|
||||
|
||||
|
315
vim/.vim/autoload/quickui/confirm.vim
Normal file
315
vim/.vim/autoload/quickui/confirm.vim
Normal file
@ -0,0 +1,315 @@
|
||||
"======================================================================
|
||||
"
|
||||
" confirm.vim -
|
||||
"
|
||||
" Created by skywind on 2021/12/11
|
||||
" Last Modified: 2021/12/13 22:07
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set ts=4 sw=4 tw=78 noet :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" build buttons
|
||||
"----------------------------------------------------------------------
|
||||
function! s:button_prepare(choices)
|
||||
let choices = quickui#utils#text_list_normalize(a:choices)
|
||||
let items = []
|
||||
let index = 0
|
||||
let max_size = 4
|
||||
for choice in choices
|
||||
let item = quickui#utils#item_parse(choice)
|
||||
let item.index = index
|
||||
let items += [item]
|
||||
let width = item.text_width
|
||||
let max_size = (max_size < width)? width : max_size
|
||||
let index += 1
|
||||
endfor
|
||||
for item in items
|
||||
let width = item.text_width
|
||||
let pad1 = (max_size - width) / 2
|
||||
let pad2 = max_size - width - pad1
|
||||
" let pad1 += 1
|
||||
" let pad2 += 1
|
||||
let item.text = repeat(' ', pad1) . item.text . repeat(' ', pad2)
|
||||
if item.key_pos >= 0
|
||||
let item.key_pos += pad1
|
||||
endif
|
||||
let item.text_width = strwidth(item.text)
|
||||
endfor
|
||||
return items
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" synthesis button line
|
||||
"----------------------------------------------------------------------
|
||||
function! s:button_finalize(items, style)
|
||||
let items = a:items
|
||||
let final = ''
|
||||
let start = 0
|
||||
let index = len(a:items) - 1
|
||||
for item in a:items
|
||||
if 0
|
||||
let text = ' ' . item.text . ' '
|
||||
else
|
||||
let text = '<' . item.text . '>'
|
||||
endif
|
||||
let item.offset = -1
|
||||
let need = 0
|
||||
if 0
|
||||
let need = 1
|
||||
let text = '[' . text . ']'
|
||||
endif
|
||||
if item.key_pos >= 0
|
||||
let item.offset = start + 1 + item.key_pos + need
|
||||
endif
|
||||
let item.start = start
|
||||
let item.endup = start + item.text_width + 2 + need * 2
|
||||
let start += item.text_width + 2 + need * 2
|
||||
let final .= text
|
||||
if index > 0
|
||||
let final .= ' '
|
||||
let start += 2
|
||||
endif
|
||||
let index -= 1
|
||||
endfor
|
||||
return final
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create highlight
|
||||
"----------------------------------------------------------------------
|
||||
function! s:hl_prepare(hwnd)
|
||||
let hwnd = a:hwnd
|
||||
let c1 = get(g:, 'quickui_button_color_on', 'QuickSel')
|
||||
let c2 = get(g:, 'quickui_button_color_off', 'QuickBG')
|
||||
let ck = get(g:, 'quickui_button_color_key', 'QuickKey')
|
||||
let hwnd.color_on = c1
|
||||
let hwnd.color_off = c2
|
||||
let hwnd.color_on2 = 'QuickButtonOn2'
|
||||
let hwnd.color_off2 = 'QuickButtonOff2'
|
||||
call quickui#highlight#clear('QuickBUttonOn2')
|
||||
call quickui#highlight#clear('QuickBUttonOff2')
|
||||
if 0
|
||||
call quickui#highlight#overlay('QuickButtonOn2', c1, ck)
|
||||
call quickui#highlight#overlay('QuickButtonOff2', c2, ck)
|
||||
else
|
||||
call quickui#highlight#make_underline('QuickButtonOn2', c1)
|
||||
call quickui#highlight#make_underline('QuickButtonOff2', c2)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" calculate requirements
|
||||
"----------------------------------------------------------------------
|
||||
function! s:init(text, choices, index, title)
|
||||
let hwnd = {}
|
||||
let hwnd.text = quickui#utils#text_list_normalize(a:text)
|
||||
let hwnd.items = s:button_prepare(a:choices)
|
||||
let hwnd.final = s:button_finalize(hwnd.items, 0)
|
||||
let hwnd.index = a:index
|
||||
let button = ''
|
||||
let text_size = 40
|
||||
for text in hwnd.text
|
||||
let ts = strdisplaywidth(text)
|
||||
let text_size = (text_size < ts)? ts : text_size
|
||||
endfor
|
||||
let limit = &columns * 80 / 100
|
||||
let limit = get(g:, 'quickui_confirm_max_width', limit)
|
||||
let text_size = (text_size < limit)? text_size : limit
|
||||
let hwnd.btn_size = strdisplaywidth(hwnd.final)
|
||||
let hwnd.text_size = text_size
|
||||
let hwnd.w = (hwnd.btn_size > text_size)? hwnd.btn_size : text_size
|
||||
let hwnd.h = len(hwnd.text) + 3
|
||||
let hwnd.tw = hwnd.w + 4
|
||||
let hwnd.th = hwnd.h + 4
|
||||
let border = g:quickui#style#border
|
||||
let opts = {}
|
||||
let opts.w = hwnd.w
|
||||
let opts.h = hwnd.h
|
||||
let opts.border = get(g:, 'quickui_confirm_border', border)
|
||||
let opts.center = 1
|
||||
let opts.title = (a:title == '')? '' : (' ' . a:title . ' ')
|
||||
let opts.padding = [1, 1, 1, 1]
|
||||
let opts.button = 1
|
||||
let opts.wrap = 1
|
||||
let hwnd.opts = opts
|
||||
let content = deepcopy(hwnd.text)
|
||||
let content += [' ', ' ']
|
||||
let hwnd.padding = hwnd.w - hwnd.btn_size
|
||||
let content += [repeat(' ', hwnd.padding) . hwnd.final]
|
||||
let hwnd.content = content
|
||||
let hwnd.win = quickui#window#new()
|
||||
let hwnd.keymap = quickui#utils#keymap()
|
||||
let index = 1
|
||||
for item in hwnd.items
|
||||
if item.key_pos >= 0
|
||||
let ch = tolower(item.key_char)
|
||||
let hwnd.keymap[ch] = 'ACCEPT:' . index
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
let hwnd.keymap['h'] = 'LEFT'
|
||||
let hwnd.keymap['l'] = 'RIGHT'
|
||||
call s:hl_prepare(hwnd)
|
||||
return hwnd
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
"
|
||||
"----------------------------------------------------------------------
|
||||
function! s:draw_button(hwnd, index)
|
||||
let hwnd = a:hwnd
|
||||
let item = hwnd.items[a:index]
|
||||
let index = a:index
|
||||
let win = hwnd.win
|
||||
let top = hwnd.h - 1
|
||||
let off = hwnd.padding
|
||||
let x = item.start
|
||||
let e = item.endup
|
||||
if hwnd.index == index
|
||||
let c1 = hwnd.color_on
|
||||
let c2 = hwnd.color_on2
|
||||
" let c1 = 'QuickSel'
|
||||
else
|
||||
let c1 = hwnd.color_off
|
||||
let c2 = hwnd.color_off2
|
||||
" let c1 = 'QuickBG'
|
||||
" return
|
||||
endif
|
||||
if item.offset < 0
|
||||
call win.syntax_region(c1, off + x, top, off + e, top)
|
||||
else
|
||||
let u = item.offset + off
|
||||
call win.syntax_region(c1, off + x, top, u, top)
|
||||
call win.syntax_region(c2, u, top, u + 1, top)
|
||||
call win.syntax_region(c1, u + 1, top, off + e, top)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" render
|
||||
"----------------------------------------------------------------------
|
||||
function! s:render(hwnd)
|
||||
let hwnd = a:hwnd
|
||||
let win = hwnd.win
|
||||
let off = hwnd.padding
|
||||
let top = hwnd.h - 1
|
||||
let index = 0
|
||||
call win.syntax_begin(1)
|
||||
for item in hwnd.items
|
||||
call s:draw_button(hwnd, index)
|
||||
let index += 1
|
||||
endfor
|
||||
" call win.syntax_region(ck, 12, 0, 13, 0)
|
||||
call win.syntax_end()
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" main entry
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#confirm#open(text, ...)
|
||||
let choices = (a:0 < 1)? " &OK " : (a:1)
|
||||
let index = (a:0 < 2)? 1 : (a:2)
|
||||
let title = (a:0 < 3)? 'Confirm' : (a:3)
|
||||
let choices = (choices == '')? " &OK " : choices
|
||||
let hwnd = s:init(a:text, choices, index - 1, title)
|
||||
let win = hwnd.win
|
||||
let accept = 0
|
||||
let size = len(hwnd.items)
|
||||
|
||||
if size == 0
|
||||
return 0
|
||||
endif
|
||||
|
||||
if has('nvim')
|
||||
let hwnd.opts.focusable = 1
|
||||
endif
|
||||
|
||||
call win.open(hwnd.content, hwnd.opts)
|
||||
|
||||
while 1
|
||||
call s:render(hwnd)
|
||||
redraw
|
||||
let ch = quickui#utils#getchar(1)
|
||||
if ch == "\<c-c>" || ch == "\<esc>"
|
||||
let accept = 0
|
||||
break
|
||||
elseif ch == "\<space>" || ch == "\<cr>"
|
||||
let accept = hwnd.index + 1
|
||||
break
|
||||
elseif win.quit != 0
|
||||
let accept = 0
|
||||
break
|
||||
elseif ch == "\<LeftMouse>"
|
||||
if has('nvim') == 0
|
||||
let pos = getmousepos()
|
||||
let x = pos.column - 1
|
||||
let y = pos.line - 1
|
||||
else
|
||||
let x = v:mouse_col - 1
|
||||
let y = v:mouse_lnum - 1
|
||||
endif
|
||||
if v:mouse_winid == win.winid
|
||||
if y == hwnd.h - 1 && x >= hwnd.padding
|
||||
let u = x - hwnd.padding
|
||||
for item in hwnd.items
|
||||
if u >= item.start && u < item.endup
|
||||
let accept = item.index + 1
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if accept > 0
|
||||
break
|
||||
endif
|
||||
endif
|
||||
elseif v:mouse_winid == win.info.border_winid
|
||||
if y == 0 && x == win.info.tw - 1
|
||||
let accept = 0
|
||||
break
|
||||
endif
|
||||
endif
|
||||
else
|
||||
let key = get(hwnd.keymap, ch, ch)
|
||||
if key == 'LEFT'
|
||||
let hwnd.index = (hwnd.index > 0)? (hwnd.index - 1) : 0
|
||||
elseif key == 'RIGHT'
|
||||
if hwnd.index < size - 1
|
||||
let hwnd.index += 1
|
||||
endif
|
||||
elseif key == 'HOME' || key == 'UP' || key == 'PAGEUP'
|
||||
let hwnd.index = 0
|
||||
elseif key == 'END' || key == 'DOWN' || key == 'PAGEDOWN'
|
||||
let hwnd.index = size - 1
|
||||
elseif key =~ '^ACCEPT:'
|
||||
let key = strpart(key, 7)
|
||||
let index = str2nr(key)
|
||||
if index > 0 && index <= size
|
||||
let accept = index
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
|
||||
if accept > 0 && win.quit == 0
|
||||
let hwnd.index = accept - 1
|
||||
call s:render(hwnd)
|
||||
redraw
|
||||
sleep 15m
|
||||
endif
|
||||
|
||||
call win.close()
|
||||
|
||||
return accept
|
||||
endfunc
|
||||
|
||||
|
||||
|
930
vim/.vim/autoload/quickui/context.vim
Normal file
930
vim/.vim/autoload/quickui/context.vim
Normal file
@ -0,0 +1,930 @@
|
||||
"======================================================================
|
||||
"
|
||||
" context.vim -
|
||||
"
|
||||
" Created by skywind on 2019/12/19
|
||||
" Last Modified: 2022/08/24 20:05
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" stats
|
||||
"----------------------------------------------------------------------
|
||||
|
||||
" last position
|
||||
let g:quickui#context#cursor = -1
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" compile
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#context#compile(items, border)
|
||||
let menu = {'border':a:border}
|
||||
let items = []
|
||||
let helps = []
|
||||
let size_l = 0
|
||||
let size_r = 0
|
||||
let index = 0
|
||||
let helps = 0
|
||||
for item in a:items
|
||||
let ni = quickui#utils#item_parse(item)
|
||||
let ni.index = index
|
||||
let items += [ni]
|
||||
let index += 1
|
||||
if ni.help != ''
|
||||
let helps += 1
|
||||
endif
|
||||
" echo ni
|
||||
if ni.text_width > size_l
|
||||
let size_l = ni.text_width
|
||||
endif
|
||||
if ni.desc_width > size_r
|
||||
let size_r = ni.desc_width
|
||||
endif
|
||||
endfor
|
||||
let stride = size_l + size_r + ((size_r > 0)? 2 : 0)
|
||||
for item in items
|
||||
call quickui#utils#context_align(item, size_l, size_r)
|
||||
endfor
|
||||
let menu.items = items
|
||||
let menu.helps = helps
|
||||
let image = []
|
||||
if a:border <= 0
|
||||
for item in items
|
||||
let image += [item.content]
|
||||
endfor
|
||||
else
|
||||
let pattern = quickui#core#border_get(a:border)
|
||||
let text = pattern[0] . repeat(pattern[1], stride + 2) . pattern[2]
|
||||
let image += [text]
|
||||
for item in items
|
||||
if item.is_sep
|
||||
let text = pattern[9] . repeat(pattern[4], stride + 2) . pattern[10]
|
||||
let image += [text]
|
||||
else
|
||||
let text = pattern[3] . ' ' . item.content . ' ' . pattern[5]
|
||||
let image += [text]
|
||||
endif
|
||||
endfor
|
||||
let text = pattern[6] . repeat(pattern[7], stride + 2) . pattern[8]
|
||||
let image += [text]
|
||||
endif
|
||||
let menu.image = image
|
||||
let menu.border = a:border
|
||||
let menu.height = len(image)
|
||||
let menu.width = (menu.height > 0)? strwidth(image[0]) : 0
|
||||
let menu.selected = -1
|
||||
let menu.size = len(items)
|
||||
let menu.exiting = 0
|
||||
let menu.state = 0
|
||||
let selection = []
|
||||
for item in menu.items
|
||||
if item.is_sep == 0
|
||||
let selection += [item.index]
|
||||
endif
|
||||
endfor
|
||||
let menu.selection = selection
|
||||
return menu
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create menu object
|
||||
"----------------------------------------------------------------------
|
||||
function! s:vim_create_context(textlist, opts)
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
let hwnd = quickui#context#compile(a:textlist, border)
|
||||
if 0
|
||||
let hwnd.bid = quickui#core#scratch_buffer('context', hwnd.image)
|
||||
let winid = popup_create(hwnd.bid, {'hidden':1, 'wrap':0})
|
||||
else
|
||||
let winid = popup_create(hwnd.image, {'hidden':1, 'wrap':0})
|
||||
endif
|
||||
let w = hwnd.width
|
||||
let h = hwnd.height
|
||||
let hwnd.winid = winid
|
||||
let hwnd.index = get(a:opts, 'index', -1)
|
||||
let hwnd.opts = deepcopy(a:opts)
|
||||
let ignore_case = get(a:opts, 'ignore_case', 1)
|
||||
let opts = {'minwidth':w, 'maxwidth':w, 'minheight':h, 'maxheight':h}
|
||||
if has_key(a:opts, 'line') && has_key(a:opts, 'col')
|
||||
let opts.line = a:opts.line
|
||||
let opts.col = a:opts.col
|
||||
else
|
||||
let pos = quickui#core#around_cursor(w, h)
|
||||
let opts.line = pos[0]
|
||||
let opts.col = pos[1]
|
||||
endif
|
||||
call popup_move(winid, opts)
|
||||
call setwinvar(winid, '&wincolor', get(a:opts, 'color', 'QuickBG'))
|
||||
let opts = {'cursorline':0, 'drag':0, 'mapping':0}
|
||||
let opts.border = [0,0,0,0,0,0,0,0,0]
|
||||
let opts.title = has_key(a:opts, 'title')? ' ' . a:opts.title . ' ' : ''
|
||||
let opts.padding = [0,0,0,0]
|
||||
let keymap = quickui#utils#keymap()
|
||||
let keymap['J'] = 'BOTTOM'
|
||||
let keymap['K'] = 'TOP'
|
||||
if has_key(a:opts, 'keymap')
|
||||
for key in keys(a:opts.keymap)
|
||||
let keymap[key] = a:opts.keymap[key]
|
||||
endfor
|
||||
endif
|
||||
let hwnd.code = 0
|
||||
let hwnd.state = 1
|
||||
let hwnd.keymap = keymap
|
||||
let hwnd.hotkey = {}
|
||||
for item in hwnd.items
|
||||
if item.enable != 0 && item.key_pos >= 0
|
||||
let key = ignore_case ? tolower(item.key_char) : item.key_char
|
||||
if get(a:opts, 'reserve', 0) == 0
|
||||
let hwnd.hotkey[key] = item.index
|
||||
elseif get(g:, 'quickui_protect_hjkl', 0) != 0
|
||||
let hwnd.hotkey[key] = item.index
|
||||
else
|
||||
if key != 'h' && key != 'j' && key != 'k' && key != 'l'
|
||||
let hwnd.hotkey[key] = item.index
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
let local = quickui#core#popup_local(winid)
|
||||
let local.hwnd = hwnd
|
||||
if get(a:opts, 'manual', 0) == 0
|
||||
let opts.callback = function('s:popup_exit')
|
||||
let opts.filter = function('s:popup_filter')
|
||||
endif
|
||||
if has_key(a:opts, 'zindex')
|
||||
let opts.zindex = a:opts.zindex
|
||||
endif
|
||||
call popup_setoptions(winid, opts)
|
||||
call quickui#context#update(hwnd)
|
||||
call popup_show(winid)
|
||||
return hwnd
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" render menu
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#context#update(hwnd)
|
||||
let winid = a:hwnd.winid
|
||||
let size = len(a:hwnd.items)
|
||||
let w = a:hwnd.width
|
||||
let h = a:hwnd.height
|
||||
let cmdlist = ['syn clear']
|
||||
for item in a:hwnd.items
|
||||
let index = item.index
|
||||
if item.enable == 0 && item.is_sep == 0
|
||||
if a:hwnd.border == 0
|
||||
let py = index + 1
|
||||
let px = 1
|
||||
let ps = px + w
|
||||
else
|
||||
let py = index + 2
|
||||
let px = 3
|
||||
let ps = px + w - 4
|
||||
endif
|
||||
let cmd = quickui#core#high_region('QuickOff', py, px, py, ps, 1)
|
||||
let cmdlist += [cmd]
|
||||
elseif item.key_pos >= 0
|
||||
if a:hwnd.border == 0
|
||||
let px = item.key_pos + 1
|
||||
let py = index + 1
|
||||
else
|
||||
let px = item.key_pos + 3
|
||||
let py = index + 2
|
||||
endif
|
||||
let ps = px + 1
|
||||
let cmd = quickui#core#high_region('QuickKey', py, px, py, ps, 1)
|
||||
let cmdlist += [cmd]
|
||||
endif
|
||||
if index == a:hwnd.index
|
||||
if a:hwnd.border == 0
|
||||
let py = index + 1
|
||||
let px = 1
|
||||
let ps = px + w
|
||||
else
|
||||
let py = index + 2
|
||||
let px = 2
|
||||
let ps = px + w - 2
|
||||
endif
|
||||
let cmd = quickui#core#high_region('QuickSel', py, px, py, ps, 1)
|
||||
let cmdlist += [cmd]
|
||||
endif
|
||||
endfor
|
||||
call quickui#core#win_execute(winid, cmdlist)
|
||||
if a:hwnd.state != 0
|
||||
redraw
|
||||
if get(g:, 'quickui_show_tip', 0) != 0
|
||||
let help = ''
|
||||
if a:hwnd.index >= 0 && a:hwnd.index < len(a:hwnd.items)
|
||||
let help = a:hwnd.items[a:hwnd.index].help
|
||||
let head = g:quickui#style#tip_head
|
||||
if help != ''
|
||||
let help = quickui#core#expand_text(help)
|
||||
let help = '' . ((head != '')? (head . ' ') : '') . help
|
||||
endif
|
||||
endif
|
||||
echohl QuickHelp
|
||||
echo help
|
||||
echohl None
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" close context
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#context#close(hwnd)
|
||||
if a:hwnd.winid > 0
|
||||
call popup_close(a:hwnd.winid)
|
||||
call quickui#core#popup_clear(a:hwnd.winid)
|
||||
let a:hwnd.winid = -1
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" handle exit code
|
||||
"----------------------------------------------------------------------
|
||||
function! s:popup_exit(winid, code)
|
||||
let local = quickui#core#popup_local(a:winid)
|
||||
if !has_key(local, 'hwnd')
|
||||
return 0
|
||||
endif
|
||||
let hwnd = local.hwnd
|
||||
let code = a:code
|
||||
let hwnd.state = 0
|
||||
let hwnd.code = code
|
||||
call quickui#core#popup_clear(a:winid)
|
||||
if get(g:, 'quickui_show_tip', 0) != 0
|
||||
if get(hwnd.opts, 'lazyredraw', 0) == 0
|
||||
redraw
|
||||
echo ''
|
||||
redraw
|
||||
endif
|
||||
endif
|
||||
let g:quickui#context#code = code
|
||||
let g:quickui#context#current = hwnd
|
||||
let g:quickui#context#cursor = hwnd.index
|
||||
let redrawed = 0
|
||||
if has_key(hwnd.opts, 'callback')
|
||||
call call(hwnd.opts.callback, [code])
|
||||
endif
|
||||
silent! call popup_hide(a:winid)
|
||||
if code >= 0 && code < len(hwnd.items)
|
||||
let item = hwnd.items[code]
|
||||
if item.is_sep == 0 && item.enable != 0
|
||||
if item.cmd != ''
|
||||
redraw
|
||||
try
|
||||
exec item.cmd
|
||||
catch /.*/
|
||||
echohl Error
|
||||
echom v:exception
|
||||
echohl None
|
||||
endtry
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" key processing
|
||||
"----------------------------------------------------------------------
|
||||
function! s:popup_filter(winid, key)
|
||||
let local = quickui#core#popup_local(a:winid)
|
||||
let hwnd = local.hwnd
|
||||
let winid = hwnd.winid
|
||||
if a:key == "\<ESC>" || a:key == "\<c-c>"
|
||||
call popup_close(a:winid, -1)
|
||||
return 1
|
||||
elseif a:key == "\<CR>" || a:key == "\<SPACE>"
|
||||
call s:on_confirm(hwnd)
|
||||
return 1
|
||||
elseif a:key == "\<LeftMouse>"
|
||||
return s:on_click(hwnd)
|
||||
elseif has_key(hwnd.hotkey, a:key)
|
||||
let key = hwnd.hotkey[a:key]
|
||||
if key >= 0 && key < len(hwnd.items)
|
||||
let item = hwnd.items[key]
|
||||
if item.is_sep == 0 && item.enable != 0
|
||||
let hwnd.index = key
|
||||
call quickui#context#update(hwnd)
|
||||
call popup_setoptions(winid, {})
|
||||
redraw
|
||||
call popup_close(winid, key)
|
||||
return 1
|
||||
endif
|
||||
endif
|
||||
elseif has_key(hwnd.keymap, a:key)
|
||||
let key = hwnd.keymap[a:key]
|
||||
if key == 'ESC'
|
||||
call popup_close(a:winid, -1)
|
||||
return 1
|
||||
elseif key == 'UP'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, -1)
|
||||
elseif key == 'DOWN'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, 1)
|
||||
elseif key == 'TOP'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, 'TOP')
|
||||
elseif key == 'BOTTOM'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, 'BOTTOM')
|
||||
endif
|
||||
if get(hwnd.opts, 'horizon', 0) != 0
|
||||
if key == 'LEFT'
|
||||
call popup_close(a:winid, -1000)
|
||||
elseif key == 'RIGHT'
|
||||
call popup_close(a:winid, -2000)
|
||||
elseif key == 'PAGEUP'
|
||||
call popup_close(a:winid, -1001)
|
||||
elseif key == 'PAGEDOWN'
|
||||
call popup_close(a:winid, -2001)
|
||||
endif
|
||||
endif
|
||||
call quickui#context#update(hwnd)
|
||||
return 1
|
||||
endif
|
||||
return 1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" press enter or space
|
||||
"----------------------------------------------------------------------
|
||||
function! s:on_confirm(hwnd)
|
||||
let index = a:hwnd.index
|
||||
if index < 0 || index > len(a:hwnd.items)
|
||||
return 1
|
||||
endif
|
||||
let item = a:hwnd.items[index]
|
||||
if item.is_sep || item.enable == 0
|
||||
return 1
|
||||
endif
|
||||
call popup_close(a:hwnd.winid, index)
|
||||
return 1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" mouse left click
|
||||
"----------------------------------------------------------------------
|
||||
function! s:on_click(hwnd)
|
||||
let hwnd = a:hwnd
|
||||
let winid = a:hwnd.winid
|
||||
if g:quickui#core#has_nvim == 0
|
||||
let pos = getmousepos()
|
||||
if pos.winid != winid
|
||||
call popup_close(winid, -2)
|
||||
return 0
|
||||
endif
|
||||
let index = -1
|
||||
if hwnd.border == 0
|
||||
let index = pos.line - 1
|
||||
else
|
||||
if pos.column > 1 && pos.column < hwnd.width
|
||||
if pos.line > 1 && pos.line < hwnd.height
|
||||
let index = pos.line - 2
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if index >= 0 && index < len(hwnd.items)
|
||||
let item = hwnd.items[index]
|
||||
if item.is_sep == 0 && item.enable != 0
|
||||
let hwnd.index = index
|
||||
call quickui#context#update(hwnd)
|
||||
call popup_setoptions(winid, {})
|
||||
redraw
|
||||
call popup_close(winid, index)
|
||||
endif
|
||||
endif
|
||||
return 1
|
||||
else
|
||||
if v:mouse_winid != winid
|
||||
return -2
|
||||
endif
|
||||
let index = -1
|
||||
if hwnd.border == 0
|
||||
let index = v:mouse_lnum - 1
|
||||
else
|
||||
if v:mouse_col > 1 && v:mouse_col < hwnd.width
|
||||
if v:mouse_lnum > 1 && v:mouse_lnum < hwnd.height
|
||||
let index = v:mouse_lnum - 2
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if index >= 0 && index < len(hwnd.items)
|
||||
let item = hwnd.items[index]
|
||||
if item.is_sep == 0 && item.enable != 0
|
||||
let hwnd.index = index
|
||||
call quickui#context#update(hwnd)
|
||||
redraw
|
||||
sleep 60m
|
||||
return index
|
||||
endif
|
||||
endif
|
||||
return -1
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" move cursor
|
||||
"----------------------------------------------------------------------
|
||||
function! s:cursor_move(menu, cursor, toward)
|
||||
let size = a:menu.size
|
||||
if type(a:toward) == v:t_number
|
||||
if a:toward == 0
|
||||
if size <= 0
|
||||
return -1
|
||||
elseif a:cursor < 0
|
||||
return a:cursor
|
||||
endif
|
||||
return (a:cursor >= size)? (size - 1) : a:cursor
|
||||
endif
|
||||
endif
|
||||
let selection = a:menu.selection
|
||||
if size == 0 || len(selection) == 0
|
||||
return -1
|
||||
endif
|
||||
let cursor = a:cursor + a:toward
|
||||
if type(a:toward) == v:t_number
|
||||
if a:toward < 0
|
||||
if a:cursor < 0
|
||||
return selection[0]
|
||||
endif
|
||||
let cursor = (cursor < 0)? 0 : cursor
|
||||
let pos = len(selection) - 1
|
||||
while pos >= 0
|
||||
if selection[pos] <= cursor
|
||||
return selection[pos]
|
||||
endif
|
||||
let pos -= 1
|
||||
endwhile
|
||||
return selection[0]
|
||||
else
|
||||
let pos = 0
|
||||
let limit = len(selection)
|
||||
while pos < limit
|
||||
if selection[pos] >= cursor
|
||||
return selection[pos]
|
||||
endif
|
||||
let pos += 1
|
||||
endwhile
|
||||
return selection[limit - 1]
|
||||
endif
|
||||
else
|
||||
if a:toward == 'TOP'
|
||||
return selection[0]
|
||||
elseif a:toward == 'BOTTOM'
|
||||
return selection[-1]
|
||||
endif
|
||||
endif
|
||||
return -1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" open context menu in neovim and returns index
|
||||
"----------------------------------------------------------------------
|
||||
function! s:nvim_create_context(textlist, opts)
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
let ignore_case = get(a:opts, 'ignore_case', 1)
|
||||
let hwnd = quickui#context#compile(a:textlist, border)
|
||||
let bid = quickui#core#scratch_buffer('context', hwnd.image)
|
||||
let hwnd.bid = bid
|
||||
let w = hwnd.width
|
||||
let h = hwnd.height
|
||||
let hwnd.index = get(a:opts, 'index', -1)
|
||||
let hwnd.opts = deepcopy(a:opts)
|
||||
let opts = {'width':w, 'height':h, 'focusable':1, 'style':'minimal'}
|
||||
let opts.relative = 'editor'
|
||||
if has_key(a:opts, 'line') && has_key(a:opts, 'col')
|
||||
let opts.row = a:opts.line - 1
|
||||
let opts.col = a:opts.col - 1
|
||||
else
|
||||
let pos = quickui#core#around_cursor(w, h)
|
||||
let opts.row = pos[0] - 1
|
||||
let opts.col = pos[1] - 1
|
||||
endif
|
||||
if has('nvim-0.6.0')
|
||||
let opts.noautocmd = 1
|
||||
endif
|
||||
let winid = nvim_open_win(bid, 0, opts)
|
||||
let hwnd.winid = winid
|
||||
let keymap = quickui#utils#keymap()
|
||||
let keymap['J'] = 'BOTTOM'
|
||||
let keymap['K'] = 'TOP'
|
||||
let hwnd.code = 0
|
||||
let hwnd.state = 1
|
||||
let hwnd.keymap = keymap
|
||||
let hwnd.hotkey = {}
|
||||
for item in hwnd.items
|
||||
if item.enable != 0 && item.key_pos >= 0
|
||||
let key = ignore_case ? tolower(item.key_char) : item.key_char
|
||||
if get(a:opts, 'reserve', 0) == 0
|
||||
let hwnd.hotkey[key] = item.index
|
||||
elseif get(g:, 'quickui_protect_hjkl', 0) != 0
|
||||
let hwnd.hotkey[key] = item.index
|
||||
else
|
||||
if key != 'h' && key != 'j' && key != 'k' && key != 'l'
|
||||
let hwnd.hotkey[key] = item.index
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
let hwnd.opts.color = get(a:opts, 'color', 'QuickBG')
|
||||
call nvim_win_set_option(winid, 'winhl', 'Normal:'. hwnd.opts.color)
|
||||
let retval = -1
|
||||
while 1
|
||||
noautocmd call quickui#context#update(hwnd)
|
||||
redraw
|
||||
try
|
||||
let code = getchar()
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<C-C>"
|
||||
endtry
|
||||
let ch = (type(code) == v:t_number)? nr2char(code) : code
|
||||
if ch == "\<ESC>" || ch == "\<c-c>"
|
||||
break
|
||||
elseif ch == " " || ch == "\<cr>"
|
||||
let index = hwnd.index
|
||||
if index >= 0 && index < len(hwnd.items)
|
||||
let item = hwnd.items[index]
|
||||
if item.is_sep == 0 && item.enable != 0
|
||||
let retval = index
|
||||
break
|
||||
endif
|
||||
endif
|
||||
elseif ch == "\<LeftMouse>"
|
||||
let hr = s:on_click(hwnd)
|
||||
if hr == -2 || hr >= 0
|
||||
let retval = hr
|
||||
break
|
||||
endif
|
||||
elseif has_key(hwnd.hotkey, ch)
|
||||
let hr = hwnd.hotkey[ch]
|
||||
if hr >= 0
|
||||
let hwnd.index = hr
|
||||
let retval = hr
|
||||
break
|
||||
endif
|
||||
elseif has_key(hwnd.keymap, ch)
|
||||
let key = hwnd.keymap[ch]
|
||||
if key == 'ESC'
|
||||
break
|
||||
elseif key == 'UP'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, -1)
|
||||
elseif key == 'DOWN'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, 1)
|
||||
elseif key == 'TOP'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, 'TOP')
|
||||
elseif key == 'BOTTOM'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, 'BOTTOM')
|
||||
endif
|
||||
if get(hwnd.opts, 'horizon', 0) != 0
|
||||
if key == 'LEFT'
|
||||
let retval = -1000
|
||||
break
|
||||
elseif key == 'RIGHT'
|
||||
let retval = -2000
|
||||
break
|
||||
elseif key == 'PAGEUP'
|
||||
let retval = -1001
|
||||
break
|
||||
elseif key == 'PAGEDOWN'
|
||||
let retval = -2001
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
call nvim_win_close(winid, 0)
|
||||
if get(a:opts, 'lazyredraw', 0) == 0
|
||||
redraw
|
||||
endif
|
||||
if get(g:, 'quickui_show_tip', 0) != 0
|
||||
if get(a:opts, 'lazyredraw', 0) == 0
|
||||
echo ''
|
||||
redraw
|
||||
endif
|
||||
endif
|
||||
let g:quickui#context#code = retval
|
||||
let g:quickui#context#current = hwnd
|
||||
let g:quickui#context#cursor = hwnd.index
|
||||
if has_key(hwnd.opts, 'callback')
|
||||
call call(hwnd.opts.callback, [retval])
|
||||
endif
|
||||
if retval >= 0 && retval < len(hwnd.items)
|
||||
let item = hwnd.items[retval]
|
||||
if item.is_sep == 0 && item.enable != 0
|
||||
if item.cmd != ''
|
||||
redraw
|
||||
try
|
||||
exec item.cmd
|
||||
catch /.*/
|
||||
echohl Error
|
||||
echom v:exception
|
||||
echohl None
|
||||
endtry
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
return retval
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" reduce with file types
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#context#reduce_items(textlist)
|
||||
let output = []
|
||||
let state = 1
|
||||
let index = 0
|
||||
let limit = len(a:textlist)
|
||||
for item in a:textlist
|
||||
if len(item) > 0
|
||||
let issep = ((item[0]) =~ '^-\+$')? 1 : 0
|
||||
if issep != 0
|
||||
if state == 0
|
||||
if index + 1 < limit
|
||||
let output += [item]
|
||||
let state = 1
|
||||
endif
|
||||
endif
|
||||
else
|
||||
if type(item) == v:t_string
|
||||
let output += [item]
|
||||
let state = 0
|
||||
elseif len(item) < 4
|
||||
let output += [item]
|
||||
let state = 0
|
||||
else
|
||||
if quickui#utils#match_ft(&ft, item[3])
|
||||
let output += [item]
|
||||
let state = 0
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
return output
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create menu object
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#context#open(textlist, opts)
|
||||
let textlist = a:textlist
|
||||
if g:quickui#core#has_nvim == 0
|
||||
return s:vim_create_context(textlist, a:opts)
|
||||
else
|
||||
return s:nvim_create_context(textlist, a:opts)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" open the context window and wait for selection
|
||||
"----------------------------------------------------------------------
|
||||
function! s:context_wait(textlist, opts) abort
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
let ignore_case = get(a:opts, 'ignore_case', 1)
|
||||
let hwnd = quickui#context#compile(a:textlist, border)
|
||||
let cwnd = quickui#window#new()
|
||||
let w = hwnd.width
|
||||
let h = hwnd.height
|
||||
let hwnd.index = get(a:opts, 'index', -1)
|
||||
let hwnd.opts = a:opts
|
||||
let opts = {'w':w, 'h':h, 'border':0}
|
||||
if has_key(a:opts, 'x') && has_key(a:opts, 'y')
|
||||
let opts.x = a:opts.x
|
||||
let opts.y = a:opts.y
|
||||
else
|
||||
let pos = quickui#core#around_cursor(w, h)
|
||||
let opts.y = pos[0] - 1
|
||||
let opts.x = pos[1] - 1
|
||||
endif
|
||||
let opts.z = get(a:opts, 'z', 500)
|
||||
let opts.color = get(a:opts, 'color', 'QuickBG')
|
||||
let hwnd.direct = get(a:opts, 'direct', 0)
|
||||
if hwnd.direct == 0
|
||||
let hwnd.direct = (opts.x <= (&columns / 2))? 1 : -1
|
||||
endif
|
||||
call cwnd.open(hwnd.image, opts)
|
||||
call cwnd.show(1)
|
||||
let keymap = quickui#utils#keymap()
|
||||
let keymap['J'] = 'BOTTOM'
|
||||
let keymap['K'] = 'TOP'
|
||||
let hwnd.code = 0
|
||||
let hwnd.state = 1
|
||||
let hwnd.keymap = keymap
|
||||
let hwnd.hotkey = {}
|
||||
for item in hwnd.items
|
||||
if item.enable != 0 && item.key_pos >= 0
|
||||
let key = ignore_case ? tolower(item.key_char) : item.key_char
|
||||
if get(a:opts, 'reserve', 0) == 0
|
||||
let hwnd.hotkey[key] = item.index
|
||||
elseif get(g:, 'quickui_protect_hjkl', 0) != 0
|
||||
let hwnd.hotkey[key] = item.index
|
||||
else
|
||||
if key != 'h' && key != 'j' && key != 'k' && key != 'l'
|
||||
let hwnd.hotkey[key] = item.index
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
let hwnd.winid = cwnd.winid
|
||||
let retval = -1
|
||||
while 1
|
||||
noautocmd call quickui#context#update(hwnd)
|
||||
redraw
|
||||
try
|
||||
let code = getchar()
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<C-C>"
|
||||
endtry
|
||||
let ch = (type(code) == v:t_number)? nr2char(code) : code
|
||||
if ch == "\<ESC>" || ch == "\<c-c>"
|
||||
break
|
||||
elseif ch == " " || ch == "\<cr>"
|
||||
let index = hwnd.index
|
||||
if index >= 0 && index < len(hwnd.items)
|
||||
let item = hwnd.items[index]
|
||||
if item.is_sep == 0 && item.enable != 0
|
||||
let retval = index
|
||||
break
|
||||
endif
|
||||
endif
|
||||
elseif ch == "\<LeftMouse>"
|
||||
let pos = cwnd.mouse_click()
|
||||
if pos.x < 0
|
||||
break
|
||||
else
|
||||
let x1 = (hwnd.border == 0)? 0 : 1
|
||||
let x2 = (hwnd.border == 0)? w : (w - 1)
|
||||
let ii = (hwnd.border == 0)? pos.y : (pos.y - 1)
|
||||
if pos.x >= x1 && pos.x < x2
|
||||
if ii >= 0 && ii < len(hwnd.items)
|
||||
let item = hwnd.items[ii]
|
||||
if item.is_sep == 0 && item.enable != 0
|
||||
let hwnd.index = ii
|
||||
let retval = ii
|
||||
noautocmd call quickui#context#update(hwnd)
|
||||
redraw
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
elseif has_key(hwnd.hotkey, ch)
|
||||
let hr = hwnd.hotkey[ch]
|
||||
if hr >= 0
|
||||
let hwnd.index = hr
|
||||
let retval = hr
|
||||
break
|
||||
endif
|
||||
elseif has_key(hwnd.keymap, ch)
|
||||
let key = hwnd.keymap[ch]
|
||||
if key == 'ESC'
|
||||
break
|
||||
elseif key == 'UP'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, -1)
|
||||
elseif key == 'DOWN'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, 1)
|
||||
elseif key == 'TOP'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, 'TOP')
|
||||
elseif key == 'BOTTOM'
|
||||
let hwnd.index = s:cursor_move(hwnd, hwnd.index, 'BOTTOM')
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
noautocmd call quickui#context#update(hwnd)
|
||||
let hr = ''
|
||||
if retval >= 0 && retval < len(hwnd.items)
|
||||
let item = hwnd.items[retval]
|
||||
if item.is_sep == 0 && item.enable != 0
|
||||
let hwnd.index = retval
|
||||
if !has_key(item, 'child')
|
||||
let hr = item.cmd
|
||||
else
|
||||
let child = item.child
|
||||
let cc = quickui#context#compile(child, border)
|
||||
let cw = cc.width
|
||||
let ch = cc.height
|
||||
unlet cc
|
||||
let op = {}
|
||||
let op.z = opts.z + 1
|
||||
let op.y = opts.y + retval
|
||||
let op.y = (op.y + ch > &lines)? (&lines - ch) : op.y
|
||||
let op.y = (op.y < 0)? 0 : op.y
|
||||
for i in range(5)
|
||||
if hwnd.direct >= 0
|
||||
let tx = opts.x + opts.w
|
||||
if tx + cw > &columns
|
||||
let hwnd.direct = -1
|
||||
else
|
||||
let op.x = tx
|
||||
break
|
||||
endif
|
||||
elseif hwnd.direct < 0
|
||||
let tx = opts.x - cw
|
||||
if tx < 0
|
||||
let hwnd.direct = 1
|
||||
else
|
||||
let op.x = tx
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
if !has_key(op, 'x')
|
||||
let op.x = 1
|
||||
endif
|
||||
let op.direct = hwnd.direct
|
||||
let op.border = get(a:opts, 'border', border)
|
||||
let hr = s:context_wait(child, op)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let g:quickui#context#cursor = hwnd.index
|
||||
let g:quickui#context#current = hwnd
|
||||
call cwnd.close()
|
||||
unlet cwnd
|
||||
return hr
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" open the context window and wait for selection
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#context#wait(textlist, opts) abort
|
||||
return s:context_wait(a:textlist, a:opts)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" open context menu and execute commands
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#context#open_nested(textlist, opts) abort
|
||||
let cmd = s:context_wait(a:textlist, a:opts)
|
||||
if has_key(a:opts, 'callback')
|
||||
call a:opts.callback(0)
|
||||
endif
|
||||
if cmd != ''
|
||||
exec cmd
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" testing suit
|
||||
"----------------------------------------------------------------------
|
||||
if 0
|
||||
call quickui#utils#highlight('default')
|
||||
let lines = [
|
||||
\ "&New File\tCtrl+n",
|
||||
\ "&Open File\tCtrl+o",
|
||||
\ ["&Close", 'echo 1234', 'help 1'],
|
||||
\ "--",
|
||||
\ "&Save\tCtrl+s",
|
||||
\ "Save &As",
|
||||
\ "Save All",
|
||||
\ "--",
|
||||
\ "&User Menu\tF9",
|
||||
\ "&Dos Shell",
|
||||
\ "~&Time %{&undolevels? '+':'-'}",
|
||||
\ ["S&plit", 'help 1', '', 'vim2'],
|
||||
\ "--",
|
||||
\ "E&xit\tAlt+x",
|
||||
\ "&Help",
|
||||
\ ]
|
||||
" echo quickui#core#pattern_ascii
|
||||
" let menu = quickui#context#menu_compile(lines, 1)
|
||||
let opts = {'cursor': -1, 'line2':'cursor+1', 'col2': 'cursor', 'horizon':1}
|
||||
" let opts.index = 2
|
||||
let opts.savepos = 'f'
|
||||
let opts.callback = 'MyCallback'
|
||||
let opts.reduce = 1
|
||||
function! MyCallback(code)
|
||||
echom "callback: " . a:code
|
||||
endfunc
|
||||
if 1
|
||||
let menu = quickui#context#open(lines, opts)
|
||||
" echo menu
|
||||
else
|
||||
let item = quickui#utils#item_parse("你好吗f&aha\tAlt+x")
|
||||
echo item
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
|
925
vim/.vim/autoload/quickui/core.vim
Normal file
925
vim/.vim/autoload/quickui/core.vim
Normal file
@ -0,0 +1,925 @@
|
||||
"======================================================================
|
||||
"
|
||||
" core.vim -
|
||||
"
|
||||
" Created by skywind on 2019/12/18
|
||||
" Last Modified: 2022/08/31 16:25
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
|
||||
"======================================================================
|
||||
" core routines
|
||||
"======================================================================
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" global variables
|
||||
"----------------------------------------------------------------------
|
||||
let g:quickui#core#has_nvim = has('nvim')
|
||||
let g:quickui#core#has_vim9 = v:version >= 900
|
||||
let g:quickui#core#has_popup = exists('*popup_create') && v:version >= 800
|
||||
let g:quickui#core#has_floating = has('nvim-0.4')
|
||||
let g:quickui#core#has_nvim_040 = has('nvim-0.4')
|
||||
let g:quickui#core#has_nvim_050 = has('nvim-0.5.0')
|
||||
let g:quickui#core#has_nvim_060 = has('nvim-0.6.0')
|
||||
let g:quickui#core#has_vim_820 = (has('nvim') == 0 && has('patch-8.2.1'))
|
||||
let g:quickui#core#has_win_exe = exists('*win_execute')
|
||||
let g:quickui#core#has_vim9script = (v:version >= 900) && has('vim9script')
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" internal variables
|
||||
"----------------------------------------------------------------------
|
||||
let s:windows = has('win32') || has('win16') || has('win64') || has('win95')
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" object pool acquire
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#object_acquire(name)
|
||||
if !exists('g:quickui#core#__object_pool__')
|
||||
let g:quickui#core#__object_pool__ = {}
|
||||
endif
|
||||
if !has_key(g:quickui#core#__object_pool__, a:name)
|
||||
let g:quickui#core#__object_pool__[a:name] = []
|
||||
endif
|
||||
let array = g:quickui#core#__object_pool__[a:name]
|
||||
if len(array) == 0
|
||||
return v:null
|
||||
endif
|
||||
let obj = remove(array, -1)
|
||||
return obj
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" object pool release
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#object_release(name, obj)
|
||||
if !exists('g:quickui#core#__object_pool__')
|
||||
let g:quickui#core#__object_pool__ = {}
|
||||
endif
|
||||
if !has_key(g:quickui#core#__object_pool__, a:name)
|
||||
let g:quickui#core#__object_pool__[a:name] = []
|
||||
endif
|
||||
call add(g:quickui#core#__object_pool__[a:name], a:obj)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" replace string
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#string_replace(text, old, new)
|
||||
let l:data = split(a:text, a:old, 1)
|
||||
return join(l:data, a:new)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" compose two string
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#string_compose(target, pos, source)
|
||||
if a:source == ''
|
||||
return a:target
|
||||
endif
|
||||
let pos = a:pos
|
||||
let source = a:source
|
||||
if pos < 0
|
||||
let source = strcharpart(a:source, -pos)
|
||||
let pos = 0
|
||||
endif
|
||||
let target = strcharpart(a:target, 0, pos)
|
||||
if strchars(target) < pos
|
||||
let target .= repeat(' ', pos - strchars(target))
|
||||
endif
|
||||
let target .= source
|
||||
let target .= strcharpart(a:target, pos + strchars(source))
|
||||
return target
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" fit size
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#string_fit(source, size)
|
||||
let require = a:size
|
||||
let source = a:source
|
||||
let size = len(source)
|
||||
if size <= require
|
||||
return source
|
||||
endif
|
||||
if require <= 2
|
||||
return repeat('.', (require < 0)? 0 : require)
|
||||
endif
|
||||
let avail = require - 2
|
||||
let left = avail / 2
|
||||
let right = avail - left
|
||||
let p1 = strpart(source, 0, left)
|
||||
let p2 = strpart(source, size - right)
|
||||
let text = p1 . '..' . p2
|
||||
return text
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" eval & expand: '%{script}' in string
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#expand_text(string) abort
|
||||
let partial = []
|
||||
let index = 0
|
||||
while 1
|
||||
let pos = stridx(a:string, '%{', index)
|
||||
if pos < 0
|
||||
let partial += [strpart(a:string, index)]
|
||||
break
|
||||
endif
|
||||
let head = ''
|
||||
if pos > index
|
||||
let partial += [strpart(a:string, index, pos - index)]
|
||||
endif
|
||||
let endup = stridx(a:string, '}', pos + 2)
|
||||
if endup < 0
|
||||
let partial += [strpart(a:stirng, index)]
|
||||
break
|
||||
endif
|
||||
let index = endup + 1
|
||||
if endup > pos + 2
|
||||
let script = strpart(a:string, pos + 2, endup - (pos + 2))
|
||||
let script = substitute(script, '^\s*\(.\{-}\)\s*$', '\1', '')
|
||||
let result = eval(script)
|
||||
let partial += [result]
|
||||
endif
|
||||
endwhile
|
||||
return join(partial, '')
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" escape key character (starts by &) from string
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#escape(text)
|
||||
let text = a:text
|
||||
let rest = ''
|
||||
let start = 0
|
||||
let obj = ['', '', -1, -1, -1]
|
||||
while 1
|
||||
let pos = stridx(text, '&', start)
|
||||
if pos < 0
|
||||
let rest .= strpart(text, start)
|
||||
break
|
||||
end
|
||||
let rest .= strpart(text, start, pos - start)
|
||||
let key = strpart(text, pos + 1, 1)
|
||||
let start = pos + 2
|
||||
if key == '&'
|
||||
let rest .= '&'
|
||||
elseif key == '~'
|
||||
let rest .= '~'
|
||||
else
|
||||
let obj[1] = key
|
||||
let obj[2] = strlen(rest)
|
||||
let obj[3] = strchars(rest)
|
||||
let obj[4] = strdisplaywidth(rest)
|
||||
let rest .= key
|
||||
endif
|
||||
endwhile
|
||||
let obj[0] = rest
|
||||
return obj
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" list parse
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#single_parse(description)
|
||||
let item = { 'part': [], 'size': 0 }
|
||||
let item.key_char = ''
|
||||
let item.key_pos = -1
|
||||
let item.key_idx = -1
|
||||
if type(a:description) == v:t_string
|
||||
let text = a:description
|
||||
let item.cmd = ''
|
||||
elseif type(a:description) == v:t_list
|
||||
let size = len(a:description)
|
||||
let text = (size > 0)? a:description[0] : ''
|
||||
let item.cmd = (size > 1)? a:description[1] : ''
|
||||
endif
|
||||
for text in split(text, "\t")
|
||||
let obj = quickui#core#escape(text)
|
||||
let item.part += [obj[0]]
|
||||
if obj[2] >= 0 && item.key_idx < 0
|
||||
let item.key_char = obj[1]
|
||||
let item.key_pos = obj[4]
|
||||
let item.key_idx = item.size
|
||||
endif
|
||||
let item.size += 1
|
||||
endfor
|
||||
return item
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" tabpage instance
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#instance(local)
|
||||
let local = a:local
|
||||
if local != 0
|
||||
if exists('t:__quickui__')
|
||||
return t:__quickui__
|
||||
endif
|
||||
let t:__quickui__ = {}
|
||||
return t:__quickui__
|
||||
else
|
||||
if exists('g:__quickui__')
|
||||
return g:__quickui__
|
||||
endif
|
||||
let g:__quickui__ = {}
|
||||
return g:__quickui__
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" buffer instance
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#object(bid)
|
||||
let name = '__quickui__'
|
||||
let bid = (a:bid > 0)? a:bid : (bufnr())
|
||||
if bufexists(bid) == 0
|
||||
return v:null
|
||||
endif
|
||||
let obj = getbufvar(bid, name)
|
||||
if type(obj) != v:t_dict
|
||||
call setbufvar(bid, name, {})
|
||||
let obj = getbufvar(bid, name)
|
||||
endif
|
||||
return obj
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" object cache: acquire
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#popup_alloc(name)
|
||||
let inst = quickui#core#instance(1)
|
||||
if !has_key(inst, 'popup_cache')
|
||||
let inst.popup_cache = {}
|
||||
endif
|
||||
if !has_key(inst.popup_cache, a:name)
|
||||
let inst.popup_cache[a:name] = []
|
||||
endif
|
||||
if !empty(inst.popup_cache[a:name])
|
||||
let winid = remove(inst.popup_cache[a:name], -1)
|
||||
return winid
|
||||
endif
|
||||
let opts = {"line":1, "col":1, "wrap":0, "pos": 'topleft'}
|
||||
let winid = popup_create([], opts)
|
||||
call popup_hide(winid)
|
||||
call win_execute(winid, 'setlocal nonumber nowrap signcolumn=no')
|
||||
call setwinvar(winid, '&wincolor', 'QuickBG')
|
||||
return winid
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" object cache: release
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#popup_release(name, winid)
|
||||
let inst = quickui#core#instance(1)
|
||||
if !has_key(inst, 'popup_cache')
|
||||
let inst.popup_cache = {}
|
||||
endif
|
||||
if !has_key(inst.popup_cache, a:name)
|
||||
let inst.popup_cache[a:name] = []
|
||||
endif
|
||||
silent! call popup_hide(a:winid)
|
||||
let size = len(inst.popup_cache[a:name])
|
||||
call insert(inst.popup_cache[a:name], a:winid, size)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" local object
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#popup_local(winid)
|
||||
let inst = quickui#core#instance(0)
|
||||
if !has_key(inst, 'popup_local')
|
||||
let inst.popup_local = {}
|
||||
endif
|
||||
if !has_key(inst.popup_local, a:winid)
|
||||
let inst.popup_local[a:winid] = {}
|
||||
endif
|
||||
return inst.popup_local[a:winid]
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" erase local data
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#popup_clear(winid)
|
||||
let inst = quickui#core#instance(0)
|
||||
if !has_key(inst, 'popup_local')
|
||||
let inst.popup_local = {}
|
||||
endif
|
||||
if has_key(inst.popup_local, a:winid)
|
||||
call remove(inst.popup_local, a:winid)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" vim/nvim compatible
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#win_execute(winid, command, ...)
|
||||
let silent = (a:0 < 1)? 0 : (a:1)
|
||||
if g:quickui#core#has_popup != 0
|
||||
if type(a:command) == v:t_string
|
||||
keepalt call win_execute(a:winid, a:command, silent)
|
||||
elseif type(a:command) == v:t_list
|
||||
keepalt call win_execute(a:winid, join(a:command, "\n"), silent)
|
||||
endif
|
||||
elseif g:quickui#core#has_win_exe == 0
|
||||
let current = nvim_get_current_win()
|
||||
keepalt call nvim_set_current_win(a:winid)
|
||||
if type(a:command) == v:t_string
|
||||
if silent == 0
|
||||
exec a:command
|
||||
else
|
||||
silent exec a:command
|
||||
endif
|
||||
elseif type(a:command) == v:t_list
|
||||
if silent == 0
|
||||
exec join(a:command, "\n")
|
||||
else
|
||||
silent exec join(a:command, "\n")
|
||||
endif
|
||||
endif
|
||||
keepalt call nvim_set_current_win(current)
|
||||
else
|
||||
if type(a:command) == v:t_string
|
||||
keepalt call win_execute(a:winid, a:command, silent)
|
||||
elseif type(a:command) == v:t_list
|
||||
keepalt call win_execute(a:winid, join(a:command, "\n"), silent)
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" close window
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#win_close(winid, force)
|
||||
let [tnr, wnr] = win_id2tabwin(a:winid)
|
||||
if tnr <= 0 || wnr <= 0
|
||||
return -1
|
||||
endif
|
||||
if g:quickui#core#has_nvim == 0
|
||||
let cmd = 'close' . ((a:force != 0)? '!' : '')
|
||||
call quickui#core#win_execute(a:winid, cmd)
|
||||
else
|
||||
call nvim_win_close(a:winid, a:force)
|
||||
endif
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" alloc a new buffer
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#buffer_alloc()
|
||||
if !exists('s:buffer_array')
|
||||
let s:buffer_array = {}
|
||||
endif
|
||||
let index = len(s:buffer_array) - 1
|
||||
if index >= 0
|
||||
let bid = s:buffer_array[index]
|
||||
unlet s:buffer_array[index]
|
||||
else
|
||||
if g:quickui#core#has_nvim == 0
|
||||
let bid = bufadd('')
|
||||
call bufload(bid)
|
||||
call setbufvar(bid, '&buflisted', 0)
|
||||
call setbufvar(bid, '&bufhidden', 'hide')
|
||||
call setbufvar(bid, '&buftype', 'nofile')
|
||||
call setbufvar(bid, 'noswapfile', 1)
|
||||
else
|
||||
let bid = nvim_create_buf(v:false, v:true)
|
||||
call setbufvar(bid, '&buftype', 'nofile')
|
||||
call setbufvar(bid, '&bufhidden', 'hide')
|
||||
call setbufvar(bid, 'noswapfile', 1)
|
||||
endif
|
||||
endif
|
||||
call setbufvar(bid, '&modifiable', 1)
|
||||
call deletebufline(bid, 1, '$')
|
||||
call setbufvar(bid, '&modified', 0)
|
||||
call setbufvar(bid, '&filetype', '')
|
||||
return bid
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" free a buffer
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#buffer_free(bid)
|
||||
if !exists('s:buffer_array')
|
||||
let s:buffer_array = {}
|
||||
endif
|
||||
let index = len(s:buffer_array)
|
||||
let s:buffer_array[index] = a:bid
|
||||
call setbufvar(a:bid, '&modifiable', 1)
|
||||
call deletebufline(a:bid, 1, '$')
|
||||
call setbufvar(a:bid, '&modified', 0)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" update content
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#buffer_update(bid, textlist)
|
||||
if type(a:textlist) == v:t_list
|
||||
let textlist = a:textlist
|
||||
else
|
||||
let textlist = split('' . a:textlist, '\n', 1)
|
||||
endif
|
||||
call setbufvar(a:bid, '&modifiable', 1)
|
||||
call deletebufline(a:bid, 1, '$')
|
||||
call setbufline(a:bid, 1, textlist)
|
||||
call setbufvar(a:bid, '&modified', 0)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" clear content
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#buffer_clear(bid)
|
||||
call quickui#core#buffer_update(a:bid, [])
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get a named buffer
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#scratch_buffer(name, textlist)
|
||||
if !exists('s:buffer_cache')
|
||||
let s:buffer_cache = {}
|
||||
endif
|
||||
if a:name != ''
|
||||
let bid = get(s:buffer_cache, a:name, -1)
|
||||
else
|
||||
let bid = -1
|
||||
endif
|
||||
if bid < 0
|
||||
let bid = quickui#core#buffer_alloc()
|
||||
if a:name != ''
|
||||
let s:buffer_cache[a:name] = bid
|
||||
endif
|
||||
endif
|
||||
call quickui#core#buffer_update(bid, a:textlist)
|
||||
call setbufvar(bid, 'current_syntax', '')
|
||||
return bid
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" dummy filter
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#mock_function(id, text)
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" highlight region
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#high_region(name, srow, scol, erow, ecol, virtual)
|
||||
let sep = (a:virtual == 0)? 'c' : 'v'
|
||||
let cmd = 'syn region ' . a:name . ' '
|
||||
let cmd .= ' start=/\%' . a:srow . 'l\%' . a:scol . sep . '/'
|
||||
let cmd .= ' end=/\%' . a:erow . 'l\%' . a:ecol . sep . '/'
|
||||
return cmd
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" patterns
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#border_extract(pattern)
|
||||
let parts = ['', '', '', '', '', '', '', '', '', '', '']
|
||||
for idx in range(11)
|
||||
let parts[idx] = strcharpart(a:pattern, idx, 1)
|
||||
endfor
|
||||
return parts
|
||||
endfunc
|
||||
|
||||
|
||||
function! quickui#core#border_convert(pattern, nvim_format)
|
||||
if type(a:pattern) == v:t_string
|
||||
let p = quickui#core#border_extract(a:pattern)
|
||||
else
|
||||
let p = a:pattern
|
||||
endif
|
||||
if len(p) == 0
|
||||
return []
|
||||
endif
|
||||
if a:nvim_format == 0
|
||||
let pattern = [ p[1], p[5], p[7], p[3], p[0], p[2], p[8], p[6] ]
|
||||
else
|
||||
let pattern = [ p[0], p[1], p[2], p[5], p[8], p[7], p[6], p[3] ]
|
||||
endif
|
||||
return pattern
|
||||
endfunc
|
||||
|
||||
let s:border_styles = {}
|
||||
|
||||
let s:border_styles[0] = quickui#core#border_extract(' ')
|
||||
let s:border_styles[1] = quickui#core#border_extract('+-+|-|+-+++')
|
||||
let s:border_styles[2] = quickui#core#border_extract('┌─┐│─│└─┘├┤')
|
||||
let s:border_styles[3] = quickui#core#border_extract('╔═╗║─║╚═╝╟╢')
|
||||
let s:border_styles[4] = quickui#core#border_extract('╭─╮│─│╰─╯├┤')
|
||||
let s:border_styles[5] = quickui#core#border_extract('/-\|-|\-/++')
|
||||
|
||||
let s:border_ascii = quickui#core#border_extract('+-+|-|+-+++')
|
||||
|
||||
let s:border_styles['none'] = []
|
||||
let s:border_styles['single'] = s:border_styles[2]
|
||||
let s:border_styles['double'] = s:border_styles[3]
|
||||
let s:border_styles['rounded'] = s:border_styles[4]
|
||||
let s:border_styles['solid'] = s:border_styles[0]
|
||||
let s:border_styles['ascii'] = s:border_styles[1]
|
||||
let s:border_styles['default'] = s:border_styles[1]
|
||||
|
||||
function! quickui#core#border_install(name, pattern)
|
||||
let s:border_styles[a:name] = quickui#core#border_extract(a:pattern)
|
||||
endfunc
|
||||
|
||||
function! quickui#core#border_get(name)
|
||||
if has_key(s:border_styles, a:name)
|
||||
return s:border_styles[a:name]
|
||||
endif
|
||||
return s:border_ascii
|
||||
endfunc
|
||||
|
||||
function! quickui#core#border_vim(name)
|
||||
let border = quickui#core#border_get(a:name)
|
||||
return quickui#core#border_convert(border, 0)
|
||||
endfunc
|
||||
|
||||
function! quickui#core#border_nvim(name)
|
||||
let border = quickui#core#border_get(a:name)
|
||||
return quickui#core#border_convert(border, 1)
|
||||
endfunc
|
||||
|
||||
function! quickui#core#border_auto(name)
|
||||
if g:quickui#core#has_nvim == 0
|
||||
return quickui#core#border_vim(a:name)
|
||||
else
|
||||
return quickui#core#border_nvim(a:name)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" returns cursor position for screen coordination
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#cursor_pos()
|
||||
let pos = win_screenpos('.')
|
||||
return [pos[0] + winline() - 1, pos[1] + wincol() - 1]
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" screen boundary check, returns 1 for in screen, 0 for exceeding
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#in_screen(line, column, width, height)
|
||||
let x = a:column - 1
|
||||
let y = a:line - 1
|
||||
let w = a:width
|
||||
let h = a:height
|
||||
let screenw = &columns
|
||||
let screenh = &lines
|
||||
return (x >= 0 && y >= 0 && x + w <= screenw && y + h <= screenh)? 1 : 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" window fit screen
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#screen_fit(line, column, width, height)
|
||||
let x = a:column - 1
|
||||
let y = a:line - 1
|
||||
let w = a:width
|
||||
let h = a:height
|
||||
let screenw = &columns
|
||||
let screenh = &lines
|
||||
let x = (x + w > screenw)? screenw - w : x
|
||||
let y = (y + h > screenh)? screenh - h : y
|
||||
let x = (x < 0)? 0 : x
|
||||
let y = (y < 0)? 0 : y
|
||||
return [y + 1, x + 1]
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" fit screen
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#around_cursor(width, height)
|
||||
let cursor_pos = quickui#core#cursor_pos()
|
||||
let row = cursor_pos[0] + 1
|
||||
let col = cursor_pos[1] + 1
|
||||
if quickui#core#in_screen(row, col, a:width, a:height)
|
||||
return [row, col]
|
||||
endif
|
||||
if col + a:width - 1 > &columns
|
||||
let col = col - (1 + a:width)
|
||||
if quickui#core#in_screen(row, col, a:width, a:height)
|
||||
return [row, col]
|
||||
endif
|
||||
endif
|
||||
if row + a:height - 1 > &lines
|
||||
let row = row - (1 + a:height)
|
||||
if quickui#core#in_screen(row, col, a:width, a:height)
|
||||
return [row, col]
|
||||
endif
|
||||
endif
|
||||
if cursor_pos[0] + a:height + 2 < &lines
|
||||
let row = cursor_pos[0] + 1
|
||||
else
|
||||
let row = cursor_pos[0] - a:height
|
||||
endif
|
||||
if cursor_pos[1] + a:width + 2 < &columns
|
||||
let col = cursor_pos[1] + 1
|
||||
else
|
||||
let col = cursor_pos[1] - a:width
|
||||
endif
|
||||
return quickui#core#screen_fit(row, col, a:width, a:height)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" safe input
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#input(prompt, text)
|
||||
call inputsave()
|
||||
try
|
||||
let t = input(a:prompt, a:text)
|
||||
catch /^Vim:Interrupt$/
|
||||
let t = "\<c-c>"
|
||||
endtry
|
||||
call inputrestore()
|
||||
return t
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" safe change dir
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#chdir(path)
|
||||
if has('nvim')
|
||||
let cmd = haslocaldir()? 'lcd' : (haslocaldir(-1, 0)? 'tcd' : 'cd')
|
||||
else
|
||||
let cmd = haslocaldir()? ((haslocaldir() == 1)? 'lcd' : 'tcd') : 'cd'
|
||||
endif
|
||||
silent execute cmd . ' '. fnameescape(a:path)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" full file name
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#fullname(f)
|
||||
let f = a:f
|
||||
if f =~ "'."
|
||||
try
|
||||
redir => m
|
||||
silent exe ':marks' f[1]
|
||||
redir END
|
||||
let f = split(split(m, '\n')[-1])[-1]
|
||||
let f = filereadable(f)? f : ''
|
||||
catch
|
||||
let f = '%'
|
||||
endtry
|
||||
endif
|
||||
if f == '%'
|
||||
let f = expand('%')
|
||||
if &bt == 'terminal' || &bt == 'nofile'
|
||||
let f = ''
|
||||
endif
|
||||
endif
|
||||
let f = fnamemodify(f, ':p')
|
||||
if s:windows
|
||||
let f = substitute(f, "\\", '/', 'g')
|
||||
endif
|
||||
if f =~ '\/$'
|
||||
let f = fnamemodify(f, ':h')
|
||||
endif
|
||||
return f
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" returns nearest parent directory contains one of the markers
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#find_root(name, markers, strict)
|
||||
let name = fnamemodify((a:name != '')? a:name : bufname('%'), ':p')
|
||||
let finding = ''
|
||||
" iterate all markers
|
||||
for marker in a:markers
|
||||
if marker != ''
|
||||
" search as a file
|
||||
let x = findfile(marker, name . '/;')
|
||||
let x = (x == '')? '' : fnamemodify(x, ':p:h')
|
||||
" search as a directory
|
||||
let y = finddir(marker, name . '/;')
|
||||
let y = (y == '')? '' : fnamemodify(y, ':p:h:h')
|
||||
" which one is the nearest directory ?
|
||||
let z = (strchars(x) > strchars(y))? x : y
|
||||
" keep the nearest one in finding
|
||||
let finding = (strchars(z) > strchars(finding))? z : finding
|
||||
endif
|
||||
endfor
|
||||
if finding == ''
|
||||
let path = (a:strict == 0)? fnamemodify(name, ':h') : ''
|
||||
else
|
||||
let path = fnamemodify(finding, ':p')
|
||||
endif
|
||||
if has('win32') || has('win16') || has('win64') || has('win95')
|
||||
let path = substitute(path, '\/', '\', 'g')
|
||||
endif
|
||||
if path =~ '[\/\\]$'
|
||||
let path = fnamemodify(path, ':h')
|
||||
endif
|
||||
return path
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" find project root
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#project_root(name, ...)
|
||||
let markers = ['.project', '.git', '.hg', '.svn', '.root']
|
||||
if exists('g:quickui_rootmarks')
|
||||
let markers = g:quickui_rootmarks
|
||||
elseif exists('g:asyncrun_rootmarks')
|
||||
let markers = g:asyncrun_rootmarks
|
||||
endif
|
||||
let path = quickui#core#fullname(a:name)
|
||||
let strict = (a:0 > 0)? (a:1) : 0
|
||||
return quickui#core#find_root(path, markers, strict)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" expand macros
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#expand_macros()
|
||||
let macros = {}
|
||||
let macros['VIM_FILEPATH'] = expand("%:p")
|
||||
let macros['VIM_FILENAME'] = expand("%:t")
|
||||
let macros['VIM_FILEDIR'] = expand("%:p:h")
|
||||
let macros['VIM_FILENOEXT'] = expand("%:t:r")
|
||||
let macros['VIM_PATHNOEXT'] = expand("%:p:r")
|
||||
let macros['VIM_FILEEXT'] = "." . expand("%:e")
|
||||
let macros['VIM_FILETYPE'] = (&filetype)
|
||||
let macros['VIM_CWD'] = getcwd()
|
||||
let macros['VIM_RELDIR'] = expand("%:h:.")
|
||||
let macros['VIM_RELNAME'] = expand("%:p:.")
|
||||
let macros['VIM_CWORD'] = expand("<cword>")
|
||||
let macros['VIM_CFILE'] = expand("<cfile>")
|
||||
let macros['VIM_CLINE'] = line('.')
|
||||
let macros['VIM_VERSION'] = ''.v:version
|
||||
let macros['VIM_SVRNAME'] = v:servername
|
||||
let macros['VIM_COLUMNS'] = ''.&columns
|
||||
let macros['VIM_LINES'] = ''.&lines
|
||||
let macros['VIM_GUI'] = has('gui_running')? 1 : 0
|
||||
let macros['VIM_ROOT'] = quickui#core#project_root('%', 0)
|
||||
let macros['VIM_HOME'] = expand(split(&rtp, ',')[0])
|
||||
let macros['VIM_PRONAME'] = fnamemodify(macros['VIM_ROOT'], ':t')
|
||||
let macros['VIM_DIRNAME'] = fnamemodify(macros['VIM_CWD'], ':t')
|
||||
let macros['<cwd>'] = macros['VIM_CWD']
|
||||
let macros['<root>'] = macros['VIM_ROOT']
|
||||
if expand("%:e") == ''
|
||||
let macros['VIM_FILEEXT'] = ''
|
||||
endif
|
||||
return macros
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" write script to a file and return filename
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#write_script(command, pause)
|
||||
let tmpname = fnamemodify(tempname(), ':h') . '\quickui1.cmd'
|
||||
let command = a:command
|
||||
if s:windows != 0
|
||||
let lines = ["@echo off\r"]
|
||||
let $VIM_COMMAND = a:command
|
||||
let $VIM_PAUSE = (a:pause)? 'pause' : ''
|
||||
let lines += ["call %VIM_COMMAND% \r"]
|
||||
let lines += ["set VIM_EXITCODE=%ERRORLEVEL%\r"]
|
||||
let lines += ["call %VIM_PAUSE% \r"]
|
||||
let lines += ["exit %VIM_EXITCODE%\r"]
|
||||
else
|
||||
let shell = split(&shell, ' ', 1)[0]
|
||||
let lines = ['#! ' . shell]
|
||||
let lines += [command]
|
||||
if a:pause != 0
|
||||
if executable('bash')
|
||||
let pause = 'read -n1 -rsp "press any key to continue ..."'
|
||||
let lines += ['bash -c ''' . pause . '''']
|
||||
else
|
||||
let lines += ['echo "press enter to continue ..."']
|
||||
let lines += ['sh -c "read _tmp_"']
|
||||
endif
|
||||
endif
|
||||
let tmpname = fnamemodify(tempname(), ':h') . '/quickui1.sh'
|
||||
endif
|
||||
call writefile(lines, tmpname)
|
||||
if s:windows == 0
|
||||
if exists('*setfperm')
|
||||
silent! call setfperm(tmpname, 'rwxrwxrws')
|
||||
endif
|
||||
endif
|
||||
return tmpname
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" string replace
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#string_replace(text, old, new)
|
||||
let data = split(a:text, a:old, 1)
|
||||
return join(data, a:new)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" string strip
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#string_strip(text)
|
||||
return substitute(a:text, '^\s*\(.\{-}\)[\t\r\n ]*$', '\1', '')
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" extract opts+command
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#extract_opts(command)
|
||||
let cmd = substitute(a:command, '^\s*\(.\{-}\)[\s\r\n]*$', '\1', '')
|
||||
let opts = {}
|
||||
while cmd =~# '^-\%(\w\+\)\%([= ]\|$\)'
|
||||
let opt = matchstr(cmd, '^-\zs\w\+')
|
||||
if cmd =~ '^-\w\+='
|
||||
let val = matchstr(cmd, '^-\w\+=\zs\%(\\.\|\S\)*')
|
||||
else
|
||||
let val = ''
|
||||
endif
|
||||
let opts[opt] = substitute(val, '\\\(\s\)', '\1', 'g')
|
||||
let cmd = substitute(cmd, '^-\w\+\%(=\%(\\.\|\S\)*\)\=\s*', '', '')
|
||||
endwhile
|
||||
let cmd = substitute(cmd, '^\s*\(.\{-}\)\s*$', '\1', '')
|
||||
let cmd = substitute(cmd, '^@\s*', '', '')
|
||||
return [cmd, opts]
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" split cmdline to argv
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#split_argv(cmdline)
|
||||
let cmd = quickui#core#string_strip(a:cmdline)
|
||||
let argv = []
|
||||
while cmd =~# '^\%(\\.\|\S\)\+'
|
||||
let arg = matchstr(cmd, '^\%(\\.\|\S\)\+')
|
||||
let cmd = substitute(cmd, '^\%(\\.\|\S\)\+\s*', '', '')
|
||||
let val = substitute(arg, '\\\(\s\)', '\1', 'g')
|
||||
let argv += [val]
|
||||
endwhile
|
||||
return argv
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" execute string
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#core#execute_string(text)
|
||||
let cmd = a:text
|
||||
if cmd =~ '^[a-zA-Z0-9_#]\+(.*)$'
|
||||
exec 'call ' . cmd
|
||||
elseif cmd =~ '^<key>'
|
||||
let keys = strpart(cmd, 5)
|
||||
call feedkeys(keys)
|
||||
elseif cmd =~ '^@'
|
||||
let keys = strpart(cmd, 1)
|
||||
call feedkeys(keys)
|
||||
elseif cmd =~ '^<plug>'
|
||||
let keys = strpart(cmd, 6)
|
||||
call feedkeys("\<plug>" . keys)
|
||||
else
|
||||
exec cmd
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
310
vim/.vim/autoload/quickui/highlight.vim
Normal file
310
vim/.vim/autoload/quickui/highlight.vim
Normal file
@ -0,0 +1,310 @@
|
||||
"======================================================================
|
||||
"
|
||||
" highlight.vim -
|
||||
"
|
||||
" Created by skywind on 2021/12/12
|
||||
" Last Modified: 2021/12/13 18:32
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set ts=4 sw=4 tw=78 noet :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" internal
|
||||
"----------------------------------------------------------------------
|
||||
let s:has_hlget = exists('*hlget')? 1 : 0
|
||||
let s:has_hlset = exists('*hlset')? 1 : 0
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get highlighting group
|
||||
"----------------------------------------------------------------------
|
||||
function! s:sim_hlget(name)
|
||||
let error = 0
|
||||
redir => g:quickui_highlight_tmp
|
||||
try
|
||||
exec 'silent hi ' . a:name
|
||||
catch
|
||||
let error = 1
|
||||
endtry
|
||||
redir END
|
||||
if error != 0
|
||||
return []
|
||||
endif
|
||||
let capture = g:quickui_highlight_tmp
|
||||
let items = []
|
||||
for text in split(capture, '\n')
|
||||
let text = quickui#core#string_strip(text)
|
||||
if text == ''
|
||||
continue
|
||||
endif
|
||||
let item = {}
|
||||
let item.name = matchstr(text, '^\w\+')
|
||||
if item.name == ''
|
||||
continue
|
||||
endif
|
||||
let parts = split(text, ' ')
|
||||
if empty(parts)
|
||||
continue
|
||||
endif
|
||||
if text =~ ' cleared$'
|
||||
let item.cleared = v:true
|
||||
elseif text =~ ' links to \w\+$'
|
||||
let links = matchstr(text, ' links to \zs\w\+$')
|
||||
let item.linksto = quickui#core#string_strip(links)
|
||||
else
|
||||
for part in parts[1:]
|
||||
if part =~ '\w\+='
|
||||
let key = matchstr(part, '^\w\+')
|
||||
let val = matchstr(part, '^\w\+=\zs\%(\\.\|\S\)*')
|
||||
if key == 'term' || key == 'cterm' || key == 'gui'
|
||||
let opts = {}
|
||||
for element in split(val, ',')
|
||||
let opts[element] = v:true
|
||||
endfor
|
||||
let item[key] = opts
|
||||
else
|
||||
let item[key] = val
|
||||
endif
|
||||
elseif part == 'cleared'
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
let items += [item]
|
||||
endfor
|
||||
return items
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" simulate hlset
|
||||
"----------------------------------------------------------------------
|
||||
function! s:sim_hlset(items)
|
||||
let skip = {'name':1, 'id':1, 'linksto':1, 'force':1}
|
||||
for item in a:items
|
||||
let name = get(item, 'name', '')
|
||||
if name == ''
|
||||
continue
|
||||
endif
|
||||
let force = get(item, 'force', v:false)
|
||||
let cmd = (force == 0)? 'hi ' : 'hi! '
|
||||
if get(item, 'cleared', v:false) == v:true
|
||||
exec cmd . 'clear ' . name
|
||||
else
|
||||
let part = []
|
||||
for key in keys(item)
|
||||
if has_key(skip, key) == 0
|
||||
let val = item[key]
|
||||
if type(val) == v:t_dict
|
||||
let r = join(keys(val), ',')
|
||||
else
|
||||
let r = val
|
||||
endif
|
||||
let part += [key . '=' . r]
|
||||
endif
|
||||
endfor
|
||||
let text = cmd . ' ' . name . ' ' . join(part, ' ')
|
||||
exec text
|
||||
endif
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get highlighting info
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#highlight#get(name, ...)
|
||||
let resolve = (a:0 > 0)? (a:1) : 0
|
||||
if s:has_hlget
|
||||
" return hlget(a:name, resolve)
|
||||
endif
|
||||
if !resolve
|
||||
return s:sim_hlget(a:name)
|
||||
endif
|
||||
let items = []
|
||||
for item in s:sim_hlget(a:name)
|
||||
if has_key(item, 'linksto') == 0
|
||||
let items += [item]
|
||||
continue
|
||||
endif
|
||||
let info = item
|
||||
while 1
|
||||
if has_key(info, 'linksto') == 0
|
||||
break
|
||||
endif
|
||||
let links = info.linksto
|
||||
let hr = s:sim_hlget(links)
|
||||
if empty(hr)
|
||||
break
|
||||
endif
|
||||
let info = hr[0]
|
||||
endwhile
|
||||
let info.name = item.name
|
||||
let items += [info]
|
||||
endfor
|
||||
return items
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" set highlight group
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#highlight#set(items)
|
||||
if s:has_hlset
|
||||
" return hlset(a:items)
|
||||
endif
|
||||
call s:sim_hlset(a:items)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" clear highlight
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#highlight#clear(name)
|
||||
if s:has_hlset
|
||||
let info = {'name': a:name, 'cleared': v:true}
|
||||
call hlset([info])
|
||||
else
|
||||
exec 'hi! clear ' . a:name
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" term add feature
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#highlight#term_add(info, what)
|
||||
let info = a:info
|
||||
let what = a:what
|
||||
if has_key(info, 'term')
|
||||
if type(info.term) == v:t_dict
|
||||
let info.term[what] = v:true
|
||||
elseif type(info.term) == v:t_string
|
||||
let opts = {}
|
||||
for key in split(info.term, ',')
|
||||
let opts[key] = v:true
|
||||
endfor
|
||||
let opts[what] = v:true
|
||||
let info.term = opts
|
||||
endif
|
||||
else
|
||||
let info.term = {}
|
||||
let info.term[what] = v:true
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" cterm add feature
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#highlight#cterm_add(info, what)
|
||||
let info = a:info
|
||||
let what = a:what
|
||||
if has_key(info, 'cterm')
|
||||
if type(info.cterm) == v:t_dict
|
||||
let info.cterm[what] = v:true
|
||||
elseif type(info.cterm) == v:t_string
|
||||
let opts = {}
|
||||
for key in split(info.cterm, ',')
|
||||
let opts[key] = v:true
|
||||
endfor
|
||||
let opts[what] = v:true
|
||||
let info.cterm = opts
|
||||
endif
|
||||
else
|
||||
let info.cterm = {}
|
||||
let info.cterm[what] = v:true
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" gui add feature
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#highlight#gui_add(info, what)
|
||||
let info = a:info
|
||||
let what = a:what
|
||||
if has_key(info, 'gui')
|
||||
if type(info.gui) == v:t_dict
|
||||
let info.gui[what] = v:true
|
||||
elseif type(info.gui) == v:t_string
|
||||
let opts = {}
|
||||
for key in split(info.gui, ',')
|
||||
let opts[key] = v:true
|
||||
endfor
|
||||
let opts[what] = v:true
|
||||
let info.gui = opts
|
||||
endif
|
||||
else
|
||||
let info.gui = {}
|
||||
let info.gui[what] = v:true
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" new underline
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#highlight#grant_underline(info)
|
||||
let info = a:info
|
||||
call quickui#highlight#term_add(info, 'underline')
|
||||
call quickui#highlight#cterm_add(info, 'underline')
|
||||
call quickui#highlight#gui_add(info, 'underline')
|
||||
return info
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" add colors
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#highlight#grant_color(info, colors)
|
||||
for key in keys(a:colors)
|
||||
let a:info[key] = a:colors[key]
|
||||
endfor
|
||||
return a:info
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" add underline feature
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#highlight#make_underline(newname, name)
|
||||
let hr = quickui#highlight#get(a:name, 1)
|
||||
if len(hr) == 0
|
||||
return -1
|
||||
endif
|
||||
let info = (len(hr) == 0)? {} : hr[0]
|
||||
call quickui#highlight#term_add(info, 'underline')
|
||||
call quickui#highlight#cterm_add(info, 'underline')
|
||||
call quickui#highlight#gui_add(info, 'underline')
|
||||
if has_key(info, 'id')
|
||||
unlet info['id']
|
||||
endif
|
||||
let info.name = a:newname
|
||||
let info.force = v:true
|
||||
call quickui#highlight#set([info])
|
||||
return info
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" combine foreground and background colors
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#highlight#overlay(newname, background, foreground)
|
||||
let hr1 = quickui#highlight#get(a:background, 1)
|
||||
let hr2 = quickui#highlight#get(a:foreground, 1)
|
||||
let info1 = empty(hr1)? {} : hr1[0]
|
||||
let info2 = empty(hr2)? {} : hr2[0]
|
||||
for key in ['ctermfg', 'guifg']
|
||||
if has_key(info2, key)
|
||||
let info1[key] = info2[key]
|
||||
endif
|
||||
endfor
|
||||
let info1.name = a:newname
|
||||
let info1.force = v:true
|
||||
call quickui#highlight#set([info1])
|
||||
endfunc
|
||||
|
||||
|
375
vim/.vim/autoload/quickui/input.vim
Normal file
375
vim/.vim/autoload/quickui/input.vim
Normal file
@ -0,0 +1,375 @@
|
||||
"======================================================================
|
||||
"
|
||||
" input.vim -
|
||||
"
|
||||
" Created by skywind on 2021/11/27
|
||||
" Last Modified: 2021/11/30 01:50
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" internal variables
|
||||
"----------------------------------------------------------------------
|
||||
let s:has_nvim = g:quickui#core#has_nvim
|
||||
let s:history = {}
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" init
|
||||
"----------------------------------------------------------------------
|
||||
function! s:init_input_box(prompt, opts)
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
let hwnd = {}
|
||||
let head = []
|
||||
if type(a:prompt) == v:t_list
|
||||
let head = deepcopy(a:prompt)
|
||||
else
|
||||
let head = split('' . a:prompt, "\n")
|
||||
endif
|
||||
let hwnd.h = 2 + len(head)
|
||||
let hwnd.lnum = 2 + len(head)
|
||||
if has_key(a:opts, 'w')
|
||||
let hwnd.w = a:opts.w
|
||||
else
|
||||
let limit = 8
|
||||
for text in head
|
||||
let width = strdisplaywidth(text)
|
||||
let limit = (limit < width)? width : limit
|
||||
endfor
|
||||
if &columns >= 80
|
||||
let limit = (limit < 50)? 50 : limit
|
||||
endif
|
||||
let hwnd.w = limit
|
||||
endif
|
||||
let hwnd.image = head + [' ', repeat(' ', hwnd.w)]
|
||||
let hwnd.bid = quickui#core#scratch_buffer('input', hwnd.image)
|
||||
let hwnd.opts = deepcopy(a:opts)
|
||||
let hwnd.opts.color = get(a:opts, 'color', 'QuickBG')
|
||||
let hwnd.opts.bordercolor = get(a:opts, 'bordercolor', 'QuickBorder')
|
||||
let hwnd.opts.text = get(a:opts, 'text', '')
|
||||
let hwnd.border = border
|
||||
let title = ' Input '
|
||||
let hwnd.rl = quickui#readline#new()
|
||||
if hwnd.opts.text != ''
|
||||
call hwnd.rl.set(hwnd.opts.text)
|
||||
call hwnd.rl.seek(0, 2)
|
||||
let hwnd.rl.select = 0
|
||||
endif
|
||||
let hwnd.pos = 0
|
||||
let hwnd.wait = get(a:opts, 'wait', 0)
|
||||
let hwnd.exit = 0
|
||||
let hwnd.strict = get(a:opts, 'strict', 1)
|
||||
let hwnd.history = get(hwnd.opts, 'history', '')
|
||||
if hwnd.history != ''
|
||||
let key = hwnd.history
|
||||
let hwnd.rl.history = [''] + get(s:history, key, [])
|
||||
" echom hwnd.rl.history
|
||||
endif
|
||||
if has_key(hwnd.opts, 'row') && has_key(hwnd.opts, 'col')
|
||||
" pass
|
||||
else
|
||||
let ww = hwnd.w
|
||||
let hh = hwnd.h
|
||||
let hwnd.opts.col = (&columns - ww) / 2
|
||||
let hwnd.opts.row = (&lines - hh) / 2
|
||||
let limit1 = (&lines - 2) * 82 / 100
|
||||
let limit2 = (&lines - 2)
|
||||
if hh + 8 < limit1
|
||||
let hwnd.opts.row = (limit1 - hh) / 2
|
||||
else
|
||||
let hwnd.opts.row = (limit2 - hh) / 2
|
||||
endif
|
||||
endif
|
||||
return hwnd
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create input box object
|
||||
"----------------------------------------------------------------------
|
||||
function! s:vim_create_input(prompt, opts)
|
||||
let hwnd = s:init_input_box(a:prompt, a:opts)
|
||||
let opts = {'hidden':1, 'wrap':1}
|
||||
let opts.minwidth = hwnd.w
|
||||
let opts.maxwidth = hwnd.w
|
||||
let opts.minheight = hwnd.h
|
||||
let opts.minheight = hwnd.h
|
||||
let winid = popup_create(hwnd.bid, opts)
|
||||
if has_key(a:opts, 'line') == 0 || has_key(a:opts, 'col') == 0
|
||||
call quickui#utils#center(winid, 1)
|
||||
endif
|
||||
let opts = {'mapping':0, 'cursorline':0, 'drag':1}
|
||||
let opts.border = [0,0,0,0,0,0,0,0,0]
|
||||
if hwnd.border > 0
|
||||
let opts.borderchars = quickui#core#border_vim(hwnd.border)
|
||||
let opts.border = [1,1,1,1,1,1,1,1,1]
|
||||
let opts.close = 'button'
|
||||
endif
|
||||
let opts.padding = [1,1,1,1]
|
||||
if has_key(a:opts, 'title') && (a:opts.title != '')
|
||||
let opts.title = ' ' . a:opts.title . ' '
|
||||
endif
|
||||
let bc = hwnd.opts.bordercolor
|
||||
let opts.resize = 0
|
||||
let opts.highlight = hwnd.opts.color
|
||||
let opts.borderhighlight = [bc, bc, bc, bc]
|
||||
let opts.callback = function('s:popup_exit')
|
||||
let hwnd.winid = winid
|
||||
let local = quickui#core#popup_local(winid)
|
||||
let local.hwnd = hwnd
|
||||
call popup_setoptions(winid, opts)
|
||||
call popup_show(winid)
|
||||
redraw
|
||||
return hwnd
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" exit callback
|
||||
"----------------------------------------------------------------------
|
||||
function! s:popup_exit(winid, code)
|
||||
let local = quickui#core#popup_local(a:winid)
|
||||
let local.hwnd.exit = 1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" neovim: create input
|
||||
"----------------------------------------------------------------------
|
||||
function! s:nvim_create_input(prompt, opts)
|
||||
let hwnd = s:init_input_box(a:prompt, a:opts)
|
||||
let opts = {'focusable':1, 'style':'minimal', 'relative':'editor'}
|
||||
let title = ' Input '
|
||||
let border = hwnd.border
|
||||
let back = quickui#utils#make_border(hwnd.w + 2, hwnd.h + 2, border, title, 1)
|
||||
let hwnd.back = back
|
||||
let opts.width = hwnd.w
|
||||
let opts.height = hwnd.h
|
||||
let opts.row = hwnd.opts.row
|
||||
let opts.col = hwnd.opts.col
|
||||
if has('nvim-0.6.0')
|
||||
let opts.noautocmd = 1
|
||||
endif
|
||||
let winid = nvim_open_win(hwnd.bid, 0, opts)
|
||||
let hwnd.winid = winid
|
||||
let background = -1
|
||||
if border > 0 && get(g:, 'quickui_nvim_simulate_border', 1) != 0
|
||||
let nbid = quickui#core#scratch_buffer('inputborder', back)
|
||||
let op = {'relative':'editor', 'focusable':1, 'style':'minimal'}
|
||||
let op.width = hwnd.w + 4
|
||||
let op.height = hwnd.h + 4
|
||||
let op.row = hwnd.opts.row - 2
|
||||
let op.col = hwnd.opts.col - 2
|
||||
let bordercolor = hwnd.opts.bordercolor
|
||||
if has('nvim-0.6.0')
|
||||
let op.noautocmd = 1
|
||||
endif
|
||||
let background = nvim_open_win(nbid, 0, op)
|
||||
call nvim_win_set_option(background, 'winhl', 'Normal:' . bordercolor)
|
||||
endif
|
||||
let hwnd.background = background
|
||||
call nvim_win_set_option(winid, 'winhl', 'Normal:' . hwnd.opts.color)
|
||||
return hwnd
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" redraw input area
|
||||
"----------------------------------------------------------------------
|
||||
function! s:update_input(hwnd)
|
||||
let hwnd = a:hwnd
|
||||
let rl = hwnd.rl
|
||||
let size = hwnd.w
|
||||
let ts = float2nr(reltimefloat(reltime()) * 1000)
|
||||
let blink = rl.blink(ts)
|
||||
let blink = (hwnd.wait)? 0 : blink
|
||||
let hwnd.pos = rl.slide(hwnd.pos, size)
|
||||
let display = rl.render(hwnd.pos, size)
|
||||
let cmdlist = ['syn clear']
|
||||
let x = 1
|
||||
let y = hwnd.lnum
|
||||
let content = []
|
||||
for [attr, text] in display
|
||||
let len = strwidth(text)
|
||||
let content += [text]
|
||||
let color = 'QuickInput'
|
||||
if attr == 1
|
||||
let color = (blink == 0)? 'QuickCursor' : 'QuickInput'
|
||||
elseif attr == 2
|
||||
let color = 'QuickVisual'
|
||||
elseif attr == 3
|
||||
let color = (blink == 0)? 'QuickCursor' : 'QuickVisual'
|
||||
endif
|
||||
let cmd = quickui#core#high_region(color, y, x, y, x + len, 1)
|
||||
let cmdlist += [cmd]
|
||||
let x += len
|
||||
endfor
|
||||
let text = join(content, '')
|
||||
call setbufline(hwnd.bid, y, text)
|
||||
call setbufvar(hwnd.bid, '&modified', 0)
|
||||
call quickui#core#win_execute(hwnd.winid, cmdlist)
|
||||
noautocmd redraw
|
||||
if 0
|
||||
echon 'blink='. blink
|
||||
echon ' <'
|
||||
call rl.echo(blink, 0, hwnd.w)
|
||||
echon '>'
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" select all text
|
||||
"----------------------------------------------------------------------
|
||||
function! s:select_all(hwnd)
|
||||
let hwnd = a:hwnd
|
||||
let rl = hwnd.rl
|
||||
let hwnd.pos = 0
|
||||
call rl.seek(0, 2)
|
||||
if rl.size > 0
|
||||
let rl.select = 0
|
||||
endif
|
||||
let hwnd.pos = rl.slide(hwnd.pos, hwnd.w)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create input box
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#input#create(prompt, opts)
|
||||
if s:has_nvim == 0
|
||||
let hwnd = s:vim_create_input(a:prompt, a:opts)
|
||||
else
|
||||
let hwnd = s:nvim_create_input(a:prompt, a:opts)
|
||||
endif
|
||||
let rl = hwnd.rl
|
||||
let accept = 0
|
||||
let result = ''
|
||||
silent! exec 'nohl'
|
||||
while hwnd.exit == 0
|
||||
call s:update_input(hwnd)
|
||||
try
|
||||
if hwnd.wait != 0
|
||||
let code = getchar()
|
||||
else
|
||||
let code = getchar(0)
|
||||
endif
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<C-C>"
|
||||
endtry
|
||||
if type(code) == v:t_number && code == 0
|
||||
try
|
||||
exec 'sleep 15m'
|
||||
continue
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<c-c>"
|
||||
endtry
|
||||
endif
|
||||
let ch = (type(code) == v:t_number)? nr2char(code) : code
|
||||
if ch == "\<ESC>" || ch == "\<c-c>"
|
||||
break
|
||||
endif
|
||||
if ch == ""
|
||||
continue
|
||||
elseif ch == "\<ESC>"
|
||||
break
|
||||
elseif ch == "\<cr>"
|
||||
let result = rl.update()
|
||||
if result != '' || hwnd.strict == 0
|
||||
let accept = 1
|
||||
call rl.history_save()
|
||||
break
|
||||
endif
|
||||
elseif ch == "\<LeftMouse>"
|
||||
if v:mouse_winid == hwnd.winid
|
||||
if v:mouse_lnum == hwnd.lnum
|
||||
let x = v:mouse_col - (s:has_nvim? 1 : 3)
|
||||
if x >= 0 && x < hwnd.w
|
||||
let pos = rl.mouse_click(hwnd.pos, x)
|
||||
call rl.seek(pos, 0)
|
||||
let rl.select = -1
|
||||
endif
|
||||
endif
|
||||
elseif s:has_nvim != 0
|
||||
if v:mouse_winid == hwnd.background
|
||||
if v:mouse_lnum == 1
|
||||
if v:mouse_col == hwnd.w + 4
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
elseif ch == "\<Up>" || ch == "\<c-p>"
|
||||
if len(rl.history) > 0
|
||||
call rl.feed("\<up>")
|
||||
call s:select_all(hwnd)
|
||||
endif
|
||||
elseif ch == "\<Down>" || ch == "\<c-n>"
|
||||
if len(rl.history) > 0
|
||||
call rl.feed("\<down>")
|
||||
call s:select_all(hwnd)
|
||||
endif
|
||||
elseif ch == "\<c-d>"
|
||||
redraw
|
||||
echon "winsize: " . hwnd.w
|
||||
elseif ch == "\<c-g>"
|
||||
call s:select_all(hwnd)
|
||||
elseif ch == "\<c-r>"
|
||||
let rop = {}
|
||||
let text = quickui#utils#read_eval(rop)
|
||||
let text = split(text, "\n", 1)[0]
|
||||
let text = substitute(text, '[\r\n\t]', ' ', 'g')
|
||||
if text != ''
|
||||
if rl.select >= 0
|
||||
call rl.visual_delete()
|
||||
endif
|
||||
call rl.insert(text)
|
||||
endif
|
||||
else
|
||||
call rl.feed(ch)
|
||||
endif
|
||||
endwhile
|
||||
if s:has_nvim == 0
|
||||
call popup_close(hwnd.winid)
|
||||
else
|
||||
call nvim_win_close(hwnd.winid, 0)
|
||||
if hwnd.background >= 0
|
||||
call nvim_win_close(hwnd.background, 0)
|
||||
endif
|
||||
endif
|
||||
call quickui#core#popup_clear(hwnd.winid)
|
||||
redraw
|
||||
if hwnd.history != ''
|
||||
let s:history[hwnd.history] = deepcopy(rl.history)
|
||||
endif
|
||||
return result
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" open input box
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#input#open(prompt, ...)
|
||||
let opts = {'title':'Input'}
|
||||
let opts.text = (a:0 >= 1)? (a:1) : ''
|
||||
if (a:0 >= 2)
|
||||
let opts.history = a:2
|
||||
endif
|
||||
let opts.wait = get(g:, 'quickui_input_wait', 0)
|
||||
return quickui#input#create(a:prompt, opts)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" testing suit
|
||||
"----------------------------------------------------------------------
|
||||
if 0
|
||||
let opts = {}
|
||||
let opts.title = 'Input'
|
||||
" let opts.w = 50
|
||||
echo quickui#input#open("Enter your name:", 'haha', 'abc')
|
||||
endif
|
||||
|
||||
|
664
vim/.vim/autoload/quickui/listbox.vim
Normal file
664
vim/.vim/autoload/quickui/listbox.vim
Normal file
@ -0,0 +1,664 @@
|
||||
"======================================================================
|
||||
"
|
||||
" listbox.vim -
|
||||
"
|
||||
" Created by skywind on 2019/12/20
|
||||
" Last Modified: 2023/08/30 14:47
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" stats
|
||||
"----------------------------------------------------------------------
|
||||
|
||||
" last position
|
||||
let g:quickui#listbox#cursor = -1
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" parse
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#listbox#parse(textlist)
|
||||
let items = {'image': [], 'column':0, 'nrows':0, 'keys':[], 'cmds':[]}
|
||||
let items.keymap = {}
|
||||
let items.displaywidth = 0
|
||||
let sizes = []
|
||||
let objects = []
|
||||
let spliter = ' '
|
||||
for description in a:textlist
|
||||
let obj = quickui#core#single_parse(description)
|
||||
let objects += [obj]
|
||||
if obj.key_pos >= 0
|
||||
let items.keymap[tolower(obj.key_char)] = items.nrows
|
||||
endif
|
||||
let items.nrows += 1
|
||||
while len(sizes) < obj.size
|
||||
let sizes += [0]
|
||||
endwhile
|
||||
let items.column = len(sizes)
|
||||
let index = 0
|
||||
for part in obj.part
|
||||
let size = strdisplaywidth(obj.part[index])
|
||||
if size > sizes[index]
|
||||
let sizes[index] = size
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
endfor
|
||||
for obj in objects
|
||||
let start = 1
|
||||
let index = 0
|
||||
let output = ' '
|
||||
let ni = ['', -1]
|
||||
for part in obj.part
|
||||
let size = strdisplaywidth(part)
|
||||
let need = sizes[index]
|
||||
if size >= need
|
||||
let element = part
|
||||
else
|
||||
let element = part . repeat(' ', need - size)
|
||||
endif
|
||||
if obj.key_idx == index
|
||||
let ni[0] = obj.key_char
|
||||
let ni[1] = start + obj.key_pos
|
||||
endif
|
||||
let output .= element
|
||||
if index + 1 < len(obj.part)
|
||||
let output .= spliter
|
||||
endif
|
||||
let start += strchars(element) + strchars(spliter)
|
||||
let index += 1
|
||||
endfor
|
||||
let items.image += [output . ' ']
|
||||
let items.keys += [ni]
|
||||
let items.cmds += [obj.cmd]
|
||||
let size = strdisplaywidth(output) + 1
|
||||
if size > items.displaywidth
|
||||
let items.displaywidth = size
|
||||
endif
|
||||
endfor
|
||||
return items
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" reposition text offset
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#listbox#reposition()
|
||||
exec 'normal! zz'
|
||||
let height = winheight(0)
|
||||
let size = line('$')
|
||||
let curline = line('.')
|
||||
let winline = winline()
|
||||
let topline = curline - winline + 1
|
||||
let botline = topline + height - 1
|
||||
let disline = botline - size
|
||||
if disline > 0
|
||||
exec 'normal ggG'
|
||||
exec ':' . curline
|
||||
exec 'normal G'
|
||||
exec ':' . curline
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" highlight keys
|
||||
"----------------------------------------------------------------------
|
||||
function! s:highlight_keys(winid, items)
|
||||
let items = a:items
|
||||
let index = 0
|
||||
let cmdlist = []
|
||||
while index < items.nrows
|
||||
let key = items.keys[index]
|
||||
if key[1] >= 0
|
||||
let px = key[1] + 1
|
||||
let py = index + 1
|
||||
let cmd = quickui#core#high_region('QuickKey', py, px, py, px + 1, 1)
|
||||
let cmdlist += [cmd]
|
||||
endif
|
||||
let index += 1
|
||||
endwhile
|
||||
call quickui#core#win_execute(a:winid, cmdlist)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" init window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:vim_create_listbox(textlist, opts)
|
||||
let hwnd = {}
|
||||
let opts = {}
|
||||
let items = quickui#listbox#parse(a:textlist)
|
||||
let winid = popup_create(items.image, {'hidden':1, 'wrap':0})
|
||||
let bufnr = winbufnr(winid)
|
||||
let hwnd.winid = winid
|
||||
let hwnd.items = items
|
||||
let hwnd.bufnr = bufnr
|
||||
let hwnd.keymap = quickui#utils#keymap()
|
||||
let hwnd.hotkey = items.keymap
|
||||
let hwnd.opts = deepcopy(a:opts)
|
||||
let hwnd.context = has_key(a:opts, 'context')? a:opts.context : {}
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
let w = has_key(a:opts, 'w')? a:opts.w : items.displaywidth
|
||||
let h = has_key(a:opts, 'h')? a:opts.h : items.nrows
|
||||
if h + 6 > &lines
|
||||
let h = &lines - 6
|
||||
let h = (h < 1)? 1 : h
|
||||
endif
|
||||
if w + 4 > &columns
|
||||
let w = &columns - 4
|
||||
let w = (w < 1)? 1 : w
|
||||
endif
|
||||
let opts = {"minwidth":w, "minheight":h, "maxwidth":w, "maxheight":h}
|
||||
let ww = w + ((border != 0)? 2 : 0)
|
||||
let hh = h + ((border != 0)? 2 : 0)
|
||||
if has_key(a:opts, 'line')
|
||||
let opts.line = a:opts.line
|
||||
else
|
||||
let limit1 = (&lines - 2) * 90 / 100
|
||||
let limit2 = (&lines - 2)
|
||||
if h + 4 < limit1
|
||||
let opts.line = (limit1 - hh) / 2
|
||||
else
|
||||
let opts.line = (limit2 - hh) / 2
|
||||
endif
|
||||
let opts.line = (opts.line < 1)? 1 : opts.line
|
||||
endif
|
||||
if has_key(a:opts, 'col')
|
||||
let opts.col = a:opts.col
|
||||
else
|
||||
let opts.col = (&columns - ww) / 2
|
||||
let opts.col = (opts.col < 1)? 1 : opts.col
|
||||
endif
|
||||
call popup_move(winid, opts)
|
||||
call setwinvar(winid, '&wincolor', get(a:opts, 'color', 'QuickBG'))
|
||||
if get(a:opts, 'index', 0) >= 0
|
||||
let moveto = get(a:opts, 'index', 0) + 1
|
||||
call popup_show(winid)
|
||||
call win_execute(winid, 'normal! G')
|
||||
call win_execute(winid, ':' . moveto)
|
||||
call win_execute(winid, 'normal! G')
|
||||
call win_execute(winid, ':' . moveto)
|
||||
call win_execute(winid, 'call quickui#listbox#reposition()')
|
||||
endif
|
||||
let opts = {'cursorline':1, 'drag':1, 'mapping':0}
|
||||
if get(a:opts, 'manual', 0) == 0
|
||||
let opts.filter = function('s:popup_filter')
|
||||
let opts.callback = function('s:popup_exit')
|
||||
endif
|
||||
let opts.border = [0,0,0,0,0,0,0,0,0]
|
||||
if border > 0
|
||||
let opts.borderchars = quickui#core#border_vim(border)
|
||||
let opts.border = [1,1,1,1,1,1,1,1,1]
|
||||
endif
|
||||
if has_key(a:opts, 'title') && (a:opts.title != '')
|
||||
let opts.title = ' ' . a:opts.title . ' '
|
||||
endif
|
||||
let opts.padding = [0,1,0,1]
|
||||
if has_key(a:opts, 'close') && (a:opts.close != '')
|
||||
let opts.close = a:opts.close
|
||||
endif
|
||||
let local = quickui#core#popup_local(winid)
|
||||
let local.hwnd = hwnd
|
||||
let local.winid = winid
|
||||
let keymap = hwnd.keymap
|
||||
if !has_key(a:opts, 'horizon')
|
||||
let keymap["\<LEFT>"] = 'HALFUP'
|
||||
let keymap["\<RIGHT>"] = 'HALFDOWN'
|
||||
let keymap["h"] = 'HALFUP'
|
||||
let keymap["l"] = 'HALFDOWN'
|
||||
endif
|
||||
if has_key(a:opts, 'keymap')
|
||||
for key in keys(a:opts.keymap)
|
||||
let keymap[key] = a:opts.keymap[key]
|
||||
endfor
|
||||
endif
|
||||
let hwnd.state = 1
|
||||
let hwnd.code = 0
|
||||
let hwnd.tag = ''
|
||||
let bc = get(a:opts, 'bordercolor', 'QuickBorder')
|
||||
let opts.borderhighlight = [bc, bc, bc, bc]
|
||||
call popup_setoptions(winid, opts)
|
||||
call win_execute(winid, 'syn clear')
|
||||
if has_key(a:opts, 'syntax')
|
||||
call win_execute(winid, 'set ft=' . fnameescape(a:opts.syntax))
|
||||
endif
|
||||
" call s:highlight_keys(winid, items)
|
||||
call s:highlight_keys(winid, items)
|
||||
call popup_show(winid)
|
||||
return hwnd
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" close list box
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#listbox#close(hwnd)
|
||||
if a:hwnd.winid > 0
|
||||
call popup_close(a:hwnd.winid)
|
||||
call quickui#core#popup_clear(a:hwnd.winid)
|
||||
let a:hwnd.winid = -1
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" handle exit code
|
||||
"----------------------------------------------------------------------
|
||||
function! s:popup_exit(winid, code)
|
||||
let local = quickui#core#popup_local(a:winid)
|
||||
let hwnd = local.hwnd
|
||||
let code = a:code
|
||||
if a:code > 0
|
||||
call win_execute(a:winid, ':' . a:code)
|
||||
redraw
|
||||
let code = a:code - 1
|
||||
endif
|
||||
let hwnd.state = 0
|
||||
let hwnd.code = code
|
||||
let g:quickui#listbox#cursor = quickui#utils#get_cursor(a:winid) - 1
|
||||
call quickui#core#popup_clear(a:winid)
|
||||
silent! call popup_hide(a:winid)
|
||||
let g:quickui#listbox#current = hwnd
|
||||
if has_key(hwnd.opts, 'callback')
|
||||
call call(hwnd.opts.callback, [code])
|
||||
endif
|
||||
if code >= 0 && code < hwnd.items.nrows
|
||||
let cmd = hwnd.items.cmds[code]
|
||||
if cmd != ''
|
||||
redraw
|
||||
try
|
||||
exec cmd
|
||||
catch /.*/
|
||||
echohl Error
|
||||
echom v:exception
|
||||
echohl None
|
||||
endtry
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" key processing
|
||||
"----------------------------------------------------------------------
|
||||
function! s:popup_filter(winid, key)
|
||||
let local = quickui#core#popup_local(a:winid)
|
||||
let hwnd = local.hwnd
|
||||
let keymap = hwnd.keymap
|
||||
if a:key == "\<ESC>" || a:key == "\<c-c>"
|
||||
call popup_close(a:winid, -1)
|
||||
return 1
|
||||
elseif a:key == "\<CR>" || a:key == "\<SPACE>"
|
||||
return popup_filter_menu(a:winid, "\<CR>")
|
||||
elseif a:key == "\<LeftMouse>"
|
||||
let pos = getmousepos()
|
||||
if pos.winid == a:winid
|
||||
if pos.line > 0
|
||||
call win_execute(a:winid, ':' . pos.line)
|
||||
call popup_setoptions(a:winid, {})
|
||||
redraw
|
||||
return popup_filter_menu(a:winid, "\<CR>")
|
||||
endif
|
||||
endif
|
||||
elseif a:key == ':' || a:key == '/' || a:key == '?'
|
||||
call quickui#utils#search_or_jump(a:winid, a:key)
|
||||
return 1
|
||||
elseif has_key(hwnd.hotkey, a:key)
|
||||
let index = hwnd.hotkey[a:key]
|
||||
call popup_close(a:winid, index + 1)
|
||||
return 1
|
||||
elseif has_key(keymap, a:key)
|
||||
let key = keymap[a:key]
|
||||
if strpart(key, 0, 4) == 'TAG:'
|
||||
let hwnd.tag = strpart(key, 4)
|
||||
return popup_filter_menu(a:winid, "\<CR>")
|
||||
elseif key == 'ESC'
|
||||
call popup_close(a:winid, -1)
|
||||
return 1
|
||||
elseif key == 'NEXT' || key == 'PREV'
|
||||
call quickui#utils#search_next(a:winid, key)
|
||||
else
|
||||
let cmd = 'quickui#listbox#cursor_movement("' . key . '")'
|
||||
call win_execute(a:winid, 'call ' . cmd)
|
||||
return 1
|
||||
endif
|
||||
endif
|
||||
return popup_filter_menu(a:winid, a:key)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" how to move cursor
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#listbox#cursor_movement(where)
|
||||
let curline = line('.')
|
||||
let endline = line('$')
|
||||
let height = winheight('.')
|
||||
if a:where == 'TOP'
|
||||
let curline = 0
|
||||
elseif a:where == 'BOTTOM'
|
||||
let curline = line('$')
|
||||
elseif a:where == 'UP'
|
||||
let curline = curline - 1
|
||||
elseif a:where == 'DOWN'
|
||||
let curline = curline + 1
|
||||
elseif a:where == 'PAGEUP'
|
||||
let curline = curline - height
|
||||
elseif a:where == 'PAGEDOWN'
|
||||
let curline = curline + height
|
||||
elseif a:where == 'HALFUP'
|
||||
let curline = curline - height / 2
|
||||
elseif a:where == 'HALFDOWN'
|
||||
let curline = curline + height / 2
|
||||
elseif a:where == 'KEEP'
|
||||
endif
|
||||
if curline < 1
|
||||
let curline = 1
|
||||
elseif curline > endline
|
||||
let curline = endline
|
||||
endif
|
||||
noautocmd exec ":" . curline
|
||||
noautocmd exec "normal! 0"
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" block and return result
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#listbox#inputlist(textlist, opts)
|
||||
if g:quickui#core#has_nvim != 0
|
||||
let opts = deepcopy(a:opts)
|
||||
if has_key(opts, 'callback')
|
||||
unlet opts['callback']
|
||||
endif
|
||||
return s:nvim_create_listbox(a:textlist, opts)
|
||||
endif
|
||||
let opts = deepcopy(a:opts)
|
||||
let opts.manual = 1
|
||||
if has_key(opts, 'callback')
|
||||
call remove(opts, 'callback')
|
||||
endif
|
||||
if len(a:textlist) == 0
|
||||
return -1000
|
||||
endif
|
||||
let hwnd = s:vim_create_listbox(a:textlist, opts)
|
||||
let winid = hwnd.winid
|
||||
let hr = -1
|
||||
" call win_execute(winid, 'normal zz')
|
||||
call popup_show(winid)
|
||||
while 1
|
||||
redraw
|
||||
try
|
||||
let code = getchar()
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<C-C>"
|
||||
endtry
|
||||
let ch = (type(code) == v:t_number)? nr2char(code) : code
|
||||
if ch == "\<ESC>" || ch == "\<c-c>"
|
||||
break
|
||||
elseif ch == " " || ch == "\<cr>"
|
||||
let cmd = 'let g:quickui#listbox#index = line(".")'
|
||||
call win_execute(winid, cmd)
|
||||
let hr = g:quickui#listbox#index - 1
|
||||
break
|
||||
elseif ch == "\<LeftMouse>"
|
||||
let pos = getmousepos()
|
||||
if pos.winid == winid
|
||||
if pos.line > 0
|
||||
call win_execute(winid, ':' . pos.line)
|
||||
call popup_setoptions(winid, {})
|
||||
redraw
|
||||
let hr = pos.line - 1
|
||||
break
|
||||
endif
|
||||
endif
|
||||
elseif ch == ':' || ch == '/' || ch == '?'
|
||||
call quickui#utils#search_or_jump(winid, ch)
|
||||
call popup_hide(winid)
|
||||
call popup_show(winid)
|
||||
elseif has_key(hwnd.hotkey, ch)
|
||||
let hr = hwnd.hotkey[ch]
|
||||
if hr >= 0
|
||||
break
|
||||
endif
|
||||
elseif has_key(hwnd.keymap, ch)
|
||||
let key = hwnd.keymap[ch]
|
||||
if key == 'ESC'
|
||||
break
|
||||
elseif key == 'NEXT' || key == 'PREV'
|
||||
call quickui#utils#search_next(winid, key)
|
||||
call popup_hide(winid)
|
||||
call popup_show(winid)
|
||||
else
|
||||
let cmd = 'quickui#listbox#cursor_movement("' . key . '")'
|
||||
call win_execute(winid, 'call ' . cmd)
|
||||
call popup_hide(winid)
|
||||
call popup_show(winid)
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
" echo 'size: '. winheight(winid)
|
||||
if hr > 0
|
||||
call quickui#core#win_execute(winid, ':' . (hr + 1))
|
||||
redraw
|
||||
endif
|
||||
let g:quickui#listbox#cursor = quickui#utils#get_cursor(winid) - 1
|
||||
call quickui#listbox#close(hwnd)
|
||||
return hr
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create list box in neovim
|
||||
"----------------------------------------------------------------------
|
||||
function! s:nvim_create_listbox(textlist, opts)
|
||||
let hwnd = {}
|
||||
let opts = {}
|
||||
let items = quickui#listbox#parse(a:textlist)
|
||||
let bid = quickui#core#scratch_buffer('listbox', items.image)
|
||||
let hwnd.items = items
|
||||
let hwnd.bid = bid
|
||||
let hwnd.keymap = quickui#utils#keymap()
|
||||
let hwnd.hotkey = items.keymap
|
||||
let hwnd.opts = deepcopy(a:opts)
|
||||
let hwnd.context = has_key(a:opts, 'context')? a:opts.context : {}
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
let w = has_key(a:opts, 'w')? a:opts.w : items.displaywidth
|
||||
let h = has_key(a:opts, 'h')? a:opts.h : items.nrows
|
||||
if h + 6 > &lines
|
||||
let h = &lines - 6
|
||||
let h = (h < 1)? 1 : h
|
||||
endif
|
||||
if w + 4 > &columns
|
||||
let w = &columns - 4
|
||||
let w = (w < 1)? 1 : w
|
||||
endif
|
||||
let ww = w + ((border != 0)? 2 : 0)
|
||||
let hh = h + ((border != 0)? 2 : 0)
|
||||
let opts = {'width':w, 'height':h, 'focusable':1, 'style':'minimal'}
|
||||
let opts.relative = 'editor'
|
||||
if has_key(a:opts, 'line')
|
||||
let opts.row = a:opts.line - 1
|
||||
else
|
||||
let limit1 = (&lines - 2) * 90 / 100
|
||||
let limit2 = (&lines - 2)
|
||||
" echom printf("limit1=%d limit2=%d h=%d hh=%d", limit1, limit2, h, hh)
|
||||
if h + 4 < limit1
|
||||
let opts.row = (limit1 - hh) / 2
|
||||
else
|
||||
let opts.row = (limit2 - hh) / 2
|
||||
endif
|
||||
let opts.row = (opts.row < 0)? 0 : opts.row
|
||||
endif
|
||||
if has_key(a:opts, 'col')
|
||||
let opts.col = a:opts.col - 1
|
||||
else
|
||||
let opts.col = (&columns - ww) / 2 - 1
|
||||
let opts.col = (opts.col < 0)? 0 : opts.col
|
||||
endif
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
let background = -1
|
||||
let hwnd.opts.color = get(a:opts, 'color', 'QuickBG')
|
||||
let color = hwnd.opts.color
|
||||
if border > 0 && get(g:, 'quickui_nvim_simulate_border', 1) != 0
|
||||
let opts.row += 1
|
||||
let opts.col += 1
|
||||
endif
|
||||
if has('nvim-0.6.0')
|
||||
let opts.noautocmd = 1
|
||||
endif
|
||||
let winid = nvim_open_win(bid, 0, opts)
|
||||
let button = (get(a:opts, 'close', '') == 'button')? 1 : 0
|
||||
if border > 0 && get(g:, 'quickui_nvim_simulate_border', 1) != 0
|
||||
let title = has_key(a:opts, 'title')? ' ' . a:opts.title . ' ' : ''
|
||||
let back = quickui#utils#make_border(w, h, border, title, button)
|
||||
let nbid = quickui#core#scratch_buffer('listborder', back)
|
||||
let op = {'relative':'editor', 'focusable':1, 'style':'minimal'}
|
||||
let op.width = w + 2
|
||||
let op.height = h + 2
|
||||
let op.row = opts.row - 1
|
||||
let op.col = opts.col - 1
|
||||
let bordercolor = get(a:opts, 'bordercolor', 'QuickBorder')
|
||||
if has('nvim-0.6.0')
|
||||
let op.noautocmd = 1
|
||||
endif
|
||||
let background = nvim_open_win(nbid, 0, op)
|
||||
call nvim_win_set_option(background, 'winhl', 'Normal:'. bordercolor)
|
||||
endif
|
||||
let hwnd.winid = winid
|
||||
call nvim_win_set_option(winid, 'winhl', 'Normal:'. color)
|
||||
if get(a:opts, 'index', 0) >= 0
|
||||
let moveto = get(a:opts, 'index', 0) + 1
|
||||
call quickui#core#win_execute(winid, 'noautocmd normal! ggG')
|
||||
call quickui#core#win_execute(winid, 'noautocmd :' . moveto)
|
||||
call quickui#core#win_execute(winid, 'noautocmd normal! 0')
|
||||
endif
|
||||
let border = get(a:opts, 'border', 1)
|
||||
let keymap = hwnd.keymap
|
||||
if !has_key(a:opts, 'horizon')
|
||||
let keymap["\<LEFT>"] = 'HALFUP'
|
||||
let keymap["\<RIGHT>"] = 'HALFDOWN'
|
||||
let keymap["h"] = 'HALFUP'
|
||||
let keymap["l"] = 'HALFDOWN'
|
||||
endif
|
||||
if has_key(a:opts, 'keymap')
|
||||
for key in keys(a:opts.keymap)
|
||||
let keymap[key] = a:opts.keymap[key]
|
||||
endfor
|
||||
endif
|
||||
let hwnd.state = 1
|
||||
let hwnd.code = 0
|
||||
let hwnd.tag = ''
|
||||
call quickui#core#win_execute(winid, 'setlocal nowrap')
|
||||
call quickui#core#win_execute(winid, 'syn clear')
|
||||
if has_key(a:opts, 'syntax')
|
||||
let syntax = fnameescape(a:opts.syntax)
|
||||
call quickui#core#win_execute(winid, 'set ft=' . syntax)
|
||||
endif
|
||||
call s:highlight_keys(winid, items)
|
||||
call quickui#core#win_execute(winid, "setlocal cursorline scrolloff=0")
|
||||
if exists('+cursorlineopt')
|
||||
call quickui#core#win_execute(winid, "setlocal cursorlineopt=both")
|
||||
endif
|
||||
let retval = -1
|
||||
while 1
|
||||
noautocmd redraw!
|
||||
try
|
||||
let code = getchar()
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<C-C>"
|
||||
endtry
|
||||
let ch = (type(code) == v:t_number)? nr2char(code) : code
|
||||
if ch == "\<ESC>" || ch == "\<c-c>"
|
||||
break
|
||||
elseif ch == "\<cr>" || ch == "\<space>"
|
||||
let retval = quickui#utils#get_cursor(winid) - 1
|
||||
break
|
||||
elseif ch == "\<LeftMouse>"
|
||||
if v:mouse_winid == winid
|
||||
if v:mouse_lnum > 0
|
||||
let cmd = ':' . v:mouse_lnum
|
||||
call quickui#core#win_execute(winid, cmd)
|
||||
redraw!
|
||||
sleep 10m
|
||||
let retval = v:mouse_lnum - 1
|
||||
break
|
||||
endif
|
||||
elseif v:mouse_winid == background
|
||||
if button != 0 && v:mouse_lnum == 1
|
||||
if v:mouse_col == w + 2
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
elseif ch == ':' || ch == '/' || ch == '?'
|
||||
call quickui#utils#search_or_jump(winid, ch)
|
||||
let cmd = 'call quickui#listbox#cursor_movement("KEEP")'
|
||||
noautocmd call quickui#core#win_execute(winid, cmd)
|
||||
elseif has_key(hwnd.hotkey, ch)
|
||||
let retval = hwnd.hotkey[ch]
|
||||
break
|
||||
elseif has_key(keymap, ch)
|
||||
let key = keymap[ch]
|
||||
if strpart(key, 0, 4) == 'TAG:'
|
||||
let hwnd.tag = strpart(key, 4)
|
||||
let retval = quickui#utils#get_cursor(winid) - 1
|
||||
break
|
||||
elseif key == "ESC"
|
||||
break
|
||||
elseif key == 'NEXT' || key == 'PREV'
|
||||
call quickui#utils#search_next(winid, key)
|
||||
else
|
||||
let cmd = 'quickui#listbox#cursor_movement("' . key . '")'
|
||||
noautocmd call quickui#core#win_execute(winid, 'call ' . cmd)
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
let hwnd.code = retval
|
||||
if retval > 0
|
||||
call quickui#core#win_execute(winid, ':' . (retval + 1))
|
||||
endif
|
||||
let g:quickui#listbox#cursor = quickui#utils#get_cursor(winid) - 1
|
||||
call nvim_win_close(winid, 0)
|
||||
if background >= 0
|
||||
call nvim_win_close(background, 0)
|
||||
endif
|
||||
redraw!
|
||||
let hwnd.state = 0
|
||||
let g:quickui#listbox#current = hwnd
|
||||
if has_key(hwnd.opts, 'callback')
|
||||
call call(hwnd.opts.callback, [retval])
|
||||
endif
|
||||
if retval >= 0 && retval < hwnd.items.nrows
|
||||
let cmd = hwnd.items.cmds[retval]
|
||||
if cmd != ''
|
||||
try
|
||||
exec cmd
|
||||
catch /.*/
|
||||
echohl Error
|
||||
echom v:exception
|
||||
echohl None
|
||||
endtry
|
||||
endif
|
||||
endif
|
||||
return retval
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" open popup and run command when select an item
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#listbox#open(content, opts)
|
||||
if g:quickui#core#has_nvim == 0
|
||||
return s:vim_create_listbox(a:content, a:opts)
|
||||
else
|
||||
return s:nvim_create_listbox(a:content, a:opts)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
|
828
vim/.vim/autoload/quickui/menu.vim
Normal file
828
vim/.vim/autoload/quickui/menu.vim
Normal file
@ -0,0 +1,828 @@
|
||||
"======================================================================
|
||||
"
|
||||
" menu.vim - main menu bar
|
||||
"
|
||||
" Created by skywind on 2019/12/24
|
||||
" Last Modified: 2019/12/30 01:14
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" namespace of configuration
|
||||
"----------------------------------------------------------------------
|
||||
let s:namespace = { 'system':{'config':{}, 'weight':100, 'index':0} }
|
||||
let s:name = 'system'
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" switch config namespace
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#switch(name)
|
||||
if !has_key(s:namespace, a:name)
|
||||
let s:namespace[a:name] = {}
|
||||
let s:namespace[a:name].config = {}
|
||||
let s:namespace[a:name].index = 0
|
||||
let s:namespace[a:name].weight = 100
|
||||
endif
|
||||
let s:name = a:name
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" clear all entries in current namespace
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#reset()
|
||||
let current = s:namespace[s:name].config
|
||||
let s:namespace[s:name].weight = 100
|
||||
let s:namespace[s:name].index = 0
|
||||
for key in keys(current)
|
||||
call remove(current, key)
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" register entry: (section='File', entry='&Save', command='w')
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#register(section, entry, command, help)
|
||||
let current = s:namespace[s:name].config
|
||||
if !has_key(current, a:section)
|
||||
let index = 0
|
||||
let maximum = 0
|
||||
for name in keys(current)
|
||||
let w = current[name].weight
|
||||
let maximum = (index == 0)? w : ((maximum < w)? w : maximum)
|
||||
let index += 1
|
||||
endfor
|
||||
let current[a:section] = {'name':a:section, 'weight':0, 'items':[]}
|
||||
let current[a:section].ft = ''
|
||||
let current[a:section].weight = s:namespace[s:name].weight
|
||||
let s:namespace[s:name].weight += 10
|
||||
endif
|
||||
let menu = current[a:section]
|
||||
let item = {'name':a:entry, 'cmd':a:command, 'help':a:help}
|
||||
let menu.items += [item]
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" remove entry:
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#remove(section, index)
|
||||
let current = s:namespace[s:name].config
|
||||
if !has_key(current, a:section)
|
||||
return -1
|
||||
endif
|
||||
let menu = current[a:section]
|
||||
if type(a:index) == v:t_number
|
||||
let index = (a:index < 0)? (len(menu.items) + a:index) : a:index
|
||||
if index < 0 || index >= len(menu.items)
|
||||
return -1
|
||||
endif
|
||||
call remove(menu.items, index)
|
||||
elseif type(a:index) == v:t_string
|
||||
if a:index ==# '*'
|
||||
menu.items = []
|
||||
else
|
||||
let index = -1
|
||||
for ii in range(len(menu.items))
|
||||
if menu.items[ii].name ==# a:index
|
||||
let index = ii
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if index < 0
|
||||
return -1
|
||||
endif
|
||||
call remove(menu.items, index)
|
||||
endif
|
||||
endif
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" return items key
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#section(section)
|
||||
let current = s:namespace[s:name].config
|
||||
return get(current, a:section, v:null)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" install a how section
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#install(section, content, ...)
|
||||
let current = s:namespace[s:name].config
|
||||
if a:0 > 2 && (a:3 != 0)
|
||||
while 1
|
||||
if quickui#menu#remove(a:section, 0) != 0
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
endif
|
||||
if type(a:content) == v:t_list
|
||||
for item in a:content
|
||||
if type(item) == v:t_dict
|
||||
call quickui#menu#register(a:section, item.name, item.command)
|
||||
elseif type(item) == v:t_list
|
||||
let size = len(item)
|
||||
let name = (size >= 1)? item[0] : ''
|
||||
let cmd = (size >= 2)? item[1] : ''
|
||||
let help = (size >= 3)? item[2] : ''
|
||||
call quickui#menu#register(a:section, name, cmd, help)
|
||||
elseif type(item) == v:t_string
|
||||
call quickui#menu#register(a:section, item, '', '')
|
||||
endif
|
||||
endfor
|
||||
elseif type(a:content) == v:t_dict
|
||||
for name in keys(a:content)
|
||||
let cmd = a:content[name]
|
||||
call quickui#menu#register(a:section, name, cmd, '')
|
||||
endfor
|
||||
endif
|
||||
if a:0 > 0 && has_key(current, a:section)
|
||||
if type(a:1) == v:t_number
|
||||
let current[a:section].weight = a:1
|
||||
endif
|
||||
endif
|
||||
if a:0 > 1 && has_key(current, a:section)
|
||||
let current[a:section].ft = a:2
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" clear all entries in current namespace
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#clear(section)
|
||||
let current = s:namespace[s:name].config
|
||||
if has_key(current, a:section)
|
||||
call remove(current, a:section)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" change weight
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#change_weight(section, weight)
|
||||
let current = s:namespace[s:name].config
|
||||
if has_key(current, a:section)
|
||||
let current[a:section].weight = a:weight
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" change file types
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#change_ft(section, ft)
|
||||
let current = s:namespace[s:name].config
|
||||
if has_key(current, a:section)
|
||||
let current[a:section].ft = a:ft
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" preset menu
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#preset(section, context, ...)
|
||||
let current = s:namespace[s:name].config
|
||||
let save_items = []
|
||||
if has_key(current, a:section)
|
||||
let save_items = current[a:section].items
|
||||
let current[a:section].items = []
|
||||
endif
|
||||
if a:0 == 0
|
||||
call quickui#menu#install(a:section, a:context)
|
||||
else
|
||||
call quickui#menu#install(a:section, a:context, a:1)
|
||||
endif
|
||||
if len(save_items) > 0
|
||||
if len(a:context) > 0
|
||||
call quickui#menu#register(a:section, '--', '', '')
|
||||
endif
|
||||
for ni in save_items
|
||||
call quickui#menu#register(a:section, ni.name, ni.cmd, ni.help)
|
||||
endfor
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" compare section
|
||||
"----------------------------------------------------------------------
|
||||
function! s:section_compare(s1, s2)
|
||||
if a:s1[0] == a:s2[0]
|
||||
return 0
|
||||
else
|
||||
return (a:s1[0] > a:s2[0])? 1 : -1
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get section
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#available(name)
|
||||
let current = s:namespace[a:name].config
|
||||
let menus = []
|
||||
let callback = get(g:, 'quickui_menu_filter', '')
|
||||
let F = (callback != '')? function(callback) : ''
|
||||
for name in keys(current)
|
||||
let menu = current[name]
|
||||
if menu.ft != ''
|
||||
let fts = split(menu.ft, ',')
|
||||
if index(fts, &ft) < 0
|
||||
continue
|
||||
endif
|
||||
endif
|
||||
if callback != ''
|
||||
if F(menu.name) == 0
|
||||
continue
|
||||
endif
|
||||
endif
|
||||
if len(menu.items) > 0
|
||||
let menus += [[menu.weight, menu.name]]
|
||||
endif
|
||||
endfor
|
||||
call sort(menus, 's:section_compare')
|
||||
let result = []
|
||||
for obj in menus
|
||||
let result += [obj[1]]
|
||||
endfor
|
||||
return result
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" parse
|
||||
"----------------------------------------------------------------------
|
||||
function! s:parse_menu(name, padding)
|
||||
let current = s:namespace[a:name].config
|
||||
let inst = {'items':[], 'text':'', 'width':0, 'hotkey':{}}
|
||||
let start = 0
|
||||
let split = repeat(' ', a:padding)
|
||||
let names = quickui#menu#available(a:name)
|
||||
let index = 0
|
||||
let size = len(names)
|
||||
for section in names
|
||||
let menu = current[section]
|
||||
let item = {'name':menu.name, 'text':''}
|
||||
let obj = quickui#core#escape(menu.name)
|
||||
let item.text = ' ' . obj[0] . ' '
|
||||
let item.key_char = obj[1]
|
||||
let item.key_pos = (obj[4] < 0)? -1 : (obj[4] + 1)
|
||||
let item.x = start
|
||||
let item.w = strwidth(item.text)
|
||||
let start += item.w + strwidth(split)
|
||||
let inst.items += [item]
|
||||
let inst.text .= item.text . ((index + 1 < size)? split : '')
|
||||
if item.key_pos >= 0
|
||||
let key = tolower(item.key_char)
|
||||
let inst.hotkey[key] = index
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
let inst.width = strwidth(inst.text)
|
||||
return inst
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" internal
|
||||
"----------------------------------------------------------------------
|
||||
let s:cmenu = {'state':0, 'index':0, 'size':0, 'winid':-1, 'drop':-1}
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create popup ui
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#create(opts)
|
||||
if s:cmenu.state != 0
|
||||
return -1
|
||||
endif
|
||||
let name = get(a:opts, 'name', s:name)
|
||||
if !has_key(s:namespace, name)
|
||||
return -1
|
||||
endif
|
||||
let current = s:namespace[name].config
|
||||
let s:cmenu.inst = s:parse_menu(name, 2)
|
||||
if s:cmenu.inst.width + 5 >= &columns
|
||||
let s:cmenu.inst = s:parse_menu(name, 1)
|
||||
if s:cmenu.inst.width + 5 >= &columns
|
||||
let s:cmenu.inst = s:parse_menu(name, 0)
|
||||
endif
|
||||
endif
|
||||
let s:cmenu.name = name
|
||||
let s:cmenu.index = s:namespace[name].index
|
||||
let s:cmenu.width = &columns
|
||||
let s:cmenu.size = len(s:cmenu.inst.items)
|
||||
let s:cmenu.current = current
|
||||
let winid = popup_create([s:cmenu.inst.text], {'hidden':1, 'wrap':0})
|
||||
let bufnr = winbufnr(winid)
|
||||
let s:cmenu.winid = winid
|
||||
let s:cmenu.bufnr = bufnr
|
||||
let s:cmenu.cfg = deepcopy(a:opts)
|
||||
let w = s:cmenu.width
|
||||
let opts = {"minwidth":w, "maxwidth":w, "minheight":1, "maxheight":1}
|
||||
let opts.line = 1
|
||||
let opts.col = 1
|
||||
call popup_move(winid, opts)
|
||||
call setwinvar(winid, '&wincolor', get(a:opts, 'color', 'QuickBG'))
|
||||
let opts = {'mapping':0, 'cursorline':0, 'drag':0, 'zindex':31000}
|
||||
let opts.border = [0,0,0,0,0,0,0,0,0]
|
||||
let opts.padding = [0,0,0,0]
|
||||
let opts.filter = 'quickui#menu#filter'
|
||||
let opts.callback = 'quickui#menu#callback'
|
||||
if 1
|
||||
let keymap = quickui#utils#keymap()
|
||||
let s:cmenu.keymap = keymap
|
||||
endif
|
||||
let s:cmenu.hotkey = s:cmenu.inst.hotkey
|
||||
" echo "hotkey: ". string(s:cmenu.hotkey)
|
||||
let s:cmenu.drop = -1
|
||||
let s:cmenu.state = 1
|
||||
let s:cmenu.context = -1
|
||||
call popup_setoptions(winid, opts)
|
||||
call quickui#menu#update()
|
||||
call popup_show(winid)
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" render menu
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#update()
|
||||
let winid = s:cmenu.winid
|
||||
if s:cmenu.state == 0
|
||||
return -1
|
||||
endif
|
||||
let inst = s:cmenu.inst
|
||||
let cmdlist = ['syn clear']
|
||||
let index = 0
|
||||
for item in inst.items
|
||||
if item.key_pos >= 0
|
||||
let x = item.key_pos + item.x + 1
|
||||
let cmd = quickui#core#high_region('QuickKey', 1, x, 1, x + 1, 1)
|
||||
let cmdlist += [cmd]
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
let index = s:cmenu.index
|
||||
if index >= 0 && index < s:cmenu.size
|
||||
let x = inst.items[index].x + 1
|
||||
let e = x + inst.items[index].w
|
||||
let cmd = quickui#core#high_region('QuickSel', 1, x, 1, e, 1)
|
||||
let cmdlist += [cmd]
|
||||
endif
|
||||
call quickui#core#win_execute(winid, cmdlist)
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" close menu
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#close()
|
||||
if s:cmenu.state != 0
|
||||
call popup_close(s:cmenu.winid)
|
||||
let s:cmenu.winid = -1
|
||||
let s:cmenu.state = 0
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" exit callback
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#callback(winid, code)
|
||||
" echom "quickui#menu#callback"
|
||||
let s:cmenu.state = 0
|
||||
let s:cmenu.winid = -1
|
||||
let s:namespace[s:cmenu.name].index = s:cmenu.index
|
||||
if s:cmenu.context >= 0
|
||||
call popup_close(s:cmenu.context, -3)
|
||||
let s:cmenu.context = -1
|
||||
endif
|
||||
redraw
|
||||
echo ""
|
||||
redraw
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" event handler
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#filter(winid, key)
|
||||
let keymap = s:cmenu.keymap
|
||||
if a:key == "\<ESC>" || a:key == "\<c-c>"
|
||||
call popup_close(a:winid, -1)
|
||||
return 1
|
||||
elseif a:key == "\<LeftMouse>"
|
||||
return s:mouse_click()
|
||||
elseif has_key(s:cmenu.hotkey, a:key)
|
||||
let index = s:cmenu.hotkey[a:key]
|
||||
let index = (index < 0)? (s:cmenu.size - 1) : index
|
||||
let index = (index >= s:cmenu.size)? 0 : index
|
||||
let s:cmenu.index = (s:cmenu.size == 0)? 0 : index
|
||||
call quickui#menu#update()
|
||||
call s:context_dropdown()
|
||||
redraw
|
||||
elseif has_key(keymap, a:key)
|
||||
let key = keymap[a:key]
|
||||
call s:movement(key)
|
||||
redraw
|
||||
return 1
|
||||
endif
|
||||
return 1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" moving
|
||||
"----------------------------------------------------------------------
|
||||
function! s:movement(key)
|
||||
if a:key == 'ESC'
|
||||
if g:quickui#core#has_nvim == 0
|
||||
call popup_close(s:cmenu.winid, -1)
|
||||
endif
|
||||
return 1
|
||||
elseif a:key == 'LEFT' || a:key == 'RIGHT'
|
||||
let index = s:cmenu.index
|
||||
if index < 0
|
||||
let index = 0
|
||||
elseif a:key == 'LEFT'
|
||||
let index -= 1
|
||||
elseif a:key == 'RIGHT'
|
||||
let index += 1
|
||||
endif
|
||||
let index = (index < 0)? (s:cmenu.size - 1) : index
|
||||
let index = (index >= s:cmenu.size)? 0 : index
|
||||
let s:cmenu.index = (s:cmenu.size == 0)? 0 : index
|
||||
call quickui#menu#update()
|
||||
" echo "MOVE: " . index
|
||||
elseif a:key == 'PAGEUP' || a:key == 'PAGEDOWN'
|
||||
let index = (a:key == 'PAGEUP')? 0 : (s:cmenu.size - 1)
|
||||
let s:cmenu.index = (s:cmenu.size == 0)? 0 : index
|
||||
call quickui#menu#update()
|
||||
elseif a:key == 'ENTER' || a:key == 'DOWN'
|
||||
if g:quickui#core#has_nvim == 0
|
||||
call s:context_dropdown()
|
||||
else
|
||||
return s:neovim_dropdown()
|
||||
endif
|
||||
endif
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" mouse click
|
||||
"----------------------------------------------------------------------
|
||||
function! s:mouse_click()
|
||||
let pos = getmousepos()
|
||||
if pos.winid != s:cmenu.winid || pos.line != 1
|
||||
call popup_close(s:cmenu.winid, -1)
|
||||
return 0
|
||||
endif
|
||||
let x = pos.wincol - 1
|
||||
let index = 0
|
||||
let select = -1
|
||||
for item in s:cmenu.inst.items
|
||||
if x >= item.x && x < item.x + item.w
|
||||
let select = index
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
if select >= 0
|
||||
let s:cmenu.index = select
|
||||
if s:cmenu.context >= 0
|
||||
call popup_close(s:cmenu.index, -1)
|
||||
let s:cmenu.context = -1
|
||||
endif
|
||||
call quickui#menu#update()
|
||||
call s:context_dropdown()
|
||||
redraw
|
||||
endif
|
||||
return 1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" drop down context
|
||||
"----------------------------------------------------------------------
|
||||
function! s:context_dropdown()
|
||||
let cursor = s:cmenu.index
|
||||
if cursor < 0 || cursor >= s:cmenu.size || s:cmenu.state == 0
|
||||
return 0
|
||||
endif
|
||||
if s:cmenu.state == 2
|
||||
call popup_close(s:cmenu.context, -3)
|
||||
let s:cmenu.state = 1
|
||||
let s:cmenu.context = -1
|
||||
endif
|
||||
let item = s:cmenu.inst.items[s:cmenu.index]
|
||||
let opts = {'col': item.x + 1, 'line': 2, 'horizon':1, 'zindex':31100}
|
||||
let opts.callback = 'quickui#menu#context_exit'
|
||||
let opts.reserve = 1
|
||||
let opts.lazyredraw = 1
|
||||
let cfg = s:cmenu.current[item.name]
|
||||
let s:cmenu.dropdown = []
|
||||
for item in cfg.items
|
||||
let s:cmenu.dropdown += [[item.name, item.cmd, item.help]]
|
||||
endfor
|
||||
let index = get(cfg, 'index', 0)
|
||||
let opts.index = (index < 0 || index >= len(cfg.items))? 0 : index
|
||||
let cfg.index = opts.index
|
||||
let hwnd = quickui#context#open(s:cmenu.dropdown, opts)
|
||||
let s:cmenu.context = hwnd.winid
|
||||
let s:cmenu.state = 1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" context menu callback
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#context_exit(code)
|
||||
" echom "quickui#menu#context_exit"
|
||||
let s:cmenu.context = -1
|
||||
let hwnd = g:quickui#context#current
|
||||
if has_key(hwnd, 'index') && hwnd.index >= 0
|
||||
let item = s:cmenu.inst.items[s:cmenu.index]
|
||||
let cfg = s:cmenu.current[item.name]
|
||||
let cfg.index = hwnd.index
|
||||
" echo "save index: ".hwnd.index
|
||||
endif
|
||||
if a:code >= 0 || a:code == -3
|
||||
if s:cmenu.state > 0 && s:cmenu.winid >= 0
|
||||
call popup_close(s:cmenu.winid, 0)
|
||||
endif
|
||||
return 0
|
||||
elseif a:code == -1 " close context menu by ESC
|
||||
if s:cmenu.state > 0 && s:cmenu.winid >= 0
|
||||
call popup_close(s:cmenu.winid, 0)
|
||||
endif
|
||||
elseif a:code == -2 " close context menu by mouse
|
||||
if s:cmenu.state > 0 && s:cmenu.winid >= 0
|
||||
let pos = getmousepos()
|
||||
if pos.winid != s:cmenu.winid
|
||||
call popup_close(s:cmenu.winid, 0)
|
||||
endif
|
||||
endif
|
||||
elseif a:code == -1000 || a:code == -2000
|
||||
call s:movement((a:code == -1000)? 'LEFT' : 'RIGHT')
|
||||
call s:movement('DOWN')
|
||||
elseif a:code == -1001 || a:code == -2001
|
||||
call s:movement((a:code == -1001)? 'PAGEUP' : 'PAGEDOWN')
|
||||
call s:movement('DOWN')
|
||||
endif
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" open menu
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#open(...)
|
||||
let opts = {}
|
||||
if a:0 > 0
|
||||
let opts.name = a:1
|
||||
endif
|
||||
if g:quickui#core#has_nvim == 0
|
||||
call quickui#menu#create(opts)
|
||||
else
|
||||
call quickui#menu#nvim_open_menu(opts)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" neovim dropdown context: returns non-zero for exit
|
||||
"----------------------------------------------------------------------
|
||||
function! s:neovim_dropdown()
|
||||
let cursor = s:cmenu.index
|
||||
if cursor < 0 || cursor >= s:cmenu.size || s:cmenu.state == 0
|
||||
return 0
|
||||
endif
|
||||
if s:cmenu.state == 2
|
||||
let s:cmenu.state = 1
|
||||
let s:cmenu.context = -1
|
||||
return 1
|
||||
endif
|
||||
let item = s:cmenu.inst.items[s:cmenu.index]
|
||||
let opts = {'col': item.x + 1, 'line': 2, 'horizon':1, 'zindex':31100}
|
||||
let opts.reserve = 1
|
||||
let opts.lazyredraw = 1
|
||||
let cfg = s:cmenu.current[item.name]
|
||||
let s:cmenu.dropdown = []
|
||||
for item in cfg.items
|
||||
let s:cmenu.dropdown += [[item.name, '', item.help]]
|
||||
endfor
|
||||
let index = get(cfg, 'index', 0)
|
||||
let opts.index = (index < 0 || index >= len(cfg.items))? 0 : index
|
||||
let cfg.index = opts.index
|
||||
let hr = quickui#context#open(s:cmenu.dropdown, opts)
|
||||
let cfg.index = g:quickui#context#current.index
|
||||
let s:cmenu.next = 0
|
||||
if hr >= 0
|
||||
if hr < len(cfg.items)
|
||||
let s:cmenu.script = cfg.items[hr].cmd
|
||||
endif
|
||||
return 1
|
||||
elseif hr == -1000
|
||||
call s:movement('LEFT')
|
||||
let s:cmenu.next = 1
|
||||
elseif hr == -2000
|
||||
call s:movement('RIGHT')
|
||||
let s:cmenu.next = 1
|
||||
elseif hr == -1001
|
||||
call s:movement('PAGEUP')
|
||||
let s:cmenu.next = 1
|
||||
elseif hr == -2001
|
||||
call s:movement('PAGEDOWN')
|
||||
let s:cmenu.next = 1
|
||||
elseif hr == -2
|
||||
call s:neovim_click()
|
||||
endif
|
||||
return (s:cmenu.next == 0)? 1 : 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" returns non-zero to quit
|
||||
"----------------------------------------------------------------------
|
||||
function! s:neovim_click()
|
||||
if v:mouse_winid != s:cmenu.winid || v:mouse_lnum != 1
|
||||
return 1
|
||||
endif
|
||||
let x = v:mouse_col - 1
|
||||
let index = 0
|
||||
let select = -1
|
||||
for item in s:cmenu.inst.items
|
||||
if x >= item.x && x < item.x + item.w
|
||||
let select = index
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
if select >= 0
|
||||
let s:cmenu.index = select
|
||||
let s:cmenu.next = 1
|
||||
endif
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" neovim open menu
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#menu#nvim_open_menu(opts)
|
||||
if s:cmenu.state != 0
|
||||
" return -1
|
||||
endif
|
||||
let name = get(a:opts, 'name', s:name)
|
||||
if !has_key(s:namespace, name)
|
||||
return -1
|
||||
endif
|
||||
let current = s:namespace[name].config
|
||||
let s:cmenu.inst = s:parse_menu(name, 2)
|
||||
if s:cmenu.inst.width + 5 >= &columns
|
||||
let s:cmenu.inst = s:parse_menu(name, 1)
|
||||
if s:cmenu.inst.width + 5 >= &columns
|
||||
let s:cmenu.inst = s:parse_menu(name, 0)
|
||||
endif
|
||||
endif
|
||||
let s:cmenu.name = name
|
||||
let s:cmenu.index = s:namespace[name].index
|
||||
let s:cmenu.width = &columns
|
||||
let s:cmenu.size = len(s:cmenu.inst.items)
|
||||
let s:cmenu.current = current
|
||||
let bid = quickui#core#scratch_buffer('menu', [s:cmenu.inst.text])
|
||||
let w = s:cmenu.width
|
||||
let opts = {'width':w, 'height':1, 'focusable':1, 'style':'minimal'}
|
||||
let opts.col = 0
|
||||
let opts.row = 0
|
||||
let opts.relative = 'editor'
|
||||
let s:cmenu.bufnr = bid
|
||||
if has('nvim-0.6.0')
|
||||
let opts.noautocmd = 1
|
||||
endif
|
||||
let winid = nvim_open_win(bid, 0, opts)
|
||||
let s:cmenu.winid = winid
|
||||
let s:cmenu.cfg = deepcopy(a:opts)
|
||||
let w = s:cmenu.width
|
||||
let color = get(a:opts, 'color', 'QuickBG')
|
||||
call nvim_win_set_option(winid, 'winhl', 'Normal:'. color)
|
||||
let s:cmenu.hotkey = s:cmenu.inst.hotkey
|
||||
let s:cmenu.state = 1
|
||||
let s:cmenu.context = -1
|
||||
let s:cmenu.next = 0
|
||||
let keymap = quickui#utils#keymap()
|
||||
let s:cmenu.keymap = keymap
|
||||
let s:cmenu.script = ''
|
||||
call quickui#menu#update()
|
||||
while 1
|
||||
noautocmd call quickui#menu#update()
|
||||
if s:cmenu.next == 0
|
||||
noautocmd redraw
|
||||
elseif s:cmenu.next == 1
|
||||
let s:cmenu.next = 0
|
||||
call quickui#menu#update()
|
||||
if s:neovim_dropdown() != 0
|
||||
break
|
||||
else
|
||||
continue
|
||||
endif
|
||||
elseif s:cmenu.next == 2
|
||||
let s:cmenu.next = 0
|
||||
continue
|
||||
endif
|
||||
let s:cmenu.next = 0
|
||||
try
|
||||
let code = getchar()
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<C-C>"
|
||||
endtry
|
||||
let ch = (type(code) == v:t_number)? nr2char(code) : code
|
||||
if ch == "\<ESC>" || ch == "\<c-c>"
|
||||
break
|
||||
elseif ch == "\<LeftMouse>"
|
||||
if s:neovim_click() != 0
|
||||
break
|
||||
endif
|
||||
elseif has_key(s:cmenu.hotkey, ch)
|
||||
let index = s:cmenu.hotkey[ch]
|
||||
let index = (index < 0)? (s:cmenu.size - 1) : index
|
||||
let index = (index >= s:cmenu.size)? 0 : index
|
||||
let s:cmenu.index = (s:cmenu.size == 0)? 0 : index
|
||||
call quickui#menu#update()
|
||||
if s:neovim_dropdown() != 0
|
||||
break
|
||||
endif
|
||||
elseif has_key(keymap, ch)
|
||||
let key = keymap[ch]
|
||||
if s:movement(key) != 0
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
call nvim_win_close(winid, 0)
|
||||
redraw
|
||||
echo ""
|
||||
redraw
|
||||
let s:namespace[name].index = s:cmenu.index
|
||||
if s:cmenu.script != ''
|
||||
let script = s:cmenu.script
|
||||
exec script
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" testing suit
|
||||
"----------------------------------------------------------------------
|
||||
if 0
|
||||
call quickui#menu#switch('test')
|
||||
call quickui#menu#reset()
|
||||
call quickui#menu#install('H&elp', [
|
||||
\ [ '&Content', 'echo 4' ],
|
||||
\ [ '&About', 'echo 5' ],
|
||||
\ ])
|
||||
call quickui#menu#install('&File', [
|
||||
\ [ "&New File\tCtrl+n", '' ],
|
||||
\ [ "&Open File\t(F3)", 'echo 1' ],
|
||||
\ [ "&Close", 'echo 3' ],
|
||||
\ [ "--", '' ],
|
||||
\ [ "&Save\tCtrl+s", ''],
|
||||
\ [ "Save &As", '' ],
|
||||
\ [ "Save All", '' ],
|
||||
\ [ "--", '' ],
|
||||
\ [ "E&xit\tAlt+x", '' ],
|
||||
\ ])
|
||||
call quickui#menu#install('&Edit', [
|
||||
\ [ '&Copy', 'echo 1', 'help1' ],
|
||||
\ [ '&Paste', 'echo 2', 'help2' ],
|
||||
\ [ '&Find', 'echo 3', 'help3' ],
|
||||
\ ])
|
||||
call quickui#menu#install('&Tools', [
|
||||
\ [ '&Copy', 'echo 1', 'help1' ],
|
||||
\ [ '&Paste', 'echo 2', 'help2' ],
|
||||
\ [ '&Find', 'echo 3', 'help3' ],
|
||||
\ ])
|
||||
|
||||
call quickui#menu#install('&Window', [])
|
||||
call quickui#menu#change_weight('H&elp', 1000)
|
||||
call quickui#menu#switch('system')
|
||||
call quickui#menu#open('test')
|
||||
endif
|
||||
|
||||
|
||||
|
719
vim/.vim/autoload/quickui/palette.vim
Normal file
719
vim/.vim/autoload/quickui/palette.vim
Normal file
@ -0,0 +1,719 @@
|
||||
"======================================================================
|
||||
"
|
||||
" palette.vim -
|
||||
"
|
||||
" Created by skywind on 2021/12/23
|
||||
" Last Modified: 2022/09/25 01:31
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set ts=4 sw=4 tw=78 noet :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" terminal palette of 256 colors
|
||||
"----------------------------------------------------------------------
|
||||
let g:quickui#palette#colors = [
|
||||
\ { 'color': 0, 'name': 'Black', 'hex': '#000000' },
|
||||
\ { 'color': 1, 'name': 'Maroon', 'hex': '#800000' },
|
||||
\ { 'color': 2, 'name': 'Green', 'hex': '#008000' },
|
||||
\ { 'color': 3, 'name': 'Olive', 'hex': '#808000' },
|
||||
\ { 'color': 4, 'name': 'Navy', 'hex': '#000080' },
|
||||
\ { 'color': 5, 'name': 'Purple', 'hex': '#800080' },
|
||||
\ { 'color': 6, 'name': 'Teal', 'hex': '#008080' },
|
||||
\ { 'color': 7, 'name': 'Silver', 'hex': '#c0c0c0' },
|
||||
\ { 'color': 8, 'name': 'Grey', 'hex': '#808080' },
|
||||
\ { 'color': 9, 'name': 'Red', 'hex': '#ff0000' },
|
||||
\ { 'color': 10, 'name': 'Lime', 'hex': '#00ff00' },
|
||||
\ { 'color': 11, 'name': 'Yellow', 'hex': '#ffff00' },
|
||||
\ { 'color': 12, 'name': 'Blue', 'hex': '#0000ff' },
|
||||
\ { 'color': 13, 'name': 'Fuchsia', 'hex': '#ff00ff' },
|
||||
\ { 'color': 14, 'name': 'Aqua', 'hex': '#00ffff' },
|
||||
\ { 'color': 15, 'name': 'White', 'hex': '#ffffff' },
|
||||
\ { 'color': 16, 'name': 'Grey0', 'hex': '#000000' },
|
||||
\ { 'color': 17, 'name': 'NavyBlue', 'hex': '#00005f' },
|
||||
\ { 'color': 18, 'name': 'DarkBlue', 'hex': '#000087' },
|
||||
\ { 'color': 19, 'name': 'Blue3', 'hex': '#0000af' },
|
||||
\ { 'color': 20, 'name': 'Blue3', 'hex': '#0000d7' },
|
||||
\ { 'color': 21, 'name': 'Blue1', 'hex': '#0000ff' },
|
||||
\ { 'color': 22, 'name': 'DarkGreen', 'hex': '#005f00' },
|
||||
\ { 'color': 23, 'name': 'DeepSkyBlue4', 'hex': '#005f5f' },
|
||||
\ { 'color': 24, 'name': 'DeepSkyBlue4', 'hex': '#005f87' },
|
||||
\ { 'color': 25, 'name': 'DeepSkyBlue4', 'hex': '#005faf' },
|
||||
\ { 'color': 26, 'name': 'DodgerBlue3', 'hex': '#005fd7' },
|
||||
\ { 'color': 27, 'name': 'DodgerBlue2', 'hex': '#005fff' },
|
||||
\ { 'color': 28, 'name': 'Green4', 'hex': '#008700' },
|
||||
\ { 'color': 29, 'name': 'SpringGreen4', 'hex': '#00875f' },
|
||||
\ { 'color': 30, 'name': 'Turquoise4', 'hex': '#008787' },
|
||||
\ { 'color': 31, 'name': 'DeepSkyBlue3', 'hex': '#0087af' },
|
||||
\ { 'color': 32, 'name': 'DeepSkyBlue3', 'hex': '#0087d7' },
|
||||
\ { 'color': 33, 'name': 'DodgerBlue1', 'hex': '#0087ff' },
|
||||
\ { 'color': 34, 'name': 'Green3', 'hex': '#00af00' },
|
||||
\ { 'color': 35, 'name': 'SpringGreen3', 'hex': '#00af5f' },
|
||||
\ { 'color': 36, 'name': 'DarkCyan', 'hex': '#00af87' },
|
||||
\ { 'color': 37, 'name': 'LightSeaGreen', 'hex': '#00afaf' },
|
||||
\ { 'color': 38, 'name': 'DeepSkyBlue2', 'hex': '#00afd7' },
|
||||
\ { 'color': 39, 'name': 'DeepSkyBlue1', 'hex': '#00afff' },
|
||||
\ { 'color': 40, 'name': 'Green3', 'hex': '#00d700' },
|
||||
\ { 'color': 41, 'name': 'SpringGreen3', 'hex': '#00d75f' },
|
||||
\ { 'color': 42, 'name': 'SpringGreen2', 'hex': '#00d787' },
|
||||
\ { 'color': 43, 'name': 'Cyan3', 'hex': '#00d7af' },
|
||||
\ { 'color': 44, 'name': 'DarkTurquoise', 'hex': '#00d7d7' },
|
||||
\ { 'color': 45, 'name': 'Turquoise2', 'hex': '#00d7ff' },
|
||||
\ { 'color': 46, 'name': 'Green1', 'hex': '#00ff00' },
|
||||
\ { 'color': 47, 'name': 'SpringGreen2', 'hex': '#00ff5f' },
|
||||
\ { 'color': 48, 'name': 'SpringGreen1', 'hex': '#00ff87' },
|
||||
\ { 'color': 49, 'name': 'MediumSpringGreen', 'hex': '#00ffaf' },
|
||||
\ { 'color': 50, 'name': 'Cyan2', 'hex': '#00ffd7' },
|
||||
\ { 'color': 51, 'name': 'Cyan1', 'hex': '#00ffff' },
|
||||
\ { 'color': 52, 'name': 'DarkRed', 'hex': '#5f0000' },
|
||||
\ { 'color': 53, 'name': 'DeepPink4', 'hex': '#5f005f' },
|
||||
\ { 'color': 54, 'name': 'Purple4', 'hex': '#5f0087' },
|
||||
\ { 'color': 55, 'name': 'Purple4', 'hex': '#5f00af' },
|
||||
\ { 'color': 56, 'name': 'Purple3', 'hex': '#5f00d7' },
|
||||
\ { 'color': 57, 'name': 'BlueViolet', 'hex': '#5f00ff' },
|
||||
\ { 'color': 58, 'name': 'Orange4', 'hex': '#5f5f00' },
|
||||
\ { 'color': 59, 'name': 'Grey37', 'hex': '#5f5f5f' },
|
||||
\ { 'color': 60, 'name': 'MediumPurple4', 'hex': '#5f5f87' },
|
||||
\ { 'color': 61, 'name': 'SlateBlue3', 'hex': '#5f5faf' },
|
||||
\ { 'color': 62, 'name': 'SlateBlue3', 'hex': '#5f5fd7' },
|
||||
\ { 'color': 63, 'name': 'RoyalBlue1', 'hex': '#5f5fff' },
|
||||
\ { 'color': 64, 'name': 'Chartreuse4', 'hex': '#5f8700' },
|
||||
\ { 'color': 65, 'name': 'DarkSeaGreen4', 'hex': '#5f875f' },
|
||||
\ { 'color': 66, 'name': 'PaleTurquoise4', 'hex': '#5f8787' },
|
||||
\ { 'color': 67, 'name': 'SteelBlue', 'hex': '#5f87af' },
|
||||
\ { 'color': 68, 'name': 'SteelBlue3', 'hex': '#5f87d7' },
|
||||
\ { 'color': 69, 'name': 'CornflowerBlue', 'hex': '#5f87ff' },
|
||||
\ { 'color': 70, 'name': 'Chartreuse3', 'hex': '#5faf00' },
|
||||
\ { 'color': 71, 'name': 'DarkSeaGreen4', 'hex': '#5faf5f' },
|
||||
\ { 'color': 72, 'name': 'CadetBlue', 'hex': '#5faf87' },
|
||||
\ { 'color': 73, 'name': 'CadetBlue', 'hex': '#5fafaf' },
|
||||
\ { 'color': 74, 'name': 'SkyBlue3', 'hex': '#5fafd7' },
|
||||
\ { 'color': 75, 'name': 'SteelBlue1', 'hex': '#5fafff' },
|
||||
\ { 'color': 76, 'name': 'Chartreuse3', 'hex': '#5fd700' },
|
||||
\ { 'color': 77, 'name': 'PaleGreen3', 'hex': '#5fd75f' },
|
||||
\ { 'color': 78, 'name': 'SeaGreen3', 'hex': '#5fd787' },
|
||||
\ { 'color': 79, 'name': 'Aquamarine3', 'hex': '#5fd7af' },
|
||||
\ { 'color': 80, 'name': 'MediumTurquoise', 'hex': '#5fd7d7' },
|
||||
\ { 'color': 81, 'name': 'SteelBlue1', 'hex': '#5fd7ff' },
|
||||
\ { 'color': 82, 'name': 'Chartreuse2', 'hex': '#5fff00' },
|
||||
\ { 'color': 83, 'name': 'SeaGreen2', 'hex': '#5fff5f' },
|
||||
\ { 'color': 84, 'name': 'SeaGreen1', 'hex': '#5fff87' },
|
||||
\ { 'color': 85, 'name': 'SeaGreen1', 'hex': '#5fffaf' },
|
||||
\ { 'color': 86, 'name': 'Aquamarine1', 'hex': '#5fffd7' },
|
||||
\ { 'color': 87, 'name': 'DarkSlateGray2', 'hex': '#5fffff' },
|
||||
\ { 'color': 88, 'name': 'DarkRed', 'hex': '#870000' },
|
||||
\ { 'color': 89, 'name': 'DeepPink4', 'hex': '#87005f' },
|
||||
\ { 'color': 90, 'name': 'DarkMagenta', 'hex': '#870087' },
|
||||
\ { 'color': 91, 'name': 'DarkMagenta', 'hex': '#8700af' },
|
||||
\ { 'color': 92, 'name': 'DarkViolet', 'hex': '#8700d7' },
|
||||
\ { 'color': 93, 'name': 'Purple', 'hex': '#8700ff' },
|
||||
\ { 'color': 94, 'name': 'Orange4', 'hex': '#875f00' },
|
||||
\ { 'color': 95, 'name': 'LightPink4', 'hex': '#875f5f' },
|
||||
\ { 'color': 96, 'name': 'Plum4', 'hex': '#875f87' },
|
||||
\ { 'color': 97, 'name': 'MediumPurple3', 'hex': '#875faf' },
|
||||
\ { 'color': 98, 'name': 'MediumPurple3', 'hex': '#875fd7' },
|
||||
\ { 'color': 99, 'name': 'SlateBlue1', 'hex': '#875fff' },
|
||||
\ { 'color': 100, 'name': 'Yellow4', 'hex': '#878700' },
|
||||
\ { 'color': 101, 'name': 'Wheat4', 'hex': '#87875f' },
|
||||
\ { 'color': 102, 'name': 'Grey53', 'hex': '#878787' },
|
||||
\ { 'color': 103, 'name': 'LightSlateGrey', 'hex': '#8787af' },
|
||||
\ { 'color': 104, 'name': 'MediumPurple', 'hex': '#8787d7' },
|
||||
\ { 'color': 105, 'name': 'LightSlateBlue', 'hex': '#8787ff' },
|
||||
\ { 'color': 106, 'name': 'Yellow4', 'hex': '#87af00' },
|
||||
\ { 'color': 107, 'name': 'DarkOliveGreen3', 'hex': '#87af5f' },
|
||||
\ { 'color': 108, 'name': 'DarkSeaGreen', 'hex': '#87af87' },
|
||||
\ { 'color': 109, 'name': 'LightSkyBlue3', 'hex': '#87afaf' },
|
||||
\ { 'color': 110, 'name': 'LightSkyBlue3', 'hex': '#87afd7' },
|
||||
\ { 'color': 111, 'name': 'SkyBlue2', 'hex': '#87afff' },
|
||||
\ { 'color': 112, 'name': 'Chartreuse2', 'hex': '#87d700' },
|
||||
\ { 'color': 113, 'name': 'DarkOliveGreen3', 'hex': '#87d75f' },
|
||||
\ { 'color': 114, 'name': 'PaleGreen3', 'hex': '#87d787' },
|
||||
\ { 'color': 115, 'name': 'DarkSeaGreen3', 'hex': '#87d7af' },
|
||||
\ { 'color': 116, 'name': 'DarkSlateGray3', 'hex': '#87d7d7' },
|
||||
\ { 'color': 117, 'name': 'SkyBlue1', 'hex': '#87d7ff' },
|
||||
\ { 'color': 118, 'name': 'Chartreuse1', 'hex': '#87ff00' },
|
||||
\ { 'color': 119, 'name': 'LightGreen', 'hex': '#87ff5f' },
|
||||
\ { 'color': 120, 'name': 'LightGreen', 'hex': '#87ff87' },
|
||||
\ { 'color': 121, 'name': 'PaleGreen1', 'hex': '#87ffaf' },
|
||||
\ { 'color': 122, 'name': 'Aquamarine1', 'hex': '#87ffd7' },
|
||||
\ { 'color': 123, 'name': 'DarkSlateGray1', 'hex': '#87ffff' },
|
||||
\ { 'color': 124, 'name': 'Red3', 'hex': '#af0000' },
|
||||
\ { 'color': 125, 'name': 'DeepPink4', 'hex': '#af005f' },
|
||||
\ { 'color': 126, 'name': 'MediumVioletRed', 'hex': '#af0087' },
|
||||
\ { 'color': 127, 'name': 'Magenta3', 'hex': '#af00af' },
|
||||
\ { 'color': 128, 'name': 'DarkViolet', 'hex': '#af00d7' },
|
||||
\ { 'color': 129, 'name': 'Purple', 'hex': '#af00ff' },
|
||||
\ { 'color': 130, 'name': 'DarkOrange3', 'hex': '#af5f00' },
|
||||
\ { 'color': 131, 'name': 'IndianRed', 'hex': '#af5f5f' },
|
||||
\ { 'color': 132, 'name': 'HotPink3', 'hex': '#af5f87' },
|
||||
\ { 'color': 133, 'name': 'MediumOrchid3', 'hex': '#af5faf' },
|
||||
\ { 'color': 134, 'name': 'MediumOrchid', 'hex': '#af5fd7' },
|
||||
\ { 'color': 135, 'name': 'MediumPurple2', 'hex': '#af5fff' },
|
||||
\ { 'color': 136, 'name': 'DarkGoldenrod', 'hex': '#af8700' },
|
||||
\ { 'color': 137, 'name': 'LightSalmon3', 'hex': '#af875f' },
|
||||
\ { 'color': 138, 'name': 'RosyBrown', 'hex': '#af8787' },
|
||||
\ { 'color': 139, 'name': 'Grey63', 'hex': '#af87af' },
|
||||
\ { 'color': 140, 'name': 'MediumPurple2', 'hex': '#af87d7' },
|
||||
\ { 'color': 141, 'name': 'MediumPurple1', 'hex': '#af87ff' },
|
||||
\ { 'color': 142, 'name': 'Gold3', 'hex': '#afaf00' },
|
||||
\ { 'color': 143, 'name': 'DarkKhaki', 'hex': '#afaf5f' },
|
||||
\ { 'color': 144, 'name': 'NavajoWhite3', 'hex': '#afaf87' },
|
||||
\ { 'color': 145, 'name': 'Grey69', 'hex': '#afafaf' },
|
||||
\ { 'color': 146, 'name': 'LightSteelBlue3', 'hex': '#afafd7' },
|
||||
\ { 'color': 147, 'name': 'LightSteelBlue', 'hex': '#afafff' },
|
||||
\ { 'color': 148, 'name': 'Yellow3', 'hex': '#afd700' },
|
||||
\ { 'color': 149, 'name': 'DarkOliveGreen3', 'hex': '#afd75f' },
|
||||
\ { 'color': 150, 'name': 'DarkSeaGreen3', 'hex': '#afd787' },
|
||||
\ { 'color': 151, 'name': 'DarkSeaGreen2', 'hex': '#afd7af' },
|
||||
\ { 'color': 152, 'name': 'LightCyan3', 'hex': '#afd7d7' },
|
||||
\ { 'color': 153, 'name': 'LightSkyBlue1', 'hex': '#afd7ff' },
|
||||
\ { 'color': 154, 'name': 'GreenYellow', 'hex': '#afff00' },
|
||||
\ { 'color': 155, 'name': 'DarkOliveGreen2', 'hex': '#afff5f' },
|
||||
\ { 'color': 156, 'name': 'PaleGreen1', 'hex': '#afff87' },
|
||||
\ { 'color': 157, 'name': 'DarkSeaGreen2', 'hex': '#afffaf' },
|
||||
\ { 'color': 158, 'name': 'DarkSeaGreen1', 'hex': '#afffd7' },
|
||||
\ { 'color': 159, 'name': 'PaleTurquoise1', 'hex': '#afffff' },
|
||||
\ { 'color': 160, 'name': 'Red3', 'hex': '#d70000' },
|
||||
\ { 'color': 161, 'name': 'DeepPink3', 'hex': '#d7005f' },
|
||||
\ { 'color': 162, 'name': 'DeepPink3', 'hex': '#d70087' },
|
||||
\ { 'color': 163, 'name': 'Magenta3', 'hex': '#d700af' },
|
||||
\ { 'color': 164, 'name': 'Magenta3', 'hex': '#d700d7' },
|
||||
\ { 'color': 165, 'name': 'Magenta2', 'hex': '#d700ff' },
|
||||
\ { 'color': 166, 'name': 'DarkOrange3', 'hex': '#d75f00' },
|
||||
\ { 'color': 167, 'name': 'IndianRed', 'hex': '#d75f5f' },
|
||||
\ { 'color': 168, 'name': 'HotPink3', 'hex': '#d75f87' },
|
||||
\ { 'color': 169, 'name': 'HotPink2', 'hex': '#d75faf' },
|
||||
\ { 'color': 170, 'name': 'Orchid', 'hex': '#d75fd7' },
|
||||
\ { 'color': 171, 'name': 'MediumOrchid1', 'hex': '#d75fff' },
|
||||
\ { 'color': 172, 'name': 'Orange3', 'hex': '#d78700' },
|
||||
\ { 'color': 173, 'name': 'LightSalmon3', 'hex': '#d7875f' },
|
||||
\ { 'color': 174, 'name': 'LightPink3', 'hex': '#d78787' },
|
||||
\ { 'color': 175, 'name': 'Pink3', 'hex': '#d787af' },
|
||||
\ { 'color': 176, 'name': 'Plum3', 'hex': '#d787d7' },
|
||||
\ { 'color': 177, 'name': 'Violet', 'hex': '#d787ff' },
|
||||
\ { 'color': 178, 'name': 'Gold3', 'hex': '#d7af00' },
|
||||
\ { 'color': 179, 'name': 'LightGoldenrod3', 'hex': '#d7af5f' },
|
||||
\ { 'color': 180, 'name': 'Tan', 'hex': '#d7af87' },
|
||||
\ { 'color': 181, 'name': 'MistyRose3', 'hex': '#d7afaf' },
|
||||
\ { 'color': 182, 'name': 'Thistle3', 'hex': '#d7afd7' },
|
||||
\ { 'color': 183, 'name': 'Plum2', 'hex': '#d7afff' },
|
||||
\ { 'color': 184, 'name': 'Yellow3', 'hex': '#d7d700' },
|
||||
\ { 'color': 185, 'name': 'Khaki3', 'hex': '#d7d75f' },
|
||||
\ { 'color': 186, 'name': 'LightGoldenrod2', 'hex': '#d7d787' },
|
||||
\ { 'color': 187, 'name': 'LightYellow3', 'hex': '#d7d7af' },
|
||||
\ { 'color': 188, 'name': 'Grey84', 'hex': '#d7d7d7' },
|
||||
\ { 'color': 189, 'name': 'LightSteelBlue1', 'hex': '#d7d7ff' },
|
||||
\ { 'color': 190, 'name': 'Yellow2', 'hex': '#d7ff00' },
|
||||
\ { 'color': 191, 'name': 'DarkOliveGreen1', 'hex': '#d7ff5f' },
|
||||
\ { 'color': 192, 'name': 'DarkOliveGreen1', 'hex': '#d7ff87' },
|
||||
\ { 'color': 193, 'name': 'DarkSeaGreen1', 'hex': '#d7ffaf' },
|
||||
\ { 'color': 194, 'name': 'Honeydew2', 'hex': '#d7ffd7' },
|
||||
\ { 'color': 195, 'name': 'LightCyan1', 'hex': '#d7ffff' },
|
||||
\ { 'color': 196, 'name': 'Red1', 'hex': '#ff0000' },
|
||||
\ { 'color': 197, 'name': 'DeepPink2', 'hex': '#ff005f' },
|
||||
\ { 'color': 198, 'name': 'DeepPink1', 'hex': '#ff0087' },
|
||||
\ { 'color': 199, 'name': 'DeepPink1', 'hex': '#ff00af' },
|
||||
\ { 'color': 200, 'name': 'Magenta2', 'hex': '#ff00d7' },
|
||||
\ { 'color': 201, 'name': 'Magenta1', 'hex': '#ff00ff' },
|
||||
\ { 'color': 202, 'name': 'OrangeRed1', 'hex': '#ff5f00' },
|
||||
\ { 'color': 203, 'name': 'IndianRed1', 'hex': '#ff5f5f' },
|
||||
\ { 'color': 204, 'name': 'IndianRed1', 'hex': '#ff5f87' },
|
||||
\ { 'color': 205, 'name': 'HotPink', 'hex': '#ff5faf' },
|
||||
\ { 'color': 206, 'name': 'HotPink', 'hex': '#ff5fd7' },
|
||||
\ { 'color': 207, 'name': 'MediumOrchid1', 'hex': '#ff5fff' },
|
||||
\ { 'color': 208, 'name': 'DarkOrange', 'hex': '#ff8700' },
|
||||
\ { 'color': 209, 'name': 'Salmon1', 'hex': '#ff875f' },
|
||||
\ { 'color': 210, 'name': 'LightCoral', 'hex': '#ff8787' },
|
||||
\ { 'color': 211, 'name': 'PaleVioletRed1', 'hex': '#ff87af' },
|
||||
\ { 'color': 212, 'name': 'Orchid2', 'hex': '#ff87d7' },
|
||||
\ { 'color': 213, 'name': 'Orchid1', 'hex': '#ff87ff' },
|
||||
\ { 'color': 214, 'name': 'Orange1', 'hex': '#ffaf00' },
|
||||
\ { 'color': 215, 'name': 'SandyBrown', 'hex': '#ffaf5f' },
|
||||
\ { 'color': 216, 'name': 'LightSalmon1', 'hex': '#ffaf87' },
|
||||
\ { 'color': 217, 'name': 'LightPink1', 'hex': '#ffafaf' },
|
||||
\ { 'color': 218, 'name': 'Pink1', 'hex': '#ffafd7' },
|
||||
\ { 'color': 219, 'name': 'Plum1', 'hex': '#ffafff' },
|
||||
\ { 'color': 220, 'name': 'Gold1', 'hex': '#ffd700' },
|
||||
\ { 'color': 221, 'name': 'LightGoldenrod2', 'hex': '#ffd75f' },
|
||||
\ { 'color': 222, 'name': 'LightGoldenrod2', 'hex': '#ffd787' },
|
||||
\ { 'color': 223, 'name': 'NavajoWhite1', 'hex': '#ffd7af' },
|
||||
\ { 'color': 224, 'name': 'MistyRose1', 'hex': '#ffd7d7' },
|
||||
\ { 'color': 225, 'name': 'Thistle1', 'hex': '#ffd7ff' },
|
||||
\ { 'color': 226, 'name': 'Yellow1', 'hex': '#ffff00' },
|
||||
\ { 'color': 227, 'name': 'LightGoldenrod1', 'hex': '#ffff5f' },
|
||||
\ { 'color': 228, 'name': 'Khaki1', 'hex': '#ffff87' },
|
||||
\ { 'color': 229, 'name': 'Wheat1', 'hex': '#ffffaf' },
|
||||
\ { 'color': 230, 'name': 'Cornsilk1', 'hex': '#ffffd7' },
|
||||
\ { 'color': 231, 'name': 'Grey100', 'hex': '#ffffff' },
|
||||
\ { 'color': 232, 'name': 'Grey3', 'hex': '#080808' },
|
||||
\ { 'color': 233, 'name': 'Grey7', 'hex': '#121212' },
|
||||
\ { 'color': 234, 'name': 'Grey11', 'hex': '#1c1c1c' },
|
||||
\ { 'color': 235, 'name': 'Grey15', 'hex': '#262626' },
|
||||
\ { 'color': 236, 'name': 'Grey19', 'hex': '#303030' },
|
||||
\ { 'color': 237, 'name': 'Grey23', 'hex': '#3a3a3a' },
|
||||
\ { 'color': 238, 'name': 'Grey27', 'hex': '#444444' },
|
||||
\ { 'color': 239, 'name': 'Grey30', 'hex': '#4e4e4e' },
|
||||
\ { 'color': 240, 'name': 'Grey35', 'hex': '#585858' },
|
||||
\ { 'color': 241, 'name': 'Grey39', 'hex': '#626262' },
|
||||
\ { 'color': 242, 'name': 'Grey42', 'hex': '#6c6c6c' },
|
||||
\ { 'color': 243, 'name': 'Grey46', 'hex': '#767676' },
|
||||
\ { 'color': 244, 'name': 'Grey50', 'hex': '#808080' },
|
||||
\ { 'color': 245, 'name': 'Grey54', 'hex': '#8a8a8a' },
|
||||
\ { 'color': 246, 'name': 'Grey58', 'hex': '#949494' },
|
||||
\ { 'color': 247, 'name': 'Grey62', 'hex': '#9e9e9e' },
|
||||
\ { 'color': 248, 'name': 'Grey66', 'hex': '#a8a8a8' },
|
||||
\ { 'color': 249, 'name': 'Grey70', 'hex': '#b2b2b2' },
|
||||
\ { 'color': 250, 'name': 'Grey74', 'hex': '#bcbcbc' },
|
||||
\ { 'color': 251, 'name': 'Grey78', 'hex': '#c6c6c6' },
|
||||
\ { 'color': 252, 'name': 'Grey82', 'hex': '#d0d0d0' },
|
||||
\ { 'color': 253, 'name': 'Grey85', 'hex': '#dadada' },
|
||||
\ { 'color': 254, 'name': 'Grey89', 'hex': '#e4e4e4' },
|
||||
\ { 'color': 255, 'name': 'Grey93', 'hex': '#eeeeee' },
|
||||
\ ]
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" color index to RGB
|
||||
"----------------------------------------------------------------------
|
||||
let g:quickui#palette#rgb = []
|
||||
let g:quickui#palette#name = {}
|
||||
let g:quickui#palette#number = get(g:, 'quickui_color_num', 256)
|
||||
|
||||
let s:palette = []
|
||||
let s:matched = {}
|
||||
let s:names = {}
|
||||
let s:diff_lookup = repeat([0], 512 * 3)
|
||||
|
||||
for color in g:quickui#palette#colors
|
||||
let cc = str2nr(strpart(color.hex, 1), 16)
|
||||
let r = and(cc / 0x10000, 0xff)
|
||||
let g = and(cc / 0x100, 0xff)
|
||||
let b = and(cc, 0xff)
|
||||
let g:quickui#palette#rgb += [[r, g, b]]
|
||||
let s:palette += [[r, g, b]]
|
||||
let g:quickui#palette#name[tolower(color.name)] = color.color
|
||||
let s:names[tolower(color.name)] = color.color
|
||||
endfor
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" bestfit color
|
||||
"----------------------------------------------------------------------
|
||||
function! s:bestfit_color(r, g, b, limit)
|
||||
if s:diff_lookup[0] == 0
|
||||
for i in range(256)
|
||||
let k = i * i
|
||||
let dr = k * 30 * 30
|
||||
let dg = k * 59 * 59
|
||||
let db = k * 11 * 11
|
||||
let s:diff_lookup[ 256 + i] = dr
|
||||
let s:diff_lookup[ 256 - i] = dr
|
||||
let s:diff_lookup[ 768 + i] = dg
|
||||
let s:diff_lookup[ 768 - i] = dg
|
||||
let s:diff_lookup[1280 + i] = db
|
||||
let s:diff_lookup[1280 - i] = db
|
||||
endfor
|
||||
let s:diff_lookup[0] = 1
|
||||
endif
|
||||
let r = (a:r < 256)? (a:r) : 255
|
||||
let g = (a:g < 256)? (a:g) : 255
|
||||
let b = (a:b < 256)? (a:b) : 255
|
||||
let lowest = 0x7fffffff
|
||||
let bestfit = 0
|
||||
let index = 0
|
||||
let limit = (a:limit < 256)? (a:limit) : 256
|
||||
let palette = s:palette
|
||||
let lookup = s:diff_lookup
|
||||
while index < limit
|
||||
let rgb = palette[index]
|
||||
let diff = lookup[ 768 + rgb[1] - g]
|
||||
if diff < lowest
|
||||
let diff += lookup[ 256 + rgb[0] - r]
|
||||
if diff < lowest
|
||||
let diff += lookup[1280 + rgb[2] - b]
|
||||
if diff < lowest
|
||||
let lowest = diff
|
||||
let bestfit = index
|
||||
endif
|
||||
if diff <= 0
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let index += 1
|
||||
endwhile
|
||||
return bestfit
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" find match in 8 colors
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#palette#bestfit8(r, g, b)
|
||||
return s:bestfit_color(a:r, a:g, a:b, 8)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" find match in 8 colors
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#palette#bestfit16(r, g, b)
|
||||
return s:bestfit_color(a:r, a:g, a:b, 16)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" find match in 8 colors
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#palette#bestfit256(r, g, b)
|
||||
return s:bestfit_color(a:r, a:g, a:b, 256)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" consider config
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#palette#bestfit(r, g, b)
|
||||
return s:bestfit_color(a:r, a:g, a:b, g:quickui#palette#number)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" matched
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#palette#match(r, g, b)
|
||||
let r = (a:r < 256)? (a:r) : 255
|
||||
let g = (a:g < 256)? (a:g) : 255
|
||||
let b = (a:b < 256)? (a:b) : 255
|
||||
let key = (r * 4096 / 4) + (g * 64 / 4) + (b / 4)
|
||||
if !has_key(s:matched, key)
|
||||
let n = g:quickui#palette#number
|
||||
let s:matched[key] = s:bestfit_color(a:r, a:g, a:b, n)
|
||||
endif
|
||||
return s:matched[key]
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" convert #112233 to [0x11, 0x22, 0x33]
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#palette#hex2rgb(hex)
|
||||
let [r, g, b] = [0, 0, 0]
|
||||
let head = strpart(a:hex, 0, 1)
|
||||
if head == '#'
|
||||
let cc = str2nr(strpart(a:hex, 1), 16)
|
||||
let r = and(cc / 0x10000, 0xff)
|
||||
let g = and(cc / 0x100, 0xff)
|
||||
let b = and(cc, 0xff)
|
||||
elseif head == '('
|
||||
let head = strpart(a:hex, 1, len(a:hex) - 2)
|
||||
let part = split(head, ',')
|
||||
let r = str2nr(part[0])
|
||||
let g = str2nr(part[1])
|
||||
let b = str2nr(part[2])
|
||||
endif
|
||||
return [r, g, b]
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" hex to palette index
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#palette#hex2index(hex)
|
||||
let [r, g, b] = quickui#palette#hex2rgb(a:hex)
|
||||
return quickui#palette#match(r, g, b)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" search name
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#palette#name2index(name, ...)
|
||||
let head = strpart(a:name, 0, 1)
|
||||
if head == '#' || head == '('
|
||||
return quickui#palette#hex2index(a:name)
|
||||
else
|
||||
let default = (a:0 < 1)? 0 : (a:1)
|
||||
let name = tolower(a:name)
|
||||
if exists('v:colornames')
|
||||
if has_key(v:colornames, name)
|
||||
let hex = v:colornames[name]
|
||||
return quickui#palette#hex2index(hex)
|
||||
endif
|
||||
endif
|
||||
return get(s:names, tolower(a:name), default)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" alpha blend
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#palette#blend(c1, c2, alpha)
|
||||
let c1 = a:c1
|
||||
let c2 = a:c2
|
||||
let alpha = a:alpha
|
||||
if type(c1) == 0 && type(c2) == 0
|
||||
return (c1 * (255 - alpha) + c2 * alpha) / 255
|
||||
endif
|
||||
let dst = quickui#palette#hex2rgb(c1)
|
||||
let src = quickui#palette#hex2rgb(c2)
|
||||
let r = (dst[0] * (255 - alpha) + src[0] * alpha) / 255
|
||||
let g = (dst[1] * (255 - alpha) + src[1] * alpha) / 255
|
||||
let b = (dst[2] * (255 - alpha) + src[2] * alpha) / 255
|
||||
return printf('#%02x%02x%02x', r, g, b)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" palette search in desert256
|
||||
"----------------------------------------------------------------------
|
||||
|
||||
" returns an approximate grey index for the given grey level
|
||||
function! s:grey_number(x)
|
||||
if &t_Co == 88
|
||||
if a:x < 23
|
||||
return 0
|
||||
elseif a:x < 69
|
||||
return 1
|
||||
elseif a:x < 103
|
||||
return 2
|
||||
elseif a:x < 127
|
||||
return 3
|
||||
elseif a:x < 150
|
||||
return 4
|
||||
elseif a:x < 173
|
||||
return 5
|
||||
elseif a:x < 196
|
||||
return 6
|
||||
elseif a:x < 219
|
||||
return 7
|
||||
elseif a:x < 243
|
||||
return 8
|
||||
else
|
||||
return 9
|
||||
endif
|
||||
else
|
||||
if a:x < 14
|
||||
return 0
|
||||
else
|
||||
let l:n = (a:x - 8) / 10
|
||||
let l:m = (a:x - 8) % 10
|
||||
if l:m < 5
|
||||
return l:n
|
||||
else
|
||||
return l:n + 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" returns the actual grey level represented by the grey index
|
||||
function! s:grey_level(n)
|
||||
if &t_Co == 88
|
||||
if a:n == 0
|
||||
return 0
|
||||
elseif a:n == 1
|
||||
return 46
|
||||
elseif a:n == 2
|
||||
return 92
|
||||
elseif a:n == 3
|
||||
return 115
|
||||
elseif a:n == 4
|
||||
return 139
|
||||
elseif a:n == 5
|
||||
return 162
|
||||
elseif a:n == 6
|
||||
return 185
|
||||
elseif a:n == 7
|
||||
return 208
|
||||
elseif a:n == 8
|
||||
return 231
|
||||
else
|
||||
return 255
|
||||
endif
|
||||
else
|
||||
if a:n == 0
|
||||
return 0
|
||||
else
|
||||
return 8 + (a:n * 10)
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" returns the palette index for the given grey index
|
||||
function! s:grey_color(n)
|
||||
if &t_Co == 88
|
||||
if a:n == 0
|
||||
return 16
|
||||
elseif a:n == 9
|
||||
return 79
|
||||
else
|
||||
return 79 + a:n
|
||||
endif
|
||||
else
|
||||
if a:n == 0
|
||||
return 16
|
||||
elseif a:n == 25
|
||||
return 231
|
||||
else
|
||||
return 231 + a:n
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" returns an approximate color index for the given color level
|
||||
function! s:rgb_number(x)
|
||||
if &t_Co == 88
|
||||
if a:x < 69
|
||||
return 0
|
||||
elseif a:x < 172
|
||||
return 1
|
||||
elseif a:x < 230
|
||||
return 2
|
||||
else
|
||||
return 3
|
||||
endif
|
||||
else
|
||||
if a:x < 75
|
||||
return 0
|
||||
else
|
||||
let l:n = (a:x - 55) / 40
|
||||
let l:m = (a:x - 55) % 40
|
||||
if l:m < 20
|
||||
return l:n
|
||||
else
|
||||
return l:n + 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" returns the actual color level for the given color index
|
||||
function! s:rgb_level(n)
|
||||
if &t_Co == 88
|
||||
if a:n == 0
|
||||
return 0
|
||||
elseif a:n == 1
|
||||
return 139
|
||||
elseif a:n == 2
|
||||
return 205
|
||||
else
|
||||
return 255
|
||||
endif
|
||||
else
|
||||
if a:n == 0
|
||||
return 0
|
||||
else
|
||||
return 55 + (a:n * 40)
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" returns the palette index for the given R/G/B color indices
|
||||
function! s:rgb_color(x, y, z)
|
||||
if &t_Co == 88
|
||||
return 16 + (a:x * 16) + (a:y * 4) + a:z
|
||||
else
|
||||
return 16 + (a:x * 36) + (a:y * 6) + a:z
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" returns the palette index to approximate the given R/G/B color levels
|
||||
function! quickui#palette#color_match(r, g, b)
|
||||
" get the closest grey
|
||||
let l:gx = s:grey_number(a:r)
|
||||
let l:gy = s:grey_number(a:g)
|
||||
let l:gz = s:grey_number(a:b)
|
||||
|
||||
" get the closest color
|
||||
let l:x = s:rgb_number(a:r)
|
||||
let l:y = s:rgb_number(a:g)
|
||||
let l:z = s:rgb_number(a:b)
|
||||
|
||||
if l:gx == l:gy && l:gy == l:gz
|
||||
" there are two possibilities
|
||||
let l:dgr = s:grey_level(l:gx) - a:r
|
||||
let l:dgg = s:grey_level(l:gy) - a:g
|
||||
let l:dgb = s:grey_level(l:gz) - a:b
|
||||
let l:dgrey = (l:dgr * l:dgr) + (l:dgg * l:dgg) + (l:dgb * l:dgb)
|
||||
let l:dr = s:rgb_level(l:gx) - a:r
|
||||
let l:dg = s:rgb_level(l:gy) - a:g
|
||||
let l:db = s:rgb_level(l:gz) - a:b
|
||||
let l:drgb = (l:dr * l:dr) + (l:dg * l:dg) + (l:db * l:db)
|
||||
if l:dgrey < l:drgb
|
||||
" use the grey
|
||||
return s:grey_color(l:gx)
|
||||
else
|
||||
" use the color
|
||||
return s:rgb_color(l:x, l:y, l:z)
|
||||
endif
|
||||
else
|
||||
" only one possibility
|
||||
return s:rgb_color(l:x, l:y, l:z)
|
||||
endif
|
||||
endfun
|
||||
|
||||
function! quickui#palette#rgb_match(rgb) abort
|
||||
if a:rgb =~ '^#'
|
||||
let r = ("0x" . strpart(a:rgb, 1, 2)) + 0
|
||||
let g = ("0x" . strpart(a:rgb, 3, 2)) + 0
|
||||
let b = ("0x" . strpart(a:rgb, 5, 2)) + 0
|
||||
else
|
||||
let r = ("0x" . strpart(a:rgb, 0, 2)) + 0
|
||||
let g = ("0x" . strpart(a:rgb, 2, 2)) + 0
|
||||
let b = ("0x" . strpart(a:rgb, 4, 2)) + 0
|
||||
endif
|
||||
return quickui#palette#color_match(r, g, b)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" benchmark
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#palette#timing()
|
||||
let ts = reltime()
|
||||
for i in range(256)
|
||||
call quickui#palette#match(i, i, i)
|
||||
endfor
|
||||
let tt = reltime(ts)
|
||||
return reltimestr(tt)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" optimize if possible: achieve 40x times faster
|
||||
"----------------------------------------------------------------------
|
||||
if has('vim9script')
|
||||
import './palette9.vim'
|
||||
function! s:bestfit_color(r, g, b, limit)
|
||||
return s:palette9.BestfitColor(a:r, a:g, a:b, a:limit)
|
||||
endfunc
|
||||
function! quickui#palette#bestfit8(r, g, b)
|
||||
return s:palette9.Bestfit8(a:r, a:g, a:b)
|
||||
endfunc
|
||||
function! quickui#palette#bestfit16(r, g, b)
|
||||
return s:palette9.Bestfit16(a:r, a:g, a:b)
|
||||
endfunc
|
||||
function! quickui#palette#bestfit256(r, g, b)
|
||||
return s:palette9.Bestfit256(a:r, a:g, a:b)
|
||||
endfunc
|
||||
function! quickui#palette#match(r, g, b)
|
||||
return s:palette9.Match(a:r, a:g, a:b, g:quickui#palette#number)
|
||||
endfunc
|
||||
function! quickui#palette#hex2rgb(hex)
|
||||
return s:palette9.Hex2RGB(a:hex)
|
||||
endfunc
|
||||
function! quickui#palette#hex2index(hex)
|
||||
return s:palette9.Hex2Index(a:hex)
|
||||
endfunc
|
||||
function! quickui#palette#name2index(name, ...)
|
||||
let default = (a:0 == 0)? 0 : (a:1)
|
||||
return s:palette9.Name2Index(a:name, default)
|
||||
endfunc
|
||||
endif
|
||||
|
||||
|
||||
|
||||
|
449
vim/.vim/autoload/quickui/palette9.vim
Normal file
449
vim/.vim/autoload/quickui/palette9.vim
Normal file
@ -0,0 +1,449 @@
|
||||
vim9script
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# terminal palette of 256 colors
|
||||
#----------------------------------------------------------------------
|
||||
final color_definition = [
|
||||
\ { 'color': 0, 'name': 'Black', 'hex': '#000000' },
|
||||
\ { 'color': 1, 'name': 'Maroon', 'hex': '#800000' },
|
||||
\ { 'color': 2, 'name': 'Green', 'hex': '#008000' },
|
||||
\ { 'color': 3, 'name': 'Olive', 'hex': '#808000' },
|
||||
\ { 'color': 4, 'name': 'Navy', 'hex': '#000080' },
|
||||
\ { 'color': 5, 'name': 'Purple', 'hex': '#800080' },
|
||||
\ { 'color': 6, 'name': 'Teal', 'hex': '#008080' },
|
||||
\ { 'color': 7, 'name': 'Silver', 'hex': '#c0c0c0' },
|
||||
\ { 'color': 8, 'name': 'Grey', 'hex': '#808080' },
|
||||
\ { 'color': 9, 'name': 'Red', 'hex': '#ff0000' },
|
||||
\ { 'color': 10, 'name': 'Lime', 'hex': '#00ff00' },
|
||||
\ { 'color': 11, 'name': 'Yellow', 'hex': '#ffff00' },
|
||||
\ { 'color': 12, 'name': 'Blue', 'hex': '#0000ff' },
|
||||
\ { 'color': 13, 'name': 'Fuchsia', 'hex': '#ff00ff' },
|
||||
\ { 'color': 14, 'name': 'Aqua', 'hex': '#00ffff' },
|
||||
\ { 'color': 15, 'name': 'White', 'hex': '#ffffff' },
|
||||
\ { 'color': 16, 'name': 'Grey0', 'hex': '#000000' },
|
||||
\ { 'color': 17, 'name': 'NavyBlue', 'hex': '#00005f' },
|
||||
\ { 'color': 18, 'name': 'DarkBlue', 'hex': '#000087' },
|
||||
\ { 'color': 19, 'name': 'Blue3', 'hex': '#0000af' },
|
||||
\ { 'color': 20, 'name': 'Blue3', 'hex': '#0000d7' },
|
||||
\ { 'color': 21, 'name': 'Blue1', 'hex': '#0000ff' },
|
||||
\ { 'color': 22, 'name': 'DarkGreen', 'hex': '#005f00' },
|
||||
\ { 'color': 23, 'name': 'DeepSkyBlue4', 'hex': '#005f5f' },
|
||||
\ { 'color': 24, 'name': 'DeepSkyBlue4', 'hex': '#005f87' },
|
||||
\ { 'color': 25, 'name': 'DeepSkyBlue4', 'hex': '#005faf' },
|
||||
\ { 'color': 26, 'name': 'DodgerBlue3', 'hex': '#005fd7' },
|
||||
\ { 'color': 27, 'name': 'DodgerBlue2', 'hex': '#005fff' },
|
||||
\ { 'color': 28, 'name': 'Green4', 'hex': '#008700' },
|
||||
\ { 'color': 29, 'name': 'SpringGreen4', 'hex': '#00875f' },
|
||||
\ { 'color': 30, 'name': 'Turquoise4', 'hex': '#008787' },
|
||||
\ { 'color': 31, 'name': 'DeepSkyBlue3', 'hex': '#0087af' },
|
||||
\ { 'color': 32, 'name': 'DeepSkyBlue3', 'hex': '#0087d7' },
|
||||
\ { 'color': 33, 'name': 'DodgerBlue1', 'hex': '#0087ff' },
|
||||
\ { 'color': 34, 'name': 'Green3', 'hex': '#00af00' },
|
||||
\ { 'color': 35, 'name': 'SpringGreen3', 'hex': '#00af5f' },
|
||||
\ { 'color': 36, 'name': 'DarkCyan', 'hex': '#00af87' },
|
||||
\ { 'color': 37, 'name': 'LightSeaGreen', 'hex': '#00afaf' },
|
||||
\ { 'color': 38, 'name': 'DeepSkyBlue2', 'hex': '#00afd7' },
|
||||
\ { 'color': 39, 'name': 'DeepSkyBlue1', 'hex': '#00afff' },
|
||||
\ { 'color': 40, 'name': 'Green3', 'hex': '#00d700' },
|
||||
\ { 'color': 41, 'name': 'SpringGreen3', 'hex': '#00d75f' },
|
||||
\ { 'color': 42, 'name': 'SpringGreen2', 'hex': '#00d787' },
|
||||
\ { 'color': 43, 'name': 'Cyan3', 'hex': '#00d7af' },
|
||||
\ { 'color': 44, 'name': 'DarkTurquoise', 'hex': '#00d7d7' },
|
||||
\ { 'color': 45, 'name': 'Turquoise2', 'hex': '#00d7ff' },
|
||||
\ { 'color': 46, 'name': 'Green1', 'hex': '#00ff00' },
|
||||
\ { 'color': 47, 'name': 'SpringGreen2', 'hex': '#00ff5f' },
|
||||
\ { 'color': 48, 'name': 'SpringGreen1', 'hex': '#00ff87' },
|
||||
\ { 'color': 49, 'name': 'MediumSpringGreen', 'hex': '#00ffaf' },
|
||||
\ { 'color': 50, 'name': 'Cyan2', 'hex': '#00ffd7' },
|
||||
\ { 'color': 51, 'name': 'Cyan1', 'hex': '#00ffff' },
|
||||
\ { 'color': 52, 'name': 'DarkRed', 'hex': '#5f0000' },
|
||||
\ { 'color': 53, 'name': 'DeepPink4', 'hex': '#5f005f' },
|
||||
\ { 'color': 54, 'name': 'Purple4', 'hex': '#5f0087' },
|
||||
\ { 'color': 55, 'name': 'Purple4', 'hex': '#5f00af' },
|
||||
\ { 'color': 56, 'name': 'Purple3', 'hex': '#5f00d7' },
|
||||
\ { 'color': 57, 'name': 'BlueViolet', 'hex': '#5f00ff' },
|
||||
\ { 'color': 58, 'name': 'Orange4', 'hex': '#5f5f00' },
|
||||
\ { 'color': 59, 'name': 'Grey37', 'hex': '#5f5f5f' },
|
||||
\ { 'color': 60, 'name': 'MediumPurple4', 'hex': '#5f5f87' },
|
||||
\ { 'color': 61, 'name': 'SlateBlue3', 'hex': '#5f5faf' },
|
||||
\ { 'color': 62, 'name': 'SlateBlue3', 'hex': '#5f5fd7' },
|
||||
\ { 'color': 63, 'name': 'RoyalBlue1', 'hex': '#5f5fff' },
|
||||
\ { 'color': 64, 'name': 'Chartreuse4', 'hex': '#5f8700' },
|
||||
\ { 'color': 65, 'name': 'DarkSeaGreen4', 'hex': '#5f875f' },
|
||||
\ { 'color': 66, 'name': 'PaleTurquoise4', 'hex': '#5f8787' },
|
||||
\ { 'color': 67, 'name': 'SteelBlue', 'hex': '#5f87af' },
|
||||
\ { 'color': 68, 'name': 'SteelBlue3', 'hex': '#5f87d7' },
|
||||
\ { 'color': 69, 'name': 'CornflowerBlue', 'hex': '#5f87ff' },
|
||||
\ { 'color': 70, 'name': 'Chartreuse3', 'hex': '#5faf00' },
|
||||
\ { 'color': 71, 'name': 'DarkSeaGreen4', 'hex': '#5faf5f' },
|
||||
\ { 'color': 72, 'name': 'CadetBlue', 'hex': '#5faf87' },
|
||||
\ { 'color': 73, 'name': 'CadetBlue', 'hex': '#5fafaf' },
|
||||
\ { 'color': 74, 'name': 'SkyBlue3', 'hex': '#5fafd7' },
|
||||
\ { 'color': 75, 'name': 'SteelBlue1', 'hex': '#5fafff' },
|
||||
\ { 'color': 76, 'name': 'Chartreuse3', 'hex': '#5fd700' },
|
||||
\ { 'color': 77, 'name': 'PaleGreen3', 'hex': '#5fd75f' },
|
||||
\ { 'color': 78, 'name': 'SeaGreen3', 'hex': '#5fd787' },
|
||||
\ { 'color': 79, 'name': 'Aquamarine3', 'hex': '#5fd7af' },
|
||||
\ { 'color': 80, 'name': 'MediumTurquoise', 'hex': '#5fd7d7' },
|
||||
\ { 'color': 81, 'name': 'SteelBlue1', 'hex': '#5fd7ff' },
|
||||
\ { 'color': 82, 'name': 'Chartreuse2', 'hex': '#5fff00' },
|
||||
\ { 'color': 83, 'name': 'SeaGreen2', 'hex': '#5fff5f' },
|
||||
\ { 'color': 84, 'name': 'SeaGreen1', 'hex': '#5fff87' },
|
||||
\ { 'color': 85, 'name': 'SeaGreen1', 'hex': '#5fffaf' },
|
||||
\ { 'color': 86, 'name': 'Aquamarine1', 'hex': '#5fffd7' },
|
||||
\ { 'color': 87, 'name': 'DarkSlateGray2', 'hex': '#5fffff' },
|
||||
\ { 'color': 88, 'name': 'DarkRed', 'hex': '#870000' },
|
||||
\ { 'color': 89, 'name': 'DeepPink4', 'hex': '#87005f' },
|
||||
\ { 'color': 90, 'name': 'DarkMagenta', 'hex': '#870087' },
|
||||
\ { 'color': 91, 'name': 'DarkMagenta', 'hex': '#8700af' },
|
||||
\ { 'color': 92, 'name': 'DarkViolet', 'hex': '#8700d7' },
|
||||
\ { 'color': 93, 'name': 'Purple', 'hex': '#8700ff' },
|
||||
\ { 'color': 94, 'name': 'Orange4', 'hex': '#875f00' },
|
||||
\ { 'color': 95, 'name': 'LightPink4', 'hex': '#875f5f' },
|
||||
\ { 'color': 96, 'name': 'Plum4', 'hex': '#875f87' },
|
||||
\ { 'color': 97, 'name': 'MediumPurple3', 'hex': '#875faf' },
|
||||
\ { 'color': 98, 'name': 'MediumPurple3', 'hex': '#875fd7' },
|
||||
\ { 'color': 99, 'name': 'SlateBlue1', 'hex': '#875fff' },
|
||||
\ { 'color': 100, 'name': 'Yellow4', 'hex': '#878700' },
|
||||
\ { 'color': 101, 'name': 'Wheat4', 'hex': '#87875f' },
|
||||
\ { 'color': 102, 'name': 'Grey53', 'hex': '#878787' },
|
||||
\ { 'color': 103, 'name': 'LightSlateGrey', 'hex': '#8787af' },
|
||||
\ { 'color': 104, 'name': 'MediumPurple', 'hex': '#8787d7' },
|
||||
\ { 'color': 105, 'name': 'LightSlateBlue', 'hex': '#8787ff' },
|
||||
\ { 'color': 106, 'name': 'Yellow4', 'hex': '#87af00' },
|
||||
\ { 'color': 107, 'name': 'DarkOliveGreen3', 'hex': '#87af5f' },
|
||||
\ { 'color': 108, 'name': 'DarkSeaGreen', 'hex': '#87af87' },
|
||||
\ { 'color': 109, 'name': 'LightSkyBlue3', 'hex': '#87afaf' },
|
||||
\ { 'color': 110, 'name': 'LightSkyBlue3', 'hex': '#87afd7' },
|
||||
\ { 'color': 111, 'name': 'SkyBlue2', 'hex': '#87afff' },
|
||||
\ { 'color': 112, 'name': 'Chartreuse2', 'hex': '#87d700' },
|
||||
\ { 'color': 113, 'name': 'DarkOliveGreen3', 'hex': '#87d75f' },
|
||||
\ { 'color': 114, 'name': 'PaleGreen3', 'hex': '#87d787' },
|
||||
\ { 'color': 115, 'name': 'DarkSeaGreen3', 'hex': '#87d7af' },
|
||||
\ { 'color': 116, 'name': 'DarkSlateGray3', 'hex': '#87d7d7' },
|
||||
\ { 'color': 117, 'name': 'SkyBlue1', 'hex': '#87d7ff' },
|
||||
\ { 'color': 118, 'name': 'Chartreuse1', 'hex': '#87ff00' },
|
||||
\ { 'color': 119, 'name': 'LightGreen', 'hex': '#87ff5f' },
|
||||
\ { 'color': 120, 'name': 'LightGreen', 'hex': '#87ff87' },
|
||||
\ { 'color': 121, 'name': 'PaleGreen1', 'hex': '#87ffaf' },
|
||||
\ { 'color': 122, 'name': 'Aquamarine1', 'hex': '#87ffd7' },
|
||||
\ { 'color': 123, 'name': 'DarkSlateGray1', 'hex': '#87ffff' },
|
||||
\ { 'color': 124, 'name': 'Red3', 'hex': '#af0000' },
|
||||
\ { 'color': 125, 'name': 'DeepPink4', 'hex': '#af005f' },
|
||||
\ { 'color': 126, 'name': 'MediumVioletRed', 'hex': '#af0087' },
|
||||
\ { 'color': 127, 'name': 'Magenta3', 'hex': '#af00af' },
|
||||
\ { 'color': 128, 'name': 'DarkViolet', 'hex': '#af00d7' },
|
||||
\ { 'color': 129, 'name': 'Purple', 'hex': '#af00ff' },
|
||||
\ { 'color': 130, 'name': 'DarkOrange3', 'hex': '#af5f00' },
|
||||
\ { 'color': 131, 'name': 'IndianRed', 'hex': '#af5f5f' },
|
||||
\ { 'color': 132, 'name': 'HotPink3', 'hex': '#af5f87' },
|
||||
\ { 'color': 133, 'name': 'MediumOrchid3', 'hex': '#af5faf' },
|
||||
\ { 'color': 134, 'name': 'MediumOrchid', 'hex': '#af5fd7' },
|
||||
\ { 'color': 135, 'name': 'MediumPurple2', 'hex': '#af5fff' },
|
||||
\ { 'color': 136, 'name': 'DarkGoldenrod', 'hex': '#af8700' },
|
||||
\ { 'color': 137, 'name': 'LightSalmon3', 'hex': '#af875f' },
|
||||
\ { 'color': 138, 'name': 'RosyBrown', 'hex': '#af8787' },
|
||||
\ { 'color': 139, 'name': 'Grey63', 'hex': '#af87af' },
|
||||
\ { 'color': 140, 'name': 'MediumPurple2', 'hex': '#af87d7' },
|
||||
\ { 'color': 141, 'name': 'MediumPurple1', 'hex': '#af87ff' },
|
||||
\ { 'color': 142, 'name': 'Gold3', 'hex': '#afaf00' },
|
||||
\ { 'color': 143, 'name': 'DarkKhaki', 'hex': '#afaf5f' },
|
||||
\ { 'color': 144, 'name': 'NavajoWhite3', 'hex': '#afaf87' },
|
||||
\ { 'color': 145, 'name': 'Grey69', 'hex': '#afafaf' },
|
||||
\ { 'color': 146, 'name': 'LightSteelBlue3', 'hex': '#afafd7' },
|
||||
\ { 'color': 147, 'name': 'LightSteelBlue', 'hex': '#afafff' },
|
||||
\ { 'color': 148, 'name': 'Yellow3', 'hex': '#afd700' },
|
||||
\ { 'color': 149, 'name': 'DarkOliveGreen3', 'hex': '#afd75f' },
|
||||
\ { 'color': 150, 'name': 'DarkSeaGreen3', 'hex': '#afd787' },
|
||||
\ { 'color': 151, 'name': 'DarkSeaGreen2', 'hex': '#afd7af' },
|
||||
\ { 'color': 152, 'name': 'LightCyan3', 'hex': '#afd7d7' },
|
||||
\ { 'color': 153, 'name': 'LightSkyBlue1', 'hex': '#afd7ff' },
|
||||
\ { 'color': 154, 'name': 'GreenYellow', 'hex': '#afff00' },
|
||||
\ { 'color': 155, 'name': 'DarkOliveGreen2', 'hex': '#afff5f' },
|
||||
\ { 'color': 156, 'name': 'PaleGreen1', 'hex': '#afff87' },
|
||||
\ { 'color': 157, 'name': 'DarkSeaGreen2', 'hex': '#afffaf' },
|
||||
\ { 'color': 158, 'name': 'DarkSeaGreen1', 'hex': '#afffd7' },
|
||||
\ { 'color': 159, 'name': 'PaleTurquoise1', 'hex': '#afffff' },
|
||||
\ { 'color': 160, 'name': 'Red3', 'hex': '#d70000' },
|
||||
\ { 'color': 161, 'name': 'DeepPink3', 'hex': '#d7005f' },
|
||||
\ { 'color': 162, 'name': 'DeepPink3', 'hex': '#d70087' },
|
||||
\ { 'color': 163, 'name': 'Magenta3', 'hex': '#d700af' },
|
||||
\ { 'color': 164, 'name': 'Magenta3', 'hex': '#d700d7' },
|
||||
\ { 'color': 165, 'name': 'Magenta2', 'hex': '#d700ff' },
|
||||
\ { 'color': 166, 'name': 'DarkOrange3', 'hex': '#d75f00' },
|
||||
\ { 'color': 167, 'name': 'IndianRed', 'hex': '#d75f5f' },
|
||||
\ { 'color': 168, 'name': 'HotPink3', 'hex': '#d75f87' },
|
||||
\ { 'color': 169, 'name': 'HotPink2', 'hex': '#d75faf' },
|
||||
\ { 'color': 170, 'name': 'Orchid', 'hex': '#d75fd7' },
|
||||
\ { 'color': 171, 'name': 'MediumOrchid1', 'hex': '#d75fff' },
|
||||
\ { 'color': 172, 'name': 'Orange3', 'hex': '#d78700' },
|
||||
\ { 'color': 173, 'name': 'LightSalmon3', 'hex': '#d7875f' },
|
||||
\ { 'color': 174, 'name': 'LightPink3', 'hex': '#d78787' },
|
||||
\ { 'color': 175, 'name': 'Pink3', 'hex': '#d787af' },
|
||||
\ { 'color': 176, 'name': 'Plum3', 'hex': '#d787d7' },
|
||||
\ { 'color': 177, 'name': 'Violet', 'hex': '#d787ff' },
|
||||
\ { 'color': 178, 'name': 'Gold3', 'hex': '#d7af00' },
|
||||
\ { 'color': 179, 'name': 'LightGoldenrod3', 'hex': '#d7af5f' },
|
||||
\ { 'color': 180, 'name': 'Tan', 'hex': '#d7af87' },
|
||||
\ { 'color': 181, 'name': 'MistyRose3', 'hex': '#d7afaf' },
|
||||
\ { 'color': 182, 'name': 'Thistle3', 'hex': '#d7afd7' },
|
||||
\ { 'color': 183, 'name': 'Plum2', 'hex': '#d7afff' },
|
||||
\ { 'color': 184, 'name': 'Yellow3', 'hex': '#d7d700' },
|
||||
\ { 'color': 185, 'name': 'Khaki3', 'hex': '#d7d75f' },
|
||||
\ { 'color': 186, 'name': 'LightGoldenrod2', 'hex': '#d7d787' },
|
||||
\ { 'color': 187, 'name': 'LightYellow3', 'hex': '#d7d7af' },
|
||||
\ { 'color': 188, 'name': 'Grey84', 'hex': '#d7d7d7' },
|
||||
\ { 'color': 189, 'name': 'LightSteelBlue1', 'hex': '#d7d7ff' },
|
||||
\ { 'color': 190, 'name': 'Yellow2', 'hex': '#d7ff00' },
|
||||
\ { 'color': 191, 'name': 'DarkOliveGreen1', 'hex': '#d7ff5f' },
|
||||
\ { 'color': 192, 'name': 'DarkOliveGreen1', 'hex': '#d7ff87' },
|
||||
\ { 'color': 193, 'name': 'DarkSeaGreen1', 'hex': '#d7ffaf' },
|
||||
\ { 'color': 194, 'name': 'Honeydew2', 'hex': '#d7ffd7' },
|
||||
\ { 'color': 195, 'name': 'LightCyan1', 'hex': '#d7ffff' },
|
||||
\ { 'color': 196, 'name': 'Red1', 'hex': '#ff0000' },
|
||||
\ { 'color': 197, 'name': 'DeepPink2', 'hex': '#ff005f' },
|
||||
\ { 'color': 198, 'name': 'DeepPink1', 'hex': '#ff0087' },
|
||||
\ { 'color': 199, 'name': 'DeepPink1', 'hex': '#ff00af' },
|
||||
\ { 'color': 200, 'name': 'Magenta2', 'hex': '#ff00d7' },
|
||||
\ { 'color': 201, 'name': 'Magenta1', 'hex': '#ff00ff' },
|
||||
\ { 'color': 202, 'name': 'OrangeRed1', 'hex': '#ff5f00' },
|
||||
\ { 'color': 203, 'name': 'IndianRed1', 'hex': '#ff5f5f' },
|
||||
\ { 'color': 204, 'name': 'IndianRed1', 'hex': '#ff5f87' },
|
||||
\ { 'color': 205, 'name': 'HotPink', 'hex': '#ff5faf' },
|
||||
\ { 'color': 206, 'name': 'HotPink', 'hex': '#ff5fd7' },
|
||||
\ { 'color': 207, 'name': 'MediumOrchid1', 'hex': '#ff5fff' },
|
||||
\ { 'color': 208, 'name': 'DarkOrange', 'hex': '#ff8700' },
|
||||
\ { 'color': 209, 'name': 'Salmon1', 'hex': '#ff875f' },
|
||||
\ { 'color': 210, 'name': 'LightCoral', 'hex': '#ff8787' },
|
||||
\ { 'color': 211, 'name': 'PaleVioletRed1', 'hex': '#ff87af' },
|
||||
\ { 'color': 212, 'name': 'Orchid2', 'hex': '#ff87d7' },
|
||||
\ { 'color': 213, 'name': 'Orchid1', 'hex': '#ff87ff' },
|
||||
\ { 'color': 214, 'name': 'Orange1', 'hex': '#ffaf00' },
|
||||
\ { 'color': 215, 'name': 'SandyBrown', 'hex': '#ffaf5f' },
|
||||
\ { 'color': 216, 'name': 'LightSalmon1', 'hex': '#ffaf87' },
|
||||
\ { 'color': 217, 'name': 'LightPink1', 'hex': '#ffafaf' },
|
||||
\ { 'color': 218, 'name': 'Pink1', 'hex': '#ffafd7' },
|
||||
\ { 'color': 219, 'name': 'Plum1', 'hex': '#ffafff' },
|
||||
\ { 'color': 220, 'name': 'Gold1', 'hex': '#ffd700' },
|
||||
\ { 'color': 221, 'name': 'LightGoldenrod2', 'hex': '#ffd75f' },
|
||||
\ { 'color': 222, 'name': 'LightGoldenrod2', 'hex': '#ffd787' },
|
||||
\ { 'color': 223, 'name': 'NavajoWhite1', 'hex': '#ffd7af' },
|
||||
\ { 'color': 224, 'name': 'MistyRose1', 'hex': '#ffd7d7' },
|
||||
\ { 'color': 225, 'name': 'Thistle1', 'hex': '#ffd7ff' },
|
||||
\ { 'color': 226, 'name': 'Yellow1', 'hex': '#ffff00' },
|
||||
\ { 'color': 227, 'name': 'LightGoldenrod1', 'hex': '#ffff5f' },
|
||||
\ { 'color': 228, 'name': 'Khaki1', 'hex': '#ffff87' },
|
||||
\ { 'color': 229, 'name': 'Wheat1', 'hex': '#ffffaf' },
|
||||
\ { 'color': 230, 'name': 'Cornsilk1', 'hex': '#ffffd7' },
|
||||
\ { 'color': 231, 'name': 'Grey100', 'hex': '#ffffff' },
|
||||
\ { 'color': 232, 'name': 'Grey3', 'hex': '#080808' },
|
||||
\ { 'color': 233, 'name': 'Grey7', 'hex': '#121212' },
|
||||
\ { 'color': 234, 'name': 'Grey11', 'hex': '#1c1c1c' },
|
||||
\ { 'color': 235, 'name': 'Grey15', 'hex': '#262626' },
|
||||
\ { 'color': 236, 'name': 'Grey19', 'hex': '#303030' },
|
||||
\ { 'color': 237, 'name': 'Grey23', 'hex': '#3a3a3a' },
|
||||
\ { 'color': 238, 'name': 'Grey27', 'hex': '#444444' },
|
||||
\ { 'color': 239, 'name': 'Grey30', 'hex': '#4e4e4e' },
|
||||
\ { 'color': 240, 'name': 'Grey35', 'hex': '#585858' },
|
||||
\ { 'color': 241, 'name': 'Grey39', 'hex': '#626262' },
|
||||
\ { 'color': 242, 'name': 'Grey42', 'hex': '#6c6c6c' },
|
||||
\ { 'color': 243, 'name': 'Grey46', 'hex': '#767676' },
|
||||
\ { 'color': 244, 'name': 'Grey50', 'hex': '#808080' },
|
||||
\ { 'color': 245, 'name': 'Grey54', 'hex': '#8a8a8a' },
|
||||
\ { 'color': 246, 'name': 'Grey58', 'hex': '#949494' },
|
||||
\ { 'color': 247, 'name': 'Grey62', 'hex': '#9e9e9e' },
|
||||
\ { 'color': 248, 'name': 'Grey66', 'hex': '#a8a8a8' },
|
||||
\ { 'color': 249, 'name': 'Grey70', 'hex': '#b2b2b2' },
|
||||
\ { 'color': 250, 'name': 'Grey74', 'hex': '#bcbcbc' },
|
||||
\ { 'color': 251, 'name': 'Grey78', 'hex': '#c6c6c6' },
|
||||
\ { 'color': 252, 'name': 'Grey82', 'hex': '#d0d0d0' },
|
||||
\ { 'color': 253, 'name': 'Grey85', 'hex': '#dadada' },
|
||||
\ { 'color': 254, 'name': 'Grey89', 'hex': '#e4e4e4' },
|
||||
\ { 'color': 255, 'name': 'Grey93', 'hex': '#eeeeee' },
|
||||
\ ]
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# initialize
|
||||
#----------------------------------------------------------------------
|
||||
var _palette: list<list<number>>
|
||||
var cnames = {}
|
||||
|
||||
for color in color_definition
|
||||
final cc: number = str2nr(strpart(color.hex, 1), 16)
|
||||
final r: number = and(cc / 0x10000, 0xff)
|
||||
final g: number = and(cc / 0x100, 0xff)
|
||||
final b: number = and(cc, 0xff)
|
||||
final p: list<number> = [r, g, b]
|
||||
_palette += [p]
|
||||
cnames[tolower(color.name)] = color.color
|
||||
endfor
|
||||
|
||||
final palette: list<list<number>> = deepcopy(_palette)
|
||||
var _diff_lookup: list<number> = repeat([0], 512 * 3)
|
||||
|
||||
for i in range(256)
|
||||
final k: number = i * i
|
||||
final dr: number = k * 30 * 30
|
||||
final dg: number = k * 59 * 59
|
||||
final db: number = k * 11 * 11
|
||||
_diff_lookup[ 256 + i] = dr
|
||||
_diff_lookup[ 256 - i] = dr
|
||||
_diff_lookup[ 768 + i] = dg
|
||||
_diff_lookup[ 768 - i] = dg
|
||||
_diff_lookup[1280 + i] = db
|
||||
_diff_lookup[1280 - i] = db
|
||||
endfor
|
||||
|
||||
final diff_lookup: list<number> = deepcopy(_diff_lookup)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# bestfit color
|
||||
#----------------------------------------------------------------------
|
||||
export def BestfitColor(r: number, g: number, b: number, limit: number = 256): number
|
||||
final R: number = (r < 256) ? r : 255
|
||||
final G: number = (g < 256) ? g : 255
|
||||
final B: number = (b < 256) ? b : 255
|
||||
final LIMIT: number = (limit < 256) ? limit : 256
|
||||
final lookup: list<number> = diff_lookup
|
||||
var lowest = 0x7fffffff
|
||||
var bestfit = 0
|
||||
var index = 0
|
||||
while index < LIMIT
|
||||
final rgb: list<number> = palette[index]
|
||||
var diff = lookup[768 + rgb[1] - G]
|
||||
if diff < lowest
|
||||
diff += lookup[256 + rgb[0] - R]
|
||||
if diff < lowest
|
||||
diff += lookup[1280 + rgb[2] - B]
|
||||
if diff < lowest
|
||||
lowest = diff
|
||||
bestfit = index
|
||||
endif
|
||||
if diff <= 0
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
index += 1
|
||||
endwhile
|
||||
return bestfit
|
||||
enddef
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# for 8 colors
|
||||
#----------------------------------------------------------------------
|
||||
export def Bestfit8(r: number, g: number, b: number): number
|
||||
return BestfitColor(r, g, b, 8)
|
||||
enddef
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# for 16 colors
|
||||
#----------------------------------------------------------------------
|
||||
export def Bestfit16(r: number, g: number, b: number): number
|
||||
return BestfitColor(r, g, b, 16)
|
||||
enddef
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# for 256 colors
|
||||
#----------------------------------------------------------------------
|
||||
export def Bestfit256(r: number, g: number, b: number): number
|
||||
return BestfitColor(r, g, b, 256)
|
||||
enddef
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# for 256 colors
|
||||
#----------------------------------------------------------------------
|
||||
var matched = {}
|
||||
|
||||
export def Match(r: number, g: number, b: number, num: number = -1): number
|
||||
final rr = (r < 256) ? r : 255
|
||||
final gg = (g < 256) ? g : 255
|
||||
final bb = (b < 256) ? b : 255
|
||||
final key: number = (rr * 4096 / 4) + (gg * 64 / 4) + (bb / 4)
|
||||
if !has_key(matched, key)
|
||||
var N: number = 256
|
||||
if num >= 0
|
||||
N = num
|
||||
else
|
||||
if exists('g:quickui#palette#number')
|
||||
N = g:quickui#palette#number
|
||||
endif
|
||||
endif
|
||||
final cc: number = BestfitColor(rr, gg, bb, N)
|
||||
matched[key] = cc
|
||||
endif
|
||||
return matched[key]
|
||||
enddef
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# convert #112233 to [0x11, 0x22, 0x33]
|
||||
#----------------------------------------------------------------------
|
||||
export def Hex2RGB(hex: string): list<number>
|
||||
var head: string = strpart(hex, 0, 1)
|
||||
var r: number = 0
|
||||
var g: number = 0
|
||||
var b: number = 0
|
||||
if head == '#'
|
||||
final c: number = str2nr(strpart(hex, 1), 16)
|
||||
r = and(c / 0x10000, 0xff)
|
||||
g = and(c / 0x100, 0xff)
|
||||
b = and(c, 0xff)
|
||||
elseif head == '('
|
||||
head = strpart(hex, 1, len(hex) - 2)
|
||||
final part: list<string> = split(head, ',')
|
||||
r = str2nr(part[0])
|
||||
g = str2nr(part[1])
|
||||
b = str2nr(part[2])
|
||||
endif
|
||||
return [r, g, b]
|
||||
enddef
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# hex to palette index
|
||||
#----------------------------------------------------------------------
|
||||
export def Hex2Index(hex: string, num: number = -1): number
|
||||
final cc: list<number> = Hex2RGB(hex)
|
||||
return Match(cc[0], cc[1], cc[2], num)
|
||||
enddef
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# search name
|
||||
#----------------------------------------------------------------------
|
||||
export def Name2Index(name: string, default: number = 0): number
|
||||
final head = strpart(name, 0, 1)
|
||||
if head == '#' || head == '('
|
||||
return Hex2Index(name)
|
||||
else
|
||||
final nm = tolower(name)
|
||||
if exists('v:colornames')
|
||||
if has_key(v:colornames, nm)
|
||||
final hex = v:colornames[nm]
|
||||
return Hex2Index(hex)
|
||||
endif
|
||||
endif
|
||||
return get(cnames, tolower(name), default)
|
||||
endif
|
||||
enddef
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# benchmark
|
||||
#----------------------------------------------------------------------
|
||||
export def Timing(): string
|
||||
var ts = reltime()
|
||||
for i in range(256)
|
||||
Match(i, i, i)
|
||||
endfor
|
||||
var tt = reltime(ts)
|
||||
return reltimestr(tt)
|
||||
enddef
|
||||
|
||||
|
299
vim/.vim/autoload/quickui/preview.vim
Normal file
299
vim/.vim/autoload/quickui/preview.vim
Normal file
@ -0,0 +1,299 @@
|
||||
"======================================================================
|
||||
"
|
||||
" preview.vim -
|
||||
"
|
||||
" Created by skywind on 2020/01/11
|
||||
" Last Modified: 2021/12/13 22:32
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" private object
|
||||
"----------------------------------------------------------------------
|
||||
let s:private = {'winid': -1, 'background': -1, 'state':0}
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" position to a proper location
|
||||
"----------------------------------------------------------------------
|
||||
function! s:around_cursor(width, height)
|
||||
let cursor_pos = quickui#core#cursor_pos()
|
||||
let row = cursor_pos[0] - a:height
|
||||
let col = cursor_pos[1] + 1
|
||||
if quickui#core#in_screen(row, col, a:width, a:height)
|
||||
return [row, col]
|
||||
endif
|
||||
if col + a:width - 1 > &columns
|
||||
let col = col - (1 + a:width)
|
||||
if quickui#core#in_screen(row, col, a:width, a:height)
|
||||
return [row, col]
|
||||
endif
|
||||
endif
|
||||
if row < 1
|
||||
let row = row + (1 + a:height)
|
||||
if quickui#core#in_screen(row, col, a:width, a:height)
|
||||
return [row, col]
|
||||
endif
|
||||
endif
|
||||
if cursor_pos[0] - a:height - 2 < 1
|
||||
let row = cursor_pos[0] + 1
|
||||
else
|
||||
let row = cursor_pos[0] - a:height
|
||||
endif
|
||||
if cursor_pos[1] + a:width + 2 < &columns
|
||||
let col = cursor_pos[1] + 1
|
||||
else
|
||||
let col = cursor_pos[1] - a:width
|
||||
endif
|
||||
return quickui#core#screen_fit(row, col, a:width, a:height)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create preview window
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#preview#display(content, opts)
|
||||
call quickui#preview#close()
|
||||
if type(a:content) == v:t_string && filereadable(a:content) == 0
|
||||
call quickui#utils#errmsg('E212: Can not open file: '. a:content)
|
||||
return -1
|
||||
endif
|
||||
let s:private.state = 0
|
||||
if type(a:content) == v:t_string
|
||||
silent let source = bufadd(a:content)
|
||||
silent call bufload(source)
|
||||
elseif type(a:content) == v:t_list
|
||||
let source = a:content
|
||||
endif
|
||||
let winid = -1
|
||||
let title = ''
|
||||
if has_key(a:opts, 'title') && (a:opts.title != '')
|
||||
let title = ' ' . a:opts.title .' '
|
||||
endif
|
||||
let w = get(a:opts, 'w', -1)
|
||||
let h = get(a:opts, 'h', -1)
|
||||
let w = (w < 0)? 50 : w
|
||||
let h = (h < 0)? 10 : h
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
let button = (get(a:opts, 'close', '') == 'button')? 1 : 0
|
||||
let color = get(a:opts, 'color', 'QuickPreview')
|
||||
let p = s:around_cursor(w + (border? 2 : 0), h + (border? 2 : 0))
|
||||
if has_key(a:opts, 'col')
|
||||
let p[0] = get(a:opts, 'line', get(a:opts, 'row', 1))
|
||||
let p[1] = get(a:opts, 'col', 1)
|
||||
endif
|
||||
if has('nvim') == 0
|
||||
let winid = popup_create(source, {'wrap':1, 'mapping':0, 'hidden':1})
|
||||
let opts = {'maxwidth':w, 'maxheight':h, 'minwidth':w, 'minheight':h}
|
||||
call popup_move(winid, opts)
|
||||
let opts = {'close':'button'}
|
||||
let opts.border = border? [1,1,1,1,1,1,1,1,1] : repeat([0], 9)
|
||||
let opts.resize = 0
|
||||
let opts.highlight = color
|
||||
let opts.borderchars = quickui#core#border_vim(border)
|
||||
if get(a:opts, 'persist', 0) == 0
|
||||
let opts.moved = 'any'
|
||||
endif
|
||||
let opts.drag = 1
|
||||
let opts.line = p[0]
|
||||
let opts.col = p[1]
|
||||
if title != ''
|
||||
let opts.title = title
|
||||
endif
|
||||
let opts.callback = function('s:popup_exit')
|
||||
" let opts.fixed = 'true'
|
||||
if has_key(a:opts, 'bordercolor')
|
||||
let c = a:opts.bordercolor
|
||||
let opts.borderhighlight = [c, c, c, c]
|
||||
endif
|
||||
call popup_setoptions(winid, opts)
|
||||
let s:private.winid = winid
|
||||
call popup_show(winid)
|
||||
else
|
||||
let opts = {'focusable':0, 'style':'minimal', 'relative':'editor'}
|
||||
let opts.width = w
|
||||
let opts.height = h
|
||||
let opts.row = p[0]
|
||||
let opts.col = p[1]
|
||||
if has_key(a:opts, 'focusable')
|
||||
let opts.focusable = a:opts.focusable
|
||||
endif
|
||||
if type(source) == v:t_number
|
||||
let bid = source
|
||||
else
|
||||
let bid = quickui#core#scratch_buffer('preview', source)
|
||||
endif
|
||||
if has('nvim-0.6.0')
|
||||
let opts.noautocmd = 1
|
||||
endif
|
||||
let winid = nvim_open_win(bid, 0, opts)
|
||||
let s:private.winid = winid
|
||||
let high = 'Normal:'.color.',NonText:'.color.',EndOfBuffer:'.color
|
||||
call nvim_win_set_option(winid, 'winhl', high)
|
||||
let s:private.background = -1
|
||||
if border > 0 && get(g:, 'quickui_nvim_simulate_border', 1) != 0
|
||||
let back = quickui#utils#make_border(w, h, border, title, button)
|
||||
let nbid = quickui#core#scratch_buffer('previewborder', back)
|
||||
let op = {'relative':'editor', 'focusable':0, 'style':'minimal'}
|
||||
let op.width = w + 2
|
||||
let op.height = h + 2
|
||||
let pos = nvim_win_get_config(winid)
|
||||
let op.row = pos.row - 1
|
||||
let op.col = pos.col - 1
|
||||
let bordercolor = get(a:opts, 'bordercolor', color)
|
||||
if has('nvim-0.6.0')
|
||||
let op.noautocmd = 1
|
||||
endif
|
||||
let background = nvim_open_win(nbid, 0, op)
|
||||
call nvim_win_set_option(background, 'winhl', 'Normal:'. bordercolor)
|
||||
let s:private.background = background
|
||||
endif
|
||||
endif
|
||||
let cmdlist = ['setlocal signcolumn=no norelativenumber']
|
||||
if get(a:opts, 'number', 1) == 0
|
||||
let cmdlist += ['setlocal nonumber']
|
||||
else
|
||||
let cmdlist += ['setlocal number']
|
||||
endif
|
||||
let cursor = get(a:opts, 'cursor', -1)
|
||||
if cursor > 0
|
||||
let cmdlist += ['exec "normal! gg' . cursor . 'Gzz"']
|
||||
endif
|
||||
if has_key(a:opts, 'syntax')
|
||||
let cmdlist += ['setl ft=' . fnameescape(a:opts.syntax) ]
|
||||
endif
|
||||
let cmdlist += ['silent! setlocal scrolloff=0']
|
||||
call setbufvar(winbufnr(winid), '__quickui_cursor__', cursor)
|
||||
call quickui#core#win_execute(winid, cmdlist)
|
||||
call quickui#utils#update_cursor(winid)
|
||||
let s:private.state = 1
|
||||
if has('nvim')
|
||||
if get(a:opts, 'persist', 0) == 0
|
||||
autocmd CursorMoved <buffer> ++once call s:autoclose_preview_window()
|
||||
endif
|
||||
endif
|
||||
return winid
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" exit callback
|
||||
"----------------------------------------------------------------------
|
||||
function! s:popup_exit(winid, code)
|
||||
let s:private.winid = -1
|
||||
let s:private.state = 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" close window
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#preview#close()
|
||||
if s:private.winid >= 0
|
||||
if has('nvim') == 0
|
||||
call popup_close(s:private.winid, 0)
|
||||
let s:private.winid = -1
|
||||
else
|
||||
call nvim_win_close(s:private.winid, 0)
|
||||
let s:private.winid = -1
|
||||
if s:private.background >= 0
|
||||
call nvim_win_close(s:private.background, 0)
|
||||
let s:private.background = -1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let s:private.state = 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" return state
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#preview#visible()
|
||||
return s:private.state
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" quit
|
||||
"----------------------------------------------------------------------
|
||||
function! s:autoclose_preview_window()
|
||||
if s:private.state != 0
|
||||
if s:private.winid >= 0
|
||||
call quickui#preview#close()
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" scroll preview window
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#preview#scroll(offset)
|
||||
if s:private.state != 0
|
||||
let winid = s:private.winid
|
||||
if s:private.winid >= 0
|
||||
noautocmd call quickui#utils#scroll(winid, a:offset)
|
||||
noautocmd call quickui#utils#update_cursor(winid)
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" press esc to close
|
||||
"----------------------------------------------------------------------
|
||||
function! s:press_esc()
|
||||
exec "nunmap <ESC>"
|
||||
call quickui#preview#close()
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" preview file
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#preview#open(content, opts)
|
||||
call quickui#preview#close()
|
||||
if type(a:content) == v:t_string && filereadable(a:content) == 0
|
||||
call quickui#utils#errmsg('E484: Cannot open file ' . a:content)
|
||||
return -1
|
||||
endif
|
||||
let opts = {}
|
||||
let opts.w = get(g:, 'quickui_preview_w', g:quickui#style#preview_w)
|
||||
let opts.h = get(g:, 'quickui_preview_h', g:quickui#style#preview_h)
|
||||
let opts.number = get(a:opts, 'number', g:quickui#style#preview_number)
|
||||
let opts.cursor = get(a:opts, 'cursor', -1)
|
||||
let title = has_key(a:opts, 'title')? (' ' .. a:opts.title) : ''
|
||||
if type(a:content) == v:t_string
|
||||
let name = fnamemodify(a:content, ':p:t')
|
||||
let opts.title = 'Preview: ' . name . title
|
||||
else
|
||||
let opts.title = 'Preview' .. ((title == '')? '' : (':' .. title))
|
||||
endif
|
||||
if g:quickui#style#preview_bordercolor != ''
|
||||
let opts.bordercolor = g:quickui#style#preview_bordercolor
|
||||
endif
|
||||
let opts.persist = get(a:opts, 'persist', 0)
|
||||
let opts.focusable = get(g:, 'quickui_preview_focusable', 1)
|
||||
if has_key(a:opts, 'syntax')
|
||||
let opts.syntax = a:opts.syntax
|
||||
endif
|
||||
if has_key(a:opts, 'col')
|
||||
let opts.col = a:opts.col
|
||||
let opts.line = get(a:opts, 'line', get(a:opts, 'row'))
|
||||
endif
|
||||
if has_key(a:opts, 'w')
|
||||
let opts.w = a:opts.w
|
||||
let opts.h = get(a:opts, 'h', opts.h)
|
||||
endif
|
||||
let hr = quickui#preview#display(a:content, opts)
|
||||
exec "nnoremap <silent><ESC> :call <SID>press_esc()<cr>"
|
||||
return hr
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
|
914
vim/.vim/autoload/quickui/readline.vim
Normal file
914
vim/.vim/autoload/quickui/readline.vim
Normal file
@ -0,0 +1,914 @@
|
||||
"======================================================================
|
||||
"
|
||||
" readline.vim -
|
||||
"
|
||||
" Created by skywind on 2021/02/20
|
||||
" Last Modified: 2021/11/30 00:04
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set ts=4 sw=4 tw=78 noet :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" readline class
|
||||
"----------------------------------------------------------------------
|
||||
let s:readline = {}
|
||||
let s:readline.cursor = 0 " cursur position in character
|
||||
let s:readline.code = [] " buffer character in int list
|
||||
let s:readline.wide = [] " char display width
|
||||
let s:readline.size = 0 " buffer size in character
|
||||
let s:readline.text = '' " text buffer
|
||||
let s:readline.dirty = 0 " dirty
|
||||
let s:readline.select = -1 " visual selection start pos
|
||||
let s:readline.history = [] " history text
|
||||
let s:readline.index = 0 " history pointer, 0 for current
|
||||
let s:readline.timer = -1 " cursor blink timer
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" move pos
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.move(pos) abort
|
||||
let pos = a:pos
|
||||
let pos = (pos < 0)? 0 : pos
|
||||
let pos = (pos > self.size)? self.size : pos
|
||||
let self.cursor = pos
|
||||
let self.timer = -1
|
||||
return pos
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" change position, mode: 0/start, 1/current, 2/eol
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.seek(pos, mode) abort
|
||||
if a:mode == 0
|
||||
call self.move(a:pos)
|
||||
elseif a:mode == 1
|
||||
call self.move(self.cursor + a:pos)
|
||||
else
|
||||
call self.move(self.size + a:pos)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" set text
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.set(text)
|
||||
let code = str2list(a:text)
|
||||
let wide = []
|
||||
for cc in code
|
||||
let ch = nr2char(cc)
|
||||
let wide += [strdisplaywidth(ch)]
|
||||
endfor
|
||||
let self.code = code
|
||||
let self.wide = wide
|
||||
let self.size = len(code)
|
||||
let self.dirty = 1
|
||||
call self.move(self.cursor)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" internal: update text parts
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.update() abort
|
||||
let self.text = list2str(self.code)
|
||||
let self.dirty = 0
|
||||
return self.text
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" slice
|
||||
"----------------------------------------------------------------------
|
||||
let s:has_nvim = has('nvim')? 1 : 0
|
||||
function! s:list_slice(code, start, endup)
|
||||
let start = a:start
|
||||
let endup = a:endup
|
||||
if s:has_nvim == 0
|
||||
return slice(a:code, a:start, a:endup)
|
||||
else
|
||||
if start == endup
|
||||
return []
|
||||
else
|
||||
return a:code[start:endup-1]
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" extract text: -1/0/1 for text before/on/after cursor
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.extract(locate)
|
||||
let cc = self.cursor
|
||||
if a:locate < 0
|
||||
let p = s:list_slice(self.code, 0, cc)
|
||||
elseif a:locate == 0
|
||||
let p = s:list_slice(self.code, cc, cc + 1)
|
||||
else
|
||||
let p = s:list_slice(self.code, cc + 1, len(self.code))
|
||||
endif
|
||||
return list2str(p)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" insert text in current cursor position
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.insert(text) abort
|
||||
let code = str2list(a:text)
|
||||
let wide = []
|
||||
let cursor = self.cursor
|
||||
for cc in code
|
||||
let ch = nr2char(cc)
|
||||
let ww = strwidth(ch)
|
||||
let wide += [ww]
|
||||
endfor
|
||||
call extend(self.code, code, cursor)
|
||||
call extend(self.wide, wide, cursor)
|
||||
let self.size = len(self.code)
|
||||
let self.cursor += len(code)
|
||||
let self.timer = -1
|
||||
let self.dirty = 1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" internal function: delete n characters on and after cursor
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.delete(size) abort
|
||||
let cursor = self.cursor
|
||||
let avail = self.size - cursor
|
||||
if avail > 0
|
||||
let size = a:size
|
||||
let size = (size > avail)? avail : size
|
||||
let cursor = self.cursor
|
||||
call remove(self.code, cursor, cursor + size - 1)
|
||||
call remove(self.wide, cursor, cursor + size - 1)
|
||||
let self.size = len(self.code)
|
||||
let self.timer = -1
|
||||
let self.dirty = 1
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" backspace
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.backspace(size) abort
|
||||
let avail = self.cursor
|
||||
let size = a:size
|
||||
let size = (size > avail)? avail : size
|
||||
if size > 0
|
||||
let self.cursor -= size
|
||||
call self.delete(size)
|
||||
let self.timer = -1
|
||||
let self.dirty = 1
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" replace
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.replace(text) abort
|
||||
let length = strchars(a:text)
|
||||
if length > 0
|
||||
call self.delete(length)
|
||||
call self.insert(a:text)
|
||||
let self.dirty = 1
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get selection range [start, end)
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.visual_range() abort
|
||||
if self.select < 0
|
||||
return [-1, -1]
|
||||
elseif self.select <= self.cursor
|
||||
return [self.select, self.cursor]
|
||||
else
|
||||
return [self.cursor, self.select]
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get selection text
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.visual_text() abort
|
||||
if self.select < 0
|
||||
return ''
|
||||
else
|
||||
let [start, end] = self.visual_range()
|
||||
let code = s:list_slice(self.code, start, end)
|
||||
return list2str(code)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" delete selection
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.visual_delete() abort
|
||||
if self.select >= 0
|
||||
let cursor = self.cursor
|
||||
let length = self.cursor - self.select
|
||||
if length > 0
|
||||
call self.backspace(length)
|
||||
let self.select = -1
|
||||
elseif length < 0
|
||||
call self.delete(-length)
|
||||
let self.select = -1
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" replace selection
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.visual_replace(text) abort
|
||||
if self.select >= 0
|
||||
call self.visual_delete()
|
||||
call self.insert(a:text)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" check is eol
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.is_eol()
|
||||
return self.cursor >= self.size
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" cursor blink, returns 0 for not blink, 1 for blink (invisible)
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.blink(millisec)
|
||||
let delay_wait = 500
|
||||
let delay_on = 300
|
||||
let delay_off = 300
|
||||
if self.timer < 0
|
||||
let self.timer = a:millisec
|
||||
return 0
|
||||
endif
|
||||
let offset = a:millisec - self.timer
|
||||
if offset < delay_wait
|
||||
return 0
|
||||
else
|
||||
let size = max([delay_on + delay_off, 1])
|
||||
return ((offset % size) < delay_on)? 0 : 1
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" read code (what == 0) or wide (what != 0)
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.read_data(pos, width, what)
|
||||
let x = a:pos
|
||||
let w = a:width
|
||||
let size = self.size
|
||||
if x < 0
|
||||
let w += x
|
||||
let x = 0
|
||||
endif
|
||||
if x + w > size
|
||||
let w = size - x
|
||||
endif
|
||||
if x >= size || w <= 0
|
||||
return []
|
||||
endif
|
||||
let data = (a:what == 0)? self.code : self.wide
|
||||
return s:list_slice(data, x, x + w)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" calculate available view port size, give length in display-width,
|
||||
" returns how many characters can fit in length.
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.avail(pos, length)
|
||||
let length = a:length
|
||||
let size = self.size
|
||||
let wide = self.wide
|
||||
let pos = a:pos
|
||||
let sum = 0
|
||||
if length == 0
|
||||
return 0
|
||||
elseif length > 0
|
||||
while 1
|
||||
let char_width = (pos >= 0 && pos < size)? wide[pos] : 1
|
||||
" echo 'pos=' . pos . ' char_width=' . char_width
|
||||
let sum += char_width
|
||||
if sum > length
|
||||
break
|
||||
endif
|
||||
let pos += 1
|
||||
endwhile
|
||||
return pos - a:pos
|
||||
else
|
||||
let length = -length
|
||||
while 1
|
||||
let char_width = (pos >= 0 && pos < size)? wide[pos] : 1
|
||||
let sum += char_width
|
||||
if sum > length
|
||||
break
|
||||
endif
|
||||
let pos -= 1
|
||||
endwhile
|
||||
return a:pos - pos
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" return display width
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.width(start, endup) abort
|
||||
let wide = self.wide
|
||||
let acc = 0
|
||||
let pos = a:start
|
||||
let end = a:endup
|
||||
while pos < end
|
||||
let acc += wide[pos]
|
||||
let pos += 1
|
||||
endwhile
|
||||
return acc
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" display: returns a list of text string with attributes
|
||||
" eg. the readline buffer is "Hello, World !!" and cursor is on "W"
|
||||
" the returns value should be:
|
||||
" [(0, "Hello, "), (1, "W"), (0, "orld !!")]
|
||||
" avail attributes: 0/normal-text, 1/cursor, 2/visual, 3/visual+cursor
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.display() abort
|
||||
let size = self.size
|
||||
let cursor = self.cursor
|
||||
let codes = self.code
|
||||
let display = []
|
||||
if (self.select < 0) || (self.select == cursor)
|
||||
" content before cursor
|
||||
if cursor > 0
|
||||
let code = s:list_slice(codes, 0, cursor)
|
||||
let display += [[0, list2str(code)]]
|
||||
endif
|
||||
" content on cursor
|
||||
let code = (cursor < size)? codes[cursor] : char2nr(' ')
|
||||
let display += [[1, list2str([code])]]
|
||||
" content after cursor
|
||||
if cursor + 1 < size
|
||||
let code = s:list_slice(codes, cursor + 1, size)
|
||||
let display += [[0, list2str(code)]]
|
||||
endif
|
||||
else
|
||||
let vis_start = (cursor < self.select)? cursor : self.select
|
||||
let vis_endup = (cursor > self.select)? cursor : self.select
|
||||
" content befor visual selection
|
||||
if vis_start > 0
|
||||
let code = s:list_slice(codes, 0, vis_start)
|
||||
let display += [[0, list2str(code)]]
|
||||
endif
|
||||
" content in visual selection
|
||||
if cursor < self.select
|
||||
let code = [codes[cursor]]
|
||||
let display += [[3, list2str(code)]]
|
||||
let code = s:list_slice(codes, cursor + 1, vis_endup)
|
||||
let display += [[2, list2str(code)]]
|
||||
if vis_endup < size
|
||||
let code = s:list_slice(codes, vis_endup, size)
|
||||
let display += [[0, list2str(code)]]
|
||||
endif
|
||||
else
|
||||
" visual selection
|
||||
let code = s:list_slice(codes, vis_start, vis_endup)
|
||||
let display += [[2, list2str(code)]]
|
||||
" content on cursor
|
||||
let code = (cursor < size)? codes[cursor] : char2nr(' ')
|
||||
let display += [[1, list2str([code])]]
|
||||
" content after cursor
|
||||
if cursor + 1 < size
|
||||
let code = s:list_slice(codes, cursor + 1, size)
|
||||
let display += [[0, list2str(code)]]
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
return display
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" filter display list with a window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.window(display, start, endup) abort
|
||||
let start = a:start
|
||||
let endup = a:endup
|
||||
let display = []
|
||||
if start < 0
|
||||
let avail = endup - start
|
||||
let avail = min([avail, -start])
|
||||
if avail > 0
|
||||
let display += [[0, repeat(' ', avail)]]
|
||||
endif
|
||||
let start += avail
|
||||
endif
|
||||
if start >= endup
|
||||
return display
|
||||
endif
|
||||
let pos = 0
|
||||
for item in a:display
|
||||
let attribute = item[0]
|
||||
let text = item[1]
|
||||
let chars = strchars(text)
|
||||
let open = pos
|
||||
let close = open + chars
|
||||
if close > start && open < endup
|
||||
let open = max([open, start])
|
||||
let open = min([open, endup])
|
||||
let close = max([close, start])
|
||||
let close = min([close, endup])
|
||||
if open < close
|
||||
if open == pos && close == open + chars
|
||||
let display += [[attribute, text]]
|
||||
else
|
||||
let text = strcharpart(text, open - pos, close - open)
|
||||
let display += [[attribute, text]]
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let pos += chars
|
||||
endfor
|
||||
if pos < endup
|
||||
let display += [[0, repeat(' ', endup - pos)]]
|
||||
endif
|
||||
return display
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" returns new window pos to fit in
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.slide(window_pos, display_width)
|
||||
let window_pos = a:window_pos
|
||||
let display_width = a:display_width
|
||||
let cursor = self.cursor
|
||||
if display_width < 1
|
||||
return cursor
|
||||
elseif cursor < window_pos
|
||||
return cursor
|
||||
endif
|
||||
let window_pos = (window_pos < 0)? 0 : window_pos
|
||||
let wides = self.read_data(window_pos, cursor - window_pos, 1)
|
||||
if s:has_nvim == 0
|
||||
let width = reduce(wides, { acc, val -> acc + val }, 0) + 1
|
||||
else
|
||||
let width = 1
|
||||
for w in wides
|
||||
let width += w
|
||||
endfor
|
||||
endif
|
||||
if width <= display_width
|
||||
return window_pos
|
||||
else
|
||||
let avail = self.avail(cursor, -display_width)
|
||||
let pos = cursor - avail + 1
|
||||
return max([pos, 0])
|
||||
endif
|
||||
return window_pos
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" render a window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.render(pos, display_width)
|
||||
let nchars = self.avail(a:pos, a:display_width)
|
||||
let display = self.display()
|
||||
let display = self.window(display, a:pos, a:pos + nchars)
|
||||
let total = 0
|
||||
for [attr, text] in display
|
||||
let total += strwidth(text)
|
||||
endfor
|
||||
if total < a:display_width
|
||||
let attr = 0
|
||||
if self.cursor == a:pos + nchars
|
||||
let attr = 1
|
||||
if self.select >= 0
|
||||
let attr = (self.cursor < self.select)? 3 : 1
|
||||
endif
|
||||
else
|
||||
if self.select > a:pos + nchars
|
||||
let attr = (self.cursor < a:pos + nchars)? 2 : 0
|
||||
endif
|
||||
endif
|
||||
let display += [[attr, repeat(' ', a:display_width - total)]]
|
||||
endif
|
||||
return display
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" calculate mouse click position
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.mouse_click(winpos, offset)
|
||||
let index = self.avail(a:winpos, a:offset) + a:winpos
|
||||
return (index > self.size)? self.size : index
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" save history in current position
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.history_save() abort
|
||||
let size = len(self.history)
|
||||
if size > 0
|
||||
let self.index = (self.index < 0)? 0 : self.index
|
||||
let self.index = (self.index >= size)? (size - 1) : self.index
|
||||
if self.dirty
|
||||
call self.update()
|
||||
endif
|
||||
let self.history[self.index] = self.text
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" previous history
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.history_prev() abort
|
||||
let size = len(self.history)
|
||||
if size > 0
|
||||
call self.history_save()
|
||||
let self.index = (self.index < size - 1)? (self.index + 1) : 0
|
||||
call self.set(self.history[self.index])
|
||||
call self.update()
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" next history
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.history_next() abort
|
||||
let size = len(self.history)
|
||||
if size > 0
|
||||
call self.history_save()
|
||||
let self.index = (self.index <= 0)? (size - 1) : (self.index - 1)
|
||||
call self.set(self.history[self.index])
|
||||
call self.update()
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" init history
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.history_init(history) abort
|
||||
if len(a:history) == 0
|
||||
let self.history = []
|
||||
let self.index = 0
|
||||
else
|
||||
let history = deepcopy(a:history) + ['']
|
||||
call reverse(history)
|
||||
let self.history = history
|
||||
let self.index = 0
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" feed character
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.feed(char) abort
|
||||
let char = a:char
|
||||
let code = str2list(char)
|
||||
let head = len(code)? code[0] : 0
|
||||
if head < 0x20 || head == 0x80
|
||||
if char == "\<BS>"
|
||||
if self.select >= 0
|
||||
call self.visual_delete()
|
||||
else
|
||||
call self.backspace(1)
|
||||
endif
|
||||
elseif char == "\<DELETE>"
|
||||
if self.select >= 0
|
||||
call self.visual_delete()
|
||||
else
|
||||
call self.delete(1)
|
||||
endif
|
||||
elseif char == "\<LEFT>" || char == "\<c-b>"
|
||||
if self.select >= 0
|
||||
call self.move(min([self.select, self.cursor]))
|
||||
let self.select = -1
|
||||
else
|
||||
call self.seek(-1, 1)
|
||||
endif
|
||||
elseif char == "\<RIGHT>" || char == "\<c-f>"
|
||||
if self.select >= 0
|
||||
call self.move(max([self.select, self.cursor]))
|
||||
let self.select = -1
|
||||
else
|
||||
call self.seek(1, 1)
|
||||
endif
|
||||
elseif char == "\<UP>"
|
||||
call self.history_prev()
|
||||
let self.select = -1
|
||||
elseif char == "\<DOWN>"
|
||||
call self.history_next()
|
||||
let self.select = -1
|
||||
elseif char == "\<S-Left>"
|
||||
if self.select < 0
|
||||
let self.select = self.cursor
|
||||
endif
|
||||
call self.seek(-1, 1)
|
||||
elseif char == "\<S-Right>"
|
||||
if self.select < 0
|
||||
let self.select = self.cursor
|
||||
endif
|
||||
call self.seek(1, 1)
|
||||
elseif char == "\<S-Home>"
|
||||
if self.select < 0
|
||||
let self.select = self.cursor
|
||||
endif
|
||||
call self.seek(0, 0)
|
||||
elseif char == "\<S-End>"
|
||||
if self.select < 0
|
||||
let self.select = self.cursor
|
||||
endif
|
||||
call self.seek(0, 2)
|
||||
elseif char == "\<c-d>"
|
||||
if self.select >= 0
|
||||
call self.visual_delete()
|
||||
else
|
||||
call self.delete(1)
|
||||
endif
|
||||
elseif char == "\<c-k>"
|
||||
if self.select >= 0
|
||||
call self.visual_delete()
|
||||
else
|
||||
if self.size > self.cursor
|
||||
call self.delete(self.size - self.cursor)
|
||||
endif
|
||||
endif
|
||||
elseif char == "\<home>" || char == "\<c-a>"
|
||||
call self.move(0)
|
||||
let self.select = -1
|
||||
elseif char == "\<end>" || char == "\<c-e>"
|
||||
call self.move(self.size)
|
||||
let self.select = -1
|
||||
elseif char == "\<C-Insert>"
|
||||
if self.select >= 0
|
||||
let text = self.visual_text()
|
||||
if text != ''
|
||||
let @* = text
|
||||
endif
|
||||
endif
|
||||
elseif char == "\<S-Insert>"
|
||||
let text = split(@*, "\n", 1)[0]
|
||||
let text = substitute(text, '[\r\n\t]', ' ', 'g')
|
||||
if text != ''
|
||||
if self.select >= 0
|
||||
call self.visual_delete()
|
||||
endif
|
||||
call self.insert(text)
|
||||
endif
|
||||
elseif char == "\<c-w>"
|
||||
if self.select < 0
|
||||
let head = self.extract(-1)
|
||||
let word = matchstr(head, '\S\+\s*$')
|
||||
if word != ''
|
||||
call self.backspace(strchars(word))
|
||||
endif
|
||||
else
|
||||
call self.visual_delete()
|
||||
endif
|
||||
elseif char == "\<c-c>"
|
||||
if self.select >= 0
|
||||
let text = self.visual_text()
|
||||
if text != ''
|
||||
let @0 = text
|
||||
endif
|
||||
endif
|
||||
elseif char == "\<c-x>"
|
||||
if self.select >= 0
|
||||
let text = self.visual_text()
|
||||
if text != ''
|
||||
let @0 = text
|
||||
call self.visual_delete()
|
||||
endif
|
||||
endif
|
||||
elseif char == "\<c-v>"
|
||||
let text = split(@0, "\n", 1)[0]
|
||||
let text = substitute(text, '[\r\n\t]', ' ', 'g')
|
||||
if text != ''
|
||||
if self.select >= 0
|
||||
call self.visual_delete()
|
||||
endif
|
||||
call self.insert(text)
|
||||
endif
|
||||
else
|
||||
return -1
|
||||
endif
|
||||
return 0
|
||||
else
|
||||
if self.select >= 0
|
||||
call self.visual_delete()
|
||||
endif
|
||||
call self.insert(char)
|
||||
endif
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" display parts
|
||||
"----------------------------------------------------------------------
|
||||
function! s:readline.echo(blink, ...)
|
||||
if a:0 < 2
|
||||
let display = self.render(0, self.size * 4)
|
||||
else
|
||||
let display = self.render(a:1, a:2)
|
||||
endif
|
||||
for [attr, text] in display
|
||||
if attr == 0
|
||||
echohl Normal
|
||||
elseif attr == 1
|
||||
if a:blink == 0
|
||||
echohl Cursor
|
||||
else
|
||||
echohl Normal
|
||||
endif
|
||||
elseif attr == 2
|
||||
echohl Visual
|
||||
elseif attr == 3
|
||||
if a:blink == 0
|
||||
echohl Cursor
|
||||
else
|
||||
echohl Visual
|
||||
endif
|
||||
endif
|
||||
echon text
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" constructor
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#readline#new()
|
||||
let obj = deepcopy(s:readline)
|
||||
return obj
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" test suit
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#readline#test()
|
||||
let v:errors = []
|
||||
let obj = quickui#readline#new()
|
||||
call obj.set('0123456789')
|
||||
call assert_equal('0123456789', obj.update(), 'test set')
|
||||
call obj.insert('ABC')
|
||||
call assert_equal('ABC0123456789', obj.update(), 'test insert')
|
||||
call obj.delete(3)
|
||||
call assert_equal('ABC3456789', obj.update(), 'test delete')
|
||||
call obj.backspace(2)
|
||||
call assert_equal('A3456789', obj.update(), 'test backspace')
|
||||
call obj.delete(1000)
|
||||
call assert_equal('A', obj.update(), 'test kill right')
|
||||
call obj.insert('BCD')
|
||||
call assert_equal('ABCD', obj.update(), 'test append')
|
||||
call obj.delete(1000)
|
||||
call assert_equal('ABCD', obj.update(), 'test append')
|
||||
call obj.backspace(1000)
|
||||
call assert_equal('', obj.update(), 'test append')
|
||||
call obj.insert('0123456789')
|
||||
call assert_equal('0123456789', obj.update(), 'test reinit')
|
||||
call obj.move(3)
|
||||
call obj.replace('abcd')
|
||||
call assert_equal('012abcd789', obj.update(), 'test replace')
|
||||
let obj.select = obj.cursor
|
||||
call obj.seek(-2, 1)
|
||||
call obj.visual_delete()
|
||||
call assert_equal('012ab789', obj.update(), 'test visual delete')
|
||||
let obj.select = obj.cursor
|
||||
call obj.seek(2, 1)
|
||||
echo obj.display()
|
||||
call assert_equal('78', obj.visual_text(), 'test visual selection')
|
||||
call obj.visual_delete()
|
||||
call assert_equal('012ab9', obj.update(), 'test visual delete2')
|
||||
call obj.seek(-2, 1)
|
||||
if len(v:errors)
|
||||
for error in v:errors
|
||||
echoerr error
|
||||
endfor
|
||||
endif
|
||||
call obj.move(1)
|
||||
let obj.select = 4
|
||||
echo obj.display()
|
||||
return obj.update()
|
||||
endfunc
|
||||
|
||||
" echo quickui#readline#test()
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" cli test
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#readline#cli(prompt)
|
||||
let rl = quickui#readline#new()
|
||||
let rl.history = ['', 'abcd', '12345']
|
||||
let index = 0
|
||||
let accept = ''
|
||||
let pos = 0
|
||||
while 1
|
||||
noautocmd redraw
|
||||
echohl Question
|
||||
echon a:prompt
|
||||
let ts = float2nr(reltimefloat(reltime()) * 1000)
|
||||
if 0
|
||||
call rl.echo(rl.blink(ts))
|
||||
else
|
||||
let size = 10
|
||||
let pos = rl.slide(pos, size)
|
||||
echohl Title
|
||||
echon "<"
|
||||
call rl.echo(rl.blink(ts), pos, size)
|
||||
echohl Title
|
||||
echon ">"
|
||||
echon " size=" . size
|
||||
echon " cursor=" . rl.cursor
|
||||
echon " pos=". pos
|
||||
echon " blink=". rl.blink(ts)
|
||||
echon " avail=". rl.avail(pos, size)
|
||||
endif
|
||||
" echon rl.display()
|
||||
try
|
||||
let code = getchar()
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<c-c>"
|
||||
endtry
|
||||
if type(code) == v:t_number && code == 0
|
||||
try
|
||||
exec 'sleep 15m'
|
||||
continue
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<c-c>"
|
||||
endtry
|
||||
endif
|
||||
let ch = (type(code) == v:t_number)? nr2char(code) : code
|
||||
if ch == ""
|
||||
continue
|
||||
elseif ch == "\<ESC>"
|
||||
break
|
||||
elseif ch == "\<cr>"
|
||||
let accept = rl.update()
|
||||
break
|
||||
else
|
||||
call rl.feed(ch)
|
||||
endif
|
||||
endwhile
|
||||
echohl None
|
||||
noautocmd redraw
|
||||
echo ""
|
||||
return accept
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" testing suit
|
||||
"----------------------------------------------------------------------
|
||||
if 0
|
||||
let suit = 0
|
||||
if suit == 0
|
||||
call quickui#readline#test()
|
||||
elseif suit == 1
|
||||
let rl = quickui#readline#new()
|
||||
call rl.insert('abad')
|
||||
echo rl.mouse_click(0, 5)
|
||||
elseif suit == 2
|
||||
echo quickui#readline#cli(">>> ")
|
||||
elseif suit == 3
|
||||
let rl = quickui#readline#new()
|
||||
let size = 10
|
||||
echo "avail=" . rl.avail(0, size)
|
||||
call rl.insert("hello")
|
||||
echo "cursor=" . rl.cursor
|
||||
echo "avail=" . rl.avail(0, size)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
22
vim/.vim/autoload/quickui/style.vim
Normal file
22
vim/.vim/autoload/quickui/style.vim
Normal file
@ -0,0 +1,22 @@
|
||||
"======================================================================
|
||||
"
|
||||
" style.vim -
|
||||
"
|
||||
" Created by skywind on 2019/12/19
|
||||
" Last Modified: 2019/12/19 16:06:59
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" default border style: 1/ascii, 2/single, 3/double
|
||||
"----------------------------------------------------------------------
|
||||
let g:quickui#style#border = get(g:, 'quickui#style#border', 1)
|
||||
|
||||
let g:quickui#style#tip_head = '[tip]'
|
||||
|
||||
let g:quickui#style#preview_w = 85
|
||||
let g:quickui#style#preview_h = 10
|
||||
let g:quickui#style#preview_number = 1
|
||||
let g:quickui#style#preview_bordercolor = ''
|
||||
|
||||
|
340
vim/.vim/autoload/quickui/terminal.vim
Normal file
340
vim/.vim/autoload/quickui/terminal.vim
Normal file
@ -0,0 +1,340 @@
|
||||
"======================================================================
|
||||
"
|
||||
" terminal.vim -
|
||||
"
|
||||
" Created by skywind on 2020/02/03
|
||||
" Last Modified: 2020/02/03 10:31:33
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" terminal return
|
||||
"----------------------------------------------------------------------
|
||||
let g:quickui#terminal#capture = []
|
||||
let g:quickui#terminal#tmpname = ''
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create a terminal popup
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#terminal#create(cmd, opts)
|
||||
let w = get(a:opts, 'w', 80)
|
||||
let h = get(a:opts, 'h', 24)
|
||||
let winid = -1
|
||||
let title = has_key(a:opts, 'title')? (' ' . a:opts.title .' ') : ''
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
let button = (get(a:opts, 'close', '') == 'button')? 1 : 0
|
||||
let color = get(a:opts, 'color', 'QuickTermBorder')
|
||||
let ww = w + ((border != 0)? 2 : 0)
|
||||
let hh = h + ((border != 0)? 2 : 0)
|
||||
let hwnd = {'opts':deepcopy(a:opts), 'code':-1}
|
||||
if !has_key(hwnd.opts, 'line')
|
||||
let limit1 = (&lines - 2) * 90 / 100
|
||||
let limit2 = (&lines - 2)
|
||||
if h + 4 < limit1
|
||||
let hwnd.opts.line = (limit1 - hh) / 2
|
||||
else
|
||||
let hwnd.opts.line = (limit2 - hh) / 2
|
||||
endif
|
||||
let hwnd.opts.line = (hwnd.opts.line < 1)? 1 : hwnd.opts.line
|
||||
endif
|
||||
if !has_key(hwnd.opts, 'col')
|
||||
let hwnd.opts.col = (&columns - ww) / 2
|
||||
let hwnd.opts.col = (hwnd.opts.col < 1)? 1 : hwnd.opts.col
|
||||
endif
|
||||
if has('nvim') == 0
|
||||
let opts = {'hidden': 1, 'term_rows':h, 'term_cols':w}
|
||||
let opts.term_kill = get(a:opts, 'term_kill', 'term')
|
||||
let opts.norestore = 1
|
||||
let opts.exit_cb = function('s:vim_term_exit')
|
||||
let opts.term_finish = 'close'
|
||||
let savedir = getcwd()
|
||||
if has_key(a:opts, 'cwd')
|
||||
call quickui#core#chdir(a:opts.cwd)
|
||||
endif
|
||||
let bid = term_start(a:cmd, opts)
|
||||
if has_key(a:opts, 'cwd')
|
||||
call quickui#core#chdir(savedir)
|
||||
endif
|
||||
if bid <= 0
|
||||
return -1
|
||||
endif
|
||||
let opts = {'maxwidth':w, 'maxheight':h, 'minwidth':w, 'minheight':h}
|
||||
let opts.wrap = 0
|
||||
let opts.mapping = 0
|
||||
let opts.title = title
|
||||
let opts.close = (button)? 'button' : 'none'
|
||||
let opts.border = border? [1,1,1,1,1,1,1,1,1] : repeat([0], 9)
|
||||
let opts.highlight = color
|
||||
let opts.borderchars = quickui#core#border_vim(border)
|
||||
let opts.drag = get(a:opts, 'drag', 1)
|
||||
let opts.resize = 0
|
||||
let opts.callback = function('s:vim_popup_callback')
|
||||
let winid = popup_create(bid, opts)
|
||||
call popup_move(winid, {'line':hwnd.opts.line, 'col':hwnd.opts.col})
|
||||
let hwnd.winid = winid
|
||||
let g:quickui#terminal#current = hwnd
|
||||
let s:current = hwnd
|
||||
call popup_show(winid)
|
||||
let init = []
|
||||
let init += ['setlocal nonumber norelativenumber scrolloff=0']
|
||||
let init += ['setlocal signcolumn=no']
|
||||
let init += ['setlocal bufhidden=wipe']
|
||||
call quickui#core#win_execute(winid, init)
|
||||
else
|
||||
let bid = quickui#core#scratch_buffer('terminal', [])
|
||||
let opts = {'focusable':1, 'style':'minimal', 'relative':'editor'}
|
||||
let opts.width = w
|
||||
let opts.height = h
|
||||
let opts.row = hwnd.opts.line - 1 + ((border > 0)? 1 : 0)
|
||||
let opts.col = hwnd.opts.col - 1 + ((border > 0)? 1 : 0)
|
||||
if has('nvim-0.6.0')
|
||||
let opts.noautocmd = 1
|
||||
endif
|
||||
let winid = nvim_open_win(bid, 1, opts)
|
||||
let hwnd.winid = winid
|
||||
let hwnd.background = -1
|
||||
if winid < 0
|
||||
return -1
|
||||
endif
|
||||
let cc = get(g:, 'terminal_color_0', 0)
|
||||
let hl = 'Normal:'.cc.',NonText:'.cc.',EndOfBuffer:'.cc
|
||||
" silent! call nvim_win_set_option(winid, 'winhl', hl)
|
||||
call setwinvar(winid, '&winhighlight', 'NormalFloat:Normal')
|
||||
if border > 0
|
||||
let title = has_key(a:opts, 'title')? ' ' . a:opts.title . ' ':''
|
||||
let back = quickui#utils#make_border(w, h, border, title, button)
|
||||
let nbid = quickui#core#scratch_buffer('terminalborder', back)
|
||||
let op = {'relative':'editor', 'focusable':0, 'style':'minimal'}
|
||||
let op.width = w + 2
|
||||
let op.height = h + 2
|
||||
let pos = nvim_win_get_config(winid)
|
||||
let op.row = hwnd.opts.line - 1
|
||||
let op.col = hwnd.opts.col - 1
|
||||
if has('nvim-0.6.0')
|
||||
let op.noautocmd = 1
|
||||
endif
|
||||
let background = nvim_open_win(nbid, 0, op)
|
||||
call nvim_win_set_option(background, 'winhl', 'Normal:'. color)
|
||||
let hwnd.background = background
|
||||
endif
|
||||
call nvim_set_current_win(winid)
|
||||
setlocal nomodified
|
||||
let opts = {'width': w, 'height':h}
|
||||
let opts.on_exit = function('s:nvim_term_exit')
|
||||
if has_key(a:opts, 'cwd')
|
||||
let opts.cwd = a:opts.cwd
|
||||
endif
|
||||
call termopen(a:cmd, opts)
|
||||
let g:quickui#terminal#current = hwnd
|
||||
let s:current = hwnd
|
||||
let init = []
|
||||
let init += ['setlocal nonumber norelativenumber scrolloff=0']
|
||||
let init += ['setlocal signcolumn=no']
|
||||
let init += ['setlocal bufhidden=wipe']
|
||||
call quickui#core#win_execute(winid, init)
|
||||
startinsert
|
||||
endif
|
||||
return hwnd
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" read back capture
|
||||
"----------------------------------------------------------------------
|
||||
function! s:capture_read()
|
||||
let g:quickui#terminal#capture = []
|
||||
if g:quickui#terminal#tmpname != ''
|
||||
let tmpname = g:quickui#terminal#tmpname
|
||||
let g:quickui#terminal#tmpname = ''
|
||||
if filereadable(tmpname)
|
||||
silent! let g:quickui#terminal#capture = readfile(tmpname)
|
||||
call delete(tmpname)
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" terminal exit_cb
|
||||
"----------------------------------------------------------------------
|
||||
function! s:vim_term_exit(job, message)
|
||||
if exists('s:current')
|
||||
let hwnd = s:current
|
||||
let hwnd.code = a:message
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" popup callback
|
||||
"----------------------------------------------------------------------
|
||||
function! s:vim_popup_callback(winid, code)
|
||||
if exists('s:current')
|
||||
let hwnd = s:current
|
||||
let hwnd.winid = -1
|
||||
call s:capture_read()
|
||||
if has_key(hwnd.opts, 'callback')
|
||||
call call(hwnd.opts.callback, [hwnd.code])
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" neovim exit
|
||||
"----------------------------------------------------------------------
|
||||
function! s:nvim_term_exit(jobid, data, event)
|
||||
if exists('s:current')
|
||||
let hwnd = s:current
|
||||
let hwnd.code = a:data
|
||||
if hwnd.winid >= 0
|
||||
call nvim_win_close(hwnd.winid, 0)
|
||||
endif
|
||||
if hwnd.background >= 0
|
||||
call nvim_win_close(hwnd.background, 0)
|
||||
endif
|
||||
let hwnd.winid = -1
|
||||
let hwnd.background = -1
|
||||
call s:capture_read()
|
||||
if has_key(hwnd.opts, 'callback')
|
||||
call call(hwnd.opts.callback, [hwnd.code])
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" open terminal in popup window
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#terminal#open(cmd, opts)
|
||||
let opts = deepcopy(a:opts)
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
if border == 0
|
||||
if has_key(opts, 'title')
|
||||
unlet opts['title']
|
||||
endif
|
||||
if has_key(opts, 'close')
|
||||
unlet opts['close']
|
||||
endif
|
||||
endif
|
||||
if has_key(opts, 'callback')
|
||||
if type(opts.callback) == v:t_string
|
||||
if opts.callback == ''
|
||||
unlet opts['callback']
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if has_key(opts, 'w')
|
||||
let opts.w = quickui#utils#read_size(opts.w, &columns)
|
||||
endif
|
||||
if has_key(opts, 'h')
|
||||
let opts.h = quickui#utils#read_size(opts.h, &lines)
|
||||
endif
|
||||
let g:quickui#terminal#capture = []
|
||||
let g:quickui#terminal#tmpname = ''
|
||||
let $VIM_INPUT = ''
|
||||
let $VIM_CAPTURE = ''
|
||||
if has_key(opts, 'input')
|
||||
if has('win32') || has('win64') || has('win95') || has('win16')
|
||||
let tmpname = fnamemodify(tempname(), ':h') . '\quickui1.txt'
|
||||
else
|
||||
let tmpname = fnamemodify(tempname(), ':h') . '/quickui1.txt'
|
||||
endif
|
||||
call writefile(opts.input, tmpname)
|
||||
let $VIM_INPUT = tmpname
|
||||
endif
|
||||
if has_key(opts, 'capture')
|
||||
if opts.capture
|
||||
if has('win32') || has('win64') || has('win95') || has('win16')
|
||||
let tmpname = fnamemodify(tempname(), ':h') . '\quickui2.txt'
|
||||
else
|
||||
let tmpname = fnamemodify(tempname(), ':h') . '/quickui2.txt'
|
||||
endif
|
||||
let g:quickui#terminal#tmpname = tmpname
|
||||
let $VIM_CAPTURE = tmpname
|
||||
if filereadable(tmpname)
|
||||
call delete(tmpname)
|
||||
endif
|
||||
endif
|
||||
unlet opts['capture']
|
||||
endif
|
||||
return quickui#terminal#create(a:cmd, opts)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" dialog exit
|
||||
"----------------------------------------------------------------------
|
||||
function! s:dialog_callback(code)
|
||||
let args = {}
|
||||
let args.code = a:code
|
||||
let args.capture = g:quickui#terminal#capture
|
||||
call call(s:dialog_cb, [args])
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" dialog: run command line tool and capture result
|
||||
" the callback function changes to a new prototype:
|
||||
" function! Callback(args), where args is a tuple of (code, capture)
|
||||
" where capture is a list of text lines in the $VIM_CAPTURE file
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#terminal#dialog(cmd, opts)
|
||||
let opts = deepcopy(a:opts)
|
||||
let opts.macros = quickui#core#expand_macros()
|
||||
if has_key(opts, 'prepare')
|
||||
call call(opts.prepare, [opts])
|
||||
endif
|
||||
let command = a:cmd
|
||||
for [key, val] in items(opts.macros)
|
||||
let replace = (key[0] != '<')? '$('.key.')' : key
|
||||
if key[0] != '<'
|
||||
exec 'let $' . key . ' = val'
|
||||
endif
|
||||
let command = quickui#core#string_replace(command, replace, val)
|
||||
if has_key(opts, 'cwd')
|
||||
let opts.cwd = quickui#core#string_replace(opts.cwd, replace, val)
|
||||
endif
|
||||
endfor
|
||||
let cwd = get(opts, 'cwd', '')
|
||||
if cwd != ''
|
||||
let previous = getcwd()
|
||||
call quickui#core#chdir(cwd)
|
||||
let opts.macros['VIM_CWD'] = getcwd()
|
||||
let opts.macros['VIM_RELDIR'] = expand("%:h:.")
|
||||
let opts.macros['VIM_RELNAME'] = expand("%:p:.")
|
||||
let opts.macros['VIM_CFILE'] = expand("<cfile>")
|
||||
let opts.macros['VIM_DIRNAME'] = fnamemodify(opts.macros['VIM_CWD'], ':t')
|
||||
let opts.macros['<cwd>'] = opts.macros['VIM_CWD']
|
||||
call quickui#core#chdir(previous)
|
||||
endif
|
||||
let pause = get(opts, 'pause', 0)
|
||||
let command = quickui#core#write_script(command, pause)
|
||||
if has_key(opts, 'callback')
|
||||
let l:F2 = opts.callback
|
||||
if type(l:F2) == v:t_string
|
||||
if l:F2 != ''
|
||||
let s:dialog_cb = function(l:F2)
|
||||
let opts.callback = function('s:dialog_callback')
|
||||
let opts.capture = 1
|
||||
endif
|
||||
elseif type(l:F2) == v:t_func
|
||||
let s:dialog_cb = function(l:F2)
|
||||
let opts.callback = function('s:dialog_callback')
|
||||
let opts.capture = 1
|
||||
endif
|
||||
unlet l:F2
|
||||
endif
|
||||
if has_key(opts, 'cwd')
|
||||
if opts.cwd == ''
|
||||
unlet opts['cwd']
|
||||
endif
|
||||
endif
|
||||
return quickui#terminal#open(command, opts)
|
||||
endfunc
|
||||
|
||||
|
452
vim/.vim/autoload/quickui/textbox.vim
Normal file
452
vim/.vim/autoload/quickui/textbox.vim
Normal file
@ -0,0 +1,452 @@
|
||||
"======================================================================
|
||||
"
|
||||
" textbox.vim -
|
||||
"
|
||||
" Created by skywind on 2019/12/27
|
||||
" Last Modified: 2020/02/20 02:29
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" reposition
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#textbox#reposition()
|
||||
let curline = line('.')
|
||||
exec 'normal! zz'
|
||||
let height = winheight(0)
|
||||
let moveup = winline() - 1
|
||||
if moveup > 0
|
||||
exec "normal " . moveup . "\<c-e>"
|
||||
exec ":" . curline
|
||||
endif
|
||||
let size = line('$')
|
||||
let winline = winline()
|
||||
let topline = curline - winline + 1
|
||||
let botline = topline + height - 1
|
||||
let disline = botline - size
|
||||
if disline > 0
|
||||
exec 'normal ggG'
|
||||
exec ':' . curline
|
||||
exec 'normal G'
|
||||
exec ':' . curline
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create textbox
|
||||
"----------------------------------------------------------------------
|
||||
function! s:vim_create_textbox(textlist, opts)
|
||||
let winid = popup_create(a:textlist, {'hidden':1, 'wrap':1})
|
||||
let opts = {}
|
||||
let opts.maxheight = &lines - 2
|
||||
let opts.maxwidth = &columns
|
||||
if has_key(a:opts, 'w')
|
||||
let opts.minwidth = a:opts.w
|
||||
let opts.maxwidth = a:opts.w
|
||||
endif
|
||||
if has_key(a:opts, 'h')
|
||||
let opts.minheight = a:opts.h
|
||||
let opts.maxheight = a:opts.h
|
||||
endif
|
||||
if has_key(a:opts, 'line') && has_key(a:opts, 'col')
|
||||
let opts.line = a:opts.line
|
||||
let opts.col = a:opts.col
|
||||
endif
|
||||
if len(opts) > 0
|
||||
call popup_move(winid, opts)
|
||||
endif
|
||||
if has_key(a:opts, 'line') == 0 || has_key(a:opts, 'col') == 0
|
||||
call quickui#utils#center(winid)
|
||||
endif
|
||||
let opts = {'mapping':0, 'cursorline':0, 'drag':1}
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
let opts.border = [0,0,0,0,0,0,0,0,0]
|
||||
if border > 0
|
||||
let opts.borderchars = quickui#core#border_vim(border)
|
||||
let opts.border = [1,1,1,1,1,1,1,1,1]
|
||||
let opts.close = 'button'
|
||||
endif
|
||||
let opts.padding = [0,1,0,1]
|
||||
if has_key(a:opts, 'title') && (a:opts.title != '')
|
||||
let opts.title = ' '. a:opts.title . ' '
|
||||
endif
|
||||
let opts.filter = function('s:popup_filter')
|
||||
let opts.callback = function('s:popup_exit')
|
||||
let opts.resize = get(a:opts, 'resize', 0)
|
||||
let opts.highlight = get(a:opts, 'color', 'QuickBG')
|
||||
if has_key(a:opts, 'index')
|
||||
let index = (a:opts.index < 1)? 1 : a:opts.index
|
||||
let opts.firstline = index
|
||||
call win_execute(winid, ':' . index)
|
||||
endif
|
||||
let local = quickui#core#popup_local(winid)
|
||||
let local.winid = winid
|
||||
let local.keymap = quickui#utils#keymap()
|
||||
let local.keymap['x'] = 'ESC'
|
||||
let local.opts = deepcopy(a:opts)
|
||||
if has_key(a:opts, 'callback')
|
||||
let local.callback = a:opts.callback
|
||||
endif
|
||||
if has_key(a:opts, 'list')
|
||||
if a:opts.list
|
||||
call win_execute(winid, 'setl list')
|
||||
else
|
||||
call win_execute(winid, 'setl nolist')
|
||||
endif
|
||||
endif
|
||||
let bc = get(a:opts, 'bordercolor', 'QuickBorder')
|
||||
let opts.borderhighlight = [bc, bc, bc, bc]
|
||||
if has_key(a:opts, 'tabstop')
|
||||
call win_execute(winid, 'setlocal tabstop=' . get(a:opts, 'tabstop', 4))
|
||||
endif
|
||||
if has_key(a:opts, 'syntax')
|
||||
call win_execute(winid, 'set ft=' . fnameescape(a:opts.syntax))
|
||||
endif
|
||||
let cursor = get(a:opts, 'cursor', -1)
|
||||
call setbufvar(winbufnr(winid), '__quickui_cursor__', cursor)
|
||||
call setbufvar(winbufnr(winid), '__quickui_line__', -1)
|
||||
if get(a:opts, 'number', 0) != 0
|
||||
call win_execute(winid, 'setlocal number')
|
||||
endif
|
||||
if cursor < 0
|
||||
call win_execute(winid, 'setlocal nocursorline')
|
||||
endif
|
||||
if has_key(a:opts, 'bordercolor')
|
||||
let c = a:opts.bordercolor
|
||||
let opts.borderhighlight = [c, c, c, c]
|
||||
endif
|
||||
call popup_setoptions(winid, opts)
|
||||
call win_execute(winid, 'setlocal scrolloff=0')
|
||||
if has_key(a:opts, 'command')
|
||||
call quickui#core#win_execute(winid, a:opts.command)
|
||||
endif
|
||||
call quickui#utils#update_cursor(winid)
|
||||
call popup_show(winid)
|
||||
redraw
|
||||
return winid
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" close textbox
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#textbox#close(winid)
|
||||
call popup_close(a:winid)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" exit and quit
|
||||
"----------------------------------------------------------------------
|
||||
function! s:popup_exit(winid, code)
|
||||
let topline = quickui#utils#get_topline(a:winid)
|
||||
let g:quickui#textbox#topline = topline
|
||||
let local = quickui#core#popup_local(a:winid)
|
||||
let g:quickui#textbox#current = local
|
||||
call quickui#core#popup_clear(a:winid)
|
||||
if has_key(local, 'callback')
|
||||
let l:F = function(local.callback)
|
||||
call l:F(topline)
|
||||
unlet l:F
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" filter
|
||||
"----------------------------------------------------------------------
|
||||
function! s:popup_filter(winid, key)
|
||||
let local = quickui#core#popup_local(a:winid)
|
||||
let keymap = local.keymap
|
||||
if a:key == "\<ESC>" || a:key == "\<C-C>" || a:key == "\<cr>"
|
||||
call popup_close(a:winid, 0)
|
||||
return 1
|
||||
elseif a:key == " " || a:key == "x" || a:key == "q"
|
||||
call popup_close(a:winid, 0)
|
||||
return 1
|
||||
elseif a:key == "\<LeftMouse>"
|
||||
let pos = getmousepos()
|
||||
if pos.winid == a:winid && pos.line > 0
|
||||
if get(local.opts, 'exit_on_click', 0) != 0
|
||||
call popup_close(a:winid, 0)
|
||||
return 1
|
||||
endif
|
||||
endif
|
||||
elseif a:key == ':' || a:key == '/' || a:key == '?'
|
||||
call quickui#utils#search_or_jump(a:winid, a:key)
|
||||
noautocmd call quickui#utils#update_cursor(a:winid)
|
||||
redraw
|
||||
return 1
|
||||
elseif has_key(keymap, a:key)
|
||||
let key = keymap[a:key]
|
||||
if key == "ENTER" || key == "ESC"
|
||||
call popup_close(a:winid, 0)
|
||||
return 1
|
||||
elseif key == 'NEXT' || key == 'PREV'
|
||||
call quickui#utils#search_next(a:winid, key)
|
||||
noautocmd call quickui#utils#update_cursor(a:winid)
|
||||
redraw
|
||||
return 1
|
||||
else
|
||||
noautocmd call quickui#utils#scroll(a:winid, key)
|
||||
redraw
|
||||
noautocmd call quickui#utils#update_cursor(a:winid)
|
||||
endif
|
||||
endif
|
||||
return popup_filter_yesno(a:winid, a:key)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create text box in neovim
|
||||
"----------------------------------------------------------------------
|
||||
function! s:nvim_create_textbox(textlist, opts)
|
||||
if type(a:textlist) == v:t_list
|
||||
let bid = quickui#core#scratch_buffer('textbox', a:textlist)
|
||||
elseif type(a:textlist) == v:t_string
|
||||
let bid = quickui#core#scratch_buffer('textbox', [a:textlist])
|
||||
elseif type(a:textlist) == v:t_number
|
||||
let bid = a:textlist
|
||||
endif
|
||||
let opts = {'focusable':1, 'style':'minimal', 'relative':'editor'}
|
||||
let opts.width = get(a:opts, 'w', 80)
|
||||
let opts.height = get(a:opts, 'h', 24)
|
||||
let opts.row = get(a:opts, 'line', 1) - 1
|
||||
let opts.col = get(a:opts, 'col', 1) - 1
|
||||
let border = get(a:opts, 'border', g:quickui#style#border)
|
||||
if border > 0 && get(g:, 'quickui_nvim_simulate_border', 1) != 0
|
||||
let opts.row += 1
|
||||
let opts.col += 1
|
||||
endif
|
||||
if has('nvim-0.6.0')
|
||||
let opts.noautocmd = 1
|
||||
endif
|
||||
let winid = nvim_open_win(bid, 0, opts)
|
||||
if has_key(a:opts, 'line') == 0 && has_key(a:opts, 'col') == 0
|
||||
call quickui#utils#center(winid)
|
||||
endif
|
||||
let color = get(a:opts, 'color', 'QuickBG')
|
||||
call nvim_win_set_option(winid, 'winhl', 'Normal:'. color)
|
||||
let opts.w = nvim_win_get_width(winid)
|
||||
let opts.h = nvim_win_get_height(winid)
|
||||
let button = (get(a:opts, 'close', '') == 'button')? 1 : 0
|
||||
let background = -1
|
||||
if border > 0 && get(g:, 'quickui_nvim_simulate_border', 1) != 0
|
||||
let title = has_key(a:opts, 'title')? ' ' . a:opts.title . ' ' : ''
|
||||
let w = opts.w
|
||||
let h = opts.h
|
||||
let back = quickui#utils#make_border(w, h, border, title, button)
|
||||
let nbid = quickui#core#scratch_buffer('textboxborder', back)
|
||||
let op = {'relative':'editor', 'focusable':1, 'style':'minimal'}
|
||||
let op.width = opts.w + 2
|
||||
let op.height = opts.h + 2
|
||||
let pos = nvim_win_get_config(winid)
|
||||
let op.row = pos.row - 1
|
||||
let op.col = pos.col - 1
|
||||
let bordercolor = get(a:opts, 'bordercolor', 'QuickBorder')
|
||||
if has('nvim-0.6.0')
|
||||
let op.noautocmd = 1
|
||||
endif
|
||||
let background = nvim_open_win(nbid, 0, op)
|
||||
call nvim_win_set_option(background, 'winhl', 'Normal:'. bordercolor)
|
||||
endif
|
||||
let init = ['syn clear']
|
||||
if has_key(a:opts, 'tabstop')
|
||||
let init += ['setlocal tabstop='. get(a:opts, 'tabstop', 4)]
|
||||
endif
|
||||
let init += ['setlocal signcolumn=no']
|
||||
let init += ['setlocal scrolloff=0']
|
||||
let init += ['setlocal wrap']
|
||||
let init += ['noautocmd exec "normal! gg"']
|
||||
if get(a:opts, 'number', 0) != 0
|
||||
let init += ['setlocal number']
|
||||
endif
|
||||
if has_key(a:opts, 'syntax')
|
||||
let init += ['set ft='.fnameescape(a:opts.syntax)]
|
||||
" echo "syntax: ". a:opts.syntax
|
||||
endif
|
||||
let cursor = get(a:opts, 'cursor', -1)
|
||||
call setbufvar(bid, '__quickui_cursor__', cursor)
|
||||
call setbufvar(bid, '__quickui_line__', -1)
|
||||
if has_key(a:opts, 'index')
|
||||
let index = (a:opts.index < 1)? 1 : a:opts.index
|
||||
let opts.firstline = index
|
||||
let init += ['noautocmd exec "normal! gg"']
|
||||
if index > 1
|
||||
let init += ['noautocmd exec "normal! '. (index - 1) . '\<c-e>"']
|
||||
endif
|
||||
endif
|
||||
call quickui#core#win_execute(winid, init)
|
||||
let highlight = 'Normal:'.color.',NonText:'.color.',EndOfBuffer:'.color
|
||||
call nvim_win_set_option(winid, 'winhl', highlight)
|
||||
if has_key(a:opts, 'command')
|
||||
call quickui#core#win_execute(winid, a:opts.command)
|
||||
endif
|
||||
noautocmd call quickui#utils#update_cursor(winid)
|
||||
let local = {}
|
||||
let local.winid = winid
|
||||
let local.keymap = quickui#utils#keymap()
|
||||
let local.keymap['x'] = 'ESC'
|
||||
let local.opts = deepcopy(a:opts)
|
||||
noautocmd redraw
|
||||
while 1
|
||||
noautocmd redraw!
|
||||
try
|
||||
let code = getchar()
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<C-C>"
|
||||
endtry
|
||||
let ch = (type(code) == v:t_number)? nr2char(code) : code
|
||||
if ch == "\<ESC>" || ch == "\<c-c>"
|
||||
break
|
||||
elseif ch == ' ' || ch == 'x' || ch == 'q'
|
||||
break
|
||||
elseif ch == "\<LeftMouse>"
|
||||
if v:mouse_winid == winid
|
||||
if v:mouse_lnum > 0
|
||||
if get(a:opts, 'exit_on_click', 0) != 0
|
||||
break
|
||||
endif
|
||||
endif
|
||||
elseif v:mouse_winid == background
|
||||
if button != 0 && v:mouse_lnum == 1
|
||||
if v:mouse_col == opts.w + 2
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
elseif ch == '/' || ch == '?' || ch == ':'
|
||||
call quickui#utils#search_or_jump(winid, ch)
|
||||
noautocmd call quickui#utils#update_cursor(winid)
|
||||
elseif has_key(local.keymap, ch)
|
||||
let key = local.keymap[ch]
|
||||
if key == 'ENTER' || key == 'ESC'
|
||||
break
|
||||
elseif key == 'NEXT' || key == 'PREV'
|
||||
call quickui#utils#search_next(winid, key)
|
||||
noautocmd call quickui#utils#update_cursor(winid)
|
||||
else
|
||||
noautocmd call quickui#utils#scroll(winid, key)
|
||||
noautocmd call quickui#utils#update_cursor(winid)
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
let topline = quickui#utils#get_topline(winid)
|
||||
let g:quickui#textbox#topline = topline
|
||||
call nvim_win_close(winid, 0)
|
||||
if background >= 0
|
||||
call nvim_win_close(background, 0)
|
||||
endif
|
||||
let g:quickui#textbox#current = local
|
||||
if has_key(a:opts, 'callback')
|
||||
let F = function(a:opts.callback)
|
||||
call F(topline)
|
||||
endif
|
||||
return topline
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" cross platform create
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#textbox#create(textlist, opts)
|
||||
if g:quickui#core#has_nvim == 0
|
||||
return s:vim_create_textbox(a:textlist, a:opts)
|
||||
else
|
||||
return s:nvim_create_textbox(a:textlist, a:opts)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" open
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#textbox#open(textlist, opts)
|
||||
let maxheight = (&lines) * 70 / 100
|
||||
let maxwidth = (&columns) * 80 / 100
|
||||
let opts = deepcopy(a:opts)
|
||||
let opts.close = 'button'
|
||||
let maxheight = has_key(opts, 'maxheight')? opts.maxheight : maxheight
|
||||
let maxwidth = has_key(opts, 'maxwidth')? opts.maxwidth : maxwidth
|
||||
if has_key(opts, 'h') == 0
|
||||
let size = (type(a:textlist) == v:t_list)? len(a:textlist) : 20
|
||||
let opts.h = (size < maxheight)? size : maxheight
|
||||
endif
|
||||
if has_key(opts, 'w') == 0
|
||||
if type(a:textlist) == v:t_list
|
||||
let opts.w = 1
|
||||
for line in a:textlist
|
||||
let size = strdisplaywidth(line)
|
||||
let opts.w = (size < opts.w)? opts.w : size
|
||||
endfor
|
||||
if opts.w > maxwidth
|
||||
let opts.w = maxwidth
|
||||
endif
|
||||
if get(a:opts, 'number', 0) != 0
|
||||
let opts.w += len(string(len(a:textlist))) + 3
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if has_key(opts, 'h')
|
||||
let minheight = get(opts, 'minheight', 1)
|
||||
let minheight = (minheight < 1)? 1 : minheight
|
||||
let opts.h = (opts.h < minheight)? minheight : opts.h
|
||||
endif
|
||||
if has_key(opts, 'w')
|
||||
let minwidth = get(opts, 'minwidth', 20)
|
||||
let minwidth = (minwidth < 1)? 1 : minwidth
|
||||
let opts.w = (opts.w < minwidth)? minwidth : opts.w
|
||||
endif
|
||||
call quickui#textbox#create(a:textlist, opts)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" run shell command and display result in the text box
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#textbox#command(cmd, opts)
|
||||
let text = quickui#utils#system(a:cmd)
|
||||
let linelist = []
|
||||
let enc = get(g:, 'quickui_shell_encoding', '')
|
||||
for line in split(text, "\n")
|
||||
if enc != ''
|
||||
let line = iconv(line, enc, &encoding)
|
||||
endif
|
||||
let line = trim(line, "\r")
|
||||
let linelist += [line]
|
||||
endfor
|
||||
call quickui#textbox#open(linelist, a:opts)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" testing suit
|
||||
"----------------------------------------------------------------------
|
||||
if 0
|
||||
let lines = []
|
||||
for i in range(2000)
|
||||
let lines += ['printf("%d\n", ' . (i + 1) . ');']
|
||||
endfor
|
||||
let opts = {}
|
||||
let opts.index = 30
|
||||
let opts.resize = 1
|
||||
let opts.title = "title"
|
||||
let opts.syntax = "cpp"
|
||||
let opts.color = "QuickBox"
|
||||
let opts.border = 0
|
||||
" let opts.bordercolor = "QuickBG"
|
||||
let opts.cursor = 38
|
||||
let opts.number = 1
|
||||
" let opts.exit_on_click = 0
|
||||
let winid = quickui#textbox#open(lines, opts)
|
||||
" call getchar()
|
||||
" call quickui#textbox#close(winid)
|
||||
endif
|
||||
|
||||
|
||||
|
||||
|
523
vim/.vim/autoload/quickui/tools.vim
Normal file
523
vim/.vim/autoload/quickui/tools.vim
Normal file
@ -0,0 +1,523 @@
|
||||
"======================================================================
|
||||
"
|
||||
" tools.vim -
|
||||
"
|
||||
" Created by skywind on 2019/12/23
|
||||
" Last Modified: 2021/11/30 14:43
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" list buffer ids
|
||||
"----------------------------------------------------------------------
|
||||
function! s:buffer_list()
|
||||
let l:ls_cli = get(g:, 'quickui_buffer_list_cli', 'ls t')
|
||||
redir => buflist
|
||||
silent execute l:ls_cli
|
||||
redir END
|
||||
let bids = []
|
||||
for curline in split(buflist, '\n')
|
||||
if curline =~ '^\s*\d\+'
|
||||
let bid = str2nr(matchstr(curline, '^\s*\zs\d\+'))
|
||||
let bids += [bid]
|
||||
endif
|
||||
endfor
|
||||
return bids
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get default width
|
||||
"----------------------------------------------------------------------
|
||||
function! s:get_tools_width()
|
||||
let width = get(g:, 'quickui_tools_width', 70)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" locals
|
||||
"----------------------------------------------------------------------
|
||||
let s:keymaps = '123456789abcdefimnopqrstuvwxyz'
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" switch buffer callback
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#buffer_switch(bid)
|
||||
let switch = get(g:, 'quickui_switch_mode', &switchbuf)
|
||||
let code = g:quickui#listbox#current.tag
|
||||
let name = fnamemodify(bufname(a:bid), ':p')
|
||||
let opts = {}
|
||||
let bid = str2nr('' . a:bid)
|
||||
if code == ''
|
||||
let opts.switch = get(g:, 'quickui_switch_enter', switch)
|
||||
call quickui#utils#switch(bid, opts)
|
||||
elseif code == '1'
|
||||
let opts.switch = get(g:, 'quickui_switch_space', switch)
|
||||
call quickui#utils#switch(bid, opts)
|
||||
elseif code == '2'
|
||||
exec 'b '. a:bid
|
||||
elseif code == '3'
|
||||
exec 'vs'
|
||||
exec 'b '. a:bid
|
||||
elseif code == '4'
|
||||
exec 'split'
|
||||
exec 'b '. a:bid
|
||||
elseif code == '5'
|
||||
exec 'tab split'
|
||||
exec 'b '. a:bid
|
||||
elseif code == '6'
|
||||
exec 'tab drop ' . fnameescape(name)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get content
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#list_buffer(switch)
|
||||
let bids = s:buffer_list()
|
||||
let content = []
|
||||
let index = 0
|
||||
let current = -1
|
||||
let bufnr = bufnr()
|
||||
let s:switch = a:switch
|
||||
for bid in bids
|
||||
let key = (index < len(s:keymaps))? strpart(s:keymaps, index, 1) : ''
|
||||
let text = '[' . ((key == '')? ' ' : ('&' . key)) . "]\t"
|
||||
let text .= "\t"
|
||||
let name = fnamemodify(bufname(bid), ':p')
|
||||
let main = fnamemodify(name, ':t')
|
||||
let path = fnamemodify(name, ':h')
|
||||
let buftype = getbufvar(bid, '&buftype')
|
||||
if main == ''
|
||||
continue
|
||||
elseif buftype == 'nofile' || buftype == 'quickfix'
|
||||
continue
|
||||
endif
|
||||
let text = text . main . " " . "(" . bid . ")\t" . path
|
||||
let cmd = 'call quickui#tools#buffer_switch(' . bid . ')'
|
||||
if a:switch != ''
|
||||
" let cmd = a:switch . ' ' . fnameescape(name)
|
||||
endif
|
||||
let content += [[text, cmd]]
|
||||
if bid == bufnr()
|
||||
let current = index
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
let opts = {'title': 'Switch Buffer', 'index':current, 'close':'button'}
|
||||
let opts.border = g:quickui#style#border
|
||||
let opts.keymap = {}
|
||||
let opts.keymap["\<space>"] = 'TAG:1'
|
||||
let opts.keymap["\<c-e>"] = 'TAG:2'
|
||||
let opts.keymap["\<c-]>"] = 'TAG:3'
|
||||
let opts.keymap["\<c-x>"] = 'TAG:4'
|
||||
let opts.keymap["\<c-t>"] = 'TAG:5'
|
||||
let opts.keymap["\<c-g>"] = 'TAG:6'
|
||||
if exists('g:quickui_tools_width')
|
||||
let opts.w = quickui#utils#tools_width()
|
||||
endif
|
||||
" let opts.syntax = 'cpp'
|
||||
let maxheight = (&lines) * 60 / 100
|
||||
if len(content) > maxheight
|
||||
let opts.h = maxheight
|
||||
endif
|
||||
if len(content) == 0
|
||||
redraw
|
||||
echohl ErrorMsg
|
||||
echo "Empty buffer list"
|
||||
echohl None
|
||||
return -1
|
||||
endif
|
||||
call quickui#listbox#open(content, opts)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" list function
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#list_function()
|
||||
let ctags = get(g:, 'quickui_ctags_exe', 'ctags')
|
||||
if !executable(ctags)
|
||||
let msg = 'Not find ctags, add to $PATH or specify in '
|
||||
call quickui#utils#errmsg(msg . 'g:quickui_ctags_exe')
|
||||
return -1
|
||||
endif
|
||||
let items = quickui#tags#function_list(bufnr(), &ft)
|
||||
if len(items) == 0
|
||||
call quickui#utils#errmsg('No content !')
|
||||
return -2
|
||||
endif
|
||||
let content = []
|
||||
let cursor = -1
|
||||
let index = 0
|
||||
let ln = line('.')
|
||||
let maxsize = (&columns) * 60 / 100
|
||||
let maxheight = (&lines) * 60 / 100
|
||||
let maxwidth = 0
|
||||
let indents = get(g:, 'quickui_tags_indent', {})
|
||||
for item in items
|
||||
if ln >= item.line
|
||||
let cursor = index
|
||||
endif
|
||||
let index += 1
|
||||
let space = get(indents, item.mode, '')
|
||||
let text = '' . item.mode . '' . " \t" . space . item.text
|
||||
let text = text . ' [:' . item.line . ']'
|
||||
let maxwidth = (maxwidth < len(text))? len(text) : maxwidth
|
||||
let text = substitute(text, '&', '&&', 'g')
|
||||
let content += [[text, ':' . item.line]]
|
||||
endfor
|
||||
let opts = {'title': 'Function List', 'close':'button'}
|
||||
if cursor >= 0
|
||||
let opts.index = cursor
|
||||
endif
|
||||
let limit = &columns * 90 / 100
|
||||
let opts.h = len(content)
|
||||
let opts.h = (opts.h < maxheight)? opts.h : maxheight
|
||||
let opts.w = (maxwidth < limit)? maxwidth : limit
|
||||
if opts.w < maxsize
|
||||
let opts.w = (opts.w < 60)? 60 : opts.w
|
||||
endif
|
||||
let opts.syntax = 'qui_func'
|
||||
if exists('g:quickui_tools_width')
|
||||
let opts.w = quickui#utils#tools_width()
|
||||
endif
|
||||
" let content += ["1\t".repeat('0', 100)]
|
||||
call quickui#listbox#open(content, opts)
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" preview register in popup and choose to paste
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#list_register()
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" display python help in the textbox
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#python_help(word)
|
||||
let python = get(g:, 'quickui_tools_python', '')
|
||||
if python == ''
|
||||
if executable('python')
|
||||
let python = 'python'
|
||||
elseif executable('python3')
|
||||
let python = 'python3'
|
||||
elseif executable('python2')
|
||||
let python = 'python2'
|
||||
endif
|
||||
endif
|
||||
if a:word == ''
|
||||
let text = getline('.')
|
||||
let pre = text[:col('.') - 1]
|
||||
let suf = text[col('.'):]
|
||||
let word = matchstr(pre, "[A-Za-z0-9_.]*$")
|
||||
let word = word . matchstr(suf, "^[A-Za-z0-9_]*")
|
||||
else
|
||||
let word = a:word
|
||||
endif
|
||||
let cmd = python . ' -m pydoc ' . shellescape(word)
|
||||
let title = 'PyDoc <'. a:word . '>'
|
||||
let opts = {'title':title}
|
||||
let opts.color = 'QuickBG'
|
||||
" let opts.bordercolor = 'QuickBG'
|
||||
let opts.tabstop = 12
|
||||
call quickui#textbox#command(cmd, opts)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" display messages
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#display_messages()
|
||||
let x = ''
|
||||
redir => x
|
||||
silent! messages
|
||||
redir END
|
||||
let x = substitute(x, '[\n\r]\+\%$', '', 'g')
|
||||
let content = filter(split(x, "\n"), 'v:key != ""')
|
||||
if len(content) == 0
|
||||
call quickui#utils#errmsg('Empty messages')
|
||||
return -1
|
||||
endif
|
||||
let opts = {"close":"button", "title":"Vim Messages"}
|
||||
if exists('g:quickui_tools_width')
|
||||
let opts.w = quickui#utils#tools_width()
|
||||
endif
|
||||
call quickui#textbox#open(content, opts)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" preview quickfix
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#preview_quickfix(...)
|
||||
if quickui#preview#visible()
|
||||
call quickui#preview#close()
|
||||
return 0
|
||||
endif
|
||||
if &bt != 'quickfix'
|
||||
call quickui#utils#errmsg('Not in quickfix window !')
|
||||
return -1
|
||||
endif
|
||||
if !exists('b:__quickui_qf__')
|
||||
let b:__quickui_qf__ = {}
|
||||
endif
|
||||
let obj = b:__quickui_qf__
|
||||
if !has_key(obj, 'version')
|
||||
let obj.version = -1
|
||||
endif
|
||||
if b:changedtick != obj.version
|
||||
if getwininfo(win_getid())[0].loclist != 0
|
||||
let obj.items = getloclist(0)
|
||||
else
|
||||
let obj.items = getqflist()
|
||||
endif
|
||||
let obj.version = b:changedtick
|
||||
endif
|
||||
let index = (a:0 > 0)? a:1 : line('.')
|
||||
if index < 1 || index > len(obj.items)
|
||||
call quickui#utils#errmsg('No information in this line')
|
||||
return -2
|
||||
endif
|
||||
let item = obj.items[index - 1]
|
||||
if item.valid == 0
|
||||
return -3
|
||||
endif
|
||||
if item.bufnr <= 0
|
||||
return -4
|
||||
endif
|
||||
let name = bufname(item.bufnr)
|
||||
let opts = {'cursor':item.lnum}
|
||||
call quickui#preview#open(name, opts)
|
||||
" echom 'lnum:'. item.lnum
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" preview tag
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#preview_tag(tagname)
|
||||
let tagname = (a:tagname == '')? expand('<cword>') : a:tagname
|
||||
if tagname == ''
|
||||
call quickui#utils#errmsg('Error: empty tagname')
|
||||
return 0
|
||||
endif
|
||||
let obj = quickui#core#object(0)
|
||||
let reuse = 0
|
||||
if has_key(obj, 'ptag')
|
||||
let ptag = obj.ptag
|
||||
if get(ptag, 'tagname', '') == tagname
|
||||
let reuse = 1
|
||||
endif
|
||||
endif
|
||||
if reuse == 0
|
||||
let obj.ptag = {}
|
||||
let ptag = obj.ptag
|
||||
let ptag.taglist = quickui#tags#tagfind(tagname)
|
||||
let ptag.tagname = tagname
|
||||
let ptag.index = 0
|
||||
else
|
||||
let ptag = obj.ptag
|
||||
let ptag.index += 1
|
||||
if ptag.index >= len(ptag.taglist)
|
||||
let ptag.index = 0
|
||||
endif
|
||||
endif
|
||||
if len(ptag.taglist) == 0
|
||||
call quickui#utils#errmsg('E257: preview: tag not find "' . tagname . '"')
|
||||
return 1
|
||||
endif
|
||||
if ptag.index >= len(ptag.taglist) || ptag.index < 0
|
||||
let ptag.index = 0
|
||||
endif
|
||||
let taginfo = ptag.taglist[ptag.index]
|
||||
let filename = taginfo.filename
|
||||
if !filereadable(filename)
|
||||
call quickui#utils#errmsg('E484: Can not open file '.filename)
|
||||
return 2
|
||||
endif
|
||||
if !has_key(taginfo, 'line')
|
||||
call quickui#utils#errmsg('Error: no "line" information in your tags, regenerate with -n')
|
||||
return 3
|
||||
endif
|
||||
let text = '('.(ptag.index + 1).'/'.len(ptag.taglist).')'
|
||||
let opts = {'cursor':taginfo.line, 'title':text}
|
||||
call quickui#preview#open(filename, opts)
|
||||
let text = taginfo.name
|
||||
let text.= ' ('.(ptag.index + 1).'/'.len(ptag.taglist).') '
|
||||
let text.= filename
|
||||
if has_key(taginfo, 'line')
|
||||
let text .= ':'.taginfo.line
|
||||
endif
|
||||
let display = has('gui_running')? 0 : 1
|
||||
let display = get(g:, 'quickui_preview_tag_msg', display)
|
||||
if display != 0
|
||||
call quickui#utils#print(text, 1)
|
||||
endif
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" display vim help in popup
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#display_help(tag)
|
||||
if !exists('s:help_tags')
|
||||
let fn = expand('$VIMRUNTIME/doc/tags')
|
||||
if filereadable(fn)
|
||||
let content = readfile(fn)
|
||||
let s:help_tags = {}
|
||||
for line in content
|
||||
let parts = split(line, "\t")
|
||||
if len(parts) >= 3
|
||||
let s:help_tags[parts[0]] = [parts[1], parts[2]]
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
if !exists('s:help_tags')
|
||||
call quickui#utils#errmsg('Sorry, not find help tags in $VIMRUNTIME')
|
||||
return -1
|
||||
endif
|
||||
if !has_key(s:help_tags, a:tag)
|
||||
call quickui#utils#errmsg('E149: Sorry, no help for '. a:tag)
|
||||
return -2
|
||||
endif
|
||||
let item = s:help_tags[a:tag]
|
||||
let name = expand($VIMRUNTIME . '/doc/' . item[0])
|
||||
let command = substitute(item[1], '\*', '', 'g')
|
||||
if !filereadable(name)
|
||||
call quickui#utils#errmsg('E484: Sorry, cannot open file '.name)
|
||||
return -3
|
||||
endif
|
||||
let content = readfile(name)
|
||||
let opts = {'syntax':'help', 'color':'QuickPreview', 'close':'button'}
|
||||
let opts.title = 'Help: ' . fnamemodify(name, ':t')
|
||||
let g:quickui#tools#hint = item[1]
|
||||
let opts.command = ['silent! exec g:quickui#tools#hint']
|
||||
let opts.command += ["exec 'nohl'"]
|
||||
let opts.command += ["normal zz"]
|
||||
let opts.w = 80
|
||||
" echom opts
|
||||
let winid = quickui#textbox#open(content, opts)
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" save curses help
|
||||
"----------------------------------------------------------------------
|
||||
let s:previous_cursor = {}
|
||||
|
||||
function! s:remember_cursor_context(code)
|
||||
let hwnd = g:quickui#context#current
|
||||
let name = hwnd.opts.keep_name
|
||||
let s:previous_cursor[name] = g:quickui#context#cursor
|
||||
endfunc
|
||||
|
||||
function! s:remember_cursor_listbox(code)
|
||||
let hwnd = g:quickui#listbox#current
|
||||
let name = hwnd.opts.keep_name
|
||||
let s:previous_cursor[name] = g:quickui#listbox#cursor
|
||||
endfunc
|
||||
|
||||
function! quickui#tools#clever_context(name, content, opts)
|
||||
let opts = deepcopy(a:opts)
|
||||
let opts.index = get(s:previous_cursor, a:name, -1)
|
||||
let opts.keep_name = a:name
|
||||
let opts.callback = function('s:remember_cursor_context')
|
||||
let content = quickui#context#reduce_items(a:content)
|
||||
call quickui#context#open_nested(content, opts)
|
||||
endfunc
|
||||
|
||||
function! quickui#tools#clever_listbox(name, content, opts)
|
||||
let opts = deepcopy(a:opts)
|
||||
let opts.index = get(s:previous_cursor, a:name, -1)
|
||||
let opts.keep_name = a:name
|
||||
let opts.callback = function('s:remember_cursor_listbox')
|
||||
call quickui#listbox#open(a:content, opts)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" terminal
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#terminal(name)
|
||||
if !exists('g:quickui_terminal_tools')
|
||||
let g:quickui_terminal_tools = {}
|
||||
endif
|
||||
if !has_key(g:quickui_terminal_tools, a:name)
|
||||
call quickui#utils#errmsg('ERROR: tool ' . a:name . ' not defined !')
|
||||
return -1
|
||||
endif
|
||||
let tools = g:quickui_terminal_tools[a:name]
|
||||
if !has_key(tools, 'cmd')
|
||||
call quickui#utils#errmsg('ERROR: key cmd not present in tool ' . a:name)
|
||||
return -1
|
||||
endif
|
||||
let opts = {}
|
||||
let cmd = tools.cmd
|
||||
let w = get(g:, 'quickui_terminal_w', 80)
|
||||
let h = get(g:, 'quickui_terminal_h', 24)
|
||||
let opts.w = get(tools, 'w', w)
|
||||
let opts.h = get(tools, 'h', h)
|
||||
if has_key(tools, 'color')
|
||||
if tools.color != ''
|
||||
let opts.color = tools.color
|
||||
endif
|
||||
endif
|
||||
if has_key(tools, 'title')
|
||||
let opts.title = tools.title
|
||||
endif
|
||||
if has_key(tools, 'callback')
|
||||
let opts.callback = tools.callback
|
||||
endif
|
||||
if has_key(tools, 'prepare')
|
||||
let opts.prepare = tools.prepare
|
||||
endif
|
||||
if has_key(tools, 'cwd')
|
||||
let opts.cwd = tools.cwd
|
||||
endif
|
||||
if has_key(tools, 'script')
|
||||
let opts.safe = tools.script
|
||||
endif
|
||||
if has_key(tools, 'pause')
|
||||
if tools.pause
|
||||
let opts.pause = 1
|
||||
endif
|
||||
endif
|
||||
if has_key(tools, 'close')
|
||||
if tools.close
|
||||
let opts.close = 1
|
||||
endif
|
||||
endif
|
||||
call quickui#terminal#dialog(cmd, opts)
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" search inputbox
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#tools#input_search()
|
||||
let cword = expand('<cword>')
|
||||
let title = 'Enter text to search:'
|
||||
let text = quickui#input#open(title, cword, 'search')
|
||||
redraw
|
||||
if text != ''
|
||||
let text = escape(text, '[\/*~^.')
|
||||
call feedkeys("\<ESC>/" . text . "\<cr>", 'n')
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
|
914
vim/.vim/autoload/quickui/utils.vim
Normal file
914
vim/.vim/autoload/quickui/utils.vim
Normal file
@ -0,0 +1,914 @@
|
||||
"======================================================================
|
||||
"
|
||||
" utils.vim -
|
||||
"
|
||||
" Created by skywind on 2019/12/19
|
||||
" Last Modified: 2023/07/23 18:44
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" parse description into item object
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#item_parse(description)
|
||||
let obj = {'text':'', 'key_pos':-1, 'key_char':'', 'is_sep':0, 'help':''}
|
||||
let text = ''
|
||||
let child = 0
|
||||
if type(a:description) == v:t_string
|
||||
let text = a:description
|
||||
let obj.help = ''
|
||||
let obj.cmd = ''
|
||||
elseif type(a:description) == v:t_list
|
||||
let size = len(a:description)
|
||||
let text = (size >= 1)? a:description[0] : ''
|
||||
let obj.help = (size >= 3)? a:description[2] : ''
|
||||
let obj.cmd = ''
|
||||
if size >= 2
|
||||
if type(a:description[1]) == v:t_string
|
||||
let obj.cmd = a:description[1]
|
||||
elseif type(a:description[1]) == v:t_list
|
||||
let obj.cmd = ''
|
||||
let obj.child = a:description[1]
|
||||
let child = 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if text =~ '^-\+$'
|
||||
let obj.is_sep = 1
|
||||
let obj.text = ""
|
||||
let obj.desc = ""
|
||||
let obj.text_width = 0
|
||||
let obj.desc_width = 0
|
||||
let obj.enable = 0
|
||||
else
|
||||
let text = quickui#core#expand_text(text)
|
||||
let obj.enable = 1
|
||||
if strpart(text, 0, 1) == '~'
|
||||
let text = strpart(text, 1)
|
||||
let obj.enable = 0
|
||||
endif
|
||||
let pos = stridx(text, "\t")
|
||||
let sep = ">"
|
||||
if pos < 0
|
||||
let obj.text = text
|
||||
let obj.desc = ""
|
||||
else
|
||||
let obj.text = strpart(text, 0, pos)
|
||||
let obj.desc = strpart(text, pos + 1)
|
||||
let obj.desc = substitute(obj.desc, "\t", " ", "g")
|
||||
endif
|
||||
let obj.desc = (child == 0)? obj.desc : sep
|
||||
let text = obj.text
|
||||
let rest = ''
|
||||
let start = 0
|
||||
while 1
|
||||
let pos = stridx(text, "&", start)
|
||||
if pos < 0
|
||||
let rest .= strpart(text, start)
|
||||
break
|
||||
end
|
||||
let rest .= strpart(text, start, pos - start)
|
||||
let key = strpart(text, pos + 1, 1)
|
||||
let start = pos + 2
|
||||
if key == '&'
|
||||
let rest .= '&'
|
||||
elseif key == '~'
|
||||
let rest .= '~'
|
||||
else
|
||||
let obj.key_char = key
|
||||
let obj.key_pos = strwidth(rest)
|
||||
let rest .= key
|
||||
endif
|
||||
endwhile
|
||||
let obj.text = rest
|
||||
let obj.text_width = strwidth(obj.text)
|
||||
let obj.desc_width = strwidth(obj.desc)
|
||||
end
|
||||
return obj
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" alignment
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#context_align(item, left_size, right_size)
|
||||
let obj = a:item
|
||||
let middle = (a:right_size > 0)? 2 : 0
|
||||
let size = a:left_size + a:right_size + middle
|
||||
if obj.is_sep
|
||||
let obj.content = repeat('-', size)
|
||||
else
|
||||
if obj.text_width < a:left_size
|
||||
let delta = a:left_size - obj.text_width
|
||||
let obj.text_left = obj.text . repeat(' ', delta)
|
||||
else
|
||||
let obj.text_left = obj.text
|
||||
endif
|
||||
if obj.desc_width < a:right_size
|
||||
let delta = a:right_size - obj.desc_width
|
||||
let obj.text_right = repeat(' ', delta) . obj.desc
|
||||
else
|
||||
let obj.text_right = obj.desc
|
||||
endif
|
||||
if a:right_size > 0
|
||||
let obj.content = obj.text_left . ' ' . obj.text_right
|
||||
else
|
||||
let obj.content = obj.text_left
|
||||
endif
|
||||
endif
|
||||
return obj
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" style: default
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#highlight(style)
|
||||
let style = (type(a:style) == v:t_number)? (''. a:style) : a:style
|
||||
let style = tolower(style)
|
||||
if style == '' || style == '0' || style == 'default' || style == 'Pmenu'
|
||||
hi! link TVisionBG Pmenu
|
||||
hi! link TVisionKey Keyword
|
||||
hi! link TVisionOff Comment
|
||||
hi! link TVisionSel PmenuSel
|
||||
hi! link TVisionHelp Title
|
||||
elseif style == 'borland'
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" build map
|
||||
"----------------------------------------------------------------------
|
||||
let s:maps = {}
|
||||
let s:maps["\<ESC>"] = 'ESC'
|
||||
let s:maps["\<CR>"] = 'ENTER'
|
||||
let s:maps["\<SPACE>"] = 'ENTER'
|
||||
let s:maps["\<UP>"] = 'UP'
|
||||
let s:maps["\<DOWN>"] = 'DOWN'
|
||||
let s:maps["\<LEFT>"] = 'LEFT'
|
||||
let s:maps["\<RIGHT>"] = 'RIGHT'
|
||||
let s:maps["\<HOME>"] = 'HOME'
|
||||
let s:maps["\<END>"] = 'END'
|
||||
let s:maps["\<c-j>"] = 'DOWN'
|
||||
let s:maps["\<c-k>"] = 'UP'
|
||||
let s:maps["\<c-h>"] = 'LEFT'
|
||||
let s:maps["\<c-l>"] = 'RIGHT'
|
||||
let s:maps["\<c-n>"] = 'NEXT'
|
||||
let s:maps["\<c-p>"] = 'PREV'
|
||||
let s:maps["\<c-b>"] = 'PAGEUP'
|
||||
let s:maps["\<c-f>"] = 'PAGEDOWN'
|
||||
let s:maps["\<c-u>"] = 'HALFUP'
|
||||
let s:maps["\<c-d>"] = 'HALFDOWN'
|
||||
let s:maps["\<PageUp>"] = 'PAGEUP'
|
||||
let s:maps["\<PageDown>"] = 'PAGEDOWN'
|
||||
let s:maps["\<c-g>"] = 'NOHL'
|
||||
let s:maps['j'] = 'DOWN'
|
||||
let s:maps['k'] = 'UP'
|
||||
let s:maps['h'] = 'LEFT'
|
||||
let s:maps['l'] = 'RIGHT'
|
||||
let s:maps['J'] = 'HALFDOWN'
|
||||
let s:maps['K'] = 'HALFUP'
|
||||
let s:maps['H'] = 'PAGEUP'
|
||||
let s:maps['L'] = 'PAGEDOWN'
|
||||
let s:maps["g"] = 'TOP'
|
||||
let s:maps["G"] = 'BOTTOM'
|
||||
let s:maps['q'] = 'ESC'
|
||||
let s:maps['n'] = 'NEXT'
|
||||
let s:maps['N'] = 'PREV'
|
||||
|
||||
|
||||
function! quickui#utils#keymap()
|
||||
return deepcopy(s:maps)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" python simulate system() on window to prevent temporary window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:python_system(cmd, version)
|
||||
if has('nvim')
|
||||
let hr = system(a:cmd)
|
||||
elseif has('win32') || has('win64') || has('win95') || has('win16')
|
||||
if a:version < 0 || (has('python3') == 0 && has('python2') == 0)
|
||||
let hr = system(a:cmd)
|
||||
let s:shell_error = v:shell_error
|
||||
return hr
|
||||
elseif a:version == 3
|
||||
let pyx = 'py3 '
|
||||
let python_eval = 'py3eval'
|
||||
elseif a:version == 2
|
||||
let pyx = 'py2 '
|
||||
let python_eval = 'pyeval'
|
||||
else
|
||||
let pyx = 'pyx '
|
||||
let python_eval = 'pyxeval'
|
||||
endif
|
||||
exec pyx . 'import subprocess, vim'
|
||||
exec pyx . '__argv = {"args":vim.eval("a:cmd"), "shell":True}'
|
||||
exec pyx . '__argv["stdout"] = subprocess.PIPE'
|
||||
exec pyx . '__argv["stderr"] = subprocess.STDOUT'
|
||||
exec pyx . '__pp = subprocess.Popen(**__argv)'
|
||||
exec pyx . '__return_text = __pp.stdout.read()'
|
||||
exec pyx . '__pp.stdout.close()'
|
||||
exec pyx . '__return_code = __pp.wait()'
|
||||
exec 'let l:hr = '. python_eval .'("__return_text")'
|
||||
exec 'let l:pc = '. python_eval .'("__return_code")'
|
||||
let s:shell_error = l:pc
|
||||
return l:hr
|
||||
else
|
||||
let hr = system(a:cmd)
|
||||
endif
|
||||
let s:shell_error = v:shell_error
|
||||
return hr
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" execute external program and return its output
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#system(cmd)
|
||||
let hr = s:python_system(a:cmd, get(g:, 'quickui_python', 0))
|
||||
let g:quickui#utils#shell_error = s:shell_error
|
||||
return hr
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" display a error msg
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#errmsg(what)
|
||||
redraw
|
||||
echohl ErrorMsg
|
||||
echom a:what
|
||||
echohl None
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" safe print
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#print(content, highlight, ...)
|
||||
let saveshow = &showmode
|
||||
set noshowmode
|
||||
let wincols = &columns
|
||||
let statusline = (&laststatus==1 && winnr('$')>1) || (&laststatus==2)
|
||||
let reqspaces_lastline = (statusline || !&ruler) ? 12 : 29
|
||||
let width = len(a:content)
|
||||
let limit = wincols - reqspaces_lastline
|
||||
let l:content = a:content
|
||||
if width + 1 > limit
|
||||
let l:content = strpart(l:content, 0, limit - 1)
|
||||
let width = len(l:content)
|
||||
endif
|
||||
" prevent scrolling caused by multiple echo
|
||||
let needredraw = (a:0 >= 1)? a:1 : 1
|
||||
if needredraw != 0
|
||||
redraw
|
||||
endif
|
||||
if a:highlight != 0
|
||||
echohl Type
|
||||
echo l:content
|
||||
echohl NONE
|
||||
else
|
||||
echo l:content
|
||||
endif
|
||||
if saveshow != 0
|
||||
set showmode
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" max height
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#max_height(percentage)
|
||||
return (&lines) * a:percentage / 100
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" cursor movement
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#movement(offset)
|
||||
let height = winheight(0)
|
||||
let winline = winline()
|
||||
let curline = line('.')
|
||||
let topline = curline - winline + 1
|
||||
let topline = (topline < 1)? 1 : topline
|
||||
let botline = topline + height - 1
|
||||
let offset = 0
|
||||
if type(a:offset) == v:t_number
|
||||
let offset = a:offset
|
||||
elseif type(a:offset) == v:t_string
|
||||
if a:offset == 'PAGEUP'
|
||||
let offset = -height
|
||||
elseif a:offset == 'PAGEDOWN'
|
||||
let offset = height
|
||||
elseif a:offset == 'HALFUP' || a:offset == 'LEFT'
|
||||
let offset = -(height / 2)
|
||||
elseif a:offset == 'HALFDOWN' || a:offset == 'RIGHT'
|
||||
let offset = height / 2
|
||||
elseif a:offset == 'UP'
|
||||
let offset = -1
|
||||
elseif a:offset == 'DOWN'
|
||||
let offset = 1
|
||||
elseif a:offset == 'TOP'
|
||||
exec "noautocmd normal gg"
|
||||
return
|
||||
elseif a:offset == 'BOTTOM'
|
||||
exec "noautocmd normal G"
|
||||
return
|
||||
endif
|
||||
endif
|
||||
" echom "offset: ". offset
|
||||
if offset > 0
|
||||
exec "noautocmd normal ". offset . "\<C-E>"
|
||||
elseif offset < 0
|
||||
exec "noautocmd normal ". (-offset) . "\<C-Y>"
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" cursor scroll
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#scroll(winid, offset)
|
||||
if type(a:offset) == v:t_number
|
||||
let cmd = 'call quickui#utils#movement(' . a:offset . ')'
|
||||
call quickui#core#win_execute(a:winid, cmd)
|
||||
else
|
||||
let cmd = 'call quickui#utils#movement("' . a:offset . '")'
|
||||
call quickui#core#win_execute(a:winid, cmd)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" centerize
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#center(winid, ...)
|
||||
if g:quickui#core#has_nvim == 0
|
||||
let pos = popup_getpos(a:winid)
|
||||
else
|
||||
let pos = {}
|
||||
let pos.width = nvim_win_get_width(a:winid)
|
||||
let pos.height = nvim_win_get_height(a:winid)
|
||||
endif
|
||||
let h = pos.height
|
||||
let w = pos.width
|
||||
let mode = (a:0 < 1)? 0 : (a:1)
|
||||
let scale = (mode == 0)? 80 : 68
|
||||
let limit1 = (&lines - 2) * scale / 100
|
||||
let limit2 = (&lines - 2)
|
||||
let opts = {}
|
||||
if h + 4 < limit1
|
||||
let opts.line = (limit1 - h) / 2
|
||||
else
|
||||
let opts.line = (limit2 - h) / 2
|
||||
endif
|
||||
let opts.col = (&columns - w) / 2
|
||||
let opts.col = (opts.col < 1)? 1 : (opts.col)
|
||||
let hr = quickui#core#screen_fit(opts.line, opts.col, w, h)
|
||||
let opts.col = hr[1]
|
||||
let opts.line = hr[0]
|
||||
if g:quickui#core#has_nvim == 0
|
||||
call popup_move(a:winid, opts)
|
||||
else
|
||||
let no = {'col': opts.col - 1, 'row': opts.line - 1}
|
||||
let no.relative = 'editor'
|
||||
call nvim_win_set_config(a:winid, no)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" show cursorline in textbox
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#show_cursor(winid, row)
|
||||
let height = winheight(0)
|
||||
let winline = winline()
|
||||
let curline = line('.')
|
||||
let topline = curline - winline + 1
|
||||
let topline = (topline < 1)? 1 : topline
|
||||
let botline = topline + height - 1
|
||||
let w:__quickui_line__ = get(w:, '__quickui_line__', -1)
|
||||
if a:row >= topline && a:row <= botline
|
||||
exec ":" . a:row
|
||||
if w:__quickui_line__ != 1
|
||||
if g:quickui#core#has_nvim == 0
|
||||
call popup_setoptions(a:winid, {'cursorline': 1})
|
||||
else
|
||||
call quickui#core#win_execute(a:winid, 'setl cursorline')
|
||||
if exists('+cursorlineopt')
|
||||
call quickui#core#win_execute(a:winid, 'setl cursorlineopt=both')
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let w:__quickui_line__ = 1
|
||||
else
|
||||
if w:__quickui_line__ != 0
|
||||
if g:quickui#core#has_nvim == 0
|
||||
call popup_setoptions(a:winid, {'cursorline': 0})
|
||||
else
|
||||
call quickui#core#win_execute(a:winid, 'setl nocursorline')
|
||||
endif
|
||||
endif
|
||||
let w:__quickui_line__ = 0
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" update cursor line
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#update_cursor(winid)
|
||||
let bid = winbufnr(a:winid)
|
||||
let row = getbufvar(bid, '__quickui_cursor__', -1)
|
||||
let cmd = 'call quickui#utils#show_cursor('. a:winid .', '.row.')'
|
||||
call quickui#core#win_execute(a:winid, cmd)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get window line
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#get_cursor(winid)
|
||||
let g:quickui#utils#__cursor_index__ = -1
|
||||
let cmd = 'let g:quickui#utils#__cursor_index__ = line(".")'
|
||||
noautocmd call quickui#core#win_execute(a:winid, cmd)
|
||||
return g:quickui#utils#__cursor_index__
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get topline in current window
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#current_topline()
|
||||
let height = winheight(0)
|
||||
let winline = winline()
|
||||
let curline = line('.')
|
||||
let topline = curline - winline + 1
|
||||
return topline
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get first cursorline
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#get_topline(winid)
|
||||
let g:quickui#utils#__cursor_topline__ = -1
|
||||
let cmd = 'let g:quickui#utils#__cursor_topline__ = '
|
||||
let cmd = cmd . 'quickui#utils#current_topline()'
|
||||
call quickui#core#win_execute(a:winid, cmd)
|
||||
return g:quickui#utils#__cursor_topline__
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" make border
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#make_border(width, height, border, title, ...)
|
||||
let pattern = quickui#core#border_get(a:border)
|
||||
let image = []
|
||||
let w = a:width
|
||||
let h = a:height
|
||||
let text = pattern[0] . repeat(pattern[1], w) . pattern[2]
|
||||
let image += [text]
|
||||
let index = 0
|
||||
while index < h
|
||||
let text = pattern[3] . repeat(' ', w) . pattern[5]
|
||||
let image += [text]
|
||||
let index += 1
|
||||
endwhile
|
||||
let text = pattern[6] . repeat(pattern[7], w) . pattern[8]
|
||||
let image += [text]
|
||||
let button = (a:0 > 0)? (a:1) : 0
|
||||
let align = (a:0 > 1)? (a:2) : ''
|
||||
let text = image[0]
|
||||
let title = quickui#core#string_fit(a:title, w)
|
||||
if align == '' || align == 'l'
|
||||
let text = quickui#core#string_compose(text, 1, title)
|
||||
elseif align == 'm'
|
||||
let left = (w + 2 - len(title)) / 2
|
||||
let text = quickui#core#string_compose(text, left, title)
|
||||
elseif align == 'r'
|
||||
let left = w + 2 - len(title) - 1
|
||||
let text = quickui#core#string_compose(text, left, title)
|
||||
endif
|
||||
if button != 0
|
||||
let text = quickui#core#string_compose(text, w + 1, 'X')
|
||||
endif
|
||||
let image[0] = text
|
||||
return image
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" search or jump
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#search_or_jump(winid, cmd)
|
||||
if a:cmd == '/' || a:cmd == '?'
|
||||
let prompt = (a:cmd == '/')? '/' : '?'
|
||||
" let prompt = (a:cmd == '/')? '(search): ' : '(search backwards): '
|
||||
let t = quickui#core#input(prompt, '')
|
||||
if t != '' && t != "\<c-c>"
|
||||
try
|
||||
silent call quickui#core#win_execute(a:winid, a:cmd . t)
|
||||
catch /^Vim\%((\a\+)\)\=:E486:/
|
||||
call quickui#utils#errmsg('E486: Pattern not find: '. t)
|
||||
endtry
|
||||
silent! call quickui#core#win_execute(a:winid, 'nohl')
|
||||
call setwinvar(a:winid, '__quickui_search_cmd', a:cmd)
|
||||
call setwinvar(a:winid, '__quickui_search_key', t)
|
||||
endif
|
||||
elseif a:cmd == ':'
|
||||
let prompt = ':'
|
||||
" let prompt = '(goto): '
|
||||
let t = quickui#core#input(prompt, '')
|
||||
if t != ''
|
||||
call quickui#core#win_execute(a:winid, ':' . t)
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" search next
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#search_next(winid, cmd)
|
||||
let prev_cmd = getwinvar(a:winid, '__quickui_search_cmd', '')
|
||||
let prev_key = getwinvar(a:winid, '__quickui_search_key', '')
|
||||
if prev_key != ''
|
||||
if a:cmd ==# 'n' || a:cmd == 'NEXT'
|
||||
let cmd = (prev_cmd == '/')? '/' : '?'
|
||||
else
|
||||
let cmd = (prev_cmd == '/')? '?' : '/'
|
||||
endif
|
||||
try
|
||||
silent call quickui#core#win_execute(a:winid, cmd . prev_key)
|
||||
catch /^Vim\%((\a\+)\)\=:E486:/
|
||||
endtry
|
||||
noautocmd call quickui#core#win_execute(a:winid, 'nohl')
|
||||
endif
|
||||
let cmds = ['exec line(".")']
|
||||
let cmds += ['normal! 0']
|
||||
silent call quickui#core#win_execute(a:winid, cmds)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" size can be in '24' or '24%' or '0.25'
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#read_size(text, maxsize)
|
||||
if type(a:text) == v:t_number
|
||||
return a:text
|
||||
elseif type(a:text) == v:t_string
|
||||
let text = trim(a:text)
|
||||
if text =~ '%$'
|
||||
let text = strpart(text, 0, len(text) - 1)
|
||||
let ratio = str2nr(text)
|
||||
let num = (a:maxsize) * ratio / 100
|
||||
return (num < a:maxsize)? num : a:maxsize
|
||||
else
|
||||
let fsize = str2float(a:text)
|
||||
if fsize <= 1.0
|
||||
return float2nr(fsize * a:maxsize)
|
||||
endif
|
||||
let size = float2nr(fsize)
|
||||
return (size > a:maxsize)? a:maxsize : size
|
||||
endif
|
||||
elseif type(a:text) == v:t_float
|
||||
let fsize = a:text
|
||||
if fsize <= 1.0
|
||||
return float2nr(fsize * a:maxsize)
|
||||
endif
|
||||
let size = float2nr(fsize)
|
||||
return (size > a:maxsize)? a:maxsize : size
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get default tools width
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#tools_width()
|
||||
let width = get(g:, 'quickui_tools_width', '60%')
|
||||
let size = quickui#utils#read_size(width, &columns)
|
||||
let minimal = (60 < &columns)? 60 : &columns
|
||||
let size = (size < minimal)? minimal : size
|
||||
return (size > &columns)? &columns : size
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" read from register or evaluation
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#read_eval(...)
|
||||
let opts = (a:0 == 0)? {} : (a:1)
|
||||
try
|
||||
let code = getchar()
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<C-C>"
|
||||
endtry
|
||||
let ch = (type(code) == v:t_number)? nr2char(code) : code
|
||||
if ch == "\<c-c>"
|
||||
return ''
|
||||
elseif ch == "\<esc>" || ch == "\<cr>"
|
||||
return ''
|
||||
elseif ch == "="
|
||||
let e = input('=')
|
||||
if e == ''
|
||||
return ''
|
||||
endif
|
||||
return eval(e)
|
||||
elseif ch == "\<c-w>"
|
||||
let x = expand('<cword>')
|
||||
return x
|
||||
elseif len(ch) == 1
|
||||
let x = eval('@' . ch)
|
||||
return x
|
||||
endif
|
||||
return ''
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" normalize textlist
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#text_list_normalize(textlist)
|
||||
if type(a:textlist) == v:t_list
|
||||
let textlist = a:textlist
|
||||
else
|
||||
let textlist = split('' . a:textlist, '\n', 1)
|
||||
endif
|
||||
let out = []
|
||||
for text in textlist
|
||||
let text = substitute(text, '[\r\n\t]', ' ', 'g')
|
||||
let out += [text]
|
||||
endfor
|
||||
return out
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" getchar
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#getchar(wait)
|
||||
try
|
||||
if a:wait != 0
|
||||
let code = getchar()
|
||||
else
|
||||
let code = getchar(0)
|
||||
endif
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<C-C>"
|
||||
endtry
|
||||
if type(code) == v:t_number && code == 0
|
||||
try
|
||||
exec 'sleep 15m'
|
||||
continue
|
||||
catch /^Vim:Interrupt$/
|
||||
let code = "\<c-c>"
|
||||
endtry
|
||||
endif
|
||||
let ch = (type(code) == v:t_number)? nr2char(code) : code
|
||||
return ch
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" switch buffer
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#switch(filename, opts)
|
||||
let switch = get(g:, 'quickui_switch_mode', &switchbuf)
|
||||
let switch = get(a:opts, 'switch', switch)
|
||||
let method = split(switch, ',')
|
||||
let goto = get(a:opts, 'goto', -1)
|
||||
let ft = get(a:opts, 'ft', '')
|
||||
let cmds = get(a:opts, 'command', [])
|
||||
if type(a:filename) == type('')
|
||||
let filename = expand(a:filename)
|
||||
if filereadable(filename) == 0
|
||||
if get(a:opts, 'exist', 0) != 0
|
||||
echohl ErrorMsg
|
||||
echom "E484: Can't open file " . (a:filename)
|
||||
echohl None
|
||||
return 0
|
||||
endif
|
||||
endif
|
||||
let bid = bufnr(filename)
|
||||
else
|
||||
let bid = a:filename
|
||||
if bid < 0
|
||||
return 0
|
||||
endif
|
||||
endif
|
||||
if index(method, 'useopen') >= 0
|
||||
for wid in range(winnr('$'))
|
||||
let b = winbufnr(wid + 1)
|
||||
if b == bid
|
||||
silent exec ''. (wid + 1) . 'wincmd w'
|
||||
if goto > 0
|
||||
silent exec ':' . goto
|
||||
endif
|
||||
for cmd in cmds
|
||||
exec cmd
|
||||
endfor
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
if index(method, 'usetab') >= 0
|
||||
for tid in range(tabpagenr('$'))
|
||||
let buflist = tabpagebuflist(tid + 1)
|
||||
for wid in range(len(buflist))
|
||||
if bid == buflist[wid]
|
||||
silent exec 'tabn ' . (tid + 1)
|
||||
silent exec '' . (wid + 1) . 'wincmd w'
|
||||
if goto > 0
|
||||
silent exec ':' . goto
|
||||
endif
|
||||
for cmd in cmds
|
||||
exec cmd
|
||||
endfor
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endif
|
||||
if index(method, 'newtab') >= 0
|
||||
silent exec 'tab split'
|
||||
elseif index(method, 'uselast') >= 0
|
||||
silent exec 'wincmd p'
|
||||
elseif index(method, 'edit') >= 0
|
||||
silent exec ''
|
||||
elseif index(method, 'drop') >= 0
|
||||
else
|
||||
if &buftype != ''
|
||||
silent exec 'wincmd p'
|
||||
endif
|
||||
for i in range(winnr('$'))
|
||||
if &buftype == ''
|
||||
break
|
||||
endif
|
||||
silent exec 'wincmd w'
|
||||
endfor
|
||||
let mods = get(a:opts, 'mods', '')
|
||||
if index(method, 'auto') >= 0
|
||||
if winwidth(0) >= 160
|
||||
exec mods . ' vsplit'
|
||||
else
|
||||
exec mods . ' split'
|
||||
endif
|
||||
elseif index(method, 'split') >= 0
|
||||
exec mods . ' split'
|
||||
elseif index(method, 'vsplit') >= 0
|
||||
exec mods . ' vsplit'
|
||||
endif
|
||||
endif
|
||||
try
|
||||
let force = ((get(a:opts, 'force', 0) != 0)? '!' : '')
|
||||
if bid >= 0
|
||||
exec 'b' . force . ' ' . bid
|
||||
else
|
||||
exec 'edit' . force . ' ' . fnameescape(expand(a:filename))
|
||||
endif
|
||||
catch /^Vim\%((\a\+)\)\=:E37:/
|
||||
echohl ErrorMsg
|
||||
echo 'E37: No write since last change (set force=1 to override)'
|
||||
echohl None
|
||||
return 0
|
||||
endtry
|
||||
if goto > 0
|
||||
exec ':' . goto
|
||||
endif
|
||||
if ft != ''
|
||||
exec 'setlocal ft=' . fnameescape(ft)
|
||||
endif
|
||||
for cmd in cmds
|
||||
exec cmd
|
||||
endfor
|
||||
return 1
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" returns 1 if filetype matches pattern, otherwise returns 0
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#match_ft(filetype, pattern)
|
||||
let pattern = quickui#core#string_strip(a:pattern)
|
||||
let ft = a:filetype
|
||||
if pattern == ''
|
||||
return 0
|
||||
elseif pattern =~ '^/'
|
||||
let pattern = strpart(pattern, 1)
|
||||
if match(ft, pattern) >= 0
|
||||
return 1
|
||||
endif
|
||||
elseif pattern =~ '^!'
|
||||
let pattern = strpart(pattern, 1)
|
||||
if match(ft, pattern) < 0
|
||||
return 1
|
||||
endif
|
||||
endif
|
||||
let blacklist = []
|
||||
let whitelist = []
|
||||
for check in split(pattern, ',')
|
||||
if pattern[0] == '-'
|
||||
let blacklist += [check]
|
||||
else
|
||||
let whitelist += [check]
|
||||
endif
|
||||
endfor
|
||||
if index(blacklist, '-' . ft) >= 0
|
||||
return 0
|
||||
endif
|
||||
if empty(whitelist) || index(whitelist, ft) >= 0
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" format table
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#tabulify(rows)
|
||||
let content = []
|
||||
let rows = []
|
||||
let nrows = len(a:rows)
|
||||
let ncols = 0
|
||||
for row in a:rows
|
||||
if len(row) > ncols
|
||||
let ncols = len(row)
|
||||
endif
|
||||
endfor
|
||||
if nrows == 0 || ncols == 0
|
||||
return content
|
||||
endif
|
||||
let sizes = repeat([0], ncols)
|
||||
let index = range(ncols)
|
||||
for row in a:rows
|
||||
let newrow = deepcopy(row)
|
||||
if len(newrow) < ncols
|
||||
let newrow += repeat([''], ncols - len(newrow))
|
||||
endif
|
||||
for i in index
|
||||
let size = strwidth(newrow[i])
|
||||
let sizes[i] = (sizes[i] < size)? size : sizes[i]
|
||||
endfor
|
||||
let rows += [newrow]
|
||||
endfor
|
||||
for row in rows
|
||||
let ni = []
|
||||
for i in index
|
||||
let x = row[i]
|
||||
let size = strwidth(x)
|
||||
if size < sizes[i]
|
||||
let x = x . repeat(' ', sizes[i] - size)
|
||||
endif
|
||||
let ni += [x]
|
||||
endfor
|
||||
let content += [ni]
|
||||
endfor
|
||||
return content
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" print table
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#utils#print_table(rows, highmap)
|
||||
let content = quickui#utils#tabulify(a:rows)
|
||||
let index = 0
|
||||
for line in content
|
||||
let col = 0
|
||||
echon (index == 0)? " " : "\n "
|
||||
for cell in line
|
||||
let key = index . ',' . col
|
||||
if !has_key(a:highmap, key)
|
||||
echohl None
|
||||
else
|
||||
exec 'echohl ' . a:highmap[key]
|
||||
endif
|
||||
echon cell . ' '
|
||||
let col += 1
|
||||
endfor
|
||||
let index += 1
|
||||
endfor
|
||||
echohl None
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
|
757
vim/.vim/autoload/quickui/window.vim
Normal file
757
vim/.vim/autoload/quickui/window.vim
Normal file
@ -0,0 +1,757 @@
|
||||
"======================================================================
|
||||
"
|
||||
" window.vim -
|
||||
"
|
||||
" Created by skywind on 2021/12/08
|
||||
" Last Modified: 2021/12/08 23:45
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set ts=4 sw=4 tw=78 noet :
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" window class
|
||||
"----------------------------------------------------------------------
|
||||
let s:window = {}
|
||||
let s:window.w = 1 " window width
|
||||
let s:window.h = 1 " window height
|
||||
let s:window.x = 1 " column starting from 0
|
||||
let s:window.y = 1 " row starting from 0
|
||||
let s:window.z = 40 " priority
|
||||
let s:window.winid = -1 " window id
|
||||
let s:window.dirty = 0 " need update buffer ?
|
||||
let s:window.text = [] " text lines
|
||||
let s:window.bid = -1 " allocated buffer id
|
||||
let s:window.hide = 0 " visibility
|
||||
let s:window.mode = 0 " mode: 0/created, 1/closed
|
||||
let s:window.opts = {} " creation options
|
||||
let s:window.info = {} " init environment
|
||||
let s:window.quit = 0 " closed by button ? (vim only)
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" internal
|
||||
"----------------------------------------------------------------------
|
||||
let s:has_nvim = g:quickui#core#has_nvim
|
||||
let s:has_nvim_060 = g:quickui#core#has_nvim_060
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" prepare opts
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.__prepare_opts(textlist, opts)
|
||||
let opts = deepcopy(a:opts)
|
||||
let opts.x = get(a:opts, 'x', 1)
|
||||
let opts.y = get(a:opts, 'y', 1)
|
||||
let opts.z = get(a:opts, 'z', 40)
|
||||
let opts.w = get(a:opts, 'w', 1)
|
||||
let opts.h = get(a:opts, 'h', -1)
|
||||
let opts.hide = get(a:opts, 'hide', 0)
|
||||
let opts.wrap = get(a:opts, 'wrap', 0)
|
||||
let opts.color = get(a:opts, 'color', 'QuickBG')
|
||||
let opts.border = get(a:opts, 'border', 0)
|
||||
let self.opts = opts
|
||||
let self.bid = quickui#core#buffer_alloc()
|
||||
let self.dirty = 1
|
||||
let self.x = opts.x
|
||||
let self.y = opts.y
|
||||
let self.z = opts.z
|
||||
let self.w = (opts.w < 1)? 1 : (opts.w)
|
||||
let self.h = (opts.h < 1)? 1 : (opts.h)
|
||||
let self.hide = opts.hide
|
||||
let self.mode = 0
|
||||
if has_key(a:opts, 'padding')
|
||||
let self.opts.padding = a:opts.padding
|
||||
else
|
||||
let self.opts.padding = [0,0,0,0]
|
||||
endif
|
||||
let pad = self.opts.padding
|
||||
let info = self.info
|
||||
let info.tw = self.w + pad[1] + pad[3]
|
||||
let info.th = self.h + pad[0] + pad[2]
|
||||
let sum_pad = pad[0] + pad[1] + pad[2] + pad[3]
|
||||
let info.has_padding = (sum_pad > 0)? 1 : 0
|
||||
let border = quickui#core#border_auto(self.opts.border)
|
||||
let info.has_border = (self.opts.border > 0)? 1 : 0
|
||||
if info.has_border != 0
|
||||
let info.tw += 2
|
||||
let info.th += 2
|
||||
endif
|
||||
" echom info
|
||||
call self.set_text(a:textlist)
|
||||
if opts.h < 0
|
||||
let opts.h = len(self.text)
|
||||
endif
|
||||
let cmd = []
|
||||
if has_key(opts, 'tabstop')
|
||||
let cmd += ['setl tabstop=' . get(opts, 'tabstop', 4)]
|
||||
endif
|
||||
if has_key(opts, 'list')
|
||||
let cmd += [(opts.list)? 'setl list' : 'setl nolist']
|
||||
else
|
||||
let cmd += ['setl nolist']
|
||||
endif
|
||||
if get(opts, 'number', 0) != 0
|
||||
let cmd += ['setl number']
|
||||
else
|
||||
let cmd += ['setl nonumber']
|
||||
endif
|
||||
let cmd += ['setl scrolloff=0']
|
||||
let cmd += ['setl signcolumn=no']
|
||||
if has_key(opts, 'syntax')
|
||||
let cmd += ['set ft=' . fnameescape(opts.syntax)]
|
||||
endif
|
||||
if has_key(opts, 'cursorline')
|
||||
let need = (opts.cursorline)? 'cursorline' : 'nocursorlin'
|
||||
let cmd += ['setl ' . need]
|
||||
if exists('+cursorlineopt')
|
||||
let cmd += ['setl cursorlineopt=both']
|
||||
endif
|
||||
else
|
||||
let cmd += ['setl nocursorline']
|
||||
endif
|
||||
let cmd += ['setl nocursorcolumn nospell']
|
||||
let cmd += [opts.wrap? 'setl wrap' : 'setl nowrap']
|
||||
if has_key(opts, 'command')
|
||||
let command = opts.command
|
||||
if type(command) == type([])
|
||||
let cmd += command
|
||||
else
|
||||
let cmd += [''. command]
|
||||
endif
|
||||
endif
|
||||
let info.cmd = cmd
|
||||
let info.pending_cmd = []
|
||||
let info.border_winid = -1
|
||||
let info.border_bid = -1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" win filter
|
||||
"----------------------------------------------------------------------
|
||||
function! s:popup_filter(winid, key)
|
||||
let local = quickui#core#popup_local(a:winid)
|
||||
let hwnd = local.window_hwnd
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" exited
|
||||
"----------------------------------------------------------------------
|
||||
function! s:popup_exit(winid, code)
|
||||
let local = quickui#core#popup_local(a:winid)
|
||||
let hwnd = local.window_hwnd
|
||||
call quickui#core#popup_clear(a:winid)
|
||||
let hwnd.quit = 1
|
||||
let hwnd.winid = -1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create window in vim
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.__vim_create()
|
||||
let opts = {"hidden":1, "pos": 'topleft'}
|
||||
let opts.hidden = 1
|
||||
let opts.wrap = self.opts.wrap
|
||||
let opts.minwidth = self.w
|
||||
let opts.maxwidth = self.w
|
||||
let opts.minheight = self.h
|
||||
let opts.maxheight = self.h
|
||||
let opts.col = self.x + 1
|
||||
let opts.line = self.y + 1
|
||||
let opts.mapping = 0
|
||||
let opts.fixed = (opts.wrap == 0)? 1 : 0
|
||||
let opts.cursorline = get(self.opts, 'cursorline', 0)
|
||||
let opts.drag = get(self.opts, 'drag', 0)
|
||||
let opts.scrollbar = 0
|
||||
let opts.zindex = self.z + 1
|
||||
if get(self.opts, 'button', 0) != 0
|
||||
let opts.close = 'button'
|
||||
endif
|
||||
let self.winid = popup_create(self.bid, opts)
|
||||
let winid = self.winid
|
||||
let local = quickui#core#popup_local(winid)
|
||||
let local.window_hwnd = self
|
||||
let init = []
|
||||
let init += ['setlocal nonumber signcolumn=no scrolloff=0']
|
||||
call quickui#core#win_execute(winid, init, 1)
|
||||
let opts = {}
|
||||
let opts.filter = function('s:popup_filter')
|
||||
let opts.callback = function('s:popup_exit')
|
||||
let opts.highlight = self.opts.color
|
||||
let border = quickui#core#border_auto(self.opts.border)
|
||||
if self.info.has_border
|
||||
let opts.borderchars = border
|
||||
let opts.border = [1,1,1,1,1,1,1,1,1]
|
||||
let bc = get(self.opts, 'bordercolor', 'QuickBorder')
|
||||
let opts.borderhighlight = [bc, bc, bc, bc]
|
||||
if has_key(self.opts, 'title')
|
||||
let opts.title = self.opts.title
|
||||
endif
|
||||
endif
|
||||
if has_key(self.opts, 'padding')
|
||||
let opts.padding = self.opts.padding
|
||||
endif
|
||||
call setwinvar(winid, '&wincolor', self.opts.color)
|
||||
call popup_setoptions(winid, opts)
|
||||
call quickui#core#win_execute(winid, self.info.cmd)
|
||||
let pc = self.info.pending_cmd
|
||||
if len(pc) > 0
|
||||
call quickui#core#win_execute(winid, pc)
|
||||
let self.info.pending_cmd = []
|
||||
endif
|
||||
let self.mode = 1
|
||||
if get(self.opts, 'center', 0) != 0
|
||||
call self.center()
|
||||
endif
|
||||
if self.hide == 0
|
||||
call popup_show(winid)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" create window in nvim
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.__nvim_create()
|
||||
let opts = {'focusable':0, 'style':'minimal', 'relative':'editor'}
|
||||
let opts.row = self.y
|
||||
let opts.col = self.x
|
||||
let opts.width = self.w
|
||||
let opts.height = self.h
|
||||
let opts.focusable = get(self.opts, 'focusable', 0)
|
||||
if s:has_nvim_060
|
||||
let opts.noautocmd = 1
|
||||
let opts.zindex = self.z + 1
|
||||
endif
|
||||
let info = self.info
|
||||
let info.nvim_opts = opts
|
||||
let info.sim_border = 0
|
||||
let info.off_x = 0
|
||||
let info.off_y = 0
|
||||
let pad = self.opts.padding
|
||||
if info.has_border
|
||||
let info.sim_border = 1
|
||||
let info.off_x = 1
|
||||
let info.off_y = 1
|
||||
if info.has_padding
|
||||
let info.sim_border = 1
|
||||
let info.off_x += pad[3]
|
||||
let info.off_y += pad[0]
|
||||
endif
|
||||
endif
|
||||
if info.has_border
|
||||
let tw = info.tw
|
||||
let th = info.th
|
||||
let opts.col += info.off_x
|
||||
let opts.row += info.off_y
|
||||
let t = get(self.opts, 'title', '')
|
||||
let b = get(self.opts, 'button', 0)
|
||||
let border = self.opts.border
|
||||
let back = quickui#utils#make_border(tw - 2, th - 2, border, t, b)
|
||||
let info.border_bid = quickui#core#buffer_alloc()
|
||||
call quickui#core#buffer_update(info.border_bid, back)
|
||||
let op = {'relative':'editor', 'focusable':0, 'style':'minimal'}
|
||||
let op.focusable = get(self.opts, 'focusable', 0)
|
||||
let op.width = tw
|
||||
let op.height = th
|
||||
let op.col = self.x
|
||||
let op.row = self.y
|
||||
if s:has_nvim_060
|
||||
let op.noautocmd = 1
|
||||
let op.zindex = self.z
|
||||
endif
|
||||
let info.border_opts = op
|
||||
let init = []
|
||||
let init += ['setl tabstop=' . get(self.opts, 'tabstop', 4)]
|
||||
let init += ['setl signcolumn=no scrolloff=0 nowrap nonumber']
|
||||
let init += ['setl nocursorline nolist']
|
||||
if exists('+cursorlineopt')
|
||||
let init += ['setl cursorlineopt=both']
|
||||
endif
|
||||
let info.border_init = init
|
||||
endif
|
||||
let self.mode = 1
|
||||
if get(self.opts, 'center', 0) != 0
|
||||
call self.center()
|
||||
endif
|
||||
if self.hide == 0
|
||||
call self.__nvim_show()
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" nvim - show window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.__nvim_show()
|
||||
if self.mode == 0
|
||||
return
|
||||
elseif self.winid >= 0
|
||||
return
|
||||
endif
|
||||
call self.move(self.x, self.y)
|
||||
let info = self.info
|
||||
let winid = nvim_open_win(self.bid, 0, info.nvim_opts)
|
||||
let self.winid = winid
|
||||
let color = self.opts.color
|
||||
call quickui#core#win_execute(winid, info.cmd)
|
||||
if len(info.pending_cmd) > 0
|
||||
call quickui#core#win_execute(winid, info.pending_cmd)
|
||||
let info.pending_cmd = []
|
||||
endif
|
||||
call nvim_win_set_option(self.winid, 'winhl', 'Normal:'. color)
|
||||
if info.has_border
|
||||
let bwid = nvim_open_win(info.border_bid, 0, info.border_opts)
|
||||
let info.border_winid = bwid
|
||||
call quickui#core#win_execute(bwid, info.border_init)
|
||||
call nvim_win_set_option(bwid, 'winhl', 'Normal:'. color)
|
||||
endif
|
||||
let self.hide = 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" nvim - hide window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.__nvim_hide()
|
||||
if self.mode == 0
|
||||
return
|
||||
elseif self.winid < 0
|
||||
return
|
||||
endif
|
||||
let info = self.info
|
||||
if info.border_winid >= 0
|
||||
call nvim_win_close(info.border_winid, 1)
|
||||
let info.border_winid = -1
|
||||
endif
|
||||
if self.winid >= 0
|
||||
call nvim_win_close(self.winid, 1)
|
||||
let self.winid = -1
|
||||
endif
|
||||
let self.hide = 1
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" open window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.open(textlist, opts)
|
||||
call self.close()
|
||||
call self.__prepare_opts(a:textlist, a:opts)
|
||||
if s:has_nvim == 0
|
||||
call self.__vim_create()
|
||||
else
|
||||
call self.__nvim_create()
|
||||
endif
|
||||
let self.mode = 1
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" close window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.close()
|
||||
if self.winid >= 0
|
||||
if s:has_nvim == 0
|
||||
call popup_close(self.winid)
|
||||
else
|
||||
call nvim_win_close(self.winid, 1)
|
||||
if self.info.border_winid >= 0
|
||||
call nvim_win_close(self.info.border_winid, 1)
|
||||
let self.info.border_winid = -1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let self.winid = -1
|
||||
if self.bid >= 0
|
||||
call quickui#core#buffer_free(self.bid)
|
||||
let self.bid = -1
|
||||
endif
|
||||
if has_key(self.info, 'border_bid')
|
||||
if self.info.border_bid >= 0
|
||||
call quickui#core#buffer_free(self.info.border_bid)
|
||||
let self.info.border_bid = -1
|
||||
endif
|
||||
endif
|
||||
let self.hide = 0
|
||||
let self.mode = 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" show the window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.show(show)
|
||||
if self.mode == 0
|
||||
return
|
||||
elseif s:has_nvim == 0
|
||||
if a:show == 0
|
||||
if self.winid >= 0
|
||||
call popup_hide(self.winid)
|
||||
endif
|
||||
else
|
||||
if self.winid >= 0
|
||||
call popup_show(self.winid)
|
||||
endif
|
||||
endif
|
||||
else
|
||||
if a:show == 0
|
||||
call self.__nvim_hide()
|
||||
else
|
||||
call self.__nvim_show()
|
||||
endif
|
||||
endif
|
||||
let self.hide = (a:show == 0)? 1 : 0
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" move window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.__move(x, y)
|
||||
let self.x = a:x
|
||||
let self.y = a:y
|
||||
if self.mode == 0
|
||||
return
|
||||
elseif s:has_nvim == 0
|
||||
if self.winid >= 0
|
||||
let opts = {}
|
||||
let opts.col = self.x + 1
|
||||
let opts.line = self.y + 1
|
||||
call popup_move(self.winid, opts)
|
||||
endif
|
||||
else
|
||||
let info = self.info
|
||||
let opts = info.nvim_opts
|
||||
let opts.col = self.x + info.off_x
|
||||
let opts.row = self.y + info.off_y
|
||||
if info.has_border != 0
|
||||
let opts = info.border_opts
|
||||
let opts.col = self.x
|
||||
let opts.row = self.y
|
||||
endif
|
||||
if self.winid >= 0
|
||||
let op = {'relative':'editor'}
|
||||
let op.col = info.nvim_opts.col
|
||||
let op.row = info.nvim_opts.row
|
||||
call nvim_win_set_config(self.winid, op)
|
||||
endif
|
||||
if info.has_border != 0
|
||||
if info.border_winid >= 0
|
||||
let op = {'relative':'editor'}
|
||||
let op.col = info.border_opts.col
|
||||
let op.row = info.border_opts.row
|
||||
call nvim_win_set_config(info.border_winid, op)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" actual move
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.move(x, y)
|
||||
let x = a:x
|
||||
let y = a:y
|
||||
let w = self.info.tw
|
||||
let h = self.info.th
|
||||
let sw = &columns
|
||||
let sh = &lines
|
||||
let x = (x + w > sw)? (sw - w) : x
|
||||
let y = (y + h > sh)? (sh - h) : y
|
||||
let x = (x < 0)? 0 : x
|
||||
let y = (y < 0)? 0 : y
|
||||
" unsilent echom ['move', x, a:x, self.opts.x]
|
||||
call self.__move(x, y)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" center window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.center(...)
|
||||
let w = self.w
|
||||
let h = self.h
|
||||
let style = (a:0 < 1)? 0 : (a:1)
|
||||
if self.mode != 0
|
||||
let w = self.info.tw
|
||||
let h = self.info.th
|
||||
endif
|
||||
let x = (&columns - w) / 2
|
||||
if style == 0
|
||||
let height = &lines - &cmdheight - 1
|
||||
let middle = height * 38 / 100
|
||||
let y = middle - (h + 1) / 2
|
||||
let y = (y < 0)? 0 : y
|
||||
else
|
||||
let y = (&lines - h) / 2
|
||||
let limit1 = (&lines - 2) * 80 / 100
|
||||
let limit2 = (&lines - 2)
|
||||
if h + 8 < limit1
|
||||
let y = (limit1 - h) / 2
|
||||
else
|
||||
let y = (limit2 - h) / 2
|
||||
endif
|
||||
endif
|
||||
call self.move(x, y)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" resize
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.resize(w, h)
|
||||
let self.w = a:w
|
||||
let self.h = a:h
|
||||
let info = self.info
|
||||
if self.mode == 0
|
||||
let info.tw = self.w
|
||||
let info.th = self.h
|
||||
return
|
||||
endif
|
||||
let pad = self.opts.padding
|
||||
let info.tw = self.w + pad[1] + pad[3]
|
||||
let info.th = self.h + pad[0] + pad[2]
|
||||
let info.tw += (info.has_border? 2 : 0)
|
||||
let info.th += (info.has_border? 2 : 0)
|
||||
if self.winid < 0
|
||||
return
|
||||
endif
|
||||
if s:has_nvim == 0
|
||||
let opts = {}
|
||||
let opts.minwidth = self.w
|
||||
let opts.maxwidth = self.w
|
||||
let opts.minheight = self.h
|
||||
let opts.maxheight = self.h
|
||||
call popup_move(self.winid, opts)
|
||||
else
|
||||
let opts = info.nvim_opts
|
||||
let opts.width = self.w
|
||||
let opts.height = self.h
|
||||
if info.has_border
|
||||
let opts = info.border_opts
|
||||
let opts.width = info.tw
|
||||
let opts.height = info.th
|
||||
let t = get(self.opts, 'title', '')
|
||||
let b = self.opts.border
|
||||
let tw = info.tw
|
||||
let th = info.th
|
||||
let btn = get(self.opts, 'button', 0)
|
||||
let back = quickui#utils#make_border(tw - 2, th - 2, b, t, btn)
|
||||
call quickui#core#buffer_update(info.border_bid, back)
|
||||
endif
|
||||
if self.winid >= 0
|
||||
let op = {'width':self.w, 'height':self.h}
|
||||
call nvim_win_set_config(self.winid, op)
|
||||
if info.has_border
|
||||
if info.border_winid >= 0
|
||||
let op = {'width':info.tw, 'height':info.th}
|
||||
call nvim_win_set_config(info.border_winid, op)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" execute commands
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.execute(cmdlist)
|
||||
if type(a:cmdlist) == v:t_string
|
||||
let cmd = split(a:cmdlist, '\n')
|
||||
else
|
||||
let cmd = a:cmdlist
|
||||
endif
|
||||
let winid = self.winid
|
||||
if winid >= 0
|
||||
let pc = self.info.pending_cmd
|
||||
if len(pc) > 0
|
||||
call quickui#core#win_execute(winid, pc)
|
||||
let self.info.pending_cmd = []
|
||||
endif
|
||||
if len(cmd) > 0
|
||||
call quickui#core#win_execute(winid, cmd)
|
||||
endif
|
||||
else
|
||||
if !has_key(self.info, 'pending_cmd')
|
||||
let self.info.pending_cmd = cmd
|
||||
else
|
||||
let self.info.pending_cmd += cmd
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" update text in buffer
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.update()
|
||||
if self.bid >= 0
|
||||
call quickui#core#buffer_update(self.bid, self.text)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" set content
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.set_text(textlist)
|
||||
if type(a:textlist) == v:t_list
|
||||
let textlist = deepcopy(a:textlist)
|
||||
else
|
||||
let textlist = split(a:textlist, '\n', 1)
|
||||
endif
|
||||
let self.text = textlist
|
||||
call self.update()
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" set line
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.set_line(index, text, ...)
|
||||
let require = a:index + 1
|
||||
let refresh = (a:0 < 1)? 1 : (a:1)
|
||||
let index = a:index
|
||||
let update = 0
|
||||
if index < 0
|
||||
return
|
||||
elseif len(self.text) < require
|
||||
let self.text += repeat([''], require - len(self.text))
|
||||
let update = 1
|
||||
endif
|
||||
let self.text[a:index] = a:text
|
||||
if update != 0
|
||||
call self.update()
|
||||
elseif refresh != 0
|
||||
let bid = self.bid
|
||||
if bid >= 0
|
||||
call setbufvar(bid, '&modifiable', 1)
|
||||
call setbufline(bid, index + 1, [a:text])
|
||||
call setbufvar(bid, '&modified', 0)
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" get line
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.get_line(index)
|
||||
if a:index >= len(self.text)
|
||||
return ''
|
||||
endif
|
||||
return self.text[a:index]
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" syntax begin
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.syntax_begin(...)
|
||||
let info = self.info
|
||||
let info.syntax_cmd = ['syn clear']
|
||||
let info.syntax_mod = (a:0 < 1)? 1 : (a:1)
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" flush commands
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.syntax_end()
|
||||
let info = self.info
|
||||
if has_key(info, 'syntax_cmd') != 0
|
||||
if len(info.syntax_cmd) > 0
|
||||
call self.execute(info.syntax_cmd)
|
||||
let info.syntax_cmd = []
|
||||
endif
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" calculate region
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.syntax_region(color, x1, y1, x2, y2)
|
||||
let info = self.info
|
||||
if a:y1 == a:y2 && a:x1 >= a:x2
|
||||
return
|
||||
elseif has_key(info, 'syntax_cmd') != 0
|
||||
let x1 = a:x1 + 1
|
||||
let y1 = a:y1 + 1
|
||||
let x2 = a:x2 + 1
|
||||
let y2 = a:y2 + 1
|
||||
let cc = a:color
|
||||
let mm = info.syntax_mod
|
||||
let cmd = quickui#core#high_region(cc, y1, x1, y2, x2, mm)
|
||||
let info.syntax_cmd += [cmd]
|
||||
" echom cmd
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" click window
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.mouse_click()
|
||||
let winid = self.winid
|
||||
let retval = {'x':-1, 'y':-1}
|
||||
if g:quickui#core#has_nvim == 0
|
||||
let pos = getmousepos()
|
||||
if pos.winid != winid
|
||||
return retval
|
||||
endif
|
||||
if self.info.has_border == 0
|
||||
let retval.x = pos.column - 1
|
||||
let retval.y = pos.line - 1
|
||||
else
|
||||
let retval.x = pos.column - 2
|
||||
let retval.y = pos.line - 2
|
||||
endif
|
||||
else
|
||||
if v:mouse_winid != winid
|
||||
return retval
|
||||
endif
|
||||
if self.info.has_border == 0
|
||||
let retval.x = v:mouse_col - 1
|
||||
let retval.y = v:mouse_lnum - 1
|
||||
else
|
||||
let retval.x = v:mouse_col - 2
|
||||
let retval.y = v:mouse_lnum - 2
|
||||
endif
|
||||
endif
|
||||
return retval
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" refresh redraw
|
||||
"----------------------------------------------------------------------
|
||||
function! s:window.refresh()
|
||||
let winid = self.winid
|
||||
if g:quickui#core#has_nvim == 0
|
||||
if winid >= 0
|
||||
call popup_setoptions(winid, {})
|
||||
endif
|
||||
else
|
||||
endif
|
||||
redraw
|
||||
endfunc
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" constructor
|
||||
"----------------------------------------------------------------------
|
||||
function! quickui#window#new()
|
||||
let obj = deepcopy(s:window)
|
||||
return obj
|
||||
endfunc
|
||||
|
||||
|
19
vim/.vim/colors/quickui/borland.vim
Normal file
19
vim/.vim/colors/quickui/borland.vim
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
hi! QuickDefaultBackground ctermfg=0 ctermbg=7 guifg=black guibg=#c0c0c0
|
||||
hi! QuickDefaultSel cterm=bold ctermfg=0 ctermbg=2 gui=bold guibg=brown guifg=#c0c0c0
|
||||
hi! QuickDefaultKey term=bold ctermfg=9 gui=bold guifg=#f92772
|
||||
hi! QuickDefaultDisable ctermfg=8 guifg=#75715e
|
||||
hi! QuickDefaultHelp ctermfg=8 guifg=#959173
|
||||
hi! QuickDefaultBorder ctermfg=0 ctermbg=7 guifg=black guibg=#c0c0c0
|
||||
hi! QuickDefaultTermBorder ctermfg=0 ctermbg=7 guifg=black guibg=#c0c0c0
|
||||
|
||||
if &background == 'dark'
|
||||
hi! QuickDefaultPreview ctermbg=237 guibg=#4c4846
|
||||
else
|
||||
hi! QuickDefaultPreview ctermbg=12 guibg=#dddddd
|
||||
endif
|
||||
|
||||
hi! QuickDefaultInput ctermfg=7 ctermbg=4 guifg=#e4e4e4 guibg=#0000a0
|
||||
hi! QuickDefaultCursor ctermfg=4 ctermbg=7 guifg=#0000a0 guibg=#e4e4e4
|
||||
hi! QuickDefaultVisual ctermfg=4 ctermbg=15 guifg=#0000a0 guibg=#f4f4f4
|
||||
|
19
vim/.vim/colors/quickui/default.vim
Normal file
19
vim/.vim/colors/quickui/default.vim
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
hi! QuickDefaultBackground ctermfg=0 ctermbg=7 guifg=black guibg=#c0c0c0
|
||||
hi! QuickDefaultSel cterm=bold ctermfg=0 ctermbg=2 gui=bold guibg=brown guifg=#c0c0c0
|
||||
hi! QuickDefaultKey term=bold ctermfg=1 gui=bold guifg=#f92772
|
||||
hi! QuickDefaultDisable ctermfg=6 guifg=#75715e
|
||||
hi! QuickDefaultHelp ctermfg=6 guifg=#959173
|
||||
hi! QuickDefaultBorder ctermfg=0 ctermbg=7 guifg=black guibg=#c0c0c0
|
||||
hi! QuickDefaultTermBorder ctermfg=0 ctermbg=7 guifg=black guibg=#c0c0c0
|
||||
|
||||
if &background == 'dark'
|
||||
hi! QuickDefaultPreview ctermbg=7 guibg=#4c4846
|
||||
else
|
||||
hi! QuickDefaultPreview ctermbg=4 guibg=#dddddd
|
||||
endif
|
||||
|
||||
hi! QuickDefaultInput ctermfg=7 ctermbg=4 guifg=#e4e4e4 guibg=#0000a0
|
||||
hi! QuickDefaultCursor ctermfg=4 ctermbg=7 guifg=#0000a0 guibg=#e4e4e4
|
||||
hi! QuickDefaultVisual ctermfg=4 ctermbg=6 guifg=#0000a0 guibg=#f4f4f4
|
||||
|
19
vim/.vim/colors/quickui/gruvbox.vim
Normal file
19
vim/.vim/colors/quickui/gruvbox.vim
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
hi! QuickDefaultBackground ctermfg=187 ctermbg=239 guifg=#ebdbb2 guibg=#504945
|
||||
hi! QuickDefaultSel cterm=bold ctermfg=239 ctermbg=108 gui=bold guifg=#504945 guibg=#83a598
|
||||
hi! QuickDefaultKey term=bold ctermfg=208 guifg=#fd9720
|
||||
hi! QuickDefaultDisable ctermfg=245 guifg=#928374
|
||||
hi! QuickDefaultHelp ctermfg=109 guifg=#83a598
|
||||
hi! QuickDefaultBorder ctermfg=187 ctermbg=239 guifg=#ebdbb2 guibg=#504945
|
||||
hi! QuickDefaultTermBorder ctermfg=187 ctermbg=239 guifg=#ebdbb2 guibg=#504945
|
||||
|
||||
if &background == 'dark'
|
||||
hi! QuickDefaultPreview ctermbg=237 guibg=#4c4846
|
||||
else
|
||||
hi! QuickDefaultPreview ctermbg=12 guibg=#dddddd
|
||||
endif
|
||||
|
||||
hi! QuickDefaultInput ctermfg=233 ctermbg=235 guifg=#ebdbb2 guibg=#282828
|
||||
hi! QuickDefaultCursor ctermfg=235 ctermbg=233 guifg=#282828 guibg=#ebdbb2
|
||||
hi! QuickDefaultVisual ctermfg=241 ctermbg=233 guifg=#665c54 guibg=#ebdbb2
|
||||
|
19
vim/.vim/colors/quickui/papercol_dark.vim
Normal file
19
vim/.vim/colors/quickui/papercol_dark.vim
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
hi! QuickDefaultBackground ctermfg=251 ctermbg=236 guifg=#c6c6c6 guibg=#303030
|
||||
hi! QuickDefaultSel ctermfg=236 ctermbg=251 guifg=#303030 guibg=#c6c6c6
|
||||
hi! QuickDefaultKey term=bold ctermfg=179 gui=bold guifg=#d7af5f
|
||||
hi! QuickDefaultDisable ctermfg=11 guifg=#808080
|
||||
hi! QuickDefaultHelp ctermfg=7 ctermbg=8 guifg=#585858 guibg=#1c1c1c
|
||||
hi! QuickDefaultBorder ctermfg=66 ctermbg=236 guifg=#5f8787 guibg=#303030
|
||||
hi! QuickDefaultTermBorder ctermfg=66 ctermbg=236 guifg=#5f8787 guibg=#303030
|
||||
|
||||
if &background == 'dark'
|
||||
hi! QuickDefaultPreview ctermbg=237 guibg=#4c4846
|
||||
else
|
||||
hi! QuickDefaultPreview ctermbg=12 guibg=#dddddd
|
||||
endif
|
||||
|
||||
hi! QuickDefaultInput ctermfg=252 ctermbg=234 guifg=#d0d0d0 guibg=#1c1c1c
|
||||
hi! QuickDefaultCursor ctermfg=234 ctermbg=252 guifg=#1c1c1c guibg=#d0d0d0
|
||||
hi! QuickDefaultVisual ctermfg=8 ctermbg=255 guifg=#000000 guibg=#8787af
|
||||
|
32
vim/.vim/colors/quickui/papercol_light.vim
Normal file
32
vim/.vim/colors/quickui/papercol_light.vim
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
hi! QuickDefaultBackground ctermfg=238 ctermbg=252 guifg=#444444 guibg=#d0d0d0
|
||||
hi! QuickDefaultSel ctermfg=252 ctermbg=238 guifg=#d0d0d0 guibg=#444444
|
||||
hi! QuickDefaultKey term=bold ctermfg=162 gui=bold guifg=#d70087
|
||||
hi! QuickDefaultDisable term=bold ctermfg=1 guifg=#878787
|
||||
" hi! QuickDefaultHelp ctermfg=7 ctermbg=8 guifg=#b2b2b2 guibg=#eeeeee
|
||||
hi! QuickDefaultHelp ctermfg=247 guifg=#959173
|
||||
" hi! QuickDefaultBorder ctermfg=31 ctermbg=252 guifg=#0087af guibg=#d0d0d0
|
||||
" hi! QuickDefaultBorder ctermfg=31 ctermbg=252 guifg=#222222 guibg=#d0d0d0
|
||||
hi! QuickDefaultBorder ctermfg=24 ctermbg=252 guifg=#005f87 guibg=#d0d0d0
|
||||
" hi! QuickDefaultBorder ctermfg=24 ctermbg=252 guifg=#d70087 guibg=#d0d0d0
|
||||
" hi! QuickDefaultTermBorder ctermfg=24 ctermbg=252 guifg=#005f87 guibg=#d0d0d0
|
||||
hi! QuickDefaultTermBorder ctermfg=51 guifg=cyan
|
||||
|
||||
if &background == 'dark'
|
||||
hi! QuickDefaultPreview ctermbg=237 guibg=#4c4846
|
||||
else
|
||||
hi! QuickDefaultPreview ctermbg=12 guibg=#dddddd
|
||||
endif
|
||||
|
||||
hi! QuickDefaultMatch0 ctermfg=166 guifg=#d75f00
|
||||
hi! QuickDefaultMatch1 ctermfg=31 guifg=#0087af
|
||||
hi! QuickDefaultMatch2 ctermfg=25 guifg=#005faf
|
||||
hi! QuickDefaultMatch3 ctermfg=64 guifg=#5f8700
|
||||
hi! QuickDefaultMatch4 ctermfg=91 guifg=#8700af
|
||||
hi! QuickDefaultMatch5 ctermfg=247 guifg=#a2a2a2
|
||||
|
||||
hi! QuickDefaultInput ctermfg=254 ctermbg=24 guifg=#e4e4e4 guibg=#005f87
|
||||
hi! QuickDefaultCursor ctermfg=238 ctermbg=222 guifg=#444444 guibg=#ffd787
|
||||
hi! QuickDefaultVisual ctermfg=31 ctermbg=255 guifg=#0087af guibg=#eeeeee
|
||||
|
||||
|
19
vim/.vim/colors/quickui/solarized.vim
Normal file
19
vim/.vim/colors/quickui/solarized.vim
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
hi! QuickDefaultBackground ctermfg=235 ctermbg=246 guifg=#073642 guibg=#839496
|
||||
hi! QuickDefaultSel ctermfg=254 ctermbg=241 guifg=#eee8d5 guibg=#586e75
|
||||
hi! QuickDefaultKey ctermfg=166 guifg=#cb4b16
|
||||
hi! QuickDefaultDisable ctermfg=242 guifg=#586e75
|
||||
hi! QuickDefaultHelp ctermfg=32 guifg=#268bd2
|
||||
hi! QuickDefaultBorder ctermfg=235 ctermbg=246 guifg=#073642 guibg=#839496
|
||||
hi! QuickDefaultTermBorder ctermfg=235 ctermbg=246 guifg=#073642 guibg=#839496
|
||||
|
||||
if &background == 'dark'
|
||||
hi! QuickDefaultPreview ctermbg=237 guibg=#4c4846
|
||||
else
|
||||
hi! QuickDefaultPreview ctermbg=12 guibg=#dddddd
|
||||
endif
|
||||
|
||||
hi! QuickDefaultInput ctermfg=244 ctermbg=234 guifg=#839496 guibg=#002b36
|
||||
hi! QuickDefaultCursor ctermfg=234 ctermbg=234 guifg=#002b36 guibg=#839496
|
||||
hi! QuickDefaultVisual ctermfg=234 ctermbg=239 guifg=#002b36 guibg=DarkGray
|
||||
|
21
vim/.vim/colors/quickui/system.vim
Normal file
21
vim/.vim/colors/quickui/system.vim
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
hi! link QuickDefaultBackground Pmenu
|
||||
hi! link QuickDefaultSel PmenuSel
|
||||
hi! link QuickDefaultKey Title
|
||||
hi! link QuickDefaultDisable Comment
|
||||
hi! link QuickDefaultHelp Conceal
|
||||
hi! link QuickDefaultBorder Pmenu
|
||||
hi! link QuickDefaultTermBorder Pmenu
|
||||
|
||||
if &background == 'dark'
|
||||
hi! QuickDefaultPreview ctermbg=237 guibg=#4c4846
|
||||
else
|
||||
hi! QuickDefaultPreview ctermbg=12 guibg=#dddddd
|
||||
endif
|
||||
|
||||
|
||||
hi! link QuickDefaultInput NonText
|
||||
hi! link QuickDefaultCursor Cursor
|
||||
hi! link QuickDefaultVisual Visual
|
||||
|
||||
|
@ -1,3 +1 @@
|
||||
au BufRead,BufNewFile *.hsc set filetype=haskell
|
||||
au BufRead,BufNewFile *.bpk set filetype=haskell
|
||||
au BufRead,BufNewFile *.hsig set filetype=haskell
|
||||
au BufRead,BufNewFile *.hsc,*.bpk,*.hsig set filetype=haskell
|
||||
|
4
vim/.vim/ftdetect/nim.vim
Normal file
4
vim/.vim/ftdetect/nim.vim
Normal file
@ -0,0 +1,4 @@
|
||||
augroup nim_vim
|
||||
au BufNewFile,BufRead *.nim,*.nims,*.nimble set filetype=nim
|
||||
augroup END
|
||||
|
1
vim/.vim/ftdetect/python.vim
Normal file
1
vim/.vim/ftdetect/python.vim
Normal file
@ -0,0 +1 @@
|
||||
au BufRead,BufNewFile *.py set noexpandtab
|
@ -1,2 +1,4 @@
|
||||
runtime! ftplugin/html.vim
|
||||
|
||||
autocmd BufNewFile,BufRead *.xml,*ui
|
||||
\ runtime! ftplugin/html.vim |
|
||||
\ let g:xml_syntax_folding=1 |
|
||||
\ set foldmethod=syntax
|
||||
|
@ -9,27 +9,31 @@ input_filename = ''
|
||||
preprocessor='clang -fdirectives-only -E {input_} -o {output}'
|
||||
tags_filename = 'vim.tags'
|
||||
polution_directory = './'
|
||||
action = 'hi'
|
||||
|
||||
def print2(s):
|
||||
print(s, file=sys.stderr)
|
||||
|
||||
def usage(name, x):
|
||||
print2("Usage: {0} <options>".format(name))
|
||||
print2("Usage: {0} <options> <verb>".format(name))
|
||||
print2("\t-h")
|
||||
print2("\t-i <file>")
|
||||
print2("\t-p <cmd>")
|
||||
print2("\t-t <path>")
|
||||
print2("\t-i <file> : input")
|
||||
print2("\t-p <cmd> : preprocessor (e.g.: 'clang -fdirectives-only -E {input_} -o {output}')")
|
||||
print2("\t-t <path> : polution directory")
|
||||
print2("\t---")
|
||||
print2("\thi")
|
||||
print2("\tsig")
|
||||
exit(x)
|
||||
|
||||
def opts(args):
|
||||
global input_filename, preprocessor, polution_directory
|
||||
global input_filename, preprocessor, polution_directory, action
|
||||
|
||||
try:
|
||||
i = args.index("--help") if "--help" in args else -1
|
||||
if i != -1:
|
||||
usage(args[0], 1)
|
||||
else:
|
||||
for idx, arg in enumerate(args[1:]):
|
||||
for idx, arg in enumerate(args[1:]): # this is terrible
|
||||
if arg in ("-h", "--help"):
|
||||
usage(args[0], 0)
|
||||
elif arg == "-i":
|
||||
@ -38,6 +42,10 @@ def opts(args):
|
||||
preprocessor = args[idx + 2]
|
||||
elif arg == "-t":
|
||||
polution_directory = args[idx + 2]
|
||||
elif arg == "hi":
|
||||
action = "hi"
|
||||
elif arg == "sig":
|
||||
action = "sig"
|
||||
except IndexError:
|
||||
usage(args[0], 1)
|
||||
if input_filename == '':
|
||||
@ -79,7 +87,7 @@ targets = [
|
||||
'type': 'u',
|
||||
'out': hi('Type')
|
||||
},
|
||||
{
|
||||
{
|
||||
'type': 'g',
|
||||
'out': hi('Type')
|
||||
},
|
||||
@ -92,15 +100,16 @@ targets = [
|
||||
'out': hi('Identifier')
|
||||
},
|
||||
]
|
||||
PATTERN_INDEX = 1 - 1
|
||||
TYPE_INDEX = 4 - 1
|
||||
NAME_INDEX = (1) - 1
|
||||
PATTERN_INDEX = (3) - 1
|
||||
TYPE_INDEX = (4) - 1
|
||||
|
||||
def do_ignore(row):
|
||||
IGNORE_IF_BEGINS_WITH = '!_'
|
||||
for i in IGNORE_IF_BEGINS_WITH:
|
||||
if row[0][0] == i:
|
||||
return True
|
||||
if row[PATTERN_INDEX].find('operator') != -1:
|
||||
if row[NAME_INDEX].find('operator') != -1:
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -131,7 +140,7 @@ def file2tags(filename, flags):
|
||||
|
||||
def tags2hi(filename):
|
||||
output = set()
|
||||
print2(filename)
|
||||
#print2(filename)
|
||||
try:
|
||||
with open(filename) as f:
|
||||
csv_reader = csv.reader(f, delimiter='\t')
|
||||
@ -141,14 +150,41 @@ def tags2hi(filename):
|
||||
for t in targets:
|
||||
try:
|
||||
if t['type'] == row[TYPE_INDEX]:
|
||||
output.add(render(t, re.escape(row[PATTERN_INDEX])))
|
||||
output.add(render(t, re.escape(row[NAME_INDEX])))
|
||||
except:
|
||||
print2(row)
|
||||
#print2(row)
|
||||
pass
|
||||
except FileNotFoundError as e:
|
||||
print2(sys.argv[0] + ": No such file or directory '{0}'.".format(filename))
|
||||
exit(1)
|
||||
return output
|
||||
|
||||
def pattern2signature(name, pattern):
|
||||
start = pattern.find(name)
|
||||
if pattern.find(')') != -1:
|
||||
end = pattern.find(')') + 1
|
||||
else:
|
||||
end = pattern.find('$')
|
||||
return pattern[start : end]
|
||||
|
||||
has_signature = ['f', 'p']
|
||||
|
||||
def tags2sigs(filename):
|
||||
output = dict()
|
||||
#print2(filename)
|
||||
with open(filename) as f:
|
||||
csv_reader = csv.reader(f, delimiter='\t')
|
||||
for row in csv_reader:
|
||||
if do_ignore(row):
|
||||
continue
|
||||
if row[TYPE_INDEX] in has_signature:
|
||||
signature = pattern2signature(row[NAME_INDEX], row[PATTERN_INDEX])
|
||||
if row[NAME_INDEX] in output:
|
||||
output[row[NAME_INDEX]].append(signature)
|
||||
else:
|
||||
output[row[NAME_INDEX]] = [signature]
|
||||
return output
|
||||
|
||||
def main(argv):
|
||||
global input_filename
|
||||
opts(argv)
|
||||
@ -162,9 +198,12 @@ def main(argv):
|
||||
if language != '':
|
||||
input_filename = preprocessfile(input_filename)
|
||||
flags += ' --language-force={0} '.format(language)
|
||||
output = tags2hi(file2tags(input_filename, flags))
|
||||
output = sorted(output)
|
||||
output = '\n'.join(output)
|
||||
if action == 'hi':
|
||||
output = tags2hi(file2tags(input_filename, flags))
|
||||
output = sorted(output)
|
||||
output = '\n'.join(output)
|
||||
elif action == 'sig':
|
||||
output = "let signatures = " + str(tags2sigs(file2tags(input_filename, flags)))
|
||||
print(output)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
33
vim/.vim/plugin/escape_dictionary.vim
Normal file
33
vim/.vim/plugin/escape_dictionary.vim
Normal file
@ -0,0 +1,33 @@
|
||||
" NOTE: keys() & values() return their results in arbitrary order
|
||||
let s:colorKeys = ['red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'black', 'white', 'bold', 'italics', 'normal', 'reverse']
|
||||
let s:colorValues = [ '31', '32', '33', '34', '35', '36', '30', '37', '1', '3', '0', '7']
|
||||
|
||||
function! s:ColorSelected(id, result)
|
||||
let val = '\033[' . s:colorValues[a:result-1] . 'm'
|
||||
exec 'normal! i' . val
|
||||
endfunction
|
||||
|
||||
function! ShowEscapeDictionary()
|
||||
call popup_menu(s:colorKeys, #{
|
||||
\ callback: 's:ColorSelected',
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
command! ShowEscapeDictionary call ShowEscapeDictionary()
|
||||
|
||||
|
||||
let s:makeKeys = ['target', 'star', 'first pre.', 'all new pre.', 'all pre.', 'uniq all pre.', 'basename target']
|
||||
let s:makeValues = [ '@', '%', '<', '?', '+', '^', '*']
|
||||
|
||||
function! s:MakeSelected(id, result)
|
||||
let val = '$' . s:makeValues[a:result-1]
|
||||
exec 'normal! i' . val
|
||||
endfunction
|
||||
|
||||
function! ShowMakeDictionary()
|
||||
call popup_menu(s:makeKeys, #{
|
||||
\ callback: 's:MakeSelected',
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
command! ShowMakeDictionary call ShowMakeDictionary()
|
@ -11,28 +11,83 @@
|
||||
" otherwise you are responsible for creating your own
|
||||
let s:polution_directory = expand('~/.vim/plugin/HiTags/')
|
||||
|
||||
" Compiler to use for preprocessing C/C++, so headers are respected
|
||||
" Either use "clang" or "gcc" or something compatible,
|
||||
" alternatively you will have to edit s:preprocessor
|
||||
let s:preprocessor_executable = "clang"
|
||||
" Compiler_Collection_based_Preprocessing:
|
||||
if 0
|
||||
" Compiler to use for preprocessing C/C++, so headers are respected
|
||||
" Either use "clang" or "gcc" or something compatible,
|
||||
" alternatively you will have to edit s:preprocessor
|
||||
let s:preprocessor_executable = "clang"
|
||||
"let s:preprocessor_executable = "gcc"
|
||||
let s:preprocessor = s:preprocessor_executable . ' -fdirectives-only -E {input_} -o {output}'
|
||||
endif
|
||||
|
||||
" Stand_alone_preprocessor:
|
||||
" The only implementation i know is fcpp (https://github.com/bagder/fcpp.git)
|
||||
" However, it has the major advantage that it will only warn on missing
|
||||
" headers and not error. Meaning a tool chain using '-I' doesn't break
|
||||
" everything.
|
||||
let s:preprocessor = "fcpp -LL {input_} {output}"
|
||||
|
||||
" --- --------------------------- ---
|
||||
" --- Don't Touch ---
|
||||
" --- Unless ---
|
||||
" --- You know What You Are Doing ---
|
||||
" --- --------------------------- ---
|
||||
let s:preprocessor = s:preprocessor_executable . ' -fdirectives-only -E {input_} -o {output}'
|
||||
let s:tags_filename = 'tags'
|
||||
let s:tags_file = expand(s:polution_directory) . s:tags_filename
|
||||
let s:tags_scriptname = 'tags.vim'
|
||||
let s:tags_script = expand(s:polution_directory) . 'tags.vim'
|
||||
let s:sigs_script = expand(s:polution_directory) . 'sigs.vim'
|
||||
"
|
||||
let s:generator_script = expand('~/.vim/plugin/HiTags/hitags.py')
|
||||
let s:generation_command = 'python ' . s:generator_script .
|
||||
let s:generation_command =
|
||||
\ 'python ' . s:generator_script .
|
||||
\ ' -i ' . '"' . expand('%:p') . '"' .
|
||||
\ ' -p ' . '"' . s:preprocessor . '"' .
|
||||
\ ' -t ' . '"' . s:polution_directory . '"' .
|
||||
\ ' > ' . '"' . s:tags_script . '"'
|
||||
\ ' hi ' .
|
||||
\ ' > ' . '"' . s:tags_script . '"' .
|
||||
\ ';' .
|
||||
\ 'python ' . s:generator_script .
|
||||
\ ' -i ' . '"' . expand('%:p') . '"' .
|
||||
\ ' -p ' . '"' . s:preprocessor . '"' .
|
||||
\ ' -t ' . '"' . s:polution_directory . '"' .
|
||||
\ ' sig ' .
|
||||
\ ' > ' . '"' . s:sigs_script . '"'
|
||||
|
||||
" --- Signature stuff ---
|
||||
function! SigDebug()
|
||||
echo s:generation_command
|
||||
endfunction
|
||||
|
||||
|
||||
function! SigInit()
|
||||
let g:signatures = {}
|
||||
|
||||
autocmd TextChangedI * call SigPopup()
|
||||
endfunction
|
||||
|
||||
call SigInit()
|
||||
|
||||
function! SigPopup()
|
||||
let key = matchstr(getline('.')[:col('.')-2], '\k\+$')
|
||||
if has_key(g:signatures, key)
|
||||
call popup_atcursor(g:signatures[key], #{} )
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! Sig()
|
||||
execute 'source ' . s:sigs_script
|
||||
endfunction
|
||||
|
||||
if exists('g:sigs_events')
|
||||
for e in g:sigs_events
|
||||
execute "autocmd " . e . " * Sig"
|
||||
endfor
|
||||
endif
|
||||
|
||||
command! Sig :call Sig()
|
||||
" --- --- ---
|
||||
|
||||
function! HiTagsUpdate()
|
||||
let pid = system(s:generation_command)
|
||||
|
104
vim/.vim/plugin/quickui.vim
Normal file
104
vim/.vim/plugin/quickui.vim
Normal file
@ -0,0 +1,104 @@
|
||||
"======================================================================
|
||||
"
|
||||
" quickui.vim -
|
||||
"
|
||||
" Created by skywind on 2019/12/26
|
||||
" Last Modified: 2021/12/08 23:01
|
||||
"
|
||||
"======================================================================
|
||||
|
||||
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
||||
|
||||
|
||||
" require vim 8.2+
|
||||
if has('patch-8.2.1') == 0 || has('nvim')
|
||||
" finish
|
||||
endif
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" exports
|
||||
"----------------------------------------------------------------------
|
||||
let g:quickui_version = '1.4.3'
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" internals
|
||||
"----------------------------------------------------------------------
|
||||
let s:home = fnamemodify(resolve(expand('<sfile>:p')), ':h')
|
||||
let s:rtp = fnamemodify(s:home, ':h')
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" QuickUI command
|
||||
"----------------------------------------------------------------------
|
||||
command! -bang -nargs=* -complete=customlist,quickui#command#complete
|
||||
\ QuickUI call quickui#command#run('<bang>', <q-args>)
|
||||
|
||||
|
||||
"----------------------------------------------------------------------
|
||||
" setup variables
|
||||
"----------------------------------------------------------------------
|
||||
let g:quickui#style#border = get(g:, 'quickui_border_style', 1)
|
||||
|
||||
function! s:set_quickui_hi()
|
||||
" hi! QuickDefaultSel ctermbg=
|
||||
hi! link QuickBG QuickDefaultBackground
|
||||
hi! link QuickSel QuickDefaultSel
|
||||
hi! link QuickKey QuickDefaultKey
|
||||
hi! link QuickOff QuickDefaultDisable
|
||||
hi! link QuickHelp QuickDefaultHelp
|
||||
hi! link QuickBorder QuickDefaultBorder
|
||||
hi! link QuickTermBorder QuickDefaultTermBorder
|
||||
hi! link QuickPreview QuickDefaultPreview
|
||||
|
||||
" for input box
|
||||
hi! link QuickInput QuickDefaultInput
|
||||
hi! link QuickCursor QuickDefaultCursor
|
||||
hi! link QuickVisual QuickDefaultVisual
|
||||
endfunc
|
||||
|
||||
function! QuickThemeChange(theme)
|
||||
let theme = 'default'
|
||||
if a:theme == ''
|
||||
let theme = 'default'
|
||||
elseif a:theme == 'default' || a:theme == 'ansi'
|
||||
let theme = 'default'
|
||||
elseif a:theme == 'borland' || a:theme == 'turboc'
|
||||
let theme = 'borland'
|
||||
elseif a:theme == 'colorscheme' || a:theme == 'system' || a:theme == 'vim'
|
||||
let theme = 'system'
|
||||
elseif a:theme == 'gruvbox'
|
||||
let theme = 'gruvbox'
|
||||
elseif a:theme == 'solarized'
|
||||
let theme = 'solarized'
|
||||
elseif a:theme == 'papercol' || a:theme == 'papercol-dark'
|
||||
let theme = 'papercol_dark'
|
||||
elseif a:theme == 'papercol dark'
|
||||
let theme = 'papercol_dark'
|
||||
elseif a:theme == 'papercol-light' || a:theme == 'papercol light'
|
||||
let theme = 'papercol_light'
|
||||
else
|
||||
let theme = a:theme
|
||||
endif
|
||||
let s:fname = s:rtp . '/colors/quickui/' . theme . '.vim'
|
||||
if !filereadable(s:fname)
|
||||
let s:fname = s:rtp . '/colors/quickui/borland.vim'
|
||||
endif
|
||||
if filereadable(s:fname)
|
||||
exec "source " . fnameescape(s:fname)
|
||||
endif
|
||||
call s:set_quickui_hi()
|
||||
endfunc
|
||||
|
||||
let s:scheme = get(g:, 'quickui_color_scheme', '')
|
||||
call QuickThemeChange(s:scheme)
|
||||
|
||||
augroup quickui "{{{
|
||||
autocmd!
|
||||
autocmd Colorscheme * call QuickThemeChange(get(g:, 'quickui_color_scheme', ''))
|
||||
augroup END "}}}
|
||||
|
||||
call s:set_quickui_hi()
|
||||
|
||||
|
@ -186,7 +186,8 @@ endfunction
|
||||
call TextEnableCodeSnip('html')
|
||||
call TextEnableCodeSnip('php')
|
||||
call TextEnableCodeSnip('sql')
|
||||
"call TextEnableCodeSnip('sh') " this breaks some highlighting
|
||||
call TextEnableCodeSnip('sh') " this breaks some highlighting
|
||||
call TextEnableCodeSnip('python') " this breaks some highlighting
|
||||
|
||||
|
||||
|
||||
|
205
vim/.vim/syntax/nim.vim
Normal file
205
vim/.vim/syntax/nim.vim
Normal file
@ -0,0 +1,205 @@
|
||||
" For version 5.x: Clear all syntax items
|
||||
" For version 6.x: Quit when a syntax file was already loaded
|
||||
if v:version < 600
|
||||
syntax clear
|
||||
elseif exists('b:current_syntax')
|
||||
finish
|
||||
endif
|
||||
|
||||
" Keep user-supplied options
|
||||
if !exists('nim_highlight_numbers')
|
||||
let nim_highlight_numbers = 1
|
||||
endif
|
||||
if !exists('nim_highlight_builtins')
|
||||
let nim_highlight_builtins = 1
|
||||
endif
|
||||
if !exists('nim_highlight_exceptions')
|
||||
let nim_highlight_exceptions = 1
|
||||
endif
|
||||
if !exists('nim_highlight_space_errors')
|
||||
let nim_highlight_space_errors = 1
|
||||
endif
|
||||
if !exists('nim_highlight_special_vars')
|
||||
let nim_highlight_special_vars = 1
|
||||
endif
|
||||
|
||||
if exists('nim_highlight_all')
|
||||
let nim_highlight_numbers = 1
|
||||
let nim_highlight_builtins = 1
|
||||
let nim_highlight_exceptions = 1
|
||||
let nim_highlight_space_errors = 1
|
||||
let nim_highlight_special_vars = 1
|
||||
endif
|
||||
|
||||
syn region nimBrackets contained extend keepend matchgroup=Bold start=+\(\\\)\@<!\[+ end=+]\|$+ skip=+\\\s*$\|\(\\\)\@<!\\]+ contains=@tclCommandCluster
|
||||
|
||||
syn keyword nimKeyword addr and as asm atomic
|
||||
syn keyword nimKeyword bind block break
|
||||
syn keyword nimKeyword case cast concept const continue converter
|
||||
syn keyword nimKeyword defer discard distinct div do
|
||||
syn keyword nimKeyword elif else end enum except export
|
||||
syn keyword nimKeyword finally for from
|
||||
syn keyword nimKeyword generic
|
||||
syn keyword nimKeyword if import in include interface is isnot iterator
|
||||
syn keyword nimKeyword let
|
||||
syn keyword nimKeyword mixin using mod
|
||||
syn keyword nimKeyword nil not notin
|
||||
syn keyword nimKeyword object of or out
|
||||
syn keyword nimKeyword proc func method macro template nextgroup=nimFunction skipwhite
|
||||
syn keyword nimKeyword ptr
|
||||
syn keyword nimKeyword raise ref return
|
||||
syn keyword nimKeyword shared shl shr static
|
||||
syn keyword nimKeyword try tuple type
|
||||
syn keyword nimKeyword var vtref vtptr
|
||||
syn keyword nimKeyword when while with without
|
||||
syn keyword nimKeyword xor
|
||||
syn keyword nimKeyword yield
|
||||
|
||||
syn match nimFunction "[a-zA-Z_][a-zA-Z0-9_]*" contained
|
||||
syn match nimClass "[a-zA-Z_][a-zA-Z0-9_]*" contained
|
||||
syn keyword nimRepeat for while
|
||||
syn keyword nimConditional if elif else case of
|
||||
syn keyword nimOperator and in is not or xor shl shr div
|
||||
syn match nimComment "#.*$" contains=nimTodo,@Spell
|
||||
syn region nimComment start="#\[" end="\]#" contains=nimTodo,@Spell
|
||||
syn keyword nimTodo TODO FIXME XXX contained
|
||||
syn keyword nimBoolean true false
|
||||
|
||||
|
||||
" Strings
|
||||
syn region nimString start=+'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=nimEscape,nimEscapeError,@Spell
|
||||
syn region nimString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=nimEscape,nimEscapeError,@Spell
|
||||
syn region nimString start=+"""+ end=+"""+ keepend contains=nimEscape,nimEscapeError,@Spell
|
||||
syn region nimRawString matchgroup=Normal start=+[rR]"+ end=+"+ skip=+\\\\\|\\"+ contains=@Spell
|
||||
|
||||
syn match nimEscape +\\[abfnrtv'"\\]+ contained
|
||||
syn match nimEscape "\\\o\{1,3}" contained
|
||||
syn match nimEscape "\\x\x\{2}" contained
|
||||
syn match nimEscape "\(\\u\x\{4}\|\\U\x\{8}\)" contained
|
||||
syn match nimEscape "\\$"
|
||||
|
||||
syn match nimEscapeError "\\x\x\=\X" display contained
|
||||
|
||||
if nim_highlight_numbers == 1
|
||||
" numbers (including longs and complex)
|
||||
let s:dec_num = '\d%(_?\d)*'
|
||||
let s:int_suf = '%(''%(%(i|I|u|U)%(8|16|32|64)|u|U))'
|
||||
let s:float_suf = '%(''%(%(f|F)%(32|64|128)?|d|D))'
|
||||
let s:exp = '%([eE][+-]?'.s:dec_num.')'
|
||||
exe 'syn match nimNumber /\v<0[bB][01]%(_?[01])*%('.s:int_suf.'|'.s:float_suf.')?>/'
|
||||
exe 'syn match nimNumber /\v<0[ocC]\o%(_?\o)*%('.s:int_suf.'|'.s:float_suf.')?>/'
|
||||
exe 'syn match nimNumber /\v<0[xX]\x%(_?\x)*%('.s:int_suf.'|'.s:float_suf.')?>/'
|
||||
exe 'syn match nimNumber /\v<'.s:dec_num.'%('.s:int_suf.'|'.s:exp.'?'.s:float_suf.'?)>/'
|
||||
exe 'syn match nimNumber /\v<'.s:dec_num.'\.'.s:dec_num.s:exp.'?'.s:float_suf.'?>/'
|
||||
unlet s:dec_num s:int_suf s:float_suf s:exp
|
||||
endif
|
||||
|
||||
if nim_highlight_builtins == 1
|
||||
" builtin functions, types and objects, not really part of the syntax
|
||||
syn keyword nimBuiltin int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64
|
||||
syn keyword nimBuiltin bool void chr char string cstring pointer range array openarray openArray seq varargs varArgs
|
||||
syn keyword nimBuiltin set Byte Natural Positive Conversion
|
||||
syn keyword nimBuiltin BiggestInt BiggestFloat cchar cschar cshort cint csize cuchar cushort
|
||||
syn keyword nimBuiltin clong clonglong cfloat cdouble clongdouble cuint culong culonglong cchar
|
||||
syn keyword nimBuiltin CompileDate CompileTime nimversion nimVersion nimmajor nimMajor
|
||||
syn keyword nimBuiltin nimminor nimMinor nimpatch nimPatch cpuendian cpuEndian hostos hostOS hostcpu hostCPU inf
|
||||
syn keyword nimBuiltin neginf nan QuitSuccess QuitFailure dbglinehook dbgLineHook stdin
|
||||
syn keyword nimBuiltin stdout stderr defined new high low sizeof succ pred
|
||||
syn keyword nimBuiltin inc dec newseq newSeq len incl excl card ord chr ze ze64
|
||||
syn keyword nimBuiltin tou8 toU8 tou16 toU16 tou32 toU32 abs min max add repr
|
||||
syn match nimBuiltin "\<contains\>"
|
||||
syn keyword nimBuiltin tofloat toFloat tobiggestfloat toBiggestFloat toint toInt tobiggestint toBiggestInt
|
||||
syn keyword nimBuiltin addquitproc addQuitProc
|
||||
syn keyword nimBuiltin copy setlen setLen newstring newString zeromem zeroMem copymem copyMem movemem moveMem
|
||||
syn keyword nimBuiltin equalmem equalMem alloc alloc0 realloc dealloc assert
|
||||
syn keyword nimBuiltin typedesc typed untyped stmt expr
|
||||
syn keyword nimBuiltin echo swap getrefcount getRefcount getcurrentexception getCurrentException Msg
|
||||
syn keyword nimBuiltin getoccupiedmem getOccupiedMem getfreemem getFreeMem gettotalmem getTotalMem isnil isNil seqtoptr seqToPtr
|
||||
syn keyword nimBuiltin find pop GC_disable GC_enable GC_fullCollect
|
||||
syn keyword nimBuiltin GC_setStrategy GC_enableMarkAndSweep GC_Strategy
|
||||
syn keyword nimBuiltin GC_disableMarkAnd Sweep GC_getStatistics GC_ref
|
||||
syn keyword nimBuiltin GC_ref GC_ref GC_unref GC_unref GC_unref quit
|
||||
syn keyword nimBuiltin OpenFile OpenFile CloseFile EndOfFile readChar
|
||||
syn keyword nimBuiltin FlushFile readfile readFile readline readLine write writeln writeLn writeline writeLine
|
||||
syn keyword nimBuiltin getfilesize getFileSize ReadBytes ReadChars readbuffer readBuffer writebytes writeBytes
|
||||
syn keyword nimBuiltin writechars writeChars writebuffer writeBuffer setfilepos setFilePos getfilepos getFilePos
|
||||
syn keyword nimBuiltin filehandle fileHandle countdown countup items lines
|
||||
syn keyword nimBuiltin FileMode File RootObj FileHandle ByteAddress Endianness
|
||||
endif
|
||||
|
||||
if nim_highlight_exceptions == 1
|
||||
" builtin exceptions and warnings
|
||||
syn keyword nimException E_Base EAsynch ESynch ESystem EIO EOS
|
||||
syn keyword nimException ERessourceExhausted EArithmetic EDivByZero
|
||||
syn keyword nimException EOverflow EAccessViolation EAssertionFailed
|
||||
syn keyword nimException EControlC EInvalidValue EOutOfMemory EInvalidIndex
|
||||
syn keyword nimException EInvalidField EOutOfRange EStackOverflow
|
||||
syn keyword nimException ENoExceptionToReraise EInvalidObjectAssignment
|
||||
syn keyword nimException EInvalidObject EInvalidLibrary EInvalidKey
|
||||
syn keyword nimException EInvalidObjectConversion EFloatingPoint
|
||||
syn keyword nimException EFloatInvalidOp EFloatDivByZero EFloatOverflow
|
||||
syn keyword nimException EFloatInexact EDeadThread EResourceExhausted
|
||||
syn keyword nimException EFloatUnderflow
|
||||
endif
|
||||
|
||||
if nim_highlight_space_errors == 1
|
||||
" trailing whitespace
|
||||
syn match nimSpaceError display excludenl "\S\s\+$"ms=s+1
|
||||
" any tabs are illegal in nim
|
||||
syn match nimSpaceError display "\t"
|
||||
endif
|
||||
|
||||
if nim_highlight_special_vars
|
||||
syn keyword nimSpecialVar result
|
||||
endif
|
||||
|
||||
syn sync match nimSync grouphere NONE "):$"
|
||||
syn sync maxlines=200
|
||||
syn sync minlines=2000
|
||||
|
||||
if v:version >= 508 || !exists('did_nim_syn_inits')
|
||||
if v:version <= 508
|
||||
let did_nim_syn_inits = 1
|
||||
command -nargs=+ HiLink hi link <args>
|
||||
else
|
||||
command -nargs=+ HiLink hi def link <args>
|
||||
endif
|
||||
|
||||
" The default methods for highlighting. Can be overridden later
|
||||
HiLink nimBrackets Operator
|
||||
HiLink nimKeyword Keyword
|
||||
HiLink nimFunction Function
|
||||
HiLink nimConditional Conditional
|
||||
HiLink nimRepeat Repeat
|
||||
HiLink nimString String
|
||||
HiLink nimRawString String
|
||||
HiLink nimBoolean Boolean
|
||||
HiLink nimEscape Special
|
||||
HiLink nimOperator Operator
|
||||
HiLink nimPreCondit PreCondit
|
||||
HiLink nimComment Comment
|
||||
HiLink nimTodo Todo
|
||||
HiLink nimDecorator Define
|
||||
HiLink nimSpecialVar Identifier
|
||||
|
||||
if nim_highlight_numbers == 1
|
||||
HiLink nimNumber Number
|
||||
endif
|
||||
|
||||
if nim_highlight_builtins == 1
|
||||
HiLink nimBuiltin Number
|
||||
endif
|
||||
|
||||
if nim_highlight_exceptions == 1
|
||||
HiLink nimException Exception
|
||||
endif
|
||||
|
||||
if nim_highlight_space_errors == 1
|
||||
HiLink nimSpaceError Error
|
||||
endif
|
||||
|
||||
delcommand HiLink
|
||||
endif
|
||||
|
||||
let b:current_syntax = 'nim'
|
||||
|
367
vim/.vimrc
367
vim/.vimrc
@ -1,229 +1,280 @@
|
||||
" -------------
|
||||
" ### LOOKS ###
|
||||
" -------------
|
||||
set title
|
||||
"set titlestring=Vim
|
||||
set iconstring=Vim
|
||||
set title
|
||||
"set titlestring=Vim
|
||||
set iconstring=Vim
|
||||
|
||||
set tabstop=4
|
||||
set shiftwidth=4
|
||||
set expandtab
|
||||
set listchars=tab:<·>,eol:¬,space:·,nbsp:⎵
|
||||
|
||||
set listchars=tab:<·>,eol:¬,space:·,nbsp:⎵
|
||||
syntax on
|
||||
|
||||
syntax on
|
||||
set nowrap "do not wrap lines not fitting the screen
|
||||
set sidescroll=1 "do not jump half a screens whenever manuvering a line not fitting the screen
|
||||
|
||||
set nowrap "do not wrap lines not fitting the screen
|
||||
set sidescroll=1 "do not jump half a screens whenever manuvering a line not fitting the screen
|
||||
set display=uhex "display hex chats as <[hex]> instead of ^C and ~C
|
||||
|
||||
set display=uhex "display hex chats as <[hex]> instead of ^C and ~C
|
||||
set laststatus=2 "display status bar
|
||||
set ruler
|
||||
"set statusline+=%l,%c%V%=%P
|
||||
|
||||
set laststatus=2 "display status bar
|
||||
set ruler
|
||||
"set statusline+=%l,%c%V%=%P
|
||||
set visualbell "flash instead of beeping; im not sure whether thats great or annoying
|
||||
|
||||
set visualbell "flash instead of beeping; im not sure whether thats great or annoying
|
||||
"autocmd InsertEnter * silent !echo -ne "\e[1 q"
|
||||
"autocmd InsertLeave * silent !echo -ne "\e[0 q"
|
||||
let &t_VS = "\e[0 q"
|
||||
let &t_SI = "\e[1 q"
|
||||
let &t_EI = "\e[0 q"
|
||||
|
||||
"autocmd InsertEnter * silent !echo -ne "\e[1 q"
|
||||
"autocmd InsertLeave * silent !echo -ne "\e[0 q"
|
||||
let &t_VS = "\e[0 q"
|
||||
let &t_SI = "\e[1 q"
|
||||
let &t_EI = "\e[0 q"
|
||||
set showmatch "highlight pair of paranthesies
|
||||
set hlsearch "highlight search
|
||||
set wildmenu "visual command auto complete
|
||||
|
||||
set showmatch "highlight pair of paranthesies
|
||||
set hlsearch "highlight search
|
||||
set wildmenu "visual command auto complete
|
||||
se nostartofline "Do not jump to first char of line when scolling
|
||||
|
||||
se nostartofline "Do not jump to first char of line when scolling
|
||||
set colorcolumn=100 " pseudo margin at 80
|
||||
|
||||
set colorcolumn=100 " pseudo margin at 80
|
||||
colorscheme knight
|
||||
|
||||
colorscheme knight
|
||||
set signcolumn=no
|
||||
|
||||
set signcolumn=no
|
||||
|
||||
set shortmess-=S "show match count on search
|
||||
set shortmess-=S "show match count on search
|
||||
|
||||
" --------------------
|
||||
" ### EASSE_OF_USE ###
|
||||
" --------------------
|
||||
set bs=2
|
||||
set undodir=/home/anon/stow/.cache/
|
||||
set undofile
|
||||
set bs=2
|
||||
set undodir=/home/anon/stow/.cache/
|
||||
set undofile
|
||||
|
||||
set directory=/home/anon/stow/.cache/
|
||||
set backupdir=/home/anon/stow/.cache/
|
||||
set directory=/home/anon/stow/.cache/
|
||||
set backupdir=/home/anon/stow/.cache/
|
||||
|
||||
set autoindent
|
||||
set autoindent
|
||||
|
||||
set ignorecase "ignore case in searches
|
||||
set smartcase "override ignorecase when upper case letters are used in the search
|
||||
set wildignorecase "ignore case when auto completing file and directory names (does not to shells)
|
||||
set ignorecase "ignore case in searches
|
||||
set smartcase "override ignorecase when upper case letters are used in the search
|
||||
set wildignorecase "ignore case when auto completing file and directory names (does not to shells)
|
||||
|
||||
set autoread "chech for external changes in the file
|
||||
set autoread "chech for external changes in the file
|
||||
|
||||
set autochdir
|
||||
set autochdir
|
||||
|
||||
set confirm "when quiting an unsaved filed, do not fail, instead ask back whether the buffer shall be saved, not saved, or cancel the operation
|
||||
set confirm "when quiting an unsaved filed, do not fail, instead ask back whether the buffer shall be saved, not saved, or cancel the operation
|
||||
|
||||
set noexpandtab
|
||||
set mouse=a
|
||||
nnoremap <LeftMouse> <nop>
|
||||
|
||||
set mouse=a
|
||||
nnoremap <LeftMouse> <nop>
|
||||
set keywordprg=:call\ ContextualMan()\ \" " better 'K' help
|
||||
|
||||
set keywordprg=:call\ ContextualMan()\ \" " better 'K' help
|
||||
set suffixes+=.info,.aux,.log,.dvi,.bbl,.out,.o,.lo,.obj " ignore on completion
|
||||
|
||||
set suffixes+=.info,.aux,.log,.dvi,.bbl,.out,.o,.lo,.obj " ignore on completion
|
||||
set foldopen-=hor " do not unfold on horizontal movement
|
||||
|
||||
set foldopen-=hor " do not unfold on horizontal movement
|
||||
" always respect # pragma region
|
||||
set foldmarker=#pragma\ region,#pragma\ endregion
|
||||
set foldmethod=marker
|
||||
|
||||
" always respect # pragma region
|
||||
set foldmarker=#pragma\ region,#pragma\ endregion
|
||||
set foldmethod=marker
|
||||
" tabs/spaces
|
||||
set tabstop=4
|
||||
set shiftwidth=4
|
||||
set expandtab
|
||||
set softtabstop=4
|
||||
|
||||
" -----------------
|
||||
" ### Functions ###
|
||||
" -----------------
|
||||
function ContextualMan()
|
||||
let word = expand('<cword>')
|
||||
let cmd = ":silent !"
|
||||
function ContextualMan()
|
||||
let word = expand('<cword>')
|
||||
let cmd = ":silent !"
|
||||
|
||||
if &filetype == "cpp"
|
||||
let cmd .= "man 3 " . word . "; [ $? == 16 ] && cppman "
|
||||
elseif &filetype == "python"
|
||||
let cmd .= "pydoc "
|
||||
else
|
||||
if &filetype == "bash" || &filetype == "sh"
|
||||
let cmd .= "man 1 "
|
||||
else
|
||||
let cmd .= "man 3 "
|
||||
endif
|
||||
endif
|
||||
if &filetype == "vim"
|
||||
:help word
|
||||
return
|
||||
endif
|
||||
|
||||
let cmd .= word
|
||||
if &filetype == "cpp"
|
||||
let cmd .= "man -s 3,2 " . word . "; [ $? == 16 ] && cppman "
|
||||
elseif &filetype == "python"
|
||||
let cmd .= "pydoc "
|
||||
else
|
||||
if &filetype == "bash" || &filetype == "sh"
|
||||
let cmd .= "man 1 "
|
||||
else
|
||||
let cmd .= "man 3 "
|
||||
endif
|
||||
endif
|
||||
|
||||
execute cmd
|
||||
redraw!
|
||||
endfunction
|
||||
let cmd .= word
|
||||
|
||||
function! Signcolumn_toggle()
|
||||
if &signcolumn == 'no'
|
||||
set signcolumn=yes
|
||||
elseif &signcolumn == 'yes'
|
||||
set signcolumn=no
|
||||
endif
|
||||
endfunction
|
||||
execute cmd
|
||||
redraw!
|
||||
endfunction
|
||||
|
||||
let s:drawit_boolean = 0
|
||||
function! Drawit_toggle()
|
||||
if s:drawit_boolean
|
||||
DIstop
|
||||
let s:drawit_boolean = 0
|
||||
else
|
||||
DIstart
|
||||
let s:drawit_boolean = 1
|
||||
endif
|
||||
endfunction
|
||||
function! Signcolumn_toggle()
|
||||
if &signcolumn == 'no'
|
||||
set signcolumn=yes
|
||||
elseif &signcolumn == 'yes'
|
||||
set signcolumn=no
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:acp_boolean = 0
|
||||
function! Acp_toggle()
|
||||
if s:drawit_boolean
|
||||
AcpDisable
|
||||
let s:drawit_boolean = 0
|
||||
else
|
||||
AcpEnable
|
||||
let s:drawit_boolean = 1
|
||||
endif
|
||||
endfunction
|
||||
function! Drawit_toggle()
|
||||
if !exists("s:drawit_boolean")
|
||||
let s:drawit_boolean = 0
|
||||
endif
|
||||
if s:drawit_boolean
|
||||
DIstop
|
||||
let s:drawit_boolean = 0
|
||||
else
|
||||
DIstart
|
||||
let s:drawit_boolean = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:spell_boolean = 0
|
||||
function! Spell_toggle()
|
||||
if s:drawit_boolean
|
||||
set nospell
|
||||
let s:drawit_boolean = 0
|
||||
else
|
||||
set spell spelllang=en_us
|
||||
let s:drawit_boolean = 1
|
||||
endif
|
||||
endfunction
|
||||
function! Programming_mode_toggle()
|
||||
if !exists("s:programming_mode_boolean")
|
||||
let s:programming_mode_boolean = 0
|
||||
endif
|
||||
|
||||
if s:programming_mode_boolean
|
||||
let s:programming_mode_boolean = 0
|
||||
AcpDisable
|
||||
else
|
||||
let s:programming_mode_boolean = 1
|
||||
AcpEnable
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! Spell_toggle()
|
||||
if !exists("s:spell_boolean")
|
||||
let s:spell_boolean = 0
|
||||
endif
|
||||
if s:spell_boolean
|
||||
set nospell
|
||||
let s:spell_boolean = 0
|
||||
else
|
||||
set spell spelllang=en_us
|
||||
let s:spell_boolean = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" --------------
|
||||
" ### REMAPS ###
|
||||
" --------------
|
||||
" Diff_mode:
|
||||
if &diff
|
||||
map <C-p> :diffput<CR>
|
||||
map <C-n> :diffget<CR>
|
||||
endif
|
||||
" Complete_on_tab:
|
||||
inoremap <expr> <TAB> pumvisible() ? "<C-y>" : "<TAB>"
|
||||
inoremap <expr> <CR> pumvisible() ? "\<C-g>u\<CR>" : "\<C-g>u\<CR>"
|
||||
inoremap <expr> <C-j> pumvisible() ? "\<C-N>" : "<C-j>"
|
||||
inoremap <expr> <C-k> pumvisible() ? "\<C-P>" : "<C-k>"
|
||||
" Function_keys:
|
||||
" ### Visibility island
|
||||
" F1: toggle whitespace visibility
|
||||
map <F1> :set invlist<CR>
|
||||
" F2: toggle visible line numbers
|
||||
map <F2> :set nu!<CR>
|
||||
" F3: toggle sign column
|
||||
map <F3> :call Signcolumn_toggle()<CR>
|
||||
" F4: unhighligh highlighted text
|
||||
map <F4> :noh<CR>
|
||||
" ### Feature island
|
||||
" F5: toggle spell check
|
||||
"map <F5> :!aspell check %<CR>:e! %<CR>
|
||||
map <F5> :call Spell_toggle()<CR>
|
||||
" F6: reload ctags and its highlighting
|
||||
map <f6> :call Cpp_tags_run()<CR>
|
||||
" F7: toggle DrawIt plugin mode
|
||||
map <F7> :call Drawit_toggle()<CR>
|
||||
" F8: toggle acp (auto suggest) plugin mode
|
||||
map <F8> :call Acp_toggle()<CR>
|
||||
" ### Call once in a while island
|
||||
" F9: copy file contents to clipboard
|
||||
map <F9> miggVG"+y'izz
|
||||
" F12: reload file
|
||||
map <F12> :e!<CR>
|
||||
" Tagbar_plugin:
|
||||
nmap <C-W>m :TagbarToggle<CR>
|
||||
" Diff_mode:
|
||||
if &diff
|
||||
map <C-p> :diffput<CR>
|
||||
map <C-n> :diffget<CR>
|
||||
endif
|
||||
" Complete_on_tab:
|
||||
inoremap <expr> <TAB> pumvisible() ? "<C-y>" : "<TAB>"
|
||||
inoremap <expr> <CR> pumvisible() ? "\<C-g>u\<CR>" : "\<C-g>u\<CR>"
|
||||
inoremap <expr> <C-j> pumvisible() ? "\<C-N>" : "<C-j>"
|
||||
inoremap <expr> <C-k> pumvisible() ? "\<C-P>" : "<C-k>"
|
||||
|
||||
" Function_keys:
|
||||
" ### Visibility island
|
||||
" F1: toggle whitespace visibility
|
||||
map <F1> :set invlist<CR>
|
||||
" F2: toggle visible line numbers
|
||||
map <F2> :set nu!<CR>
|
||||
" F3: toggle sign column
|
||||
map <F3> :call Signcolumn_toggle()<CR>
|
||||
" F4: unhighligh highlighted text
|
||||
map <F4> :noh<CR>
|
||||
|
||||
" ### Feature island
|
||||
" F5: Display Turbo Menu
|
||||
map <F5> :call quickui#menu#open()<CR>
|
||||
" F6: compile with bake
|
||||
map <f6> :!bake %:p<CR>
|
||||
" F7:
|
||||
" NOTHING YET
|
||||
" F8: toggle acp (auto suggest) plugin mode
|
||||
map <F8> :call Programming_mode_toggle()<CR>
|
||||
|
||||
" ### Call once in a while island
|
||||
" F9: copy file contents to clipboard
|
||||
map <F9> miggVG"+y'izz
|
||||
" F10:
|
||||
noremap <F10> <Nop>
|
||||
" F11:
|
||||
noremap <F11> <Nop>
|
||||
" F12: reload file
|
||||
"map <F12> :e!<CR>
|
||||
noremap <F12> <Nop>
|
||||
|
||||
" Tagbar_plugin:
|
||||
nmap <C-W>m :TagbarToggle<CR>
|
||||
|
||||
"------------------
|
||||
" ### VARIABLES ###
|
||||
"------------------
|
||||
let $BASH_ENV = "/home/jacob/Desktop/minecraft mod/Linux/Vim/bash_aliases"
|
||||
let g:hitags_events = ["BufWrite"]
|
||||
let g:hitags_events = ["BufWrite"]
|
||||
let g:sigs_events = ["BufWrite"]
|
||||
|
||||
" -------------
|
||||
" ### NETRW ###
|
||||
" -------------
|
||||
let g:netrw_keepdir = 0
|
||||
let g:netrw_banner = 0
|
||||
"let g:netrw_browse_split = 2
|
||||
let g:netrw_liststyle = 3
|
||||
let g:netrw_keepdir = 0
|
||||
let g:netrw_banner = 0
|
||||
"let g:netrw_browse_split = 2
|
||||
let g:netrw_liststyle = 3
|
||||
|
||||
" ---------------
|
||||
" ### QUICKUI ###
|
||||
" ---------------
|
||||
call quickui#menu#install('&Edit', [
|
||||
\ [ '&Drawit', ':call Drawit_toggle()'],
|
||||
\ [ '&Expandtab', ':set expandtab!'],
|
||||
\ [ '&Brace unf*', ':%s/\n\s*{/ {/g'],
|
||||
\ ])
|
||||
call quickui#menu#install('&View', [
|
||||
\ [ '&Spell', ':call Spell_toggle()'],
|
||||
\ [ '&Netrw', ':Lex'],
|
||||
\ [ '&Diff', ':diffthis'],
|
||||
\ ])
|
||||
call quickui#menu#install('&Modify', [
|
||||
\ [ '&Remove trailing', ':%s/\s\+$//g'],
|
||||
\ [ '&Retab', ':retab!'],
|
||||
\ ])
|
||||
call quickui#menu#install('&Development', [
|
||||
\ [ '&Ascii Escape', ':ShowEscapeDictionary'],
|
||||
\ [ '&Make special', ':ShowMakeDictionary'],
|
||||
\ [ '&Symbol map', ':TagbarToggle', '<C-W>m'],
|
||||
\ ])
|
||||
|
||||
" ------------
|
||||
" ### TMUX ###
|
||||
" ------------
|
||||
function! Fname()
|
||||
if expand("%:t") != ""
|
||||
return expand("%:t")
|
||||
else
|
||||
return "vim"
|
||||
endif
|
||||
if expand("%:t") != ""
|
||||
return expand("%:t")
|
||||
else
|
||||
return "vim"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if exists('$TMUX')
|
||||
autocmd BufEnter * call system('tmux rename-window ' . Fname())
|
||||
autocmd VimLeave * call system('sh -c "sleep 1 && tmux setw automatic-rename" & disown')
|
||||
autocmd BufEnter * let &titlestring = expand("%:t")
|
||||
"set title " already called
|
||||
autocmd BufEnter * call system('tmux rename-window ' . Fname())
|
||||
autocmd VimLeave * call system('sh -c "sleep 1 && tmux setw automatic-rename" & disown')
|
||||
autocmd BufEnter * let &titlestring = expand("%:t")
|
||||
"set title " already called
|
||||
endif
|
||||
|
||||
"---###NOTES###---
|
||||
"https://vimawesome.com/plugin/syntastic#introduction
|
||||
"https://vimawesome.com/plugin/syntastic#introduction
|
||||
|
||||
"" Souce VimScript9 settings
|
||||
"source ~/.vimrc9
|
||||
|
||||
set formatoptions-=cro
|
||||
|
||||
" TEMP:
|
||||
highlight DiffChange ctermbg=3
|
||||
|
||||
" AI notes:
|
||||
" <C-W>v<C-W>l
|
||||
" :new
|
||||
" :windo diffthis
|
||||
|
6
x11/x_startup.sh
Executable file
6
x11/x_startup.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
xset s off
|
||||
xset r rate 170 45
|
||||
setxkbmap -layout hu -variant nodeadkeys
|
||||
setxkbmap -option caps:swapescape
|
Loading…
x
Reference in New Issue
Block a user