Ubuntu 18.04 LTS 配置

2018/04/27 Linux

安装完 Ubuntu 18.04 LTS 后进行一些必要的配置,方便使用。

将你的硬件时钟设置为本地时区

sudo timedatectl set-local-rtc 1

更改源为阿里云

在 应用程序 > 软件和更新 中更改源为阿里云 mirrors.aliyun.com

安装aptitude

sudo apt-get install aptitude

安装vim

sudo apt-get install vim-gnome

vim配置

vim ~/.vimrc

添加

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Maintainer:
"       Amir Salihefendic — @amix3k
"
" Awesome_version:
"       Get this config, nice color schemes and lots of plugins!
"
"       Install the awesome version from:
"
"           https://github.com/amix/vimrc
"
" Sections:
"    -> General
"    -> VIM user interface
"    -> Colors and Fonts
"    -> Files and backups
"    -> Text, tab and indent related
"    -> Visual mode related
"    -> Moving around, tabs and buffers
"    -> Status line
"    -> Editing mappings
"    -> vimgrep searching and cope displaying
"    -> Spell checking
"    -> Misc
"    -> Helper functions
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Plugins
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"call plug#begin('~/.config/nvim/plugged')
call plug#begin('~/AppData/Local/nvim/plugged')
Plug 'nlknguyen/papercolor-theme'
Plug 'tpope/vim-unimpaired'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-fugitive'
Plug 'rickhowe/diffchar.vim'
Plug 'preservim/nerdtree'
Plug 'preservim/nerdcommenter'
Plug 'vim-scripts/matchit.zip'
Plug 'mbbill/undotree'
Plug 'townk/vim-autoclose'
Plug 'terryma/vim-expand-region'
Plug 'kana/vim-textobj-user'
"Plug 'vim-scripts/YankRing.vim'
Plug 'maxbrunsfeld/vim-yankstack'
Plug 'easymotion/vim-easymotion'
Plug 'yggdroot/leaderf', { 'do': ':leaderfinstallcextension' }
Plug 'neoclide/coc.nvim', {'branch': 'release'}
call plug#end()


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => general
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 关闭兼容模式。开启兼容模式会影响大部分vim功能,所以需要首先关掉兼容模式
" not compatible with the old-fashion vi mode
set nocompatible

" 命令行历史条目数。详细见:help 'history',其中描述片段:a history of ':' commands, and a history of previous search patterns is remembered.
" sets how many lines of history vim has to remember
set history=500

" 开启文件类型检测
" enable filetype detection
filetype on
" 开启基于文件类型的缩进
" enable filetype-specific indenting
filetype plugin on
" 开启基于文件类型的插件
" enable filetype-specific plugins
filetype indent on

" 当文件被修改时重新加载文件,终端没效果待确认???
" set to auto read when a file is changed from the outside
set autoread
au focusgained,bufenter * checktime

" 设置leader键
" with a map leader it's possible to do extra key combinations
" like <leader>w saves the current file
let mapleader = ","

" fast saving
nmap <leader>w :w!<cr>

" :W sudo saves the file
" (useful for handling the permission-denied error)
command! W execute 'w !sudo tee % > /dev/null' <bar> edit!

" 显示行号
" show line numbers
set number

" 显示相对行号
" set relativenumber

" vim和系统共用剪切板
set clipboard=unnamed


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => VIM user interface
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 光标距离屏幕顶部和底部7行时就开始滚动屏幕
" Set 7 lines to the cursor - when moving vertically using j/k
set so=7

" Avoid garbled characters in Chinese language windows OS
let $LANG='en'
set langmenu=en
source $VIMRUNTIME/delmenu.vim
source $VIMRUNTIME/menu.vim

" 启用增强模式的命令行补全
" Turn on the Wild menu
set wildmenu
" 在命令行中输入命令时,按下wildchar键(默认为Tab)将自动补全命令和参数:此时将在命令行的上方显示可能的匹配项;继续按下wildchar键,可以遍历所有的匹配项;也可以使用方向键或者CTRL-P/CTRL-N键,在匹配列表中进行移动;最后点击回车键,选择需要的匹配项。
" start wild expansion in the command line using <TAB>
set wildchar=<TAB>

" <Tab>自动补全,文件名或目录补全的时候,忽略以下编译产生的文件中存在的字符串选项
" Ignore compiled files
"set wildignore=*.o,*~,*.pyc
set wildignore=*.o,*~,*.class,*.pyc,*.elc,*.a,*.lib
if has("win16") || has("win32")
    set wildignore+=.git\*,.hg\*,.svn\*
else
    set wildignore+=*/.git/*,*/.hg/*,*/.svn/*,*/.DS_Store
endif

" 设置标尺,总是在右下角显示当前光标所在位置的信息
"Always show current position
set ruler

" Height of the command bar
set cmdheight=1

" A buffer becomes hidden when it is abandoned
set hid

" 允许退格键在插入模式中删除任意字符。:set backspace=2 相当于 :set backspace=indent,eol,start
" Configure backspace so it acts as it should act
set backspace=eol,start,indent
set whichwrap+=<,>,h,l

" 搜索忽略大小写
" Ignore case when searching
set ignorecase

" 智能开启大小写敏感搜索,想要大小写不敏感,搜索模式要全部小写,反之,搜索模式有一个大写字母,自动开启大小写敏感
" When searching try to be smart about cases
set smartcase

" 高亮显示搜索结果
" Highlight search results
set hlsearch

" 递增的搜索,/或?搜索时,输入字符的时候就立刻高亮显示当前所有匹配结果
" Makes search act like search in modern browsers
set incsearch

" Don't redraw while executing macros (good performance config)
set lazyredraw

" For regular expressions turn magic on
set magic

" 光标遇到圆括号、方括号、大括号时,自动高亮对应的另一个圆括号、方括号和大括号。
" Show matching brackets when text indicator is over them
set showmatch
" How many tenths of a second to blink when matching brackets
set mat=2

" 关闭发生错误时的哔声
" No annoying sound on errors
set noerrorbells
" 关闭使用刷新屏幕来代替哔声,当设置了visualbell,会刷新屏幕来代替哔声
set novisualbell
" 清空visualbell用来刷新屏幕的代码
set t_vb=
" 超时时间,默认1000,单位ms。mapping 或者 key sequence 等待下一个字符的超时时间
"set tm=500

" Properly disable sound on errors on MacVim
if has("gui_macvim")
    autocmd GUIEnter * set vb t_vb=
endif


" Add a bit extra margin to the left
set foldcolumn=1


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Colors and Fonts
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 打开语法高亮。自动识别代码,使用多种颜色显示。
" Enable syntax highlighting
syntax enable

"" Enable 256 colors palette in Gnome Terminal
"if $COLORTERM == 'gnome-terminal'
"    set t_Co=256
"endif
"
"try
""    colorscheme desert
"    colorscheme molokai
"catch
"endtry
"
"set background=dark
"
"" Set extra options when running in GUI mode
"if has("gui_running")
"    set guioptions-=T
"    set guioptions-=e
"    set t_Co=256
"    set guitablabel=%M\ %t
"endif

" Set utf8 as standard encoding and en_US as the standard language
"set encoding=utf8
set encoding=utf-8
set termencoding=utf-8
set fileencoding=utf-8
set fileencodings=ucs-bom,utf-8,big5,gb2312,latin1

" Use Unix as the standard file type
set ffs=unix,dos,mac

" 主题和字体
if has("gui_running") " GUI color and font settings
  set background=dark
  set t_Co=256          " 256 color mode
  " NO menu,toolbar ...
  set guioptions-=m
  set guioptions-=T
  set guioptions-=l
  set guioptions-=L
  set guioptions-=r
  set guioptions-=R

  if has("win32")
    "start gvim maximized
    if has("autocmd")
      au GUIEnter * simalt ~x
    endif
  endif
  colorscheme molokai
else
  " terminal color settings
  "colorscheme evening
  "colorscheme monokai

  set background=light
  colorscheme PaperColor
  "colorscheme gruvbox
endif

" 81个字符高亮显示
" 


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Files, backups and undo
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 关闭自动备份,备份的文件名通常是原文件名后面加一个~
" Turn backup off, since most stuff is in SVN, git etc. anyway...
set nobackup
set nowb
set noswapfile

" semicolon 分号,读音为 send 米 call 冷(len三声)
" https://vim.fandom.com/wiki/Single_tags_file_for_a_source_tree
" set autochdir 自动切换工作目录。这主要用在一个 Vim 会话之中打开多个文件的情况,默认的工作目录是打开的第一个文件的目录。该配置可以将工作目录自动切换到,正在编辑的文件的目录。
" vim当前工作目录和文件所在目录是有区别的,可以通过设置set autochdir来自动切换vim当前工作目录
" 设置vim搜索ctags生成的tag文件时的行为,./ 告诉vim从当前文件所在目录开始寻找,而不是vim的工作目录
set tags=./tags;


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Text, tab and indent related
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 使用空格代替 Tab
" Use spaces instead of tabs
set expandtab

" Tab 转为多少个空格。
set softtabstop=4

" 智能的tab,具体功能待确认???
" Be smart when using tabs ;)
set smarttab

" 在文本上按下>>(增加一级缩进)、<<(取消一级缩进)或者==(自动缩进)时,每一级的字符数。
" 1 tab == 4 spaces
set shiftwidth=4
set tabstop=4

" Linebreak on 500 characters
set lbr
set tw=500

" 自动缩进,按下回车键后,下一行的缩进会自动跟上一行的缩进保持一致。
" autoindent
set ai
" smartindent
set si
" wrap lines
set wrap


""""""""""""""""""""""""""""""
" => Visual mode related
""""""""""""""""""""""""""""""
" Visual mode pressing * or # searches for the current selection
" Super useful! From an idea by Michael Naumann
vnoremap <silent> * :<C-u>call VisualSelection('', '')<CR>/<C-R>=@/<CR><CR>
vnoremap <silent> # :<C-u>call VisualSelection('', '')<CR>?<C-R>=@/<CR><CR>

" 在visual mode下让 *(#) 也能正常搜索
" vnoremap * y/<C-r>0<CR>
" vnoremap # y?<C-r>0<CR>

" 支持使用鼠标
set mouse=a


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Moving around, tabs, windows and buffers
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Map <Space> to / (search) and Ctrl-<Space> to ? (backwards search)
"map <space> /
"map <C-space> ?

" Disable highlight when <leader><cr> is pressed
map <silent> <leader><cr> :noh<cr>

" Smart way to move between windows
map <C-j> <C-W>j
map <C-k> <C-W>k
map <C-h> <C-W>h
map <C-l> <C-W>l

" 切换到当前文件所在目录
nmap <leader>cd :cd %:p:h<cr>

" 窗口打开关
nmap <leader>xs :write<CR>
nmap <leader>sd :vs<CR>
nmap <leader>s3 :vs<CR>
nmap <leader>sa :sp<CR>
nmap <leader>s2 :sp<CR>
nmap <leader>s1 <C-W>o
nmap <leader>sq :close<CR>
nmap <leader>s0 :close<CR>
nmap <leader>x3 :vs<CR>
nmap <leader>x2 :sp<CR>
nmap <leader>x1 <C-W>o
nmap <leader>x0 :close<CR>

" 窗口移动
noremap <leader>wh <C-W>h
noremap <leader>wj <C-W>j
noremap <leader>wk <C-W>k
noremap <leader>wl <C-W>l
noremap <leader>ww <C-W>w
noremap <leader>wc <C-W>c
noremap <leader>wo <C-W>o

" Do :help cope if you are unsure what cope is. It's super useful!
" 打开Quickfix List,通常是make之后,显示所有编译的错误,方便进入修改???
nmap <leader>co :botright copen<cr>

" Bash like keys for the command line
cnoremap <C-A>      <Home>
cnoremap <C-E>      <End>
cnoremap <C-K>      <C-U>
" cnoremap <C-F>      <Right>
" cnoremap <C-B>      <Left>
" <C-F> 原有功能,列出之前输入过的命令,可以移动选择回车执行,比较有用,左右移动用的比较少,暂时不做映射
" <C-A> 原来似乎没有作用
" <C-E> 和<End>的功能一样,也是跳到行尾
" <C-K> 是将按键的 字符表示 打印出来,Linux的<C-K>是删除光标之后的所有字符,但是vim命令行好像没有对应的功能,所以替换成<C-U>
" <C-U> 是删除光标前的所有字符,和Linux命令一样

" Close the current buffer
map <leader>bd :Bclose<cr>:tabclose<cr>gT

" Close all the buffers
map <leader>ba :bufdo bd<cr>

map <leader>l :bnext<cr>
map <leader>h :bprevious<cr>

" Useful mappings for managing tabs
" 打开一个新的标签页
map <leader>tn :tabnew<cr>
" 关闭所有其他标签页,只保留当前标签页
map <leader>to :tabonly<cr>
" 关闭当前标签页
map <leader>tc :tabclose<cr>
" 把标签页向右移动
map <leader>tm :tabmove<cr>
" 移动到下一个标签页
map <leader>t<leader> :tabnext<cr>

" Let 'tl' toggle between this and the last accessed tab
let g:lasttab = 1
nmap <Leader>tl :exe "tabn ".g:lasttab<CR>
au TabLeave * let g:lasttab = tabpagenr()


" Opens a new tab with the current buffer's path
" Super useful when editing files in the same directory
map <leader>te :tabedit <C-r>=expand("%:p:h")<cr>/

" Switch CWD to the directory of the open buffer
map <leader>cd :cd %:p:h<cr>:pwd<cr>

" Specify the behavior when switching between buffers
try
  set switchbuf=useopen,usetab,newtab
  set stal=2
catch
endtry

" Return to last edit position when opening files (You want this!)
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif


""""""""""""""""""""""""""""""
" => Status line
""""""""""""""""""""""""""""""
" Always show the status line
"set laststatus=2

" Format the status line
"set statusline=\ %{HasPaste()}%F%m%r%h\ %w\ \ CWD:\ %r%{getcwd()}%h\ \ \ Line:\ %l\ \ Column:\ %c

