By userofdrupal on
I don't like typing underscores in code in languages that use underscores heavily like php and python. I was trying to come up with a way to swap the underscore and dash keys in emacs when editing code . Couldn't figure out a solution I was happy with but recently I just came across this bit of lisp code that seems pretty cool. It intelligently decides whether to type a dash or underscore depending on the context.
The newest version is available at http://malsyned.net/smart-dash.html
Old version:
From http://paste.lisp.org/display/73509
smart-dash.el:
;; Smart-Dash minor mode
;; (C) 2008 Dennis Lambe Jr.
;; This is a simple minor mode which causes the dash key to insert an
;; underscore within C identifiers and a dash otherwise. This allows
;; you to type all_lowercase_c_identifiers as comfortably as you would
;; lisp-style-identifiers.
;;
;; While Smart-Dash mode is active, you can type "C-q -" or use the
;; dash on the numeric keypad to override it and insert a dash after a
;; C identifier character. You might need to do this if you want to
;; type a cramped-looking expression like x-5.
;;
;; If Smart-Dash mode is activated while in a C-like mode (c-mode,
;; c++-mode, and objc-mode by default, customizable with
;; SMART-DASH-C-MODES) it will also activate Smart-Dash-C mode, which
;; allows you to type "_>" and it will be translated to "->"
;; automatically so that struct pointer member access isn't made more
;; difficult by Smart-Dash mode's tendency to insert underscores at
;; the tail ends of identifiers whether you want it to or not.
(defcustom smart-dash-c-modes '(c-mode c++-mode objc-mode)
; Remove definition with (makunbound 'smart-dash-c-modes)
"List of major modes in which _> should be replaced by the ->
struct pointer member access operator")
(defun smart-dash-in-regular-code-p ()
(let* ((syntax-ppss (syntax-ppss))
(in-string (nth 3 syntax-ppss))
(in-comment (nth 4 syntax-ppss)))
(and (not in-string)
(not in-comment))))
(defun smart-dash-insert ()
"Insert an underscore following [A-Za-z0-9_], a dash otherwise."
(interactive)
(let* ((prev-char (char-before)))
(if (and (smart-dash-in-regular-code-p)
prev-char
(string-match "[A-Za-z0-9_]" (string prev-char)))
(insert ?_)
(insert ?-))))
(defun smart-dash-insert-dash ()
"Insert a dash regardless of the preceeding character."
(interactive)
(insert ?-))
(defun smart-dash-insert-gt ()
"Insert a greater-than symbol. If the preceeding character is
an underscore, replace it with a dash.
This behavior is desirable in order to make struct pointer member
access comfortable."
(interactive)
(let ((prev-char (char-before)))
(if (and (smart-dash-in-regular-code-p)
prev-char
(= prev-char ?_))
(progn
(delete-backward-char 1)
(insert "->"))
(insert ?>))))
;; I tried also mapping "_" to the inverse operation, but it made it
;; much more awkward to type double-underscored identifiers like
;; __attribute__. The default Emacs C-q escape works almost as well
;; and doesn't have nasty interactions with common cases.
;; <kp-subtract> on the numeric keypad can also be used to always
;; insert a dash.
(easy-mmode-defmap smart-dash-mode-keymap
; Remove definition with (makunbound 'smart-dash-mode-keymap)
`(("-" . smart-dash-insert)
,(cons (kbd "<kp-subtract>") 'smart-dash-insert-dash))
"Key map for `smart-dash-mode'")
(define-minor-mode smart-dash-mode
"Set the dash key to call insert-dash-or-underscore."
nil "" smart-dash-mode-keymap
(if (memq major-mode smart-dash-c-modes)
(if smart-dash-mode
(smart-dash-c-mode 1)
(smart-dash-c-mode 0))))
(easy-mmode-defmap smart-dash-c-mode-keymap
; Remove definition with (makunbound 'smart-dash-c-mode-keymap)
'((">" . smart-dash-insert-gt))
"Key map for smart-dash-mode when in a C-like major mode")
(define-minor-mode smart-dash-c-mode
"Set the > key to call smart-dash-insert-gt."
nil "" smart-dash-c-mode-keymap)
Comments
New version, new homepage
I'm the author of this code. I've made many improvements to this module since I posted it on #emacs for comments and suggestions a year ago.
The project is now hosted on bitbucket and has a homepage here: http://malsyned.net/smart-dash.html
I would appreciate it if you would replace this old code listing with a link to the project's new homepage. Especially since you're the top google result for "smart dash mode" right now.
Thanks!
Included to extras of Drupal + Emacs prj
Thank for this tool! I included it into a new Drupal + Emacs integration project.