mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
@@ -145,7 +145,8 @@ public abstract class LanguagePerFileMappings<T> implements PersistentStateCompo
|
||||
}
|
||||
|
||||
protected abstract List<T> getAvailableValues();
|
||||
|
||||
|
||||
@Nullable
|
||||
protected abstract String serialize(T t);
|
||||
|
||||
public Element getState() {
|
||||
@@ -161,10 +162,13 @@ public abstract class LanguagePerFileMappings<T> implements PersistentStateCompo
|
||||
});
|
||||
for (VirtualFile file : files) {
|
||||
final T dialect = myMappings.get(file);
|
||||
final Element child = new Element("file");
|
||||
element.addContent(child);
|
||||
child.setAttribute("url", file == null ? "PROJECT" : file.getUrl());
|
||||
child.setAttribute(getValueAttribute(), serialize(dialect));
|
||||
String value = serialize(dialect);
|
||||
if (value != null) {
|
||||
final Element child = new Element("file");
|
||||
element.addContent(child);
|
||||
child.setAttribute("url", file == null ? "PROJECT" : file.getUrl());
|
||||
child.setAttribute(getValueAttribute(), value);
|
||||
}
|
||||
}
|
||||
return element;
|
||||
}
|
||||
@@ -184,7 +188,10 @@ public abstract class LanguagePerFileMappings<T> implements PersistentStateCompo
|
||||
synchronized (myMappings) {
|
||||
final THashMap<String, T> dialectMap = new THashMap<String, T>();
|
||||
for (T dialect : getAvailableValues()) {
|
||||
dialectMap.put(serialize(dialect), dialect);
|
||||
String key = serialize(dialect);
|
||||
if (key != null) {
|
||||
dialectMap.put(key, dialect);
|
||||
}
|
||||
}
|
||||
final List<Element> files = state.getChildren("file");
|
||||
for (Element fileElement : files) {
|
||||
|
||||
+26
-11
@@ -162,7 +162,10 @@ public class TextChangesStorage {
|
||||
int newChangeStart = change.getStart();
|
||||
int newChangeEnd = change.getEnd();
|
||||
int storedChangeStart = getChangeIndex(change.getStart());
|
||||
int clientShift = 0;
|
||||
int clientShift = 0; // 'Client text' shift before the given change to store. I.e. this value can be subtracted from the
|
||||
// given change's start/end offsets in order to get original document range affected by the given change.
|
||||
int changeDiff = change.getText().length() - (change.getEnd() - change.getStart());
|
||||
boolean updateClientOffsetOnly = false;
|
||||
|
||||
if (storedChangeStart < 0) {
|
||||
storedChangeStart = -storedChangeStart - 1;
|
||||
@@ -171,9 +174,6 @@ public class TextChangesStorage {
|
||||
ChangeEntry changeEntry = myChanges.get(storedChangeStart - 1);
|
||||
clientShift = changeEntry.clientStartOffset - changeEntry.change.getStart() + changeEntry.change.getDiff();
|
||||
}
|
||||
}
|
||||
|
||||
if (storedChangeStart >= myChanges.size()) {
|
||||
myChanges.add(new ChangeEntry(
|
||||
new TextChangeImpl(change.getText(), change.getStart() - clientShift, change.getEnd() - clientShift),
|
||||
change.getStart()
|
||||
@@ -192,6 +192,21 @@ public class TextChangesStorage {
|
||||
CharSequence storedText = changeEntry.change.getText();
|
||||
int storedClientEnd = storedClientStart + storedText.length();
|
||||
|
||||
// Stored change lays after the new one.
|
||||
if (!updateClientOffsetOnly && storedClientStart > newChangeEnd) {
|
||||
if (changeDiff != 0) {
|
||||
updateClientOffsetOnly = true;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateClientOffsetOnly) {
|
||||
changeEntry.clientStartOffset += changeDiff;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Stored change lays before the new one.
|
||||
if (storedClientEnd <= newChangeStart) {
|
||||
clientShift += changeEntry.change.getDiff();
|
||||
@@ -199,9 +214,7 @@ public class TextChangesStorage {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We know that given change and stored change have intersections if control flow reaches this place.
|
||||
|
||||
// Check if given change target sub-range of the stored one
|
||||
// Check if given change targets sub-range of the stored one.
|
||||
if (storedClientStart <= newChangeStart && storedClientEnd >= newChangeEnd) {
|
||||
StringBuilder adjustedText = new StringBuilder();
|
||||
if (storedClientStart < newChangeStart) {
|
||||
@@ -215,13 +228,15 @@ public class TextChangesStorage {
|
||||
if (adjustedText.length() == 0 && changeEntry.change.getStart() == changeEntry.change.getEnd()) {
|
||||
myChanges.remove(i);
|
||||
insertionIndex = -1;
|
||||
break;
|
||||
updateClientOffsetOnly = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
TextChangeImpl adjusted = new TextChangeImpl(adjustedText, changeEntry.change.getStart(), changeEntry.change.getEnd());
|
||||
myChanges.set(i, new ChangeEntry(adjusted, adjusted.getStart()));
|
||||
insertionIndex = -1;
|
||||
break;
|
||||
updateClientOffsetOnly = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if given change completely contains stored change range.
|
||||
@@ -234,7 +249,7 @@ public class TextChangesStorage {
|
||||
}
|
||||
|
||||
// Check if given change intersects stored change range from the left.
|
||||
if (newChangeStart <= storedClientStart && newChangeEnd < storedClientEnd) {
|
||||
if (newChangeStart <= storedClientStart && newChangeEnd > storedClientStart) {
|
||||
int numberOfStoredChangeSymbolsToRemove = newChangeEnd - storedClientStart;
|
||||
CharSequence adjustedText = storedText.subSequence(numberOfStoredChangeSymbolsToRemove, storedText.length());
|
||||
changeEntry.change = new TextChangeImpl(adjustedText, changeEntry.change.getStart(), changeEntry.change.getEnd());
|
||||
@@ -244,7 +259,7 @@ public class TextChangesStorage {
|
||||
}
|
||||
|
||||
// Check if given change intersects stored change range from the right.
|
||||
if (newChangeStart < storedClientEnd && newChangeEnd > storedClientEnd) {
|
||||
if (newChangeStart < storedClientEnd && newChangeEnd >= storedClientEnd) {
|
||||
CharSequence adjustedText = storedText.subSequence(0, newChangeStart - storedClientStart);
|
||||
TextChangeImpl adjusted = new TextChangeImpl(adjustedText, changeEntry.change.getStart(), changeEntry.change.getEnd());
|
||||
myChanges.set(i, new ChangeEntry(adjusted, adjusted.getStart()));
|
||||
|
||||
+7
@@ -64,6 +64,13 @@ public class TextChangesStorageTest {
|
||||
checkChanges(c("abc", 2), c("def", 3), c("ghi", 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disconnectedInsertsFromTailToStart() {
|
||||
insert("abc", 10);
|
||||
insert("def", 1);
|
||||
checkChanges(c("def", 1), c("abc", 10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void adjacentInserts() {
|
||||
insert("abc", 2);
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -83,8 +82,22 @@ public abstract class AbstractConfigUtils {
|
||||
*/
|
||||
@Nullable
|
||||
public static String getSDKJarVersion(String jarPath, final String jarRegex, String manifestPath) {
|
||||
return getSDKJarVersion(jarPath, Pattern.compile(jarRegex), manifestPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return value of Implementation-Version attribute in jar manifest
|
||||
* <p/>
|
||||
*
|
||||
* @param jarPath directory containing jar file
|
||||
* @param jarPattern filename pattern for jar file
|
||||
* @param manifestPath path to manifest file in jar file
|
||||
* @return value of Implementation-Version attribute, null if not found
|
||||
*/
|
||||
@Nullable
|
||||
public static String getSDKJarVersion(String jarPath, final Pattern jarPattern, String manifestPath) {
|
||||
try {
|
||||
File[] jars = GroovyUtils.getFilesInDirectoryByPattern(jarPath, jarRegex);
|
||||
File[] jars = GroovyUtils.getFilesInDirectoryByPattern(jarPath, jarPattern);
|
||||
if (jars.length != 1) {
|
||||
return null;
|
||||
}
|
||||
@@ -107,7 +120,7 @@ public abstract class AbstractConfigUtils {
|
||||
return version;
|
||||
}
|
||||
|
||||
final Matcher matcher = Pattern.compile(jarRegex).matcher(jars[0].getName());
|
||||
final Matcher matcher = jarPattern.matcher(jars[0].getName());
|
||||
if (matcher.matches() && matcher.groupCount() == 1) {
|
||||
return matcher.group(1);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class GroovyHotSwapper extends JavaProgramPatcher {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean containsGroovyClasses(Project project) {
|
||||
|
||||
+13
-1
@@ -23,7 +23,9 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.SettingsEditor;
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.ComboboxSpeedSearch;
|
||||
import com.intellij.ui.FieldPanel;
|
||||
import com.intellij.ui.RawCommandLineEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -31,6 +33,8 @@ import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class GroovyRunConfigurationEditor extends SettingsEditor<GroovyScriptRunConfiguration> {
|
||||
private DefaultComboBoxModel myModulesModel;
|
||||
@@ -84,7 +88,9 @@ public class GroovyRunConfigurationEditor extends SettingsEditor<GroovyScriptRun
|
||||
myDebugCB.setSelected(configuration.isDebugEnabled());
|
||||
|
||||
myModulesModel.removeAllElements();
|
||||
for (Module module : configuration.getValidModules()) {
|
||||
List<Module> modules = new ArrayList<Module>(configuration.getValidModules());
|
||||
Collections.sort(modules, ModulesAlphaComparator.INSTANCE);
|
||||
for (Module module : modules) {
|
||||
myModulesModel.addElement(module);
|
||||
}
|
||||
myModulesModel.setSelectedItem(configuration.getModule());
|
||||
@@ -118,6 +124,12 @@ public class GroovyRunConfigurationEditor extends SettingsEditor<GroovyScriptRun
|
||||
}
|
||||
}
|
||||
});
|
||||
new ComboboxSpeedSearch(myModulesBox) {
|
||||
@Override
|
||||
protected String getElementText(Object element) {
|
||||
return element instanceof Module ? ((Module)element).getName() : "";
|
||||
}
|
||||
};
|
||||
|
||||
return myMainPanel;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public class XmlUnwrapDescriptor implements UnwrapDescriptor {
|
||||
|
||||
PsiElement tag = PsiTreeUtil.getParentOfType(e, XmlTag.class);
|
||||
while (tag != null) {
|
||||
if (XmlChildRole.START_TAG_END_FINDER.findChild(tag.getNode()) != null) { // Exclude implicit tags suck as 'jsp:root'
|
||||
if (XmlChildRole.START_TAG_NAME_FINDER.findChild(tag.getNode()) != null) { // Exclude implicit tags suck as 'jsp:root'
|
||||
result.add(new Pair<PsiElement, Unwrapper>(tag, new XmlEnclosingTagUnwrapper()));
|
||||
}
|
||||
tag = PsiTreeUtil.getParentOfType(tag, XmlTag.class);
|
||||
|
||||
Reference in New Issue
Block a user