deprecated
deprecated

Reputation: 5242

Close HTML tags as soon as one opens them

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?

Upvotes: 6

Views: 1552

Answers (5)

Achylles
Achylles

Reputation: 39

Using sgml-mode is a pain for me... When I hit "C-c C-t" in an html file, the minibuffer opens and I enter the attributes... But it keeps asking for more attributes in a infinity loop... If I hit C-g to get out of the non-sense loop, it deletes everything I had entered before.... How do I get out from the sgml-tag minibuffer loop without it erasing my tags in the file?

Upvotes: 0

Thomas
Thomas

Reputation: 17422

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))

Upvotes: 4

Daniel Neal
Daniel Neal

Reputation: 4173

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!

Upvotes: 5

juanleon
juanleon

Reputation: 9380

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

Upvotes: 1

abo-abo
abo-abo

Reputation: 20342

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 kbdC-o and it get's expanded to <kbd></kbd> with cursor right in the middle. You can have the same behavior for div.

Upvotes: 1

Related Questions