diff kitten: Allow diffing remote files easily via ssh

See #727
This commit is contained in:
Kovid Goyal 2019-10-04 09:08:22 +05:30
parent 53ab7617ca
commit 802da7087c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 22 additions and 2 deletions

View File

@ -13,6 +13,8 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- When drawing unicode symbols that are followed by spaces, use multiple cells
to avoid resized or cut-off glyphs (:iss:`1452`)
- diff kitten: Allow diffing remote files easily via ssh (:iss:`727`)
0.14.6 [2019-09-25]
---------------------

View File

@ -2,14 +2,17 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import atexit
import os
import signal
import subprocess
import sys
import tempfile
import warnings
from collections import defaultdict
from contextlib import suppress
from functools import partial
from gettext import gettext as _
from contextlib import suppress
from kitty.cli import CONFIG_HELP, parse_args
from kitty.constants import appname
@ -506,7 +509,7 @@ def showwarning(message, category, filename, lineno, file=None, line=None):
showwarning.warnings = []
help_text = 'Show a side-by-side diff of the specified files/directories'
help_text = 'Show a side-by-side diff of the specified files/directories. You can also use ssh:hostname:remote-file-path to diff remote files.'
usage = 'file_or_directory_left file_or_directory_right'
@ -516,6 +519,20 @@ def terminate_processes(processes):
os.kill(pid, signal.SIGKILL)
def get_remote_file(path):
if path.startswith('ssh:'):
parts = path.split(':', 2)
if len(parts) == 3:
hostname, rpath = parts[1:]
with tempfile.NamedTemporaryFile(suffix='-' + os.path.basename(rpath), prefix='remote:', delete=False) as tf:
atexit.register(os.remove, tf.name)
p = subprocess.Popen(['ssh', hostname, 'cat', rpath], stdout=tf)
if p.wait() != 0:
raise SystemExit(p.returncode)
return tf.name
return path
def main(args):
warnings.showwarning = showwarning
args, items = parse_args(args[1:], OPTIONS, usage, help_text, 'kitty +kitten diff')
@ -528,6 +545,7 @@ def main(args):
opts = init_config(args)
set_diff_command(opts.diff_cmd)
lines_for_path.replace_tab_by = opts.replace_tab_by
left, right = map(get_remote_file, (left, right))
for f in left, right:
if not os.path.exists(f):
raise SystemExit('{} does not exist'.format(f))