現在のバッファーの内容を一時バッファーにコピーして操作する


8

現在のバッファーの内容を一時バッファーにコピーし、そのバッファーを特定のメジャーモードに設定して、その利点を活用し、必要な情報をメインロジックに戻す必要があります。

これは完全な狂気ですか?そうでない場合、これの構造は何ですか?

回答:


10

一部の情報を別のバッファにコピーしたい場合は、それ以降、バッファを個別に展開させれば、それを行うことができます

しかし、他のバッファに元のコンテンツをリアルタイムで反映させたい場合、Emacsはこれに間接バッファを提供します。間接バッファーは、元のバッファーと同じ内容(別のバッファーに変更が反映される)の別のバッファーですが、設定が異なります:異なるメジャーモード、異なるマイナーモード、異なるローカル変数、異なるポイント、異なるマーク、別の絞り込みなど

したがって、元のバッファーでの変更を追跡し、変更を元のバッファーに反映して、別のメジャーモードでバッファーの一部のビューを取得できます。まず、で間接バッファを作成しM-x clone-indirect bufferます。また、ありますclone-indirect-buffer-other-windowにバインドされているC-x 4 cC-x 4窓のプレフィックス、およびcのためのクローン)。クローンバッファで、必要な領域に絞り込みます。対象の部分を選択して実行しますC-x n nnarrow-to-region)。必要に応じてメジャーモードを変更します。

インタラクティブに使用するために、次のようなコマンドで自動化できます。

(defun edit-region-in-foo-mode (beg end)
  (interactive "@r")
  (let ((new-buffer (clone-indirect-buffer nil t)))
    (narrow-to-region beg end)
    (foo-mode)))

プログラミング用:

(defmacro with-indirect-buffer-in-foo-mode (beg end &rest body)
  `(with-current-buffer (clone-indirect-buffer nil nil)
     (narrow-to-region beg end)
     (foo-mode)
     (unwind-protect
         ,body
       (kill-buffer (current-buffer)))))

8

このようなもの:

(let ((old-buffer (current-buffer)))
  (with-temp-buffer
    (insert-buffer-substring old-buffer)
    (my-favourite-major-mode 1)
    (extract-needed-information)))

2
ほぼ正確にそれを書いていた。それを任意に呼び出すことができる必要がある場合は、それをdefunで囲みます
Jonathan Leech-Pepin 14年

よさそうですね。承認済みとしてマークするためのより良い何かが存在する場合に備えて、少し待つつもりですが、これはそれだと思います:)
2014年

私は実際にを提案していたM-x copy-to-bufferので、@ legosciaの回答を赤にしました。抽出プロセスとメジャーモードが同じである場合、機能は向上します
Nsukami _

2

@Gillesが書いたものが好きだった。@Gillesがユーザーにどのモードを使用したいかを尋ねるために書いた内容を変更しました。私が書いたものを編集して、好きなモードを提供したり、デフォルトのリストで提供されていないモードを提供できるように、読み取りの完了への呼び出しを変更したりすることもできます。

(defun edit-region-in-mode (beg end)
  "Create an indirect buffer cloned from the current buffer and
  narrowed to the highlighted region. The cloned indirect buffer
  will have org-mode active. Changes to the indirect buffer will
  be updated in real time in the originating buffer. This is
  useful, for instance, when you are in a non-org-mode mode and
  want to edit table data or in a non-emacs-lisp mode and want to
  write some elisp utilizing code formatting and highlighting."
  (interactive "@r")
  (let ((new-buffer (clone-indirect-buffer nil t)))
    (narrow-to-region beg end)
    (funcall
     (intern
      (completing-read
       "Choose the mode you want to use when editing the highlighted region: "
       '(org-mode emacs-lisp-mode lisp-mode haskell-mode julia-mode
          python-mode mathematica-mode matlab-mode c++-mode))))))

1

同様のユースケースでmodi/switch-to-scratch-and-back、バッファーFILEと、FILEバッファーと同じメジャーモードを持つ* scratch *バッファーをすばやく切り替えることができるelisp関数を記述しました。上記のハイパーリンクされた関数は、既存のemacs SEの質問に導きます。

この関数の使用方法は次のとおりです。

  • 既存のバッファーをコピーするラッパー関数を作成し、同じメジャーモードで* scratch *バッファーを作成して、コピーした内容を貼り付けます。

これはラッパー関数の例です

(defun copy-current-buffer-to-scratch ()
 "Copied the current buffer, open scratch, paste it there."
  (interactive)
  (kill-ring-save (point-min) (point-max))
  (modi/switch-to-scratch-and-back)
  (yank))
  • これcopy-current-buffer-to-scratchで、必要に応じてこれをキーにバインドできます。これを実行すると、作業バッファーの内容を含む* scratch *バッファーが得られます。
  • スクラッチバッファーでの編集に満足したら、手動で必要なセクションを元のバッファーにコピーする必要があります。

これは、あなたがやりたいことをするためのもう一つの方法です。ただし、@ Gillesのソリューションで説明されている間接バッファを使用することもできます。この方法は、安定したソリューションに到達するまで、元のバッファーに誤って保存するリスクを冒さずに一時バッファーで大量の編集を行う必要がある場合に役立ちます。

使用例としては、emacs initに保存する前に実験的なelisp関数を試してみることです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.