1 ;;; smart-operator.el --- Insert operators with surrounding spaces smartly
3 ;; Copyright (C) 2004, 2005, 2007, 2008, 2009 William Xu
5 ;; Author: William Xu <william.xwl@gmail.com>
7 ;; Url: http://xwl.appspot.com/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)
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.
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
32 ;; (require 'smart-operator)
34 ;; Then `M-x smart-operator-mode' for toggling this minor mode.
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 insert spaces in some specific occasions. For
43 ;; example, in c-mode, `a*' -> `a * ', `char *' -> `char *'.
47 ;; Nikolaj Schumacher <n_schumacher@web.de>, for suggesting
48 ;; reimplementing as a minor mode and providing an initial patch for
53 ;; - for c mode, probably it would be much better doing this in cc-mode.
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-.
)
77 "Keymap used my `smart-operator-mode'.")
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))
88 (defun smart-operator-self-insert-command (arg)
89 "Insert the entered operator plus surrounding spaces."
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)
107 (progn (insert (concat op
" "))
111 (indent-according-to-mode))))
112 (insert (concat " " op
" "))))
114 (defun smart-operator-bol ()
122 (defun smart-operator-< ()
123 "See `smart-operator-insert'."
125 (cond ((and (memq major-mode
'(c-mode c
++-mode objc-mode
))
130 '("#include" "vector" "deque" "list" "map" "stack"
131 "multimap" "set" "hash_map" "iterator" "template"
132 "pair" "auto_ptr" "static_cast"
133 "dynmaic_cast" "const_cast" "reintepret_cast")
136 (smart-operator-bol)))
139 ((eq major-mode
'sgml-mode
)
143 (smart-operator-insert "<"))))
145 (defun smart-operator-: ()
146 "See `smart-operator-insert'."
148 (cond ((memq major-mode
'(c-mode c
++-mode
))
149 (if (looking-back "\\?.+" (smart-operator-bol))
150 (smart-operator-insert ":")
153 (smart-operator-insert ":" t
))))
155 (defun smart-operator-, ()
156 "See `smart-operator-insert'."
158 (smart-operator-insert "," t
))
160 (defun smart-operator-.
()
161 "See `smart-operator-insert'."
163 (cond ((or (looking-back "[0-9]" (1- (point)))
164 (and (memq major-mode
'(c-mode c
++-mode python-mode
))
165 (looking-back "[a-z]" (1- (point)))))
168 (smart-operator-insert "." t
)
171 (defun smart-operator-& ()
172 "See `smart-operator-insert'."
174 (cond ((memq major-mode
'(c-mode c
++-mode
))
177 (smart-operator-insert "&"))))
179 (defun smart-operator-* ()
180 "See `smart-operator-insert'."
182 (cond ((memq major-mode
'(c-mode c
++-mode objc-mode
))
183 (if (or (looking-back "[0-9a-zA-Z]" (1- (point)))
185 (smart-operator-insert "*")
188 (smart-operator-insert "*"))))
190 (defun smart-operator-> ()
191 "See `smart-operator-insert'."
193 (cond ((and (memq major-mode
'(c-mode c
++-mode
))
194 (looking-back " - " (- (point) 3)))
198 (smart-operator-insert ">"))))
200 (defun smart-operator-+ ()
201 "See `smart-operator-insert'."
203 (cond ((and (memq major-mode
'(c-mode c
++-mode
))
204 (looking-back "+ " (- (point) 2)))
206 ;; (delete-horizontal-space)
208 (indent-according-to-mode))
210 (smart-operator-insert "+"))))
212 (defun smart-operator-- ()
213 "See `smart-operator-insert'."
215 (cond ((and (memq major-mode
'(c-mode c
++-mode
))
216 (looking-back "- " (- (point) 2)))
218 (delete-horizontal-space)
220 (indent-according-to-mode))
222 (smart-operator-insert "-"))))
224 (defun smart-operator-?
()
225 "See `smart-operator-insert'."
227 (cond ((memq major-mode
'(c-mode c
++-mode
))
228 (smart-operator-insert "?"))
230 (smart-operator-insert "?" t
))))
232 (defun smart-operator-%
()
233 "See `smart-operator-insert'."
235 (cond ((and (memq major-mode
'(c-mode c
++-mode objc-mode
)))
238 (smart-operator-insert "%"))))
240 (provide 'smart-operator
)
242 ;;; smart-operator.el ends here