dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

with-editor.org (12742B)


      1 #+title: With-Editor User Manual
      2 :PREAMBLE:
      3 #+author: Jonas Bernoulli
      4 #+email: jonas@bernoul.li
      5 #+date: 2015-{{{year}}}
      6 
      7 #+texinfo_dir_category: Emacs
      8 #+texinfo_dir_title: With-Editor: (with-editor).
      9 #+texinfo_dir_desc: Using the Emacsclient as $EDITOR
     10 #+subtitle: for version 3.2.0
     11 
     12 #+setupfile: .orgconfig
     13 
     14 The library ~with-editor~ makes it easy to use the Emacsclient as the
     15 ~$EDITOR~ of child processes, making sure they know how to call home.
     16 For remote processes a substitute is provided, which communicates with
     17 Emacs on standard output instead of using a socket as the Emacsclient
     18 does.
     19 
     20 This library was written because Magit has to be able to do the above
     21 to allow the user to edit commit messages gracefully and to edit
     22 rebase sequences, which wouldn't be possible at all otherwise.
     23 
     24 Because other packages can benefit from such functionality, this
     25 library is made available as a separate package.  It also defines some
     26 additional functionality which makes it useful even for end-users, who
     27 don't use Magit or another package which uses it internally.
     28 
     29 #+texinfo: @noindent
     30 This manual is for With-Editor version 3.2.0.
     31 
     32 #+begin_quote
     33 Copyright (C) 2015-{{{year}}} Jonas Bernoulli <jonas@bernoul.li>
     34 
     35 You can redistribute this document and/or modify it under the terms
     36 of the GNU General Public License as published by the Free Software
     37 Foundation, either version 3 of the License, or (at your option) any
     38 later version.
     39 
     40 This document is distributed in the hope that it will be useful,
     41 but WITHOUT ANY WARRANTY; without even the implied warranty of
     42 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     43 General Public License for more details.
     44 #+end_quote
     45 :END:
     46 * Using the With-Editor package
     47 
     48 The ~With-Editor~ package is used internally by Magit when editing
     49 commit messages and rebase sequences.  It also provides some commands
     50 and features which are useful by themselves, even if you don't use
     51 Magit.
     52 
     53 For information about using this library in you own package, see
     54 [[*Using With-Editor as a library]].
     55 
     56 ** Configuring With-Editor
     57 
     58 With-Editor tries very hard to locate a suitable ~emacsclient~
     59 executable, so ideally you should never have to customize the option
     60 ~with-editor-emacsclient-executable~.  When it fails to do so, then the
     61 most likely reason is that someone found yet another way to package
     62 Emacs (most likely on macOS) without putting the executable on ~$PATH~,
     63 and we have to add another kludge to find it anyway.
     64 
     65 - User Option: with-editor-emacsclient-executable ::
     66 
     67   The ~emacsclient~ executable used as the editor by child process of
     68   this Emacs instance.  By using this executable, child processes can
     69   call home to their parent process.
     70 
     71   This option is automatically set at startup by looking in ~exec-path~,
     72   and other places where the executable could be installed, to find
     73   the ~emacsclient~ executable most suitable for the current Emacs
     74   instance.
     75 
     76   You should *not* customize this option permanently.  If you have to do
     77   it, then you should consider that a temporary kludge and inform the
     78   Magit maintainer as described in [[*Debugging][Debugging]].
     79 
     80   If With-Editor fails to find a suitable ~emacsclient~ on you system,
     81   then this should be fixed for all users at once, by teaching
     82   ~with-editor-locate-emacsclient~ how to do so on your system and
     83   system like yours. Doing it this way has the advantage, that you
     84   won't have do it again every time you update Emacs, and that other
     85   users who have installed Emacs the same way as you have, won't have
     86   to go through the same trouble.
     87 
     88   Note that there also is a nuclear option; setting this variable to
     89   ~nil~ causes the "sleeping editor" described below to be used even for
     90   local child processes.  Obviously we don't recommend that you use
     91   this except in "emergencies", i.e. before we had a change to add a
     92   kludge appropriate for you setup.
     93 
     94 - Function: with-editor-locate-emacsclient ::
     95 
     96   The function used to set the initial value of the option
     97   ~with-editor-emacsclient-executable~.  There's a lot of voodoo here.
     98 
     99 The ~emacsclient~ cannot be used when using Tramp to run a process on a
    100 remote machine.  (Theoretically it could, but that would be hard to
    101 setup, very fragile, and rather insecure).
    102 
    103 With-Editor provides an alternative "editor" which can be used by
    104 remote processes in much the same way as local processes use an
    105 ~emacsclient~ executable.  This alternative is known as the "sleeping
    106 editor" because it is implemented as a shell script which sleeps until
    107 it receives a signal.
    108 
    109 - User Option: with-editor-sleeping-editor ::
    110 
    111   The sleeping editor is a shell script used as the editor of child
    112   processes when the ~emacsclient~ executable cannot be used.
    113 
    114   This fallback is used for asynchronous process started inside the
    115   macro ~with-editor~, when the process runs on a remote machine or for
    116   local processes when ~with-editor-emacsclient-executable~ is ~nil~.
    117 
    118   Where the latter uses a socket to communicate with Emacs' server,
    119   this substitute prints edit requests to its standard output on
    120   which a process filter listens for such requests.  As such it is
    121   not a complete substitute for a proper ~emacsclient~, it can only
    122   be used as ~$EDITOR~ of child process of the current Emacs instance.
    123 
    124   Some shells do not execute traps immediately when waiting for a
    125   child process, but by default we do use such a blocking child
    126   process.
    127 
    128   If you use such a shell (e.g. ~csh~ on FreeBSD, but not Debian), then
    129   you have to edit this option.  You can either replace ~sh~ with ~bash~
    130   (and install that), or you can use the older, less performant
    131   implementation:
    132 
    133   #+BEGIN_SRC emacs-lisp
    134     "sh -c '\
    135     echo \"WITH-EDITOR: $$ OPEN $0 IN $(pwd)\"; \
    136     trap \"exit 0\" USR1; \
    137     trap \"exit 1\" USR2; \
    138     while true; do sleep 1; done'"
    139   #+END_SRC
    140 
    141   Note that the unit separator character () right after the file
    142   name ($0) is required.
    143 
    144   Also note that using this alternative implementation leads to a
    145   delay of up to a second.  The delay can be shortened by replacing
    146   ~sleep 1~ with ~sleep 0.01~, or if your implementation does not support
    147   floats, then by using ~nanosleep~ instead.
    148 
    149 ** Using With-Editor commands
    150 
    151 This section describes how to use the ~with-editor~ library /outside/ of
    152 Magit.  You don't need to know any of this just to create commits
    153 using Magit.
    154 
    155 The commands ~with-editor-async-shell-command~ and
    156 ~with-editor-shell-command~ are intended as drop in replacements for
    157 ~async-shell-command~ and ~shell-command~.  They automatically export
    158 ~$EDITOR~ making sure the executed command uses the current Emacs
    159 instance as "the editor".  With a prefix argument these commands
    160 prompt for an alternative environment variable such as ~$GIT_EDITOR~.
    161 
    162 - Command: with-editor-async-shell-command ::
    163 
    164   This command is like ~async-shell-command~, but it runs the shell
    165   command with the current Emacs instance exported as ~$EDITOR~.
    166 
    167 - Command: with-editor-shell-command ::
    168 
    169   This command is like ~shell-command~, but if the shell command ends
    170   with ~&~ and is therefore run asynchronously, then the current Emacs
    171   instance is exported as ~$EDITOR~.
    172 
    173 To always use these variants add this to you init file:
    174 
    175 #+begin_src emacs-lisp
    176   (define-key (current-global-map)
    177     [remap async-shell-command] 'with-editor-async-shell-command)
    178   (define-key (current-global-map)
    179     [remap shell-command] 'with-editor-shell-command)
    180 #+end_src
    181 
    182 Alternatively use the global ~shell-command-with-editor-mode~.
    183 
    184 - Variable: shell-command-with-editor-mode ::
    185 
    186   When this mode is active, then ~$EDITOR~ is exported whenever
    187   ultimately ~shell-command~ is called to asynchronously run some shell
    188   command.  This affects most variants of that command, whether they
    189   are defined in Emacs or in some third-party package.
    190 
    191 The command ~with-editor-export-editor~ exports ~$EDITOR~ or another
    192 such environment variable in ~shell-mode~, ~eshell-mode~, ~term-mode~ and
    193 ~vterm-mode~ buffers.  Use this Emacs command before executing a shell
    194 command which needs the editor set, or always arrange for the current
    195 Emacs instance to be used as editor by adding it to the appropriate
    196 mode hooks:
    197 
    198 #+begin_src emacs-lisp
    199   (add-hook 'shell-mode-hook  'with-editor-export-editor)
    200   (add-hook 'eshell-mode-hook 'with-editor-export-editor)
    201   (add-hook 'term-exec-hook   'with-editor-export-editor)
    202   (add-hook 'vterm-exec-hook  'with-editor-export-editor)
    203 #+end_src
    204 
    205 Some variants of this function exist; these two forms are equivalent:
    206 
    207 #+begin_src emacs-lisp
    208   (add-hook 'shell-mode-hook
    209             (apply-partially 'with-editor-export-editor "GIT_EDITOR"))
    210   (add-hook 'shell-mode-hook 'with-editor-export-git-editor)
    211 #+end_src
    212 
    213 - Command: with-editor-export-editor ::
    214 
    215   When invoked in a ~shell-mode~, ~eshell-mode~, ~term-mode~ or ~vterm-mode~
    216   buffer, this command teaches shell commands to use the current Emacs
    217   instance as the editor, by exporting ~$EDITOR~.
    218 
    219 - Command: with-editor-export-git-editor ::
    220 
    221   This command is like ~with-editor-export-editor~ but exports
    222   ~$GIT_EDITOR~.
    223 
    224 - Command: with-editor-export-hg-editor ::
    225 
    226   This command is like ~with-editor-export-editor~ but exports
    227   ~$HG_EDITOR~.
    228 
    229 * Using With-Editor as a library
    230 
    231 This section describes how to use the ~with-editor~ library /outside/ of
    232 Magit to teach another package how to have its child processes call
    233 home, just like Magit does.  You don't need to know any of this just
    234 to create commits using Magit.  You can also ignore this if you use
    235 ~with-editor~ outside of Magit, but only as an end-user.
    236 
    237 For information about interactive use and options that affect both
    238 interactive and non-interactive use, see [[*Using the With-Editor
    239 package]].
    240 
    241 - Macro: with-editor &rest body ::
    242 
    243   This macro arranges for the ~emacsclient~ or the sleeping editor to be
    244   used as the editor of child processes, effectively teaching them to
    245   call home to the current Emacs instance when they require that the
    246   user edits a file.
    247 
    248   This is done by establishing a local binding for ~process-environment~
    249   and changing the value of the ~EDITOR~ environment variable in that
    250   scope.  This affects all (asynchronous) processes started by forms
    251   (dynamically) inside BODY.
    252 
    253   If BODY begins with a literal string, then that variable is set
    254   instead of ~EDITOR~.
    255 
    256 - Macro: with-editor envvar &rest body ::
    257 
    258   This macro is like ~with-editor~ instead that the ENVVAR argument is
    259   required and that it is evaluated at run-time.
    260 
    261 - Function: with-editor-set-process-filter process filter ::
    262 
    263   This function is like ~set-process-filter~ but ensures that adding the
    264   new FILTER does not remove the ~with-editor-process-filter~.  This is
    265   done by wrapping the two filter functions using a lambda, which
    266   becomes the actual filter.  It calls FILTER first, which may or
    267   may not insert the text into the PROCESS's buffer.  Then it calls
    268   ~with-editor-process-filter~, passing t as NO-STANDARD-FILTER.
    269 
    270 * Debugging
    271 
    272 With-Editor tries very hard to locate a suitable ~emacsclient~
    273 executable, and then sets option ~with-editor-emacsclient-executable~
    274 accordingly.  In very rare cases this fails.  When it does fail, then
    275 the most likely reason is that someone found yet another way to
    276 package Emacs (most likely on macOS) without putting the executable on
    277 ~$PATH~, and we have to add another kludge to find it anyway.
    278 
    279 If you are having problems using ~with-editor~, e.g. you cannot commit
    280 in Magit, then please open a new issue at
    281 https://github.com/magit/with-editor/issues and provide information
    282 about your Emacs installation.  Most importantly how did you install
    283 Emacs and what is the output of ~M-x with-editor-debug RET~.
    284 
    285 * Function and Command Index
    286 :PROPERTIES:
    287 :APPENDIX:   t
    288 :INDEX:      fn
    289 :END:
    290 * Variable Index
    291 :PROPERTIES:
    292 :APPENDIX:   t
    293 :INDEX:      vr
    294 :END:
    295 * Copying
    296 :PROPERTIES:
    297 :COPYING:    t
    298 :END:
    299 
    300 #+begin_quote
    301 Copyright (C) 2015-{{{year}}} Jonas Bernoulli <jonas@bernoul.li>
    302 
    303 You can redistribute this document and/or modify it under the terms
    304 of the GNU General Public License as published by the Free Software
    305 Foundation, either version 3 of the License, or (at your option) any
    306 later version.
    307 
    308 This document is distributed in the hope that it will be useful,
    309 but WITHOUT ANY WARRANTY; without even the implied warranty of
    310 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    311 General Public License for more details.
    312 #+end_quote
    313 
    314 # LocalWords: LocalWords
    315 # LocalWords: Magit Emacs emacsclient FreeBSD macOS texinfo
    316 # LocalWords: async eval hg init performant rebase startup
    317 
    318 # IMPORTANT: Also update ORG_ARGS and ORG_EVAL in the Makefile.
    319 # Local Variables:
    320 # eval: (require 'magit-utils nil t)
    321 # indent-tabs-mode: nil
    322 # org-src-preserve-indentation: nil
    323 # End: