とある事情で DocBook を使い始めたのだけれど、nxml-mode *1 で auto-complete *2 してみたくてでっち上げてみた。
defadvice で無理矢理やってるので、多分、よい子は真似してはいけないと思う。
;;;
;;; ac-source-rng-nxml
;;;
;;; usage:
;;; (require 'nxml-mode)
;;; (require 'ac-source-rng-nxml)
;;; (add-hook 'nxml-mode-hook
;;; (lambda ()
;;; (make-local-variable ac-sources-prefix-function)
;;; (setq
;;; ac-sources-prefix-function 'ac-source-rng-nxml-prefix
;;; ac-sources '(ac-source-rng-nxml))))
(defvar ac-source-rng-nxml-candidates nil)
(defun ac-source-rng-nxml-prefix ()
(or (ac-sources-prefix-default)
(and (looking-back "[[:blank:]]")
(1- (point)))))
(defadvice rng-complete-before-point (around
ac-source-rng-nxml-complete-advice
disable)
(setq ad-return-value
(or ac-source-rng-nxml-candidates
(progn
(setq ac-source-rng-nxml-candidates
(mapcar
(lambda (x) (cdr x))
rng-complete-target-names))
nil))))
(defun ac-source-rng-nxml-do-complete ()
(ad-enable-advice 'rng-complete-before-point
'around 'ac-source-rng-nxml-complete-advice)
(ad-activate 'rng-complete-before-point)
(rng-complete)
(ad-disable-advice 'rng-complete-before-point
'around 'ac-source-rng-nxml-complete-advice)
(ad-activate 'rng-complete-before-point))
(defun ac-source-rng-nxml-get-prefix (str)
(and (string-match "^\\([^[:alpha:]]+\\)" str)
(match-string-no-properties 1 str)))
(defvar ac-source-rng-nxml
`((init
. (lambda ()
(setq ac-source-rng-nxml-candidates nil)
(ac-source-rng-nxml-do-complete)))
(candidates
. (lambda ()
(let* ((prefix (ac-source-rng-nxml-get-prefix ac-target))
(kw (substring ac-target (length prefix)))
(kwlen (length kw)))
(loop for c in ac-source-rng-nxml-candidates
if (eq (compare-strings kw 0 nil
c 0 kwlen)
t)
collect (concat prefix c)))))
(action
. (lambda ()
(let* ((prefix (ac-source-rng-nxml-get-prefix ac-target))
(kw (substring ac-target (length prefix))))
(setq ac-source-rng-nxml-candidates kw)
(ac-source-rng-nxml-do-complete))))
))
(provide 'ac-source-rng-nxml)

コメントする