diff options
| author | Kim F. Storm | 2002-06-27 20:42:35 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2002-06-27 20:42:35 +0000 |
| commit | fec8f23ec02a66c45b23bc34ce8d303dfa53e1b1 (patch) | |
| tree | 96b69ba48db424a2d528b84f1668b664faa90ddb /src | |
| parent | 377408cff4548fbbc431c475a48968003311f847 (diff) | |
| download | emacs-fec8f23ec02a66c45b23bc34ce8d303dfa53e1b1.tar.gz emacs-fec8f23ec02a66c45b23bc34ce8d303dfa53e1b1.zip | |
(mode_line_string_list, mode_line_string_face)
(mode_line_string_face_prop): New variables.
(store_mode_line_string): New function.
(display_mode_element): Use store_mode_line_string to
add mode-line string elements to mode_line_string_list
when mode_line_string_list is non-nil.
(Fformat_mode_line): Now returns propertized string by
default. New arg NO-PROPS to ignore properties.
(decode_mode_spec): Only add two dashes for %- in propertized
mode-line string.
(syms_of_xdisp): Init and staticpro mode_line_string_list.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 197 |
1 files changed, 188 insertions, 9 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 53d45451c2f..afcce0b7b9f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -211,6 +211,7 @@ extern int command_loop_level; | |||
| 211 | extern int minibuffer_auto_raise; | 211 | extern int minibuffer_auto_raise; |
| 212 | 212 | ||
| 213 | extern Lisp_Object Qface; | 213 | extern Lisp_Object Qface; |
| 214 | extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line; | ||
| 214 | 215 | ||
| 215 | extern Lisp_Object Voverriding_local_map; | 216 | extern Lisp_Object Voverriding_local_map; |
| 216 | extern Lisp_Object Voverriding_local_map_menu_flag; | 217 | extern Lisp_Object Voverriding_local_map_menu_flag; |
| @@ -762,6 +763,7 @@ static int display_line P_ ((struct it *)); | |||
| 762 | static int display_mode_lines P_ ((struct window *)); | 763 | static int display_mode_lines P_ ((struct window *)); |
| 763 | static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object)); | 764 | static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object)); |
| 764 | static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int)); | 765 | static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int)); |
| 766 | static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object)); | ||
| 765 | static char *decode_mode_spec P_ ((struct window *, int, int, int, int *)); | 767 | static char *decode_mode_spec P_ ((struct window *, int, int, int, int *)); |
| 766 | static void display_menu_bar P_ ((struct window *)); | 768 | static void display_menu_bar P_ ((struct window *)); |
| 767 | static int display_count_lines P_ ((int, int, int, int, int *)); | 769 | static int display_count_lines P_ ((int, int, int, int, int *)); |
| @@ -13625,6 +13627,14 @@ display_mode_line (w, face_id, format) | |||
| 13625 | Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */ | 13627 | Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */ |
| 13626 | Lisp_Object mode_line_proptrans_alist; | 13628 | Lisp_Object mode_line_proptrans_alist; |
| 13627 | 13629 | ||
| 13630 | /* List of strings making up the mode-line. */ | ||
| 13631 | Lisp_Object mode_line_string_list; | ||
| 13632 | |||
| 13633 | /* Base face property when building propertized mode line string. */ | ||
| 13634 | static Lisp_Object mode_line_string_face; | ||
| 13635 | static Lisp_Object mode_line_string_face_prop; | ||
| 13636 | |||
| 13637 | |||
| 13628 | /* Contribute ELT to the mode line for window IT->w. How it | 13638 | /* Contribute ELT to the mode line for window IT->w. How it |
| 13629 | translates into text depends on its data type. | 13639 | translates into text depends on its data type. |
| 13630 | 13640 | ||
| @@ -13733,6 +13743,8 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 13733 | prec = precision - n; | 13743 | prec = precision - n; |
| 13734 | if (frame_title_ptr) | 13744 | if (frame_title_ptr) |
| 13735 | n += store_frame_title (SDATA (elt), -1, prec); | 13745 | n += store_frame_title (SDATA (elt), -1, prec); |
| 13746 | else if (!NILP (mode_line_string_list)) | ||
| 13747 | n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil); | ||
| 13736 | else | 13748 | else |
| 13737 | n += display_string (NULL, elt, Qnil, 0, 0, it, | 13749 | n += display_string (NULL, elt, Qnil, 0, 0, it, |
| 13738 | 0, prec, 0, STRING_MULTIBYTE (elt)); | 13750 | 0, prec, 0, STRING_MULTIBYTE (elt)); |
| @@ -13743,6 +13755,7 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 13743 | while ((precision <= 0 || n < precision) | 13755 | while ((precision <= 0 || n < precision) |
| 13744 | && *this | 13756 | && *this |
| 13745 | && (frame_title_ptr | 13757 | && (frame_title_ptr |
| 13758 | || !NILP (mode_line_string_list) | ||
| 13746 | || it->current_x < it->last_visible_x)) | 13759 | || it->current_x < it->last_visible_x)) |
| 13747 | { | 13760 | { |
| 13748 | unsigned char *last = this; | 13761 | unsigned char *last = this; |
| @@ -13764,6 +13777,15 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 13764 | 13777 | ||
| 13765 | if (frame_title_ptr) | 13778 | if (frame_title_ptr) |
| 13766 | n += store_frame_title (last, 0, prec); | 13779 | n += store_frame_title (last, 0, prec); |
| 13780 | else if (!NILP (mode_line_string_list)) | ||
| 13781 | { | ||
| 13782 | int bytepos = last - lisp_string; | ||
| 13783 | int charpos = string_byte_to_char (elt, bytepos); | ||
| 13784 | n += store_mode_line_string (NULL, | ||
| 13785 | Fsubstring (elt, make_number (charpos), | ||
| 13786 | make_number (charpos + prec)), | ||
| 13787 | 0, 0, 0, Qnil); | ||
| 13788 | } | ||
| 13767 | else | 13789 | else |
| 13768 | { | 13790 | { |
| 13769 | int bytepos = last - lisp_string; | 13791 | int bytepos = last - lisp_string; |
| @@ -13810,6 +13832,14 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 13810 | 13832 | ||
| 13811 | if (frame_title_ptr) | 13833 | if (frame_title_ptr) |
| 13812 | n += store_frame_title (spec, field, prec); | 13834 | n += store_frame_title (spec, field, prec); |
| 13835 | else if (!NILP (mode_line_string_list)) | ||
| 13836 | { | ||
| 13837 | int len = strlen (spec); | ||
| 13838 | Lisp_Object tem = make_string (spec, len); | ||
| 13839 | props = Ftext_properties_at (make_number (charpos), elt); | ||
| 13840 | /* Should only keep face property in props */ | ||
| 13841 | n += store_mode_line_string (NULL, tem, 0, field, prec, props); | ||
| 13842 | } | ||
| 13813 | else | 13843 | else |
| 13814 | { | 13844 | { |
| 13815 | int nglyphs_before, nwritten; | 13845 | int nglyphs_before, nwritten; |
| @@ -13998,6 +14028,8 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 13998 | invalid: | 14028 | invalid: |
| 13999 | if (frame_title_ptr) | 14029 | if (frame_title_ptr) |
| 14000 | n += store_frame_title ("*invalid*", 0, precision - n); | 14030 | n += store_frame_title ("*invalid*", 0, precision - n); |
| 14031 | else if (!NILP (mode_line_string_list)) | ||
| 14032 | n += store_mode_line_string ("*invalid*", Qnil, 0, 0, precision - n, Qnil); | ||
| 14001 | else | 14033 | else |
| 14002 | n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0, | 14034 | n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0, |
| 14003 | precision - n, 0, 0); | 14035 | precision - n, 0, 0); |
| @@ -14009,6 +14041,8 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 14009 | { | 14041 | { |
| 14010 | if (frame_title_ptr) | 14042 | if (frame_title_ptr) |
| 14011 | n += store_frame_title ("", field_width - n, 0); | 14043 | n += store_frame_title ("", field_width - n, 0); |
| 14044 | else if (!NILP (mode_line_string_list)) | ||
| 14045 | n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil); | ||
| 14012 | else | 14046 | else |
| 14013 | n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n, | 14047 | n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n, |
| 14014 | 0, 0, 0); | 14048 | 0, 0, 0); |
| @@ -14017,22 +14051,123 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 14017 | return n; | 14051 | return n; |
| 14018 | } | 14052 | } |
| 14019 | 14053 | ||
| 14054 | /* Store a mode-line string element in mode_line_string_list. | ||
| 14055 | |||
| 14056 | If STRING is non-null, display that C string. Otherwise, the Lisp | ||
| 14057 | string LISP_STRING is displayed. | ||
| 14058 | |||
| 14059 | FIELD_WIDTH is the minimum number of output glyphs to produce. | ||
| 14060 | If STRING has fewer characters than FIELD_WIDTH, pad to the right | ||
| 14061 | with spaces. FIELD_WIDTH <= 0 means don't pad. | ||
| 14062 | |||
| 14063 | PRECISION is the maximum number of characters to output from | ||
| 14064 | STRING. PRECISION <= 0 means don't truncate the string. | ||
| 14065 | |||
| 14066 | If COPY_STRING is non-zero, make a copy of LISP_STRING before adding | ||
| 14067 | properties to the string. | ||
| 14068 | |||
| 14069 | PROPS are the properties to add to the string. | ||
| 14070 | The mode_line_string_face face property is always added to the string. | ||
| 14071 | */ | ||
| 14072 | |||
| 14073 | static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props) | ||
| 14074 | char *string; | ||
| 14075 | Lisp_Object lisp_string; | ||
| 14076 | int copy_string; | ||
| 14077 | int field_width; | ||
| 14078 | int precision; | ||
| 14079 | Lisp_Object props; | ||
| 14080 | { | ||
| 14081 | int len; | ||
| 14082 | int n = 0; | ||
| 14083 | |||
| 14084 | if (string != NULL) | ||
| 14085 | { | ||
| 14086 | len = strlen (string); | ||
| 14087 | if (precision > 0 && len > precision) | ||
| 14088 | len = precision; | ||
| 14089 | lisp_string = make_string (string, len); | ||
| 14090 | if (NILP (props)) | ||
| 14091 | props = mode_line_string_face_prop; | ||
| 14092 | else if (!NILP (mode_line_string_face)) | ||
| 14093 | { | ||
| 14094 | Lisp_Object face = Fplist_get (props, Qface); | ||
| 14095 | props = Fcopy_sequence (props); | ||
| 14096 | if (NILP (face)) | ||
| 14097 | face = mode_line_string_face; | ||
| 14098 | else | ||
| 14099 | face = Fcons (face, Fcons (mode_line_string_face, Qnil)); | ||
| 14100 | props = Fplist_put (props, Qface, face); | ||
| 14101 | } | ||
| 14102 | Fadd_text_properties (make_number (0), make_number (len), | ||
| 14103 | props, lisp_string); | ||
| 14104 | } | ||
| 14105 | else | ||
| 14106 | { | ||
| 14107 | len = Flength (lisp_string); | ||
| 14108 | if (precision > 0 && len > precision) | ||
| 14109 | { | ||
| 14110 | len = precision; | ||
| 14111 | lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len)); | ||
| 14112 | precision = -1; | ||
| 14113 | } | ||
| 14114 | if (!NILP (mode_line_string_face)) | ||
| 14115 | { | ||
| 14116 | Lisp_Object face; | ||
| 14117 | if (NILP (props)) | ||
| 14118 | props = Ftext_properties_at (make_number (0), lisp_string); | ||
| 14119 | face = Fplist_get (props, Qface); | ||
| 14120 | if (NILP (face)) | ||
| 14121 | face = mode_line_string_face; | ||
| 14122 | else | ||
| 14123 | face = Fcons (face, Fcons (mode_line_string_face, Qnil)); | ||
| 14124 | props = Fcons (Qface, Fcons (face, Qnil)); | ||
| 14125 | if (copy_string) | ||
| 14126 | lisp_string = Fcopy_sequence (lisp_string); | ||
| 14127 | } | ||
| 14128 | if (!NILP (props)) | ||
| 14129 | Fadd_text_properties (make_number (0), make_number (len), | ||
| 14130 | props, lisp_string); | ||
| 14131 | } | ||
| 14132 | |||
| 14133 | if (len > 0) | ||
| 14134 | { | ||
| 14135 | mode_line_string_list = Fcons (lisp_string, mode_line_string_list); | ||
| 14136 | n += len; | ||
| 14137 | } | ||
| 14138 | |||
| 14139 | if (field_width > len) | ||
| 14140 | { | ||
| 14141 | field_width -= len; | ||
| 14142 | lisp_string = Fmake_string (make_number (field_width), make_number (' ')); | ||
| 14143 | if (!NILP (props)) | ||
| 14144 | Fadd_text_properties (make_number (0), make_number (field_width), | ||
| 14145 | props, lisp_string); | ||
| 14146 | mode_line_string_list = Fcons (lisp_string, mode_line_string_list); | ||
| 14147 | n += field_width; | ||
| 14148 | } | ||
| 14149 | |||
| 14150 | return n; | ||
| 14151 | } | ||
| 14152 | |||
| 14020 | 14153 | ||
| 14021 | DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line, | 14154 | DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line, |
| 14022 | 0, 2, 0, | 14155 | 0, 3, 0, |
| 14023 | doc: /* Return the mode-line of selected window as a string. | 14156 | doc: /* Return the mode-line of selected window as a string. |
| 14024 | First optional arg FORMAT specifies a different format string (see | 14157 | First optional arg FORMAT specifies a different format string (see |
| 14025 | `mode-line-format' for details) to use. If FORMAT is t, return | 14158 | `mode-line-format' for details) to use. If FORMAT is t, return |
| 14026 | the buffer's header-line. Second optional arg WINDOW specifies a | 14159 | the buffer's header-line. Second optional arg WINDOW specifies a |
| 14027 | different window to use as the context for the formatting. */) | 14160 | different window to use as the context for the formatting. |
| 14028 | (format, window) | 14161 | If third optional arg NO-PROPS is non-nil, string is not propertized. */) |
| 14029 | Lisp_Object format, window; | 14162 | (format, window, no_props) |
| 14163 | Lisp_Object format, window, no_props; | ||
| 14030 | { | 14164 | { |
| 14031 | struct it it; | 14165 | struct it it; |
| 14032 | struct face *face; | 14166 | struct face *face; |
| 14033 | int len; | 14167 | int len; |
| 14034 | struct window *w; | 14168 | struct window *w; |
| 14035 | struct buffer *old_buffer = NULL; | 14169 | struct buffer *old_buffer = NULL; |
| 14170 | enum face_id face_id = DEFAULT_FACE_ID; | ||
| 14036 | 14171 | ||
| 14037 | if (NILP (window)) | 14172 | if (NILP (window)) |
| 14038 | window = selected_window; | 14173 | window = selected_window; |
| @@ -14047,13 +14182,41 @@ different window to use as the context for the formatting. */) | |||
| 14047 | } | 14182 | } |
| 14048 | 14183 | ||
| 14049 | if (NILP (format) || EQ (format, Qt)) | 14184 | if (NILP (format) || EQ (format, Qt)) |
| 14050 | format = NILP (format) | 14185 | { |
| 14051 | ? current_buffer->mode_line_format | 14186 | face_id = NILP (format) |
| 14052 | : current_buffer->header_line_format; | 14187 | ? CURRENT_MODE_LINE_FACE_ID (w) : |
| 14188 | HEADER_LINE_FACE_ID; | ||
| 14189 | format = NILP (format) | ||
| 14190 | ? current_buffer->mode_line_format | ||
| 14191 | : current_buffer->header_line_format; | ||
| 14192 | } | ||
| 14193 | |||
| 14194 | init_iterator (&it, w, -1, -1, NULL, face_id); | ||
| 14053 | 14195 | ||
| 14054 | init_iterator (&it, w, -1, -1, NULL, DEFAULT_FACE_ID); | 14196 | if (NILP (no_props)) |
| 14197 | { | ||
| 14198 | mode_line_string_face = | ||
| 14199 | (face_id == MODE_LINE_FACE_ID ? Qmode_line : | ||
| 14200 | face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive : | ||
| 14201 | face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil); | ||
| 14055 | 14202 | ||
| 14056 | frame_title_ptr = frame_title_buf; | 14203 | mode_line_string_face_prop = |
| 14204 | NILP (mode_line_string_face) ? Qnil : | ||
| 14205 | Fcons (Qface, Fcons (mode_line_string_face, Qnil)); | ||
| 14206 | |||
| 14207 | /* We need a dummy last element in mode_line_string_list to | ||
| 14208 | indicate we are building the propertized mode-line string. | ||
| 14209 | Using mode_line_string_face_prop here GC protects it. */ | ||
| 14210 | mode_line_string_list = | ||
| 14211 | Fcons (mode_line_string_face_prop, Qnil); | ||
| 14212 | frame_title_ptr = NULL; | ||
| 14213 | } | ||
| 14214 | else | ||
| 14215 | { | ||
| 14216 | mode_line_string_face_prop = Qnil; | ||
| 14217 | mode_line_string_list = Qnil; | ||
| 14218 | frame_title_ptr = frame_title_buf; | ||
| 14219 | } | ||
| 14057 | 14220 | ||
| 14058 | push_frame_kboard (it.f); | 14221 | push_frame_kboard (it.f); |
| 14059 | display_mode_element (&it, 0, 0, 0, format, Qnil, 0); | 14222 | display_mode_element (&it, 0, 0, 0, format, Qnil, 0); |
| @@ -14062,6 +14225,17 @@ different window to use as the context for the formatting. */) | |||
| 14062 | if (old_buffer) | 14225 | if (old_buffer) |
| 14063 | set_buffer_internal_1 (old_buffer); | 14226 | set_buffer_internal_1 (old_buffer); |
| 14064 | 14227 | ||
| 14228 | if (NILP (no_props)) | ||
| 14229 | { | ||
| 14230 | Lisp_Object str; | ||
| 14231 | mode_line_string_list = Fnreverse (mode_line_string_list); | ||
| 14232 | str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list), | ||
| 14233 | make_string ("", 0)); | ||
| 14234 | mode_line_string_face_prop = Qnil; | ||
| 14235 | mode_line_string_list = Qnil; | ||
| 14236 | return str; | ||
| 14237 | } | ||
| 14238 | |||
| 14065 | len = frame_title_ptr - frame_title_buf; | 14239 | len = frame_title_ptr - frame_title_buf; |
| 14066 | if (len > 0 && frame_title_ptr[-1] == '-') | 14240 | if (len > 0 && frame_title_ptr[-1] == '-') |
| 14067 | { | 14241 | { |
| @@ -14273,6 +14447,8 @@ decode_mode_spec (w, c, field_width, precision, multibyte) | |||
| 14273 | register int i; | 14447 | register int i; |
| 14274 | 14448 | ||
| 14275 | /* Let lots_of_dashes be a string of infinite length. */ | 14449 | /* Let lots_of_dashes be a string of infinite length. */ |
| 14450 | if (!NILP (mode_line_string_list)) | ||
| 14451 | return "--"; | ||
| 14276 | if (field_width <= 0 | 14452 | if (field_width <= 0 |
| 14277 | || field_width > sizeof (lots_of_dashes)) | 14453 | || field_width > sizeof (lots_of_dashes)) |
| 14278 | { | 14454 | { |
| @@ -15062,6 +15238,9 @@ syms_of_xdisp () | |||
| 15062 | mode_line_proptrans_alist = Qnil; | 15238 | mode_line_proptrans_alist = Qnil; |
| 15063 | staticpro (&mode_line_proptrans_alist); | 15239 | staticpro (&mode_line_proptrans_alist); |
| 15064 | 15240 | ||
| 15241 | mode_line_string_list = Qnil; | ||
| 15242 | staticpro (&mode_line_string_list); | ||
| 15243 | |||
| 15065 | DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace, | 15244 | DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace, |
| 15066 | doc: /* Non-nil means highlight trailing whitespace. | 15245 | doc: /* Non-nil means highlight trailing whitespace. |
| 15067 | The face used for trailing whitespace is `trailing-whitespace'. */); | 15246 | The face used for trailing whitespace is `trailing-whitespace'. */); |