Tag completion mode for emacs or the like?
April 18, 2006 7:34 AM   Subscribe

I have a huge list of unique identifiers. A person needs to enter, for each one of those identifiers, a list of tags, and I'd like to make it really easy for them to tab-complete those tags, based on the ones they've already entered.

For example:

CAT mammal, animal, has-whiskers, has-fur, enjoys-petting

I want to make it really easy for them to enter those properties. When they start, no properties will have been defined yet. Each time they enter a new one, a new property gets defined.

So, after hitting return after typing 'enjoys-petting', their cursor will be after


I'd like them to be able to type 'm', and have some sort of way to see the "mammal" completion on the screen somewhere, and hitting tab or somesuch should accept the completion. If they typed 'h', they should see both 'has-whiskers' and 'has-fur'; hitting tab should complete it up to 'has-'; if they then type 'f', the completion list should dwindle to 'has-fur', and ... you get the idea.

Is there some editor that would make this trivial? This isn't (or doesn't have to be) web-based - it's all going to be done by one or two people. It'd probably be best, I think, if it were implemented as something like an emacs mode. Anyone have the emacs-fu do make this happen? Or any other bright ideas? I just know this is close to trivial.
posted by dmd to Computers & Internet (10 answers total)
Not exactly what you're asking for, but check out the tag entry screen in del.icio.us. Better than tab-completion, IMO.
posted by Leon at 7:55 AM on April 18, 2006

Microsoft Excel's AutoComplete feature works pretty much exactly like this, as far as the actual typing and completion; the only problem is that (as far as I can tell) the values all have to be in the same column. So you'd have to have the users type in the CAT and DOG terms rather than starting with a spreadsheet with all the terms already there, and you'd end up with something that looked like
CAT     mammal
DOG     mammal
...but it probably wouldn't be too hard to write a script to convert that into whatever format you actually need.
posted by staggernation at 8:31 AM on April 18, 2006

Hmm. The typing in of the terms oneself is kinda annoying - there's several hundred of them - and Excel can't seem to get it into its head that I want to stay in column 2, not go back to column 1...
posted by dmd at 9:13 AM on April 18, 2006

Under Preferences > Edit, there's a "Move selection after Return" option. If you turn this on and set it to Down, you should be able to hit Return after entering a tag and go to the next cell down in column 2.
posted by staggernation at 9:38 AM on April 18, 2006

It looks like what you want is abbrev-mode. You might also want to look up the emacs lisp functions for defining abbrevs. Here is an example config file snippit. Just as a general rule, I tend to preface my abbrevs with some kind of a punctuation character to avoid clobbering regular text. So "!mam" followed by a space would expand to "mammal..."

Another option would be to create your own source file for tags using the etags utility and the regexp option. Then you can insert a tag with M-TAB. I got this working with a sample file that put one tag per line, then ran etags thus:

etags --language=none --regex="/.*/" test-tags.txt

emacs foo.baz

M-x visit-tags-file

Then has- followed by M-tab completes to has-fur.

If you want to automate this process, you might want to check out the manual.

Note that M-TAB runs ispell-complete-word rather than complete-tag in text mode, and probably some other modes. But it's reasonably easy to remap keys.

Depending on how complex you want to get you might want to create your own mode for this kind of thing.

Let me know if you have any questions.
posted by KirkJobSluder at 10:08 AM on April 18, 2006

Oh, and this code takes care of moving to the end of the next line. If you want to go forward to the end of the first word, you can use "forward-word" instead.
(defun end-of-next-line ()

(global-set-key (quote [S-return]) (quote end-of-next-line))

posted by KirkJobSluder at 10:52 AM on April 18, 2006

abbev-mode seems close to what I want, but I'm a bit confused as to how to get it to learn the abbrevs.

I want it to learn a new abbrev every single time I enter a new string it hasn't seen before. And, it needs to forget them if I delete a string (if has-lice no longer appears anywhere in the document, typing has-li<tab> shouldn't show it has a completion possibility even if it was one before).
posted by dmd at 3:27 PM on April 18, 2006

Ohh, perhaps try dynamic abbrev (dabbrev-expand) then?

It's usually mapped to M-/, but you could remap it to tab with global-set-key or local-set-key. What it does is search backwards through the file for the first matching word. Repeated calls to dabbrev-expand will continue to search backwards through the current buffer, and then to all open buffers.

It's not quite the behavior you described, but close enough to get the job done perhaps?
posted by KirkJobSluder at 4:24 PM on April 18, 2006

Oh, and if you go the emacs route, you might want to use shift-tab rather than tab to preserve the tab key for navigation.
posted by KirkJobSluder at 4:37 PM on April 18, 2006

Access can do this with drop-down menus. You have to write a bit of script to make it refresh the menu data source after each entry, but as I recall that wasn't too hard. I imagine OpenOffice.org's Base component has a similar facility.

If you're open to the idea of putting your stuff in a database and you can't figure out how to do it yourself, drop me an email and I'll have a bit of a muck around with OOo.
posted by flabdablet at 6:57 PM on April 18, 2006

« Older How to choose a new web design firm?   |   Seeking good 'zero commercial' travel resources on... Newer »
This thread is closed to new comments.