1

Regenerate nvim config

This commit is contained in:
2024-06-02 03:29:20 +02:00
parent 75eea0c030
commit ef2e28883d
5576 changed files with 604886 additions and 503 deletions

View File

@ -0,0 +1,6 @@
local telescope = require("telescope")
local get_exports = require("yanky.telescope.yank_history").get_exports
return telescope.register_extension({
exports = get_exports(),
})

View File

@ -0,0 +1,404 @@
local utils = require("yanky.utils")
local highlight = require("yanky.highlight")
local system_clipboard = require("yanky.system_clipboard")
local preserve_cursor = require("yanky.preserve_cursor")
local picker = require("yanky.picker")
local textobj = require("yanky.textobj")
local yanky = {}
yanky.ring = {
state = nil,
is_cycling = false,
callback = nil,
}
yanky.direction = {
FORWARD = 1,
BACKWARD = -1,
}
yanky.type = {
PUT_BEFORE = "P",
PUT_AFTER = "p",
GPUT_BEFORE = "gP",
GPUT_AFTER = "gp",
PUT_INDENT_AFTER = "]p",
PUT_INDENT_BEFORE = "[p",
}
function yanky.setup(options)
yanky.config = require("yanky.config")
yanky.config.setup(options)
yanky.history = require("yanky.history")
yanky.history.setup()
system_clipboard.setup()
highlight.setup()
preserve_cursor.setup()
picker.setup()
local yanky_augroup = vim.api.nvim_create_augroup("Yanky", { clear = true })
vim.api.nvim_create_autocmd("TextYankPost", {
group = yanky_augroup,
pattern = "*",
callback = function(_)
yanky.on_yank()
end,
})
if vim.v.vim_did_enter == 1 then
yanky.init_history()
else
vim.api.nvim_create_autocmd("VimEnter", {
group = yanky_augroup,
pattern = "*",
callback = yanky.init_history,
})
end
vim.api.nvim_create_user_command("YankyClearHistory", yanky.clear_history, {})
end
function yanky.init_history()
yanky.history.push(utils.get_register_info(utils.get_default_register()))
yanky.history.sync_with_numbered_registers()
end
local function do_put(state, _)
if state.is_visual then
vim.cmd([[execute "normal! \<esc>"]])
end
local ok, val = pcall(
vim.cmd,
string.format(
'silent normal! %s"%s%s%s',
state.is_visual and "gv" or "",
state.register ~= "=" and state.register or "=" .. vim.api.nvim_replace_termcodes("<CR>", true, false, true),
state.count,
state.type
)
)
if not ok then
vim.notify(val, vim.log.levels.WARN)
return
end
highlight.highlight_put(state)
end
function yanky.put(type, is_visual, callback)
if not vim.tbl_contains(vim.tbl_values(yanky.type), type) then
vim.notify("Invalid type " .. type, vim.log.levels.ERROR)
return
end
yanky.ring.state = nil
yanky.ring.is_cycling = false
yanky.ring.callback = callback or do_put
-- On Yank event is not triggered when put from expression register,
-- To allows cycling, we must store value here
if vim.v.register == "=" then
local entry = utils.get_register_info("=")
entry.filetype = vim.bo.filetype
yanky.history.push(entry)
end
yanky.init_ring(type, vim.v.register, vim.v.count, is_visual, yanky.ring.callback)
end
function yanky.clear_ring()
if yanky.can_cycle() and nil ~= yanky.ring.state.augroup then
vim.api.nvim_clear_autocmds({ group = yanky.ring.state.augroup })
end
yanky.ring.state = nil
yanky.ring.is_cycling = false
end
function yanky.attach_cancel()
if yanky.config.options.ring.cancel_event == "move" then
yanky.ring.state.augroup = vim.api.nvim_create_augroup("YankyRingClear", { clear = true })
vim.schedule(function()
vim.api.nvim_create_autocmd("CursorMoved", {
group = yanky.ring.state.augroup,
buffer = 0,
callback = yanky.clear_ring,
})
end)
else
vim.api.nvim_buf_attach(0, false, {
on_lines = function(_)
yanky.clear_ring()
return true
end,
})
end
end
function yanky.init_ring(type, register, count, is_visual, callback)
register = (register ~= '"' and register ~= "_") and register or utils.get_default_register()
local reg_content = vim.fn.getreg(register)
if nil == reg_content or "" == reg_content then
vim.notify(string.format('Register "%s" is empty', register), vim.log.levels.WARN)
return
end
local new_state = {
type = type,
register = register,
count = count > 0 and count or 1,
is_visual = is_visual,
use_repeat = callback == nil,
}
if nil ~= callback then
callback(new_state, do_put)
end
yanky.ring.state = new_state
yanky.ring.is_cycling = false
yanky.attach_cancel()
if yanky.config.options.textobj.enabled then
textobj.save_put()
end
end
function yanky.can_cycle()
return nil ~= yanky.ring.state
end
function yanky.cycle(direction)
if not yanky.can_cycle() then
vim.notify("Your last action was not put, ignoring cycle", vim.log.levels.INFO)
return
end
direction = direction or yanky.direction.FORWARD
if not vim.tbl_contains(vim.tbl_values(yanky.direction), direction) then
vim.notify("Invalid direction for cycle", vim.log.levels.ERROR)
return
end
if nil ~= yanky.ring.state.augroup then
vim.api.nvim_clear_autocmds({ group = yanky.ring.state.augroup })
end
if not yanky.ring.is_cycling then
yanky.history.reset()
local reg = utils.get_register_info(yanky.ring.state.register)
local first = yanky.history.first()
if nil ~= first and reg.regcontents == first.regcontents and reg.regtype == first.regtype then
yanky.history.skip()
end
end
local new_state = yanky.ring.state
local next_content
if direction == yanky.direction.FORWARD then
next_content = yanky.history.next()
if nil == next_content then
vim.notify("Reached oldest item", vim.log.levels.INFO)
yanky.attach_cancel()
return
end
else
next_content = yanky.history.previous()
if nil == next_content then
vim.notify("Reached first item", vim.log.levels.INFO)
yanky.attach_cancel()
return
end
end
yanky.ring.state.register = yanky.ring.state.register ~= "=" and yanky.ring.state.register
or utils.get_default_register()
utils.use_temporary_register(yanky.ring.state.register, next_content, function()
if new_state.use_repeat then
local ok, val = pcall(vim.cmd, "silent normal! u.")
if not ok then
vim.notify(val, vim.log.levels.WARN)
yanky.attach_cancel()
return
end
highlight.highlight_put(new_state)
else
local ok, val = pcall(vim.cmd, "silent normal! u")
if not ok then
vim.notify(val, vim.log.levels.WARN)
yanky.attach_cancel()
return
end
yanky.ring.callback(new_state, do_put)
end
end)
if yanky.config.options.ring.update_register_on_cycle then
vim.fn.setreg(new_state.register, next_content.regcontents, next_content.regtype)
end
yanky.ring.is_cycling = true
yanky.ring.state = new_state
yanky.attach_cancel()
end
function yanky.on_yank()
if vim.tbl_contains(yanky.config.options.ring.ignore_registers, vim.v.register) then
return
end
-- Only historize first delete in visual mode
if vim.v.event.visual and vim.v.event.operator == "d" and yanky.ring.is_cycling then
return
end
local entry = utils.get_register_info(vim.v.event.regname)
entry.filetype = vim.bo.filetype
yanky.history.push(entry)
preserve_cursor.on_yank()
end
function yanky.yank(options)
options = options or {}
preserve_cursor.yank()
return string.format("%sy", options.register and '"' .. options.register or "")
end
function yanky.clear_history()
yanky.history.clear()
end
function yanky.register_plugs()
local yanky_wrappers = require("yanky.wrappers")
vim.keymap.set("n", "<Plug>(YankyCycleForward)", function()
yanky.cycle(1)
end, { silent = true })
vim.keymap.set("n", "<Plug>(YankyCycleBackward)", function()
yanky.cycle(-1)
end, { silent = true })
vim.keymap.set("n", "<Plug>(YankyPreviousEntry)", function()
yanky.cycle(1)
end, { silent = true })
vim.keymap.set("n", "<Plug>(YankyNextEntry)", function()
yanky.cycle(-1)
end, { silent = true })
vim.keymap.set({ "n", "x" }, "<Plug>(YankyYank)", yanky.yank, { silent = true, expr = true })
for type, type_text in pairs({
p = "PutAfter",
P = "PutBefore",
gp = "GPutAfter",
gP = "GPutBefore",
["]p"] = "PutIndentAfter",
["[p"] = "PutIndentBefore",
}) do
vim.keymap.set("n", string.format("<Plug>(Yanky%s)", type_text), function()
yanky.put(type, false)
end, { silent = true })
vim.keymap.set("x", string.format("<Plug>(Yanky%s)", type_text), function()
yanky.put(type, true)
end, { silent = true })
vim.keymap.set("n", string.format("<Plug>(Yanky%sJoined)", type_text), function()
yanky.put(type, false, yanky_wrappers.trim_and_join_lines())
end, { silent = true })
vim.keymap.set("x", string.format("<Plug>(Yanky%sJoined)", type_text), function()
yanky.put(type, true, yanky_wrappers.trim_and_join_lines())
end, { silent = true })
vim.keymap.set("n", string.format("<Plug>(Yanky%sLinewise)", type_text), function()
yanky.put(type, false, yanky_wrappers.linewise())
end, { silent = true })
vim.keymap.set("x", string.format("<Plug>(Yanky%sLinewise)", type_text), function()
yanky.put(type, true, yanky_wrappers.linewise())
end, { silent = true })
vim.keymap.set("n", string.format("<Plug>(Yanky%sLinewiseJoined)", type_text), function()
yanky.put(type, false, yanky_wrappers.linewise(yanky_wrappers.trim_and_join_lines()))
end, { silent = true })
vim.keymap.set("x", string.format("<Plug>(Yanky%sLinewiseJoined)", type_text), function()
yanky.put(type, true, yanky_wrappers.linewise(yanky_wrappers.trim_and_join_lines()))
end, { silent = true })
vim.keymap.set("n", string.format("<Plug>(Yanky%sCharwise)", type_text), function()
yanky.put(type, false, yanky_wrappers.charwise())
end, { silent = true })
vim.keymap.set("x", string.format("<Plug>(Yanky%sCharwise)", type_text), function()
yanky.put(type, true, yanky_wrappers.charwise())
end, { silent = true })
vim.keymap.set("n", string.format("<Plug>(Yanky%sCharwiseJoined)", type_text), function()
yanky.put(type, false, yanky_wrappers.charwise(yanky_wrappers.trim_and_join_lines()))
end, { silent = true })
vim.keymap.set("x", string.format("<Plug>(Yanky%sCharwiseJoined)", type_text), function()
yanky.put(type, true, yanky_wrappers.charwise(yanky_wrappers.trim_and_join_lines()))
end, { silent = true })
vim.keymap.set("n", string.format("<Plug>(Yanky%sBlockwise)", type_text), function()
yanky.put(type, false, yanky_wrappers.blockwise())
end, { silent = true })
vim.keymap.set("x", string.format("<Plug>(Yanky%sBlockwise)", type_text), function()
yanky.put(type, true, yanky_wrappers.blockwise())
end, { silent = true })
vim.keymap.set("n", string.format("<Plug>(Yanky%sBlockwiseJoined)", type_text), function()
yanky.put(type, false, yanky_wrappers.blockwise(yanky_wrappers.trim_and_join_lines()))
end, { silent = true })
vim.keymap.set("x", string.format("<Plug>(Yanky%sBlockwiseJoined)", type_text), function()
yanky.put(type, true, yanky_wrappers.blockwise(yanky_wrappers.trim_and_join_lines()))
end, { silent = true })
for change, change_text in pairs({ [">>"] = "ShiftRight", ["<<"] = "ShiftLeft", ["=="] = "Filter" }) do
vim.keymap.set("n", string.format("<Plug>(Yanky%s%s)", type_text, change_text), function()
yanky.put(type, false, yanky_wrappers.linewise(yanky_wrappers.change(change)))
end, { silent = true })
vim.keymap.set("x", string.format("<Plug>(Yanky%s%s)", type_text, change_text), function()
yanky.put(type, true, yanky_wrappers.linewise(yanky_wrappers.change(change)))
end, { silent = true })
vim.keymap.set("n", string.format("<Plug>(Yanky%s%sJoined)", type_text, change_text), function()
yanky.put(
type,
false,
yanky_wrappers.linewise(yanky_wrappers.trim_and_join_lines(yanky_wrappers.change(change)))
)
end, { silent = true })
vim.keymap.set("x", string.format("<Plug>(Yanky%s%sJoined)", type_text, change_text), function()
yanky.put(
type,
true,
yanky_wrappers.linewise(yanky_wrappers.trim_and_join_lines(yanky_wrappers.change(change)))
)
end, { silent = true })
end
end
end
return yanky

