├── LICENSE ├── README.md ├── autoload └── miniyank.vim ├── lua ├── MessagePack.lua └── miniyank.lua ├── plugin └── miniyank.vim └── rplugin └── python3 └── denite ├── kind └── miniyank.py └── source └── miniyank.py /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016: Björn Linse 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nvim-miniyank 2 | 3 | The killring-alike plugin with no default mappings. 4 | 5 | Works in neovim, as well as vim with lua enabled and patch 8.0.1394. 6 | 7 | # Usage 8 | 9 | Yanks and deletes will be detected using `TextYankPost` autocommand, so no mappings for these actions are needed. 10 | The yank history is shared between [n]vim instances. 11 | 12 | There is two different mappings for starting to put from the history. 13 | To remap `p`, "autoput" mapping should be used. This will first put the same text as unmapped "p" would have, and still support `"xp` and `clipboard=unnamed[plus]`: 14 | 15 | map p (miniyank-autoput) 16 | map P (miniyank-autoPut) 17 | 18 | "startput" will directly put the most recent item in the shared history: 19 | 20 | map p (miniyank-startput) 21 | map P (miniyank-startPut) 22 | 23 | Right after a put, use "cycle" to go through history: 24 | 25 | map n (miniyank-cycle) 26 | 27 | Stepped too far? You can cycle back to more recent items using: 28 | 29 | map N (miniyank-cycleback) 30 | 31 | Maybe the register type was wrong? Well, you can change it after putting: 32 | 33 | map c (miniyank-tochar) 34 | map l (miniyank-toline) 35 | map b (miniyank-toblock) 36 | 37 | # clipboard=unnamed register type fixing 38 | Currently neovim doesn't have support for register types in the clipboard. This makes blockwise yanking and putting broken when `clipboard=unnamed` or `unnamedplus` is used. When this option is set, and "p" is mapped to "autoput" mappings as suggested above, this plugin will try to _correct_ the register type when an unnamed paste is done. It uses heuristics that _at least_ will work if you yank blockwise and then immediately paste unnamed in the same or another nvim instance. 39 | 40 | Of course, regardless if `clipboard=unnamed` is set or not, you can always do the correct paste using a "startPut" mapping, or cycling one step back in history when needed. 41 | 42 | # Throttling of big unnamed deletes 43 | 44 | The plugin tries to avoid unnecessary copying on unnamed deletes (`d` or `c` with no preceeding `"x`). Unnamed deletes with more than `g:miniyank_delete_maxlines` (default 1000) will be ignored. To force yanking, just add a register name, like `""d` or `"*d`. 45 | 46 | # Denite source 47 | 48 | If Denite is installed, the yank history can be displayed using `:Denite miniyank` 49 | 50 | # FAQ 51 | 52 | ## Does it work in vim 8? 53 | 54 | Yes, if lua is enabled and with vim 8.1 or later. (Lua is not really intrinsically needed. One day I might implement the small necessary subset of msgpack directly in vimL.) 55 | 56 | ## It doesn't work! 57 | 58 | This plugin tries to autodetect a suitable file path for the shared yankring. `$XDG_RUNTIME_DIR` is used if set, otherwise `stdpath('cache')` will be used. Check that `g:miniyank_filename` was set to a location that is both readable and writeable by your user account. If not, either fix your environment, or override it manually: 59 | 60 | 61 | let g:miniyank_filename = $HOME."/.miniyank.mpack" 62 | 63 | 64 | 65 | ## Is python3 required? 66 | 67 | Python is only required for the optional Denite source. The rest of the plugin is pure vimscript. 68 | 69 | ## 10 items? That is not close to be enough! 70 | 71 | How about 72 | 73 | let g:miniyank_maxitems = 100 74 | 75 | ## It doesn't persist across reboots! 76 | 77 | Sigh, just why? Okay, do 78 | 79 | let g:miniyank_filename = $HOME."/.miniyank.mpack" 80 | 81 | 82 | -------------------------------------------------------------------------------- /autoload/miniyank.vim: -------------------------------------------------------------------------------- 1 | if has("nvim") 2 | let s:lua = v:false 3 | else 4 | if !has("lua") 5 | finish 6 | endif 7 | let s:lua = v:true 8 | let s:plug_path = expand( ':p:h:h') 9 | lua <:p:h:h')")..'/lua/?.lua' 11 | miniyank = require'miniyank' 12 | EOF 13 | endif 14 | 15 | function! miniyank#read() abort 16 | if !filereadable(g:miniyank_filename) 17 | return [] 18 | end 19 | if s:lua 20 | return luaeval("miniyank.read(_A)",g:miniyank_filename) 21 | end 22 | return msgpackparse(readfile(g:miniyank_filename, 'b')) 23 | endfunction 24 | 25 | function! miniyank#write(data) abort 26 | if s:lua 27 | return luaeval("miniyank.write(_A[1], _A[2])",[g:miniyank_filename,a:data]) 28 | end 29 | call writefile(msgpackdump(a:data), g:miniyank_filename, 'b') 30 | endfunction 31 | 32 | function! miniyank#add_item(list, item) abort 33 | for n in range(len(a:list)) 34 | if a:list[n][:1] ==# a:item[:1] 35 | call remove(a:list, n) 36 | break 37 | endif 38 | endfor 39 | call insert(a:list, a:item, 0) 40 | if len(a:list) > g:miniyank_maxitems 41 | call remove(a:list, g:miniyank_maxitems, -1) 42 | endif 43 | return a:list 44 | endfunction 45 | 46 | function! miniyank#parse_cb() abort 47 | let parts = split(&clipboard, ',') 48 | let cbs = '' 49 | if index(parts, "unnamed") >= 0 50 | let cbs = cbs.'*' 51 | endif 52 | if index(parts, "unnamedplus") >= 0 53 | let cbs = cbs.'+' 54 | endif 55 | return cbs 56 | endfunction 57 | 58 | function! miniyank#on_yank(ev) abort 59 | if len(a:ev.regcontents) == 1 && len(a:ev.regcontents[0]) <= 1 60 | return 61 | end 62 | " avoid expensive copying on delete unless yanking to a register was 63 | " explcitly requested 64 | if a:ev.operator != 'y' && a:ev.regname == '' && len(a:ev.regcontents) > g:miniyank_delete_maxlines 65 | return 66 | end 67 | let state = miniyank#read() 68 | if a:ev.regname == '' 69 | let a:ev.regname = miniyank#parse_cb() 70 | endif 71 | call miniyank#add_item(state, [a:ev.regcontents, a:ev.regtype, a:ev.regname]) 72 | call miniyank#write(state) 73 | endfunction 74 | 75 | " TODO: this should be a nvim builtin 76 | function! miniyank#putreg(data,cmd) abort 77 | let regsave = [getreg('0'), getregtype('0')] 78 | call setreg('0', a:data[0], a:data[1]) 79 | execute 'normal! '.(s:visual ? 'gv' : '').s:count.'"0'.a:cmd 80 | call setreg('0', regsave[0], regsave[1]) 81 | let s:last = a:data[0] 82 | endfunction 83 | 84 | " work-around nvim:s lack of register types in clipboard 85 | " only use this when clipboard=unnamed[plus] 86 | " otherwise you are expected to use startput 87 | function! miniyank#fix_clip(list, pasted) abort 88 | if !has("nvim") 89 | return v:false 90 | end 91 | if stridx('*+', a:pasted[2]) < 0 || miniyank#parse_cb() ==# '' || len(a:list) == 0 92 | return v:false 93 | endif 94 | let last = a:list[0] 95 | if stridx(last[2], a:pasted[2]) < 0 96 | return v:false 97 | endif 98 | if last[1] ==# 'v' && len(last[0]) >= 2 && last[0][-1] == '' 99 | " this would been had missinterpreted as a line, but is a charwise 100 | return a:pasted[1] == 'V' && a:pasted[0] ==# last[0][:-2] 101 | endif 102 | return a:pasted[1] ==# 'V' && a:pasted[0] ==# last[0] 103 | endfunction 104 | 105 | let s:changedtick = -1 106 | 107 | " TODO: put autocommand plz 108 | function! miniyank#startput(cmd,defer) abort 109 | if mode(1) ==# "no" 110 | return a:cmd " don't override diffput 111 | end 112 | let s:pastelist = miniyank#read() 113 | let s:pos = 0 114 | let s:cmd = a:cmd 115 | let s:visual = index(["v","V","\026"], mode()) >= 0 116 | let s:count = string(v:count1) 117 | if a:defer 118 | let first = [getreg(v:register,0,1), getregtype(v:register), v:register] 119 | if !miniyank#fix_clip(s:pastelist, first) 120 | call miniyank#add_item(s:pastelist, first) 121 | endif 122 | end 123 | return ":\call miniyank#do_putlist()\015" 124 | endfunction 125 | 126 | function! miniyank#cycle(dir) abort 127 | if s:changedtick != b:changedtick 128 | return 129 | end 130 | if a:dir > 0 " forward 131 | if s:pos+a:dir >= len(s:pastelist) 132 | echoerr "miniyank: no more items!" 133 | return 134 | endif 135 | elseif a:dir < 0 " backward 136 | if s:pos+a:dir < 0 137 | echoerr "miniyank: no previous items!" 138 | return 139 | endif 140 | end 141 | let s:pos += a:dir 142 | silent undo 143 | call miniyank#do_putlist() 144 | endfunction 145 | 146 | function! miniyank#do_putlist() abort 147 | call miniyank#putreg(s:pastelist[s:pos],s:cmd) 148 | let s:changedtick = b:changedtick 149 | endfunction 150 | 151 | function! miniyank#force_motion(motion) abort 152 | if s:changedtick != b:changedtick 153 | return 154 | end 155 | silent undo 156 | call miniyank#putreg([s:last, a:motion], s:cmd) 157 | let s:changedtick = b:changedtick 158 | endfunction 159 | 160 | " FIXME: integrate with the rest 161 | function! miniyank#drop(data,cmd) abort 162 | let s:pastelist = [a:data] 163 | let s:pos = 0 164 | let s:visual = '' 165 | let s:count = 1 166 | let s:cmd = a:cmd 167 | " why not putreg?? 168 | call miniyank#do_putlist() 169 | endfunction 170 | -------------------------------------------------------------------------------- /lua/MessagePack.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- lua-MessagePack : 3 | -- 4 | 5 | local r, jit = pcall(require, 'jit') 6 | if not r then 7 | jit = nil 8 | end 9 | 10 | local SIZEOF_NUMBER = string.pack and #string.pack('n', 0.0) or 8 11 | local maxinteger 12 | local mininteger 13 | if not jit and _VERSION < 'Lua 5.3' then 14 | -- Lua 5.1 & 5.2 15 | local loadstring = loadstring or load 16 | local luac = string.dump(loadstring "a = 1") 17 | local header = { luac:sub(1, 12):byte(1, 12) } 18 | SIZEOF_NUMBER = header[11] 19 | end 20 | 21 | local assert = assert 22 | local error = error 23 | local pairs = pairs 24 | local pcall = pcall 25 | local setmetatable = setmetatable 26 | local tostring = tostring 27 | local type = type 28 | local char = require'string'.char 29 | local format = require'string'.format 30 | local floor = require'math'.floor 31 | local tointeger = require'math'.tointeger or floor 32 | local frexp = require'math'.frexp or require'mathx'.frexp 33 | local ldexp = require'math'.ldexp or require'mathx'.ldexp 34 | local huge = require'math'.huge 35 | local tconcat = require'table'.concat 36 | 37 | local _ENV = nil 38 | local m = {} 39 | 40 | --[[ debug only 41 | local function hexadump (s) 42 | return (s:gsub('.', function (c) return format('%02X ', c:byte()) end)) 43 | end 44 | m.hexadump = hexadump 45 | --]] 46 | 47 | local function argerror (caller, narg, extramsg) 48 | error("bad argument #" .. tostring(narg) .. " to " 49 | .. caller .. " (" .. extramsg .. ")") 50 | end 51 | 52 | local function typeerror (caller, narg, arg, tname) 53 | argerror(caller, narg, tname .. " expected, got " .. type(arg)) 54 | end 55 | 56 | local function checktype (caller, narg, arg, tname) 57 | if type(arg) ~= tname then 58 | typeerror(caller, narg, arg, tname) 59 | end 60 | end 61 | 62 | local packers = setmetatable({}, { 63 | __index = function (t, k) 64 | if k == 1 then return end -- allows ipairs 65 | error("pack '" .. k .. "' is unimplemented") 66 | end 67 | }) 68 | m.packers = packers 69 | 70 | packers['nil'] = function (buffer) 71 | buffer[#buffer+1] = char(0xC0) -- nil 72 | end 73 | 74 | packers['boolean'] = function (buffer, bool) 75 | if bool then 76 | buffer[#buffer+1] = char(0xC3) -- true 77 | else 78 | buffer[#buffer+1] = char(0xC2) -- false 79 | end 80 | end 81 | 82 | packers['string_compat'] = function (buffer, str) 83 | local n = #str 84 | if n <= 0x1F then 85 | buffer[#buffer+1] = char(0xA0 + n) -- fixstr 86 | elseif n <= 0xFFFF then 87 | buffer[#buffer+1] = char(0xDA, -- str16 88 | floor(n / 0x100), 89 | n % 0x100) 90 | elseif n <= 4294967295.0 then 91 | buffer[#buffer+1] = char(0xDB, -- str32 92 | floor(n / 0x1000000), 93 | floor(n / 0x10000) % 0x100, 94 | floor(n / 0x100) % 0x100, 95 | n % 0x100) 96 | else 97 | error"overflow in pack 'string_compat'" 98 | end 99 | buffer[#buffer+1] = str 100 | end 101 | 102 | packers['_string'] = function (buffer, str) 103 | local n = #str 104 | if n <= 0x1F then 105 | buffer[#buffer+1] = char(0xA0 + n) -- fixstr 106 | elseif n <= 0xFF then 107 | buffer[#buffer+1] = char(0xD9, -- str8 108 | n) 109 | elseif n <= 0xFFFF then 110 | buffer[#buffer+1] = char(0xDA, -- str16 111 | floor(n / 0x100), 112 | n % 0x100) 113 | elseif n <= 4294967295.0 then 114 | buffer[#buffer+1] = char(0xDB, -- str32 115 | floor(n / 0x1000000), 116 | floor(n / 0x10000) % 0x100, 117 | floor(n / 0x100) % 0x100, 118 | n % 0x100) 119 | else 120 | error"overflow in pack 'string'" 121 | end 122 | buffer[#buffer+1] = str 123 | end 124 | 125 | packers['binary'] = function (buffer, str) 126 | local n = #str 127 | if n <= 0xFF then 128 | buffer[#buffer+1] = char(0xC4, -- bin8 129 | n) 130 | elseif n <= 0xFFFF then 131 | buffer[#buffer+1] = char(0xC5, -- bin16 132 | floor(n / 0x100), 133 | n % 0x100) 134 | elseif n <= 4294967295.0 then 135 | buffer[#buffer+1] = char(0xC6, -- bin32 136 | floor(n / 0x1000000), 137 | floor(n / 0x10000) % 0x100, 138 | floor(n / 0x100) % 0x100, 139 | n % 0x100) 140 | else 141 | error"overflow in pack 'binary'" 142 | end 143 | buffer[#buffer+1] = str 144 | end 145 | 146 | local set_string = function (str) 147 | if str == 'string_compat' then 148 | packers['string'] = packers['string_compat'] 149 | elseif str == 'string' then 150 | packers['string'] = packers['_string'] 151 | elseif str == 'binary' then 152 | packers['string'] = packers['binary'] 153 | else 154 | argerror('set_string', 1, "invalid option '" .. str .."'") 155 | end 156 | end 157 | m.set_string = set_string 158 | 159 | packers['map'] = function (buffer, tbl, n) 160 | if n <= 0x0F then 161 | buffer[#buffer+1] = char(0x80 + n) -- fixmap 162 | elseif n <= 0xFFFF then 163 | buffer[#buffer+1] = char(0xDE, -- map16 164 | floor(n / 0x100), 165 | n % 0x100) 166 | elseif n <= 4294967295.0 then 167 | buffer[#buffer+1] = char(0xDF, -- map32 168 | floor(n / 0x1000000), 169 | floor(n / 0x10000) % 0x100, 170 | floor(n / 0x100) % 0x100, 171 | n % 0x100) 172 | else 173 | error"overflow in pack 'map'" 174 | end 175 | for k, v in pairs(tbl) do 176 | packers[type(k)](buffer, k) 177 | packers[type(v)](buffer, v) 178 | end 179 | end 180 | 181 | packers['array'] = function (buffer, tbl, n) 182 | if n <= 0x0F then 183 | buffer[#buffer+1] = char(0x90 + n) -- fixarray 184 | elseif n <= 0xFFFF then 185 | buffer[#buffer+1] = char(0xDC, -- array16 186 | floor(n / 0x100), 187 | n % 0x100) 188 | elseif n <= 4294967295.0 then 189 | buffer[#buffer+1] = char(0xDD, -- array32 190 | floor(n / 0x1000000), 191 | floor(n / 0x10000) % 0x100, 192 | floor(n / 0x100) % 0x100, 193 | n % 0x100) 194 | else 195 | error"overflow in pack 'array'" 196 | end 197 | for i = 1, n do 198 | local v = tbl[i] 199 | packers[type(v)](buffer, v) 200 | end 201 | end 202 | 203 | local set_array = function (array) 204 | if array == 'without_hole' then 205 | packers['_table'] = function (buffer, tbl) 206 | local is_map, n, max = false, 0, 0 207 | for k in pairs(tbl) do 208 | if type(k) == 'number' and k > 0 then 209 | if k > max then 210 | max = k 211 | end 212 | else 213 | is_map = true 214 | end 215 | n = n + 1 216 | end 217 | if max ~= n then -- there are holes 218 | is_map = true 219 | end 220 | if is_map then 221 | packers['map'](buffer, tbl, n) 222 | else 223 | packers['array'](buffer, tbl, n) 224 | end 225 | end 226 | elseif array == 'with_hole' then 227 | packers['_table'] = function (buffer, tbl) 228 | local is_map, n, max = false, 0, 0 229 | for k in pairs(tbl) do 230 | if type(k) == 'number' and k > 0 then 231 | if k > max then 232 | max = k 233 | end 234 | else 235 | is_map = true 236 | end 237 | n = n + 1 238 | end 239 | if is_map then 240 | packers['map'](buffer, tbl, n) 241 | else 242 | packers['array'](buffer, tbl, max) 243 | end 244 | end 245 | elseif array == 'always_as_map' then 246 | packers['_table'] = function(buffer, tbl) 247 | local n = 0 248 | for k in pairs(tbl) do 249 | n = n + 1 250 | end 251 | packers['map'](buffer, tbl, n) 252 | end 253 | else 254 | argerror('set_array', 1, "invalid option '" .. array .."'") 255 | end 256 | end 257 | m.set_array = set_array 258 | 259 | packers['table'] = function (buffer, tbl) 260 | packers['_table'](buffer, tbl) 261 | end 262 | 263 | packers['unsigned'] = function (buffer, n) 264 | if n >= 0 then 265 | if n <= 0x7F then 266 | buffer[#buffer+1] = char(n) -- fixnum_pos 267 | elseif n <= 0xFF then 268 | buffer[#buffer+1] = char(0xCC, -- uint8 269 | n) 270 | elseif n <= 0xFFFF then 271 | buffer[#buffer+1] = char(0xCD, -- uint16 272 | floor(n / 0x100), 273 | n % 0x100) 274 | elseif n <= 4294967295.0 then 275 | buffer[#buffer+1] = char(0xCE, -- uint32 276 | floor(n / 0x1000000), 277 | floor(n / 0x10000) % 0x100, 278 | floor(n / 0x100) % 0x100, 279 | n % 0x100) 280 | else 281 | buffer[#buffer+1] = char(0xCF, -- uint64 282 | 0, -- only 53 bits from double 283 | floor(n / 0x1000000000000) % 0x100, 284 | floor(n / 0x10000000000) % 0x100, 285 | floor(n / 0x100000000) % 0x100, 286 | floor(n / 0x1000000) % 0x100, 287 | floor(n / 0x10000) % 0x100, 288 | floor(n / 0x100) % 0x100, 289 | n % 0x100) 290 | end 291 | else 292 | if n >= -0x20 then 293 | buffer[#buffer+1] = char(0x100 + n) -- fixnum_neg 294 | elseif n >= -0x80 then 295 | buffer[#buffer+1] = char(0xD0, -- int8 296 | 0x100 + n) 297 | elseif n >= -0x8000 then 298 | n = 0x10000 + n 299 | buffer[#buffer+1] = char(0xD1, -- int16 300 | floor(n / 0x100), 301 | n % 0x100) 302 | elseif n >= -0x80000000 then 303 | n = 4294967296.0 + n 304 | buffer[#buffer+1] = char(0xD2, -- int32 305 | floor(n / 0x1000000), 306 | floor(n / 0x10000) % 0x100, 307 | floor(n / 0x100) % 0x100, 308 | n % 0x100) 309 | else 310 | buffer[#buffer+1] = char(0xD3, -- int64 311 | 0xFF, -- only 53 bits from double 312 | floor(n / 0x1000000000000) % 0x100, 313 | floor(n / 0x10000000000) % 0x100, 314 | floor(n / 0x100000000) % 0x100, 315 | floor(n / 0x1000000) % 0x100, 316 | floor(n / 0x10000) % 0x100, 317 | floor(n / 0x100) % 0x100, 318 | n % 0x100) 319 | end 320 | end 321 | end 322 | 323 | packers['signed'] = function (buffer, n) 324 | if n >= 0 then 325 | if n <= 0x7F then 326 | buffer[#buffer+1] = char(n) -- fixnum_pos 327 | elseif n <= 0x7FFF then 328 | buffer[#buffer+1] = char(0xD1, -- int16 329 | floor(n / 0x100), 330 | n % 0x100) 331 | elseif n <= 0x7FFFFFFF then 332 | buffer[#buffer+1] = char(0xD2, -- int32 333 | floor(n / 0x1000000), 334 | floor(n / 0x10000) % 0x100, 335 | floor(n / 0x100) % 0x100, 336 | n % 0x100) 337 | else 338 | buffer[#buffer+1] = char(0xD3, -- int64 339 | 0, -- only 53 bits from double 340 | floor(n / 0x1000000000000) % 0x100, 341 | floor(n / 0x10000000000) % 0x100, 342 | floor(n / 0x100000000) % 0x100, 343 | floor(n / 0x1000000) % 0x100, 344 | floor(n / 0x10000) % 0x100, 345 | floor(n / 0x100) % 0x100, 346 | n % 0x100) 347 | end 348 | else 349 | if n >= -0x20 then 350 | buffer[#buffer+1] = char(0xE0 + 0x20 + n) -- fixnum_neg 351 | elseif n >= -0x80 then 352 | buffer[#buffer+1] = char(0xD0, -- int8 353 | 0x100 + n) 354 | elseif n >= -0x8000 then 355 | n = 0x10000 + n 356 | buffer[#buffer+1] = char(0xD1, -- int16 357 | floor(n / 0x100), 358 | n % 0x100) 359 | elseif n >= -0x80000000 then 360 | n = 4294967296.0 + n 361 | buffer[#buffer+1] = char(0xD2, -- int32 362 | floor(n / 0x1000000), 363 | floor(n / 0x10000) % 0x100, 364 | floor(n / 0x100) % 0x100, 365 | n % 0x100) 366 | else 367 | buffer[#buffer+1] = char(0xD3, -- int64 368 | 0xFF, -- only 53 bits from double 369 | floor(n / 0x1000000000000) % 0x100, 370 | floor(n / 0x10000000000) % 0x100, 371 | floor(n / 0x100000000) % 0x100, 372 | floor(n / 0x1000000) % 0x100, 373 | floor(n / 0x10000) % 0x100, 374 | floor(n / 0x100) % 0x100, 375 | n % 0x100) 376 | end 377 | end 378 | end 379 | 380 | local set_integer = function (integer) 381 | if integer == 'unsigned' then 382 | packers['integer'] = packers['unsigned'] 383 | elseif integer == 'signed' then 384 | packers['integer'] = packers['signed'] 385 | else 386 | argerror('set_integer', 1, "invalid option '" .. integer .."'") 387 | end 388 | end 389 | m.set_integer = set_integer 390 | 391 | packers['float'] = function (buffer, n) 392 | local sign = 0 393 | if n < 0.0 then 394 | sign = 0x80 395 | n = -n 396 | end 397 | local mant, expo = frexp(n) 398 | if mant ~= mant then 399 | buffer[#buffer+1] = char(0xCA, -- nan 400 | 0xFF, 0x88, 0x00, 0x00) 401 | elseif mant == huge or expo > 0x80 then 402 | if sign == 0 then 403 | buffer[#buffer+1] = char(0xCA, -- inf 404 | 0x7F, 0x80, 0x00, 0x00) 405 | else 406 | buffer[#buffer+1] = char(0xCA, -- -inf 407 | 0xFF, 0x80, 0x00, 0x00) 408 | end 409 | elseif (mant == 0.0 and expo == 0) or expo < -0x7E then 410 | buffer[#buffer+1] = char(0xCA, -- zero 411 | sign, 0x00, 0x00, 0x00) 412 | else 413 | expo = expo + 0x7E 414 | mant = floor((mant * 2.0 - 1.0) * ldexp(0.5, 24)) 415 | buffer[#buffer+1] = char(0xCA, 416 | sign + floor(expo / 0x2), 417 | (expo % 0x2) * 0x80 + floor(mant / 0x10000), 418 | floor(mant / 0x100) % 0x100, 419 | mant % 0x100) 420 | end 421 | end 422 | 423 | packers['double'] = function (buffer, n) 424 | local sign = 0 425 | if n < 0.0 then 426 | sign = 0x80 427 | n = -n 428 | end 429 | local mant, expo = frexp(n) 430 | if mant ~= mant then 431 | buffer[#buffer+1] = char(0xCB, -- nan 432 | 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) 433 | elseif mant == huge or expo > 0x400 then 434 | if sign == 0 then 435 | buffer[#buffer+1] = char(0xCB, -- inf 436 | 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) 437 | else 438 | buffer[#buffer+1] = char(0xCB, -- -inf 439 | 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) 440 | end 441 | elseif (mant == 0.0 and expo == 0) or expo < -0x3FE then 442 | buffer[#buffer+1] = char(0xCB, -- zero 443 | sign, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) 444 | else 445 | expo = expo + 0x3FE 446 | mant = floor((mant * 2.0 - 1.0) * ldexp(0.5, 53)) 447 | buffer[#buffer+1] = char(0xCB, 448 | sign + floor(expo / 0x10), 449 | (expo % 0x10) * 0x10 + floor(mant / 0x1000000000000), 450 | floor(mant / 0x10000000000) % 0x100, 451 | floor(mant / 0x100000000) % 0x100, 452 | floor(mant / 0x1000000) % 0x100, 453 | floor(mant / 0x10000) % 0x100, 454 | floor(mant / 0x100) % 0x100, 455 | mant % 0x100) 456 | end 457 | end 458 | 459 | local set_number = function (number) 460 | if number == 'float' then 461 | packers['number'] = function (buffer, n) 462 | if floor(n) == n and n < maxinteger and n > mininteger then 463 | packers['integer'](buffer, n) 464 | else 465 | packers['float'](buffer, n) 466 | end 467 | end 468 | elseif number == 'double' then 469 | packers['number'] = function (buffer, n) 470 | if floor(n) == n and n < maxinteger and n > mininteger then 471 | packers['integer'](buffer, n) 472 | else 473 | packers['double'](buffer, n) 474 | end 475 | end 476 | else 477 | argerror('set_number', 1, "invalid option '" .. number .."'") 478 | end 479 | end 480 | m.set_number = set_number 481 | 482 | for k = 0, 4 do 483 | local n = tointeger(2^k) 484 | local fixext = 0xD4 + k 485 | packers['fixext' .. tostring(n)] = function (buffer, tag, data) 486 | assert(#data == n, "bad length for fixext" .. tostring(n)) 487 | buffer[#buffer+1] = char(fixext, 488 | tag < 0 and tag + 0x100 or tag) 489 | buffer[#buffer+1] = data 490 | end 491 | end 492 | 493 | packers['ext'] = function (buffer, tag, data) 494 | local n = #data 495 | if n <= 0xFF then 496 | buffer[#buffer+1] = char(0xC7, -- ext8 497 | n, 498 | tag < 0 and tag + 0x100 or tag) 499 | elseif n <= 0xFFFF then 500 | buffer[#buffer+1] = char(0xC8, -- ext16 501 | floor(n / 0x100), 502 | n % 0x100, 503 | tag < 0 and tag + 0x100 or tag) 504 | elseif n <= 4294967295.0 then 505 | buffer[#buffer+1] = char(0xC9, -- ext&32 506 | floor(n / 0x1000000), 507 | floor(n / 0x10000) % 0x100, 508 | floor(n / 0x100) % 0x100, 509 | n % 0x100, 510 | tag < 0 and tag + 0x100 or tag) 511 | else 512 | error"overflow in pack 'ext'" 513 | end 514 | buffer[#buffer+1] = data 515 | end 516 | 517 | function m.pack (data) 518 | local buffer = {} 519 | packers[type(data)](buffer, data) 520 | return tconcat(buffer) 521 | end 522 | 523 | 524 | local unpackers -- forward declaration 525 | 526 | local function unpack_cursor (c) 527 | local s, i, j = c.s, c.i, c.j 528 | if i > j then 529 | c:underflow(i) 530 | s, i, j = c.s, c.i, c.j 531 | end 532 | local val = s:sub(i, i):byte() 533 | c.i = i+1 534 | return unpackers[val](c, val) 535 | end 536 | m.unpack_cursor = unpack_cursor 537 | 538 | local function unpack_str (c, n) 539 | local s, i, j = c.s, c.i, c.j 540 | local e = i+n-1 541 | if e > j or n < 0 then 542 | c:underflow(e) 543 | s, i, j = c.s, c.i, c.j 544 | e = i+n-1 545 | end 546 | c.i = i+n 547 | return s:sub(i, e) 548 | end 549 | 550 | local function unpack_array (c, n) 551 | local t = {} 552 | for i = 1, n do 553 | t[i] = unpack_cursor(c) 554 | end 555 | return t 556 | end 557 | 558 | local function unpack_map (c, n) 559 | local t = {} 560 | for i = 1, n do 561 | local k = unpack_cursor(c) 562 | local val = unpack_cursor(c) 563 | if k == nil or k ~= k then 564 | k = m.sentinel 565 | end 566 | if k ~= nil then 567 | t[k] = val 568 | end 569 | end 570 | return t 571 | end 572 | 573 | local function unpack_float (c) 574 | local s, i, j = c.s, c.i, c.j 575 | if i+3 > j then 576 | c:underflow(i+3) 577 | s, i, j = c.s, c.i, c.j 578 | end 579 | local b1, b2, b3, b4 = s:sub(i, i+3):byte(1, 4) 580 | local sign = b1 > 0x7F 581 | local expo = (b1 % 0x80) * 0x2 + floor(b2 / 0x80) 582 | local mant = ((b2 % 0x80) * 0x100 + b3) * 0x100 + b4 583 | if sign then 584 | sign = -1 585 | else 586 | sign = 1 587 | end 588 | local n 589 | if mant == 0 and expo == 0 then 590 | n = sign * 0.0 591 | elseif expo == 0xFF then 592 | if mant == 0 then 593 | n = sign * huge 594 | else 595 | n = 0.0/0.0 596 | end 597 | else 598 | n = sign * ldexp(1.0 + mant / 0x800000, expo - 0x7F) 599 | end 600 | c.i = i+4 601 | return n 602 | end 603 | 604 | local function unpack_double (c) 605 | local s, i, j = c.s, c.i, c.j 606 | if i+7 > j then 607 | c:underflow(i+7) 608 | s, i, j = c.s, c.i, c.j 609 | end 610 | local b1, b2, b3, b4, b5, b6, b7, b8 = s:sub(i, i+7):byte(1, 8) 611 | local sign = b1 > 0x7F 612 | local expo = (b1 % 0x80) * 0x10 + floor(b2 / 0x10) 613 | local mant = ((((((b2 % 0x10) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8 614 | if sign then 615 | sign = -1 616 | else 617 | sign = 1 618 | end 619 | local n 620 | if mant == 0 and expo == 0 then 621 | n = sign * 0.0 622 | elseif expo == 0x7FF then 623 | if mant == 0 then 624 | n = sign * huge 625 | else 626 | n = 0.0/0.0 627 | end 628 | else 629 | n = sign * ldexp(1.0 + mant / 4503599627370496.0, expo - 0x3FF) 630 | end 631 | c.i = i+8 632 | return n 633 | end 634 | 635 | local function unpack_uint8 (c) 636 | local s, i, j = c.s, c.i, c.j 637 | if i > j then 638 | c:underflow(i) 639 | s, i, j = c.s, c.i, c.j 640 | end 641 | local b1 = s:sub(i, i):byte() 642 | c.i = i+1 643 | return b1 644 | end 645 | 646 | local function unpack_uint16 (c) 647 | local s, i, j = c.s, c.i, c.j 648 | if i+1 > j then 649 | c:underflow(i+1) 650 | s, i, j = c.s, c.i, c.j 651 | end 652 | local b1, b2 = s:sub(i, i+1):byte(1, 2) 653 | c.i = i+2 654 | return b1 * 0x100 + b2 655 | end 656 | 657 | local function unpack_uint32 (c) 658 | local s, i, j = c.s, c.i, c.j 659 | if i+3 > j then 660 | c:underflow(i+3) 661 | s, i, j = c.s, c.i, c.j 662 | end 663 | local b1, b2, b3, b4 = s:sub(i, i+3):byte(1, 4) 664 | c.i = i+4 665 | return ((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4 666 | end 667 | 668 | local function unpack_uint64 (c) 669 | local s, i, j = c.s, c.i, c.j 670 | if i+7 > j then 671 | c:underflow(i+7) 672 | s, i, j = c.s, c.i, c.j 673 | end 674 | local b1, b2, b3, b4, b5, b6, b7, b8 = s:sub(i, i+7):byte(1, 8) 675 | c.i = i+8 676 | return ((((((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8 677 | end 678 | 679 | local function unpack_int8 (c) 680 | local s, i, j = c.s, c.i, c.j 681 | if i > j then 682 | c:underflow(i) 683 | s, i, j = c.s, c.i, c.j 684 | end 685 | local b1 = s:sub(i, i):byte() 686 | c.i = i+1 687 | if b1 < 0x80 then 688 | return b1 689 | else 690 | return b1 - 0x100 691 | end 692 | end 693 | 694 | local function unpack_int16 (c) 695 | local s, i, j = c.s, c.i, c.j 696 | if i+1 > j then 697 | c:underflow(i+1) 698 | s, i, j = c.s, c.i, c.j 699 | end 700 | local b1, b2 = s:sub(i, i+1):byte(1, 2) 701 | c.i = i+2 702 | if b1 < 0x80 then 703 | return b1 * 0x100 + b2 704 | else 705 | return ((b1 - 0xFF) * 0x100 + (b2 - 0xFF)) - 1 706 | end 707 | end 708 | 709 | local function unpack_int32 (c) 710 | local s, i, j = c.s, c.i, c.j 711 | if i+3 > j then 712 | c:underflow(i+3) 713 | s, i, j = c.s, c.i, c.j 714 | end 715 | local b1, b2, b3, b4 = s:sub(i, i+3):byte(1, 4) 716 | c.i = i+4 717 | if b1 < 0x80 then 718 | return ((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4 719 | else 720 | return ((((b1 - 0xFF) * 0x100 + (b2 - 0xFF)) * 0x100 + (b3 - 0xFF)) * 0x100 + (b4 - 0xFF)) - 1 721 | end 722 | end 723 | 724 | local function unpack_int64 (c) 725 | local s, i, j = c.s, c.i, c.j 726 | if i+7 > j then 727 | c:underflow(i+7) 728 | s, i, j = c.s, c.i, c.j 729 | end 730 | local b1, b2, b3, b4, b5, b6, b7, b8 = s:sub(i, i+7):byte(1, 8) 731 | c.i = i+8 732 | if b1 < 0x80 then 733 | return ((((((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8 734 | else 735 | return ((((((((b1 - 0xFF) * 0x100 + (b2 - 0xFF)) * 0x100 + (b3 - 0xFF)) * 0x100 + (b4 - 0xFF)) * 0x100 + (b5 - 0xFF)) * 0x100 + (b6 - 0xFF)) * 0x100 + (b7 - 0xFF)) * 0x100 + (b8 - 0xFF)) - 1 736 | end 737 | end 738 | 739 | function m.build_ext (tag, data) 740 | return nil 741 | end 742 | 743 | local function unpack_ext (c, n, tag) 744 | local s, i, j = c.s, c.i, c.j 745 | local e = i+n-1 746 | if e > j or n < 0 then 747 | c:underflow(e) 748 | s, i, j = c.s, c.i, c.j 749 | e = i+n-1 750 | end 751 | c.i = i+n 752 | return m.build_ext(tag, s:sub(i, e)) 753 | end 754 | 755 | unpackers = setmetatable({ 756 | [0xC0] = function () return nil end, 757 | [0xC2] = function () return false end, 758 | [0xC3] = function () return true end, 759 | [0xC4] = function (c) return unpack_str(c, unpack_uint8(c)) end, -- bin8 760 | [0xC5] = function (c) return unpack_str(c, unpack_uint16(c)) end, -- bin16 761 | [0xC6] = function (c) return unpack_str(c, unpack_uint32(c)) end, -- bin32 762 | [0xC7] = function (c) return unpack_ext(c, unpack_uint8(c), unpack_int8(c)) end, 763 | [0xC8] = function (c) return unpack_ext(c, unpack_uint16(c), unpack_int8(c)) end, 764 | [0xC9] = function (c) return unpack_ext(c, unpack_uint32(c), unpack_int8(c)) end, 765 | [0xCA] = unpack_float, 766 | [0xCB] = unpack_double, 767 | [0xCC] = unpack_uint8, 768 | [0xCD] = unpack_uint16, 769 | [0xCE] = unpack_uint32, 770 | [0xCF] = unpack_uint64, 771 | [0xD0] = unpack_int8, 772 | [0xD1] = unpack_int16, 773 | [0xD2] = unpack_int32, 774 | [0xD3] = unpack_int64, 775 | [0xD4] = function (c) return unpack_ext(c, 1, unpack_int8(c)) end, 776 | [0xD5] = function (c) return unpack_ext(c, 2, unpack_int8(c)) end, 777 | [0xD6] = function (c) return unpack_ext(c, 4, unpack_int8(c)) end, 778 | [0xD7] = function (c) return unpack_ext(c, 8, unpack_int8(c)) end, 779 | [0xD8] = function (c) return unpack_ext(c, 16, unpack_int8(c)) end, 780 | [0xD9] = function (c) return unpack_str(c, unpack_uint8(c)) end, 781 | [0xDA] = function (c) return unpack_str(c, unpack_uint16(c)) end, 782 | [0xDB] = function (c) return unpack_str(c, unpack_uint32(c)) end, 783 | [0xDC] = function (c) return unpack_array(c, unpack_uint16(c)) end, 784 | [0xDD] = function (c) return unpack_array(c, unpack_uint32(c)) end, 785 | [0xDE] = function (c) return unpack_map(c, unpack_uint16(c)) end, 786 | [0xDF] = function (c) return unpack_map(c, unpack_uint32(c)) end, 787 | }, { 788 | __index = function (t, k) 789 | if k < 0xC0 then 790 | if k < 0x80 then 791 | return function (c, val) return val end 792 | elseif k < 0x90 then 793 | return function (c, val) return unpack_map(c, val % 0x10) end 794 | elseif k < 0xA0 then 795 | return function (c, val) return unpack_array(c, val % 0x10) end 796 | else 797 | return function (c, val) return unpack_str(c, val % 0x20) end 798 | end 799 | elseif k > 0xDF then 800 | return function (c, val) return val - 0x100 end 801 | else 802 | return function () error("unpack '" .. format('%#x', k) .. "' is unimplemented") end 803 | end 804 | end 805 | }) 806 | 807 | local function cursor_string (str) 808 | return { 809 | s = str, 810 | i = 1, 811 | j = #str, 812 | underflow = function () 813 | error "missing bytes" 814 | end, 815 | } 816 | end 817 | 818 | local function cursor_loader (ld) 819 | return { 820 | s = '', 821 | i = 1, 822 | j = 0, 823 | underflow = function (self, e) 824 | self.s = self.s:sub(self.i) 825 | e = e - self.i + 1 826 | self.i = 1 827 | self.j = 0 828 | while e > self.j do 829 | local chunk = ld() 830 | if not chunk then 831 | error "missing bytes" 832 | end 833 | self.s = self.s .. chunk 834 | self.j = #self.s 835 | end 836 | end, 837 | } 838 | end 839 | 840 | function m.unpack (s) 841 | checktype('unpack', 1, s, 'string') 842 | local cursor = cursor_string(s) 843 | local data = unpack_cursor(cursor) 844 | if cursor.i <= cursor.j then 845 | error "extra bytes" 846 | end 847 | return data 848 | end 849 | 850 | function m.unpacker (src) 851 | if type(src) == 'string' then 852 | local cursor = cursor_string(src) 853 | return function () 854 | if cursor.i <= cursor.j then 855 | return cursor.i, unpack_cursor(cursor) 856 | end 857 | end 858 | elseif type(src) == 'function' then 859 | local cursor = cursor_loader(src) 860 | return function () 861 | if cursor.i > cursor.j then 862 | pcall(cursor.underflow, cursor, cursor.i) 863 | end 864 | if cursor.i <= cursor.j then 865 | return true, unpack_cursor(cursor) 866 | end 867 | end 868 | else 869 | argerror('unpacker', 1, "string or function expected, got " .. type(src)) 870 | end 871 | end 872 | 873 | set_string'string_compat' 874 | set_integer'unsigned' 875 | if SIZEOF_NUMBER == 4 then 876 | maxinteger = 16777215 877 | mininteger = -maxinteger 878 | m.small_lua = true 879 | unpackers[0xCB] = nil -- double 880 | unpackers[0xCF] = nil -- uint64 881 | unpackers[0xD3] = nil -- int64 882 | set_number'float' 883 | else 884 | maxinteger = 9007199254740991 885 | mininteger = -maxinteger 886 | set_number'double' 887 | if SIZEOF_NUMBER > 8 then 888 | m.long_double = true 889 | end 890 | end 891 | set_array'without_hole' 892 | 893 | m._VERSION = '0.5.0' 894 | m._DESCRIPTION = "lua-MessagePack : a pure Lua implementation" 895 | m._COPYRIGHT = "Copyright (c) 2012-2017 Francois Perrad" 896 | return m 897 | -- 898 | -- This library is licensed under the terms of the MIT/X11 license, 899 | -- like Lua itself. 900 | -- 901 | -------------------------------------------------------------------------------- /lua/miniyank.lua: -------------------------------------------------------------------------------- 1 | local mp = require"MessagePack" 2 | --inspect = require"inspect" 3 | mp.set_string('binary') 4 | 5 | local function lua2vim(t) 6 | if type(t) ~= "table" then 7 | return t 8 | end 9 | local l = vim.list() 10 | for _,v in ipairs(t) do 11 | l:add(lua2vim(v)) 12 | end 13 | return l 14 | end 15 | local list_t = getmetatable(vim.list()) 16 | local function vim2lua(l) 17 | if getmetatable(l) ~= list_t then 18 | return l 19 | end 20 | local t = {} 21 | for v in l() do 22 | t[#t+1] = vim2lua(v) 23 | end 24 | return t 25 | end 26 | 27 | local function read(fn) 28 | local file = io.open(fn, 'rb') 29 | data = file:read('*all') 30 | res = vim.list() 31 | for p,item in mp .unpacker(data) do 32 | x = item 33 | res:add(lua2vim(item)) 34 | end 35 | file:close() 36 | return res 37 | end 38 | local function write(fn,data) 39 | local file = io.open(fn, 'wb') 40 | for item in data() do 41 | file:write(mp.pack(vim2lua(item))) 42 | end 43 | file:close() 44 | end 45 | 46 | return {read=read,write=write} 47 | -------------------------------------------------------------------------------- /plugin/miniyank.vim: -------------------------------------------------------------------------------- 1 | if !exists('##TextYankPost') 2 | finish 3 | endif 4 | 5 | if !has("nvim") && !has("lua") 6 | echoerr "miniyank requires lua in vim 8" 7 | finish 8 | endif 9 | 10 | if !has_key(g:,"miniyank_filename") 11 | if exists('$XDG_RUNTIME_DIR') 12 | let g:miniyank_filename = $XDG_RUNTIME_DIR."/miniyank.mpack" 13 | elseif exists('*stdpath') 14 | call mkdir(stdpath('cache'), 'p') 15 | let g:miniyank_filename = stdpath('cache')."/miniyank.mpack" 16 | else 17 | let g:miniyank_filename = "/tmp/".$USER."_miniyank.mpack" 18 | endif 19 | endif 20 | 21 | if !has_key(g:,"miniyank_maxitems") 22 | let g:miniyank_maxitems = 10 23 | endif 24 | 25 | if !has_key(g:,"miniyank_delete_maxlines") 26 | let g:miniyank_delete_maxlines = 1000 27 | endif 28 | 29 | augroup MiniYank 30 | au! TextYankPost * call miniyank#on_yank(copy(v:event)) 31 | augroup END 32 | 33 | noremap (miniyank-startput) miniyank#startput("p",0) 34 | noremap (miniyank-startPut) miniyank#startput("P",0) 35 | noremap (miniyank-autoput) miniyank#startput("p",1) 36 | noremap (miniyank-autoPut) miniyank#startput("P",1) 37 | noremap (miniyank-cycle) :call miniyank#cycle(1) 38 | noremap (miniyank-cycleback) :call miniyank#cycle(-1) 39 | 40 | noremap (miniyank-tochar) :call miniyank#force_motion('v') 41 | noremap (miniyank-toline) :call miniyank#force_motion('V') 42 | noremap (miniyank-toblock) :call miniyank#force_motion('b') 43 | -------------------------------------------------------------------------------- /rplugin/python3/denite/kind/miniyank.py: -------------------------------------------------------------------------------- 1 | from .base import Base 2 | from denite.util import debug 3 | 4 | class Kind(Base): 5 | 6 | def __init__(self, vim): 7 | Base.__init__(self, vim) 8 | 9 | self.name = 'miniyank' 10 | self.default_action = "put" 11 | 12 | def action_put(self, context): 13 | target = context['targets'][0] 14 | data = target['action__data'] 15 | data = self.vim.call("miniyank#drop", data, 'p') 16 | 17 | def action_Put(self, context): 18 | target = context['targets'][0] 19 | data = target['action__data'] 20 | data = self.vim.call("miniyank#drop", data, 'P') 21 | 22 | def action_delete(self, context): 23 | indexes = [x['action__index'] for x in context['targets']] 24 | indexes.sort(reverse=True) 25 | data = self.vim.call('miniyank#read') 26 | for x in indexes: 27 | del data[x] 28 | self.vim.call('miniyank#write', data) 29 | debug(self.vim, f'[miniyank] {len(indexes)} item(s) deleted') 30 | -------------------------------------------------------------------------------- /rplugin/python3/denite/source/miniyank.py: -------------------------------------------------------------------------------- 1 | from .base import Base 2 | 3 | class Source(Base): 4 | 5 | def __init__(self, vim): 6 | Base.__init__(self, vim) 7 | 8 | self.name = 'miniyank' 9 | self.kind = 'miniyank' 10 | 11 | def on_init(self, context): 12 | pass 13 | 14 | 15 | def gather_candidates(self, context): 16 | data = self.vim.call("miniyank#read") 17 | return [ 18 | {'word': '\\n'.join(d[0]), 'action__data': d, 'action__index': i} 19 | for i, d in enumerate(data) 20 | ] 21 | --------------------------------------------------------------------------------