" 状态栏设置
" status line {
" 是否显示状态栏。0 表示不显示,1 表示只在多窗口时显示,2 表示显示。
set laststatus=2
"set statusline=%-10.3n  "buffer number
set statusline=\ [%n]\   "buffer number
" 仅显示文件名,想要显示完整路径,可改为%F
set statusline+=%t       "tail of the filename
" 文件编码
set statusline+=[%{strlen(&fenc)?&fenc:'none'}, "file encoding
" 文件格式 unix dos
set statusline+=%{&ff}] "file format
" 帮助缓冲标记
set statusline+=%h      "help file flag
" 当前缓冲被修改标记
set statusline+=%m      "modified flag
" 当前缓冲只读标记
set statusline+=%r      "read only flag
" 文件类型
set statusline+=%y      "filetype
" ,左右分隔符,将剩下的显示项分割到右边
set statusline+=%=      "left/right separator
" 光标所在的列数
set statusline+=%c      "cursor column
" 空格分隔符
set statusline+=\       "space separator
" 当前光标所在行号/总行数
set statusline+=[%l/%L]
" 当前光标所在文件位置的百分比
set statusline+=\ %P    "percent through file


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Editing mappings
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Remap VIM 0 to first non-blank character
map 0 ^

" Move a line of text using ALT+[jk] or Command+[jk] on mac
nmap <M-j> mz:m+<cr>`z
nmap <M-k> mz:m-2<cr>`z
vmap <M-j> :m'>+<cr>`<my`>mzgv`yo`z
vmap <M-k> :m'<-2<cr>`>my`<mzgv`yo`z

if has("mac") || has("macunix")
  nmap <D-j> <M-j>
  nmap <D-k> <M-k>
  vmap <D-j> <M-j>
  vmap <D-k> <M-k>
endif

" Delete trailing white space on save, useful for some filetypes ;)
fun! CleanExtraSpaces()
    let save_cursor = getpos(".")
    let old_query = getreg('/')
    silent! %s/\s\+$//e
    call setpos('.', save_cursor)
    call setreg('/', old_query)
endfun

if has("autocmd")
    autocmd BufWritePre *.txt,*.js,*.py,*.wiki,*.sh,*.coffee :call CleanExtraSpaces()
endif

inoremap kj <ESC>

" 把行尾多余的空格删除
nmap <leader>tr :%s/ \+$//g<CR>

" 挂起vim进程,同ctrl+z,fg还原
nmap <leader>xc :suspend<CR>


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Spell checking
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Pressing ,ss will toggle and untoggle spell checking
"map <leader>ss :setlocal spell!<cr>

" Shortcuts using <leader>
"map <leader>sn ]s
"map <leader>sp [s
"map <leader>sa zg
"map <leader>s? z=


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Misc
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Remove the Windows ^M - when the encodings gets messed up
noremap <Leader>m mmHmt:%s/<C-V><cr>//ge<cr>'tzt'm

" Quickly open a buffer for scribble
"map <leader>q :e ~/buffer<cr>

" Quickly open a markdown buffer for scribble
"map <leader>x :e ~/buffer.md<cr>

" 粘贴模式开关,解决粘贴乱码问题???
" Toggle paste mode on and off
map <leader>pp :setlocal paste!<cr>


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Helper functions
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Returns true if paste mode is enabled
function! HasPaste()
    if &paste
        return 'PASTE MODE  '
    endif
    return ''
endfunction

" Don't close window, when deleting a buffer
command! Bclose call <SID>BufcloseCloseIt()
function! <SID>BufcloseCloseIt()
    let l:currentBufNum = bufnr("%")
    let l:alternateBufNum = bufnr("#")

    if buflisted(l:alternateBufNum)
        buffer #
    else
        bnext
    endif

    if bufnr("%") == l:currentBufNum
        new
    endif

    if buflisted(l:currentBufNum)
        execute("bdelete! ".l:currentBufNum)
    endif
endfunction

function! CmdLine(str)
    call feedkeys(":" . a:str)
endfunction

function! VisualSelection(direction, extra_filter) range
    let l:saved_reg = @"
    execute "normal! vgvy"

    let l:pattern = escape(@", "\\/.*'$^~[]")
    let l:pattern = substitute(l:pattern, "\n$", "", "")

    if a:direction == 'gv'
        call CmdLine("Ack '" . l:pattern . "' " )
    elseif a:direction == 'replace'
        call CmdLine("%s" . '/'. l:pattern . '/')
    endif

    let @/ = l:pattern
    let @" = l:saved_reg
endfunction


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => coc.nvim
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Set internal encoding of vim, not needed on neovim, since coc.nvim using some
" unicode characters in the file autoload/float.vim
set encoding=utf-8

" TextEdit might fail if hidden is not set.
set hidden

" Some servers have issues with backup files, see #649.
set nobackup
set nowritebackup

" Give more space for displaying messages.
set cmdheight=2

" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable
" delays and poor user experience.
set updatetime=300

" Don't pass messages to |ins-completion-menu|.
set shortmess+=c

" Always show the signcolumn, otherwise it would shift the text each time
" diagnostics appear/become resolved.
if has("patch-8.1.1564")
  " Recently vim can merge signcolumn and number column into one
  set signcolumn=number
else
  set signcolumn=yes
endif

" Use tab for trigger completion with characters ahead and navigate.
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config.
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

" Use <c-space> to trigger completion.
if has('nvim')
  inoremap <silent><expr> <c-space> coc#refresh()
else
  inoremap <silent><expr> <c-@> coc#refresh()
endif

" Make <CR> auto-select the first completion item and notify coc.nvim to
" format on enter, <cr> could be remapped by other vim plugin
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
                              \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"

" Use `[g` and `]g` to navigate diagnostics
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)

" GoTo code navigation.
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

" Use K to show documentation in preview window.
nnoremap <silent> K :call <SID>show_documentation()<CR>

function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  elseif (coc#rpc#ready())
    call CocActionAsync('doHover')
  else
    execute '!' . &keywordprg . " " . expand('<cword>')
  endif
endfunction

" Highlight the symbol and its references when holding the cursor.
autocmd CursorHold * silent call CocActionAsync('highlight')

" Symbol renaming.
nmap <leader>rn <Plug>(coc-rename)

" Formatting selected code.
xmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)

augroup mygroup
  autocmd!
  " Setup formatexpr specified filetype(s).
  autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
  " Update signature help on jump placeholder.
  autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end

" Applying codeAction to the selected region.
" Example: `<leader>aap` for current paragraph
xmap <leader>a  <Plug>(coc-codeaction-selected)
nmap <leader>a  <Plug>(coc-codeaction-selected)

" Remap keys for applying codeAction to the current buffer.
nmap <leader>ac  <Plug>(coc-codeaction)
" Apply AutoFix to problem on the current line.
nmap <leader>qf  <Plug>(coc-fix-current)

" Map function and class text objects
" NOTE: Requires 'textDocument.documentSymbol' support from the language server.
xmap if <Plug>(coc-funcobj-i)
omap if <Plug>(coc-funcobj-i)
xmap af <Plug>(coc-funcobj-a)
omap af <Plug>(coc-funcobj-a)
xmap ic <Plug>(coc-classobj-i)
omap ic <Plug>(coc-classobj-i)
xmap ac <Plug>(coc-classobj-a)
omap ac <Plug>(coc-classobj-a)

" Remap <C-f> and <C-b> for scroll float windows/popups.
if has('nvim-0.4.0') || has('patch-8.2.0750')
  nnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
  nnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
  inoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
  inoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
  vnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
  vnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
endif

" Use CTRL-S for selections ranges.
" Requires 'textDocument/selectionRange' support of language server.
nmap <silent> <C-s> <Plug>(coc-range-select)
xmap <silent> <C-s> <Plug>(coc-range-select)

" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocAction('format')

" Add `:Fold` command to fold current buffer.
command! -nargs=? Fold :call     CocAction('fold', <f-args>)

" Add `:OR` command for organize imports of the current buffer.
command! -nargs=0 OR   :call     CocAction('runCommand', 'editor.action.organizeImport')

" Add (Neo)Vim's native statusline support.
" NOTE: Please see `:h coc-status` for integrations with external plugins that
" provide custom statusline: lightline.vim, vim-airline.
set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}

" Mappings for CoCList
" Show all diagnostics.
nnoremap <silent><nowait> <space>a  :<C-u>CocList diagnostics<cr>
" Manage extensions.
nnoremap <silent><nowait> <space>e  :<C-u>CocList extensions<cr>
" Show commands.
nnoremap <silent><nowait> <space>c  :<C-u>CocList commands<cr>
" Find symbol of current document.
nnoremap <silent><nowait> <space>o  :<C-u>CocList outline<cr>
" Search workspace symbols.
nnoremap <silent><nowait> <space>s  :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent><nowait> <space>j  :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent><nowait> <space>k  :<C-u>CocPrev<CR>
" Resume latest coc list.
nnoremap <silent><nowait> <space>p  :<C-u>CocListResume<CR>


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Nerdtree
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 自动开启Nerdtree
"autocmd vimenter * NERDTree
" 设定 NERDTree 视窗大小
"let g:NERDTreeWinSize = 25
" 开启/关闭nerdtree快捷键
nnoremap <leader>nt :NERDTreeToggle<CR>
" 开启Nerdtree时自动显示Bookmarks
"let NERDTreeShowBookmarks=1
" 打开vim时如果没有文件自动打开NERDTree
autocmd vimenter * if !argc()|NERDTree|endif
" 当NERDTree为剩下的唯一窗口时自动关闭
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
" 设置树的显示图标
let g:NERDTreeDirArrowExpandable = '▸'
let g:NERDTreeDirArrowCollapsible = '▾'
" 不显示隐藏文件
let g:NERDTreeHidden=0
" 过滤: 所有指定文件和文件夹不显示
let NERDTreeIgnore = ['\.pyc$', '\.swp', '\.swo', '\.vscode', '__pycache__']
" 是否显示行号
"let g:NERDTreeShowLineNumbers=1
" Making it prettier
let NERDTreeMinimalUI = 1
let NERDTreeDirArrows = 1


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => LeaderF
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" let g:Lf_ShortcutF = '<c-p>'
nnoremap <leader>kk :LeaderfFile<CR>
nnoremap <leader>xf :LeaderfFile<CR>
" 包含以下目录的标记为根目录
let g:Lf_RootMarkers = ['.git', '.svn', '.hg', '.project', '.root']
" 先找当前文件的所有祖先目录里最近的根目录, 如果找到就使用这个根目录为查找起点(A的含义) 
" 如果没找到任何根目录, 看看当前打开的文件是否在VIM的工作目录(working directory)下, 或者任何其子目录下。如果是, 就是用工作目录作为查找起点(F的含义)
let g:Lf_WorkingDirectoryMode = 'AF'

" 索引文件工具
" 如果LeaderF发现根目录是一个git或者hg的仓库(repository), 使用git或者hg作为索引文件的工具。这个是默认选项, 可以不写
let g:Lf_UseVersionControlTool=1
" 如果Lf_UseVersionControlTool=0或者根目录不是仓库,会检查是否配置外部工具
"let g:Lf_DefaultExternalTool='rg'
" 如果以上都没有,则使用python脚本索引文件

if has('nvim')
    let s:cachedir = expand(stdpath('cache'))
    let s:configdir = expand(stdpath('config'))
else
    "vim will share same folder with nvim
    if has('win32')
        let s:cachedir = expand('~/AppData/Local/Temp/cache/nvim')
        let s:configdir = expand('~/AppData/Local/nvim')
    else
        let s:cachedir = expand('~/.cache/nvim')
        let s:configdir = expand('~/.config/nvim')
    endif
endif
" 设置1则显示隐藏文件,默认值0
"g:Lf_ShowHidden = 0
" 设置成1, 预览(preview)会在弹出(popup)窗口里显示, 而不会在原来的文件所在的窗口里显示. 默认值是0.
let g:Lf_PreviewInPopup = 1
" 设置窗口高度
let g:Lf_WindowHeight = 0.30
" 设置缓存路径
let g:Lf_CacheDirectory = s:cachedir
" 设置状态栏配色方案
let g:Lf_StlColorscheme = 'powerline'
" 设置哪几个功能自动显示preview
let g:Lf_PreviewResult = {
        \ 'File': 0,
        \ 'Buffer': 0,
        \ 'Mru': 0,
        \ 'Tag': 0,
        \ 'BufTag': 1,
        \ 'Function': 1,
        \ 'Line': 1,
        \ 'Colorscheme': 0,
        \ 'Rg': 0,
        \ 'Gtags': 0
        \}
" 设置为1, 结果从下到上显示, 跟fzf/CtrlP一致, 默认是0, 从上倒下显示
"let g:Lf_ReverseOrder = 0


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Undotree
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
nnoremap <leader>ut :UndotreeToggle<CR>


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => vim-expand-region
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
map <leader>xx <Plug>(expand_region_expand)
map <leader>zz <Plug>(expand_region_shrink)
vmap v <Plug>(expand_region_expand)
vmap z <Plug>(expand_region_shrink)


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => vertical diffsplit
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
set diffopt+=vertical
" better diff algorithm from xdiff
" code checked into vim repo in c93262b2e
" @see https://vimways.org/2018/the-power-of-diff/
" @see https://raw.githubusercontent.com/ashfinal/vimrc-config/master/.vimrc
if has("patch-8.1.360") || has("nvim-0.3.5")
  set diffopt+=algorithm:histogram
  set diffopt+=indent-heuristic
endif


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => diffchar
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" [b ]b [e ]e 和 vim-unimpaired 冲突,加载插件的顺序放到 vim-unimpaired 之后,防止[b ]b [e ]e被覆盖
nmap <silent> [w <Plug>JumpDiffCharPrevStart
nmap <silent> ]w <Plug>JumpDiffCharNextStart
"nmap <silent> [e <Plug>JumpDiffCharPrevEnd
"nmap <silent> ]e <Plug>JumpDiffCharNextEnd
nmap <silent> <Leader>do <Plug>GetDiffCharPair
nmap <silent> <Leader>dp <Plug>PutDiffCharPair


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => vim-unimpaired
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 补充官方丢失的[]相关命令,部分快捷键如下
" ]b 和[b 循环遍历缓冲区。
" ]e 和[e 交换上下两行。
" ]f 和[f 循环遍历同一目录中的文件,并打开为当前缓冲区。
" ]l 和[l 遍历位置列表。
" ]q 和[q 遍历快速修复列表。
" ]t 和[t 遍历标签列表。


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => vim-textobj-user
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 和 coc classobj funcobj 冲突,暂时先屏蔽
"call textobj#user#plugin('file', {
      "\ 'file': {
      "\ 'pattern': '\f\+', 'select': ['af', 'if']
      "\ }
      "\ })
