*** empty log message ***
[xwl-elisp.git] / smart-operator.el
blob7f233561eb2846d8f111d7f54576d2067212c318
1 ;;; smart-operator.el --- Insert operators with surrounding spaces smartly
3 ;; Copyright (C) 2004, 2005, 2007, 2008 William Xu
5 ;; Author: William Xu <william.xwl@gmail.com>
6 ;; Version: 1.0
7 ;; Url: http://williamxu.net9.org/ref/smart-operator.el
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, or (at your option)
12 ;; any later version.
14 ;; This program is distributed in the hope that it will be useful, but
15 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 ;; General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with EMMS; see the file COPYING. If not, write to the
21 ;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
24 ;;; Commentary:
26 ;; When typing operators, this package can automatically insert spaces
27 ;; before and after operators. For instance, `=' will become ` = ', `+='
28 ;; will become ` += '. This is handy for writing C-style sources.
30 ;; To use, put this file to your load-path and the following to your
31 ;; ~/.emacs:
32 ;; (require 'smart-operator)
34 ;; Then `M-x smart-operator-mode' for toggling this minor mode.
36 ;; Usage Tips
37 ;; ----------
39 ;; - If you want it to insert operator with surrounding spaces , you'd
40 ;; better not type the front space yourself, instead, type operator
41 ;; directly. smart-operator-mode will also take this as a hint on how
42 ;; to properly generating spaces in some specific occasions. For
43 ;; example, in c-mode, `a*' -> `a * ', `char *' -> `char *'.
45 ;;; Acknowledgements
47 ;; Nikolaj Schumacher <n_schumacher@web.de>, for suggesting
48 ;; reimplementing as a minor mode and providing an initial patch for
49 ;; that.
51 ;;; TODO:
53 ;; - for c mode, probaly it would be much better doing this in cc-mode.
55 ;;; Code:
57 ;;; smart-operator minor mode
59 (defvar smart-operator-mode-map
60 (let ((keymap (make-sparse-keymap)))
61 (define-key keymap "=" 'smart-operator-self-insert-command)
62 (define-key keymap "<" 'smart-operator-<)
63 (define-key keymap ">" 'smart-operator->)
64 (define-key keymap "%" 'smart-operator-%)
65 (define-key keymap "+" 'smart-operator-+)
66 (define-key keymap "-" 'smart-operator--)
67 (define-key keymap "*" 'smart-operator-*)
68 (define-key keymap "/" 'smart-operator-self-insert-command)
69 (define-key keymap "&" 'smart-operator-&)
70 (define-key keymap "|" 'smart-operator-self-insert-command)
71 (define-key keymap "!" 'smart-operator-self-insert-command)
72 (define-key keymap ":" 'smart-operator-:)
73 (define-key keymap "?" 'smart-operator-?)
74 (define-key keymap "," 'smart-operator-,)
75 (define-key keymap "." 'smart-operator-.)
76 keymap)
77 "Keymap used my `smart-operator-mode'.")
79 ;;;###autoload
80 (define-minor-mode smart-operator-mode
81 "Insert operators with surrounding spaces smartly."
82 nil "_+_ " smart-operator-mode-map)
84 (defun smart-operator-mode-on ()
85 (smart-operator-mode 1))
87 ;;;###autoload
88 (defun smart-operator-self-insert-command (arg)
89 "Insert the entered operator plus surrounding spaces."
90 (interactive "p")
91 (smart-operator-insert (string last-command-char)))
93 (defvar smart-operator-list
94 '("=" "<" ">" "%" "+" "-" "*" "/" "&" "|" "!" ":" "?" "," "."))
96 (defun smart-operator-insert (op &optional only-after)
97 "Insert operator OP with surrounding spaces.
98 e.g., `=' will become ` = ', `+=' will become ` += '.
100 When ONLY-AFTER, insert space at back only."
101 (delete-horizontal-space)
102 (if (or (looking-back (regexp-opt smart-operator-list)
103 (save-excursion (beginning-of-line)
104 (point)))
105 only-after
106 (bolp))
107 (progn (insert (concat op " "))
108 (save-excursion
109 (backward-char 2)
110 (when (bolp)
111 (indent-according-to-mode))))
112 (insert (concat " " op " "))))
114 (defun smart-operator-bol ()
115 (save-excursion
116 (beginning-of-line)
117 (point)))
120 ;;; Fine Tunings
122 (defun smart-operator-< ()
123 "See `smart-operator-insert'."
124 (interactive)
125 (cond ((and (memq major-mode '(c-mode c++-mode objc-mode))
126 (looking-back
127 (concat "\\("
128 (regexp-opt
129 (append
130 '("#include" "vector" "deque" "list" "map"
131 "multimap" "set" "hash_map" "iterator" "template"
132 "pair" "auto_ptr")
133 '("#import")))
134 "\\)\\ *")
135 (smart-operator-bol)))
136 (insert "<>")
137 (backward-char))
138 ((eq major-mode 'sgml-mode)
139 (insert "<>")
140 (backward-char))
142 (smart-operator-insert "<"))))
144 (defun smart-operator-: ()
145 "See `smart-operator-insert'."
146 (interactive)
147 (cond ((memq major-mode '(c-mode c++-mode))
148 (if (looking-back "\\?.+" (smart-operator-bol))
149 (smart-operator-insert ":")
150 (insert ":")))
152 (smart-operator-insert ":" t))))
154 (defun smart-operator-, ()
155 "See `smart-operator-insert'."
156 (interactive)
157 (smart-operator-insert "," t))
159 (defun smart-operator-. ()
160 "See `smart-operator-insert'."
161 (interactive)
162 (cond ((or (looking-back "[0-9]" (1- (point)))
163 (and (memq major-mode '(c-mode c++-mode))
164 (looking-back "[a-z]" (1- (point)))))
165 (insert "."))
167 (smart-operator-insert "." t)
168 (insert " "))))
170 (defun smart-operator-& ()
171 "See `smart-operator-insert'."
172 (interactive)
173 (cond ((memq major-mode '(c-mode c++-mode))
174 (insert "&"))
176 (smart-operator-insert "&"))))
178 (defun smart-operator-* ()
179 "See `smart-operator-insert'."
180 (interactive)
181 (cond ((memq major-mode '(c-mode c++-mode objc-mode))
182 ;; (if (or (looking-back "[0-9a-zA-Z]" (1- (point)))
183 ;; (bolp))
184 ;; (smart-operator-insert "*")
185 (insert "*"))
187 (smart-operator-insert "*"))))
189 (defun smart-operator-> ()
190 "See `smart-operator-insert'."
191 (interactive)
192 (cond ((and (memq major-mode '(c-mode c++-mode))
193 (looking-back " - " (- (point) 3)))
194 (delete-char -3)
195 (insert "->"))
197 (smart-operator-insert ">"))))
199 (defun smart-operator-+ ()
200 "See `smart-operator-insert'."
201 (interactive)
202 (cond ((and (memq major-mode '(c-mode c++-mode))
203 (looking-back "+ " (- (point) 2)))
204 (delete-char -2)
205 (delete-horizontal-space)
206 (insert "++")
207 (indent-according-to-mode))
209 (smart-operator-insert "+"))))
211 (defun smart-operator-- ()
212 "See `smart-operator-insert'."
213 (interactive)
214 (cond ((and (memq major-mode '(c-mode c++-mode))
215 (looking-back "- " (- (point) 2)))
216 (delete-char -2)
217 (delete-horizontal-space)
218 (insert "--")
219 (indent-according-to-mode))
221 (smart-operator-insert "-"))))
223 (defun smart-operator-? ()
224 "See `smart-operator-insert'."
225 (interactive)
226 (cond ((memq major-mode '(c-mode c++-mode))
227 (smart-operator-insert "?"))
229 (smart-operator-insert "?" t))))
231 (defun smart-operator-% ()
232 "See `smart-operator-insert'."
233 (interactive)
234 (cond ((and (memq major-mode '(c-mode c++-mode objc-mode)))
235 (insert "%"))
237 (smart-operator-insert "%"))))
239 (provide 'smart-operator)
241 ;;; smart-operator.el ends here