-
-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
223 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
core/commands/custom.py | 2 +- | ||
core/commands/diff.py | 39 +++++++++++++++++++++++++++++++++++---- | ||
2 files changed, 36 insertions(+), 5 deletions(-) | ||
|
||
diff --git a/core/commands/custom.py b/core/commands/custom.py | ||
index 1facb191..8b079d4d 100644 | ||
--- a/core/commands/custom.py | ||
+++ b/core/commands/custom.py | ||
@@ -16,7 +16,7 @@ class CustomCommandThread(threading.Thread): | ||
self.daemon = True | ||
|
||
def run(self): | ||
- return self.cmd_func(*self.cmd_args, | ||
+ return self.cmd_func( *self.cmd_args, | ||
custom_environ=self.custom_environ) | ||
|
||
|
||
diff --git a/core/commands/diff.py b/core/commands/diff.py | ||
index 185eb6ee..f3581797 100644 | ||
--- a/core/commands/diff.py | ||
+++ b/core/commands/diff.py | ||
@@ -52,8 +52,7 @@ class GsDiffCommand(WindowCommand, GitCommand): | ||
diff_view = diff_views[view_key] | ||
else: | ||
diff_view = util.view.get_scratch_view(self, "diff", read_only=True) | ||
- if not title: | ||
- title = (DIFF_CACHED_TITLE if in_cached_mode else DIFF_TITLE).format(os.path.basename(repo_path)) | ||
+ | ||
settings = diff_view.settings() | ||
settings.set("git_savvy.repo_path", repo_path) | ||
settings.set("git_savvy.file_path", file_path) | ||
@@ -64,9 +63,41 @@ class GsDiffCommand(WindowCommand, GitCommand): | ||
settings.set("git_savvy.diff_view.target_commit", target_commit) | ||
settings.set("git_savvy.diff_view.show_diffstat", self.savvy_settings.get("show_diffstat", True)) | ||
settings.set("git_savvy.diff_view.disable_stage", disable_stage) | ||
- settings.set("result_file_regex", r"^\+\+\+ b/(.+)$") | ||
- settings.set("result_line_regex", r"^@@ -(\d+),") | ||
+ | ||
+ # Clickable lines: | ||
+ # (A) common/commands/view_manipulation.py | 1 + | ||
+ # (B) --- a/common/commands/view_manipulation.py | ||
+ # (C) +++ b/common/commands/view_manipulation.py | ||
+ # (D) diff --git a/common/commands/view_manipulation.py b/common/commands/view_manipulation.py | ||
+ # | ||
+ # Now the actual problem is that Sublime only accepts a subset of modern reg expressions, | ||
+ # B, C, and D are relatively straight forward because they match a whole line, and | ||
+ # basically all other lines in a diff start with one of `[+- ]`. | ||
+ FILE_RE = ( | ||
+ r"^(?:\s(?=.*\s+\|\s+\d+\s)|--- a\/|\+{3} b\/|diff .+b\/)" | ||
+ # ^^^^^^^^^^^^^^^^^^^^^ (A) | ||
+ # ^ one space, and then somewhere later on the line the pattern ` | 23 ` | ||
+ # ^^^^^^^ (B) | ||
+ # ^^^^^^^^ (C) | ||
+ # ^^^^^^^^^^^ (D) | ||
+ r"(?<filename>\S[^|]*?)" | ||
+ # ^ ! lazy to not match the trailing spaces, see below | ||
+ | ||
+ r"(?:\s+\||$)" | ||
+ # ^ (B), (C), (D) | ||
+ # ^^^^^ (A) We must match the spaces here bc Sublime will not rstrip() the | ||
+ # filename for us. | ||
+ ) | ||
+ | ||
+ settings.set("result_file_regex", FILE_RE) | ||
+ # Clickable line: | ||
+ # @@ -69,6 +69,7 @@ class GsHandleVintageousCommand(TextCommand): | ||
+ # ^^ we want the second (current) line offset of the diff | ||
+ settings.set("result_line_regex", r"^@@ [^+]*\+(\d+),") | ||
settings.set("result_base_dir", repo_path) | ||
+ | ||
+ if not title: | ||
+ title = (DIFF_CACHED_TITLE if in_cached_mode else DIFF_TITLE).format(os.path.basename(repo_path)) | ||
diff_view.set_name(title) | ||
diff_view.set_syntax_file("Packages/GitSavvy/syntax/diff.sublime-syntax") | ||
diff_views[view_key] = diff_view |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import os | ||
import re | ||
|
||
import sublime | ||
|
||
from unittesting import DeferrableTestCase | ||
from GitSavvy.tests.mockito import expect, unstub, when, spy2 | ||
|
||
from GitSavvy.core.commands.diff import GsDiffCommand, GsDiffRefreshCommand | ||
|
||
|
||
THIS_DIRNAME = os.path.dirname(os.path.realpath(__file__)) | ||
|
||
|
||
def fixture(name): | ||
with open(os.path.join(THIS_DIRNAME, 'fixtures', name)) as f: | ||
return f.read() | ||
|
||
|
||
class TestDiffView(DeferrableTestCase): | ||
def setUp(self): | ||
original_window_id = sublime.active_window().id() | ||
sublime.run_command("new_window") | ||
|
||
yield lambda: sublime.active_window().id() != original_window_id | ||
|
||
self.window = sublime.active_window() | ||
self.view = sublime.active_window().new_file() | ||
self.window.focus_view(self.view) | ||
yield lambda: sublime.active_window().active_view().id() == self.view.id() | ||
# make sure we have a window to work with | ||
s = sublime.load_settings("Preferences.sublime-settings") | ||
s.set("close_windows_when_empty", False) | ||
|
||
def tearDown(self): | ||
if self.view: | ||
self.view.set_scratch(True) | ||
self.view.window().focus_view(self.view) | ||
self.view.close() | ||
self.window.run_command('close_window') | ||
unstub() | ||
|
||
def test_extract_clickable_lines(self): | ||
REPO_PATH = '/not/there' | ||
FILE_PATH = '/not/there/README.md' | ||
DIFF = fixture('diff_1.txt') | ||
|
||
when(GsDiffRefreshCommand).git('diff', ...).thenReturn(DIFF) | ||
cmd = GsDiffCommand(self.window) | ||
when(cmd).get_repo_path().thenReturn(REPO_PATH) | ||
cmd.run_async() | ||
|
||
diff_view = self.window.active_view() | ||
actual = diff_view.find_all_results() | ||
# `find_all_results` only returns full filename-with-line matches. | ||
# These match clicking on `@@ -52,8 +XX,7` lines | ||
expected = [ | ||
('/not/there/core/commands/custom.py', 16, 0), | ||
('/not/there/core/commands/diff.py', 52, 0), | ||
('/not/there/core/commands/diff.py', 63, 0) | ||
] | ||
|
||
self.assertEqual(actual, expected) | ||
|
||
def test_result_file_regex(self): | ||
REPO_PATH = '/not/there' | ||
FILE_PATH = '/not/there/README.md' | ||
DIFF = fixture('diff_1.txt') | ||
|
||
when(GsDiffRefreshCommand).git('diff', ...).thenReturn(DIFF) | ||
cmd = GsDiffCommand(self.window) | ||
when(cmd).get_repo_path().thenReturn(REPO_PATH) | ||
cmd.run_async() | ||
|
||
diff_view = self.window.active_view() | ||
self.assertEqual(diff_view.substr(sublime.Region(0, diff_view.size())), DIFF) | ||
|
||
regex = diff_view.settings().get('result_file_regex') | ||
|
||
matches = re.findall(regex, DIFF, re.M) | ||
expected = [ | ||
'core/commands/custom.py', | ||
'core/commands/diff.py', | ||
'core/commands/custom.py', | ||
'core/commands/custom.py', | ||
'core/commands/custom.py', | ||
'core/commands/diff.py', | ||
'core/commands/diff.py', | ||
'core/commands/diff.py' | ||
] | ||
self.assertEqual(matches, expected) | ||
|
||
matches = re.finditer(regex, DIFF, re.M) | ||
actual = [ | ||
(m.group(0), diff_view.rowcol(m.span(1)[0])[0] + 1) | ||
# Oh boy, a oneliner. ^^^^^^^^^^^^ start offset | ||
# ^^^^^^ convert to (row, col) | ||
# ^^^^^^^ only take row | ||
# but add 1 for convenience | ||
for m in matches | ||
] | ||
expected = [ | ||
(' core/commands/custom.py |', 1), | ||
(' core/commands/diff.py |', 2), | ||
('diff --git a/core/commands/custom.py b/core/commands/custom.py', 5), | ||
('--- a/core/commands/custom.py', 7), | ||
('+++ b/core/commands/custom.py', 8), | ||
('diff --git a/core/commands/diff.py b/core/commands/diff.py', 18), | ||
('--- a/core/commands/diff.py', 20), | ||
('+++ b/core/commands/diff.py', 21) | ||
] | ||
self.assertEqual(actual, expected) |