diff --git a/README.md b/README.md index a1d5b7df..de4c6a50 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,20 @@ -## VCS Gutter +## VCS Gutter Modern **Now supporting Sublime Text 3.** -VCS Gutter is a plugin for Sublime Text 2 and 3 that displays an icon in the gutter area indicating whether a line has been inserted, modified or deleted relative to the version of the file in the local source -code repository. VCS Gutter supports Git, Mercurial and Subversion. +VCS Gutter Modern is a plugin for Sublime Text 2 and 3 that displays an icon in the gutter area indicating whether a line has been inserted, modified or deleted relative to the version of the file in the local source +code repository. VCS Gutter supports: -VCS Gutter is a "friendly fork" that builds on the original work by -[jisaacks](https://github.com/jisaacks) on [GitGutter](https://github.com/jisaacks/GitGutter). +* Fossil +* Git +* Mercurial +* Subversion + +Any pull request for a different VCS is more than welcome! + +Note: this is a fork of the unmaintained version of VcsGutter from https://github.com/bradsokol/VcsGutter / It adds support for Fossil, and any contribution is welcome. + +VCS Gutter was originally a "friendly fork" that builds on the original work by [jisaacks](https://github.com/jisaacks) on [GitGutter](https://github.com/jisaacks/GitGutter). ### Screenshot: @@ -20,23 +28,23 @@ Or you can clone this repo into your *Sublime Text 2/Packages* *Mac OS X* ```shell cd ~/Library/Application\ Support/Sublime\ Text\ 2/Packages/ -git clone git://github.com/bradsokol/VcsGutter.git "VCS Gutter" +git clone https://github.com/bohwaz/VcsGutter.git "VCS Gutter" ``` *Ubuntu* ```shell cd ~/.config/sublime-text-2/Packages -git clone git://github.com/bradsokol/VcsGutter.git "VCS Gutter" +git clone https://github.com/bohwaz/VcsGutter.git "VCS Gutter" ``` *Windows* ```shell cd %USERPROFILE%\AppData\Roaming\Sublime Text 2\Packages -git clone git://github.com/bradsokol/VcsGutter.git "VCS Gutter" +git clone https://github.com/bohwaz/VcsGutter.git "VCS Gutter" ``` -VcsGutter assumes that the `git`, `hg`, `svn` and `diff` commands are availible on the command line. The installers for these tools may not add the directory containing the executables to the PATH environment variable. If not, you must add the appropriate directory to your PATH variable. +VcsGutter assumes that the `git`, `hg`, `svn`, `fossil` and `diff` commands are availible on the command line. The installers for these tools may not add the directory containing the executables to the PATH environment variable. If not, you must add the appropriate directory to your PATH variable. For example: ```dos @@ -63,14 +71,15 @@ By default, this is turned off. When the parameter ```shown_in_minimap``` is set By default, VcsGutter runs in the same thread which can block if it starts to perform slowly. Usually this isn't a problem but depending on the size of your file or repo it can be. If you set `non_blocking` to `true` then VcsGutter will run in a seperate thread and will not block. This does cause a slight delay between when you make a modification and when the icons update in the gutter. This is a ***Sublime Text 3 only feature***. Sublime Text 2 users can turn off live mode if performance is an issue. #### Executable Path -If your VCS executable (git, hg, or svn) or diff utility is not in your PATH, you may need to set the `vcs_paths` setting to the location of your executables: +If your VCS executable (git, hg, or svn, fossil) or diff utility is not in your PATH, you may need to set the `vcs_paths` setting to the location of your executables: ```js { "vcs_paths": { "diff": "diff", "git": "git", "hg": "/usr/local/bin/hg", - "svn": "svn" + "svn": "svn", + "fossil": "fossil" } } ``` diff --git a/gutter_handlers.py b/gutter_handlers.py index c75fa25f..4d14e359 100644 --- a/gutter_handlers.py +++ b/gutter_handlers.py @@ -84,6 +84,8 @@ def update_vcs_file(self): open(self.vcs_temp_file.name, 'w').close() args = self.get_diff_args() try: + # Necessary for Fossil (needs to be in checkout) + os.chdir(self.vcs_tree) contents = self.run_command(args) contents = contents.replace(b'\r\n', b'\n') contents = contents.replace(b'\r', b'\n') @@ -178,7 +180,7 @@ def get_vcs_helper(self): def get_diff_args(self): args = [ self.exc_path, - '--git-dir=' + self.vcs_dir, + '--git-dir=' + self.vcs_dir[0], '--work-tree=' + self.vcs_tree, 'show', 'HEAD:' + self.vcs_path, @@ -212,3 +214,15 @@ def get_diff_args(self): os.path.join(self.vcs_tree, self.vcs_path), ] return args + +class FossilGutterHandler(VcsGutterHandler): + def get_vcs_helper(self): + return vcs_helpers.FossilHelper() + + def get_diff_args(self): + args = [ + self.exc_path, + 'cat', + self.vcs_path, + ] + return args diff --git a/vcs_helpers.py b/vcs_helpers.py index 10aad9ee..f93e28cd 100644 --- a/vcs_helpers.py +++ b/vcs_helpers.py @@ -10,7 +10,13 @@ def vcs_dir(cls, directory): directly under the passed directory.""" if not directory: return False - return os.path.join(directory, cls.meta_data_directory()) + + directory_list = [] + + for meta_data_directory in cls.meta_data_directory(): + directory_list.append(os.path.join(directory, meta_data_directory)) + + return directory_list @classmethod def vcs_file_path(cls, view, vcs_path): @@ -28,16 +34,16 @@ def vcs_file_path(cls, view, vcs_path): @classmethod def vcs_root(cls, directory): """Returns the top-level directory of the repository.""" - if os.path.exists(os.path.join(directory, - cls.meta_data_directory())): - return directory + for meta_data_directory in cls.meta_data_directory(): + if (os.path.exists(os.path.join(directory, meta_data_directory))): + return directory + + parent = os.path.realpath(os.path.join(directory, os.path.pardir)) + if parent == directory: + # we have reached root dir + return False else: - parent = os.path.realpath(os.path.join(directory, os.path.pardir)) - if parent == directory: - # we have reached root dir - return False - else: - return cls.vcs_root(parent) + return cls.vcs_root(parent) @classmethod def vcs_tree(cls, view): @@ -49,16 +55,25 @@ def vcs_tree(cls, view): @classmethod def is_repository(cls, view): - if view is None or view.file_name() is None or not cls.vcs_dir(cls.vcs_tree(view)): + if view is None or view.file_name() is None: return False else: - return True + vcs_dir_list = cls.vcs_dir(cls.vcs_tree(view)) + + if not vcs_dir_list: + return False + + for directory in vcs_dir_list: + if directory: + return True + + return False class GitHelper(VcsHelper): @classmethod def meta_data_directory(cls): - return '.git' + return ['.git'] @classmethod def is_git_repository(cls, view): @@ -68,7 +83,7 @@ def is_git_repository(cls, view): class HgHelper(VcsHelper): @classmethod def meta_data_directory(cls): - return '.hg' + return ['.hg'] @classmethod def is_hg_repository(cls, view): @@ -78,8 +93,17 @@ def is_hg_repository(cls, view): class SvnHelper(VcsHelper): @classmethod def meta_data_directory(cls): - return '.svn' + return ['.svn'] @classmethod def is_svn_repository(cls, view): return cls.is_repository(view) + +class FossilHelper(VcsHelper): + @classmethod + def meta_data_directory(cls): + return ['.fslckout', '_FOSSIL_'] + + @classmethod + def is_fossil_repository(cls, view): + return cls.is_repository(view) diff --git a/view_collection.py b/view_collection.py index de154409..2512c5cb 100644 --- a/view_collection.py +++ b/view_collection.py @@ -4,9 +4,9 @@ import sublime try: - from .vcs_helpers import GitHelper, HgHelper, SvnHelper + from .vcs_helpers import GitHelper, HgHelper, SvnHelper, FossilHelper except ValueError: - from vcs_helpers import GitHelper, HgHelper, SvnHelper + from vcs_helpers import GitHelper, HgHelper, SvnHelper, FossilHelper class ViewCollection: @@ -18,15 +18,16 @@ class ViewCollection: @staticmethod def add(view): try: - from .gutter_handlers import GitGutterHandler, HgGutterHandler, SvnGutterHandler + from .gutter_handlers import GitGutterHandler, HgGutterHandler, SvnGutterHandler, FossilGutterHandler except ValueError: - from gutter_handlers import GitGutterHandler, HgGutterHandler, SvnGutterHandler + from gutter_handlers import GitGutterHandler, HgGutterHandler, SvnGutterHandler, FossilGutterHandler settings = sublime.load_settings('VcsGutter.sublime-settings') vcs_paths = settings.get('vcs_paths', { 'git': 'git', 'hg': 'hg', - 'svn': 'svn' + 'svn': 'svn', + 'fossil': 'fossil' }) key = None @@ -39,6 +40,9 @@ def add(view): elif SvnHelper.is_svn_repository(view): key = 'svn' klass = SvnGutterHandler + elif FossilHelper.is_fossil_repository(view): + key = 'fossil' + klass = FossilGutterHandler handler = None if key is not None: