Skip to content

Instantly share code, notes, and snippets.

@sunjon
Created November 16, 2021 19:01
Show Gist options
  • Save sunjon/b29db05b9b3e568a4f7019e83c906ddc to your computer and use it in GitHub Desktop.
Save sunjon/b29db05b9b3e568a4f7019e83c906ddc to your computer and use it in GitHub Desktop.
local api = vim.api
local fn = vim.fn
local ddc = {
enable = fn["ddc#enable"],
patch_global = fn["ddc#custom#patch_global"],
patch_filetype = fn["ddc#custom#patch_filetype"],
manual_complete = fn["ddc#map#manual_complete"],
get_complete_info = fn["ddc#complete_info"],
}
local delimitmate = {
should_jump = fn["delimitMate#ShouldJump"],
}
local USER_COMPLETION_NEXT = "<TAB>"
local USER_COMPLETION_PREV = "<S-TAB>"
local USER_COMPLETION_ACCEPT = "<CR>"
local escape_termcodes = function(raw)
return api.nvim_replace_termcodes(raw, true, false, true)
end
local KEYS = {
accept_completion = escape_termcodes "<C-y>",
cancel_completion = escape_termcodes "<C-e>",
completion_next = escape_termcodes "<C-n>",
completion_prev = escape_termcodes "<C-p>",
normal_cr = escape_termcodes "<CR>",
normal_tab = escape_termcodes "<Tab>",
normal_bs = escape_termcodes "<BS>",
delimitmate_jump_any = escape_termcodes "<C-R>=delimitMate#JumpAny()<CR>",
delimitmate_cr = escape_termcodes "<Plug>delimitMateCR",
delimitmate_bs = escape_termcodes "<Plug>delimitMateBS",
}
local normal_tab_after = {
[" "] = true,
["{"] = true,
["}"] = true,
["("] = true,
[")"] = true,
["["] = true,
["]"] = true,
[","] = true,
["="] = true,
}
local function should_insert_normal_tab()
local col = fn.col "."
if col == 1 then
return true
end
local prev_char = fn.getline("."):sub(col - 1, col - 1)
return normal_tab_after[prev_char] or false
end
local function set_insertmode_keymap(key, action)
local map_opts = { silent = true, nowait = true, expr = true }
api.nvim_set_keymap("i", key, action, map_opts)
end
--
local M = {}
M.setup = function()
_G.vimrc = _G.vimrc or {}
_G.vimrc.completion = require "config.plugin.ddc"
ddc.patch_global {
completionMode = "manual",
backspaceCompletion = true,
overwriteCompleteopt = false,
sources = { "nvim-lsp", "omni", "file" },
sourceOptions = {
_ = {
-- converters = { "converter_remove_overlap" },
matchers = { "matcher_head" },
sorters = { "sorter_rank" },
},
file = {
mark = "F",
isVolatile = true,
forceCompletionPattern = "\\S/\\S*",
},
dictionary = {
sourceParams = {
dictPaths = { "/usr/share/words" },
smartCase = true,
},
},
},
}
ddc.patch_filetype("wiki", {
sources = { "omni", "dictionary", "file" },
})
ddc.patch_filetype("txt", {
sources = { "dictionary" },
})
vim.cmd [[
augroup vimrc_completion
autocmd!
autocmd CompleteDonePre * lua _G.vimrc.completion.add_function_braces(vim.api.nvim_get_vvar("completed_item"))
augroup END
]]
set_insertmode_keymap(USER_COMPLETION_NEXT, "v:lua.vimrc.completion.tab_handler(1)")
set_insertmode_keymap(USER_COMPLETION_PREV, "v:lua.vimrc.completion.tab_handler(-1)")
set_insertmode_keymap(USER_COMPLETION_ACCEPT, "v:lua.vimrc.completion.cr_handler()")
set_insertmode_keymap("<Backspace>", "v:lua.vimrc.completion.bs_handler()")
ddc.enable()
end
M.tab_handler = function(direction)
direction = direction or 1
local complete_info = ddc.get_complete_info()
if (complete_info.pum_visible == 1) then
return (direction == 1 and KEYS.completion_next or KEYS.completion_prev)
end
if (direction == -1) and (delimitmate.should_jump() == 1) then
return KEYS.delimitmate_jump_any
end
if (direction == 1) and should_insert_normal_tab() then
return KEYS.normal_tab
end
--
if (direction == 1) then
return ddc.manual_complete()
end
end
M.cr_handler = function()
local complete_info = ddc.get_complete_info()
if (complete_info.pum_visible == 0) then
return KEYS.delimitmate_cr
else
if (complete_info.selected == -1) then
return KEYS.cancel_completion
else
return KEYS.accept_completion
end
end
end
M.bs_handler = function()
local complete_info = ddc.get_complete_info()
if (complete_info.pum_visible == 0) then
return KEYS.delimitmate_bs
else
return KEYS.cancel_completion..KEYS.normal_bs..KEYS.normal_tab
end
end
M.add_function_braces = function(completed_item)
if (completed_item.kind == "Function") then
local has_params = completed_item.abbr:match("%(.+%)")
local brackets = (has_params) and "(" or "()"
api.nvim_feedkeys(brackets, "i", true)
end
end
return M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment