Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,15 @@ object TooltipTag {
const val EDITOR_CODE_ACTIONS_GEN_TO_STRING_DIALOG = "editor.codeactions.gentostring.dialog"
const val EDITOR_CODE_ACTIONS_UNUSED_IMPORTS = "editor.codeactions.unusedimports"
const val EDITOR_CODE_ACTIONS_ORGANIZE_IMPORTS = "editor.codeactions.organizeimports"
const val EDITOR_CODE_ACTIONS_KT_FIX_IMPORTS = "editor.codeactions.kotlin.fiximports"

// Kotlin code actions. Tags are per-language even where the action exists in both languages,
// so the tooltip can describe the Kotlin behaviour (see ADFA-4730).
const val EDITOR_CODE_ACTIONS_KT_COMMENT = "editor.codeactions.kotlin.comment"
const val EDITOR_CODE_ACTIONS_KT_UNCOMMENT = "editor.codeactions.kotlin.uncomment"
const val EDITOR_CODE_ACTIONS_KT_IMPORT_CLASS = "editor.codeactions.kotlin.importclass"
const val EDITOR_CODE_ACTIONS_KT_ORGANIZE_IMPORTS = "editor.codeactions.kotlin.organizeimports"
const val EDITOR_CODE_ACTIONS_KT_IMPLEMENT_MEMBERS = "editor.codeactions.kotlin.implementmembers"
const val EDITOR_CODE_ACTIONS_KT_NULL_SAFETY_FIX = "editor.codeactions.kotlin.nullsafetyfix"
const val EDITOR_CODE_ACTIONS_KT_SURROUND_TRY_CATCH = "editor.codeactions.kotlin.trycatch"

const val EXIT_TO_MAIN = "exit.to.main"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,86 +1,94 @@
/*
* 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.lsp.actions

import android.content.Context
import android.graphics.drawable.Drawable
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.actions.EditorActionItem
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireContext
import com.itsaky.androidide.actions.requireEditor
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.idetooltips.TooltipTag
import com.itsaky.androidide.resources.R
import io.github.rosemoe.sora.text.batchEdit
import java.io.File

/** @author Akash Yadav */
class CommentLineAction(
lang: String,
private val targetFileExtensions: List<String>,
private val lineCommentToken: String,
) : EditorActionItem {

constructor(lang: String, extension: String, lineCommentToken: String) :
this(lang, listOf(extension), lineCommentToken)
override val id: String = "ide.editor.lsp.$lang.commentLine"
override var label: String = ""

override var visible = true
override var enabled = true
override var icon: Drawable? = null
override var location: ActionItem.Location = ActionItem.Location.EDITOR_CODE_ACTIONS
override var requiresUIThread: Boolean = true
override var tooltipTag: String = TooltipTag.EDITOR_CODE_ACTIONS_COMMENT

override fun prepare(data: ActionData) {
super.prepare(data)

if (!data.hasRequiredData(Context::class.java, File::class.java)) {
markInvisible()
return
}

val context = data.requireContext()
label = context.getString(R.string.action_comment_line)

val file = data.requireFile()
if (file.extension !in targetFileExtensions) {
markInvisible()
return
}
}

override suspend fun execAction(data: ActionData): Boolean {
val editor = data.requireEditor()
val text = editor.text
val cursor = editor.cursor

text.batchEdit {
for (line in cursor.leftLine..cursor.rightLine) {
text.insert(line, 0, lineCommentToken)
}
}

return true
}

override fun dismissOnAction() = true
}
/*
* 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.lsp.actions

import android.content.Context
import android.graphics.drawable.Drawable
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.actions.EditorActionItem
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireContext
import com.itsaky.androidide.actions.requireEditor
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.resources.R
import io.github.rosemoe.sora.text.batchEdit
import java.io.File

/** @author Akash Yadav */
class CommentLineAction(
lang: String,
private val targetFileExtensions: List<String>,
private val lineCommentToken: String,
tag: String,
) : EditorActionItem {
companion object {
/** The id is per-language, since one instance is registered per language. */
fun idFor(lang: String) = "ide.editor.lsp.$lang.commentLine"
}

constructor(lang: String, extension: String, lineCommentToken: String, tag: String) :
this(lang, listOf(extension), lineCommentToken, tag)
Comment on lines +34 to +46

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Document the new required per-language tooltip-tag API.

Both public action constructors gained a mandatory tag parameter, so their KDoc should define its per-language requirement and tooltip behavior.

  • lsp/api/src/main/java/com/itsaky/androidide/lsp/actions/CommentLineAction.kt#L34-L41: document the comment action contract and required tag.
  • lsp/api/src/main/java/com/itsaky/androidide/lsp/actions/UncommentLineAction.kt#L34-L41: document the uncomment action contract and required tag.
📍 Affects 2 files
  • lsp/api/src/main/java/com/itsaky/androidide/lsp/actions/CommentLineAction.kt#L34-L41 (this comment)
  • lsp/api/src/main/java/com/itsaky/androidide/lsp/actions/UncommentLineAction.kt#L34-L41
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lsp/api/src/main/java/com/itsaky/androidide/lsp/actions/CommentLineAction.kt`
around lines 34 - 41, Document both public constructors of CommentLineAction in
lsp/api/src/main/java/com/itsaky/androidide/lsp/actions/CommentLineAction.kt:34-41
and UncommentLineAction in
lsp/api/src/main/java/com/itsaky/androidide/lsp/actions/UncommentLineAction.kt:34-41
with KDoc describing the comment/uncomment contract, the required per-language
tag parameter, and how that tag is used for tooltips.

Source: Coding guidelines


override val id: String = idFor(lang)
override var label: String = ""

override var visible = true
override var enabled = true
override var icon: Drawable? = null
override var location: ActionItem.Location = ActionItem.Location.EDITOR_CODE_ACTIONS
override var requiresUIThread: Boolean = true

// Required, not defaulted: one instance is registered per language, and a default would let a
// new language silently inherit another language's tooltip.
override var tooltipTag: String = tag

override fun prepare(data: ActionData) {
super.prepare(data)

if (!data.hasRequiredData(Context::class.java, File::class.java)) {
markInvisible()
return
}

val context = data.requireContext()
label = context.getString(R.string.action_comment_line)

val file = data.requireFile()
if (file.extension !in targetFileExtensions) {
markInvisible()
return
}
}

override suspend fun execAction(data: ActionData): Boolean {
val editor = data.requireEditor()
val text = editor.text
val cursor = editor.cursor

text.batchEdit {
for (line in cursor.leftLine..cursor.rightLine) {
text.insert(line, 0, lineCommentToken)
}
}

return true
}

override fun dismissOnAction() = true
}
Original file line number Diff line number Diff line change
@@ -1,92 +1,98 @@
/*
* 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.lsp.actions

import android.content.Context
import android.graphics.drawable.Drawable
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.actions.EditorActionItem
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireContext
import com.itsaky.androidide.actions.requireEditor
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.idetooltips.TooltipTag
import com.itsaky.androidide.resources.R
import io.github.rosemoe.sora.text.batchEdit
import java.io.File

/** @author Akash Yadav */
class UncommentLineAction(
lang: String,
private val targetFileExtensions: List<String>,
private val lineCommentToken: String,
) : EditorActionItem {

constructor(lang: String, extension: String, lineCommentToken: String) :
this(lang, listOf(extension), lineCommentToken)

override val id: String = "ide.editor.lsp.$lang.uncommentLine"
override var label: String = ""

override var visible = true
override var enabled = true
override var icon: Drawable? = null
override var location: ActionItem.Location = ActionItem.Location.EDITOR_CODE_ACTIONS
override var requiresUIThread: Boolean = true
override var tooltipTag: String = TooltipTag.EDITOR_CODE_ACTIONS_UNCOMMENT


override fun prepare(data: ActionData) {
super.prepare(data)

if (!data.hasRequiredData(Context::class.java, File::class.java)) {
markInvisible()
return
}

val context = data.requireContext()
label = context.getString(R.string.action_uncomment_line)

val file = data.requireFile()
if (file.extension !in targetFileExtensions) {
markInvisible()
return
}
}

override suspend fun execAction(data: ActionData): Boolean {
val editor = data.requireEditor()
val text = editor.text
val cursor = editor.cursor

text.batchEdit {
for (line in cursor.leftLine..cursor.rightLine) {
val l = text.getLineString(line)
if (l.trim().startsWith(lineCommentToken)) {
val i = l.indexOf(lineCommentToken)
text.delete(line, i, line, i + 2)
}
}
}

return true
}

override fun dismissOnAction() = true
}
/*
* 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.lsp.actions

import android.content.Context
import android.graphics.drawable.Drawable
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.actions.EditorActionItem
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireContext
import com.itsaky.androidide.actions.requireEditor
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.resources.R
import io.github.rosemoe.sora.text.batchEdit
import java.io.File

/** @author Akash Yadav */
class UncommentLineAction(
lang: String,
private val targetFileExtensions: List<String>,
private val lineCommentToken: String,
tag: String,
) : EditorActionItem {
companion object {
/** The id is per-language, since one instance is registered per language. */
fun idFor(lang: String) = "ide.editor.lsp.$lang.uncommentLine"
}

constructor(lang: String, extension: String, lineCommentToken: String, tag: String) :
this(lang, listOf(extension), lineCommentToken, tag)

override val id: String = idFor(lang)
override var label: String = ""

override var visible = true
override var enabled = true
override var icon: Drawable? = null
override var location: ActionItem.Location = ActionItem.Location.EDITOR_CODE_ACTIONS
override var requiresUIThread: Boolean = true

// Required, not defaulted: one instance is registered per language, and a default would let a
// new language silently inherit another language's tooltip.
override var tooltipTag: String = tag

override fun prepare(data: ActionData) {
super.prepare(data)

if (!data.hasRequiredData(Context::class.java, File::class.java)) {
markInvisible()
return
}

val context = data.requireContext()
label = context.getString(R.string.action_uncomment_line)

val file = data.requireFile()
if (file.extension !in targetFileExtensions) {
markInvisible()
return
}
}

override suspend fun execAction(data: ActionData): Boolean {
val editor = data.requireEditor()
val text = editor.text
val cursor = editor.cursor

text.batchEdit {
for (line in cursor.leftLine..cursor.rightLine) {
val l = text.getLineString(line)
if (l.trim().startsWith(lineCommentToken)) {
val i = l.indexOf(lineCommentToken)
text.delete(line, i, line, i + 2)
}
}
}

return true
}

override fun dismissOnAction() = true
}
Loading
Loading