[Prev][Next][Index][Thread]
Re: Question on implementing a Deuce command
"Chris Double" <chris@double.co.nz> wrote in message
wkk7yfwlzv.fsf@double.co.nz">news:wkk7yfwlzv.fsf@double.co.nz...
> Doing some playing around with Deuce, the Dylan Editor, I thought I'd
> try implementing the equivalent of some Emacs Lisp packages to see
> what programming with Deuce is like compared to Emacs.
By way of apology or perhaps just defensiveness, I have to point out
that I didn't design Deuce to have a super-convenient extension language
like gnuemacs. It requires a bit more programming. This deficiency is
mainly due to the schedule constraints we had -- we needed an editor
that did the job, more than we needed a Dylan reinvention of gnuemacs.
> Starting simple, I used morse.el, and attempted a morse.dylan. There
> being little in the way of Deuce documentation I thought I'd post my
> attempt here to get some feedback as to whether I'm doing it the right
> way - or if there are other ways of doing it.
>
> Here's my 'morse-region' code:
>
Here's my annotated version:
define command morse-region(frame)
"Convert the selected text to morse code."
let bp1 = copy-bp(point());
let bp2 = mark();
when(bp2)
do-morse-region(frame, bp1, bp2);
end when;
end command morse-region;
define method do-morse-region(frame,
bp1 :: <basic-bp>,
bp2 :: <basic-bp>)
=> ()
let window = frame.frame-window;
let buffer = frame.frame-buffer;
// *** DELETE UPCASED CODE -- 'MAKE-INTERVAL' DOES THE RIGHT THING
LET REVERSE? = BP-LESS?(BP1, BP2);
let interval = make-interval(bp1, bp2, IN-ORDER?: REVERSE?);
check-read-only(interval);
clear-mark!();
queue-region-redisplay(window, bp1, bp2, centering: #f);
local method morse-line(line :: <line>, si :: <integer>, ei :: <integer>,
last?)
// *** DELETE UPCASED CODE -- 'INSERT!' AND 'KILL!' DO THE RIGHT THING
LET LINE = NOTE-LINE-CHANGED(LINE);
let contents = line-contents(line);
// *** YOU COULD SAFELY USE 'AS-LOWERCASE!' SINCE YOU'RE ABOUT TO
// *** KILL THAT INTERVAL ANYWAY
let morse = convert-to-morse(AS-LOWERCASE(CONTENTS), start: si, end:
ei);
let start-bp = make-bp(line, si);
let end-bp = make-bp(line, ei);
// *** IT WOULD BE MORE EFFICIENT TO USE 'LINE-CONTENTS-SETTER'
// *** IN THE CASE WHERE YOU ARE MUNGING THE WHOLE LINE
// *** (TOO BAD 'DELETE-WITHIN-LINE' ISN'T EXPORTED...)
insert!(kill!(make-interval(start-bp, end-bp)), morse);
end method morse-line;
with-change-recording(buffer, <replace-change-record>, interval: interval)
do-lines(morse-line, interval);
end with-change-recording;
end method do-morse-region;
> ------------------8<-------------------------
>
> Note that 'convert-to-morse' takes a string and converts it to morse
> code in much the same way as morse.el does it. It returns the
> converted string. I won't post my attempt at convert-to-morse and
> convert-from-morse just yet. An exercise for the reader!
>
> I couldn't work out how to do the conversion character by character
> within the Deuce buffer itself, so I went for the function that
> returns a converted string and did it line by line. How would I do it
> character by character 'in-place'?
I think you made the correct choice -- it's much more efficient to snip
out a whole interval and then replace it in one go than it is to do it
one character at a time.
> Is the 'note-line-changed' needed? What exactly does that do? Inform
> clients that the line has changed so it can be redisplayed?
No to the first question, and your third question is the correct answer
to the second one.
> The 'with-change-recording' macro...Does that do the do/undo handling
> for me? I notice I can undo the morse-region.
Yes, it handles undo/redo for you. The "undo class" tells the undo/redo
facility what sort of changes you are making so that the most efficient
representation for change can be used.
> I added this code to 'standalone-deuce' and it worked ok. Just curious
> if it's the right approach. Deuce is fairly large and there is a lot
> in there.
Pretty good first stab, if you ask me.
Note to self:
- Export 'delete-within-line' from deuce-internals
- Export 'insert-into-line' from deuce-internals
Follow-Ups:
References: