[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ELPA-diffs] /srv/bzr/emacs/elpa r263: Add smart-operator.
From: |
Stefan Monnier |
Subject: |
[ELPA-diffs] /srv/bzr/emacs/elpa r263: Add smart-operator. |
Date: |
Sat, 06 Oct 2012 13:51:11 -0400 |
User-agent: |
Bazaar (2.5.0) |
------------------------------------------------------------
revno: 263 [merge]
author: William Xu <address@hidden>
committer: Stefan Monnier <address@hidden>
branch nick: elpa
timestamp: Sat 2012-10-06 13:51:11 -0400
message:
Add smart-operator.
added:
packages/smart-operator/
packages/smart-operator/smart-operator.el
=== added directory 'packages/smart-operator'
=== added file 'packages/smart-operator/smart-operator.el'
--- a/packages/smart-operator/smart-operator.el 1970-01-01 00:00:00 +0000
+++ b/packages/smart-operator/smart-operator.el 2012-10-06 17:51:11 +0000
@@ -0,0 +1,358 @@
+;;; smart-operator.el --- Insert operators with surrounding spaces smartly
+
+;; Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012 William Xu
+
+;; Author: William Xu <address@hidden>
+;; Version: 4.0
+;; Url: http://xwl.appspot.com/ref/smart-operator.el
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with EMMS; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This extension tries to insert operators with surrounding spaces smartly.
+;; e.g., `=' becomes ` = ', `+=' becomes ` += '. This is handy for writing
+;; C-style sources.
+
+;; To use, put this file to your load-path and the following to your
+;; ~/.emacs:
+;; (require 'smart-operator)
+;;
+;; Then `M-x smart-operator-mode' for toggling this minor mode.
+
+;;; Acknowledgements
+
+;; Nikolaj Schumacher <address@hidden>, for suggesting
+;; reimplementing as a minor mode and providing an initial patch for
+;; that.
+
+;;; Code:
+
+(require 'cc-mode)
+
+;;; smart-operator minor mode
+
+(defvar smart-operator-mode-map
+ (let ((keymap (make-sparse-keymap)))
+ (define-key keymap "=" 'smart-operator-self-insert-command)
+ (define-key keymap "<" 'smart-operator-<)
+ (define-key keymap ">" 'smart-operator->)
+ (define-key keymap "%" 'smart-operator-%)
+ (define-key keymap "+" 'smart-operator-+)
+ (define-key keymap "-" 'smart-operator--)
+ (define-key keymap "*" 'smart-operator-*)
+ (define-key keymap "/" 'smart-operator-/)
+ (define-key keymap "&" 'smart-operator-&)
+ (define-key keymap "|" 'smart-operator-self-insert-command)
+ ;; (define-key keymap "!" 'smart-operator-self-insert-command)
+ (define-key keymap ":" 'smart-operator-:)
+ (define-key keymap "?" 'smart-operator-?)
+ (define-key keymap "," 'smart-operator-\,)
+ (define-key keymap "~" 'smart-operator-~)
+ (define-key keymap "." 'smart-operator-.)
+ keymap)
+ "Keymap used my `smart-operator-mode'.")
+
+(defvar smart-operator-double-space-docs t
+ "Enable double spacing of . in document lines - e,g, type '.' => get '. '")
+
+(defvar smart-operator-docs t
+ "Enable smart-operator in strings and comments")
+
+;;;###autoload
+(define-minor-mode smart-operator-mode
+ "Insert operators with surrounding spaces smartly."
+ nil " _+_" smart-operator-mode-map)
+
+;;;###autoload
+(defun smart-operator-mode-on ()
+ "Turn on `smart-operator-mode'. "
+ (smart-operator-mode 1))
+
+;;;###autoload
+(defun smart-operator-self-insert-command (arg)
+ "Insert the entered operator plus surrounding spaces."
+ (interactive "p")
+ (smart-operator-insert (string last-command-event)))
+
+(defvar smart-operator-list
+ '("=" "<" ">" "%" "+" "-" "*" "/" "&" "|" "!" ":" "?" "," "."))
+
+(defun smart-operator-insert (op &optional only-where)
+ "See `smart-operator-insert-1'."
+ (delete-horizontal-space)
+ (cond ((and (smart-operator-lispy-mode?)
+ (not (smart-operator-document-line?)))
+ (smart-operator-lispy op))
+ ((not smart-operator-docs)
+ (smart-operator-insert-1 op 'middle))
+ (t
+ (smart-operator-insert-1 op only-where))))
+
+(defun smart-operator-insert-1 (op &optional only-where)
+ "Insert operator OP with surrounding spaces.
+e.g., `=' becomes ` = ', `+=' becomes ` += '.
+
+When `only-where' is 'after, we will insert space at back only;
+when `only-where' is 'before, we will insert space at front only;
+when `only-where' is 'middle, we will not insert space."
+ (case only-where
+ ((before) (insert " " op))
+ ((middle) (insert op))
+ ((after) (insert op " "))
+ (t
+ (let ((begin? (bolp)))
+ (unless (or (looking-back (regexp-opt smart-operator-list)
+ (line-beginning-position))
+ begin?)
+ (insert " "))
+ (insert op " ")
+ (when begin?
+ (indent-according-to-mode))))))
+
+(defun smart-operator-c-types ()
+ (concat c-primitive-type-key "?"))
+
+(defun smart-operator-document-line? ()
+ (memq (syntax-ppss-context (syntax-ppss)) '(comment string)))
+
+(defun smart-operator-lispy-mode? ()
+ (memq major-mode '(emacs-lisp-mode
+ lisp-mode
+ lisp-interaction-mode
+ scheme-mode)))
+
+(defun smart-operator-lispy (op)
+ "We're in a Lisp-ish mode, so let's look for parenthesis.
+Meanwhile, if not found after ( operators are more likely to be function names,
+so let's not get too insert-happy."
+ (cond
+ ((save-excursion
+ (backward-char 1)
+ (looking-at "("))
+ (if (equal op ",")
+ (smart-operator-insert-1 op 'middle)
+ (smart-operator-insert-1 op 'after)))
+ ((equal op ",")
+ (smart-operator-insert-1 op 'before))
+ (t
+ (smart-operator-insert-1 op 'middle))))
+
+
+;;; Fine Tunings
+
+(defun smart-operator-< ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (cond
+ ((or (and c-buffer-is-cc-mode
+ (looking-back
+ (concat "\\("
+ (regexp-opt
+ '("#include" "vector" "deque" "list" "map" "stack"
+ "multimap" "set" "hash_map" "iterator" "template"
+ "pair" "auto_ptr" "static_cast"
+ "dynmaic_cast" "const_cast" "reintepret_cast"
+
+ "#import"))
+ "\\)\\ *")
+ (line-beginning-position)))
+ (eq major-mode 'sgml-mode))
+ (insert "<>")
+ (backward-char))
+ (t
+ (smart-operator-insert "<"))))
+
+(defun smart-operator-: ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (cond (c-buffer-is-cc-mode
+ (if (looking-back "\\?.+")
+ (smart-operator-insert ":")
+ (smart-operator-insert ":" 'middle)))
+ ((memq major-mode '(haskell-mode))
+ (smart-operator-insert ":"))
+ (t
+ (smart-operator-insert ":" 'after))))
+
+(defun smart-operator-\, ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (smart-operator-insert "," 'after))
+
+(defun smart-operator-. ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (cond ((and smart-operator-double-space-docs
+ (smart-operator-document-line?))
+ (smart-operator-insert "." 'after)
+ (insert " "))
+ ((or (looking-back "[0-9]")
+ (or (and c-buffer-is-cc-mode
+ (looking-back "[a-z]"))
+ (and
+ (memq major-mode '(python-mode ruby-mode))
+ (looking-back "[a-z\)]"))
+ (and
+ (memq major-mode '(js-mode js2-mode))
+ (looking-back "[a-z\)$]"))))
+ (insert "."))
+ ((memq major-mode '(cperl-mode perl-mode ruby-mode))
+ ;; Check for the .. range operator
+ (if (looking-back ".")
+ (insert ".")
+ (insert " . ")))
+ (t
+ (smart-operator-insert "." 'after)
+ (insert " "))))
+
+(defun smart-operator-& ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (cond (c-buffer-is-cc-mode
+ ;; ,----[ cases ]
+ ;; | char &a = b; // FIXME
+ ;; | void foo(const int& a);
+ ;; | char *a = &b;
+ ;; | int c = a & b;
+ ;; | a && b;
+ ;; `----
+ (cond ((looking-back (concat (smart-operator-c-types) " *" ))
+ (smart-operator-insert "&" 'after))
+ ((looking-back "= *")
+ (smart-operator-insert "&" 'before))
+ (t
+ (smart-operator-insert "&"))))
+ (t
+ (smart-operator-insert "&"))))
+
+(defun smart-operator-* ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (cond (c-buffer-is-cc-mode
+ ;; ,----
+ ;; | a * b;
+ ;; | char *a;
+ ;; | char **b;
+ ;; | (*a)->func();
+ ;; | *p++;
+ ;; | *a = *b;
+ ;; `----
+ (cond ((looking-back (concat (smart-operator-c-types) " *" ))
+ (smart-operator-insert "*" 'before))
+ ((looking-back "\\* *")
+ (smart-operator-insert "*" 'middle))
+ ((looking-back "^[ (]*")
+ (smart-operator-insert "*" 'middle)
+ (indent-according-to-mode))
+ ((looking-back "= *")
+ (smart-operator-insert "*" 'before))
+ (t
+ (smart-operator-insert "*"))))
+ (t
+ (smart-operator-insert "*"))))
+
+(defun smart-operator-> ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (cond ((and c-buffer-is-cc-mode (looking-back " - "))
+ (delete-char -3)
+ (insert "->"))
+ (t
+ (smart-operator-insert ">"))))
+
+(defun smart-operator-+ ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (cond ((and c-buffer-is-cc-mode (looking-back "\\+ *"))
+ (when (looking-back "[a-zA-Z0-9_] +\\+ *")
+ (save-excursion
+ (backward-char 2)
+ (delete-horizontal-space)))
+ (smart-operator-insert "+" 'middle)
+ (indent-according-to-mode))
+ (t
+ (smart-operator-insert "+"))))
+
+(defun smart-operator-- ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (cond ((and c-buffer-is-cc-mode (looking-back "\\- *"))
+ (when (looking-back "[a-zA-Z0-9_] +\\- *")
+ (save-excursion
+ (backward-char 2)
+ (delete-horizontal-space)))
+ (smart-operator-insert "-" 'middle)
+ (indent-according-to-mode))
+ (t
+ (smart-operator-insert "-"))))
+
+(defun smart-operator-? ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (cond (c-buffer-is-cc-mode
+ (smart-operator-insert "?"))
+ (t
+ (smart-operator-insert "?" 'after))))
+
+(defun smart-operator-% ()
+ "See `smart-operator-insert'."
+ (interactive)
+ (cond (c-buffer-is-cc-mode
+ ;; ,----
+ ;; | a % b;
+ ;; | printf("%d %d\n", a % b);
+ ;; `----
+ (if (and (looking-back "\".*")
+ (not (looking-back "\",.*")))
+ (insert "%")
+ (smart-operator-insert "%")))
+ ;; If this is a comment or string, we most likely
+ ;; want no spaces - probably string formatting
+ ((and (memq major-mode '(python-mode))
+ (smart-operator-document-line?))
+ (insert "%"))
+ (t
+ (smart-operator-insert "%"))))
+
+(defun smart-operator-~ ()
+ "See `smart-operator-insert'."
+ (interactive)
+ ;; First class regex operator =~ langs
+ (cond ((memq major-mode '(ruby-mode perl-mode cperl-mode))
+ (if (looking-back "= ")
+ (progn
+ (delete-char -2)
+ (insert "=~ "))
+ (insert "~")))
+ (t
+ (insert "~"))))
+
+(defun smart-operator-/ ()
+ "See `smart-operator-insert'."
+ (interactive)
+ ;; *nix shebangs #!
+ (cond ((and (eq 1 (line-number-at-pos))
+ (save-excursion
+ (move-beginning-of-line nil)
+ (looking-at "#!")))
+ (insert "/"))
+ (t
+ (smart-operator-insert "/"))))
+
+(provide 'smart-operator)
+
+;;; smart-operator.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [ELPA-diffs] /srv/bzr/emacs/elpa r263: Add smart-operator.,
Stefan Monnier <=