Skip to content

ADFA-2106 | Enable text selection in build logs#732

Merged
jatezzz merged 9 commits intostagefrom
feat/ADFA-2106-enable-log-text-selection
Dec 17, 2025
Merged

ADFA-2106 | Enable text selection in build logs#732
jatezzz merged 9 commits intostagefrom
feat/ADFA-2106-enable-log-text-selection

Conversation

@jatezzz
Copy link
Collaborator

@jatezzz jatezzz commented Dec 12, 2025

Description

This PR modifies the long-press behavior in the build output and log views to prioritize text selection over the immediate help tooltip.

Instead of blocking interaction with a "help" popup, a long-press now:

  1. Selects the text under the finger (standard editor behavior).
  2. Opens the text selection toolbar.
  3. Includes a new "Help" button in the toolbar to access the original tooltip functionality.

This resolves the UX conflict where developers were unable to copy text from logs.

Details

  • Long-press: Now triggers setSelectionFromPoint to highlight the specific word or line.
  • Toolbar: Added logic to ShowTooltipAction so it appears in the floating menu when text is selected.
  • Refactor: BuildOutputFragment now exposes the underlying editor to handle coordinate-based selection.
Screen.Recording.2025-12-12.at.3.44.18.PM.mov

Ticket

ADFA-2106

Observation

The ShowTooltipAction was updated to check for editor.cursor.isSelected. The help icon will now only appear when there is an active selection in the editor/log view.

…ates log viewer to support native text selection and adds tooltip action to the selection toolbar
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 2025

📝 Walkthrough

Release Notes: Enable Text Selection in Build Logs (ADFA-2106)

Features

  • Text Selection on Long-Press: Long-press in build output and log views now selects text at the touch point instead of immediately showing a tooltip
  • Coordinate-Based Selection: New setSelectionFromPoint(x, y) method in IDEEditor enables precise text selection from touch coordinates
  • Help Tooltip in Selection Toolbar: "Help" button now appears in the floating text selection toolbar (shown only when text is selected), providing access to original tooltip functionality
  • Editor Tag Support: Build output and log views now expose their underlying editor instance via currentEditor property for coordinate-based operations

Technical Changes

  • ShowTooltipAction (ide.editor.code.text.show_tooltip):

    • Updated action identifier
    • New prepare(ActionData) method controls visibility based on selection state
    • Smart tag resolution: editor.tag → XML attribute name → selected word
  • EmptyStateFragment:

    • New currentEditor: IDEEditor? property for editor access
    • Overloaded onFragmentLongPressed(x, y, Float) methods with coordinate forwarding
    • Long-press handler checks readonly state before selecting text
  • BuildOutputFragment & LogViewFragment:

    • Expose editor instance via currentEditor override
    • Removed direct tooltip triggers on long-press
    • Editor tagged with appropriate tooltip context (PROJECT_BUILD_OUTPUT, etc.)

⚠️ Breaking Changes

  • EmptyStateFragment.onFragmentLongPressed() method signature changed from abstract single method to overloaded open methods with coordinates
  • All Fragment subclasses overriding this method require updates to match new signature

⚠️ Risks & Best Practice Violations

  1. Silent Error Handling: setSelectionFromPoint() wraps coordinate conversion in try/catch with only logging—errors could silently fail without user feedback
  2. Subclass Compatibility: Breaking change to abstract method signature in base Fragment class requires migration of all subclasses; incomplete updates could cause runtime errors
  3. Null-Safety: currentEditor is nullable throughout; relies on null-checks in multiple locations (EmptyStateFragment.onFragmentLongPressed checks this)
  4. Coordinate Validation: No documented validation of x/y coordinates before passing to setSelectionFromPoint; invalid coordinates could cause unexpected selection behavior
  5. Behavioral Migration: Removal of immediate tooltip on long-press represents significant UX change; users expecting original behavior may be confused until selection toolbar appears
  6. Tag Resolution Logic: Multi-tier tag fallback (editor.tag → XML attribute → selected word) adds complexity; XML attribute parsing with substringAfterLast(":") could be fragile for edge cases

