我在Sublime Text中有这样的文本(通常是一个非常大的文本文件):
#tag3
Some notes here about this and that.
#tag1 #tag2
Hello world, here is some text
#tag4
Blah
Blah
#tag2
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
#foo
bar
如何使用Sublime Text分组或仅显示与#tag2
相关的段落?是否可以使用“多个游标”或其他技术?
这是所需的输出:#tag2
段落首先移动,然后其余部分移动到最后:
#tag1 #tag2
Hello world, here is some text
#tag2
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
#tag3
Something else
#tag4
Blah
Blah
#foo
bar
我到目前为止尝试过:CTRL + F和#tag2
,然后浏览不同的匹配项以查找与此标记相关的所有内容。
注意:我不是在寻找命令行方法,而是在Sulbime Text中使用方便的方法来快速浏览带有由标签组织的注释/段落的巨大文本文档。
做这样的事情没有简单的内置方式。正如您所提到的,您可以搜索有问题的标签并在结果之间跳过。您还可以尝试制作一个只与您感兴趣的标签(及其内容)匹配的正则表达式,然后执行Find All
选择它们并将它们剪切并粘贴到顶部。但是,根据文件的内容,这可能是也可能不可行。
一种可能的方法是为您的笔记创建某种自定义语法,以便您可以利用内置符号列表功能。
%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
scope: text.plain.notes
file_extensions:
- notes
contexts:
main:
- match: '^\s*(#\w+)'
captures:
1: entity.name.type
push:
- match: '#\w+'
scope: entity.name.type
- match: $
pop: true
如果将这个简单的示例语法(仅限ST3)应用于您的注释文件,则所有标记都将突出显示语法并显示在符号列表中,允许您使用Goto > Goto Symbol
。
在这种情况下,标记将按照它们在文件中出现的顺序出现在符号列表中,但您可以输入一些过滤文本来过滤列表并轻松地在它们之间跳过。您还可以通过Goto > Goto Anything
直接在标签上打开文件。
此外,将光标放在标签上,Goto > Goto Defintion...
将显示一个快速面板,为当前文件和其他文件提供该标签的其他位置(如果有),允许您跳转到适当的位置。
对于你在问题中提到的那些会改变文件内容的东西,你需要一个插件。
这样一个插件的一个例子如下,它假设标签总是单独出现在行上,并且跟随它们的所有内容直到下一行标记是正文(例如在示例文本中列出)。
import sublime
import sublime_plugin
import re
# Regular expressions that match a single tag as well as a line that contains
# one or more tags. Note that the code below presumes that lines with tags
# contain ONLY tags and nothing else.
_tag_regex = r"#\w+"
_tag_line_regex = r"^[ \t]*(?:(?:#\w+)\s*){1,}"
# Command palette input handlers are only supported in Sublime builds 3154 and
# later, so guard against using them in a previous version.
st_ver = int(sublime.version())
HandlerBase = sublime_plugin.ListInputHandler if st_ver >= 3154 else object
class TagInputHandler(HandlerBase):
"""
Input handler for a command argument named "tag"; tries to provide a list
of tags that appear in the current file, if any. The selected value becomes
the value for the argument.
"""
def __init__(self, view):
self.view = view
def placeholder(self):
return "Tag to move"
def list_items(self):
tags = set()
tag_lines = self.view.find_all(_tag_line_regex)
for region in tag_lines:
line = self.view.substr(region)
tags.update(re.findall(_tag_regex, line))
if not tags:
sublime.status_message("File contains no tags")
return list(sorted(tags))
class TagToTopCommand(sublime_plugin.TextCommand):
def run(self, edit, tag=None):
if tag is None:
return self.prompt_tag()
# Find all lines that contain tags; they are considered the start of
# sections.
lines = self.view.find_all(_tag_line_regex)
matched = []
eof = sublime.Region(self.view.size())
# Keep any tag lines that contain the tag we were given. The found
# regions are modified so that they start at the start of the tag line
# and end at the start of the following tag section (or end of file)
# so that the region entirely encompasses the data for these tags.
for idx, line in enumerate(lines):
end = lines[idx + 1] if idx + 1 < len(lines) else eof
if tag in re.findall(_tag_regex, self.view.substr(line)):
matched.append(sublime.Region(line.a, end.a))
# Extract all of the sections that we matched above.
text = []
if matched:
# Go bottom up so we don't disturb our offsets.
for region in reversed(matched):
text.append(self.view.substr(region))
# Special handling if this region ends at the buffer end
if region.b == eof.b:
# Move the start up the region upwards to skip over all
# blank lines, so that when we trim this section out there
# aren't extra blank lines left at the bottom of the view.
prev_line = self.view.line(region.a - 1)
while prev_line.a == prev_line.b:
prev_line = self.view.line(prev_line.a - 1)
region.a = prev_line.b + 1
# The region doesn't capture the last line of the buffer,
# so ensure that this item is separated from the other
# items when it moves.
text[-1] += "\n"
self.view.replace(edit, region, '')
# Add all of the text back at the beginning, but reverse the order
# of the entries so they preserve the order they appeared in the
# file.
self.view.insert(edit, 0, ''.join(reversed(text)))
else:
sublime.status_message("'%s' not found in the current file" % tag)
def input(self, args):
# This is invoked by Sublime if the command is executed from the
# command palette; we make the palette prompt us for the tag if one is
# not given.
if args.get("tag", None) is None:
return TagInputHandler(self.view)
def prompt_tag(self):
# This is invoked in situations where the command is executed without a
# "tag" parameter and it's not executing in the command palette; fall
# back to prompting via a quick panel
items = TagInputHandler(self.view).list_items()
def pick(idx):
if idx != -1:
self.view.window().run_command("tag_to_top", {"tag": items[idx]})
self.view.window().show_quick_panel(
items,
lambda idx: pick(idx))
这实现了一个tag_to_top
命令,给定一个标记,它将找到提及该标记的所有部分,并以当前文件顺序将它们拉到文件的顶部。
tag
参数是可选的;如果没有给出当前文件中所有唯一标签的列表,将显示在列表中供您选择。您也可以直接将标签传递给它,例如,如果您有经常查看的标签或其他标签。
{
"keys": ["super+t"], "command": "tag_to_top",
//"args": { "tag": "#something" }
},
如果需要,您还可以将以下内容添加到TagActions.sublime-commands
包中名为User
的文件中,将其添加到命令面板中:
[
{ "caption": "Bring Tag to Top", "command": "tag_to_top" }
]
如上所述,您可以提供标记作为参数,可能会多次使用不同的标记添加命令以轻松交换文件。
此外,如果您正在使用支持它的Sublime版本,则从命令选项板运行时,这将直接提示您输入标记,而不是打开快速面板。
请注意,上面的内容适用于Sublime Text 3,但它也适用于Sublime Text 2(因为你标记了它),尽管这只是我自己的温和测试。
该示例演示了如何查找表示标记的文件部分,以便可以从文件中删除它们并将其添加回顶部。对于非破坏性选项,这可以适用于确定与标记不匹配的区域,而是将它们折叠起来,这样只会让您感兴趣的标记立即在缓冲区中可见。