diff --git a/docs/with-editor.org b/docs/with-editor.org index 7926389..9b747da 100644 --- a/docs/with-editor.org +++ b/docs/with-editor.org @@ -7,7 +7,7 @@ #+texinfo_dir_category: Emacs #+texinfo_dir_title: With-Editor: (with-editor). #+texinfo_dir_desc: Using the Emacsclient as $EDITOR -#+subtitle: for {{{version}}} +#+subtitle: for version 3.4.1 #+setupfile: .orgconfig @@ -27,7 +27,7 @@ additional functionality which makes it useful even for end-users, who don't use Magit or another package which uses it internally. #+texinfo: @noindent -This manual is for With-Editor {{{version}}}. +This manual is for With-Editor version 3.4.1. #+texinfo: @insertcopying :END: diff --git a/docs/with-editor.texi b/docs/with-editor.texi new file mode 100644 index 0000000..98b20c0 --- /dev/null +++ b/docs/with-editor.texi @@ -0,0 +1,344 @@ +\input texinfo @c -*- texinfo -*- +@c %**start of header +@setfilename with-editor.info +@settitle With-Editor User Manual +@documentencoding UTF-8 +@documentlanguage en +@c %**end of header + +@copying +@quotation +Copyright (C) 2015-2024 Jonas Bernoulli + +You can redistribute this document and/or modify it under the terms +of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any +later version. + +This document is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE@. See the GNU +General Public License for more details. + +@end quotation +@end copying + +@dircategory Emacs +@direntry +* With-Editor: (with-editor). Using the Emacsclient as $EDITOR. +@end direntry + +@finalout +@titlepage +@title With-Editor User Manual +@subtitle for version 3.4.1 +@author Jonas Bernoulli +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@ifnottex +@node Top +@top With-Editor User Manual + +The library @code{with-editor} makes it easy to use the Emacsclient as the +@code{$EDITOR} of child processes, making sure they know how to call home. +For remote processes a substitute is provided, which communicates with +Emacs on standard output instead of using a socket as the Emacsclient +does. + +This library was written because Magit has to be able to do the above +to allow the user to edit commit messages gracefully and to edit +rebase sequences, which wouldn't be possible at all otherwise. + +Because other packages can benefit from such functionality, this +library is made available as a separate package. It also defines some +additional functionality which makes it useful even for end-users, who +don't use Magit or another package which uses it internally. + +@noindent +This manual is for With-Editor version 3.4.1. + +@insertcopying +@end ifnottex + +@menu +* Using the With-Editor package:: +* Using With-Editor as a library:: +* Debugging:: +* Function and Command Index:: +* Variable Index:: + +@detailmenu +--- The Detailed Node Listing --- + +Using the With-Editor package + +* Configuring With-Editor:: +* Using With-Editor commands:: + +@end detailmenu +@end menu + +@node Using the With-Editor package +@chapter Using the With-Editor package + +The @code{With-Editor} package is used internally by Magit when editing +commit messages and rebase sequences. It also provides some commands +and features which are useful by themselves, even if you don't use +Magit. + +For information about using this library in your own package, see +@ref{Using With-Editor as a library}. + +@menu +* Configuring With-Editor:: +* Using With-Editor commands:: +@end menu + +@node Configuring With-Editor +@section Configuring With-Editor + +With-Editor tries very hard to locate a suitable @code{emacsclient} +executable, so ideally you should never have to customize the option +@code{with-editor-emacsclient-executable}. When it fails to do so, then the +most likely reason is that someone found yet another way to package +Emacs (most likely on macOS) without putting the executable on @code{$PATH}, +and we have to add another kludge to find it anyway. + +@defopt with-editor-emacsclient-executable +The @code{emacsclient} executable used as the editor by child processes of +this Emacs instance. By using this executable, child processes can +call home to their parent process. + +This option is automatically set at startup by looking in @code{exec-path}, +and other places where the executable could be installed, to find +the @code{emacsclient} executable most suitable for the current Emacs +instance. + +You should @strong{not} customize this option permanently. If you have to do +it, then you should consider that a temporary kludge and inform the +Magit maintainer as described in @ref{Debugging}. + +If With-Editor fails to find a suitable @code{emacsclient} on your system, +then this should be fixed for all users at once, by teaching +@code{with-editor-locate-emacsclient} how to do so on your system and +systems like yours. Doing it this way has the advantage, that you +won't have do it again every time you update Emacs, and that other +users who have installed Emacs the same way as you have, won't have +to go through the same trouble. + +Note that there also is a nuclear option; setting this variable to +@code{nil} causes the "sleeping editor" described below to be used even for +local child processes. Obviously we don't recommend that you use +this except in "emergencies", i.e., before we had a change to add a +kludge appropriate for your setup. +@end defopt + +@defun with-editor-locate-emacsclient +The function used to set the initial value of the option +@code{with-editor-emacsclient-executable}. There's a lot of voodoo here. +@end defun + +The @code{emacsclient} cannot be used when using Tramp to run a process on a +remote machine. (Theoretically it could, but that would be hard to +setup, very fragile, and rather insecure). + +With-Editor provides an alternative "editor" which can be used by +remote processes in much the same way as local processes use an +@code{emacsclient} executable. This alternative is known as the "sleeping +editor" because it is implemented as a shell script which sleeps until +it receives a signal. + +@defopt with-editor-sleeping-editor +The sleeping editor is a shell script used as the editor of child +processes when the @code{emacsclient} executable cannot be used. + +This fallback is used for asynchronous processes started inside the +macro @code{with-editor}, when the process runs on a remote machine or for +local processes when @code{with-editor-emacsclient-executable} is @code{nil}. + +Where the latter uses a socket to communicate with Emacs' server, +this substitute prints edit requests to its standard output on +which a process filter listens for such requests. As such it is +not a complete substitute for a proper @code{emacsclient}, it can only +be used as @code{$EDITOR} of child process of the current Emacs instance. + +Some shells do not execute traps immediately when waiting for a +child process, but by default we do use such a blocking child +process. + +If you use such a shell (e.g., @code{csh} on FreeBSD, but not Debian), then +you have to edit this option. You can either replace @code{sh} with @code{bash} +(and install that), or you can use the older, less performant +implementation: + +@lisp +"sh -c '\ +echo \"WITH-EDITOR: $$ OPEN $0$1 IN $(pwd)\"; \ +trap \"exit 0\" USR1; \ +trap \"exit 1\" USR2; \ +while true; do sleep 1; done'" +@end lisp + +Note that the unit separator character () right after the file +name ($0) is required. + +Also note that using this alternative implementation leads to a +delay of up to a second. The delay can be shortened by replacing +@code{sleep 1} with @code{sleep 0.01}, or if your implementation does not support +floats, then by using @code{nanosleep} instead. +@end defopt + +@node Using With-Editor commands +@section Using With-Editor commands + +This section describes how to use the @code{with-editor} library @emph{outside} of +Magit. You don't need to know any of this just to create commits +using Magit. + +The commands @code{with-editor-async-shell-command} and +@code{with-editor-shell-command} are intended as drop in replacements for +@code{async-shell-command} and @code{shell-command}. They automatically export +@code{$EDITOR} making sure the executed command uses the current Emacs +instance as "the editor". With a prefix argument these commands +prompt for an alternative environment variable such as @code{$GIT_EDITOR}. + +@deffn Command with-editor-async-shell-command +This command is like @code{async-shell-command}, but it runs the shell +command with the current Emacs instance exported as @code{$EDITOR}. +@end deffn + +@deffn Command with-editor-shell-command +This command is like @code{shell-command}, but if the shell command ends +with @code{&} and is therefore run asynchronously, then the current Emacs +instance is exported as @code{$EDITOR}. +@end deffn + +To always use these variants add this to your init file: + +@lisp +(keymap-global-set " " + #'with-editor-async-shell-command) +(keymap-global-set " " + #'with-editor-shell-command) +@end lisp + +Alternatively use the global @code{shell-command-with-editor-mode}. + +@defvar shell-command-with-editor-mode +When this mode is active, then @code{$EDITOR} is exported whenever +ultimately @code{shell-command} is called to asynchronously run some shell +command. This affects most variants of that command, whether they +are defined in Emacs or in some third-party package. +@end defvar + +The command @code{with-editor-export-editor} exports @code{$EDITOR} or another +such environment variable in @code{shell-mode}, @code{eshell-mode}, @code{term-mode} and +@code{vterm-mode} buffers. Use this Emacs command before executing a shell +command which needs the editor set, or always arrange for the current +Emacs instance to be used as editor by adding it to the appropriate +mode hooks: + +@lisp +(add-hook 'shell-mode-hook 'with-editor-export-editor) +(add-hook 'eshell-mode-hook 'with-editor-export-editor) +(add-hook 'term-exec-hook 'with-editor-export-editor) +(add-hook 'vterm-mode-hook 'with-editor-export-editor) +@end lisp + +Some variants of this function exist; these two forms are equivalent: + +@lisp +(add-hook 'shell-mode-hook + (apply-partially 'with-editor-export-editor "GIT_EDITOR")) +(add-hook 'shell-mode-hook 'with-editor-export-git-editor) +@end lisp + +@deffn Command with-editor-export-editor +When invoked in a @code{shell-mode}, @code{eshell-mode}, @code{term-mode} or @code{vterm-mode} +buffer, this command teaches shell commands to use the current Emacs +instance as the editor, by exporting @code{$EDITOR}. +@end deffn + +@deffn Command with-editor-export-git-editor +This command is like @code{with-editor-export-editor} but exports +@code{$GIT_EDITOR}. +@end deffn + +@deffn Command with-editor-export-hg-editor +This command is like @code{with-editor-export-editor} but exports +@code{$HG_EDITOR}. +@end deffn + +@node Using With-Editor as a library +@chapter Using With-Editor as a library + +This section describes how to use the @code{with-editor} library @emph{outside} of +Magit to teach another package how to have its child processes call +home, just like Magit does. You don't need to know any of this just +to create commits using Magit. You can also ignore this if you use +@code{with-editor} outside of Magit, but only as an end-user. + +For information about interactive use and options that affect both +interactive and non-interactive use, see @ref{Using the With-Editor package}. + +@defmac with-editor &rest body +This macro arranges for the @code{emacsclient} or the sleeping editor to be +used as the editor of child processes, effectively teaching them to +call home to the current Emacs instance when they require that the +user edits a file. + +This is done by establishing a local binding for @code{process-environment} +and changing the value of the @code{EDITOR} environment variable in that +scope. This affects all (asynchronous) processes started by forms +(dynamically) inside BODY@. + +If BODY begins with a literal string, then that variable is set +instead of @code{EDITOR}. +@end defmac + +@defmac with-editor* envvar &rest body +This macro is like @code{with-editor} instead that the ENVVAR argument is +required and that it is evaluated at run-time. +@end defmac + +@defun with-editor-set-process-filter process filter +This function is like @code{set-process-filter} but ensures that adding the +new FILTER does not remove the @code{with-editor-process-filter}. This is +done by wrapping the two filter functions using a lambda, which +becomes the actual filter. It calls FILTER first, which may or +may not insert the text into the PROCESS's buffer. Then it calls +@code{with-editor-process-filter}, passing @code{t} as NO-STANDARD-FILTER@. +@end defun + +@node Debugging +@chapter Debugging + +With-Editor tries very hard to locate a suitable @code{emacsclient} +executable, and then sets option @code{with-editor-emacsclient-executable} +accordingly. In very rare cases this fails. When it does fail, then +the most likely reason is that someone found yet another way to +package Emacs (most likely on macOS) without putting the executable on +@code{$PATH}, and we have to add another kludge to find it anyway. + +If you are having problems using @code{with-editor}, e.g., you cannot commit +in Magit, then please open a new issue at +@uref{https://github.com/magit/with-editor/issues} and provide information +about your Emacs installation. Most importantly how did you install +Emacs and what is the output of @code{M-x with-editor-debug RET}. + +@node Function and Command Index +@appendix Function and Command Index + +@printindex fn + +@node Variable Index +@appendix Variable Index + +@printindex vr + +@bye