Vim:缩进一个空格(而非 shiftwidth 空格)

60

默认的VIM缩进命令会缩进shiftwidth个空格

例如:

>>   Indent line by shiftwidth spaces
<<   De-indent line by shiftwidth spaces

有没有一种方法可以缩进一个或N个(其中n!= shiftwidth)空格?

一种方法是使用 Ctrl+V 在该块中垂直选择列,然后使用 I 垂直插入,然后输入一个 space 并按 <Esc>。 但是否有更好的方法?


2
你为什么想避免更改 sw?那是它存在的目的。 - Daenyth
在可视行选择中,{count}> 将缩进 {count}*'shiftwidth',而在普通模式下,{count} 用于计算已缩进的行数。也许这正是你想要的。请注意,对于可视块选择,情况相同,但空格插入在块的第一列之前,而不是行的开头。 - Benoit
8个回答

50

我不确定是否有更好的方法。但是,有一些方法可以做到这一点(至少是我能想到的)...

使用可视块解决方案

像你说的那样:按下Ctl-V键选择你想要的行,按I键插入,然后输入空格数。

搜索

类似于上面的方法,但更加灵活 - 你可以与“选择段落”vip命令或任何范围一起使用:按vvip或其他命令选择范围,然后输入::s/^/{n spaces}其中{n spaces}是你想要插入的空格数。

虽然有点冗长,但对于任何范围都很有效。如果你想对整个文件进行操作,你可以做到Ctl-A(依赖于操作系统)并缩进整个文件(或者直接在命令模式下跳过整个可视模式的步骤...比如::1,$s/^/{n spaces}

注意,由于你没有在搜索结尾处添加任何开关,因此不必包括s///中的第三个斜杠。

全局

也许你只想缩进与某个模式匹配的行。比如...所有包含foo的行。没问题:键入:g/foo/s/^/{n spaces}

如果有多行类似模式的部分,全局命令尤其方便。你可以进入正常模式并选择你想要的行,然后相应地缩进::g/foo/norm Vjj:s/^/{n spaces}Ctl-V{Enter}。虽然需要在结尾处添加额外的Ctl-V{Enter},但在某些情况下非常有用。

使用tabstop和shiftwidth

是的,如果你经常这样做 - 我会使用:set ts=2:set et:set sw=2,并使用>><<...

创建函数

好吧,如果还是不够简洁,并且由于某种原因你需要频繁执行此操作,而且无法容忍改动swetts设置。没问题,只需编写一个快速函数并给它一个localleader映射:

function! AddSpace(num) range
  let s:counter = 0
  let s:spaces = ''
  while s:counter < a:num
    let s:spaces .= ' '
    let s:counter = s:counter + 1
  endwhile
    execute a:firstline .','. a:lastline .'s/^/'. s:spaces
endfunction

:map <LocalLeader>i :call AddSpace(3)Ctl-V{enter}
也许掌握多种方法比只了解一种更好?毕竟,有时候最佳解决方案取决于问题本身 :)

使用搜索方法时,似乎会在空行开头插入空格。有没有一种干净而聪明的方法来避免这种情况?此外,我发现需要可视化选择一个块,然后输入 :,接着输入 '<,'>s/^/ / 来添加一个空格。谢谢! - ryanjdillon
+1 对于可视化块解决方案来说非常完美,它非常适合快速修改。 - verboze
可视化块解决方案对我不起作用,它只插入到单行而不是所有行。 - Pavel Šimerda
2
对于那些想要了解ettssw的人:它们分别代表着expandtabtabstopshiftwidth - winklerrr

32

使用Visual Block模式在vi中将一块代码缩进三个空格:

  1. 选择你想要缩进的代码块。在normal模式下使用Ctrl+V并用箭头向下选择文本。当它被选择后,输入“:”来给所选文本块发送命令。

  2. 以下内容将出现在命令行中::'<,'>

  3. 要将缩进设置为3个空格,请键入le 3并按回车。这是将出现的内容::'<,'>le 3

  4. 所选文本立即缩进3个空格。

使用Visual Line模式在vi中将一块代码缩进三个空格:

  1. 在VI中打开您的文件。
  2. 将光标放在一些代码上。
  3. 进入normal模式,按以下键:

    Vjjjj:le 3
    

你所做的操作解释:

V 表示开始选择文本。

jjjj 向下箭头移动 4 行,高亮 4 行文本。

: 告诉 vi 你将输入一个指令来处理被选中的文本。

le 3 表示将高亮的文本向右缩进 3 行。


这很棒,但是...当有空行时,它会插入空格。有什么方法可以避免这种情况吗? - ryanjdillon
1
这是更好的答案。被选中的答案太复杂了,在那个答案中,选项1“您的可视块解决方案”在大多数系统上都不起作用。 - Nike
9
我不同意,因为使用 :le 3 缩进是从左边距(列1/0)开始的解决方案,但我认为原帖想要从文本块的位置进一步缩进。例如,为了更好地垂直对齐代码/文本,与更好的位置相比,自动缩进的文本只有几个空格。 - Paul Lemmens
1
我同意这是最好的解决方案,但它可能应该在前面加上(0)导航到行最终应该落在哪一列,读取并记住列号(在我的配置中显示在右下角),将其用作“le”命令的参数,而不是3。 - Pavel Šimerda

19

要更改插入缩进空格字符的数量,请使用 shiftwidth 选项:

:set shiftwidth = <number>

查看这里以获取更多详细信息。

您还可以将其添加到.vimrc文件中。


1
这节省了我大量的时间。赞! - fruqi
2
1up。一些建议的解决方案如果不设置shiftwidth就不能像它们声称的那样工作。 - yantaq

8

4
在你希望缩进的代码之间放置标记('a'和'b'):
<position cursor at top of block>
m a
<position cursor at bottom of block>
m b

进行替换命令,使得你的标记之间每个换行符都被替换为所需数量的空格(在此示例中为2个空格):

:'a,'bs/^/  /g

1
如果已经存在空格缩进并且您想要将其增加一个或多个列,则可以使用Ctrl-V选择一个或多个空格列块,然后在相同位置上复制和粘贴。

0

我喜欢使用空格来缩进一个可视选择,只需一个空格:

vnoremap <silent> <space> :s/^/ /<CR>:noh<CR>gv

我无法使用 Shift+Space 来取消缩进,所以我使用 z

vnoremap <silent> z :s/^\s\=//<CR>:noh<CR>gv

0

我需要在vim脚本中将给定数量的空格,amount,去除。这个方法可行:

    let sw_setting = &shiftwidth
    set shiftwidth=1
    exe "normal v" . amount . "<"
    let &shiftwidth = sw_setting

一个副作用是它会重置最后一次的可视模式选择。相反,您可能希望编辑exe...行,使其在正常模式下执行"<<"重复amount次。也就是说:如果amount为3,则不要使用normal v3<,而应该使用normal <<<<<<

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接