强制 Vi/Vim 仅在重新制表时使用前导制表符!

发布于 2024-10-19 17:35:37 字数 57 浏览 4 评论 0原文

有没有办法强制vim使用制表符进行初始缩进,但是在运行重新制表符时!命令不使用制表符替换内部字间距?

Is there a way to force vim to use tabs to do the initial indent, but when running the retab! command NOT replace inner word spacing with tabs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

二手情话 2024-10-26 17:35:37

根据我的经验,执行此操作的最佳方法是使用自定义函数:

" Retab spaced file, but only indentation
command! RetabIndents call RetabIndents()

" Retab spaced file, but only indentation
func! RetabIndents()
    let saved_view = winsaveview()
    execute '%s@^\( \{'.&ts.'}\)\+@\=repeat("\t", len(submatch(0))/'.&ts.')@'
    call winrestview(saved_view)
endfunc

然后您可以使用:

:RetabIndents

将所有前导空格替换为制表符,但不影响其他字符之后的制表符。它假设“ts”设置正确。通过执行以下操作,您可以在很大程度上使未对齐的文件变得更好:

:set ts=8     " Or whatever makes the file looks like right
:set et       " Switch to 'space mode'
:retab        " This makes everything spaces
:set noet     " Switch back to 'tab mode'
:RetabIndents " Change indentation (not alignment) to tabs
:set ts=4     " Or whatever your coding convention says it should be

您最终会得到一个文件,其中所有前导空白都是制表符,这样人们就可以以他们想要的任何格式查看它,但是所有的尾随空白是空格,以便所有行尾注释、表格等与任何制表符宽度正确对齐。

编辑

“exe”行的说明:

execute '%s@^\( \{'.&ts.'}\)\+@\=repeat("\t", len(submatch(0))/'.&ts.')@'

" Execute the result of joining a few strings together:

%s               " Search and replace over the whole file
@....@....@      " Delimiters for search and replace
^                " Start of line
\(...\)          " Match group
 \{...}          " Match a space the number of times in the curly braces
&ts              " The current value of 'tabstop' option, so:
                 " 'string'.&ts.'string' becomes 'string4string' if tabstop is 4
                 " Thus the bracket bit becomes \( \{4}\)
\+               " Match one or more of the groups of 'tabstop' spaces (so if
                 " tabstop is 4, match 4, 8, 12, 16 etc spaces
@                " The middle delimiter
\=               " Replace with the result of an expression:
repeat(s,c)      " Make a string that is c copies of s, so repeat('xy',4) is 'xyxyxyxy'
"\t"             " String consisting of a single tab character
submatch(0)      " String that was matched by the first part (a number of multiples 
                 " of tabstop spaces)
len(submatch(0)) " The length of the match
/'.&ts.'         " This adds the string "/4" onto the expression (if tabstop is 4),
                 " resulting in len(submatch(0))/4 which gives the number of tabs that
                 " the line has been indented by
)                " The end of the repeat() function call

@                " End delimiter

In my experience the best way to do this is with a custom function:

" Retab spaced file, but only indentation
command! RetabIndents call RetabIndents()

" Retab spaced file, but only indentation
func! RetabIndents()
    let saved_view = winsaveview()
    execute '%s@^\( \{'.&ts.'}\)\+@\=repeat("\t", len(submatch(0))/'.&ts.')@'
    call winrestview(saved_view)
endfunc

You can then use:

:RetabIndents

to replace all leading spaces as tabs but not to affect tabs after other characters. It assumes that 'ts' is set correctly. You can go a long way to making files that are misaligned better by doing something like this:

:set ts=8     " Or whatever makes the file looks like right
:set et       " Switch to 'space mode'
:retab        " This makes everything spaces
:set noet     " Switch back to 'tab mode'
:RetabIndents " Change indentation (not alignment) to tabs
:set ts=4     " Or whatever your coding convention says it should be

You'll end up with a file where all the leading whitespace is tabs so people can look at it in whatever format they want, but where all the trailing whitespace is spaces so that all the end-of-line comments, tables etc line up properly with any tab width.

Edit

Explanation of the 'exe' line:

execute '%s@^\( \{'.&ts.'}\)\+@\=repeat("\t", len(submatch(0))/'.&ts.')@'

" Execute the result of joining a few strings together:

%s               " Search and replace over the whole file
@....@....@      " Delimiters for search and replace
^                " Start of line
\(...\)          " Match group
 \{...}          " Match a space the number of times in the curly braces
&ts              " The current value of 'tabstop' option, so:
                 " 'string'.&ts.'string' becomes 'string4string' if tabstop is 4
                 " Thus the bracket bit becomes \( \{4}\)
\+               " Match one or more of the groups of 'tabstop' spaces (so if
                 " tabstop is 4, match 4, 8, 12, 16 etc spaces
@                " The middle delimiter
\=               " Replace with the result of an expression:
repeat(s,c)      " Make a string that is c copies of s, so repeat('xy',4) is 'xyxyxyxy'
"\t"             " String consisting of a single tab character
submatch(0)      " String that was matched by the first part (a number of multiples 
                 " of tabstop spaces)
len(submatch(0)) " The length of the match
/'.&ts.'         " This adds the string "/4" onto the expression (if tabstop is 4),
                 " resulting in len(submatch(0))/4 which gives the number of tabs that
                 " the line has been indented by
)                " The end of the repeat() function call

@                " End delimiter
风和你 2024-10-26 17:35:37

根据我对另一个 (*) 问题的回答:

为了解决这个小问题,我建议进行搜索,而不是重新创建。

<前><代码>:%s/^\(^I*\)␣␣␣␣/\1^I/g

此搜索将在整个文件中查找以
任意数量的制表符,后跟 4 个空格,并将其替换为
无论它找到多少个标签加一。

比您需要使用 @:10@: 重新进行搜索,

下面的链接有更好的解释。

(*)
如何将空格转换为Vim 或 Linux 中的选项卡?

From my answer to this other (*) question:

To settle this little problem I recomend a search, instead of retab.

:%s/^\(^I*\)␣␣␣␣/\1^I/g

This search will look in the whole file for any lines starting with
whatever number of tabs, followed by 4 spaces, and substitute it for
whatever number of tabs it found plus one.

Than you need to redo the search with @: or 10@:

Its better explained in the link bellow.

(*)
How can I convert spaces to tabs in Vim or Linux?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文