Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
marvel
GitHub Repository: marvel/qnf
Path: blob/master/elisp/emacs-for-python/plugins/smart-operator.el
990 views
1
;;; smart-operator.el --- Insert operators with surrounding spaces smartly
2
3
;; Copyright (C) 2004, 2005, 2007, 2008, 2009 William Xu
4
5
;; Author: William Xu <[email protected]>
6
;; Version: 1.1
7
;; Url: http://xwl.appspot.com/ref/smart-operator.el
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, or (at your option)
12
;; any later version.
13
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.
18
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.
23
24
;;; Commentary:
25
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.
29
30
;; To use, put this file to your load-path and the following to your
31
;; ~/.emacs:
32
;; (require 'smart-operator)
33
;;
34
;; Then `M-x smart-operator-mode' for toggling this minor mode.
35
36
;; Usage Tips
37
;; ----------
38
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 *'.
44
45
;;; Acknowledgements
46
47
;; Nikolaj Schumacher <[email protected]>, for suggesting
48
;; reimplementing as a minor mode and providing an initial patch for
49
;; that.
50
51
;;; TODO:
52
53
;; - for c mode, probably it would be much better doing this in cc-mode.
54
55
;;; Code:
56
57
;;; smart-operator minor mode
58
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'.")
78
79
;;;###autoload
80
(define-minor-mode smart-operator-mode
81
"Insert operators with surrounding spaces smartly."
82
nil " _+_" smart-operator-mode-map)
83
84
(defun smart-operator-mode-on ()
85
(smart-operator-mode 1))
86
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-event)))
92
93
(defvar smart-operator-list
94
'("=" "<" ">" "%" "+" "-" "*" "/" "&" "|" "!" ":" "?" "," "."))
95
96
(defun smart-operator-insert (op &optional only-after)
97
"Insert operator OP with surrounding spaces.
98
e.g., `=' will become ` = ', `+=' will become ` += '.
99
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 " "))))
113
114
(defun smart-operator-bol ()
115
(save-excursion
116
(beginning-of-line)
117
(point)))
118
119
(if (fboundp 'python-comment-line-p)
120
(defalias 'smart-operator-comment-line-p 'python-comment-line-p)
121
(defun smart-operator-comment-line-p ()
122
"Return non-nil if and only if current line has only a comment."
123
(save-excursion
124
(end-of-line)
125
(when (eq 'comment (syntax-ppss-context (syntax-ppss)))
126
(back-to-indentation)
127
(looking-at (rx (or (syntax comment-start) line-end))))))
128
)
129
130
131
;;; Fine Tunings
132
133
(defun smart-operator-< ()
134
"See `smart-operator-insert'."
135
(interactive)
136
(cond ((and (memq major-mode '(c-mode c++-mode objc-mode))
137
(looking-back
138
(concat "\\("
139
(regexp-opt
140
(append
141
'("#include" "vector" "deque" "list" "map" "stack"
142
"multimap" "set" "hash_map" "iterator" "template"
143
"pair" "auto_ptr" "static_cast"
144
"dynmaic_cast" "const_cast" "reintepret_cast")
145
'("#import")))
146
"\\)\\ *")
147
(smart-operator-bol)))
148
(insert "<>")
149
(backward-char))
150
((eq major-mode 'sgml-mode)
151
(insert "<>")
152
(backward-char))
153
(t
154
(smart-operator-insert "<"))))
155
156
(defun smart-operator-: ()
157
"See `smart-operator-insert'."
158
(interactive)
159
(cond ((memq major-mode '(c-mode c++-mode))
160
(if (looking-back "\\?.+" (smart-operator-bol))
161
(smart-operator-insert ":")
162
(insert ":")))
163
(t
164
(smart-operator-insert ":" t))))
165
166
(defun smart-operator-, ()
167
"See `smart-operator-insert'."
168
(interactive)
169
(smart-operator-insert "," t))
170
171
(defun smart-operator-. ()
172
"See `smart-operator-insert'."
173
(interactive)
174
(cond ((smart-operator-comment-line-p)
175
(smart-operator-insert "." t)
176
(insert " "))
177
((or (looking-back "[0-9]" (1- (point)))
178
(and (memq major-mode '(c-mode c++-mode python-mode))
179
(looking-back "[a-z]" (1- (point)))))
180
(insert "."))
181
((memq major-mode '(cperl-mode perl-mode))
182
(insert " . "))
183
(t
184
(smart-operator-insert "." t)
185
(insert " "))))
186
187
(defun smart-operator-& ()
188
"See `smart-operator-insert'."
189
(interactive)
190
(cond ((memq major-mode '(c-mode c++-mode))
191
(insert "&"))
192
(t
193
(smart-operator-insert "&"))))
194
195
(defun smart-operator-* ()
196
"See `smart-operator-insert'."
197
(interactive)
198
(cond ((memq major-mode '(c-mode c++-mode objc-mode))
199
(if (or (looking-back "[0-9a-zA-Z]" (1- (point)))
200
(bolp))
201
(smart-operator-insert "*")
202
(insert "*")))
203
(t
204
(smart-operator-insert "*"))))
205
206
(defun smart-operator-> ()
207
"See `smart-operator-insert'."
208
(interactive)
209
(cond ((and (memq major-mode '(c-mode c++-mode))
210
(looking-back " - " (- (point) 3)))
211
(delete-char -3)
212
(insert "->"))
213
(t
214
(smart-operator-insert ">"))))
215
216
(defun smart-operator-+ ()
217
"See `smart-operator-insert'."
218
(interactive)
219
(cond ((and (memq major-mode '(c-mode c++-mode))
220
(looking-back "+ " (- (point) 2)))
221
(delete-char -2)
222
;; (delete-horizontal-space)
223
(insert "++")
224
(indent-according-to-mode))
225
(t
226
(smart-operator-insert "+"))))
227
228
(defun smart-operator-- ()
229
"See `smart-operator-insert'."
230
(interactive)
231
(cond ((and (memq major-mode '(c-mode c++-mode))
232
(looking-back "- " (- (point) 2)))
233
(delete-char -2)
234
(delete-horizontal-space)
235
(insert "--")
236
(indent-according-to-mode))
237
(t
238
(smart-operator-insert "-"))))
239
240
(defun smart-operator-? ()
241
"See `smart-operator-insert'."
242
(interactive)
243
(cond ((memq major-mode '(c-mode c++-mode))
244
(smart-operator-insert "?"))
245
(t
246
(smart-operator-insert "?" t))))
247
248
(defun smart-operator-% ()
249
"See `smart-operator-insert'."
250
(interactive)
251
(cond ((and (memq major-mode '(c-mode c++-mode objc-mode)))
252
(insert "%"))
253
(t
254
(smart-operator-insert "%"))))
255
256
(provide 'smart-operator)
257
258
;;; smart-operator.el ends here
259
260