├── .github ├── FUNDING.yml └── workflows │ └── reviewdog.yml ├── .gitignore ├── .travis.yml ├── Gemfile ├── README.md ├── Rakefile ├── autoload ├── EasyMotion.vim ├── EasyMotion │ ├── cmigemo.vim │ ├── command_line.vim │ ├── helper.vim │ ├── highlight.vim │ ├── migemo │ │ ├── cp932.vim │ │ ├── eucjp.vim │ │ └── utf8.vim │ ├── overwin.vim │ ├── sticky_table.vim │ └── undo.vim ├── vital.vim └── vital │ ├── _easymotion.vim │ ├── _easymotion │ ├── Data │ │ ├── Dict.vim │ │ ├── List.vim │ │ └── Set.vim │ ├── HitAHint │ │ ├── Hint.vim │ │ └── Motion.vim │ ├── Over │ │ ├── Commandline │ │ │ ├── Base.vim │ │ │ ├── Modules.vim │ │ │ └── Modules │ │ │ │ ├── BufferComplete.vim │ │ │ │ ├── Cancel.vim │ │ │ │ ├── CursorMove.vim │ │ │ │ ├── Delete.vim │ │ │ │ ├── Doautocmd.vim │ │ │ │ ├── DrawCommandline.vim │ │ │ │ ├── ExceptionExit.vim │ │ │ │ ├── ExceptionMessage.vim │ │ │ │ ├── Exit.vim │ │ │ │ ├── History.vim │ │ │ │ ├── InsertRegister.vim │ │ │ │ ├── KeyMapping.vim │ │ │ │ ├── NoInsert.vim │ │ │ │ ├── Paste.vim │ │ │ │ └── Redraw.vim │ │ ├── Exception.vim │ │ ├── Input.vim │ │ ├── Keymapping.vim │ │ ├── Signals.vim │ │ └── String.vim │ ├── Palette │ │ ├── Capture.vim │ │ ├── Highlight.vim │ │ └── Keymapping.vim │ ├── Prelude.vim │ └── Vim │ │ ├── Buffer.vim │ │ ├── Guard.vim │ │ └── Message.vim │ ├── easymotion.vim │ └── easymotion.vital ├── doc └── easymotion.txt ├── plugin └── EasyMotion.vim └── t ├── compare_movements_spec.vim ├── easymotion_spec.vim ├── operator_pending_spec.vim └── smartsign_spec.vim /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [haya14busa] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/workflows/reviewdog.yml: -------------------------------------------------------------------------------- 1 | name: reviewdog 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | 8 | jobs: 9 | vint: 10 | name: runner / vint 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: reviewdog/action-vint@v1 15 | if: github.event_name == 'pull_request' 16 | with: 17 | github_token: ${{ secrets.github_token }} 18 | reporter: github-pr-check 19 | level: warning 20 | - uses: reviewdog/action-vint@v1 21 | if: github.event_name != 'pull_request' 22 | with: 23 | github_token: ${{ secrets.github_token }} 24 | reporter: github-check 25 | level: warning 26 | 27 | languagetool: 28 | name: runner / languagetool 29 | runs-on: ubuntu-latest 30 | steps: 31 | - uses: actions/checkout@v2 32 | - uses: reviewdog/action-languagetool@v1 33 | with: 34 | github_token: ${{ secrets.github_token }} 35 | reporter: github-check 36 | level: info 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | doc/tags 2 | tmp* 3 | *.lock 4 | .vim-flavor 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # This config is based on lightline.vim 2 | 3 | language: ruby 4 | rvm: 5 | - 2.0.0 6 | install: 7 | - git clone https://github.com/kana/vim-vspec.git 8 | before_script: 9 | - bundle install 10 | - bundle show 11 | - (if ! test -d $HOME/vim-$VIM_VERSION/bin; then 12 | git clone https://github.com/vim/vim $HOME/vim && 13 | cd $HOME/vim && 14 | git checkout v$VIM_VERSION && 15 | ./configure --prefix=$HOME/vim-$VIM_VERSION && 16 | make && 17 | make install; 18 | fi) 19 | 20 | cache: 21 | directories: 22 | - $HOME/vim-$VIM_VERSION 23 | 24 | env: 25 | - VIM_VERSION=8.0.0000 26 | - VIM_VERSION=7.4 27 | 28 | script: 29 | - export PATH=$HOME/vim-$VIM_VERSION/bin:$PATH 30 | - cd $TRAVIS_BUILD_DIR 31 | - rake ci 32 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'vim-flavor', '~> 2.2.2' 4 | gem 'rake' 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Vim motion on speed! 2 | ===== 3 | [![Build Status](https://travis-ci.org/easymotion/vim-easymotion.svg?branch=master)](https://travis-ci.org/easymotion/vim-easymotion) 4 | [![reviewdog](https://github.com/easymotion/vim-easymotion/workflows/reviewdog/badge.svg?branch=master&event=push)](https://github.com/easymotion/vim-easymotion/actions?query=workflow%3Areviewdog+event%3Apush+branch%3Amaster) 5 | 6 | ![Animated demonstration](https://f.cloud.github.com/assets/3797062/2039359/a8e938d6-899f-11e3-8789-60025ea83656.gif) 7 | 8 | About the authors 9 | ===== 10 | 11 | | Authors | | 12 | |------------------|-------------------------------| 13 | | Kim Silkebækken | https://github.com/Lokaltog | 14 | | haya14busa | https://github.com/haya14busa | 15 | 16 | The EasyMotion project, revived! 17 | ====== 18 | 19 | Starting from version 2.0 [haya14busa](https://github.com/haya14busa) will be 20 | taking over the project from [Lokaltog](https://github.com/Lokaltog). He's 21 | improved the default motions, implemented many useful new features, and fixed 22 | some bugs. 23 | 24 | EasyMotion is now completely: 25 | 26 | - **Well-behaved**: It's consistent with the default motions of Vim and works 27 | well in all modes. And it now supports repeating with the dot operator. 28 | - **Configurable**: You can easily configure its behavior and map it to any key 29 | - **Sophisticated**: Provide flawless, smooth and fast motions with minimal keystrokes 30 | 31 | Even though some default behaviors were modified and many new features were 32 | added, I carefully considered backward compatibility. So those of you updating 33 | from older versions can do so without worry and start benefiting immediately 34 | from all the new features! 35 | 36 | Introduction 37 | ===== 38 | 39 | EasyMotion provides a much simpler way to use some motions in vim. It 40 | takes the `` out of `w` or `f{char}` by 41 | highlighting all possible choices and allowing you to press one key to 42 | jump directly to the target. 43 | 44 | When one of the available motions is triggered, all visible text 45 | preceding or following the cursor is faded, and motion targets are 46 | highlighted. 47 | 48 | EasyMotion is triggered by the provided mappings. This readme only covers the 49 | basics; please refer to 50 | [`:help easymotion.txt`](https://github.com/easymotion/vim-easymotion/blob/master/doc/easymotion.txt#L86) 51 | to see all the available mappings. 52 | 53 | Important notes 54 | ===== 55 | 56 | ### Default bindings 57 | 58 | **The default leader has been changed to `` to avoid 59 | conflicts with other plugins you may have installed.** This can easily be 60 | changed back to pre-1.3 behavior by rebinding the leader in your vimrc: 61 | 62 | ```vim 63 | map (easymotion-prefix) 64 | ``` 65 | 66 | All motions will then be triggered with `` by default, e.g. 67 | `s`, `gE`. 68 | 69 | ### For users of the forked version 70 | 71 | SelectLines and SelectPhrase are not actually *motions*, so I've moved them into 72 | separate plugins. 73 | 74 | - https://github.com/haya14busa/vim-easyoperator-line 75 | - https://github.com/haya14busa/vim-easyoperator-phrase 76 | 77 | Usage example for the base features 78 | ===== 79 | 80 | Lorem ipsum dolor sit amet. 81 | 82 | Type `w`(`(easymotion-w)`) to trigger the word motion `w`. 83 | When the motion is triggered, the text is updated (no braces are actually added, 84 | the text is highlighted in red by default): 85 | 86 | Lorem {a}psum {b}olor {c}it {d}met. 87 | 88 | Press `c` to jump to the beginning of the word "sit": 89 | 90 | Lorem ipsum dolor sit amet. 91 | 92 | Similarly, if you're looking for an "o", you can use the `f` motion. 93 | Type `fo`, and all "o" characters are highlighted: 94 | 95 | L{a}rem ipsum d{b}l{c}r sit amet. 96 | 97 | Press `b` to jump to the second "o": 98 | 99 | Lorem ipsum dolor sit amet. 100 | 101 | Jeffrey Way of Nettuts+ has also [written 102 | a tutorial](https://code.tutsplus.com/tutorials/vim-essential-plugin-easymotion--net-19223) 103 | about EasyMotion. 104 | 105 | New features in version 3.0 106 | ==== 107 | 108 | ### Overwin motions 109 | ![](https://raw.githubusercontent.com/haya14busa/i/2753bd4dd1dfdf5962dbdbffabf24244e4e14243/easymotion/overwin-motions.gif) 110 | 111 | EasyMotion now supports moving cursor across/over window. 112 | Since it doesn't make sense that moving cursor to other window while Visual or 113 | Operator-pending mode, overwin motions only provides mappings for Normal 114 | mode. Please use `nmap` to use overwin motions. Overwin motions only 115 | supports bi-directional motions. 116 | 117 | #### Example configuration 118 | 119 | ```vim 120 | " f{char} to move to {char} 121 | map f (easymotion-bd-f) 122 | nmap f (easymotion-overwin-f) 123 | 124 | " s{char}{char} to move to {char}{char} 125 | nmap s (easymotion-overwin-f2) 126 | 127 | " Move to line 128 | map L (easymotion-bd-jk) 129 | nmap L (easymotion-overwin-line) 130 | 131 | " Move to word 132 | map w (easymotion-bd-w) 133 | nmap w (easymotion-overwin-w) 134 | ``` 135 | 136 | #### Integration with incsearch.vim 137 | - [haya14busa/incsearch.vim](https://github.com/haya14busa/incsearch.vim) 138 | - [haya14busa/incsearch-easymotion.vim](https://github.com/haya14busa/incsearch-easymotion.vim) 139 | 140 | ```vim 141 | " You can use other keymappings like instead of if you want to 142 | " use these mappings as default search and sometimes want to move cursor with 143 | " EasyMotion. 144 | function! s:incsearch_config(...) abort 145 | return incsearch#util#deepextend(deepcopy({ 146 | \ 'modules': [incsearch#config#easymotion#module({'overwin': 1})], 147 | \ 'keymap': { 148 | \ "\": '(easymotion)' 149 | \ }, 150 | \ 'is_expr': 0 151 | \ }), get(a:, 1, {})) 152 | endfunction 153 | 154 | noremap / incsearch#go(incsearch_config()) 155 | noremap ? incsearch#go(incsearch_config({'command': '?'})) 156 | noremap g/ incsearch#go(incsearch_config({'is_stay': 1})) 157 | ``` 158 | 159 | ### Bonus fuzzy-search with EasyMotion 160 | 161 | ![](https://raw.githubusercontent.com/haya14busa/i/eab1d12a8bd322223d551956a4fd8a21d5c4bfe9/easymotion/fuzzy-incsearch-easymotion.gif) 162 | 163 | - [haya14busa/incsearch.vim](https://github.com/haya14busa/incsearch.vim) 164 | - [haya14busa/incsearch-fuzzy.vim](https://github.com/haya14busa/incsearch-fuzzy.vim) 165 | - [haya14busa/incsearch-easymotion.vim](https://github.com/haya14busa/incsearch-easymotion.vim) 166 | 167 | ```vim 168 | function! s:config_easyfuzzymotion(...) abort 169 | return extend(copy({ 170 | \ 'converters': [incsearch#config#fuzzyword#converter()], 171 | \ 'modules': [incsearch#config#easymotion#module({'overwin': 1})], 172 | \ 'keymap': {"\": '(easymotion)'}, 173 | \ 'is_expr': 0, 174 | \ 'is_stay': 1 175 | \ }), get(a:, 1, {})) 176 | endfunction 177 | 178 | noremap / incsearch#go(config_easyfuzzymotion()) 179 | ``` 180 | 181 | New features in version 2.0 182 | ==== 183 | 184 | ### Two key highlighting 185 | 186 | When EasyMotion runs out of single characters to highlight movement targets, it 187 | immediately shows you the keys you have to press. 188 | 189 | In previous versions you could not see the next character you would need to 190 | press until you entered the first one. This made movement over long distances 191 | less fluid. Now you can see at a glance exactly which characters to select to 192 | get to your destination. 193 | 194 | ### Bidirectional motions 195 | 196 | All motions now come in bidirectional variants (e.g. `(easymotion-s)`, 197 | `(easymotion-bd-w)` and so forth). 198 | By default, you can already jump forward or backward with `s`. A useful 199 | trick is to map `nmap s (easymotion-s)` to use `s` instead and save one 200 | keystroke! 201 | 202 | ### 2-character search motion 203 | 204 | You can now also perform a 2-character search, similar to [vim-seek](https://github.com/goldfeld/vim-seek)/[vim-sneak](https://github.com/justinmk/vim-sneak) with `(easymotion-s2)`. For example, you can highlight all words that start with `fu`. 205 | 206 | ![2-key-find-motion](https://f.cloud.github.com/assets/3797062/2039612/7cafcec8-89a5-11e3-8f2c-5f26a6b83efd.gif) 207 | 208 | ```vim 209 | " Gif config 210 | nmap s (easymotion-s2) 211 | nmap t (easymotion-t2) 212 | ``` 213 | 214 | ### n-character search motion 215 | 216 | You can also search for `n` characters, which can be used to replace the default search of Vim. 217 | It supports incremental highlighting and you can use `` and `` to scroll down/up a page. If you press 218 | ``, you get the usual EasyMotion highlighting and can jump to any matching target destination with a 219 | single keystroke. 220 | 221 | What sounds complicated should become clear if you look at the following examples. 222 | 223 | ![n-key-motion-scroll](https://f.cloud.github.com/assets/3797062/2039254/4fbf7276-899e-11e3-9bf3-1e446cabc097.gif) 224 | 225 | ![replace-search](https://f.cloud.github.com/assets/3797062/2039751/64b72bd8-89a8-11e3-80ea-2a6b578040b2.gif) 226 | 227 | ```vim 228 | " Gif config 229 | map / (easymotion-sn) 230 | omap / (easymotion-tn) 231 | 232 | " These `n` & `N` mappings are options. You do not have to map `n` & `N` to EasyMotion. 233 | " Without these mappings, `n` & `N` works fine. (These mappings just provide 234 | " different highlight method and have some other features ) 235 | map n (easymotion-next) 236 | map N (easymotion-prev) 237 | ``` 238 | 239 | ### Within line motion 240 | 241 | Every motion also has variants that are restricted to just the current line 242 | (e.g. `(easymotion-sl)`, `(easymotion-bd-wl)`, etc...). This can be 243 | helpful if you find the full search distracting or slows down vim. 244 | 245 | ### hjkl motions 246 | 247 | EasyMotion can be configured to avoid repetitive use of the `h` `j` `k` and 248 | `l` keys. 249 | 250 | ![hjkl-motion](https://f.cloud.github.com/assets/3797062/2039413/d8b32ab2-89a0-11e3-894f-3e81db084cfd.gif) 251 | 252 | ```vim 253 | " Gif config 254 | map l (easymotion-lineforward) 255 | map j (easymotion-j) 256 | map k (easymotion-k) 257 | map h (easymotion-linebackward) 258 | 259 | let g:EasyMotion_startofline = 0 " keep cursor column when JK motion 260 | ``` 261 | 262 | ### Smartcase & Smartsign 263 | 264 | This setting makes EasyMotion work similarly to Vim's `smartcase` option for 265 | global searches. 266 | 267 | ```vim 268 | let g:EasyMotion_smartcase = 1 269 | ``` 270 | 271 | With this option set, `v` will match both `v` and `V`, but `V` will match `V` 272 | only. Default: 0. 273 | 274 | ```vim 275 | let g:EasyMotion_use_smartsign_us = 1 " US layout 276 | " or 277 | let g:EasyMotion_use_smartsign_jp = 1 " JP layout 278 | ``` 279 | 280 | This applies the same concept, but for symbols and numerals. `1` will match `1` 281 | and `!`; `!` matches `!` only. Default: 0. 282 | 283 | 284 | ### Migemo feature (for Japanese user) 285 | 286 | ```vim 287 | let g:EasyMotion_use_migemo = 1 288 | ``` 289 | 290 | 291 | Easymotion can match multibyte Japanese characters with alphabetical input. 292 | For example, `sa` can search 'あ'. 293 | This feature doesn't require cmigemo because Easymotion includes regex 294 | patterns generated by cmigemo. However, installing `cmigemo` will make 295 | 2-character and n-character search motions to also support the migemo feature. 296 | Default:0 297 | 298 | 299 | ### Repeat motions 300 | 301 | #### Repeat the last motion 302 | 303 | `(easymotion-repeat)` 304 | 305 | #### Repeat the last find motion 306 | 307 | In a find motion (e.g. `(easymotion-s)`), type `` without 308 | input characters to find the last motion again. 309 | 310 | #### Jump to next/previous match (even on next/previous page) 311 | 312 | * `(easymotion-next)` 313 | * `(easymotion-prev)` 314 | 315 | #### Support for dot repeat 316 | 317 | This requires https://github.com/tpope/vim-repeat. 318 | 319 | You can use EasyMotion with operators and press `.` to repeat! 320 | It is well-behaved and consistent with the default behavior of Vim. 321 | 322 | ![repeat-motion](https://f.cloud.github.com/assets/3797062/2039538/0aef66aa-89a4-11e3-8242-c27a5208cfca.gif) 323 | 324 | ```vim 325 | " Gif config 326 | 327 | " Require tpope/vim-repeat to enable dot repeat support 328 | " Jump to anywhere with only `s{char}{target}` 329 | " `s` repeat last find motion. 330 | nmap s (easymotion-s) 331 | " Bidirectional & within line 't' motion 332 | omap t (easymotion-bd-tl) 333 | " Use uppercase target labels and type as a lower case 334 | let g:EasyMotion_use_upper = 1 335 | " type `l` and match `l`&`L` 336 | let g:EasyMotion_smartcase = 1 337 | " Smartsign (type `3` and match `3`&`#`) 338 | let g:EasyMotion_use_smartsign_us = 1 339 | ``` 340 | 341 | 342 | Installation 343 | ------------ 344 | ### Pathogen (https://github.com/tpope/vim-pathogen) 345 | ``` 346 | git clone https://github.com/easymotion/vim-easymotion ~/.vim/bundle/vim-easymotion 347 | ``` 348 | 349 | ### Vundle (https://github.com/gmarik/vundle) 350 | ``` 351 | Plugin 'easymotion/vim-easymotion' 352 | ``` 353 | 354 | ### NeoBundle (https://github.com/Shougo/neobundle.vim) 355 | ``` 356 | NeoBundle 'easymotion/vim-easymotion' 357 | ``` 358 | 359 | ### Vim-Plug (https://github.com/junegunn/vim-plug) 360 | ``` 361 | Plug 'easymotion/vim-easymotion' 362 | ``` 363 | 364 | ### Vim8 Native Plugin Manager (https://vimhelp.org/repeat.txt.html#packages) 365 | ``` 366 | git clone https://github.com/easymotion/vim-easymotion.git ~/.vim/pack/plugins/start/vim-easymotion 367 | ``` 368 | 369 | Minimal Configuration Tutorial 370 | ------------------------------ 371 | **I recommend configuring and map keys by yourself if you are true Vimmer.** 372 | 373 | **Please do not be satisfied with just installing vim-easymotion, configuring it yourself boost your productivity more and more!** 374 | 375 | Default `` prefix isn't easy to press, and I leave them just for backwards compatibility. 376 | You should at least change the prefix key like this `map (easymotion-prefix)` 377 | 378 | Minimal but useful vimrc example: 379 | 380 | ```vim 381 | let g:EasyMotion_do_mapping = 0 " Disable default mappings 382 | 383 | " Jump to anywhere you want with minimal keystrokes, with just one key binding. 384 | " `s{char}{label}` 385 | nmap s (easymotion-overwin-f) 386 | " or 387 | " `s{char}{char}{label}` 388 | " Need one more keystroke, but on average, it may be more comfortable. 389 | nmap s (easymotion-overwin-f2) 390 | 391 | " Turn on case-insensitive feature 392 | let g:EasyMotion_smartcase = 1 393 | 394 | " JK motions: Line motions 395 | map j (easymotion-j) 396 | map k (easymotion-k) 397 | ``` 398 | Now, all you need to remember is `s` and JK motions bindings, and it's good enough to boost your cursor speed! 399 | 400 | **`s`** is bidirectional find motion, you can move to anywhere with it. 401 | 402 | **`j`** & **`k`** make it easy to move to the lines. 403 | 404 | Of course, you can use any key you want instead of `s` such as ``, `s`, etc... 405 | 406 | If you want to use more useful mappings, please see [:h easymotion.txt](https://github.com/easymotion/vim-easymotion/blob/master/doc/easymotion.txt) for more detail. 407 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | 3 | task :ci => [:dump, :test] 4 | 5 | task :dump do 6 | sh 'vim --version' 7 | end 8 | 9 | task :test do 10 | sh 'bundle exec vim-flavor test' 11 | end 12 | -------------------------------------------------------------------------------- /autoload/EasyMotion/cmigemo.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " FILE: autoload/EasyMotion/cmigemo.vim 3 | " AUTHOR: haya14busa 4 | " License: MIT license {{{ 5 | " Permission is hereby granted, free of charge, to any person obtaining 6 | " a copy of this software and associated documentation files (the 7 | " "Software"), to deal in the Software without restriction, including 8 | " without limitation the rights to use, copy, modify, merge, publish, 9 | " distribute, sublicense, and/or sell copies of the Software, and to 10 | " permit persons to whom the Software is furnished to do so, subject to 11 | " the following conditions: 12 | " 13 | " The above copyright notice and this permission notice shall be included 14 | " in all copies or substantial portions of the Software. 15 | " 16 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | " }}} 24 | "============================================================================= 25 | scriptencoding utf-8 26 | " Saving 'cpoptions' {{{ 27 | let s:save_cpo = &cpo 28 | set cpo&vim 29 | " }}} 30 | 31 | function! s:has_vimproc() "{{{ 32 | if !exists('s:exists_vimproc') 33 | try 34 | silent call vimproc#version() 35 | let s:exists_vimproc = 1 36 | catch 37 | let s:exists_vimproc = 0 38 | endtry 39 | endif 40 | 41 | return s:exists_vimproc 42 | endfunction "}}} 43 | 44 | function! EasyMotion#cmigemo#system(...) "{{{ 45 | return call(s:has_vimproc() ? 'vimproc#system' : 'system', a:000) 46 | endfunction "}}} 47 | 48 | function! s:SearchDict2(name) "{{{ 49 | let path = $VIM . ',' . &runtimepath 50 | let dict = globpath(path, "dict/".a:name) 51 | if dict == '' 52 | let dict = globpath(path, a:name) 53 | endif 54 | if dict == '' 55 | for path in [ 56 | \ '/usr/local/share/migemo/', 57 | \ '/usr/local/share/cmigemo/', 58 | \ '/usr/local/share/', 59 | \ '/usr/share/cmigemo/', 60 | \ '/usr/share/', 61 | \ ] 62 | let path = path . a:name 63 | if filereadable(path) 64 | let dict = path 65 | break 66 | endif 67 | endfor 68 | endif 69 | let dict = matchstr(dict, "^[^\]*") 70 | return dict 71 | endfunction "}}} 72 | 73 | function! s:SearchDict() "{{{ 74 | for path in [ 75 | \ 'migemo/'.&encoding.'/migemo-dict', 76 | \ &encoding.'/migemo-dict', 77 | \ 'migemo-dict', 78 | \ ] 79 | let dict = s:SearchDict2(path) 80 | if dict != '' 81 | return dict 82 | endif 83 | endfor 84 | echoerr 'a dictionary for migemo is not found' 85 | echoerr 'your encoding is '.&encoding 86 | endfunction "}}} 87 | 88 | function! EasyMotion#cmigemo#getMigemoPattern(input) "{{{ 89 | if !exists('s:migemodict') 90 | let s:migemodict = s:SearchDict() 91 | endif 92 | 93 | if has('migemo') 94 | " Use migemo(). 95 | if &migemodict !=# '' 96 | return migemo(a:input) 97 | endif 98 | let &migemodict = s:migemodict 99 | try 100 | return migemo(a:input) 101 | finally 102 | let &migemodict = '' 103 | endtry 104 | elseif executable('cmigemo') 105 | " Use cmigemo. 106 | return EasyMotion#cmigemo#system('cmigemo -v -w "'.a:input.'" -d "'.s:migemodict.'"') 107 | else 108 | " Not supported 109 | return a:input 110 | endif 111 | endfunction "}}} 112 | 113 | " Restore 'cpoptions' {{{ 114 | let &cpo = s:save_cpo 115 | unlet s:save_cpo 116 | " }}} 117 | " vim: fdm=marker:et:ts=4:sw=4:sts=4 118 | -------------------------------------------------------------------------------- /autoload/EasyMotion/command_line.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " FILE: autoload/EasyMotion/command_line.vim 3 | " AUTHOR: haya14busa 4 | " Reference: https://github.com/osyo-manga/vim-over 5 | " License: MIT license {{{ 6 | " Permission is hereby granted, free of charge, to any person obtaining 7 | " a copy of this software and associated documentation files (the 8 | " "Software"), to deal in the Software without restriction, including 9 | " without limitation the rights to use, copy, modify, merge, publish, 10 | " distribute, sublicense, and/or sell copies of the Software, and to 11 | " permit persons to whom the Software is furnished to do so, subject to 12 | " the following conditions: 13 | " 14 | " The above copyright notice and this permission notice shall be included 15 | " in all copies or substantial portions of the Software. 16 | " 17 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | " }}} 25 | "============================================================================= 26 | scriptencoding utf-8 27 | " Saving 'cpoptions' {{{ 28 | let s:save_cpo = &cpo 29 | set cpo&vim 30 | " }}} 31 | 32 | " CommandLine: 33 | let s:V = vital#easymotion#new() 34 | let s:cmdline = s:V.import('Over.Commandline.Base') 35 | let s:modules = s:V.import("Over.Commandline.Modules") 36 | let s:search = s:cmdline.make() 37 | let s:search.highlights.prompt = 'Question' 38 | 39 | " Add Module: {{{ 40 | call s:search.connect('Exit') 41 | call s:search.connect('Cancel') 42 | call s:search.connect('Redraw') 43 | call s:search.connect('DrawCommandline') 44 | call s:search.connect('Delete') 45 | call s:search.connect('CursorMove') 46 | call s:search.connect('Paste') 47 | call s:search.connect('BufferComplete') 48 | call s:search.connect('InsertRegister') 49 | call s:search.connect('ExceptionExit') 50 | call s:search.connect(s:modules.get('ExceptionMessage').make('EasyMotion: ', 'echom')) 51 | call s:search.connect(s:modules.get('History').make('/')) 52 | call s:search.connect(s:modules.get('NoInsert').make_special_chars()) 53 | call s:search.connect(s:modules.get('KeyMapping').make_emacs()) 54 | call s:search.connect(s:modules.get('Doautocmd').make('EMCommandLine')) 55 | 56 | let s:module = { 57 | \ "name" : "EasyMotion", 58 | \} 59 | function! s:module.on_char_pre(cmdline) 60 | if a:cmdline.is_input("(em-scroll-f)") 61 | call s:scroll(0) 62 | call a:cmdline.setchar('') 63 | elseif a:cmdline.is_input("(em-scroll-b)") 64 | call s:scroll(1) 65 | call a:cmdline.setchar('') 66 | elseif a:cmdline.is_input("(em-jumpback)") 67 | keepjumps call setpos('.', s:save_orig_pos) 68 | let s:orig_pos = s:save_orig_pos 69 | let s:orig_line_start = getpos('w0') 70 | let s:orig_line_end = getpos('w$') 71 | let s:direction = s:save_direction 72 | call a:cmdline.setchar('') 73 | elseif a:cmdline.is_input("(em-openallfold)") 74 | " TODO: better solution 75 | normal! zR 76 | call a:cmdline.setchar('') 77 | endif 78 | endfunction 79 | call s:search.connect(s:module) 80 | "}}} 81 | 82 | " CommandLine Keymap: {{{ 83 | " .keymapping() won't be remapped by user defined KeyMappings. 84 | function! s:search.keymapping() "{{{ 85 | return { 86 | \ "\" : { 87 | \ "key" : "(exit)", 88 | \ "noremap" : 1, 89 | \ "lock" : 1, 90 | \ }, 91 | \ } 92 | endfunction "}}} 93 | 94 | call s:search.cnoremap("\", '(buffer-complete)') 95 | call s:search.cnoremap("\", '(em-scroll-f)') 96 | call s:search.cnoremap("\", '(em-scroll-b)') 97 | call s:search.cnoremap("\", '(em-jumpback)') 98 | call s:search.cnoremap("\", '(em-openallfold)') 99 | 100 | " Fins Motion CommandLine Mapping Command: {{{ 101 | function! EasyMotion#command_line#cmap(args) 102 | let lhs = s:as_keymapping(a:args[0]) 103 | let rhs = s:as_keymapping(a:args[1]) 104 | call s:search.cmap(lhs, rhs) 105 | endfunction 106 | function! EasyMotion#command_line#cnoremap(args) 107 | let lhs = s:as_keymapping(a:args[0]) 108 | let rhs = s:as_keymapping(a:args[1]) 109 | call s:search.cnoremap(lhs, rhs) 110 | endfunction 111 | function! EasyMotion#command_line#cunmap(lhs) 112 | let lhs = s:as_keymapping(a:lhs) 113 | call s:search.cunmap(lhs) 114 | endfunction 115 | function! s:as_keymapping(key) 116 | execute 'let result = "' . substitute(a:key, '\(<.\{-}>\)', '\\\1', 'g') . '"' 117 | return result 118 | endfunction 119 | "}}} 120 | "}}} 121 | 122 | " Event: {{{ 123 | function! s:search.on_enter(cmdline) "{{{ 124 | if s:num_strokes == -1 125 | call EasyMotion#highlight#delete_highlight() 126 | call EasyMotion#helper#VarReset('&scrolloff', 0) 127 | if g:EasyMotion_do_shade 128 | call EasyMotion#highlight#add_highlight('\_.*', 129 | \ g:EasyMotion_hl_group_shade) 130 | endif 131 | endif 132 | if g:EasyMotion_cursor_highlight 133 | call EasyMotion#highlight#add_highlight('\%#', 134 | \ g:EasyMotion_hl_inc_cursor) 135 | endif 136 | endfunction "}}} 137 | function! s:search.on_leave(cmdline) "{{{ 138 | if s:num_strokes == -1 139 | call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search) 140 | if g:EasyMotion_do_shade 141 | call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_group_shade) 142 | endif 143 | endif 144 | if g:EasyMotion_cursor_highlight 145 | call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_cursor) 146 | endif 147 | endfunction "}}} 148 | function! s:search.on_char(cmdline) "{{{ 149 | if s:num_strokes == -1 150 | let re = s:search.getline() 151 | if EasyMotion#helper#should_case_sensitive(re, 1) 152 | let case_flag = '\c' 153 | else 154 | let case_flag = '\C' 155 | endif 156 | let re .= case_flag 157 | if g:EasyMotion_inc_highlight 158 | call s:inc_highlight(re) 159 | endif 160 | if g:EasyMotion_off_screen_search 161 | call s:off_screen_search(re) 162 | endif 163 | elseif s:search.line.length() >= s:num_strokes 164 | call s:search.exit() 165 | endif 166 | endfunction "}}} 167 | "}}} 168 | 169 | " Main: 170 | function! EasyMotion#command_line#GetInput(num_strokes, prev, direction) "{{{ 171 | let s:num_strokes = a:num_strokes 172 | 173 | let s:prompt_base = s:getPromptMessage(a:num_strokes) 174 | call s:search.set_prompt(s:prompt_base) 175 | 176 | " Screen: cursor position, first and last line 177 | let s:orig_pos = getpos('.') 178 | let s:orig_line_start = getpos('w0') 179 | let s:orig_line_end = getpos('w$') 180 | let s:save_orig_pos = deepcopy(s:orig_pos) 181 | 182 | " Direction: 183 | let s:direction = a:direction == 1 ? 'b' : '' 184 | let s:save_direction = deepcopy(s:direction) 185 | 186 | let input = s:search.get() 187 | if input == '' && ! s:search.exit_code() 188 | return a:prev 189 | elseif s:search.exit_code() == 1 || s:search.exit_code() == -1 190 | call s:Cancell() 191 | return '' 192 | else 193 | return input 194 | endif 195 | endfunction "}}} 196 | 197 | " Helper: 198 | function! s:Cancell() " {{{ 199 | call EasyMotion#highlight#delete_highlight() 200 | call EasyMotion#helper#VarReset('&scrolloff') 201 | keepjumps call setpos('.', s:save_orig_pos) 202 | if g:EasyMotion_verbose 203 | echo 'EasyMotion: Cancelled' 204 | endif 205 | return '' 206 | endfunction " }}} 207 | function! s:getPromptMessage(num_strokes) "{{{ 208 | if a:num_strokes == 1 209 | let prompt = substitute( 210 | \ substitute(g:EasyMotion_prompt,'{n}', a:num_strokes, 'g'), 211 | \ '(s)', '', 'g') 212 | elseif a:num_strokes == -1 213 | let prompt = substitute( 214 | \ substitute(g:EasyMotion_prompt, '{n}\s\{0,1}', '', 'g'), 215 | \ '(s)', 's', 'g') 216 | else 217 | let prompt = substitute( 218 | \ substitute(g:EasyMotion_prompt,'{n}', a:num_strokes, 'g'), 219 | \ '(s)', 's', 'g') 220 | endif 221 | return prompt 222 | endfunction "}}} 223 | 224 | function! s:off_screen_search(re) "{{{ 225 | " First: search within visible screen range 226 | call s:adjust_screen() 227 | " Error occur when '\zs' without '!' 228 | silent! let pos = searchpos(a:re, s:direction . 'n', s:orig_line_end[1]) 229 | if pos != [0, 0] 230 | " Restore cursor posision 231 | keepjumps call setpos('.', s:orig_pos) 232 | else 233 | " Second: if there were no much, search off screen 234 | silent! let pos = searchpos(a:re, s:direction) 235 | if pos != [0, 0] 236 | " Match 237 | keepjumps call setpos('.', pos) 238 | " Move cursor 239 | if s:save_direction != 'b' 240 | normal! zzH0 241 | else 242 | normal! zzL0 243 | endif 244 | else 245 | " No much 246 | call s:adjust_screen() 247 | keepjumps call setpos('.', s:orig_pos) 248 | endif 249 | endif 250 | " redraw 251 | endfunction "}}} 252 | function! s:adjust_screen() "{{{ 253 | if s:save_direction != 'b' 254 | " Forward 255 | keepjumps call setpos('.', s:orig_line_start) 256 | normal! zt 257 | else 258 | " Backward 259 | keepjumps call setpos('.', s:orig_line_end) 260 | normal! zb 261 | endif 262 | endfunction "}}} 263 | function! s:scroll(direction) "{{{ 264 | " direction: 0 -> forward, 1 -> backward 265 | exec a:direction == 0 ? "normal! \" : "normal! \" 266 | let s:orig_pos = getpos('.') 267 | let s:orig_line_start = getpos('w0') 268 | let s:orig_line_end = getpos('w$') 269 | let s:direction = a:direction == 0 ? '' : 'b' 270 | endfunction "}}} 271 | function! s:inc_highlight(re) "{{{ 272 | call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search) 273 | if s:search.line.length() > 0 274 | " Error occur when '\zs' without '!' 275 | silent! call EasyMotion#highlight#add_highlight(a:re, g:EasyMotion_hl_inc_search) 276 | endif 277 | endfunction "}}} 278 | 279 | " Restore 'cpoptions' {{{ 280 | let &cpo = s:save_cpo 281 | unlet s:save_cpo 282 | " }}} 283 | " vim: fdm=marker:et:ts=4:sw=4:sts=4 284 | -------------------------------------------------------------------------------- /autoload/EasyMotion/helper.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " FILE: autoload/EasyMotion/helper.vim 3 | " AUTHOR: haya14busa 4 | " License: MIT license {{{ 5 | " Permission is hereby granted, free of charge, to any person obtaining 6 | " a copy of this software and associated documentation files (the 7 | " "Software"), to deal in the Software without restriction, including 8 | " without limitation the rights to use, copy, modify, merge, publish, 9 | " distribute, sublicense, and/or sell copies of the Software, and to 10 | " permit persons to whom the Software is furnished to do so, subject to 11 | " the following conditions: 12 | " 13 | " The above copyright notice and this permission notice shall be included 14 | " in all copies or substantial portions of the Software. 15 | " 16 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | " }}} 24 | "============================================================================= 25 | scriptencoding utf-8 26 | " Saving 'cpoptions' {{{ 27 | let s:save_cpo = &cpo 28 | set cpo&vim 29 | " }}} 30 | 31 | function! EasyMotion#helper#mode(flag) "{{{ 32 | return mode(a:flag) == "\" ? "C-v" : mode(a:flag) 33 | endfunction "}}} 34 | 35 | function! EasyMotion#helper#get_char_by_coord(coord) "{{{ 36 | " @param coord: [lnum, col] or [bufnum, lnum, col, off] 37 | if len(a:coord) == 4 38 | let [line_num, col_num] = [a:coord[1], a:coord[2]] 39 | else 40 | let [line_num, col_num] = a:coord 41 | endif 42 | let target_col_regexp = '\%' . (col_num) . 'c.' 43 | return matchstr(getline(line_num), target_col_regexp) 44 | endfunction "}}} 45 | 46 | function! EasyMotion#helper#is_greater_coords(coords1, coords2) "{{{ 47 | " [line_num, col_num] < [line_num, col_num] 48 | " 49 | " coords1 < coords2 : return 1 50 | " coords1 > coords2 : return -1 51 | " coords1 == coords2 : return 0 52 | if a:coords1 == a:coords2 | return 0 | endif 53 | 54 | if a:coords1[0] < a:coords2[0] 55 | return 1 56 | elseif a:coords1[0] > a:coords2[0] 57 | return -1 58 | endif 59 | 60 | " Same line 61 | if a:coords1[1] < a:coords2[1] 62 | return 1 63 | elseif a:coords1[1] > a:coords2[1] 64 | return -1 65 | endif 66 | endfunction "}}} 67 | 68 | function! EasyMotion#helper#is_folded(line) "{{{ 69 | " Return false if g:EasyMotion_skipfoldedline == 1 70 | " and line is start of folded lines 71 | let _foldclosed = foldclosed(a:line) 72 | return _foldclosed != -1 && 73 | \ (g:EasyMotion_skipfoldedline == 1 || a:line != _foldclosed) 74 | endfunction "}}} 75 | function! EasyMotion#helper#should_case_sensitive(input, is_search) "{{{ 76 | if !a:is_search 77 | if g:EasyMotion_smartcase == 0 78 | return 0 79 | else 80 | " return 1 if input didn't match uppercase letter 81 | return match(a:input, '\u') == -1 82 | endif 83 | endif 84 | 85 | if (g:EasyMotion_smartcase == 1 && match(a:input, '\u') == -1) || 86 | \ (&ignorecase && &smartcase && match(a:input, '\u') == -1) || 87 | \ (&ignorecase && !&smartcase) 88 | return 1 89 | endif 90 | return 0 91 | endfunction "}}} 92 | function! EasyMotion#helper#silent_feedkeys(expr, name, ...) "{{{ 93 | " Ref: 94 | " https://github.com/osyo-manga/vim-over/blob/d51b028c29661d4a5f5b79438ad6d69266753711/autoload/over.vim#L6 95 | let mode = get(a:, 1, "m") 96 | let name = "easymotion-" . a:name 97 | let map = printf("(%s)", name) 98 | if mode == "n" 99 | let command = "nnoremap" 100 | else 101 | let command = "nmap" 102 | endif 103 | execute command "" map printf("%s:nunmap %s", a:expr, map) 104 | if mode(1) !=# 'ce' 105 | " FIXME: mode(1) !=# 'ce' exists only for the test 106 | " :h feedkeys() doesn't work while runnning a test script 107 | " https://github.com/kana/vim-vspec/issues/27 108 | call feedkeys(printf("\(%s)", name)) 109 | endif 110 | endfunction "}}} 111 | function! EasyMotion#helper#VarReset(var, ...) "{{{ 112 | if ! exists('s:var_reset') 113 | let s:var_reset = {} 114 | endif 115 | 116 | if a:0 == 0 && has_key(s:var_reset, a:var) 117 | " Reset var to original value 118 | " setbufvar( or bufname): '' or '%' can be used for the current buffer 119 | call setbufvar('%', a:var, s:var_reset[a:var]) 120 | elseif a:0 == 1 121 | " Save original value and set new var value 122 | 123 | let new_value = a:0 == 1 ? a:1 : '' 124 | 125 | " Store original value 126 | let s:var_reset[a:var] = getbufvar("", a:var) 127 | 128 | " Set new var value 129 | call setbufvar('%', a:var, new_value) 130 | endif 131 | endfunction "}}} 132 | 133 | " Migemo {{{ 134 | function! EasyMotion#helper#load_migemo_dict() "{{{ 135 | let enc = &l:encoding 136 | if enc ==# 'utf-8' 137 | return EasyMotion#migemo#utf8#load_dict() 138 | elseif enc ==# 'cp932' 139 | return EasyMotion#migemo#cp932#load_dict() 140 | elseif enc ==# 'euc-jp' 141 | return EasyMotion#migemo#eucjp#load_dict() 142 | else 143 | let g:EasyMotion_use_migemo = 0 144 | throw "Error: ".enc." is not supported. Migemo is made disabled." 145 | endif 146 | endfunction "}}} 147 | 148 | " EasyMotion#helper#strchars() {{{ 149 | if exists('*strchars') 150 | function! EasyMotion#helper#strchars(str) 151 | return strchars(a:str) 152 | endfunction 153 | else 154 | function! EasyMotion#helper#strchars(str) 155 | return strlen(substitute(a:str, ".", "x", "g")) 156 | endfunction 157 | endif "}}} 158 | function! EasyMotion#helper#include_multibyte_char(str) "{{{ 159 | return strlen(a:str) != EasyMotion#helper#strchars(a:str) 160 | endfunction "}}} 161 | 162 | function! EasyMotion#helper#vcol(expr) abort 163 | let col_num = col(a:expr) 164 | let line = getline(a:expr) 165 | let before_line = col_num > 2 ? line[: col_num - 2] 166 | \ : col_num is# 2 ? line[0] 167 | \ : '' 168 | let vcol_num = 1 169 | for c in split(before_line, '\zs') 170 | let vcol_num += c is# "\t" ? s:_virtual_tab2spacelen(vcol_num) : len(c) 171 | endfor 172 | return vcol_num 173 | endfunction 174 | 175 | function! s:_virtual_tab2spacelen(col_num) abort 176 | return &tabstop - ((a:col_num - 1) % &tabstop) 177 | endfunction 178 | 179 | "}}} 180 | 181 | " Restore 'cpoptions' {{{ 182 | let &cpo = s:save_cpo 183 | unlet s:save_cpo 184 | " }}} 185 | " vim: fdm=marker:et:ts=4:sw=4:sts=4 186 | -------------------------------------------------------------------------------- /autoload/EasyMotion/highlight.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " FILE: highlight.vim 3 | " AUTHOR: haya14busa 4 | " Reference: https://github.com/t9md/vim-smalls 5 | " License: MIT license {{{ 6 | " Permission is hereby granted, free of charge, to any person obtaining 7 | " a copy of this software and associated documentation files (the 8 | " "Software"), to deal in the Software without restriction, including 9 | " without limitation the rights to use, copy, modify, merge, publish, 10 | " distribute, sublicense, and/or sell copies of the Software, and to 11 | " permit persons to whom the Software is furnished to do so, subject to 12 | " the following conditions: 13 | " 14 | " The above copyright notice and this permission notice shall be included 15 | " in all copies or substantial portions of the Software. 16 | " 17 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | " }}} 25 | "============================================================================= 26 | scriptencoding utf-8 27 | " Saving 'cpoptions' {{{ 28 | let s:save_cpo = &cpo 29 | set cpo&vim 30 | " }}} 31 | 32 | function! EasyMotion#highlight#load() 33 | "load 34 | endfunction 35 | 36 | " -- Default highlighting ---------------- {{{ 37 | let g:EasyMotion_hl_group_target = get(g:, 38 | \ 'EasyMotion_hl_group_target', 'EasyMotionTarget') 39 | let g:EasyMotion_hl2_first_group_target = get(g:, 40 | \ 'EasyMotion_hl2_first_group_target', 'EasyMotionTarget2First') 41 | let g:EasyMotion_hl2_second_group_target = get(g:, 42 | \ 'EasyMotion_hl2_second_group_target', 'EasyMotionTarget2Second') 43 | let g:EasyMotion_hl_group_shade = get(g:, 44 | \ 'EasyMotion_hl_group_shade', 'EasyMotionShade') 45 | 46 | let g:EasyMotion_hl_inc_search = get(g:, 47 | \ 'EasyMotion_hl_inc_search', 'EasyMotionIncSearch') 48 | let g:EasyMotion_hl_inc_cursor = get(g:, 49 | \ 'EasyMotion_hl_inc_cursor', 'EasyMotionIncCursor') 50 | let g:EasyMotion_hl_move = get(g:, 51 | \ 'EasyMotion_hl_move', 'EasyMotionMoveHL') 52 | 53 | let s:target_hl_defaults = { 54 | \ 'gui' : ['NONE', '#ff0000' , 'bold'] 55 | \ , 'cterm256': ['NONE', '196' , 'bold'] 56 | \ , 'cterm' : ['NONE', 'red' , 'bold'] 57 | \ } 58 | 59 | let s:target_hl2_first_defaults = { 60 | \ 'gui' : ['NONE', '#ffb400' , 'bold'] 61 | \ , 'cterm256': ['NONE', '11' , 'bold'] 62 | \ , 'cterm' : ['NONE', 'yellow' , 'bold'] 63 | \ } 64 | 65 | let s:target_hl2_second_defaults = { 66 | \ 'gui' : ['NONE', '#b98300' , 'bold'] 67 | \ , 'cterm256': ['NONE', '3' , 'bold'] 68 | \ , 'cterm' : ['NONE', 'yellow' , 'bold'] 69 | \ } 70 | 71 | let s:shade_hl_defaults = { 72 | \ 'gui' : ['NONE', '#777777' , 'NONE'] 73 | \ , 'cterm256': ['NONE', '242' , 'NONE'] 74 | \ , 'cterm' : ['NONE', 'grey' , 'NONE'] 75 | \ } 76 | 77 | let s:shade_hl_line_defaults = { 78 | \ 'gui' : ['red' , '#FFFFFF' , 'NONE'] 79 | \ , 'cterm256': ['red' , '242' , 'NONE'] 80 | \ , 'cterm' : ['red' , 'grey' , 'NONE'] 81 | \ } 82 | 83 | let s:target_hl_inc = { 84 | \ 'gui' : ['NONE', '#7fbf00' , 'bold'] 85 | \ , 'cterm256': ['NONE', '40' , 'bold'] 86 | \ , 'cterm' : ['NONE', 'green' , 'bold'] 87 | \ } 88 | let s:target_hl_inc_cursor = { 89 | \ 'gui' : ['#ACDBDA', '#121813' , 'bold'] 90 | \ , 'cterm256': ['cyan' , '232' , 'bold'] 91 | \ , 'cterm' : ['cyan' , 'black' , 'bold'] 92 | \ } 93 | let s:target_hl_move = { 94 | \ 'gui' : ['#7fbf00', '#121813' , 'bold'] 95 | \ , 'cterm256': ['green' , '15' , 'bold'] 96 | \ , 'cterm' : ['green' , 'white' , 'bold'] 97 | \ } 98 | " }}} 99 | function! EasyMotion#highlight#InitHL(group, colors) " {{{ 100 | let group_default = a:group . 'Default' 101 | 102 | " Prepare highlighting variables 103 | let guihl = printf('guibg=%s guifg=%s gui=%s', a:colors.gui[0], a:colors.gui[1], a:colors.gui[2]) 104 | let ctermhl = &t_Co == 256 105 | \ ? printf('ctermbg=%s ctermfg=%s cterm=%s', a:colors.cterm256[0], a:colors.cterm256[1], a:colors.cterm256[2]) 106 | \ : printf('ctermbg=%s ctermfg=%s cterm=%s', a:colors.cterm[0], a:colors.cterm[1], a:colors.cterm[2]) 107 | 108 | " Create default highlighting group 109 | execute printf('hi default %s %s %s', group_default, guihl, ctermhl) 110 | 111 | " Check if the hl group exists 112 | if hlexists(a:group) 113 | redir => hlstatus | exec 'silent hi ' . a:group | redir END 114 | 115 | " Return if the group isn't cleared 116 | if hlstatus !~ 'cleared' 117 | return 118 | endif 119 | endif 120 | 121 | " No colors are defined for this group, link to defaults 122 | execute printf('hi default link %s %s', a:group, group_default) 123 | endfunction " }}} 124 | function! EasyMotion#highlight#init() "{{{ 125 | call EasyMotion#highlight#InitHL(g:EasyMotion_hl_group_target, s:target_hl_defaults) 126 | call EasyMotion#highlight#InitHL(g:EasyMotion_hl2_first_group_target, s:target_hl2_first_defaults) 127 | call EasyMotion#highlight#InitHL(g:EasyMotion_hl2_second_group_target, s:target_hl2_second_defaults) 128 | call EasyMotion#highlight#InitHL(g:EasyMotion_hl_group_shade, s:shade_hl_defaults) 129 | call EasyMotion#highlight#InitHL(g:EasyMotion_hl_inc_search, s:target_hl_inc) 130 | call EasyMotion#highlight#InitHL(g:EasyMotion_hl_inc_cursor, s:target_hl_inc_cursor) 131 | call EasyMotion#highlight#InitHL(g:EasyMotion_hl_move, s:target_hl_move) 132 | if exists(':CSApprox') == 2 && g:EasyMotion_force_csapprox 133 | "TODO: better solution or remove completly 134 | CSApprox! 135 | endif 136 | endfunction "}}} 137 | 138 | " Reset highlighting after loading a new color scheme {{{ 139 | augroup EasyMotionInitHL 140 | autocmd! 141 | autocmd ColorScheme * call EasyMotion#highlight#init() 142 | augroup end 143 | " }}} 144 | 145 | call EasyMotion#highlight#init() 146 | " Init: {{{ 147 | let s:h = {} 148 | let s:h.ids = {} 149 | let s:priorities = { 150 | \ g:EasyMotion_hl_group_target : 100, 151 | \ g:EasyMotion_hl2_first_group_target : 100, 152 | \ g:EasyMotion_hl2_second_group_target : 100, 153 | \ g:EasyMotion_hl_group_shade : 0, 154 | \ g:EasyMotion_hl_inc_search : 1, 155 | \ g:EasyMotion_hl_inc_cursor : 2, 156 | \ g:EasyMotion_hl_move : 0, 157 | \ } 158 | for s:group in keys(s:priorities) 159 | let s:h.ids[s:group] = [] 160 | endfor 161 | unlet s:group 162 | "}}} 163 | 164 | function! EasyMotion#highlight#delete_highlight(...) "{{{ 165 | let groups = !empty(a:000) ? a:000 : keys(s:priorities) 166 | for group in groups 167 | for id in s:h.ids[group] 168 | silent! call matchdelete(id) 169 | endfor 170 | let s:h.ids[group] = [] 171 | endfor 172 | endfunction "}}} 173 | function! EasyMotion#highlight#add_highlight(re, group) "{{{ 174 | call add(s:h.ids[a:group], matchadd(a:group, a:re, s:priorities[a:group])) 175 | endfunction "}}} 176 | function! EasyMotion#highlight#add_pos_highlight(line_num, col_num, group) "{{{ 177 | call add(s:h.ids[a:group], matchaddpos(a:group, [[a:line_num, a:col_num]], s:priorities[a:group])) 178 | endfunction "}}} 179 | function! EasyMotion#highlight#attach_autocmd() "{{{ 180 | " Reference: https://github.com/justinmk/vim-sneak 181 | augroup plugin-easymotion 182 | autocmd! 183 | autocmd InsertEnter,WinLeave,BufLeave 184 | \ silent! call EasyMotion#highlight#delete_highlight() 185 | \ | autocmd! plugin-easymotion * 186 | autocmd CursorMoved 187 | \ autocmd plugin-easymotion CursorMoved 188 | \ silent! call EasyMotion#highlight#delete_highlight() 189 | \ | autocmd! plugin-easymotion * 190 | augroup END 191 | endfunction "}}} 192 | function! EasyMotion#highlight#add_color_group(new_groups) "{{{ 193 | let s:priorities = extend(deepcopy(s:priorities), a:new_groups) 194 | for group in keys(a:new_groups) 195 | let s:h.ids[group] = [] 196 | endfor 197 | endfunction "}}} 198 | 199 | function! EasyMotion#highlight#capture(hlname) "{{{ 200 | " Based On: https://github.com/t9md/vim-ezbar 201 | " https://github.com/osyo-manga/vital-over 202 | let hlname = a:hlname 203 | if !hlexists(hlname) 204 | return 205 | endif 206 | while 1 207 | let save_verbose = &verbose 208 | let &verbose = 0 209 | try 210 | redir => HL_SAVE 211 | execute 'silent! highlight ' . hlname 212 | redir END 213 | finally 214 | let &verbose = save_verbose 215 | endtry 216 | if !empty(matchstr(HL_SAVE, 'xxx cleared$')) 217 | return '' 218 | endif 219 | " follow highlight link 220 | let ml = matchlist(HL_SAVE, 'links to \zs.*') 221 | if !empty(ml) 222 | let hlname = ml[0] 223 | continue 224 | endif 225 | break 226 | endwhile 227 | let HL_SAVE = substitute(matchstr(HL_SAVE, 'xxx \zs.*'), 228 | \ '[ \t\n]\+', ' ', 'g') 229 | return [hlname, HL_SAVE] 230 | endfunction "}}} 231 | function! EasyMotion#highlight#turn_off(hl) "{{{ 232 | if type(a:hl) != type([]) 233 | return 234 | endif 235 | execute 'highlight ' . a:hl[0] . ' NONE' 236 | endfunction "}}} 237 | function! EasyMotion#highlight#turn_on(hl) "{{{ 238 | if type(a:hl) != type([]) 239 | return 240 | endif 241 | execute 'highlight ' . a:hl[0] . ' ' . a:hl[1] 242 | endfunction "}}} 243 | 244 | " Restore 'cpoptions' {{{ 245 | let &cpo = s:save_cpo 246 | unlet s:save_cpo 247 | " }}} 248 | " __END__ {{{ 249 | " vim: expandtab softtabstop=4 shiftwidth=4 250 | " vim: foldmethod=marker 251 | " }}} 252 | -------------------------------------------------------------------------------- /autoload/EasyMotion/migemo/cp932.vim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easymotion/vim-easymotion/b3cfab2a6302b3b39f53d9fd2cd997e1127d7878/autoload/EasyMotion/migemo/cp932.vim -------------------------------------------------------------------------------- /autoload/EasyMotion/migemo/eucjp.vim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easymotion/vim-easymotion/b3cfab2a6302b3b39f53d9fd2cd997e1127d7878/autoload/EasyMotion/migemo/eucjp.vim -------------------------------------------------------------------------------- /autoload/EasyMotion/overwin.vim: -------------------------------------------------------------------------------- 1 | let s:V = vital#easymotion#new() 2 | let s:HitAHintMotion = s:V.import('HitAHint.Motion') 3 | 4 | call EasyMotion#init() 5 | 6 | function! EasyMotion#overwin#move(pattern) abort 7 | return s:HitAHintMotion.move(a:pattern, { 8 | \ 'keys': g:EasyMotion_keys, 9 | \ 'use_upper': g:EasyMotion_use_upper, 10 | \ 'highlight': { 11 | \ 'shade': g:EasyMotion_hl_group_shade, 12 | \ 'target': g:EasyMotion_hl_group_target, 13 | \ }, 14 | \ 'jump_first_target_keys': 15 | \ (g:EasyMotion_enter_jump_first ? ["\"] : []) + 16 | \ (g:EasyMotion_space_jump_first ? ["\"] : []), 17 | \ 'do_shade': g:EasyMotion_do_shade, 18 | \ }) 19 | endfunction 20 | 21 | function! EasyMotion#overwin#line() abort 22 | return EasyMotion#overwin#move('^') 23 | endfunction 24 | 25 | function! EasyMotion#overwin#w() abort 26 | return EasyMotion#overwin#move('\(\<.\|^$\)') 27 | endfunction 28 | -------------------------------------------------------------------------------- /autoload/EasyMotion/sticky_table.vim: -------------------------------------------------------------------------------- 1 | " Saving 'cpoptions' {{{ 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | " }}} 5 | " 6 | let EasyMotion#sticky_table#us = { 7 | \',' : '<', '.' : '>', '/' : '?', 8 | \'1' : '!', '2' : '@', '3' : '#', '4' : '$', '5' : '%', 9 | \'6' : '^', '7' : '&', '8' : '*', '9' : '(', '0' : ')', '-' : '_', '=' : '+', 10 | \';' : ':', '[' : '{', ']' : '}', '`' : '~', "'" : "\"", '\' : '|', 11 | \} 12 | 13 | let EasyMotion#sticky_table#jp = { 14 | \',' : '<', '.' : '>', '/' : '?', 15 | \'1' : '!', '2' : '"', '3' : '#', '4' : '$', '5' : '%', 16 | \'6' : '&', '7' : "'", '8' : '(', '9' : ')', '0' : '_', '-' : '=', '^' : '~', 17 | \';' : '+', ':' : '*', '[' : '{', ']' : '}', '@' : '`', '\' : '|', 18 | \} 19 | 20 | " Restore 'cpoptions' {{{ 21 | let &cpo = s:save_cpo 22 | unlet s:save_cpo 23 | " }}} 24 | " vim: fdm=marker:et:ts=4:sw=4:sts=4 25 | -------------------------------------------------------------------------------- /autoload/EasyMotion/undo.vim: -------------------------------------------------------------------------------- 1 | let s:Buffer = vital#easymotion#import('Vim.Buffer') 2 | 3 | function! EasyMotion#undo#save() abort 4 | return s:undo_lock.save() 5 | endfunction 6 | 7 | let s:undo_lock = {} 8 | 9 | function! s:undo_lock.save() abort 10 | let undo = deepcopy(self) 11 | call undo._save() 12 | return undo 13 | endfunction 14 | 15 | function! s:undo_lock._save() abort 16 | if undotree().seq_last == 0 17 | " if there are no undo history, disable undo feature by setting 18 | " 'undolevels' to -1 and restore it. 19 | let self.save_undolevels = &l:undolevels 20 | let &l:undolevels = -1 21 | elseif !s:Buffer.is_cmdwin() 22 | " command line window doesn't support :wundo. 23 | let self.undofile = tempname() 24 | execute 'wundo!' self.undofile 25 | else 26 | let self.is_cmdwin = s:TRUE 27 | endif 28 | endfunction 29 | 30 | function! s:undo_lock.restore() abort 31 | if has_key(self, 'save_undolevels') 32 | let &l:undolevels = self.save_undolevels 33 | endif 34 | if has_key(self, 'undofile') && filereadable(self.undofile) 35 | silent execute 'rundo' self.undofile 36 | call delete(self.undofile) 37 | endif 38 | if has_key(self, 'is_cmdwin') 39 | " XXX: it breaks undo history. AFAIK, there are no way to save and restore 40 | " undo history in commandline window. 41 | call self.undobreak() 42 | endif 43 | endfunction 44 | 45 | function! s:undo_lock.undobreak() abort 46 | let old_undolevels = &l:undolevels 47 | setlocal undolevels=-1 48 | keepjumps call setline('.', getline('.')) 49 | let &l:undolevels = old_undolevels 50 | endfunction 51 | -------------------------------------------------------------------------------- /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/_easymotion.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:]}#new() 5 | endfunction 6 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/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#_easymotion#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#_easymotion#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/_easymotion/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#_easymotion#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#_easymotion#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/_easymotion/Data/Set.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#_easymotion#Data#Set#import() abort 6 | return map({'set': '', 'frozenset': ''}, '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#_easymotion#Data#Set#import() abort', printf("return map({'set': '', 'frozenset': ''}, \"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 | let s:TRUE = !0 20 | let s:FALSE = 0 21 | 22 | function! s:set(...) abort 23 | return call(s:set._new, a:000, s:set) 24 | endfunction 25 | 26 | function! s:frozenset(...) abort 27 | return call(s:frozenset._new, a:000, s:frozenset) 28 | endfunction 29 | 30 | function! s:_hash_func(x) abort 31 | return a:x 32 | endfunction 33 | 34 | let s:_base_set = { 35 | \ '_is_set' : s:TRUE, 36 | \ '_data' : {}, 37 | \ '_hash_func' : function('s:_hash_func') 38 | \ } 39 | 40 | function! s:_base_set._new(...) abort 41 | let obj = deepcopy(self) 42 | let xs = get(a:, 1, []) 43 | let obj._hash_func = get(a:, 2, obj._hash_func) 44 | call obj._set_data(xs) 45 | return obj 46 | endfunction 47 | 48 | "" Return the union of two sets as a new set. 49 | " (I.e. all elements that are in either set.) 50 | function! s:_base_set.union(t) abort 51 | let r = deepcopy(self) 52 | call r._update(a:t) 53 | return r 54 | endfunction 55 | let s:_base_set.or = s:_base_set.union 56 | 57 | "" Return the intersection of two sets as a new set. 58 | " (I.e. all elements that are in both sets.) 59 | function! s:_base_set.intersection(t) abort 60 | let t = self._to_set(a:t) 61 | let [little, big] = self.len() <= t.len() ? [self, t] : [t, self] 62 | return self._new(filter(copy(big.to_list()), 'little.in(v:val)')) 63 | endfunction 64 | let s:_base_set.and = s:_base_set.intersection 65 | 66 | "" Return the symmetric difference of two sets as a new set. 67 | " (I.e. all elements that are in exactly one of the sets.) 68 | function! s:_base_set.symmetric_difference(t) abort 69 | let t = self._to_set(a:t) 70 | return self._new(filter(copy(self.to_list()), '!t.in(v:val)') 71 | \ + filter(copy(t.to_list()), '!self.in(v:val)')) 72 | endfunction 73 | let s:_base_set.xor = s:_base_set.symmetric_difference 74 | 75 | "" Return the difference of two sets as a new Set. 76 | function! s:_base_set.difference(t) abort 77 | let t = self._to_set(a:t) 78 | return self._new(filter(copy(self.to_list()), '!t.in(v:val)')) 79 | endfunction 80 | let s:_base_set.sub = s:_base_set.difference 81 | 82 | "" Report whether another set contains this set. 83 | function! s:_base_set.issubset(t) abort 84 | let t = self._to_set(a:t) 85 | return self.len() > t.len() ? s:FALSE 86 | \ : empty(filter(copy(self.to_list()), '!t.in(v:val)')) 87 | endfunction 88 | 89 | "" Report whether this set contains another set. 90 | function! s:_base_set.issuperset(t) abort 91 | let t = self._to_set(a:t) 92 | return self.len() < t.len() ? s:FALSE 93 | \ : empty(filter(copy(t.to_list()), '!self.in(v:val)')) 94 | endfunction 95 | 96 | " less than equal & greater than equal 97 | let s:_base_set.le = s:_base_set.issubset 98 | let s:_base_set.ge = s:_base_set.issuperset 99 | 100 | " less than 101 | function! s:_base_set.lt(t) abort 102 | let t = self._to_set(a:t) 103 | return self.len() < t.len() && self.issubset(t) 104 | endfunction 105 | 106 | " greater than 107 | function! s:_base_set.gt(t) abort 108 | let t = self._to_set(a:t) 109 | return self.len() > t.len() && self.issuperset(t) 110 | endfunction 111 | 112 | function! s:_base_set.len() abort 113 | return len(self._data) 114 | endfunction 115 | 116 | function! s:_base_set.to_list() abort 117 | return values(self._data) 118 | endfunction 119 | 120 | function! s:_base_set._update(xs) abort 121 | for X in (s:_is_set(a:xs) ? a:xs.to_list() : a:xs) 122 | call self._add(X) 123 | unlet X 124 | endfor 125 | endfunction 126 | 127 | function! s:_base_set._add(x) abort 128 | let key = self._hash(a:x) 129 | if !has_key(self._data, key) 130 | let self._data[key] = a:x 131 | endif 132 | endfunction 133 | 134 | " Report whether an element is a member of a set. 135 | function! s:_base_set.in(x) abort 136 | return has_key(self._data, self._hash(a:x)) 137 | endfunction 138 | 139 | function! s:_base_set._to_set(x) abort 140 | return s:_is_set(a:x) ? a:x : self._new(a:x) 141 | endfunction 142 | 143 | function! s:_base_set._clear() abort 144 | let self._data = {} 145 | endfunction 146 | 147 | function! s:_base_set._set_data(xs) abort 148 | call self._clear() 149 | call self._update(a:xs) 150 | endfunction 151 | 152 | function! s:_base_set._hash(x) abort 153 | return string(self._hash_func(a:x)) 154 | endfunction 155 | 156 | " frozenset: Immutable set class. 157 | 158 | let s:frozenset = deepcopy(s:_base_set) 159 | 160 | " Set: Mutable set class. 161 | 162 | let s:set = deepcopy(s:_base_set) 163 | 164 | " Update a set with the union of itself and another. 165 | function! s:set.update(iterable) abort 166 | call self._update(a:iterable) 167 | endfunction 168 | 169 | " Update a set with the union of itself and another. 170 | function! s:set.ior(t) abort 171 | call self.update(a:t) 172 | return self 173 | endfunction 174 | 175 | " Update a set with the intersection of itself and another. 176 | function! s:set.intersection_update(t) abort 177 | let r = self.and(a:t).to_list() 178 | call self.clear() 179 | call self.update(r) 180 | endfunction 181 | 182 | " Update a set with the intersection of itself and another. 183 | function! s:set.iand(t) abort 184 | call self.intersection_update(a:t) 185 | return self 186 | endfunction 187 | 188 | " Update a set with the symmetric difference of itself and another. 189 | function! s:set.symmetric_difference_update(t) abort 190 | let t = self._to_set(a:t) 191 | if self is t 192 | call self.clear() 193 | return 194 | endif 195 | for X in t.to_list() 196 | if self.in(X) 197 | call self.remove(X) 198 | else 199 | call self._add(X) 200 | endif 201 | unlet X 202 | endfor 203 | endfunction 204 | 205 | " Update a set with the symmetric difference of itself and another. 206 | function! s:set.ixor(t) abort 207 | call self.symmetric_difference_update(a:t) 208 | return self 209 | endfunction 210 | 211 | " Remove all elements of another set from this set. 212 | function! s:set.difference_update(t) abort 213 | let t = self._to_set(a:t) 214 | if self is t 215 | call self.clear() 216 | return 217 | endif 218 | for X in filter(t.to_list(), 'self.in(v:val)') 219 | call self.remove(X) 220 | unlet X 221 | endfor 222 | endfunction 223 | 224 | " Remove all elements of another set from this set. 225 | function! s:set.isub(t) abort 226 | call self.difference_update(a:t) 227 | return self 228 | endfunction 229 | 230 | " Remove all elements from this set. 231 | function! s:set.clear() abort 232 | call self._clear() 233 | endfunction 234 | 235 | "" Add an element to a set. 236 | " This has no effect if the element is already present. 237 | function! s:set.add(x) abort 238 | return self._add(a:x) 239 | endfunction 240 | 241 | "" Remove an element from a set; it must be a member. 242 | " If the element is not a member, throw Exception. 243 | function! s:set.remove(e) abort 244 | try 245 | unlet self._data[self._hash(a:e)] 246 | catch /^Vim\%((\a\+)\)\?:E716/ 247 | call s:_throw('the element is not a member') 248 | endtry 249 | endfunction 250 | 251 | "" Remove an element from a set if it is a member. 252 | " If the element is not a member, do nothing. 253 | function! s:set.discard(e) abort 254 | try 255 | call self.remove(a:e) 256 | catch /vital: Data.Set: the element is not a member/ 257 | " Do nothing 258 | endtry 259 | endfunction 260 | 261 | " Remove and return an arbitrary set element. 262 | function! s:set.pop() abort 263 | try 264 | let k = keys(self._data)[0] 265 | catch /^Vim\%((\a\+)\)\?:E684/ 266 | call s:_throw('set is empty') 267 | endtry 268 | let v = self._data[k] 269 | unlet self._data[k] 270 | return v 271 | endfunction 272 | 273 | " Helper: 274 | 275 | function! s:_is_set(x) abort 276 | return type(a:x) is type({}) && get(a:x, '_is_set', s:FALSE) 277 | endfunction 278 | 279 | function! s:_throw(message) abort 280 | throw 'vital: Data.Set: ' . a:message 281 | endfunction 282 | 283 | let &cpo = s:save_cpo 284 | unlet s:save_cpo 285 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/HitAHint/Hint.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#_easymotion#HitAHint#Hint#import() abort 6 | return map({'create': '', '_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#_easymotion#HitAHint#Hint#import() abort', printf("return map({'create': '', '_vital_loaded': ''}, \"function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") 13 | delfunction s:_SID 14 | endif 15 | " ___vital___ 16 | " function() wrapper 17 | if v:version > 703 || v:version == 703 && has('patch1170') 18 | let s:_function = function('function') 19 | else 20 | function! s:_SID() abort 21 | return matchstr(expand(''), '\zs\d\+\ze__SID$') 22 | endfunction 23 | let s:_s = '' . s:_SID() . '_' 24 | function! s:_function(fstr) abort 25 | return function(substitute(a:fstr, 's:', s:_s, 'g')) 26 | endfunction 27 | endif 28 | 29 | function! s:_assert(...) abort 30 | return '' 31 | endfunction 32 | 33 | function! s:_vital_loaded(V) abort 34 | if a:V.exists('Vim.PowerAssert') 35 | let s:assert = a:V.import('Vim.PowerAssert').assert 36 | else 37 | let s:assert = s:_function('s:_assert') 38 | endif 39 | endfunction 40 | 41 | " TERMS: 42 | " key: A character to generate hint. e.g. a,b,c,d,e,f,... 43 | " hint: A hint is a combination of keys. e.g. a,b,ab,abc,.. 44 | 45 | " s:create() assigns keys to each targets and generate hint dict. 46 | " Example: 47 | " let targets = [1, 2, 3, 4, 5, 6] 48 | " echo s:label(targets, ['a', 'b', 'c']) 49 | " " => { 50 | " 'a': 1, 51 | " 'b': { 52 | " 'a': 2, 53 | " 'b': 3 54 | " }, 55 | " 'c': { 56 | " 'a': 4, 57 | " 'b': 5, 58 | " 'c': 6 59 | " } 60 | " } 61 | " Hint-to-target: 62 | " a -> 1 63 | " ba -> 2 64 | " bb -> 3 65 | " ca -> 4 66 | " cb -> 5 67 | " cc -> 6 68 | " @param {list} targets 69 | " @param {list} keys each key should be uniq 70 | " @return Tree{string: (T|Tree)} 71 | function! s:create(targets, keys) abort 72 | exe s:assert('len(a:keys) > 1') 73 | let groups = {} 74 | let keys_count = reverse(s:_keys_count(len(a:targets), len(a:keys))) 75 | 76 | let target_idx = 0 77 | let key_idx = 0 78 | for key_count in keys_count 79 | if key_count > 1 80 | " We need to create a subgroup 81 | " Recurse one level deeper 82 | let sub_targets = a:targets[target_idx : target_idx + key_count - 1] 83 | let groups[a:keys[key_idx]] = s:create(sub_targets, a:keys) 84 | elseif key_count == 1 85 | " Assign single target key_idx 86 | let groups[a:keys[key_idx]] = a:targets[target_idx] 87 | else 88 | " No target 89 | continue 90 | endif 91 | let key_idx += 1 92 | let target_idx += key_count 93 | endfor 94 | return groups 95 | endfunction 96 | 97 | " s:_keys_count() generates list which represents how many targets to be 98 | " assigned to the key. 99 | " If the count > 1, use tree recursively. 100 | " Example: 101 | " echo s:_keys_count(5, 3) 102 | " " => [3, 1, 1] 103 | " echo s:_keys_count(8, 3) 104 | " " => [3, 3, 2] 105 | " @param {number} target_len 106 | " @param {number} keys_len 107 | function! s:_keys_count(targets_len, keys_len) abort 108 | exe s:assert('a:keys_len > 1') 109 | let _keys_count = repeat([0], a:keys_len) 110 | let is_first_level = 1 111 | let targets_left_cnt = a:targets_len 112 | while targets_left_cnt > 0 113 | let cnt_to_add = is_first_level ? 1 : a:keys_len - 1 114 | for i in range(a:keys_len) 115 | let _keys_count[i] += cnt_to_add 116 | let targets_left_cnt -= cnt_to_add 117 | if targets_left_cnt <= 0 118 | let _keys_count[i] += targets_left_cnt 119 | break 120 | endif 121 | endfor 122 | let is_first_level = 0 123 | endwhile 124 | exe s:assert('len(_keys_count) is# a:keys_len') 125 | return _keys_count 126 | endfunction 127 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules.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#_easymotion#Over#Commandline#Modules#import() abort 6 | return map({'get': '', 'make': '', '_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#_easymotion#Over#Commandline#Modules#import() abort', printf("return map({'get': '', 'make': '', '_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 | endfunction 24 | 25 | 26 | function! s:get(name) 27 | if exists("s:" . a:name) 28 | return s:{a:name} 29 | endif 30 | let s:{a:name} = s:V.import('Over.Commandline.Modules.' . a:name) 31 | return s:{a:name} 32 | endfunction 33 | 34 | 35 | function! s:make(name, ...) 36 | let module = s:get(a:name) 37 | return call(module.make, a:000, module) 38 | endfunction 39 | 40 | 41 | let &cpo = s:save_cpo 42 | unlet s:save_cpo 43 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/BufferComplete.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#_easymotion#Over#Commandline#Modules#BufferComplete#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#_easymotion#Over#Commandline#Modules#BufferComplete#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 | function! s:_uniq(list) 22 | let dict = {} 23 | for _ in a:list 24 | let dict[_] = 0 25 | endfor 26 | return keys(dict) 27 | endfunction 28 | 29 | 30 | let s:module = { 31 | \ "name" : "BufferComplete", 32 | \} 33 | 34 | 35 | function! s:_buffer_complete() 36 | return sort(s:_uniq(filter(split(join(getline(1, '$')), '\W'), '!empty(v:val)')), 1) 37 | endfunction 38 | 39 | 40 | function! s:_parse_line(line) 41 | let keyword = matchstr(a:line, '\zs\w\+\ze$') 42 | let pos = strchars(a:line) - strchars(keyword) 43 | return [pos, keyword] 44 | endfunction 45 | 46 | 47 | function! s:_as_statusline(list, count) 48 | if empty(a:list) 49 | return 50 | endif 51 | let hl_none = "%#StatusLine#" 52 | let hl_select = "%#StatusLineNC#" 53 | let tail = " > " 54 | let result = a:list[0] 55 | let pos = 0 56 | for i in range(1, len(a:list)-1) 57 | if strdisplaywidth(result . " " . a:list[i]) > &columns - len(tail) 58 | if a:count < i 59 | break 60 | else 61 | let pos = -i 62 | endif 63 | let result = a:list[i] 64 | else 65 | let result .= (" " . a:list[i]) 66 | endif 67 | if a:count == i 68 | let pos = pos + i 69 | endif 70 | endfor 71 | return join(map(split(result, " "), 'v:key == pos ? hl_select . v:val . hl_none : v:val')) 72 | endfunction 73 | 74 | 75 | function! s:module.get_complete_words() 76 | return s:_buffer_complete() 77 | endfunction 78 | 79 | 80 | function! s:module.complete(cmdline) 81 | call s:_finish() 82 | let s:old_statusline = &statusline 83 | 84 | let backward = a:cmdline.backward() 85 | let [pos, keyword] = s:_parse_line(backward) 86 | 87 | if !exists("s:complete") 88 | let s:complete = self.get_complete_words() 89 | endif 90 | let s:complete_list = filter(copy(s:complete), 'v:val =~ ''^''.keyword') 91 | if empty(s:complete_list) 92 | return -1 93 | endif 94 | 95 | if pos == 0 96 | let backward = "" 97 | else 98 | let backward = join(split(backward, '\zs')[ : pos-1 ], "") 99 | endif 100 | let s:line = backward . a:cmdline.forward() 101 | let s:pos = pos 102 | call a:cmdline.setline(s:line) 103 | 104 | let s:count = 0 105 | endfunction 106 | 107 | 108 | function! s:_finish() 109 | if exists("s:old_statusline") 110 | let &statusline = s:old_statusline 111 | unlet s:old_statusline 112 | redrawstatus 113 | endif 114 | endfunction 115 | 116 | 117 | function! s:module.on_char_pre(cmdline) 118 | if a:cmdline.is_input("(buffer-complete)") 119 | \ || a:cmdline.is_input("(buffer-complete-prev)") 120 | if self.complete(a:cmdline) == -1 121 | call s:_finish() 122 | call a:cmdline.setchar('') 123 | return 124 | endif 125 | if a:cmdline.is_input("(buffer-complete-prev)") 126 | let s:count = len(s:complete_list) - 1 127 | endif 128 | call a:cmdline.setchar('') 129 | call a:cmdline.tap_keyinput("Completion") 130 | " elseif a:cmdline.is_input("\", "Completion") 131 | elseif a:cmdline.is_input("(buffer-complete)", "Completion") 132 | \ || a:cmdline.is_input("\", "Completion") 133 | call a:cmdline.setchar('') 134 | let s:count += 1 135 | if s:count >= len(s:complete_list) 136 | let s:count = 0 137 | endif 138 | elseif a:cmdline.is_input("(buffer-complete-prev)", "Completion") 139 | \ || a:cmdline.is_input("\", "Completion") 140 | call a:cmdline.setchar('') 141 | let s:count -= 1 142 | if s:count < 0 143 | let s:count = len(s:complete_list) - 1 144 | endif 145 | else 146 | if a:cmdline.untap_keyinput("Completion") 147 | call a:cmdline.callevent("on_char_pre") 148 | endif 149 | call s:_finish() 150 | return 151 | endif 152 | call a:cmdline.setline(s:line) 153 | call a:cmdline.insert(s:complete_list[s:count], s:pos) 154 | if len(s:complete_list) > 1 155 | let &statusline = s:_as_statusline(s:complete_list, s:count) 156 | redrawstatus 157 | endif 158 | if len(s:complete_list) == 1 159 | call a:cmdline.untap_keyinput("Completion") 160 | endif 161 | endfunction 162 | 163 | 164 | function! s:module.on_draw_pre(...) 165 | " redrawstatus 166 | endfunction 167 | 168 | 169 | function! s:module.on_leave(cmdline) 170 | call s:_finish() 171 | unlet! s:complete 172 | endfunction 173 | 174 | function! s:make() 175 | return deepcopy(s:module) 176 | endfunction 177 | 178 | let &cpo = s:save_cpo 179 | unlet s:save_cpo 180 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/Cancel.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#_easymotion#Over#Commandline#Modules#Cancel#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#_easymotion#Over#Commandline#Modules#Cancel#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 | let s:module = { 21 | \ "name" : "Cancel" 22 | \} 23 | 24 | function! s:module.on_char_pre(cmdline) 25 | if a:cmdline.is_input("\") 26 | \ || a:cmdline.is_input("\") 27 | " call a:cmdline.cancel() 28 | call a:cmdline.exit(1) 29 | call a:cmdline.setchar("") 30 | endif 31 | endfunction 32 | 33 | 34 | function! s:make() 35 | return deepcopy(s:module) 36 | endfunction 37 | 38 | 39 | let &cpo = s:save_cpo 40 | unlet s:save_cpo 41 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/CursorMove.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#_easymotion#Over#Commandline#Modules#CursorMove#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#_easymotion#Over#Commandline#Modules#CursorMove#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:module = { 22 | \ "name" : "CursorMove" 23 | \} 24 | function! s:module.on_char_pre(cmdline) 25 | if a:cmdline.is_input("\") 26 | call a:cmdline.line.next() 27 | call a:cmdline.setchar('') 28 | elseif a:cmdline.is_input("\") 29 | call a:cmdline.line.prev() 30 | call a:cmdline.setchar('') 31 | elseif a:cmdline.is_input("\") 32 | \ || a:cmdline.is_input("\") 33 | call a:cmdline.setline(0) 34 | call a:cmdline.setchar('') 35 | elseif a:cmdline.is_input("\") 36 | \ || a:cmdline.is_input("\") 37 | call a:cmdline.setline(a:cmdline.line.length()) 38 | call a:cmdline.setchar('') 39 | elseif a:cmdline.is_input("\") 40 | \ || a:cmdline.is_input("\") 41 | call a:cmdline.setline(strridx(a:cmdline.backward()[:-2], ' ') + 1) 42 | call a:cmdline.setchar('') 43 | elseif a:cmdline.is_input("\") 44 | \ || a:cmdline.is_input("\") 45 | let p = stridx(a:cmdline.forward()[1:], ' ') 46 | call a:cmdline.setline(p != -1 ? a:cmdline.line.pos() + p + 2 : a:cmdline.line.length()) 47 | call a:cmdline.setchar('') 48 | endif 49 | endfunction 50 | 51 | 52 | function! s:make() 53 | return deepcopy(s:module) 54 | endfunction 55 | 56 | 57 | let &cpo = s:save_cpo 58 | unlet s:save_cpo 59 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/Delete.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#_easymotion#Over#Commandline#Modules#Delete#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#_easymotion#Over#Commandline#Modules#Delete#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:module = { 22 | \ "name" : "Delete", 23 | \} 24 | function! s:module.on_char_pre(cmdline) 25 | if a:cmdline.is_input("\") 26 | \ || a:cmdline.is_input("\") 27 | if a:cmdline.line.length() == 0 28 | return a:cmdline.exit(1) 29 | else 30 | call a:cmdline.line.remove_prev() 31 | call a:cmdline.setchar('') 32 | endif 33 | elseif a:cmdline.is_input("\") 34 | call a:cmdline.line.remove_pos() 35 | call a:cmdline.setchar('') 36 | elseif a:cmdline.is_input("\") 37 | let word = a:cmdline.backward_word() 38 | let backward = a:cmdline.backward()[ : -strlen(word)-1 ] 39 | call a:cmdline.setline(backward . a:cmdline.line.pos_char() . a:cmdline.forward()) 40 | call a:cmdline.setline(strchars(backward)) 41 | call a:cmdline.setchar('') 42 | elseif a:cmdline.is_input("\") 43 | call a:cmdline.setline(a:cmdline.line.pos_char() . a:cmdline.forward()) 44 | call a:cmdline.setline(0) 45 | call a:cmdline.setchar('') 46 | endif 47 | endfunction 48 | 49 | 50 | function! s:make() 51 | return deepcopy(s:module) 52 | endfunction 53 | 54 | 55 | let &cpo = s:save_cpo 56 | unlet s:save_cpo 57 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/Doautocmd.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#_easymotion#Over#Commandline#Modules#Doautocmd#import() abort 6 | return map({'_vital_depends': '', 'doautocmd_user': '', 'get_cmdline': '', 'make': '', '_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#_easymotion#Over#Commandline#Modules#Doautocmd#import() abort', printf("return map({'_vital_depends': '', 'doautocmd_user': '', 'get_cmdline': '', 'make': '', '_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:E = s:V.import("Over.Exception") 24 | endfunction 25 | 26 | 27 | function! s:_vital_depends() 28 | return [ 29 | \ "Over.Exception", 30 | \ ] 31 | endfunction 32 | 33 | 34 | let s:cache_command = {} 35 | function! s:doautocmd_user(prefix, command) 36 | let group = a:prefix . "-vital-over-commandline-doautocmd-dummy" 37 | if !has_key(s:cache_command, a:prefix) 38 | let s:cache_command[a:prefix] = {} 39 | endif 40 | 41 | if !has_key(s:cache_command[a:prefix], a:command) 42 | execute "autocmd " . group 43 | \ . " User " . a:command." silent! execute ''" 44 | 45 | if v:version > 703 || v:version == 703 && has("patch438") 46 | let s:cache_command[a:prefix][a:command] = "doautocmd User " . a:command 47 | else 48 | let s:cache_command[a:prefix][a:command] = "doautocmd User " . a:command 49 | endif 50 | endif 51 | 52 | execute s:cache_command[a:prefix][a:command] 53 | endfunction 54 | 55 | 56 | let s:hooks = [ 57 | \ "enter", 58 | \ "leave", 59 | \ "char", 60 | \ "char_pre", 61 | \ "draw", 62 | \ "draw_pre", 63 | \ "execute_pre", 64 | \ "execute_failed", 65 | \ "execute", 66 | \ "exception", 67 | \] 68 | 69 | let s:hooks_camel = [ 70 | \ "Enter", 71 | \ "Leave", 72 | \ "Char", 73 | \ "CharPre", 74 | \ "Draw", 75 | \ "DrawPre", 76 | \ "ExecutePre", 77 | \ "ExecuteFailed", 78 | \ "Execute", 79 | \ "Exception", 80 | \] 81 | 82 | 83 | let s:module = { 84 | \ "name" : "Doautocmd", 85 | \} 86 | 87 | 88 | for s:i in range(len(s:hooks)) 89 | execute join([ 90 | \ "function! s:module.on_" . s:hooks[s:i] . "(cmdline, ...)", 91 | \ " let s:cmdline = a:cmdline", 92 | \ " call s:doautocmd_user(self.prefix, self.prefix . " . string(s:hooks_camel[s:i]) . ")", 93 | \ "endfunction", 94 | \ ], "\n") 95 | endfor 96 | 97 | 98 | function! s:get_cmdline() 99 | if !exists("s:cmdline") 100 | execute s:E.throw_cmd("Undefined cmdline object.", "Over.Commandline.Modules.Doautocmd") 101 | endif 102 | return s:cmdline 103 | endfunction 104 | 105 | 106 | function! s:make(prefix) 107 | if has_key(s:cache_command, a:prefix) 108 | unlet! s:cache_command[a:prefix] 109 | endif 110 | execute "augroup " a:prefix . "-vital-over-commandline-doautocmd-dummy" 111 | autocmd! 112 | augroup END 113 | 114 | let module = deepcopy(s:module) 115 | let module.prefix = a:prefix 116 | return module 117 | endfunction 118 | 119 | 120 | let &cpo = s:save_cpo 121 | unlet s:save_cpo 122 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/DrawCommandline.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#_easymotion#Over#Commandline#Modules#DrawCommandline#import() abort 6 | return map({'suffix': '', '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#_easymotion#Over#Commandline#Modules#DrawCommandline#import() abort', printf("return map({'suffix': '', '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 | let s:module = { 21 | \ "name" : "DrawCommandline" 22 | \} 23 | 24 | let s:cmdheight = {} 25 | 26 | function! s:cmdheight.save() 27 | if has_key(self, "value") 28 | return 29 | endif 30 | let self.value = &cmdheight 31 | endfunction 32 | 33 | function! s:cmdheight.restore() 34 | if has_key(self, "value") 35 | let &cmdheight = self.value 36 | unlet self.value 37 | endif 38 | endfunction 39 | 40 | 41 | function! s:cmdheight.get() 42 | return self.value 43 | endfunction 44 | 45 | 46 | function! s:suffix(left, suffix) 47 | let left_len = strdisplaywidth(a:left) 48 | let len = &columns - left_len % &columns 49 | let len = len + (&columns * (strdisplaywidth(a:suffix) > (len - 1))) - 1 50 | return repeat(" ", len - strdisplaywidth(a:suffix)) . a:suffix 51 | " return printf("%" . len . "S", a:suffix) 52 | endfunction 53 | 54 | 55 | let s:old_width = 0 56 | function! s:_redraw(cmdline) 57 | let left = a:cmdline.get_prompt() . a:cmdline.getline() . (empty(a:cmdline.line.pos_char()) ? " " : "") 58 | let width = len(left) + 1 59 | 60 | if a:cmdline.get_suffix() != "" 61 | let width += len(s:suffix(left, a:cmdline.get_suffix())) - 1 62 | endif 63 | 64 | if &columns >= width && &columns <= s:old_width && s:old_width >= width 65 | redraw 66 | normal! : 67 | elseif &columns <= width 68 | normal! : 69 | else 70 | redraw 71 | endif 72 | let s:old_width = width 73 | 74 | call s:cmdheight.save() 75 | let height = max([(width - 1) / (&columns) + 1, s:cmdheight.get()]) 76 | if height > &cmdheight || &cmdheight > height 77 | let &cmdheight = height 78 | redraw 79 | endif 80 | endfunction 81 | 82 | 83 | function! s:_as_echon(str) 84 | return "echon " . strtrans(string(a:str)) 85 | endfunction 86 | 87 | 88 | function! s:module.on_draw_pre(cmdline) 89 | if empty(a:cmdline.line.pos_char()) 90 | let cursor = "echohl " . a:cmdline.highlights.cursor . " | echon ' '" 91 | else 92 | let cursor = "echohl " . a:cmdline.highlights.cursor_on . " | " . s:_as_echon(a:cmdline.line.pos_char()) 93 | endif 94 | let suffix = "" 95 | if a:cmdline.get_suffix() != "" 96 | let suffix = s:_as_echon(s:suffix(a:cmdline.get_prompt() . a:cmdline.getline() . repeat(" ", empty(a:cmdline.line.pos_char())), a:cmdline.get_suffix())) 97 | endif 98 | let self.draw_command = join([ 99 | \ "echohl " . a:cmdline.highlights.prompt, 100 | \ s:_as_echon(a:cmdline.get_prompt()), 101 | \ "echohl NONE", 102 | \ s:_as_echon(a:cmdline.backward()), 103 | \ cursor, 104 | \ "echohl NONE", 105 | \ s:_as_echon(a:cmdline.forward()), 106 | \ suffix, 107 | \ ], " | ") 108 | 109 | call s:_redraw(a:cmdline) 110 | endfunction 111 | 112 | 113 | function! s:_echon(expr) 114 | echon strtrans(a:expr) 115 | endfunction 116 | 117 | 118 | function! s:module.on_draw(cmdline) 119 | execute self.draw_command 120 | " execute "echohl" a:cmdline.highlights.prompt 121 | " call s:echon(a:cmdline.get_prompt()) 122 | " echohl NONE 123 | " call s:echon(a:cmdline.backward()) 124 | " if empty(a:cmdline.line.pos_char()) 125 | " execute "echohl" a:cmdline.highlights.cursor 126 | " call s:echon(' ') 127 | " else 128 | " execute "echohl" a:cmdline.highlights.cursor_on 129 | " call s:echon(a:cmdline.line.pos_char()) 130 | " endif 131 | " echohl NONE 132 | " call s:echon(a:cmdline.forward()) 133 | " if a:cmdline.get_suffix() != "" 134 | " call s:echon(s:suffix(a:cmdline.get_prompt() . a:cmdline.getline() . repeat(" ", empty(a:cmdline.line.pos_char())), a:cmdline.get_suffix())) 135 | " endif 136 | endfunction 137 | 138 | 139 | function! s:module.on_execute_pre(...) 140 | call s:cmdheight.restore() 141 | endfunction 142 | 143 | 144 | function! s:module.on_leave(...) 145 | call s:cmdheight.restore() 146 | endfunction 147 | 148 | 149 | function! s:make() 150 | return deepcopy(s:module) 151 | endfunction 152 | 153 | 154 | let &cpo = s:save_cpo 155 | unlet s:save_cpo 156 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/ExceptionExit.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#_easymotion#Over#Commandline#Modules#ExceptionExit#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#_easymotion#Over#Commandline#Modules#ExceptionExit#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 | let s:module = { 21 | \ "name" : "ExceptionExit", 22 | \} 23 | 24 | 25 | function! s:module.on_exception(cmdline) 26 | call a:cmdline.exit(-1) 27 | endfunction 28 | 29 | 30 | function! s:make(...) 31 | let result = deepcopy(s:module) 32 | let result.exit_code = get(a:, 1, 0) 33 | return result 34 | endfunction 35 | 36 | let &cpo = s:save_cpo 37 | unlet s:save_cpo 38 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/ExceptionMessage.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#_easymotion#Over#Commandline#Modules#ExceptionMessage#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#_easymotion#Over#Commandline#Modules#ExceptionMessage#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:vname = expand(":h:h:h:h:t") 22 | 23 | 24 | let s:module = { 25 | \ "name" : "ExceptionMessage", 26 | \} 27 | 28 | 29 | function! s:module.on_exception(cmdline) 30 | let self.exception = v:exception 31 | let self.throwpoint = v:throwpoint 32 | endfunction 33 | 34 | 35 | function! s:module.on_draw_pre(cmdline) 36 | if has_key(self, "exception") 37 | call self.message(a:cmdline) 38 | unlet self.exception 39 | endif 40 | endfunction 41 | 42 | function! s:module.message(...) 43 | echohl ErrorMsg 44 | execute self.command string(self.prefix . " : " . self.throwpoint . " " . self.exception) 45 | echohl None 46 | endfunction 47 | 48 | 49 | function! s:module.on_leave(cmdline) 50 | if has_key(self, "exception") 51 | call self.message(a:cmdline) 52 | unlet self.exception 53 | endif 54 | endfunction 55 | 56 | 57 | function! s:make(...) 58 | let result = deepcopy(s:module) 59 | let result.prefix = get(a:, 1, "vital-over(".s:vname.") Exception") 60 | let result.command = get(a:, 2, "echom") 61 | return result 62 | endfunction 63 | 64 | 65 | let &cpo = s:save_cpo 66 | unlet s:save_cpo 67 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/Exit.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#_easymotion#Over#Commandline#Modules#Exit#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#_easymotion#Over#Commandline#Modules#Exit#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 | let s:module = { 21 | \ "name" : "Exit", 22 | \ "exit_code" : 0 23 | \} 24 | 25 | 26 | function! s:module.on_char_pre(cmdline) 27 | if a:cmdline.is_input("(exit)") 28 | call a:cmdline.setchar("") 29 | call a:cmdline.exit(self.exit_code) 30 | endif 31 | endfunction 32 | 33 | 34 | function! s:make() 35 | return deepcopy(s:module) 36 | endfunction 37 | 38 | 39 | let &cpo = s:save_cpo 40 | unlet s:save_cpo 41 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/History.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#_easymotion#Over#Commandline#Modules#History#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#_easymotion#Over#Commandline#Modules#History#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 | let s:module = { 21 | \ "name" : "History", 22 | \ "mode" : "cmd", 23 | \} 24 | 25 | function! s:module.histories() 26 | return map(range(1, &history), 'histget(self.mode, v:val * -1)') 27 | endfunction 28 | 29 | function! s:_should_match_cmdline(cmdline) 30 | return a:cmdline.is_input("\") 31 | \ || a:cmdline.is_input("\") 32 | endfunction 33 | 34 | function! s:_reset() 35 | let s:cmdhist = [] 36 | let s:count = 0 37 | let s:is_match_mode = 0 " /: true, /: false 38 | endfunction 39 | 40 | function! s:module.on_enter(...) 41 | call s:_reset() 42 | endfunction 43 | 44 | function! s:module.on_char_pre(cmdline) 45 | if !a:cmdline.is_input("\") && !a:cmdline.is_input("\") 46 | \ && !a:cmdline.is_input("\") && !a:cmdline.is_input("\") 47 | call s:_reset() 48 | return 49 | else 50 | if s:count == 0 && empty(s:cmdhist) 51 | \ || s:is_match_mode != s:_should_match_cmdline(a:cmdline) 52 | let cmdline = '^' . a:cmdline.getline() 53 | let s:is_match_mode = s:_should_match_cmdline(a:cmdline) 54 | let s:cmdhist = [a:cmdline.getline()] + (s:is_match_mode ? 55 | \ filter(self.histories(), 'v:val =~ cmdline') : self.histories()) 56 | endif 57 | endif 58 | call a:cmdline.setchar("") 59 | if a:cmdline.is_input("\") || a:cmdline.is_input("\") 60 | let s:count = max([s:count - 1, 0]) 61 | endif 62 | if a:cmdline.is_input("\") || a:cmdline.is_input("\") 63 | let s:count = min([s:count + 1, len(s:cmdhist)]) 64 | endif 65 | call a:cmdline.setline(get(s:cmdhist, s:count, a:cmdline.getline())) 66 | endfunction 67 | 68 | function! s:make(...) 69 | let module = deepcopy(s:module) 70 | let module.mode = get(a:, 1, "cmd") 71 | return module 72 | endfunction 73 | 74 | let &cpo = s:save_cpo 75 | unlet s:save_cpo 76 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/InsertRegister.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#_easymotion#Over#Commandline#Modules#InsertRegister#import() abort 6 | return map({'_vital_depends': '', 'to_string': '', 'input': '', 'get_cmdline_cword': '', 'make': '', '_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#_easymotion#Over#Commandline#Modules#InsertRegister#import() abort', printf("return map({'_vital_depends': '', 'to_string': '', 'input': '', 'get_cmdline_cword': '', 'make': '', '_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:String = s:V.import("Over.String") 24 | endfunction 25 | 26 | 27 | function! s:_vital_depends() 28 | return [ 29 | \ "Over.String", 30 | \ ] 31 | endfunction 32 | 33 | 34 | function! s:to_string(expr) 35 | return type(a:expr) == type("") ? a:expr : string(a:expr) 36 | endfunction 37 | 38 | 39 | function! s:input(cmdline) 40 | let CR_index = index(a:cmdline.input_key_stack(), "\") 41 | if CR_index != -1 42 | let input = a:cmdline.input_key_stack_string() 43 | let input = input[ : CR_index-1] 44 | call a:cmdline.set_input_key_stack(a:cmdline.input_key_stack()[CR_index+1 : ]) 45 | return eval(input) 46 | endif 47 | 48 | let input_text = "" 49 | if !empty(a:cmdline.input_key_stack()) 50 | let input_text = a:cmdline.input_key_stack_string() 51 | call a:cmdline.set_input_key_stack([]) 52 | endif 53 | 54 | call a:cmdline.hl_cursor_on() 55 | try 56 | redraw 57 | let input = input("=", input_text, "expression") 58 | if !empty(input) 59 | let input = s:to_string(eval(input)) 60 | endif 61 | catch 62 | return "" 63 | finally 64 | call a:cmdline.hl_cursor_off() 65 | endtry 66 | return input 67 | endfunction 68 | 69 | 70 | let s:module = { 71 | \ "name" : "InsertRegister" 72 | \} 73 | 74 | 75 | 76 | function! s:module.reset() 77 | let self.cword = expand("") 78 | let self.cWORD = expand("") 79 | let self.cfile = expand("") 80 | endfunction 81 | 82 | function! s:module.on_enter(...) 83 | call self.reset() 84 | " let self.prefix_key = "" 85 | endfunction 86 | 87 | 88 | function! s:get_cmdline_cword(backward, cword) 89 | " let backward = matchstr(a:backward, '.\{-}\zs\k\+$') 90 | let backward = a:backward 91 | if &incsearch == 0 || a:cword == "" || a:backward == "" || s:String.index(a:cword, backward) != 0 92 | return a:cword 93 | endif 94 | return a:cword[len(backward) : ] 95 | endfunction 96 | 97 | 98 | function! s:module.on_char_pre(cmdline) 99 | if a:cmdline.is_input("\") 100 | call a:cmdline.setchar('"') 101 | let self.prefix_key = a:cmdline.input_key() 102 | let self.old_line = a:cmdline.getline() 103 | let self.old_pos = a:cmdline.getpos() 104 | return 105 | elseif exists("self.prefix_key") 106 | \ && a:cmdline.get_tap_key() == self.prefix_key 107 | call a:cmdline.setline(self.old_line) 108 | call a:cmdline.setpos(self.old_pos) 109 | let char = a:cmdline.input_key() 110 | if char =~ '^[0-9a-zA-z.%#:/"\-*+]$' 111 | let register = tr(getreg(char), "\n", "\r") 112 | call a:cmdline.setchar(register) 113 | elseif char == "=" 114 | call a:cmdline.setchar(s:input(a:cmdline)) 115 | elseif char == "\" 116 | call a:cmdline.setchar(s:get_cmdline_cword(a:cmdline.backward_word(), self.cword)) 117 | elseif char == "\" 118 | call a:cmdline.setchar(self.cWORD) 119 | elseif char == "\" 120 | call a:cmdline.setchar(self.cfile) 121 | elseif char == "\" 122 | call a:cmdline.setchar('"') 123 | else 124 | call a:cmdline.setchar("") 125 | endif 126 | " elseif a:cmdline.is_input('=', self.prefix_key) 127 | " call a:cmdline.setchar(s:input(a:cmdline)) 128 | " elseif a:cmdline.is_input("\", self.prefix_key) 129 | " call a:cmdline.setchar(self.cword) 130 | " elseif a:cmdline.is_input("\", self.prefix_key) 131 | " call a:cmdline.setchar(self.cWORD) 132 | " elseif a:cmdline.is_input("\", self.prefix_key) 133 | " call a:cmdline.setchar(self.cfile) 134 | " elseif a:cmdline.is_input("\", self.prefix_key) 135 | " call a:cmdline.setchar('"') 136 | " else 137 | " call a:cmdline.setchar("") 138 | " endif 139 | endif 140 | endfunction 141 | 142 | 143 | function! s:module.on_char(cmdline) 144 | if a:cmdline.is_input("\") 145 | call a:cmdline.tap_keyinput(self.prefix_key) 146 | call a:cmdline.disable_keymapping() 147 | call a:cmdline.setpos(a:cmdline.getpos()-1) 148 | else 149 | if exists("self.prefix_key") 150 | call a:cmdline.untap_keyinput(self.prefix_key) 151 | call a:cmdline.enable_keymapping() 152 | unlet! self.prefix_key 153 | endif 154 | endif 155 | endfunction 156 | 157 | 158 | 159 | function! s:make() 160 | return deepcopy(s:module) 161 | endfunction 162 | 163 | let &cpo = s:save_cpo 164 | unlet s:save_cpo 165 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/KeyMapping.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#_easymotion#Over#Commandline#Modules#KeyMapping#import() abort 6 | return map({'_vital_depends': '', 'make_emacs': '', 'make_vim_cmdline_mapping': '', '_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#_easymotion#Over#Commandline#Modules#KeyMapping#import() abort', printf("return map({'_vital_depends': '', 'make_emacs': '', 'make_vim_cmdline_mapping': '', '_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:Keymapping = a:V.import("Palette.Keymapping") 23 | endfunction 24 | 25 | 26 | function! s:_vital_depends() 27 | return [ 28 | \ "Palette.Keymapping", 29 | \ ] 30 | endfunction 31 | 32 | 33 | let s:emacs = { 34 | \ "name" : "KeyMapping_emacs_like" 35 | \} 36 | 37 | function! s:emacs.keymapping(cmdline) 38 | return { 39 | \ "\" : { 40 | \ "key" : "\", 41 | \ "noremap" : 1, 42 | \ "lock" : 1, 43 | \ }, 44 | \ "\" : { 45 | \ "key" : "\", 46 | \ "noremap" : 1, 47 | \ "lock" : 1, 48 | \ }, 49 | \ "\" : { 50 | \ "key" : "\", 51 | \ "noremap" : 1, 52 | \ "lock" : 1, 53 | \ }, 54 | \ "\" : { 55 | \ "key" : "\", 56 | \ "noremap" : 1, 57 | \ "lock" : 1, 58 | \ }, 59 | \ "\" : { 60 | \ "key" : "\", 61 | \ "noremap" : 1, 62 | \ "lock" : 1, 63 | \ }, 64 | \ "\" : { 65 | \ "key" : "\", 66 | \ "noremap" : 1, 67 | \ "lock" : 1, 68 | \ }, 69 | \ "\" : { 70 | \ "key" : "\", 71 | \ "noremap" : 1, 72 | \ "lock" : 1, 73 | \ }, 74 | \ "\" : { 75 | \ "key" : "\", 76 | \ "noremap" : 1, 77 | \ "lock" : 1, 78 | \ }, 79 | \ "\" : { 80 | \ "key" : "\", 81 | \ "noremap" : 1, 82 | \ "lock" : 1, 83 | \ }, 84 | \ "\" : { 85 | \ "key" : "\", 86 | \ "noremap" : 1, 87 | \ "lock" : 1, 88 | \ }, 89 | \ } 90 | endfunction 91 | 92 | 93 | function! s:make_emacs() 94 | return deepcopy(s:emacs) 95 | endfunction 96 | 97 | 98 | let s:vim_cmdline_mapping = { 99 | \ "name" : "KeyMapping_vim_cmdline_mapping", 100 | \ "_cmaps" : {} 101 | \} 102 | 103 | function! s:_convert_sid(rhs, sid) abort 104 | return substitute(a:rhs, '', '' . a:sid . '_', 'g') 105 | endfunction 106 | 107 | function! s:_auto_cmap() 108 | let cmaps = {} 109 | let cmap_info = s:Keymapping.rhs_key_list("c", 0, 1) 110 | " vital-over currently doesn't support mappings 111 | for c in filter(cmap_info, "v:val['buffer'] ==# 0") 112 | let cmaps[s:Keymapping.escape_special_key(c['lhs'])] = { 113 | \ 'noremap' : c['noremap'], 114 | \ 'key' : s:Keymapping.escape_special_key(s:_convert_sid(c['rhs'], c['sid'])), 115 | \ 'expr' : s:Keymapping.escape_special_key(c['expr']), 116 | \ } 117 | endfor 118 | return cmaps 119 | endfunction 120 | 121 | 122 | function! s:vim_cmdline_mapping.on_enter(cmdline) 123 | let self._cmaps = s:_auto_cmap() 124 | endfunction 125 | 126 | 127 | function! s:vim_cmdline_mapping.keymapping(cmdline) 128 | return self._cmaps 129 | endfunction 130 | 131 | 132 | function! s:make_vim_cmdline_mapping() 133 | return deepcopy(s:vim_cmdline_mapping) 134 | endfunction 135 | 136 | 137 | 138 | let &cpo = s:save_cpo 139 | unlet s:save_cpo 140 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/NoInsert.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#_easymotion#Over#Commandline#Modules#NoInsert#import() abort 6 | return map({'make_special_chars': '', '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#_easymotion#Over#Commandline#Modules#NoInsert#import() abort', printf("return map({'make_special_chars': '', '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 | let s:module = { 21 | \ "name" : "NoInsert", 22 | \ "chars" : [] 23 | \} 24 | 25 | 26 | function! s:module.is_no_insert(char) 27 | return index(self.chars, a:char) >= 0 28 | endfunction 29 | 30 | 31 | function! s:module.on_char_pre(cmdline) 32 | if self.is_no_insert(a:cmdline.char()) 33 | call a:cmdline.setchar("", 0) 34 | endif 35 | endfunction 36 | 37 | 38 | function! s:make(chars) 39 | let module = deepcopy(s:module) 40 | let module.chars = type(a:chars) == type([]) ? a:chars : [a:chars] 41 | return module 42 | endfunction 43 | 44 | 45 | function! s:make_special_chars() 46 | let module = s:make([]) 47 | function! module.is_no_insert(char) 48 | return char2nr(a:char) == 128 || char2nr(a:char) < 27 49 | endfunction 50 | return module 51 | endfunction 52 | 53 | 54 | let &cpo = s:save_cpo 55 | unlet s:save_cpo 56 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/Paste.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#_easymotion#Over#Commandline#Modules#Paste#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#_easymotion#Over#Commandline#Modules#Paste#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:module = { 22 | \ "name" : "Paste" 23 | \} 24 | 25 | function! s:module.on_char_pre(cmdline) 26 | if a:cmdline.is_input("(paste)") 27 | let register = v:register == "" ? '"' : v:register 28 | call a:cmdline.insert(tr(getreg("*"), "\n", "\r")) 29 | call a:cmdline.setchar('') 30 | endif 31 | endfunction 32 | 33 | 34 | function! s:make() 35 | return deepcopy(s:module) 36 | endfunction 37 | 38 | 39 | let &cpo = s:save_cpo 40 | unlet s:save_cpo 41 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Commandline/Modules/Redraw.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#_easymotion#Over#Commandline#Modules#Redraw#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#_easymotion#Over#Commandline#Modules#Redraw#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:module = { 22 | \ "name" : "Redraw", 23 | \} 24 | 25 | function! s:module.on_execute_pre(cmdline) 26 | call self.redraw(a:cmdline) 27 | endfunction 28 | 29 | function! s:module.on_enter(...) 30 | let self.is_execute = 0 31 | endfunction 32 | 33 | function! s:module.on_execute(...) 34 | let self.is_execute = 1 35 | endfunction 36 | 37 | function! s:module.on_execute_failed(...) 38 | let self.is_execute = 0 39 | endfunction 40 | 41 | function! s:module.on_leave(cmdline) 42 | if self.is_execute == 0 && a:cmdline.exit_code() != -1 43 | call self.redraw(a:cmdline) 44 | endif 45 | endfunction 46 | 47 | 48 | " function! s:module.on_draw_pre(cmdline) 49 | " call self.redraw(a:cmdline) 50 | " endfunction 51 | 52 | 53 | function! s:module.redraw(cmdline) 54 | redraw 55 | " Workaround for the :set cedit= 56 | " https://github.com/osyo-manga/vital-over/issues/52 57 | " https://github.com/Lokaltog/vim-easymotion/issues/177#issuecomment-53663431 58 | if &cedit != "" 59 | \ ||(v:version > 704 || v:version == 704 && has("patch441")) 60 | normal! : 61 | else 62 | execute "normal! :\" 63 | endif 64 | endfunction 65 | 66 | function! s:make() 67 | return deepcopy(s:module) 68 | endfunction 69 | 70 | 71 | let &cpo = s:save_cpo 72 | unlet s:save_cpo 73 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Exception.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#_easymotion#Over#Exception#import() abort 6 | return map({'throw': '', 'throw_cmd': '', 'set_prefix': '', 'error': ''}, '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#_easymotion#Over#Exception#import() abort', printf("return map({'throw': '', 'throw_cmd': '', 'set_prefix': '', 'error': ''}, \"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:vname = expand(":h:h:t") 22 | let s:prefix = printf("vital-over(%s) Exception", s:vname) 23 | 24 | function! s:set_prefix(prefix) 25 | let s:prefix = a:prefix 26 | endfunction 27 | 28 | function! s:throw_cmd(exp, where) 29 | return 'throw ' . string(s:prefix . " : " . a:exp . " in " . a:where) 30 | endfunction 31 | 32 | 33 | function! s:throw(exp, where) 34 | execute s:throw_cmd(a:exp, a:where) 35 | endfunction 36 | 37 | 38 | function! s:error(text, where) 39 | echohl ErrorMsg 40 | echom s:prefix . " : " . a:text . " in " . a:where 41 | echohl None 42 | endfunction 43 | 44 | 45 | let &cpo = s:save_cpo 46 | unlet s:save_cpo 47 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Input.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#_easymotion#Over#Input#import() abort 6 | return map({'getchar': ''}, '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#_easymotion#Over#Input#import() abort', printf("return map({'getchar': ''}, \"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:getchar(...) 22 | let mode = get(a:, 1, 0) 23 | while 1 24 | " Workaround for https://github.com/osyo-manga/vital-over/issues/53 25 | try 26 | let char = call("getchar", a:000) 27 | catch /^Vim:Interrupt$/ 28 | let char = 3 " 29 | endtry 30 | " Workaround for the mappings 31 | if string(char) !=# "\x80\xfd`" 32 | return mode == 1 ? !!char 33 | \ : type(char) == type(0) ? nr2char(char) : char 34 | endif 35 | endwhile 36 | endfunction 37 | 38 | 39 | let &cpo = s:save_cpo 40 | unlet s:save_cpo 41 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Keymapping.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#_easymotion#Over#Keymapping#import() abort 6 | return map({'_vital_depends': '', 'unmapping': '', 'as_key_config': '', 'match_key': '', '_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#_easymotion#Over#Keymapping#import() abort', printf("return map({'_vital_depends': '', 'unmapping': '', 'as_key_config': '', 'match_key': '', '_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:String = s:V.import("Over.String") 25 | endfunction 26 | 27 | 28 | function! s:_vital_depends() 29 | return [ 30 | \ "Over.String", 31 | \ ] 32 | endfunction 33 | 34 | 35 | function! s:as_key_config(config) 36 | let base = { 37 | \ "noremap" : 0, 38 | \ "lock" : 0, 39 | \ "expr" : 0, 40 | \ } 41 | return type(a:config) == type({}) ? extend(base, a:config) 42 | \ : extend(base, { 43 | \ "key" : a:config, 44 | \ }) 45 | endfunction 46 | 47 | 48 | function! s:match_key(keymapping, key) 49 | let keys = sort(keys(a:keymapping)) 50 | return get(filter(keys, 'stridx(a:key, v:val) == 0'), -1, '') 51 | endfunction 52 | 53 | 54 | function! s:_safe_eval(expr, ...) 55 | call extend(l:, get(a:, 1, {})) 56 | let result = get(a:, 2, "") 57 | try 58 | let result = eval(a:expr) 59 | catch 60 | echohl ErrorMsg | echom v:exception | echohl None 61 | endtry 62 | return result 63 | endfunction 64 | 65 | 66 | function! s:_get_key(conf) 67 | " call extend(l:, a:conf) 68 | let self = a:conf 69 | return get(a:conf, "expr", 0) ? s:_safe_eval(a:conf.key, l:) : a:conf.key 70 | endfunction 71 | 72 | 73 | function! s:unmapping(keymapping, key, ...) 74 | let is_locking = get(a:, 1, 0) 75 | let key = s:match_key(a:keymapping, a:key) 76 | if key == "" 77 | return s:String.length(a:key) <= 1 ? a:key : s:unmapping(a:keymapping, a:key[0], is_locking) . s:unmapping(a:keymapping, a:key[1:], is_locking) 78 | endif 79 | 80 | let map_conf = s:as_key_config(a:keymapping[key]) 81 | 82 | let next_input = s:unmapping(a:keymapping, a:key[len(key) : ], is_locking) 83 | if map_conf.lock == 0 && is_locking 84 | return key . next_input 85 | elseif map_conf.lock 86 | return s:unmapping(a:keymapping, s:_get_key(map_conf), is_locking) . next_input 87 | else 88 | return s:unmapping(a:keymapping, s:_get_key(map_conf), map_conf.noremap) . next_input 89 | endif 90 | endfunction 91 | 92 | 93 | 94 | let &cpo = s:save_cpo 95 | unlet s:save_cpo 96 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/Signals.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#_easymotion#Over#Signals#import() abort 6 | return map({'_vital_depends': '', 'call': '', 'make': '', '_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#_easymotion#Over#Signals#import() abort', printf("return map({'_vital_depends': '', 'call': '', 'make': '', '_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:L = s:V.import("Data.List") 24 | endfunction 25 | 26 | 27 | function! s:_vital_depends() 28 | return ["Data.List"] 29 | endfunction 30 | 31 | 32 | let s:base = { 33 | \ "variables" : { 34 | \ "slots" : [], 35 | \ "counter" : 0, 36 | \ } 37 | \} 38 | 39 | 40 | function! s:base.connect(slot) 41 | let self.variables.counter += 1 42 | let slot = { "id" : self.variables.counter, "slot" : a:slot } 43 | call add(self.variables.slots, slot) 44 | return slot 45 | endfunction 46 | 47 | 48 | function! s:base.disconnect(slot) 49 | if empty(a:slot) 50 | return -1 51 | endif 52 | for i in range(len(self.variables.slots)) 53 | if self.variables.slots[i].id == a:slot.id 54 | unlet self.variables.slots[i] 55 | return 56 | endif 57 | endfor 58 | return -1 59 | endfunction 60 | 61 | 62 | function! s:base.disconnect_by(expr) 63 | return self.disconnect(self.find_first_by(a:expr)) 64 | endfunction 65 | 66 | 67 | function! s:call(list, func, ...) 68 | let args = get(a:, 1, []) 69 | let def = get(a:, 2, 0) 70 | return map(copy(a:list), "has_key(v:val, a:func) ? call(v:val.".a:func.", args, v:val) : def") 71 | endfunction 72 | 73 | function! s:base.call(func, ...) 74 | return call("s:call", [self.slots(), a:func] + a:000) 75 | endfunction 76 | 77 | 78 | function! s:base.find_by(expr) 79 | return filter(copy(self.variables.slots), a:expr) 80 | endfunction 81 | 82 | 83 | function! s:base.find_first_by(expr) 84 | return get(self.find_by(a:expr), 0, {}) 85 | endfunction 86 | 87 | 88 | function! s:base.sort_by(expr) 89 | let self.variables.slots = s:L.sort_by(self.variables.slots, a:expr) 90 | endfunction 91 | 92 | 93 | function! s:base.get_slot(val) 94 | return a:val.slot 95 | endfunction 96 | 97 | 98 | function! s:base.slots() 99 | return map(copy(self.variables.slots), "self.get_slot(v:val)") 100 | endfunction 101 | 102 | 103 | " function! s:base.dict() 104 | " let result = {} 105 | " for _ in self.variables.slots 106 | " let result[_.id] = _.value 107 | " endfor 108 | " return result 109 | " endfunction 110 | 111 | 112 | function! s:make() 113 | let result = deepcopy(s:base) 114 | return result 115 | endfunction 116 | 117 | 118 | let &cpo = s:save_cpo 119 | unlet s:save_cpo 120 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Over/String.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#_easymotion#Over#String#import() abort 6 | return map({'_vital_depends': '', 'length': '', 'index': '', 'split_by_keys': '', 'make': '', '_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#_easymotion#Over#String#import() abort', printf("return map({'_vital_depends': '', 'length': '', 'index': '', 'split_by_keys': '', 'make': '', '_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:List = s:V.import("Data.List") 24 | endfunction 25 | 26 | 27 | function! s:_vital_depends() 28 | return [ 29 | \ "Data.List", 30 | \ ] 31 | endfunction 32 | 33 | 34 | function! s:_clamp(x, max, min) 35 | return min([max([a:x, a:max]), a:min]) 36 | endfunction 37 | 38 | 39 | let s:base = {} 40 | 41 | function! s:base.set(item) 42 | return type(a:item) == type("") ? self.set_str(a:item) 43 | \ : type(a:item) == type(0) ? self.set_pos(a:item) 44 | \ : self 45 | endfunction 46 | 47 | function! s:base.str() 48 | return join(self.list, "") 49 | endfunction 50 | 51 | function! s:base.set_pos(pos) 52 | let self.col = s:_clamp(a:pos, 0, self.length()) 53 | return self 54 | endfunction 55 | 56 | function! s:base.backward() 57 | return self.col > 0 ? join(self.list[ : self.col-1], '') : "" 58 | endfunction 59 | 60 | function! s:base.forward() 61 | return join(self.list[self.col+1 : ], '') 62 | endfunction 63 | 64 | function! s:base.pos_char() 65 | return get(self.list, self.col, "") 66 | endfunction 67 | 68 | function! s:base.set_str(str) 69 | let self.list = split(a:str, '\zs') 70 | let self.col = strchars(a:str) 71 | return self 72 | endfunction 73 | 74 | function! s:base.pos() 75 | return self.col 76 | endfunction 77 | 78 | function! s:base.input(str) 79 | call extend(self.list, split(a:str, '\zs'), self.col) 80 | let self.col += len(split(a:str, '\zs')) 81 | return self 82 | endfunction 83 | 84 | function! s:base.length() 85 | return len(self.list) 86 | endfunction 87 | 88 | function! s:base.next() 89 | return self.set_pos(self.col + 1) 90 | endfunction 91 | 92 | function! s:base.prev() 93 | return self.set_pos(self.col - 1) 94 | endfunction 95 | 96 | function! s:base.remove(index) 97 | if a:index < 0 || self.length() <= a:index 98 | return "" 99 | endif 100 | let result = self.list[a:index] 101 | unlet self.list[a:index] 102 | if a:index < self.col 103 | call self.set(self.col - 1) 104 | endif 105 | return result 106 | endfunction 107 | 108 | function! s:base.remove_pos() 109 | return self.remove(self.col) 110 | endfunction 111 | 112 | function! s:base.remove_prev() 113 | return self.remove(self.col - 1) 114 | endfunction 115 | 116 | function! s:base.remove_next() 117 | return self.remove(self.col + 1) 118 | endfunction 119 | 120 | 121 | function! s:make(...) 122 | let default = get(a:, 1, "") 123 | let result = deepcopy(s:base) 124 | call result.set(default) 125 | return result 126 | endfunction 127 | 128 | " NOTE: old regexpengine has a bug with string which contains binary 129 | " :echo "\x80" =~ "\\%#=1\x80" | " => 0 130 | " But it matches correctly with :h /collection 131 | " :echo "\x80" =~ "\\%#=1[\x80]" | " => 1 132 | " http://lingr.com/room/vim/archives/2015/02/13#message-21261450 133 | let s:_engine = exists("+regexpengine") ? '\%#=2' : '' 134 | " \ => Û\xfdQ 135 | " \ => À\xfeX 136 | let s:_regex = exists("+regexpengine") 137 | \ ? "\\%(Û\xfdQ\\|À\xfeX\\|\x80\xfc.\\%(\x80..\\|.\\)\\|\x80..\\|.\\)\\zs" 138 | \ : "\\%(Û[\xfd]Q\\|À[\xfe]X\\|[\x80][\xfc].\\%([\x80]..\\|.\\)\\|[\x80]..\\|.\\)\\zs" 139 | function! s:_split_keystring(str, ...) 140 | return split(a:str, s:_engine . '\m\%(' . get(a:, 1, '') . s:_regex . '\)') 141 | endfunction 142 | 143 | function! s:split_by_keys(str) 144 | return s:_split_keystring(a:str, "\\%(\\\|\\)(.\\{-})\\zs\\|") 145 | endfunction 146 | 147 | function! s:index(haystack, needle, ...) 148 | let start = get(a:, 1, 0) 149 | let ignorecase = get(a:, 2, &ignorecase) 150 | if ignorecase 151 | return stridx(tolower(a:haystack), tolower(a:needle), start) 152 | else 153 | return stridx(a:haystack, a:needle, start) 154 | endif 155 | endfunction 156 | 157 | 158 | function! s:length(str) 159 | return len(s:split_by_keys(a:str)) 160 | endfunction 161 | 162 | 163 | let &cpo = s:save_cpo 164 | unlet s:save_cpo 165 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Palette/Capture.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#_easymotion#Palette#Capture#import() abort 6 | return map({'extend': '', '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#_easymotion#Palette#Capture#import() abort', printf("return map({'extend': '', 'command': ''}, \"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:verbosefiles = [] 22 | 23 | function! s:_verbosefile_push(file) 24 | call add(s:verbosefiles, &verbosefile) 25 | let &verbosefile = a:file 26 | return a:file 27 | endfunction 28 | 29 | 30 | function! s:_verbosefile_pop() 31 | let filename = &verbosefile 32 | let &verbosefile = get(s:verbosefiles, -1) 33 | call remove(s:verbosefiles, -1) 34 | return filename 35 | endfunction 36 | 37 | 38 | function! s:_reset() 39 | let s:verbosefiles = [] 40 | endfunction 41 | 42 | 43 | function! s:extend(dict, src) 44 | for [key, value] in items(a:src) 45 | let a:dict[key] = value 46 | unlet value 47 | endfor 48 | endfunction 49 | 50 | 51 | function! s:command(cmd, ...) 52 | " Workaround : Vim 7.3.xxx in Travis and Ubuntu 53 | " https://github.com/osyo-manga/vital-palette/issues/5 54 | " call extend(l:, get(a:, 1, {})) 55 | if a:0 > 0 56 | call s:extend(l:, a:1) 57 | endif 58 | 59 | call s:_verbosefile_push(tempname()) 60 | try 61 | redir =>result 62 | silent execute a:cmd 63 | finally 64 | redir END 65 | endtry 66 | call s:_verbosefile_pop() 67 | " let result = substitute(result, "", "\", "g") 68 | " let result = substitute(result, "", "\", "g") 69 | return result 70 | endfunction 71 | 72 | 73 | let &cpo = s:save_cpo 74 | unlet s:save_cpo 75 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Palette/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#_easymotion#Palette#Highlight#import() abort 6 | return map({'capture': '', '_vital_depends': '', 'parse': '', 'group_list': '', 'set': '', 'parse_to_name': '', 'links_to': '', 'get': '', '_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#_easymotion#Palette#Highlight#import() abort', printf("return map({'capture': '', '_vital_depends': '', 'parse': '', 'group_list': '', 'set': '', 'parse_to_name': '', 'links_to': '', 'get': '', '_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:Message = s:V.import("Vim.Message") 24 | endfunction 25 | 26 | 27 | function! s:_vital_depends() 28 | return [ 29 | \ "Vim.Message", 30 | \ ] 31 | endfunction 32 | 33 | 34 | function! s:_execute(cmd) 35 | execute a:cmd 36 | endfunction 37 | 38 | 39 | function! s:capture(name) 40 | if hlexists(a:name) == 0 41 | return "" 42 | endif 43 | return s:Message.capture("highlight " . a:name) 44 | endfunction 45 | 46 | 47 | function! s:links_to(highlight) 48 | return matchstr(a:highlight, '^\S\+\s\+xxx links to \zs.*\ze$') 49 | endfunction 50 | 51 | 52 | function! s:parse_to_name(highlight) 53 | return matchstr(a:highlight, '^\zs\w\+\ze') 54 | endfunction 55 | 56 | 57 | function! s:parse(highlight) 58 | let highlight = a:highlight 59 | 60 | if highlight !~# '^\w\+\s\+xxx\s' 61 | return {} 62 | endif 63 | 64 | let name = s:parse_to_name(a:highlight) 65 | let result = { "_name" : name } 66 | 67 | if highlight =~# '^\w\+\s\+xxx cleared' 68 | let result.cleared = 1 69 | return result 70 | endif 71 | 72 | let link = s:links_to(highlight) 73 | if link != "" 74 | let result.link = link 75 | return result 76 | endif 77 | 78 | let attrs = [ 79 | \ "term", 80 | \ "cterm", 81 | \ "ctermfg", 82 | \ "ctermbg", 83 | \ "gui", 84 | \ "font", 85 | \ "guifg", 86 | \ "guibg", 87 | \ "guisp", 88 | \ ] 89 | for attr in attrs 90 | let item = matchstr(highlight, '\s' . attr . '=\zs#\?\w\+\ze') 91 | if item != "" 92 | let result[attr] = item 93 | endif 94 | endfor 95 | return result 96 | endfunction 97 | 98 | 99 | function! s:get(name, ...) 100 | if !hlexists(a:name) 101 | return {} 102 | endif 103 | let result = s:parse(substitute(s:capture(a:name), "\n", "", "g")) 104 | if has_key(result, "link") && get(a:, 1, 0) 105 | return s:get(result.link, get(a:, 1, 0)) 106 | else 107 | return result 108 | endif 109 | endfunction 110 | 111 | 112 | function! s:set(name, config) 113 | if type(a:config) == type("") 114 | return s:set(a:config, s:get(a:config)) 115 | endif 116 | if has_key(a:config, "cleared") 117 | return s:_execute("highlight clear " . a:name) 118 | endif 119 | if has_key(a:config, "link") 120 | return s:_execute("highlight link " . a:name . " " . a:config.link) 121 | endif 122 | return s:_execute("highlight " . a:name . " " . join(map(items(filter(a:config, "v:key !=# '_name'")), "v:val[0] . '=' . v:val[1]"), " ")) 123 | endfunction 124 | 125 | 126 | function! s:group_list() 127 | let highlights = split(s:Message.capture("highlight"), "\n") 128 | return filter(map(highlights, "s:parse_to_name(v:val)"), "v:val != ''") 129 | endfunction 130 | 131 | 132 | let &cpo = s:save_cpo 133 | unlet s:save_cpo 134 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Palette/Keymapping.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#_easymotion#Palette#Keymapping#import() abort 6 | return map({'capture': '', '_vital_depends': '', 'escape_special_key': '', 'rhs_key_list': '', 'parse_lhs_list': '', 'lhs_key_list': '', 'capture_list': '', 'parse_lhs': '', '_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#_easymotion#Palette#Keymapping#import() abort', printf("return map({'capture': '', '_vital_depends': '', 'escape_special_key': '', 'rhs_key_list': '', 'parse_lhs_list': '', 'lhs_key_list': '', 'capture_list': '', 'parse_lhs': '', '_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 | let s:modep = "[nvoicsxl]" 22 | 23 | 24 | function! s:_vital_loaded(V) 25 | let s:V = a:V 26 | let s:Capture = s:V.import("Palette.Capture") 27 | endfunction 28 | 29 | 30 | function! s:_vital_depends() 31 | return [ 32 | \ "Palette.Capture", 33 | \ ] 34 | endfunction 35 | 36 | 37 | function! s:_capture(mode) 38 | let cmd = "map" 39 | if a:mode ==# "!" 40 | let cmd = cmd . "!" 41 | elseif a:mode =~# "[nvoicsxl]" 42 | let cmd = a:mode . cmd 43 | endif 44 | return s:Capture.command(cmd) 45 | endfunction 46 | 47 | 48 | function! s:capture(...) 49 | let mode = get(a:, 1, "") 50 | let modes = split(mode, '\zs') 51 | return join(map(modes, "s:_capture(v:val)"), "\n") 52 | endfunction 53 | 54 | 55 | function! s:_keymapping(str) 56 | return a:str =~ '^[!nvoicsxl]\s' 57 | endfunction 58 | 59 | 60 | function! s:capture_list(...) 61 | let mode = get(a:, 1, "") 62 | return filter(split(s:capture(mode), "\n"), "s:_keymapping(v:val)") 63 | endfunction 64 | 65 | 66 | function! s:escape_special_key(key) 67 | " Workaround : https://github.com/osyo-manga/vital-palette/issues/5 68 | if a:key ==# "<^?>" 69 | return "\" 70 | endif 71 | execute 'let result = "' . substitute(escape(a:key, '\"'), '\(<.\{-}>\)', '\\\1', 'g') . '"' 72 | return result 73 | endfunction 74 | 75 | 76 | function! s:parse_lhs(text, ...) 77 | let mode = get(a:, 1, '[!nvoicsxl]') 78 | " NOTE: :map! Surpport : https://github.com/osyo-manga/vital-palette/issues/4 79 | if get(a:, 1, "") =~# '[!ci]' 80 | let mode = '[!ci]' 81 | endif 82 | return matchstr(a:text, mode . '\{1,3\}\s*\zs\S\{-}\ze\s\+') 83 | endfunction 84 | 85 | 86 | function! s:parse_lhs_list(...) 87 | let mode = get(a:, 1, "") 88 | return map(s:capture_list(mode), "s:parse_lhs(v:val, mode)") 89 | endfunction 90 | 91 | 92 | function! s:lhs_key_list(...) 93 | let mode = get(a:, 1, "") 94 | return map(s:parse_lhs_list(mode), "s:escape_special_key(v:val)") 95 | endfunction 96 | 97 | 98 | function! s:_maparg(name, mode, abbr, dict) 99 | " Workaround : https://github.com/osyo-manga/vital-palette/issues/5 100 | if a:name ==# "<^?>" 101 | return maparg("\", a:mode, a:abbr, a:dict) 102 | endif 103 | return maparg(a:name, a:mode, a:abbr, a:dict) 104 | endfunction 105 | 106 | 107 | function! s:rhs_key_list(...) 108 | let mode = get(a:, 1, "") 109 | let abbr = get(a:, 2, 0) 110 | let dict = get(a:, 3, 0) 111 | 112 | let result = [] 113 | for m in split(mode, '\zs') 114 | let result += map(s:parse_lhs_list(m), "s:_maparg(v:val, m, abbr, dict)") 115 | endfor 116 | return filter(result, "empty(v:val) == 0") 117 | endfunction 118 | 119 | 120 | let &cpo = s:save_cpo 121 | unlet s:save_cpo 122 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/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#_easymotion#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#_easymotion#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 == 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 | return split(glob(a:expr, 1), '\n') 27 | endfunction 28 | endif 29 | 30 | if v:version > 704 || 31 | \ (v:version == 704 && has('patch279')) 32 | function! s:globpath(path, expr) abort 33 | return globpath(a:path, a:expr, 1, 1) 34 | endfunction 35 | else 36 | function! s:globpath(path, expr) abort 37 | return split(globpath(a:path, a:expr, 1), '\n') 38 | endfunction 39 | endif 40 | 41 | " Wrapper functions for type(). 42 | " NOTE: __TYPE_FLOAT = -1 when -float. 43 | " this doesn't match to anything. 44 | if has('patch-7.4.2071') 45 | let [ 46 | \ s:__TYPE_NUMBER, 47 | \ s:__TYPE_STRING, 48 | \ s:__TYPE_FUNCREF, 49 | \ s:__TYPE_LIST, 50 | \ s:__TYPE_DICT, 51 | \ s:__TYPE_FLOAT] = [ 52 | \ v:t_number, 53 | \ v:t_string, 54 | \ v:t_func, 55 | \ v:t_list, 56 | \ v:t_dict, 57 | \ v:t_float] 58 | else 59 | let [ 60 | \ s:__TYPE_NUMBER, 61 | \ s:__TYPE_STRING, 62 | \ s:__TYPE_FUNCREF, 63 | \ s:__TYPE_LIST, 64 | \ s:__TYPE_DICT, 65 | \ s:__TYPE_FLOAT] = [ 66 | \ type(3), 67 | \ type(''), 68 | \ type(function('tr')), 69 | \ type([]), 70 | \ type({}), 71 | \ has('float') ? type(str2float('0')) : -1] 72 | endif 73 | 74 | " Number or Float 75 | function! s:is_numeric(Value) abort 76 | let _ = type(a:Value) 77 | return _ ==# s:__TYPE_NUMBER 78 | \ || _ ==# s:__TYPE_FLOAT 79 | endfunction 80 | 81 | " Number 82 | function! s:is_number(Value) abort 83 | return type(a:Value) ==# s:__TYPE_NUMBER 84 | endfunction 85 | 86 | " String 87 | function! s:is_string(Value) abort 88 | return type(a:Value) ==# s:__TYPE_STRING 89 | endfunction 90 | 91 | " Funcref 92 | function! s:is_funcref(Value) abort 93 | return type(a:Value) ==# s:__TYPE_FUNCREF 94 | endfunction 95 | 96 | " List 97 | function! s:is_list(Value) abort 98 | return type(a:Value) ==# s:__TYPE_LIST 99 | endfunction 100 | 101 | " Dictionary 102 | function! s:is_dict(Value) abort 103 | return type(a:Value) ==# s:__TYPE_DICT 104 | endfunction 105 | 106 | " Float 107 | function! s:is_float(Value) abort 108 | return type(a:Value) ==# s:__TYPE_FLOAT 109 | endfunction 110 | 111 | 112 | function! s:truncate_skipping(str, max, footer_width, separator) abort 113 | call s:_warn_deprecated('truncate_skipping', 'Data.String.truncate_skipping') 114 | 115 | let width = s:wcswidth(a:str) 116 | if width <= a:max 117 | let ret = a:str 118 | else 119 | let header_width = a:max - s:wcswidth(a:separator) - a:footer_width 120 | let ret = s:strwidthpart(a:str, header_width) . a:separator 121 | \ . s:strwidthpart_reverse(a:str, a:footer_width) 122 | endif 123 | 124 | return s:truncate(ret, a:max) 125 | endfunction 126 | 127 | function! s:truncate(str, width) abort 128 | " Original function is from mattn. 129 | " http://github.com/mattn/googlereader-vim/tree/master 130 | 131 | call s:_warn_deprecated('truncate', 'Data.String.truncate') 132 | 133 | if a:str =~# '^[\x00-\x7f]*$' 134 | return len(a:str) < a:width ? 135 | \ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width) 136 | endif 137 | 138 | let ret = a:str 139 | let width = s:wcswidth(a:str) 140 | if width > a:width 141 | let ret = s:strwidthpart(ret, a:width) 142 | let width = s:wcswidth(ret) 143 | endif 144 | 145 | if width < a:width 146 | let ret .= repeat(' ', a:width - width) 147 | endif 148 | 149 | return ret 150 | endfunction 151 | 152 | function! s:strwidthpart(str, width) abort 153 | call s:_warn_deprecated('strwidthpart', 'Data.String.strwidthpart') 154 | 155 | if a:width <= 0 156 | return '' 157 | endif 158 | let ret = a:str 159 | let width = s:wcswidth(a:str) 160 | while width > a:width 161 | let char = matchstr(ret, '.$') 162 | let ret = ret[: -1 - len(char)] 163 | let width -= s:wcswidth(char) 164 | endwhile 165 | 166 | return ret 167 | endfunction 168 | function! s:strwidthpart_reverse(str, width) abort 169 | call s:_warn_deprecated('strwidthpart_reverse', 'Data.String.strwidthpart_reverse') 170 | 171 | if a:width <= 0 172 | return '' 173 | endif 174 | let ret = a:str 175 | let width = s:wcswidth(a:str) 176 | while width > a:width 177 | let char = matchstr(ret, '^.') 178 | let ret = ret[len(char) :] 179 | let width -= s:wcswidth(char) 180 | endwhile 181 | 182 | return ret 183 | endfunction 184 | 185 | if v:version >= 703 186 | " Use builtin function. 187 | function! s:wcswidth(str) abort 188 | call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth') 189 | return strwidth(a:str) 190 | endfunction 191 | else 192 | function! s:wcswidth(str) abort 193 | call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth') 194 | 195 | if a:str =~# '^[\x00-\x7f]*$' 196 | return strlen(a:str) 197 | end 198 | 199 | let mx_first = '^\(.\)' 200 | let str = a:str 201 | let width = 0 202 | while 1 203 | let ucs = char2nr(substitute(str, mx_first, '\1', '')) 204 | if ucs == 0 205 | break 206 | endif 207 | let width += s:_wcwidth(ucs) 208 | let str = substitute(str, mx_first, '', '') 209 | endwhile 210 | return width 211 | endfunction 212 | 213 | " UTF-8 only. 214 | function! s:_wcwidth(ucs) abort 215 | let ucs = a:ucs 216 | if (ucs >= 0x1100 217 | \ && (ucs <= 0x115f 218 | \ || ucs == 0x2329 219 | \ || ucs == 0x232a 220 | \ || (ucs >= 0x2e80 && ucs <= 0xa4cf 221 | \ && ucs != 0x303f) 222 | \ || (ucs >= 0xac00 && ucs <= 0xd7a3) 223 | \ || (ucs >= 0xf900 && ucs <= 0xfaff) 224 | \ || (ucs >= 0xfe30 && ucs <= 0xfe6f) 225 | \ || (ucs >= 0xff00 && ucs <= 0xff60) 226 | \ || (ucs >= 0xffe0 && ucs <= 0xffe6) 227 | \ || (ucs >= 0x20000 && ucs <= 0x2fffd) 228 | \ || (ucs >= 0x30000 && ucs <= 0x3fffd) 229 | \ )) 230 | return 2 231 | endif 232 | return 1 233 | endfunction 234 | endif 235 | 236 | let s:is_windows = has('win16') || has('win32') || has('win64') || has('win95') 237 | let s:is_cygwin = has('win32unix') 238 | let s:is_mac = !s:is_windows && !s:is_cygwin 239 | \ && (has('mac') || has('macunix') || has('gui_macvim') || 240 | \ (!isdirectory('/proc') && executable('sw_vers'))) 241 | let s:is_unix = has('unix') 242 | 243 | function! s:is_windows() abort 244 | return s:is_windows 245 | endfunction 246 | 247 | function! s:is_cygwin() abort 248 | return s:is_cygwin 249 | endfunction 250 | 251 | function! s:is_mac() abort 252 | return s:is_mac 253 | endfunction 254 | 255 | function! s:is_unix() abort 256 | return s:is_unix 257 | endfunction 258 | 259 | function! s:_warn_deprecated(name, alternative) abort 260 | try 261 | echohl Error 262 | echomsg 'Prelude.' . a:name . ' is deprecated! Please use ' . a:alternative . ' instead.' 263 | finally 264 | echohl None 265 | endtry 266 | endfunction 267 | 268 | function! s:smart_execute_command(action, word) abort 269 | execute a:action . ' ' . (a:word ==# '' ? '' : '`=a:word`') 270 | endfunction 271 | 272 | function! s:escape_file_searching(buffer_name) abort 273 | return escape(a:buffer_name, '*[]?{}, ') 274 | endfunction 275 | 276 | function! s:escape_pattern(str) abort 277 | call s:_warn_deprecated( 278 | \ 'escape_pattern', 279 | \ 'Data.String.escape_pattern', 280 | \) 281 | return escape(a:str, '~"\.^$[]*') 282 | endfunction 283 | 284 | function! s:getchar(...) abort 285 | let c = call('getchar', a:000) 286 | return type(c) == type(0) ? nr2char(c) : c 287 | endfunction 288 | 289 | function! s:getchar_safe(...) abort 290 | let c = s:input_helper('getchar', a:000) 291 | return type(c) == type('') ? c : nr2char(c) 292 | endfunction 293 | 294 | function! s:input_safe(...) abort 295 | return s:input_helper('input', a:000) 296 | endfunction 297 | 298 | function! s:input_helper(funcname, args) abort 299 | let success = 0 300 | if inputsave() !=# success 301 | throw 'vital: Prelude: inputsave() failed' 302 | endif 303 | try 304 | return call(a:funcname, a:args) 305 | finally 306 | if inputrestore() !=# success 307 | throw 'vital: Prelude: inputrestore() failed' 308 | endif 309 | endtry 310 | endfunction 311 | 312 | function! s:set_default(var, val) abort 313 | if !exists(a:var) || type({a:var}) != type(a:val) 314 | let {a:var} = a:val 315 | endif 316 | endfunction 317 | 318 | function! s:substitute_path_separator(path) abort 319 | return s:is_windows ? substitute(a:path, '\\', '/', 'g') : a:path 320 | endfunction 321 | 322 | function! s:path2directory(path) abort 323 | return s:substitute_path_separator(isdirectory(a:path) ? a:path : fnamemodify(a:path, ':p:h')) 324 | endfunction 325 | 326 | function! s:_path2project_directory_git(path) abort 327 | let parent = a:path 328 | 329 | while 1 330 | let path = parent . '/.git' 331 | if isdirectory(path) || filereadable(path) 332 | return parent 333 | endif 334 | let next = fnamemodify(parent, ':h') 335 | if next == parent 336 | return '' 337 | endif 338 | let parent = next 339 | endwhile 340 | endfunction 341 | 342 | function! s:_path2project_directory_svn(path) abort 343 | let search_directory = a:path 344 | let directory = '' 345 | 346 | let find_directory = s:escape_file_searching(search_directory) 347 | let d = finddir('.svn', find_directory . ';') 348 | if d ==# '' 349 | return '' 350 | endif 351 | 352 | let directory = fnamemodify(d, ':p:h:h') 353 | 354 | " Search parent directories. 355 | let parent_directory = s:path2directory( 356 | \ fnamemodify(directory, ':h')) 357 | 358 | if parent_directory !=# '' 359 | let d = finddir('.svn', parent_directory . ';') 360 | if d !=# '' 361 | let directory = s:_path2project_directory_svn(parent_directory) 362 | endif 363 | endif 364 | return directory 365 | endfunction 366 | 367 | function! s:_path2project_directory_others(vcs, path) abort 368 | let vcs = a:vcs 369 | let search_directory = a:path 370 | 371 | let find_directory = s:escape_file_searching(search_directory) 372 | let d = finddir(vcs, find_directory . ';') 373 | if d ==# '' 374 | return '' 375 | endif 376 | return fnamemodify(d, ':p:h:h') 377 | endfunction 378 | 379 | function! s:path2project_directory(path, ...) abort 380 | let is_allow_empty = get(a:000, 0, 0) 381 | let search_directory = s:path2directory(a:path) 382 | let directory = '' 383 | 384 | " Search VCS directory. 385 | for vcs in ['.git', '.bzr', '.hg', '.svn'] 386 | if vcs ==# '.git' 387 | let directory = s:_path2project_directory_git(search_directory) 388 | elseif vcs ==# '.svn' 389 | let directory = s:_path2project_directory_svn(search_directory) 390 | else 391 | let directory = s:_path2project_directory_others(vcs, search_directory) 392 | endif 393 | if directory !=# '' 394 | break 395 | endif 396 | endfor 397 | 398 | " Search project file. 399 | if directory ==# '' 400 | for d in ['build.xml', 'prj.el', '.project', 'pom.xml', 'package.json', 401 | \ 'Makefile', 'configure', 'Rakefile', 'NAnt.build', 402 | \ 'P4CONFIG', 'tags', 'gtags'] 403 | let d = findfile(d, s:escape_file_searching(search_directory) . ';') 404 | if d !=# '' 405 | let directory = fnamemodify(d, ':p:h') 406 | break 407 | endif 408 | endfor 409 | endif 410 | 411 | if directory ==# '' 412 | " Search /src/ directory. 413 | let base = s:substitute_path_separator(search_directory) 414 | if base =~# '/src/' 415 | let directory = base[: strridx(base, '/src/') + 3] 416 | endif 417 | endif 418 | 419 | if directory ==# '' && !is_allow_empty 420 | " Use original path. 421 | let directory = search_directory 422 | endif 423 | 424 | return s:substitute_path_separator(directory) 425 | endfunction 426 | 427 | let &cpo = s:save_cpo 428 | unlet s:save_cpo 429 | 430 | " vim:set et ts=2 sts=2 sw=2 tw=0: 431 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/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#_easymotion#Vim#Buffer#import() abort 6 | return map({'parse_cmdarg': '', '_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#_easymotion#Vim#Buffer#import() abort', printf("return map({'parse_cmdarg': '', '_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 | \ 'line': '', 118 | \}, get(a:000, 0, {})) 119 | let tempfile = empty(options.tempfile) ? tempname() : options.tempfile 120 | let optnames = [ 121 | \ empty(options.fileformat) ? '' : '++ff=' . options.fileformat, 122 | \ empty(options.encoding) ? '' : '++enc=' . options.encoding, 123 | \ empty(options.binary) ? '' : '++bin', 124 | \ empty(options.nobinary) ? '' : '++nobin', 125 | \ empty(options.bad) ? '' : '++bad=' . options.bad, 126 | \ empty(options.edit) ? '' : '++edit', 127 | \] 128 | let optname = join(filter(optnames, '!empty(v:val)')) 129 | try 130 | call writefile(a:content, tempfile) 131 | execute printf('keepalt keepjumps %sread %s%s', 132 | \ options.line, 133 | \ empty(optname) ? '' : optname . ' ', 134 | \ fnameescape(tempfile), 135 | \) 136 | finally 137 | call delete(tempfile) 138 | execute 'bwipeout!' tempfile 139 | endtry 140 | endfunction 141 | 142 | function! s:edit_content(content, ...) abort 143 | let options = extend({ 144 | \ 'edit': 1, 145 | \}, get(a:000, 0, {})) 146 | let guard = s:G.store(['&l:modifiable']) 147 | let saved_view = winsaveview() 148 | try 149 | let &l:modifiable=1 150 | silent keepjumps %delete _ 151 | silent call s:read_content(a:content, options) 152 | silent keepjumps 1delete _ 153 | finally 154 | keepjump call winrestview(saved_view) 155 | call guard.restore() 156 | endtry 157 | setlocal nomodified 158 | endfunction 159 | 160 | function! s:parse_cmdarg(...) abort 161 | let cmdarg = get(a:000, 0, v:cmdarg) 162 | let options = {} 163 | if cmdarg =~# '++enc=' 164 | let options.encoding = matchstr(cmdarg, '++enc=\zs[^ ]\+\ze') 165 | endif 166 | if cmdarg =~# '++ff=' 167 | let options.fileformat = matchstr(cmdarg, '++ff=\zs[^ ]\+\ze') 168 | endif 169 | if cmdarg =~# '++bad=' 170 | let options.bad = matchstr(cmdarg, '++bad=\zs[^ ]\+\ze') 171 | endif 172 | if cmdarg =~# '++bin' 173 | let options.binary = 1 174 | endif 175 | if cmdarg =~# '++nobin' 176 | let options.nobinary = 1 177 | endif 178 | if cmdarg =~# '++edit' 179 | let options.edit = 1 180 | endif 181 | return options 182 | endfunction 183 | 184 | let &cpo = s:save_cpo 185 | unlet s:save_cpo 186 | 187 | " vim:set et ts=2 sts=2 sw=2 tw=0: 188 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/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#_easymotion#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#_easymotion#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 | " https://github.com/vim/vim/commit/5a50c2255c447838d08d3b4895a3be3a41cd8eda 104 | if has('patch-7.4.243') || self.name !=# '=' 105 | call setreg(self.name, self.value, self.type) 106 | else 107 | let @= = self.value 108 | endif 109 | endfunction 110 | 111 | let s:environment = {} 112 | function! s:_new_environment(name) abort 113 | if a:name !~# '^\$' 114 | call s:_throw(printf( 115 | \'An environment variable name "%s" requires to be started from "$"', a:name 116 | \)) 117 | elseif !exists(a:name) 118 | call s:_throw(printf( 119 | \'An environment variable name "%s" does not exist. While Vim cannot unlet environment variable, it requires to exist', a:name 120 | \)) 121 | endif 122 | let environment = copy(s:environment) 123 | let environment.name = a:name 124 | let environment.value = eval(a:name) 125 | return environment 126 | endfunction 127 | function! s:environment.restore() abort 128 | execute printf('let %s = %s', self.name, string(self.value)) 129 | endfunction 130 | 131 | let s:variable = {} 132 | function! s:_new_variable(name, ...) abort 133 | if a:0 == 0 134 | let m = matchlist(a:name, '^\([bwtg]:\)\(.*\)$') 135 | if empty(m) 136 | call s:_throw(printf( 137 | \ join([ 138 | \ 'An variable name "%s" requires to start from b:, w:, t:, or g:', 139 | \ 'while no {namespace} is specified', 140 | \ ]), 141 | \ a:name, 142 | \)) 143 | endif 144 | let [prefix, name] = m[1 : 2] 145 | let namespace = eval(prefix) 146 | else 147 | let name = a:name 148 | let namespace = a:1 149 | endif 150 | let variable = copy(s:variable) 151 | let variable.name = name 152 | let variable.value = get(namespace, name, s:_UNDEFINED) 153 | let variable.value = 154 | \ type(variable.value) == type({}) || type(variable.value) == type([]) 155 | \ ? deepcopy(variable.value) 156 | \ : variable.value 157 | let variable._namespace = namespace 158 | return variable 159 | endfunction 160 | function! s:variable.restore() abort 161 | " unlet the variable to prevent variable type mis-match in case 162 | silent! unlet! self._namespace[self.name] 163 | if type(self.value) == type(s:_UNDEFINED) && self.value == s:_UNDEFINED 164 | " do nothing, leave the variable as undefined 165 | else 166 | let self._namespace[self.name] = self.value 167 | endif 168 | endfunction 169 | 170 | let s:instance = {} 171 | function! s:_new_instance(instance, ...) abort 172 | let shallow = get(a:000, 0, 0) 173 | if !s:Prelude.is_list(a:instance) && !s:Prelude.is_dict(a:instance) 174 | call s:_throw(printf( 175 | \'An instance "%s" requires to be List or Dictionary', string(a:instance) 176 | \)) 177 | endif 178 | let instance = copy(s:instance) 179 | let instance.instance = a:instance 180 | let instance.values = shallow ? copy(a:instance) : deepcopy(a:instance) 181 | return instance 182 | endfunction 183 | function! s:instance.restore() abort 184 | if s:Prelude.is_list(self.instance) 185 | call s:List.clear(self.instance) 186 | else 187 | call s:Dict.clear(self.instance) 188 | endif 189 | call extend(self.instance, self.values) 190 | endfunction 191 | 192 | let s:guard = {} 193 | function! s:store(targets) abort 194 | let resources = [] 195 | for meta in a:targets 196 | if s:Prelude.is_list(meta) 197 | if len(meta) == 1 198 | call add(resources, s:_new_instance(meta[0])) 199 | elseif len(meta) == 2 200 | if s:Prelude.is_string(meta[0]) 201 | call add(resources, call('s:_new_variable', meta)) 202 | else 203 | call add(resources, call('s:_new_instance', meta)) 204 | endif 205 | else 206 | call s:_throw('List assignment requires one or two elements') 207 | endif 208 | elseif type(meta) == type('') 209 | if meta =~# '^[bwtgls]:' 210 | " Note: 211 | " To improve an error message, handle l:XXX or s:XXX as well 212 | call add(resources, s:_new_variable(meta)) 213 | elseif meta =~# '^&' 214 | call add(resources, s:_new_option(meta)) 215 | elseif meta =~# '^@' 216 | call add(resources, s:_new_register(meta)) 217 | elseif meta =~# '^\$' 218 | call add(resources, s:_new_environment(meta)) 219 | else 220 | call s:_throw(printf( 221 | \ 'Unknown value "%s" was specified', 222 | \ meta 223 | \)) 224 | endif 225 | endif 226 | unlet meta 227 | endfor 228 | let guard = copy(s:guard) 229 | let guard._resources = resources 230 | return guard 231 | endfunction 232 | function! s:guard.restore() abort 233 | for resource in self._resources 234 | call resource.restore() 235 | endfor 236 | endfunction 237 | 238 | let &cpo = s:save_cpo 239 | unlet! s:save_cpo 240 | " vim:set et ts=2 sts=2 sw=2 tw=0 fdm=marker: 241 | -------------------------------------------------------------------------------- /autoload/vital/_easymotion/Vim/Message.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#_easymotion#Vim#Message#import() abort 6 | return map({'capture': '', 'echomsg': '', 'echo': '', 'warn': '', 'get_hit_enter_max_length': '', 'error': ''}, '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#_easymotion#Vim#Message#import() abort', printf("return map({'capture': '', 'echomsg': '', 'echo': '', 'warn': '', 'get_hit_enter_max_length': '', 'error': ''}, \"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 | 20 | 21 | function! s:echo(hl, msg) abort 22 | execute 'echohl' a:hl 23 | try 24 | echo a:msg 25 | finally 26 | echohl None 27 | endtry 28 | endfunction 29 | 30 | function! s:echomsg(hl, msg) abort 31 | execute 'echohl' a:hl 32 | try 33 | for m in split(a:msg, "\n") 34 | echomsg m 35 | endfor 36 | finally 37 | echohl None 38 | endtry 39 | endfunction 40 | 41 | function! s:error(msg) abort 42 | call s:echomsg('ErrorMsg', a:msg) 43 | endfunction 44 | 45 | function! s:warn(msg) abort 46 | call s:echomsg('WarningMsg', a:msg) 47 | endfunction 48 | 49 | function! s:capture(command) abort 50 | try 51 | redir => out 52 | silent execute a:command 53 | finally 54 | redir END 55 | endtry 56 | return out 57 | endfunction 58 | 59 | " * Get max length of |hit-enter|. 60 | " If a string length of a message is greater than the max length, 61 | " Vim waits for user input according to |hit-enter|. 62 | " XXX: Those fixed values may be different between different OSes? 63 | " Currently tested on only Windows. 64 | function! s:get_hit_enter_max_length() abort 65 | let maxlen = &columns * &cmdheight - 1 66 | if &ruler 67 | " TODO 68 | endif 69 | if &showcmd 70 | let maxlen -= 11 71 | endif 72 | return maxlen 73 | endfunction 74 | 75 | 76 | 77 | let &cpo = s:save_cpo 78 | unlet s:save_cpo 79 | 80 | " vim:set et ts=2 sts=2 sw=2 tw=0: 81 | -------------------------------------------------------------------------------- /autoload/vital/easymotion.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}#new() 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}#new()) 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/easymotion.vital: -------------------------------------------------------------------------------- 1 | easymotion 2 | 882de6964d10595e839ccbcc0fb20b7ff14e43cb 3 | 4 | Over.Commandline.Base 5 | Over.Commandline.Modules.Cancel 6 | Over.Commandline.Modules.BufferComplete 7 | Over.Commandline.Modules.Paste 8 | Over.Commandline.Modules.KeyMapping 9 | Over.Commandline.Modules.Doautocmd 10 | Over.Commandline.Modules.CursorMove 11 | Over.Commandline.Modules.Delete 12 | Over.Commandline.Modules.Redraw 13 | Over.Commandline.Modules.InsertRegister 14 | Over.Commandline.Modules.History 15 | Over.Commandline.Modules.NoInsert 16 | Over.Commandline.Modules.Exit 17 | Over.Commandline.Modules.DrawCommandline 18 | Over.Commandline.Modules.ExceptionMessage 19 | Over.Commandline.Modules.ExceptionExit 20 | HitAHint.Motion 21 | -------------------------------------------------------------------------------- /plugin/EasyMotion.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | " EasyMotion - Vim motions on speed! 3 | " 4 | " Author: Kim Silkebækken 5 | " haya14busa 6 | " Source: https://github.com/easymotion/vim-easymotion 7 | " == Script initialization {{{ 8 | if expand("%:p") ==# expand(":p") 9 | unlet! g:EasyMotion_loaded 10 | endif 11 | if exists('g:EasyMotion_loaded') || &compatible || version < 703 12 | finish 13 | endif 14 | 15 | let g:EasyMotion_loaded = 1 16 | " }}} 17 | 18 | " == Saving 'cpoptions' {{{ 19 | let s:save_cpo = &cpo 20 | set cpo&vim 21 | " }}} 22 | 23 | " == Default configuration {{{ 24 | " -- Option ------------------------------ {{{ 25 | let g:EasyMotion_keys = get(g:, 26 | \ 'EasyMotion_keys', 'asdghklqwertyuiopzxcvbnmfj;') 27 | " \ 'EasyMotion_keys', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') 28 | let g:EasyMotion_do_mapping = get(g: , 'EasyMotion_do_mapping' , 1) 29 | let g:EasyMotion_do_shade = get(g: , 'EasyMotion_do_shade' , 1) 30 | let g:EasyMotion_grouping = get(g: , 'EasyMotion_grouping' , 1) 31 | let g:EasyMotion_startofline = get(g: , 'EasyMotion_startofline' , 1) 32 | let g:EasyMotion_smartcase = get(g: , 'EasyMotion_smartcase' , 0) 33 | let g:EasyMotion_skipfoldedline = get(g: , 'EasyMotion_skipfoldedline' , 1) 34 | let g:EasyMotion_use_migemo = get(g: , 'EasyMotion_use_migemo' , 0) 35 | let g:EasyMotion_use_upper = get(g: , 'EasyMotion_use_upper' , 0) 36 | let g:EasyMotion_enter_jump_first = get(g: , 'EasyMotion_enter_jump_first' , 0) 37 | let g:EasyMotion_space_jump_first = get(g: , 'EasyMotion_space_jump_first' , 0) 38 | let g:EasyMotion_inc_highlight = get(g: , 'EasyMotion_inc_highlight' , 1) 39 | let g:EasyMotion_move_highlight = get(g: , 'EasyMotion_move_highlight' , 1) 40 | let g:EasyMotion_landing_highlight = get(g: , 'EasyMotion_landing_highlight' , 0) 41 | let g:EasyMotion_cursor_highlight = get(g: , 'EasyMotion_cursor_highlight' , 1) 42 | let g:EasyMotion_use_regexp = get(g: , 'EasyMotion_use_regexp' , 1) 43 | let g:EasyMotion_add_search_history = get(g: , 'EasyMotion_add_search_history' , 1) 44 | let g:EasyMotion_off_screen_search = get(g: , 'EasyMotion_off_screen_search' , 1) 45 | let g:EasyMotion_force_csapprox = get(g: , 'EasyMotion_force_csapprox' , 0) 46 | let g:EasyMotion_show_prompt = get(g: , 'EasyMotion_show_prompt' , 1) 47 | let g:EasyMotion_verbose = get(g: , 'EasyMotion_verbose' , 1) 48 | let g:EasyMotion_prompt = 49 | \ get(g: , 'EasyMotion_prompt' , 'Search for {n} character(s): ') 50 | let g:EasyMotion_command_line_key_mappings = 51 | \ get(g: , 'EasyMotion_command_line_key_mappings' , {}) 52 | let g:EasyMotion_disable_two_key_combo = 53 | \ get(g: , 'EasyMotion_disable_two_key_combo' , 0) 54 | 55 | "}}} 56 | 57 | " }}} 58 | 59 | " == Mapping {{{ 60 | " Note: bd is short for bidirectional 61 | " l is short for (within) line 62 | 63 | function! s:motion_map_helper(motions) "{{{ 64 | for [name, dict] in items(a:motions) 65 | let mapargs = [] 66 | let xmapargs = [] 67 | if dict.fnc ==# 'S' || dict.fnc ==# 'SL' || dict.fnc ==# 'T' || dict.fnc ==# 'TL' 68 | let mapargs += [dict.cnt, 0, dict.direction] 69 | let xmapargs += [dict.cnt, 1, dict.direction] 70 | elseif dict.fnc ==# 'Search' 71 | let mapargs += [0, dict.direction, dict.respect_direction] 72 | let xmapargs += [1, dict.direction, dict.respect_direction] 73 | else 74 | let mapargs += [0, dict.direction] 75 | let xmapargs += [1, dict.direction] 76 | endif 77 | 78 | silent exec 'noremap (easymotion-'.name.')' . 79 | \ ' :call EasyMotion#' . dict.fnc . '('. join(mapargs, ',') . ')' 80 | silent exec 'xnoremap (easymotion-'.name.')' . 81 | \ ' :call EasyMotion#' . dict.fnc . '('. join(xmapargs, ',') . ')' 82 | " Example: 83 | " noremap (easymotion-f2) :call EasyMotion#S(2,1,0) 84 | " xnoremap (easymotion-f2) :call EasyMotion#S(2,1,0) 85 | endfor 86 | endfunction "}}} 87 | 88 | " Find Motion: {{{ 89 | call s:motion_map_helper({ 90 | \ 'f' : {'fnc' : 'S' , 'cnt' : 1, 'direction' : 0}, 91 | \ 'F' : {'fnc' : 'S' , 'cnt' : 1, 'direction' : 1}, 92 | \ 's' : {'fnc' : 'S' , 'cnt' : 1, 'direction' : 2}, 93 | \ 'bd-f' : {'fnc' : 'S' , 'cnt' : 1, 'direction' : 2}, 94 | \ 't' : {'fnc' : 'T' , 'cnt' : 1, 'direction' : 0}, 95 | \ 'T' : {'fnc' : 'T' , 'cnt' : 1, 'direction' : 1}, 96 | \ 'bd-t' : {'fnc' : 'T' , 'cnt' : 1, 'direction' : 2}, 97 | \ 'fl' : {'fnc' : 'SL' , 'cnt' : 1, 'direction' : 0}, 98 | \ 'Fl' : {'fnc' : 'SL' , 'cnt' : 1, 'direction' : 1}, 99 | \ 'sl' : {'fnc' : 'SL' , 'cnt' : 1, 'direction' : 2}, 100 | \ 'bd-fl' : {'fnc' : 'SL' , 'cnt' : 1, 'direction' : 2}, 101 | \ 'tl' : {'fnc' : 'TL' , 'cnt' : 1, 'direction' : 0}, 102 | \ 'Tl' : {'fnc' : 'TL' , 'cnt' : 1, 'direction' : 1}, 103 | \ 'bd-tl' : {'fnc' : 'TL' , 'cnt' : 1, 'direction' : 2}, 104 | \ 105 | \ 'f2' : {'fnc' : 'S' , 'cnt' : 2, 'direction' : 0}, 106 | \ 'F2' : {'fnc' : 'S' , 'cnt' : 2, 'direction' : 1}, 107 | \ 's2' : {'fnc' : 'S' , 'cnt' : 2, 'direction' : 2}, 108 | \ 'bd-f2' : {'fnc' : 'S' , 'cnt' : 2, 'direction' : 2}, 109 | \ 't2' : {'fnc' : 'T' , 'cnt' : 2, 'direction' : 0}, 110 | \ 'T2' : {'fnc' : 'T' , 'cnt' : 2, 'direction' : 1}, 111 | \ 'bd-t2' : {'fnc' : 'T' , 'cnt' : 2, 'direction' : 2}, 112 | \ 'fl2' : {'fnc' : 'SL' , 'cnt' : 2, 'direction' : 0}, 113 | \ 'Fl2' : {'fnc' : 'SL' , 'cnt' : 2, 'direction' : 1}, 114 | \ 'sl2' : {'fnc' : 'SL' , 'cnt' : 2, 'direction' : 2}, 115 | \ 'bd-fl2' : {'fnc' : 'SL' , 'cnt' : 2, 'direction' : 2}, 116 | \ 'tl2' : {'fnc' : 'TL' , 'cnt' : 2, 'direction' : 0}, 117 | \ 'Tl2' : {'fnc' : 'TL' , 'cnt' : 2, 'direction' : 1}, 118 | \ 'bd-tl2' : {'fnc' : 'TL' , 'cnt' : 2, 'direction' : 2}, 119 | \ 120 | \ 'fn' : {'fnc' : 'S' , 'cnt' : -1, 'direction' : 0}, 121 | \ 'Fn' : {'fnc' : 'S' , 'cnt' : -1, 'direction' : 1}, 122 | \ 'sn' : {'fnc' : 'S' , 'cnt' : -1, 'direction' : 2}, 123 | \ 'bd-fn' : {'fnc' : 'S' , 'cnt' : -1, 'direction' : 2}, 124 | \ 'tn' : {'fnc' : 'T' , 'cnt' : -1, 'direction' : 0}, 125 | \ 'Tn' : {'fnc' : 'T' , 'cnt' : -1, 'direction' : 1}, 126 | \ 'bd-tn' : {'fnc' : 'T' , 'cnt' : -1, 'direction' : 2}, 127 | \ 'fln' : {'fnc' : 'SL' , 'cnt' : -1, 'direction' : 0}, 128 | \ 'Fln' : {'fnc' : 'SL' , 'cnt' : -1, 'direction' : 1}, 129 | \ 'sln' : {'fnc' : 'SL' , 'cnt' : -1, 'direction' : 2}, 130 | \ 'bd-fln' : {'fnc' : 'SL' , 'cnt' : -1, 'direction' : 2}, 131 | \ 'tln' : {'fnc' : 'TL' , 'cnt' : -1, 'direction' : 0}, 132 | \ 'Tln' : {'fnc' : 'TL' , 'cnt' : -1, 'direction' : 1}, 133 | \ 'bd-tln' : {'fnc' : 'TL' , 'cnt' : -1, 'direction' : 2}, 134 | \ }) 135 | 136 | nnoremap (easymotion-overwin-f) :call EasyMotion#OverwinF(1) 137 | nnoremap (easymotion-overwin-f2) :call EasyMotion#OverwinF(2) 138 | nnoremap (easymotion-overwin-line) :call EasyMotion#overwin#line() 139 | nnoremap (easymotion-overwin-w) :call EasyMotion#overwin#w() 140 | 141 | "}}} 142 | 143 | " -- Word Motion {{{ 144 | call s:motion_map_helper({ 145 | \ 'w' : {'fnc' : 'WB' , 'direction' : 0}, 146 | \ 'b' : {'fnc' : 'WB' , 'direction' : 1}, 147 | \ 'bd-w' : {'fnc' : 'WB' , 'direction' : 2}, 148 | \ 'W' : {'fnc' : 'WBW', 'direction' : 0}, 149 | \ 'B' : {'fnc' : 'WBW', 'direction' : 1}, 150 | \ 'bd-W' : {'fnc' : 'WBW', 'direction' : 2}, 151 | \ 'iskeyword-w' : {'fnc' : 'WBK', 'direction' : 0}, 152 | \ 'iskeyword-b' : {'fnc' : 'WBK', 'direction' : 1}, 153 | \ 'iskeyword-bd-w' : {'fnc' : 'WBK', 'direction' : 2}, 154 | \ 155 | \ 'e' : {'fnc' : 'E' , 'direction' : 0}, 156 | \ 'ge' : {'fnc' : 'E' , 'direction' : 1}, 157 | \ 'bd-e' : {'fnc' : 'E' , 'direction' : 2}, 158 | \ 'E' : {'fnc' : 'EW' , 'direction' : 0}, 159 | \ 'gE' : {'fnc' : 'EW' , 'direction' : 1}, 160 | \ 'bd-E' : {'fnc' : 'EW' , 'direction' : 2}, 161 | \ 'iskeyword-e' : {'fnc' : 'EK' , 'direction' : 0}, 162 | \ 'iskeyword-ge' : {'fnc' : 'EK' , 'direction' : 1}, 163 | \ 'iskeyword-bd-e' : {'fnc' : 'EK' , 'direction' : 2}, 164 | \ }) 165 | "}}} 166 | 167 | " -- JK Motion {{{ 168 | call s:motion_map_helper({ 169 | \ 'j' : {'fnc' : 'JK' , 'direction' : 0}, 170 | \ 'k' : {'fnc' : 'JK' , 'direction' : 1}, 171 | \ 'bd-jk' : {'fnc' : 'JK' , 'direction' : 2}, 172 | \ 'sol-j' : {'fnc' : 'Sol', 'direction' : 0}, 173 | \ 'sol-k' : {'fnc' : 'Sol', 'direction' : 1}, 174 | \ 'sol-bd-jk' : {'fnc' : 'Sol', 'direction' : 2}, 175 | \ 'eol-j' : {'fnc' : 'Eol', 'direction' : 0}, 176 | \ 'eol-k' : {'fnc' : 'Eol', 'direction' : 1}, 177 | \ 'eol-bd-jk' : {'fnc' : 'Eol', 'direction' : 2}, 178 | \ }) 179 | "}}} 180 | 181 | " -- Search Motion {{{ 182 | call s:motion_map_helper({ 183 | \ 'n' : {'fnc' : 'Search', 'direction': 0, 'respect_direction': 0}, 184 | \ 'N' : {'fnc' : 'Search', 'direction': 1, 'respect_direction': 0}, 185 | \ 'bd-n' : {'fnc' : 'Search', 'direction': 2, 'respect_direction': 0}, 186 | \ 'vim-n' : {'fnc' : 'Search', 'direction': 0, 'respect_direction': 1}, 187 | \ 'vim-N' : {'fnc' : 'Search', 'direction': 1, 'respect_direction': 1}, 188 | \ }) 189 | "}}} 190 | 191 | " -- Jump To Anywhere Motion {{{ 192 | call s:motion_map_helper({ 193 | \ 'jumptoanywhere' : {'fnc' : 'JumpToAnywhere', 'direction': 2}, 194 | \ }) 195 | "}}} 196 | 197 | " -- Line Motion {{{ 198 | call s:motion_map_helper({ 199 | \ 'wl' : {'fnc' : 'WBL', 'direction': 0}, 200 | \ 'bl' : {'fnc' : 'WBL', 'direction': 1}, 201 | \ 'bd-wl' : {'fnc' : 'WBL', 'direction': 2}, 202 | \ 'el' : {'fnc' : 'EL' , 'direction': 0}, 203 | \ 'gel' : {'fnc' : 'EL' , 'direction': 1}, 204 | \ 'bd-el' : {'fnc' : 'EL' , 'direction': 2}, 205 | \ 'lineforward' : {'fnc' : 'LineAnywhere', 'direction': 0}, 206 | \ 'linebackward' : {'fnc' : 'LineAnywhere', 'direction': 1}, 207 | \ 'lineanywhere' : {'fnc' : 'LineAnywhere', 'direction': 2}, 208 | \ }) 209 | "}}} 210 | 211 | " -- Next, Previous Motion {{{ 212 | noremap (easymotion-next) 213 | \ :call EasyMotion#NextPrevious(0,0) 214 | xnoremap (easymotion-next) 215 | \ :call EasyMotion#NextPrevious(1,0) 216 | 217 | noremap (easymotion-prev) 218 | \ :call EasyMotion#NextPrevious(0,1) 219 | xnoremap (easymotion-prev) 220 | \ :call EasyMotion#NextPrevious(1,1) 221 | "}}} 222 | 223 | " -- Repeat Motion {{{ 224 | noremap (easymotion-repeat) 225 | \ :call EasyMotion#Repeat(0) 226 | xnoremap (easymotion-repeat) 227 | \ :call EasyMotion#Repeat(1) 228 | 229 | noremap (easymotion-dotrepeat) 230 | \ :call EasyMotion#DotRepeat() 231 | "}}} 232 | 233 | noremap (easymotion-activate) :call EasyMotion#activate(0) 234 | xnoremap (easymotion-activate) :call EasyMotion#activate(1) 235 | " }}} 236 | 237 | " == Default key mapping {{{ 238 | if g:EasyMotion_do_mapping == 1 239 | " Prepare Prefix: {{{ 240 | if exists('g:EasyMotion_leader_key') 241 | exec 'map ' . g:EasyMotion_leader_key . ' (easymotion-prefix)' 242 | else 243 | if !hasmapto('(easymotion-prefix)') 244 | map (easymotion-prefix) 245 | endif 246 | endif 247 | "}}} 248 | 249 | function! s:default_mapping(motions, do_mapping) "{{{ 250 | for motion in a:motions 251 | " Mapping {{{ 252 | if exists('g:EasyMotion_mapping_' . motion) 253 | " Backward compatible mapping [deprecated] 254 | silent exec 'map ' . 255 | \ eval('g:EasyMotion_mapping_' . motion) . ' (easymotion-' . motion . ')' 256 | elseif a:do_mapping 257 | \ && !hasmapto('(easymotion-' . motion . ')') 258 | \ && empty(maparg('(easymotion-prefix)' . motion, 'nov')) 259 | 260 | " Do mapping 261 | silent exec 'map ' . 262 | \'(easymotion-prefix)' . motion . ' (easymotion-' . motion . ')' 263 | endif "}}} 264 | endfor 265 | endfunction "}}} 266 | 267 | " Default Mapping: 268 | call s:default_mapping( 269 | \ ['f', 'F', 's', 't', 'T', 270 | \ 'w', 'W', 'b', 'B', 'e', 'E', 'ge', 'gE', 271 | \ 'j', 'k', 'n', 'N'], g:EasyMotion_do_mapping) 272 | endif "}}} 273 | 274 | " == CommandLine Mapping {{{ 275 | command! -nargs=* 276 | \ EMCommandLineNoreMap 277 | \ call EasyMotion#command_line#cnoremap([]) 278 | command! -nargs=* 279 | \ EMCommandLineMap 280 | \ call EasyMotion#command_line#cmap([]) 281 | command! -nargs=1 282 | \ EMCommandLineUnMap 283 | \ call EasyMotion#command_line#cunmap() 284 | "}}} 285 | 286 | " == Restore 'cpoptions' {{{ 287 | let &cpo = s:save_cpo 288 | unlet s:save_cpo 289 | " }}} 290 | " vim: fdm=marker:et:ts=4:sw=4:sts=4 291 | -------------------------------------------------------------------------------- /t/compare_movements_spec.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " FILE: t/compare_movements_spec.vim 3 | " AUTHOR: YggdrasiI 4 | " Test: https://github.com/kana/vim-vspec 5 | " Description: EasyMotion keyword movement test with vim-vspec 6 | " License: MIT license {{{ 7 | " Permission is hereby granted, free of charge, to any person obtaining 8 | " a copy of this software and associated documentation files (the 9 | " "Software"), to deal in the Software without restriction, including 10 | " without limitation the rights to use, copy, modify, merge, publish, 11 | " distribute, sublicense, and/or sell copies of the Software, and to 12 | " permit persons to whom the Software is furnished to do so, subject to 13 | " the following conditions: 14 | " 15 | " The above copyright notice and this permission notice shall be included 16 | " in all copies or substantial portions of the Software. 17 | " 18 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | " }}} 26 | "============================================================================= 27 | 28 | " Setup {{{ 29 | let s:root_dir = matchstr(system('git rev-parse --show-cdup'), '[^\n]\+') 30 | 31 | " The consumed time depends from the length of the text and could be really high 32 | " on vimdoc pages. (See it 'Loop through Vim help buffer and compare movements') 33 | " Reduce this value to stop CompareMovements(...) before it reached the end of the 34 | " buffer. 35 | let s:maximal_number_of_compared_movments = 10000 36 | execute 'set' 'rtp +=./'.s:root_dir 37 | runtime! plugin/EasyMotion.vim 38 | " }}} 39 | 40 | " Functions for Test {{{ 41 | function! AddLine(str) 42 | put =a:str 43 | endfunction 44 | 45 | function! CursorPos() 46 | return [line('.'), col('.'), getline('.')[col('.')-1]] 47 | endfunction 48 | 49 | " Nested normal to avoid throwing readonly errors. They abort the testing. 50 | function TryNormal(str) 51 | try 52 | exec 'normal ' . a:str 53 | catch /^Vim\%((\a\+)\)\=:E21/ 54 | endtry 55 | return 0 56 | endfunction 57 | 58 | let s:to_cursor = {} 59 | function! s:to_cursor.match(actual, expected) 60 | return a:actual == a:expected 61 | endfunction 62 | 63 | " Add metadata about failure. 64 | function! s:to_cursor.failure_message_for_should(actual, expected) 65 | Expect a:actual[0] > 0 66 | Expect a:expected[0] > 0 67 | Expect a:actual[0] <= getpos('$')[1] 68 | Expect a:expected[0] <= getpos('$')[1] 69 | Expect a:actual[1] > 0 70 | Expect a:expected[1] > 0 71 | 72 | let line1 = getline(a:actual[0]) 73 | let line2 = getline(a:expected[0]) 74 | " Change char on cursor to '█'. 75 | let line1 = strpart(l:line1, 0, a:actual[1]-1) 76 | \ . '█' 77 | \ . strpart(l:line1, a:actual[1]) 78 | let line2 = strpart(l:line2, 0, a:expected[1]-1) 79 | \ . '█' 80 | \ . strpart(l:line2, a:expected[1]) 81 | " Separation of both cases with \n would be nice, but 82 | " vim-vspec allow oneliners as return string, only. 83 | let msg = 'Line ' . string(a:actual[0]) . ": '" . l:line1 84 | \ . "',\x09\x09 Line " . string(a:expected[0]) . ": '" . l:line2 . "'\x0a" 85 | return l:msg 86 | endfunction 87 | 88 | function! CompareMovements(movement1, movement2, backward) 89 | let jumpmarks = [ 90 | \ [a:movement1, []], 91 | \ [a:movement2, []], 92 | \ ] 93 | 94 | " Loop through current buffer in both variants {{ 95 | for [l:handler, l:list] in l:jumpmarks 96 | if a:backward == 1 97 | let last_line = line('$') 98 | let last_char = len(getline(l:last_line)) 99 | call cursor(l:last_line, l:last_char) 100 | else 101 | call cursor([1,1]) 102 | endif 103 | 104 | let lastpos = [0,0] 105 | 106 | " Centralize line. Otherwise, Easymotion functions aborts 107 | " at the end of the (virtual) window. 108 | call TryNormal('zz') 109 | call TryNormal(l:handler) 110 | let curpos = getpos(".")[1:2] 111 | 112 | while l:lastpos != l:curpos 113 | let list += [l:curpos] 114 | let lastpos = l:curpos 115 | call TryNormal('zz') 116 | call TryNormal(l:handler) 117 | let curpos = getpos(".")[1:2] 118 | " Abort after a fixed number of steps. 119 | if len(l:list) > s:maximal_number_of_compared_movments 120 | break 121 | endif 122 | endwhile 123 | endfor 124 | " }} 125 | 126 | " The resulting lists are stored in l:jumpmarks[*][1], now. 127 | let [l:cursor_positions1, l:cursor_positions2] = [ l:jumpmarks[0][1], l:jumpmarks[1][1] ] 128 | 129 | if l:cursor_positions1 == l:cursor_positions2 130 | return 0 131 | endif 132 | 133 | " Search for first unmatching position. {{ 134 | let index = 0 135 | let len = min([len(l:cursor_positions2), len(l:cursor_positions1)]) 136 | while l:index < l:len 137 | Expect l:cursor_positions2[l:index] to_cursor l:cursor_positions1[l:index] 138 | let index += 1 139 | endwhile 140 | 141 | " Collision with begin or end of file or while loop aborts to early. 142 | if a:backward == 1 143 | Expect join([a:movement2, ': File begin reached after ', len(l:cursor_positions2), ' steps.']) 144 | \ == join([a:movement1, ': File begin reached after ', len(l:cursor_positions1), ' steps.']) 145 | else 146 | Expect l:cursor_positions2[l:index-1] to_cursor l:cursor_positions1[l:index] 147 | Expect join([a:movement2, ': File end reached after ', len(l:cursor_positions2), ' steps.']) 148 | \ == join([a:movement1, ': File end reached after ', len(l:cursor_positions1), ' steps.']) 149 | endif 150 | " }} 151 | 152 | return -1 153 | endfunction 154 | 155 | " Hand crafted text with rare cases 156 | function! InsertTestText1() 157 | 158 | " Blanks at document begin 159 | call AddLine('') 160 | call AddLine(' ') 161 | call AddLine('') 162 | 163 | call AddLine('scriptencoding utf-8') 164 | 165 | " '^\s*[not-\k]'-case 166 | call AddLine('!foo') 167 | call AddLine(' !bar') 168 | 169 | call AddLine('s! ') 170 | 171 | " Blanks at document end 172 | call AddLine('') 173 | call AddLine(' ') 174 | call AddLine('') 175 | endfunction 176 | 177 | "}}} 178 | 179 | "Keyword word motion {{{ 180 | describe 'Keyword word motion' 181 | before 182 | new 183 | resize 10 184 | nmap a 185 | let g:EasyMotion_keys = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 186 | let g:EasyMotion_maximal_jumpmarks = 2 " Error for value 1 unanalyzed. 187 | nmap w (easymotion-iskeyword-w) 188 | nmap b (easymotion-iskeyword-b) 189 | nmap e (easymotion-iskeyword-e) 190 | nmap ge (easymotion-iskeyword-ge) 191 | nmap W (easymotion-W) 192 | nmap B (easymotion-B) 193 | nmap E (easymotion-E) 194 | nmap gE (easymotion-gE) 195 | call EasyMotion#init() 196 | call vspec#customize_matcher('to_cursor', s:to_cursor) 197 | end 198 | 199 | after 200 | close! 201 | end 202 | 203 | it 'Simple test to check setup of this test' 204 | " Check if a is remapped to to avoid start of insert mode. 205 | normal aa\ 206 | Expect getline(1) == '' 207 | 208 | call AddLine('word') 209 | Expect CompareMovements('w', 'w', 0) == 0 210 | Expect CompareMovements('w', '\wa', 0) == 0 211 | Expect CompareMovements('b', '\ba', 1) == 0 212 | Expect CompareMovements('e', '\ea', 0) == 0 213 | Expect CompareMovements('ge', '\gea', 1) == 0 214 | Expect CompareMovements('W', '\Wa', 0) == 0 215 | Expect CompareMovements('B', '\Ba', 1) == 0 216 | Expect CompareMovements('E', '\Ea', 0) == 0 217 | Expect CompareMovements('gE', '\gEa', 1) == 0 218 | end 219 | 220 | it 'w' 221 | call InsertTestText1() 222 | Expect CompareMovements('w', '\wa', 0) == 0 223 | end 224 | 225 | it 'b' 226 | call InsertTestText1() 227 | Expect CompareMovements('b', '\ba', 1) == 0 228 | end 229 | 230 | it 'e' 231 | call InsertTestText1() 232 | Expect CompareMovements('e', '\ea', 0) == 0 233 | end 234 | 235 | it 'ge' 236 | call InsertTestText1() 237 | Expect CompareMovements('ge', '\gea', 1) == 0 238 | end 239 | 240 | it 'W' 241 | call InsertTestText1() 242 | Expect CompareMovements('W', 'W', 0) == 0 243 | end 244 | 245 | it 'B' 246 | call InsertTestText1() 247 | Expect CompareMovements('B', 'B', 1) == 0 248 | end 249 | 250 | it 'E' 251 | call InsertTestText1() 252 | Expect CompareMovements('E', 'E', 0) == 0 253 | end 254 | 255 | it 'gE' 256 | call InsertTestText1() 257 | Expect CompareMovements('gE', 'gE', 1) == 0 258 | end 259 | 260 | " Really time consuming test... 261 | "it 'Loop through Vim help buffer and compare movements' 262 | " help motion.txt 263 | " Expect expand('%:t') ==# 'motion.txt' 264 | " "Optional: Copy text into editable buffer 265 | " exec "normal! Gygg\cP" 266 | " Expect CompareMovements('w', '\wa', 0) == 0 267 | "end 268 | 269 | end 270 | "}}} 271 | 272 | " __END__ {{{ 273 | " vim: fdm=marker:et:ts=4:sw=4:sts=4 274 | " }}} 275 | -------------------------------------------------------------------------------- /t/operator_pending_spec.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " FILE: t/operator_pending_spec.vim 3 | " AUTHOR: haya14busa 4 | " License: MIT license {{{ 5 | " Permission is hereby granted, free of charge, to any person obtaining 6 | " a copy of this software and associated documentation files (the 7 | " "Software"), to deal in the Software without restriction, including 8 | " without limitation the rights to use, copy, modify, merge, publish, 9 | " distribute, sublicense, and/or sell copies of the Software, and to 10 | " permit persons to whom the Software is furnished to do so, subject to 11 | " the following conditions: 12 | " 13 | " The above copyright notice and this permission notice shall be included 14 | " in all copies or substantial portions of the Software. 15 | " 16 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | " }}} 24 | "============================================================================= 25 | 26 | " Avoid source test files {{{ 27 | if expand("%:p") ==# expand(":p") 28 | finish 29 | endif 30 | "}}} 31 | 32 | " Setup {{{ 33 | let s:root_dir = matchstr(system('git rev-parse --show-cdup'), '[^\n]\+') 34 | execute 'set' 'rtp +=./'.s:root_dir 35 | runtime! plugin/EasyMotion.vim 36 | "}}} 37 | 38 | " Functions for Test {{{ 39 | function! AddLine(str) 40 | put! =a:str 41 | endfunction 42 | 43 | function! CursorPos() 44 | return [line('.'), col('.'), getline('.')[col('.')-1]] 45 | endfunction 46 | "}}} 47 | 48 | 49 | " NOTE: 50 | " I cannot test inclusive motion because mode() doesn't works well with 51 | " vim-vspec 52 | 53 | " word motions {{{ 54 | describe 'word motions' 55 | before 56 | new 57 | let g:EasyMotion_keys = '123456789' 58 | omap f (easymotion-f) 59 | omap w (easymotion-w) 60 | omap b (easymotion-b) 61 | call EasyMotion#init() 62 | call AddLine('vim deco vim deco vim deco') 63 | " 123456789012345678901234567890 64 | end 65 | 66 | after 67 | close! 68 | end 69 | 70 | it '(easymotion-w)' 71 | " Default position 72 | normal! 0 73 | let l = line('.') 74 | Expect CursorPos() == [l,1,'v'] 75 | 76 | normal dw1 77 | Expect CursorPos() == [l,1,'d'] 78 | normal! u 79 | normal! 0 80 | Expect CursorPos() == [l,1,'v'] 81 | 82 | normal dw2 83 | Expect CursorPos() == [l,1,'v'] 84 | normal! 0 85 | normal! u 86 | normal! 0 87 | Expect CursorPos() == [l,1,'v'] 88 | end 89 | 90 | it '(easymotion-b)' 91 | " Default position 92 | normal! $ 93 | let l = line('.') 94 | Expect CursorPos() == [l,26,'o'] 95 | 96 | normal db1 97 | Expect CursorPos() == [l,23,'o'] 98 | normal! u 99 | normal! $ 100 | Expect CursorPos() == [l,26,'o'] 101 | 102 | normal db2 103 | Expect CursorPos() == [l,19,'o'] 104 | normal! u 105 | normal! $ 106 | Expect CursorPos() == [l,26,'o'] 107 | end 108 | end 109 | "}}} 110 | 111 | --------------------------------------------------------------------------------