├── 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 | [](http://melpa.org/#/guru-mode)
5 | [](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 | [](https://ko-fi.com/bbatsov)
21 | [](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 |
--------------------------------------------------------------------------------