From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.devel Subject: Losing minibuffer input Date: Sun, 09 Nov 2014 19:57:27 +0200 Organization: JURTA Message-ID: <87fvds2r5i.fsf@mail.jurta.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1415556061 16588 80.91.229.3 (9 Nov 2014 18:01:01 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 9 Nov 2014 18:01:01 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Nov 09 19:00:52 2014 Return-path: Envelope-to: ged-emacs-devel@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 1XnWnE-0005bS-7p for ged-emacs-devel@m.gmane.org; Sun, 09 Nov 2014 19:00:52 +0100 Original-Received: from localhost ([::1]:39589 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XnWnD-000209-UI for ged-emacs-devel@m.gmane.org; Sun, 09 Nov 2014 13:00:51 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:38688) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XnWmh-0001wX-4D for emacs-devel@gnu.org; Sun, 09 Nov 2014 13:00:25 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XnWmZ-0002jO-QL for emacs-devel@gnu.org; Sun, 09 Nov 2014 13:00:19 -0500 Original-Received: from ps18281.dreamhost.com ([69.163.222.226]:50454 helo=ps18281.dreamhostps.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XnWmZ-0002jI-L2 for emacs-devel@gnu.org; Sun, 09 Nov 2014 13:00:11 -0500 Original-Received: from localhost.jurta.org (ps18281.dreamhostps.com [69.163.222.226]) by ps18281.dreamhostps.com (Postfix) with ESMTP id 4E72A348328E50 for ; Sun, 9 Nov 2014 10:00:11 -0800 (PST) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (x86_64-pc-linux-gnu) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 69.163.222.226 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:176631 Archived-At: There is a long-standing usability problem when editing multi-line text in the minibuffer: it's too easy to lose edited text by pressing an up-down arrow key with the intention to go to the next/previous line like in a normal buffer. The changes are lost because the up-down key has a special meaning in the minibuffer to go to the next/previous history item. The fix is simple: allow up-down arrow keys to have their usual behavior and only on hitting the beginning/end of the minibuffer move to the next or previous history item, thus making navigation more smooth and continuous. === modified file 'lisp/bindings.el' --- lisp/bindings.el 2014-07-21 05:38:17 +0000 +++ lisp/bindings.el 2014-11-09 17:56:08 +0000 @@ -839,11 +839,11 @@ (define-key global-map [XF86Back] 'previ (let ((map minibuffer-local-map)) (define-key map "\en" 'next-history-element) (define-key map [next] 'next-history-element) - (define-key map [down] 'next-history-element) + (define-key map [down] 'next-line-or-history-element) (define-key map [XF86Forward] 'next-history-element) (define-key map "\ep" 'previous-history-element) (define-key map [prior] 'previous-history-element) - (define-key map [up] 'previous-history-element) + (define-key map [up] 'previous-line-or-history-element) (define-key map [XF86Back] 'previous-history-element) (define-key map "\es" 'next-matching-history-element) (define-key map "\er" 'previous-matching-history-element) === modified file 'lisp/simple.el' --- lisp/simple.el 2014-11-08 23:52:59 +0000 +++ lisp/simple.el 2014-11-09 17:57:01 +0000 @@ -1982,6 +1982,36 @@ (defun previous-history-element (n) (or (zerop n) (goto-history-element (+ minibuffer-history-position n)))) +(defun next-line-or-history-element (&optional arg) + "Move cursor vertically down ARG lines, or to the next history element. +When point is at the bottom line of multi-line minibuffer, puts ARGth +next element of the minibuffer history in the minibuffer." + (interactive "^p") + (or arg (setq arg 1)) + (let ((old-point (point))) + (condition-case nil + (next-line arg) + (end-of-buffer + ;; Restore old position since `line-move-visual' moves point to + ;; the end of the line when it fails to go to the next line. + (goto-char old-point) + (next-history-element arg))))) + +(defun previous-line-or-history-element (&optional arg) + "Move cursor vertically up ARG lines, or to the previous history element. +When point is at the top line of multi-line minibuffer, puts ARGth +previous element of the minibuffer history in the minibuffer." + (interactive "^p") + (or arg (setq arg 1)) + (let ((old-point (point))) + (condition-case nil + (previous-line arg) + (beginning-of-buffer + ;; Restore old position since `line-move-visual' moves point to + ;; the beginning of the line when it fails to go to the previous line. + (goto-char old-point) + (previous-history-element arg))))) + (defun next-complete-history-element (n) "Get next history element which completes the minibuffer before the point. The contents of the minibuffer after the point are deleted, and replaced