From: Andreas Gerler Date: Tue, 22 Jan 2019 14:12:10 +0000 (+0100) Subject: Update with-editor. X-Git-Url: http://git.bundesbrandschatzamt.de/?a=commitdiff_plain;h=8edd7fe54e8ae7cd58697f7b0f2aef7b89b10df7;p=emacsconfig.git Update with-editor. Signed-off-by: Andreas Gerler --- diff --git a/elpa/with-editor-20160117.1513/dir b/elpa/with-editor-20160117.1513/dir deleted file mode 100644 index 93a7ef74..00000000 --- a/elpa/with-editor-20160117.1513/dir +++ /dev/null @@ -1,18 +0,0 @@ -This is the file .../info/dir, which contains the -topmost node of the Info hierarchy, called (dir)Top. -The first time you invoke Info you start off looking at this node. - -File: dir, Node: Top This is the top of the INFO tree - - This (the Directory node) gives a menu of major topics. - Typing "q" exits, "?" lists all Info commands, "d" returns here, - "h" gives a primer for first-timers, - "mEmacs" visits the Emacs manual, etc. - - In Emacs, you can click mouse button 2 on a menu item or cross reference - to select it. - -* Menu: - -Emacs -* With-Editor: (with-editor). Using the Emacsclient as $EDITOR. diff --git a/elpa/with-editor-20160117.1513/with-editor-autoloads.el b/elpa/with-editor-20160117.1513/with-editor-autoloads.el deleted file mode 100644 index fa01582c..00000000 --- a/elpa/with-editor-20160117.1513/with-editor-autoloads.el +++ /dev/null @@ -1,16 +0,0 @@ -;;; with-editor-autoloads.el --- automatically extracted autoloads -;; -;;; Code: -(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) - -;;;### (autoloads nil nil ("with-editor-pkg.el" "with-editor.el") -;;;;;; (22173 11883 665867 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; with-editor-autoloads.el ends here diff --git a/elpa/with-editor-20160117.1513/with-editor-pkg.el b/elpa/with-editor-20160117.1513/with-editor-pkg.el deleted file mode 100644 index a8a94245..00000000 --- a/elpa/with-editor-20160117.1513/with-editor-pkg.el +++ /dev/null @@ -1,9 +0,0 @@ -(define-package "with-editor" "20160117.1513" "Use the Emacsclient as $EDITOR" - '((emacs "24.4") - (async "20150909.2257") - (dash "20151021.113")) - :url "https://github.com/magit/magit" :keywords - '("tools")) -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/elpa/with-editor-20160117.1513/with-editor.el b/elpa/with-editor-20160117.1513/with-editor.el deleted file mode 100644 index fac092cd..00000000 --- a/elpa/with-editor-20160117.1513/with-editor.el +++ /dev/null @@ -1,724 +0,0 @@ -;;; with-editor.el --- Use the Emacsclient as $EDITOR -*- lexical-binding: t -*- - -;; Copyright (C) 2014-2016 The Magit Project Contributors -;; -;; You should have received a copy of the AUTHORS.md file which -;; lists all contributors. If not, see http://magit.vc/authors. - -;; Author: Jonas Bernoulli -;; Maintainer: Jonas Bernoulli - -;; Package-Requires: ((emacs "24.4") (async "20150909.2257") (dash "20151021.113")) -;; Keywords: tools -;; Homepage: https://github.com/magit/magit - -;; This file is not part of GNU Emacs. - -;; This file is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. - -;; This file 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. - -;; You should have received a copy of the GNU General Public License -;; along with this file. If not, see . - -;;; Commentary: - -;; Use the Emacsclient as `$EDITOR' of child processes, making sure -;; they know how to call home. For remote processes a substitute is -;; provided, which communicates with Emacs on stdout instead of using -;; a socket as the Emacsclient does. - -;; The commands `with-editor-async-shell-command' and -;; `with-editor-shell-command' are intended as drop in replacements -;; for `async-shell-command' and `shell-command'. They automatically -;; export `$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 -;; `$GIT_EDITOR'. To always use these variants add this to your init -;; file: -;; -;; (define-key (current-global-map) -;; [remap async-shell-command] 'with-editor-async-shell-command) -;; (define-key (current-global-map) -;; [remap shell-command] 'with-editor-shell-command) - -;; Alternatively use the global `shell-command-with-editor-mode', -;; which always sets `$EDITOR' for all Emacs commands which ultimately -;; use `shell-command' to asynchronously run some shell command. - -;; The command `with-editor-export-editor' exports `$EDITOR' or -;; another such environment variable in `shell-mode', `term-mode' and -;; `eshell-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: -;; -;; (add-hook 'shell-mode-hook 'with-editor-export-editor) -;; (add-hook 'term-mode-hook 'with-editor-export-editor) -;; (add-hook 'eshell-mode-hook 'with-editor-export-editor) - -;; Some variants of this function exist, these two forms are -;; equivalent: -;; -;; (add-hook 'shell-mode-hook -;; (apply-partially 'with-editor-export-editor "GIT_EDITOR")) -;; (add-hook 'shell-mode-hook 'with-editor-export-git-editor) - -;; This library can also be used by other packages which need to use -;; the current Emacs instance as editor. In fact this library was -;; written for Magit and its `git-commit-mode' and `git-rebase-mode'. -;; Consult `git-rebase.el' and the related code in `magit-sequence.el' -;; for a simple example. - -;;; Code: - -(require 'cl-lib) -(require 'dash) -(require 'server) -(require 'tramp) -(require 'tramp-sh nil t) - -(and (require 'async-bytecomp nil t) - (memq 'magit (bound-and-true-p async-bytecomp-allowed-packages)) - (fboundp 'async-bytecomp-package-mode) - (async-bytecomp-package-mode 1)) - -(eval-when-compile - (progn (require 'dired nil t) - (require 'eshell nil t) - (require 'term nil t) - (require 'warnings nil t))) -(declare-function dired-get-filename 'dired) -(declare-function term-emulate-terminal 'term) -(defvar eshell-preoutput-filter-functions) - -;;; Options - -(defgroup with-editor nil - "Use the Emacsclient as $EDITOR." - :group 'external - :group 'server) - -(defun with-editor-locate-emacsclient () - "Search for a suitable Emacsclient executable." - (--if-let (with-editor-locate-emacsclient-1 (with-editor-emacsclient-path) 3) - it - (display-warning 'with-editor (format "\ -Cannot determine a suitable Emacsclient - -Determining an Emacsclient executable suitable for the -current Emacs instance failed. For more information -please see https://github.com/magit/magit/wiki/Emacsclient.")) - nil)) - -(defun with-editor-locate-emacsclient-1 (path depth) - (let* ((version-lst (-take depth (split-string emacs-version "\\."))) - (version-reg (concat "^" (mapconcat #'identity version-lst "\\.")))) - (or (locate-file-internal - "emacsclient" path - (cl-mapcan - (lambda (v) (cl-mapcar (lambda (e) (concat v e)) exec-suffixes)) - (nconc (cl-mapcon (lambda (v) - (setq v (mapconcat #'identity (reverse v) ".")) - (list v (concat "-" v) (concat ".emacs" v))) - (reverse version-lst)) - (list "" "emacsclient-snapshot"))) - (lambda (exec) - (ignore-errors - (string-match-p version-reg - (with-editor-emacsclient-version exec))))) - (and (> depth 1) - (with-editor-locate-emacsclient-1 path (1- depth)))))) - -(defun with-editor-emacsclient-version (exec) - (-when-let (1st-line (car (process-lines exec "--version"))) - (cadr (split-string 1st-line)))) - -(defun with-editor-emacsclient-path () - (let ((path exec-path)) - (when invocation-directory - (push (directory-file-name invocation-directory) path) - (let* ((linkname (expand-file-name invocation-name invocation-directory)) - (truename (file-chase-links linkname))) - (unless (equal truename linkname) - (push (directory-file-name (file-name-directory truename)) path))) - (when (eq system-type 'darwin) - (let ((dir (expand-file-name "bin" invocation-directory))) - (when (file-directory-p dir) - (push dir path))) - (when (string-match-p "Cellar" invocation-directory) - (let ((dir (expand-file-name "../../../bin" invocation-directory))) - (when (file-directory-p dir) - (push dir path)))))) - (cl-remove-duplicates path :test 'equal))) - -(defcustom with-editor-emacsclient-executable (with-editor-locate-emacsclient) - "The Emacsclient executable used by the `with-editor' macro." - :group 'with-editor - :type '(choice (string :tag "Executable") - (const :tag "Don't use Emacsclient" nil))) - -(defcustom with-editor-sleeping-editor "\ -sh -c '\ -echo \"WITH-EDITOR: $$ OPEN $0\"; \ -sleep 604800 & sleep=$!; \ -trap \"kill $sleep; exit 0\" USR1; \ -trap \"kill $sleep; exit 1\" USR2; \ -wait $sleep'" - "The sleeping editor, used when the Emacsclient cannot be used. - -This fallback is used for asynchronous process started inside the -macro `with-editor', when the process runs on a remote machine or -for local processes when `with-editor-emacsclient-executable' is -nil (i.e. when no suitable Emacsclient was found, or the user -decided not to use it). - -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 Emacsclient, it can only -be used as $EDITOR of child process of the current Emacs instance." - :group 'with-editor - :type 'string) - -(defcustom with-editor-finish-query-functions nil - "List of functions called to query before finishing session. - -The buffer in question is current while the functions are called. -If any of them returns nil, then the session is not finished and -the buffer is not killed. The user should then fix the issue and -try again. The functions are called with one argument. If it is -non-nil then that indicates that the user used a prefix argument -to force finishing the session despite issues. Functions should -usually honor that and return non-nil." - :group 'with-editor - :type 'hook) -(put 'with-editor-finish-query-functions 'permanent-local t) - -(defcustom with-editor-cancel-query-functions nil - "List of functions called to query before canceling session. - -The buffer in question is current while the functions are called. -If any of them returns nil, then the session is not canceled and -the buffer is not killed. The user should then fix the issue and -try again. The functions are called with one argument. If it is -non-nil then that indicates that the user used a prefix argument -to force canceling the session despite issues. Functions should -usually honor that and return non-nil." - :group 'with-editor - :type 'hook) -(put 'with-editor-cancel-query-functions 'permanent-local t) - -(defcustom with-editor-mode-lighter " WE" - "The mode-line lighter of the With-Editor mode." - :group 'with-editor - :type '(choice (const :tag "No lighter" "") string)) - -(defvar with-editor-server-window-alist nil - "Alist of filename patterns vs corresponding `server-window'. - -Each element looks like (REGEXP . FUNCTION). Files matching -REGEXP are selected using FUNCTION instead of the default in -`server-window'. - -Note that when a package adds an entry here then it probably -has a reason to disrespect `server-window' and it likely is -not a good idea to change such entries.") - -;;; Mode Commands - -(defvar with-editor-pre-finish-hook nil) -(defvar with-editor-pre-cancel-hook nil) -(defvar with-editor-post-finish-hook nil) -(defvar with-editor-post-finish-hook-1 nil) -(defvar with-editor-post-cancel-hook nil) -(defvar with-editor-post-cancel-hook-1 nil) -(defvar with-editor-cancel-alist nil) -(put 'with-editor-pre-finish-hook 'permanent-local t) -(put 'with-editor-pre-cancel-hook 'permanent-local t) -(put 'with-editor-post-finish-hook 'permanent-local t) -(put 'with-editor-post-cancel-hook 'permanent-local t) - -(defvar with-editor-show-usage t) -(defvar with-editor-cancel-message nil) -(defvar with-editor-previous-winconf nil) -(make-variable-buffer-local 'with-editor-show-usage) -(make-variable-buffer-local 'with-editor-cancel-message) -(make-variable-buffer-local 'with-editor-previous-winconf) -(put 'with-editor-cancel-message 'permanent-local t) -(put 'with-editor-previous-winconf 'permanent-local t) - -(defvar-local with-editor--pid nil "For internal use.") -(put 'with-editor--pid 'permanent-local t) - -(defun with-editor-finish (force) - "Finish the current edit session." - (interactive "P") - (when (run-hook-with-args-until-failure - 'with-editor-finish-query-functions force) - (let ((with-editor-post-finish-hook-1 - (ignore-errors (delq t with-editor-post-finish-hook)))) - (run-hooks 'with-editor-pre-finish-hook) - (with-editor-return nil) - (accept-process-output nil 0.1) - (run-hooks 'with-editor-post-finish-hook-1)))) - -(defun with-editor-cancel (force) - "Cancel the current edit session." - (interactive "P") - (when (run-hook-with-args-until-failure - 'with-editor-cancel-query-functions force) - (let ((message with-editor-cancel-message)) - (when (functionp message) - (setq message (funcall message))) - (let ((with-editor-post-cancel-hook-1 - (ignore-errors (delq t with-editor-post-cancel-hook))) - (with-editor-cancel-alist nil)) - (run-hooks 'with-editor-pre-cancel-hook) - (with-editor-return t) - (accept-process-output nil 0.1) - (run-hooks 'with-editor-post-cancel-hook-1)) - (message (or message "Canceled by user"))))) - -(defun with-editor-return (cancel) - (let ((winconf with-editor-previous-winconf) - (clients server-buffer-clients) - (dir default-directory) - (pid with-editor--pid)) - (remove-hook 'kill-buffer-query-functions - 'with-editor-kill-buffer-noop t) - (cond (cancel - (save-buffer) - (if clients - (dolist (client clients) - (ignore-errors - (server-send-string client "-error Canceled by user")) - (delete-process client)) - ;; Fallback for when emacs was used as $EDITOR instead - ;; of emacsclient or the sleeping editor. See #2258. - (ignore-errors (delete-file buffer-file-name)) - (kill-buffer))) - (t - (save-buffer) - (if clients - ;; Don't use `server-edit' because we do not want to show - ;; another buffer belonging to another client. See #2197. - (server-done) - (kill-buffer)))) - (when pid - (let ((default-directory dir)) - (process-file "kill" nil nil nil - "-s" (if cancel "USR2" "USR1") pid))) - (when (and winconf (eq (window-configuration-frame winconf) - (selected-frame))) - (set-window-configuration winconf)))) - -;;; Mode - -(defvar with-editor-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-c" 'with-editor-finish) - (define-key map [remap server-edit] 'with-editor-finish) - (define-key map "\C-c\C-k" 'with-editor-cancel) - (define-key map [remap kill-buffer] 'with-editor-cancel) - (define-key map [remap ido-kill-buffer] 'with-editor-cancel) - (define-key map [remap iswitchb-kill-buffer] 'with-editor-cancel) - map)) - -(define-minor-mode with-editor-mode - "Edit a file as the $EDITOR of an external process." - :lighter with-editor-mode-lighter - ;; Protect the user from killing the buffer without using - ;; either `with-editor-finish' or `with-editor-cancel', - ;; and from removing the key bindings for these commands. - (unless with-editor-mode - (error "With-Editor mode cannot be turned off")) - (add-hook 'kill-buffer-query-functions - 'with-editor-kill-buffer-noop nil t) - ;; `server-execute' displays a message which is not - ;; correct when using this mode. - (when with-editor-show-usage - (with-editor-usage-message))) - -(put 'with-editor-mode 'permanent-local t) - -(defun with-editor-kill-buffer-noop () - (message (substitute-command-keys "\ -Don't kill this buffer. Instead cancel using \\[with-editor-cancel]"))) - -(defun with-editor-usage-message () - ;; Run after `server-execute', which is run using - ;; a timer which starts immediately. - (run-with-timer - 0.01 nil `(lambda () - (with-current-buffer ,(current-buffer) - (message (substitute-command-keys "\ -Type \\[with-editor-finish] to finish, \ -or \\[with-editor-cancel] to cancel")))))) - -;;; Wrappers - -(defvar with-editor--envvar nil "For internal use.") - -(defmacro with-editor (&rest body) - "Use the Emacsclient as $EDITOR while evaluating BODY. -Modify the `process-environment' for processes started in BODY, -instructing them to use the Emacsclient as $EDITOR. If optional -ENVVAR is provided then bind that environment variable instead. -\n(fn [ENVVAR] BODY...)" - (declare (indent defun) (debug (body))) - `(let ((with-editor--envvar ,(if (stringp (car body)) - (pop body) - '(or with-editor--envvar "EDITOR"))) - (process-environment process-environment)) - (if (or (not with-editor-emacsclient-executable) - (file-remote-p default-directory)) - (setenv with-editor--envvar with-editor-sleeping-editor) - ;; Make sure server-use-tcp's value is valid. - (unless (featurep 'make-network-process '(:family local)) - (setq server-use-tcp t)) - ;; Make sure the server is running. - (unless server-process - (when (server-running-p server-name) - (setq server-name (format "server%s" (emacs-pid))) - (when (server-running-p server-name) - (server-force-delete server-name))) - (server-start)) - ;; Tell $EDITOR to use the Emacsclient. - (setenv with-editor--envvar - (concat (shell-quote-argument with-editor-emacsclient-executable) - ;; Tell the process where the server file is. - (and (not server-use-tcp) - (concat " --socket-name=" - (shell-quote-argument - (expand-file-name server-name - server-socket-dir)))))) - (when server-use-tcp - (setenv "EMACS_SERVER_FILE" - (expand-file-name server-name server-auth-dir))) - ;; As last resort fallback to the sleeping editor. - (setenv "ALTERNATE_EDITOR" with-editor-sleeping-editor)) - ,@body)) - -(defun with-editor-server-window () - (or (and buffer-file-name - (cdr (--first (string-match-p (car it) buffer-file-name) - with-editor-server-window-alist))) - server-window)) - -(defun server-switch-buffer--with-editor-server-window-alist - (fn &optional next-buffer killed-one filepos) - "Honor `with-editor-server-window-alist' (which see)." - (let ((server-window (with-current-buffer - (or next-buffer (current-buffer)) - (when with-editor-mode - (setq with-editor-previous-winconf - (current-window-configuration))) - (with-editor-server-window)))) - (funcall fn next-buffer killed-one filepos))) - -(advice-add 'server-switch-buffer :around - 'server-switch-buffer--with-editor-server-window-alist) - -(defun start-file-process--with-editor-process-filter - (fn name buffer program &rest program-args) - "When called inside a `with-editor' form and the Emacsclient -cannot be used, then give the process the filter function -`with-editor-process-filter'. To avoid overriding the filter -being added here you should use `with-editor-set-process-filter' -instead of `set-process-filter' inside `with-editor' forms. - -When the `default-directory' is located on a remote machine, -then also manipulate PROGRAM and PROGRAM-ARGS in order to set -the appropriate editor environment variable." - (if (not with-editor--envvar) - (apply fn name buffer program program-args) - (when (file-remote-p default-directory) - (unless (equal program "env") - (push program program-args) - (setq program "env")) - (push (concat with-editor--envvar "=" with-editor-sleeping-editor) - program-args)) - (let ((process (apply fn name buffer program program-args))) - (set-process-filter process 'with-editor-process-filter) - (process-put process 'default-dir default-directory) - process))) - -(advice-add 'start-file-process :around - 'start-file-process--with-editor-process-filter) - -(defun with-editor-set-process-filter (process filter) - "Like `set-process-filter' but keep `with-editor-process-filter'. -Give PROCESS the new FILTER but keep `with-editor-process-filter' -if that was added earlier by the adviced `start-file-process'. - -Do so by wrapping the two filter functions using a lambda, which -becomes the actual filter. It calls `with-editor-process-filter' -first, passing t as NO-STANDARD-FILTER. Then it calls FILTER, -which may or may not insert the text into the PROCESS' buffer." - (set-process-filter - process - (if (eq (process-filter process) 'with-editor-process-filter) - `(lambda (proc str) - (,filter proc str) - (with-editor-process-filter proc str t)) - filter))) - -(defvar with-editor-filter-visit-hook nil) - -(defun with-editor-output-filter (string) - (save-match-data - (if (string-match "^WITH-EDITOR: \\([0-9]+\\) OPEN \\(.+?\\)\r?$" string) - (let ((pid (match-string 1 string)) - (file (match-string 2 string))) - (with-current-buffer - (find-file-noselect - (if (file-name-absolute-p file) - (if (tramp-tramp-file-p default-directory) - (with-parsed-tramp-file-name default-directory nil - (tramp-make-tramp-file-name method user host file hop)) - file) - (expand-file-name file))) - (with-editor-mode 1) - (setq with-editor--pid pid) - (run-hooks 'with-editor-filter-visit-hook) - (funcall (or (with-editor-server-window) 'switch-to-buffer) - (current-buffer)) - (kill-local-variable 'server-window)) - nil) - string))) - -(defun with-editor-process-filter - (process string &optional no-default-filter) - "Listen for edit requests by child processes." - (let ((default-directory (process-get process 'default-dir))) - (with-editor-output-filter string)) - (unless no-default-filter - (internal-default-process-filter process string))) - -;;; Augmentations - -(cl-defun with-editor-export-editor (&optional (envvar "EDITOR")) - "Teach subsequent commands to use current Emacs instance as editor. - -Set and export the environment variable ENVVAR, by default -\"EDITOR\". The value is automatically generated to teach -commands use the current Emacs instance as \"the editor\". - -This works in `shell-mode', `term-mode' and `eshell-mode'." - (interactive (list (with-editor-read-envvar))) - (cond - ((derived-mode-p 'comint-mode 'term-mode) - (let* ((process (get-buffer-process (current-buffer))) - (filter (process-filter process))) - (set-process-filter process 'ignore) - (goto-char (process-mark process)) - (process-send-string - process (format "export %s=%s\n" envvar - (shell-quote-argument with-editor-sleeping-editor))) - (while (accept-process-output process 0.1)) - (set-process-filter process filter) - (if (derived-mode-p 'term-mode) - (with-editor-set-process-filter process 'with-editor-emulate-terminal) - (add-hook 'comint-output-filter-functions 'with-editor-output-filter - nil t)))) - ((derived-mode-p 'eshell-mode) - (add-to-list 'eshell-preoutput-filter-functions - 'with-editor-output-filter) - (setenv envvar with-editor-sleeping-editor)) - (t - (error "Cannot export environment variables in this buffer"))) - (message "Successfully exported %s" envvar)) - -(defun with-editor-export-git-editor () - "Like `with-editor-export-editor' but always set `$GIT_EDITOR'." - (interactive) - (with-editor-export-editor "GIT_EDITOR")) - -(defun with-editor-export-hg-editor () - "Like `with-editor-export-editor' but always set `$HG_EDITOR'." - (interactive) - (with-editor-export-editor "HG_EDITOR")) - -(defun with-editor-emulate-terminal (process string) - "Like `term-emulate-terminal' but also handle edit requests." - (when (with-editor-output-filter string) - (term-emulate-terminal process string))) - -(defvar with-editor-envvars '("EDITOR" "GIT_EDITOR" "HG_EDITOR")) - -(cl-defun with-editor-read-envvar - (&optional (prompt "Set environment variable") - (default "EDITOR")) - (let ((reply (completing-read (if default - (format "%s (%s): " prompt default) - (concat prompt ": ")) - with-editor-envvars nil nil nil nil default))) - (if (string= reply "") (user-error "Nothing selected") reply))) - -(define-minor-mode shell-command-with-editor-mode - "Teach `shell-command' to use current Emacs instance as editor. - -Teach `shell-command', and all commands that ultimately call that -command, to use the current Emacs instance as editor by executing -\"EDITOR=CLIENT COMMAND&\" instead of just \"COMMAND&\". - -CLIENT is automatically generated; EDITOR=CLIENT instructs -COMMAND to use to the current Emacs instance as \"the editor\", -assuming no other variable overrides the effect of \"$EDITOR\". -CLIENT may be the path to an appropriate emacsclient executable -with arguments, or a script which also works over Tramp. - -Alternatively you can use the `with-editor-async-shell-command', -which also allows the use of another variable instead of -\"EDITOR\"." - :global t) - -(defun with-editor-async-shell-command - (command &optional output-buffer error-buffer envvar) - "Like `async-shell-command' but with `$EDITOR' set. - -Execute string \"ENVVAR=CLIENT COMMAND\" in an inferior shell; -display output, if any. With a prefix argument prompt for an -environment variable, otherwise the default \"EDITOR\" variable -is used. With a negative prefix argument additionally insert -the COMMAND's output at point. - -CLIENT is automatically generated; ENVVAR=CLIENT instructs -COMMAND to use to the current Emacs instance as \"the editor\", -assuming it respects ENVVAR as an \"EDITOR\"-like variable. -CLIENT maybe the path to an appropriate emacsclient executable -with arguments, or a script which also works over Tramp. - -Also see `async-shell-command' and `shell-command'." - (interactive (with-editor-shell-command-read-args "Async shell command: " t)) - (let ((with-editor--envvar envvar)) - (with-editor - (async-shell-command command output-buffer error-buffer)))) - -(defun with-editor-shell-command - (command &optional output-buffer error-buffer envvar) - "Like `shell-command' or `with-editor-async-shell-command'. -If COMMAND ends with \"&\" behave like the latter, -else like the former." - (interactive (with-editor-shell-command-read-args "Shell command: ")) - (if (string-match "&[ \t]*\\'" command) - (with-editor-async-shell-command - command output-buffer error-buffer envvar) - (shell-command command output-buffer error-buffer))) - -(defun with-editor-shell-command-read-args (prompt &optional async) - (let ((command (read-shell-command - prompt nil nil - (--when-let (or buffer-file-name - (and (eq major-mode 'dired-mode) - (dired-get-filename nil t))) - (file-relative-name it))))) - (list command - (if (or async (setq async (string-match-p "&[ \t]*\\'" command))) - (< (prefix-numeric-value current-prefix-arg) 0) - current-prefix-arg) - shell-command-default-error-buffer - (and async current-prefix-arg (with-editor-read-envvar))))) - -(defun shell-command--shell-command-with-editor-mode - (fn command &optional output-buffer error-buffer) - (cond ((or (not (or with-editor--envvar shell-command-with-editor-mode)) - (not (string-match-p "&\\'" command))) - (funcall fn command output-buffer error-buffer)) - ((and with-editor-emacsclient-executable - (not (file-remote-p default-directory))) - (with-editor (funcall fn command output-buffer error-buffer))) - (t - (apply fn (format "%s=%s %s" - (or with-editor--envvar "EDITOR") - (shell-quote-argument with-editor-sleeping-editor) - command) - output-buffer error-buffer) - (ignore-errors - (let ((process (get-buffer-process - (or output-buffer - (get-buffer "*Async Shell Command*"))))) - (set-process-filter - process (lambda (proc str) - (comint-output-filter proc str) - (with-editor-process-filter proc str t))) - process))))) - -(advice-add 'shell-command :around - 'shell-command--shell-command-with-editor-mode) - -;;; with-editor.el ends soon - -(defun with-editor-debug () - "Debug configuration issues. -See `with-editor.info' for instructions." - (interactive) - (with-current-buffer (get-buffer-create "*with-editor-debug*") - (pop-to-buffer (current-buffer)) - (erase-buffer) - (ignore-errors (with-editor)) - (insert - (format "with-editor: %s\n" (locate-library "with-editor.el")) - (format "emacs: %s (%s)\n" - (expand-file-name invocation-name invocation-directory) - emacs-version) - "system:\n" - (format " system-type: %s\n" system-type) - (format " system-configuration: %s\n" system-configuration) - (format " system-configuration-options: %s\n" system-configuration-options) - "server:\n" - (format " server-running-p: %s\n" (server-running-p)) - (format " server-process: %S\n" server-process) - (format " server-use-tcp: %s\n" server-use-tcp) - (format " server-name: %s\n" server-name) - (format " server-socket-dir: %s\n" server-socket-dir)) - (if (and server-socket-dir (file-accessible-directory-p server-socket-dir)) - (--each (directory-files server-socket-dir nil "^[^.]") - (insert (format " %s\n" it))) - (insert (format " %s: not an accessible directory\n" - (if server-use-tcp "WARNING" "ERROR")))) - (insert (format " server-auth-dir: %s\n" server-auth-dir)) - (if (file-accessible-directory-p server-auth-dir) - (--each (directory-files server-auth-dir nil "^[^.]") - (insert (format " %s\n" it))) - (insert (format " %s: not an accessible directory\n" - (if server-use-tcp "ERROR" "WARNING")))) - (let ((val with-editor-emacsclient-executable) - (def (default-value 'with-editor-emacsclient-executable)) - (fun (let ((warning-minimum-level :error) - (warning-minimum-log-level :error)) - (with-editor-locate-emacsclient)))) - (insert "magit-emacsclient-executable:\n" - (format " value: %s (%s)\n" val - (and val (with-editor-emacsclient-version val))) - (format " default: %s (%s)\n" def - (and def (with-editor-emacsclient-version def))) - (format " funcall: %s (%s)\n" fun - (and fun (with-editor-emacsclient-version fun))))) - (insert "path:\n" - (format " $PATH: %S\n" (getenv "PATH")) - (format " exec-path: %s\n" exec-path)) - (insert (format " with-editor-emacsclient-path:\n")) - (--each (with-editor-emacsclient-path) - (insert (format " %s (%s)\n" it (car (file-attributes it)))) - (when (file-directory-p it) - (dolist (exec (directory-files it t "emacsclient")) - (insert (format " %s (%s)\n" exec - (with-editor-emacsclient-version exec)))))))) - -(defconst with-editor-font-lock-keywords - '(("(\\(with-\\(?:git-\\)?editor\\)\\_>" (1 'font-lock-keyword-face)))) -(font-lock-add-keywords 'emacs-lisp-mode with-editor-font-lock-keywords) - -(provide 'with-editor) -;; Local Variables: -;; indent-tabs-mode: nil -;; End: -;;; with-editor.el ends here diff --git a/elpa/with-editor-20160117.1513/with-editor.info b/elpa/with-editor-20160117.1513/with-editor.info deleted file mode 100644 index 41419b99..00000000 --- a/elpa/with-editor-20160117.1513/with-editor.info +++ /dev/null @@ -1,323 +0,0 @@ -This is with-editor.info, produced by makeinfo version 5.2 from -with-editor.texi. - -The library ‘with-editor’ makes it easy to use the Emacsclient as the -‘$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. - - Copyright (C) 2015-2016 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. -INFO-DIR-SECTION Emacs -START-INFO-DIR-ENTRY -* With-Editor: (with-editor). Using the Emacsclient as $EDITOR. -END-INFO-DIR-ENTRY - - -File: with-editor.info, Node: Top, Next: Using the With-Editor package, Up: (dir) - -With-Editor User Manual -*********************** - -The library ‘with-editor’ makes it easy to use the Emacsclient as the -‘$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. - - Copyright (C) 2015-2016 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. - -* Menu: - -* Using the With-Editor package:: -* Using With-Editor as a library:: -* Debugging:: - -— The Detailed Node Listing — - -Using the With-Editor package - -* Configuring With-Editor:: -* Using With-Editor commands:: - - - -File: with-editor.info, Node: Using the With-Editor package, Next: Using With-Editor as a library, Prev: Top, Up: Top - -1 Using the With-Editor package -******************************* - -The ‘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 you own package, see -*note Using With-Editor as a library: Using With-Editor as a library. - -* Menu: - -* Configuring With-Editor:: -* Using With-Editor commands:: - - -File: with-editor.info, Node: Configuring With-Editor, Next: Using With-Editor commands, Up: Using the With-Editor package - -1.1 Configuring With-Editor -=========================== - -With-Editor tries very hard to locate a suitable emacsclient executable, -so ideally you should never have to customize the option -‘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 OS X) without putting the executable on ‘$PATH’, -and we have to add another kludge to find it anyway. - - -- User Option: with-editor-emacsclient-executable - - The emacsclient executable used as the editor by child process 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 - ‘exec-path’, and other places where the executable could be - installed, to find the emacsclient executable most suitable for the - current emacs instance. - - You should *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 *note Debugging: Debugging. - - If With-Editor fails to find a suitable emacsclient on you system, - then this should be fixed for all users at once, by teaching - ‘with-editor-locate-emacsclient’ how to so on your system and - system 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 - ‘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 you setup. - - -- Function: with-editor-locate-emacsclient - - The function used to set the initial value of the option - ‘with-editor-emacsclient-executable’. There’s a lot of voodoo - here. - - The 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 -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. - - -- User Option: with-editor-sleeping-editor - - The sleeping editor is a shell script used as the editor of child - processes when the emacsclient executable cannot be used. - - This fallback is used for asynchronous process started inside the - macro ‘with-editor’, when the process runs on a remote machine or - for local processes when ‘with-editor-emacsclient-executable’ is - ‘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 Emacsclient, it can only be - used as ‘$EDITOR’ of child process of the current Emacs instance. - - It is unlikely that you should ever have to customize this option. - - -File: with-editor.info, Node: Using With-Editor commands, Prev: Configuring With-Editor, Up: Using the With-Editor package - -1.2 Using With-Editor commands -============================== - -This section describes how to use the ‘with-editor’ library _outside_ of -Magit. You don’t need to know any of this just to create commits using -Magit. - - The commands ‘with-editor-async-shell-command’ and -‘with-editor-shell-command’ are intended as drop in replacements for -‘async-shell-command’ and ‘shell-command’. They automatically export -‘$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 ‘$GIT_EDITOR’. - - -- Command: with-editor-async-shell-command - - Like ‘async-shell-command’, but the command is run with the current - Emacs instance exported as ‘$EDITOR’. - - -- Command: with-editor-shell-command - - Like ‘async-shell-command’, but the command is run with the current - Emacs instance exported as ‘$EDITOR’. This only has an effect if - the command is run asynchronously, i.e. when the command ends with - ‘&’. - - To always use these variants add this to you init file: - - (define-key (current-global-map) - [remap async-shell-command] 'with-editor-async-shell-command) - (define-key (current-global-map) - [remap shell-command] 'with-editor-shell-command) - - Alternatively use the global ‘shell-command-with-editor-mode’. - - -- Variable: shell-command-with-editor-mode - - When this mode is active, then ‘$EDITOR’ is exported whenever - ultimately ‘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. - - The command ‘with-editor-export-editor’ exports ‘$EDITOR’ or another -such environment variable in ‘shell-mode’, ‘term-mode’ and ‘eshell-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: - - (add-hook 'shell-mode-hook 'with-editor-export-editor) - (add-hook 'term-mode-hook 'with-editor-export-editor) - (add-hook 'eshell-mode-hook 'with-editor-export-editor) - - Some variants of this function exist; these two forms are equivalent: - - (add-hook 'shell-mode-hook - (apply-partially 'with-editor-export-editor "GIT_EDITOR")) - (add-hook 'shell-mode-hook 'with-editor-export-git-editor) - - -- Command: with-editor-export-editor - - When invoked in a ‘shell-mode’, ‘term-mode’, or ‘eshell-mode’ - buffer, this command teaches shell commands to use the current - Emacs instance as the editor, by exporting ‘$EDITOR’. - - -- Command: with-editor-export-git-editor - - Like ‘with-editor-export-editor’ but exports ‘$GIT_EDITOR’. - - -- Command: with-editor-export-hg-editor - - Like ‘with-editor-export-editor’ but exports ‘$HG_EDITOR’. - - -File: with-editor.info, Node: Using With-Editor as a library, Next: Debugging, Prev: Using the With-Editor package, Up: Top - -2 Using With-Editor as a library -******************************** - -This section describes how to use the with-editor library _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 -‘with-editor’ outside of Magit, but only as an end-user. - - For information about interactive use and options which affect both -interactive and non-interactive use, see *note Using the With-Editor -package: Using the With-Editor package. - - -- Macro: with-editor &rest body - - This macro arranges for the 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 essentially done by establishing a local binding for - ‘process-environment’ and changing the value of the ‘$EDITOR’ - environment variable. This affects all processes started by forms - inside BODY. - - -- Function: with-editor-set-process-filter process filter - - This function is like ‘set-process-filter’ but ensures that adding - the new FILTER does not remove the ‘with-editor-process-filter’. - This is done by wrapping the two filter functions using a lambda, - which becomes the actual filter. It calls - ‘with-editor-process-filter’ first, passing ‘t’ as - NO-STANDARD-FILTER. Then it calls FILTER. - - -File: with-editor.info, Node: Debugging, Prev: Using With-Editor as a library, Up: Top - -3 Debugging -*********** - -With-Editor tries very hard to locate a suitable emacsclient executable, -and then sets option ‘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 OS X) without putting the executable on ‘$PATH’, and we have -to add another kludge to find it anyway. - - If you are having problems using ‘with-editor’, e.g. you cannot -commit in Magit, then please open a new issue at - and provide information about -your Emacs installation. Most importantly how did you install Emacs and -what is the output of ‘M-x with-editor-debug’? - - - -Tag Table: -Node: Top1545 -Node: Using the With-Editor package3237 -Node: Configuring With-Editor3853 -Node: Using With-Editor commands7460 -Node: Using With-Editor as a library10623 -Node: Debugging12295 - -End Tag Table - - -Local Variables: -coding: utf-8 -End: diff --git a/elpa/with-editor-20161109.403/dir b/elpa/with-editor-20161109.403/dir deleted file mode 100644 index 93a7ef74..00000000 --- a/elpa/with-editor-20161109.403/dir +++ /dev/null @@ -1,18 +0,0 @@ -This is the file .../info/dir, which contains the -topmost node of the Info hierarchy, called (dir)Top. -The first time you invoke Info you start off looking at this node. - -File: dir, Node: Top This is the top of the INFO tree - - This (the Directory node) gives a menu of major topics. - Typing "q" exits, "?" lists all Info commands, "d" returns here, - "h" gives a primer for first-timers, - "mEmacs" visits the Emacs manual, etc. - - In Emacs, you can click mouse button 2 on a menu item or cross reference - to select it. - -* Menu: - -Emacs -* With-Editor: (with-editor). Using the Emacsclient as $EDITOR. diff --git a/elpa/with-editor-20161109.403/with-editor-autoloads.el b/elpa/with-editor-20161109.403/with-editor-autoloads.el deleted file mode 100644 index 55e08577..00000000 --- a/elpa/with-editor-20161109.403/with-editor-autoloads.el +++ /dev/null @@ -1,16 +0,0 @@ -;;; with-editor-autoloads.el --- automatically extracted autoloads -;; -;;; Code: -(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path)))) - -;;;### (autoloads nil nil ("with-editor-pkg.el" "with-editor.el") -;;;;;; (22576 8240 0 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; with-editor-autoloads.el ends here diff --git a/elpa/with-editor-20161109.403/with-editor-pkg.el b/elpa/with-editor-20161109.403/with-editor-pkg.el deleted file mode 100644 index 34844b61..00000000 --- a/elpa/with-editor-20161109.403/with-editor-pkg.el +++ /dev/null @@ -1,9 +0,0 @@ -(define-package "with-editor" "20161109.403" "Use the Emacsclient as $EDITOR" - '((emacs "24.4") - (async "1.9") - (dash "2.13.0")) - :url "https://github.com/magit/with-editor" :keywords - '("tools")) -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/elpa/with-editor-20161109.403/with-editor.el b/elpa/with-editor-20161109.403/with-editor.el deleted file mode 100644 index 546c119f..00000000 --- a/elpa/with-editor-20161109.403/with-editor.el +++ /dev/null @@ -1,777 +0,0 @@ -;;; with-editor.el --- Use the Emacsclient as $EDITOR -*- lexical-binding: t -*- - -;; Copyright (C) 2014-2016 The Magit Project Contributors -;; -;; You should have received a copy of the AUTHORS.md file. If not, -;; see https://github.com/magit/with-editor/blob/master/AUTHORS.md. - -;; Author: Jonas Bernoulli -;; Maintainer: Jonas Bernoulli - -;; Package-Requires: ((emacs "24.4") (async "1.9") (dash "2.13.0")) -;; Keywords: tools -;; Homepage: https://github.com/magit/with-editor - -;; This file is not part of GNU Emacs. - -;; This file is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. - -;; This file 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. - -;; You should have received a copy of the GNU General Public License -;; along with Magit. If not, see http://www.gnu.org/licenses. - -;;; Commentary: - -;; This library makes it possible to reliably use the Emacsclient as -;; the `$EDITOR' of child processes. It makes sure that they know how -;; to call home. For remote processes a substitute is provided, which -;; communicates with Emacs on standard output/input instead of using a -;; socket as the Emacsclient does. - -;; It provides the commands `with-editor-async-shell-command' and -;; `with-editor-shell-command', which are intended as replacements -;; for `async-shell-command' and `shell-command'. They automatically -;; export `$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 -;; `$GIT_EDITOR'. To always use these variants add this to your init -;; file: -;; -;; (define-key (current-global-map) -;; [remap async-shell-command] 'with-editor-async-shell-command) -;; (define-key (current-global-map) -;; [remap shell-command] 'with-editor-shell-command) - -;; Alternatively use the global `shell-command-with-editor-mode', -;; which always sets `$EDITOR' for all Emacs commands which ultimately -;; use `shell-command' to asynchronously run some shell command. - -;; The command `with-editor-export-editor' exports `$EDITOR' or -;; another such environment variable in `shell-mode', `term-mode' and -;; `eshell-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: -;; -;; (add-hook 'shell-mode-hook 'with-editor-export-editor) -;; (add-hook 'term-exec-hook 'with-editor-export-editor) -;; (add-hook 'eshell-mode-hook 'with-editor-export-editor) - -;; Some variants of this function exist, these two forms are -;; equivalent: -;; -;; (add-hook 'shell-mode-hook -;; (apply-partially 'with-editor-export-editor "GIT_EDITOR")) -;; (add-hook 'shell-mode-hook 'with-editor-export-git-editor) - -;; This library can also be used by other packages which need to use -;; the current Emacs instance as editor. In fact this library was -;; written for Magit and its `git-commit-mode' and `git-rebase-mode'. -;; Consult `git-rebase.el' and the related code in `magit-sequence.el' -;; for a simple example. - -;;; Code: - -(require 'cl-lib) -(require 'dash) -(require 'server) -(require 'tramp) -(require 'tramp-sh nil t) - -(and (require 'async-bytecomp nil t) - (memq 'magit (bound-and-true-p async-bytecomp-allowed-packages)) - (fboundp 'async-bytecomp-package-mode) - (async-bytecomp-package-mode 1)) - -(eval-when-compile - (progn (require 'dired nil t) - (require 'eshell nil t) - (require 'term nil t) - (require 'warnings nil t))) -(declare-function dired-get-filename 'dired) -(declare-function term-emulate-terminal 'term) -(defvar eshell-preoutput-filter-functions) - -;;; Options - -(defgroup with-editor nil - "Use the Emacsclient as $EDITOR." - :group 'external - :group 'server) - -(defun with-editor-locate-emacsclient () - "Search for a suitable Emacsclient executable." - (--if-let (with-editor-locate-emacsclient-1 (with-editor-emacsclient-path) 3) - it - (display-warning 'with-editor (format "\ -Cannot determine a suitable Emacsclient - -Determining an Emacsclient executable suitable for the -current Emacs instance failed. For more information -please see https://github.com/magit/magit/wiki/Emacsclient.")) - nil)) - -(defun with-editor-locate-emacsclient-1 (path depth) - (let* ((version-lst (-take depth (split-string emacs-version "\\."))) - (version-reg (concat "^" (mapconcat #'identity version-lst "\\.")))) - (or (locate-file-internal - "emacsclient" path - (cl-mapcan - (lambda (v) (cl-mapcar (lambda (e) (concat v e)) exec-suffixes)) - (nconc (and (boundp 'debian-emacs-flavor) - (list (format ".%s" debian-emacs-flavor))) - (cl-mapcon (lambda (v) - (setq v (mapconcat #'identity (reverse v) ".")) - (list v (concat "-" v) (concat ".emacs" v))) - (reverse version-lst)) - (list "" "-snapshot" ".emacs-snapshot"))) - (lambda (exec) - (ignore-errors - (string-match-p version-reg - (with-editor-emacsclient-version exec))))) - (and (> depth 1) - (with-editor-locate-emacsclient-1 path (1- depth)))))) - -(defun with-editor-emacsclient-version (exec) - (-when-let (1st-line (car (process-lines exec "--version"))) - (cadr (split-string 1st-line)))) - -(defun with-editor-emacsclient-path () - (let ((path exec-path)) - (when invocation-directory - (push (directory-file-name invocation-directory) path) - (let* ((linkname (expand-file-name invocation-name invocation-directory)) - (truename (file-chase-links linkname))) - (unless (equal truename linkname) - (push (directory-file-name (file-name-directory truename)) path))) - (when (eq system-type 'darwin) - (let ((dir (expand-file-name "bin" invocation-directory))) - (when (file-directory-p dir) - (push dir path))) - (when (string-match-p "Cellar" invocation-directory) - (let ((dir (expand-file-name "../../../bin" invocation-directory))) - (when (file-directory-p dir) - (push dir path)))))) - (cl-remove-duplicates path :test 'equal))) - -(defcustom with-editor-emacsclient-executable (with-editor-locate-emacsclient) - "The Emacsclient executable used by the `with-editor' macro." - :group 'with-editor - :type '(choice (string :tag "Executable") - (const :tag "Don't use Emacsclient" nil))) - -(defcustom with-editor-sleeping-editor "\ -sh -c '\ -echo \"WITH-EDITOR: $$ OPEN $0\"; \ -sleep 604800 & sleep=$!; \ -trap \"kill $sleep; exit 0\" USR1; \ -trap \"kill $sleep; exit 1\" USR2; \ -wait $sleep'" - "The sleeping editor, used when the Emacsclient cannot be used. - -This fallback is used for asynchronous process started inside the -macro `with-editor', when the process runs on a remote machine or -for local processes when `with-editor-emacsclient-executable' is -nil (i.e. when no suitable Emacsclient was found, or the user -decided not to use it). - -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 Emacsclient, it can only -be used as $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. `csh' on FreeBSD, but not Debian), -then you have to edit this option. You can either replace \"sh\" -with \"bash\" (and install that), or you can use the older, less -performant implementation: - - \"sh -c '\\ - echo \\\"WITH-EDITOR: $$ OPEN $0\\\"; \\ - trap \\\"exit 0\\\" USR1; \\ - trap \\\"exit 1\" USR2; \\ - while true; do sleep 1; done'\" - -Note that this leads to a delay of up to a second. The delay can -be shortened by replacing \"sleep 1\" with \"sleep 0.01\", or if your -implementation does not support floats, then by using `nanosleep' -instead." - :group 'with-editor - :type 'string) - -(defcustom with-editor-finish-query-functions nil - "List of functions called to query before finishing session. - -The buffer in question is current while the functions are called. -If any of them returns nil, then the session is not finished and -the buffer is not killed. The user should then fix the issue and -try again. The functions are called with one argument. If it is -non-nil then that indicates that the user used a prefix argument -to force finishing the session despite issues. Functions should -usually honor that and return non-nil." - :group 'with-editor - :type 'hook) -(put 'with-editor-finish-query-functions 'permanent-local t) - -(defcustom with-editor-cancel-query-functions nil - "List of functions called to query before canceling session. - -The buffer in question is current while the functions are called. -If any of them returns nil, then the session is not canceled and -the buffer is not killed. The user should then fix the issue and -try again. The functions are called with one argument. If it is -non-nil then that indicates that the user used a prefix argument -to force canceling the session despite issues. Functions should -usually honor that and return non-nil." - :group 'with-editor - :type 'hook) -(put 'with-editor-cancel-query-functions 'permanent-local t) - -(defcustom with-editor-mode-lighter " WE" - "The mode-line lighter of the With-Editor mode." - :group 'with-editor - :type '(choice (const :tag "No lighter" "") string)) - -(defvar with-editor-server-window-alist nil - "Alist of filename patterns vs corresponding `server-window'. - -Each element looks like (REGEXP . FUNCTION). Files matching -REGEXP are selected using FUNCTION instead of the default in -`server-window'. - -Note that when a package adds an entry here then it probably -has a reason to disrespect `server-window' and it likely is -not a good idea to change such entries.") - -(defvar with-editor-file-name-history-exclude nil - "List of regexps for filenames `server-visit' should no remember. -When a filename matches any of the regexps, then `server-visit' -does not add it to the variable `file-name-history', which is -used when reading a filename in the minibuffer.") - -;;; Mode Commands - -(defvar with-editor-pre-finish-hook nil) -(defvar with-editor-pre-cancel-hook nil) -(defvar with-editor-post-finish-hook nil) -(defvar with-editor-post-finish-hook-1 nil) -(defvar with-editor-post-cancel-hook nil) -(defvar with-editor-post-cancel-hook-1 nil) -(defvar with-editor-cancel-alist nil) -(put 'with-editor-pre-finish-hook 'permanent-local t) -(put 'with-editor-pre-cancel-hook 'permanent-local t) -(put 'with-editor-post-finish-hook 'permanent-local t) -(put 'with-editor-post-cancel-hook 'permanent-local t) - -(defvar with-editor-show-usage t) -(defvar with-editor-cancel-message nil) -(defvar with-editor-previous-winconf nil) -(make-variable-buffer-local 'with-editor-show-usage) -(make-variable-buffer-local 'with-editor-cancel-message) -(make-variable-buffer-local 'with-editor-previous-winconf) -(put 'with-editor-cancel-message 'permanent-local t) -(put 'with-editor-previous-winconf 'permanent-local t) - -(defvar-local with-editor--pid nil "For internal use.") -(put 'with-editor--pid 'permanent-local t) - -(defun with-editor-finish (force) - "Finish the current edit session." - (interactive "P") - (when (run-hook-with-args-until-failure - 'with-editor-finish-query-functions force) - (let ((with-editor-post-finish-hook-1 - (ignore-errors (delq t with-editor-post-finish-hook)))) - (run-hooks 'with-editor-pre-finish-hook) - (with-editor-return nil) - (accept-process-output nil 0.1) - (run-hooks 'with-editor-post-finish-hook-1)))) - -(defun with-editor-cancel (force) - "Cancel the current edit session." - (interactive "P") - (when (run-hook-with-args-until-failure - 'with-editor-cancel-query-functions force) - (let ((message with-editor-cancel-message)) - (when (functionp message) - (setq message (funcall message))) - (let ((with-editor-post-cancel-hook-1 - (ignore-errors (delq t with-editor-post-cancel-hook))) - (with-editor-cancel-alist nil)) - (run-hooks 'with-editor-pre-cancel-hook) - (with-editor-return t) - (accept-process-output nil 0.1) - (run-hooks 'with-editor-post-cancel-hook-1)) - (message (or message "Canceled by user"))))) - -(defun with-editor-return (cancel) - (let ((winconf with-editor-previous-winconf) - (clients server-buffer-clients) - (dir default-directory) - (pid with-editor--pid)) - (remove-hook 'kill-buffer-query-functions - 'with-editor-kill-buffer-noop t) - (cond (cancel - (save-buffer) - (if clients - (dolist (client clients) - (ignore-errors - (server-send-string client "-error Canceled by user")) - (delete-process client)) - ;; Fallback for when emacs was used as $EDITOR instead - ;; of emacsclient or the sleeping editor. See #2258. - (ignore-errors (delete-file buffer-file-name)) - (kill-buffer))) - (t - (save-buffer) - (if clients - ;; Don't use `server-edit' because we do not want to show - ;; another buffer belonging to another client. See #2197. - (server-done) - (kill-buffer)))) - (when pid - (let ((default-directory dir)) - (process-file "kill" nil nil nil - "-s" (if cancel "USR2" "USR1") pid))) - (when (and winconf (eq (window-configuration-frame winconf) - (selected-frame))) - (set-window-configuration winconf)))) - -;;; Mode - -(defvar with-editor-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-c" 'with-editor-finish) - (define-key map [remap server-edit] 'with-editor-finish) - (define-key map [remap evil-save-and-close] 'with-editor-finish) - (define-key map [remap evil-save-modified-and-close] 'with-editor-finish) - (define-key map "\C-c\C-k" 'with-editor-cancel) - (define-key map [remap kill-buffer] 'with-editor-cancel) - (define-key map [remap ido-kill-buffer] 'with-editor-cancel) - (define-key map [remap iswitchb-kill-buffer] 'with-editor-cancel) - (define-key map [remap evil-quit] 'with-editor-cancel) - map)) - -(define-minor-mode with-editor-mode - "Edit a file as the $EDITOR of an external process." - :lighter with-editor-mode-lighter - ;; Protect the user from killing the buffer without using - ;; either `with-editor-finish' or `with-editor-cancel', - ;; and from removing the key bindings for these commands. - (unless with-editor-mode - (error "With-Editor mode cannot be turned off")) - (add-hook 'kill-buffer-query-functions - 'with-editor-kill-buffer-noop nil t) - ;; `server-execute' displays a message which is not - ;; correct when using this mode. - (when with-editor-show-usage - (with-editor-usage-message))) - -(put 'with-editor-mode 'permanent-local t) - -(defun with-editor-kill-buffer-noop () - (message (substitute-command-keys "\ -Don't kill this buffer. Instead cancel using \\[with-editor-cancel]"))) - -(defun with-editor-usage-message () - ;; Run after `server-execute', which is run using - ;; a timer which starts immediately. - (run-with-timer - 0.01 nil `(lambda () - (with-current-buffer ,(current-buffer) - (message (substitute-command-keys "\ -Type \\[with-editor-finish] to finish, \ -or \\[with-editor-cancel] to cancel")))))) - -;;; Wrappers - -(defvar with-editor--envvar nil "For internal use.") - -(defmacro with-editor (&rest body) - "Use the Emacsclient as $EDITOR while evaluating BODY. -Modify the `process-environment' for processes started in BODY, -instructing them to use the Emacsclient as $EDITOR. If optional -ENVVAR is provided then bind that environment variable instead. -\n(fn [ENVVAR] BODY...)" - (declare (indent defun) (debug (body))) - `(let ((with-editor--envvar ,(if (stringp (car body)) - (pop body) - '(or with-editor--envvar "EDITOR"))) - (process-environment process-environment)) - (if (or (not with-editor-emacsclient-executable) - (file-remote-p default-directory)) - (push (concat with-editor--envvar "=" with-editor-sleeping-editor) - process-environment) - ;; Make sure server-use-tcp's value is valid. - (unless (featurep 'make-network-process '(:family local)) - (setq server-use-tcp t)) - ;; Make sure the server is running. - (unless server-process - (when (server-running-p server-name) - (setq server-name (format "server%s" (emacs-pid))) - (when (server-running-p server-name) - (server-force-delete server-name))) - (server-start)) - ;; Tell $EDITOR to use the Emacsclient. - (push (concat with-editor--envvar "=" - (shell-quote-argument with-editor-emacsclient-executable) - ;; Tell the process where the server file is. - (and (not server-use-tcp) - (concat " --socket-name=" - (shell-quote-argument - (expand-file-name server-name - server-socket-dir))))) - process-environment) - (when server-use-tcp - (push (concat "EMACS_SERVER_FILE=" - (expand-file-name server-name server-auth-dir)) - process-environment)) - ;; As last resort fallback to the sleeping editor. - (push (concat "ALTERNATE_EDITOR=" with-editor-sleeping-editor) - process-environment)) - ,@body)) - -(defun with-editor-server-window () - (or (and buffer-file-name - (cdr (--first (string-match-p (car it) buffer-file-name) - with-editor-server-window-alist))) - server-window)) - -(defun server-switch-buffer--with-editor-server-window-alist - (fn &optional next-buffer killed-one filepos) - "Honor `with-editor-server-window-alist' (which see)." - (let ((server-window (with-current-buffer - (or next-buffer (current-buffer)) - (when with-editor-mode - (setq with-editor-previous-winconf - (current-window-configuration))) - (with-editor-server-window)))) - (funcall fn next-buffer killed-one filepos))) - -(advice-add 'server-switch-buffer :around - 'server-switch-buffer--with-editor-server-window-alist) - -(defun start-file-process--with-editor-process-filter - (fn name buffer program &rest program-args) - "When called inside a `with-editor' form and the Emacsclient -cannot be used, then give the process the filter function -`with-editor-process-filter'. To avoid overriding the filter -being added here you should use `with-editor-set-process-filter' -instead of `set-process-filter' inside `with-editor' forms. - -When the `default-directory' is located on a remote machine, -then also manipulate PROGRAM and PROGRAM-ARGS in order to set -the appropriate editor environment variable." - (if (not with-editor--envvar) - (apply fn name buffer program program-args) - (when (file-remote-p default-directory) - (unless (equal program "env") - (push program program-args) - (setq program "env")) - (push (concat with-editor--envvar "=" with-editor-sleeping-editor) - program-args)) - (let ((process (apply fn name buffer program program-args))) - (set-process-filter process 'with-editor-process-filter) - (process-put process 'default-dir default-directory) - process))) - -(advice-add 'start-file-process :around - 'start-file-process--with-editor-process-filter) - -(defun with-editor-set-process-filter (process filter) - "Like `set-process-filter' but keep `with-editor-process-filter'. -Give PROCESS the new FILTER but keep `with-editor-process-filter' -if that was added earlier by the adviced `start-file-process'. - -Do so by wrapping the two filter functions using a lambda, which -becomes the actual filter. It calls `with-editor-process-filter' -first, passing t as NO-STANDARD-FILTER. Then it calls FILTER, -which may or may not insert the text into the PROCESS' buffer." - (set-process-filter - process - (if (eq (process-filter process) 'with-editor-process-filter) - `(lambda (proc str) - (,filter proc str) - (with-editor-process-filter proc str t)) - filter))) - -(defvar with-editor-filter-visit-hook nil) - -(defun with-editor-output-filter (string) - (save-match-data - (if (string-match "^WITH-EDITOR: \\([0-9]+\\) OPEN \\(.+?\\)\r?$" string) - (let ((pid (match-string 1 string)) - (file (match-string 2 string))) - (with-current-buffer - (find-file-noselect - (if (file-name-absolute-p file) - (if (tramp-tramp-file-p default-directory) - (with-parsed-tramp-file-name default-directory nil - (tramp-make-tramp-file-name method user host file hop)) - file) - (expand-file-name file))) - (with-editor-mode 1) - (setq with-editor--pid pid) - (run-hooks 'with-editor-filter-visit-hook) - (funcall (or (with-editor-server-window) 'switch-to-buffer) - (current-buffer)) - (kill-local-variable 'server-window)) - nil) - string))) - -(defun with-editor-process-filter - (process string &optional no-default-filter) - "Listen for edit requests by child processes." - (let ((default-directory (process-get process 'default-dir))) - (with-editor-output-filter string)) - (unless no-default-filter - (internal-default-process-filter process string))) - -(advice-add 'server-visit-files :after - 'server-visit-files--with-editor-file-name-history-exclude) - -(defun server-visit-files--with-editor-file-name-history-exclude - (files _proc &optional _nowait) - (dolist (file files) - (setq file (car file)) - (when (--any (string-match-p it file) - with-editor-file-name-history-exclude) - (setq file-name-history (delete file file-name-history))))) - -;;; Augmentations - -(cl-defun with-editor-export-editor (&optional (envvar "EDITOR")) - "Teach subsequent commands to use current Emacs instance as editor. - -Set and export the environment variable ENVVAR, by default -\"EDITOR\". The value is automatically generated to teach -commands to use the current Emacs instance as \"the editor\". - -This works in `shell-mode', `term-mode' and `eshell-mode'." - (interactive (list (with-editor-read-envvar))) - (cond - ((derived-mode-p 'comint-mode 'term-mode) - (let* ((process (get-buffer-process (current-buffer))) - (filter (process-filter process))) - (goto-char (process-mark process)) - (process-send-string - process (format "export %s=%s\n" envvar - (shell-quote-argument with-editor-sleeping-editor))) - (while (accept-process-output process 0.1)) - (set-process-filter process filter) - (if (derived-mode-p 'term-mode) - (with-editor-set-process-filter process 'with-editor-emulate-terminal) - (add-hook 'comint-output-filter-functions 'with-editor-output-filter - nil t)))) - ((derived-mode-p 'eshell-mode) - (add-to-list 'eshell-preoutput-filter-functions - 'with-editor-output-filter) - (setenv envvar with-editor-sleeping-editor)) - (t - (error "Cannot export environment variables in this buffer"))) - (message "Successfully exported %s" envvar)) - -(defun with-editor-export-git-editor () - "Like `with-editor-export-editor' but always set `$GIT_EDITOR'." - (interactive) - (with-editor-export-editor "GIT_EDITOR")) - -(defun with-editor-export-hg-editor () - "Like `with-editor-export-editor' but always set `$HG_EDITOR'." - (interactive) - (with-editor-export-editor "HG_EDITOR")) - -(defun with-editor-emulate-terminal (process string) - "Like `term-emulate-terminal' but also handle edit requests." - (when (with-editor-output-filter string) - (term-emulate-terminal process string))) - -(defvar with-editor-envvars '("EDITOR" "GIT_EDITOR" "HG_EDITOR")) - -(cl-defun with-editor-read-envvar - (&optional (prompt "Set environment variable") - (default "EDITOR")) - (let ((reply (completing-read (if default - (format "%s (%s): " prompt default) - (concat prompt ": ")) - with-editor-envvars nil nil nil nil default))) - (if (string= reply "") (user-error "Nothing selected") reply))) - -(define-minor-mode shell-command-with-editor-mode - "Teach `shell-command' to use current Emacs instance as editor. - -Teach `shell-command', and all commands that ultimately call that -command, to use the current Emacs instance as editor by executing -\"EDITOR=CLIENT COMMAND&\" instead of just \"COMMAND&\". - -CLIENT is automatically generated; EDITOR=CLIENT instructs -COMMAND to use to the current Emacs instance as \"the editor\", -assuming no other variable overrides the effect of \"$EDITOR\". -CLIENT may be the path to an appropriate emacsclient executable -with arguments, or a script which also works over Tramp. - -Alternatively you can use the `with-editor-async-shell-command', -which also allows the use of another variable instead of -\"EDITOR\"." - :global t) - -(defun with-editor-async-shell-command - (command &optional output-buffer error-buffer envvar) - "Like `async-shell-command' but with `$EDITOR' set. - -Execute string \"ENVVAR=CLIENT COMMAND\" in an inferior shell; -display output, if any. With a prefix argument prompt for an -environment variable, otherwise the default \"EDITOR\" variable -is used. With a negative prefix argument additionally insert -the COMMAND's output at point. - -CLIENT is automatically generated; ENVVAR=CLIENT instructs -COMMAND to use to the current Emacs instance as \"the editor\", -assuming it respects ENVVAR as an \"EDITOR\"-like variable. -CLIENT maybe the path to an appropriate emacsclient executable -with arguments, or a script which also works over Tramp. - -Also see `async-shell-command' and `shell-command'." - (interactive (with-editor-shell-command-read-args "Async shell command: " t)) - (let ((with-editor--envvar envvar)) - (with-editor - (async-shell-command command output-buffer error-buffer)))) - -(defun with-editor-shell-command - (command &optional output-buffer error-buffer envvar) - "Like `shell-command' or `with-editor-async-shell-command'. -If COMMAND ends with \"&\" behave like the latter, -else like the former." - (interactive (with-editor-shell-command-read-args "Shell command: ")) - (if (string-match "&[ \t]*\\'" command) - (with-editor-async-shell-command - command output-buffer error-buffer envvar) - (shell-command command output-buffer error-buffer))) - -(defun with-editor-shell-command-read-args (prompt &optional async) - (let ((command (read-shell-command - prompt nil nil - (--when-let (or buffer-file-name - (and (eq major-mode 'dired-mode) - (dired-get-filename nil t))) - (file-relative-name it))))) - (list command - (if (or async (setq async (string-match-p "&[ \t]*\\'" command))) - (< (prefix-numeric-value current-prefix-arg) 0) - current-prefix-arg) - shell-command-default-error-buffer - (and async current-prefix-arg (with-editor-read-envvar))))) - -(defun shell-command--shell-command-with-editor-mode - (fn command &optional output-buffer error-buffer) - ;; `shell-mode' and its hook are intended for buffers in which an - ;; interactive shell is running, but `shell-command' also turns on - ;; that mode, even though it only runs the shell to run a single - ;; command. The `with-editor-export-editor' hook function is only - ;; intended to be used in buffers in which an interactive shell is - ;; running, so it has to be remove here. - (let ((shell-mode-hook (remove 'with-editor-export-editor shell-mode-hook))) - (cond ((or (not (or with-editor--envvar shell-command-with-editor-mode)) - (not (string-match-p "&\\'" command))) - (funcall fn command output-buffer error-buffer)) - ((and with-editor-emacsclient-executable - (not (file-remote-p default-directory))) - (with-editor (funcall fn command output-buffer error-buffer))) - (t - (apply fn (format "%s=%s %s" - (or with-editor--envvar "EDITOR") - (shell-quote-argument with-editor-sleeping-editor) - command) - output-buffer error-buffer) - (ignore-errors - (let ((process (get-buffer-process - (or output-buffer - (get-buffer "*Async Shell Command*"))))) - (set-process-filter - process (lambda (proc str) - (comint-output-filter proc str) - (with-editor-process-filter proc str t))) - process)))))) - -(advice-add 'shell-command :around - 'shell-command--shell-command-with-editor-mode) - -;;; with-editor.el ends soon - -(defun with-editor-debug () - "Debug configuration issues. -See `with-editor.info' for instructions." - (interactive) - (with-current-buffer (get-buffer-create "*with-editor-debug*") - (pop-to-buffer (current-buffer)) - (erase-buffer) - (ignore-errors (with-editor)) - (insert - (format "with-editor: %s\n" (locate-library "with-editor.el")) - (format "emacs: %s (%s)\n" - (expand-file-name invocation-name invocation-directory) - emacs-version) - "system:\n" - (format " system-type: %s\n" system-type) - (format " system-configuration: %s\n" system-configuration) - (format " system-configuration-options: %s\n" system-configuration-options) - "server:\n" - (format " server-running-p: %s\n" (server-running-p)) - (format " server-process: %S\n" server-process) - (format " server-use-tcp: %s\n" server-use-tcp) - (format " server-name: %s\n" server-name) - (format " server-socket-dir: %s\n" server-socket-dir)) - (if (and server-socket-dir (file-accessible-directory-p server-socket-dir)) - (--each (directory-files server-socket-dir nil "^[^.]") - (insert (format " %s\n" it))) - (insert (format " %s: not an accessible directory\n" - (if server-use-tcp "WARNING" "ERROR")))) - (insert (format " server-auth-dir: %s\n" server-auth-dir)) - (if (file-accessible-directory-p server-auth-dir) - (--each (directory-files server-auth-dir nil "^[^.]") - (insert (format " %s\n" it))) - (insert (format " %s: not an accessible directory\n" - (if server-use-tcp "ERROR" "WARNING")))) - (let ((val with-editor-emacsclient-executable) - (def (default-value 'with-editor-emacsclient-executable)) - (fun (let ((warning-minimum-level :error) - (warning-minimum-log-level :error)) - (with-editor-locate-emacsclient)))) - (insert "magit-emacsclient-executable:\n" - (format " value: %s (%s)\n" val - (and val (with-editor-emacsclient-version val))) - (format " default: %s (%s)\n" def - (and def (with-editor-emacsclient-version def))) - (format " funcall: %s (%s)\n" fun - (and fun (with-editor-emacsclient-version fun))))) - (insert "path:\n" - (format " $PATH: %S\n" (getenv "PATH")) - (format " exec-path: %s\n" exec-path)) - (insert (format " with-editor-emacsclient-path:\n")) - (--each (with-editor-emacsclient-path) - (insert (format " %s (%s)\n" it (car (file-attributes it)))) - (when (file-directory-p it) - (dolist (exec (directory-files it t "emacsclient")) - (insert (format " %s (%s)\n" exec - (with-editor-emacsclient-version exec)))))))) - -(defconst with-editor-font-lock-keywords - '(("(\\(with-\\(?:git-\\)?editor\\)\\_>" (1 'font-lock-keyword-face)))) -(font-lock-add-keywords 'emacs-lisp-mode with-editor-font-lock-keywords) - -(provide 'with-editor) -;; Local Variables: -;; indent-tabs-mode: nil -;; End: -;;; with-editor.el ends here diff --git a/elpa/with-editor-20161109.403/with-editor.info b/elpa/with-editor-20161109.403/with-editor.info deleted file mode 100644 index b4e77661..00000000 --- a/elpa/with-editor-20161109.403/with-editor.info +++ /dev/null @@ -1,340 +0,0 @@ -This is with-editor.info, produced by makeinfo version 5.2 from -with-editor.texi. - -The library ‘with-editor’ makes it easy to use the Emacsclient as the -‘$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. - - Copyright (C) 2015-2016 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. -INFO-DIR-SECTION Emacs -START-INFO-DIR-ENTRY -* With-Editor: (with-editor). Using the Emacsclient as $EDITOR. -END-INFO-DIR-ENTRY - - -File: with-editor.info, Node: Top, Next: Using the With-Editor package, Up: (dir) - -With-Editor User Manual -*********************** - -The library ‘with-editor’ makes it easy to use the Emacsclient as the -‘$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. - - Copyright (C) 2015-2016 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. - -* Menu: - -* Using the With-Editor package:: -* Using With-Editor as a library:: -* Debugging:: - -— The Detailed Node Listing — - -Using the With-Editor package - -* Configuring With-Editor:: -* Using With-Editor commands:: - - -File: with-editor.info, Node: Using the With-Editor package, Next: Using With-Editor as a library, Prev: Top, Up: Top - -1 Using the With-Editor package -******************************* - -The ‘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 you own package, see -*note Using With-Editor as a library: Using With-Editor as a library. - -* Menu: - -* Configuring With-Editor:: -* Using With-Editor commands:: - - -File: with-editor.info, Node: Configuring With-Editor, Next: Using With-Editor commands, Up: Using the With-Editor package - -1.1 Configuring With-Editor -=========================== - -With-Editor tries very hard to locate a suitable emacsclient executable, -so ideally you should never have to customize the option -‘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 OS X) without putting the executable on ‘$PATH’, -and we have to add another kludge to find it anyway. - - -- User Option: with-editor-emacsclient-executable - - The emacsclient executable used as the editor by child process 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 - ‘exec-path’, and other places where the executable could be - installed, to find the emacsclient executable most suitable for the - current emacs instance. - - You should *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 *note Debugging: Debugging. - - If With-Editor fails to find a suitable emacsclient on you system, - then this should be fixed for all users at once, by teaching - ‘with-editor-locate-emacsclient’ how to so on your system and - system 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 - ‘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 you setup. - - -- Function: with-editor-locate-emacsclient - - The function used to set the initial value of the option - ‘with-editor-emacsclient-executable’. There’s a lot of voodoo - here. - - The 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 -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. - - -- User Option: with-editor-sleeping-editor - - The sleeping editor is a shell script used as the editor of child - processes when the emacsclient executable cannot be used. - - This fallback is used for asynchronous process started inside the - macro ‘with-editor’, when the process runs on a remote machine or - for local processes when ‘with-editor-emacsclient-executable’ is - ‘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 Emacsclient, it can only be - used as ‘$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. ‘csh’ on FreeBSD, but not Debian), - then you have to edit this option. You can either replace ‘sh’ - with ‘bash’ (and install that), or you can use the older, less - performant implementation: - - "sh -c '\ - echo \"WITH-EDITOR: $$ OPEN $0\"; \ - trap \"exit 0\" USR1; \ - trap \"exit 1\" USR2; \ - while true; do sleep 1; done'" - - This leads to a delay of up to a second. The delay can be - shortened by replacing ‘sleep 1’ with ‘sleep 0.01’, or if your - implementation does not support floats, then by using ‘nanosleep - 0.01’ instead. - - -File: with-editor.info, Node: Using With-Editor commands, Prev: Configuring With-Editor, Up: Using the With-Editor package - -1.2 Using With-Editor commands -============================== - -This section describes how to use the ‘with-editor’ library _outside_ of -Magit. You don’t need to know any of this just to create commits using -Magit. - - The commands ‘with-editor-async-shell-command’ and -‘with-editor-shell-command’ are intended as drop in replacements for -‘async-shell-command’ and ‘shell-command’. They automatically export -‘$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 ‘$GIT_EDITOR’. - - -- Command: with-editor-async-shell-command - - Like ‘async-shell-command’, but the command is run with the current - Emacs instance exported as ‘$EDITOR’. - - -- Command: with-editor-shell-command - - Like ‘async-shell-command’, but the command is run with the current - Emacs instance exported as ‘$EDITOR’. This only has an effect if - the command is run asynchronously, i.e. when the command ends with - ‘&’. - - To always use these variants add this to you init file: - - (define-key (current-global-map) - [remap async-shell-command] 'with-editor-async-shell-command) - (define-key (current-global-map) - [remap shell-command] 'with-editor-shell-command) - - Alternatively use the global ‘shell-command-with-editor-mode’. - - -- Variable: shell-command-with-editor-mode - - When this mode is active, then ‘$EDITOR’ is exported whenever - ultimately ‘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. - - The command ‘with-editor-export-editor’ exports ‘$EDITOR’ or another -such environment variable in ‘shell-mode’, ‘term-mode’ and ‘eshell-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: - - (add-hook 'shell-mode-hook 'with-editor-export-editor) - (add-hook 'term-exec-hook 'with-editor-export-editor) - (add-hook 'eshell-mode-hook 'with-editor-export-editor) - - Some variants of this function exist; these two forms are equivalent: - - (add-hook 'shell-mode-hook - (apply-partially 'with-editor-export-editor "GIT_EDITOR")) - (add-hook 'shell-mode-hook 'with-editor-export-git-editor) - - -- Command: with-editor-export-editor - - When invoked in a ‘shell-mode’, ‘term-mode’, or ‘eshell-mode’ - buffer, this command teaches shell commands to use the current - Emacs instance as the editor, by exporting ‘$EDITOR’. - - -- Command: with-editor-export-git-editor - - Like ‘with-editor-export-editor’ but exports ‘$GIT_EDITOR’. - - -- Command: with-editor-export-hg-editor - - Like ‘with-editor-export-editor’ but exports ‘$HG_EDITOR’. - - -File: with-editor.info, Node: Using With-Editor as a library, Next: Debugging, Prev: Using the With-Editor package, Up: Top - -2 Using With-Editor as a library -******************************** - -This section describes how to use the with-editor library _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 -‘with-editor’ outside of Magit, but only as an end-user. - - For information about interactive use and options which affect both -interactive and non-interactive use, see *note Using the With-Editor -package: Using the With-Editor package. - - -- Macro: with-editor &rest body - - This macro arranges for the 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 essentially done by establishing a local binding for - ‘process-environment’ and changing the value of the ‘$EDITOR’ - environment variable. This affects all processes started by forms - inside BODY. - - -- Function: with-editor-set-process-filter process filter - - This function is like ‘set-process-filter’ but ensures that adding - the new FILTER does not remove the ‘with-editor-process-filter’. - This is done by wrapping the two filter functions using a lambda, - which becomes the actual filter. It calls - ‘with-editor-process-filter’ first, passing ‘t’ as - NO-STANDARD-FILTER. Then it calls FILTER. - - -File: with-editor.info, Node: Debugging, Prev: Using With-Editor as a library, Up: Top - -3 Debugging -*********** - -With-Editor tries very hard to locate a suitable emacsclient executable, -and then sets option ‘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 OS X) without putting the executable on ‘$PATH’, and we have -to add another kludge to find it anyway. - - If you are having problems using ‘with-editor’, e.g. you cannot -commit in Magit, then please open a new issue at - and provide information -about your Emacs installation. Most importantly how did you install -Emacs and what is the output of ‘M-x with-editor-debug’? - - - -Tag Table: -Node: Top1545 -Node: Using the With-Editor package3236 -Node: Configuring With-Editor3852 -Node: Using With-Editor commands8201 -Node: Using With-Editor as a library11364 -Node: Debugging13036 - -End Tag Table - - -Local Variables: -coding: utf-8 -End: diff --git a/elpa/with-editor-20170817.1240/dir b/elpa/with-editor-20170817.1240/dir deleted file mode 100644 index 93a7ef74..00000000 --- a/elpa/with-editor-20170817.1240/dir +++ /dev/null @@ -1,18 +0,0 @@ -This is the file .../info/dir, which contains the -topmost node of the Info hierarchy, called (dir)Top. -The first time you invoke Info you start off looking at this node. - -File: dir, Node: Top This is the top of the INFO tree - - This (the Directory node) gives a menu of major topics. - Typing "q" exits, "?" lists all Info commands, "d" returns here, - "h" gives a primer for first-timers, - "mEmacs" visits the Emacs manual, etc. - - In Emacs, you can click mouse button 2 on a menu item or cross reference - to select it. - -* Menu: - -Emacs -* With-Editor: (with-editor). Using the Emacsclient as $EDITOR. diff --git a/elpa/with-editor-20170817.1240/with-editor-autoloads.el b/elpa/with-editor-20170817.1240/with-editor-autoloads.el deleted file mode 100644 index 36bf06ac..00000000 --- a/elpa/with-editor-20170817.1240/with-editor-autoloads.el +++ /dev/null @@ -1,16 +0,0 @@ -;;; with-editor-autoloads.el --- automatically extracted autoloads -;; -;;; Code: -(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path)))) - -;;;### (autoloads nil nil ("with-editor-pkg.el" "with-editor.el") -;;;;;; (22975 34390 0 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; with-editor-autoloads.el ends here diff --git a/elpa/with-editor-20170817.1240/with-editor-pkg.el b/elpa/with-editor-20170817.1240/with-editor-pkg.el deleted file mode 100644 index fa2f6e3d..00000000 --- a/elpa/with-editor-20170817.1240/with-editor-pkg.el +++ /dev/null @@ -1,8 +0,0 @@ -(define-package "with-editor" "20170817.1240" "Use the Emacsclient as $EDITOR" - '((emacs "24.4") - (async "1.9")) - :url "https://github.com/magit/with-editor" :keywords - '("tools")) -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/elpa/with-editor-20170817.1240/with-editor.el b/elpa/with-editor-20170817.1240/with-editor.el deleted file mode 100644 index 83b4b92d..00000000 --- a/elpa/with-editor-20170817.1240/with-editor.el +++ /dev/null @@ -1,782 +0,0 @@ -;;; with-editor.el --- Use the Emacsclient as $EDITOR -*- lexical-binding: t -*- - -;; Copyright (C) 2014-2017 The Magit Project Contributors -;; -;; You should have received a copy of the AUTHORS.md file. If not, -;; see https://github.com/magit/with-editor/blob/master/AUTHORS.md. - -;; Author: Jonas Bernoulli -;; Maintainer: Jonas Bernoulli - -;; Package-Requires: ((emacs "24.4") (async "1.9")) -;; Keywords: tools -;; Homepage: https://github.com/magit/with-editor - -;; This file is not part of GNU Emacs. - -;; This file is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. - -;; This file 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. - -;; You should have received a copy of the GNU General Public License -;; along with Magit. If not, see http://www.gnu.org/licenses. - -;;; Commentary: - -;; This library makes it possible to reliably use the Emacsclient as -;; the `$EDITOR' of child processes. It makes sure that they know how -;; to call home. For remote processes a substitute is provided, which -;; communicates with Emacs on standard output/input instead of using a -;; socket as the Emacsclient does. - -;; It provides the commands `with-editor-async-shell-command' and -;; `with-editor-shell-command', which are intended as replacements -;; for `async-shell-command' and `shell-command'. They automatically -;; export `$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 -;; `$GIT_EDITOR'. To always use these variants add this to your init -;; file: -;; -;; (define-key (current-global-map) -;; [remap async-shell-command] 'with-editor-async-shell-command) -;; (define-key (current-global-map) -;; [remap shell-command] 'with-editor-shell-command) - -;; Alternatively use the global `shell-command-with-editor-mode', -;; which always sets `$EDITOR' for all Emacs commands which ultimately -;; use `shell-command' to asynchronously run some shell command. - -;; The command `with-editor-export-editor' exports `$EDITOR' or -;; another such environment variable in `shell-mode', `term-mode' and -;; `eshell-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: -;; -;; (add-hook 'shell-mode-hook 'with-editor-export-editor) -;; (add-hook 'term-exec-hook 'with-editor-export-editor) -;; (add-hook 'eshell-mode-hook 'with-editor-export-editor) - -;; Some variants of this function exist, these two forms are -;; equivalent: -;; -;; (add-hook 'shell-mode-hook -;; (apply-partially 'with-editor-export-editor "GIT_EDITOR")) -;; (add-hook 'shell-mode-hook 'with-editor-export-git-editor) - -;; This library can also be used by other packages which need to use -;; the current Emacs instance as editor. In fact this library was -;; written for Magit and its `git-commit-mode' and `git-rebase-mode'. -;; Consult `git-rebase.el' and the related code in `magit-sequence.el' -;; for a simple example. - -;;; Code: - -(require 'cl-lib) -(require 'server) -(require 'shell) - -(and (require 'async-bytecomp nil t) - (memq 'magit (bound-and-true-p async-bytecomp-allowed-packages)) - (fboundp 'async-bytecomp-package-mode) - (async-bytecomp-package-mode 1)) - -(eval-when-compile - (progn (require 'dired nil t) - (require 'eshell nil t) - (require 'term nil t) - (require 'warnings nil t))) -(declare-function dired-get-filename 'dired) -(declare-function term-emulate-terminal 'term) -(defvar eshell-preoutput-filter-functions) - -;;; Options - -(defgroup with-editor nil - "Use the Emacsclient as $EDITOR." - :group 'external - :group 'server) - -(defun with-editor-locate-emacsclient () - "Search for a suitable Emacsclient executable." - (or (with-editor-locate-emacsclient-1 - (with-editor-emacsclient-path) - (length (split-string emacs-version "\\."))) - (prog1 nil (display-warning 'with-editor "\ -Cannot determine a suitable Emacsclient - -Determining an Emacsclient executable suitable for the -current Emacs instance failed. For more information -please see https://github.com/magit/magit/wiki/Emacsclient.")))) - -(defun with-editor-locate-emacsclient-1 (path depth) - (let* ((version-lst (cl-subseq (split-string emacs-version "\\.") 0 depth)) - (version-reg (concat "^" (mapconcat #'identity version-lst "\\.")))) - (or (locate-file-internal - (if (equal invocation-name "remacs") "remacsclient" "emacsclient") - path - (cl-mapcan - (lambda (v) (cl-mapcar (lambda (e) (concat v e)) exec-suffixes)) - (nconc (and (boundp 'debian-emacs-flavor) - (list (format ".%s" debian-emacs-flavor))) - (cl-mapcon (lambda (v) - (setq v (mapconcat #'identity (reverse v) ".")) - (list v (concat "-" v) (concat ".emacs" v))) - (reverse version-lst)) - (list "" "-snapshot" ".emacs-snapshot"))) - (lambda (exec) - (ignore-errors - (string-match-p version-reg - (with-editor-emacsclient-version exec))))) - (and (> depth 1) - (with-editor-locate-emacsclient-1 path (1- depth)))))) - -(defun with-editor-emacsclient-version (exec) - (let ((default-directory (file-name-directory exec))) - (ignore-errors - (cadr (split-string (car (process-lines exec "--version"))))))) - -(defun with-editor-emacsclient-path () - (let ((path exec-path)) - (when invocation-directory - (push (directory-file-name invocation-directory) path) - (let* ((linkname (expand-file-name invocation-name invocation-directory)) - (truename (file-chase-links linkname))) - (unless (equal truename linkname) - (push (directory-file-name (file-name-directory truename)) path))) - (when (eq system-type 'darwin) - (let ((dir (expand-file-name "bin" invocation-directory))) - (when (file-directory-p dir) - (push dir path))) - (when (string-match-p "Cellar" invocation-directory) - (let ((dir (expand-file-name "../../../bin" invocation-directory))) - (when (file-directory-p dir) - (push dir path)))))) - (cl-remove-duplicates path :test 'equal))) - -(defcustom with-editor-emacsclient-executable (with-editor-locate-emacsclient) - "The Emacsclient executable used by the `with-editor' macro." - :group 'with-editor - :type '(choice (string :tag "Executable") - (const :tag "Don't use Emacsclient" nil))) - -(defcustom with-editor-sleeping-editor "\ -sh -c '\ -echo \"WITH-EDITOR: $$ OPEN $0\"; \ -sleep 604800 & sleep=$!; \ -trap \"kill $sleep; exit 0\" USR1; \ -trap \"kill $sleep; exit 1\" USR2; \ -wait $sleep'" - "The sleeping editor, used when the Emacsclient cannot be used. - -This fallback is used for asynchronous processes started inside -the macro `with-editor', when the process runs on a remote machine -or for local processes when `with-editor-emacsclient-executable' -is nil (i.e. when no suitable Emacsclient was found, or the user -decided not to use it). - -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 Emacsclient, it can only -be used as $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. `csh' on FreeBSD, but not Debian), -then you have to edit this option. You can either replace \"sh\" -with \"bash\" (and install that), or you can use the older, less -performant implementation: - - \"sh -c '\\ - echo \\\"WITH-EDITOR: $$ OPEN $0\\\"; \\ - trap \\\"exit 0\\\" USR1; \\ - trap \\\"exit 1\" USR2; \\ - while true; do sleep 1; done'\" - -Note that this leads to a delay of up to a second. The delay can -be shortened by replacing \"sleep 1\" with \"sleep 0.01\", or if your -implementation does not support floats, then by using `nanosleep' -instead." - :group 'with-editor - :type 'string) - -(defcustom with-editor-finish-query-functions nil - "List of functions called to query before finishing session. - -The buffer in question is current while the functions are called. -If any of them returns nil, then the session is not finished and -the buffer is not killed. The user should then fix the issue and -try again. The functions are called with one argument. If it is -non-nil then that indicates that the user used a prefix argument -to force finishing the session despite issues. Functions should -usually honor that and return non-nil." - :group 'with-editor - :type 'hook) -(put 'with-editor-finish-query-functions 'permanent-local t) - -(defcustom with-editor-cancel-query-functions nil - "List of functions called to query before canceling session. - -The buffer in question is current while the functions are called. -If any of them returns nil, then the session is not canceled and -the buffer is not killed. The user should then fix the issue and -try again. The functions are called with one argument. If it is -non-nil then that indicates that the user used a prefix argument -to force canceling the session despite issues. Functions should -usually honor that and return non-nil." - :group 'with-editor - :type 'hook) -(put 'with-editor-cancel-query-functions 'permanent-local t) - -(defcustom with-editor-mode-lighter " WE" - "The mode-line lighter of the With-Editor mode." - :group 'with-editor - :type '(choice (const :tag "No lighter" "") string)) - -(defvar with-editor-server-window-alist nil - "Alist of filename patterns vs corresponding `server-window'. - -Each element looks like (REGEXP . FUNCTION). Files matching -REGEXP are selected using FUNCTION instead of the default in -`server-window'. - -Note that when a package adds an entry here then it probably -has a reason to disrespect `server-window' and it likely is -not a good idea to change such entries.") - -(defvar with-editor-file-name-history-exclude nil - "List of regexps for filenames `server-visit' should not remember. -When a filename matches any of the regexps, then `server-visit' -does not add it to the variable `file-name-history', which is -used when reading a filename in the minibuffer.") - -;;; Mode Commands - -(defvar with-editor-pre-finish-hook nil) -(defvar with-editor-pre-cancel-hook nil) -(defvar with-editor-post-finish-hook nil) -(defvar with-editor-post-finish-hook-1 nil) -(defvar with-editor-post-cancel-hook nil) -(defvar with-editor-post-cancel-hook-1 nil) -(defvar with-editor-cancel-alist nil) -(put 'with-editor-pre-finish-hook 'permanent-local t) -(put 'with-editor-pre-cancel-hook 'permanent-local t) -(put 'with-editor-post-finish-hook 'permanent-local t) -(put 'with-editor-post-cancel-hook 'permanent-local t) - -(defvar with-editor-show-usage t) -(defvar with-editor-cancel-message nil) -(defvar with-editor-previous-winconf nil) -(make-variable-buffer-local 'with-editor-show-usage) -(make-variable-buffer-local 'with-editor-cancel-message) -(make-variable-buffer-local 'with-editor-previous-winconf) -(put 'with-editor-cancel-message 'permanent-local t) -(put 'with-editor-previous-winconf 'permanent-local t) - -(defvar-local with-editor--pid nil "For internal use.") -(put 'with-editor--pid 'permanent-local t) - -(defun with-editor-finish (force) - "Finish the current edit session." - (interactive "P") - (when (run-hook-with-args-until-failure - 'with-editor-finish-query-functions force) - (let ((with-editor-post-finish-hook-1 - (ignore-errors (delq t with-editor-post-finish-hook)))) - (run-hooks 'with-editor-pre-finish-hook) - (with-editor-return nil) - (accept-process-output nil 0.1) - (run-hooks 'with-editor-post-finish-hook-1)))) - -(defun with-editor-cancel (force) - "Cancel the current edit session." - (interactive "P") - (when (run-hook-with-args-until-failure - 'with-editor-cancel-query-functions force) - (let ((message with-editor-cancel-message)) - (when (functionp message) - (setq message (funcall message))) - (let ((with-editor-post-cancel-hook-1 - (ignore-errors (delq t with-editor-post-cancel-hook))) - (with-editor-cancel-alist nil)) - (run-hooks 'with-editor-pre-cancel-hook) - (with-editor-return t) - (accept-process-output nil 0.1) - (run-hooks 'with-editor-post-cancel-hook-1)) - (message (or message "Canceled by user"))))) - -(defun with-editor-return (cancel) - (let ((winconf with-editor-previous-winconf) - (clients server-buffer-clients) - (dir default-directory) - (pid with-editor--pid)) - (remove-hook 'kill-buffer-query-functions - 'with-editor-kill-buffer-noop t) - (cond (cancel - (save-buffer) - (if clients - (dolist (client clients) - (ignore-errors - (server-send-string client "-error Canceled by user")) - (delete-process client)) - ;; Fallback for when emacs was used as $EDITOR - ;; instead of emacsclient or the sleeping editor. - ;; See https://github.com/magit/magit/issues/2258. - (ignore-errors (delete-file buffer-file-name)) - (kill-buffer))) - (t - (save-buffer) - (if clients - ;; Don't use `server-edit' because we do not want to - ;; show another buffer belonging to another client. - ;; See https://github.com/magit/magit/issues/2197. - (server-done) - (kill-buffer)))) - (when pid - (let ((default-directory dir)) - (process-file "kill" nil nil nil - "-s" (if cancel "USR2" "USR1") pid))) - (when (and winconf (eq (window-configuration-frame winconf) - (selected-frame))) - (set-window-configuration winconf)))) - -;;; Mode - -(defvar with-editor-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-c" 'with-editor-finish) - (define-key map [remap server-edit] 'with-editor-finish) - (define-key map [remap evil-save-and-close] 'with-editor-finish) - (define-key map [remap evil-save-modified-and-close] 'with-editor-finish) - (define-key map "\C-c\C-k" 'with-editor-cancel) - (define-key map [remap kill-buffer] 'with-editor-cancel) - (define-key map [remap ido-kill-buffer] 'with-editor-cancel) - (define-key map [remap iswitchb-kill-buffer] 'with-editor-cancel) - (define-key map [remap evil-quit] 'with-editor-cancel) - map)) - -(define-minor-mode with-editor-mode - "Edit a file as the $EDITOR of an external process." - :lighter with-editor-mode-lighter - ;; Protect the user from killing the buffer without using - ;; either `with-editor-finish' or `with-editor-cancel', - ;; and from removing the key bindings for these commands. - (unless with-editor-mode - (user-error "With-Editor mode cannot be turned off")) - (add-hook 'kill-buffer-query-functions - 'with-editor-kill-buffer-noop nil t) - ;; `server-execute' displays a message which is not - ;; correct when using this mode. - (when with-editor-show-usage - (with-editor-usage-message))) - -(put 'with-editor-mode 'permanent-local t) - -(defun with-editor-kill-buffer-noop () - (user-error (substitute-command-keys "\ -Don't kill this buffer. Instead cancel using \\[with-editor-cancel]"))) - -(defun with-editor-usage-message () - ;; Run after `server-execute', which is run using - ;; a timer which starts immediately. - (run-with-timer - 0.01 nil `(lambda () - (with-current-buffer ,(current-buffer) - (message (substitute-command-keys "\ -Type \\[with-editor-finish] to finish, \ -or \\[with-editor-cancel] to cancel")))))) - -;;; Wrappers - -(defvar with-editor--envvar nil "For internal use.") - -(defmacro with-editor (&rest body) - "Use the Emacsclient as $EDITOR while evaluating BODY. -Modify the `process-environment' for processes started in BODY, -instructing them to use the Emacsclient as $EDITOR. If optional -ENVVAR is provided then bind that environment variable instead. -\n(fn [ENVVAR] BODY...)" - (declare (indent defun) (debug (body))) - `(let ((with-editor--envvar ,(if (stringp (car body)) - (pop body) - '(or with-editor--envvar "EDITOR"))) - (process-environment process-environment)) - (with-editor--setup) - ,@body)) - -(defun with-editor--setup () - (if (or (not with-editor-emacsclient-executable) - (file-remote-p default-directory)) - (push (concat with-editor--envvar "=" with-editor-sleeping-editor) - process-environment) - ;; Make sure server-use-tcp's value is valid. - (unless (featurep 'make-network-process '(:family local)) - (setq server-use-tcp t)) - ;; Make sure the server is running. - (unless server-process - (when (server-running-p server-name) - (setq server-name (format "server%s" (emacs-pid))) - (when (server-running-p server-name) - (server-force-delete server-name))) - (server-start)) - ;; Tell $EDITOR to use the Emacsclient. - (push (concat with-editor--envvar "=" - (shell-quote-argument with-editor-emacsclient-executable) - ;; Tell the process where the server file is. - (and (not server-use-tcp) - (concat " --socket-name=" - (shell-quote-argument - (expand-file-name server-name - server-socket-dir))))) - process-environment) - (when server-use-tcp - (push (concat "EMACS_SERVER_FILE=" - (expand-file-name server-name server-auth-dir)) - process-environment)) - ;; As last resort fallback to the sleeping editor. - (push (concat "ALTERNATE_EDITOR=" with-editor-sleeping-editor) - process-environment))) - -(defun with-editor-server-window () - (or (and buffer-file-name - (cdr (cl-find-if (lambda (cons) - (string-match-p (car cons) buffer-file-name)) - with-editor-server-window-alist))) - server-window)) - -(defun server-switch-buffer--with-editor-server-window-alist - (fn &optional next-buffer killed-one filepos) - "Honor `with-editor-server-window-alist' (which see)." - (let ((server-window (with-current-buffer - (or next-buffer (current-buffer)) - (when with-editor-mode - (setq with-editor-previous-winconf - (current-window-configuration))) - (with-editor-server-window)))) - (funcall fn next-buffer killed-one filepos))) - -(advice-add 'server-switch-buffer :around - 'server-switch-buffer--with-editor-server-window-alist) - -(defun start-file-process--with-editor-process-filter - (fn name buffer program &rest program-args) - "When called inside a `with-editor' form and the Emacsclient -cannot be used, then give the process the filter function -`with-editor-process-filter'. To avoid overriding the filter -being added here you should use `with-editor-set-process-filter' -instead of `set-process-filter' inside `with-editor' forms. - -When the `default-directory' is located on a remote machine, -then also manipulate PROGRAM and PROGRAM-ARGS in order to set -the appropriate editor environment variable." - (if (not with-editor--envvar) - (apply fn name buffer program program-args) - (when (file-remote-p default-directory) - (unless (equal program "env") - (push program program-args) - (setq program "env")) - (push (concat with-editor--envvar "=" with-editor-sleeping-editor) - program-args)) - (let ((process (apply fn name buffer program program-args))) - (set-process-filter process 'with-editor-process-filter) - (process-put process 'default-dir default-directory) - process))) - -(advice-add 'start-file-process :around - 'start-file-process--with-editor-process-filter) - -(defun with-editor-set-process-filter (process filter) - "Like `set-process-filter' but keep `with-editor-process-filter'. -Give PROCESS the new FILTER but keep `with-editor-process-filter' -if that was added earlier by the adviced `start-file-process'. - -Do so by wrapping the two filter functions using a lambda, which -becomes the actual filter. It calls `with-editor-process-filter' -first, passing t as NO-STANDARD-FILTER. Then it calls FILTER, -which may or may not insert the text into the PROCESS' buffer." - (set-process-filter - process - (if (eq (process-filter process) 'with-editor-process-filter) - `(lambda (proc str) - (,filter proc str) - (with-editor-process-filter proc str t)) - filter))) - -(defvar with-editor-filter-visit-hook nil) - -(defun with-editor-output-filter (string) - (save-match-data - (if (string-match "^WITH-EDITOR: \\([0-9]+\\) OPEN \\(.+?\\)\r?$" string) - (let ((pid (match-string 1 string)) - (file (match-string 2 string))) - (with-current-buffer - (find-file-noselect - (if (file-name-absolute-p file) - (concat (file-remote-p default-directory) file) - (expand-file-name file))) - (with-editor-mode 1) - (setq with-editor--pid pid) - (run-hooks 'with-editor-filter-visit-hook) - (funcall (or (with-editor-server-window) 'switch-to-buffer) - (current-buffer)) - (kill-local-variable 'server-window)) - nil) - string))) - -(defun with-editor-process-filter - (process string &optional no-default-filter) - "Listen for edit requests by child processes." - (let ((default-directory (process-get process 'default-dir))) - (with-editor-output-filter string)) - (unless no-default-filter - (internal-default-process-filter process string))) - -(advice-add 'server-visit-files :after - 'server-visit-files--with-editor-file-name-history-exclude) - -(defun server-visit-files--with-editor-file-name-history-exclude - (files _proc &optional _nowait) - (dolist (file files) - (setq file (car file)) - (when (cl-find-if (lambda (regexp) - (string-match-p regexp file)) - with-editor-file-name-history-exclude) - (setq file-name-history (delete file file-name-history))))) - -;;; Augmentations - -(cl-defun with-editor-export-editor (&optional (envvar "EDITOR")) - "Teach subsequent commands to use current Emacs instance as editor. - -Set and export the environment variable ENVVAR, by default -\"EDITOR\". The value is automatically generated to teach -commands to use the current Emacs instance as \"the editor\". - -This works in `shell-mode', `term-mode' and `eshell-mode'." - (interactive (list (with-editor-read-envvar))) - (cond - ((derived-mode-p 'comint-mode 'term-mode) - (let* ((process (get-buffer-process (current-buffer))) - (filter (process-filter process))) - (goto-char (process-mark process)) - (process-send-string - process (format " export %s=%s\n" envvar - (shell-quote-argument with-editor-sleeping-editor))) - (while (accept-process-output process 0.1)) - (set-process-filter process filter) - (if (derived-mode-p 'term-mode) - (with-editor-set-process-filter process 'with-editor-emulate-terminal) - (add-hook 'comint-output-filter-functions 'with-editor-output-filter - nil t)))) - ((derived-mode-p 'eshell-mode) - (add-to-list 'eshell-preoutput-filter-functions - 'with-editor-output-filter) - (setenv envvar with-editor-sleeping-editor)) - (t - (error "Cannot export environment variables in this buffer"))) - (message "Successfully exported %s" envvar)) - -(defun with-editor-export-git-editor () - "Like `with-editor-export-editor' but always set `$GIT_EDITOR'." - (interactive) - (with-editor-export-editor "GIT_EDITOR")) - -(defun with-editor-export-hg-editor () - "Like `with-editor-export-editor' but always set `$HG_EDITOR'." - (interactive) - (with-editor-export-editor "HG_EDITOR")) - -(defun with-editor-emulate-terminal (process string) - "Like `term-emulate-terminal' but also handle edit requests." - (when (with-editor-output-filter string) - (term-emulate-terminal process string))) - -(defvar with-editor-envvars '("EDITOR" "GIT_EDITOR" "HG_EDITOR")) - -(cl-defun with-editor-read-envvar - (&optional (prompt "Set environment variable") - (default "EDITOR")) - (let ((reply (completing-read (if default - (format "%s (%s): " prompt default) - (concat prompt ": ")) - with-editor-envvars nil nil nil nil default))) - (if (string= reply "") (user-error "Nothing selected") reply))) - -(define-minor-mode shell-command-with-editor-mode - "Teach `shell-command' to use current Emacs instance as editor. - -Teach `shell-command', and all commands that ultimately call that -command, to use the current Emacs instance as editor by executing -\"EDITOR=CLIENT COMMAND&\" instead of just \"COMMAND&\". - -CLIENT is automatically generated; EDITOR=CLIENT instructs -COMMAND to use to the current Emacs instance as \"the editor\", -assuming no other variable overrides the effect of \"$EDITOR\". -CLIENT may be the path to an appropriate emacsclient executable -with arguments, or a script which also works over Tramp. - -Alternatively you can use the `with-editor-async-shell-command', -which also allows the use of another variable instead of -\"EDITOR\"." - :global t) - -(defun with-editor-async-shell-command - (command &optional output-buffer error-buffer envvar) - "Like `async-shell-command' but with `$EDITOR' set. - -Execute string \"ENVVAR=CLIENT COMMAND\" in an inferior shell; -display output, if any. With a prefix argument prompt for an -environment variable, otherwise the default \"EDITOR\" variable -is used. With a negative prefix argument additionally insert -the COMMAND's output at point. - -CLIENT is automatically generated; ENVVAR=CLIENT instructs -COMMAND to use to the current Emacs instance as \"the editor\", -assuming it respects ENVVAR as an \"EDITOR\"-like variable. -CLIENT maybe the path to an appropriate emacsclient executable -with arguments, or a script which also works over Tramp. - -Also see `async-shell-command' and `shell-command'." - (interactive (with-editor-shell-command-read-args "Async shell command: " t)) - (let ((with-editor--envvar envvar)) - (with-editor - (async-shell-command command output-buffer error-buffer)))) - -(defun with-editor-shell-command - (command &optional output-buffer error-buffer envvar) - "Like `shell-command' or `with-editor-async-shell-command'. -If COMMAND ends with \"&\" behave like the latter, -else like the former." - (interactive (with-editor-shell-command-read-args "Shell command: ")) - (if (string-match "&[ \t]*\\'" command) - (with-editor-async-shell-command - command output-buffer error-buffer envvar) - (shell-command command output-buffer error-buffer))) - -(defun with-editor-shell-command-read-args (prompt &optional async) - (let ((command (read-shell-command - prompt nil nil - (let ((filename (or buffer-file-name - (and (eq major-mode 'dired-mode) - (dired-get-filename nil t))))) - (and filename (file-relative-name filename)))))) - (list command - (if (or async (setq async (string-match-p "&[ \t]*\\'" command))) - (< (prefix-numeric-value current-prefix-arg) 0) - current-prefix-arg) - shell-command-default-error-buffer - (and async current-prefix-arg (with-editor-read-envvar))))) - -(defun shell-command--shell-command-with-editor-mode - (fn command &optional output-buffer error-buffer) - ;; `shell-mode' and its hook are intended for buffers in which an - ;; interactive shell is running, but `shell-command' also turns on - ;; that mode, even though it only runs the shell to run a single - ;; command. The `with-editor-export-editor' hook function is only - ;; intended to be used in buffers in which an interactive shell is - ;; running, so it has to be remove here. - (let ((shell-mode-hook (remove 'with-editor-export-editor shell-mode-hook))) - (cond ((or (not (or with-editor--envvar shell-command-with-editor-mode)) - (not (string-match-p "&\\'" command))) - (funcall fn command output-buffer error-buffer)) - ((and with-editor-emacsclient-executable - (not (file-remote-p default-directory))) - (with-editor (funcall fn command output-buffer error-buffer))) - (t - (apply fn (format "%s=%s %s" - (or with-editor--envvar "EDITOR") - (shell-quote-argument with-editor-sleeping-editor) - command) - output-buffer error-buffer) - (ignore-errors - (let ((process (get-buffer-process - (or output-buffer - (get-buffer "*Async Shell Command*"))))) - (set-process-filter - process (lambda (proc str) - (comint-output-filter proc str) - (with-editor-process-filter proc str t))) - process)))))) - -(advice-add 'shell-command :around - 'shell-command--shell-command-with-editor-mode) - -;;; with-editor.el ends soon - -(defun with-editor-debug () - "Debug configuration issues. -See info node `(with-editor)Debugging' for instructions." - (interactive) - (with-current-buffer (get-buffer-create "*with-editor-debug*") - (pop-to-buffer (current-buffer)) - (erase-buffer) - (ignore-errors (with-editor)) - (insert - (format "with-editor: %s\n" (locate-library "with-editor.el")) - (format "emacs: %s (%s)\n" - (expand-file-name invocation-name invocation-directory) - emacs-version) - "system:\n" - (format " system-type: %s\n" system-type) - (format " system-configuration: %s\n" system-configuration) - (format " system-configuration-options: %s\n" system-configuration-options) - "server:\n" - (format " server-running-p: %s\n" (server-running-p)) - (format " server-process: %S\n" server-process) - (format " server-use-tcp: %s\n" server-use-tcp) - (format " server-name: %s\n" server-name) - (format " server-socket-dir: %s\n" server-socket-dir)) - (if (and server-socket-dir (file-accessible-directory-p server-socket-dir)) - (dolist (file (directory-files server-socket-dir nil "^[^.]")) - (insert (format " %s\n" file))) - (insert (format " %s: not an accessible directory\n" - (if server-use-tcp "WARNING" "ERROR")))) - (insert (format " server-auth-dir: %s\n" server-auth-dir)) - (if (file-accessible-directory-p server-auth-dir) - (dolist (file (directory-files server-auth-dir nil "^[^.]")) - (insert (format " %s\n" file))) - (insert (format " %s: not an accessible directory\n" - (if server-use-tcp "ERROR" "WARNING")))) - (let ((val with-editor-emacsclient-executable) - (def (default-value 'with-editor-emacsclient-executable)) - (fun (let ((warning-minimum-level :error) - (warning-minimum-log-level :error)) - (with-editor-locate-emacsclient)))) - (insert "with-editor-emacsclient-executable:\n" - (format " value: %s (%s)\n" val - (and val (with-editor-emacsclient-version val))) - (format " default: %s (%s)\n" def - (and def (with-editor-emacsclient-version def))) - (format " funcall: %s (%s)\n" fun - (and fun (with-editor-emacsclient-version fun))))) - (insert "path:\n" - (format " $PATH: %S\n" (getenv "PATH")) - (format " exec-path: %s\n" exec-path)) - (insert (format " with-editor-emacsclient-path:\n")) - (dolist (dir (with-editor-emacsclient-path)) - (insert (format " %s (%s)\n" dir (car (file-attributes dir)))) - (when (file-directory-p dir) - ;; Don't match emacsclientw.exe, it makes popup windows. - (dolist (exec (directory-files dir t "emacsclient\\(?:[^w]\\|\\'\\)")) - (insert (format " %s (%s)\n" exec - (with-editor-emacsclient-version exec)))))))) - -(defconst with-editor-font-lock-keywords - '(("(\\(with-\\(?:git-\\)?editor\\)\\_>" (1 'font-lock-keyword-face)))) -(font-lock-add-keywords 'emacs-lisp-mode with-editor-font-lock-keywords) - -(provide 'with-editor) -;; Local Variables: -;; indent-tabs-mode: nil -;; End: -;;; with-editor.el ends here diff --git a/elpa/with-editor-20170817.1240/with-editor.info b/elpa/with-editor-20170817.1240/with-editor.info deleted file mode 100644 index e4d614d1..00000000 --- a/elpa/with-editor-20170817.1240/with-editor.info +++ /dev/null @@ -1,328 +0,0 @@ -This is with-editor.info, produced by makeinfo version 5.2 from -with-editor.texi. - - Copyright (C) 2015-2017 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. -INFO-DIR-SECTION Emacs -START-INFO-DIR-ENTRY -* With-Editor: (with-editor). Using the Emacsclient as $EDITOR. -END-INFO-DIR-ENTRY - - -File: with-editor.info, Node: Top, Next: Using the With-Editor package, Up: (dir) - -With-Editor User Manual -*********************** - -The library ‘with-editor’ makes it easy to use the Emacsclient as the -‘$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. - - Copyright (C) 2015-2017 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. - -* Menu: - -* Using the With-Editor package:: -* Using With-Editor as a library:: -* Debugging:: - -— The Detailed Node Listing — - -Using the With-Editor package - -* Configuring With-Editor:: -* Using With-Editor commands:: - - -File: with-editor.info, Node: Using the With-Editor package, Next: Using With-Editor as a library, Prev: Top, Up: Top - -1 Using the With-Editor package -******************************* - -The ‘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 you own package, see -*note Using With-Editor as a library::. - -* Menu: - -* Configuring With-Editor:: -* Using With-Editor commands:: - - -File: with-editor.info, Node: Configuring With-Editor, Next: Using With-Editor commands, Up: Using the With-Editor package - -1.1 Configuring With-Editor -=========================== - -With-Editor tries very hard to locate a suitable ‘emacsclient’ -executable, so ideally you should never have to customize the option -‘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 ‘$PATH’, -and we have to add another kludge to find it anyway. - - -- User Option: with-editor-emacsclient-executable - - The ‘emacsclient’ executable used as the editor by child process 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 - ‘exec-path’, and other places where the executable could be - installed, to find the ‘emacsclient’ executable most suitable for - the current Emacs instance. - - You should *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 *note Debugging::. - - If With-Editor fails to find a suitable ‘emacsclient’ on you - system, then this should be fixed for all users at once, by - teaching ‘with-editor-locate-emacsclient’ how to do so on your - system and system 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 - ‘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 you setup. - - -- Function: with-editor-locate-emacsclient - - The function used to set the initial value of the option - ‘with-editor-emacsclient-executable’. There’s a lot of voodoo - here. - - The ‘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 -‘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. - - -- User Option: with-editor-sleeping-editor - - The sleeping editor is a shell script used as the editor of child - processes when the ‘emacsclient’ executable cannot be used. - - This fallback is used for asynchronous process started inside the - macro ‘with-editor’, when the process runs on a remote machine or - for local processes when ‘with-editor-emacsclient-executable’ is - ‘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 ‘emacsclient’, it can only - be used as ‘$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. ‘csh’ on FreeBSD, but not Debian), - then you have to edit this option. You can either replace ‘sh’ - with ‘bash’ (and install that), or you can use the older, less - performant implementation: - - "sh -c '\ - echo \"WITH-EDITOR: $$ OPEN $0\"; \ - trap \"exit 0\" USR1; \ - trap \"exit 1\" USR2; \ - while true; do sleep 1; done'" - - This leads to a delay of up to a second. The delay can be - shortened by replacing ‘sleep 1’ with ‘sleep 0.01’, or if your - implementation does not support floats, then by using ‘nanosleep - 0.01’ instead. - - -File: with-editor.info, Node: Using With-Editor commands, Prev: Configuring With-Editor, Up: Using the With-Editor package - -1.2 Using With-Editor commands -============================== - -This section describes how to use the ‘with-editor’ library _outside_ of -Magit. You don’t need to know any of this just to create commits using -Magit. - - The commands ‘with-editor-async-shell-command’ and -‘with-editor-shell-command’ are intended as drop in replacements for -‘async-shell-command’ and ‘shell-command’. They automatically export -‘$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 ‘$GIT_EDITOR’. - - -- Command: with-editor-async-shell-command - - This command is like ‘async-shell-command’, but it runs the shell - command with the current Emacs instance exported as ‘$EDITOR’. - - -- Command: with-editor-shell-command - - This command is like ‘async-shell-command’, but it runs the shell - command with the current Emacs instance exported as ‘$EDITOR’. - This only has an effect if the shell command is run asynchronously, - i.e. when the command ends with ‘&’. - - To always use these variants add this to you init file: - - (define-key (current-global-map) - [remap async-shell-command] 'with-editor-async-shell-command) - (define-key (current-global-map) - [remap shell-command] 'with-editor-shell-command) - - Alternatively use the global ‘shell-command-with-editor-mode’. - - -- Variable: shell-command-with-editor-mode - - When this mode is active, then ‘$EDITOR’ is exported whenever - ultimately ‘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. - - The command ‘with-editor-export-editor’ exports ‘$EDITOR’ or another -such environment variable in ‘shell-mode’, ‘term-mode’ and ‘eshell-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: - - (add-hook 'shell-mode-hook 'with-editor-export-editor) - (add-hook 'term-exec-hook 'with-editor-export-editor) - (add-hook 'eshell-mode-hook 'with-editor-export-editor) - - Some variants of this function exist; these two forms are equivalent: - - (add-hook 'shell-mode-hook - (apply-partially 'with-editor-export-editor "GIT_EDITOR")) - (add-hook 'shell-mode-hook 'with-editor-export-git-editor) - - -- Command: with-editor-export-editor - - When invoked in a ‘shell-mode’, ‘term-mode’, or ‘eshell-mode’ - buffer, this command teaches shell commands to use the current - Emacs instance as the editor, by exporting ‘$EDITOR’. - - -- Command: with-editor-export-git-editor - - This command is like ‘with-editor-export-editor’ but exports - ‘$GIT_EDITOR’. - - -- Command: with-editor-export-hg-editor - - This command is like ‘with-editor-export-editor’ but exports - ‘$HG_EDITOR’. - - -File: with-editor.info, Node: Using With-Editor as a library, Next: Debugging, Prev: Using the With-Editor package, Up: Top - -2 Using With-Editor as a library -******************************** - -This section describes how to use the ‘with-editor’ library _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 -‘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 *note Using the With-Editor -package::. - - -- Macro: with-editor &rest body - - This macro arranges for the ‘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 essentially done by establishing a local binding for - ‘process-environment’ and changing the value of the ‘$EDITOR’ - environment variable in that scope. This affects all asynchronous - processes started by forms (dynamically) inside BODY. - - -- Function: with-editor-set-process-filter process filter - - This function is like ‘set-process-filter’ but ensures that adding - the new FILTER does not remove the ‘with-editor-process-filter’. - This is done by wrapping the two filter functions using a lambda, - which becomes the actual filter. It calls - ‘with-editor-process-filter’ first, passing ‘t’ as - NO-STANDARD-FILTER. Then it calls FILTER. - - -File: with-editor.info, Node: Debugging, Prev: Using With-Editor as a library, Up: Top - -3 Debugging -*********** - -With-Editor tries very hard to locate a suitable ‘emacsclient’ -executable, and then sets option ‘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 ‘$PATH’, -and we have to add another kludge to find it anyway. - - If you are having problems using ‘with-editor’, e.g. you cannot -commit in Magit, then please open a new issue at - and provide information -about your Emacs installation. Most importantly how did you install -Emacs and what is the output of ‘M-x with-editor-debug RET’. - - - -Tag Table: -Node: Top771 -Node: Using the With-Editor package2462 -Node: Configuring With-Editor3048 -Node: Using With-Editor commands7445 -Node: Using With-Editor as a library10708 -Node: Debugging12403 - -End Tag Table - - -Local Variables: -coding: utf-8 -End: diff --git a/elpa/with-editor-20181113.1845/dir b/elpa/with-editor-20181113.1845/dir new file mode 100644 index 00000000..c5810e07 --- /dev/null +++ b/elpa/with-editor-20181113.1845/dir @@ -0,0 +1,18 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "H" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: + +Emacs +* With-Editor: (with-editor). Using the Emacsclient as $EDITOR. diff --git a/elpa/with-editor-20181113.1845/with-editor-autoloads.el b/elpa/with-editor-20181113.1845/with-editor-autoloads.el new file mode 100644 index 00000000..cdfafa8e --- /dev/null +++ b/elpa/with-editor-20181113.1845/with-editor-autoloads.el @@ -0,0 +1,99 @@ +;;; with-editor-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "with-editor" "with-editor.el" (0 0 0 0)) +;;; Generated autoloads from with-editor.el + +(autoload 'with-editor-export-editor "with-editor" "\ +Teach subsequent commands to use current Emacs instance as editor. + +Set and export the environment variable ENVVAR, by default +\"EDITOR\". The value is automatically generated to teach +commands to use the current Emacs instance as \"the editor\". + +This works in `shell-mode', `term-mode' and `eshell-mode'. + +\(fn &optional (ENVVAR \"EDITOR\"))" t nil) + +(autoload 'with-editor-export-git-editor "with-editor" "\ +Like `with-editor-export-editor' but always set `$GIT_EDITOR'. + +\(fn)" t nil) + +(autoload 'with-editor-export-hg-editor "with-editor" "\ +Like `with-editor-export-editor' but always set `$HG_EDITOR'. + +\(fn)" t nil) + +(defvar shell-command-with-editor-mode nil "\ +Non-nil if Shell-Command-With-Editor mode is enabled. +See the `shell-command-with-editor-mode' command +for a description of this minor mode.") + +(custom-autoload 'shell-command-with-editor-mode "with-editor" nil) + +(autoload 'shell-command-with-editor-mode "with-editor" "\ +Teach `shell-command' to use current Emacs instance as editor. + +Teach `shell-command', and all commands that ultimately call that +command, to use the current Emacs instance as editor by executing +\"EDITOR=CLIENT COMMAND&\" instead of just \"COMMAND&\". + +CLIENT is automatically generated; EDITOR=CLIENT instructs +COMMAND to use to the current Emacs instance as \"the editor\", +assuming no other variable overrides the effect of \"$EDITOR\". +CLIENT may be the path to an appropriate emacsclient executable +with arguments, or a script which also works over Tramp. + +Alternatively you can use the `with-editor-async-shell-command', +which also allows the use of another variable instead of +\"EDITOR\". + +\(fn &optional ARG)" t nil) + +(autoload 'with-editor-async-shell-command "with-editor" "\ +Like `async-shell-command' but with `$EDITOR' set. + +Execute string \"ENVVAR=CLIENT COMMAND\" in an inferior shell; +display output, if any. With a prefix argument prompt for an +environment variable, otherwise the default \"EDITOR\" variable +is used. With a negative prefix argument additionally insert +the COMMAND's output at point. + +CLIENT is automatically generated; ENVVAR=CLIENT instructs +COMMAND to use to the current Emacs instance as \"the editor\", +assuming it respects ENVVAR as an \"EDITOR\"-like variable. +CLIENT may be the path to an appropriate emacsclient executable +with arguments, or a script which also works over Tramp. + +Also see `async-shell-command' and `shell-command'. + +\(fn COMMAND &optional OUTPUT-BUFFER ERROR-BUFFER ENVVAR)" t nil) + +(autoload 'with-editor-shell-command "with-editor" "\ +Like `shell-command' or `with-editor-async-shell-command'. +If COMMAND ends with \"&\" behave like the latter, +else like the former. + +\(fn COMMAND &optional OUTPUT-BUFFER ERROR-BUFFER ENVVAR)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "with-editor" '("with-editor" "start-file-process--with-editor-process-filter" "server-" "shell-command--shell-command-with-editor-mode"))) + +;;;*** + +;;;### (autoloads nil nil ("with-editor-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; with-editor-autoloads.el ends here diff --git a/elpa/with-editor-20181113.1845/with-editor-pkg.el b/elpa/with-editor-20181113.1845/with-editor-pkg.el new file mode 100644 index 00000000..b74275f3 --- /dev/null +++ b/elpa/with-editor-20181113.1845/with-editor-pkg.el @@ -0,0 +1,13 @@ +(define-package "with-editor" "20181113.1845" "Use the Emacsclient as $EDITOR" + '((emacs "24.4") + (async "1.9")) + :keywords + '("tools") + :authors + '(("Jonas Bernoulli" . "jonas@bernoul.li")) + :maintainer + '("Jonas Bernoulli" . "jonas@bernoul.li") + :url "https://github.com/magit/with-editor") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/with-editor-20181113.1845/with-editor.el b/elpa/with-editor-20181113.1845/with-editor.el new file mode 100644 index 00000000..80929d5d --- /dev/null +++ b/elpa/with-editor-20181113.1845/with-editor.el @@ -0,0 +1,852 @@ +;;; with-editor.el --- Use the Emacsclient as $EDITOR -*- lexical-binding: t -*- + +;; Copyright (C) 2014-2018 The Magit Project Contributors +;; +;; You should have received a copy of the AUTHORS.md file. If not, +;; see https://github.com/magit/with-editor/blob/master/AUTHORS.md. + +;; Author: Jonas Bernoulli +;; Maintainer: Jonas Bernoulli + +;; Package-Requires: ((emacs "24.4") (async "1.9")) +;; Keywords: tools +;; Homepage: https://github.com/magit/with-editor + +;; This file is not part of GNU Emacs. + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; This file 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. + +;; You should have received a copy of the GNU General Public License +;; along with Magit. If not, see http://www.gnu.org/licenses. + +;;; Commentary: + +;; This library makes it possible to reliably use the Emacsclient as +;; the `$EDITOR' of child processes. It makes sure that they know how +;; to call home. For remote processes a substitute is provided, which +;; communicates with Emacs on standard output/input instead of using a +;; socket as the Emacsclient does. + +;; It provides the commands `with-editor-async-shell-command' and +;; `with-editor-shell-command', which are intended as replacements +;; for `async-shell-command' and `shell-command'. They automatically +;; export `$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 +;; `$GIT_EDITOR'. To always use these variants add this to your init +;; file: +;; +;; (define-key (current-global-map) +;; [remap async-shell-command] 'with-editor-async-shell-command) +;; (define-key (current-global-map) +;; [remap shell-command] 'with-editor-shell-command) + +;; Alternatively use the global `shell-command-with-editor-mode', +;; which always sets `$EDITOR' for all Emacs commands which ultimately +;; use `shell-command' to asynchronously run some shell command. + +;; The command `with-editor-export-editor' exports `$EDITOR' or +;; another such environment variable in `shell-mode', `term-mode' and +;; `eshell-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: +;; +;; (add-hook 'shell-mode-hook 'with-editor-export-editor) +;; (add-hook 'term-exec-hook 'with-editor-export-editor) +;; (add-hook 'eshell-mode-hook 'with-editor-export-editor) + +;; Some variants of this function exist, these two forms are +;; equivalent: +;; +;; (add-hook 'shell-mode-hook +;; (apply-partially 'with-editor-export-editor "GIT_EDITOR")) +;; (add-hook 'shell-mode-hook 'with-editor-export-git-editor) + +;; This library can also be used by other packages which need to use +;; the current Emacs instance as editor. In fact this library was +;; written for Magit and its `git-commit-mode' and `git-rebase-mode'. +;; Consult `git-rebase.el' and the related code in `magit-sequence.el' +;; for a simple example. + +;;; Code: + +(require 'cl-lib) +;; `pcase-dolist' is not autoloaded on Emacs 24. +(eval-when-compile (require 'pcase)) +(require 'server) +(require 'shell) + +(and (require 'async-bytecomp nil t) + (memq 'magit (bound-and-true-p async-bytecomp-allowed-packages)) + (fboundp 'async-bytecomp-package-mode) + (async-bytecomp-package-mode 1)) + +(eval-when-compile + (progn (require 'dired nil t) + (require 'eshell nil t) + (require 'term nil t) + (require 'warnings nil t))) +(declare-function dired-get-filename 'dired) +(declare-function term-emulate-terminal 'term) +(defvar eshell-preoutput-filter-functions) + +;;; Options + +(defgroup with-editor nil + "Use the Emacsclient as $EDITOR." + :group 'external + :group 'server) + +(defun with-editor-locate-emacsclient () + "Search for a suitable Emacsclient executable." + (or (with-editor-locate-emacsclient-1 + (with-editor-emacsclient-path) + (length (split-string emacs-version "\\."))) + (prog1 nil (display-warning 'with-editor "\ +Cannot determine a suitable Emacsclient + +Determining an Emacsclient executable suitable for the +current Emacs instance failed. For more information +please see https://github.com/magit/magit/wiki/Emacsclient.")))) + +(defun with-editor-locate-emacsclient-1 (path depth) + (let* ((version-lst (cl-subseq (split-string emacs-version "\\.") 0 depth)) + (version-reg (concat "^" (mapconcat #'identity version-lst "\\.")))) + (or (locate-file-internal + (if (equal (downcase invocation-name) "remacs") + "remacsclient" + "emacsclient") + path + (cl-mapcan + (lambda (v) (cl-mapcar (lambda (e) (concat v e)) exec-suffixes)) + (nconc (and (boundp 'debian-emacs-flavor) + (list (format ".%s" debian-emacs-flavor))) + (cl-mapcon (lambda (v) + (setq v (mapconcat #'identity (reverse v) ".")) + (list v (concat "-" v) (concat ".emacs" v))) + (reverse version-lst)) + (list "" "-snapshot" ".emacs-snapshot"))) + (lambda (exec) + (ignore-errors + (string-match-p version-reg + (with-editor-emacsclient-version exec))))) + (and (> depth 1) + (with-editor-locate-emacsclient-1 path (1- depth)))))) + +(defun with-editor-emacsclient-version (exec) + (let ((default-directory (file-name-directory exec))) + (ignore-errors + (cadr (split-string (car (process-lines exec "--version"))))))) + +(defun with-editor-emacsclient-path () + (let ((path exec-path)) + (when invocation-directory + (push (directory-file-name invocation-directory) path) + (let* ((linkname (expand-file-name invocation-name invocation-directory)) + (truename (file-chase-links linkname))) + (unless (equal truename linkname) + (push (directory-file-name (file-name-directory truename)) path))) + (when (eq system-type 'darwin) + (let ((dir (expand-file-name "bin" invocation-directory))) + (when (file-directory-p dir) + (push dir path))) + (when (string-match-p "Cellar" invocation-directory) + (let ((dir (expand-file-name "../../../bin" invocation-directory))) + (when (file-directory-p dir) + (push dir path)))))) + (cl-remove-duplicates path :test 'equal))) + +(defcustom with-editor-emacsclient-executable (with-editor-locate-emacsclient) + "The Emacsclient executable used by the `with-editor' macro." + :group 'with-editor + :type '(choice (string :tag "Executable") + (const :tag "Don't use Emacsclient" nil))) + +(defcustom with-editor-sleeping-editor "\ +sh -c '\ +echo \"WITH-EDITOR: $$ OPEN $0 IN $(pwd)\"; \ +sleep 604800 & sleep=$!; \ +trap \"kill $sleep; exit 0\" USR1; \ +trap \"kill $sleep; exit 1\" USR2; \ +wait $sleep'" + "The sleeping editor, used when the Emacsclient cannot be used. + +This fallback is used for asynchronous processes started inside +the macro `with-editor', when the process runs on a remote machine +or for local processes when `with-editor-emacsclient-executable' +is nil (i.e. when no suitable Emacsclient was found, or the user +decided not to use it). + +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 Emacsclient, it can only +be used as $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. `csh' on FreeBSD, but not Debian), +then you have to edit this option. You can either replace \"sh\" +with \"bash\" (and install that), or you can use the older, less +performant implementation: + + \"sh -c '\\ + echo \\\"WITH-EDITOR: $$ OPEN $0 IN $(pwd)\\\"; \\ + trap \\\"exit 0\\\" USR1; \\ + trap \\\"exit 1\" USR2; \\ + while true; do sleep 1; done'\" + +Note that the unit seperator 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 +\"sleep 1\" with \"sleep 0.01\", or if your implementation does +not support floats, then by using \"nanosleep\" instead." + :package-version '(with-editor . "2.8.0") + :group 'with-editor + :type 'string) + +(defcustom with-editor-finish-query-functions nil + "List of functions called to query before finishing session. + +The buffer in question is current while the functions are called. +If any of them returns nil, then the session is not finished and +the buffer is not killed. The user should then fix the issue and +try again. The functions are called with one argument. If it is +non-nil then that indicates that the user used a prefix argument +to force finishing the session despite issues. Functions should +usually honor that and return non-nil." + :group 'with-editor + :type 'hook) +(put 'with-editor-finish-query-functions 'permanent-local t) + +(defcustom with-editor-cancel-query-functions nil + "List of functions called to query before canceling session. + +The buffer in question is current while the functions are called. +If any of them returns nil, then the session is not canceled and +the buffer is not killed. The user should then fix the issue and +try again. The functions are called with one argument. If it is +non-nil then that indicates that the user used a prefix argument +to force canceling the session despite issues. Functions should +usually honor that and return non-nil." + :group 'with-editor + :type 'hook) +(put 'with-editor-cancel-query-functions 'permanent-local t) + +(defcustom with-editor-mode-lighter " WE" + "The mode-line lighter of the With-Editor mode." + :group 'with-editor + :type '(choice (const :tag "No lighter" "") string)) + +(defvar with-editor-server-window-alist nil + "Alist of filename patterns vs corresponding `server-window'. + +Each element looks like (REGEXP . FUNCTION). Files matching +REGEXP are selected using FUNCTION instead of the default in +`server-window'. + +Note that when a package adds an entry here then it probably +has a reason to disrespect `server-window' and it likely is +not a good idea to change such entries.") + +(defvar with-editor-file-name-history-exclude nil + "List of regexps for filenames `server-visit' should not remember. +When a filename matches any of the regexps, then `server-visit' +does not add it to the variable `file-name-history', which is +used when reading a filename in the minibuffer.") + +(defcustom with-editor-shell-command-use-emacsclient t + "Whether to use the emacsclient when running shell commands. + +This affects `with-editor-shell-command-async' and, if the input +ends with \"&\" `with-editor-shell-command' . + +If `shell-command-with-editor-mode' is enabled, then it also +affects `shell-command-async' and, if the input ends with \"&\" +`shell-command'. + +This is a temporary kludge that lets you choose between two +possible defects, the ones described in the issues #23 and #40. + +When t, then use the emacsclient. This has the disadvantage that +`with-editor-mode' won't be enabled because we don't know whether +this package was involved at all in the call to the emacsclient, +and when it is not, then we really should. The problem is that +the emacsclient doesn't pass a long any environment variables to +the server. This will hopefully be fixed in Emacs eventually. + +When nil, then use the sleeping editor. Because in this case we +know that this package is involved, we can enable the mode. But +this makes it necessary that you invoke $EDITOR in shell scripts +like so: + + eval \"$EDITOR\" file + +And some tools that do not handle $EDITOR properly also break." + :package-version '(with-editor . "2.7.1") + :group 'with-editor + :type 'boolean) + +;;; Mode Commands + +(defvar with-editor-pre-finish-hook nil) +(defvar with-editor-pre-cancel-hook nil) +(defvar with-editor-post-finish-hook nil) +(defvar with-editor-post-finish-hook-1 nil) +(defvar with-editor-post-cancel-hook nil) +(defvar with-editor-post-cancel-hook-1 nil) +(defvar with-editor-cancel-alist nil) +(put 'with-editor-pre-finish-hook 'permanent-local t) +(put 'with-editor-pre-cancel-hook 'permanent-local t) +(put 'with-editor-post-finish-hook 'permanent-local t) +(put 'with-editor-post-cancel-hook 'permanent-local t) + +(defvar with-editor-show-usage t) +(defvar with-editor-cancel-message nil) +(defvar with-editor-previous-winconf nil) +(make-variable-buffer-local 'with-editor-show-usage) +(make-variable-buffer-local 'with-editor-cancel-message) +(make-variable-buffer-local 'with-editor-previous-winconf) +(put 'with-editor-cancel-message 'permanent-local t) +(put 'with-editor-previous-winconf 'permanent-local t) + +(defvar-local with-editor--pid nil "For internal use.") +(put 'with-editor--pid 'permanent-local t) + +(defun with-editor-finish (force) + "Finish the current edit session." + (interactive "P") + (when (run-hook-with-args-until-failure + 'with-editor-finish-query-functions force) + (let ((post-finish-hook with-editor-post-finish-hook) + (post-commit-hook (bound-and-true-p git-commit-post-finish-hook)) + (dir default-directory)) + (run-hooks 'with-editor-pre-finish-hook) + (with-editor-return nil) + (accept-process-output nil 0.1) + (with-temp-buffer + (setq default-directory dir) + (setq-local with-editor-post-finish-hook post-finish-hook) + (when (bound-and-true-p git-commit-post-finish-hook) + (setq-local git-commit-post-finish-hook post-commit-hook)) + (run-hooks 'with-editor-post-finish-hook))))) + +(defun with-editor-cancel (force) + "Cancel the current edit session." + (interactive "P") + (when (run-hook-with-args-until-failure + 'with-editor-cancel-query-functions force) + (let ((message with-editor-cancel-message)) + (when (functionp message) + (setq message (funcall message))) + (let ((post-cancel-hook with-editor-post-cancel-hook) + (with-editor-cancel-alist nil) + (dir default-directory)) + (run-hooks 'with-editor-pre-cancel-hook) + (with-editor-return t) + (accept-process-output nil 0.1) + (with-temp-buffer + (setq default-directory dir) + (setq-local with-editor-post-cancel-hook post-cancel-hook) + (run-hooks 'with-editor-post-cancel-hook))) + (message (or message "Canceled by user"))))) + +(defun with-editor-return (cancel) + (let ((winconf with-editor-previous-winconf) + (clients server-buffer-clients) + (dir default-directory) + (pid with-editor--pid)) + (remove-hook 'kill-buffer-query-functions + 'with-editor-kill-buffer-noop t) + (cond (cancel + (save-buffer) + (if clients + (dolist (client clients) + (ignore-errors + (server-send-string client "-error Canceled by user")) + (delete-process client)) + ;; Fallback for when emacs was used as $EDITOR + ;; instead of emacsclient or the sleeping editor. + ;; See https://github.com/magit/magit/issues/2258. + (ignore-errors (delete-file buffer-file-name)) + (kill-buffer))) + (t + (save-buffer) + (if clients + ;; Don't use `server-edit' because we do not want to + ;; show another buffer belonging to another client. + ;; See https://github.com/magit/magit/issues/2197. + (server-done) + (kill-buffer)))) + (when pid + (let ((default-directory dir)) + (process-file "kill" nil nil nil + "-s" (if cancel "USR2" "USR1") pid))) + (when (and winconf (eq (window-configuration-frame winconf) + (selected-frame))) + (set-window-configuration winconf)))) + +;;; Mode + +(defvar with-editor-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "\C-c\C-c" 'with-editor-finish) + (define-key map [remap server-edit] 'with-editor-finish) + (define-key map [remap evil-save-and-close] 'with-editor-finish) + (define-key map [remap evil-save-modified-and-close] 'with-editor-finish) + (define-key map "\C-c\C-k" 'with-editor-cancel) + (define-key map [remap kill-buffer] 'with-editor-cancel) + (define-key map [remap ido-kill-buffer] 'with-editor-cancel) + (define-key map [remap iswitchb-kill-buffer] 'with-editor-cancel) + (define-key map [remap evil-quit] 'with-editor-cancel) + map)) + +(define-minor-mode with-editor-mode + "Edit a file as the $EDITOR of an external process." + :lighter with-editor-mode-lighter + ;; Protect the user from killing the buffer without using + ;; either `with-editor-finish' or `with-editor-cancel', + ;; and from removing the key bindings for these commands. + (unless with-editor-mode + (user-error "With-Editor mode cannot be turned off")) + (add-hook 'kill-buffer-query-functions + 'with-editor-kill-buffer-noop nil t) + ;; `server-execute' displays a message which is not + ;; correct when using this mode. + (when with-editor-show-usage + (with-editor-usage-message))) + +(put 'with-editor-mode 'permanent-local t) + +(defun with-editor-kill-buffer-noop () + (user-error (substitute-command-keys "\ +Don't kill this buffer. Instead cancel using \\[with-editor-cancel]"))) + +(defun with-editor-usage-message () + ;; Run after `server-execute', which is run using + ;; a timer which starts immediately. + (run-with-timer + 0.01 nil `(lambda () + (with-current-buffer ,(current-buffer) + (message (substitute-command-keys "\ +Type \\[with-editor-finish] to finish, \ +or \\[with-editor-cancel] to cancel")))))) + +;;; Wrappers + +(defvar with-editor--envvar nil "For internal use.") + +(defmacro with-editor (&rest body) + "Use the Emacsclient as $EDITOR while evaluating BODY. +Modify the `process-environment' for processes started in BODY, +instructing them to use the Emacsclient as $EDITOR. If optional +ENVVAR is a literal string then bind that environment variable +instead. +\n(fn [ENVVAR] BODY...)" + (declare (indent defun) (debug (body))) + `(let ((with-editor--envvar ,(if (stringp (car body)) + (pop body) + '(or with-editor--envvar "EDITOR"))) + (process-environment process-environment)) + (with-editor--setup) + ,@body)) + +(defmacro with-editor* (envvar &rest body) + "Use the Emacsclient as the editor while evaluating BODY. +Modify the `process-environment' for processes started in BODY, +instructing them to use the Emacsclient as editor. ENVVAR is the +environment variable that is exported to do so, it is evaluated +at run-time. +\n(fn [ENVVAR] BODY...)" + (declare (indent defun) (debug (sexp body))) + `(let ((with-editor--envvar ,envvar) + (process-environment process-environment)) + (with-editor--setup) + ,@body)) + +(defun with-editor--setup () + (if (or (not with-editor-emacsclient-executable) + (file-remote-p default-directory)) + (push (concat with-editor--envvar "=" with-editor-sleeping-editor) + process-environment) + ;; Make sure server-use-tcp's value is valid. + (unless (featurep 'make-network-process '(:family local)) + (setq server-use-tcp t)) + ;; Make sure the server is running. + (unless (process-live-p server-process) + (when (server-running-p server-name) + (setq server-name (format "server%s" (emacs-pid))) + (when (server-running-p server-name) + (server-force-delete server-name))) + (server-start)) + ;; Tell $EDITOR to use the Emacsclient. + (push (concat with-editor--envvar "=" + (shell-quote-argument with-editor-emacsclient-executable) + ;; Tell the process where the server file is. + (and (not server-use-tcp) + (concat " --socket-name=" + (shell-quote-argument + (expand-file-name server-name + server-socket-dir))))) + process-environment) + (when server-use-tcp + (push (concat "EMACS_SERVER_FILE=" + (expand-file-name server-name server-auth-dir)) + process-environment)) + ;; As last resort fallback to the sleeping editor. + (push (concat "ALTERNATE_EDITOR=" with-editor-sleeping-editor) + process-environment))) + +(defun with-editor-server-window () + (or (and buffer-file-name + (cdr (cl-find-if (lambda (cons) + (string-match-p (car cons) buffer-file-name)) + with-editor-server-window-alist))) + server-window)) + +(defun server-switch-buffer--with-editor-server-window-alist + (fn &optional next-buffer killed-one filepos) + "Honor `with-editor-server-window-alist' (which see)." + (let ((server-window (with-current-buffer + (or next-buffer (current-buffer)) + (when with-editor-mode + (setq with-editor-previous-winconf + (current-window-configuration))) + (with-editor-server-window)))) + (funcall fn next-buffer killed-one filepos))) + +(advice-add 'server-switch-buffer :around + 'server-switch-buffer--with-editor-server-window-alist) + +(defun start-file-process--with-editor-process-filter + (fn name buffer program &rest program-args) + "When called inside a `with-editor' form and the Emacsclient +cannot be used, then give the process the filter function +`with-editor-process-filter'. To avoid overriding the filter +being added here you should use `with-editor-set-process-filter' +instead of `set-process-filter' inside `with-editor' forms. + +When the `default-directory' is located on a remote machine, +then also manipulate PROGRAM and PROGRAM-ARGS in order to set +the appropriate editor environment variable." + (if (not with-editor--envvar) + (apply fn name buffer program program-args) + (when (file-remote-p default-directory) + (unless (equal program "env") + (push program program-args) + (setq program "env")) + (push (concat with-editor--envvar "=" with-editor-sleeping-editor) + program-args)) + (let ((process (apply fn name buffer program program-args))) + (set-process-filter process 'with-editor-process-filter) + (process-put process 'default-dir default-directory) + process))) + +(advice-add 'start-file-process :around + 'start-file-process--with-editor-process-filter) + +(defun with-editor-set-process-filter (process filter) + "Like `set-process-filter' but keep `with-editor-process-filter'. +Give PROCESS the new FILTER but keep `with-editor-process-filter' +if that was added earlier by the adviced `start-file-process'. + +Do so by wrapping the two filter functions using a lambda, which +becomes the actual filter. It calls `with-editor-process-filter' +first, passing t as NO-STANDARD-FILTER. Then it calls FILTER, +which may or may not insert the text into the PROCESS' buffer." + (set-process-filter + process + (if (eq (process-filter process) 'with-editor-process-filter) + `(lambda (proc str) + (,filter proc str) + (with-editor-process-filter proc str t)) + filter))) + +(defvar with-editor-filter-visit-hook nil) + +(defun with-editor-output-filter (string) + (save-match-data + (if (string-match "^WITH-EDITOR: \ +\\([0-9]+\\) OPEN \\([^]+?\\)\ +\\(?: IN \\([^\r]+?\\)\\)?\r?$" string) + (let ((pid (match-string 1 string)) + (file (match-string 2 string)) + (dir (match-string 3 string))) + (unless (file-name-absolute-p file) + (setq file (expand-file-name file dir))) + (when default-directory + (setq file (concat (file-remote-p default-directory) file))) + (with-current-buffer (find-file-noselect file) + (with-editor-mode 1) + (setq with-editor--pid pid) + (run-hooks 'with-editor-filter-visit-hook) + (funcall (or (with-editor-server-window) 'switch-to-buffer) + (current-buffer)) + (kill-local-variable 'server-window)) + nil) + string))) + +(defun with-editor-process-filter + (process string &optional no-default-filter) + "Listen for edit requests by child processes." + (let ((default-directory (process-get process 'default-dir))) + (with-editor-output-filter string)) + (unless no-default-filter + (internal-default-process-filter process string))) + +(advice-add 'server-visit-files :after + 'server-visit-files--with-editor-file-name-history-exclude) + +(defun server-visit-files--with-editor-file-name-history-exclude + (files _proc &optional _nowait) + (pcase-dolist (`(,file . ,_) files) + (when (cl-find-if (lambda (regexp) + (string-match-p regexp file)) + with-editor-file-name-history-exclude) + (setq file-name-history (delete file file-name-history))))) + +;;; Augmentations + +;;;###autoload +(cl-defun with-editor-export-editor (&optional (envvar "EDITOR")) + "Teach subsequent commands to use current Emacs instance as editor. + +Set and export the environment variable ENVVAR, by default +\"EDITOR\". The value is automatically generated to teach +commands to use the current Emacs instance as \"the editor\". + +This works in `shell-mode', `term-mode' and `eshell-mode'." + (interactive (list (with-editor-read-envvar))) + (cond + ((derived-mode-p 'comint-mode 'term-mode) + (let ((process (get-buffer-process (current-buffer)))) + (goto-char (process-mark process)) + (process-send-string + process (format " export %s=%s\n" envvar + (shell-quote-argument with-editor-sleeping-editor))) + (while (accept-process-output process 0.1)) + (if (derived-mode-p 'term-mode) + (with-editor-set-process-filter process 'with-editor-emulate-terminal) + (add-hook 'comint-output-filter-functions 'with-editor-output-filter + nil t)))) + ((derived-mode-p 'eshell-mode) + (add-to-list 'eshell-preoutput-filter-functions + 'with-editor-output-filter) + (setenv envvar with-editor-sleeping-editor)) + (t + (error "Cannot export environment variables in this buffer"))) + (message "Successfully exported %s" envvar)) + +;;;###autoload +(defun with-editor-export-git-editor () + "Like `with-editor-export-editor' but always set `$GIT_EDITOR'." + (interactive) + (with-editor-export-editor "GIT_EDITOR")) + +;;;###autoload +(defun with-editor-export-hg-editor () + "Like `with-editor-export-editor' but always set `$HG_EDITOR'." + (interactive) + (with-editor-export-editor "HG_EDITOR")) + +(defun with-editor-emulate-terminal (process string) + "Like `term-emulate-terminal' but also handle edit requests." + (when (with-editor-output-filter string) + (term-emulate-terminal process string))) + +(defvar with-editor-envvars '("EDITOR" "GIT_EDITOR" "HG_EDITOR")) + +(cl-defun with-editor-read-envvar + (&optional (prompt "Set environment variable") + (default "EDITOR")) + (let ((reply (completing-read (if default + (format "%s (%s): " prompt default) + (concat prompt ": ")) + with-editor-envvars nil nil nil nil default))) + (if (string= reply "") (user-error "Nothing selected") reply))) + +;;;###autoload +(define-minor-mode shell-command-with-editor-mode + "Teach `shell-command' to use current Emacs instance as editor. + +Teach `shell-command', and all commands that ultimately call that +command, to use the current Emacs instance as editor by executing +\"EDITOR=CLIENT COMMAND&\" instead of just \"COMMAND&\". + +CLIENT is automatically generated; EDITOR=CLIENT instructs +COMMAND to use to the current Emacs instance as \"the editor\", +assuming no other variable overrides the effect of \"$EDITOR\". +CLIENT may be the path to an appropriate emacsclient executable +with arguments, or a script which also works over Tramp. + +Alternatively you can use the `with-editor-async-shell-command', +which also allows the use of another variable instead of +\"EDITOR\"." + :global t) + +;;;###autoload +(defun with-editor-async-shell-command + (command &optional output-buffer error-buffer envvar) + "Like `async-shell-command' but with `$EDITOR' set. + +Execute string \"ENVVAR=CLIENT COMMAND\" in an inferior shell; +display output, if any. With a prefix argument prompt for an +environment variable, otherwise the default \"EDITOR\" variable +is used. With a negative prefix argument additionally insert +the COMMAND's output at point. + +CLIENT is automatically generated; ENVVAR=CLIENT instructs +COMMAND to use to the current Emacs instance as \"the editor\", +assuming it respects ENVVAR as an \"EDITOR\"-like variable. +CLIENT may be the path to an appropriate emacsclient executable +with arguments, or a script which also works over Tramp. + +Also see `async-shell-command' and `shell-command'." + (interactive (with-editor-shell-command-read-args "Async shell command: " t)) + (let ((with-editor--envvar envvar)) + (with-editor + (async-shell-command command output-buffer error-buffer)))) + +;;;###autoload +(defun with-editor-shell-command + (command &optional output-buffer error-buffer envvar) + "Like `shell-command' or `with-editor-async-shell-command'. +If COMMAND ends with \"&\" behave like the latter, +else like the former." + (interactive (with-editor-shell-command-read-args "Shell command: ")) + (if (string-match "&[ \t]*\\'" command) + (with-editor-async-shell-command + command output-buffer error-buffer envvar) + (shell-command command output-buffer error-buffer))) + +(defun with-editor-shell-command-read-args (prompt &optional async) + (let ((command (read-shell-command + prompt nil nil + (let ((filename (or buffer-file-name + (and (eq major-mode 'dired-mode) + (dired-get-filename nil t))))) + (and filename (file-relative-name filename)))))) + (list command + (if (or async (setq async (string-match-p "&[ \t]*\\'" command))) + (< (prefix-numeric-value current-prefix-arg) 0) + current-prefix-arg) + shell-command-default-error-buffer + (and async current-prefix-arg (with-editor-read-envvar))))) + +(defun shell-command--shell-command-with-editor-mode + (fn command &optional output-buffer error-buffer) + ;; `shell-mode' and its hook are intended for buffers in which an + ;; interactive shell is running, but `shell-command' also turns on + ;; that mode, even though it only runs the shell to run a single + ;; command. The `with-editor-export-editor' hook function is only + ;; intended to be used in buffers in which an interactive shell is + ;; running, so it has to be remove here. + (let ((shell-mode-hook (remove 'with-editor-export-editor shell-mode-hook))) + (cond ((or (not (or with-editor--envvar shell-command-with-editor-mode)) + (not (string-match-p "&\\'" command))) + (funcall fn command output-buffer error-buffer)) + ((and with-editor-shell-command-use-emacsclient + with-editor-emacsclient-executable + (not (file-remote-p default-directory))) + (with-editor (funcall fn command output-buffer error-buffer))) + (t + (apply fn (format "%s=%s %s" + (or with-editor--envvar "EDITOR") + (shell-quote-argument with-editor-sleeping-editor) + command) + output-buffer error-buffer) + (ignore-errors + (let ((process (get-buffer-process + (or output-buffer + (get-buffer "*Async Shell Command*"))))) + (set-process-filter + process (lambda (proc str) + (comint-output-filter proc str) + (with-editor-process-filter proc str t))) + process)))))) + +(advice-add 'shell-command :around + 'shell-command--shell-command-with-editor-mode) + +;;; _ + +(defun with-editor-debug () + "Debug configuration issues. +See info node `(with-editor)Debugging' for instructions." + (interactive) + (with-current-buffer (get-buffer-create "*with-editor-debug*") + (pop-to-buffer (current-buffer)) + (erase-buffer) + (ignore-errors (with-editor)) + (insert + (format "with-editor: %s\n" (locate-library "with-editor.el")) + (format "emacs: %s (%s)\n" + (expand-file-name invocation-name invocation-directory) + emacs-version) + "system:\n" + (format " system-type: %s\n" system-type) + (format " system-configuration: %s\n" system-configuration) + (format " system-configuration-options: %s\n" system-configuration-options) + "server:\n" + (format " server-running-p: %s\n" (server-running-p)) + (format " server-process: %S\n" server-process) + (format " server-use-tcp: %s\n" server-use-tcp) + (format " server-name: %s\n" server-name) + (format " server-socket-dir: %s\n" server-socket-dir)) + (if (and server-socket-dir (file-accessible-directory-p server-socket-dir)) + (dolist (file (directory-files server-socket-dir nil "^[^.]")) + (insert (format " %s\n" file))) + (insert (format " %s: not an accessible directory\n" + (if server-use-tcp "WARNING" "ERROR")))) + (insert (format " server-auth-dir: %s\n" server-auth-dir)) + (if (file-accessible-directory-p server-auth-dir) + (dolist (file (directory-files server-auth-dir nil "^[^.]")) + (insert (format " %s\n" file))) + (insert (format " %s: not an accessible directory\n" + (if server-use-tcp "ERROR" "WARNING")))) + (let ((val with-editor-emacsclient-executable) + (def (default-value 'with-editor-emacsclient-executable)) + (fun (let ((warning-minimum-level :error) + (warning-minimum-log-level :error)) + (with-editor-locate-emacsclient)))) + (insert "with-editor-emacsclient-executable:\n" + (format " value: %s (%s)\n" val + (and val (with-editor-emacsclient-version val))) + (format " default: %s (%s)\n" def + (and def (with-editor-emacsclient-version def))) + (format " funcall: %s (%s)\n" fun + (and fun (with-editor-emacsclient-version fun))))) + (insert "path:\n" + (format " $PATH: %S\n" (getenv "PATH")) + (format " exec-path: %s\n" exec-path)) + (insert (format " with-editor-emacsclient-path:\n")) + (dolist (dir (with-editor-emacsclient-path)) + (insert (format " %s (%s)\n" dir (car (file-attributes dir)))) + (when (file-directory-p dir) + ;; Don't match emacsclientw.exe, it makes popup windows. + (dolist (exec (directory-files dir t "emacsclient\\(?:[^w]\\|\\'\\)")) + (insert (format " %s (%s)\n" exec + (with-editor-emacsclient-version exec)))))))) + +(defconst with-editor-font-lock-keywords + '(("(\\(with-\\(?:git-\\)?editor\\)\\_>" (1 'font-lock-keyword-face)))) +(font-lock-add-keywords 'emacs-lisp-mode with-editor-font-lock-keywords) + +(provide 'with-editor) +;; Local Variables: +;; indent-tabs-mode: nil +;; End: +;;; with-editor.el ends here diff --git a/elpa/with-editor-20181113.1845/with-editor.info b/elpa/with-editor-20181113.1845/with-editor.info new file mode 100644 index 00000000..157b4ce7 --- /dev/null +++ b/elpa/with-editor-20181113.1845/with-editor.info @@ -0,0 +1,343 @@ +This is with-editor.info, produced by makeinfo version 6.5 from +with-editor.texi. + + Copyright (C) 2015-2018 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. + +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* With-Editor: (with-editor). Using the Emacsclient as $EDITOR. +END-INFO-DIR-ENTRY + + +File: with-editor.info, Node: Top, Next: Using the With-Editor package, Up: (dir) + +With-Editor User Manual +*********************** + +The library ‘with-editor’ makes it easy to use the Emacsclient as the +‘$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. + +This manual is for With-Editor version 2.8.0 (v2.8.0-2-g87c96b3+1). + + Copyright (C) 2015-2018 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. + +* Menu: + +* Using the With-Editor package:: +* Using With-Editor as a library:: +* Debugging:: + +— The Detailed Node Listing — + +Using the With-Editor package + +* Configuring With-Editor:: +* Using With-Editor commands:: + + + +File: with-editor.info, Node: Using the With-Editor package, Next: Using With-Editor as a library, Prev: Top, Up: Top + +1 Using the With-Editor package +******************************* + +The ‘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 you own package, see +*note Using With-Editor as a library::. + +* Menu: + +* Configuring With-Editor:: +* Using With-Editor commands:: + + +File: with-editor.info, Node: Configuring With-Editor, Next: Using With-Editor commands, Up: Using the With-Editor package + +1.1 Configuring With-Editor +=========================== + +With-Editor tries very hard to locate a suitable ‘emacsclient’ +executable, so ideally you should never have to customize the option +‘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 ‘$PATH’, +and we have to add another kludge to find it anyway. + + -- User Option: with-editor-emacsclient-executable + + The ‘emacsclient’ executable used as the editor by child process 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 + ‘exec-path’, and other places where the executable could be + installed, to find the ‘emacsclient’ executable most suitable for + the current Emacs instance. + + You should *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 *note Debugging::. + + If With-Editor fails to find a suitable ‘emacsclient’ on you + system, then this should be fixed for all users at once, by + teaching ‘with-editor-locate-emacsclient’ how to do so on your + system and system 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 + ‘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 you setup. + + -- Function: with-editor-locate-emacsclient + + The function used to set the initial value of the option + ‘with-editor-emacsclient-executable’. There’s a lot of voodoo + here. + + The ‘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 +‘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. + + -- User Option: with-editor-sleeping-editor + + The sleeping editor is a shell script used as the editor of child + processes when the ‘emacsclient’ executable cannot be used. + + This fallback is used for asynchronous process started inside the + macro ‘with-editor’, when the process runs on a remote machine or + for local processes when ‘with-editor-emacsclient-executable’ is + ‘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 ‘emacsclient’, it can only + be used as ‘$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. ‘csh’ on FreeBSD, but not Debian), + then you have to edit this option. You can either replace ‘sh’ + with ‘bash’ (and install that), or you can use the older, less + performant implementation: + + "sh -c '\ + echo \"WITH-EDITOR: $$ OPEN $0 IN $(pwd)\"; \ + trap \"exit 0\" USR1; \ + trap \"exit 1\" USR2; \ + while true; do sleep 1; done'" + + Note that the unit seperator 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 + ‘sleep 1’ with ‘sleep 0.01’, or if your implementation does not + support floats, then by using ‘nanosleep’ instead. + + +File: with-editor.info, Node: Using With-Editor commands, Prev: Configuring With-Editor, Up: Using the With-Editor package + +1.2 Using With-Editor commands +============================== + +This section describes how to use the ‘with-editor’ library _outside_ of +Magit. You don’t need to know any of this just to create commits using +Magit. + + The commands ‘with-editor-async-shell-command’ and +‘with-editor-shell-command’ are intended as drop in replacements for +‘async-shell-command’ and ‘shell-command’. They automatically export +‘$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 ‘$GIT_EDITOR’. + + -- Command: with-editor-async-shell-command + + This command is like ‘async-shell-command’, but it runs the shell + command with the current Emacs instance exported as ‘$EDITOR’. + + -- Command: with-editor-shell-command + + This command is like ‘shell-command’, but if the shell command ends + with ‘&’ and is therefore run asynchronously, then the current + Emacs instance is exported as ‘$EDITOR’. + + To always use these variants add this to you init file: + + (define-key (current-global-map) + [remap async-shell-command] 'with-editor-async-shell-command) + (define-key (current-global-map) + [remap shell-command] 'with-editor-shell-command) + + Alternatively use the global ‘shell-command-with-editor-mode’. + + -- Variable: shell-command-with-editor-mode + + When this mode is active, then ‘$EDITOR’ is exported whenever + ultimately ‘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. + + The command ‘with-editor-export-editor’ exports ‘$EDITOR’ or another +such environment variable in ‘shell-mode’, ‘term-mode’ and ‘eshell-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: + + (add-hook 'shell-mode-hook 'with-editor-export-editor) + (add-hook 'term-exec-hook 'with-editor-export-editor) + (add-hook 'eshell-mode-hook 'with-editor-export-editor) + + Some variants of this function exist; these two forms are equivalent: + + (add-hook 'shell-mode-hook + (apply-partially 'with-editor-export-editor "GIT_EDITOR")) + (add-hook 'shell-mode-hook 'with-editor-export-git-editor) + + -- Command: with-editor-export-editor + + When invoked in a ‘shell-mode’, ‘term-mode’, or ‘eshell-mode’ + buffer, this command teaches shell commands to use the current + Emacs instance as the editor, by exporting ‘$EDITOR’. + + -- Command: with-editor-export-git-editor + + This command is like ‘with-editor-export-editor’ but exports + ‘$GIT_EDITOR’. + + -- Command: with-editor-export-hg-editor + + This command is like ‘with-editor-export-editor’ but exports + ‘$HG_EDITOR’. + + +File: with-editor.info, Node: Using With-Editor as a library, Next: Debugging, Prev: Using the With-Editor package, Up: Top + +2 Using With-Editor as a library +******************************** + +This section describes how to use the ‘with-editor’ library _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 +‘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 *note Using the With-Editor +package::. + + -- Macro: with-editor &rest body + + This macro arranges for the ‘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 + ‘process-environment’ and changing the value of the ‘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 ‘EDITOR’. + + -- Macro: with-editor envvar &rest body + + This macro is like ‘with-editor’ instead that the ENVVAR argument + is required and that it is evaluated at run-time. + + -- Function: with-editor-set-process-filter process filter + + This function is like ‘set-process-filter’ but ensures that adding + the new FILTER does not remove the ‘with-editor-process-filter’. + This is done by wrapping the two filter functions using a lambda, + which becomes the actual filter. It calls + ‘with-editor-process-filter’ first, passing ‘t’ as + NO-STANDARD-FILTER. Then it calls FILTER. + + +File: with-editor.info, Node: Debugging, Prev: Using With-Editor as a library, Up: Top + +3 Debugging +*********** + +With-Editor tries very hard to locate a suitable ‘emacsclient’ +executable, and then sets option ‘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 ‘$PATH’, +and we have to add another kludge to find it anyway. + + If you are having problems using ‘with-editor’, e.g. you cannot +commit in Magit, then please open a new issue at + and provide information +about your Emacs installation. Most importantly how did you install +Emacs and what is the output of ‘M-x with-editor-debug RET’. + + + +Tag Table: +Node: Top773 +Node: Using the With-Editor package2535 +Node: Configuring With-Editor3121 +Node: Using With-Editor commands7670 +Node: Using With-Editor as a library10865 +Node: Debugging12828 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: diff --git a/elpa/with-editor-readme.txt b/elpa/with-editor-readme.txt deleted file mode 100644 index 7c6c5597..00000000 --- a/elpa/with-editor-readme.txt +++ /dev/null @@ -1,46 +0,0 @@ -Use the Emacsclient as `$EDITOR' of child processes, making sure -they know how to call home. For remote processes a substitute is -provided, which communicates with Emacs on stdout instead of using -a socket as the Emacsclient does. - -The commands `with-editor-async-shell-command' and -`with-editor-shell-command' are intended as drop in replacements -for `async-shell-command' and `shell-command'. They automatically -export `$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 -`$GIT_EDITOR'. To always use these variants add this to your init -file: - - (define-key (current-global-map) - [remap async-shell-command] 'with-editor-async-shell-command) - (define-key (current-global-map) - [remap shell-command] 'with-editor-shell-command) - -Alternatively use the global `shell-command-with-editor-mode', -which always sets `$EDITOR' for all Emacs commands which ultimately -use `shell-command' to asynchronously run some shell command. - -The command `with-editor-export-editor' exports `$EDITOR' or -another such environment variable in `shell-mode', `term-mode' and -`eshell-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: - - (add-hook 'shell-mode-hook 'with-editor-export-editor) - (add-hook 'term-mode-hook 'with-editor-export-editor) - (add-hook 'eshell-mode-hook 'with-editor-export-editor) - -Some variants of this function exist, these two forms are -equivalent: - - (add-hook 'shell-mode-hook - (apply-partially 'with-editor-export-editor "GIT_EDITOR")) - (add-hook 'shell-mode-hook 'with-editor-export-git-editor) - -This library can also be used by other packages which need to use -the current Emacs instance as editor. In fact this library was -written for Magit and its `git-commit-mode' and `git-rebase-mode'. -Consult `git-rebase.el' and the related code in `magit-sequence.el' -for a simple example.