Skip to content

fix: preserve cursor position on selection, add clickable table headers/rows#9

Merged
kjanat merged 12 commits intomasterfrom
claude/fix-table-resort-issue-Ef7sH
Jan 16, 2026
Merged

fix: preserve cursor position on selection, add clickable table headers/rows#9
kjanat merged 12 commits intomasterfrom
claude/fix-table-resort-issue-Ef7sH

Conversation

@kjanat
Copy link
Owner

@kjanat kjanat commented Jan 10, 2026

Summary

  • Fix table "jumping" when selecting a process with space bar by updating only the selection cell instead of rebuilding the entire table
  • Preserve cursor position when the table is rebuilt (refresh, view change) by restoring cursor to the same PID
  • Add mouse click support for table rows (toggles selection) and column headers (changes sort)
  • Fix CLI docs generation to preserve true colors (#98f641) instead of downgrading to basic ANSI (#00ff00)

Test plan

  • Launch TUI with uv run procclean
  • Select a process with space bar - verify cursor stays on the same row
  • Click a table row - verify it toggles selection
  • Click column headers (PID, Name, RAM, CPU, CWD) - verify sorting changes
  • Press r to refresh - verify cursor stays on the same process
  • Run uv run pytest - all 233 tests pass
  • Verify docs/cli.md contains #98f641 (not #00ff00)

Summary by CodeRabbit

  • New Features

    • Clickable table rows to toggle selection
    • Clickable headers to sort the process list
    • New "Killable" view and keybinding to show killable processes
    • Cursor restored to previous row after list updates
  • Improvements

    • Incremental selection updates to avoid full table redraws
    • Richer CLI help rendering with truecolor and HTML export
    • Project metadata (license / issues URL) added
    • Repository labeling/issue taxonomy expanded and clarified
  • Documentation

    • CLI usage blocks reformatted for clarity and parameter grouping
    • TUI keybindings table updated with the new binding

✏️ Tip: You can customize this high-level summary in your review settings.

…rs/rows

- Fix table re-sorting when selecting a process with space bar by updating
  only the selection cell instead of rebuilding the entire table
- Preserve cursor position when table is rebuilt (e.g., on refresh) by
  restoring cursor to the same PID after rebuild
- Add click handler for table rows to toggle selection on click
- Add click handler for column headers to sort by that column (PID, Name,
  RAM, CPU, CWD)
- Refactor update_table to extract _filter_by_view and _restore_cursor helpers
Use truecolor console when generating CLI docs to prevent hex colors
like #98f641 from being downgraded to basic ANSI colors like #00ff00
when running in non-TTY environments (pre-commit hooks).
@kjanat kjanat self-assigned this Jan 10, 2026
Copilot AI review requested due to automatic review settings January 10, 2026 23:50
@kjanat kjanat added bug Something isn't working feature New feature or request labels Jan 10, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 10, 2026

Warning

Rate limit exceeded

@kjanat has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 59e2af2 and da9c6ac.

📒 Files selected for processing (1)
  • src/procclean/tui/app.py

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Added a "killable" TUI view with per-row click and header-click handlers, cursor restoration, view-based filtering, and Coordinate-based single-cell updates; switched CLI help rendering to use a dedicated truecolor Rich Console and HTML export; reflowed CLI docs; updated keybindings and project metadata.

Changes

Cohort / File(s) Summary
Documentation Reformatting
docs/cli.md
Reflowed and expanded usage blocks for procclean list and procclean kill; presentational only (line breaks, grouping, wrapping).
CLI Help Generation
src/procclean/cli/docs.py
Replaced env-based color handling with a dedicated truecolor rich.console.Console; inject console into RichHelpFormatter via functools.partial, generate ANSI from parser.format_help()Text.from_ansi() and export HTML; restored original formatter. Added from functools import partial.
TUI Interactive Features
src/procclean/tui/app.py
Replaced "stale" view with "killable" in ViewType; added _filter_by_view, _restore_cursor, on_row_clicked, on_header_clicked, and action_show_killable; update flow now captures cursor PID, filters/sorts processes, repopulates rows, restores cursor, and performs Coordinate-based single-cell selection updates. Updated imports for Coordinate and row-safety handling.
Docs / Keybindings
AGENTS.md
Added keybinding O → "Show killable" to reflect the new TUI view option.
Project Metadata
pyproject.toml
Added license-files = ["LICENSE"] and project URL Issues = "https://github.com/kjanat/procclean/issues".
Repo Automation Config
.coderabbit.yaml
Expanded labeling_instructions from a single placeholder entry to a comprehensive multi-category labeling taxonomy (issue types, priority, status, components, community, maintenance, etc.).

Sequence Diagram

sequenceDiagram
    actor User
    participant DataTable as "DataTable"
    participant App as "ProcessCleanerApp"
    participant Store as "ProcessStore"

    User->>DataTable: Click row
    DataTable->>App: RowSelected event
    App->>Store: toggle selection for PID
    App->>DataTable: Update single cell using Coordinate (rgba(0, 128, 0, 0.5))
    DataTable->>User: Refresh selection indicator

    User->>DataTable: Click header (sort)
    DataTable->>App: HeaderSelected event
    App->>App: set sort key / view
    App->>Store: _filter_by_view() -> list
    App->>App: sort processes
    App->>App: _restore_cursor(table, pid)
    App->>DataTable: Repopulate rows
    DataTable->>User: Display sorted/filtered table
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels: refactor, documentation, area: tui, area: cli

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main changes: preserving cursor position and adding clickable table interactions, which align with the primary objectives and the largest code changes in src/procclean/tui/app.py.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/fix-table-resort-issue-Ef7sH

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

This comment was marked as duplicate.

coderabbitai[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

- Add width=80 to Console for consistent CLI docs text wrapping
- Save/restore parser.formatter_class in try/finally block
- Use is_orphan_candidate instead of is_orphan in TUI orphans view
- Make on_row_clicked use update_cell_at for consistency with action_toggle_select
@kjanat kjanat force-pushed the claude/fix-table-resort-issue-Ef7sH branch from 1f1d898 to 865f39b Compare January 11, 2026 10:42
coderabbitai[bot]

This comment was marked as resolved.

The orphan view was incorrectly changed to use is_orphan_candidate,
which excludes tmux orphans. This created inconsistent behavior where
processes would show [orphan] marker in All view but not appear in
Orphans view.

Changes:
- Orphan view now correctly uses is_orphan (all orphans)
- Added new Killable view using is_orphan_candidate (safe-to-kill orphans)
- Added O keybinding for killable view
- Updated AGENTS.md with new keybinding

This maintains CLI/TUI consistency: -o shows orphans, -k shows killable.
@github-actions
Copy link

github-actions bot commented Jan 11, 2026

📦 Test this PR (archived)

Status: ✅ Merged

This PR has been merged. You can still test the final state:

uvx --from git+https://github.com/kjanat/procclean@da9c6ac807a32c067259ffa415876107af942013 procclean
📋 PR Details
Field Value
Final commit da9c6ac807a32c067259ffa415876107af942013
Commit message refactor: use row key lookup in _restore_cursor
Branch claude/fix-table-resort-issue-Ef7sH

Merge commit: f504d02eba8bf2d59e0b55d547a083095560b35e

Available commands:

# Launch TUI (default)
uvx --from git+https://github.com/kjanat/procclean@da9c6ac807a32c067259ffa415876107af942013 procclean

# List processes
uvx --from git+https://github.com/kjanat/procclean@da9c6ac807a32c067259ffa415876107af942013 procclean list

# Show memory summary
uvx --from git+https://github.com/kjanat/procclean@da9c6ac807a32c067259ffa415876107af942013 procclean mem

# Show help
uvx --from git+https://github.com/kjanat/procclean@da9c6ac807a32c067259ffa415876107af942013 procclean --help

🤖 Archived on merge

coderabbitai[bot]

This comment was marked as outdated.

columns is a dict[ColumnKey, Column], not indexable by int.
ordered_columns is the list property that preserves column order.
get_row_at returns a list of cell values, not a row key.
Also fix comment that incorrectly said 'tuple'.
coderabbitai[bot]

This comment was marked as outdated.

Signed-off-by: Kaj Kowalski <info@kajkowalski.nl>
- Add try/except for ValueError/IndexError in cursor restore
- Simplify groups view filter with list comprehension
- Document sortable vs non-sortable columns in header click handler
coderabbitai[bot]

This comment was marked as resolved.

@coderabbitai coderabbitai bot added the none label Jan 16, 2026
@kjanat kjanat removed the none label Jan 16, 2026
- Add RowDoesNotExist exception handling in on_row_clicked to prevent
  crashes when auto-refresh removes rows mid-event
- Populate labeling_instructions with all labels from .github/labels.yml
- Fix column index comment (Status is at index 8, not 6)
Replace hardcoded column index iteration with get_row_index() using
the PID-based row key. Falls back to row 0 when PID no longer exists.
@coderabbitai coderabbitai bot added the area: cli Related to CLI interface label Jan 16, 2026
@coderabbitai coderabbitai bot added area: tui Related to TUI interface documentation Improvements or additions to documentation refactor Code refactoring without behavior change labels Jan 16, 2026
@kjanat kjanat merged commit f504d02 into master Jan 16, 2026
4 checks passed
@kjanat kjanat deleted the claude/fix-table-resort-issue-Ef7sH branch January 16, 2026 03:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Related to CLI interface area: tui Related to TUI interface bug Something isn't working documentation Improvements or additions to documentation feature New feature or request refactor Code refactoring without behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments