diff --git a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/FindReferencesAction.kt b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/FindReferencesAction.kt
new file mode 100644
index 000000000..bdf976fa9
--- /dev/null
+++ b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/FindReferencesAction.kt
@@ -0,0 +1,62 @@
+/*
+ * 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 .
+ */
+
+package com.itsaky.lsp.java.actions
+
+import com.itsaky.androidide.actions.ActionData
+import com.itsaky.androidide.utils.Logger
+import com.itsaky.lsp.java.R
+import io.github.rosemoe.sora.widget.CodeEditor
+import java.io.File
+
+/**
+ * Action that allows the user to find references to a variable, field, method or class.
+ *
+ * @author Akash Yadav
+ */
+class FindReferencesAction : BaseCodeAction() {
+ override val titleTextRes: Int = R.string.action_find_references
+ override val id: String = "lsp_java_findReferences"
+ override var label: String = "Find references"
+ override var requiresUIThread: Boolean = true
+ private val log = Logger.newInstance(javaClass.simpleName)
+
+ override fun prepare(data: ActionData) {
+ super.prepare(data)
+
+ if (!visible || !hasRequiredData(data, CodeEditor::class.java, File::class.java)) {
+ markInvisible()
+ return
+ }
+ }
+
+ override fun execAction(data: ActionData): Any {
+ val editor = data[CodeEditor::class.java]!!
+ return tryExecFindDefinition(editor)
+ }
+
+ private fun tryExecFindDefinition(editor: CodeEditor): Boolean {
+ return try {
+ val method = editor::class.java.getDeclaredMethod("findReferences")
+ method.isAccessible = true
+ method.invoke(editor)
+ true
+ } catch (error: Throwable) {
+ false
+ }
+ }
+}
diff --git a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/GoToDefinitionAction.kt b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/GoToDefinitionAction.kt
new file mode 100644
index 000000000..2c5630977
--- /dev/null
+++ b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/GoToDefinitionAction.kt
@@ -0,0 +1,63 @@
+/*
+ * 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 .
+ */
+
+package com.itsaky.lsp.java.actions
+
+import com.itsaky.androidide.actions.ActionData
+import com.itsaky.androidide.utils.Logger
+import com.itsaky.lsp.java.R
+import io.github.rosemoe.sora.widget.CodeEditor
+import java.io.File
+
+/**
+ * Action that allows the user to navigate to the definition of a variable, field, method, class,
+ * etc.
+ *
+ * @author Akash Yadav
+ */
+class GoToDefinitionAction : BaseCodeAction() {
+ override val titleTextRes: Int = R.string.action_goto_definition
+ override val id: String = "lsp_java_gotoDefinition"
+ override var label: String = "Go to definition"
+ override var requiresUIThread: Boolean = true
+ private val log = Logger.newInstance(javaClass.simpleName)
+
+ override fun prepare(data: ActionData) {
+ super.prepare(data)
+
+ if (!visible || !hasRequiredData(data, CodeEditor::class.java, File::class.java)) {
+ markInvisible()
+ return
+ }
+ }
+
+ override fun execAction(data: ActionData): Any {
+ val editor = data[CodeEditor::class.java]!!
+ return tryExecFindDefinition(editor)
+ }
+
+ private fun tryExecFindDefinition(editor: CodeEditor): Boolean {
+ return try {
+ val method = editor::class.java.getDeclaredMethod("findDefinition")
+ method.isAccessible = true
+ method.invoke(editor)
+ true
+ } catch (error: Throwable) {
+ false
+ }
+ }
+}
diff --git a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/JavaCodeActionsMenu.kt b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/JavaCodeActionsMenu.kt
index ec51383ca..9fa36cc2a 100644
--- a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/JavaCodeActionsMenu.kt
+++ b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/JavaCodeActionsMenu.kt
@@ -24,6 +24,8 @@ class JavaCodeActionsMenu : CodeActionsMenu() {
init {
addAction(CommentAction())
addAction(UncommentAction())
+ addAction(GoToDefinitionAction())
+ addAction(FindReferencesAction())
addAction(AddImportAction())
addAction(ImplementAbstractMethodsAction())
addAction(VariableToStatementAction())
diff --git a/lsp/java/src/main/res/values/strings.xml b/lsp/java/src/main/res/values/strings.xml
index 8e11e7244..c049880d8 100644
--- a/lsp/java/src/main/res/values/strings.xml
+++ b/lsp/java/src/main/res/values/strings.xml
@@ -39,4 +39,6 @@
Unable to generate setters and getters
Select methods to override
Unable to find any overridable method
+ Go to definition
+ Find references
\ No newline at end of file