added easymotion
This commit is contained in:
parent
b7a7348736
commit
d1be1a7aab
60 changed files with 13052 additions and 0 deletions
4
sources_non_forked/vim-easymotion/.gitignore
vendored
Normal file
4
sources_non_forked/vim-easymotion/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
doc/tags
|
||||
tmp*
|
||||
*.lock
|
||||
.vim-flavor
|
15
sources_non_forked/vim-easymotion/.travis.yml
Normal file
15
sources_non_forked/vim-easymotion/.travis.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
language: ruby
|
||||
rvm:
|
||||
- 2.0.0
|
||||
install:
|
||||
- git clone https://github.com/kana/vim-vspec.git
|
||||
- pip install vim-vint --user
|
||||
- go env
|
||||
- go get -u github.com/haya14busa/reviewdog/cmd/reviewdog
|
||||
before_script:
|
||||
- bundle install
|
||||
- bundle show
|
||||
script:
|
||||
- >-
|
||||
vint plugin autoload/EasyMotion.vim autoload/EasyMotion/ | reviewdog -name=vint -efm="%f:%l:%c: %m" -reporter=github-pr-check
|
||||
- rake ci
|
4
sources_non_forked/vim-easymotion/Gemfile
Normal file
4
sources_non_forked/vim-easymotion/Gemfile
Normal file
|
@ -0,0 +1,4 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'vim-flavor', '~> 1.1'
|
||||
gem 'rake'
|
395
sources_non_forked/vim-easymotion/README.md
Normal file
395
sources_non_forked/vim-easymotion/README.md
Normal file
|
@ -0,0 +1,395 @@
|
|||
Vim motion on speed!
|
||||
=====
|
||||
[![Build Status](https://travis-ci.org/easymotion/vim-easymotion.svg?branch=master)](https://travis-ci.org/easymotion/vim-easymotion)
|
||||
|
||||
![Animated demonstration](https://f.cloud.github.com/assets/3797062/2039359/a8e938d6-899f-11e3-8789-60025ea83656.gif)
|
||||
|
||||
About the authors
|
||||
=====
|
||||
|
||||
| Authors | |
|
||||
|------------------|-------------------------------|
|
||||
| Kim Silkebækken | https://github.com/Lokaltog |
|
||||
| haya14busa | https://github.com/haya14busa |
|
||||
|
||||
The EasyMotion project, revived!
|
||||
======
|
||||
|
||||
Starting from version 2.0 [haya14busa](https://github.com/haya14busa) will be
|
||||
taking over the project from [Lokaltog](https://github.com/Lokaltog). He's
|
||||
improved the default motions, implemented many useful new features, and fixed
|
||||
some bugs.
|
||||
|
||||
EasyMotion is now completely:
|
||||
|
||||
- **Well-behaved**: It's consistent with the default motions of Vim and works
|
||||
well in all modes. And it now supports repeating with the dot operator.
|
||||
- **Configurable**: You can easily configure its behavior and map it to any key
|
||||
- **Sophisticated**: Provide flawless, smooth and fast motions with minimal keystrokes
|
||||
|
||||
Even though some default behaviors were modified and many new features were
|
||||
added, I carefully considered backward compatibility. So those of you updating
|
||||
from older versions can do so without worry and start benefiting immediately
|
||||
from all the new features!
|
||||
|
||||
Introduction
|
||||
=====
|
||||
|
||||
EasyMotion provides a much simpler way to use some motions in vim. It
|
||||
takes the `<number>` out of `<number>w` or `<number>f{char}` by
|
||||
highlighting all possible choices and allowing you to press one key to
|
||||
jump directly to the target.
|
||||
|
||||
When one of the available motions is triggered, all visible text
|
||||
preceding or following the cursor is faded, and motion targets are
|
||||
highlighted.
|
||||
|
||||
EasyMotion is triggered by the provided mappings. This readme only covers the
|
||||
basics; please refer to
|
||||
[`:help easymotion.txt`](https://github.com/easymotion/vim-easymotion/blob/master/doc/easymotion.txt#L86)
|
||||
to see all the available mappings.
|
||||
|
||||
Important notes
|
||||
=====
|
||||
|
||||
### Default bindings
|
||||
|
||||
**The default leader has been changed to `<Leader><Leader>` to avoid
|
||||
conflicts with other plugins you may have installed.** This can easily be
|
||||
changed back to pre-1.3 behavior by rebinding the leader in your vimrc:
|
||||
|
||||
```vim
|
||||
map <Leader> <Plug>(easymotion-prefix)
|
||||
```
|
||||
|
||||
All motions will then be triggered with `<Leader>` by default, e.g.
|
||||
`<Leader>s`, `<Leader>gE`.
|
||||
|
||||
### For users of the forked version
|
||||
|
||||
SelectLines and SelectPhrase are not actually *motions*, so I've moved them into
|
||||
separate plugins.
|
||||
|
||||
- https://github.com/haya14busa/vim-easyoperator-line
|
||||
- https://github.com/haya14busa/vim-easyoperator-phrase
|
||||
|
||||
Usage example for the base features
|
||||
=====
|
||||
|
||||
<cursor>Lorem ipsum dolor sit amet.
|
||||
|
||||
Type `<Leader><Leader>w`(`<Plug>(easymotion-w)`) to trigger the word motion `w`.
|
||||
When the motion is triggered, the text is updated (no braces are actually added,
|
||||
the text is highlighted in red by default):
|
||||
|
||||
<cursor>Lorem {a}psum {b}olor {c}it {d}met.
|
||||
|
||||
Press `c` to jump to the beginning of the word "sit":
|
||||
|
||||
Lorem ipsum dolor <cursor>sit amet.
|
||||
|
||||
Similarly, if you're looking for an "o", you can use the `f` motion.
|
||||
Type `<Leader><Leader>fo`, and all "o" characters are highlighted:
|
||||
|
||||
<cursor>L{a}rem ipsum d{b}l{c}r sit amet.
|
||||
|
||||
Press `b` to jump to the second "o":
|
||||
|
||||
Lorem ipsum d<cursor>olor sit amet.
|
||||
|
||||
Jeffrey Way of Nettuts+ has also [written
|
||||
a tutorial](http://net.tutsplus.com/tutorials/other/vim-essential-plugin-easymotion/)
|
||||
about EasyMotion.
|
||||
|
||||
New features in version 3.0
|
||||
====
|
||||
|
||||
### Overwin motions
|
||||
![](https://raw.githubusercontent.com/haya14busa/i/2753bd4dd1dfdf5962dbdbffabf24244e4e14243/easymotion/overwin-motions.gif)
|
||||
|
||||
EasyMotion now supports moving cursor across/over window.
|
||||
Since it doesn't make sense that moving cursor to other window while Visual or
|
||||
Operator-pending mode, overwin motions only provides mappings for Normal
|
||||
mode. Please use `nmap` to use overwin motions. Overwin motions only
|
||||
supports bi-directional motions.
|
||||
|
||||
#### Example configuration
|
||||
|
||||
```vim
|
||||
" <Leader>f{char} to move to {char}
|
||||
map <Leader>f <Plug>(easymotion-bd-f)
|
||||
nmap <Leader>f <Plug>(easymotion-overwin-f)
|
||||
|
||||
" s{char}{char} to move to {char}{char}
|
||||
nmap s <Plug>(easymotion-overwin-f2)
|
||||
|
||||
" Move to line
|
||||
map <Leader>L <Plug>(easymotion-bd-jk)
|
||||
nmap <Leader>L <Plug>(easymotion-overwin-line)
|
||||
|
||||
" Move to word
|
||||
map <Leader>w <Plug>(easymotion-bd-w)
|
||||
nmap <Leader>w <Plug>(easymotion-overwin-w)
|
||||
```
|
||||
|
||||
#### Integration with incsearch.vim
|
||||
- [haya14busa/incsearch.vim](https://github.com/haya14busa/incsearch.vim)
|
||||
- [haya14busa/incsearch-easymotion.vim](https://github.com/haya14busa/incsearch-easymotion.vim)
|
||||
|
||||
```vim
|
||||
" You can use other keymappings like <C-l> instead of <CR> if you want to
|
||||
" use these mappings as default search and sometimes want to move cursor with
|
||||
" EasyMotion.
|
||||
function! s:incsearch_config(...) abort
|
||||
return incsearch#util#deepextend(deepcopy({
|
||||
\ 'modules': [incsearch#config#easymotion#module({'overwin': 1})],
|
||||
\ 'keymap': {
|
||||
\ "\<CR>": '<Over>(easymotion)'
|
||||
\ },
|
||||
\ 'is_expr': 0
|
||||
\ }), get(a:, 1, {}))
|
||||
endfunction
|
||||
|
||||
noremap <silent><expr> / incsearch#go(<SID>incsearch_config())
|
||||
noremap <silent><expr> ? incsearch#go(<SID>incsearch_config({'command': '?'}))
|
||||
noremap <silent><expr> g/ incsearch#go(<SID>incsearch_config({'is_stay': 1}))
|
||||
```
|
||||
|
||||
### Bonus fuzzy-search with EasyMotion
|
||||
|
||||
![](https://raw.githubusercontent.com/haya14busa/i/eab1d12a8bd322223d551956a4fd8a21d5c4bfe9/easymotion/fuzzy-incsearch-easymotion.gif)
|
||||
|
||||
- [haya14busa/incsearch.vim](https://github.com/haya14busa/incsearch.vim)
|
||||
- [haya14busa/incsearch-fuzzy.vim](https://github.com/haya14busa/incsearch-fuzzy.vim)
|
||||
- [haya14busa/incsearch-easymotion.vim](https://github.com/haya14busa/incsearch-easymotion.vim)
|
||||
|
||||
```vim
|
||||
function! s:config_easyfuzzymotion(...) abort
|
||||
return extend(copy({
|
||||
\ 'converters': [incsearch#config#fuzzyword#converter()],
|
||||
\ 'modules': [incsearch#config#easymotion#module({'overwin': 1})],
|
||||
\ 'keymap': {"\<CR>": '<Over>(easymotion)'},
|
||||
\ 'is_expr': 0,
|
||||
\ 'is_stay': 1
|
||||
\ }), get(a:, 1, {}))
|
||||
endfunction
|
||||
|
||||
noremap <silent><expr> <Space>/ incsearch#go(<SID>config_easyfuzzymotion())
|
||||
```
|
||||
|
||||
New features in version 2.0
|
||||
====
|
||||
|
||||
### Two key highlighting
|
||||
|
||||
When EasyMotion runs out of single characters to highlight movement targets, it
|
||||
immediately shows you the keys you have to press.
|
||||
|
||||
In previous versions you could not see the next character you would need to
|
||||
press until you entered the first one. This made movement over long distances
|
||||
less fluid. Now you can see at a glance exactly which characters to select to
|
||||
get to your destination.
|
||||
|
||||
### Bidirectional motions
|
||||
|
||||
All motions now come in a bidirectional variants (e.g. `<Plug>(easymotion-s)`,
|
||||
`<Plug>(easymotion-bd-w)` and so forth).
|
||||
By default, you can already jump forward or backward with `<Leader>s`. A useful
|
||||
trick is to map `nmap s <Plug>(easymotion-s)` to use `s` instead and save one
|
||||
keystroke!
|
||||
|
||||
### 2-character search motion
|
||||
|
||||
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 `<Plug>(easymotion-s2)`. For example you can highlight all words that start with `fu`.
|
||||
|
||||
![2-key-find-motion](https://f.cloud.github.com/assets/3797062/2039612/7cafcec8-89a5-11e3-8f2c-5f26a6b83efd.gif)
|
||||
|
||||
```vim
|
||||
" Gif config
|
||||
nmap s <Plug>(easymotion-s2)
|
||||
nmap t <Plug>(easymotion-t2)
|
||||
```
|
||||
|
||||
### n-character search motion
|
||||
|
||||
You can also search for `n` characters, which can be used to replace the default search of Vim.
|
||||
It supports incremental highlighting and you can use `<Tab>` and `<S-Tab>` to scroll down/up a page. If you press
|
||||
`<CR>`, you get the usual EasyMotion highlighting and can jump to any matching target destination with a
|
||||
single keystroke.
|
||||
|
||||
What sounds complicated should become clear if you look at the following examples.
|
||||
|
||||
![n-key-motion-scroll](https://f.cloud.github.com/assets/3797062/2039254/4fbf7276-899e-11e3-9bf3-1e446cabc097.gif)
|
||||
|
||||
![replace-search](https://f.cloud.github.com/assets/3797062/2039751/64b72bd8-89a8-11e3-80ea-2a6b578040b2.gif)
|
||||
|
||||
```vim
|
||||
" Gif config
|
||||
map / <Plug>(easymotion-sn)
|
||||
omap / <Plug>(easymotion-tn)
|
||||
|
||||
" These `n` & `N` mappings are options. You do not have to map `n` & `N` to EasyMotion.
|
||||
" Without these mappings, `n` & `N` works fine. (These mappings just provide
|
||||
" different highlight method and have some other features )
|
||||
map n <Plug>(easymotion-next)
|
||||
map N <Plug>(easymotion-prev)
|
||||
```
|
||||
|
||||
### Within line motion
|
||||
|
||||
Every motion also has variants that are restricted to just the current line
|
||||
(e.g. `<Plug>(easymotion-sl)`, `<Plug>(easymotion-bd-wl)`, etc...). This can be
|
||||
helpful if you find the full search distracting or slows down vim.
|
||||
|
||||
### hjkl motions
|
||||
|
||||
EasyMotion can be configured to avoid repetitive use of the `h` `j` `k` and
|
||||
`l` keys.
|
||||
|
||||
![hjkl-motion](https://f.cloud.github.com/assets/3797062/2039413/d8b32ab2-89a0-11e3-894f-3e81db084cfd.gif)
|
||||
|
||||
```vim
|
||||
" Gif config
|
||||
map <Leader>l <Plug>(easymotion-lineforward)
|
||||
map <Leader>j <Plug>(easymotion-j)
|
||||
map <Leader>k <Plug>(easymotion-k)
|
||||
map <Leader>h <Plug>(easymotion-linebackward)
|
||||
|
||||
let g:EasyMotion_startofline = 0 " keep cursor column when JK motion
|
||||
```
|
||||
|
||||
### Smartcase & Smartsign
|
||||
|
||||
This setting makes EasyMotion work similarly to Vim's `smartcase` option for
|
||||
global searches.
|
||||
|
||||
```vim
|
||||
let g:EasyMotion_smartcase = 1
|
||||
```
|
||||
|
||||
With this option set, `v` will match both `v` and `V`, but `V` will match `V`
|
||||
only. Default: 0.
|
||||
|
||||
```vim
|
||||
let g:EasyMotion_use_smartsign_us = 1 " US layout
|
||||
" or
|
||||
let g:EasyMotion_use_smartsign_jp = 1 " JP layout
|
||||
```
|
||||
|
||||
This applies the same concept, but for symbols and numerals. `1` will match `1`
|
||||
and `!`; `!` matches `!` only. Default: 0.
|
||||
|
||||
|
||||
### Migemo feature (for Japanese user)
|
||||
|
||||
```vim
|
||||
let g:EasyMotion_use_migemo = 1
|
||||
```
|
||||
|
||||
|
||||
Easymotion can match multibyte Japanese characters with alphabetical input.
|
||||
For example, `<Leader><Leader>sa` can search 'あ'.
|
||||
This feature doesn't require cmigemo because Easymotion includes regex
|
||||
patterns generated by cmigemo. However, installing `cmigemo` will make
|
||||
2-character and n-character search motions to also support the migemo feature.
|
||||
Default:0
|
||||
|
||||
|
||||
### Repeat motions
|
||||
|
||||
#### Repeat the last motion
|
||||
|
||||
`<Plug>(easymotion-repeat)`
|
||||
|
||||
#### Repeat the last find motion
|
||||
|
||||
In a find motion (e.g. `<Plug>(easymotion-s)`), type `<CR>` without
|
||||
input characters to find the last motion again.
|
||||
|
||||
#### Jump to next/previous match (even on next/previous page)
|
||||
|
||||
* `<Plug>(easymotion-next)`
|
||||
* `<Plug>(easymotion-prev)`
|
||||
|
||||
#### Support for dot repeat
|
||||
|
||||
This requires https://github.com/tpope/vim-repeat.
|
||||
|
||||
You can use EasyMotion with operators and press `.` to repeat!
|
||||
It is well-behaved and consistent with the default behavior of Vim.
|
||||
|
||||
![repeat-motion](https://f.cloud.github.com/assets/3797062/2039538/0aef66aa-89a4-11e3-8242-c27a5208cfca.gif)
|
||||
|
||||
```vim
|
||||
" Gif config
|
||||
|
||||
" Require tpope/vim-repeat to enable dot repeat support
|
||||
" Jump to anywhere with only `s{char}{target}`
|
||||
" `s<CR>` repeat last find motion.
|
||||
nmap s <Plug>(easymotion-s)
|
||||
" Bidirectional & within line 't' motion
|
||||
omap t <Plug>(easymotion-bd-tl)
|
||||
" Use uppercase target labels and type as a lower case
|
||||
let g:EasyMotion_use_upper = 1
|
||||
" type `l` and match `l`&`L`
|
||||
let g:EasyMotion_smartcase = 1
|
||||
" Smartsign (type `3` and match `3`&`#`)
|
||||
let g:EasyMotion_use_smartsign_us = 1
|
||||
```
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
### Pathogen (https://github.com/tpope/vim-pathogen)
|
||||
```
|
||||
git clone https://github.com/easymotion/vim-easymotion ~/.vim/bundle/vim-easymotion
|
||||
```
|
||||
|
||||
### Vundle (https://github.com/gmarik/vundle)
|
||||
```
|
||||
Plugin 'easymotion/vim-easymotion'
|
||||
```
|
||||
|
||||
### NeoBundle (https://github.com/Shougo/neobundle.vim)
|
||||
```
|
||||
NeoBundle 'easymotion/vim-easymotion'
|
||||
```
|
||||
|
||||
Minimal Configuration Tutorial
|
||||
------------------------------
|
||||
**I recommend configuring and map keys by yourself if you are true Vimmer.**
|
||||
|
||||
**Please do not be satisfied with just installing vim-easymotion, configuring it yourself boost your productivity more and more!**
|
||||
|
||||
Default `<Leader><Leader>` prefix isn't easy to press, and I leave them just for backwards compatibility.
|
||||
You should at least change the prefix key like this `map <Leader> <Plug>(easymotion-prefix)`
|
||||
|
||||
Minimal but useful vimrc example:
|
||||
|
||||
```vim
|
||||
let g:EasyMotion_do_mapping = 0 " Disable default mappings
|
||||
|
||||
" Jump to anywhere you want with minimal keystrokes, with just one key binding.
|
||||
" `s{char}{label}`
|
||||
nmap s <Plug>(easymotion-overwin-f)
|
||||
" or
|
||||
" `s{char}{char}{label}`
|
||||
" Need one more keystroke, but on average, it may be more comfortable.
|
||||
nmap s <Plug>(easymotion-overwin-f2)
|
||||
|
||||
" Turn on case-insensitive feature
|
||||
let g:EasyMotion_smartcase = 1
|
||||
|
||||
" JK motions: Line motions
|
||||
map <Leader>j <Plug>(easymotion-j)
|
||||
map <Leader>k <Plug>(easymotion-k)
|
||||
```
|
||||
Now, all you need to remember is `s` and JK motions bindings, and it's good enough to boost your cursor speed!
|
||||
|
||||
**`s`** is bidirectional find motion, you can move to anywhere with it.
|
||||
|
||||
**`<Leader>j`** & **`<Leader>k`** make it easy to move to the lines.
|
||||
|
||||
Of course you can use any key you want instead of `s` such as `<Space>`, `<Leader>s`, etc...
|
||||
|
||||
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.
|
11
sources_non_forked/vim-easymotion/Rakefile
Normal file
11
sources_non_forked/vim-easymotion/Rakefile
Normal file
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env rake
|
||||
|
||||
task :ci => [:dump, :test]
|
||||
|
||||
task :dump do
|
||||
sh 'vim --version'
|
||||
end
|
||||
|
||||
task :test do
|
||||
sh 'bundle exec vim-flavor test'
|
||||
end
|
1604
sources_non_forked/vim-easymotion/autoload/EasyMotion.vim
Normal file
1604
sources_non_forked/vim-easymotion/autoload/EasyMotion.vim
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,117 @@
|
|||
"=============================================================================
|
||||
" FILE: autoload/EasyMotion/cmigemo.vim
|
||||
" AUTHOR: haya14busa
|
||||
" License: MIT license {{{
|
||||
" Permission is hereby granted, free of charge, to any person obtaining
|
||||
" a copy of this software and associated documentation files (the
|
||||
" "Software"), to deal in the Software without restriction, including
|
||||
" without limitation the rights to use, copy, modify, merge, publish,
|
||||
" distribute, sublicense, and/or sell copies of the Software, and to
|
||||
" permit persons to whom the Software is furnished to do so, subject to
|
||||
" the following conditions:
|
||||
"
|
||||
" The above copyright notice and this permission notice shall be included
|
||||
" in all copies or substantial portions of the Software.
|
||||
"
|
||||
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
scriptencoding utf-8
|
||||
" Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
|
||||
function! s:has_vimproc() "{{{
|
||||
if !exists('s:exists_vimproc')
|
||||
try
|
||||
silent call vimproc#version()
|
||||
let s:exists_vimproc = 1
|
||||
catch
|
||||
let s:exists_vimproc = 0
|
||||
endtry
|
||||
endif
|
||||
|
||||
return s:exists_vimproc
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#cmigemo#system(...) "{{{
|
||||
return call(s:has_vimproc() ? 'vimproc#system' : 'system', a:000)
|
||||
endfunction "}}}
|
||||
|
||||
function! s:SearchDict2(name) "{{{
|
||||
let path = $VIM . ',' . &runtimepath
|
||||
let dict = globpath(path, "dict/".a:name)
|
||||
if dict == ''
|
||||
let dict = globpath(path, a:name)
|
||||
endif
|
||||
if dict == ''
|
||||
for path in [
|
||||
\ '/usr/local/share/migemo/',
|
||||
\ '/usr/local/share/cmigemo/',
|
||||
\ '/usr/local/share/',
|
||||
\ '/usr/share/cmigemo/',
|
||||
\ '/usr/share/',
|
||||
\ ]
|
||||
let path = path . a:name
|
||||
if filereadable(path)
|
||||
let dict = path
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
let dict = matchstr(dict, "^[^\<NL>]*")
|
||||
return dict
|
||||
endfunction "}}}
|
||||
|
||||
function! s:SearchDict() "{{{
|
||||
for path in [
|
||||
\ 'migemo/'.&encoding.'/migemo-dict',
|
||||
\ &encoding.'/migemo-dict',
|
||||
\ 'migemo-dict',
|
||||
\ ]
|
||||
let dict = s:SearchDict2(path)
|
||||
if dict != ''
|
||||
return dict
|
||||
endif
|
||||
endfor
|
||||
echoerr 'a dictionary for migemo is not found'
|
||||
echoerr 'your encoding is '.&encoding
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#cmigemo#getMigemoPattern(input) "{{{
|
||||
if !exists('s:migemodict')
|
||||
let s:migemodict = s:SearchDict()
|
||||
endif
|
||||
|
||||
if has('migemo')
|
||||
" Use migemo().
|
||||
if &migemodict !=# ''
|
||||
return migemo(a:input)
|
||||
endif
|
||||
let &migemodict = s:migemodict
|
||||
try
|
||||
return migemo(a:input)
|
||||
finally
|
||||
let &migemodict = ''
|
||||
endtry
|
||||
elseif executable('cmigemo')
|
||||
" Use cmigemo.
|
||||
return EasyMotion#cmigemo#system('cmigemo -v -w "'.a:input.'" -d "'.s:migemodict.'"')
|
||||
else
|
||||
" Not supported
|
||||
return a:input
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" vim: fdm=marker:et:ts=4:sw=4:sts=4
|
|
@ -0,0 +1,283 @@
|
|||
"=============================================================================
|
||||
" FILE: autoload/EasyMotion/command_line.vim
|
||||
" AUTHOR: haya14busa
|
||||
" Reference: https://github.com/osyo-manga/vim-over
|
||||
" License: MIT license {{{
|
||||
" Permission is hereby granted, free of charge, to any person obtaining
|
||||
" a copy of this software and associated documentation files (the
|
||||
" "Software"), to deal in the Software without restriction, including
|
||||
" without limitation the rights to use, copy, modify, merge, publish,
|
||||
" distribute, sublicense, and/or sell copies of the Software, and to
|
||||
" permit persons to whom the Software is furnished to do so, subject to
|
||||
" the following conditions:
|
||||
"
|
||||
" The above copyright notice and this permission notice shall be included
|
||||
" in all copies or substantial portions of the Software.
|
||||
"
|
||||
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
scriptencoding utf-8
|
||||
" Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
|
||||
" CommandLine:
|
||||
let s:V = vital#easymotion#new()
|
||||
let s:cmdline = s:V.import('Over.Commandline.Base')
|
||||
let s:modules = s:V.import("Over.Commandline.Modules")
|
||||
let s:search = s:cmdline.make()
|
||||
let s:search.highlights.prompt = 'Question'
|
||||
|
||||
" Add Module: {{{
|
||||
call s:search.connect('Exit')
|
||||
call s:search.connect('Cancel')
|
||||
call s:search.connect('Redraw')
|
||||
call s:search.connect('DrawCommandline')
|
||||
call s:search.connect('Delete')
|
||||
call s:search.connect('CursorMove')
|
||||
call s:search.connect('Paste')
|
||||
call s:search.connect('BufferComplete')
|
||||
call s:search.connect('InsertRegister')
|
||||
call s:search.connect('ExceptionExit')
|
||||
call s:search.connect(s:modules.get('ExceptionMessage').make('EasyMotion: ', 'echom'))
|
||||
call s:search.connect(s:modules.get('History').make('/'))
|
||||
call s:search.connect(s:modules.get('NoInsert').make_special_chars())
|
||||
call s:search.connect(s:modules.get('KeyMapping').make_emacs())
|
||||
call s:search.connect(s:modules.get('Doautocmd').make('EMCommandLine'))
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "EasyMotion",
|
||||
\}
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("<Over>(em-scroll-f)")
|
||||
call s:scroll(0)
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(em-scroll-b)")
|
||||
call s:scroll(1)
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(em-jumpback)")
|
||||
keepjumps call setpos('.', s:save_orig_pos)
|
||||
let s:orig_pos = s:save_orig_pos
|
||||
let s:orig_line_start = getpos('w0')
|
||||
let s:orig_line_end = getpos('w$')
|
||||
let s:direction = s:save_direction
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(em-openallfold)")
|
||||
" TODO: better solution
|
||||
normal! zR
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
endfunction
|
||||
call s:search.connect(s:module)
|
||||
"}}}
|
||||
|
||||
" CommandLine Keymap: {{{
|
||||
" .keymapping() won't be remapped by user defined KeyMappings.
|
||||
function! s:search.keymapping() "{{{
|
||||
return {
|
||||
\ "\<CR>" : {
|
||||
\ "key" : "<Over>(exit)",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ }
|
||||
endfunction "}}}
|
||||
|
||||
call s:search.cnoremap("\<C-l>", '<Over>(buffer-complete)')
|
||||
call s:search.cnoremap("\<Tab>", '<Over>(em-scroll-f)')
|
||||
call s:search.cnoremap("\<S-Tab>", '<Over>(em-scroll-b)')
|
||||
call s:search.cnoremap("\<C-o>", '<Over>(em-jumpback)')
|
||||
call s:search.cnoremap("\<C-z>", '<Over>(em-openallfold)')
|
||||
|
||||
" Fins Motion CommandLine Mapping Command: {{{
|
||||
function! EasyMotion#command_line#cmap(args)
|
||||
let lhs = s:as_keymapping(a:args[0])
|
||||
let rhs = s:as_keymapping(a:args[1])
|
||||
call s:search.cmap(lhs, rhs)
|
||||
endfunction
|
||||
function! EasyMotion#command_line#cnoremap(args)
|
||||
let lhs = s:as_keymapping(a:args[0])
|
||||
let rhs = s:as_keymapping(a:args[1])
|
||||
call s:search.cnoremap(lhs, rhs)
|
||||
endfunction
|
||||
function! EasyMotion#command_line#cunmap(lhs)
|
||||
let lhs = s:as_keymapping(a:lhs)
|
||||
call s:search.cunmap(lhs)
|
||||
endfunction
|
||||
function! s:as_keymapping(key)
|
||||
execute 'let result = "' . substitute(a:key, '\(<.\{-}>\)', '\\\1', 'g') . '"'
|
||||
return result
|
||||
endfunction
|
||||
"}}}
|
||||
"}}}
|
||||
|
||||
" Event: {{{
|
||||
function! s:search.on_enter(cmdline) "{{{
|
||||
if s:num_strokes == -1
|
||||
call EasyMotion#highlight#delete_highlight()
|
||||
call EasyMotion#helper#VarReset('&scrolloff', 0)
|
||||
if g:EasyMotion_do_shade
|
||||
call EasyMotion#highlight#add_highlight('\_.*',
|
||||
\ g:EasyMotion_hl_group_shade)
|
||||
endif
|
||||
endif
|
||||
if g:EasyMotion_cursor_highlight
|
||||
call EasyMotion#highlight#add_highlight('\%#',
|
||||
\ g:EasyMotion_hl_inc_cursor)
|
||||
endif
|
||||
endfunction "}}}
|
||||
function! s:search.on_leave(cmdline) "{{{
|
||||
if s:num_strokes == -1
|
||||
call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search)
|
||||
if g:EasyMotion_do_shade
|
||||
call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_group_shade)
|
||||
endif
|
||||
endif
|
||||
if g:EasyMotion_cursor_highlight
|
||||
call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_cursor)
|
||||
endif
|
||||
endfunction "}}}
|
||||
function! s:search.on_char(cmdline) "{{{
|
||||
if s:num_strokes == -1
|
||||
let re = s:search.getline()
|
||||
if EasyMotion#helper#should_case_sensitive(re, 1)
|
||||
let case_flag = '\c'
|
||||
else
|
||||
let case_flag = '\C'
|
||||
endif
|
||||
let re .= case_flag
|
||||
if g:EasyMotion_inc_highlight
|
||||
call s:inc_highlight(re)
|
||||
endif
|
||||
if g:EasyMotion_off_screen_search
|
||||
call s:off_screen_search(re)
|
||||
endif
|
||||
elseif s:search.line.length() >= s:num_strokes
|
||||
call s:search.exit()
|
||||
endif
|
||||
endfunction "}}}
|
||||
"}}}
|
||||
|
||||
" Main:
|
||||
function! EasyMotion#command_line#GetInput(num_strokes, prev, direction) "{{{
|
||||
let s:num_strokes = a:num_strokes
|
||||
|
||||
let s:prompt_base = s:getPromptMessage(a:num_strokes)
|
||||
call s:search.set_prompt(s:prompt_base)
|
||||
|
||||
" Screen: cursor position, first and last line
|
||||
let s:orig_pos = getpos('.')
|
||||
let s:orig_line_start = getpos('w0')
|
||||
let s:orig_line_end = getpos('w$')
|
||||
let s:save_orig_pos = deepcopy(s:orig_pos)
|
||||
|
||||
" Direction:
|
||||
let s:direction = a:direction == 1 ? 'b' : ''
|
||||
let s:save_direction = deepcopy(s:direction)
|
||||
|
||||
let input = s:search.get()
|
||||
if input == '' && ! s:search.exit_code()
|
||||
return a:prev
|
||||
elseif s:search.exit_code() == 1 || s:search.exit_code() == -1
|
||||
call s:Cancell()
|
||||
return ''
|
||||
else
|
||||
return input
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" Helper:
|
||||
function! s:Cancell() " {{{
|
||||
call EasyMotion#highlight#delete_highlight()
|
||||
call EasyMotion#helper#VarReset('&scrolloff')
|
||||
keepjumps call setpos('.', s:save_orig_pos)
|
||||
if g:EasyMotion_verbose
|
||||
echo 'EasyMotion: Cancelled'
|
||||
endif
|
||||
return ''
|
||||
endfunction " }}}
|
||||
function! s:getPromptMessage(num_strokes) "{{{
|
||||
if a:num_strokes == 1
|
||||
let prompt = substitute(
|
||||
\ substitute(g:EasyMotion_prompt,'{n}', a:num_strokes, 'g'),
|
||||
\ '(s)', '', 'g')
|
||||
elseif a:num_strokes == -1
|
||||
let prompt = substitute(
|
||||
\ substitute(g:EasyMotion_prompt, '{n}\s\{0,1}', '', 'g'),
|
||||
\ '(s)', 's', 'g')
|
||||
else
|
||||
let prompt = substitute(
|
||||
\ substitute(g:EasyMotion_prompt,'{n}', a:num_strokes, 'g'),
|
||||
\ '(s)', 's', 'g')
|
||||
endif
|
||||
return prompt
|
||||
endfunction "}}}
|
||||
|
||||
function! s:off_screen_search(re) "{{{
|
||||
" First: search within visible screen range
|
||||
call s:adjust_screen()
|
||||
" Error occur when '\zs' without '!'
|
||||
silent! let pos = searchpos(a:re, s:direction . 'n', s:orig_line_end[1])
|
||||
if pos != [0, 0]
|
||||
" Restore cursor posision
|
||||
keepjumps call setpos('.', s:orig_pos)
|
||||
else
|
||||
" Second: if there were no much, search off screen
|
||||
silent! let pos = searchpos(a:re, s:direction)
|
||||
if pos != [0, 0]
|
||||
" Match
|
||||
keepjumps call setpos('.', pos)
|
||||
" Move cursor
|
||||
if s:save_direction != 'b'
|
||||
normal! zzH0
|
||||
else
|
||||
normal! zzL0
|
||||
endif
|
||||
else
|
||||
" No much
|
||||
call s:adjust_screen()
|
||||
keepjumps call setpos('.', s:orig_pos)
|
||||
endif
|
||||
endif
|
||||
" redraw
|
||||
endfunction "}}}
|
||||
function! s:adjust_screen() "{{{
|
||||
if s:save_direction != 'b'
|
||||
" Forward
|
||||
keepjumps call setpos('.', s:orig_line_start)
|
||||
normal! zt
|
||||
else
|
||||
" Backward
|
||||
keepjumps call setpos('.', s:orig_line_end)
|
||||
normal! zb
|
||||
endif
|
||||
endfunction "}}}
|
||||
function! s:scroll(direction) "{{{
|
||||
" direction: 0 -> forward, 1 -> backward
|
||||
exec a:direction == 0 ? "normal! \<C-f>" : "normal! \<C-b>"
|
||||
let s:orig_pos = getpos('.')
|
||||
let s:orig_line_start = getpos('w0')
|
||||
let s:orig_line_end = getpos('w$')
|
||||
let s:direction = a:direction == 0 ? '' : 'b'
|
||||
endfunction "}}}
|
||||
function! s:inc_highlight(re) "{{{
|
||||
call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search)
|
||||
if s:search.line.length() > 0
|
||||
" Error occur when '\zs' without '!'
|
||||
silent! call EasyMotion#highlight#add_highlight(a:re, g:EasyMotion_hl_inc_search)
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" vim: fdm=marker:et:ts=4:sw=4:sts=4
|
185
sources_non_forked/vim-easymotion/autoload/EasyMotion/helper.vim
Normal file
185
sources_non_forked/vim-easymotion/autoload/EasyMotion/helper.vim
Normal file
|
@ -0,0 +1,185 @@
|
|||
"=============================================================================
|
||||
" FILE: autoload/EasyMotion/helper.vim
|
||||
" AUTHOR: haya14busa
|
||||
" License: MIT license {{{
|
||||
" Permission is hereby granted, free of charge, to any person obtaining
|
||||
" a copy of this software and associated documentation files (the
|
||||
" "Software"), to deal in the Software without restriction, including
|
||||
" without limitation the rights to use, copy, modify, merge, publish,
|
||||
" distribute, sublicense, and/or sell copies of the Software, and to
|
||||
" permit persons to whom the Software is furnished to do so, subject to
|
||||
" the following conditions:
|
||||
"
|
||||
" The above copyright notice and this permission notice shall be included
|
||||
" in all copies or substantial portions of the Software.
|
||||
"
|
||||
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
scriptencoding utf-8
|
||||
" Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
|
||||
function! EasyMotion#helper#mode(flag) "{{{
|
||||
return mode(a:flag) == "\<C-v>" ? "C-v" : mode(a:flag)
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#helper#get_char_by_coord(coord) "{{{
|
||||
" @param coord: [lnum, col] or [bufnum, lnum, col, off]
|
||||
if len(a:coord) == 4
|
||||
let [line_num, col_num] = [a:coord[1], a:coord[2]]
|
||||
else
|
||||
let [line_num, col_num] = a:coord
|
||||
endif
|
||||
let target_col_regexp = '\%' . (col_num) . 'c.'
|
||||
return matchstr(getline(line_num), target_col_regexp)
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#helper#is_greater_coords(coords1, coords2) "{{{
|
||||
" [line_num, col_num] < [line_num, col_num]
|
||||
"
|
||||
" coords1 < coords2 : return 1
|
||||
" coords1 > coords2 : return -1
|
||||
" coords1 == coords2 : return 0
|
||||
if a:coords1 == a:coords2 | return 0 | endif
|
||||
|
||||
if a:coords1[0] < a:coords2[0]
|
||||
return 1
|
||||
elseif a:coords1[0] > a:coords2[0]
|
||||
return -1
|
||||
endif
|
||||
|
||||
" Same line
|
||||
if a:coords1[1] < a:coords2[1]
|
||||
return 1
|
||||
elseif a:coords1[1] > a:coords2[1]
|
||||
return -1
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#helper#is_folded(line) "{{{
|
||||
" Return false if g:EasyMotion_skipfoldedline == 1
|
||||
" and line is start of folded lines
|
||||
let _foldclosed = foldclosed(a:line)
|
||||
return _foldclosed != -1 &&
|
||||
\ (g:EasyMotion_skipfoldedline == 1 || a:line != _foldclosed)
|
||||
endfunction "}}}
|
||||
function! EasyMotion#helper#should_case_sensitive(input, is_search) "{{{
|
||||
if !a:is_search
|
||||
if g:EasyMotion_smartcase == 0
|
||||
return 0
|
||||
else
|
||||
" return 1 if input didn't match uppercase letter
|
||||
return match(a:input, '\u') == -1
|
||||
endif
|
||||
endif
|
||||
|
||||
if (g:EasyMotion_smartcase == 1 && match(a:input, '\u') == -1) ||
|
||||
\ (&ignorecase && &smartcase && match(a:input, '\u') == -1) ||
|
||||
\ (&ignorecase && !&smartcase)
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
endfunction "}}}
|
||||
function! EasyMotion#helper#silent_feedkeys(expr, name, ...) "{{{
|
||||
" Ref:
|
||||
" https://github.com/osyo-manga/vim-over/blob/d51b028c29661d4a5f5b79438ad6d69266753711/autoload/over.vim#L6
|
||||
let mode = get(a:, 1, "m")
|
||||
let name = "easymotion-" . a:name
|
||||
let map = printf("<Plug>(%s)", name)
|
||||
if mode == "n"
|
||||
let command = "nnoremap"
|
||||
else
|
||||
let command = "nmap"
|
||||
endif
|
||||
execute command "<silent>" map printf("%s:nunmap %s<CR>", a:expr, map)
|
||||
if mode(1) !=# 'ce'
|
||||
" FIXME: mode(1) !=# 'ce' exists only for the test
|
||||
" :h feedkeys() doesn't work while runnning a test script
|
||||
" https://github.com/kana/vim-vspec/issues/27
|
||||
call feedkeys(printf("\<Plug>(%s)", name))
|
||||
endif
|
||||
endfunction "}}}
|
||||
function! EasyMotion#helper#VarReset(var, ...) "{{{
|
||||
if ! exists('s:var_reset')
|
||||
let s:var_reset = {}
|
||||
endif
|
||||
|
||||
if a:0 == 0 && has_key(s:var_reset, a:var)
|
||||
" Reset var to original value
|
||||
" setbufvar( or bufname): '' or '%' can be used for the current buffer
|
||||
call setbufvar('%', a:var, s:var_reset[a:var])
|
||||
elseif a:0 == 1
|
||||
" Save original value and set new var value
|
||||
|
||||
let new_value = a:0 == 1 ? a:1 : ''
|
||||
|
||||
" Store original value
|
||||
let s:var_reset[a:var] = getbufvar("", a:var)
|
||||
|
||||
" Set new var value
|
||||
call setbufvar('%', a:var, new_value)
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" Migemo {{{
|
||||
function! EasyMotion#helper#load_migemo_dict() "{{{
|
||||
let enc = &l:encoding
|
||||
if enc ==# 'utf-8'
|
||||
return EasyMotion#migemo#utf8#load_dict()
|
||||
elseif enc ==# 'cp932'
|
||||
return EasyMotion#migemo#cp932#load_dict()
|
||||
elseif enc ==# 'euc-jp'
|
||||
return EasyMotion#migemo#eucjp#load_dict()
|
||||
else
|
||||
let g:EasyMotion_use_migemo = 0
|
||||
throw "Error: ".enc." is not supported. Migemo is made disabled."
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" EasyMotion#helper#strchars() {{{
|
||||
if exists('*strchars')
|
||||
function! EasyMotion#helper#strchars(str)
|
||||
return strchars(a:str)
|
||||
endfunction
|
||||
else
|
||||
function! EasyMotion#helper#strchars(str)
|
||||
return strlen(substitute(a:str, ".", "x", "g"))
|
||||
endfunction
|
||||
endif "}}}
|
||||
function! EasyMotion#helper#include_multibyte_char(str) "{{{
|
||||
return strlen(a:str) != EasyMotion#helper#strchars(a:str)
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#helper#vcol(expr) abort
|
||||
let col_num = col(a:expr)
|
||||
let line = getline(a:expr)
|
||||
let before_line = col_num > 2 ? line[: col_num - 2]
|
||||
\ : col_num is# 2 ? line[0]
|
||||
\ : ''
|
||||
let vcol_num = 1
|
||||
for c in split(before_line, '\zs')
|
||||
let vcol_num += c is# "\t" ? s:_virtual_tab2spacelen(vcol_num) : len(c)
|
||||
endfor
|
||||
return vcol_num
|
||||
endfunction
|
||||
|
||||
function! s:_virtual_tab2spacelen(col_num) abort
|
||||
return &tabstop - ((a:col_num - 1) % &tabstop)
|
||||
endfunction
|
||||
|
||||
"}}}
|
||||
|
||||
" Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" vim: fdm=marker:et:ts=4:sw=4:sts=4
|
|
@ -0,0 +1,251 @@
|
|||
"=============================================================================
|
||||
" FILE: highlight.vim
|
||||
" AUTHOR: haya14busa
|
||||
" Reference: https://github.com/t9md/vim-smalls
|
||||
" License: MIT license {{{
|
||||
" Permission is hereby granted, free of charge, to any person obtaining
|
||||
" a copy of this software and associated documentation files (the
|
||||
" "Software"), to deal in the Software without restriction, including
|
||||
" without limitation the rights to use, copy, modify, merge, publish,
|
||||
" distribute, sublicense, and/or sell copies of the Software, and to
|
||||
" permit persons to whom the Software is furnished to do so, subject to
|
||||
" the following conditions:
|
||||
"
|
||||
" The above copyright notice and this permission notice shall be included
|
||||
" in all copies or substantial portions of the Software.
|
||||
"
|
||||
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
scriptencoding utf-8
|
||||
" Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
|
||||
function! EasyMotion#highlight#load()
|
||||
"load
|
||||
endfunction
|
||||
|
||||
" -- Default highlighting ---------------- {{{
|
||||
let g:EasyMotion_hl_group_target = get(g:,
|
||||
\ 'EasyMotion_hl_group_target', 'EasyMotionTarget')
|
||||
let g:EasyMotion_hl2_first_group_target = get(g:,
|
||||
\ 'EasyMotion_hl2_first_group_target', 'EasyMotionTarget2First')
|
||||
let g:EasyMotion_hl2_second_group_target = get(g:,
|
||||
\ 'EasyMotion_hl2_second_group_target', 'EasyMotionTarget2Second')
|
||||
let g:EasyMotion_hl_group_shade = get(g:,
|
||||
\ 'EasyMotion_hl_group_shade', 'EasyMotionShade')
|
||||
|
||||
let g:EasyMotion_hl_inc_search = get(g:,
|
||||
\ 'EasyMotion_hl_inc_search', 'EasyMotionIncSearch')
|
||||
let g:EasyMotion_hl_inc_cursor = get(g:,
|
||||
\ 'EasyMotion_hl_inc_cursor', 'EasyMotionIncCursor')
|
||||
let g:EasyMotion_hl_move = get(g:,
|
||||
\ 'EasyMotion_hl_move', 'EasyMotionMoveHL')
|
||||
|
||||
let s:target_hl_defaults = {
|
||||
\ 'gui' : ['NONE', '#ff0000' , 'bold']
|
||||
\ , 'cterm256': ['NONE', '196' , 'bold']
|
||||
\ , 'cterm' : ['NONE', 'red' , 'bold']
|
||||
\ }
|
||||
|
||||
let s:target_hl2_first_defaults = {
|
||||
\ 'gui' : ['NONE', '#ffb400' , 'bold']
|
||||
\ , 'cterm256': ['NONE', '11' , 'bold']
|
||||
\ , 'cterm' : ['NONE', 'yellow' , 'bold']
|
||||
\ }
|
||||
|
||||
let s:target_hl2_second_defaults = {
|
||||
\ 'gui' : ['NONE', '#b98300' , 'bold']
|
||||
\ , 'cterm256': ['NONE', '3' , 'bold']
|
||||
\ , 'cterm' : ['NONE', 'yellow' , 'bold']
|
||||
\ }
|
||||
|
||||
let s:shade_hl_defaults = {
|
||||
\ 'gui' : ['NONE', '#777777' , 'NONE']
|
||||
\ , 'cterm256': ['NONE', '242' , 'NONE']
|
||||
\ , 'cterm' : ['NONE', 'grey' , 'NONE']
|
||||
\ }
|
||||
|
||||
let s:shade_hl_line_defaults = {
|
||||
\ 'gui' : ['red' , '#FFFFFF' , 'NONE']
|
||||
\ , 'cterm256': ['red' , '242' , 'NONE']
|
||||
\ , 'cterm' : ['red' , 'grey' , 'NONE']
|
||||
\ }
|
||||
|
||||
let s:target_hl_inc = {
|
||||
\ 'gui' : ['NONE', '#7fbf00' , 'bold']
|
||||
\ , 'cterm256': ['NONE', '40' , 'bold']
|
||||
\ , 'cterm' : ['NONE', 'green' , 'bold']
|
||||
\ }
|
||||
let s:target_hl_inc_cursor = {
|
||||
\ 'gui' : ['#ACDBDA', '#121813' , 'bold']
|
||||
\ , 'cterm256': ['cyan' , '232' , 'bold']
|
||||
\ , 'cterm' : ['cyan' , 'black' , 'bold']
|
||||
\ }
|
||||
let s:target_hl_move = {
|
||||
\ 'gui' : ['#7fbf00', '#121813' , 'bold']
|
||||
\ , 'cterm256': ['green' , '15' , 'bold']
|
||||
\ , 'cterm' : ['green' , 'white' , 'bold']
|
||||
\ }
|
||||
" }}}
|
||||
function! EasyMotion#highlight#InitHL(group, colors) " {{{
|
||||
let group_default = a:group . 'Default'
|
||||
|
||||
" Prepare highlighting variables
|
||||
let guihl = printf('guibg=%s guifg=%s gui=%s', a:colors.gui[0], a:colors.gui[1], a:colors.gui[2])
|
||||
let ctermhl = &t_Co == 256
|
||||
\ ? printf('ctermbg=%s ctermfg=%s cterm=%s', a:colors.cterm256[0], a:colors.cterm256[1], a:colors.cterm256[2])
|
||||
\ : printf('ctermbg=%s ctermfg=%s cterm=%s', a:colors.cterm[0], a:colors.cterm[1], a:colors.cterm[2])
|
||||
|
||||
" Create default highlighting group
|
||||
execute printf('hi default %s %s %s', group_default, guihl, ctermhl)
|
||||
|
||||
" Check if the hl group exists
|
||||
if hlexists(a:group)
|
||||
redir => hlstatus | exec 'silent hi ' . a:group | redir END
|
||||
|
||||
" Return if the group isn't cleared
|
||||
if hlstatus !~ 'cleared'
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
" No colors are defined for this group, link to defaults
|
||||
execute printf('hi default link %s %s', a:group, group_default)
|
||||
endfunction " }}}
|
||||
function! EasyMotion#highlight#init() "{{{
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl_group_target, s:target_hl_defaults)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl2_first_group_target, s:target_hl2_first_defaults)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl2_second_group_target, s:target_hl2_second_defaults)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl_group_shade, s:shade_hl_defaults)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl_inc_search, s:target_hl_inc)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl_inc_cursor, s:target_hl_inc_cursor)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl_move, s:target_hl_move)
|
||||
if exists(':CSApprox') == 2 && g:EasyMotion_force_csapprox
|
||||
"TODO: better solution or remove completly
|
||||
CSApprox!
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" Reset highlighting after loading a new color scheme {{{
|
||||
augroup EasyMotionInitHL
|
||||
autocmd!
|
||||
autocmd ColorScheme * call EasyMotion#highlight#init()
|
||||
augroup end
|
||||
" }}}
|
||||
|
||||
call EasyMotion#highlight#init()
|
||||
" Init: {{{
|
||||
let s:h = {}
|
||||
let s:h.ids = {}
|
||||
let s:priorities = {
|
||||
\ g:EasyMotion_hl_group_target : 100,
|
||||
\ g:EasyMotion_hl2_first_group_target : 100,
|
||||
\ g:EasyMotion_hl2_second_group_target : 100,
|
||||
\ g:EasyMotion_hl_group_shade : 0,
|
||||
\ g:EasyMotion_hl_inc_search : 1,
|
||||
\ g:EasyMotion_hl_inc_cursor : 2,
|
||||
\ g:EasyMotion_hl_move : 0,
|
||||
\ }
|
||||
for s:group in keys(s:priorities)
|
||||
let s:h.ids[s:group] = []
|
||||
endfor
|
||||
unlet s:group
|
||||
"}}}
|
||||
|
||||
function! EasyMotion#highlight#delete_highlight(...) "{{{
|
||||
let groups = !empty(a:000) ? a:000 : keys(s:priorities)
|
||||
for group in groups
|
||||
for id in s:h.ids[group]
|
||||
silent! call matchdelete(id)
|
||||
endfor
|
||||
let s:h.ids[group] = []
|
||||
endfor
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#add_highlight(re, group) "{{{
|
||||
call add(s:h.ids[a:group], matchadd(a:group, a:re, s:priorities[a:group]))
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#add_pos_highlight(line_num, col_num, group) "{{{
|
||||
call add(s:h.ids[a:group], matchaddpos(a:group, [[a:line_num, a:col_num]], s:priorities[a:group]))
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#attach_autocmd() "{{{
|
||||
" Reference: https://github.com/justinmk/vim-sneak
|
||||
augroup plugin-easymotion
|
||||
autocmd!
|
||||
autocmd InsertEnter,WinLeave,BufLeave <buffer>
|
||||
\ silent! call EasyMotion#highlight#delete_highlight()
|
||||
\ | autocmd! plugin-easymotion * <buffer>
|
||||
autocmd CursorMoved <buffer>
|
||||
\ autocmd plugin-easymotion CursorMoved <buffer>
|
||||
\ silent! call EasyMotion#highlight#delete_highlight()
|
||||
\ | autocmd! plugin-easymotion * <buffer>
|
||||
augroup END
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#add_color_group(new_groups) "{{{
|
||||
let s:priorities = extend(deepcopy(s:priorities), a:new_groups)
|
||||
for group in keys(a:new_groups)
|
||||
let s:h.ids[group] = []
|
||||
endfor
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#highlight#capture(hlname) "{{{
|
||||
" Based On: https://github.com/t9md/vim-ezbar
|
||||
" https://github.com/osyo-manga/vital-over
|
||||
let hlname = a:hlname
|
||||
if !hlexists(hlname)
|
||||
return
|
||||
endif
|
||||
while 1
|
||||
let save_verbose = &verbose
|
||||
let &verbose = 0
|
||||
try
|
||||
redir => HL_SAVE
|
||||
execute 'silent! highlight ' . hlname
|
||||
redir END
|
||||
finally
|
||||
let &verbose = save_verbose
|
||||
endtry
|
||||
if !empty(matchstr(HL_SAVE, 'xxx cleared$'))
|
||||
return ''
|
||||
endif
|
||||
" follow highlight link
|
||||
let ml = matchlist(HL_SAVE, 'links to \zs.*')
|
||||
if !empty(ml)
|
||||
let hlname = ml[0]
|
||||
continue
|
||||
endif
|
||||
break
|
||||
endwhile
|
||||
let HL_SAVE = substitute(matchstr(HL_SAVE, 'xxx \zs.*'),
|
||||
\ '[ \t\n]\+', ' ', 'g')
|
||||
return [hlname, HL_SAVE]
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#turn_off(hl) "{{{
|
||||
if type(a:hl) != type([])
|
||||
return
|
||||
endif
|
||||
execute 'highlight ' . a:hl[0] . ' NONE'
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#turn_on(hl) "{{{
|
||||
if type(a:hl) != type([])
|
||||
return
|
||||
endif
|
||||
execute 'highlight ' . a:hl[0] . ' ' . a:hl[1]
|
||||
endfunction "}}}
|
||||
|
||||
" Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" __END__ {{{
|
||||
" vim: expandtab softtabstop=4 shiftwidth=4
|
||||
" vim: foldmethod=marker
|
||||
" }}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,27 @@
|
|||
let s:V = vital#easymotion#new()
|
||||
let s:HitAHintMotion = s:V.import('HitAHint.Motion')
|
||||
|
||||
call EasyMotion#init()
|
||||
|
||||
function! EasyMotion#overwin#move(pattern) abort
|
||||
return s:HitAHintMotion.move(a:pattern, {
|
||||
\ 'keys': g:EasyMotion_keys,
|
||||
\ 'use_upper': g:EasyMotion_use_upper,
|
||||
\ 'highlight': {
|
||||
\ 'shade': g:EasyMotion_hl_group_shade,
|
||||
\ 'target': g:EasyMotion_hl_group_target,
|
||||
\ },
|
||||
\ 'jump_first_target_keys':
|
||||
\ (g:EasyMotion_enter_jump_first ? ["\<CR>"] : []) +
|
||||
\ (g:EasyMotion_space_jump_first ? ["\<Space>"] : []),
|
||||
\ 'do_shade': g:EasyMotion_do_shade,
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
function! EasyMotion#overwin#line() abort
|
||||
return EasyMotion#overwin#move('^')
|
||||
endfunction
|
||||
|
||||
function! EasyMotion#overwin#w() abort
|
||||
return EasyMotion#overwin#move('\(\<.\|^$\)')
|
||||
endfunction
|
|
@ -0,0 +1,24 @@
|
|||
" Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
"
|
||||
let EasyMotion#sticky_table#us = {
|
||||
\',' : '<', '.' : '>', '/' : '?',
|
||||
\'1' : '!', '2' : '@', '3' : '#', '4' : '$', '5' : '%',
|
||||
\'6' : '^', '7' : '&', '8' : '*', '9' : '(', '0' : ')', '-' : '_', '=' : '+',
|
||||
\';' : ':', '[' : '{', ']' : '}', '`' : '~', "'" : "\"", '\' : '|',
|
||||
\}
|
||||
|
||||
let EasyMotion#sticky_table#jp = {
|
||||
\',' : '<', '.' : '>', '/' : '?',
|
||||
\'1' : '!', '2' : '"', '3' : '#', '4' : '$', '5' : '%',
|
||||
\'6' : '&', '7' : "'", '8' : '(', '9' : ')', '0' : '_', '-' : '=', '^' : '~',
|
||||
\';' : '+', ':' : '*', '[' : '{', ']' : '}', '@' : '`', '\' : '|',
|
||||
\}
|
||||
|
||||
" Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" vim: fdm=marker:et:ts=4:sw=4:sts=4
|
|
@ -0,0 +1,50 @@
|
|||
let s:Buffer = vital#easymotion#import('Vim.Buffer')
|
||||
|
||||
function! EasyMotion#undo#save() abort
|
||||
return s:undo_lock.save()
|
||||
endfunction
|
||||
|
||||
let s:undo_lock = {}
|
||||
|
||||
function! s:undo_lock.save() abort
|
||||
let undo = deepcopy(self)
|
||||
call undo._save()
|
||||
return undo
|
||||
endfunction
|
||||
|
||||
function! s:undo_lock._save() abort
|
||||
if undotree().seq_last == 0
|
||||
" if there are no undo history, disable undo feature by setting
|
||||
" 'undolevels' to -1 and restore it.
|
||||
let self.save_undolevels = &l:undolevels
|
||||
let &l:undolevels = -1
|
||||
elseif !s:Buffer.is_cmdwin()
|
||||
" command line window doesn't support :wundo.
|
||||
let self.undofile = tempname()
|
||||
execute 'wundo!' self.undofile
|
||||
else
|
||||
let self.is_cmdwin = s:TRUE
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:undo_lock.restore() abort
|
||||
if has_key(self, 'save_undolevels')
|
||||
let &l:undolevels = self.save_undolevels
|
||||
endif
|
||||
if has_key(self, 'undofile') && filereadable(self.undofile)
|
||||
silent execute 'rundo' self.undofile
|
||||
call delete(self.undofile)
|
||||
endif
|
||||
if has_key(self, 'is_cmdwin')
|
||||
" XXX: it breaks undo history. AFAIK, there are no way to save and restore
|
||||
" undo history in commandline window.
|
||||
call self.undobreak()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:undo_lock.undobreak() abort
|
||||
let old_undolevels = &l:undolevels
|
||||
setlocal undolevels=-1
|
||||
keepjumps call setline('.', getline('.'))
|
||||
let &l:undolevels = old_undolevels
|
||||
endfunction
|
12
sources_non_forked/vim-easymotion/autoload/vital.vim
Normal file
12
sources_non_forked/vim-easymotion/autoload/vital.vim
Normal file
|
@ -0,0 +1,12 @@
|
|||
function! vital#of(name) abort
|
||||
let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital', 1)
|
||||
let file = split(files, "\n")
|
||||
if empty(file)
|
||||
throw 'vital: version file not found: ' . a:name
|
||||
endif
|
||||
let ver = readfile(file[0], 'b')
|
||||
if empty(ver)
|
||||
throw 'vital: invalid version file: ' . a:name
|
||||
endif
|
||||
return vital#_{substitute(ver[0], '\W', '', 'g')}#new()
|
||||
endfunction
|
|
@ -0,0 +1,5 @@
|
|||
let s:_plugin_name = expand('<sfile>:t:r')
|
||||
|
||||
function! vital#{s:_plugin_name}#new() abort
|
||||
return vital#{s:_plugin_name[1:]}#new()
|
||||
endfunction
|
|
@ -0,0 +1,116 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Data#Dict#import() abort
|
||||
return map({'pick': '', 'clear': '', 'max_by': '', 'foldl': '', 'swap': '', 'omit': '', 'min_by': '', 'foldr': '', 'make_index': '', 'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
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('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
" Utilities for dictionary.
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Makes a dict from keys and values
|
||||
function! s:make(keys, values, ...) abort
|
||||
let dict = {}
|
||||
let fill = a:0 ? a:1 : 0
|
||||
for i in range(len(a:keys))
|
||||
let key = type(a:keys[i]) == type('') ? a:keys[i] : string(a:keys[i])
|
||||
if key ==# ''
|
||||
throw "vital: Data.Dict: Can't use an empty string for key."
|
||||
endif
|
||||
let dict[key] = get(a:values, i, fill)
|
||||
endfor
|
||||
return dict
|
||||
endfunction
|
||||
|
||||
" Swaps keys and values
|
||||
function! s:swap(dict) abort
|
||||
return s:make(values(a:dict), keys(a:dict))
|
||||
endfunction
|
||||
|
||||
" Makes a index dict from a list
|
||||
function! s:make_index(list, ...) abort
|
||||
let value = a:0 ? a:1 : 1
|
||||
return s:make(a:list, [], value)
|
||||
endfunction
|
||||
|
||||
function! s:pick(dict, keys) abort
|
||||
let new_dict = {}
|
||||
for key in a:keys
|
||||
if has_key(a:dict, key)
|
||||
let new_dict[key] = a:dict[key]
|
||||
endif
|
||||
endfor
|
||||
return new_dict
|
||||
endfunction
|
||||
|
||||
function! s:omit(dict, keys) abort
|
||||
let new_dict = copy(a:dict)
|
||||
for key in a:keys
|
||||
if has_key(a:dict, key)
|
||||
call remove(new_dict, key)
|
||||
endif
|
||||
endfor
|
||||
return new_dict
|
||||
endfunction
|
||||
|
||||
function! s:clear(dict) abort
|
||||
for key in keys(a:dict)
|
||||
call remove(a:dict, key)
|
||||
endfor
|
||||
return a:dict
|
||||
endfunction
|
||||
|
||||
function! s:_max_by(dict, expr) abort
|
||||
let dict = s:swap(map(copy(a:dict), a:expr))
|
||||
let key = dict[max(keys(dict))]
|
||||
return [key, a:dict[key]]
|
||||
endfunction
|
||||
|
||||
function! s:max_by(dict, expr) abort
|
||||
if empty(a:dict)
|
||||
throw 'vital: Data.Dict: Empty dictionary'
|
||||
endif
|
||||
return s:_max_by(a:dict, a:expr)
|
||||
endfunction
|
||||
|
||||
function! s:min_by(dict, expr) abort
|
||||
if empty(a:dict)
|
||||
throw 'vital: Data.Dict: Empty dictionary'
|
||||
endif
|
||||
return s:_max_by(a:dict, '-(' . a:expr . ')')
|
||||
endfunction
|
||||
|
||||
function! s:_foldl(f, init, xs) abort
|
||||
let memo = a:init
|
||||
for [k, v] in a:xs
|
||||
let expr = substitute(a:f, 'v:key', string(k), 'g')
|
||||
let expr = substitute(expr, 'v:val', string(v), 'g')
|
||||
let expr = substitute(expr, 'v:memo', string(memo), 'g')
|
||||
unlet memo
|
||||
let memo = eval(expr)
|
||||
endfor
|
||||
return memo
|
||||
endfunction
|
||||
|
||||
function! s:foldl(f, init, dict) abort
|
||||
return s:_foldl(a:f, a:init, items(a:dict))
|
||||
endfunction
|
||||
|
||||
function! s:foldr(f, init, dict) abort
|
||||
return s:_foldl(a:f, a:init, reverse(items(a:dict)))
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0:
|
|
@ -0,0 +1,457 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Data#List#import() abort
|
||||
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)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
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('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
" Utilities for list.
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
function! s:pop(list) abort
|
||||
return remove(a:list, -1)
|
||||
endfunction
|
||||
|
||||
function! s:push(list, val) abort
|
||||
call add(a:list, a:val)
|
||||
return a:list
|
||||
endfunction
|
||||
|
||||
function! s:shift(list) abort
|
||||
return remove(a:list, 0)
|
||||
endfunction
|
||||
|
||||
function! s:unshift(list, val) abort
|
||||
return insert(a:list, a:val)
|
||||
endfunction
|
||||
|
||||
function! s:cons(x, xs) abort
|
||||
return [a:x] + a:xs
|
||||
endfunction
|
||||
|
||||
function! s:conj(xs, x) abort
|
||||
return a:xs + [a:x]
|
||||
endfunction
|
||||
|
||||
" Removes duplicates from a list.
|
||||
function! s:uniq(list) abort
|
||||
return s:uniq_by(a:list, 'v:val')
|
||||
endfunction
|
||||
|
||||
" Removes duplicates from a list.
|
||||
function! s:uniq_by(list, f) abort
|
||||
let list = map(copy(a:list), printf('[v:val, %s]', a:f))
|
||||
let i = 0
|
||||
let seen = {}
|
||||
while i < len(list)
|
||||
let key = string(list[i][1])
|
||||
if has_key(seen, key)
|
||||
call remove(list, i)
|
||||
else
|
||||
let seen[key] = 1
|
||||
let i += 1
|
||||
endif
|
||||
endwhile
|
||||
return map(list, 'v:val[0]')
|
||||
endfunction
|
||||
|
||||
function! s:clear(list) abort
|
||||
if !empty(a:list)
|
||||
unlet! a:list[0 : len(a:list) - 1]
|
||||
endif
|
||||
return a:list
|
||||
endfunction
|
||||
|
||||
" Concatenates a list of lists.
|
||||
" XXX: Should we verify the input?
|
||||
function! s:concat(list) abort
|
||||
let memo = []
|
||||
for Value in a:list
|
||||
let memo += Value
|
||||
endfor
|
||||
return memo
|
||||
endfunction
|
||||
|
||||
" Take each elements from lists to a new list.
|
||||
function! s:flatten(list, ...) abort
|
||||
let limit = a:0 > 0 ? a:1 : -1
|
||||
let memo = []
|
||||
if limit == 0
|
||||
return a:list
|
||||
endif
|
||||
let limit -= 1
|
||||
for Value in a:list
|
||||
let memo +=
|
||||
\ type(Value) == type([]) ?
|
||||
\ s:flatten(Value, limit) :
|
||||
\ [Value]
|
||||
unlet! Value
|
||||
endfor
|
||||
return memo
|
||||
endfunction
|
||||
|
||||
" Sorts a list with expression to compare each two values.
|
||||
" a:a and a:b can be used in {expr}.
|
||||
function! s:sort(list, expr) abort
|
||||
if type(a:expr) == type(function('function'))
|
||||
return sort(a:list, a:expr)
|
||||
endif
|
||||
let s:expr = a:expr
|
||||
return sort(a:list, 's:_compare')
|
||||
endfunction
|
||||
|
||||
function! s:_compare(a, b) abort
|
||||
return eval(s:expr)
|
||||
endfunction
|
||||
|
||||
" Sorts a list using a set of keys generated by mapping the values in the list
|
||||
" through the given expr.
|
||||
" v:val is used in {expr}
|
||||
function! s:sort_by(list, expr) abort
|
||||
let pairs = map(a:list, printf('[v:val, %s]', a:expr))
|
||||
return map(s:sort(pairs,
|
||||
\ 'a:a[1] ==# a:b[1] ? 0 : a:a[1] ># a:b[1] ? 1 : -1'), 'v:val[0]')
|
||||
endfunction
|
||||
|
||||
" Returns a maximum value in {list} through given {expr}.
|
||||
" Returns 0 if {list} is empty.
|
||||
" v:val is used in {expr}
|
||||
function! s:max_by(list, expr) abort
|
||||
if empty(a:list)
|
||||
return 0
|
||||
endif
|
||||
let list = map(copy(a:list), a:expr)
|
||||
return a:list[index(list, max(list))]
|
||||
endfunction
|
||||
|
||||
" Returns a minimum value in {list} through given {expr}.
|
||||
" Returns 0 if {list} is empty.
|
||||
" v:val is used in {expr}
|
||||
" FIXME: -0x80000000 == 0x80000000
|
||||
function! s:min_by(list, expr) abort
|
||||
return s:max_by(a:list, '-(' . a:expr . ')')
|
||||
endfunction
|
||||
|
||||
" Returns List of character sequence between [a:from, a:to]
|
||||
" e.g.: s:char_range('a', 'c') returns ['a', 'b', 'c']
|
||||
function! s:char_range(from, to) abort
|
||||
return map(
|
||||
\ range(char2nr(a:from), char2nr(a:to)),
|
||||
\ 'nr2char(v:val)'
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Returns true if a:list has a:value.
|
||||
" Returns false otherwise.
|
||||
function! s:has(list, value) abort
|
||||
return index(a:list, a:value) isnot -1
|
||||
endfunction
|
||||
|
||||
" Returns true if a:list[a:index] exists.
|
||||
" Returns false otherwise.
|
||||
" NOTE: Returns false when a:index is negative number.
|
||||
function! s:has_index(list, index) abort
|
||||
" Return true when negative index?
|
||||
" let index = a:index >= 0 ? a:index : len(a:list) + a:index
|
||||
return 0 <= a:index && a:index < len(a:list)
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Data.List.span
|
||||
function! s:span(f, xs) abort
|
||||
let border = len(a:xs)
|
||||
for i in range(len(a:xs))
|
||||
if !eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
|
||||
let border = i
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
return border == 0 ? [[], copy(a:xs)] : [a:xs[: border - 1], a:xs[border :]]
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Data.List.break
|
||||
function! s:break(f, xs) abort
|
||||
return s:span(printf('!(%s)', a:f), a:xs)
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Data.List.takeWhile
|
||||
function! s:take_while(f, xs) abort
|
||||
return s:span(a:f, a:xs)[0]
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Data.List.partition
|
||||
function! s:partition(f, xs) abort
|
||||
return [filter(copy(a:xs), a:f), filter(copy(a:xs), '!(' . a:f . ')')]
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.all
|
||||
function! s:all(f, xs) abort
|
||||
return !s:any(printf('!(%s)', a:f), a:xs)
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.any
|
||||
function! s:any(f, xs) abort
|
||||
return !empty(filter(map(copy(a:xs), a:f), 'v:val'))
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.and
|
||||
function! s:and(xs) abort
|
||||
return s:all('v:val', a:xs)
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.or
|
||||
function! s:or(xs) abort
|
||||
return s:any('v:val', a:xs)
|
||||
endfunction
|
||||
|
||||
function! s:map_accum(expr, xs, init) abort
|
||||
let memo = []
|
||||
let init = a:init
|
||||
for x in a:xs
|
||||
let expr = substitute(a:expr, 'v:memo', init, 'g')
|
||||
let expr = substitute(expr, 'v:val', x, 'g')
|
||||
let [tmp, init] = eval(expr)
|
||||
call add(memo, tmp)
|
||||
endfor
|
||||
return memo
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.foldl
|
||||
function! s:foldl(f, init, xs) abort
|
||||
let memo = a:init
|
||||
for x in a:xs
|
||||
let expr = substitute(a:f, 'v:val', string(x), 'g')
|
||||
let expr = substitute(expr, 'v:memo', string(memo), 'g')
|
||||
unlet memo
|
||||
let memo = eval(expr)
|
||||
endfor
|
||||
return memo
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.foldl1
|
||||
function! s:foldl1(f, xs) abort
|
||||
if len(a:xs) == 0
|
||||
throw 'vital: Data.List: foldl1'
|
||||
endif
|
||||
return s:foldl(a:f, a:xs[0], a:xs[1:])
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.foldr
|
||||
function! s:foldr(f, init, xs) abort
|
||||
return s:foldl(a:f, a:init, reverse(copy(a:xs)))
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.fold11
|
||||
function! s:foldr1(f, xs) abort
|
||||
if len(a:xs) == 0
|
||||
throw 'vital: Data.List: foldr1'
|
||||
endif
|
||||
return s:foldr(a:f, a:xs[-1], a:xs[0:-2])
|
||||
endfunction
|
||||
|
||||
" similar to python's zip()
|
||||
function! s:zip(...) abort
|
||||
return map(range(min(map(copy(a:000), 'len(v:val)'))), "map(copy(a:000), 'v:val['.v:val.']')")
|
||||
endfunction
|
||||
|
||||
" similar to zip(), but goes until the longer one.
|
||||
function! s:zip_fill(xs, ys, filler) abort
|
||||
if empty(a:xs) && empty(a:ys)
|
||||
return []
|
||||
elseif empty(a:ys)
|
||||
return s:cons([a:xs[0], a:filler], s:zip_fill(a:xs[1 :], [], a:filler))
|
||||
elseif empty(a:xs)
|
||||
return s:cons([a:filler, a:ys[0]], s:zip_fill([], a:ys[1 :], a:filler))
|
||||
else
|
||||
return s:cons([a:xs[0], a:ys[0]], s:zip_fill(a:xs[1 :], a:ys[1: ], a:filler))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Inspired by Ruby's with_index method.
|
||||
function! s:with_index(list, ...) abort
|
||||
let base = a:0 > 0 ? a:1 : 0
|
||||
return map(copy(a:list), '[v:val, v:key + base]')
|
||||
endfunction
|
||||
|
||||
" similar to Ruby's detect or Haskell's find.
|
||||
function! s:find(list, default, f) abort
|
||||
for x in a:list
|
||||
if eval(substitute(a:f, 'v:val', string(x), 'g'))
|
||||
return x
|
||||
endif
|
||||
endfor
|
||||
return a:default
|
||||
endfunction
|
||||
|
||||
" Returns the index of the first element which satisfies the given expr.
|
||||
function! s:find_index(xs, f, ...) abort
|
||||
let len = len(a:xs)
|
||||
let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : 0
|
||||
let default = a:0 > 1 ? a:2 : -1
|
||||
if start >=# len || start < 0
|
||||
return default
|
||||
endif
|
||||
for i in range(start, len - 1)
|
||||
if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
|
||||
return i
|
||||
endif
|
||||
endfor
|
||||
return default
|
||||
endfunction
|
||||
|
||||
" Returns the index of the last element which satisfies the given expr.
|
||||
function! s:find_last_index(xs, f, ...) abort
|
||||
let len = len(a:xs)
|
||||
let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : len - 1
|
||||
let default = a:0 > 1 ? a:2 : -1
|
||||
if start >=# len || start < 0
|
||||
return default
|
||||
endif
|
||||
for i in range(start, 0, -1)
|
||||
if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
|
||||
return i
|
||||
endif
|
||||
endfor
|
||||
return default
|
||||
endfunction
|
||||
|
||||
" Similar to find_index but returns the list of indices satisfying the given expr.
|
||||
function! s:find_indices(xs, f, ...) abort
|
||||
let len = len(a:xs)
|
||||
let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : 0
|
||||
let result = []
|
||||
if start >=# len || start < 0
|
||||
return result
|
||||
endif
|
||||
for i in range(start, len - 1)
|
||||
if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
|
||||
call add(result, i)
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
" Return non-zero if a:list1 and a:list2 have any common item(s).
|
||||
" Return zero otherwise.
|
||||
function! s:has_common_items(list1, list2) abort
|
||||
return !empty(filter(copy(a:list1), 'index(a:list2, v:val) isnot -1'))
|
||||
endfunction
|
||||
|
||||
function! s:intersect(list1, list2) abort
|
||||
let items = []
|
||||
" for funcref
|
||||
for X in a:list1
|
||||
if index(a:list2, X) != -1 && index(items, X) == -1
|
||||
let items += [X]
|
||||
endif
|
||||
endfor
|
||||
return items
|
||||
endfunction
|
||||
|
||||
" similar to Ruby's group_by.
|
||||
function! s:group_by(xs, f) abort
|
||||
let result = {}
|
||||
let list = map(copy(a:xs), printf('[v:val, %s]', a:f))
|
||||
for x in list
|
||||
let Val = x[0]
|
||||
let key = type(x[1]) !=# type('') ? string(x[1]) : x[1]
|
||||
if has_key(result, key)
|
||||
call add(result[key], Val)
|
||||
else
|
||||
let result[key] = [Val]
|
||||
endif
|
||||
unlet Val
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:_default_compare(a, b) abort
|
||||
return a:a <# a:b ? -1 : a:a ># a:b ? 1 : 0
|
||||
endfunction
|
||||
|
||||
function! s:binary_search(list, value, ...) abort
|
||||
let Predicate = a:0 >= 1 ? a:1 : 's:_default_compare'
|
||||
let dic = a:0 >= 2 ? a:2 : {}
|
||||
let start = 0
|
||||
let end = len(a:list) - 1
|
||||
|
||||
while 1
|
||||
if start > end
|
||||
return -1
|
||||
endif
|
||||
|
||||
let middle = (start + end) / 2
|
||||
|
||||
let compared = call(Predicate, [a:value, a:list[middle]], dic)
|
||||
|
||||
if compared < 0
|
||||
let end = middle - 1
|
||||
elseif compared > 0
|
||||
let start = middle + 1
|
||||
else
|
||||
return middle
|
||||
endif
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
function! s:product(lists) abort
|
||||
let result = [[]]
|
||||
for pool in a:lists
|
||||
let tmp = []
|
||||
for x in result
|
||||
let tmp += map(copy(pool), 'x + [v:val]')
|
||||
endfor
|
||||
let result = tmp
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:permutations(list, ...) abort
|
||||
if a:0 > 1
|
||||
throw 'vital: Data.List: too many arguments'
|
||||
endif
|
||||
let r = a:0 == 1 ? a:1 : len(a:list)
|
||||
if r > len(a:list)
|
||||
return []
|
||||
elseif r < 0
|
||||
throw 'vital: Data.List: {r} must be non-negative integer'
|
||||
endif
|
||||
let n = len(a:list)
|
||||
let result = []
|
||||
for indices in s:product(map(range(r), 'range(n)'))
|
||||
if len(s:uniq(indices)) == r
|
||||
call add(result, map(indices, 'a:list[v:val]'))
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:combinations(list, r) abort
|
||||
if a:r > len(a:list)
|
||||
return []
|
||||
elseif a:r < 0
|
||||
throw 'vital: Data:List: {r} must be non-negative integer'
|
||||
endif
|
||||
let n = len(a:list)
|
||||
let result = []
|
||||
for indices in s:permutations(range(n), a:r)
|
||||
if s:sort(copy(indices), 'a:a - a:b') == indices
|
||||
call add(result, map(indices, 'a:list[v:val]'))
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0:
|
|
@ -0,0 +1,284 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Data#Set#import() abort
|
||||
return map({'set': '', 'frozenset': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Data#Set#import() abort', printf("return map({'set': '', 'frozenset': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:TRUE = !0
|
||||
let s:FALSE = 0
|
||||
|
||||
function! s:set(...) abort
|
||||
return call(s:set._new, a:000, s:set)
|
||||
endfunction
|
||||
|
||||
function! s:frozenset(...) abort
|
||||
return call(s:frozenset._new, a:000, s:frozenset)
|
||||
endfunction
|
||||
|
||||
function! s:_hash_func(x) abort
|
||||
return a:x
|
||||
endfunction
|
||||
|
||||
let s:_base_set = {
|
||||
\ '_is_set' : s:TRUE,
|
||||
\ '_data' : {},
|
||||
\ '_hash_func' : function('s:_hash_func')
|
||||
\ }
|
||||
|
||||
function! s:_base_set._new(...) abort
|
||||
let obj = deepcopy(self)
|
||||
let xs = get(a:, 1, [])
|
||||
let obj._hash_func = get(a:, 2, obj._hash_func)
|
||||
call obj._set_data(xs)
|
||||
return obj
|
||||
endfunction
|
||||
|
||||
"" Return the union of two sets as a new set.
|
||||
" (I.e. all elements that are in either set.)
|
||||
function! s:_base_set.union(t) abort
|
||||
let r = deepcopy(self)
|
||||
call r._update(a:t)
|
||||
return r
|
||||
endfunction
|
||||
let s:_base_set.or = s:_base_set.union
|
||||
|
||||
"" Return the intersection of two sets as a new set.
|
||||
" (I.e. all elements that are in both sets.)
|
||||
function! s:_base_set.intersection(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
let [little, big] = self.len() <= t.len() ? [self, t] : [t, self]
|
||||
return self._new(filter(copy(big.to_list()), 'little.in(v:val)'))
|
||||
endfunction
|
||||
let s:_base_set.and = s:_base_set.intersection
|
||||
|
||||
"" Return the symmetric difference of two sets as a new set.
|
||||
" (I.e. all elements that are in exactly one of the sets.)
|
||||
function! s:_base_set.symmetric_difference(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self._new(filter(copy(self.to_list()), '!t.in(v:val)')
|
||||
\ + filter(copy(t.to_list()), '!self.in(v:val)'))
|
||||
endfunction
|
||||
let s:_base_set.xor = s:_base_set.symmetric_difference
|
||||
|
||||
"" Return the difference of two sets as a new Set.
|
||||
function! s:_base_set.difference(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self._new(filter(copy(self.to_list()), '!t.in(v:val)'))
|
||||
endfunction
|
||||
let s:_base_set.sub = s:_base_set.difference
|
||||
|
||||
"" Report whether another set contains this set.
|
||||
function! s:_base_set.issubset(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self.len() > t.len() ? s:FALSE
|
||||
\ : empty(filter(copy(self.to_list()), '!t.in(v:val)'))
|
||||
endfunction
|
||||
|
||||
"" Report whether this set contains another set.
|
||||
function! s:_base_set.issuperset(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self.len() < t.len() ? s:FALSE
|
||||
\ : empty(filter(copy(t.to_list()), '!self.in(v:val)'))
|
||||
endfunction
|
||||
|
||||
" less than equal & greater than equal
|
||||
let s:_base_set.le = s:_base_set.issubset
|
||||
let s:_base_set.ge = s:_base_set.issuperset
|
||||
|
||||
" less than
|
||||
function! s:_base_set.lt(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self.len() < t.len() && self.issubset(t)
|
||||
endfunction
|
||||
|
||||
" greater than
|
||||
function! s:_base_set.gt(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self.len() > t.len() && self.issuperset(t)
|
||||
endfunction
|
||||
|
||||
function! s:_base_set.len() abort
|
||||
return len(self._data)
|
||||
endfunction
|
||||
|
||||
function! s:_base_set.to_list() abort
|
||||
return values(self._data)
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._update(xs) abort
|
||||
for X in (s:_is_set(a:xs) ? a:xs.to_list() : a:xs)
|
||||
call self._add(X)
|
||||
unlet X
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._add(x) abort
|
||||
let key = self._hash(a:x)
|
||||
if !has_key(self._data, key)
|
||||
let self._data[key] = a:x
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Report whether an element is a member of a set.
|
||||
function! s:_base_set.in(x) abort
|
||||
return has_key(self._data, self._hash(a:x))
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._to_set(x) abort
|
||||
return s:_is_set(a:x) ? a:x : self._new(a:x)
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._clear() abort
|
||||
let self._data = {}
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._set_data(xs) abort
|
||||
call self._clear()
|
||||
call self._update(a:xs)
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._hash(x) abort
|
||||
return string(self._hash_func(a:x))
|
||||
endfunction
|
||||
|
||||
" frozenset: Immutable set class.
|
||||
|
||||
let s:frozenset = deepcopy(s:_base_set)
|
||||
|
||||
" Set: Mutable set class.
|
||||
|
||||
let s:set = deepcopy(s:_base_set)
|
||||
|
||||
" Update a set with the union of itself and another.
|
||||
function! s:set.update(iterable) abort
|
||||
call self._update(a:iterable)
|
||||
endfunction
|
||||
|
||||
" Update a set with the union of itself and another.
|
||||
function! s:set.ior(t) abort
|
||||
call self.update(a:t)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" Update a set with the intersection of itself and another.
|
||||
function! s:set.intersection_update(t) abort
|
||||
let r = self.and(a:t).to_list()
|
||||
call self.clear()
|
||||
call self.update(r)
|
||||
endfunction
|
||||
|
||||
" Update a set with the intersection of itself and another.
|
||||
function! s:set.iand(t) abort
|
||||
call self.intersection_update(a:t)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" Update a set with the symmetric difference of itself and another.
|
||||
function! s:set.symmetric_difference_update(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
if self is t
|
||||
call self.clear()
|
||||
return
|
||||
endif
|
||||
for X in t.to_list()
|
||||
if self.in(X)
|
||||
call self.remove(X)
|
||||
else
|
||||
call self._add(X)
|
||||
endif
|
||||
unlet X
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Update a set with the symmetric difference of itself and another.
|
||||
function! s:set.ixor(t) abort
|
||||
call self.symmetric_difference_update(a:t)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" Remove all elements of another set from this set.
|
||||
function! s:set.difference_update(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
if self is t
|
||||
call self.clear()
|
||||
return
|
||||
endif
|
||||
for X in filter(t.to_list(), 'self.in(v:val)')
|
||||
call self.remove(X)
|
||||
unlet X
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Remove all elements of another set from this set.
|
||||
function! s:set.isub(t) abort
|
||||
call self.difference_update(a:t)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" Remove all elements from this set.
|
||||
function! s:set.clear() abort
|
||||
call self._clear()
|
||||
endfunction
|
||||
|
||||
"" Add an element to a set.
|
||||
" This has no effect if the element is already present.
|
||||
function! s:set.add(x) abort
|
||||
return self._add(a:x)
|
||||
endfunction
|
||||
|
||||
"" Remove an element from a set; it must be a member.
|
||||
" If the element is not a member, throw Exception.
|
||||
function! s:set.remove(e) abort
|
||||
try
|
||||
unlet self._data[self._hash(a:e)]
|
||||
catch /^Vim\%((\a\+)\)\?:E716/
|
||||
call s:_throw('the element is not a member')
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
"" Remove an element from a set if it is a member.
|
||||
" If the element is not a member, do nothing.
|
||||
function! s:set.discard(e) abort
|
||||
try
|
||||
call self.remove(a:e)
|
||||
catch /vital: Data.Set: the element is not a member/
|
||||
" Do nothing
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Remove and return an arbitrary set element.
|
||||
function! s:set.pop() abort
|
||||
try
|
||||
let k = keys(self._data)[0]
|
||||
catch /^Vim\%((\a\+)\)\?:E684/
|
||||
call s:_throw('set is empty')
|
||||
endtry
|
||||
let v = self._data[k]
|
||||
unlet self._data[k]
|
||||
return v
|
||||
endfunction
|
||||
|
||||
" Helper:
|
||||
|
||||
function! s:_is_set(x) abort
|
||||
return type(a:x) is type({}) && get(a:x, '_is_set', s:FALSE)
|
||||
endfunction
|
||||
|
||||
function! s:_throw(message) abort
|
||||
throw 'vital: Data.Set: ' . a:message
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,126 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#HitAHint#Hint#import() abort
|
||||
return map({'create': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#HitAHint#Hint#import() abort', printf("return map({'create': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
" function() wrapper
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
let s:_function = function('function')
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
let s:_s = '<SNR>' . s:_SID() . '_'
|
||||
function! s:_function(fstr) abort
|
||||
return function(substitute(a:fstr, 's:', s:_s, 'g'))
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:_assert(...) abort
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:_vital_loaded(V) abort
|
||||
if a:V.exists('Vim.PowerAssert')
|
||||
let s:assert = a:V.import('Vim.PowerAssert').assert
|
||||
else
|
||||
let s:assert = s:_function('s:_assert')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" TERMS:
|
||||
" key: A character to generate hint. e.g. a,b,c,d,e,f,...
|
||||
" hint: A hint is a combination of keys. e.g. a,b,ab,abc,..
|
||||
|
||||
" s:create() assigns keys to each targets and generate hint dict.
|
||||
" Example:
|
||||
" let targets = [1, 2, 3, 4, 5, 6]
|
||||
" echo s:label(targets, ['a', 'b', 'c'])
|
||||
" " => {
|
||||
" 'a': 1,
|
||||
" 'b': {
|
||||
" 'a': 2,
|
||||
" 'b': 3
|
||||
" },
|
||||
" 'c': {
|
||||
" 'a': 4,
|
||||
" 'b': 5,
|
||||
" 'c': 6
|
||||
" }
|
||||
" }
|
||||
" Hint-to-target:
|
||||
" a -> 1
|
||||
" ba -> 2
|
||||
" bb -> 3
|
||||
" ca -> 4
|
||||
" cb -> 5
|
||||
" cc -> 6
|
||||
" @param {list<T>} targets
|
||||
" @param {list<string>} keys each key should be uniq
|
||||
" @return Tree{string: (T|Tree)}
|
||||
function! s:create(targets, keys) abort
|
||||
exe s:assert('len(a:keys) > 1')
|
||||
let groups = {}
|
||||
let keys_count = reverse(s:_keys_count(len(a:targets), len(a:keys)))
|
||||
|
||||
let target_idx = 0
|
||||
let key_idx = 0
|
||||
for key_count in keys_count
|
||||
if key_count > 1
|
||||
" We need to create a subgroup
|
||||
" Recurse one level deeper
|
||||
let sub_targets = a:targets[target_idx : target_idx + key_count - 1]
|
||||
let groups[a:keys[key_idx]] = s:create(sub_targets, a:keys)
|
||||
elseif key_count == 1
|
||||
" Assign single target key_idx
|
||||
let groups[a:keys[key_idx]] = a:targets[target_idx]
|
||||
else
|
||||
" No target
|
||||
continue
|
||||
endif
|
||||
let key_idx += 1
|
||||
let target_idx += key_count
|
||||
endfor
|
||||
return groups
|
||||
endfunction
|
||||
|
||||
" s:_keys_count() generates list which represents how many targets to be
|
||||
" assigned to the key.
|
||||
" If the count > 1, use tree recursively.
|
||||
" Example:
|
||||
" echo s:_keys_count(5, 3)
|
||||
" " => [3, 1, 1]
|
||||
" echo s:_keys_count(8, 3)
|
||||
" " => [3, 3, 2]
|
||||
" @param {number} target_len
|
||||
" @param {number} keys_len
|
||||
function! s:_keys_count(targets_len, keys_len) abort
|
||||
exe s:assert('a:keys_len > 1')
|
||||
let _keys_count = repeat([0], a:keys_len)
|
||||
let is_first_level = 1
|
||||
let targets_left_cnt = a:targets_len
|
||||
while targets_left_cnt > 0
|
||||
let cnt_to_add = is_first_level ? 1 : a:keys_len - 1
|
||||
for i in range(a:keys_len)
|
||||
let _keys_count[i] += cnt_to_add
|
||||
let targets_left_cnt -= cnt_to_add
|
||||
if targets_left_cnt <= 0
|
||||
let _keys_count[i] += targets_left_cnt
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
let is_first_level = 0
|
||||
endwhile
|
||||
exe s:assert('len(_keys_count) is# a:keys_len')
|
||||
return _keys_count
|
||||
endfunction
|
|
@ -0,0 +1,806 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#HitAHint#Motion#import() abort
|
||||
return map({'deepextend': '', 'gather_poses': '', 'tab2spacelen': '', 'move_f': '', 'setline': '', '_vital_depends': '', 'wincall': '', 'move': '', 'move_to_winpos': '', 'pos2hint_to_line2col2hint': '', 'gather_visible_matched_poses': '', 'move_to_win': '', 'throw': '', 'has_patch': '', 'win2pos2hint_to_w2l2c2h': '', 'move_f2': '', 'new_overwin': '', 'create_win2pos2hint': '', 'pos2poskey': '', 'winnr2poses_to_list': '', 'poskey2pos': '', 'is_in_fold': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#HitAHint#Motion#import() abort', printf("return map({'deepextend': '', 'gather_poses': '', 'tab2spacelen': '', 'move_f': '', 'setline': '', '_vital_depends': '', 'wincall': '', 'move': '', 'move_to_winpos': '', 'pos2hint_to_line2col2hint': '', 'gather_visible_matched_poses': '', 'move_to_win': '', 'throw': '', 'has_patch': '', 'win2pos2hint_to_w2l2c2h': '', 'move_f2': '', 'new_overwin': '', 'create_win2pos2hint': '', 'pos2poskey': '', 'winnr2poses_to_list': '', 'poskey2pos': '', 'is_in_fold': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
function! s:_vital_loaded(V) abort
|
||||
let s:Hint = a:V.import('HitAHint.Hint')
|
||||
let s:PHighlight = a:V.import('Palette.Highlight')
|
||||
let s:Buffer = a:V.import('Vim.Buffer')
|
||||
let s:Prelude = a:V.import('Prelude')
|
||||
let s:Set = a:V.import('Data.Set')
|
||||
let s:Input = a:V.import('Over.Input')
|
||||
endfunction
|
||||
|
||||
function! s:_vital_depends() abort
|
||||
return [
|
||||
\ 'HitAHint.Hint',
|
||||
\ 'Palette.Highlight',
|
||||
\ 'Vim.Buffer',
|
||||
\ 'Prelude',
|
||||
\ 'Data.Set',
|
||||
\ 'Over.Input',
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
let s:TRUE = !0
|
||||
let s:FALSE = 0
|
||||
let s:DIRECTION = {'forward': 0, 'backward': 1}
|
||||
|
||||
" Check Vim version
|
||||
function! s:has_patch(major, minor, patch) abort
|
||||
let l:version = (a:major * 100 + a:minor)
|
||||
return has('patch-' . a:major . '.' . a:minor . '.' . a:patch) ||
|
||||
\ (v:version > l:version) ||
|
||||
\ (v:version == l:version && 'patch' . a:patch)
|
||||
endfunction
|
||||
|
||||
" matchadd('Conceal', {pattern}, {priority}, -1, {'conceal': {char}}}) can
|
||||
" highlight pattern and conceal target correctly even if the target is keyword
|
||||
" characters.
|
||||
" - http://ftp.vim.org/vim/patches/7.4/7.4.792
|
||||
" - https://groups.google.com/forum/#!searchin/vim_dev/matchadd$20conceal/vim_dev/8bKa98GhHdk/VOzIBhd1m8YJ
|
||||
let s:can_preserve_syntax = s:has_patch(7, 4, 792)
|
||||
|
||||
" s:move() moves cursor over/across window with Hit-A-Hint feature like
|
||||
" vim-easymotion
|
||||
" @param {dict} config
|
||||
function! s:move(pattern, ...) abort
|
||||
let o = s:new_overwin(get(a:, 1, {}))
|
||||
return o.pattern(a:pattern)
|
||||
endfunction
|
||||
|
||||
function! s:move_f(...) abort
|
||||
echo 'Target: '
|
||||
let c = s:Input.getchar()
|
||||
return s:move(c, get(a:, 1, {}))
|
||||
endfunction
|
||||
|
||||
function! s:move_f2() abort
|
||||
echo 'Target: '
|
||||
let c = s:Input.getchar()
|
||||
redraw
|
||||
echo 'Target: ' . c
|
||||
let c2 = s:Input.getchar()
|
||||
return s:move(s:Prelude.escape_pattern(c . c2), get(a:, 1, {}))
|
||||
endfunction
|
||||
|
||||
|
||||
let s:overwin = {
|
||||
\ 'config': {
|
||||
\ 'keys': 'asdghklqwertyuiopzxcvbnmfj;',
|
||||
\ 'use_upper': s:FALSE,
|
||||
\ 'auto_land': s:TRUE,
|
||||
\ 'highlight': {
|
||||
\ 'shade': 'HitAHintShade',
|
||||
\ 'target': 'HitAHintTarget',
|
||||
\ 'cursor': 'HitAHintCursor',
|
||||
\ },
|
||||
\ 'jump_first_target_keys': [],
|
||||
\ 'do_shade': s:TRUE,
|
||||
\ }
|
||||
\ }
|
||||
|
||||
function! s:_init_hl() abort
|
||||
highlight default HitAHintShade ctermfg=242 guifg=#777777
|
||||
highlight default HitAHintTarget ctermfg=81 guifg=#66D9EF
|
||||
" Cursor highlight doesn't exist for some environment with some
|
||||
" colorscheme ref:#275
|
||||
" e.g.
|
||||
" - :colorscheme default
|
||||
" - :colorscheme hybrid
|
||||
if hlexists('Cursor')
|
||||
highlight default link HitAHintCursor Cursor
|
||||
else
|
||||
highlight default HitAHintCursor term=reverse cterm=reverse gui=reverse
|
||||
endif
|
||||
endfunction
|
||||
|
||||
call s:_init_hl()
|
||||
|
||||
augroup vital-hit-a-hint-motion-default-highlight
|
||||
autocmd!
|
||||
autocmd ColorScheme * call s:_init_hl()
|
||||
augroup END
|
||||
|
||||
|
||||
function! s:new_overwin(...) abort
|
||||
let o = deepcopy(s:overwin)
|
||||
call s:deepextend(o.config, get(a:, 1, {}))
|
||||
return o
|
||||
endfunction
|
||||
|
||||
function! s:overwin.pattern(pattern) abort
|
||||
let winpos = self.select_winpos(self.gather_poses_overwin(a:pattern), self.config.keys)
|
||||
if winpos is# -1
|
||||
else
|
||||
call s:move_to_winpos(winpos)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" @param {{winnr: [lnum, cnum]}}
|
||||
function! s:move_to_winpos(winpos) abort
|
||||
let [winnr_str, pos] = a:winpos
|
||||
let winnr = str2nr(winnr_str)
|
||||
let is_win_moved = !(winnr is# winnr())
|
||||
if is_win_moved
|
||||
if exists('#WinLeave')
|
||||
silent doautocmd WinLeave
|
||||
endif
|
||||
call s:move_to_win(winnr)
|
||||
else
|
||||
normal! m`
|
||||
endif
|
||||
call cursor(pos)
|
||||
if is_win_moved && exists('#WinEnter')
|
||||
silent doautocmd WinEnter
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:overwin.select_winpos(winnr2poses, keys) abort
|
||||
let wposes = s:winnr2poses_to_list(a:winnr2poses)
|
||||
if self.config.auto_land && len(wposes) is# 1
|
||||
return wposes[0]
|
||||
endif
|
||||
call self.set_options()
|
||||
try
|
||||
return self.choose_prompt(s:Hint.create(wposes, a:keys))
|
||||
finally
|
||||
call self.restore_options()
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:overwin.set_options() abort
|
||||
" s:move_to_win() takes long time if 'foldmethod' == 'syntax' or 'expr'
|
||||
let self.save_foldmethod = {}
|
||||
for winnr in range(1, winnr('$'))
|
||||
let self.save_foldmethod[winnr] = getwinvar(winnr, '&foldmethod')
|
||||
call setwinvar(winnr, '&foldmethod', 'manual')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:overwin.restore_options() abort
|
||||
for winnr in range(1, winnr('$'))
|
||||
call setwinvar(winnr, '&foldmethod', self.save_foldmethod[winnr])
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" s:wpos_to_hint() returns dict whose key is position with window and whose
|
||||
" value is the hints.
|
||||
" @param Tree{string: ((winnr, (number,number))|Tree)} hint_dict
|
||||
" @return {{winnr: {string: list<char>}}} poskey to hint for each window
|
||||
" e.g.
|
||||
" {
|
||||
" '1': {
|
||||
" '00168:00004': ['b', 'c', 'b'],
|
||||
" '00174:00001': ['b', 'c', 'a'],
|
||||
" '00188:00004': ['b', 'b'],
|
||||
" '00190:00001': ['b', 'a'],
|
||||
" '00191:00016': ['a', 'c'],
|
||||
" '00192:00004': ['a', 'b'],
|
||||
" '00195:00035': ['a', 'a']
|
||||
" },
|
||||
" '3': {
|
||||
" '00168:00004': ['c', 'c', 'c'],
|
||||
" '00174:00001': ['c', 'c', 'b'],
|
||||
" '00188:00004': ['c', 'c', 'a'],
|
||||
" '00190:00001': ['c', 'b'],
|
||||
" '00191:00016': ['c', 'a'],
|
||||
" '00192:00004': ['b', 'c', 'c']
|
||||
" }
|
||||
" }
|
||||
function! s:create_win2pos2hint(hint_dict) abort
|
||||
return s:_create_win2pos2hint({}, a:hint_dict)
|
||||
endfunction
|
||||
|
||||
function! s:_create_win2pos2hint(dict, hint_dict, ...) abort
|
||||
let prefix = get(a:, 1, [])
|
||||
for [hint, v] in items(a:hint_dict)
|
||||
if type(v) is# type({})
|
||||
call s:_create_win2pos2hint(a:dict, v, prefix + [hint])
|
||||
else
|
||||
let [winnr, pos] = v
|
||||
let a:dict[winnr] = get(a:dict, winnr, {})
|
||||
let a:dict[winnr][s:pos2poskey(pos)] = prefix + [hint]
|
||||
endif
|
||||
unlet v
|
||||
endfor
|
||||
return a:dict
|
||||
endfunction
|
||||
|
||||
" s:pos2poskey() convertes pos to poskey to use pos as dictionary keys and
|
||||
" sort pos correctly.
|
||||
" @param {(number,number)} pos
|
||||
" @return string
|
||||
" e.g. [1, 1] -> '00001:00001'
|
||||
function! s:pos2poskey(pos) abort
|
||||
return join(map(copy(a:pos), "printf('%05d', v:val)"), ':')
|
||||
endfunction
|
||||
|
||||
" s:poskey2pos() convertes poskey to pos.
|
||||
" @param {string} poskey e.g. '00001:00001'
|
||||
" @return {(number,number)}
|
||||
" e.g. '00001:00001' -> [1, 1]
|
||||
function! s:poskey2pos(poskey) abort
|
||||
return map(split(a:poskey, ':'), 'str2nr(v:val)')
|
||||
endfunction
|
||||
|
||||
function! s:overwin.choose_prompt(hint_dict) abort
|
||||
if empty(a:hint_dict)
|
||||
redraw
|
||||
echo 'No target'
|
||||
return -1
|
||||
endif
|
||||
let hinter = s:Hinter.new(a:hint_dict, self.config)
|
||||
try
|
||||
call hinter.before()
|
||||
call hinter.show_hint()
|
||||
redraw
|
||||
echo 'Target key: '
|
||||
let c = s:Input.getchar()
|
||||
if self.config.use_upper
|
||||
let c = toupper(c)
|
||||
endif
|
||||
catch
|
||||
echo v:throwpoint . ':' . v:exception
|
||||
return -1
|
||||
finally
|
||||
call hinter.after()
|
||||
endtry
|
||||
|
||||
" Jump to first target if target key is in config.jump_first_target_keys.
|
||||
if index(self.config.jump_first_target_keys, c) isnot# -1
|
||||
let c = split(self.config.keys, '\zs')[0]
|
||||
endif
|
||||
|
||||
if has_key(a:hint_dict, c)
|
||||
let target = a:hint_dict[c]
|
||||
return type(target) is# type({}) ? self.choose_prompt(target) : target
|
||||
else
|
||||
redraw
|
||||
echo 'Invalid target: ' . c
|
||||
return -1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Hinter show hints accross window.
|
||||
" save_lines: {{winnr: {lnum: string}}}
|
||||
" w2l2c2h: winnr to lnum to col num to hints. col2hints is tuple because we
|
||||
" need sorted col to hints pair.
|
||||
" save_syntax: {{winnr: &syntax}}
|
||||
" {{winnr: {lnum: list<(cnum, list<char>)>}}}
|
||||
let s:Hinter = {
|
||||
\ 'save_lines': {},
|
||||
\ 'w2l2c2h': {},
|
||||
\ 'winnrs': [],
|
||||
\ 'save_syntax': {},
|
||||
\ 'save_conceallevel': {},
|
||||
\ 'save_concealcursor': {},
|
||||
\ 'save_modified': {},
|
||||
\ 'save_modifiable': {},
|
||||
\ 'save_readonly': {},
|
||||
\ 'save_undo': {},
|
||||
\ 'highlight_ids': {},
|
||||
\ }
|
||||
|
||||
function! s:Hinter.new(hint_dict, config) abort
|
||||
let s = deepcopy(self)
|
||||
let s.config = a:config
|
||||
call s.init(a:hint_dict)
|
||||
return s
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.init(hint_dict) abort
|
||||
let win2pos2hint = s:create_win2pos2hint(a:hint_dict)
|
||||
let self.winnrs = sort(map(keys(win2pos2hint), 'str2nr(v:val)'))
|
||||
let self.win2pos2hint = win2pos2hint
|
||||
let self.w2l2c2h = s:win2pos2hint_to_w2l2c2h(win2pos2hint)
|
||||
let self.hl_target_ids = {}
|
||||
for winnr in self.winnrs
|
||||
let self.hl_target_ids[winnr] = []
|
||||
endfor
|
||||
call self._save_lines()
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.before() abort
|
||||
let self.highlight_id_cursor = matchadd(self.config.highlight.cursor, '\%#', 101)
|
||||
call self.save_options()
|
||||
call self.disable_conceal_in_other_win()
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.after() abort
|
||||
call matchdelete(self.highlight_id_cursor)
|
||||
call self.restore_env()
|
||||
call self.restore_conceal_in_other_win()
|
||||
endfunction
|
||||
|
||||
function! s:Hinter._save_lines() abort
|
||||
let nr = winnr()
|
||||
try
|
||||
for [winnr, pos2hint] in items(self.win2pos2hint)
|
||||
call s:move_to_win(winnr)
|
||||
let lnums = map(copy(keys(pos2hint)), 's:poskey2pos(v:val)[0]')
|
||||
let self.save_lines[winnr] = get(self.save_lines, winnr, {})
|
||||
for lnum in lnums
|
||||
let self.save_lines[winnr][lnum] = getline(lnum)
|
||||
endfor
|
||||
endfor
|
||||
finally
|
||||
call s:move_to_win(nr)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.restore_lines_for_win(winnr) abort
|
||||
let lnum2line = self.save_lines[a:winnr]
|
||||
for [lnum, line] in items(lnum2line)
|
||||
call s:setline(lnum, line)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.save_options() abort
|
||||
for winnr in self.winnrs
|
||||
let self.save_syntax[winnr] = getwinvar(winnr, '&syntax')
|
||||
let self.save_conceallevel[winnr] = getwinvar(winnr, '&conceallevel')
|
||||
let self.save_concealcursor[winnr] = getwinvar(winnr, '&concealcursor')
|
||||
let self.save_modified[winnr] = getwinvar(winnr, '&modified')
|
||||
let self.save_modifiable[winnr] = getwinvar(winnr, '&modifiable')
|
||||
let self.save_readonly[winnr] = getwinvar(winnr, '&readonly')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.restore_options() abort
|
||||
for winnr in self.winnrs
|
||||
call setwinvar(winnr, '&conceallevel', self.save_conceallevel[winnr])
|
||||
call setwinvar(winnr, '&concealcursor', self.save_concealcursor[winnr])
|
||||
call setwinvar(winnr, '&modified', self.save_modified[winnr])
|
||||
call setwinvar(winnr, '&modifiable', self.save_modifiable[winnr])
|
||||
call setwinvar(winnr, '&readonly', self.save_readonly[winnr])
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.modify_env_for_win(winnr) abort
|
||||
let self.save_conceal = s:PHighlight.get('Conceal')
|
||||
let self.save_undo[a:winnr] = s:undo_lock.save()
|
||||
|
||||
setlocal modifiable
|
||||
setlocal noreadonly
|
||||
|
||||
if !s:can_preserve_syntax
|
||||
ownsyntax overwin
|
||||
endif
|
||||
|
||||
setlocal conceallevel=2
|
||||
setlocal concealcursor=ncv
|
||||
|
||||
let self.highlight_ids[a:winnr] = get(self.highlight_ids, a:winnr, [])
|
||||
if self.config.do_shade
|
||||
if !s:can_preserve_syntax
|
||||
syntax clear
|
||||
endif
|
||||
let self.highlight_ids[a:winnr] += [matchadd(self.config.highlight.shade, '\_.*', 100)]
|
||||
endif
|
||||
|
||||
" XXX: other plugins specific handling
|
||||
if getbufvar('%', 'indentLine_enabled', 0)
|
||||
silent! syntax clear IndentLine
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.restore_env() abort
|
||||
call s:PHighlight.set('Conceal', self.save_conceal)
|
||||
let nr = winnr()
|
||||
try
|
||||
for winnr in self.winnrs
|
||||
call s:move_to_win(winnr)
|
||||
call self.restore_lines_for_win(winnr)
|
||||
call self.remove_hints(winnr)
|
||||
|
||||
if !s:can_preserve_syntax && self.config.do_shade
|
||||
let &syntax = self.save_syntax[winnr]
|
||||
endif
|
||||
|
||||
call self.save_undo[winnr].restore()
|
||||
|
||||
for id in self.highlight_ids[winnr]
|
||||
call matchdelete(id)
|
||||
endfor
|
||||
|
||||
" XXX: other plugins specific handling
|
||||
if getbufvar('%', 'indentLine_enabled', 0) && exists(':IndentLinesEnable') is# 2
|
||||
call setbufvar('%', 'indentLine_enabled', 0)
|
||||
:IndentLinesEnable
|
||||
endif
|
||||
endfor
|
||||
catch
|
||||
call s:throw(v:throwpoint . ' ' . v:exception)
|
||||
finally
|
||||
call s:move_to_win(nr)
|
||||
endtry
|
||||
|
||||
call self.restore_options()
|
||||
endfunction
|
||||
|
||||
let s:undo_lock = {}
|
||||
|
||||
function! s:undo_lock.save() abort
|
||||
let undo = deepcopy(self)
|
||||
call undo._save()
|
||||
return undo
|
||||
endfunction
|
||||
|
||||
function! s:undo_lock._save() abort
|
||||
if undotree().seq_last == 0
|
||||
" if there are no undo history, disable undo feature by setting
|
||||
" 'undolevels' to -1 and restore it.
|
||||
let self.save_undolevels = &l:undolevels
|
||||
let &l:undolevels = -1
|
||||
elseif !s:Buffer.is_cmdwin()
|
||||
" command line window doesn't support :wundo.
|
||||
let self.undofile = tempname()
|
||||
execute 'wundo!' self.undofile
|
||||
else
|
||||
let self.is_cmdwin = s:TRUE
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:undo_lock.restore() abort
|
||||
if has_key(self, 'save_undolevels')
|
||||
let &l:undolevels = self.save_undolevels
|
||||
endif
|
||||
if has_key(self, 'undofile') && filereadable(self.undofile)
|
||||
silent execute 'rundo' self.undofile
|
||||
call delete(self.undofile)
|
||||
endif
|
||||
if has_key(self, 'is_cmdwin')
|
||||
" XXX: it breaks undo history. AFAIK, there are no way to save and restore
|
||||
" undo history in commandline window.
|
||||
call self.undobreak()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:undo_lock.undobreak() abort
|
||||
let old_undolevels = &l:undolevels
|
||||
setlocal undolevels=-1
|
||||
keepjumps call setline('.', getline('.'))
|
||||
let &l:undolevels = old_undolevels
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.disable_conceal_in_other_win() abort
|
||||
let allwinnrs = s:Set.set(range(1, winnr('$')))
|
||||
let other_winnrs = allwinnrs.sub(self.winnrs).to_list()
|
||||
for w in other_winnrs
|
||||
if 'help' !=# getwinvar(w, '&buftype')
|
||||
call setwinvar(w, 'overwin_save_conceallevel', getwinvar(w, '&conceallevel'))
|
||||
call setwinvar(w, '&conceallevel', 0)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.restore_conceal_in_other_win() abort
|
||||
let allwinnrs = s:Set.set(range(1, winnr('$')))
|
||||
let other_winnrs = allwinnrs.sub(self.winnrs).to_list()
|
||||
for w in other_winnrs
|
||||
if 'help' !=# getwinvar(w, '&buftype')
|
||||
call setwinvar(w, '&conceallevel', getwinvar(w, 'overwin_save_conceallevel'))
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" ._pos2hint_to_line2col2hint() converts pos2hint to line2col2hint dict whose
|
||||
" key is line number and whose value is list of tuple of col number to hint.
|
||||
" line2col2hint is for show hint with replacing line by line.
|
||||
" col should be sorted.
|
||||
" @param {{string: list<char>}} pos2hint
|
||||
" @return {number: [(number, list<char>)]}
|
||||
function! s:Hinter._pos2hint_to_line2col2hint(pos2hint) abort
|
||||
let line2col2hint = {}
|
||||
let poskeys = sort(keys(a:pos2hint))
|
||||
for poskey in poskeys
|
||||
let [lnum, cnum] = s:poskey2pos(poskey)
|
||||
let line2col2hint[lnum] = get(line2col2hint, lnum, [])
|
||||
let line2col2hint[lnum] += [[cnum, a:pos2hint[poskey]]]
|
||||
endfor
|
||||
return line2col2hint
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.show_hint() abort
|
||||
let nr = winnr()
|
||||
try
|
||||
for winnr in self.winnrs
|
||||
call s:move_to_win(winnr)
|
||||
call self._show_hint_for_win(winnr)
|
||||
endfor
|
||||
finally
|
||||
call s:move_to_win(nr)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:Hinter._show_hint_for_win(winnr) abort
|
||||
call self.modify_env_for_win(a:winnr)
|
||||
|
||||
let hints = []
|
||||
for [lnum, col2hint] in items(self.w2l2c2h[a:winnr])
|
||||
let hints += self._show_hint_for_line(a:winnr, lnum, col2hint)
|
||||
endfor
|
||||
" Restore syntax and show hints after replacing all lines for performance.
|
||||
if !s:can_preserve_syntax && !self.config.do_shade
|
||||
let &l:syntax = self.save_syntax[a:winnr]
|
||||
endif
|
||||
execute 'highlight! link Conceal' self.config.highlight.target
|
||||
for [lnum, cnum, char] in hints
|
||||
call self.show_hint_pos(lnum, cnum, char, a:winnr)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:Hinter._show_hint_for_line(winnr, lnum, col2hint) abort
|
||||
let hints = [] " [lnum, cnum, char]
|
||||
let line = self.save_lines[a:winnr][a:lnum]
|
||||
let col_offset = 0
|
||||
let prev_cnum = -1
|
||||
let next_offset = 0
|
||||
for [cnum, hint] in a:col2hint
|
||||
let col_num = cnum + col_offset
|
||||
|
||||
let is_consecutive = cnum is# prev_cnum + 1
|
||||
if !is_consecutive
|
||||
let col_num += next_offset
|
||||
endif
|
||||
let save_next_offset = next_offset
|
||||
|
||||
let [line, offset, next_offset] = self._replace_line_for_hint(col_num, line, hint)
|
||||
|
||||
if is_consecutive
|
||||
let col_offset += save_next_offset
|
||||
endif
|
||||
let col_offset += offset
|
||||
|
||||
let hints = [[a:lnum, col_num, hint[0]]] + hints
|
||||
if len(hint) > 1
|
||||
let hints = [[a:lnum, col_num + 1, hint[1]]] + hints
|
||||
endif
|
||||
|
||||
let prev_cnum = cnum
|
||||
endfor
|
||||
call s:setline(a:lnum, line)
|
||||
return hints
|
||||
endfunction
|
||||
|
||||
" ._replace_line_for_hint() replaces line to show hints.
|
||||
" - It appends space if the line is empty
|
||||
" - It replaces <Tab> to space if the target character is <Tab>
|
||||
" - It replaces next target character if it's <Tab> and len(hint) > 1
|
||||
" Replacing line changes col number, so it returns offset of col number.
|
||||
" As for replaceing next target character, the timing to calculate offset
|
||||
" depends on the col number of next hint in the same line, so it returns
|
||||
" `next_offset` instead of returning offset all at once.
|
||||
" @return {(string, number, number)} (line, offset, next_offset)
|
||||
function! s:Hinter._replace_line_for_hint(col_num, line, hint) abort
|
||||
let line = a:line
|
||||
let col_num = a:col_num
|
||||
let do_replace_target = !(self.config.do_shade || s:can_preserve_syntax)
|
||||
let target = matchstr(line, '\%' . col_num .'c.')
|
||||
" Append one space for empty line or match at end of line
|
||||
if target is# ''
|
||||
let hintwidth = strdisplaywidth(join(a:hint[:1], ''))
|
||||
let char = do_replace_target ? ' ' : '.'
|
||||
let line .= repeat(char, hintwidth)
|
||||
return [line, hintwidth, 0]
|
||||
endif
|
||||
|
||||
let offset = 0
|
||||
if target is# "\t"
|
||||
let [line, offset] = self._replace_tab_target(col_num, line)
|
||||
elseif strdisplaywidth(target) > 1
|
||||
let line = self._replace_text_to_space(line, col_num, strdisplaywidth(target))
|
||||
let offset = strdisplaywidth(target) - len(target)
|
||||
else
|
||||
if do_replace_target
|
||||
" The priority of :syn-cchar is always under the priority of keywords.
|
||||
" So, Hit-A-Hint replaces targets character with '.'.
|
||||
let space = '.'
|
||||
let line = substitute(line, '\%' . col_num . 'c.', space, '')
|
||||
let offset = len(space) - len(target)
|
||||
endif
|
||||
endif
|
||||
|
||||
let next_offset = 0
|
||||
if len(a:hint) > 1 && target isnot# "\t"
|
||||
" pass [' '] as hint to stop recursion.
|
||||
let [line, next_offset, _] = self._replace_line_for_hint(col_num + offset + 1, line, [' '])
|
||||
endif
|
||||
return [line, offset, next_offset]
|
||||
endfunction
|
||||
|
||||
" @return {(line, offset)}
|
||||
function! s:Hinter._replace_tab_target(col_num, line) abort
|
||||
let space_len = s:tab2spacelen(a:line, a:col_num)
|
||||
let line = self._replace_text_to_space(a:line, a:col_num, space_len)
|
||||
return [line, space_len - 1]
|
||||
endfunction
|
||||
|
||||
function! s:Hinter._replace_text_to_space(line, col_num, len) abort
|
||||
let target = printf('\%%%dc.', a:col_num)
|
||||
let line = substitute(a:line, target, repeat(' ', a:len), '')
|
||||
return line
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.show_hint_pos(lnum, cnum, char, winnr) abort
|
||||
let p = '\%'. a:lnum . 'l\%'. a:cnum . 'c.'
|
||||
if s:can_preserve_syntax
|
||||
let self.hl_target_ids[a:winnr] += [matchadd('Conceal', p, 101, -1, {'conceal': a:char})]
|
||||
else
|
||||
exec "syntax match HitAHintTarget '". p . "' contains=NONE containedin=.* conceal cchar=". a:char
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.remove_hints(winnr) abort
|
||||
if s:can_preserve_syntax
|
||||
for id in self.hl_target_ids[a:winnr]
|
||||
call matchdelete(id)
|
||||
endfor
|
||||
else
|
||||
" Clear syntax defined by Hit-A-Hint motion before restoring syntax.
|
||||
syntax clear HitAHintTarget
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" @param {number} col_num col_num is 1 origin like col()
|
||||
function! s:tab2spacelen(line, col_num) abort
|
||||
let before_line = a:col_num > 2 ? a:line[: a:col_num - 2]
|
||||
\ : a:col_num is# 2 ? a:line[0]
|
||||
\ : ''
|
||||
let vcol_num = 1
|
||||
for c in split(before_line, '\zs')
|
||||
let vcol_num += c is# "\t" ? s:_virtual_tab2spacelen(vcol_num) : len(c)
|
||||
endfor
|
||||
return s:_virtual_tab2spacelen(vcol_num)
|
||||
endfunction
|
||||
|
||||
function! s:_virtual_tab2spacelen(col_num) abort
|
||||
return &tabstop - ((a:col_num - 1) % &tabstop)
|
||||
endfunction
|
||||
|
||||
function! s:win2pos2hint_to_w2l2c2h(win2pos2hint) abort
|
||||
let w2l2c2h = {}
|
||||
for [winnr, pos2hint] in items(a:win2pos2hint)
|
||||
let w2l2c2h[winnr] = s:pos2hint_to_line2col2hint(pos2hint)
|
||||
endfor
|
||||
return w2l2c2h
|
||||
endfunction
|
||||
|
||||
" s:pos2hint_to_line2col2hint() converts pos2hint to line2col2hint dict whose
|
||||
" key is line number and whose value is list of tuple of col number to hint.
|
||||
" line2col2hint is for show hint with replacing line by line.
|
||||
" col should be sorted.
|
||||
" @param {{string: list<char>}} pos2hint
|
||||
" @return {number: [(number, list<char>)]}
|
||||
function! s:pos2hint_to_line2col2hint(pos2hint) abort
|
||||
let line2col2hint = {}
|
||||
let poskeys = sort(keys(a:pos2hint))
|
||||
for poskey in poskeys
|
||||
let [lnum, cnum] = s:poskey2pos(poskey)
|
||||
let line2col2hint[lnum] = get(line2col2hint, lnum, [])
|
||||
let line2col2hint[lnum] += [[cnum, a:pos2hint[poskey]]]
|
||||
endfor
|
||||
return line2col2hint
|
||||
endfunction
|
||||
|
||||
" @param {number} winnr
|
||||
function! s:move_to_win(winnr) abort
|
||||
if a:winnr !=# winnr()
|
||||
execute 'noautocmd' a:winnr . 'wincmd w'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" @param {regex} pattern
|
||||
" @return {{winnr: list<list<(number,number))>}}
|
||||
function! s:overwin.gather_poses_overwin(pattern) abort
|
||||
return s:wincall(function('s:gather_poses'), [a:pattern])
|
||||
endfunction
|
||||
|
||||
" s:gather_poses() aggregates patterm matched positions in visible current
|
||||
" window for both direction excluding poses in fold.
|
||||
" @return {{list<list<(number,number))>}}
|
||||
function! s:gather_poses(pattern) abort
|
||||
let f = s:gather_visible_matched_poses(a:pattern, s:DIRECTION.forward, s:TRUE)
|
||||
let b = s:gather_visible_matched_poses(a:pattern, s:DIRECTION.backward, s:FALSE)
|
||||
return filter(f + b, '!s:is_in_fold(v:val[0])')
|
||||
endfunction
|
||||
|
||||
" s:gather_visible_matched_poses() aggregates pattern matched positions in visible current
|
||||
" window.
|
||||
" @param {regex} pattern
|
||||
" @param {enum<DIRECTION>} direction see s:DIRECTION
|
||||
" @param {bool} allow_cursor_pos_match
|
||||
" @return {list<list<(number,number)>>} positions
|
||||
function! s:gather_visible_matched_poses(pattern, direction, allow_cursor_pos_match) abort
|
||||
let stop_line = line(a:direction is# s:DIRECTION.forward ? 'w$' : 'w0')
|
||||
let search_flag = (a:direction is# s:DIRECTION.forward ? '' : 'b')
|
||||
let c_flag = a:allow_cursor_pos_match ? 'c' : ''
|
||||
let view = winsaveview()
|
||||
let poses = []
|
||||
keepjumps let pos = searchpos(a:pattern, c_flag . search_flag, stop_line)
|
||||
while pos != [0, 0]
|
||||
let poses += [pos]
|
||||
keepjumps let pos = searchpos(a:pattern, search_flag, stop_line)
|
||||
endwhile
|
||||
call winrestview(view)
|
||||
return poses
|
||||
endfunction
|
||||
|
||||
" @param {{winnr: list<list<(number,number))>}} winnr2poses
|
||||
" @param {number?} first_winnr the top winnr poses in returned list
|
||||
" @return {list<{list<(winnr, (number,number))}>}
|
||||
function! s:winnr2poses_to_list(winnr2poses, ...) abort
|
||||
let first_winnr = get(a:, 1, winnr())
|
||||
let first_winnr_poses = []
|
||||
let other_poses = []
|
||||
for [winnr_str, poses] in items(a:winnr2poses)
|
||||
let winnr = str2nr(winnr_str)
|
||||
if winnr is# first_winnr
|
||||
let first_winnr_poses = map(copy(poses), '[winnr, v:val]')
|
||||
else
|
||||
let other_poses += map(copy(poses), '[winnr, v:val]')
|
||||
endif
|
||||
endfor
|
||||
return first_winnr_poses + other_poses
|
||||
endfunction
|
||||
|
||||
" @param {number} lnum line number
|
||||
function! s:is_in_fold(lnum) abort
|
||||
return foldclosed(a:lnum) != -1
|
||||
endfunction
|
||||
|
||||
" @param {funcref} func
|
||||
" @param {arglist} list<S>
|
||||
" @param {dict?} dict for :h call()
|
||||
" @return {{winnr: <T>}}
|
||||
function! s:wincall(func, arglist, ...) abort
|
||||
let dict = get(a:, 1, {})
|
||||
let r = {}
|
||||
let start_winnr = winnr()
|
||||
let r[start_winnr] = call(a:func, a:arglist, dict)
|
||||
if s:Buffer.is_cmdwin()
|
||||
return r
|
||||
endif
|
||||
noautocmd wincmd w
|
||||
while winnr() isnot# start_winnr
|
||||
let r[winnr()] = call(a:func, a:arglist, dict)
|
||||
noautocmd wincmd w
|
||||
endwhile
|
||||
return r
|
||||
endfunction
|
||||
|
||||
" deepextend (nest: 1)
|
||||
function! s:deepextend(expr1, expr2) abort
|
||||
let expr2 = copy(a:expr2)
|
||||
for [k, V] in items(a:expr1)
|
||||
if (type(V) is type({}) || type(V) is type([])) && has_key(expr2, k)
|
||||
let a:expr1[k] = extend(a:expr1[k], expr2[k])
|
||||
unlet expr2[k]
|
||||
endif
|
||||
unlet V
|
||||
endfor
|
||||
return extend(a:expr1, expr2)
|
||||
endfunction
|
||||
|
||||
function! s:setline(lnum, text) abort
|
||||
if getline(a:lnum) isnot# a:text
|
||||
call setline(a:lnum, a:text)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:throw(message) abort
|
||||
throw 'vital: HitAHint.Motion: ' . a:message
|
||||
endfunction
|
||||
|
|
@ -0,0 +1,606 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Base#import() abort
|
||||
return map({'_vital_depends': '', 'make_plain': '', 'is_input_waiting': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Base#import() abort', printf("return map({'_vital_depends': '', 'make_plain': '', 'is_input_waiting': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:String = s:V.import("Over.String")
|
||||
let s:Signals = s:V.import("Over.Signals")
|
||||
let s:Input = s:V.import("Over.Input")
|
||||
let s:Keymapping = s:V.import("Over.Keymapping")
|
||||
let s:Module = s:V.import("Over.Commandline.Modules")
|
||||
let s:base.variables.modules = s:Signals.make()
|
||||
function! s:base.variables.modules.get_slot(val)
|
||||
return a:val.slot.module
|
||||
endfunction
|
||||
|
||||
let s:Highlight = s:V.import("Palette.Highlight")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Over.String",
|
||||
\ "Over.Signals",
|
||||
\ "Over.Input",
|
||||
\ "Over.Keymapping",
|
||||
\ "Over.Commandline.Modules",
|
||||
\ "Palette.Highlight",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(...)
|
||||
let result = deepcopy(s:base)
|
||||
call result.set_prompt(get(a:, 1, ":"))
|
||||
call result.connect(result, "_")
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make_plain()
|
||||
return deepcopy(s:base)
|
||||
endfunction
|
||||
|
||||
|
||||
let s:base = {
|
||||
\ "line" : {},
|
||||
\ "variables" : {
|
||||
\ "prompt" : "",
|
||||
\ "char" : "",
|
||||
\ "input" : "",
|
||||
\ "tap_key" : "",
|
||||
\ "exit" : 0,
|
||||
\ "keymapping" : {},
|
||||
\ "suffix" : "",
|
||||
\ "is_setted" : 0,
|
||||
\ },
|
||||
\ "highlights" : {
|
||||
\ "prompt" : "NONE",
|
||||
\ "cursor" : "VitalOverCommandLineCursor",
|
||||
\ "cursor_on" : "VitalOverCommandLineCursorOn",
|
||||
\ "cursor_insert" : "VitalOverCommandLineOnCursor",
|
||||
\ },
|
||||
\}
|
||||
|
||||
if exists("s:Signals")
|
||||
let s:base.variables.modules = s:Signals.make()
|
||||
function! s:base.variables.modules.get_slot(val)
|
||||
return a:val.slot.module
|
||||
endfunction
|
||||
endif
|
||||
|
||||
|
||||
function! s:base.getline()
|
||||
return self.line.str()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.setline(line)
|
||||
return self.line.set(a:line)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.char()
|
||||
return self.variables.char
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.setchar(char, ...)
|
||||
" 1 の場合は既に設定されていても上書きする
|
||||
" 0 の場合は既に設定されていれば上書きしない
|
||||
let overwrite = get(a:, 1, 1)
|
||||
if overwrite || self.variables.is_setted == 0
|
||||
let self.variables.input = a:char
|
||||
let self.variables.is_setted = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.getpos()
|
||||
return self.line.pos()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.setpos(pos)
|
||||
return self.line.set_pos(a:pos)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.tap_keyinput(key)
|
||||
let self.variables.tap_key = a:key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.untap_keyinput(key)
|
||||
if self.variables.tap_key == a:key
|
||||
let self.variables.tap_key = ""
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_tap_key()
|
||||
return self.variables.tap_key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.is_input(key, ...)
|
||||
let prekey = get(a:, 1, "")
|
||||
return self.get_tap_key() ==# prekey
|
||||
\ && self.char() ==# a:key
|
||||
" \ && self.char() == (prekey . a:key)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.input_key()
|
||||
return self.variables.input_key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.set_prompt(prompt)
|
||||
let self.variables.prompt = a:prompt
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_prompt()
|
||||
return self.variables.prompt
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.set_suffix(str)
|
||||
let self.variables.suffix = a:str
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_suffix()
|
||||
return self.variables.suffix
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.insert(word, ...)
|
||||
if a:0
|
||||
call self.line.set(a:1)
|
||||
endif
|
||||
call self.line.input(a:word)
|
||||
endfunction
|
||||
|
||||
function! s:base.forward()
|
||||
return self.line.forward()
|
||||
endfunction
|
||||
|
||||
function! s:base.backward()
|
||||
return self.line.backward()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.backward_word(...)
|
||||
let pat = get(a:, 1, '\k\+\s*\|.')
|
||||
return matchstr(self.backward(), '\%(' . pat . '\)$')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.connect(module, ...)
|
||||
if type(a:module) == type("")
|
||||
return call(self.connect, [s:Module.make(a:module)] + a:000, self)
|
||||
endif
|
||||
if empty(a:module)
|
||||
return
|
||||
endif
|
||||
let name = a:0 > 0 ? a:1 : a:module.name
|
||||
let slot = self.variables.modules.find_first_by("get(v:val.slot, 'name', '') == " . string(name))
|
||||
if empty(slot)
|
||||
call self.variables.modules.connect({ "name" : name, "module" : a:module })
|
||||
else
|
||||
let slot.slot.module = a:module
|
||||
endif
|
||||
" let self.variables.modules[name] = a:module
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.disconnect(name)
|
||||
return self.variables.modules.disconnect_by(
|
||||
\ "get(v:val.slot, 'name', '') == " . string(a:name)
|
||||
\ )
|
||||
" unlet self.variables.modules[a:name]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_module(name)
|
||||
let slot = self.variables.modules.find_first_by("get(v:val.slot, 'name', '') == " . string(a:name))
|
||||
return empty(slot) ? {} : slot.slot.module
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.callevent(event)
|
||||
call self.variables.modules.sort_by("has_key(v:val.slot.module, 'priority') ? v:val.slot.module.priority('" . a:event . "') : 0")
|
||||
return self.variables.modules.call(a:event, [self])
|
||||
" call map(filter(copy(self.variables.modules), "has_key(v:val, a:event)"), "v:val." . a:event . "(self)")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.cmap(lhs, rhs)
|
||||
let self.variables.keymapping[a:lhs] = a:rhs
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.cnoremap(lhs, rhs)
|
||||
let key = s:Keymapping.as_key_config(a:rhs)
|
||||
let key.noremap = 1
|
||||
let self.variables.keymapping[a:lhs] = key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.cunmap(lhs)
|
||||
unlet self.variables.keymapping[a:lhs]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.keymapping()
|
||||
return self.__keymapping__()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__keymapping__()
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.execute(...)
|
||||
let command = get(a:, 1, self.getline())
|
||||
call self.__execute(command)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.draw()
|
||||
call self.callevent("on_draw_pre")
|
||||
call self.callevent("on_draw")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.exit(...)
|
||||
let self.variables.exit = 1
|
||||
let self.variables.exit_code = get(a:, 1, 0)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.enable_keymapping()
|
||||
let self.variables.enable_keymapping = 1
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.disable_keymapping()
|
||||
let self.variables.enable_keymapping = 0
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.is_enable_keymapping()
|
||||
return self.variables.enable_keymapping
|
||||
endfunction
|
||||
|
||||
" function! s:base.cancel()
|
||||
" call self.exit(1)
|
||||
" call self.__on_cancel()
|
||||
" endfunction
|
||||
|
||||
|
||||
function! s:base.exit_code()
|
||||
return self.variables.exit_code
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.hl_cursor_on()
|
||||
if exists("self.variables.old_guicursor")
|
||||
set guicursor&
|
||||
let &guicursor = self.variables.old_guicursor
|
||||
unlet self.variables.old_guicursor
|
||||
endif
|
||||
|
||||
if exists("self.variables.old_t_ve")
|
||||
let &t_ve = self.variables.old_t_ve
|
||||
unlet self.variables.old_t_ve
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.hl_cursor_off()
|
||||
if exists("self.variables.old_t_ve")
|
||||
return
|
||||
endif
|
||||
|
||||
let self.variables.old_guicursor = &guicursor
|
||||
set guicursor=n:block-NONE
|
||||
let self.variables.old_t_ve = &t_ve
|
||||
set t_ve=
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.start(...)
|
||||
let exit_code = call(self.__main, a:000, self)
|
||||
return exit_code
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__empty(...)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get(...)
|
||||
let Old_execute = self.execute
|
||||
let self.execute = self.__empty
|
||||
try
|
||||
let exit_code = call(self.start, a:000, self)
|
||||
if exit_code == 0
|
||||
return self.getline()
|
||||
endif
|
||||
finally
|
||||
let self.execute = Old_execute
|
||||
endtry
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.input_key_stack()
|
||||
return self.variables.input_key_stack
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.input_key_stack_string()
|
||||
return join(self.variables.input_key_stack, "")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.set_input_key_stack(stack)
|
||||
let self.variables.input_key_stack = a:stack
|
||||
return self.variables.input_key_stack
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.input_key_stack_pop()
|
||||
return remove(self.input_key_stack(), 0)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.getchar(...)
|
||||
if empty(self.input_key_stack())
|
||||
return call(s:Input.getchar, a:000, s:Input)
|
||||
endif
|
||||
return self.input_key_stack_pop()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__init_variables()
|
||||
let self.variables.tap_key = ""
|
||||
let self.variables.char = ""
|
||||
let self.variables.input = ""
|
||||
let self.variables.exit = 0
|
||||
let self.variables.exit_code = 1
|
||||
let self.variables.enable_keymapping = 1
|
||||
let self.variables.input_key_stack = []
|
||||
let self.line = deepcopy(s:String.make())
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_is_valid_highlight(name)
|
||||
let highlight = s:Highlight.get(a:name)
|
||||
if empty(highlight)
|
||||
return 0
|
||||
endif
|
||||
|
||||
if has("gui_running")
|
||||
\ && (has_key(highlight, "guifg") || has_key(highlight, "guibg"))
|
||||
return 1
|
||||
elseif (has_key(highlight, "ctermfg") || has_key(highlight, "ctermbg"))
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__init()
|
||||
call self.__init_variables()
|
||||
call self.hl_cursor_off()
|
||||
if !hlexists(self.highlights.cursor)
|
||||
if s:_is_valid_highlight("Cursor")
|
||||
execute "highlight link " . self.highlights.cursor . " Cursor"
|
||||
else
|
||||
" Workaround by CUI Vim Cursor Highlight
|
||||
" issues #92
|
||||
" https://github.com/osyo-manga/vital-over/issues/92
|
||||
execute "highlight " . self.highlights.cursor . " term=reverse cterm=reverse gui=reverse"
|
||||
endif
|
||||
endif
|
||||
if !hlexists(self.highlights.cursor_on)
|
||||
execute "highlight link " . self.highlights.cursor_on . " " . self.highlights.cursor
|
||||
endif
|
||||
if !hlexists(self.highlights.cursor_insert)
|
||||
execute "highlight " . self.highlights.cursor_insert . " cterm=underline term=underline gui=underline"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__execute(command)
|
||||
call self.callevent("on_execute_pre")
|
||||
try
|
||||
call self.__execute__(a:command)
|
||||
catch
|
||||
echohl ErrorMsg
|
||||
echom matchstr(v:exception, 'Vim\((\w*)\)\?:\zs.*\ze')
|
||||
echohl None
|
||||
call self.callevent("on_execute_failed")
|
||||
finally
|
||||
call self.callevent("on_execute")
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__execute__(cmd)
|
||||
execute a:cmd
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__input_char(char)
|
||||
let char = a:char
|
||||
let self.variables.input_key = char
|
||||
let self.variables.char = char
|
||||
call self.setchar(self.variables.char)
|
||||
let self.variables.is_setted = 0
|
||||
call self.callevent("on_char_pre")
|
||||
call self.insert(self.variables.input)
|
||||
call self.callevent("on_char")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__input(input, ...)
|
||||
if a:input == ""
|
||||
return
|
||||
endif
|
||||
|
||||
let self.variables.input_key = a:input
|
||||
if a:0 == 0
|
||||
let keymapping = self.__get_keymapping()
|
||||
else
|
||||
let keymapping = a:1
|
||||
endif
|
||||
if self.is_enable_keymapping()
|
||||
let key = s:Keymapping.unmapping(keymapping, a:input)
|
||||
else
|
||||
let key = a:input
|
||||
endif
|
||||
if key == ""
|
||||
return
|
||||
endif
|
||||
|
||||
call self.set_input_key_stack(s:String.split_by_keys(key))
|
||||
while !(empty(self.input_key_stack()) || self.is_exit())
|
||||
call self.__input_char(self.input_key_stack_pop())
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:is_input_waiting(keymapping, input)
|
||||
let num = len(filter(copy(a:keymapping), 'stridx(v:key, a:input) == 0'))
|
||||
return num > 1 || (num == 1 && !has_key(a:keymapping, a:input))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__inputting()
|
||||
if !self.is_enable_keymapping()
|
||||
return self.__input(s:Input.getchar())
|
||||
endif
|
||||
|
||||
let input = s:Input.getchar()
|
||||
let old_line = self.getline()
|
||||
let old_pos = self.getpos()
|
||||
let keymapping = self.__get_keymapping()
|
||||
try
|
||||
let t = reltime()
|
||||
while s:is_input_waiting(keymapping, input)
|
||||
\ && str2nr(reltimestr(reltime(t))) * 1000 < &timeoutlen
|
||||
call self.setline(old_line)
|
||||
call self.insert(input)
|
||||
call self.setpos(old_pos)
|
||||
call self.draw()
|
||||
let input .= s:Input.getchar(0)
|
||||
endwhile
|
||||
finally
|
||||
call self.setline(old_line)
|
||||
call self.setpos(old_pos)
|
||||
endtry
|
||||
call self.__input(input, keymapping)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__update()
|
||||
" call self.callevent("on_update")
|
||||
" if !getchar(1)
|
||||
" continue
|
||||
" endif
|
||||
"
|
||||
" call self.__input(s:getchar(0))
|
||||
" call self.draw()
|
||||
|
||||
call self.callevent("on_update")
|
||||
call self.__inputting()
|
||||
" call self.__input(s:Input.getchar())
|
||||
if self.is_exit()
|
||||
return -1
|
||||
endif
|
||||
call self.draw()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__main(...)
|
||||
try
|
||||
call self.__init()
|
||||
call self.callevent("on_enter")
|
||||
|
||||
call self.__input(get(a:, 1, ""))
|
||||
call self.draw()
|
||||
while !self.is_exit()
|
||||
try
|
||||
if self.__update()
|
||||
break
|
||||
endif
|
||||
catch
|
||||
call self.callevent("on_exception")
|
||||
endtry
|
||||
endwhile
|
||||
catch
|
||||
echohl ErrorMsg | echom v:throwpoint . " " . v:exception | echohl None
|
||||
let self.variables.exit_code = -1
|
||||
finally
|
||||
call self.__finish()
|
||||
call self.callevent("on_leave")
|
||||
endtry
|
||||
return self.exit_code()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__finish()
|
||||
call self.hl_cursor_on()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__is_exit()
|
||||
return self.is_exit()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.is_exit()
|
||||
return self.variables.exit
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__get_keymapping()
|
||||
let result = {}
|
||||
" for module in values(self.variables.modules)
|
||||
for module in self.variables.modules.slots()
|
||||
if has_key(module, "keymapping")
|
||||
if module isnot self
|
||||
call extend(result, module.keymapping(self))
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
return extend(extend(result, self.variables.keymapping), self.keymapping())
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,42 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#import() abort
|
||||
return map({'get': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#import() abort', printf("return map({'get': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:get(name)
|
||||
if exists("s:" . a:name)
|
||||
return s:{a:name}
|
||||
endif
|
||||
let s:{a:name} = s:V.import('Over.Commandline.Modules.' . a:name)
|
||||
return s:{a:name}
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(name, ...)
|
||||
let module = s:get(a:name)
|
||||
return call(module.make, a:000, module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,179 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#BufferComplete#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#BufferComplete#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_uniq(list)
|
||||
let dict = {}
|
||||
for _ in a:list
|
||||
let dict[_] = 0
|
||||
endfor
|
||||
return keys(dict)
|
||||
endfunction
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "BufferComplete",
|
||||
\}
|
||||
|
||||
|
||||
function! s:_buffer_complete()
|
||||
return sort(s:_uniq(filter(split(join(getline(1, '$')), '\W'), '!empty(v:val)')), 1)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_parse_line(line)
|
||||
let keyword = matchstr(a:line, '\zs\w\+\ze$')
|
||||
let pos = strchars(a:line) - strchars(keyword)
|
||||
return [pos, keyword]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_as_statusline(list, count)
|
||||
if empty(a:list)
|
||||
return
|
||||
endif
|
||||
let hl_none = "%#StatusLine#"
|
||||
let hl_select = "%#StatusLineNC#"
|
||||
let tail = " > "
|
||||
let result = a:list[0]
|
||||
let pos = 0
|
||||
for i in range(1, len(a:list)-1)
|
||||
if strdisplaywidth(result . " " . a:list[i]) > &columns - len(tail)
|
||||
if a:count < i
|
||||
break
|
||||
else
|
||||
let pos = -i
|
||||
endif
|
||||
let result = a:list[i]
|
||||
else
|
||||
let result .= (" " . a:list[i])
|
||||
endif
|
||||
if a:count == i
|
||||
let pos = pos + i
|
||||
endif
|
||||
endfor
|
||||
return join(map(split(result, " "), 'v:key == pos ? hl_select . v:val . hl_none : v:val'))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.get_complete_words()
|
||||
return s:_buffer_complete()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.complete(cmdline)
|
||||
call s:_finish()
|
||||
let s:old_statusline = &statusline
|
||||
|
||||
let backward = a:cmdline.backward()
|
||||
let [pos, keyword] = s:_parse_line(backward)
|
||||
|
||||
if !exists("s:complete")
|
||||
let s:complete = self.get_complete_words()
|
||||
endif
|
||||
let s:complete_list = filter(copy(s:complete), 'v:val =~ ''^''.keyword')
|
||||
if empty(s:complete_list)
|
||||
return -1
|
||||
endif
|
||||
|
||||
if pos == 0
|
||||
let backward = ""
|
||||
else
|
||||
let backward = join(split(backward, '\zs')[ : pos-1 ], "")
|
||||
endif
|
||||
let s:line = backward . a:cmdline.forward()
|
||||
let s:pos = pos
|
||||
call a:cmdline.setline(s:line)
|
||||
|
||||
let s:count = 0
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_finish()
|
||||
if exists("s:old_statusline")
|
||||
let &statusline = s:old_statusline
|
||||
unlet s:old_statusline
|
||||
redrawstatus
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("<Over>(buffer-complete)")
|
||||
\ || a:cmdline.is_input("<Over>(buffer-complete-prev)")
|
||||
if self.complete(a:cmdline) == -1
|
||||
call s:_finish()
|
||||
call a:cmdline.setchar('')
|
||||
return
|
||||
endif
|
||||
if a:cmdline.is_input("<Over>(buffer-complete-prev)")
|
||||
let s:count = len(s:complete_list) - 1
|
||||
endif
|
||||
call a:cmdline.setchar('')
|
||||
call a:cmdline.tap_keyinput("Completion")
|
||||
" elseif a:cmdline.is_input("\<Tab>", "Completion")
|
||||
elseif a:cmdline.is_input("<Over>(buffer-complete)", "Completion")
|
||||
\ || a:cmdline.is_input("\<Right>", "Completion")
|
||||
call a:cmdline.setchar('')
|
||||
let s:count += 1
|
||||
if s:count >= len(s:complete_list)
|
||||
let s:count = 0
|
||||
endif
|
||||
elseif a:cmdline.is_input("<Over>(buffer-complete-prev)", "Completion")
|
||||
\ || a:cmdline.is_input("\<Left>", "Completion")
|
||||
call a:cmdline.setchar('')
|
||||
let s:count -= 1
|
||||
if s:count < 0
|
||||
let s:count = len(s:complete_list) - 1
|
||||
endif
|
||||
else
|
||||
if a:cmdline.untap_keyinput("Completion")
|
||||
call a:cmdline.callevent("on_char_pre")
|
||||
endif
|
||||
call s:_finish()
|
||||
return
|
||||
endif
|
||||
call a:cmdline.setline(s:line)
|
||||
call a:cmdline.insert(s:complete_list[s:count], s:pos)
|
||||
if len(s:complete_list) > 1
|
||||
let &statusline = s:_as_statusline(s:complete_list, s:count)
|
||||
redrawstatus
|
||||
endif
|
||||
if len(s:complete_list) == 1
|
||||
call a:cmdline.untap_keyinput("Completion")
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_draw_pre(...)
|
||||
" redrawstatus
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_leave(cmdline)
|
||||
call s:_finish()
|
||||
unlet! s:complete
|
||||
endfunction
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,40 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Cancel#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Cancel#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Cancel"
|
||||
\}
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("\<Esc>")
|
||||
\ || a:cmdline.is_input("\<C-c>")
|
||||
" call a:cmdline.cancel()
|
||||
call a:cmdline.exit(1)
|
||||
call a:cmdline.setchar("")
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,58 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#CursorMove#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#CursorMove#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "CursorMove"
|
||||
\}
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("\<Right>")
|
||||
call a:cmdline.line.next()
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<Left>")
|
||||
call a:cmdline.line.prev()
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-b>")
|
||||
\ || a:cmdline.is_input("\<Home>")
|
||||
call a:cmdline.setline(0)
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-e>")
|
||||
\ || a:cmdline.is_input("\<End>")
|
||||
call a:cmdline.setline(a:cmdline.line.length())
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-Left>")
|
||||
\ || a:cmdline.is_input("\<S-Left>")
|
||||
call a:cmdline.setline(strridx(a:cmdline.backward()[:-2], ' ') + 1)
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-Right>")
|
||||
\ || a:cmdline.is_input("\<S-Right>")
|
||||
let p = stridx(a:cmdline.forward()[1:], ' ')
|
||||
call a:cmdline.setline(p != -1 ? a:cmdline.line.pos() + p + 2 : a:cmdline.line.length())
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,56 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Delete#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Delete#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Delete",
|
||||
\}
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("\<C-h>")
|
||||
\ || a:cmdline.is_input("\<BS>")
|
||||
if a:cmdline.line.length() == 0
|
||||
return a:cmdline.exit(1)
|
||||
else
|
||||
call a:cmdline.line.remove_prev()
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
elseif a:cmdline.is_input("\<Del>")
|
||||
call a:cmdline.line.remove_pos()
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-w>")
|
||||
let word = a:cmdline.backward_word()
|
||||
let backward = a:cmdline.backward()[ : -strlen(word)-1 ]
|
||||
call a:cmdline.setline(backward . a:cmdline.line.pos_char() . a:cmdline.forward())
|
||||
call a:cmdline.setline(strchars(backward))
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-u>")
|
||||
call a:cmdline.setline(a:cmdline.line.pos_char() . a:cmdline.forward())
|
||||
call a:cmdline.setline(0)
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,121 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Doautocmd#import() abort
|
||||
return map({'_vital_depends': '', 'doautocmd_user': '', 'get_cmdline': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Doautocmd#import() abort', printf("return map({'_vital_depends': '', 'doautocmd_user': '', 'get_cmdline': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:E = s:V.import("Over.Exception")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Over.Exception",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
let s:cache_command = {}
|
||||
function! s:doautocmd_user(prefix, command)
|
||||
let group = a:prefix . "-vital-over-commandline-doautocmd-dummy"
|
||||
if !has_key(s:cache_command, a:prefix)
|
||||
let s:cache_command[a:prefix] = {}
|
||||
endif
|
||||
|
||||
if !has_key(s:cache_command[a:prefix], a:command)
|
||||
execute "autocmd " . group
|
||||
\ . " User " . a:command." silent! execute ''"
|
||||
|
||||
if v:version > 703 || v:version == 703 && has("patch438")
|
||||
let s:cache_command[a:prefix][a:command] = "doautocmd <nomodeline> User " . a:command
|
||||
else
|
||||
let s:cache_command[a:prefix][a:command] = "doautocmd User " . a:command
|
||||
endif
|
||||
endif
|
||||
|
||||
execute s:cache_command[a:prefix][a:command]
|
||||
endfunction
|
||||
|
||||
|
||||
let s:hooks = [
|
||||
\ "enter",
|
||||
\ "leave",
|
||||
\ "char",
|
||||
\ "char_pre",
|
||||
\ "draw",
|
||||
\ "draw_pre",
|
||||
\ "execute_pre",
|
||||
\ "execute_failed",
|
||||
\ "execute",
|
||||
\ "exception",
|
||||
\]
|
||||
|
||||
let s:hooks_camel = [
|
||||
\ "Enter",
|
||||
\ "Leave",
|
||||
\ "Char",
|
||||
\ "CharPre",
|
||||
\ "Draw",
|
||||
\ "DrawPre",
|
||||
\ "ExecutePre",
|
||||
\ "ExecuteFailed",
|
||||
\ "Execute",
|
||||
\ "Exception",
|
||||
\]
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Doautocmd",
|
||||
\}
|
||||
|
||||
|
||||
for s:i in range(len(s:hooks))
|
||||
execute join([
|
||||
\ "function! s:module.on_" . s:hooks[s:i] . "(cmdline, ...)",
|
||||
\ " let s:cmdline = a:cmdline",
|
||||
\ " call s:doautocmd_user(self.prefix, self.prefix . " . string(s:hooks_camel[s:i]) . ")",
|
||||
\ "endfunction",
|
||||
\ ], "\n")
|
||||
endfor
|
||||
|
||||
|
||||
function! s:get_cmdline()
|
||||
if !exists("s:cmdline")
|
||||
execute s:E.throw_cmd("Undefined cmdline object.", "Over.Commandline.Modules.Doautocmd")
|
||||
endif
|
||||
return s:cmdline
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(prefix)
|
||||
if has_key(s:cache_command, a:prefix)
|
||||
unlet! s:cache_command[a:prefix]
|
||||
endif
|
||||
execute "augroup " a:prefix . "-vital-over-commandline-doautocmd-dummy"
|
||||
autocmd!
|
||||
augroup END
|
||||
|
||||
let module = deepcopy(s:module)
|
||||
let module.prefix = a:prefix
|
||||
return module
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,155 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#DrawCommandline#import() abort
|
||||
return map({'suffix': '', 'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#DrawCommandline#import() abort', printf("return map({'suffix': '', 'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "DrawCommandline"
|
||||
\}
|
||||
|
||||
let s:cmdheight = {}
|
||||
|
||||
function! s:cmdheight.save()
|
||||
if has_key(self, "value")
|
||||
return
|
||||
endif
|
||||
let self.value = &cmdheight
|
||||
endfunction
|
||||
|
||||
function! s:cmdheight.restore()
|
||||
if has_key(self, "value")
|
||||
let &cmdheight = self.value
|
||||
unlet self.value
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:cmdheight.get()
|
||||
return self.value
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:suffix(left, suffix)
|
||||
let left_len = strdisplaywidth(a:left)
|
||||
let len = &columns - left_len % &columns
|
||||
let len = len + (&columns * (strdisplaywidth(a:suffix) > (len - 1))) - 1
|
||||
return repeat(" ", len - strdisplaywidth(a:suffix)) . a:suffix
|
||||
" return printf("%" . len . "S", a:suffix)
|
||||
endfunction
|
||||
|
||||
|
||||
let s:old_width = 0
|
||||
function! s:_redraw(cmdline)
|
||||
let left = a:cmdline.get_prompt() . a:cmdline.getline() . (empty(a:cmdline.line.pos_char()) ? " " : "")
|
||||
let width = len(left) + 1
|
||||
|
||||
if a:cmdline.get_suffix() != ""
|
||||
let width += len(s:suffix(left, a:cmdline.get_suffix())) - 1
|
||||
endif
|
||||
|
||||
if &columns >= width && &columns <= s:old_width && s:old_width >= width
|
||||
redraw
|
||||
normal! :
|
||||
elseif &columns <= width
|
||||
normal! :
|
||||
else
|
||||
redraw
|
||||
endif
|
||||
let s:old_width = width
|
||||
|
||||
call s:cmdheight.save()
|
||||
let height = max([(width - 1) / (&columns) + 1, s:cmdheight.get()])
|
||||
if height > &cmdheight || &cmdheight > height
|
||||
let &cmdheight = height
|
||||
redraw
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_as_echon(str)
|
||||
return "echon " . strtrans(string(a:str))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_draw_pre(cmdline)
|
||||
if empty(a:cmdline.line.pos_char())
|
||||
let cursor = "echohl " . a:cmdline.highlights.cursor . " | echon ' '"
|
||||
else
|
||||
let cursor = "echohl " . a:cmdline.highlights.cursor_on . " | " . s:_as_echon(a:cmdline.line.pos_char())
|
||||
endif
|
||||
let suffix = ""
|
||||
if a:cmdline.get_suffix() != ""
|
||||
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()))
|
||||
endif
|
||||
let self.draw_command = join([
|
||||
\ "echohl " . a:cmdline.highlights.prompt,
|
||||
\ s:_as_echon(a:cmdline.get_prompt()),
|
||||
\ "echohl NONE",
|
||||
\ s:_as_echon(a:cmdline.backward()),
|
||||
\ cursor,
|
||||
\ "echohl NONE",
|
||||
\ s:_as_echon(a:cmdline.forward()),
|
||||
\ suffix,
|
||||
\ ], " | ")
|
||||
|
||||
call s:_redraw(a:cmdline)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_echon(expr)
|
||||
echon strtrans(a:expr)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_draw(cmdline)
|
||||
execute self.draw_command
|
||||
" execute "echohl" a:cmdline.highlights.prompt
|
||||
" call s:echon(a:cmdline.get_prompt())
|
||||
" echohl NONE
|
||||
" call s:echon(a:cmdline.backward())
|
||||
" if empty(a:cmdline.line.pos_char())
|
||||
" execute "echohl" a:cmdline.highlights.cursor
|
||||
" call s:echon(' ')
|
||||
" else
|
||||
" execute "echohl" a:cmdline.highlights.cursor_on
|
||||
" call s:echon(a:cmdline.line.pos_char())
|
||||
" endif
|
||||
" echohl NONE
|
||||
" call s:echon(a:cmdline.forward())
|
||||
" if a:cmdline.get_suffix() != ""
|
||||
" call s:echon(s:suffix(a:cmdline.get_prompt() . a:cmdline.getline() . repeat(" ", empty(a:cmdline.line.pos_char())), a:cmdline.get_suffix()))
|
||||
" endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_execute_pre(...)
|
||||
call s:cmdheight.restore()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_leave(...)
|
||||
call s:cmdheight.restore()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,37 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#ExceptionExit#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#ExceptionExit#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "ExceptionExit",
|
||||
\}
|
||||
|
||||
|
||||
function! s:module.on_exception(cmdline)
|
||||
call a:cmdline.exit(-1)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(...)
|
||||
let result = deepcopy(s:module)
|
||||
let result.exit_code = get(a:, 1, 0)
|
||||
return result
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,66 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#ExceptionMessage#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#ExceptionMessage#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:vname = expand("<sfile>:h:h:h:h:t")
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "ExceptionMessage",
|
||||
\}
|
||||
|
||||
|
||||
function! s:module.on_exception(cmdline)
|
||||
let self.exception = v:exception
|
||||
let self.throwpoint = v:throwpoint
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_draw_pre(cmdline)
|
||||
if has_key(self, "exception")
|
||||
call self.message(a:cmdline)
|
||||
unlet self.exception
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:module.message(...)
|
||||
echohl ErrorMsg
|
||||
execute self.command string(self.prefix . " : " . self.throwpoint . " " . self.exception)
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_leave(cmdline)
|
||||
if has_key(self, "exception")
|
||||
call self.message(a:cmdline)
|
||||
unlet self.exception
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(...)
|
||||
let result = deepcopy(s:module)
|
||||
let result.prefix = get(a:, 1, "vital-over(".s:vname.") Exception")
|
||||
let result.command = get(a:, 2, "echom")
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,40 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Exit#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Exit#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Exit",
|
||||
\ "exit_code" : 0
|
||||
\}
|
||||
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("<Over>(exit)")
|
||||
call a:cmdline.setchar("")
|
||||
call a:cmdline.exit(self.exit_code)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,75 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#History#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#History#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "History",
|
||||
\ "mode" : "cmd",
|
||||
\}
|
||||
|
||||
function! s:module.histories()
|
||||
return map(range(1, &history), 'histget(self.mode, v:val * -1)')
|
||||
endfunction
|
||||
|
||||
function! s:_should_match_cmdline(cmdline)
|
||||
return a:cmdline.is_input("\<Up>")
|
||||
\ || a:cmdline.is_input("\<Down>")
|
||||
endfunction
|
||||
|
||||
function! s:_reset()
|
||||
let s:cmdhist = []
|
||||
let s:count = 0
|
||||
let s:is_match_mode = 0 " <Up>/<Down>: true, <C-n>/<C-p>: false
|
||||
endfunction
|
||||
|
||||
function! s:module.on_enter(...)
|
||||
call s:_reset()
|
||||
endfunction
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if !a:cmdline.is_input("\<Up>") && !a:cmdline.is_input("\<Down>")
|
||||
\ && !a:cmdline.is_input("\<C-p>") && !a:cmdline.is_input("\<C-n>")
|
||||
call s:_reset()
|
||||
return
|
||||
else
|
||||
if s:count == 0 && empty(s:cmdhist)
|
||||
\ || s:is_match_mode != s:_should_match_cmdline(a:cmdline)
|
||||
let cmdline = '^' . a:cmdline.getline()
|
||||
let s:is_match_mode = s:_should_match_cmdline(a:cmdline)
|
||||
let s:cmdhist = [a:cmdline.getline()] + (s:is_match_mode ?
|
||||
\ filter(self.histories(), 'v:val =~ cmdline') : self.histories())
|
||||
endif
|
||||
endif
|
||||
call a:cmdline.setchar("")
|
||||
if a:cmdline.is_input("\<Down>") || a:cmdline.is_input("\<C-n>")
|
||||
let s:count = max([s:count - 1, 0])
|
||||
endif
|
||||
if a:cmdline.is_input("\<Up>") || a:cmdline.is_input("\<C-p>")
|
||||
let s:count = min([s:count + 1, len(s:cmdhist)])
|
||||
endif
|
||||
call a:cmdline.setline(get(s:cmdhist, s:count, a:cmdline.getline()))
|
||||
endfunction
|
||||
|
||||
function! s:make(...)
|
||||
let module = deepcopy(s:module)
|
||||
let module.mode = get(a:, 1, "cmd")
|
||||
return module
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,164 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#InsertRegister#import() abort
|
||||
return map({'_vital_depends': '', 'to_string': '', 'input': '', 'get_cmdline_cword': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
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('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:String = s:V.import("Over.String")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Over.String",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:to_string(expr)
|
||||
return type(a:expr) == type("") ? a:expr : string(a:expr)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:input(cmdline)
|
||||
let CR_index = index(a:cmdline.input_key_stack(), "\<CR>")
|
||||
if CR_index != -1
|
||||
let input = a:cmdline.input_key_stack_string()
|
||||
let input = input[ : CR_index-1]
|
||||
call a:cmdline.set_input_key_stack(a:cmdline.input_key_stack()[CR_index+1 : ])
|
||||
return eval(input)
|
||||
endif
|
||||
|
||||
let input_text = ""
|
||||
if !empty(a:cmdline.input_key_stack())
|
||||
let input_text = a:cmdline.input_key_stack_string()
|
||||
call a:cmdline.set_input_key_stack([])
|
||||
endif
|
||||
|
||||
call a:cmdline.hl_cursor_on()
|
||||
try
|
||||
redraw
|
||||
let input = input("=", input_text, "expression")
|
||||
if !empty(input)
|
||||
let input = s:to_string(eval(input))
|
||||
endif
|
||||
catch
|
||||
return ""
|
||||
finally
|
||||
call a:cmdline.hl_cursor_off()
|
||||
endtry
|
||||
return input
|
||||
endfunction
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "InsertRegister"
|
||||
\}
|
||||
|
||||
|
||||
|
||||
function! s:module.reset()
|
||||
let self.cword = expand("<cword>")
|
||||
let self.cWORD = expand("<cWORD>")
|
||||
let self.cfile = expand("<cfile>")
|
||||
endfunction
|
||||
|
||||
function! s:module.on_enter(...)
|
||||
call self.reset()
|
||||
" let self.prefix_key = ""
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:get_cmdline_cword(backward, cword)
|
||||
" let backward = matchstr(a:backward, '.\{-}\zs\k\+$')
|
||||
let backward = a:backward
|
||||
if &incsearch == 0 || a:cword == "" || a:backward == "" || s:String.index(a:cword, backward) != 0
|
||||
return a:cword
|
||||
endif
|
||||
return a:cword[len(backward) : ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("\<C-r>")
|
||||
call a:cmdline.setchar('"')
|
||||
let self.prefix_key = a:cmdline.input_key()
|
||||
let self.old_line = a:cmdline.getline()
|
||||
let self.old_pos = a:cmdline.getpos()
|
||||
return
|
||||
elseif exists("self.prefix_key")
|
||||
\ && a:cmdline.get_tap_key() == self.prefix_key
|
||||
call a:cmdline.setline(self.old_line)
|
||||
call a:cmdline.setpos(self.old_pos)
|
||||
let char = a:cmdline.input_key()
|
||||
if char =~ '^[0-9a-zA-z.%#:/"\-*+]$'
|
||||
let register = tr(getreg(char), "\n", "\r")
|
||||
call a:cmdline.setchar(register)
|
||||
elseif char == "="
|
||||
call a:cmdline.setchar(s:input(a:cmdline))
|
||||
elseif char == "\<C-w>"
|
||||
call a:cmdline.setchar(s:get_cmdline_cword(a:cmdline.backward_word(), self.cword))
|
||||
elseif char == "\<C-a>"
|
||||
call a:cmdline.setchar(self.cWORD)
|
||||
elseif char == "\<C-f>"
|
||||
call a:cmdline.setchar(self.cfile)
|
||||
elseif char == "\<C-r>"
|
||||
call a:cmdline.setchar('"')
|
||||
else
|
||||
call a:cmdline.setchar("")
|
||||
endif
|
||||
" elseif a:cmdline.is_input('=', self.prefix_key)
|
||||
" call a:cmdline.setchar(s:input(a:cmdline))
|
||||
" elseif a:cmdline.is_input("\<C-w>", self.prefix_key)
|
||||
" call a:cmdline.setchar(self.cword)
|
||||
" elseif a:cmdline.is_input("\<C-a>", self.prefix_key)
|
||||
" call a:cmdline.setchar(self.cWORD)
|
||||
" elseif a:cmdline.is_input("\<C-f>", self.prefix_key)
|
||||
" call a:cmdline.setchar(self.cfile)
|
||||
" elseif a:cmdline.is_input("\<C-r>", self.prefix_key)
|
||||
" call a:cmdline.setchar('"')
|
||||
" else
|
||||
" call a:cmdline.setchar("")
|
||||
" endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char(cmdline)
|
||||
if a:cmdline.is_input("\<C-r>")
|
||||
call a:cmdline.tap_keyinput(self.prefix_key)
|
||||
call a:cmdline.disable_keymapping()
|
||||
call a:cmdline.setpos(a:cmdline.getpos()-1)
|
||||
else
|
||||
if exists("self.prefix_key")
|
||||
call a:cmdline.untap_keyinput(self.prefix_key)
|
||||
call a:cmdline.enable_keymapping()
|
||||
unlet! self.prefix_key
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,139 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#KeyMapping#import() abort
|
||||
return map({'_vital_depends': '', 'make_emacs': '', 'make_vim_cmdline_mapping': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
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('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:Keymapping = a:V.import("Palette.Keymapping")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Palette.Keymapping",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
let s:emacs = {
|
||||
\ "name" : "KeyMapping_emacs_like"
|
||||
\}
|
||||
|
||||
function! s:emacs.keymapping(cmdline)
|
||||
return {
|
||||
\ "\<C-f>" : {
|
||||
\ "key" : "\<Right>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-b>" : {
|
||||
\ "key" : "\<Left>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-n>" : {
|
||||
\ "key" : "\<Down>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-p>" : {
|
||||
\ "key" : "\<Up>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-a>" : {
|
||||
\ "key" : "\<Home>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-e>" : {
|
||||
\ "key" : "\<End>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-d>" : {
|
||||
\ "key" : "\<Del>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<A-d>" : {
|
||||
\ "key" : "\<C-w>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<A-b>" : {
|
||||
\ "key" : "\<S-Left>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<A-f>" : {
|
||||
\ "key" : "\<S-Right>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make_emacs()
|
||||
return deepcopy(s:emacs)
|
||||
endfunction
|
||||
|
||||
|
||||
let s:vim_cmdline_mapping = {
|
||||
\ "name" : "KeyMapping_vim_cmdline_mapping",
|
||||
\ "_cmaps" : {}
|
||||
\}
|
||||
|
||||
function! s:_convert_sid(rhs, sid) abort
|
||||
return substitute(a:rhs, '<SID>', '<SNR>' . a:sid . '_', 'g')
|
||||
endfunction
|
||||
|
||||
function! s:_auto_cmap()
|
||||
let cmaps = {}
|
||||
let cmap_info = s:Keymapping.rhs_key_list("c", 0, 1)
|
||||
" vital-over currently doesn't support <buffer> mappings
|
||||
for c in filter(cmap_info, "v:val['buffer'] ==# 0")
|
||||
let cmaps[s:Keymapping.escape_special_key(c['lhs'])] = {
|
||||
\ 'noremap' : c['noremap'],
|
||||
\ 'key' : s:Keymapping.escape_special_key(s:_convert_sid(c['rhs'], c['sid'])),
|
||||
\ 'expr' : s:Keymapping.escape_special_key(c['expr']),
|
||||
\ }
|
||||
endfor
|
||||
return cmaps
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:vim_cmdline_mapping.on_enter(cmdline)
|
||||
let self._cmaps = s:_auto_cmap()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:vim_cmdline_mapping.keymapping(cmdline)
|
||||
return self._cmaps
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make_vim_cmdline_mapping()
|
||||
return deepcopy(s:vim_cmdline_mapping)
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,55 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#NoInsert#import() abort
|
||||
return map({'make_special_chars': '', 'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#NoInsert#import() abort', printf("return map({'make_special_chars': '', 'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "NoInsert",
|
||||
\ "chars" : []
|
||||
\}
|
||||
|
||||
|
||||
function! s:module.is_no_insert(char)
|
||||
return index(self.chars, a:char) >= 0
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if self.is_no_insert(a:cmdline.char())
|
||||
call a:cmdline.setchar("", 0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(chars)
|
||||
let module = deepcopy(s:module)
|
||||
let module.chars = type(a:chars) == type([]) ? a:chars : [a:chars]
|
||||
return module
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make_special_chars()
|
||||
let module = s:make([])
|
||||
function! module.is_no_insert(char)
|
||||
return char2nr(a:char) == 128 || char2nr(a:char) < 27
|
||||
endfunction
|
||||
return module
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,40 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Paste#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Paste#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Paste"
|
||||
\}
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("<Over>(paste)")
|
||||
let register = v:register == "" ? '"' : v:register
|
||||
call a:cmdline.insert(tr(getreg("*"), "\n", "\r"))
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,72 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Redraw#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Redraw#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Redraw",
|
||||
\}
|
||||
|
||||
function! s:module.on_execute_pre(cmdline)
|
||||
call self.redraw(a:cmdline)
|
||||
endfunction
|
||||
|
||||
function! s:module.on_enter(...)
|
||||
let self.is_execute = 0
|
||||
endfunction
|
||||
|
||||
function! s:module.on_execute(...)
|
||||
let self.is_execute = 1
|
||||
endfunction
|
||||
|
||||
function! s:module.on_execute_failed(...)
|
||||
let self.is_execute = 0
|
||||
endfunction
|
||||
|
||||
function! s:module.on_leave(cmdline)
|
||||
if self.is_execute == 0 && a:cmdline.exit_code() != -1
|
||||
call self.redraw(a:cmdline)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
" function! s:module.on_draw_pre(cmdline)
|
||||
" call self.redraw(a:cmdline)
|
||||
" endfunction
|
||||
|
||||
|
||||
function! s:module.redraw(cmdline)
|
||||
redraw
|
||||
" Workaround for the :set cedit=<C-c>
|
||||
" https://github.com/osyo-manga/vital-over/issues/52
|
||||
" https://github.com/Lokaltog/vim-easymotion/issues/177#issuecomment-53663431
|
||||
if &cedit != "<C-c>"
|
||||
\ ||(v:version > 704 || v:version == 704 && has("patch441"))
|
||||
normal! :
|
||||
else
|
||||
execute "normal! :\<Esc>"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,46 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Exception#import() abort
|
||||
return map({'throw': '', 'throw_cmd': '', 'set_prefix': '', 'error': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Exception#import() abort', printf("return map({'throw': '', 'throw_cmd': '', 'set_prefix': '', 'error': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:vname = expand("<sfile>:h:h:t")
|
||||
let s:prefix = printf("vital-over(%s) Exception", s:vname)
|
||||
|
||||
function! s:set_prefix(prefix)
|
||||
let s:prefix = a:prefix
|
||||
endfunction
|
||||
|
||||
function! s:throw_cmd(exp, where)
|
||||
return 'throw ' . string(s:prefix . " : " . a:exp . " in " . a:where)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:throw(exp, where)
|
||||
execute s:throw_cmd(a:exp, a:where)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:error(text, where)
|
||||
echohl ErrorMsg
|
||||
echom s:prefix . " : " . a:text . " in " . a:where
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,40 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Input#import() abort
|
||||
return map({'getchar': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Input#import() abort', printf("return map({'getchar': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:getchar(...)
|
||||
let mode = get(a:, 1, 0)
|
||||
while 1
|
||||
" Workaround for https://github.com/osyo-manga/vital-over/issues/53
|
||||
try
|
||||
let char = call("getchar", a:000)
|
||||
catch /^Vim:Interrupt$/
|
||||
let char = 3 " <C-c>
|
||||
endtry
|
||||
" Workaround for the <expr> mappings
|
||||
if string(char) !=# "\x80\xfd`"
|
||||
return mode == 1 ? !!char
|
||||
\ : type(char) == type(0) ? nr2char(char) : char
|
||||
endif
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,95 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Keymapping#import() abort
|
||||
return map({'_vital_depends': '', 'unmapping': '', 'as_key_config': '', 'match_key': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Keymapping#import() abort', printf("return map({'_vital_depends': '', 'unmapping': '', 'as_key_config': '', 'match_key': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:String = s:V.import("Over.String")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Over.String",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:as_key_config(config)
|
||||
let base = {
|
||||
\ "noremap" : 0,
|
||||
\ "lock" : 0,
|
||||
\ "expr" : 0,
|
||||
\ }
|
||||
return type(a:config) == type({}) ? extend(base, a:config)
|
||||
\ : extend(base, {
|
||||
\ "key" : a:config,
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:match_key(keymapping, key)
|
||||
let keys = sort(keys(a:keymapping))
|
||||
return get(filter(keys, 'stridx(a:key, v:val) == 0'), -1, '')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_safe_eval(expr, ...)
|
||||
call extend(l:, get(a:, 1, {}))
|
||||
let result = get(a:, 2, "")
|
||||
try
|
||||
let result = eval(a:expr)
|
||||
catch
|
||||
echohl ErrorMsg | echom v:exception | echohl None
|
||||
endtry
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_get_key(conf)
|
||||
" call extend(l:, a:conf)
|
||||
let self = a:conf
|
||||
return get(a:conf, "expr", 0) ? s:_safe_eval(a:conf.key, l:) : a:conf.key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:unmapping(keymapping, key, ...)
|
||||
let is_locking = get(a:, 1, 0)
|
||||
let key = s:match_key(a:keymapping, a:key)
|
||||
if key == ""
|
||||
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)
|
||||
endif
|
||||
|
||||
let map_conf = s:as_key_config(a:keymapping[key])
|
||||
|
||||
let next_input = s:unmapping(a:keymapping, a:key[len(key) : ], is_locking)
|
||||
if map_conf.lock == 0 && is_locking
|
||||
return key . next_input
|
||||
elseif map_conf.lock
|
||||
return s:unmapping(a:keymapping, s:_get_key(map_conf), is_locking) . next_input
|
||||
else
|
||||
return s:unmapping(a:keymapping, s:_get_key(map_conf), map_conf.noremap) . next_input
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,119 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Signals#import() abort
|
||||
return map({'_vital_depends': '', 'call': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Signals#import() abort', printf("return map({'_vital_depends': '', 'call': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:L = s:V.import("Data.List")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return ["Data.List"]
|
||||
endfunction
|
||||
|
||||
|
||||
let s:base = {
|
||||
\ "variables" : {
|
||||
\ "slots" : [],
|
||||
\ "counter" : 0,
|
||||
\ }
|
||||
\}
|
||||
|
||||
|
||||
function! s:base.connect(slot)
|
||||
let self.variables.counter += 1
|
||||
let slot = { "id" : self.variables.counter, "slot" : a:slot }
|
||||
call add(self.variables.slots, slot)
|
||||
return slot
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.disconnect(slot)
|
||||
if empty(a:slot)
|
||||
return -1
|
||||
endif
|
||||
for i in range(len(self.variables.slots))
|
||||
if self.variables.slots[i].id == a:slot.id
|
||||
unlet self.variables.slots[i]
|
||||
return
|
||||
endif
|
||||
endfor
|
||||
return -1
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.disconnect_by(expr)
|
||||
return self.disconnect(self.find_first_by(a:expr))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:call(list, func, ...)
|
||||
let args = get(a:, 1, [])
|
||||
let def = get(a:, 2, 0)
|
||||
return map(copy(a:list), "has_key(v:val, a:func) ? call(v:val.".a:func.", args, v:val) : def")
|
||||
endfunction
|
||||
|
||||
function! s:base.call(func, ...)
|
||||
return call("s:call", [self.slots(), a:func] + a:000)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.find_by(expr)
|
||||
return filter(copy(self.variables.slots), a:expr)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.find_first_by(expr)
|
||||
return get(self.find_by(a:expr), 0, {})
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.sort_by(expr)
|
||||
let self.variables.slots = s:L.sort_by(self.variables.slots, a:expr)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_slot(val)
|
||||
return a:val.slot
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.slots()
|
||||
return map(copy(self.variables.slots), "self.get_slot(v:val)")
|
||||
endfunction
|
||||
|
||||
|
||||
" function! s:base.dict()
|
||||
" let result = {}
|
||||
" for _ in self.variables.slots
|
||||
" let result[_.id] = _.value
|
||||
" endfor
|
||||
" return result
|
||||
" endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
let result = deepcopy(s:base)
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,164 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#String#import() abort
|
||||
return map({'_vital_depends': '', 'length': '', 'index': '', 'split_by_keys': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#String#import() abort', printf("return map({'_vital_depends': '', 'length': '', 'index': '', 'split_by_keys': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:List = s:V.import("Data.List")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Data.List",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_clamp(x, max, min)
|
||||
return min([max([a:x, a:max]), a:min])
|
||||
endfunction
|
||||
|
||||
|
||||
let s:base = {}
|
||||
|
||||
function! s:base.set(item)
|
||||
return type(a:item) == type("") ? self.set_str(a:item)
|
||||
\ : type(a:item) == type(0) ? self.set_pos(a:item)
|
||||
\ : self
|
||||
endfunction
|
||||
|
||||
function! s:base.str()
|
||||
return join(self.list, "")
|
||||
endfunction
|
||||
|
||||
function! s:base.set_pos(pos)
|
||||
let self.col = s:_clamp(a:pos, 0, self.length())
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! s:base.backward()
|
||||
return self.col > 0 ? join(self.list[ : self.col-1], '') : ""
|
||||
endfunction
|
||||
|
||||
function! s:base.forward()
|
||||
return join(self.list[self.col+1 : ], '')
|
||||
endfunction
|
||||
|
||||
function! s:base.pos_char()
|
||||
return get(self.list, self.col, "")
|
||||
endfunction
|
||||
|
||||
function! s:base.set_str(str)
|
||||
let self.list = split(a:str, '\zs')
|
||||
let self.col = strchars(a:str)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! s:base.pos()
|
||||
return self.col
|
||||
endfunction
|
||||
|
||||
function! s:base.input(str)
|
||||
call extend(self.list, split(a:str, '\zs'), self.col)
|
||||
let self.col += len(split(a:str, '\zs'))
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! s:base.length()
|
||||
return len(self.list)
|
||||
endfunction
|
||||
|
||||
function! s:base.next()
|
||||
return self.set_pos(self.col + 1)
|
||||
endfunction
|
||||
|
||||
function! s:base.prev()
|
||||
return self.set_pos(self.col - 1)
|
||||
endfunction
|
||||
|
||||
function! s:base.remove(index)
|
||||
if a:index < 0 || self.length() <= a:index
|
||||
return ""
|
||||
endif
|
||||
let result = self.list[a:index]
|
||||
unlet self.list[a:index]
|
||||
if a:index < self.col
|
||||
call self.set(self.col - 1)
|
||||
endif
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:base.remove_pos()
|
||||
return self.remove(self.col)
|
||||
endfunction
|
||||
|
||||
function! s:base.remove_prev()
|
||||
return self.remove(self.col - 1)
|
||||
endfunction
|
||||
|
||||
function! s:base.remove_next()
|
||||
return self.remove(self.col + 1)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(...)
|
||||
let default = get(a:, 1, "")
|
||||
let result = deepcopy(s:base)
|
||||
call result.set(default)
|
||||
return result
|
||||
endfunction
|
||||
|
||||
" NOTE: old regexpengine has a bug with string which contains binary
|
||||
" :echo "\x80" =~ "\\%#=1\x80" | " => 0
|
||||
" But it matches correctly with :h /collection
|
||||
" :echo "\x80" =~ "\\%#=1[\x80]" | " => 1
|
||||
" http://lingr.com/room/vim/archives/2015/02/13#message-21261450
|
||||
let s:_engine = exists("+regexpengine") ? '\%#=2' : ''
|
||||
" \<A-]> => Û\xfdQ
|
||||
" \<A-@> => À\xfeX
|
||||
let s:_regex = exists("+regexpengine")
|
||||
\ ? "\\%(Û\xfdQ\\|À\xfeX\\|\x80\xfc.\\%(\x80..\\|.\\)\\|\x80..\\|.\\)\\zs"
|
||||
\ : "\\%(Û[\xfd]Q\\|À[\xfe]X\\|[\x80][\xfc].\\%([\x80]..\\|.\\)\\|[\x80]..\\|.\\)\\zs"
|
||||
function! s:_split_keystring(str, ...)
|
||||
return split(a:str, s:_engine . '\m\%(' . get(a:, 1, '') . s:_regex . '\)')
|
||||
endfunction
|
||||
|
||||
function! s:split_by_keys(str)
|
||||
return s:_split_keystring(a:str, "\\%(\<Plug>\\|<Over>\\)(.\\{-})\\zs\\|")
|
||||
endfunction
|
||||
|
||||
function! s:index(haystack, needle, ...)
|
||||
let start = get(a:, 1, 0)
|
||||
let ignorecase = get(a:, 2, &ignorecase)
|
||||
if ignorecase
|
||||
return stridx(tolower(a:haystack), tolower(a:needle), start)
|
||||
else
|
||||
return stridx(a:haystack, a:needle, start)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:length(str)
|
||||
return len(s:split_by_keys(a:str))
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,74 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Palette#Capture#import() abort
|
||||
return map({'extend': '', 'command': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Palette#Capture#import() abort', printf("return map({'extend': '', 'command': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:verbosefiles = []
|
||||
|
||||
function! s:_verbosefile_push(file)
|
||||
call add(s:verbosefiles, &verbosefile)
|
||||
let &verbosefile = a:file
|
||||
return a:file
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_verbosefile_pop()
|
||||
let filename = &verbosefile
|
||||
let &verbosefile = get(s:verbosefiles, -1)
|
||||
call remove(s:verbosefiles, -1)
|
||||
return filename
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_reset()
|
||||
let s:verbosefiles = []
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:extend(dict, src)
|
||||
for [key, value] in items(a:src)
|
||||
let a:dict[key] = value
|
||||
unlet value
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:command(cmd, ...)
|
||||
" Workaround : Vim 7.3.xxx in Travis and Ubuntu
|
||||
" https://github.com/osyo-manga/vital-palette/issues/5
|
||||
" call extend(l:, get(a:, 1, {}))
|
||||
if a:0 > 0
|
||||
call s:extend(l:, a:1)
|
||||
endif
|
||||
|
||||
call s:_verbosefile_push(tempname())
|
||||
try
|
||||
redir =>result
|
||||
silent execute a:cmd
|
||||
finally
|
||||
redir END
|
||||
endtry
|
||||
call s:_verbosefile_pop()
|
||||
" let result = substitute(result, "<SRN>", "\<SNR>", "g")
|
||||
" let result = substitute(result, "<SID>", "\<SID>", "g")
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,133 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Palette#Highlight#import() abort
|
||||
return map({'capture': '', '_vital_depends': '', 'parse': '', 'group_list': '', 'set': '', 'parse_to_name': '', 'links_to': '', 'get': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
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('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:Message = s:V.import("Vim.Message")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Vim.Message",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_execute(cmd)
|
||||
execute a:cmd
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:capture(name)
|
||||
if hlexists(a:name) == 0
|
||||
return ""
|
||||
endif
|
||||
return s:Message.capture("highlight " . a:name)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:links_to(highlight)
|
||||
return matchstr(a:highlight, '^\S\+\s\+xxx links to \zs.*\ze$')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:parse_to_name(highlight)
|
||||
return matchstr(a:highlight, '^\zs\w\+\ze')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:parse(highlight)
|
||||
let highlight = a:highlight
|
||||
|
||||
if highlight !~# '^\w\+\s\+xxx\s'
|
||||
return {}
|
||||
endif
|
||||
|
||||
let name = s:parse_to_name(a:highlight)
|
||||
let result = { "_name" : name }
|
||||
|
||||
if highlight =~# '^\w\+\s\+xxx cleared'
|
||||
let result.cleared = 1
|
||||
return result
|
||||
endif
|
||||
|
||||
let link = s:links_to(highlight)
|
||||
if link != ""
|
||||
let result.link = link
|
||||
return result
|
||||
endif
|
||||
|
||||
let attrs = [
|
||||
\ "term",
|
||||
\ "cterm",
|
||||
\ "ctermfg",
|
||||
\ "ctermbg",
|
||||
\ "gui",
|
||||
\ "font",
|
||||
\ "guifg",
|
||||
\ "guibg",
|
||||
\ "guisp",
|
||||
\ ]
|
||||
for attr in attrs
|
||||
let item = matchstr(highlight, '\s' . attr . '=\zs#\?\w\+\ze')
|
||||
if item != ""
|
||||
let result[attr] = item
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:get(name, ...)
|
||||
if !hlexists(a:name)
|
||||
return {}
|
||||
endif
|
||||
let result = s:parse(substitute(s:capture(a:name), "\n", "", "g"))
|
||||
if has_key(result, "link") && get(a:, 1, 0)
|
||||
return s:get(result.link, get(a:, 1, 0))
|
||||
else
|
||||
return result
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:set(name, config)
|
||||
if type(a:config) == type("")
|
||||
return s:set(a:config, s:get(a:config))
|
||||
endif
|
||||
if has_key(a:config, "cleared")
|
||||
return s:_execute("highlight clear " . a:name)
|
||||
endif
|
||||
if has_key(a:config, "link")
|
||||
return s:_execute("highlight link " . a:name . " " . a:config.link)
|
||||
endif
|
||||
return s:_execute("highlight " . a:name . " " . join(map(items(filter(a:config, "v:key !=# '_name'")), "v:val[0] . '=' . v:val[1]"), " "))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:group_list()
|
||||
let highlights = split(s:Message.capture("highlight"), "\n")
|
||||
return filter(map(highlights, "s:parse_to_name(v:val)"), "v:val != ''")
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,121 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Palette#Keymapping#import() abort
|
||||
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)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
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('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:modep = "[nvoicsxl]"
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:Capture = s:V.import("Palette.Capture")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Palette.Capture",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_capture(mode)
|
||||
let cmd = "map"
|
||||
if a:mode ==# "!"
|
||||
let cmd = cmd . "!"
|
||||
elseif a:mode =~# "[nvoicsxl]"
|
||||
let cmd = a:mode . cmd
|
||||
endif
|
||||
return s:Capture.command(cmd)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:capture(...)
|
||||
let mode = get(a:, 1, "")
|
||||
let modes = split(mode, '\zs')
|
||||
return join(map(modes, "s:_capture(v:val)"), "\n")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_keymapping(str)
|
||||
return a:str =~ '^[!nvoicsxl]\s'
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:capture_list(...)
|
||||
let mode = get(a:, 1, "")
|
||||
return filter(split(s:capture(mode), "\n"), "s:_keymapping(v:val)")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:escape_special_key(key)
|
||||
" Workaround : <C-?> https://github.com/osyo-manga/vital-palette/issues/5
|
||||
if a:key ==# "<^?>"
|
||||
return "\<C-?>"
|
||||
endif
|
||||
execute 'let result = "' . substitute(escape(a:key, '\"'), '\(<.\{-}>\)', '\\\1', 'g') . '"'
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:parse_lhs(text, ...)
|
||||
let mode = get(a:, 1, '[!nvoicsxl]')
|
||||
" NOTE: :map! Surpport : https://github.com/osyo-manga/vital-palette/issues/4
|
||||
if get(a:, 1, "") =~# '[!ci]'
|
||||
let mode = '[!ci]'
|
||||
endif
|
||||
return matchstr(a:text, mode . '\{1,3\}\s*\zs\S\{-}\ze\s\+')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:parse_lhs_list(...)
|
||||
let mode = get(a:, 1, "")
|
||||
return map(s:capture_list(mode), "s:parse_lhs(v:val, mode)")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:lhs_key_list(...)
|
||||
let mode = get(a:, 1, "")
|
||||
return map(s:parse_lhs_list(mode), "s:escape_special_key(v:val)")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_maparg(name, mode, abbr, dict)
|
||||
" Workaround : <C-?> https://github.com/osyo-manga/vital-palette/issues/5
|
||||
if a:name ==# "<^?>"
|
||||
return maparg("\<C-?>", a:mode, a:abbr, a:dict)
|
||||
endif
|
||||
return maparg(a:name, a:mode, a:abbr, a:dict)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:rhs_key_list(...)
|
||||
let mode = get(a:, 1, "")
|
||||
let abbr = get(a:, 2, 0)
|
||||
let dict = get(a:, 3, 0)
|
||||
|
||||
let result = []
|
||||
for m in split(mode, '\zs')
|
||||
let result += map(s:parse_lhs_list(m), "s:_maparg(v:val, m, abbr, dict)")
|
||||
endfor
|
||||
return filter(result, "empty(v:val) == 0")
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
|
@ -0,0 +1,430 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Prelude#import() abort
|
||||
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)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
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('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
if v:version > 703 ||
|
||||
\ (v:version == 703 && has('patch465'))
|
||||
function! s:glob(expr) abort
|
||||
return glob(a:expr, 1, 1)
|
||||
endfunction
|
||||
else
|
||||
function! s:glob(expr) abort
|
||||
return split(glob(a:expr, 1), '\n')
|
||||
endfunction
|
||||
endif
|
||||
|
||||
if v:version > 704 ||
|
||||
\ (v:version == 704 && has('patch279'))
|
||||
function! s:globpath(path, expr) abort
|
||||
return globpath(a:path, a:expr, 1, 1)
|
||||
endfunction
|
||||
else
|
||||
function! s:globpath(path, expr) abort
|
||||
return split(globpath(a:path, a:expr, 1), '\n')
|
||||
endfunction
|
||||
endif
|
||||
|
||||
" Wrapper functions for type().
|
||||
" NOTE: __TYPE_FLOAT = -1 when -float.
|
||||
" this doesn't match to anything.
|
||||
if has('patch-7.4.2071')
|
||||
let [
|
||||
\ s:__TYPE_NUMBER,
|
||||
\ s:__TYPE_STRING,
|
||||
\ s:__TYPE_FUNCREF,
|
||||
\ s:__TYPE_LIST,
|
||||
\ s:__TYPE_DICT,
|
||||
\ s:__TYPE_FLOAT] = [
|
||||
\ v:t_number,
|
||||
\ v:t_string,
|
||||
\ v:t_func,
|
||||
\ v:t_list,
|
||||
\ v:t_dict,
|
||||
\ v:t_float]
|
||||
else
|
||||
let [
|
||||
\ s:__TYPE_NUMBER,
|
||||
\ s:__TYPE_STRING,
|
||||
\ s:__TYPE_FUNCREF,
|
||||
\ s:__TYPE_LIST,
|
||||
\ s:__TYPE_DICT,
|
||||
\ s:__TYPE_FLOAT] = [
|
||||
\ type(3),
|
||||
\ type(''),
|
||||
\ type(function('tr')),
|
||||
\ type([]),
|
||||
\ type({}),
|
||||
\ has('float') ? type(str2float('0')) : -1]
|
||||
endif
|
||||
|
||||
" Number or Float
|
||||
function! s:is_numeric(Value) abort
|
||||
let _ = type(a:Value)
|
||||
return _ ==# s:__TYPE_NUMBER
|
||||
\ || _ ==# s:__TYPE_FLOAT
|
||||
endfunction
|
||||
|
||||
" Number
|
||||
function! s:is_number(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_NUMBER
|
||||
endfunction
|
||||
|
||||
" String
|
||||
function! s:is_string(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_STRING
|
||||
endfunction
|
||||
|
||||
" Funcref
|
||||
function! s:is_funcref(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_FUNCREF
|
||||
endfunction
|
||||
|
||||
" List
|
||||
function! s:is_list(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_LIST
|
||||
endfunction
|
||||
|
||||
" Dictionary
|
||||
function! s:is_dict(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_DICT
|
||||
endfunction
|
||||
|
||||
" Float
|
||||
function! s:is_float(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_FLOAT
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:truncate_skipping(str, max, footer_width, separator) abort
|
||||
call s:_warn_deprecated('truncate_skipping', 'Data.String.truncate_skipping')
|
||||
|
||||
let width = s:wcswidth(a:str)
|
||||
if width <= a:max
|
||||
let ret = a:str
|
||||
else
|
||||
let header_width = a:max - s:wcswidth(a:separator) - a:footer_width
|
||||
let ret = s:strwidthpart(a:str, header_width) . a:separator
|
||||
\ . s:strwidthpart_reverse(a:str, a:footer_width)
|
||||
endif
|
||||
|
||||
return s:truncate(ret, a:max)
|
||||
endfunction
|
||||
|
||||
function! s:truncate(str, width) abort
|
||||
" Original function is from mattn.
|
||||
" http://github.com/mattn/googlereader-vim/tree/master
|
||||
|
||||
call s:_warn_deprecated('truncate', 'Data.String.truncate')
|
||||
|
||||
if a:str =~# '^[\x00-\x7f]*$'
|
||||
return len(a:str) < a:width ?
|
||||
\ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width)
|
||||
endif
|
||||
|
||||
let ret = a:str
|
||||
let width = s:wcswidth(a:str)
|
||||
if width > a:width
|
||||
let ret = s:strwidthpart(ret, a:width)
|
||||
let width = s:wcswidth(ret)
|
||||
endif
|
||||
|
||||
if width < a:width
|
||||
let ret .= repeat(' ', a:width - width)
|
||||
endif
|
||||
|
||||
return ret
|
||||
endfunction
|
||||
|
||||
function! s:strwidthpart(str, width) abort
|
||||
call s:_warn_deprecated('strwidthpart', 'Data.String.strwidthpart')
|
||||
|
||||
if a:width <= 0
|
||||
return ''
|
||||
endif
|
||||
let ret = a:str
|
||||
let width = s:wcswidth(a:str)
|
||||
while width > a:width
|
||||
let char = matchstr(ret, '.$')
|
||||
let ret = ret[: -1 - len(char)]
|
||||
let width -= s:wcswidth(char)
|
||||
endwhile
|
||||
|
||||
return ret
|
||||
endfunction
|
||||
function! s:strwidthpart_reverse(str, width) abort
|
||||
call s:_warn_deprecated('strwidthpart_reverse', 'Data.String.strwidthpart_reverse')
|
||||
|
||||
if a:width <= 0
|
||||
return ''
|
||||
endif
|
||||
let ret = a:str
|
||||
let width = s:wcswidth(a:str)
|
||||
while width > a:width
|
||||
let char = matchstr(ret, '^.')
|
||||
let ret = ret[len(char) :]
|
||||
let width -= s:wcswidth(char)
|
||||
endwhile
|
||||
|
||||
return ret
|
||||
endfunction
|
||||
|
||||
if v:version >= 703
|
||||
" Use builtin function.
|
||||
function! s:wcswidth(str) abort
|
||||
call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth')
|
||||
return strwidth(a:str)
|
||||
endfunction
|
||||
else
|
||||
function! s:wcswidth(str) abort
|
||||
call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth')
|
||||
|
||||
if a:str =~# '^[\x00-\x7f]*$'
|
||||
return strlen(a:str)
|
||||
end
|
||||
|
||||
let mx_first = '^\(.\)'
|
||||
let str = a:str
|
||||
let width = 0
|
||||
while 1
|
||||
let ucs = char2nr(substitute(str, mx_first, '\1', ''))
|
||||
if ucs == 0
|
||||
break
|
||||
endif
|
||||
let width += s:_wcwidth(ucs)
|
||||
let str = substitute(str, mx_first, '', '')
|
||||
endwhile
|
||||
return width
|
||||
endfunction
|
||||
|
||||
" UTF-8 only.
|
||||
function! s:_wcwidth(ucs) abort
|
||||
let ucs = a:ucs
|
||||
if (ucs >= 0x1100
|
||||
\ && (ucs <= 0x115f
|
||||
\ || ucs == 0x2329
|
||||
\ || ucs == 0x232a
|
||||
\ || (ucs >= 0x2e80 && ucs <= 0xa4cf
|
||||
\ && ucs != 0x303f)
|
||||
\ || (ucs >= 0xac00 && ucs <= 0xd7a3)
|
||||
\ || (ucs >= 0xf900 && ucs <= 0xfaff)
|
||||
\ || (ucs >= 0xfe30 && ucs <= 0xfe6f)
|
||||
\ || (ucs >= 0xff00 && ucs <= 0xff60)
|
||||
\ || (ucs >= 0xffe0 && ucs <= 0xffe6)
|
||||
\ || (ucs >= 0x20000 && ucs <= 0x2fffd)
|
||||
\ || (ucs >= 0x30000 && ucs <= 0x3fffd)
|
||||
\ ))
|
||||
return 2
|
||||
endif
|
||||
return 1
|
||||
endfunction
|
||||
endif
|
||||
|
||||
let s:is_windows = has('win16') || has('win32') || has('win64') || has('win95')
|
||||
let s:is_cygwin = has('win32unix')
|
||||
let s:is_mac = !s:is_windows && !s:is_cygwin
|
||||
\ && (has('mac') || has('macunix') || has('gui_macvim') ||
|
||||
\ (!isdirectory('/proc') && executable('sw_vers')))
|
||||
let s:is_unix = has('unix')
|
||||
|
||||
function! s:is_windows() abort
|
||||
return s:is_windows
|
||||
endfunction
|
||||
|
||||
function! s:is_cygwin() abort
|
||||
return s:is_cygwin
|
||||
endfunction
|
||||
|
||||
function! s:is_mac() abort
|
||||
return s:is_mac
|
||||
endfunction
|
||||
|
||||
function! s:is_unix() abort
|
||||
return s:is_unix
|
||||
endfunction
|
||||
|
||||
function! s:_warn_deprecated(name, alternative) abort
|
||||
try
|
||||
echohl Error
|
||||
echomsg 'Prelude.' . a:name . ' is deprecated! Please use ' . a:alternative . ' instead.'
|
||||
finally
|
||||
echohl None
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:smart_execute_command(action, word) abort
|
||||
execute a:action . ' ' . (a:word ==# '' ? '' : '`=a:word`')
|
||||
endfunction
|
||||
|
||||
function! s:escape_file_searching(buffer_name) abort
|
||||
return escape(a:buffer_name, '*[]?{}, ')
|
||||
endfunction
|
||||
|
||||
function! s:escape_pattern(str) abort
|
||||
call s:_warn_deprecated(
|
||||
\ 'escape_pattern',
|
||||
\ 'Data.String.escape_pattern',
|
||||
\)
|
||||
return escape(a:str, '~"\.^$[]*')
|
||||
endfunction
|
||||
|
||||
function! s:getchar(...) abort
|
||||
let c = call('getchar', a:000)
|
||||
return type(c) == type(0) ? nr2char(c) : c
|
||||
endfunction
|
||||
|
||||
function! s:getchar_safe(...) abort
|
||||
let c = s:input_helper('getchar', a:000)
|
||||
return type(c) == type('') ? c : nr2char(c)
|
||||
endfunction
|
||||
|
||||
function! s:input_safe(...) abort
|
||||
return s:input_helper('input', a:000)
|
||||
endfunction
|
||||
|
||||
function! s:input_helper(funcname, args) abort
|
||||
let success = 0
|
||||
if inputsave() !=# success
|
||||
throw 'vital: Prelude: inputsave() failed'
|
||||
endif
|
||||
try
|
||||
return call(a:funcname, a:args)
|
||||
finally
|
||||
if inputrestore() !=# success
|
||||
throw 'vital: Prelude: inputrestore() failed'
|
||||
endif
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:set_default(var, val) abort
|
||||
if !exists(a:var) || type({a:var}) != type(a:val)
|
||||
let {a:var} = a:val
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:substitute_path_separator(path) abort
|
||||
return s:is_windows ? substitute(a:path, '\\', '/', 'g') : a:path
|
||||
endfunction
|
||||
|
||||
function! s:path2directory(path) abort
|
||||
return s:substitute_path_separator(isdirectory(a:path) ? a:path : fnamemodify(a:path, ':p:h'))
|
||||
endfunction
|
||||
|
||||
function! s:_path2project_directory_git(path) abort
|
||||
let parent = a:path
|
||||
|
||||
while 1
|
||||
let path = parent . '/.git'
|
||||
if isdirectory(path) || filereadable(path)
|
||||
return parent
|
||||
endif
|
||||
let next = fnamemodify(parent, ':h')
|
||||
if next == parent
|
||||
return ''
|
||||
endif
|
||||
let parent = next
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
function! s:_path2project_directory_svn(path) abort
|
||||
let search_directory = a:path
|
||||
let directory = ''
|
||||
|
||||
let find_directory = s:escape_file_searching(search_directory)
|
||||
let d = finddir('.svn', find_directory . ';')
|
||||
if d ==# ''
|
||||
return ''
|
||||
endif
|
||||
|
||||
let directory = fnamemodify(d, ':p:h:h')
|
||||
|
||||
" Search parent directories.
|
||||
let parent_directory = s:path2directory(
|
||||
\ fnamemodify(directory, ':h'))
|
||||
|
||||
if parent_directory !=# ''
|
||||
let d = finddir('.svn', parent_directory . ';')
|
||||
if d !=# ''
|
||||
let directory = s:_path2project_directory_svn(parent_directory)
|
||||
endif
|
||||
endif
|
||||
return directory
|
||||
endfunction
|
||||
|
||||
function! s:_path2project_directory_others(vcs, path) abort
|
||||
let vcs = a:vcs
|
||||
let search_directory = a:path
|
||||
|
||||
let find_directory = s:escape_file_searching(search_directory)
|
||||
let d = finddir(vcs, find_directory . ';')
|
||||
if d ==# ''
|
||||
return ''
|
||||
endif
|
||||
return fnamemodify(d, ':p:h:h')
|
||||
endfunction
|
||||
|
||||
function! s:path2project_directory(path, ...) abort
|
||||
let is_allow_empty = get(a:000, 0, 0)
|
||||
let search_directory = s:path2directory(a:path)
|
||||
let directory = ''
|
||||
|
||||
" Search VCS directory.
|
||||
for vcs in ['.git', '.bzr', '.hg', '.svn']
|
||||
if vcs ==# '.git'
|
||||
let directory = s:_path2project_directory_git(search_directory)
|
||||
elseif vcs ==# '.svn'
|
||||
let directory = s:_path2project_directory_svn(search_directory)
|
||||
else
|
||||
let directory = s:_path2project_directory_others(vcs, search_directory)
|
||||
endif
|
||||
if directory !=# ''
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Search project file.
|
||||
if directory ==# ''
|
||||
for d in ['build.xml', 'prj.el', '.project', 'pom.xml', 'package.json',
|
||||
\ 'Makefile', 'configure', 'Rakefile', 'NAnt.build',
|
||||
\ 'P4CONFIG', 'tags', 'gtags']
|
||||
let d = findfile(d, s:escape_file_searching(search_directory) . ';')
|
||||
if d !=# ''
|
||||
let directory = fnamemodify(d, ':p:h')
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
if directory ==# ''
|
||||
" Search /src/ directory.
|
||||
let base = s:substitute_path_separator(search_directory)
|
||||
if base =~# '/src/'
|
||||
let directory = base[: strridx(base, '/src/') + 3]
|
||||
endif
|
||||
endif
|
||||
|
||||
if directory ==# '' && !is_allow_empty
|
||||
" Use original path.
|
||||
let directory = search_directory
|
||||
endif
|
||||
|
||||
return s:substitute_path_separator(directory)
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0:
|
|
@ -0,0 +1,187 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Vim#Buffer#import() abort
|
||||
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)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
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('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
function! s:_vital_loaded(V) abort
|
||||
let s:V = a:V
|
||||
let s:P = s:V.import('Prelude')
|
||||
let s:G = s:V.import('Vim.Guard')
|
||||
endfunction
|
||||
|
||||
function! s:_vital_depends() abort
|
||||
return ['Prelude', 'Vim.Guard']
|
||||
endfunction
|
||||
|
||||
if exists('*getcmdwintype')
|
||||
function! s:is_cmdwin() abort
|
||||
return getcmdwintype() !=# ''
|
||||
endfunction
|
||||
else
|
||||
function! s:is_cmdwin() abort
|
||||
return bufname('%') ==# '[Command Line]'
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:open(buffer, opener) abort
|
||||
let save_wildignore = &wildignore
|
||||
let &wildignore = ''
|
||||
try
|
||||
if s:P.is_funcref(a:opener)
|
||||
let loaded = !bufloaded(a:buffer)
|
||||
call a:opener(a:buffer)
|
||||
elseif a:buffer is 0 || a:buffer is# ''
|
||||
let loaded = 1
|
||||
silent execute a:opener
|
||||
enew
|
||||
else
|
||||
let loaded = !bufloaded(a:buffer)
|
||||
if s:P.is_string(a:buffer)
|
||||
execute a:opener '`=a:buffer`'
|
||||
elseif s:P.is_number(a:buffer)
|
||||
silent execute a:opener
|
||||
execute a:buffer 'buffer'
|
||||
else
|
||||
throw 'vital: Vim.Buffer: Unknown opener type.'
|
||||
endif
|
||||
endif
|
||||
finally
|
||||
let &wildignore = save_wildignore
|
||||
endtry
|
||||
return loaded
|
||||
endfunction
|
||||
|
||||
function! s:get_selected_text(...) abort
|
||||
echohl WarningMsg
|
||||
echom "[WARN] s:get_selected_text() is deprecated. Use 's:get_last_selected()'."
|
||||
echohl None
|
||||
return call('s:get_last_selected', a:000)
|
||||
endfunction
|
||||
|
||||
" Get the last selected text in visual mode
|
||||
" without using |gv| to avoid |textlock|.
|
||||
" NOTE:
|
||||
" * This function uses |gv| only when using |CTRL-V|
|
||||
" because |gv| is the only way to get selected text
|
||||
" when using <C-v>$ .
|
||||
" Please see #192 for the details.
|
||||
" * If you don't care about |textlock|,
|
||||
" you can use simple version of this function.
|
||||
" https://github.com/vim-jp/vital.vim/commit/39aae80f3839fdbeebd838ff14d87327a6b889a9
|
||||
function! s:get_last_selected() abort
|
||||
if visualmode() ==# "\<C-v>"
|
||||
let save = getreg('"', 1)
|
||||
let save_type = getregtype('"')
|
||||
try
|
||||
normal! gv""y
|
||||
return @"
|
||||
finally
|
||||
call setreg('"', save, save_type)
|
||||
endtry
|
||||
else
|
||||
let [begin, end] = [getpos("'<"), getpos("'>")]
|
||||
let lastchar = matchstr(getline(end[1])[end[2]-1 :], '.')
|
||||
if begin[1] ==# end[1]
|
||||
let lines = [getline(begin[1])[begin[2]-1 : end[2]-2]]
|
||||
else
|
||||
let lines = [getline(begin[1])[begin[2]-1 :]]
|
||||
\ + (end[1] - begin[1] <# 2 ? [] : getline(begin[1]+1, end[1]-1))
|
||||
\ + [getline(end[1])[: end[2]-2]]
|
||||
endif
|
||||
return join(lines, "\n") . lastchar . (visualmode() ==# 'V' ? "\n" : '')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:read_content(content, ...) abort
|
||||
let options = extend({
|
||||
\ 'tempfile': '',
|
||||
\ 'fileformat': '',
|
||||
\ 'encoding': '',
|
||||
\ 'binary': 0,
|
||||
\ 'nobinary': 0,
|
||||
\ 'bad': '',
|
||||
\ 'edit': 0,
|
||||
\ 'line': '',
|
||||
\}, get(a:000, 0, {}))
|
||||
let tempfile = empty(options.tempfile) ? tempname() : options.tempfile
|
||||
let optnames = [
|
||||
\ empty(options.fileformat) ? '' : '++ff=' . options.fileformat,
|
||||
\ empty(options.encoding) ? '' : '++enc=' . options.encoding,
|
||||
\ empty(options.binary) ? '' : '++bin',
|
||||
\ empty(options.nobinary) ? '' : '++nobin',
|
||||
\ empty(options.bad) ? '' : '++bad=' . options.bad,
|
||||
\ empty(options.edit) ? '' : '++edit',
|
||||
\]
|
||||
let optname = join(filter(optnames, '!empty(v:val)'))
|
||||
try
|
||||
call writefile(a:content, tempfile)
|
||||
execute printf('keepalt keepjumps %sread %s%s',
|
||||
\ options.line,
|
||||
\ empty(optname) ? '' : optname . ' ',
|
||||
\ fnameescape(tempfile),
|
||||
\)
|
||||
finally
|
||||
call delete(tempfile)
|
||||
execute 'bwipeout!' tempfile
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:edit_content(content, ...) abort
|
||||
let options = extend({
|
||||
\ 'edit': 1,
|
||||
\}, get(a:000, 0, {}))
|
||||
let guard = s:G.store(['&l:modifiable'])
|
||||
let saved_view = winsaveview()
|
||||
try
|
||||
let &l:modifiable=1
|
||||
silent keepjumps %delete _
|
||||
silent call s:read_content(a:content, options)
|
||||
silent keepjumps 1delete _
|
||||
finally
|
||||
keepjump call winrestview(saved_view)
|
||||
call guard.restore()
|
||||
endtry
|
||||
setlocal nomodified
|
||||
endfunction
|
||||
|
||||
function! s:parse_cmdarg(...) abort
|
||||
let cmdarg = get(a:000, 0, v:cmdarg)
|
||||
let options = {}
|
||||
if cmdarg =~# '++enc='
|
||||
let options.encoding = matchstr(cmdarg, '++enc=\zs[^ ]\+\ze')
|
||||
endif
|
||||
if cmdarg =~# '++ff='
|
||||
let options.fileformat = matchstr(cmdarg, '++ff=\zs[^ ]\+\ze')
|
||||
endif
|
||||
if cmdarg =~# '++bad='
|
||||
let options.bad = matchstr(cmdarg, '++bad=\zs[^ ]\+\ze')
|
||||
endif
|
||||
if cmdarg =~# '++bin'
|
||||
let options.binary = 1
|
||||
endif
|
||||
if cmdarg =~# '++nobin'
|
||||
let options.nobinary = 1
|
||||
endif
|
||||
if cmdarg =~# '++edit'
|
||||
let options.edit = 1
|
||||
endif
|
||||
return options
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0:
|
|
@ -0,0 +1,240 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Vim#Guard#import() abort
|
||||
return map({'_vital_depends': '', '_vital_created': '', 'store': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Vim#Guard#import() abort', printf("return map({'_vital_depends': '', '_vital_created': '', 'store': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Use a Funcref as a special term _UNDEFINED
|
||||
function! s:_undefined() abort
|
||||
return 'undefined'
|
||||
endfunction
|
||||
let s:_UNDEFINED = function('s:_undefined')
|
||||
|
||||
function! s:_vital_loaded(V) abort
|
||||
let s:V = a:V
|
||||
let s:Prelude = s:V.import('Prelude')
|
||||
let s:List = s:V.import('Data.List')
|
||||
let s:Dict = s:V.import('Data.Dict')
|
||||
endfunction
|
||||
function! s:_vital_depends() abort
|
||||
return ['Prelude', 'Data.List', 'Data.Dict']
|
||||
endfunction
|
||||
function! s:_vital_created(module) abort
|
||||
" define constant variables
|
||||
if !exists('s:const')
|
||||
let s:const = {}
|
||||
let s:const.is_local_variable_supported =
|
||||
\ v:version > 703 || (v:version == 703 && has('patch560'))
|
||||
" NOTE:
|
||||
" The third argument is available from 7.4.242 but it had bug and that
|
||||
" bug was fixed from 7.4.513
|
||||
let s:const.is_third_argument_of_getreg_supported = has('patch-7.4.513')
|
||||
lockvar s:const
|
||||
endif
|
||||
call extend(a:module, s:const)
|
||||
endfunction
|
||||
function! s:_throw(msg) abort
|
||||
throw printf('vital: Vim.Guard: %s', a:msg)
|
||||
endfunction
|
||||
|
||||
let s:option = {}
|
||||
function! s:_new_option(name) abort
|
||||
if a:name !~# '^&'
|
||||
call s:_throw(printf(
|
||||
\'An option name "%s" requires to be started from "&"', a:name
|
||||
\))
|
||||
elseif !exists(a:name)
|
||||
call s:_throw(printf(
|
||||
\'An option name "%s" does not exist', a:name
|
||||
\))
|
||||
endif
|
||||
let option = copy(s:option)
|
||||
let option.name = a:name
|
||||
let option.value = eval(a:name)
|
||||
return option
|
||||
endfunction
|
||||
function! s:option.restore() abort
|
||||
execute printf('let %s = %s', self.name, string(self.value))
|
||||
endfunction
|
||||
|
||||
let s:register = {}
|
||||
function! s:_new_register(name) abort
|
||||
if len(a:name) != 2
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" requires to be "@" + a single character', a:name
|
||||
\))
|
||||
elseif a:name !~# '^@'
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" requires to be started from "@"', a:name
|
||||
\))
|
||||
elseif a:name =~# '^@[:.%]$'
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" is read only', a:name
|
||||
\))
|
||||
elseif a:name !~# '^@[@0-9a-zA-Z#=*+~_/-]$'
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" does not exist. See ":help let-register"', a:name
|
||||
\))
|
||||
endif
|
||||
let name = a:name ==# '@@' ? '' : a:name[1]
|
||||
let register = copy(s:register)
|
||||
let register.name = name
|
||||
if s:const.is_third_argument_of_getreg_supported
|
||||
let register.value = getreg(name, 1, 1)
|
||||
else
|
||||
let register.value = getreg(name, 1)
|
||||
endif
|
||||
let register.type = getregtype(name)
|
||||
return register
|
||||
endfunction
|
||||
function! s:register.restore() abort
|
||||
" https://github.com/vim/vim/commit/5a50c2255c447838d08d3b4895a3be3a41cd8eda
|
||||
if has('patch-7.4.243') || self.name !=# '='
|
||||
call setreg(self.name, self.value, self.type)
|
||||
else
|
||||
let @= = self.value
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:environment = {}
|
||||
function! s:_new_environment(name) abort
|
||||
if a:name !~# '^\$'
|
||||
call s:_throw(printf(
|
||||
\'An environment variable name "%s" requires to be started from "$"', a:name
|
||||
\))
|
||||
elseif !exists(a:name)
|
||||
call s:_throw(printf(
|
||||
\'An environment variable name "%s" does not exist. While Vim cannot unlet environment variable, it requires to exist', a:name
|
||||
\))
|
||||
endif
|
||||
let environment = copy(s:environment)
|
||||
let environment.name = a:name
|
||||
let environment.value = eval(a:name)
|
||||
return environment
|
||||
endfunction
|
||||
function! s:environment.restore() abort
|
||||
execute printf('let %s = %s', self.name, string(self.value))
|
||||
endfunction
|
||||
|
||||
let s:variable = {}
|
||||
function! s:_new_variable(name, ...) abort
|
||||
if a:0 == 0
|
||||
let m = matchlist(a:name, '^\([bwtg]:\)\(.*\)$')
|
||||
if empty(m)
|
||||
call s:_throw(printf(
|
||||
\ join([
|
||||
\ 'An variable name "%s" requires to start from b:, w:, t:, or g:',
|
||||
\ 'while no {namespace} is specified',
|
||||
\ ]),
|
||||
\ a:name,
|
||||
\))
|
||||
endif
|
||||
let [prefix, name] = m[1 : 2]
|
||||
let namespace = eval(prefix)
|
||||
else
|
||||
let name = a:name
|
||||
let namespace = a:1
|
||||
endif
|
||||
let variable = copy(s:variable)
|
||||
let variable.name = name
|
||||
let variable.value = get(namespace, name, s:_UNDEFINED)
|
||||
let variable.value =
|
||||
\ type(variable.value) == type({}) || type(variable.value) == type([])
|
||||
\ ? deepcopy(variable.value)
|
||||
\ : variable.value
|
||||
let variable._namespace = namespace
|
||||
return variable
|
||||
endfunction
|
||||
function! s:variable.restore() abort
|
||||
" unlet the variable to prevent variable type mis-match in case
|
||||
silent! unlet! self._namespace[self.name]
|
||||
if type(self.value) == type(s:_UNDEFINED) && self.value == s:_UNDEFINED
|
||||
" do nothing, leave the variable as undefined
|
||||
else
|
||||
let self._namespace[self.name] = self.value
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:instance = {}
|
||||
function! s:_new_instance(instance, ...) abort
|
||||
let shallow = get(a:000, 0, 0)
|
||||
if !s:Prelude.is_list(a:instance) && !s:Prelude.is_dict(a:instance)
|
||||
call s:_throw(printf(
|
||||
\'An instance "%s" requires to be List or Dictionary', string(a:instance)
|
||||
\))
|
||||
endif
|
||||
let instance = copy(s:instance)
|
||||
let instance.instance = a:instance
|
||||
let instance.values = shallow ? copy(a:instance) : deepcopy(a:instance)
|
||||
return instance
|
||||
endfunction
|
||||
function! s:instance.restore() abort
|
||||
if s:Prelude.is_list(self.instance)
|
||||
call s:List.clear(self.instance)
|
||||
else
|
||||
call s:Dict.clear(self.instance)
|
||||
endif
|
||||
call extend(self.instance, self.values)
|
||||
endfunction
|
||||
|
||||
let s:guard = {}
|
||||
function! s:store(targets) abort
|
||||
let resources = []
|
||||
for meta in a:targets
|
||||
if s:Prelude.is_list(meta)
|
||||
if len(meta) == 1
|
||||
call add(resources, s:_new_instance(meta[0]))
|
||||
elseif len(meta) == 2
|
||||
if s:Prelude.is_string(meta[0])
|
||||
call add(resources, call('s:_new_variable', meta))
|
||||
else
|
||||
call add(resources, call('s:_new_instance', meta))
|
||||
endif
|
||||
else
|
||||
call s:_throw('List assignment requires one or two elements')
|
||||
endif
|
||||
elseif type(meta) == type('')
|
||||
if meta =~# '^[bwtgls]:'
|
||||
" Note:
|
||||
" To improve an error message, handle l:XXX or s:XXX as well
|
||||
call add(resources, s:_new_variable(meta))
|
||||
elseif meta =~# '^&'
|
||||
call add(resources, s:_new_option(meta))
|
||||
elseif meta =~# '^@'
|
||||
call add(resources, s:_new_register(meta))
|
||||
elseif meta =~# '^\$'
|
||||
call add(resources, s:_new_environment(meta))
|
||||
else
|
||||
call s:_throw(printf(
|
||||
\ 'Unknown value "%s" was specified',
|
||||
\ meta
|
||||
\))
|
||||
endif
|
||||
endif
|
||||
unlet meta
|
||||
endfor
|
||||
let guard = copy(s:guard)
|
||||
let guard._resources = resources
|
||||
return guard
|
||||
endfunction
|
||||
function! s:guard.restore() abort
|
||||
for resource in self._resources
|
||||
call resource.restore()
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet! s:save_cpo
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0 fdm=marker:
|
|
@ -0,0 +1,80 @@
|
|||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Vim#Message#import() abort
|
||||
return map({'capture': '', 'echomsg': '', 'echo': '', 'warn': '', 'get_hit_enter_max_length': '', 'error': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Vim#Message#import() abort', printf("return map({'capture': '', 'echomsg': '', 'echo': '', 'warn': '', 'get_hit_enter_max_length': '', 'error': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
|
||||
function! s:echo(hl, msg) abort
|
||||
execute 'echohl' a:hl
|
||||
try
|
||||
echo a:msg
|
||||
finally
|
||||
echohl None
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:echomsg(hl, msg) abort
|
||||
execute 'echohl' a:hl
|
||||
try
|
||||
for m in split(a:msg, "\n")
|
||||
echomsg m
|
||||
endfor
|
||||
finally
|
||||
echohl None
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:error(msg) abort
|
||||
call s:echomsg('ErrorMsg', a:msg)
|
||||
endfunction
|
||||
|
||||
function! s:warn(msg) abort
|
||||
call s:echomsg('WarningMsg', a:msg)
|
||||
endfunction
|
||||
|
||||
function! s:capture(command) abort
|
||||
try
|
||||
redir => out
|
||||
silent execute a:command
|
||||
finally
|
||||
redir END
|
||||
endtry
|
||||
return out
|
||||
endfunction
|
||||
|
||||
" * Get max length of |hit-enter|.
|
||||
" If a string length of a message is greater than the max length,
|
||||
" Vim waits for user input according to |hit-enter|.
|
||||
" XXX: Those fixed values may be different between different OSes?
|
||||
" Currently tested on only Windows.
|
||||
function! s:get_hit_enter_max_length() abort
|
||||
let maxlen = &columns * &cmdheight - 1
|
||||
if &ruler
|
||||
" TODO
|
||||
endif
|
||||
if &showcmd
|
||||
let maxlen -= 11
|
||||
endif
|
||||
return maxlen
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0:
|
339
sources_non_forked/vim-easymotion/autoload/vital/easymotion.vim
Normal file
339
sources_non_forked/vim-easymotion/autoload/vital/easymotion.vim
Normal file
|
@ -0,0 +1,339 @@
|
|||
let s:plugin_name = expand('<sfile>:t:r')
|
||||
let s:vital_base_dir = expand('<sfile>:h')
|
||||
let s:project_root = expand('<sfile>:h:h:h')
|
||||
let s:is_vital_vim = s:plugin_name is# 'vital'
|
||||
|
||||
let s:loaded = {}
|
||||
let s:cache_sid = {}
|
||||
|
||||
" function() wrapper
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! s:_function(fstr) abort
|
||||
return function(a:fstr)
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
let s:_s = '<SNR>' . s:_SID() . '_'
|
||||
function! s:_function(fstr) abort
|
||||
return function(substitute(a:fstr, 's:', s:_s, 'g'))
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! vital#{s:plugin_name}#new() abort
|
||||
return s:new(s:plugin_name)
|
||||
endfunction
|
||||
|
||||
function! vital#{s:plugin_name}#import(...) abort
|
||||
if !exists('s:V')
|
||||
let s:V = s:new(s:plugin_name)
|
||||
endif
|
||||
return call(s:V.import, a:000, s:V)
|
||||
endfunction
|
||||
|
||||
let s:Vital = {}
|
||||
|
||||
function! s:new(plugin_name) abort
|
||||
let base = deepcopy(s:Vital)
|
||||
let base._plugin_name = a:plugin_name
|
||||
return base
|
||||
endfunction
|
||||
|
||||
function! s:vital_files() abort
|
||||
if !exists('s:vital_files')
|
||||
let s:vital_files = map(
|
||||
\ s:is_vital_vim ? s:_global_vital_files() : s:_self_vital_files(),
|
||||
\ 'fnamemodify(v:val, ":p:gs?[\\\\/]?/?")')
|
||||
endif
|
||||
return copy(s:vital_files)
|
||||
endfunction
|
||||
let s:Vital.vital_files = s:_function('s:vital_files')
|
||||
|
||||
function! s:import(name, ...) abort dict
|
||||
let target = {}
|
||||
let functions = []
|
||||
for a in a:000
|
||||
if type(a) == type({})
|
||||
let target = a
|
||||
elseif type(a) == type([])
|
||||
let functions = a
|
||||
endif
|
||||
unlet a
|
||||
endfor
|
||||
let module = self._import(a:name)
|
||||
if empty(functions)
|
||||
call extend(target, module, 'keep')
|
||||
else
|
||||
for f in functions
|
||||
if has_key(module, f) && !has_key(target, f)
|
||||
let target[f] = module[f]
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
return target
|
||||
endfunction
|
||||
let s:Vital.import = s:_function('s:import')
|
||||
|
||||
function! s:load(...) abort dict
|
||||
for arg in a:000
|
||||
let [name; as] = type(arg) == type([]) ? arg[: 1] : [arg, arg]
|
||||
let target = split(join(as, ''), '\W\+')
|
||||
let dict = self
|
||||
let dict_type = type({})
|
||||
while !empty(target)
|
||||
let ns = remove(target, 0)
|
||||
if !has_key(dict, ns)
|
||||
let dict[ns] = {}
|
||||
endif
|
||||
if type(dict[ns]) == dict_type
|
||||
let dict = dict[ns]
|
||||
else
|
||||
unlet dict
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
if exists('dict')
|
||||
call extend(dict, self._import(name))
|
||||
endif
|
||||
unlet arg
|
||||
endfor
|
||||
return self
|
||||
endfunction
|
||||
let s:Vital.load = s:_function('s:load')
|
||||
|
||||
function! s:unload() abort dict
|
||||
let s:loaded = {}
|
||||
let s:cache_sid = {}
|
||||
unlet! s:vital_files
|
||||
endfunction
|
||||
let s:Vital.unload = s:_function('s:unload')
|
||||
|
||||
function! s:exists(name) abort dict
|
||||
if a:name !~# '\v^\u\w*%(\.\u\w*)*$'
|
||||
throw 'vital: Invalid module name: ' . a:name
|
||||
endif
|
||||
return s:_module_path(a:name) isnot# ''
|
||||
endfunction
|
||||
let s:Vital.exists = s:_function('s:exists')
|
||||
|
||||
function! s:search(pattern) abort dict
|
||||
let paths = s:_extract_files(a:pattern, self.vital_files())
|
||||
let modules = sort(map(paths, 's:_file2module(v:val)'))
|
||||
return s:_uniq(modules)
|
||||
endfunction
|
||||
let s:Vital.search = s:_function('s:search')
|
||||
|
||||
function! s:plugin_name() abort dict
|
||||
return self._plugin_name
|
||||
endfunction
|
||||
let s:Vital.plugin_name = s:_function('s:plugin_name')
|
||||
|
||||
function! s:_self_vital_files() abort
|
||||
let builtin = printf('%s/__%s__/', s:vital_base_dir, s:plugin_name)
|
||||
let installed = printf('%s/_%s/', s:vital_base_dir, s:plugin_name)
|
||||
let base = builtin . ',' . installed
|
||||
return split(globpath(base, '**/*.vim', 1), "\n")
|
||||
endfunction
|
||||
|
||||
function! s:_global_vital_files() abort
|
||||
let pattern = 'autoload/vital/__*__/**/*.vim'
|
||||
return split(globpath(&runtimepath, pattern, 1), "\n")
|
||||
endfunction
|
||||
|
||||
function! s:_extract_files(pattern, files) abort
|
||||
let tr = {'.': '/', '*': '[^/]*', '**': '.*'}
|
||||
let target = substitute(a:pattern, '\.\|\*\*\?', '\=tr[submatch(0)]', 'g')
|
||||
let regexp = printf('autoload/vital/[^/]\+/%s.vim$', target)
|
||||
return filter(a:files, 'v:val =~# regexp')
|
||||
endfunction
|
||||
|
||||
function! s:_file2module(file) abort
|
||||
let filename = fnamemodify(a:file, ':p:gs?[\\/]?/?')
|
||||
let tail = matchstr(filename, 'autoload/vital/_\w\+/\zs.*\ze\.vim$')
|
||||
return join(split(tail, '[\\/]\+'), '.')
|
||||
endfunction
|
||||
|
||||
" @param {string} name e.g. Data.List
|
||||
function! s:_import(name) abort dict
|
||||
if has_key(s:loaded, a:name)
|
||||
return copy(s:loaded[a:name])
|
||||
endif
|
||||
let module = self._get_module(a:name)
|
||||
if has_key(module, '_vital_created')
|
||||
call module._vital_created(module)
|
||||
endif
|
||||
let export_module = filter(copy(module), 'v:key =~# "^\\a"')
|
||||
" Cache module before calling module.vital_loaded() to avoid cyclic
|
||||
" dependences but remove the cache if module._vital_loaded() fails.
|
||||
" let s:loaded[a:name] = export_module
|
||||
let s:loaded[a:name] = export_module
|
||||
if has_key(module, '_vital_loaded')
|
||||
try
|
||||
call module._vital_loaded(vital#{s:plugin_name}#new())
|
||||
catch
|
||||
unlet s:loaded[a:name]
|
||||
throw 'vital: fail to call ._vital_loaded(): ' . v:exception
|
||||
endtry
|
||||
endif
|
||||
return copy(s:loaded[a:name])
|
||||
endfunction
|
||||
let s:Vital._import = s:_function('s:_import')
|
||||
|
||||
" s:_get_module() returns module object wihch has all script local functions.
|
||||
function! s:_get_module(name) abort dict
|
||||
let funcname = s:_import_func_name(self.plugin_name(), a:name)
|
||||
if s:_exists_autoload_func_with_source(funcname)
|
||||
return call(funcname, [])
|
||||
else
|
||||
return s:_get_builtin_module(a:name)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:_get_builtin_module(name) abort
|
||||
return s:sid2sfuncs(s:_module_sid(a:name))
|
||||
endfunction
|
||||
|
||||
if s:is_vital_vim
|
||||
" For vital.vim, we can use s:_get_builtin_module directly
|
||||
let s:Vital._get_module = s:_function('s:_get_builtin_module')
|
||||
else
|
||||
let s:Vital._get_module = s:_function('s:_get_module')
|
||||
endif
|
||||
|
||||
function! s:_import_func_name(plugin_name, module_name) abort
|
||||
return printf('vital#_%s#%s#import', a:plugin_name, s:_dot_to_sharp(a:module_name))
|
||||
endfunction
|
||||
|
||||
function! s:_module_sid(name) abort
|
||||
let path = s:_module_path(a:name)
|
||||
if !filereadable(path)
|
||||
throw 'vital: module not found: ' . a:name
|
||||
endif
|
||||
let vital_dir = s:is_vital_vim ? '__\w\+__' : printf('_\{1,2}%s\%%(__\)\?', s:plugin_name)
|
||||
let base = join([vital_dir, ''], '[/\\]\+')
|
||||
let p = base . substitute('' . a:name, '\.', '[/\\\\]\\+', 'g')
|
||||
let sid = s:_sid(path, p)
|
||||
if !sid
|
||||
call s:_source(path)
|
||||
let sid = s:_sid(path, p)
|
||||
if !sid
|
||||
throw printf('vital: cannot get <SID> from path: %s', path)
|
||||
endif
|
||||
endif
|
||||
return sid
|
||||
endfunction
|
||||
|
||||
function! s:_module_path(name) abort
|
||||
return get(s:_extract_files(a:name, s:vital_files()), 0, '')
|
||||
endfunction
|
||||
|
||||
function! s:_module_sid_base_dir() abort
|
||||
return s:is_vital_vim ? &rtp : s:project_root
|
||||
endfunction
|
||||
|
||||
function! s:_dot_to_sharp(name) abort
|
||||
return substitute(a:name, '\.', '#', 'g')
|
||||
endfunction
|
||||
|
||||
" It will sources autoload file if a given func is not already defined.
|
||||
function! s:_exists_autoload_func_with_source(funcname) abort
|
||||
if exists('*' . a:funcname)
|
||||
" Return true if a given func is already defined
|
||||
return 1
|
||||
endif
|
||||
" source a file which may include a given func definition and try again.
|
||||
let path = 'autoload/' . substitute(substitute(a:funcname, '#[^#]*$', '.vim', ''), '#', '/', 'g')
|
||||
call s:_runtime(path)
|
||||
return exists('*' . a:funcname)
|
||||
endfunction
|
||||
|
||||
function! s:_runtime(path) abort
|
||||
execute 'runtime' fnameescape(a:path)
|
||||
endfunction
|
||||
|
||||
function! s:_source(path) abort
|
||||
execute 'source' fnameescape(a:path)
|
||||
endfunction
|
||||
|
||||
" @vimlint(EVL102, 1, l:_)
|
||||
" @vimlint(EVL102, 1, l:__)
|
||||
function! s:_sid(path, filter_pattern) abort
|
||||
let unified_path = s:_unify_path(a:path)
|
||||
if has_key(s:cache_sid, unified_path)
|
||||
return s:cache_sid[unified_path]
|
||||
endif
|
||||
for line in filter(split(s:_redir(':scriptnames'), "\n"), 'v:val =~# a:filter_pattern')
|
||||
let [_, sid, path; __] = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$')
|
||||
if s:_unify_path(path) is# unified_path
|
||||
let s:cache_sid[unified_path] = sid
|
||||
return s:cache_sid[unified_path]
|
||||
endif
|
||||
endfor
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:_redir(cmd) abort
|
||||
let [save_verbose, save_verbosefile] = [&verbose, &verbosefile]
|
||||
set verbose=0 verbosefile=
|
||||
redir => res
|
||||
silent! execute a:cmd
|
||||
redir END
|
||||
let [&verbose, &verbosefile] = [save_verbose, save_verbosefile]
|
||||
return res
|
||||
endfunction
|
||||
|
||||
if filereadable(expand('<sfile>:r') . '.VIM') " is case-insensitive or not
|
||||
let s:_unify_path_cache = {}
|
||||
" resolve() is slow, so we cache results.
|
||||
" Note: On windows, vim can't expand path names from 8.3 formats.
|
||||
" So if getting full path via <sfile> and $HOME was set as 8.3 format,
|
||||
" vital load duplicated scripts. Below's :~ avoid this issue.
|
||||
function! s:_unify_path(path) abort
|
||||
if has_key(s:_unify_path_cache, a:path)
|
||||
return s:_unify_path_cache[a:path]
|
||||
endif
|
||||
let value = tolower(fnamemodify(resolve(fnamemodify(
|
||||
\ a:path, ':p')), ':~:gs?[\\/]?/?'))
|
||||
let s:_unify_path_cache[a:path] = value
|
||||
return value
|
||||
endfunction
|
||||
else
|
||||
function! s:_unify_path(path) abort
|
||||
return resolve(fnamemodify(a:path, ':p:gs?[\\/]?/?'))
|
||||
endfunction
|
||||
endif
|
||||
|
||||
" copied and modified from Vim.ScriptLocal
|
||||
let s:SNR = join(map(range(len("\<SNR>")), '"[\\x" . printf("%0x", char2nr("\<SNR>"[v:val])) . "]"'), '')
|
||||
function! s:sid2sfuncs(sid) abort
|
||||
let fs = split(s:_redir(printf(':function /^%s%s_', s:SNR, a:sid)), "\n")
|
||||
let r = {}
|
||||
let pattern = printf('\m^function\s<SNR>%d_\zs\w\{-}\ze(', a:sid)
|
||||
for fname in map(fs, 'matchstr(v:val, pattern)')
|
||||
let r[fname] = function(s:_sfuncname(a:sid, fname))
|
||||
endfor
|
||||
return r
|
||||
endfunction
|
||||
|
||||
"" Return funcname of script local functions with SID
|
||||
function! s:_sfuncname(sid, funcname) abort
|
||||
return printf('<SNR>%s_%s', a:sid, a:funcname)
|
||||
endfunction
|
||||
|
||||
if exists('*uniq')
|
||||
function! s:_uniq(list) abort
|
||||
return uniq(a:list)
|
||||
endfunction
|
||||
else
|
||||
function! s:_uniq(list) abort
|
||||
let i = len(a:list) - 1
|
||||
while 0 < i
|
||||
if a:list[i] ==# a:list[i - 1]
|
||||
call remove(a:list, i)
|
||||
endif
|
||||
let i -= 1
|
||||
endwhile
|
||||
return a:list
|
||||
endfunction
|
||||
endif
|
|
@ -0,0 +1,20 @@
|
|||
easymotion
|
||||
882de6964d10595e839ccbcc0fb20b7ff14e43cb
|
||||
|
||||
Over.Commandline.Base
|
||||
Over.Commandline.Modules.Cancel
|
||||
Over.Commandline.Modules.BufferComplete
|
||||
Over.Commandline.Modules.Paste
|
||||
Over.Commandline.Modules.KeyMapping
|
||||
Over.Commandline.Modules.Doautocmd
|
||||
Over.Commandline.Modules.CursorMove
|
||||
Over.Commandline.Modules.Delete
|
||||
Over.Commandline.Modules.Redraw
|
||||
Over.Commandline.Modules.InsertRegister
|
||||
Over.Commandline.Modules.History
|
||||
Over.Commandline.Modules.NoInsert
|
||||
Over.Commandline.Modules.Exit
|
||||
Over.Commandline.Modules.DrawCommandline
|
||||
Over.Commandline.Modules.ExceptionMessage
|
||||
Over.Commandline.Modules.ExceptionExit
|
||||
HitAHint.Motion
|
1232
sources_non_forked/vim-easymotion/doc/easymotion.txt
Normal file
1232
sources_non_forked/vim-easymotion/doc/easymotion.txt
Normal file
File diff suppressed because it is too large
Load diff
290
sources_non_forked/vim-easymotion/plugin/EasyMotion.vim
Normal file
290
sources_non_forked/vim-easymotion/plugin/EasyMotion.vim
Normal file
|
@ -0,0 +1,290 @@
|
|||
scriptencoding utf-8
|
||||
" EasyMotion - Vim motions on speed!
|
||||
"
|
||||
" Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com>
|
||||
" haya14busa <hayabusa1419@gmail.com>
|
||||
" Source: https://github.com/easymotion/vim-easymotion
|
||||
" == Script initialization {{{
|
||||
if expand("%:p") ==# expand("<sfile>:p")
|
||||
unlet! g:EasyMotion_loaded
|
||||
endif
|
||||
if exists('g:EasyMotion_loaded') || &compatible || version < 703
|
||||
finish
|
||||
endif
|
||||
|
||||
let g:EasyMotion_loaded = 1
|
||||
" }}}
|
||||
|
||||
" == Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
|
||||
" == Default configuration {{{
|
||||
" -- Option ------------------------------ {{{
|
||||
let g:EasyMotion_keys = get(g:,
|
||||
\ 'EasyMotion_keys', 'asdghklqwertyuiopzxcvbnmfj;')
|
||||
" \ 'EasyMotion_keys', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
|
||||
let g:EasyMotion_do_mapping = get(g: , 'EasyMotion_do_mapping' , 1)
|
||||
let g:EasyMotion_do_shade = get(g: , 'EasyMotion_do_shade' , 1)
|
||||
let g:EasyMotion_grouping = get(g: , 'EasyMotion_grouping' , 1)
|
||||
let g:EasyMotion_startofline = get(g: , 'EasyMotion_startofline' , 1)
|
||||
let g:EasyMotion_smartcase = get(g: , 'EasyMotion_smartcase' , 0)
|
||||
let g:EasyMotion_skipfoldedline = get(g: , 'EasyMotion_skipfoldedline' , 1)
|
||||
let g:EasyMotion_use_migemo = get(g: , 'EasyMotion_use_migemo' , 0)
|
||||
let g:EasyMotion_use_upper = get(g: , 'EasyMotion_use_upper' , 0)
|
||||
let g:EasyMotion_enter_jump_first = get(g: , 'EasyMotion_enter_jump_first' , 0)
|
||||
let g:EasyMotion_space_jump_first = get(g: , 'EasyMotion_space_jump_first' , 0)
|
||||
let g:EasyMotion_inc_highlight = get(g: , 'EasyMotion_inc_highlight' , 1)
|
||||
let g:EasyMotion_move_highlight = get(g: , 'EasyMotion_move_highlight' , 1)
|
||||
let g:EasyMotion_landing_highlight = get(g: , 'EasyMotion_landing_highlight' , 0)
|
||||
let g:EasyMotion_cursor_highlight = get(g: , 'EasyMotion_cursor_highlight' , 1)
|
||||
let g:EasyMotion_use_regexp = get(g: , 'EasyMotion_use_regexp' , 1)
|
||||
let g:EasyMotion_add_search_history = get(g: , 'EasyMotion_add_search_history' , 1)
|
||||
let g:EasyMotion_off_screen_search = get(g: , 'EasyMotion_off_screen_search' , 1)
|
||||
let g:EasyMotion_force_csapprox = get(g: , 'EasyMotion_force_csapprox' , 0)
|
||||
let g:EasyMotion_show_prompt = get(g: , 'EasyMotion_show_prompt' , 1)
|
||||
let g:EasyMotion_verbose = get(g: , 'EasyMotion_verbose' , 1)
|
||||
let g:EasyMotion_prompt =
|
||||
\ get(g: , 'EasyMotion_prompt' , 'Search for {n} character(s): ')
|
||||
let g:EasyMotion_command_line_key_mappings =
|
||||
\ get(g: , 'EasyMotion_command_line_key_mappings' , {})
|
||||
let g:EasyMotion_disable_two_key_combo =
|
||||
\ get(g: , 'EasyMotion_disable_two_key_combo' , 0)
|
||||
|
||||
"}}}
|
||||
|
||||
" }}}
|
||||
|
||||
" == <Plug> Mapping {{{
|
||||
" Note: bd is short for bidirectional
|
||||
" l is short for (within) line
|
||||
|
||||
function! s:motion_map_helper(motions) "{{{
|
||||
for [name, dict] in items(a:motions)
|
||||
let mapargs = []
|
||||
let xmapargs = []
|
||||
if dict.fnc ==# 'S' || dict.fnc ==# 'SL' || dict.fnc ==# 'T' || dict.fnc ==# 'TL'
|
||||
let mapargs += [dict.cnt, 0, dict.direction]
|
||||
let xmapargs += [dict.cnt, 1, dict.direction]
|
||||
elseif dict.fnc ==# 'Search'
|
||||
let mapargs += [0, dict.direction, dict.respect_direction]
|
||||
let xmapargs += [1, dict.direction, dict.respect_direction]
|
||||
else
|
||||
let mapargs += [0, dict.direction]
|
||||
let xmapargs += [1, dict.direction]
|
||||
endif
|
||||
|
||||
silent exec 'noremap <silent><Plug>(easymotion-'.name.')' .
|
||||
\ ' :<C-u>call EasyMotion#' . dict.fnc . '('. join(mapargs, ',') . ')<CR>'
|
||||
silent exec 'xnoremap <silent><Plug>(easymotion-'.name.')' .
|
||||
\ ' <Esc>:<C-u>call EasyMotion#' . dict.fnc . '('. join(xmapargs, ',') . ')<CR>'
|
||||
" Example:
|
||||
" noremap <silent><Plug>(easymotion-f2) :<C-u>call EasyMotion#S(2,1,0)<CR>
|
||||
" xnoremap <silent><Plug>(easymotion-f2) <Esc>:<C-u>call EasyMotion#S(2,1,0)<CR>
|
||||
endfor
|
||||
endfunction "}}}
|
||||
|
||||
" Find Motion: {{{
|
||||
call s:motion_map_helper({
|
||||
\ 'f' : {'fnc' : 'S' , 'cnt' : 1, 'direction' : 0},
|
||||
\ 'F' : {'fnc' : 'S' , 'cnt' : 1, 'direction' : 1},
|
||||
\ 's' : {'fnc' : 'S' , 'cnt' : 1, 'direction' : 2},
|
||||
\ 'bd-f' : {'fnc' : 'S' , 'cnt' : 1, 'direction' : 2},
|
||||
\ 't' : {'fnc' : 'T' , 'cnt' : 1, 'direction' : 0},
|
||||
\ 'T' : {'fnc' : 'T' , 'cnt' : 1, 'direction' : 1},
|
||||
\ 'bd-t' : {'fnc' : 'T' , 'cnt' : 1, 'direction' : 2},
|
||||
\ 'fl' : {'fnc' : 'SL' , 'cnt' : 1, 'direction' : 0},
|
||||
\ 'Fl' : {'fnc' : 'SL' , 'cnt' : 1, 'direction' : 1},
|
||||
\ 'sl' : {'fnc' : 'SL' , 'cnt' : 1, 'direction' : 2},
|
||||
\ 'bd-fl' : {'fnc' : 'SL' , 'cnt' : 1, 'direction' : 2},
|
||||
\ 'tl' : {'fnc' : 'TL' , 'cnt' : 1, 'direction' : 0},
|
||||
\ 'Tl' : {'fnc' : 'TL' , 'cnt' : 1, 'direction' : 1},
|
||||
\ 'bd-tl' : {'fnc' : 'TL' , 'cnt' : 1, 'direction' : 2},
|
||||
\
|
||||
\ 'f2' : {'fnc' : 'S' , 'cnt' : 2, 'direction' : 0},
|
||||
\ 'F2' : {'fnc' : 'S' , 'cnt' : 2, 'direction' : 1},
|
||||
\ 's2' : {'fnc' : 'S' , 'cnt' : 2, 'direction' : 2},
|
||||
\ 'bd-f2' : {'fnc' : 'S' , 'cnt' : 2, 'direction' : 2},
|
||||
\ 't2' : {'fnc' : 'T' , 'cnt' : 2, 'direction' : 0},
|
||||
\ 'T2' : {'fnc' : 'T' , 'cnt' : 2, 'direction' : 1},
|
||||
\ 'bd-t2' : {'fnc' : 'T' , 'cnt' : 2, 'direction' : 2},
|
||||
\ 'fl2' : {'fnc' : 'SL' , 'cnt' : 2, 'direction' : 0},
|
||||
\ 'Fl2' : {'fnc' : 'SL' , 'cnt' : 2, 'direction' : 1},
|
||||
\ 'sl2' : {'fnc' : 'SL' , 'cnt' : 2, 'direction' : 2},
|
||||
\ 'bd-fl2' : {'fnc' : 'SL' , 'cnt' : 2, 'direction' : 2},
|
||||
\ 'tl2' : {'fnc' : 'TL' , 'cnt' : 2, 'direction' : 0},
|
||||
\ 'Tl2' : {'fnc' : 'TL' , 'cnt' : 2, 'direction' : 1},
|
||||
\ 'bd-tl2' : {'fnc' : 'TL' , 'cnt' : 2, 'direction' : 2},
|
||||
\
|
||||
\ 'fn' : {'fnc' : 'S' , 'cnt' : -1, 'direction' : 0},
|
||||
\ 'Fn' : {'fnc' : 'S' , 'cnt' : -1, 'direction' : 1},
|
||||
\ 'sn' : {'fnc' : 'S' , 'cnt' : -1, 'direction' : 2},
|
||||
\ 'bd-fn' : {'fnc' : 'S' , 'cnt' : -1, 'direction' : 2},
|
||||
\ 'tn' : {'fnc' : 'T' , 'cnt' : -1, 'direction' : 0},
|
||||
\ 'Tn' : {'fnc' : 'T' , 'cnt' : -1, 'direction' : 1},
|
||||
\ 'bd-tn' : {'fnc' : 'T' , 'cnt' : -1, 'direction' : 2},
|
||||
\ 'fln' : {'fnc' : 'SL' , 'cnt' : -1, 'direction' : 0},
|
||||
\ 'Fln' : {'fnc' : 'SL' , 'cnt' : -1, 'direction' : 1},
|
||||
\ 'sln' : {'fnc' : 'SL' , 'cnt' : -1, 'direction' : 2},
|
||||
\ 'bd-fln' : {'fnc' : 'SL' , 'cnt' : -1, 'direction' : 2},
|
||||
\ 'tln' : {'fnc' : 'TL' , 'cnt' : -1, 'direction' : 0},
|
||||
\ 'Tln' : {'fnc' : 'TL' , 'cnt' : -1, 'direction' : 1},
|
||||
\ 'bd-tln' : {'fnc' : 'TL' , 'cnt' : -1, 'direction' : 2},
|
||||
\ })
|
||||
|
||||
nnoremap <silent> <Plug>(easymotion-overwin-f) :<C-u>call EasyMotion#OverwinF(1)<CR>
|
||||
nnoremap <silent> <Plug>(easymotion-overwin-f2) :<C-u>call EasyMotion#OverwinF(2)<CR>
|
||||
nnoremap <silent> <Plug>(easymotion-overwin-line) :<C-u>call EasyMotion#overwin#line()<CR>
|
||||
nnoremap <silent> <Plug>(easymotion-overwin-w) :<C-u>call EasyMotion#overwin#w()<CR>
|
||||
|
||||
"}}}
|
||||
|
||||
" -- Word Motion {{{
|
||||
call s:motion_map_helper({
|
||||
\ 'w' : {'fnc' : 'WB' , 'direction' : 0},
|
||||
\ 'b' : {'fnc' : 'WB' , 'direction' : 1},
|
||||
\ 'bd-w' : {'fnc' : 'WB' , 'direction' : 2},
|
||||
\ 'W' : {'fnc' : 'WBW', 'direction' : 0},
|
||||
\ 'B' : {'fnc' : 'WBW', 'direction' : 1},
|
||||
\ 'bd-W' : {'fnc' : 'WBW', 'direction' : 2},
|
||||
\ 'iskeyword-w' : {'fnc' : 'WBK', 'direction' : 0},
|
||||
\ 'iskeyword-b' : {'fnc' : 'WBK', 'direction' : 1},
|
||||
\ 'iskeyword-bd-w' : {'fnc' : 'WBK', 'direction' : 2},
|
||||
\
|
||||
\ 'e' : {'fnc' : 'E' , 'direction' : 0},
|
||||
\ 'ge' : {'fnc' : 'E' , 'direction' : 1},
|
||||
\ 'bd-e' : {'fnc' : 'E' , 'direction' : 2},
|
||||
\ 'E' : {'fnc' : 'EW' , 'direction' : 0},
|
||||
\ 'gE' : {'fnc' : 'EW' , 'direction' : 1},
|
||||
\ 'bd-E' : {'fnc' : 'EW' , 'direction' : 2},
|
||||
\ 'iskeyword-e' : {'fnc' : 'EK' , 'direction' : 0},
|
||||
\ 'iskeyword-ge' : {'fnc' : 'EK' , 'direction' : 1},
|
||||
\ 'iskeyword-bd-e' : {'fnc' : 'EK' , 'direction' : 2},
|
||||
\ })
|
||||
"}}}
|
||||
|
||||
" -- JK Motion {{{
|
||||
call s:motion_map_helper({
|
||||
\ 'j' : {'fnc' : 'JK' , 'direction' : 0},
|
||||
\ 'k' : {'fnc' : 'JK' , 'direction' : 1},
|
||||
\ 'bd-jk' : {'fnc' : 'JK' , 'direction' : 2},
|
||||
\ 'sol-j' : {'fnc' : 'Sol', 'direction' : 0},
|
||||
\ 'sol-k' : {'fnc' : 'Sol', 'direction' : 1},
|
||||
\ 'sol-bd-jk' : {'fnc' : 'Sol', 'direction' : 2},
|
||||
\ 'eol-j' : {'fnc' : 'Eol', 'direction' : 0},
|
||||
\ 'eol-k' : {'fnc' : 'Eol', 'direction' : 1},
|
||||
\ 'eol-bd-jk' : {'fnc' : 'Eol', 'direction' : 2},
|
||||
\ })
|
||||
"}}}
|
||||
|
||||
" -- Search Motion {{{
|
||||
call s:motion_map_helper({
|
||||
\ 'n' : {'fnc' : 'Search', 'direction': 0, 'respect_direction': 0},
|
||||
\ 'N' : {'fnc' : 'Search', 'direction': 1, 'respect_direction': 0},
|
||||
\ 'bd-n' : {'fnc' : 'Search', 'direction': 2, 'respect_direction': 0},
|
||||
\ 'vim-n' : {'fnc' : 'Search', 'direction': 0, 'respect_direction': 1},
|
||||
\ 'vim-N' : {'fnc' : 'Search', 'direction': 1, 'respect_direction': 1},
|
||||
\ })
|
||||
"}}}
|
||||
|
||||
" -- Jump To Anywhere Motion {{{
|
||||
call s:motion_map_helper({
|
||||
\ 'jumptoanywhere' : {'fnc' : 'JumpToAnywhere', 'direction': 2},
|
||||
\ })
|
||||
"}}}
|
||||
|
||||
" -- Line Motion {{{
|
||||
call s:motion_map_helper({
|
||||
\ 'wl' : {'fnc' : 'WBL', 'direction': 0},
|
||||
\ 'bl' : {'fnc' : 'WBL', 'direction': 1},
|
||||
\ 'bd-wl' : {'fnc' : 'WBL', 'direction': 2},
|
||||
\ 'el' : {'fnc' : 'EL' , 'direction': 0},
|
||||
\ 'gel' : {'fnc' : 'EL' , 'direction': 1},
|
||||
\ 'bd-el' : {'fnc' : 'EL' , 'direction': 2},
|
||||
\ 'lineforward' : {'fnc' : 'LineAnywhere', 'direction': 0},
|
||||
\ 'linebackward' : {'fnc' : 'LineAnywhere', 'direction': 1},
|
||||
\ 'lineanywhere' : {'fnc' : 'LineAnywhere', 'direction': 2},
|
||||
\ })
|
||||
"}}}
|
||||
|
||||
" -- Next, Previous Motion {{{
|
||||
noremap <silent><Plug>(easymotion-next)
|
||||
\ :<C-u>call EasyMotion#NextPrevious(0,0)<CR>
|
||||
xnoremap <silent><Plug>(easymotion-next)
|
||||
\ :<C-u>call EasyMotion#NextPrevious(1,0)<CR>
|
||||
|
||||
noremap <silent><Plug>(easymotion-prev)
|
||||
\ :<C-u>call EasyMotion#NextPrevious(0,1)<CR>
|
||||
xnoremap <silent><Plug>(easymotion-prev)
|
||||
\ :<C-u>call EasyMotion#NextPrevious(1,1)<CR>
|
||||
"}}}
|
||||
|
||||
" -- Repeat Motion {{{
|
||||
noremap <silent><Plug>(easymotion-repeat)
|
||||
\ :<C-u>call EasyMotion#Repeat(0)<CR>
|
||||
xnoremap <silent><Plug>(easymotion-repeat)
|
||||
\ <Esc>:<C-u>call EasyMotion#Repeat(1)<CR>
|
||||
|
||||
noremap <silent><Plug>(easymotion-dotrepeat)
|
||||
\ :<C-u>call EasyMotion#DotRepeat()<CR>
|
||||
"}}}
|
||||
|
||||
noremap <silent><Plug>(easymotion-activate) :<C-u>call EasyMotion#activate(0)<CR>
|
||||
xnoremap <silent><Plug>(easymotion-activate) :<C-u>call EasyMotion#activate(1)<CR>
|
||||
" }}}
|
||||
|
||||
" == Default key mapping {{{
|
||||
if g:EasyMotion_do_mapping == 1
|
||||
" Prepare Prefix: {{{
|
||||
if exists('g:EasyMotion_leader_key')
|
||||
exec 'map ' . g:EasyMotion_leader_key . ' <Plug>(easymotion-prefix)'
|
||||
else
|
||||
if !hasmapto('<Plug>(easymotion-prefix)')
|
||||
map <Leader><Leader> <Plug>(easymotion-prefix)
|
||||
endif
|
||||
endif
|
||||
"}}}
|
||||
|
||||
function! s:default_mapping(motions, do_mapping) "{{{
|
||||
for motion in a:motions
|
||||
" Mapping {{{
|
||||
if exists('g:EasyMotion_mapping_' . motion)
|
||||
" Backward compatible mapping [deprecated]
|
||||
silent exec 'map <silent> ' .
|
||||
\ eval('g:EasyMotion_mapping_' . motion) . ' <Plug>(easymotion-' . motion . ')'
|
||||
elseif a:do_mapping
|
||||
\ && !hasmapto('<Plug>(easymotion-' . motion . ')')
|
||||
\ && empty(maparg('<Plug>(easymotion-prefix)' . motion, 'nov'))
|
||||
|
||||
" Do mapping
|
||||
silent exec 'map <silent> ' .
|
||||
\'<Plug>(easymotion-prefix)' . motion . ' <Plug>(easymotion-' . motion . ')'
|
||||
endif "}}}
|
||||
endfor
|
||||
endfunction "}}}
|
||||
|
||||
" Default Mapping:
|
||||
call s:default_mapping(
|
||||
\ ['f', 'F', 's', 't', 'T',
|
||||
\ 'w', 'W', 'b', 'B', 'e', 'E', 'ge', 'gE',
|
||||
\ 'j', 'k', 'n', 'N'], g:EasyMotion_do_mapping)
|
||||
endif "}}}
|
||||
|
||||
" == CommandLine Mapping {{{
|
||||
command! -nargs=*
|
||||
\ EMCommandLineNoreMap
|
||||
\ call EasyMotion#command_line#cnoremap([<f-args>])
|
||||
command! -nargs=*
|
||||
\ EMCommandLineMap
|
||||
\ call EasyMotion#command_line#cmap([<f-args>])
|
||||
command! -nargs=1
|
||||
\ EMCommandLineUnMap
|
||||
\ call EasyMotion#command_line#cunmap(<f-args>)
|
||||
"}}}
|
||||
|
||||
" == Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" vim: fdm=marker:et:ts=4:sw=4:sts=4
|
274
sources_non_forked/vim-easymotion/t/compare_movements_spec.vim
Normal file
274
sources_non_forked/vim-easymotion/t/compare_movements_spec.vim
Normal file
|
@ -0,0 +1,274 @@
|
|||
"=============================================================================
|
||||
" FILE: t/compare_movements_spec.vim
|
||||
" AUTHOR: YggdrasiI
|
||||
" Test: https://github.com/kana/vim-vspec
|
||||
" Description: EasyMotion keyword movement test with vim-vspec
|
||||
" License: MIT license {{{
|
||||
" Permission is hereby granted, free of charge, to any person obtaining
|
||||
" a copy of this software and associated documentation files (the
|
||||
" "Software"), to deal in the Software without restriction, including
|
||||
" without limitation the rights to use, copy, modify, merge, publish,
|
||||
" distribute, sublicense, and/or sell copies of the Software, and to
|
||||
" permit persons to whom the Software is furnished to do so, subject to
|
||||
" the following conditions:
|
||||
"
|
||||
" The above copyright notice and this permission notice shall be included
|
||||
" in all copies or substantial portions of the Software.
|
||||
"
|
||||
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
|
||||
" Setup {{{
|
||||
let s:root_dir = matchstr(system('git rev-parse --show-cdup'), '[^\n]\+')
|
||||
|
||||
" The consumed time depends from the length of the text and could be really high
|
||||
" on vimdoc pages. (See it 'Loop through Vim help buffer and compare movements')
|
||||
" Reduce this value to stop CompareMovements(...) before it reached the end of the
|
||||
" buffer.
|
||||
let s:maximal_number_of_compared_movments = 10000
|
||||
execute 'set' 'rtp +=./'.s:root_dir
|
||||
runtime! plugin/EasyMotion.vim
|
||||
" }}}
|
||||
|
||||
" Functions for Test {{{
|
||||
function! AddLine(str)
|
||||
put =a:str
|
||||
endfunction
|
||||
|
||||
function! CursorPos()
|
||||
return [line('.'), col('.'), getline('.')[col('.')-1]]
|
||||
endfunction
|
||||
|
||||
" Nested normal to avoid throwing readonly errors. They abort the testing.
|
||||
function TryNormal(str)
|
||||
try
|
||||
exec 'normal ' . a:str
|
||||
catch /^Vim\%((\a\+)\)\=:E21/
|
||||
endtry
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
let s:to_cursor = {}
|
||||
function! s:to_cursor.match(actual, expected)
|
||||
return a:actual == a:expected
|
||||
endfunction
|
||||
|
||||
" Add metadata about failure.
|
||||
function! s:to_cursor.failure_message_for_should(actual, expected)
|
||||
Expect a:actual[0] > 0
|
||||
Expect a:expected[0] > 0
|
||||
Expect a:actual[0] <= getpos('$')[1]
|
||||
Expect a:expected[0] <= getpos('$')[1]
|
||||
Expect a:actual[1] > 0
|
||||
Expect a:expected[1] > 0
|
||||
|
||||
let line1 = getline(a:actual[0])
|
||||
let line2 = getline(a:expected[0])
|
||||
" Change char on cursor to '█'.
|
||||
let line1 = strpart(l:line1, 0, a:actual[1]-1)
|
||||
\ . '█'
|
||||
\ . strpart(l:line1, a:actual[1])
|
||||
let line2 = strpart(l:line2, 0, a:expected[1]-1)
|
||||
\ . '█'
|
||||
\ . strpart(l:line2, a:expected[1])
|
||||
" Separation of both cases with \n would be nice, but
|
||||
" vim-vspec allow oneliners as return string, only.
|
||||
let msg = 'Line ' . string(a:actual[0]) . ": '" . l:line1
|
||||
\ . "',\x09\x09 Line " . string(a:expected[0]) . ": '" . l:line2 . "'\x0a"
|
||||
return l:msg
|
||||
endfunction
|
||||
|
||||
function! CompareMovements(movement1, movement2, backward)
|
||||
let jumpmarks = [
|
||||
\ [a:movement1, []],
|
||||
\ [a:movement2, []],
|
||||
\ ]
|
||||
|
||||
" Loop through current buffer in both variants {{
|
||||
for [l:handler, l:list] in l:jumpmarks
|
||||
if a:backward == 1
|
||||
let last_line = line('$')
|
||||
let last_char = len(getline(l:last_line))
|
||||
call cursor(l:last_line, l:last_char)
|
||||
else
|
||||
call cursor([1,1])
|
||||
endif
|
||||
|
||||
let lastpos = [0,0]
|
||||
|
||||
" Centralize line. Otherwise, Easymotion functions aborts
|
||||
" at the end of the (virtual) window.
|
||||
call TryNormal('zz')
|
||||
call TryNormal(l:handler)
|
||||
let curpos = getpos(".")[1:2]
|
||||
|
||||
while l:lastpos != l:curpos
|
||||
let list += [l:curpos]
|
||||
let lastpos = l:curpos
|
||||
call TryNormal('zz')
|
||||
call TryNormal(l:handler)
|
||||
let curpos = getpos(".")[1:2]
|
||||
" Abort after a fixed number of steps.
|
||||
if len(l:list) > s:maximal_number_of_compared_movments
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
endfor
|
||||
" }}
|
||||
|
||||
" The resulting lists are stored in l:jumpmarks[*][1], now.
|
||||
let [l:cursor_positions1, l:cursor_positions2] = [ l:jumpmarks[0][1], l:jumpmarks[1][1] ]
|
||||
|
||||
if l:cursor_positions1 == l:cursor_positions2
|
||||
return 0
|
||||
endif
|
||||
|
||||
" Search for first unmatching position. {{
|
||||
let index = 0
|
||||
let len = min([len(l:cursor_positions2), len(l:cursor_positions1)])
|
||||
while l:index < l:len
|
||||
Expect l:cursor_positions2[l:index] to_cursor l:cursor_positions1[l:index]
|
||||
let index += 1
|
||||
endwhile
|
||||
|
||||
" Collision with begin or end of file or while loop aborts to early.
|
||||
if a:backward == 1
|
||||
Expect join([a:movement2, ': File begin reached after ', len(l:cursor_positions2), ' steps.'])
|
||||
\ == join([a:movement1, ': File begin reached after ', len(l:cursor_positions1), ' steps.'])
|
||||
else
|
||||
Expect l:cursor_positions2[l:index-1] to_cursor l:cursor_positions1[l:index]
|
||||
Expect join([a:movement2, ': File end reached after ', len(l:cursor_positions2), ' steps.'])
|
||||
\ == join([a:movement1, ': File end reached after ', len(l:cursor_positions1), ' steps.'])
|
||||
endif
|
||||
" }}
|
||||
|
||||
return -1
|
||||
endfunction
|
||||
|
||||
" Hand crafted text with rare cases
|
||||
function! InsertTestText1()
|
||||
|
||||
" Blanks at document begin
|
||||
call AddLine('')
|
||||
call AddLine(' ')
|
||||
call AddLine('')
|
||||
|
||||
call AddLine('scriptencoding utf-8')
|
||||
|
||||
" '^\s*[not-\k]'-case
|
||||
call AddLine('!foo')
|
||||
call AddLine(' !bar')
|
||||
|
||||
call AddLine('<!{}>s! ')
|
||||
|
||||
" Blanks at document end
|
||||
call AddLine('')
|
||||
call AddLine(' ')
|
||||
call AddLine('')
|
||||
endfunction
|
||||
|
||||
"}}}
|
||||
|
||||
"Keyword word motion {{{
|
||||
describe 'Keyword word motion'
|
||||
before
|
||||
new
|
||||
resize 10
|
||||
nmap a <Nop>
|
||||
let g:EasyMotion_keys = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
let g:EasyMotion_maximal_jumpmarks = 2 " Error for value 1 unanalyzed.
|
||||
nmap <Leader>w <Plug>(easymotion-iskeyword-w)
|
||||
nmap <Leader>b <Plug>(easymotion-iskeyword-b)
|
||||
nmap <Leader>e <Plug>(easymotion-iskeyword-e)
|
||||
nmap <Leader>ge <Plug>(easymotion-iskeyword-ge)
|
||||
nmap <Leader>W <Plug>(easymotion-W)
|
||||
nmap <Leader>B <Plug>(easymotion-B)
|
||||
nmap <Leader>E <Plug>(easymotion-E)
|
||||
nmap <Leader>gE <Plug>(easymotion-gE)
|
||||
call EasyMotion#init()
|
||||
call vspec#customize_matcher('to_cursor', s:to_cursor)
|
||||
end
|
||||
|
||||
after
|
||||
close!
|
||||
end
|
||||
|
||||
it 'Simple test to check setup of this test'
|
||||
" Check if a is remapped to <Nop> to avoid start of insert mode.
|
||||
normal aa\<Esc>
|
||||
Expect getline(1) == ''
|
||||
|
||||
call AddLine('word')
|
||||
Expect CompareMovements('w', 'w', 0) == 0
|
||||
Expect CompareMovements('w', '\wa', 0) == 0
|
||||
Expect CompareMovements('b', '\ba', 1) == 0
|
||||
Expect CompareMovements('e', '\ea', 0) == 0
|
||||
Expect CompareMovements('ge', '\gea', 1) == 0
|
||||
Expect CompareMovements('W', '\Wa', 0) == 0
|
||||
Expect CompareMovements('B', '\Ba', 1) == 0
|
||||
Expect CompareMovements('E', '\Ea', 0) == 0
|
||||
Expect CompareMovements('gE', '\gEa', 1) == 0
|
||||
end
|
||||
|
||||
it 'w'
|
||||
call InsertTestText1()
|
||||
Expect CompareMovements('w', '\wa', 0) == 0
|
||||
end
|
||||
|
||||
it 'b'
|
||||
call InsertTestText1()
|
||||
Expect CompareMovements('b', '\ba', 1) == 0
|
||||
end
|
||||
|
||||
it 'e'
|
||||
call InsertTestText1()
|
||||
Expect CompareMovements('e', '\ea', 0) == 0
|
||||
end
|
||||
|
||||
it 'ge'
|
||||
call InsertTestText1()
|
||||
Expect CompareMovements('ge', '\gea', 1) == 0
|
||||
end
|
||||
|
||||
it 'W'
|
||||
call InsertTestText1()
|
||||
Expect CompareMovements('W', 'W', 0) == 0
|
||||
end
|
||||
|
||||
it 'B'
|
||||
call InsertTestText1()
|
||||
Expect CompareMovements('B', 'B', 1) == 0
|
||||
end
|
||||
|
||||
it 'E'
|
||||
call InsertTestText1()
|
||||
Expect CompareMovements('E', 'E', 0) == 0
|
||||
end
|
||||
|
||||
it 'gE'
|
||||
call InsertTestText1()
|
||||
Expect CompareMovements('gE', 'gE', 1) == 0
|
||||
end
|
||||
|
||||
" Really time consuming test...
|
||||
"it 'Loop through Vim help buffer and compare movements'
|
||||
" help motion.txt
|
||||
" Expect expand('%:t') ==# 'motion.txt'
|
||||
" "Optional: Copy text into editable buffer
|
||||
" exec "normal! Gygg\<C-W>cP"
|
||||
" Expect CompareMovements('w', '\wa', 0) == 0
|
||||
"end
|
||||
|
||||
end
|
||||
"}}}
|
||||
|
||||
" __END__ {{{
|
||||
" vim: fdm=marker:et:ts=4:sw=4:sts=4
|
||||
" }}}
|
1471
sources_non_forked/vim-easymotion/t/easymotion_spec.vim
Normal file
1471
sources_non_forked/vim-easymotion/t/easymotion_spec.vim
Normal file
File diff suppressed because it is too large
Load diff
110
sources_non_forked/vim-easymotion/t/operator_pending_spec.vim
Normal file
110
sources_non_forked/vim-easymotion/t/operator_pending_spec.vim
Normal file
|
@ -0,0 +1,110 @@
|
|||
"=============================================================================
|
||||
" FILE: t/operator_pending_spec.vim
|
||||
" AUTHOR: haya14busa
|
||||
" License: MIT license {{{
|
||||
" Permission is hereby granted, free of charge, to any person obtaining
|
||||
" a copy of this software and associated documentation files (the
|
||||
" "Software"), to deal in the Software without restriction, including
|
||||
" without limitation the rights to use, copy, modify, merge, publish,
|
||||
" distribute, sublicense, and/or sell copies of the Software, and to
|
||||
" permit persons to whom the Software is furnished to do so, subject to
|
||||
" the following conditions:
|
||||
"
|
||||
" The above copyright notice and this permission notice shall be included
|
||||
" in all copies or substantial portions of the Software.
|
||||
"
|
||||
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
|
||||
" Avoid source test files {{{
|
||||
if expand("%:p") ==# expand("<sfile>:p")
|
||||
finish
|
||||
endif
|
||||
"}}}
|
||||
|
||||
" Setup {{{
|
||||
let s:root_dir = matchstr(system('git rev-parse --show-cdup'), '[^\n]\+')
|
||||
execute 'set' 'rtp +=./'.s:root_dir
|
||||
runtime! plugin/EasyMotion.vim
|
||||
"}}}
|
||||
|
||||
" Functions for Test {{{
|
||||
function! AddLine(str)
|
||||
put! =a:str
|
||||
endfunction
|
||||
|
||||
function! CursorPos()
|
||||
return [line('.'), col('.'), getline('.')[col('.')-1]]
|
||||
endfunction
|
||||
"}}}
|
||||
|
||||
|
||||
" NOTE:
|
||||
" I cannot test inclusive motion because mode() doesn't works well with
|
||||
" vim-vspec
|
||||
|
||||
" word motions {{{
|
||||
describe 'word motions'
|
||||
before
|
||||
new
|
||||
let g:EasyMotion_keys = '123456789'
|
||||
omap f <Plug>(easymotion-f)
|
||||
omap w <Plug>(easymotion-w)
|
||||
omap b <Plug>(easymotion-b)
|
||||
call EasyMotion#init()
|
||||
call AddLine('vim deco vim deco vim deco')
|
||||
" 123456789012345678901234567890
|
||||
end
|
||||
|
||||
after
|
||||
close!
|
||||
end
|
||||
|
||||
it '<Plug>(easymotion-w)'
|
||||
" Default position
|
||||
normal! 0
|
||||
let l = line('.')
|
||||
Expect CursorPos() == [l,1,'v']
|
||||
|
||||
normal dw1
|
||||
Expect CursorPos() == [l,1,'d']
|
||||
normal! u
|
||||
normal! 0
|
||||
Expect CursorPos() == [l,1,'v']
|
||||
|
||||
normal dw2
|
||||
Expect CursorPos() == [l,1,'v']
|
||||
normal! 0
|
||||
normal! u
|
||||
normal! 0
|
||||
Expect CursorPos() == [l,1,'v']
|
||||
end
|
||||
|
||||
it '<Plug>(easymotion-b)'
|
||||
" Default position
|
||||
normal! $
|
||||
let l = line('.')
|
||||
Expect CursorPos() == [l,26,'o']
|
||||
|
||||
normal db1
|
||||
Expect CursorPos() == [l,23,'o']
|
||||
normal! u
|
||||
normal! $
|
||||
Expect CursorPos() == [l,26,'o']
|
||||
|
||||
normal db2
|
||||
Expect CursorPos() == [l,19,'o']
|
||||
normal! u
|
||||
normal! $
|
||||
Expect CursorPos() == [l,26,'o']
|
||||
end
|
||||
end
|
||||
"}}}
|
||||
|
575
sources_non_forked/vim-easymotion/t/smartsign_spec.vim
Normal file
575
sources_non_forked/vim-easymotion/t/smartsign_spec.vim
Normal file
|
@ -0,0 +1,575 @@
|
|||
"=============================================================================
|
||||
" FILE: t/smartsign_spec.vim
|
||||
" AUTHOR: haya14busa
|
||||
" License: MIT license {{{
|
||||
" Permission is hereby granted, free of charge, to any person obtaining
|
||||
" a copy of this software and associated documentation files (the
|
||||
" "Software"), to deal in the Software without restriction, including
|
||||
" without limitation the rights to use, copy, modify, merge, publish,
|
||||
" distribute, sublicense, and/or sell copies of the Software, and to
|
||||
" permit persons to whom the Software is furnished to do so, subject to
|
||||
" the following conditions:
|
||||
"
|
||||
" The above copyright notice and this permission notice shall be included
|
||||
" in all copies or substantial portions of the Software.
|
||||
"
|
||||
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
|
||||
" Test for `smartsign` feature for find motions
|
||||
|
||||
" Avoid source test files {{{
|
||||
if expand("%:p") ==# expand("<sfile>:p")
|
||||
finish
|
||||
endif
|
||||
"}}}
|
||||
|
||||
" Setup {{{
|
||||
let s:root_dir = matchstr(system('git rev-parse --show-cdup'), '[^\n]\+')
|
||||
execute 'set' 'rtp +=./'.s:root_dir
|
||||
runtime! plugin/EasyMotion.vim
|
||||
"}}}
|
||||
|
||||
" Functions for Test {{{
|
||||
function! AddLine(str)
|
||||
put! =a:str
|
||||
endfunction
|
||||
|
||||
function! CursorPos()
|
||||
return [line('.'), col('.'), getline('.')[col('.')-1]]
|
||||
endfunction
|
||||
"}}}
|
||||
|
||||
" Smartsign configulation {{{
|
||||
describe 'Smartsign configulation'
|
||||
it 'provide default dictionary'
|
||||
let smartdict_us = g:EasyMotion#sticky_table#us
|
||||
let smartdict_jp = g:EasyMotion#sticky_table#jp
|
||||
Expect smartdict_us !=# {}
|
||||
Expect smartdict_jp !=# {}
|
||||
end
|
||||
end
|
||||
"}}}
|
||||
|
||||
" Basic Smartsign feature with 1-key findmotions with US layout {{{
|
||||
describe 'Basic Smartsign feature with 1-key findmotions with US layout'
|
||||
before
|
||||
new
|
||||
let g:EasyMotion_keys = '123456789'
|
||||
let g:EasyMotion_use_smartsign_us = 1
|
||||
map s <Plug>(easymotion-s)
|
||||
call EasyMotion#init()
|
||||
call AddLine(' -_ =+ ;: [{ ]} `~ ''" \|')
|
||||
call AddLine(' 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0)')
|
||||
call AddLine(' ,< .> /?')
|
||||
" 123456789012345678901234567890
|
||||
" 1 2 3
|
||||
"
|
||||
" ',' : '<', '.' : '>', '/' : '?',
|
||||
" '1' : '!', '2' : '@', '3' : '#', '4' : '$', '5' : '%',
|
||||
" '6' : '^', '7' : '&', '8' : '*', '9' : '(', '0' : ')', '-' : '_', '=' : '+',
|
||||
" ';' : ':', '[' : '{', ']' : '}', '`' : '~', "'" : "\"", '\' : '|',
|
||||
end
|
||||
|
||||
after
|
||||
close!
|
||||
end
|
||||
|
||||
it 'works well for all sign as a target char'
|
||||
" Default position
|
||||
normal! 0
|
||||
let l = line('.')
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
|
||||
" ,<
|
||||
normal s,1
|
||||
Expect CursorPos() == [l,2,',']
|
||||
normal! 0
|
||||
normal s,2
|
||||
Expect CursorPos() == [l,3,'<']
|
||||
normal! 0
|
||||
normal s<1
|
||||
Expect CursorPos() == [l,3,'<']
|
||||
normal! 0
|
||||
normal s,3
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
|
||||
" .>
|
||||
normal s.1
|
||||
Expect CursorPos() == [l,5,'.']
|
||||
normal! 0
|
||||
normal s.2
|
||||
Expect CursorPos() == [l,6,'>']
|
||||
normal! 0
|
||||
normal s>1
|
||||
Expect CursorPos() == [l,6,'>']
|
||||
normal! 0
|
||||
normal s.3
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
|
||||
" /?
|
||||
normal s/1
|
||||
Expect CursorPos() == [l,8,'/']
|
||||
normal! 0
|
||||
normal s/2
|
||||
Expect CursorPos() == [l,9,'?']
|
||||
normal! 0
|
||||
normal s?1
|
||||
Expect CursorPos() == [l,9,'?']
|
||||
normal! 0
|
||||
normal s/3
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
|
||||
" 1!
|
||||
normal s11
|
||||
Expect CursorPos() == [l+1,2,'1']
|
||||
normal! 0
|
||||
normal s12
|
||||
Expect CursorPos() == [l+1,3,'!']
|
||||
normal! 0
|
||||
normal s!1
|
||||
Expect CursorPos() == [l+1,3,'!']
|
||||
normal! 0
|
||||
normal s13
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
|
||||
" 2@
|
||||
normal s21
|
||||
Expect CursorPos() == [l+1,5,'2']
|
||||
normal! 0
|
||||
normal s22
|
||||
Expect CursorPos() == [l+1,6,'@']
|
||||
normal! 0
|
||||
normal s@1
|
||||
Expect CursorPos() == [l+1,6,'@']
|
||||
normal! 0
|
||||
normal s23
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
|
||||
" 3#
|
||||
normal s31
|
||||
Expect CursorPos() == [l+1,8,'3']
|
||||
normal! 0
|
||||
normal s32
|
||||
Expect CursorPos() == [l+1,9,'#']
|
||||
normal! 0
|
||||
normal s#1
|
||||
Expect CursorPos() == [l+1,9,'#']
|
||||
normal! 0
|
||||
normal s33
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
|
||||
" 4$
|
||||
normal s41
|
||||
Expect CursorPos() == [l+1,11,'4']
|
||||
normal! 0
|
||||
normal s42
|
||||
Expect CursorPos() == [l+1,12,'$']
|
||||
normal! 0
|
||||
normal s$1
|
||||
Expect CursorPos() == [l+1,12,'$']
|
||||
normal! 0
|
||||
normal s43
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
|
||||
" 5%
|
||||
normal s51
|
||||
Expect CursorPos() == [l+1,14,'5']
|
||||
normal! 0
|
||||
normal s52
|
||||
Expect CursorPos() == [l+1,15,'%']
|
||||
normal! 0
|
||||
normal s%1
|
||||
Expect CursorPos() == [l+1,15,'%']
|
||||
normal! 0
|
||||
normal s53
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
|
||||
" 6^
|
||||
normal s61
|
||||
Expect CursorPos() == [l+1,17,'6']
|
||||
normal! 0
|
||||
normal s62
|
||||
Expect CursorPos() == [l+1,18,'^']
|
||||
normal! 0
|
||||
normal s^1
|
||||
Expect CursorPos() == [l+1,18,'^']
|
||||
normal! 0
|
||||
normal s63
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
|
||||
" 7&
|
||||
normal s71
|
||||
Expect CursorPos() == [l+1,20,'7']
|
||||
normal! 0
|
||||
normal s72
|
||||
Expect CursorPos() == [l+1,21,'&']
|
||||
normal! 0
|
||||
normal s&1
|
||||
Expect CursorPos() == [l+1,21,'&']
|
||||
normal! 0
|
||||
normal s73
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
|
||||
" 8*
|
||||
normal s81
|
||||
Expect CursorPos() == [l+1,23,'8']
|
||||
normal! 0
|
||||
normal s82
|
||||
Expect CursorPos() == [l+1,24,'*']
|
||||
normal! 0
|
||||
normal s*1
|
||||
Expect CursorPos() == [l+1,24,'*']
|
||||
normal! 0
|
||||
normal s83
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
|
||||
" 9(
|
||||
normal s91
|
||||
Expect CursorPos() == [l+1,26,'9']
|
||||
normal! 0
|
||||
normal s92
|
||||
Expect CursorPos() == [l+1,27,'(']
|
||||
normal! 0
|
||||
normal s(1
|
||||
Expect CursorPos() == [l+1,27,'(']
|
||||
normal! 0
|
||||
normal s93
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
|
||||
" 0)
|
||||
normal s01
|
||||
Expect CursorPos() == [l+1,29,'0']
|
||||
normal! 0
|
||||
normal s02
|
||||
Expect CursorPos() == [l+1,30,')']
|
||||
normal! 0
|
||||
normal s)1
|
||||
Expect CursorPos() == [l+1,30,')']
|
||||
normal! 0
|
||||
normal s03
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
|
||||
" -_
|
||||
normal s-1
|
||||
Expect CursorPos() == [l+2,2,'-']
|
||||
normal! 0
|
||||
normal s-2
|
||||
Expect CursorPos() == [l+2,3,'_']
|
||||
normal! 0
|
||||
normal s_1
|
||||
Expect CursorPos() == [l+2,3,'_']
|
||||
normal! 0
|
||||
normal s-3
|
||||
Expect CursorPos() == [l+2,1,' ']
|
||||
normal! 0
|
||||
|
||||
" =+
|
||||
normal s=1
|
||||
Expect CursorPos() == [l+2,5,'=']
|
||||
normal! 0
|
||||
normal s=2
|
||||
Expect CursorPos() == [l+2,6,'+']
|
||||
normal! 0
|
||||
normal s+1
|
||||
Expect CursorPos() == [l+2,6,'+']
|
||||
normal! 0
|
||||
normal s=3
|
||||
Expect CursorPos() == [l+2,1,' ']
|
||||
normal! 0
|
||||
|
||||
" ;:
|
||||
normal s;1
|
||||
Expect CursorPos() == [l+2,8,';']
|
||||
normal! 0
|
||||
normal s;2
|
||||
Expect CursorPos() == [l+2,9,':']
|
||||
normal! 0
|
||||
normal s:1
|
||||
Expect CursorPos() == [l+2,9,':']
|
||||
normal! 0
|
||||
normal s;3
|
||||
Expect CursorPos() == [l+2,1,' ']
|
||||
normal! 0
|
||||
|
||||
" [{
|
||||
normal s[1
|
||||
Expect CursorPos() == [l+2,11,'[']
|
||||
normal! 0
|
||||
normal s[2
|
||||
Expect CursorPos() == [l+2,12,'{']
|
||||
normal! 0
|
||||
normal s{1
|
||||
Expect CursorPos() == [l+2,12,'{']
|
||||
normal! 0
|
||||
normal s[3
|
||||
Expect CursorPos() == [l+2,1,' ']
|
||||
normal! 0
|
||||
|
||||
" ]}
|
||||
normal s]1
|
||||
Expect CursorPos() == [l+2,14,']']
|
||||
normal! 0
|
||||
normal s]2
|
||||
Expect CursorPos() == [l+2,15,'}']
|
||||
normal! 0
|
||||
normal s}1
|
||||
Expect CursorPos() == [l+2,15,'}']
|
||||
normal! 0
|
||||
normal s]3
|
||||
Expect CursorPos() == [l+2,1,' ']
|
||||
normal! 0
|
||||
|
||||
" `~
|
||||
normal s`1
|
||||
Expect CursorPos() == [l+2,17,'`']
|
||||
normal! 0
|
||||
normal s`2
|
||||
Expect CursorPos() == [l+2,18,'~']
|
||||
normal! 0
|
||||
normal s~1
|
||||
Expect CursorPos() == [l+2,18,'~']
|
||||
normal! 0
|
||||
normal s`3
|
||||
Expect CursorPos() == [l+2,1,' ']
|
||||
normal! 0
|
||||
|
||||
" '"
|
||||
normal s'1
|
||||
Expect CursorPos() == [l+2,20,'''']
|
||||
normal! 0
|
||||
normal s'2
|
||||
Expect CursorPos() == [l+2,21,'"']
|
||||
normal! 0
|
||||
normal s"1
|
||||
Expect CursorPos() == [l+2,21,'"']
|
||||
normal! 0
|
||||
normal s'3
|
||||
Expect CursorPos() == [l+2,1,' ']
|
||||
normal! 0
|
||||
|
||||
" \|
|
||||
normal s\1
|
||||
Expect CursorPos() == [l+2,23,'\']
|
||||
normal! 0
|
||||
normal s\2
|
||||
Expect CursorPos() == [l+2,24,'|']
|
||||
normal! 0
|
||||
normal s|1
|
||||
Expect CursorPos() == [l+2,24,'|']
|
||||
normal! 0
|
||||
normal s\3
|
||||
Expect CursorPos() == [l+2,1,' ']
|
||||
normal! 0
|
||||
end
|
||||
end
|
||||
"}}}
|
||||
|
||||
" Smartsign with 2-key find motions with US layout {{{
|
||||
describe 'Smartsign with 2-key find motions with US layout'
|
||||
before
|
||||
new
|
||||
let g:EasyMotion_keys = '123456789'
|
||||
let g:EasyMotion_use_smartsign_us = 1
|
||||
map s <Plug>(easymotion-s2)
|
||||
call EasyMotion#init()
|
||||
call AddLine(' -_ =+ ;: [{ ]} `~ ''" \|')
|
||||
call AddLine(' 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0)')
|
||||
call AddLine(' ,< .> /?')
|
||||
call AddLine(' -_ =+ ;: [{ ]} `~ ''" \|')
|
||||
call AddLine(' 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0)')
|
||||
call AddLine(' ,< .> /?')
|
||||
" 123456789012345678901234567890
|
||||
" 1 2 3
|
||||
end
|
||||
|
||||
after
|
||||
close!
|
||||
end
|
||||
|
||||
it 'works well'
|
||||
" Default position
|
||||
normal! 0
|
||||
let l = line('.')
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
|
||||
" ,<
|
||||
normal s,,1
|
||||
Expect CursorPos() == [l,2,',']
|
||||
normal! 0
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal s,,3
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
normal s, 1
|
||||
Expect CursorPos() == [l,3,'<']
|
||||
normal! 0
|
||||
normal s<<1
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
normal s,<1
|
||||
Expect CursorPos() == [l,2,',']
|
||||
normal! 0
|
||||
normal s<,1
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
end
|
||||
it ': s,,3'
|
||||
normal! 0
|
||||
let l = line('.')
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal s,,3
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
end
|
||||
|
||||
it 'escape * asterisc #151'
|
||||
normal! 0
|
||||
let l = line('.')
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal s1*22
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
normal s8*1
|
||||
Expect CursorPos() == [l+1,23,'8']
|
||||
normal! 0
|
||||
normal s881
|
||||
Expect CursorPos() == [l+1,23,'8']
|
||||
normal! 0
|
||||
normal s**1
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
normal s*81
|
||||
Expect CursorPos() == [l+1,1,' ']
|
||||
normal! 0
|
||||
end
|
||||
end
|
||||
"}}}
|
||||
|
||||
" Smartsign with 2-key find motions with JP layout {{{
|
||||
describe 'Smartsign with 2-key find motions with JP layout'
|
||||
before
|
||||
new
|
||||
let g:EasyMotion_keys = '123456789'
|
||||
let g:EasyMotion_use_smartsign_jp = 1
|
||||
map s <Plug>(easymotion-s2)
|
||||
call EasyMotion#init()
|
||||
call AddLine(' -= ^~ ;+ :* [{ ]} @` \|')
|
||||
call AddLine(' 1! 2" 3# 4$ 5% 6& 7'' 8( 9) 0_')
|
||||
call AddLine(' ,< .> /?')
|
||||
call AddLine(' -= ^~ ;+ :* [{ ]} @` \|')
|
||||
call AddLine(' 1! 2" 3# 4$ 5% 6& 7'' 8( 9) 0_')
|
||||
call AddLine(' ,< .> /?')
|
||||
" 123456789012345678901234567890
|
||||
" 1 2 3
|
||||
"
|
||||
"',' : '<', '.' : '>', '/' : '?',
|
||||
"'1' : '!', '2' : '"', '3' : '#', '4' : '$', '5' : '%',
|
||||
"'6' : '&', '7' : "'", '8' : '(', '9' : ')', '0' : '_', '-' : '=', '^' : '~',
|
||||
"';' : '+', ':' : '*', '[' : '{', ']' : '}', '@' : '`', '\' : '|',
|
||||
"
|
||||
end
|
||||
|
||||
after
|
||||
close!
|
||||
end
|
||||
|
||||
it 'works well'
|
||||
" Default position
|
||||
normal! 0
|
||||
let l = line('.')
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
|
||||
" ,<
|
||||
normal s,,1
|
||||
Expect CursorPos() == [l,2,',']
|
||||
normal! 0
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal s,,3
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
normal s, 1
|
||||
Expect CursorPos() == [l,3,'<']
|
||||
normal! 0
|
||||
normal s<<1
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
normal s,<1
|
||||
Expect CursorPos() == [l,2,',']
|
||||
normal! 0
|
||||
normal s<,1
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
end
|
||||
it ': s,,3'
|
||||
normal! 0
|
||||
let l = line('.')
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal s,,3
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
end
|
||||
end
|
||||
"}}}
|
||||
|
||||
" Smartsign with n-key find search motions {{{
|
||||
describe 'Smartsign with n-key find search motions'
|
||||
before
|
||||
new
|
||||
let g:EasyMotion_keys = '123456789'
|
||||
let g:EasyMotion_use_smartsign_jp = 1
|
||||
map / <Plug>(easymotion-sn)
|
||||
call EasyMotion#init()
|
||||
call AddLine(' -= ^~ ;+ :* [{ ]} @` \|')
|
||||
call AddLine(' 1! 2" 3# 4$ 5% 6& 7'' 8( 9) 0_')
|
||||
call AddLine(' ,< .> /?')
|
||||
call AddLine(' -= ^~ ;+ :* [{ ]} @` \|')
|
||||
call AddLine(' 1! 2" 3# 4$ 5% 6& 7'' 8( 9) 0_')
|
||||
call AddLine(' ,< .> /?')
|
||||
end
|
||||
|
||||
after
|
||||
close!
|
||||
end
|
||||
|
||||
it 'do not work'
|
||||
" Default position
|
||||
normal! 0
|
||||
let l = line('.')
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
|
||||
" ,<
|
||||
normal /,,1
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
normal /,<1
|
||||
Expect CursorPos() == [l,1,' ']
|
||||
normal! 0
|
||||
end
|
||||
end
|
||||
"}}}
|
||||
|
||||
" __END__ {{{
|
||||
" vim: expandtab softtabstop=4 shiftwidth=4
|
||||
" vim: foldmethod=marker
|
||||
" }}}
|
Loading…
Reference in a new issue