" C:\Users\Administrator\AppData\Local\nvim\init.vim
" /root/init.vim /home/wh/demo.txt

安装git

sudo apt-get install git

设置name,email,push

git config --global user.name <name>
git config --global user.email <email>
git config --global push.default simple

使用ssh,生成公钥后在github上添加SSH keys

ssh-keygen -t rsa -C <email>

安装gnome-tweak-tool

Ubuntu 18.04 LTS 中 gnome 为默认桌面,安装优化工具可以进行高级设置

sudo apt-get install gnome-tweak-tool

安装zsh & oh-my-zsh

安装zsh

sudo apt-get install zsh

更改当前用户默认的shell为zsh

chsh -s $(which zsh)

安装oh-my-zsh

sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"

修改主题为agnoster

vim ~/.zshrc

# 主题改为如下
# ZSH_THEME="agnoster"

安装 agnoster 主题依赖的字体 powerline ,并设置等宽字体,否则会出现乱码

# clone
git clone https://github.com/powerline/fonts.git --depth=1

# install
cd fonts
./install.sh

# clean-up a bit
cd ..
rm -rf fonts

打开优化工具,等宽字体设置为 Ubuntu Mono derivative Powerline Regular

注销后生效

开启TCP BBR拥塞控制算法

Linux kernel 4.9+ 已经支持tcp_bbr,ubuntu 18.04 默认使用4.15内核,可以直接开启

写入配置文件

sudo bash -c 'cat >> /etc/sysctl.conf' << EOF

net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF

让内核配置生效

sudo sysctl -p

以下两条命令的结果中都有bbr,说明内核已经开启bbr

sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control

以下命令看到有 tcp_bbr,说明bbr已启动

lsmod | grep bbr

我这边网络环境比较恶劣,开启bbr后大幅改善响应速度

全局智能代理

流量分流方案: tun2socks + shadowsocks-libev

常见透明代理方案(tcp+udp)使用ss-redir(运行在网关上,在mangle表PREROUTING链中用TPROXY转发内网udp),但局限是无法转发网关自身的udp流量

tun2socks支持转发本地udp,适用于想要把代理部署在本地的用户

可选udp通路的丢包改善方案: UDPspeeder + udp2raw

UDPspeeder提供了FEC(前向纠错)和多倍发包方案,可以在牺牲一定带宽的前提下大大降低丢包率(准确的说是在原始丢包率的网络状况下通过发送额外的冗余包来实现恢复出原始udp包,从而避免丢包重传)

  • 优点: 降低丢包率,提高稳定性
  • 缺点: 浪费额外带宽(也就意味着有效带宽减少,体现为udp下载速度变慢),引入少量延迟

udp2raw可将udp包模拟成tcp,模拟三次握手,从而绕过ISP的qos限制,本质仍是udp

DNS分流方案: overture

overture是一个DNS分流净化软件,可配置多个上游DNS,自动选择最快应答,支持缓存,支持ECS,支持本地Host配置

处理逻辑: 配置主从DNS集合,主DNS集为国内常用DNS服务提供商,本地ISP、DNSPod、AliDNS之流,从DNS一般配置一个支持ECS的DNS,主要用于查询国外域名,默认使用OpenDNS的443端口进行tcp查询。用户请求的域名如果在DomainFile中匹配,则直接使用从DNS解析。若主DNS解析得出的IP不在IPNetworkFile中,则使用从DNS解析

ss-tun2socks

项目地址

https://github.com/zfl9/ss-tun2socks.git

由于dns我用的是overture,脚本中的chinadns和pdnsd部分可以删掉,然后再整合UDPspeeder和udp2raw进去

ss-tun2socks修改如下

#!/bin/bash

main_cfg='/etc/tun2socks/ss-tun2socks.conf'

if [ ! -e "${main_cfg}" ]; then
    echo -e "\e[37m${main_cfg}\e[0m  [\e[1;35mnot_exist\e[0m]" 1>&2
    exit 1
else
    source "${main_cfg}"
fi

function chnip_update() {
    #chnip_url="http://f.ip.cn/rt/chnroutes.txt"
    chnip_url="https://github.com/17mon/china_ip_list/raw/master/china_ip_list.txt"
    curl -4sSkL ${chnip_url} | egrep -v '^\s*$|^\s*#' > ${dns_chnroute}
    cat ${dns_chnroute} | xargs -n1 echo add chnroute > ${ipset_save_file}

    ipset -L chnroute &> /dev/null
    if [ $? -ne 0 ]; then
        ipset -N chnroute hash:net
    else
        ipset -F chnroute &> /dev/null
    fi

    ipset -R < ${ipset_save_file}
    ipset -S chnroute > ${ipset_save_file}
}

function ipts_update() {
    iptables -t mangle -F OUTPUT
    iptables -t mangle -F PREROUTING
    iptables -t mangle -F TUN2SOCKS &> /dev/null
    iptables -t mangle -X TUN2SOCKS &> /dev/null
    iptables -t nat -F PREROUTING
    iptables -t nat -F POSTROUTING

    iptables -t mangle -N TUN2SOCKS
    iptables -t mangle -A TUN2SOCKS -d 0/8 -j RETURN
    iptables -t mangle -A TUN2SOCKS -d 10/8 -j RETURN
    iptables -t mangle -A TUN2SOCKS -d 127/8 -j RETURN
    iptables -t mangle -A TUN2SOCKS -d 169.254/16 -j RETURN
    iptables -t mangle -A TUN2SOCKS -d 172.16/12 -j RETURN
    iptables -t mangle -A TUN2SOCKS -d 192.168/16 -j RETURN
    iptables -t mangle -A TUN2SOCKS -d 224/4 -j RETURN
    iptables -t mangle -A TUN2SOCKS -d 240/4 -j RETURN
    #iptables -t mangle -A TUN2SOCKS -d ${socks5_remote} -j RETURN
    # Reserved port 4000 for testing
    iptables -t mangle -A TUN2SOCKS -d ${socks5_remote} -p tcp ! --dport 4000 -j RETURN
    iptables -t mangle -A TUN2SOCKS -d ${socks5_remote} -p udp ! --dport 4000 -j RETURN
    iptables -t mangle -A TUN2SOCKS -m set --match-set chnroute dst -j RETURN
    iptables -t mangle -A TUN2SOCKS -j MARK --set-mark ${iptables_mark}

    iptables -t mangle -A OUTPUT -p tcp -j TUN2SOCKS
    iptables -t mangle -A OUTPUT -p udp -j TUN2SOCKS

    for intranet in "${iptables_intranet[@]}"; do
        iptables -t mangle -A PREROUTING -p udp -s $intranet ! -d $intranet --dport 53 -j ACCEPT
        iptables -t nat -A PREROUTING -p udp -s $intranet ! -d $intranet --dport 53 -j REDIRECT --to-ports 53

        iptables -t mangle -A PREROUTING -p tcp -s $intranet -j TUN2SOCKS
        iptables -t mangle -A PREROUTING -p udp -s $intranet -j TUN2SOCKS

        iptables -t nat -A POSTROUTING -s $intranet ! -d $intranet -j MASQUERADE
    done
}
function ipts_origin() {
    iptables -t mangle -F OUTPUT
    iptables -t mangle -F PREROUTING
    iptables -t mangle -F TUN2SOCKS &> /dev/null
    iptables -t mangle -X TUN2SOCKS &> /dev/null
    iptables -t nat -F PREROUTING
    iptables -t nat -F POSTROUTING

#    for intranet in "${iptables_intranet[@]}"; do
#        iptables -t nat -A PREROUTING -p udp -s $intranet -d $intranet --dport 53 -j DNAT --to-destination ${dns_original[0]}
#        iptables -t nat -A POSTROUTING -s $intranet ! -d $intranet -j MASQUERADE
#    done
}

