├── .zshrc.etc.d ├── .gitkeep ├── docker-alias-commands.zshrc ├── python-global-init.zshrc ├── chmod-root-s.zshrc ├── kube-promote.zshrc ├── hosts-on-off.zshrc ├── clean-cache.zshrc └── project.zshrc ├── local ├── etc │ ├── mssql_bindings.txt │ └── Blank.css └── bin │ ├── tinyproxy_start.sh │ ├── myip │ ├── trash-put │ ├── jmxsh │ ├── myip-ip-sb │ ├── myip-ip-sb-hk │ ├── myip-ip-me-usa │ ├── myip-ifconfig-co │ ├── myip-ifconfig-gcs │ ├── myip-ipecho │ ├── myip-ipinfo │ ├── soks5proxyhttp │ ├── jmxterm │ ├── crash │ ├── myip-dig │ ├── tinyproxy_stop.sh │ ├── rsocks_start.sh │ ├── myip-ipip │ ├── soks5proxyssh │ ├── paste-weread-to-md │ ├── apple-music-playing │ ├── format-gfm │ ├── paste-md-to-html │ ├── paste-weread-to-md-copy │ ├── resize-img-1200 │ ├── resize-img-2000 │ ├── resize-img-800 │ ├── fcitx-remote-osa │ ├── generate-summary-md │ ├── shadowsocks_client_start_ha.sh │ ├── paste-rtf-to-md-copy │ ├── format-markdown │ ├── paste-rtf-to-html-copy │ ├── paste-html-to-rtf │ ├── ls-upload-log4d │ ├── paste-html-to-md-copy │ ├── paste-html-to-rtf-copy │ ├── paste-md-to-html-copy │ ├── paste-md-to-rtf-copy │ ├── mouse-tracking-echo-in-shell │ ├── paste-rtf-to-md-for-table-copy │ ├── svn_diff_wrapper │ ├── yaml-pretty-pyyaml │ ├── git-archive-zip │ ├── git_diff_wrapper │ ├── git-changes │ ├── yaml-pretty │ ├── dig-http │ ├── paste-md-to-rtf │ ├── paste-rtf-to-html │ ├── funiq │ ├── paste-rtf-to-md-for-table │ ├── uniqf │ ├── rime_dict_manager │ ├── paste-simplemind-outline-to-md │ ├── git-code-numbers-by-authors │ ├── privoxy_restart.sh │ ├── tsa │ ├── puml-format-order-node │ ├── git-min-backup │ ├── qrdecode │ ├── shj │ ├── release-sbt-to-git-release-binary-branch.sh │ ├── shadowsocks_client_start_hk.sh │ ├── shadowsocks_client_start_jp.sh │ ├── paste-html-to-md │ ├── release-mvn-to-git-release-binary-branch.sh │ ├── resize-img │ ├── mouse_restore.sh │ ├── unzip-gbk │ ├── lark-gen-markdown │ ├── tinypng │ ├── image-from-clipboard-to-png-global │ ├── mdmv │ ├── mdsearch │ ├── image-from-clipboard-to-png-copy-markdown │ ├── image-from-path-to-assets-copy-markdown │ ├── generate-output-summary-md │ ├── ddns-by-cloudflare-wan │ ├── mov2gif │ ├── ddns-by-dnspod │ ├── mdcp │ ├── ddns-by-cloudflare │ ├── socks5proxywrapper │ ├── ddns-by-dnspod-wan │ ├── view-pyc-file │ ├── view-pyc-file3 │ ├── iterm2-send-zmodem.sh │ ├── homebrew-using-mirror │ ├── bing-wallpaper.sh │ ├── iterm2-recv-zmodem.sh │ ├── sqlite3-to-mysql.py │ ├── csv2json │ ├── viscosity-to-ios-connect.rb │ ├── tree2fulltree │ ├── paste-rtf-to-md │ ├── remark │ ├── speedfox │ ├── check-brew-cask-upgrade │ ├── gh-md-toc │ ├── scel2mmseg.py │ ├── generate_dash_index.sh │ ├── mysql2sqlite.sh │ ├── cdnjs-download.py │ ├── reveal │ ├── svg2icns │ └── markdown2ctags.py ├── .iftoprc ├── .config ├── kitty │ ├── kitty.d │ │ └── local │ │ │ └── .gitkeeper │ └── theme.conf ├── uv │ └── uv.toml └── ghostty │ └── config ├── VimFx-custom ├── vimfx.js ├── bootstrap.js └── install.rdf ├── mac ├── phoenix │ ├── _asserts │ │ ├── window.gif │ │ ├── application-launch.gif │ │ └── application-switch.gif │ ├── tsconfig.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── mouse.ts │ │ ├── config.ts │ │ ├── space.ts │ │ ├── util.ts │ │ └── window.ts │ ├── webpack.config.js │ ├── README.md │ └── tslint.json ├── Library │ └── LaunchAgents │ │ └── com.alswl.edit-server.plist ├── .slate ├── _Library │ └── Application Support │ │ └── Karabiner │ │ └── private.xml ├── .bashrc ├── .mjolnir │ └── init.lua └── .amethyst ├── .jslintrc ├── .npmrc ├── .wgetrc ├── .pip └── pip.conf ├── .pydistutils.cfg ├── .nload ├── .zprofile ├── .gitignore_global ├── .screenrc ├── linux ├── .Xmodmap ├── .xprofile ├── .Xresources └── .config │ ├── fontconfig │ └── fonts.conf │ └── conky │ └── conky.conf ├── diff └── usr │ └── local │ └── share │ └── zsh │ └── site-functions │ └── git-completion.bash.diff ├── .htoprc ├── .webterm.lua ├── .gitignore ├── .pentadactylrc ├── .vimperatorrc ├── .obsidian.vimrc ├── .cvimrc ├── .tmux.conf ├── _.gitconfig ├── .ctags ├── .cvim.css ├── .ideavimrc ├── .surfingkeys.js ├── README.md └── .zsh_completion └── _toodledo /.zshrc.etc.d/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /local/etc/mssql_bindings.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.iftoprc: -------------------------------------------------------------------------------- 1 | max-bandwidth: 10M 2 | -------------------------------------------------------------------------------- /.config/kitty/kitty.d/local/.gitkeeper: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /local/bin/tinyproxy_start.sh: -------------------------------------------------------------------------------- 1 | tinyproxy 2 | -------------------------------------------------------------------------------- /local/bin/myip: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | myip-ifconfig-co 3 | -------------------------------------------------------------------------------- /local/bin/trash-put: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | trash "$@" 4 | -------------------------------------------------------------------------------- /local/bin/jmxsh: -------------------------------------------------------------------------------- 1 | java -jar $HOME/local/libs/jmxsh-R5.jar 2 | -------------------------------------------------------------------------------- /local/bin/myip-ip-sb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -s http://ip.sb 3 | -------------------------------------------------------------------------------- /local/bin/myip-ip-sb-hk: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -sL http://ip.sb 3 | -------------------------------------------------------------------------------- /local/bin/myip-ip-me-usa: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -sL https://ip.me 3 | -------------------------------------------------------------------------------- /VimFx-custom/vimfx.js: -------------------------------------------------------------------------------- 1 | console.log('Hello, world! This is vimfx:', vimfx) -------------------------------------------------------------------------------- /local/bin/myip-ifconfig-co: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -sL http://ifconfig.co 3 | -------------------------------------------------------------------------------- /local/bin/myip-ifconfig-gcs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -sL http://ifconfig.me 3 | -------------------------------------------------------------------------------- /local/bin/myip-ipecho: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -sL http://ipecho.net/plain 3 | -------------------------------------------------------------------------------- /local/bin/myip-ipinfo: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -sL https://ipinfo.io/ip 3 | -------------------------------------------------------------------------------- /local/bin/soks5proxyhttp: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | connect -H 127.0.0.1:1235 "$@" 3 | -------------------------------------------------------------------------------- /local/bin/jmxterm: -------------------------------------------------------------------------------- 1 | java -jar $HOME/local/libs/jmxterm-1.0-alpha-4-uber.jar 2 | -------------------------------------------------------------------------------- /local/bin/crash: -------------------------------------------------------------------------------- 1 | java -jar ~/local/libs/crash.shell-1.3.1-SNAPSHOT-standalone.jar 2 | -------------------------------------------------------------------------------- /local/bin/myip-dig: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | dig +short myip.opendns.com @resolver1.opendns.com 3 | -------------------------------------------------------------------------------- /local/bin/tinyproxy_stop.sh: -------------------------------------------------------------------------------- 1 | kill $(cat /usr/local/var/run/tinyproxy/tinyproxy.pid) 2 | -------------------------------------------------------------------------------- /.config/uv/uv.toml: -------------------------------------------------------------------------------- 1 | [[index]] 2 | url = "https://pypi.tuna.tsinghua.edu.cn/simple" 3 | default = true 4 | -------------------------------------------------------------------------------- /local/bin/rsocks_start.sh: -------------------------------------------------------------------------------- 1 | nohup $HOME/.virtualenvs/7/bin/rsocks --config=$HOME/.rsocks.toml >/dev/null & 2 | -------------------------------------------------------------------------------- /local/bin/myip-ipip: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -s https://myip.ipip.net | awk -F ':' '{print $2}' | awk '{print $1}' 3 | -------------------------------------------------------------------------------- /local/bin/soks5proxyssh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ssh -o ProxyCommand="$HOME/local/bin/socks5proxywrapper %h %p" "$@" 3 | -------------------------------------------------------------------------------- /mac/phoenix/_asserts/window.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alswl/.oOo./HEAD/mac/phoenix/_asserts/window.gif -------------------------------------------------------------------------------- /local/bin/paste-weread-to-md: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pbpaste | 4 | gsed 's/◆ /> /' 5 | 6 | 7 | # vim: set ft=sh: 8 | -------------------------------------------------------------------------------- /.jslintrc: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, regexp: true */ 2 | /*global jQuery, $, window */ 3 | 4 | // vim: set ft=javascript: 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | email= 2 | registry=https://registry.npmmirror.com 3 | electron_mirror=https://npmmirror.com/mirrors/electron/ 4 | -------------------------------------------------------------------------------- /local/bin/apple-music-playing: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | osascript -e 'tell application "Music" to get name of current track' 4 | -------------------------------------------------------------------------------- /local/bin/format-gfm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat $1 | pandoc -f markdown_github -t markdown_github --wrap=none | sponge $1 4 | -------------------------------------------------------------------------------- /local/bin/paste-md-to-html: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pbpaste | 4 | pandoc -f markdown -t html 5 | 6 | # vim: set ft=sh: 7 | -------------------------------------------------------------------------------- /local/bin/paste-weread-to-md-copy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./paste-weread-to-md | pbcopy 4 | 5 | 6 | # vim: set ft=sh: 7 | 8 | -------------------------------------------------------------------------------- /.wgetrc: -------------------------------------------------------------------------------- 1 | # 不要乱转义中文 2 | --restrict-file-names=nocontrol 3 | # 使用重定向后的文件名 4 | --trust-server-names=on 5 | --content-disposition=on 6 | -------------------------------------------------------------------------------- /local/bin/resize-img-1200: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # using imagemagic to resize image 3 | 4 | set -e 5 | 6 | resize-img "$1" 1200x1200 7 | -------------------------------------------------------------------------------- /local/bin/resize-img-2000: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # using imagemagic to resize image 3 | 4 | set -e 5 | 6 | resize-img "$1" 2000x2000 7 | -------------------------------------------------------------------------------- /local/bin/resize-img-800: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # using imagemagic to resize image 3 | 4 | set -e 5 | 6 | resize-img "$1" 800x800 7 | 8 | -------------------------------------------------------------------------------- /mac/phoenix/_asserts/application-launch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alswl/.oOo./HEAD/mac/phoenix/_asserts/application-launch.gif -------------------------------------------------------------------------------- /mac/phoenix/_asserts/application-switch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alswl/.oOo./HEAD/mac/phoenix/_asserts/application-switch.gif -------------------------------------------------------------------------------- /.config/ghostty/config: -------------------------------------------------------------------------------- 1 | window-inherit-working-directory = false 2 | macos-titlebar-proxy-icon = hidden 3 | copy-on-select = clipboard 4 | -------------------------------------------------------------------------------- /.pip/pip.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | #index-url = https://mirrors.aliyun.com/pypi/simple/ 3 | index-url = https://pypi.tuna.tsinghua.edu.cn/simple 4 | -------------------------------------------------------------------------------- /local/bin/fcitx-remote-osa: -------------------------------------------------------------------------------- 1 | #!/usr/bin/osascript 2 | 3 | tell application "System Events" to keystroke "z" using {shift down, control down} 4 | -------------------------------------------------------------------------------- /local/bin/generate-summary-md: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ls *.md | sed 's/.md//g' | grep -v summary | awk '{print "- ["$0"]("$0")"}' >summary.md 4 | -------------------------------------------------------------------------------- /.pydistutils.cfg: -------------------------------------------------------------------------------- 1 | [easy_install] 2 | # index-url = https://mirrors.aliyun.com/pypi/simple/ 3 | index-url = https://pypi.tuna.tsinghua.edu.cn/simple 4 | -------------------------------------------------------------------------------- /local/bin/shadowsocks_client_start_ha.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ss-local -c /usr/local/etc/shadowsocks-libev_ha.json -f /usr/local/var/run/ss-local_ha.pid 4 | -------------------------------------------------------------------------------- /local/bin/paste-rtf-to-md-copy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | 5 | $DIR/paste-rtf-to-md | pbcopy 6 | -------------------------------------------------------------------------------- /local/bin/format-markdown: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat $1 | pandoc -f markdown -t markdown --wrap=auto --columns=100 | sponge $1 4 | 5 | # TODO fix colums not work 6 | -------------------------------------------------------------------------------- /local/bin/paste-rtf-to-html-copy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | 5 | $DIR/paste-rtf-to-html | pbcopy 6 | -------------------------------------------------------------------------------- /.zshrc.etc.d/docker-alias-commands.zshrc: -------------------------------------------------------------------------------- 1 | #alias swagger="docker run --rm -it --user $(id -u):$(id -g) -e GOPATH=$HOME/go:/go -v $HOME:$HOME -w $(pwd) quay.io/goswagger/swagger" 2 | -------------------------------------------------------------------------------- /.zshrc.etc.d/python-global-init.zshrc: -------------------------------------------------------------------------------- 1 | alias python-global-init='pip2 install virtualenvwrapper 2 | pip3 install virtualenvwrapper 3 | pip2 install pynvim 4 | pip3 install pynvim' 5 | -------------------------------------------------------------------------------- /local/bin/paste-html-to-rtf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pbpaste | 4 | textutil -stdin -inputencoding utf-8 -encoding utf-8 -format html -convert rtf -stdout 5 | 6 | # vim: set ft=sh: 7 | -------------------------------------------------------------------------------- /local/bin/ls-upload-log4d: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pushd ~/Dropbox/Public/upload_dropbox 4 | ls */* | awk '{print "!["$0"](http://upload-log4d.qiniudn.com/upload_dropbox/"$0")"}' 5 | popd 6 | -------------------------------------------------------------------------------- /local/bin/paste-html-to-md-copy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | 5 | $DIR/paste-html-to-md | pbcopy 6 | 7 | # vim: set ft=sh: 8 | -------------------------------------------------------------------------------- /local/bin/paste-html-to-rtf-copy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | 5 | $DIR/paste-html-to-rtf | pbcopy 6 | 7 | # vim: set ft=sh: 8 | -------------------------------------------------------------------------------- /local/bin/paste-md-to-html-copy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | 5 | $DIR/paste-md-to-html | pbcopy 6 | 7 | # vim: set ft=sh: 8 | -------------------------------------------------------------------------------- /local/bin/paste-md-to-rtf-copy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | 5 | $DIR/paste-md-to-rtf | pbcopy 6 | 7 | # vim: set ft=sh: 8 | -------------------------------------------------------------------------------- /local/bin/mouse-tracking-echo-in-shell: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # usage: source mouse-tracing-echo-in-shell 3 | # and move your mouse 4 | # https://stackoverflow.com/a/51911371/342757 5 | 6 | echo -e "\e[?1003h" 7 | -------------------------------------------------------------------------------- /local/bin/paste-rtf-to-md-for-table-copy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | 5 | $DIR/paste-rtf-to-md-for-table | pbcopy 6 | 7 | # vim: set ft=sh: 8 | -------------------------------------------------------------------------------- /local/bin/svn_diff_wrapper: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 配置你喜欢的diff程序路径 3 | DIFF="vimdiff" 4 | # SVN diff命令会传入两个文件的参数 5 | LEFT=${6} 6 | RIGHT=${7} 7 | # 拼接成diff命令所需要的命令格式 8 | $DIFF $LEFT $RIGHT 9 | 10 | # vim: set ft=sh: 11 | -------------------------------------------------------------------------------- /.nload: -------------------------------------------------------------------------------- 1 | Version="1" 2 | AverageWindow="300" 3 | BarMaxIn="10240" 4 | BarMaxOut="10240" 5 | DataFormat="Human Readable (Byte)" 6 | Devices="all" 7 | MultipleDevices="[ ]" 8 | RefreshInterval="500" 9 | TrafficFormat="MByte" 10 | -------------------------------------------------------------------------------- /local/bin/yaml-pretty-pyyaml: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # cat f | yaml-pretty-pyyaml 3 | # comment inline is not supported 4 | 5 | python -c 'import sys,yaml; print(yaml.dump_all(yaml.safe_load_all(sys.stdin), indent=2, allow_unicode=True))' 6 | -------------------------------------------------------------------------------- /local/bin/git-archive-zip: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BRANCH=master 4 | 5 | if [ -n "$1" ]; then 6 | BRANCH=$1 7 | fi 8 | 9 | git archive --format zip --output ../$(basename "$PWD").$(git rev-parse --short "$BRANCH").zip "$BRANCH" 10 | -------------------------------------------------------------------------------- /local/bin/git_diff_wrapper: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # deprecated, shoud use git difftoll 3 | # see https://git-scm.com/docs/git-difftool 4 | # see https://stackoverflow.com/questions/3713765/viewing-all-git-diffs-with-vimdiff 5 | 6 | vimdiff "$2" "$5" 7 | -------------------------------------------------------------------------------- /local/bin/git-changes: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | target_branch=origin/master 4 | 5 | # if params is empty, using origin/master 6 | if [ $# -eq 1 ]; then 7 | target_branch=$1 8 | fi 9 | 10 | git log --format='- %h: %s' "$target_branch"..HEAD 11 | -------------------------------------------------------------------------------- /local/bin/yaml-pretty: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # usage: yaml-pretty your-file 3 | 4 | # Checking to ensure a filename was specified and that it exists 5 | if [ -f "$1" ]; then 6 | yq --prettyPrint -M "$1" | sponge "$1"; 7 | else 8 | echo "No file given!" 9 | fi 10 | -------------------------------------------------------------------------------- /.zprofile: -------------------------------------------------------------------------------- 1 | # Added by Toolbox App 2 | export PATH="$PATH:$HOME/Library/Application Support/JetBrains/Toolbox/scripts" 3 | 4 | 5 | [ -f /usr/local/bin/brew ] && eval $(/usr/local/bin/brew shellenv) 6 | [ -f /opt/homebrew/bin/brew ] && eval $(/opt/homebrew/bin/brew shellenv) 7 | -------------------------------------------------------------------------------- /local/bin/dig-http: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # query DNS via DNSPod HTTP API 4 | # 5 | # API doc: https://www.dnspod.cn/httpdns/guide 6 | 7 | domain=$1 8 | 9 | if [ -z $domain ]; then 10 | echo "error auguments" 11 | exit 0 12 | fi 13 | 14 | curl -s "http://119.29.29.29/d?dn=$domain." 15 | -------------------------------------------------------------------------------- /local/bin/paste-md-to-rtf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #set -x 4 | #set -e 5 | 6 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 7 | 8 | $DIR/paste-md-to-html | 9 | textutil -stdin -inputencoding utf-8 -encoding utf-8 -format html -convert rtf -stdout 10 | 11 | # vim: set ft=sh: 12 | -------------------------------------------------------------------------------- /local/bin/paste-rtf-to-html: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | osascript -e 'the clipboard as "HTML"' | 4 | perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))' | 5 | gsed -E 's/style="[^"]+"//g' | 6 | gsed -E 's/ / /g' | 7 | gsed -E 's/​//g' | 8 | gsed -E 's///g' 9 | 10 | # vim: set ft=sh: 11 | -------------------------------------------------------------------------------- /.zshrc.etc.d/chmod-root-s.zshrc: -------------------------------------------------------------------------------- 1 | alias chmod-root-s-hostess='sudo chown root:wheel /usr/local/Cellar/hostess/*/bin/hostess; sudo chmod +s /usr/local/Cellar/hostess/*/bin/hostess' 2 | alias chmod-root-s-mtr='sudo chown root:wheel /usr/local/Cellar/mtr/*/sbin/mtr-packet; sudo chmod +s /usr/local/Cellar/mtr/*/sbin/mtr-packet' 3 | -------------------------------------------------------------------------------- /local/bin/funiq: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # funiq = file uniq 3 | 4 | FILE_NAME=$1 5 | 6 | if [ -z $FILE_NAME ]; then 7 | echo "Useage: file-uniq filename" 8 | exit 0 9 | fi 10 | 11 | HASH=$(cat "$FILE_NAME" | gmd5sum | cut -c -7) 12 | NAME="${FILE_NAME%.*}" 13 | EXT="${FILE_NAME##*.}" 14 | 15 | mv "$FILE_NAME" "$NAME.$HASH.$EXT" 16 | -------------------------------------------------------------------------------- /local/bin/paste-rtf-to-md-for-table: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | 5 | $DIR/paste-rtf-to-html | 6 | sed 's/

//g' | 7 | sed 's/<\/p>//g' | 8 | sed 's/
//g' | 9 | pandoc -f html --wrap none -t 'markdown_strict+pipe_tables' 10 | 11 | # vim: set ft=sh: 12 | -------------------------------------------------------------------------------- /local/bin/uniqf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # funiq = file uniq 3 | 4 | FILE_NAME=$1 5 | 6 | if [ -z $FILE_NAME ]; then 7 | echo "Useage: file-uniq filename" 8 | exit 0 9 | fi 10 | 11 | HASH=$(cat "$FILE_NAME" | gmd5sum | cut -c -7) 12 | NAME="${FILE_NAME%.*}" 13 | EXT="${FILE_NAME##*.}" 14 | 15 | mv "$FILE_NAME" "$NAME.$HASH.$EXT" 16 | -------------------------------------------------------------------------------- /local/bin/rime_dict_manager: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # put this script in ~/Library/Rime, list existing user dictionaries: 4 | # ./rime_dict_manager --list 5 | # see other supported options: 6 | # ./rime_dict_manager 7 | 8 | DYLD_LIBRARY_PATH="/Library/Input Methods/Squirrel.app/Contents/Frameworks" "/Library/Input Methods/Squirrel.app/Contents/MacOS/rime_dict_manager" $@ 9 | -------------------------------------------------------------------------------- /local/bin/paste-simplemind-outline-to-md: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 1. tab to space 4 | # 2. add - before every emptyline 5 | # 3. remove head space 6 | # 4. add newline to second line 7 | 8 | pbpaste \ 9 | | gsed -E 's/\t/ /g' \ 10 | | gsed -E 's/( +) /\1- /g' \ 11 | | gsed -E 's/^ //g' \ 12 | | awk 'NR==1{print; print ""} NR!=1' 13 | 14 | # vim: set ft=sh: 15 | -------------------------------------------------------------------------------- /local/bin/git-code-numbers-by-authors: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SINCE=$1 4 | 5 | if [ -z $SINCE ]; then 6 | SINCE=50.years 7 | fi 8 | 9 | git log --since=$SINCE --numstat --pretty="%ae %H" | sed 's/@.*//g' | awk '{ if (NF == 1){ name = $1}; if(NF == 3) {plus[name] += $1; minus[name] += $2}} END { for (name in plus) {print name": +"plus[name]" -"minus[name]}}' | sort -k2 -gr 10 | -------------------------------------------------------------------------------- /local/bin/privoxy_restart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #set -e 4 | #set -x 5 | 6 | killall privoxy 7 | PORT=$(networksetup -getsocksfirewallproxy Wi-Fi | grep 'Port' | cut -d ' ' -f2) 8 | cp $HOME/local/etc/privoxy/config.template /usr/local/etc/privoxy/config 9 | /usr/local/bin/gsed -i "s/PORT/$PORT/g" /usr/local/etc/privoxy/config 10 | 11 | /usr/local/sbin/privoxy /usr/local/etc/privoxy/config 12 | networksetup -setsocksfirewallproxystate Wi-Fi off 13 | -------------------------------------------------------------------------------- /local/bin/tsa: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $(tmux ls | grep sa | wc -l) -gt 0 ]; then 4 | tmux attach -t sa 5 | exit 6 | fi 7 | 8 | tmux new -s sa -d 9 | for host in 12; do 10 | cmd='echo "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > /home/admin/alswl/.ssh/auth_sock.sh && chmod 755 /home/admin/alswl/.ssh/auth_sock.sh && screen -rD sa_d' 11 | tmux neww -d -t $host -n "s$host" "ssh s$host -t '$cmd'" 12 | done 13 | tmux killw -t 0 14 | 15 | tmux attach -t sa 16 | -------------------------------------------------------------------------------- /local/bin/puml-format-order-node: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # format plantuml file for ording description. 3 | # eg. 4 | # 5 | # original file: 6 | # 7 | # BigFish -> Bateway: 0. Request 8 | # Bateway -> openmonitor: 0.Forward 9 | # 10 | # after file: 11 | # 12 | # BigFish -> Bateway: 1. Request 13 | # Bateway -> openmonitor: 2.Forward 14 | 15 | cat $1 | sponge | perl -pe 's/(: +)(\d+)\. +/"$1".++$i.". "/e' | sponge $1 16 | 17 | # vim: set ft=sh: 18 | -------------------------------------------------------------------------------- /local/bin/git-min-backup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | DIR=$PWD 6 | 7 | if [ ! -z $1 ]; then 8 | DIR=$1 9 | fi 10 | 11 | 12 | if [[ $(git -C $DIR status --porcelain) ]]; then 13 | # Changes 14 | echo 'Error, Git Changed, exited' 15 | exit 1 16 | else 17 | # No changes 18 | echo -n '' 19 | fi 20 | 21 | DIR=$(greadlink -f $DIR) 22 | NAME=$(basename $DIR) 23 | 24 | git -C $DIR remote -v > $(dirname $DIR)/$NAME.git.archived 25 | trash $DIR 26 | -------------------------------------------------------------------------------- /.gitignore_global: -------------------------------------------------------------------------------- 1 | ## Vim ## 2 | 3 | # Swap 4 | [._]*.s[a-v][a-z] 5 | [._]*.sw[a-p] 6 | [._]s[a-rt-v][a-z] 7 | [._]ss[a-gi-z] 8 | [._]sw[a-p] 9 | 10 | # Session 11 | Session.vim 12 | 13 | # Temporary 14 | .netrwhist 15 | *~ 16 | # Auto-generated tag files 17 | /tags 18 | # Persistent undo 19 | [._]*.un~ 20 | 21 | ## Jetbrains 22 | 23 | .idea 24 | 25 | 26 | ## My Global ## 27 | 28 | *.generated.html 29 | .DS_Store 30 | .java-version 31 | .python-version 32 | ~* 33 | .env 34 | .venv 35 | -------------------------------------------------------------------------------- /.screenrc: -------------------------------------------------------------------------------- 1 | startup_message off # default: on 2 | 3 | autodetach on # default:on 4 | 5 | shell zsh 6 | 7 | encoding UTF-8 8 | 9 | caption always "%{=b}%{b}%{C}[stream]%{-} %+010=%-w%8L>%{uB .my}*%n %t%{-}%+w%-014< %-012=%{b m} " 10 | 11 | term screen-256color 12 | 13 | # bind F9 to "move to previous window" 14 | bindkey -k k9 prev 15 | # bind F10 to "move to next window" 16 | bindkey -k k; next 17 | 18 | # bind key see 19 | # http://web.mit.edu/gnu/doc/html/screen_toc.html#SEC82 20 | -------------------------------------------------------------------------------- /local/bin/qrdecode: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # usage: # copy image data, and run qrdecode 3 | 4 | set -e 5 | 6 | check_command_installed() { 7 | name=$1 8 | brew_name=$2 9 | if ! [ -x "$(command -v $name)" ]; then 10 | echo "Error: Required GNU $name, try \`brew install $brew_name\`" 11 | exit 1 12 | fi 13 | } 14 | check_command_installed brew brew 15 | check_command_installed zbarimg zbarimg 16 | check_command_installed pngpaste pngpaste 17 | 18 | pngpaste /tmp/a.png && zbarimg /tmp/a.png 19 | -------------------------------------------------------------------------------- /mac/phoenix/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es6", 4 | "allowJs": false, 5 | "target": "es6", 6 | "strict": true, 7 | "pretty": true, 8 | "moduleResolution": "node", 9 | "typeRoots": [ 10 | "./node_modules/@types", 11 | "./typings/globals/" 12 | ], 13 | "lib": [ 14 | "es2017" 15 | ] 16 | }, 17 | "include": [ 18 | "./src/**/*" 19 | ], 20 | "exclude": [ 21 | "node_modules", 22 | "**/*.spec.ts" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /linux/.Xmodmap: -------------------------------------------------------------------------------- 1 | ! clear 2 | 3 | !clear lock 4 | !clear control 5 | !clear mod1 6 | !clear mod4 7 | 8 | ! modify physical keycode to logical button 9 | 10 | !keycode 64 = Super_L Super_L Super_L Super_L 11 | !keycode 108 = Super_R Super_R Super_R Super_R 12 | !keycode 133 = Control_L Control_L Control_L Control_L 13 | !keycode 134 = Control_R Control_R Control_R Control_R 14 | 15 | ! add logical button to logical modifier group 16 | 17 | !add control = Caps_Lock Control_L Control_R 18 | !add mod4 = Super_L Super_R 19 | -------------------------------------------------------------------------------- /local/bin/shj: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # shortcut command for ssh login 4 | # ssh-agent 5 | # tmux 6 | # tmux set window title 7 | # usage: shj 192.168.1.1 8 | 9 | SHORTCUT=$1 10 | #SHORTCUT=`echo $SHORTCUT | sed 's/^192\.168\.//g'` 11 | #SHORTCUT=`echo $SHORTCUT | sed 's/^192\.168\.//g'` 12 | 13 | # set tmux window title 14 | printf "\033k$SHORTCUT\033\\" 15 | 16 | ssh $SHORTCUT -A -t 'echo "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > /home/hjdjc/.ssh/auth_sock.sh && chmod 755 /home/hjdjc/.ssh/auth_sock.sh && screen -RDU alswl' 17 | 18 | exit 19 | -------------------------------------------------------------------------------- /local/bin/release-sbt-to-git-release-binary-branch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | sbt clean assembly 6 | 7 | GIT_HASH=$(git rev-parse --short HEAD) 8 | BRANCH=release-binary-$(date +%y%m%d.%H%M)-$GIT_HASH 9 | TAG=v-$(date +%y%m%d.%H%M) 10 | 11 | git tag $TAG 12 | git push origin $TAG 13 | git checkout --orphan $BRANCH 14 | cp target/scala-*/*-assembly-*.jar . 15 | git rm --cached -r . 16 | cp *-assembly-*.jar . 17 | git add -f *.jar 18 | git commit -a -m 'release' 19 | git push origin HEAD 20 | git checkout -f master 21 | git branch -D $BRANCH 22 | -------------------------------------------------------------------------------- /local/bin/shadowsocks_client_start_hk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | args=$(getopt -a -o: -l japan,hokong: -- $*) # Notice: Mac OSX 上面 getopt 非标准实现,需要安装 `brew install gnu-getopt` 4 | eval set -- "$args" 5 | 6 | for i; do 7 | case "$1" in 8 | -j | --japan) 9 | japan="1" 10 | shift 2 11 | ;; 12 | -h | --hongkong) 13 | terrier=$2 14 | shift 2 15 | ;; 16 | --) 17 | shift 18 | break 19 | ;; 20 | esac 21 | done 22 | 23 | ss-local -c /usr/local/etc/shadowsocks-libev_hk.json -b 127.0.0.1 -f /usr/local/var/run/ss-local.pid 24 | -------------------------------------------------------------------------------- /local/bin/shadowsocks_client_start_jp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | args=$(getopt -a -o: -l japan,hokong: -- $*) # Notice: Mac OSX 上面 getopt 非标准实现,需要安装 `brew install gnu-getopt` 4 | eval set -- "$args" 5 | 6 | for i; do 7 | case "$1" in 8 | -j | --japan) 9 | japan="1" 10 | shift 2 11 | ;; 12 | -h | --hongkong) 13 | terrier=$2 14 | shift 2 15 | ;; 16 | --) 17 | shift 18 | break 19 | ;; 20 | esac 21 | done 22 | 23 | ss-local -c /usr/local/etc/shadowsocks-libev_jp.json -b 127.0.0.1 -f /usr/local/var/run/ss-local.pid 24 | -------------------------------------------------------------------------------- /.zshrc.etc.d/kube-promote.zshrc: -------------------------------------------------------------------------------- 1 | kube_prompt_info () { 2 | local context 3 | if [[ "$(command kubectl config get-contexts | grep '*' | wc -l | awk '{print $1}' 2>/dev/null)" != "0" ]] 4 | then 5 | context=$(command kubectl config get-contexts | grep '*' | awk '{print $2"@"$3}' 2> /dev/null) || return 0 6 | echo "%{%}(%{%}${context}%{%})%{%} " 7 | fi 8 | } 9 | 10 | load_kube_promote_info() { 11 | export PROMOTE='%{$fg[cyan]%}%c%{$reset_color%} $(git_prompt_info)$(kube_prompt_info)${ret_status}%{$reset_color%} ' 12 | export PS1="$PROMOTE" 13 | } 14 | -------------------------------------------------------------------------------- /local/bin/paste-html-to-md: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pbpaste | 4 | pandoc -f html --wrap none -t "markdown+pipe_tables-simple_tables-multiline_tables-raw_html-link_attributes" | 5 | gsed -E '/^

