Source Code Cross Referenced for LispMode.java in  » IDE » J » org » armedbear » j » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » J » org.armedbear.j 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * LispMode.java
0003:         *
0004:         * Copyright (C) 1998-2004 Peter Graves
0005:         * $Id: LispMode.java,v 1.82 2004/09/13 13:49:09 piso Exp $
0006:         *
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License
0009:         * as published by the Free Software Foundation; either version 2
0010:         * of the License, or (at your option) any later version.
0011:         *
0012:         * This program is distributed in the hope that it will be useful,
0013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015:         * GNU General Public License for more details.
0016:         *
0017:         * You should have received a copy of the GNU General Public License
0018:         * along with this program; if not, write to the Free Software
0019:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
0020:         */
0021:
0022:        package org.armedbear.j;
0023:
0024:        import java.awt.event.KeyEvent;
0025:        import java.util.HashMap;
0026:        import java.util.StringTokenizer;
0027:        import org.armedbear.lisp.Interpreter;
0028:        import org.armedbear.lisp.Lisp;
0029:        import org.armedbear.lisp.LispObject;
0030:
0031:        public class LispMode extends AbstractMode implements  Constants, Mode {
0032:            private static final LispMode mode = new LispMode();
0033:
0034:            private LispMode() {
0035:                super (LISP_MODE, LISP_MODE_NAME);
0036:                keywords = new Keywords(this );
0037:                setProperty(Property.INDENT_SIZE, 2);
0038:                setProperty(Property.HIGHLIGHT_BRACKETS, true);
0039:            }
0040:
0041:            protected LispMode(int id, String displayName) {
0042:                super (id, displayName);
0043:            }
0044:
0045:            public static Mode getMode() {
0046:                return mode;
0047:            }
0048:
0049:            public String getCommentStart() {
0050:                return ";; ";
0051:            }
0052:
0053:            public final SyntaxIterator getSyntaxIterator(Position pos) {
0054:                return new LispSyntaxIterator(pos);
0055:            }
0056:
0057:            public Formatter getFormatter(Buffer buffer) {
0058:                return new LispFormatter(buffer);
0059:            }
0060:
0061:            protected void setKeyMapDefaults(KeyMap km) {
0062:                km.mapKey(KeyEvent.VK_TAB, 0, "tab");
0063:                km.mapKey(KeyEvent.VK_TAB, CTRL_MASK, "insertTab");
0064:                km.mapKey(KeyEvent.VK_F12, 0, "wrapComment");
0065:                km.mapKey(KeyEvent.VK_ENTER, 0, "newlineAndIndent");
0066:                km.mapKey(KeyEvent.VK_T, CTRL_MASK, "findTag");
0067:                km.mapKey(KeyEvent.VK_PERIOD, ALT_MASK, "findTagAtDot");
0068:                km.mapKey(KeyEvent.VK_COMMA, ALT_MASK, "listMatchingTagsAtDot");
0069:                km.mapKey(KeyEvent.VK_PERIOD, CTRL_MASK | ALT_MASK,
0070:                        "findTagAtDotOtherWindow");
0071:                km.mapKey(')', "closeParen");
0072:                km.mapKey(KeyEvent.VK_F1, ALT_MASK, "hyperspec");
0073:                km.mapKey(KeyEvent.VK_F, CTRL_MASK | ALT_MASK, "forwardSexp");
0074:                km.mapKey(KeyEvent.VK_B, CTRL_MASK | ALT_MASK, "backwardSexp");
0075:                km.mapKey(KeyEvent.VK_D, CTRL_MASK | ALT_MASK, "downList");
0076:                km
0077:                        .mapKey(KeyEvent.VK_U, CTRL_MASK | ALT_MASK,
0078:                                "backwardUpList");
0079:                km.mapKey(KeyEvent.VK_X, CTRL_MASK | ALT_MASK, "evalDefunLisp");
0080:                km.mapKey(KeyEvent.VK_C, CTRL_MASK | ALT_MASK,
0081:                        "compileDefunLisp");
0082:                km
0083:                        .mapKey(KeyEvent.VK_R, CTRL_MASK | ALT_MASK,
0084:                                "evalRegionLisp");
0085:                km.mapKey(KeyEvent.VK_M, CTRL_MASK, "lispFindMatchingChar");
0086:                km.mapKey(KeyEvent.VK_M, CTRL_MASK | SHIFT_MASK,
0087:                        "lispSelectSyntax");
0088:                km.mapKey(KeyEvent.VK_9, CTRL_MASK | SHIFT_MASK,
0089:                        "insertParentheses");
0090:                km.mapKey(KeyEvent.VK_0, CTRL_MASK | SHIFT_MASK,
0091:                        "movePastCloseAndReindent");
0092:            }
0093:
0094:            public void populateModeMenu(Editor editor, Menu menu) {
0095:                boolean enabled = LispShell.findLisp(null) != null;
0096:                if (isSlimeLoaded()) {
0097:                    menu.add(editor, "Eval Region", 'R',
0098:                            "(slime:slime-eval-region)", enabled);
0099:                    menu.add(editor, "Eval Defun", 'D',
0100:                            "(slime:slime-eval-defun)", enabled);
0101:                    menu.add(editor, "Compile Defun", 'C',
0102:                            "(slime:slime-compile-defun)", enabled);
0103:                    menu.add(editor, "Load File", 'L',
0104:                            "(slime:slime-load-file)", enabled);
0105:                    menu.add(editor, "Compile File", 'F',
0106:                            "(slime:slime-compile-file)", enabled);
0107:                    menu.add(editor, "Compile and Load File", 'A',
0108:                            "(slime:slime-compile-and-load-file)", enabled);
0109:                } else {
0110:                    menu.add(editor, "Eval Region", 'R', "evalRegionLisp",
0111:                            enabled);
0112:                    menu.add(editor, "Eval Defun", 'D', "evalDefunLisp",
0113:                            enabled);
0114:                    menu.add(editor, "Compile Defun", 'C', "compileDefunLisp",
0115:                            enabled);
0116:                    menu.add(editor, "Load File", 'L', "loadLispFile", enabled);
0117:                    menu.add(editor, "Compile File", 'F', "compileLispFile",
0118:                            enabled);
0119:                    menu.add(editor, "Compile and Load File", 'A',
0120:                            "compileAndLoadLispFile", enabled);
0121:                }
0122:            }
0123:
0124:            private static final boolean isSlimeLoaded() {
0125:                if (Editor.isLispInitialized()) {
0126:                    try {
0127:                        LispObject result = Interpreter
0128:                                .evaluate("(sys:featurep :slime)");
0129:                        return (result != Lisp.NIL) ? true : false;
0130:                    } catch (Throwable t) {
0131:                        Log.debug(t);
0132:                    }
0133:                }
0134:                return false;
0135:            }
0136:
0137:            public boolean isTaggable() {
0138:                return true;
0139:            }
0140:
0141:            public Tagger getTagger(SystemBuffer buffer) {
0142:                return new LispTagger(buffer);
0143:            }
0144:
0145:            private static final String validChars = "!$%&*+-./0123456789<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{}~";
0146:
0147:            public final boolean isIdentifierStart(char c) {
0148:                return validChars.indexOf(c) >= 0;
0149:            }
0150:
0151:            public final boolean isIdentifierPart(char c) {
0152:                return validChars.indexOf(c) >= 0;
0153:            }
0154:
0155:            private static final HashMap definers = new HashMap();
0156:
0157:            static {
0158:                String[] strings = new String[] { "defclass", "defconstant",
0159:                        "defgeneric", "define-condition", "defmacro",
0160:                        "defmethod", "defparameter", "defstruct", "deftype",
0161:                        "defun", "defvar" };
0162:                for (int i = strings.length; i-- > 0;)
0163:                    definers.put(strings[i], strings[i]);
0164:                // SBCL
0165:                definers.put("def!struct", "defstruct");
0166:                definers.put("defmacro-mundanely", "defmacro");
0167:                definers.put("def!macro", "defmacro");
0168:                // Slime
0169:                definers.put("defslimefun", "defun");
0170:                definers.put("definterface", "defgeneric");
0171:                definers.put("defimplementation", "defmethod");
0172:            }
0173:
0174:            public static final String translateDefiner(String s) {
0175:                if (s.length() >= 5 && s.startsWith("def"))
0176:                    return (String) definers.get(s);
0177:                return null;
0178:            }
0179:
0180:            public boolean isInQuote(Buffer buffer, Position pos) {
0181:                // This implementation only considers the current line.
0182:                final Line line = pos.getLine();
0183:                final int offset = pos.getOffset();
0184:                boolean inQuote = false;
0185:                for (int i = 0; i < offset; i++) {
0186:                    char c = line.charAt(i);
0187:                    if (c == '\\') {
0188:                        // Escape.
0189:                        ++i;
0190:                    } else if (inQuote) {
0191:                        if (c == '"')
0192:                            inQuote = false;
0193:                    } else if (c == '"') {
0194:                        inQuote = true;
0195:                    }
0196:                }
0197:                return inQuote;
0198:            }
0199:
0200:            public boolean canIndent() {
0201:                return true;
0202:            }
0203:
0204:            private final String[] specials = new String[] { "block", "case",
0205:                    "catch", "do-all-symbols", "do-external-symbols",
0206:                    "do-symbols", "dolist", "dotimes", "ecase", "etypecase",
0207:                    "eval-when", "flet", "handler-bind", "labels", "lambda",
0208:                    "let", "let*", "locally", "loop", "macrolet",
0209:                    "multiple-value-bind", "progn", "typecase", "unless",
0210:                    "when" };
0211:
0212:            private final String[] elispSpecials = new String[] { "while" };
0213:
0214:            private final String[] hemlockSpecials = new String[] { "frob",
0215:                    "with-mark" };
0216:
0217:            public int getCorrectIndentation(Line line, Buffer buffer) {
0218:                final Line model = findModel(line);
0219:                if (model == null)
0220:                    return 0;
0221:                final int modelIndent = buffer.getIndentation(model);
0222:                final String modelTrim = model.trim();
0223:                if (line.flags() == STATE_QUOTE) {
0224:                    if (modelTrim.length() > 0 && modelTrim.charAt(0) == '"')
0225:                        return modelIndent + 1;
0226:                    else
0227:                        return modelIndent;
0228:                }
0229:                if (modelTrim.length() == 0)
0230:                    return 0;
0231:                if (modelTrim.charAt(0) == ';')
0232:                    return modelIndent;
0233:                final int indentSize = buffer.getIndentSize();
0234:                Position here = new Position(line, 0);
0235:                Position pos = findContainingSexp(here);
0236:                if (pos == null) // Top level.
0237:                    return 0;
0238:                Debug.bugIfNot(pos.getChar() == '(');
0239:                int offset = pos.getOffset();
0240:                if (offset > 1) {
0241:                    if (new Position(pos.getLine(), offset - 2)
0242:                            .lookingAt("'#("))
0243:                        return buffer.getCol(pos) + 1;
0244:                }
0245:                if (offset > 0) {
0246:                    if (pos.getLine().charAt(offset - 1) == '\'')
0247:                        return buffer.getCol(pos) + 1;
0248:                }
0249:                Position posFirst = downList(pos);
0250:                if (posFirst != null) {
0251:                    if (posFirst.equals(here))
0252:                        return buffer.getCol(pos) + 1;
0253:                    char firstChar = posFirst.getChar();
0254:                    if (firstChar == '(' || firstChar == ',') {
0255:                        // First element of containing sexp is a list or backquote
0256:                        // expansion.
0257:                        return buffer.getCol(posFirst);
0258:                    }
0259:                    // Otherwise...
0260:                    String token = gatherToken(posFirst);
0261:                    if (token.equals("do") || token.equals("do*")) {
0262:                        // Skip DO/DO*.
0263:                        Position p1 = forwardSexp(posFirst);
0264:                        if (p1 != null) {
0265:                            // Skip whitespace to get to opening '(' of variable list.
0266:                            p1.skipWhitespace();
0267:                            // Skip past variable list.
0268:                            Position p2 = forwardSexp(p1);
0269:                            if (p2 != null) {
0270:                                // Skip past end test form.
0271:                                p2 = forwardSexp(p2);
0272:                                // Make sure line numbers are right for isBefore().
0273:                                if (buffer.needsRenumbering())
0274:                                    buffer.renumber();
0275:                                if (p2 != null && here.isBefore(p2)) {
0276:                                    // This is the end test form. Indent it under the
0277:                                    // opening '(' of the variable list
0278:                                    return buffer.getCol(p1);
0279:                                }
0280:                            }
0281:                        }
0282:                        return buffer.getCol(pos) + indentSize;
0283:                    }
0284:                    if (token.equals("handler-case")) {
0285:                        Position p1 = forwardSexp(posFirst);
0286:                        if (p1 != null) {
0287:                            // Skip whitespace to get to opening '(' of form to be
0288:                            // evaluated.
0289:                            p1.skipWhitespace();
0290:                            // Make sure line numbers are right for isBefore().
0291:                            if (buffer.needsRenumbering())
0292:                                buffer.renumber();
0293:                            if (here.isBefore(p1))
0294:                                return buffer.getCol(pos) + indentSize * 2;
0295:                        }
0296:                        return buffer.getCol(pos) + indentSize;
0297:                    }
0298:                    if (token.startsWith("def")
0299:                            || Utilities.isOneOf(token, specials)
0300:                            || Utilities.isOneOf(token, elispSpecials)
0301:                            || Utilities.isOneOf(token, hemlockSpecials)
0302:                            || token.startsWith("with-"))
0303:                        return buffer.getCol(pos) + indentSize;
0304:                    // Not special. Indent under the second element of the containing
0305:                    // list, if the second element is on the same line as the first.
0306:                    Position posSecond = forwardSexp(posFirst);
0307:                    if (posSecond != null) {
0308:                        posSecond.skipWhitespace();
0309:                        if (posSecond.getChar() != ';')
0310:                            if (posSecond.getLine() == pos.getLine())
0311:                                return buffer.getCol(posSecond);
0312:                    }
0313:                }
0314:                return buffer.getCol(pos) + 1;
0315:            }
0316:
0317:            private static Line findModel(Line line) {
0318:                Line model = line.previous();
0319:                if (line.flags() == STATE_COMMENT) {
0320:                    // Any non-blank line is an acceptable model.
0321:                    while (model != null && model.isBlank())
0322:                        model = model.previous();
0323:                } else {
0324:                    while (model != null) {
0325:                        if (isAcceptableModel(model))
0326:                            break; // Found an acceptable model.
0327:                        else
0328:                            model = model.previous();
0329:                    }
0330:                }
0331:                return model;
0332:            }
0333:
0334:            private static boolean isAcceptableModel(Line model) {
0335:                String trim = model.trim();
0336:                if (trim.length() == 0)
0337:                    return false;
0338:                if (trim.charAt(0) == ';')
0339:                    return false;
0340:                return true;
0341:            }
0342:
0343:            private String gatherToken(Position start) {
0344:                Position pos = start.copy();
0345:                FastStringBuffer sb = new FastStringBuffer();
0346:                while (true) {
0347:                    char c = pos.getChar();
0348:                    if (Character.isWhitespace(c))
0349:                        break;
0350:                    sb.append(c);
0351:                    if (!pos.next())
0352:                        break;
0353:                }
0354:                return sb.toString();
0355:            }
0356:
0357:            private static Position findStartOfDefun(Position pos) {
0358:                Line line = pos.getLine();
0359:                while (true) {
0360:                    if (line.getText().startsWith("(def"))
0361:                        return new Position(line, 0);
0362:                    Line prev = line.previous();
0363:                    if (prev == null)
0364:                        return new Position(line, 0);
0365:                    line = prev;
0366:                }
0367:            }
0368:
0369:            public static Position findContainingSexp(Position start) {
0370:                LispSyntaxIterator it = new LispSyntaxIterator(start);
0371:                int parenCount = 0;
0372:                while (true) {
0373:                    switch (it.prevChar()) {
0374:                    case ')':
0375:                        ++parenCount;
0376:                        break;
0377:                    case '(':
0378:                        if (parenCount == 0) {
0379:                            // Found unmatched '('.
0380:                            return it.getPosition();
0381:                        }
0382:                        --parenCount;
0383:                        break;
0384:                    case SyntaxIterator.DONE:
0385:                        return null;
0386:                    default:
0387:                        break;
0388:                    }
0389:                }
0390:            }
0391:
0392:            private Position downList(Position start) {
0393:                if (start == null)
0394:                    return null;
0395:                Position pos = start.copy();
0396:                // Skip whitespace and comments.
0397:                char c;
0398:                while (true) {
0399:                    pos.skipWhitespace();
0400:                    c = pos.getChar();
0401:                    if (c == ';')
0402:                        skipComment(pos);
0403:                    else
0404:                        break;
0405:                }
0406:                // Reached non-whitespace char.
0407:                while (true) {
0408:                    if (c == ')')
0409:                        return null; // "Containing expression ends prematurely."
0410:                    if (c == '(') {
0411:                        // List starting.
0412:                        if (!pos.next())
0413:                            return null;
0414:                        // Skip whitespace and comments.
0415:                        while (true) {
0416:                            pos.skipWhitespace();
0417:                            c = pos.getChar();
0418:                            if (c == ';')
0419:                                skipComment(pos);
0420:                            else
0421:                                break;
0422:                        }
0423:                        if (pos.atEnd())
0424:                            return null;
0425:                        return pos;
0426:                    }
0427:                    if (c == '"') {
0428:                        // Skip string.
0429:                        skipString(pos);
0430:                        if (pos.atEnd())
0431:                            return null;
0432:                        continue;
0433:                    }
0434:                    if (c == ';') {
0435:                        skipComment(pos);
0436:                        if (pos.atEnd())
0437:                            return null;
0438:                        continue;
0439:                    }
0440:                    if (!pos.next())
0441:                        return null;
0442:                    c = pos.getChar();
0443:                }
0444:            }
0445:
0446:            public static void downList() {
0447:                final Editor editor = Editor.currentEditor();
0448:                if (editor.getMode() instanceof  LispMode) {
0449:                    Position pos = mode.downList(editor.getDot());
0450:                    if (pos != null)
0451:                        editor.moveDotTo(pos);
0452:                }
0453:            }
0454:
0455:            public static void backwardUpList() {
0456:                final Editor editor = Editor.currentEditor();
0457:                if (editor.getMode() instanceof  LispMode) {
0458:                    Position pos = findContainingSexp(editor.getDot());
0459:                    if (pos != null)
0460:                        editor.moveDotTo(pos);
0461:                }
0462:            }
0463:
0464:            private void skipString(Position pos) {
0465:                while (true) {
0466:                    if (!pos.next())
0467:                        return;
0468:                    switch (pos.getChar()) {
0469:                    case '\\':
0470:                        if (!pos.next())
0471:                            return;
0472:                        break;
0473:                    case '"':
0474:                        pos.next();
0475:                        return;
0476:                    }
0477:                }
0478:            }
0479:
0480:            private Position forwardSexp(Position start) {
0481:                if (start == null)
0482:                    return null;
0483:                Position pos = start.copy();
0484:                // Skip whitespace and comments.
0485:                char c;
0486:                while (true) {
0487:                    pos.skipWhitespace();
0488:                    c = pos.getChar();
0489:                    if (c == ';')
0490:                        skipComment(pos);
0491:                    else
0492:                        break;
0493:                }
0494:                // Reached non-whitespace char.
0495:                if (c == ')')
0496:                    return null; // "Containing expression ends prematurely."
0497:                if (c == '(') {
0498:                    // List starting.
0499:                    int parenCount = 1;
0500:                    while (true) {
0501:                        if (!pos.next())
0502:                            return null;
0503:                        switch (pos.getChar()) {
0504:                        case ';':
0505:                            skipComment(pos);
0506:                            break;
0507:                        case ')':
0508:                            --parenCount;
0509:                            if (parenCount == 0) {
0510:                                if (pos.next())
0511:                                    return pos;
0512:                                else
0513:                                    return null;
0514:                            }
0515:                            break;
0516:                        case '(':
0517:                            ++parenCount;
0518:                            break;
0519:                        default:
0520:                            break;
0521:                        }
0522:                    }
0523:                }
0524:                if (c == '"') {
0525:                    while (true) {
0526:                        if (!pos.next())
0527:                            return null;
0528:                        switch (pos.getChar()) {
0529:                        case '\\':
0530:                            if (!pos.next())
0531:                                return null;
0532:                            break;
0533:                        case '"':
0534:                            if (!pos.next())
0535:                                return null;
0536:                            return pos;
0537:                        default:
0538:                            break;
0539:                        }
0540:                    }
0541:                }
0542:                // Otherwise...
0543:                while (true) {
0544:                    if (!pos.next())
0545:                        return null;
0546:                    c = pos.getChar();
0547:                    if (Character.isWhitespace(c) || c == '(' || c == ')')
0548:                        return pos;
0549:                }
0550:            }
0551:
0552:            private Position backwardSexp(Position start) {
0553:                Position pos = findContainingSexp(start);
0554:                if (pos == null) {
0555:                    // Top level.
0556:                    LispSyntaxIterator it = new LispSyntaxIterator(start);
0557:                    while (true) {
0558:                        char c = it.prevChar();
0559:                        if (c == SyntaxIterator.DONE)
0560:                            return null;
0561:                        if (!Character.isWhitespace(c)) {
0562:                            pos = it.getPosition();
0563:                            break;
0564:                        }
0565:                    }
0566:                    if (pos.getChar() == ')')
0567:                        return findContainingSexp(pos);
0568:                    while (true) {
0569:                        if (!pos.prev())
0570:                            return pos;
0571:                        if (Character.isWhitespace(pos.getChar())) {
0572:                            pos.next();
0573:                            return pos;
0574:                        }
0575:                    }
0576:                }
0577:                pos = downList(pos);
0578:                if (pos == null)
0579:                    return null;
0580:                while (true) {
0581:                    Position last = pos;
0582:                    pos = forwardSexp(pos);
0583:                    if (pos == null)
0584:                        return last;
0585:                    // Skip whitespace and comments.
0586:                    char c;
0587:                    while (true) {
0588:                        pos.skipWhitespace();
0589:                        c = pos.getChar();
0590:                        if (c == ';')
0591:                            skipComment(pos);
0592:                        else
0593:                            break;
0594:                    }
0595:                    if (c == ')')
0596:                        return last;
0597:                    if (pos.equals(start))
0598:                        return last;
0599:                    if (pos.isAfter(start))
0600:                        return last;
0601:                }
0602:            }
0603:
0604:            // Advances pos to start of next line.
0605:            private static void skipComment(Position pos) {
0606:                Line nextLine = pos.getNextLine();
0607:                if (nextLine != null)
0608:                    pos.moveTo(nextLine, 0);
0609:            }
0610:
0611:            public static void forwardSexp() {
0612:                final Editor editor = Editor.currentEditor();
0613:                if (editor.getMode() instanceof  LispMode) {
0614:                    Position pos = mode.forwardSexp(editor.getDot());
0615:                    if (pos != null)
0616:                        editor.moveDotTo(pos);
0617:                }
0618:            }
0619:
0620:            public static void backwardSexp() {
0621:                final Editor editor = Editor.currentEditor();
0622:                if (editor.getMode() instanceof  LispMode) {
0623:                    Position pos = mode.backwardSexp(editor.getDot());
0624:                    if (pos != null)
0625:                        editor.moveDotTo(pos);
0626:                }
0627:            }
0628:
0629:            public static void lispFindMatchingChar() {
0630:                final Editor editor = Editor.currentEditor();
0631:                Position dot = editor.getDotCopy();
0632:                if (dot == null)
0633:                    return;
0634:                Position pos = findDelimiterNear(dot);
0635:                editor.setWaitCursor();
0636:                Position match = editor.findMatchInternal(pos, 0);
0637:                editor.setDefaultCursor();
0638:                if (match != null) {
0639:                    // Move past closing parenthesis.
0640:                    if (match.getChar() == ')')
0641:                        match.next();
0642:                    editor.addUndo(SimpleEdit.MOVE);
0643:                    editor.unmark();
0644:                    editor.updateDotLine();
0645:                    editor.getDot().moveTo(match);
0646:                    editor.updateDotLine();
0647:                    editor.moveCaretToDotCol();
0648:                } else
0649:                    editor.status("No match");
0650:            }
0651:
0652:            public static void lispSelectSyntax() {
0653:                final Editor editor = Editor.currentEditor();
0654:                Position dot = editor.getDotCopy();
0655:                if (dot == null)
0656:                    return;
0657:                Position pos;
0658:                if (editor.getMark() != null) {
0659:                    pos = findContainingSexp(dot);
0660:                } else {
0661:                    pos = findDelimiterNear(dot);
0662:                    if (pos == null)
0663:                        pos = findContainingSexp(dot);
0664:                }
0665:                if (pos == null)
0666:                    return;
0667:                editor.setWaitCursor();
0668:                Position match = editor.findMatchInternal(pos, 0);
0669:                if (match != null) {
0670:                    if (pos.getChar() == ')')
0671:                        pos.next();
0672:                    else if (match.getChar() == ')')
0673:                        match.next();
0674:                    if (pos.getLine() != match.getLine()) {
0675:                        // Extend selection to full lines if possible.
0676:                        Region r = new Region(editor.getBuffer(), pos, match);
0677:                        Position begin = r.getBegin();
0678:                        if (begin.getLine().substring(0, begin.getOffset())
0679:                                .trim().length() == 0) {
0680:                            Position end = r.getEnd();
0681:                            String trim = end.getLine().substring(
0682:                                    end.getOffset()).trim();
0683:                            if (trim.length() == 0 || trim.charAt(0) == ';') {
0684:                                // Extend selection to complete lines.
0685:                                begin.setOffset(0);
0686:                                if (end.getNextLine() != null)
0687:                                    end.moveTo(end.getNextLine(), 0);
0688:                                else
0689:                                    end.setOffset(end.getLineLength());
0690:                                if (pos.isBefore(match)) {
0691:                                    pos = begin;
0692:                                    match = end;
0693:                                } else {
0694:                                    match = begin;
0695:                                    pos = end;
0696:                                }
0697:                            }
0698:                        }
0699:                    }
0700:                    editor.addUndo(SimpleEdit.MOVE);
0701:                    editor.unmark();
0702:                    editor.getDot().moveTo(pos);
0703:                    editor.setMarkAtDot();
0704:                    editor.updateDotLine();
0705:                    editor.getDot().moveTo(match);
0706:                    editor.updateDotLine();
0707:                    editor.moveCaretToDotCol();
0708:                    if (editor.getDotLine() != editor.getMarkLine())
0709:                        editor.setUpdateFlag(REPAINT);
0710:                } else
0711:                    editor.status("No match");
0712:                editor.setDefaultCursor();
0713:            }
0714:
0715:            private static Position findDelimiterNear(Position pos) {
0716:                Position saved = pos.copy();
0717:                if (pos.getChar() == '(')
0718:                    return pos;
0719:                if (pos.getOffset() > 0) {
0720:                    pos.prev();
0721:                    if (pos.getChar() == ')')
0722:                        return pos;
0723:                }
0724:                // Go back to original starting point.
0725:                pos.moveTo(saved);
0726:                while (pos.getOffset() > 0) {
0727:                    // Look at previous char.
0728:                    pos.prev();
0729:                    char c = pos.getChar();
0730:                    if (c == '(' || c == ')')
0731:                        return pos;
0732:                }
0733:                // Go back to original starting point.
0734:                pos.moveTo(saved);
0735:                final int limit = pos.getLineLength() - 1;
0736:                while (pos.getOffset() < limit) {
0737:                    // Look at next char.
0738:                    pos.next();
0739:                    char c = pos.getChar();
0740:                    if (c == '(' || c == ')')
0741:                        return pos;
0742:                    if (c == ';')
0743:                        return null; // The rest of the line is a comment.
0744:                }
0745:                return null;
0746:            }
0747:
0748:            private static Editor getLispShellEditor(Editor editor) {
0749:                Editor ed = editor.getOtherEditor();
0750:                if (ed != null) {
0751:                    Buffer b = ed.getBuffer();
0752:                    if (b instanceof  CommandInterpreter) {
0753:                        CommandInterpreter comint = (CommandInterpreter) b;
0754:                        if (comint.isLisp())
0755:                            return ed;
0756:                    }
0757:                }
0758:                CommandInterpreter lisp = LispShell.findLisp(null);
0759:                if (lisp == null) {
0760:                    MessageDialog.showMessageDialog("No Lisp shell is running",
0761:                            "Error");
0762:                    return null;
0763:                }
0764:                ed = findEditor(lisp);
0765:                if (ed != null)
0766:                    return ed;
0767:                return editor.displayInOtherWindow(lisp);
0768:            }
0769:
0770:            private static Editor findEditor(Buffer buf) {
0771:                Editor ed = null;
0772:                for (EditorIterator it = new EditorIterator(); it.hasNext();) {
0773:                    ed = it.nextEditor();
0774:                    if (ed.getBuffer() == buf)
0775:                        return ed;
0776:                }
0777:                return null;
0778:            }
0779:
0780:            public static String getCurrentDefun(Editor editor) {
0781:                Position begin = findStartOfDefun(editor.getDot());
0782:                if (begin != null && begin.lookingAt("(def")) {
0783:                    Position end = mode.forwardSexp(begin);
0784:                    if (end != null) {
0785:                        Region r = new Region(editor.getBuffer(), begin, end);
0786:                        return r.toString().trim();
0787:                    }
0788:                }
0789:                return null;
0790:            }
0791:
0792:            private static String getDefunName(String s) {
0793:                StringTokenizer st = new StringTokenizer(s);
0794:                int count = st.countTokens();
0795:                if (count >= 2) {
0796:                    // Skip first token.
0797:                    st.nextToken();
0798:                    // Return second token.
0799:                    return st.nextToken().toUpperCase();
0800:                }
0801:                return "";
0802:            }
0803:
0804:            public static void evalDefunLisp() {
0805:                final Editor editor = Editor.currentEditor();
0806:                if (editor.getMode() != mode)
0807:                    return;
0808:                Editor ed = getLispShellEditor(editor);
0809:                if (ed != null) {
0810:                    CommandInterpreter lisp = (CommandInterpreter) ed
0811:                            .getBuffer();
0812:                    String defun = getCurrentDefun(editor);
0813:                    if (defun != null) {
0814:                        String name = getDefunName(defun);
0815:                        if (name != null) {
0816:                            Position end = lisp.getEnd();
0817:                            end.getLine().setFlags(STATE_INPUT);
0818:                            lisp.insertString(end, ";;; Evaluating defun "
0819:                                    + name + " ...\n");
0820:                            lisp.renumber();
0821:                            ed.eob();
0822:                            ed.getDotLine().setFlags(0);
0823:                            lisp.send(defun);
0824:                        }
0825:                    }
0826:                }
0827:            }
0828:
0829:            public static void compileDefunLisp() {
0830:                final Editor editor = Editor.currentEditor();
0831:                if (editor.getMode() != mode)
0832:                    return;
0833:                Editor ed = getLispShellEditor(editor);
0834:                if (ed != null) {
0835:                    CommandInterpreter lisp = (CommandInterpreter) ed
0836:                            .getBuffer();
0837:                    String defun = getCurrentDefun(editor);
0838:                    if (defun != null) {
0839:                        String name = getDefunName(defun);
0840:                        if (name != null) {
0841:                            Position end = lisp.getEnd();
0842:                            end.getLine().setFlags(STATE_INPUT);
0843:                            lisp.insertString(end, ";;; Compiling defun "
0844:                                    + name + " ...\n");
0845:                            lisp.renumber();
0846:                            ed.eob();
0847:                            ed.getDotLine().setFlags(0);
0848:                            lisp.send("(CL:PROGN " + defun + " (CL:COMPILE '"
0849:                                    + name + "))\n");
0850:                        }
0851:                    }
0852:                }
0853:            }
0854:
0855:            public static void evalRegionLisp() {
0856:                final Editor editor = Editor.currentEditor();
0857:                if (editor.getMode() != mode)
0858:                    return;
0859:                if (editor.getMark() == null)
0860:                    return;
0861:                if (editor.isColumnSelection()) {
0862:                    editor.notSupportedForColumnSelections();
0863:                    return;
0864:                }
0865:                Editor ed = getLispShellEditor(editor);
0866:                if (ed != null) {
0867:                    CommandInterpreter lisp = (CommandInterpreter) ed
0868:                            .getBuffer();
0869:                    Position bufEnd = lisp.getEnd();
0870:                    bufEnd.getLine().setFlags(STATE_INPUT);
0871:                    lisp.insertString(bufEnd, ";;; Evaluating region ...\n");
0872:                    lisp.renumber();
0873:                    ed.eob();
0874:                    ed.getDotLine().setFlags(0);
0875:                    lisp.send(new Region(editor).toString().trim());
0876:                }
0877:            }
0878:
0879:            public static void loadLispFile() {
0880:                final Editor editor = Editor.currentEditor();
0881:                if (editor.getMode() != mode)
0882:                    return;
0883:                Editor ed = getLispShellEditor(editor);
0884:                if (ed != null) {
0885:                    Buffer buffer = editor.getBuffer();
0886:                    boolean save = false;
0887:                    if (buffer.isModified()) {
0888:                        int response = ConfirmDialog
0889:                                .showConfirmDialogWithCancelButton(editor,
0890:                                        CHECK_SAVE_PROMPT, "Load File");
0891:                        switch (response) {
0892:                        case RESPONSE_YES:
0893:                            save = true;
0894:                            break;
0895:                        case RESPONSE_NO:
0896:                            break;
0897:                        case RESPONSE_CANCEL:
0898:                            return;
0899:                        }
0900:                        editor.repaintNow();
0901:                    }
0902:                    if (!save || buffer.save()) {
0903:                        CommandInterpreter lisp = (CommandInterpreter) ed
0904:                                .getBuffer();
0905:                        String path = editor.getBuffer().getFile()
0906:                                .canonicalPath();
0907:                        if (path != null) {
0908:                            Position end = lisp.getEnd();
0909:                            end.getLine().setFlags(STATE_INPUT);
0910:                            lisp.insertString(end, ";;; Loading file " + path
0911:                                    + " ...\n");
0912:                            lisp.renumber();
0913:                            ed.eob();
0914:                            ed.getDotLine().setFlags(0);
0915:                            lisp.send("(CL:LOAD \"" + path + "\")\n");
0916:                        }
0917:                    }
0918:                }
0919:            }
0920:
0921:            public static void compileLispFile() {
0922:                final Editor editor = Editor.currentEditor();
0923:                if (editor.getMode() != mode)
0924:                    return;
0925:                Editor ed = getLispShellEditor(editor);
0926:                if (ed != null) {
0927:                    Buffer buffer = editor.getBuffer();
0928:                    boolean save = false;
0929:                    if (buffer.isModified()) {
0930:                        int response = ConfirmDialog
0931:                                .showConfirmDialogWithCancelButton(editor,
0932:                                        CHECK_SAVE_PROMPT, "Compile File");
0933:                        switch (response) {
0934:                        case RESPONSE_YES:
0935:                            save = true;
0936:                            break;
0937:                        case RESPONSE_NO:
0938:                            break;
0939:                        case RESPONSE_CANCEL:
0940:                            return;
0941:                        }
0942:                        editor.repaintNow();
0943:                    }
0944:                    if (!save || buffer.save()) {
0945:                        CommandInterpreter lisp = (CommandInterpreter) ed
0946:                                .getBuffer();
0947:                        String path = editor.getBuffer().getFile()
0948:                                .canonicalPath();
0949:                        if (path != null) {
0950:                            Position end = lisp.getEnd();
0951:                            end.getLine().setFlags(STATE_INPUT);
0952:                            lisp.insertString(end, ";;; Compiling " + path
0953:                                    + " ...\n");
0954:                            lisp.renumber();
0955:                            ed.eob();
0956:                            ed.getDotLine().setFlags(0);
0957:                            lisp.send("(CL:COMPILE-FILE \"" + path + "\")\n");
0958:                        }
0959:                    }
0960:                }
0961:            }
0962:
0963:            public static void compileAndLoadLispFile() {
0964:                final Editor editor = Editor.currentEditor();
0965:                if (editor.getMode() != mode)
0966:                    return;
0967:                Editor ed = getLispShellEditor(editor);
0968:                if (ed != null) {
0969:                    Buffer buffer = editor.getBuffer();
0970:                    boolean save = false;
0971:                    if (buffer.isModified()) {
0972:                        int response = ConfirmDialog
0973:                                .showConfirmDialogWithCancelButton(editor,
0974:                                        CHECK_SAVE_PROMPT,
0975:                                        "Compile and Load File");
0976:                        switch (response) {
0977:                        case RESPONSE_YES:
0978:                            save = true;
0979:                            break;
0980:                        case RESPONSE_NO:
0981:                            break;
0982:                        case RESPONSE_CANCEL:
0983:                            return;
0984:                        }
0985:                        editor.repaintNow();
0986:                    }
0987:                    if (!save || buffer.save()) {
0988:                        CommandInterpreter lisp = (CommandInterpreter) ed
0989:                                .getBuffer();
0990:                        String path = editor.getBuffer().getFile()
0991:                                .canonicalPath();
0992:                        if (path != null) {
0993:                            Position end = lisp.getEnd();
0994:                            end.getLine().setFlags(STATE_INPUT);
0995:                            lisp.insertString(end, ";;; Compiling and loading "
0996:                                    + path + " ...\n");
0997:                            lisp.renumber();
0998:                            ed.eob();
0999:                            ed.getDotLine().setFlags(0);
1000:                            lisp.send("(CL:LOAD (CL:COMPILE-FILE \"" + path
1001:                                    + "\"))\n");
1002:                        }
1003:                    }
1004:                }
1005:            }
1006:
1007:            private static HashMap map;
1008:
1009:            public static void hyperspec() {
1010:                hyperspec(null);
1011:            }
1012:
1013:            public static void hyperspec(String s) {
1014:                final Editor editor = Editor.currentEditor();
1015:                if (s == null) {
1016:                    if (editor.getDot() == null)
1017:                        return;
1018:                    char c = editor.getDotChar();
1019:                    if (c == ')' || Character.isWhitespace(c)) {
1020:                        final Line dotLine = editor.getDotLine();
1021:                        final String text = dotLine.getText();
1022:                        for (int offset = editor.getDotOffset(); offset-- > 0;) {
1023:                            c = text.charAt(offset);
1024:                            if (mode.isIdentifierPart(c)) {
1025:                                s = mode.getIdentifier(dotLine, offset);
1026:                                break;
1027:                            }
1028:                        }
1029:                    } else
1030:                        s = mode.getIdentifier(editor.getDot());
1031:                    if (s == null)
1032:                        return;
1033:                }
1034:                if (s.length() == 0)
1035:                    return;
1036:                final Buffer buffer = editor.getBuffer();
1037:                String clhsRoot = buffer.getStringProperty(Property.CLHS_ROOT);
1038:                File rootDir = File.getInstance(clhsRoot);
1039:                if (rootDir == null || rootDir.isRemote()
1040:                        || !rootDir.isDirectory())
1041:                    return;
1042:                if (map == null) {
1043:                    File file = File.getInstance(rootDir, "Data/Map_Sym.txt");
1044:                    if (!file.isFile())
1045:                        return;
1046:                    SystemBuffer buf = new SystemBuffer(file);
1047:                    buf.load();
1048:                    if (!buf.isLoaded())
1049:                        return;
1050:                    map = new HashMap();
1051:                    Line line = buf.getFirstLine();
1052:                    while (true) {
1053:                        String key = line.trim().toLowerCase();
1054:                        line = line.next();
1055:                        if (line == null)
1056:                            break;
1057:                        if (line != null) {
1058:                            String value = line.trim();
1059:                            if (key.length() > 0 && value.length() > 0)
1060:                                map.put(key, value);
1061:                        }
1062:                        line = line.next();
1063:                        if (line == null)
1064:                            break;
1065:                    }
1066:                }
1067:                String filename = (String) map.get(s.toLowerCase());
1068:                if (filename == null) {
1069:                    editor.status("No entry for \"" + s + '"');
1070:                    return;
1071:                }
1072:                String rootPath = rootDir.canonicalPath();
1073:                File dataDir = File.getInstance(rootDir, "Data");
1074:                File file = File.getInstance(dataDir, filename);
1075:                WebBuffer buf = null;
1076:                // Look for existing buffer.
1077:                if (buffer instanceof  WebBuffer) {
1078:                    if (buffer.getFile().canonicalPath().startsWith(rootPath))
1079:                        buf = (WebBuffer) buffer;
1080:                }
1081:                if (buf == null) {
1082:                    for (BufferIterator it = new BufferIterator(); it.hasNext();) {
1083:                        Buffer b = it.nextBuffer();
1084:                        if (b instanceof  WebBuffer) {
1085:                            if (b.getFile().canonicalPath()
1086:                                    .startsWith(rootPath)) {
1087:                                buf = (WebBuffer) b;
1088:                                break;
1089:                            }
1090:                        }
1091:                    }
1092:                }
1093:                if (buf != null)
1094:                    buf.go(file, 0, "text/html");
1095:                else {
1096:                    buf = WebBuffer.createWebBuffer(file, null, null);
1097:                    buf.setTransient(true);
1098:                }
1099:                if (editor.getBuffer() != buf) {
1100:                    Editor otherEditor = editor.getOtherEditor();
1101:                    if (otherEditor != null) {
1102:                        buf.setUnsplitOnClose(false);
1103:                        otherEditor.makeNext(buf);
1104:                    } else
1105:                        editor.makeNext(buf);
1106:                    editor.displayInOtherWindow(buf);
1107:                }
1108:            }
1109:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.