diff options
| author | Jimmy Aguilar Mena | 2019-03-12 20:06:28 +0100 |
|---|---|---|
| committer | Jimmy Aguilar Mena | 2019-05-05 16:27:37 +0200 |
| commit | 245dff16e3e62c3b7458170a2436a5fa3e2945fd (patch) | |
| tree | f7d295df39389167e332bba4c115adc7328a428f /src | |
| parent | f8625bc8f7573162b1c6b136f4791d8facecd836 (diff) | |
| download | emacs-245dff16e3e62c3b7458170a2436a5fa3e2945fd.tar.gz emacs-245dff16e3e62c3b7458170a2436a5fa3e2945fd.zip | |
Start display-fill-column-indicator-mode.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 179 |
1 files changed, 170 insertions, 9 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 3bdb8ea1b0f..f1609664277 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -20152,15 +20152,49 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 20152 | it->what = IT_CHARACTER; | 20152 | it->what = IT_CHARACTER; |
| 20153 | memset (&it->position, 0, sizeof it->position); | 20153 | memset (&it->position, 0, sizeof it->position); |
| 20154 | it->object = Qnil; | 20154 | it->object = Qnil; |
| 20155 | it->c = it->char_to_display = ' '; | ||
| 20156 | it->len = 1; | 20155 | it->len = 1; |
| 20157 | 20156 | ||
| 20157 | int local_default_face_id = | ||
| 20158 | lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); | ||
| 20159 | struct face* default_face = | ||
| 20160 | FACE_FROM_ID_OR_NULL (it->f, local_default_face_id); | ||
| 20161 | |||
| 20162 | /* Corner case for when display-fill-column-indicator-mode | ||
| 20163 | is active and the extra character should be added in the | ||
| 20164 | same place than the line */ | ||
| 20165 | if (!NILP (Vdisplay_fill_column_indicator) | ||
| 20166 | && (it->w->pseudo_window_p == 0) | ||
| 20167 | && FIXNATP (Vdisplay_fill_column_indicator_column) | ||
| 20168 | && FIXNATP (Vdisplay_fill_column_indicator_character)) | ||
| 20169 | { | ||
| 20170 | struct font *font = | ||
| 20171 | default_face->font ? default_face->font : FRAME_FONT (it->f); | ||
| 20172 | const int char_width = | ||
| 20173 | font->average_width ? font->average_width : font->space_width; | ||
| 20174 | const int fill_column = | ||
| 20175 | XFIXNAT (Vdisplay_fill_column_indicator_column); | ||
| 20176 | const int column_x = | ||
| 20177 | char_width * fill_column + it->lnum_pixel_width; | ||
| 20178 | |||
| 20179 | if (it->current_x == column_x) | ||
| 20180 | { | ||
| 20181 | it->c = it->char_to_display = | ||
| 20182 | XFIXNAT (Vdisplay_fill_column_indicator_character); | ||
| 20183 | it->face_id = | ||
| 20184 | merge_faces (it->w, Qfill_column_face, 0, DEFAULT_FACE_ID); | ||
| 20185 | face = FACE_FROM_ID(it->f, it->face_id); | ||
| 20186 | goto produce_glyphs; | ||
| 20187 | } | ||
| 20188 | } | ||
| 20189 | |||
| 20190 | it->c = it->char_to_display = ' '; | ||
| 20158 | /* If the default face was remapped, be sure to use the | 20191 | /* If the default face was remapped, be sure to use the |
| 20159 | remapped face for the appended newline. */ | 20192 | remapped face for the appended newline. */ |
| 20160 | if (default_face_p) | 20193 | if (default_face_p) |
| 20161 | it->face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); | 20194 | it->face_id = local_default_face_id; |
| 20162 | else if (it->face_before_selective_p) | 20195 | else if (it->face_before_selective_p) |
| 20163 | it->face_id = it->saved_face_id; | 20196 | it->face_id = it->saved_face_id; |
| 20197 | |||
| 20164 | face = FACE_FROM_ID (it->f, it->face_id); | 20198 | face = FACE_FROM_ID (it->f, it->face_id); |
| 20165 | it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); | 20199 | it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); |
| 20166 | /* In R2L rows, we will prepend a stretch glyph that will | 20200 | /* In R2L rows, we will prepend a stretch glyph that will |
| @@ -20169,11 +20203,12 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 20169 | set. */ | 20203 | set. */ |
| 20170 | if (it->glyph_row->reversed_p | 20204 | if (it->glyph_row->reversed_p |
| 20171 | /* But if the appended newline glyph goes all the way to | 20205 | /* But if the appended newline glyph goes all the way to |
| 20172 | the end of the row, there will be no stretch glyph, | 20206 | the end of the row, there will be no stretch glyph, |
| 20173 | so leave the box flag set. */ | 20207 | so leave the box flag set. */ |
| 20174 | && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) | 20208 | && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) |
| 20175 | it->end_of_box_run_p = false; | 20209 | it->end_of_box_run_p = false; |
| 20176 | 20210 | ||
| 20211 | produce_glyphs: | ||
| 20177 | PRODUCE_GLYPHS (it); | 20212 | PRODUCE_GLYPHS (it); |
| 20178 | 20213 | ||
| 20179 | #ifdef HAVE_WINDOW_SYSTEM | 20214 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -20322,7 +20357,8 @@ extend_face_to_end_of_line (struct it *it) | |||
| 20322 | #ifdef HAVE_WINDOW_SYSTEM | 20357 | #ifdef HAVE_WINDOW_SYSTEM |
| 20323 | && !face->stipple | 20358 | && !face->stipple |
| 20324 | #endif | 20359 | #endif |
| 20325 | && !it->glyph_row->reversed_p) | 20360 | && !it->glyph_row->reversed_p |
| 20361 | && NILP (Vdisplay_fill_column_indicator)) | ||
| 20326 | return; | 20362 | return; |
| 20327 | 20363 | ||
| 20328 | /* Set the glyph row flag indicating that the face of the last glyph | 20364 | /* Set the glyph row flag indicating that the face of the last glyph |
| @@ -20374,8 +20410,81 @@ extend_face_to_end_of_line (struct it *it) | |||
| 20374 | default_face->id; | 20410 | default_face->id; |
| 20375 | it->glyph_row->used[RIGHT_MARGIN_AREA] = 1; | 20411 | it->glyph_row->used[RIGHT_MARGIN_AREA] = 1; |
| 20376 | } | 20412 | } |
| 20413 | |||
| 20414 | /* Display fill column indicator if not in modeline or | ||
| 20415 | toolbar and display fill column indicator mode is | ||
| 20416 | active */ | ||
| 20417 | if (!NILP (Vdisplay_fill_column_indicator) | ||
| 20418 | && (it->w->pseudo_window_p == 0) | ||
| 20419 | && FIXNATP (Vdisplay_fill_column_indicator_column) | ||
| 20420 | && FIXNATP (Vdisplay_fill_column_indicator_character)) | ||
| 20421 | { | ||
| 20422 | struct font *font = | ||
| 20423 | default_face->font ? default_face->font : FRAME_FONT (f); | ||
| 20424 | const int char_width = | ||
| 20425 | font->average_width ? font->average_width : font->space_width; | ||
| 20426 | |||
| 20427 | const int fill_column = | ||
| 20428 | XFIXNAT (Vdisplay_fill_column_indicator_column); | ||
| 20429 | |||
| 20430 | const int column_x = char_width * fill_column + it->lnum_pixel_width; | ||
| 20431 | |||
| 20432 | if ((it->current_x <= column_x) | ||
| 20433 | && (column_x <= it->last_visible_x)) | ||
| 20434 | { | ||
| 20435 | const char saved_char = it->char_to_display; | ||
| 20436 | const struct text_pos saved_pos = it->position; | ||
| 20437 | const bool saved_avoid_cursor = it->avoid_cursor_p; | ||
| 20438 | const int saved_face_id = it->face_id; | ||
| 20439 | const bool saved_box_start = it->start_of_box_run_p; | ||
| 20440 | Lisp_Object save_object = it->object; | ||
| 20441 | |||
| 20442 | /* The stretch width needs to considet the latter added glyph */ | ||
| 20443 | const int stretch_width = column_x - it->current_x - char_width; | ||
| 20444 | |||
| 20445 | memset (&it->position, 0, sizeof it->position); | ||
| 20446 | it->avoid_cursor_p = true; | ||
| 20447 | it->object = Qnil; | ||
| 20448 | |||
| 20449 | /* Only generate a stretch glysph if there is distance between | ||
| 20450 | current_x and and the indicator position */ | ||
| 20451 | if (stretch_width > 0) | ||
| 20452 | { | ||
| 20453 | int stretch_ascent = (((it->ascent + it->descent) | ||
| 20454 | * FONT_BASE (font)) / FONT_HEIGHT (font)); | ||
| 20455 | append_stretch_glyph (it, Qnil, stretch_width, | ||
| 20456 | it->ascent + it->descent, stretch_ascent); | ||
| 20457 | } | ||
| 20458 | |||
| 20459 | /* Generate the glysph indicator only if append_space_for_newline | ||
| 20460 | didn't already. */ | ||
| 20461 | if (it->current_x < column_x) | ||
| 20462 | { | ||
| 20463 | it->char_to_display = | ||
| 20464 | XFIXNAT (Vdisplay_fill_column_indicator_character); | ||
| 20465 | it->face_id = | ||
| 20466 | merge_faces (it->w, Qfill_column_face, 0, DEFAULT_FACE_ID); | ||
| 20467 | PRODUCE_GLYPHS (it); | ||
| 20468 | } | ||
| 20469 | |||
| 20470 | /* Restore the face after the indicator was generated */ | ||
| 20471 | it->face_id = saved_face_id; | ||
| 20472 | |||
| 20473 | /* If there is space after the indicator generate an extra | ||
| 20474 | empty glysph to restore the face. */ | ||
| 20475 | it->char_to_display = ' '; | ||
| 20476 | PRODUCE_GLYPHS (it); | ||
| 20477 | |||
| 20478 | it->char_to_display = saved_char; | ||
| 20479 | it->position = saved_pos; | ||
| 20480 | it->avoid_cursor_p = saved_avoid_cursor; | ||
| 20481 | it->start_of_box_run_p = saved_box_start; | ||
| 20482 | it->object = save_object; | ||
| 20483 | } | ||
| 20484 | } | ||
| 20377 | } | 20485 | } |
| 20378 | #ifdef HAVE_WINDOW_SYSTEM | 20486 | #ifdef HAVE_WINDOW_SYSTEM |
| 20487 | |||
| 20379 | if (it->glyph_row->reversed_p) | 20488 | if (it->glyph_row->reversed_p) |
| 20380 | { | 20489 | { |
| 20381 | /* Prepend a stretch glyph to the row, such that the | 20490 | /* Prepend a stretch glyph to the row, such that the |
| @@ -20495,10 +20604,37 @@ extend_face_to_end_of_line (struct it *it) | |||
| 20495 | it->face_id = default_face->id; | 20604 | it->face_id = default_face->id; |
| 20496 | else | 20605 | else |
| 20497 | it->face_id = face->id; | 20606 | it->face_id = face->id; |
| 20498 | PRODUCE_GLYPHS (it); | ||
| 20499 | 20607 | ||
| 20500 | while (it->current_x <= it->last_visible_x) | 20608 | /* Display fill-column-line if mode is active */ |
| 20501 | PRODUCE_GLYPHS (it); | 20609 | if (!NILP (Vdisplay_fill_column_indicator)) |
| 20610 | { | ||
| 20611 | const int fill_column_indicator_line = | ||
| 20612 | XFIXNAT (Vdisplay_fill_column_indicator_column) | ||
| 20613 | + it->lnum_pixel_width; | ||
| 20614 | do | ||
| 20615 | { | ||
| 20616 | if (it->current_x == fill_column_indicator_line) | ||
| 20617 | { | ||
| 20618 | const int saved_face = it->face_id; | ||
| 20619 | it->face_id = | ||
| 20620 | merge_faces (it->w, Qfill_column_face, 0, DEFAULT_FACE_ID); | ||
| 20621 | it->c = it->char_to_display = | ||
| 20622 | XFIXNAT (Vdisplay_fill_column_indicator_character); | ||
| 20623 | PRODUCE_GLYPHS (it); | ||
| 20624 | it->face_id = saved_face; | ||
| 20625 | it->c = it->char_to_display = ' '; | ||
| 20626 | } | ||
| 20627 | else | ||
| 20628 | PRODUCE_GLYPHS (it); | ||
| 20629 | } while (it->current_x <= it->last_visible_x); | ||
| 20630 | } | ||
| 20631 | else | ||
| 20632 | { | ||
| 20633 | do | ||
| 20634 | { | ||
| 20635 | PRODUCE_GLYPHS (it); | ||
| 20636 | } while (it->current_x <= it->last_visible_x); | ||
| 20637 | } | ||
| 20502 | 20638 | ||
| 20503 | if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0 | 20639 | if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0 |
| 20504 | && (it->glyph_row->used[RIGHT_MARGIN_AREA] | 20640 | && (it->glyph_row->used[RIGHT_MARGIN_AREA] |
| @@ -20588,7 +20724,8 @@ highlight_trailing_whitespace (struct it *it) | |||
| 20588 | if (!row->reversed_p) | 20724 | if (!row->reversed_p) |
| 20589 | { | 20725 | { |
| 20590 | while (glyph >= start | 20726 | while (glyph >= start |
| 20591 | && glyph->type == CHAR_GLYPH | 20727 | && (glyph->type == CHAR_GLYPH |
| 20728 | || glyph->type == STRETCH_GLYPH) | ||
| 20592 | && NILP (glyph->object)) | 20729 | && NILP (glyph->object)) |
| 20593 | --glyph; | 20730 | --glyph; |
| 20594 | } | 20731 | } |
| @@ -32663,6 +32800,9 @@ be let-bound around code that needs to disable messages temporarily. */); | |||
| 32663 | /* Name of a text property which disables line-number display. */ | 32800 | /* Name of a text property which disables line-number display. */ |
| 32664 | DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable"); | 32801 | DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable"); |
| 32665 | 32802 | ||
| 32803 | /* Names of the face used to display fill column indicator character. */ | ||
| 32804 | DEFSYM (Qfill_column_face, "fill-column-face"); | ||
| 32805 | |||
| 32666 | /* Name and number of the face used to highlight escape glyphs. */ | 32806 | /* Name and number of the face used to highlight escape glyphs. */ |
| 32667 | DEFSYM (Qescape_glyph, "escape-glyph"); | 32807 | DEFSYM (Qescape_glyph, "escape-glyph"); |
| 32668 | 32808 | ||
| @@ -33235,6 +33375,27 @@ either `relative' or `visual'. */); | |||
| 33235 | DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen"); | 33375 | DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen"); |
| 33236 | Fmake_variable_buffer_local (Qdisplay_line_numbers_widen); | 33376 | Fmake_variable_buffer_local (Qdisplay_line_numbers_widen); |
| 33237 | 33377 | ||
| 33378 | DEFVAR_LISP ("display-fill-column-indicator", Vdisplay_fill_column_indicator, | ||
| 33379 | doc: /* Non-nil means display the fill column indicator. */); | ||
| 33380 | Vdisplay_fill_column_indicator = Qnil; | ||
| 33381 | DEFSYM (Qdisplay_fill_column_indicator, "display-fill-column-indicator"); | ||
| 33382 | Fmake_variable_buffer_local (Qdisplay_fill_column_indicator); | ||
| 33383 | |||
| 33384 | DEFVAR_LISP ("display-fill-column-indicator-column", Vdisplay_fill_column_indicator_column, | ||
| 33385 | doc: /* Column to draw the indicator when `display-fill-column-indicator' is non-nil. | ||
| 33386 | The default value is the variable `fill-column' if not other value is given. */); | ||
| 33387 | Vdisplay_fill_column_indicator_column = Qnil; | ||
| 33388 | DEFSYM (Qdisplay_fill_column_indicator_column, "display-fill-column-indicator-column"); | ||
| 33389 | Fmake_variable_buffer_local (Qdisplay_fill_column_indicator_column); | ||
| 33390 | |||
| 33391 | DEFVAR_LISP ("display-fill-column-indicator-character", Vdisplay_fill_column_indicator_character, | ||
| 33392 | doc: /* Character to draw the indicator when `display-fill-column-indicator' is non-nil. | ||
| 33393 | The default is U+2502 but a good alternative is (ascii 124) if | ||
| 33394 | the font in fill-column-face does not support Unicode characters. */); | ||
| 33395 | Vdisplay_fill_column_indicator_character = Qnil; | ||
| 33396 | DEFSYM (Qdisplay_fill_column_indicator_character, "display-fill-column-indicator-character"); | ||
| 33397 | Fmake_variable_buffer_local (Qdisplay_fill_column_indicator_character); | ||
| 33398 | |||
| 33238 | DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay, | 33399 | DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay, |
| 33239 | doc: /* Non-nil means don't eval Lisp during redisplay. */); | 33400 | doc: /* Non-nil means don't eval Lisp during redisplay. */); |
| 33240 | inhibit_eval_during_redisplay = false; | 33401 | inhibit_eval_during_redisplay = false; |