I'd like the corresponding, closing HTML tag to be automatically inserted whenever I open one.
So if I type
<div>
I should get
<div></div>
Without having to call to sgml-close-tag
myself.
How to achieve this?
Rather than calling a hook function after every single key-stroke, it makes sense to only call it after a > was typed. This can be achieved by rebinding the > character in the keymap that sgml-mode
uses.
In addition, sgml-close-tag
shouldn't get called if the tag is already closed. Therefore, the following code adds a simple regexp check for that:
(defun my-sgml-insert-gt ()
"Inserts a `>' character and calls
`my-sgml-close-tag-if-necessary', leaving point where it is."
(interactive)
(insert ">")
(save-excursion (my-sgml-close-tag-if-necessary)))
(defun my-sgml-close-tag-if-necessary ()
"Calls sgml-close-tag if the tag immediately before point is
an opening tag that is not followed by a matching closing tag."
(when (looking-back "<\\s-*\\([^</> \t\r\n]+\\)[^</>]*>")
(let ((tag (match-string 1)))
(unless (and (not (sgml-unclosed-tag-p tag))
(looking-at (concat "\\s-*<\\s-*/\\s-*" tag "\\s-*>")))
(sgml-close-tag)))))
(eval-after-load "sgml-mode"
'(define-key sgml-mode-map ">" 'my-sgml-insert-gt))
If you like paredit
(and if you're an emacs user, chances are you do), you may be interested in tagedit
, an emacs package written by Magnar Sveen that provides paredit
-like features for editing html.
The library is here: https://github.com/magnars/tagedit, and can be installed through Melpa/Marmalade (package-install tagedit
).
If you enable the experimental features (tagedit-add-experimental-features)
, then it will automatically close tags for you and keep the corresponding closing tag text matching the opening tag text. That's on top of being able to splice, slurp, barf and all the other crazy things that paredit
lets you do when working with balanced expressions...I think it's great!
I'm using yasnippet
for this purpose.
To type shortcuts this answer, like <kbd>C-o</kbd>
, I have the following snippet:
# -*- mode: snippet -*-
# name: kbd
# key: kbd
# --
<kbd>$0</kbd>
So I type kbd
C-o and it get's expanded to <kbd></kbd>
with cursor
right in the middle. You can have the same behavior for div
.
You may eval this on your sgml-buffer or add ii to your sgml-hook:
(add-hook 'post-self-insert-hook
(lambda () (and (eq (char-before) ?>) (sgml-close-tag))) nil t)
Whenever you insert a ">", the function sgml-close-tag
will be run for you
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With