Emacsモードの征服:DIYハンドブック





プログラマーは2つのカテゴリーに分けられます。

1)すでにVimを使用している人。

2)すでにEmacsを使用している人。

3)まだ使用していない人。



まえがき



どういうわけか、Emacsを2回目にするというアイデアが生まれました。これは、これがさまざまなゲームを備えた何らかの誤ったエディターであることを確認しますが、テキストを操作する機能ではありません。 そしてその上にとどまりました。



追加モード



Emacsには、機能を追加するさまざまなモードがあります。 原則として、機能が必要な場合、.elファイル(Emacs Lisp)で構成されるパッケージとしてダウンロードされ、エディターの読み込みを担当する組み込みの.elファイルに既に接続されています。



最初はすべて使用すると便利ですが、その後何かを見逃し始め、独自の機能を追加することを検討する必要があります。



キーボードショートカットを1つ追加する必要がある場合は、任意の構成ファイルで直接実行できます。 最初は機能し、完全な喜びをもたらしますが、すぐに機能し始めます。一部のキーは他のキーに、別のキーは最初のキーに、別のキーは第2のキーに登ります。 すべてをやり直すか、何かを拒否する必要があります。



Emacsを長く使用すればするほど、それが好きになります。 そのため、やる気はすぐに来ました。「フォーラムへの回答を自動的にフォーマットするためのツールを備えた何らかのボックスが必要です」というタスクが登場しました。



解決方法(当然、Emacsをオフにせずに)



答えは簡単です。独自のモードを追加する必要があります。必要に応じてオンにし、反対の場合は無効にすることができます。



リバースエンジニアリング



当然、モードを追加するには、多くのドキュメントを読んで、他のモードがどのように作られているかを確認し、Lispを調べ、Emacsの動作中に誤って混乱させないようにする必要があります。



ドキュメントの検索が開始されました。 まず、チュートリアル記事...記事はありません。 次に、モードの例...例は、不必要な構造で満たされています。 次に、ドキュメント...を読んで数日間チェックします。 その後、完成したモード...何も明確ではない、あなたはLispを学ぶ必要があります。



円は閉じています。 すべてを一度にたくさん使わなければなりませんでした。



最初のアプローチ



情報:



1)モードはメイン(メジャー)およびセカンダリ(マイナー)です。

2)モードは既存のモードから継承できます。

3)メインモードは1つしか選択できませんが、サイドはたくさんあります。

4)多くの副作用をメインモードに追加できます。



最初に、最も最小限のモードが作成されました。
;; My test mode (define-derived-mode test-mode python-mode "Test" "Major mode for editing Test source text." (set (make-local-variable 'test-variable) "Test variable value")) (add-to-list 'auto-mode-alist (cons "\\.test\\'" 'test-mode)) (provide 'test-mode)
      
      





このテキストを含むtest-mode.elファイルは便利なフォルダーに配置され、モードは他の初期化ファイルのどこかに接続されます。



 (add-to-list 'load-path "~/.emacs.d/packages/modes/test-mode/") (require 'test-mode)
      
      







内容説明:
Pythonモードからすべてを継承するモードを作成します。



 (define-derived-mode test-mode python-mode
      
      





この行は、モード名のストリップに表示されます。



  "Test"
      
      





これは、モードのヘルプを開いたときに表示されるコメントです。



 "Major mode for editing Test source text."
      
      





これは、モードに入ると作成され、終了すると破棄される変数です。



  (set (make-local-variable 'test-variable) "Test variable value"))
      
      





これにより、拡張子.testのファイルにこのモードが自動的に割り当てられます。



 (add-to-list 'auto-mode-alist (cons "\\.test\\'" 'test-mode))
      
      





これはモードを共有し、他のファイルから接続できるようにします:



 (provide 'test-mode)
      
      







最小限で終了しました。



すべてを使用する方法は?



さて、詳細を継承して再定義することができます。 たとえば、キーボードショートカットの1つが別のショートカットに置き換えられるか、1つの色で塗りつぶされて別の色で塗り替えられる構文の単語に置き換えられます。



関数を追加し、それにキーを割り当てます。
 ;; My test function mode (defun test-func-hello() (interactive) (message "Pressed Cc 1, test-func-hello()")) (defvar test-func-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "Cc 1") 'test-func-hello) map) "Keymap for `test-func-mode'.") (define-derived-mode test-func-mode python-mode "TestFunc" "Major mode for editing TestFunc source text." (set (make-local-variable 'test-func-variable) "TestFunc variable value")) (add-to-list 'auto-mode-alist (cons "\\.testfunc\\'" 'test-func-mode)) (provide 'test-func-mode)
      
      







ここでは、モード名と、自動的に含まれるファイル拡張子のみが変更されます。 そして、機能とキーの表示という2つのことを追加します。



file.testfuncファイルを作成してEmacsで開くと、TestFuncモードが設定されます。 モードはPythonから継承されるため、構文の強調表示などがあります。 しかし、Ctrl + c + 1を押すと、この組み合わせが押されたというメッセージと、機能した関数の名前が表示されます。



ここで、モードtest-modeまたはtest-func-modeの名前でyasnippetディレクトリにモードディレクトリを作成し、通常のPythonのものとは分離され、重複する場合にのみ互いに​​補完するスニペットを挿入できます。



最小限のバインディング



しばらくすると、これはすべて良いことであることに気づきますが、正しいモードで座っているときは、そのモードにとどまる必要があります。 また、現在のモードとそのチップは、最初に継承されたモードと一致しない場合があります。



したがって、現在のモードに機能を追加するには、サイドモード(小規模またはマイナー)が役立ちます。 メインモードと同じものがすべてありますが、現在のモードが処理済みのデータを強制的にスローしたり、どこかに緊急に切り替えたりすることはありません。



関数を横に並べてメインモードをリメイクします。
 ;; My test minor mode (defun test-minor-hello() (interactive) (message "Pressed Cc 1, test-minor-hello()")) (defvar test-minor-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "Cc 1") 'test-minor-hello) map) "Keymap for `test-minor-mode'.") (define-minor-mode test-minor-mode "Minor mode for editing TestMinor text." nil " TestMinor" nil (if test-minor-mode (set (make-local-variable 'test-minor-variable) "TestMinor variable value") (makunbound 'test-minor-variable))) (add-to-list 'auto-mode-alist (cons "\\.testminor\\'" 'test-minor-mode)) (provide 'test-minor-mode)
      
      







ご覧のように、ここではすべてが主政権を作成するときほど楽しいものではありません。 いくつかの奇妙なデザインがありましたが、まったく明確ではありませんでした。



簡単に説明すると、サイドモードは切り替え可能なデザインです。 オンまたはオフにできるため、すでにオンになっているときに再びオンにならないように、その状態を判別できる必要があります。 さらに、メインモードとは異なり、変数をクリーンアップしないため、オフになったときに機能するブランチが必要です。



複雑な方法で説明する場合、Emacsにはそのようなモードで動作する特定の動作があります。 それらを改善することはできますが、手遅れです。



小さなモードについて覚えておくべき主なことは、上部に4つの変数があることです。 そこで、これを誤って見逃してしまう可能性があります。彼は、モードがオンになったときに実行されるべき式を、最後の変数の代わりに置き換えますが、これは何らかの方法でそれを報告しません-式が機能しない理由を理解するために2時間ドキュメントに座っています。



問題の解決策



最終オプション
 ;; Forum minor mode (defun forum-minor-wrap-code() "Wrap selection to <code></code> tags." (interactive) (if (not (mark)) (set-mark (point))) (narrow-to-region (mark) (point)) (goto-char (point-min)) (insert "<code>") (goto-char (point-max)) (insert "</code>") (set-mark (point-min)) (widen)) (defun forum-minor-wrap-quote() "Wrap selection to <quote></quote> tags." (interactive) (if (not (mark)) (set-mark (point))) (narrow-to-region (mark) (point)) (goto-char (point-min)) (insert "<quote>") (goto-char (point-max)) (insert "</quote>") (set-mark (point-min)) (widen)) (defvar forum-minor-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "Cc 1") 'forum-minor-wrap-quote) (define-key map (kbd "Cc 2") 'forum-minor-wrap-code) map) "Keymap for `forum-minor-mode'.") (define-minor-mode forum-minor-mode "Minor mode for editing text for `http://forum.example.ru'. \\{forum-minor-mode-map}" nil " Forum" nil (if forum-minor-mode (progn (set (make-local-variable 'forum-minor-nick) "Nick") (add-to-list 'yas-extra-modes 'forum-minor-mode) (yas-minor-mode t)) (progn (makunbound 'forum-minor-nick) (set 'yas-extra-modes (delete 'forum-minor-mode yas-extra-modes))))) (add-to-list 'auto-mode-alist (cons "\\.forum\\'" 'forum-minor-mode)) (provide 'forum-minor-mode)
      
      







ここで、選択したテキストを<quote> </ quote>および<code> </ code>タグで囲むための関数がいくつか追加されました。 さらに、メインモードのみを検出するため、yasnippetにモードを追加する必要がありました。



ここで、モードはファイルに添付するか、Alt + x +名前を使用して手動で起動するか、フックを介して別のモードに添付できることに注意してください。



Pythonへの参加は次のようになります。



 (add-hook 'python-mode-hook 'forum-minor-mode)
      
      





これで、より高度なテキスト処理機能を作成できます。 モードは、残りの設定に影響を与えることなく追加および削除できます。



おわりに



初めてEmacsをインストールしたとき、私はそれを理解していませんでした;(古代のフォントのために)複雑で、不快で、いように見えました。 さて、もう一度言いますと、私は彼を認めませんでした。 非常に多くの素晴らしいアプリケーションであることが判明し、その利便性はスケール外れです。



彼の前に、私はVimを使用しました。それは良くて面白かったのですが、ニーモニックを理解するために何かを読まなければならなかったので、その設定はどういうわけか異なっていました。 このため、私は何も学ぶ必要がないので、長い間kwriteでプログラミングしました。また、構文は適切に調整されています。



しかし、インストールしてEmacsにマージしただけで、そのパワーとシンプルさを実感しました(もちろん、当分の間、20 Mbでファイルを開こうとするまで)。



PS:私のコードやアプローチに何か問題がある場合-まあ。



All Articles