Use external tool `w3m' for dumping html to plain texts.
[xwl-elisp.git] / smart-operator.el
blobcbc6152714f573ac8904d9be99e5f04ea6f1bc75
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>
6 ;; Version: 1.0.1
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)
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 insert 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, probably 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" "stack"
131 "multimap" "set" "hash_map" "iterator" "template"
132 "pair" "auto_ptr" "static_cast"
133 "dynmaic_cast" "const_cast" "reintepret_cast")
134 '("#import")))
135 "\\)\\ *")
136 (smart-operator-bol)))
137 (insert "<>")
138 (backward-char))
139 ((eq major-mode 'sgml-mode)
140 (insert "<>")
141 (backward-char))
143 (smart-operator-insert "<"))))
145 (defun smart-operator-: ()
146 "See `smart-operator-insert'."
147 (interactive)
148 (cond ((memq major-mode '(c-mode c++-mode))
149 (if (looking-back "\\?.+" (smart-operator-bol))
150 (smart-operator-insert ":")
151 (insert ":")))
153 (smart-operator-insert ":" t))))
155 (defun smart-operator-, ()
156 "See `smart-operator-insert'."
157 (interactive)
158 (smart-operator-insert "," t))
160 (defun smart-operator-. ()
161 "See `smart-operator-insert'."
162 (interactive)
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)))))
166 (insert "."))
168 (smart-operator-insert "." t)
169 (insert " "))))
171 (defun smart-operator-& ()
172 "See `smart-operator-insert'."
173 (interactive)
174 (cond ((memq major-mode '(c-mode c++-mode))
175 (insert "&"))
177 (smart-operator-insert "&"))))
179 (defun smart-operator-* ()
180 "See `smart-operator-insert'."
181 (interactive)
182 (cond ((memq major-mode '(c-mode c++-mode objc-mode))
183 (if (or (looking-back "[0-9a-zA-Z]" (1- (point)))
184 (bolp))
185 (smart-operator-insert "*")
186 (insert "*")))
188 (smart-operator-insert "*"))))
190 (defun smart-operator-> ()
191 "See `smart-operator-insert'."
192 (interactive)
193 (cond ((and (memq major-mode '(c-mode c++-mode))
194 (looking-back " - " (- (point) 3)))
195 (delete-char -3)
196 (insert "->"))
198 (smart-operator-insert ">"))))
200 (defun smart-operator-+ ()
201 "See `smart-operator-insert'."
202 (interactive)
203 (cond ((and (memq major-mode '(c-mode c++-mode))
204 (looking-back "+ " (- (point) 2)))
205 (delete-char -2)
206 ;; (delete-horizontal-space)
207 (insert "++")
208 (indent-according-to-mode))
210 (smart-operator-insert "+"))))
212 (defun smart-operator-- ()
213 "See `smart-operator-insert'."
214 (interactive)
215 (cond ((and (memq major-mode '(c-mode c++-mode))
216 (looking-back "- " (- (point) 2)))
217 (delete-char -2)
218 (delete-horizontal-space)
219 (insert "--")
220 (indent-according-to-mode))
222 (smart-operator-insert "-"))))
224 (defun smart-operator-? ()
225 "See `smart-operator-insert'."
226 (interactive)
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'."
234 (interactive)
235 (cond ((and (memq major-mode '(c-mode c++-mode objc-mode)))
236 (insert "%"))
238 (smart-operator-insert "%"))))
240 (provide 'smart-operator)
242 ;;; smart-operator.el ends here