├── .travis.yml ├── LICENSE ├── README.md ├── configfiles ├── etc │ └── init.d │ │ └── xvfb ├── konsole │ ├── Monokai.colorscheme │ └── MyColor.colorscheme └── minttyrc ├── docs └── snapshots │ ├── git_log.PNG │ ├── installing.PNG │ ├── layout.PNG │ └── package_box.PNG ├── dotfiles ├── aliases ├── completion.zsh ├── editorconfig ├── exports ├── functions ├── gitconfig.devstrap ├── gitignore ├── hgignore ├── irbrc ├── path ├── tmux.conf.local ├── vimrc └── zshrc ├── dotfiles_cn ├── gemrc └── npmrc ├── install.sh ├── scripts ├── install │ ├── common │ │ ├── env.sh │ │ ├── gem.sh │ │ ├── go.sh │ │ ├── main.sh │ │ ├── npm.sh │ │ ├── package.conf │ │ └── pip.sh │ ├── macos │ │ ├── install_depends.sh │ │ ├── main.sh │ │ └── package.conf │ ├── ubuntu │ │ ├── helper.sh │ │ ├── main.sh │ │ └── package.conf │ └── versions.sh └── utils.sh └── test ├── check_travis_result.sh ├── pre_installations.sh ├── run_test.sh ├── test_prerequisites.sh └── ubuntu.16.04.docker.setup.sh /.travis.yml: -------------------------------------------------------------------------------- 1 | language: generic 2 | 3 | sudo: required 4 | 5 | matrix: 6 | include: 7 | - os: linux 8 | dist: trusty 9 | 10 | - os: osx 11 | osx_image: xcode8.1 12 | 13 | allow_failures: 14 | - os: osx 15 | 16 | branches: 17 | only: master 18 | 19 | before_script: 20 | - ./test/pre_installations.sh 21 | - ./test/test_prerequisites.sh 22 | 23 | script: 24 | - ./test/run_test.sh 25 | 26 | after_success: 27 | - ./test/check_travis_result.sh 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ray Guo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DevStrap 2 | 3 | [![Build Status](https://travis-ci.org/ray-g/devstrap.svg?branch=master)](https://travis-ci.org/ray-g/devstrap) 4 | 5 | Quickly add necessary packages and a set of dotfiles to 6 | bootstrap your development environments. 7 | 8 | Currently it only supports Ubuntu now. But this framework should 9 | work on MacOS and any other Linux. 10 | 11 | For platforms other than Ubuntu, `install.sh --env-only` is an option 12 | to skip package selection and installation, only setup the dotfiles. 13 | 14 | PRs are welcome. :smile: 15 | 16 | The packages and settings are based on my personal favorite, 17 | but they are customizable during installation via an 18 | interactive `whiptail` dialog. 19 | 20 | And some dotfiles are also [custmizable](#customize) after installation. 21 | Details are here 22 | [~/.zshrc.local](#zshrclocal), 23 | [~/.zshrc.theme.local](#zshrcthemelocal), 24 | [~/.vimrc.local](#vimrclocal), 25 | [~/.gitconfig](#gitconfig). 26 | 27 | ## Quick Start 28 | 29 | ```shell 30 | git clone https://github.com/ray-g/devstrap.git ~/.devstrap 31 | ~/.devstrap/install.sh 32 | ``` 33 | 34 | ## Snapshots 35 | 36 | ### Package Select Dialog 37 | 38 | 39 | 40 | ### Installing Result 41 | 42 | 43 | 44 | ### Sample UI with Tmux 45 | 46 | 47 | 48 | ### Git Log 49 | 50 | 51 | 52 | ## Command Line Options 53 | 54 | ```text 55 | ./install.sh -h 56 | Usage: ./install.sh [options] 57 | Options: 58 | -h | --help print this help 59 | -d | --debug enable debug mode 60 | -r | --dryrun enable dryrun mode 61 | --all-yes install all packages without selecting 62 | -n | --sel-none select none packages in box 63 | --env-only setup environments only 64 | ``` 65 | 66 | ## Customize 67 | 68 | The `dotfiles` can be easily extended to suit additional 69 | local requirements by using the following files: 70 | 71 | ### ~/.zshrc.local 72 | 73 | The `~/.zshrc.local` file will be automatically sourced after 74 | all the other `shell` related files, thus, allowing its content 75 | to add to or overwrite the existing aliases, settings, PATH, etc. 76 | 77 | Here is a very simple example of a `~/.zshrc.local` file: 78 | 79 | ```shell 80 | #!/bin/bash 81 | 82 | # Set local aliases. 83 | alias starwars="telnet towel.blinkenlights.nl" 84 | 85 | # Set PATH additions. 86 | PATH="$PATH:$HOME/projects/bin" 87 | export PATH 88 | ``` 89 | 90 | ### ~/.zshrc.theme.local 91 | 92 | The `~/.zshrc.theme.local` file will be automatically sourced before 93 | [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) setting up theme. 94 | Thus, allowing you to set your favorite `oh-my-zsh` theme. 95 | By default I have set it to a fence one [ys](https://github.com/robbyrussell/oh-my-zsh/wiki/themes#ys) 96 | 97 | ### ~/.vimrc.local 98 | 99 | The `~/.vimrc.local` file will be automatically sourced after 100 | `~/.vimrc`, thus, allowing its content to add or overwrite the 101 | settings from `~/.vimrc`. 102 | 103 | ### ~/.gitconfig 104 | 105 | The `~/.gitconfig` file will automatically included `~/.gitconfig.devstrap` first, 106 | which contains a set of git configs out of the box. 107 | Then any configurations can be written here `~/.gitconfig`, thus, allowing its 108 | content to overwrite or add to the existing `git` configurations without touch the `devstrap` git repo. 109 | 110 | __Note:__ Use `~/.gitconfig` to store sensitive information 111 | such as the `git` user credentials, e.g.: 112 | 113 | ```shell 114 | [commit] 115 | # Sign commits using GPG. 116 | # https://help.github.com/articles/signing-commits-using-gpg/ 117 | 118 | gpgsign = true 119 | 120 | [user] 121 | name = John Doe 122 | email = john.doe@example.com 123 | signingkey = XXXXXXXX 124 | ``` 125 | 126 | ## Acknowledgements 127 | 128 | Inspiration and code was taken from many sources, including: 129 | 130 | * [Mathias Bynens'](https://github.com/mathiasbynens) [dotfiles](https://github.com/mathiasbynens/dotfiles) 131 | * [Cătălin Mariș'](https://github.com/alrra) [dotfiles](https://github.com/alrra/dotfiles) 132 | * [Amir Salihefendic's](https://github.com/amix) [vimrc](https://github.com/amix/vimrc) 133 | * [Vincent Zhang's](https://github.com/seagle0128) [dotfiles](https://github.com/seagle0128/dotfiles) 134 | 135 | ## License 136 | 137 | The code is available under the [MIT License](LICENSE) 138 | -------------------------------------------------------------------------------- /configfiles/etc/init.d/xvfb: -------------------------------------------------------------------------------- 1 | XVFB=/usr/bin/Xvfb 2 | XVFBARGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 3 | PIDFILE=/var/run/xvfb.pid 4 | case "$1" in 5 | start) 6 | echo -n "Starting virtual X frame buffer: Xvfb" 7 | start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 8 | echo "." 9 | ;; 10 | stop) 11 | echo -n "Stopping virtual X frame buffer: Xvfb" 12 | start-stop-daemon --stop --quiet --pidfile $PIDFILE 13 | rm $PIDFILE 14 | echo "." 15 | ;; 16 | status) 17 | [ -f $PIDFILE ] && cat $PIDFILE | xargs ps | grep $XVFB > /dev/null 2>&1 && echo "Xvfb is running" || echo "Xvfb is stopped" 18 | ;; 19 | restart) 20 | $0 stop 21 | $0 start 22 | ;; 23 | *) 24 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 25 | exit 1 26 | esac 27 | 28 | exit 0 29 | 30 | -------------------------------------------------------------------------------- /configfiles/konsole/Monokai.colorscheme: -------------------------------------------------------------------------------- 1 | [Background] 2 | Color=39,40,34 3 | 4 | [BackgroundIntense] 5 | Color=104,104,104 6 | 7 | [Color0] 8 | Color=39,40,34 9 | 10 | [Color0Intense] 11 | Color=104,104,104 12 | 13 | [Color1] 14 | Color=229,34,34 15 | 16 | [Color1Intense] 17 | Color=229,24,24 18 | 19 | [Color2] 20 | Color=166,227,45 21 | 22 | [Color2Intense] 23 | Color=177,227,50 24 | 25 | [Color3] 26 | Color=252,149,30 27 | 28 | [Color3Intense] 29 | Color=252,82,9 30 | 31 | [Color4] 32 | Color=118,76,255 33 | 34 | [Color4Intense] 35 | Color=72,102,255 36 | 37 | [Color5] 38 | Color=250,37,115 39 | 40 | [Color5Intense] 41 | Color=250,69,148 42 | 43 | [Color6] 44 | Color=103,217,240 45 | 46 | [Color6Intense] 47 | Color=28,219,240 48 | 49 | [Color7] 50 | Color=225,225,218 51 | 52 | [Color7Intense] 53 | Color=255,255,255 54 | 55 | [Foreground] 56 | Color=225,225,218 57 | 58 | [ForegroundIntense] 59 | Color=255,255,255 60 | 61 | [General] 62 | Description=Monokai 63 | Opacity=1 64 | Wallpaper= -------------------------------------------------------------------------------- /configfiles/konsole/MyColor.colorscheme: -------------------------------------------------------------------------------- 1 | [Background] 2 | Color=15,15,15 3 | 4 | [BackgroundIntense] 5 | Color=104,104,104 6 | 7 | [Color0] 8 | Color=0,0,0 9 | 10 | [Color0Intense] 11 | Color=104,104,104 12 | 13 | [Color1] 14 | Color=178,24,24 15 | 16 | [Color1Intense] 17 | Color=255,84,84 18 | 19 | [Color2] 20 | Color=24,178,24 21 | 22 | [Color2Intense] 23 | Color=84,255,84 24 | 25 | [Color3] 26 | Color=178,104,24 27 | 28 | [Color3Intense] 29 | Color=255,255,84 30 | 31 | [Color4] 32 | Color=0,85,255 33 | 34 | [Color4Intense] 35 | Color=40,158,221 36 | 37 | [Color5] 38 | Color=178,24,178 39 | 40 | [Color5Intense] 41 | Color=255,84,255 42 | 43 | [Color6] 44 | Color=24,178,178 45 | 46 | [Color6Intense] 47 | Color=84,255,255 48 | 49 | [Color7] 50 | Color=178,178,178 51 | 52 | [Color7Intense] 53 | Color=255,255,255 54 | 55 | [Foreground] 56 | Color=178,178,178 57 | 58 | [ForegroundIntense] 59 | Color=255,255,255 60 | 61 | [General] 62 | Description=MyColor 63 | Opacity=1 64 | Wallpaper= 65 | -------------------------------------------------------------------------------- /configfiles/minttyrc: -------------------------------------------------------------------------------- 1 | BoldAsFont=no 2 | FontHeight=11 3 | Columns=100 4 | Rows=30 5 | Font=DejaVu Sans Mono for Powerline 6 | Transparency=off 7 | Term=xterm-256color 8 | /*Monokai theme*/ 9 | ForegroundColour=248,248,242 10 | BackgroundColour=39,40,34 11 | CursorColour=253,157,79 12 | Black=39,40,34 13 | BoldBlack=117,113,94 14 | Red=249,38,114 15 | BoldRed=204,6,78 16 | Green=166,226,46 17 | BoldGreen=122,172,24 18 | Yellow=244,191,117 19 | BoldYellow=240,169,69 20 | Blue=102,217,239 21 | BoldBlue=33,199,233 22 | Magenta=174,129,255 23 | BoldMagenta=126,51,255 24 | Cyan=161,239,228 25 | BoldCyan=95,227,210 26 | White=248,248,242 27 | BoldWhite=249,248,245 28 | CursorType=block 29 | CursorBlinks=yes 30 | ComposeKey=off 31 | -------------------------------------------------------------------------------- /docs/snapshots/git_log.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ray-g/devstrap/78eab9eec786778e6ccb80239fc66c984f62ae59/docs/snapshots/git_log.PNG -------------------------------------------------------------------------------- /docs/snapshots/installing.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ray-g/devstrap/78eab9eec786778e6ccb80239fc66c984f62ae59/docs/snapshots/installing.PNG -------------------------------------------------------------------------------- /docs/snapshots/layout.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ray-g/devstrap/78eab9eec786778e6ccb80239fc66c984f62ae59/docs/snapshots/layout.PNG -------------------------------------------------------------------------------- /docs/snapshots/package_box.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ray-g/devstrap/78eab9eec786778e6ccb80239fc66c984f62ae59/docs/snapshots/package_box.PNG -------------------------------------------------------------------------------- /dotfiles/aliases: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Devstrap Upgrade Related 4 | alias upgrade_devstrap_noreload='[ -d ~/.devstrap ] && cd ~/.devstrap && git pull --rebase --stat origin master && cd - >/dev/null' 5 | alias upgrade_devstrap='upgrade_devstrap_noreload && reload' 6 | alias upgrade_emacs='[ -d ~/.emacs.d ] && cd ~/.emacs.d && git pull --rebase --stat origin master && cd - >/dev/null' 7 | alias upgrade_omt='[ -d ~/.tmux ] && cd ~/.tmux && git pull --rebase --stat origin master && cd - >/dev/null' 8 | alias upgrade_system='sudo apt-get update -y && sudo apt-get upgrade -y && sudo apt-get autoremove -y && sudo apt-get autoclean -y' 9 | alias upgrade_all='sudo -v &> /dev/null && upgrade_devstrap_noreload && upgrade_emacs && upgrade_omt && upgrade_system' 10 | 11 | # Shortcuts 12 | alias dl="cd ~/Downloads" 13 | alias dt="cd ~/Desktop" 14 | alias p="cd ~/projects" 15 | alias g="git" 16 | alias h="history" 17 | alias j="jobs" 18 | alias aa='ag --ignore "*.[js|cache|tpm|log]*"' 19 | alias a='ag' 20 | alias e='emacsclient -n' 21 | alias stracef='strace -e trace=file' 22 | alias cls='clear' 23 | alias lns='ln -s' 24 | alias tf='tail -f' 25 | alias cl='cdl' 26 | alias dfh='df -h' 27 | alias duh='du -h' 28 | alias dsh='du -sh *' 29 | alias wl='wc -l' 30 | alias cldiff='colordiff' 31 | alias deltree='rm -rf' 32 | alias f='find ./ -iname' 33 | alias ff='find ./ -iname' 34 | alias lg='ls -al | grep' 35 | alias fstab='cat /etc/fstab' 36 | alias findapp='ps aux | grep -i' 37 | alias killapp='sudo kill -9' 38 | alias qrpm='rpm -qa | grep' 39 | 40 | # directories 41 | alias cds='echo "`pwd`" > ~/.cdsave' 42 | alias cdb='cd "`cat ~/.cdsave`"' 43 | 44 | # env editor 45 | alias envzshconf='$EDITOR ~/.zshrc' 46 | alias envpath='$EDITOR ~/.path' 47 | alias envexports='$EDITOR ~/.exports' 48 | alias envalias='$EDITOR ~/.aliases' 49 | alias envfunc='$EDITOR ~/.functions' 50 | 51 | # List all files colorized in long format 52 | alias lf="ls -lF" 53 | 54 | # List all files colorized in long format, including dot files 55 | alias laf="ls -laF" 56 | 57 | # List only directories 58 | alias lsd="ls -lF | grep --color=never '^d'" 59 | 60 | # List only links 61 | alias lsl="ls -lah | grep --color=never '^l'" 62 | 63 | # Always enable colored `grep` output 64 | # Note: `GREP_OPTIONS="--color=auto"` is deprecated, hence the alias usage. 65 | alias grep='grep --color=auto' 66 | alias fgrep='fgrep --color=auto' 67 | alias egrep='egrep --color=auto' 68 | 69 | # Enable aliases to be sudo’ed 70 | alias sudo='sudo ' 71 | 72 | # Get week number 73 | alias week='date +%V' 74 | 75 | # Stopwatch 76 | alias timer='echo "Timer started. Stop with Ctrl-D." && date && time cat && date' 77 | 78 | # Get macOS Software Updates, and update installed Ruby gems, Homebrew, npm, and their installed packages 79 | # Mac 80 | # alias update='sudo softwareupdate -i -a; brew update; brew upgrade; brew cleanup; npm install npm -g; npm update -g; sudo gem update --system; sudo gem update; sudo gem cleanup' 81 | 82 | # Google Chrome 83 | # Mac 84 | # alias chrome='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome' 85 | 86 | # IP addresses 87 | # alias ip="dig +short myip.opendns.com @resolver1.opendns.com" 88 | # alias localip="ipconfig getifaddr en0" 89 | alias ips="ifconfig -a | grep -o 'inet6\? \(addr:\)\?\s\?\(\(\([0-9]\+\.\)\{3\}[0-9]\+\)\|[a-fA-F0-9:]\+\)' | awk '{ sub(/inet6? (addr:)? ?/, \"\"); print }'" 90 | 91 | # Show active network interfaces 92 | alias ifactive="ifconfig | pcregrep -M -o '^[^\t:]+:([^\n]|\n\t)*status: active'" 93 | 94 | # Flush Directory Service cache 95 | alias flush="dscacheutil -flushcache && killall -HUP mDNSResponder" 96 | 97 | # Clean up LaunchServices to remove duplicates in the “Open With” menu 98 | # Mac 99 | # alias lscleanup="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user && killall Finder" 100 | 101 | # View HTTP traffic 102 | alias sniff="sudo ngrep -d 'en1' -t '^(GET|POST) ' 'tcp and port 80'" 103 | alias httpdump="sudo tcpdump -i en1 -n -s 0 -w - | grep -a -o -E \"Host\: .*|GET \/.*\"" 104 | 105 | # Canonical hex dump; some systems have this symlinked 106 | command -v hd > /dev/null || alias hd="hexdump -C" 107 | 108 | # macOS has no `md5sum`, so use `md5` as a fallback 109 | command -v md5sum > /dev/null || alias md5sum="md5" 110 | 111 | # macOS has no `sha1sum`, so use `shasum` as a fallback 112 | command -v sha1sum > /dev/null || alias sha1sum="shasum" 113 | 114 | # JavaScriptCore REPL 115 | # Mac 116 | # jscbin="/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc"; 117 | # [ -e "${jscbin}" ] && alias jsc="${jscbin}"; 118 | # unset jscbin; 119 | 120 | # Trim new lines and copy to clipboard 121 | alias c="tr -d '\n' | pbcopy" 122 | 123 | # Recursively delete `.DS_Store` files 124 | alias cleanup="find . -type f -name '*.DS_Store' -ls -delete" 125 | 126 | # Empty the Trash on all mounted volumes and the main HDD. 127 | # Also, clear Apple’s System Logs to improve shell startup speed. 128 | # Finally, clear download history from quarantine. https://mths.be/bum 129 | alias emptytrash="sudo rm -rfv /Volumes/*/.Trashes; sudo rm -rfv ~/.Trash; sudo rm -rfv /private/var/log/asl/*.asl; sqlite3 ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV* 'delete from LSQuarantineEvent'" 130 | 131 | # Show/hide hidden files in Finder 132 | alias show="defaults write com.apple.finder AppleShowAllFiles -bool true && killall Finder" 133 | alias hide="defaults write com.apple.finder AppleShowAllFiles -bool false && killall Finder" 134 | 135 | # Hide/show all desktop icons (useful when presenting) 136 | alias hidedesktop="defaults write com.apple.finder CreateDesktop -bool false && killall Finder" 137 | alias showdesktop="defaults write com.apple.finder CreateDesktop -bool true && killall Finder" 138 | 139 | # URL-encode strings 140 | alias urlencode='python -c "import sys, urllib.parse as ul; print(ul.quote_plus(sys.argv[1]));"' 141 | 142 | # Merge PDF files 143 | # Usage: `mergepdf -o output.pdf input{1,2,3}.pdf` 144 | # Mac 145 | # alias mergepdf='/System/Library/Automator/Combine\ PDF\ Pages.action/Contents/Resources/join.py' 146 | 147 | # Disable Spotlight 148 | alias spotoff="sudo mdutil -a -i off" 149 | # Enable Spotlight 150 | alias spoton="sudo mdutil -a -i on" 151 | 152 | # PlistBuddy alias, because sometimes `defaults` just doesn’t cut it 153 | alias plistbuddy="/usr/libexec/PlistBuddy" 154 | 155 | # Airport CLI alias 156 | # Mac 157 | # alias airport='/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport' 158 | 159 | # Ring the terminal bell, and put a badge on Terminal.app’s Dock icon 160 | # (useful when executing time-consuming commands) 161 | alias badge="tput bel" 162 | 163 | # Intuitive map function 164 | # For example, to list all directories that contain a certain file: 165 | # find . -name .gitattributes | map dirname 166 | alias map="xargs -n1" 167 | 168 | # One of @janmoesen’s ProTip™s 169 | for method in GET HEAD POST PUT DELETE TRACE OPTIONS; do 170 | alias "$method"="lwp-request -m '$method'" 171 | done 172 | 173 | # Make Grunt print stack traces by default 174 | command -v grunt > /dev/null && alias grunt="grunt --stack" 175 | 176 | # Stuff I never really use but cannot delete either because of http://xkcd.com/530/ 177 | alias stfu="osascript -e 'set volume output muted true'" 178 | alias pumpitup="osascript -e 'set volume output volume 100'" 179 | 180 | # Kill all the tabs in Chrome to free up memory 181 | # [C] explained: http://www.commandlinefu.com/commands/view/402/exclude-grep-from-your-grepped-output-of-ps-alias-included-in-description 182 | alias chromekill="ps ux | grep '[C]hrome Helper --type=renderer' | grep -v extension-process | tr -s ' ' | cut -d ' ' -f2 | xargs kill" 183 | 184 | # Lock the screen (when going AFK) 185 | # Mac 186 | # alias afk="/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend" 187 | alias afk="systemctl suspend" 188 | 189 | # Reload the shell (i.e. invoke as a login shell) 190 | alias reload="exec $SHELL -l" 191 | 192 | # Print each PATH entry on a separate line 193 | alias path='echo -e ${PATH//:/\\n}' 194 | 195 | # Alias for Emacs 196 | alias rmelc='rm -f ~/.emacs.d/lisp/*.elc' 197 | alias restart_emacs='emacsclient -e "(let ((last-nonmenu-event nil) (kill-emacs-query-functions nil)) (save-buffers-kill-emacs t))" && te' 198 | 199 | # bind P and N for EMACS mode 200 | # bindkey -M emacs '^P' history-substring-search-up 201 | # bindkey -M emacs '^N' history-substring-search-down 202 | 203 | # nvdia 204 | alias watchnv='watch -n1 nvidia-smi' 205 | 206 | # RSync related 207 | alias rsyncto='rsync -rlhtvzP' 208 | alias rsyncback='rsync -aAXv' 209 | alias rsyncsync='rsync -aAXv --delete' 210 | -------------------------------------------------------------------------------- /dotfiles/completion.zsh: -------------------------------------------------------------------------------- 1 | # 2 | # Completion enhancements 3 | # 4 | 5 | # 6 | # zsh options 7 | # 8 | 9 | # If a completion is performed with the cursor within a word, and a full completion is inserted, 10 | # the cursor is moved to the end of the word 11 | setopt ALWAYS_TO_END 12 | 13 | # Automatically use menu completion after the second consecutive request for completion 14 | setopt AUTO_MENU 15 | 16 | # Automatically list choices on an ambiguous completion. 17 | setopt AUTO_LIST 18 | 19 | # Perform a path search even on command names with slashes in them. 20 | setopt PATH_DIRS 21 | 22 | # Make globbing (filename generation) sensitive to case. 23 | unsetopt CASE_GLOB 24 | 25 | # On an ambiguous completion, instead of listing possibilities or beeping, insert the first match immediately. 26 | # Then when completion is requested again, remove the first match and insert the second match, etc. 27 | unsetopt MENU_COMPLETE 28 | 29 | 30 | # 31 | # completion module options 32 | # 33 | 34 | # group matches and describe. 35 | zstyle ':completion:*:*:*:*:*' menu select 36 | zstyle ':completion:*:matches' group 'yes' 37 | zstyle ':completion:*:options' description 'yes' 38 | zstyle ':completion:*:options' auto-description '%d' 39 | zstyle ':completion:*:corrections' format ' %F{green}-- %d (errors: %e) --%f' 40 | zstyle ':completion:*:descriptions' format ' %F{yellow}-- %d --%f' 41 | zstyle ':completion:*:messages' format ' %F{purple} -- %d --%f' 42 | zstyle ':completion:*:warnings' format ' %F{red}-- no matches found --%f' 43 | zstyle ':completion:*:default' list-prompt '%S%M matches%s' 44 | zstyle ':completion:*' format ' %F{yellow}-- %d --%f' 45 | zstyle ':completion:*' group-name '' 46 | zstyle ':completion:*' verbose yes 47 | 48 | # Directories 49 | zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS} 50 | zstyle ':completion:*:*:cd:*' tag-order local-directories directory-stack path-directories 51 | zstyle ':completion:*:*:cd:*:directory-stack' menu yes select 52 | zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand' 53 | zstyle ':completion:*' squeeze-slashes true 54 | 55 | # Ignore useless commands and functions 56 | zstyle ':completion:*:functions' ignored-patterns '(_*|pre(cmd|exec)|prompt_*)' 57 | 58 | # Completion sorting 59 | zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters 60 | 61 | # Man 62 | zstyle ':completion:*:manuals' separate-sections true 63 | zstyle ':completion:*:manuals.(^1*)' insert-sections true 64 | 65 | # History 66 | zstyle ':completion:*:history-words' stop yes 67 | zstyle ':completion:*:history-words' remove-all-dups yes 68 | zstyle ':completion:*:history-words' list false 69 | zstyle ':completion:*:history-words' menu yes 70 | 71 | # ignore multiple entries. 72 | zstyle ':completion:*:(rm|kill|diff):*' ignore-line other 73 | zstyle ':completion:*:rm:*' file-patterns '*:all-files' 74 | 75 | # Environmental Variables 76 | zstyle ':completion::*:(-command-|export):*' fake-parameters ${${${_comps[(I)-value-*]#*,}%%,*}:#-*-} 77 | 78 | # Kill 79 | zstyle ':completion:*:*:*:*:processes' command 'ps -u $LOGNAME -o pid,user,command -w' 80 | zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;36=0=01' 81 | zstyle ':completion:*:*:kill:*' menu yes select 82 | zstyle ':completion:*:*:kill:*' force-list always 83 | zstyle ':completion:*:*:kill:*' insert-ids single 84 | 85 | # SSH/SCP/RSYNC 86 | zstyle ':completion:*:(ssh|scp|rsync):*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *' 87 | zstyle ':completion:*:(scp|rsync):*' group-order users files all-files hosts-domain hosts-host hosts-ipaddr 88 | zstyle ':completion:*:ssh:*' group-order users hosts-domain hosts-host users hosts-ipaddr 89 | zstyle ':completion:*:(ssh|scp|rsync):*:hosts-host' ignored-patterns '*(.|:)*' loopback ip6-loopback localhost ip6-localhost broadcasthost 90 | zstyle ':completion:*:(ssh|scp|rsync):*:hosts-domain' ignored-patterns '<->.<->.<->.<->' '^[-[:alnum:]]##(.[-[:alnum:]]##)##' '*@*' 91 | zstyle ':completion:*:(ssh|scp|rsync):*:hosts-ipaddr' ignored-patterns '^(<->.<->.<->.<->|(|::)([[:xdigit:].]##:(#c,2))##(|%*))' '127.0.0.<->' '255.255.255.255' '::1' 'fe80::*' 92 | 93 | # Media Players 94 | zstyle ':completion:*:*:mpg123:*' file-patterns '*.(mp3|MP3):mp3\ files *(-/):directories' 95 | zstyle ':completion:*:*:mpg321:*' file-patterns '*.(mp3|MP3):mp3\ files *(-/):directories' 96 | zstyle ':completion:*:*:ogg123:*' file-patterns '*.(ogg|OGG|flac):ogg\ files *(-/):directories' 97 | zstyle ':completion:*:*:mocp:*' file-patterns '*.(wav|WAV|mp3|MP3|ogg|OGG|flac):ogg\ files *(-/):directories' 98 | -------------------------------------------------------------------------------- /dotfiles/editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /dotfiles/exports: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Enable persistent REPL history for `node`. 4 | export NODE_REPL_HISTORY=~/.node_history; 5 | # Allow 32³ entries; the default is 1000. 6 | export NODE_REPL_HISTORY_SIZE='32768'; 7 | # Use sloppy mode by default, matching web browsers. 8 | export NODE_REPL_MODE='sloppy'; 9 | 10 | # Make Python use UTF-8 encoding for output to stdin, stdout, and stderr. 11 | export PYTHONIOENCODING='UTF-8'; 12 | 13 | # Increase Bash history size. Allow 32³ entries; the default is 500. 14 | export HISTSIZE='32768'; 15 | export HISTFILESIZE="${HISTSIZE}"; 16 | # Omit duplicates and commands that begin with a space from history. 17 | export HISTCONTROL='ignoreboth'; 18 | 19 | # Highlight section titles in manual pages. 20 | export LESS_TERMCAP_md="${yellow}"; 21 | 22 | # Don’t clear the screen after quitting a manual page. 23 | export MANPAGER='less -X'; 24 | -------------------------------------------------------------------------------- /dotfiles/functions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Change directory and list files 4 | function cdl() 5 | { 6 | if [ -d "$@" ]; then 7 | cd "$@" && pwd ; ls; 8 | else 9 | echo "$@ doesn't exists." 10 | fi 11 | } 12 | 13 | function chpwd() 14 | { 15 | if [[ $OSTYPE == linux* ]]; then 16 | ls --color=auto; 17 | elif [[ $OSTYPE == darwin* ]]; then 18 | ls -G 19 | else 20 | ls 21 | fi 22 | } 23 | 24 | # Create a new directory and enter it 25 | function mkd() { 26 | mkdir -p "$@" && cd "$_"; 27 | } 28 | 29 | # Change working directory to the top-most Finder window location 30 | function cdf() { # short for `cdfinder` 31 | cd "$(osascript -e 'tell app "Finder" to POSIX path of (insertion location as alias)')"; 32 | } 33 | 34 | # Create a .tar.gz archive, using `zopfli`, `pigz` or `gzip` for compression 35 | function targz() { 36 | local tmpFile="${@%/}.tar"; 37 | tar -cvf "${tmpFile}" --exclude=".DS_Store" "${@}" || return 1; 38 | 39 | size=$( 40 | stat -f"%z" "${tmpFile}" 2> /dev/null; # macOS `stat` 41 | stat -c"%s" "${tmpFile}" 2> /dev/null; # GNU `stat` 42 | ); 43 | 44 | local cmd=""; 45 | if (( size < 52428800 )) && hash zopfli 2> /dev/null; then 46 | # the .tar file is smaller than 50 MB and Zopfli is available; use it 47 | cmd="zopfli"; 48 | else 49 | if hash pigz 2> /dev/null; then 50 | cmd="pigz"; 51 | else 52 | cmd="gzip"; 53 | fi; 54 | fi; 55 | 56 | echo "Compressing .tar ($((size / 1000)) kB) using \`${cmd}\`…"; 57 | "${cmd}" -v "${tmpFile}" || return 1; 58 | [ -f "${tmpFile}" ] && rm "${tmpFile}"; 59 | 60 | zippedSize=$( 61 | stat -f"%z" "${tmpFile}.gz" 2> /dev/null; # macOS `stat` 62 | stat -c"%s" "${tmpFile}.gz" 2> /dev/null; # GNU `stat` 63 | ); 64 | 65 | echo "${tmpFile}.gz ($((zippedSize / 1000)) kB) created successfully."; 66 | } 67 | 68 | # Determine size of a file or total size of a directory 69 | function fs() { 70 | if du -b /dev/null > /dev/null 2>&1; then 71 | local arg=-sbh; 72 | else 73 | local arg=-sh; 74 | fi 75 | if [[ -n "$@" ]]; then 76 | du $arg -- "$@"; 77 | else 78 | du $arg .[^.]* ./*; 79 | fi; 80 | } 81 | 82 | # Use Git’s colored diff when available 83 | hash git &>/dev/null; 84 | if [ $? -eq 0 ]; then 85 | function diff() { 86 | git diff --no-index --color-words "$@"; 87 | } 88 | fi; 89 | 90 | # Create a data URL from a file 91 | function dataurl() { 92 | local mimeType=$(file -b --mime-type "$1"); 93 | if [[ $mimeType == text/* ]]; then 94 | mimeType="${mimeType};charset=utf-8"; 95 | fi 96 | echo "data:${mimeType};base64,$(openssl base64 -in "$1" | tr -d '\n')"; 97 | } 98 | 99 | # Create a git.io short URL 100 | function gitio() { 101 | if [ -z "${1}" -o -z "${2}" ]; then 102 | echo "Usage: \`gitio slug url\`"; 103 | return 1; 104 | fi; 105 | curl -i https://git.io/ -F "url=${2}" -F "code=${1}"; 106 | } 107 | 108 | # Start an HTTP server from a directory, optionally specifying the port 109 | function server() { 110 | local port="${1:-8000}"; 111 | sleep 1 && open "http://localhost:${port}/" & 112 | # Set the default Content-Type to `text/plain` instead of `application/octet-stream` 113 | # And serve everything as UTF-8 (although not technically correct, this doesn’t break anything for binary files) 114 | python -c $'import SimpleHTTPServer;\nmap = SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map;\nmap[""] = "text/plain";\nfor key, value in map.items():\n\tmap[key] = value + ";charset=UTF-8";\nSimpleHTTPServer.test();' "$port"; 115 | } 116 | 117 | # Start a PHP server from a directory, optionally specifying the port 118 | # (Requires PHP 5.4.0+.) 119 | function phpserver() { 120 | local port="${1:-4000}"; 121 | local ip=$(ipconfig getifaddr en1); 122 | sleep 1 && open "http://${ip}:${port}/" & 123 | php -S "${ip}:${port}"; 124 | } 125 | 126 | # Compare original and gzipped file size 127 | function gz() { 128 | local origsize=$(wc -c < "$1"); 129 | local gzipsize=$(gzip -c "$1" | wc -c); 130 | local ratio=$(echo "$gzipsize * 100 / $origsize" | bc -l); 131 | printf "orig: %d bytes\n" "$origsize"; 132 | printf "gzip: %d bytes (%2.2f%%)\n" "$gzipsize" "$ratio"; 133 | } 134 | 135 | # Syntax-highlight JSON strings or files 136 | # Usage: `json '{"foo":42}'` or `echo '{"foo":42}' | json` 137 | function json() { 138 | if [ -t 0 ]; then # argument 139 | python -mjson.tool <<< "$*" | pygmentize -l javascript; 140 | else # pipe 141 | python -mjson.tool | pygmentize -l javascript; 142 | fi; 143 | } 144 | 145 | # Run `dig` and display the most useful info 146 | function digga() { 147 | dig +nocmd "$1" any +multiline +noall +answer; 148 | } 149 | 150 | # UTF-8-encode a string of Unicode symbols 151 | function escape() { 152 | printf "\\\x%s" $(printf "$@" | xxd -p -c1 -u); 153 | # print a newline unless we’re piping the output to another program 154 | if [ -t 1 ]; then 155 | echo ""; # newline 156 | fi; 157 | } 158 | 159 | # Decode \x{ABCD}-style Unicode escape sequences 160 | function unidecode() { 161 | perl -e "binmode(STDOUT, ':utf8'); print \"$@\""; 162 | # print a newline unless we’re piping the output to another program 163 | if [ -t 1 ]; then 164 | echo ""; # newline 165 | fi; 166 | } 167 | 168 | # Get a character’s Unicode code point 169 | function codepoint() { 170 | perl -e "use utf8; print sprintf('U+%04X', ord(\"$@\"))"; 171 | # print a newline unless we’re piping the output to another program 172 | if [ -t 1 ]; then 173 | echo ""; # newline 174 | fi; 175 | } 176 | 177 | # Show all the names (CNs and SANs) listed in the SSL certificate 178 | # for a given domain 179 | function getcertnames() { 180 | if [ -z "${1}" ]; then 181 | echo "ERROR: No domain specified."; 182 | return 1; 183 | fi; 184 | 185 | local domain="${1}"; 186 | echo "Testing ${domain}…"; 187 | echo ""; # newline 188 | 189 | local tmp=$(echo -e "GET / HTTP/1.0\nEOT" \ 190 | | openssl s_client -connect "${domain}:443" -servername "${domain}" 2>&1); 191 | 192 | if [[ "${tmp}" = *"-----BEGIN CERTIFICATE-----"* ]]; then 193 | local certText=$(echo "${tmp}" \ 194 | | openssl x509 -text -certopt "no_aux, no_header, no_issuer, no_pubkey, \ 195 | no_serial, no_sigdump, no_signame, no_validity, no_version"); 196 | echo "Common Name:"; 197 | echo ""; # newline 198 | echo "${certText}" | grep "Subject:" | sed -e "s/^.*CN=//" | sed -e "s/\/emailAddress=.*//"; 199 | echo ""; # newline 200 | echo "Subject Alternative Name(s):"; 201 | echo ""; # newline 202 | echo "${certText}" | grep -A 1 "Subject Alternative Name:" \ 203 | | sed -e "2s/DNS://g" -e "s/ //g" | tr "," "\n" | tail -n +2; 204 | return 0; 205 | else 206 | echo "ERROR: Certificate not found."; 207 | return 1; 208 | fi; 209 | } 210 | 211 | # `s` with no arguments opens the current directory in Sublime Text, otherwise 212 | # opens the given location 213 | function s() { 214 | if [ $# -eq 0 ]; then 215 | subl .; 216 | else 217 | subl "$@"; 218 | fi; 219 | } 220 | 221 | # `a` with no arguments opens the current directory in Atom Editor, otherwise 222 | # opens the given location 223 | function a() { 224 | if [ $# -eq 0 ]; then 225 | atom .; 226 | else 227 | atom "$@"; 228 | fi; 229 | } 230 | 231 | # `v` with no arguments opens the current directory in Vim, otherwise opens the 232 | # given location 233 | function v() { 234 | if [ $# -eq 0 ]; then 235 | vim .; 236 | else 237 | vim "$@"; 238 | fi; 239 | } 240 | 241 | # `o` with no arguments opens the current directory, otherwise opens the given 242 | # location 243 | function o() { 244 | if [ $# -eq 0 ]; then 245 | open .; 246 | else 247 | open "$@"; 248 | fi; 249 | } 250 | 251 | # `c` with no arguments opens the current directory in vscode, otherwise opens the 252 | # given location 253 | function c() { 254 | if [ $# -eq 0 ]; then 255 | code .; 256 | else 257 | code "$@"; 258 | fi; 259 | } 260 | 261 | # `tre` is a shorthand for `tree` with hidden files and color enabled, ignoring 262 | # the `.git` directory, listing directories first. The output gets piped into 263 | # `less` with options to preserve color and line numbers, unless the output is 264 | # small enough for one screen. 265 | function tre() { 266 | tree -aC -I '.git|node_modules|bower_components' --dirsfirst "$@" | less -FRNX; 267 | } 268 | 269 | # Extract files 270 | function unpkg() 271 | { 272 | if [ -z "$1" ]; then 273 | # display usage if no parameters given 274 | echo "Usage: extract ." 275 | else 276 | if [ -f $1 ] ; then 277 | # NAME=${1%.*} 278 | # mkdir $NAME && cd $NAME 279 | case $1 in 280 | *.tar.bz2) tar xvjf $1 ;; 281 | *.tar.gz) tar xvzf $1 ;; 282 | *.tar.xz) tar xvJf $1 ;; 283 | *.lzma) unlzma $1 ;; 284 | *.bz2) bunzip2 $1 ;; 285 | *.rar) unrar x -ad $1 ;; 286 | *.gz) gunzip $1 ;; 287 | *.tar) tar xvf $1 ;; 288 | *.tbz2) tar xvjf $1 ;; 289 | *.tgz) tar xvzf $1 ;; 290 | *.zip) unzip $1 ;; 291 | *.Z) uncompress $1 ;; 292 | *.7z) 7z x $1 ;; 293 | *.xz) unxz $1 ;; 294 | *.exe) cabextract $1 ;; 295 | *) echo "extract: '$1' - unknown archive method" ;; 296 | esac 297 | else 298 | echo "$1 - file does not exist" 299 | fi 300 | fi 301 | } 302 | 303 | # Go test and show coverage 304 | function gotest() { 305 | cached="" 306 | if [[ $1 == "-nocache" ]]; then 307 | cached="-count=1" 308 | shift 309 | fi 310 | if [ -z $1 ]; then 311 | go test ${cached} -cover -race ./... 312 | elif [ $1 = "-t" ]; then 313 | go test ${cached} -cover -race ./... | column -t 314 | elif [ $1 = "." ]; then 315 | go test ${cached} -v -race -coverprofile=profile.out -covermode=atomic 316 | elif [ $1 = "./..." ]; then 317 | echo 'mode: atomic' > profile.out 318 | go list ./... | xargs -I {} sh -c "go test ${cached} -race -coverprofile=profile.out.tmp -covermode=atomic {}; cat profile.out.tmp | tail -n +2 >> profile.out; rm profile.out.tmp" 319 | else 320 | go list ./... | grep --color=never $1 | xargs go test ${cached} -v -race -coverprofile=profile.out -covermode=atomic 321 | fi 322 | local exitCode=$? 323 | if [ -f profile.out ]; then 324 | go tool cover -func=profile.out 325 | rm profile.out 326 | fi 327 | return $exitCode 328 | } 329 | 330 | function gotestcov() { 331 | go list ./... | grep --color=never $1 | xargs go test -count=1 -v -race -coverprofile=profile.out -covermode=atomic 332 | local exitCode=$? 333 | if [ -f profile.out ]; then 334 | go tool cover -func=profile.out 335 | go tool cover -html=profile.out 336 | rm profile.out 337 | fi 338 | return $exitCode 339 | } 340 | 341 | function gobench() { 342 | local target="" 343 | if [ ! -z $1 ]; then 344 | target=./$1 345 | fi 346 | # go test -bench=${foo} -benchmem ./... 2>/dev/null | grep Benchmark | column -t 347 | go test -count=1 -benchmem -bench=. $target 348 | } 349 | 350 | # E-Book Convert 351 | function epub2mobi() { 352 | if [ $# -eq 0 ]; then 353 | find . -name "*.epub" -exec ebook-convert {} {}.mobi \; 354 | else 355 | for epub in "$@"; do 356 | ebook-convert $epub ${epub}.mobi 357 | done 358 | fi 359 | find . -name "*.epub.mobi" -exec rename 's/\.epub\.mobi$/.mobi/' {} + 360 | } 361 | 362 | 363 | # List Docker Tags 364 | function dockertags() { 365 | if [ $# -lt 1 ]; then 366 | printf '%s\n' \ 367 | "dockertags -- list all tags for a Docker image on Docker Hub registry." \ 368 | "" \ 369 | "EXAMPLE: " \ 370 | " - list all tags for ubuntu:" \ 371 | " ${0} ubuntu" \ 372 | " - list all php tags containing apache:" \ 373 | " ${0} php apache" 374 | return 1 375 | fi 376 | 377 | image="$1" 378 | tags=`wget -q https://registry.hub.docker.com/v1/repositories/${image}/tags -O - | sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | tr '}' '\n' | awk -F: '{print $3}'` 379 | 380 | if [ -n "$2" ]; then 381 | tags=` echo "${tags}" | grep "$2" ` 382 | fi 383 | 384 | echo "${tags}" 385 | } 386 | 387 | # VirtualEnv shortcuts 388 | export VIRTUAL_ENV_PATH="${HOME}/.virtualenvs/" 389 | function venv3() { 390 | if [ $# -eq 0 ]; then 391 | if [ ! -z ${VIRTUAL_ENV} ]; then 392 | echo $(basename ${VIRTUAL_ENV}) 393 | fi 394 | return 0 395 | fi 396 | 397 | if [ $1 = "ls" ]; then 398 | ls $VIRTUAL_ENV_PATH 399 | return 0 400 | fi 401 | 402 | if [ $1 = "new" ]; then 403 | if [ ! -z $2 ]; then 404 | virtualenv -p python3 ${VIRTUAL_ENV_PATH}/$2 405 | fi 406 | else 407 | local ACTIVATE=${VIRTUAL_ENV_PATH}/$1/bin/activate 408 | if [ -f ${ACTIVATE} ]; then 409 | source ${ACTIVATE} 410 | else 411 | echo "$1 not exists" 412 | return 2 413 | fi 414 | fi 415 | } 416 | 417 | # Sync Git repo(s) of all direct subfolders 418 | function syncgits() { 419 | if [ -d .git ]; then 420 | git pull; 421 | else 422 | for entry in "."/* 423 | do 424 | if [[ -d "$entry" && -d "$entry/.git" ]]; then 425 | pushd "$entry" 426 | git pull 427 | popd 428 | fi 429 | done 430 | fi 431 | } 432 | -------------------------------------------------------------------------------- /dotfiles/gitconfig.devstrap: -------------------------------------------------------------------------------- 1 | [alias] 2 | 3 | # View abbreviated SHA, description, and history graph of the latest 20 commits 4 | l = log --pretty=oneline -n 20 --graph --abbrev-commit 5 | 6 | # View the current working tree status using the short format 7 | s = status -s 8 | 9 | # Show the diff between the latest commit and the current state 10 | d = !"git diff-index --quiet HEAD -- || clear; git --no-pager diff --patch-with-stat" 11 | 12 | # `git di $number` shows the diff between the state `$number` revisions ago and the current state 13 | di = !"d() { git diff --patch-with-stat HEAD~$1; }; git diff-index --quiet HEAD -- || clear; d" 14 | 15 | # Pull in remote changes for the current repository and all its submodules 16 | p = !"git pull; git submodule foreach git pull origin master" 17 | 18 | # Clone a repository including all submodules 19 | c = clone --recursive 20 | 21 | # Commit all changes 22 | ca = !git add -A && git commit -av 23 | 24 | # Switch to a branch, creating it if necessary 25 | go = "!f() { git checkout -b \"$1\" 2> /dev/null || git checkout \"$1\"; }; f" 26 | 27 | # Show verbose output about tags, branches or remotes 28 | tags = tag -l 29 | branches = branch -a 30 | remotes = remote -v 31 | 32 | # Amend the currently staged files to the latest commit 33 | amend = commit --amend --reuse-message=HEAD 34 | 35 | # Credit an author on the latest commit 36 | credit = "!f() { git commit --amend --author \"$1 <$2>\" -C HEAD; }; f" 37 | 38 | # Interactive rebase with the given number of latest commits 39 | reb = "!r() { git rebase -i HEAD~$1; }; r" 40 | 41 | # Remove the old tag with this name and tag the latest commit with it. 42 | retag = "!r() { git tag -d $1 && git push origin :refs/tags/$1 && git tag $1; }; r" 43 | 44 | # Find branches containing commit 45 | fb = "!f() { git branch -a --contains $1; }; f" 46 | 47 | # Find tags containing commit 48 | ft = "!f() { git describe --always --contains $1; }; f" 49 | 50 | # Find commits by source code 51 | fc = "!f() { git log --pretty=format:'%C(yellow)%h %Cblue%ad %Creset%s%Cgreen [%cn] %Cred%d' --decorate --date=short -S$1; }; f" 52 | 53 | # Find commits by commit message 54 | fm = "!f() { git log --pretty=format:'%C(yellow)%h %Cblue%ad %Creset%s%Cgreen [%cn] %Cred%d' --decorate --date=short --grep=$1; }; f" 55 | 56 | # Remove branches that have already been merged with master 57 | # a.k.a. ‘delete merged’ 58 | dm = "!git branch --merged | grep -v '\\*' | xargs -n 1 git branch -d" 59 | 60 | # List contributors with number of commits 61 | contributors = shortlog --summary --numbered 62 | 63 | # Merge GitHub pull request on top of the current branch or, 64 | # if a branch name is specified, on top of the specified branch 65 | mpr = "!f() { \ 66 | declare currentBranch=\"$(git symbolic-ref --short HEAD)\"; \ 67 | declare branch=\"${2:-$currentBranch}\"; \ 68 | if [ $(printf \"%s\" \"$1\" | grep '^[0-9]\\+$' > /dev/null; printf $?) -eq 0 ]; then \ 69 | git fetch origin refs/pull/$1/head:pr/$1 && \ 70 | git checkout -B $branch && \ 71 | git rebase $branch pr/$1 && \ 72 | git checkout -B $branch && \ 73 | git merge pr/$1 && \ 74 | git branch -D pr/$1 && \ 75 | git commit --amend -m \"$(git log -1 --pretty=%B)\n\nCloses #$1.\"; \ 76 | fi \ 77 | }; f" 78 | 79 | [apply] 80 | 81 | # Detect whitespace errors when applying a patch 82 | whitespace = fix 83 | 84 | [core] 85 | 86 | # Use custom `.gitignore` and `.gitattributes` 87 | excludesfile = ~/.gitignore 88 | attributesfile = ~/.gitattributes 89 | 90 | # Treat spaces before tabs and all kinds of trailing whitespace as an error 91 | # [default] trailing-space: looks for spaces at the end of a line 92 | # [default] space-before-tab: looks for spaces before tabs at the beginning of a line 93 | whitespace = space-before-tab,-indent-with-non-tab,trailing-space 94 | 95 | # Make `git rebase` safer on macOS 96 | # More info: 97 | trustctime = false 98 | 99 | # Prevent showing files whose names contain non-ASCII symbols as unversioned. 100 | # http://michael-kuehnel.de/git/2014/11/21/git-mac-osx-and-german-umlaute.html 101 | precomposeunicode = false 102 | 103 | [color] 104 | 105 | # Use colors in Git commands that are capable of colored output when 106 | # outputting to the terminal. (This is the default setting in Git ≥ 1.8.4.) 107 | ui = auto 108 | 109 | [color "branch"] 110 | 111 | current = yellow reverse 112 | local = yellow 113 | remote = green 114 | 115 | [color "diff"] 116 | 117 | meta = yellow bold 118 | frag = magenta bold # line info 119 | old = red # deletions 120 | new = green # additions 121 | 122 | [color "status"] 123 | 124 | added = yellow 125 | changed = green 126 | untracked = cyan 127 | 128 | # [commit] 129 | 130 | # https://help.github.com/articles/signing-commits-using-gpg/ 131 | # gpgsign = true 132 | 133 | [diff] 134 | 135 | # Detect copies as well as renames 136 | renames = copies 137 | 138 | [diff "bin"] 139 | 140 | # Use `hexdump` to diff binary files 141 | textconv = hexdump -v -C 142 | 143 | [help] 144 | 145 | # Automatically correct and execute mistyped commands 146 | autocorrect = 1 147 | 148 | [merge] 149 | 150 | # Include summaries of merged commits in newly created merge commit messages 151 | log = true 152 | 153 | [push] 154 | 155 | # Use the Git 1.x.x default to avoid errors on machines with old Git 156 | # installations. To use `simple` instead, add this to your `~/.extra` file: 157 | # `git config --global push.default simple`. See http://git.io/mMah-w. 158 | default = matching 159 | # Make `git push` push relevant annotated tags when pushing branches out. 160 | followTags = true 161 | 162 | # URL shorthands 163 | 164 | [url "git@github.com:"] 165 | 166 | insteadOf = "gh:" 167 | pushInsteadOf = "github:" 168 | pushInsteadOf = "git://github.com/" 169 | 170 | [url "git://github.com/"] 171 | 172 | insteadOf = "github:" 173 | 174 | [url "git@gist.github.com:"] 175 | 176 | insteadOf = "gst:" 177 | pushInsteadOf = "gist:" 178 | pushInsteadOf = "git://gist.github.com/" 179 | 180 | [url "git://gist.github.com/"] 181 | 182 | insteadOf = "gist:" 183 | 184 | [user] 185 | # Don't guess the user's identity. 186 | # https://github.com/git/git/blob/90f7b16b3adc78d4bbabbd426fb69aa78c714f71/Documentation/config.txt#L2847-L2855 187 | 188 | useConfigOnly = true 189 | -------------------------------------------------------------------------------- /dotfiles/gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Python files 2 | *.pyc 3 | 4 | # Folder view configuration files 5 | .DS_Store 6 | Desktop.ini 7 | 8 | # Thumbnail cache files 9 | ._* 10 | Thumbs.db 11 | 12 | # Files that might appear on external disks 13 | .Spotlight-V100 14 | .Trashes -------------------------------------------------------------------------------- /dotfiles/hgignore: -------------------------------------------------------------------------------- 1 | # Use shell-style glob syntax 2 | syntax: glob 3 | 4 | # Compiled Python files 5 | *.pyc 6 | 7 | # Folder view configuration files 8 | .DS_Store 9 | Desktop.ini 10 | 11 | # Thumbnail cache files 12 | ._* 13 | Thumbs.db 14 | 15 | # Files that might appear on external disks 16 | .Spotlight-V100 17 | .Trashes -------------------------------------------------------------------------------- /dotfiles/irbrc: -------------------------------------------------------------------------------- 1 | require 'pry' 2 | Pry.start 3 | exit 4 | -------------------------------------------------------------------------------- /dotfiles/path: -------------------------------------------------------------------------------- 1 | # -*- mode: shell-script; -*- 2 | # vim: ft=shell: sw=2: 3 | 4 | ################################################################# 5 | # PATH Environments 6 | ################################################################# 7 | 8 | # 9 | # Copied from .zshrc. Initialize PATH 10 | # 11 | export PATH="${HOME}/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11" 12 | 13 | # 14 | # Go Lang Environment Variables 15 | # 16 | export GO_HOME=/usr/local/go 17 | export PATH=${GO_HOME}/bin:$PATH 18 | # GOPATH_ROOT=${HOME}/.gopath 19 | # GOPATH_CACHE=${GOPATH_ROOT}/cache 20 | # GOPATH_PKGS=${GOPATH_ROOT}/pkgs 21 | # GOPATH_PROJECTS=${HOME}/projects/go_projects 22 | # export GOPATH=$GOPATH_CACHE:$GOPATH_PKGS:$GOPATH_PROJECTS 23 | export GOPATH=${HOME}/.go 24 | export PATH=$PATH:${GOPATH//://bin:}/bin 25 | # alias gocachesync='cp -rfp ${GOPATH_CACHE}/* ${GOPATH_PKGS}/' 26 | # alias gocacheclean='[ -d "$GOPATH_CACHE" ] && rm -rf ${GOPATH_CACHE}/*' 27 | # alias gocachecleansrc='[ -d "$GOPATH_CACHE" ] && rm -rf ${GOPATH_CACHE}/src/* && rm -rf ${GOPATH_CACHE}/pkg/*' 28 | # alias gocachelist='ls -lah "${GOPATH_CACHE}/bin"' 29 | # alias gopkgslist='ls -lah "${GOPATH_PKGS}/bin"' 30 | # alias gopathlist='echo -e ${GOPATH//:/\\n}' 31 | alias goapplist="ls -lah ${GOPATH}/bin" 32 | 33 | # 34 | # Rust-Lang Environment Variables 35 | # 36 | RUST_CARGO_BIN=${HOME}/.cargo/bin 37 | export PATH=${PATH}:${RUST_CARGO_BIN} 38 | 39 | # 40 | # Add /sbin folder to PATH 41 | # 42 | export PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin 43 | -------------------------------------------------------------------------------- /dotfiles/tmux.conf.local: -------------------------------------------------------------------------------- 1 | # https://github.com/gpakosz/.tmux 2 | # (‑●‑●)> released under the WTFPL v2 license, by Gregory Pakosz (@gpakosz) 3 | 4 | 5 | # -- navigation ---------------------------------------------------------------- 6 | 7 | # if you're running tmux within iTerm2 8 | # - and tmux is 1.9 or 1.9a 9 | # - and iTerm2 is configured to let option key act as +Esc 10 | # - and iTerm2 is configured to send [1;9A -> [1;9D for option + arrow keys 11 | # then uncomment the following line to make Meta + arrow keys mapping work 12 | #set -ga terminal-overrides "*:kUP3=\e[1;9A,*:kDN3=\e[1;9B,*:kRIT3=\e[1;9C,*:kLFT3=\e[1;9D" 13 | 14 | 15 | # -- windows & pane creation --------------------------------------------------- 16 | 17 | # new window retains current path, possible values are: 18 | # - true 19 | # - false (default) 20 | tmux_conf_new_window_retain_current_path=false 21 | 22 | # new pane retains current path, possible values are: 23 | # - true (default) 24 | # - false 25 | tmux_conf_new_pane_retain_current_path=true 26 | 27 | # new pane tries to reconnect ssh sessions (experimental), possible values are: 28 | # - true 29 | # - false (default) 30 | tmux_conf_new_pane_reconnect_ssh=false 31 | 32 | # prompt for session name when creating a new session, possible values are: 33 | # - true 34 | # - false (default) 35 | tmux_conf_new_session_prompt=false 36 | 37 | 38 | # -- display ------------------------------------------------------------------- 39 | 40 | # RGB 24-bit colour support (since tmux 2.2), possible values are: 41 | # - true 42 | # - false (default) 43 | tmux_conf_theme_24b_colour=false 44 | 45 | # window style 46 | tmux_conf_theme_window_fg='default' 47 | tmux_conf_theme_window_bg='default' 48 | 49 | # highlight focused pane (tmux 2.1+), possible values are: 50 | # - true 51 | # - false (default) 52 | tmux_conf_theme_highlight_focused_pane=false 53 | 54 | # focused pane colours: 55 | tmux_conf_theme_focused_pane_fg='default' 56 | tmux_conf_theme_focused_pane_bg='#0087d7' # light blue 57 | 58 | # pane border style, possible values are: 59 | # - thin (default) 60 | # - fat 61 | tmux_conf_theme_pane_border_style=thin 62 | 63 | # pane borders colours: 64 | tmux_conf_theme_pane_border='#444444' # gray 65 | tmux_conf_theme_pane_active_border='#00afff' # light blue 66 | 67 | # pane indicator colours 68 | tmux_conf_theme_pane_indicator='#00afff' # light blue 69 | tmux_conf_theme_pane_active_indicator='#00afff' # light blue 70 | 71 | # status line style 72 | tmux_conf_theme_message_fg='#000000' # black 73 | tmux_conf_theme_message_bg='#ffff00' # yellow 74 | tmux_conf_theme_message_attr='bold' 75 | 76 | # status line command style ( : Escape) 77 | tmux_conf_theme_message_command_fg='#ffff00' # yellow 78 | tmux_conf_theme_message_command_bg='#000000' # black 79 | tmux_conf_theme_message_command_attr='bold' 80 | 81 | # window modes style 82 | tmux_conf_theme_mode_fg='#000000' # black 83 | tmux_conf_theme_mode_bg='#ffff00' # yellow 84 | tmux_conf_theme_mode_attr='bold' 85 | 86 | # status line style 87 | tmux_conf_theme_status_fg='#8a8a8a' # light gray 88 | tmux_conf_theme_status_bg='#080808' # dark gray 89 | tmux_conf_theme_status_attr='none' 90 | 91 | # window status style 92 | # - built-in variables are: 93 | # - #{circled_window_index} 94 | tmux_conf_theme_window_status_fg='#8a8a8a' # light gray 95 | tmux_conf_theme_window_status_bg='#080808' # dark gray 96 | tmux_conf_theme_window_status_attr='none' 97 | tmux_conf_theme_window_status_format='#I #W' 98 | #tmux_conf_theme_window_status_format='#{circled_window_index} #W' 99 | #tmux_conf_theme_window_status_format='#I #W#{?window_bell_flag,🔔,}#{?window_zoomed_flag,🔍,}' 100 | 101 | # window current status style 102 | # - built-in variables are: 103 | # - #{circled_window_index} 104 | tmux_conf_theme_window_status_current_fg='#000000' # black 105 | tmux_conf_theme_window_status_current_bg='#00afff' # light blue 106 | tmux_conf_theme_window_status_current_attr='bold' 107 | tmux_conf_theme_window_status_current_format='#I #W' 108 | #tmux_conf_theme_window_status_current_format='#{circled_window_index} #W' 109 | #tmux_conf_theme_window_status_current_format='#I #W#{?window_zoomed_flag,🔍,}' 110 | 111 | # window activity status style 112 | tmux_conf_theme_window_status_activity_fg='default' 113 | tmux_conf_theme_window_status_activity_bg='default' 114 | tmux_conf_theme_window_status_activity_attr='underscore' 115 | 116 | # window bell status style 117 | tmux_conf_theme_window_status_bell_fg='#ffff00' # yellow 118 | tmux_conf_theme_window_status_bell_bg='default' 119 | tmux_conf_theme_window_status_bell_attr='blink,bold' 120 | 121 | # window last status style 122 | tmux_conf_theme_window_status_last_fg='#00afff' # light blue 123 | tmux_conf_theme_window_status_last_bg='default' 124 | tmux_conf_theme_window_status_last_attr='none' 125 | 126 | # status left/right sections separators 127 | # tmux_conf_theme_left_separator_main='' 128 | # tmux_conf_theme_left_separator_sub='|' 129 | # tmux_conf_theme_right_separator_main='' 130 | # tmux_conf_theme_right_separator_sub='|' 131 | tmux_conf_theme_left_separator_main='' # /!\ you don't need to install powerline 132 | tmux_conf_theme_left_separator_sub='' # you only need fonts patched with 133 | tmux_conf_theme_right_separator_main='' # powerline symbols or the standalone 134 | tmux_conf_theme_right_separator_sub='' # PowerlineSymbols.otf font 135 | 136 | # status left/right content: 137 | # - separate main sections with '|' 138 | # - separate subsections with ',' 139 | # - built-in variables are: 140 | # - #{battery_bar} 141 | # - #{battery_hbar} 142 | # - #{battery_percentage} 143 | # - #{battery_status} 144 | # - #{battery_vbar} 145 | # - #{circled_session_name} 146 | # - #{hostname_ssh} 147 | # - #{hostname} 148 | # - #{loadavg} 149 | # - #{pairing} 150 | # - #{prefix} 151 | # - #{root} 152 | # - #{uptime_d} 153 | # - #{uptime_h} 154 | # - #{uptime_m} 155 | # - #{uptime_s} 156 | # - #{username} 157 | # - #{username_ssh} 158 | tmux_conf_theme_status_left=' ❐ #S | ↑#{?uptime_d, #{uptime_d}d,}#{?uptime_h, #{uptime_h}h,}#{?uptime_m, #{uptime_m}m,} ' 159 | tmux_conf_theme_status_right='#{prefix}#{pairing}#{?battery_status, #{battery_status},}#{?battery_bar, #{battery_bar},}#{?battery_percentage, #{battery_percentage},} , %R , %d %b | #{username}#{root} | #{hostname} ' 160 | 161 | # status left style 162 | tmux_conf_theme_status_left_fg='#000000,#e4e4e4,#e4e4e4' # black, white , white 163 | tmux_conf_theme_status_left_bg='#ffff00,#ff00af,#00afff' # yellow, pink, white blue 164 | tmux_conf_theme_status_left_attr='bold,none,none' 165 | 166 | # status right style 167 | tmux_conf_theme_status_right_fg='#8a8a8a,#e4e4e4,#000000' # light gray, white, black 168 | tmux_conf_theme_status_right_bg='#080808,#d70000,#e4e4e4' # dark gray, red, white 169 | tmux_conf_theme_status_right_attr='none,none,bold' 170 | 171 | # pairing indicator 172 | tmux_conf_theme_pairing='👓' # U+1F453 173 | tmux_conf_theme_pairing_fg='none' 174 | tmux_conf_theme_pairing_bg='none' 175 | tmux_conf_theme_pairing_attr='none' 176 | 177 | # prefix indicator 178 | tmux_conf_theme_prefix='⌨' # U+2328 179 | tmux_conf_theme_prefix_fg='none' 180 | tmux_conf_theme_prefix_bg='none' 181 | tmux_conf_theme_prefix_attr='none' 182 | 183 | # root indicator 184 | tmux_conf_theme_root='!' 185 | tmux_conf_theme_root_fg='none' 186 | tmux_conf_theme_root_bg='none' 187 | tmux_conf_theme_root_attr='bold,blink' 188 | 189 | # battery bar symbols 190 | tmux_conf_battery_bar_symbol_full='◼' 191 | tmux_conf_battery_bar_symbol_empty='◻' 192 | #tmux_conf_battery_bar_symbol_full='♥' 193 | #tmux_conf_battery_bar_symbol_empty='·' 194 | 195 | # battery bar length (in number of symbols), possible values are: 196 | # - auto 197 | # - a number, e.g. 5 198 | tmux_conf_battery_bar_length='auto' 199 | 200 | # battery bar palette, possible values are: 201 | # - gradient (default) 202 | # - heat 203 | # - 'colour_full_fg,colour_empty_fg,colour_bg' 204 | tmux_conf_battery_bar_palette='gradient' 205 | #tmux_conf_battery_bar_palette='#d70000,#e4e4e4,#000000' # red, white, black 206 | 207 | # battery hbar palette, possible values are: 208 | # - gradient (default) 209 | # - heat 210 | # - 'colour_low,colour_half,colour_full' 211 | tmux_conf_battery_hbar_palette='gradient' 212 | #tmux_conf_battery_hbar_palette='#d70000,#ff5f00,#5fff00' # red, orange, green 213 | 214 | # battery vbar palette, possible values are: 215 | # - gradient (default) 216 | # - heat 217 | # - 'colour_low,colour_half,colour_full' 218 | tmux_conf_battery_vbar_palette='gradient' 219 | #tmux_conf_battery_vbar_palette='#d70000,#ff5f00,#5fff00' # red, orange, green 220 | 221 | # symbols used to indicate whether battery is charging or discharging 222 | tmux_conf_battery_status_charging='⚡' # U+26A1 223 | tmux_conf_battery_status_discharging='🔋' # U+1F50B 224 | 225 | # clock style 226 | tmux_conf_theme_clock_colour='#00afff' # light blue 227 | tmux_conf_theme_clock_style='24' 228 | 229 | 230 | # ------------------------------------------------------------------------------ 231 | # this is the place to override or undo settings 232 | 233 | # increase history size 234 | #set -g history-limit 10000 235 | 236 | # force Vi mode 237 | # really you should export VISUAL or EDITOR environment variable, see manual 238 | #set -g status-keys vi 239 | #set -g mode-keys vi 240 | 241 | # move status line to top 242 | #set -g status-position top 243 | 244 | # use defalut key-bindings to avoid compatibility issue with Emacs 245 | set -gu prefix2 246 | unbind C-a 247 | 248 | bind -r p previous-window # select previous window 249 | bind -r n next-window # select next window -------------------------------------------------------------------------------- /dotfiles/vimrc: -------------------------------------------------------------------------------- 1 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 2 | " Maintainer: 3 | " Amir Salihefendic 4 | " http://amix.dk - amix@amix.dk 5 | " 6 | " Version: 7 | " 5.0 - 29/05/12 15:43:36 8 | " 9 | " Blog_post: 10 | " http://amix.dk/blog/post/19691#The-ultimate-Vim-configuration-on-Github 11 | " 12 | " Awesome_version: 13 | " Get this config, nice color schemes and lots of plugins! 14 | " 15 | " Install the awesome version from: 16 | " 17 | " https://github.com/amix/vimrc 18 | " 19 | " Syntax_highlighted: 20 | " http://amix.dk/vim/vimrc.html 21 | " 22 | " Raw_version: 23 | " http://amix.dk/vim/vimrc.txt 24 | " 25 | " Sections: 26 | " -> General 27 | " -> VIM user interface 28 | " -> Colors and Fonts 29 | " -> Files and backups 30 | " -> Text, tab and indent related 31 | " -> Visual mode related 32 | " -> Moving around, tabs and buffers 33 | " -> Status line 34 | " -> Editing mappings 35 | " -> vimgrep searching and cope displaying 36 | " -> Spell checking 37 | " -> Misc 38 | " -> Helper functions 39 | " 40 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 41 | 42 | " Enable line numbers 43 | set number 44 | 45 | " Show the current mode 46 | set showmode 47 | 48 | " Show the filename in the window titlebar 49 | set title 50 | set titleold= 51 | set titlestring=VIM:\ %F 52 | 53 | " Show the (partial) command as it’s being typed 54 | set showcmd 55 | 56 | " Use relative line numbers 57 | if exists("&relativenumber") 58 | set relativenumber 59 | au BufReadPost * set relativenumber 60 | endif 61 | 62 | " Start scrolling three lines before the horizontal window border 63 | set scrolloff=3 64 | 65 | " Highlight current line 66 | set cursorline 67 | 68 | " Enable mouse in all modes 69 | set mouse=a 70 | 71 | " Don’t reset cursor to start of line when moving around. 72 | set nostartofline 73 | 74 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 75 | " => General 76 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 77 | " Sets how many lines of history VIM has to remember 78 | set history=500 79 | 80 | " Enable filetype plugins 81 | filetype plugin on 82 | filetype indent on 83 | 84 | " Set to auto read when a file is changed from the outside 85 | set autoread 86 | 87 | " With a map leader it's possible to do extra key combinations 88 | " like w saves the current file 89 | let mapleader = "," 90 | let g:mapleader = "," 91 | 92 | " Fast saving 93 | nmap w :w! 94 | 95 | " :W sudo saves the file 96 | " (useful for handling the permission-denied error) 97 | command W w !sudo tee % > /dev/null 98 | 99 | 100 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 101 | " => VIM user interface 102 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 103 | " Set 7 lines to the cursor - when moving vertically using j/k 104 | set so=7 105 | 106 | " Avoid garbled characters in Chinese language windows OS 107 | let $LANG='en' 108 | set langmenu=en 109 | source $VIMRUNTIME/delmenu.vim 110 | source $VIMRUNTIME/menu.vim 111 | 112 | " Turn on the WiLd menu 113 | set wildmenu 114 | 115 | " Ignore compiled files 116 | set wildignore=*.o,*~,*.pyc 117 | if has("win16") || has("win32") 118 | set wildignore+=.git\*,.hg\*,.svn\* 119 | else 120 | set wildignore+=*/.git/*,*/.hg/*,*/.svn/*,*/.DS_Store 121 | endif 122 | 123 | "Always show current position 124 | set ruler 125 | 126 | " Height of the command bar 127 | set cmdheight=2 128 | 129 | " A buffer becomes hidden when it is abandoned 130 | set hid 131 | 132 | " Configure backspace so it acts as it should act 133 | set backspace=eol,start,indent 134 | set whichwrap+=<,>,h,l 135 | 136 | " Ignore case when searching 137 | set ignorecase 138 | 139 | " When searching try to be smart about cases 140 | set smartcase 141 | 142 | " Highlight search results 143 | set hlsearch 144 | 145 | " Makes search act like search in modern browsers 146 | set incsearch 147 | 148 | " Don't redraw while executing macros (good performance config) 149 | set lazyredraw 150 | 151 | " For regular expressions turn magic on 152 | set magic 153 | 154 | " Show matching brackets when text indicator is over them 155 | set showmatch 156 | " How many tenths of a second to blink when matching brackets 157 | set mat=2 158 | 159 | " No annoying sound on errors 160 | set noerrorbells 161 | set novisualbell 162 | set t_vb= 163 | set tm=500 164 | 165 | " Properly disable sound on errors on MacVim 166 | if has("gui_macvim") 167 | autocmd GUIEnter * set vb t_vb= 168 | endif 169 | 170 | 171 | " Add a bit extra margin to the left 172 | set foldcolumn=1 173 | 174 | 175 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 176 | " => Colors and Fonts 177 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 178 | " Enable syntax highlighting 179 | syntax enable 180 | 181 | " Enable 256 colors palette in Gnome Terminal 182 | if $COLORTERM == 'gnome-terminal' 183 | set t_Co=256 184 | endif 185 | 186 | try 187 | colorscheme desert 188 | catch 189 | endtry 190 | 191 | set background=dark 192 | 193 | " Set extra options when running in GUI mode 194 | if has("gui_running") 195 | set guioptions-=T 196 | set guioptions-=e 197 | set t_Co=256 198 | set guitablabel=%M\ %t 199 | endif 200 | 201 | " Set utf8 as standard encoding and en_US as the standard language 202 | set encoding=utf8 203 | 204 | " Use Unix as the standard file type 205 | set ffs=unix,dos,mac 206 | 207 | 208 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 209 | " => Files, backups and undo 210 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 211 | " Turn backup off, since most stuff is in SVN, git et.c anyway... 212 | set nobackup 213 | set nowb 214 | set noswapfile 215 | 216 | 217 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 218 | " => Text, tab and indent related 219 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 220 | " Use spaces instead of tabs 221 | set expandtab 222 | 223 | " Be smart when using tabs ;) 224 | set smarttab 225 | 226 | " 1 tab == 4 spaces 227 | set shiftwidth=4 228 | set tabstop=4 229 | 230 | " Linebreak on 500 characters 231 | set lbr 232 | set tw=500 233 | 234 | set ai "Auto indent 235 | set si "Smart indent 236 | set wrap "Wrap lines 237 | 238 | 239 | """""""""""""""""""""""""""""" 240 | " => Visual mode related 241 | """""""""""""""""""""""""""""" 242 | " Visual mode pressing * or # searches for the current selection 243 | " Super useful! From an idea by Michael Naumann 244 | vnoremap * :call VisualSelection('', '')/=@/ 245 | vnoremap # :call VisualSelection('', '')?=@/ 246 | 247 | 248 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 249 | " => Moving around, tabs, windows and buffers 250 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 251 | " Map to / (search) and Ctrl- to ? (backwards search) 252 | map / 253 | map ? 254 | 255 | " Disable highlight when is pressed 256 | map :noh 257 | 258 | " Smart way to move between windows 259 | map j 260 | map k 261 | map h 262 | map l 263 | 264 | " Close the current buffer 265 | map bd :Bclose:tabclosegT 266 | 267 | " Close all the buffers 268 | map ba :bufdo bd 269 | 270 | map l :bnext 271 | map h :bprevious 272 | 273 | " Useful mappings for managing tabs 274 | map tn :tabnew 275 | map to :tabonly 276 | map tc :tabclose 277 | map tm :tabmove 278 | map t :tabnext 279 | 280 | " Let 'tl' toggle between this and the last accessed tab 281 | let g:lasttab = 1 282 | nmap tl :exe "tabn ".g:lasttab 283 | au TabLeave * let g:lasttab = tabpagenr() 284 | 285 | 286 | " Opens a new tab with the current buffer's path 287 | " Super useful when editing files in the same directory 288 | map te :tabedit =expand("%:p:h")/ 289 | 290 | " Switch CWD to the directory of the open buffer 291 | map cd :cd %:p:h:pwd 292 | 293 | " Specify the behavior when switching between buffers 294 | try 295 | set switchbuf=useopen,usetab,newtab 296 | set stal=2 297 | catch 298 | endtry 299 | 300 | " Return to last edit position when opening files (You want this!) 301 | au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif 302 | 303 | 304 | """""""""""""""""""""""""""""" 305 | " => Status line 306 | """""""""""""""""""""""""""""" 307 | " Always show the status line 308 | set laststatus=2 309 | 310 | " Format the status line 311 | set statusline=\ %{HasPaste()}%F%m%r%h\ %w\ \ CWD:\ %r%{getcwd()}%h\ \ \ Line:\ %l\ \ Column:\ %c 312 | 313 | 314 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 315 | " => Editing mappings 316 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 317 | " Remap VIM 0 to first non-blank character 318 | map 0 ^ 319 | 320 | " Move a line of text using ALT+[jk] or Command+[jk] on mac 321 | nmap mz:m+`z 322 | nmap mz:m-2`z 323 | vmap :m'>+`mzgv`yo`z 324 | vmap :m'<-2`>my` 328 | nmap 329 | vmap 330 | vmap 331 | endif 332 | 333 | " Delete trailing white space on save, useful for Python and CoffeeScript ;) 334 | func! DeleteTrailingWS() 335 | exe "normal mz" 336 | %s/\s\+$//ge 337 | exe "normal `z" 338 | endfunc 339 | autocmd BufWrite *.py :call DeleteTrailingWS() 340 | autocmd BufWrite *.coffee :call DeleteTrailingWS() 341 | 342 | 343 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 344 | " => Ag searching and cope displaying 345 | " requires ag.vim - it's much better than vimgrep/grep 346 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 347 | " When you press gv you Ag after the selected text 348 | vnoremap gv :call VisualSelection('gv', '') 349 | 350 | " Open Ag and put the cursor in the right position 351 | map g :Ag 352 | 353 | " When you press r you can search and replace the selected text 354 | vnoremap r :call VisualSelection('replace', '') 355 | 356 | " Do :help cope if you are unsure what cope is. It's super useful! 357 | " 358 | " When you search with Ag, display your results in cope by doing: 359 | " cc 360 | " 361 | " To go to the next search result do: 362 | " n 363 | " 364 | " To go to the previous search results do: 365 | " p 366 | " 367 | map cc :botright cope 368 | map co ggVGy:tabnew:set syntax=qfpgg 369 | map n :cn 370 | map p :cp 371 | 372 | 373 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 374 | " => Spell checking 375 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 376 | " Pressing ,ss will toggle and untoggle spell checking 377 | map ss :setlocal spell! 378 | 379 | " Shortcuts using 380 | map sn ]s 381 | map sp [s 382 | map sa zg 383 | map s? z= 384 | 385 | 386 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 387 | " => Misc 388 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 389 | " Remove the Windows ^M - when the encodings gets messed up 390 | noremap m mmHmt:%s///ge'tzt'm 391 | 392 | " Quickly open a buffer for scribble 393 | map q :e ~/buffer 394 | 395 | " Quickly open a markdown buffer for scribble 396 | map x :e ~/buffer.md 397 | 398 | " Toggle paste mode on and off 399 | map pp :setlocal paste! 400 | 401 | 402 | 403 | 404 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 405 | " => Helper functions 406 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 407 | function! CmdLine(str) 408 | exe "menu Foo.Bar :" . a:str 409 | emenu Foo.Bar 410 | unmenu Foo 411 | endfunction 412 | 413 | function! VisualSelection(direction, extra_filter) range 414 | let l:saved_reg = @" 415 | execute "normal! vgvy" 416 | 417 | let l:pattern = escape(@", "\\/.*'$^~[]") 418 | let l:pattern = substitute(l:pattern, "\n$", "", "") 419 | 420 | if a:direction == 'gv' 421 | call CmdLine("Ag '" . l:pattern . "' " ) 422 | elseif a:direction == 'replace' 423 | call CmdLine("%s" . '/'. l:pattern . '/') 424 | endif 425 | 426 | let @/ = l:pattern 427 | let @" = l:saved_reg 428 | endfunction 429 | 430 | 431 | " Returns true if paste mode is enabled 432 | function! HasPaste() 433 | if &paste 434 | return 'PASTE MODE ' 435 | endif 436 | return '' 437 | endfunction 438 | 439 | " Don't close window, when deleting a buffer 440 | command! Bclose call BufcloseCloseIt() 441 | function! BufcloseCloseIt() 442 | let l:currentBufNum = bufnr("%") 443 | let l:alternateBufNum = bufnr("#") 444 | 445 | if buflisted(l:alternateBufNum) 446 | buffer # 447 | else 448 | bnext 449 | endif 450 | 451 | if bufnr("%") == l:currentBufNum 452 | new 453 | endif 454 | 455 | if buflisted(l:currentBufNum) 456 | execute("bdelete! ".l:currentBufNum) 457 | endif 458 | endfunction 459 | 460 | " Make VIM remember position in file after reopen 461 | " if has("autocmd") 462 | " au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif 463 | "endif 464 | 465 | " ---------------------------------------------------------------------- 466 | " | Local Settings | 467 | " ---------------------------------------------------------------------- 468 | 469 | " Load local settings if they exist. 470 | " 471 | " [!] The following needs to remain at the end of this file in 472 | " order to allow any of the above settings to be overwritten 473 | " by the local ones. 474 | 475 | if filereadable(glob("~/.vimrc.local")) 476 | source ~/.vimrc.local 477 | endif 478 | -------------------------------------------------------------------------------- /dotfiles/zshrc: -------------------------------------------------------------------------------- 1 | # -*- mode: shell-script; -*- 2 | # vim: ft=shell: sw=2: 3 | 4 | # Path to your antigen installation. 5 | export ANTIGEN=$HOME/.antigen 6 | 7 | # Configure Antigen 8 | declare -a ANTIGEN_CHECK_FILES 9 | ANTIGEN_CHECK_FILES=("${HOME}/.zshrc" "${HOME}/.zshrc.local" "${HOME}/.zshrc.theme.local") 10 | 11 | # Load Antigen 12 | source ${ANTIGEN}/antigen.zsh 13 | 14 | # Load the oh-my-zsh 15 | antigen use oh-my-zsh 16 | 17 | # Bundles from the default repo (robbyrussell's oh-my-zsh) 18 | antigen bundle git 19 | antigen bundle colored-man-pages 20 | antigen bundle extract 21 | antigen bundle sudo 22 | antigen bundle z 23 | antigen bundle tmux 24 | antigen bundle colorize 25 | antigen bundle history 26 | # antigen bundle emacs 27 | antigen bundle copypath 28 | antigen bundle copyfile 29 | [[ $OSTYPE == darwin* ]] && antigen bundle osx 30 | 31 | # Misc bundles 32 | antigen bundle djui/alias-tips 33 | [[ $OSTYPE != cygwin* ]] && antigen bundle andrewferrier/fzf-z 34 | 35 | # antigen bundle zsh-users/zsh-completions 36 | antigen bundle zsh-users/zsh-autosuggestions 37 | antigen bundle zdharma/fast-syntax-highlighting 38 | # antigen bundle zsh-users/zsh-syntax-highlighting 39 | antigen bundle zsh-users/zsh-history-substring-search 40 | 41 | # Basic PATH configuration 42 | export PATH="${HOME}/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11" 43 | 44 | # Load the theme 45 | antigen theme ray-g/zsh-theme 46 | 47 | # Load the shell dotfiles, and then some: 48 | # * ~/.path can be used to extend `$PATH`. 49 | # * ~/.zshrc.local can be used for other settings you don’t want to commit. 50 | for file in ~/.{path,exports,aliases,functions,zshrc.local,zshrc.theme.local}; do 51 | [ -r "$file" ] && [ -f "$file" ] && source "$file"; 52 | done; 53 | unset file 54 | 55 | # Tell Antigen that you've done 56 | antigen apply 57 | 58 | # Hook after antigen_apply 59 | file=~/.zshrc.final.local 60 | [ -r "$file" ] && [ -f "$file" ] && source "$file" 61 | unset file 62 | 63 | # Source rust 64 | [ -f "$HOME/.cargo/env" ] && source "$HOME/.cargo/env" 65 | 66 | # Completion enhancements 67 | [ -f ~/.completion.zsh ] && source ~/.completion.zsh 68 | 69 | [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh 70 | -------------------------------------------------------------------------------- /dotfiles_cn/gemrc: -------------------------------------------------------------------------------- 1 | --- 2 | :backtrace: false 3 | :bulk_threshold: 1000 4 | :sources: 5 | - https://gems.ruby-china.com/ 6 | :update_sources: true 7 | :verbose: true 8 | -------------------------------------------------------------------------------- /dotfiles_cn/npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npm.taobao.org/ -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BASE_DIR="${BASH_SOURCE%/*}" 4 | if [[ ! -d "$BASE_DIR" ]]; then BASE_DIR="$PWD"; fi 5 | 6 | . "${BASE_DIR}/scripts/utils.sh" 7 | . "${BASE_DIR}/scripts/install/versions.sh" 8 | . "${BASE_DIR}/scripts/install/$(get_os)/main.sh" 9 | . "${BASE_DIR}/scripts/install/common/main.sh" 10 | 11 | if ! continue_as_root; then 12 | exit 1 13 | fi 14 | 15 | parse_options $@ 16 | 17 | if ! DRYRUN; then 18 | ask_for_sudo 19 | fi 20 | 21 | if ENV_ONLY; then 22 | setup_env_only 23 | exit 0 24 | fi 25 | 26 | read_package_conf "${BASE_DIR}/scripts/install/$(get_os)/package.conf" 27 | read_package_conf "${BASE_DIR}/scripts/install/common/package.conf" 28 | # print_packages 29 | 30 | if ! ALLYES; then 31 | check_and_install_whiptail 32 | fi 33 | 34 | _continue=show_select_package_box 35 | 36 | if $_continue; then 37 | install_selected_packages 38 | else 39 | print_in_purple 'Canceled\n' 40 | fi 41 | 42 | # Not able to get overall installation status. 43 | # Simply return success here. 44 | exit 0 45 | -------------------------------------------------------------------------------- /scripts/install/common/env.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function install_antigen() { 4 | local antigen_home="${HOME}/.antigen" 5 | execute "mkdir -p \"${antigen_home}\"" || return $? 6 | execute "curl -fsSL git.io/antigen > ${antigen_home}/antigen.zsh.tmp" || return $? 7 | execute "mv \"${antigen_home}/antigen.zsh.tmp\" \"${antigen_home}/antigen.zsh\"" 8 | } 9 | 10 | function install_omz() { 11 | # Install Oh-My-ZSH 12 | # http://ohmyz.sh/ 13 | local exitCode=0 14 | if [ ! -e ~/.oh-my-zsh ]; then 15 | execute "sh -c \"\$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | sed 's/env zsh/ /g;s/chsh -s .*/sudo & \$(whoami)/g')\"" "Oh-My-ZSH" 16 | exitCode=$? 17 | fi 18 | 19 | if [ $exitCode ]; then 20 | # Oh-My-Zsh plugins 21 | execute "sync_repo https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions" 22 | execute "sync_repo https://github.com/zsh-users/zsh-syntax-highlighting.git ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting" 23 | execute "sync_repo https://github.com/djui/alias-tips.git ~/.oh-my-zsh/custom/plugins/alias-tips" 24 | fi 25 | return $exitCode 26 | } 27 | 28 | function install_omt() { 29 | # Install Oh-My-Tmux 30 | execute "sync_repo https://github.com/gpakosz/.tmux.git ~/.tmux" || return $? 31 | execute "ln -s -f ~/.tmux/.tmux.conf ~/.tmux.conf" 32 | } 33 | 34 | function install_emacsconf() { 35 | # Install .emacs.d 36 | execute "sync_repo https://github.com/seagle0128/.emacs.d ~/.emacs.d" 37 | } 38 | 39 | function install_fzf() { 40 | # Install fzf searcher 41 | if [ ! -e ~/.fzf ]; then 42 | execute "git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf" || return $? 43 | execute "~/.fzf/install --all" 44 | else 45 | return 0 46 | fi 47 | } 48 | 49 | function install_z() { 50 | # Install z, the new j 51 | execute "sync_repo https://github.com/rupa/z ~/bin/z" 52 | } 53 | 54 | function install_dotfiles() { 55 | # Create dotfiles 56 | local filename="" 57 | 58 | for filename in ${BASE_DIR}/dotfiles/*; do 59 | if [ -e $filename ]; then 60 | # realpath not found in travis 61 | create_link $(realpath $filename) ${HOME}/.$(basename ${filename}) 62 | # create_link $(readlink -f $filename) ${HOME}/.$(basename ${filename}) 63 | fi 64 | done 65 | 66 | # clean old files 67 | for filename in ~/.{zsh_prompt,zshrc.local,zshrc.theme.local,gitconfig,vimrc.local}; do 68 | if [[ -L "$filename" && ! -e "$filename" ]]; then 69 | # broken link 70 | execute "rm $filename" 71 | elif [ -f "$filename" ]; then 72 | execute "mv ${filename} ${filename}.devstrap.bak" 73 | print_info "Backup existing file: ${filename} to ${filename}.devstrap.bak" 74 | print_info "You can get your config back by copy the content" 75 | print_info "or remove backups if you don't need them." 76 | fi 77 | done 78 | 79 | # Create customize (*.local) files if not exists 80 | 81 | # gitconfig should use original filename without ".local" suffix 82 | # so customized "git config --global" can be saved without touch devstrap repo 83 | filename=~/.gitconfig 84 | if [ ! -f "$filename" ]; then 85 | execute "touch $filename" 86 | local newline=$'\n' 87 | local content="" 88 | content+="# Include devstrap's gitconfig first.${newline}" 89 | content+="# Keep this in the top of this file to allow any setting overwritten it.${newline}" 90 | content+="[include]${newline}" 91 | content+=" # Load local configs.${newline}" 92 | content+=" # https://git-scm.com/docs/git-config#_includes${newline}" 93 | content+="${newline}" 94 | content+=" path = ~/.gitconfig.devstrap" 95 | content+="${newline}" 96 | execute "echo \"${content}\" > $filename" "Update file: $filename" 97 | print_info "You can add your personal configurations in $filename" 98 | fi 99 | 100 | # Create customize .zshrc.local file if not exists 101 | filename=~/.zshrc.local 102 | if [ ! -f "$filename" ]; then 103 | execute "touch $filename" 104 | local newline=$'\n' 105 | local content="" 106 | content+="# Please add your personal configurations here.${newline}" 107 | content+="${newline}" 108 | content+="# Customize Antigen Plugins:${newline}" 109 | content+="# antigen bundle golang${newline}" 110 | content+="# antigen bundle python${newline}" 111 | content+="# antigen bundle ruby${newline}" 112 | content+="# antigen bundle docker${newline}" 113 | content+="# antigen bundle docker-compose${newline}" 114 | content+="# antigen bundle docker-machine${newline}" 115 | content+="# antigen bundle npm${newline}" 116 | content+="${newline}" 117 | content+="# thefuck alias${newline}" 118 | content+="[ -x \\\"\\\$(command -v thefuck)\\\" ] && eval \\\$(thefuck --alias)" 119 | execute "echo \"${content}\" > $filename" "Update file: $filename" 120 | print_info "You can set your personal configurations in $filename" 121 | fi 122 | 123 | filename=~/.zshrc.final.local 124 | if [ ! -f "$filename" ]; then 125 | execute "touch $filename" 126 | local newline=$'\n' 127 | local content="" 128 | content+="# Please add your personal configurations which should apply after antigen here.${newline}" 129 | content+="if type '...' > /dev/null 2>&1; then${newline}" 130 | content+=" unalias '...'${newline}" 131 | content+="fi${newline}" 132 | execute "echo \"${content}\" > $filename" "Update file: $filename" 133 | print_info "You can add your personal final contifutations in $filename" 134 | fi 135 | 136 | # Create customize .vimrc.local file if not exists 137 | filename=~/.vimrc.local 138 | if [ ! -f "$filename" ]; then 139 | execute "touch $filename" 140 | execute "echo '\" Please add your personal configurations here.' > $filename" "Update file: $filename" 141 | print_info "You can add your personal configurations in $filename" 142 | fi 143 | 144 | # Create customize .zshrc.theme.local file if not exists 145 | filename=~/.zshrc.theme.local 146 | if [ ! -f "$filename" ]; then 147 | execute "touch $filename" 148 | local newline=$'\n' 149 | local content="" 150 | content+="# Set name of the theme to load.${newline}" 151 | content+="# Look in ~/.oh-my-zhe/themes/${newline}" 152 | content+="# Optionally, if you set this to \"random\", it will load a random theme each${newline}" 153 | content+="# time that oh-my-zsh is loaded.${newline}" 154 | content+="# ZSH_THEME=\"ys\"${newline}" 155 | content+="#${newline}" 156 | content+="# Use Antigen to load theme${newline}" 157 | content+="antigen theme ys #ys, dst, steeef, wedisagree, robbyrussell${newline}" 158 | execute "echo \"${content}\" > $filename" "Update file: $filename" 159 | print_info "You can set your favorite theme in $filename" 160 | fi 161 | 162 | # For Centaur Emacs 163 | pathfile=~/.path 164 | zshenvfile=~/.zshenv 165 | if [ -f "$pathfile" ]; then 166 | execute "cp $pathfile $zshenvfile" "Update $zshenvfile" 167 | fi 168 | } 169 | 170 | function install_cn_mirrors() { 171 | for filename in ${BASE_DIR}/dotfiles_cn/*; do 172 | if [ -e $filename ]; then 173 | # realpath not found in travis 174 | create_link $(realpath $filename) ${HOME}/.$(basename ${filename}) 175 | # create_link $(readlink -f $filename) ${HOME}/.$(basename ${filename}) 176 | fi 177 | done 178 | } 179 | 180 | function change_to_zsh() { 181 | if hash zsh 2> /dev/null; then 182 | print_info "Now enter ZSH" 183 | if ! IS_TRAVIS && ! DRYRUN; then 184 | env zsh 185 | else 186 | execute "env zsh" 187 | fi 188 | else 189 | print_error "ZSH not installed." 190 | fi 191 | } 192 | 193 | function setup_env_only() { 194 | install_antigen 195 | install_omt 196 | install_emacsconf 197 | install_fzf 198 | install_dotfiles 199 | install_cn_mirrors 200 | change_to_zsh 201 | } 202 | -------------------------------------------------------------------------------- /scripts/install/common/gem.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function install_via_gem() { 4 | local PACKAGE=${pkg_name} 5 | local PACKAGE_DESC=${pkg_desc} 6 | local PACKAGE_EXE=${pkg_exe} 7 | local PACKAGE_LOCATION=${pkg_cmd} 8 | 9 | if ! cmd_exists "gem"; then 10 | print_error "${PACKAGE_DESC}. Ruby 'gem' didn't installed properly." 11 | return 1 12 | fi 13 | 14 | if ! cmd_exists $PACKAGE_EXE; then 15 | execute "sudo gem install ${PACKAGE}" "${PACKAGE_DESC}" 16 | else 17 | print_success "${PACKAGE_DESC}" 18 | fi 19 | } 20 | 21 | regist_pkg_installer "gem" "install_via_gem" 22 | -------------------------------------------------------------------------------- /scripts/install/common/go.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function check_go_env() { 4 | if ! cmd_exists "go"; then 5 | return 1 6 | elif [ -z $GOPATH ]; then 7 | return 1 8 | fi 9 | } 10 | 11 | function install_via_go() { 12 | local PACKAGE=${pkg_name} 13 | local PACKAGE_DESC=${pkg_desc} 14 | local PACKAGE_EXE=${pkg_exe} 15 | local PACKAGE_LOCATION=${pkg_cmd} 16 | 17 | if ! check_go_env; then 18 | print_error "${PACKAGE_DESC}. Golang didn't installed properly." 19 | return 1 20 | fi 21 | 22 | if ! cmd_exists $PACKAGE_EXE; then 23 | execute "go get -u -v ${PACKAGE}" "${PACKAGE_DESC}" 24 | else 25 | print_success "${PACKAGE_DESC}" 26 | fi 27 | } 28 | 29 | regist_pkg_installer "go" "install_via_go" 30 | -------------------------------------------------------------------------------- /scripts/install/common/main.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd "$(dirname "${BASH_SOURCE[0]}")" \ 4 | && . "npm.sh" \ 5 | && . "go.sh" \ 6 | && . "gem.sh" \ 7 | && . "pip.sh" \ 8 | && . "env.sh" \ 9 | && cd - &> /dev/null 10 | 11 | function install_calibre() { 12 | execute "sudo -v && wget -nv -O- https://download.calibre-ebook.com/linux-installer.py | sudo python -c \"import sys; main=lambda:sys.stderr.write('Download failed\\n'); exec(sys.stdin.read()); main()\"" "Calibre" 13 | } 14 | 15 | function install_cheat_sh() { 16 | execute "curl https://cht.sh/:cht.sh > ~/bin/cht.sh && chmod +x ~/bin/cht.sh" 17 | } 18 | -------------------------------------------------------------------------------- /scripts/install/common/npm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function install_via_npm() { 4 | local PACKAGE=${pkg_name} 5 | local PACKAGE_DESC=${pkg_desc} 6 | local PACKAGE_EXE=${pkg_exe} 7 | local PACKAGE_LOCATION=${pkg_cmd} 8 | 9 | if ! cmd_exists "npm"; then 10 | print_error "${PACKAGE_DESC}. NPM didn't installed properly." 11 | return 1 12 | fi 13 | 14 | if ! cmd_exists $PACKAGE_EXE; then 15 | execute "sudo npm install -g ${PACKAGE}" "${PACKAGE_DESC}" 16 | else 17 | print_success "${PACKAGE_DESC}" 18 | fi 19 | } 20 | 21 | regist_pkg_installer "npm" "install_via_npm" 22 | -------------------------------------------------------------------------------- /scripts/install/common/package.conf: -------------------------------------------------------------------------------- 1 | # seperation: ';' 2 | # NOTE: Empty tail line is necessary 3 | # 4 | # FORMAT: pkg_name; pkg_desc; pkg_sel; pkg_type; pkg_exe; pkg_cmd 5 | # pkg_name: Package Name; should exactly the same with package manager; no duplicated package allowed 6 | # pkg_desc: A readable package Description 7 | # pkg_sel: Default selection in whiptail box, on - selected, off - not selected, hide - not shown but selected. 8 | # pkg_type: Package manager type, available in apt, git, npm, go, gem, etc., should be registed before use 9 | # pkg_exe: Package executable name (Optional) 10 | # pkg_cmd: A command to install the package (Optional) 11 | 12 | # Common Packages, OS independed environments etc 13 | install_common_pkgs; Install OS independed packages; on; seperator;; 14 | calibre; E-book converter and library management; off; cmd;;install_calibre 15 | cheat.sh; Cheat sheet in shell; on; cmd;;install_cheat_sh 16 | 17 | # Go packages 18 | # Most of these package are from https://github.com/Microsoft/vscode-go/blob/master/src/goInstallTools.ts 19 | # and from this page https://github.com/seagle0128/.emacs.d/blob/master/lisp/init-go.el 20 | install_go_pkgs; Install Golang Packages; on; seperator;; 21 | github.com/nsf/gocode; gocode: An autocompletion daemon for Go; on; go; gocode; 22 | github.com/uudashr/gopkgs/cmd/gopkgs; gopkgs: Provide list of available Go packages; on; go; gopkgs; 23 | github.com/ramya-rao-a/go-outline; go-outline: Extract JSON of declarations from a Go source file; on; go; go-outline; 24 | github.com/acroca/go-symbols; go-symbols: Extract JSON of declarations from a Go source tree; on; go; go-symbols; 25 | golang.org/x/tools/cmd/guru; guru: a tool for answering questions about Go source code; on; go; guru; 26 | golang.org/x/tools/cmd/gorename; gorename: Type-safe renaming in Go source code; on; go; gorename; 27 | github.com/fatih/gomodifytags; gomodifytags: Go tool to modify struct field tags; off; go; gomodifytags; 28 | github.com/haya14busa/goplay/cmd/goplay; goplay: Go playground; off; go; goplay; 29 | github.com/josharian/impl; impl: generates method stubs for implementing an interface; off; go; impl; 30 | github.com/tylerb/gotype-live; gotype-live: A gotype allows processing of code as it is being edited; off; go; gotype-live; 31 | github.com/rogpeppe/godef; godef: Print where symbols are defined in Go source code; on; go; godef; 32 | golang.org/x/tools/cmd/godoc; godoc: extracts and generates documentation for Go programs; on; go; godoc; 33 | github.com/zmb3/gogetdoc; gogetdoc: Gets documentation for items in Go source code; on; go; gogetdoc; 34 | golang.org/x/tools/cmd/goimports; goimports: Update Go import lines in Go source code; on; go; goimports; 35 | sourcegraph.com/sqs/goreturns; goreturns: goimports-like tool fills Go return statements to match the func; on; go; goreturns; 36 | github.com/golang/lint/golint; golint: Linter for Golang; on; go; golint; 37 | github.com/cweill/gotests/...; gotests: Generate Go tests from your source code; on; go; gotests; 38 | github.com/alecthomas/gometalinter; gometalinter: Concurrently run Go lint tools and normalise their output; on; go; gometalinter; 39 | honnef.co/go/tools/...; megacheck: runs staticcheck, gosimple and unused; off; go; megacheck; 40 | github.com/sourcegraph/go-langserver; go-langserver: Add Go support that use the Language Server Protocol (LSP); on; go; go-langserver; 41 | github.com/derekparker/delve/cmd/dlv; dlv: Go debug tool; on; go; dlv; 42 | github.com/golang/dep/cmd/dep; dep: Go dependency management tool; on; go; godep; 43 | github.com/davidrjenni/reftools/cmd/fillstruct; fillstruct: fills a struct literal with default values; on; go; fillstruct 44 | 45 | # Global installed Python PIP packages 46 | install_pip_pkgs; Install Python PIP Packages; on; seperator;; 47 | use_pip3; Use Python3 PIP to install following Python Packages; on; cmd;; install_via_pip3 48 | docker-compose; Docker Compose; on; pip; Docker Compose; 49 | thefuck; Magnificent app which corrects your previous console command; off; pip; thefuck; 50 | 51 | # Global installed Ruby gem packages 52 | install_gem_pkgs; Install Ruby Gem Packages; on; seperator;; 53 | rake; Ruby Make; on; gem ;; 54 | pry; Powerful irb; on; gem; pry; 55 | rubocop; Ruby linter package; on; gem; rubocop; 56 | 57 | # Global installed NPM packages 58 | install_npm_pkgs; Install Npm Packages; on; seperator;; 59 | gulp-cli; Gulp command line interface; on; npm; gulp; 60 | gitbook; Gitbook to make books; on; npm; gitbook; 61 | 62 | # Setting up dotfiles 63 | install_shell_utilities; Setting up shell utilities; on; seperator;; 64 | antigen; Antigen: plugin manager for ZSH; on; cmd;;install_antigen 65 | oh-my-tmux; Oh-My-TMUX; on; cmd;;install_omt 66 | emacs.d; Emacs Configurations; on; cmd;;install_emacsconf 67 | fzf; A command-line fuzzy finder; on; cmd;; install_fzf 68 | # z; jump around, (the new j); on; cmd;;install_z 69 | install_dotfiles; Setup Dotfiles; on;cmd;;install_dotfiles 70 | install_dotfiles_cn; Setup NPM/Gem China mirrors; off; cmd;; install_cn_mirrors 71 | 72 | # The final task, change to ZSH 73 | change_to_ZSH; Change to ZSH; on; cmd;; change_to_zsh 74 | 75 | # End of package conf 76 | -------------------------------------------------------------------------------- /scripts/install/common/pip.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function install_via_pip() { 4 | local PACKAGE=${pkg_name} 5 | local PACKAGE_DESC=${pkg_desc} 6 | local PACKAGE_EXE=${pkg_exe} 7 | local PACKAGE_LOCATION=${pkg_cmd} 8 | 9 | if ! cmd_exists "pip"; then 10 | print_error "${PACKAGE_DESC}. Python 'pip' didn't installed properly." 11 | return 1 12 | fi 13 | 14 | if ! cmd_exists $PACKAGE_EXE; then 15 | execute "sudo -H pip install ${PACKAGE}" "${PACKAGE_DESC}" 16 | else 17 | print_success "${PACKAGE_DESC}" 18 | fi 19 | } 20 | 21 | function install_via_pip3() { 22 | local PACKAGE=${pkg_name} 23 | local PACKAGE_DESC=${pkg_desc} 24 | local PACKAGE_EXE=${pkg_exe} 25 | local PACKAGE_LOCATION=${pkg_cmd} 26 | 27 | if ! cmd_exists "pip3"; then 28 | print_error "${PACKAGE_DESC}. Python3 'pip' didn't installed properly." 29 | return 1 30 | fi 31 | 32 | if ! cmd_exists $PACKAGE_EXE; then 33 | execute "sudo -H pip3 install ${PACKAGE}" "${PACKAGE_DESC}" 34 | else 35 | print_success "${PACKAGE_DESC}" 36 | fi 37 | } 38 | 39 | regist_pkg_installer "pip" "install_via_pip" 40 | 41 | function regist_pip3() { 42 | regist_pkg_installer "pip" "install_via_pip3" 43 | } 44 | -------------------------------------------------------------------------------- /scripts/install/macos/install_depends.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ray-g/devstrap/78eab9eec786778e6ccb80239fc66c984f62ae59/scripts/install/macos/install_depends.sh -------------------------------------------------------------------------------- /scripts/install/macos/main.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ray-g/devstrap/78eab9eec786778e6ccb80239fc66c984f62ae59/scripts/install/macos/main.sh -------------------------------------------------------------------------------- /scripts/install/macos/package.conf: -------------------------------------------------------------------------------- 1 | # seperation: ';' 2 | # NOTE: Empty tail line is necessary 3 | # 4 | # FORMAT: pkg_name; pkg_desc; pkg_sel; pkg_type; pkg_exe; pkg_cmd 5 | # pkg_name: Package Name; should exactly the same with package manager; no duplicated package allowed 6 | # pkg_desc: A readable package Description 7 | # pkg_sel: Default selection in whiptail box, on - selected, off - not selected, hide - not shown but selected. 8 | # pkg_type: Package manager type, available in apt, git, npm, go, gem, etc., should be registed before use 9 | # pkg_exe: Package executable name (Optional) 10 | # pkg_cmd: A command to install the package (Optional) 11 | 12 | 13 | # End of package.conf 14 | -------------------------------------------------------------------------------- /scripts/install/ubuntu/helper.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function add_key() { 4 | wget -qO - "$1" | sudo apt-key add - &> /dev/null 5 | # │└─ write output to file 6 | # └─ don't show output 7 | } 8 | 9 | function add_ppa() { 10 | sudo add-apt-repository -y ppa:"$1" &> /dev/null 11 | } 12 | 13 | function add_to_source_list() { 14 | sudo sh -c "printf 'deb $1' >> '/etc/apt/sources.list.d/$2'" 15 | } 16 | 17 | function autoremove() { 18 | # Remove packages that were automatically installed to satisfy 19 | # dependencies for other packages and are no longer needed. 20 | execute "sudo apt-get autoremove -qqy" "APT (autoremove)" 21 | # suppress output ─┘│ 22 | # assume "yes" to all prompts ──┘ 23 | } 24 | 25 | function install_package() { 26 | declare -r PACKAGE="${1:-$pkg_name}" 27 | declare -r PACKAGE_READABLE_NAME="${2:-$pkg_desc}" 28 | 29 | if ! package_is_installed "$PACKAGE"; then 30 | execute "sudo apt-get install --allow-unauthenticated -qqy $PACKAGE" "$PACKAGE_READABLE_NAME" 31 | # suppress output ─┘│ 32 | # assume "yes" as the answer to all prompts ──┘ 33 | else 34 | print_success "$PACKAGE_READABLE_NAME" 35 | fi 36 | } 37 | 38 | function package_is_installed() { 39 | dpkg -s "$1" &> /dev/null 40 | } 41 | 42 | function update() { 43 | # Resynchronize the package index files from their sources. 44 | execute "sudo apt-get update -qqy" "APT (update)" 45 | # suppress output ─┘│ 46 | # assume "yes" to all prompts ──┘ 47 | } 48 | 49 | function upgrade() { 50 | # Install the newest versions of all packages installed. 51 | execute \ 52 | "export DEBIAN_FRONTEND=\"noninteractive\" \ 53 | && sudo apt-get -o Dpkg::Options::=\"--force-confnew\" upgrade -qqy" \ 54 | "APT (upgrade)" 55 | # suppress output ─┘│ 56 | # assume "yes" to all prompts ──┘ 57 | } 58 | -------------------------------------------------------------------------------- /scripts/install/ubuntu/main.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd "$(dirname "${BASH_SOURCE[0]}")" \ 4 | && . "helper.sh" \ 5 | && cd - &> /dev/null 6 | 7 | # Register apt installer 8 | regist_pkg_installer "apt" "install_package" 9 | 10 | function pre_install() { 11 | update 12 | } 13 | 14 | function post_install() { 15 | : 16 | } 17 | 18 | function install_docker() { 19 | execute "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -" || return $? 20 | execute "sudo add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\"" || return $? 21 | update || return $? 22 | execute "apt-cache policy docker-ce" || return $? 23 | install_package "docker-ce" "Docker CE" || return $? 24 | execute "sudo usermod -aG docker $(whoami)" || return $? 25 | # execute "sudo mkdir /docker" || return $? 26 | # execute "sudo ln -s /docker /var/lib/docker" || return $? 27 | # execute "echo 'DOCKER_OPTS=\"-g /docker\"' | sudo tee /etc/default/docker" || return $? 28 | 29 | # # Install Docker Compose 30 | # if ! cmd_exists "docker-compose"; then 31 | # if cmd_exists "pip"; then 32 | # execute "sudo pip install docker-compose" "Docker Compose" 33 | # else 34 | # print_error "Failed to install docker-compose. 'pip' is not installed properly" 35 | # return 1 36 | # fi 37 | # fi 38 | } 39 | 40 | # Install Node.JS 41 | # https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions 42 | function install_nodejs10() { 43 | execute "curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -" || return $? 44 | install_package "nodejs" "NodeJS_10" 45 | } 46 | 47 | function install_nodejs12() { 48 | execute "curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -" || return $? 49 | install_package "nodejs" "NodeJS_12" 50 | } 51 | 52 | function upgrade_golang() { 53 | remove_golang 54 | install_golang 55 | } 56 | 57 | function remove_golang() { 58 | local GO_ROOT="/usr/local/go" 59 | local GO_EXE="go" 60 | if cmd_exists "${GO_EXE}"; then 61 | if [[ -d "${GO_ROOT}" && "${GO_ROOT}/bin/go" == "$(which go)" ]]; then 62 | execute "sudo rm -rf ${GO_ROOT}" 63 | fi 64 | fi 65 | } 66 | 67 | function install_golang() { 68 | local GO_VER=$DEVSTRAP_GO_VER 69 | local GO_OS="linux" 70 | local GO_ARCH="amd64" 71 | 72 | if ! cmd_exists "${pkg_exe}"; then 73 | execute "wget --no-check-certificate https://go.dev/dl/go${GO_VER}.${GO_OS}-${GO_ARCH}.tar.gz" || return $? 74 | execute "sudo tar -C /usr/local -xzf go${GO_VER}.${GO_OS}-${GO_ARCH}.tar.gz" 75 | local exitCode=$? 76 | execute "rm go${GO_VER}.${GO_OS}-${GO_ARCH}.tar.gz" 77 | 78 | if [ $exitCode -eq 0 ]; then 79 | # Successfully installed Golang, setup environment 80 | export GOPATH="${HOME}/.go" 81 | export PATH=${GOPATH}/bin:/usr/local/go/bin:$PATH 82 | fi 83 | return $exitCode 84 | else 85 | return 0 86 | fi 87 | } 88 | 89 | function install_rust() { 90 | if ! cmd_exists "${pkg_exe}"; then 91 | execute "curl https://sh.rustup.rs -sSf | sh -s -- --no-modify-path" 92 | return $? 93 | fi 94 | } 95 | 96 | function install_vscode() { 97 | local vscode="vscode_stable_devstrap.deb" 98 | execute "wget --no-check-certificate https://vscode-update.azurewebsites.net/latest/linux-deb-x64/stable -O $vscode" || return $? 99 | execute "sudo dpkg -i $vscode" 100 | local exitCode=$? 101 | execute "rm $vscode" 102 | return $exitCode 103 | } 104 | 105 | function install_emacs_ppa() { 106 | execute "sudo add-apt-repository ppa:kelleyk/emacs -y && sudo apt-get update" 107 | install_package 108 | } 109 | 110 | function upgrade_ripgrep() { 111 | remove_ripgrep 112 | install_ripgrep 113 | } 114 | 115 | function remove_ripgrep() { 116 | local RG_ROOT="/usr/local/rg" 117 | local RG_EXE="rg" 118 | local RG_LINK="/usr/local/bin/rg" 119 | if cmd_exists "${RG_EXE}"; then 120 | if [[ -d "${RG_ROOT}" && "${RG_LINK}" == "$(which rg)" && "$(realpath ${RG_LINK})" == "${RG_ROOT}/rg" ]]; then 121 | execute "sudo rm -rf ${RG_ROOT}" 122 | execute "sudo rm ${RG_LINK}" 123 | fi 124 | fi 125 | } 126 | 127 | function install_ripgrep() { 128 | local RG_VER=${DEVSTRAP_RG_VER} 129 | local RG_TAR="ripgrep-${RG_VER}-x86_64-unknown-linux-musl.tar.gz" 130 | 131 | if ! cmd_exists "${pkg_exe}"; then 132 | execute "wget --no-check-certificate https://github.com/BurntSushi/ripgrep/releases/download/${RG_VER}/${RG_TAR}" || return $? 133 | execute "sudo mkdir -p /usr/local/rg && sudo tar -C /usr/local/rg --strip-components 1 -xzf ${RG_TAR}" 134 | if [ ! -e "/usr/local/bin/rg" ]; then 135 | execute "sudo ln -s /usr/local/rg/rg /usr/local/bin/rg" 136 | fi 137 | local exitCode=$? 138 | execute "rm ${RG_TAR}" 139 | 140 | return $exitCode 141 | else 142 | return 0 143 | fi 144 | } 145 | 146 | function upgrade_fd() { 147 | always_install_fd 148 | } 149 | 150 | function install_fd() { 151 | if ! cmd_exists "${pkg_exe}"; then 152 | always_install_fd 153 | else 154 | return 0 155 | fi 156 | } 157 | 158 | function always_install_fd() { 159 | local FD_VER=${DEVSTRAP_FD_VER} 160 | local FD_DEB="fd_${FD_VER}_amd64.deb" 161 | 162 | # if ! cmd_exists "${pkg_exe}"; then 163 | execute "wget --no-check-certificate https://github.com/sharkdp/fd/releases/download/v${FD_VER}/${FD_DEB}" || return $? 164 | execute "sudo dpkg -i ${FD_DEB}" 165 | local exitCode=$? 166 | execute "rm ${FD_DEB}" 167 | 168 | return $exitCode 169 | #else 170 | # return 0 171 | #fi 172 | } 173 | 174 | function upgrade_peco() { 175 | remove_peco 176 | install_peco 177 | } 178 | 179 | function remove_peco() { 180 | local PECO_ROOT="/usr/local/peco" 181 | local PECO_EXE="peco" 182 | local PECO_LINK="/usr/local/bin/peco" 183 | if cmd_exists "${PECO_EXE}"; then 184 | if [[ -d "${PECO_ROOT}" && "${RG_LINK}" == "$(which peco)" && "$(realpath ${PECO_LINK})" == "${PECO_ROOT}/peco" ]]; then 185 | execute "sudo rm -rf ${PECO_ROOT}" 186 | execute "sudo rm ${PECO_LINK}" 187 | fi 188 | fi 189 | } 190 | 191 | function install_peco() { 192 | local PECO_VER=${DEVSTRAP_PECO_VER} 193 | local PECO_TAR="peco_linux_amd64.tar.gz" 194 | 195 | if ! cmd_exists "${pkg_exe}"; then 196 | execute "wget --no-check-certificate https://github.com/peco/peco/releases/download/v${PECO_VER}/${PECO_TAR}" || return $? 197 | execute "sudo mkdir -p /usr/local/peco && sudo tar -C /usr/local/peco --strip-components 1 -xzf ${PECO_TAR}" 198 | if [ ! -e "/usr/local/bin/peco" ]; then 199 | execute "sudo ln -s /usr/local/peco/peco /usr/local/bin/peco" 200 | fi 201 | local exitCode=$? 202 | execute "rm ${PECO_TAR}" 203 | 204 | return $exitCode 205 | else 206 | return 0 207 | fi 208 | } 209 | 210 | function install_bazel() { 211 | execute "sudo apt-get install openjdk-8-jdk" || return $? 212 | execute "echo \"deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8\" | sudo tee /etc/apt/sources.list.d/bazel.list" || return $? 213 | execute "curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -" || return $? 214 | update || return $? 215 | install_package 216 | } 217 | 218 | function install_protobuf() { 219 | # http://google.github.io/proto-lens/installing-protoc.html 220 | local PB_VER=${DEVSTRAP_PROTOBUF_VER} 221 | local PB_ZIP="protoc-${PB_VER}-linux-x86_64.zip" 222 | local PROTOC_INC_PATH="/usr/local/include/google" 223 | local PROTOC_EXE_PATH="/usr/local/bin/protoc" 224 | 225 | if ! cmd_exists "${pkg_exe}"; then 226 | execute "curl -OL https://github.com/google/protobuf/releases/download/v${PB_VER}/${PB_ZIP}" 227 | execute "sudo unzip -o ${PB_ZIP} -d /usr/local bin/protoc && sudo unzip -o ${PB_ZIP} -d /usr/local include/*" 228 | execute "sudo chmod o+rx ${PROTOC_EXE_PATH}" 229 | execute "sudo chmod o+rx -R ${PROTOC_INC_PATH}" 230 | local exitCode=$? 231 | execute "rm -f ${PB_ZIP}" 232 | 233 | return $exitCode 234 | else 235 | return 0 236 | fi 237 | } 238 | 239 | function remove_protobuf() { 240 | local PROTOC_EXE_PATH="/usr/local/bin/protoc" 241 | local PROTOC_INC_PATH="/usr/local/include/google" 242 | local PROTOC_EXE="protoc" 243 | if cmd_exists "${PROTOC_EXE}"; then 244 | if [ -f "${PROTOC_EXE_PATH}" ]; then 245 | execute "sudo rm -f ${PROTOC_EXE_PATH}" 246 | fi 247 | if [ -d "${PROTOC_INC_PATH}" ]; then 248 | execute "sudo rm -rf ${PROTOC_INC_PATH}" 249 | fi 250 | fi 251 | } 252 | 253 | function upgrade_protobuf() { 254 | remove_protobuf 255 | install_protobuf 256 | } 257 | -------------------------------------------------------------------------------- /scripts/install/ubuntu/package.conf: -------------------------------------------------------------------------------- 1 | # seperation: ';' 2 | # NOTE: Empty tail line is necessary 3 | # 4 | # FORMAT: pkg_name; pkg_desc; pkg_sel; pkg_type; pkg_exe; pkg_cmd 5 | # pkg_name: Package Name; should exactly the same with package manager; no duplicated package allowed 6 | # pkg_desc: A readable package Description 7 | # pkg_sel: Default selection in whiptail box, on - selected, off - not selected, hide - not shown but selected. 8 | # pkg_type: Package manager type, available in apt, git, npm, go, gem, etc., should be registed before use 9 | # pkg_exe: Package executable name (Optional) 10 | # pkg_cmd: A command to install the package (Optional) 11 | 12 | install_update_repo; Update Repo; on; seperator; ; 13 | # pre_install; Update apt repo; hide; cmd; ; pre_install 14 | apt_update; Update apt repo; on; cmd; ; update 15 | apt_upgrade; Upgrade installed packages to latest version;on; cmd; ; upgrade 16 | 17 | install_ubuntu_packages; Install Packages; on; seperator; ; 18 | 19 | build-essential; Build Essential; on; apt; ; 20 | debian-archive-keyring; GnuPG archive keys; on; apt; ; 21 | software-properties-common; Install software-properties-common Package; on; apt; ; 22 | 23 | curl; cURL; on; apt;; 24 | wget; wget; on; apt;; 25 | git; git; on; apt;; 26 | htop; htop; on; apt;; 27 | colordiff; Colorized Diff; on; apt;; 28 | alien; convert and install packages; off; apt;; 29 | xvfb; fake x server for headless; off; apt;; 30 | xsel; cmd tool to access X clipboard and selection buffers; on; apt;; 31 | rlwrap; readline feature command line wrapper; on; apt;; 32 | wrk; HTTP benchmarking tool; off; apt;; 33 | libgconf-2-4; Depends by other pkgs, e.g. VSCode; on; apt;; 34 | 35 | zsh; ZSH; on; apt;; 36 | fonts-powerline; powerline symbols font; on; apt;; 37 | tmux; Terminal Multiplexer; on; apt;; 38 | gnome-do; Application Launcher; off; apt;; 39 | 40 | emacs; GNU Emacs; off; apt;; 41 | emacs-nox; GNU Emacs without X; off; apt;; 42 | emacs25; GNU Emacs 25; off; cmd; ; install_emacs_ppa 43 | emacs25-nox; GNU Emacs 25 without X; off; cmd; ; install_emacs_ppa 44 | emacs26; GNU Emacs 26; off; cmd; ; install_emacs_ppa 45 | emacs26-nox; GNU Emacs 26 without X; off; cmd; ; install_emacs_ppa 46 | 47 | editorconfig; Coding style indenter for all editors; on; apt;; 48 | 49 | vim; Vi IMproved; off; apt;; 50 | 51 | python; Python; off; apt;; 52 | python-pip; Python Package Manager; off; apt;; 53 | python3; Python3; on; apt;; 54 | python3-pip; Python3 Package Manager; on; apt;; 55 | upgrade_pip; Upgrade pip; on; cmd; ;sudo pip install --upgrade pip 56 | 57 | ruby; Ruby; on; apt;; 58 | ruby-dev; Ruby Development Package; on; apt;; 59 | 60 | nginx; NGINX; on; apt;; 61 | 62 | silversearcher-ag; The silver seacher, AKA ack+grep; on; apt;; 63 | ripgrep; GREP like searcher, faster than ag; on; cmd; rg; install_ripgrep 64 | upgrade_riggrep; Upgrade Ripgrep rg; off; cmd; ; upgrade_ripgrep 65 | fd; Simple, fast and user-friendly alternative to find; on; cmd; fd; install_fd 66 | upgrade_fd; Upgrade fd, alternative to find; off; cmd_nc; fd; upgrade_fd 67 | peco; Simplistic interactive filtering tool; on; cmd; peco; install_peco 68 | upgrade_peco; Upgrade peco; off; cmd; ; upgrade_peco 69 | 70 | protobuf; Install Protobuf; off; cmd; protoc; install_protobuf 71 | upgrade_protobuf; Upgrade Protobuf; off; cmd; ; upgrade_protobuf 72 | 73 | golang; Go Language; on; cmd; go; install_golang 74 | upgrade_golang; Upgrade Golang; off; cmd; ; upgrade_golang 75 | 76 | rust; Rust Language; on; cmd; rustc; install_rust 77 | 78 | docker-ce; Docker CE; on; cmd; docker ;install_docker 79 | nodejs10; NodeJS_10; off; cmd; node; install_nodejs10 80 | nodejs12; NodeJS_12; off; cmd; node; install_nodejs12 81 | # npm; Package manager for NodeJS; on; apt;; 82 | vscode; VSCode; on; cmd; vscode ;install_vscode 83 | 84 | openjdk-8-jdk; OpenJDK 8; on; apt;; 85 | bazel; Bazel build tool; on; cmd; bazel; install_bazel 86 | fcitx-googlepinyin; Google Pinyin for Chinese input; off; apt;; 87 | 88 | # Apps 89 | cherrytree; A cross platform Note-Taking App; off; apt;; 90 | chromium-browser; Chromium Browser; off; apt;; 91 | 92 | # This is the last thing that to install Ubuntu, setup environment variables here. 93 | # post_install_ubuntu_pkgs; Setting up environments; on; seperator;; 94 | # post_install; Setup environment variables e.g. PATH etc.; hide; cmd; ; post_install 95 | 96 | # End of package.conf 97 | -------------------------------------------------------------------------------- /scripts/install/versions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # https://go.dev/dl/ 4 | DEVSTRAP_GO_VER="1.18.1" 5 | 6 | # https://github.com/BurntSushi/ripgrep/releases 7 | DEVSTRAP_RG_VER="11.0.2" 8 | 9 | # https://github.com/sharkdp/fd/releases 10 | DEVSTRAP_FD_VER="7.4.0" 11 | 12 | # https://github.com/peco/peco/releases 13 | DEVSTRAP_PECO_VER="0.5.3" 14 | 15 | # https://github.com/google/protobuf/releases 16 | DEVSTRAP_PROTOBUF_VER="3.17.3" 17 | -------------------------------------------------------------------------------- /scripts/utils.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | _DEBUG="off" 4 | _DRYRUN="off" 5 | _ALLYES="off" 6 | _SELECTNONE="off" 7 | _ENV_ONLY="off" 8 | 9 | function print_options_help() { 10 | echo "Usage: $0 [options]" 11 | echo "Options:" 12 | echo "-h | --help print this help" 13 | echo "-d | --debug enable debug mode" 14 | echo "-r | --dryrun enable dryrun mode" 15 | echo " --all-yes install all packages without selecting" 16 | echo "-n | --sel-none select none packages in box" 17 | echo " --env-only setup environments only" 18 | } 19 | 20 | function parse_options() { 21 | while [[ $# -ge 1 ]] 22 | do 23 | key="$1" 24 | 25 | case $key in 26 | -d|--debug) 27 | print_in_purple "debug enabled\n" 28 | _DEBUG="on" 29 | ;; 30 | -r|--dryrun) 31 | print_in_purple "dryrun enabled\n" 32 | _DRYRUN="on" 33 | ;; 34 | --all-yes) 35 | print_in_purple "all yes mode enabled\n" 36 | _ALLYES="on" 37 | ;; 38 | -n|--sel-none) 39 | print_in_purple "select none mode enabled\n" 40 | _SELECTNONE="on" 41 | ;; 42 | --env-only) 43 | print_in_purple "env only mode enabled\n" 44 | _ENV_ONLY="on" 45 | ;; 46 | -h|--help) 47 | print_options_help 48 | exit 49 | ;; 50 | *) 51 | # unknown option 52 | ;; 53 | esac 54 | shift # past argument or value 55 | done 56 | } 57 | 58 | YES=0 59 | NO=1 60 | function promote_yn() { 61 | if [ "$#" -ne 2 ]; then 62 | print_error "ERROR with promote_yn. Usage: promote_yn " 63 | print_fatal_error_msg_and_exit $FUNCNAME $@ 64 | fi 65 | 66 | eval ${2}=$NO 67 | print_question "$1 [Yn]" 68 | read yn 69 | DEBUG_PRINT "Entered $yn" 70 | case $yn in 71 | [Yy]*|'' ) eval ${2}=$YES;; 72 | [Nn]* ) eval ${2}=$NO;; 73 | *) eval ${2}=$NO;; 74 | esac 75 | } 76 | 77 | # Almost the same as 'promote_yn', the only difference is the default selection is No. 78 | function promote_ny() { 79 | if [ "$#" -ne 2 ]; then 80 | print_error "ERROR with promote_ny. Usage: promote_ny " 81 | print_fatal_error_msg_and_exit $FUNCNAME $@ 82 | fi 83 | 84 | eval ${2}=$NO 85 | print_question "$1 [Ny]" 86 | read yn 87 | DEBUG_PRINT "Entered $yn" 88 | case $yn in 89 | [Nn]*|'' ) eval ${2}=$NO;; 90 | [Yy]* ) eval ${2}=$YES;; 91 | *) eval ${2}=$NO;; 92 | esac 93 | } 94 | 95 | function ask_for_sudo() { 96 | # Ask for the administrator password upfront. 97 | sudo -v &> /dev/null 98 | 99 | # Update existing `sudo` time stamp 100 | # until this script has finished. 101 | # 102 | # https://gist.github.com/cowboy/3118588 103 | while true; do 104 | sudo -n true 105 | sleep 60 106 | kill -0 "$$" || exit 107 | done &> /dev/null & 108 | } 109 | 110 | function IS_TRAVIS() { 111 | [[ "$TRAVIS" == "true" ]] 112 | } 113 | 114 | function DRYRUN() { 115 | [[ "$_DRYRUN" == "on" ]] 116 | } 117 | 118 | function ALLYES() { 119 | [[ "$_ALLYES" == "on" ]] 120 | } 121 | 122 | function ENV_ONLY() { 123 | [[ "$_ENV_ONLY" == "on" ]] 124 | } 125 | 126 | function SELECTNONE() { 127 | [[ "$_SELECTNONE" == "on" ]] 128 | } 129 | 130 | function DEBUG() { 131 | [[ "$_DEBUG" == "on" ]] 132 | } 133 | 134 | function DEBUG_PRINT() { 135 | DEBUG && printf "$1" 136 | } 137 | 138 | function DEBUG_BEGIN() { 139 | DEBUG && set -x 140 | } 141 | 142 | function DEBUG_END() { 143 | DEBUG && set +x 144 | } 145 | 146 | function continue_as_root() { 147 | local _continue=$NO 148 | if [[ $(whoami) == "root" ]]; then 149 | promote_ny "Are you sure you want to execute as the user 'root'?" _continue 150 | else 151 | _continue=$YES 152 | fi 153 | 154 | [[ $_continue == $YES ]] 155 | } 156 | 157 | function trim_quote() { 158 | local var="$*" 159 | var="${var#\"}" # remove leading quotes 160 | var="${var%\"}" # remove trailing quotes 161 | # var=${var//\"} # remove all quotes... 162 | echo -n $var 163 | } 164 | 165 | function trim_space() { 166 | local var="$*" 167 | var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters 168 | var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters 169 | echo -n $var 170 | } 171 | 172 | function cmd_exists() { 173 | command -v "$1" &> /dev/null 174 | } 175 | 176 | function fn_exists() { 177 | declare -f "$1" &> /dev/null 178 | } 179 | 180 | function kill_all_subprocesses() { 181 | local i="" 182 | 183 | for i in $(jobs -p); do 184 | kill "$i" 185 | wait "$i" &> /dev/null 186 | done 187 | } 188 | 189 | function set_trap() { 190 | trap -p "$1" | grep "$2" &> /dev/null \ 191 | || trap '$2' "$1" 192 | } 193 | 194 | function execute() { 195 | local -r CMDS="$1" 196 | local -r MSG="${2:-$1}" 197 | local -r TMP_FILE="$(mktemp /tmp/XXXXXX)" 198 | 199 | local exitCode=0 200 | local cmdsPID="" 201 | 202 | if DRYRUN; then 203 | print_result $exitCode "${MSG}" 204 | print_in_blue " ↳ DRYRUN: ${CMDS}\n" 205 | else 206 | if DEBUG; then 207 | echo "$CMDS" 208 | eval "$CMDS" 209 | exitCode=$? 210 | print_result $exitCode "$MSG" 211 | return $exitCode 212 | fi 213 | 214 | # If the current process is ended, 215 | # also end all its subprocesses. 216 | set_trap "EXIT" "kill_all_subprocesses" 217 | 218 | # Execute commands in background 219 | eval "$CMDS" \ 220 | &> /dev/null \ 221 | 2> "$TMP_FILE" & 222 | 223 | cmdsPID=$! 224 | 225 | # Show a spinner if the commands 226 | # require more time to complete. 227 | show_spinner "$cmdsPID" "$CMDS" "$MSG" 228 | 229 | # Wait for the commands to no longer be executing 230 | # in the background, and then get their exit code. 231 | wait "$cmdsPID" &> /dev/null 232 | exitCode=$? 233 | 234 | # Print output based on what happened. 235 | print_result $exitCode "$MSG" 236 | 237 | if [ $exitCode -ne 0 ]; then 238 | print_error_stream < "$TMP_FILE" 239 | fi 240 | 241 | rm -rf "$TMP_FILE" 242 | fi 243 | 244 | return $exitCode 245 | } 246 | 247 | function get_os() { 248 | local os="" 249 | local kernelName="" 250 | 251 | kernelName="$(uname -s)" 252 | 253 | if [ "$kernelName" == "Darwin" ]; then 254 | os="macos" 255 | elif [ "$kernelName" == "Linux" ]; then 256 | if [ -f "/etc/lsb-release" ]; then 257 | os="ubuntu" 258 | elif [ -f "/etc/debian_version" ]; then 259 | os="debian" 260 | elif [ -f "/etc/redhat-release" ]; then 261 | os="redhat" 262 | elif [ -f "/etc/SuSE-release" ]; then 263 | os="suse" 264 | fi 265 | else 266 | os="$kernelName" 267 | fi 268 | 269 | printf "%s" "$os" 270 | } 271 | 272 | function get_os_version() { 273 | local os="" 274 | local version="" 275 | 276 | os="$(get_os)" 277 | 278 | if [ "$os" == "macos" ]; then 279 | version="$(sw_vers -productVersion)" 280 | elif [ "$os" == "ubuntu" ]; then 281 | version="$(lsb_release -d | cut -f2 | cut -d' ' -f2)" 282 | fi 283 | 284 | printf "%s" "$version" 285 | } 286 | 287 | function get_arch() { 288 | printf "%s" "$(uname -m)" 289 | } 290 | 291 | function is_supported_version() { 292 | declare -a v1=(${1//./ }) 293 | declare -a v2=(${2//./ }) 294 | local i="" 295 | 296 | # Fill empty positions in v1 with zeros. 297 | for (( i=${#v1[@]}; i<${#v2[@]}; i++ )); do 298 | v1[i]=0 299 | done 300 | 301 | for (( i=0; i<${#v1[@]}; i++ )); do 302 | # Fill empty positions in v2 with zeros. 303 | if [[ -z ${v2[i]} ]]; then 304 | v2[i]=0 305 | fi 306 | 307 | if (( 10#${v1[i]} < 10#${v2[i]} )); then 308 | return 1 309 | elif (( 10#${v1[i]} > 10#${v2[i]} )); then 310 | return 0 311 | fi 312 | done 313 | } 314 | 315 | function is_git_repository() { 316 | git rev-parse &> /dev/null 317 | } 318 | 319 | function sync_repo() { 320 | local repo_uri=${1/\~/$HOME} 321 | local repo_path=${2/\~/$HOME} 322 | 323 | if [ ! -e ${repo_path} ]; then 324 | execute "mkdir -p ${repo_path}" 325 | execute "git clone ${repo_uri} ${repo_path}" 326 | else 327 | cd ${repo_path} && git pull origin master && cd - >/dev/null 328 | fi 329 | } 330 | 331 | function create_link() { 332 | local SOURCE=${1/\~/$HOME} 333 | local DEST=${2/\~/$HOME} 334 | 335 | if [ ! -e ${SOURCE} ]; then 336 | print_error "${SOURCE} doen't exists." 337 | return 2 338 | fi 339 | 340 | if [[ -f ${DEST} && ! -h ${DEST} ]]; then 341 | # If dest is a file and not a symbolic link, backup it 342 | execute "mv ${DEST} ${DEST}.devstrap.bak" 343 | fi 344 | 345 | local dest_dir=$(dirname ${DEST}) 346 | if [ ! -d $dest_dir ]; then 347 | execute "mkdir -p ${dest_dir}" 348 | fi 349 | 350 | execute "ln -s -f ${SOURCE} ${DEST}" 351 | } 352 | 353 | ############################################################ 354 | # Print functions 355 | ############################################################ 356 | 357 | # Use colors, but only if connected to a terminal, and that terminal 358 | # supports them. 359 | if which tput >/dev/null 2>&1; then 360 | ncolors=$(tput colors) 361 | fi 362 | if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then 363 | RED="$(tput setaf 1 2> /dev/null)" 364 | GREEN="$(tput setaf 2 2> /dev/null)" 365 | YELLOW="$(tput setaf 3 2> /dev/null)" 366 | BLUE="$(tput setaf 4 2> /dev/null)" 367 | PURPLE="$(tput setaf 5 2> /dev/null)" 368 | BOLD="$(tput bold 2> /dev/null)" 369 | NORMAL="$(tput sgr0 2> /dev/null)" 370 | else 371 | RED="" 372 | GREEN="" 373 | YELLOW="" 374 | BLUE="" 375 | PURPLE="" 376 | BOLD="" 377 | NORMAL="" 378 | fi 379 | 380 | function println() { 381 | printf "%s\n" $1 382 | } 383 | 384 | declare _indent=0 385 | function indent() { 386 | local spacing="" 387 | local i="" 388 | 389 | for(( i=0; i<$_indent; i++ )); do 390 | spacing="${spacing} " 391 | done 392 | 393 | echo -n "$spacing" 394 | } 395 | 396 | function print_in_color() { 397 | printf "%b" \ 398 | "$2" \ 399 | "$(indent)$1" \ 400 | "${NORMAL}" 401 | } 402 | 403 | function print_in_red() { 404 | print_in_color "$1" $RED 405 | } 406 | 407 | function print_in_green() { 408 | print_in_color "$1" $GREEN 409 | } 410 | 411 | function print_in_yellow() { 412 | print_in_color "$1" $YELLOW 413 | } 414 | 415 | function print_in_blue() { 416 | print_in_color "$1" $BLUE 417 | } 418 | 419 | function print_in_purple() { 420 | print_in_color "$1" $PURPLE 421 | } 422 | 423 | function print_question() { 424 | print_in_yellow " [?] $1" 425 | } 426 | 427 | function print_error() { 428 | print_in_red " [✖] $1 $2\n" 429 | } 430 | 431 | function print_error_stream() { 432 | while read -r line; do 433 | print_error "↳ ERROR: $line" 434 | done 435 | } 436 | 437 | function print_call_stack() { 438 | # Print out the stack trace described by $function_stack 439 | local -r SKIP_STACKS=2 440 | local i="" 441 | 442 | if [ ${#FUNCNAME[@]} -gt 2 ] 443 | then 444 | print_error "↳ Callstacks:" 445 | for ((i=${SKIP_STACKS};i<${#FUNCNAME[@]};i++)) 446 | do 447 | print_error " $[$i-${SKIP_STACKS}]: ${BASH_SOURCE[$i]}:${BASH_LINENO[$i-1]} ${FUNCNAME[$i]}(...)" 448 | done 449 | fi 450 | println '' 451 | } 452 | 453 | function print_callstack() { 454 | print_error "Callstacks:" 455 | local frame=1 456 | while caller $frame; do 457 | ((frame++)); 458 | done 459 | println '' 460 | } 461 | 462 | function print_fatal_error_msg_and_exit() { 463 | funcname=$1 464 | shift 465 | print_error "Error occured in \"$0\", when calling \"$funcname\" with \"$@\"." 466 | # print_callstack 467 | print_call_stack 468 | exit 1 469 | } 470 | 471 | function print_result() { 472 | if [ "$1" -eq 0 ]; then 473 | print_success "$2" 474 | else 475 | print_error "$2" 476 | fi 477 | 478 | return "$1" 479 | } 480 | 481 | function print_success() { 482 | print_in_green " [✔] $1\n" 483 | } 484 | 485 | function print_warning() { 486 | print_in_yellow " [!] $1\n" 487 | } 488 | 489 | function print_info() { 490 | print_in_blue " [i] $1\n" 491 | } 492 | 493 | function show_spinner() { 494 | local -r FRAMES='/-\|' 495 | 496 | # shellcheck disable=SC2034 497 | local -r NUMBER_OR_FRAMES=${#FRAMES} 498 | 499 | local -r CMDS="$2" 500 | local -r MSG="$3" 501 | local -r PID="$1" 502 | 503 | local i=0 504 | local frameText="" 505 | 506 | # Note: In order for the Travis CI site to display 507 | # things correctly, it needs special treatment, hence, 508 | # the "is Travis CI?" checks. 509 | if ! IS_TRAVIS; then 510 | # Provide more space so that the text hopefully 511 | # doesn't reach the bottom line of the terminal window. 512 | # 513 | # This is a workaround for escape sequences not tracking 514 | # the buffer position (accounting for scrolling). 515 | # 516 | # See also: https://unix.stackexchange.com/a/278888 517 | printf "\n\n\n" 518 | tput cuu 3 519 | tput sc 520 | fi 521 | 522 | # Display spinner while the commands are being executed. 523 | while kill -0 "$PID" &>/dev/null; do 524 | frameText="$(indent) [${FRAMES:i++%NUMBER_OR_FRAMES:1}] $MSG" 525 | # Print frame text. 526 | if ! IS_TRAVIS; then 527 | printf "%s\n" "$frameText" 528 | else 529 | printf "%s" "$frameText" 530 | fi 531 | 532 | sleep 0.2 533 | 534 | # Clear frame text. 535 | if ! IS_TRAVIS; then 536 | tput rc 537 | else 538 | printf "\r" 539 | fi 540 | done 541 | } 542 | 543 | ############################################################ 544 | # Package Conf File Reader 545 | ############################################################ 546 | 547 | declare -A def_packages 548 | declare -A sel_packages 549 | declare -a order_packages 550 | declare package_count=0 551 | 552 | declare -r PACKAGE_IFS=$';' 553 | declare -r PKG_DEFS="pkg_name pkg_desc pkg_sel pkg_type pkg_exe pkg_cmd" 554 | 555 | function parse_package_def() { 556 | if [[ -z $1 ]]; then 557 | print_fatal_error_msg_and_exit $FUNCNAME $@ 558 | fi 559 | 560 | local OLD_IFS=$IFS 561 | IFS=$PACKAGE_IFS 562 | eval "read $PKG_DEFS <<<\"$1\"" 563 | eval "vars=($PKG_DEFS)" 564 | local var="" 565 | for var in ${vars[@]}; do 566 | eval "$var=\"$(trim_space ${!var})\"" 567 | done 568 | IFS=$OLD_IFS 569 | } 570 | 571 | declare MAX_NAME_LEN=0 572 | declare MAX_DESC_LEN=0 573 | function read_package_conf() { 574 | local conf_file=$1 575 | local OLD_IFS=$IFS 576 | 577 | while IFS=$'\n' read -r line; do 578 | if [[ ${#line} -gt 1 && $line != [#]* ]]; then 579 | IFS=$PACKAGE_IFS 580 | parse_package_def "${line}" 581 | if [[ -z ${sel_packages["$pkg_name"]} && -z ${def_packages["$pkg_name"]} ]]; then 582 | def_packages["$pkg_name"]="${line}" 583 | sel_packages["$pkg_name"]=0 584 | order_packages+=( $pkg_name ) 585 | ((++package_count)) 586 | 587 | local name_len=0 588 | local desc_len=0 589 | if [ ${pkg_sel} == "hide" ]; then 590 | : 591 | elif [ ${pkg_type} == "seperator" ]; then 592 | # Seperator: ========== 593 | # 3 spaces between description and back seperator 594 | name_len=10 595 | (( desc_len = ${#pkg_desc} + 10 + 3 + 2 )) # 2 ending spaces in seperator 596 | else 597 | name_len=${#pkg_name} 598 | (( desc_len = ${#pkg_desc} + 4 )) # 4 ending spaces 599 | fi 600 | # Update max length 601 | if [ $name_len -gt $MAX_NAME_LEN ]; then MAX_NAME_LEN=$name_len; fi 602 | if [ $desc_len -gt $MAX_DESC_LEN ]; then MAX_DESC_LEN=$desc_len; fi 603 | else 604 | IFS=$OLD_IFS 605 | print_error "Duplicated packages found! name: $pkg_name, desc: $pkg_desc, type: $pkg_type" 606 | print_fatal_error_msg_and_exit $FUNCNAME $@ 607 | fi 608 | fi 609 | done < $conf_file 610 | 611 | IFS=$OLD_IFS 612 | } 613 | 614 | function print_packages() { 615 | local OLD_IFS=$IFS 616 | IFS=$PACKAGE_IFS 617 | 618 | local name="" 619 | for name in "${order_packages[@]}"; do 620 | local pkg 621 | pkg=${def_packages[$name]} 622 | parse_package_def "${pkg}" 623 | printf "pkg name: %s, pkg desc: %s, pkg type: %s\n" "${pkg_name}" "${pkg_desc}" "${pkg_type}" 624 | done 625 | IFS=$OLD_IFS 626 | 627 | local key="" 628 | for key in "${!sel_packages[@]}"; do 629 | printf "pkg name: $key, selected: ${sel_packages[${key}]}\n" 630 | done 631 | } 632 | 633 | function select_package() { 634 | pkg_name=$1 635 | if [[ -z ${sel_packages[${pkg_name}]} ]]; then 636 | print_error "$pkg_name not found!" 637 | print_fatal_error_msg_and_exit $FUNCNAME $@ 638 | else 639 | sel_packages["$pkg_name"]=1 640 | fi 641 | } 642 | 643 | function has_selected_package() { 644 | pkg_name=$1 645 | if [[ -z ${sel_packages[${pkg_name}]} ]]; then 646 | print_error "$pkg_name not found!" 647 | print_fatal_error_msg_and_exit $FUNCNAME $@ 648 | else 649 | if [[ ${sel_packages[${pkg_name}]} == 1 ]]; then 650 | return 0 # true 651 | else 652 | return 1 # false 653 | fi 654 | fi 655 | } 656 | 657 | function show_select_package_box() { 658 | local max_len 659 | # 16 is a magic number, looks like is the spaces between name and description columns 660 | (( max_len = $MAX_DESC_LEN + $MAX_NAME_LEN + 16 )) 661 | 662 | DIALOG_HEIGHT=40 663 | DIALOG_WIDTH=$max_len 664 | # ITEMS_COUNT=${#def_packages[@]} 665 | ITEMS_COUNT=30 666 | 667 | declare -a options 668 | declare -r SEP_LINE="==========" 669 | local OLD_IFS=$IFS 670 | IFS=$PACKAGE_IFS 671 | local name="" 672 | for name in "${order_packages[@]}" 673 | do 674 | local pkg 675 | pkg=${def_packages[$name]} 676 | parse_package_def "${pkg}" 677 | # Don't show 'hide' or 'seperator' 678 | if [[ ${pkg_sel} == "hide" || ${pkg_type} == "seperator" ]]; then 679 | select_package ${pkg_name} 680 | if [ ${pkg_type} == "seperator" ]; then 681 | options+=("${SEP_LINE}" "${pkg_desc} ${SEP_LINE} " "OFF") 682 | fi 683 | continue 684 | elif ALLYES; then 685 | select_package ${pkg_name} 686 | fi 687 | 688 | if ! SELECTNONE; then 689 | options+=("${pkg_name}" "${pkg_desc} " "${pkg_sel}") 690 | else 691 | options+=("${pkg_name}" "${pkg_desc} " "OFF") 692 | fi 693 | done 694 | IFS=$OLD_IFS 695 | 696 | if ! ALLYES; then 697 | result=$( whiptail --title "Select packages you want to install" \ 698 | --fb --ok-button "Done" \ 699 | --clear \ 700 | --checklist "Packages:" $DIALOG_HEIGHT $DIALOG_WIDTH $ITEMS_COUNT \ 701 | "${options[@]}" \ 702 | 3>&2 2>&1 1>&3-) 703 | 704 | [[ "$?" == 1 ]] && return 1 705 | [[ ${#result} == 0 ]] && return 1 706 | 707 | local item="" 708 | for item in $result; do 709 | local package_name=$(trim_quote $item) 710 | if [ ! ${package_name} == ${SEP_LINE} ]; then 711 | select_package $package_name 712 | fi 713 | done 714 | fi 715 | 716 | return 0 717 | } 718 | 719 | function check_and_install_whiptail() { 720 | if ! cmd_exists "whiptail"; then 721 | case $(get_os) in 722 | ubuntu) 723 | execute "sudo apt-get install -y whiptail" 724 | ;; 725 | macos) 726 | if ! cmd_exists 'brew'; then 727 | execute "ruby -e \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"" "Homebrew" 728 | fi 729 | execute "brew install newt" 730 | ;; 731 | *) 732 | print_error "Unsupported OS type $(get_os)" 733 | print_fatal_error_msg_and_exit $FUNCNAME $@ 734 | ;; 735 | esac 736 | fi 737 | 738 | if ! $(whiptail -v > /dev/null 2>&1); then 739 | print_error "Failed to install whiptail." 740 | print_fatal_error_msg_and_exit $FUNCNAME $@ 741 | fi 742 | } 743 | 744 | ############################################################ 745 | # Package Installer Register and common installers 746 | ############################################################ 747 | 748 | declare -A pkg_installers 749 | function regist_pkg_installer() { 750 | local type=$1 751 | local installer=$2 752 | 753 | if [[ -z ${pkg_installers["$type"]} ]]; then 754 | pkg_installers["$type"]="$installer" 755 | else 756 | print_error "Duplicated packages installer! type: '$type', installer: '$installer'" 757 | print_fatal_error_msg_and_exit $FUNCNAME $@ 758 | fi 759 | } 760 | 761 | function install_selected_packages() { 762 | local pkg="" 763 | for pkg in ${order_packages[@]}; do 764 | if has_selected_package $pkg; then 765 | install_it $pkg 766 | fi 767 | done 768 | } 769 | 770 | function install_it() { 771 | local pkg="$1" 772 | parse_package_def "${def_packages[${pkg}]}" 773 | 774 | DEBUG_PRINT "\nDealing with selected package:\n" 775 | DEBUG_PRINT " pkg_name: ${pkg_name}\n" 776 | DEBUG_PRINT " pkg_desc: ${pkg_desc}\n" 777 | DEBUG_PRINT " pkg_exe: ${pkg_exe}\n" 778 | DEBUG_PRINT " pkg_type: ${pkg_type}\n" 779 | DEBUG_PRINT " pkg_cmd: ${pkg_cmd}\n" 780 | DEBUG_PRINT "\n" 781 | 782 | if [[ -z ${pkg_installers[${pkg_type}]} ]]; then 783 | print_error "Unknown package type: '${pkg_type}' of '${pkg_name}'" 784 | else 785 | installer="${pkg_installers[${pkg_type}]}" 786 | eval "${installer}" 787 | fi 788 | 789 | DEBUG_PRINT "\nDone with selected package: ${pkg_name}\n" 790 | } 791 | 792 | function install_via_cmd() { 793 | if fn_exists "${pkg_cmd}"; then 794 | # install via a pre-defined command 795 | print_info "Starting ${pkg_desc} ..." 796 | DRYRUN && print_in_purple "↱ function ${pkg_cmd} ↰\n" 797 | ((_indent++)) 798 | eval "$pkg_cmd" 799 | local exitCode=$? 800 | ((_indent--)) 801 | DRYRUN && print_in_purple "↳ function ${pkg_cmd} ↲\n" 802 | print_result $exitCode "${pkg_desc}" 803 | else 804 | execute "$pkg_cmd" "$pkg_desc" 805 | fi 806 | } 807 | 808 | function check_and_install_via_cmd() { 809 | if ! cmd_exists "${pkg_exe}"; then 810 | install_via_cmd 811 | else 812 | print_success "${pkg_desc}" 813 | fi 814 | } 815 | 816 | regist_pkg_installer "cmd" "check_and_install_via_cmd" 817 | regist_pkg_installer "cmd_nc" "install_via_cmd" 818 | 819 | function install_print_seperator() { 820 | print_in_purple "\n • ${pkg_desc}\n\n" 821 | } 822 | regist_pkg_installer "seperator" "install_print_seperator" 823 | -------------------------------------------------------------------------------- /test/check_travis_result.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BASE_DIR="$(dirname ${BASH_SOURCE%/*})" 4 | 5 | . "${BASE_DIR}/scripts/utils.sh" 6 | 7 | function print_space_lines() { 8 | echo 9 | echo 10 | } 11 | 12 | print_info "cat /etc/passwd:" 13 | cat /etc/passwd | grep $(whoami) 14 | cat /etc/passwd | grep $(whoami) | grep "zsh" 15 | print_result $? "Oh-My-Zsh change shell" 16 | 17 | print_space_lines 18 | 19 | print_info "ls -al ~:" 20 | ls -al ~ 21 | 22 | print_space_lines 23 | 24 | print_info "ls -la ~/.oh-my-zsh" 25 | ls -al ~/.oh-my-zsh 26 | 27 | print_space_lines 28 | 29 | print_info "ls -al ~/bin" 30 | ls -al ~/bin 31 | 32 | print_space_lines 33 | 34 | print_info "ls -al $PWD" 35 | ls -al $PWD 36 | 37 | exit 0 -------------------------------------------------------------------------------- /test/pre_installations.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ $TRAVIS_OS_NAME == 'osx' ]]; then 4 | if ! hash brew 2>/dev/null; then 5 | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 6 | fi 7 | brew update 8 | brew install bash bash-completion 9 | sudo sh -c "echo '$(brew --prefix)/bin/bash' >> /etc/shells" 10 | sudo chsh -s $(brew --prefix)/bin/bash $(whoami) 11 | else 12 | # ubuntu 13 | sudo apt-get update 14 | sudo apt-get install realpath 15 | fi 16 | -------------------------------------------------------------------------------- /test/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BASE_DIR="$(dirname ${BASH_SOURCE%/*})" 4 | 5 | if [[ $TRAVIS_OS_NAME == 'osx' ]]; then 6 | ${BASE_DIR}/install.sh --env-only 7 | else 8 | ${BASE_DIR}/install.sh --all-yes 9 | fi 10 | -------------------------------------------------------------------------------- /test/test_prerequisites.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BASE_DIR="$(dirname ${BASH_SOURCE%/*})" 4 | 5 | . "${BASE_DIR}/scripts/utils.sh" 6 | 7 | execute "check_and_install_whiptail" 8 | 9 | # Log shell before install on Travis 10 | echo $SHELL 11 | -------------------------------------------------------------------------------- /test/ubuntu.16.04.docker.setup.sh: -------------------------------------------------------------------------------- 1 | sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list 2 | apt-get update && apt-get install -y git sudo whiptail apt-transport-https 3 | useradd -s /bin/bash -m -U admin 4 | #/usr/sbin/useradd -p \`openssl passwd -1 $PASS\` $USER 5 | # sudo visudo 6 | # Defaults env_reset,timestamp_timeout=30 --------------------------------------------------------------------------------