]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement default help-echo for mode line.
authorChong Yidong <cyd@gnu.org>
Sun, 3 Jun 2012 09:03:23 +0000 (17:03 +0800)
committerChong Yidong <cyd@gnu.org>
Sun, 3 Jun 2012 09:03:23 +0000 (17:03 +0800)
* lisp/bindings.el: Remove explicit help-echo from format-mode-line.
(mode-line-front-space, mode-line-end-spaces)
(mode-line-misc-info): New variables.
(mode-line-modes, mode-line-position): Move the default value to
the variable definition.
(mode-line-default-help-echo): New defcustom.

* src/buffer.c (buffer_local_value_1): New function, split from
Fbuffer_local_value; can return Qunbound.
(Fbuffer_local_value): Use it.
(Vmode_line_format): Docstring tweaks.

* src/xdisp.c (calc_pixel_width_or_height): Use Fbuffer_local_value.
(note_mode_line_or_margin_highlight): If there is no help echo,
use mode-line-default-help-echo.  Handle the case where the mouse
position is past the end of the mode line string.

* doc/lispref/modes.texi (Mode Line Data): Use "mode line construct"
terminology for consistency.

doc/lispref/ChangeLog
doc/lispref/modes.texi
lisp/ChangeLog
lisp/bindings.el
src/ChangeLog
src/buffer.c
src/buffer.h
src/xdisp.c

index 850b3f9cf549921cc3ad0cf85a435efeedab78b4..b774809feb9a5fa0277e56cd4eabef742c0e4624 100644 (file)
@@ -1,3 +1,8 @@
+2012-06-03  Chong Yidong  <cyd@gnu.org>
+
+       * modes.texi (Mode Line Data): Use "mode line construct"
+       terminology for consistency.
+
 2012-05-27  Glenn Morris  <rgm@gnu.org>
 
        * abbrevs.texi, advice.texi, anti.texi, backups.texi:
index 8dca250ce1022d86d1e213b7582bb084f2102e1c..96e9b78f8715edd149161acedcd854c69b17c707 100644 (file)
@@ -1843,9 +1843,9 @@ properties specified by @var{props} to the result.  The argument
 A list whose first element is a symbol that is not a keyword specifies
 a conditional.  Its meaning depends on the value of @var{symbol}.  If
 @var{symbol} has a non-@code{nil} value, the second element,
-@var{then}, is processed recursively as a mode line element.
+@var{then}, is processed recursively as a mode line construct.
 Otherwise, the third element, @var{else}, is processed recursively.
-You may omit @var{else}; then the mode line element displays nothing
+You may omit @var{else}; then the mode line construct displays nothing
 if the value of @var{symbol} is @code{nil} or void.
 
 @item (@var{width} @var{rest}@dots{})
index e39b8a64205fec4417a9a26c1b4659aabf424710..5a3b1d3926d1218c896de36cec4e2f215ec22dc2 100644 (file)
@@ -1,3 +1,13 @@
+2012-06-03  Chong Yidong  <cyd@gnu.org>
+
+       * bindings.el: Remove explicit help text from format-mode-line.
+       It is now supplied by mode-line-default-help-echo.
+       (mode-line-front-space, mode-line-end-spaces)
+       (mode-line-misc-info): New variables.
+       (mode-line-modes, mode-line-position): Move the default value to
+       the variable definition.
+       (mode-line-default-help-echo): New defcustom.
+
 2012-06-02  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * simple.el (execute-extended-command): Set real-this-command
index 69d96ab68894ec3e97f23621ed5418922f7ac635..65dd68a4447a37adfc3fe87902fdce0813fd9236 100644 (file)
@@ -43,7 +43,6 @@ corresponding to the mode line clicked."
     (with-no-warnings (toggle-read-only))
     (force-mode-line-update)))
 
-
 (defun mode-line-toggle-modified (event)
   "Toggle the buffer-modified flag from the mode-line."
   (interactive "e")
@@ -52,7 +51,6 @@ corresponding to the mode line clicked."
     (set-buffer-modified-p (not (buffer-modified-p)))
     (force-mode-line-update)))
 
