dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

nxml-mode-expansions.el (4167B)


      1 ;;; nxml-mode-expansions.el --- Nxml-specific expansions for expand-region  -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2012-2023  Free Software Foundation, Inc
      4 
      5 ;; Author: Ivan Andrus
      6 ;; Based on js-mode-expansions by: Magnar Sveen <magnars@gmail.com>
      7 ;; Keywords: marking region
      8 
      9 ;; This program is free software; you can redistribute it and/or modify
     10 ;; it under the terms of the GNU General Public License as published by
     11 ;; the Free Software Foundation, either version 3 of the License, or
     12 ;; (at your option) any later version.
     13 
     14 ;; This program is distributed in the hope that it will be useful,
     15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 ;; GNU General Public License for more details.
     18 
     19 ;; You should have received a copy of the GNU General Public License
     20 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 ;;; Commentary:
     23 
     24 ;; Feel free to contribute any other expansions for Nxml at
     25 ;;
     26 ;;     https://github.com/magnars/expand-region.el
     27 
     28 ;;; Code:
     29 
     30 (require 'cl-lib)
     31 (require 'expand-region-core)
     32 (require 'html-mode-expansions)
     33 (require 'nxml-mode)
     34 
     35 (defun er/mark-nxml-tag ()
     36   "Marks one nxml element e.g. <p>"
     37   (interactive)
     38   (cond ((looking-at "<")
     39          (nxml-mark-token-after))
     40         ((er/looking-back-exact ">")
     41          (backward-char 1)
     42          (nxml-mark-token-after))
     43         ((er/looking-back-max "<[^<>]*" 1000)
     44          (nxml-mark-token-after))))
     45 
     46 (defun er/mark-nxml-element ()
     47   "Marks one nxml element e.g. <p>...</p>"
     48   (interactive)
     49   (if (not (looking-at "<[^/]"))
     50       (er/mark-nxml-containing-element)
     51     (set-mark (point))
     52     (nxml-forward-element)
     53     (exchange-point-and-mark)))
     54 
     55 (defun er/mark-nxml-containing-element ()
     56   "Marks one nxml element, but always e.g. <p>...</p>"
     57   (interactive)
     58   (nxml-up-element)
     59   (set-mark (point))
     60   (nxml-backward-element))
     61 
     62 (defun er/mark-nxml-inside-element ()
     63   "Marks the inside Nxml statement, eg. <p>...</p>"
     64   (interactive)
     65   (let ((nxml-sexp-element-flag nil))
     66     (nxml-up-element)
     67     (nxml-forward-balanced-item -1)
     68     (set-mark (point))
     69     (nxml-backward-up-element)
     70     (nxml-forward-balanced-item 1)))
     71 
     72 (defun er/inside-nxml-attribute-string? ()
     73   "Returns the attribute from `xmltok-attributes' array that
     74 point is in, or otherwise nil"
     75   (save-excursion 
     76     (forward-char 1)
     77     (nxml-token-before))
     78   (cl-find-if (lambda (att)
     79 		(and (<= (xmltok-attribute-value-start att) (point))
     80 		     (>= (xmltok-attribute-value-end att) (point))))
     81 	      xmltok-attributes))
     82 
     83 (defun er/mark-nxml-attribute-inner-string ()
     84   "Marks an attribute string"
     85   (interactive)
     86   (let ((attr (er/inside-nxml-attribute-string?)))
     87     (when attr
     88       (set-mark (xmltok-attribute-value-start attr))
     89       (goto-char (xmltok-attribute-value-end attr))
     90       (exchange-point-and-mark))))
     91 
     92 (defun er/mark-nxml-attribute-string ()
     93   "Marks an attribute string inside quotes."
     94   (interactive)
     95   (let ((attr (er/inside-nxml-attribute-string?)))
     96     (when attr      
     97       (set-mark (1- (xmltok-attribute-value-start attr)))
     98       (goto-char (1+ (xmltok-attribute-value-end attr)))
     99       (exchange-point-and-mark))))
    100 
    101 (defun er/add-nxml-mode-expansions ()
    102   "Adds Nxml-specific expansions for buffers in nxml-mode"
    103   (interactive)
    104   (set (make-local-variable 'er/try-expand-list)
    105        (append
    106         '(nxml-mark-paragraph
    107           ;; nxml-mark-token-after ;; Marks the current tag, etc.  It's a bit schizophrenic
    108           er/mark-nxml-tag
    109           er/mark-nxml-inside-element
    110           er/mark-nxml-element
    111           er/mark-nxml-containing-element
    112           er/mark-nxml-attribute-string
    113           er/mark-nxml-attribute-inner-string
    114           ;; Steal from html-mode-expansions
    115           er/mark-html-attribute)
    116         ;; some normal marks are more hindrance than help:
    117         (remove 'er/mark-method-call
    118                 (remove 'er/mark-symbol-with-prefix
    119                         (remove 'er/mark-symbol er/try-expand-list))))))
    120 
    121 (er/enable-mode-expansions 'nxml-mode #'er/add-nxml-mode-expansions)
    122 
    123 (provide 'nxml-mode-expansions)
    124 
    125 ;; nxml-mode-expansions.el ends here