はじめに
自分が利用しているtc.elを利用して実現している独自の補完環境,
tc-ac-completeについて紹介します。
仕組み
実は,tc.elには元々補完の機能が実装されていました。
しかし,バグか何か分からないのですが,動作するところは私は見たことがありません。
そして,15年前当時,Emacsではauto-complete.elによる補完がよく利用されていて,
tc.elに付属のtc-complete.elの変換関数だけを利用して,auto-complete.elのインターフェースを利用して,
補完しようとしたものになります。
ただ,auto-complete.elも既にちゃんとメンテナンスされているとはいい難い状態であり,
ここで紹介する内容もいつまで役に立つかは分からないといった状態です。
セットアップ方法
tc-ac-complete.elの配置
githubのtc-ac-completeからtc-ac-complete.elをダウンロードします。
次に,load-pathの通っているフォルダにこのファイルを配置します。
20日目の記事の設定ファイルだと,
~/.emacs.d/site-lisp/フォルダに配置すると有効になるかと思います。
そして,auto-completeパッケージをインストールします。
M-x package-installを使ってもいいですし,
20日目の記事の方式だと,
Markdown-modeとtcをインストールするように設定したところにauto-completeをインストールするよう
設定しておく方法もあります。
;; パッケージがインストールされてなければ自動で追加するおまじない (require 'cl-lib) (defvar installing-package-list '(auto-complete popup markdown-mode tc)) (let ((not-installed (cl-loop for x in installing-package-list when (not (package-installed-p x)) collect x))) (when not-installed (package-refresh-contents) (cl-dolist (pkg not-installed) (package-install pkg))))
次に,init.elには次のような設定を追加します。
; auto-completeの初期化 (require 'auto-complete-config) (ac-config-default) ;; emacs 30以上では,ac-source-abbrevがac-sources関連のコードで ;; emacs内部の仕様変更に対応できていない部分があり ;; とりあえず削除しておくというworkaroundです。 (add-hook 'auto-complete-mode-hook (lambda () (setq ac-sources (remove 'ac-source-abbrev ac-sources)))) ;; tc-ac-completeのロード (require 'tc-ac-complete) ;; テキストモード時にtc-ac-completeの補完を設定 (add-hook 'text-mode-hook (function (lambda () (setq ac-sources '(ac-source-tcode-complete ac-source-dictionary))))) ;; Markdownモード時にtc-ac-completeの補完を設定 (add-hook 'markdown-mode-hook (function (lambda () (setq ac-sources '(ac-source-tcode-complete ac-source-dictionary))))) ; auto-completeの対応を ccモードから外す (remove-hook 'c-mode-common-hook 'ac-cc-mode-setup) (setq ac-modes (delete 'objec-mode (delete 'c++-mode (delete 'cc-mode (delete 'c-mode ac-modes)))))
auto-complete.elの動かない機能を削除するのと,
必要なモード「のみ」にauto-completeが動作するようにするための
細かい設定をしています。
次に~/.tcに次のような設定をします。
;; 補完の最大候補数 (setq tcode-complete-max-candidate-count 20) ;; 補完を表示する最小フレーズ長 (setq tcode-complete-min-context-length 2) ;; 補完を表示する最大フレーズ長 (setq tcode-complete-max-context-length 20) ;; 交ぜ書き変換辞書から検索する固定長 (setq tcode-complete-mazegaki-prefix-length 3) ;; 候補を表示するまでの遅延時間(意味があるのかどうか不明) (setq tcode-complete-delay 0.5) ;; tc-ac-completeがインストールされていない時は無視 (when (fboundp 'auto-complete) (require 'tc-ac-complete) (require 'nadvice) ;; tcode-ac-complete-set-functionにオーバーライドしているけど ;; 今となっては何でこんなことをしているか不明 (defun my-tcode-ac-complete-set-function () (if (memq last-command tcode-input-command-list) (tcode-ac-complete-set))) (advice-add 'tcode-ac-complete-set-function :override #'my-tcode-ac-complete-set-function) ;; tcode-complete-add-to-dictionaryをした後ログを表示する関数 (defun my-tcode-complete-add-to-dictionary-after (beg end) (progn (deactivate-mark t) (tcode-verbose-message "補完辞書に追加しました"))) (advice-add 'tcode-complete-add-to-dictionary :after #'my-tcode-complete-add-to-dictionary-after) (global-set-key [(C c) (t) (a)] 'tcode-complete-add-to-dictionary) ; 補完辞書に追加 (global-set-key [(C c) (t) (s)] 'tcode-complete-switch-to-dictionary) ; 補完辞書表示 (global-set-key [(C c) (t) (C s)] 'tcode-complete-save-dictionary) ; 補完辞書保存 (global-set-key [(C c) (t) (r)] 'tcode-complete-reload-dictionary) ; 補完辞書読み込み ) (add-hook 'tcode-ready-hook (function (lambda () ;; auto-completeがインストールされている時のみ ;; tc-ac-complete補完のバックグラウンド処理開始 (when (fboundp 'auto-complete) (tcode-ac-candidate-start)) )))
使い方
通常
使い方といっても登録しているキーワードの候補の表示がされるので, それを選択しないならそのままT-Codeの入力方法で入力していって, 候補を選択するなら,メニューから選ぶかゴースト表示している候補については タブキーでその候補を選択できます。

キーワードの登録(キーボード操作)
今回の設定では,補完候補の登録をキーボードから登録できるようにしています。
通常のキーワードの登録は簡単です。
まずEmacsの操作でリージョン(範囲)選択をします。
で,登録しているキーボードのショートカットCtrl+c t aを入力すると
登録できます。
上記の表現はCtrl+cを押してから,t,aと順に入力することを意味します。

また,変換操作用の候補も登録可能です。
キーワードと変換後の文字列との間に半角空白文字を入れてから,
その両方が含まれるようリージョン選択し,先ほどと同じようにCtrl+c t a
する方法でOKです。

なお,ショートカットに登録していない場合は,リージョン選択した後,
M-x tcode-complete-add-to-dictionaryという操作でも同じようにキーワード登録が可能です。
キーワードの登録(補完辞書ファイルを直接編集)
補完辞書ファイルを直接編集して登録することも可能です。
tcode-data-directoyrで設定されている~/.emacs.d/tcode/フォルダの中のcomplete.dicという
ファイルが補完用の辞書ファイルになります。
ただし,次の図のように通常はメモリ用の補完用バッファから補完候補が表示されます。

また,先ほどの辞書追加は補完用バッファに登録されるため,この時点では 辞書ファイルには保存されていません。通常はEmacs終了時に自動的に保存されますが, 手動操作にてメモリ上の補完用バッファの内容を保存できます。
complete.dicファイルを編集してから辞書の再読み込みを行うとそのファイルの
編集内容が反映された辞書をメモリ上に読み込みして,その内容を元に補完することが
できます。
complete.dicファイルのフォーマットは簡単で,キーワードのみの補完の場合,
「一行が一キーワード」という形式です。
変換を伴うときは,キーワード[半角スペース]変換後文字列の形式が一行となります。
したがって,半角スペースを間に含むキーワードは登録できないことに注意が必要です。
tc-ac-completeの今後
実は,tc.elの不備をどんどん指摘して直していこうという動きがあり,
tc-complete.elのバグについても直そうとする動きがあるようです。
個人的には,tc-complete.elのユーザーインターフェースの動作はよく分かっておらず,
また,明らかに現在利用しているtc-ac-complete 環境の方が良いと思っているので,
tooro88さんが直したコードに合わせてtc-ac-complete.elも変更して利用する感じになると思います。
というかissueの中の文を見ると,機能自体omitしたいようですね。 そうなると,完全にtc-ac-complete側でコードを引き取る感じでしょうか。メンドクセ。 まぁtooro88さんがそう思うのならしょうがないですね。
tc-complete.elの補完機能のユーザーインターフェースを利用することは私としてはおそらくないですし,
動いていないコードをメンテナンスするコストを考えると,
利用していないコードを削除するのは自然な流れでしょうか。
また,そうでなくても現在のtc-ac-complete.elのコードは別のプルリクがマージされると
動かなくなるとの情報があります。まぁイシューを立ててくれるのはありがたいです。
今のtc-complete.elの状態で,一部のコードを闇で使っているなんて思う人なんていないので,
有無を言わさずomitされてても文句が言えない状態です。
まぁマージされたらそれに合わせて修正するといった対応になりそうです。
「漢直のメリットは補完」と感じさせてくれたtc-ac-completeなので,
なるべく今後も利用していきたいです。
追記: なお,色々気を使っていただいて,バグがあるユーザーインターフェースの部分にパッチを当てて,とりあえずWarning無しに一通り動かすような感じにしていただけそうです。自分が使っているところは文字入力から候補作成の部分なので,特別影響も無さそうです。
ただlast-commandのチェックをしているところはthis-commandのチェックへの変更がtc-ac-complete側で必要のようです。
さいごに
今回は,tc.elの内部関数と,Emacsの外部パッケージauto-completeを利用した補完機能について簡単に紹介しました。
自分の場合は,補完というよりどちらかというと変換機能で利用している方が多いですが, 特別な操作も必要なく候補をどんどん出してくれるので,カジュアルに何か入力したい時は楽チンです。
単語登録にキーボードのショートカットを登録しておくと,手軽にキーワードも登録できるので,
かなり便利に使えると思います。ただ,tc.el自体利用している人も少ないと思うので
実際に役に立つ人はほとんどいないかもとも思います。
プログラム言語の補完チックなので,プログラマーの人なら一番メリットを感じられるかと思います。
それではまた。