├── CONTRIBUTING.md ├── README.md └── guru-mode.el /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | If you discover issues, have ideas for improvements or new features, or 4 | want to contribute a new module, please report them to the 5 | [issue tracker][1] of the repository or submit a pull request. Please, 6 | try to follow these guidelines when you do so. 7 | 8 | ## Issue reporting 9 | 10 | * Check that the issue has not already been reported. 11 | * Check that the issue has not already been fixed in the latest code 12 | (a.k.a. `master`). 13 | * Be clear, concise and precise in your description of the problem. 14 | * Open an issue with a descriptive title and a summary in grammatically correct, 15 | complete sentences. 16 | * Include any relevant code to the issue summary. 17 | 18 | ## Pull requests 19 | 20 | * Read [how to properly contribute to open source projects on Github][2]. 21 | * Use a topic branch to easily amend a pull request later, if necessary. 22 | * Write [good commit messages][3]. 23 | * Use the same coding conventions as the rest of the project. 24 | * Verify your Emacs Lisp code with `checkdoc` (C-c ? d). 25 | * Open a [pull request][4] that relates to *only* one subject with a clear title 26 | and description in grammatically correct, complete sentences. 27 | 28 | [1]: https://github.com/bbatsov/guru-mode/issues 29 | [2]: http://gun.io/blog/how-to-github-fork-branch-and-pull-request 30 | [3]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 31 | [4]: https://help.github.com/articles/using-pull-requests 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # guru-mode 2 | 3 | [![License GPL 3][badge-license]](http://www.gnu.org/licenses/gpl-3.0.txt) 4 | [![MELPA](http://melpa.org/packages/guru-mode-badge.svg)](http://melpa.org/#/guru-mode) 5 | [![MELPA Stable](http://stable.melpa.org/packages/guru-mode-badge.svg)](http://stable.melpa.org/#/guru-mode) 6 | 7 | [badge-license]: https://img.shields.io/badge/license-GPL_3-green.svg 8 | 9 | ## Synopsis 10 | 11 | Guru mode disables (or warns on) some generic keybindings and suggests the use of the 12 | established and more efficient Emacs alternatives instead. Here are a few examples: 13 | 14 | * It will teach you to avoid the arrow keys and use keybindings like `C-f`, `C-b`, etc. 15 | * It will teach you to avoid keybindings using Home, End, etc. 16 | * It will teach you to avoid Delete/Backspace. 17 | 18 | ------------- 19 | 20 | [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/bbatsov) 21 | [![Patreon](https://img.shields.io/badge/patreon-donate-orange.svg)](https://www.patreon.com/bbatsov) 22 | 23 | You can support my work on `guru-mode` and my other Emacs packages via 24 | [PayPal](https://www.paypal.me/bbatsov), 25 | [ko-fi](https://ko-fi.com/bbatsov), 26 | [Patreon](https://www.patreon.com/bbatsov) and 27 | [GitHub Sponsors](https://github.com/sponsors/bbatsov). 28 | 29 | ## Installation 30 | 31 | ### Manual 32 | 33 | Just drop `guru-mode.el` somewhere in your `load-path`. I favour the 34 | folder `~/.emacs.d/vendor`: 35 | 36 | ```emacs-lisp 37 | (add-to-list 'load-path "~/emacs.d/vendor") 38 | (require 'guru-mode) 39 | ``` 40 | 41 | ### MELPA 42 | 43 | If you're an Emacs 24 user or you have a recent version of package.el 44 | you can install guru-mode from the [MELPA](https://melpa.org/) repository. 45 | 46 | ### Emacs Prelude 47 | 48 | `guru-mode` is naturally part of the 49 | [Emacs Prelude](https://github.com/bbatsov/prelude). If you're a Prelude 50 | user - `guru-mode` is already properly configured and ready for 51 | action. 52 | 53 | ## Usage 54 | 55 | You can enable `guru-mode` globally like this: 56 | 57 | ```emacs-lisp 58 | (guru-global-mode +1) 59 | ``` 60 | 61 | Most likely you'd like to enable `guru-mode` only in specific modes 62 | (like `prog-mode` in Emacs 24): 63 | 64 | ```emacs-lisp 65 | (add-hook 'prog-mode-hook 'guru-mode) 66 | ``` 67 | 68 | If you only want to get warnings when you the arrow keys use the following config: 69 | 70 | ```emacs-lisp 71 | (setq guru-warn-only t) 72 | ``` 73 | 74 | You can extend the list of keybindings covered by `guru-mode` like this: 75 | 76 | ``` emacs-lisp 77 | (add-to-list 'guru-affected-bindings-list '("" "M-b" left-word)) 78 | ``` 79 | 80 | The list you're adding is of the format (discouraged keybinding, recommended keybinding, command). 81 | 82 | **Note:** `guru-mode` operates only on global keybindings and it will never interfere with 83 | some mode-specific keybindings. 84 | 85 | ## Known issues 86 | 87 | Check out the project's 88 | [issue list](https://github.com/bbatsov/guru-mode/issues?sort=created&direction=desc&state=open) 89 | a list of unresolved issues. By the way - feel free to fix any of them 90 | and send me a pull request. :-) 91 | 92 | ## Contributors 93 | 94 | Here's a [list](https://github.com/bbatsov/guru-mode/contributors) of 95 | all the people who have contributed to the development of guru-mode. 96 | 97 | ## Bugs & Improvements 98 | 99 | Bug reports and suggestions for improvements are always 100 | welcome. GitHub pull requests are even better! :-) 101 | 102 | Cheers,
103 | [Bozhidar](http://twitter.com/bbatsov) 104 | -------------------------------------------------------------------------------- /guru-mode.el: -------------------------------------------------------------------------------- 1 | ;;; guru-mode.el --- Become an Emacs guru -*- lexical-binding:t -*- 2 | 3 | ;; Copyright (C) 2012-2020 Bozhidar Batsov 4 | 5 | ;; Author: Bozhidar Batsov 6 | ;; URL: https://github.com/bbatsov/guru-mode 7 | ;; Version: 1.0 8 | ;; Keywords: convenience 9 | 10 | ;; This file is NOT part of GNU Emacs. 11 | 12 | ;;; License: 13 | 14 | ;; This program is free software; you can redistribute it and/or modify 15 | ;; it under the terms of the GNU General Public License as published by 16 | ;; the Free Software Foundation; either version 3, or (at your option) 17 | ;; any later version. 18 | ;; 19 | ;; This program is distributed in the hope that it will be useful, 20 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | ;; GNU General Public License for more details. 23 | ;; 24 | ;; You should have received a copy of the GNU General Public License 25 | ;; along with GNU Emacs; see the file COPYING. If not, write to the 26 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 27 | ;; Boston, MA 02110-1301, USA. 28 | 29 | ;;; Commentary: 30 | ;; 31 | ;; Guru mode teaches you how to use Emacs effectively. 32 | ;; In particular it promotes the use of idiomatic keybindings 33 | ;; for essential editing commands. It can be configured to 34 | ;; either disallow the alternative keybindings completely or 35 | ;; to warn when they are being used. 36 | ;; 37 | ;;; Code: 38 | 39 | (defgroup guru nil 40 | "Learn essential Emacs keybindings with the help of a guru." 41 | :group 'tools 42 | :group 'convenience) 43 | 44 | (defvar guru-mode-map (make-sparse-keymap) 45 | "Guru mode's keymap.") 46 | 47 | (defcustom guru-warn-only nil 48 | "When non-nil you'll only get an error message." 49 | :group 'guru 50 | :type 'boolean 51 | :package-version '(guru . "0.2.0")) 52 | 53 | (defvar guru-affected-bindings-list 54 | '(("" "C-b" left-char) 55 | ("" "C-f" right-char) 56 | ("" "C-p" previous-line) 57 | ("" "C-n" next-line) 58 | ("" "M-b" left-word) 59 | ("" "M-f" right-word) 60 | ("" "M-{" backward-paragraph) 61 | ("" "M-}" forward-paragraph) 62 | ("" "M-b" left-word) 63 | ("" "M-f" right-word) 64 | ("" "C-d" delete-forward-char) 65 | ("" "M-d" kill-word) 66 | ("" "C-v" scroll-up-command) 67 | ("" "C-x <" scroll-left) 68 | ("" "M-v" scroll-down-command) 69 | ("" "C-x >" scroll-right) 70 | ("" "C-a" move-beginning-of-line) 71 | ("" "C-e" move-end-of-line) 72 | ("" "M-<" beginning-of-buffer) 73 | ("" "M->" end-of-buffer))) 74 | 75 | (defun guru-current-key-binding (key) 76 | "Look up the current binding for KEY without guru-mode." 77 | (prog2 (guru-mode -1) (key-binding (kbd key)) (guru-mode +1))) 78 | 79 | (defun guru-rebind (original-key alt-key original-binding) 80 | "Rebind ORIGINAL-KEY to a lambda. 81 | 82 | It will disable or warn and suggest using ALT-KEY for ORIGINAL-BINDING. 83 | The exact behavior of the lambda depends on the value of `guru-warn-only'." 84 | (lambda () 85 | (interactive) 86 | (let ((current-binding (guru-current-key-binding original-key))) 87 | (if (eq current-binding original-binding) 88 | (progn 89 | (let ((warning-text (if guru-warn-only "discouraged" "disabled"))) 90 | (message "%s keybinding is %s! Use <%s> instead" original-key warning-text alt-key)) 91 | (when guru-warn-only 92 | (call-interactively (key-binding (kbd alt-key))))) 93 | ;; else: the key has been re-mapped from the global default, 94 | ;; use it without interference. 95 | (call-interactively current-binding))))) 96 | 97 | (defun guru-init () 98 | "Initialize the guru keybindings." 99 | (dolist (cell guru-affected-bindings-list) 100 | (let ((original-key (car cell)) 101 | (recommended-key (cadr cell)) 102 | (original-binding (caddr cell))) 103 | (define-key guru-mode-map 104 | (read-kbd-macro original-key) (guru-rebind original-key recommended-key original-binding))))) 105 | 106 | ;;;###autoload 107 | (define-minor-mode guru-mode 108 | "A minor mode that teaches you to use Emacs effectively." 109 | :lighter " guru" 110 | :keymap guru-mode-map 111 | :group 'guru 112 | (when guru-mode 113 | (guru-init))) 114 | 115 | ;; define global minor mode 116 | ;;;###autoload 117 | (define-globalized-minor-mode guru-global-mode guru-mode guru-mode) 118 | 119 | (provide 'guru-mode) 120 | ;;; guru-mode.el ends here 121 | --------------------------------------------------------------------------------