Sửa lỗi CApitals khi tôi gõ


23

Tôi có một chút hồng hào chậm. Khi các ngón tay khác của tôi ngày càng nhanh hơn khi gõ, hồng hào của tôi không thể theo kịp. Điều này thường dẫn tôi đến loại câu có từ đầu tiên bắt đầu bằng hai chữ cái viết hoa. Đây là một ví dụ ngắn.

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

Thông thường những gì tôi làm là đánh M-b M-c(giả sử tôi phát hiện ra nó ngay lập tức), nhưng tôi cảm thấy hơi mệt vì điều đó.

Làm thế nào tôi có thể có Emacs tự động sửa lỗi này cho tôi?

Đó là, tôi muốn Emacs phát hiện khi tôi gõ một từ bắt đầu bằng hai chữ cái in hoa theo sau là ít nhất một chữ cái viết thường và tự động sửa nó.

Câu trả lời:


19

Đây là một chức năng sẽ chuyển đổi các CApitals thành các Capitals đơn. Ban đầu tôi đề nghị thêm nó vào post-self-insert-hook, nhưng bên dưới là một tùy chọn cho chế độ nhỏ được tôn vinh để bạn chỉ thêm vào móc đó khi bạn thực sự muốn nó:

(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)

Và định nghĩa chế độ nhỏ:

(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)))

Để biết giá trị của nó, sử dụng phiên bản này:

  • rất đơn giản: chỉ cần bật / tắt thủ công hoặc trong một móc chế độ;
  • không yêu cầu thay đổi đối với các ràng buộc chính, vì vậy bạn sẽ không mất bất kỳ chức năng nào khác.

Ngay cả khi bạn thêm nó vào post-self-insert-hook, chi phí gần như không tồn tại, ít nhất là theo một số điểm chuẩn đơn giản. Trên máy của tôi, đây là những gì tôi nhận được với 10.000 lần lặp lại mỗi dạng đơn giản và lố bịch dcaps-to-scaps:

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

Vì vậy, vâng, nó chậm hơn so với việc thêm 1 + 1, nhưng về mặt tuyệt đối bạn sẽ không bao giờ nhận thấy.


Bạn có thể sử dụng looking-at-p, hoàn toàn không thiết lập dữ liệu khớp (điều đó ổn vì bạn không cần hoặc không sử dụng dữ liệu ở đây).
YoungFrog

Một vài nhận xét nữa, chủ yếu là không quan trọng (nhưng tôi thích câu trả lời của bạn hơn nên tôi muốn đóng góp; p): việc sử dụng forward-wordsẽ không hoạt động tốt subword-mode, sử dụng (char-syntax (char-before))ý chí (tôi đoán) bỏ qua bất kỳ lớp cú pháp nào có thuộc tính (giải pháp thay thế (syntax-after (1- (point)):) và (cuối cùng nhưng không kém phần quan trọng) regrec sẽ không tìm thấy các chữ cái có dấu (ví dụ: "ÉMincer", bằng tiếng Pháp)
YoungFrog

@YoungFrog: được cập nhật để giải quyết forward-wordvấn đề và thay đổi biểu thức chính quy để xử lý các chữ viết hoa có dấu.
Dân

Có một lý do để thích andhơn when, đặc biệt trong trường hợp đầu tiên?
Clément

@ Clément: andđược ngắn mạch, vì vậy logic hoạt động như whenở đây. Tôi không chắc chắn liệu có cách thực hành tốt nhất nào về việc sử dụng cái này so với cái kia hay không, nhưng có vẻ như nó sẽ tạo ra một câu hỏi hay trên trang web này (dù sao tôi cũng sẽ nâng cấp).
Dan

8

Sở thích của tôi là chỉ đơn giản là tạo ra một chức năng mới làm những gì thông thường self-insert-commandsẽ làm cộng với nhiều hơn nữa .

Dưới đây là một vài lý do:

  • Kiểm soát tốt hơn về chế độ chính nào sẽ có khả năng tự động sửa lỗi này. Đối với trường hợp sử dụng này, nó có thể là chế độ văn bản chỉ thích org-mode, text-modevv
  • Đối với loại chỉnh sửa được yêu cầu trong câu hỏi, người dùng thường nhấn SPChoặc REThoặc .phím sau từ. Vì vậy, sử dụng một cái gì đó như post-self-insert-hookcó thể là quá mức cần thiết và chúng tôi sẽ xử lý thêm mỗi lần chúng tôi nhấn bất kỳ phím nào.

Vì vậy, giải pháp đề xuất dưới đây liên kết chức năng này chỉ với SPCkhóa trong org-mode-map(bỏ qua trường hợp góc trong đó từ có thể là từ cuối cùng trong một dòng). Nếu cần, người dùng có thể liên kết các chức năng bao bọc tương tự với nhiều khóa hơn.

(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)

Đây là một bài tập elisp thú vị :)

