何もしなかった場合でも、フィル段落に変更済みのマークを付ける


11

fill-paragraphコマンドを実行しても効果がない場合(つまり、段落が既に入力されている場合)でも、を呼び出すと、バッファーは常に変更済みとしてマークされます。また、空の取り消し可能なアクションが作成されます(で簡単に検出されますundo-tree-mode)。インデントコマンドなど、変更を加える可能性のある他のコマンドは、バッファを変更済みとしてマークしたり、何も変更されていない場合に取り消し可能なアクションを作成したりしません。fill-paragraph変更されたバッファにマークを付けて、実際に何かを変更した場合にのみ、取り消し可能なアクションを作成する方法はありますか?


私はこれが正しいとM-qは思いません-少なくとも私のテストから、デフォルトで変更されたバッファにマークを付けません。どのモードを使用していますか?モードがfill-paragraph何らかの方法で上書きされていると思います。
shosti 2014

@shosti基本モードを使用しています。段落は(適切に記入された場合)1行以上でなければなりません。
リリー・チョン

ああ、わかりました。
shosti 2014

回答:


2

これは新しいEmacsen(v.26以降)で修正されていることに注意してください。


10

問題は、段落が分割されている間fill-paragraph(またはfill-region-as-paragraph)が改行を削除して再挿入することです。行が1つしかない場合、バッファは変更されません。元に戻すリストで何もしないのは、fill-paragraph改行を削除して再挿入することだけです。

これを回避するのは簡単ではありません。以下はかなり悪いハックであり、大きなバッファに対しては非常に非効率的ですが、おそらくあなたにとってはうまくいきます。コマンドは同じ動作でfill-paragraphM-q)を模倣しますが、呼び出す前にバッファーの内容を保存し、その後、内容が同じままの場合、変更前の変更状態と元に戻すリストを復元します。これを行うには、バッファの内容のコピー(実際には2つ)が必要なので、実際には、これは非常に非効率的です。:-)

(defun my/fill-paragraph (&optional justify region)
  (interactive (progn
                 (barf-if-buffer-read-only)
                 (list (if current-prefix-arg 'full) t)))
  (let ((old-text (buffer-string))
        (old-modified (buffer-modified-p))
        (old-undo-list buffer-undo-list))
    (fill-paragraph justify region)
    (when (equal old-text (buffer-string))
      (setq buffer-undo-list old-undo-list)
      (set-buffer-modified-p old-modified))))

これをにバインドできM-qます。


1
はい、これは長い間苦痛でした。;-)これに対する修正が以前に要求されていたかどうか(私は覚えていません)かどうか疑問に思います。それはそうだったようだ。
2014

うーん。バッファ全体をチェックする必要がないより良い解決策があるかどうか疑問に思います-おそらくそれは選択された段落のみを何らかの方法でチェックできるでしょうか?
リリーチョン

fill-paragraphさまざまなケースを区別します。つまり、アクティブな領域、既存のfill-paragraph関数などによって動作が異なります。実際に変更されるバッファーの部分を特定するには、その動作を複製する必要があります。可能ですが、トリッキーです。:-)
JorgenSchäfer2014

@Drew昨年、メーリングリストで長い議論がありました:bug#13949:24.3.50; 'fill-paragraph'は常に変更されたバッファーを置く必要はありません
dkim

@dkim:はい、今覚えています。そして、これからは何も生まれませんでした...
2014年

1

遅い答えですが、テキストが変更されない場合にバッファを変更しない単純なバージョンを次に示します。

(defun my-fill-paragraph (&optional justify region)
  "Fill paragraph, but don't modify the buffer if filling doesn't
change the text.  See `fill-paragraph' for details."
  (interactive (progn
                 (barf-if-buffer-read-only)
                 (list (if current-prefix-arg 'full) t)))
  (if (buffer-modified-p)
      ;; if modified: use standard fill-paragraph
      (fill-paragraph justify region)
    ;; if unmodified: get a candidate filled version
    (save-excursion
      (let* ((col fill-column)
             (beg (progn (forward-paragraph -1)
                         (skip-syntax-forward " >")
                         (point)))
             (end (progn (forward-paragraph 1)
                         (skip-syntax-backward " >")
                         (point)))
             (old (buffer-substring-no-properties beg end))
             (new (with-temp-buffer
                    (setq fill-column col)
                    (insert old)
                    (fill-paragraph justify region)
                    (buffer-string))))
        ;; don't modify unless the old and new versions differ
        (unless (string-equal old new)
          (delete-region beg end)
          (insert new))))))

これは、@JorgenSchäferの回答のいくつかのアイデアを採用していますが、現在の段落でのみ機能し、空白で区切られた単純な方法でのみ機能します(内部の複雑化に関する@JorgenSchäferの回答に関するコメントを参照)。

これは私自身の目的に関連する唯一のユースケース(つまり、「通常の」散文でのインタラクティブな使用、アクティブな領域がない)に関するものなので、誰かがそれを使用したり、より複雑なユースケースで改善したい場合に備えて投稿します。 。

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