1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-23 10:30:05 +08:00

Highlight symbol mode (#1394)

This commit is contained in:
Wang Shidong 2018-02-15 21:02:45 +08:00 committed by GitHub
parent a2495b4c9a
commit 1fe370de9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 444 additions and 51 deletions

View File

@ -44,6 +44,13 @@ Here is a throughput graph of the repository for the last few weeks:
## Features
**Highlight cursor symbol**
SpaceVim supports highlighting of the current symbol on demand and adds
a transient state to easily navigate and rename this symbol.
![highlight cursor symbol](https://user-images.githubusercontent.com/13142418/36210381-e6dffde6-1163-11e8-9b35-0bf262e6f22b.gif)
[**Fly Grep in Vim**](https://spacevim.org/grep-on-the-fly-in-spacevim/)
With this feature, vim will display the searching result as you type. Of course, it is running

View File

@ -5,6 +5,8 @@ let s:self._on_syntax = ''
let s:self._title = 'Transient State'
let s:self._handle_inputs = {}
let s:self._is_quit = []
let s:self._handle_quit = {}
let s:self.noredraw = 0
function! s:self.open() abort
noautocmd botright split __transient_state__
@ -37,8 +39,23 @@ function! s:self.open() abort
endif
" move to prvious window
wincmd p
if has_key(self._keys, 'init')
call call(self._keys.init, [])
endif
while 1
redraw!
if has_key(self._keys, 'logo')
noautocmd wincmd p
if self.noredraw
redraw!
endif
call call(self._keys.logo, [])
noautocmd wincmd p
endif
if !self.noredraw
redraw!
else
let self.noredraw = 0
endif
let char = self._getchar()
if char ==# "\<FocusLost>" || char ==# "\<FocusGained>" || char2nr(char) == 128
continue
@ -58,6 +75,14 @@ function! s:self.open() abort
endwhile
exe 'bd ' . self._bufid
doautocmd WinEnter
if has_key(self._handle_quit, char)
if type(self._handle_quit[char]) == 2
call call(self._handle_quit[char], [])
elseif type(self._handle_quit[char]) == 1
exe self._handle_quit[char]
endif
endif
redraw!
endfunction
@ -108,7 +133,7 @@ else
endif
function! s:self._update_content() abort
if get(self._keys, 'layout', '') == 'vertical split'
if get(self._keys, 'layout', '') ==# 'vertical split'
let linenum = max([len(self._keys.right), len(self._keys.left)])
let left_max_key_len = 0
for key in self._keys.left
@ -130,14 +155,25 @@ function! s:self._update_content() abort
let right_max_key_len = max([len(key.key.name), right_max_key_len])
endif
endfor
if has_key(self._keys, 'logo') && has_key(self._keys, 'logo_width')
let logo_width = self._keys.logo_width
else
let logo_width = 0
endif
for i in range(linenum)
let left = get(self._keys.left, i)
let right = get(self._keys.right, i)
let line = ''
let line = repeat(' ', logo_width)
if !empty(left)
if type(left.key) == 1
let line .= '[' . left.key . '] ' . repeat(' ', left_max_key_len - len(left.key)) . left.desc
call self.highlight_keys(left.exit, i + 2, 1, 1 + len(left.key))
if left.key ==# "\<tab>"
let line .= '[Tab] ' . repeat(' ', left_max_key_len - len(left.key)) . left.desc
call self.highlight_keys(left.exit, i + 2, 1 + logo_width, 1 + logo_width + 3)
else
let line .= '[' . left.key . '] ' . repeat(' ', left_max_key_len - len(left.key)) . left.desc
call self.highlight_keys(left.exit, i + 2, 1 + logo_width, 1 + logo_width + len(left.key))
endif
if !empty(left.cmd)
call extend(self._handle_inputs, {left.key : left.cmd})
elseif !empty(left.func)
@ -145,12 +181,15 @@ function! s:self._update_content() abort
endif
if left.exit
call add(self._is_quit, left.key)
if has_key(left, 'exit_cmd') && !empty(left.exit_cmd)
call extend(self._handle_quit, {left.key : left.exit_cmd})
endif
endif
elseif type(left.key) == 3
let line .= '[' . join(left.key, '/') . '] '
let line .= repeat(' ', left_max_key_len - len(join(left.key, '/')))
let line .= left.desc
let begin = 1
let begin = 1 + logo_width
for key in left.key
call self.highlight_keys(left.exit, i + 2, begin, begin + len(key))
let begin = begin + len(key) + 1
@ -166,6 +205,10 @@ function! s:self._update_content() abort
endif
if left.exit
call extend(self._is_quit, left.key)
" TODO: need fix
" if has_key(left, 'exit_cmd') && !empty(left.exit_cmd)
" call extend(self._handle_quit, {left.key : left.exit_cmd})
" endif
endif
elseif type(left.key) == 4
let line .= '[' . left.key.name . '] '
@ -179,14 +222,18 @@ function! s:self._update_content() abort
endfor
if left.exit
call extend(self._is_quit, keys(left.key))
" TODO: need to fixed
" if has_key(left, 'exit_cmd') && !empty(left.exit_cmd)
" call extend(self._handle_quit, {left.key : left.exit_cmd})
" endif
endif
endif
endif
let line .= repeat(' ', 40 - len(line))
let line .= repeat(' ', 40 + logo_width - len(line))
if !empty(right)
if type(right.key) == 1
let line .= '[' . right.key . '] ' . repeat(' ', right_max_key_len - len(right.key)) . right.desc
call self.highlight_keys(right.exit, i + 2, 41, 41 + len(right.key))
call self.highlight_keys(right.exit, i + 2, 41 + logo_width, 41 + logo_width + len(right.key))
if !empty(right.cmd)
call extend(self._handle_inputs, {right.key : right.cmd})
elseif !empty(right.func)
@ -194,12 +241,15 @@ function! s:self._update_content() abort
endif
if right.exit
call add(self._is_quit, right.key)
if has_key(right, 'exit_cmd') && !empty(right.exit_cmd)
call extend(self._handle_quit, {right.key : right.exit_cmd})
endif
endif
elseif type(right.key) == 3
let line .= '[' . join(right.key, '/') . '] '
let line .= repeat(' ', right_max_key_len - len(join(right.key, '/')))
let line .= right.desc
let begin = 41
let begin = 41 + logo_width
for key in right.key
call self.highlight_keys(right.exit, i + 2, begin, begin + len(key))
let begin = begin + len(key) + 1
@ -215,12 +265,16 @@ function! s:self._update_content() abort
endif
if right.exit
call extend(self._is_quit, right.key)
" TODO: need fix
" if has_key(right, 'exit_cmd') && !empty(right.exit_cmd)
" call extend(self._handle_quit, {right.key : right.exit_cmd})
" endif
endif
elseif type(right.key) == 4
let line .= '[' . right.key.name . '] '
let line .= repeat(' ', right_max_key_len - len(right.key.name))
let line .= right.desc
let begin = 41
let begin = 41 + logo_width
for pos in right.key.pos
call self.highlight_keys(right.exit, i + 2, begin + pos[0], begin + pos[1])
endfor
@ -229,6 +283,10 @@ function! s:self._update_content() abort
endfor
if right.exit
call extend(self._is_quit, keys(right.key))
" TODO: need fix
" if has_key(right, 'exit_cmd') && !empty(right.exit_cmd)
" call extend(self._handle_quit, {right.key : right.exit_cmd})
" endif
endif
endif
endif

View File

@ -20,6 +20,7 @@ endfunction
function! SpaceVim#layers#lang#vim#config() abort
call SpaceVim#mapping#gd#add('vim','lookup#lookup')
call SpaceVim#mapping#space#regesit_lang_mappings('vim', function('s:language_specified_mappings'))
call SpaceVim#plugins#highlight#reg_expr('vim', '^\s*\(func\|fu\|function\)!\?\s\+', '^\s*\(endfunc\|endf\|endfunction\)')
endfunction
function! s:language_specified_mappings() abort

View File

@ -6,36 +6,308 @@
" License: MIT license
"=============================================================================
" TODO: {{{
" e: iedit
" d/D: next previous definition
" f: search files
" s: swoop
" }}}
" Loadding SpaceVim api {{{
let s:VIMH = SpaceVim#api#import('vim#highlight')
let s:STRING = SpaceVim#api#import('data#string')
"}}}
" init local variable {{{
let s:function_expr = {}
let s:hi_range_id = 0
let s:hi_range_index = 0
" }}}
" transient_state API func: logo {{{
function! s:range_logo() abort
let line = getline(3)
let range = s:current_range
let index = '[' . (s:index + 1) . '/' . len(s:stack) . ']'
let logo = s:STRING.fill_middle(range . ' ' . index, 30)
let begin = stridx(logo, s:current_range)
call setline(3, logo . line[30:])
try
call matchdelete(s:hi_range_id)
call matchdelete(s:hi_range_index)
catch
endtry
let s:hi_range_id = matchaddpos('HiRrange' . s:current_range, [[3, begin, len(s:current_range) + 2]])
let s:hi_range_index = matchaddpos('HiRrangeIndex', [[3, begin + len(s:current_range) + 2, len(index) + 2]])
redraw!
echon ' Change current range to:'
exe 'echohl HiRrange' . s:current_range
echon s:current_range
echohl None
endfunction
" }}}
" transient_state API func: init {{{
let s:hi_info = [
\ {
\ 'name' : 'HiPurpleBold',
\ 'guibg' : '#d3869b',
\ 'guifg' : '#282828',
\ 'ctermbg' : '',
\ 'ctermfg' : 175,
\ 'bold' : 1,
\ },
\ {
\ 'name' : 'HiRrangeDisplay',
\ 'guibg' : '#458588',
\ 'guifg' : '#282828',
\ 'ctermbg' : '',
\ 'ctermfg' : 175,
\ 'bold' : 1,
\ },
\ {
\ 'name' : 'HiRrangeBuffer',
\ 'guibg' : '#689d6a',
\ 'guifg' : '#282828',
\ 'ctermbg' : '',
\ 'ctermfg' : 175,
\ 'bold' : 1,
\ },
\ {
\ 'name' : 'HiRrangeFunction',
\ 'guibg' : '#d38696',
\ 'guifg' : '#282828',
\ 'ctermbg' : '',
\ 'ctermfg' : 175,
\ 'bold' : 1,
\ },
\ {
\ 'name' : 'HiRrangeIndex',
\ 'guibg' : '#3c3836',
\ 'guifg' : '#a89984',
\ 'ctermbg' : 237,
\ 'ctermfg' : 246,
\ 'bold' : 1,
\ },
\ {
\ 'name' : 'HiBlueBold',
\ 'guibg' : '#83a598',
\ 'guifg' : '#282828',
\ 'ctermbg' : '',
\ 'ctermfg' : 109,
\ 'bold' : 1,
\ }
\ ]
function! s:hi() abort
for info in s:hi_info
call s:VIMH.hi(info)
endfor
endfunction
function! s:init() abort
call s:hi()
let s:current_range = 'Display'
let [s:stack, s:index] = SpaceVim#plugins#iedit#paser(line('w0'), line('w$'), s:current_match, 0)
call s:highlight()
endfunction
" }}}
" public API func: start Highlight mode {{{
function! SpaceVim#plugins#highlight#start() abort
let state = SpaceVim#api#import('transient_state')
let stack = []
call state.set_title('Highlight Transient State')
call state.defind_keys(
let curpos = getcurpos()
let save_reg_k = @k
normal! viw"ky
let s:current_match = @k
let @k = save_reg_k
call setpos('.', curpos)
let s:state = SpaceVim#api#import('transient_state')
call s:state.set_title('Highlight Transient State')
call s:state.defind_keys(
\ {
\ 'layout' : 'vertical split',
\ 'logo' : s:_function('s:range_logo'),
\ 'logo_width' : 30,
\ 'init' : s:_function('s:init'),
\ 'left' : [
\ {
\ 'key' : 'n',
\ 'desc' : 'Toggle highlight',
\ 'func' : s:_function('s:next_item'),
\ 'cmd' : '',
\ 'exit' : 0,
\ },
\ {
\ 'key' : "\<tab>",
\ 'desc' : 'Toggle highlight',
\ 'func' : s:_function('s:toggle_item'),
\ 'cmd' : '',
\ 'exit' : 0,
\ },
\ {
\ 'key' : 'r',
\ 'desc' : 'change range',
\ 'func' : '',
\ 'cmd' : 'call call(' . string(s:_function('s:change_range')) . ', [])',
\ 'exit' : 0,
\ },
\ {
\ 'key' : 'e',
\ 'desc' : 'iedit',
\ 'cmd' : '',
\ 'func' : '',
\ 'exit_cmd' : 'call call(' . string(s:_function('s:iedit')) . ', [])',
\ 'exit' : 1,
\ },
\ ],
\ 'right' : [
\ {
\ 'key' : ['N', 'p'],
\ 'desc' : 'Previous match',
\ 'cmd' : 'call call(' . string(s:_function('s:previous_item')) . ', [])',
\ 'func' : '',
\ 'exit' : 0,
\ },
\ {
\ 'key' : 'b',
\ 'desc' : 'search buffers',
\ 'cmd' : '',
\ 'func' : '',
\ 'exit_cmd' : 'call call(' . string(s:_function('s:search_buffers')) . ', [])',
\ 'exit' : 1,
\ },
\ {
\ 'key' : '/',
\ 'desc' : 'Search project',
\ 'cmd' : '',
\ 'func' : '',
\ 'exit_cmd' : 'call call(' . string(s:_function('s:search_project')) . ', [])',
\ 'exit' : 1,
\ },
\ {
\ 'key' : 'R',
\ 'desc' : 'Reset',
\ 'cmd' : '',
\ 'func' : s:_function('s:reset_range'),
\ 'exit' : 0,
\ },
\ ],
\ }
\ )
call state.open()
call s:state.open()
try
call s:clear_highlight()
catch
endtry
endfunction
" }}}
" public API func: register function range expression {{{
function! SpaceVim#plugins#highlight#reg_expr(ft, begin, end) abort
call extend(s:function_expr, {a:ft : [a:begin, a:end]})
endfunction
" }}}
" key binding: R reset_range {{{
function! s:reset_range() abort
let s:current_range = 'Display'
let [s:stack, s:index] = SpaceVim#plugins#iedit#paser(line('w0'), line('w$'), s:current_match, 0)
call s:clear_highlight()
call s:highlight()
endfunction
"}}}
" key binding: n next_item {{{
function! s:next_item() abort
if s:index == len(s:stack) - 1
let s:index = 0
else
let s:index += 1
endif
call cursor(s:stack[s:index][0], s:stack[s:index][1] + s:stack[s:index][2] - 1)
call s:update_highlight()
endfunction
" }}}
" key binding: r change_range {{{
function! s:change_range() abort
if s:current_range ==# 'Display'
let s:current_range = 'Buffer'
let [s:stack, s:index] = SpaceVim#plugins#iedit#paser(1, line('$'), s:current_match, 0)
call s:clear_highlight()
call s:highlight()
elseif s:current_range ==# 'Buffer'
let s:current_range = 'Function'
let range = s:find_func_range()
let [s:stack, s:index] = SpaceVim#plugins#iedit#paser(range[0], range[1], s:current_match, 0)
call s:clear_highlight()
call s:highlight()
elseif s:current_range ==# 'Function'
let s:current_range = 'Display'
let [s:stack, s:index] = SpaceVim#plugins#iedit#paser(line('w0'), line('w$'), s:current_match, 0)
call s:clear_highlight()
call s:highlight()
endif
let s:state.noredraw = 1
endfunction
" }}}
" key binding: e iedit {{{
function! s:iedit() abort
call SpaceVim#plugins#iedit#start()
endfunction
" }}}
" key binding: N/p previous_item {{{
function! s:previous_item() abort
if s:index == 0
let s:index = len(s:stack) - 1
else
let s:index -= 1
endif
call cursor(s:stack[s:index][0], s:stack[s:index][1] + s:stack[s:index][2] - 1)
call s:update_highlight()
endfunction
" }}}
" key binding: b search_buffers {{{
function! s:search_buffers() abort
call SpaceVim#plugins#flygrep#open({'input' : s:current_match, 'files':'@buffers'})
endfunction
" }}}
" key binding: / search_project {{{
function! s:search_project() abort
call spacevim#plugins#flygrep#open({'input' : s:current_match})
endfunction
" }}}
" local func: highlight symbol {{{
function! s:highlight() abort
let s:highlight_id = []
for item in s:stack
call add(s:highlight_id, matchaddpos('HiBlueBold', [ item ]))
endfor
let s:highlight_id_c = matchaddpos('HiPurpleBold', [s:stack[s:index]])
endfunction
" }}}
" local func: clear highlight {{{
function! s:clear_highlight() abort
for id in s:highlight_id
call matchdelete(id)
endfor
call matchdelete(s:highlight_id_c)
endfunction
" }}}
" key binding: Tab toggle_item {{{
function! s:toggle_item() abort
endfunction
" function() wrapper
endfunction
" }}}
" local func: function() wrapper {{{
if v:version > 703 || v:version == 703 && has('patch1170')
function! s:_function(fstr) abort
return function(a:fstr)
@ -49,3 +321,29 @@ else
return function(substitute(a:fstr, 's:', s:_s, 'g'))
endfunction
endif
" }}}
" local func: update highlight symbol {{{
function! s:update_highlight() abort
call s:clear_highlight()
call s:highlight()
endfunction
" }}}
" local func: find function range {{{
function! s:find_func_range() abort
let line = line('.')
if !empty(&ft) && has_key(s:function_expr, &ft)
let begin = s:function_expr[&ft][0]
let end = s:function_expr[&ft][1]
let pos1 = search(end, 'nb',line('w0'))
let pos2 = search(begin, 'nb',line('w0'))
let pos3 = search(end, 'n',line('w$'))
let pos0 = line('.')
if pos1 < pos2 && pos2 < pos0 && pos0 < pos3
return [pos2, pos3]
endif
endif
return [line, line]
endfunction
" }}}

View File

@ -21,7 +21,7 @@ let s:cursor_stack = []
let s:iedit_hi_info = [
\ {
\ 'name' : 'IeditPurpleBold',
\ 'guibg' : '',
\ 'guibg' : '#3c3836',
\ 'guifg' : '#d3869b',
\ 'ctermbg' : '',
\ 'ctermfg' : 175,
@ -29,7 +29,7 @@ let s:iedit_hi_info = [
\ },
\ {
\ 'name' : 'IeditBlueBold',
\ 'guibg' : '',
\ 'guibg' : '#3c3836',
\ 'guifg' : '#83a598',
\ 'ctermbg' : '',
\ 'ctermfg' : 109,
@ -79,30 +79,30 @@ function! SpaceVim#plugins#iedit#start(...)
let s:mode = 'n'
let w:spacevim_iedit_mode = s:mode
let w:spacevim_statusline_mode = 'in'
let curpos = getcurpos()
let argv = get(a:000, 0, '')
let save_reg_k = @k
let use_expr = 0
if !empty(argv) && type(argv) == 4
if has_key(argv, 'expr')
let use_expr = 1
let symbol = argv.expr
elseif has_key(argv, 'word')
let symbol = argv.word
elseif has_key(argv, 'stack')
endif
elseif type(argv) == 0 && argv == 1
normal! gv"ky
let symbol = split(@k, "\n")[0]
else
normal! viw"ky
let symbol = split(@k, "\n")[0]
endif
let @k = save_reg_k
call setpos('.', curpos)
let begin = get(a:000, 1, 1)
let end = get(a:000, 2, line('$'))
if empty(s:stack)
let curpos = getcurpos()
let argv = get(a:000, 0, '')
let save_reg_k = @k
let use_expr = 0
if !empty(argv) && type(argv) == 4
if has_key(argv, 'expr')
let use_expr = 1
let symbol = argv.expr
elseif has_key(argv, 'word')
let symbol = argv.word
elseif has_key(argv, 'stack')
endif
elseif type(argv) == 0 && argv == 1
normal! gv"ky
let symbol = split(@k, "\n")[0]
else
normal! viw"ky
let symbol = split(@k, "\n")[0]
endif
let @k = save_reg_k
call setpos('.', curpos)
let begin = get(a:000, 1, 1)
let end = get(a:000, 2, line('$'))
if use_expr
call s:parse_symbol(begin, end, symbol, 1)
else
@ -338,7 +338,6 @@ function! s:parse_symbol(begin, end, symbol, ...) abort
let s:index = 0
call cursor(s:stack[0][0], s:stack[0][1])
endif
let g:wsd = [s:stack, s:cursor_stack]
endfunction
@ -400,4 +399,11 @@ function! s:fixstack(idxs) abort
endfor
endfunction
function! SpaceVim#plugins#iedit#paser(begin, end, symbol, expr) abort
let s:cursor_stack = []
let s:stack = []
call s:parse_symbol(a:begin, a:end, a:symbol, a:expr)
return [deepcopy(s:stack), s:index]
endfunction
" vim:set et sw=2 cc=80 nowrap:

View File

@ -10,8 +10,6 @@ lang: cn
## 讨论
关于中文讨论,其实一直没有找到合适的讨论区,类似与 reddit 的网站还没有。
- <i class="fab fa-discourse"></i> [知乎专栏](https://zhuanlan.zhihu.com/SpaceVim)
- <i class="fab fa-weibo"></i> [新浪微博](https://weibo.com/SpaceVim)
- <i class="fab fa-weixin"></i> 微信公众号SpaceVim
@ -23,5 +21,9 @@ lang: cn
## 聊天
需要说明下,自 2018-02-11 起 QQ 群的加入方式改为付费加入,目的在于提高 QQ 群交流质量,对于不假思索的提问、斗图、或者是无礼争论会直接 T 掉,希望大家珍惜这个清爽的交流环境:
进群后,请不要发布无意义的内容,在你提问前,请务必要阅读[《提问的智慧》](http://doc.zengrong.net/smart-questions/cn.html)。
- <i class="fab fa-qq"></i> [`121056965` SpaceVim 中文交流群](https://jq.qq.com/?_wv=1027&k=43DB6SG)
- <i class="fab fa-telegram-plane"></i> [`t.me/VimHub` Vim 中文 telegram 群](https://t.me/VimHub)

View File

@ -1,11 +1,29 @@
### 我应该把我的配置文件放到什么位置?
---
title: "FAQ"
description: "SpaceVim 常见问题详解,包括安装、更新、设置等等"
---
# SpaceVim 常见问题解答
这里罗列了一些关于 SpaceVim 的常见问题,如果你觉得需要添加某些问题,欢迎帮助改进本页面。
## 我应该把我的配置文件放到什么位置?
SpaceVim 默认从 ~/.SpaceVim.d/init.vim 中加载配置文件.
1. E492: 未编辑的命令: ^M
## E492: 未编辑的命令: ^M
这个问题是git在克隆过程中,自动添加了^M, 可以通过下面的方法来解决:
```sh
git config --global core.autocrlf input
```
## 为什么 SpaceVim 颜色怪异?
因为在 SpaceVim 中,默认情况下是启用了终端真色,因此你需要确保你的终端支持真色。
当然如果实在没有办法支持真色,你可以禁用 SpaceVim 的真色选项, 在 `~/.SpaceVim.d/init.vim`
文件中添加:
```vim
let g:spacevim_enable_guicolors = 0
```

View File

@ -1402,7 +1402,10 @@ In highlight symbol transient state:
| ------------- | ------------------------------------------------------------- |
| `e` | edit occurrences (`*`) |
| `n` | go to next occurrence |
| `N` | go to previous occurrence |
| `N`/`p` | go to previous occurrence |
| `b` | search occurrence in all buffers |
| `/` | search occurrence in whole project |
| `Tab` | toggle highlight current occurrence |
| `r` | change range (function, display area, whole buffer) |
| `R` | go to home occurrence (reset position to starting occurrence) |
| Any other key | leave the navigation transient state |