diff --git a/lisp/outline.el b/lisp/outline.el index 9b0b8d6ea92..c3284f231dc 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -582,11 +582,17 @@ See the command `outline-mode' for more information on this mode." 'outline-close-rtl-in-margins 'outline-close-in-margins))))) (* (default-font-width) 1.0))))) - (if outline--use-rtl - (setq-local right-margin-width (+ right-margin-width - outline--margin-width)) - (setq-local left-margin-width (+ left-margin-width - outline--margin-width))) + (cond + (outline--use-rtl + (setq-local right-margin-width + (+ right-margin-width outline--margin-width)) + (setq-local right-margin-columns + (append right-margin-columns '(outline)))) + (t + (setq-local left-margin-width + (+ left-margin-width outline--margin-width)) + (setq-local left-margin-columns + (append left-margin-columns '(outline))))) (setq-local fringes-outside-margins t) ;; Force display of margins (when (eq (current-buffer) (window-buffer)) @@ -628,14 +634,18 @@ See the command `outline-mode' for more information on this mode." (when outline-minor-mode-use-buttons (outline--remove-buttons (point-min) (point-max)) (when (and (eq outline-minor-mode-use-buttons 'in-margins) - outline--margin-width - (< 0 (if outline--use-rtl right-margin-width - left-margin-width))) - (if outline--use-rtl - (setq-local right-margin-width (- right-margin-width - outline--margin-width)) - (setq-local left-margin-width (- left-margin-width - outline--margin-width))) + outline--margin-width) + (cond + (outline--use-rtl + (setq-local right-margin-width + (max 0 (- right-margin-width outline--margin-width))) + (setq-local right-margin-columns + (remq 'outline right-margin-columns))) + (t + (setq-local left-margin-width + (max 0 (- left-margin-width outline--margin-width))) + (setq-local left-margin-columns + (remq 'outline left-margin-columns)))) (setq-local outline--margin-width nil) (kill-local-variable 'fringes-outside-margins) ;; Force removal of margins @@ -1963,7 +1973,8 @@ With a prefix argument, show headings up to that LEVEL." (string (plist-get icon 'string)) (image (plist-get icon 'image)) (display `((margin ,(if outline--use-rtl - 'right-margin 'left-margin)) + 'right-margin 'left-margin) + outline) ,(or image (if face (propertize string 'face face) string)))) diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 07a3e7785a3..6e33f884d03 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -883,7 +883,7 @@ symbol `fringes' or the symbol `margins'." (cons flymake-fringe-indicator-position valuelist)) ((and (stringp indicator-car) flymake-margin-indicator-position) - `((margin ,flymake-margin-indicator-position) + `((margin ,flymake-margin-indicator-position flymake) ,(propertize indicator-car 'face `(:inherit (,(cdr valuelist) default)) @@ -897,9 +897,24 @@ symbol `fringes' or the symbol `margins'." (defun flymake--restore-margins () (when flymake--original-margin-width - (if (eq flymake-margin-indicator-position 'left-margin) - (setq left-margin-width flymake--original-margin-width) - (setq right-margin-width flymake--original-margin-width)))) + (if (boundp 'left-margin-columns) + (cond + ((eq flymake-margin-indicator-position 'left-margin) + (setq left-margin-width + (max 0 (- left-margin-width flymake--original-margin-width))) + (setq-local left-margin-columns + (remq 'flymake left-margin-columns))) + (t + (setq right-margin-width + (max 0 (- right-margin-width flymake--original-margin-width))) + (setq-local right-margin-columns + (remq 'flymake right-margin-columns)))) + (if (eq flymake-margin-indicator-position 'left-margin) + (setq left-margin-width flymake--original-margin-width) + (setq right-margin-width flymake--original-margin-width))) + (mapc (lambda (x) + (set-window-buffer x (window-buffer x))) + (get-buffer-window-list nil nil 'visible)))) (defun flymake--resize-margins () (let* ((indicators @@ -912,11 +927,22 @@ symbol `fringes' or the symbol `margins'." (car ind))) '(flymake-error flymake-warning flymake-note))) (width (apply #'max (mapcar #'string-width indicators)))) - (if (eq flymake-margin-indicator-position 'left-margin) - (setq flymake--original-margin-width left-margin-width - left-margin-width width) - (setq flymake--original-margin-width right-margin-width - right-margin-width width))) + (setq flymake--original-margin-width width) + (if (boundp 'left-margin-columns) + (cond + ((eq flymake-margin-indicator-position 'left-margin) + (setq left-margin-width (+ left-margin-width width)) + (setq-local left-margin-columns + (append left-margin-columns '(flymake)))) + (t + (setq right-margin-width (+ right-margin-width width)) + (setq-local right-margin-columns + (append right-margin-columns '(flymake))))) + (if (eq flymake-margin-indicator-position 'left-margin) + (setq flymake--original-margin-width left-margin-width + left-margin-width width) + (setq flymake--original-margin-width right-margin-width + right-margin-width width)))) (mapc (lambda (x) (set-window-buffer x (window-buffer x))) (get-buffer-window-list nil nil 'visible))) diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el index 688f2e7cdff..f1037a8e207 100644 --- a/lisp/progmodes/hideshow.el +++ b/lisp/progmodes/hideshow.el @@ -1068,7 +1068,7 @@ the overlay: `invisible' `hs'. Also, depending on variable ('margin (propertize "+" 'display - `((margin left-margin) + `((margin left-margin hideshow) ,(or (plist-get (icon-elements face-or-icon) 'image) (propertize (icon-string face-or-icon) 'keymap hs-indicators-map))) @@ -1511,6 +1511,8 @@ Key bindings: (setq-local hs-indicator-type 'margin)) (when (eq hs-indicator-type 'margin) (setq-local left-margin-width (1+ left-margin-width)) + (setq-local left-margin-columns + (append left-margin-columns '(hideshow))) (setq-local fringes-outside-margins t) ;; Force display of margins (when (eq (current-buffer) (window-buffer)) @@ -1525,6 +1527,7 @@ Key bindings: (when (and (eq hs-indicator-type 'margin) (< 0 left-margin-width)) (setq-local left-margin-width (1- left-margin-width)) + (setq-local left-margin-columns (remq 'hideshow left-margin-columns)) (kill-local-variable 'fringes-outside-margins) ;; Force removal of margins (when (eq (current-buffer) (window-buffer)) diff --git a/src/xdisp.c b/src/xdisp.c index 7afcf1ef727..5c34e8f8d80 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -6382,8 +6382,9 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, /* Prepare to handle `((margin left-margin) ...)', `((margin right-margin) ...)' and `((margin nil) ...)' prefixes for display specifications. - Also handle `((margin left-margin COLUMN) ...)' where COLUMN - specifies the column position (0-based) in the margin. */ + Also handle `((margin left-margin COLUMN) ...)' + where COLUMN specifies the column position (0-based) + in the margin, or a symbol. */ location = Qunbound; int margin_column = -1; /* -1 means no specific column requested */ if (CONSP (spec) && CONSP (XCAR (spec))) @@ -6407,9 +6408,25 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, tem = XCDR (XCAR (spec)); if (CONSP (tem) && (tem = XCDR (tem), CONSP (tem)) - && (tem = XCAR (tem), FIXNUMP (tem)) - && XFIXNUM (tem) >= 0) - margin_column = (int) XFIXNUM (tem); + && (tem = XCAR (tem), !NILP (tem))) + { + if (FIXNUMP (tem) && XFIXNUM (tem) >= 0) + margin_column = (int) XFIXNUM (tem); + else if (SYMBOLP (tem)) + { + Lisp_Object columns_list = Fsymbol_value + (EQ (location, Qleft_margin) + ? Qleft_margin_columns : Qright_margin_columns); + int pos = 0; + for (Lisp_Object tail = columns_list; CONSP (tail); + tail = XCDR (tail), pos++) + if (EQ (XCAR (tail), tem)) + { + margin_column = pos; + break; + } + } + } } } @@ -38996,6 +39013,29 @@ The recommended non-zero value is between 100000 and 1000000, depending on your patience and the speed of your system. */); max_redisplay_ticks = 0; + DEFSYM (Qleft_margin_columns, "left-margin-columns"); + DEFVAR_LISP ("left-margin-columns", Vleft_margin_columns, + doc: /* List of symbols for left margin columns. +Each symbol represents a mode that displays indicators in the left margin. +The position of a symbol in this list (0-based) determines the column +where that mode's margin indicators appear. + +For example, if this variable is set to (flymake outline hideshow), then +flymake indicators appear in column 0, outline in column 1, and hideshow +in column 2. Modes can use their symbol in a display spec like +((margin left-margin flymake) \">\") instead of a numeric column. */); + Vleft_margin_columns = Qnil; + + DEFSYM (Qright_margin_columns, "right-margin-columns"); + DEFVAR_LISP ("right-margin-columns", Vright_margin_columns, + doc: /* List of symbols for right margin columns. +Each symbol represents a mode that displays indicators in the right margin. +The position of a symbol in this list (0-based) determines the column +where that mode's margin indicators appear. + +See `left-margin-columns' for more details. */); + Vright_margin_columns = Qnil; + /* Called by decode_mode_spec. */ DEFSYM (Qfile_remote_p, "file-remote-p");