我有一个仅包含一行的 html 源文件,如下所示:
<html><head>test</head><body>wow</body></html>
,我想将其格式化如下:
<html>
<head>
test
</head>
<body>
wow
</body>
</html>
,我使用了命令:Edit-> Line-> Reindent 但它不起作用。
我有一个仅包含一行的 html 源文件,如下所示:
<html><head>test</head><body>wow</body></html>
,我想将其格式化如下:
<html>
<head>
test
</head>
<body>
wow
</body>
</html>
,我使用了命令:Edit-> Line-> Reindent 但它不起作用。
在 Sublime Text 中试试这个:
>
”Find
> Quick Add Next
(Mac上的Command+或PC上的+ )DCtrlD您现在将在多个选择中突出显示所有出现,将插入符号移动到标签的末尾并按回车键插入您需要的所有新行。
祝你好运
我的印象是 Sublime 也提供了这种能力。当我发现它不是时,我有了使用正则表达式的想法。尽管 regex 通常被认为不适合解析 XML/HTML,但我发现这种方法在这种情况下是可以接受的。据说 Sublime 也可以通过插件高度定制,所以我认为这将是一种方式。
老实说,我本可以想到tidy
或至少怀疑肯定有插件可以解决您的问题。相反,我最终编写了我的第一个 sublime 插件。我只用你的输入和预期的输出对它进行了测试,它满足了,但它肯定离可靠地工作还很远。但是,我在这里发布它以分享我学到的东西,它仍然是问题的答案。
打开一个新Ctrl+n的缓冲区(示例插件(作为 Python 模块),它为实现子类提供了一个很好的模板。TextCommand 提供对活动缓冲区/当前打开文件的访问。像它的亲戚和一样,它需要覆盖运行方法。sublime_plugin.TextCommand
WindowCommand
ApplicationCommand
官方 API 参考建议通过阅读随 Sublime 构建分发并位于Packages/Default
相对于 Sublime 配置路径的示例源来学习。更多示例可在网站上找到。互联网上还有更多内容。
要为您的问题找到解决方案,我们主要需要访问View
表示活动文本缓冲区的对象。幸运的是,TextCommand
我们即将实现的子类有一个,我们可以方便地向它询问当前选择的区域及其选择内容,处理符合我们需要的选择文本,然后将选择的文本替换为我们的偏好。
总结一下字符串操作:有四个正则表达式,每个都匹配元素类<start-tag>
、<empty-tag/>
和。假设我们所有的标记文本都被这些覆盖,我们将选择中的每一行都放入匹配的子字符串中。然后每行重新对齐这些。完成此操作后,我们通过记住缩进其前身包含开始标记的每一行来应用简单的缩进。包含结束标记的行立即取消缩进。 </close-tag>
text-node
使用 Python 正则表达式的组寻址功能,我们可以确定每一行的缩进并相应地对齐下一行。事不宜迟,这将导致内部一致的缩进标记,但不考虑选择之外的行。通过将选择扩展到封闭元素,或者至少符合相邻行的缩进级别,可以轻松改善结果。它总是可以使用默认命令。
另一件需要注意的事情是将键绑定到插件命令和贡献菜单条目。可能以某种方式可能,并且默认值.sublime-menu
和.sublime-commands
文件Packages/Default
至少给出了一个想法。无论如何,这里有一些代码。它必须保存在Packages/User/whatever.py
Sublime Python 控制台 ( ) 中,并且可以像这样调用:.Ctrl+`
view.run_command('guess_indentation')
import sublime
import sublime_plugin
import re
class GuessIndentationCommand(sublime_plugin.TextCommand):
def run(self, edit):
view = self.view
#view.begin_edit()
# patterns
start_tag = '<\w+(?:\s+[^>\/]+)*\s*>' # tag_start
node_patterns = [start_tag,
start_tag[:-1]+'\/\s*>', # tag_empty
'<\/\s?\w+\s?>', # tag_close
'[^>\s][^<>]*[^<\s]'] # text_node
patterns = '(?:{0})'.format('|'.join(node_patterns))
indentors = re.compile('[ \t]*({0})'.format('|'.join(node_patterns[:1])))
unindentors=re.compile('[ \t]*({0})'.format(node_patterns[2]))
# process selected text
for region in view.sel():
# if selection contains text:
if not region.empty():
selection = view.substr(region)
expanded = []
# divide selected lines into XML elements, if it contains more than one
for line in selection.split('\n'):
elements = re.findall(patterns, line)
if len(elements)>0:
expanded += elements
else:
expanded.append(line)
# indent output
indent=0
indented = []
for line in expanded:
match = unindentors.match(line)
if match:
indent = max(0, indent-1)
# append line to output, unindented if closing tag
indented.append('\t'*indent+line)
if match:
continue
# test for possible indentation candidate
# indentation applies to the NEXT line
match = indentors.match(line)
if match:
indent+=1
# replace selection with aligned output
view.replace(edit, region, '\n'.join(indented))
如果它是为了简单的事情,我能够记录一个缩进标签的宏(工具->记录宏),然后保存它并重用这个宏。不确定这是否有帮助。