From 807732d223088e002ef234c64c4962408a65ced8 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Sat, 27 Jun 2015 18:33:26 +0200 Subject: [PATCH 1/7] fix: jump by match instead of by search result Fixes #16 --- Default.sublime-keymap | 4 +-- find_results.py | 57 ++++++++++++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/Default.sublime-keymap b/Default.sublime-keymap index 2df2259..a481081 100644 --- a/Default.sublime-keymap +++ b/Default.sublime-keymap @@ -23,14 +23,14 @@ }, { "keys": ["j"], - "command": "find_next", + "command": "find_in_files_jump_match", "context": [ {"key": "selector", "operator": "equal", "operand": "text.find-in-files" } ] }, { "keys": ["k"], - "command": "find_prev", + "command": "find_in_files_jump_match", "args": { "forward": false }, "context": [ {"key": "selector", "operator": "equal", "operand": "text.find-in-files" } diff --git a/find_results.py b/find_results.py index 852e244..cfd0421 100644 --- a/find_results.py +++ b/find_results.py @@ -37,22 +37,53 @@ def get_file(self): return None -class FindInFilesJumpFileCommand(sublime_plugin.TextCommand): +class FindInFilesJumpCommand(sublime_plugin.TextCommand): def run(self, edit, forward=True): - v = self.view - files = v.find_by_selector("entity.name.filename.find-in-files") - caret = v.sel()[0] + caret = self.view.sel()[0] + matches = self.find_matches() if forward: - file_match = next((f for f in files if caret.begin() < f.begin()), None) + match = self.find_next_match(caret, matches) else: - files.reverse() - file_match = next((f for f in files if caret.begin() > f.begin()), None) - if file_match: - region = sublime.Region(file_match.begin(), file_match.begin()) - v.sel().clear() - v.sel().add(region) - top_offset = v.text_to_layout(region.begin())[1] - v.line_height() - v.set_viewport_position((0, top_offset), True) + match = self.find_prev_match(caret, matches) + if match: + self.goto_match(match) + + def find_next_match(self, caret, matches): + return next((m for m in matches if caret.begin() < m.begin()), None) + + def find_prev_match(self, caret, matches): + return next((m for m in reversed(matches) if caret.begin() > m.begin()), None) + + def goto_match(self, match): + self.view.sel().clear() + self.view.sel().add(match) + + +class FindInFilesJumpFileCommand(FindInFilesJumpCommand): + def find_matches(self): + return self.view.find_by_selector('entity.name.filename.find-in-files') + + def goto_match(self, match): + v = self.view + region = sublime.Region(match.begin(), match.begin()) + super(FindInFilesJumpFileCommand, self).goto_match(region) + top_offset = v.text_to_layout(region.begin())[1] - v.line_height() + v.set_viewport_position((0, top_offset), True) + + +class FindInFilesJumpMatchCommand(FindInFilesJumpCommand): + def find_matches(self): + return self.view.get_regions('match') + + def goto_match(self, match): + v = self.view + super(FindInFilesJumpMatchCommand, self).goto_match(match) + vx, vy = v.viewport_position() + vw, vh = v.viewport_extent() + x, y = v.text_to_layout(match.begin()) + h = v.line_height() + if y < vy or y + h > vy + vh: + v.show_at_center(match) class FindInFilesSetReadOnly(sublime_plugin.EventListener): From db07aae20f93a5dd45c0b343c28eae8c7499ee19 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Sat, 27 Jun 2015 19:15:35 +0200 Subject: [PATCH 2/7] feat: add a `wrap` option to cycle through the matches --- find_results.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/find_results.py b/find_results.py index cfd0421..0338202 100644 --- a/find_results.py +++ b/find_results.py @@ -38,21 +38,23 @@ def get_file(self): class FindInFilesJumpCommand(sublime_plugin.TextCommand): - def run(self, edit, forward=True): + def run(self, edit, forward=True, wrap=False): caret = self.view.sel()[0] matches = self.find_matches() if forward: - match = self.find_next_match(caret, matches) + match = self.find_next_match(caret, matches, wrap) else: - match = self.find_prev_match(caret, matches) + match = self.find_prev_match(caret, matches, wrap) if match: self.goto_match(match) - def find_next_match(self, caret, matches): - return next((m for m in matches if caret.begin() < m.begin()), None) + def find_next_match(self, caret, matches, wrap): + default = matches[0] if wrap else None + return next((m for m in matches if caret.begin() < m.begin()), default) - def find_prev_match(self, caret, matches): - return next((m for m in reversed(matches) if caret.begin() > m.begin()), None) + def find_prev_match(self, caret, matches, wrap): + default = matches[-1] if wrap else None + return next((m for m in reversed(matches) if caret.begin() > m.begin()), default) def goto_match(self, match): self.view.sel().clear() From 8a97582879e59f027061126a724f84a29b202012 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Sat, 11 Jul 2015 13:33:08 +0200 Subject: [PATCH 3/7] fix: prevent `IndexError`s if there is no matches --- find_results.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/find_results.py b/find_results.py index 0338202..28209b3 100644 --- a/find_results.py +++ b/find_results.py @@ -49,11 +49,11 @@ def run(self, edit, forward=True, wrap=False): self.goto_match(match) def find_next_match(self, caret, matches, wrap): - default = matches[0] if wrap else None + default = matches[0] if wrap and len(matches) else None return next((m for m in matches if caret.begin() < m.begin()), default) def find_prev_match(self, caret, matches, wrap): - default = matches[-1] if wrap else None + default = matches[-1] if wrap and len(matches) else None return next((m for m in reversed(matches) if caret.begin() > m.begin()), default) def goto_match(self, match): From 49f5bc214e73f27fa5eaa7559745946d5086bee0 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Sat, 11 Jul 2015 16:56:13 +0200 Subject: [PATCH 4/7] chore: rename the `wrap` option to `cycle` --- find_results.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/find_results.py b/find_results.py index 28209b3..9448714 100644 --- a/find_results.py +++ b/find_results.py @@ -38,22 +38,22 @@ def get_file(self): class FindInFilesJumpCommand(sublime_plugin.TextCommand): - def run(self, edit, forward=True, wrap=False): + def run(self, edit, forward=True, cycle=False): caret = self.view.sel()[0] matches = self.find_matches() if forward: - match = self.find_next_match(caret, matches, wrap) + match = self.find_next_match(caret, matches, cycle) else: - match = self.find_prev_match(caret, matches, wrap) + match = self.find_prev_match(caret, matches, cycle) if match: self.goto_match(match) - def find_next_match(self, caret, matches, wrap): - default = matches[0] if wrap and len(matches) else None + def find_next_match(self, caret, matches, cycle): + default = matches[0] if cycle and len(matches) else None return next((m for m in matches if caret.begin() < m.begin()), default) - def find_prev_match(self, caret, matches, wrap): - default = matches[-1] if wrap and len(matches) else None + def find_prev_match(self, caret, matches, cycle): + default = matches[-1] if cycle and len(matches) else None return next((m for m in reversed(matches) if caret.begin() > m.begin()), default) def goto_match(self, match): From 250cc2bb7f33adfaa4d7abc23c5b9ab4c6c79086 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Sat, 11 Jul 2015 17:00:25 +0200 Subject: [PATCH 5/7] feat: cycle through matches by default --- find_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/find_results.py b/find_results.py index 9448714..2b5bf1d 100644 --- a/find_results.py +++ b/find_results.py @@ -38,7 +38,7 @@ def get_file(self): class FindInFilesJumpCommand(sublime_plugin.TextCommand): - def run(self, edit, forward=True, cycle=False): + def run(self, edit, forward=True, cycle=True): caret = self.view.sel()[0] matches = self.find_matches() if forward: From d2f962f0bd5b78366fbd3d8cc5550f66dd245cc8 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Sat, 11 Jul 2015 01:03:50 +0200 Subject: [PATCH 6/7] =?UTF-8?q?fix:=20don=E2=80=99t=20navigate=20to=20matc?= =?UTF-8?q?hes=20from=20previous=20searches?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- find_results.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/find_results.py b/find_results.py index 2b5bf1d..d2a31a0 100644 --- a/find_results.py +++ b/find_results.py @@ -40,7 +40,7 @@ def get_file(self): class FindInFilesJumpCommand(sublime_plugin.TextCommand): def run(self, edit, forward=True, cycle=True): caret = self.view.sel()[0] - matches = self.find_matches() + matches = self.filter_matches(caret, self.find_matches()) if forward: match = self.find_next_match(caret, matches, cycle) else: @@ -52,6 +52,12 @@ def find_next_match(self, caret, matches, cycle): default = matches[0] if cycle and len(matches) else None return next((m for m in matches if caret.begin() < m.begin()), default) + def filter_matches(self, caret, matches): + footers = self.view.find_by_selector('footer.find-in-files') + lower_bound = next((f.end() for f in footers if f.end() < caret.begin()), 0) + upper_bound = next((f.end() for f in footers if f.end() > caret.begin()), self.view.size()) + return [m for m in matches if m.begin() > lower_bound and m.begin() < upper_bound] + def find_prev_match(self, caret, matches, cycle): default = matches[-1] if cycle and len(matches) else None return next((m for m in reversed(matches) if caret.begin() > m.begin()), default) From 005d34efa08b32ce05af60805380b2d3c2caf6c1 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Sun, 19 Jul 2015 20:58:02 +0200 Subject: [PATCH 7/7] fix: pick the footer just before the caret instead of the first one --- find_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/find_results.py b/find_results.py index d2a31a0..4f4fda9 100644 --- a/find_results.py +++ b/find_results.py @@ -54,7 +54,7 @@ def find_next_match(self, caret, matches, cycle): def filter_matches(self, caret, matches): footers = self.view.find_by_selector('footer.find-in-files') - lower_bound = next((f.end() for f in footers if f.end() < caret.begin()), 0) + lower_bound = next((f.end() for f in reversed(footers) if f.end() < caret.begin()), 0) upper_bound = next((f.end() for f in footers if f.end() > caret.begin()), self.view.size()) return [m for m in matches if m.begin() > lower_bound and m.begin() < upper_bound]