From 1223fcf71d1bab2763c9cff1223f7e198418970a Mon Sep 17 00:00:00 2001 From: TherCN Date: Wed, 3 Apr 2024 08:30:15 +0800 Subject: [PATCH 1/3] fix: lsp bugs --- .../editor/signature/SignatureHelpWindow.kt | 16 ++++++-- .../lsp/events/document/ApplyEditsEvent.kt | 41 ++++++++++--------- .../events/document/DocumentChangeEvent.kt | 6 +-- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/editor/signature/SignatureHelpWindow.kt b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/editor/signature/SignatureHelpWindow.kt index b58161e2a..c4a329881 100644 --- a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/editor/signature/SignatureHelpWindow.kt +++ b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/editor/signature/SignatureHelpWindow.kt @@ -85,9 +85,16 @@ open class SignatureHelpWindow(editor: CodeEditor) : EditorPopupWindow( open fun show(signatureHelp: SignatureHelp) { this.signatureHelp = signatureHelp - renderSignatureHelp() - updateWindowSizeAndLocation() - show() + + if (signatureHelp.activeSignature != null && signatureHelp.activeParameter != null) { + renderSignatureHelp() + updateWindowSizeAndLocation() + show() + } else { + Log.d("SignatureHelpWindow", "activeSignature or activeParameter is null") + return + } + } @@ -132,6 +139,7 @@ open class SignatureHelpWindow(editor: CodeEditor) : EditorPopupWindow( val activeSignatureIndex = signatureHelp.activeSignature val activeParameterIndex = signatureHelp.activeParameter + val signatures = signatureHelp.signatures val renderStringBuilder = SpannableStringBuilder() @@ -145,6 +153,8 @@ open class SignatureHelpWindow(editor: CodeEditor) : EditorPopupWindow( Log.d("SignatureHelpWindow", "activeSignature is out of range") return } + + // Get only the activated signature for (i in 0..activeSignatureIndex) { diff --git a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/ApplyEditsEvent.kt b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/ApplyEditsEvent.kt index 092a699c6..c4cb07a5b 100644 --- a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/ApplyEditsEvent.kt +++ b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/ApplyEditsEvent.kt @@ -37,32 +37,33 @@ class ApplyEditsEvent : EventListener { override val eventName: String = "textDocument/applyEdits" override fun handle(context: EventContext) { - val editList: List = context.get("edits") + val editList: List> = context.get("edits") val content = context.getByClass() ?: return - editList.forEach { textEdit: TextEdit -> - val range = textEdit.range - val text = textEdit.newText - var startIndex = - content.getCharIndex(range.start.line, range.start.character) - var endIndex = - content.getCharIndex(range.end.line, range.end.character) - if (endIndex < startIndex) { - Logger.instance(this.javaClass.name) - .w( - "Invalid location information found applying edits from %s to %s", - range.start, - range.end - ) - val diff = startIndex - endIndex - endIndex = startIndex - startIndex = endIndex - diff + editList.forEach { list: ArrayList -> + list.forEach { textEdit : TextEdit -> + val range = textEdit.range + val text = textEdit.newText + var startIndex = + content.getCharIndex(range.start.line, range.start.character) + var endIndex = + content.getCharIndex(range.end.line, range.end.character) + if (endIndex < startIndex) { + Logger.instance(this.javaClass.name) + .w( + "Invalid location information found applying edits from %s to %s", + range.start, + range.end + ) + val diff = startIndex - endIndex + endIndex = startIndex + startIndex = endIndex - diff + } + content.replace(startIndex, endIndex, text) } - content.replace(startIndex, endIndex, text) } } - } val EventType.applyEdits: String diff --git a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/DocumentChangeEvent.kt b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/DocumentChangeEvent.kt index d97974a33..93d167e5d 100644 --- a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/DocumentChangeEvent.kt +++ b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/DocumentChangeEvent.kt @@ -81,13 +81,9 @@ class DocumentChangeEvent : AsyncEventListener() { editor: LspEditor, data: ContentChangeEvent ): List { - val text = data.changedText.toString() + val text = data.editor.text.toString() return listOf( editor.uri.createTextDocumentContentChangeEvent( - createRange( - data.changeStart, - data.changeEnd - ), if (data.action == ContentChangeEvent.ACTION_DELETE) "" else text ) ) From 9ff6ba5cf46315bf71e0986bdca9a4fdce571cc2 Mon Sep 17 00:00:00 2001 From: TherCN Date: Mon, 14 Oct 2024 13:27:37 +0800 Subject: [PATCH 2/3] fix some bugs --- .../editor/completion/LspCompletionItem.kt | 26 +++++-- .../events/document/DocumentChangeEvent.kt | 6 +- .../rosemoe/sora/lsp/utils/OtherUtils.java | 74 +++++++++++++++++++ 3 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/utils/OtherUtils.java diff --git a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/editor/completion/LspCompletionItem.kt b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/editor/completion/LspCompletionItem.kt index 7c1c79a09..08c8961b0 100644 --- a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/editor/completion/LspCompletionItem.kt +++ b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/editor/completion/LspCompletionItem.kt @@ -24,12 +24,14 @@ package io.github.rosemoe.sora.lsp.editor.completion +import android.util.Log import io.github.rosemoe.sora.lang.completion.CompletionItemKind import io.github.rosemoe.sora.lang.completion.SimpleCompletionIconDrawer.draw import io.github.rosemoe.sora.lang.completion.snippet.parser.CodeSnippetParser import io.github.rosemoe.sora.lsp.editor.LspEventManager import io.github.rosemoe.sora.lsp.events.EventType import io.github.rosemoe.sora.lsp.events.document.applyEdits +import io.github.rosemoe.sora.lsp.utils.OtherUtils import io.github.rosemoe.sora.lsp.utils.asLspPosition import io.github.rosemoe.sora.lsp.utils.createPosition import io.github.rosemoe.sora.lsp.utils.createRange @@ -116,13 +118,21 @@ class LspCompletionItem( val codeSnippet = CodeSnippetParser.parse(textEdit.newText) val startIndex = text.getCharIndex(textEdit.range.start.line, textEdit.range.start.character) - val endIndex = text.getCharIndex(textEdit.range.end.line, textEdit.range.end.character) - val selectedText = text.subSequence(startIndex, endIndex).toString() - text.delete(startIndex, endIndex) - - editor.snippetController - .startSnippet(startIndex, codeSnippet, selectedText) - + var endIndex = 0; + try { + endIndex = text.getCharIndex(textEdit.range.end.line, textEdit.range.end.character) + } catch (e:StringIndexOutOfBoundsException) { + //fix StringIndexOutOfBoundsException + OtherUtils.handleOutOfBoundIndex(e,editor) + endIndex = text.getCharIndex(textEdit.range.end.line, textEdit.range.end.character) + } + + if (startIndex < endIndex) { + val selectedText = text.subSequence(startIndex, endIndex).toString() + text.delete(startIndex, endIndex) + editor.snippetController + .startSnippet(startIndex, codeSnippet, selectedText) + } } else { eventManager.emit(EventType.applyEdits) { put("edits", listOf(finalTextEdit)) @@ -133,7 +143,7 @@ class LspCompletionItem( if (completionItem.additionalTextEdits != null) { eventManager.emit(EventType.applyEdits) { - put("edits", listOf(completionItem.additionalTextEdits)) + put("edits", completionItem.additionalTextEdits) put(text) } } diff --git a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/DocumentChangeEvent.kt b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/DocumentChangeEvent.kt index 93d167e5d..d97974a33 100644 --- a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/DocumentChangeEvent.kt +++ b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/DocumentChangeEvent.kt @@ -81,9 +81,13 @@ class DocumentChangeEvent : AsyncEventListener() { editor: LspEditor, data: ContentChangeEvent ): List { - val text = data.editor.text.toString() + val text = data.changedText.toString() return listOf( editor.uri.createTextDocumentContentChangeEvent( + createRange( + data.changeStart, + data.changeEnd + ), if (data.action == ContentChangeEvent.ACTION_DELETE) "" else text ) ) diff --git a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/utils/OtherUtils.java b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/utils/OtherUtils.java new file mode 100644 index 000000000..4e3961909 --- /dev/null +++ b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/utils/OtherUtils.java @@ -0,0 +1,74 @@ +package io.github.rosemoe.sora.lsp.utils; + +import android.annotation.SuppressLint; +import android.util.Log; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.lsp4j.CompletionItem; + +import io.github.rosemoe.sora.widget.CodeEditor; + +public class OtherUtils { + @SuppressLint("NewApi") + public static String toString(List list) { + return Arrays + .toString(list + .stream() + .map(Object::toString) + .collect(java.util.stream.Collectors.toList()) + .toArray(new String[0])); + } + @SuppressLint("NewApi") + public static String compeltionItemListToString(List list) { + return Arrays + .toString(list + .stream() + .map(completionItem -> { + StringBuilder str = new StringBuilder("detail:" + completionItem.getDetail() + "\n"); + str.append("label:" +completionItem.getLabel() + '\n'); + str.append("insertText:" + completionItem.getInsertText() + "\n"); + str.append("data:" + completionItem.getData() + "\n"); + return str.toString(); + }) + .collect(java.util.stream.Collectors.toList()) + .toArray(new String[0])); + } + @SuppressLint("NewApi") + public static K getKeyClass(Map map, V value) { + for (K key: map.keySet()) { + if (map.get(key).getClass() == value.getClass()) return key; + } + return null; + } + + public static int handleOutOfBoundIndex(StringIndexOutOfBoundsException e, CodeEditor editor) { + //example : e.getMessage() = "Column 15 out of bounds. line: 15 , column count (line separator included):14" + List numbers = new ArrayList<>(); + Pattern pattern = Pattern.compile("\\d+"); + Matcher matcher = pattern.matcher(e.getMessage()); + + while (matcher.find()) { + numbers.add(Integer.parseInt(matcher.group())); + } + Log.i("out",String.format("message:%s,result:%s",e.getMessage(),toString(numbers))); + int size = numbers.get(0) - numbers.get(2); + for (int i = 0; i Date: Mon, 14 Oct 2024 13:45:36 +0800 Subject: [PATCH 3/3] restore file :ApplyEditsEvent --- .../lsp/events/document/ApplyEditsEvent.kt | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/ApplyEditsEvent.kt b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/ApplyEditsEvent.kt index c4cb07a5b..092a699c6 100644 --- a/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/ApplyEditsEvent.kt +++ b/editor-lsp/src/main/java/io/github/rosemoe/sora/lsp/events/document/ApplyEditsEvent.kt @@ -37,33 +37,32 @@ class ApplyEditsEvent : EventListener { override val eventName: String = "textDocument/applyEdits" override fun handle(context: EventContext) { - val editList: List> = context.get("edits") + val editList: List = context.get("edits") val content = context.getByClass() ?: return - editList.forEach { list: ArrayList -> - list.forEach { textEdit : TextEdit -> - val range = textEdit.range - val text = textEdit.newText - var startIndex = - content.getCharIndex(range.start.line, range.start.character) - var endIndex = - content.getCharIndex(range.end.line, range.end.character) - if (endIndex < startIndex) { - Logger.instance(this.javaClass.name) - .w( - "Invalid location information found applying edits from %s to %s", - range.start, - range.end - ) - val diff = startIndex - endIndex - endIndex = startIndex - startIndex = endIndex - diff - } - content.replace(startIndex, endIndex, text) + editList.forEach { textEdit: TextEdit -> + val range = textEdit.range + val text = textEdit.newText + var startIndex = + content.getCharIndex(range.start.line, range.start.character) + var endIndex = + content.getCharIndex(range.end.line, range.end.character) + if (endIndex < startIndex) { + Logger.instance(this.javaClass.name) + .w( + "Invalid location information found applying edits from %s to %s", + range.start, + range.end + ) + val diff = startIndex - endIndex + endIndex = startIndex + startIndex = endIndex - diff } + content.replace(startIndex, endIndex, text) } } + } val EventType.applyEdits: String