all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* How to use emacs as a "diff3 -m" compatible merge tool?
@ 2022-06-09 10:52 Tassilo Horn
  2022-06-09 19:53 ` Michael Heerdegen
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Tassilo Horn @ 2022-06-09 10:52 UTC (permalink / raw)
  To: help-gnu-emacs

Hi all,

there are certain tools/scripts such as Arch GNU/Linux' pacdiff which
call a user-defined tool for doing a 3-way merge.  For example, pacdiff
wants to merge the current config file with the current package-provided
config file and the package-provided config file of a previous version
as a base/ancestor.

pacdiff calls the user-defined mergeprog like so:

--8<---------------cut here---------------start------------->8---
	if $mergeprog "$file" "$base" "$pacfile" >"$merged"; then
		msg2 "Merged without conflicts."
	fi
--8<---------------cut here---------------end--------------->8---

I'd like to use emacs as mergetool so need to support these calling
convention (which are the ones of "diff3 -m"), i.e.,

  1. args are MY-VERSION BASE THEIR-VERSION
  2. a successful merge exits zero, an aborted merge exits non-zero
  3. the merge result is printed to stdout

I've come up with two versions (ediff-merge & emerge):

--8<---------------cut here---------------start------------->8---
(defun th/command-line-ediff-merge3 (_switch)
  "Do a 3-way merge using `ediff-merge-files-with-ancestor'."
  (let ((make-backup-files nil)
        (my-version    (pop command-line-args-left))
        (base-version  (pop command-line-args-left))
        (their-version (pop command-line-args-left)))
    (ediff-merge-files-with-ancestor
     my-version their-version base-version)))

