Magic emacs bindings for dabbrev-expand and TAB indentation.

I use emacs for all my text editing.  When editing code, I also like to use dabbrev-expand, but I find the default binding of C-M-/ really hard to press and remember.  I’m used to TAB expanding everything.

But, I also want TAB to indent the current line according to the current mode.  So, here’s a best of both worlds solution:

(defun virtual-beginning-of-line ()
  "Returns 't if there is nothing more than whitespace between
   point and the beginning of the line"
  (interactive)
  (let ((startpos (point))
        (matchpos 0)
        )
    (save-excursion
      (beginning-of-line)
      (setq matchpos (search-forward-regexp "[ \t]*" startpos 't))
      (if (<= startpos matchpos)
          't
        nil))))

(defun virtual-end-of-line ()
  "Returns 't if there is nothing more than whitespace between
   point and the end of the line"
  (interactive)
  (let ((matchpos 0)
        (lep (line-end-position)))
    (save-excursion
      (setq matchpos (search-forward-regexp "[ \t]+" lep 't))
      (if matchpos
          (if (= matchpos lep)
              't
            nil)
        't))))

(defun smart-tab ()
  (interactive)
  (if (virtual-end-of-line)
      (delete-horizontal-space))
  (if (virtual-beginning-of-line)
      (c-indent-command)
    (if (virtual-end-of-line) (dabbrev-expand 'nil))))

Then, in any mode you’d like, just do something like this:

(local-set-key [tab] 'smart-tab)
This entry was posted in General. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>