四、nvim配置檔案

7hu95b發表於2024-06-10

這是一份沒有外掛的 neovim 配置。

init.vim

source $HOME/.config/nvim/general/settings.vim
source $HOME/.config/nvim/general/appearance.vim
source $HOME/.config/nvim/general/keyshortcuts.vim
source $HOME/.config/nvim/general/plugins.vim

下屬四個子配置檔案:

(一)settings.vim

set nocompatible  " 關閉 vi 相容模式
set modelines=0  " 禁用模式行(安全措施)
set nobackup  " 不進行備份設定
set nowritebackup
set noswapfile  " 禁止產生交換檔案
set autoread  " 自動檢測檔案外部更改

" === 中文顯示
set langmenu=zh_CN.UTF-8
set helplang=cn
set termencoding=utf-8
set encoding=utf8
set fileencodings=utf8,ucs-bom,gbk,cp936,gb2312,gb18030

" === 環境變數
let g:python3_host_prog = expand("/usr/bin/python3") 
let g:markdown_fenced_languages =['c', 'cpp', 'python', 'javascript']

" === 智慧提示相關
syntax enable " 語法高亮
filetype on  " 檔案型別檢測
filetype plugin indent on  " 根據檔案型別自動縮排


" === 顯示相關
set termguicolors
set background=dark
" colorscheme desert
set showtabline=2 " 始終顯示頂部tabline
set number  " 顯示絕對行號
" set relativenumber  " 顯示相對行號(和絕對行號的設定衝突)
set ruler  " 顯示標尺:右下角顯示游標位置
" set cursorline  " 高亮顯示當前行(256色是一條橫線,真彩顯示才是高亮)
" set nowrap  " 不自動折行顯示
set pumheight=10  " 彈出選單的高度
set splitbelow  " 左右分割視窗時,新視窗預設出現在右側
set splitright  " 水平分割視窗時,新視窗預設出現在底部
set ambiwidth=double  " 中文標點顯示一致
set sidescroll=10  " 移動到看不見的字元時,自動向右滾動10個字元
set sm!  " 高亮顯示匹配括號
set novisualbell  " 不要閃爍
set showcmd  " select 模式下顯示選中的行數
set vb t_vb=  " 不要響鈴

" === 游標樣式
let &t_SI = "\<Esc>]50;CursorShape=1\x7"
let &t_SR = "\<Esc>]50;CursorShape=2\x7"
let &t_EI = "\<Esc>]50;CursorShape=0\x7"
" set virtualedit=block,onemore   " 允許游標出現在最後一個字元的後面

" === 禁止顯示捲軸
set guioptions-=l
set guioptions-=L
set guioptions-=r
set guioptions-=R
" 禁止顯示選單和工具條
set guioptions-=m
set guioptions-=T

" === 操作相關
set mouse="" " 不使用滑鼠
" set mouse=a  " 使用滑鼠
" set mousehide  " 輸入時隱藏游標
set hidden  " 允許在有未儲存的修改時切換緩衝區,此時的修改由 vim 負責儲存
set iskeyword+=-  " 將 - 分隔的單詞作為一個單詞文字物件
set backspace=2  " 允許退格鍵Backspace刪除 indent,eol,start
set conceallevel=0  " 在 markdonw 檔案中可以看到 `` 符號
autocmd BufWritePost $MYVIMRC source $MYVIMRC  " 修改配置時,自動載入檔案
" =(start)= 跨會話撤銷,即新開啟的檔案依然能夠撤銷之前的 undo
set undofile
set undodir=~/.cache/nvim/undodir
if !isdirectory(&undodir)
   call mkdir(&undodir, "p", 0700)
endif
" =(end)=
" set autochdir  " 自動切換工作目錄

" == 搜尋查詢相關
set ignorecase  " 搜尋忽略大小寫
set smartcase  " 智慧匹配大小寫
set hlsearch  " 高亮查詢匹配
set incsearch  " 開始實時搜尋功能