(add-to-list 'command-switch-alist
             '("--ediff-merge3" . th/command-line-ediff-merge3))

(defun th/command-line-emerge3 (_switch)
  "Do a 3-way merge using `emerge-files-with-ancestor'."
  (let* ((make-backup-files nil)
         (my-version    (pop command-line-args-left))
         (base-version  (pop command-line-args-left))
         (their-version (pop command-line-args-left))
         (merged (make-temp-file (concat (file-name-nondirectory my-version)
                                         ".merged"))))
    (emerge-files-with-ancestor
     nil my-version their-version base-version merged)))

(add-to-list 'command-switch-alist
             '("--emerge3" . th/command-line-emerge3))
--8<---------------cut here---------------end--------------->8---

So now I can call "emacs --ediff-merge3 my base theirs" or "emacs
--emerge3 my base theirs" and do the merge.  However, points 2 and 3
are not yet addressed.

So how to address those?  I guess I need to stick a function in
ediff-quit-merge-hook and emerge-quit-hook.  But then?  How do I print
the merge buffer's contents to stdout?  And how can I influence the exit
code? (I could do (kill-emacs my-exit-code) but would be more happy if I
could also use the merge command with emacsclient where I obviously
don't want to kill emacs.)

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-09 10:52 How to use emacs as a "diff3 -m" compatible merge tool? Tassilo Horn
@ 2022-06-09 19:53 ` Michael Heerdegen
  2022-06-10 16:42   ` Tassilo Horn
  2022-06-10 22:52 ` Emanuel Berg
  2022-06-13 13:34 ` Tassilo Horn
  2 siblings, 1 reply; 16+ messages in thread
From: Michael Heerdegen @ 2022-06-09 19:53 UTC (permalink / raw)
  To: help-gnu-emacs

Tassilo Horn <tsdh@gnu.org> writes:

> How do I print the merge buffer's contents to stdout?  And how can I
> influence the exit code? (I could do (kill-emacs my-exit-code) but
> would be more happy if I could also use the merge command with
> emacsclient where I obviously don't want to kill emacs.)

Never did something like this before.  I spent some time trying to
understand the code in server.el however.  Seems `server-send-string'
can be used for this.  Maybe search for the occurrences - e.g. in
`server-edit-abort' (and the rest of server.el).

The available "options" are explained in the doc of
`server-process-filter' AFAIU.  I think you are interested in those
"accepted by the client" - especially -print and -error.


Michael.




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-09 19:53 ` Michael Heerdegen
@ 2022-06-10 16:42   ` Tassilo Horn
  2022-06-10 18:50     ` Michael Heerdegen
  0 siblings, 1 reply; 16+ messages in thread
From: Tassilo Horn @ 2022-06-10 16:42 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: help-gnu-emacs

Michael Heerdegen <michael_heerdegen@web.de> writes:

Hi Michael,

>> How do I print the merge buffer's contents to stdout?  And how can I
>> influence the exit code? (I could do (kill-emacs my-exit-code) but
>> would be more happy if I could also use the merge command with
>> emacsclient where I obviously don't want to kill emacs.)
>
> Never did something like this before.  I spent some time trying to
> understand the code in server.el however.  Seems `server-send-string'
> can be used for this.  Maybe search for the occurrences - e.g. in
> `server-edit-abort' (and the rest of server.el).
>
> The available "options" are explained in the doc of
> `server-process-filter' AFAIU.  I think you are interested in those
> "accepted by the client" - especially -print and -error.

Thanks, I will have a look.  Do I understand it correctly that your
answer is specifically about the emacsclient case?

If so, I'd rather tackle my usual sysadmin work "emacs -Q -l minimal.el
..." use-case first where (kill-emacs my-exit-code) would be ok.  But
how do I print buffer contents to emacs' stdout?

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-10 16:42   ` Tassilo Horn
@ 2022-06-10 18:50     ` Michael Heerdegen
  2022-06-12 11:31       ` Robert Pluim
  0 siblings, 1 reply; 16+ messages in thread
From: Michael Heerdegen @ 2022-06-10 18:50 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: help-gnu-emacs

Tassilo Horn <tsdh@gnu.org> writes:

> Thanks, I will have a look.  Do I understand it correctly that your
> answer is specifically about the emacsclient case?

Yes.

> But how do I print buffer contents to emacs' stdout?

I don't know.

Michael.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-09 10:52 How to use emacs as a "diff3 -m" compatible merge tool? Tassilo Horn
  2022-06-09 19:53 ` Michael Heerdegen
@ 2022-06-10 22:52 ` Emanuel Berg
  2022-06-13  5:21   ` Tassilo Horn
  2022-06-13 13:34 ` Tassilo Horn
  2 siblings, 1 reply; 16+ messages in thread
From: Emanuel Berg @ 2022-06-10 22:52 UTC (permalink / raw)
  To: help-gnu-emacs

Tassilo Horn wrote:

> And how can I influence the exit code? (I could do
> (kill-emacs my-exit-code) but would be more happy if I could
> also use the merge command with emacsclient where
> I obviously don't want to kill emacs.)

Why not, isn't this supposed to be a shell tool? If so, see
emacs(1) as you know ...

If not, and if it isn't supposed to be exited, how can there
be an exit code to begin? (To end with, without
ending anything.)

> How do I print the merge buffer's contents to stdout?

Here is some material on that but if you use Emacs as a shell
tool you don't need it

  https://stackoverflow.com/a/41435631

-- 
underground experts united
https://dataswamp.org/~incal




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-10 18:50     ` Michael Heerdegen
@ 2022-06-12 11:31       ` Robert Pluim
  0 siblings, 0 replies; 16+ messages in thread
From: Robert Pluim @ 2022-06-12 11:31 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Tassilo Horn, help-gnu-emacs

>>>>> On Fri, 10 Jun 2022 20:50:57 +0200, Michael Heerdegen <michael_heerdegen@web.de> said:

    Michael> Tassilo Horn <tsdh@gnu.org> writes:
    >> Thanks, I will have a look.  Do I understand it correctly that your
    >> answer is specifically about the emacsclient case?

    Michael> Yes.

    >> But how do I print buffer contents to emacs' stdout?

    Michael> I don't know.

With any of the methods to run emacs non-interactively, eg

    emacs -Q --script FILE

any calls to `message' in FILE will go to stdout, so

    (with-current-buffer "mybuffer" (message "%s" (buffer-string)))

should do.

If youʼre using emacsclient, you can write to std*err* using
`external-debugging-output':

    (print "My interesting contents" #'external-debugging-output)

Robert
-- 



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-10 22:52 ` Emanuel Berg
@ 2022-06-13  5:21   ` Tassilo Horn
  2022-06-13  8:09     ` Robert Pluim
  2022-06-13 21:13     ` Emanuel Berg
  0 siblings, 2 replies; 16+ messages in thread
From: Tassilo Horn @ 2022-06-13  5:21 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

Hi Emanuel,

>> And how can I influence the exit code? (I could do (kill-emacs
>> my-exit-code) but would be more happy if I could also use the merge
>> command with emacsclient where I obviously don't want to kill emacs.)
>
> Why not, isn't this supposed to be a shell tool? If so, see
> emacs(1) as you know ...
>
> If not, and if it isn't supposed to be exited, how can there be an
> exit code to begin? (To end with, without ending anything.)

"emacsclient <file>" exits on `server-edit' (C-x #) (or goes to the next
buffer if more than one file were specified on the command line) but
won't make emacs itself exit.  So there is an exit code for emacsclient
but it seem one cannot influence it.

>> How do I print the merge buffer's contents to stdout?
>
> Here is some material on that but if you use Emacs as a shell
> tool you don't need it
>
>   https://stackoverflow.com/a/41435631

Indeed,

  (append-to-file (point-min) (point-max) "/dev/stdout")

seems to do the trick!

Thanks,
Tassilo



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-13  5:21   ` Tassilo Horn
@ 2022-06-13  8:09     ` Robert Pluim
  2022-06-13  9:34       ` Tassilo Horn
  2022-06-13  9:52       ` Michael Heerdegen
  2022-06-13 21:13     ` Emanuel Berg
  1 sibling, 2 replies; 16+ messages in thread
From: Robert Pluim @ 2022-06-13  8:09 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Emanuel Berg, help-gnu-emacs

>>>>> On Mon, 13 Jun 2022 07:21:00 +0200, Tassilo Horn <tsdh@gnu.org> said:

    Tassilo> "emacsclient <file>" exits on `server-edit' (C-x #) (or goes to the next
    Tassilo> buffer if more than one file were specified on the command line) but
    Tassilo> won't make emacs itself exit.  So there is an exit code for emacsclient
    Tassilo> but it seem one cannot influence it.

Thereʼs `server-edit-abort', but that doesnʼt (currently) allow you to
tell emacsclient which exit code to use. I guess it could be extended.

    >>> How do I print the merge buffer's contents to stdout?
    >> 
    >> Here is some material on that but if you use Emacs as a shell
    >> tool you don't need it
    >> 
    >> https://stackoverflow.com/a/41435631

    Tassilo> Indeed,

    Tassilo>   (append-to-file (point-min) (point-max) "/dev/stdout")

Except on platforms that donʼt have "/dev/stdout".

Robert
-- 



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-13  8:09     ` Robert Pluim
@ 2022-06-13  9:34       ` Tassilo Horn
  2022-06-13  9:52       ` Michael Heerdegen
  1 sibling, 0 replies; 16+ messages in thread
From: Tassilo Horn @ 2022-06-13  9:34 UTC (permalink / raw)
  To: Robert Pluim; +Cc: Emanuel Berg, help-gnu-emacs

Robert Pluim <rpluim@gmail.com> writes:

Hi Robert,

>     Tassilo> "emacsclient <file>" exits on `server-edit' (C-x #) (or goes to the next
>     Tassilo> buffer if more than one file were specified on the command line) but
>     Tassilo> won't make emacs itself exit.  So there is an exit code for emacsclient
>     Tassilo> but it seem one cannot influence it.
>
> Thereʼs `server-edit-abort', but that doesnʼt (currently) allow you to
> tell emacsclient which exit code to use. I guess it could be extended.

Maybe.  I guess there's a problem with "emacsclient file1 file2" when
you abort the edit of file1 but complete the one of file2.

In the end, the exit code is probably not that important.  At least the
pacdiff script asks you if the merge result should be used.

>     >>> How do I print the merge buffer's contents to stdout?
>     >> 
>     >> Here is some material on that but if you use Emacs as a shell
>     >> tool you don't need it
>     >> 
>     >> https://stackoverflow.com/a/41435631
>
>     Tassilo> Indeed,
>
>     Tassilo>   (append-to-file (point-min) (point-max) "/dev/stdout")
>
> Except on platforms that donʼt have "/dev/stdout".

Sure, but those don't matter to me.  Maybe I'll bring that topic up on
emacs-devel once I have a working solution for GNU systems.

Thanks,
Tassilo



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-13  8:09     ` Robert Pluim
  2022-06-13  9:34       ` Tassilo Horn
@ 2022-06-13  9:52       ` Michael Heerdegen
  2022-06-13 11:18         ` Robert Pluim
  1 sibling, 1 reply; 16+ messages in thread
From: Michael Heerdegen @ 2022-06-13  9:52 UTC (permalink / raw)
  To: help-gnu-emacs

Robert Pluim <rpluim@gmail.com> writes:

> Thereʼs `server-edit-abort', but that doesnʼt (currently) allow you to
> tell emacsclient which exit code to use. I guess it could be extended.

That uses the `server-send-string' command I mentioned.

I guess the exit code generation itself is done in the C sources.

Michael.




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-13  9:52       ` Michael Heerdegen
@ 2022-06-13 11:18         ` Robert Pluim
  0 siblings, 0 replies; 16+ messages in thread
From: Robert Pluim @ 2022-06-13 11:18 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: help-gnu-emacs

>>>>> On Mon, 13 Jun 2022 11:52:44 +0200, Michael Heerdegen <michael_heerdegen@web.de> said:

    Michael> Robert Pluim <rpluim@gmail.com> writes:
    >> Thereʼs `server-edit-abort', but that doesnʼt (currently) allow you to
    >> tell emacsclient which exit code to use. I guess it could be extended.

    Michael> That uses the `server-send-string' command I mentioned.

    Michael> I guess the exit code generation itself is done in the C sources.

Yes, and itʼs going to be either EXIT_SUCCESS or EXIT_FAILURE.

Robert
-- 



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-09 10:52 How to use emacs as a "diff3 -m" compatible merge tool? Tassilo Horn
  2022-06-09 19:53 ` Michael Heerdegen
  2022-06-10 22:52 ` Emanuel Berg
@ 2022-06-13 13:34 ` Tassilo Horn
  2 siblings, 0 replies; 16+ messages in thread
From: Tassilo Horn @ 2022-06-13 13:34 UTC (permalink / raw)
  Cc: help-gnu-emacs

Hi all,

> pacdiff calls the user-defined mergeprog like so:
>
> 	if $mergeprog "$file" "$base" "$pacfile" >"$merged"; then
> 		msg2 "Merged without conflicts."
> 	fi
>
>
> I'd like to use emacs as mergetool so need to support these calling
> convention (which are the ones of "diff3 -m"), i.e.,
>
>   1. args are MY-VERSION BASE THEIR-VERSION
>   2. a successful merge exits zero, an aborted merge exits non-zero
>   3. the merge result is printed to stdout

Here's a version which works for me (on GNU/Linux where /dev/stdout is a
thing) and fulfills all requirements except for 2 which turns out not to
be important at least in my pacdiff use-case.  It'll ask if I want to
use the merge result anyhow so exiting successfully even when I abort
the merge is no big deal.

--8<---------------cut here---------------start------------->8---
(defun th/ediff-spit-merge-result-and-kill-emacs ()
  (if-let ((merge-buf (ediff-get-buffer 'C)))
      (with-current-buffer merge-buf
        (append-to-file (point-min) (point-max)
                        "/dev/stdout")
        (kill-emacs))
    (error "There is no merge result buffer")))

(defun th/command-line-ediff-merge3 (_switch)
  "Do a 3-way merge using `ediff-merge-files-with-ancestor'.
Assumes the command line args were: my-version base-version their-version"
  (setq ediff-quit-merge-hook (list #'th/ediff-spit-merge-result-and-kill-emacs))
  (let ((make-backup-files nil)
        (my-version    (pop command-line-args-left))
        (base-version  (pop command-line-args-left))
        (their-version (pop command-line-args-left)))
    (ediff-merge-files-with-ancestor
     my-version their-version base-version)))

(add-to-list 'command-switch-alist
             '("--ediff-merge3" . th/command-line-ediff-merge3))
--8<---------------cut here---------------end--------------->8---

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-13  5:21   ` Tassilo Horn
  2022-06-13  8:09     ` Robert Pluim
@ 2022-06-13 21:13     ` Emanuel Berg
  2022-06-14  7:50       ` Tassilo Horn
  1 sibling, 1 reply; 16+ messages in thread
From: Emanuel Berg @ 2022-06-13 21:13 UTC (permalink / raw)
  To: help-gnu-emacs

Tassilo Horn wrote:

> "emacsclient <file>" exits on `server-edit' (C-x #) (or goes
> to the next buffer if more than one file were specified on
> the command line) but won't make emacs itself exit. So there
> is an exit code for emacsclient but it seem one cannot
> influence it.

OK, but is that hooked to whatever adheres to the interface
you showed, if so what is that and how does that
happen exactly?

-- 
underground experts united
https://dataswamp.org/~incal




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-13 21:13     ` Emanuel Berg
@ 2022-06-14  7:50       ` Tassilo Horn
  2022-06-14 10:06         ` Emanuel Berg
  0 siblings, 1 reply; 16+ messages in thread
From: Tassilo Horn @ 2022-06-14  7:50 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

>> "emacsclient <file>" exits on `server-edit' (C-x #) (or goes
>> to the next buffer if more than one file were specified on
>> the command line) but won't make emacs itself exit. So there
>> is an exit code for emacsclient but it seem one cannot
>> influence it.
>
> OK, but is that hooked to whatever adheres to the interface you
> showed,

No, it's independent of my specific use-case but would be nice to have
in general in scripting scenarios, i.e., where a script/program invokes
emacsclient in order to let the user edit something where the user
should be able to propagate back to the calling program if his edits
were successfully completed or aborted.

> if so what is that and how does that happen exactly?

Sorry, I don't understand the question.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-14  7:50       ` Tassilo Horn
@ 2022-06-14 10:06         ` Emanuel Berg
  2022-06-14 11:23           ` Tassilo Horn
  0 siblings, 1 reply; 16+ messages in thread
From: Emanuel Berg @ 2022-06-14 10:06 UTC (permalink / raw)
  To: help-gnu-emacs

Tassilo Horn wrote:

>>> "emacsclient <file>" exits on `server-edit' (C-x #) (or
>>> goes to the next buffer if more than one file were
>>> specified on the command line) but won't make emacs itself
>>> exit. So there is an exit code for emacsclient but it seem
>>> one cannot influence it.
>>
>> OK, but is that hooked to whatever adheres to the interface
>> you showed,
>
> No, it's independent of my specific use-case but would be
> nice to have in general in scripting scenarios, i.e., where
> a script/program invokes emacsclient in order to let the
> user edit something where the user should be able to
> propagate back to the calling program if his edits were
> successfully completed or aborted.

This

  (server-send-string (car server-buffer-clients) "-error die")

?

https://superuser.com/questions/295156/how-to-set-the-exit-status-for-emacsclient

-- 
underground experts united
https://dataswamp.org/~incal




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to use emacs as a "diff3 -m" compatible merge tool?
  2022-06-14 10:06         ` Emanuel Berg
@ 2022-06-14 11:23           ` Tassilo Horn
  0 siblings, 0 replies; 16+ messages in thread
From: Tassilo Horn @ 2022-06-14 11:23 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

>>>> "emacsclient <file>" exits on `server-edit' (C-x #) (or
>>>> goes to the next buffer if more than one file were
>>>> specified on the command line) but won't make emacs itself
>>>> exit. So there is an exit code for emacsclient but it seem
>>>> one cannot influence it.
>>>
>>> OK, but is that hooked to whatever adheres to the interface
>>> you showed,
>>
>> No, it's independent of my specific use-case but would be
>> nice to have in general in scripting scenarios, i.e., where
>> a script/program invokes emacsclient in order to let the
>> user edit something where the user should be able to
>> propagate back to the calling program if his edits were
>> successfully completed or aborted.
>
> This
>
>   (server-send-string (car server-buffer-clients) "-error die")
>
> ?
>
> https://superuser.com/questions/295156/how-to-set-the-exit-status-for-emacsclient

Indeed, that seems to do the job.  (I haven't tested but the SO answer
suggests it used to work.)

Thanks,
Tassilo



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2022-06-14 11:23 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-09 10:52 How to use emacs as a "diff3 -m" compatible merge tool? Tassilo Horn
2022-06-09 19:53 ` Michael Heerdegen
2022-06-10 16:42   ` Tassilo Horn
2022-06-10 18:50     ` Michael Heerdegen
2022-06-12 11:31       ` Robert Pluim
2022-06-10 22:52 ` Emanuel Berg
2022-06-13  5:21   ` Tassilo Horn
2022-06-13  8:09     ` Robert Pluim
2022-06-13  9:34       ` Tassilo Horn
2022-06-13  9:52       ` Michael Heerdegen
2022-06-13 11:18         ` Robert Pluim
2022-06-13 21:13     ` Emanuel Berg
2022-06-14  7:50       ` Tassilo Horn
2022-06-14 10:06         ` Emanuel Berg
2022-06-14 11:23           ` Tassilo Horn
2022-06-13 13:34 ` Tassilo Horn

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.