-
 (defun mode-line-widen (event)
   "Widen a buffer from the mode-line."
   (interactive "e")
@@ -61,7 +59,6 @@ corresponding to the mode line clicked."
     (widen)
     (force-mode-line-update)))
 
-
 (defvar mode-line-input-method-map
   (let ((map (make-sparse-keymap)))
     (define-key map [mode-line mouse-2]
@@ -81,7 +78,6 @@ corresponding to the mode line clicked."
          (describe-current-input-method))))
     (purecopy map)))
 
-
 (defvar mode-line-coding-system-map
   (let ((map (make-sparse-keymap)))
     (define-key map [mode-line mouse-1]
@@ -95,7 +91,6 @@ corresponding to the mode line clicked."
     (purecopy map))
   "Local keymap for the coding-system part of the mode line.")
 
-
 (defun mode-line-change-eol (event)
   "Cycle through the various possible kinds of end-of-line styles."
   (interactive "e")
@@ -130,13 +125,28 @@ corresponding to the mode line clicked."
       (push (cons eol (cons mnemonic desc)) mode-line-eol-desc-cache)
       desc)))
 
-(defvar mode-line-client
-  `(""
-    (:propertize ("" (:eval (if (frame-parameter nil 'client) "@" "")))
-                help-echo ,(purecopy "emacsclient frame")))
-  "Mode-line control for identifying emacsclient frames.")
-;;;###autoload
-(put 'mode-line-client 'risky-local-variable t)
+\f
+;;; Mode line contents
+
+(defcustom mode-line-default-help-echo
+  "mouse-1: Select (drag to resize)\n\
+mouse-2: Make current window occupy the whole frame\n\
+mouse-3: Remove current window from display"
+  "Default help text for the mode line.
+If the value is a string, it specifies the tooltip or echo area
+message to display when the mouse is moved over the mode line.
+If the text at the mouse position has a `help-echo' text
+property, that overrides this variable."
+  :type '(choice (const :tag "No help" :value nil) string)
+  :version "24.2"
+  :group 'mode-line)
+
+(defvar mode-line-front-space '(:eval (if (display-graphic-p) " " "-"))
+  "Mode line construct to put at the front of the mode line.
+By default, this construct is displayed right at the beginning of
+the mode line, except that if there is a memory-full message, it
+is displayed first.")
+(put 'mode-line-front-space 'risky-local-variable t)
 
 (defvar mode-line-mule-info
   `(""
@@ -167,7 +177,7 @@ mouse-3: Describe current input method"))
       'mouse-face 'mode-line-highlight
       'local-map mode-line-coding-system-map)
     (:eval (mode-line-eol-desc)))
-  "Mode-line control for displaying information of multilingual environment.
+  "Mode line construct for displaying information of multilingual environment.
 Normally it displays current input method (if any activated) and
 mnemonics of the following coding systems:
   coding system for saving or writing the current buffer
@@ -177,34 +187,17 @@ mnemonics of the following coding systems:
   ;;  coding system for decoding output of buffer process (if any)
   ;;  coding system for encoding text to send to buffer process (if any)."
 )
-
 ;;;###autoload
 (put 'mode-line-mule-info 'risky-local-variable t)
 (make-variable-buffer-local 'mode-line-mule-info)
 
-;; MSDOS frames have window-system, but want the Fn identification.
-(defun mode-line-frame-control ()
-  "Compute mode-line control for frame identification.
-Value is used for `mode-line-frame-identification', which see."
-  (if (or (null window-system)
-         (eq window-system 'pc))
-      "-%F  "
-    "  "))
-
-;; We need to defer the call to mode-line-frame-control to the time
-;; the mode line is actually displayed.
-(defvar mode-line-frame-identification '(:eval (mode-line-frame-control))
-  "Mode-line control to describe the current frame.")
-;;;###autoload
-(put 'mode-line-frame-identification 'risky-local-variable t)
-
-(defvar mode-line-process nil "\
-Mode-line control for displaying info on process status.
-Normally nil in most modes, since there is no process to display.")
-
+(defvar mode-line-client
+  `(""
+    (:propertize ("" (:eval (if (frame-parameter nil 'client) "@" "")))
+                help-echo ,(purecopy "emacsclient frame")))
+  "Mode line construct for identifying emacsclient frames.")
 ;;;###autoload
-(put 'mode-line-process 'risky-local-variable t)
-(make-variable-buffer-local 'mode-line-process)
+(put 'mode-line-client 'risky-local-variable t)
 
 (defvar mode-line-modified
   (list (propertize
@@ -232,8 +225,7 @@ Normally nil in most modes, since there is no process to display.")
         'local-map (purecopy (make-mode-line-mouse-map
                               'mouse-1 #'mode-line-toggle-modified))
         'mouse-face 'mode-line-highlight))
-  "Mode-line control for displaying whether current buffer is modified.")
-
+  "Mode line construct for displaying whether current buffer is modified.")
 ;;;###autoload
 (put 'mode-line-modified 'risky-local-variable t)
 (make-variable-buffer-local 'mode-line-modified)
@@ -251,24 +243,33 @@ Normally nil in most modes, since there is no process to display.")
                                               "Current directory is remote: "
                                             "Current directory is local: ")
                                           default-directory)))))))
-  "Mode-line flag to show if default-directory for current buffer is remote.")
+  "Mode line construct to indicate a remote buffer.")
 ;;;###autoload
 (put 'mode-line-remote 'risky-local-variable t)
-
 (make-variable-buffer-local 'mode-line-remote)
 
-;; Actual initialization is below.
-(defvar mode-line-position nil
-  "Mode-line control for displaying the position in the buffer.
-Normally displays the buffer percentage and, optionally, the
-buffer size, the line number and the column number.")
+;; MSDOS frames have window-system, but want the Fn identification.
+(defun mode-line-frame-control ()
+  "Compute mode line construct for frame identification.
+Value is used for `mode-line-frame-identification', which see."
+  (if (or (null window-system)
+         (eq window-system 'pc))
+      "-%F  "
+    "  "))
+
+;; We need to defer the call to mode-line-frame-control to the time
+;; the mode line is actually displayed.
+(defvar mode-line-frame-identification '(:eval (mode-line-frame-control))
+  "Mode line construct to describe the current frame.")
 ;;;###autoload
-(put 'mode-line-position 'risky-local-variable t)
+(put 'mode-line-frame-identification 'risky-local-variable t)
 
-(defvar mode-line-modes nil
-  "Mode-line control for displaying major and minor modes.")
+(defvar mode-line-process nil
+  "Mode line construct for displaying info on process status.
+Normally nil in most modes, since there is no process to display.")
 ;;;###autoload
-(put 'mode-line-modes 'risky-local-variable t)
+(put 'mode-line-process 'risky-local-variable t)
+(make-variable-buffer-local 'mode-line-process)
 
 (defvar mode-line-mode-menu (make-sparse-keymap "Minor Modes") "\
 Menu of mode operations in the mode line.")
@@ -292,6 +293,35 @@ Keymap to display on major mode.")
     map) "\
 Keymap to display on minor modes.")
 
+(defvar mode-line-modes
+  (let ((recursive-edit-help-echo "Recursive edit, type C-M-c to get out"))
+    (list (propertize "%[" 'help-echo recursive-edit-help-echo)
+         "("
+         `(:propertize ("" mode-name)
+                       help-echo "Major mode\n\
+mouse-1: Display major mode menu\n\
+mouse-2: Show help for major mode\n\
+mouse-3: Toggle minor modes"
+                       mouse-face mode-line-highlight
+                       local-map ,mode-line-major-mode-keymap)
+         '("" mode-line-process)
+         `(:propertize ("" minor-mode-alist)
+                       mouse-face mode-line-highlight
+                       help-echo "Minor mode\n\
+mouse-1: Display minor mode menu\n\
+mouse-2: Show help for minor mode\n\
+mouse-3: Toggle minor modes"
+                       local-map ,mode-line-minor-mode-keymap)
+         (propertize "%n" 'help-echo "mouse-2: Remove narrowing from the current buffer"
+                     'mouse-face 'mode-line-highlight
+                     'local-map (make-mode-line-mouse-map
+                                 'mouse-2 #'mode-line-widen))
+         ")"
+         (propertize "%]" 'help-echo recursive-edit-help-echo)
+         " "))
+  "Mode line construct for displaying major and minor modes.")
+(put 'mode-line-modes 'risky-local-variable t)
+
 (defvar mode-line-column-line-number-mode-map
   (let ((map (make-sparse-keymap))
        (menu-map (make-sparse-keymap "Toggle Line and Column Number Display")))
@@ -307,114 +337,47 @@ Keymap to display on minor modes.")
     map) "\
 Keymap to display on column and line numbers.")
 
-(let* ((help-echo
-       ;; The multi-line message doesn't work terribly well on the
-       ;; bottom mode line...  Better ideas?
-       ;;        "\
-       ;; mouse-1: select window, mouse-2: delete others, mouse-3: delete,
-       ;; drag-mouse-1: resize, C-mouse-2: split horizontally"
-       "mouse-1: Select (drag to resize)\n\
-mouse-2: Make current window occupy the whole frame\n\
-mouse-3: Remove current window from display")
-       (recursive-edit-help-echo "Recursive edit, type C-M-c to get out")
-       (spaces (propertize " " 'help-echo help-echo))
-       (standard-mode-line-format
-       (list
-        "%e"
-        `(:eval (if (display-graphic-p)
-                    ,(propertize " " 'help-echo help-echo)
-                  ,(propertize "-" 'help-echo help-echo)))
-        'mode-line-mule-info
-        'mode-line-client
-        'mode-line-modified
-        'mode-line-remote
-        'mode-line-frame-identification
-        'mode-line-buffer-identification
-        (propertize "   " 'help-echo help-echo)
-        'mode-line-position
-        '(vc-mode vc-mode)
-        (propertize "  " 'help-echo help-echo)
-        'mode-line-modes
-        `(which-func-mode ("" which-func-format ,spaces))
-        `(global-mode-string ("" global-mode-string ,spaces))
-        `(:eval (unless (display-graphic-p)
-                  ,(propertize "-%-" 'help-echo help-echo)))))
-       (standard-mode-line-modes
-       (list
-        (propertize "%[" 'help-echo recursive-edit-help-echo)
-        (propertize "(" 'help-echo help-echo)
-        `(:propertize ("" mode-name)
-                      help-echo "Major mode\n\
-mouse-1: Display major mode menu\n\
-mouse-2: Show help for major mode\n\
-mouse-3: Toggle minor modes"
-                      mouse-face mode-line-highlight
-                      local-map ,mode-line-major-mode-keymap)
-        '("" mode-line-process)
-        `(:propertize ("" minor-mode-alist)
-                      mouse-face mode-line-highlight
-                      help-echo "Minor mode\n\
-mouse-1: Display minor mode menu\n\
-mouse-2: Show help for minor mode\n\
-mouse-3: Toggle minor modes"
-                      local-map ,mode-line-minor-mode-keymap)
-        (propertize "%n" 'help-echo "mouse-2: Remove narrowing from the current buffer"
-                    'mouse-face 'mode-line-highlight
-                    'local-map (make-mode-line-mouse-map
-                                'mouse-2 #'mode-line-widen))
-        (propertize ")" 'help-echo help-echo)
-        (propertize "%]" 'help-echo recursive-edit-help-echo)
-        spaces))
-
-       (standard-mode-line-position
-       `((-3 ,(propertize
-               "%p"
-               'local-map mode-line-column-line-number-mode-map
-               'mouse-face 'mode-line-highlight
-               ;; XXX needs better description
-               'help-echo "Size indication mode\n\
+(defvar mode-line-position
+  `((-3 ,(propertize
+         "%p"
+         'local-map mode-line-column-line-number-mode-map
+         'mouse-face 'mode-line-highlight
+         ;; XXX needs better description
+         'help-echo "Size indication mode\n\
 mouse-1: Display Line and Column Mode Menu"))
-         (size-indication-mode
-          (8 ,(propertize
-               " of %I"
-               'local-map mode-line-column-line-number-mode-map
-               'mouse-face 'mode-line-highlight
-               ;; XXX needs better description
-               'help-echo "Size indication mode\n\
+    (size-indication-mode
+     (8 ,(propertize
+         " of %I"
+         'local-map mode-line-column-line-number-mode-map
+         'mouse-face 'mode-line-highlight
+         ;; XXX needs better description
+         'help-echo "Size indication mode\n\
 mouse-1: Display Line and Column Mode Menu")))
-         (line-number-mode
-          ((column-number-mode
-            (10 ,(propertize
-                  " (%l,%c)"
-                  'local-map mode-line-column-line-number-mode-map
-                  'mouse-face 'mode-line-highlight
-                  'help-echo "Line number and Column number\n\
+    (line-number-mode
+     ((column-number-mode
+       (10 ,(propertize
+            " (%l,%c)"
+            'local-map mode-line-column-line-number-mode-map
+            'mouse-face 'mode-line-highlight
+            'help-echo "Line number and Column number\n\
 mouse-1: Display Line and Column Mode Menu"))
-            (6 ,(propertize
-                 " L%l"
-                 'local-map mode-line-column-line-number-mode-map
-                 'mouse-face 'mode-line-highlight
-                 'help-echo "Line Number\n\
+       (6 ,(propertize
+           " L%l"
+           'local-map mode-line-column-line-number-mode-map
+           'mouse-face 'mode-line-highlight
+           'help-echo "Line Number\n\
 mouse-1: Display Line and Column Mode Menu"))))
-          ((column-number-mode
-            (5 ,(propertize
-                 " C%c"
-                 'local-map mode-line-column-line-number-mode-map
-                 'mouse-face 'mode-line-highlight
-                 'help-echo "Column number\n\
-mouse-1: Display Line and Column Mode Menu"))))))))
-
-  (setq-default mode-line-format standard-mode-line-format)
-  (put 'mode-line-format 'standard-value
-       (list `(quote ,standard-mode-line-format)))
-
-  (setq-default mode-line-modes standard-mode-line-modes)
-  (put 'mode-line-modes 'standard-value
-       (list `(quote ,standard-mode-line-modes)))
-
-  (setq-default mode-line-position standard-mode-line-position)
-  (put 'mode-line-position 'standard-value
-       (list `(quote ,standard-mode-line-position))))
+     ((column-number-mode
+       (5 ,(propertize
+           " C%c"
+           'local-map mode-line-column-line-number-mode-map
+           'mouse-face 'mode-line-highlight
+           'help-echo "Column number\n\
+mouse-1: Display Line and Column Mode Menu"))))))
+  "Mode line construct for displaying the position in the buffer.
+Normally displays the buffer percentage and, optionally, the
+buffer size, the line number and the column number.")
+(put 'mode-line-position 'risky-local-variable t)
 
 (defvar mode-line-buffer-identification-keymap
   ;; Add menu of buffer operations to the buffer identification part
@@ -444,16 +407,50 @@ mouse-3: next buffer")
                    'mouse-face 'mode-line-highlight
                    'local-map mode-line-buffer-identification-keymap)))
 
-(defvar mode-line-buffer-identification (propertized-buffer-identification "%12b") "\
-Mode-line control for identifying the buffer being displayed.
+(defvar mode-line-buffer-identification
+  (propertized-buffer-identification "%12b")
+  "Mode line construct for identifying the buffer being displayed.
 Its default value is (\"%12b\") with some text properties added.
 Major modes that edit things other than ordinary files may change this
 \(e.g. Info, Dired,...)")
-
 ;;;###autoload
 (put 'mode-line-buffer-identification 'risky-local-variable t)
 (make-variable-buffer-local 'mode-line-buffer-identification)
 
+(defvar mode-line-misc-info
+  '((which-func-mode ("" which-func-format " "))
+    (global-mode-string ("" global-mode-string " ")))
+  "Mode line construct for miscellaneous information.
+By default, this shows the information specified by
+`which-func-mode' and `global-mode-string'.")
+(put 'mode-line-misc-info 'risky-local-variable t)
+
+(defvar mode-line-end-spaces '(:eval (unless (display-graphic-p) "-%-"))
+  "Mode line construct to put at the end of the mode line.")
+(put 'mode-line-end-spaces 'risky-local-variable t)
+
+;; Default value of the top-level `mode-line-format' variable:
+(let ((standard-mode-line-format
+       (list "%e"
+            'mode-line-front-space
+            'mode-line-mule-info
+            'mode-line-client
+            'mode-line-modified
+            'mode-line-remote
+            'mode-line-frame-identification
+            'mode-line-buffer-identification
+            "   "
+            'mode-line-position
+            '(vc-mode vc-mode)
+            "  "
+            'mode-line-modes
+            'mode-line-misc-info
+            'mode-line-end-spaces)))
+  (setq-default mode-line-format standard-mode-line-format)
+  (put 'mode-line-format 'standard-value
+       (list `(quote ,standard-mode-line-format))))
+
+\f
 (defun mode-line-unbury-buffer (event) "\
 Call `unbury-buffer' in this window."
   (interactive "e")
@@ -551,8 +548,8 @@ Alist saying how to show minor modes in the mode line.
 Each element looks like (VARIABLE STRING);
 STRING is included in the mode line if VARIABLE's value is non-nil.
 
-Actually, STRING need not be a string; any possible mode-line element
-is okay.  See `mode-line-format'.")
+Actually, STRING need not be a string; any mode-line construct is
+okay.  See `mode-line-format'.")
 ;;;###autoload
 (put 'minor-mode-alist 'risky-local-variable t)
 ;; Don't use purecopy here--some people want to change these strings.
index b90db0b7fa942af75dfbdeefd13074bf200afac6..c0098445cb820d6883c77b23409a41eb9b7e720f 100644 (file)
@@ -1,3 +1,15 @@
+2012-06-03  Chong Yidong  <cyd@gnu.org>
+
+       * xdisp.c (calc_pixel_width_or_height): Use Fbuffer_local_value.
+       (note_mode_line_or_margin_highlight): If there is no help echo,
+       use mode-line-default-help-echo.  Handle the case where the mouse
+       position is past the end of the mode line string.
+
+       * buffer.c (buffer_local_value_1): New function, split from
+       Fbuffer_local_value; can return Qunbound.
+       (Fbuffer_local_value): Use it.
+       (Vmode_line_format): Docstring tweaks.
+
 2012-06-02  Paul Eggert  <eggert@cs.ucla.edu>
 
        * sysdep.c (system_process_attributes): Improve comment.
index 20260d5a5d8794558671fa93c58799143b7e4300..386d9a78153c9bc82a32e11849c0a70bc7c3f21a 100644 (file)
@@ -932,6 +932,21 @@ DEFUN ("buffer-local-value", Fbuffer_local_value,
 If VARIABLE does not have a buffer-local binding in BUFFER, the value
 is the default binding of the variable. */)
   (register Lisp_Object variable, register Lisp_Object buffer)
+{
+  register Lisp_Object result = buffer_local_value_1 (variable, buffer);
+
+  if (EQ (result, Qunbound))
+    xsignal1 (Qvoid_variable, variable);
+
+  return result;
+}
+
+
+/* Like Fbuffer_local_value, but return Qunbound if the variable is
+   locally unbound.  */
+
+Lisp_Object
+buffer_local_value_1 (Lisp_Object variable, Lisp_Object buffer)
 {
   register struct buffer *buf;
   register Lisp_Object result;
@@ -985,10 +1000,7 @@ is the default binding of the variable. */)
     default: abort ();
     }
 
-  if (!EQ (result, Qunbound))
-    return result;
-
-  xsignal1 (Qvoid_variable, variable);
+  return result;
 }
 
 /* Return an alist of the Lisp-level buffer-local bindings of
@@ -5329,31 +5341,40 @@ the mode line appears at the bottom.  */);
   DEFVAR_PER_BUFFER ("mode-line-format", &BVAR (current_buffer, mode_line_format),
                     Qnil,
                     doc: /* Template for displaying mode line for current buffer.
-Each buffer has its own value of this variable.
-Value may be nil, a string, a symbol or a list or cons cell.
+
+The value may be nil, a string, a symbol or a list.
+
 A value of nil means don't display a mode line.
-For a symbol, its value is used (but it is ignored if t or nil).
- A string appearing directly as the value of a symbol is processed verbatim
- in that the %-constructs below are not recognized.
- Note that unless the symbol is marked as a `risky-local-variable', all
- properties in any strings, as well as all :eval and :propertize forms
- in the value of that symbol will be ignored.
-For a list of the form `(:eval FORM)', FORM is evaluated and the result
- is used as a mode line element.  Be careful--FORM should not load any files,
- because that can cause an infinite recursion.
-For a list of the form `(:propertize ELT PROPS...)', ELT is displayed
- with the specified properties PROPS applied.
-For a list whose car is a symbol, the symbol's value is taken,
- and if that is non-nil, the cadr of the list is processed recursively.
- Otherwise, the caddr of the list (if there is one) is processed.
-For a list whose car is a string or list, each element is processed
- recursively and the results are effectively concatenated.
-For a list whose car is an integer, the cdr of the list is processed
-  and padded (if the number is positive) or truncated (if negative)
-  to the width specified by that number.
+
+For any symbol other than t or nil, the symbol's value is processed as
+ a mode line construct.  As a special exception, if that value is a
+ string, the string is processed verbatim, without handling any
+ %-constructs (see below).  Also, unless the symbol has a non-nil
+ `risky-local-variable' property, all properties in any strings, as
+ well as all :eval and :propertize forms in the value, are ignored.
+
+A list whose car is a string or list is processed by processing each
+ of the list elements recursively, as separate mode line constructs,
+ and concatenating the results.
+
+A list of the form `(:eval FORM)' is processed by evaluating FORM and
+ using the result as a mode line construct.  Be careful--FORM should
+ not load any files, because that can cause an infinite recursion.
+
+A list of the form `(:propertize ELT PROPS...)' is processed by
+ processing ELT as the mode line construct, and adding the text
+ properties PROPS to the result.
+
+A list whose car is a symbol is processed by examining the symbol's
+ value, and, if that value is non-nil, processing the cadr of the list
+ recursively; and if that value is nil, processing the caddr of the
+ list recursively.
+
+A list whose car is an integer is processed by processing the cadr of
+ the list, and padding (if the number is positive) or truncating (if
+ negative) to the width specified by that number.
+
 A string is printed verbatim in the mode line except for %-constructs:
-  (%-constructs are allowed when the string is the entire mode-line-format
-   or when it is found in a cons-cell or a list)
   %b -- print buffer name.      %f -- print visited file name.
   %F -- print frame name.
   %* -- print %, * or hyphen.   %+ -- print *, % or hyphen.
index 97d891f044b8df22adca816977a6965c79b8cfba..3aa4b11c45058bb09382d398f34721ae19f5ac56 100644 (file)
@@ -912,6 +912,7 @@ extern void validate_region (Lisp_Object *, Lisp_Object *);
 extern void set_buffer_internal (struct buffer *);
 extern void set_buffer_internal_1 (struct buffer *);
 extern void set_buffer_temp (struct buffer *);
+extern Lisp_Object buffer_local_value_1 (Lisp_Object, Lisp_Object);
 extern void record_buffer (Lisp_Object);
 extern void buffer_slot_type_mismatch (Lisp_Object, int) NO_RETURN;
 extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t);
index 0763fc19c73905f6cef7cb2bddbb0566c0db2f76..6eb7f50c6fc827502a874cb1b96d36ae5fd1b38b 100644 (file)
@@ -751,6 +751,7 @@ static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
 int redisplaying_p;
 
 static Lisp_Object Qinhibit_free_realized_faces;
+static Lisp_Object Qmode_line_default_help_echo;
 
 /* If a string, XTread_socket generates an event to display that string.
    (The display is done in read_char.)  */
@@ -22091,7 +22092,9 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
            return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
        }
 
-      prop = Fbuffer_local_value (prop, it->w->buffer);
+      prop = buffer_local_value_1 (prop, it->w->buffer);
+      if (EQ (prop, Qunbound))
+       prop = Qnil;
     }
 
   if (INTEGERP (prop) || FLOATP (prop))
@@ -22141,7 +22144,9 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
              return OK_PIXELS (pixels);
            }
 
-         car = Fbuffer_local_value (car, it->w->buffer);
+         car = buffer_local_value_1 (car, it->w->buffer);
+         if (EQ (car, Qunbound))
+           car = Qnil;
        }
 
       if (INTEGERP (car) || FLOATP (car))
@@ -27035,7 +27040,6 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
              if (!NILP (help))
                {
                  help_echo_string = help;
-                 /* Is this correct?  ++kfs */
                  XSETWINDOW (help_echo_window, w);
                  help_echo_object = w->buffer;
                  help_echo_pos = charpos;
@@ -27048,46 +27052,77 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
 #endif /* HAVE_WINDOW_SYSTEM */
 
   if (STRINGP (string))
+    pos = make_number (charpos);
+
+  /* Set the help text and mouse pointer.  If the mouse is on a part
+     of the mode line without any text (e.g. past the right edge of
+     the mode line text), use the default help text and pointer.  */
+  if (STRINGP (string) || area == ON_MODE_LINE)
     {
-      pos = make_number (charpos);
-      /* If we're on a string with `help-echo' text property, arrange
-        for the help to be displayed.  This is done by setting the
-        global variable help_echo_string to the help string.  */
+      /* Arrange to display the help by setting the global variables
+        help_echo_string, help_echo_object, and help_echo_pos.  */
       if (NILP (help))
        {
-         help = Fget_text_property (pos, Qhelp_echo, string);
-         if (!NILP (help))
+         if (STRINGP (string))
+           help = Fget_text_property (pos, Qhelp_echo, string);
+
+         if (STRINGP (help))
            {
              help_echo_string = help;
              XSETWINDOW (help_echo_window, w);
              help_echo_object = string;
              help_echo_pos = charpos;
            }
+         else if (area == ON_MODE_LINE)
+           {
+             Lisp_Object default_help
+               = buffer_local_value_1 (Qmode_line_default_help_echo,
+                                       w->buffer);
+
+             if (STRINGP (default_help))
+               {
+                 help_echo_string = default_help;
+                 XSETWINDOW (help_echo_window, w);
+                 help_echo_object = Qnil;
+                 help_echo_pos = -1;
+               }
+           }
        }
 
 #ifdef HAVE_WINDOW_SYSTEM
+      /* Change the mouse pointer according to what is under it.  */
       if (FRAME_WINDOW_P (f))
        {
          dpyinfo = FRAME_X_DISPLAY_INFO (f);
-         cursor  = FRAME_X_OUTPUT (f)->nontext_cursor;
-         if (NILP (pointer))
-           pointer = Fget_text_property (pos, Qpointer, string);
-
-         /* Change the mouse pointer according to what is under X/Y.  */
-         if (NILP (pointer)
-             && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
+         if (STRINGP (string))
            {
-             Lisp_Object map;
-             map = Fget_text_property (pos, Qlocal_map, string);
-             if (!KEYMAPP (map))
-               map = Fget_text_property (pos, Qkeymap, string);
-             if (!KEYMAPP (map))
-               cursor = dpyinfo->vertical_scroll_bar_cursor;
+             cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
+
+             if (NILP (pointer))
+               pointer = Fget_text_property (pos, Qpointer, string);
+
+             /* Change the mouse pointer according to what is under X/Y.  */
+             if (NILP (pointer)
+                 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
+               {
+                 Lisp_Object map;
+                 map = Fget_text_property (pos, Qlocal_map, string);
+                 if (!KEYMAPP (map))
+                   map = Fget_text_property (pos, Qkeymap, string);
+                 if (!KEYMAPP (map))
+                   cursor = dpyinfo->vertical_scroll_bar_cursor;
+               }
            }
+         else
+           /* Default mode-line pointer.  */
+           cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
        }
 #endif
+    }
 
-     /* Change the mouse face according to what is under X/Y.  */
+  /* Change the mouse face according to what is under X/Y.  */
+  if (STRINGP (string))
+    {
       mouse_face = Fget_text_property (pos, Qmouse_face, string);
       if (!NILP (mouse_face)
          && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
@@ -28428,6 +28463,8 @@ syms_of_xdisp (void)
   Vmode_line_unwind_vector = Qnil;
   staticpro (&Vmode_line_unwind_vector);
 
+  DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
+
   help_echo_string = Qnil;
   staticpro (&help_echo_string);
   help_echo_object = Qnil;