Skip to content

Instantly share code, notes, and snippets.

@OdatNurd
Created November 8, 2018 20:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save OdatNurd/de24ea58e458e8765732c5ca1b245cba to your computer and use it in GitHub Desktop.
Save OdatNurd/de24ea58e458e8765732c5ca1b245cba to your computer and use it in GitHub Desktop.
Dirt simple integration to Sublime Merge from Sublime Text
[
{ "command": "smerge_search" },
]
[
{ "caption": "View File History in Sublime Merge", "command": "smerge_search", "args": {"files": []} },
{ "caption": "-", "id": "folder_commands" },
{ "caption": "Open in Sublime Merge", "command": "smerge_open", "args": { "dirs": [], "side_bar": true} }
]
import sublime
import sublime_plugin
import os
import subprocess
from Default.exec import AsyncProcess, ProcessListener
def _find_git_root(path):
"""
Find the containing git repository (if any) in a given path; returns the
repository root or None if one can't be found.
"""
if os.path.isdir(os.path.join(path, ".git")):
return path
nPath = os.path.split(path)[0]
if nPath != path:
return _find_git_root(nPath)
return None
def _git_root_for_view(view):
"""
Find the git repository that the file in the provided view exists in, if
any.
"""
if not hasattr(_git_root_for_view, "cache"):
_git_root_for_view.cache = {}
if not view or view.file_name() is None:
return None
path, file = os.path.split(view.file_name())
if path not in _git_root_for_view.cache:
_git_root_for_view.cache[path] = _find_git_root(path)
return _git_root_for_view.cache[path]
class SublimeMerge(ProcessListener):
"""
Abstract the execution of Sublime Merge.
"""
encoding = "utf-8"
def __init__(self, args, working_dir="", env={}):
self.working_dir = working_dir
self.env = env
self.shell_cmd = "{cmd} {args}".format(
cmd="smerge.exe" if sublime.platform() == "windows" else "smerge",
args=" ".join(map(lambda x: '"{}"'.format(x), args)))
def execute(self):
try:
if self.working_dir:
os.chdir(self.working_dir)
AsyncProcess(None, self.shell_cmd, self.env, listener=self)
except Exception as err:
sublime.status_message("Error smerging: {0}".format(str(err)))
class SmergeOpenCommand(sublime_plugin.WindowCommand):
"""
Open a repository in Sublime Merge; takes a git path explicitly or from
the path of the currently active view if none is provided and the command
is not being invoked from the side bar.
"""
def run(self, dirs, side_bar=False):
SublimeMerge([self.git_root(dirs)]).execute()
def git_root(self, dirs):
if len(dirs) == 0 and self.window.active_view() is not None:
return _git_root_for_view(self.window.active_view())
if len(dirs) == 1:
return _find_git_root(dirs[0])
return None
def is_enabled(self, dirs, side_bar=False):
if side_bar and len(dirs) != 1:
return False
return self.git_root(dirs) is not None
class SmergeSearchCommand(sublime_plugin.TextCommand):
"""
Open a Sublime Merge search for the current file, optionally focusing on
the history of the currently selected lines, if any.
"""
def run(self, edit, files=[]):
target = self.target_path(files)
path, file = os.path.split(target)
git_dir = _find_git_root(path)
relpath = os.path.relpath(target, git_dir)
lines = self.sel_lines()
if " " in relpath:
relpath = '\\"{0}\\"'.format(relpath)
term = "file:{0}".format(relpath)
if lines:
term = term + " " + lines
SublimeMerge(["search", term], git_dir).execute()
def target_path(self, files):
if files:
return files[0]
return self.view.file_name()
def sel_lines(self):
sel = self.view.sel()[0]
if sel.empty():
return ''
start = self.view.rowcol(sel.begin())[0] + 1
end = self.view.rowcol(sel.end())[0] + 1
return 'line:{0}-{1}'.format(start, end)
def description(self, files=[]):
if self.view.sel()[0].empty():
return "Sublime Merge: View File History"
return "Sublime Merge: View Selection History"
def is_enabled(self, files=[]):
if len(files) <= 1:
target = self.target_path(files)
if target:
path = os.path.split(target)[0]
return _find_git_root(path) is not None
return False
[
{ "caption": "Sublime Merge: View File History", "command": "smerge_search" },
{ "caption": "Sublime Merge: Open Repository", "command": "smerge_open", "args": { "dirs": [] } },
]
@dipandit
Copy link

This is nice, I am loving it.
View File History does not work for files stored at one or more level below. When it opens Sublime Merge, the search key is using back-slash in file path. It needs to be changed to forward-slash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment