From 755f17948a95df8b0c6793310ce8abc448dd2b2d Mon Sep 17 00:00:00 2001 From: nsfisis Date: Mon, 19 Dec 2022 00:08:48 +0900 Subject: neovim: refactor --- .config/nvim/lua/my_env.lua | 39 -- .config/nvim/lua/plugins.lua | 781 ------------------------------------- .config/nvim/lua/vimrc.lua | 150 ------- .config/nvim/lua/vimrc/init.lua | 150 +++++++ .config/nvim/lua/vimrc/my_env.lua | 41 ++ .config/nvim/lua/vimrc/plugins.lua | 781 +++++++++++++++++++++++++++++++++++++ 6 files changed, 972 insertions(+), 970 deletions(-) delete mode 100644 .config/nvim/lua/my_env.lua delete mode 100644 .config/nvim/lua/plugins.lua delete mode 100644 .config/nvim/lua/vimrc.lua create mode 100644 .config/nvim/lua/vimrc/init.lua create mode 100644 .config/nvim/lua/vimrc/my_env.lua create mode 100644 .config/nvim/lua/vimrc/plugins.lua (limited to '.config/nvim/lua') diff --git a/.config/nvim/lua/my_env.lua b/.config/nvim/lua/my_env.lua deleted file mode 100644 index dbfcfb6..0000000 --- a/.config/nvim/lua/my_env.lua +++ /dev/null @@ -1,39 +0,0 @@ -local M = {} - -local F = vim.fn - -if F.has('unix') then - M.os = 'unix' -elseif F.has('mac') then - M.os = 'mac' -elseif F.has('wsl') then - M.os = 'wsl' -elseif F.has('win32') or F.has('win64') then - M.os = 'windows' -else - M.os = 'unknown' -end - -M.home = vim.env.HOME or F.expand('~') - -M.config_home = vim.env.XDG_CONFIG_HOME or vim.env.HOME .. '/.config' - -M.config_dir = F.stdpath('config') -M.cache_dir = F.stdpath('cache') -M.data_dir = F.stdpath('data') - -M.backup_dir = M.data_dir .. '/backup' -M.yankround_dir = M.data_dir .. '/yankround' - -M.skk_dir = M.config_home .. '/skk' -M.scratch_dir = M.home .. '/scratch' - -function M.mkdir() - for k, v in pairs(M) do - if vim.endswith(k, '_dir') and F.isdirectory(v) == 0 then - F.mkdir(v, 'p') - end - end -end - -return M diff --git a/.config/nvim/lua/plugins.lua b/.config/nvim/lua/plugins.lua deleted file mode 100644 index d72820d..0000000 --- a/.config/nvim/lua/plugins.lua +++ /dev/null @@ -1,781 +0,0 @@ -vim.cmd.packadd('packer.nvim') -local packer = require('packer') - --- Plugins {{{1 -packer.startup(function(use) - -- Plugin management {{{2 - use { - 'wbthomason/packer.nvim', - opt = true, - } - -- Libraries {{{2 - -- telescope.nvim depends on it. - use { - 'nvim-lua/plenary.nvim', - } - -- Text editing {{{2 - -- IME {{{3 - -- SKK (Simple Kana to Kanji conversion program) for Vim. - use { - 'vim-skk/eskk.vim', - config = function() - local my_env = require('my_env') - - vim.g['eskk#dictionary'] = { - path = my_env.skk_dir .. '/jisyo', - sorted = false, - encoding = 'utf-8', - } - - vim.g['eskk#large_dictionary'] = { - path = my_env.skk_dir .. '/jisyo.L', - sorted = true, - encoding = 'euc-jp', - } - - vim.g['eskk#backup_dictionary'] = vim.g['eskk#dictionary'].path .. '.bak' - - -- NOTE: - -- Boolean values are not accepted because eskk#utils#set_default() checks types. - vim.g['eskk#enable_completion'] = 0 - vim.g['eskk#egg_like_newline'] = 1 - - -- Change default markers because they are EAW (East Asian Width) characters. - vim.g['eskk#marker_henkan'] = '[!]' - vim.g['eskk#marker_okuri'] = '-' - vim.g['eskk#marker_henkan_select'] = '[#]' - vim.g['eskk#marker_jisyo_touroku'] = '[?]' - - vim.cmd([=[ - function! My_eskk_initialize_pre() - for [orgtable, mode] in [['rom_to_hira', 'hira'], ['rom_to_kata', 'kata']] - let t = eskk#table#new(orgtable . '*', orgtable) - call t.add_map('z ', ' ') - call t.add_map('0.', '0.') - call t.add_map('1.', '1.') - call t.add_map('2.', '2.') - call t.add_map('3.', '3.') - call t.add_map('4.', '4.') - call t.add_map('5.', '5.') - call t.add_map('6.', '6.') - call t.add_map('7.', '7.') - call t.add_map('8.', '8.') - call t.add_map('9.', '9.') - call t.add_map(':', ':') - call t.add_map('z:', ':') - " Workaround: 'zl' does not work as 'l' key leaves from SKK mode. - call t.add_map('zL', '→') - call eskk#register_mode_table(mode, t) - endfor - endfunction - - autocmd Vimrc User eskk-initialize-pre call My_eskk_initialize_pre() - - function! My_eskk_initialize_post() - " I don't use hankata mode for now. - EskkUnmap -type=mode:hira:toggle-hankata - EskkUnmap -type=mode:kata:toggle-hankata - - " I don't use abbrev mode for now. - EskkUnmap -type=mode:hira:to-abbrev - EskkUnmap -type=mode:kata:to-abbrev - - " I don't use ascii mode for now. - EskkUnmap -type=mode:hira:to-ascii - EskkUnmap -type=mode:kata:to-ascii - - " Instead, l key disable SKK input. - EskkMap -type=disable l - - " I type for new line. - EskkMap -type=kakutei - - map! jk (eskk:disable) - - " Custom highlight for henkan markers. - syntax match skkMarker '\[[!#?]\]' - hi link skkMarker Special - endfunction - - autocmd Vimrc User eskk-initialize-post call My_eskk_initialize_post() - ]=]) - end, - } - -- Operators {{{3 - -- Support for user-defined operators. - use { - 'kana/vim-operator-user', - } - -- Extract expression and make assingment statement. - use { - 'tek/vim-operator-assign', - } - -- Replace text without updating registers. - use { - 'kana/vim-operator-replace', - opt = true, - keys = { - {'n', '(operator-replace)'}, - {'o', '(operator-replace)'}, - {'x', '(operator-replace)'}, - }, - setup = function() - vim.keymap.set('n', '', '(operator-replace)') - vim.keymap.set('o', '', '(operator-replace)') - vim.keymap.set('x', '', '(operator-replace)') - end, - } - -- Super surround. - use { - 'machakann/vim-sandwich', - config = function() - vim.fn['operator#sandwich#set']('add', 'all', 'highlight', 2) - vim.fn['operator#sandwich#set']('delete', 'all', 'highlight', 0) - vim.fn['operator#sandwich#set']('replace', 'all', 'highlight', 2) - - do - local rs = vim.fn['sandwich#get_recipes']() - - rs[#rs+1] = { - buns = {'「', '」'}, - input = {'j[', 'j]'}, - } - rs[#rs+1] = { - buns = {'『', '』'}, - input = {'j{', 'j}'}, - } - rs[#rs+1] = { - buns = {'【', '】'}, - input = {'j(', 'j)'}, - } - - vim.g['sandwich#recipes'] = rs - end - end, - } - -- Non-operators {{{3 - -- Comment out. - use { - 'numToStr/Comment.nvim', - opt = true, - keys = { - {'n', 'm//'}, - {'n', 'm??'}, - {'n', 'm/'}, {'x', 'm/'}, - {'n', 'm?'}, {'x', 'm?'}, - {'n', 'm/O'}, - {'n', 'm/o'}, - {'n', 'm/A'}, - }, - config = function() - require('Comment').setup { - toggler = { - line = 'm//', - block = 'm??', - }, - opleader = { - line = 'm/', - block = 'm?', - }, - extra = { - above = 'm/O', - below = 'm/o', - eol = 'm/A', - }, - } - end, - } - -- Align text. - use { - 'junegunn/vim-easy-align', - opt = true, - cmd = {'EasyAlign'}, - keys = { - {'n', '(EasyAlign)'}, - {'x', '(EasyAlign)'}, - }, - setup = function() - vim.keymap.set('n', '=', '(EasyAlign)') - vim.keymap.set('x', '=', '(EasyAlign)') - end, - } - -- Text objects {{{2 - -- Support for user-defined text objects. - use { - 'kana/vim-textobj-user', - } - -- Text object for blockwise. - use { - 'osyo-manga/vim-textobj-blockwise', - } - -- Text object for comment. - use { - 'thinca/vim-textobj-comment', - } - -- Text object for indent. - use { - 'kana/vim-textobj-indent', - } - -- Text object for line. - use { - 'kana/vim-textobj-line', - } - -- Text object for parameter. - use { - 'sgur/vim-textobj-parameter', - } - -- Text object for space. - use { - 'saihoooooooo/vim-textobj-space', - opt = true, - keys = { - {'o', 'a'}, {'x', 'a'}, - {'o', 'i'}, {'x', 'i'}, - }, - setup = function() - vim.g.textobj_space_no_default_key_mappings = true - end, - config = function() - vim.keymap.set('o', 'a', '(textobj-space-a)') - vim.keymap.set('x', 'a', '(textobj-space-a)') - vim.keymap.set('o', 'i', '(textobj-space-i)') - vim.keymap.set('x', 'i', '(textobj-space-i)') - end, - } - -- Text object for syntax. - use { - 'kana/vim-textobj-syntax', - } - -- Text object for URL. - use { - 'mattn/vim-textobj-url', - } - -- Text object for words in words. - use { - 'h1mesuke/textobj-wiw', - opt = true, - keys = { - {'n', ''}, {'o', ''}, {'x', ''}, - {'n', 'g'}, {'o', 'g'}, {'x', 'g'}, - {'n', ''}, {'o', ''}, {'x', ''}, - {'n', 'g'}, {'o', 'g'}, {'x', 'g'}, - {'o', 'a'}, {'x', 'a'}, - {'o', 'i'}, {'x', 'i'}, - }, - setup = function() - vim.g.textobj_wiw_no_default_key_mappings = true - end, - config = function() - vim.keymap.set('n', '', '(textobj-wiw-n)') - vim.keymap.set('o', '', '(textobj-wiw-n)') - vim.keymap.set('x', '', '(textobj-wiw-n)') - vim.keymap.set('n', 'g', '(textobj-wiw-p)') - vim.keymap.set('o', 'g', '(textobj-wiw-p)') - vim.keymap.set('x', 'g', '(textobj-wiw-p)') - vim.keymap.set('n', '', '(textobj-wiw-N)') - vim.keymap.set('o', '', '(textobj-wiw-N)') - vim.keymap.set('x', '', '(textobj-wiw-N)') - vim.keymap.set('n', 'g', '(textobj-wiw-P)') - vim.keymap.set('o', 'g', '(textobj-wiw-P)') - vim.keymap.set('x', 'g', '(textobj-wiw-P)') - - vim.keymap.set('o', 'a', '(textobj-wiw-a)') - vim.keymap.set('x', 'a', '(textobj-wiw-a)') - vim.keymap.set('o', 'i', '(textobj-wiw-i)') - vim.keymap.set('x', 'i', '(textobj-wiw-i)') - end, - } - -- Search {{{2 - -- Extend * and #. - use { - 'haya14busa/vim-asterisk', - opt = true, - keys = { - {'n', '(asterisk-z*)'}, {'x', '(asterisk-z*)'}, - {'n', '(asterisk-gz*)'}, {'x', '(asterisk-gz*)'}, - }, - setup = function() - vim.keymap.set({'n', 'x'}, '*', '(asterisk-z*)') - vim.keymap.set({'n', 'x'}, 'g*', '(asterisk-gz*)') - end, - } - -- NOTE: it is a fork version of jremmen/vim-ripgrep - -- Integration with ripgrep, fast alternative of grep command. - use { - 'nsfisis/vim-ripgrep', - opt = true, - cmd = {'Rg', 'RG'}, - config = function() - -- Workaround: do not open quickfix window. - -- exe g:rg_window_location 'copen' - vim.g.rg_window_location = 'silent! echo' - vim.g.rg_jump_to_first = true - - vim.api.nvim_create_user_command( - 'RG', - 'Rg ', - { - bang = true, - bar = true, - nargs = '*', - complete = 'file', - } - ) - end, - } - -- Files {{{2 - -- Switch to related files. - use { - 'kana/vim-altr', - config = function() - -- C/C++ - vim.fn['altr#define']('%.c', '%.cpp', '%.cc', '%.h', '%.hh', '%.hpp') - -- Vim - vim.fn['altr#define']('autoload/%.vim', 'doc/%.txt', 'plugin/%.vim') - - -- Go to File Alternative - vim.keymap.set('n', 'gfa', '(altr-forward)') - end, - } - -- Full-featured filer. - use { - 'lambdalisue/fern.vim', - opt = true, - cmd = {'Fern'}, - config = function() - local vimrc = require('vimrc') - - vimrc.autocmd('FileType', { - pattern = {'fern'}, - callback = function() - vim.keymap.del('n', 't', { buffer = true }) - end, - }) - end, - } - -- Fern plugin: hijack Netrw. - use { - 'lambdalisue/fern-hijack.vim', - } - -- Appearance {{{2 - -- Show highlight. - use { - 'cocopon/colorswatch.vim', - opt = true, - cmd = {'ColorSwatchGenerate'}, - } - -- Makes folding text cool. - use { - 'LeafCage/foldCC.vim', - config = function() - vim.o.foldtext = 'FoldCCtext()' - vim.g.foldCCtext_head = 'repeat(">", v:foldlevel) . " "' - end, - } - -- Show indentation guide. - use { - 'lukas-reineke/indent-blankline.nvim', - config = function() - require("indent_blankline").setup { - char_blankline = ' ', - show_first_indent_level = false, - } - end, - } - -- Highlight matched parentheses. - use { - 'itchyny/vim-parenmatch', - } - -- Tree-sitter integration. - use { - 'nvim-treesitter/nvim-treesitter', - run = ':TSUpdate', - config = function() - require('nvim-treesitter.configs').setup { - ensure_installed = 'all', - sync_install = false, - highlight = { - enable = true, - additional_vim_regex_highlighting = false, - }, - --[[ - incremental_selection = { - enable = true, - keymaps = { - init_selection = 'TODO', - node_incremental = 'TODO', - scope_incremental = 'TODO', - node_decremental = 'TODO', - }, - }, - --]] - indent = { - enable = false, - }, - yati = { - enable = true, - }, - } - end, - } - -- Tree-sitter debugging. - use { - 'nvim-treesitter/playground', - } - -- Highlight specified words. - use { - 't9md/vim-quickhl', - config = function() - -- TODO: CUI - vim.g.quickhl_manual_colors = { - 'guifg=#101020 guibg=#8080c0 gui=bold', - 'guifg=#101020 guibg=#80c080 gui=bold', - 'guifg=#101020 guibg=#c08080 gui=bold', - 'guifg=#101020 guibg=#80c0c0 gui=bold', - 'guifg=#101020 guibg=#c0c080 gui=bold', - 'guifg=#101020 guibg=#a0a0ff gui=bold', - 'guifg=#101020 guibg=#a0ffa0 gui=bold', - 'guifg=#101020 guibg=#ffa0a0 gui=bold', - 'guifg=#101020 guibg=#a0ffff gui=bold', - 'guifg=#101020 guibg=#ffffa0 gui=bold', - } - - vim.keymap.set('n', '"', '(quickhl-manual-this)') - vim.keymap.set('x', '"', '(quickhl-manual-this)') - vim.keymap.set('n', '', ':nohlsearch QuickhlManualReset', { silent=true }) - end, - } - -- Yet another tree-sitter indentation. - -- TODO: uninstall it once the official nvim-treesitter provides sane indentation. - use { - 'yioneko/nvim-yati', - } - -- Filetypes {{{2 - -- Faster replacement for bundled filetype.vim - use { - 'nathom/filetype.nvim', - config = function() - require('filetype').setup({ - overrides = { - -- My settings here - }, - }) - end, - } - -- C/C++ - use { - 'rhysd/vim-clang-format', - config = function() - local vimrc = require('vimrc') - - vim.g['clang_format#auto_format'] = true - - vimrc.autocmd('FileType', { - pattern = {'javascript', 'typescript'}, - command = 'ClangFormatAutoDisable', - }) - end, - } - -- HTML/CSS - use { - 'mattn/emmet-vim', - opt = true, - cmd = {'EmmetInstall'}, - setup = function() - local vimrc = require('vimrc') - - vim.g.user_emmet_install_global = false - vimrc.autocmd('FileType', { - pattern = {'html', 'css'}, - command = 'EmmetInstall', - }) - end, - } - -- Rust - use { - 'rust-lang/rust.vim', - config = function() - vim.g.rustfmt_autosave = true - end, - } - -- QoL {{{2 - -- Capture the output of a command. - use { - 'tyru/capture.vim', - opt = true, - cmd = {'Capture'}, - } - -- Write git commit message. - use { - 'rhysd/committia.vim', - config = function() - vim.g.committia_hooks = { - edit_open = function(_info) - vim.wo.spell = true - end, - } - end, - } - -- Neovim clone of EasyMotion - use { - 'phaazon/hop.nvim', - branch = 'v2', -- Hop.nvim's README recommends this. - opt = true, - keys = { - {'n', '(hop-f)'}, {'o', '(hop-f)'}, - {'x', '(hop-f)'}, {'n', '(hop-F)'}, - {'o', '(hop-F)'}, {'x', '(hop-F)'}, - {'o', '(hop-t)'}, {'x', '(hop-t)'}, - {'o', '(hop-T)'}, {'x', '(hop-T)'}, - {'n', '(hop-s2)'}, {'o', '(hop-s2)'}, {'x', '(hop-s2)'}, - {'n', '(hop-n)'}, {'o', '(hop-n)'}, {'x', '(hop-n)'}, - {'n', '(hop-N)'}, {'o', '(hop-N)'}, {'x', '(hop-N)'}, - {'n', '(hop-j)'}, {'o', '(hop-j)'}, {'x', '(hop-j)'}, - {'n', '(hop-k)'}, {'o', '(hop-k)'}, {'x', '(hop-k)'}, - }, - config = function() - require('hop').setup { - keys = 'asdfghweryuiocvbnmjkl;', - } - - -- Emulate `g:EasyMotion_startofline = 0` in hop.nvim. - local function hop_jk(opts) - local hop = require('hop') - local jump_target = require('hop.jump_target') - - local column = vim.fn.col('.') - local match - if column == 1 then - match = function(_) - return 0, 1, false - end - else - local pat = vim.regex('\\%' .. column .. 'c') - match = function(s) - return pat:match_str(s) - end - end - setmetatable(opts, { __index = hop.opts }) - hop.hint_with( - jump_target.jump_targets_by_scanning_lines({ - oneshot = true, - match = match, - }), - opts - ) - end - - local hop = require('hop') - local HintDirection = require('hop.hint').HintDirection - local AFTER_CURSOR = HintDirection.AFTER_CURSOR - local BEFORE_CURSOR = HintDirection.BEFORE_CURSOR - - vim.keymap.set('', '(hop-f)', function() hop.hint_char1({ direction = AFTER_CURSOR, current_line_only = true }) end, { silent = true }) - vim.keymap.set('', '(hop-F)', function() hop.hint_char1({ direction = BEFORE_CURSOR, current_line_only = true }) end, { silent = true }) - vim.keymap.set('', '(hop-t)', function() hop.hint_char1({ direction = AFTER_CURSOR, current_line_only = true, hint_offset = -1 }) end, { silent = true }) - vim.keymap.set('', '(hop-T)', function() hop.hint_char1({ direction = BEFORE_CURSOR, current_line_only = true, hint_offset = 1 }) end, { silent = true }) - - vim.keymap.set('', '(hop-s2)', function() hop.hint_char2() end, { silent = true }) - vim.keymap.set('', '(hop-n)', function() hop.hint_patterns({ direction = AFTER_CURSOR }, vim.fn.getreg('/')) end, { silent = true }) - vim.keymap.set('', '(hop-N)', function() hop.hint_patterns({ direction = BEFORE_CURSOR }, vim.fn.getreg('/')) end, { silent = true }) - vim.keymap.set('', '(hop-j)', function() hop_jk({ direction = AFTER_CURSOR }) end, { silent = true }) - vim.keymap.set('', '(hop-k)', function() hop_jk({ direction = BEFORE_CURSOR }) end, { silent = true }) - end, - setup = function() - vim.keymap.set('n', 'f', '(hop-f)') - vim.keymap.set('o', 'f', '(hop-f)') - vim.keymap.set('x', 'f', '(hop-f)') - vim.keymap.set('n', 'F', '(hop-F)') - vim.keymap.set('o', 'F', '(hop-F)') - vim.keymap.set('x', 'F', '(hop-F)') - vim.keymap.set('o', 't', '(hop-t)') - vim.keymap.set('x', 't', '(hop-t)') - vim.keymap.set('o', 'T', '(hop-T)') - vim.keymap.set('x', 'T', '(hop-T)') - - -- Note: Don't use the following key sequences! They are used by 'vim-sandwich'. - -- * sa - -- * sd - -- * sr - vim.keymap.set('n', 'ss', '(hop-s2)') - vim.keymap.set('o', 'ss', '(hop-s2)') - vim.keymap.set('x', 'ss', '(hop-s2)') - vim.keymap.set('n', 'sn', '(hop-n)') - vim.keymap.set('o', 'sn', '(hop-n)') - vim.keymap.set('x', 'sn', '(hop-n)') - vim.keymap.set('n', 'sN', '(hop-N)') - vim.keymap.set('o', 'sN', '(hop-N)') - vim.keymap.set('x', 'sN', '(hop-N)') - vim.keymap.set('n', 'sj', '(hop-j)') - vim.keymap.set('o', 'sj', '(hop-j)') - vim.keymap.set('x', 'sj', '(hop-j)') - vim.keymap.set('n', 'sk', '(hop-k)') - vim.keymap.set('o', 'sk', '(hop-k)') - vim.keymap.set('x', 'sk', '(hop-k)') - end, - } - -- Integration with EditorConfig (https://editorconfig.org) - use { - 'editorconfig/editorconfig-vim', - } - -- Extend J. - use { - 'osyo-manga/vim-jplus', - config = function() - vim.g['jplus#input_config'] = { - __DEFAULT__ = { delimiter_format = ' %d ' }, - __EMPTY__ = { delimiter_format = '' }, - [' '] = { delimiter_format = ' ' }, - [','] = { delimiter_format = '%d ' }, - [':'] = { delimiter_format = '%d ' }, - [';'] = { delimiter_format = '%d ' }, - l = { delimiter_format = '' }, - L = { delimiter_format = '' }, - } - - vim.keymap.set('n', 'J', '(jplus-getchar)') - vim.keymap.set('x', 'J', '(jplus-getchar)') - vim.keymap.set('n', 'gJ', '(jplus-input)') - vim.keymap.set('x', 'gJ', '(jplus-input)') - end, - } - -- Improve behaviors of I, A and gI in Blockwise-Visual mode. - use { - 'kana/vim-niceblock', - config = function() - vim.keymap.set('x', 'I', '(niceblock-I)') - vim.keymap.set('x', 'gI', '(niceblock-gI)') - vim.keymap.set('x', 'A', '(niceblock-A)') - end, - } - -- Edit QuickFix freely. - use { - 'itchyny/vim-qfedit', - } - -- Edit QuickFix and reflect to original buffers. - use { - 'thinca/vim-qfreplace', - opt = true, - cmd = {'Qfreplace'}, - config = function() - vim.keymap.set('n', 'br', ':Qfreplace SmartOpen', { silent=true }) - end, - } - -- Run anything. - use { - 'thinca/vim-quickrun', - config = function() - vim.g.quickrun_config = { - cpp = { - cmdopt = '--std=c++17 -Wall -Wextra', - }, - d = { - exec = 'dub run', - }, - haskell = { - exec = {'stack build', 'stack exec %{matchstr(globpath(".,..,../..,../../..", "*.cabal"), "\\w\\+\\ze\\.cabal")}'}, - }, - python = { - command = 'python3', - }, - } - - vim.keymap.set('n', 'BB', '(quickrun)') - vim.keymap.set('x', 'BB', '(quickrun)') - end, - } - -- Extend dot-repeat. - use { - 'tpope/vim-repeat', - config = function() - vim.keymap.set('n', 'U', '(RepeatRedo)') - -- Autoload vim-repeat immediately in order to make (RepeatRedo) available. - -- repeat#setreg() does nothing here. - vim.fn['repeat#setreg']('', '') - end, - } - -- Introduce user-defined mode. - use { - 'kana/vim-submode', - config = function() - -- Global settings {{{3 - vim.g.submode_always_show_submode = true - vim.g.submode_keyseqs_to_leave = {'', ''} - vim.g.submode_keep_leaving_key = true - - -- yankround {{{3 - vim.fn['submode#enter_with']('YankRound', 'nv', 'rs', 'gp', '(yankround-p)') - vim.fn['submode#enter_with']('YankRound', 'nv', 'rs', 'gP', '(yankround-P)') - vim.fn['submode#map']('YankRound', 'nv', 'rs', 'p', '(yankround-prev)') - vim.fn['submode#map']('YankRound', 'nv', 'rs', 'P', '(yankround-next)') - - -- swap {{{3 - vim.fn['submode#enter_with']('Swap', 'n', 'rs', 'g>', '(swap-next)') - vim.fn['submode#map']('Swap', 'n', 'rs', '<', '(swap-prev)') - vim.fn['submode#enter_with']('Swap', 'n', 'rs', 'g<', '(swap-prev)') - vim.fn['submode#map']('Swap', 'n', 'rs', '>', '(swap-next)') - - -- TODO - if packer_plugins['vim-swap'] and not packer_plugins['vim-swap'].loaded then - vim.cmd.packadd('vim-swap') - end - - -- Resizing a window (height) {{{3 - vim.fn['submode#enter_with']('WinResizeH', 'n', 's', 'trh') - vim.fn['submode#enter_with']('WinResizeH', 'n', 's', 'trh') - vim.fn['submode#map']('WinResizeH', 'n', 's', '+', '+') - vim.fn['submode#map']('WinResizeH', 'n', 's', '-', '-') - - -- Resizing a window (width) {{{3 - vim.fn['submode#enter_with']('WinResizeW', 'n', 's', 'trw') - vim.fn['submode#enter_with']('WinResizeW', 'n', 's', 'trw') - vim.fn['submode#map']('WinResizeW', 'n', 's', '+', '>') - vim.fn['submode#map']('WinResizeW', 'n', 's', '-', '') - - -- Super undo/redo {{{3 - vim.fn['submode#enter_with']('Undo/Redo', 'n', 's', 'gu', 'g-') - vim.fn['submode#map']('Undo/Redo', 'n', 's', 'u', 'g-') - vim.fn['submode#enter_with']('Undo/Redo', 'n', 's', 'gU', 'g+') - vim.fn['submode#map']('Undo/Redo', 'n', 's', 'U', 'g+') - -- }}} - end, - } - -- Swap arguments. - use { - 'machakann/vim-swap', - opt = true, - setup = function() - vim.g.swap_no_default_key_mappings = true - end, - } - -- Fuzzy finder. - use { - 'nvim-telescope/telescope.nvim', - } - -- Adjust window size. - use { - 'rhysd/vim-window-adjuster', - config = function() - vim.keymap.set('n', 'tRw', 'AdjustScreenWidth') - vim.keymap.set('n', 'tRh', 'AdjustScreenHeight') - vim.keymap.set('n', 'tRr', ':AdjustScreenWidth AdjustScreenHeight', { silent=true }) - end, - } - -- Remember yank history and paste them. - use { - 'LeafCage/yankround.vim', - config = function() - local my_env = require('my_env') - - vim.g.yankround_dir = my_env.yankround_dir - vim.g.yankround_use_region_hl = true - end, - } - -- }}} -end) --- }}} - -return { - compile = packer.compile, - sync = packer.sync, -} diff --git a/.config/nvim/lua/vimrc.lua b/.config/nvim/lua/vimrc.lua deleted file mode 100644 index 65d229e..0000000 --- a/.config/nvim/lua/vimrc.lua +++ /dev/null @@ -1,150 +0,0 @@ -local M = {} - - - -local vimrc_augroup - -function M.create_augroup_for_vimrc() - vimrc_augroup = vim.api.nvim_create_augroup('Vimrc', {}) -end - -function M.autocmd(event, opts) - if not opts.group then - opts.group = vimrc_augroup - end - vim.api.nvim_create_autocmd(event, opts) -end - - - -function M.after_ftplugin(ft, callback) - local var_name = 'did_ftplugin_' .. ft .. '_after' - if vim.b[var_name] ~= nil then - return - end - - callback(conf) - - vim.b[var_name] = true -end - - - -local function set_indentation(style, width) - vim.bo.expandtab = style - vim.bo.tabstop = width - vim.bo.shiftwidth = width - vim.bo.softtabstop = width -end - - -function M.register_filetype_autocmds_for_indentation() - local SPACE = true - local TAB = false - - local indentation_settings = { - c = { style = SPACE, width = 4 }, - cmake = { style = SPACE, width = 2 }, - cpp = { style = SPACE, width = 4 }, - css = { style = SPACE, width = 2 }, - docbk = { style = SPACE, width = 2 }, - go = { style = TAB, width = 4 }, - haskell = { style = SPACE, width = 4 }, - html = { style = SPACE, width = 2 }, - javascript = { style = SPACE, width = 2 }, - json = { style = SPACE, width = 2 }, - leaf = { style = SPACE, width = 4 }, - lisp = { style = SPACE, width = 2 }, - lua = { style = SPACE, width = 3 }, - markdown = { style = SPACE, width = 4 }, - php = { style = SPACE, width = 2 }, - python = { style = SPACE, width = 4 }, - ruby = { style = SPACE, width = 2 }, - toml = { style = SPACE, width = 2 }, - typescript = { style = SPACE, width = 2 }, - vim = { style = SPACE, width = 4 }, - xml = { style = SPACE, width = 2 }, - yaml = { style = SPACE, width = 2 }, - } - - for ft, setting in pairs(indentation_settings) do - vimrc.autocmd('FileType', { - pattern = ft, - callback = function() - set_indentation(setting.style, setting.width) - end, - }) - end -end - - - -function M.hi(group, attributes) - vim.cmd(('highlight! %s %s'):format(group, attributes)) -end - - -function M.hi_link(from, to) - vim.cmd(('highlight! link %s %s'):format(from, to)) -end - - -M.map_callbacks = {} - - - --- Wrapper of |getchar()|. -function M.getchar() - local ch = vim.fn.getchar() - while ch == "\\" do - ch = vim.fn.getchar() - end - return type(ch) == 'number' and vim.fn.nr2char(ch) or ch -end - - --- Wrapper of |:echo| and |:echohl|. -function M.echo(message, hl) - if not hl then - hl = 'None' - end - vim.cmd('redraw') - vim.api.nvim_echo({{ message, hl }}, false, {}) -end - - --- Wrapper of |getchar()|. -function M.getchar_with_prompt(prompt) - M.echo(prompt, 'Question') - return M.getchar() -end - - --- Wrapper of |input()|. --- Only when it is used in a mapping, |inputsave()| and |inputstore()| are --- required. -function M.input(prompt) - vim.fn.inputsave() - local result = vim.fn.input(prompt) - vim.fn.inputrestore() - return result -end - - -function M.term(s) - return vim.api.nvim_replace_termcodes(s, true, true, true) -end - - - -function M.iabbrev(from, to) - vim.cmd(('inoreabbrev %s %s'):format(from, to)) -end - - -function M.cabbrev(from, to) - vim.cmd(('cnoreabbrev %s %s'):format(from, to)) -end - - -return M diff --git a/.config/nvim/lua/vimrc/init.lua b/.config/nvim/lua/vimrc/init.lua new file mode 100644 index 0000000..65d229e --- /dev/null +++ b/.config/nvim/lua/vimrc/init.lua @@ -0,0 +1,150 @@ +local M = {} + + + +local vimrc_augroup + +function M.create_augroup_for_vimrc() + vimrc_augroup = vim.api.nvim_create_augroup('Vimrc', {}) +end + +function M.autocmd(event, opts) + if not opts.group then + opts.group = vimrc_augroup + end + vim.api.nvim_create_autocmd(event, opts) +end + + + +function M.after_ftplugin(ft, callback) + local var_name = 'did_ftplugin_' .. ft .. '_after' + if vim.b[var_name] ~= nil then + return + end + + callback(conf) + + vim.b[var_name] = true +end + + + +local function set_indentation(style, width) + vim.bo.expandtab = style + vim.bo.tabstop = width + vim.bo.shiftwidth = width + vim.bo.softtabstop = width +end + + +function M.register_filetype_autocmds_for_indentation() + local SPACE = true + local TAB = false + + local indentation_settings = { + c = { style = SPACE, width = 4 }, + cmake = { style = SPACE, width = 2 }, + cpp = { style = SPACE, width = 4 }, + css = { style = SPACE, width = 2 }, + docbk = { style = SPACE, width = 2 }, + go = { style = TAB, width = 4 }, + haskell = { style = SPACE, width = 4 }, + html = { style = SPACE, width = 2 }, + javascript = { style = SPACE, width = 2 }, + json = { style = SPACE, width = 2 }, + leaf = { style = SPACE, width = 4 }, + lisp = { style = SPACE, width = 2 }, + lua = { style = SPACE, width = 3 }, + markdown = { style = SPACE, width = 4 }, + php = { style = SPACE, width = 2 }, + python = { style = SPACE, width = 4 }, + ruby = { style = SPACE, width = 2 }, + toml = { style = SPACE, width = 2 }, + typescript = { style = SPACE, width = 2 }, + vim = { style = SPACE, width = 4 }, + xml = { style = SPACE, width = 2 }, + yaml = { style = SPACE, width = 2 }, + } + + for ft, setting in pairs(indentation_settings) do + vimrc.autocmd('FileType', { + pattern = ft, + callback = function() + set_indentation(setting.style, setting.width) + end, + }) + end +end + + + +function M.hi(group, attributes) + vim.cmd(('highlight! %s %s'):format(group, attributes)) +end + + +function M.hi_link(from, to) + vim.cmd(('highlight! link %s %s'):format(from, to)) +end + + +M.map_callbacks = {} + + + +-- Wrapper of |getchar()|. +function M.getchar() + local ch = vim.fn.getchar() + while ch == "\\" do + ch = vim.fn.getchar() + end + return type(ch) == 'number' and vim.fn.nr2char(ch) or ch +end + + +-- Wrapper of |:echo| and |:echohl|. +function M.echo(message, hl) + if not hl then + hl = 'None' + end + vim.cmd('redraw') + vim.api.nvim_echo({{ message, hl }}, false, {}) +end + + +-- Wrapper of |getchar()|. +function M.getchar_with_prompt(prompt) + M.echo(prompt, 'Question') + return M.getchar() +end + + +-- Wrapper of |input()|. +-- Only when it is used in a mapping, |inputsave()| and |inputstore()| are +-- required. +function M.input(prompt) + vim.fn.inputsave() + local result = vim.fn.input(prompt) + vim.fn.inputrestore() + return result +end + + +function M.term(s) + return vim.api.nvim_replace_termcodes(s, true, true, true) +end + + + +function M.iabbrev(from, to) + vim.cmd(('inoreabbrev %s %s'):format(from, to)) +end + + +function M.cabbrev(from, to) + vim.cmd(('cnoreabbrev %s %s'):format(from, to)) +end + + +return M diff --git a/.config/nvim/lua/vimrc/my_env.lua b/.config/nvim/lua/vimrc/my_env.lua new file mode 100644 index 0000000..9860a04 --- /dev/null +++ b/.config/nvim/lua/vimrc/my_env.lua @@ -0,0 +1,41 @@ +local M = {} + +local V = vim +local E = V.env +local F = V.fn + +if F.has('unix') then + M.os = 'unix' +elseif F.has('mac') then + M.os = 'mac' +elseif F.has('wsl') then + M.os = 'wsl' +elseif F.has('win32') or F.has('win64') then + M.os = 'windows' +else + M.os = 'unknown' +end + +M.home = E.HOME or F.expand('~') + +M.config_home = E.XDG_CONFIG_HOME or E.HOME .. '/.config' + +M.config_dir = F.stdpath('config') +M.cache_dir = F.stdpath('cache') +M.data_dir = F.stdpath('data') + +M.backup_dir = M.data_dir .. '/backup' +M.yankround_dir = M.data_dir .. '/yankround' + +M.skk_dir = M.config_home .. '/skk' +M.scratch_dir = M.home .. '/scratch' + +function M.mkdir() + for k, v in pairs(M) do + if V.endswith(k, '_dir') and F.isdirectory(v) == 0 then + F.mkdir(v, 'p') + end + end +end + +return M diff --git a/.config/nvim/lua/vimrc/plugins.lua b/.config/nvim/lua/vimrc/plugins.lua new file mode 100644 index 0000000..2e1d9cc --- /dev/null +++ b/.config/nvim/lua/vimrc/plugins.lua @@ -0,0 +1,781 @@ +vim.cmd.packadd('packer.nvim') +local packer = require('packer') + +-- Plugins {{{1 +packer.startup(function(use) + -- Plugin management {{{2 + use { + 'wbthomason/packer.nvim', + opt = true, + } + -- Libraries {{{2 + -- telescope.nvim depends on it. + use { + 'nvim-lua/plenary.nvim', + } + -- Text editing {{{2 + -- IME {{{3 + -- SKK (Simple Kana to Kanji conversion program) for Vim. + use { + 'vim-skk/eskk.vim', + config = function() + local my_env = require('vimrc.my_env') + + vim.g['eskk#dictionary'] = { + path = my_env.skk_dir .. '/jisyo', + sorted = false, + encoding = 'utf-8', + } + + vim.g['eskk#large_dictionary'] = { + path = my_env.skk_dir .. '/jisyo.L', + sorted = true, + encoding = 'euc-jp', + } + + vim.g['eskk#backup_dictionary'] = vim.g['eskk#dictionary'].path .. '.bak' + + -- NOTE: + -- Boolean values are not accepted because eskk#utils#set_default() checks types. + vim.g['eskk#enable_completion'] = 0 + vim.g['eskk#egg_like_newline'] = 1 + + -- Change default markers because they are EAW (East Asian Width) characters. + vim.g['eskk#marker_henkan'] = '[!]' + vim.g['eskk#marker_okuri'] = '-' + vim.g['eskk#marker_henkan_select'] = '[#]' + vim.g['eskk#marker_jisyo_touroku'] = '[?]' + + vim.cmd([=[ + function! My_eskk_initialize_pre() + for [orgtable, mode] in [['rom_to_hira', 'hira'], ['rom_to_kata', 'kata']] + let t = eskk#table#new(orgtable . '*', orgtable) + call t.add_map('z ', ' ') + call t.add_map('0.', '0.') + call t.add_map('1.', '1.') + call t.add_map('2.', '2.') + call t.add_map('3.', '3.') + call t.add_map('4.', '4.') + call t.add_map('5.', '5.') + call t.add_map('6.', '6.') + call t.add_map('7.', '7.') + call t.add_map('8.', '8.') + call t.add_map('9.', '9.') + call t.add_map(':', ':') + call t.add_map('z:', ':') + " Workaround: 'zl' does not work as 'l' key leaves from SKK mode. + call t.add_map('zL', '→') + call eskk#register_mode_table(mode, t) + endfor + endfunction + + autocmd Vimrc User eskk-initialize-pre call My_eskk_initialize_pre() + + function! My_eskk_initialize_post() + " I don't use hankata mode for now. + EskkUnmap -type=mode:hira:toggle-hankata + EskkUnmap -type=mode:kata:toggle-hankata + + " I don't use abbrev mode for now. + EskkUnmap -type=mode:hira:to-abbrev + EskkUnmap -type=mode:kata:to-abbrev + + " I don't use ascii mode for now. + EskkUnmap -type=mode:hira:to-ascii + EskkUnmap -type=mode:kata:to-ascii + + " Instead, l key disable SKK input. + EskkMap -type=disable l + + " I type for new line. + EskkMap -type=kakutei + + map! jk (eskk:disable) + + " Custom highlight for henkan markers. + syntax match skkMarker '\[[!#?]\]' + hi link skkMarker Special + endfunction + + autocmd Vimrc User eskk-initialize-post call My_eskk_initialize_post() + ]=]) + end, + } + -- Operators {{{3 + -- Support for user-defined operators. + use { + 'kana/vim-operator-user', + } + -- Extract expression and make assingment statement. + use { + 'tek/vim-operator-assign', + } + -- Replace text without updating registers. + use { + 'kana/vim-operator-replace', + opt = true, + keys = { + {'n', '(operator-replace)'}, + {'o', '(operator-replace)'}, + {'x', '(operator-replace)'}, + }, + setup = function() + vim.keymap.set('n', '', '(operator-replace)') + vim.keymap.set('o', '', '(operator-replace)') + vim.keymap.set('x', '', '(operator-replace)') + end, + } + -- Super surround. + use { + 'machakann/vim-sandwich', + config = function() + vim.fn['operator#sandwich#set']('add', 'all', 'highlight', 2) + vim.fn['operator#sandwich#set']('delete', 'all', 'highlight', 0) + vim.fn['operator#sandwich#set']('replace', 'all', 'highlight', 2) + + do + local rs = vim.fn['sandwich#get_recipes']() + + rs[#rs+1] = { + buns = {'「', '」'}, + input = {'j[', 'j]'}, + } + rs[#rs+1] = { + buns = {'『', '』'}, + input = {'j{', 'j}'}, + } + rs[#rs+1] = { + buns = {'【', '】'}, + input = {'j(', 'j)'}, + } + + vim.g['sandwich#recipes'] = rs + end + end, + } + -- Non-operators {{{3 + -- Comment out. + use { + 'numToStr/Comment.nvim', + opt = true, + keys = { + {'n', 'm//'}, + {'n', 'm??'}, + {'n', 'm/'}, {'x', 'm/'}, + {'n', 'm?'}, {'x', 'm?'}, + {'n', 'm/O'}, + {'n', 'm/o'}, + {'n', 'm/A'}, + }, + config = function() + require('Comment').setup { + toggler = { + line = 'm//', + block = 'm??', + }, + opleader = { + line = 'm/', + block = 'm?', + }, + extra = { + above = 'm/O', + below = 'm/o', + eol = 'm/A', + }, + } + end, + } + -- Align text. + use { + 'junegunn/vim-easy-align', + opt = true, + cmd = {'EasyAlign'}, + keys = { + {'n', '(EasyAlign)'}, + {'x', '(EasyAlign)'}, + }, + setup = function() + vim.keymap.set('n', '=', '(EasyAlign)') + vim.keymap.set('x', '=', '(EasyAlign)') + end, + } + -- Text objects {{{2 + -- Support for user-defined text objects. + use { + 'kana/vim-textobj-user', + } + -- Text object for blockwise. + use { + 'osyo-manga/vim-textobj-blockwise', + } + -- Text object for comment. + use { + 'thinca/vim-textobj-comment', + } + -- Text object for indent. + use { + 'kana/vim-textobj-indent', + } + -- Text object for line. + use { + 'kana/vim-textobj-line', + } + -- Text object for parameter. + use { + 'sgur/vim-textobj-parameter', + } + -- Text object for space. + use { + 'saihoooooooo/vim-textobj-space', + opt = true, + keys = { + {'o', 'a'}, {'x', 'a'}, + {'o', 'i'}, {'x', 'i'}, + }, + setup = function() + vim.g.textobj_space_no_default_key_mappings = true + end, + config = function() + vim.keymap.set('o', 'a', '(textobj-space-a)') + vim.keymap.set('x', 'a', '(textobj-space-a)') + vim.keymap.set('o', 'i', '(textobj-space-i)') + vim.keymap.set('x', 'i', '(textobj-space-i)') + end, + } + -- Text object for syntax. + use { + 'kana/vim-textobj-syntax', + } + -- Text object for URL. + use { + 'mattn/vim-textobj-url', + } + -- Text object for words in words. + use { + 'h1mesuke/textobj-wiw', + opt = true, + keys = { + {'n', ''}, {'o', ''}, {'x', ''}, + {'n', 'g'}, {'o', 'g'}, {'x', 'g'}, + {'n', ''}, {'o', ''}, {'x', ''}, + {'n', 'g'}, {'o', 'g'}, {'x', 'g'}, + {'o', 'a'}, {'x', 'a'}, + {'o', 'i'}, {'x', 'i'}, + }, + setup = function() + vim.g.textobj_wiw_no_default_key_mappings = true + end, + config = function() + vim.keymap.set('n', '', '(textobj-wiw-n)') + vim.keymap.set('o', '', '(textobj-wiw-n)') + vim.keymap.set('x', '', '(textobj-wiw-n)') + vim.keymap.set('n', 'g', '(textobj-wiw-p)') + vim.keymap.set('o', 'g', '(textobj-wiw-p)') + vim.keymap.set('x', 'g', '(textobj-wiw-p)') + vim.keymap.set('n', '', '(textobj-wiw-N)') + vim.keymap.set('o', '', '(textobj-wiw-N)') + vim.keymap.set('x', '', '(textobj-wiw-N)') + vim.keymap.set('n', 'g', '(textobj-wiw-P)') + vim.keymap.set('o', 'g', '(textobj-wiw-P)') + vim.keymap.set('x', 'g', '(textobj-wiw-P)') + + vim.keymap.set('o', 'a', '(textobj-wiw-a)') + vim.keymap.set('x', 'a', '(textobj-wiw-a)') + vim.keymap.set('o', 'i', '(textobj-wiw-i)') + vim.keymap.set('x', 'i', '(textobj-wiw-i)') + end, + } + -- Search {{{2 + -- Extend * and #. + use { + 'haya14busa/vim-asterisk', + opt = true, + keys = { + {'n', '(asterisk-z*)'}, {'x', '(asterisk-z*)'}, + {'n', '(asterisk-gz*)'}, {'x', '(asterisk-gz*)'}, + }, + setup = function() + vim.keymap.set({'n', 'x'}, '*', '(asterisk-z*)') + vim.keymap.set({'n', 'x'}, 'g*', '(asterisk-gz*)') + end, + } + -- NOTE: it is a fork version of jremmen/vim-ripgrep + -- Integration with ripgrep, fast alternative of grep command. + use { + 'nsfisis/vim-ripgrep', + opt = true, + cmd = {'Rg', 'RG'}, + config = function() + -- Workaround: do not open quickfix window. + -- exe g:rg_window_location 'copen' + vim.g.rg_window_location = 'silent! echo' + vim.g.rg_jump_to_first = true + + vim.api.nvim_create_user_command( + 'RG', + 'Rg ', + { + bang = true, + bar = true, + nargs = '*', + complete = 'file', + } + ) + end, + } + -- Files {{{2 + -- Switch to related files. + use { + 'kana/vim-altr', + config = function() + -- C/C++ + vim.fn['altr#define']('%.c', '%.cpp', '%.cc', '%.h', '%.hh', '%.hpp') + -- Vim + vim.fn['altr#define']('autoload/%.vim', 'doc/%.txt', 'plugin/%.vim') + + -- Go to File Alternative + vim.keymap.set('n', 'gfa', '(altr-forward)') + end, + } + -- Full-featured filer. + use { + 'lambdalisue/fern.vim', + opt = true, + cmd = {'Fern'}, + config = function() + local vimrc = require('vimrc') + + vimrc.autocmd('FileType', { + pattern = {'fern'}, + callback = function() + vim.keymap.del('n', 't', { buffer = true }) + end, + }) + end, + } + -- Fern plugin: hijack Netrw. + use { + 'lambdalisue/fern-hijack.vim', + } + -- Appearance {{{2 + -- Show highlight. + use { + 'cocopon/colorswatch.vim', + opt = true, + cmd = {'ColorSwatchGenerate'}, + } + -- Makes folding text cool. + use { + 'LeafCage/foldCC.vim', + config = function() + vim.o.foldtext = 'FoldCCtext()' + vim.g.foldCCtext_head = 'repeat(">", v:foldlevel) . " "' + end, + } + -- Show indentation guide. + use { + 'lukas-reineke/indent-blankline.nvim', + config = function() + require("indent_blankline").setup { + char_blankline = ' ', + show_first_indent_level = false, + } + end, + } + -- Highlight matched parentheses. + use { + 'itchyny/vim-parenmatch', + } + -- Tree-sitter integration. + use { + 'nvim-treesitter/nvim-treesitter', + run = ':TSUpdate', + config = function() + require('nvim-treesitter.configs').setup { + ensure_installed = 'all', + sync_install = false, + highlight = { + enable = true, + additional_vim_regex_highlighting = false, + }, + --[[ + incremental_selection = { + enable = true, + keymaps = { + init_selection = 'TODO', + node_incremental = 'TODO', + scope_incremental = 'TODO', + node_decremental = 'TODO', + }, + }, + --]] + indent = { + enable = false, + }, + yati = { + enable = true, + }, + } + end, + } + -- Tree-sitter debugging. + use { + 'nvim-treesitter/playground', + } + -- Highlight specified words. + use { + 't9md/vim-quickhl', + config = function() + -- TODO: CUI + vim.g.quickhl_manual_colors = { + 'guifg=#101020 guibg=#8080c0 gui=bold', + 'guifg=#101020 guibg=#80c080 gui=bold', + 'guifg=#101020 guibg=#c08080 gui=bold', + 'guifg=#101020 guibg=#80c0c0 gui=bold', + 'guifg=#101020 guibg=#c0c080 gui=bold', + 'guifg=#101020 guibg=#a0a0ff gui=bold', + 'guifg=#101020 guibg=#a0ffa0 gui=bold', + 'guifg=#101020 guibg=#ffa0a0 gui=bold', + 'guifg=#101020 guibg=#a0ffff gui=bold', + 'guifg=#101020 guibg=#ffffa0 gui=bold', + } + + vim.keymap.set('n', '"', '(quickhl-manual-this)') + vim.keymap.set('x', '"', '(quickhl-manual-this)') + vim.keymap.set('n', '', ':nohlsearch QuickhlManualReset', { silent=true }) + end, + } + -- Yet another tree-sitter indentation. + -- TODO: uninstall it once the official nvim-treesitter provides sane indentation. + use { + 'yioneko/nvim-yati', + } + -- Filetypes {{{2 + -- Faster replacement for bundled filetype.vim + use { + 'nathom/filetype.nvim', + config = function() + require('filetype').setup({ + overrides = { + -- My settings here + }, + }) + end, + } + -- C/C++ + use { + 'rhysd/vim-clang-format', + config = function() + local vimrc = require('vimrc') + + vim.g['clang_format#auto_format'] = true + + vimrc.autocmd('FileType', { + pattern = {'javascript', 'typescript'}, + command = 'ClangFormatAutoDisable', + }) + end, + } + -- HTML/CSS + use { + 'mattn/emmet-vim', + opt = true, + cmd = {'EmmetInstall'}, + setup = function() + local vimrc = require('vimrc') + + vim.g.user_emmet_install_global = false + vimrc.autocmd('FileType', { + pattern = {'html', 'css'}, + command = 'EmmetInstall', + }) + end, + } + -- Rust + use { + 'rust-lang/rust.vim', + config = function() + vim.g.rustfmt_autosave = true + end, + } + -- QoL {{{2 + -- Capture the output of a command. + use { + 'tyru/capture.vim', + opt = true, + cmd = {'Capture'}, + } + -- Write git commit message. + use { + 'rhysd/committia.vim', + config = function() + vim.g.committia_hooks = { + edit_open = function(_info) + vim.wo.spell = true + end, + } + end, + } + -- Neovim clone of EasyMotion + use { + 'phaazon/hop.nvim', + branch = 'v2', -- Hop.nvim's README recommends this. + opt = true, + keys = { + {'n', '(hop-f)'}, {'o', '(hop-f)'}, + {'x', '(hop-f)'}, {'n', '(hop-F)'}, + {'o', '(hop-F)'}, {'x', '(hop-F)'}, + {'o', '(hop-t)'}, {'x', '(hop-t)'}, + {'o', '(hop-T)'}, {'x', '(hop-T)'}, + {'n', '(hop-s2)'}, {'o', '(hop-s2)'}, {'x', '(hop-s2)'}, + {'n', '(hop-n)'}, {'o', '(hop-n)'}, {'x', '(hop-n)'}, + {'n', '(hop-N)'}, {'o', '(hop-N)'}, {'x', '(hop-N)'}, + {'n', '(hop-j)'}, {'o', '(hop-j)'}, {'x', '(hop-j)'}, + {'n', '(hop-k)'}, {'o', '(hop-k)'}, {'x', '(hop-k)'}, + }, + config = function() + require('hop').setup { + keys = 'asdfghweryuiocvbnmjkl;', + } + + -- Emulate `g:EasyMotion_startofline = 0` in hop.nvim. + local function hop_jk(opts) + local hop = require('hop') + local jump_target = require('hop.jump_target') + + local column = vim.fn.col('.') + local match + if column == 1 then + match = function(_) + return 0, 1, false + end + else + local pat = vim.regex('\\%' .. column .. 'c') + match = function(s) + return pat:match_str(s) + end + end + setmetatable(opts, { __index = hop.opts }) + hop.hint_with( + jump_target.jump_targets_by_scanning_lines({ + oneshot = true, + match = match, + }), + opts + ) + end + + local hop = require('hop') + local HintDirection = require('hop.hint').HintDirection + local AFTER_CURSOR = HintDirection.AFTER_CURSOR + local BEFORE_CURSOR = HintDirection.BEFORE_CURSOR + + vim.keymap.set('', '(hop-f)', function() hop.hint_char1({ direction = AFTER_CURSOR, current_line_only = true }) end, { silent = true }) + vim.keymap.set('', '(hop-F)', function() hop.hint_char1({ direction = BEFORE_CURSOR, current_line_only = true }) end, { silent = true }) + vim.keymap.set('', '(hop-t)', function() hop.hint_char1({ direction = AFTER_CURSOR, current_line_only = true, hint_offset = -1 }) end, { silent = true }) + vim.keymap.set('', '(hop-T)', function() hop.hint_char1({ direction = BEFORE_CURSOR, current_line_only = true, hint_offset = 1 }) end, { silent = true }) + + vim.keymap.set('', '(hop-s2)', function() hop.hint_char2() end, { silent = true }) + vim.keymap.set('', '(hop-n)', function() hop.hint_patterns({ direction = AFTER_CURSOR }, vim.fn.getreg('/')) end, { silent = true }) + vim.keymap.set('', '(hop-N)', function() hop.hint_patterns({ direction = BEFORE_CURSOR }, vim.fn.getreg('/')) end, { silent = true }) + vim.keymap.set('', '(hop-j)', function() hop_jk({ direction = AFTER_CURSOR }) end, { silent = true }) + vim.keymap.set('', '(hop-k)', function() hop_jk({ direction = BEFORE_CURSOR }) end, { silent = true }) + end, + setup = function() + vim.keymap.set('n', 'f', '(hop-f)') + vim.keymap.set('o', 'f', '(hop-f)') + vim.keymap.set('x', 'f', '(hop-f)') + vim.keymap.set('n', 'F', '(hop-F)') + vim.keymap.set('o', 'F', '(hop-F)') + vim.keymap.set('x', 'F', '(hop-F)') + vim.keymap.set('o', 't', '(hop-t)') + vim.keymap.set('x', 't', '(hop-t)') + vim.keymap.set('o', 'T', '(hop-T)') + vim.keymap.set('x', 'T', '(hop-T)') + + -- Note: Don't use the following key sequences! They are used by 'vim-sandwich'. + -- * sa + -- * sd + -- * sr + vim.keymap.set('n', 'ss', '(hop-s2)') + vim.keymap.set('o', 'ss', '(hop-s2)') + vim.keymap.set('x', 'ss', '(hop-s2)') + vim.keymap.set('n', 'sn', '(hop-n)') + vim.keymap.set('o', 'sn', '(hop-n)') + vim.keymap.set('x', 'sn', '(hop-n)') + vim.keymap.set('n', 'sN', '(hop-N)') + vim.keymap.set('o', 'sN', '(hop-N)') + vim.keymap.set('x', 'sN', '(hop-N)') + vim.keymap.set('n', 'sj', '(hop-j)') + vim.keymap.set('o', 'sj', '(hop-j)') + vim.keymap.set('x', 'sj', '(hop-j)') + vim.keymap.set('n', 'sk', '(hop-k)') + vim.keymap.set('o', 'sk', '(hop-k)') + vim.keymap.set('x', 'sk', '(hop-k)') + end, + } + -- Integration with EditorConfig (https://editorconfig.org) + use { + 'editorconfig/editorconfig-vim', + } + -- Extend J. + use { + 'osyo-manga/vim-jplus', + config = function() + vim.g['jplus#input_config'] = { + __DEFAULT__ = { delimiter_format = ' %d ' }, + __EMPTY__ = { delimiter_format = '' }, + [' '] = { delimiter_format = ' ' }, + [','] = { delimiter_format = '%d ' }, + [':'] = { delimiter_format = '%d ' }, + [';'] = { delimiter_format = '%d ' }, + l = { delimiter_format = '' }, + L = { delimiter_format = '' }, + } + + vim.keymap.set('n', 'J', '(jplus-getchar)') + vim.keymap.set('x', 'J', '(jplus-getchar)') + vim.keymap.set('n', 'gJ', '(jplus-input)') + vim.keymap.set('x', 'gJ', '(jplus-input)') + end, + } + -- Improve behaviors of I, A and gI in Blockwise-Visual mode. + use { + 'kana/vim-niceblock', + config = function() + vim.keymap.set('x', 'I', '(niceblock-I)') + vim.keymap.set('x', 'gI', '(niceblock-gI)') + vim.keymap.set('x', 'A', '(niceblock-A)') + end, + } + -- Edit QuickFix freely. + use { + 'itchyny/vim-qfedit', + } + -- Edit QuickFix and reflect to original buffers. + use { + 'thinca/vim-qfreplace', + opt = true, + cmd = {'Qfreplace'}, + config = function() + vim.keymap.set('n', 'br', ':Qfreplace SmartOpen', { silent=true }) + end, + } + -- Run anything. + use { + 'thinca/vim-quickrun', + config = function() + vim.g.quickrun_config = { + cpp = { + cmdopt = '--std=c++17 -Wall -Wextra', + }, + d = { + exec = 'dub run', + }, + haskell = { + exec = {'stack build', 'stack exec %{matchstr(globpath(".,..,../..,../../..", "*.cabal"), "\\w\\+\\ze\\.cabal")}'}, + }, + python = { + command = 'python3', + }, + } + + vim.keymap.set('n', 'BB', '(quickrun)') + vim.keymap.set('x', 'BB', '(quickrun)') + end, + } + -- Extend dot-repeat. + use { + 'tpope/vim-repeat', + config = function() + vim.keymap.set('n', 'U', '(RepeatRedo)') + -- Autoload vim-repeat immediately in order to make (RepeatRedo) available. + -- repeat#setreg() does nothing here. + vim.fn['repeat#setreg']('', '') + end, + } + -- Introduce user-defined mode. + use { + 'kana/vim-submode', + config = function() + -- Global settings {{{3 + vim.g.submode_always_show_submode = true + vim.g.submode_keyseqs_to_leave = {'', ''} + vim.g.submode_keep_leaving_key = true + + -- yankround {{{3 + vim.fn['submode#enter_with']('YankRound', 'nv', 'rs', 'gp', '(yankround-p)') + vim.fn['submode#enter_with']('YankRound', 'nv', 'rs', 'gP', '(yankround-P)') + vim.fn['submode#map']('YankRound', 'nv', 'rs', 'p', '(yankround-prev)') + vim.fn['submode#map']('YankRound', 'nv', 'rs', 'P', '(yankround-next)') + + -- swap {{{3 + vim.fn['submode#enter_with']('Swap', 'n', 'rs', 'g>', '(swap-next)') + vim.fn['submode#map']('Swap', 'n', 'rs', '<', '(swap-prev)') + vim.fn['submode#enter_with']('Swap', 'n', 'rs', 'g<', '(swap-prev)') + vim.fn['submode#map']('Swap', 'n', 'rs', '>', '(swap-next)') + + -- TODO + if packer_plugins['vim-swap'] and not packer_plugins['vim-swap'].loaded then + vim.cmd.packadd('vim-swap') + end + + -- Resizing a window (height) {{{3 + vim.fn['submode#enter_with']('WinResizeH', 'n', 's', 'trh') + vim.fn['submode#enter_with']('WinResizeH', 'n', 's', 'trh') + vim.fn['submode#map']('WinResizeH', 'n', 's', '+', '+') + vim.fn['submode#map']('WinResizeH', 'n', 's', '-', '-') + + -- Resizing a window (width) {{{3 + vim.fn['submode#enter_with']('WinResizeW', 'n', 's', 'trw') + vim.fn['submode#enter_with']('WinResizeW', 'n', 's', 'trw') + vim.fn['submode#map']('WinResizeW', 'n', 's', '+', '>') + vim.fn['submode#map']('WinResizeW', 'n', 's', '-', '') + + -- Super undo/redo {{{3 + vim.fn['submode#enter_with']('Undo/Redo', 'n', 's', 'gu', 'g-') + vim.fn['submode#map']('Undo/Redo', 'n', 's', 'u', 'g-') + vim.fn['submode#enter_with']('Undo/Redo', 'n', 's', 'gU', 'g+') + vim.fn['submode#map']('Undo/Redo', 'n', 's', 'U', 'g+') + -- }}} + end, + } + -- Swap arguments. + use { + 'machakann/vim-swap', + opt = true, + setup = function() + vim.g.swap_no_default_key_mappings = true + end, + } + -- Fuzzy finder. + use { + 'nvim-telescope/telescope.nvim', + } + -- Adjust window size. + use { + 'rhysd/vim-window-adjuster', + config = function() + vim.keymap.set('n', 'tRw', 'AdjustScreenWidth') + vim.keymap.set('n', 'tRh', 'AdjustScreenHeight') + vim.keymap.set('n', 'tRr', ':AdjustScreenWidth AdjustScreenHeight', { silent=true }) + end, + } + -- Remember yank history and paste them. + use { + 'LeafCage/yankround.vim', + config = function() + local my_env = require('vimrc.my_env') + + vim.g.yankround_dir = my_env.yankround_dir + vim.g.yankround_use_region_hl = true + end, + } + -- }}} +end) +-- }}} + +return { + compile = packer.compile, + sync = packer.sync, +} -- cgit v1.2.3-70-g09d2