Skip to content

Enhance panel display and scrollbar alignment#14

Merged
leszek3737 merged 3 commits into
mainfrom
0.0.13
May 6, 2026
Merged

Enhance panel display and scrollbar alignment#14
leszek3737 merged 3 commits into
mainfrom
0.0.13

Conversation

@leszek3737

@leszek3737 leszek3737 commented May 6, 2026

Copy link
Copy Markdown
Owner

Summary by Sourcery

Adjust panel and viewer layout to improve scrollbar alignment and add configurability for displaying file permissions.

New Features:

  • Introduce a per-panel setting to toggle display of file permissions in listings and the status bar, persisted across sessions and exposed via the Options menu.

Enhancements:

  • Change timestamp formatting in panel listings to a shorter YY-MM-DD HH:MM form and update tests accordingly.
  • Align panel list and scrollbar by using a fixed-width column for the scrollbar regardless of overall panel width.
  • Ensure long listing filenames are padded so size/date/permission columns stay vertically aligned and handle Unicode truncation more robustly.
  • Simplify viewer and hex viewer borders to only top and bottom, adjusting inner margins for a cleaner layout.

Tests:

  • Update and extend tests to cover the new permissions toggle behavior, revised time and entry formatting, and menu configuration changes.

@sourcery-ai

sourcery-ai Bot commented May 6, 2026

Copy link
Copy Markdown

Reviewer's Guide

Refines panel and viewer layout/scrollbar behavior, introduces a user-toggleable and persisted “show permissions” option affecting long listing and status bar, updates date formatting to a shorter YY-MM-DD format, and adjusts tests/config/menu wiring accordingly.

Sequence diagram for toggling permissions display in panel

sequenceDiagram
    actor User
    participant Menu as MenuUI
    participant Input as InputHandler
    participant App as AppState
    participant Panel as PanelState
    participant UI as PanelRenderer

    User->>Menu: Select Show_permissions
    Menu->>Input: MenuAction TogglePermissions
    Input->>App: execute_panel_action(TogglePermissions)
    App->>Panel: active_panel_mut()
    App->>Panel: toggle show_permissions
    App->>App: set status_message
    App-->>Input: Some(None)

    User->>UI: Next render tick
    UI->>App: read active PanelState
    UI->>Panel: render_panel(..., show_permissions)
    UI->>Panel: render_status_bar(..., show_permissions)
    Panel-->>User: Panel list and status bar with permissions visibility updated
Loading

Class diagram for panel state, persisted panel, and menu actions

classDiagram
    class PanelState {
        +SortMode sort_mode
        +ListingMode listing_mode
        +bool show_hidden
        +bool show_permissions
        +Option_String filter
        +usize selected_count
        +u64 selected_size
    }

    class PersistedPanel {
        +PathBuf cwd
        +SortMode sort_mode
        +String filter
        +bool show_hidden
        +bool show_permissions
    }

    class AppState {
        +PanelState left_panel
        +PanelState right_panel
        +ActivePanel active_panel
        +Option_String status_message
        +PanelState active_panel_mut()
    }

    class MenuAction {
        <<enumeration>>
        ToggleHiddenFiles
        TogglePermissions
        ToggleLayoutMode
        TogglePanelHidden
        ResetPanelFilter
        SaveSetup
        DirectoryHotlist
        SaveCurrentPathToHotlist
    }

    class PanelsModule {
        +render_panel(f, area, panel, is_active)
        +render_status_bar(f, area, panel)
        +format_entry_line(entry, width, show_permissions) String
    }

    class ConfigModule {
        +panel_to_persisted(panel) PersistedPanel
        +apply_panel(panel, persisted)
    }

    class MenuActionsModule {
        +execute_panel_action(action, state) Option_Option_KeyEvent
    }

    AppState "1" o-- "1" PanelState : active_panel
    AppState "1" o-- "1" PanelState : other_panel

    ConfigModule ..> PanelState : use
    ConfigModule ..> PersistedPanel : create_apply

    MenuActionsModule ..> AppState : mutate
    MenuActionsModule ..> MenuAction : consume

    PanelsModule ..> PanelState : read
    PanelsModule ..> FileEntry : format

    PersistedPanel --> PanelState : applied_to
    MenuAction --> MenuActionsModule : handled_by
Loading

File-Level Changes

Change Details Files
Adjust time formatting to a shorter, two-digit year representation and update related tests.
  • Change format_time output from YYYY-MM-DD HH:MM to YY-MM-DD HH:MM while preserving local timezone conversion.
  • Update fallback invalid-time strings to match the shorter format.
  • Relax unit test expectations for format_time string length to reflect the new format.
src/ui/panels.rs
Rework panel layout and entry rendering to better align the scrollbar and improve long-listing column behavior, including optional permission display and padding.
  • Change the horizontal layout split to use a minimal main area plus fixed 1-column scrollbar, improving alignment across widths.
  • Extend format_entry_line signature to accept a show_permissions flag and pass it from render_panel based on PanelState.
  • Simplify suffix selection logic for size/date/permission fields, conditionally including permissions only when enabled and space allows.
  • Ensure file name column is padded so the suffix columns stay vertically aligned even with truncation and Unicode names.
  • Update tests for format_entry_line to call the new signature, tweak truncation tests, and adjust Unicode test data.
