myobj.myfunc("Some string parameter that goes on and on and on and on and sometimes doesn't"
"split very"
"neatly over different lines so that"
"it is formatted attractively")
我希望将其重新格式化,以便重新设置为我设置的
textwidth
: myobj.myfunc("Some string parameter that goes on and on and "
"on and on and sometimes doesn't split very "
"neatly over different lines so that it is "
"formatted attractively")
有简单的方法吗?如果这是常规的文本段落,则gqip或类似的内容将很有用,但这将不能处理用于修饰字符串的引号。
注意:我在这里专门询问Python,但理想情况下,此答案与允许字符串连续的许多类型的编程语言有关。
#1 楼
哦,那是一个艰难的过程。我认为最好的方法可能是宏,但更可能是插件。这是我举个例子(我需要一个更好的爱好)。它似乎为我工作,但需要python缩进插件正确缩进。试试吧。function ReformatMultiLines()
let brx = '^\s*"'
let erx = '"\s*$'
let fullrx = brx . '\(.\+\)' . erx
let startLine = line(".")
let endLine = line(".")
while getline(startLine) =~ fullrx
let startLine -= 1
endwhile
if getline(endLine) =~ erx
let endLine += 1
endif
while getline(endLine) =~ fullrx
let endLine += 1
endwhile
if startLine != endLine
exec endLine . ' s/' . brx . '//'
exec startLine . ' s/' . erx . '//'
exec startLine . ',' . endLine . ' s/' . fullrx . '//'
exec startLine . ',' . endLine . ' join'
endif
exec startLine
let orig_tw = &tw
if &tw == 0
let &tw = &columns
if &tw > 79
let &tw = 79
endif
endif
let &tw -= 3 " Adjust for missing quotes and space characters
exec "normal A%-%\<Esc>gqq"
let &tw = orig_tw
let endLine = search("%-%$")
exec endLine . ' s/%-%$//'
if startLine == endLine
return
endif
exec endLine
exec 'normal I"'
exec startLine
exec 'normal A "'
if endLine - startLine == 1
return
endif
let startLine += 1
while startLine != endLine
exec startLine
exec 'normal I"'
exec 'normal A "'
let startLine += 1
endwhile
endfunction
然后您可以将其与
:call ReformatMultiLines()
一起使用和/或在映射中使用。#2 楼
如果这是经常发生的情况,那么最好是寻找插件或使用@Sukima的函数。但是,如果我是即时执行此操作,则可能会执行以下操作:在开始括号后和结束括号前添加换行符,以便字符串在单独的行上。
myobj.myfunc(
"Some string parameter that goes on and on and on and on and sometimes doesn't"
"split very"
"neatly over different lines so that"
"it is formatted attractively"
)
选择带有字符串的行并删除周围的引号:
:norm ^x$x
减小文本宽度(以解决引号引起的问题) -选择并格式化:
:set tw-=2
修复文本宽度:
gvgq
重新添加引号:
:set tw+=2
。而不是gv:norm I"<Esc>A"
,您想通过键入ctrl-v和后跟转义键来插入文字转义。由于我将jj映射为转义,因此通常只在此处键入jj。也可以选择使用J重新连接前两行/后两行。当我在python这样的字符串中有一个很长的字符串时,我通常更喜欢在下一行开始它,并且只将其缩进一个级别,而不是上一行。这为弦乐提供了更多的水平空间,让我感觉更自然。或者,您可以将字符串保存到上方的某个变量中。假设它是一个静态字符串,您甚至可以将其保存到全局变量中,以使其缩进级别低得多,并且可以容纳更少的行。请注意,要在同一行上重新加入结束括号,您可能希望将文本宽度减小/增加3,而不是2。
评论
谢谢。我只是试过了,但E487:set tw- = 2结果:参数必须为正:tw- = 2。语法不正确吗?
–安德鲁·费里尔(Andrew Ferrier)
15年3月23日在11:30
用:set tw?检查当前的textwidth值。我的猜测是您将textwidth设置为0。这些步骤假定textwidth开始时是每行所需的字符数。
–马特·博姆(Matt Boehm)
2015年3月23日14:05
在您的示例中,您可能想要s / 2/3 /并在右引号之前添加一个空格,您的长字符串在单词之间没有适当的间距。
–cdosborn
18-09-24在18:28
#3 楼
解析和格式化代码非常困难,尤其是对于诸如Python之类的动态语言。我建议您使用诸如yapf之类的外部格式化程序,而不是尝试在Vimscript中解析Python。使用我的答案,您可以在使用以下代码自动编写该代码:如果发现错误,则不必在两个地方进行更新:-)
还可以将
s:write_cmd()
设置为formatprg
并使用yapf
手动对其进行格式化。评论
你好有用的答案,但我很不满意,因为我认为它不能回答这个问题:这个问题非常具体地要求重新格式化多行字符串,而yapf似乎不这样做。不过,我同意它看起来像是一个有用的工具。
–安德鲁·费里尔(Andrew Ferrier)
17年1月7日在14:28
@AndrewFerrier足够公平;我发誓我前几天进行测试时看到它重新格式化了字符串,但现在也不能使它工作:-/猜猜我很困惑。
–马丁·图尔诺伊(Martin Tournoij)
17年1月8日在16:36
#4 楼
以下功能和对应的映射为我解决了此问题:function! BreakMultlineString(quote)
let c = 100
while c == 100
normal 100|
let c = virtcol('.')
if c == 100
execute "normal ," . a:quote
endif
endwhile
endfunction
function! JoinMultilineString()
let c = "'"
while c == "'" || c == '"'
normal gj^
let c = matchstr(getline('.'), '\%' . col('.') . 'c.')
normal k
if c == "'" || c == '"'
normal ,j
endif
endwhile
endfunction
" break lines
nnoremap <Leader>" 100\|Bi"<CR>"<Esc>
nnoremap <Leader><Leader>" :call BreakMultlineString('"')<CR>
nnoremap <Leader>' 100\|Bi'<CR>'<Esc>
nnoremap <Leader><Leader>' :call BreakMultlineString("'")<CR>
" join lines
nmap <Leader>j Jds'ds"x
nnoremap <Leader>J :call JoinMultilineString()<CR>
评论
这里类似的问题:vim.1045645.n5.nabble.com/…您是否还考虑过将代码重写为““”多行字符串“”“”?
@ 200_success,很好的提示,谢谢。我完全不了解Python的功能。似乎大部分都可以正常工作-尽管该函数的所有参数均已重排,但这并不理想。我认为我的问题对于我拥有的字符串类型仍然有效,当然对于其他语言也是如此。
请注意,多行字符串将添加空格字符,如果字符串中的空格很重要,则可能会出现问题。
非常相关的问题:vi.stackexchange.com/questions/2135/…...