]> code.delx.au - gnu-emacs/blobdiff - lisp/mouse.el
(ps-mule-begin-job): Redo this change "if
[gnu-emacs] / lisp / mouse.el
index 1b053404c3cc61cd11bca25b241be5b8e13d4027..47ede180693cf884d4699462d39fc38474d75d2c 100644 (file)
@@ -49,6 +49,8 @@
   ;; Switch to the window clicked on, because otherwise
   ;; the mode's commands may not make sense.
   (interactive "@e\nP")
+  ;; Let the mode update its menus first.
+  (run-hooks 'activate-menubar-hook)
   (let (;; This is where mouse-major-mode-menu-prefix
        ;; returns the prefix we should use (after menu-bar).
        ;; It is either nil or (SOME-SYMBOL).
 
 (defun mouse-delete-window (click)
   "Delete the window you click on.
-This must be bound to a mouse click."
+If the frame has just one window, bury the current buffer instead.
+This command must be bound to a mouse click."
   (interactive "e")
-  (mouse-minibuffer-check click)
-  (delete-window (posn-window (event-start click))))
+  (if (one-window-p t)
+      (bury-buffer)
+    (mouse-minibuffer-check click)
+    (delete-window (posn-window (event-start click)))))
 
 (defun mouse-select-window (click)
   "Select the window clicked on; don't move point."
@@ -312,12 +317,12 @@ This command must be bound to a mouse click."
              'right)))
     (if (one-window-p t)
        (error "Attempt to resize sole ordinary window"))
-    (if (eq which-side 'left)
-       (if (= (nth 0 (window-edges start-event-window)) 0)
-           (error "Attempt to drag leftmost scrollbar"))
-      (if (= (nth 2 (window-edges start-event-window))
-            (frame-width start-event-frame))
-         (error "Attempt to drag rightmost scrollbar")))
+    (if (eq which-side 'right)
+       (if (= (nth 2 (window-edges start-event-window))
+              (frame-width start-event-frame))
+           (error "Attempt to drag rightmost scrollbar"))
+      (if (= (nth 0 (window-edges start-event-window)) 0)
+         (error "Attempt to drag leftmost scrollbar")))
     (track-mouse
       (progn
        ;; enlarge-window only works on the selected window, so
@@ -358,10 +363,10 @@ This command must be bound to a mouse click."
                 (save-selected-window
                   ;; If the scroll bar is on the window's left,
                   ;; adjust the window on the left.
-                  (if (eq which-side 'left)
-                      (select-window (previous-window)))
+                  (unless (eq which-side 'right)
+                    (select-window (previous-window)))
                   (setq x (- (car (cdr mouse))
-                             (if (eq which-side 'left) 2 0))
+                             (if (eq which-side 'right) 0 2))
                         edges (window-edges)
                         left (nth 0 edges)
                         right (nth 2 edges))
@@ -431,7 +436,7 @@ This should be bound to a mouse drag event."
     ;; Don't set this-command to kill-region, so that a following
     ;; C-w will not double the text in the kill ring.
     ;; Ignore last-command so we don't append to a preceding kill.
-    (let (this-command last-command)
+    (let (this-command last-command deactivate-mark)
       (copy-region-as-kill (mark) (point)))
     (mouse-set-region-1)))
 
@@ -478,11 +483,13 @@ Upon exit, point is at the far edge of the newly visible text."
                 (progn
                   (set-window-start window (point))
                   (if (natnump jump)
-                      (progn
-                        (goto-char (window-end window))
-                        ;; window-end doesn't reflect the window's new
-                        ;; start position until the next redisplay.  Hurrah.
-                        (vertical-motion (1- jump) window))
+                      (if (window-end window)
+                          (progn
+                            (goto-char (window-end window))
+                            ;; window-end doesn't reflect the window's new
+                            ;; start position until the next redisplay.
+                            (vertical-motion (1- jump) window))
+                        (vertical-motion (- (window-height window) 2)))
                     (goto-char (window-start window)))
                   (if overlay
                       (move-overlay overlay start (point)))
@@ -580,6 +587,25 @@ remains active.  Otherwise, it remains until the next input event."
                  (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
                                     mouse-drag-overlay start-point)
                  (setq end-of-range (overlay-end mouse-drag-overlay))))))))))
+      ;; In case we did not get a mouse-motion event
+      ;; for the final move of the mouse before a drag event
+      ;; pretend that we did get one.
+      (when (and (memq 'drag (event-modifiers (car-safe event)))
+                (setq end (event-end event)
+                      end-point (posn-point end))
+                (eq (posn-window end) start-window)
+                (integer-or-marker-p end-point))
+
+       ;; Go to START-POINT first, so that when we move to END-POINT,
+       ;; if it's in the middle of intangible text,
+       ;; point jumps in the direction away from START-POINT.
+       (goto-char start-point)
+       (goto-char end-point)
+       (if (zerop (% click-count 3))
+           (setq end-of-range (point)))
+       (let ((range (mouse-start-end start-point (point) click-count)))
+         (move-overlay mouse-drag-overlay (car range) (nth 1 range))))
+
       (if (consp event)
          (let ((fun (key-binding (vector (car event)))))
            ;; Run the binding of the terminating up-event, if possible.
@@ -606,7 +632,9 @@ remains active.  Otherwise, it remains until the next input event."
                       last-command this-command)
                  (push-mark region-commencement t t)
                  (goto-char region-termination)
-                 (copy-region-as-kill (point) (mark t))
+                 ;; Don't let copy-region-as-kill set deactivate-mark.
+                 (let (deactivate-mark)
+                   (copy-region-as-kill (point) (mark t)))
                  (let ((buffer (current-buffer)))
                    (mouse-show-mark)
                    ;; mouse-show-mark can call read-event,
@@ -630,7 +658,18 @@ remains active.  Otherwise, it remains until the next input event."
 If DIR is positive skip forward; if negative, skip backward."
   (let* ((char (following-char))
         (syntax (char-to-string (char-syntax char))))
-    (cond ((or (string= syntax "w") (string= syntax " "))
+    (cond ((string= syntax "w")
+          ;; Here, we can't use skip-syntax-forward/backward because
+          ;; they don't pay attention to word-separating-categories,
+          ;; and thus they will skip over a true word boundary.  So,
+          ;; we simularte the original behaviour by using
+          ;; forward-word.
+          (if (< dir 0)
+              (if (not (looking-at "\\<"))
+                  (forward-word -1))
+            (if (or (looking-at "\\<") (not (looking-at "\\>")))
+                (forward-word 1))))
+         ((string= syntax " ")
           (if (< dir 0)
               (skip-syntax-backward syntax)
             (skip-syntax-forward syntax)))
@@ -918,7 +957,9 @@ selection through the word or line clicked on.  If you do this
 again in a different position, it extends the selection again.
 If you do this twice in the same position, the selection is killed." 
   (interactive "e")
-  (let ((before-scroll point-before-scroll))
+  (let ((before-scroll
+        (with-current-buffer (window-buffer (posn-window (event-start click)))
+          point-before-scroll)))
     (mouse-minibuffer-check click)
     (let ((click-posn (posn-point (event-start click)))
          ;; Don't let a subsequent kill command append to this one:
@@ -1277,8 +1318,9 @@ again.  If you do this twice in the same position, it kills the selection."
                    (kill-new (buffer-substring
                               (overlay-start mouse-secondary-overlay)
                               (overlay-end mouse-secondary-overlay)) t)
-                 (copy-region-as-kill (overlay-start mouse-secondary-overlay)
-                                      (overlay-end mouse-secondary-overlay))))
+                 (let (deactivate-mark)
+                   (copy-region-as-kill (overlay-start mouse-secondary-overlay)
+                                        (overlay-end mouse-secondary-overlay)))))
            (if mouse-secondary-start
                ;; All we have is one end of a selection,
                ;; so put the other end here.
@@ -1296,13 +1338,24 @@ again.  If you do this twice in the same position, it kills the selection."
                            (overlay-start mouse-secondary-overlay)
                            (overlay-end mouse-secondary-overlay)))))))
 \f
-(defcustom mouse-menu-buffer-maxlen 20
+(defcustom mouse-buffer-menu-maxlen 20
   "*Number of buffers in one pane (submenu) of the buffer menu.
 If we have lots of buffers, divide them into groups of
-`mouse-menu-buffer-maxlen' and make a pane (or submenu) for each one."
+`mouse-buffer-menu-maxlen' and make a pane (or submenu) for each one."
   :type 'integer
   :group 'mouse)
 
+(defcustom mouse-buffer-menu-mode-mult 4
+  "*Group the buffers by the major mode groups on \\[mouse-buffer-menu]?
+This number which determines (in a hairy way) whether \\[mouse-buffer-menu]
+will split the buffer menu by the major modes (see
+`mouse-buffer-menu-mode-groups') or just by menu length.
+Set to 1 (or even 0!) if you want to group by major mode always, and to
+a large number if you prefer a mixed multitude.  The default is 4."
+  :type 'integer
+  :group 'mouse
+  :version "20.3")
+
 (defvar mouse-buffer-menu-mode-groups
   '(("Info\\|Help\\|Apropos\\|Man" . "Help")
     ("\\bVM\\b\\|\\bMH\\b\\|Message\\|Mail\\|Group\\|Score\\|Summary\\|Article"
@@ -1322,8 +1375,7 @@ This switches buffers in the window that you clicked on,
 and selects that window."
   (interactive "e")
   (mouse-minibuffer-check event)
-  (let (buffers alist menu split-by-major-mode sum-of-squares)
-    (setq buffers (buffer-list))
+  (let ((buffers (buffer-list))  alist menu split-by-major-mode sum-of-squares)
     ;; Make an alist of elements that look like (MENU-ITEM . BUFFER).
     (let ((tail buffers))
       (while tail
@@ -1352,10 +1404,10 @@ and selects that window."
       (while tail
        (setq sum-of-squares
              (+ sum-of-squares
-                (* (length (cdr (cdr (car tail))))
-                   (length (cdr (cdr (car tail)))))))
+                (let ((len (length (cdr (cdr (car tail)))))) (* len len))))
        (setq tail (cdr tail))))
-    (if (< (* sum-of-squares 4) (* (length buffers) (length buffers)))
+    (if (< (* sum-of-squares mouse-buffer-menu-mode-mult)
+          (* (length buffers) (length buffers)))
        ;; Subdividing by major modes really helps, so let's do it.
        (let (subdivided-menus (buffers-left (length buffers)))
          ;; Sort the list to put the most popular major modes first.
@@ -1385,23 +1437,20 @@ and selects that window."
                    (cons (cons
                           "Others"
                           (mouse-buffer-menu-alist
-                           (apply 'append
-                                  (mapcar 'cdr
-                                          (mapcar 'cdr split-by-major-mode)))))
+                           ;; we don't need split-by-major-mode any
+                           ;; more, so we can ditch it with nconc.
+                           (apply 'nconc (mapcar 'cddr split-by-major-mode))))
                          subdivided-menus)))
-         (setq subdivided-menus
-               (nreverse subdivided-menus))
-         (setq menu (cons "Buffer Menu" subdivided-menus)))
+         (setq menu (cons "Buffer Menu" (nreverse subdivided-menus))))
       (progn
        (setq alist (mouse-buffer-menu-alist buffers))
        (setq menu (cons "Buffer Menu"
                         (mouse-buffer-menu-split "Select Buffer" alist)))))
     (let ((buf (x-popup-menu event menu))
          (window (posn-window (event-start event))))
-      (if buf
-         (progn
+      (when buf
            (or (framep window) (select-window window))
-           (switch-to-buffer buf))))))
+       (switch-to-buffer buf)))))
 
 (defun mouse-buffer-menu-alist (buffers)
   (let (tail
@@ -1448,15 +1497,15 @@ and selects that window."
 (defun mouse-buffer-menu-split (title alist)
   ;; If we have lots of buffers, divide them into groups of 20
   ;; and make a pane (or submenu) for each one.
-  (if (> (length alist) (/ (* mouse-menu-buffer-maxlen 3) 2))
+  (if (> (length alist) (/ (* mouse-buffer-menu-maxlen 3) 2))
       (let ((alist alist) sublists next
            (i 1))
        (while alist
-         ;; Pull off the next mouse-menu-buffer-maxlen buffers
+         ;; Pull off the next mouse-buffer-menu-maxlen buffers
          ;; and make them the next element of sublist.
-         (setq next (nthcdr mouse-menu-buffer-maxlen alist))
+         (setq next (nthcdr mouse-buffer-menu-maxlen alist))
          (if next
-             (setcdr (nthcdr (1- mouse-menu-buffer-maxlen) alist)
+             (setcdr (nthcdr (1- mouse-buffer-menu-maxlen) alist)
                      nil))
          (setq sublists (cons (cons (format "Buffers %d" i) alist)
                               sublists))