[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: nXML mode indentation
From: |
N. Raghavendra |
Subject: |
Re: nXML mode indentation |
Date: |
Wed, 09 May 2018 08:52:36 +0530 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) |
At 2018-05-08T21:00:14+05:30, N. Raghavendra wrote:
> Now, the next thing I see is that if, after this indentation, I do
> `fill-paragraph', it goes back to the old indentation. Anyway, I'll
> deal with that later. For now, I'll make do with these changes, which
> at least give me the indentation I want.
I've found a fix for this also.
I've seen references to difficulties with nXML mode indentation, so I am
enclosing the changes in case someone else is bugged by the problem.
Using the advice mechanism seems a kludge, but it will do for me at
present.
Thanks,
Raghu.
----------
;; Fix indentation, so that it conforms to the guidelines of the
;; FreeBSD Documentation Project.
;;
https://www.freebsd.org/doc/en_US.ISO8859-1/books/fdp-primer/writing-style-guide.html#writing-style-indentation
(defun my-nxml-compute-indent-from-matching-start-tag ()
"Compute the indent for an end tag line using its start tag.
This function is meant to be an overriding advice for
`nxml-compute-indent-from-matching-start-tag'. Adds a
local variable ONLY-END-TAG to distinguish between end
tags that are alone on a line, from end tags that are
accompanied by text on a line."
(save-excursion
(back-to-indentation)
(let ((bol (point))
(only-end-tag nil))
(let ((inhibit-field-text-motion t))
(end-of-line))
(skip-chars-backward " \t")
(and (= (nxml-token-before) (point))
(memq xmltok-type '(end-tag partial-end-tag))
;; start of line must not be inside a token
(or (and (= xmltok-start bol)
(setq only-end-tag t))
(save-excursion
(goto-char bol)
(nxml-token-after)
(= xmltok-start bol))
(eq xmltok-type 'data))
(condition-case nil
(nxml-scan-element-backward
(point)
nil
(- (point)
nxml-end-tag-indent-scan-distance))
(nxml-scan-error nil))
(< xmltok-start bol)
(progn
(goto-char xmltok-start)
(skip-chars-backward " \t")
(bolp))
(if only-end-tag
(current-indentation)
(+ (current-indentation) nxml-child-indent))))))
(advice-add 'nxml-compute-indent-from-matching-start-tag :override
#'my-nxml-compute-indent-from-matching-start-tag)
(defun my-nxml-compute-indent-from-previous-line ()
"Compute the indent for a line using the previous line.
This function is meant to be an overriding advice for
`nxml-compute-indent-from-previous-line'. Considers
extra cases depending on the context of the line."
(save-excursion
(end-of-line)
(let ((eol (point))
bol prev-bol ref
before-context after-context)
(back-to-indentation)
(setq bol (point))
(catch 'indent
;; Move backwards until the start of a non-blank line that is
;; not inside a token.
(while (progn
(when (= (forward-line -1) -1)
(throw 'indent 0))
(back-to-indentation)
(if (looking-at "[ \t]*$")
t
(or prev-bol
(setq prev-bol (point)))
(nxml-token-after)
(not (or (= xmltok-start (point))
(eq xmltok-type 'data))))))
(setq ref (point))
;; Now scan over tokens until the end of the line to be indented.
;; Determine the context before and after the beginning of the
;; line.
(while (< (point) eol)
(nxml-tokenize-forward)
(cond ((<= bol xmltok-start)
(setq after-context
(nxml-merge-indent-context-type after-context)))
((and (<= (point) bol)
(not (and (eq xmltok-type 'partial-start-tag)
(= (point) bol))))
(setq before-context
(nxml-merge-indent-context-type before-context)))
((eq xmltok-type 'data)
(setq before-context
(nxml-merge-indent-context-type before-context))
(setq after-context
(nxml-merge-indent-context-type after-context)))
;; If in the middle of a token that looks inline,
;; then indent relative to the previous non-blank line
((eq (nxml-merge-indent-context-type before-context)
'mixed)
(goto-char prev-bol)
(throw 'indent (current-column)))
(t
(throw 'indent
(nxml-compute-indent-in-token bol))))
(skip-chars-forward " \t\r\n"))
(goto-char ref)
(cond ((and (eq before-context 'mixed)
(eq after-context 'markup))
(+ (current-column) nxml-child-indent))
((and (eq before-context 'markup)
(eq after-context 'markup))
(current-column))
(t (+ (current-column)
(* nxml-child-indent
(+ (if (eq before-context 'start-tag) 1 0)
(if (eq after-context 'end-tag) -1 0))))))))))
(advice-add 'nxml-compute-indent-from-previous-line :override
#'my-nxml-compute-indent-from-previous-line)
(defun my-nxml-do-fill-paragraph (arg)
"Fill paragraph in `nxml-mode'.
This function is meant to be an overriding advice for
`nxml-do-fill-paragraph'. Adds some space to `fill-prefix'."
(let (fill-paragraph-function
fill-prefix
start end)
(save-excursion
(nxml-forward-paragraph)
(setq end (point))
(nxml-backward-paragraph)
(skip-chars-forward " \t\r\n")
(setq start (point))
(beginning-of-line)
(setq fill-prefix
(concat
(buffer-substring-no-properties (point) start)
(make-string nxml-child-indent ?\s)))
(when (and (not (nxml-get-inside (point)))
(looking-at "[ \t]*<!--"))
(setq fill-prefix (concat fill-prefix " ")))
(fill-region-as-paragraph start end arg))
(skip-line-prefix fill-prefix)
fill-prefix))
(advice-add 'nxml-do-fill-paragraph :override
#'my-nxml-do-fill-paragraph))
----------
--
N. Raghavendra <raghu@hri.res.in>, http://www.retrotexts.net/
Harish-Chandra Research Institute, http://www.hri.res.in/