答案如下https://stackoverflow.com/questions/20519040/search-in-all-files-in-a-project-in-sublime-text-3和使用 Sublime Text 2 搜索打开的标签页中的所有内容告诉如何搜索打开的文件按其内容,使用⌘++⇧和F。Where: <open files>
但当我尝试这个时,它只搜索在选项卡中打开的文件在当前窗口中。如果我打开了两个窗口,每个窗口有 10 个选项卡,并且在其中一个窗口中使用⌘++ ⇧,则搜索结果会告诉我搜索了 10 个文件,而不是 20 个。F
现在,如果我打开了十几个窗口,我不想循环浏览每个窗口来搜索我想要的文件。(是的,我应该清理杂乱的东西,但这不是我要问的问题。)
有没有办法找到打开的文件任何打开的窗口?
我还想找到该文件按名字(或标签标题,通常相同)而不是按内容。但如果我可以搜索所有打开的窗口,我会满足于按内容搜索。
更新:看起来应该起作用的东西
我发现像这样的包Emacs Pro 基础知识和扩展标签切换器,两者都描述了允许您按名称切换到其他视图/缓冲区/选项卡的功能。 这两个包都明确表示默认行为是这样做在所有群体中(我认为这意味着跨所有窗口)。但是当我尝试它们时,只有来自同一窗口的选项卡才会显示在列表中以供选择。
内置Goto
>Goto Anything
菜单项的行为方式相同(十年前未得到答复的技术支持论坛请求)。
这让我怀疑 Mac 版本是否存在某些特定问题,导致所有这些工具无法访问其他窗口中的选项卡。
答案1
你可以用一个小包来解决这个问题。这是我的尝试:winfinder
在 Sublime 3 包文件夹下创建一个名为“ ”的文件夹(在 Mac 上,这将是~/Library/Application Support/Sublime Text 3/Packages/winfinder
)。
main.py
接下来,在该文件夹中创建一个包含以下内容的文件:
import sublime
import sublime_plugin
class WinFindCommand(sublime_plugin.TextCommand):
def search(self, search_string):
l = []
for w in sublime.windows():
for sh in w.sheets():
fn = sh.view().file_name()
if fn is not None:
if search_string.lower() in fn:
l.append(fn + "\n")
if len(l) > 0:
v = sublime.active_window().new_file()
v.set_name("SearchResults")
v.run_command("insert",{"characters": str(len(l)) + " matches:\n\n"})
v.run_command("insert",{"characters": "\n".join(l)})
else:
sublime.message_dialog("No match found.")
def run(self, edit):
w = sublime.active_window()
w.show_input_panel("Search text", "", self.search, None, None)
现在我们需要一种方法来调用该功能。这可以通过在同一个文件夹中创建一个名为的文件来完成main.sublime-commands
。内容如下:
[
{ "caption": "WindowFind: find in window title", "command": "win_find" },
]
用法
如果您打开命令面板并输入“ WindowFind
”,您应该会看到该命令。按 [ENTER],包将提示您在所有窗口的所有选项卡中搜索要搜索的搜索字符串。如果没有匹配,则会显示一条消息。
如果匹配,则会打开一个名为“SearchResults”的新选项卡,其中包含搜索结果:
3 matches:
/Users/your_user/notes/daylog.txt
/Users/your_user/Documents/2018/paychecks.csv
/Users/your_user/source/python/daily_tweets/daily.py
(搜索字符串是“ay”)——只需在 Sublime 3 上测试一下,就可以了。谢谢你的想法,这很有帮助!:-)
答案2
使用@Arminius 的想法回答,我修改了“切换到视图”代码Emacs Pro Essentials 插件,这样它现在就可以与所有窗口中的视图一起使用。以下是生成的代码main.py
:
# coding=utf-8
# Sublime plugin to search open files by filename, across all windows.
# See problem statement at https://superuser.com/questions/1327172/how-to-find-the-tab-of-an-open-file-by-name-in-all-sublime-text-windows
# Code adapted from https://github.com/sublime-emacs/sublemacspro/blob/master/switch_to_view.py
# and https://superuser.com/a/1328545/75777
import sublime, sublime_plugin, os
#
# Switch buffer command. "C-x b" equiv in emacs. This limits the set of files in a chooser to the
# ones currently loaded. Do we sort the files by last access? like emacs
class SwitchToViewCommand(sublime_plugin.TextCommand):
def run(self, util, current_group_only=False, preview=False, completion_components=2, display_components=1):
self.preview = preview
self.completion_components = completion_components
self.display_components = display_components
window = self.window = sublime.active_window()
self.group = window.active_group()
# was: self.views = ViewState.sorted_views(window, window.active_group() if current_group_only else None)
self.views = [sh.view() for w in sublime.windows() for sh in w.sheets()]
## TODO: sort the above views?
# if window.num_groups() > 1 and not current_group_only:
# self.group_views = set(view.id() for view in sorted_views(window, window.active_group()))
# else:
# self.group_views = None
self.roots = get_project_roots()
self.original_view = window.active_view()
self.highlight_count = 0
# swap the top two views to enable switching back and forth like emacs
if len(self.views) >= 2:
index = 1
else:
index = 0
window.show_quick_panel(self.get_items(), self.on_select, 0, index, self.on_highlight)
def on_select(self, index):
if index >= 0:
# Does this work even on views that aren't in self.window?
v = self.views[index]
if v.window() is not self.window:
try:
v.window().bring_to_front()
v.window().focus_window()
# Strangely, I get the error 'Window' object has no attribute 'focus_window'
# even though the documentation says it should be there in this version of ST.
except AttributeError as e:
print(f"{type(e).__name__} at line {e.__traceback__.tb_lineno} of {__file__}: {e}")
v.window().focus_view(self.views[index])
else:
self.window.focus_view(self.original_view)
def on_highlight(self, index):
if not self.preview:
return
self.highlight_count += 1
if self.highlight_count > 1:
# if self.group_views is None or self.views[index].id() in self.group_views:
self.window.focus_view(self.views[index])
def get_items(self):
if self.display_components > 0:
return [[self.get_path(view), self.get_display_name(view)] for view in self.views]
return [[self.get_path(view)] for view in self.views]
def get_display_name(self, view):
mod_star = '*' if view.is_dirty() else ''
if view.is_scratch() or not view.file_name():
disp_name = view.name() if len(view.name()) > 0 else 'untitled'
else:
disp_name = get_relative_path(self.roots, view.file_name(), self.display_components)
return '%s%s' % (disp_name, mod_star)
def get_path(self, view):
if view.is_scratch():
return view.name() or ""
if not view.file_name():
return '<unsaved>'
return get_relative_path(self.roots, view.file_name(), self.completion_components)
# From https://github.com/sublime-emacs/sublemacspro/blob/master/lib/misc.py
# Returns the relative path for the specified file name. The roots are supplied by the
# get_project_roots function, which sorts them appropriately for this function.
#
def get_relative_path(roots, file_name, n_components=2):
if file_name is not None:
if roots is not None:
for root in roots:
if file_name.startswith(root):
file_name = file_name[len(root) + 1:]
break
# show (no more than the) last 2 components of the matching path name
return os.path.sep.join(file_name.split(os.path.sep)[-n_components:])
else:
return "<no file>"
# Get the current set of project roots, sorted from longest to shortest. They are suitable for
# passing to the get_relative_path function to produce the best relative path for a view file name.
#
def get_project_roots():
window = sublime.active_window()
if window.project_file_name() is None:
roots = None
else:
project_dir = os.path.dirname(window.project_file_name())
roots = sorted([os.path.normpath(os.path.join(project_dir, folder))
for folder in window.folders()],
key=lambda name: len(name), reverse=True)
return roots
# # From ViewState. But I'm not using these right now. Don't really want to build the data structure of ViewStates.
#
# # Returns a list of views from a given window sorted by most recently accessed/touched. If group
# # is specified, uses only views in that group.
# #
# # @classmethod
# def sorted_views(window, group=None):
# views = window.views_in_group(group) if group is not None else window.views()
# states = [find_or_create(view) for view in views]
# sorted_states = sorted(states, key=lambda state: state.touched, reverse=True)
# return [state.view for state in sorted_states]
#
#
# # Finds or creates the state for the given view. This doesn't imply a touch().
# #
# # @classmethod
# def find_or_create(cls, view):
# state = cls.view_state_dict.get(view.id(), None)
# if state is None:
# state = ViewState(view)
# return state