" === 縮排相關
set autoindent  " 開始新行時處理縮排
set smartindent  " 智慧縮排
set smarttab  " 在行和段開始處使用製表符
set tabstop=4  " 編輯時製表符佔用空格數
set shiftwidth=4  " 格式化時,製表符佔用的空格數
set softtabstop=4  " 設定 4 個空格為製表符
set expandtab  " 將製表符Tab展開為空格, 這對於Python尤其有用

" === 程式碼補全
set completeopt=longest,menu  " 讓Vim補全選單行為跟IDE一致
set wildmenu                             " vim自身命名行模式智慧補全
set completeopt=menuone,preview,noselect " 補全時不顯示視窗,只顯示補全列表
set omnifunc=syntaxcomplete#Complete     " 設定全能補全
set shortmess+=c                         " 設定補全靜默
set cpt+=kspell                          " 設定補全單詞

(二)keyshortcuts.vim

let mapleader=' '
" 模式切換
inoremap jk <ESC>

" Window
noremap <Leader>wn <C-w>w
noremap <Leader>wh <C-w><left>
noremap <Leader>wl <C-w><right>
noremap <Leader>wk <C-w><up>
noremap <Leader>wj <C-w><down>
noremap <Leader>wv :vs<CR>
noremap <Leader>ws :sp<CR>
noremap <Leader>w= <C-w>=
noremap <Leader>w+ <C-w>5>
noremap <Leader>w- <C-w>5<

" Buffer
noremap <Leader>bp :bp<CR>
noremap <Leader>bn :bn<CR>

" Tab
noremap <Leader>tn :tabnew<CR>
noremap <Leader>tn :tabnext<CR>
noremap <Leader>tp :tabprevious<CR>
noremap <Leader>tc :tabc<CR>

" 使用 \ + s 儲存, \ + q 退出
noremap <Leader>fs :w<CR>
noremap <Leader>qq :q<CR>

" 開啟或關閉目錄樹
nnoremap <leader>fe :Lexplore<CR>

(三)appearance.vim

" ===== 狀態行 =====
set laststatus=2  " 始終顯示狀態列  
set cmdheight=2  " 命令列區的高度  

