ac-jsx(auto-complete for JSX)を書いてみた
jsx --complete で tmpfile or stdin からソースを読めるようにした - Islands in the byte stream
と jsx.vimを見て、それとなく書いてみました。
仕様とか全然わからなかったんですが、出力を見たら JSONっぽかったので
JSONとして出力を解釈しています。ハマったところは columnの指定で、
TABを 1文字として数える必要があったところでしょうか。
コード
;;; ac-jsx.el --- auto-complete for JSX ;; Copyright (C) 2012 by Syohei YOSHIDA ;; Author: Syohei YOSHIDA <syohex@gmail.com> ;; URL: ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see <http://www.gnu.org/licenses/>. ;;; Commentary: ;;; Code: (require 'json) (defgroup ac-jsx nil "auto-complete for jsx" :group 'jsx :prefix "ac-jsx:") (defvar ac-jsx:command (or (and (boundp 'jsx-cmd) jsx-cmd) "jsx")) (defun ac-jsx:complete-command (tempfile) (let ((file (buffer-file-name))) (format "%s --input-filename %s --complete %d:%d '%s'" ac-jsx:command file (line-number-at-pos) (ac-jsx:current-char-number) tempfile))) (defun ac-jsx:current-char-number () (length (buffer-substring-no-properties (line-beginning-position) (1+ (point))))) (defun ac-jsx:write-temp-file () (let ((temp (concat (make-temp-name "jsx") ".jsx"))) (let ((str (buffer-substring-no-properties (point-min) (point-max)))) (with-temp-file temp (insert str)) (expand-file-name temp)))) (defun ac-jsx:completion-at-point () (let* ((tempfile (ac-jsx:write-temp-file)) (cmd (ac-jsx:complete-command tempfile))) (with-temp-buffer (let (retval) (unwind-protect (setq retval (call-process-shell-command cmd nil t nil)) (delete-file tempfile)) (unless (zerop retval) (error (format "Failed: '%s'(ret=%d)" cmd retval)))) (json-read-from-string (buffer-substring-no-properties (point-min) (point-max)))))) (defvar ac-source-jsx '((candidates . ac-jsx:completion-at-point) (prefix . "\\(.*\\)") (requires . 0)) "Source for JSX completion") (add-hook 'jsx-mode-hook (lambda () (add-to-list 'ac-sources 'ac-source-jsx))) (provide 'ac-jsx) ;;; ac-jsx.el ends here
設定
;; jsx-mode (add-to-list 'auto-mode-alist '("\\.jsx\\'" . jsx-mode)) (autoload 'jsx-mode "jsx-mode" "JSX mode" t) ;; auto-complete (require 'auto-complete-config) (ac-config-default) (global-auto-complete-mode t) (global-set-key (kbd "C-M-i") 'auto-complete) (add-hook 'jsx-mode-hook (lambda () (auto-complete-mode)))
おわりに
処理系側で補完機能があると、エディタの補完拡張が楽に書けて
いいですね。Clangはそんな感じなんですけど、GCCも標準でそんな
風になればいいかなと思います。(m2ymさんの GCCSenseなんかは
ありますけど、標準ではないので。)