]> git.eshelyaron.com Git - emacs.git/commitdiff
Start display-fill-column-indicator-mode.
authorJimmy Aguilar Mena <spacibba@aol.com>
Tue, 12 Mar 2019 19:06:28 +0000 (20:06 +0100)
committerJimmy Aguilar Mena <spacibba@aol.com>
Sun, 5 May 2019 14:27:37 +0000 (16:27 +0200)
lisp/cus-start.el
lisp/display-fill-column-indicator.el [new file with mode: 0644]
lisp/faces.el
lisp/frame.el
lisp/ldefs-boot.el
src/xdisp.c

index baa05d0a89a665a7835fbe4e61d01a527d0f7070..3f58eac63bc168f6c63e05ce7ed242ab071ab44e 100644 (file)
@@ -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 (file)
index 0000000..6e09908
--- /dev/null
@@ -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
index fa526c35061f62a04df65b375bd1e305b7edf694..67d963e34965c28da3f8b832961bcf469d496ea9 100644 (file)
@@ -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
index 539a0f4dfc748d7e202e6346c7539f441935dca2..a8c230cb7b20c1d9437084a2dae48df2afe40ecb 100644 (file)
@@ -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))
 
index cb378ceaede291a49fef69440baffb89665a076a..45c72ffbd4dfcb276bf38d34b20aba86420e503d 100644 (file)
@@ -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-")))
+
+;;;***
+\f
+;;;### (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-")))
 
 ;;;***
 \f
index 3bdb8ea1b0f4a8b69391b165720567229814b4f3..f16096642771509c28c35c12a0b30957cb3b129f 100644 (file)
@@ -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;