Path: blob/master/elisp/emacs-for-python/plugins/smart-operator.el
990 views
;;; smart-operator.el --- Insert operators with surrounding spaces smartly12;; Copyright (C) 2004, 2005, 2007, 2008, 2009 William Xu34;; Author: William Xu <[email protected]>5;; Version: 1.16;; Url: http://xwl.appspot.com/ref/smart-operator.el78;; This program is free software; you can redistribute it and/or modify9;; it under the terms of the GNU General Public License as published by10;; the Free Software Foundation; either version 3, or (at your option)11;; any later version.1213;; This program is distributed in the hope that it will be useful, but14;; WITHOUT ANY WARRANTY; without even the implied warranty of15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU16;; General Public License for more details.1718;; You should have received a copy of the GNU General Public License19;; along with EMMS; see the file COPYING. If not, write to the20;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,21;; Boston, MA 02110-1301, USA.2223;;; Commentary:2425;; When typing operators, this package can automatically insert spaces26;; before and after operators. For instance, `=' will become ` = ', `+='27;; will become ` += '. This is handy for writing C-style sources.2829;; To use, put this file to your load-path and the following to your30;; ~/.emacs:31;; (require 'smart-operator)32;;33;; Then `M-x smart-operator-mode' for toggling this minor mode.3435;; Usage Tips36;; ----------3738;; - If you want it to insert operator with surrounding spaces , you'd39;; better not type the front space yourself, instead, type operator40;; directly. smart-operator-mode will also take this as a hint on how41;; to properly insert spaces in some specific occasions. For42;; example, in c-mode, `a*' -> `a * ', `char *' -> `char *'.4344;;; Acknowledgements4546;; Nikolaj Schumacher <[email protected]>, for suggesting47;; reimplementing as a minor mode and providing an initial patch for48;; that.4950;;; TODO:5152;; - for c mode, probably it would be much better doing this in cc-mode.5354;;; Code:5556;;; smart-operator minor mode5758(defvar smart-operator-mode-map59(let ((keymap (make-sparse-keymap)))60(define-key keymap "=" 'smart-operator-self-insert-command)61(define-key keymap "<" 'smart-operator-<)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-self-insert-command)68(define-key keymap "&" 'smart-operator-&)69(define-key keymap "|" 'smart-operator-self-insert-command)70;; (define-key keymap "!" 'smart-operator-self-insert-command)71(define-key keymap ":" 'smart-operator-:)72(define-key keymap "?" 'smart-operator-?)73(define-key keymap "," 'smart-operator-,)74(define-key keymap "." 'smart-operator-.)75keymap)76"Keymap used my `smart-operator-mode'.")7778;;;###autoload79(define-minor-mode smart-operator-mode80"Insert operators with surrounding spaces smartly."81nil " _+_" smart-operator-mode-map)8283(defun smart-operator-mode-on ()84(smart-operator-mode 1))8586;;;###autoload87(defun smart-operator-self-insert-command (arg)88"Insert the entered operator plus surrounding spaces."89(interactive "p")90(smart-operator-insert (string last-command-event)))9192(defvar smart-operator-list93'("=" "<" ">" "%" "+" "-" "*" "/" "&" "|" "!" ":" "?" "," "."))9495(defun smart-operator-insert (op &optional only-after)96"Insert operator OP with surrounding spaces.97e.g., `=' will become ` = ', `+=' will become ` += '.9899When ONLY-AFTER, insert space at back only."100(delete-horizontal-space)101(if (or (looking-back (regexp-opt smart-operator-list)102(save-excursion (beginning-of-line)103(point)))104only-after105(bolp))106(progn (insert (concat op " "))107(save-excursion108(backward-char 2)109(when (bolp)110(indent-according-to-mode))))111(insert (concat " " op " "))))112113(defun smart-operator-bol ()114(save-excursion115(beginning-of-line)116(point)))117118(if (fboundp 'python-comment-line-p)119(defalias 'smart-operator-comment-line-p 'python-comment-line-p)120(defun smart-operator-comment-line-p ()121"Return non-nil if and only if current line has only a comment."122(save-excursion123(end-of-line)124(when (eq 'comment (syntax-ppss-context (syntax-ppss)))125(back-to-indentation)126(looking-at (rx (or (syntax comment-start) line-end))))))127)128129130;;; Fine Tunings131132(defun smart-operator-< ()133"See `smart-operator-insert'."134(interactive)135(cond ((and (memq major-mode '(c-mode c++-mode objc-mode))136(looking-back137(concat "\\("138(regexp-opt139(append140'("#include" "vector" "deque" "list" "map" "stack"141"multimap" "set" "hash_map" "iterator" "template"142"pair" "auto_ptr" "static_cast"143"dynmaic_cast" "const_cast" "reintepret_cast")144'("#import")))145"\\)\\ *")146(smart-operator-bol)))147(insert "<>")148(backward-char))149((eq major-mode 'sgml-mode)150(insert "<>")151(backward-char))152(t153(smart-operator-insert "<"))))154155(defun smart-operator-: ()156"See `smart-operator-insert'."157(interactive)158(cond ((memq major-mode '(c-mode c++-mode))159(if (looking-back "\\?.+" (smart-operator-bol))160(smart-operator-insert ":")161(insert ":")))162(t163(smart-operator-insert ":" t))))164165(defun smart-operator-, ()166"See `smart-operator-insert'."167(interactive)168(smart-operator-insert "," t))169170(defun smart-operator-. ()171"See `smart-operator-insert'."172(interactive)173(cond ((smart-operator-comment-line-p)174(smart-operator-insert "." t)175(insert " "))176((or (looking-back "[0-9]" (1- (point)))177(and (memq major-mode '(c-mode c++-mode python-mode))178(looking-back "[a-z]" (1- (point)))))179(insert "."))180((memq major-mode '(cperl-mode perl-mode))181(insert " . "))182(t183(smart-operator-insert "." t)184(insert " "))))185186(defun smart-operator-& ()187"See `smart-operator-insert'."188(interactive)189(cond ((memq major-mode '(c-mode c++-mode))190(insert "&"))191(t192(smart-operator-insert "&"))))193194(defun smart-operator-* ()195"See `smart-operator-insert'."196(interactive)197(cond ((memq major-mode '(c-mode c++-mode objc-mode))198(if (or (looking-back "[0-9a-zA-Z]" (1- (point)))199(bolp))200(smart-operator-insert "*")201(insert "*")))202(t203(smart-operator-insert "*"))))204205(defun smart-operator-> ()206"See `smart-operator-insert'."207(interactive)208(cond ((and (memq major-mode '(c-mode c++-mode))209(looking-back " - " (- (point) 3)))210(delete-char -3)211(insert "->"))212(t213(smart-operator-insert ">"))))214215(defun smart-operator-+ ()216"See `smart-operator-insert'."217(interactive)218(cond ((and (memq major-mode '(c-mode c++-mode))219(looking-back "+ " (- (point) 2)))220(delete-char -2)221;; (delete-horizontal-space)222(insert "++")223(indent-according-to-mode))224(t225(smart-operator-insert "+"))))226227(defun smart-operator-- ()228"See `smart-operator-insert'."229(interactive)230(cond ((and (memq major-mode '(c-mode c++-mode))231(looking-back "- " (- (point) 2)))232(delete-char -2)233(delete-horizontal-space)234(insert "--")235(indent-according-to-mode))236(t237(smart-operator-insert "-"))))238239(defun smart-operator-? ()240"See `smart-operator-insert'."241(interactive)242(cond ((memq major-mode '(c-mode c++-mode))243(smart-operator-insert "?"))244(t245(smart-operator-insert "?" t))))246247(defun smart-operator-% ()248"See `smart-operator-insert'."249(interactive)250(cond ((and (memq major-mode '(c-mode c++-mode objc-mode)))251(insert "%"))252(t253(smart-operator-insert "%"))))254255(provide 'smart-operator)256257;;; smart-operator.el ends here258259260