[climacs-devel] "Vial" mode for Climacs?

Brad Beveridge brad.beveridge at gmail.com
Wed Oct 25 16:39:43 UTC 2006


Hi all, I'm the author of Vial (http://common-lisp.net/project/vial/),
a Vi like editor for CL.  I've recently gone public, which prompted
Troels to hit me with a cluebat :)
He asked "Why didn't you use Flexichain?", which is a reasonable
question.  I answered "Well the project was originally just for fun
and to learn CL, but now its got some life it makes sense to reuse FC"
Reuse is a slippery, slippery slope, and for me the bottom of that
slope is implementing a "Viper" mode for Climacs.  But, if I do it I
want to call in "Vial" - I like the name, and it needs to be not
"Viper".
So my thinking is that if I want to really be sensible (damn logic!),
I at least need to figure out how hard it would be to make a Vial mode
for Climacs.  I am a total Climacs and McClim newbie, and really
pretty new to vanilla CL, so please forgive any particularly dense
questions I have.

I've skimmed the Climacs code and read about Clim command tables, I
think that I have a basic understanding.  I'll ramble for a bit below
about what I think I know, I'd love it if somebody could correct my
misconceptions :)

A command table essentially maps one or more keystrokes (including
modified keys) into a function call.  Defining commands involves a
somewhat fancy Clim macro that does most of the work for you.
Command tables setup a paradigm of a one to one map: keystrokes map to
a single function call.  I'm not sure how repeats work, but I assume
C-u or M-[0-9] prime some sort of repeat accumulator.

Vi style editors have at least 3 modes, normal/command, insert, and EX
mode.  I suspect that each mode will need its own command table,
probably replacing the 'BASE table in Climacs.
Insert mode is trivial.  EX mode is probably almost trivial because it
is just a minibuffer.
Normal mode is a bit harder, I think, and doesn't fit well.
Some Vi commands are just single or double keystrokes, eg
j k l h - move the cursor
dd - delete line
The rest involve a two part command, it starts with an op and then has a motion.
d{motion} - delete from cursor to the end of motion

As far as I can tell, commands fall into either operations, or
operation-motion.  In my editor I currently solve this with pattern
matching.  A key is pressed and a regular expression runs, if a match
is found in either the OP or MOTION expressions, then the function is
just called.  So pressing "dd" or "j" is an immediate match and a line
is deleted or the cursor moved down a line, respectively.  The next
table to search is the OP-MOTION expression table, if a match is found
then two things happen
1) A region is defined by taking the current point, then executing the
specific MOTION.
2) The OP function is called with the created region.

Also, everything can be prefixed with a number, hence 2dd, delete 2
lines.  d2j, delete from point till two lines down.  2d2q, delete from
point till two lines down, then do it again - 4 lines deleted (the "d"
op works on whole lines).

My code for defining patterns is quite simple:
(define-pattern 'motion "j" #'move-forward-line)
(define-pattern 'op "dd" #'delete-line)
(define-pattern 'op-motion "d" #delete-region)

If you've managed to read this far - thanks!!
So my basic problem is trying to shoehorn this kind of key matching
into a table structure that I don't think is a good fit - though it
could be done by permuting the op-motions I guess.  If I am missing
something obvious, I'd love to hear about a better way to do the
op-motion style handling.

So I think I have two options:
1) Define a command table that replaces 'BASE, and basically does
self-insert to redirect all keystrokes to a matching function that I
define.  Possibly the most straight forward.
2) Define a new McClim command table instance that has the semantics I
would like.  I have no idea how to do this though :)
3) Do what Viper appears to do: map keys where the make sense, and
redirect everything else to a huge switch statement function.  I guess
this is really equivalent to #1, but uglier :)

Thanks,
Brad



More information about the climacs-devel mailing list