Migration Guidance

  • Update all Fragment subclasses extending EmptyStateFragment to implement new overloaded long-press methods
  • Test coordinate-based selection across different screen sizes and device orientations
  • Verify readonly contexts properly prevent selection attempts
  • Review error logs during testing for any failed coordinate conversions

Walkthrough

Fragments now forward touch coordinates on long-press to select text in an editor; IDEEditor gains setSelectionFromPoint(x,y); BuildOutputFragment and LogViewFragment expose their editor via currentEditor; ShowTooltipAction ID changed and gains prepare(data) to control visibility/enabled state based on editor selection.

Changes

Cohort / File(s) Summary
Action ID & visibility
app/src/main/java/com/itsaky/androidide/actions/file/ShowTooltipAction.kt
Action ID changed from "ide.editor.code.text.format" to "ide.editor.code.text.show_tooltip"; added override fun prepare(data: ActionData) to hide/disable when no editor and to enable only when selection state indicates visibility.
Fragment long-press API & dispatch
app/src/main/java/com/itsaky/androidide/fragments/EmptyStateFragment.kt
Added open val currentEditor: IDEEditor?; replaced single abstract onFragmentLongPressed() with open fun onFragmentLongPressed(x: Float = -1f, y: Float = -1f) plus a no-arg overload; long-press handling now forwards MotionEvent coordinates and short-circuits when editor is read-only.
Fragments exposing editor & tooltip tag
app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.kt, app/src/main/java/com/itsaky/androidide/fragments/output/LogViewFragment.kt
Removed fragment-specific onFragmentLongPressed() overrides; added override val currentEditor: IDEEditor? get() = editor and set editor?.tag = TooltipTag.PROJECT_BUILD_OUTPUT / editor.tag = tooltipTag in view setup.
Editor: selection from touch
editor/src/main/java/com/itsaky/androidide/editor/ui/IDEEditor.kt
Added fun setSelectionFromPoint(x: Float, y: Float) that maps touch coordinates to a packed position, extracts line/column, and calls setSelection(line, column) with error handling and early-return when released.

Sequence Diagram

sequenceDiagram
    participant User
    participant GestureDetector
    participant EmptyStateFragment
    participant IDEEditor
    Note over EmptyStateFragment: Fragment may expose currentEditor

    User->>GestureDetector: long-press at (x,y)
    GestureDetector->>EmptyStateFragment: onFragmentLongPressed(x,y)
    alt currentEditor != null and not read-only
        EmptyStateFragment->>IDEEditor: setSelectionFromPoint(x,y)
        IDEEditor->>IDEEditor: map point -> packed position
        IDEEditor->>IDEEditor: extract line,col and call setSelection
        IDEEditor-->>EmptyStateFragment: selection updated
    else no editor or read-only
        EmptyStateFragment-->>GestureDetector: no-op / ignore
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas to focus on:

  • EmptyStateFragment long-press overloads and coordinate forwarding (default params, read-only short-circuit).
  • IDEEditor.setSelectionFromPoint correctness (point → packed position math, bounds, exception handling).
  • ShowTooltipAction.prepare visibility/enablement logic and tag resolution in execAction.

Poem

🐰 A hop, a press, a pinpoint nudge,
I trace the line where characters judge.
Fragments pass the tangent true,
The editor hops and selects for you —
Tiny paws, precise little judge. 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: enabling text selection in build logs through modified long-press behavior.
Description check ✅ Passed The description is well-detailed and directly related to the changeset, explaining the UX improvement and technical implementation.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/ADFA-2106-enable-log-text-selection

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01540fc and 0f7f905.

📒 Files selected for processing (4)
  • app/src/main/java/com/itsaky/androidide/actions/file/ShowTooltipAction.kt (3 hunks)
  • app/src/main/java/com/itsaky/androidide/fragments/EmptyStateFragment.kt (3 hunks)
  • app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.kt (2 hunks)
  • app/src/main/java/com/itsaky/androidide/fragments/output/LogViewFragment.kt (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/com/itsaky/androidide/fragments/EmptyStateFragment.kt (5)
app/src/main/java/com/itsaky/androidide/fragments/RecyclerViewFragment.kt (1)
  • onFragmentLongPressed (71-73)
app/src/main/java/com/itsaky/androidide/agent/fragments/AgentFragmentContainer.kt (1)
  • onFragmentLongPressed (14-15)
app/src/main/java/com/itsaky/androidide/agent/fragments/ChatFragment.kt (1)
  • onFragmentLongPressed (95-96)
app/src/main/java/com/itsaky/androidide/fragments/debug/DebuggerFragment.kt (1)
  • onFragmentLongPressed (277-279)
app/src/main/java/com/itsaky/androidide/fragments/sidebar/BuildVariantsFragment.kt (1)
  • onFragmentLongPressed (112-114)
🔇 Additional comments (6)
app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.kt (2)

36-45: Tagging build output editor with a concrete TooltipTag is good (avoids empty-tag pitfalls).
This plays nicely with the new “Help” action using editor.tag as the tooltip key.


23-27: currentEditor override type is correct. The parent NonEditableEditorFragment.getEditor() returns IDEEditor?, and the binding's root view is explicitly typed as IDEEditor in the layout, so the override signature currentEditor: IDEEditor? is properly aligned with the fragment hierarchy.

app/src/main/java/com/itsaky/androidide/fragments/output/LogViewFragment.kt (1)

130-131: currentEditor wiring looks right for the new long-press selection behavior.

app/src/main/java/com/itsaky/androidide/actions/file/ShowTooltipAction.kt (2)

42-52: prepare() gating visibility/enabled on selection is solid (and null-safe).


33-33: The review comment's concern about action ID rename verification is not applicable here. The ShowTooltipAction uses a stable ID "ide.editor.code.text.show_tooltip" with no evidence of any rename operation. The action is properly registered in EditorActivityActions.kt (line 110), and all string resources are correctly configured across localization files. No cleanup needed.

app/src/main/java/com/itsaky/androidide/fragments/EmptyStateFragment.kt (1)

44-45: Nice direction: currentEditor hook + forwarding long-press coords is the right abstraction for selection-first UX.

Also applies to: 67-69, 179-181


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e73e832 and fdcb1b3.

📒 Files selected for processing (4)
  • app/src/main/java/com/itsaky/androidide/actions/file/ShowTooltipAction.kt (2 hunks)
  • app/src/main/java/com/itsaky/androidide/fragments/EmptyStateFragment.kt (4 hunks)
  • app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.kt (1 hunks)
  • editor/src/main/java/com/itsaky/androidide/editor/ui/IDEEditor.kt (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
editor/src/main/java/com/itsaky/androidide/editor/ui/IDEEditor.kt (1)
editor/src/main/java/com/itsaky/androidide/editor/ui/EditorFeatures.kt (2)
  • setSelection (40-44)
  • setSelection (46-58)
app/src/main/java/com/itsaky/androidide/fragments/EmptyStateFragment.kt (6)
app/src/main/java/com/itsaky/androidide/fragments/RecyclerViewFragment.kt (1)
  • onFragmentLongPressed (71-73)
app/src/main/java/com/itsaky/androidide/agent/fragments/AgentFragmentContainer.kt (1)
  • onFragmentLongPressed (14-15)
app/src/main/java/com/itsaky/androidide/agent/fragments/ChatFragment.kt (1)
  • onFragmentLongPressed (95-96)
app/src/main/java/com/itsaky/androidide/fragments/debug/DebuggerFragment.kt (1)
  • onFragmentLongPressed (277-279)
app/src/main/java/com/itsaky/androidide/fragments/output/LogViewFragment.kt (1)
  • onFragmentLongPressed (284-286)
app/src/main/java/com/itsaky/androidide/fragments/sidebar/BuildVariantsFragment.kt (1)
  • onFragmentLongPressed (112-114)
🔇 Additional comments (2)
app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.kt (1)

23-27: Expose currentEditor for unified long-press selection flow (good).
This aligns the fragment with the new EmptyStateFragment.currentEditor extension point and enables coordinate-based selection without fragment-specific hacks.

Please sanity-check on-device that after onDestroyView() (Line 45-48), no long-press path can still reference a released editor instance (e.g., via delayed events).

app/src/main/java/com/itsaky/androidide/actions/file/ShowTooltipAction.kt (1)

33-33: No action required. ShowTooltipAction is a newly added action, not a renamed one. The id "ide.editor.code.text.show_tooltip" has no prior references to update because this is a new action being introduced. The action is properly registered in EditorActivityActions.kt and all resource strings are in place.

Likely an incorrect or invalid review comment.

@jatezzz jatezzz requested review from a team, Daniel-ADFA and dara-abijo-adfa December 12, 2025 21:14
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/src/main/java/com/itsaky/androidide/fragments/EmptyStateFragment.kt (1)

60-63: Consider renaming local variable to avoid shadowing.

The local variable currentEditor shadows the class property of the same name. While functionally correct, this can be confusing when reading the code.

 	open fun onFragmentLongPressed() {
-		val currentEditor = currentEditor ?: return
-		currentEditor.selectCurrentWord()
+		val editor = currentEditor ?: return
+		editor.selectCurrentWord()
 	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fdcb1b3 and 01540fc.

📒 Files selected for processing (3)
  • app/src/main/java/com/itsaky/androidide/actions/file/ShowTooltipAction.kt (2 hunks)
  • app/src/main/java/com/itsaky/androidide/fragments/EmptyStateFragment.kt (4 hunks)
  • editor/src/main/java/com/itsaky/androidide/editor/ui/IDEEditor.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/src/main/java/com/itsaky/androidide/actions/file/ShowTooltipAction.kt
  • editor/src/main/java/com/itsaky/androidide/editor/ui/IDEEditor.kt
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/com/itsaky/androidide/fragments/EmptyStateFragment.kt (6)
app/src/main/java/com/itsaky/androidide/fragments/RecyclerViewFragment.kt (1)
  • onFragmentLongPressed (71-73)
app/src/main/java/com/itsaky/androidide/agent/fragments/AgentFragmentContainer.kt (1)
  • onFragmentLongPressed (14-15)
app/src/main/java/com/itsaky/androidide/agent/fragments/ChatFragment.kt (1)
  • onFragmentLongPressed (95-96)
app/src/main/java/com/itsaky/androidide/fragments/debug/DebuggerFragment.kt (1)
  • onFragmentLongPressed (277-279)
app/src/main/java/com/itsaky/androidide/fragments/output/LogViewFragment.kt (1)
  • onFragmentLongPressed (284-286)
app/src/main/java/com/itsaky/androidide/fragments/sidebar/BuildVariantsFragment.kt (1)
  • onFragmentLongPressed (112-114)
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build Universal APK
🔇 Additional comments (3)
app/src/main/java/com/itsaky/androidide/fragments/EmptyStateFragment.kt (3)

45-46: LGTM!

Clean extension point allowing subclasses to opt into coordinate-based selection behavior.


65-71: LGTM!

The isReadOnlyContext check correctly prevents double-dispatch of long-press handling in read-only editors, as discussed in the previous review.


178-182: LGTM!

The event handler correctly extracts coordinates from the motion event for position-aware selection.

@hasanelfalakiy
Copy link

apply it in terminal too, previously couldn't highlight/select text properly when in terminal

@dara-abijo-adfa
Copy link
Contributor

apply it in terminal too, previously couldn't highlight/select text properly when in terminal

Thank you @hasanelfalakiy
We will look into that also.

@jatezzz jatezzz merged commit 0fe47f8 into stage Dec 17, 2025
2 checks passed
@jatezzz jatezzz deleted the feat/ADFA-2106-enable-log-text-selection branch December 17, 2025 18:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants