diff options
Diffstat (limited to 'src/xdisp.c')
-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) it->what = IT_CHARACTER; memset (&it->position, 0, sizeof it->position); it->object = Qnil; - it->c = it->char_to_display = ' '; it->len = 1; + int local_default_face_id = + lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); + struct face* default_face = + FACE_FROM_ID_OR_NULL (it->f, local_default_face_id); + + /* Corner case for when display-fill-column-indicator-mode + is active and the extra character should be added in the + same place than the line */ + if (!NILP (Vdisplay_fill_column_indicator) + && (it->w->pseudo_window_p == 0) + && FIXNATP (Vdisplay_fill_column_indicator_column) + && FIXNATP (Vdisplay_fill_column_indicator_character)) + { + struct font *font = + default_face->font ? default_face->font : FRAME_FONT (it->f); + const int char_width = + font->average_width ? font->average_width : font->space_width; + const int fill_column = + XFIXNAT (Vdisplay_fill_column_indicator_column); + const int column_x = + char_width * fill_column + it->lnum_pixel_width; + + if (it->current_x == column_x) + { + it->c = it->char_to_display = + XFIXNAT (Vdisplay_fill_column_indicator_character); + it->face_id = + merge_faces (it->w, Qfill_column_face, 0, DEFAULT_FACE_ID); + face = FACE_FROM_ID(it->f, it->face_id); + goto produce_glyphs; + } + } + + it->c = it->char_to_display = ' '; /* If the default face was remapped, be sure to use the remapped face for the appended newline. */ if (default_face_p) - it->face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); + it->face_id = local_default_face_id; else if (it->face_before_selective_p) it->face_id = it->saved_face_id; + face = FACE_FROM_ID (it->f, it->face_id); it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); /* 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) set. */ if (it->glyph_row->reversed_p /* But if the appended newline glyph goes all the way to - the end of the row, there will be no stretch glyph, - so leave the box flag set. */ + the end of the row, there will be no stretch glyph, + so leave the box flag set. */ && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) it->end_of_box_run_p = false; + produce_glyphs: PRODUCE_GLYPHS (it); #ifdef HAVE_WINDOW_SYSTEM @@ -20322,7 +20357,8 @@ extend_face_to_end_of_line (struct it *it) #ifdef HAVE_WINDOW_SYSTEM && !face->stipple #endif - && !it->glyph_row->reversed_p) + && !it->glyph_row->reversed_p + && NILP (Vdisplay_fill_column_indicator)) return; /* 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) default_face->id; it->glyph_row->used[RIGHT_MARGIN_AREA] = 1; } + + /* Display fill column indicator if not in modeline or + toolbar and display fill column indicator mode is + active */ + if (!NILP (Vdisplay_fill_column_indicator) + && (it->w->pseudo_window_p == 0) + && FIXNATP (Vdisplay_fill_column_indicator_column) + && FIXNATP (Vdisplay_fill_column_indicator_character)) + { + struct font *font = + default_face->font ? default_face->font : FRAME_FONT (f); + const int char_width = + font->average_width ? font->average_width : font->space_width; + + const int fill_column = + XFIXNAT (Vdisplay_fill_column_indicator_column); + + const int column_x = char_width * fill_column + it->lnum_pixel_width; + + if ((it->current_x <= column_x) + && (column_x <= it->last_visible_x)) + { + const char saved_char = it->char_to_display; + const struct text_pos saved_pos = it->position; + const bool saved_avoid_cursor = it->avoid_cursor_p; + const int saved_face_id = it->face_id; + const bool saved_box_start = it->start_of_box_run_p; + Lisp_Object save_object = it->object; + + /* The stretch width needs to considet the latter added glyph */ + const int stretch_width = column_x - it->current_x - char_width; + + memset (&it->position, 0, sizeof it->position); + it->avoid_cursor_p = true; + it->object = Qnil; + + /* Only generate a stretch glysph if there is distance between + current_x and and the indicator position */ + if (stretch_width > 0) + { + int stretch_ascent = (((it->ascent + it->descent) + * FONT_BASE (font)) / FONT_HEIGHT (font)); + append_stretch_glyph (it, Qnil, stretch_width, + it->ascent + it->descent, stretch_ascent); + } + + /* Generate the glysph indicator only if append_space_for_newline + didn't already. */ + if (it->current_x < column_x) + { + it->char_to_display = + XFIXNAT (Vdisplay_fill_column_indicator_character); + it->face_id = + merge_faces (it->w, Qfill_column_face, 0, DEFAULT_FACE_ID); + PRODUCE_GLYPHS (it); + } + + /* Restore the face after the indicator was generated */ + it->face_id = saved_face_id; + + /* If there is space after the indicator generate an extra + empty glysph to restore the face. */ + it->char_to_display = ' '; + PRODUCE_GLYPHS (it); + + it->char_to_display = saved_char; + it->position = saved_pos; + it->avoid_cursor_p = saved_avoid_cursor; + it->start_of_box_run_p = saved_box_start; + it->object = save_object; + } + } } #ifdef HAVE_WINDOW_SYSTEM + if (it->glyph_row->reversed_p) { /* Prepend a stretch glyph to the row, such that the @@ -20495,10 +20604,37 @@ extend_face_to_end_of_line (struct it *it) it->face_id = default_face->id; else it->face_id = face->id; - PRODUCE_GLYPHS (it); - while (it->current_x <= it->last_visible_x) - PRODUCE_GLYPHS (it); + /* Display fill-column-line if mode is active */ + if (!NILP (Vdisplay_fill_column_indicator)) + { + const int fill_column_indicator_line = + XFIXNAT (Vdisplay_fill_column_indicator_column) + + it->lnum_pixel_width; + do + { + if (it->current_x == fill_column_indicator_line) + { + const int saved_face = it->face_id; + it->face_id = + merge_faces (it->w, Qfill_column_face, 0, DEFAULT_FACE_ID); + it->c = it->char_to_display = + XFIXNAT (Vdisplay_fill_column_indicator_character); + PRODUCE_GLYPHS (it); + it->face_id = saved_face; + it->c = it->char_to_display = ' '; + } + else + PRODUCE_GLYPHS (it); + } while (it->current_x <= it->last_visible_x); + } + else + { + do + { + PRODUCE_GLYPHS (it); + } while (it->current_x <= it->last_visible_x); + } if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0 && (it->glyph_row->used[RIGHT_MARGIN_AREA] @@ -20588,7 +20724,8 @@ highlight_trailing_whitespace (struct it *it) if (!row->reversed_p) { while (glyph >= start - && glyph->type == CHAR_GLYPH + && (glyph->type == CHAR_GLYPH + || glyph->type == STRETCH_GLYPH) && NILP (glyph->object)) --glyph; } @@ -32663,6 +32800,9 @@ be let-bound around code that needs to disable messages temporarily. */); /* Name of a text property which disables line-number display. */ DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable"); + /* Names of the face used to display fill column indicator character. */ + DEFSYM (Qfill_column_face, "fill-column-face"); + /* Name and number of the face used to highlight escape glyphs. */ DEFSYM (Qescape_glyph, "escape-glyph"); @@ -33235,6 +33375,27 @@ either `relative' or `visual'. */); DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen"); Fmake_variable_buffer_local (Qdisplay_line_numbers_widen); + DEFVAR_LISP ("display-fill-column-indicator", Vdisplay_fill_column_indicator, + doc: /* Non-nil means display the fill column indicator. */); + Vdisplay_fill_column_indicator = Qnil; + DEFSYM (Qdisplay_fill_column_indicator, "display-fill-column-indicator"); + Fmake_variable_buffer_local (Qdisplay_fill_column_indicator); + + DEFVAR_LISP ("display-fill-column-indicator-column", Vdisplay_fill_column_indicator_column, + doc: /* Column to draw the indicator when `display-fill-column-indicator' is non-nil. +The default value is the variable `fill-column' if not other value is given. */); + Vdisplay_fill_column_indicator_column = Qnil; + DEFSYM (Qdisplay_fill_column_indicator_column, "display-fill-column-indicator-column"); + Fmake_variable_buffer_local (Qdisplay_fill_column_indicator_column); + + DEFVAR_LISP ("display-fill-column-indicator-character", Vdisplay_fill_column_indicator_character, + doc: /* Character to draw the indicator when `display-fill-column-indicator' is non-nil. +The default is U+2502 but a good alternative is (ascii 124) if +the font in fill-column-face does not support Unicode characters. */); + Vdisplay_fill_column_indicator_character = Qnil; + DEFSYM (Qdisplay_fill_column_indicator_character, "display-fill-column-indicator-character"); + Fmake_variable_buffer_local (Qdisplay_fill_column_indicator_character); + DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay, doc: /* Non-nil means don't eval Lisp during redisplay. */); inhibit_eval_during_redisplay = false; |