1.1 --- a/editor.completion/nbproject/project.properties Mon Feb 22 10:33:12 2016 +0100
1.2 +++ b/editor.completion/nbproject/project.properties Mon Feb 22 10:54:11 2016 +0100
1.3 @@ -44,4 +44,4 @@
1.4 javac.source=1.7
1.5 javadoc.arch=${basedir}/arch.xml
1.6 javadoc.apichanges=${basedir}/apichanges.xml
1.7 -spec.version.base=1.44.0
1.8 +spec.version.base=1.45.0
2.1 --- a/editor.completion/nbproject/project.xml Mon Feb 22 10:33:12 2016 +0100
2.2 +++ b/editor.completion/nbproject/project.xml Mon Feb 22 10:54:11 2016 +0100
2.3 @@ -112,6 +112,15 @@
2.4 </run-dependency>
2.5 </dependency>
2.6 <dependency>
2.7 + <code-name-base>org.netbeans.modules.lexer</code-name-base>
2.8 + <build-prerequisite/>
2.9 + <compile-dependency/>
2.10 + <run-dependency>
2.11 + <release-version>2</release-version>
2.12 + <specification-version>1.63</specification-version>
2.13 + </run-dependency>
2.14 + </dependency>
2.15 + <dependency>
2.16 <code-name-base>org.netbeans.modules.sampler</code-name-base>
2.17 <build-prerequisite/>
2.18 <compile-dependency/>
3.1 --- a/editor.completion/src/org/netbeans/modules/editor/completion/CompletionImpl.java Mon Feb 22 10:33:12 2016 +0100
3.2 +++ b/editor.completion/src/org/netbeans/modules/editor/completion/CompletionImpl.java Mon Feb 22 10:54:11 2016 +0100
3.3 @@ -75,6 +75,8 @@
3.4 import org.netbeans.api.editor.mimelookup.MimeLookup;
3.5 import org.netbeans.api.editor.mimelookup.MimePath;
3.6 import org.netbeans.api.editor.settings.KeyBindingSettings;
3.7 +import org.netbeans.api.lexer.TokenHierarchy;
3.8 +import org.netbeans.api.lexer.TokenSequence;
3.9 import org.netbeans.editor.BaseDocument;
3.10 import org.netbeans.editor.BaseKit;
3.11 import org.netbeans.editor.GuardedDocument;
3.12 @@ -189,7 +191,7 @@
3.13 /* Completion providers registered for the active component (its mime-type). Changed in AWT only. */
3.14 private CompletionProvider[] activeProviders = null;
3.15
3.16 - /** Mapping of mime-type to array of providers. Changed in AWT only. */
3.17 + /** Mapping of mime-path to array of providers. Changed in AWT only. */
3.18 private HashMap<String, CompletionProvider[]> providersCache = new HashMap<String, CompletionProvider[]>();
3.19
3.20 /**
3.21 @@ -539,8 +541,15 @@
3.22 }
3.23
3.24 private boolean ensureActiveProviders() {
3.25 - if (activeProviders != null)
3.26 - return true;
3.27 + if (activeProviders != null) {
3.28 + String mime = getMimePath(getActiveComponent());
3.29 + if (mime == null) {
3.30 + return false;
3.31 + }
3.32 + if (mime.equals(currentMimePath)) {
3.33 + return true;
3.34 + }
3.35 + }
3.36 JTextComponent component = getActiveComponent();
3.37 activeProviders = (component != null)
3.38 ? getCompletionProvidersForComponent(component, false)
3.39 @@ -577,32 +586,128 @@
3.40 docAutoPopupTimer.restart();
3.41 }
3.42
3.43 + /**
3.44 + * Gives MimePath of the caret position as String
3.45 + * @param component
3.46 + * @return
3.47 + */
3.48 + private String getMimePath(JTextComponent component) {
3.49 + final int offset = component.getCaretPosition();
3.50 + final MimePath[] mimePathR = new MimePath[1];
3.51 + final Document doc = component.getDocument();
3.52 +
3.53 + doc.render(new Runnable() {
3.54 + @Override
3.55 + public void run() {
3.56 + List<TokenSequence<?>> seqs = TokenHierarchy.get(doc).embeddedTokenSequences(offset, true);
3.57 + TokenSequence<?> seq;
3.58 +
3.59 + if (seqs.isEmpty()) {
3.60 + seq = TokenHierarchy.get(doc).tokenSequence();
3.61 + } else {
3.62 + seq = seqs.get(seqs.size() - 1);
3.63 + }
3.64 +
3.65 + if (seq != null) {
3.66 + mimePathR[0] = MimePath.parse(seq.languagePath().mimePath());
3.67 + }
3.68 + }
3.69 + });
3.70 + if (mimePathR[0] != null) {
3.71 + return mimePathR[0].getPath();
3.72 + }
3.73 + // original mimeType code
3.74 + Object mimeTypeObj = DocumentUtilities.getMimeType(doc); //NOI18N
3.75 + String mimeType;
3.76 +
3.77 + if (mimeTypeObj instanceof String) {
3.78 + mimeType = (String) mimeTypeObj;
3.79 + } else {
3.80 + BaseKit kit = Utilities.getKit(component);
3.81 +
3.82 + if (kit == null) {
3.83 + return null;
3.84 + }
3.85 +
3.86 + mimeType = kit.getContentType();
3.87 + }
3.88 + return mimeType;
3.89 + }
3.90 +
3.91 + private String currentMimePath;
3.92 +
3.93 + /**
3.94 + * Gets a complete MIME path for the given offset in the document
3.95 + * @param doc the document
3.96 + * @param offset point of interest
3.97 + * @return MimePath
3.98 + */
3.99 + static MimePath getMimePath(final Document doc, final int offset) {
3.100 + final MimePath[] mimePathR = new MimePath[1];
3.101 + doc.render(new Runnable() {
3.102 + @Override
3.103 + public void run() {
3.104 + List<TokenSequence<?>> seqs = TokenHierarchy.get(doc).embeddedTokenSequences(offset, true);
3.105 + TokenSequence<?> seq = seqs.isEmpty() ? null : seqs.get(seqs.size() - 1);
3.106 + seq = seq == null ? TokenHierarchy.get(doc).tokenSequence() : seq;
3.107 + mimePathR[0] = seq == null ? MimePath.parse(DocumentUtilities.getMimeType(doc)) : MimePath.parse(seq.languagePath().mimePath());
3.108 + }
3.109 + });
3.110 + return mimePathR[0];
3.111 + }
3.112 +
3.113 + /**
3.114 + * Gives MimeType
3.115 + * @param component
3.116 + * @return
3.117 + */
3.118 + private String getMimeType(JTextComponent component) {
3.119 + MimePath path = getMimePath(component.getDocument(), component.getCaretPosition());
3.120 + Object mimeTypeObj = component.getDocument().getProperty("mimeType"); //NOI18N
3.121 + String mimeType;
3.122 +
3.123 + if (path != null) {
3.124 + mimeType = path.getPath();
3.125 + } else if (mimeTypeObj instanceof String) {
3.126 + mimeType = (String) mimeTypeObj;
3.127 + } else {
3.128 + BaseKit kit = Utilities.getKit(component);
3.129 +
3.130 + if (kit == null) {
3.131 + return null;
3.132 + }
3.133 +
3.134 + mimeType = kit.getContentType();
3.135 + }
3.136 + return mimeType;
3.137 + }
3.138 +
3.139 + private String currentMimeType;
3.140 +
3.141 + /**
3.142 + * Has side effects !
3.143 + * @param component
3.144 + * @param asyncWarmUp
3.145 + * @return
3.146 + */
3.147 private CompletionProvider[] getCompletionProvidersForComponent(JTextComponent component, boolean asyncWarmUp) {
3.148 assert (SwingUtilities.isEventDispatchThread());
3.149
3.150 if (component == null)
3.151 return null;
3.152
3.153 - Object mimeTypeObj = component.getDocument().getProperty("mimeType"); //NOI18N
3.154 - String mimeType;
3.155 -
3.156 - if (mimeTypeObj instanceof String)
3.157 - mimeType = (String) mimeTypeObj;
3.158 - else {
3.159 - BaseKit kit = Utilities.getKit(component);
3.160 -
3.161 - if (kit == null) {
3.162 - return new CompletionProvider[0];
3.163 - }
3.164 -
3.165 - mimeType = kit.getContentType();
3.166 + String mimePath = getMimePath(component);
3.167 +
3.168 + if (mimePath == null) {
3.169 + return null;
3.170 }
3.171 -
3.172 - if (providersCache.containsKey(mimeType))
3.173 - return providersCache.get(mimeType);
3.174 + if (providersCache.containsKey(mimePath)) {
3.175 + currentMimePath = mimePath;
3.176 + return providersCache.get(mimePath);
3.177 + }
3.178
3.179 if (asyncWarmUpTask != null) {
3.180 - if (asyncWarmUp && mimeType != null && mimeType.equals(asyncWarmUpMimeType))
3.181 + if (asyncWarmUp && mimePath != null && mimePath.equals(asyncWarmUpMimeType))
3.182 return null;
3.183 if (!asyncWarmUpTask.cancel()) {
3.184 asyncWarmUpTask.waitFinished();
3.185 @@ -610,9 +715,9 @@
3.186 asyncWarmUpTask = null;
3.187 asyncWarmUpMimeType = null;
3.188 }
3.189 - final Lookup lookup = MimeLookup.getLookup(MimePath.get(mimeType));
3.190 + final Lookup lookup = MimeLookup.getLookup(MimePath.parse(mimePath));
3.191 if (asyncWarmUp) {
3.192 - asyncWarmUpMimeType = mimeType;
3.193 + asyncWarmUpMimeType = mimePath;
3.194 asyncWarmUpTask = RequestProcessor.getDefault().post(new Runnable() {
3.195 @Override
3.196 public void run() {
3.197 @@ -624,7 +729,8 @@
3.198 Collection<? extends CompletionProvider> col = lookup.lookupAll(CompletionProvider.class);
3.199 int size = col.size();
3.200 CompletionProvider[] ret = size == 0 ? null : col.toArray(new CompletionProvider[size]);
3.201 - providersCache.put(mimeType, ret);
3.202 + currentMimePath = mimePath;
3.203 + providersCache.put(mimePath, ret);
3.204 return ret;
3.205 }
3.206
4.1 --- a/editor.guards/apichanges.xml Mon Feb 22 10:33:12 2016 +0100
4.2 +++ b/editor.guards/apichanges.xml Mon Feb 22 10:54:11 2016 +0100
4.3 @@ -108,6 +108,18 @@
4.4 <!-- ACTUAL CHANGES BEGIN HERE: -->
4.5
4.6 <changes>
4.7 + <change id="protectRange">
4.8 + <api name="general"/>
4.9 + <summary>Allow to protect existing text</summary>
4.10 + <version major="1" minor="33"/>
4.11 + <date day="17" month="2" year="2016"/>
4.12 + <author login="sdedic"/>
4.13 + <compatibility addition="yes" binary="compatible" source="compatible"/>
4.14 + <description>
4.15 + Added method to create guarded block on top of existing text.
4.16 + </description>
4.17 + <class name="GuardedSectionManager" package="org.netbeans.api.editor.guards"/>
4.18 + </change>
4.19 <change id="DocumentGuards">
4.20 <api name="general"/>
4.21 <summary>DocumentGuards API</summary>
5.1 --- a/editor.guards/manifest.mf Mon Feb 22 10:33:12 2016 +0100
5.2 +++ b/editor.guards/manifest.mf Mon Feb 22 10:54:11 2016 +0100
5.3 @@ -1,6 +1,6 @@
5.4 Manifest-Version: 1.0
5.5 OpenIDE-Module: org.netbeans.modules.editor.guards/1
5.6 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/guards/Bundle.properties
5.7 -OpenIDE-Module-Specification-Version: 1.32
5.8 +OpenIDE-Module-Specification-Version: 1.33
5.9
5.10
6.1 --- a/editor.guards/src/org/netbeans/api/editor/guards/GuardedSectionManager.java Mon Feb 22 10:33:12 2016 +0100
6.2 +++ b/editor.guards/src/org/netbeans/api/editor/guards/GuardedSectionManager.java Mon Feb 22 10:54:11 2016 +0100
6.3 @@ -52,6 +52,7 @@
6.4 import org.netbeans.modules.editor.guards.GuardsAccessor;
6.5 import org.netbeans.modules.editor.guards.InteriorSectionImpl;
6.6 import org.netbeans.modules.editor.guards.SimpleSectionImpl;
6.7 +import org.netbeans.spi.editor.guards.GuardedEditorSupport;
6.8
6.9 /**
6.10 * This is the entry point for clients to manipulate guarded sections
6.11 @@ -109,7 +110,30 @@
6.12 throws IllegalArgumentException, BadLocationException {
6.13 return impl.createSimpleSection(pos, name);
6.14 }
6.15 -
6.16 +
6.17 + /**
6.18 + * Creates a simple section from a region of code. The code region will become
6.19 + * guarded as in the case of `initComponents' method in forms. The section name
6.20 + * can be used to find the section and if the section is persisted, will be written
6.21 + * into the output file. Unline {@link #createSimpleSection}, this method is
6.22 + * intended for marking existing text protected/guarded.
6.23 + * <p/>
6.24 + * Use {@link GuardedSection#removeSection()} to remove the protection.
6.25 + *
6.26 + * @param start start of the protected text
6.27 + * @param end end of text, exclusive.
6.28 + * @param name name for the guarded section
6.29 + * @return SimpleSection instance, to allow further manipulation with the
6.30 + * protected content.
6.31 + * @throws IllegalArgumentException
6.32 + * @throws BadLocationException
6.33 + * @since 1.33
6.34 + */
6.35 + public SimpleSection protectSimpleRegion(Position start, Position end, String name)
6.36 + throws IllegalArgumentException, BadLocationException {
6.37 + return impl.createSimpleSection(start, end, name);
6.38 + }
6.39 +
6.40 /**
6.41 * Creates an empty interior section at the given position.
6.42 * The position must not be within any existing guarded section
7.1 --- a/editor.guards/src/org/netbeans/modules/editor/guards/GuardedSectionsImpl.java Mon Feb 22 10:33:12 2016 +0100
7.2 +++ b/editor.guards/src/org/netbeans/modules/editor/guards/GuardedSectionsImpl.java Mon Feb 22 10:54:11 2016 +0100
7.3 @@ -159,10 +159,15 @@
7.4 public InteriorSection createInteriorSectionObject(String name, PositionBounds header, PositionBounds body, PositionBounds footer) {
7.5 return (InteriorSection) createInteriorSectionImpl(name, header, body, footer).guard;
7.6 }
7.7 +
7.8 + public SimpleSection createSimpleSection(Position pos, Position end, String name) throws BadLocationException {
7.9 + checkNewSection(pos, name);
7.10 + return doCreateSimpleSection(pos, end, name);
7.11 + }
7.12
7.13 public SimpleSection createSimpleSection(Position pos, String name) throws BadLocationException {
7.14 checkNewSection(pos, name);
7.15 - return doCreateSimpleSection(pos, name);
7.16 + return doCreateSimpleSection(pos, null, name);
7.17 }
7.18
7.19 public InteriorSection createInteriorSection(Position pos, String name) throws BadLocationException {
7.20 @@ -170,7 +175,7 @@
7.21 return doCreateInteriorSection(pos, name);
7.22 }
7.23
7.24 - private SimpleSection doCreateSimpleSection(final Position pos, final String name)
7.25 + private SimpleSection doCreateSimpleSection(final Position pos, final Position end, final String name)
7.26 throws /*IllegalArgumentException,*/ BadLocationException {
7.27
7.28 StyledDocument loadedDoc = null;
7.29 @@ -183,8 +188,17 @@
7.30 public void run() {
7.31 try {
7.32 int where = pos.getOffset();
7.33 - doc.insertString(where, "\n \n", null); // NOI18N
7.34 - sect[0] = createSimpleSectionImpl(name, PositionBounds.create(where + 1, where + 2, GuardedSectionsImpl.this));
7.35 + int offEnd = where +2;
7.36 + int offStart = where;
7.37 + if (end != null) {
7.38 + offEnd = end.getOffset();
7.39 + offStart = pos.getOffset();
7.40 + } else {
7.41 + offStart = where + 1;
7.42 + offEnd = where + 2;
7.43 + doc.insertString(where, "\n \n", null); // NOI18N
7.44 + }
7.45 + sect[0] = createSimpleSectionImpl(name, PositionBounds.create(offStart, offEnd, GuardedSectionsImpl.this));
7.46 sect[0].markGuarded(doc);
7.47 } catch (BadLocationException ex) {
7.48 blex[0] = ex;