Cá nhân tôi không muốn ràng buộc điều này RETvì sau đó tôi sẽ mất các ràng buộc mặc định trong org-modevà có lẽ các chế độ chính khác cũng vậy. Nhưng thật thú vị khi tìm hiểu về 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))))

Ồ vâng, hạn chế nó ở chế độ có nguồn gốc văn bản chắc chắn là một ý tưởng tốt. :)
Malabarba 14/07/2015

@Malabarba bạn không muốn hành vi này trong chuỗi cho các chế độ xuất phát từ chế độ prog?
YoungFrog 14/07/2015

@YoungFrog chắc chắn, nhưng sau đó nó sẽ phải kiểm tra xem nó thực sự nằm trong một chuỗi, nếu không nó sẽ cản trở bạn.
Malabarba

0

Có thể câu trả lời này không cung cấp giải pháp mà bạn mong đợi (điều chỉnh tương tác các từ khi bạn nhập), tôi muốn chia sẻ các cách của tôi để chống lại các vấn đề như vậy.

Trước hết, tôi không thích những thứ âm thầm thay đổi văn bản của mình (viết hoa, v.v., nếu bạn muốn gõ từ này IBuffer, tôi nghĩ "sửa lỗi" như vậy là một cách sai), vì vậy tôi khuyên hai điều:

Trước tiên, hãy thử bật tính năng "Phím dính". Nó có vẻ kỳ lạ lúc đầu nhưng tôi sử dụng nó mọi lúc. Tính năng này khả dụng ở cấp độ môi trường của hệ điều hành / máy tính để bàn, đây không phải là công cụ Emacs. Khi điều này được kích hoạt, trước tiên bạn nhấn ⇧ Shiftvà sau đó bạn nhấn một phím khác mà bạn muốn viết hoa. Bằng cách này, vấn đề của bạn thậm chí không thể phát sinh, chỉ có một chữ cái được viết hoa theo cách tiếp cận tuần tự này! Nó cũng làm giảm công việc tay của bạn cần phải giữ ⇧ Shiftchìa khóa. Tôi nghĩ bây giờ dễ dàng hơn để gõ.

Thứ hai, bây giờ bạn vẫn có thể sử dụng ⇧ Shiftkhóa một cách bình thường (giữ nó) khi bạn nghĩ cần thiết, nhưng tôi muốn đề xuất cho bạn gói Emacs có tên Fix Word . Ngay cả khi bạn không thích "Phím dính", bạn có thể sửa các từ thành dạng thích hợp của chúng một cách dễ dàng và bạn có thể sửa một số từ liên tiếp mà không cần di chuyển con trỏ vô dụng. Hãy thử xem, tôi sử dụng nó mọi lúc. (Vẫn còn khó để sửa lỗi nếu bạn nhập một vài từ và từ bạn cần viết hoa ở đâu đó ở giữa.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.