From: William Xu Date: Sun, 13 Jul 2014 09:21:38 +0000 (+0800) Subject: electric-spacing.el: Refactor by following electric.el minor modes. X-Git-Url: https://code.delx.au/gnu-emacs-elpa/commitdiff_plain/7610e2434c0b123858070f5cfea89d8134017f54 electric-spacing.el: Refactor by following electric.el minor modes. --- diff --git a/packages/electric-spacing/electric-spacing.el b/packages/electric-spacing/electric-spacing.el index 68332dd44..fba04b679 100644 --- a/packages/electric-spacing/electric-spacing.el +++ b/packages/electric-spacing/electric-spacing.el @@ -1,10 +1,9 @@ -;;; smart-operator.el --- Insert operators with surrounding spaces smartly +;;; electric-spacing.el --- Insert operators with surrounding spaces smartly -;; Copyright (C) 2004, 2005, 2007-2013 Free Software Foundation, Inc. +;; Copyright (C) 2004, 2005, 2007-2014 Free Software Foundation, Inc. ;; Author: William Xu ;; 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 @@ -40,66 +39,75 @@ (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") +;;; electric-spacing minor mode + +(defcustom electric-spacing-double-space-docs t + "Enable double spacing of . in document lines - e,g, type '.' => get '. '." + :type 'boolean + :group 'electricity) + +(defcustom electric-spacing-docs t + "Enable electric-spacing in strings and comments." + :type 'boolean + :group 'electricity) + +(defvar electric-spacing-rules + '((?= . electric-spacing-self-insert-command) + (?< . electric-spacing-<) + (?> . electric-spacing->) + (?% . electric-spacing-%) + (?+ . electric-spacing-+) + (?- . electric-spacing--) + (?* . electric-spacing-*) + (?/ . electric-spacing-/) + (?& . electric-spacing-&) + (?| . electric-spacing-self-insert-command) + (?: . electric-spacing-:) + (?? . electric-spacing-?) + (?, . electric-spacing-\,) + (?~ . electric-spacing-~) + (?. . electric-spacing-.))) + +(defun electric-spacing-post-self-insert-function () + (when electric-spacing-mode + (let ((rule (cdr (assq last-command-event electric-spacing-rules)))) + (when rule + (goto-char (electric--after-char-pos)) + (delete-char -1) + (funcall rule))))) + +(add-hook 'post-self-insert-hook #'electric-spacing-post-self-insert-function) ;;;###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'." +(define-minor-mode electric-spacing-mode + "Toggle automatic surrounding space insertion (Electric Spacing mode). +With a prefix argument ARG, enable Electric Spacing mode if ARG is +positive, and disable it otherwise. If called from Lisp, enable +the mode if ARG is omitted or nil. + +This is a local minor mode. When enabled, typing an operator automatically +inserts surrounding spaces. e.g., `=' becomes ` = ',`+=' becomes ` += '. This +is very handy for many programming languages." + :global nil + :group 'electricity + :lighter " _+_") + +(defun electric-spacing-self-insert-command () + "Insert character with surrounding spaces." + (electric-spacing-insert (string last-command-event))) + +(defun electric-spacing-insert (op &optional only-where) + "See `electric-spacing-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)) + (cond ((and (electric-spacing-lispy-mode?) + (not (electric-spacing-document?))) + (electric-spacing-lispy op)) + ((not electric-spacing-docs) + (electric-spacing-insert-1 op 'middle)) (t - (smart-operator-insert-1 op only-where)))) + (electric-spacing-insert-1 op only-where)))) -(defun smart-operator-insert-1 (op &optional only-where) +(defun electric-spacing-insert-1 (op &optional only-where) "Insert operator OP with surrounding spaces. e.g., `=' becomes ` = ', `+=' becomes ` += '. @@ -112,7 +120,9 @@ when `only-where' is 'middle, we will not insert space." (`after (insert op " ")) (_ (let ((begin? (bolp))) - (unless (or (looking-back (regexp-opt smart-operator-list) + (unless (or (looking-back (regexp-opt + (mapcar 'char-to-string + (mapcar 'car electric-spacing-rules))) (line-beginning-position)) begin?) (insert " ")) @@ -120,19 +130,19 @@ when `only-where' is 'middle, we will not insert space." (when begin? (indent-according-to-mode)))))) -(defun smart-operator-c-types () +(defun electric-spacing-c-types () (concat c-primitive-type-key "?")) -(defun smart-operator-document-line? () - (memq (syntax-ppss-context (syntax-ppss)) '(comment string))) +(defun electric-spacing-document? () + (nth 8 (syntax-ppss))) -(defun smart-operator-lispy-mode? () - (memq major-mode '(emacs-lisp-mode - lisp-mode - lisp-interaction-mode - scheme-mode))) +(defun electric-spacing-lispy-mode? () + (derived-mode-p 'emacs-lisp-mode + 'lisp-mode + 'lisp-interaction-mode + 'scheme-mode)) -(defun smart-operator-lispy (op) +(defun electric-spacing-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." @@ -141,84 +151,79 @@ so let's not get too insert-happy." (backward-char 1) (looking-at "(")) (if (equal op ",") - (smart-operator-insert-1 op 'middle) - (smart-operator-insert-1 op 'after))) + (electric-spacing-insert-1 op 'middle) + (electric-spacing-insert-1 op 'after))) ((equal op ",") - (smart-operator-insert-1 op 'before)) + (electric-spacing-insert-1 op 'before)) (t - (smart-operator-insert-1 op 'middle)))) + (electric-spacing-insert-1 op 'middle)))) ;;; Fine Tunings -(defun smart-operator-< () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-< () + "See `electric-spacing-insert'." (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" + "multimap" "set" "hash_map" "iterator" "template" + "pair" "auto_ptr" "static_cast" + "dynmaic_cast" "const_cast" "reintepret_cast" - "#import")) + "#import")) "\\)\\ *") (line-beginning-position))) - (eq major-mode 'sgml-mode)) + (derived-mode-p 'sgml-mode)) (insert "<>") (backward-char)) (t - (smart-operator-insert "<")))) + (electric-spacing-insert "<")))) -(defun smart-operator-: () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-: () + "See `electric-spacing-insert'." (cond (c-buffer-is-cc-mode (if (looking-back "\\?.+") - (smart-operator-insert ":") - (smart-operator-insert ":" 'middle))) - ((memq major-mode '(haskell-mode)) - (smart-operator-insert ":")) + (electric-spacing-insert ":") + (electric-spacing-insert ":" 'middle))) + ((derived-mode-p 'haskell-mode) + (electric-spacing-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) + (electric-spacing-insert ":" 'after)))) + +(defun electric-spacing-\, () + "See `electric-spacing-insert'." + (electric-spacing-insert "," 'after)) + +(defun electric-spacing-. () + "See `electric-spacing-insert'." + (cond ((and electric-spacing-double-space-docs + (electric-spacing-document?)) + (electric-spacing-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)) + (derived-mode-p 'python-mode 'ruby-mode) (looking-back "[a-z\)]")) (and - (memq major-mode '(js-mode js2-mode)) + (derived-mode-p 'js-mode 'js2-mode) (looking-back "[a-z\)$]")))) - (insert ".")) - ((memq major-mode '(cperl-mode perl-mode ruby-mode)) + (insert ".")) + ((derived-mode-p 'cperl-mode 'perl-mode 'ruby-mode) ;; Check for the .. range operator (if (looking-back ".") - (insert ".") + (insert ".") (insert " . "))) (t - (smart-operator-insert "." 'after) + (electric-spacing-insert "." 'after) (insert " ")))) -(defun smart-operator-& () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-& () + "See `electric-spacing-insert'." (cond (c-buffer-is-cc-mode ;; ,----[ cases ] ;; | char &a = b; // FIXME @@ -227,18 +232,17 @@ so let's not get too insert-happy." ;; | int c = a & b; ;; | a && b; ;; `---- - (cond ((looking-back (concat (smart-operator-c-types) " *" )) - (smart-operator-insert "&" 'after)) + (cond ((looking-back (concat (electric-spacing-c-types) " *" )) + (electric-spacing-insert "&" 'after)) ((looking-back "= *") - (smart-operator-insert "&" 'before)) + (electric-spacing-insert "&" 'before)) (t - (smart-operator-insert "&")))) + (electric-spacing-insert "&")))) (t - (smart-operator-insert "&")))) + (electric-spacing-insert "&")))) -(defun smart-operator-* () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-* () + "See `electric-spacing-insert'." (cond (c-buffer-is-cc-mode ;; ,---- ;; | a * b; @@ -248,66 +252,61 @@ so let's not get too insert-happy." ;; | *p++; ;; | *a = *b; ;; `---- - (cond ((looking-back (concat (smart-operator-c-types) " *" )) - (smart-operator-insert "*" 'before)) + (cond ((looking-back (concat (electric-spacing-c-types) " *" )) + (electric-spacing-insert "*" 'before)) ((looking-back "\\* *") - (smart-operator-insert "*" 'middle)) + (electric-spacing-insert "*" 'middle)) ((looking-back "^[ (]*") - (smart-operator-insert "*" 'middle) + (electric-spacing-insert "*" 'middle) (indent-according-to-mode)) ((looking-back "= *") - (smart-operator-insert "*" 'before)) + (electric-spacing-insert "*" 'before)) (t - (smart-operator-insert "*")))) + (electric-spacing-insert "*")))) (t - (smart-operator-insert "*")))) + (electric-spacing-insert "*")))) -(defun smart-operator-> () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-> () + "See `electric-spacing-insert'." (cond ((and c-buffer-is-cc-mode (looking-back " - ")) (delete-char -3) (insert "->")) (t - (smart-operator-insert ">")))) + (electric-spacing-insert ">")))) -(defun smart-operator-+ () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-+ () + "See `electric-spacing-insert'." (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) + (electric-spacing-insert "+" 'middle) (indent-according-to-mode)) (t - (smart-operator-insert "+")))) + (electric-spacing-insert "+")))) -(defun smart-operator-- () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-- () + "See `electric-spacing-insert'." (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) + (electric-spacing-insert "-" 'middle) (indent-according-to-mode)) (t - (smart-operator-insert "-")))) + (electric-spacing-insert "-")))) -(defun smart-operator-? () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-? () + "See `electric-spacing-insert'." (cond (c-buffer-is-cc-mode - (smart-operator-insert "?")) + (electric-spacing-insert "?")) (t - (smart-operator-insert "?" 'after)))) + (electric-spacing-insert "?" 'after)))) -(defun smart-operator-% () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-% () + "See `electric-spacing-insert'." (cond (c-buffer-is-cc-mode ;; ,---- ;; | a % b; @@ -316,20 +315,19 @@ so let's not get too insert-happy." (if (and (looking-back "\".*") (not (looking-back "\",.*"))) (insert "%") - (smart-operator-insert "%"))) + (electric-spacing-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 "%")) + ((and (derived-mode-p 'python-mode) + (electric-spacing-document?)) + (insert "%")) (t - (smart-operator-insert "%")))) + (electric-spacing-insert "%")))) -(defun smart-operator-~ () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-~ () + "See `electric-spacing-insert'." ;; First class regex operator =~ langs - (cond ((memq major-mode '(ruby-mode perl-mode cperl-mode)) + (cond ((derived-mode-p 'ruby-mode 'perl-mode 'cperl-mode) (if (looking-back "= ") (progn (delete-char -2) @@ -338,9 +336,8 @@ so let's not get too insert-happy." (t (insert "~")))) -(defun smart-operator-/ () - "See `smart-operator-insert'." - (interactive) +(defun electric-spacing-/ () + "See `electric-spacing-insert'." ;; *nix shebangs #! (cond ((and (eq 1 (line-number-at-pos)) (save-excursion @@ -348,8 +345,8 @@ so let's not get too insert-happy." (looking-at "#!"))) (insert "/")) (t - (smart-operator-insert "/")))) + (electric-spacing-insert "/")))) -(provide 'smart-operator) +(provide 'electric-spacing) -;;; smart-operator.el ends here +;;; electric-spacing.el ends here