summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJimmy Aguilar Mena <spacibba@aol.com>2019-03-12 20:06:28 +0100
committerJimmy Aguilar Mena <spacibba@aol.com>2019-05-03 23:34:29 +0200
commit942f68a539bc516ef578be108a9c967722f0175e (patch)
tree167354d22bcbd057bf9401bbb1f47415232ae498
parent6caf9be6cacad2da36f2a1303304df588325d38b (diff)
downloademacs-942f68a539bc516ef578be108a9c967722f0175e.tar.gz
Start display-fill-column-indicator-mode.
-rw-r--r--lisp/cus-start.el5
-rw-r--r--lisp/display-fill-column-indicator.el78
-rw-r--r--lisp/faces.el14
-rw-r--r--lisp/frame.el3
-rw-r--r--lisp/ldefs-boot.el39
-rw-r--r--src/xdisp.c179
6 files changed, 308 insertions, 10 deletions
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index baa05d0a89a..3f58eac63bc 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -648,6 +648,11 @@ since it could result in memory overflow and make Emacs crash."
(const :tag "Count lines from beginning of narrowed region"
:value nil))
"26.1")
+
+ (display-fill-column-indicator-column display-fill-column-indicator
+ integer "27.1")
+ (display-fill-column-indicator-character display-fill-column-indicator
+ character "27.1")
;; xfaces.c
(scalable-fonts-allowed display boolean "22.1")
;; xfns.c
diff --git a/lisp/display-fill-column-indicator.el b/lisp/display-fill-column-indicator.el
new file mode 100644
index 00000000000..6e0990839e6
--- /dev/null
+++ b/lisp/display-fill-column-indicator.el
@@ -0,0 +1,78 @@
+;;; display-fill-column-indicator.el --- interface for display-fill-column-indicator -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+;; Maintainer: emacs-devel@gnu.org
+;; Keywords: convenience
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Provides a minor mode interface for `display-fill-column-indicator'.
+;;
+;; Toggle display of line numbers with M-x
+;; display-fill-column-indicator-mode. To enable line numbering in
+;; all buffers, use M-x global-display-fill-column-indicator-mode. To
+;; change the default line column
+
+
+;; NOTE: Customization variables for
+;; `display-fill-column-indicator-column' and
+;; `display-fill-column-indicator-char' itself are defined in
+;; cus-start.el.
+
+;;; Code:
+
+(defgroup display-fill-column-indicator nil
+ "Display line numbers in the buffer."
+ :group 'convenience
+ :group 'display)
+
+
+;;;###autoload
+(define-minor-mode display-fill-column-indicator-mode
+ "Toggle display fill column indicator.
+This uses `display-fill-column-indicator' internally.
+
+To change the position of the line displayed by default,
+customize `display-fill-column-indicator-column' you can change the
+character for the line setting `display-fill-column-indicator-character'."
+ :lighter nil
+ (if display-fill-column-indicator-mode
+ (progn
+ (setq display-fill-column-indicator t)
+ (unless display-fill-column-indicator-column
+ (setq display-fill-column-indicator-column fill-column))
+ (unless display-fill-column-indicator-character
+ (if (char-displayable-p ?\u2502)
+ (setq display-fill-column-indicator-character ?\u2502)
+ (setq display-fill-column-indicator-character ?|))))
+ (setq display-fill-column-indicator nil)))
+
+(defun display-fill-column-indicator--turn-on ()
+ "Turn on `display-fill-column-indicator-mode'."
+ (unless (or (minibufferp)
+ (and (daemonp) (null (frame-parameter nil 'client))))
+ (display-fill-column-indicator-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode global-display-fill-column-indicator-mode
+ display-fill-column-indicator-mode display-fill-column-indicator--turn-on)
+
+(provide 'display-fill-column-indicator)
+
+;;; display-fill-column-indicator.el ends here
diff --git a/lisp/faces.el b/lisp/faces.el
index fa526c35061..67d963e3496 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2500,6 +2500,20 @@ unwanted effects."
:group 'basic-faces
:group 'display-line-numbers)
+;; Definition stolen from display-line-numbers.
+(defface fill-column-face
+ '((t :inherit (shadow default) :height 1.0))
+ "Face for displaying fill column indicator line.
+This face is used when `display-fill-column-indicator-mode' is
+non-nil.
+
+If you customize the font of this face, make sure it is a
+monospaced font, otherwise the line's characters will not line
+up horizontally."
+ :version "27.1"
+ :group 'basic-faces
+ :group 'display-fill-column-indicator)
+
(defface escape-glyph
'((((background dark)) :foreground "cyan")
;; See the comment in minibuffer-prompt for
diff --git a/lisp/frame.el b/lisp/frame.el
index 539a0f4dfc7..a8c230cb7b2 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -2682,6 +2682,9 @@ See also `toggle-frame-maximized'."
display-line-numbers-width
display-line-numbers-current-absolute
display-line-numbers-widen
+ display-fill-column-indicator
+ display-fill-column-indicator-column
+ display-fill-column-indicator-character
bidi-paragraph-direction
bidi-display-reordering))
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index cb378ceaede..45c72ffbd4d 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -7734,7 +7734,44 @@ See `display-line-numbers-mode' for more information on Display-Line-Numbers mod
\(fn &optional ARG)" t nil)
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "display-line-numbers" '("display-line-numbers-")))
+(if (fboundp 'register-definition-prefixes)
+ (register-definition-prefixes "display-line-numbers" '("display-line-numbers-")))
+
+;;;***
+
+;;;### (autoloads nil "display-fill-column-indicator" "display-fill-column-indicator.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from display-fill-column-indicator.el
+
+(autoload 'display-fill-column-indicator-mode "display-fill-column-indicator" "\
+Toggle display fill column indicator.
+This uses `display-fill-column-indicator' internally.
+
+To change the position of the line displayed by default,
+customize `display-fill-column-indicator-column'.
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-display-fill-column-indicator-mode nil "\
+Non-nil if Global Display-fill-column-indicator mode is enabled.
+See the `global-display-fill-column-indicator-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'global-display-fill-column-indicator-mode
+ "display-fill-column-indicator" nil)
+
+(autoload 'global-display-fill-column-indicator-mode
+ "display-fill-column-indicator" "\
+Toggle display fill column indicator.
+This uses `display-fill-column-indicator' internally.
+
+To change the position of the line displayed by default,
+customize `display-fill-column-indicator-column'.
+
+\(fn &optional ARG)" t nil)
+
+(if (fboundp 'register-definition-prefixes)
+ (register-definition-prefixes "display-fill-column-indicator" '("display-fill-column-indicator-")))
;;;***
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;