feat(editor): add file and workspace based snippet variable resolvers

This commit is contained in:
Akash Yadav
2023-04-01 18:31:38 +05:30
parent 402c3f6db6
commit df74c35e3e
4 changed files with 160 additions and 2 deletions
@@ -0,0 +1,30 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.editor.snippets
import io.github.rosemoe.sora.widget.snippet.variable.ISnippetVariableResolver
/**
* Base class for snippet variable resolvers.
*
* @author Akash Yadav
*/
interface AbstractSnippetVariableResolver : ISnippetVariableResolver, AutoCloseable {
override fun close() {
}
}
@@ -0,0 +1,61 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.editor.snippets
import com.itsaky.androidide.editor.ui.IDEEditor
import com.itsaky.androidide.projects.ProjectManager
import io.github.rosemoe.sora.widget.snippet.variable.FileBasedSnippetVariableResolver
/**
* Resolver for resolving snippet variables related to the file opened in an editor.
*
* @author Akash Yadav
*/
class FileVariableResolver(editor: IDEEditor) : FileBasedSnippetVariableResolver(), AbstractSnippetVariableResolver {
var editor: IDEEditor? = editor
private set
companion object {
private const val TM_FILENAME = "TM_FILENAME"
private const val TM_FILENAME_BASE = "TM_FILENAME_BASE"
private const val TM_DIRECTORY = "TM_DIRECTORY"
private const val TM_FILEPATH = "TM_FILEPATH"
private const val RELATIVE_FILEPATH = "RELATIVE_FILEPATH"
}
override fun resolve(name: String): String {
val file = editor?.file ?: return ""
return when (name) {
TM_FILENAME -> file.name
TM_FILENAME_BASE -> file.nameWithoutExtension
TM_DIRECTORY -> file.parentFile?.absolutePath ?: ""
TM_FILEPATH -> file.absolutePath
RELATIVE_FILEPATH -> file.relativeTo(ProjectManager.getProjectDir()).absolutePath
else -> ""
}
}
override fun getResolvableNames(): Array<String> {
return arrayOf(TM_FILENAME, TM_FILENAME_BASE, TM_DIRECTORY, TM_FILEPATH, RELATIVE_FILEPATH)
}
override fun close() {
editor = null
}
}
@@ -0,0 +1,48 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.editor.snippets
import com.itsaky.androidide.projects.ProjectManager
import io.github.rosemoe.sora.widget.snippet.variable.WorkspaceBasedSnippetVariableResolver
/**
* Resolver for resolving snippet variables related to the opened workspace folder (project).
*
* @author Akash Yadav
*/
class WorkspaceVariableResolver :
WorkspaceBasedSnippetVariableResolver(), AbstractSnippetVariableResolver {
companion object {
private const val WORKSPACE_NAME = "WORKSPACE_NAME"
private const val WORKSPACE_FOLDER = "WORKSPACE_FOLDER"
}
override fun resolve(name: String): String {
val directory = ProjectManager.getProjectDir()
return when (name) {
WORKSPACE_NAME -> directory.name
WORKSPACE_FOLDER -> directory.absolutePath
else -> ""
}
}
override fun getResolvableNames(): Array<String> {
return arrayOf(WORKSPACE_NAME, WORKSPACE_FOLDER)
}
}
@@ -46,6 +46,9 @@ import com.itsaky.androidide.editor.language.treesitter.TreeSitterLanguage;
import com.itsaky.androidide.editor.language.treesitter.TreeSitterLanguageProvider;
import com.itsaky.androidide.editor.schemes.IDEColorScheme;
import com.itsaky.androidide.editor.schemes.IDEColorSchemeProvider;
import com.itsaky.androidide.editor.snippets.AbstractSnippetVariableResolver;
import com.itsaky.androidide.editor.snippets.FileVariableResolver;
import com.itsaky.androidide.editor.snippets.WorkspaceVariableResolver;
import com.itsaky.androidide.eventbus.events.editor.ChangeType;
import com.itsaky.androidide.eventbus.events.editor.ColorSchemeInvalidatedEvent;
import com.itsaky.androidide.eventbus.events.editor.DocumentChangeEvent;
@@ -80,6 +83,7 @@ import io.github.rosemoe.sora.widget.CodeEditor;
import io.github.rosemoe.sora.widget.IDEEditorSearcher;
import io.github.rosemoe.sora.widget.component.EditorAutoCompletion;
import io.github.rosemoe.sora.widget.component.EditorTextActionWindow;
import io.github.rosemoe.sora.widget.snippet.variable.ISnippetVariableResolver;
import java.io.File;
import java.util.concurrent.CompletableFuture;
import kotlin.io.FilesKt;
@@ -426,6 +430,8 @@ public class IDEEditor extends CodeEditor implements IEditor, ILspEditor {
if (server != null) {
this.languageClient = server.getClient();
getSnippetController().setFileVariableResolver(new FileVariableResolver(this));
getSnippetController().setWorkspaceVariableResolver(new WorkspaceVariableResolver());
}
}
@@ -755,8 +761,8 @@ public class IDEEditor extends CodeEditor implements IEditor, ILspEditor {
new Position(end.line, end.column, end.index));
final var changedText = event.getChangedText().toString();
final var changeEvent = new DocumentChangeEvent(file, changedText, getText().toString(), ++fileVersion, type,
changeDelta, changeRange);
final var changeEvent = new DocumentChangeEvent(file, changedText, getText().toString(),
++fileVersion, type, changeDelta, changeRange);
// Notify FileManager first
FileManager.INSTANCE.onDocumentContentChange(changeEvent);
@@ -819,6 +825,19 @@ public class IDEEditor extends CodeEditor implements IEditor, ILspEditor {
public void release() {
ensureWindowsDismissed();
super.release();
ISnippetVariableResolver resolver = getSnippetController().getFileVariableResolver();
if (resolver instanceof AbstractSnippetVariableResolver) {
((AbstractSnippetVariableResolver) resolver).close();
}
resolver = getSnippetController().getWorkspaceVariableResolver();
if (resolver instanceof AbstractSnippetVariableResolver) {
((AbstractSnippetVariableResolver) resolver).close();
}
getSnippetController().setFileVariableResolver(null);
getSnippetController().setWorkspaceVariableResolver(null);
if (this.actionsMenu != null) {
this.actionsMenu.destroy();
}