src/ui/panels.rs
Tighten viewer and hex-view layout so borders align with panels and scrollbar column, avoiding extra side padding.
  • Change viewer and hex viewer blocks to draw only top and bottom borders instead of all sides.
  • Set horizontal margin to zero in viewer and hex viewer so content lines up with panel columns.
  • Remove the separate background block in hex viewer and apply panel styling directly to the main block.
src/ui/viewer.rs
Introduce a per-panel, persisted "show permissions" option, with menu wiring and runtime behavior changes.
  • Add show_permissions field to PanelState with default false and use it to control permission display in long listing and status bar.
  • Extend persisted panel configuration to serialize/deserialize show_permissions and apply it when loading settings.
  • Add a new menu item and MenuAction (TogglePermissions) in the Options menu and wire it to toggle PanelState.show_permissions and set a status message.
  • Adjust menu_action_at test expectations due to the increased number of options menu items.
  • Update compare and config-related tests to include the new show_permissions field in PanelState and PersistedPanel expectations.
src/app/types.rs
src/app/config.rs
src/menu.rs
src/input/menu_actions.rs
src/ops/compare.rs
src/ui/panels.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In format_entry_line, the suffix selection logic now builds and measures three separate strings on every call; consider refactoring to reuse computed widths/strings or branch earlier on show_permissions to avoid unnecessary allocations.
  • In render_status_bar, the full_info/meta branches duplicate the formatting of name/size/owner/group and recompute permissions when show_permissions is true; extracting a small helper to build these segments once would simplify the code and reduce repetition.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `format_entry_line`, the suffix selection logic now builds and measures three separate strings on every call; consider refactoring to reuse computed widths/strings or branch earlier on `show_permissions` to avoid unnecessary allocations.
- In `render_status_bar`, the `full_info`/`meta` branches duplicate the formatting of name/size/owner/group and recompute permissions when `show_permissions` is true; extracting a small helper to build these segments once would simplify the code and reduce repetition.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request implements a "Show permissions" toggle for file panels, enabling users to view file mode bits in long listing mode and the status bar. The changes involve updates to configuration persistence, menu actions, and UI rendering logic. The feedback recommends maintaining a consistent date format throughout the application, optimizing performance by minimizing redundant string allocations in the rendering loop, and addressing a visual inconsistency introduced by changing the viewer's border style.

Comment thread src/ui/panels.rs
Comment on lines +54 to +57
"{:02}-{:02}-{:02} {:02}:{:02}",
local.day(),
local.month(),
local.year() % 100,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The date format has been changed from ISO-like YYYY-MM-DD to DD-MM-YY. This introduces an inconsistency with FileEntry::display_modified in src/app/types.rs (line 682), which still uses %Y-%m-%d. It is recommended to maintain a consistent date format across the application, preferably ISO 8601 for clarity and to avoid regional ambiguity.

Comment thread src/ui/panels.rs Outdated
Comment on lines +178 to +180
let full_with_perms = format!(" {size_str} {date_str} {perms_str}");
let full_no_perms = format!(" {size_str} {date_str}");
let nd = format!(" {size_str}");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

These format! calls are executed for every visible file entry in the panel on every frame render. This results in a high number of redundant string allocations. It would be more efficient to calculate the visual widths of the individual components (size_str, date_str, perms_str) first and only perform the format! call for the suffix that actually fits the available width.

        let size_width = UnicodeWidthStr::width(size_str.as_str());
        let date_width = UnicodeWidthStr::width(date_str.as_str());
        let perms_width = UnicodeWidthStr::width(perms_str.as_str());

        if show_permissions && 2 + size_width + 1 + date_width + 1 + perms_width <= width {
            let full = format!(" {size_str} {date_str} {perms_str}");
            let w = size_width + date_width + perms_width + 3;
            (full, w)
        } else if 2 + size_width + 1 + date_width <= width {
            let full = format!(" {size_str} {date_str}");
            let w = size_width + date_width + 2;
            (full, w)
        } else if 2 + size_width <= width {
            let full = format!(" {size_str}");
            let w = size_width + 1;
            (full, w)
        } else {
            (String::new(), 0)
        }

Comment thread src/ui/panels.rs Outdated
Comment on lines +352 to +363
let full_info = if panel.show_permissions {
let perms_str = format_permissions(entry.mode_bits());
format!(
"{} | {} | {} | {} | {}",
entry.name, size_str, perms_str, entry.owner, entry.group,
)
} else {
format!(
"{} | {} | {} | {}",
entry.name, size_str, entry.owner, entry.group,
)
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Similar to the file entry formatting, this logic performs redundant format! calls and string allocations in the status bar rendering. Calculating widths before formatting would improve performance.

Comment thread src/ui/viewer.rs
pub fn render_viewer(f: &mut Frame, area: Rect, state: &ViewerState) {
let block = Block::default()
.borders(Borders::ALL)
.borders(Borders::TOP | Borders::BOTTOM)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Changing the viewer borders to TOP | BOTTOM only creates a visual inconsistency with the main file panels, which use Borders::ALL. If the intention was to maximize horizontal space, consider if this inconsistency is acceptable for the overall UI design.

@leszek3737
leszek3737 merged commit c8a1e9d into main May 6, 2026
5 checks passed
@leszek3737
leszek3737 deleted the 0.0.13 branch May 6, 2026 05:36
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.

1 participant