入力中のDOuble CApitalsの修正


23

私は少し遅い小指があります。私の他の指がタイピングでますます速くなるにつれて、私の小指は追いつくことができません。これにより、最初の単語が2つの大文字で始まる文を入力することがよくあります。以下に簡単な例を示します。

THere's nothing in there. DEfinitely not a body.

通常、私がすることはヒットですM-b M-c(すぐにそれを見つけたと仮定します)が、それには少しうんざりしています。

Emacsにこれを自動的に修正させるにはどうすればよいですか?

つまり、2つの大文字で始まり、少なくとも1つの小文字が続く単語を入力したときにEmacsが検出し、それを自動的に修正するようにします。

回答:


19

DOuble CApitalsをシングルキャピタルに変換する関数を次に示します。私はもともとそれをpost-self-insert-hookに追加することを提案していましたが、本当に必要なときにのみそのフックに追加できるように、以下は栄光マイナーモードのオプションです:

(defun dcaps-to-scaps ()
  "Convert word in DOuble CApitals to Single Capitals."
  (interactive)
  (and (= ?w (char-syntax (char-before)))
       (save-excursion
         (and (if (called-interactively-p)
                  (skip-syntax-backward "w")
                (= -3 (skip-syntax-backward "w")))
              (let (case-fold-search)
                (looking-at "\\b[[:upper:]]\\{2\\}[[:lower:]]"))
              (capitalize-word 1)))))

(add-hook 'post-self-insert-hook #'dcaps-to-scaps nil 'local)

マイナーモードの定義:

(define-minor-mode dubcaps-mode
  "Toggle `dubcaps-mode'.  Converts words in DOuble CApitals to
Single Capitals as you type."
  :init-value nil
  :lighter (" DC")
  (if dubcaps-mode
      (add-hook 'post-self-insert-hook #'dcaps-to-scaps nil 'local)
    (remove-hook 'post-self-insert-hook #'dcaps-to-scaps 'local)))

このバージョンを使用して、価値があるもの:

  • 簡単です:手動で、またはモードフックでオン/オフするだけです。
  • キーバインディングを変更する必要がないため、他の機能が失われることはありません。

それをに追加してもpost-self-insert-hook、少なくともいくつかの単純なベンチマークによると、オーバーヘッドはほとんど存在しません。私のマシンでは、おもしろいほど単純なフォームとdcaps-to-scaps関数をそれぞれ10,000回繰り返して取得しています。

(benchmark-run-compiled 10000 (+ 1 1))          ; => .001 to .003 -ish
(benchmark-run-compiled 10000 (dcaps-to-scaps)) ; => .003 to .006 -ish

そのため、はい、1 + 1を追加するよりも遅くなりますが、絶対的には気付かないでしょう。


を使用することもできますがlooking-at-p、これは一致データをまったく設定しません(ここでは必要ないか使用しないので問題ありません)。
YoungFrog

さらにいくつかの発言は、(私が貢献したいので、私はあなたの答えを好む; p)は、ほとんど重要でない:の使用はforward-wordとうまく動作しませんsubword-mode使用して、(char-syntax (char-before))(私は推測)構文クラスのプロパティとセット無視します(代替ソリューションを:(syntax-after (1- (point))) 、そして(最後になりましたが重要ではありませんが)正規表現はアクセント付き文字を見つけません(たとえば、フランス語で "ÉMincer")
YoungFrog

@YoungFrog:このforward-word問題に対処するために更新され、アクセント付きの大文字に対処するために正規表現を変更しました。
ダン

好む理由があるandの上にwhenまず第一に、特には、?
クレメント

@Clément:andは短絡しているため、ロジックは次のように機能しwhenます。どちらを使用するかについてのベストプラクティスがあるかどうかはわかりませんが、このサイトでは良い質問になると思われます(とにかく賛成です)。
ダン

8

私の好みは、普通self-insert-commandがすることに加えてもっとする新しい機能を単に作成することです。

いくつかの理由があります。

  • どのメジャーモードでこの自動修正機能を使用するかをより細かく制御します。このユースケースでorg-modetext-mode、などのテキストのみのモードにすることができます。
  • 質問で要求された修正の種類については、ユーザーは通常、単語の後にを押すSPCか、RETまたは.キーを押します。そのため、次のようなものを使用post-self-insert-hookするのはやり過ぎかもしれません。キーを押すたびに追加の処理を行います。

そのため、以下に提案するソリューションは、この関数をSPCキー入力のみでバインドしますorg-mode-map(単語が行の最後の単語になる可能性があるコーナーケースを無視します)。必要に応じて、ユーザーは同様のラッパー関数をより多くのキーにバインドできます。

(defun space-plus-more ()
  (interactive)
  (save-excursion
    (backward-word 1)
    (let ((case-fold-search))
      (when (looking-at-p "[A-Z]\\{2\\}.*?[a-z]+.*?\\b")
        (capitalize-word 1))))
  (self-insert-command 1))

(define-key org-mode-map (kbd "<SPC>") #'space-plus-more)

これは興味深いelisp演習です:)

個人的には、これにバインドしたくありません。RETその場合、デフォルトのバインドを失い、org-modeおそらく他のメジャーモードも失います。しかし、学ぶために面白かったeltthis-command-keys-vector

(defun my/fix-double-caps ()
  (interactive)
  (save-excursion
    (backward-word 1)
    (let ((case-fold-search))
      (when (looking-at-p "[A-Z]\\{2\\}.*?[a-z]+.*?\\b")
        (capitalize-word 1))))
  (if (eq 13 (elt (this-command-keys-vector) 0)) ; detect RET
      (newline)
    (self-insert-command 1)))

(let ((maps-list (list org-mode-map
                       text-mode-map))
      (keys-list (list "<SPC>" "<RET>" ".")))
  (dolist (map maps-list)
    (dolist (key keys-list)
      (define-key map (kbd key) #'my/fix-double-caps))))

そうそう、テキスト派生モードに制限することは間違いなく良い考えです。:)
マラバルバ

@Malabarba prog-modeから派生したモードの文字列でこの動作をしたくないですか?
YoungFrog

@YoungFrogは確かですが、それが実際に文字列内にあることを確認する必要があります。そうでなければ、邪魔になります。
マラバルバ

0

たぶん、この答えはあなたが期待している解決策を提供しないかもしれません(あなたがタイプするときの言葉のインタラクティブな修正)、私はそのような問題と戦う私の方法を共有したいと思います。

まず、テキストを静かに変更するもの(大文字など)が好きではありません。単語を入力したい場合IBuffer、このような「修正」は間違った方法だと思います)、次の2つのことをお勧めします。

まず、機能「スティッキーキー」を有効にしてみてください。最初は奇妙に見えるかもしれませんが、私はいつもそれを使用しています。この機能は、OS /デスクトップ環境レベルで利用できますが、Emacsのものではありません。この機能を有効にする⇧ Shiftと、最初にを押して から、大文字にする別のキーを押します。この方法では、問題が発生することさえありません。この連続的なアプローチでは、1文字のみが大文字になります。また、手が⇧ Shiftキーを保持するために必要な作業も削減されます。今はタイプしやすいと思います。

第二に、⇧ Shift必要に応じてキーを通常どおり使用(保持)できるようになりましたが、Fix WordというEmacsパッケージを提案したいと思います。「スティッキーキー」が気に入らなくても、単語を正しい形式に簡単に修正できます。また、カーソルを無駄に動かすことなく、複数の単語を連続して修正できます。それを試してみてください、私はいつもそれを使用します。(いくつかの単語を入力し、大文字にする必要がある単語が途中にある場合、物事を修正することは依然として困難です。)

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