diff --git a/GitGutter.sublime-settings b/GitGutter.sublime-settings index 91d186d6..27401499 100644 --- a/GitGutter.sublime-settings +++ b/GitGutter.sublime-settings @@ -57,7 +57,7 @@ "ignore_whitespace": "none", // Add a special marker on untracked files - "show_markers_on_untracked_file": false, + "show_markers_on_untracked_file": true, // Add --patience switch to git diff command. See // http://bramcohen.livejournal.com/73318.html for diff --git a/git_gutter_handler.py b/git_gutter_handler.py index ffc7a7c7..176df41f 100644 --- a/git_gutter_handler.py +++ b/git_gutter_handler.py @@ -32,6 +32,7 @@ def __init__(self, view): self.git_tree = None self.git_dir = None self.git_path = None + self.git_tracked = False self._last_refresh_time_git_file = 0 @@ -82,6 +83,14 @@ def _get_view_encoding(self): origin_encoding = self.view.settings().get('origin_encoding') return origin_encoding or encoding + def in_repo(self): + """Return true, if the most recent `git show` returned any content. + + If `git show` returns empty content, any diff will result in + all lines added state and the view's file is most commonly untracked. + """ + return self.git_tracked + def on_disk(self): """Determine, if the view is saved to disk.""" file_name = self.view.file_name() @@ -125,6 +134,7 @@ def update_git_file(self): def write_file(contents): contents = contents.replace(b'\r\n', b'\n') contents = contents.replace(b'\r', b'\n') + self.git_tracked = bool(contents) with open(self.git_temp_file, 'wb') as f: f.write(contents) diff --git a/git_gutter_popup.py b/git_gutter_popup.py index e13b6fa0..199be865 100644 --- a/git_gutter_popup.py +++ b/git_gutter_popup.py @@ -22,12 +22,10 @@ def show_diff_popup(view, point, git_handler, highlight_diff=False, flags=0): - if not _MDPOPUPS_INSTALLED: - return - - line = view.rowcol(point)[0] + 1 - git_handler.diff_line_change(line).then( - partial(_show_diff_popup_impl, view, point, highlight_diff, flags)) + if _MDPOPUPS_INSTALLED and git_handler.in_repo(): + line = view.rowcol(point)[0] + 1 + git_handler.diff_line_change(line).then( + partial(_show_diff_popup_impl, view, point, highlight_diff, flags)) def _show_diff_popup_impl(view, point, highlight_diff, flags, diff_info): diff --git a/git_gutter_show_diff.py b/git_gutter_show_diff.py index bfa5e458..0b400153 100644 --- a/git_gutter_show_diff.py +++ b/git_gutter_show_diff.py @@ -21,45 +21,43 @@ def __init__(self, view, git_handler): self.view = view self.git_handler = git_handler self.diff_results = None + self.show_untracked = False def run(self): self.git_handler.diff().then(self._check_ignored_or_untracked) def _check_ignored_or_untracked(self, contents): - show_untracked = settings.get( - 'show_markers_on_untracked_file', False) - if show_untracked and self._are_all_lines_added(contents): - def bind_ignored_or_untracked(is_ignored): - if is_ignored: - self._bind_files('ignored') - else: - def bind_untracked(is_untracked): - if is_untracked: - self._bind_files('untracked') - else: - self._lazy_update_ui(contents) - self.git_handler.untracked().then(bind_untracked) - - self.git_handler.ignored().then(bind_ignored_or_untracked) - return - self._lazy_update_ui(contents) - - # heuristic to determine if the file is either untracked or ignored: all - # lines show up as "inserted" in the diff. Relying on the output of the - # normal diff command to trigger the actual untracked / ignored check (which - # is expensive because it's two separate git ls-files calls) allows us to - # save the extra git calls - def _are_all_lines_added(self, contents): - inserted, modified, deleted = contents - if len(modified) == 0 and len(deleted) == 0: - chars = self.view.size() - region = sublime.Region(0, chars) - return len(self.view.split_by_newlines(region)) == len(inserted) - else: - return False - - def _lazy_update_ui(self, contents): - if self.diff_results is None or self.diff_results != contents: + """Check diff result and invoke gutter and status message update. + + Arguments: + contentes - a tuble of ([inserted], [modified], [deleted]) lines + """ + if self.git_handler.in_repo() is False: + show_untracked = settings.get( + 'show_markers_on_untracked_file', False) + # need to check for ignored or untracked file + if show_untracked: + def bind_ignored_or_untracked(is_ignored): + if is_ignored: + self._bind_files('ignored') + else: + def bind_untracked(is_untracked): + if is_untracked: + self._bind_files('untracked') + else: + # file was staged but empty + self._bind_files('inserted') + self.git_handler.untracked().then(bind_untracked) + self.git_handler.ignored().then(bind_ignored_or_untracked) + + # show_untracked was set to false recently so clear gutter + elif self.show_untracked: + self._clear_all() + self._update_status(0, 0, 0, "", "") + self.show_untracked = show_untracked + + # update the if lines changed + elif self.diff_results is None or self.diff_results != contents: self.diff_results = contents self._update_ui(contents) @@ -179,12 +177,7 @@ def _bind_icons(self, event, lines): 'git_gutter_%s' % event, regions, scope, icon, flags) def _bind_files(self, event): - lines = [] - line_count = self._total_lines() - i = 0 - while i < line_count: - lines += [i + 1] - i = i + 1 + lines = [line + 1 for line in range(self._total_lines())] self._bind_icons(event, lines) def _total_lines(self):