KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > LispAPI


1 /*
2  * LispAPI.java
3  *
4  * Copyright (C) 2003-2004 Peter Graves
5  * $Id: LispAPI.java,v 1.55 2004/09/23 14:34:27 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import gnu.regexp.REException;
25 import java.util.Iterator JavaDoc;
26 import javax.swing.SwingUtilities JavaDoc;
27 import javax.swing.undo.CompoundEdit JavaDoc;
28 import org.armedbear.lisp.AbstractString;
29 import org.armedbear.lisp.ConditionThrowable;
30 import org.armedbear.lisp.Fixnum;
31 import org.armedbear.lisp.Function;
32 import org.armedbear.lisp.GenericFunction;
33 import org.armedbear.lisp.JavaObject;
34 import org.armedbear.lisp.Keyword;
35 import org.armedbear.lisp.Lisp;
36 import org.armedbear.lisp.LispCharacter;
37 import org.armedbear.lisp.LispError;
38 import org.armedbear.lisp.LispObject;
39 import org.armedbear.lisp.LispThread;
40 import org.armedbear.lisp.Package;
41 import org.armedbear.lisp.Packages;
42 import org.armedbear.lisp.Pathname;
43 import org.armedbear.lisp.Primitive0;
44 import org.armedbear.lisp.Primitive1;
45 import org.armedbear.lisp.Primitive2;
46 import org.armedbear.lisp.Primitive3;
47 import org.armedbear.lisp.Primitive;
48 import org.armedbear.lisp.Primitives;
49 import org.armedbear.lisp.SimpleString;
50 import org.armedbear.lisp.Symbol;
51 import org.armedbear.lisp.TypeError;
52 import org.armedbear.lisp.UndefinedFunction;
53 import org.armedbear.lisp.WrongNumberOfArgumentsException;
54
55 public final class LispAPI extends Lisp
56 {
57     private static final Preferences preferences = Editor.preferences();
58
59     public static final Package JavaDoc PACKAGE_J =
60         Packages.createPackage("J");
61     public static final Package JavaDoc PACKAGE_J_INTERNALS =
62         Packages.createPackage("J-INTERNALS");
63     static {
64         PACKAGE_J.usePackage(PACKAGE_CL);
65         PACKAGE_J.usePackage(PACKAGE_EXT);
66         PACKAGE_J.usePackage(PACKAGE_JAVA);
67         PACKAGE_J_INTERNALS.usePackage(PACKAGE_CL);
68         PACKAGE_J_INTERNALS.usePackage(PACKAGE_EXT);
69         PACKAGE_J_INTERNALS.usePackage(PACKAGE_JAVA);
70     }
71
72     public static final Symbol BUFFER_STREAM =
73         LispAPI.PACKAGE_J.addExternalSymbol("BUFFER-STREAM");
74
75     public static final Symbol _CURRENT_COMMAND_ =
76         exportSpecial("*CURRENT-COMMAND*", PACKAGE_J, NIL);
77
78     public static final Symbol _LAST_COMMAND_ =
79         exportSpecial("*LAST-COMMAND*", PACKAGE_J, NIL);
80
81     public static final void eventHandled()
82     {
83         _LAST_COMMAND_.setSymbolValue(_CURRENT_COMMAND_.getSymbolValue());
84         _CURRENT_COMMAND_.setSymbolValue(NIL);
85     }
86
87     public static final Editor checkEditor(LispObject obj)
88         throws ConditionThrowable
89     {
90         if (obj == null)
91             throw new NullPointerException JavaDoc();
92         try {
93             return (Editor) ((JavaObject)obj).getObject();
94         }
95         catch (ClassCastException JavaDoc e) {
96             signal(new TypeError("The value " + obj.writeToString() +
97                                  " is not an editor."));
98             // Not reached.
99
return null;
100         }
101     }
102
103     public static final Buffer checkBuffer(LispObject obj)
104         throws ConditionThrowable
105     {
106         if (obj == null)
107             throw new NullPointerException JavaDoc();
108         if (obj == NIL)
109             return Editor.currentEditor().getBuffer();
110         try {
111             return (Buffer) ((JavaObject)obj).getObject();
112         }
113         catch (ClassCastException JavaDoc e) {
114             signal(new TypeError("The value " + obj.writeToString() +
115                                  " is not a buffer."));
116             // Not reached.
117
return null;
118         }
119     }
120
121     private static final Position checkMark(LispObject obj)
122         throws ConditionThrowable
123     {
124         if (obj == null)
125             throw new NullPointerException JavaDoc();
126         try {
127             return (Position) ((JavaObject)obj).getObject();
128         }
129         catch (ClassCastException JavaDoc e) {
130             signal(new TypeError("The value " + obj.writeToString() +
131                                  " is not a mark."));
132             // Not reached.
133
return null;
134         }
135     }
136
137     public static final Line checkLine(LispObject obj)
138         throws ConditionThrowable
139     {
140         if (obj == null)
141             throw new NullPointerException JavaDoc();
142         try {
143             return (Line) ((JavaObject)obj).getObject();
144         }
145         catch (ClassCastException JavaDoc e) {
146             signal(new TypeError("The value " + obj.writeToString() +
147                                  " is not a line."));
148             // Not reached.
149
return null;
150         }
151     }
152
153     // ### current-editor
154
private static final Primitive0 CURRENT_EDITOR =
155         new Primitive0("current-editor", PACKAGE_J, true,
156                        "()",
157                        "Returns the current editor as a Lisp object.")
158     {
159         public LispObject execute()
160         {
161             return new JavaObject(Editor.currentEditor());
162         }
163     };
164
165     // ### %set-current-editor
166
private static final Primitive1 _SET_CURRENT_EDITOR =
167         new Primitive1("%set-current-editor", PACKAGE_J, false,
168                        "(EDITOR)",
169                        "Makes EDITOR the current editor.")
170     {
171         public LispObject execute(LispObject arg) throws ConditionThrowable
172         {
173             Editor.setCurrentEditor(checkEditor(arg));
174             return arg;
175         }
176     };
177
178     // ### other-editor
179
private static final Primitive0 OTHER_EDITOR =
180         new Primitive0("other-editor", PACKAGE_J, true) {
181         public LispObject execute()
182         {
183             Editor otherEditor = Editor.currentEditor().getOtherEditor();
184             return otherEditor != null ? new JavaObject(otherEditor) : NIL;
185         }
186     };
187
188     // ### current-buffer
189
private static final Primitive0 CURRENT_BUFFER =
190         new Primitive0("current-buffer", PACKAGE_J, true) {
191         public LispObject execute()
192         {
193             return new JavaObject(Editor.currentEditor().getBuffer());
194         }
195     };
196
197     // ### editor-buffer editor => buffer
198
private static final Primitive1 BUFFER =
199         new Primitive1("editor-buffer", PACKAGE_J, true)
200     {
201         public LispObject execute(LispObject arg) throws ConditionThrowable
202         {
203             return new JavaObject(checkEditor(arg).getBuffer());
204         }
205     };
206
207     // ### buffer-name
208
private static final Primitive BUFFER_NAME =
209         new Primitive("buffer-name", PACKAGE_J, true, "&optional buffer")
210     {
211         public LispObject execute()
212         {
213             String JavaDoc name = Editor.currentEditor().getBuffer().getTitle();
214             return name != null ? new SimpleString(name) : NIL;
215         }
216
217         public LispObject execute(LispObject arg) throws ConditionThrowable
218         {
219             String JavaDoc name = checkBuffer(arg).getTitle();
220             return name != null ? new SimpleString(name) : NIL;
221         }
222     };
223
224     // ### get-buffer
225
private static final Primitive1 GET_BUFFER =
226         new Primitive1("get-buffer", PACKAGE_J, true, "name")
227     {
228         public LispObject execute(LispObject arg) throws ConditionThrowable
229         {
230             if (arg instanceof AbstractString) {
231                 String JavaDoc name = arg.getStringValue();
232                 BufferIterator iterator = new BufferIterator();
233                 while (iterator.hasNext()) {
234                     Buffer buffer = iterator.nextBuffer();
235                     if (buffer.getTitle().equals(name))
236                         return new JavaObject(buffer);
237                 }
238                 return NIL;
239             }
240             if (arg instanceof JavaObject) {
241                 if (((JavaObject)arg).getObject() instanceof Buffer)
242                     return arg;
243             }
244             return NIL;
245         }
246     };
247
248     // ### buffer-live-p object => generalized-boolean
249
private static final Primitive1 BUFFER_LIVE_P =
250         new Primitive1("buffer-live-p", PACKAGE_J, true, "object")
251     {
252         public LispObject execute(LispObject arg) throws ConditionThrowable
253         {
254             if (arg instanceof JavaObject) {
255                 if (((JavaObject)arg).getObject() instanceof Buffer) {
256                     if (Editor.getBufferList().contains((Buffer)((JavaObject)arg).getObject()))
257                         return T;
258                 }
259             }
260             return NIL;
261         }
262     };
263
264     // ### buffer-pathname
265
private static final Primitive BUFFER_PATHNAME =
266         new Primitive("buffer-pathname", PACKAGE_J, true, "&optional buffer")
267     {
268         public LispObject execute() throws ConditionThrowable
269         {
270             File file = Editor.currentEditor().getBuffer().getFile();
271             if (file != null && file.isLocal()) {
272                 String JavaDoc s = file.canonicalPath();
273                 if (file.isDirectory())
274                     if (!s.endsWith(LocalFile.getSeparator()))
275                         s = s.concat(LocalFile.getSeparator());
276                 return new Pathname(s);
277             }
278             return NIL;
279         }
280
281         public LispObject execute(LispObject arg) throws ConditionThrowable
282         {
283             File file = checkBuffer(arg).getFile();
284             if (file != null && file.isLocal()) {
285                 String JavaDoc s = file.canonicalPath();
286                 if (file.isDirectory())
287                     if (!s.endsWith(LocalFile.getSeparator()))
288                         s = s.concat(LocalFile.getSeparator());
289                 return new Pathname(s);
290             }
291             return NIL;
292         }
293     };
294
295     // ### buffer-string
296
private static final Primitive BUFFER_STRING =
297         new Primitive("buffer-string", PACKAGE_J, true, "&optional buffer")
298     {
299         public LispObject execute() throws ConditionThrowable
300         {
301             return new SimpleString(Editor.currentBuffer().getText());
302         }
303         public LispObject execute(LispObject arg) throws ConditionThrowable
304         {
305             return new SimpleString(checkBuffer(arg).getText());
306         }
307     };
308
309     // ### buffer-substring
310
private static final Primitive BUFFER_SUBSTRING =
311         new Primitive("buffer-substring", PACKAGE_J, true,
312                       "start end &optional buffer")
313     {
314         public LispObject execute(LispObject first, LispObject second)
315             throws ConditionThrowable
316         {
317             Region region = new Region(Editor.currentEditor().getBuffer(),
318                                        checkMark(first),
319                                        checkMark(second));
320             return new SimpleString(region.toString());
321         }
322         public LispObject execute(LispObject first, LispObject second,
323                                   LispObject third)
324             throws ConditionThrowable
325         {
326             Position start = checkMark(first);
327             Position end = checkMark(second);
328             Region region = new Region(checkBuffer(third), start, end);
329             return new SimpleString(region.toString());
330         }
331     };
332
333     // ### goto-char
334
// goto-char position
335
private static final Primitive GOTO_CHAR =
336         new Primitive("goto-char", PACKAGE_J, true)
337     {
338         public LispObject execute(LispObject arg) throws ConditionThrowable
339         {
340             // Move dot to position.
341
final Editor editor = Editor.currentEditor();
342             if (arg instanceof Fixnum) {
343                 Position pos =
344                     editor.getBuffer().getPosition(((Fixnum)arg).value);
345                 if (pos != null)
346                     editor.moveDotTo(pos);
347             } else
348                 editor.moveDotTo(checkMark(arg));
349             return new JavaObject(editor.getDot());
350         }
351     };
352
353     // ### move-to-position mark charpos &optional line
354
private static final Primitive MOVE_TO_POSITION =
355         new Primitive("move-to-position", PACKAGE_J, true,
356                       "mark charpos &optional line")
357     {
358         public LispObject execute(LispObject mark, LispObject charpos)
359             throws ConditionThrowable
360         {
361             Position pos = checkMark(mark);
362             pos.setOffset(Fixnum.getValue(charpos));
363             return mark;
364         }
365         public LispObject execute(LispObject mark, LispObject charpos,
366                                   LispObject line)
367             throws ConditionThrowable
368         {
369             Position pos = checkMark(mark);
370             if (line == NIL)
371                 pos.setOffset(Fixnum.getValue(charpos));
372             else
373                 pos.moveTo(checkLine(line), Fixnum.getValue(charpos));
374             return mark;
375         }
376     };
377
378     // ### current-point
379
private static final Primitive0 CURRENT_POINT =
380         new Primitive0("current-point", PACKAGE_J, true, "")
381     {
382         public LispObject execute()
383         {
384             Position dot = Editor.currentEditor().getDot();
385             if (dot != null)
386                 return new JavaObject(dot.copy());
387             return NIL;
388         }
389     };
390
391     // ### current-mark
392
private static final Primitive0 CURRENT_MARK =
393         new Primitive0("current-mark", PACKAGE_J, true, "")
394     {
395         public LispObject execute()
396         {
397             Position mark = Editor.currentEditor().getMark();
398             if (mark != null)
399                 return new JavaObject(mark.copy());
400             return NIL;
401         }
402     };
403
404     // ### point-min
405
private static final Primitive0 POINT_MIN =
406         new Primitive0("point-min", PACKAGE_J, true)
407     {
408         public LispObject execute()
409         {
410             final Line line = Editor.currentBuffer().getFirstLine();
411             if (line == null)
412                 return NIL;
413             return new JavaObject(new Position(line, 0));
414         }
415     };
416
417     // ### point-max
418
private static final Primitive0 POINT_MAX =
419         new Primitive0("point-max", PACKAGE_J, true)
420     {
421         public LispObject execute()
422         {
423             Position pos = Editor.currentBuffer().getEnd();
424             if (pos == null)
425                 return NIL;
426             return new JavaObject(pos);
427         }
428     };
429
430     // ### make-mark
431
private static final Primitive1 MAKE_MARK =
432         new Primitive1("make-mark", PACKAGE_J, true)
433     {
434         public LispObject execute(LispObject first, LispObject second)
435             throws ConditionThrowable
436         {
437             Line line = checkLine(first);
438             int offset = Fixnum.getValue(second);
439             return new JavaObject(new Position(line, offset));
440         }
441     };
442
443     // ### mark-line
444
private static final Primitive1 MARK_LINE =
445         new Primitive1("mark-line", PACKAGE_J, true)
446     {
447         public LispObject execute(LispObject arg) throws ConditionThrowable
448         {
449             return new JavaObject(checkMark(arg).getLine());
450         }
451     };
452
453     // ### mark-charpos
454
private static final Primitive1 MARK_CHARPOS =
455         new Primitive1("mark-charpos", PACKAGE_J, true)
456     {
457         public LispObject execute(LispObject arg) throws ConditionThrowable
458         {
459             return number(checkMark(arg).getOffset());
460         }
461     };
462
463     // ### current-line
464
private static final Primitive0 CURRENT_LINE =
465         new Primitive0("current-line", PACKAGE_J, true)
466     {
467         public LispObject execute()
468         {
469             Editor editor = Editor.currentEditor();
470             Position dot = Editor.currentEditor().getDot();
471             if (dot != null)
472                 return new JavaObject(dot.getLine());
473             return NIL;
474         }
475     };
476
477     // ### line-next
478
private static final Primitive1 LINE_NEXT =
479         new Primitive1("line-next", PACKAGE_J, true)
480     {
481         public LispObject execute(LispObject arg) throws ConditionThrowable
482         {
483             Line next = checkLine(arg).next();
484             return next != null ? new JavaObject(next) : NIL;
485         }
486     };
487
488     // ### line-previous
489
private static final Primitive1 LINE_PREVIOUS =
490         new Primitive1("line-previous", PACKAGE_J, true)
491     {
492         public LispObject execute(LispObject arg) throws ConditionThrowable
493         {
494             Line prev = checkLine(arg).previous();
495             return prev != null ? new JavaObject(prev) : NIL;
496         }
497     };
498
499     // ### line-chars
500
private static final Primitive1 LINE_CHARS =
501         new Primitive1("line-chars", PACKAGE_J, true)
502     {
503         public LispObject execute(LispObject arg) throws ConditionThrowable
504         {
505             String JavaDoc s = checkLine(arg).getText();
506             return s != null ? new SimpleString(s) : NIL;
507         }
508     };
509
510     // ### line-flags
511
private static final Primitive1 LINE_FLAGS =
512         new Primitive1("line-flags", PACKAGE_J, true)
513     {
514         public LispObject execute(LispObject arg) throws ConditionThrowable
515         {
516             return number(checkLine(arg).flags());
517         }
518     };
519
520     // ### %set-line-flags
521
private static final Primitive2 _SET_LINE_FLAGS =
522         new Primitive2("%set-line-flags", PACKAGE_J, false)
523     {
524         public LispObject execute(LispObject first, LispObject second)
525             throws ConditionThrowable
526         {
527             Line line = checkLine(first);
528             int flags = Fixnum.getValue(second);
529             line.setFlags(flags);
530             return second;
531         }
532     };
533
534     // ### line-number
535
private static final Primitive1 LINE_NUMBER =
536         new Primitive1("line-number", PACKAGE_J, true, "line")
537     {
538         public LispObject execute(LispObject arg) throws ConditionThrowable
539         {
540             return number(checkLine(arg).lineNumber());
541         }
542     };
543
544     // ### char-after
545
// Returns character immediately after mark.
546
private static final Primitive1 CHAR_AFTER =
547         new Primitive1("char-after", PACKAGE_J, true)
548     {
549         public LispObject execute(LispObject arg) throws ConditionThrowable
550         {
551             return LispCharacter.getInstance(checkMark(arg).getChar());
552         }
553     };
554
555     // ### char-before
556
// Returns character immediately before mark.
557
private static final Primitive1 CHAR_BEFORE =
558         new Primitive1("char-before", PACKAGE_J, true)
559     {
560         public LispObject execute(LispObject arg) throws ConditionThrowable
561         {
562             Position pos = checkMark(arg).copy();
563             return pos.prev() ? LispCharacter.getInstance(pos.getChar()) : NIL;
564         }
565     };
566
567     // ### forward-char
568
// Move point right N characters (left if N is negative).
569
private static final Primitive FORWARD_CHAR =
570         new Primitive("forward-char", PACKAGE_J, true)
571     {
572         public LispObject execute() throws ConditionThrowable
573         {
574             return forwardChar(1);
575         }
576         public LispObject execute(LispObject arg) throws ConditionThrowable
577         {
578             return forwardChar(Fixnum.getValue(arg));
579         }
580     };
581
582     // ### backward-char
583
// Move point left N characters (right if N is negative).
584
private static final Primitive BACKWARD_CHAR =
585         new Primitive("backward-char", PACKAGE_J, true) {
586         public LispObject execute() throws ConditionThrowable
587         {
588             return forwardChar(-1);
589         }
590         public LispObject execute(LispObject arg) throws ConditionThrowable
591         {
592             return forwardChar(-Fixnum.getValue(arg));
593         }
594     };
595
596     private static final LispObject forwardChar(int n) throws ConditionThrowable
597     {
598         if (n != 0) {
599             final Editor editor = Editor.currentEditor();
600             Position pos = editor.getDot();
601             if (pos != null) {
602                 editor.addUndo(SimpleEdit.MOVE);
603                 if (n > 0) {
604                     while (n-- > 0) {
605                         if (!pos.next())
606                             return signal(new LispError("reached end of buffer"));
607                     }
608                 } else {
609                     Debug.assertTrue(n < 0);
610                     while (n++ < 0) {
611                         if (!pos.prev())
612                             return signal(new LispError("reached beginning of buffer"));
613                     }
614                 }
615                 editor.moveCaretToDotCol();
616             }
617         }
618         return NIL;
619     }
620
621     // ### beginning-of-line
622
private static final Primitive BEGINNING_OF_LINE =
623         new Primitive("beginning-of-line", PACKAGE_J, true)
624     {
625         public LispObject execute() throws ConditionThrowable
626         {
627             Editor.currentEditor().bol();
628             return NIL;
629         }
630
631         public LispObject execute(LispObject arg) throws ConditionThrowable
632         {
633             int n = (arg != NIL) ? Fixnum.getValue(arg) : 1;
634             final Editor editor = Editor.currentEditor();
635             Position pos = editor.getDot();
636             if (pos != null) {
637                 editor.addUndo(SimpleEdit.MOVE);
638                 while (--n > 0) {
639                     Line nextLine = pos.getNextLine();
640                     if (nextLine != null)
641                         pos.setLine(nextLine);
642                     else
643                         break;
644                 }
645                 pos.setOffset(0);
646                 editor.moveCaretToDotCol();
647             }
648             return NIL;
649         }
650     };
651
652     // ### end-of-line
653
private static final Primitive END_OF_LINE =
654         new Primitive("end-of-line", PACKAGE_J, true)
655     {
656         public LispObject execute() throws ConditionThrowable
657         {
658             Editor.currentEditor().eol();
659             return NIL;
660         }
661
662         public LispObject execute(LispObject arg) throws ConditionThrowable
663         {
664             int n = (arg != NIL) ? Fixnum.getValue(arg) : 1;
665             final Editor editor = Editor.currentEditor();
666             Position pos = editor.getDot();
667             if (pos != null) {
668                 editor.addUndo(SimpleEdit.MOVE);
669                 while (--n > 0) {
670                     Line nextLine = pos.getNextLine();
671                     if (nextLine != null)
672                         pos.setLine(nextLine);
673                     else
674                         break;
675                 }
676                 pos.setOffset(pos.getLineLength());
677                 editor.moveCaretToDotCol();
678             }
679             return NIL;
680         }
681     };
682
683     // ### backward-up-list
684
private static final Primitive BACKWARD_UP_LIST =
685         new Primitive("backward-up-list", PACKAGE_J, true)
686     {
687         public LispObject execute() throws ConditionThrowable
688         {
689             LispMode.backwardUpList();
690             return NIL;
691         }
692     };
693
694     // ### looking-at pattern => generalized-boolean
695
private static final Primitive LOOKING_AT =
696         new Primitive("looking-at", PACKAGE_J, true)
697     {
698         public LispObject execute(LispObject arg) throws ConditionThrowable
699         {
700             if (arg instanceof AbstractString) {
701                 String JavaDoc pattern = arg.getStringValue();
702                 Editor editor = Editor.currentEditor();
703                 Position dot = editor.getDot();
704                 if (dot != null) {
705                     if (dot.getLine().substring(dot.getOffset()).startsWith(pattern))
706                         return T;
707                 }
708                 return NIL;
709             }
710             return signal(new TypeError(arg, Symbol.STRING));
711         }
712     };
713
714     private static final Symbol KEYWORD_GLOBAL =
715         Keyword.internKeyword("GLOBAL");
716     private static final Symbol KEYWORD_MODE =
717         Keyword.internKeyword("MODE");
718     private static final Symbol KEYWORD_BUFFER =
719         Keyword.internKeyword("BUFFER");
720     private static final Symbol KEYWORD_CURRENT =
721         Keyword.internKeyword("CURRENT");
722
723     // ### %variable-value
724
// %variable-value symbol kind where => value
725
private static final Primitive3 _VARIABLE_VALUE =
726         new Primitive3("%variable-value", PACKAGE_J, false) {
727         public LispObject execute(LispObject first, LispObject second,
728             LispObject third) throws ConditionThrowable
729         {
730             Symbol symbol = checkSymbol(first);
731             JVar jvar = JVar.getJVar(symbol);
732             Property property = jvar.getProperty();
733             LispObject kind = second;
734             LispObject where = third;
735             final Editor editor = Editor.currentEditor();
736             if (kind == KEYWORD_CURRENT) {
737                 if (where != NIL)
738                     return signal(new LispError("Bad argument: " + where + "."));
739                 final Buffer buffer = editor.getBuffer();
740                 if (property.isBooleanProperty())
741                     return buffer.getBooleanProperty(property) ? T : NIL;
742                 if (property.isIntegerProperty())
743                     return number(buffer.getIntegerProperty(property));
744                 String JavaDoc value = buffer.getStringProperty(property);
745                 return value != null ? new SimpleString(value) : NIL;
746             }
747             if (kind == KEYWORD_GLOBAL) {
748                 if (property.isBooleanProperty())
749                     return preferences.getBooleanProperty(property) ? T : NIL;
750                 if (property.isIntegerProperty())
751                     return number(preferences.getIntegerProperty(property));
752                 String JavaDoc value = preferences.getStringProperty(property);
753                 return value != null ? new SimpleString(value) : NIL;
754             }
755             if (kind == KEYWORD_MODE) {
756                 final Mode mode;
757                 if (where == NIL)
758                     mode = editor.getMode();
759                 else {
760                     mode = Editor.getModeList().getModeFromModeName(where.getStringValue());
761                     if (mode == null)
762                         return signal(new LispError("Unknown mode: " + where + "."));
763                 }
764                 if (property.isBooleanProperty())
765                     return mode.getBooleanProperty(property) ? T : NIL;
766                 if (property.isIntegerProperty())
767                     return number(mode.getIntegerProperty(property));
768                 String JavaDoc value = mode.getStringProperty(property);
769                 return value != null ? new SimpleString(value) : NIL;
770             }
771             if (kind == KEYWORD_BUFFER) {
772                 final Buffer buffer;
773                 if (where != NIL)
774                     buffer = checkBuffer(where);
775                 else
776                     buffer = editor.getBuffer();
777                 if (property.isBooleanProperty())
778                     return buffer.getBooleanProperty(property) ? T : NIL;
779                 if (property.isIntegerProperty())
780                     return number(buffer.getIntegerProperty(property));
781                 String JavaDoc value = buffer.getStringProperty(property);
782                 return value != null ? new SimpleString(value) : NIL;
783             }
784             return signal(new LispError("Invalid parameter: " + kind + "."));
785         }
786     };
787
788     // ### %set-variable-value
789
// %set-variable-value symbol kind where new-value => new-value
790
private static final Primitive _SET_VARIABLE_VALUE =
791         new Primitive("%set-variable-value", PACKAGE_J, false) {
792         public LispObject execute(LispObject[] args) throws ConditionThrowable
793         {
794             if (args.length != 4)
795                 return signal(new WrongNumberOfArgumentsException(this));
796             Symbol symbol = checkSymbol(args[0]);
797             JVar jvar = JVar.getJVar(symbol);
798             Property property = jvar.getProperty();
799             LispObject kind = args[1];
800             LispObject where = args[2];
801             LispObject newValue = args[3];
802             if (kind == KEYWORD_GLOBAL) {
803                 if (property.isBooleanProperty()) {
804                     if (newValue == NIL) {
805                         preferences.setProperty(property, "false");
806                         return NIL;
807                     } else {
808                         preferences.setProperty(property, "true");
809                         return T;
810                     }
811                 } else {
812                     preferences.setProperty(property, newValue.getStringValue());
813                     return newValue;
814                 }
815             }
816             final Editor editor = Editor.currentEditor();
817             if (kind == KEYWORD_MODE) {
818                 final Mode mode;
819                 if (where == NIL)
820                     mode = editor.getMode();
821                 else
822                     mode = Editor.getModeList().getModeFromModeName(where.getStringValue());
823                 if (property.isBooleanProperty()) {
824                     if (newValue == NIL) {
825                         mode.setProperty(property, false);
826                         return NIL;
827                     } else {
828                         mode.setProperty(property, true);
829                         return T;
830                     }
831                 } else {
832                     mode.setProperty(property, newValue.getStringValue());
833                     return newValue;
834                 }
835             }
836             if (kind == KEYWORD_BUFFER) {
837                 final Buffer buffer;
838                 if (where != NIL)
839                     buffer = checkBuffer(where);
840                 else
841                     buffer = editor.getBuffer();
842                 if (property.isBooleanProperty()) {
843                     buffer.setProperty(property, newValue != NIL);
844                     return newValue != NIL ? T : NIL;
845                 }
846                 if (property.isIntegerProperty()) {
847                     buffer.setProperty(property, Fixnum.getValue(newValue));
848                     return newValue;
849                 }
850                 buffer.setProperty(property, newValue.getStringValue());
851                 return newValue;
852             }
853             return signal(new LispError("Invalid parameter: " + kind));
854         }
855     };
856
857     // ### kill-theme
858
private static final Primitive0 KILL_THEME =
859         new Primitive0("kill-theme", PACKAGE_J, true)
860     {
861         public LispObject execute()
862         {
863             preferences.killTheme();
864             return T;
865         }
866     };
867
868     // ### restore-focus
869
private static final Primitive0 RESTORE_FOCUS =
870         new Primitive0("restore-focus", PACKAGE_J, true)
871     {
872         public LispObject execute()
873         {
874             Editor.currentEditor().setFocusToDisplay();
875             return T;
876         }
877     };
878
879     // ### global-map-key key command => generalized-boolean
880
private static final Primitive2 GLOBAL_MAP_KEY =
881         new Primitive2("global-map-key", PACKAGE_J, true, "key command")
882     {
883         public LispObject execute(LispObject first, LispObject second)
884         throws ConditionThrowable
885         {
886             String JavaDoc keyText = first.getStringValue();
887             Object JavaDoc command;
888             if (second instanceof AbstractString) {
889                 command = second.getStringValue();
890             } else {
891                 // Verify that the command can be coerced to a function.
892
coerceToFunction(second);
893                 command = second;
894             }
895             return KeyMap.getGlobalKeyMap().mapKey(keyText, command) ? T : NIL;
896         }
897     };
898
899     // ### global-unmap-key key => generalized-boolean
900
private static final Primitive1 GLOBAL_UNMAP_KEY =
901         new Primitive1("global-unmap-key", PACKAGE_J, true, "key")
902     {
903         public LispObject execute(LispObject arg)
904         throws ConditionThrowable
905         {
906             String JavaDoc keyText = arg.getStringValue();
907             return KeyMap.getGlobalKeyMap().unmapKey(keyText) ? T : NIL;
908         }
909     };
910
911     // ### map-key-for-mode key command mode => generalized-boolean
912
private static final Primitive3 MAP_KEY_FOR_MODE =
913         new Primitive3("map-key-for-mode", PACKAGE_J, true, "key command mode")
914     {
915         public LispObject execute(LispObject first, LispObject second,
916                                   LispObject third)
917         throws ConditionThrowable
918         {
919             String JavaDoc keyText = first.getStringValue();
920             Object JavaDoc command;
921             if (second instanceof AbstractString) {
922                 command = second.getStringValue();
923             } else {
924                 // Verify that the command can be coerced to a function.
925
coerceToFunction(second);
926                 command = second;
927             }
928             String JavaDoc modeName = third.getStringValue();
929             Mode mode = Editor.getModeList().getModeFromModeName(modeName);
930             if (mode == null)
931                 return signal(new LispError("Unknown mode \"".concat(modeName).concat("\"")));
932             return mode.getKeyMap().mapKey(keyText, command) ? T : NIL;
933         }
934     };
935
936     // ### unmap-key-for-mode key mode => generalized-boolean
937
private static final Primitive2 UNMAP_KEY_FOR_MODE =
938         new Primitive2("unmap-key-for-mode", PACKAGE_J, true, "key mode")
939     {
940         public LispObject execute(LispObject first, LispObject second)
941         throws ConditionThrowable
942         {
943             String JavaDoc keyText = first.getStringValue();
944             String JavaDoc modeName = second.getStringValue();
945             Mode mode = Editor.getModeList().getModeFromModeName(modeName);
946             if (mode == null)
947                 return signal(new LispError("Unknown mode \"".concat(modeName).concat("\"")));
948             return mode.getKeyMap().unmapKey(keyText) ? T : NIL;
949         }
950     };
951
952     // ### %set-global-property
953
private static final Primitive2 _SET_GLOBAL_PROPERTY =
954         new Primitive2("%set-global-property", PACKAGE_J, false) {
955         public LispObject execute(LispObject first, LispObject second)
956         throws ConditionThrowable
957         {
958             String JavaDoc key = first.getStringValue();
959             final String JavaDoc value;
960             if (second instanceof Fixnum)
961                 value = String.valueOf(Fixnum.getValue(second));
962             else
963                 value = second.getStringValue();
964             Editor.setGlobalProperty(key, value);
965             return second;
966         }
967     };
968
969     // ### insert
970
private static final Primitive INSERT =
971         new Primitive("insert", PACKAGE_J, true, "&rest args")
972     {
973         public LispObject execute(LispObject[] args) throws ConditionThrowable
974         {
975             if (args.length == 0)
976                 return NIL;
977             final Editor editor = Editor.currentEditor();
978             if (!editor.checkReadOnly())
979                 return NIL;
980             CompoundEdit JavaDoc compoundEdit = editor.beginCompoundEdit();
981             try {
982                 for (int i = 0; i < args.length; i++) {
983                     LispObject obj = args[i];
984                     if (obj instanceof LispCharacter) {
985                         editor.insertChar(((LispCharacter)obj).getValue());
986                     } else if (obj instanceof AbstractString) {
987                         editor.insertString(obj.getStringValue());
988                     } else
989                         return signal(new TypeError(obj, "character or string"));
990                 }
991                 return NIL;
992             }
993             finally {
994                 editor.endCompoundEdit(compoundEdit);
995             }
996         }
997     };
998
999     // ### delete-region => nil
1000
private static final Primitive0 DELETE_REGION =
1001        new Primitive0("delete-region", PACKAGE_J, true)
1002    {
1003        public LispObject execute() throws ConditionThrowable
1004        {
1005            final Editor editor = Editor.currentEditor();
1006            if (!editor.checkReadOnly())
1007                return NIL;
1008            editor.deleteRegion();
1009            return NIL;
1010        }
1011    };
1012
1013    // ### set-mark pos => pos
1014
private static final Primitive1 SET_MARK =
1015        new Primitive1("set-mark", PACKAGE_J, true)
1016    {
1017        public LispObject execute(LispObject arg) throws ConditionThrowable
1018        {
1019            final Editor editor = Editor.currentEditor();
1020            if (arg != NIL)
1021                editor.setMark(checkMark(arg));
1022            else
1023                editor.unmark();
1024            return arg;
1025        }
1026    };
1027
1028    // ### undo
1029
private static final Primitive UNDO =
1030        new Primitive("undo", PACKAGE_J, true, "&optional count")
1031    {
1032        public LispObject execute() throws ConditionThrowable
1033        {
1034            Editor.currentEditor().undo();
1035            return NIL;
1036        }
1037
1038        public LispObject execute(LispObject arg) throws ConditionThrowable
1039        {
1040            Editor editor = Editor.currentEditor();
1041            int count;
1042            if (arg == NIL)
1043                count = 1;
1044            else
1045                count = Fixnum.getValue(arg);
1046            for (int i = 0; i < count; i++)
1047                editor.undo();
1048            return NIL;
1049        }
1050    };
1051
1052    // ### begin-compound-edit
1053
private static final Primitive0 BEGIN_COMPOUND_EDIT =
1054        new Primitive0("begin-compound-edit", PACKAGE_J, false)
1055    {
1056        public LispObject execute()
1057        {
1058            return new JavaObject(Editor.currentEditor().beginCompoundEdit());
1059        }
1060    };
1061
1062    // ### end-compound-edit
1063
private static final Primitive1 END_COMPOUND_EDIT =
1064        new Primitive1("end-compound-edit", PACKAGE_J, false)
1065    {
1066        public LispObject execute(LispObject arg) throws ConditionThrowable
1067        {
1068            try {
1069                CompoundEdit JavaDoc compoundEdit =
1070                    (CompoundEdit JavaDoc) ((JavaObject)arg).getObject();
1071                Editor.currentEditor().endCompoundEdit(compoundEdit);
1072                return NIL;
1073            }
1074            catch (ClassCastException JavaDoc e) {
1075                return signal(new TypeError(arg, "compound edit"));
1076            }
1077        }
1078    };
1079
1080    // ### %log-debug
1081
private static final Primitive1 _LOG_DEBUG =
1082        new Primitive1("%log-debug", PACKAGE_J, false)
1083    {
1084        public LispObject execute(LispObject arg) throws ConditionThrowable
1085        {
1086            Log.debug(arg.getStringValue());
1087            return arg;
1088        }
1089    };
1090
1091    // ### get-last-event-time
1092
private static final Primitive0 GET_LAST_EVENT_INTERNAL_TIME =
1093        new Primitive0("get-last-event-internal-time", PACKAGE_J, true)
1094    {
1095        public LispObject execute() throws ConditionThrowable
1096        {
1097            return number(Dispatcher.getLastEventMillis());
1098        }
1099    };
1100
1101    public static void invokeOpenFileHook(Buffer buffer)
1102    {
1103        try {
1104            Primitives.FUNCALL.execute(PACKAGE_J.intern("INVOKE-HOOK"),
1105                                       PACKAGE_J.intern("OPEN-FILE-HOOK"),
1106                                       new JavaObject(buffer));
1107        }
1108        catch (Throwable JavaDoc t) {
1109            Log.debug(t);
1110        }
1111    }
1112
1113    public static void invokeBufferActivatedHook(Buffer buffer)
1114    {
1115        if (buffer != null) {
1116            try {
1117                Primitives.FUNCALL.execute(PACKAGE_J.intern("INVOKE-HOOK"),
1118                                           PACKAGE_J.intern("BUFFER-ACTIVATED-HOOK"),
1119                                           new JavaObject(buffer));
1120            }
1121            catch (Throwable JavaDoc t) {
1122                Log.debug(t);
1123            }
1124        }
1125    }
1126
1127    public static void invokeAfterSaveHook(Buffer buffer)
1128    {
1129        try {
1130            Primitives.FUNCALL.execute(PACKAGE_J.intern("INVOKE-HOOK"),
1131                                       PACKAGE_J.intern("AFTER-SAVE-HOOK"),
1132                                       new JavaObject(buffer));
1133        }
1134        catch (Throwable JavaDoc t) {
1135            Log.debug(t);
1136        }
1137    }
1138
1139    public static void invokeLispShellStartupHook(Buffer buffer, String JavaDoc command)
1140    {
1141        try {
1142            Primitives.FUNCALL.execute(PACKAGE_J.intern("INVOKE-HOOK"),
1143                                       PACKAGE_J.intern("LISP-SHELL-STARTUP-HOOK"),
1144                                       new JavaObject(buffer),
1145                                       new SimpleString(command));
1146        }
1147        catch (Throwable JavaDoc t) {
1148            Log.debug(t);
1149        }
1150    }
1151
1152    // ### invoke-later
1153
public static final Primitive1 INVOKE_LATER =
1154        new Primitive1("invoke-later", PACKAGE_J, true)
1155    {
1156        public LispObject execute(LispObject arg) throws ConditionThrowable
1157        {
1158            final LispObject fun;
1159            if (arg instanceof Symbol)
1160                fun = arg.getSymbolFunction();
1161            else
1162                fun = arg;
1163            if (fun instanceof Function || fun instanceof GenericFunction) {
1164                Runnable JavaDoc r = new Runnable JavaDoc() {
1165                    public void run()
1166                    {
1167                        try {
1168                            funcall0(fun, LispThread.currentThread());
1169                        }
1170                        catch (Throwable JavaDoc t) {
1171                            Log.error(t);
1172                        }
1173                    }
1174                };
1175                SwingUtilities.invokeLater(r);
1176                return NIL;
1177            }
1178            return signal(new UndefinedFunction(arg));
1179        }
1180    };
1181
1182    // ### make-buffer-stream buffer => stream
1183
private static final Primitive MAKE_BUFFER_STREAM =
1184        new Primitive("make-buffer-stream", PACKAGE_J, true)
1185    {
1186        public LispObject execute() throws ConditionThrowable
1187        {
1188            return new BufferStream(new Buffer(0));
1189        }
1190
1191        public LispObject execute(LispObject arg) throws ConditionThrowable
1192        {
1193            return new BufferStream(checkBuffer(arg));
1194        }
1195    };
1196
1197    // ### buffer-stream-buffer stream => buffer
1198
private static final Primitive1 BUFFER_STREAM_BUFFER =
1199        new Primitive1("buffer-stream-buffer", PACKAGE_J, true)
1200    {
1201        public LispObject execute(LispObject arg) throws ConditionThrowable
1202        {
1203            if (arg instanceof BufferStream)
1204                return new JavaObject(((BufferStream)arg).getBuffer());
1205            return signal(new TypeError(arg, "BUFFER-STREAM"));
1206        }
1207    };
1208
1209    // ### pop-to-buffer buffer => buffer
1210
private static final Primitive POP_TO_BUFFER =
1211        new Primitive("pop-to-buffer", PACKAGE_J, true)
1212    {
1213        public LispObject execute(LispObject arg) throws ConditionThrowable
1214        {
1215            if (arg != NIL) {
1216                Buffer buffer = checkBuffer(arg);
1217                Editor editor = Editor.currentEditor();
1218                editor.makeNext(buffer);
1219                editor.activateInOtherWindow(buffer);
1220            }
1221            return arg;
1222        }
1223    };
1224
1225    // ### switch-to-buffer buffer => buffer
1226
private static final Primitive switch_TO_BUFFER =
1227        new Primitive("switch-to-buffer", PACKAGE_J, true)
1228    {
1229        public LispObject execute(LispObject arg) throws ConditionThrowable
1230        {
1231            Buffer buffer = checkBuffer(arg);
1232            Editor editor = Editor.currentEditor();
1233            editor.makeNext(buffer);
1234            editor.activate(buffer);
1235            return arg;
1236        }
1237    };
1238
1239    // ### %status string => generalized-boolean
1240
private static final Primitive STATUS =
1241        new Primitive("status", PACKAGE_J, true, "string")
1242    {
1243        public LispObject execute(LispObject arg) throws ConditionThrowable
1244        {
1245            if (arg instanceof AbstractString) {
1246                final String JavaDoc s = ((AbstractString)arg).getStringValue();
1247                Runnable JavaDoc r = new Runnable JavaDoc() {
1248                    public void run()
1249                    {
1250                        try {
1251                            Editor.currentEditor().status(s);
1252                        }
1253                        catch (Throwable JavaDoc t) {
1254                            Log.error(t);
1255                        }
1256                    }
1257                };
1258                SwingUtilities.invokeLater(r);
1259                return T;
1260            }
1261            return signal(new TypeError(arg, Symbol.STRING));
1262        }
1263
1264        public LispObject execute(LispObject first, LispObject second)
1265            throws ConditionThrowable
1266        {
1267            if (first instanceof AbstractString) {
1268                final String JavaDoc s = ((AbstractString)first).getStringValue();
1269                final Editor editor = checkEditor(second);
1270                Runnable JavaDoc r = new Runnable JavaDoc() {
1271                    public void run()
1272                    {
1273                        try {
1274                            editor.status(s);
1275                        }
1276                        catch (Throwable JavaDoc t) {
1277                            Log.error(t);
1278                        }
1279                    }
1280                };
1281                SwingUtilities.invokeLater(r);
1282                return T;
1283            }
1284            return signal(new TypeError(first, Symbol.STRING));
1285        }
1286    };
1287
1288    // ### %search
1289
private static final Primitive _SEARCH =
1290        new Primitive("%search", PACKAGE_J, false,
1291                      "pattern direction regexp-p buffer start ignore-case-p whole-words-only-p")
1292    {
1293        public LispObject execute(LispObject[] args) throws ConditionThrowable
1294        {
1295            if (args.length != 7)
1296                return signal(new WrongNumberOfArgumentsException(this));
1297            final String JavaDoc pattern;
1298            if (args[0] instanceof AbstractString)
1299                pattern = args[0].getStringValue();
1300            else
1301                return signal(new TypeError(args[0], Symbol.STRING));
1302            final boolean backward;
1303            Symbol direction = checkSymbol(args[1]);
1304            if (direction == NIL || direction.getName().equals("BACKWARD"))
1305                backward = true;
1306            else if (direction.getName().equals("FORWARD"))
1307                backward = false;
1308            else
1309                return signal(new LispError("Invalid direction " + direction.writeToString()));
1310            final Buffer buffer = checkBuffer(args[3]);
1311            final Position start;
1312            if (args[4] == NIL)
1313                start = Editor.currentEditor().getDot();
1314            else
1315                start = checkMark(args[4]);
1316            final boolean ignoreCase = (args[5] != NIL);
1317            final boolean wholeWordsOnly = (args[6] != NIL);
1318            Search search =
1319                new Search(pattern, ignoreCase, wholeWordsOnly);
1320            final Position pos;
1321            if (args[2] != NIL) {
1322                try {
1323                    search.setREFromPattern();
1324                }
1325                catch (REException e) {
1326                    return signal(new LispError("Invalid regular expression: \"" +
1327                                                pattern + '"'));
1328                }
1329                if (backward)
1330                    pos = search.reverseFindRegExp(buffer, start);
1331                else
1332                    pos = search.findRegExp(buffer, start);
1333            } else {
1334                if (backward)
1335                    pos = search.reverseFindString(buffer, start);
1336                else
1337                    pos = search.findString(buffer, start);
1338            }
1339            return pos != null ? new JavaObject(pos) : NIL;
1340        }
1341    };
1342
1343    // ### find-file-buffer pathname => buffer
1344
private static final Primitive FIND_FILE_BUFFER =
1345        new Primitive("find-file-buffer", PACKAGE_J, true, "pathname")
1346    {
1347        public LispObject execute(LispObject arg) throws ConditionThrowable
1348        {
1349            final Pathname pathname = Pathname.coerceToPathname(arg);
1350            final String JavaDoc namestring = pathname.getNamestring();
1351            if (namestring != null) {
1352                final Editor editor = Editor.currentEditor();
1353                final Buffer buffer = editor.getBuffer(File.getInstance(namestring));
1354                if (buffer != null)
1355                    return new JavaObject(buffer);
1356            }
1357            return NIL;
1358        }
1359    };
1360
1361    // ### defun-at-point => string
1362
private static final Primitive CURRENT_DEFUN =
1363        new Primitive("defun-at-point", PACKAGE_J, true, "")
1364    {
1365        public LispObject execute() throws ConditionThrowable
1366        {
1367            String JavaDoc s = LispMode.getCurrentDefun(Editor.currentEditor());
1368            return s != null ? new SimpleString(s) : NIL;
1369        }
1370    };
1371
1372    // ### forward-sexp
1373
private static final Primitive FORWARD_SEXP =
1374        new Primitive("forward-sexp", PACKAGE_J, true, "")
1375    {
1376        public LispObject execute() throws ConditionThrowable
1377        {
1378            LispMode.forwardSexp();
1379            return NIL;
1380        }
1381    };
1382
1383    // ### backward-sexp
1384
private static final Primitive BACKWARD_SEXP =
1385        new Primitive("backward-sexp", PACKAGE_J, true, "")
1386    {
1387        public LispObject execute() throws ConditionThrowable
1388        {
1389            LispMode.backwardSexp();
1390            return NIL;
1391        }
1392    };
1393
1394    static {
1395        for (Iterator JavaDoc it = Property.iterator(); it.hasNext();)
1396            JVar.addVariableForProperty((Property)it.next());
1397    }
1398}
1399
Popular Tags