KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * JavaScriptMode.java
3  *
4  * Copyright (C) 1998-2003 Peter Graves
5  * $Id: JavaScriptMode.java,v 1.2 2003/06/12 16:35:05 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 java.awt.event.KeyEvent JavaDoc;
25
26 public final class JavaScriptMode extends JavaMode implements Constants, Mode
27 {
28     // Since this class is final, we may as well construct the singleton class
29
// instance right away.
30
private static JavaScriptMode mode = new JavaScriptMode();
31
32     private JavaScriptMode()
33     {
34         super(JAVASCRIPT_MODE, JAVASCRIPT_MODE_NAME);
35         keywords = new Keywords(this);
36     }
37
38     public static final Mode getMode()
39     {
40         return mode;
41     }
42
43     public final Formatter getFormatter(Buffer buffer)
44     {
45         return new JavaFormatter(buffer, LANGUAGE_JAVASCRIPT);
46     }
47
48     protected void setKeyMapDefaults(KeyMap km)
49     {
50         super.setKeyMapDefaults(km);
51         km.mapKey(KeyEvent.VK_ENTER, CTRL_MASK, "newline");
52     }
53
54     public void populateModeMenu(Editor editor, Menu menu)
55     {
56         // No mode menu yet.
57
}
58
59     public int getCorrectIndentation(Line line, Buffer buffer)
60     {
61         final int indentSize = buffer.getIndentSize();
62         int indent = 0;
63         String JavaDoc text = line.trim();
64
65         if (text.startsWith("}")) {
66             Position pos = new Position(line, line.getText().indexOf('}'));
67             pos = matchClosingBrace(pos);
68             pos = findBeginningOfStatement(pos);
69             indent = buffer.getIndentation(pos.getLine());
70             return indent;
71         }
72
73         String JavaDoc identifier = getFirstIdentifier(line);
74
75         if (identifier.equals("case") || identifier.equals("default")) {
76             Line switchLine = findSwitch(line);
77             if (switchLine != null)
78                 indent = buffer.getIndentation(switchLine) + indentSize;
79             return indent;
80         }
81
82         Position paren = findEnclosingParen(new Position(line, 0) );
83
84         if (paren != null) {
85             if (text.startsWith(")"))
86                 return buffer.getIndentation(paren.getLine());
87             if (paren.getLine().trim().endsWith("(") ||
88                 !buffer.getBooleanProperty(Property.LINEUP_ARGLIST)) {
89                 indent = buffer.getIndentation(paren.getLine()) + indentSize;
90             } else {
91                 paren.skip(1);
92                 while (paren.getOffset() < paren.getLineLength() &&
93                     paren.getLine().charAt(paren.getOffset()) <= ' ') {
94                     paren.skip(1);
95                 }
96                 if (paren.getOffset() <= paren.getLineLength())
97                     indent = buffer.getCol(paren);
98             }
99             return indent;
100         }
101
102         // Figure out indentation of previous non-blank line.
103
Line model = findModel(line);
104
105         if (model == null)
106             return 0;
107
108         if (line.flags() == STATE_COMMENT) {
109             indent = buffer.getIndentation(model);
110             String JavaDoc s = model.getText().trim();
111             if (s.startsWith("/*") && text.startsWith("*"))
112                 return indent + 1;
113             else
114                 return indent;
115         }
116
117         String JavaDoc modelText = trimSyntacticWhitespace(model.getText());
118         final boolean indentBeforeBrace =
119             buffer.getBooleanProperty(Property.INDENT_BEFORE_BRACE);
120         if (modelText.endsWith("}")) {
121             indent = buffer.getIndentation(model);
122             if (indentBeforeBrace)
123                 indent -= indentSize;
124             return indent;
125         }
126
127         Position bos = findBeginningOfStatement(new Position(model, 0));
128         indent = buffer.getIndentation(bos.getLine());
129         final boolean indentAfterBrace =
130             buffer.getBooleanProperty(Property.INDENT_AFTER_BRACE);
131
132         if (modelText.endsWith(")")) {
133             Position pos = new Position(model, model.length()-1);
134             while (pos.getChar() != ')')
135                 pos.skip(-1);
136             pos = matchClosingParen(pos);
137             indent = buffer.getIndentation(pos.getLine());
138
139             // Loose JavaScript
140
String JavaDoc s = pos.getLine().trim();
141
142             if (s.startsWith("}"))
143                 s = s.substring(1).trim();
144
145             String JavaDoc firstToken = getFirstIdentifier(s);
146
147             if (!firstToken.equals("if") &&
148                 !firstToken.equals("else") &&
149                 !firstToken.equals("for") &&
150                 !firstToken.equals("while") &&
151                 !firstToken.equals("switch")) {
152                 Position begin = findBeginningOfBlock(pos);
153                 if (begin != null) {
154                     indent = buffer.getIndentation(begin.getLine());
155                     if (indentAfterBrace)
156                         indent += indentSize;
157                 }
158                 return indent;
159             }
160
161             if (indentBeforeBrace || !text.startsWith("{"))
162                 indent += indentSize;
163
164             return indent;
165         }
166
167         String JavaDoc lastIdentifier = getLastIdentifier(modelText);
168
169         if (lastIdentifier != null && lastIdentifier.equals("else")) {
170             if (indentBeforeBrace || !text.startsWith("{"))
171                 indent += indentSize;
172             return indent;
173         }
174
175         if (isContinued(modelText)) {
176             // Continuation line.
177
Position pos = findBeginningOfStatement(new Position(model, 0));
178             return buffer.getIndentation(pos.getLine()) + indentSize;
179         }
180
181         String JavaDoc modelFirstIdentifier = getFirstIdentifier(model);
182
183         if (modelFirstIdentifier.equals("case")) {
184             if (indentBeforeBrace || !text.startsWith("{"))
185                 indent += indentSize;
186         } else if (modelFirstIdentifier.equals("default")) {
187             if (indentBeforeBrace || !text.startsWith("{"))
188                 indent += indentSize;
189         } else if (modelText.endsWith("{")) {
190             if (indentAfterBrace)
191                 indent += indentSize;
192         } else {
193             // Match indentation of beginning of statement.
194
Position pos = findBeginningOfStatement(new Position(model, 0));
195             indent = buffer.getIndentation(pos.getLine());
196         }
197
198         return indent;
199     }
200
201     private boolean isContinued(String JavaDoc text)
202     {
203         if (text.length() == 0)
204             return false;
205         return isContinued(text, text.charAt(text.length()-1));
206     }
207
208     private static Position findBeginningOfBlock(Position pos)
209     {
210         JavaSyntaxIterator iter = new JavaSyntaxIterator(pos);
211
212         int count = 1;
213
214         while (true) {
215             char c = iter.prevChar();
216
217             if (c == JavaSyntaxIterator.DONE)
218                 return null;
219
220             if (c == '}')
221                 ++count;
222             else if (c == '{')
223                 --count;
224
225             if (count == 0)
226                 return iter.getPosition();
227         }
228     }
229 }
230
Popular Tags