function pbr_add() {
    ip route add 0/0 via ${tun2socks_gateway} dev ${tun2socks_tundev} table ${pbr_table}
    ip rule add fwmark ${iptables_mark} table ${pbr_table}
}
function pbr_del() {
    ip rule show | grep "fwmark ${iptables_mark}" | awk -F':' '{print $1}' | xargs -n1 ip rule del pref &> /dev/null
    ip route flush table ${pbr_table}
}

function kernel_opts() {
    if [ $(cat /proc/sys/net/ipv4/ip_forward) -ne 1 ]; then
        echo 1 > /proc/sys/net/ipv4/ip_forward
    fi
    if [ $(cat /proc/sys/net/ipv4/conf/$tun2socks_tundev/rp_filter) -ne 2 ]; then
        echo 2 > /proc/sys/net/ipv4/conf/$tun2socks_tundev/rp_filter
    fi
}

function dns_update() {
    echo "# Generated by ss-tun2socks at $(date '+%F %T')" > /etc/resolv.conf
    #echo "nameserver 127.0.0.1" >> /etc/resolv.conf
    # 127.0.0.53 for ubuntu 18.04 lts
    echo "nameserver 127.0.0.53" >> /etc/resolv.conf
}
function dns_origin() {
#    echo "# Generated by ss-tun2socks at $(date '+%F %T')" > /etc/resolv.conf
#    for dns in "${dns_original[@]}"; do
#        echo "nameserver $dns" >> /etc/resolv.conf
#    done
    systemctl restart NetworkManager
}

function current_ip() {
    ip_info=$(curl -4skL ip.chinaz.com/getip.aspx | sed -r "s/^\{ip:'(.*)',address:'(.*)'\}$/\1|\2/g")
    my_ip=$(echo ${ip_info} | awk -F'|' '{print $1}')
    my_loc=$(echo ${ip_info} | awk -F'|' '{print $2}')
    echo -e "\e[37mIP:\e[0m ${my_ip}\t\e[37mLocation:\e[0m ${my_loc}"
}

function start() {
    dns_origin

    if [ ! -e ${dns_chnroute} ]; then
        echo -e "\e[37m${dns_chnroute}\e[0m  [\e[1;35mnot_exist\e[0m]"
        exit 1
    fi

    eval "${tinymapper_runcmd}"
    eval "${udp2raw_runcmd}"
    eval "${speederv2_runcmd}"

    eval "${socks5_runcmd}"

    nohup tun2socks -tun-device $tun2socks_tundev -tun-address $tun2socks_address -tun-mask $tun2socks_netmask -tun-gw $tun2socks_gateway -local-socks-addr $socks5_listen -public-only < /dev/null &>> $tun2socks_log &

    ipset -X chnroute &> /dev/null
    ipset -R < ${ipset_save_file}

    ipts_update
    pbr_add
    kernel_opts

    dns_update
}

function stop() {
    port=$(echo $socks5_listen | awk -F: '{print $2}')
    ss -lnptu | grep :$port | grep -Eo 'pid=[0-9]+' | awk -F= '{print $2}' | sort -n | uniq | xargs kill &> /dev/null

    pkill '^tun2socks$'

    pkill '^tinymapper$'
    pkill '^speederv2$'
    pkill '^udp2raw$'

    ipts_origin
    ipset -X chnroute &> /dev/null
    pbr_del

    dns_origin
}

function status() {
    if [ $(pgrep -c '^tun2socks$') -ge 1 ]; then
        echo -e "\e[37mtun2socks\e[0m\t[\e[1;32mrunning\e[0m]"
    else
        echo -e "\e[37mtun2socks\e[0m\t[\e[1;35mstopped\e[0m]"
    fi

    port=$(echo $socks5_listen | awk -F: '{print $2}')

    if [ $(ss -lnpt | grep :$port | wc -l) -ne 0 ]; then
        echo -e "\e[37msocks5/tcp\e[0m\t[\e[1;32mrunning\e[0m]"
    else
        echo -e "\e[37msocks5/tcp\e[0m\t[\e[1;35mstopped\e[0m]"
    fi

    if [ $(ss -lnpu | grep :$port | wc -l) -ne 0 ]; then
        echo -e "\e[37msocks5/udp\e[0m\t[\e[1;32mrunning\e[0m]"
    else
        echo -e "\e[37msocks5/udp\e[0m\t[\e[1;35mstopped\e[0m]"
    fi

    if [ $(pgrep -c '^tinymapper$') -ge 1 ]; then
        echo -e "\e[37mtinymapper\e[0m\t[\e[1;32mrunning\e[0m]"
    else
        echo -e "\e[37mtinymapper\e[0m\t[\e[1;35mstopped\e[0m]"
    fi

    if [ $(pgrep -c '^speederv2$') -ge 1 ]; then
        echo -e "\e[37mspeederv2\e[0m\t[\e[1;32mrunning\e[0m]"
    else
        echo -e "\e[37mspeederv2\e[0m\t[\e[1;35mstopped\e[0m]"
    fi

    if [ $(pgrep -c '^udp2raw$') -ge 1 ]; then
        echo -e "\e[37mudp2raw \e[0m\t[\e[1;32mrunning\e[0m]"
    else
        echo -e "\e[37mudp2raw \e[0m\t[\e[1;35mstopped\e[0m]"
    fi
}

function usage() {
    echo -e "\e[37mUsage:\e[0m \e[36m${0}\e[0m \e[1;37mCOMMAND\e[0m"
    echo -e "\e[1;37mCOMMAND\e[0m := {"
    echo -e "\t\e[33mstart\e[0m\t\tstart ss-tun2socks"
    echo -e "\t\e[33mstop\e[0m\t\tstop ss-tun2socks"
    echo -e "\t\e[33mrestart\e[0m\t\trestart ss-tun2socks"
    echo -e "\t\e[33mstatus\e[0m\t\tstatus of ss-tun2socks"
    echo -e "\t\e[33mcurrent_ip\e[0m\tget current ipaddr info"
    echo -e "\t\e[33mupdate_chnip\e[0m\tupdate chnroute for ipset/chinadns"
    echo -e "}"
}

case $1 in
star*)  # start
    start
    status
    ;;
stat*)  # status
    status
    ;;
sto*)   # stop
    stop
    status
    ;;
r*)     # restart
    stop
    status
    echo
    start
    status
    ;;

c*)     # current_ip
    current_ip
    ;;
u*)     # update_chnip
    chnip_update
    ;;

h*)     # help
    usage
    ;;
*)
    usage 1>&2
    exit 1
    ;;
esac

ss-tun2socks.conf 配置文件如下

## socks5 配置
socks5_listen="127.0.0.1:1080"  # ss本地监听地址
socks5_remote="**.**.**.**"  # ss远程地址
socks5_remote_port="7788"  # ss远程端口
udp2raw_remote_port="4020"  # udp2raw远程端口
#socks5_runcmd="nohup ss-local -c /etc/ss-local.json < /dev/null &>> /var/log/ss-local.log &" # 启动命令

socks5_runcmd="nohup ss-local -s 127.0.0.1 -p 6010 -b 127.0.0.1 -l 1080 -k '******' -m aes-256-gcm -u --fast-open < /dev/null &>> /var/log/ss-local.log &" # 启动命令

tinymapper_runcmd="nohup tinymapper -l0.0.0.0:6010 -r$socks5_remote:$socks5_remote_port -t > /var/log/tinymapper.log 2>&1 &"

udp2raw_runcmd="nohup udp2raw -c -l0.0.0.0:4021 -r$socks5_remote:$udp2raw_remote_port -a -k "passwd" --raw-mode faketcp --cipher-mode xor > /var/log/udp2raw_udp.log 2>&1 &"

speederv2_runcmd="nohup speederv2 -c -l0.0.0.0:6010 -r127.0.0.1:4021 -k "passwd" -f20:10 --mode 0 -i 10 --timeout 8 --report 20 > /var/log/speederv2.log 2>&1 &"

## tun2socks 配置
tun2socks_tundev="tun0"                 # tun 网卡
tun2socks_address="10.0.0.1"            # 接口地址
tun2socks_gateway="10.0.0.254"          # 网关地址
tun2socks_netmask="255.255.255.0"       # 网络掩码
tun2socks_log='/var/log/tun2socks.log'  # 日志文件

## ipset 配置
ipset_save_file='/etc/tun2socks/chnroute.ipset' # chnip列表文件
dns_chnroute='/etc/tun2socks/chnroute.txt' # 大陆地址段列表

## iptables 配置
iptables_mark='0x2333/0x2333'       # mangle mark
iptables_intranet=(192.168.0.0/16)  # 内网网段,多个空格隔开

## pbr 配置
pbr_table=100   # 路由表-表号

## dns 配置
dns_original=(**.**.**.** 119.29.29.29 180.76.76.76) # 正常网络的 DNS,最多 3 个,**.**.**.**替换成本地ISP提供的DNS

install.sh

#!/bin/sh

