Что такое хорошие пользовательские сочетания клавиш в emacs?

Кажется, что в Emacs все возможные комбинации клавиш уже случайным образом распределены между его командами. :п

Если мне нужно определить новые сочетания клавиш, где их разместить? Какие префиксы следует использовать?

Например: я хочу определить ярлыки для следующих функций:

  • indent-buffer (C-c i, после того, как я получил ответ)
  • область комментирования или раскомментирования (C-c C)
  • rdebug (рубиновый отладчик) (C-c R)
  • rsense-complete (автозаполнение ruby) (C-c e)

Куда бы вы их положили? Почему?


person Pedro Rolo    schedule 15.04.2011    source источник


Ответы (5)


Emacs на самом деле имеет очень определенный шаблон для своих привязок, этот ответ показывает некоторые из них.

Что касается того, где вы должны определять ключи, если вы посмотрите на документацию по соглашениям, вы увидите, что Cc a (где a – любой символ нижнего или верхнего регистра) зарезервирован для пользователей. .

Кроме того, если вы определяете клавишу, которая действительно имеет смысл только в определенном режиме, вы должны определить ее в этой раскладке.

Например, M-/ привязано к dabbrev-expand, что является удобным способом автоматического завершения слова, которое вы печатаете. Вместо этого вполне может иметь смысл использовать rsense-complete, но только когда вы работаете в ruby. В этом случае вы можете сделать это:

(add-hook 'ruby-mode-hook
     (lambda () (define-key ruby-mode-map (kbd "M-/") 'rsense-complete)))

Это переопределит привязку для M-/ только тогда, когда вы находитесь в ruby-mode, и оставит ее неизменной (или доступной) для остальных режимов.

person Trey Jackson    schedule 15.04.2011

По умолчанию C-x h помечает весь буфер, а C-M-\ запускает indent-region, поэтому выполнение этих двух действий один за другим приведет к отступу всего буфера.

comment-dwim уже привязан по умолчанию к M-; и, вероятно, работает лучше, чем comment-or-uncomment-region. («DWIM» означает «делай то, что я имею в виду»)

Для завершения я рекомендую настроить режим автозаполнения, который взаимодействует с rsense. Автозаполнение имеет стандартные сочетания клавиш для всех дополнений.

Что касается rdebug, я бы, вероятно, просто прикрепил его к одной из F-клавиш или к чему-то еще с префиксом C-c, так как это своего рода назначенный «пользовательский» префикс. Может быть, C-c d для "Отладки". Чтобы убедиться, что ключ еще не привязан, перейдите к ruby-буферу и нажмите C-h k, а затем нажмите комбинацию клавиш и убедитесь, что Emacs сообщает вам, что она не определена.

person Ryan C. Thompson    schedule 15.04.2011

У меня есть нетрадиционный подход к этому, который я очень рекомендую. Я переопределил клавишу C-l («ell») как префиксную клавишу и использую ее для префикса моих любимых команд. Эту клавишу очень легко ввести, и она привязана к функции (recenter), которая используется не так часто.

Ну, я не часто использую 'recenter, но даже если бы вы это сделали, его можно назначить Cl Cl, который почти так же легко набирать, и небольшая цена за возможности, открываемые Ctrl-L-карта . (На самом деле я предпочитаю «перерисовку-отображение» «повторному центрированию», поэтому я отдал этому почетное место.)

Я не помню, где я взял волшебное заклинание, которое заставляет его работать:

(global-unset-key "\C-l")
(defvar ctl-l-map (make-keymap)
     "Keymap for local bindings and functions, prefixed by (^L)")
(define-key global-map "\C-l" 'Control-L-prefix)
(fset 'Control-L-prefix ctl-l-map)

Затем вы можете определить ключи к своему сердцу. C-l — отличное место для размещения привязок для ваших собственных команд, а также функций, которые не привязаны к клавишам или привязаны к клавишам, которые вы не можете вспомнить или с трудом набираете. Вот несколько примеров привязок к стандартным функциям:

(define-key ctl-l-map "\C-l"  'redraw-display)
(define-key ctl-l-map "l"  'recenter)

(define-key ctl-l-map "g"  'goto-line)
(define-key ctl-l-map "r"  'replace-string)
(define-key ctl-l-map "R"  'replace-regexp)
(define-key ctl-l-map "q"  'query-replace)
(define-key ctl-l-map "Q"  'query-replace-regexp)
(define-key ctl-l-map "o"  'overwrite-mode)
(define-key ctl-l-map "\C-w"  'kill-rectangle)
(define-key ctl-l-map "\C-y"  'yank-rectangle)
(define-key ctl-l-map "h"  'command-history)
(define-key ctl-l-map "w"  'write-region)
(define-key ctl-l-map "r" 'electric-replace-string)
(define-key ctl-l-map "\er" 'replace-string)
(define-key ctl-l-map "T"  'delete-trailing-whitespace)
(define-key ctl-l-map "C"  'describe-char)
(define-key ctl-l-map "W"  'ediff-regions-wordwise)
(define-key ctl-l-map "L"  'ediff-regions-linewise)
(define-key ctl-l-map "\C-f" 'facemenu-remove-all)
(define-key ctl-l-map "\C-c" 'calendar)
(define-key ctl-l-map "m"  'not-modified)   ;; already at M-~
(define-key ctl-l-map "\C-q" 'fill-region)
(define-key ctl-l-map "u" 'set-buffer-file-coding-system)
(define-key ctl-l-map [?\C-2] 'transient-mark-mode)
(define-key ctl-l-map "\C-@"  'transient-mark-mode)
(define-key ctl-l-map "\C-n"  'linum-mode)
(define-key ctl-l-map "\C-s" 'isearch-forward-regexp)
(define-key ctl-l-map "\C-r" 'isearch-backward-regexp)a
(define-key ctl-l-map "U" 'browse-url)
(define-key ctl-l-map "F" 'browse-url-of-file)
(define-key ctl-l-map "\C-u" 'undo-only)
person LenW    schedule 29.04.2011

Обычно я помещаю глобальные привязки клавиш в отдельный файл (часть моей конфигурации) и конфигурацию для конкретного режима в файлах конфигурации для конкретного режима. Таким образом, все скудно, плотно и легко найти. Некоторые из вещей, которые вы упомянули, такие как комментарий / раскомментирование, уже имеют прикрепленные сочетания клавиш. Я реализовал отступ-буфер с функцией отступ-буфер-или-регион (часть EDT), которую я привязал к стандартному ключу отступа C-M-\. Существуют формальные правила того, какие клавиши должны использоваться пользователями для своих пользовательских привязок клавиш, и, конечно же, есть здравый смысл. Ничто не написано на камне.

Вот несколько примеров из Emacs Prelude:

;; You know, like Readline.
(global-set-key (kbd "C-M-h") 'backward-kill-word)

;; Align your code in a pretty way.
(global-set-key (kbd "C-x \\") 'align-regexp)

;; Perform general cleanup.
(global-set-key (kbd "C-c n") 'cleanup-buffer)

;; Font size
(define-key global-map (kbd "C-+") 'text-scale-increase)
(define-key global-map (kbd "C--") 'text-scale-decrease)

;; Jump to a definition in the current file. (This is awesome.)
(global-set-key (kbd "C-x C-i") 'ido-imenu)

;; File finding
(global-set-key (kbd "C-x M-f") 'ido-find-file-other-window)
(global-set-key (kbd "C-x C-M-f") 'find-file-in-project)
(global-set-key (kbd "C-x f") 'recentf-ido-find-file)
(global-set-key (kbd "C-c r") 'bury-buffer)
(global-set-key (kbd "M-`") 'file-cache-minibuffer-complete)

;; Window switching. (C-x o goes to the next window)
(global-set-key (kbd "C-x O") (lambda ()
                                (interactive)
                                (other-window -1))) ;; back one

;; Indentation help
(global-set-key (kbd "C-x ^") 'join-line)
(global-set-key (kbd "C-M-\\") 'indent-region-or-buffer)

;; Start proced in a similar manner to dired
(global-set-key (kbd "C-x p") 'proced)

;; Start eshell or switch to it if it's active.
(global-set-key (kbd "C-x m") 'eshell)

;; Start a new eshell even if one is active.
(global-set-key (kbd "C-x M") (lambda () (interactive) (eshell t)))

;; Start a regular shell if you prefer that.
(global-set-key (kbd "C-x M-m") 'shell)

;; If you want to be able to M-x without meta
(global-set-key (kbd "C-x C-m") 'execute-extended-command)

;; Fetch the contents at a URL, display it raw.
(global-set-key (kbd "C-x C-h") 'view-url)

;; Help should search more than just commands
(global-set-key (kbd "C-h a") 'apropos)

;; Should be able to eval-and-replace anywhere.
(global-set-key (kbd "C-c e") 'eval-and-replace)

;; Magit rules!
(global-set-key (kbd "C-x g") 'magit-status)

;; Activate occur easily inside isearch
(define-key isearch-mode-map (kbd "C-o")
  (lambda () (interactive)
    (let ((case-fold-search isearch-case-fold-search))
      (occur (if isearch-regexp
                 isearch-string
               (regexp-quote isearch-string))))))

;; cycle through buffers
(global-set-key (kbd "<C-tab>") 'bury-buffer)

;; use hippie-expand instead of dabbrev
(global-set-key (kbd "M-/") 'hippie-expand)

;; spell check Bulgarian text
(global-set-key (kbd "C-c B")
                (lambda()(interactive)
                  (ispell-change-dictionary "bulgarian")
                  (flyspell-buffer)))

;; replace buffer-menu with ibuffer
(global-set-key (kbd "C-x C-b") 'ibuffer)

;; interactive text replacement
(global-set-key (kbd "C-c C-r") 'iedit-mode)

;; swap windows
(global-set-key (kbd "C-c s") 'swap-windows)

;; duplicate the current line or region
(global-set-key (kbd "C-c d") 'duplicate-current-line-or-region)

;; rename buffer & visited file
(global-set-key (kbd "C-c r") 'rename-file-and-buffer)

;; open an ansi-term buffer
(global-set-key (kbd "C-x t") 'visit-term-buffer)

;; toggle input method
(global-set-key (kbd "C-\\") 'toggle-bulgarian-input-method)

;; search with google
(global-set-key (kbd "C-c g") 'google)

;; toggle menu-bar visibility
(global-set-key (kbd "<f12>") (lambda () (interactive) (menu-bar-mode)))
person Bozhidar Batsov    schedule 15.04.2011
comment
Я бы сказал, что это плохой ответ. Это может привести меня к несоблюдению условностей. - person Pedro Rolo; 16.04.2011
comment
Вы, конечно, имеете право на мнение. Я долгое время пользуюсь Emacs, я знаю соглашения и знаю, что почти никто не использует их для специальных сочетаний клавиш, подобных тем, которые вам нужны. Они гораздо более важны, когда кто-то разрабатывает второстепенные/основные моды. - person Bozhidar Batsov; 16.04.2011

Это мое.

Обратите внимание, что я переназначил клавиши движения. Это произошло потому, что я использую MS NS4K, который делает эти конкретные движения клавиш очень простыми.

;;;;;;;; remapping of keys ;;;;;;;;;;;;;;;

(global-set-key "\C-cg" 'goto-line)
;C-c u untabifies...yuck!
(global-set-key "\C-cu" 'untabify)
;Regex replace
(global-set-key "\C-x%" `query-replace-regexp)
;;Backward-kill-line is defined later on in this file.
(global-set-key "\M-k" `backward-kill-line)

(global-set-key "\C-x\C-j" 'eval-print-last-sexp)
;;M-up/down -> start/end of buffer. Yay!
(global-set-key (kbd "M-<up>") 'beginning-of-buffer)
(global-set-key (kbd "M-<down>") 'end-of-buffer)
(global-set-key (kbd "M-[") 'beginning-of-buffer)
(global-set-key (kbd "M-]") 'end-of-buffer)

;;remap movement keys to get rid of emacs pinky
;Jump back and forth by 5.
(global-set-key "\C-n" '(lambda () (interactive) (forward-line 5)))
(global-set-key "\C-p" '(lambda () (interactive) (forward-line -5)))
(global-set-key "\M-a" 'move-beginning-of-line)
(global-set-key "\M-e" 'move-end-of-line)
(global-set-key "\M-n" 'next-line)
(global-set-key "\M-p" 'previous-line)

;bookmark
(global-set-key (kbd "<M-f2>") 'bm-toggle)
(global-set-key (kbd "<f2>")   'bm-next)
(global-set-key (kbd "<f3>") 'bm-previous)
(setq bm-cycle-all-buffers t)

(global-set-key (kbd "<f5>") 'revert-buffer)
(global-set-key (kbd "<f12>") 'delete-trailing-whitespace)
(global-set-key (kbd "<f11>") 'comment-or-uncomment-region)

(global-set-key (kbd "M-RET") 'newline-and-indent)
(global-set-key "\C-m" 'newline-and-indent)

;;Jump "backwards"
(global-set-key "\C-xp" '(lambda () (interactive) (other-window -1)))

;;copy
(global-set-key "\M-y" 'yank)

;;insert line
(global-set-key "\M-o" '(lambda () (interactive) (open-line 1)))

;zap to char backwards
(global-set-key "\C-z" 'minimize)
;;suspend-emacs is the send-to-background command on linux

;simplify register usage
(global-set-key "\M-s" 'copy-to-register)
(global-set-key "\M-i" 'insert-register)

;;autocomplete hacks
(global-set-key [?\M-/] 'hippie-expand)
(global-set-key [?\C-/] 'dabbrev-expand)


(global-set-key [?\C-.] 'find-tag)
;(global-set-key "\C-.\C-s" 'find-tag)
(global-unset-key [?\M-.])

;;this lets us have long lines go off the side of the screen instead of hosing up the ascii art
(global-set-key "\C-t" 'toggle-truncate-lines)

;comment/uncomment region
(global-set-key "\C-c\C-c" 'comment-or-uncomment-region)

;;Buffer-move
(global-set-key (kbd "<C-S-left>")   'buf-move-left)
(global-set-key (kbd "<C-S-right>")  'buf-move-right)
person Paul Nathan    schedule 29.04.2011