vim可视模式插入问题

Vim、Emacs配置和使用
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

vim可视模式插入问题

#1

帖子 eexpress » 2011-11-24 13:44

在可视模式,就是鼠标选择文字,想按{[(就直接在所选文字2边插入相应符号。不知道如何定义map。
● 鸣学
sarrow
帖子: 403
注册时间: 2007-10-27 1:04

Re: vim可视模式插入问题

#2

帖子 sarrow » 2011-11-24 13:59

竟然是ee大人!
这里有我写的一个插件;我是放在autoload/util.vim下面的;

然后针对txt或者cpp源代码文件,分别启用util#Pair*_chinese_style(),function! util#Pair*_english_style()。

另外,util#PairAdd_*_style(),util#PairVisual_*_style(),分别可视模式的成队添加或者选中。另外,本插件还带有自动修改的功能。用了就知道。

代码: 全选

" User Interfaces:			" {{{1
function! util#PairAdd_chinese_style()	" {{{2
    inoremap <buffer> <A-'> ‘’<Left>
    inoremap <buffer> <A-"> “”<Left>
    inoremap <buffer> <A-9> ()<Left>
    inoremap <buffer> <A-(> ()<Left>
    inoremap <buffer> <A-[> 『』<Left>
    inoremap <buffer> <A-{> 「」<Left>
    inoremap <buffer> <A-<> 《》<Left>

    vnoremap <buffer> <A-'> <ESC>:call util#Quote_this_block('‘', '’', "'\"“”‘’")<CR>
    vnoremap <buffer> <A-"> <ESC>:call util#Quote_this_block('“', '”', "'\"“”‘’")<CR>
    vnoremap <buffer> <A-9> <ESC>:call util#Quote_this_block('(', ')', "()()")<CR>
    vnoremap <buffer> <A-(> <ESC>:call util#Quote_this_block('(', ')', "()()")<CR>
    vnoremap <buffer> <A-[> <ESC>:call util#Quote_this_block('『', '』', "『』")<CR>
    vnoremap <buffer> <A-{> <ESC>:call util#Quote_this_block('「', '」', "「」")<CR>
    vnoremap <buffer> <A-<> <ESC>:call util#Quote_this_block('《', '》', "<>《》")<CR>
endfunction

function! util#PairAdd_english_style()	" {{{2
    inoremap <buffer> <A-[> []<Left>
    inoremap <buffer> <A-{> {}<Left>
    inoremap <buffer> <A-(> ()<Left>
    inoremap <buffer> <A-'> ''<Left>
    inoremap <buffer> <A-"> ""<Left>
    inoremap <buffer> <A-<> <><Left>

    vnoremap <buffer> <A-'> <ESC>:call util#Quote_this_block("'", "'", "'\"")<CR>
    vnoremap <buffer> <A-"> <ESC>:call util#Quote_this_block('"', '"', "'\"")<CR>
    vnoremap <buffer> <A-(> <ESC>:call util#Quote_this_block("(", ")", "()")<CR>
    vnoremap <buffer> <A-[> <ESC>:call util#Quote_this_block("[", "]", "[]")<CR>
    vnoremap <buffer> <A-{> <ESC>:call util#Quote_this_block("{", "}", "{}")<CR>
    vnoremap <buffer> <A-<> <ESC>:call util#Quote_this_block("<", ">", "<>")<CR>
    vnoremap <buffer> <A-Space> <ESC>:call util#Quote_this_block(" ", " ", " ")<CR>
endfunction

function! util#PairVisual_chinese_style()	" {{{2
    vnoremap <buffer> a'	<ESC>:call util#VisualPairOf('‘', '’', 1)<CR>
    vnoremap <buffer> i'	<ESC>:call util#VisualPairOf('‘', '’', 0)<CR>

    vnoremap <buffer> a"	<ESC>:call util#VisualPairOf('“', '”', 1)<CR>
    vnoremap <buffer> i"	<ESC>:call util#VisualPairOf('“', '”', 0)<CR>

    vnoremap <buffer> a<	<ESC>:call util#VisualPairOf('《', '》', 1)<CR>
    vnoremap <buffer> i<	<ESC>:call util#VisualPairOf('《', '》', 0)<CR>

    vnoremap <buffer> a[	<ESC>:call util#VisualPairOf('『', '』', 1)<CR>
    vnoremap <buffer> i[	<ESC>:call util#VisualPairOf('『', '』', 0)<CR>
endfunction

function! util#PairVisual_english_style()	" {{{2
    " Sarrow:
    " vim系统已经内建支持。
    "vnoremap <buffer> a'	<ESC>:call util#VisualPairOf('‘', '’', 1)<CR>
    "vnoremap <buffer> a"	<ESC>:call util#VisualPairOf('“', '”', 1)<CR>

    "vnoremap <buffer> i'	<ESC>:call util#VisualPairOf('‘', '’', 0)<CR>
    "vnoremap <buffer> i"	<ESC>:call util#VisualPairOf('“', '”', 0)<CR>

    " Sarrow: 2011-09-15
    vnoremap <buffer> a/	<ESC>:call util#VisualPairOf('/', '/', 1)<CR>
    vnoremap <buffer> i/	<ESC>:call util#VisualPairOf('/', '/', 0)<CR>

    vnoremap <buffer> ax	<ESC>:call util#VisualPairOf('x', 'x', 1)<CR>
    vnoremap <buffer> a"	<ESC>:call util#VisualPairOf('"', '"', 1)<CR>

    vnoremap <buffer> a\	<ESC>:call util#VisualPairOf('\', '\', 1)<CR>
    vnoremap <buffer> i\	<ESC>:call util#VisualPairOf('\', '\', 0)<CR>
endfunction

" Util Functions:
" Sarrow: 2010-12-19
function! util#Quote_this_block(q_b, q_e, sequence)	" {{{2
    let _tw_ = &tw
    let &tw=0
    let _tmp_a_ = @a
    normal gv"ay
    " NOTE: 空格 本身应该被替换掉!
    let _pattern_ = '[ '.a:sequence.']$'
    let _str_ = @a
    if _str_ !~ a:q_e.'$'
	if _str_ =~ _pattern_
	    silent normal! `>s=a:q_e
	else
	    silent normal! `>a=a:q_e
	endif
    endif
    let _pattern_ = '^[ '.a:sequence.']'
    if _str_ !~ '^'.a:q_b
	if _str_ =~ _pattern_
	    silent normal! `<s=a:q_b
	else
	    silent normal! `<i=a:q_b
	endif
    endif
    let @a = _tmp_a_
    let &tw=_tw_
endfunction

" mark begin: m_b
" mark end  : m_e
" is include mark : flag(Zero or none Zero)
function! util#VisualPairOf(m_b, m_e, flag)	" {{{2
    let [b_r, b_c] = searchpairpos(escape(a:m_b,'\*'), '', escape(a:m_e,'\*'), 'ncbW')
    " Sarrow: 2011年01月14日 21:31:21
    "vnoremap <buffer> i'	<ESC>/’/b-1<CR>v?‘?e+1<CR>
    "vnoremap <buffer> i"	<ESC>/”/b-1<CR>v?“?e+1<CR>
    if b_r
	let m_e= escape(a:m_e,'/\*')
	let m_b= escape(a:m_b,'?\*')
	if a:flag
	    " Sarrow: 2011-09-16
	    execute 'silent normal /'.m_e."\<CR>v?".m_b."\<CR>"
	    "silent normal! /=m_e

v?=m_b

	    " End:
	else
	    execute 'silent normal /'.m_e."/b-1\<CR>v?".m_b."?e+1\<CR>"
	    "silent normal! /=m_e
/b-1
v?=m_b
?e+1
	endif
    endif
    " Sarrow: 2011年01月14日 21:12:16	{{{3
    " sick-style implementation
    " is there any beautiful ones exists?
    "
    " execute "normal! /\<C-R>=".a:m_e."\<CR>v?\<C-R>=".a:m_b."\<CR>"
    " <ESC>/’<CR>v?‘<CR>
    " <ESC>/’/b-1<CR>v?‘?e+1<CR>
    "if b_r
    "    let [e_r, e_c] = searchpairpos(a:m_b, '', a:m_e, 'nW')
    "    let keys = 'v'
    "    if a:flag
    "        call search(a:m_b, 'cb')
    "    else
    "        call search(a:m_b, 'cbe')
    "        let keys .= 'lol'
    "    endif
    "    let line_to_down = e_r - b_r
    "    if !a:flag && e_c == 1
    "        let line_to_down -= 1
    "    endif
    "    let keys .= repeat('j',  line_to_down)
    "    if (b_c > e_c)
    "        let keys .= '0'
    "    endif
    "    if a:flag
    "        let keys .= 'f'.a:m_e
    "    elseif e_c > 1
    "        let keys .= 't'.a:m_e
    "    else
    "        let keys .= '$'
    "    endif
    "    execute "normal! ".keys
    "endif	}}}3
endfunction
上次由 sarrow 在 2011-11-24 14:23,总共编辑 1 次。
sarrow
帖子: 403
注册时间: 2007-10-27 1:04

Re: vim可视模式插入问题

#3

帖子 sarrow » 2011-11-24 14:19

晕了——有些特殊的字符显示不出来!

嗯,弄了一个util#Quote_this_block函数的修改版:

代码: 全选

" Util Functions:
" Sarrow: 2010-12-19
function! util#Quote_this_block(q_b, q_e, sequence)	" {{{2
    let _tw_ = &tw
    let &tw=0
    let _tmp_a_ = @a
    normal gv"ay
    " NOTE: 空格 本身应该被替换掉!
    let _pattern_ = '[ '.a:sequence.']$'
    let _str_ = @a
    " Sarrow: 2011-11-24
    " 用 execute 方式,替换掉可视字符
    if _str_ !~ a:q_e.'$'
	if _str_ =~ _pattern_
	    execute "silent normal! `>s\<C-R>=a:q_e\<CR>"
	else
	    execute "silent normal! `>a\<C-R>=a:q_e\<CR>"
	endif
    endif
    let _pattern_ = '^[ '.a:sequence.']'
    if _str_ !~ '^'.a:q_b
	if _str_ =~ _pattern_
	    execute "silent normal! `<s\<C-R>=a:q_b\<CR>"
	else
	    execute "silent normal! `<i\<C-R>=a:q_b\<CR>"
	endif
    endif
    " End: 2011-11-24
    let @a = _tmp_a_
    let &tw=_tw_
endfunction
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: vim可视模式插入问题

#4

帖子 eexpress » 2011-11-24 15:18

这么复杂啊。我以为只有几行的函数,就是当前词前后插入呢。

let w = expand("<cword>")
然后前后插入{}[]()这样的。
● 鸣学
sarrow
帖子: 403
注册时间: 2007-10-27 1:04

Re: vim可视模式插入问题

#5

帖子 sarrow » 2011-11-24 15:36

我考虑的情况比你的复杂——比如:

"xxx"选中,然后替换成“xxx”——就是半角变全角;
“xxx 选中补上一个”,变成“xxx”。
还有空格,默认会在替换/添加的时候,删除掉。

但是,真正的代码也很短,就是类似这样的语句了:

execute "silent normal! `>s\<C-R>=a:q_e\<CR>"

多出来的代码,就是封装了。
头像
rykka
帖子: 59
注册时间: 2011-06-24 9:14

Re: vim可视模式插入问题

#6

帖子 rykka » 2011-11-24 16:33

代码: 全选

vnoremap [p <esc>`>a]<esc>`<i[<esc>evi[
vnoremap (( <esc>`>a)<esc>`<i(<esc>evi(
vnoremap {{ <esc>`>a}<esc>`<i{<esc>evi{
默认选中括号内字符。
[[在vim脚本里和本来的mapping有冲突。

或者

代码: 全选

vn [p c[<C-r>"]<ESC>`[evi[
vn (( c(<C-r>")<ESC>`[evi(
vn {{ c{<C-r>"}<ESC>`[evi{
补完
上次由 rykka 在 2011-11-24 16:59,总共编辑 2 次。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: vim可视模式插入问题

#7

帖子 eexpress » 2011-11-24 16:47

{{这样,也可接受,还不错。
多谢。
● 鸣学
头像
Fermat618
帖子: 728
注册时间: 2008-12-28 16:01

Re: vim可视模式插入问题

#8

帖子 Fermat618 » 2011-11-24 16:49

有个叫surround的插件就是做这个的。可视选择以后,按s及接着按{[("'等,两边就可以插入相应的符号。
爱因斯坦会弹钢琴
爱因斯坦会拉小提琴
爱因斯坦会骑自行车
头像
rykka
帖子: 59
注册时间: 2011-06-24 9:14

Re: vim可视模式插入问题

#9

帖子 rykka » 2011-11-24 17:12

用surround.vim的话

对于鼠标选择的区域,先要<ctrl-g> 将select转化为visual 然后"S",然后插入符号。

不是特别方便。

最关键在于会失去选择区域。
头像
rykka
帖子: 59
注册时间: 2011-06-24 9:14

Re: vim可视模式插入问题

#10

帖子 rykka » 2011-11-24 17:25

这两个mapping也并非完全可靠。
1.后面那个可能会跟smart indent之类有冲突
2.可能选中的是其内部的[]()""对,如果选中的第一个字符是相应symbol的话
头像
Fermat618
帖子: 728
注册时间: 2008-12-28 16:01

Re: vim可视模式插入问题

#11

帖子 Fermat618 » 2011-11-24 20:59

rykka 写了:用surround.vim的话
对于鼠标选择的区域,先要<ctrl-g> 将select转化为visual 然后"S",然后插入符号。
不是特别方便。
最关键在于会失去选择区域。
第一个一般是那个mswin.vim搞成那样的。
[vim]
:help :behave
:help 'selectmode'
[/vim]
恢复原来的选择,按

代码: 全选

gv
即可。
爱因斯坦会弹钢琴
爱因斯坦会拉小提琴
爱因斯坦会骑自行车
头像
rykka
帖子: 59
注册时间: 2011-06-24 9:14

Re: vim可视模式插入问题

#12

帖子 rykka » 2011-11-24 21:46

添加'[]'后所括住的文字位置已经改变了,
但gv选择的还是原来的区域。


原来selectmode可以直接改掉。这个好
" set 'selection', 'selectmode', 'mousemodel' and 'keymodel' for MS-Windows
原来如此。
头像
tenzu
论坛版主
帖子: 36924
注册时间: 2008-11-21 20:26

Re: vim可视模式插入问题

#13

帖子 tenzu » 2011-11-24 22:00

神这是要闹哪样? :em70
niejieqiang
帖子: 151
注册时间: 2009-05-29 22:05

Re: vim可视模式插入问题

#14

帖子 niejieqiang » 2011-11-24 23:29

zencoding,专门针对css,html开发的插件。
不过我仅仅只是用它来写wordpress
很好用的说。
:em32
头像
Fermat618
帖子: 728
注册时间: 2008-12-28 16:01

Re: vim可视模式插入问题

#15

帖子 Fermat618 » 2011-11-25 4:10

rykka 写了:添加'[]'后所括住的文字位置已经改变了,
但gv选择的还是原来的区域。
你没有用surround插件吧,我这里gv后,选择的区域也已经更新到包含新加的[]了。
爱因斯坦会弹钢琴
爱因斯坦会拉小提琴
爱因斯坦会骑自行车
回复