diff --git a/apisupport.project/nbproject/project.xml b/apisupport.project/nbproject/project.xml
--- a/apisupport.project/nbproject/project.xml
+++ b/apisupport.project/nbproject/project.xml
@@ -139,8 +139,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/beans/nbproject/project.xml b/beans/nbproject/project.xml
--- a/beans/nbproject/project.xml
+++ b/beans/nbproject/project.xml
@@ -116,8 +116,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/bpel.debugger.ui/nbproject/project.xml b/bpel.debugger.ui/nbproject/project.xml
--- a/bpel.debugger.ui/nbproject/project.xml
+++ b/bpel.debugger.ui/nbproject/project.xml
@@ -96,8 +96,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/bugtracking.bridge/nbproject/project.xml b/bugtracking.bridge/nbproject/project.xml
--- a/bugtracking.bridge/nbproject/project.xml
+++ b/bugtracking.bridge/nbproject/project.xml
@@ -36,8 +36,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/cnd.asm/nbproject/project.xml b/cnd.asm/nbproject/project.xml
--- a/cnd.asm/nbproject/project.xml
+++ b/cnd.asm/nbproject/project.xml
@@ -27,7 +27,7 @@
3
- 1.41
+ 1.53
@@ -44,8 +44,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/cnd.completion/nbproject/project.xml b/cnd.completion/nbproject/project.xml
--- a/cnd.completion/nbproject/project.xml
+++ b/cnd.completion/nbproject/project.xml
@@ -87,7 +87,7 @@
3
- 1.41
+ 1.53
@@ -122,8 +122,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/cnd.debugger.common/nbproject/project.xml b/cnd.debugger.common/nbproject/project.xml
--- a/cnd.debugger.common/nbproject/project.xml
+++ b/cnd.debugger.common/nbproject/project.xml
@@ -79,8 +79,8 @@
- 2
- 2.7
+ 3
+ 3.1
diff --git a/cnd.debugger.gdb/nbproject/project.xml b/cnd.debugger.gdb/nbproject/project.xml
--- a/cnd.debugger.gdb/nbproject/project.xml
+++ b/cnd.debugger.gdb/nbproject/project.xml
@@ -124,8 +124,8 @@
- 2
- 2.7
+ 3
+ 3.1
diff --git a/cnd.editor/nbproject/project.xml b/cnd.editor/nbproject/project.xml
--- a/cnd.editor/nbproject/project.xml
+++ b/cnd.editor/nbproject/project.xml
@@ -36,7 +36,7 @@
3
- 1.41
+ 1.53
@@ -71,8 +71,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/cnd.editor/src/org/netbeans/modules/cnd/editor/cplusplus/CCKit.java b/cnd.editor/src/org/netbeans/modules/cnd/editor/cplusplus/CCKit.java
--- a/cnd.editor/src/org/netbeans/modules/cnd/editor/cplusplus/CCKit.java
+++ b/cnd.editor/src/org/netbeans/modules/cnd/editor/cplusplus/CCKit.java
@@ -47,7 +47,6 @@
import java.awt.event.ActionEvent;
import javax.swing.Action;
import javax.swing.text.Caret;
-import javax.swing.text.Position;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.TextAction;
@@ -228,52 +227,52 @@
return;
}
- final BaseDocument doc = (BaseDocument) target.getDocument();
+ final BaseDocument doc = (BaseDocument)target.getDocument();
+ final Reformat formatter = Reformat.get(doc);
+
// Set hourglass cursor
Cursor origCursor = target.getCursor();
target.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
+ formatter.lock();
+ try {
+ doc.runAtomic(new Runnable() {
- doc.runAtomicAsUser(new Runnable() {
+ public void run() {
+ try {
+ Caret caret = target.getCaret();
- public void run() {
- try {
- Caret caret = target.getCaret();
+ int caretLine = Utilities.getLineOffset(doc, caret.getDot());
+ int start;
+ int end;
+ //if (caret.isSelectionVisible()) {
+ if (Utilities.isSelectionShowing(caret)) {
+ start = target.getSelectionStart();
+ end = target.getSelectionEnd();
+ } else {
+ start = 0;
+ end = doc.getLength();
+ }
- int caretLine = Utilities.getLineOffset(doc, caret.getDot());
- int startPos;
- Position endPosition;
- //if (caret.isSelectionVisible()) {
- if (Utilities.isSelectionShowing(caret)) {
- startPos = target.getSelectionStart();
- endPosition = doc.createPosition(target.getSelectionEnd());
- } else {
- startPos = 0;
- endPosition = doc.createPosition(doc.getLength());
+ formatter.reformat(start, end);
+
+ // Restore the line
+ int pos = Utilities.getRowStartFromLineOffset(doc, caretLine);
+ if (pos >= 0) {
+ caret.setDot(pos);
+ }
+ } catch (BadLocationException e) {
+ //failed to format
}
+ }
+ });
+ } finally {
+ formatter.unlock();
+ }
- int pos = startPos;
- Reformat reformat = Reformat.get(doc);
- reformat.lock();
- try {
- reformat.reformat(pos, endPosition.getOffset());
- } finally {
- reformat.unlock();
- }
-
- // Restore the line
- pos = Utilities.getRowStartFromLineOffset(doc, caretLine);
- if (pos >= 0) {
- caret.setDot(pos);
- }
- } catch (BadLocationException e) {
- //failed to format
- }
- }
- });
target.setCursor(origCursor);
-
- }
- }
+ }
+ }
}
public static class CCDefaultKeyTypedAction extends ExtDefaultKeyTypedAction {
@@ -372,8 +371,7 @@
}
doc.insertString(end, "\n" + insString, null); // NOI18N
// Lock does not need because method is invoked from BaseKit that already lock indent.
- Indent indent = Indent.get(doc);
- indent.reindent(end + 1);
+ Indent.get(doc).indentNewLine(end);
caret.setDot(dotPos);
return Boolean.TRUE;
}
diff --git a/cnd.editor/src/org/netbeans/modules/cnd/editor/cplusplus/InsertSemicolonAction.java b/cnd.editor/src/org/netbeans/modules/cnd/editor/cplusplus/InsertSemicolonAction.java
--- a/cnd.editor/src/org/netbeans/modules/cnd/editor/cplusplus/InsertSemicolonAction.java
+++ b/cnd.editor/src/org/netbeans/modules/cnd/editor/cplusplus/InsertSemicolonAction.java
@@ -38,6 +38,7 @@
import org.netbeans.editor.BaseDocument;
import org.netbeans.editor.Utilities;
import org.netbeans.modules.editor.indent.api.Indent;
+import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
/**
@@ -72,30 +73,34 @@
return;
}
final BaseDocument doc = (BaseDocument) target.getDocument();
+ final Indent indenter = Indent.get(doc);
final class R implements Runnable {
public void run() {
- Caret caret = target.getCaret();
- int dotpos = caret.getDot();
try {
+ Caret caret = target.getCaret();
+ int dotpos = caret.getDot();
int eoloffset = Utilities.getRowEnd(target, dotpos);
- String insertString = "" + what;
- doc.insertString(eoloffset, insertString, null); //NOI18N
+ doc.insertString(eoloffset, "" + what, null); //NOI18N
if (withNewline) {
- Indent indent = Indent.get(doc);
- indent.lock();
- try {
- int eolDot = Utilities.getRowEnd(target, caret.getDot());
- doc.insertString(eolDot, "\n", null); // NOI18N
- caret.setDot(eolDot+1);
- indent.reindent(eolDot+1);
- } finally {
- indent.unlock();
- }
+ //This is code from the editor module, but it is
+ //a pretty strange way to do this:
+ doc.insertString(dotpos, "-", null); //NOI18N
+ doc.remove(dotpos, 1);
+ int eolDot = Utilities.getRowEnd(target, caret.getDot());
+ int newDotPos = indenter.indentNewLine(eolDot);
+ caret.setDot(newDotPos);
}
} catch (BadLocationException ex) {
+ Exceptions.printStackTrace(ex);
}
}
}
- doc.runAtomicAsUser(new R());
+
+ indenter.lock();
+ try {
+ doc.runAtomicAsUser(new R());
+ } finally {
+ indenter.lock();
+ }
}
}
diff --git a/cnd.editor/src/org/netbeans/modules/cnd/editor/options/EditorPropertySheet.java b/cnd.editor/src/org/netbeans/modules/cnd/editor/options/EditorPropertySheet.java
--- a/cnd.editor/src/org/netbeans/modules/cnd/editor/options/EditorPropertySheet.java
+++ b/cnd.editor/src/org/netbeans/modules/cnd/editor/options/EditorPropertySheet.java
@@ -55,6 +55,8 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
@@ -62,14 +64,11 @@
import javax.swing.JEditorPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
-import org.netbeans.api.editor.mimelookup.MimeLookup;
import org.netbeans.api.editor.settings.SimpleValueNames;
import org.netbeans.editor.BaseDocument;
import org.netbeans.modules.cnd.editor.api.CodeStyle;
import org.netbeans.modules.cnd.editor.options.PreviewPreferencesModel.Filter;
import org.netbeans.modules.cnd.editor.reformat.Reformatter;
-import org.netbeans.modules.cnd.utils.MIMENames;
-import org.netbeans.modules.editor.indent.api.IndentUtils;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.explorer.propertysheet.PropertySheet;
@@ -98,7 +97,6 @@
private PreviewPreferencesModel preferencesModel;
private Filter filter;
private PropertySheet holder;
- private Object[] originalEditorProperties = null;
EditorPropertySheet(EditorOptionsPanelController topControler, CodeStyle.Language language, PreviewPreferencesModel preferencesModel, Filter filter) {
this.topController = topControler;
@@ -383,9 +381,6 @@
void load() {
loaded = false;
- if (filter == Filter.All) {
- originalEditorProperties = preserveEditorProperties();
- }
initLanguageMap();
initLanguageCategory();
loaded = true;
@@ -449,10 +444,6 @@
if (filter != Filter.All) {
return;
}
- if (originalEditorProperties != null) {
- restoreEditorProperties(originalEditorProperties);
- originalEditorProperties = null;
- }
preferencesModel.clear(language);
}
@@ -581,7 +572,7 @@
is.close();
}
} catch (IOException ioe) {
- ioe.printStackTrace();
+ Logger.getLogger(EditorPropertySheet.class.getName()).log(Level.FINE, null, ioe);
}
return sb.toString();
} else {
@@ -593,127 +584,10 @@
pane.setText(getPreviewText());
BaseDocument bd = (BaseDocument) pane.getDocument();
CodeStyle codeStyle = EditorOptions.createCodeStyle(language, p, false);
- setEditorProperties(p);
try {
- if (TRACE) {
- System.err.println("Refreshing preview"); // NOI18N
- System.err.println(" tabSize=" + IndentUtils.tabSize(bd)+"/"+codeStyle.getTabSize()); // NOI18N
- System.err.println(" expandTabs=" + IndentUtils.isExpandTabs(bd)+"/"+codeStyle.expandTabToSpaces()); // NOI18N
- System.err.println(" indentLevelSize=" + IndentUtils.indentLevelSize(bd)+"/"+codeStyle.indentSize()); // NOI18N
- System.err.println(" doc=" + bd); //NOI18N
- }
new Reformatter(bd, codeStyle).reformat();
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
- } catch (Throwable ex) {
- ex.printStackTrace();
- }
- }
-
- private void setEditorProperties(Preferences p) {
- Preferences def = null;
- switch (language){
- case C:
- def = MimeLookup.getLookup(MIMENames.C_MIME_TYPE).lookup(Preferences.class);
- break;
- case HEADER:
- def = MimeLookup.getLookup(MIMENames.HEADER_MIME_TYPE).lookup(Preferences.class);
- break;
- case CPP:
- default:
- def = MimeLookup.getLookup(MIMENames.CPLUSPLUS_MIME_TYPE).lookup(Preferences.class);
- break;
- }
- if (def != null) {
- def.putInt(SimpleValueNames.TAB_SIZE, p.getInt(EditorOptions.tabSize, EditorOptions.tabSizeDefault));
- def.putInt(SimpleValueNames.SPACES_PER_TAB, p.getInt(EditorOptions.tabSize, EditorOptions.tabSizeDefault));
- def.putBoolean(SimpleValueNames.EXPAND_TABS, p.getBoolean(EditorOptions.expandTabToSpaces, EditorOptions.expandTabToSpacesDefault));
- def.putInt(SimpleValueNames.INDENT_SHIFT_WIDTH, p.getInt(EditorOptions.indentSize, EditorOptions.indentSizeDefault));
- }
- }
-
- private Object[] preserveEditorProperties() {
- Preferences def = null;
- Object oldValues[] = null;
- switch (language){
- case C:
- def = MimeLookup.getLookup(MIMENames.C_MIME_TYPE).lookup(Preferences.class);
- break;
- case HEADER:
- def = MimeLookup.getLookup(MIMENames.HEADER_MIME_TYPE).lookup(Preferences.class);
- break;
- case CPP:
- default:
- def = MimeLookup.getLookup(MIMENames.CPLUSPLUS_MIME_TYPE).lookup(Preferences.class);
- break;
- }
- if (def != null) {
- oldValues = new Object[]{null, null, null, null};
- if (null != def.get(SimpleValueNames.TAB_SIZE, null)) {
- oldValues[0] = def.getInt(SimpleValueNames.TAB_SIZE, EditorOptions.tabSizeDefault);
- }
- if (null != def.get(SimpleValueNames.SPACES_PER_TAB, null)) {
- oldValues[1] = def.getInt(SimpleValueNames.SPACES_PER_TAB, EditorOptions.tabSizeDefault);
- }
- if (null != def.get(SimpleValueNames.EXPAND_TABS, null)) {
- oldValues[2] = def.getBoolean(SimpleValueNames.EXPAND_TABS, EditorOptions.expandTabToSpacesDefault);
- }
- if (null != def.get(SimpleValueNames.INDENT_SHIFT_WIDTH, null)) {
- oldValues[3] = def.getInt(SimpleValueNames.INDENT_SHIFT_WIDTH, EditorOptions.indentSizeDefault);
- }
- if (TRACE) {
- System.err.println("Preserving editor properties:"); //NOI18N
- System.err.println(" tabSize=" + oldValues[0]); //NOI18N
- System.err.println(" spacesPerTab=" + oldValues[1]); //NOI18N
- System.err.println(" expandTabs=" + oldValues[2]); //NOI18N
- System.err.println(" indentShiftWidth=" + oldValues[3]); //NOI18N
- }
- }
- return oldValues;
- }
-
- private void restoreEditorProperties(Object[] oldValues) {
- Preferences def = null;
- switch (language){
- case C:
- def = MimeLookup.getLookup(MIMENames.C_MIME_TYPE).lookup(Preferences.class);
- break;
- case HEADER:
- def = MimeLookup.getLookup(MIMENames.HEADER_MIME_TYPE).lookup(Preferences.class);
- break;
- case CPP:
- default:
- def = MimeLookup.getLookup(MIMENames.CPLUSPLUS_MIME_TYPE).lookup(Preferences.class);
- break;
- }
- if (def != null && oldValues != null) {
- if (TRACE) {
- System.err.println("Restoring editor properties:"); //NOI18N
- System.err.println(" tabSize=" + oldValues[0]); //NOI18N
- System.err.println(" spacesPerTab=" + oldValues[1]); //NOI18N
- System.err.println(" expandTabs=" + oldValues[2]); //NOI18N
- System.err.println(" indentShiftWidth=" + oldValues[3]); //NOI18N
- }
- if (oldValues[0] == null) {
- def.remove(SimpleValueNames.TAB_SIZE);
- } else {
- def.putInt(SimpleValueNames.TAB_SIZE, ((Integer)oldValues[0]).intValue());
- }
- if (oldValues[1] == null) {
- def.remove(SimpleValueNames.SPACES_PER_TAB);
- } else {
- def.putInt(SimpleValueNames.SPACES_PER_TAB, ((Integer)oldValues[1]).intValue());
- }
- if (oldValues[2] == null) {
- def.remove(SimpleValueNames.EXPAND_TABS);
- } else {
- def.putBoolean(SimpleValueNames.EXPAND_TABS, ((Boolean)oldValues[2]).booleanValue());
- }
- if (oldValues[3] == null) {
- def.remove(SimpleValueNames.INDENT_SHIFT_WIDTH);
- } else {
- def.putInt(SimpleValueNames.INDENT_SHIFT_WIDTH, ((Integer)oldValues[3]).intValue());
- }
}
}
diff --git a/cnd.editor/test/unit/src/org/netbeans/modules/cnd/editor/cplusplus/BracketCompletionTestCase.java b/cnd.editor/test/unit/src/org/netbeans/modules/cnd/editor/cplusplus/BracketCompletionTestCase.java
--- a/cnd.editor/test/unit/src/org/netbeans/modules/cnd/editor/cplusplus/BracketCompletionTestCase.java
+++ b/cnd.editor/test/unit/src/org/netbeans/modules/cnd/editor/cplusplus/BracketCompletionTestCase.java
@@ -33,6 +33,8 @@
import org.netbeans.modules.cnd.editor.api.CodeStyle;
import org.netbeans.modules.cnd.editor.options.EditorOptions;
+import org.netbeans.modules.editor.indent.api.Indent;
+import org.openide.util.Exceptions;
/**
* Class was taken from java
diff --git a/cnd.editor/test/unit/src/org/netbeans/modules/cnd/editor/cplusplus/EditorBase.java b/cnd.editor/test/unit/src/org/netbeans/modules/cnd/editor/cplusplus/EditorBase.java
--- a/cnd.editor/test/unit/src/org/netbeans/modules/cnd/editor/cplusplus/EditorBase.java
+++ b/cnd.editor/test/unit/src/org/netbeans/modules/cnd/editor/cplusplus/EditorBase.java
@@ -42,6 +42,7 @@
import org.netbeans.modules.cnd.editor.reformat.Reformatter;
import org.netbeans.modules.cnd.test.base.BaseDocumentUnitTestCase;
import org.netbeans.modules.editor.indent.api.Indent;
+import org.netbeans.modules.editor.indent.api.Reformat;
import org.openide.util.Exceptions;
/**
@@ -145,14 +146,22 @@
/**
* Perform reformatting of the whole document's text.
*/
- protected final void reformat() {
- Reformatter f = new Reformatter(getDocument(), CodeStyle.getDefault(getDocument()));
+ protected void reformat() {
+ Reformat f = Reformat.get(getDocument());
+ f.lock();
try {
- f.reformat();
+ getDocument().atomicLock();
+ try {
+ f.reformat(0, getDocument().getLength());
+ } finally {
+ getDocument().atomicUnlock();
+ }
} catch (BadLocationException e) {
e.printStackTrace(getLog());
fail(e.getMessage());
- }
+ } finally {
+ f.unlock();
+ }
}
// ------- help methods -------------
diff --git a/cnd.gizmo/nbproject/project.xml b/cnd.gizmo/nbproject/project.xml
--- a/cnd.gizmo/nbproject/project.xml
+++ b/cnd.gizmo/nbproject/project.xml
@@ -152,8 +152,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/cnd.gotodeclaration/nbproject/project.xml b/cnd.gotodeclaration/nbproject/project.xml
--- a/cnd.gotodeclaration/nbproject/project.xml
+++ b/cnd.gotodeclaration/nbproject/project.xml
@@ -50,6 +50,33 @@
+ org.netbeans.modules.editor.completion
+
+
+
+ 1
+ 1.6.12
+
+
+
+ org.netbeans.modules.editor.lib
+
+
+
+ 3
+ 3.1
+
+
+
+ org.netbeans.modules.editor.settings
+
+
+
+ 1
+ 1.4.12
+
+
+ org.netbeans.modules.jumpto
diff --git a/cnd.highlight/nbproject/project.xml b/cnd.highlight/nbproject/project.xml
--- a/cnd.highlight/nbproject/project.xml
+++ b/cnd.highlight/nbproject/project.xml
@@ -106,8 +106,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/cnd.modelimpl/nbproject/project.xml b/cnd.modelimpl/nbproject/project.xml
--- a/cnd.modelimpl/nbproject/project.xml
+++ b/cnd.modelimpl/nbproject/project.xml
@@ -105,8 +105,8 @@
- 2
- 2.10
+ 3
+ 3.1
diff --git a/cnd.modelutil/nbproject/project.xml b/cnd.modelutil/nbproject/project.xml
--- a/cnd.modelutil/nbproject/project.xml
+++ b/cnd.modelutil/nbproject/project.xml
@@ -46,7 +46,7 @@
3
- 1.41
+ 1.53
@@ -54,8 +54,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/cnd.navigation/nbproject/project.xml b/cnd.navigation/nbproject/project.xml
--- a/cnd.navigation/nbproject/project.xml
+++ b/cnd.navigation/nbproject/project.xml
@@ -54,7 +54,7 @@
3
- 1.42
+ 1.53
@@ -62,8 +62,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/cnd.refactoring/nbproject/project.xml b/cnd.refactoring/nbproject/project.xml
--- a/cnd.refactoring/nbproject/project.xml
+++ b/cnd.refactoring/nbproject/project.xml
@@ -73,7 +73,7 @@
3
- 1.41
+ 1.53
@@ -90,8 +90,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/cnd.script/nbproject/project.xml b/cnd.script/nbproject/project.xml
--- a/cnd.script/nbproject/project.xml
+++ b/cnd.script/nbproject/project.xml
@@ -37,7 +37,7 @@
3
- 1.48
+ 1.53
@@ -54,8 +54,8 @@
- 2
- 2.2
+ 3
+ 3.1
diff --git a/cnd.testrunner/nbproject/project.xml b/cnd.testrunner/nbproject/project.xml
--- a/cnd.testrunner/nbproject/project.xml
+++ b/cnd.testrunner/nbproject/project.xml
@@ -95,8 +95,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/cnd/nbproject/project.xml b/cnd/nbproject/project.xml
--- a/cnd/nbproject/project.xml
+++ b/cnd/nbproject/project.xml
@@ -61,7 +61,25 @@
2
- 1.9
+ 1.10
+
+
+
+ org.netbeans.modules.editor.mimelookup
+
+
+
+ 1
+ 1.10
+
+
+
+ org.netbeans.modules.editor.settings
+
+
+
+ 1
+ 1.22
@@ -70,6 +88,15 @@
2
+ 1.22
+
+
+
+ org.netbeans.modules.lexer
+
+
+
+ 21.16
diff --git a/collab.channel.chat/nbproject/project.xml b/collab.channel.chat/nbproject/project.xml
--- a/collab.channel.chat/nbproject/project.xml
+++ b/collab.channel.chat/nbproject/project.xml
@@ -65,7 +65,7 @@
3
- 1.41
+ 1.53
@@ -73,8 +73,8 @@
- 2
- 2.1
+ 3
+ 3.1
@@ -125,7 +125,7 @@
6.2
-
+
org.netbeans.modules.collab.channel.chatorg.netbeans.modules.collab.channel.chat.messagetype
diff --git a/compapp.casaeditor/nbproject/project.xml b/compapp.casaeditor/nbproject/project.xml
--- a/compapp.casaeditor/nbproject/project.xml
+++ b/compapp.casaeditor/nbproject/project.xml
@@ -123,8 +123,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/compapp.projects.base/nbproject/project.xml b/compapp.projects.base/nbproject/project.xml
--- a/compapp.projects.base/nbproject/project.xml
+++ b/compapp.projects.base/nbproject/project.xml
@@ -64,8 +64,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/compapp.projects.jbi/nbproject/project.xml b/compapp.projects.jbi/nbproject/project.xml
--- a/compapp.projects.jbi/nbproject/project.xml
+++ b/compapp.projects.jbi/nbproject/project.xml
@@ -174,8 +174,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/csl.api/nbproject/project.xml b/csl.api/nbproject/project.xml
--- a/csl.api/nbproject/project.xml
+++ b/csl.api/nbproject/project.xml
@@ -56,7 +56,7 @@
3
- 1.41
+ 1.53
@@ -118,8 +118,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/css.editor/nbproject/project.xml b/css.editor/nbproject/project.xml
--- a/css.editor/nbproject/project.xml
+++ b/css.editor/nbproject/project.xml
@@ -29,7 +29,7 @@
3
- 1.41
+ 1.53
@@ -55,8 +55,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/css.visual/nbproject/project.xml b/css.visual/nbproject/project.xml
--- a/css.visual/nbproject/project.xml
+++ b/css.visual/nbproject/project.xml
@@ -82,7 +82,7 @@
3
- 1.41
+ 1.53
@@ -95,12 +95,21 @@
+ org.netbeans.modules.editor.indent
+
+
+
+ 2
+ 1.9
+
+
+ org.netbeans.modules.editor.lib
- 2
- 2.1
+ 3
+ 3.1
diff --git a/css.visual/src/org/netbeans/modules/css/editor/CssEditorSupport.java b/css.visual/src/org/netbeans/modules/css/editor/CssEditorSupport.java
--- a/css.visual/src/org/netbeans/modules/css/editor/CssEditorSupport.java
+++ b/css.visual/src/org/netbeans/modules/css/editor/CssEditorSupport.java
@@ -63,6 +63,9 @@
import org.netbeans.modules.css.visual.ui.preview.CssPreviewable;
import org.netbeans.modules.css.visual.ui.preview.CssPreviewable.Listener;
import org.netbeans.modules.editor.NbEditorDocument;
+import org.netbeans.modules.editor.indent.api.IndentUtils;
+import org.openide.cookies.EditorCookie;
+import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
/**
@@ -139,7 +142,7 @@
} else if (oldRule == null && newRule != null) {
//add the new rule at the end of the rule block:
List items = myRule.items();
- final int INDENT = doc.getFormatter().getShiftWidth();
+ final int INDENT = IndentUtils.indentLevelSize(document);
int insertOffset = myRule.getRuleCloseBracketOffset();
boolean initialNewLine = false;
@@ -160,7 +163,9 @@
}
String text = (initialNewLine ? LINE_SEPARATOR : "") +
- makeIndentString(INDENT) +
+// XXX: see the method comment
+// makeIndentString(INDENT) +
+ IndentUtils.createIndentString(document, INDENT) +
newRule.key().name() + ": " + newRule.value().name() + ";" +
LINE_SEPARATOR;
@@ -189,13 +194,17 @@
}
};
- private String makeIndentString(int level) {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < level; i++) {
- sb.append(' ');
- }
- return sb.toString();
- }
+ // XXX: This is most likely wrong! Unless CSS only allows spaces for indentation.
+ // But even then the same should be achieved by correctly setting the indentation
+ // settings. Otherwise a simple Reformat.get(doc).reformat(...) call on a CSS document
+ // could break its structure.
+// private String makeIndentString(int level) {
+// StringBuffer sb = new StringBuffer();
+// for (int i = 0; i < level; i++) {
+// sb.append(' ');
+// }
+// return sb.toString();
+// }
void parsed(final CssParserResult result, final int caretOffset) {
d("model updated");
diff --git a/db.core/nbproject/project.xml b/db.core/nbproject/project.xml
--- a/db.core/nbproject/project.xml
+++ b/db.core/nbproject/project.xml
@@ -80,8 +80,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/db.sql.editor/nbproject/project.xml b/db.sql.editor/nbproject/project.xml
--- a/db.sql.editor/nbproject/project.xml
+++ b/db.sql.editor/nbproject/project.xml
@@ -98,7 +98,7 @@
3
- 1.41
+ 1.53
@@ -115,8 +115,8 @@
- 2
- 2.1
+ 3
+ 3.1
@@ -232,6 +232,15 @@
8.0
+
+ org.netbeans.modules.editor.deprecated.pre65formatting
+
+
+
+ 0-1
+ 1.0
+
+
diff --git a/debugger.jpda.ant/nbproject/project.xml b/debugger.jpda.ant/nbproject/project.xml
--- a/debugger.jpda.ant/nbproject/project.xml
+++ b/debugger.jpda.ant/nbproject/project.xml
@@ -101,8 +101,8 @@
- 2
- 2.1
+ 3
+ 3.1
@@ -147,9 +147,9 @@
org.openide.util.lookup
-
- 8.0
-
+
+ 8.0
+
diff --git a/debugger.jpda.projects/nbproject/project.xml b/debugger.jpda.projects/nbproject/project.xml
--- a/debugger.jpda.projects/nbproject/project.xml
+++ b/debugger.jpda.projects/nbproject/project.xml
@@ -96,8 +96,8 @@
- 2
- 2.10
+ 3
+ 3.1
diff --git a/debugger.jpda.ui/nbproject/project.xml b/debugger.jpda.ui/nbproject/project.xml
--- a/debugger.jpda.ui/nbproject/project.xml
+++ b/debugger.jpda.ui/nbproject/project.xml
@@ -103,8 +103,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/debugger.jpda/nbproject/project.xml b/debugger.jpda/nbproject/project.xml
--- a/debugger.jpda/nbproject/project.xml
+++ b/debugger.jpda/nbproject/project.xml
@@ -96,8 +96,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/diff/nbproject/project.xml b/diff/nbproject/project.xml
--- a/diff/nbproject/project.xml
+++ b/diff/nbproject/project.xml
@@ -87,8 +87,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/dlight.annotationsupport/nbproject/project.xml b/dlight.annotationsupport/nbproject/project.xml
--- a/dlight.annotationsupport/nbproject/project.xml
+++ b/dlight.annotationsupport/nbproject/project.xml
@@ -60,8 +60,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/editor.actions/nbproject/project.xml b/editor.actions/nbproject/project.xml
--- a/editor.actions/nbproject/project.xml
+++ b/editor.actions/nbproject/project.xml
@@ -54,8 +54,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/editor.bookmarks/nbproject/project.xml b/editor.bookmarks/nbproject/project.xml
--- a/editor.bookmarks/nbproject/project.xml
+++ b/editor.bookmarks/nbproject/project.xml
@@ -55,7 +55,7 @@
3
- 1.41
+ 1.53
@@ -63,8 +63,8 @@
- 2
- 2.1
+ 3
+ 3.1
@@ -152,7 +152,7 @@
- 8.0
+ 8.4
diff --git a/editor.bracesmatching/nbproject/project.xml b/editor.bracesmatching/nbproject/project.xml
--- a/editor.bracesmatching/nbproject/project.xml
+++ b/editor.bracesmatching/nbproject/project.xml
@@ -20,7 +20,7 @@
3
- 1.41
+ 1.53
@@ -28,8 +28,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/editor.codetemplates/nbproject/project.xml b/editor.codetemplates/nbproject/project.xml
--- a/editor.codetemplates/nbproject/project.xml
+++ b/editor.codetemplates/nbproject/project.xml
@@ -64,7 +64,7 @@
3
- 1.41
+ 1.53
@@ -76,12 +76,21 @@
+ org.netbeans.modules.editor.indent
+
+
+
+ 2
+ 1.9
+
+
+ org.netbeans.modules.editor.lib
- 2
- 2.1
+ 3
+ 3.1
diff --git a/editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateInsertHandler.java b/editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateInsertHandler.java
--- a/editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateInsertHandler.java
+++ b/editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateInsertHandler.java
@@ -61,7 +61,6 @@
import javax.swing.undo.CannotUndoException;
import org.netbeans.api.editor.completion.Completion;
import org.netbeans.editor.BaseDocument;
-import org.netbeans.editor.Formatter;
import org.netbeans.editor.Utilities;
import org.netbeans.lib.editor.codetemplates.api.CodeTemplate;
import org.netbeans.lib.editor.codetemplates.spi.CodeTemplateInsertRequest;
@@ -77,6 +76,7 @@
import org.netbeans.lib.editor.util.CharSequenceUtilities;
import org.netbeans.lib.editor.util.CharacterConversions;
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
+import org.netbeans.modules.editor.indent.api.Reformat;
/**
* Code template allows the client to paste itself into the given
@@ -125,7 +125,7 @@
private String completeInsertString;
- private Formatter formatter;
+ private Reformat formatter;
private TextSyncGroup textSyncGroup;
@@ -247,30 +247,19 @@
// Build insert string outside of the atomic lock
completeInsertString = getInsertText();
- BaseDocument bdoc = (doc instanceof BaseDocument)
- ? (BaseDocument)doc
- : null;
+
// Need to lock formatter first because CT's multiline text will be reformatted
- formatter = null;
- if (bdoc != null) {
- formatter = bdoc.getFormatter();
- if (formatter != null) {
- formatter.reformatLock();
- }
- }
+ formatter = Reformat.get(doc);
+ formatter.lock();
try {
- if (bdoc != null) {
- bdoc.runAtomicAsUser(this);
+ if (doc instanceof BaseDocument) {
+ ((BaseDocument) doc).runAtomicAsUser(this);
} else { // Otherwise run without atomic locking
this.run();
}
} finally {
- if (bdoc != null) {
- if (formatter != null) {
- formatter.reformatUnlock();
- }
- formatter = null;
- }
+ formatter.unlock();
+ formatter = null;
completeInsertString = null;
}
}
@@ -344,8 +333,7 @@
this.inserted = true;
if (bdoc != null) {
- formatter.reformat(bdoc, pos.getOffset(),
- pos.getOffset() + completeInsertString.length());
+ formatter.reformat(pos.getOffset(), pos.getOffset() + completeInsertString.length());
}
if (!released) {
diff --git a/editor.completion/nbproject/project.xml b/editor.completion/nbproject/project.xml
--- a/editor.completion/nbproject/project.xml
+++ b/editor.completion/nbproject/project.xml
@@ -55,7 +55,7 @@
3
- 1.41
+ 1.53
@@ -63,8 +63,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/editor.deprecated.pre61completion/nbproject/project.xml b/editor.deprecated.pre61completion/nbproject/project.xml
--- a/editor.deprecated.pre61completion/nbproject/project.xml
+++ b/editor.deprecated.pre61completion/nbproject/project.xml
@@ -19,8 +19,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/editor.deprecated.pre61settings/nbproject/project.xml b/editor.deprecated.pre61settings/nbproject/project.xml
--- a/editor.deprecated.pre61settings/nbproject/project.xml
+++ b/editor.deprecated.pre61settings/nbproject/project.xml
@@ -59,11 +59,20 @@
+ org.netbeans.modules.editor.deprecated.pre65formatting
+
+
+
+ 0-1
+ 1.0
+
+
+ org.netbeans.modules.editor.lib
- 2
+ 3
diff --git a/editor.deprecated.pre65formatting/build.xml b/editor.deprecated.pre65formatting/build.xml
new file mode 100644
--- /dev/null
+++ b/editor.deprecated.pre65formatting/build.xml
@@ -0,0 +1,5 @@
+
+
+ Builds, tests, and runs the project org.netbeans.modules.editor.deprecated.pre65formatting
+
+
diff --git a/editor.deprecated.pre65formatting/manifest.mf b/editor.deprecated.pre65formatting/manifest.mf
new file mode 100644
--- /dev/null
+++ b/editor.deprecated.pre65formatting/manifest.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.netbeans.modules.editor.deprecated.pre65formatting/0
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Layer: org/netbeans/modules/editor/deprecated/pre65formatting/layer.xml
+OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/deprecated/pre65formatting/Bundle.properties
+OpenIDE-Module-Deprecated: true
diff --git a/editor.deprecated.pre65formatting/nbproject/project.properties b/editor.deprecated.pre65formatting/nbproject/project.properties
new file mode 100644
--- /dev/null
+++ b/editor.deprecated.pre65formatting/nbproject/project.properties
@@ -0,0 +1,4 @@
+is.autoload=true
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
+spec.version.base=1.0
diff --git a/editor.deprecated.pre65formatting/nbproject/project.xml b/editor.deprecated.pre65formatting/nbproject/project.xml
new file mode 100644
--- /dev/null
+++ b/editor.deprecated.pre65formatting/nbproject/project.xml
@@ -0,0 +1,103 @@
+
+
+ org.netbeans.modules.apisupport.project
+
+
+ org.netbeans.modules.editor.deprecated.pre65formatting
+
+
+ org.netbeans.modules.editor
+
+
+
+ 3
+
+
+
+
+ org.netbeans.modules.editor.indent
+
+
+
+ 2
+ 1.10
+
+
+
+ org.netbeans.modules.editor.lib
+
+
+
+ 3
+
+
+
+
+ org.netbeans.modules.editor.lib2
+
+
+
+ 1
+
+
+
+
+ org.netbeans.modules.editor.mimelookup
+
+
+
+ 1
+ 1.10
+
+
+
+ org.netbeans.modules.editor.settings
+
+
+
+ 1
+ 1.22
+
+
+
+ org.netbeans.modules.editor.util
+
+
+
+ 1
+ 1.25
+
+
+
+ org.openide.text
+
+
+
+ 6.21
+
+
+
+ org.openide.util
+
+
+
+ 7.18
+
+
+
+ org.openide.util.lookup
+
+
+
+ 8.4
+
+
+
+
+ org.netbeans.editor
+ org.netbeans.editor.ext
+ org.netbeans.modules.editor
+
+
+
+
diff --git a/editor.lib/src/org/netbeans/editor/Formatter.java b/editor.deprecated.pre65formatting/src/org/netbeans/editor/Formatter.java
rename from editor.lib/src/org/netbeans/editor/Formatter.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/editor/Formatter.java
--- a/editor.lib/src/org/netbeans/editor/Formatter.java
+++ b/editor.deprecated.pre65formatting/src/org/netbeans/editor/Formatter.java
@@ -48,10 +48,8 @@
import java.io.IOException;
import java.io.Writer;
import java.io.CharArrayWriter;
-import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
-import java.util.Stack;
import java.util.WeakHashMap;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;
@@ -64,6 +62,7 @@
import org.netbeans.api.editor.settings.SimpleValueNames;
import org.netbeans.lib.editor.util.CharSequenceUtilities;
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
+import org.netbeans.modules.editor.deprecated.pre65formatting.LegacyFormattersProvider;
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
import org.netbeans.modules.editor.lib.KitsTracker;
import org.netbeans.modules.editor.lib.SettingsConversions;
@@ -106,7 +105,8 @@
} else {
Formatter formatter = kitClass2Formatter.get(kitClass);
if (formatter == null) {
- formatter = BaseKit.getKit(kitClass).createFormatter();
+ BaseKit kit = BaseKit.getKit(kitClass);
+ formatter = callCreateFormatterMethod(kit);
kitClass2Formatter.put(kitClass, formatter);
}
return formatter;
@@ -130,9 +130,9 @@
if (formatter == null) {
EditorKit editorKit = MimeLookup.getLookup(mimePath).lookup(EditorKit.class);
if (editorKit instanceof BaseKit) {
- formatter = ((BaseKit) editorKit).createFormatter();
+ formatter = callCreateFormatterMethod((BaseKit) editorKit);
} else {
- formatter = BaseKit.getKit(BaseKit.class).createFormatter();
+ formatter = callCreateFormatterMethod(BaseKit.getKit(BaseKit.class));
}
mimePath2Formatter.put(mimePath, formatter);
}
@@ -264,7 +264,7 @@
* @see BaseDocument.getTabSize()
*/
public int getTabSize() {
- Document doc = getFormattingContextDocument();
+ Document doc = LegacyFormattersProvider.getFormattingContextDocument();
if (doc != null) {
Object ret = callIndentUtils("tabSize", doc); //NOI18N
if (ret instanceof Integer) {
@@ -300,7 +300,7 @@
* @see getSpacesPerTab()
*/
public int getShiftWidth() {
- Document doc = getFormattingContextDocument();
+ Document doc = LegacyFormattersProvider.getFormattingContextDocument();
if (doc != null) {
Object ret = callIndentUtils("indentLevelSize", doc); //NOI18N
if (ret instanceof Integer) {
@@ -329,7 +329,7 @@
/** Should the typed tabs be expanded to the spaces? */
public boolean expandTabs() {
- Document doc = getFormattingContextDocument();
+ Document doc = LegacyFormattersProvider.getFormattingContextDocument();
if (doc != null) {
Object ret = callIndentUtils("isExpandTabs", doc); //NOI18N
if (ret instanceof Boolean) {
@@ -353,7 +353,7 @@
* instead of one typed tab.
*/
public int getSpacesPerTab() {
- Document doc = getFormattingContextDocument();
+ Document doc = LegacyFormattersProvider.getFormattingContextDocument();
if (doc != null) {
Object ret = callIndentUtils("indentLevelSize", doc); //NOI18N
if (ret instanceof Integer) {
@@ -378,11 +378,11 @@
// ------------------------------------------------------------------------
public String getIndentString(BaseDocument doc, int indent) {
- pushFormattingContextDocument(doc);
+ LegacyFormattersProvider.pushFormattingContextDocument(doc);
try {
return getIndentString(indent, expandTabs(), doc.getTabSize());
} finally {
- popFormattingContextDocument(doc);
+ LegacyFormattersProvider.popFormattingContextDocument(doc);
}
}
@@ -403,7 +403,7 @@
*/
public void insertTabString (final BaseDocument doc, final int dotPos)
throws BadLocationException {
- pushFormattingContextDocument(doc);
+ LegacyFormattersProvider.pushFormattingContextDocument(doc);
try {
final BadLocationException[] badLocationExceptions = new BadLocationException [1];
doc.runAtomic (new Runnable () {
@@ -436,7 +436,7 @@
if (badLocationExceptions[0] != null)
throw badLocationExceptions [0];
} finally {
- popFormattingContextDocument(doc);
+ LegacyFormattersProvider.popFormattingContextDocument(doc);
}
}
@@ -445,7 +445,7 @@
*/
public void changeRowIndent (final BaseDocument doc, final int pos, final int newIndent)
throws BadLocationException {
- pushFormattingContextDocument(doc);
+ LegacyFormattersProvider.pushFormattingContextDocument(doc);
try {
final BadLocationException[] badLocationExceptions = new BadLocationException [1];
doc.runAtomic (new Runnable () {
@@ -484,7 +484,7 @@
if (badLocationExceptions[0] != null)
throw badLocationExceptions [0];
} finally {
- popFormattingContextDocument(doc);
+ LegacyFormattersProvider.popFormattingContextDocument(doc);
}
}
@@ -498,7 +498,7 @@
*/
public void changeBlockIndent (final BaseDocument doc, final int startPos, final int endPos,
final int shiftCnt) throws BadLocationException {
- pushFormattingContextDocument(doc);
+ LegacyFormattersProvider.pushFormattingContextDocument(doc);
try {
GuardedDocument gdoc = (doc instanceof GuardedDocument)
? (GuardedDocument)doc : null;
@@ -538,14 +538,14 @@
if (badLocationExceptions[0] != null)
throw badLocationExceptions [0];
} finally {
- popFormattingContextDocument(doc);
+ LegacyFormattersProvider.popFormattingContextDocument(doc);
}
}
/** Shift line either left or right */
public void shiftLine(BaseDocument doc, int dotPos, boolean right)
throws BadLocationException {
- pushFormattingContextDocument(doc);
+ LegacyFormattersProvider.pushFormattingContextDocument(doc);
try {
int ind = doc.getShiftWidth();
if (!right) {
@@ -560,7 +560,7 @@
ind = Math.max(ind, 0);
changeRowIndent(doc, dotPos, ind);
} finally {
- popFormattingContextDocument(doc);
+ LegacyFormattersProvider.popFormattingContextDocument(doc);
}
}
@@ -572,7 +572,7 @@
*/
public int reformat(BaseDocument doc, int startOffset, int endOffset)
throws BadLocationException {
- pushFormattingContextDocument(doc);
+ LegacyFormattersProvider.pushFormattingContextDocument(doc);
try {
try {
CharArrayWriter cw = new CharArrayWriter();
@@ -594,7 +594,7 @@
return 0;
}
} finally {
- popFormattingContextDocument(doc);
+ LegacyFormattersProvider.popFormattingContextDocument(doc);
}
}
@@ -772,33 +772,6 @@
// private implementation
// ------------------------------------------------------------------------
- private static ThreadLocal>> FORMATTING_CONTEXT_DOCUMENT = new ThreadLocal>>() {
- @Override
- protected Stack> initialValue() {
- return new Stack>();
- }
- };
-
- private static Document getFormattingContextDocument() {
- Stack> stack = FORMATTING_CONTEXT_DOCUMENT.get();
- return stack.isEmpty() ? null : stack.peek().get();
- }
-
- /* package */ static void pushFormattingContextDocument(Document doc) {
- FORMATTING_CONTEXT_DOCUMENT.get().push(new WeakReference(doc));
- }
-
- /* package */ static void popFormattingContextDocument(Document doc) {
- Stack> stack = FORMATTING_CONTEXT_DOCUMENT.get();
- assert !stack.empty() : "Calling popFormattingContextDocument without pushFormattingContextDocument"; //NOI18N
-
- Reference ref = stack.pop();
- Document docFromStack = ref.get();
- assert docFromStack == doc : "Popping " + doc + ", but the stack contains " + docFromStack;
-
- ref.clear();
- }
-
private static boolean noIndentUtils = false;
private static WeakReference indentUtilsClassRef = null;
private static Object callIndentUtils(String methodName, Document doc) {
@@ -861,4 +834,12 @@
}
}
+ private static Formatter callCreateFormatterMethod(BaseKit kit) {
+ try {
+ Method m = kit.getClass().getMethod("createFormatter"); //NOI18N
+ return (Formatter) m.invoke(kit);
+ } catch (Exception e) {
+ return new Formatter(kit.getClass());
+ }
+ }
}
diff --git a/editor.lib/src/org/netbeans/editor/ext/AbstractFormatLayer.java b/editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/AbstractFormatLayer.java
rename from editor.lib/src/org/netbeans/editor/ext/AbstractFormatLayer.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/AbstractFormatLayer.java
diff --git a/editor.lib/src/org/netbeans/editor/ext/ExtFormatSupport.java b/editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/ExtFormatSupport.java
rename from editor.lib/src/org/netbeans/editor/ext/ExtFormatSupport.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/ExtFormatSupport.java
diff --git a/editor.lib/src/org/netbeans/editor/ext/ExtFormatter.java b/editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/ExtFormatter.java
rename from editor.lib/src/org/netbeans/editor/ext/ExtFormatter.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/ExtFormatter.java
diff --git a/editor.lib/src/org/netbeans/editor/ext/FormatLayer.java b/editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/FormatLayer.java
rename from editor.lib/src/org/netbeans/editor/ext/FormatLayer.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/FormatLayer.java
diff --git a/editor.lib/src/org/netbeans/editor/ext/FormatSupport.java b/editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/FormatSupport.java
rename from editor.lib/src/org/netbeans/editor/ext/FormatSupport.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/FormatSupport.java
diff --git a/editor.lib/src/org/netbeans/editor/ext/FormatTokenPosition.java b/editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/FormatTokenPosition.java
rename from editor.lib/src/org/netbeans/editor/ext/FormatTokenPosition.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/FormatTokenPosition.java
diff --git a/editor.lib/src/org/netbeans/editor/ext/FormatTokenPositionSupport.java b/editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/FormatTokenPositionSupport.java
rename from editor.lib/src/org/netbeans/editor/ext/FormatTokenPositionSupport.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/FormatTokenPositionSupport.java
diff --git a/editor.lib/src/org/netbeans/editor/ext/FormatWriter.java b/editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/FormatWriter.java
rename from editor.lib/src/org/netbeans/editor/ext/FormatWriter.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/editor/ext/FormatWriter.java
diff --git a/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/Bundle.properties b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/Bundle.properties
new file mode 100644
--- /dev/null
+++ b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/Bundle.properties
@@ -0,0 +1,38 @@
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+#
+# The contents of this file are subject to the terms of either the GNU
+# General Public License Version 2 only ("GPL") or the Common
+# Development and Distribution License("CDDL") (collectively, the
+# "License"). You may not use this file except in compliance with the
+# License. You can obtain a copy of the License at
+# http://www.netbeans.org/cddl-gplv2.html
+# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+# specific language governing permissions and limitations under the
+# License. When distributing the software, include this License Header
+# Notice in each file and include the License file at
+# nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the GPL Version 2 section of the License file that
+# accompanied this code. If applicable, add the following below the
+# License Header, with the fields enclosed by brackets [] replaced by
+# your own identifying information:
+# "Portions Copyrighted [year] [name of copyright owner]"
+#
+# If you wish your version of this file to be governed by only the CDDL
+# or only the GPL Version 2, indicate your decision by adding
+# "[Contributor] elects to include this software in this distribution
+# under the [CDDL or GPL Version 2] license." If you do not indicate a
+# single choice of license, a recipient has the option to distribute
+# your version of this file under either the CDDL, the GPL Version 2 or
+# to extend the choice of license to its licensees as provided above.
+# However, if you add GPL Version 2 code and therefore, elected the GPL
+# Version 2 license, then the option applies only if the new code is
+# made subject to such option by the copyright holder.
+#
+# Contributor(s):
+#
+# Portions Copyrighted 2008 Sun Microsystems, Inc.
+
+MSG_NegativeValue=Negative value is not allowed
diff --git a/editor/src/org/netbeans/modules/editor/FormatterIndentEngine.java b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/FormatterIndentEngine.java
rename from editor/src/org/netbeans/modules/editor/FormatterIndentEngine.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/FormatterIndentEngine.java
--- a/editor/src/org/netbeans/modules/editor/FormatterIndentEngine.java
+++ b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/FormatterIndentEngine.java
@@ -44,12 +44,16 @@
package org.netbeans.modules.editor;
+import java.awt.Toolkit;
import java.io.*;
import javax.swing.text.Document;
import org.netbeans.api.editor.settings.SimpleValueNames;
import org.netbeans.editor.BaseKit;
import org.netbeans.editor.ext.ExtFormatter;
+import org.openide.ErrorManager;
import org.openide.text.IndentEngine;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
/**
* Indent engine that delegates to formatter
@@ -168,8 +172,15 @@
public void setSpacesPerTab(int spacesPerTab) {
if (spacesPerTab <= 0) {
- NbEditorUtilities.invalidArgument("MSG_NegativeValue"); // NOI18N
- return; // value unchanged
+ IllegalArgumentException iae = new IllegalArgumentException("Invalid argument"); //NOI18N
+ ErrorManager errMan = Lookup.getDefault().lookup(ErrorManager.class);
+
+ if (errMan != null) {
+ Toolkit.getDefaultToolkit().beep();
+ errMan.annotate(iae, ErrorManager.USER, iae.getMessage(), NbBundle.getMessage(FormatterIndentEngine.class, "MSG_NegativeValue"), null, null); //NOI18N
+ } else {
+ throw iae;
+ }
}
int old = getFormatter().getSpacesPerTab();
diff --git a/editor/src/org/netbeans/modules/editor/FormatterIndentEngineBeanInfo.java b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/FormatterIndentEngineBeanInfo.java
rename from editor/src/org/netbeans/modules/editor/FormatterIndentEngineBeanInfo.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/FormatterIndentEngineBeanInfo.java
diff --git a/editor/src/org/netbeans/modules/editor/IndentEngineFormatter.java b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/IndentEngineFormatter.java
rename from editor/src/org/netbeans/modules/editor/IndentEngineFormatter.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/IndentEngineFormatter.java
diff --git a/editor/src/org/netbeans/modules/editor/SimpleIndentEngine.java b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/SimpleIndentEngine.java
rename from editor/src/org/netbeans/modules/editor/SimpleIndentEngine.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/SimpleIndentEngine.java
diff --git a/editor/src/org/netbeans/modules/editor/SimpleIndentEngineBeanInfo.java b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/SimpleIndentEngineBeanInfo.java
rename from editor/src/org/netbeans/modules/editor/SimpleIndentEngineBeanInfo.java
rename to editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/SimpleIndentEngineBeanInfo.java
diff --git a/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/Bundle.properties b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/Bundle.properties
new file mode 100644
--- /dev/null
+++ b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/Bundle.properties
@@ -0,0 +1,2 @@
+OpenIDE-Module-Display-Category=Editing
+OpenIDE-Module-Name=Editor Formatting Prior 6.5 Separation
diff --git a/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/ComplexValueSettingsFactory.java b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/ComplexValueSettingsFactory.java
new file mode 100644
--- /dev/null
+++ b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/ComplexValueSettingsFactory.java
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2010 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.editor.deprecated.pre65formatting;
+
+import javax.swing.text.EditorKit;
+import org.netbeans.api.editor.mimelookup.MimeLookup;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.modules.editor.FormatterIndentEngine;
+import org.netbeans.modules.editor.IndentEngineFormatter;
+import org.netbeans.modules.editor.NbEditorDocument;
+import org.openide.text.IndentEngine;
+
+/**
+ *
+ * @author vita
+ */
+public final class ComplexValueSettingsFactory {
+
+ private ComplexValueSettingsFactory() {
+ // no-op
+ }
+
+ // -----------------------------------------------------------------------
+ // 'formatter' setting
+ // -----------------------------------------------------------------------
+
+ public static Object getFormatterValue(MimePath mimePath, String settingName) {
+ assert settingName.equals(NbEditorDocument.FORMATTER) : "The getFormatter factory called for '" + settingName + "'"; //NOI18N
+
+ IndentEngine eng = org.netbeans.modules.editor.impl.ComplexValueSettingsFactory.getIndentEngine(mimePath);
+
+ if (eng != null) {
+ if (eng instanceof FormatterIndentEngine) {
+ return ((FormatterIndentEngine)eng).getFormatter();
+ } else {
+ EditorKit kit = MimeLookup.getLookup(mimePath).lookup(EditorKit.class);
+ if (kit != null) {
+ return new IndentEngineFormatter(kit.getClass(), eng);
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/LegacyFormattersProvider.java b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/LegacyFormattersProvider.java
new file mode 100644
--- /dev/null
+++ b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/LegacyFormattersProvider.java
@@ -0,0 +1,379 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2008 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.editor.deprecated.pre65formatting;
+
+import java.io.IOException;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Stack;
+import java.util.WeakHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.EditorKit;
+import javax.swing.text.Element;
+import javax.swing.text.Position;
+import javax.swing.text.StyledDocument;
+import org.netbeans.api.editor.mimelookup.MimeLookup;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.editor.BaseDocument;
+import org.netbeans.editor.Formatter;
+import org.netbeans.editor.Utilities;
+import org.netbeans.editor.ext.ExtFormatter;
+import org.netbeans.modules.editor.indent.spi.Context;
+import org.netbeans.modules.editor.indent.spi.ExtraLock;
+import org.netbeans.modules.editor.indent.spi.IndentTask;
+import org.netbeans.modules.editor.indent.spi.ReformatTask;
+import org.netbeans.modules.editor.lib.KitsTracker;
+import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
+import org.netbeans.spi.editor.typinghooks.TypedTextInterceptor;
+import org.openide.util.Lookup;
+import org.openide.util.lookup.Lookups;
+
+/**
+ *
+ * @author vita
+ */
+@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.editor.mimelookup.MimeDataProvider.class)
+public final class LegacyFormattersProvider implements MimeDataProvider {
+
+ public LegacyFormattersProvider() {
+ // no-op
+ }
+
+ // ------------------------------------------------------------------------
+ // MimeDataProvider implementation
+ // ------------------------------------------------------------------------
+
+ public Lookup getLookup(MimePath mimePath) {
+ if (mimePath.size() == 1) {
+ IndentReformatTaskFactoriesProvider provider = IndentReformatTaskFactoriesProvider.get(mimePath);
+ if (provider != null) {
+ IndentTask.Factory legacyIndenter = provider.getIndentTaskFactory();
+ ReformatTask.Factory legacyFormatter = provider.getReformatTaskFactory();
+ TypedTextInterceptor.Factory legacyAutoIndenter = provider.getTypedTextInterceptorFactory();
+
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.fine("'" + mimePath.getPath() + "' uses legacyIndenter=" + legacyIndenter //NOI18N
+ + ", legacyFormatter=" + legacyFormatter //NOI18N
+ + ", legacyAutoIndenter=" + legacyAutoIndenter); //NOI18N
+ }
+
+ return Lookups.fixed(legacyIndenter, legacyFormatter, legacyAutoIndenter);
+ }
+ }
+
+ return null;
+ }
+
+ // ------------------------------------------------------------------------
+ // Formatting context manipulation methods
+ // ------------------------------------------------------------------------
+
+ public static Document getFormattingContextDocument() {
+ Stack> stack = FORMATTING_CONTEXT_DOCUMENT.get();
+ return stack.isEmpty() ? null : stack.peek().get();
+ }
+
+ public static void pushFormattingContextDocument(Document doc) {
+ FORMATTING_CONTEXT_DOCUMENT.get().push(new WeakReference(doc));
+ }
+
+ public static void popFormattingContextDocument(Document doc) {
+ Stack> stack = FORMATTING_CONTEXT_DOCUMENT.get();
+ assert !stack.empty() : "Calling popFormattingContextDocument without pushFormattingContextDocument"; //NOI18N
+
+ Reference ref = stack.pop();
+ Document docFromStack = ref.get();
+ assert docFromStack == doc : "Popping " + doc + ", but the stack contains " + docFromStack;
+
+ ref.clear();
+ }
+
+ // ------------------------------------------------------------------------
+ // Private implementation
+ // ------------------------------------------------------------------------
+
+ private static final Logger LOG = Logger.getLogger(LegacyFormattersProvider.class.getName());
+
+ private static ThreadLocal>> FORMATTING_CONTEXT_DOCUMENT = new ThreadLocal>>() {
+ @Override
+ protected Stack> initialValue() {
+ return new Stack>();
+ }
+ };
+
+ private static final class IndentReformatTaskFactoriesProvider {
+
+ public static IndentReformatTaskFactoriesProvider get(MimePath mimePath) {
+ Reference ref = cache.get(mimePath);
+ IndentReformatTaskFactoriesProvider provider = ref == null ? null : ref.get();
+ if (provider == null) {
+ try {
+ Class kitClass = KitsTracker.getInstance().findKitClass(mimePath.getPath());
+ Method createFormatterMethod = kitClass.getDeclaredMethod("createFormatter"); //NOI18N
+ provider = new IndentReformatTaskFactoriesProvider(mimePath);
+ cache.put(mimePath, new WeakReference(provider));
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ return provider;
+ }
+
+ public IndentTask.Factory getIndentTaskFactory() {
+ if (indentTaskFactory == null) {
+ indentTaskFactory = new IndentTask.Factory() {
+ public IndentTask createTask(Context context) {
+ Formatter formatter = getFormatter();
+ if (formatter != null && context.document() instanceof BaseDocument) {
+ return new Indenter(context, formatter);
+ } else {
+ return null;
+ }
+ }
+ };
+ }
+ return indentTaskFactory;
+ }
+
+ public ReformatTask.Factory getReformatTaskFactory() {
+ if (reformatTaskFactory == null) {
+ reformatTaskFactory = new ReformatTask.Factory() {
+ public ReformatTask createTask(Context context) {
+ Formatter formatter = getFormatter();
+ if (formatter != null && context.document() instanceof BaseDocument) {
+ return new Reformatter(context, formatter);
+ } else {
+ return null;
+ }
+ }
+ };
+ }
+ return reformatTaskFactory;
+ }
+
+ public TypedTextInterceptor.Factory getTypedTextInterceptorFactory() {
+ if (typedTextInterceptorFactory == null) {
+ typedTextInterceptorFactory = new TypedTextInterceptor.Factory() {
+ public TypedTextInterceptor createTypedTextInterceptor(MimePath mimePath) {
+ Formatter formatter = getFormatter();
+ if (formatter instanceof ExtFormatter) {
+ return new AutoIndenter((ExtFormatter)formatter);
+ } else {
+ return null;
+ }
+ }
+ };
+ }
+ return typedTextInterceptorFactory;
+ }
+
+ // -------------------------------------------------------------------
+ // private implementation
+ // -------------------------------------------------------------------
+
+ private static final Map> cache = new WeakHashMap>();
+ private static final String NO_FORMATTER = new String("NO_FORMATTER"); //NOI18N
+
+ private final MimePath mimePath;
+
+ private IndentTask.Factory indentTaskFactory;
+ private ReformatTask.Factory reformatTaskFactory;
+ private TypedTextInterceptor.Factory typedTextInterceptorFactory;
+ private Object legacyFormatter;
+
+ private IndentReformatTaskFactoriesProvider(MimePath mimePath) {
+ this.mimePath = mimePath;
+ }
+
+ private Formatter getFormatter() {
+ if (legacyFormatter == null) {
+ EditorKit kit = MimeLookup.getLookup(mimePath).lookup(EditorKit.class);
+ if (kit != null) {
+ try {
+ Method createFormatterMethod = kit.getClass().getDeclaredMethod("createFormatter"); //NOI18N
+ legacyFormatter = createFormatterMethod.invoke(kit);
+ } catch (Exception e) {
+ legacyFormatter = e;
+ }
+ } else {
+ legacyFormatter = NO_FORMATTER;
+ }
+ }
+ return legacyFormatter instanceof Formatter ? (Formatter) legacyFormatter : null;
+ }
+
+ } // End of IndentReformatTaskFactoriesProvider class
+
+ private static final class Indenter implements IndentTask {
+
+ private final Context context;
+ private final Formatter formatter;
+
+ public Indenter(Context context, Formatter formatter) {
+ this.context = context;
+ this.formatter = formatter;
+ }
+
+ public void reindent() throws BadLocationException {
+ Document doc = context.document();
+ int startOffset = context.startOffset();
+ int endOffset = context.endOffset();
+
+ pushFormattingContextDocument(doc);
+ try {
+ // Original formatter does not have reindentation of multiple lines
+ // so reformat start line and continue for each line.
+ Element lineRootElem = lineRootElement(doc);
+ Position endPos = doc.createPosition(endOffset);
+ do {
+ startOffset = formatter.indentLine(doc, startOffset);
+ int startLineIndex = lineRootElem.getElementIndex(startOffset) + 1;
+ if (startLineIndex >= lineRootElem.getElementCount())
+ break;
+ Element lineElem = lineRootElem.getElement(startLineIndex);
+ startOffset = lineElem.getStartOffset(); // Move to next line
+ } while (startOffset < endPos.getOffset());
+ } finally {
+ popFormattingContextDocument(doc);
+ }
+ }
+
+ public ExtraLock indentLock() {
+ return new ExtraLock() {
+ public void lock() {
+ formatter.indentLock();
+ }
+
+ public void unlock() {
+ formatter.indentUnlock();
+ }
+ };
+ }
+
+ private static Element lineRootElement(Document doc) {
+ return (doc instanceof StyledDocument)
+ ? ((StyledDocument)doc).getParagraphElement(0).getParentElement()
+ : doc.getDefaultRootElement();
+ }
+ } // End of Indenter class
+
+ private static final class Reformatter implements ReformatTask {
+
+ private final Context context;
+ private final Formatter formatter;
+
+ public Reformatter(Context context, Formatter formatter) {
+ this.context = context;
+ this.formatter = formatter;
+ }
+
+ public void reformat() throws BadLocationException {
+ pushFormattingContextDocument(context.document());
+ try {
+ formatter.reformat((BaseDocument) context.document(), context.startOffset(), context.endOffset());
+ } finally {
+ popFormattingContextDocument(context.document());
+ }
+ }
+
+ public ExtraLock reformatLock() {
+ return new ExtraLock() {
+ public void lock() {
+ formatter.reformatLock();
+ }
+
+ public void unlock() {
+ formatter.reformatUnlock();
+ }
+ };
+ }
+ } // End of Reformatter class
+
+ private static final class AutoIndenter implements TypedTextInterceptor {
+
+ private final ExtFormatter formatter;
+
+ public AutoIndenter(ExtFormatter formatter) {
+ this.formatter = formatter;
+ }
+
+ public boolean beforeInsert(Context context) throws BadLocationException {
+ // no-op
+ return false;
+ }
+
+ public void insert(MutableContext context) throws BadLocationException {
+ // no-op
+ }
+
+ public void afterInsert(Context context) throws BadLocationException {
+ if (context.getDocument() instanceof BaseDocument) {
+ BaseDocument doc = (BaseDocument) context.getDocument();
+ int [] fmtBlk = formatter.getReformatBlock(context.getComponent(), context.getText());
+ if (fmtBlk != null) {
+ try {
+
+ fmtBlk[0] = Utilities.getRowStart(doc, fmtBlk[0]);
+ fmtBlk[1] = Utilities.getRowEnd(doc, fmtBlk[1]);
+
+ //this was the of #18922, that causes the bug #20198
+ //ef.reformat(doc, fmtBlk[0], fmtBlk[1]);
+
+ //bugfix of the bug #20198. Bug #18922 is fixed too as well as #6968
+ formatter.reformat(doc, fmtBlk[0], fmtBlk[1], true);
+
+ } catch (BadLocationException e) {
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ public void cancelled(Context context) {
+ // no-op
+ }
+
+ } // End of AutoIndenter class
+}
diff --git a/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/layer.xml b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/layer.xml
new file mode 100644
--- /dev/null
+++ b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/layer.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/preferences.xml b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/preferences.xml
new file mode 100644
--- /dev/null
+++ b/editor.deprecated.pre65formatting/src/org/netbeans/modules/editor/deprecated/pre65formatting/preferences.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/editor.errorstripe/nbproject/project.xml b/editor.errorstripe/nbproject/project.xml
--- a/editor.errorstripe/nbproject/project.xml
+++ b/editor.errorstripe/nbproject/project.xml
@@ -71,8 +71,8 @@
- 2
- 2.1
+ 3
+ 3.1
diff --git a/editor.highlights/nbproject/project.xml b/editor.highlights/nbproject/project.xml
--- a/editor.highlights/nbproject/project.xml
+++ b/editor.highlights/nbproject/project.xml
@@ -54,8 +54,8 @@
- 1
- 1.27
+ 3
+ 3.1
@@ -115,6 +115,15 @@
1.0
+
+ org.netbeans.modules.editor.deprecated.pre65formatting
+
+
+
+ 0-1
+ 1.0
+
+
diff --git a/editor.indent/apichanges.xml b/editor.indent/apichanges.xml
--- a/editor.indent/apichanges.xml
+++ b/editor.indent/apichanges.xml
@@ -108,6 +108,36 @@
+
+ Adding org.netbeans.modules.editor.indent.spi.support.AutomatedIndenting
+
+
+
+
+
+ The AutomatedIndenting support class provides regex-based
+ automatic re-indentation of lines as user types. This is a replacement for
+ the deprecated ExtFormatter.getReformatBlock and INDENT_HOT_CHARS_ACCEPTOR
+ setting.
+
+
+
+
+
+
+ Adding org.netbeans.modules.editor.indent.api.Indent.indentNewLine
+
+
+
+
+
+ The new method int Indent.indentNewLine(int) was added as
+ a replacement for the old int Formatter.indentNewLine(BaseDocument, int).
+
+
+
+
+
Adding CodeStylePreferences.Provider
diff --git a/editor.indent/manifest.mf b/editor.indent/manifest.mf
--- a/editor.indent/manifest.mf
+++ b/editor.indent/manifest.mf
@@ -4,3 +4,4 @@
OpenIDE-Module-Layer: org/netbeans/modules/editor/indent/resources/layer.xml
AutoUpdate-Show-In-Client: false
OpenIDE-Module-Recommends: org.netbeans.modules.editor.indent.spi.CodeStylePreferences.Provider
+OpenIDE-Module-Specification-Version: 1.20.0
diff --git a/editor.indent/nbproject/project.properties b/editor.indent/nbproject/project.properties
--- a/editor.indent/nbproject/project.properties
+++ b/editor.indent/nbproject/project.properties
@@ -42,7 +42,6 @@
javac.source=1.6
javac.compilerargs=-Xlint:unchecked
-spec.version.base=1.20.0
javadoc.arch=${basedir}/arch.xml
javadoc.apichanges=${basedir}/apichanges.xml
diff --git a/editor.indent/nbproject/project.xml b/editor.indent/nbproject/project.xml
--- a/editor.indent/nbproject/project.xml
+++ b/editor.indent/nbproject/project.xml
@@ -50,12 +50,12 @@
org.netbeans.modules.editor.indent
- org.netbeans.modules.editor.lib
+ org.netbeans.modules.editor.lib2
- 2
-
+ 1
+ 1.31
@@ -176,6 +176,7 @@
org.netbeans.modules.editor.indent.apiorg.netbeans.modules.editor.indent.spi
+ org.netbeans.modules.editor.indent.spi.support
diff --git a/editor.indent/src/org/netbeans/modules/editor/indent/FormatterImpl.java b/editor.indent/src/org/netbeans/modules/editor/indent/FormatterImpl.java
deleted file mode 100644
--- a/editor.indent/src/org/netbeans/modules/editor/indent/FormatterImpl.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
- *
- * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
- * Other names may be trademarks of their respective owners.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common
- * Development and Distribution License("CDDL") (collectively, the
- * "License"). You may not use this file except in compliance with the
- * License. You can obtain a copy of the License at
- * http://www.netbeans.org/cddl-gplv2.html
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
- * specific language governing permissions and limitations under the
- * License. When distributing the software, include this License Header
- * Notice in each file and include the License file at
- * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the GPL Version 2 section of the License file that
- * accompanied this code. If applicable, add the following below the
- * License Header, with the fields enclosed by brackets [] replaced by
- * your own identifying information:
- * "Portions Copyrighted [year] [name of copyright owner]"
- *
- * Contributor(s):
- *
- * The Original Software is NetBeans. The Initial Developer of the Original
- * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
- * Microsystems, Inc. All Rights Reserved.
- *
- * If you wish your version of this file to be governed by only the CDDL
- * or only the GPL Version 2, indicate your decision by adding
- * "[Contributor] elects to include this software in this distribution
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
- * single choice of license, a recipient has the option to distribute
- * your version of this file under either the CDDL, the GPL Version 2 or
- * to extend the choice of license to its licensees as provided above.
- * However, if you add GPL Version 2 code and therefore, elected the GPL
- * Version 2 license, then the option applies only if the new code is
- * made subject to such option by the copyright holder.
- */
-
-package org.netbeans.modules.editor.indent;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.lang.reflect.Method;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.Document;
-import javax.swing.text.JTextComponent;
-import org.netbeans.editor.BaseDocument;
-import org.netbeans.editor.Formatter;
-import org.netbeans.editor.GuardedException;
-import org.netbeans.editor.ext.ExtFormatter;
-import org.netbeans.modules.editor.indent.api.IndentUtils;
-
-/**
- * Indentation and code reformatting services for a swing text document.
- *
- * @author Miloslav Metelka
- */
-public final class FormatterImpl extends ExtFormatter {
-
- private final Document doc;
- private final Formatter defaultFormatter;
- private final IndentImpl indentImpl;
-
- private final boolean tabSizeOverriden;
- private final boolean shiftWidthOverriden;
- private final boolean expandTabsOverriden;
-
- FormatterImpl(Formatter defaultFormatter, Document doc) {
- super(defaultFormatter.getKitClass());
-
- this.defaultFormatter = defaultFormatter;
- this.tabSizeOverriden = isOverriden(defaultFormatter.getClass(), "getTabSize"); //NOI18N
- this.shiftWidthOverriden = isOverriden(defaultFormatter.getClass(), "getShiftWidth"); //NOI18N
- this.expandTabsOverriden = isOverriden(defaultFormatter.getClass(), "expandTabs"); //NOI18N
-
- this.doc = doc;
- assert doc != null;
-
- this.indentImpl = IndentImpl.get(doc);
- indentImpl.setDefaultFormatter(defaultFormatter);
- }
-
- @Override
- public int[] getReformatBlock(JTextComponent target, String typedText) {
- return (defaultFormatter instanceof ExtFormatter)
- ? ((ExtFormatter)defaultFormatter).getReformatBlock(target, typedText)
- : null;
- }
-
- @Override
- public void indentLock() {
- indentImpl.indentLock();
- }
-
- @Override
- public void indentUnlock() {
- indentImpl.indentUnlock();
- }
-
- @Override
- public void reformatLock() {
- indentImpl.reformatLock();
- }
-
- @Override
- public void reformatUnlock() {
- indentImpl.reformatUnlock();
- }
-
- @Override
- public int getTabSize() {
- if (tabSizeOverriden) {
- return defaultFormatter.getTabSize();
- } else {
- return IndentUtils.tabSize(doc);
- }
- }
-
- @Override
- public int getSpacesPerTab() {
- return defaultFormatter.getSpacesPerTab();
- }
-
- @Override
- public int getShiftWidth() {
- if (shiftWidthOverriden) {
- return defaultFormatter.getShiftWidth();
- } else {
- return IndentUtils.indentLevelSize(doc);
- }
- }
-
- @Override
- public boolean expandTabs() {
- if (expandTabsOverriden) {
- return defaultFormatter.expandTabs();
- } else {
- return IndentUtils.isExpandTabs(doc);
- }
- }
-
- @Override
- public int indentLine(Document doc, int offset) {
- return indentLine(doc, offset, false);
- }
-
- /** Inserts new line at given position and indents the new line with
- * spaces.
- *
- * @param doc the document to work on
- * @param offset the offset of a character on the line
- * @return new offset to place cursor to
- */
- @Override
- public int indentNewLine(Document doc, int offset) {
- return indentLine(doc, offset, true);
- }
-
- private int indentLine(Document doc, int offset, boolean indentNewLine) {
- try {
- return indentImpl.reindent(offset, offset, offset, indentNewLine);
- } catch (GuardedException e) {
- java.awt.Toolkit.getDefaultToolkit().beep();
- } catch (BadLocationException e) {
- throw new IllegalStateException(e);
- }
- return offset;
- }
-
- @Override
- public Writer reformat(BaseDocument doc, int startOffset, int endOffset,
- boolean indentOnly) throws BadLocationException, IOException {
- // TBD delegate somehow
- return (defaultFormatter instanceof ExtFormatter)
- ? ((ExtFormatter)defaultFormatter).reformat(doc, startOffset, endOffset, indentOnly)
- : null;
- }
-
- @Override
- public int reformat(BaseDocument doc, int startOffset, int endOffset)
- throws BadLocationException {
- if (doc != indentImpl.document())
- return endOffset - startOffset; // should not happen in reality
- indentImpl.reformat(startOffset, endOffset);
- TaskHandler handler = indentImpl.reformatHandler();
- return (handler != null && handler.hasItems())
- ? Math.max(handler.endPos().getOffset() - startOffset, 0)
- : endOffset - startOffset;
- }
-
- @Override
- public Writer createWriter(Document doc, int offset, Writer writer) {
- if (doc != indentImpl.document()) {
- throw new IllegalStateException("Unexpected document doc=" + doc); //NOI18N
- }
- return new FormatterWriterImpl(indentImpl, offset, writer);
- }
-
- private static boolean isOverriden(Class clazz, String methodName) {
- while (clazz != Formatter.class && clazz != ExtFormatter.class) {
- for(Method m : clazz.getDeclaredMethods()) {
- if (m.getName().equals(methodName) && m.getParameterTypes().length == 0) {
- return true;
- }
- }
-
- clazz = clazz.getSuperclass();
- }
-
- return false;
- }
-}
diff --git a/editor.indent/src/org/netbeans/modules/editor/indent/FormatterOverrideImpl.java b/editor.indent/src/org/netbeans/modules/editor/indent/FormatterOverrideImpl.java
deleted file mode 100644
--- a/editor.indent/src/org/netbeans/modules/editor/indent/FormatterOverrideImpl.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
- *
- * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
- * Other names may be trademarks of their respective owners.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common
- * Development and Distribution License("CDDL") (collectively, the
- * "License"). You may not use this file except in compliance with the
- * License. You can obtain a copy of the License at
- * http://www.netbeans.org/cddl-gplv2.html
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
- * specific language governing permissions and limitations under the
- * License. When distributing the software, include this License Header
- * Notice in each file and include the License file at
- * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the GPL Version 2 section of the License file that
- * accompanied this code. If applicable, add the following below the
- * License Header, with the fields enclosed by brackets [] replaced by
- * your own identifying information:
- * "Portions Copyrighted [year] [name of copyright owner]"
- *
- * Contributor(s):
- *
- * The Original Software is NetBeans. The Initial Developer of the Original
- * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
- * Microsystems, Inc. All Rights Reserved.
- *
- * If you wish your version of this file to be governed by only the CDDL
- * or only the GPL Version 2, indicate your decision by adding
- * "[Contributor] elects to include this software in this distribution
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
- * single choice of license, a recipient has the option to distribute
- * your version of this file under either the CDDL, the GPL Version 2 or
- * to extend the choice of license to its licensees as provided above.
- * However, if you add GPL Version 2 code and therefore, elected the GPL
- * Version 2 license, then the option applies only if the new code is
- * made subject to such option by the copyright holder.
- */
-
-package org.netbeans.modules.editor.indent;
-
-import javax.swing.text.Document;
-import org.netbeans.editor.Formatter;
-import org.netbeans.modules.editor.lib.FormatterOverride;
-
-/**
- * Indentation and code reformatting services for a swing text document.
- *
- * @author Miloslav Metelka
- */
-@org.openide.util.lookup.ServiceProvider(service=org.netbeans.modules.editor.lib.FormatterOverride.class)
-public final class FormatterOverrideImpl implements FormatterOverride {
-
- public Formatter getFormatter(Document doc, Formatter defaultFormatter) {
- // Always override and possibly delegate to default formatter
- return new FormatterImpl(defaultFormatter, doc);
- }
-
-}
diff --git a/editor.indent/src/org/netbeans/modules/editor/indent/IndentImpl.java b/editor.indent/src/org/netbeans/modules/editor/indent/IndentImpl.java
--- a/editor.indent/src/org/netbeans/modules/editor/indent/IndentImpl.java
+++ b/editor.indent/src/org/netbeans/modules/editor/indent/IndentImpl.java
@@ -49,12 +49,9 @@
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
-import javax.swing.text.Position;
import javax.swing.text.StyledDocument;
import org.netbeans.modules.editor.indent.api.Indent;
import org.netbeans.modules.editor.indent.api.Reformat;
-import org.netbeans.editor.BaseDocument;
-import org.netbeans.editor.Formatter;
/**
* Indentation and code reformatting services for a swing text document.
@@ -72,7 +69,8 @@
indentImpl = new IndentImpl(doc);
doc.putProperty(IndentImpl.class, indentImpl);
}
- indentImpl.refresh();
+// XXX: formatting infra cleanup
+// indentImpl.refresh();
return indentImpl;
}
@@ -85,9 +83,10 @@
private TaskHandler indentHandler;
private TaskHandler reformatHandler;
+
+// XXX: formatting infra cleanup
+// private Formatter defaultFormatter;
- private Formatter defaultFormatter;
-
private Thread lockThread;
private int lockExtraDepth;
@@ -116,17 +115,18 @@
this.reformat = reformat;
}
- void setDefaultFormatter(Formatter defaultFormatter) {
- this.defaultFormatter = defaultFormatter;
- }
-
- void refresh() {
- if (defaultFormatter == null) {
- if (doc instanceof BaseDocument) {
- defaultFormatter = ((BaseDocument)doc).getLegacyFormatter();
- }
- }
- }
+// XXX: formatting infra cleanup
+// void setDefaultFormatter(Formatter defaultFormatter) {
+// this.defaultFormatter = defaultFormatter;
+// }
+//
+// void refresh() {
+// if (defaultFormatter == null) {
+// if (doc instanceof BaseDocument) {
+// defaultFormatter = ((BaseDocument)doc).getLegacyFormatter();
+// }
+// }
+// }
public synchronized void indentLock() {
if (LOG.isLoggable(Level.FINE)) {
@@ -221,7 +221,8 @@
// Find begining of line
Element lineRootElem = lineRootElement(doc);
// Correct the start offset to point to the begining of the start line
- boolean done = false;
+// XXX: formatting infra cleanup
+// boolean done = false;
if (indentHandler.hasItems()) {
// When indenting newline first insert a plain newline
if (indentNewLine) {
@@ -257,37 +258,40 @@
// Perform whole reindent on top and possibly embedded levels
indentHandler.runTasks();
- done = true;
+// XXX: formatting infra cleanup
+// done = true;
}
- // Fallback to Formatter
- if (!done && doc instanceof BaseDocument && defaultFormatter != null) {
- if (indentNewLine) {
- if (LOG.isLoggable(Level.FINE)) {
- LOG.fine("Defaulting reindent() to indentNewLine() in legacy formatter " + // NOI18N
- defaultFormatter + '\n');
- }
- // Fallback to indentNewLine() will insert '\n'
- int newCaretOffset = defaultFormatter.indentNewLine(doc, caretOffset);
- indentHandler.setCaretOffset(newCaretOffset);
- } else { // Indent line
- // Original formatter does not have reindentation of multiple lines
- // so reformat start line and continue for each line.
- Position endPos = doc.createPosition(endOffset);
- if (LOG.isLoggable(Level.FINE)) {
- LOG.fine("Defaulting reindent() to indentLine() in legacy formatter " + // NOI18N
- defaultFormatter + '\n');
- }
- do {
- startOffset = defaultFormatter.indentLine(doc, startOffset);
- int startLineIndex = lineRootElem.getElementIndex(startOffset) + 1;
- if (startLineIndex >= lineRootElem.getElementCount())
- break;
- Element lineElem = lineRootElem.getElement(startLineIndex);
- startOffset = lineElem.getStartOffset(); // Move to next line
- } while (startOffset < endPos.getOffset());
- }
- }
+// XXX: formatting infra cleanup
+// // Fallback to Formatter
+// if (!done && doc instanceof BaseDocument && defaultFormatter != null) {
+// if (indentNewLine) {
+// if (LOG.isLoggable(Level.FINE)) {
+// LOG.fine("Defaulting reindent() to indentNewLine() in legacy formatter " + // NOI18N
+// defaultFormatter + '\n');
+// }
+// // Fallback to indentNewLine() will insert '\n'
+// int newCaretOffset = defaultFormatter.indentNewLine(doc, caretOffset);
+// indentHandler.setCaretOffset(newCaretOffset);
+// } else { // Indent line
+// // Original formatter does not have reindentation of multiple lines
+// // so reformat start line and continue for each line.
+// Position endPos = doc.createPosition(endOffset);
+// if (LOG.isLoggable(Level.FINE)) {
+// LOG.fine("Defaulting reindent() to indentLine() in legacy formatter " + // NOI18N
+// defaultFormatter + '\n');
+// }
+// do {
+// startOffset = defaultFormatter.indentLine(doc, startOffset);
+// int startLineIndex = lineRootElem.getElementIndex(startOffset) + 1;
+// if (startLineIndex >= lineRootElem.getElementCount())
+// break;
+// Element lineElem = lineRootElem.getElement(startLineIndex);
+// startOffset = lineElem.getStartOffset(); // Move to next line
+// } while (startOffset < endPos.getOffset());
+// }
+// }
+
return indentHandler.caretOffset();
} finally {
if (runUnlocked)
@@ -310,7 +314,8 @@
if (runUnlocked) {
reformatHandler.collectTasks();
}
- boolean done = false;
+// XXX: formatting infra cleanup
+// boolean done = false;
if (reformatHandler.hasItems()) {
reformatHandler.setGlobalBounds(
doc.createPosition(startOffset),
@@ -320,18 +325,20 @@
reformatHandler.runTasks();
// Perform reformatting of the top section and possible embedded sections
- done = true;
+// XXX: formatting infra cleanup
+// done = true;
}
- // Fallback to Formatter
- if (!done && doc instanceof BaseDocument && defaultFormatter != null) {
- if (LOG.isLoggable(Level.FINE)) {
- LOG.fine("Defaulting reformat() to reformat() in legacy formatter " + // NOI18N
- defaultFormatter + '\n');
- }
- BaseDocument bdoc = (BaseDocument)doc;
- defaultFormatter.reformat(bdoc, startOffset, endOffset);
- }
+// XXX: formatting infra cleanup
+// // Fallback to Formatter
+// if (!done && doc instanceof BaseDocument && defaultFormatter != null) {
+// if (LOG.isLoggable(Level.FINE)) {
+// LOG.fine("Defaulting reformat() to reformat() in legacy formatter " + // NOI18N
+// defaultFormatter + '\n');
+// }
+// BaseDocument bdoc = (BaseDocument)doc;
+// defaultFormatter.reformat(bdoc, startOffset, endOffset);
+// }
} finally {
if (runUnlocked)
reformatHandler = null;
diff --git a/editor.indent/src/org/netbeans/modules/editor/indent/TaskHandler.java b/editor.indent/src/org/netbeans/modules/editor/indent/TaskHandler.java
--- a/editor.indent/src/org/netbeans/modules/editor/indent/TaskHandler.java
+++ b/editor.indent/src/org/netbeans/modules/editor/indent/TaskHandler.java
@@ -62,7 +62,6 @@
import org.netbeans.api.lexer.LanguagePath;
import org.netbeans.api.lexer.TokenHierarchy;
import org.netbeans.api.lexer.TokenSequence;
-import org.netbeans.editor.GuardedDocument;
import org.netbeans.lib.editor.util.swing.MutablePositionRegion;
import org.netbeans.modules.editor.indent.spi.Context;
import org.netbeans.modules.editor.indent.spi.ExtraLock;
@@ -464,10 +463,10 @@
}
// Filter out guarded regions
- if (indentRegions.size() > 0 && doc instanceof GuardedDocument) {
- MutablePositionRegion region = IndentSpiPackageAccessor.get().positionRegion(indentRegions.get(0));
- int regionStartOffset = region.getStartOffset();
- GuardedDocument gdoc = (GuardedDocument)doc;
+// if (indentRegions.size() > 0 && doc instanceof GuardedDocument) {
+// MutablePositionRegion region = IndentSpiPackageAccessor.get().positionRegion(indentRegions.get(0));
+// int regionStartOffset = region.getStartOffset();
+// GuardedDocument gdoc = (GuardedDocument)doc;
// int gbStartOffset = guardedBlocks.adjustToBlockEnd(region.getEndOffset());
// MarkBlockChain guardedBlocks = gdoc.getGuardedBlockChain();
// if (guardedBlocks != null && guardedBlocks.getChain() != null) {
@@ -500,7 +499,7 @@
// }
// }
// }
- }
+// }
} catch (BadLocationException e) {
Exceptions.printStackTrace(e);
indentRegions = Collections.emptyList();
diff --git a/editor.indent/src/org/netbeans/modules/editor/indent/api/Indent.java b/editor.indent/src/org/netbeans/modules/editor/indent/api/Indent.java
--- a/editor.indent/src/org/netbeans/modules/editor/indent/api/Indent.java
+++ b/editor.indent/src/org/netbeans/modules/editor/indent/api/Indent.java
@@ -171,4 +171,23 @@
impl.reindent(startOffset, endOffset, startOffset, false);
}
+ /**
+ * Creates new line at offset and reindents it.
+ *
+ *
This method will insert a line break (ie EOL character) at the specified
+ * offset and then reindent the newly created line. The method will return the
+ * offset of the indented beginning of the new line. That is the offset where
+ * the new text should appear when typing in the document.
+ *
+ * @param offset The document offset where the new line will be created.
+ *
+ * @return The offset of the first non-white character (or the EOL character)
+ * on the new line. This is basically where the caret should be moved to.
+ * @throws javax.swing.text.BadLocationException
+ * @since 1.10
+ */
+ public int indentNewLine(int offset) throws BadLocationException {
+ return impl.reindent(offset, offset, offset, true);
+ }
+
}
diff --git a/editor.indent/src/org/netbeans/modules/editor/indent/spi/support/AutomatedIndenting.java b/editor.indent/src/org/netbeans/modules/editor/indent/spi/support/AutomatedIndenting.java
new file mode 100644
--- /dev/null
+++ b/editor.indent/src/org/netbeans/modules/editor/indent/spi/support/AutomatedIndenting.java
@@ -0,0 +1,238 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2008 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.editor.indent.spi.support;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.lib.editor.util.swing.DocumentUtilities;
+import org.netbeans.modules.editor.indent.api.Indent;
+import org.netbeans.spi.editor.typinghooks.TypedTextInterceptor;
+
+/**
+ * This class contains factory methods for typing interceptor implementations
+ * that can be used for automated text indenting.
+ *
+ *
The interceptors provided by this class are implementations of Typing Hooks SPI
+ * interfaces that can be registered in MimeLookup. Typically there are
+ * two factory methods for each interceptor implementation. One factory method creates
+ * the implementated interceptor and is suitable for direct use from java code. The
+ * other factory method creates a factory object that can be registred in an XML layer
+ * as an .instance file.
+ *
+ * @author Vita Stejskal
+ * @since 1.11
+ */
+public final class AutomatedIndenting {
+
+ /**
+ * Creates TypedTextInterceptor that automatically
+ * indents a line depending on text typed on that line.
+ *
+ *
The text patterns recognized by the intercetor are defined in form
+ * of regular expressions passed to this method. The interceptor will match
+ * all text before the caret on the line where a user is typing (including
+ * the last typed character) against the regular expression patterns. If the text
+ * matches at least one pattern the interceptor will reindent the line by
+ * calling {@link Indent#reindent(int)} method.
+ *
+ * @param linePatterns The regular expressions that will be used for matching
+ * text typed on a line. Any matching pattern will trigger the line reindentation.
+ *
+ * @return The interceptor that checks text typed on a line and reindents the line
+ * if it matches any of the linePatterns.
+ *
+ * @since 1.11
+ */
+ public static TypedTextInterceptor createHotCharsIndenter(Pattern... linePatterns) {
+ return new RegExBasedIndenter(linePatterns);
+ }
+
+ /**
+ * This is a version of {@link #createHotCharsIndenter(java.util.regex.Pattern[])} method suitable
+ * for XML layers registration.
+ *
+ *
+ *
Here is an example of an XML layer registration done
+ * for text/x-java mime type. The registered interceptor will indent
+ * any line that contains whitespace followed by 'else'. The ending 'e' character is
+ * the last character typed on the line.
+ *
+ *
+ *
+ * @param fileAttributes The map of FileObject attributes. This method
+ * will recognize any attributes, which name starts with regex and will
+ * try to interpret their value as a regular expression. These regular expressions
+ * will then be used as linePatterns when calling createHotCharsIndenter(Pattern...) method.
+ *
+ * @return The interceptor factory that will provide a regular expressions based
+ * automated indenter returned from the {@link #createHotCharsIndenter(java.util.regex.Pattern[])} method.
+ * The list of line patterns will be recovered from the fileAttributes.
+ *
+ * @since 1.11
+ */
+ public static TypedTextInterceptor.Factory createHotCharsIndenter(Map
+ org.netbeans.modules.editor.indent
+
+
+
+ 2
+ 1.9
+
+
+ org.netbeans.modules.editor.lib2
@@ -136,6 +145,14 @@
+ org.openide.filesystems
+
+
+
+ 7.13
+
+
+ org.openide.util
diff --git a/editor.lib/src/org/netbeans/editor/Abbrev.java b/editor.lib/src/org/netbeans/editor/Abbrev.java
--- a/editor.lib/src/org/netbeans/editor/Abbrev.java
+++ b/editor.lib/src/org/netbeans/editor/Abbrev.java
@@ -56,6 +56,7 @@
import javax.swing.text.Caret;
import org.netbeans.lib.editor.util.CharSequenceUtilities;
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
+import org.netbeans.modules.editor.indent.api.Reformat;
/**
* Abbreviation support allowing to expand defined character sequences
@@ -296,12 +297,17 @@
}
if(ins.indexOf("\n") != -1) { // NOI18N
- Formatter formatter = doc.getFormatter();
- formatter.reformatLock();
+ Reformat formatter = Reformat.get(doc);
+ formatter.lock();
try {
- formatter.reformat(doc, dotPos, dotPos + ins.length());
+ doc.atomicLock();
+ try {
+ formatter.reformat(dotPos, dotPos + ins.length());
+ } finally {
+ doc.atomicUnlock();
+ }
} finally {
- formatter.reformatUnlock();
+ formatter.unlock();
}
}
diff --git a/editor.lib/src/org/netbeans/editor/ActionFactory.java b/editor.lib/src/org/netbeans/editor/ActionFactory.java
--- a/editor.lib/src/org/netbeans/editor/ActionFactory.java
+++ b/editor.lib/src/org/netbeans/editor/ActionFactory.java
@@ -45,6 +45,7 @@
package org.netbeans.editor;
import java.awt.Component;
+import java.awt.Cursor;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
@@ -52,6 +53,7 @@
import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.logging.Level;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.ButtonModel;
@@ -77,6 +79,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.swing.ImageIcon;
import javax.swing.JToggleButton;
import javax.swing.event.ChangeListener;
import javax.swing.text.AbstractDocument;
@@ -89,6 +92,9 @@
import org.netbeans.api.progress.ProgressUtils;
import org.netbeans.modules.editor.lib2.search.EditorFindSupport;
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
+import org.netbeans.modules.editor.indent.api.Indent;
+import org.netbeans.modules.editor.indent.api.Reformat;
+import org.netbeans.modules.editor.lib2.typinghooks.TypedBreakInterceptorsManager;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import org.openide.util.WeakListeners;
@@ -107,6 +113,9 @@
public class ActionFactory {
+ // -J-Dorg.netbeans.editor.ActionFactory.level=FINE
+ private static final Logger LOG = Logger.getLogger(ActionFactory.class.getName());
+
private ActionFactory() {
// no instantiation
}
@@ -133,12 +142,14 @@
doc.runAtomicAsUser (new Runnable () {
public void run () {
DocumentUtilities.setTypingModification(doc, true);
- Formatter.pushFormattingContextDocument(doc);
try {
if (Utilities.isSelectionShowing(caret)) { // block selected
try {
- doc.getFormatter().changeBlockIndent(doc,
- target.getSelectionStart(), target.getSelectionEnd(), -1);
+ BaseKit.changeBlockIndent(
+ doc,
+ target.getSelectionStart(),
+ target.getSelectionEnd(),
+ -1);
} catch (GuardedException e) {
target.getToolkit().beep();
} catch (BadLocationException e) {
@@ -150,7 +161,7 @@
int firstNW = Utilities.getRowFirstNonWhite(doc, caret.getDot());
int endOffset = Utilities.getRowEnd(doc, caret.getDot());
if (firstNW == -1 || (firstNW >= caret.getDot()))
- doc.getFormatter().changeBlockIndent(doc, startOffset, endOffset, -1);
+ BaseKit.changeBlockIndent(doc, startOffset, endOffset, -1);
else {
// TODO:
// after we will have action which will do opposite to "tab" action
@@ -164,7 +175,6 @@
}
}
} finally {
- Formatter.popFormattingContextDocument(doc);
DocumentUtilities.setTypingModification(doc, false);
}
}
@@ -1447,22 +1457,21 @@
doc.runAtomicAsUser (new Runnable () {
public void run () {
DocumentUtilities.setTypingModification(doc, true);
- Formatter.pushFormattingContextDocument(doc);
try {
boolean right = BaseKit.shiftLineRightAction.equals(getValue(Action.NAME));
if (Utilities.isSelectionShowing(caret)) {
- doc.getFormatter().changeBlockIndent(doc,
- target.getSelectionStart(), target.getSelectionEnd(),
- right ? +1 : -1);
+ BaseKit.changeBlockIndent(
+ doc,
+ target.getSelectionStart(), target.getSelectionEnd(),
+ right ? +1 : -1);
} else {
- doc.getFormatter().shiftLine(doc, caret.getDot(), right);
+ BaseKit.shiftLine(doc, caret.getDot(), right);
}
} catch (GuardedException e) {
target.getToolkit().beep();
} catch (BadLocationException e) {
e.printStackTrace();
} finally {
- Formatter.popFormattingContextDocument(doc);
DocumentUtilities.setTypingModification(doc, false);
}
}
@@ -1494,9 +1503,8 @@
final GuardedDocument gdoc = (doc instanceof GuardedDocument)
? (GuardedDocument)doc : null;
- final Formatter formatter = doc.getFormatter();
- formatter.reformatLock();
- Formatter.pushFormattingContextDocument(doc);
+ final Reformat formatter = Reformat.get(doc);
+ formatter.lock();
try {
doc.runAtomicAsUser (new Runnable () {
public void run () {
@@ -1527,8 +1535,9 @@
}
}
- int reformattedLen = formatter.reformat(doc, pos, stopPos);
- pos = pos + reformattedLen;
+ Position stopPosition = doc.createPosition(stopPos);
+ formatter.reformat(pos, stopPos);
+ pos = pos + Math.max(stopPosition.getOffset() - pos, 0);
if (gdoc != null) { // adjust to end of current block
pos = gdoc.getGuardedBlockChain().adjustToBlockEnd(pos);
@@ -1542,8 +1551,7 @@
}
});
} finally {
- Formatter.popFormattingContextDocument(doc);
- formatter.reformatUnlock();
+ formatter.unlock();
}
}
}
@@ -1637,15 +1645,18 @@
return;
final GuardedDocument gdoc = (doc instanceof GuardedDocument)
? (GuardedDocument)doc : null;
+
+ // Set hourglass cursor
+ final Cursor origCursor = target.getCursor();
+ target.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
final AtomicBoolean canceled = new AtomicBoolean();
ProgressUtils.runOffEventDispatchThread(new Runnable() {
public void run() {
if (canceled.get()) return;
- final Formatter formatter = doc.getFormatter();
- formatter.reformatLock();
- Formatter.pushFormattingContextDocument(doc);
+ final Reformat formatter = Reformat.get(doc);
+ formatter.lock();
try {
if (canceled.get()) return;
doc.runAtomicAsUser (new Runnable () {
@@ -1680,8 +1691,9 @@
}
if (pos < stopPos) {
- int reformattedLen = formatter.reformat(doc, pos, stopPos);
- pos = pos + reformattedLen;
+ Position stopPosition = doc.createPosition(stopPos);
+ formatter.reformat(pos, stopPos);
+ pos = pos + Math.max(stopPosition.getOffset() - pos, 0);
} else {
pos++; //ensure to make progress
}
@@ -1695,12 +1707,13 @@
target.getToolkit().beep();
} catch (BadLocationException e) {
Utilities.annotateLoggable(e);
+ } finally {
+ target.setCursor(origCursor);
}
}
});
} finally {
- Formatter.popFormattingContextDocument(doc);
- formatter.reformatUnlock();
+ formatter.unlock();
}
}
}, NbBundle.getMessage(FormatAction.class, "Format_in_progress"), canceled, false); //NOI18N
@@ -1710,7 +1723,6 @@
}
}
}
-
}
@EditorActionRegistrations({
@@ -2331,7 +2343,12 @@
}
}
- /** Starts a new line in code. */
+ /**
+ * Starts a new line in code.
+ *
+ * @deprecated Please do not subclass this class. Use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
@EditorActionRegistration(name = BaseKit.startNewLineAction)
public static class StartNewLine extends LocalBaseAction {
public StartNewLine(){
@@ -2345,35 +2362,112 @@
return;
}
+ final int caretOffset;
+ final int insertionOffset;
+
+ try {
+ caretOffset = target.getCaretPosition();
+ insertionOffset = Utilities.getRowEnd(target, caretOffset);
+ } catch (BadLocationException ble) {
+ LOG.log(Level.FINE, null, ble);
+ return;
+ }
final BaseDocument doc = (BaseDocument)target.getDocument();
- final Formatter formatter = doc.getFormatter();
- formatter.indentLock();
+ final TypedBreakInterceptorsManager.Transaction transaction = TypedBreakInterceptorsManager.getInstance().openTransaction(
+ target, caretOffset, insertionOffset);
+
try {
- doc.runAtomicAsUser (new Runnable () {
- public void run () {
- try {
- //target.replaceSelection(""); //NOI18N -fix of issue #52485
- Caret caret = target.getCaret();
+ if (!transaction.beforeInsertion()) {
+ final Boolean [] result = new Boolean [] { Boolean.FALSE }; //NOI18N
+ final Indent indenter = Indent.get(doc);
+ indenter.lock();
+ try {
+ doc.runAtomicAsUser (new Runnable () {
+ public void run () {
+ Object [] r = transaction.textTyped();
+ String insertionText = r == null ? "\n" : (String) r[0]; //NOI18N
+ int breakInsertPosition = r == null ? -1 : (Integer) r[1];
+ int caretPosition = r == null ? -1 : (Integer) r[2];
+ int [] reindentBlocks = r == null ? null : (int []) r[3];
- // insert and remove '-' to remember caret
- // position
- int dotpos = caret.getDot();
- doc.insertString(dotpos,"-",null); //NOI18N
- doc.remove(dotpos,1);
- int eolDot = Utilities.getRowEnd(target, caret.getDot());
- int newDotPos = formatter.indentNewLine(doc,eolDot);
- caret.setDot(newDotPos);
- } catch (BadLocationException ex) {
- ex.printStackTrace();
- }
+ try {
+ performLineBreakInsertion(target, insertionOffset, insertionText, breakInsertPosition, caretPosition, reindentBlocks, indenter);
+ result[0] = Boolean.TRUE;
+ } catch (BadLocationException ble) {
+ LOG.log(Level.FINE, null, ble);
+ target.getToolkit().beep();
+ }
+ }
+ });
+ } finally {
+ indenter.unlock();
}
- });
+
+ if (result[0].booleanValue()) {
+ transaction.afterInsertion();
+ } // else line-break insertion failed
+
+ }
} finally {
- formatter.indentUnlock();
+ transaction.close();
}
}
- }
+
+ // --------------------------------------------------------------------
+ // Private implementation
+ // --------------------------------------------------------------------
+
+ private void performLineBreakInsertion(
+ JTextComponent target,
+ int insertionOffset,
+ String insertionText,
+ int breakInsertPosition,
+ int caretPosition,
+ int [] reindentBlocks,
+ Indent indenter) throws BadLocationException
+ {
+ BaseDocument doc = (BaseDocument) target.getDocument();
+ DocumentUtilities.setTypingModification(doc, true);
+ try {
+ //target.replaceSelection(""); //NOI18N -fix of issue #52485
+ Caret caret = target.getCaret();
+
+ // XXX: WTF is this?
+ // insert and remove '-' to remember caret
+ // position
+ int dotPos = caret.getDot();
+ doc.insertString(dotPos, "-", null); //NOI18N
+ doc.remove(dotPos, 1);
+
+ // insert new line, caret moves to the new line
+// int eolDot = Utilities.getRowEnd(target, caret.getDot());
+// doc.insertString(eolDot, "\n", null); //NOI18N
+ doc.insertString(insertionOffset, insertionText, null);
+ dotPos = insertionOffset;
+ dotPos += caretPosition != -1 ? caretPosition :
+ breakInsertPosition != -1 ? breakInsertPosition + 1 :
+ insertionText.indexOf('\n') + 1; //NOI18N
+
+ // reindent the new line
+ Position newDotPos = doc.createPosition(dotPos);
+ if (reindentBlocks != null && reindentBlocks.length > 0) {
+ for(int i = 0; i < reindentBlocks.length / 2; i++) {
+ int startOffset = insertionOffset + reindentBlocks[2 * i];
+ int endOffset = insertionOffset + reindentBlocks[2 * i + 1];
+ indenter.reindent(startOffset, endOffset);
+ }
+ } else {
+ indenter.reindent(dotPos);
+ }
+
+ caret.setDot(newDotPos.getOffset());
+ } finally {
+ DocumentUtilities.setTypingModification(doc, false);
+ }
+ }
+
+ } // End of StartNewLine class
/**
* Cut text from the caret position to either begining or end
diff --git a/editor.lib/src/org/netbeans/editor/BaseDocument.java b/editor.lib/src/org/netbeans/editor/BaseDocument.java
--- a/editor.lib/src/org/netbeans/editor/BaseDocument.java
+++ b/editor.lib/src/org/netbeans/editor/BaseDocument.java
@@ -100,7 +100,6 @@
import org.netbeans.modules.editor.lib.EditorPackageAccessor;
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
-import org.netbeans.modules.editor.lib.FormatterOverride;
import org.netbeans.modules.editor.lib.TrailingWhitespaceRemove;
import org.netbeans.modules.editor.lib.SettingsConversions;
import org.netbeans.modules.editor.lib.drawing.DrawEngine;
@@ -253,11 +252,6 @@
new Integer(3)
};
- /** Size of one indentation level. If this variable is null (value
- * is not set in Settings, then the default algorithm will be used.
- */
- private Integer shiftWidth;
-
/** How many times current writer requested writing */
private int writeDepth;
@@ -353,9 +347,10 @@
private Position lastPositionEditedByTyping = null;
- /** Formatter being used. */
- private Formatter formatter;
-
+ /** Size of one indentation level. If this variable is null (value
+ * is not set in Settings, then the default algorithm will be used.
+ */
+ private int shiftWidth = -1;
private int tabSize;
private Preferences prefs;
@@ -367,9 +362,12 @@
}
if (key == null || SimpleValueNames.INDENT_SHIFT_WIDTH.equals(key)) {
- int shw = prefs.getInt(SimpleValueNames.INDENT_SHIFT_WIDTH, -1);
- if (shw >= 0) {
- shiftWidth = shw;
+ shiftWidth = prefs.getInt(SimpleValueNames.INDENT_SHIFT_WIDTH, -1);
+ }
+
+ if (key == null || SimpleValueNames.SPACES_PER_TAB.equals(key)) {
+ if (shiftWidth == -1) {
+ shiftWidth = prefs.getInt(SimpleValueNames.SPACES_PER_TAB, EditorPreferencesDefaults.defaultSpacesPerTab);
}
}
@@ -457,9 +455,6 @@
putProperty(EditorPreferencesKeys.PREVIOUS_WORD_FINDER, finder != null ? finder : new FinderFactory.PreviousWordBwdFinder(BaseDocument.this, stopOnEOL, false));
}
- // Refresh formatter
- formatter = null;
-
SettingsConversions.callSettingsChange(BaseDocument.this);
}
};
@@ -621,31 +616,32 @@
// }
}
- /**
- * @deprecated Please use Editor Indentation API instead, for details see
- * Editor Indentation.
- */
- public Formatter getLegacyFormatter() {
- if (formatter == null) {
- formatter = (Formatter) SettingsConversions.callFactory(prefs, MimePath.parse(mimeType), FORMATTER, null);
- if (formatter == null) {
- formatter = Formatter.getFormatter(mimeType);
- }
- }
- return formatter;
- }
-
- /**
- * Gets the formatter for this document.
- *
- * @deprecated Please use Editor Indentation API instead, for details see
- * Editor Indentation.
- */
- public Formatter getFormatter() {
- Formatter f = getLegacyFormatter();
- FormatterOverride fp = Lookup.getDefault().lookup(FormatterOverride.class);
- return (fp != null) ? fp.getFormatter(this, f) : f;
- }
+// XXX: formatting cleanup
+// /**
+// * @deprecated Please use Editor Indentation API instead, for details see
+// * Editor Indentation.
+// */
+// public Formatter getLegacyFormatter() {
+// if (formatter == null) {
+// formatter = (Formatter) SettingsConversions.callFactory(prefs, MimePath.parse(mimeType), FORMATTER, null);
+// if (formatter == null) {
+// formatter = Formatter.getFormatter(mimeType);
+// }
+// }
+// return formatter;
+// }
+//
+// /**
+// * Gets the formatter for this document.
+// *
+// * @deprecated Please use Editor Indentation API instead, for details see
+// * Editor Indentation.
+// */
+// public Formatter getFormatter() {
+// Formatter f = getLegacyFormatter();
+// FormatterOverride fp = Lookup.getDefault().lookup(FormatterOverride.class);
+// return (fp != null) ? fp.getFormatter(this, f) : f;
+// }
/**
* @deprecated Please use Lexer instead, for details see
@@ -1570,15 +1566,11 @@
* setting. If so it uses it, otherwise it uses formatter.getSpacesPerTab().
*
* @see getTabSize()
- * @see Formatter.getSpacesPerTab()
+ * @deprecated Please use Editor Indentation API instead, for details see
+ * Editor Indentation.
*/
public int getShiftWidth() {
- if (shiftWidth != null) {
- return shiftWidth.intValue();
-
- } else {
- return getFormatter().getSpacesPerTab();
- }
+ return shiftWidth;
}
/**
diff --git a/editor.lib/src/org/netbeans/editor/BaseKit.java b/editor.lib/src/org/netbeans/editor/BaseKit.java
--- a/editor.lib/src/org/netbeans/editor/BaseKit.java
+++ b/editor.lib/src/org/netbeans/editor/BaseKit.java
@@ -67,10 +67,8 @@
import javax.swing.text.ViewFactory;
import javax.swing.text.Caret;
import javax.swing.text.JTextComponent;
-import java.io.CharArrayWriter;
import java.lang.reflect.Method;
import java.util.Set;
-import java.util.Vector;
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -87,14 +85,23 @@
import org.netbeans.api.editor.mimelookup.MimeLookup;
import org.netbeans.api.editor.mimelookup.MimePath;
import org.netbeans.api.editor.settings.KeyBindingSettings;
+import org.netbeans.api.editor.settings.SimpleValueNames;
+import org.netbeans.lib.editor.util.CharSequenceUtilities;
import org.netbeans.lib.editor.util.ListenerList;
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
+import org.netbeans.modules.editor.indent.api.Indent;
+import org.netbeans.modules.editor.indent.api.IndentUtils;
+import org.netbeans.modules.editor.indent.api.Reformat;
+import org.netbeans.modules.editor.indent.spi.CodeStylePreferences;
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
import org.netbeans.modules.editor.lib.KitsTracker;
import org.netbeans.modules.editor.lib.NavigationHistory;
import org.netbeans.modules.editor.lib.SettingsConversions;
import org.netbeans.modules.editor.lib2.highlighting.HighlightingManager;
+import org.netbeans.modules.editor.lib2.typinghooks.DeletedTextInterceptorsManager;
+import org.netbeans.modules.editor.lib2.typinghooks.TypedBreakInterceptorsManager;
+import org.netbeans.modules.editor.lib2.typinghooks.TypedTextInterceptorsManager;
import org.openide.awt.StatusDisplayer;
import org.openide.util.HelpCtx;
import org.openide.util.Lookup;
@@ -616,14 +623,15 @@
return new SyntaxSupport(doc);
}
- /**
- * Create the formatter appropriate for this kit
- * @deprecated Please use Editor Indentation API instead, for details see
- * Editor Indentation.
- */
- public Formatter createFormatter() {
- return new Formatter(this.getClass());
- }
+// XXX: formatting cleanup
+// /**
+// * Create the formatter appropriate for this kit
+// * @deprecated Please use Editor Indentation API instead, for details see
+// * Editor Indentation.
+// */
+// public Formatter createFormatter() {
+// return new Formatter(this.getClass());
+// }
/** Create text UI */
protected BaseTextUI createTextUI() {
@@ -1020,11 +1028,16 @@
- /** Default typed action */
+ /**
+ * Default typed action
+ *
+ * @deprecated Please do not subclass this class. Use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
// @EditorActionRegistration(name = defaultKeyTypedAction)
public static class DefaultKeyTypedAction extends LocalBaseAction {
- static final long serialVersionUID =3069164318144463899L;
+ static final long serialVersionUID = 3069164318144463899L;
public DefaultKeyTypedAction() {
// Construct with defaultKeyTypedAction name to retain full compatibility for extending actions
@@ -1033,8 +1046,6 @@
LOG.fine("DefaultKeyTypedAction with enhanced logging, see issue #145306"); //NOI18N
}
- private static final boolean isMac = System.getProperty("mrj.version") != null; //NOI18N
-
public void actionPerformed (final ActionEvent evt, final JTextComponent target) {
if ((target != null) && (evt != null)) {
@@ -1043,7 +1054,7 @@
boolean ctrl = ((mod & ActionEvent.CTRL_MASK) != 0);
// On the mac, norwegian and french keyboards use Alt to do bracket characters.
// This replicates Apple's modification DefaultEditorKit.DefaultKeyTypedAction
- boolean alt = isMac ? ((mod & ActionEvent.META_MASK) != 0) :
+ boolean alt = org.openide.util.Utilities.isMac() ? ((mod & ActionEvent.META_MASK) != 0) :
((mod & ActionEvent.ALT_MASK) != 0);
@@ -1057,67 +1068,50 @@
return;
}
- final Caret caret = target.getCaret();
- final BaseDocument doc = (BaseDocument)target.getDocument();
- final EditorUI editorUI = Utilities.getEditorUI(target);
// determine if typed char is valid
final String cmd = evt.getActionCommand();
- if ((cmd != null) && (cmd.length() == 1)) {
- // Utilities.clearStatusText(target);
+ if (cmd != null && cmd.length() == 1 && cmd.charAt(0) >= 0x20 && cmd.charAt(0) != 0x7F) {
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.log(Level.FINE, "Processing command char: {0}", Integer.toHexString(cmd.charAt(0))); //NOI18N
+ }
+ final BaseDocument doc = (BaseDocument)target.getDocument();
+ final int insertionOffset = computeInsertionOffset(target.getCaret());
+ final TypedTextInterceptorsManager.Transaction transaction = TypedTextInterceptorsManager.getInstance().openTransaction(
+ target, insertionOffset, cmd);
+
try {
- NavigationHistory.getEdits().markWaypoint(target, caret.getDot(), false, true);
- } catch (BadLocationException e) {
- LOG.log(Level.WARNING, "Can't add position to the history of edits.", e); //NOI18N
- }
-
- doc.runAtomicAsUser (new Runnable () {
- public void run () {
- DocumentUtilities.setTypingModification(doc, true);
- try {
- char ch = cmd.charAt(0);
- if ((ch >= 0x20) && (ch != 0x7F)) { // valid character
- LOG.fine("Processing command char: " + Integer.toHexString(ch)); //NOI18N
-
- editorUI.getWordMatch().clear(); // reset word matching
- Boolean overwriteMode = (Boolean)editorUI.getProperty(
- EditorUI.OVERWRITE_MODE_PROPERTY);
+ if (!transaction.beforeInsertion()) {
+ final Object [] result = new Object [] { Boolean.FALSE, "" }; //NOI18N
+ doc.runAtomicAsUser (new Runnable () {
+ public void run () {
+ Object [] r = transaction.textTyped();
+ String insertionText = r == null ? cmd : (String) r[0];
+ int caretPosition = r == null ? -1 : (Integer) r[1];
+
try {
- boolean doInsert = true; // editorUI.getAbbrev().checkAndExpand(ch, evt);
- if (doInsert) {
- if (Utilities.isSelectionShowing(caret)) { // valid selection
- boolean ovr = (overwriteMode != null && overwriteMode.booleanValue());
- try {
- doc.putProperty(DOC_REPLACE_SELECTION_PROPERTY, true);
- replaceSelection(target, caret.getDot(), caret, cmd, ovr);
- } finally {
- doc.putProperty(DOC_REPLACE_SELECTION_PROPERTY, null);
- }
- } else { // no selection
- int dotPos = caret.getDot();
- if (overwriteMode != null && overwriteMode.booleanValue()
- && dotPos < doc.getLength() && doc.getChars(dotPos, 1)[0] != '\n'
- ) { // overwrite current char
- insertString(doc, dotPos, caret, cmd, true);
- } else { // insert mode
- insertString(doc, dotPos, caret, cmd, false);
- }
- }
- }
- } catch (BadLocationException e) {
- LOG.log(Level.FINE, null, e);
+ performTextInsertion(target, insertionOffset, insertionText, caretPosition);
+ result[0] = Boolean.TRUE;
+ result[1] = insertionText;
+ } catch (BadLocationException ble) {
+ LOG.log(Level.FINE, null, ble);
target.getToolkit().beep();
}
- } else {
- LOG.fine("Invalid command char: " + Integer.toHexString(ch)); //NOI18N
}
+ });
+
+ if (((Boolean)result[0]).booleanValue()) {
+ transaction.afterInsertion();
- checkIndent(target, cmd);
- } finally {
- DocumentUtilities.setTypingModification(doc, false);
- }
+ // XXX: this is potentially wrong and we may need to call this with
+ // the original cmd; or maybe only if insertionText == cmd; but maybe
+ // it does not matter, because nobody seems to be overwriting this method anyway
+ checkIndent(target, (String)result[1]);
+ } // else text insertion failed
}
- });
+ } finally {
+ transaction.close();
+ }
} else {
if (LOG.isLoggable(Level.FINE)) {
StringBuilder sb = new StringBuilder();
@@ -1128,54 +1122,127 @@
sb.append(" ");
}
}
- LOG.fine("Invalid command: '" + sb + "'"); //NOI18N
+ LOG.log(Level.FINE, "Invalid command: {0}", sb); //NOI18N
}
}
}
}
- /**
- * Hook to insert the given string at the given position into
- * the given document in insert-mode, no selection, writeable
- * document. Designed to be overridden by subclasses that want
- * to intercept inserted characters.
- */
- protected void insertString(BaseDocument doc,
+ // --------------------------------------------------------------------
+ // SPI
+ // --------------------------------------------------------------------
+
+ /**
+ * Hook to insert the given string at the given position into
+ * the given document in insert-mode, no selection, writeable
+ * document. Designed to be overridden by subclasses that want
+ * to intercept inserted characters.
+ *
+ * @deprecated Please use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
+ protected void insertString(BaseDocument doc,
int dotPos,
Caret caret,
String str,
- boolean overwrite)
- throws BadLocationException
- {
- if (overwrite) doc.remove(dotPos, 1);
- doc.insertString(dotPos, str, null);
- }
+ boolean overwrite) throws BadLocationException
+ {
+ if (overwrite) {
+ doc.remove(dotPos, 1);
+ }
+
+ doc.insertString(dotPos, str, null);
+ }
- /**
- * Hook to insert the given string at the given position into
- * the given document in insert-mode with selection visible
- * Designed to be overridden by subclasses that want
- * to intercept inserted characters.
- */
- protected void replaceSelection(JTextComponent target,
- int dotPos,
- Caret caret,
- String str,
- boolean overwrite)
- throws BadLocationException
- {
- target.replaceSelection(str);
- }
+ /**
+ * Hook to insert the given string at the given position into
+ * the given document in insert-mode with selection visible
+ * Designed to be overridden by subclasses that want
+ * to intercept inserted characters.
+ *
+ * @deprecated Please use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
+ protected void replaceSelection(
+ JTextComponent target,
+ int dotPos,
+ Caret caret,
+ String str,
+ boolean overwrite) throws BadLocationException
+ {
+ target.replaceSelection(str);
+ }
-
- /** Check whether there was any important character typed
- * so that the line should be possibly reformatted.
- */
+ /**
+ * Check whether there was any important character typed
+ * so that the line should be possibly reformatted.
+ *
+ * @deprecated Please use AutomatedIndentig
+ * or Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
protected void checkIndent(JTextComponent target, String typedText) {
}
- }
+ // --------------------------------------------------------------------
+ // Private implementation
+ // --------------------------------------------------------------------
+ private void performTextInsertion(JTextComponent target, int insertionOffset, String insertionText, int caretPosition) throws BadLocationException {
+ final BaseDocument doc = (BaseDocument)target.getDocument();
+
+ try {
+ NavigationHistory.getEdits().markWaypoint(target, insertionOffset, false, true);
+ } catch (BadLocationException e) {
+ LOG.log(Level.WARNING, "Can't add position to the history of edits.", e); //NOI18N
+ }
+
+ DocumentUtilities.setTypingModification(doc, true);
+ try {
+ EditorUI editorUI = Utilities.getEditorUI(target);
+ Caret caret = target.getCaret();
+
+ editorUI.getWordMatch().clear(); // reset word matching
+ Boolean overwriteMode = (Boolean)editorUI.getProperty(EditorUI.OVERWRITE_MODE_PROPERTY);
+ boolean ovr = (overwriteMode != null && overwriteMode.booleanValue());
+ if (Utilities.isSelectionShowing(caret)) { // valid selection
+ try {
+ doc.putProperty(DOC_REPLACE_SELECTION_PROPERTY, true);
+ replaceSelection(target, insertionOffset, caret, insertionText, ovr);
+ } finally {
+ doc.putProperty(DOC_REPLACE_SELECTION_PROPERTY, null);
+ }
+ } else { // no selection
+ if (ovr && insertionOffset < doc.getLength() && doc.getChars(insertionOffset, 1)[0] != '\n') { //NOI18N
+ // overwrite current char
+ insertString(doc, insertionOffset, caret, insertionText, true);
+ } else { // insert mode
+ insertString(doc, insertionOffset, caret, insertionText, false);
+ }
+ }
+
+ if (caretPosition != -1) {
+ assert caretPosition >= 0 && caretPosition < insertionText.length();
+ caret.setDot(insertionOffset + caretPosition);
+ }
+ } finally {
+ DocumentUtilities.setTypingModification(doc, false);
+ }
+ }
+
+ private int computeInsertionOffset(Caret caret) {
+ if (Utilities.isSelectionShowing(caret)) {
+ return Math.min(caret.getMark(), caret.getDot());
+ } else {
+ return caret.getDot();
+ }
+ }
+ } // End of DefaultKeyTypedAction class
+
+ /**
+ * @deprecated Please do not subclass this class. Use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
public static class InsertBreakAction extends LocalBaseAction {
static final long serialVersionUID =7966576342334158659L;
@@ -1192,51 +1259,140 @@
}
final BaseDocument doc = (BaseDocument)target.getDocument();
- final Formatter formatter = doc.getFormatter();
- formatter.indentLock();
+ final int insertionOffset = computeInsertionOffset(target.getCaret());
+ final TypedBreakInterceptorsManager.Transaction transaction = TypedBreakInterceptorsManager.getInstance().openTransaction(
+ target, insertionOffset, insertionOffset);
+
try {
- doc.runAtomicAsUser (new Runnable () {
- public void run () {
- DocumentUtilities.setTypingModification(doc, true);
- try {
- target.replaceSelection("");
- Caret caret = target.getCaret();
- Object cookie = beforeBreak(target, doc, caret);
+ if (!transaction.beforeInsertion()) {
+ final Boolean [] result = new Boolean [] { Boolean.FALSE }; //NOI18N
+ final Indent indenter = Indent.get(doc);
+ indenter.lock();
+ try {
+ doc.runAtomicAsUser (new Runnable () {
+ public void run () {
+ Object [] r = transaction.textTyped();
+ String insertionText = r == null ? "\n" : (String) r[0]; //NOI18N
+ int breakInsertPosition = r == null ? -1 : (Integer) r[1];
+ int caretPosition = r == null ? -1 : (Integer) r[2];
+ int [] reindentBlocks = r == null ? null : (int []) r[3];
- int dotPos = caret.getDot();
- int newDotPos = formatter.indentNewLine(doc, dotPos);
- caret.setDot(newDotPos);
-
- afterBreak(target, doc, caret, cookie);
- } finally {
- DocumentUtilities.setTypingModification(doc, false);
- }
+ try {
+ performLineBreakInsertion(target, insertionOffset, insertionText, breakInsertPosition, caretPosition, reindentBlocks, indenter);
+ result[0] = Boolean.TRUE;
+ } catch (BadLocationException ble) {
+ LOG.log(Level.FINE, null, ble);
+ target.getToolkit().beep();
+ }
+ }
+ });
+ } finally {
+ indenter.unlock();
}
- });
+
+ if (result[0].booleanValue()) {
+ transaction.afterInsertion();
+ } // else line-break insertion failed
+
+ }
} finally {
- formatter.indentUnlock();
+ transaction.close();
}
+
}
}
- /**
- * Hook called before any changes to the document. The value
- * returned is passed intact to the other hook.
- */
- protected Object beforeBreak(JTextComponent target, BaseDocument doc, Caret caret) {
- return null;
- }
+ // --------------------------------------------------------------------
+ // SPI
+ // --------------------------------------------------------------------
- /**
- * Hook called after the enter was inserted and cursor
- * repositioned. *data* is the object returned previously by
- * *beforeBreak* hook. By default null.
- */
- protected void afterBreak(JTextComponent target, BaseDocument doc, Caret caret, Object data) {
- }
- }
+ /**
+ * Hook called before any changes to the document. The value
+ * returned is passed intact to the other hook.
+ *
+ * @deprecated Please use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
+ protected Object beforeBreak(JTextComponent target, BaseDocument doc, Caret caret) {
+ return null;
+ }
- @EditorActionRegistration(name = splitLineAction)
+ /**
+ * Hook called after the enter was inserted and cursor
+ * repositioned.
+ *
+ * @param data the object returned from previously called
+ * {@link #beforeBreak(javax.swing.text.JTextComponent, org.netbeans.editor.BaseDocument, javax.swing.text.Caret)} hook.
+ * By default null.
+ *
+ * @deprecated Please use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
+ protected void afterBreak(JTextComponent target, BaseDocument doc, Caret caret, Object data) {
+ }
+
+ // --------------------------------------------------------------------
+ // Private implementation
+ // --------------------------------------------------------------------
+
+ private void performLineBreakInsertion(
+ JTextComponent target,
+ int insertionOffset,
+ String insertionText,
+ int breakInsertPosition,
+ int caretPosition,
+ int [] reindentBlocks,
+ Indent indenter) throws BadLocationException
+ {
+ BaseDocument doc = (BaseDocument) target.getDocument();
+ DocumentUtilities.setTypingModification(doc, true);
+ try {
+ target.replaceSelection(""); // NOI18N
+ Caret caret = target.getCaret();
+ Object cookie = beforeBreak(target, doc, caret);
+
+ // insert new line, caret moves to the new line
+ int dotPos = caret.getDot();
+ assert dotPos == insertionOffset : "dotPos=" + dotPos + " != " + "insertionOffset=" + insertionOffset; //NOI18N
+// doc.insertString(dotPos, "\n", null); //NOI18N
+// dotPos++;
+ doc.insertString(dotPos, insertionText, null);
+ dotPos += caretPosition != -1 ? caretPosition :
+ breakInsertPosition != -1 ? breakInsertPosition + 1 :
+ insertionText.indexOf('\n') + 1; //NOI18N
+
+ // reindent the new line
+ Position newDotPos = doc.createPosition(dotPos);
+ if (reindentBlocks != null && reindentBlocks.length > 0) {
+ for(int i = 0; i < reindentBlocks.length / 2; i++) {
+ int startOffset = insertionOffset + reindentBlocks[2 * i];
+ int endOffset = insertionOffset + reindentBlocks[2 * i + 1];
+ indenter.reindent(startOffset, endOffset);
+ }
+ } else {
+ indenter.reindent(dotPos);
+ }
+
+ // adjust the caret
+ caret.setDot(newDotPos.getOffset());
+
+ afterBreak(target, doc, caret, cookie);
+ } finally {
+ DocumentUtilities.setTypingModification(doc, false);
+ }
+ }
+
+ private int computeInsertionOffset(Caret caret) {
+ if (Utilities.isSelectionShowing(caret)) {
+ return Math.min(caret.getMark(), caret.getDot());
+ } else {
+ return caret.getDot();
+ }
+ }
+
+ } // End of InsertBreakAction class
+
+ @EditorActionRegistration(name = splitLineAction)
public static class SplitLineAction extends LocalBaseAction {
static final long serialVersionUID =7966576342334158659L;
@@ -1255,24 +1411,33 @@
final BaseDocument doc = (BaseDocument)target.getDocument();
final Caret caret = target.getCaret();
- final Formatter formatter = doc.getFormatter();
- formatter.indentLock();
+ final Indent formatter = Indent.get(doc);
+ formatter.lock();
try {
doc.runAtomicAsUser (new Runnable () {
public void run () {
DocumentUtilities.setTypingModification(doc, true);
try{
- target.replaceSelection("");
- final int dotPos = caret.getDot(); // dot stays where it was
- formatter.indentNewLine(doc, dotPos); // newline
+ target.replaceSelection(""); //NOI18N
+
+ // insert new line, caret stays where it is
+ int dotPos = caret.getDot();
+ doc.insertString(dotPos, "\n", null); //NOI18N
+
+ // reindent the new line
+ formatter.reindent(dotPos + 1); // newline
+
+ // make sure the caret stays on its original position
caret.setDot(dotPos);
+ } catch (BadLocationException ble) {
+ LOG.log(Level.WARNING, null, ble);
} finally {
DocumentUtilities.setTypingModification(doc, false);
}
}
});
} finally {
- formatter.indentUnlock();
+ formatter.unlock();
}
}
}
@@ -1300,12 +1465,10 @@
doc.runAtomicAsUser (new Runnable () {
public void run () {
DocumentUtilities.setTypingModification(doc, true);
- Formatter.pushFormattingContextDocument(doc);
try {
if (Utilities.isSelectionShowing(caret)) { // block selected
try {
- doc.getFormatter().changeBlockIndent(doc,
- target.getSelectionStart(), target.getSelectionEnd(), +1);
+ changeBlockIndent(doc, target.getSelectionStart(), target.getSelectionEnd(), +1);
} catch (GuardedException e) {
target.getToolkit().beep();
} catch (BadLocationException e) {
@@ -1341,7 +1504,7 @@
// Fix of #32240 - #1 of 2
int rowStart = Utilities.getRowStart(doc, dotPos);
- doc.getFormatter().changeRowIndent(doc, dotPos, indent);
+ changeRowIndent(doc, dotPos, indent);
// Fix of #32240 - #2 of 2
int newDotPos = doc.getOffsetFromVisCol(indent, rowStart);
@@ -1350,7 +1513,7 @@
}
} else { // already chars on the line
- doc.getFormatter().insertTabString(doc, dotPos);
+ insertTabString(doc, dotPos);
}
} catch (BadLocationException e) {
@@ -1358,7 +1521,6 @@
}
}
} finally {
- Formatter.popFormattingContextDocument(doc);
DocumentUtilities.setTypingModification(doc, false);
}
}
@@ -1507,7 +1669,10 @@
}
}
- /** Remove previous or next character */
+ /**
+ * @deprecated Please do not subclass this class. Use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
public static class DeleteCharAction extends LocalBaseAction {
protected boolean nextChar;
@@ -1531,44 +1696,90 @@
final int dot = caret.getDot();
final int mark = caret.getMark();
- doc.runAtomicAsUser (new Runnable () {
- public void run () {
- DocumentUtilities.setTypingModification(doc, true);
-
- try {
- if (dot != mark) { // remove selection
- doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
- } else {
- if (nextChar) { // remove next char
- char ch = doc.getChars(dot, 1)[0];
- doc.remove(dot, 1);
- charDeleted(doc, dot, caret, ch);
- } else { // remove previous char
- char ch = doc.getChars(dot-1, 1)[0];
- doc.remove(dot - 1, 1);
- charBackspaced(doc, dot-1, caret, ch);
+ if (dot != mark) {
+ // remove selection
+ doc.runAtomicAsUser (new Runnable () {
+ public void run () {
+ DocumentUtilities.setTypingModification(doc, true);
+ try {
+ doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
+ } catch (BadLocationException e) {
+ target.getToolkit().beep();
+ } finally {
+ DocumentUtilities.setTypingModification(doc, false);
}
}
- } catch (BadLocationException e) {
+ });
+ } else {
+ char [] removedChar = null;
+
+ try {
+ removedChar = nextChar ?
+ dot < doc.getLength() - 1 ? doc.getChars(dot, 1) : null :
+ dot > 0 ? doc.getChars(dot - 1, 1) : null;
+ } catch (BadLocationException ble) {
target.getToolkit().beep();
- } finally {
- DocumentUtilities.setTypingModification(doc, false);
}
+
+ if (removedChar != null) {
+ final String removedText = String.valueOf(removedChar);
+ final DeletedTextInterceptorsManager.Transaction t = DeletedTextInterceptorsManager.getInstance().openTransaction(target, dot, removedText, !nextChar);
+ try {
+ if (!t.beforeRemove()) {
+ final boolean [] result = new boolean [] { false };
+ doc.runAtomicAsUser (new Runnable () {
+ public void run () {
+ DocumentUtilities.setTypingModification(doc, true);
+ try {
+ if (nextChar) { // remove next char
+ doc.remove(dot, 1);
+ } else { // remove previous char
+ doc.remove(dot - 1, 1);
+ }
+
+ t.textDeleted();
+
+ if (nextChar) {
+ charDeleted(doc, dot, caret, removedText.charAt(0));
+ } else {
+ charBackspaced(doc, dot - 1, caret, removedText.charAt(0));
+ }
+
+ result[0] = true;
+ } catch (BadLocationException e) {
+ target.getToolkit().beep();
+ } finally {
+ DocumentUtilities.setTypingModification(doc, false);
+ }
+ }
+ });
+
+ if (result[0]) {
+ t.afterRemove();
+ }
+ }
+ } finally {
+ t.close();
+ }
}
- });
+ }
}
}
- protected void charBackspaced(BaseDocument doc, int dotPos, Caret caret, char ch)
- throws BadLocationException
- {
- }
-
- protected void charDeleted(BaseDocument doc, int dotPos, Caret caret, char ch)
- throws BadLocationException
- {
- }
- }
+ /**
+ * @deprecated Please use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
+ protected void charBackspaced(BaseDocument doc, int dotPos, Caret caret, char ch) throws BadLocationException {
+ }
+
+ /**
+ * @deprecated Please use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
+ protected void charDeleted(BaseDocument doc, int dotPos, Caret caret, char ch) throws BadLocationException {
+ }
+ } // End of DeleteCharAction class
/**
* @deprecated this action is no longer used. It is reimplemented in editor.actions module.
@@ -1734,10 +1945,10 @@
LOG.log(Level.WARNING, "Can't add position to the history of edits.", e); //NOI18N
}
- final Formatter formatter = doc.getFormatter();
+ final Reformat formatter = Reformat.get(doc);
final boolean formatted = pasteFormatedAction.equals(getValue(Action.NAME));
if (formatted) {
- formatter.reformatLock();
+ formatter.lock();
}
try {
doc.runAtomicAsUser (new Runnable () {
@@ -1758,7 +1969,7 @@
}
int endOffset = caret.getDot();
if (formatted) {
- formatter.reformat(doc, startOffset, endOffset);
+ formatter.reformat(startOffset, endOffset);
}
} catch (Exception e) {
target.getToolkit().beep();
@@ -1769,72 +1980,72 @@
});
} finally {
if (formatted) {
- formatter.reformatUnlock();
+ formatter.unlock();
}
}
}
}
- public static void indentBlock(BaseDocument doc, int startOffset, int endOffset)
- throws BadLocationException
- {
- char [] text = doc.getChars(startOffset, endOffset-startOffset);
- String [] lines = toLines(new String(text));
-
- doc.remove(startOffset, endOffset - startOffset);
- // System.out.println("Lines:\n"); // NOI18N
- // for (int j = 0 ; j < lines.length; j++) System.out.println(lines[j] + "<"); // NOI18N
-
- int offset = startOffset;
- // handle the full lines
- for (int i = 0; i < lines.length - 1; i++) {
- String indent = getIndentString(doc, offset, lines[i]);
- String fragment = indent + lines[i].trim() + '\n';
- // System.out.println(fragment + "|"); // NOI18N
- doc.insertString(offset, fragment, null);
- offset += fragment.length();
- }
-
- // the rest just paste without indenting
- doc.insertString(offset, lines[lines.length-1], null);
-
- }
-
- /** Break string to lines */
- private static String [] toLines(String str) {
- Vector v = new Vector();
- int p=0 , p0=0;
- for (; p < str.length() ; p++) {
- if (str.charAt(p) == '\n') {
- v.add(str.substring(p0, p+1));
- p0 = p+1;
- }
- }
- if (p0 < str.length()) v.add(str.substring(p0, str.length())); else v.add("");
-
- return (String [])v.toArray(new String [0]);
- }
-
- private static String getIndentString(BaseDocument doc, int startOffset, String str) {
- try {
- Formatter f = doc.getFormatter();
- CharArrayWriter cw = new CharArrayWriter();
- Writer w = f.createWriter(doc, startOffset, cw);
- w.write(str, 0, str.length());
- w.close();
- String out = new String(cw.toCharArray());
- int i = 0;
- for (; i < out.length(); i++) {
- if (out.charAt(i) != ' ' && out.charAt(i) != '\t') break;
- }
- // System.out.println(out+"|"); // NOI18N
- // System.out.println(out.substring(0,i)+"^"); // NOI18N
-
- return out.substring(0, i);
- } catch (java.io.IOException e) {
- return "";
- }
- }
+// public static void indentBlock(BaseDocument doc, int startOffset, int endOffset)
+// throws BadLocationException
+// {
+// char [] text = doc.getChars(startOffset, endOffset-startOffset);
+// String [] lines = toLines(new String(text));
+//
+// doc.remove(startOffset, endOffset - startOffset);
+// // System.out.println("Lines:\n"); // NOI18N
+// // for (int j = 0 ; j < lines.length; j++) System.out.println(lines[j] + "<"); // NOI18N
+//
+// int offset = startOffset;
+// // handle the full lines
+// for (int i = 0; i < lines.length - 1; i++) {
+// String indent = getIndentString(doc, offset, lines[i]);
+// String fragment = indent + lines[i].trim() + '\n';
+// // System.out.println(fragment + "|"); // NOI18N
+// doc.insertString(offset, fragment, null);
+// offset += fragment.length();
+// }
+//
+// // the rest just paste without indenting
+// doc.insertString(offset, lines[lines.length-1], null);
+//
+// }
+//
+// /** Break string to lines */
+// private static String [] toLines(String str) {
+// Vector v = new Vector();
+// int p=0 , p0=0;
+// for (; p < str.length() ; p++) {
+// if (str.charAt(p) == '\n') {
+// v.add(str.substring(p0, p+1));
+// p0 = p+1;
+// }
+// }
+// if (p0 < str.length()) v.add(str.substring(p0, str.length())); else v.add("");
+//
+// return (String [])v.toArray(new String [0]);
+// }
+//
+// private static String getIndentString(BaseDocument doc, int startOffset, String str) {
+// try {
+// Formatter f = doc.getFormatter();
+// CharArrayWriter cw = new CharArrayWriter();
+// Writer w = f.createWriter(doc, startOffset, cw);
+// w.write(str, 0, str.length());
+// w.close();
+// String out = new String(cw.toCharArray());
+// int i = 0;
+// for (; i < out.length(); i++) {
+// if (out.charAt(i) != ' ' && out.charAt(i) != '\t') break;
+// }
+// // System.out.println(out+"|"); // NOI18N
+// // System.out.println(out.substring(0,i)+"^"); // NOI18N
+//
+// return out.substring(0, i);
+// } catch (java.io.IOException e) {
+// return "";
+// }
+// }
}
@@ -2875,4 +3086,154 @@
}
+
+ /** Modify the line to move the text starting at dotPos one tab
+ * column to the right. Whitespace preceeding dotPos may be
+ * replaced by a TAB character if tabs expanding is on.
+ * @param doc document to operate on
+ * @param dotPos insertion point
+ */
+ static void insertTabString (final BaseDocument doc, final int dotPos) throws BadLocationException {
+ final BadLocationException[] badLocationExceptions = new BadLocationException [1];
+ doc.runAtomic (new Runnable () {
+ public void run () {
+ try {
+ // Determine first white char before dotPos
+ int rsPos = Utilities.getRowStart(doc, dotPos);
+ int startPos = Utilities.getFirstNonWhiteBwd(doc, dotPos, rsPos);
+ startPos = (startPos >= 0) ? (startPos + 1) : rsPos;
+
+ int startCol = Utilities.getVisualColumn(doc, startPos);
+ int endCol = Utilities.getNextTabColumn(doc, dotPos);
+ Preferences prefs = CodeStylePreferences.get(doc).getPreferences();
+ String tabStr = Analyzer.getWhitespaceString(
+ startCol, endCol,
+ prefs.getBoolean(SimpleValueNames.EXPAND_TABS, EditorPreferencesDefaults.defaultExpandTabs),
+ prefs.getInt(SimpleValueNames.TAB_SIZE, EditorPreferencesDefaults.defaultTabSize));
+
+ // Search for the first non-common char
+ char[] removeChars = doc.getChars(startPos, dotPos - startPos);
+ int ind = 0;
+ while (ind < removeChars.length && removeChars[ind] == tabStr.charAt(ind)) {
+ ind++;
+ }
+
+ startPos += ind;
+ doc.remove(startPos, dotPos - startPos);
+ doc.insertString(startPos, tabStr.substring(ind), null);
+ } catch (BadLocationException ex) {
+ badLocationExceptions [0] = ex;
+ }
+ }
+ });
+ if (badLocationExceptions[0] != null)
+ throw badLocationExceptions [0];
+ }
+
+ /** Change the indent of the given row. Document is atomically locked
+ * during this operation.
+ */
+ static void changeRowIndent (final BaseDocument doc, final int pos, final int newIndent) throws BadLocationException {
+ final BadLocationException[] badLocationExceptions = new BadLocationException [1];
+ doc.runAtomic (new Runnable () {
+ public void run () {
+ try {
+ int indent = newIndent < 0 ? 0 : newIndent;
+ int firstNW = Utilities.getRowFirstNonWhite(doc, pos);
+ if (firstNW == -1) { // valid first non-blank
+ firstNW = Utilities.getRowEnd(doc, pos);
+ }
+ int replacePos = Utilities.getRowStart(doc, pos);
+ int removeLen = firstNW - replacePos;
+ CharSequence removeText = DocumentUtilities.getText(doc, replacePos, removeLen);
+ String newIndentText = IndentUtils.createIndentString(doc, indent);
+ if (CharSequenceUtilities.startsWith(newIndentText, removeText)) {
+ // Skip removeLen chars at start
+ newIndentText = newIndentText.substring(removeLen);
+ replacePos += removeLen;
+ removeLen = 0;
+ } else if (CharSequenceUtilities.endsWith(newIndentText, removeText)) {
+ // Skip removeLen chars at the end
+ newIndentText = newIndentText.substring(0, newIndentText.length() - removeLen);
+ removeLen = 0;
+ }
+
+ if (removeLen != 0) {
+ doc.remove(replacePos, removeLen);
+ }
+
+ doc.insertString(replacePos, newIndentText, null);
+ } catch (BadLocationException ex) {
+ badLocationExceptions [0] = ex;
+ }
+ }
+ });
+ if (badLocationExceptions[0] != null)
+ throw badLocationExceptions [0];
+ }
+
+ /** Increase/decrease indentation of the block of the code. Document
+ * is atomically locked during the operation.
+ * @param doc document to operate on
+ * @param startPos starting line position
+ * @param endPos ending line position
+ * @param shiftCnt positive/negative count of shiftwidths by which indentation
+ * should be shifted right/left
+ */
+ static void changeBlockIndent (final BaseDocument doc, final int startPos, final int endPos,
+ final int shiftCnt) throws BadLocationException {
+ GuardedDocument gdoc = (doc instanceof GuardedDocument)
+ ? (GuardedDocument)doc : null;
+ if (gdoc != null){
+ for (int i = startPos; i 0 && Utilities.getRowStart(doc, endPos) == endPos) ?
+ endPos - 1 : endPos;
+
+ int pos = Utilities.getRowStart(doc, startPos );
+ for (int lineCnt = Utilities.getRowCount(doc, startPos, end);
+ lineCnt > 0; lineCnt--
+ ) {
+ int indent = Utilities.getRowIndent(doc, pos);
+ if (Utilities.isRowWhite(doc, pos)) {
+ indent = -indentDelta; // zero indentation for white line
+ }
+ changeRowIndent(doc, pos, Math.max(indent + indentDelta, 0));
+ pos = Utilities.getRowStart(doc, pos, +1);
+ }
+ } catch (BadLocationException ex) {
+ badLocationExceptions [0] = ex;
+ }
+ }
+ });
+ if (badLocationExceptions[0] != null)
+ throw badLocationExceptions [0];
+ }
+
+ /** Shift line either left or right */
+ static void shiftLine(BaseDocument doc, int dotPos, boolean right) throws BadLocationException {
+ int ind = doc.getShiftWidth();
+ if (!right) {
+ ind = -ind;
+ }
+
+ if (Utilities.isRowWhite(doc, dotPos)) {
+ ind += Utilities.getVisualColumn(doc, dotPos);
+ } else {
+ ind += Utilities.getRowIndent(doc, dotPos);
+ }
+ ind = Math.max(ind, 0);
+ changeRowIndent(doc, dotPos, ind);
+ }
}
diff --git a/editor.lib/src/org/netbeans/editor/Utilities.java b/editor.lib/src/org/netbeans/editor/Utilities.java
--- a/editor.lib/src/org/netbeans/editor/Utilities.java
+++ b/editor.lib/src/org/netbeans/editor/Utilities.java
@@ -58,6 +58,7 @@
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.prefs.Preferences;
import javax.swing.SwingUtilities;
import javax.swing.Action;
import javax.swing.InputMap;
@@ -79,12 +80,17 @@
import javax.swing.plaf.TextUI;
import javax.swing.text.AbstractDocument;
import javax.swing.text.Element;
+import javax.swing.text.Position;
import javax.swing.text.View;
import org.netbeans.api.editor.EditorRegistry;
import org.netbeans.api.editor.mimelookup.MimeLookup;
+import org.netbeans.api.editor.settings.SimpleValueNames;
import org.netbeans.lib.editor.util.CharSequenceUtilities;
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
+import org.netbeans.modules.editor.indent.api.Reformat;
+import org.netbeans.modules.editor.indent.spi.CodeStylePreferences;
import org.netbeans.modules.editor.lib.drawing.DrawEngineDocView;
+import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
import org.netbeans.modules.editor.lib2.highlighting.HighlightingManager;
import org.netbeans.modules.editor.lib2.view.DocumentView;
@@ -984,26 +990,29 @@
* @param endOffset offset at which the formatting ends
* @return length of the reformatted code
*/
- public static int reformat (final BaseDocument doc, final int startOffset, final int endOffset)
- throws BadLocationException {
- final Formatter formatter = doc.getFormatter();
- formatter.reformatLock();
+ public static int reformat (final BaseDocument doc, final int startOffset, final int endOffset) throws BadLocationException {
+ final Reformat formatter = Reformat.get(doc);
+ formatter.lock();
try {
- final Object[] result = new Object [1];
- doc.runAtomicAsUser (new Runnable () {
- public @Override void run () {
+ final Object[] result = new Object[1];
+ doc.runAtomicAsUser(new Runnable() {
+ public @Override void run() {
try {
- result [0] = formatter.reformat (doc, startOffset, endOffset);
+ Position endPos = doc.createPosition(endOffset);
+ formatter.reformat(startOffset, endOffset);
+ result[0] = Math.max(endPos.getOffset() - startOffset, 0);
} catch (BadLocationException ex) {
- result [0] = ex;
+ result[0] = ex;
}
}
});
- if (result [0] instanceof BadLocationException)
- throw (BadLocationException) result [0];
- return (Integer) result [0];
+ if (result[0] instanceof BadLocationException) {
+ throw (BadLocationException) result[0];
+ } else {
+ return (Integer) result[0];
+ }
} finally {
- formatter.reformatUnlock();
+ formatter.unlock();
}
}
@@ -1043,10 +1052,10 @@
public static String getTabInsertString(BaseDocument doc, int offset)
throws BadLocationException {
int col = getVisualColumn(doc, offset);
- Formatter f = doc.getFormatter();
- boolean expandTabs = f.expandTabs();
+ Preferences prefs = CodeStylePreferences.get(doc).getPreferences();
+ boolean expandTabs = prefs.getBoolean(SimpleValueNames.EXPAND_TABS, EditorPreferencesDefaults.defaultExpandTabs);
if (expandTabs) {
- int spacesPerTab = f.getSpacesPerTab();
+ int spacesPerTab = prefs.getInt(SimpleValueNames.SPACES_PER_TAB, EditorPreferencesDefaults.defaultSpacesPerTab);
int len = (col + spacesPerTab) / spacesPerTab * spacesPerTab - col;
return new String(Analyzer.getSpacesBuffer(len), 0, len);
} else { // insert pure tab
@@ -1062,7 +1071,8 @@
public static int getNextTabColumn(BaseDocument doc, int offset)
throws BadLocationException {
int col = getVisualColumn(doc, offset);
- int tabSize = doc.getFormatter().getSpacesPerTab();
+ Preferences prefs = CodeStylePreferences.get(doc).getPreferences();
+ int tabSize = prefs.getInt(SimpleValueNames.SPACES_PER_TAB, EditorPreferencesDefaults.defaultSpacesPerTab);
return (col + tabSize) / tabSize * tabSize;
}
diff --git a/editor.lib/src/org/netbeans/editor/ext/ExtKit.java b/editor.lib/src/org/netbeans/editor/ext/ExtKit.java
--- a/editor.lib/src/org/netbeans/editor/ext/ExtKit.java
+++ b/editor.lib/src/org/netbeans/editor/ext/ExtKit.java
@@ -46,7 +46,6 @@
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.prefs.Preferences;
@@ -67,7 +66,6 @@
import org.netbeans.editor.Utilities;
import org.netbeans.editor.BaseDocument;
import org.netbeans.editor.SyntaxSupport;
-import org.netbeans.editor.Formatter;
import org.netbeans.lib.editor.util.CharSequenceUtilities;
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
import org.netbeans.modules.editor.lib.NavigationHistory;
@@ -370,7 +368,7 @@
protected final void debugPopupMenuItem(JMenuItem item, Action action) {
if (debugPopupMenu) {
- StringBuffer sb = new StringBuffer("POPUP: "); // NOI18N
+ StringBuilder sb = new StringBuilder("POPUP: "); // NOI18N
if (item != null) {
sb.append('"'); //NOI18N
sb.append(item.getText());
@@ -1043,7 +1041,10 @@
}
- // Completion customized actions
+ /**
+ * @deprecated Please do not subclass this class. Use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
// @EditorActionRegistration(
// name = defaultKeyTypedAction,
// shortDescription = editorBundleHash + defaultKeyTypedAction
@@ -1081,33 +1082,18 @@
}
}
- /** Check the characters that should cause reindenting the line. */
+ // --------------------------------------------------------------------
+ // SPI
+ // --------------------------------------------------------------------
+
+ /**
+ * Check the characters that should cause reindenting the line.
+ *
+ * @deprecated Please use AutomatedIndentig
+ * or Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
protected void checkIndentHotChars(JTextComponent target, String typedText) {
- BaseDocument doc = Utilities.getDocument(target);
- if (doc != null) {
- Caret caret = target.getCaret();
- Formatter f = doc.getFormatter();
- if (f instanceof ExtFormatter) {
- ExtFormatter ef = (ExtFormatter)f;
- int[] fmtBlk = ef.getReformatBlock(target, typedText);
-
- if (fmtBlk != null) {
- try {
- fmtBlk[0] = Utilities.getRowStart(doc, fmtBlk[0]);
- fmtBlk[1] = Utilities.getRowEnd(doc, fmtBlk[1]);
-
- //this was the of #18922, that causes the bug #20198
- //ef.reformat(doc, fmtBlk[0], fmtBlk[1]);
-
- //bugfix of the bug #20198. Bug #18922 is fixed too as well as #6968
- ef.reformat(doc, fmtBlk[0], fmtBlk[1], true);
-
- } catch (BadLocationException e) {
- } catch (IOException e) {
- }
- }
- }
- }
}
@@ -1117,37 +1103,6 @@
* Editor Code Completion.
*/
protected void checkCompletion(JTextComponent target, String typedText) {
-// XXX: remove
-// Completion completion = ExtUtilities.getCompletion(target);
-//
-// BaseDocument doc = (BaseDocument)target.getDocument();
-// ExtSyntaxSupport extSup = (ExtSyntaxSupport)doc.getSyntaxSupport();
-//
-// if (completion != null && typedText.length() > 0) {
-// if( !completion.isPaneVisible() ) {
-// if (completion.isAutoPopupEnabled()) {
-// int result = extSup.checkCompletion( target, typedText, false );
-// if ( result == ExtSyntaxSupport.COMPLETION_POPUP ) {
-// completion.popup(true);
-// } else if ( result == ExtSyntaxSupport.COMPLETION_CANCEL ) {
-// completion.cancelRequest();
-// }
-// }
-// } else {
-// int result = extSup.checkCompletion( target, typedText, true );
-// switch( result ) {
-// case ExtSyntaxSupport.COMPLETION_HIDE:
-// completion.setPaneVisible(false);
-// break;
-// case ExtSyntaxSupport.COMPLETION_REFRESH:
-// completion.refresh(false);
-// break;
-// case ExtSyntaxSupport.COMPLETION_POST_REFRESH:
-// completion.refresh(true);
-// break;
-// }
-// }
-// }
}
}
@@ -1225,6 +1180,10 @@
}
+ /**
+ * @deprecated Please do not subclass this class. Use Typing Hooks instead, for details see
+ * Editor Library 2.
+ */
public static class ExtDeleteCharAction extends DeleteCharAction {
public ExtDeleteCharAction(String nm, boolean nextChar) {
diff --git a/editor.lib/src/org/netbeans/modules/editor/lib/FormatterOverride.java b/editor.lib/src/org/netbeans/modules/editor/lib/FormatterOverride.java
deleted file mode 100644
--- a/editor.lib/src/org/netbeans/modules/editor/lib/FormatterOverride.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
- *
- * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
- * Other names may be trademarks of their respective owners.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common
- * Development and Distribution License("CDDL") (collectively, the
- * "License"). You may not use this file except in compliance with the
- * License. You can obtain a copy of the License at
- * http://www.netbeans.org/cddl-gplv2.html
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
- * specific language governing permissions and limitations under the
- * License. When distributing the software, include this License Header
- * Notice in each file and include the License file at
- * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the GPL Version 2 section of the License file that
- * accompanied this code. If applicable, add the following below the
- * License Header, with the fields enclosed by brackets [] replaced by
- * your own identifying information:
- * "Portions Copyrighted [year] [name of copyright owner]"
- *
- * Contributor(s):
- *
- * The Original Software is NetBeans. The Initial Developer of the Original
- * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
- * Microsystems, Inc. All Rights Reserved.
- *
- * If you wish your version of this file to be governed by only the CDDL
- * or only the GPL Version 2, indicate your decision by adding
- * "[Contributor] elects to include this software in this distribution
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
- * single choice of license, a recipient has the option to distribute
- * your version of this file under either the CDDL, the GPL Version 2 or
- * to extend the choice of license to its licensees as provided above.
- * However, if you add GPL Version 2 code and therefore, elected the GPL
- * Version 2 license, then the option applies only if the new code is
- * made subject to such option by the copyright holder.
- */
-
-package org.netbeans.modules.editor.lib;
-
-import javax.swing.text.Document;
-import org.netbeans.editor.Formatter;
-
-/**
- * Class to be searched in lookup that can override a formatter for the given document.
- *
- * It is a private contract between editor/lib and editor/indent.
- *
- * @author Miloslav Metelka
- */
-public interface FormatterOverride {
-
- /**
- * Possibly override the default formatter used for the given document.
- *
- * @param doc non-null document for which the formatter is being searched.
- * @param defaultFormatter default formatter found by the infrastructure
- * or null if there is none.
- * @return overriden formatter or the default formatter passed as the argument.
- */
- Formatter getFormatter(Document doc, Formatter defaultFormatter);
-
-}
diff --git a/editor.lib2/apichanges.xml b/editor.lib2/apichanges.xml
--- a/editor.lib2/apichanges.xml
+++ b/editor.lib2/apichanges.xml
@@ -107,6 +107,21 @@
+
+ Typing Hooks SPI added
+
+
+
+
+
+ Typing Hooks SPI allows interception of various key typed events
+ that are processed in the editor. The SPI is a replacement for
+ subclassing editor actions such as DefaultKeyTypedAction,
+ InsertBreakAction, etc.
+
+
+
+
Adding line/column based dialog bindings
diff --git a/editor.lib2/arch.xml b/editor.lib2/arch.xml
--- a/editor.lib2/arch.xml
+++ b/editor.lib2/arch.xml
@@ -80,8 +80,14 @@
+ Code Generator SPI
+
+
Highlighting SPI
+
+ Typing Hooks SPI
+
@@ -120,9 +126,19 @@
-->
- At the moment the Editor Library 2 module contains only the Highlighting SPI,
- which use cases can be found in the org.netbeans.spi.editor.highlighting package
- overview.
+ At the moment the Editor Library 2 module contains three distinct SPIs. Each SPI lives
+ in its own package and the usecases can be found in the packages overview.
+
diff --git a/editor.lib2/manifest.mf b/editor.lib2/manifest.mf
--- a/editor.lib2/manifest.mf
+++ b/editor.lib2/manifest.mf
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.modules.editor.lib2/1
-OpenIDE-Module-Implementation-Version: 2
+OpenIDE-Module-Implementation-Version: 3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/lib2/Bundle.properties
OpenIDE-Module-Layer: org/netbeans/modules/editor/lib2/resources/layer.xml
OpenIDE-Module-Needs: org.netbeans.modules.editor.actions
diff --git a/editor.lib2/nbproject/project.properties b/editor.lib2/nbproject/project.properties
--- a/editor.lib2/nbproject/project.properties
+++ b/editor.lib2/nbproject/project.properties
@@ -43,7 +43,7 @@
is.autoload=true
javac.source=1.6
javac.compilerargs=-Xlint:unchecked
-spec.version.base=1.30.0
+spec.version.base=1.31.0
javadoc.arch=${basedir}/arch.xml
javadoc.apichanges=${basedir}/apichanges.xml
diff --git a/editor.lib2/nbproject/project.xml b/editor.lib2/nbproject/project.xml
--- a/editor.lib2/nbproject/project.xml
+++ b/editor.lib2/nbproject/project.xml
@@ -181,6 +181,7 @@
org.netbeans.spi.editor.codegenorg.netbeans.spi.editor.highlightingorg.netbeans.spi.editor.highlighting.support
+ org.netbeans.spi.editor.typinghooks
diff --git a/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/DeletedTextInterceptorsManager.java b/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/DeletedTextInterceptorsManager.java
new file mode 100644
--- /dev/null
+++ b/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/DeletedTextInterceptorsManager.java
@@ -0,0 +1,215 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2010 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.editor.lib2.typinghooks;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import org.netbeans.api.editor.mimelookup.MimeLookup;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.api.lexer.TokenHierarchy;
+import org.netbeans.api.lexer.TokenSequence;
+import org.netbeans.lib.editor.util.swing.DocumentUtilities;
+import org.netbeans.spi.editor.typinghooks.DeletedTextInterceptor;
+
+/**
+ *
+ * @author vita
+ */
+public final class DeletedTextInterceptorsManager {
+
+ public static DeletedTextInterceptorsManager getInstance() {
+ if (instance == null) {
+ instance = new DeletedTextInterceptorsManager();
+ }
+ return instance;
+ }
+
+ public Transaction openTransaction(JTextComponent c, int offset, String removedText, boolean backwardDelete) {
+ synchronized (this) {
+ if (transaction == null) {
+ transaction = new Transaction(c, offset, removedText, backwardDelete);
+ return transaction;
+ } else {
+ throw new IllegalStateException("Too many transactions; only one at a time is allowed!"); //NOI18N
+ }
+ }
+ }
+
+ public final class Transaction {
+
+ public boolean beforeRemove() {
+ for(DeletedTextInterceptor i : interceptors) {
+ try {
+ if (i.beforeRemove(context)) {
+ return true;
+ }
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "DeletedTextInterceptor crashed in beforeRemove(): " + i, e); //NOI18N
+ }
+ }
+
+ phase++;
+ return false;
+ }
+
+ public void textDeleted() {
+ Object [] data = null;
+
+ for(DeletedTextInterceptor i : interceptors) {
+ try {
+ i.remove(context);
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "DeletedTextInterceptor crashed in remove(): " + i, e); //NOI18N
+ continue;
+ }
+ }
+
+ phase++;
+ }
+
+ public void afterRemove() {
+ for(DeletedTextInterceptor i : interceptors) {
+ try {
+ i.afterRemove(context);
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "DeletedTextInterceptor crashed in afterRemove(): " + i, e); //NOI18N
+ }
+ }
+
+ phase++;
+ }
+
+ public void close() {
+ if (phase < 3) {
+ for(DeletedTextInterceptor i : interceptors) {
+ try {
+ i.cancelled(context);
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "DeletedTextInterceptor crashed in cancelled(): " + i, e); //NOI18N
+ }
+ }
+ }
+
+ synchronized (DeletedTextInterceptorsManager.this) {
+ transaction = null;
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Private implementation
+ // ------------------------------------------------------------------------
+
+ private final DeletedTextInterceptor.Context context;
+ private final Collection extends DeletedTextInterceptor> interceptors;
+ private int phase = 0;
+
+ private Transaction(JTextComponent c, int offset, String removedText, boolean backwardDelete) {
+ this.context = TypingHooksSpiAccessor.get().createDtiContext(c, offset, removedText, backwardDelete);
+ this.interceptors = getInterceptors(c.getDocument(), offset);
+ }
+ } // End of Transaction class
+
+ // ------------------------------------------------------------------------
+ // Private implementation
+ // ------------------------------------------------------------------------
+
+ private static final Logger LOG = Logger.getLogger(DeletedTextInterceptorsManager.class.getName());
+
+ private static DeletedTextInterceptorsManager instance;
+
+ private Transaction transaction = null;
+ private final Map>> cache = new WeakHashMap>>();
+
+ private DeletedTextInterceptorsManager() {
+
+ }
+
+ // XXX: listne on changes in MimeLookup
+ private Collection extends DeletedTextInterceptor> getInterceptors(Document doc, int offset) {
+ List> seqs = TokenHierarchy.get(doc).embeddedTokenSequences(offset, true);
+ TokenSequence> seq = seqs.isEmpty() ? null : seqs.get(seqs.size() - 1);
+ MimePath mimePath = seq == null ? MimePath.parse(DocumentUtilities.getMimeType(doc)) : MimePath.parse(seq.languagePath().mimePath());
+
+ synchronized (cache) {
+ Reference> ref = cache.get(mimePath);
+ Collection interceptors = ref == null ? null : ref.get();
+
+ if (interceptors == null) {
+ Collection extends DeletedTextInterceptor.Factory> factories = MimeLookup.getLookup(mimePath).lookupAll(DeletedTextInterceptor.Factory.class);
+ interceptors = new HashSet(factories.size());
+
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.log(Level.FINE, "DeletedTextInterceptor.Factory instances for {0} {" , mimePath.getPath()); //NOI18N
+ }
+
+ for(DeletedTextInterceptor.Factory f : factories) {
+ DeletedTextInterceptor interceptor = f.createDeletedTextInterceptor(mimePath);
+ if (interceptor != null) {
+ interceptors.add(interceptor);
+ }
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.log(Level.FINE, "{0} created: {1}", new Object[] { f, interceptor }); //NOI18N
+ }
+ }
+
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.fine("}"); //NOI18N
+ }
+
+ // XXX: this should really be a timed WeakReference
+ cache.put(mimePath, new SoftReference>(interceptors));
+ }
+
+ return interceptors;
+ }
+ }
+}
diff --git a/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/TypedBreakInterceptorsManager.java b/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/TypedBreakInterceptorsManager.java
new file mode 100644
--- /dev/null
+++ b/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/TypedBreakInterceptorsManager.java
@@ -0,0 +1,226 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2010 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.editor.lib2.typinghooks;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import org.netbeans.api.editor.mimelookup.MimeLookup;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.api.lexer.TokenHierarchy;
+import org.netbeans.api.lexer.TokenSequence;
+import org.netbeans.lib.editor.util.swing.DocumentUtilities;
+import org.netbeans.spi.editor.typinghooks.TypedBreakInterceptor;
+
+/**
+ *
+ * @author Vita Stejskal
+ */
+public final class TypedBreakInterceptorsManager {
+
+ public static TypedBreakInterceptorsManager getInstance() {
+ if (instance == null) {
+ instance = new TypedBreakInterceptorsManager();
+ }
+ return instance;
+ }
+
+ public Transaction openTransaction(JTextComponent c, int caretOffset, int insertBreakOffset) {
+ synchronized (this) {
+ if (transaction == null) {
+ transaction = new Transaction(c, caretOffset, insertBreakOffset);
+ return transaction;
+ } else {
+ throw new IllegalStateException("Too many transactions; only one at a time is allowed!"); //NOI18N
+ }
+ }
+ }
+
+ public final class Transaction {
+
+ public boolean beforeInsertion() {
+ for(TypedBreakInterceptor i : interceptors) {
+ try {
+ if (i.beforeInsert(context)) {
+ return true;
+ }
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "TypedBreakInterceptor crashed in beforeInsert(): " + i, e); //NOI18N
+ }
+ }
+
+ phase++;
+ return false;
+ }
+
+ /**
+ *
+ * @return [0] == insertionText, [1] == new caret position (!) within [0]
+ */
+ public Object [] textTyped() {
+ Object [] data = null;
+
+ for(TypedBreakInterceptor i : interceptors) {
+ try {
+ i.insert(context);
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "TypedBreakInterceptor crashed in insert(): " + i, e); //NOI18N
+ TypingHooksSpiAccessor.get().resetTbiContextData(context);
+ continue;
+ }
+
+ data = TypingHooksSpiAccessor.get().getTbiContextData(context);
+ if (data != null) {
+ break;
+ }
+ }
+
+ phase++;
+ return data;
+ }
+
+ public void afterInsertion() {
+ for(TypedBreakInterceptor i : interceptors) {
+ try {
+ i.afterInsert(context);
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "TypedBreakInterceptor crashed in afterInsert(): " + i, e); //NOI18N
+ }
+ }
+
+ phase++;
+ }
+
+ public void close() {
+ if (phase < 3) {
+ for(TypedBreakInterceptor i : interceptors) {
+ try {
+ i.cancelled(context);
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "TypedBreakInterceptor crashed in cancelled(): " + i, e); //NOI18N
+ }
+ }
+ }
+
+ synchronized (TypedBreakInterceptorsManager.this) {
+ transaction = null;
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Private implementation
+ // ------------------------------------------------------------------------
+
+ private final TypedBreakInterceptor.MutableContext context;
+ private final Collection extends TypedBreakInterceptor> interceptors;
+ private int phase = 0;
+
+ private Transaction(JTextComponent c, int caretOffset, int insertBreakOffset) {
+ this.context = TypingHooksSpiAccessor.get().createTbiContext(c, caretOffset, insertBreakOffset);
+ this.interceptors = getInterceptors(c.getDocument(), insertBreakOffset);
+ }
+ } // End of Transaction class
+
+ // ------------------------------------------------------------------------
+ // Private implementation
+ // ------------------------------------------------------------------------
+
+ private static final Logger LOG = Logger.getLogger(TypedBreakInterceptorsManager.class.getName());
+
+ private static TypedBreakInterceptorsManager instance;
+
+ private Transaction transaction = null;
+ private final Map>> cache = new WeakHashMap>>();
+
+ private TypedBreakInterceptorsManager() {
+
+ }
+
+ // XXX: listne on changes in MimeLookup
+ private Collection extends TypedBreakInterceptor> getInterceptors(Document doc, int offset) {
+ List> seqs = TokenHierarchy.get(doc).embeddedTokenSequences(offset, true);
+ TokenSequence> seq = seqs.isEmpty() ? null : seqs.get(seqs.size() - 1);
+ MimePath mimePath = seq == null ? MimePath.parse(DocumentUtilities.getMimeType(doc)) : MimePath.parse(seq.languagePath().mimePath());
+
+ synchronized (cache) {
+ Reference> ref = cache.get(mimePath);
+ Collection interceptors = ref == null ? null : ref.get();
+
+ if (interceptors == null) {
+ Collection extends TypedBreakInterceptor.Factory> factories = MimeLookup.getLookup(mimePath).lookupAll(TypedBreakInterceptor.Factory.class);
+ interceptors = new HashSet(factories.size());
+
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.log(Level.FINE, "TypedBreakInterceptor.Factory instances for {0} {" , mimePath.getPath()); //NOI18N
+ }
+
+ for(TypedBreakInterceptor.Factory f : factories) {
+ TypedBreakInterceptor interceptor = f.createTypedBreakInterceptor(mimePath);
+ if (interceptor != null) {
+ interceptors.add(interceptor);
+ }
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.log(Level.FINE, "{0} created: {1}", new Object[] { f, interceptor }); //NOI18N
+ }
+ }
+
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.fine("}"); //NOI18N
+ }
+
+ // XXX: this should really be a timed WeakReference
+ cache.put(mimePath, new SoftReference>(interceptors));
+ }
+
+ return interceptors;
+ }
+ }
+}
diff --git a/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/TypedTextInterceptorsManager.java b/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/TypedTextInterceptorsManager.java
new file mode 100644
--- /dev/null
+++ b/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/TypedTextInterceptorsManager.java
@@ -0,0 +1,223 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2008 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.editor.lib2.typinghooks;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import org.netbeans.api.editor.mimelookup.MimeLookup;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.api.lexer.TokenHierarchy;
+import org.netbeans.api.lexer.TokenSequence;
+import org.netbeans.lib.editor.util.swing.DocumentUtilities;
+import org.netbeans.spi.editor.typinghooks.TypedTextInterceptor;
+
+/**
+ *
+ * @author vita
+ */
+public final class TypedTextInterceptorsManager {
+
+ public static TypedTextInterceptorsManager getInstance() {
+ if (instance == null) {
+ instance = new TypedTextInterceptorsManager();
+ }
+ return instance;
+ }
+
+ public Transaction openTransaction(JTextComponent c, int offset, String typedText) {
+ synchronized (this) {
+ if (transaction == null) {
+ transaction = new Transaction(c, offset, typedText);
+ return transaction;
+ } else {
+ throw new IllegalStateException("Too many transactions; only one at a time is allowed!"); //NOI18N
+ }
+ }
+ }
+
+ public final class Transaction {
+
+ public boolean beforeInsertion() {
+ for(TypedTextInterceptor i : interceptors) {
+ try {
+ if (i.beforeInsert(context)) {
+ return true;
+ }
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "TypedTextInterceptor crashed in beforeInsert(): " + i, e); //NOI18N
+ }
+ }
+
+ phase++;
+ return false;
+ }
+
+ /**
+ *
+ * @return [0] == insertionText, [1] == new caret position (!) within [0]
+ */
+ public Object [] textTyped() {
+ Object [] data = null;
+
+ for(TypedTextInterceptor i : interceptors) {
+ try {
+ i.insert(context);
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "TypedTextInterceptor crashed in insert(): " + i, e); //NOI18N
+ TypingHooksSpiAccessor.get().resetTtiContextData(context);
+ continue;
+ }
+
+ data = TypingHooksSpiAccessor.get().getTtiContextData(context);
+ if (data != null) {
+ break;
+ }
+ }
+
+ phase++;
+ return data;
+ }
+
+ public void afterInsertion() {
+ for(TypedTextInterceptor i : interceptors) {
+ try {
+ i.afterInsert(context);
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "TypedTextInterceptor crashed in afterInsert(): " + i, e); //NOI18N
+ }
+ }
+
+ phase++;
+ }
+
+ public void close() {
+ if (phase < 3) {
+ for(TypedTextInterceptor i : interceptors) {
+ try {
+ i.cancelled(context);
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "TypedTextInterceptor crashed in cancelled(): " + i, e); //NOI18N
+ }
+ }
+ }
+
+ synchronized (TypedTextInterceptorsManager.this) {
+ transaction = null;
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Private implementation
+ // ------------------------------------------------------------------------
+
+ private final TypedTextInterceptor.MutableContext context;
+ private final Collection extends TypedTextInterceptor> interceptors;
+ private int phase = 0;
+
+ private Transaction(JTextComponent c, int offset, String typedText) {
+ this.context = TypingHooksSpiAccessor.get().createTtiContext(c, offset, typedText);
+ this.interceptors = getInterceptors(c.getDocument(), offset);
+ }
+ } // End of Transaction class
+
+ // ------------------------------------------------------------------------
+ // Private implementation
+ // ------------------------------------------------------------------------
+
+ private static final Logger LOG = Logger.getLogger(TypedTextInterceptorsManager.class.getName());
+
+ private static TypedTextInterceptorsManager instance;
+
+ private Transaction transaction = null;
+ private final Map>> cache = new WeakHashMap>>();
+
+ private TypedTextInterceptorsManager() {
+
+ }
+
+ // XXX: listne on changes in MimeLookup
+ private Collection extends TypedTextInterceptor> getInterceptors(Document doc, int offset) {
+ List> seqs = TokenHierarchy.get(doc).embeddedTokenSequences(offset, true);
+ TokenSequence> seq = seqs.isEmpty() ? null : seqs.get(seqs.size() - 1);
+ MimePath mimePath = seq == null ? MimePath.parse(DocumentUtilities.getMimeType(doc)) : MimePath.parse(seq.languagePath().mimePath());
+
+ synchronized (cache) {
+ Reference> ref = cache.get(mimePath);
+ Collection interceptors = ref == null ? null : ref.get();
+
+ if (interceptors == null) {
+ Collection extends TypedTextInterceptor.Factory> factories = MimeLookup.getLookup(mimePath).lookupAll(TypedTextInterceptor.Factory.class);
+ interceptors = new HashSet(factories.size());
+
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.log(Level.FINE, "TypedTextInterceptor.Factory instances for {0} {" , mimePath.getPath()); //NOI18N
+ }
+
+ for(TypedTextInterceptor.Factory f : factories) {
+ TypedTextInterceptor interceptor = f.createTypedTextInterceptor(mimePath);
+ if (interceptor != null) {
+ interceptors.add(interceptor);
+ }
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.log(Level.FINE, "{0} created: {1}", new Object[] { f, interceptor }); //NOI18N
+ }
+ }
+
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.fine("}"); //NOI18N
+ }
+
+ // XXX: this should really be a timed WeakReference
+ cache.put(mimePath, new SoftReference>(interceptors));
+ }
+
+ return interceptors;
+ }
+ }
+}
diff --git a/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/TypingHooksSpiAccessor.java b/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/TypingHooksSpiAccessor.java
new file mode 100644
--- /dev/null
+++ b/editor.lib2/src/org/netbeans/modules/editor/lib2/typinghooks/TypingHooksSpiAccessor.java
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2008 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.editor.lib2.typinghooks;
+
+import javax.swing.text.JTextComponent;
+import org.netbeans.spi.editor.typinghooks.DeletedTextInterceptor;
+import org.netbeans.spi.editor.typinghooks.TypedBreakInterceptor;
+import org.netbeans.spi.editor.typinghooks.TypedTextInterceptor;
+
+/**
+ *
+ * @author vita
+ */
+public abstract class TypingHooksSpiAccessor {
+
+ private static TypingHooksSpiAccessor ACCESSOR = null;
+
+ public static synchronized void register(TypingHooksSpiAccessor accessor) {
+ assert ACCESSOR == null : "Can't register two package accessors!"; //NOI18N
+ ACCESSOR = accessor;
+ }
+
+ public static synchronized TypingHooksSpiAccessor get() {
+ // Trying to wake up HighlightsLayer ...
+ try {
+ Class clazz = Class.forName(TypedTextInterceptor.MutableContext.class.getName());
+ } catch (ClassNotFoundException e) {
+ // ignore
+ }
+
+ assert ACCESSOR != null : "There is no package accessor available!"; //NOI18N
+ return ACCESSOR;
+ }
+
+ /** Creates a new instance of HighlightingSpiPackageAccessor */
+ protected TypingHooksSpiAccessor() {
+ }
+
+ public abstract TypedTextInterceptor.MutableContext createTtiContext(JTextComponent c, int offset, String typedText);
+ public abstract Object [] getTtiContextData(TypedTextInterceptor.MutableContext context);
+ public abstract void resetTtiContextData(TypedTextInterceptor.MutableContext context);
+
+ public abstract DeletedTextInterceptor.Context createDtiContext(JTextComponent c, int offset, String removedText, boolean backwardDelete);
+
+ public abstract TypedBreakInterceptor.MutableContext createTbiContext(JTextComponent c, int caretOffset, int insertBreakOffset);
+ public abstract Object [] getTbiContextData(TypedBreakInterceptor.MutableContext context);
+ public abstract void resetTbiContextData(TypedBreakInterceptor.MutableContext context);
+}
diff --git a/editor.lib2/src/org/netbeans/spi/editor/codegen/package.html b/editor.lib2/src/org/netbeans/spi/editor/codegen/package.html
--- a/editor.lib2/src/org/netbeans/spi/editor/codegen/package.html
+++ b/editor.lib2/src/org/netbeans/spi/editor/codegen/package.html
@@ -143,6 +143,10 @@
with the additional data and runs the task obtained as the parameter with the newly
created context.