SmartOperator

Last major edit (later minor edits)

Changed:

< + ((and c-buffer-is-cc-mode (looking-back "[*/%+(><=&^|] *"))

to

> + ((and c-buffer-is-cc-mode (looking-back "[*/%+(><=&^|,] *"))

Changed:

< * "ioctl(fd, HPET_INFO, &info) -> "ioctl(fd, HPET_INFO, & info)

to

> * "ioctl(*fd, HPET_INFO, &info) -> "ioctl( * fd, HPET_INFO, & info)
> Fixed by the patch listed below
> --- extensions/smart-operator.el 2012-11-10 16:25:27.393138909 +0900
> +++ /home/adam/.emacs.d/site-lisp/extensions/smart-operator.el 2012-11-10 21:10:39.979202141 +0900
> @@ -244,6 +244,8 @@
> (smart-operator-insert "&" 'after))
> ((looking-back "= *")
> (smart-operator-insert "&" 'before))
> + ((looking-back ", *")
> + (smart-operator-insert "&" 'before))
> (t
> (smart-operator-insert "&"))))
> (t
> @@ -252,7 +254,8 @@
> (defun smart-operator-* ()
> "See `smart-operator-insert'."
> (interactive)
> - (cond (c-buffer-is-cc-mode
> + (cond ((and c-buffer-is-cc-mode
> + (not (smart-operator-document-line?)))
> ;; ,----
> ;; | a * b;
> ;; | char *a;
> @@ -265,9 +268,17 @@
> (smart-operator-insert "*" 'before))
> ((looking-back "\\* *")
> (smart-operator-insert "*" 'middle))
> - ((looking-back "^[ (]*")
> + ;; case foo(
> + ;; *bar);
> + ((looking-back "^[\\sc]*")
> (smart-operator-insert "*" 'middle)
> (indent-according-to-mode))
> + ;; case foo(*bar)
> + ((looking-back "(")
> + (smart-operator-insert "*" 'middle))
> + ;; case foo(bar, *bar)
> + ((looking-back ", *")
> + (smart-operator-insert "*" 'before))
> ((looking-back "= *")
> (smart-operator-insert "*" 'before))
> (t


the latest version can be found here: http://xwl.appspot.com/ref/smart-operator.el


smart-operator.el is a tool to automatically add spaces around operators on input.

For example:

  x=5

will become:

  x = 5 

I personally found the approach of modifying the local map uncomfortable. I’d rather have a minor mode instead, so I wrote this additional code:

  (defun smart-operator-self-insert-command (arg)
    "Insert the entered operator plus surrounding spaces."
    (interactive "p")
    (smart-operator-insert (string last-command-char)))
  (defvar smart-operator-mode-map
    (let ((keymap (make-sparse-keymap)))
      (define-key keymap "=" 'smart-operator-self-insert-command)
      (define-key keymap "+" 'smart-operator-self-insert-command)
      (define-key keymap "-" 'smart-operator-self-insert-command)
      (define-key keymap "/" 'smart-operator-self-insert-command)
      (define-key keymap "%" 'smart-operator-self-insert-command)
      (define-key keymap "&" 'smart-operator-self-insert-command)
      (define-key keymap "*" 'smart-operator-self-insert-command)
      (define-key keymap "!" 'smart-operator-self-insert-command)
      (define-key keymap "|" 'smart-operator-self-insert-command)
      (define-key keymap "<" 'smart-operator-self-insert-command)
      (define-key keymap ">" 'smart-operator-self-insert-command)
      (define-key keymap "," 'smart-operator-self-insert-command)
      (define-key keymap "." 'smart-operator-self-insert-command)
      (define-key keymap ":" 'smart-operator-self-insert-command)
      keymap)
    "Keymap used my `smart-operator-mode'.")
  (define-minor-mode smart-operator-mode
    "Insert operators packed with whitespaces smartly."
    nil " _=_" smart-operator-mode-map)

nschum

What does it mean “I wrote this additional code”. I looked in the linked source, and it defines a minor mode. The code looks exactly like what you provided here. Has smart-operator.el been updated to reflect your solution?

-DinoChiesa - 2011 October 18

Oh, I see now…. The header comments in that code give a mention to nschum for the suggestion to make it into a minor mode. So, anyone who is reading this – if you get the smart-operator.el module referenced above, it includes the code from nschum.

-DinoChiesa - 2011 Oct 18 (later)


fixed function name for ‘smart-operator-insert’; BTW remember this all needs a preceeding:

  (require 'smart-operator)

– ch2048

Nice extension but it is buggy with C/CC comments:

Fixed with the patch listed below

    --- a/smart-operator.el 2012-11-10 16:25:27.393138909 +0900
    +++ b/smart-operator.el 2012-11-10 18:22:18.281490742 +0900
    @@ -252,7 +253,8 @@
     (defun smart-operator-* ()
       "See `smart-operator-insert'."
       (interactive)
    -  (cond (c-buffer-is-cc-mode
    +  (cond ((and c-buffer-is-cc-mode
    +	      (not (smart-operator-document-line?)))
              ;; ,----
              ;; | a * b;
              ;; | char *a;
    @@ -360,6 +366,16 @@
                     (move-beginning-of-line nil)
                     (looking-at "#!")))
              (insert "/"))
    +	;; case /* hello */
    +	;; insert SPC before */ instread of SPC between * and /
    +	((and c-buffer-is-cc-mode
    +	      (smart-operator-document-line?))
    +	 (when (looking-back "[^\sc]+\\*")
    +	   (save-excursion
    +	     (backward-char 1)
    +	     (insert " "))
    +	   (smart-operator-insert "/" 'middle)
    +	   (indent-according-to-mode)))
             (t
              (smart-operator-insert "/"))))

– jcadam

more tests on this with all kinds of C/C++ operators:

Fixed this issue by this patch

    --- a/smart-operator.el 2012-11-10 16:25:27.393138909 +0900
    +++ b/smart-operator.el 2012-11-10 18:22:18.281490742 +0900
    @@ -307,6 +307,10 @@
                  (delete-horizontal-space)))
              (smart-operator-insert "-" 'middle)
              (indent-according-to-mode))
    +   ((and c-buffer-is-cc-mode (looking-back "[*/%+(><=&^|,] *"))
    +    (smart-operator-insert "-" 'before))
    +   ((and c-buffer-is-cc-mode (looking-back "\\(return\\) *"))
    +    (smart-operator-insert "-" 'before))
             (t
              (smart-operator-insert "-"))))

Fixed the problem by

    --- a/smart-operator.el 2012-11-10 16:25:27.393138909 +0900
    +++ b/smart-operator.el 2012-11-10 18:22:18.281490742 +0900
    @@ -57,6 +57,7 @@
         (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-self-insert-command)
         (define-key keymap ":" 'smart-operator-:)
         (define-key keymap "?" 'smart-operator-?)
    @@ -89,7 +90,7 @@
       (smart-operator-insert (string last-command-event)))
     
     (defvar smart-operator-list
    -  '("=" "<" ">" "%" "+" "-" "*" "/" "&" "|" "!" ":" "?" "," "."))
    +  '("=" "<" ">" "%" "+" "-" "*" "/" "&" "|" "^" "!" ":" "?" "," "."))

Fixed by the patch listed below

    --- a/smart-operator.el	2012-11-10 16:25:27.393138909 +0900
    +++ b/smart-operator.el	2012-11-10 21:10:39.979202141 +0900
    @@ -244,6 +244,8 @@
                     (smart-operator-insert "&" 'after))
                    ((looking-back "= *")
                     (smart-operator-insert "&" 'before))
    +	       ((looking-back ", *")
    +		(smart-operator-insert "&" 'before))
                    (t
                     (smart-operator-insert "&"))))
             (t
    @@ -252,7 +254,8 @@
     (defun smart-operator-* ()
       "See `smart-operator-insert'."
       (interactive)
    -  (cond (c-buffer-is-cc-mode
    +  (cond ((and c-buffer-is-cc-mode
    +	      (not (smart-operator-document-line?)))
              ;; ,----
              ;; | a * b;
              ;; | char *a;
    @@ -265,9 +268,17 @@
                     (smart-operator-insert "*" 'before))
                    ((looking-back "\\* *")
                     (smart-operator-insert "*" 'middle))
    -               ((looking-back "^[ (]*")
    +	       ;; case foo(
    +	       ;;          *bar);
    +               ((looking-back "^[\\sc]*")
                     (smart-operator-insert "*" 'middle)
                     (indent-according-to-mode))
    +	       ;; case foo(*bar)
    +               ((looking-back "(")
    +                (smart-operator-insert "*" 'middle))
    +	       ;; case foo(bar, *bar)
    +               ((looking-back ", *")
    +                (smart-operator-insert "*" 'before))
                    ((looking-back "= *")
                     (smart-operator-insert "*" 'before))
                    (t