From 190371b805dad8c46920dd333f7bac525e6fb34c Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 16 Jul 2017 16:08:46 -0400 Subject: ediff: learn --merge, and gain an optional REGEX filter for --recursive This brings it much closer to being a complete interface to ediff on files. --- common.sh.in | 6 ++++-- ediff.sh.in | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/common.sh.in b/common.sh.in index 2488a69..54431fe 100644 --- a/common.sh.in +++ b/common.sh.in @@ -1,6 +1,6 @@ # begin common.sh {{{ -# Copyright (C) 2013-2014, 2016 Luke Shumaker +# Copyright (C) 2013-2014, 2016-2017 Luke Shumaker # # This file is not considered part of GNU Emacs. # @@ -42,7 +42,9 @@ flag() { printf -- "%s\n" "$flag" flag='' fi - printf -- "%- ${_flag_indent}s%s\n" "$flag" "$(print "${@:2}")" + local text + text="$(print "${@:2}")" + printf -- "%- ${_flag_indent}s%s\n" "$flag" "${text//$'\n'/"$(printf -- "\n%- ${_flag_indent}s%s\n" '')"}" } error() { diff --git a/ediff.sh.in b/ediff.sh.in index 569721e..1a227bb 100644 --- a/ediff.sh.in +++ b/ediff.sh.in @@ -1,6 +1,6 @@ #!@bash@ -# Copyright (C) 2014, 2016 Luke Shumaker +# Copyright (C) 2014, 2016-2017 Luke Shumaker # # This file is not considered part of GNU Emacs. # @@ -21,25 +21,56 @@ m4_include(common.sh.in) usage() { print 'Usage: %q [OPTIONS] FILE_A FILE_B' "$0" - print ' or: %q -3 [OPTIONS] FILE_A FILE_B FILE_C' "$0" + print ' or: %q -3 [OPTIONS] FILE_A FILE_B FILE_C|FILE_ANCESTOR' "$0" print "Use Emacs' ediff-mode to compare two files" echo print 'The following OPTIONS are accepted:' emacs_usage - flag '-3' 'Do a 3-way diff instead of 2-way' - flag '-r, --recursive' 'Diff directories recursively' + flag '-r, -R REGEXP, --recursive[=REGEXP]' \ + 'Diff directories recursively, +excluding filenames not matching REGEXP' + + flag '-3' \ + 'Do a 3-way diff instead of 2-way +When used in the context of a --merge, +the 3rd file is the common ancestor between A and B' + + flag '-m OUTFILE, --merge=OUTFILE' \ + 'Merge files A and B, saving the output in OUTFILE' } main() { declare -a flags=() - declare -a files=() - declare -i cnt=2 - declare cmd=ediff declare mode=normal + # The functions that we currently make available are: + # (ediff FILE-A FILE-B &optional STARTUP-HOOKS) + # (ediff3 FILE-A FILE-B FILE-C &optional STARTUP-HOOKS) + # (ediff-merge FILE-A FILE-B &optional STARTUP-HOOKS MERGE-BUFFER-FILE) + # (ediff-merge-with-ancestor FILE-A FILE-B FILE-ANCESTOR &optional STARTUP-HOOKS MERGE-BUFFER-FILE) + # and their recursive equivalents: + # (edirs DIR1 DIR2 REGEXP) + # (edirs3 DIR1 DIR2 DIR3 REGEXP) + # (edirs-merge DIR1 DIR2 REGEXP &optional MERGE-AUTOSTORE-DIR) + # (edirs-merge-with-ancestor DIR1 DIR2 ANCESTOR-DIR REGEXP &optional MERGE-AUTOSTORE-DIR) + # + # This list is currently missing the "revision" commands: + # (ediff-revision &optional FILE STARTUP-HOOKS) + # (edir-revisions DIR1 REGEXP) + # (edir-merge-revisions DIR1 REGEXP &optional MERGE-AUTOSTORE-DIR) + # (edir-merge-revisions-with-ancestor DIR1 REGEXP &optional MERGE-AUTOSTORE-DIR) + # and the epatch command: + # (epatch &optional ARG PATCH-BUF) + + declare cmd=ediff + declare -i cnt=2 + declare -a files=() + declare extra=nil # STARTUP-HOOKS for cmd=ediff, REGEXP for cmd=edirs + declare merge='' + emacs_getopt_init declare args - if ! args="$(emacs_getopt 3r recursive "$@")"; then + if ! args="$(emacs_getopt rR:3m: recursive::,merge: "$@")"; then mode=error else eval set -- "$args" @@ -47,8 +78,18 @@ main() { case "$1" in -V|--version) shift; mode=version;; -H|--help) shift; mode=usage;; - -r|--recursive) shift; cmd=edirs;; + + -r) shift; cmd=edirs;; + -R|--recursive) + cmd=edirs + [[ -z "$2" ]] || extra="$(emacs_quote "$2")" + shift 2 + ;; + -3) shift; cnt=3;; + + -m|--merge) merge="$(emacs_quote "$2")"; shift 2;; + --) shift; break;; *) if [[ $1 =~ $emacs_getopt_2 ]]; then @@ -65,9 +106,15 @@ main() { fi fi + if [[ -z "$merge" ]]; then + [[ $cnt == 2 ]] || cmd+='3' + else + cmd+='-merge' + [[ $cnt == 2 ]] || cmd+='-with-ancestor' + fi next "$mode" \ emacsclient "${flags[@]}" --eval \ - "(${cmd}${cnt#2} $(emacs_quote "${files[@]}"))" + "(${cmd} $(emacs_quote "${files[@]}") $extra $merge)" } main "$@" -- cgit v1.2.3