feat!: Colored builds and clickable file path references
This commit is contained in:
parent
4e401d276a
commit
66aef224b2
24 changed files with 595 additions and 266 deletions
|
@ -181,6 +181,7 @@ project(":lsp") {
|
||||||
plugin("java-library")
|
plugin("java-library")
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation(project(":common"))
|
||||||
api("org.eclipse.lsp4j:org.eclipse.lsp4j:0.22.0")
|
api("org.eclipse.lsp4j:org.eclipse.lsp4j:0.22.0")
|
||||||
implementation("com.vladsch.flexmark:flexmark:0.64.8")
|
implementation("com.vladsch.flexmark:flexmark:0.64.8")
|
||||||
api("org.apache.commons:commons-lang3:3.14.0")
|
api("org.apache.commons:commons-lang3:3.14.0")
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023-2024 FalsePattern
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.common.util;
|
||||||
|
|
||||||
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
|
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
public class FileUtil {
|
||||||
|
private static final Logger LOG = Logger.getInstance(FileUtil.class);
|
||||||
|
|
||||||
|
public final static String SPACE_ENCODED = "%20";
|
||||||
|
private final static OS os = (System.getProperty("os.name").toLowerCase().contains("win")) ? OS.WINDOWS : OS.UNIX;
|
||||||
|
private final static String COLON_ENCODED = "%3A";
|
||||||
|
private final static String URI_FILE_BEGIN = "file:";
|
||||||
|
private final static String URI_VALID_FILE_BEGIN = "file:///";
|
||||||
|
private final static char URI_PATH_SEP = '/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fixes common problems in uri, mainly related to Windows
|
||||||
|
*
|
||||||
|
* @param uri The uri to sanitize
|
||||||
|
* @return The sanitized uri
|
||||||
|
*/
|
||||||
|
public static String sanitizeURI(String uri) {
|
||||||
|
if (uri != null) {
|
||||||
|
StringBuilder reconstructed = new StringBuilder();
|
||||||
|
String uriCp = uri.replaceAll(" ", SPACE_ENCODED); //Don't trust servers
|
||||||
|
if (!uri.startsWith(URI_FILE_BEGIN)) {
|
||||||
|
LOG.warn("Malformed uri : " + uri);
|
||||||
|
return uri; //Probably not an uri
|
||||||
|
} else {
|
||||||
|
uriCp = uriCp.substring(URI_FILE_BEGIN.length());
|
||||||
|
while (uriCp.startsWith(Character.toString(URI_PATH_SEP))) {
|
||||||
|
uriCp = uriCp.substring(1);
|
||||||
|
}
|
||||||
|
reconstructed.append(URI_VALID_FILE_BEGIN);
|
||||||
|
if (os == OS.UNIX) {
|
||||||
|
return reconstructed.append(uriCp).toString();
|
||||||
|
} else {
|
||||||
|
reconstructed.append(uriCp.substring(0, uriCp.indexOf(URI_PATH_SEP)));
|
||||||
|
char driveLetter = reconstructed.charAt(URI_VALID_FILE_BEGIN.length());
|
||||||
|
if (Character.isLowerCase(driveLetter)) {
|
||||||
|
reconstructed.setCharAt(URI_VALID_FILE_BEGIN.length(), Character.toUpperCase(driveLetter));
|
||||||
|
}
|
||||||
|
if (reconstructed.toString().endsWith(COLON_ENCODED)) {
|
||||||
|
reconstructed.delete(reconstructed.length() - 3, reconstructed.length());
|
||||||
|
}
|
||||||
|
if (!reconstructed.toString().endsWith(":")) {
|
||||||
|
reconstructed.append(":");
|
||||||
|
}
|
||||||
|
return reconstructed.append(uriCp.substring(uriCp.indexOf(URI_PATH_SEP))).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the URI string corresponding to a VirtualFileSystem file
|
||||||
|
*
|
||||||
|
* @param file The file
|
||||||
|
* @return the URI
|
||||||
|
*/
|
||||||
|
public static String URIFromVirtualFile(VirtualFile file) {
|
||||||
|
return file == null? null : pathToUri(file.getPath());
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Transforms an URI string into a VFS file
|
||||||
|
*
|
||||||
|
* @param uri The uri
|
||||||
|
* @return The virtual file
|
||||||
|
*/
|
||||||
|
public static VirtualFile virtualFileFromURI(URI uri) {
|
||||||
|
return LocalFileSystem.getInstance().findFileByIoFile(new File(uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms an URI string into a VFS file
|
||||||
|
*
|
||||||
|
* @param uri The uri
|
||||||
|
* @return The virtual file
|
||||||
|
*/
|
||||||
|
public static VirtualFile virtualFileFromURI(String uri) {
|
||||||
|
try {
|
||||||
|
return virtualFileFromURI(new URI(sanitizeURI(uri)));
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
LOG.warn(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms a path into an URI string
|
||||||
|
*
|
||||||
|
* @param path The path
|
||||||
|
* @return The uri
|
||||||
|
*/
|
||||||
|
public static String pathToUri(@Nullable String path) {
|
||||||
|
return path != null ? sanitizeURI(new File(path).toURI().toString()) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object representing the OS type (Windows or Unix)
|
||||||
|
*/
|
||||||
|
public enum OS {
|
||||||
|
WINDOWS, UNIX
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,10 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.common.util;
|
package com.falsepattern.zigbrains.common.util;
|
||||||
|
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class StringUtil {
|
public class StringUtil {
|
||||||
public static String blankToNull(String value) {
|
public static String blankToNull(String value) {
|
||||||
return value == null || value.isBlank() ? null : value;
|
return value == null || value.isBlank() ? null : value;
|
||||||
|
@ -24,4 +28,56 @@ public class StringUtil {
|
||||||
public static String orEmpty(String value) {
|
public static String orEmpty(String value) {
|
||||||
return value == null ? "" : value;
|
return value == null ? "" : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final char[] VT100_CHARS = new char[256];
|
||||||
|
|
||||||
|
static {
|
||||||
|
Arrays.fill(VT100_CHARS, ' ');
|
||||||
|
VT100_CHARS[0x6A] = '┘';
|
||||||
|
VT100_CHARS[0x6B] = '┐';
|
||||||
|
VT100_CHARS[0x6C] = '┌';
|
||||||
|
VT100_CHARS[0x6D] = '└';
|
||||||
|
VT100_CHARS[0x6E] = '┼';
|
||||||
|
VT100_CHARS[0x71] = '─';
|
||||||
|
VT100_CHARS[0x74] = '├';
|
||||||
|
VT100_CHARS[0x75] = '┤';
|
||||||
|
VT100_CHARS[0x76] = '┴';
|
||||||
|
VT100_CHARS[0x77] = '┬';
|
||||||
|
VT100_CHARS[0x78] = '│';
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String VT100_BEGIN_SEQ = "\u001B(0";
|
||||||
|
private static final String VT100_END_SEQ = "\u001B(B";
|
||||||
|
private static final int VT100_BEGIN_SEQ_LENGTH = VT100_BEGIN_SEQ.length();
|
||||||
|
private static final int VT100_END_SEQ_LENGTH = VT100_END_SEQ.length();
|
||||||
|
|
||||||
|
public static String translateVT100Escapes(String text) {
|
||||||
|
int offset = 0;
|
||||||
|
val result = new StringBuilder();
|
||||||
|
val textLength = text.length();
|
||||||
|
while (offset < textLength) {
|
||||||
|
val startIndex = text.indexOf(VT100_BEGIN_SEQ, offset);
|
||||||
|
if (startIndex < 0) {
|
||||||
|
result.append(text.substring(offset, textLength).replace(VT100_END_SEQ, ""));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.append(text, offset, startIndex);
|
||||||
|
val blockOffset = startIndex + VT100_BEGIN_SEQ_LENGTH;
|
||||||
|
var endIndex = text.indexOf(VT100_END_SEQ, blockOffset);
|
||||||
|
if (endIndex < 0) {
|
||||||
|
endIndex = textLength;
|
||||||
|
}
|
||||||
|
for (int i = blockOffset; i < endIndex; i++) {
|
||||||
|
val c = text.charAt(i);
|
||||||
|
if (c >= 256) {
|
||||||
|
result.append(c);
|
||||||
|
} else {
|
||||||
|
result.append(VT100_CHARS[c]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset = endIndex + VT100_END_SEQ_LENGTH;
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.falsepattern.zigbrains.lsp;
|
package com.falsepattern.zigbrains.lsp;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.ServerStatus;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.ServerStatus;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.serverdefinition.LanguageServerDefinition;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.serverdefinition.LanguageServerDefinition;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.wrapper.LanguageServerWrapper;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.wrapper.LanguageServerWrapper;
|
||||||
|
@ -331,7 +332,7 @@ public class IntellijLanguageClient {
|
||||||
if (wrapper.getProject() != null) {
|
if (wrapper.getProject() != null) {
|
||||||
String[] extensions = wrapper.getServerDefinition().ext.split(LanguageServerDefinition.SPLIT_CHAR);
|
String[] extensions = wrapper.getServerDefinition().ext.split(LanguageServerDefinition.SPLIT_CHAR);
|
||||||
for (String ext : extensions) {
|
for (String ext : extensions) {
|
||||||
MutablePair<String, String> extProjectPair = new MutablePair<>(ext, FileUtils.pathToUri(
|
MutablePair<String, String> extProjectPair = new MutablePair<>(ext, FileUtil.pathToUri(
|
||||||
new File(wrapper.getProjectRootPath()).getAbsolutePath()));
|
new File(wrapper.getProjectRootPath()).getAbsolutePath()));
|
||||||
extToLanguageWrapper.remove(extProjectPair);
|
extToLanguageWrapper.remove(extProjectPair);
|
||||||
extToServerDefinition.remove(extProjectPair);
|
extToServerDefinition.remove(extProjectPair);
|
||||||
|
|
|
@ -15,10 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package com.falsepattern.zigbrains.lsp.client;
|
package com.falsepattern.zigbrains.lsp.client;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.lsp.editor.EditorEventManagerBase;
|
import com.falsepattern.zigbrains.lsp.editor.EditorEventManagerBase;
|
||||||
import com.falsepattern.zigbrains.lsp.requests.WorkspaceEditHandler;
|
import com.falsepattern.zigbrains.lsp.requests.WorkspaceEditHandler;
|
||||||
import com.falsepattern.zigbrains.lsp.utils.ApplicationUtils;
|
import com.falsepattern.zigbrains.lsp.utils.ApplicationUtils;
|
||||||
import com.falsepattern.zigbrains.lsp.utils.FileUtils;
|
|
||||||
import com.intellij.notification.Notification;
|
import com.intellij.notification.Notification;
|
||||||
import com.intellij.notification.NotificationAction;
|
import com.intellij.notification.NotificationAction;
|
||||||
import com.intellij.notification.NotificationGroup;
|
import com.intellij.notification.NotificationGroup;
|
||||||
|
@ -123,7 +123,7 @@ public class DefaultLanguageClient implements LanguageClient {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void publishDiagnostics(PublishDiagnosticsParams publishDiagnosticsParams) {
|
public void publishDiagnostics(PublishDiagnosticsParams publishDiagnosticsParams) {
|
||||||
String uri = FileUtils.sanitizeURI(publishDiagnosticsParams.getUri());
|
String uri = FileUtil.sanitizeURI(publishDiagnosticsParams.getUri());
|
||||||
List<Diagnostic> diagnostics = publishDiagnosticsParams.getDiagnostics();
|
List<Diagnostic> diagnostics = publishDiagnosticsParams.getDiagnostics();
|
||||||
EditorEventManagerBase.diagnostics(uri, diagnostics);
|
EditorEventManagerBase.diagnostics(uri, diagnostics);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.falsepattern.zigbrains.lsp.client.languageserver.wrapper;
|
package com.falsepattern.zigbrains.lsp.client.languageserver.wrapper;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
||||||
import com.falsepattern.zigbrains.lsp.client.DefaultLanguageClient;
|
import com.falsepattern.zigbrains.lsp.client.DefaultLanguageClient;
|
||||||
import com.falsepattern.zigbrains.lsp.client.ServerWrapperBaseClientContext;
|
import com.falsepattern.zigbrains.lsp.client.ServerWrapperBaseClientContext;
|
||||||
|
@ -23,7 +24,6 @@ import com.falsepattern.zigbrains.lsp.client.languageserver.ServerStatus;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.requestmanager.DefaultRequestManager;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.requestmanager.DefaultRequestManager;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.requestmanager.RequestManager;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.requestmanager.RequestManager;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.serverdefinition.LanguageServerDefinition;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.serverdefinition.LanguageServerDefinition;
|
||||||
import com.falsepattern.zigbrains.lsp.editor.DocumentEventManager;
|
|
||||||
import com.falsepattern.zigbrains.lsp.editor.EditorEventManager;
|
import com.falsepattern.zigbrains.lsp.editor.EditorEventManager;
|
||||||
import com.falsepattern.zigbrains.lsp.editor.EditorEventManagerBase;
|
import com.falsepattern.zigbrains.lsp.editor.EditorEventManagerBase;
|
||||||
import com.falsepattern.zigbrains.lsp.extensions.LSPExtensionManager;
|
import com.falsepattern.zigbrains.lsp.extensions.LSPExtensionManager;
|
||||||
|
@ -182,7 +182,7 @@ public class LanguageServerWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LanguageServerWrapper forVirtualFile(VirtualFile file, Project project) {
|
public static LanguageServerWrapper forVirtualFile(VirtualFile file, Project project) {
|
||||||
return uriToLanguageServerWrapper.get(new ImmutablePair<>(FileUtils.VFSToURI(file), FileUtils.projectToUri(project)));
|
return uriToLanguageServerWrapper.get(new ImmutablePair<>(FileUtil.URIFromVirtualFile(file), FileUtils.projectToUri(project)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -280,7 +280,7 @@ public class LanguageServerWrapper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
VirtualFile currentOpenFile = selectedEditor.getFile();
|
VirtualFile currentOpenFile = selectedEditor.getFile();
|
||||||
VirtualFile requestedFile = FileUtils.virtualFileFromURI(uri);
|
VirtualFile requestedFile = FileUtil.virtualFileFromURI(uri);
|
||||||
if (currentOpenFile == null || requestedFile == null) {
|
if (currentOpenFile == null || requestedFile == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -550,7 +550,7 @@ public class LanguageServerWrapper {
|
||||||
|
|
||||||
private InitializeParams getInitParams() throws URISyntaxException {
|
private InitializeParams getInitParams() throws URISyntaxException {
|
||||||
InitializeParams initParams = new InitializeParams();
|
InitializeParams initParams = new InitializeParams();
|
||||||
String projectRootUri = FileUtils.pathToUri(projectRootPath);
|
String projectRootUri = FileUtil.pathToUri(projectRootPath);
|
||||||
WorkspaceFolder workspaceFolder = new WorkspaceFolder(projectRootUri, this.project.getName());
|
WorkspaceFolder workspaceFolder = new WorkspaceFolder(projectRootUri, this.project.getName());
|
||||||
initParams.setWorkspaceFolders(Collections.singletonList(workspaceFolder));
|
initParams.setWorkspaceFolders(Collections.singletonList(workspaceFolder));
|
||||||
|
|
||||||
|
@ -679,7 +679,7 @@ public class LanguageServerWrapper {
|
||||||
List<String> connected = new ArrayList<>();
|
List<String> connected = new ArrayList<>();
|
||||||
urisUnderLspControl.forEach(s -> {
|
urisUnderLspControl.forEach(s -> {
|
||||||
try {
|
try {
|
||||||
connected.add(new URI(FileUtils.sanitizeURI(s)).toString());
|
connected.add(new URI(FileUtil.sanitizeURI(s)).toString());
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
LOG.warn(e);
|
LOG.warn(e);
|
||||||
}
|
}
|
||||||
|
@ -733,7 +733,7 @@ public class LanguageServerWrapper {
|
||||||
* @param projectUri The project root uri
|
* @param projectUri The project root uri
|
||||||
*/
|
*/
|
||||||
public void disconnect(String uri, String projectUri) {
|
public void disconnect(String uri, String projectUri) {
|
||||||
uriToLanguageServerWrapper.remove(new ImmutablePair<>(FileUtils.sanitizeURI(uri), FileUtils.sanitizeURI(projectUri)));
|
uriToLanguageServerWrapper.remove(new ImmutablePair<>(FileUtil.sanitizeURI(uri), FileUtil.sanitizeURI(projectUri)));
|
||||||
|
|
||||||
Set<EditorEventManager> managers = uriToEditorManagers.get(uri);
|
Set<EditorEventManager> managers = uriToEditorManagers.get(uri);
|
||||||
if (managers == null) {
|
if (managers == null) {
|
||||||
|
@ -752,7 +752,7 @@ public class LanguageServerWrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
urisUnderLspControl.remove(uri);
|
urisUnderLspControl.remove(uri);
|
||||||
uriToLanguageServerWrapper.remove(new ImmutablePair<>(FileUtils.sanitizeURI(uri), FileUtils.sanitizeURI(projectUri)));
|
uriToLanguageServerWrapper.remove(new ImmutablePair<>(FileUtil.sanitizeURI(uri), FileUtil.sanitizeURI(projectUri)));
|
||||||
}
|
}
|
||||||
if (connectedEditors.isEmpty()) {
|
if (connectedEditors.isEmpty()) {
|
||||||
stop(true);
|
stop(true);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.falsepattern.zigbrains.lsp.contributors.annotator;
|
package com.falsepattern.zigbrains.lsp.contributors.annotator;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.ServerStatus;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.ServerStatus;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.wrapper.LanguageServerWrapper;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.wrapper.LanguageServerWrapper;
|
||||||
|
@ -103,7 +104,7 @@ public class LSPAnnotator extends ExternalAnnotator<Object, Object> {
|
||||||
|
|
||||||
VirtualFile virtualFile = file.getVirtualFile();
|
VirtualFile virtualFile = file.getVirtualFile();
|
||||||
if (FileUtils.isFileSupported(virtualFile) && IntellijLanguageClient.isExtensionSupported(virtualFile)) {
|
if (FileUtils.isFileSupported(virtualFile) && IntellijLanguageClient.isExtensionSupported(virtualFile)) {
|
||||||
String uri = FileUtils.VFSToURI(virtualFile);
|
String uri = FileUtil.URIFromVirtualFile(virtualFile);
|
||||||
// TODO annotations are applied to a file / document not to an editor. so store them by file and not by editor..
|
// TODO annotations are applied to a file / document not to an editor. so store them by file and not by editor..
|
||||||
EditorEventManager eventManager = EditorEventManagerBase.forUri(uri);
|
EditorEventManager eventManager = EditorEventManagerBase.forUri(uri);
|
||||||
if (eventManager == null) {
|
if (eventManager == null) {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.falsepattern.zigbrains.lsp.contributors.symbol;
|
package com.falsepattern.zigbrains.lsp.contributors.symbol;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.ServerStatus;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.ServerStatus;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.requestmanager.RequestManager;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.requestmanager.RequestManager;
|
||||||
|
@ -70,7 +71,7 @@ public class WorkspaceSymbolProvider {
|
||||||
final SymbolInformation information = (result.getSymbolInformation() != null) ?
|
final SymbolInformation information = (result.getSymbolInformation() != null) ?
|
||||||
result.getSymbolInformation() : from(result.getWorkspaceSymbol());
|
result.getSymbolInformation() : from(result.getWorkspaceSymbol());
|
||||||
final Location location = information.getLocation();
|
final Location location = information.getLocation();
|
||||||
final VirtualFile file = FileUtils.URIToVFS(location.getUri());
|
final VirtualFile file = FileUtil.virtualFileFromURI(location.getUri());
|
||||||
|
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
final LSPIconProvider iconProviderFor = GUIUtils.getIconProviderFor(result.getDefinition());
|
final LSPIconProvider iconProviderFor = GUIUtils.getIconProviderFor(result.getDefinition());
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.falsepattern.zigbrains.lsp.editor;
|
package com.falsepattern.zigbrains.lsp.editor;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.lsp.actions.LSPReferencesAction;
|
import com.falsepattern.zigbrains.lsp.actions.LSPReferencesAction;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.ServerOptions;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.ServerOptions;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.requestmanager.RequestManager;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.requestmanager.RequestManager;
|
||||||
|
@ -25,7 +26,6 @@ import com.falsepattern.zigbrains.lsp.contributors.icon.LSPIconProvider;
|
||||||
import com.falsepattern.zigbrains.lsp.contributors.psi.LSPPsiElement;
|
import com.falsepattern.zigbrains.lsp.contributors.psi.LSPPsiElement;
|
||||||
import com.falsepattern.zigbrains.lsp.contributors.rename.LSPRenameProcessor;
|
import com.falsepattern.zigbrains.lsp.contributors.rename.LSPRenameProcessor;
|
||||||
import com.falsepattern.zigbrains.lsp.listeners.LSPCaretListenerImpl;
|
import com.falsepattern.zigbrains.lsp.listeners.LSPCaretListenerImpl;
|
||||||
import com.falsepattern.zigbrains.lsp.requests.HoverHandler;
|
|
||||||
import com.falsepattern.zigbrains.lsp.requests.Timeout;
|
import com.falsepattern.zigbrains.lsp.requests.Timeout;
|
||||||
import com.falsepattern.zigbrains.lsp.requests.Timeouts;
|
import com.falsepattern.zigbrains.lsp.requests.Timeouts;
|
||||||
import com.falsepattern.zigbrains.lsp.requests.WorkspaceEditHandler;
|
import com.falsepattern.zigbrains.lsp.requests.WorkspaceEditHandler;
|
||||||
|
@ -54,15 +54,10 @@ import com.intellij.openapi.editor.EditorModificationUtil;
|
||||||
import com.intellij.openapi.editor.LogicalPosition;
|
import com.intellij.openapi.editor.LogicalPosition;
|
||||||
import com.intellij.openapi.editor.ScrollType;
|
import com.intellij.openapi.editor.ScrollType;
|
||||||
import com.intellij.openapi.editor.SelectionModel;
|
import com.intellij.openapi.editor.SelectionModel;
|
||||||
import com.intellij.openapi.editor.colors.EditorColors;
|
|
||||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||||
import com.intellij.openapi.editor.event.DocumentListener;
|
import com.intellij.openapi.editor.event.DocumentListener;
|
||||||
import com.intellij.openapi.editor.event.EditorMouseEvent;
|
import com.intellij.openapi.editor.event.EditorMouseEvent;
|
||||||
import com.intellij.openapi.editor.event.EditorMouseListener;
|
|
||||||
import com.intellij.openapi.editor.event.EditorMouseMotionListener;
|
|
||||||
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||||
import com.intellij.openapi.editor.markup.HighlighterLayer;
|
|
||||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
|
|
||||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||||
|
@ -72,7 +67,6 @@ import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.openapi.vfs.VfsUtil;
|
import com.intellij.openapi.vfs.VfsUtil;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
|
||||||
import com.intellij.psi.PsiDocumentManager;
|
import com.intellij.psi.PsiDocumentManager;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
|
@ -96,8 +90,6 @@ import org.eclipse.lsp4j.DocumentFormattingParams;
|
||||||
import org.eclipse.lsp4j.DocumentRangeFormattingParams;
|
import org.eclipse.lsp4j.DocumentRangeFormattingParams;
|
||||||
import org.eclipse.lsp4j.ExecuteCommandParams;
|
import org.eclipse.lsp4j.ExecuteCommandParams;
|
||||||
import org.eclipse.lsp4j.FormattingOptions;
|
import org.eclipse.lsp4j.FormattingOptions;
|
||||||
import org.eclipse.lsp4j.Hover;
|
|
||||||
import org.eclipse.lsp4j.HoverParams;
|
|
||||||
import org.eclipse.lsp4j.InlayHint;
|
import org.eclipse.lsp4j.InlayHint;
|
||||||
import org.eclipse.lsp4j.InlayHintParams;
|
import org.eclipse.lsp4j.InlayHintParams;
|
||||||
import org.eclipse.lsp4j.InsertReplaceEdit;
|
import org.eclipse.lsp4j.InsertReplaceEdit;
|
||||||
|
@ -124,7 +116,6 @@ import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||||
import org.eclipse.lsp4j.jsonrpc.messages.Tuple;
|
import org.eclipse.lsp4j.jsonrpc.messages.Tuple;
|
||||||
import org.eclipse.lsp4j.services.TextDocumentService;
|
import org.eclipse.lsp4j.services.TextDocumentService;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
@ -144,7 +135,6 @@ import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -370,8 +360,8 @@ public class EditorEventManager {
|
||||||
res.forEach(l -> {
|
res.forEach(l -> {
|
||||||
Position start = l.getRange().getStart();
|
Position start = l.getRange().getStart();
|
||||||
Position end = l.getRange().getEnd();
|
Position end = l.getRange().getEnd();
|
||||||
String uri = FileUtils.sanitizeURI(l.getUri());
|
String uri = FileUtil.sanitizeURI(l.getUri());
|
||||||
VirtualFile file = FileUtils.virtualFileFromURI(uri);
|
VirtualFile file = FileUtil.virtualFileFromURI(uri);
|
||||||
if (fast) {
|
if (fast) {
|
||||||
if (file == null)
|
if (file == null)
|
||||||
return;
|
return;
|
||||||
|
@ -1322,7 +1312,7 @@ public class EditorEventManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String locUri = FileUtils.sanitizeURI(loc.getUri());
|
String locUri = FileUtil.sanitizeURI(loc.getUri());
|
||||||
|
|
||||||
if (identifier.getUri().equals(locUri)
|
if (identifier.getUri().equals(locUri)
|
||||||
&& sourceOffset >= DocumentUtils.LSPPosToOffset(editor, loc.getRange().getStart())
|
&& sourceOffset >= DocumentUtils.LSPPosToOffset(editor, loc.getRange().getStart())
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.falsepattern.zigbrains.lsp.listeners;
|
package com.falsepattern.zigbrains.lsp.listeners;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.ServerStatus;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.ServerStatus;
|
||||||
import com.falsepattern.zigbrains.lsp.client.languageserver.wrapper.LanguageServerWrapper;
|
import com.falsepattern.zigbrains.lsp.client.languageserver.wrapper.LanguageServerWrapper;
|
||||||
|
@ -51,7 +52,7 @@ class LSPFileEventManager {
|
||||||
* @param doc The document
|
* @param doc The document
|
||||||
*/
|
*/
|
||||||
static void willSave(Document doc) {
|
static void willSave(Document doc) {
|
||||||
String uri = FileUtils.VFSToURI(FileDocumentManager.getInstance().getFile(doc));
|
String uri = FileUtil.URIFromVirtualFile(FileDocumentManager.getInstance().getFile(doc));
|
||||||
EditorEventManagerBase.willSave(uri);
|
EditorEventManagerBase.willSave(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ class LSPFileEventManager {
|
||||||
if (!FileUtils.isFileSupported(file)) {
|
if (!FileUtils.isFileSupported(file)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String uri = FileUtils.VFSToURI(file);
|
String uri = FileUtil.URIFromVirtualFile(file);
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -96,8 +97,8 @@ class LSPFileEventManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String newFileUri = FileUtils.VFSToURI(file);
|
String newFileUri = FileUtil.URIFromVirtualFile(file);
|
||||||
String oldParentUri = FileUtils.VFSToURI(event.getOldParent());
|
String oldParentUri = FileUtil.URIFromVirtualFile(event.getOldParent());
|
||||||
if (newFileUri == null || oldParentUri == null) {
|
if (newFileUri == null || oldParentUri == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +118,7 @@ class LSPFileEventManager {
|
||||||
if (!FileUtils.isFileSupported(file)) {
|
if (!FileUtils.isFileSupported(file)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String uri = FileUtils.VFSToURI(file);
|
String uri = FileUtil.URIFromVirtualFile(file);
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -146,7 +147,7 @@ class LSPFileEventManager {
|
||||||
if (!FileUtils.isFileSupported(file)) {
|
if (!FileUtils.isFileSupported(file)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String newFileUri = FileUtils.VFSToURI(file);
|
String newFileUri = FileUtil.URIFromVirtualFile(file);
|
||||||
String oldFileUri = newFileUri.replace(file.getName(), oldFileName);
|
String oldFileUri = newFileUri.replace(file.getName(), oldFileName);
|
||||||
closeAndReopenAffectedFile(file, oldFileUri);
|
closeAndReopenAffectedFile(file, oldFileUri);
|
||||||
}
|
}
|
||||||
|
@ -157,7 +158,7 @@ class LSPFileEventManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void closeAndReopenAffectedFile(VirtualFile file, String oldFileUri) {
|
private static void closeAndReopenAffectedFile(VirtualFile file, String oldFileUri) {
|
||||||
String newFileUri = FileUtils.VFSToURI(file);
|
String newFileUri = FileUtil.URIFromVirtualFile(file);
|
||||||
|
|
||||||
// Notifies the language server.
|
// Notifies the language server.
|
||||||
FileUtils.findProjectsFor(file).forEach(p -> changedConfiguration(oldFileUri,
|
FileUtils.findProjectsFor(file).forEach(p -> changedConfiguration(oldFileUri,
|
||||||
|
@ -189,7 +190,7 @@ class LSPFileEventManager {
|
||||||
if (!FileUtils.isFileSupported(file)) {
|
if (!FileUtils.isFileSupported(file)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String uri = FileUtils.VFSToURI(file);
|
String uri = FileUtil.URIFromVirtualFile(file);
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
ApplicationUtils.invokeAfterPsiEvents(() -> {
|
ApplicationUtils.invokeAfterPsiEvents(() -> {
|
||||||
FileUtils.findProjectsFor(file).forEach(p -> changedConfiguration(uri,
|
FileUtils.findProjectsFor(file).forEach(p -> changedConfiguration(uri,
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.falsepattern.zigbrains.lsp.requests;
|
package com.falsepattern.zigbrains.lsp.requests;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.lsp.contributors.psi.LSPPsiElement;
|
import com.falsepattern.zigbrains.lsp.contributors.psi.LSPPsiElement;
|
||||||
import com.falsepattern.zigbrains.lsp.editor.EditorEventManager;
|
import com.falsepattern.zigbrains.lsp.editor.EditorEventManager;
|
||||||
import com.falsepattern.zigbrains.lsp.editor.EditorEventManagerBase;
|
import com.falsepattern.zigbrains.lsp.editor.EditorEventManagerBase;
|
||||||
|
@ -81,8 +82,8 @@ public class WorkspaceEditHandler {
|
||||||
TextEdit edit = new TextEdit(lspRange, newName);
|
TextEdit edit = new TextEdit(lspRange, newName);
|
||||||
String uri = null;
|
String uri = null;
|
||||||
try {
|
try {
|
||||||
uri = FileUtils.sanitizeURI(
|
uri = FileUtil.sanitizeURI(
|
||||||
new URL(ui.getVirtualFile().getUrl().replace(" ", FileUtils.SPACE_ENCODED)).toURI()
|
new URL(ui.getVirtualFile().getUrl().replace(" ", FileUtil.SPACE_ENCODED)).toURI()
|
||||||
.toString());
|
.toString());
|
||||||
} catch (MalformedURLException | URISyntaxException e) {
|
} catch (MalformedURLException | URISyntaxException e) {
|
||||||
LOG.warn(e);
|
LOG.warn(e);
|
||||||
|
@ -131,7 +132,7 @@ public class WorkspaceEditHandler {
|
||||||
TextDocumentEdit textEdit = tEdit.getLeft();
|
TextDocumentEdit textEdit = tEdit.getLeft();
|
||||||
VersionedTextDocumentIdentifier doc = textEdit.getTextDocument();
|
VersionedTextDocumentIdentifier doc = textEdit.getTextDocument();
|
||||||
int version = doc.getVersion() != null ? doc.getVersion() : Integer.MAX_VALUE;
|
int version = doc.getVersion() != null ? doc.getVersion() : Integer.MAX_VALUE;
|
||||||
String uri = FileUtils.sanitizeURI(doc.getUri());
|
String uri = FileUtil.sanitizeURI(doc.getUri());
|
||||||
EditorEventManager manager = EditorEventManagerBase.forUri(uri);
|
EditorEventManager manager = EditorEventManagerBase.forUri(uri);
|
||||||
if (manager != null) {
|
if (manager != null) {
|
||||||
curProject[0] = manager.editor.getProject();
|
curProject[0] = manager.editor.getProject();
|
||||||
|
@ -151,7 +152,7 @@ public class WorkspaceEditHandler {
|
||||||
|
|
||||||
} else if (changes != null) {
|
} else if (changes != null) {
|
||||||
changes.forEach((key, lChanges) -> {
|
changes.forEach((key, lChanges) -> {
|
||||||
String uri = FileUtils.sanitizeURI(key);
|
String uri = FileUtil.sanitizeURI(key);
|
||||||
|
|
||||||
EditorEventManager manager = EditorEventManagerBase.forUri(uri);
|
EditorEventManager manager = EditorEventManagerBase.forUri(uri);
|
||||||
if (manager != null) {
|
if (manager != null) {
|
||||||
|
@ -198,12 +199,12 @@ public class WorkspaceEditHandler {
|
||||||
Project[] projects = ProjectManager.getInstance().getOpenProjects();
|
Project[] projects = ProjectManager.getInstance().getOpenProjects();
|
||||||
//Infer the project from the uri
|
//Infer the project from the uri
|
||||||
Project project = Stream.of(projects)
|
Project project = Stream.of(projects)
|
||||||
.map(p -> new ImmutablePair<>(FileUtils.VFSToURI(ProjectUtil.guessProjectDir(p)), p))
|
.map(p -> new ImmutablePair<>(FileUtil.URIFromVirtualFile(ProjectUtil.guessProjectDir(p)), p))
|
||||||
.filter(p -> uri.startsWith(p.getLeft())).sorted(Collections.reverseOrder())
|
.filter(p -> uri.startsWith(p.getLeft())).sorted(Collections.reverseOrder())
|
||||||
.map(ImmutablePair::getRight).findFirst().orElse(projects[0]);
|
.map(ImmutablePair::getRight).findFirst().orElse(projects[0]);
|
||||||
VirtualFile file = null;
|
VirtualFile file = null;
|
||||||
try {
|
try {
|
||||||
file = LocalFileSystem.getInstance().findFileByIoFile(new File(new URI(FileUtils.sanitizeURI(uri))));
|
file = LocalFileSystem.getInstance().findFileByIoFile(new File(new URI(FileUtil.sanitizeURI(uri))));
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
LOG.warn(e);
|
LOG.warn(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.falsepattern.zigbrains.lsp.utils;
|
package com.falsepattern.zigbrains.lsp.utils;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
import com.falsepattern.zigbrains.lsp.IntellijLanguageClient;
|
||||||
import com.falsepattern.zigbrains.lsp.extensions.LSPExtensionManager;
|
import com.falsepattern.zigbrains.lsp.extensions.LSPExtensionManager;
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
|
@ -28,7 +29,6 @@ import com.intellij.openapi.fileTypes.FileType;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.project.ProjectManager;
|
import com.intellij.openapi.project.ProjectManager;
|
||||||
import com.intellij.openapi.util.io.FileUtilRt;
|
import com.intellij.openapi.util.io.FileUtilRt;
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiDocumentManager;
|
import com.intellij.psi.PsiDocumentManager;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
|
@ -40,8 +40,6 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -56,13 +54,6 @@ import static com.falsepattern.zigbrains.lsp.utils.ApplicationUtils.computableRe
|
||||||
* Various file / uri related methods
|
* Various file / uri related methods
|
||||||
*/
|
*/
|
||||||
public class FileUtils {
|
public class FileUtils {
|
||||||
private final static OS os = (System.getProperty("os.name").toLowerCase().contains("win")) ? OS.WINDOWS : OS.UNIX;
|
|
||||||
private final static String COLON_ENCODED = "%3A";
|
|
||||||
public final static String SPACE_ENCODED = "%20";
|
|
||||||
private final static String URI_FILE_BEGIN = "file:";
|
|
||||||
private final static String URI_VALID_FILE_BEGIN = "file:///";
|
|
||||||
private final static char URI_PATH_SEP = '/';
|
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getInstance(FileUtils.class);
|
private static final Logger LOG = Logger.getInstance(FileUtils.class);
|
||||||
|
|
||||||
public static List<Editor> getAllOpenedEditors(Project project) {
|
public static List<Editor> getAllOpenedEditors(Project project) {
|
||||||
|
@ -83,7 +74,7 @@ public class FileUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Editor> getAllOpenedEditorsForUri(@NotNull Project project, String uri) {
|
public static List<Editor> getAllOpenedEditorsForUri(@NotNull Project project, String uri) {
|
||||||
VirtualFile file = virtualFileFromURI(uri);
|
VirtualFile file = FileUtil.virtualFileFromURI(uri);
|
||||||
if (file == null)
|
if (file == null)
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
return getAllOpenedEditorsForVirtualFile(project, file);
|
return getAllOpenedEditorsForVirtualFile(project, file);
|
||||||
|
@ -106,38 +97,13 @@ public class FileUtils {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This can be used to instantly apply a language server definition without restarting the IDE.
|
|
||||||
*/
|
|
||||||
public static void reloadAllEditors() {
|
|
||||||
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
|
|
||||||
for (Project project : openProjects) {
|
|
||||||
reloadEditors(project);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This can be used to instantly apply a project-specific language server definition without restarting the
|
|
||||||
* project/IDE.
|
|
||||||
*
|
|
||||||
* @param project The project instance which need to be restarted
|
|
||||||
*/
|
|
||||||
public static void reloadEditors(@NotNull Project project) {
|
|
||||||
try {
|
|
||||||
List<Editor> allOpenedEditors = FileUtils.getAllOpenedEditors(project);
|
|
||||||
allOpenedEditors.forEach(IntellijLanguageClient::editorClosed);
|
|
||||||
allOpenedEditors.forEach(IntellijLanguageClient::editorOpened);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.warn(String.format("Refreshing project: %s is failed due to: ", project.getName()), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Editor editorFromPsiFile(PsiFile psiFile) {
|
public static Editor editorFromPsiFile(PsiFile psiFile) {
|
||||||
return editorFromVirtualFile(psiFile.getVirtualFile(), psiFile.getProject());
|
return editorFromVirtualFile(psiFile.getVirtualFile(), psiFile.getProject());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Editor editorFromUri(String uri, Project project) {
|
public static Editor editorFromUri(String uri, Project project) {
|
||||||
return editorFromVirtualFile(virtualFileFromURI(uri), project);
|
return editorFromVirtualFile(FileUtil.virtualFileFromURI(uri), project);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -149,15 +115,6 @@ public class FileUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VirtualFile virtualFileFromURI(String uri) {
|
|
||||||
try {
|
|
||||||
return LocalFileSystem.getInstance().findFileByIoFile(new File(new URI(sanitizeURI(uri))));
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
LOG.warn(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a file type given an editor
|
* Returns a file type given an editor
|
||||||
*
|
*
|
||||||
|
@ -185,79 +142,14 @@ public class FileUtils {
|
||||||
* @return The URI
|
* @return The URI
|
||||||
*/
|
*/
|
||||||
public static String editorToURIString(Editor editor) {
|
public static String editorToURIString(Editor editor) {
|
||||||
return sanitizeURI(VFSToURI(FileDocumentManager.getInstance().getFile(editor.getDocument())));
|
return FileUtil.sanitizeURI(
|
||||||
|
FileUtil.URIFromVirtualFile(FileDocumentManager.getInstance().getFile(editor.getDocument())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VirtualFile virtualFileFromEditor(Editor editor) {
|
public static VirtualFile virtualFileFromEditor(Editor editor) {
|
||||||
return FileDocumentManager.getInstance().getFile(editor.getDocument());
|
return FileDocumentManager.getInstance().getFile(editor.getDocument());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the URI string corresponding to a VirtualFileSystem file
|
|
||||||
*
|
|
||||||
* @param file The file
|
|
||||||
* @return the URI
|
|
||||||
*/
|
|
||||||
public static String VFSToURI(VirtualFile file) {
|
|
||||||
return file == null? null : pathToUri(file.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fixes common problems in uri, mainly related to Windows
|
|
||||||
*
|
|
||||||
* @param uri The uri to sanitize
|
|
||||||
* @return The sanitized uri
|
|
||||||
*/
|
|
||||||
public static String sanitizeURI(String uri) {
|
|
||||||
if (uri != null) {
|
|
||||||
StringBuilder reconstructed = new StringBuilder();
|
|
||||||
String uriCp = uri.replaceAll(" ", SPACE_ENCODED); //Don't trust servers
|
|
||||||
if (!uri.startsWith(URI_FILE_BEGIN)) {
|
|
||||||
LOG.warn("Malformed uri : " + uri);
|
|
||||||
return uri; //Probably not an uri
|
|
||||||
} else {
|
|
||||||
uriCp = uriCp.substring(URI_FILE_BEGIN.length());
|
|
||||||
while (uriCp.startsWith(Character.toString(URI_PATH_SEP))) {
|
|
||||||
uriCp = uriCp.substring(1);
|
|
||||||
}
|
|
||||||
reconstructed.append(URI_VALID_FILE_BEGIN);
|
|
||||||
if (os == OS.UNIX) {
|
|
||||||
return reconstructed.append(uriCp).toString();
|
|
||||||
} else {
|
|
||||||
reconstructed.append(uriCp.substring(0, uriCp.indexOf(URI_PATH_SEP)));
|
|
||||||
char driveLetter = reconstructed.charAt(URI_VALID_FILE_BEGIN.length());
|
|
||||||
if (Character.isLowerCase(driveLetter)) {
|
|
||||||
reconstructed.setCharAt(URI_VALID_FILE_BEGIN.length(), Character.toUpperCase(driveLetter));
|
|
||||||
}
|
|
||||||
if (reconstructed.toString().endsWith(COLON_ENCODED)) {
|
|
||||||
reconstructed.delete(reconstructed.length() - 3, reconstructed.length());
|
|
||||||
}
|
|
||||||
if (!reconstructed.toString().endsWith(":")) {
|
|
||||||
reconstructed.append(":");
|
|
||||||
}
|
|
||||||
return reconstructed.append(uriCp.substring(uriCp.indexOf(URI_PATH_SEP))).toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms an URI string into a VFS file
|
|
||||||
*
|
|
||||||
* @param uri The uri
|
|
||||||
* @return The virtual file
|
|
||||||
*/
|
|
||||||
public static VirtualFile URIToVFS(String uri) {
|
|
||||||
try {
|
|
||||||
return LocalFileSystem.getInstance().findFileByIoFile(new File(new URI(sanitizeURI(uri))));
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
LOG.warn(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the project base dir uri given an editor
|
* Returns the project base dir uri given an editor
|
||||||
*
|
*
|
||||||
|
@ -265,7 +157,7 @@ public class FileUtils {
|
||||||
* @return The project whose the editor belongs
|
* @return The project whose the editor belongs
|
||||||
*/
|
*/
|
||||||
public static String editorToProjectFolderUri(Editor editor) {
|
public static String editorToProjectFolderUri(Editor editor) {
|
||||||
return pathToUri(editorToProjectFolderPath(editor));
|
return FileUtil.pathToUri(editorToProjectFolderPath(editor));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String editorToProjectFolderPath(Editor editor) {
|
public static String editorToProjectFolderPath(Editor editor) {
|
||||||
|
@ -275,51 +167,15 @@ public class FileUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms a path into an URI string
|
|
||||||
*
|
|
||||||
* @param path The path
|
|
||||||
* @return The uri
|
|
||||||
*/
|
|
||||||
public static String pathToUri(@Nullable String path) {
|
|
||||||
return path != null ? sanitizeURI(new File(path).toURI().toString()) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String projectToUri(Project project) {
|
public static String projectToUri(Project project) {
|
||||||
if (project != null && project.getBasePath() != null) {
|
if (project != null && project.getBasePath() != null) {
|
||||||
return pathToUri(new File(project.getBasePath()).getAbsolutePath());
|
return FileUtil.pathToUri(new File(project.getBasePath()).getAbsolutePath());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String documentToUri(Document document) {
|
public static String documentToUri(Document document) {
|
||||||
return sanitizeURI(VFSToURI(FileDocumentManager.getInstance().getFile(document)));
|
return FileUtil.sanitizeURI(FileUtil.URIFromVirtualFile(FileDocumentManager.getInstance().getFile(document)));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Object representing the OS type (Windows or Unix)
|
|
||||||
*/
|
|
||||||
public enum OS {
|
|
||||||
WINDOWS, UNIX
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the given virtual file instance is supported by this LS client library.
|
|
||||||
*/
|
|
||||||
public static boolean isFileSupported(@Nullable VirtualFile file) {
|
|
||||||
if (file == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file instanceof LightVirtualFileBase) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getUrl().isEmpty() || file.getUrl().startsWith("jar:")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return IntellijLanguageClient.isExtensionSupported(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -341,6 +197,51 @@ public class FileUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This can be used to instantly apply a language server definition without restarting the IDE.
|
||||||
|
*/
|
||||||
|
public static void reloadAllEditors() {
|
||||||
|
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
|
||||||
|
for (Project project : openProjects) {
|
||||||
|
reloadEditors(project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This can be used to instantly apply a project-specific language server definition without restarting the
|
||||||
|
* project/IDE.
|
||||||
|
*
|
||||||
|
* @param project The project instance which need to be restarted
|
||||||
|
*/
|
||||||
|
public static void reloadEditors(@NotNull Project project) {
|
||||||
|
try {
|
||||||
|
List<Editor> allOpenedEditors = FileUtils.getAllOpenedEditors(project);
|
||||||
|
allOpenedEditors.forEach(IntellijLanguageClient::editorClosed);
|
||||||
|
allOpenedEditors.forEach(IntellijLanguageClient::editorOpened);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.warn(String.format("Refreshing project: %s is failed due to: ", project.getName()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given virtual file instance is supported by this LS client library.
|
||||||
|
*/
|
||||||
|
public static boolean isFileSupported(@Nullable VirtualFile file) {
|
||||||
|
if (file == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file instanceof LightVirtualFileBase) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.getUrl().isEmpty() || file.getUrl().startsWith("jar:")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntellijLanguageClient.isExtensionSupported(file);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the file in editor is supported by this LS client library.
|
* Checks if the file in editor is supported by this LS client library.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023-2024 FalsePattern
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.project.console;
|
||||||
|
|
||||||
|
import com.intellij.execution.filters.ConsoleFilterProvider;
|
||||||
|
import com.intellij.execution.filters.Filter;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class ZigConsoleFilterProvider implements ConsoleFilterProvider {
|
||||||
|
@Override
|
||||||
|
public Filter @NotNull [] getDefaultFilters(@NotNull Project project) {
|
||||||
|
return new Filter[]{new ZigSourceFileFilter(project)};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023-2024 FalsePattern
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.project.console;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.FileUtil;
|
||||||
|
import com.falsepattern.zigbrains.project.openapi.module.ZigModuleType;
|
||||||
|
import com.intellij.execution.filters.Filter;
|
||||||
|
import com.intellij.execution.filters.OpenFileHyperlinkInfo;
|
||||||
|
import com.intellij.ide.impl.ProjectUtil;
|
||||||
|
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||||
|
import com.intellij.openapi.module.ModuleUtil;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.val;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ZigSourceFileFilter implements Filter {
|
||||||
|
private final Project project;
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Result applyFilter(@NotNull String line, int entireLength) {
|
||||||
|
val lineStart = entireLength - line.length();
|
||||||
|
int splitA, splitB, splitC;
|
||||||
|
splitA = line.indexOf(':');
|
||||||
|
if (splitA < 0)
|
||||||
|
return null;
|
||||||
|
splitB = line.indexOf(':', splitA + 1);
|
||||||
|
if (splitB < 0)
|
||||||
|
return null;
|
||||||
|
splitC = line.indexOf(':', splitB + 1);
|
||||||
|
if (splitC < 0)
|
||||||
|
return null;
|
||||||
|
final int lineNumber, lineOffset;
|
||||||
|
try {
|
||||||
|
lineNumber = Math.max(Integer.parseInt(line, splitA + 1, splitB, 10) - 1, 0);
|
||||||
|
lineOffset = Math.max(Integer.parseInt(line, splitB + 1, splitC, 10) - 1, 0);
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
val pathStr = line.substring(0, splitA);
|
||||||
|
var path = Path.of(pathStr);
|
||||||
|
if (!Files.exists(path) || !Files.isRegularFile(path)) {
|
||||||
|
val projectPath = project.getBasePath();
|
||||||
|
if (projectPath == null)
|
||||||
|
return null;
|
||||||
|
path = Path.of(projectPath, pathStr);
|
||||||
|
if (!Files.exists(path) || !Files.isRegularFile(path))
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
val file = FileUtil.virtualFileFromURI(path.toUri());
|
||||||
|
return new Result(lineStart, lineStart + splitC, new OpenFileHyperlinkInfo(project, file, lineNumber, lineOffset));
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,13 +18,17 @@ package com.falsepattern.zigbrains.project.execution;
|
||||||
|
|
||||||
import com.intellij.execution.ExecutionException;
|
import com.intellij.execution.ExecutionException;
|
||||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||||
|
import com.intellij.execution.process.CapturingAnsiEscapesAwareProcessHandler;
|
||||||
import com.intellij.execution.process.CapturingProcessHandler;
|
import com.intellij.execution.process.CapturingProcessHandler;
|
||||||
|
import com.intellij.execution.process.ColoredProcessHandler;
|
||||||
|
import com.intellij.execution.process.KillableColoredProcessHandler;
|
||||||
|
import com.intellij.execution.process.ProcessOutput;
|
||||||
import com.intellij.util.io.BaseOutputReader;
|
import com.intellij.util.io.BaseOutputReader;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class ZigCapturingProcessHandler extends CapturingProcessHandler {
|
public class ZigCapturingProcessHandler extends CapturingAnsiEscapesAwareProcessHandler {
|
||||||
public static Optional<ZigCapturingProcessHandler> startProcess(GeneralCommandLine commandLine) {
|
public static Optional<ZigCapturingProcessHandler> startProcess(GeneralCommandLine commandLine) {
|
||||||
try {
|
try {
|
||||||
return Optional.of(new ZigCapturingProcessHandler(commandLine));
|
return Optional.of(new ZigCapturingProcessHandler(commandLine));
|
||||||
|
|
|
@ -20,6 +20,7 @@ import com.falsepattern.zigbrains.project.execution.ZigCapturingProcessHandler;
|
||||||
import com.falsepattern.zigbrains.project.runconfig.ZigProcessHandler;
|
import com.falsepattern.zigbrains.project.runconfig.ZigProcessHandler;
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||||
import com.falsepattern.zigbrains.project.util.ProjectUtil;
|
import com.falsepattern.zigbrains.project.util.ProjectUtil;
|
||||||
|
import com.intellij.build.BuildTextConsoleView;
|
||||||
import com.intellij.execution.DefaultExecutionResult;
|
import com.intellij.execution.DefaultExecutionResult;
|
||||||
import com.intellij.execution.ExecutionException;
|
import com.intellij.execution.ExecutionException;
|
||||||
import com.intellij.execution.configurations.CommandLineState;
|
import com.intellij.execution.configurations.CommandLineState;
|
||||||
|
@ -31,6 +32,7 @@ import lombok.val;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public abstract class ProfileStateBase<T extends ZigExecConfigBase<T>> extends CommandLineState {
|
public abstract class ProfileStateBase<T extends ZigExecConfigBase<T>> extends CommandLineState {
|
||||||
protected final T configuration;
|
protected final T configuration;
|
||||||
|
@ -42,7 +44,7 @@ public abstract class ProfileStateBase<T extends ZigExecConfigBase<T>> extends C
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected @NotNull ProcessHandler startProcess() throws ExecutionException {
|
protected @NotNull ProcessHandler startProcess() throws ExecutionException {
|
||||||
return new ZigCapturingProcessHandler(getCommandLine(ProjectUtil.getToolchain(getEnvironment().getProject())));
|
return new ZigProcessHandler(getCommandLine(ProjectUtil.getToolchain(getEnvironment().getProject())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeneralCommandLine getCommandLine(AbstractZigToolchain toolchain) {
|
public GeneralCommandLine getCommandLine(AbstractZigToolchain toolchain) {
|
||||||
|
@ -63,7 +65,7 @@ public abstract class ProfileStateBase<T extends ZigExecConfigBase<T>> extends C
|
||||||
public DefaultExecutionResult executeCommandLine(GeneralCommandLine commandLine, ExecutionEnvironment environment)
|
public DefaultExecutionResult executeCommandLine(GeneralCommandLine commandLine, ExecutionEnvironment environment)
|
||||||
throws ExecutionException {
|
throws ExecutionException {
|
||||||
val handler = startProcess(commandLine);
|
val handler = startProcess(commandLine);
|
||||||
val console = getConsoleBuilder().getConsole();
|
val console = new BuildTextConsoleView(environment.getProject(), true, Collections.emptyList());
|
||||||
console.attachToProcess(handler);
|
console.attachToProcess(handler);
|
||||||
return new DefaultExecutionResult(console, handler);
|
return new DefaultExecutionResult(console, handler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,71 +22,133 @@ import com.intellij.openapi.options.ConfigurationException;
|
||||||
import com.intellij.openapi.options.SettingsEditor;
|
import com.intellij.openapi.options.SettingsEditor;
|
||||||
import com.intellij.openapi.ui.LabeledComponent;
|
import com.intellij.openapi.ui.LabeledComponent;
|
||||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||||
|
import com.intellij.ui.components.JBCheckBox;
|
||||||
import com.intellij.ui.dsl.builder.AlignX;
|
import com.intellij.ui.dsl.builder.AlignX;
|
||||||
import com.intellij.ui.dsl.builder.AlignY;
|
import com.intellij.ui.dsl.builder.AlignY;
|
||||||
import com.intellij.ui.dsl.builder.Panel;
|
import com.intellij.ui.dsl.builder.Panel;
|
||||||
|
import lombok.val;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static com.intellij.ui.dsl.builder.BuilderKt.panel;
|
import static com.intellij.ui.dsl.builder.BuilderKt.panel;
|
||||||
|
|
||||||
public class ZigConfigEditor<T extends ZigExecConfigBase<T>> extends SettingsEditor<T> {
|
public class ZigConfigEditor<T extends ZigExecConfigBase<T>> extends SettingsEditor<T> {
|
||||||
protected final LabeledComponent<TextFieldWithBrowseButton> workingDirectoryComponent =
|
private final List<ZigConfigModule<T>> modules;
|
||||||
new WorkingDirectoryComponent();
|
|
||||||
|
public ZigConfigEditor(List<ZigConfigModule<T>> modules) {
|
||||||
|
this.modules = new ArrayList<>(modules);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyEditorTo(@NotNull T s) throws ConfigurationException {
|
protected void applyEditorTo(@NotNull T s) throws ConfigurationException {
|
||||||
s.workingDirectory = Paths.get(workingDirectoryComponent.getComponent().getText());
|
for (val module: modules) {
|
||||||
|
module.applyTo(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void resetEditorFrom(@NotNull T s) {
|
protected void resetEditorFrom(@NotNull T s) {
|
||||||
workingDirectoryComponent.getComponent().setText(Objects.requireNonNullElse(s.workingDirectory, "").toString());
|
for (val module: modules) {
|
||||||
|
module.resetFrom(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final @NotNull JComponent createEditor() {
|
protected final @NotNull JComponent createEditor() {
|
||||||
return panel((p) -> {
|
return panel((p) -> {
|
||||||
constructPanel(p);
|
for (val module: modules) {
|
||||||
|
module.construct(p);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void constructPanel(Panel p) {
|
public interface ZigConfigModule<T> {
|
||||||
|
void applyTo(@NotNull T s) throws ConfigurationException;
|
||||||
|
void resetFrom(@NotNull T s);
|
||||||
|
void construct(Panel p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class WorkingDirectoryModule<T extends ZigExecConfigBase<T>> implements ZigConfigModule<T> {
|
||||||
|
protected final LabeledComponent<TextFieldWithBrowseButton> workingDirectoryComponent =
|
||||||
|
new WorkingDirectoryComponent();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTo(@NotNull T s) {
|
||||||
|
s.workingDirectory = Paths.get(workingDirectoryComponent.getComponent().getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetFrom(@NotNull T s) {
|
||||||
|
workingDirectoryComponent.getComponent().setText(Objects.requireNonNullElse(s.workingDirectory, "").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void construct(Panel p) {
|
||||||
p.row(workingDirectoryComponent.getLabel(), (r) -> {
|
p.row(workingDirectoryComponent.getLabel(), (r) -> {
|
||||||
r.cell(workingDirectoryComponent).resizableColumn().align(AlignX.FILL).align(AlignY.FILL);
|
r.cell(workingDirectoryComponent).resizableColumn().align(AlignX.FILL).align(AlignY.FILL);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static abstract class WithFilePath<T extends ZigExecConfigBase<T>> extends ZigConfigEditor<T> {
|
public static class FilePathModule<T extends ZigExecConfigBase<T> & FilePathModule.Carrier> implements ZigConfigModule<T> {
|
||||||
private final ZigFilePathPanel filePathPanel = new ZigFilePathPanel();
|
private final ZigFilePathPanel filePathPanel = new ZigFilePathPanel();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyEditorTo(@NotNull T s) throws ConfigurationException {
|
public void applyTo(@NotNull T s) {
|
||||||
super.applyEditorTo(s);
|
s.setFilePath(filePathPanel.getText());
|
||||||
setFilePath(s, filePathPanel.getText());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void resetEditorFrom(@NotNull T s) {
|
public void resetFrom(@NotNull T s) {
|
||||||
super.resetEditorFrom(s);
|
filePathPanel.setText(Objects.requireNonNullElse(s.getFilePath(), ""));
|
||||||
filePathPanel.setText(Objects.requireNonNullElse(getFilePath(s), ""));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void constructPanel(Panel p) {
|
public void construct(Panel p) {
|
||||||
super.constructPanel(p);
|
|
||||||
p.row("Target file", (r) -> {
|
p.row("Target file", (r) -> {
|
||||||
r.cell(filePathPanel).resizableColumn().align(AlignX.FILL).align(AlignY.FILL);
|
r.cell(filePathPanel).resizableColumn().align(AlignX.FILL).align(AlignY.FILL);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String getFilePath(T config);
|
public interface Carrier {
|
||||||
protected abstract void setFilePath(T config, String path);
|
void setFilePath(String path);
|
||||||
|
String getFilePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ColoredModule<T extends ZigExecConfigBase<T> & ColoredModule.Carrier> implements ZigConfigModule<T> {
|
||||||
|
private final JBCheckBox checkBox = new JBCheckBox();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTo(@NotNull T s) throws ConfigurationException {
|
||||||
|
s.setColored(checkBox.isSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetFrom(@NotNull T s) {
|
||||||
|
checkBox.setSelected(s.isColored());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void construct(Panel p) {
|
||||||
|
p.row("Colored terminal", (r) -> {
|
||||||
|
r.cell(checkBox);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface Carrier {
|
||||||
|
void setColored(boolean color);
|
||||||
|
boolean isColored();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,17 +16,26 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.execution.base;
|
package com.falsepattern.zigbrains.project.execution.base;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.util.ElementUtil;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.execution.ExecutionException;
|
import com.intellij.execution.ExecutionException;
|
||||||
import com.intellij.execution.Executor;
|
import com.intellij.execution.Executor;
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory;
|
import com.intellij.execution.configurations.ConfigurationFactory;
|
||||||
import com.intellij.execution.configurations.LocatableConfigurationBase;
|
import com.intellij.execution.configurations.LocatableConfigurationBase;
|
||||||
|
import com.intellij.execution.configurations.RunConfiguration;
|
||||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||||
|
import com.intellij.openapi.options.SettingsEditor;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.util.InvalidDataException;
|
||||||
import com.intellij.openapi.util.NlsActions;
|
import com.intellij.openapi.util.NlsActions;
|
||||||
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.nio.file.InvalidPathException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public abstract class ZigExecConfigBase<T extends ZigExecConfigBase<T>> extends LocatableConfigurationBase<ProfileStateBase<T>> {
|
public abstract class ZigExecConfigBase<T extends ZigExecConfigBase<T>> extends LocatableConfigurationBase<ProfileStateBase<T>> {
|
||||||
|
@ -38,6 +47,30 @@ public abstract class ZigExecConfigBase<T extends ZigExecConfigBase<T>> extends
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
|
||||||
|
return new ZigConfigEditor<>(getEditorConfigModules());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readExternal(@NotNull Element element) throws InvalidDataException {
|
||||||
|
super.readExternal(element);
|
||||||
|
ElementUtil.readString(element, "workingDirectory").ifPresent(dir -> {
|
||||||
|
try {
|
||||||
|
workingDirectory = Path.of(dir);
|
||||||
|
} catch (InvalidPathException ignored) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeExternal(@NotNull Element element) {
|
||||||
|
super.writeExternal(element);
|
||||||
|
if (workingDirectory != null)
|
||||||
|
ElementUtil.writeString(element, "workingDirectory", workingDirectory.toString());
|
||||||
|
}
|
||||||
|
|
||||||
public abstract String[] buildCommandLineArgs();
|
public abstract String[] buildCommandLineArgs();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,4 +80,7 @@ public abstract class ZigExecConfigBase<T extends ZigExecConfigBase<T>> extends
|
||||||
public abstract @Nullable ProfileStateBase<T> getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment)
|
public abstract @Nullable ProfileStateBase<T> getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment)
|
||||||
throws ExecutionException;
|
throws ExecutionException;
|
||||||
|
|
||||||
|
public @NotNull List<ZigConfigEditor.@NotNull ZigConfigModule<T>> getEditorConfigModules() {
|
||||||
|
return new ArrayList<>(List.of(new ZigConfigEditor.WorkingDirectoryModule<>()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,23 +29,30 @@ import com.intellij.ui.components.JBTextField;
|
||||||
import com.intellij.ui.dsl.builder.AlignX;
|
import com.intellij.ui.dsl.builder.AlignX;
|
||||||
import com.intellij.ui.dsl.builder.AlignY;
|
import com.intellij.ui.dsl.builder.AlignY;
|
||||||
import com.intellij.ui.dsl.builder.Panel;
|
import com.intellij.ui.dsl.builder.Panel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.apache.groovy.util.Arrays;
|
import org.apache.groovy.util.Arrays;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ZigExecConfigBuild extends ZigExecConfigBase<ZigExecConfigBuild> {
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ZigExecConfigBuild extends ZigExecConfigBase<ZigExecConfigBuild> implements
|
||||||
|
ZigConfigEditor.ColoredModule.Carrier {
|
||||||
public String extraArguments = "";
|
public String extraArguments = "";
|
||||||
|
public boolean colored = true;
|
||||||
public ZigExecConfigBuild(@NotNull Project project, @NotNull ConfigurationFactory factory) {
|
public ZigExecConfigBuild(@NotNull Project project, @NotNull ConfigurationFactory factory) {
|
||||||
super(project, factory, "Zig Build");
|
super(project, factory, "Zig Build");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] buildCommandLineArgs() {
|
public String[] buildCommandLineArgs() {
|
||||||
val base = new String[]{"build"};
|
val base = new String[]{"build", "--color", colored ? "on" : "off"};
|
||||||
if (extraArguments.isBlank()) {
|
if (extraArguments.isBlank()) {
|
||||||
return base;
|
return base;
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,8 +66,11 @@ public class ZigExecConfigBuild extends ZigExecConfigBase<ZigExecConfigBuild> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull Editor getConfigurationEditor() {
|
public @NotNull List<ZigConfigEditor.ZigConfigModule<ZigExecConfigBuild>> getEditorConfigModules() {
|
||||||
return new Editor();
|
val arr = super.getEditorConfigModules();
|
||||||
|
arr.add(new ExtraArgsModule());
|
||||||
|
arr.add(new ZigConfigEditor.ColoredModule<>());
|
||||||
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -72,10 +82,8 @@ public class ZigExecConfigBuild extends ZigExecConfigBase<ZigExecConfigBuild> {
|
||||||
public void readExternal(@NotNull Element element) throws InvalidDataException {
|
public void readExternal(@NotNull Element element) throws InvalidDataException {
|
||||||
super.readExternal(element);
|
super.readExternal(element);
|
||||||
|
|
||||||
val extraArguments = ElementUtil.readString(element, "extraArguments");
|
ElementUtil.readString(element, "extraArguments").ifPresent(x -> extraArguments = x);
|
||||||
if (extraArguments != null) {
|
ElementUtil.readBoolean(element, "colored").ifPresent(x -> colored = x);
|
||||||
this.extraArguments = extraArguments;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -83,26 +91,24 @@ public class ZigExecConfigBuild extends ZigExecConfigBase<ZigExecConfigBuild> {
|
||||||
super.writeExternal(element);
|
super.writeExternal(element);
|
||||||
|
|
||||||
ElementUtil.writeString(element, "extraArguments", extraArguments);
|
ElementUtil.writeString(element, "extraArguments", extraArguments);
|
||||||
|
ElementUtil.writeBoolean(element, "colored", colored);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Editor extends ZigConfigEditor<ZigExecConfigBuild> {
|
public static class ExtraArgsModule implements ZigConfigEditor.ZigConfigModule<ZigExecConfigBuild> {
|
||||||
private final JBTextField extraArgs = new JBTextField();
|
private final JBTextField extraArgs = new JBTextField();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyEditorTo(@NotNull ZigExecConfigBuild s) throws ConfigurationException {
|
public void applyTo(@NotNull ZigExecConfigBuild s) throws ConfigurationException {
|
||||||
super.applyEditorTo(s);
|
|
||||||
s.extraArguments = extraArgs.getText();
|
s.extraArguments = extraArgs.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void resetEditorFrom(@NotNull ZigExecConfigBuild s) {
|
public void resetFrom(@NotNull ZigExecConfigBuild s) {
|
||||||
super.resetEditorFrom(s);
|
|
||||||
extraArgs.setText(Objects.requireNonNullElse(s.extraArguments, ""));
|
extraArgs.setText(Objects.requireNonNullElse(s.extraArguments, ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void constructPanel(Panel p) {
|
public void construct(Panel p) {
|
||||||
super.constructPanel(p);
|
|
||||||
p.row("Extra arguments", (r) -> {
|
p.row("Extra arguments", (r) -> {
|
||||||
r.cell(extraArgs).resizableColumn().align(AlignX.FILL).align(AlignY.FILL);
|
r.cell(extraArgs).resizableColumn().align(AlignX.FILL).align(AlignY.FILL);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -26,21 +26,26 @@ import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.InvalidDataException;
|
import com.intellij.openapi.util.InvalidDataException;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import lombok.val;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
public class ZigExecConfigRun extends ZigExecConfigBase<ZigExecConfigRun> {
|
public class ZigExecConfigRun extends ZigExecConfigBase<ZigExecConfigRun> implements
|
||||||
|
ZigConfigEditor.FilePathModule.Carrier, ZigConfigEditor.ColoredModule.Carrier {
|
||||||
public String filePath = "";
|
public String filePath = "";
|
||||||
|
public boolean colored = true;
|
||||||
public ZigExecConfigRun(@NotNull Project project, @NotNull ConfigurationFactory factory) {
|
public ZigExecConfigRun(@NotNull Project project, @NotNull ConfigurationFactory factory) {
|
||||||
super(project, factory, "Zig Run");
|
super(project, factory, "Zig Run");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] buildCommandLineArgs() {
|
public String[] buildCommandLineArgs() {
|
||||||
return new String[]{"run", filePath};
|
return new String[]{"run", "--color", colored ? "on" : "off", filePath};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,8 +54,11 @@ public class ZigExecConfigRun extends ZigExecConfigBase<ZigExecConfigRun> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull Editor getConfigurationEditor() {
|
public @NotNull List<ZigConfigEditor.ZigConfigModule<ZigExecConfigRun>> getEditorConfigModules() {
|
||||||
return new Editor();
|
val modules = super.getEditorConfigModules();
|
||||||
|
modules.add(new ZigConfigEditor.FilePathModule<>());
|
||||||
|
modules.add(new ZigConfigEditor.ColoredModule<>());
|
||||||
|
return modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,10 +70,8 @@ public class ZigExecConfigRun extends ZigExecConfigBase<ZigExecConfigRun> {
|
||||||
public void readExternal(@NotNull Element element) throws InvalidDataException {
|
public void readExternal(@NotNull Element element) throws InvalidDataException {
|
||||||
super.readExternal(element);
|
super.readExternal(element);
|
||||||
|
|
||||||
var filePath = ElementUtil.readString(element, "filePath");
|
ElementUtil.readString(element, "filePath").ifPresent(x -> filePath = x);
|
||||||
if (filePath != null) {
|
ElementUtil.readBoolean(element, "colored").ifPresent(x -> colored = x);
|
||||||
this.filePath = filePath;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,18 +79,6 @@ public class ZigExecConfigRun extends ZigExecConfigBase<ZigExecConfigRun> {
|
||||||
super.writeExternal(element);
|
super.writeExternal(element);
|
||||||
|
|
||||||
ElementUtil.writeString(element, "filePath", filePath);
|
ElementUtil.writeString(element, "filePath", filePath);
|
||||||
}
|
ElementUtil.writeBoolean(element, "colored", colored);
|
||||||
|
|
||||||
public static class Editor extends ZigConfigEditor.WithFilePath<ZigExecConfigRun> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getFilePath(ZigExecConfigRun config) {
|
|
||||||
return config.filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setFilePath(ZigExecConfigRun config, String path) {
|
|
||||||
config.filePath = path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,24 +19,36 @@ package com.falsepattern.zigbrains.project.execution.test;
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ProfileStateBase;
|
import com.falsepattern.zigbrains.project.execution.base.ProfileStateBase;
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigExecConfigBase;
|
import com.falsepattern.zigbrains.project.execution.base.ZigExecConfigBase;
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigEditor;
|
import com.falsepattern.zigbrains.project.execution.base.ZigConfigEditor;
|
||||||
|
import com.falsepattern.zigbrains.project.util.ElementUtil;
|
||||||
import com.intellij.execution.Executor;
|
import com.intellij.execution.Executor;
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory;
|
import com.intellij.execution.configurations.ConfigurationFactory;
|
||||||
import com.intellij.execution.configurations.RunConfiguration;
|
import com.intellij.execution.configurations.RunConfiguration;
|
||||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||||
import com.intellij.openapi.options.SettingsEditor;
|
import com.intellij.openapi.options.SettingsEditor;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.util.InvalidDataException;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.val;
|
||||||
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class ZigExecConfigTest extends ZigExecConfigBase<ZigExecConfigTest> {
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ZigExecConfigTest extends ZigExecConfigBase<ZigExecConfigTest> implements ZigConfigEditor.FilePathModule.Carrier,
|
||||||
|
ZigConfigEditor.ColoredModule.Carrier {
|
||||||
public String filePath = "";
|
public String filePath = "";
|
||||||
|
public boolean colored = true;
|
||||||
public ZigExecConfigTest(@NotNull Project project, @NotNull ConfigurationFactory factory) {
|
public ZigExecConfigTest(@NotNull Project project, @NotNull ConfigurationFactory factory) {
|
||||||
super(project, factory, "Zig Test");
|
super(project, factory, "Zig Test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] buildCommandLineArgs() {
|
public String[] buildCommandLineArgs() {
|
||||||
return new String[]{"test", filePath};
|
return new String[]{"test", "--color", colored ? "on" : "off", filePath};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -50,20 +62,26 @@ public class ZigExecConfigTest extends ZigExecConfigBase<ZigExecConfigTest> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
|
public void readExternal(@NotNull Element element) throws InvalidDataException {
|
||||||
return new Editor();
|
super.readExternal(element);
|
||||||
}
|
|
||||||
|
|
||||||
public static class Editor extends ZigConfigEditor.WithFilePath<ZigExecConfigTest> {
|
ElementUtil.readString(element, "filePath").ifPresent(x -> filePath = x);
|
||||||
|
ElementUtil.readBoolean(element, "colored").ifPresent(x -> colored = x);
|
||||||
@Override
|
|
||||||
protected String getFilePath(ZigExecConfigTest config) {
|
|
||||||
return config.filePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setFilePath(ZigExecConfigTest config, String path) {
|
public void writeExternal(@NotNull Element element) {
|
||||||
config.filePath = path;
|
super.writeExternal(element);
|
||||||
|
|
||||||
|
ElementUtil.writeString(element, "filePath", filePath);
|
||||||
|
ElementUtil.writeBoolean(element, "colored", colored);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<ZigConfigEditor.ZigConfigModule<ZigExecConfigTest>> getEditorConfigModules() {
|
||||||
|
val modules = super.getEditorConfigModules();
|
||||||
|
modules.add(new ZigConfigEditor.FilePathModule<>());
|
||||||
|
modules.add(new ZigConfigEditor.ColoredModule<>());
|
||||||
|
return modules;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,22 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.runconfig;
|
package com.falsepattern.zigbrains.project.runconfig;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.common.util.StringUtil;
|
||||||
import com.intellij.execution.ExecutionException;
|
import com.intellij.execution.ExecutionException;
|
||||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||||
import com.intellij.execution.configurations.PtyCommandLine;
|
import com.intellij.execution.configurations.PtyCommandLine;
|
||||||
|
import com.intellij.execution.process.AnsiEscapeDecoder;
|
||||||
|
import com.intellij.execution.process.KillableColoredProcessHandler;
|
||||||
import com.intellij.execution.process.KillableProcessHandler;
|
import com.intellij.execution.process.KillableProcessHandler;
|
||||||
|
import com.intellij.openapi.util.Key;
|
||||||
import com.pty4j.PtyProcess;
|
import com.pty4j.PtyProcess;
|
||||||
|
import lombok.val;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class ZigProcessHandler extends KillableProcessHandler {
|
public class ZigProcessHandler extends KillableColoredProcessHandler implements AnsiEscapeDecoder.ColoredTextAcceptor {
|
||||||
public ZigProcessHandler(@NotNull GeneralCommandLine commandLine) throws ExecutionException {
|
public ZigProcessHandler(@NotNull GeneralCommandLine commandLine) throws ExecutionException {
|
||||||
super(commandLine);
|
super(commandLine);
|
||||||
setHasPty(commandLine instanceof PtyCommandLine);
|
setHasPty(commandLine instanceof PtyCommandLine);
|
||||||
|
@ -37,4 +43,9 @@ public class ZigProcessHandler extends KillableProcessHandler {
|
||||||
setHasPty(process instanceof PtyProcess);
|
setHasPty(process instanceof PtyProcess);
|
||||||
setShouldDestroyProcessRecursively(!hasPty());
|
setShouldDestroyProcessRecursively(!hasPty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void coloredTextAvailable(@NotNull String text, @NotNull Key attributes) {
|
||||||
|
super.coloredTextAvailable(StringUtil.translateVT100Escapes(text), attributes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,10 @@ import lombok.val;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class ElementUtil {
|
public class ElementUtil {
|
||||||
public static @Nullable String readString(Element element, String name) {
|
public static Optional<String> readString(Element element, String name) {
|
||||||
return element.getChildren()
|
return element.getChildren()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(it -> it.getName()
|
.filter(it -> it.getName()
|
||||||
|
@ -29,8 +31,7 @@ public class ElementUtil {
|
||||||
it.getAttributeValue("name")
|
it.getAttributeValue("name")
|
||||||
.equals(name))
|
.equals(name))
|
||||||
.findAny()
|
.findAny()
|
||||||
.map(it -> it.getAttributeValue("value"))
|
.map(it -> it.getAttributeValue("value"));
|
||||||
.orElse(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeString(Element element, String name, String value) {
|
public static void writeString(Element element, String name, String value) {
|
||||||
|
@ -40,4 +41,12 @@ public class ElementUtil {
|
||||||
|
|
||||||
element.addContent(option);
|
element.addContent(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void writeBoolean(Element element, String name, boolean state) {
|
||||||
|
writeString(element, name, Boolean.toString(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<Boolean> readBoolean(Element element, String name) {
|
||||||
|
return readString(element, name).map(Boolean::parseBoolean);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,9 @@
|
||||||
bundle="zigbrains.zig.Bundle"
|
bundle="zigbrains.zig.Bundle"
|
||||||
key="notif-zls"
|
key="notif-zls"
|
||||||
id="ZigBrains.ZLS"/>
|
id="ZigBrains.ZLS"/>
|
||||||
|
|
||||||
|
<consoleFilterProvider implementation="com.falsepattern.zigbrains.project.console.ZigConsoleFilterProvider"/>
|
||||||
|
<analyzeStacktraceFilter implementation="com.falsepattern.zigbrains.project.console.ZigSourceFileFilter"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue