aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2007-07-23 20:29:55 +0000
committerJuri Linkov2007-07-23 20:29:55 +0000
commit297b8ccd7a0a30b566ea95d6c3ac20a8e68e9818 (patch)
tree19810f77a4ca16669d47aad253c02c148a453ca2
parentac475d3a720d3f0650061411d40403d6f9bba04d (diff)
downloademacs-297b8ccd7a0a30b566ea95d6c3ac20a8e68e9818.tar.gz
emacs-297b8ccd7a0a30b566ea95d6c3ac20a8e68e9818.zip
(goto-history-element): New function created from
next-history-element. (next-history-element): Most code moved to goto-history-element. Call goto-history-element with (- minibuffer-history-position n). (previous-history-element): Call goto-history-element with (+ minibuffer-history-position n). (minibuffer-setup-hook): Add minibuffer-history-isearch-setup. (minibuffer-history-isearch-message-overlay): New buffer-local variable. (minibuffer-history-isearch-setup, minibuffer-history-isearch-end) (minibuffer-history-isearch-search, minibuffer-history-isearch-message) (minibuffer-history-isearch-wrap, minibuffer-history-isearch-push-state) (minibuffer-history-isearch-pop-state): New functions.
-rw-r--r--etc/NEWS10
-rw-r--r--lisp/ChangeLog18
-rw-r--r--lisp/simple.el215
3 files changed, 204 insertions, 39 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 84abb56e56a..0d79d30f4ee 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -57,6 +57,16 @@ recenter the visited source file. Its value can be a number (for example,
57 57
58** New command kill-matching-buffers kills buffers whose name matches a regexp. 58** New command kill-matching-buffers kills buffers whose name matches a regexp.
59 59
60** Minibuffer changes:
61
62*** isearch started in the minibuffer searches in the minibuffer history.
63Reverse isearch commands (C-r, C-M-r) search in previous minibuffer
64history elements, and forward isearch commands (C-s, C-M-s) search in
65next history elements. When the reverse search reaches the first history
66element, it wraps to the last history element, and the forward search
67wraps to the first history element. When the search is terminated, the
68history element containing the search string becomes the current.
69
60 70
61* New Modes and Packages in Emacs 23.1 71* New Modes and Packages in Emacs 23.1
62 72
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 88481804473..b8872038d0a 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,21 @@
12007-07-23 Juri Linkov <juri@jurta.org>
2
3 * isearch.el (isearch-message-function): New variable.
4 (isearch-update, isearch-search): Use it.
5
6 * simple.el (goto-history-element): New function created from
7 next-history-element.
8 (next-history-element): Most code moved to goto-history-element.
9 Call goto-history-element with (- minibuffer-history-position n).
10 (previous-history-element): Call goto-history-element with (+
11 minibuffer-history-position n).
12 (minibuffer-setup-hook): Add minibuffer-history-isearch-setup.
13 (minibuffer-history-isearch-message-overlay): New buffer-local variable.
14 (minibuffer-history-isearch-setup, minibuffer-history-isearch-end)
15 (minibuffer-history-isearch-search, minibuffer-history-isearch-message)
16 (minibuffer-history-isearch-wrap, minibuffer-history-isearch-push-state)
17 (minibuffer-history-isearch-pop-state): New functions.
18
12007-07-23 Thien-Thi Nguyen <ttn@gnuvola.org> 192007-07-23 Thien-Thi Nguyen <ttn@gnuvola.org>
2 20
3 * vc-hooks.el (vc-stay-local-p): Fix bug: Avoid remove-if-not. 21 * vc-hooks.el (vc-stay-local-p): Fix bug: Avoid remove-if-not.
diff --git a/lisp/simple.el b/lisp/simple.el
index c052ce3574b..10374e16cd2 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1300,55 +1300,61 @@ makes the search case-sensitive."
1300 1300
1301(defvar minibuffer-temporary-goal-position nil) 1301(defvar minibuffer-temporary-goal-position nil)
1302 1302
1303(defun goto-history-element (nabs)
1304 "Puts element of the minibuffer history in the minibuffer.
1305The argument NABS specifies the absolute history position."
1306 (interactive "p")
1307 (let ((minimum (if minibuffer-default -1 0))
1308 elt minibuffer-returned-to-present)
1309 (if (and (zerop minibuffer-history-position)
1310 (null minibuffer-text-before-history))
1311 (setq minibuffer-text-before-history
1312 (minibuffer-contents-no-properties)))
1313 (if (< nabs minimum)
1314 (if minibuffer-default
1315 (error "End of history; no next item")
1316 (error "End of history; no default available")))
1317 (if (> nabs (length (symbol-value minibuffer-history-variable)))
1318 (error "Beginning of history; no preceding item"))
1319 (unless (memq last-command '(next-history-element
1320 previous-history-element))
1321 (let ((prompt-end (minibuffer-prompt-end)))
1322 (set (make-local-variable 'minibuffer-temporary-goal-position)
1323 (cond ((<= (point) prompt-end) prompt-end)
1324 ((eobp) nil)
1325 (t (point))))))
1326 (goto-char (point-max))
1327 (delete-minibuffer-contents)
1328 (setq minibuffer-history-position nabs)
1329 (cond ((= nabs -1)
1330 (setq elt minibuffer-default))
1331 ((= nabs 0)
1332 (setq elt (or minibuffer-text-before-history ""))
1333 (setq minibuffer-returned-to-present t)
1334 (setq minibuffer-text-before-history nil))
1335 (t (setq elt (nth (1- minibuffer-history-position)
1336 (symbol-value minibuffer-history-variable)))))
1337 (insert
1338 (if (and (eq minibuffer-history-sexp-flag (minibuffer-depth))
1339 (not minibuffer-returned-to-present))
1340 (let ((print-level nil))
1341 (prin1-to-string elt))
1342 elt))
1343 (goto-char (or minibuffer-temporary-goal-position (point-max)))))
1344
1303(defun next-history-element (n) 1345(defun next-history-element (n)
1304 "Puts next element of the minibuffer history in the minibuffer. 1346 "Puts next element of the minibuffer history in the minibuffer.
1305With argument N, it uses the Nth following element." 1347With argument N, it uses the Nth following element."
1306 (interactive "p") 1348 (interactive "p")
1307 (or (zerop n) 1349 (or (zerop n)
1308 (let ((narg (- minibuffer-history-position n)) 1350 (goto-history-element (- minibuffer-history-position n))))
1309 (minimum (if minibuffer-default -1 0))
1310 elt minibuffer-returned-to-present)
1311 (if (and (zerop minibuffer-history-position)
1312 (null minibuffer-text-before-history))
1313 (setq minibuffer-text-before-history
1314 (minibuffer-contents-no-properties)))
1315 (if (< narg minimum)
1316 (if minibuffer-default
1317 (error "End of history; no next item")
1318 (error "End of history; no default available")))
1319 (if (> narg (length (symbol-value minibuffer-history-variable)))
1320 (error "Beginning of history; no preceding item"))
1321 (unless (memq last-command '(next-history-element
1322 previous-history-element))
1323 (let ((prompt-end (minibuffer-prompt-end)))
1324 (set (make-local-variable 'minibuffer-temporary-goal-position)
1325 (cond ((<= (point) prompt-end) prompt-end)
1326 ((eobp) nil)
1327 (t (point))))))
1328 (goto-char (point-max))
1329 (delete-minibuffer-contents)
1330 (setq minibuffer-history-position narg)
1331 (cond ((= narg -1)
1332 (setq elt minibuffer-default))
1333 ((= narg 0)
1334 (setq elt (or minibuffer-text-before-history ""))
1335 (setq minibuffer-returned-to-present t)
1336 (setq minibuffer-text-before-history nil))
1337 (t (setq elt (nth (1- minibuffer-history-position)
1338 (symbol-value minibuffer-history-variable)))))
1339 (insert
1340 (if (and (eq minibuffer-history-sexp-flag (minibuffer-depth))
1341 (not minibuffer-returned-to-present))
1342 (let ((print-level nil))
1343 (prin1-to-string elt))
1344 elt))
1345 (goto-char (or minibuffer-temporary-goal-position (point-max))))))
1346 1351
1347(defun previous-history-element (n) 1352(defun previous-history-element (n)
1348 "Puts previous element of the minibuffer history in the minibuffer. 1353 "Puts previous element of the minibuffer history in the minibuffer.
1349With argument N, it uses the Nth previous element." 1354With argument N, it uses the Nth previous element."
1350 (interactive "p") 1355 (interactive "p")
1351 (next-history-element (- n))) 1356 (or (zerop n)
1357 (goto-history-element (+ minibuffer-history-position n))))
1352 1358
1353(defun next-complete-history-element (n) 1359(defun next-complete-history-element (n)
1354 "Get next history element which completes the minibuffer before the point. 1360 "Get next history element which completes the minibuffer before the point.
@@ -1381,6 +1387,137 @@ Return 0 if current buffer is not a minibuffer."
1381 ;; the buffer; this should be 0 for normal buffers. 1387 ;; the buffer; this should be 0 for normal buffers.
1382 (1- (minibuffer-prompt-end))) 1388 (1- (minibuffer-prompt-end)))
1383 1389
1390;; isearch minibuffer history
1391(add-hook 'minibuffer-setup-hook 'minibuffer-history-isearch-setup)
1392
1393(defvar minibuffer-history-isearch-message-overlay)
1394(make-variable-buffer-local 'minibuffer-history-isearch-message-overlay)
1395
1396(defun minibuffer-history-isearch-setup ()
1397 "Set up a minibuffer for using isearch to search the minibuffer history.
1398Intended to be added to `minibuffer-setup-hook'."
1399 (set (make-local-variable 'isearch-search-fun-function)
1400 'minibuffer-history-isearch-search)
1401 (set (make-local-variable 'isearch-message-function)
1402 'minibuffer-history-isearch-message)
1403 (set (make-local-variable 'isearch-wrap-function)
1404 'minibuffer-history-isearch-wrap)
1405 (set (make-local-variable 'isearch-push-state-function)
1406 'minibuffer-history-isearch-push-state)
1407 (add-hook 'isearch-mode-end-hook 'minibuffer-history-isearch-end nil t))
1408
1409(defun minibuffer-history-isearch-end ()
1410 "Clean up the minibuffer after terminating isearch in the minibuffer."
1411 (if minibuffer-history-isearch-message-overlay
1412 (delete-overlay minibuffer-history-isearch-message-overlay)))
1413
1414(defun minibuffer-history-isearch-search ()
1415 "Return the proper search function, for isearch in minibuffer history."
1416 (cond
1417 (isearch-word
1418 (if isearch-forward 'word-search-forward 'word-search-backward))
1419 (t
1420 (lambda (string bound noerror)
1421 (let ((search-fun
1422 ;; Use standard functions to search within minibuffer text
1423 (cond
1424 (isearch-regexp
1425 (if isearch-forward 're-search-forward 're-search-backward))
1426 (t
1427 (if isearch-forward 'search-forward 'search-backward))))
1428 found)
1429 ;; Avoid lazy-highlighting matches in the minibuffer prompt when
1430 ;; searching forward. Lazy-highlight calls this lambda with the
1431 ;; bound arg, so skip the minibuffer prompt.
1432 (if (and bound isearch-forward (< (point) (minibuffer-prompt-end)))
1433 (goto-char (minibuffer-prompt-end)))
1434 (or
1435 ;; 1. First try searching in the initial minibuffer text
1436 (funcall search-fun string
1437 (if isearch-forward bound (minibuffer-prompt-end))
1438 noerror)
1439 ;; 2. If the above search fails, start putting next/prev history
1440 ;; elements in the minibuffer successively, and search the string
1441 ;; in them. Do this only when bound is nil (i.e. not while
1442 ;; lazy-highlighting search strings in the current minibuffer text).
1443 (unless bound
1444 (condition-case nil
1445 (progn
1446 (while (not found)
1447 (cond (isearch-forward
1448 (next-history-element 1)
1449 (goto-char (minibuffer-prompt-end)))
1450 (t
1451 (previous-history-element 1)
1452 (goto-char (point-max))))
1453 (setq isearch-barrier (point) isearch-opoint (point))
1454 ;; After putting the next/prev history element, search
1455 ;; the string in them again, until next-history-element
1456 ;; or previous-history-element raises an error at the
1457 ;; beginning/end of history.
1458 (setq found (funcall search-fun string
1459 (unless isearch-forward
1460 ;; For backward search, don't search
1461 ;; in the minibuffer prompt
1462 (minibuffer-prompt-end))
1463 noerror)))
1464 ;; Return point of the new search result
1465 (point))
1466 ;; Return nil when next(prev)-history-element fails
1467 (error nil)))))))))
1468
1469(defun minibuffer-history-isearch-message (&optional c-q-hack ellipsis)
1470 "Display the minibuffer history search prompt.
1471If there are no search errors, this function displays an overlay with
1472the isearch prompt which replaces the original minibuffer prompt.
1473Otherwise, it displays the standard isearch message returned from
1474`isearch-message'."
1475 (if (not (and (minibufferp) isearch-success (not isearch-error)))
1476 ;; Use standard function `isearch-message' when not in the minibuffer,
1477 ;; or search fails, or has an error (like incomplete regexp).
1478 ;; This function overwrites minibuffer text with isearch message,
1479 ;; so it's possible to see what is wrong in the search string.
1480 (isearch-message c-q-hack ellipsis)
1481 ;; Otherwise, put the overlay with the standard isearch prompt over
1482 ;; the initial minibuffer prompt.
1483 (if (overlayp minibuffer-history-isearch-message-overlay)
1484 (move-overlay minibuffer-history-isearch-message-overlay
1485 (point-min) (minibuffer-prompt-end))
1486 (setq minibuffer-history-isearch-message-overlay
1487 (make-overlay (point-min) (minibuffer-prompt-end)))
1488 (overlay-put minibuffer-history-isearch-message-overlay 'evaporate t))
1489 (overlay-put minibuffer-history-isearch-message-overlay
1490 'display (isearch-message-prefix c-q-hack ellipsis))
1491 ;; And clear any previous isearch message.
1492 (message "")))
1493
1494(defun minibuffer-history-isearch-wrap ()
1495 "Wrap the minibuffer history search when search is failed.
1496Move point to the first history element for a forward search,
1497or to the last history element for a backward search."
1498 (unless isearch-word
1499 ;; When `minibuffer-history-isearch-search' fails on reaching the
1500 ;; beginning/end of the history, wrap the search to the first/last
1501 ;; minibuffer history element.
1502 (if isearch-forward
1503 (goto-history-element (length (symbol-value minibuffer-history-variable)))
1504 (goto-history-element 0))
1505 (setq isearch-success t))
1506 (goto-char (if isearch-forward (minibuffer-prompt-end) (point-max))))
1507
1508(defun minibuffer-history-isearch-push-state ()
1509 "Save a function restoring the state of minibuffer history search.
1510Save `minibuffer-history-position' to the additional state parameter
1511in the search status stack."
1512 `(lambda (cmd)
1513 (minibuffer-history-isearch-pop-state cmd ,minibuffer-history-position)))
1514
1515(defun minibuffer-history-isearch-pop-state (cmd hist-pos)
1516 "Restore the minibuffer history search state.
1517Go to the history element by the absolute history position `hist-pos'."
1518 (goto-history-element hist-pos))
1519
1520
1384;Put this on C-x u, so we can force that rather than C-_ into startup msg 1521;Put this on C-x u, so we can force that rather than C-_ into startup msg
1385(defalias 'advertised-undo 'undo) 1522(defalias 'advertised-undo 'undo)
1386 1523