From ca72e352923425e1d1632661ffa131d72a03e99f Mon Sep 17 00:00:00 2001 From: Mark Amery Date: Mon, 3 Nov 2014 23:57:23 +0000 Subject: [PATCH 1/5] windows support, maybe? --- gitignore_plugin.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/gitignore_plugin.py b/gitignore_plugin.py index 4273dea..6799acb 100644 --- a/gitignore_plugin.py +++ b/gitignore_plugin.py @@ -3,17 +3,28 @@ import os import os.path import threading +import platform from time import sleep # Used for output suppression when calling subprocess functions; see # http://stackoverflow.com/questions/10251391/suppressing-output-in-python-subprocess-call devnull = open(os.devnull, 'w') +# Used to prevent a new command prompt window from popping up every time a new +# process is spawned on Windows. See +# https://docs.python.org/2/library/subprocess.html#subprocess.STARTUPINFO +if platform.system() == 'Windows': + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = SW_HIDE +else: + startupinfo = None + def start(): # Gets invoked at the bottom of this file. """ Regularly (every 5s) updates the file_exclude_patterns setting from a background thread. - """ + """ if is_first_launch(): migrate_exclude_patterns() record_first_launch() @@ -122,7 +133,8 @@ def parent_repo_path(folder): return subprocess.Popen( ['git', 'rev-parse', '--show-toplevel'], stdout=subprocess.PIPE, - cwd=folder + cwd=folder, + startupinfo=startupinfo ).stdout.read().decode('utf-8', 'ignore').strip() def find_git_repos(folder): @@ -145,7 +157,8 @@ def repo_ignored_paths(git_repo): command_output = subprocess.Popen( ['git', 'clean', '-ndX'], stdout=subprocess.PIPE, - cwd=git_repo + cwd=git_repo, + startupinfo=startupinfo ).stdout.read() command_output = command_output.decode('utf-8', 'ignore') From 3af904a7adb46572242ee7dfbe80e3b83dee2571 Mon Sep 17 00:00:00 2001 From: Mark Amery Date: Tue, 4 Nov 2014 00:10:36 +0000 Subject: [PATCH 2/5] oops --- gitignore_plugin.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gitignore_plugin.py b/gitignore_plugin.py index 6799acb..6fa0521 100644 --- a/gitignore_plugin.py +++ b/gitignore_plugin.py @@ -16,7 +16,7 @@ if platform.system() == 'Windows': startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = SW_HIDE + startupinfo.wShowWindow = subprocess.SW_HIDE else: startupinfo = None @@ -119,7 +119,8 @@ def is_in_git_repo(folder): ["git", "rev-parse", "--is-inside-work-tree"], cwd=folder, stdout=devnull, - stderr=devnull + stderr=devnull, + startupinfo=startupinfo ) return exit_code == 0 From 11d6f004772109465fc46306f57bc7912c54c8b6 Mon Sep 17 00:00:00 2001 From: foo Date: Tue, 4 Nov 2014 21:48:42 +0000 Subject: [PATCH 3/5] it works on windows wooo! --- gitignore_plugin.py | 52 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/gitignore_plugin.py b/gitignore_plugin.py index 6fa0521..5af4292 100644 --- a/gitignore_plugin.py +++ b/gitignore_plugin.py @@ -51,10 +51,24 @@ def update_file_exclude_patterns(): folder_exclude_patterns = s.get('extra_folder_exclude_patterns', []) for path in all_ignored_paths(): if os.path.isdir(path): - folder_exclude_patterns.append(path.rstrip(u'/')) + folder_exclude_patterns.append(path.rstrip(os.path.sep)) else: file_exclude_patterns.append(path) + if platform.system() == 'Windows': + # For some bizarre reason Sublime wants all its filenames to look like + # C/somedir/somefile + # instead of + # C:\somedir\somefile + # as they are normally written on Windows, and will not understand the + # latter at all. All the other functions in this file return paths with + # OS-standard separtors and include the colon after the drive letter on + # Windows, so we need to convert them here to Sublime-format. + folder_exclude_patterns = [windows_path_to_sublime_path(path) + for path in folder_exclude_patterns] + file_exclude_patterns = [windows_path_to_sublime_path(path) + for path in file_exclude_patterns] + new_files = set(file_exclude_patterns) old_files = set(s.get('file_exclude_patterns', [])) new_folders = set(folder_exclude_patterns) @@ -102,7 +116,7 @@ def folder_ignored_paths(folder): # find the .git folder of the repo containing it: if is_in_git_repo(folder): repos.add(parent_repo_path(folder)) - + # Now we find all the ignored paths in any of the above repos for git_repo in repos: ignored_paths = repo_ignored_paths(git_repo) @@ -131,12 +145,17 @@ def parent_repo_path(folder): parent repo. """ - return subprocess.Popen( - ['git', 'rev-parse', '--show-toplevel'], - stdout=subprocess.PIPE, - cwd=folder, - startupinfo=startupinfo - ).stdout.read().decode('utf-8', 'ignore').strip() + # abspath call converts forward slashes to backslashes on Windows; we do + # this wherever necessary to keep the format of our paths standardised on + # Windows. + return os.path.abspath( + subprocess.Popen( + ['git', 'rev-parse', '--show-toplevel'], + stdout=subprocess.PIPE, + cwd=folder, + startupinfo=startupinfo + ).stdout.read().decode('utf-8', 'ignore').strip() + ) def find_git_repos(folder): """ @@ -172,7 +191,7 @@ def repo_ignored_paths(git_repo): # "Would remove foo/bar/yourfile.txt" relative_paths = [line.replace(u'Would remove ', u'', 1) for line in lines] - absolute_paths = [git_repo + u'/' + path for path in relative_paths] + absolute_paths = [os.path.join(git_repo, path) for path in relative_paths] return absolute_paths @@ -196,5 +215,20 @@ def record_first_launch(): s = sublime.load_settings("gitignorer.sublime-settings") s.set('_sublime_gitignorer_has_run', True) sublime.save_settings("gitignorer.sublime-settings") + +def windows_path_to_sublime_path(path): + """ + Removes the colon after the drive letter and replaces backslashes with + slashes. + + e.g. + + windows_path_to_sublime_path("C:\somedir\somefile") + == "C/somedir/somefile" + """ + + assert(path[1] == u':') + without_colon = path[0] + path[2:] + return without_colon.replace(u'\\', u'/') start() \ No newline at end of file From 95395f295c020e35aca43ac4fb0585cc20bbf0da Mon Sep 17 00:00:00 2001 From: foo Date: Tue, 4 Nov 2014 21:49:44 +0000 Subject: [PATCH 4/5] um, now it works on windows --- gitignore_plugin.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gitignore_plugin.py b/gitignore_plugin.py index 5af4292..3f1c3ac 100644 --- a/gitignore_plugin.py +++ b/gitignore_plugin.py @@ -51,7 +51,7 @@ def update_file_exclude_patterns(): folder_exclude_patterns = s.get('extra_folder_exclude_patterns', []) for path in all_ignored_paths(): if os.path.isdir(path): - folder_exclude_patterns.append(path.rstrip(os.path.sep)) + folder_exclude_patterns.append(path) else: file_exclude_patterns.append(path) @@ -190,7 +190,8 @@ def repo_ignored_paths(git_repo): # Each line in `lines` now looks something like: # "Would remove foo/bar/yourfile.txt" - relative_paths = [line.replace(u'Would remove ', u'', 1) for line in lines] + relative_paths = [line.replace(u'Would remove ', u'', 1).rstrip(u'/') + for line in lines] absolute_paths = [os.path.join(git_repo, path) for path in relative_paths] return absolute_paths From f7bbccb9eff17ea60f258b163efbdd5ba9ba6bae Mon Sep 17 00:00:00 2001 From: foo Date: Tue, 4 Nov 2014 22:17:54 +0000 Subject: [PATCH 5/5] st2 fixes --- gitignore_plugin.py | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/gitignore_plugin.py b/gitignore_plugin.py index 3f1c3ac..df85eb1 100644 --- a/gitignore_plugin.py +++ b/gitignore_plugin.py @@ -30,13 +30,10 @@ def start(): # Gets invoked at the bottom of this file. record_first_launch() def run(): - while True: - update_file_exclude_patterns() - sleep(5) - - thread = threading.Thread(target=run) - thread.daemon = True - thread.start() + update_file_exclude_patterns() + sublime.set_timeout(run, 5000) + + run() def update_file_exclude_patterns(): """ @@ -50,24 +47,21 @@ def update_file_exclude_patterns(): file_exclude_patterns = s.get('extra_file_exclude_patterns', []) folder_exclude_patterns = s.get('extra_folder_exclude_patterns', []) for path in all_ignored_paths(): - if os.path.isdir(path): + is_directory = os.path.isdir(path) + if platform.system() == 'Windows': + # For some bizarre reason Sublime wants all its filenames to look like + # C/somedir/somefile + # instead of + # C:\somedir\somefile + # as they are normally written on Windows, and will not understand the + # latter at all. All the other functions in this file return paths with + # OS-standard separtors and include the colon after the drive letter on + # Windows, so we need to convert them here to Sublime-format. + path = windows_path_to_sublime_path(path) + if is_directory: folder_exclude_patterns.append(path) else: file_exclude_patterns.append(path) - - if platform.system() == 'Windows': - # For some bizarre reason Sublime wants all its filenames to look like - # C/somedir/somefile - # instead of - # C:\somedir\somefile - # as they are normally written on Windows, and will not understand the - # latter at all. All the other functions in this file return paths with - # OS-standard separtors and include the colon after the drive letter on - # Windows, so we need to convert them here to Sublime-format. - folder_exclude_patterns = [windows_path_to_sublime_path(path) - for path in folder_exclude_patterns] - file_exclude_patterns = [windows_path_to_sublime_path(path) - for path in file_exclude_patterns] new_files = set(file_exclude_patterns) old_files = set(s.get('file_exclude_patterns', [])) @@ -77,8 +71,8 @@ def update_file_exclude_patterns(): # Only make changes if anything has actually changed, to avoid spamming the # sublime console if new_files != old_files or new_folders != old_folders: - s.set('file_exclude_patterns', file_exclude_patterns) - s.set('folder_exclude_patterns', folder_exclude_patterns) + s.set('file_exclude_patterns', list(file_exclude_patterns)) + s.set('folder_exclude_patterns', list(folder_exclude_patterns)) sublime.save_settings("Preferences.sublime-settings") def all_ignored_paths():