View File

@ -0,0 +1,45 @@
local config = {}
config.options = {}
local default_values = {
ring = {
history_length = 100,
storage = "shada",
storage_path = vim.fn.stdpath("data") .. "/databases/yanky.db",
sync_with_numbered_registers = true,
ignore_registers = { "_" },
cancel_event = "update",
update_register_on_cycle = false,
},
system_clipboard = {
sync_with_ring = true,
clipboard_register = nil,
},
highlight = {
on_put = true,
on_yank = true,
timer = 500,
},
preserve_cursor_position = {
enabled = true,
},
picker = {
select = {
action = nil,
},
telescope = {
use_default_mappings = true,
mappings = nil,
},
},
textobj = {
enabled = false,
},
}
function config.setup(options)
config.options = vim.tbl_deep_extend("force", default_values, options or {})
end
return config

View File

@ -0,0 +1,64 @@
local highlight = {}
function highlight.setup()
highlight.config = require("yanky.config").options.highlight
if highlight.config.on_put then
highlight.hl_put = vim.api.nvim_create_namespace("yanky.put")
highlight.timer = vim.loop.new_timer()
vim.api.nvim_set_hl(0, "YankyPut", { link = "Search", default = true })
end
if highlight.config.on_yank then
vim.api.nvim_create_autocmd("TextYankPost", {
pattern = "*",
callback = function(_)
pcall(vim.highlight.on_yank, { higroup = "YankyYanked", timeout = highlight.config.timer })
end,
})
vim.api.nvim_set_hl(0, "YankyYanked", { link = "Search", default = true })
end
end
local function get_region()
local start = vim.api.nvim_buf_get_mark(0, "[")
local finish = vim.api.nvim_buf_get_mark(0, "]")
return {
start_row = start[1] - 1,
start_col = start[2],
end_row = finish[1] - 1,
end_col = finish[2],
}
end
function highlight.highlight_put(state)
if not highlight.config.on_put then
return
end
highlight.timer:stop()
vim.api.nvim_buf_clear_namespace(0, highlight.hl_put, 0, -1)
local region = get_region()
vim.highlight.range(
0,
highlight.hl_put,
"YankyPut",
{ region.start_row, region.start_col },
{ region.end_row, region.end_col },
{ regtype = vim.fn.getregtype(state.register), inclusive = true }
)
highlight.timer:start(
highlight.config.timer,
0,
vim.schedule_wrap(function()
vim.api.nvim_buf_clear_namespace(0, highlight.hl_put, 0, -1)
end)
)
end
return highlight

View File

@ -0,0 +1,85 @@
local history = {
storage = nil,
position = 1,
config = nil,
}
function history.setup()
history.config = require("yanky.config").options.ring
history.storage = require("yanky.storage." .. history.config.storage)
if false == history.storage.setup() then
history.storage = require("yanky.storage.memory")
end
end
function history.push(item)
local prev = history.storage.get(1)
if prev ~= nil and prev.regcontents == item.regcontents and prev.regtype == item.regtype then
return
end
history.storage.push(item)
history.sync_with_numbered_registers()
end
function history.sync_with_numbered_registers()
if history.config.sync_with_numbered_registers then
for i = 1, math.min(history.storage.length(), 9) do
local reg = history.storage.get(i)
vim.fn.setreg(i, reg.regcontents, reg.regtype)
end
end
end
function history.first()
if history.storage.length() <= 0 then
return nil
end
return history.storage.get(1)
end
function history.skip()
history.position = history.position + 1
end
function history.next()
local new_position = history.position + 1
if new_position > history.storage.length() then
return nil
end
history.position = new_position
return history.storage.get(history.position)
end
function history.previous()
if history.position == 1 then
return nil
end
history.position = history.position - 1
return history.storage.get(history.position)
end
function history.reset()
history.position = 0
end
function history.all()
return history.storage.all()
end
function history.clear()
history.storage.clear()
history.position = 1
end
function history.delete(index)
history.storage.delete(index)
end
return history

View File

@ -0,0 +1,13 @@
local yanky = require("yanky")
local integration = {}
function integration.substitute()
return function(event)
local is_visual = require("substitute.utils").is_visual(event.vmode)
yanky.init_ring("p", event.register, event.count, is_visual)
end
end
return integration

View File

@ -0,0 +1,86 @@
local utils = require("yanky.utils")
local picker = {
actions = {},
}
function picker.setup()
vim.api.nvim_create_user_command("YankyRingHistory", picker.select_in_history, {})
end
function picker.select_in_history()
local history = {}
for index, value in pairs(require("yanky.history").all()) do
value.history_index = index
history[index] = value
end
local config = require("yanky.config").options.picker.select
local action = config.action or require("yanky.picker").actions.put("p", false)
vim.ui.select(history, {
prompt = "Ring history",
format_item = function(item)
return item.regcontents and item.regcontents:gsub("\n", "\\n") or ""
end,
}, action)
end
function picker.actions.put(type, is_visual)
local yanky = require("yanky")
if not vim.tbl_contains(vim.tbl_values(yanky.type), type) then
vim.notify("Invalid type " .. type, vim.log.levels.ERROR)
return
end
return function(next_content)
if nil == next_content then
return
end
utils.use_temporary_register(utils.get_default_register(), next_content, function()
yanky.put(type, is_visual)
end)
end
end
function picker.actions.delete()
return function(content)
if nil == content then
return
end
local yanky = require("yanky")
yanky.history.delete(content.history_index)
end
end
function picker.actions.set_register(register)
return function(content)
if nil == content then
return
end
vim.fn.setreg(register, content.regcontents, content.regtype)
end
end
function picker.actions.special_put(name, is_visual)
if "" == vim.fn.maparg(string.format("<Plug>(%s)", name), "n") then
vim.notify("Invalid special put " .. type, vim.log.levels.ERROR)
return
end
return function(next_content)
if nil == next_content then
return
end
utils.use_temporary_register(utils.get_default_register(), next_content, function()
vim.fn.maparg(string.format("<Plug>(%s)", name), is_visual and "x" or "n", false, true).callback()
end)
end
end
return picker

View File

@ -0,0 +1,50 @@
local preserve_cursor = {}
preserve_cursor.state = {
cusor_position = nil,
win_state = nil,
}
function preserve_cursor.setup()
preserve_cursor.config = require("yanky.config").options.preserve_cursor_position
end
function preserve_cursor.on_yank()
if not preserve_cursor.config.enabled then
return
end
if nil ~= preserve_cursor.state.cusor_position then
vim.fn.setpos(".", preserve_cursor.state.cusor_position)
vim.fn.winrestview(preserve_cursor.state.win_state)
preserve_cursor.state = {
cusor_position = nil,
win_state = nil,
}
end
end
function preserve_cursor.yank()
if not preserve_cursor.config.enabled then
return
end
preserve_cursor.state = {
cusor_position = vim.fn.getpos("."),
win_state = vim.fn.winsaveview(),
}
vim.api.nvim_buf_attach(0, false, {
on_lines = function()
preserve_cursor.state = {
cusor_position = nil,
win_state = nil,
}
return true
end,
})
end
return preserve_cursor

View File

@ -0,0 +1,37 @@
local memory = {
state = {},
}
function memory.setup()
memory.config = require("yanky.config").options.ring
end
function memory.push(item)
table.insert(memory.state, 1, item)
if #memory.state > memory.config.history_length then
table.remove(memory.state)
end
end
function memory.get(n)
return memory.state[n]
end
function memory.length()
return #memory.state
end
function memory.all()
return memory.state
end
function memory.clear()
memory.state = {}
end
function memory.delete(index)
table.remove(memory.state, index)
end
return memory

View File

@ -0,0 +1,53 @@
local shada = {}
function shada.setup()
shada.config = require("yanky.config").options.ring
end
function shada.push(item)
local copy = vim.deepcopy(vim.g.YANKY_HISTORY)
table.insert(copy, 1, item)
if #copy > shada.config.history_length then
table.remove(copy)
end
vim.g.YANKY_HISTORY = copy
end
function shada.get(n)
if nil == vim.g.YANKY_HISTORY then
vim.g.YANKY_HISTORY = {}
end
return vim.g.YANKY_HISTORY[n]
end
function shada.length()
if nil == vim.g.YANKY_HISTORY then
vim.g.YANKY_HISTORY = {}
end
return #vim.g.YANKY_HISTORY
end
function shada.all()
if nil == vim.g.YANKY_HISTORY then
vim.g.YANKY_HISTORY = {}
end
return vim.g.YANKY_HISTORY
end
function shada.clear()
vim.g.YANKY_HISTORY = {}
end
function shada.delete(index)
local copy = vim.deepcopy(vim.g.YANKY_HISTORY)
table.remove(copy, index)
vim.g.YANKY_HISTORY = copy
end
return shada

View File

@ -0,0 +1,90 @@
local sqlite = {
db = nil,
}
function sqlite.setup()
sqlite.config = require("yanky.config").options.ring
local has_sqlite, connection = pcall(require, "sqlite")
if not has_sqlite then
if type(connection) ~= "string" then
vim.notify("Couldn't find sqlite.lua.", vim.log.levels.ERROR, {})
else
vim.notify("Found sqlite.lua: but got the following error: " .. connection)
end
return false
end
vim.fn.mkdir(string.match(sqlite.config.storage_path, "(.*[/\\])"), "p")
sqlite.db = connection:open(sqlite.config.storage_path)
if not sqlite.db then
vim.notify("Error in opening DB", vim.log.levels.ERROR)
return
end
if not sqlite.db:exists("history") then
sqlite.db:create("history", {
id = { "integer", "primary", "key", "autoincrement" },
regcontents = "text",
regtype = "text",
filetype = "text",
})
end
sqlite.db:close()
end
function sqlite.push(item)
sqlite.db:with_open(function()
sqlite.db:eval(
"INSERT INTO history (filetype, regcontents, regtype) VALUES (:filetype, :regcontents, :regtype)",
item
)
sqlite.db:eval(
string.format(
"DELETE FROM history WHERE id NOT IN (SELECT id FROM history ORDER BY id DESC LIMIT %s)",
sqlite.config.history_length
)
)
end)
end
function sqlite.get(index)
return sqlite.db:with_open(function()
return sqlite.db:select("history", { order_by = { desc = "id" }, limit = { 1, index - 1 } })[1]
end)
end
function sqlite.length()
return sqlite.db:with_open(function()
return sqlite.db:tbl("history"):count()
end)
end
function sqlite.all()
return sqlite.db:with_open(function()
return sqlite.db:select("history", { order_by = { desc = "id" } })
end)
end
function sqlite.clear()
return sqlite.db:with_open(function()
return sqlite.db:delete("history")
end)
end
function sqlite.delete(index)
return sqlite.db:with_open(function()
return sqlite.db:eval(
string.format(
"DELETE FROM history WHERE id IN (SELECT id FROM history ORDER BY id DESC LIMIT 1 OFFSET %s)",
index - 1
)
)
end)
end
return sqlite

View File

@ -0,0 +1,64 @@
local utils = require("yanky.utils")
local system_clipboard = {
state = {
reg_info_on_focus_lost = nil,
},
}
function system_clipboard.setup()
system_clipboard.config = require("yanky.config").options.system_clipboard
system_clipboard.config.clipboard_register = system_clipboard.config.clipboard_register or utils.get_system_register()
system_clipboard.history = require("yanky.history")
if system_clipboard.config.sync_with_ring then
local yanky_clipboard_augroup = vim.api.nvim_create_augroup("YankySyncClipboard", { clear = true })
local fetching = false
vim.api.nvim_create_autocmd("FocusGained", {
group = yanky_clipboard_augroup,
pattern = "*",
callback = function(_)
if fetching then
return
end
fetching = true
local ok, err = pcall(system_clipboard.on_focus_gained)
vim.schedule(function()
fetching = false
end)
if not ok then
error(err)
end
end,
})
vim.api.nvim_create_autocmd("FocusLost", {
group = yanky_clipboard_augroup,
pattern = "*",
callback = function(_)
if fetching then
return
end
system_clipboard.on_focus_lost()
end,
})
end
end
function system_clipboard.on_focus_lost()
system_clipboard.state.reg_info_on_focus_lost = utils.get_register_info(system_clipboard.config.clipboard_register)
end
function system_clipboard.on_focus_gained()
local new_reg_info = utils.get_register_info(system_clipboard.config.clipboard_register)
if
system_clipboard.state.reg_info_on_focus_lost ~= nil
and not vim.deep_equal(system_clipboard.state.reg_info_on_focus_lost, new_reg_info)
then
system_clipboard.history.push(new_reg_info)
end
system_clipboard.state.reg_info_on_focus_lost = nil
end
return system_clipboard

View File

@ -0,0 +1,103 @@
local picker = require("yanky.picker")
local utils = require("yanky.utils")
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local mapping = {
state = { is_visual = false },
}
function mapping.put(type)
return function(prompt_bufnr)
if vim.api.nvim_buf_is_valid(prompt_bufnr) then
actions.close(prompt_bufnr)
end
local selection = action_state.get_selected_entry()
-- fix cursor position since
-- https://github.com/nvim-telescope/telescope.nvim/commit/3eb90430b61b78b707e8ffe0cfe49138daaddbcc
local cursor_pos = nil
if vim.api.nvim_get_mode().mode == "i" then
cursor_pos = vim.api.nvim_win_get_cursor(0)
end
vim.schedule(function()
if nil ~= cursor_pos then
vim.api.nvim_win_set_cursor(0, { cursor_pos[1], math.max(cursor_pos[2] - 1, 0) })
end
picker.actions.put(type, mapping.state.is_visual)(selection.value)
end)
end
end
function mapping.special_put(name)
return function(prompt_bufnr)
if vim.api.nvim_buf_is_valid(prompt_bufnr) then
actions.close(prompt_bufnr)
end
local selection = action_state.get_selected_entry()
-- fix cursor position since
-- https://github.com/nvim-telescope/telescope.nvim/commit/3eb90430b61b78b707e8ffe0cfe49138daaddbcc
local cursor_pos = nil
if vim.api.nvim_get_mode().mode == "i" then
cursor_pos = vim.api.nvim_win_get_cursor(0)
end
vim.schedule(function()
if nil ~= cursor_pos then
vim.api.nvim_win_set_cursor(0, { cursor_pos[1], math.max(cursor_pos[2] - 1, 0) })
end
picker.actions.special_put(name, mapping.state.is_visual)(selection.value)
end)
end
end
function mapping.delete()
return function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
current_picker:delete_selection(function(selection)
picker.actions.delete()(selection.value)
end)
end
end
function mapping.set_register(register)
return function(prompt_bufnr)
if vim.api.nvim_buf_is_valid(prompt_bufnr) then
actions.close(prompt_bufnr)
end
local selection = action_state.get_selected_entry()
vim.schedule(function()
picker.actions.set_register(register)(selection.value)
end)
end
end
function mapping.put_and_set_register(type, register)
return function(prompt_bufnr)
mapping.put(type)(prompt_bufnr)
mapping.set_register(register)(prompt_bufnr)
end
end
function mapping.get_defaults()
return {
default = mapping.put("p"),
i = {
["<c-g>"] = mapping.put("p"),
["<c-k>"] = mapping.put("P"),
["<c-x>"] = mapping.delete(),
["<c-r>"] = mapping.set_register(utils.get_default_register()),
},
n = {
p = mapping.put("p"),
P = mapping.put("P"),
d = mapping.delete(),
r = mapping.set_register(utils.get_default_register()),
},
}
end
return mapping