" %F 完整檔案路徑名;%m 當前緩衝被修改標記;%r 當前緩衝只讀標記  
" %h 幫助緩衝標記;%w 預覽緩衝標記
set statusline=%1*%F%m%r%h%w%=\ 
" %Y 檔案型別
set statusline+=%2*\ %Y\ \|\
" %{...} 評估表示式的值,並用值代替  
" %{"[fenc=".(&fenc==""?&enc:&fenc).((exists("+bomb") && &bomb)?"+":"")."]"} 顯示檔案編碼  
set statusline+=%3*%{\"\".(\"\"?&enc:&fenc).((exists(\"+bomb\")\ &&\ &bomb)?\"+\":\"\").\"\"}\
" %l 行數;%v 列數  
set statusline+=%4*[%l:%v]\ 
" %p 當前行數佔總行數的的百分比
set statusline+=%5*%p%%\ \|\
" %L 總行數
set statusline+=%6*%LL\
" 其他可用配置:%b ASCII值;%B 十六進位制值;%{&ff} 顯示檔案型別

" 顏色
hi User1 cterm=none ctermfg=gray ctermbg=darkgray
hi User2 cterm=none ctermfg=darkgrey ctermbg=darkgray
hi User3 cterm=bold ctermfg=darkgrey ctermbg=gray
hi User4 cterm=bold ctermfg=yellow ctermbg=gray
hi User5 cterm=none ctermfg=darkgrey ctermbg=gray
hi User6 cterm=none ctermfg=darkgrey ctermbg=gray

" ===== Tabline 檔案選項卡 =====
" Tabline 背景色
hi TabLineFill term=reverse ctermfg=5 ctermbg=7 guibg=#6c6c6c
" 設定 tab 選中狀態時的顏色
hi SelectTabLine term=Bold cterm=Bold ctermfg=DarkYellow ctermbg=LightGray
hi SelectPageNum cterm=None ctermfg=DarkRed ctermbg=LightGray
hi SelectWindowsNum cterm=None ctermfg=DarkCyan ctermbg=LightGray
" 設定 tab 未選中狀態時的顏色
hi NormalTabLine cterm=None ctermfg=Gray ctermbg=DarkGray
hi NormalPageNum cterm=None ctermfg=Gray ctermbg=DarkGray
hi NormalWindowsNum cterm=None ctermfg=Gray ctermbg=DarkGray

" 設定每個 tab 的顯示樣式,比如使用「」包裹
function MyTabLine()
    let s = ''
    for i in range(tabpagenr('$'))
        " select the highlighting
        let hlTab = ''
        let select = 0
        if i + 1 == tabpagenr()
            let hlTab = '%#SelectTabLine#'
            let s ..= hlTab . '⎡%#SelectPageNum#%T' . (i + 1) . hlTab
            let select = 1
        else
            let hlTab = '%#NormalTabLine#'
            let s ..= hlTab . "⎡%#NormalTabLine#%T" . (i + 1) . hlTab
        endif

        " the label is made by MyTabLabel()
        let s .= ' %<%{MyTabLabel(' . (i + 1) . ', ' . select . ')} '
        "追加視窗數量
        let wincount = tabpagewinnr(i + 1, '$')
        if wincount > 1
            if select == 1
                let s .= "%#SelectWindowsNum#" . wincount
            else
                let s .= "%#NormalWindowsNum#" . wincount
            endif
        endif
        let s .= hlTab . "⎦"
    endfor

    " after the last tab fill with TabLineFill and reset tab page nr
    let s ..= '%#TabLineFill#%T'

    " right-align the label to close the current tab page
    if tabpagenr('$') > 1
      let s ..= '%=%#TabLine#%999X░❨X❩'
    endif

    return s
endfunction

" Now the MyTabLabel() function is called for each tab page to get its label. >
function MyTabLabel(n, select)
    let label = ''
    let buflist = tabpagebuflist(a:n)

    for bufnr in buflist
        if getbufvar(bufnr, "&modified")
            let label = '+'
            break
        endif
    endfor

    let winnr = tabpagewinnr(a:n)
    let name = bufname(buflist[winnr - 1])

    if name == ''
        if &buftype == 'quickfix'
            let name = '[Quickfix List]'
        else
            let name = '[No Name]'
        endif
    else
        let name = fnamemodify(name, ':t')
    endif

    let label .= name
    return label
endfunction

set tabline=%!MyTabLine()

" ===== netrw 檔案資源管理器 =====
let g:netrw_banner = 0         " 設定是否顯示橫幅
let g:netrw_liststyle = 3      " 設定目錄列表樣式:樹形
let g:netrw_browse_split = 4   " 在之前的視窗編輯檔案
let g:netrw_altv = 1           " 水平分割時,檔案瀏覽器始終顯示在左邊
let g:netrw_winsize = 25       " 設定檔案瀏覽器視窗寬度為25%
let g:netrw_list_hide= '^\..*' " 不顯示隱藏檔案 用 a 鍵就可以顯示所有檔案、 隱藏匹配檔案或只顯示匹配檔案

(四)plugins.vim

call plug#begin("~/.config/nvim/plugged")
" The default plugin directory will be as follows:
"   - Vim (Linux/macOS): '~/.vim/plugged'
"   - Vim (Windows): '~/vimfiles/plugged'
"   - Neovim (Linux/macOS/Windows): stdpath('data') . '/plugged'
" You can specify a custom plugin directory by passing it as the argument
"   - e.g. `call plug#begin('~/.vim/plugged')`
"   - Avoid using standard Vim directory names like 'plugin'

" 這裡只新增了 coc 一個外掛
Plug 'neoclide/coc.nvim', {'branch': 'release'}

" Initialize plugin system
" - Automatically executes `filetype plugin indent on` and `syntax enable`.
call plug#end()