nxml-mode extensions
unknown [Fri, 2 Mar 2012 09:56:58 +0000 (10:56 +0100)]
setup/nxml.el

index f756d1e..208e587 100644 (file)
   (hs-hide-block)
   (nxml-backward-up-element))
 
+(defun hs-nxml-hide-other ()
+  (interactive)
+  (let ((p (point)))
+    (hs-hide-all)
+    (while (progn (goto-char p) (hs-already-hidden-p))
+      (hs-nxml-enter))
+    (hs-show-block)
+    (goto-char p)
+    (recenter-top-bottom)))
+
 (define-key nxml-mode-map (kbd "\C-c <left>") 'hs-nxml-leave)
 (define-key nxml-mode-map (kbd "\C-c <right>") 'hs-nxml-enter)
+(define-key nxml-mode-map (kbd "\C-c @ o") 'hs-nxml-hide-other)
+
+(defun nxml-complete-and-autoclose-element (use-region)
+  (interactive "P")
+  (let* ((start (if use-region (setq start (set-marker (make-marker) (region-beginning)))))
+         (end (setq use-region (set-marker (make-marker) (region-end))))
+         (beg (and start (= (point) start))))
+  (save-excursion
+    (insert " "))
+  (nxml-complete)
+  (let ((name (xmltok-start-tag-local-name)))
+    (delete-char 1)
+    (if (and start end)
+        (progn
+          (if (not beg)
+              (progn
+                (delete-char (- (1+ (length name))))
+                (goto-char start)
+                (insert "<" name ">"))
+            (insert ">"))
+          (goto-char end))
+      (insert ">"))
+    (save-excursion
+      (insert "</" name ">")))))
+
+(define-key nxml-mode-map (kbd "\C-c ." ) 'nxml-complete-and-autoclose-element)
+(define-key nxml-mode-map (kbd "\C-c\C-c") 'recompile)
+
+(defconst nxml-docbook-common-elements
+  '(("section" . ("para" "itemizedlist" "variablelist" "section" "bridgehead" "task" "procedure"))
+    ("para" . ("emphasis" "code" "replaceable"))
+    ("emphasis" . ("code"))
+    ("itemizedlist" . ("listitem"))
+    ("orderedlist" . ("listitem"))
+    ("variablelist" . ("varlistentry"))
+    ("varlistentry" . ("term" "listitem"))
+    ("term" . ("emphasis" "code"))
+    ("listitem" . ("para" "itemizedlist"))
+    ("task" . ("tasksummary" "procedure"))
+    ("tasksummary" . ("para"))
+    ("procedure" . ("step"))
+    ("step" . ("para" "procedure"))
+    ("mathphrase" . ("replaceable" "superscript" "subscript"))
+    ("title" . ("code" "replaceable"))
+    ("literallayout" . ("replaceable" "emphasis" "code"))))
+
+(defvar nxml-docbook-last-common-element nil)
+
+(defun nxml-docbook-make-common-element ()
+  (interactive)
+  (let ((start (set-marker (make-marker) (point)))
+        (end (set-marker (make-marker) (point)))
+        do-region)
+    (when (or (region-active-p)
+              (and (eq real-last-command 'nxml-docbook-make-common-element)
+                   (car nxml-docbook-last-common-element)))
+      (set-marker start (region-beginning))
+      (set-marker end (region-end))
+      (message "do-mark %s %s" start end)
+      (setq do-region t))
+    (message "cycle? %s %s" real-last-command nxml-docbook-last-common-element)
+    (when (and (eq real-last-command 'nxml-docbook-make-common-element)
+               (cdr nxml-docbook-last-common-element))
+      (delete-region (save-excursion (skip-chars-backward "^<") (1- (point))) start)
+      (delete-region end (save-excursion (skip-chars-forward "^>") (1+ (point)))))
+    (let* ((token-end (nxml-token-before)) 
+           (start-tag-end
+            (save-excursion
+              (when (and (< (point) token-end)
+                         (memq xmltok-type
+                               '(cdata-section
+                                 processing-instruction
+                                 comment
+                                 start-tag
+                                 end-tag
+                                 empty-element)))
+                (setq nxml-docbook-last-common-element nil)
+                (error "Point is inside a %s"
+                       (nxml-token-type-friendly-name xmltok-type)))
+              (nxml-scan-element-backward token-end t)))
+           (context (xmltok-start-tag-qname))
+           (elements (cdr (assoc context nxml-docbook-common-elements)))
+           (index (if (and elements
+                           (eq real-last-command 'nxml-docbook-make-common-element)
+                           (cdr nxml-docbook-last-common-element))
+                      (1+ (cdr nxml-docbook-last-common-element))
+                    0))
+           (element (and elements (nth index elements))))
+      (when (not elements)
+        (setq nxml-docbook-last-common-element nil)
+        (error "No common elements for %s" context))
+      (if element
+          (progn
+            (goto-char start)
+            (insert-before-markers "<" element ">")
+            (goto-char end)
+            (insert "</" element ">")
+            (goto-char end)
+            (setq nxml-docbook-last-common-element (cons do-region index)))
+        (setq nxml-docbook-last-common-element (cons do-region nil)))
+      (when do-region
+        (set-mark start)
+        (message  "Fiddlesticks: %s %s %s" (mark t) mark-active (region-active-p))))))
+
+(defun nxml-just-one-space-or-skip-end ()
+  (interactive)
+  (if (looking-at "</")
+      (progn
+        (skip-chars-forward "^>")
+        (forward-char 1))
+    (just-one-space)))
+
+(define-key nxml-mode-map (kbd "M-RET") 'nxml-docbook-make-common-element)
+(define-key nxml-mode-map (kbd "M-SPC") 'nxml-just-one-space-or-skip-end)
+
+(defun nxml-open-line ()
+  (interactive)
+  (open-line 1)
+  (save-excursion
+    (forward-line 1)
+    (indent-according-to-mode))
+  (newline-and-indent))
+
+(define-key nxml-mode-map (kbd "M-o") 'nxml-open-line)