From 5f2c76c6cee2b5d2d84ffd409839fd58d2ad16fa Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sun, 3 Jun 2012 17:03:23 +0800 Subject: [PATCH] Implement default help-echo for mode line. * 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 | 5 + doc/lispref/modes.texi | 4 +- lisp/ChangeLog | 10 ++ lisp/bindings.el | 313 ++++++++++++++++++++++++------------------------- src/ChangeLog | 12 ++ src/buffer.c | 75 +++++++----- src/buffer.h | 1 + src/xdisp.c | 83 +++++++++---- 8 files changed, 293 insertions(+), 210 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 850b3f9cf54..b774809feb9 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,8 @@ +2012-06-03 Chong Yidong + + * modes.texi (Mode Line Data): Use "mode line construct" + terminology for consistency. + 2012-05-27 Glenn Morris * abbrevs.texi, advice.texi, anti.texi, backups.texi: diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 8dca250ce10..96e9b78f871 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -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{}) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index e39b8a64205..5a3b1d3926d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,13 @@ +2012-06-03 Chong Yidong + + * 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 * simple.el (execute-extended-command): Set real-this-command diff --git a/lisp/bindings.el b/lisp/bindings.el index 69d96ab6889..65dd68a4447 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -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) + +;;; 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)))) + + (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. diff --git a/src/ChangeLog b/src/ChangeLog index b90db0b7fa9..c0098445cb8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2012-06-03 Chong Yidong + + * 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 * sysdep.c (system_process_attributes): Improve comment. diff --git a/src/buffer.c b/src/buffer.c index 20260d5a5d8..386d9a78153 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -933,6 +933,21 @@ 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; struct Lisp_Symbol *sym; @@ -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. diff --git a/src/buffer.h b/src/buffer.h index 97d891f044b..3aa4b11c450 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -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); diff --git a/src/xdisp.c b/src/xdisp.c index 0763fc19c73..6eb7f50c6fc 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -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; -- 2.11.4.GIT