VIMの開発環境を整えたかったので、その時のメモ。
Plugの導入
ターミナルの設定
NerdTree用のアイコン表示設定
サーバー上で作業する場合
クリップボードにヤンクしたコードをコピーしたい時の準備
クライアントサイドでは不要
sudo apt-get install tmux
cat > ~/.tmux.conf
# クリップボード共有を有効化
set-option -g mouse on
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -selection clipboard -in"
# ステータスライン全体の背景を暗めに設定
set -g status-bg colour234
set -g status-fg white
nvimの設定
mkdir -p ~/.config/nvim
cat > ~/.config/nvim/init.vim
以下の設定をコピペ
" ===== 基本設定 =====
set clipboard+=unnamedplus " システムクリップボードを使用
" ===== 検索設定 =====
set ignorecase " 大文字小文字を区別しない
set smartcase " 検索文字に大文字がある場合は大文字小文字を区別
set incsearch " インクリメンタルサーチ
set hlsearch " 検索結果をハイライト
" ===== 表示設定 =====
set number " 行番号を表示
set cursorline " カーソル行をハイライト"
set wrap " 長い行を折り返す
set textwidth=0 " 自動的な改行を無効化
set autowrite " 自動保存
set showcmd " 入力中のコマンドを表示
set showmode " 現在のモードを表示
set showmatch " 対応する括弧を表示
set expandtab " タブをスペースに変換
set smartindent " スマートインデント
set autoindent " 自動インデント
set shiftwidth=4 " インデント幅
set textwidth=78 " テキスト幅
set softtabstop=4 " ソフトタブストップ
set tabstop=4 " タブ幅
set fenc=UTF-8
set fencs=UTF-8,ISO-2022-JP,EUC-JP,CP932,SHIFT-JIS
set foldmethod=syntax " 構文に基づいて折りたたみ
set foldlevelstart=0 " 99: 全て開いた状態 0: 全て閉じた状態"
" ===== バックアップとスワップファイルの設定 =====
set history=10000 " コマンドライン履歴を10000行保持
set nobackup " バックアップファイルを作成しない
set nowritebackup " ファイルの上書き前にバックアップを作成しない
set noswapfile " スワップファイルを使用しない
set smarttab " スマートタブ
" ===== プラグイン管理 =====
call plug#begin('~/.vim/plugged')
" Gitプラグイン
Plug 'tpope/vim-fugitive'
Plug 'airblade/vim-gitgutter'
" 自動ペアリングプラグイン
Plug 'windwp/nvim-autopairs'
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-path'
Plug 'hrsh7th/cmp-cmdline'
" 各種言語のシンタックスとインデントプラグイン
Plug 'sheerun/vim-polyglot'
" カラースキーム
Plug 'morhetz/gruvbox'
" Python固有のプラグイン
Plug 'hynek/vim-python-pep8-indent'
" 言語固有のプラグイン
Plug 'toyamarinyon/vim-swift'
Plug 'wuelnerdotexe/vim-astro'
" 強力な補完エンジン
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'neoclide/coc-git'
" リンティングと修正
Plug 'dense-analysis/ale'
" Tailwind CSS補完
Plug 'iamcco/coc-tailwindcss', {'do': 'yarn install --frozen-lockfile'}
" ファイルエクスプローラ
Plug 'preservim/nerdtree'
" ターミナル
Plug 'akinsho/toggleterm.nvim'
" JavaScript/JSXプラグイン
Plug 'mxw/vim-jsx'
Plug 'isRuslan/vim-es6'
Plug 'pangloss/vim-javascript'
Plug 'maxmellon/vim-jsx-pretty'
Plug 'alampros/vim-styled-jsx'
Plug 'moll/vim-node'
" ステータスライン
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
" アイコン
Plug 'ryanoasis/vim-devicons'
Plug 'kristijanhusak/defx-icons'
" 自動保存
Plug 'Pocco81/auto-save.nvim'
Plug 'nvim-lua/plenary.nvim'
Plug 'nvim-treesitter/nvim-treesitter'
Plug 'hrsh7th/nvim-cmp' " Optional: For using slash commands and variables in the chat buffer
Plug 'nvim-telescope/telescope.nvim' " Optional: For working with files with slash commands
Plug 'stevearc/dressing.nvim' " Optional: Improves the default Neovim UI
Plug 'olimorris/codecompanion.nvim'
call plug#end()
" ===== プラグイン設定 =====
" Pydiction設定
let g:pydiction_location = '~/.vim/pydiction/complete-dict'
let g:PyFlakeOnWrite = 1
let g:PyFlakeCheckers = 'pep8,mccabe,pyflakes'
let g:PyFlakeDefaultComplexity=10
let g:PyFlakeRangeCommand = 'q'
let g:jedi#completions_command = "<C-k>"
" Astro設定
let g:astro_typescript = 'enable'
" Devicons設定
let g:webdevicons_enable_nerdtree = 1
let g:airline_powerline_fonts = 1
let g:airline#extensions#tabline#enabled = 1
" Copilot設定
let g:copilot_filetypes = { '*': v:true }
" JSX設定
let g:vim_jsx_pretty_highlight_close_tag = 1
" ===== ファイルタイプ固有の設定 =====
augroup FileTypeSpecificSettings
autocmd!
autocmd BufNewFile,BufRead *.jsx setlocal filetype=typescriptreact softtabstop=2 tabstop=2 shiftwidth=2
autocmd BufNewFile,BufRead *.tsx,*.js,*ts,*.astro setlocal filetype=typescript softtabstop=2 tabstop=2 shiftwidth=2
autocmd BufNewFile,BufRead *.vim setlocal filetype=vim softtabstop=2 tabstop=2 shiftwidth=2
autocmd FileType python let b:did_ftplugin = 1
autocmd FileType python setl colorcolumn=80 textwidth=78
augroup END
" ===== NERDTree設定 =====
let g:NERDTreeIgnore = ['\.pyc$', '\.pyo$', '__pycache__', '\.git$', '\.DS_Store$', '\.vscode$', '\.idea$', '\.venv$', '\.mypy_cache$', '\.pytest_cache$', '\.cache', '\.vscode', '\.idea', '\.venv', '\.mypy_cache', '\.pytest_cache', '\.svn']
let g:NERDTreeShowHidden = 1
let g:NERDTreeWinSize=35
" NERDTreeを自動的に開く
" autocmd vimenter * NERDTree | wincmd p
function! CloseVimIfLastWindow()
" 現在のウィンドウが1つしかないかどうかを確認
if winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree()
" NERDTree以外のバッファをフィルタリング
let l:other_buffers = filter(range(1, bufnr('$')), 'buflisted(v:val) && getbufvar(v:val, "&filetype") != "nerdtree"')
" NERDTree以外のバッファが1つだけ残っている場合、そのバッファが表示されていると仮定
if len(l:other_buffers) == 1
" 現在のバッファがNERDTreeではない場合、他のバッファに切り替えてから終了
if &filetype != "nerdtree"
execute 'buffer ' . l:other_buffers[0]
endif
" 現在のウィンドウを閉じる
quit
elseif len(l:other_buffers) == 0
" NERDTree以外のバッファが存在しない場合にVimを終了
quit
endif
endif
endfunction
" autocmdを使ってバッファの状態を監視し、条件が満たされたときに関数を実行
autocmd bufenter * call CloseVimIfLastWindow()
" バッファリストを取得する関数
function! GetBufferList()
return filter(range(1, bufnr('$')), 'buflisted(v:val) && getbufvar(v:val, "&filetype") != "nerdtree"')
endfunction
" 指定されたバッファに移動する関数
function! SwitchToBuffer(buffer_number)
execute 'buffer ' . a:buffer_number
endfunction
" NERDTreeの状態を更新する関数
function! UpdateNERDTree()
if exists(':NERDTreeFind')
NERDTreeFind
wincmd p
endif
endfunction
" NERDTreeが閉じられたときの処理
function! HandleNERDTreeClose()
let l:buffer_list = GetBufferList()
if len(l:buffer_list) >= 1
call SwitchToBuffer(l:buffer_list[-1])
call UpdateNERDTree()
else
quit
endif
endfunction
" カスタムバッファクローズ処理
function! CustomBufferClose()
let l:current_bufnr = bufnr('%')
let l:buffer_list = GetBufferList()
if &filetype == 'nerdtree'
call HandleNERDTreeClose()
return
endif
if len(l:buffer_list) > 1
let l:current_index = index(l:buffer_list, l:current_bufnr)
execute 'bdelete ' . l:current_bufnr
if l:current_index == len(l:buffer_list) - 1
call SwitchToBuffer(l:buffer_list[l:current_index - 1])
else
call SwitchToBuffer(l:buffer_list[l:current_index + 1])
endif
call UpdateNERDTree()
else
quit
endif
endfunction
" NERDTreeが閉じられたときのイベントハンドラ
augroup NERDTreeCustom
autocmd!
autocmd BufDelete * if &filetype == 'nerdtree' | call HandleNERDTreeClose() | endif
augroup END
" :q コマンドのカスタマイズ
command! -bang -nargs=* QClose silent! call CustomBufferClose()
cnoreabbrev <expr> q getcmdtype() == ":" && getcmdline() == "q" ? "QClose" : "q"
" NERDTree表示設定
let g:NERDTreeShowLineNumbers=1
let g:NERDTreeDirArrows=1
" NERDTreeキーマッピング
let g:NERDTreeMapOpenVSplit = 'v'
nnoremap <silent> <C-n> :NERDTreeToggle<CR>
nnoremap <silent> <C-t> :NERDTreeFind<CR>
" バッファナビゲーション
nnoremap <silent> <C-{> :bprevious<CR>
nnoremap <silent> <C-}> :bnext<CR>
" 隠しファイルを表示
let NERDTreeShowHidden=1
" NERDTreeウィンドウサイズ
let NERDTreeWinSize=35
" 新しいタブでファイルを開く
let g:NERDTreeMapOpenInTab='t'
" Gitステータスインジケータ
let g:NERDTreeGitStatusIndicatorMapCustom = {
\ 'Modified' : '✹',
\ 'Staged' : '✔',
\ 'Untracked' : '✭',
\ 'Renamed' : '➜',
\ 'Unmerged' : '═',
\ 'Deleted' : '✖',
\ 'Dirty' : '✗',
\ 'Clean' : '✔︎',
\ 'Ignored' : '☒',
\ 'Unknown' : '?'
\ }
" Gitステータスを表示
let g:NERDTreeShowGitStatus = 1
" ===== Airline設定 =====
" Gitブランチを表示
let g:airline#extensions#branch#enabled = 1
let g:airline#extensions#branch#format = 0
let g:airline#extensions#hunks#enabled = 1
" バッファラインを有効化
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#formatter = 'default'
" NERDTreeが開いている時でもバッファリストを表示
let g:airline#extensions#tabline#fnamemod = ':t'
let g:airline#extensions#tabline#show_buffers = 1
" ===== リンティング設定 =====
let g:ale_linters = {
\ 'javascript': ['eslint'],
\ 'typescript': ['tsserver', 'eslint'],
\ 'python': ['flake8'],
\ }
let g:ale_fixers = {
\ 'python': ['autopep8'],
\ 'javascript': ['prettier'],
\ 'typescript': ['prettier'],
\ }
" let g:syntastic_python_checkers = ['pyflakes', 'pep8']
let g:ale_python_flake8_executable = 'flake8'
let g:ale_python_autopep8_executable = 'autopep8'
let g:ale_fix_on_save = 1
" ===== リモート同期設定 =====
let g:sync_remote = 1
if g:sync_remote
" autocmd BufWritePost ''
endif
" ===== フォントと色の設定 =====
" set guifont=DroidSansMono_Nerd_Font:h11
set background=dark
colorscheme habamax
" 補完メニューの色
highlight! CmpItemAbbr guifg=#ebdbb2 guibg=NONE
highlight! CmpItemKind guifg=#d79921 guibg=NONE
highlight! CmpItemMenu guifg=#83a598 guibg=NONE
highlight! CmpItemAbbrMatch guifg=#fe8019 guibg=NONE
highlight! CmpItemAbbrMatchFuzzy guifg=#fe8019 guibg=NONE
" ===== ファイルタイプ設定 =====
filetype indent on
filetype plugin indent on
filetype on
syntax on
" ===== ファイルタイプ別の設定 =====
" Vimスクリプトファイルの設定
autocmd FileType vim setlocal foldmethod=marker
" Pythonファイルの設定
autocmd FileType python setlocal
\ tabstop=4
\ softtabstop=4
\ shiftwidth=4
\ textwidth=79
\ expandtab
\ autoindent
\ fileformat=unix
\ foldmethod=indent
" JavaScript/TypeScript/JSX/TSXファイルの設定
autocmd FileType javascript,typescript,javascriptreact,typescriptreact setlocal
\ tabstop=2
\ softtabstop=2
\ shiftwidth=2
" HTMLファイルの設定
autocmd FileType html setlocal
\ tabstop=2
\ softtabstop=2
\ shiftwidth=2
" CSSファイルの設定
autocmd FileType css setlocal
\ tabstop=2
\ softtabstop=2
\ shiftwidth=2
" ===== キーマッピング =====
" リーダーキーの設定
let mapleader = "\<Space>"
" ファイル保存のショートカット
nnoremap <leader>w :w<CR>
" ファイル終了のショートカット
nnoremap <leader>q :q<CR>
" 分割ウィンドウの移動
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
" タブ操作
nnoremap <leader>tn :tabnew<CR>
nnoremap <leader>tc :tabclose<CR>
nnoremap <leader>to :tabonly<CR>
" ===== プラグイン固有の設定 =====
" NERDTreeの設定
nnoremap <leader>n :NERDTreeToggle<CR>
let g:NERDTreeIgnore = ['\.pyc$', '\.pyo$', '__pycache__']
let g:NERDTreeShowHidden = 1
" Fugitiveの設定
nnoremap <leader>gs :Git<CR>
nnoremap <leader>gc :Git commit<CR>
nnoremap <leader>gp :Git push<CR>
" fzfの設定
nnoremap <C-p> :Files<CR>
nnoremap <leader>b :Buffers<CR>
" ===== プラグイン設定 =====
let maplocalleader = ","
" ALE(非同期Lint Engine)の設定
let g:ale_linters = {
\ 'python': ['flake8'],
\ 'javascript': ['eslint'],
\ 'typescript': ['tslint']
\}
let g:ale_fixers = {
\ '*': ['remove_trailing_lines', 'trim_whitespace'],
\ 'python': ['black'],
\ 'javascript': ['prettier'],
\ 'typescript': ['prettier']
\}
let g:ale_fix_on_save = 1
" ステータスラインの設定
set laststatus=2
let g:airline_powerline_fonts = 1
let g:airline#extensions#tabline#enabled = 1
" ===== 自動コマンド =====
" ファイルを開いたときに、カーソルを最後の位置に移動
autocmd BufReadPost *
\ if line("'\"") > 1 && line("'\"") <= line("$") |
\ exe "normal! g`\"" |
\ endif
" ファイルタイプごとのプラグイン・インデント設定を有効化
filetype plugin indent on
" シンタックスハイライトを有効化
syntax enable
" ===== lua設定 =====
" ===== ターミナル設定 =====
" Ctrl + バックスラッシュでターミナルを開閉
lua << EOF
-- ターミナル設定
require("toggleterm").setup {
-- ターミナルのサイズ
size = 60,
-- ターミナルを開くキーマッピング
open_mapping = [[<c-\>]],
-- ファイルタイプごとの影の設定
shade_filetypes = {},
-- ターミナルに影をつける
shade_terminals = true,
-- 影の濃さ
shading_factor = '2',
-- 挿入モードで開始
start_in_insert = true,
-- 挿入モードのマッピングを有化
insert_mappings = true,
-- サイズを保持
persist_size = true,
-- ターミナルの方向
direction = 'vertical',
}
-- 自動保存設定
require('auto-save').setup {
-- 自動保存を有効化
enabled = true,
-- 自動保存をトリガーするイベント
events = {"InsertLeave", "TextChanged"},
-- 実行メッセージの設定
execution_message = {
message = function()
return ("AutoSave: " .. vim.fn.strftime("%H:%M:%S") .. "に保存しました")
end,
dim = 0.18,
cleaning_interval = 1250,
},
-- 自動保存の条件
conditions = {
exists = true,
filename_is_not = {},
filetype_is_not = {},
modifiable = true
},
-- すべてのバッファを書き込むかどうか
write_all_buffers = false,
-- オン/オフコマンドを有効化
on_off_commands = true,
-- コマンドラインのクリーニング間隔
clean_command_line_interval = 0,
-- 遅延時間
debounce_delay = 135
}
-- 補完設定
local cmp = require'cmp'
cmp.setup({
-- スニペットエンジンの設定
snippet = {
expand = function(args)
vim.fn["vsnip#anonymous"](args.body) -- vsnipユーザー向け
end,
},
-- キーマッピングの設定
mapping = {
['<C-b>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.close(),
['<CR>'] = cmp.mapping.confirm({ select = true }),
},
-- 補完ソースの設定
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
{ name = 'vsnip' }, -- vsnipユーザー向け
}, {
{ name = 'buffer' },
})
})
-- 検索コマンド用の補完ソース設定
cmp.setup.cmdline('/', {
sources = {
{ name = 'buffer' }
}
})
cmp.setup.cmdline('?', {
sources = {
{ name = 'buffer' }
}
})
-- コマンドライン用の補完ソース設定
cmp.setup.cmdline(':', {
sources = cmp.config.sources({
{ name = 'path' }
}, {
{ name = 'cmdline' }
})
})
-- 自動括弧補完の設定
-- 自動ペアリング設定
require('nvim-autopairs').setup()
local cmp = require('cmp')
local cmp_autopairs = require('nvim-autopairs.completion.cmp')
cmp.event:on(
'confirm_done',
cmp_autopairs.on_confirm_done()
)
-- ===== コードコンパニオン設定 =====
local status, codecompanion = pcall(require, "codecompanion")
if not status then
print("Error loading codecompanion")
return
end
require("codecompanion").setup({
strategies = {
chat = {
adapter = "openai", -- o1-miniをためす。
},
inline = {
adapter = "openai", -- copilotにすると動かない
},
agent = {
adapter = "openai",
},
},
adapters = {
ollama = function()
return require("codecompanion.adapters").extend("ollama", {
env = {
url = "https://localhost:11434",
api_key = "OLLAMA_API_KEY",
},
headers = {
["Content-Type"] = "application/json",
["Authorization"] = "Bearer ${api_key}",
},
parameters = {
sync = true,
},
})
end,
deepseek = function()
return require("codecompanion.adapters").extend("ollama", {
schema = {
model = {
default = "deepseek-coder-v2:latest",
},
num_ctx = {
default = 128000,
},
num_predict = {
default = -1,
},
},
})
end,
openai = function()
return require("codecompanion.adapters").extend("openai", {
env = {
api_key = "sk-**"
},
schema = {
model = {
default = "o1-mini ",
},
},
})
end,
haiku = function()
return require("codecompanion.adapters").extend("anthropic", {
env = {
api_key = "--",
},
schema = {
model = {
default = "claude-3-haiku-20240307",
},
},
})
end,
sonet = function()
return require("codecompanion.adapters").extend("anthropic", {
env = {
api_key = "--",
},
schema = {
model = {
default = "claude-3-sonnet-20240229",
},
},
})
end,
},
})
vim.api.nvim_set_keymap("n", "<C-a>", "<cmd>CodeCompanionActions<cr>", { noremap = true, silent = true })
vim.api.nvim_set_keymap("v", "<C-a>", "<cmd>CodeCompanionActions<cr>", { noremap = true, silent = true })
vim.api.nvim_set_keymap("n", "<LocalLeader>a", "<cmd>CodeCompanionToggle<cr>", { noremap = true, silent = true })
vim.api.nvim_set_keymap("v", "<LocalLeader>a", "<cmd>CodeCompanionToggle<cr>", { noremap = true, silent = true })
vim.api.nvim_set_keymap("v", "ga", "<cmd>CodeCompanionAdd<cr>", { noremap = true, silent = true })
vim.cmd([[cab cc CodeCompanion]])
EOF