diff options
| author | Daiki Ueno | 2015-08-18 11:09:29 +0900 |
|---|---|---|
| committer | Daiki Ueno | 2015-08-18 11:09:29 +0900 |
| commit | 9bc757830a9c6edeb950c294a32f058504550148 (patch) | |
| tree | 78cb21308ae40bd5ecb6e47770b43a1555add34b | |
| parent | c24a067eacef1b5292116e367b0213c27f1195b9 (diff) | |
| download | emacs-9bc757830a9c6edeb950c294a32f058504550148.tar.gz emacs-9bc757830a9c6edeb950c294a32f058504550148.zip | |
pinentry.el: Popup window for multiline prompt
* lisp/net/pinentry.el (pinentry): New custom group.
(pinentry-popup-prompt-window): New user option.
(pinentry-prompt-window-height): New user option.
(pinentry--prompt-buffer): New variable.
(pinentry-prompt-mode-map): New variable.
(pinentry-prompt-mode): New function.
(pinentry--prompt): New function.
(pinentry--process-filter): Use `pinentry--prompt' instead of
`read-passwd' and `y-or-n-p'.
| -rw-r--r-- | lisp/net/pinentry.el | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/lisp/net/pinentry.el b/lisp/net/pinentry.el index 7cbe9f50c4a..05cb124f2cb 100644 --- a/lisp/net/pinentry.el +++ b/lisp/net/pinentry.el | |||
| @@ -50,6 +50,21 @@ | |||
| 50 | 50 | ||
| 51 | ;;; Code: | 51 | ;;; Code: |
| 52 | 52 | ||
| 53 | (defgroup pinentry nil | ||
| 54 | "The Pinentry server" | ||
| 55 | :version "25.1" | ||
| 56 | :group 'external) | ||
| 57 | |||
| 58 | (defcustom pinentry-popup-prompt-window t | ||
| 59 | "If non-nil, display status information from epa commands in another window." | ||
| 60 | :type 'boolean | ||
| 61 | :group 'pinentry) | ||
| 62 | |||
| 63 | (defcustom pinentry-prompt-window-height 5 | ||
| 64 | "Number of lines used to display status information." | ||
| 65 | :type 'integer | ||
| 66 | :group 'pinentry) | ||
| 67 | |||
| 53 | (defvar pinentry--server-process nil) | 68 | (defvar pinentry--server-process nil) |
| 54 | (defvar pinentry--connection-process-list nil) | 69 | (defvar pinentry--connection-process-list nil) |
| 55 | 70 | ||
| @@ -58,6 +73,8 @@ | |||
| 58 | (defvar pinentry--read-point nil) | 73 | (defvar pinentry--read-point nil) |
| 59 | (put 'pinentry--read-point 'permanent-local t) | 74 | (put 'pinentry--read-point 'permanent-local t) |
| 60 | 75 | ||
| 76 | (defvar pinentry--prompt-buffer nil) | ||
| 77 | |||
| 61 | ;; We use the same location as `server-socket-dir', when local sockets | 78 | ;; We use the same location as `server-socket-dir', when local sockets |
| 62 | ;; are supported. | 79 | ;; are supported. |
| 63 | (defvar pinentry--socket-dir | 80 | (defvar pinentry--socket-dir |
| @@ -82,6 +99,52 @@ If local sockets are not supported, this is nil.") | |||
| 82 | 99 | ||
| 83 | (autoload 'server-ensure-safe-dir "server") | 100 | (autoload 'server-ensure-safe-dir "server") |
| 84 | 101 | ||
| 102 | (defvar pinentry-prompt-mode-map | ||
| 103 | (let ((keymap (make-sparse-keymap))) | ||
| 104 | (define-key keymap "q" 'quit-window) | ||
| 105 | keymap)) | ||
| 106 | |||
| 107 | (define-derived-mode pinentry-prompt-mode special-mode "Pinentry" | ||
| 108 | "Major mode for `pinentry--prompt-buffer'." | ||
| 109 | (buffer-disable-undo) | ||
| 110 | (setq truncate-lines t | ||
| 111 | buffer-read-only t)) | ||
| 112 | |||
| 113 | (defun pinentry--prompt (prompt short-prompt query-function &rest query-args) | ||
| 114 | (if (and (string-match "\n" prompt) | ||
| 115 | pinentry-popup-prompt-window) | ||
| 116 | (save-window-excursion | ||
| 117 | (delete-other-windows) | ||
| 118 | (unless (and pinentry--prompt-buffer | ||
| 119 | (buffer-live-p pinentry--prompt-buffer)) | ||
| 120 | (setq pinentry--prompt-buffer (generate-new-buffer "*Pinentry*"))) | ||
| 121 | (if (get-buffer-window pinentry--prompt-buffer) | ||
| 122 | (delete-window (get-buffer-window pinentry--prompt-buffer))) | ||
| 123 | (with-current-buffer pinentry--prompt-buffer | ||
| 124 | (let ((inhibit-read-only t) | ||
| 125 | buffer-read-only) | ||
| 126 | (erase-buffer) | ||
| 127 | (insert prompt)) | ||
| 128 | (pinentry-prompt-mode) | ||
| 129 | (goto-char (point-min))) | ||
| 130 | (if (> (window-height) | ||
| 131 | pinentry-prompt-window-height) | ||
| 132 | (set-window-buffer (split-window nil | ||
| 133 | (- (window-height) | ||
| 134 | pinentry-prompt-window-height)) | ||
| 135 | pinentry--prompt-buffer) | ||
| 136 | (pop-to-buffer pinentry--prompt-buffer) | ||
| 137 | (if (> (window-height) pinentry-prompt-window-height) | ||
| 138 | (shrink-window (- (window-height) | ||
| 139 | pinentry-prompt-window-height)))) | ||
| 140 | (prog1 (apply query-function short-prompt query-args) | ||
| 141 | (quit-window))) | ||
| 142 | (apply query-function | ||
| 143 | ;; Append a suffix to the prompt, which can be derived from | ||
| 144 | ;; SHORT-PROMPT. | ||
| 145 | (concat prompt (substring short-prompt -2)) | ||
| 146 | query-args))) | ||
| 147 | |||
| 85 | ;;;###autoload | 148 | ;;;###autoload |
| 86 | (defun pinentry-start () | 149 | (defun pinentry-start () |
| 87 | "Start a Pinentry service. | 150 | "Start a Pinentry service. |
| @@ -267,16 +330,13 @@ Assuan protocol." | |||
| 267 | (if (setq entry (assq 'title pinentry--labels)) | 330 | (if (setq entry (assq 'title pinentry--labels)) |
| 268 | (setq prompt (format "[%s] %s" | 331 | (setq prompt (format "[%s] %s" |
| 269 | (cdr entry) prompt))) | 332 | (cdr entry) prompt))) |
| 270 | (if (string-match ":?[ \n]*\\'" prompt) | ||
| 271 | (setq prompt (concat | ||
| 272 | (substring | ||
| 273 | prompt 0 (match-beginning 0)) ": "))) | ||
| 274 | (let (passphrase escaped-passphrase encoded-passphrase) | 333 | (let (passphrase escaped-passphrase encoded-passphrase) |
| 275 | (unwind-protect | 334 | (unwind-protect |
| 276 | (condition-case nil | 335 | (condition-case nil |
| 277 | (progn | 336 | (progn |
| 278 | (setq passphrase | 337 | (setq passphrase |
| 279 | (read-passwd prompt confirm)) | 338 | (pinentry--prompt prompt "Password: " |
| 339 | #'read-passwd confirm)) | ||
| 280 | (setq escaped-passphrase | 340 | (setq escaped-passphrase |
| 281 | (pinentry--escape-string | 341 | (pinentry--escape-string |
| 282 | passphrase)) | 342 | passphrase)) |
| @@ -350,7 +410,7 @@ Assuan protocol." | |||
| 350 | (substring | 410 | (substring |
| 351 | prompt 0 (match-beginning 0)) " "))) | 411 | prompt 0 (match-beginning 0)) " "))) |
| 352 | (if (condition-case nil | 412 | (if (condition-case nil |
| 353 | (y-or-n-p prompt) | 413 | (pinentry--prompt prompt "Confirm? " #'y-or-n-p) |
| 354 | (quit)) | 414 | (quit)) |
| 355 | (ignore-errors | 415 | (ignore-errors |
| 356 | (process-send-string process "OK\n")) | 416 | (process-send-string process "OK\n")) |