Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 680
deprecated Avatar asked Sep 05 '13 08:09

deprecated


4 Answers

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))
like image 121
Thomas Avatar answered Sep 30 '22 06:09

Thomas


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!

like image 32
Daniel Neal Avatar answered Sep 30 '22 07:09

Daniel Neal


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.

like image 24
abo-abo Avatar answered Sep 30 '22 07:09

abo-abo


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

like image 39
juanleon Avatar answered Sep 30 '22 07:09

juanleon