From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Leo Liu Newsgroups: gmane.emacs.bugs Subject: bug#15525: 24.3; register-read-with-preview Date: Sat, 05 Oct 2013 11:19:34 +0800 Message-ID: References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1380943282 29440 80.91.229.3 (5 Oct 2013 03:21:22 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 5 Oct 2013 03:21:22 +0000 (UTC) Cc: =?UTF-8?Q?=C3=93scar?= Fuentes , 15525@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Oct 05 05:21:24 2013 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1VSIQm-0003DJ-AJ for geb-bug-gnu-emacs@m.gmane.org; Sat, 05 Oct 2013 05:21:24 +0200 Original-Received: from localhost ([::1]:50504 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VSIQl-0005A9-A0 for geb-bug-gnu-emacs@m.gmane.org; Fri, 04 Oct 2013 23:21:23 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39406) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VSIQZ-00059x-R4 for bug-gnu-emacs@gnu.org; Fri, 04 Oct 2013 23:21:19 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VSIQQ-0000Ms-7J for bug-gnu-emacs@gnu.org; Fri, 04 Oct 2013 23:21:11 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:46838) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VSIQQ-0000Ml-3U for bug-gnu-emacs@gnu.org; Fri, 04 Oct 2013 23:21:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1VSIQP-0004NG-LF for bug-gnu-emacs@gnu.org; Fri, 04 Oct 2013 23:21:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Leo Liu Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 05 Oct 2013 03:21:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 15525 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 15525-submit@debbugs.gnu.org id=B15525.138094323316780 (code B ref 15525); Sat, 05 Oct 2013 03:21:01 +0000 Original-Received: (at 15525) by debbugs.gnu.org; 5 Oct 2013 03:20:33 +0000 Original-Received: from localhost ([127.0.0.1]:55131 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1VSIPu-0004MX-BU for submit@debbugs.gnu.org; Fri, 04 Oct 2013 23:20:32 -0400 Original-Received: from mail-pd0-f182.google.com ([209.85.192.182]:34278) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1VSIPp-0004MM-QI for 15525@debbugs.gnu.org; Fri, 04 Oct 2013 23:20:27 -0400 Original-Received: by mail-pd0-f182.google.com with SMTP id r10so4793110pdi.13 for <15525@debbugs.gnu.org>; Fri, 04 Oct 2013 20:20:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:references:face:date:in-reply-to:message-id :user-agent:mime-version:content-type; bh=3bqj4u87P53QLKlvmAPuEC80yqZVV0xNufmCfmFi1YA=; b=jaADv0rnvZ2H4FZe/trIFOFH8P+MXv7em/k5QlWO/eFLh7dZnThgspg5iQUmQszFZM oAPhzi54igR1v4j5bqGYu/t1/6BPDRxOq2Z86GDGd6sPVxNZXP1zO5tH3YKWUNGyOmIK EluelkV9w+sWMsRwUsND6AlbuNNAqeZs/l7aLKWHqiV1kV+56iNcfK6wqEh+345vTOri dJdo3OSP5oOEl81xUe/LPJeZwVY1KsCwBYO+VPNL2VBt8bNp43fjUpkdaWw8CX27zDmC me62h6k7FDMr269QovZ217m8RmiI+nI6Pc3xLT2bzHSismJCmttxgDuWvdmGQXyfenl2 lTQA== X-Received: by 10.68.101.3 with SMTP id fc3mr9853127pbb.107.1380943224854; Fri, 04 Oct 2013 20:20:24 -0700 (PDT) Original-Received: from localhost ([222.131.216.43]) by mx.google.com with ESMTPSA id dk3sm17986810pbc.32.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 04 Oct 2013 20:20:23 -0700 (PDT) Face: iVBORw0KGgoAAAANSUhEUgAAACgAAAAoBAMAAAB+0KVeAAAAGFBMVEUKDAg1NjRWV1V9fnyg op/DxcLk5uP8/voi63ReAAAACXBIWXMAAAWJAAAFiQFtaJ36AAAAB3RJTUUH1goZAgAz00bgXgAA AeVJREFUKM9lk0Fz2jAQhQXJD3CCO70CmcC1YMtcWyTZ14Bl69xats4N9r6/3zWQBlodNKNPu/s0 b1cCQFuZGpfVVh3vAvBJolIXRkapSuoRUtIdFyo1Y5xSdlAj7OtvD1XnXxmWRi+eWgcxyCed1lVV B1CrKyujMoi+eLA5kU1SsjoHlW+nQjTtFxk4MXgrOxvIqzoTZR8XgPaLl419zgsMaSGFPiUOZCIh thsx5Xy9NsK8Kwf/JoQgMxcVJ301HKkcSWaT0O7FY056J4U9xcYfnmVXG4801lW6lqwu2nKFZoHC HuzvaTVndZ+LaRQgZdthXw1cpynEkLEwyFHXk/aIxNQ6QeooJuzPMB+wn+D7JJNsiCcVA13/A3h/ xE9J+WidpAwoYNmRFwyvSRhNVtsdaAewzZZP5uw82QL9+tyNfocyP0McAzICUr5Mk9RdIjWasUNx aIIt6NK4ZtXIMdfMQt3nuMAyWbLI4DqZ4xPq/ag8jPond4XU/cLuOgw6XCFX/YCUfcDAMMH58fD4 G9kDchwfqVefkBwup2uZM+Q4WhJt5jN3AxXCsaS2yXEDuWgS8VOzW0gFjhEPmLyFMKBFaLb1HRwc DiaKwx0EeTMRYnYPQRW3PP4HApvlMv0PttX5v/D6Aws3IOSEwzmLAAAAAElFTkSuQmCC In-Reply-To: (Stefan Monnier's message of "Fri, 04 Oct 2013 09:57:19 -0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (OS X 10.8.5) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:78934 Archived-At: --=-=-= Content-Type: text/plain On 2013-10-04 21:57 +0800, Stefan Monnier wrote: [snipped 3 lines] > I like the idea of displaying the available choices, but I'm not sure > "0.5s delay" is a good enough trigger: it's probably a fine choice for > some users, but usually Emacs doesn't like to use such time-dependent > behavior too much. > > Could we offer, additionally to the delay, a different trigger > (e.g. help-char and help-event-list)? > > > Stefan Good idea. The attached patch implements this. i.e. if one sets register-preview-delay to t it means forever, i.e. the timer is never set. Users can customise register-read-help-char to nil if they don't want any help-char to bring up the preview window. BTW, the delay is so that if you can remember which register to choose within some time (0.5s) you shall never see the preview window. [snipped 10 lines] >> PS: How does it compare to register-list? Could they be >> consolidated? > > I hope so. The Org merge is higher on my todo-list, but working on > register-list.el comes right after. I leave a hook i.e. register-preview-functions for customising how the preview should be presented. I am not sure other ways to have integration with register-list. Comments welcome. Best wishes, Leo --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=reg2.diff Content-Description: reg2.diff === modified file 'lisp/register.el' --- lisp/register.el 2013-08-09 00:30:24 +0000 +++ lisp/register.el 2013-10-05 03:08:31 +0000 @@ -89,6 +89,16 @@ :type '(choice (const :tag "None" nil) (character :tag "Use register" :value ?+))) +(defcustom register-preview-delay 0.5 + "Delay in seconds before popping up the preview window." + :type '(choice number (const :tag "Indefinitely" t)) + :group 'register) + +(defcustom register-read-help-char help-char + "Character to recognize as meaning help." + :type '(choice character (const :tag "Never" nil)) + :group 'register) + (defun get-register (register) "Return contents of Emacs register named REGISTER, or nil if none." (cdr (assq register register-alist))) @@ -102,12 +112,60 @@ (push (cons register value) register-alist)) value)) +(defun register-describe-oneline (c) + (let ((d (replace-regexp-in-string + "\n[ \t]*" " " + (with-output-to-string (describe-register-1 c))))) + (if (string-match "Register.+? contains \\(?:an? \\|the \\)?" d) + (substring d (match-end 0)) + d))) + +(defvar register-preview-functions nil) + +(defun register-preview (buffer) + "Pop up a window to show register preview in BUFFER." + (when (consp register-alist) + (let ((split-height-threshold 0)) + (with-temp-buffer-window + buffer + (cons 'display-buffer-below-selected + '((window-height . fit-window-to-buffer))) + nil + (with-current-buffer standard-output + (setq cursor-in-non-selected-windows nil) + (mapc (lambda (r) + (insert + (format + "%s %s\n" + (concat (single-key-description (car r)) ":") + (or (run-hook-with-args 'register-preview-functions (cdr r)) + (register-describe-oneline (car r)))))) + register-alist)))))) + +(defun register-read-with-preview (prompt) + (let* ((buffer "*Register Preview*") + (timer (when (numberp register-preview-delay) + (run-with-timer register-preview-delay nil + #'register-preview buffer)))) + (unwind-protect + (progn + (while (eq (read-event (propertize prompt 'face 'minibuffer-prompt)) + register-read-help-char) + (unless (get-buffer-window buffer) + (register-preview buffer))) + last-input-event) + (and (timerp timer) (cancel-timer timer)) + (let ((w (get-buffer-window buffer))) + (and (window-live-p w) (delete-window w))) + (and (get-buffer buffer) (kill-buffer buffer))))) + (defun point-to-register (register &optional arg) "Store current location of point in register REGISTER. With prefix argument, store current frame configuration. Use \\[jump-to-register] to go to that location or restore that configuration. Argument is a character, naming the register." - (interactive "cPoint to register: \nP") + (interactive (list (register-read-with-preview "Point to register: ") + current-prefix-arg)) ;; Turn the marker into a file-ref if the buffer is killed. (add-hook 'kill-buffer-hook 'register-swap-out nil t) (set-register register @@ -118,7 +176,9 @@ "Store the window configuration of the selected frame in register REGISTER. Use \\[jump-to-register] to restore the configuration. Argument is a character, naming the register." - (interactive "cWindow configuration to register: \nP") + (interactive (list (register-read-with-preview + "Window configuration to register: ") + current-prefix-arg)) ;; current-window-configuration does not include the value ;; of point in the current buffer, so record that separately. (set-register register (list (current-window-configuration) (point-marker)))) @@ -127,7 +187,9 @@ "Store the window configuration of all frames in register REGISTER. Use \\[jump-to-register] to restore the configuration. Argument is a character, naming the register." - (interactive "cFrame configuration to register: \nP") + (interactive (list (register-read-with-preview + "Frame configuration to register: ") + current-prefix-arg)) ;; current-frame-configuration does not include the value ;; of point in the current buffer, so record that separately. (set-register register (list (current-frame-configuration) (point-marker)))) @@ -143,7 +205,8 @@ Optional second arg non-nil (interactively, prefix argument) says to delete any existing frames that the frameset doesn't mention. \(Otherwise, these frames are iconified.)" - (interactive "cJump to register: \nP") + (interactive (list (register-read-with-preview "Jump to register: ") + current-prefix-arg)) (let ((val (get-register register))) (cond ((registerv-p val) @@ -190,7 +253,8 @@ If NUMBER is nil, a decimal number is read from the buffer starting at point, and point moves to the end of that number. Interactively, NUMBER is the prefix arg (none means nil)." - (interactive "P\ncNumber to register: ") + (interactive (list current-prefix-arg + (register-read-with-preview "Number to register: "))) (set-register register (if number (prefix-numeric-value number) @@ -222,7 +286,7 @@ (defun view-register (register) "Display what is contained in register named REGISTER. The Lisp value REGISTER is a character." - (interactive "cView register: ") + (interactive (list (register-read-with-preview "View register: "))) (let ((val (get-register register))) (if (null val) (message "Register %s is empty" (single-key-description register)) @@ -323,7 +387,10 @@ Normally puts point before and mark after the inserted text. If optional second arg is non-nil, puts mark before and point after. Interactively, second arg is non-nil if prefix arg is supplied." - (interactive "*cInsert register: \nP") + (interactive (progn + (barf-if-buffer-read-only) + (register-read-with-preview "Insert register: ") + current-prefix-arg)) (push-mark) (let ((val (get-register register))) (cond @@ -349,7 +416,10 @@ With prefix arg, delete as well. Called from program, takes four args: REGISTER, START, END and DELETE-FLAG. START and END are buffer positions indicating what to copy." - (interactive "cCopy to register: \nr\nP") + (interactive (list (register-read-with-preview "Copy to register: ") + (region-beginning) + (region-end) + current-prefix-arg)) (set-register register (filter-buffer-substring start end)) (setq deactivate-mark t) (cond (delete-flag @@ -362,7 +432,10 @@ With prefix arg, delete as well. Called from program, takes four args: REGISTER, START, END and DELETE-FLAG. START and END are buffer positions indicating what to append." - (interactive "cAppend to register: \nr\nP") + (interactive (list (register-read-with-preview "Append to register: ") + (region-beginning) + (region-end) + current-prefix-arg)) (let ((reg (get-register register)) (text (filter-buffer-substring start end)) (separator (and register-separator (get-register register-separator)))) @@ -381,7 +454,10 @@ With prefix arg, delete as well. Called from program, takes four args: REGISTER, START, END and DELETE-FLAG. START and END are buffer positions indicating what to prepend." - (interactive "cPrepend to register: \nr\nP") + (interactive (list (register-read-with-preview "Prepend to register: ") + (region-beginning) + (region-end) + current-prefix-arg)) (let ((reg (get-register register)) (text (filter-buffer-substring start end)) (separator (and register-separator (get-register register-separator)))) @@ -402,7 +478,11 @@ Called from a program, takes four args: REGISTER, START, END and DELETE-FLAG. START and END are buffer positions giving two corners of rectangle." - (interactive "cCopy rectangle to register: \nr\nP") + (interactive (list (register-read-with-preview + "Copy rectangle to register: ") + (region-beginning) + (region-end) + current-prefix-arg)) (let ((rectangle (if delete-flag (delete-extract-rectangle start end) (extract-rectangle start end)))) @@ -412,6 +492,5 @@ (setq deactivate-mark t) (indicate-copied-region (length (car rectangle)))))) - (provide 'register) ;;; register.el ends here --=-=-=--