View File

@ -0,0 +1,128 @@
local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
local previewers = require("telescope.previewers")
local actions = require("telescope.actions")
local entry_display = require("telescope.pickers.entry_display")
local conf = require("telescope.config").values
local mapping = require("yanky.telescope.mapping")
local config = require("yanky.config")
local yank_history = {}
function yank_history.get_exports()
return {
yank_history = yank_history.yank_history,
}
end
local regtype_to_text = function(regtype)
if "v" == regtype then
return "charwise"
end
if "V" == regtype then
return "linewise"
end
return "blockwise"
end
local format_title = function(entry)
return regtype_to_text(entry.value.regtype)
end
function yank_history.previewer()
return previewers.new_buffer_previewer({
dyn_title = function(_, entry)
return format_title(entry)
end,
define_preview = function(self, entry)
vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, true, vim.split(entry.value.regcontents, "\n"))
if entry.value.filetype ~= nil then
vim.bo[self.state.bufnr].filetype = entry.value.filetype
end
end,
})
end
function yank_history.attach_mappings(_, map)
local mappings = config.options.picker.telescope.use_default_mappings
and vim.tbl_deep_extend("force", mapping.get_defaults(), config.options.picker.telescope.mappings or {})
or (config.options.picker.telescope.mappings or {})
if mappings.default then
actions.select_default:replace(mappings.default)
end
for _, mode in pairs({ "i", "n" }) do
if mappings[mode] then
for keys, action in pairs(mappings[mode]) do
map(mode, keys, action)
end
end
end
return true
end
function yank_history.gen_from_history(opts)
local displayer = entry_display.create({
separator = " ",
items = {
{ width = #tostring(opts.history_length) },
{ remaining = true },
},
})
local make_display = function(entry)
local content = entry.content
return displayer({
{ entry.value.history_index, "TelescopeResultsNumber" },
content:gsub("\n", "\\n"),
})
end
return function(entry)
return {
valid = true,
value = entry,
ordinal = entry.regcontents,
content = entry.regcontents,
display = make_display,
}
end
end
function yank_history.yank_history(opts)
local is_visual = vim.fn.mode() == "v" or vim.fn.mode() == "V"
if is_visual then
vim.cmd([[execute "normal! \<esc>"]])
end
mapping.state.is_visual = is_visual
opts = opts or {}
local history = {}
for index, value in pairs(require("yanky.history").all()) do
value.history_index = index
history[index] = value
end
opts.history_length = #history
pickers
.new(opts, {
prompt_title = "Yank history",
finder = finders.new_table({
results = history,
entry_maker = yank_history.gen_from_history(opts),
}),
attach_mappings = yank_history.attach_mappings,
previewer = yank_history.previewer(),
sorter = conf.generic_sorter(opts),
})
:find()
end
return yank_history

View File

@ -0,0 +1,63 @@
local textobj = {
state = nil,
}
local function get_region(regtype)
local start = vim.api.nvim_buf_get_mark(0, "[")
local finish = vim.api.nvim_buf_get_mark(0, "]")
return {
start_row = start[1],
start_col = "V" ~= regtype and start[2] or 0,
end_row = finish[1],
end_col = "V" ~= regtype and finish[2] or vim.fn.col("$"),
}
end
local function is_visual_mode()
return nil ~= vim.fn.mode():find("v")
end
local function set_selection(startpos, endpos)
vim.api.nvim_win_set_cursor(0, startpos)
if is_visual_mode() then
vim.cmd("normal! o")
else
vim.cmd("normal! v")
end
vim.api.nvim_win_set_cursor(0, endpos)
end
function textobj.save_put()
vim.b.yanky_textobj = {
region = get_region(vim.fn.getregtype(vim.v.register)),
regtype = vim.fn.getregtype(vim.v.register),
}
vim.api.nvim_buf_attach(0, false, {
on_lines = function(_, _, _, first_line)
if vim.b.yanky_textobj and (first_line <= vim.b.yanky_textobj.region.end_row) then
vim.b.yanky_textobj = nil
return true
end
end,
})
end
function textobj.last_put()
if nil == vim.b.yanky_textobj then
vim.notify("No last put text-object", vim.log.levels.INFO)
return
end
set_selection({
vim.b.yanky_textobj.region.start_row,
vim.b.yanky_textobj.region.start_col,
}, {
vim.b.yanky_textobj.region.end_row,
vim.b.yanky_textobj.region.end_col,
})
end
return textobj

View File

@ -0,0 +1,45 @@
local utils = {}
function utils.get_default_register()
local clipboard_tool = vim.fn["provider#clipboard#Executable"]()
if not clipboard_tool or "" == clipboard_tool then
return '"'
end
local clipboard_flags = vim.split(vim.api.nvim_get_option("clipboard"), ",")
if vim.tbl_contains(clipboard_flags, "unnamedplus") then
return "+"
end
if vim.tbl_contains(clipboard_flags, "unnamed") then
return "*"
end
return '"'
end
function utils.get_system_register()
local clipboardFlags = vim.split(vim.api.nvim_get_option("clipboard"), ",")
if vim.tbl_contains(clipboardFlags, "unnamedplus") then
return "+"
end
return "*"
end
function utils.get_register_info(register)
return {
regcontents = vim.fn.getreg(register),
regtype = vim.fn.getregtype(register),
}
end
function utils.use_temporary_register(register, register_info, callback)
local current_register_info = utils.get_register_info(register)
vim.fn.setreg(register, register_info.regcontents, register_info.regtype)
callback()
vim.fn.setreg(register, current_register_info.regcontents, current_register_info.regtype)
end
return utils

View File

@ -0,0 +1,101 @@
local wrappers = {}
function wrappers.linewise(next)
return function(state, callback)
local body = vim.fn.getreg(state.register)
local type = vim.fn.getregtype(state.register)
vim.fn.setreg(state.register, body, "l")
if nil == next then
callback(state)
else
next(state, callback)
end
vim.fn.setreg(state.register, body, type)
end
end
function wrappers.charwise(next)
return function(state, callback)
local body = vim.fn.getreg(state.register)
local type = vim.fn.getregtype(state.register)
local reformated_body = body:gsub("\n$", "")
vim.fn.setreg(state.register, reformated_body, "c")
if nil == next then
callback(state)
else
next(state, callback)
end
vim.fn.setreg(state.register, body, type)
end
end
function wrappers.blockwise(next)
return function(state, callback)
local body = vim.fn.getreg(state.register)
local type = vim.fn.getregtype(state.register)
vim.fn.setreg(state.register, body, "b")
if nil == next then
callback(state)
else
next(state, callback)
end
vim.fn.setreg(state.register, body, type)
end
end
function wrappers.trim_and_join_lines(next)
return function(state, callback)
local body = vim.fn.getreg(state.register)
local reformated_body = body:gsub("%s*\r?\n%s*", " "):gsub("^%s*", ""):gsub("%s*$", "")
vim.fn.setreg(state.register, reformated_body, vim.fn.getregtype(state.register))
if nil == next then
callback(state)
else
next(state, callback)
end
vim.fn.setreg(state.register, body, vim.fn.getregtype(state.register))
end
end
function wrappers.change(change, next)
return function(state, callback)
if nil == next then
callback(state)
else
next(state, callback)
end
-- local line_len = vim.api.nvim_get_current_line():len()
local cursor_pos = vim.api.nvim_win_get_cursor(0)
vim.cmd(string.format("silent '[,']normal! %s", change))
vim.api.nvim_win_set_cursor(0, cursor_pos)
vim.cmd(string.format("silent normal! %s", (state.type == "gp" or state.type == "gP") and "0" or "^"))
end
end
function wrappers.set_cursor_pos(pos, next)
return function(state, callback)
if nil == next then
callback(state)
else
next(state, callback)
end
vim.cmd(string.format("silent normal! %s", pos))
end
end
return wrappers