├── LICENSE ├── README.md ├── autoload ├── operator │ └── flashy.vim ├── vital.vim └── vital │ ├── _operator_flashy.vim │ ├── _operator_flashy │ ├── Coaster │ │ ├── Buffer.vim │ │ ├── Buffer │ │ │ └── Object.vim │ │ ├── Highlight.vim │ │ ├── Search.vim │ │ └── Window.vim │ ├── Data │ │ ├── Dict.vim │ │ └── List.vim │ ├── Gift.vim │ ├── Gift │ │ ├── Tabpage.vim │ │ └── Window.vim │ ├── Prelude.vim │ └── Vim │ │ ├── Buffer.vim │ │ └── Guard.vim │ ├── operator_flashy.vim │ └── operator_flashy.vital ├── doc └── operator-flashy.txt └── plugin └── operator └── flashy.vim /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015 haya14busa 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 17 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 20 | THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | :flashlight: vim-operator-flashy: Highlight yanked area 2 | ======================================================= 3 | 4 | [![](http://img.shields.io/github/tag/haya14busa/vim-operator-flashy.svg)](https://github.com/haya14busa/vim-operator-flashy/releases) 5 | [![](http://img.shields.io/github/issues/haya14busa/vim-operator-flashy.svg)](https://github.com/haya14busa/vim-operator-flashy/issues) 6 | [![](http://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) 7 | [![](https://img.shields.io/badge/doc-%3Ah%20operator--flashy.txt-red.svg)](doc/operator-flashy.txt) 8 | 9 | :flashlight: Introduction :flashlight: 10 | -------------------------------------- 11 | 12 | Flash yanked area :flashlight: 13 | 14 | ![i/flashy_key.gif at f04722bfb519570aea79903d976c642e9099606c · haya14busa/i](https://github.com/haya14busa/i/blob/f04722bfb519570aea79903d976c642e9099606c/vim-operator-flashy/flashy_key.gif) 15 | 16 | You can confirm that text is yanked correctly and see yanked text by highlighting. 17 | 18 | :heavy_check_mark: Dependency :heavy_check_mark: 19 | ------------------------------------------------ 20 | 21 | This plugin depends on [kana/vim-operator-user](https://github.com/kana/vim-operator-user). Please install it in advance. 22 | 23 | :package: Installation :package: 24 | -------------------------------- 25 | 26 | Install with your favorite plugin managers like [Neobundle](https://github.com/Shougo/neobundle.vim) / [Vundle](https://github.com/gmarik/Vundle.vim) / [vim-plug](https://github.com/junegunn/vim-plug) 27 | 28 | ```vim 29 | NeoBundle 'kana/vim-operator-user' 30 | NeoBundle 'haya14busa/vim-operator-flashy' 31 | 32 | Plugin 'kana/vim-operator-user' 33 | Plugin 'haya14busa/vim-operator-flashy' 34 | 35 | Plug 'kana/vim-operator-user' 36 | Plug 'haya14busa/vim-operator-flashy' 37 | ``` 38 | 39 | [pathogen](https://github.com/tpope/vim-pathogen) 40 | 41 | ``` 42 | git clone https://github.com/kana/vim-operator-user ~/.vim/bundle/vim-operator-user 43 | git clone https://github.com/haya14busa/vim-operator-flashy ~/.vim/bundle/vim-operator-flashy 44 | ``` 45 | 46 | :tada: Usage :tada: 47 | ------------------- 48 | 49 | ```vim 50 | map y (operator-flashy) 51 | nmap Y (operator-flashy)$ 52 | ``` 53 | 54 | :bird: Author :bird: 55 | -------------------- 56 | haya14busa (https://github.com/haya14busa) 57 | 58 | :orange_book: Documentation :orange_book: 59 | ----------------------------------------- 60 | 61 | [**:h operator-flashy.txt**](./doc/operator-flashy.txt) 62 | -------------------------------------------------------------------------------- /autoload/operator/flashy.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " FILE: autoload/operator/flashy.vim 3 | " AUTHOR: haya14busa 4 | " License: MIT license 5 | "============================================================================= 6 | scriptencoding utf-8 7 | let s:save_cpo = &cpo 8 | set cpo&vim 9 | 10 | let s:V = vital#of('operator_flashy') 11 | let s:Highlight = s:V.import('Coaster.Highlight') 12 | let s:Search = s:V.import('Coaster.Search') 13 | 14 | let g:operator#flashy#group = get(g:, 'operator#flashy#group', 'Flashy') 15 | let g:operator#flashy#flash_time = get(g:, 'operator#flashy#flash_time', 100) 16 | 17 | function! s:init_hl() abort 18 | highlight default Flashy term=bold ctermbg=0 guibg=#13354A 19 | if hlexists('Cursor') 20 | highlight default link FlashyCursor Cursor 21 | else 22 | highlight default FlashyCursor term=reverse cterm=reverse gui=reverse 23 | endif 24 | endfunction 25 | 26 | call s:init_hl() 27 | 28 | augroup plugin-flashy-highlight 29 | autocmd! 30 | autocmd ColorScheme * call s:init_hl() 31 | augroup END 32 | 33 | " operator#flashy#do() yanks text with flash in normal mode. 34 | " It assumes not to provide mappings for visual mode. 35 | " @param {'char'|'line'|'block'} wise 36 | function! operator#flashy#do(wise) abort 37 | if s:is_empty_region() 38 | return 39 | endif 40 | 41 | " Save cursor position for linewise motion like 'yj'. 42 | if a:wise is# 'line' 43 | let w = winsaveview() 44 | endif 45 | 46 | let visual_command = operator#user#visual_command_from_wise_name(a:wise) 47 | let start = [line("'["), virtcol("'[")] 48 | let end = [line("']"), virtcol("']")] 49 | let pattern = s:Search.pattern_by_range(visual_command, start, end) 50 | " Call s:yank() first to show information while flashing. 51 | " e.g. 14lines yanked 52 | call s:yank(visual_command) 53 | call s:flash(pattern, g:operator#flashy#flash_time) 54 | 55 | " Restore cursor position for linewise motion like 'yj'. 56 | if a:wise is# 'line' 57 | call winrestview(w) 58 | endif 59 | endfunction 60 | 61 | " o_y() keeps cursor position for linewise motion like 'yy'. 62 | " Example: 63 | " onoremap y operator#flashy#o_y() 64 | function! operator#flashy#o_y() abort 65 | let cursor = getpos('.') 66 | let yank = "\\"" . operator#user#register() . v:count1 . 'yy' 67 | return printf("%s:call operator#flashy#_o_y(%s)\", yank, string(cursor)) 68 | endfunction 69 | 70 | function! operator#flashy#_o_y(cursor_pos) abort 71 | call setpos('.', a:cursor_pos) 72 | let pattern = printf('\%%%dl\_.*\%%%dl', line("'["), line("']")) 73 | " Turn off cursorline temporalily because redraw of highlight line with 74 | " cursorline is too slow in large file. 75 | " ref: https://github.com/haya14busa/vim-operator-flashy/issues/5 76 | let cursorline_save = &cursorline 77 | let &cursorline = 0 78 | try 79 | call s:flash(pattern, g:operator#flashy#flash_time) 80 | finally 81 | let &cursorline = cursorline_save 82 | endtry 83 | endfunction 84 | 85 | function! s:flash(pattern, time) abort 86 | try 87 | call s:highlight_cursor() 88 | call s:highlight_yanked_region(a:pattern) 89 | redraw 90 | call s:sleep(a:time) 91 | finally 92 | call s:clear() 93 | endtry 94 | endfunction 95 | 96 | function! s:sleep(ms) abort 97 | let t = reltime() 98 | while !getchar(1) && a:ms - str2float(reltimestr(reltime(t))) * 1000.0 > 0 99 | endwhile 100 | endfunction 101 | 102 | function! s:highlight_cursor() abort 103 | " Do not highlight cursor if the character under cursor is Tab character 104 | " because it has more than one width and the cursor highlight will be 105 | " ugly. 106 | if s:get_cursor_char() isnot# "\t" 107 | call s:Highlight.highlight('FlashyCursor', 'FlashyCursor', '\%#', 11) 108 | endif 109 | endfunction 110 | 111 | function! s:get_cursor_char() abort 112 | return getline('.')[col('.')-1] 113 | endfunction 114 | 115 | function! s:highlight_yanked_region(pattern) abort 116 | call s:Highlight.highlight('YankRegion', g:operator#flashy#group, a:pattern, 10) 117 | endfunction 118 | 119 | function! s:clear() abort 120 | call s:Highlight.clear('FlashyCursor') 121 | call s:Highlight.clear('YankRegion') 122 | endfunction 123 | 124 | function! s:yank(visual_command) abort 125 | let reg = operator#user#register() 126 | execute 'normal!' '`["' . reg . 'y' . a:visual_command . '`]"' 127 | endfunction 128 | 129 | " :h cpo-E 130 | function! s:is_empty_region() abort 131 | return line("'[") is# line("']") + 1 132 | endfunction 133 | 134 | let &cpo = s:save_cpo 135 | unlet s:save_cpo 136 | " __END__ 137 | " vim: expandtab softtabstop=2 shiftwidth=2 foldmethod=marker 138 | -------------------------------------------------------------------------------- /autoload/vital.vim: -------------------------------------------------------------------------------- 1 | function! vital#of(name) abort 2 | let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital', 1) 3 | let file = split(files, "\n") 4 | if empty(file) 5 | throw 'vital: version file not found: ' . a:name 6 | endif 7 | let ver = readfile(file[0], 'b') 8 | if empty(ver) 9 | throw 'vital: invalid version file: ' . a:name 10 | endif 11 | return vital#_{substitute(ver[0], '\W', '', 'g')}#new() 12 | endfunction 13 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy.vim: -------------------------------------------------------------------------------- 1 | let s:_plugin_name = expand(':t:r') 2 | 3 | function! vital#{s:_plugin_name}#new() abort 4 | return vital#{s:_plugin_name[1:]}#of() 5 | endfunction 6 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Coaster/Buffer.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Coaster#Buffer#import() abort 6 | return map({'get_text_line_from_lnum': '', 'setbufline': '', 'pos_less_equal': '', 'execute': '', 'get_line_from_region': '', 'open': '', 'delete': '', 'get_block_from_region': '', 'new': '', 'paste': '', '_vital_depends': '', 'setbufline_if_python': '', 'get_text_from_latest_yank': '', 'get': '', 'get_text_from_region': '', 'as_wise_key': '', 'yank': '', 'get_line_from_pos': '', 'current': '', 'get_region_from_textobj': '', 'get_text_from_pattern': '', 'get_char_from_region': '', 'paste_for_text': '', '_vital_loaded': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Coaster#Buffer#import() abort', printf("return map({'get_text_line_from_lnum': '', 'setbufline': '', 'pos_less_equal': '', 'execute': '', 'get_line_from_region': '', 'open': '', 'delete': '', 'get_block_from_region': '', 'new': '', 'paste': '', '_vital_depends': '', 'setbufline_if_python': '', 'get_text_from_latest_yank': '', 'get': '', 'get_text_from_region': '', 'as_wise_key': '', 'yank': '', 'get_line_from_pos': '', 'current': '', 'get_region_from_textobj': '', 'get_text_from_pattern': '', 'get_char_from_region': '', 'paste_for_text': '', '_vital_loaded': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | scriptencoding utf-8 17 | let s:save_cpo = &cpo 18 | set cpo&vim 19 | 20 | 21 | 22 | function! s:_vital_loaded(V) 23 | let s:V = a:V 24 | let s:Search = a:V.import("Coaster.Search") 25 | let s:Object = a:V.import("Coaster.Buffer.Object") 26 | endfunction 27 | 28 | 29 | function! s:_vital_depends() 30 | return [ 31 | \ "Coaster.Search", 32 | \ "Coaster.Buffer.Object" 33 | \ ] 34 | endfunction 35 | 36 | 37 | " a <= b 38 | function! s:pos_less_equal(a, b) 39 | return a:a[0] == a:b[0] ? a:a[1] <= a:b[1] : a:a[0] <= a:b[0] 40 | endfunction 41 | 42 | 43 | function! s:as_wise_key(name) 44 | return a:name ==# "char" ? "v" 45 | \ : a:name ==# "line" ? "V" 46 | \ : a:name ==# "block" ? "\" 47 | \ : a:name 48 | endfunction 49 | 50 | 51 | function! s:get_text_from_latest_yank(...) 52 | if mode() != "n" 53 | return 54 | endif 55 | 56 | let wise = get(a:, 1, "v") 57 | let register = v:register == "" ? '"' : v:register 58 | 59 | let old_selection = &selection 60 | let &selection = 'inclusive' 61 | let old_pos = getpos(".") 62 | let old_reg = getreg(register) 63 | try 64 | execute printf('silent normal! `[%s`]y', wise) 65 | return getreg(register) 66 | finally 67 | let &selection = old_selection 68 | call setreg(register, old_reg) 69 | call cursor(old_pos[1], old_pos[2]) 70 | endtry 71 | endfunction 72 | 73 | 74 | function! s:get_line_from_pos(pos) 75 | return a:pos[0] == 0 ? getline(a:pos[1]) : getbufline(a:pos[0], a:pos[1]) 76 | endfunction 77 | 78 | 79 | function! s:get_line_from_region(first, last) 80 | if type(a:first) == type(0) 81 | return s:get_line_from_region([0, a:first, 0, 0], a:last) 82 | elseif type(a:last) == type(0) 83 | return s:get_line_from_region(a:first, [0, a:last, 0, 0]) 84 | endif 85 | if a:first[0] != 0 && a:first[0] == a:last[0] 86 | return join(getbufline(a:first[0], a:first[1], a:last[1]), "\n") 87 | endif 88 | return join(getline(a:first[1], a:last[1]), "\n") 89 | endfunction 90 | 91 | 92 | function! s:yank(wise, first, last) 93 | let old_view = winsaveview() 94 | let old_selection = &selection 95 | let &selection = 'inclusive' 96 | let old_first = getpos("'[") 97 | let old_last = getpos("']") 98 | let old_pos = getpos(".") 99 | try 100 | call s:_setpos("'[", a:first) 101 | call s:_setpos("']", a:last) 102 | execute "normal! `[" . a:wise . "`]y" 103 | finally 104 | call s:_setpos("'[", old_first) 105 | call s:_setpos("']", old_last) 106 | let &selection = old_selection 107 | call winrestview(old_view) 108 | call s:_setpos(".", old_pos) 109 | endtry 110 | endfunction 111 | 112 | 113 | function! s:delete(wise, first, last) 114 | let old_view = winsaveview() 115 | let old_selection = &selection 116 | let &selection = 'inclusive' 117 | let old_first = getpos("'[") 118 | let old_last = getpos("']") 119 | let old_pos = getpos(".") 120 | try 121 | call s:_setpos("'[", a:first) 122 | call s:_setpos("']", a:last) 123 | execute printf('normal! `[%s`]"_d', a:wise) 124 | finally 125 | call s:_setpos("'[", old_first) 126 | call s:_setpos("']", old_last) 127 | let &selection = old_selection 128 | call winrestview(old_view) 129 | call s:_setpos(".", old_pos) 130 | endtry 131 | endfunction 132 | 133 | 134 | function! s:_as_pos(pos) 135 | return len(a:list) == 2 ? [0] + a:pos + [0] : a:pos 136 | endfunction 137 | 138 | 139 | function! s:_setpos(expr, list) 140 | if len(a:list) == 2 141 | return s:_setpos(a:expr, [0] + a:list + [0]) 142 | endif 143 | return setpos(a:expr, a:list) 144 | endfunction 145 | 146 | 147 | function! s:paste(wise, first, last, register) 148 | let old_view = winsaveview() 149 | let old_selection = &selection 150 | let &selection = 'inclusive' 151 | let old_first = getpos("'[") 152 | let old_last = getpos("']") 153 | let old_pos = getpos(".") 154 | try 155 | call s:_setpos("'[", a:first) 156 | call s:_setpos("']", a:last) 157 | execute printf('normal! `[%s`]"%sp', a:wise, a:register) 158 | finally 159 | call s:_setpos("'[", old_first) 160 | call s:_setpos("']", old_last) 161 | let &selection = old_selection 162 | call winrestview(old_view) 163 | call s:_setpos(".", old_pos) 164 | endtry 165 | endfunction 166 | 167 | 168 | function! s:paste_for_text(wise, first, last, text) 169 | let old = @a 170 | try 171 | let @a = a:text 172 | return s:paste(a:wise, a:first, a:last, "a") 173 | finally 174 | let @a = old 175 | endtry 176 | endfunction 177 | 178 | 179 | 180 | function! s:get_text_line_from_lnum(first, last) 181 | return join(getline(a:first, a:last), "\n") 182 | endfunction 183 | 184 | 185 | " function! s:get_text_line_from_region(first, last) 186 | " " if type(a:first) == type([]) 187 | " " return s:get_text_line_from_region(a:first[1], a:last) 188 | " " elseif type(a:last) == type([]) 189 | " " return s:get_text_line_from_region(a:first, a:last[1]) 190 | " " endif 191 | " " return join(getline(a:first, a:last), "\n") 192 | " 193 | " return s:get_text_line_from_lnum(a:first[1], a:last[1]) 194 | " endfunction 195 | 196 | 197 | function! s:get_char_from_region(first, last) 198 | if a:first[1] == a:last[1] 199 | return getline(a:first[1])[a:first[2] - 1 : a:last[2] - 1] 200 | elseif (a:last[1] - a:first[1]) == 1 201 | return getline(a:first[1])[ a:first[2] - 1 : ] . "\n" 202 | \ . getline(a:last[1])[ : a:last[2] - 1] 203 | else 204 | return getline(a:first[1])[ a:first[2] - 1 : ] . "\n" 205 | \ . s:get_text_line_from_lnum(a:first[1] + 1, a:last[1] - 1) . "\n" 206 | \ . getline(a:last[1])[ : a:last[2] - 1] 207 | endif 208 | endfunction 209 | 210 | 211 | function! s:get_block_from_region(first, last) 212 | let first = a:first 213 | let last = a:last 214 | return join(map(range(a:first[1], a:last[1]), "s:get_char_from_region([first[0], v:val, first[2], first[3]], [last[0], v:val, last[2], last[3]])"), "\n") 215 | endfunction 216 | 217 | 218 | function! s:get_text_from_region(first, last, ...) 219 | let wise = get(a:, 1, "v") 220 | if wise ==# "v" 221 | return s:get_char_from_region(a:first, a:last) 222 | elseif wise ==# "V" 223 | return s:get_line_from_region(a:first, a:last) 224 | elseif wise ==# "\" 225 | return s:get_block_from_region(a:first, a:last) 226 | endif 227 | endfunction 228 | 229 | 230 | function! s:get_text_from_pattern(pattern) 231 | let [first, last] = s:Search.region(a:pattern, "Wncb", "Wnce") 232 | if first == [0, 0] 233 | return "" 234 | endif 235 | if last == [0, 0] 236 | return "" 237 | endif 238 | let result = s:get_text_from_region([0] + first + [0], [0] + last + [0], "v") 239 | if result !~ '^' . a:pattern . '$' 240 | return "" 241 | endif 242 | return result 243 | endfunction 244 | 245 | 246 | function! s:_as_config(config) 247 | let default = { 248 | \ "textobj" : "", 249 | \ "is_cursor_in" : 0, 250 | \ "noremap" : 0, 251 | \ } 252 | let config 253 | \ = type(a:config) == type("") ? { "textobj" : a:config } 254 | \ : type(a:config) == type({}) ? a:config 255 | \ : {} 256 | return extend(default, config) 257 | endfunction 258 | 259 | 260 | let s:region = [] 261 | let s:wise = "" 262 | function! s:_buffer_region_operator(wise) 263 | let reg_save = @@ 264 | let s:wise = a:wise 265 | let s:region = [getpos("'[")[1:], getpos("']")[1:]] 266 | let @@ = reg_save 267 | endfunction 268 | 269 | nnoremap (vital-coaster_buffer_region) 270 | \ :set operatorfunc=_buffer_region_operatorg@ 271 | 272 | 273 | function! s:get_region_from_textobj(textobj) 274 | let s:region = [] 275 | let config = s:_as_config(a:textobj) 276 | 277 | let winview = winsaveview() 278 | let pos = getpos(".") 279 | try 280 | silent execute (config.noremap ? 'onoremap' : 'omap') '' 281 | \ '(vital-coaster_buffer_region-target)' string(config.textobj) 282 | 283 | let tmp = &operatorfunc 284 | silent execute "normal \(vital-coaster_buffer_region)\(vital-coaster_buffer_region-target)" 285 | let &operatorfunc = tmp 286 | 287 | if !empty(s:region) && !s:pos_less_equal(s:region[0], s:region[1]) 288 | return ["", []] 289 | endif 290 | if !empty(s:region) && config.is_cursor_in && (s:pos_less(pos[1:], s:region[0]) || s:pos_less(s:region[1], pos[1:])) 291 | return ["", []] 292 | endif 293 | return deepcopy([s:wise, s:region]) 294 | finally 295 | call winrestview(winview) 296 | call cursor(pos[1], pos[2]) 297 | endtry 298 | endfunction 299 | 300 | 301 | function! s:get(bufnr) 302 | return s:Object.make(a:bufnr) 303 | endfunction 304 | 305 | 306 | " function! s:make(expr) 307 | " let buffer = s:get(a:expr) 308 | " if buffer.is_exists() 309 | " return buffer 310 | " endif 311 | " return s:new("", type(a:expr) == type("") ? a:expr : "") 312 | " endfunction 313 | 314 | 315 | function! s:current() 316 | return s:get(bufnr("%")) 317 | endfunction 318 | 319 | 320 | function! s:new(...) 321 | let name = get(a:, 1, "") 322 | execute "new" name 323 | let buffer = s:current() 324 | quit 325 | return buffer 326 | endfunction 327 | 328 | 329 | function! s:open(cmd) 330 | let buffer = s:new() 331 | call buffer.open(a:cmd) 332 | return buffer 333 | endfunction 334 | 335 | 336 | function! s:execute(expr, cmd) 337 | return s:get(a:expr).execute(a:cmd) 338 | endfunction 339 | 340 | 341 | function! s:setbufline_if_python(expr, lnum, text) 342 | if len(getbufline(a:expr, 1, "$")) < a:lnum - 1 343 | return 344 | endif 345 | let list = type(a:text) == type([]) ? a:text : [a:text] 346 | python import vim 347 | py vim.buffers[int(vim.eval('a:expr'))][int(vim.eval("a:lnum")) - 1 : int(vim.eval("a:lnum")) - 1 + len(vim.eval("list"))] = vim.eval("list") 348 | endfunction 349 | 350 | 351 | function! s:setbufline(expr, lnum, text) 352 | return s:get(a:expr).setline(a:lnum, a:text) 353 | endfunction 354 | 355 | 356 | let &cpo = s:save_cpo 357 | unlet s:save_cpo 358 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Coaster/Buffer/Object.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Coaster#Buffer#Object#import() abort 6 | return map({'make': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Coaster#Buffer#Object#import() abort', printf("return map({'make': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | scriptencoding utf-8 17 | let s:save_cpo = &cpo 18 | set cpo&vim 19 | 20 | 21 | let s:obj = { 22 | \ "__variable" : {} 23 | \} 24 | 25 | 26 | function! s:obj.number() 27 | return self.__variable.bufnr 28 | endfunction 29 | 30 | 31 | function! s:obj.invoke(func, ...) 32 | let args = get(a:, 1, []) 33 | return call(a:func, [self.number()] + args) 34 | endfunction 35 | 36 | 37 | function! s:obj.name() 38 | return self.invoke("bufname") 39 | endfunction 40 | 41 | 42 | function! s:obj.get_variable(...) 43 | return self.invoke("getbufvar", a:000) 44 | endfunction 45 | 46 | 47 | function! s:obj.set_variable(...) 48 | return self.invoke("setbufvar", a:000) 49 | endfunction 50 | 51 | 52 | function! s:obj.get_option(name) 53 | return self.get_variable("&" . a:name) 54 | endfunction 55 | 56 | 57 | function! s:obj.set_option(name, var) 58 | return self.set_variable("&" . a:name, a:var) 59 | endfunction 60 | 61 | 62 | function! s:obj.winnr() 63 | return self.invoke("bufwinnr") 64 | endfunction 65 | 66 | 67 | function! s:obj.is_exists() 68 | return bufexists(self.number()) 69 | endfunction 70 | 71 | 72 | function! s:obj.is_listed() 73 | return self.invoke("buflisted") 74 | endfunction 75 | 76 | 77 | function! s:obj.is_loaded() 78 | return self.invoke("bufloaded") 79 | endfunction 80 | 81 | 82 | function! s:obj.is_current() 83 | return self.number() == bufnr("%") 84 | endfunction 85 | 86 | 87 | function! s:obj.is_modifiable() 88 | return self.get_option("modifiable") 89 | endfunction 90 | 91 | 92 | function! s:obj.is_opened_in_current_tabpage() 93 | return self.winnr() != -1 94 | endfunction 95 | 96 | 97 | function! s:obj.tap() 98 | if !self.is_exists() || self.is_tapped() 99 | return 100 | endif 101 | let self.__variable.tap_bufnr = bufnr("%") 102 | split 103 | execute "b" self.number() 104 | return self.number() 105 | endfunction 106 | 107 | 108 | function! s:obj.untap() 109 | if !self.is_tapped() 110 | return 111 | endif 112 | quit 113 | silent! execute "buffer" self.__variable.tap_bufnr 114 | unlet self.__variable.tap_bufnr 115 | return self.number() 116 | endfunction 117 | 118 | 119 | function! s:obj.tap_modifiable(...) 120 | let force = get(a:, 1, 1) 121 | if !(self.is_modifiable() || force) 122 | return 123 | endif 124 | let result = self.tap() 125 | if result 126 | let self.__variable.modifiable = &modifiable 127 | set modifiable 128 | endif 129 | return result 130 | endfunction 131 | 132 | 133 | function! s:obj.untap_modifiable() 134 | if has_key(self.__variable, "modifiable") 135 | let &modifiable = self.__variable.modifiable 136 | unlet self.__variable.modifiable 137 | call self.untap() 138 | endif 139 | endfunction 140 | 141 | 142 | function! s:obj.is_tapped() 143 | return has_key(self.__variable, "tap_bufnr") 144 | endfunction 145 | 146 | 147 | function! s:obj.execute(cmd) 148 | if self.is_current() 149 | execute a:cmd 150 | return 151 | endif 152 | if self.tap() 153 | try 154 | execute a:cmd 155 | finally 156 | call self.untap() 157 | endtry 158 | endif 159 | 160 | " let view = winsaveview() 161 | " try 162 | " noautocmd silent! execute "bufdo if bufnr('%') == " a:expr . ' | ' . string(a:cmd) . ' | endif' 163 | " finally 164 | " noautocmd silent! execute "buffer" bufnr 165 | " call winrestview(view) 166 | " endtry 167 | endfunction 168 | 169 | 170 | function! s:obj.setline(lnum, text, ...) 171 | " if has("python") 172 | " return s:setbufline_if_python(a:expr, a:lnum, a:text) 173 | " else 174 | " return s:execute(bufnr(a:expr), "call setline(" . a:lnum . "," . string(a:text) . ")") 175 | " endif 176 | 177 | let force = get(a:, 1, 0) 178 | if self.tap_modifiable(force) 179 | try 180 | call setline(a:lnum, a:text) 181 | finally 182 | call self.untap_modifiable() 183 | endtry 184 | endif 185 | " return self.execute("call setline(" . a:lnum . "," . string(a:text) . ")") 186 | endfunction 187 | 188 | 189 | function! s:obj.clear(...) 190 | let force = get(a:, 1, 0) 191 | if self.tap_modifiable(force) 192 | try 193 | silent % delete _ 194 | finally 195 | call self.untap_modifiable() 196 | endtry 197 | endif 198 | endfunction 199 | 200 | 201 | function! s:obj.getline(...) 202 | return self.invoke("getbufline", a:000) 203 | endfunction 204 | 205 | 206 | function! s:obj.open(...) 207 | let open_cmd = get(a:, 1, "") 208 | execute open_cmd 209 | execute "buffer" self.number() 210 | endfunction 211 | 212 | 213 | function! s:obj.delete(...) 214 | let force = get(a:, 1, 0) 215 | if self.is_exists() 216 | try 217 | execute "bdelete" . (force ? "! " : " ") . self.number() 218 | return 0 219 | catch 220 | return -1 221 | endtry 222 | endif 223 | endfunction 224 | 225 | 226 | function! s:obj.set_name(name) 227 | return self.execute(":file " . string(a:name)) 228 | endfunction 229 | 230 | 231 | function! s:make(expr) 232 | let obj = deepcopy(s:obj) 233 | let obj.__variable.bufnr = bufnr(a:expr) 234 | return obj 235 | endfunction 236 | 237 | 238 | 239 | let &cpo = s:save_cpo 240 | unlet s:save_cpo 241 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Coaster/Highlight.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Coaster#Highlight#import() abort 6 | return map({'highlight': '', 'clear': '', 'delete': '', 'add': '', 'as_windo': '', '_vital_depends': '', 'get_hl_id': '', 'to_list': '', 'clear_all': '', 'delete_all': '', 'to_list_by': '', 'update': '', 'enable': '', 'delete_by': '', 'hl_list': '', 'make': '', 'enable_list': '', 'update_all': '', 'disable': '', 'disable_all': '', 'is_enabled': '', 'enable_all': '', 'is_added': '', '_vital_loaded': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Coaster#Highlight#import() abort', printf("return map({'highlight': '', 'clear': '', 'delete': '', 'add': '', 'as_windo': '', '_vital_depends': '', 'get_hl_id': '', 'to_list': '', 'clear_all': '', 'delete_all': '', 'to_list_by': '', 'update': '', 'enable': '', 'delete_by': '', 'hl_list': '', 'make': '', 'enable_list': '', 'update_all': '', 'disable': '', 'disable_all': '', 'is_enabled': '', 'enable_all': '', 'is_added': '', '_vital_loaded': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | scriptencoding utf-8 17 | let s:save_cpo = &cpo 18 | set cpo&vim 19 | 20 | 21 | function! s:_vital_loaded(V) 22 | let s:V = a:V 23 | let s:Window = a:V.import("Coaster.Window") 24 | let s:Gift = a:V.import("Gift") 25 | call s:_init() 26 | endfunction 27 | 28 | 29 | function! s:_vital_depends() 30 | return [ 31 | \ "Coaster.Window", 32 | \ "Gift", 33 | \ ] 34 | endfunction 35 | 36 | 37 | 38 | let s:base = { 39 | \ "variables" : { 40 | \ "hl_list" : {}, 41 | \ "id_list" : {} 42 | \ } 43 | \} 44 | 45 | 46 | function! s:base.add(name, group, pattern, ...) 47 | call self.delete(a:name) 48 | let priority = get(a:, 1, 10) 49 | let self.variables.hl_list[a:name] = { 50 | \ "group" : a:group, 51 | \ "pattern" : a:pattern, 52 | \ "priority" : priority, 53 | \ "name" : a:name, 54 | \ } 55 | endfunction 56 | 57 | 58 | function! s:base.is_added(name) 59 | return has_key(self.variables.hl_list, a:name) 60 | endfunction 61 | 62 | 63 | function! s:base.hl_list() 64 | return keys(self.variables.hl_list) 65 | endfunction 66 | 67 | 68 | function! s:base.to_list() 69 | return values(self.variables.hl_list) 70 | endfunction 71 | 72 | 73 | function! s:_is_equal(__expr, __hl) 74 | let name = a:__hl.name 75 | let group = a:__hl.group 76 | let pattern = a:__hl.pattern 77 | let priority = a:__hl.priority 78 | return eval(a:__expr) 79 | endfunction 80 | 81 | 82 | function! s:base.to_list_by(expr) 83 | return filter(values(self.variables.hl_list), "s:_is_equal(a:expr, v:val)") 84 | endfunction 85 | 86 | 87 | function! s:base.enable_list(...) 88 | let window = get(a:, 1, s:Gift.uniq_winnr()) 89 | return keys(get(self.variables.id_list, window, {})) 90 | endfunction 91 | 92 | 93 | function! s:base.delete(name) 94 | if !self.is_added(a:name) 95 | return -1 96 | endif 97 | unlet! self.variables.hl_list[a:name] 98 | endfunction 99 | 100 | 101 | function! s:base.delete_by(expr) 102 | return map(self.to_list_by(a:expr), "self.delete(v:val.name)") 103 | endfunction 104 | 105 | 106 | function! s:base.delete_all() 107 | for name in self.hl_list() 108 | call self.delete(name) 109 | endfor 110 | endfunction 111 | 112 | 113 | function! s:base.get_hl_id(name, ...) 114 | let window = get(a:, 1, s:Gift.uniq_winnr()) 115 | return get(get(self.variables.id_list, window, {}), a:name, "") 116 | endfunction 117 | 118 | 119 | function! s:base.is_enabled(name, ...) 120 | let window = get(a:, 1, s:Gift.uniq_winnr()) 121 | return self.get_hl_id(a:name, window) != "" 122 | endfunction 123 | 124 | 125 | function! s:base.enable(name) 126 | let hl = get(self.variables.hl_list, a:name, {}) 127 | if empty(hl) 128 | return -1 129 | endif 130 | if self.is_enabled(a:name) 131 | call self.disable(a:name) 132 | endif 133 | let winnr = s:Gift.uniq_winnr() 134 | if !has_key(self.variables.id_list, winnr) 135 | let self.variables.id_list[winnr] = {} 136 | endif 137 | let self.variables.id_list[winnr][a:name] = matchadd(hl.group, hl.pattern, hl.priority) 138 | endfunction 139 | 140 | 141 | function! s:base.enable_all() 142 | for name in self.hl_list() 143 | call self.enable(name) 144 | endfor 145 | endfunction 146 | 147 | 148 | function! s:base.disable(name) 149 | if !self.is_enabled(a:name) 150 | return -1 151 | endif 152 | let id = -1 153 | silent! let id = matchdelete(self.get_hl_id(a:name)) 154 | if id == -1 155 | return -1 156 | endif 157 | let winnr = get(a:, 1, s:Gift.uniq_winnr()) 158 | unlet! self.variables.id_list[winnr][a:name] 159 | endfunction 160 | 161 | 162 | function! s:base.disable_all() 163 | for name in self.enable_list() 164 | call self.disable(name) 165 | endfor 166 | endfunction 167 | 168 | 169 | function! s:base.update(name) 170 | call self.disable(a:name) 171 | call self.enable(a:name) 172 | endfunction 173 | 174 | 175 | function! s:base.update_all() 176 | call self.disable_all() 177 | call self.enable_all() 178 | endfunction 179 | 180 | 181 | function! s:base.highlight(name, group, pattern, ...) 182 | let priority = get(a:, 1, 10) 183 | call self.add(a:name, a:group, a:pattern, priority) 184 | call self.enable(a:name) 185 | endfunction 186 | 187 | 188 | function! s:base.clear(name) 189 | call self.disable(a:name) 190 | call self.delete(a:name) 191 | endfunction 192 | 193 | 194 | function! s:base.clear_all() 195 | call self.disable_all() 196 | call self.delete_all() 197 | endfunction 198 | 199 | 200 | function! s:base.as_windo() 201 | return self.windo 202 | endfunction 203 | 204 | 205 | function! s:make() 206 | let result = deepcopy(s:base) 207 | let result.windo = s:Window.as_windo(result) 208 | return result 209 | endfunction 210 | 211 | 212 | let s:global = deepcopy(s:base) 213 | let s:funcs = keys(filter(copy(s:global), "type(v:val) == type(function('tr'))")) 214 | 215 | for s:name in s:funcs 216 | execute 217 | \ "function! s:" . s:name . "(...) \n" 218 | \ "return call(s:global." . s:name . ", a:000, s:global) \n" 219 | \ "endfunction" 220 | endfor 221 | unlet s:name 222 | 223 | 224 | function! s:_init() 225 | let s:global.windo = s:Window.as_windo(s:global) 226 | endfunction 227 | 228 | " function! s:matchadd(...) 229 | " return { 230 | " \ "id" : call("matchadd", a:000), 231 | " \ "bufnr" : bufnr("%"), 232 | " \ } 233 | " endfunction 234 | " 235 | " 236 | " function! s:matchdelete(id) 237 | " if empty(a:id) 238 | " return -1 239 | " endif 240 | " return s:Buffer.execute(a:id.bufnr, "call matchdelete(" . a:id.id . ")") 241 | " endfunction 242 | 243 | 244 | let &cpo = s:save_cpo 245 | unlet s:save_cpo 246 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Coaster/Search.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Coaster#Search#import() abort 6 | return map({'region': '', '_vital_depends': '', 'pos_ignore_syntaxes': '', 'pattern_by_range': '', 'pattern_in_region': '', 'pattern_in_region_char': '', 'pattern_in_region_block': '', 'pattern_in_region_line': '', 'region_pair': '', 'pattern_in_range': '', 'text_by_pattern': '', '_vital_loaded': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Coaster#Search#import() abort', printf("return map({'region': '', '_vital_depends': '', 'pos_ignore_syntaxes': '', 'pattern_by_range': '', 'pattern_in_region': '', 'pattern_in_region_char': '', 'pattern_in_region_block': '', 'pattern_in_region_line': '', 'region_pair': '', 'pattern_in_range': '', 'text_by_pattern': '', '_vital_loaded': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | scriptencoding utf-8 17 | let s:save_cpo = &cpo 18 | set cpo&vim 19 | 20 | 21 | function! s:_vital_loaded(V) 22 | let s:V = a:V 23 | let s:Buffer = s:V.import("Coaster.Buffer") 24 | endfunction 25 | 26 | 27 | function! s:_vital_depends() 28 | return [ 29 | \ ] 30 | endfunction 31 | 32 | 33 | function! s:region(pattern, ...) 34 | let flag_first = get(a:, 1, "") 35 | let flag_last = get(a:, 2, "") 36 | return [searchpos(a:pattern, flag_first), searchpos(a:pattern, flag_last)] 37 | endfunction 38 | 39 | 40 | function! s:region_pair(fist, last, ...) 41 | " todo 42 | endfunction 43 | 44 | 45 | function! s:pattern_in_region_char(first, last, pattern) 46 | if a:first == a:last 47 | return printf('\%%%dl\%%%dv', a:first[0], a:first[1]) 48 | elseif a:first[0] == a:last[0] 49 | return printf('\%%%dl\%%>%dv\%%(%s\M\)\%%<%dv', a:first[0], a:first[1]-1, a:pattern, a:last[1]+1) 50 | elseif a:last[0] - a:first[0] == 1 51 | return printf('\%%%dl\%%>%dv\%%(%s\M\)', a:first[0], a:first[1]-1, a:pattern) 52 | \ . "\\|" . printf('\%%%dl\%%(%s\M\)\%%<%dv', a:last[0], a:pattern, a:last[1]+1) 53 | else 54 | return printf('\%%%dl\%%>%dv\%%(%s\M\)', a:first[0], a:first[1]-1, a:pattern) 55 | \ . "\\|" . printf('\%%>%dl\%%(%s\M\)\%%<%dl', a:first[0], a:pattern, a:last[0]) 56 | \ . "\\|" . printf('\%%%dl\%%(%s\M\)\%%<%dv', a:last[0], a:pattern, a:last[1]+1) 57 | endif 58 | endfunction 59 | 60 | 61 | function! s:pattern_in_region_line(first, last, pattern) 62 | return printf('\%%>%dl\%%(%s\M\)\%%<%dl', a:first[0]-1, a:pattern, a:last[0]+1) 63 | endfunction 64 | 65 | 66 | function! s:pattern_in_region_block(first, last, pattern) 67 | return join(map(range(a:first[0], a:last[0]), "s:pattern_in_region_char([v:val, a:first[1]], [v:val, a:last[1]], a:pattern)"), '\|') 68 | endfunction 69 | 70 | 71 | function! s:pattern_in_region(wise, first, last, ...) 72 | let pattern = get(a:, 1, "") 73 | if a:wise ==# "v" 74 | return s:pattern_in_region_char(a:first, a:last, pattern) 75 | elseif a:wise ==# "V" 76 | return s:pattern_in_region_line(a:first, a:last, pattern) 77 | elseif a:wise ==# "\" 78 | return s:pattern_in_region_block(a:first, a:last, pattern) 79 | endif 80 | endfunction 81 | 82 | function! s:pattern_in_range(...) 83 | return call("s:pattern_in_region", a:000) 84 | endfunction 85 | 86 | 87 | function! s:pattern_by_range(wise, first, last) 88 | return s:pattern_in_range(a:wise, a:first, a:last, '.\{-}') 89 | endfunction 90 | 91 | 92 | function! s:text_by_pattern(pattern, ...) 93 | let flag = get(a:, 1, "") 94 | let [first, last] = s:region(a:pattern, "c" . flag, "ce" . flag) 95 | if first == [0, 0] || last == [0, 0] 96 | endif 97 | let result = s:Buffer.get_text_from_region([0] + first + [0], [0] + last + [0], "v") 98 | return result 99 | endfunction 100 | 101 | 102 | function! s:_syntax_name(pos) 103 | return synIDattr(synIDtrans(synID(a:pos[0], a:pos[1], 1)), 'name') 104 | endfunction 105 | 106 | 107 | " log : http://lingr.com/room/vim/archives/2014/08/15#message-19938628 108 | function! s:pos_ignore_syntaxes(pattern, syntaxes, ...) 109 | let old_pos = getpos(".") 110 | let old_view = winsaveview() 111 | let flag = substitute(get(a:, 1, ""), 'n', "", "g") 112 | try 113 | while 1 114 | let pos = searchpos(a:pattern, flag . "W") 115 | if pos == [0, 0] || index(a:syntaxes, s:_syntax_name(pos)) == -1 116 | return pos 117 | endif 118 | endwhile 119 | finally 120 | if get(a:, 1, "") =~# "n" 121 | call setpos(".", old_pos) 122 | call winrestview(old_view) 123 | endif 124 | endtry 125 | 126 | endfunction 127 | 128 | 129 | let &cpo = s:save_cpo 130 | unlet s:save_cpo 131 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Coaster/Window.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Coaster#Window#import() abort 6 | return map({'as_windo': '', '_vital_depends': '', 'windo': '', '_vital_loaded': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Coaster#Window#import() abort', printf("return map({'as_windo': '', '_vital_depends': '', 'windo': '', '_vital_loaded': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | scriptencoding utf-8 17 | let s:save_cpo = &cpo 18 | set cpo&vim 19 | 20 | 21 | function! s:_vital_loaded(V) 22 | let s:V = a:V 23 | let s:Buffer = a:V.import("Vim.Buffer") 24 | endfunction 25 | 26 | 27 | function! s:_vital_depends() 28 | return [ 29 | \ "Vim.Buffer", 30 | \ ] 31 | endfunction 32 | 33 | 34 | function! s:windo(func, args, ...) 35 | let dict = get(a:, 1, {}) 36 | if len(tabpagebuflist()) <= 1 || s:Buffer.is_cmdwin() 37 | return call(a:func, a:args, dict) 38 | endif 39 | let pre_winnr = winnr() 40 | 41 | noautocmd windo call call(a:func, a:args, dict) 42 | 43 | if pre_winnr == winnr() 44 | return 45 | endif 46 | execute pre_winnr . "wincmd w" 47 | endfunction 48 | 49 | 50 | function! s:as_windo(base) 51 | let windo = {} 52 | let windo.obj = a:base 53 | for [key, Value] in items(a:base) 54 | if type(function("tr")) == type(Value) 55 | execute 56 | \ "function! windo.". key. "(...)\n" 57 | \ " return s:windo(self.obj." . key . ", a:000, self.obj)\n" 58 | \ "endfunction" 59 | endif 60 | unlet Value 61 | endfor 62 | return windo 63 | endfunction 64 | 65 | 66 | 67 | let &cpo = s:save_cpo 68 | unlet s:save_cpo 69 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Data/Dict.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Data#Dict#import() abort 6 | return map({'pick': '', 'clear': '', 'max_by': '', 'foldl': '', 'swap': '', 'omit': '', 'min_by': '', 'foldr': '', 'make_index': '', 'make': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Data#Dict#import() abort', printf("return map({'pick': '', 'clear': '', 'max_by': '', 'foldl': '', 'swap': '', 'omit': '', 'min_by': '', 'foldr': '', 'make_index': '', 'make': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | " Utilities for dictionary. 17 | 18 | let s:save_cpo = &cpo 19 | set cpo&vim 20 | 21 | " Makes a dict from keys and values 22 | function! s:make(keys, values, ...) abort 23 | let dict = {} 24 | let fill = a:0 ? a:1 : 0 25 | for i in range(len(a:keys)) 26 | let key = type(a:keys[i]) == type('') ? a:keys[i] : string(a:keys[i]) 27 | if key ==# '' 28 | throw "vital: Data.Dict: Can't use an empty string for key." 29 | endif 30 | let dict[key] = get(a:values, i, fill) 31 | endfor 32 | return dict 33 | endfunction 34 | 35 | " Swaps keys and values 36 | function! s:swap(dict) abort 37 | return s:make(values(a:dict), keys(a:dict)) 38 | endfunction 39 | 40 | " Makes a index dict from a list 41 | function! s:make_index(list, ...) abort 42 | let value = a:0 ? a:1 : 1 43 | return s:make(a:list, [], value) 44 | endfunction 45 | 46 | function! s:pick(dict, keys) abort 47 | let new_dict = {} 48 | for key in a:keys 49 | if has_key(a:dict, key) 50 | let new_dict[key] = a:dict[key] 51 | endif 52 | endfor 53 | return new_dict 54 | endfunction 55 | 56 | function! s:omit(dict, keys) abort 57 | let new_dict = copy(a:dict) 58 | for key in a:keys 59 | if has_key(a:dict, key) 60 | call remove(new_dict, key) 61 | endif 62 | endfor 63 | return new_dict 64 | endfunction 65 | 66 | function! s:clear(dict) abort 67 | for key in keys(a:dict) 68 | call remove(a:dict, key) 69 | endfor 70 | return a:dict 71 | endfunction 72 | 73 | function! s:_max_by(dict, expr) abort 74 | let dict = s:swap(map(copy(a:dict), a:expr)) 75 | let key = dict[max(keys(dict))] 76 | return [key, a:dict[key]] 77 | endfunction 78 | 79 | function! s:max_by(dict, expr) abort 80 | if empty(a:dict) 81 | throw 'vital: Data.Dict: Empty dictionary' 82 | endif 83 | return s:_max_by(a:dict, a:expr) 84 | endfunction 85 | 86 | function! s:min_by(dict, expr) abort 87 | if empty(a:dict) 88 | throw 'vital: Data.Dict: Empty dictionary' 89 | endif 90 | return s:_max_by(a:dict, '-(' . a:expr . ')') 91 | endfunction 92 | 93 | function! s:_foldl(f, init, xs) abort 94 | let memo = a:init 95 | for [k, v] in a:xs 96 | let expr = substitute(a:f, 'v:key', string(k), 'g') 97 | let expr = substitute(expr, 'v:val', string(v), 'g') 98 | let expr = substitute(expr, 'v:memo', string(memo), 'g') 99 | unlet memo 100 | let memo = eval(expr) 101 | endfor 102 | return memo 103 | endfunction 104 | 105 | function! s:foldl(f, init, dict) abort 106 | return s:_foldl(a:f, a:init, items(a:dict)) 107 | endfunction 108 | 109 | function! s:foldr(f, init, dict) abort 110 | return s:_foldl(a:f, a:init, reverse(items(a:dict))) 111 | endfunction 112 | 113 | let &cpo = s:save_cpo 114 | unlet s:save_cpo 115 | 116 | " vim:set et ts=2 sts=2 sw=2 tw=0: 117 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Data/List.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Data#List#import() abort 6 | return map({'combinations': '', 'and': '', 'sort_by': '', 'foldr1': '', 'sort': '', 'flatten': '', 'has_index': '', 'find_indices': '', 'any': '', 'unshift': '', 'span': '', 'pop': '', 'binary_search': '', 'uniq_by': '', 'or': '', 'all': '', 'zip': '', 'find_last_index': '', 'find': '', 'partition': '', 'map_accum': '', 'permutations': '', 'break': '', 'max_by': '', 'foldl': '', 'foldr': '', 'find_index': '', 'group_by': '', 'take_while': '', 'conj': '', 'push': '', 'char_range': '', 'cons': '', 'foldl1': '', 'intersect': '', 'concat': '', 'shift': '', 'clear': '', 'has_common_items': '', 'product': '', 'zip_fill': '', 'uniq': '', 'has': '', 'min_by': '', 'with_index': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Data#List#import() abort', printf("return map({'combinations': '', 'and': '', 'sort_by': '', 'foldr1': '', 'sort': '', 'flatten': '', 'has_index': '', 'find_indices': '', 'any': '', 'unshift': '', 'span': '', 'pop': '', 'binary_search': '', 'uniq_by': '', 'or': '', 'all': '', 'zip': '', 'find_last_index': '', 'find': '', 'partition': '', 'map_accum': '', 'permutations': '', 'break': '', 'max_by': '', 'foldl': '', 'foldr': '', 'find_index': '', 'group_by': '', 'take_while': '', 'conj': '', 'push': '', 'char_range': '', 'cons': '', 'foldl1': '', 'intersect': '', 'concat': '', 'shift': '', 'clear': '', 'has_common_items': '', 'product': '', 'zip_fill': '', 'uniq': '', 'has': '', 'min_by': '', 'with_index': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | " Utilities for list. 17 | 18 | let s:save_cpo = &cpo 19 | set cpo&vim 20 | 21 | function! s:pop(list) abort 22 | return remove(a:list, -1) 23 | endfunction 24 | 25 | function! s:push(list, val) abort 26 | call add(a:list, a:val) 27 | return a:list 28 | endfunction 29 | 30 | function! s:shift(list) abort 31 | return remove(a:list, 0) 32 | endfunction 33 | 34 | function! s:unshift(list, val) abort 35 | return insert(a:list, a:val) 36 | endfunction 37 | 38 | function! s:cons(x, xs) abort 39 | return [a:x] + a:xs 40 | endfunction 41 | 42 | function! s:conj(xs, x) abort 43 | return a:xs + [a:x] 44 | endfunction 45 | 46 | " Removes duplicates from a list. 47 | function! s:uniq(list) abort 48 | return s:uniq_by(a:list, 'v:val') 49 | endfunction 50 | 51 | " Removes duplicates from a list. 52 | function! s:uniq_by(list, f) abort 53 | let list = map(copy(a:list), printf('[v:val, %s]', a:f)) 54 | let i = 0 55 | let seen = {} 56 | while i < len(list) 57 | let key = string(list[i][1]) 58 | if has_key(seen, key) 59 | call remove(list, i) 60 | else 61 | let seen[key] = 1 62 | let i += 1 63 | endif 64 | endwhile 65 | return map(list, 'v:val[0]') 66 | endfunction 67 | 68 | function! s:clear(list) abort 69 | if !empty(a:list) 70 | unlet! a:list[0 : len(a:list) - 1] 71 | endif 72 | return a:list 73 | endfunction 74 | 75 | " Concatenates a list of lists. 76 | " XXX: Should we verify the input? 77 | function! s:concat(list) abort 78 | let memo = [] 79 | for Value in a:list 80 | let memo += Value 81 | endfor 82 | return memo 83 | endfunction 84 | 85 | " Take each elements from lists to a new list. 86 | function! s:flatten(list, ...) abort 87 | let limit = a:0 > 0 ? a:1 : -1 88 | let memo = [] 89 | if limit == 0 90 | return a:list 91 | endif 92 | let limit -= 1 93 | for Value in a:list 94 | let memo += 95 | \ type(Value) == type([]) ? 96 | \ s:flatten(Value, limit) : 97 | \ [Value] 98 | unlet! Value 99 | endfor 100 | return memo 101 | endfunction 102 | 103 | " Sorts a list with expression to compare each two values. 104 | " a:a and a:b can be used in {expr}. 105 | function! s:sort(list, expr) abort 106 | if type(a:expr) == type(function('function')) 107 | return sort(a:list, a:expr) 108 | endif 109 | let s:expr = a:expr 110 | return sort(a:list, 's:_compare') 111 | endfunction 112 | 113 | function! s:_compare(a, b) abort 114 | return eval(s:expr) 115 | endfunction 116 | 117 | " Sorts a list using a set of keys generated by mapping the values in the list 118 | " through the given expr. 119 | " v:val is used in {expr} 120 | function! s:sort_by(list, expr) abort 121 | let pairs = map(a:list, printf('[v:val, %s]', a:expr)) 122 | return map(s:sort(pairs, 123 | \ 'a:a[1] ==# a:b[1] ? 0 : a:a[1] ># a:b[1] ? 1 : -1'), 'v:val[0]') 124 | endfunction 125 | 126 | " Returns a maximum value in {list} through given {expr}. 127 | " Returns 0 if {list} is empty. 128 | " v:val is used in {expr} 129 | function! s:max_by(list, expr) abort 130 | if empty(a:list) 131 | return 0 132 | endif 133 | let list = map(copy(a:list), a:expr) 134 | return a:list[index(list, max(list))] 135 | endfunction 136 | 137 | " Returns a minimum value in {list} through given {expr}. 138 | " Returns 0 if {list} is empty. 139 | " v:val is used in {expr} 140 | " FIXME: -0x80000000 == 0x80000000 141 | function! s:min_by(list, expr) abort 142 | return s:max_by(a:list, '-(' . a:expr . ')') 143 | endfunction 144 | 145 | " Returns List of character sequence between [a:from, a:to] 146 | " e.g.: s:char_range('a', 'c') returns ['a', 'b', 'c'] 147 | function! s:char_range(from, to) abort 148 | return map( 149 | \ range(char2nr(a:from), char2nr(a:to)), 150 | \ 'nr2char(v:val)' 151 | \) 152 | endfunction 153 | 154 | " Returns true if a:list has a:value. 155 | " Returns false otherwise. 156 | function! s:has(list, value) abort 157 | return index(a:list, a:value) isnot -1 158 | endfunction 159 | 160 | " Returns true if a:list[a:index] exists. 161 | " Returns false otherwise. 162 | " NOTE: Returns false when a:index is negative number. 163 | function! s:has_index(list, index) abort 164 | " Return true when negative index? 165 | " let index = a:index >= 0 ? a:index : len(a:list) + a:index 166 | return 0 <= a:index && a:index < len(a:list) 167 | endfunction 168 | 169 | " similar to Haskell's Data.List.span 170 | function! s:span(f, xs) abort 171 | let border = len(a:xs) 172 | for i in range(len(a:xs)) 173 | if !eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g')) 174 | let border = i 175 | break 176 | endif 177 | endfor 178 | return border == 0 ? [[], copy(a:xs)] : [a:xs[: border - 1], a:xs[border :]] 179 | endfunction 180 | 181 | " similar to Haskell's Data.List.break 182 | function! s:break(f, xs) abort 183 | return s:span(printf('!(%s)', a:f), a:xs) 184 | endfunction 185 | 186 | " similar to Haskell's Data.List.takeWhile 187 | function! s:take_while(f, xs) abort 188 | return s:span(a:f, a:xs)[0] 189 | endfunction 190 | 191 | " similar to Haskell's Data.List.partition 192 | function! s:partition(f, xs) abort 193 | return [filter(copy(a:xs), a:f), filter(copy(a:xs), '!(' . a:f . ')')] 194 | endfunction 195 | 196 | " similar to Haskell's Prelude.all 197 | function! s:all(f, xs) abort 198 | return !s:any(printf('!(%s)', a:f), a:xs) 199 | endfunction 200 | 201 | " similar to Haskell's Prelude.any 202 | function! s:any(f, xs) abort 203 | return !empty(filter(map(copy(a:xs), a:f), 'v:val')) 204 | endfunction 205 | 206 | " similar to Haskell's Prelude.and 207 | function! s:and(xs) abort 208 | return s:all('v:val', a:xs) 209 | endfunction 210 | 211 | " similar to Haskell's Prelude.or 212 | function! s:or(xs) abort 213 | return s:any('v:val', a:xs) 214 | endfunction 215 | 216 | function! s:map_accum(expr, xs, init) abort 217 | let memo = [] 218 | let init = a:init 219 | for x in a:xs 220 | let expr = substitute(a:expr, 'v:memo', init, 'g') 221 | let expr = substitute(expr, 'v:val', x, 'g') 222 | let [tmp, init] = eval(expr) 223 | call add(memo, tmp) 224 | endfor 225 | return memo 226 | endfunction 227 | 228 | " similar to Haskell's Prelude.foldl 229 | function! s:foldl(f, init, xs) abort 230 | let memo = a:init 231 | for x in a:xs 232 | let expr = substitute(a:f, 'v:val', string(x), 'g') 233 | let expr = substitute(expr, 'v:memo', string(memo), 'g') 234 | unlet memo 235 | let memo = eval(expr) 236 | endfor 237 | return memo 238 | endfunction 239 | 240 | " similar to Haskell's Prelude.foldl1 241 | function! s:foldl1(f, xs) abort 242 | if len(a:xs) == 0 243 | throw 'vital: Data.List: foldl1' 244 | endif 245 | return s:foldl(a:f, a:xs[0], a:xs[1:]) 246 | endfunction 247 | 248 | " similar to Haskell's Prelude.foldr 249 | function! s:foldr(f, init, xs) abort 250 | return s:foldl(a:f, a:init, reverse(copy(a:xs))) 251 | endfunction 252 | 253 | " similar to Haskell's Prelude.fold11 254 | function! s:foldr1(f, xs) abort 255 | if len(a:xs) == 0 256 | throw 'vital: Data.List: foldr1' 257 | endif 258 | return s:foldr(a:f, a:xs[-1], a:xs[0:-2]) 259 | endfunction 260 | 261 | " similar to python's zip() 262 | function! s:zip(...) abort 263 | return map(range(min(map(copy(a:000), 'len(v:val)'))), "map(copy(a:000), 'v:val['.v:val.']')") 264 | endfunction 265 | 266 | " similar to zip(), but goes until the longer one. 267 | function! s:zip_fill(xs, ys, filler) abort 268 | if empty(a:xs) && empty(a:ys) 269 | return [] 270 | elseif empty(a:ys) 271 | return s:cons([a:xs[0], a:filler], s:zip_fill(a:xs[1 :], [], a:filler)) 272 | elseif empty(a:xs) 273 | return s:cons([a:filler, a:ys[0]], s:zip_fill([], a:ys[1 :], a:filler)) 274 | else 275 | return s:cons([a:xs[0], a:ys[0]], s:zip_fill(a:xs[1 :], a:ys[1: ], a:filler)) 276 | endif 277 | endfunction 278 | 279 | " Inspired by Ruby's with_index method. 280 | function! s:with_index(list, ...) abort 281 | let base = a:0 > 0 ? a:1 : 0 282 | return map(copy(a:list), '[v:val, v:key + base]') 283 | endfunction 284 | 285 | " similar to Ruby's detect or Haskell's find. 286 | function! s:find(list, default, f) abort 287 | for x in a:list 288 | if eval(substitute(a:f, 'v:val', string(x), 'g')) 289 | return x 290 | endif 291 | endfor 292 | return a:default 293 | endfunction 294 | 295 | " Returns the index of the first element which satisfies the given expr. 296 | function! s:find_index(xs, f, ...) abort 297 | let len = len(a:xs) 298 | let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : 0 299 | let default = a:0 > 1 ? a:2 : -1 300 | if start >=# len || start < 0 301 | return default 302 | endif 303 | for i in range(start, len - 1) 304 | if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g')) 305 | return i 306 | endif 307 | endfor 308 | return default 309 | endfunction 310 | 311 | " Returns the index of the last element which satisfies the given expr. 312 | function! s:find_last_index(xs, f, ...) abort 313 | let len = len(a:xs) 314 | let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : len - 1 315 | let default = a:0 > 1 ? a:2 : -1 316 | if start >=# len || start < 0 317 | return default 318 | endif 319 | for i in range(start, 0, -1) 320 | if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g')) 321 | return i 322 | endif 323 | endfor 324 | return default 325 | endfunction 326 | 327 | " Similar to find_index but returns the list of indices satisfying the given expr. 328 | function! s:find_indices(xs, f, ...) abort 329 | let len = len(a:xs) 330 | let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : 0 331 | let result = [] 332 | if start >=# len || start < 0 333 | return result 334 | endif 335 | for i in range(start, len - 1) 336 | if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g')) 337 | call add(result, i) 338 | endif 339 | endfor 340 | return result 341 | endfunction 342 | 343 | " Return non-zero if a:list1 and a:list2 have any common item(s). 344 | " Return zero otherwise. 345 | function! s:has_common_items(list1, list2) abort 346 | return !empty(filter(copy(a:list1), 'index(a:list2, v:val) isnot -1')) 347 | endfunction 348 | 349 | function! s:intersect(list1, list2) abort 350 | let items = [] 351 | " for funcref 352 | for X in a:list1 353 | if index(a:list2, X) != -1 && index(items, X) == -1 354 | let items += [X] 355 | endif 356 | endfor 357 | return items 358 | endfunction 359 | 360 | " similar to Ruby's group_by. 361 | function! s:group_by(xs, f) abort 362 | let result = {} 363 | let list = map(copy(a:xs), printf('[v:val, %s]', a:f)) 364 | for x in list 365 | let Val = x[0] 366 | let key = type(x[1]) !=# type('') ? string(x[1]) : x[1] 367 | if has_key(result, key) 368 | call add(result[key], Val) 369 | else 370 | let result[key] = [Val] 371 | endif 372 | unlet Val 373 | endfor 374 | return result 375 | endfunction 376 | 377 | function! s:_default_compare(a, b) abort 378 | return a:a <# a:b ? -1 : a:a ># a:b ? 1 : 0 379 | endfunction 380 | 381 | function! s:binary_search(list, value, ...) abort 382 | let Predicate = a:0 >= 1 ? a:1 : 's:_default_compare' 383 | let dic = a:0 >= 2 ? a:2 : {} 384 | let start = 0 385 | let end = len(a:list) - 1 386 | 387 | while 1 388 | if start > end 389 | return -1 390 | endif 391 | 392 | let middle = (start + end) / 2 393 | 394 | let compared = call(Predicate, [a:value, a:list[middle]], dic) 395 | 396 | if compared < 0 397 | let end = middle - 1 398 | elseif compared > 0 399 | let start = middle + 1 400 | else 401 | return middle 402 | endif 403 | endwhile 404 | endfunction 405 | 406 | function! s:product(lists) abort 407 | let result = [[]] 408 | for pool in a:lists 409 | let tmp = [] 410 | for x in result 411 | let tmp += map(copy(pool), 'x + [v:val]') 412 | endfor 413 | let result = tmp 414 | endfor 415 | return result 416 | endfunction 417 | 418 | function! s:permutations(list, ...) abort 419 | if a:0 > 1 420 | throw 'vital: Data.List: too many arguments' 421 | endif 422 | let r = a:0 == 1 ? a:1 : len(a:list) 423 | if r > len(a:list) 424 | return [] 425 | elseif r < 0 426 | throw 'vital: Data.List: {r} must be non-negative integer' 427 | endif 428 | let n = len(a:list) 429 | let result = [] 430 | for indices in s:product(map(range(r), 'range(n)')) 431 | if len(s:uniq(indices)) == r 432 | call add(result, map(indices, 'a:list[v:val]')) 433 | endif 434 | endfor 435 | return result 436 | endfunction 437 | 438 | function! s:combinations(list, r) abort 439 | if a:r > len(a:list) 440 | return [] 441 | elseif a:r < 0 442 | throw 'vital: Data:List: {r} must be non-negative integer' 443 | endif 444 | let n = len(a:list) 445 | let result = [] 446 | for indices in s:permutations(range(n), a:r) 447 | if s:sort(copy(indices), 'a:a - a:b') == indices 448 | call add(result, map(indices, 'a:list[v:val]')) 449 | endif 450 | endfor 451 | return result 452 | endfunction 453 | 454 | let &cpo = s:save_cpo 455 | unlet s:save_cpo 456 | 457 | " vim:set et ts=2 sts=2 sw=2 tw=0: 458 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Gift.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Gift#import() abort 6 | return map({'flatten': '', 'uniq_tabpagenr': '', 'tabpagewinnr_list': '', 'execute': '', 'getwinvar': '', 'winnr': '', 'jump_window': '', '_vital_depends': '', 'uniq_winnr': '', 'setwinvar': '', 'find': '', 'openable_bufnr_list': '', 'to_fullpath': '', 'bufnr': '', 'set_current_window': '', 'tabpagewinnr': '', 'close_window': '', 'close_window_by': '', 'uniq_winnr_list': '', '_vital_loaded': '', 'find_by': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Gift#import() abort', printf("return map({'flatten': '', 'uniq_tabpagenr': '', 'tabpagewinnr_list': '', 'execute': '', 'getwinvar': '', 'winnr': '', 'jump_window': '', '_vital_depends': '', 'uniq_winnr': '', 'setwinvar': '', 'find': '', 'openable_bufnr_list': '', 'to_fullpath': '', 'bufnr': '', 'set_current_window': '', 'tabpagewinnr': '', 'close_window': '', 'close_window_by': '', 'uniq_winnr_list': '', '_vital_loaded': '', 'find_by': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | scriptencoding utf-8 17 | let s:save_cpo = &cpo 18 | set cpo&vim 19 | 20 | 21 | function! s:_vital_loaded(V) 22 | let s:V = a:V 23 | let s:Window = s:V.import("Gift.Window") 24 | let s:Tabpage = s:V.import("Gift.Tabpage") 25 | endfunction 26 | 27 | 28 | function! s:_vital_depends() 29 | return [ 30 | \ "Gift.Window", 31 | \ "Gift.Tabpage", 32 | \ ] 33 | endfunction 34 | 35 | 36 | function! s:to_fullpath(filename) 37 | let name = substitute(fnamemodify(a:filename, ":p"), '\', '/', "g") 38 | if filereadable(name) 39 | return name 40 | else 41 | return a:filename 42 | endif 43 | endfunction 44 | 45 | 46 | function! s:flatten(list) 47 | return eval(join(a:list, "+")) 48 | endfunction 49 | 50 | 51 | function! s:bufnr(expr) 52 | return type(a:expr) == type([]) 53 | \ ? s:bufnr(s:uniq_winnr(a:expr[1], a:expr[0])) 54 | \ : s:Window.bufnr(a:expr) 55 | endfunction 56 | 57 | 58 | function! s:openable_bufnr_list() 59 | return map(s:tabpagewinnr_list(), "s:bufnr([v:val[0], v:val[1]])") 60 | endfunction 61 | 62 | 63 | function! s:tabpagewinnr(...) 64 | return a:0 == 0 ? s:tabpagewinnr(s:uniq_winnr()) 65 | \ : s:Window.tabpagewinnr(a:1) 66 | endfunction 67 | 68 | 69 | function! s:tabpagewinnr_list() 70 | return s:Window.tabpagewinnr_list() 71 | " return s:flatten(map(range(1, tabpagenr("$")), "map(range(1, tabpagewinnr(v:val, '$')), '['.v:val.', v:val]')")) 72 | endfunction 73 | 74 | 75 | 76 | function! s:uniq_winnr(...) 77 | return call(s:Window.uniq_nr, a:000, s:Window) 78 | endfunction 79 | 80 | 81 | function! s:winnr(uniqnr) 82 | let [tabnr, winnr] = s:Window.tabpagewinnr(a:uniqnr) 83 | return winnr 84 | endfunction 85 | 86 | 87 | function! s:uniq_winnr_list(...) 88 | return map(s:tabpagewinnr_list(), "s:uniq_winnr(v:val[1], v:val[0])") 89 | endfunction 90 | 91 | 92 | 93 | function! s:find(expr) 94 | let gift_find_result = [] 95 | for [tabnr, winnr] in s:tabpagewinnr_list() 96 | let bufnr = s:bufnr([tabnr, winnr]) 97 | if eval(a:expr) 98 | call add(gift_find_result, [tabnr, winnr]) 99 | endif 100 | endfor 101 | return gift_find_result 102 | endfunction 103 | 104 | 105 | function! s:find_by(expr) 106 | if type(a:expr) == type(function("tr")) 107 | return filter(s:tabpagewinnr_list(), "a:expr(s:bufnr([v:val[0], v:val[1]]), v:val[0], v:val[1])") 108 | else 109 | return s:find(a:expr) 110 | endif 111 | endfunction 112 | 113 | 114 | function! s:jump_window(expr) 115 | return type(a:expr) == type([]) 116 | \ ? s:jump_window(s:uniq_winnr(a:expr[1], a:expr[0])) 117 | \ : s:Window.jump(a:expr) 118 | endfunction 119 | 120 | 121 | function! s:set_current_window(expr) 122 | return s:jump_window(a:expr) 123 | endfunction 124 | 125 | 126 | function! s:close_window(expr, ...) 127 | let close_cmd = get(a:, 1, "close") 128 | return type(a:expr) == type([]) 129 | \ ? s:close_window(s:uniq_winnr(a:expr[1], a:expr[0]), close_cmd) 130 | \ : s:Window.close(a:expr, close_cmd) 131 | endfunction 132 | 133 | 134 | function! s:close_window_by(expr, ...) 135 | let close_cmd = get(a:, 1, "close") 136 | return map(map(s:find(a:expr), "s:uniq_winnr(v:val[1], v:val[0])"), 's:close_window(v:val, close_cmd)') 137 | endfunction 138 | 139 | 140 | function! s:execute(expr, execute) 141 | return type(a:expr) == type([]) 142 | \ ? s:execute(s:uniq_winnr(a:expr[1], a:expr[0]), a:execute) 143 | \ : s:Window.execute(a:expr, a:execute) 144 | endfunction 145 | 146 | 147 | function! s:getwinvar(uniq_winnr, varname, ...) 148 | let def = get(a:, 1, "") 149 | return s:Window.getvar(a:uniq_winnr, a:varname, def) 150 | endfunction 151 | 152 | 153 | function! s:setwinvar(uniq_winnr, varname, val) 154 | return s:Window.setvar(a:uniq_winnr, a:varname, a:val) 155 | endfunction 156 | 157 | 158 | function! s:uniq_tabpagenr(...) 159 | return call(s:Tabpage.uniq_nr, a:000, s:Tabpage) 160 | endfunction 161 | 162 | 163 | 164 | let &cpo = s:save_cpo 165 | unlet s:save_cpo 166 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Gift/Tabpage.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Gift#Tabpage#import() abort 6 | return map({'uniq_nr': '', 'make_uniq_nr': '', 'numbering': '', 'set_prefix': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Gift#Tabpage#import() abort', printf("return map({'uniq_nr': '', 'make_uniq_nr': '', 'numbering': '', 'set_prefix': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | scriptencoding utf-8 17 | let s:save_cpo = &cpo 18 | set cpo&vim 19 | 20 | 21 | let s:prefix = expand(":p:h:h:t") 22 | function! s:set_prefix(prefix) 23 | let s:prefix = a:prefix 24 | endfunction 25 | 26 | 27 | let s:uniq_counter = 0 28 | function! s:make_uniq_nr() 29 | let s:uniq_counter += 1 30 | return s:uniq_counter 31 | endfunction 32 | 33 | 34 | function! s:numbering(...) 35 | let tabnr = get(a:, 1, tabpagenr()) 36 | let uniq_nr = s:make_uniq_nr() 37 | call settabvar(tabnr, s:prefix . "_gift_uniq_tabpagenr", uniq_nr) 38 | return uniq_nr 39 | endfunction 40 | 41 | 42 | function! s:uniq_nr(...) 43 | let tabnr = get(a:, 1, tabpagenr()) 44 | let uniq_nr = get(gettabvar(tabnr, ""), s:prefix . "_gift_uniq_tabpagenr", -1) 45 | if uniq_nr == -1 46 | let uniq_nr = s:numbering(tabnr) 47 | endif 48 | return uniq_nr 49 | endfunction 50 | 51 | 52 | let &cpo = s:save_cpo 53 | unlet s:save_cpo 54 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Gift/Window.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Gift#Window#import() abort 6 | return map({'flatten': '', 'tabpagewinnr_list': '', 'execute': '', 'close': '', 'numbering': '', 'set_prefix': '', '_vital_depends': '', 'exists': '', 'jump': '', 'setvar': '', 'bufnr': '', 'uniq_nr': '', 'make_uniq_nr': '', 'tabpagewinnr': '', 'getvar': '', '_vital_loaded': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Gift#Window#import() abort', printf("return map({'flatten': '', 'tabpagewinnr_list': '', 'execute': '', 'close': '', 'numbering': '', 'set_prefix': '', '_vital_depends': '', 'exists': '', 'jump': '', 'setvar': '', 'bufnr': '', 'uniq_nr': '', 'make_uniq_nr': '', 'tabpagewinnr': '', 'getvar': '', '_vital_loaded': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | scriptencoding utf-8 17 | let s:save_cpo = &cpo 18 | set cpo&vim 19 | 20 | 21 | function! s:_vital_loaded(V) 22 | let s:V = a:V 23 | let s:Tabpage = s:V.import("Gift.Tabpage") 24 | endfunction 25 | 26 | 27 | function! s:_vital_depends() 28 | return [ 29 | \ "Gift.Tabpage", 30 | \ ] 31 | endfunction 32 | 33 | 34 | let s:prefix = expand(":p:h:h:t") 35 | function! s:set_prefix(prefix) 36 | let s:prefix = a:prefix 37 | endfunction 38 | 39 | function! s:flatten(list) 40 | return eval(join(a:list, "+")) 41 | endfunction 42 | 43 | 44 | function! s:tabpagewinnr_list() 45 | return s:flatten(map(range(1, tabpagenr("$")), "map(range(1, tabpagewinnr(v:val, '$')), '['.v:val.', v:val]')")) 46 | endfunction 47 | 48 | 49 | if !exists("s:uniq_counter") 50 | let s:uniq_counter = 0 51 | endif 52 | function! s:make_uniq_nr() 53 | let s:uniq_counter += 1 54 | return s:uniq_counter 55 | endfunction 56 | 57 | 58 | function! s:numbering(...) 59 | let winnr = get(a:, 1, winnr()) 60 | let tabnr = get(a:, 2, tabpagenr()) 61 | let uniq_nr = s:make_uniq_nr() 62 | call settabwinvar(tabnr, winnr, s:prefix . "_gift_uniq_winnr", uniq_nr) 63 | return uniq_nr 64 | endfunction 65 | 66 | 67 | function! s:uniq_nr(...) 68 | let winnr = get(a:, 1, winnr()) 69 | let tabnr = get(a:, 2, tabpagenr()) 70 | let uniq_nr = get(gettabwinvar(tabnr, winnr, ""), s:prefix . "_gift_uniq_winnr", -1) 71 | if uniq_nr == -1 72 | let uniq_nr = s:numbering(winnr, tabnr) 73 | endif 74 | return uniq_nr 75 | endfunction 76 | 77 | 78 | function! s:exists(nr) 79 | let [tabnr, winnr] = s:tabpagewinnr(a:nr) 80 | return tabnr != 0 && winnr != 0 81 | endfunction 82 | 83 | 84 | function! s:tabpagewinnr(nr) 85 | if a:nr == 0 86 | return s:tabpagewinnr(s:uniq_nr()) 87 | endif 88 | let tabwinnrs = s:tabpagewinnr_list() 89 | for [tabnr, winnr] in tabwinnrs 90 | if s:uniq_nr(winnr, tabnr) == a:nr 91 | return [tabnr, winnr] 92 | endif 93 | endfor 94 | return [0, 0] 95 | endfunction 96 | 97 | 98 | function! s:getvar(nr, varname, ...) 99 | let def = get(a:, 1, "") 100 | let [tabnr, winnr] = s:tabpagewinnr(a:nr) 101 | return get(gettabwinvar(tabnr, winnr, ""), a:varname, def) 102 | endfunction 103 | 104 | 105 | function! s:setvar(nr, varname, val) 106 | let [tabnr, winnr] = s:tabpagewinnr(a:nr) 107 | if tabnr == 0 || winnr == 0 108 | return 109 | endif 110 | return settabwinvar(tabnr, winnr, a:varname, a:val) 111 | endfunction 112 | 113 | 114 | function! s:bufnr(nr) 115 | let [tabnr, winnr] = s:tabpagewinnr(a:nr) 116 | return winnr >= 1 ? get(tabpagebuflist(tabnr), winnr-1, -1) : -1 117 | endfunction 118 | 119 | 120 | 121 | function! s:jump(nr) 122 | let [tabnr, winnr] = s:tabpagewinnr(a:nr) 123 | if tabnr == 0 || winnr == 0 124 | return -1 125 | endif 126 | 127 | execute "tabnext" tabnr 128 | execute winnr . "wincmd w" 129 | endfunction 130 | 131 | 132 | function! s:close(nr, close_cmd) 133 | call s:execute(a:nr, a:close_cmd) 134 | " let current = gift#uniq_winnr() 135 | " let result = s:jump(a:nr) 136 | " if result == -1 137 | " return -1 138 | " endif 139 | " execute a:close_cmd 140 | " return s:jump(current) 141 | endfunction 142 | 143 | 144 | function! s:execute(nr, expr) 145 | let current = s:uniq_nr() 146 | let result = s:jump(a:nr) 147 | if result == -1 148 | return -1 149 | endif 150 | execute a:expr 151 | return s:jump(current) 152 | endfunction 153 | 154 | 155 | 156 | 157 | 158 | let &cpo = s:save_cpo 159 | unlet s:save_cpo 160 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Prelude.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Prelude#import() abort 6 | return map({'escape_pattern': '', 'is_funcref': '', 'path2directory': '', 'wcswidth': '', 'is_string': '', 'input_helper': '', 'is_number': '', 'is_cygwin': '', 'path2project_directory': '', 'strwidthpart_reverse': '', 'input_safe': '', 'is_list': '', 'truncate_skipping': '', 'glob': '', 'truncate': '', 'is_dict': '', 'set_default': '', 'is_numeric': '', 'getchar_safe': '', 'substitute_path_separator': '', 'is_mac': '', 'strwidthpart': '', 'getchar': '', 'is_unix': '', 'is_windows': '', 'globpath': '', 'escape_file_searching': '', 'is_float': '', 'smart_execute_command': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Prelude#import() abort', printf("return map({'escape_pattern': '', 'is_funcref': '', 'path2directory': '', 'wcswidth': '', 'is_string': '', 'input_helper': '', 'is_number': '', 'is_cygwin': '', 'path2project_directory': '', 'strwidthpart_reverse': '', 'input_safe': '', 'is_list': '', 'truncate_skipping': '', 'glob': '', 'truncate': '', 'is_dict': '', 'set_default': '', 'is_numeric': '', 'getchar_safe': '', 'substitute_path_separator': '', 'is_mac': '', 'strwidthpart': '', 'getchar': '', 'is_unix': '', 'is_windows': '', 'globpath': '', 'escape_file_searching': '', 'is_float': '', 'smart_execute_command': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | let s:save_cpo = &cpo 17 | set cpo&vim 18 | 19 | if v:version ># 703 || 20 | \ (v:version is 703 && has('patch465')) 21 | function! s:glob(expr) abort 22 | return glob(a:expr, 1, 1) 23 | endfunction 24 | else 25 | function! s:glob(expr) abort 26 | let R = glob(a:expr, 1) 27 | return split(R, '\n') 28 | endfunction 29 | endif 30 | 31 | function! s:globpath(path, expr) abort 32 | let R = globpath(a:path, a:expr, 1) 33 | return split(R, '\n') 34 | endfunction 35 | 36 | " Wrapper functions for type(). 37 | let [ 38 | \ s:__TYPE_NUMBER, 39 | \ s:__TYPE_STRING, 40 | \ s:__TYPE_FUNCREF, 41 | \ s:__TYPE_LIST, 42 | \ s:__TYPE_DICT, 43 | \ s:__TYPE_FLOAT] = [ 44 | \ type(3), 45 | \ type(''), 46 | \ type(function('tr')), 47 | \ type([]), 48 | \ type({}), 49 | \ has('float') ? type(str2float('0')) : -1] 50 | " __TYPE_FLOAT = -1 when -float 51 | " This doesn't match to anything. 52 | 53 | " Number or Float 54 | function! s:is_numeric(Value) abort 55 | let _ = type(a:Value) 56 | return _ ==# s:__TYPE_NUMBER 57 | \ || _ ==# s:__TYPE_FLOAT 58 | endfunction 59 | 60 | " Number 61 | function! s:is_number(Value) abort 62 | return type(a:Value) ==# s:__TYPE_NUMBER 63 | endfunction 64 | 65 | " Float 66 | function! s:is_float(Value) abort 67 | return type(a:Value) ==# s:__TYPE_FLOAT 68 | endfunction 69 | " String 70 | function! s:is_string(Value) abort 71 | return type(a:Value) ==# s:__TYPE_STRING 72 | endfunction 73 | " Funcref 74 | function! s:is_funcref(Value) abort 75 | return type(a:Value) ==# s:__TYPE_FUNCREF 76 | endfunction 77 | " List 78 | function! s:is_list(Value) abort 79 | return type(a:Value) ==# s:__TYPE_LIST 80 | endfunction 81 | " Dictionary 82 | function! s:is_dict(Value) abort 83 | return type(a:Value) ==# s:__TYPE_DICT 84 | endfunction 85 | 86 | function! s:truncate_skipping(str, max, footer_width, separator) abort 87 | call s:_warn_deprecated('truncate_skipping', 'Data.String.truncate_skipping') 88 | 89 | let width = s:wcswidth(a:str) 90 | if width <= a:max 91 | let ret = a:str 92 | else 93 | let header_width = a:max - s:wcswidth(a:separator) - a:footer_width 94 | let ret = s:strwidthpart(a:str, header_width) . a:separator 95 | \ . s:strwidthpart_reverse(a:str, a:footer_width) 96 | endif 97 | 98 | return s:truncate(ret, a:max) 99 | endfunction 100 | 101 | function! s:truncate(str, width) abort 102 | " Original function is from mattn. 103 | " http://github.com/mattn/googlereader-vim/tree/master 104 | 105 | call s:_warn_deprecated('truncate', 'Data.String.truncate') 106 | 107 | if a:str =~# '^[\x00-\x7f]*$' 108 | return len(a:str) < a:width ? 109 | \ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width) 110 | endif 111 | 112 | let ret = a:str 113 | let width = s:wcswidth(a:str) 114 | if width > a:width 115 | let ret = s:strwidthpart(ret, a:width) 116 | let width = s:wcswidth(ret) 117 | endif 118 | 119 | if width < a:width 120 | let ret .= repeat(' ', a:width - width) 121 | endif 122 | 123 | return ret 124 | endfunction 125 | 126 | function! s:strwidthpart(str, width) abort 127 | call s:_warn_deprecated('strwidthpart', 'Data.String.strwidthpart') 128 | 129 | if a:width <= 0 130 | return '' 131 | endif 132 | let ret = a:str 133 | let width = s:wcswidth(a:str) 134 | while width > a:width 135 | let char = matchstr(ret, '.$') 136 | let ret = ret[: -1 - len(char)] 137 | let width -= s:wcswidth(char) 138 | endwhile 139 | 140 | return ret 141 | endfunction 142 | function! s:strwidthpart_reverse(str, width) abort 143 | call s:_warn_deprecated('strwidthpart_reverse', 'Data.String.strwidthpart_reverse') 144 | 145 | if a:width <= 0 146 | return '' 147 | endif 148 | let ret = a:str 149 | let width = s:wcswidth(a:str) 150 | while width > a:width 151 | let char = matchstr(ret, '^.') 152 | let ret = ret[len(char) :] 153 | let width -= s:wcswidth(char) 154 | endwhile 155 | 156 | return ret 157 | endfunction 158 | 159 | if v:version >= 703 160 | " Use builtin function. 161 | function! s:wcswidth(str) abort 162 | call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth') 163 | return strwidth(a:str) 164 | endfunction 165 | else 166 | function! s:wcswidth(str) abort 167 | call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth') 168 | 169 | if a:str =~# '^[\x00-\x7f]*$' 170 | return strlen(a:str) 171 | end 172 | 173 | let mx_first = '^\(.\)' 174 | let str = a:str 175 | let width = 0 176 | while 1 177 | let ucs = char2nr(substitute(str, mx_first, '\1', '')) 178 | if ucs == 0 179 | break 180 | endif 181 | let width += s:_wcwidth(ucs) 182 | let str = substitute(str, mx_first, '', '') 183 | endwhile 184 | return width 185 | endfunction 186 | 187 | " UTF-8 only. 188 | function! s:_wcwidth(ucs) abort 189 | let ucs = a:ucs 190 | if (ucs >= 0x1100 191 | \ && (ucs <= 0x115f 192 | \ || ucs == 0x2329 193 | \ || ucs == 0x232a 194 | \ || (ucs >= 0x2e80 && ucs <= 0xa4cf 195 | \ && ucs != 0x303f) 196 | \ || (ucs >= 0xac00 && ucs <= 0xd7a3) 197 | \ || (ucs >= 0xf900 && ucs <= 0xfaff) 198 | \ || (ucs >= 0xfe30 && ucs <= 0xfe6f) 199 | \ || (ucs >= 0xff00 && ucs <= 0xff60) 200 | \ || (ucs >= 0xffe0 && ucs <= 0xffe6) 201 | \ || (ucs >= 0x20000 && ucs <= 0x2fffd) 202 | \ || (ucs >= 0x30000 && ucs <= 0x3fffd) 203 | \ )) 204 | return 2 205 | endif 206 | return 1 207 | endfunction 208 | endif 209 | 210 | let s:is_windows = has('win16') || has('win32') || has('win64') || has('win95') 211 | let s:is_cygwin = has('win32unix') 212 | let s:is_mac = !s:is_windows && !s:is_cygwin 213 | \ && (has('mac') || has('macunix') || has('gui_macvim') || 214 | \ (!isdirectory('/proc') && executable('sw_vers'))) 215 | let s:is_unix = has('unix') 216 | 217 | function! s:is_windows() abort 218 | return s:is_windows 219 | endfunction 220 | 221 | function! s:is_cygwin() abort 222 | return s:is_cygwin 223 | endfunction 224 | 225 | function! s:is_mac() abort 226 | return s:is_mac 227 | endfunction 228 | 229 | function! s:is_unix() abort 230 | return s:is_unix 231 | endfunction 232 | 233 | function! s:_warn_deprecated(name, alternative) abort 234 | try 235 | echohl Error 236 | echomsg 'Prelude.' . a:name . ' is deprecated! Please use ' . a:alternative . ' instead.' 237 | finally 238 | echohl None 239 | endtry 240 | endfunction 241 | 242 | function! s:smart_execute_command(action, word) abort 243 | execute a:action . ' ' . (a:word ==# '' ? '' : '`=a:word`') 244 | endfunction 245 | 246 | function! s:escape_file_searching(buffer_name) abort 247 | return escape(a:buffer_name, '*[]?{}, ') 248 | endfunction 249 | 250 | function! s:escape_pattern(str) abort 251 | call s:_warn_deprecated( 252 | \ 'escape_pattern', 253 | \ 'Data.String.escape_pattern', 254 | \) 255 | return escape(a:str, '~"\.^$[]*') 256 | endfunction 257 | 258 | function! s:getchar(...) abort 259 | let c = call('getchar', a:000) 260 | return type(c) == type(0) ? nr2char(c) : c 261 | endfunction 262 | 263 | function! s:getchar_safe(...) abort 264 | let c = s:input_helper('getchar', a:000) 265 | return type(c) == type('') ? c : nr2char(c) 266 | endfunction 267 | 268 | function! s:input_safe(...) abort 269 | return s:input_helper('input', a:000) 270 | endfunction 271 | 272 | function! s:input_helper(funcname, args) abort 273 | let success = 0 274 | if inputsave() !=# success 275 | throw 'vital: Prelude: inputsave() failed' 276 | endif 277 | try 278 | return call(a:funcname, a:args) 279 | finally 280 | if inputrestore() !=# success 281 | throw 'vital: Prelude: inputrestore() failed' 282 | endif 283 | endtry 284 | endfunction 285 | 286 | function! s:set_default(var, val) abort 287 | if !exists(a:var) || type({a:var}) != type(a:val) 288 | let {a:var} = a:val 289 | endif 290 | endfunction 291 | 292 | function! s:substitute_path_separator(path) abort 293 | return s:is_windows ? substitute(a:path, '\\', '/', 'g') : a:path 294 | endfunction 295 | 296 | function! s:path2directory(path) abort 297 | return s:substitute_path_separator(isdirectory(a:path) ? a:path : fnamemodify(a:path, ':p:h')) 298 | endfunction 299 | 300 | function! s:_path2project_directory_git(path) abort 301 | let parent = a:path 302 | 303 | while 1 304 | let path = parent . '/.git' 305 | if isdirectory(path) || filereadable(path) 306 | return parent 307 | endif 308 | let next = fnamemodify(parent, ':h') 309 | if next == parent 310 | return '' 311 | endif 312 | let parent = next 313 | endwhile 314 | endfunction 315 | 316 | function! s:_path2project_directory_svn(path) abort 317 | let search_directory = a:path 318 | let directory = '' 319 | 320 | let find_directory = s:escape_file_searching(search_directory) 321 | let d = finddir('.svn', find_directory . ';') 322 | if d ==# '' 323 | return '' 324 | endif 325 | 326 | let directory = fnamemodify(d, ':p:h:h') 327 | 328 | " Search parent directories. 329 | let parent_directory = s:path2directory( 330 | \ fnamemodify(directory, ':h')) 331 | 332 | if parent_directory !=# '' 333 | let d = finddir('.svn', parent_directory . ';') 334 | if d !=# '' 335 | let directory = s:_path2project_directory_svn(parent_directory) 336 | endif 337 | endif 338 | return directory 339 | endfunction 340 | 341 | function! s:_path2project_directory_others(vcs, path) abort 342 | let vcs = a:vcs 343 | let search_directory = a:path 344 | 345 | let find_directory = s:escape_file_searching(search_directory) 346 | let d = finddir(vcs, find_directory . ';') 347 | if d ==# '' 348 | return '' 349 | endif 350 | return fnamemodify(d, ':p:h:h') 351 | endfunction 352 | 353 | function! s:path2project_directory(path, ...) abort 354 | let is_allow_empty = get(a:000, 0, 0) 355 | let search_directory = s:path2directory(a:path) 356 | let directory = '' 357 | 358 | " Search VCS directory. 359 | for vcs in ['.git', '.bzr', '.hg', '.svn'] 360 | if vcs ==# '.git' 361 | let directory = s:_path2project_directory_git(search_directory) 362 | elseif vcs ==# '.svn' 363 | let directory = s:_path2project_directory_svn(search_directory) 364 | else 365 | let directory = s:_path2project_directory_others(vcs, search_directory) 366 | endif 367 | if directory !=# '' 368 | break 369 | endif 370 | endfor 371 | 372 | " Search project file. 373 | if directory ==# '' 374 | for d in ['build.xml', 'prj.el', '.project', 'pom.xml', 'package.json', 375 | \ 'Makefile', 'configure', 'Rakefile', 'NAnt.build', 376 | \ 'P4CONFIG', 'tags', 'gtags'] 377 | let d = findfile(d, s:escape_file_searching(search_directory) . ';') 378 | if d !=# '' 379 | let directory = fnamemodify(d, ':p:h') 380 | break 381 | endif 382 | endfor 383 | endif 384 | 385 | if directory ==# '' 386 | " Search /src/ directory. 387 | let base = s:substitute_path_separator(search_directory) 388 | if base =~# '/src/' 389 | let directory = base[: strridx(base, '/src/') + 3] 390 | endif 391 | endif 392 | 393 | if directory ==# '' && !is_allow_empty 394 | " Use original path. 395 | let directory = search_directory 396 | endif 397 | 398 | return s:substitute_path_separator(directory) 399 | endfunction 400 | 401 | let &cpo = s:save_cpo 402 | unlet s:save_cpo 403 | 404 | " vim:set et ts=2 sts=2 sw=2 tw=0: 405 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Vim/Buffer.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Vim#Buffer#import() abort 6 | return map({'_vital_depends': '', 'read_content': '', 'get_selected_text': '', 'is_cmdwin': '', 'edit_content': '', 'open': '', 'get_last_selected': '', '_vital_loaded': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Vim#Buffer#import() abort', printf("return map({'_vital_depends': '', 'read_content': '', 'get_selected_text': '', 'is_cmdwin': '', 'edit_content': '', 'open': '', 'get_last_selected': '', '_vital_loaded': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | let s:save_cpo = &cpo 17 | set cpo&vim 18 | 19 | function! s:_vital_loaded(V) abort 20 | let s:V = a:V 21 | let s:P = s:V.import('Prelude') 22 | let s:G = s:V.import('Vim.Guard') 23 | endfunction 24 | 25 | function! s:_vital_depends() abort 26 | return ['Prelude', 'Vim.Guard'] 27 | endfunction 28 | 29 | if exists('*getcmdwintype') 30 | function! s:is_cmdwin() abort 31 | return getcmdwintype() !=# '' 32 | endfunction 33 | else 34 | function! s:is_cmdwin() abort 35 | return bufname('%') ==# '[Command Line]' 36 | endfunction 37 | endif 38 | 39 | function! s:open(buffer, opener) abort 40 | let save_wildignore = &wildignore 41 | let &wildignore = '' 42 | try 43 | if s:P.is_funcref(a:opener) 44 | let loaded = !bufloaded(a:buffer) 45 | call a:opener(a:buffer) 46 | elseif a:buffer is 0 || a:buffer is# '' 47 | let loaded = 1 48 | silent execute a:opener 49 | enew 50 | else 51 | let loaded = !bufloaded(a:buffer) 52 | if s:P.is_string(a:buffer) 53 | execute a:opener '`=a:buffer`' 54 | elseif s:P.is_number(a:buffer) 55 | silent execute a:opener 56 | execute a:buffer 'buffer' 57 | else 58 | throw 'vital: Vim.Buffer: Unknown opener type.' 59 | endif 60 | endif 61 | finally 62 | let &wildignore = save_wildignore 63 | endtry 64 | return loaded 65 | endfunction 66 | 67 | function! s:get_selected_text(...) abort 68 | echohl WarningMsg 69 | echom "[WARN] s:get_selected_text() is deprecated. Use 's:get_last_selected()'." 70 | echohl None 71 | return call('s:get_last_selected', a:000) 72 | endfunction 73 | 74 | " Get the last selected text in visual mode 75 | " without using |gv| to avoid |textlock|. 76 | " NOTE: 77 | " * This function uses |gv| only when using |CTRL-V| 78 | " because |gv| is the only way to get selected text 79 | " when using $ . 80 | " Please see #192 for the details. 81 | " * If you don't care about |textlock|, 82 | " you can use simple version of this function. 83 | " https://github.com/vim-jp/vital.vim/commit/39aae80f3839fdbeebd838ff14d87327a6b889a9 84 | function! s:get_last_selected() abort 85 | if visualmode() ==# "\" 86 | let save = getreg('"', 1) 87 | let save_type = getregtype('"') 88 | try 89 | normal! gv""y 90 | return @" 91 | finally 92 | call setreg('"', save, save_type) 93 | endtry 94 | else 95 | let [begin, end] = [getpos("'<"), getpos("'>")] 96 | let lastchar = matchstr(getline(end[1])[end[2]-1 :], '.') 97 | if begin[1] ==# end[1] 98 | let lines = [getline(begin[1])[begin[2]-1 : end[2]-2]] 99 | else 100 | let lines = [getline(begin[1])[begin[2]-1 :]] 101 | \ + (end[1] - begin[1] <# 2 ? [] : getline(begin[1]+1, end[1]-1)) 102 | \ + [getline(end[1])[: end[2]-2]] 103 | endif 104 | return join(lines, "\n") . lastchar . (visualmode() ==# 'V' ? "\n" : '') 105 | endif 106 | endfunction 107 | 108 | function! s:read_content(content, ...) abort 109 | let options = extend({ 110 | \ 'tempfile': '', 111 | \ 'fileformat': '', 112 | \ 'encoding': '', 113 | \ 'binary': 0, 114 | \ 'nobinary': 0, 115 | \ 'bad': '', 116 | \ 'edit': 0, 117 | \}, get(a:000, 0, {})) 118 | let tempfile = empty(options.tempfile) ? tempname() : options.tempfile 119 | let optnames = [ 120 | \ empty(options.fileformat) ? '' : '++ff=' . options.fileformat, 121 | \ empty(options.encoding) ? '' : '++enc=' . options.encoding, 122 | \ empty(options.binary) ? '' : '++bin', 123 | \ empty(options.nobinary) ? '' : '++nobin', 124 | \ empty(options.bad) ? '' : '++bad=' . options.bad, 125 | \ empty(options.edit) ? '' : '++edit', 126 | \] 127 | let optname = join(filter(optnames, '!empty(v:val)')) 128 | try 129 | call writefile(a:content, tempfile) 130 | execute printf('keepalt keepjumps read %s%s', 131 | \ empty(optname) ? '' : optname . ' ', 132 | \ fnameescape(tempfile), 133 | \) 134 | finally 135 | call delete(tempfile) 136 | endtry 137 | endfunction 138 | 139 | function! s:edit_content(content, ...) abort 140 | let options = extend({ 141 | \ 'edit': 1, 142 | \}, get(a:000, 0, {})) 143 | let guard = s:G.store(['&l:modifiable']) 144 | let saved_view = winsaveview() 145 | try 146 | let &l:modifiable=1 147 | silent keepjumps %delete _ 148 | silent call s:read_content(a:content, options) 149 | silent keepjumps 1delete _ 150 | finally 151 | keepjump call winrestview(saved_view) 152 | call guard.restore() 153 | endtry 154 | setlocal nomodified 155 | endfunction 156 | 157 | let &cpo = s:save_cpo 158 | unlet s:save_cpo 159 | 160 | " vim:set et ts=2 sts=2 sw=2 tw=0: 161 | -------------------------------------------------------------------------------- /autoload/vital/_operator_flashy/Vim/Guard.vim: -------------------------------------------------------------------------------- 1 | " ___vital___ 2 | " NOTE: lines between '" ___vital___' is generated by :Vitalize. 3 | " Do not mofidify the code nor insert new lines before '" ___vital___' 4 | if v:version > 703 || v:version == 703 && has('patch1170') 5 | function! vital#_operator_flashy#Vim#Guard#import() abort 6 | return map({'_vital_depends': '', '_vital_created': '', 'store': '', '_vital_loaded': ''}, 'function("s:" . v:key)') 7 | endfunction 8 | else 9 | function! s:_SID() abort 10 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 11 | endfunction 12 | execute join(['function! vital#_operator_flashy#Vim#Guard#import() abort', printf("return map({'_vital_depends': '', '_vital_created': '', 'store': '', '_vital_loaded': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | let s:save_cpo = &cpo 17 | set cpo&vim 18 | 19 | " Use a Funcref as a special term _UNDEFINED 20 | function! s:_undefined() abort 21 | return 'undefined' 22 | endfunction 23 | let s:_UNDEFINED = function('s:_undefined') 24 | 25 | function! s:_vital_loaded(V) abort 26 | let s:V = a:V 27 | let s:Prelude = s:V.import('Prelude') 28 | let s:List = s:V.import('Data.List') 29 | let s:Dict = s:V.import('Data.Dict') 30 | endfunction 31 | function! s:_vital_depends() abort 32 | return ['Prelude', 'Data.List', 'Data.Dict'] 33 | endfunction 34 | function! s:_vital_created(module) abort 35 | " define constant variables 36 | if !exists('s:const') 37 | let s:const = {} 38 | let s:const.is_local_variable_supported = 39 | \ v:version > 703 || (v:version == 703 && has('patch560')) 40 | " NOTE: 41 | " The third argument is available from 7.4.242 but it had bug and that 42 | " bug was fixed from 7.4.513 43 | let s:const.is_third_argument_of_getreg_supported = has('patch-7.4.513') 44 | lockvar s:const 45 | endif 46 | call extend(a:module, s:const) 47 | endfunction 48 | function! s:_throw(msg) abort 49 | throw printf('vital: Vim.Guard: %s', a:msg) 50 | endfunction 51 | 52 | let s:option = {} 53 | function! s:_new_option(name) abort 54 | if a:name !~# '^&' 55 | call s:_throw(printf( 56 | \'An option name "%s" requires to be started from "&"', a:name 57 | \)) 58 | elseif !exists(a:name) 59 | call s:_throw(printf( 60 | \'An option name "%s" does not exist', a:name 61 | \)) 62 | endif 63 | let option = copy(s:option) 64 | let option.name = a:name 65 | let option.value = eval(a:name) 66 | return option 67 | endfunction 68 | function! s:option.restore() abort 69 | execute printf('let %s = %s', self.name, string(self.value)) 70 | endfunction 71 | 72 | let s:register = {} 73 | function! s:_new_register(name) abort 74 | if len(a:name) != 2 75 | call s:_throw(printf( 76 | \'A register name "%s" requires to be "@" + a single character', a:name 77 | \)) 78 | elseif a:name !~# '^@' 79 | call s:_throw(printf( 80 | \'A register name "%s" requires to be started from "@"', a:name 81 | \)) 82 | elseif a:name =~# '^@[:.%]$' 83 | call s:_throw(printf( 84 | \'A register name "%s" is read only', a:name 85 | \)) 86 | elseif a:name !~# '^@[@0-9a-zA-Z#=*+~_/-]$' 87 | call s:_throw(printf( 88 | \'A register name "%s" does not exist. See ":help let-register"', a:name 89 | \)) 90 | endif 91 | let name = a:name ==# '@@' ? '' : a:name[1] 92 | let register = copy(s:register) 93 | let register.name = name 94 | if s:const.is_third_argument_of_getreg_supported 95 | let register.value = getreg(name, 1, 1) 96 | else 97 | let register.value = getreg(name, 1) 98 | endif 99 | let register.type = getregtype(name) 100 | return register 101 | endfunction 102 | function! s:register.restore() abort 103 | call setreg(self.name, self.value, self.type) 104 | endfunction 105 | 106 | let s:environment = {} 107 | function! s:_new_environment(name) abort 108 | if a:name !~# '^\$' 109 | call s:_throw(printf( 110 | \'An environment variable name "%s" requires to be started from "$"', a:name 111 | \)) 112 | elseif !exists(a:name) 113 | call s:_throw(printf( 114 | \'An environment variable name "%s" does not exist. While Vim cannot unlet environment variable, it requires to exist', a:name 115 | \)) 116 | endif 117 | let environment = copy(s:environment) 118 | let environment.name = a:name 119 | let environment.value = eval(a:name) 120 | return environment 121 | endfunction 122 | function! s:environment.restore() abort 123 | execute printf('let %s = %s', self.name, string(self.value)) 124 | endfunction 125 | 126 | let s:variable = {} 127 | function! s:_new_variable(name, ...) abort 128 | if a:0 == 0 129 | let m = matchlist(a:name, '^\([bwtg]:\)\(.*\)$') 130 | if empty(m) 131 | call s:_throw(printf( 132 | \ join([ 133 | \ 'An variable name "%s" requires to start from b:, w:, t:, or g:', 134 | \ 'while no {namespace} is specified', 135 | \ ]), 136 | \ a:name, 137 | \)) 138 | endif 139 | let [prefix, name] = m[1 : 2] 140 | let namespace = eval(prefix) 141 | else 142 | let name = a:name 143 | let namespace = a:1 144 | endif 145 | let variable = copy(s:variable) 146 | let variable.name = name 147 | let variable.value = get(namespace, name, s:_UNDEFINED) 148 | let variable.value = 149 | \ type(variable.value) == type({}) || type(variable.value) == type([]) 150 | \ ? deepcopy(variable.value) 151 | \ : variable.value 152 | let variable._namespace = namespace 153 | return variable 154 | endfunction 155 | function! s:variable.restore() abort 156 | " unlet the variable to prevent variable type mis-match in case 157 | silent! unlet! self._namespace[self.name] 158 | if type(self.value) == type(s:_UNDEFINED) && self.value == s:_UNDEFINED 159 | " do nothing, leave the variable as undefined 160 | else 161 | let self._namespace[self.name] = self.value 162 | endif 163 | endfunction 164 | 165 | let s:instance = {} 166 | function! s:_new_instance(instance, ...) abort 167 | let shallow = get(a:000, 0, 0) 168 | if !s:Prelude.is_list(a:instance) && !s:Prelude.is_dict(a:instance) 169 | call s:_throw(printf( 170 | \'An instance "%s" requires to be List or Dictionary', string(a:instance) 171 | \)) 172 | endif 173 | let instance = copy(s:instance) 174 | let instance.instance = a:instance 175 | let instance.values = shallow ? copy(a:instance) : deepcopy(a:instance) 176 | return instance 177 | endfunction 178 | function! s:instance.restore() abort 179 | if s:Prelude.is_list(self.instance) 180 | call s:List.clear(self.instance) 181 | else 182 | call s:Dict.clear(self.instance) 183 | endif 184 | call extend(self.instance, self.values) 185 | endfunction 186 | 187 | let s:guard = {} 188 | function! s:store(targets) abort 189 | let resources = [] 190 | for meta in a:targets 191 | if s:Prelude.is_list(meta) 192 | if len(meta) == 1 193 | call add(resources, s:_new_instance(meta[0])) 194 | elseif len(meta) == 2 195 | if s:Prelude.is_string(meta[0]) 196 | call add(resources, call('s:_new_variable', meta)) 197 | else 198 | call add(resources, call('s:_new_instance', meta)) 199 | endif 200 | else 201 | call s:_throw('List assignment requires one or two elements') 202 | endif 203 | elseif type(meta) == type('') 204 | if meta =~# '^[bwtgls]:' 205 | " Note: 206 | " To improve an error message, handle l:XXX or s:XXX as well 207 | call add(resources, s:_new_variable(meta)) 208 | elseif meta =~# '^&' 209 | call add(resources, s:_new_option(meta)) 210 | elseif meta =~# '^@' 211 | call add(resources, s:_new_register(meta)) 212 | elseif meta =~# '^\$' 213 | call add(resources, s:_new_environment(meta)) 214 | else 215 | call s:_throw(printf( 216 | \ 'Unknown value "%s" was specified', 217 | \ meta 218 | \)) 219 | endif 220 | endif 221 | unlet meta 222 | endfor 223 | let guard = copy(s:guard) 224 | let guard._resources = resources 225 | return guard 226 | endfunction 227 | function! s:guard.restore() abort 228 | for resource in self._resources 229 | call resource.restore() 230 | endfor 231 | endfunction 232 | 233 | let &cpo = s:save_cpo 234 | unlet! s:save_cpo 235 | " vim:set et ts=2 sts=2 sw=2 tw=0 fdm=marker: 236 | -------------------------------------------------------------------------------- /autoload/vital/operator_flashy.vim: -------------------------------------------------------------------------------- 1 | let s:plugin_name = expand(':t:r') 2 | let s:vital_base_dir = expand(':h') 3 | let s:project_root = expand(':h:h:h') 4 | let s:is_vital_vim = s:plugin_name is# 'vital' 5 | 6 | let s:loaded = {} 7 | let s:cache_sid = {} 8 | 9 | " function() wrapper 10 | if v:version > 703 || v:version == 703 && has('patch1170') 11 | function! s:_function(fstr) abort 12 | return function(a:fstr) 13 | endfunction 14 | else 15 | function! s:_SID() abort 16 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 17 | endfunction 18 | let s:_s = '' . s:_SID() . '_' 19 | function! s:_function(fstr) abort 20 | return function(substitute(a:fstr, 's:', s:_s, 'g')) 21 | endfunction 22 | endif 23 | 24 | function! vital#{s:plugin_name}#of() abort 25 | return s:new(s:plugin_name) 26 | endfunction 27 | 28 | function! vital#{s:plugin_name}#import(...) abort 29 | if !exists('s:V') 30 | let s:V = s:new(s:plugin_name) 31 | endif 32 | return call(s:V.import, a:000, s:V) 33 | endfunction 34 | 35 | let s:Vital = {} 36 | 37 | function! s:new(plugin_name) abort 38 | let base = deepcopy(s:Vital) 39 | let base._plugin_name = a:plugin_name 40 | return base 41 | endfunction 42 | 43 | function! s:vital_files() abort 44 | if !exists('s:vital_files') 45 | let s:vital_files = map( 46 | \ s:is_vital_vim ? s:_global_vital_files() : s:_self_vital_files(), 47 | \ 'fnamemodify(v:val, ":p:gs?[\\\\/]?/?")') 48 | endif 49 | return copy(s:vital_files) 50 | endfunction 51 | let s:Vital.vital_files = s:_function('s:vital_files') 52 | 53 | function! s:import(name, ...) abort dict 54 | let target = {} 55 | let functions = [] 56 | for a in a:000 57 | if type(a) == type({}) 58 | let target = a 59 | elseif type(a) == type([]) 60 | let functions = a 61 | endif 62 | unlet a 63 | endfor 64 | let module = self._import(a:name) 65 | if empty(functions) 66 | call extend(target, module, 'keep') 67 | else 68 | for f in functions 69 | if has_key(module, f) && !has_key(target, f) 70 | let target[f] = module[f] 71 | endif 72 | endfor 73 | endif 74 | return target 75 | endfunction 76 | let s:Vital.import = s:_function('s:import') 77 | 78 | function! s:load(...) abort dict 79 | for arg in a:000 80 | let [name; as] = type(arg) == type([]) ? arg[: 1] : [arg, arg] 81 | let target = split(join(as, ''), '\W\+') 82 | let dict = self 83 | let dict_type = type({}) 84 | while !empty(target) 85 | let ns = remove(target, 0) 86 | if !has_key(dict, ns) 87 | let dict[ns] = {} 88 | endif 89 | if type(dict[ns]) == dict_type 90 | let dict = dict[ns] 91 | else 92 | unlet dict 93 | break 94 | endif 95 | endwhile 96 | if exists('dict') 97 | call extend(dict, self._import(name)) 98 | endif 99 | unlet arg 100 | endfor 101 | return self 102 | endfunction 103 | let s:Vital.load = s:_function('s:load') 104 | 105 | function! s:unload() abort dict 106 | let s:loaded = {} 107 | let s:cache_sid = {} 108 | unlet! s:vital_files 109 | endfunction 110 | let s:Vital.unload = s:_function('s:unload') 111 | 112 | function! s:exists(name) abort dict 113 | if a:name !~# '\v^\u\w*%(\.\u\w*)*$' 114 | throw 'vital: Invalid module name: ' . a:name 115 | endif 116 | return s:_module_path(a:name) isnot# '' 117 | endfunction 118 | let s:Vital.exists = s:_function('s:exists') 119 | 120 | function! s:search(pattern) abort dict 121 | let paths = s:_extract_files(a:pattern, self.vital_files()) 122 | let modules = sort(map(paths, 's:_file2module(v:val)')) 123 | return s:_uniq(modules) 124 | endfunction 125 | let s:Vital.search = s:_function('s:search') 126 | 127 | function! s:plugin_name() abort dict 128 | return self._plugin_name 129 | endfunction 130 | let s:Vital.plugin_name = s:_function('s:plugin_name') 131 | 132 | function! s:_self_vital_files() abort 133 | let builtin = printf('%s/__%s__/', s:vital_base_dir, s:plugin_name) 134 | let installed = printf('%s/_%s/', s:vital_base_dir, s:plugin_name) 135 | let base = builtin . ',' . installed 136 | return split(globpath(base, '**/*.vim', 1), "\n") 137 | endfunction 138 | 139 | function! s:_global_vital_files() abort 140 | let pattern = 'autoload/vital/__*__/**/*.vim' 141 | return split(globpath(&runtimepath, pattern, 1), "\n") 142 | endfunction 143 | 144 | function! s:_extract_files(pattern, files) abort 145 | let tr = {'.': '/', '*': '[^/]*', '**': '.*'} 146 | let target = substitute(a:pattern, '\.\|\*\*\?', '\=tr[submatch(0)]', 'g') 147 | let regexp = printf('autoload/vital/[^/]\+/%s.vim$', target) 148 | return filter(a:files, 'v:val =~# regexp') 149 | endfunction 150 | 151 | function! s:_file2module(file) abort 152 | let filename = fnamemodify(a:file, ':p:gs?[\\/]?/?') 153 | let tail = matchstr(filename, 'autoload/vital/_\w\+/\zs.*\ze\.vim$') 154 | return join(split(tail, '[\\/]\+'), '.') 155 | endfunction 156 | 157 | " @param {string} name e.g. Data.List 158 | function! s:_import(name) abort dict 159 | if has_key(s:loaded, a:name) 160 | return copy(s:loaded[a:name]) 161 | endif 162 | let module = self._get_module(a:name) 163 | if has_key(module, '_vital_created') 164 | call module._vital_created(module) 165 | endif 166 | let export_module = filter(copy(module), 'v:key =~# "^\\a"') 167 | " Cache module before calling module.vital_loaded() to avoid cyclic 168 | " dependences but remove the cache if module._vital_loaded() fails. 169 | " let s:loaded[a:name] = export_module 170 | let s:loaded[a:name] = export_module 171 | if has_key(module, '_vital_loaded') 172 | try 173 | call module._vital_loaded(vital#{s:plugin_name}#of()) 174 | catch 175 | unlet s:loaded[a:name] 176 | throw 'vital: fail to call ._vital_loaded(): ' . v:exception 177 | endtry 178 | endif 179 | return copy(s:loaded[a:name]) 180 | endfunction 181 | let s:Vital._import = s:_function('s:_import') 182 | 183 | " s:_get_module() returns module object wihch has all script local functions. 184 | function! s:_get_module(name) abort dict 185 | let funcname = s:_import_func_name(self.plugin_name(), a:name) 186 | if s:_exists_autoload_func_with_source(funcname) 187 | return call(funcname, []) 188 | else 189 | return s:_get_builtin_module(a:name) 190 | endif 191 | endfunction 192 | 193 | function! s:_get_builtin_module(name) abort 194 | return s:sid2sfuncs(s:_module_sid(a:name)) 195 | endfunction 196 | 197 | if s:is_vital_vim 198 | " For vital.vim, we can use s:_get_builtin_module directly 199 | let s:Vital._get_module = s:_function('s:_get_builtin_module') 200 | else 201 | let s:Vital._get_module = s:_function('s:_get_module') 202 | endif 203 | 204 | function! s:_import_func_name(plugin_name, module_name) abort 205 | return printf('vital#_%s#%s#import', a:plugin_name, s:_dot_to_sharp(a:module_name)) 206 | endfunction 207 | 208 | function! s:_module_sid(name) abort 209 | let path = s:_module_path(a:name) 210 | if !filereadable(path) 211 | throw 'vital: module not found: ' . a:name 212 | endif 213 | let vital_dir = s:is_vital_vim ? '__\w\+__' : printf('_\{1,2}%s\%%(__\)\?', s:plugin_name) 214 | let base = join([vital_dir, ''], '[/\\]\+') 215 | let p = base . substitute('' . a:name, '\.', '[/\\\\]\\+', 'g') 216 | let sid = s:_sid(path, p) 217 | if !sid 218 | call s:_source(path) 219 | let sid = s:_sid(path, p) 220 | if !sid 221 | throw printf('vital: cannot get from path: %s', path) 222 | endif 223 | endif 224 | return sid 225 | endfunction 226 | 227 | function! s:_module_path(name) abort 228 | return get(s:_extract_files(a:name, s:vital_files()), 0, '') 229 | endfunction 230 | 231 | function! s:_module_sid_base_dir() abort 232 | return s:is_vital_vim ? &rtp : s:project_root 233 | endfunction 234 | 235 | function! s:_dot_to_sharp(name) abort 236 | return substitute(a:name, '\.', '#', 'g') 237 | endfunction 238 | 239 | " It will sources autoload file if a given func is not already defined. 240 | function! s:_exists_autoload_func_with_source(funcname) abort 241 | if exists('*' . a:funcname) 242 | " Return true if a given func is already defined 243 | return 1 244 | endif 245 | " source a file which may include a given func definition and try again. 246 | let path = 'autoload/' . substitute(substitute(a:funcname, '#[^#]*$', '.vim', ''), '#', '/', 'g') 247 | call s:_runtime(path) 248 | return exists('*' . a:funcname) 249 | endfunction 250 | 251 | function! s:_runtime(path) abort 252 | execute 'runtime' fnameescape(a:path) 253 | endfunction 254 | 255 | function! s:_source(path) abort 256 | execute 'source' fnameescape(a:path) 257 | endfunction 258 | 259 | " @vimlint(EVL102, 1, l:_) 260 | " @vimlint(EVL102, 1, l:__) 261 | function! s:_sid(path, filter_pattern) abort 262 | let unified_path = s:_unify_path(a:path) 263 | if has_key(s:cache_sid, unified_path) 264 | return s:cache_sid[unified_path] 265 | endif 266 | for line in filter(split(s:_redir(':scriptnames'), "\n"), 'v:val =~# a:filter_pattern') 267 | let [_, sid, path; __] = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$') 268 | if s:_unify_path(path) is# unified_path 269 | let s:cache_sid[unified_path] = sid 270 | return s:cache_sid[unified_path] 271 | endif 272 | endfor 273 | return 0 274 | endfunction 275 | 276 | function! s:_redir(cmd) abort 277 | let [save_verbose, save_verbosefile] = [&verbose, &verbosefile] 278 | set verbose=0 verbosefile= 279 | redir => res 280 | silent! execute a:cmd 281 | redir END 282 | let [&verbose, &verbosefile] = [save_verbose, save_verbosefile] 283 | return res 284 | endfunction 285 | 286 | if filereadable(expand(':r') . '.VIM') " is case-insensitive or not 287 | let s:_unify_path_cache = {} 288 | " resolve() is slow, so we cache results. 289 | " Note: On windows, vim can't expand path names from 8.3 formats. 290 | " So if getting full path via and $HOME was set as 8.3 format, 291 | " vital load duplicated scripts. Below's :~ avoid this issue. 292 | function! s:_unify_path(path) abort 293 | if has_key(s:_unify_path_cache, a:path) 294 | return s:_unify_path_cache[a:path] 295 | endif 296 | let value = tolower(fnamemodify(resolve(fnamemodify( 297 | \ a:path, ':p')), ':~:gs?[\\/]?/?')) 298 | let s:_unify_path_cache[a:path] = value 299 | return value 300 | endfunction 301 | else 302 | function! s:_unify_path(path) abort 303 | return resolve(fnamemodify(a:path, ':p:gs?[\\/]?/?')) 304 | endfunction 305 | endif 306 | 307 | " copied and modified from Vim.ScriptLocal 308 | let s:SNR = join(map(range(len("\")), '"[\\x" . printf("%0x", char2nr("\"[v:val])) . "]"'), '') 309 | function! s:sid2sfuncs(sid) abort 310 | let fs = split(s:_redir(printf(':function /^%s%s_', s:SNR, a:sid)), "\n") 311 | let r = {} 312 | let pattern = printf('\m^function\s%d_\zs\w\{-}\ze(', a:sid) 313 | for fname in map(fs, 'matchstr(v:val, pattern)') 314 | let r[fname] = function(s:_sfuncname(a:sid, fname)) 315 | endfor 316 | return r 317 | endfunction 318 | 319 | "" Return funcname of script local functions with SID 320 | function! s:_sfuncname(sid, funcname) abort 321 | return printf('%s_%s', a:sid, a:funcname) 322 | endfunction 323 | 324 | if exists('*uniq') 325 | function! s:_uniq(list) abort 326 | return uniq(a:list) 327 | endfunction 328 | else 329 | function! s:_uniq(list) abort 330 | let i = len(a:list) - 1 331 | while 0 < i 332 | if a:list[i] ==# a:list[i - 1] 333 | call remove(a:list, i) 334 | endif 335 | let i -= 1 336 | endwhile 337 | return a:list 338 | endfunction 339 | endif 340 | -------------------------------------------------------------------------------- /autoload/vital/operator_flashy.vital: -------------------------------------------------------------------------------- 1 | operator_flashy 2 | 64a8be0c1fbfbf944043fb22f16bab8c28756459 3 | 4 | Coaster.Search 5 | Coaster.Highlight 6 | Coaster.Buffer 7 | -------------------------------------------------------------------------------- /doc/operator-flashy.txt: -------------------------------------------------------------------------------- 1 | *operator-flashy.txt* Flash yanked area 2 | 3 | Author : haya14busa 4 | Version : 0.9.0 5 | License : MIT license {{{ 6 | 7 | Copyright (c) 2015 haya14busa 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining 10 | a copy of this software and associated documentation files (the 11 | "Software"), to deal in the Software without restriction, including 12 | without limitation the rights to use, copy, modify, merge, publish, 13 | distribute, sublicense, and/or sell copies of the Software, and to 14 | permit persons to whom the Software is furnished to do so, subject to 15 | the following conditions: 16 | The above copyright notice and this permission notice shall be 17 | included in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | 27 | }}} 28 | 29 | ============================================================================== 30 | CONTENTS *operator-flashy-contents* 31 | 32 | INTRODUCTION |operator-flashy-introduction| 33 | DEPENDENCY |operator-flashy-dependency| 34 | INSTALLATION |operator-flashy-installation| 35 | INTERFACE |operator-flashy-interface| 36 | KEY MAPPINGS |operator-flashy-key-mappings| 37 | VARIABLES |operator-flashy-variables| 38 | CHANGELOG |operator-flashy-changelog| 39 | 40 | ============================================================================== 41 | INTRODUCTION *operator-flashy-introduction* 42 | 43 | *vim-operator-flashy* (*operator-flashy.vim* ) flash yanked area. You can 44 | confirm that text is yanked correctly and see yanked text by highlighting. 45 | > 46 | map y (operator-flashy) 47 | map Y (operator-flashy)$ 48 | 49 | ============================================================================== 50 | DEPENDENCY *operator-flashy-dependency* 51 | 52 | |operator-user| (requried) 53 | https://github.com/kana/vim-operator-user 54 | 55 | ============================================================================== 56 | INSTALLATION *operator-flashy-installation* 57 | 58 | Install with your favorite plugin managers like NeoBundle/Plugin/Plug 59 | > 60 | NeoBundle 'haya14busa/vim-operator-flashy' 61 | Plugin 'haya14busa/vim-operator-flashy' 62 | Plug 'haya14busa/vim-operator-flashy' 63 | 64 | ============================================================================== 65 | INTERFACE *operator-flashy-interface* 66 | 67 | ------------------------------------------------------------------------------ 68 | KEY MAPPINGS *operator-flashy-key-mappings* 69 | 70 | ["x](operator-flashy){motion} *(operator-flashy)* 71 | Yank {motion} text [into register x] with flashing. See |y|. 72 | 73 | ------------------------------------------------------------------------------ 74 | VARIABLES *operator-flashy-variables* 75 | 76 | g:operator#flashy#group *g:operator#flashy#group* 77 | Highlight {group-name} for flashing yanked area. 78 | Default: > 79 | Flashy xxx term=bold ctermbg=0 guibg=#13354A 80 | 81 | g:operator#flashy#flash_time *g:operator#flashy#flash_time* 82 | The time in milliseconds for flashing yanked area. 83 | Defualt: 100 84 | 85 | ============================================================================== 86 | CHANGELOG *operator-flashy-changelog* 87 | 88 | 0.9.1 2016-01-05 89 | - Do not block Vim while flashing. 90 | - Highlight cursor position while flashing. 91 | - Fix character handling. 92 | 93 | 0.9.0 2015-12-31 94 | - Init. 95 | 96 | ============================================================================== 97 | vim:tw=78:ts=8:ft=help:norl:noet:fen:fdl=0:fdm=marker: 98 | -------------------------------------------------------------------------------- /plugin/operator/flashy.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " FILE: plugin/operator/flashy.vim 3 | " AUTHOR: haya14busa 4 | " License: MIT license 5 | "============================================================================= 6 | scriptencoding utf-8 7 | if expand('%:p') ==# expand(':p') 8 | unlet! g:loaded_operator_flashy 9 | endif 10 | if exists('g:loaded_operator_flashy') 11 | finish 12 | endif 13 | let g:loaded_operator_flashy = 1 14 | let s:save_cpo = &cpo 15 | set cpo&vim 16 | 17 | call operator#user#define('flashy', 'operator#flashy#do') 18 | vnoremap (operator-flashy) y 19 | onoremap (operator-flashy) operator#flashy#o_y() 20 | 21 | let &cpo = s:save_cpo 22 | unlet s:save_cpo 23 | " __END__ 24 | " vim: expandtab softtabstop=2 shiftwidth=2 foldmethod=marker 25 | --------------------------------------------------------------------------------