sudo cp -af ss-tun2socks /usr/local/bin/
sudo cp -af tun2socks.bin/tun2socks.x86_64 /usr/local/bin/tun2socks
sudo chown root:root /usr/local/bin/tun2socks /usr/local/bin/ss-tun2socks
sudo chmod +x /usr/local/bin/tun2socks /usr/local/bin/ss-tun2socks
sudo mkdir -m 0755 -p /etc/tun2socks
sudo cp -af chnroute.txt /etc/tun2socks/
sudo cp -af chnroute.ipset /etc/tun2socks/
sudo cp -af ss-tun2socks.conf /etc/tun2socks/
sudo chown -R root:root /etc/tun2socks
sudo chmod 0644 /etc/tun2socks/*

# speederv2 udp2raw tinymapper

sudo cp -af speederv2_binaries/speederv2_amd64 /usr/local/bin/speederv2
sudo cp -af udp2raw_binaries/udp2raw_amd64 /usr/local/bin/udp2raw
sudo cp -af tinymapper_binaries/tinymapper_amd64 /usr/local/bin/tinymapper
sudo chown root:root /usr/local/bin/speederv2 /usr/local/bin/udp2raw /usr/local/bin/tinymapper
sudo chmod +x /usr/local/bin/speederv2 /usr/local/bin/udp2raw /usr/local/bin/tinymapper

# 自启

sudo cp -af ss-tun2socks.service /lib/systemd/system/ss-tun2socks.service
sudo chown root:root /lib/systemd/system/ss-tun2socks.service
sudo chmod +x /lib/systemd/system/ss-tun2socks.service
sudo systemctl daemon-reload

overture

下载overture,项目地址

https://github.com/shawn1m/overture

在Releases页面下载最新版本overture-linux-amd64.zip

解压到overture目录

unzip ./overture-linux-amd64.zip -d ./overture
cd overture

下载最新的china_ip_list.txtgfwlist.txt

wget -c -N https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
wget -c -N https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt

修改配置文件config.json

vim ./config.json

主DNS列表中添加以下两个DNS,并设置cache和ttl

  1. 本地运营商自动分配的DNS
  2. 阿里DNS
{
  "BindAddress": ":53",
  "PrimaryDNS": [
    {
      "Name": "Auto",
      "Address": "xx.xx.xx.xx:53",
      "Protocol": "udp",
      "SOCKS5Address": "",
      "Timeout": 6,
      "EDNSClientSubnet": {
        "Policy": "disable",
        "ExternalIP": ""
      }
    },
    {
      "Name": "DNSPod",
      "Address": "119.29.29.29:53",
      "Protocol": "udp",
      "SOCKS5Address": "",
      "Timeout": 6,
      "EDNSClientSubnet": {
        "Policy": "disable",
        "ExternalIP": ""
      }
    },
    {
      "Name": "AliDNS",
      "Address": "223.5.5.5:53",
      "Protocol": "udp",
      "SOCKS5Address": "",
      "Timeout": 6,
      "EDNSClientSubnet": {
        "Policy": "disable",
        "ExternalIP": ""
      }
    }
  ],
  "AlternativeDNS": [
    {
      "Name": "OpenDNS",
      "Address": "208.67.222.222:443",
      "Protocol": "tcp",
      "SOCKS5Address": "",
      "Timeout": 6,
      "EDNSClientSubnet": {
        "Policy": "disable",
        "ExternalIP": ""
      }
    }
  ],
  "OnlyPrimaryDNS": false,
  "RedirectIPv6Record": false,
  "IPNetworkFile": "/etc/overture/china_ip_list.txt",
  "DomainFile": "/etc/overture/gfwlist.txt",
  "DomainBase64Decode": true,
  "HostsFile": "/etc/overture/hosts_sample",
  "MinimumTTL": 86400,
  "CacheSize" : 604800,
  "RejectQtype": [255]
}

新建install.sh脚本,用于安装overture

#!/bin/sh

# 复制程序到/usr/bin下
sudo cp -af ./overture-linux-amd64 /usr/local/bin/overture
sudo chown root:root /usr/local/bin/overture
sudo chmod +x /usr/local/bin/overture

# 复制配置文件到/etc/overture下
sudo rsync -r --delete --exclude="overture-linux-amd64" --exclude="domain_sample" --exclude="ip_network_sample" --exclude="install.sh" ./ /etc/overture

# 配置overture服务
sudo bash -c 'cat > /lib/systemd/system/overture.service' << EOF
[Unit]
Description=overture service

[Service]
ExecStart=/usr/local/bin/overture -c /etc/overture/config.json -l /etc/overture/overture.log
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target
EOF

# 重载修改过的配置文件
sudo systemctl daemon-reload

安装

./install.sh

Ubuntu 18.04 LTS 默认使用systemd-resolved进行dns解析,停掉该服务,再启动overture

停止systemd-resolved

sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

更改resolv.conf符号连接

sudo mv /etc/resolv.conf /etc/resolv.conf.bak
sudo ln -s /var/run/NetworkManager/resolv.conf /etc/resolv.conf

修改网络连接中的DNS服务器为127.0.0.53

一些软件依赖于NetworkManage或/etc/resolv.conf中的域名服务器才能正常工作,所以我们要把所有DNS的请求接口修改为127.0.0.53:53

重启NetworkManager

sudo systemctl restart NetworkManager

启动overture前,检查53端口是否被占用

sudo lsof -i:53

如果被占用,就杀掉进程(一般被dnsmasq之类的DNS服务占用)

sudo kill -9 <PID>

激活开机启动

sudo systemctl enable overture

启动overture服务

sudo systemctl start overture

检查运行状态

sudo systemctl status overture

至此,默认DNS服务由overture提供

局部代理

有了全局智能代理,没必要使用局部代理,这里只是记录一下,需shadowsocks配合

apt-get使用代理

vim apt_proxy_conf

添加

Acquire::http::proxy "http://127.0.0.1:1080/";
Acquire::ftp::proxy "ftp://127.0.0.1:1080/";
Acquire::https::proxy "https://127.0.0.1:1080/";

更新时使用配置代理

sudo apt-get update -c apt_proxy_conf

proxychain5代理

sudo apt-get install proxychains

配置

sudo vim /etc/proxychains.conf

添加

socks5  127.0.0.1 1080

安装Chrome

sudo apt-get install gdebi
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo gdebi google-chrome-stable_current_amd64.deb

安装Redshift

Ubuntu 18.04 LTS 已经集成了夜灯模式,位于 设置-设备-显示-夜灯

Redshift作为备选,有特殊需求可以安装

sudo apt-get install redshift-gtk

Redshift项目地址

https://github.com/jonls/redshift

下载配置文件redshift.conf,放到如下目录

~/.config/redshift.conf

修改几个主要参数

; Set the day and night screen temperatures
temp-day=4300
temp-night=3300

; Disable the smooth fade between temperatures when Redshift starts and stops.
; 0 will cause an immediate change between screen temperatures.
; 1 will gradually apply the new screen temperature over a couple of seconds.
fade=0

[manual]
lat=22.5
lon=114.0

运行,在托盘图标勾选Autostart

安装Dropbox

下载最新的Stable版本包,解压到~/.dropbox-dist目录下

wget https://clientupdates.dropboxstatic.com/dbx-releng/client/dropbox-lnx.x86_64-48.4.58.tar.gz

tar -zxvf dropbox-lnx.x86_64-48.4.58.tar.gz

新建dropbox.servive

[Unit]
Description=Dropbox as a user service
After=local-fs.target network.target

[Service]
Type=simple
ExecStart=%h/.dropbox-dist/dropboxd
Restart=on-failure
RestartSec=1
# Note: don't set these in user mode- they're already set, and
# systemd won't have permission to set them- killing your service before
# it starts
# User=%U
# Group=%U

[Install]
WantedBy=default.target

把dropbox.service移动到用户服务目录下

mkdir -p ~/.config/systemd/user
mv ~/dropbox.service ~/.config/systemd/user/

重载服务

systemctl --user daemon-reload

开机自动启动服务

systemctl --user enable dropbox

启动服务

systemctl --user start dropbox

安装Jekyll

安装ruby开发包

sudo apt-get install ruby ruby-dev

安装jekyll和bundler

sudo gem install jekyll bundler

进入Gemfile所在目录,更新依赖

bundle install

或者安装gem包到指定目录,以隔离对系统gem的影响

bundle install --path vendor/bundle

过程可能会报错,我的具体情况是 nokogiri 依赖 zlib

sudo apt-get install zlib1g-dev

启动本地服务

bundle exec jekyll serve --baseurl=""

安装Virtualbox

sudo apt install virtualbox

安装扩展,可选

sudo apt install virtualbox-ext-pack

安装Docker

确保APT能使用https方式工作,并且CA证书已安装

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

添加官方GPG密钥

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

添加REPO并更新

echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

或者直接追加进sources.list中

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

更新

sudo apt-get update

安装docker-ce

sudo apt-get install docker-ce

Docker Hub加速

sudo vim /etc/docker/daemon.json

添加镜像加速地址

{
    "registry-mirrors": ["https://40fcvoar.mirror.aliyuncs.com"]
}

重启docker服务

sudo service docker restart

安装docker-machine

curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine && chmod +x /tmp/docker-machine && sudo cp /tmp/docker-machine /usr/local/bin/docker-machine

系统备份 & 还原

安装pigz多线程压缩

sudo apt-get install pigz

备份

备份文件所存放的位置,根据实际情况更改

BACKUP_FILE_PATH=/media/howie/F63E9E535BFBE2AE/Ubuntu

备份软件包

sudo cp -r /var/cache/apt/archives/* $BACKUP_FILE_PATH/archives/

执行备份

sudo tar --use-compress-program=pigz -cvpf $BACKUP_FILE_PATH/ubuntu.tar.gz \
--exclude=/proc \
--exclude=/tmp \
--exclude=/mnt \
--exclude=/dev \
--exclude=/sys \
--exclude=/run \
--exclude=/media \
--exclude=/var/log \
--exclude=/var/cache/apt/archives \
--exclude=/usr/src/linux-headers* \
--exclude=/home/*/.gvfs \
--exclude=/home/*/.cache \
--exclude=/home/*/.local/share/Trash \
--exclude=/cdrom \
--exclude=/lost+found \
--exclude=/swapfile \
--exclude=/root/.cache \
--exclude=/var/tmp \
/ > $BACKUP_FILE_PATH/ubuntu.log 2>&1

还原

通过live cd进入试用ubuntu

备份文件所存放的位置,根据实际情况更改

BACKUP_FILE_PATH=/media/ubuntu/F63E9E535BFBE2AE/Ubuntu

查看分区情况

lsblk

挂载备份文件所在分区,一般会自动挂载在media下,自行查看

sudo mount /dev/nvme0n1p5 /mnt

删除旧系统所有数据

sudo rm -rf /mnt/*

挂载UEFI分区

sudo mkdir -p /mnt/boot/efi
sudo mount /dev/nvme0n1p1 /mnt/boot/efi

恢复

sudo tar -zxvpf $BACKUP_FILE_PATH/ubuntu.tar.gz -C /mnt --numeric-owner

新建目录

cd /mnt
sudo mkdir -p proc sys dev run mnt tmp var/log var/cache/apt/archives

复制软件包

sudo cp -r $BACKUP_FILE_PATH/archives/* /var/cache/apt/archives/

修复grub2引导

通过live cd进入试用ubuntu

挂载安装的Linux分区

sudo mount /dev/nvme0n1p5 /mnt

挂载EFI分区

sudo mount /dev/nvme0n1p1 /mnt/boot/efi
for i in /dev /dev/pts /proc /sys /run; do sudo mount -B $i /mnt$i; done

chroot到安装的Linux

sudo chroot /mnt

重装grub-efi

apt-get install --reinstall grub-efi

安装grub2到UEFI分区所在的硬盘上

grub-install /dev/nvme0n1

更新grub配置

update-grub
Show Disqus Comments

Search

    Table of Contents