前些阵子爸妈去了趟香港顺便给我换了台电脑,怀着开心愉悦(并不)的心情开始了装机之旅。

基础部件

免费

  • 网络代理:ShadowsocksClashX
  • 文本编辑器:Sublime Text
  • 思维导图:xmind(免费版导出带水印)
  • 压缩软件:eZip
  • 邮件管理:网易邮件大师(自带Mail.app叉掉后不能提醒,而网易邮件大师可以在不完全关闭情况下提醒。缺点是可能会有一些广告,暂时只发现在新添加邮箱时会发送一封广告)
  • 最佳视频播放器:IINA
  • TODOList:滴答清单
  • 检查英文文章的拼写、句式、结构:1Checker

一次性付费

订阅式付费

  • 地表最强密码管理软件:1Password

小工具

免费

  • Wechat免密登陆&防撤回:WeChatTweak-macOS
  • 非敏感图片上传最佳图床:iPic(免费图床是匿名微博)
  • 卸载工具:AppCleaner(不能保证完全,单比直接拖回收站好很多)
  • 局域网内终端间通信:Dukto(Mac与Win传输文件等)
  • 壁纸软件:pap.er
  • 下载程序:Aria2GUI(百度云链接解析网站
  • 查看电池循环次数:Battery Health2
  • 避免合盖睡眠:InsomniaX
  • gif录制工具:GIPHY CAPTURE
  • BT下载工具:Folx(app内搜索种子下载)
  • 日历快速查看工具:PixelScheduler(在系统自带日历应用或其它第三方日历应用的基础上,展现在屏幕的边缘)
  • 根据发生的事件自动执行命令/脚本:ControlPlane
  • 正版 app 的序列号收集器:KCNScrew
  • 屏幕录像的最佳 app:LICEcap
  • 远程桌面:Microsoft Remote Desktop
  • 远程控制:TeamViewer(个人免费)

一次性付费

  • 增强版Spotlight:Alfred
  • 自动填充:CodeExpander(强烈推荐)

开发相关

免费

  • Vim插件(https://github.com/junegunn/vim-plug)
    • C++语法高亮: octol/vim-cpp-enhanced-highlight
    • markdown即时渲染: godlygeek/tabular, plasticboy/vim-markdown, suan/vim-instant-markdown
    • 批量注释: scrooloose/nerdcommenter
    • AI自动补全: zxqfl/tabnine-vim(sublime上也可以来一个)
    • 静态语法与代码风格检查: dense-analysis/ale(scrooloose/syntastic与YouCompleteMe默认冲突,需要设置let g:ycm_show_diagnostics_ui = 0,同时syntastic过于笨重;ale的语法检查是异步执行的,基本不会出现卡顿的情况,且默认会使用所有检查工具并发地进行检查)
  • IDE:xcode
  • 终端:iTerm + oh my zsh(iTerm可以用F12快速切换,oh my zsh可以智能扩展文件名以及配置好看的界面)
  • 命令行工具
    • Python版本管理:pyenv(舒服地切换py版本)
    • 终端窗口复用:tmux
    • 打印系统软硬件信息:Neofetch
    • 终端路径跳转:autojump
  • 富媒体内容下载:You-Get
  • 离线API文档:Dash
  • Latex:MacTex(可以用自带的TexShop或者参照如何用 macOS 优雅的敲 LaTeX配合sublime使用)
  • Markdown:Typora
  • 捕获流量:Wireshark
  • 图片压缩工具:Guetzli

zsh

# ==================== 垃圾箱 ======================
TERMINAL_TRASH="/Users/barriery/.Trash.terminal"
alias rm=rmtrash
alias rls='ls ${TERMINAL_TRASH}'
alias rll='ll ${TERMINAL_TRASH}'
alias rrm='/bin/rm -rf'
function rmtrash(){
  mv -i $@ ${TERMINAL_TRASH}/
}
function recover(){
  mv -i ${TERMINAL_TRASH}/$@ ./
}
function cleartrash(){
  /bin/rm -rf ${TERMINAL_TRASH}/*
}


# ===================== util =======================
function setcolor() {
    export BLACK='\033[30m'
    export RED='\033[0;31m'
    export GREEN='\033[32m'
    export YELLOW='\033[33m'
    export BLUE='\033[0;34m'
    export PURPLE='\033[35m'
    export CYAN='\033[36m'
    export WHITE='\033[37m'
    export BOLD='\033[1m'
    export NONE='\033[0m'
}
function unsetcolor() {
    unset BLACK
    unset RED
    unset GREEN
    unset YELLOW
    unset BLUE
    unset PURPLE
    unset CYAN
    unset WHITE
    unset BOLD
    unset NONE
}
function plog(){
    if [ $# -ne 3 ]; then
        plog ERROR red "Usage: plog LEVEL COLOR MESSAGE"
        return 1
    fi
    level=[$1]
    color=$2
    message=$3
    timestamp=[$(date "+%Y-%m-%d %H:%M:%S")]
    setcolor
    case ${color} in
        black|k|黑|30)
            level=${BLACK}${level}${NONE};;
        red|r|红|31)
            level=${RED}${level}${NONE};;
        green|g|绿|32)
            level=${GREEN}${level}${NONE};;
        yellow|y|黄|33)
            level=${YELLOW}${level}${NONE};;
        blue|b|蓝|34)
            level=${BLUE}${level}${NONE};;
        purple|p|紫|35)
            level=${PURPLE}${level}${NONE};;
        cyan|c|青|36)
            level=${CYAN}${level}${NONE};;
        white|w|白|37)
            level=${WHITE}${level}${NONE};;
        *)
            plog ERROR red "Unknown param color ${color}"
            unsetcolor
            return 1;;
    esac
    unsetcolor
    echo ${timestamp} ${level} ${message}
}

# mac 下的命令完成通知
function notify(){
  start_time=`date +%s`;
  cmd=`echo $@`;
  eval $@;
  end_time=`date +%s`
  timer_time=$((end_time-start_time))
  unit="s"
  if [[ $timer_time -gt 60 ]]; then
      unit="m"
      timer_time=`echo $(($timer_time/60.0))|awk '{printf("%.2f", $1)}'`
  fi
  terminal-notifier -title 'Notifier' -message 'command was finished in '${timer_time}${unit}'
'${cmd} -sound default -execute "open /Applications/iTerm.app";
}


# ===================== 代理 =======================
function setproxy(){
  export http_proxy="socks5://0.0.0.0:1086";
  export https_proxy="socks5://0.0.0.0:1086";
  # export ALL_PROXY="socks5://127.0.0.1:1086";
}
function unsetproxy(){
  unset http_proxy
  unset https_proxy
  unset ALL_PROXY
}
function proxy(){
  setproxy
  $@;
  unsetproxy
}
setproxy # 默认开启


# =================== ssh/frp =====================
# frp
function frp(){
    if [ $# -ne 4 ]; then
        plog ERROR red "Usage: frp SERVER_IP CLIENT_IP PORT USR"
        return 1
    fi
    server_ip=$1
    client_ip=$2
    port=$3
    usr=$4
    gtimeout 1 nc -z -n ${client_ip} 22 &>/dev/null
    if [ $? -ne 0 ]; then
        plog INFO green "SSH by FRP"
        ssh -p ${port} ${usr}@${server_ip}
    else
        ssh ${usr}@${client_ip}
    fi
}


# ================== c/c++ env =====================
alias g++='echo "\033[32musing Homebrew GCC 9.1.0 \033[0m"; /usr/local/Cellar/gcc/9.2.0_3/bin/g++-9'
# alias gcc='echo "\033[32musing Homebrew GCC 9.1.0 \033[0m";/usr/local/Cellar/gcc/9.2.0_3/bin/gcc-9'

# boost
export BOOST_ROOT=/Users/barriery/Helper/third_party/boost/
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/Users/barriery/Helper/third_party/boost/lib"


# ================== python env ====================
# pyenv
alias brew='env PATH=${PATH//$(pyenv root)\/shims:/} brew'
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
eval "$(pipenv --completion)"


# =================== ruby env =====================
export PATH="/usr/local/opt/ruby/bin:$PATH"
# for compile
# export LDFLAGS="-L/usr/local/opt/ruby/lib"
# export CPPFLAGS="-I/usr/local/opt/ruby/include"


# ================== other env =====================
# autojump
[ -f /usr/local/etc/profile.d/autojump.sh ] && . /usr/local/etc/profile.d/autojump.sh

# brew mirror
export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles
export PATH="/usr/local/opt/gnu-getopt/bin:$PATH"

Vim

let mapleader=";" " 定义快捷键的前缀,即<Leader>

" 用~/clipsongzboard作为剪切板实现复制粘贴到系统剪切板
map <C-c> y:e ~/clipsongzboard<CR>P:w<cr>:w !pbcopy<CR><cr>:1,$d<cr>:w<cr><C-o><C-o>

" 让光标停留在上一次打开的行
if has("autocmd")
  au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif

" 移除 Windows 文件结尾的 `^M`
noremap <leader>m :%s/<C-V><C-M>//ge<CR>

" 在断行、合并(join)行时,针对多字节字符(比如中文)的优化处理
set formatoptions+=mM

" 高亮不想要的空格(行尾)
" See [http://vim.wikia.com/wiki/Highlight_unwanted_spaces]
" - highlight trailing whitespace in red
" - have this highlighting not appear whilst you are typing in insert mode
" - have the highlighting of whitespace apply when you open new buffers
highlight ExtraWhitespace ctermbg=red guibg=red
match ExtraWhitespace /\s\+$/
autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
autocmd InsertLeave * match ExtraWhitespace /\s\+$/
autocmd BufWinLeave * call clearmatches() " for performance

colorscheme default " 设置颜色主题
filetype on " 检测文件类型
filetype plugin on " 根据侦测到的不同类型加载对应的插件
filetype indent on " 自适应不同语言的智能缩进
set backspace=2
set tabstop=4 " TAB宽4个空格
set expandtab " 将TAB转化成space
set number
set encoding=utf-8 " 文件默认编码
set softtabstop=4 " 让 vim 把连续数量的空格视为一个制表符
syntax on " 语法高亮
set hlsearch " 高亮显示搜索结果

" 设置vim-plug管理的插件安装位置
call plug#begin('~/.vim/bundle')
" 下面就是一些插件的例.
" 插件必须装在  plug#begin/end这两行命令之间.
" 对于在github上面的插件, 我们可以用以下方法添加, 只需要添加`用户名/插件名称`就行
"Plug 'tpope/vim-fugitive'
Plug 'octol/vim-cpp-enhanced-highlight'
Plug 'scrooloose/nerdtree' " 文件树
Plug 'godlygeek/tabular' " before vim-markdown
Plug 'plasticboy/vim-markdown'
Plug 'suan/vim-instant-markdown'
Plug 'scrooloose/nerdcommenter' " 批量注释
Plug 'zxqfl/tabnine-vim' " AI自动补全
Plug 'luochen1990/rainbow' " 嵌套括号不同染色
Plug 'autozimu/LanguageClient-neovim', {'branch': 'next', 'do': 'bash install.sh'} " LSP
Plug 'dense-analysis/ale' " 语法检查
" 对于在http://vim-scripts.org/vim/scripts.html下的插件, 我们直接添加插件名称就行
" Plug 'L9'
" 对于不是github也不是vim-scripts的插件, 则需要用完整路径
"Plug 'git://git.wincent.com/command-t.git'
" 本地或者你自己的插件
"Plug 'file:///home/gmarik/path/to/plugin'


" 所有的插件都需要安装在这条命令之前
call plug#end()

"ale
"始终开启标志列
let g:ale_sign_column_always = 1
let g:ale_set_highlights = 0
"自定义error和warning图标
let g:ale_sign_error = ''
let g:ale_sign_warning = ''
"在vim自带的状态栏中整合ale
let g:ale_statusline_format = ['✗ %d', '⚡ %d', '✔ OK']
"显示Linter名称,出错或警告等相关信息
let g:ale_echo_msg_error_str = 'E'
let g:ale_echo_msg_warning_str = 'W'
let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
"普通模式下,sp前往上一个错误或警告,sn前往下一个错误或警告
nmap sp <Plug>(ale_previous_wrap)
nmap sn <Plug>(ale_next_wrap)
"<Leader>s触发/关闭语法检查
nmap <Leader>s :ALEToggle<CR>
"<Leader>d查看错误或警告的详细信息
nmap <Leader>d :ALEDetail<CR>

" LSP
let g:LanguageClient_loadSettings = 1
let g:LanguageClient_diagnosticsEnable = 0
let g:LanguageClient_settingsPath = expand('/Users/barriery/.vim/languageclient.json')
let g:LanguageClient_selectionUI = 'quickfix'
let g:LanguageClient_diagnosticsList = v:null
let g:LanguageClient_hoverPreview = 'Never'
let g:LanguageClient_serverCommands = {}
let g:LanguageClient_serverCommands.c = ['cquery']
let g:LanguageClient_serverCommands.cpp = ['cquery']
noremap <leader>rd :call LanguageClient#textDocument_definition()<cr>
noremap <leader>rr :call LanguageClient#textDocument_references()<cr>
noremap <leader>rv :call LanguageClient#textDocument_hover()<cr>

" rainbow
let g:rainbow_active = 1

" NERD commenter
let g:NERDSpaceDelims=1 " 注释的时候自动加个空格,

" vim
autocmd BufNewFile,BufRead *.md set nofoldenable " 取消自动折叠

" NERD tree
let NERDChristmasTree=0
let NERDTreeWinSize=35
let NERDTreeChDirMode=2
let NERDTreeIgnore=['\~$', '\.pyc$', '\.swp$']
let NERDTreeShowBookmarks=1
let NERDTreeWinPos="left"
let NERDTreeShowHidden=1
" Automatically open a NERDTree if no files where specified
autocmd vimenter * if !argc() | NERDTree | endif
" Close vim if the only window left open is a NERDTree
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif
" Open a NERDTree
nmap <F5> :NERDTreeToggle<cr>

function HeaderPython()
        call setline(1, "#-*- coding:utf8 -*-")
        call append(1, "# Powered by barriery")
        call append(2, "# at ".strftime('%Y-%m-%d %T', localtime()))
        call append(3, "# ----------------------")
endf
function HeaderCPP()
        call setline(1, "// Powered by barriery")
        call append(1, "// at ".strftime('%Y-%m-%d %T', localtime()))
        call append(2, "// ----------------------")
endf
autocmd bufnewfile *.py call HeaderPython()
autocmd bufnewfile *.c call HeaderCPP()
autocmd bufnewfile *.cc call HeaderCPP()
autocmd bufnewfile *.cpp call HeaderCPP()

autocmd BufWritePost $MYVIMRC source $MYVIMR " 让配置变更立即生效

About

上述仅个人使用Mac时所用软件。

mac各类开发的安装向导:https://github.com/sb2nov/mac-setup

参考电脑配置环境记录