chore: better project path management

This commit is contained in:
FalsePattern 2024-03-11 01:22:00 +01:00
parent 6fbf826574
commit 0ebbe1cc9b
Signed by: falsepattern
GPG key ID: E930CDEC50C50E23
6 changed files with 61 additions and 23 deletions

View file

@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.file.Path;
public class FileUtil { public class FileUtil {
private static final Logger LOG = Logger.getInstance(FileUtil.class); private static final Logger LOG = Logger.getInstance(FileUtil.class);
@ -120,6 +121,10 @@ public class FileUtil {
return path != null ? sanitizeURI(new File(path).toURI().toString()) : null; return path != null ? sanitizeURI(new File(path).toURI().toString()) : null;
} }
public static String pathToUri(@Nullable Path path) {
return path != null ? sanitizeURI(path.toUri().toString()) : null;
}
/** /**
* Object representing the OS type (Windows or Unix) * Object representing the OS type (Windows or Unix)
*/ */

View file

@ -28,6 +28,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import lombok.val;
import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.MutablePair;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@ -331,9 +332,14 @@ public class IntellijLanguageClient {
public static void removeWrapper(LanguageServerWrapper wrapper) { public static void removeWrapper(LanguageServerWrapper wrapper) {
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);
val rootPath = wrapper.getProjectRootPath();
if (rootPath == null) {
LOG.error("Project root path is null");
return;
}
val absolutePath = FileUtil.pathToUri(rootPath);
for (String ext : extensions) { for (String ext : extensions) {
MutablePair<String, String> extProjectPair = new MutablePair<>(ext, FileUtil.pathToUri( MutablePair<String, String> extProjectPair = new MutablePair<>(ext, absolutePath);
new File(wrapper.getProjectRootPath()).getAbsolutePath()));
extToLanguageWrapper.remove(extProjectPair); extToLanguageWrapper.remove(extProjectPair);
extToServerDefinition.remove(extProjectPair); extToServerDefinition.remove(extProjectPair);
} }

View file

@ -43,6 +43,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtil;
import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
@ -51,6 +52,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import com.intellij.remoteServer.util.CloudNotifier; import com.intellij.remoteServer.util.CloudNotifier;
import com.intellij.util.PlatformIcons; import com.intellij.util.PlatformIcons;
import lombok.val;
import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.eclipse.lsp4j.ClientCapabilities; import org.eclipse.lsp4j.ClientCapabilities;
@ -104,6 +106,7 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -135,7 +138,8 @@ public class LanguageServerWrapper {
private final LSPExtensionManager extManager; private final LSPExtensionManager extManager;
private final Project project; private final Project project;
private final HashSet<Editor> toConnect = new HashSet<>(); private final HashSet<Editor> toConnect = new HashSet<>();
private final String projectRootPath; @Nullable
private final Path projectRootPath;
private final HashSet<String> urisUnderLspControl = new HashSet<>(); private final HashSet<String> urisUnderLspControl = new HashSet<>();
private final HashSet<Editor> connectedEditors = new HashSet<>(); private final HashSet<Editor> connectedEditors = new HashSet<>();
private final Map<String, Set<EditorEventManager>> uriToEditorManagers = new HashMap<>(); private final Map<String, Set<EditorEventManager>> uriToEditorManagers = new HashMap<>();
@ -166,7 +170,12 @@ public class LanguageServerWrapper {
this.project = project; this.project = project;
// We need to keep the project rootPath in addition to the project instance, since we cannot get the project // We need to keep the project rootPath in addition to the project instance, since we cannot get the project
// base path if the project is disposed. // base path if the project is disposed.
this.projectRootPath = project.getBasePath(); val projectDir = ProjectUtil.guessProjectDir(project);
if (projectDir != null) {
this.projectRootPath = projectDir.toNioPath();
} else {
this.projectRootPath = null;
}
this.extManager = extManager; this.extManager = extManager;
projectToLanguageServerWrapper.put(project, this); projectToLanguageServerWrapper.put(project, this);
} }
@ -200,7 +209,7 @@ public class LanguageServerWrapper {
return serverDefinition; return serverDefinition;
} }
public String getProjectRootPath() { public Path getProjectRootPath() {
return projectRootPath; return projectRootPath;
} }
@ -448,7 +457,7 @@ public class LanguageServerWrapper {
launcherFuture.cancel(true); launcherFuture.cancel(true);
} }
if (serverDefinition != null) { if (serverDefinition != null) {
serverDefinition.stop(projectRootPath); serverDefinition.stop(projectRootPath != null ? projectRootPath.toString() : null);
} }
for (Editor ed : new HashSet<>(connectedEditors)) { for (Editor ed : new HashSet<>(connectedEditors)) {
disconnect(ed); disconnect(ed);
@ -495,7 +504,7 @@ public class LanguageServerWrapper {
if (status == STOPPED && !alreadyShownCrash && !alreadyShownTimeout) { if (status == STOPPED && !alreadyShownCrash && !alreadyShownTimeout) {
setStatus(STARTING); setStatus(STARTING);
try { try {
Pair<InputStream, OutputStream> streams = serverDefinition.start(projectRootPath); Pair<InputStream, OutputStream> streams = serverDefinition.start(projectRootPath != null ? projectRootPath.toString() : null);
InputStream inputStream = streams.getKey(); InputStream inputStream = streams.getKey();
OutputStream outputStream = streams.getValue(); OutputStream outputStream = streams.getValue();
InitializeParams initParams = getInitParams(); InitializeParams initParams = getInitParams();

View file

@ -28,6 +28,7 @@ import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.fileTypes.FileType; 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.project.ProjectUtil;
import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiDocumentManager;
@ -35,11 +36,11 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.LightVirtualFileBase; import com.intellij.testFramework.LightVirtualFileBase;
import lombok.val;
import org.eclipse.lsp4j.TextDocumentIdentifier; import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -161,17 +162,29 @@ public class FileUtils {
} }
public static String editorToProjectFolderPath(Editor editor) { public static String editorToProjectFolderPath(Editor editor) {
if (editor != null && editor.getProject() != null && editor.getProject().getBasePath() != null) { if (editor == null)
return new File(editor.getProject().getBasePath()).getAbsolutePath();
}
return null; return null;
val project = editor.getProject();
if (project == null)
return null;
val projectDir = ProjectUtil.guessProjectDir(editor.getProject());
if (projectDir == null)
return null;
return projectDir.toNioPath().toAbsolutePath().toString();
} }
public static String projectToUri(Project project) { public static String projectToUri(Project project) {
if (project != null && project.getBasePath() != null) { if (project == null)
return FileUtil.pathToUri(new File(project.getBasePath()).getAbsolutePath());
}
return null; return null;
val path = ProjectUtil.guessProjectDir(project);
if (path == null)
return null;
return FileUtil.pathToUri(path.toNioPath());
} }
public static String documentToUri(Document document) { public static String documentToUri(Document document) {

View file

@ -20,6 +20,8 @@ import com.falsepattern.zigbrains.common.util.FileUtil;
import com.intellij.execution.filters.Filter; import com.intellij.execution.filters.Filter;
import com.intellij.execution.filters.OpenFileHyperlinkInfo; import com.intellij.execution.filters.OpenFileHyperlinkInfo;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtil;
import com.intellij.openapi.vfs.VirtualFile;
import kotlin.Pair; import kotlin.Pair;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.val; import lombok.val;
@ -30,6 +32,7 @@ import java.nio.file.Files;
import java.nio.file.InvalidPathException; import java.nio.file.InvalidPathException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Optional;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@RequiredArgsConstructor @RequiredArgsConstructor
@ -37,15 +40,15 @@ public class ZigSourceFileFilter implements Filter {
private final Project project; private final Project project;
private final Pattern LEN_REGEX = Pattern.compile(":(\\d+):(\\d+)"); private final Pattern LEN_REGEX = Pattern.compile(":(\\d+):(\\d+)");
private Pair<Path, Integer> findLongestParsablePathFromOffset(String line, int end, String projectPath) { private Pair<Path, Integer> findLongestParsablePathFromOffset(String line, int end, Path projectPath) {
int longestStart = -1; int longestStart = -1;
Path longest = null; Path longest = null;
for (int i = end - 1; i >= 0; i--) { for (int i = end - 1; i >= 0; i--) {
try { try {
val pathStr = line.substring(i, end); val pathStr = line.substring(i, end);
var path = Path.of(pathStr); var path = Path.of(pathStr);
if (!Files.exists(path) || !Files.isRegularFile(path)) { if (!(Files.exists(path) && Files.isRegularFile(path)) && projectPath != null) {
path = Path.of(projectPath, pathStr); path = projectPath.resolve(pathStr);
if (!Files.exists(path) || !Files.isRegularFile(path)) if (!Files.exists(path) || !Files.isRegularFile(path))
continue; continue;
} }
@ -60,7 +63,7 @@ public class ZigSourceFileFilter implements Filter {
@Override @Override
public Result applyFilter(@NotNull String line, int entireLength) { public Result applyFilter(@NotNull String line, int entireLength) {
val lineStart = entireLength - line.length(); val lineStart = entireLength - line.length();
val projectPath = project.getBasePath(); val projectPath = Optional.ofNullable(ProjectUtil.guessProjectDir(project)).map(VirtualFile::toNioPath).orElse(null);
val results = new ArrayList<ResultItem>(); val results = new ArrayList<ResultItem>();
val matcher = LEN_REGEX.matcher(line); val matcher = LEN_REGEX.matcher(line);
while (matcher.find()) { while (matcher.find()) {

View file

@ -22,8 +22,10 @@ import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.LocatableConfigurationBase; import com.intellij.execution.configurations.LocatableConfigurationBase;
import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtil;
import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.NlsActions; import com.intellij.openapi.util.NlsActions;
import com.intellij.openapi.vfs.VirtualFile;
import lombok.Getter; import lombok.Getter;
import lombok.val; import lombok.val;
import org.jdom.Element; import org.jdom.Element;
@ -39,8 +41,8 @@ public abstract class ZigExecConfigBase<T extends ZigExecConfigBase<T>> extends
private ZigConfigEditor.WorkDirectoryConfigurable workingDirectory = new ZigConfigEditor.WorkDirectoryConfigurable("workingDirectory"); private ZigConfigEditor.WorkDirectoryConfigurable workingDirectory = new ZigConfigEditor.WorkDirectoryConfigurable("workingDirectory");
public ZigExecConfigBase(@NotNull Project project, @NotNull ConfigurationFactory factory, @Nullable String name) { public ZigExecConfigBase(@NotNull Project project, @NotNull ConfigurationFactory factory, @Nullable String name) {
super(project, factory, name); super(project, factory, name);
workingDirectory.setPath(project.isDefault() ? null : Optional.ofNullable(project.getBasePath()) workingDirectory.setPath(getProject().isDefault() ? null : Optional.ofNullable(ProjectUtil.guessProjectDir(getProject()))
.map(Path::of) .map(VirtualFile::toNioPath)
.orElse(null)); .orElse(null));
} }