]> code.delx.au - gnu-emacs-elpa/blob - packages/quarter-plane/quarter-plane.el
Merge commit '0cda39255827f283e7578cd469ae42daad9556a2' from js2-mode
[gnu-emacs-elpa] / packages / quarter-plane / quarter-plane.el
1 ;;; quarter-plane.el --- Minor mode for quarter-plane style editing
2
3 ;; Copyright (C) 2011 Free Software Foundation, Inc.
4
5 ;; Author: Peter J. Weisberg
6 ;; Version: 0.1
7 ;; Keywords: convenience wp
8
9 ;; This program is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
13
14 ;; This program is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22 ;;; Commentary:
23
24 ;; This package provides Quarter Plane mode, a minor mode which
25 ;; provides Picture mode style editing (treating the screen as a
26 ;; semi-infinite quarter-plane). Unlike Picture mode, it is a minor
27 ;; mode (see the Emacs manual for the documentation of Picture mode).
28 ;; Type M-x quarter-plane-mode to enable Quarter Plane mode in the
29 ;; current buffer, and M-x global-quarter-plane-mode to enable it
30 ;; globally.
31
32 ;; In Quarter Plane mode, the commands `right-char', `forward-char',
33 ;; `previous-line', `next-line', and `mouse-set-point' are rebound to
34 ;; Quarter Plane commands.
35
36 ;; Known issues:
37
38 ;; Quarter-Plane mode doesn't work in read-only buffers, where it
39 ;; can't insert spaces.
40
41 ;; The user doesn't really care about the "modifications" of adding
42 ;; whitespace that's going to be trimmed when he exits quarter-plane
43 ;; mode or saves, but it's still part of the undo history.
44
45 ;; Both of these are due to the disconnect between what the user
46 ;; really wants--movement of the cursor within the window, regardless
47 ;; of where the text is--and what the mode can actually do--add dummy
48 ;; text to give the cursor a place to move to.
49
50 ;;; Code:
51
52 (require 'picture)
53
54 (defvar quarter-plane-mode-map
55 (let ((map (make-sparse-keymap)))
56 (define-key map [remap right-char] 'picture-forward-column)
57 (define-key map [remap forward-char] 'picture-forward-column)
58 (define-key map [remap previous-line] 'picture-move-up)
59 (define-key map [remap next-line] 'picture-move-down)
60 (define-key map [remap mouse-set-point] 'picture-mouse-set-point)
61 map))
62
63 (defvar quarter-plane-saved-values nil)
64 (make-variable-buffer-local 'quarter-plane-saved-values)
65
66 ;;;###autoload
67 (define-minor-mode quarter-plane-mode
68 "Toggle Quarter-Plane mode on or off.
69 Interactively, with no prefix argument, toggle the mode.
70 With universal prefix ARG turn mode on.
71 With zero or negative ARG turn mode off.
72
73 Use point movement commands that act as if the text extended
74 infinitely down and to the right, inserting spaces as necessary.
75 Excess whitespace is trimmed when saving or exiting Quarter-Plane mode.
76
77 Because it works by inserting spaces, Quarter-Plane mode won't work in
78 read-only buffers.
79
80 \\{quarter-plane-mode-map}"
81 :lighter " Plane"
82 :group 'picture
83 :keymap quarter-plane-mode-map
84 (remove-hook 'before-save-hook 'quarter-plane-delete-whitespace t)
85 (dolist (symval (prog1 quarter-plane-saved-values
86 (setq quarter-plane-saved-values nil)))
87 (set (car symval) (cdr symval)))
88 (when quarter-plane-mode
89 (add-hook 'before-save-hook 'quarter-plane-delete-whitespace nil t)
90 ;; Since quarter-plane-mode is not permanent-local, it should turn itself
91 ;; off cleanly.
92 (add-hook 'change-major-mode-hook (lambda () (quarter-plane-mode -1)) nil t)
93 (dolist (symval '((truncate-lines . t)
94 (show-trailing-whitespace . nil)))
95 (push (cons (car symval) (symbol-value (car symval)))
96 quarter-plane-saved-values)
97 (set (car symval) (cdr symval)))))
98
99 ;;;###autoload
100 (define-global-minor-mode global-quarter-plane-mode quarter-plane-mode
101 quarter-plane-mode
102 :group 'picture)
103
104 (defun quarter-plane-delete-whitespace ()
105 "Call `delete-trailing-whitespace' if the buffer is not read-only."
106 (if (not buffer-read-only)
107 (delete-trailing-whitespace)))
108
109 (add-hook 'quarter-plane-mode-off-hook 'quarter-plane-delete-whitespace)
110
111 (provide 'quarter-plane)
112
113 ;;; quarter-plane.el ends here