$/d' | 6 | gsed -E '/^<\/div>$/d' | 7 | gsed -E '/\s*:::\s*$/d' | 8 | gsed -E '/\s*:::\s* \{.+\}$/d' | 9 | gsed -E 's/\{\s?(\s*(#\S+)*|(\.[a-zA-Z0-9\-]+)*|([a-zA-Z0-9\-]+="[^"]+")*\s*)+\}//g' | 10 | gsed -E 's/\s+$//g' | 11 | gsed -E '/^$/N;/^\n$/D' | 12 | gsed -E '/^\[\[\[\]\]\]$/d' | 13 | gsed -E 's/^\\$//g' | 14 | gsed -E 's/^ $//g' 15 | 16 | # vim: set ft=sh: 17 | -------------------------------------------------------------------------------- /mac/Library/LaunchAgents/com.alswl.edit-server.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.alswl.edit-server 7 | LaunchOnlyOnce 8 | 9 | RunAtLoad 10 | 11 | ProgramArguments 12 | 13 | /bin/bash 14 | -c 15 | $HOME/local/bin/edit-server 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /diff/usr/local/share/zsh/site-functions/git-completion.bash.diff: -------------------------------------------------------------------------------- 1 | --- /usr/local/etc/bash_completion.d/git-completion.bash 2019-03-18 17:29:54.000000000 +0800 2 | +++ /usr/local/share/zsh/site-functions/git-completion.bash 2019-03-18 17:29:47.000000000 +0800 3 | @@ -1329,7 +1329,12 @@ 4 | [ -n "$(__git_find_on_cmdline "$flags")" ]; then 5 | track_opt='' 6 | fi 7 | - __git_complete_refs $track_opt 8 | + #__git_complete_refs $track_opt 9 | + if [ "$command" = "checkoutr" ]; then 10 | + __git_complete_refs $track_opt 11 | + else 12 | + __gitcomp_nl "$(__git_heads '' $track)" 13 | + fi 14 | ;; 15 | esac 16 | } 17 | -------------------------------------------------------------------------------- /local/bin/release-mvn-to-git-release-binary-branch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | TARGET=$1 7 | 8 | REPO_PATH=$(git rev-parse --show-toplevel) 9 | REPO_NAME=$(basename $REPO_PATH) 10 | 11 | mvn clean package 12 | GIT_HASH=$(git rev-parse --short HEAD) 13 | BRANCH=$REPO_NAME-release-binary-$(date +%y%m%d.%H%M)-$GIT_HASH 14 | TAG=$REPO_NAME-$(date +%y%m%d.%H%M) 15 | git tag $TAG 16 | git push origin $TAG 17 | git checkout --orphan $BRANCH 18 | cp $TARGET . 19 | git rm --cached -r . 20 | git add -f *.jar 21 | git commit -a -m 'release' 22 | git push origin HEAD 23 | git checkout -f master 24 | git branch -D $BRANCH 25 | -------------------------------------------------------------------------------- /.htoprc: -------------------------------------------------------------------------------- 1 | # Beware! This file is rewritten every time htop exits. 2 | # The parser is also very primitive, and not human-friendly. 3 | # (I know, it's in the todo list). 4 | fields=0 48 17 18 38 39 40 2 46 47 49 1 5 | sort_key=46 6 | sort_direction=1 7 | hide_threads=1 8 | hide_kernel_threads=1 9 | hide_userland_threads=1 10 | shadow_other_users=1 11 | highlight_base_name=0 12 | highlight_megabytes=1 13 | highlight_threads=0 14 | tree_view=0 15 | header_margin=1 16 | detailed_cpu_time=0 17 | color_scheme=0 18 | delay=15 19 | left_meters=AllCPUs Memory Swap 20 | left_meter_modes=1 1 1 21 | right_meters=Tasks LoadAverage Uptime 22 | right_meter_modes=2 2 2 23 | -------------------------------------------------------------------------------- /linux/.xprofile: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | xrandr --output HDMI1 --brightness 0.85 4 | xrandr --output DP2 --brightness 0.85 5 | xrandr --output HDMI1 --primary 6 | xrandr --output DP2 --rotate normal --right-of HDMI1 7 | 8 | xset r rate 200 30 9 | 10 | export GTK_IM_MODULE=fcitx 11 | export QT_IM_MODULE=fcitx 12 | export XMODIFIERS=@im=fcitx 13 | 14 | xscreensaver -no-splash & 15 | numlockx & 16 | fcitx & 17 | #ibus-daemon -drx 18 | dropbox & 19 | copyq & 20 | xclip & 21 | albert & 22 | rescuetime & 23 | shutter --min_at_startup & 24 | 25 | /usr/bin/feh --randomize --bg-scale $HOME/Pictures/bing-wallpapers.all 26 | wmname LG3D 27 | 28 | #exec awesome 29 | #exec i3 30 | -------------------------------------------------------------------------------- /VimFx-custom/bootstrap.js: -------------------------------------------------------------------------------- 1 | let {classes: Cc, interfaces: Ci, utils: Cu} = Components 2 | function startup() { 3 | Cu.import('resource://gre/modules/Services.jsm') 4 | Cu.import('resource://gre/modules/devtools/Console.jsm') 5 | let apiPref = 'extensions.VimFx.api_url' 6 | let apiUrl = Services.prefs.getComplexValue(apiPref, Ci.nsISupportsString).data 7 | Cu.import(apiUrl, {}).getAPI(vimfx => { 8 | let path = __SCRIPT_URI_SPEC__.replace('bootstrap.js', 'vimfx.js') 9 | let scope = {Cc, Ci, Cu, vimfx} 10 | Services.scriptloader.loadSubScript(path, scope, 'UTF-8') 11 | }) 12 | } 13 | function shutdown() {} 14 | function install() {} 15 | function uninstall() {} -------------------------------------------------------------------------------- /local/bin/resize-img: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # using imagemagic to resize image 3 | 4 | set -e 5 | 6 | file_name=$1 7 | size=$2 8 | 9 | check_command_installed() { 10 | name=$1 11 | brew_name=$2 12 | if ! [ -x "$(command -v $name)" ]; then 13 | echo "Error: Required GNU $name, try \`brew install $brew_name\`" 14 | exit 1 15 | fi 16 | } 17 | 18 | check_command_installed mogrify 19 | 20 | if [ -z "$file_name" ]; then 21 | echo "Useage: resize-img filename [widthxheight]" 22 | exit 0 23 | fi 24 | if [ -z "$size" ]; then 25 | size='1200x1200' 26 | fi 27 | 28 | cp "$file_name" "$file_name.original" 29 | mogrify -resize $size "$file_name" 30 | 31 | # vim: set ft=sh: 32 | -------------------------------------------------------------------------------- /.webterm.lua: -------------------------------------------------------------------------------- 1 | -- Pull in the wezterm API 2 | local wezterm = require 'wezterm' 3 | 4 | -- This will hold the configuration. 5 | local config = wezterm.config_builder() 6 | 7 | -- This is where you actually apply your config choices 8 | 9 | -- For example, changing the color scheme: 10 | -- config.color_scheme = 'AdventureTime' 11 | -- config.font = wezterm.font 'Monaco' 12 | config.font = wezterm.font("Monaco", {weight="Regular", stretch="Normal", style="Normal"}) 13 | -- config.font = wezterm.font 'Menlo' 14 | config.font_size = 13.0 15 | 16 | config.default_prog = { '/opt/homebrew/bin/tmux' } 17 | 18 | 19 | -- and finally, return the configuration to wezterm 20 | return config 21 | -------------------------------------------------------------------------------- /local/bin/mouse_restore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ## Save 4 | # get current postion, save to last 5 | CURRENT_WINDOW=iTerm 6 | [ -f /tmp/SLATE_M_CURR ] && CURRENT_WINDOW=$(cat /tmp/SLATE_M_CURR) 7 | 8 | # save now pos 9 | 10 | NOW_POS=$(/usr/local/bin/cliclick p | /usr/bin/awk '{print $4}') 11 | echo $NOW_POS >/tmp/SLATE_M_$CURRENT_WINDOW 12 | 13 | ## Restore 14 | if [ $1 != '' ]; then 15 | # get wanted position 16 | POS=500,400 17 | [ -f /tmp/SLATE_M_$1 ] && POS=$(cat /tmp/SLATE_M_$1) 18 | 19 | # restore postion 20 | /usr/local/bin/cliclick m:$POS 21 | 22 | #LAST_WINDOW=iTerm 23 | #[ -f /tmp/SLATE_M_LAST_WINDOW ] && LAST_WINDOW=`cat /tmp/SLATE_M_LAST_WINDOW` 24 | echo $1 >/tmp/SLATE_M_CURR 25 | fi 26 | -------------------------------------------------------------------------------- /local/bin/unzip-gbk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import sys 6 | import zipfile 7 | 8 | print 9 | "Processing File " + sys.argv[1] 10 | 11 | zip_file = zipfile.ZipFile(sys.argv[1], "r"); 12 | 13 | for name in zip_file.namelist(): 14 | utf8name = name.decode('gbk') 15 | print 16 | "Extracting " + utf8name 17 | pathname = os.path.dirname(utf8name) 18 | if not os.path.exists(pathname) and pathname != "": 19 | os.makedirs(pathname) 20 | data = zip_file.read(name) 21 | if not os.path.exists(utf8name): 22 | output_file = open(utf8name, "w") 23 | output_file.write(data) 24 | output_file.close() 25 | 26 | zip_file.close() 27 | -------------------------------------------------------------------------------- /.config/kitty/theme.conf: -------------------------------------------------------------------------------- 1 | background #202020 2 | foreground #adadad 3 | cursor #ffffff 4 | selection_background #1a3272 5 | color0 #000000 6 | color8 #545454 7 | color1 #fa5355 8 | color9 #fb7172 9 | color2 #126e00 10 | color10 #67ff4f 11 | color3 #c2c300 12 | color11 #ffff00 13 | color4 #4581eb 14 | color12 #6d9df1 15 | color5 #fa54ff 16 | color13 #fb82ff 17 | color6 #33c2c1 18 | color14 #60d3d1 19 | color7 #adadad 20 | color15 #eeeeee 21 | selection_foreground #202020 22 | -------------------------------------------------------------------------------- /local/bin/lark-gen-markdown: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | OUTPUT_DIR=./.output 6 | 7 | rm -rf $OUTPUT_DIR/* 8 | touch $OUTPUT_DIR/.gitkeep 9 | cp .lark.yml $OUTPUT_DIR/lark.yml 10 | 11 | for FILE_NAME in $(find . -type f -name "*.md"); do 12 | NEW_FILE_NAME=$OUTPUT_DIR/${FILE_NAME%.*}.md 13 | mkdir -p $(dirname $NEW_FILE_NAME) 14 | cat $FILE_NAME | pandoc -f markdown -t markdown_github --wrap=none >$NEW_FILE_NAME 2>/dev/null 15 | echo "" >>$NEW_FILE_NAME 16 | echo "" >>$NEW_FILE_NAME 17 | echo "" >>$NEW_FILE_NAME 18 | done 19 | 20 | for ASSETS_DIR in $(find . -type d -name "*.assets"); do 21 | rsync -q -avr $ASSETS_DIR/ $OUTPUT_DIR/$ASSETS_DIR/ 22 | done 23 | 24 | generate-output-summary-md 25 | -------------------------------------------------------------------------------- /local/bin/tinypng: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # set token in your `~/.zshrc.etc.d/tinypng.zshrc`, 3 | # export TINYPNG_API_SECRECT=YOUR-TOKEN-HERE 4 | 5 | set -e 6 | 7 | file_name=$1 8 | 9 | check_command_installed() { 10 | name=$1 11 | brew_name=$2 12 | if ! [ -x "$(command -v $name)" ]; then 13 | echo "Error: Required GNU $name, try \`brew install $brew_name\`" 14 | exit 1 15 | fi 16 | } 17 | 18 | if [ -z "$file_name" ]; then 19 | echo "Useage: tinypng filename" 20 | exit 0 21 | fi 22 | check_command_installed jq jq 23 | 24 | cp "$file_name" "$file_name.original" 25 | url=$(curl -s --user "api:${TINYPNG_API_SECRECT}" --data-binary "@$file_name" https://api.tinify.com/shrink | jq -r ".output.url") 26 | wget $url -O "$file_name" 27 | 28 | # vim: set ft=sh: 29 | -------------------------------------------------------------------------------- /local/bin/image-from-clipboard-to-png-global: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IMAGE_DIR="$HOME/Desktop/md/assets/" 4 | URL_PREFIX=$IMAGE_DIR 5 | test -d $IMAGE_DIR || mkdir -p $IMAGE_DIR 6 | 7 | FILE_NAME=$1 8 | 9 | if [ -z $FILE_NAME ]; then 10 | FILE_NAME="paste-$(date '+%Y%m%d-%H%M%S').png" 11 | else 12 | FILE_NAME=$FILE_NAME".png" 13 | fi 14 | 15 | if [ $(uname) = 'Darwin' ]; then 16 | PNGPASTE_BIN="/usr/local/bin/pngpaste" 17 | $PNGPASTE_BIN "$IMAGE_DIR/$FILE_NAME" 18 | echo -n "![$FILE_NAME]($URL_PREFIX/$FILE_NAME)" | tee | pbcopy 19 | elif [ $(uname -s) = 'Linux' ] || [ $(uname -o) = 'Cygwin' ]; then 20 | xclip -selection clipboard -t image/png -o >"$IMAGE_DIR/$FILE_NAME" 21 | echo -n "![$FILE_NAME]($URL_PREFIX/$FILE_NAME)" | tee | xclip -selection clipboard 22 | fi 23 | -------------------------------------------------------------------------------- /local/bin/mdmv: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # rename markdown file with assets 3 | 4 | if [ "$#" -eq 2 ]; then 5 | source_path=$1 6 | target_path=$2 7 | fi 8 | 9 | if [ ! -f "${source_path}" ]; then 10 | echo "Error: Cannot find ${source_path}" 11 | exit 1 12 | fi 13 | if [ -f "${target_path}" ]; then 14 | echo "Error: ${target_path} exist" 15 | exit 1 16 | fi 17 | 18 | source_base_name=$(basename "${source_path}") 19 | target_base_name=$(basename "${target_path}") 20 | 21 | mv "${source_path}" "${target_path}" 22 | 23 | if [ -d "${source_path}.assets" ]; then 24 | mv "${source_path}.assets" "${target_path}.assets" 25 | perl -p -i -e 's/(?<=\!\[.{0,100}\]\(.{0,100})'"${source_base_name}"'(?=\.assets\/.+\))/'"${target_base_name}"'/g' "${target_path}" 26 | fi 27 | 28 | # vim: set ft=sh: 29 | -------------------------------------------------------------------------------- /local/bin/mdsearch: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # mdsearch = markdown search 3 | 4 | positional=() 5 | while [[ $# -gt 0 ]]; do 6 | key="$1" 7 | 8 | case $key in 9 | -l | --lib) 10 | list=YES 11 | shift # past argument 12 | ;; 13 | *) # unknown option 14 | positional+=("$1") # save it in an array for later 15 | shift # past argument 16 | ;; 17 | esac 18 | done 19 | 20 | if [ "${#positional[@]}" -eq 1 ]; then 21 | dir=. 22 | text=${positional[0]} 23 | elif [ "${#positional[@]}" -eq 2 ]; then 24 | dir=${positional[0]} 25 | text=${positional[1]} 26 | fi 27 | 28 | parameters="-i --markdown" 29 | 30 | if [ "$list" = "YES" ]; then 31 | parameters="$parameters -l" 32 | fi 33 | 34 | ag $parameters "^#(.*$text.*)" $dir 35 | 36 | # vim: set ft=sh: 37 | -------------------------------------------------------------------------------- /mac/phoenix/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@types/lodash": "^4.14.195", 4 | "@types/phoenix": "github:mafredri/phoenix-typings#main", 5 | "awesome-typescript-loader": "^5.2.1", 6 | "lodash": "^4.17.21", 7 | "source-map-loader": "^4.0.1", 8 | "ts-loader": "^9.4.4", 9 | "tslint": "^6.1.0", 10 | "typescript": "^5.1.6", 11 | "typings": "^2.1.1", 12 | "webpack": "^5.88.1", 13 | "webpack-cli": "^5.1.4" 14 | }, 15 | "name": "phoenix_configuration_ts", 16 | "version": "1.0.0", 17 | "main": "webpack.config.js", 18 | "scripts": { 19 | "test": "echo \"Error: no test specified\" && exit 1" 20 | }, 21 | "keywords": [], 22 | "author": "", 23 | "license": "ISC", 24 | "description": "", 25 | "repository": "git@github.com:alswl/.oOo..git" 26 | } 27 | -------------------------------------------------------------------------------- /local/bin/image-from-clipboard-to-png-copy-markdown: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DOC_NAME=$1 4 | if [ -z $DOC_NAME ]; then 5 | exit 1 6 | fi 7 | 8 | IMAGE_DIR="./${DOC_NAME%.*}.assets" 9 | URL_PREFIX=$IMAGE_DIR 10 | test -d $IMAGE_DIR || mkdir -p $IMAGE_DIR 11 | 12 | FILE_NAME=$2 13 | 14 | if [ -z $FILE_NAME ]; then 15 | FILE_NAME="paste-$(date '+%Y%m%d-%H%M%S').png" 16 | else 17 | FILE_NAME=$FILE_NAME".png" 18 | fi 19 | 20 | if [ $(uname) = 'Darwin' ]; then 21 | PNGPASTE_BIN="/usr/local/bin/pngpaste" 22 | $PNGPASTE_BIN "$IMAGE_DIR/$FILE_NAME" 23 | echo -n "![$FILE_NAME]($URL_PREFIX/$FILE_NAME)" | tee | pbcopy 24 | elif [ $(uname -s) = 'Linux' ] || [ $(uname -o) = 'Cygwin' ]; then 25 | xclip -selection clipboard -t image/png -o >"$IMAGE_DIR/$FILE_NAME" 26 | echo -n "![$FILE_NAME]($URL_PREFIX/$FILE_NAME)" | tee | xclip -selection clipboard 27 | fi 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Vim ## 2 | 3 | *.s[a-w][a-z] 4 | *.un~ 5 | Session.vim 6 | .netrwhist 7 | *~ 8 | 9 | ## Project ## 10 | 11 | .vimperator/info/ 12 | .pentadactyl/info/ 13 | .pip/pip.log 14 | .pip/zsh-cache 15 | 16 | .gitmessage.txt 17 | .fonts/.uuid 18 | .fonts/ttf-dejavu-powerline/.uuid 19 | *.generated.html 20 | .DS_Store 21 | .java-version 22 | .python-version 23 | .zshrc.etc.d/alibaba.zshrc 24 | .zshrc.etc.d/tinypng.zshrc 25 | node_modules 26 | dist 27 | package-lock.json 28 | typings 29 | .zshrc.etc.d/*alibaba*.zshrc 30 | .zshrc.etc.d/*secrets*.zshrc 31 | .config/goneovim/sessions 32 | .zsh_completion/_baiyan 33 | .zsh_completion/_sofa 34 | .zsh_completion/_antcode 35 | .zshrc.etc.d/_*.zshrc 36 | .config/kitty/kitty.d/local/* 37 | .zsh_completion/_cpt 38 | .zsh_completion/_aone 39 | .zsh_completion/_hrctl 40 | .zsh_completion/_dima 41 | .zsh_completion/_cloudinc 42 | .zsh_completion/_isee 43 | -------------------------------------------------------------------------------- /VimFx-custom/install.rdf: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | VimFx-custom 8 | VimFx-custom@vimfx.org 9 | 1 10 | 11 | 12 | true 13 | true 14 | 2 15 | 16 | 17 | {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 18 | 38 19 | * 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /local/bin/image-from-path-to-assets-copy-markdown: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DOC_NAME=$1 4 | if [ -z $DOC_NAME ]; then 5 | exit 1 6 | fi 7 | 8 | IMAGE_DIR="./${DOC_NAME%.*}.assets" 9 | URL_PREFIX=$IMAGE_DIR 10 | test -d $IMAGE_DIR || mkdir -p $IMAGE_DIR 11 | 12 | if [ $(uname) = 'Darwin' ]; then 13 | SOURCE=$(pbpaste) 14 | elif [ $(uname -s) = 'Linux' ] || [ $(uname -o) = 'Cygwin' ]; then 15 | SOURCE=$(xselect -selection -o) 16 | fi 17 | 18 | FILE_NAME=$2 19 | if [ -z $FILE_NAME ]; then 20 | FILE_NAME=$(basename "$SOURCE") 21 | else 22 | FILE_NAME=$FILE_NAME".png" 23 | fi 24 | 25 | cp "$SOURCE" "$IMAGE_DIR/$FILE_NAME" 26 | 27 | if [ $(uname) = 'Darwin' ]; then 28 | echo -n "![$FILE_NAME]($URL_PREFIX/$FILE_NAME)" | tee | pbcopy 29 | elif [ $(uname -s) = 'Linux' ] || [ $(uname -o) = 'Cygwin' ]; then 30 | echo -n "![$FILE_NAME]($URL_PREFIX/$FILE_NAME)" | tee | xclip -selection clipboard 31 | fi 32 | -------------------------------------------------------------------------------- /local/bin/generate-output-summary-md: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | check_command_installed() { 4 | NAME=$1 5 | BREW_NAME=$2 6 | if ! [ -x "$(command -v $NAME)" ]; then 7 | echo "Error: Required GNU $NAME, try \`brew install $BREW_NAME\`" 8 | exit 1 9 | fi 10 | } 11 | 12 | if [ $(uname) = 'Darwin' ]; then 13 | check_command_installed gsed gnu-sed 14 | fi 15 | 16 | mkdir -p .output 17 | echo -n '' >.output/summary.md 18 | # ls *.md | sed 's/.md//g' | grep -v summary | awk '{print "- ["$0"]("$0")"}' 19 | 20 | for file in $(gfind . -name "*.md" -printf "%T+\t%p\n" | awk '{print $2}' | gsed 's/^\.\///g' | grep -v .output | grep -v summary.md | gsort -h); do 21 | TITLE=$(cat $file | grep -m 1 '^# ' | awk -F '#' '{gsub(/[ \t]+$/, "", $2);gsub(/^[ \t]+/, "", $2); print $2}') 22 | NAME=$(echo $file | sed 's/.md//g' | awk -F '/' '{print $NF}') 23 | echo "- [$TITLE]($NAME)" >>.output/summary.md 24 | done 25 | 26 | # vim: set ft=sh: 27 | -------------------------------------------------------------------------------- /local/bin/ddns-by-cloudflare-wan: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # set domain A record with public IP 3 | # Usage: ddns-by-cloudflare-wan 4 | 5 | set -e 6 | 7 | DOMAIN=$1 8 | ZONE_ID=$2 9 | RECORD_ID=$3 10 | TOKEN=$4 11 | 12 | if [ -z $DOMAIN ] || [ -z $ZONE_ID ] || [ -z $RECORD_ID ] || [ -z $TOKEN ]; then 13 | echo "error auguments" 14 | echo "Usage: ddns-by-cloudflare-wan " 15 | exit 0 16 | fi 17 | 18 | IP=$(curl -s https://ifconfig.me); 19 | C_IP=$(drill $DOMAIN | grep "^$DOMAIN" | awk '{print $5}') 20 | 21 | [ "$IP" = "$C_IP" ] && exit 0 22 | [ -z $IP ] && exit 0 23 | 24 | 25 | curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" \ 26 | -H "Authorization: Bearer ${TOKEN}" \ 27 | -H "Content-Type: application/json" \ 28 | --data "{\"type\":\"A\",\"name\":\"${DOMAIN}\",\"content\":\"${IP}\",\"proxied\":false}" 29 | 30 | # vim: set ft=sh: 31 | -------------------------------------------------------------------------------- /local/bin/mov2gif: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # By: Hua Liang [Stupid ET] 3 | # Website: http://EverET.org 4 | # brew install ffmpeg imagemagick gifsicle 5 | 6 | 7 | check_command_installed() { 8 | name=$1 9 | brew_name=$2 10 | if ! [ -x "$(command -v $name)" ]; then 11 | echo "Error: Required GNU $name, try \`brew install $brew_name\`" 12 | exit 1 13 | fi 14 | } 15 | 16 | check_command_installed ffmpeg ffmpeg 17 | check_command_installed convert imagemagick 18 | check_command_installed gifsicle gifsicle 19 | 20 | mov_file=$1 21 | gif_file=$2 22 | 23 | if [ -z "$mov_file" ]; then 24 | echo "Useage: mov2gif mov_file gif_file" 25 | exit 0 26 | fi 27 | 28 | if [ -z "$gif_file" ]; then 29 | echo "Useage: mov2gif mov_file gif_file" 30 | exit 0 31 | fi 32 | 33 | ffmpeg -i $mov_file -r 10 -f image2pipe -vcodec ppm - | convert -verbose +dither -layers Optimize -resize 640x640\> - gif:- | gifsicle --colors 128 --delay=5 --loop --optimize=3 --multifile - >$gif_file 34 | -------------------------------------------------------------------------------- /local/bin/ddns-by-dnspod: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DEVICE=$1 4 | SUB_DOMAIN=$2 5 | BASE_DOMAIN=$3 6 | DOMAIN_ID=$4 7 | RECORD_ID=$5 8 | TOKEN=$6 9 | 10 | if [ -z $DEVICE ] || [ -z $SUB_DOMAIN ] || [ -z $BASE_DOMAIN ] || [ -z $DOMAIN_ID ] || [ -z $RECORD_ID ] || [ -z $TOKEN ]; then 11 | echo "error auguments" 12 | exit 0 13 | fi 14 | 15 | DOMAIN="$SUB_DOMAIN.$BASE_DOMAIN" 16 | IP=$(ifconfig | grep $DEVICE: -A 4 | grep "inet " | tail -n 1 | awk '{print $2}') 17 | C_IP=$(drill $DOMAIN | grep "^$DOMAIN" | awk '{print $5}') 18 | 19 | [ "$IP" = "$C_IP" ] && exit 0 20 | [ -z $IP ] && exit 0 21 | 22 | #record_list_json=$(curl -s https://dnsapi.cn/Record.List -d "domain=$BASE_DOMAIN&sub_domain=$SUB_DOMAIN&record_type=A&record_line=默认&login_token=$TOKEN&format=json") 23 | 24 | curl -s https://dnsapi.cn/Record.Modify -d "domain_id=$DOMAIN_ID&record_id=$RECORD_ID&sub_domain=$SUB_DOMAIN&record_type=A&record_line=默认&value=$IP&login_token=$TOKEN&format=json" 25 | 26 | # vim: set ft=sh: 27 | -------------------------------------------------------------------------------- /local/bin/mdcp: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # copy markdown file with assets 3 | 4 | if [ "$#" -eq 2 ]; then 5 | source_path=$1 6 | target_path=$2 7 | fi 8 | 9 | if [ ! -f "${source_path}" ]; then 10 | echo "Error: Cannot find ${source_path}" 11 | exit 1 12 | fi 13 | if [ -f "${target_path}" ]; then 14 | echo "Error: ${target_path} exist" 15 | exit 1 16 | fi 17 | 18 | source_base_name=$(basename "${source_path}") 19 | target_base_name=$(basename "${target_path}") 20 | #if [ -d "${target_path}" ]; then 21 | #target_base_name="$target_path"/"" 22 | #target_path="$target_path"/"${source_path##*/}" 23 | #else 24 | #target_base_name=$(basename "${target_path}") 25 | #fi 26 | 27 | cp "${source_path}" "${target_path}" 28 | 29 | if [ -d "${source_path}.assets" ]; then 30 | cp -R "${source_path}.assets" "${target_path}.assets" 31 | perl -p -i -e 's/(?<=\!\[.{0,100}\]\(.{0,100})'"${source_base_name}"'(?=\.assets\/.+\))/'"${target_base_name}"'/g' "${target_path}" 32 | fi 33 | 34 | # vim: set ft=sh: 35 | -------------------------------------------------------------------------------- /local/bin/ddns-by-cloudflare: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Usage: ddns-by-cloudflare.sh 3 | 4 | set -e 5 | 6 | DEVICE=$1 7 | DOMAIN=$2 8 | ZONE_ID=$3 9 | RECORD_ID=$4 10 | TOKEN=$5 11 | 12 | if [ -z $DEVICE ] || [ -z $DOMAIN ] || [ -z $ZONE_ID ] || [ -z $RECORD_ID ] || [ -z $TOKEN ]; then 13 | echo "error auguments" 14 | echo "Usage: ddns-by-cloudflare.sh " 15 | exit 0 16 | fi 17 | 18 | IP=$(ifconfig | grep $DEVICE: -A 4 | grep "inet " | tail -n 1 | awk '{print $2}') 19 | C_IP=$(drill $DOMAIN | grep "^$DOMAIN" | awk '{print $5}') 20 | 21 | [ "$IP" = "$C_IP" ] && exit 0 22 | [ -z $IP ] && exit 0 23 | 24 | 25 | curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" \ 26 | -H "Authorization: Bearer ${TOKEN}" \ 27 | -H "Content-Type: application/json" \ 28 | --data "{\"type\":\"A\",\"name\":\"${DOMAIN}\",\"content\":\"${IP}\",\"proxied\":false}" 29 | 30 | # vim: set ft=sh: 31 | -------------------------------------------------------------------------------- /local/bin/socks5proxywrapper: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ 0 = $# ]; then 6 | echo "export GIT_PROXY_COMMAND='$(which $0)'" 7 | exit 0 8 | fi 9 | 10 | SOCKS_SERVER=127.0.0.1 11 | SOCKS_PORT=1234 12 | SYSTEM_PROXY_ENABLED=$(networksetup -getsocksfirewallproxy Wi-Fi | grep '^Enabled' | cut -d ' ' -f2) 13 | SYSTEM_PROXY_PORT=$(networksetup -getsocksfirewallproxy Wi-Fi | grep 'Port' | cut -d ' ' -f2) 14 | if [[ $SYSTEM_PROXY_ENABLED = "Yes" ]] && [[ $SYSTEM_PROXY_PORT != "0" ]]; then 15 | SOCKS_PORT=$SYSTEM_PROXY_PORT 16 | fi 17 | 18 | # sniproxy 19 | #SOCKS_SERVER=192.168.203.11 20 | #SOCKS_PORT=80 21 | #SOCKS_PORT=443 22 | 23 | if [ $(uname) = 'Darwin' ]; then 24 | # https://bitbucket.org/gotoh/connect 25 | # https://github.com/gotoh/ssh-connect 26 | connect -S ${SOCKS_SERVER}:${SOCKS_PORT} "$@" 27 | elif [ $(uname -s) = 'Linux' ] || [ $(uname -o) = 'Cygwin' ]; then 28 | # openbsd-netcat 29 | exec nc -x${SOCKS_SERVER}:${SOCKS_PORT} -X5 $@ 30 | fi 31 | 32 | # socat 33 | # exec socat STDIO SOCKS4:${SOCKS_SERVER}:$1:$2,socksport=${SOCKS_PORT} 34 | -------------------------------------------------------------------------------- /mac/phoenix/src/app.ts: -------------------------------------------------------------------------------- 1 | import * as _ from "lodash"; 2 | import {restoreMousePositionForWindow, saveMousePositionForWindow} from './mouse'; 3 | import {getCurrentWindow} from "./window"; 4 | 5 | /** 6 | * App Functions 7 | */ 8 | // switch app, and remember mouse position 9 | export function callApp(appName: string, orAppName?: string) { 10 | const window = getCurrentWindow(); 11 | if (window !== undefined) { 12 | saveMousePositionForWindow(window); 13 | } 14 | let app: App | undefined = App.launch(appName); 15 | // backup app 16 | if (app === undefined && orAppName) { 17 | app = App.launch(orAppName); 18 | } 19 | if (app === undefined) { 20 | return; 21 | } 22 | const mainWindow = app.mainWindow(); 23 | if (mainWindow === undefined) { 24 | return; 25 | } 26 | if (window !== undefined && window.hash() === mainWindow.hash()) { 27 | return; 28 | } 29 | 30 | Timer.after(0.300, () => { 31 | (app as App).focus(); 32 | restoreMousePositionForWindow((app as App).mainWindow()); 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /local/bin/ddns-by-dnspod-wan: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # set domain A record with public IP 3 | # Usage: ddns-by-dnspod 4 | 5 | SUB_DOMAIN=$1 6 | BASE_DOMAIN=$2 7 | DOMAIN_ID=$3 8 | RECORD_ID=$4 9 | TOKEN=$5 10 | 11 | if [ -z $SUB_DOMAIN ] || [ -z $BASE_DOMAIN ] || [ -z $DOMAIN_ID ] || [ -z $RECORD_ID ] || [ -z $TOKEN ]; then 12 | echo "error auguments" 13 | echo "Usage: ddns-by-dnspod " 14 | exit 0 15 | fi 16 | 17 | DOMAIN="$SUB_DOMAIN.$BASE_DOMAIN" 18 | IP=$(curl -s https://ifconfig.me); 19 | C_IP=$(drill $DOMAIN | grep "^$DOMAIN" | awk '{print $5}') 20 | 21 | [ "$IP" = "$C_IP" ] && exit 0 22 | [ -z $IP ] && exit 0 23 | 24 | #record_list_json=$(curl -s https://dnsapi.cn/Record.List -d "domain=$BASE_DOMAIN&sub_domain=$SUB_DOMAIN&record_type=A&record_line=默认&login_token=$TOKEN&format=json") 25 | 26 | curl -s https://dnsapi.cn/Record.Modify -d "domain_id=$DOMAIN_ID&record_id=$RECORD_ID&sub_domain=$SUB_DOMAIN&record_type=A&record_line=默认&value=$IP&login_token=$TOKEN&format=json" 27 | 28 | # vim: set ft=sh: 29 | -------------------------------------------------------------------------------- /local/bin/view-pyc-file: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import platform 4 | import time 5 | import sys 6 | import binascii 7 | import marshal 8 | import dis 9 | import struct 10 | 11 | 12 | def view_pyc_file(path): 13 | """Read and display a content of the Python`s bytecode in a pyc-file.""" 14 | 15 | file = open(path, 'rb') 16 | 17 | magic = file.read(4) 18 | timestamp = file.read(4) 19 | size = None 20 | 21 | if sys.version_info.major == 3 and sys.version_info.minor >= 3: 22 | size = file.read(4) 23 | size = struct.unpack('I', size)[0] 24 | 25 | code = marshal.load(file) 26 | 27 | magic = binascii.hexlify(magic).decode('utf-8') 28 | timestamp = time.asctime(time.localtime(struct.unpack('I', b'D\xa5\xc2X')[0])) 29 | 30 | dis.disassemble(code) 31 | 32 | print('-' * 80) 33 | print( 34 | 'Python version: {}\nMagic code: {}\nTimestamp: {}\nSize: {}' 35 | .format(platform.python_version(), magic, timestamp, size) 36 | ) 37 | 38 | file.close() 39 | 40 | 41 | if __name__ == '__main__': 42 | view_pyc_file(sys.argv[1]) 43 | 44 | # vim: set ft=python: 45 | -------------------------------------------------------------------------------- /local/bin/view-pyc-file3: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import platform 4 | import time 5 | import sys 6 | import binascii 7 | import marshal 8 | import dis 9 | import struct 10 | 11 | 12 | def view_pyc_file(path): 13 | """Read and display a content of the Python`s bytecode in a pyc-file.""" 14 | 15 | file = open(path, 'rb') 16 | 17 | magic = file.read(4) 18 | timestamp = file.read(4) 19 | size = None 20 | 21 | if sys.version_info.major == 3 and sys.version_info.minor >= 3: 22 | size = file.read(4) 23 | size = struct.unpack('I', size)[0] 24 | 25 | code = marshal.load(file) 26 | 27 | magic = binascii.hexlify(magic).decode('utf-8') 28 | timestamp = time.asctime(time.localtime(struct.unpack('I', b'D\xa5\xc2X')[0])) 29 | 30 | dis.disassemble(code) 31 | 32 | print('-' * 80) 33 | print( 34 | 'Python version: {}\nMagic code: {}\nTimestamp: {}\nSize: {}' 35 | .format(platform.python_version(), magic, timestamp, size) 36 | ) 37 | 38 | file.close() 39 | 40 | 41 | if __name__ == '__main__': 42 | view_pyc_file(sys.argv[1]) 43 | 44 | # vim: set ft=python: 45 | -------------------------------------------------------------------------------- /linux/.Xresources: -------------------------------------------------------------------------------- 1 | !Set background color and transparent property 2 | URxvt.background: rgba:0010/0010/0010/cccc 3 | URxvt.foreground: #CBCB7A 4 | 5 | !Black 6 | URxvt.color0: #000000 7 | URxvt.color8: #555753 8 | !Red 9 | URxvt.color1: #CC0000 10 | URxvt.color9: #EF2929 11 | !Green 12 | URxvt.color2: #4E9A06 13 | URxvt.color10: #8AE234 14 | !Yellow 15 | URxvt.color3: #C4A000 16 | URxvt.color11: #FCE94F 17 | !Blue 18 | URxvt.color4: #3465A4 19 | URxvt.color12: #729FCF 20 | !Magenta 21 | URxvt.color5: #75507B 22 | URxvt.color13: #AD7FA8 23 | !Cyan 24 | URxvt.color6: #06989A 25 | URxvt.color14: #34E2E2 26 | !White 27 | URxvt.color7: #D3D7CF 28 | URxvt.color15: #EEEEEC 29 | 30 | !Replace these font settings by your favorate 31 | URxvt*font: xft:Monospace:size=12:antialias=true 32 | 33 | URxvt.scrollbar: False 34 | ! Use shift+pageup/down to scroll in screen 35 | URxvt.secondaryScroll: true 36 | 37 | !!Enable the tab and link 38 | URxvt.perl-ext-common: default,matcher 39 | !!Set the default browser 40 | URxvt.urlLauncher: firefox 41 | URxvt.matcher.button: 1 42 | 43 | URxvt.depth: 32 44 | 45 | URxvt*keysym.Home: \033[1~ 46 | URxvt*keysym.End: \033[4~ 47 | -------------------------------------------------------------------------------- /mac/phoenix/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mode: "development", 3 | //mode: "production", 4 | //entry: "./src/phoenix.ts", 5 | entry: "./src/phoenix.ts", 6 | output: { 7 | filename: "./phoenix.js", 8 | }, 9 | 10 | // Enable sourcemaps for debugging webpack's output. 11 | //devtool: "source-map", 12 | 13 | resolve: { 14 | // Add '.ts' and '.tsx' as resolvable extensions. 15 | extensions: [".ts", ".js"] 16 | }, 17 | 18 | module: { 19 | rules: [ 20 | { 21 | test: /\.ts(x?)$/, 22 | exclude: /node_modules/, 23 | use: [ 24 | { 25 | //loader: "awesome-typescript-loader" 26 | loader: "ts-loader" 27 | } 28 | ] 29 | }, 30 | // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. 31 | { 32 | enforce: "pre", 33 | test: /\.js$/, 34 | loader: "source-map-loader" 35 | } 36 | ] 37 | }, 38 | 39 | // Other options... 40 | }; 41 | -------------------------------------------------------------------------------- /local/bin/iterm2-send-zmodem.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Author: Matt Mastracci (matthew@mastracci.com) 3 | # AppleScript from http://stackoverflow.com/questions/4309087/cancel-button-on-osascript-in-a-bash-script 4 | # licensed under cc-wiki with attribution required 5 | # Remainder of script public domain 6 | 7 | osascript -e 'tell application "iTerm2" to version' >/dev/null 2>&1 && NAME=iTerm2 || NAME=iTerm 8 | if [[ $NAME = "iTerm" ]]; then 9 | FILE=$(osascript -e 'tell application "iTerm" to activate' -e 'tell application "iTerm" to set thefile to choose file with prompt "Choose a file to send"' -e "do shell script (\"echo \"&(quoted form of POSIX path of thefile as Unicode text)&\"\")") 10 | else 11 | FILE=$(osascript -e 'tell application "iTerm2" to activate' -e 'tell application "iTerm2" to set thefile to choose file with prompt "Choose a file to send"' -e "do shell script (\"echo \"&(quoted form of POSIX path of thefile as Unicode text)&\"\")") 12 | fi 13 | if [[ $FILE = "" ]]; then 14 | echo Cancelled. 15 | # Send ZModem cancel 16 | echo -e \\x18\\x18\\x18\\x18\\x18 17 | sleep 1 18 | echo 19 | echo \# Cancelled transfer 20 | else 21 | /usr/local/bin/sz "$FILE" -e -b 22 | sleep 1 23 | echo 24 | echo \# Received $FILE 25 | fi 26 | -------------------------------------------------------------------------------- /linux/.config/fontconfig/fonts.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Noto Color Emoji 7 | 8 | 9 | true 10 | 11 | 12 | 18 13 | 14 | 15 | 16 | 17 | sans-serif 18 | 19 | Noto Color Emoji 20 | 21 | 22 | 23 | 24 | monospace 25 | 26 | Noto Color Emoji 27 | 28 | 29 | 30 | 31 | serif 32 | 33 | Noto Color Emoji 34 | 35 | 36 | 37 | 38 | Apple Color Emoji 39 | 40 | Noto Color Emoji 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /local/bin/homebrew-using-mirror: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | mirror=$1 6 | 7 | check_command_installed() { 8 | name=$1 9 | brew_name=$2 10 | if ! [ -x "$(command -v $name)" ]; then 11 | echo "Error: Required GNU $name, try \`brew install $brew_name\`" 12 | exit 1 13 | fi 14 | } 15 | 16 | if [ -z "$mirror" ]; then 17 | echo "Useage: homebrew-using-mirror mirror" 18 | echo "mirror example: https://mirrors.tuna.tsinghua.edu.cn/git/" 19 | echo "default example: https://github.com/" 20 | exit 0 21 | fi 22 | check_command_installed brew brew 23 | 24 | BREW_TAPS="$( 25 | BREW_TAPS="$(brew tap 2>/dev/null)" 26 | echo -n "${BREW_TAPS//$'\n'/:}" 27 | )" 28 | for tap in core cask{,-fonts,-drivers,-versions} command-not-found; do 29 | if [[ ":${BREW_TAPS}:" == *":homebrew/${tap}:"* ]]; then 30 | # 将已有 tap 的上游设置为本镜像并设置 auto update 31 | # 注:原 auto update 只针对托管在 GitHub 上的上游有效 32 | git -C "$(brew --repo homebrew/${tap})" remote set-url origin "${mirror}homebrew/homebrew-${tap}.git" 33 | git -C "$(brew --repo homebrew/${tap})" config homebrew.forceautoupdate true 34 | else # 在 tap 缺失时自动安装(如不需要请删除此行和下面一行) 35 | # brew tap --force-auto-update "homebrew/${tap}" "${mirror}/homebrew/homebrew-${tap}.git" 36 | echo -n '' 37 | fi 38 | done 39 | -------------------------------------------------------------------------------- /local/bin/bing-wallpaper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | export PATH=$PATH:/usr/local/bin 6 | PICTURE_DIR="$HOME/Pictures/bing-wallpapers" 7 | LOCALE=zh-CN 8 | mkdir -p "$PICTURE_DIR" 9 | 10 | check_command_installed() { 11 | NAME=$1 12 | BREW_NAME=$2 13 | if ! [ -x "$(command -v "$NAME")" ]; then 14 | echo "Error: Required GNU $NAME, try \`brew install $BREW_NAME\` or others pkg manager" 15 | exit 1 16 | fi 17 | } 18 | 19 | if [ $(uname) = 'Darwin' ]; then 20 | check_command_installed wget wget 21 | check_command_installed curl curl 22 | check_command_installed ggrep grep 23 | check_command_installed gsed gnu-sed 24 | GREP=ggrep 25 | SED=gsed 26 | elif [[ "$OSTYPE" == 'linux'* ]] || [[ "$OSTYPE" == 'cygwin'* ]]; then 27 | check_command_installed wget wget 28 | check_command_installed curl curl 29 | check_command_installed grep grep 30 | check_command_installed sed sed 31 | GREP=grep 32 | SED=sed 33 | fi 34 | check_command_installed jq jq 35 | 36 | for i in {0..7}; do 37 | URL="https://s.cn.bing.net"$(curl -s "https://www.bing.com/HPImageArchive.aspx?format=js&idx=$i&n=1&mkt=$LOCALE" | jq -r '.images[0].url') 38 | FILENAME=$(echo $URL | $GREP -oP '\K(id=[^=]+.jpg)' | $SED 's/id=//g' | $SED 's/OHR\.//g') 39 | wget -q -nc -O "$PICTURE_DIR/$FILENAME" "$URL" 40 | done 41 | -------------------------------------------------------------------------------- /local/bin/iterm2-recv-zmodem.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Author: Matt Mastracci (matthew@mastracci.com) 3 | # AppleScript from http://stackoverflow.com/questions/4309087/cancel-button-on-osascript-in-a-bash-script 4 | # licensed under cc-wiki with attribution required 5 | # Remainder of script public domain 6 | 7 | osascript -e 'tell application "iTerm2" to version' >/dev/null 2>&1 && NAME=iTerm2 || NAME=iTerm 8 | if [[ $NAME = "iTerm" ]]; then 9 | FILE=$(osascript -e 'tell application "iTerm" to activate' -e 'tell application "iTerm" to set thefile to choose folder with prompt "Choose a folder to place received files in"' -e "do shell script (\"echo \"&(quoted form of POSIX path of thefile as Unicode text)&\"\")") 10 | else 11 | FILE=$(osascript -e 'tell application "iTerm2" to activate' -e 'tell application "iTerm2" to set thefile to choose folder with prompt "Choose a folder to place received files in"' -e "do shell script (\"echo \"&(quoted form of POSIX path of thefile as Unicode text)&\"\")") 12 | fi 13 | 14 | if [[ $FILE = "" ]]; then 15 | echo Cancelled. 16 | # Send ZModem cancel 17 | echo -e \\x18\\x18\\x18\\x18\\x18 18 | sleep 1 19 | echo 20 | echo \# Cancelled transfer 21 | else 22 | cd "$FILE" 23 | /usr/local/bin/rz -E -e -b 24 | sleep 1 25 | echo 26 | echo 27 | echo \# Sent \-\> $FILE 28 | fi 29 | -------------------------------------------------------------------------------- /local/bin/sqlite3-to-mysql.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import sys 4 | 5 | 6 | def main(): 7 | print 8 | "SET sql_mode='NO_BACKSLASH_ESCAPES';" 9 | lines = sys.stdin.read().splitlines() 10 | for line in lines: 11 | processLine(line) 12 | 13 | 14 | def processLine(line): 15 | if ( 16 | line.startswith("PRAGMA") or 17 | line.startswith("BEGIN TRANSACTION;") or 18 | line.startswith("COMMIT;") or 19 | line.startswith("DELETE FROM sqlite_sequence;") or 20 | line.startswith("INSERT INTO \"sqlite_sequence\"") 21 | ): 22 | return 23 | line = line.replace("AUTOINCREMENT", "AUTO_INCREMENT") 24 | line = line.replace("DEFAULT 't'", "DEFAULT '1'") 25 | line = line.replace("DEFAULT 'f'", "DEFAULT '0'") 26 | line = line.replace(",'t'", ",'1'") 27 | line = line.replace(",'f'", ",'0'") 28 | in_string = False 29 | newLine = '' 30 | for c in line: 31 | if not in_string: 32 | if c == "'": 33 | in_string = True 34 | elif c == '"': 35 | newLine = newLine + '`' 36 | continue 37 | elif c == "'": 38 | in_string = False 39 | newLine = newLine + c 40 | print 41 | newLine 42 | 43 | 44 | if __name__ == "__main__": 45 | main() 46 | -------------------------------------------------------------------------------- /local/bin/csv2json: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import csv 4 | import json 5 | import time 6 | import sys 7 | 8 | 9 | def csv_to_json(csv_path, json_path): 10 | json_array = [] 11 | 12 | # read csv file 13 | with open(csv_path, encoding='utf-8') as csvf: 14 | # load csv file data using csv library's dictionary reader 15 | csvReader = csv.DictReader(csvf) 16 | 17 | # convert each csv row into python dict 18 | for row in csvReader: 19 | # add this python dict to json array 20 | json_array.append(row) 21 | 22 | # convert python jsonArray to JSON String and write to file 23 | with open(json_path, 'w', encoding='utf-8') as jsonf: 24 | json_str = json.dumps(json_array, indent=4) 25 | jsonf.write(json_str) 26 | 27 | 28 | def main(): 29 | if len(sys.argv) != 3: 30 | print("Usage: csv2json.py ") 31 | sys.exit(1) 32 | 33 | csv_file_path = sys.argv[1] 34 | json_file_path = sys.argv[2] 35 | 36 | start = time.perf_counter() 37 | csv_to_json(csv_file_path, json_file_path) 38 | finish = time.perf_counter() 39 | 40 | # print to stderr 41 | print(f"Conversion 100.000 rows completed successfully in {finish - start:0.4f} seconds", file=sys.stderr) 42 | 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /local/bin/viscosity-to-ios-connect.rb: -------------------------------------------------------------------------------- 1 | # from: https://gist.github.com/iMerica/dfb1be6e2f664c716756 2 | Dir.glob("#{ENV['HOME']}/Library/Application Support/Viscosity/OpenVPN/*/config.conf").each do |file| 3 | certificate_files = ['ca', 'cert', 'key', 'tls-auth'] 4 | config_dir = File.dirname(file) 5 | connection_name = nil 6 | new_config = [] 7 | 8 | File.read(file).lines.each do |line| 9 | line.strip! 10 | 11 | if line.start_with?('#viscosity name') 12 | connection_name = line.match(/^#viscosity name (.*)/)[1] 13 | next 14 | end 15 | 16 | next if line.start_with?('#') 17 | (key, value) = line.split(/\s+/, 2) 18 | 19 | if certificate_files.include?(key) 20 | # Special case for tls-auth which is "key direction" 21 | if key == 'tls-auth' 22 | # add direction to config 23 | (value, direction) = value.split(/\s+/) 24 | new_config << "key-direction #{direction}" unless direction.nil? 25 | end 26 | 27 | certificate = File.read("#{config_dir}/#{value}") 28 | new_config << "<#{key}>" 29 | new_config << certificate 30 | new_config << "" 31 | next 32 | end 33 | new_config << line 34 | end 35 | raise "Unable to find connection name in #{file}. Aborting." if connection_name.nil? 36 | new_config.unshift("# OpenVPN Config for #{connection_name}") 37 | out_file = "#{connection_name}.ovpn" 38 | File.open(out_file, 'w') { |f| f.write(new_config.join("\n") + "\n") } 39 | puts "wrote #{out_file}" 40 | end 41 | -------------------------------------------------------------------------------- /local/bin/tree2fulltree: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # coding=utf-8 3 | """ 4 | convert `tree` command output to file path output 5 | """ 6 | 7 | from __future__ import unicode_literals, absolute_import, print_function 8 | 9 | import fileinput 10 | import re 11 | import urllib 12 | import sys 13 | 14 | REGEX_MATCH = r'([\| ]? )*[\||``]-- \[.+]\ (.+)' 15 | 16 | 17 | def main(): 18 | last_level = 0 19 | parents = [] 20 | last_name = None 21 | endpoint = None 22 | 23 | for line in fileinput.input(): 24 | line = line.decode('utf-8') 25 | if endpoint is None: 26 | endpoint = line.strip() 27 | 28 | match = re.match(REGEX_MATCH, line) 29 | if not match: 30 | continue 31 | if len(match.groups()) != 2: 32 | continue 33 | 34 | level = len((match.groups()[0] or '')) / 4 35 | name = match.groups()[1] 36 | if level > last_level: 37 | parents.append(last_name) 38 | elif level < last_level: 39 | parents.pop() 40 | 41 | output = endpoint + '/' + '/'.join(parents + [name]) + '\n' 42 | output += ' => ' + endpoint + '/' + '/'.join( 43 | [urllib.quote(x.encode('gbk')) for x in parents + [name]]) + '\n' 44 | print(output.encode('utf-8'), end='') 45 | 46 | last_name = name 47 | last_level = level 48 | sys.stdout.flush() 49 | 50 | 51 | if __name__ == '__main__': 52 | try: 53 | main() 54 | except IOError: 55 | pass 56 | 57 | # vim: set ft=python: 58 | -------------------------------------------------------------------------------- /mac/phoenix/src/mouse.ts: -------------------------------------------------------------------------------- 1 | import * as config from './config'; 2 | import {heartbeatWindow} from './window'; 3 | 4 | export function saveMousePositionForWindow(window: Window) { 5 | if (!window) { 6 | return; 7 | } 8 | heartbeatWindow(window); 9 | const pos = Mouse.location() 10 | // pos.y = 800 - pos.y; // fix phoenix 2.x bug 11 | config.MOUSE_POSITIONS[window.hash()] = pos; 12 | } 13 | 14 | export function setMousePositionForWindowCenter(window: Window | undefined) { 15 | if (window === undefined) { 16 | return; 17 | } 18 | Mouse.move({ 19 | x: window.topLeft().x + window.frame().width / 2, 20 | y: window.topLeft().y + window.frame().height / 2, 21 | }); 22 | heartbeatWindow(window); 23 | } 24 | 25 | export function restoreMousePositionForWindow(window: Window | undefined) { 26 | if (window === undefined) { 27 | return; 28 | } 29 | if (!config.MOUSE_POSITIONS[window.hash()]) { 30 | setMousePositionForWindowCenter(window); 31 | return; 32 | } 33 | const pos = config.MOUSE_POSITIONS[window.hash()]; 34 | const rect = window.frame(); 35 | if (pos.x < rect.x || pos.x > (rect.x + rect.width) || pos.y < rect.y || pos.y > (rect.y + rect.height)) { 36 | setMousePositionForWindowCenter(window); 37 | return; 38 | } 39 | // Phoenix.log(String.format('x: {0}, y: {1}', pos.x, pos.y)); 40 | Mouse.move(pos); 41 | heartbeatWindow(window); 42 | } 43 | 44 | export function restoreMousePositionForNow() { 45 | const window = Window.focused(); 46 | if (window === undefined) { 47 | return; 48 | } 49 | restoreMousePositionForWindow(window); 50 | } 51 | -------------------------------------------------------------------------------- /.zshrc.etc.d/hosts-on-off.zshrc: -------------------------------------------------------------------------------- 1 | # hosts-on-off can managed your hosts files 2 | # Feature: one click / groups / managed by zshrc.etc.d 3 | # 4 | # Required: hostess: 5 | # brew install hostess 6 | # sudo chown root /usr/local/Cellar/hostess/*/bin/hostess 7 | # sudo chmod +s /usr/local/Cellar/hostess/*/bin/hostess 8 | 9 | # Usage: 10 | # put the following into ~/.zshrc.etc.d/hosts-sample.zshrc and `source ~/.zshrc.etc.d/hosts-sample.zshrc` 11 | # 12 | # test_com_hosts=" 13 | # 127.0.0.1 a.test.com 14 | # 127.0.0.1 b.test.com 15 | # " 16 | # alias hosts-on-test="hosts-on test_com_hosts" 17 | # alias hosts-off-test="hosts-off test_com_hosts" 18 | 19 | function hosts-on { 20 | hosts="$1" 21 | if [ -z ${hosts} ]; then 22 | print "error read \$hosts" 23 | return 24 | fi 25 | hosts_content=$(printf '%s\n' "${(P)$(echo "$hosts")}") 26 | 27 | while read -r line; do 28 | ip=$(echo ${line} | awk '{print $1}') 29 | domain=$(echo ${line} | awk '{print $2}') 30 | if [ -z ${ip} ] || [ -z ${domain} ]; then 31 | continue 32 | fi 33 | 34 | # chmod-root-s-hostess first 35 | hostess add ${domain} ${ip} 36 | done <<< "${hosts_content}" 37 | } 38 | 39 | 40 | function hosts-off { 41 | hosts="$1" 42 | if [ -z ${hosts} ]; then 43 | print "error read \$hosts" 44 | return 45 | fi 46 | hosts_content=$(printf '%s\n' "${(P)$(echo "$hosts")}") 47 | 48 | while read -r line; do 49 | ip=$(echo ${line} | awk '{print $1}') 50 | domain=$(echo ${line} | awk '{print $2}') 51 | if [ -z ${ip} ] || [ -z ${domain} ]; then 52 | continue 53 | fi 54 | 55 | # chmod-root-s-hostess first 56 | hostess rm ${domain}; 57 | done <<< "${hosts_content}" 58 | } 59 | -------------------------------------------------------------------------------- /local/bin/paste-rtf-to-md: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | 5 | $DIR/paste-rtf-to-html | 6 | perl -0777pe 's/class="[a-zA-Z0-9:;\. \s\(\)\-\,]*"//g' | 7 | pandoc -f html --wrap none -t "markdown+pipe_tables-simple_tables-multiline_tables-raw_html-link_attributes+lists_without_preceding_blankline" | 8 | gsed -E '/^
$/d' | 9 | gsed -E '/^<\/div>$/d' | 10 | perl -0777pe 's/-
\n\n /-/g' | 11 | gsed -E '/^ <\/div>$/d' | 12 | gsed -E '/[ \s]*:::[ \s]*$/d' | 13 | gsed -E '/[ \s]*:::[ \s]* \{.+\}$/d' | 14 | perl -0777pe 's/[ \s]+$//g' | 15 | gsed -E '/^$/N;/^\n$/D' | 16 | gsed -E '/^\[\[\[\]\]\]$/d' | 17 | perl -0777pe 's/^\\$//g' | 18 | gsed -E 's/^ $//g' | 19 | gsed -E 's/^\\$//g' | 20 | perl -0777pe 's/{[^}]+}//g' | 21 | gsed -E 's/^- - - -/ -/g' | 22 | gsed -E 's/^- - -/ -/g' | 23 | gsed -E 's/^- -/ -/g' | 24 | gsed -E 's/^- -/ -/g' | 25 | perl -0777pe 's/\n\n\n\n( *-)/\n\1/g' 26 | 27 | # for yuque ul li merge 28 | # | gsed -E 's/^- - - -/ -/g' \ 29 | # | gsed -E 's/^- - -/ -/g' \ 30 | # | gsed -E 's/^- -/ -/g' \ 31 | # | gsed -E 's/^- -/ -/g' \ 32 | # | perl -0777pe 's/\n\n\n\n( *-)/\n\1/g' 33 | 34 | # vim: set ft=sh: 35 | -------------------------------------------------------------------------------- /mac/phoenix/src/config.ts: -------------------------------------------------------------------------------- 1 | const MASH: Phoenix.ModifierKey[] = ['alt']; 2 | const MASH_CTRL: Phoenix.ModifierKey[] = ['alt', 'ctrl']; 3 | const MASH_SHIFT: Phoenix.ModifierKey[] = ['alt', 'shift']; 4 | const MASH_CTRL_SHIFT: Phoenix.ModifierKey[] = ['alt', 'ctrl', 'shift']; 5 | const MOUSE_POSITIONS: { [name: number]: Point } = {}; 6 | const HIDE_INACTIVE_WINDOW_TIME = 10; // minitus 7 | const ACTIVE_WINDOWS_TIMES: { [name: number]: number } = {}; 8 | const DEFAULT_WIDTH = 1280; 9 | const WORK_SPACE_INDEX_MAP: { [name: number]: number } = { 10 | 1: 0, // one display case 11 | 2: 3, // two display case 12 | }; // is a dict, key is display count, val is work space 13 | const SECOND_WORK_SPACE_INDEX_MAP: { [name: number]: number } = { 14 | 1: 0, // one display case 15 | 2: 0, // two display case 16 | }; // is a dict, key is display count, val is work space 17 | const PARK_SPACE_INDEX_MAP: { [name: number]: number } = { 18 | 1: 2, 19 | 2: 2, 20 | }; 21 | const PARK_SPACE_APP_INDEX_MAP: { [name: string]: number } = { 22 | iTerm: 0, 23 | 'Google Chrome': 0, 24 | Chromium: 0, 25 | Firefox: 0, 26 | QQ: 1, 27 | Dingtalk: 1, 28 | WeChat: 2, 29 | 'Electronic WeChat': 2, 30 | Mail: 2, 31 | Airmail: 2, 32 | }; 33 | const A_BIG_PIXEL = 10000; 34 | // TODO MAC_SCREEN_IN_THE_RIGHT to DISPLAYS_ORDER 35 | const MAC_SCREEN_IN_THE_RIGHT = true; 36 | const DISPLAYS_ORDER = {} 37 | // const MAC_SCREEN_IN_THE_RIGHT = false; 38 | const RESIZE_WITH_RATIO = false; 39 | 40 | export { 41 | MAC_SCREEN_IN_THE_RIGHT, 42 | MASH, 43 | MASH_CTRL, 44 | MASH_SHIFT, 45 | MASH_CTRL_SHIFT, 46 | MOUSE_POSITIONS, 47 | HIDE_INACTIVE_WINDOW_TIME, 48 | ACTIVE_WINDOWS_TIMES, 49 | DEFAULT_WIDTH, 50 | WORK_SPACE_INDEX_MAP, 51 | SECOND_WORK_SPACE_INDEX_MAP, 52 | PARK_SPACE_APP_INDEX_MAP, 53 | A_BIG_PIXEL, 54 | RESIZE_WITH_RATIO 55 | }; 56 | -------------------------------------------------------------------------------- /.pentadactylrc: -------------------------------------------------------------------------------- 1 | "let mapleader = "," 2 | 3 | "map 4 | "map 5 | "map 6 | "map 7 | "imap 8 | "imap 9 | "imap 10 | "imap 11 | 12 | "map j 13 | "map k 14 | "map J 15 | "map K 16 | "map -builtin j 10j 17 | "map -builtin k 10k 18 | noremap j 5j 19 | noremap k 5k 20 | map w 21 | map e 22 | map W 23 | map E 24 | map h gT 25 | map l gt 26 | map s :stop 27 | cmap 28 | cmap 29 | 30 | map da :tabopen about:addons 31 | map dp :dialog preferences 32 | map dd :downloads 33 | map ds :dialog pagesource 34 | map dc :dialog console 35 | map di :dialog pageinfo 36 | 37 | " use b for bookmarks 38 | map b :bmarks 39 | 40 | "干掉一些快捷键 41 | " map 42 | " map 43 | 44 | " set titlestring=Mozilla\ Firefox 45 | 46 | "命令行下拉菜单最多显示的条目数 47 | "set maxitems=6 48 | 49 | "Next Page and Previous Page超级的下一页,基本上是够用了.快捷键是[[和]] 50 | set nextpattern=\s*下一页|下一张|下一篇|下页|后页\s*,^\bnext\b,\\bnext\\b,^>$,^(>>|»)$,^(>|»),(>|»)$,\\bmore\\b 51 | set previouspattern=\s*上一页|上一张|上一篇|上页|前页\s*,^\bprev|previous\b,\\bprev|previous\\b,^<$,^(<<|«)$,^(<|«),(<|«)$ 52 | 53 | set hintmatching=custom 54 | hi -a Hint font-size: 18pt !important; 55 | "set hintkeys=asdfg;lkjh 56 | 57 | "surround com and net可以直接先输入网站名,再用+快捷输入.com/.net 58 | "cnoremap .orgwww. 59 | " cnoremap .com 60 | 61 | set editor='/usr/local/bin/mvim -f + +"sil! call cursor(0, )" ' 62 | "set yankencodedurl=true 63 | 64 | " ignorekeys add https://www.toodledo.com/tasks/index.php 65 | " ignorekeys add http://www.toodledo.com/tasks/index.php 66 | " ignorekeys add https://mail.google.com/ 67 | 68 | " vim: set ft=vim: 69 | -------------------------------------------------------------------------------- /.zshrc.etc.d/clean-cache.zshrc: -------------------------------------------------------------------------------- 1 | if [[ "$OSTYPE" == "darwin"* ]]; then 2 | alias clean-homebrew='du -sh $HOME/Library/Caches/Homebrew/; find $HOME/Library/Caches/Homebrew/ -maxdepth 1 -mindepth 1 -exec trash {} \; ; brew cleanup -s' 3 | alias clean-coursier='find $HOME/Library/Caches/Coursier/v1/http -maxdepth 1 -mindepth 1 -exec trash {} \; ; find $HOME/Library/Caches/Coursier/v1/https -maxdepth 1 -mindepth 1 -exec trash {} \;' 4 | alias clean-pip='find $HOME/Library/Caches/pip/http -maxdepth 1 -mindepth 1 -exec trash {} \;' 5 | alias clean-yarn='find $HOME/Library/Caches/Yarn -maxdepth 1 -mindepth 1 -exec trash {} \;' 6 | alias clean-docker-machne='docker-machine rm default' 7 | alias clean-minikube='minikube delete && rm -rf $HOME/.minikube/cache' 8 | alias clean-npm-cacache='du -sh $HOME/.npm/_cacache; trash $HOME/.npm/_cacache' 9 | alias clean-pnpm='du -sh $HOME/Library/pnpm; trash $HOME/Library/pnpm' 10 | alias clean-sbt-boot='du -sh $HOME/.sbt/boot; trash $HOME/.sbt/boot' 11 | alias clean-npm-tarball='du -sh $HOME/.npminstall_tarball; trash $HOME/.npminstall_tarball' 12 | alias clean-dev-go-pkg-mod='du -sh $HOME/dev/go/pkg/mod; trash $HOME/dev/go/pkg/mod' 13 | alias clean-dev-node-modules='gfind $HOME/dev -maxdepth 2 -name node_modules -exec trash {} \;' 14 | alias clean-dev-venv='gfind $HOME/dev -maxdepth 2 -name .venv -exec trash {} \;' 15 | alias clean-ws-go-pkg-mod='du -sh $HOME/ws/go/pkg/mod; trash $HOME/ws/go/pkg/mod' 16 | alias clean-ws-node-modules='gfind $HOME/ws -maxdepth 2 -name node_modules -exec trash {} \;' 17 | alias clean-ws-venv='gfind $HOME/ws -maxdepth 2 -name .venv -exec trash {} \;' 18 | alias clean-m2='du -sh $HOME/.m2/repository; trash $HOME/.m2/repository' 19 | alias clean-lima='du -sh $HOME/Library/Caches/lima; trash $HOME/Library/Caches/lima' 20 | alias clean-netease-music-cache='du -sh $HOME/Library/Caches/com.netease.163music/; trash $HOME/Library/Caches/com.netease.163music/' 21 | fi 22 | -------------------------------------------------------------------------------- /.vimperatorrc: -------------------------------------------------------------------------------- 1 | let mapleader = "," 2 | 3 | "noremap 4 | "noremap 5 | "noremap 6 | "noremap 7 | "noremap 8 | "inoremap 9 | "inoremap 10 | "inoremap 11 | "inoremap 12 | 13 | "noremap j 4j 14 | "noremap k 4k 15 | noremap x d 16 | noremap d 17 | noremap j 5j 18 | noremap k 5k 19 | noremap J 20 | noremap K 21 | noremap w 22 | noremap e 23 | noremap W 24 | noremap E 25 | noremap h gT 26 | noremap l gt 27 | noremap s :stop 28 | noremap 29 | 30 | noremap da :tabopen about:addons 31 | noremap dp :dialog preferences 32 | noremap dd :downloads 33 | noremap ds :dialog pagesource 34 | noremap dc :dialog console 35 | noremap di :dialog pageinfo 36 | 37 | " use b for bookmarks 38 | noremap b :bmarks 39 | 40 | map S :source ~/.vimperatorrc:echo 'rc reloaded!' 41 | 42 | "map 43 | " map 44 | 45 | " set titlestring=Mozilla\ Firefox 46 | 47 | "命令行下拉菜单最多显示的条目数 48 | "set maxitems=6 49 | 50 | "Next Page and Previous Page超级的下一页,基本上是够用了.快捷键是[[和]] 51 | set nextpattern=\s*下一页|下一张|下一篇|下页|后页\s*,^\bnext\b,\\bnext\\b,^>$,^(>>|»)$,^(>|»),(>|»)$,\\bmore\\b 52 | set previouspattern=\s*上一页|上一张|上一篇|上页|前页\s*,^\bprev|previous\b,\\bprev|previous\\b,^<$,^(<<|«)$,^(<|«),(<|«)$ 53 | 54 | "set gui=nonavigation 55 | 56 | "surround com and net可以直接先输入网站名,再用+快捷输入.com/.net 57 | "cnoremap .orgwww. 58 | cnoremap .com 59 | 60 | set 'editor=/usr/local/bin/mvim -f' 61 | set yankencodedurl=true 62 | 63 | " ignorekeys add https://www.toodledo.com/tasks/index.php 64 | " ignorekeys add http://www.toodledo.com/tasks/index.php 65 | " ignorekeys add https://mail.google.com/ 66 | 67 | " vim: set ft=vim: 68 | -------------------------------------------------------------------------------- /.obsidian.vimrc: -------------------------------------------------------------------------------- 1 | " vimrc for obsidian 2 | " plugin: https://github.com/esm7/obsidian-vimrc-support 3 | " remember link this file to you vault dir 4 | 5 | 6 | " # obcommand doc https://meleu.dev/notes/obcommand-list/ 7 | " 8 | " nmap j gj 9 | " nmap k gk 10 | " I like using H and L for beginning/end of line 11 | " nmap H ^ 12 | " nmap L $ 13 | " Quickly remove search highlights 14 | " nmap :nohl 15 | 16 | " Yank to system clipboard 17 | " set clipboard=unnamed 18 | 19 | " Go back and forward with Ctrl+O and Ctrl+I 20 | " (make sure to remove default Obsidian shortcuts for these to work) 21 | " exmap back obcommand app:go-back 22 | " nmap :back 23 | " exmap forward obcommand app:go-forward 24 | " nmap :forward 25 | 26 | 27 | " Emulate Folding https://vimhelp.org/fold.txt.html#fold-commands 28 | exmap togglefold obcommand editor:toggle-fold 29 | nmap zo :togglefold 30 | nmap zc :togglefold 31 | nmap za :togglefold 32 | 33 | exmap unfoldall obcommand editor:unfold-all 34 | nmap zR :unfoldall 35 | 36 | exmap foldall obcommand editor:fold-all 37 | nmap zM :foldall 38 | 39 | " tab navigate 40 | exmap tabnext obcommand workspace:next-tab 41 | nmap gt :tabnext 42 | exmap tabprevious obcommand workspace:previous-tab 43 | nmap gT :tabprevious 44 | 45 | nmap gT 46 | nmap gt 47 | 48 | " tab group management 49 | exmap focusRight obcommand editor:focus-right 50 | nmap l :focusRight 51 | 52 | exmap focusLeft obcommand editor:focus-left 53 | nmap h :focusLeft 54 | 55 | exmap focusTop obcommand editor:focus-top 56 | nmap k :focusTop 57 | nmap :focusTop 58 | 59 | exmap focusBottom obcommand editor:focus-bottom 60 | nmap j :focusBottom 61 | nmap :focusBottom 62 | 63 | exmap splitVertical obcommand workspace:split-vertical 64 | nmap v :splitVertical 65 | 66 | exmap splitHorizontal obcommand workspace:split-horizontal 67 | nmap s :splitHorizontal 68 | -------------------------------------------------------------------------------- /.cvimrc: -------------------------------------------------------------------------------- 1 | " let configpath = '/Users/alswl/.cvimrc' 2 | " set localconfig 3 | 4 | let mapleader = "," 5 | 6 | set noautofocus " The opposite of autofocus; this setting stops 7 | 8 | map h gT 9 | map l gt 10 | map s gq 11 | 12 | iunmap 13 | iunmap 14 | iunmap 15 | iunmap 16 | iunmap 17 | iunmap 18 | iunmap 19 | iunmap 20 | iunmap 21 | iunmap 22 | iunmap 23 | iunmap 24 | 25 | 26 | let searchengine t = "https://twitter.com/search/%s" 27 | let searchengine we = "http://en.wikipedia.org/wiki/Special:Search?search=%s" 28 | let searchengine zh = "http://www.zhihu.com/search?q=%s" 29 | let searchengine tb = "http://s.taobao.com/search?q=%s" 30 | let searchengine h = "http://dict.cn/search.php?q=%s" 31 | let searchengine k = "http://www.amazon.cn/s/ref=nb_sb_noss?__mk_zh_CN=%E4%BA%9A%E9%A9%AC%E9%80%8A%E7%BD%91%E7%AB%99&url=node%3D116169071&field-keywords=%s" 32 | let searchengine bing = "http://www.bing.com/search?q=%s&pc=MOZI" 33 | let searchengine etao = "http://s.etao.com/search?q=%s" 34 | let searchengine db = "http://www.douban.com/search?q=%s" 35 | let searchengine gh = "https://github.com/search?q=%s&ref=opensearch" 36 | let searchengine ip = "http://www.ip138.com/ips138.asp?ip=%s&action=2" 37 | let searchengine wb = "http://s.weibo.com/weibo/%s?topnav=1&wvr=6&b=1" 38 | let searchengine g = "https://www.google.com/#q=%s" 39 | let searchengine b = "https://www.baidu.com/s?wd=%s" 40 | let searchengine wc = "https://zh.wikipedia.org/w/index.php?title=Special:%E6%90%9C%E7%B4%A2&search=%s" 41 | let searchengine jd = "http://search.jd.com/Search?keyword=%s&enc=utf-8&wq=%s" 42 | let searchengine dk = "https://duckduckgo.com/?q=%s&atb=v17" 43 | let searchengine b = "http://www.baidu.com/#ie={inputEncoding}&wd=%s" 44 | let searchengine sogou = "http://www.sogou.com/web?ie={inputEncoding}&query=%s" 45 | let searchengine g = "https://www.google.com/search?q=%s" 46 | let searchengine google = "https://www.google.com/search?q=%s" 47 | 48 | 49 | -------------------------------------------------------------------------------- /.tmux.conf: -------------------------------------------------------------------------------- 1 | set-option -g default-shell "/opt/homebrew/bin/zsh" 2 | #set-option -g default-path $HOME 3 | set -g default-terminal "screen-256color" 4 | set-option -sa terminal-overrides ',screen-256color:RGB' 5 | 6 | unbind C-b 7 | set -g prefix C-q 8 | bind C-q send-prefix 9 | 10 | # start window index of 1 11 | #set-option -g base-index 1 12 | #setw -g pane-base-index 1 13 | 14 | # active window title colors 15 | set -g window-status-current-format "#[fg=white,bg=red] #I:#W* " 16 | 17 | set-window-option -g mode-keys vi 18 | bind-key -T copy-mode-vi v send -X begin-selection 19 | # bind-key -T copy-mode-vi y send -X copy-selection-and-cancel 20 | # after 2025-03 21 | bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy" 22 | # TODO 23 | # run-shell "bash ~/.tmux_darwin.sh" 24 | # run-shell "bash ~/.tmux_linux.sh" 25 | 26 | 27 | # -n means no prefix 28 | bind -n F11 previous-window 29 | bind -n F12 next-window 30 | 31 | bind-key -r j select-pane -D 32 | bind-key -r k select-pane -U 33 | bind-key -r h select-pane -L 34 | bind-key -r l select-pane -R 35 | 36 | #set-option -g status-justify "centre" 37 | 38 | set-option -g status-left-length 60 39 | set-option -g status-right-length 90 40 | set-option -g set-titles on 41 | 42 | set-option -g history-limit 10000 43 | 44 | # active window title colors 45 | #set-window-option -g window-status-current-fg colour166 #orange 46 | #set-window-option -g window-status-current-bg default 47 | #set-window-option -g window-status-current-attr bright 48 | 49 | set -g status-right '#(hostname)' 50 | 51 | set-option -sg escape-time 10 52 | 53 | # pbcopy / pbpaste mac, https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard 54 | # not need for Tmux 2.6+, https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard/issues/66 55 | # set-option -g default-command "reattach-to-user-namespace -l zsh" 56 | # set-window-option -g mode-keys vi 57 | # bind-key -T copy-mode-vi v send -X begin-selection 58 | # bind-key -T copy-mode-vi y send -X copy-pipe "reattach-to-user-namespace pbcopy" 59 | # unbind -T copy-mode-vi Enter 60 | # bind-key -T copy-mode-vi Enter send -X copy-pipe "reattach-to-user-namespace pbcopy" 61 | 62 | # required by neovim 63 | set-option -g focus-events on 64 | -------------------------------------------------------------------------------- /local/bin/remark: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # render markdown file with remark https://github.com/gnab/remark 4 | 5 | if [ $(uname) = 'Darwin' ]; then 6 | SED_BIN="gsed" 7 | elif [ $(uname -s) = 'Linux' ] || [ $(uname -o) = 'Cygwin' ]; then 8 | SED_BIN="sed" 9 | fi 10 | 11 | FILE_NAME=$1 12 | 13 | if [ ! -f $FILE_NAME ]; then 14 | echo "warnning: $FILE_NAME not exist!" 15 | echo '' 16 | echo 'Usage:' 17 | echo 'remark example.md' 18 | exit 0 19 | fi 20 | 21 | OUTPUT_FILE_NAME=$FILE_NAME.remark.generated.html 22 | 23 | check_command_installed() { 24 | NAME=$1 25 | BREW_NAME=$2 26 | if ! [ -x "$(command -v $NAME)" ]; then 27 | echo "Error: Required GNU $NAME, try \`brew install $BREW_NAME\`" 28 | exit 1 29 | fi 30 | } 31 | 32 | if [ $(uname) = 'Darwin' ]; then 33 | check_command_installed gsed gnu-sed 34 | fi 35 | 36 | cat >$OUTPUT_FILE_NAME < 38 | 39 | 40 | $FILE_NAME 41 | 42 | 52 | 53 | 54 | 63 | 64 | 65 | 66 | 67 | 73 | 74 | 75 | EOF 76 | 77 | echo "Generate $OUTPUT_FILE_NAME successful." 78 | 79 | #vim: set expandtab: 80 | -------------------------------------------------------------------------------- /local/bin/speedfox: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Alex Alexander (wired) 3 | # http://www.linuxized.com 4 | # 5 | # this script makes sure your .mozilla folder is in tmpfs and constantly syncs it 6 | # with a folder on your hdd so you won't lose anything :) 7 | # for more details on how it works visit my blog in the link above. 8 | # 9 | # for this to have any meaning, the MOZTMPFS folder must be on tmpfs 10 | # i.e. to make /var/tmp a tmpfs folder, add the following in /etc/fstab 11 | # tmpfs /var/tmp tmpfs size=768M,mode=0777 0 0 12 | # 13 | # don't forget to mount the first time! 14 | 15 | # your ram mozilla folder 16 | MOZTMPFS=/dev/shm/$(whoami)_mozilla 17 | # your original mozilla folder - i recommend: mv ~/.mozilla ~/.mozilla-hdd 18 | MOZHDD="${HOME}/.mozilla-hdd" 19 | # your ~/.mozilla 20 | MOZHOME="${HOME}/.mozilla" 21 | # seconds interval for rsync 22 | INTERVAL=60 23 | 24 | # lets make sure MOZHDD exists before we do anything naughty 25 | if [ ! -d "${MOZHDD}" ]; then 26 | echo "ERROR" 27 | echo "${MOZHDD} doesn't exist." 28 | echo "we won't do anything until you cp/mv your ${MOZHOME} folder there." 29 | echo "try: mv ${MOZHOME} ${MOZHDD}" 30 | exit 31 | fi 32 | 33 | # check for and create tmp folder 34 | if [ ! -d "${MOZTMPFS}" ]; then 35 | mkdir -p ${MOZTMPFS} 36 | fi 37 | 38 | # check for ~/.mozilla 39 | # if it exists and is a directory die 40 | if [ -e "${MOZHOME}" ] && [ ! -L "${MOZHOME}" ]; then 41 | echo "ERROR" 42 | echo "${MOZHOME} should not exist or should be a link" 43 | echo "aborting to avoid permanent damage" 44 | echo "backup and/or delete ${MOZHOME} and try again" 45 | exit 46 | else 47 | if [ ! -e "${MOZHOME}" ]; then 48 | ln -s "${MOZTMPFS}" "${MOZHOME}" 49 | fi 50 | fi 51 | 52 | # sync to tmpfs 53 | echo "syching ${MOZHDD} to ${MOZTMPFS}" 54 | rsync -avi --delete "${MOZHDD}/" "${MOZTMPFS}/" 55 | 56 | echo "executing reverse sync every ${INTERVAL} seconds" 57 | (while true; do 58 | sleep ${INTERVAL} 59 | rsync -avi --delete "${MOZTMPFS}/" "${MOZHDD}/" 60 | done) & 61 | SYNC=$! 62 | 63 | echo "launching firefox" 64 | firefox 65 | 66 | echo "firefox closed, kill auto sync and reverse sync one last time" 67 | echo "please wait..." 68 | kill $! 69 | rsync -avi --delete "${MOZTMPFS}/" "${MOZHDD}/" 70 | echo "all done, removing ${MOZHOME} link for safety reasons =]" 71 | rm ${MOZHOME} 72 | -------------------------------------------------------------------------------- /linux/.config/conky/conky.conf: -------------------------------------------------------------------------------- 1 | conky.config = { 2 | use_xft= true, 3 | xftalpha= .1, 4 | update_interval= 1, 5 | total_run_times= 0, 6 | 7 | background= true, 8 | 9 | own_window= true, 10 | own_window_type= 'desktop', 11 | own_window_transparent= true, 12 | own_window_hints= 'undecorated,below,sticky,skip_taskbar,skip_pager', 13 | own_window_colour= '000000', 14 | own_window_argb_visual= true, 15 | own_window_argb_value= 0, 16 | 17 | double_buffer= true, 18 | 19 | minimum_width= 270, 20 | maximum_width= 270, 21 | 22 | minimum_height= 10, 23 | 24 | draw_shades= false, 25 | draw_outline= false, 26 | draw_borders= false, 27 | draw_graph_borders= false, 28 | 29 | default_color= 'FFFFFF', 30 | default_shade_color= '333333', 31 | default_outline_color= 'black', 32 | color1 = 'A9A9A9', 33 | color3 = '616161', 34 | 35 | alignment= 'top_right', 36 | gap_x= 56, 37 | gap_y= 0, 38 | no_buffers= true, 39 | text_buffer_size = 2048, 40 | uppercase= false, 41 | cpu_avg_samples= 4, 42 | net_avg_samples = 2, 43 | override_utf8_locale= true, 44 | 45 | font= 'Ubuntu:style=medium:size=16' 46 | } 47 | 48 | conky.text = [[ 49 | 50 | ${color1} 51 | ${voffset 20} 52 | ${alignr}${font Ubuntu:style=Medium:pixelsize=50}${time %H:%M}${font} 53 | ${voffset 10} 54 | ${alignr}${font Ubuntu:style=Medium:pixelsize=13}${time %A %d %B %Y}${font} 55 | 56 | ${voffset 20} 57 | ${font FontAwesome}${font} ${alignr}${addrs enp2s0} 58 | ${hr} 59 | ${font FontAwesome}${font} ${alignr}${exec curl ipinfo.io/ip} 60 | 61 | ${font FontAwesome}${font} disques ${alignr}${hddtemp /dev/sda}°.${hddtemp /dev/sdb}°.${hddtemp /dev/sdc}° 62 | #.${hddtemp /dev/sdd}°.${hddtemp /dev/sde}°.${hddtemp /dev/sdf}°. 63 | ${hr} 64 | ${font FontAwesome}${font} cpu ${alignr}${hwmon 0 temp 1}°.${hwmon 0 temp 2}°.${hwmon 0 temp 3}° 65 | ${font FontAwesome}${font} ventilo ${alignr}${hwmon 0 fan 1} tour/min 66 | ${color3}${cpugraph cpu1 50,133 5e7b7b d8deeb -t} ${cpugraph cpu2 50,133 5e7b7b d8deeb -t} 67 | ${cpugraph cpu3 50,133 5e7b7b d8deeb -t} ${cpugraph cpu4 50,133 5e7b7b d8deeb -t} 68 | 69 | ${color3}${downspeedgraph enp3s0 50,269 5e7b7b d8deeb} 70 | ${color1}${font FontAwesome}${font} download ${alignr}${downspeedf enp3s0}k/s (${totaldown enp3s0}) 71 | ${hr} 72 | ${font FontAwesome}${font} upload ${alignr}${upspeedf enp3s0}k/s (${totalup enp3s0}) 73 | ${color3}${upspeedgraph enp3s0 50,269 99c8e8 618094} 74 | 75 | ]] 76 | -------------------------------------------------------------------------------- /_.gitconfig: -------------------------------------------------------------------------------- 1 | [user] 2 | email = 3 | name = 4 | [color] 5 | diff = auto 6 | ui = true 7 | status = auto 8 | diff = auto 9 | branch = auto 10 | [diff] 11 | #external = git_diff_wrapper 12 | # tool = vimdiff 13 | tool = nvimdiff 14 | [difftool] 15 | prompt = false 16 | [pager] 17 | diff = 18 | branch = false 19 | [alias] 20 | s = status 21 | c = commit -av 22 | b = branch 23 | br = branch 24 | brm = branch --merged 25 | fl = flow 26 | f = fetch --all -p 27 | sv = svn 28 | svf = svn fetch 29 | svnf = svn fetch 30 | lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit 31 | lgd = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit 32 | lgf = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --first-parent 33 | ll = log --stat --abbrev-commit 34 | lol = log --oneline --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cs) %C(bold blue)<%an>%Creset' --abbrev-commit 35 | st = status 36 | sta = stash 37 | pl = pull 38 | ps = push 39 | df = diff 40 | dt = difftool 41 | #dr = diff --no-ext-diff 42 | dn = diff --name-only 43 | ci = commit 44 | civ = commit -v 45 | co = checkout 46 | cor = checkoutr 47 | spl = svn rebase 48 | sps = svn dcommit 49 | rs = reset 50 | checkoutr = checkout 51 | local-ignore = update-index --assume-unchanged 52 | local-unignore = update-index --no-assume-unchanged 53 | local-ignored = !git ls-files -v | grep "^[[:lower:]]" 54 | [merge] 55 | tool = vimdiff 56 | [push] 57 | default = simple 58 | [pull] 59 | rebase = false 60 | [core] 61 | excludesfile = ~/.gitignore_global 62 | precomposeUnicode = true 63 | quotePath = false 64 | [difftool "sourcetree"] 65 | cmd = opendiff \"$LOCAL\" \"$REMOTE\" 66 | path = 67 | [difftool "nvimdiff"] 68 | cmd = "nvim -d \"$LOCAL\" \"$REMOTE\"" 69 | [mergetool "sourcetree"] 70 | cmd = /Applications/Sourcetree.app/Contents/Resources/opendiff-w.sh \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$MERGED\" 71 | trustExitCode = true 72 | [color "diff-highlight"] 73 | oldNormal = red bold 74 | oldHighlight = red bold 52 75 | newNormal = green bold 76 | newHighlight = green bold 22 77 | [color "diff"] 78 | meta = yellow 79 | frag = magenta bold 80 | commit = yellow bold 81 | old = red bold 82 | new = green bold 83 | whitespace = red reverse 84 | [init] 85 | defaultBranch = master 86 | [url "git@github.com:"] 87 | insteadOf = https://github.com/ 88 | [url "git@gitlab.com:"] 89 | insteadOf = https://gitlab.com/ 90 | [gitflow "branch"] 91 | develop = develop 92 | -------------------------------------------------------------------------------- /.zshrc.etc.d/project.zshrc: -------------------------------------------------------------------------------- 1 | alias init-project='now=$(date "+%Y-%m-%d %H:%M:%S"); 2 | mkdir configuration diagram document md scripts; 3 | cd md; 4 | echo "---\ntitle: Overview\n\ndate: ${now}\n\n---\n">> 0.overview.md; 5 | echo "---\ntitle: Project-manage\n\ndate: ${now}\n\n---\n">> 0.project-manage.md; 6 | echo "---\ntitle: Project-manage-for-me\n\ndate: ${now}\n\n---\n">> 0.project-manage-for-me.md; 7 | echo "---\ntitle: Announcement\n\ndate: ${now}\n\n---\n">> 0.announcement.md; 8 | echo "---\ntitle: Meetings\n\ndate: ${now}\n\n---\n">> 0.meetings.md; 9 | echo "---\ntitle: Resource\n\ndate: ${now}\n\n---\n">> 0.resource.md; 10 | echo "---\ntitle: Background\n\ndate: ${now}\n\n---\n">> 1.background.md; 11 | echo "---\ntitle: Requirement\n\ndate: ${now}\n\n---\n">> 1.requirement.md; 12 | echo "---\ntitle: Design\n\ndate: ${now}\n\n---\n">> 2.design.md; 13 | echo "---\ntitle: Design-for-me-x\n\ndate: ${now}\n\n---\n">> 2.design-for-me-x.md; 14 | echo "---\ntitle: Dev\n\ndate: ${now}\n\n---\n">> 3.dev.md; 15 | echo "---\ntitle: Dev-for-me-x\n\ndate: ${now}\n\n---\n">> 3.dev-for-me-x.md; 16 | echo "---\ntitle: Test\n\ndate: ${now}\n\n---\n">> 4.test.md; 17 | echo "---\ntitle: QA\n\ndate: ${now}\n\n---\n">> 5.qa.md; 18 | echo "---\ntitle: QA-issue-x\n\ndate: ${now}\n\n---\n">> 5.qa-issue-x.md; 19 | echo "---\ntitle: Deploy\n\ndate: ${now}\n\n---\n">> 6.deploy.md; 20 | echo "---\ntitle: Project-review\n\ndate: ${now}\n\n---\n">> 9.project-review.md; 21 | echo "---\ntitle: Inbox\n\ndate: ${now}\n\n---\n">> 9.inbox.md; 22 | cd ..; 23 | echo -e "*.generated.*\n*.svg\n*.png\n.output\ndocument\nconfiguration/*.key\nfiles\n" >> .gitignore; 24 | git init; 25 | git add .; 26 | git commit -m "init"; ' 27 | 28 | alias init-project-brief='now=$(date "+%Y-%m-%d %H:%M:%S"); 29 | mkdir configuration diagram document md scripts; 30 | cd md; 31 | echo "---\ntitle: Overview\n\ndate: ${now}\n\n---\n">> 0.overview.md; 32 | echo "---\ntitle: Project-manage\n\ndate: ${now}\n\n---\n">> 0.project-manage.md; 33 | echo "---\ntitle: Meetings\n\ndate: ${now}\n\n---\n">> 0.meetings.md; 34 | echo "---\ntitle: Background\n\ndate: ${now}\n\n---\n">> 1.background.md; 35 | echo "---\ntitle: Design\n\ndate: ${now}\n\n---\n">> 2.design.md; 36 | echo "---\ntitle: Dev\n\ndate: ${now}\n\n---\n">> 3.dev.md; 37 | echo "---\ntitle: Test\n\ndate: ${now}\n\n---\n">> 4.test.md; 38 | echo "---\ntitle: QA\n\ndate: ${now}\n\n---\n">> 5.qa.md; 39 | echo "---\ntitle: Deploy\n\ndate: ${now}\n\n---\n">> 6.deploy.md; 40 | echo "---\ntitle: Inbox\n\ndate: ${now}\n\n---\n">> 9.inbox.md; 41 | cd ..; 42 | echo -e "*.generated.*\n*.svg\n*.png\n.output\ndocument\nconfiguration/*.key\nfiles\n" >> .gitignore; 43 | git init; 44 | git add .; 45 | git commit -m "init"; ' 46 | -------------------------------------------------------------------------------- /local/bin/check-brew-cask-upgrade: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # set -x 4 | set -e 5 | 6 | HOMEBREW_PREFIX="$(brew config | grep HOMEBREW_PREFIX | awk '{print $2}')" 7 | # fix for Intel chips and Arm chips 8 | HOMEBREW_LIBRARY="${HOMEBREW_PREFIX}/Library" 9 | if [ $HOMEBREW_PREFIX == '/usr/local' ]; then 10 | HOMEBREW_LIBRARY="${HOMEBREW_PREFIX}/Homebrew/Library" 11 | fi 12 | 13 | check_command_installed() { 14 | NAME=$1 15 | BREW_NAME=$2 16 | if ! [ -x "$(command -v $NAME)" ]; then 17 | echo "Error: Required GNU $NAME, try \`brew install $BREW_NAME\`" 18 | exit 1 19 | fi 20 | } 21 | 22 | get_version_by_info() { 23 | local __cask=$1 24 | local __info=$(brew info --cask $__cask) 25 | local __latest=$(echo $__info | head -n 1 | gsed 's/^==>//g' | awk '{print $2}') 26 | echo $__latest 27 | } 28 | 29 | get_first_letter() { 30 | local __input=$1 31 | echo ${__input:0:1} 32 | } 33 | 34 | gen_path() { 35 | local __cask=$1 36 | local __sharding=$2 37 | local __font=$3 38 | 39 | if [ $__font == "true" ]; then 40 | letter="font/font-"$(get_first_letter $__cask) 41 | echo $HOMEBREW_LIBRARY/Taps/*/*/Casks/$letter/$__cask.rb 42 | else 43 | if [ $__sharding == "true" ]; then 44 | letter=$(get_first_letter $__cask) 45 | echo $HOMEBREW_LIBRARY/Taps/*/*/Casks/$letter/$__cask.rb 46 | else 47 | echo $HOMEBREW_LIBRARY/Taps/*/*/Casks/$__cask.rb 48 | fi 49 | fi 50 | } 51 | 52 | get_versions_by_cat() { 53 | local __cask=$1 54 | local __sharding=$2 55 | local __font=$3 56 | p=$(gen_path $__cask $__sharding $__font) 57 | local __latest=$(cat $p | ggrep -Po 'version "\K[^"]+' | sort -r --version-sort) 58 | echo $__latest 59 | } 60 | 61 | if [ $(uname) = 'Darwin' ]; then 62 | check_command_installed ggrep grep 63 | fi 64 | 65 | for cask in $(ls $HOMEBREW_PREFIX/Caskroom); do 66 | if [ -L $HOMEBREW_PREFIX/Caskroom/$cask ]; then 67 | continue 68 | fi 69 | 70 | sharding=false 71 | font=false 72 | # if cask start with font- 73 | if [[ $cask == font-* ]]; then 74 | # echo ">>> Font $cask" 75 | font=true 76 | fi 77 | if [ ! -f $HOMEBREW_LIBRARY/Taps/*/*/Casks/$cask.rb ]; then 78 | sharding=true 79 | fi 80 | p=$(gen_path $cask $sharding $font) 81 | if [ ! -f $p ]; then 82 | # echo ">>> $cask not found in $p" 83 | continue 84 | fi 85 | # echo $cask " sharding is " $sharding 86 | latest="$(get_versions_by_cat $cask $sharding $font)" 87 | lines="$(echo "$latest" | gsed "s/ /\n/g" | wc -l | awk '{print $1}')" 88 | # echo $lines 89 | if [ "$lines" -gt 1 ]; then 90 | # echo ">>> Multi $cask" 91 | latest="$(get_version_by_info $cask)" 92 | fi 93 | # echo ">>>> $latest" 94 | 95 | if [ ! -d "$HOMEBREW_PREFIX/Caskroom/$cask/$latest" ]; then 96 | echo "$cask latest: $latest, nothing in $HOMEBREW_PREFIX/Caskroom/$cask/$latest" 97 | fi 98 | done 99 | -------------------------------------------------------------------------------- /local/bin/gh-md-toc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Steps: 5 | # 6 | # 1. Download coresponding html file for some README.md: 7 | # curl -s $1 8 | # 9 | # 2. Discard rows where no substring 'user-content-' (github's markup): 10 | # awk '/user-content-/ { ... 11 | # 12 | # 3. Get header level and insert corresponding number of spaces before '*': 13 | # sprintf("%*s", substr($NF, length($NF)-1, 1)*2, " ") 14 | # 15 | # 4. Find head's text and insert it inside "* [ ... ]": 16 | # substr($0, match($0, /a>.*<\/h/)+2, RLENGTH-5) 17 | # 18 | # 5. Find anchor and insert it inside "(...)": 19 | # substr($4, 7) 20 | # 21 | 22 | gh_toc_version="0.2.1" 23 | 24 | # 25 | # Download rendered into html README.md by it's url. 26 | # 27 | # 28 | gh_toc_load() { 29 | local gh_url=$1 30 | local gh_user_agent=$2 31 | 32 | if type curl &>/dev/null; then 33 | curl --user-agent "$gh_user_agent" -s "$gh_url" 34 | elif type wget &>/dev/null; then 35 | wget --user-agent="$gh_user_agent" -qO- "$gh_url" 36 | else 37 | echo "Please, install 'curl' or 'wget' and try again." 38 | exit 1 39 | fi 40 | } 41 | 42 | # 43 | # TOC generator 44 | # 45 | gh_toc() { 46 | local gh_url=$1 47 | local gh_user_agent=${2:-"gh-md-toc"} 48 | local gh_count=$3 49 | 50 | if [ "$gh_url" = "" ]; then 51 | echo "Please, enter URL for a README.md" 52 | exit 1 53 | fi 54 | 55 | if [ "$gh_count" = "1" ]; then 56 | 57 | echo "Table of Contents" 58 | echo "=================" 59 | echo "" 60 | 61 | gh_toc_load "$gh_url" "$gh_user_agent" | gh_toc_grab "" 62 | else 63 | gh_toc_load "$gh_url" "$gh_user_agent" | gh_toc_grab "$gh_url" 64 | fi 65 | } 66 | 67 | gh_toc_grab() { 68 | awk -v "gh_url=$1" '/user-content-/ { 69 | print sprintf("%*s", substr($NF, length($NF)-1, 1)*2, " ") "* [" substr($0, match($0, /a>.*<\/h/)+2, RLENGTH-5)"](" gh_url substr($4, 7, length($4)-7) ")"}' 70 | } 71 | 72 | # 73 | # Returns filename only from full path or url 74 | # 75 | gh_toc_get_filename() { 76 | echo "${1##*/}" 77 | } 78 | 79 | # 80 | # Options hendlers 81 | # 82 | gh_toc_app() { 83 | local app_name=${0/\.\//} 84 | 85 | if [ "$1" = '--help' ]; then 86 | echo "GitHub TOC generator ($app_name): $gh_toc_version" 87 | echo "" 88 | echo "Usage:" 89 | echo " $app_name Create TOC for passed url of a README file" 90 | echo " $app_name --help Show help" 91 | echo " $app_name --version Show help" 92 | return 93 | fi 94 | 95 | if [ "$1" = '--version' ]; then 96 | echo "$gh_toc_version" 97 | return 98 | fi 99 | 100 | for md in "$@"; do 101 | echo "" 102 | gh_toc "$md" "$app_name" "$#" 103 | done 104 | 105 | echo "" 106 | echo "Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)" 107 | } 108 | 109 | # 110 | # Entry point 111 | # 112 | gh_toc_app "$@" 113 | -------------------------------------------------------------------------------- /mac/phoenix/src/space.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import {restoreMousePositionForWindow} from './mouse'; 3 | import {getNextWindowsOnSameScreen, moveToScreen, sortedWindowsOnSameScreen} from './screen'; 4 | import {displayAllVisiableWindowModal, log} from './util'; 5 | 6 | // TODO refact 7 | export function moveWindowToTargetSpace(window: Window | undefined, nextWindow: Window | undefined, targetSpace: Space) { 8 | if (window === undefined) { 9 | return; 10 | } 11 | if (nextWindow === undefined) { 12 | return; 13 | } 14 | const currentSpaceOptional = Space.active(); 15 | if (currentSpaceOptional === undefined) { 16 | return; 17 | } 18 | const currentSpace = currentSpaceOptional; 19 | // _.map(targetSpace.windows(), (w) => { alert(w.title()); } ); 20 | if (currentSpace.screens()[0].hash() !== targetSpace.screens()[0].hash()) { 21 | moveToScreen(window, targetSpace.screens()[0]); 22 | } 23 | currentSpace.removeWindows([window]); 24 | targetSpace.addWindows([window]); 25 | if (nextWindow) { 26 | // App.get('Finder').focus(); // Hack for Screen unfocus 27 | // nextWindow.raise(); 28 | nextWindow.focus(); 29 | restoreMousePositionForWindow(nextWindow); 30 | } 31 | } 32 | 33 | export function moveWindowToSpace(window: Window | undefined, targetSpaceFn: (space: Space) => Space | null, direction: number) { 34 | if (window === undefined) { 35 | return; 36 | } 37 | if (window.isFullScreen() || window.isMinimized()) { 38 | return; 39 | } 40 | const currentOptional: Space | undefined = Space.active(); 41 | if (currentOptional === undefined) { 42 | log("moveWindowToSpace no currentSpace"); 43 | return; 44 | } 45 | log("a"); 46 | const current = currentOptional; 47 | const allSpaces: Space[] = Space.all(); 48 | const targetSpaceOptinal = targetSpaceFn(current); 49 | if (targetSpaceOptinal === null) { 50 | log("moveWindowToSpace no targetSpaceOptinal"); 51 | return; 52 | } 53 | const target = targetSpaceOptinal; 54 | if (target.isFullScreen()) { 55 | return; 56 | } 57 | if (target.screens().length === 0) { 58 | return; 59 | } 60 | if (target.screens()[0].hash() !== current.screens()[0].hash()) { 61 | log("moveWindowToSpace, target equlas current"); 62 | return; 63 | } 64 | const targetIndex = _.indexOf(_.map(allSpaces, (x) => x.hash()), target.hash()); 65 | const currentIndex = _.indexOf(_.map(allSpaces, (x) => x.hash()), current.hash()); 66 | if ((direction > 0 && targetIndex <= currentIndex) || (direction < 0 && targetIndex >= currentIndex)) { 67 | log("moveWindowToSpace, space execeed"); 68 | return; 69 | } 70 | current.removeWindows([window]); 71 | target.addWindows([window]); 72 | const prevWindowOptional = getNextWindowsOnSameScreen(window, sortedWindowsOnSameScreen(window)); 73 | if (prevWindowOptional === undefined) { 74 | return; 75 | } 76 | 77 | if (prevWindowOptional != null) { 78 | prevWindowOptional.focus(); 79 | } 80 | displayAllVisiableWindowModal(current.windows(), prevWindowOptional, null); 81 | } 82 | -------------------------------------------------------------------------------- /local/etc/Blank.css: -------------------------------------------------------------------------------- 1 | h1, 2 | h2, 3 | h3, 4 | h4, 5 | h5, 6 | h6, 7 | p, 8 | blockquote { 9 | margin: 0; 10 | padding: 0; 11 | } 12 | body { 13 | font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif; 14 | font-size: 14px; 15 | line-height: 18px; 16 | background-color: white; 17 | margin: 10px 14px 10px 14px; 18 | } 19 | table { 20 | margin: 10px 0 15px 0; 21 | border-collapse: collapse; 22 | } 23 | td,th { 24 | border: 1px solid #ddd; 25 | padding: 3px 10px; 26 | } 27 | th { 28 | padding: 5px 10px; 29 | } 30 | 31 | a { 32 | color: #0069d6; 33 | } 34 | a:hover { 35 | color: #0050a3; 36 | text-decoration: none; 37 | } 38 | a img { 39 | border: none; 40 | } 41 | p { 42 | margin-bottom: 9px; 43 | } 44 | h1, 45 | h2, 46 | h3, 47 | h4, 48 | h5, 49 | h6 { 50 | color: #404040; 51 | line-height: 36px; 52 | } 53 | h1 { 54 | margin-bottom: 18px; 55 | font-size: 30px; 56 | } 57 | h2 { 58 | font-size: 24px; 59 | margin-bottom: 18px; 60 | } 61 | h3 { 62 | font-size: 18px; 63 | margin-bottom: 18px; 64 | } 65 | h4 { 66 | font-size: 16px; 67 | margin-bottom: 18px; 68 | } 69 | h5 { 70 | font-size: 14px; 71 | margin-bottom: 18px; 72 | } 73 | h6 { 74 | font-size: 14px; 75 | margin-bottom: 18px; 76 | } 77 | hr { 78 | margin: 0 0 19px; 79 | border: 0; 80 | border-bottom: 1px solid #ccc; 81 | } 82 | blockquote { 83 | padding: 14px 14px 21px 15px; 84 | margin-bottom: 18px; 85 | font-family:georgia,serif; 86 | color:#666; 87 | /*font-style: italic;*/ 88 | } 89 | blockquote:before { 90 | content:"\201C"; 91 | font-size:40px; 92 | margin-left:-10px; 93 | font-family:georgia,serif; 94 | color:#eee; 95 | } 96 | blockquote p { 97 | font-size: 14px; 98 | font-weight: 300; 99 | line-height: 18px; 100 | margin-bottom: 0; 101 | /*font-style: italic;*/ 102 | } 103 | code, pre { 104 | font-family: Monaco, Andale Mono, Courier New, monospace; 105 | } 106 | code { 107 | background-color: #fee9cc; 108 | color: rgba(0, 0, 0, 0.75); 109 | padding: 1px 3px; 110 | font-size: 12px; 111 | -webkit-border-radius: 3px; 112 | -moz-border-radius: 3px; 113 | border-radius: 3px; 114 | } 115 | pre { 116 | display: block; 117 | padding: 14px; 118 | margin: 0 0 18px; 119 | line-height: 16px; 120 | font-size: 11px; 121 | border: 1px solid #d9d9d9; 122 | white-space: pre-wrap; 123 | word-wrap: break-word; 124 | } 125 | pre code { 126 | background-color: #fff; 127 | font-size: 11px; 128 | padding: 0; 129 | } 130 | sup { 131 | font-size: 0.83em; 132 | vertical-align: super; 133 | line-height: 0; 134 | } 135 | strong { 136 | color: red; 137 | } 138 | img { 139 | max-width: 100%; 140 | } 141 | * { 142 | -webkit-print-color-adjust: exact; 143 | } 144 | @media screen and (min-width: 914px) { 145 | body { 146 | width: 854px; 147 | margin:10px auto; 148 | } 149 | } 150 | @media print { 151 | body,code,pre code,h1,h2,h3,h4,h5,h6 { 152 | color: black; 153 | } 154 | table, pre { 155 | page-break-inside: avoid; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /local/bin/scel2mmseg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # download from https://github.com/archerhu/scel2mmseg/blob/master/scel2mmseg.py 4 | 5 | import struct 6 | import os, sys, glob 7 | 8 | 9 | def read_utf16_str(f, offset=-1, len=2): 10 | if offset >= 0: 11 | f.seek(offset) 12 | str = f.read(len) 13 | return str.decode('UTF-16LE') 14 | 15 | 16 | def read_uint16(f): 17 | return struct.unpack(' iTerm 26 | - mod + \` => iTerm 27 | - mod + 1 => Browser (Microsoft Edge) 28 | - mod + 2 => Browser (Safari) 29 | - mod + 3 => IM (Dingtalk or Wchat) 30 | - mod + 4 => IM (Wechat of Browser) 31 | - mod + 8 => Music (Apple Music) 32 | - mod + 9 => Music (Netease Music 33 | - mod + e => Preview 34 | - mod + r => Meeting 35 | - mod + a => Editor (VimR) 36 | - mod + s => Editor (IntelliJ IDEA) 37 | - mod + d => Editor (Visual Studio Code) 38 | - mod + f => Editor (Clion) 39 | - mod + x => Editor (GoLand) 40 | - mod + z => Editor (Obsidian) 41 | - mod + , => Editor (Yuque) 42 | - mod + . => Editor (Quiver or Motion) 43 | - mod + / => Finder 44 | - Screen 45 | - mod + l => Next screen 46 | - mod + h => Previous screen 47 | - mod + ctrl + o => Move current window to next screen 48 | - mod + ctrl + i => Move current window to previouse screen 49 | - Window 50 | - mod + shift + m => Toogle window maximize 51 | - mod + - => Window smaller 52 | - mod + = => Window larger 53 | - mod + m => Move window to screen centeral 54 | - mod + \\ => Window height max 55 | - mod + k => Next window of screen 56 | - mod + j => Previous window of screen 57 | - mod + ctrl + left => Move window left 58 | - mod + ctrl + right => Move window right 59 | - mod + ctrl + up => Move window up 60 | - mod + ctrl + down => Move window down 61 | - mod + option + left => Enlarge window to left 62 | - mod + option + right => Enlarge window to right 63 | - mod + option + up => Enlarge window to up 64 | - mod + option + down => Enlarge window to down 65 | - mod + ctrl + h => Move window to lef of screen 66 | - mod + ctrl + l => Move window to righ of screen 67 | - mod + ctrl + k => Move window to to of screen 68 | - mod + ctrl + j => Move window to bottom of screen 69 | - mod + shift + h => Move window to left, and resize half of screen 70 | - mod + shift + l => Move window to right, and resize half of screen 71 | - mod + shift + k => Move window to top, and resize half of screen 72 | - mod + shift + j => Move window to bottom, and resize half of screen 73 | - mod + shift + \\ => Window width max 74 | - mod + shift + , => Winow larger to left 75 | - mod + shift + . => Winow larger to right 76 | - mod + ctrl + \\ => Auto range windows 77 | - Mouse 78 | - mod + space => Move pointer to current window 79 | - Space 80 | - mod + shift + i => move window to previous space 81 | - mod + shift + o => move window to next space 82 | - mod + delete => move window to parking space 83 | - mod + ctrl + enter => move window to working space 84 | 85 | 86 | 87 | ## Build and install 88 | 89 | ``` 90 | npm install 91 | # cnpm install for Mainland China user 92 | npx webpack 93 | cp dist/phoenix.js $HOME/.phoenix.js 94 | ``` 95 | 96 | More details in [Windows management for hacker | Log4D](https://blog.alswl.com/2016/04/windows-management-for-hacker/) 97 | -------------------------------------------------------------------------------- /mac/.slate: -------------------------------------------------------------------------------- 1 | # This is the default .slate file. 2 | # If no ~/.slate file exists this is the file that will be used. 3 | 4 | config defaultToCurrentScreen true 5 | config nudgePercentOf screenSize 6 | config resizePercentOf screenSize 7 | 8 | # Alias 9 | alias mouse_left shell path:~/ '/usr/local/bin/cliclick m:640,400 && /Users/alswl/dev/myproject/.oOo./local/bin/mouse_restore.sh' 10 | alias mouse_right shell path:~/ '/usr/local/bin/cliclick m:1920,400 && /Users/alswl/dev/myproject/.oOo./local/bin/mouse_restore.sh' 11 | 12 | alias mouse_iTerm shell path:~/ '/Users/alswl/dev/myproject/.oOo./local/bin/mouse_restore.sh iTerm' 13 | alias mouse_Firefox shell path:~/ '/Users/alswl/dev/myproject/.oOo./local/bin/mouse_restore.sh Firefox' 14 | alias mouse_Google_Chrome shell path:~/ '/Users/alswl/dev/myproject/.oOo./local/bin/mouse_restore.sh Google_Chrome' 15 | alias mouse_QQ shell path:~/ '/Users/alswl/dev/myproject/.oOo./local/bin/mouse_restore.sh QQ' 16 | alias mouse_MacVim shell path:~/ '/Users/alswl/dev/myproject/.oOo./local/bin/mouse_restore.sh MacVim' 17 | alias mouse_Sparrow shell path:~/ '/Users/alswl/dev/myproject/.oOo./local/bin/mouse_restore.sh Sparrow' 18 | 19 | # Resize Bindings 20 | #bind right:alt resize +10% +0 21 | #bind left:alt resize -10% +0 22 | #bind up:alt resize +0 -10% 23 | #bind down:alt resize +0 +10% 24 | #bind right:ctrl;alt resize -10% +0 bottom-right 25 | #bind left:ctrl;alt resize +10% +0 bottom-right 26 | #bind up:ctrl;alt resize +0 +10% bottom-right 27 | #bind down:ctrl;alt resize +0 -10% bottom-right 28 | 29 | # Push Bindings 30 | #bind right:ctrl;cmd push right bar-resize:screenSizeX/3 31 | #bind left:ctrl;cmd push left bar-resize:screenSizeX/3 32 | #bind up:ctrl;cmd push up bar-resize:screenSizeY/2 33 | #bind down:ctrl;cmd push down bar-resize:screenSizeY/2 34 | 35 | # Nudge Bindings 36 | #bind right:shift;alt nudge +10% +0 37 | #bind left:shift;alt nudge -10% +0 38 | #bind up:shift;alt nudge +0 -10% 39 | #bind down:shift;alt nudge +0 +10% 40 | 41 | # Throw Bindings 42 | bind 1:ctrl;alt throw 0 resize 43 | bind 2:ctrl;alt throw 1 resize 44 | #bind 3:ctrl;alt throw 2 resize 45 | #bind right:ctrl;alt;cmd throw right resize 46 | #bind left:ctrl;alt;cmd throw left resize 47 | #bind up:ctrl;alt;cmd throw up resize 48 | #bind down:ctrl;alt;cmd throw down resize 49 | 50 | # Focus Bindings 51 | bind `:alt sequence ${mouse_iTerm} > focus 'iTerm' 52 | bind 1:alt sequence ${mouse_Firefox} > focus 'Firefox' 53 | bind 2:alt sequence ${mouse_Google_Chrome} > focus 'Google Chrome' 54 | bind 3:alt sequence ${mouse_QQ} > focus 'QQ' 55 | bind a:alt sequence ${mouse_MacVim} > focus 'MacVim' 56 | bind s:alt sequence ${mouse_Sparrow} > focus 'IntelliJ IDEA' 57 | bind h:alt sequence ${mouse_left} > focus left 58 | bind l:alt sequence ${mouse_right} > focus right 59 | #bind up:cmd focus up 60 | #bind down:cmd focus down 61 | bind k:alt focus behind 62 | bind j:alt focus behind 63 | 64 | # Move Bindings 65 | #bind h:alt;shift sequence ${mouse_left} > focus left > throw 0 resize 66 | #bind l:alt;shift sequence ${mouse_right} > focus right > throw 1 resize 67 | bind h:alt;shift sequence ${mouse_left} > focus left > throw 0 68 | bind l:alt;shift sequence ${mouse_right} > focus right > throw 1 69 | 70 | # Window Hints 71 | #bind esc:cmd hint 72 | 73 | # Toogle Application 74 | #bind `:alt toggle 'iTerm' 75 | 76 | #bind tab:cmd switch 77 | -------------------------------------------------------------------------------- /local/bin/generate_dash_index.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o 4 | set -x 5 | 6 | WHOAMI=$(whoami) 7 | FINAL_INDEX_PATH="$HOME/Documents/doc/index.html" 8 | TEMP_INDEX_PATH="$HOME/Documents/index.html.tmp" 9 | BODY_INDEX_PATH="$HOME/Documents/index.html.body" 10 | 11 | echo -n '' >"$TEMP_INDEX_PATH" 12 | 13 | ### general index.html 14 | #ls $HOME/Library/Application\ Support/Dash/DocSets/*/*/Contents/Resources/Documents/index.html | sed "s/\\/Users\\/$WHOAMI\\/Library\\/Application Support\\/Dash\\///g" >> "$TEMP_INDEX_PATH" 15 | ### general doc/index.html 16 | #ls $HOME/Library/Application\ Support/Dash/DocSets/*/*/Contents/Resources/Documents/doc/index.html | sed "s/\\/Users\\/$WHOAMI\\/Library\\/Application Support\\/Dash\\///g" >> "$TEMP_INDEX_PATH" 17 | ### general Documents/index.html 18 | #ls $HOME/Library/Application\ Support/Dash/User\ Contributed/*/*/Contents/Resources/Documents/index.html | sed "s/\\/Users\\/$WHOAMI\\/Library\\/Application Support\\/Dash\\///g" >> "$TEMP_INDEX_PATH" 19 | ### general Documents/configuration.html 20 | #ls $HOME/Library/Application\ Support/Dash/User\ Contributed/*/*/Contents/Resources/Documents/configuration.html | sed "s/\\/Users\\/$WHOAMI\\/Library\\/Application Support\\/Dash\\///g" >> "$TEMP_INDEX_PATH" 21 | #ls $HOME/Library/Application\ Support/Dash/Cheat\ Sheets/*/*/Contents/Resources/Documents/index.html | sed "s/\\/Users\\/$WHOAMI\\/Library\\/Application Support\\/Dash\\///g" >> "$TEMP_INDEX_PATH" 22 | ## dash 23 | #ls $HOME/Library/Application\ Support/Dash/Java\ DocSets/*/*/Contents/Resources/Documents/dash_javadoc/index.html | sed "s/\\/Users\\/$WHOAMI\\/Library\\/Application Support\\/Dash\\///g" >> "$TEMP_INDEX_PATH" 24 | 25 | mkdir -p /Users/$WHOAMI/Documents/doc/ 26 | rm -Rf /Users/$WHOAMI/Documents/doc/* 27 | 28 | pushd /Users/$WHOAMI/Documents/doc/ 29 | 30 | find $HOME/Library/Application\ Support/Dash/ -name 'tarix.tgz' -exec tar xzvf {} \; 31 | 32 | find $HOME/Library/Application\ Support/Dash/ -name 'Documents' | while read f; do 33 | docset=$(echo $f | grep -E -o '.*docset') 34 | cp -R "$docset" . 35 | done 36 | 37 | ls /Users/$WHOAMI/Documents/doc/*/Contents/Resources/Documents/index.html | sed "s/\\/Users\\/$WHOAMI\\/Documents\\/doc\\///g" >>"$TEMP_INDEX_PATH" 38 | ls /Users/$WHOAMI/Documents/doc/*/Contents/Resources/Documents/doc/index.html | sed "s/\\/Users\\/$WHOAMI\\/Documents\\/doc\\///g" >>"$TEMP_INDEX_PATH" 39 | # uwsgi 40 | ls /Users/$WHOAMI/Documents/doc/*/Contents/Resources/Documents/configuration.html | sed "s/\\/Users\\/$WHOAMI\\/Documents\\/doc\\///g" >>"$TEMP_INDEX_PATH" 41 | ## java 42 | ls /Users/$WHOAMI/Documents/doc/*/Contents/Resources/Documents/dash_javadoc/index.html | sed "s/\\/Users\\/$WHOAMI\\/Documents\\/doc\\///g" >>"$TEMP_INDEX_PATH" 43 | 44 | awk -F '/' '{printf("
  • %s
  • ", $0, $1);}' "$TEMP_INDEX_PATH" >"$BODY_INDEX_PATH" 45 | 46 | echo -n '' >"$FINAL_INDEX_PATH" 47 | echo '' >>"$FINAL_INDEX_PATH" 48 | echo '' >>"$FINAL_INDEX_PATH" 49 | echo '' >>"$FINAL_INDEX_PATH" 50 | echo '' >>"$FINAL_INDEX_PATH" 51 | echo '' >>"$FINAL_INDEX_PATH" 52 | echo '
    ' >>"$FINAL_INDEX_PATH" 53 | 54 | echo '
      ' >>"$FINAL_INDEX_PATH" 55 | cat "$BODY_INDEX_PATH" >>"$FINAL_INDEX_PATH" 56 | echo '
    ' >>"$FINAL_INDEX_PATH" 57 | 58 | echo '
    ' >>"$FINAL_INDEX_PATH" 59 | echo '' >>"$FINAL_INDEX_PATH" 60 | 61 | popd 62 | -------------------------------------------------------------------------------- /local/bin/mysql2sqlite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Converts a mysqldump file into a Sqlite 3 compatible file. It also extracts the MySQL `KEY xxxxx` from the 4 | # CREATE block and create them in separate commands _after_ all the INSERTs. 5 | 6 | # Awk is choosen because it's fast and portable. You can use gawk, original awk or even the lightning fast mawk. 7 | # The mysqldump file is traversed only once. 8 | 9 | # Usage: $ ./mysql2sqlite mysqldump-opts db-name | sqlite3 database.sqlite 10 | # Example: $ ./mysql2sqlite --no-data -u root -pMySecretPassWord myDbase | sqlite3 database.sqlite 11 | 12 | # Thanks to and @artemyk and @gkuenning for their nice tweaks. 13 | 14 | mysqldump --compatible=ansi --skip-extended-insert --compact "$@" | 15 | awk ' 16 | 17 | BEGIN { 18 | FS=",$" 19 | print "PRAGMA synchronous = OFF;" 20 | print "PRAGMA journal_mode = MEMORY;" 21 | print "BEGIN TRANSACTION;" 22 | } 23 | 24 | # CREATE TRIGGER statements have funny commenting. Remember we are in trigger. 25 | /^\/\*.*CREATE.*TRIGGER/ { 26 | gsub( /^.*TRIGGER/, "CREATE TRIGGER" ) 27 | print 28 | inTrigger = 1 29 | next 30 | } 31 | 32 | # The end of CREATE TRIGGER has a stray comment terminator 33 | /END \*\/;;/ { gsub( /\*\//, "" ); print; inTrigger = 0; next } 34 | 35 | # The rest of triggers just get passed through 36 | inTrigger != 0 { print; next } 37 | 38 | # Skip other comments 39 | /^\/\*/ { next } 40 | 41 | # Print all `INSERT` lines. The single quotes are protected by another single quote. 42 | /INSERT/ { 43 | gsub( /\\\047/, "\047\047" ) 44 | gsub(/\\n/, "\n") 45 | gsub(/\\r/, "\r") 46 | gsub(/\\"/, "\"") 47 | gsub(/\\\\/, "\\") 48 | gsub(/\\\032/, "\032") 49 | print 50 | next 51 | } 52 | 53 | # Print the `CREATE` line as is and capture the table name. 54 | /^CREATE/ { 55 | print 56 | if ( match( $0, /\"[^\"]+/ ) ) tableName = substr( $0, RSTART+1, RLENGTH-1 ) 57 | } 58 | 59 | # Replace `FULLTEXT KEY` or any other `XXXXX KEY` except PRIMARY by `KEY` 60 | /^ [^"]+KEY/ && !/^ PRIMARY KEY/ { gsub( /.+KEY/, " KEY" ) } 61 | 62 | # Get rid of field lengths in KEY lines 63 | / KEY/ { gsub(/\([0-9]+\)/, "") } 64 | 65 | # Print all fields definition lines except the `KEY` lines. 66 | /^ / && !/^( KEY|\);)/ { 67 | gsub( /AUTO_INCREMENT|auto_increment/, "" ) 68 | gsub( /(CHARACTER SET|character set) [^ ]+ /, "" ) 69 | gsub( /DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP|default current_timestamp on update current_timestamp/, "" ) 70 | gsub( /(COLLATE|collate) [^ ]+ /, "" ) 71 | gsub(/(ENUM|enum)[^)]+\)/, "text ") 72 | gsub(/(SET|set)\([^)]+\)/, "text ") 73 | gsub(/UNSIGNED|unsigned/, "") 74 | if (prev) print prev "," 75 | prev = $1 76 | } 77 | 78 | # `KEY` lines are extracted from the `CREATE` block and stored in array for later print 79 | # in a separate `CREATE KEY` command. The index name is prefixed by the table name to 80 | # avoid a sqlite error for duplicate index name. 81 | /^( KEY|\);)/ { 82 | if (prev) print prev 83 | prev="" 84 | if ($0 == ");"){ 85 | print 86 | } else { 87 | if ( match( $0, /\"[^"]+/ ) ) indexName = substr( $0, RSTART+1, RLENGTH-1 ) 88 | if ( match( $0, /\([^()]+/ ) ) indexKey = substr( $0, RSTART+1, RLENGTH-1 ) 89 | key[tableName]=key[tableName] "CREATE INDEX \"" tableName "_" indexName "\" ON \"" tableName "\" (" indexKey ");\n" 90 | } 91 | } 92 | 93 | # Print all `KEY` creation lines. 94 | END { 95 | for (table in key) printf key[table] 96 | print "END TRANSACTION;" 97 | } 98 | ' 99 | exit 0 100 | -------------------------------------------------------------------------------- /mac/phoenix/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "arrow-parens": false, 9 | "arrow-return-shorthand": true, 10 | "callable-types": true, 11 | "class-name": true, 12 | "comment-format": [ 13 | true, 14 | "check-space" 15 | ], 16 | "curly": true, 17 | "eofline": true, 18 | "forin": true, 19 | "import-spacing": true, 20 | "indent": [ 21 | false, 22 | "tabs" 23 | ], 24 | "interface-over-type-literal": true, 25 | "interface-name": [ 26 | true, 27 | "never-prefix" 28 | ], 29 | "label-position": true, 30 | "max-line-length": [ 31 | false, 32 | 120 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-arg": true, 47 | "no-bitwise": true, 48 | "no-console": [ 49 | true 50 | ], 51 | "no-construct": true, 52 | "no-debugger": true, 53 | "no-duplicate-super": true, 54 | "no-empty": false, 55 | "no-empty-interface": true, 56 | "no-eval": true, 57 | "no-inferrable-types": [ 58 | true, 59 | "ignore-params" 60 | ], 61 | "no-misused-new": true, 62 | "no-non-null-assertion": true, 63 | "no-shadowed-variable": true, 64 | "no-string-literal": true, 65 | "no-string-throw": true, 66 | "no-switch-case-fall-through": true, 67 | "no-trailing-whitespace": false, 68 | "no-unnecessary-initializer": true, 69 | "no-unused-expression": true, 70 | "no-use-before-declare": true, 71 | "no-var-keyword": true, 72 | "object-literal-sort-keys": false, 73 | "one-line": [ 74 | false 75 | ], 76 | "prefer-const": [ 77 | true, 78 | { 79 | "destructuring": "all" 80 | } 81 | ], 82 | "quotemark": [ 83 | false, 84 | "single" 85 | ], 86 | "radix": true, 87 | "semicolon": [ 88 | false, 89 | "always" 90 | ], 91 | "triple-equals": [ 92 | true, 93 | "allow-null-check" 94 | ], 95 | "typedef-whitespace": [ 96 | true, 97 | { 98 | "call-signature": "nospace", 99 | "index-signature": "nospace", 100 | "parameter": "nospace", 101 | "property-declaration": "nospace", 102 | "variable-declaration": "nospace" 103 | } 104 | ], 105 | "typeof-compare": true, 106 | "unified-signatures": true, 107 | "variable-name": false, 108 | "whitespace": [ 109 | false 110 | ], 111 | "ordered-imports": [ 112 | true, 113 | { 114 | "import-sources-order": "lowercase-last", 115 | "named-imports-order": "case-insensitive" 116 | } 117 | ], 118 | "no-internal-module": true, 119 | "no-unnecessary-type-assertion": true, 120 | "prefer-object-spread": true, 121 | "no-angle-bracket-type-assertion": true, 122 | "no-boolean-literal-compare": true, 123 | "no-irregular-whitespace": true, 124 | "no-unnecessary-qualifier": true, 125 | "object-literal-key-quotes": [ 126 | true, 127 | "as-needed" 128 | ], 129 | "object-literal-shorthand": true, 130 | "prefer-method-signature": true 131 | }, 132 | "rulesDirectory": [] 133 | } 134 | -------------------------------------------------------------------------------- /mac/phoenix/src/util.ts: -------------------------------------------------------------------------------- 1 | import * as _ from "lodash"; 2 | 3 | declare var console: any; 4 | 5 | export function log(...args: any[]): void { 6 | args = args.map(arg => stringify(arg)); 7 | Phoenix.log(...args); 8 | // tslint:disable-next-line:no-console 9 | console.trace(...args); 10 | } 11 | 12 | export function alert(message: string) { 13 | const modal = new Modal(); 14 | modal.text = message; 15 | modal.duration = 2; 16 | modal.show(); 17 | } 18 | 19 | export function alert_title(window: Window) { 20 | alert(window.title()); 21 | }; 22 | 23 | export function stringify(value: any) { 24 | if (value instanceof Error) { 25 | let stack = ''; 26 | if (value.stack) { 27 | const s = value.stack.trim().split('\n'); 28 | s[0] += ` (:${value.line}:${value.column})`; 29 | const indented = s.map(line => '\t at ' + line).join('\n'); 30 | stack = `\n${indented}`; 31 | } 32 | return `\n${value.toString()}${stack}`; 33 | } 34 | switch (typeof value) { 35 | case 'object': 36 | return '\n' + JSON.stringify(value, null, 2); 37 | case 'function': 38 | return value.toString(); 39 | default: 40 | return value; 41 | } 42 | } 43 | 44 | export function assert(condition: boolean, message: string) { 45 | if (!condition) { 46 | throw message || 'Assertion failed'; 47 | } 48 | } 49 | 50 | export function displayAllVisiableWindowModal(windows: Window[], windowOptional: Window | null, rectangleOptional: Rectangle | null) { 51 | const screenFrame = rectangleOptional || Screen.main().flippedFrame(); 52 | Modal.build({ 53 | appearance: 'dark', 54 | text: _.chain(windows) 55 | .map(x => windowOptional !== null && windowOptional.hash() === x.hash() ? '[[' + x.app().name() + ']]' : ' ' + x.app().name() + ' ') 56 | .join(' ') 57 | .value(), 58 | duration: 1, 59 | // animationDuration: 0, 60 | weight: 18, 61 | origin(frame) { 62 | return { 63 | x: screenFrame.x + (screenFrame.width / 2) - (frame.width / 2), 64 | y: ((-screenFrame.y) + (screenFrame.height / 2) + (frame.height / 2)), 65 | // y: screenFrame.y + screenFrame.height - (frame.height / 2), 66 | } 67 | }, 68 | }).show(); 69 | }; 70 | 71 | export function showTitleModal(text: string, duration: number = 1, icon?: Phoenix.Icon) { 72 | const modal = new Modal(); 73 | modal.text = text; 74 | modal.duration = duration; 75 | if (icon) { 76 | modal.icon = icon; 77 | } 78 | showAt(modal, Screen.main(), 2, 1 + 1 / 3); 79 | } 80 | 81 | function showAt( 82 | modal: Modal, 83 | screen: Screen, 84 | widthDiv: number, 85 | heightDiv: number, 86 | ) { 87 | const {height, width, x, y} = modal.frame(); 88 | const sf = screen.visibleFrame(); 89 | modal.origin = { 90 | x: sf.x + (sf.width / widthDiv - width / 2), 91 | y: sf.y + (sf.height / heightDiv - height / 2), 92 | }; 93 | modal.show(); 94 | } 95 | 96 | // doc https://github.com/kasper/phoenix/issues/180 97 | export function getEnv(name = '') { 98 | return new Promise((resolve, reject) => { 99 | if (name === '') { 100 | return reject('no variable name provided'); 101 | } 102 | 103 | Task.run('/bin/sh', ['-c', `echo "$${name}"`], (t) => { 104 | if (t.status === 0) { 105 | return resolve(t.output); 106 | } else { 107 | return reject(`could not execute command to fetch '$${name}'`); 108 | } 109 | }); 110 | }); 111 | } 112 | -------------------------------------------------------------------------------- /.ctags: -------------------------------------------------------------------------------- 1 | --langdef=markdown 2 | --langmap=markdown:.mkd 3 | --regex-markdown=/^#[ \t]+(.*)/\1/h,Heading_L1/ 4 | --regex-markdown=/^##[ \t]+(.*)/\1/i,Heading_L2/ 5 | --regex-markdown=/^###[ \t]+(.*)/\1/k,Heading_L3/ 6 | 7 | --langdef=ansible 8 | --langmap=ansible:.yml 9 | --regex-ansible=/^\s*- name:(.*)/\1/t,task/ 10 | 11 | --langdef=groovy 12 | --langmap=groovy:.groovy 13 | --regex-groovy=/^[ \t]*package[ \t]+([a-zA-Z0-9.-_]+)/\1/p,package/ 14 | --regex-groovy=/^[ \t]*(private|public)?[ \t]*(abstract|final|static)?[ \t]*class[ \t]+([A-Za-z0-9_]+)/\3/c,class/ 15 | --regex-groovy=/^[ \t]*(private|public)?[ \t]*interface[ \t]+([A-Za-z0-9_]+)/\2/i,interface/ 16 | --regex-groovy=/^[ \t]*(private|public)?[ \t]*trait[ \t]+([A-Za-z0-9_]+)/\2/t,trait/ 17 | --regex-groovy=/^[ \t]*(private|public)?[ \t]*enum[ \t]+([A-Za-z0-9_]+)/\2/e,enum/ 18 | --regex-groovy=/^[ \t]*[(abstract|final|static) \t]*((def|void|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+)?([a-zA-Z0-9_]+\(.*\))[ \t]+/~\3/m,package method/ 19 | --regex-groovy=/^[ \t]*public[ \t]+[(abstract|final|static) \t]*((def|void|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+)?([a-zA-Z0-9_]+\(.*\))[ \t]+/+\3/m,public method/ 20 | --regex-groovy=/^[ \t]*protected[ \t]+[(abstract|final|static) \t]*((def|void|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+)?([a-zA-Z0-9_]+\(.*\))[ \t]+/#\3/m,protected method/ 21 | --regex-groovy=/^[ \t]*private[ \t]+[(abstract|final|static) \t]*((def|void|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+)?([a-zA-Z0-9_]+\(.*\))[ \t]+/-\3/m,private method/ 22 | --regex-groovy=/^[ \t]*[(final|static|synchronized) \t]*(def|byte|int|short|long|float|double|boolean|char|[A-Z][A-Za-z0-9_]*)[ \t]+([a-zA-Z0-9_]+)([ \t]*[\/]+.*)?/~\2/f,property/ 23 | --regex-groovy=/^[ \t]*public[ \t]+[(final|static|synchronized) \t]*(def|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+([a-zA-Z0-9_]+)([ \t]*[\/]+.*)?/+\2/f,public field/ 24 | --regex-groovy=/^[ \t]*protected[ \t]+[(final|static|synchronized) \t]*(def|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+([a-zA-Z0-9_]+)([ \t]*[\/]+.*)?/#\2/f,protected field/ 25 | --regex-groovy=/^[ \t]*private[ \t]+[(final|static|synchronized) \t]*(def|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+([a-zA-Z0-9_]+)([ \t]*[\/]+.*)?/-\2/f,private field/ 26 | 27 | --langdef=scala 28 | --langmap=scala:.scala 29 | 30 | --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*class[ \t]+([a-zA-Z0-9_]+)/\4/c,classes/ 31 | --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*object[ \t]+([a-zA-Z0-9_]+)/\4/o,objects/ 32 | --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*((abstract|final|sealed|implicit|lazy)[ \t ]*)*case class[ \t ]+([a-zA-Z0-9_]+)/\6/C,case classes/ 33 | --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*case object[ \t]+([a-zA-Z0-9_]+)/\4/O,case objects/ 34 | --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*trait[ \t]+([a-zA-Z0-9_]+)/\4/t,traits/ 35 | --regex-scala=/^[ \t]*type[ \t]+([a-zA-Z0-9_]+)/\1/T,types/ 36 | --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*(\[[a-z]*\])*|protected)[ \t]*)*def[ \t]+([a-zA-Z0-9_]+)/\4/m,methods/ 37 | --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*|protected)[ \t]*)*val[ \t]+([a-zA-Z0-9_]+)/\3/V,values/ 38 | --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*|protected)[ \t]*)*var[ \t]+([a-zA-Z0-9_]+)/\3/v,variables/ 39 | --regex-scala=/^[ \t]*package[ \t]+([a-zA-Z0-9_.]+)/\1/p,packages/ 40 | -------------------------------------------------------------------------------- /.cvim.css: -------------------------------------------------------------------------------- 1 | #cVim-command-bar, #cVim-command-bar-mode, #cVim-command-bar-input, #cVim-command-bar-search-results, 2 | .cVim-completion-item, .cVim-completion-item .cVim-full, .cVim-completion-item .cVim-left, 3 | .cVim-completion-item .cVim-right { 4 | font-family: Helvetica, Helvetica Neue, Neue, sans-serif, monospace, Arial; 5 | font-size: 14pt !important; 6 | -webkit-font-smoothing: antialiased !important; 7 | } 8 | 9 | #cVim-command-bar { 10 | position: fixed; 11 | z-index: 2147483646; 12 | background-color: #1b1d1e; 13 | color: #bbb; 14 | display: none; 15 | box-sizing: content-box; 16 | box-shadow: 0 3px 3px rgba(0,0,0,0.4); 17 | left: 0; 18 | width: 100%; 19 | height: 24px; 20 | } 21 | 22 | #cVim-command-bar-mode { 23 | display: inline-block; 24 | vertical-align: middle; 25 | box-sizing: border-box; 26 | padding-left: 2px; 27 | height: 100%; 28 | width: 10px; 29 | padding-top: 2px; 30 | color: #888; 31 | } 32 | 33 | #cVim-command-bar-input { 34 | background-color: #1b1d1e; 35 | color: #bbb; 36 | height: 100%; 37 | right: 0; 38 | top: 0; 39 | width: calc(100% - 10px); 40 | position: absolute; 41 | } 42 | 43 | #cVim-command-bar-search-results { 44 | position: fixed; 45 | width: 100%; 46 | overflow: hidden; 47 | z-index: 2147483647; 48 | left: 0; 49 | box-shadow: 0 3px 3px rgba(0,0,0,0.4); 50 | background-color: #1c1c1c; 51 | } 52 | 53 | .cVim-completion-item, .cVim-completion-item .cVim-full, .cVim-completion-item .cVim-left, .cVim-completion-item .cVim-right { 54 | text-overflow: ellipsis; 55 | padding: 1px; 56 | display: inline-block; 57 | box-sizing: border-box; 58 | vertical-align: middle; 59 | overflow: hidden; 60 | white-space: nowrap; 61 | } 62 | 63 | .cVim-completion-item:nth-child(even) { 64 | background-color: #1f1f1f; 65 | } 66 | 67 | .cVim-completion-item { 68 | width: 100%; left: 0; 69 | color: #bcbcbc; 70 | } 71 | 72 | .cVim-completion-item[active] { 73 | width: 100%; left: 0; 74 | color: #1b1d1e; 75 | background-color: #f1f1f1; 76 | } 77 | 78 | .cVim-completion-item[active] span { 79 | color: #1b1d1e; 80 | } 81 | 82 | .cVim-completion-item .cVim-left { 83 | color: #fff; 84 | width: 37%; 85 | } 86 | 87 | .cVim-completion-item .cVim-right { 88 | font-style: italic; 89 | color: #888; 90 | width: 57%; 91 | } 92 | 93 | 94 | #cVim-link-container, .cVim-link-hint, 95 | #cVim-hud, #cVim-status-bar { 96 | font-family: Helvetica, Helvetica Neue, Neue, sans-serif, monospace, Arial; 97 | font-size: 10pt !important; 98 | -webkit-font-smoothing: antialiased !important; 99 | } 100 | 101 | #cVim-link-container { 102 | position: absolute; 103 | pointer-events: none; 104 | width: 100%; left: 0; 105 | height: 100%; top: 0; 106 | z-index: 2147483647; 107 | } 108 | 109 | .cVim-link-hint { 110 | position: absolute; 111 | color: #302505 !important; 112 | background-color: #ffd76e !important; 113 | border-radius: 2px !important; 114 | padding: 2px !important; 115 | font-size: 8pt !important; 116 | font-weight: 500 !important; 117 | text-transform: uppercase !important; 118 | border: 1px solid #ad810c; 119 | display: inline-block !important; 120 | vertical-align: middle !important; 121 | text-align: center !important; 122 | box-shadow: 2px 2px 1px rgba(0,0,0,0.25) !important; 123 | } 124 | 125 | .cVim-link-hint_match { 126 | color: #777; 127 | text-transform: uppercase !important; 128 | } 129 | 130 | 131 | #cVim-hud { 132 | background-color: lightgreen; 133 | position: fixed !important; 134 | transition: right 0.2s ease-out; 135 | z-index: 24724289; 136 | } 137 | 138 | #cVim-hud span { 139 | padding: 2px; 140 | padding-left: 4px; 141 | padding-right: 4px; 142 | color: #8f8f8f; 143 | font-size: 36pt; 144 | } 145 | 146 | #cVim-frames-outline { 147 | position: fixed; 148 | width: 100%; 149 | height: 100%; 150 | left: 0; 151 | top: 0; 152 | right: 0; 153 | z-index: 9999999999; 154 | box-sizing: border-box; 155 | border: 3px solid yellow; 156 | } 157 | -------------------------------------------------------------------------------- /local/bin/cdnjs-download.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import argparse 3 | import os 4 | from urllib.parse import urljoin 5 | 6 | def search_cdnjs_library(library_name): 7 | """ 8 | 搜索 CDNJS 上的库信息 9 | """ 10 | search_url = f"https://api.cdnjs.com/libraries?search={library_name}&fields=version,latest,fileType" 11 | try: 12 | response = requests.get(search_url) 13 | response.raise_for_status() 14 | data = response.json() 15 | return data 16 | except requests.exceptions.RequestException as e: 17 | print(f"搜索库时出错: {e}") 18 | return None 19 | 20 | def get_library_info(library_name): 21 | """ 22 | 获取指定库的详细信息 23 | """ 24 | api_url = f"https://api.cdnjs.com/libraries/{library_name}?fields=versions,assets" 25 | try: 26 | response = requests.get(api_url) 27 | response.raise_for_status() 28 | return response.json() 29 | except requests.exceptions.RequestException as e: 30 | print(f"获取库信息时出错: {e}") 31 | return None 32 | 33 | def download_file(url, local_filename): 34 | """ 35 | 下载文件到本地 36 | """ 37 | try: 38 | # 确保父目录存在 39 | os.makedirs(os.path.dirname(local_filename), exist_ok=True) 40 | 41 | with requests.get(url, stream=True) as response: 42 | response.raise_for_status() 43 | with open(local_filename, 'wb') as f: 44 | for chunk in response.iter_content(chunk_size=8192): 45 | if chunk: 46 | f.write(chunk) 47 | print(f"文件已下载: {local_filename}") 48 | return True 49 | except requests.exceptions.RequestException as e: 50 | print(f"下载文件时出错: {e}") 51 | return False 52 | 53 | def main(): 54 | parser = argparse.ArgumentParser(description='从CDNJS下载前端库') 55 | parser.add_argument('library', help='库名称 (如: jquery)') 56 | parser.add_argument('version', help='版本号 (如: 3.6.0)') 57 | parser.add_argument('-f', '--file', help='指定文件名 (默认下载所有文件)') 58 | parser.add_argument('-o', '--output', default='./', help='输出目录 (默认: 当前目录)') 59 | 60 | args = parser.parse_args() 61 | 62 | # 获取库信息 63 | library_info = get_library_info(args.library) 64 | if not library_info: 65 | print(f"找不到库: {args.library}") 66 | return 67 | 68 | # 检查版本是否存在 69 | if args.version not in library_info.get('versions', []): 70 | print(f"版本 {args.version} 不存在于库 {args.library} 中") 71 | print(f"可用版本: {', '.join(library_info.get('versions', []))}") 72 | return 73 | 74 | # 构建下载URL 75 | base_url = f"https://cdnjs.cloudflare.com/ajax/libs/{args.library}/{args.version}/" 76 | 77 | # 获取文件列表 78 | assets_url = f"https://api.cdnjs.com/libraries/{args.library}/{args.version}?fields=files" 79 | assets_response = requests.get(assets_url) 80 | 81 | if assets_response.status_code != 200: 82 | print(f"无法获取文件列表: {assets_response.status_code}") 83 | return 84 | 85 | files = assets_response.json().get('files', []) 86 | 87 | # 创建与CDNJS相同的目录结构: output/{library}/{version}/ 88 | cdnjs_path = os.path.join(args.output, args.library, args.version) 89 | os.makedirs(cdnjs_path, exist_ok=True) 90 | 91 | # 下载文件 92 | if args.file: 93 | # 下载指定文件 94 | if args.file in files: 95 | file_url = urljoin(base_url, args.file) 96 | local_path = os.path.join(cdnjs_path, args.file) 97 | download_file(file_url, local_path) 98 | else: 99 | print(f"文件 {args.file} 不存在于该版本中") 100 | print(f"可用文件: {', '.join(files)}") 101 | else: 102 | # 下载所有文件 103 | print(f"下载 {args.library}@{args.version} 的所有文件到 {cdnjs_path}") 104 | for file in files: 105 | file_url = urljoin(base_url, file) 106 | local_path = os.path.join(cdnjs_path, file) 107 | print(f"下载: {file}") 108 | download_file(file_url, local_path) 109 | 110 | if __name__ == "__main__": 111 | main() 112 | -------------------------------------------------------------------------------- /mac/_Library/Application Support/Karabiner/private.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Key Press Ins to Fn_Lock 20 | private.ins_to_fnlock 21 | __KeyToKey__ KeyCode::HELP, KeyCode::VK_LOCK_FN 22 | 23 | 24 | Key Press Application to Fn_Lock 25 | private.application_to_fnlock 26 | __KeyToKey__ KeyCode::PC_APPLICATION, KeyCode::VK_LOCK_FN 27 | 28 | 29 | Fn+[/;' to Arrow Keys(HHKB) 30 | private.remap.fn_hhkb_diamond_to_arrow_keys 31 | 32 | __KeyToKey__ 33 | KeyCode::BRACKET_LEFT, ModifierFlag::FN, 34 | KeyCode::CURSOR_UP 35 | 36 | 37 | __KeyToKey__ 38 | KeyCode::SLASH, ModifierFlag::FN, 39 | KeyCode::CURSOR_DOWN 40 | 41 | 42 | __KeyToKey__ 43 | KeyCode::SEMICOLON, ModifierFlag::FN, 44 | KeyCode::CURSOR_LEFT 45 | 46 | 47 | __KeyToKey__ 48 | KeyCode::QUOTE, ModifierFlag::FN, 49 | KeyCode::CURSOR_RIGHT 50 | 51 | 52 | 53 | Fn+EDSF to Arrow Keys 54 | private.remap.fn_edsf_diamond_to_arrow_keys 55 | 56 | __KeyToKey__ 57 | KeyCode::E, ModifierFlag::FN, 58 | KeyCode::CURSOR_UP 59 | 60 | 61 | __KeyToKey__ 62 | KeyCode::D, ModifierFlag::FN, 63 | KeyCode::CURSOR_DOWN 64 | 65 | 66 | __KeyToKey__ 67 | KeyCode::S, ModifierFlag::FN, 68 | KeyCode::CURSOR_LEFT 69 | 70 | 71 | __KeyToKey__ 72 | KeyCode::F, ModifierFlag::FN, 73 | KeyCode::CURSOR_RIGHT 74 | 75 | 76 | 77 | Fn+spacem,.jkluio to 0123456789 78 | private.remap.fn_space_m_j_k_l_u_i_o_to_number 79 | __KeyToKey__ KeyCode::SPACE, ModifierFlag::FN, KeyCode::KEYPAD_0 80 | __KeyToKey__ KeyCode::M, ModifierFlag::FN, KeyCode::KEYPAD_1 81 | __KeyToKey__ KeyCode::COMMA, ModifierFlag::FN, KeyCode::KEYPAD_2 82 | __KeyToKey__ KeyCode::DOT, ModifierFlag::FN, KeyCode::KEYPAD_3 83 | __KeyToKey__ KeyCode::J, ModifierFlag::FN, KeyCode::KEYPAD_4 84 | __KeyToKey__ KeyCode::K, ModifierFlag::FN, KeyCode::KEYPAD_5 85 | __KeyToKey__ KeyCode::L, ModifierFlag::FN, KeyCode::KEYPAD_6 86 | __KeyToKey__ KeyCode::U, ModifierFlag::FN, KeyCode::KEYPAD_7 87 | __KeyToKey__ KeyCode::I, ModifierFlag::FN, KeyCode::KEYPAD_8 88 | __KeyToKey__ KeyCode::O, ModifierFlag::FN, KeyCode::KEYPAD_9 89 | __KeyToKey__ KeyCode::N, ModifierFlag::FN, KeyCode::KEYPAD_DOT 90 | __KeyToKey__ KeyCode::DELETE, ModifierFlag::FN, KeyCode::DELETE 91 | __KeyToKey__ KeyCode::MINUS, ModifierFlag::FN, KeyCode::KEYPAD_MINUS 92 | __KeyToKey__ KeyCode::KEY_8, ModifierFlag::FN, KeyCode::KEYPAD_MULTIPLY 93 | __KeyToKey__ KeyCode::EQUAL, ModifierFlag::FN, KeyCode::KEYPAD_PLUS 94 | __KeyToKey__ KeyCode::B, ModifierFlag::FN, KeyCode::KEYPAD_SLASH 95 | 96 | 97 | -------------------------------------------------------------------------------- /local/bin/reveal: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # render markdown file with reveal https://github.com/hakimel/reveal.js#markdown 4 | 5 | if [ $(uname) = 'Darwin' ]; then 6 | SED_BIN="gsed" 7 | elif [ $(uname -s) = 'Linux' ] || [ $(uname -o) = 'Cygwin' ]; then 8 | SED_BIN="sed" 9 | fi 10 | 11 | FILE_NAME=$1 12 | 13 | if [ ! -f $FILE_NAME ]; then 14 | echo "warnning: $FILE_NAME not exist!" 15 | echo '' 16 | echo 'Usage:' 17 | echo 'reveal example.md' 18 | exit 0 19 | fi 20 | 21 | check_command_installed() { 22 | NAME=$1 23 | BREW_NAME=$2 24 | if ! [ -x "$(command -v $NAME)" ]; then 25 | echo "Error: Required GNU $NAME, try \`brew install $BREW_NAME\`" 26 | exit 1 27 | fi 28 | } 29 | 30 | OUTPUT_FILE_NAME=$FILE_NAME.reveal.generated.html 31 | 32 | if [ $(uname) = 'Darwin' ]; then 33 | check_command_installed gsed gnu-sed 34 | fi 35 | 36 | cat >$OUTPUT_FILE_NAME < 38 | 39 | 40 | 41 | 42 | 43 | reveal.js 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 57 | 58 | 59 | 66 | 67 | 68 |
    69 |
    70 | 71 | EOF 72 | 73 | cat >>$OUTPUT_FILE_NAME < 75 | 84 | 85 | EOF 86 | 87 | cat >>$OUTPUT_FILE_NAME < 89 |
    90 | 91 | 92 | 93 | 108 | 109 | 110 | 111 | EOF 112 | 113 | echo "Generate $OUTPUT_FILE_NAME successful." 114 | 115 | #vim: set expandtab: 116 | -------------------------------------------------------------------------------- /local/bin/svg2icns: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | ### from https://gist.github.com/plroebuck/af19a26c908838c7f9e363c571199deb 3 | ### 4 | ### svg2icns.bash 5 | ### Create ICNS file from SVG 6 | ### 7 | ### See also: 8 | ### 9 | ### 10 | ### 11 | 12 | script="$(basename $0 .bash)" 13 | 14 | : ${MAGICK_HOME?Requires ImageMagick to be installed} 15 | # CONVERT_BIN="${MAGICK_HOME}/bin/convert" 16 | CONVERT_BIN="convert" 17 | 18 | ## Usage function 19 | usage() { 20 | cat <&2 21 | Usage: ${script} [] 22 | svgfilename: input file in SVG format 23 | icnsfilename: output file in ICNS format (optional) 24 | 25 | END_USAGE 26 | } 27 | 28 | ## Call usage() function if args not supplied 29 | argc="$#" 30 | if [[ "$argc" -lt 1 ]] || [[ "$argc" -gt 2 ]]; then 31 | usage 32 | exit 1 33 | fi 34 | 35 | ## Verify first positional argument 36 | svgfilename="$1" 37 | if [ ! -f "${svgfilename}" ]; then 38 | usage 39 | echo "${script}: no such file: ${svgfilename}" >&2 40 | exit 1 41 | else 42 | echo -n '' 43 | # ## Verify scalable vector graphics file 44 | # $(file "${svgfilename}" | cut -d':' -f2- | grep -qs 'SVG') 45 | # if [ "$?" -ne 0 ]; 46 | # then 47 | # usage 48 | # echo "${script}: SVG file required: ${svgfilename}" >&2 49 | # exit 1 50 | # fi 51 | fi 52 | 53 | ## Verify second positional argument if given 54 | if [ "$argc" -eq 2 ]; then 55 | icnsfilename="$2" 56 | if [ -n "${icnsfilename}" ]; then 57 | ## Ensure file extension 58 | ext=${icnsfilename##*.} 59 | if [ "$ext" != "icns" ]; then 60 | icnsfilename="${icnsfilename}.icns" 61 | fi 62 | else 63 | ## Given empty string as second arg 64 | icnsfilename="${svgfilename%.*}.icns" 65 | fi 66 | else 67 | ## No second arg 68 | icnsfilename="${svgfilename%.*}.icns" 69 | fi 70 | 71 | ## Create iconset directory if necessary 72 | iconsetdirname="${icnsfilename%.*}.iconset" 73 | mkdir -p "${iconsetdirname}" 74 | 75 | ##+---------------------+--------------------+--------------+ 76 | ##| filename | resolution, pixels | density, PPI | 77 | ##+---------------------+--------------------+--------------+ 78 | ##| icon_16x16.png | 16x16 | 72 | 79 | ##| icon_16x16@2x.png | 32x32 | 144 | 80 | ##| icon_32x32.png | 32x32 | 72 | 81 | ##| icon_32x32@2x.png | 64x64 | 144 | 82 | ##| icon_128x128.png | 128x128 | 72 | 83 | ##| icon_128x128@2x.png | 256x256 | 144 | 84 | ##| icon_256x256.png | 256x256 | 72 | 85 | ##| icon_256x256@2x.png | 512x512 | 144 | 86 | ##| icon_512x512.png | 512x512 | 72 | 87 | ##| icon_512x512@2x.png | 1024x1024 | 144 | 88 | ##+---------------------+--------------------+--------------+ 89 | 90 | ## Create PNG files as described in table 91 | sizes=(16 32 128 256 512) 92 | densities=(72 144) 93 | 94 | for size in "${sizes[@]}"; do 95 | dimen="${size}x${size}" 96 | for density in "${densities[@]}"; do 97 | if [ "${density}" == "72" ]; then 98 | ## std 99 | resolution="${dimen}" 100 | scale="" 101 | else 102 | ## hires 103 | resolution="$(($size * 2))x$(($size * 2))" 104 | scale="@2x" 105 | fi 106 | pngfilename="${iconsetdirname}/icon_${dimen}${scale}.png" 107 | #echo \ 108 | ${CONVERT_BIN} \ 109 | -background "none" \ 110 | -density "${density}" \ 111 | -resize "${resolution}!" \ 112 | -units "PixelsPerInch" \ 113 | "${svgfilename}" \ 114 | "${pngfilename}" 115 | if [ "$?" -ne 0 ]; then 116 | echo "${script}: error creating icon file: ${pngfilename}" >&2 117 | exit 1 118 | fi 119 | done 120 | done 121 | 122 | ## Convert iconset to ICNS file 123 | iconutil --convert icns "${iconsetdirname}" 124 | if [ "$?" -ne 0 ]; then 125 | echo "${script}: error converting iconset to ICNS: ${iconsetdirname}" >&2 126 | exit 1 127 | else 128 | rm -rf "${iconsetdirname}" 129 | fi 130 | 131 | exit 0 132 | -------------------------------------------------------------------------------- /mac/.bashrc: -------------------------------------------------------------------------------- 1 | # ~/.bashrc: executed by bash(1) for non-login shells. 2 | # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) 3 | # for examples 4 | 5 | # If not running interactively, don't do anything 6 | [ -z "$PS1" ] && return 7 | 8 | # don't put duplicate lines or lines starting with space in the history. 9 | # See bash(1) for more options 10 | HISTCONTROL=ignoreboth 11 | 12 | # append to the history file, don't overwrite it 13 | shopt -s histappend 14 | 15 | # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) 16 | HISTSIZE=1000 17 | HISTFILESIZE=2000 18 | 19 | # check the window size after each command and, if necessary, 20 | # update the values of LINES and COLUMNS. 21 | shopt -s checkwinsize 22 | 23 | # If set, the pattern "**" used in a pathname expansion context will 24 | # match all files and zero or more directories and subdirectories. 25 | #shopt -s globstar 26 | 27 | # make less more friendly for non-text input files, see lesspipe(1) 28 | [ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" 29 | 30 | # set variable identifying the chroot you work in (used in the prompt below) 31 | if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then 32 | debian_chroot=$(cat /etc/debian_chroot) 33 | fi 34 | 35 | # set a fancy prompt (non-color, unless we know we "want" color) 36 | case "$TERM" in 37 | xterm-color) color_prompt=yes;; 38 | esac 39 | 40 | # uncomment for a colored prompt, if the terminal has the capability; turned 41 | # off by default to not distract the user: the focus in a terminal window 42 | # should be on the output of commands, not on the prompt 43 | #force_color_prompt=yes 44 | 45 | if [ -n "$force_color_prompt" ]; then 46 | if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then 47 | # We have color support; assume it's compliant with Ecma-48 48 | # (ISO/IEC-6429). (Lack of such support is extremely rare, and such 49 | # a case would tend to support setf rather than setaf.) 50 | color_prompt=yes 51 | else 52 | color_prompt= 53 | fi 54 | fi 55 | 56 | if [ "$color_prompt" = yes ]; then 57 | PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' 58 | else 59 | PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' 60 | fi 61 | unset color_prompt force_color_prompt 62 | 63 | # If this is an xterm set the title to user@host:dir 64 | case "$TERM" in 65 | xterm*|rxvt*) 66 | PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" 67 | ;; 68 | *) 69 | ;; 70 | esac 71 | 72 | # enable color support of ls and also add handy aliases 73 | if [ -x /usr/bin/dircolors ]; then 74 | test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" 75 | alias ls='ls --color=auto' 76 | #alias dir='dir --color=auto' 77 | #alias vdir='vdir --color=auto' 78 | 79 | alias grep='grep --color=auto' 80 | alias fgrep='fgrep --color=auto' 81 | alias egrep='egrep --color=auto' 82 | fi 83 | 84 | # some more ls aliases 85 | alias ll='ls -alF' 86 | alias la='ls -A' 87 | alias l='ls -CF' 88 | 89 | # Add an "alert" alias for long running commands. Use like so: 90 | # sleep 10; alert 91 | alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' 92 | 93 | # Alias definitions. 94 | # You may want to put all your additions into a separate file like 95 | # ~/.bash_aliases, instead of adding them here directly. 96 | # See /usr/share/doc/bash-doc/examples in the bash-doc package. 97 | 98 | if [ -f ~/.bash_aliases ]; then 99 | . ~/.bash_aliases 100 | fi 101 | 102 | # enable programmable completion features (you don't need to enable 103 | # this, if it's already enabled in /etc/bash.bashrc and /etc/profile 104 | # sources /etc/bash.bashrc). 105 | if [ -f /etc/bash_completion ] && ! shopt -oq posix; then 106 | . /etc/bash_completion 107 | fi 108 | 109 | export EDITOR=vim 110 | export LANG="en_US.UTF-8" 111 | export LC_ALL="en_US.UTF-8" 112 | 113 | PATH=$HOME/local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/local/sbin:$PATH 114 | 115 | # Add RVM to PATH for scripting. Make sure this is the last PATH variable change. 116 | #PATH="$PATH:$HOME/.rvm/bin" 117 | 118 | export PATH 119 | export JAVA_HOME=`/usr/libexec/java_home -v 1.8` 120 | launchctl setenv PATH $PATH 121 | 122 | -------------------------------------------------------------------------------- /mac/.mjolnir/init.lua: -------------------------------------------------------------------------------- 1 | 2 | --dofile(package.searchpath("grid", package.path)) 3 | 4 | 5 | local application = require "mjolnir.application" 6 | local hotkey = require "mjolnir.hotkey" 7 | local window = require "mjolnir.window" 8 | local alert = require "mjolnir.alert" 9 | local fnutils = require "mjolnir.fnutils" 10 | local grid = require "mjolnir.bg.grid" 11 | --_ = require 'underscore' 12 | 13 | local mash = {"alt"} 14 | local mash_ctrl = {"ctrl", "alt"} 15 | local mash_shift = {"shift", "alt"} 16 | 17 | -- Start 18 | 19 | alert.show('Mjolnir on service now.') 20 | 21 | 22 | -- Functions >>> 23 | 24 | table.indexOf = function( t, object ) 25 | local result 26 | if "table" == type( t ) then 27 | for i=1,#t do 28 | if object == t[i] then 29 | result = i 30 | break 31 | end 32 | end 33 | end 34 | return result 35 | end 36 | 37 | function getAnotherWindowsOnSameScreen(win, offset) 38 | local windows = win:otherwindows_samescreen() 39 | table.insert(windows, win) 40 | table.sort(windows, function(x, y) return x:frame().x > y:frame().x end) 41 | local index = table.indexOf(windows, win) 42 | return windows[(index + offset + #windows) % #windows] 43 | end 44 | 45 | function getNextWindowsOnSameScreen(win) 46 | return getAnotherWindowsOnSameScreen(win, 1) 47 | end 48 | 49 | function getPreviousWindowsOnSameScreen(win) 50 | return getAnotherWindowsOnSameScreen(win, -1) 51 | end 52 | 53 | -- Functions <<< 54 | 55 | 56 | -- Application >>> 57 | 58 | hotkey.bind(mash, '`', function() application.launchorfocus("iTerm") end) 59 | hotkey.bind(mash, '1', function() application.launchorfocus("Firefox") end) 60 | hotkey.bind(mash, '2', function() application.launchorfocus("Google Chrome") end) 61 | hotkey.bind(mash, '3', function() application.launchorfocus("QQ") end) 62 | hotkey.bind(mash, 'e', function() application.launchorfocus("Preview") end) 63 | hotkey.bind(mash, 'a', function() application.launchorfocus("MacVim") end) 64 | hotkey.bind(mash, 's', function() application.launchorfocus("IntelliJ IDEA 14") end) 65 | hotkey.bind(mash, 'z', function() application.launchorfocus("MacDown") end) 66 | hotkey.bind(mash, ',', function() application.launchorfocus("Airmail") end) 67 | hotkey.bind(mash, '9', function() application.launchorfocus("NeteaseMusic") end) 68 | hotkey.bind(mash, '.', function() application.launchorfocus("Evernote") end) 69 | hotkey.bind(mash, '/', function() application.launchorfocus("Finder") end) 70 | 71 | -- Application <<< 72 | 73 | 74 | -- Size >>> 75 | 76 | hotkey.bind(mash_shift, 'm', grid.maximize_window) -- TODO 77 | 78 | hotkey.bind(mash, "=", function() -- TODO 79 | grid.adjustheight(1) 80 | end) 81 | -- hotkey.bind(mash, '+', function() grid.adjustheight(1) end) -- my 82 | hotkey.bind(mash, '-', function() -- TODO 83 | grid.adjustheight(-1) 84 | end) 85 | 86 | hotkey.bind(mash, '\\', function() -- TODO 87 | end) 88 | 89 | -- Size <<< 90 | 91 | -- Position >>> 92 | 93 | hotkey.bind(mash_ctrl, "l", function() -- < 94 | local win = window.focusedwindow() 95 | local f = win:frame() 96 | f.x = f.x + 100 97 | win:setframe(f) 98 | end) 99 | 100 | hotkey.bind(mash_ctrl, "h", function() -- > 101 | local win = window.focusedwindow() 102 | local f = win:frame() 103 | f.x = f.x - 100 104 | win:setframe(f) 105 | end) 106 | 107 | hotkey.bind(mash_ctrl, "j", function() -- v 108 | local win = window.focusedwindow() 109 | local f = win:frame() 110 | f.y = f.y + 100 111 | win:setframe(f) 112 | end) 113 | 114 | hotkey.bind(mash_ctrl, "k", function() -- ^ 115 | local win = window.focusedwindow() 116 | local f = win:frame() 117 | f.y = f.y - 100 118 | win:setframe(f) 119 | end) 120 | 121 | -- Position <<< 122 | 123 | 124 | -- Multi Screen >>> 125 | 126 | hotkey.bind(mash, "h", function() -- TODO 127 | end) 128 | 129 | 130 | hotkey.bind(mash, "l", function() -- TODO 131 | end) 132 | 133 | 134 | hotkey.bind(mash_shift, "h", function() -- TODO 135 | end) 136 | 137 | 138 | hotkey.bind(mash_shift, "l", function() -- TODO 139 | end) 140 | 141 | -- Multi Screen <<< 142 | 143 | 144 | -- Screen >>> 145 | 146 | hotkey.bind(mash, "j", function() -- TODO 147 | local win = window.focusedwindow() 148 | if win == nil then 149 | return 150 | end 151 | --local others = win:otherwindows_samescreen() 152 | --if #others == 0 then return end 153 | --others[1]:focus() 154 | getNextWindowsOnSameScreen(win):focus() 155 | end) 156 | 157 | hotkey.bind(mash, "k", function() -- TODO 158 | local win = window.focusedwindow() 159 | if win == nil then 160 | return 161 | end 162 | getPreviousWindowsOnSameScreen(win):focus() 163 | end) 164 | 165 | -- Screen <<< 166 | 167 | 168 | hotkey.bind(mash, "0", function() 169 | alert.show('Focus') 170 | end) 171 | 172 | -------------------------------------------------------------------------------- /mac/.amethyst: -------------------------------------------------------------------------------- 1 | { 2 | "LAYOUTS": "----------------------", 3 | "layouts": [ 4 | "floating", 5 | "tall" 6 | ], 7 | 8 | "MODIFIERS": "----------------------", 9 | "Valid modifiers are": [ 10 | "option", 11 | "shift", 12 | "control", 13 | "command" 14 | ], 15 | 16 | "mod1": [ 17 | "option", 18 | ], 19 | "mod2": [ 20 | "option", 21 | "shift", 22 | ], 23 | 24 | "COMMANDS": "----------------------", 25 | "Commands are": { 26 | "cycle-layout": "Cycle layout to the next layout", 27 | "cycle-layout-backward": "Cycle layout to the previous layout", 28 | "focus-screen-1": "Focus the main window on the first screen", 29 | "focus-screen-2": "Focus the main window on the second screen", 30 | "focus-screen-3": "Focus the main window on the third screen", 31 | "throw-screen-1": "Throw the focused window to the first screen", 32 | "throw-screen-2": "Throw the focused window to the second screen", 33 | "throw-screen-3": "Throw the focused window to the third screen", 34 | "shrink-main": "Shrink the main pane of the current layout", 35 | "expand-main": "Expand the main pane of the current layout", 36 | "increase-main": "Increase the number of windows in the main pane", 37 | "decrease-main": "Decrease the number of windows in the main pane", 38 | "focus-ccw": "Move window focus counter-clockwise on the current screen", 39 | "focus-cw": "Move window focus clockwise on the current screen", 40 | "swap-ccw": "Swap focused window with the next window going counter-clockwise", 41 | "swap-cw": "Swap focused window with the next window going clockwise", 42 | "swap-main": "Swap focused window with the main window of its screen", 43 | "throw-space-1": "Throw the focused window to the first space", 44 | "throw-space-2": "Throw the focused window to the second space", 45 | "throw-space-3": "Throw the focused window to the third space", 46 | "throw-space-4": "Throw the focused window to the fourth space", 47 | "throw-space-5": "Throw the focused window to the fifth space", 48 | "throw-space-6": "Throw the focused window to the sixth space", 49 | "throw-space-7": "Throw the focused window to the seventh space", 50 | "throw-space-8": "Throw the focused window to the eighth space", 51 | "throw-space-9": "Throw the focused window to the ninth space", 52 | "toggle-float": "Toggle the focused window between being floating and tiled" 53 | }, 54 | 55 | "cycle-layout": { 56 | "mod": "mod1", 57 | "key": "space" 58 | }, 59 | "cycle-layout-backward": { 60 | "mod": "mod2", 61 | "key": "space" 62 | }, 63 | "focus-screen-1": { 64 | "mod": "mod1", 65 | "key": "h" 66 | }, 67 | "focus-screen-2": { 68 | "mod": "mod1", 69 | "key": "l" 70 | }, 71 | "throw-screen-1": { 72 | "mod": "mod2", 73 | "key": "h" 74 | }, 75 | "throw-screen-2": { 76 | "mod": "mod2", 77 | "key": "l" 78 | }, 79 | "shrink-main": { 80 | "mod": "mod1", 81 | "key": "9" 82 | }, 83 | "expand-main": { 84 | "mod": "mod1", 85 | "key": "0" 86 | }, 87 | "increase-main": { 88 | "mod": "mod1", 89 | "key": "," 90 | }, 91 | "decrease-main": { 92 | "mod": "mod1", 93 | "key": "." 94 | }, 95 | "focus-ccw": { 96 | "mod": "mod1", 97 | "key": "j" 98 | }, 99 | "focus-cw": { 100 | "mod": "mod1", 101 | "key": "k" 102 | }, 103 | "swap-screen-ccw": { 104 | "mod": "mod2", 105 | "key": "h" 106 | }, 107 | "swap-screen-cw": { 108 | "mod": "mod2", 109 | "key": "l" 110 | }, 111 | "swap-main": { 112 | "mod": "mod1", 113 | "key": "enter" 114 | }, 115 | "throw-space-1": { 116 | "mod": "mod2", 117 | "key": "1" 118 | }, 119 | "throw-space-2": { 120 | "mod": "mod2", 121 | "key": "2" 122 | }, 123 | "throw-space-3": { 124 | "mod": "mod2", 125 | "key": "3" 126 | }, 127 | "throw-space-4": { 128 | "mod": "mod2", 129 | "key": "4" 130 | }, 131 | "throw-space-5": { 132 | "mod": "mod2", 133 | "key": "5" 134 | }, 135 | "throw-space-6": { 136 | "mod": "mod2", 137 | "key": "6" 138 | }, 139 | "throw-space-7": { 140 | "mod": "mod2", 141 | "key": "7" 142 | }, 143 | "throw-space-8": { 144 | "mod": "mod2", 145 | "key": "8" 146 | }, 147 | "throw-space-9": { 148 | "mod": "mod2", 149 | "key": "9" 150 | }, 151 | "display-current-layout": { 152 | "mod": "mod1", 153 | "key": "i" 154 | }, 155 | 156 | "MISC": "----------------------", 157 | "floating": [], 158 | "float-small-windows": true, 159 | "mouse-follows-focus": true, 160 | "enables-layout-hud": true, 161 | "enables-layout-hud-on-space-change": true 162 | } 163 | -------------------------------------------------------------------------------- /.ideavimrc: -------------------------------------------------------------------------------- 1 | "source $VIMRUNTIME/vimrc_example.vim 2 | 3 | """"""""""""""""""""""""""""""""""""""" 4 | "Gerneral 5 | """"""""""""""""""""""""""""""""""""""" 6 | 7 | " Enable filetype plugin 8 | filetype plugin on 9 | filetype indent on 10 | 11 | " Set to auto read when a file is changed from the outside 12 | set autoread 13 | 14 | " 编辑vimrc之后,重新加载 15 | autocmd! bufwritepost .vimrc source ~/.vimrc 16 | 17 | " 禁用Vi的兼容模式 18 | set nocompatible 19 | 20 | set noscrollbind 21 | set nocursorbind 22 | 23 | 24 | """"""""""""""""""""""""""""""""""""""" 25 | "VIM user interface 26 | """"""""""""""""""""""""""""""""""""""" 27 | " use chinese help 28 | "set helplang=cn 29 | 30 | "set the menu & the message to English 31 | set langmenu=en_US 32 | let $LANG="en_US.UTF-8" 33 | 34 | set ruler "右下角显示当前光标 35 | 36 | "set cmdheight=2 "The commandbar height 37 | 38 | " Set backspace config 39 | set backspace=eol,start,indent 40 | "set whichwrap+=<,>,h,l 41 | 42 | set ignorecase "Ignore case when searching 43 | set smartcase 44 | "set nowrapscan 45 | 46 | " 使用正统的搜索正则 47 | "nnoremap / /\v 48 | "vnoremap / /\v 49 | 50 | set hlsearch "Highlight search things 51 | 52 | set incsearch "在输入部分查找模式时显示相应的匹配点。 53 | "set nolazyredraw "Don't redraw while executing macros 54 | 55 | set magic "Set magic on, for regular expressions 56 | 57 | set showmatch "Show matching bracets when text indicator is over them 58 | 59 | set sidescroll=10 "左右移动边距 60 | 61 | "set list " 显示制表符/回车符 62 | set listchars=tab:>-,trail:$ " 行尾符号 63 | 64 | set showcmd "显示右下角命令 65 | set cursorline 66 | 67 | set noerrorbells 68 | set novisualbell 69 | 70 | "set iskeyword=@,48-57,192-255 71 | 72 | if ! has("gui_running") 73 | set mouse-=a 74 | endif 75 | 76 | set equalalways "分割窗口时保持相等的宽/高 77 | 78 | set guitablabel=%N.%t " 设定标签上显示序号 79 | 80 | set foldmethod=syntax 81 | set foldcolumn=0 82 | set foldlevel=0 83 | set nofoldenable 84 | set diffopt=vertical,iwhite 85 | 86 | """"""""""""""""""""""""""""""""""""""" 87 | "Colors and Fonts 88 | """"""""""""""""""""""""""""""""""""""" 89 | 90 | syntax enable "Enable syntax hl 91 | 92 | 93 | " 设定行首tab为灰色 94 | highlight LeaderTab guifg=#666666 95 | 96 | 97 | """"""""""""""""""""""""""""""""""""""" 98 | "Files, backups and undo 99 | """"""""""""""""""""""""""""""""""""""" 100 | 101 | " Turn backup off, since most stuff is in SVN, git anyway... 102 | set nobackup 103 | set nowritebackup 104 | "set noswapfile 105 | set backupext=.bak 106 | 107 | "设置编码 108 | set fileencodings=utf-8,gbk,ucs-bom,default,latin1 109 | set termencoding=utf-8 110 | set encoding=utf-8 111 | 112 | """"""""""""""""""""""""""""""""""""""" 113 | "Text, tab and indent related 114 | """"""""""""""""""""""""""""""""""""""" 115 | 116 | "set expandtab 117 | set noexpandtab "是否使用Tab缩进 默认使用 118 | 119 | set shiftwidth=4 120 | set tabstop=4 121 | set smarttab 122 | 123 | set autoindent "Auto indent 124 | set smartindent "Smart indet 125 | set wrap "Wrap lines 126 | 127 | 128 | """"""""""""""""""""""""""""""""""""""" 129 | "Moving around, tabs and buffers 130 | """"""""""""""""""""""""""""""""""""""" 131 | " Smart way to move btw. windows 132 | map j 133 | map k 134 | map h 135 | map l 136 | 137 | " Use the arrows to something usefull 138 | "map :bn 139 | "map :bp 140 | 141 | 142 | """"""""""""""""""""""""""""""""""""""" 143 | "Visual Cues 144 | """"""""""""""""""""""""""""""""""""""" 145 | set number " 显示行号 146 | set numberwidth=2 "行号栏的宽度 147 | " set foldclose=all 148 | 149 | "function! MarkPoint() 150 | "mark ` 151 | "endfunction 152 | 153 | "autocmd CursorMoved * call MarkPoint() 154 | 155 | 156 | """"""""""""""""""""""""""""""""""""""" 157 | " Text Formatting/Layout 158 | """"""""""""""""""""""""""""""""""""""" 159 | 160 | set formatoptions+=mB 161 | set linebreak "智能换行 162 | "set tw=500 "自动换行 超过n列 163 | 164 | 165 | """"""""""""""""""""""""""""""""""""""" 166 | " Plugin 167 | """"""""""""""""""""""""""""""""""""""" 168 | set tags=tags; 169 | 170 | """"""""""""""""""""""""""""""""""""""" 171 | " Map 172 | """"""""""""""""""""""""""""""""""""""" 173 | "map :Tlist 174 | "代码折叠快捷方式 175 | map zR 176 | imap zR 177 | map zM 178 | imap zM 179 | 180 | " 标签设置 181 | map gT 182 | map gt 183 | noremap :tabnext 184 | noremap :tabprev 185 | inoremap :tabnext 186 | inoremap :tabprev 187 | map 188 | 189 | map Q :q 190 | 191 | " 用 * / # 匹配选中 192 | vnoremap * y/=escape(@", '\\/.*$^~[]') 193 | vnoremap # y?=escape(@", '\\/.*$^~[]') 194 | 195 | " html缩进 196 | let g:html_indent_inctags = "p,li,dt,dd" 197 | 198 | nnoremap << 199 | inoremap 200 | 201 | " 模拟 Emacs 键绑定 202 | " Move 203 | inoremap 204 | inoremap 205 | " inoremap 206 | " inoremap 207 | inoremap 208 | inoremap 209 | cmap 210 | cmap 211 | cmap 212 | cmap 213 | cmap 214 | cmap 215 | 216 | inoremap b 217 | inoremap w 218 | " Rubout word / line and enter insert mode 219 | " use instead of 220 | inoremap dbcl 221 | " delete 222 | inoremap d0cl 223 | inoremap C 224 | inoremap 225 | inoremap de 226 | 227 | "let g:pep8_map='8' " PEP8 Check 228 | 229 | " diff 230 | map d /^[=<>]\{7\} 231 | 232 | " noremap b :BufExplorer 233 | 234 | inoremap p "*p 235 | noremap p "*p 236 | 237 | inoremap q :q 238 | noremap q :q 239 | 240 | inoremap w :w 241 | noremap w :w 242 | 243 | nnoremap << 244 | inoremap 245 | 246 | set ideajoin 247 | -------------------------------------------------------------------------------- /.surfingkeys.js: -------------------------------------------------------------------------------- 1 | // vim: set ft=javascript tabstop=4 shiftwidth=4 expandtab: 2 | const { 3 | aceVimMap, 4 | mapkey, 5 | imap, 6 | iunmap, 7 | imapkey, 8 | getClickableElements, 9 | vmapkey, 10 | map, 11 | unmap, 12 | cmap, 13 | addSearchAlias, 14 | removeSearchAlias, 15 | tabOpenLink, 16 | readText, 17 | Clipboard, 18 | Front, 19 | Hints, 20 | Visual, 21 | RUNTIME, 22 | } = api; 23 | 24 | // Constants 25 | var USE_NAVIGATOR_CLIPBOARD_DOMAINS = [ 26 | 'yuque.com', 27 | ]; 28 | 29 | // Global 30 | 31 | settings.hintAlign = "left"; 32 | //Events.hotKey=""; 33 | 34 | map('?', 'u'); 35 | //map('gi', 'i'); 36 | //map('gI', 'I'); 37 | unmap(''); 38 | map('', ''); // FIXME it not works https://github.com/brookhong/Surfingkeys/issues/290 39 | 40 | // Insert mode 41 | 42 | iunmap(''); 43 | iunmap(''); 44 | 45 | // Navigator 46 | 47 | map('h', 'E'); // tab focus left 48 | map('l', 'R'); // tab focus right 49 | map('u', 'e'); // ⬆️ 50 | 51 | // map('o', 'go'); // open in current tab 52 | 53 | map('H', 'S'); // backward 54 | map('L', 'D'); // forward 55 | map('T', 'on'); 56 | 57 | settings.smartPageBoundary = false; 58 | iunmap(":"); // disable emoji input 59 | 60 | // Action 61 | 62 | map('`', "'"); 63 | // map('F', 'af'); // open in new tab 64 | map('F', 'gf'); // open in new unactive tab 65 | mapkey('p', "Open the clipboard's URL in the current tab", function() { 66 | navigator.clipboard.readText().then( 67 | text => { 68 | if (text.startsWith("http://") || text.startsWith("https://")) { 69 | window.location = text; 70 | } else { 71 | window.location = text = "https://www.google.com/search?q=" + text; 72 | } 73 | } 74 | ); 75 | }); 76 | mapkey('P', 'Open link from clipboard', function() { 77 | navigator.clipboard.readText().then( 78 | text => { 79 | if (text.startsWith("http://") || text.startsWith("https://")) { 80 | tabOpenLink(text); 81 | } else { 82 | tabOpenLink("https://www.google.com/search?q=" + text); 83 | } 84 | } 85 | ); 86 | }); 87 | 88 | // source: https://gist.github.com/Echostream/fe560aa30271172398cf432b7b281fd5 89 | mapkey('gi', '#1Go to edit box', function() { 90 | var inputs = document.getElementsByTagName('input'); 91 | var input = null; 92 | for(var i=0; i>|»/i; 183 | 184 | // Style 185 | 186 | settings.theme = ` 187 | `; 188 | -------------------------------------------------------------------------------- /mac/phoenix/src/window.ts: -------------------------------------------------------------------------------- 1 | import * as _ from "lodash"; 2 | import * as config from './config'; 3 | import {restoreMousePositionForWindow, saveMousePositionForWindow} from "./mouse"; 4 | import {windowsOnOtherScreen} from "./screen"; 5 | import {displayAllVisiableWindowModal, log} from "./util"; 6 | 7 | export function sortByMostRecent(windows: Window[]): Window[] { 8 | // var start = new Date().getTime(); 9 | const windowsRecent = Window.recent(); 10 | const visibleAppMostRecentFirst = _.map( 11 | windowsRecent, (w) => w.hash(), 12 | ); 13 | // Phoenix.log('Time s0: ' + (new Date().getTime() - start)); 14 | const visibleAppMostRecentFirstWithWeight = _.zipObject( 15 | visibleAppMostRecentFirst, _.range(visibleAppMostRecentFirst.length), 16 | ); 17 | return _.sortBy(windows, (window) => visibleAppMostRecentFirstWithWeight[window.hash()]); 18 | }; 19 | 20 | export function calcResizeFrame(frame: Rectangle, ratio: number): Rectangle { 21 | return { 22 | x: Math.round(frame.x + frame.width / 2 * (1 - ratio)), 23 | y: Math.round(frame.y + frame.height / 2 * (1 - ratio)), 24 | width: Math.round(frame.width * ratio), 25 | height: Math.round(frame.height * ratio), 26 | } 27 | } 28 | 29 | export function calcSmallerFrame(frame: Rectangle): Rectangle { 30 | return calcResizeFrame(frame, 0.75); 31 | } 32 | 33 | export function calcSmallerFrameSticky(frame: Rectangle, screenFrame: Rectangle): Rectangle { 34 | const newFrame = calcSmallerFrame(frame); 35 | 36 | // sticky when not max 37 | if (!(frame.width === screenFrame.width && frame.height === screenFrame.height)) { 38 | // sticky to screen 39 | if (frame.width === screenFrame.width) { 40 | newFrame.width = screenFrame.width; 41 | } 42 | if (frame.height === screenFrame.height) { 43 | newFrame.height = screenFrame.height; 44 | } 45 | if (frame.x === screenFrame.x) { 46 | newFrame.x = screenFrame.x; 47 | } 48 | if (frame.y === screenFrame.y) { 49 | newFrame.y = screenFrame.y; 50 | } 51 | if (frame.x + frame.width === screenFrame.x + screenFrame.width) { 52 | newFrame.x = screenFrame.x + screenFrame.width - newFrame.width; 53 | } 54 | if (frame.y + frame.height === screenFrame.y + screenFrame.height) { 55 | newFrame.y = screenFrame.y + screenFrame.height - newFrame.height; 56 | } 57 | } 58 | return newFrame; 59 | } 60 | 61 | export function calcLargerFrame(frame: Rectangle): Rectangle { 62 | return calcResizeFrame(frame, 1.25); 63 | } 64 | 65 | export function getCurrentWindow(): Window | undefined { 66 | const windowOptional = Window.focused(); 67 | if (windowOptional !== undefined) { 68 | return windowOptional; 69 | } 70 | // FIXME sometime mainWindow is undefined 71 | return App.focused().mainWindow(); 72 | } 73 | 74 | export function hideInactiveWindow(windows: Window[]) { 75 | const now = new Date().getTime() / 1000; 76 | _.chain(windows).filter((window) => { 77 | if (!config.ACTIVE_WINDOWS_TIMES[window.app().processIdentifier()]) { 78 | config.ACTIVE_WINDOWS_TIMES[window.app().processIdentifier()] = now; 79 | return false; 80 | } else { 81 | return true 82 | } 83 | ; 84 | }).filter((window) => { 85 | return now - config.ACTIVE_WINDOWS_TIMES[window.app().processIdentifier()] > config.HIDE_INACTIVE_WINDOW_TIME * 60; 86 | // return now - ACTIVE_WINDOWS_TIMES[window.app().pid]> 5; 87 | }).map((window) => { 88 | window.app().hide() 89 | }); 90 | } 91 | 92 | export function heartbeatWindow(window: Window) { 93 | config.ACTIVE_WINDOWS_TIMES[window.app().processIdentifier()] = new Date().getTime() / 1000; 94 | // hide_inactiveWindow(window.otherWindowsOnSameScreen()); 95 | } 96 | 97 | export function setWindowCentral(window: Window) { 98 | window.setTopLeft({ 99 | x: (window.screen().flippedFrame().width - window.size().width) / 2 + window.screen().flippedFrame().x, 100 | y: (window.screen().flippedFrame().height - window.size().height) / 2 + window.screen().flippedFrame().y, 101 | }); 102 | heartbeatWindow(window); 103 | }; 104 | 105 | export function autoRangeByRecent() { 106 | const screen = Screen.main() 107 | const frame = screen.flippedVisibleFrame(); 108 | 109 | const windows: Window[] = sortByMostRecent(screen.windows({visible: true})); 110 | _.map(windows, (window, index) => { 111 | window.setTopLeft({ 112 | x: frame.x + index * 100, 113 | y: frame.y, 114 | }); 115 | window.setSize({ 116 | // width: (window.topLeft().x + window.size().width) > (frame.x + frame.width) ? frame.x + frame.width - window.topLeft().x: window.size().width, 117 | width: window.size().width, 118 | height: frame.height, 119 | }); 120 | }); 121 | } 122 | 123 | export function focusWindowInSameScreen(window: Window | undefined, windowsFn: (window: Window) => Window[], 124 | selectFn: (window: Window | undefined, windows: Window[]) => Window | undefined) { 125 | if (window === undefined) { 126 | return; 127 | } 128 | const screen = Screen.main(); 129 | const rectangle = screen.flippedFrame(); 130 | const windows = windowsFn(window); 131 | saveMousePositionForWindow(window); 132 | const targetWindow = selectFn(window, windows); 133 | // const targetWindow = getPreviousWindowsOnSameScreen(window); 134 | if (!targetWindow) { 135 | return; 136 | } 137 | log(`focusWindowInSameScreen.targetWindow: ${targetWindow.title()}`); 138 | targetWindow.focus(); 139 | // TODO cannot focus Chrome on same screen, if two Chrome in two Screen. 140 | restoreMousePositionForWindow(targetWindow); 141 | displayAllVisiableWindowModal(windows, targetWindow, rectangle); 142 | } 143 | 144 | export function marginWindow(positionFn: (window: Window, frame: Rectangle) => any) { 145 | const frame = Screen.main().flippedVisibleFrame(); 146 | const window = Window.focused(); 147 | 148 | if (window === undefined) { 149 | return; 150 | } 151 | positionFn(window, frame); 152 | } 153 | 154 | export function isMax(windowSize: Size, screenSize: Size): boolean { 155 | return windowSize.width === screenSize.width && windowSize.height === screenSize.height; 156 | } 157 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Alswl's .oOo. # 2 | 3 | 这里是我的 Linux / macOS 配置文件,有兴趣的可以参考。 4 | 5 | This is my Linux / macOS configuration. 6 | 7 | 目前的配置文件包括: 8 | 9 | These configuration Includes: 10 | 11 | - awesome # moved to [awesome][] 12 | - zsh 13 | - vim # moved to [miv][] 14 | - vimperator # deprecated, use Surfingkeys in Chrome 15 | - pentadactyl # deprecated, use Surfingkeys in Chrome 16 | - Vimium # deprecated, use Surfingkeys 17 | - CVim # deprecated, use Surfingkeys 18 | - VimFx # deprecated, use Surfingkeys in Chrome 19 | - Surfingkeys 20 | - Xmodmap # deprecated, use Ergodox 21 | - font 22 | - tmux / screen 23 | - xmonad # deprecated, use awesome 24 | - xmobar # deprecated, use awesome 25 | - ideavimrc 26 | - .gitconfig 27 | - mac/phoenix, see https://github.com/alswl/.oOo./blob/master/mac/phoenix/README.md 28 | - mjolnir # deprecated, use phoenix 29 | - mac/Library/LaunchAgents/com.alswl.edit-server.plist 30 | - com.alswl.edit-server.plist # TextAid server for https://chrome.google.com/webstore/detail/textaid/ppoadiihggafnhokfkpphojggcdigllp?hl=en 31 | - .obsidian.vimrc # for Obsidian 32 | 33 | Useful `local/bin` (scripts): 34 | 35 | - SimpleHTTPServerWithUpload.py # simple HTTPS Server with Upload 36 | - bing-wallpaper.sh # bing wallpaper downloader 37 | - check-brew-cask-upgrade # fast check brew cask updates 38 | - crash # crash link 39 | - csv2json 40 | - ddns-by-cloudflare # update dns record for local device by cloudflare 41 | - ddns-by-cloudflare-wan # update dns record for public IP by cloudflare 42 | - ddns-by-dnspod # update dns record for local device by dnspod 43 | - ddns-by-dnspod-wan # update dns record for public IP by dnspod 44 | - dig-http 45 | - edit-server # script for TextAid, use vim in Chorme, https://chrome.google.com/webstore/detail/ppoadiihggafnhokfkpphojggcdigllp 46 | - fcitx-remote-osa # use osa switch macOS Input Method 47 | - format-gfm # format file with github flavor markdown 48 | - format-markdown # format file with markdown 49 | - funiq # file uniq, generate hash for file 50 | - generate-output-summary-md # generate .output for yuque 51 | - generate-summary-md # generate summary.md for markdown directory 52 | - generate_dash_index.sh # generate dash doc index 53 | - gh-md-toc 54 | - git-archive-zip # archive a git repo to zip, and rename it to xxx.git 55 | - git-code-numbers-by-authors # analytics git repo by author 56 | - git_diff_wrapper # deprecate, use git difftool 57 | - homebrew-using-mirror # using mirror for homebrew 58 | - image-from-clipboard-to-png-copy-markdown # paste image from clipcbard to png file with markdown format 59 | - image-from-clipboard-to-png-global # paste image from clipcbard to png file 60 | - image-from-path-to-assets-copy-markdown # paste image from path to png file with markdown format 61 | - iterm2-recv-zmodem.sh # rz for iTerm2 62 | - iterm2-send-zmodem.sh # sz for iTerm2 63 | - jmxsh 64 | - jmxterm 65 | - lark-gen-markdown # yuque markdown generate .output 66 | - ls-upload-log4d 67 | - markdown2ctags.py 68 | - mdcp # copy markdown with internal links update (DEPRECATED, using Obsidian) 69 | - mdmv # move markdown with internal links update (DEPRECATED, using Obsidian) 70 | - mdsearch # markdown search, mardkown file search by title (DEPRECATED, using Obsidian) 71 | - mouse-tracking-echo-in-shell 72 | - mouse_restore.sh 73 | - mov2gif 74 | - mysql2sqlite.sh 75 | - paste-html-to-md 76 | - paste-html-to-md-copy 77 | - paste-html-to-rtf 78 | - paste-html-to-rtf-copy 79 | - paste-md-to-html 80 | - paste-md-to-html-copy 81 | - paste-md-to-rtf 82 | - paste-md-to-rtf-copy 83 | - paste-rtf-to-html 84 | - paste-rtf-to-html-copy 85 | - paste-rtf-to-md 86 | - paste-rtf-to-md-copy 87 | - paste-rtf-to-md-for-table 88 | - paste-rtf-to-md-for-table-copy 89 | - privoxy_restart.sh 90 | - puml-format-order-node 91 | - pyyaml-format # format yaml with pyyaml 92 | - qrdecode 93 | - reduceimg 94 | - release-mvn-to-git-release-binary-branch.sh 95 | - release-sbt-to-git-release-binary-branch.sh 96 | - remark # generate remark slide by md 97 | - reveal # generate reveal slide by md 98 | - rime_dict_manager 99 | - rsocks_start.sh 100 | - scel2mmseg.py 101 | - shadowsocks_client_start_ha.sh 102 | - shadowsocks_client_start_hk.sh 103 | - shadowsocks_client_start_jp.sh 104 | - shj 105 | - socks5proxywrapper 106 | - soks5proxyhttp 107 | - soks5proxyssh 108 | - speedfox 109 | - sqlite3-to-mysql.py 110 | - svg2icns # convert svg to icns (icons set) 111 | - svn_diff_wrapper 112 | - tinypng # use tinypng to compress image 113 | - tinyproxy_start.sh 114 | - tinyproxy_stop.sh 115 | - trash-put # implement trash-put command with trash command 116 | - tree2fulltree # convert tree output to list 117 | - tsa 118 | - uniqf # alias for funiq 119 | - unzip-gbk # unizp gbk file in Linux / macOS 120 | - url_diff 121 | - view-pyc-file 122 | - view-pyc-file3 123 | - viscosity-to-ios-connect.rb 124 | 125 | 126 | ## Usage ## 127 | 128 | 129 | ``` bash 130 | # install zsh 131 | apt-get-install zsh 132 | # or 133 | brew install zsh 134 | 135 | # install oh-my-zsh 136 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" 137 | # git clone zsh-autosuggestions 138 | git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions 139 | 140 | 141 | # install .oOo. 142 | cd YOUR_REPO_PARENT_PATH 143 | git clone https://github.com/alswl/.oOo. 144 | cd .oOo. 145 | ln -s $(pwd)/.* $HOME/ 146 | rm $HOME/.git 147 | rm $HOME/.DS_Store 148 | cp $(pwd)/_.gitconfig $HOME/.gitconfig 149 | 150 | mkdir -p $HOME/local/bin 151 | mkdir -p $HOME/local/etc 152 | ln -s $(pwd)/local/bin/* $HOME/local/bin/ 153 | ln -s $(pwd)/local/etc/* $HOME/local/etc/ 154 | ``` 155 | 156 | macOS continues: 157 | 158 | ```bash 159 | cd YOUR_REPO_PATH 160 | ln -s $(pwd)/mac/.* $HOME/ 161 | ln -s $(pwd)/mac/phoenix/dist/phoenix.js $HOME/.phoenix.js 162 | ln -s $(pwd)/mac/_Library/Application\ Support/Karabiner/private.xml $HOME/Library/Application\ Support/Karabiner/private.xml 163 | ln -s $(pwd)/mac/_config/karabiner/karabiner.json $HOME/.config/karabiner/karabiner.json 164 | ``` 165 | 166 | Linux continues: 167 | 168 | ```bash 169 | cd YOUR_REPO_PATH 170 | ln -s $(pwd)/linux/.* $HOME/ 171 | ``` 172 | 173 | ## Phoenix (window management in macOS as tiling system) 174 | 175 | Application launch: 176 | 177 | ![](./mac/phoenix/_asserts/application-launch.gif) 178 | 179 | Application in window switch: 180 | 181 | ![](./mac/phoenix/_asserts/application-switch.gif) 182 | 183 | 184 | Window movement: 185 | 186 | ![](./mac/phoenix/_asserts/window.gif) 187 | 188 | More details in [Windows management for hacker | Log4D](https://blog.alswl.com/2016/04/windows-management-for-hacker/) 189 | 190 | ## Related ## 191 | 192 | - [miv][] vim configuration 193 | - [awesome][] awesome configuration 194 | 195 | [.oOo.]: https://github.com/alswl/.oOo. 196 | [awesome]: https://github.com/alswl/awesome 197 | [miv]: https://github.com/alswl/miv 198 | -------------------------------------------------------------------------------- /.zsh_completion/_toodledo: -------------------------------------------------------------------------------- 1 | #compdef _toodledo toodledo 2 | 3 | # zsh completion for toodledo -*- shell-script -*- 4 | 5 | __toodledo_debug() 6 | { 7 | local file="$BASH_COMP_DEBUG_FILE" 8 | if [[ -n ${file} ]]; then 9 | echo "$*" >> "${file}" 10 | fi 11 | } 12 | 13 | _toodledo() 14 | { 15 | local shellCompDirectiveError=1 16 | local shellCompDirectiveNoSpace=2 17 | local shellCompDirectiveNoFileComp=4 18 | local shellCompDirectiveFilterFileExt=8 19 | local shellCompDirectiveFilterDirs=16 20 | 21 | local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace 22 | local -a completions 23 | 24 | __toodledo_debug "\n========= starting completion logic ==========" 25 | __toodledo_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}" 26 | 27 | # The user could have moved the cursor backwards on the command-line. 28 | # We need to trigger completion from the $CURRENT location, so we need 29 | # to truncate the command-line ($words) up to the $CURRENT location. 30 | # (We cannot use $CURSOR as its value does not work when a command is an alias.) 31 | words=("${=words[1,CURRENT]}") 32 | __toodledo_debug "Truncated words[*]: ${words[*]}," 33 | 34 | lastParam=${words[-1]} 35 | lastChar=${lastParam[-1]} 36 | __toodledo_debug "lastParam: ${lastParam}, lastChar: ${lastChar}" 37 | 38 | # For zsh, when completing a flag with an = (e.g., toodledo -n=) 39 | # completions must be prefixed with the flag 40 | setopt local_options BASH_REMATCH 41 | if [[ "${lastParam}" =~ '-.*=' ]]; then 42 | # We are dealing with a flag with an = 43 | flagPrefix="-P ${BASH_REMATCH}" 44 | fi 45 | 46 | # Prepare the command to obtain completions 47 | requestComp="${words[1]} __complete ${words[2,-1]}" 48 | if [ "${lastChar}" = "" ]; then 49 | # If the last parameter is complete (there is a space following it) 50 | # We add an extra empty parameter so we can indicate this to the go completion code. 51 | __toodledo_debug "Adding extra empty parameter" 52 | requestComp="${requestComp} \"\"" 53 | fi 54 | 55 | __toodledo_debug "About to call: eval ${requestComp}" 56 | 57 | # Use eval to handle any environment variables and such 58 | out=$(eval ${requestComp} 2>/dev/null) 59 | __toodledo_debug "completion output: ${out}" 60 | 61 | # Extract the directive integer following a : from the last line 62 | local lastLine 63 | while IFS='\n' read -r line; do 64 | lastLine=${line} 65 | done < <(printf "%s\n" "${out[@]}") 66 | __toodledo_debug "last line: ${lastLine}" 67 | 68 | if [ "${lastLine[1]}" = : ]; then 69 | directive=${lastLine[2,-1]} 70 | # Remove the directive including the : and the newline 71 | local suffix 72 | (( suffix=${#lastLine}+2)) 73 | out=${out[1,-$suffix]} 74 | else 75 | # There is no directive specified. Leave $out as is. 76 | __toodledo_debug "No directive found. Setting do default" 77 | directive=0 78 | fi 79 | 80 | __toodledo_debug "directive: ${directive}" 81 | __toodledo_debug "completions: ${out}" 82 | __toodledo_debug "flagPrefix: ${flagPrefix}" 83 | 84 | if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then 85 | __toodledo_debug "Completion received error. Ignoring completions." 86 | return 87 | fi 88 | 89 | while IFS='\n' read -r comp; do 90 | if [ -n "$comp" ]; then 91 | # If requested, completions are returned with a description. 92 | # The description is preceded by a TAB character. 93 | # For zsh's _describe, we need to use a : instead of a TAB. 94 | # We first need to escape any : as part of the completion itself. 95 | comp=${comp//:/\\:} 96 | 97 | local tab=$(printf '\t') 98 | comp=${comp//$tab/:} 99 | 100 | __toodledo_debug "Adding completion: ${comp}" 101 | completions+=${comp} 102 | lastComp=$comp 103 | fi 104 | done < <(printf "%s\n" "${out[@]}") 105 | 106 | if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then 107 | __toodledo_debug "Activating nospace." 108 | noSpace="-S ''" 109 | fi 110 | 111 | if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then 112 | # File extension filtering 113 | local filteringCmd 114 | filteringCmd='_files' 115 | for filter in ${completions[@]}; do 116 | if [ ${filter[1]} != '*' ]; then 117 | # zsh requires a glob pattern to do file filtering 118 | filter="\*.$filter" 119 | fi 120 | filteringCmd+=" -g $filter" 121 | done 122 | filteringCmd+=" ${flagPrefix}" 123 | 124 | __toodledo_debug "File filtering command: $filteringCmd" 125 | _arguments '*:filename:'"$filteringCmd" 126 | elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then 127 | # File completion for directories only 128 | local subDir 129 | subdir="${completions[1]}" 130 | if [ -n "$subdir" ]; then 131 | __toodledo_debug "Listing directories in $subdir" 132 | pushd "${subdir}" >/dev/null 2>&1 133 | else 134 | __toodledo_debug "Listing directories in ." 135 | fi 136 | 137 | local result 138 | _arguments '*:dirname:_files -/'" ${flagPrefix}" 139 | result=$? 140 | if [ -n "$subdir" ]; then 141 | popd >/dev/null 2>&1 142 | fi 143 | return $result 144 | else 145 | __toodledo_debug "Calling _describe" 146 | if eval _describe "completions" completions $flagPrefix $noSpace; then 147 | __toodledo_debug "_describe found some completions" 148 | 149 | # Return the success of having called _describe 150 | return 0 151 | else 152 | __toodledo_debug "_describe did not find completions." 153 | __toodledo_debug "Checking if we should do file completion." 154 | if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then 155 | __toodledo_debug "deactivating file completion" 156 | 157 | # We must return an error code here to let zsh know that there were no 158 | # completions found by _describe; this is what will trigger other 159 | # matching algorithms to attempt to find completions. 160 | # For example zsh can match letters in the middle of words. 161 | return 1 162 | else 163 | # Perform file completion 164 | __toodledo_debug "Activating file completion" 165 | 166 | # We must return the result of this command, so it must be the 167 | # last command, or else we must store its result to return it. 168 | _arguments '*:filename:_files'" ${flagPrefix}" 169 | fi 170 | fi 171 | fi 172 | } 173 | 174 | # don't run the completion function when being source-ed or eval-ed 175 | if [ "$funcstack[1]" = "_toodledo" ]; then 176 | _toodledo 177 | fi 178 | -------------------------------------------------------------------------------- /local/bin/markdown2ctags.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | # Copyright (C) 2013 John Szakmeister 4 | # All rights reserved. 5 | # 6 | # This software is licensed as described in the file LICENSE.txt, which 7 | # you should have received as part of this distribution. 8 | 9 | import sys 10 | import re 11 | 12 | __version__ = '0.1.3' 13 | 14 | 15 | class ScriptError(Exception): 16 | pass 17 | 18 | 19 | def ctagNameEscape(str): 20 | return re.sub('[\t\r\n]+', ' ', str) 21 | 22 | 23 | def ctagSearchEscape(str): 24 | str = str.replace('\t', r'\t') 25 | str = str.replace('\r', r'\r') 26 | str = str.replace('\n', r'\n') 27 | str = str.replace('\\', r'\\') 28 | return str 29 | 30 | 31 | class Tag(object): 32 | def __init__(self, tagName, tagFile, tagAddress): 33 | self.tagName = tagName 34 | self.tagFile = tagFile 35 | self.tagAddress = tagAddress 36 | self.fields = [] 37 | 38 | def addField(self, type, value=None): 39 | if type == 'kind': 40 | type = None 41 | self.fields.append((type, value or "")) 42 | 43 | def _formatFields(self): 44 | formattedFields = [] 45 | for name, value in self.fields: 46 | if name: 47 | s = '%s:%s' % (name, value or "") 48 | else: 49 | s = str(value) 50 | formattedFields.append(s) 51 | return '\t'.join(formattedFields) 52 | 53 | def __str__(self): 54 | return '%s\t%s\t%s;"\t%s' % ( 55 | self.tagName, self.tagFile, self.tagAddress, 56 | self._formatFields()) 57 | 58 | def __repr__(self): 59 | return "" % ( 60 | self.tagName, self.tagFile, self.tagAddress, 61 | self._formatFields().replace('\t', ' ')) 62 | 63 | def __cmp__(self, other): 64 | return cmp(str(self), str(other)) 65 | 66 | @staticmethod 67 | def section(section): 68 | tagName = ctagNameEscape(section.name) 69 | tagAddress = '/^%s$/' % ctagSearchEscape(section.line) 70 | t = Tag(tagName, section.filename, tagAddress) 71 | t.addField('kind', 's') 72 | t.addField('line', section.lineNumber) 73 | 74 | parents = [] 75 | p = section.parent 76 | while p is not None: 77 | parents.append(ctagNameEscape(p.name)) 78 | p = p.parent 79 | parents.reverse() 80 | 81 | if parents: 82 | t.addField('section', '|'.join(parents)) 83 | 84 | return t 85 | 86 | 87 | class Section(object): 88 | def __init__(self, level, name, line, lineNumber, filename, parent=None): 89 | self.level = level 90 | self.name = name 91 | self.line = line 92 | self.lineNumber = lineNumber 93 | self.filename = filename 94 | self.parent = parent 95 | 96 | def __repr__(self): 97 | return '
    ' % (self.name, self.level, self.lineNumber) 98 | 99 | 100 | def popSections(sections, level): 101 | while sections: 102 | s = sections.pop() 103 | if s and s.level < level: 104 | sections.append(s) 105 | return 106 | 107 | 108 | atxHeadingRe = re.compile(r'^(#+)\s+(.*?)(?:\s+#+)?\s*$') 109 | settextHeadingRe = re.compile(r'^[-=]+$') 110 | settextSubjectRe = re.compile(r'^[^\s]+.*$') 111 | 112 | 113 | def findSections(filename, lines): 114 | sections = [] 115 | inCodeBlock = False 116 | 117 | previousSections = [] 118 | 119 | for i, line in enumerate(lines): 120 | # Skip GitHub Markdown style code blocks. 121 | if line.startswith("```"): 122 | inCodeBlock = not inCodeBlock 123 | continue 124 | 125 | if inCodeBlock: 126 | continue 127 | 128 | m = atxHeadingRe.match(line) 129 | if m: 130 | level = len(m.group(1)) 131 | name = m.group(2) 132 | 133 | popSections(previousSections, level) 134 | if previousSections: 135 | parent = previousSections[-1] 136 | else: 137 | parent = None 138 | lineNumber = i + 1 139 | 140 | s = Section(level, name, line, lineNumber, filename, parent) 141 | previousSections.append(s) 142 | sections.append(s) 143 | else: 144 | m = settextHeadingRe.match(line) 145 | if i and m: 146 | if not settextSubjectRe.match(lines[i - 1]): 147 | continue 148 | 149 | name = lines[i - 1].strip() 150 | 151 | if line[0] == '=': 152 | level = 1 153 | else: 154 | level = 2 155 | 156 | popSections(previousSections, level) 157 | if previousSections: 158 | parent = previousSections[-1] 159 | else: 160 | parent = None 161 | lineNumber = i 162 | 163 | s = Section(level, name, lines[i - 1], lineNumber, 164 | filename, parent) 165 | previousSections.append(s) 166 | sections.append(s) 167 | 168 | return sections 169 | 170 | 171 | def sectionsToTags(sections): 172 | tags = [] 173 | 174 | for section in sections: 175 | tags.append(Tag.section(section)) 176 | 177 | return tags 178 | 179 | 180 | def genTagsFile(output, tags, sort): 181 | if sort == "yes": 182 | tags = sorted(tags) 183 | sortedLine = '!_TAG_FILE_SORTED\t1\n' 184 | elif sort == "foldcase": 185 | tags = sorted(tags, key=lambda x: str(x).lower()) 186 | sortedLine = '!_TAG_FILE_SORTED\t2\n' 187 | else: 188 | sortedLine = '!_TAG_FILE_SORTED\t0\n' 189 | 190 | output.write('!_TAG_FILE_FORMAT\t2\n') 191 | output.write(sortedLine) 192 | 193 | for t in tags: 194 | output.write(str(t)) 195 | output.write('\n') 196 | 197 | 198 | def main(): 199 | from optparse import OptionParser 200 | 201 | parser = OptionParser(usage="usage: %prog [options] file(s)", 202 | version=__version__) 203 | parser.add_option( 204 | "-f", "--file", metavar="FILE", dest="tagfile", 205 | default="tags", 206 | help='Write tags into FILE (default: "tags"). Use "-" to write ' 207 | 'tags to stdout.') 208 | parser.add_option( 209 | "", "--sort", metavar="[yes|foldcase|no]", dest="sort", 210 | choices=["yes", "no", "foldcase"], 211 | default="yes", 212 | help='Produce sorted output. Acceptable values are "yes", ' 213 | '"no", and "foldcase". Default is "yes".') 214 | 215 | options, args = parser.parse_args() 216 | 217 | if options.tagfile == '-': 218 | output = sys.stdout 219 | else: 220 | output = open(options.tagfile, 'wb') 221 | 222 | for filename in args: 223 | f = open(filename, 'rb') 224 | lines = f.read().splitlines() 225 | f.close() 226 | sections = findSections(filename, lines) 227 | 228 | genTagsFile(output, sectionsToTags(sections), sort=options.sort) 229 | 230 | output.flush() 231 | output.close() 232 | 233 | 234 | if __name__ == '__main__': 235 | try: 236 | main() 237 | except IOError as e: 238 | import errno 239 | 240 | if e.errno == errno.EPIPE: 241 | # Exit saying we got SIGPIPE. 242 | sys.exit(141) 243 | raise 244 | except ScriptError as e: 245 | print >> sys.stderr, "ERROR: %s" % str(e) 246 | sys.exit(1) 247 | --------------------------------------------------------------------------------