key-bindings – ¿Un atajo de tecla para saltar en dos sentidos entre las etiquetas de apertura / cierre coincidentes en el modo nxml?

Pregunta:

Contexto

Editar un archivo XML arbitrario en nxml-mode .

Necesitar

Digamos que tengo una estructura como esta:

<a>
  <b>...</b>
</a>

Digamos que el cursor está en <a> . Estoy buscando un atajo que lleve el cursor directamente de <a> a </a> y vuelva si se vuelve a llamar .

Busca antes de preguntar

Esta pregunta solicita un salto unidireccional y obtiene una respuesta: CMn para saltar hacia adelante, Cu -1 CMn para saltar hacia atrás – Emacs, nxhtml ¿cómo resaltar o saltar a la etiqueta html de cierre? – Desbordamiento de pila .

Pero esto es un inconveniente porque para saltar hacia atrás uno tiene que:

  1. coloque el cursor exactamente al final de la etiqueta de cierre, y
  2. utilice un atajo de teclado largo y complicado Cu -1 CMn .

Hay espacio para más conveniencia: un atajo para ir en ambas direcciones .

¿Como hacer eso?

Si esto aún no existe, me gustaría hacerlo. Soy un desarrollador experimentado en varios lenguajes y entornos, pero no soy lo suficientemente competente en emacs-lisp para crear mi propia solución. Aún así, podría ser bastante fácil de hacer para un asistente de emacs-lisp.

Técnicamente, una función con este comportamiento funcionaría :

  • cuando el cursor está en una etiqueta de apertura, salta hacia adelante (llamada (nxml-forward-element 1) )
  • cuando el cursor está en una etiqueta de cierre, salta hacia atrás (llamada (nxml-forward-element -1) )
  • puntos de bonificación si, cuando el cursor está en cualquier lugar entre < y > (no solo justo antes de < como lo nxml-forward-element ), la función aún funciona
  • puntos de bonificación si, cuando el cursor está en cualquier lugar dentro del texto o lo que sea, salta hacia atrás a la etiqueta de apertura.

Respuesta:

Si usa el modo malvado, puede instalar https://github.com/redguardtoo/evil-matchit y presione %

Si prefiere Emacs original,

(autoload 'sgml-skip-tag-backward "sgml-mode" nil t)
(autoload 'sgml-skip-tag-forward "sgml-mode" nil t)
(defun html-get-tag ()
  (let ((b (line-beginning-position))
        (e (line-end-position))
        (looping t)
        (html-tag-char (string-to-char "<"))
        (char (following-char))
        (p (point))
        (found_tag -1))

    (save-excursion
      ;; search backward
      (unless (= char html-tag-char)
        (while (and looping (<= b (point)) (not (= char 60)))
          (setq char (following-char))
          (setq p (point))
          (if (= p (point-min))
              ;; need get out of loop anyway
              (setq looping nil)
            (backward-char))))

      ;; search forward
      (if (not (= char html-tag-char))
          (save-excursion
            (while (and (>= e (point)) (not (= char 60)))
              (setq char (following-char))
              (setq p (point))
              (forward-char))))

      ;; is end tag?
      (when (and (= char html-tag-char) (< p e))
        (goto-char p)
        (forward-char)
        (if (= (following-char) 47)
            (progn
              ;; </
              (skip-chars-forward "^>")
              (forward-char)
              (setq p (point))
              (setq found_tag 1))
          (progn
            ;; < , looks fine
            (backward-char)
            (setq found_tag 0)))))
    found_tag))

(defun html-jump(&optional num)
  "Jump forward from html open tag"
  (interactive "P")
  (unless num (setq num 1))
  ;; web-mode-forward-sexp is assigned to forward-sexp-function
  ;; it's buggy in web-mode v11, here is the workaround
  (let ((backup-forward-sexp-function forward-sexp-function))
    (if (= (html-get-tag) 0)
        (sgml-skip-tag-forward num)
      (sgml-skip-tag-backward num))))

Uso: Mx html-jump , funciona en cualquier modo principal relacionado con html (modo php, modo xml, modo web, modo nxml …)

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top

web tasarım