aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2017-10-20 12:36:12 +0300
committerEli Zaretskii2017-10-20 12:36:12 +0300
commitfd3d8610b27e26107ba15070aba0d488152f8f4d (patch)
treed62498e78ac088c6f992a1f0077951ea9db6ba08 /src
parent831eafc8ae201881e6449e2ab5d15d594573650b (diff)
downloademacs-fd3d8610b27e26107ba15070aba0d488152f8f4d.tar.gz
emacs-fd3d8610b27e26107ba15070aba0d488152f8f4d.zip
Make :align-to account for display-line-numbers
These changes also update the various bundled packages to use new feature, and better support customizations of the line-number face. * src/xdisp.c (calc_pixel_width_or_height): Improve commentary. Make :align-to count from the end of the line-number display when the offset or the width form reference that of the text area. (Bug#28855) * src/indent.c (Fline_number_display_width): Implement support for the PIXELWISE argument being 'columns'. Update the doc string. (syms_of_indent): New symbol 'columns'. * lisp/ruler-mode.el (ruler-mode-window-col, ruler-mode-ruler): Call line-number-display-width with last argument 'columns'. * lisp/proced.el (proced-header-line): Call line-number-display-width with 2nd arg 'columns', which also fixes a problem when display-line-numbers is nil. * lisp/emacs-lisp/tabulated-list.el (tabulated-list-line-number-width): Call line-number-display-width with 2nd arg 'columns. (tabulated-list-entry-lnum-width): Remove unneeded defvar. (tabulated-list-print, tabulated-list-print-entry): No need to account for the value of tabulated-list-entry-lnum-width. (tabulated-list--current-lnum-width): New defvar. (tabulated-list-watch-line-number-width): New function. (tabulated-list-mode): Bind tabulated-list--current-lnum-width locally, and set up tabulated-list-watch-line-number-width as pre-redisplay-functions hook. * doc/lispref/display.texi (Size of Displayed Text): Document the 'columns' value of the PIXELWISE argument. (Pixel Specification): Update and improve the documentation of the supported forms.
Diffstat (limited to 'src')
-rw-r--r--src/indent.c23
-rw-r--r--src/xdisp.c51
2 files changed, 64 insertions, 10 deletions
diff --git a/src/indent.c b/src/indent.c
index a3e9b5b0b9a..192eec72efe 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1991,15 +1991,26 @@ line_number_display_width (struct window *w, int *width, int *pixel_width)
1991DEFUN ("line-number-display-width", Fline_number_display_width, 1991DEFUN ("line-number-display-width", Fline_number_display_width,
1992 Sline_number_display_width, 0, 1, 0, 1992 Sline_number_display_width, 0, 1, 0,
1993 doc: /* Return the width used for displaying line numbers in the selected window. 1993 doc: /* Return the width used for displaying line numbers in the selected window.
1994If optional argument PIXELWISE is non-nil, return the width in pixels, 1994If optional argument PIXELWISE is the symbol `columns', return the width
1995otherwise return the width in columns of the face used to display 1995in units of the frame's canonical character width. In this case, the
1996line numbers, `line-number'. Note that in the latter case, the value 1996value is a float.
1997doesn't include the 2 columns used for padding the numbers. */) 1997If optional argument PIXELWISE is t or any other non-nil value, return
1998the width as an integer number of pixels.
1999Otherwise return the value as an integer number of columns of the face
2000used to display line numbers, `line-number'. Note that in the latter
2001case, the value doesn't include the 2 columns used for padding the
2002numbers on display. */)
1998 (Lisp_Object pixelwise) 2003 (Lisp_Object pixelwise)
1999{ 2004{
2000 int width, pixel_width; 2005 int width, pixel_width;
2006 struct window *w = XWINDOW (selected_window);
2001 line_number_display_width (XWINDOW (selected_window), &width, &pixel_width); 2007 line_number_display_width (XWINDOW (selected_window), &width, &pixel_width);
2002 if (!NILP (pixelwise)) 2008 if (EQ (pixelwise, Qcolumns))
2009 {
2010 struct frame *f = XFRAME (w->frame);
2011 return make_float ((double) pixel_width / FRAME_COLUMN_WIDTH (f));
2012 }
2013 else if (!NILP (pixelwise))
2003 return make_number (pixel_width); 2014 return make_number (pixel_width);
2004 return make_number (width); 2015 return make_number (width);
2005} 2016}
@@ -2361,6 +2372,8 @@ syms_of_indent (void)
2361 doc: /* Indentation can insert tabs if this is non-nil. */); 2372 doc: /* Indentation can insert tabs if this is non-nil. */);
2362 indent_tabs_mode = 1; 2373 indent_tabs_mode = 1;
2363 2374
2375 DEFSYM (Qcolumns, "columns");
2376
2364 defsubr (&Scurrent_indentation); 2377 defsubr (&Scurrent_indentation);
2365 defsubr (&Sindent_to); 2378 defsubr (&Sindent_to);
2366 defsubr (&Scurrent_column); 2379 defsubr (&Scurrent_column);
diff --git a/src/xdisp.c b/src/xdisp.c
index 6d9acecb424..dc23959aadb 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -25123,7 +25123,20 @@ else if the text is replaced by an ellipsis. */)
25123 '(space :width (+ left-fringe left-margin (- (1)))) 25123 '(space :width (+ left-fringe left-margin (- (1))))
25124 '(space :width (+ left-fringe left-margin (-1))) 25124 '(space :width (+ left-fringe left-margin (-1)))
25125 25125
25126*/ 25126 If ALIGN_TO is NULL, returns the result in *RES. If ALIGN_TO is
25127 non-NULL, the value of *ALIGN_TO is a window-relative pixel
25128 coordinate, and *RES is the additional pixel width from that point
25129 till the end of the stretch glyph.
25130
25131 WIDTH_P non-zero means take the width dimension or X coordinate of
25132 the object specified by PROP, WIDTH_P zero means take the height
25133 dimension or the Y coordinate. (Therefore, if ALIGN_TO is
25134 non-NULL, WIDTH_P should be non-zero.)
25135
25136 FONT is the font of the face of the surrounding text.
25137
25138 The return value is non-zero if width or height were successfully
25139 calculated, i.e. if PROP is a valid spec. */
25127 25140
25128static bool 25141static bool
25129calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop, 25142calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
@@ -25145,6 +25158,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25145 { 25158 {
25146 char *unit = SSDATA (SYMBOL_NAME (prop)); 25159 char *unit = SSDATA (SYMBOL_NAME (prop));
25147 25160
25161 /* The UNIT expression, e.g. as part of (NUM . UNIT). */
25148 if (unit[0] == 'i' && unit[1] == 'n') 25162 if (unit[0] == 'i' && unit[1] == 'n')
25149 pixels = 1.0; 25163 pixels = 1.0;
25150 else if (unit[0] == 'm' && unit[1] == 'm') 25164 else if (unit[0] == 'm' && unit[1] == 'm')
@@ -25165,10 +25179,12 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25165 } 25179 }
25166 25180
25167#ifdef HAVE_WINDOW_SYSTEM 25181#ifdef HAVE_WINDOW_SYSTEM
25182 /* 'height': the height of FONT. */
25168 if (EQ (prop, Qheight)) 25183 if (EQ (prop, Qheight))
25169 return OK_PIXELS (font 25184 return OK_PIXELS (font
25170 ? normal_char_height (font, -1) 25185 ? normal_char_height (font, -1)
25171 : FRAME_LINE_HEIGHT (it->f)); 25186 : FRAME_LINE_HEIGHT (it->f));
25187 /* 'width': the width of FONT. */
25172 if (EQ (prop, Qwidth)) 25188 if (EQ (prop, Qwidth))
25173 return OK_PIXELS (font 25189 return OK_PIXELS (font
25174 ? FONT_WIDTH (font) 25190 ? FONT_WIDTH (font)
@@ -25178,33 +25194,48 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25178 return OK_PIXELS (1); 25194 return OK_PIXELS (1);
25179#endif 25195#endif
25180 25196
25197 /* 'text': the width or height of the text area. */
25181 if (EQ (prop, Qtext)) 25198 if (EQ (prop, Qtext))
25182 return OK_PIXELS (width_p 25199 return OK_PIXELS (width_p
25183 ? window_box_width (it->w, TEXT_AREA) 25200 ? (window_box_width (it->w, TEXT_AREA)
25201 - it->lnum_pixel_width)
25184 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w)); 25202 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
25185 25203
25204 /* ':align_to'. First time we compute the value, window
25205 elements are interpreted as the position of the element's
25206 left edge. */
25186 if (align_to && *align_to < 0) 25207 if (align_to && *align_to < 0)
25187 { 25208 {
25188 *res = 0; 25209 *res = 0;
25210 /* 'left': left edge of the text area. */
25189 if (EQ (prop, Qleft)) 25211 if (EQ (prop, Qleft))
25190 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)); 25212 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25213 + it->lnum_pixel_width);
25214 /* 'right': right edge of the text area. */
25191 if (EQ (prop, Qright)) 25215 if (EQ (prop, Qright))
25192 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA)); 25216 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
25217 /* 'center': the center of the text area. */
25193 if (EQ (prop, Qcenter)) 25218 if (EQ (prop, Qcenter))
25194 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA) 25219 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25220 + it->lnum_pixel_width
25195 + window_box_width (it->w, TEXT_AREA) / 2); 25221 + window_box_width (it->w, TEXT_AREA) / 2);
25222 /* 'left-fringe': left edge of the left fringe. */
25196 if (EQ (prop, Qleft_fringe)) 25223 if (EQ (prop, Qleft_fringe))
25197 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w) 25224 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25198 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w) 25225 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
25199 : window_box_right_offset (it->w, LEFT_MARGIN_AREA)); 25226 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
25227 /* 'right-fringe': left edge of the right fringe. */
25200 if (EQ (prop, Qright_fringe)) 25228 if (EQ (prop, Qright_fringe))
25201 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w) 25229 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25202 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA) 25230 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25203 : window_box_right_offset (it->w, TEXT_AREA)); 25231 : window_box_right_offset (it->w, TEXT_AREA));
25232 /* 'left-margin': left edge of the left display margin. */
25204 if (EQ (prop, Qleft_margin)) 25233 if (EQ (prop, Qleft_margin))
25205 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA)); 25234 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
25235 /* 'right-margin': left edge of the right display margin. */
25206 if (EQ (prop, Qright_margin)) 25236 if (EQ (prop, Qright_margin))
25207 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA)); 25237 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
25238 /* 'scroll-bar': left edge of the vertical scroll bar. */
25208 if (EQ (prop, Qscroll_bar)) 25239 if (EQ (prop, Qscroll_bar))
25209 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w) 25240 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
25210 ? 0 25241 ? 0
@@ -25215,6 +25246,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25215 } 25246 }
25216 else 25247 else
25217 { 25248 {
25249 /* Otherwise, the elements stand for their width. */
25218 if (EQ (prop, Qleft_fringe)) 25250 if (EQ (prop, Qleft_fringe))
25219 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w)); 25251 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
25220 if (EQ (prop, Qright_fringe)) 25252 if (EQ (prop, Qright_fringe))
@@ -25237,6 +25269,8 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25237 int base_unit = (width_p 25269 int base_unit = (width_p
25238 ? FRAME_COLUMN_WIDTH (it->f) 25270 ? FRAME_COLUMN_WIDTH (it->f)
25239 : FRAME_LINE_HEIGHT (it->f)); 25271 : FRAME_LINE_HEIGHT (it->f));
25272 if (width_p && align_to && *align_to < 0)
25273 return OK_PIXELS (XFLOATINT (prop) * base_unit + it->lnum_pixel_width);
25240 return OK_PIXELS (XFLOATINT (prop) * base_unit); 25274 return OK_PIXELS (XFLOATINT (prop) * base_unit);
25241 } 25275 }
25242 25276
@@ -25248,6 +25282,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25248 if (SYMBOLP (car)) 25282 if (SYMBOLP (car))
25249 { 25283 {
25250#ifdef HAVE_WINDOW_SYSTEM 25284#ifdef HAVE_WINDOW_SYSTEM
25285 /* '(image PROPS...)': width or height of the specified image. */
25251 if (FRAME_WINDOW_P (it->f) 25286 if (FRAME_WINDOW_P (it->f)
25252 && valid_image_p (prop)) 25287 && valid_image_p (prop))
25253 { 25288 {
@@ -25256,12 +25291,15 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25256 25291
25257 return OK_PIXELS (width_p ? img->width : img->height); 25292 return OK_PIXELS (width_p ? img->width : img->height);
25258 } 25293 }
25294 /* '(xwidget PROPS...)': dimensions of the specified xwidget. */
25259 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop)) 25295 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
25260 { 25296 {
25261 /* TODO: Don't return dummy size. */ 25297 /* TODO: Don't return dummy size. */
25262 return OK_PIXELS (100); 25298 return OK_PIXELS (100);
25263 } 25299 }
25264#endif 25300#endif
25301 /* '(+ EXPR...)' or '(- EXPR...)' add or subtract
25302 recursively calculated values. */
25265 if (EQ (car, Qplus) || EQ (car, Qminus)) 25303 if (EQ (car, Qplus) || EQ (car, Qminus))
25266 { 25304 {
25267 bool first = true; 25305 bool first = true;
@@ -25289,15 +25327,18 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25289 car = Qnil; 25327 car = Qnil;
25290 } 25328 }
25291 25329
25330 /* '(NUM)': absolute number of pixels. */
25292 if (NUMBERP (car)) 25331 if (NUMBERP (car))
25293 { 25332 {
25294 double fact; 25333 double fact;
25334 int offset =
25335 width_p && align_to && *align_to < 0 ? it->lnum_pixel_width : 0;
25295 pixels = XFLOATINT (car); 25336 pixels = XFLOATINT (car);
25296 if (NILP (cdr)) 25337 if (NILP (cdr))
25297 return OK_PIXELS (pixels); 25338 return OK_PIXELS (pixels + offset);
25298 if (calc_pixel_width_or_height (&fact, it, cdr, 25339 if (calc_pixel_width_or_height (&fact, it, cdr,
25299 font, width_p, align_to)) 25340 font, width_p, align_to))
25300 return OK_PIXELS (pixels * fact); 25341 return OK_PIXELS (pixels * fact + offset);
25301 return false; 25342 return false;
25302 } 25343 }
25303 25344