Posts Tagged ‘dabbrev’

When writing a muse file it always annoyed me when I have written (for example) a-really-long-variable somewhere else in the file and then when I type =a-rea and press M-/ it fails to expand.

The way to fix this behaviour is by setting dabbrev-abbrev-skip-leading-regexp

(setq dabbrev-abbrev-skip-leading-regexp "[=*]")

(Edit: fixed the first regex per Billy’s comment below. Thanks)

Okay, you think, this doesn’t affect me – I don’t use muse (why not?) How about if you’re writing some html/xml.

(setq dabbrev-abbrev-skip-leading-regexp "[^ ]*[<>=*]")

Now <strong>long-word- completes as you would expect.

There is also dabbrev-abbrev-char-regexp if you want even more control over what should be considered a match.

Also, I’m no longer using autocomplete as I find vanilla dabbrev nicer to use.

Read Full Post »

A few weeks ago when I was talking about autocomplete and dabbrevone of my commenters asked if I had tried hippie-expand. My response was no, but I should take a look as it might allow me to input buffer names more quickly which is something I often need to do.

Following the recipe from the emacs wiki, I tried this:

(global-set-key [(meta f5)] (make-hippie-expand-function
                               try-complete-file-name) t))

After some experimentation, the limitation is obvious. I usually want to complete the entire filename including the path but I can’t remember what the path begins with.

The next thing I thought about was removing *Messages* and *Buffer List* from dabbrev-ignored-buffer-names. Unfortunately, I still need to complete from the beginning of the path but this is generally useful so I’m going to keep it. Really, I want to be able to select any part of the filename and complete from that. Sounds like a job for ido.

First I need a method that returns all buffer names and filenames.

(defun get-files-and-buffers ()
  (let ((res '()))
    (dolist (buffer (buffer-list) res)
      (let ((buffername (buffer-name buffer))
            (filename (buffer-file-name buffer)))
        (unless (string-match "^ *\\*.*\\*$" buffername)
          (push buffername res))
        (when filename (push filename res))))))

Then I can use ido to select between them which is perfect.

(defun insert-file-or-buffer-name (&optional initial)
  (let ((name (ido-completing-read "File/Buffer Name: "
                                   nil nil initial)))
    (when (and (stringp name) (> (length name) 0))
      (insert name))))

(global-set-key (kbd "<f2> i b") 'insert-file-or-buffer-name)

Read Full Post »

Emacs-fu Emacs Tips

Emacs-fu started a great post requesting little tricks. I gave my own response, covering cut-and-paste, ido mode, uniquify and tidy backups. Da Zhang has a nice summary of some of the other tips.

Using/Extending Core Libraries

There are a few emacs libraries that store current state in global variables. For example, ido stores the list of current matches in ido-matches. Accessing this variable while filtering using ido can be a little convoluted. I gave an example of how to do this in Shell Command on Multiple Buffers.

Dabbrev also uses global variables although it provides [internal] functions for completing an abbreviation. I have a complete example at Autocomplete with a Dabbrev Twist but the core is very simple:

(let ((dabbrev-check-all-buffers t))
  (dabbrev--find-all-expansions <abbreviation> t))

Multi-file Search/Replace

I really liked this post from Ian Eure demonstrating how to do multi-file search and replace in emacs. I frequently see emacs proponents saying its awesome and you’ll know when you reach emacs nirvana so it is nice to see a practical demonstration of emacs power. And of course I know it is possible in shell but the simplicity and the interactive nature of emacs makes this a much more pleasant experience. A quick summary:

  • M-x find-grep-dired RET <pattern> (put matching files in dired buffer)
  • m .php$ RET (mark all php files)
  • Q <pattern> RET <replace string> (run query-replace on marked files)
  • C-x s (save all modified files)

Emacs Popularity

So first of all I found this post referring to a thread where a guy says he recommends nano as he has used Unix-like systems that don’t have vi. Hmmm… okay, and then that post has this one from 2007 in the auto-generated links list about Emacs losing in popularity.

And from there I get to this one which has a poll where 56% of the almost 750 respondants chose vim1 as their favourite Linux text editor compared to 9% choosing emacs. Of course it is a highly unscientific result, but do you think more than 6 times as many people use vim as emacs?

1. Fair enough – it is a fine editor

Read Full Post »

I briefly mentioned dabbrev expand in one of my interesting links posts when I noted a post that was covering auto-complete.el. Dabbrev expand is a great little feature of emacs. With one keychord, you can expand text using any match from any buffer that you have opened. Until now, I haven’t particularly wanted more.

However, now it is time to move to auto-complete. It’s nice to get feedback about potential completions. In the linked post, it states that auto-complete is just a framework and it needs quite a bit of tweaking to get the behaviour I want.

The primary thing I want to fix is that by default it only uses completions from the current buffer. I like completion to use all open buffers as dabbrev does by default. I thought that it would be easy to add this by setting ac-sources to ac-source-words-in-all-buffer.

(setq-default ac-sources '(ac-source-words-in-all-buffer))

Unfortunately, that isn’t come close to what I want. There is also an extension called ac-dabbrev.el but that doesn’t work for me either. Fortunately, it is fairly easy to fix myself.

We can use functions from dabbrev to get all of the possible dabbrev expansions.

(require 'cl)
(require 'dabbrev)
(require 'auto-complete)

(defun ac-source-dabbrev (abbrev)
  (let ((dabbrev-check-all-buffers t))
    (sort (dabbrev--find-all-expansions abbrev t) #'string<)))

auto-complete allows you to list multiple sources for completions in ac-sources. Here we just want one but I could see that it might be nice to add language keywords or something like that.

(defvar ac-source-dabbrev-words
     . (lambda () (all-completions ac-target
                                   (ac-source-dabbrev ac-target)))))
  "Get all the completions using dabbrev")

(setq-default ac-sources '(ac-source-dabbrev-words))

I prefer to manually start completion rather than have it trigger automatically.

(setq ac-auto-start nil)
(global-set-key (kbd "M-/") 'ac-start)

There is a keymap you can add your own keys to. By default, C-g doesn’t cancel the completion window which feels really strange to me. In emacs C-g is pervasive for cancelling options. Fortunately, it is pretty easy to fix that.

(define-key ac-complete-mode-map (kbd "M-x") 'execute-extended-command)
(define-key ac-complete-mode-map (kbd "C-n") 'ac-next)
(define-key ac-complete-mode-map (kbd "C-p") 'ac-previous)
(define-key ac-complete-mode-map (kbd "C-g") 'ac-stop)

I like both RETURN and TAB for completion.

(define-key ac-complete-mode-map "\t" 'ac-complete)
(define-key ac-complete-mode-map "\r" 'ac-complete)

I want completions to update as you type. Did you know that by adding a vector to a keymap, you can capture all ascii keypresses?

(defun ac-self-insert ()
  (self-insert-command 1)

;; (define-key ac-complete-mode-map [t] 'ac-self-insert)

However, [t] also absorbs other ASCII keypresses you’ve defined such as TAB and RETURN. Therefore, we have to define them all individually.

(defun ac-fix-keymap ()
  (let ((i 32))
    (while (<= i ?z)
      (define-key ac-complete-mode-map
        (make-string 1 i) 'ac-self-insert)
      (incf i))))


I also want DELETE to trigger a new completion update.

(define-key ac-complete-mode-map (kbd "DEL")
  (lambda ()
    (backward-delete-char-untabify 1)

(provide 'auto-complete-config)

Read Full Post »