(不是Swap text around equal sign的可能重复:)
我经常发现自己在交换东西。这是屁股的痛苦。
我写完这段代码之后就说吧
tmp = realloc (words, sizeof (char **) * (*count + 1));
我注意到连续的星号太多,不喜欢它,并希望在乘法星号周围交换这两个因子。
或者,我写了
#if !defined(_CONSOLE_H_) && defined (__MINGW32__)
但我突然意识到defined (__MINGW32__)
必须先出于某种原因。
我认为如果能做到这样的话会很酷:
(在一个字符x
上,[x]
表示光标位置。<S>
代表这种假设的“交换”命令)
#if [!]defined(_CONSOLE_H_) && defined (__MINGW32__)
命令:vf&<S>$
=&gt;选择从光标到枢轴(单词&&
),并将选择与文本交换到行尾。
或者,对于前一个例子:
tmp = realloc (words, [s]izeof (char **) * (*count + 1));
命令:v3f*<S>f)
=&gt;从此处选择第三个*
,将文字转发至)
。
对我来说,它会非常有用。有没有这样的东西,或者我必须编写自己的插件?
谢谢!
编辑 -
作为@ib。在他的回答的评论中说,我需要更具体地说明什么是支点。
枢轴也可以是一个角色,例如:
static char ** tokenize_input (char * input, PDWORD count);
我可能想要围绕","
交换两个参数。更确切地说,", "
。
所以也许我需要两个命令:
<s> - char-wise - the pivot is the last character of the selection;
<S> - word-wise - the pivot is the last word of the selection.
谢谢! (ps。最后的 Word ?:)
答案 0 :(得分:5)
这似乎在这里工作,让我知道它是如何做的:
function! Swap(...) "{{{
let start_v = col("'<")
let end_v = col("'>")
let mv = ''
let isMv = 0
while !isMv
let char = s:GetChar()
if char == '<Esc>'
return ''
endif
let mv .= char
let isMv = s:IsMovement(mv)
echon mv."\r"
endwhile
if isMv == 2
return ''
endif
exec "normal! ".end_v.'|'.mv
let lhs = '\%'.start_v.'c\(.\{-}\S\)'
if !a:0
let pivot = '\(\s*\%'.(end_v).'c.\s*\)'
else
let pivot = '\(\s*'.a:1.'*\%'.(end_v).'c'.a:1.'\+\s*\)'
endif
let rhs = '\(.*\%#.\)'
exec 's/'.lhs.pivot.rhs.'/\3\2\1/'
endfunction "Swap }}}
function! s:GetChar() "{{{
let char = getchar()
if type(char) == type(0) && char < 33
return '<Esc>'
elseif char
let char = nr2char(char)
endif
return char
endfunction "GetChar }}}
function! s:IsMovement(mv) "{{{
let ft = a:mv =~ '^\C\d*[fFtT].$'
let ft_partial = a:mv =~ '^\C\d*\%([fFtT].\?\)\?$'
let right = a:mv =~ '^\d*[l$|;,]\|g[m$]$'
let right_partial = a:mv =~ '^\d*\%([l$|;,]\|g[m$]\?\)\?$'
if !right_partial && !ft_partial
return 2
endif
return ft || right
endfunction "IsMovement2Right }}}
" Use last char as pivot. e.g.: the comma in the given example.
vmap <silent> <leader>s1 :<C-U>call Swap()<CR>
" Use \S\+ (WORD) as pivot. e.g.: &&
vmap <silent> <leader>ss :<C-U>call Swap('\S')<CR>
" Use \w\+ as pivot.
vmap <silent> <leader>sw :<C-U>call Swap('\w')<CR>
无需按Enter即可指定移动。 'pivot'总是包含任何周围的空格,它可以使用单个字符类定义,作为映射中Swap()的参数。
如果要突出显示,请检查https://gist.github.com/1921196
答案 1 :(得分:1)
让我提出以下映射作为假设的实现
<S>
命令。
vnoremap <silent> <leader>m xm':<c-u>set opfunc=PasteAfter<cr>g@
function! PasteAfter(type)
let [sl, sc] = getpos("'[")[1:2]
let [cl, cc] = getpos("''")[1:2]
let back = sl < cl || (sl == cl && sc < cc)
undojoin | exe 'norm!' ['`]p`[', '`[P`]'][back]
endfunction
此实现不仅适用于单个字符的字符选择 line,但也用于行选择和块选择。
答案 2 :(得分:1)
我使用受到vim提示启发的following plugin。
首先我删除(一次性 - diw
也算作一个,而xx
没有)我要交换的第一部分。然后我在视觉上选择第二部分。最后我点击g"
。
Etvoilà!这两个文本已被交换。
当然,这并不像选择枢轴那么简单。这是正常的,因为它不仅仅是关于一个支点:我们必须指定交换开始和结束的两个文本的时间,以及转轴为零长度(编辑?)的情况。
答案 3 :(得分:1)
我想出了一个有点不同工作流程的解决方案。您以可视模式选择文本,然后指示要转动的字符/文本。在大多数情况下,我想要考虑空白,因此,默认情况下,数据透视文本周围的空白作为实际数据透视的一部分包含在内。我将它映射到像\ a这样的序列,以绕过逗号(使用',',';','。'和空格的显式映射)和\ aa提示透视文本,这样你就可以使用\ aaand围绕“和”一词转动。
这是vimscript:
vmap <silent> <leader>aa :call SwapAround()<CR>
vmap <silent> <leader>a, :call SwapAround(',')<CR>
vmap <silent> <leader>a. :call SwapAround('\.')<CR>
vmap <silent> <leader>a; :call SwapAround(';')<CR>
vmap <silent> <leader>a<Space> :call SwapAround("[ \t\n]*")<CR>
function! SwapAround(...) range
if 1 == a:0
let exp = a:1
else
call inputsave()
let exp = input('pivot:')
call inputrestore()
endif
if exp !~ '[ \t\n]'
let exp = '[ \t\n]*'.exp.'[ \t\n]*'
endif
call s:SwapAroundBase(exp, getpos("'<"), getpos("'>"))
endfunction
function! s:SwapAroundBase(sepExp, start, end) range
let save_a = @a
try
let originalText = s:getText(a:start, a:end)
let sepStart = match(originalText, a:sepExp)
let sepEnd = matchend(originalText, a:sepExp)
let firstOne = strpart(originalText, 0, sepStart)
let sep = strpart(originalText, sepStart, sepEnd - sepStart)
let secondOne = strpart(originalText, sepEnd)
let @a = secondOne.sep.firstOne
let posStatus = setpos(".", a:start)
normal! v
let posStatus = setpos(".", a:end)
normal "ap
finally
let @a = save_a
endtry
endfunction
function! s:getText(start, end)
let lines = getline(a:start[1], a:end[1])
let lines[-1] = lines[-1][: a:end[2] - 1]
let lines[0] = lines[0][a:start[2] - 1:]
return join(lines, "\n")
endfunction
这适用于单行交换,但我认为需要清理多行情况。