diff: Make the diff implementation configurable

This commit is contained in:
Kovid Goyal 2018-05-08 23:32:21 +05:30
parent 196bd9c22b
commit 3a1f85cb69
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 32 additions and 5 deletions

View File

@ -12,6 +12,11 @@ pygments_style default
# The number of lines of context to show around each change. # The number of lines of context to show around each change.
num_context_lines 3 num_context_lines 3
# The diff command to use. Must contain the placeholder _CONTEXT_
# which will be replaced by the number of lines of context. The default
# is to search the system for either git or diff and use that, if found.
diff_cmd auto
# Colors # Colors
foreground black foreground black
background white background white

View File

@ -17,7 +17,7 @@ from ..tui.handler import Handler
from ..tui.loop import Loop from ..tui.loop import Loop
from .collect import create_collection, data_for_path, set_highlight_data from .collect import create_collection, data_for_path, set_highlight_data
from .config import init_config from .config import init_config
from .patch import Differ from .patch import Differ, set_diff_command
from .render import LineRef, render_diff from .render import LineRef, render_diff
try: try:
@ -299,6 +299,7 @@ def main(args):
if os.path.isdir(left) != os.path.isdir(right): if os.path.isdir(left) != os.path.isdir(right):
raise SystemExit('The items to be diffed should both be either directories or files. Comparing a directory to a file is not valid.') raise SystemExit('The items to be diffed should both be either directories or files. Comparing a directory to a file is not valid.')
opts = init_config(args) opts = init_config(args)
set_diff_command(opts.diff_cmd)
loop = Loop() loop = Loop()
handler = DiffHandler(args, opts, left, right) handler = DiffHandler(args, opts, left, right)

View File

@ -4,19 +4,40 @@
import concurrent.futures import concurrent.futures
import os import os
import shlex
import shutil
import subprocess import subprocess
from .collect import lines_for_path from .collect import lines_for_path
from .diff_speedup import changed_center from .diff_speedup import changed_center
left_lines = right_lines = None left_lines = right_lines = None
GIT_DIFF = 'git diff --no-color --no-ext-diff --exit-code -U_CONTEXT_ --no-index --'
DIFF_DIFF = 'diff -p -U _CONTEXT_ --'
def find_differ():
if shutil.which('git'):
return GIT_DIFF
if shutil.which('diff'):
return DIFF_DIFF
def set_diff_command(opt):
if opt == 'auto':
cmd = find_differ()
if cmd is None:
raise SystemExit('Failed to find either the git or diff programs on your system')
else:
cmd = opt
set_diff_command.cmd = cmd
def run_diff(file1, file2, context=3): def run_diff(file1, file2, context=3):
# returns: ok, is_different, patch # returns: ok, is_different, patch
p = subprocess.Popen([ cmd = shlex.split(set_diff_command.cmd.replace('_CONTEXT_', str(context)))
'git', 'diff', '--no-color', '--no-ext-diff', '--exit-code', '-U' + str(context), '--no-index', '--' p = subprocess.Popen(
] + [file1, file2], cmd + [file1, file2],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.DEVNULL) stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.DEVNULL)
stdout, stderr = p.communicate() stdout, stderr = p.communicate()
returncode = p.wait() returncode = p.wait()