Files
logseq/docs/agent-guide/079-logseq-cli-list-title-display-width.md
2026-04-07 23:49:58 +08:00

11 KiB

Logseq CLI List Title Display Width Implementation Plan

Goal: Make every TITLE column in logseq list * human output use a fixed maximum visual width with correct CJK-aware width handling via string-width.

Architecture: Keep list data retrieval unchanged in db-worker-node thread APIs and implement presentation-only changes in the CLI formatter layer.

Architecture: Introduce a display-width-aware truncation and padding path that is applied to list title cells before table rendering.

Tech Stack: ClojureScript, logseq.cli.format, logseq.cli.command.list, db-worker thread APIs in frontend.worker.db-core, JavaScript string-width.

Related: Builds on docs/agent-guide/062-logseq-cli-list-default-sort-updated-at.md, docs/agent-guide/066-logseq-cli-list-property-cardinality-column.md, docs/agent-guide/078-logseq-cli-task-subcommands.md, and docs/cli/logseq-cli.md.

Problem statement

Current human table rendering in src/main/logseq/cli/format.cljs uses (count text) for width calculation and right padding.

count is code-point length, not terminal display width.

This breaks alignment when titles contain CJK or mixed-width text.

Current list human output also allows unbounded title length, which can push important columns out of view for list page, list tag, list property, and list task.

We need a stable, readable table contract where TITLE is capped to a reasonable visual width and aligned correctly for mixed-language content.

Current baseline from implementation

The active CLI stack is the src/main/logseq/cli/* implementation, not the legacy deps/cli command stack.

List command data is produced by db-worker helpers and returned through thread APIs without formatter concerns.

The relevant path is:

logseq list <page|tag|property|task>
  -> /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/list.cljs
  -> transport/invoke :thread-api/cli-list-*
  -> /Users/rcmerci/gh-repos/logseq/src/main/frontend/worker/db_core.cljs
  -> /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/common/db_worker.cljs
  -> /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/format.cljs

TITLE columns are defined in formatter column configs in src/main/logseq/cli/format.cljs.

All table rendering goes through render-table and format-counted-table in the same file.

Scope

In scope commands are:

Command Human output table has TITLE column Source formatter function
logseq list page Yes format-list-page
logseq list tag Yes format-list-tag
logseq list property Yes format-list-property
logseq list task Yes format-list-task

The default max visual width target for title is 40 columns.

The value is configurable in cli.edn via a new CLI config key.

The cap is measured by display width, not character count.

Out of scope commands include search *, query list, graph list, and server list.

Out of scope outputs include JSON and EDN payload shape changes.

Design decisions

1) Keep db-worker-node payloads unchanged

No changes are required in src/main/logseq/cli/common/db_worker.cljs or thread API wiring in src/main/frontend/worker/db_core.cljs.

db-worker should continue returning full :block/title values.

Human formatting is the only layer that applies visual truncation.

2) Add explicit title max-width policy in formatter

Introduce a formatter default constant such as list-human-title-max-display-width-default with value 40.

Read an optional override from resolved CLI config using a new cli.edn key :list-title-max-display-width.

Apply this policy only to TITLE extractors in list column definitions.

Truncated values append a suffix and remain within the max display width.

3) Use string-width for display width operations

Add npm interop in src/main/logseq/cli/format.cljs for string-width.

Use string-width for:

  • Width measurement during truncation.
  • Width measurement during table column width calculation.
  • Padding logic in pad-right or equivalent.

This ensures CJK and mixed-width titles align with other columns.

4) Preserve existing list data semantics

Sorting, filtering, --fields, --limit, and --offset behavior in src/main/logseq/cli/command/list.cljs remain unchanged.

Only rendered human strings are affected.

5) Keep non-list command behavior stable

Prefer implementing title truncation in list-specific extractors.

If render-table is upgraded to display-width-aware padding globally, verify non-list tables are unaffected except improved alignment.

Proposed implementation steps

  1. Invoke @test-driven-development and add failing formatter tests for long ASCII title truncation in each list command.

  2. Add failing formatter tests for long CJK and mixed CJK/ASCII titles in each list command.

  3. Add failing config resolution tests in src/test/logseq/cli/config_test.cljs for :list-title-max-display-width, including default fallback to 40 and valid cli.edn override.

  4. Add a focused formatter unit test for truncation helper behavior ensuring output display width is <= 40 and suffix handling is correct.

  5. Add a focused formatter unit test for width-aware padding behavior with CJK text so column alignment is deterministic.

  6. Add config normalization helpers in src/main/logseq/cli/config.cljs to parse and validate :list-title-max-display-width as a positive integer.

  7. Add string-width import and helper functions in src/main/logseq/cli/format.cljs.

  8. Add title truncation helper and wire it into the TITLE extractor entries in list-page-columns, list-tag-columns, list-property-columns, and list-task-columns.

  9. Replace (count ...)-based width and padding internals in table rendering with display-width-aware logic.

  10. Run formatter and config tests and update exact spacing snapshots where needed.

  11. Update user-facing docs in docs/cli/logseq-cli.md to mention that list human TITLE uses default width 40, supports cli.edn override, and always truncates with .

  12. Optionally add one CLI e2e non-sync human-output case for long mixed-width title rendering if we want package-level regression protection.

Files to modify

  • /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/config.cljs.
  • /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/config_test.cljs.
  • /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/format.cljs.
  • /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/format_test.cljs.
  • /Users/rcmerci/gh-repos/logseq/docs/cli/logseq-cli.md.
  • /Users/rcmerci/gh-repos/logseq/cli-e2e/spec/non_sync_cases.edn (optional, only if we decide to cover human output end-to-end).
  • /Users/rcmerci/gh-repos/logseq/package.json (only if string-width is added as an explicit direct dependency).

Edge cases to cover

A title with only CJK characters that exceeds max width.

A title with alternating CJK and ASCII characters.

A title exactly at width boundary.

A title one display cell over boundary.

A title containing emoji or variation selectors.

A nil title where current logic falls back to -.

A title containing newlines where current multiline row rendering is preserved.

A very short title where no extra truncation marker appears.

An invalid cli.edn width value such as 0, negative numbers, or non-numeric values that must fall back to default 40.

Risks and mitigation

Risk: Moving width calculations to display width can shift spacing in non-list tables.

Mitigation: Add or adjust tests for affected command outputs and constrain behavioral changes to alignment only.

Risk: string-width import style may vary by bundling mode.

Mitigation: Verify in unit tests and CLI runtime, and choose the interop form that matches current CJS usage conventions in the repo.

Risk: New truncation can reduce discoverability of long titles.

Mitigation: Keep JSON and EDN outputs untruncated and document this behavior clearly.

Risk: Invalid cli.edn width values can produce inconsistent rendering if not normalized.

Mitigation: Parse as positive integer with fallback to default 40 and add config tests for invalid values.

Open questions

No open question.

Decisions locked for this plan are default width 40, cli.edn configurability, truncation suffix , and list-only scope.

Testing Plan

I will add formatter behavior tests in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/format_test.cljs that verify title truncation and alignment for list page, list tag, list property, and list task human output.

I will add helper-level tests in the same test namespace to validate width-aware truncation and padding with CJK and mixed-width samples.

I will add config tests in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/config_test.cljs to validate default value 40, cli.edn override, and invalid-value fallback behavior.

I will run focused tests first with bb dev:test -v logseq.cli.format-test/test-human-output-list-page, bb dev:test -v logseq.cli.format-test/test-human-output-list-tag-property, and bb dev:test -v logseq.cli.format-test/test-human-output-list-task.

I will run broader CLI tests with bb dev:test -v logseq.cli.format-test and config tests with bb dev:test -v logseq.cli.config-test.

If e2e coverage is added, I will run bb -f cli-e2e/bb.edn test --skip-build.

I will finish with bb dev:lint-and-test.

NOTE: I will write all tests before I add any implementation behavior.

Step-by-step execution checklist

Step Action Verification
1 Add failing list title truncation tests. Tests fail with current unbounded title output.
2 Add failing CJK width alignment tests. Tests fail due current count-based width logic.
3 Add failing config tests for :list-title-max-display-width. Tests fail before config parsing is implemented.
4 Implement config parsing with default 40 and invalid fallback. Config tests pass for default and override behavior.
5 Implement string-width helpers. Helper tests pass.
6 Implement title truncation in list column extractors. List tests show bounded title width and suffix.
7 Switch table padding/width to display-width-aware logic. CJK alignment tests pass.
8 Update docs and optional e2e. Docs mention truncation behavior and tests stay green.
9 Run full regression. bb dev:lint-and-test passes.

Testing Details

The tests validate observable CLI behavior by asserting final human output strings for list commands, including truncation marker presence and table alignment under mixed-width input.

The tests do not assert internal helper data structures beyond what is needed to validate final output semantics.

Implementation Details

  • Keep default max title width as formatter constant 40.
  • Allow override from cli.edn key :list-title-max-display-width.
  • Parse config width as positive integer and fall back to default on invalid values.
  • Truncate by display width instead of character count.
  • Keep truncation policy limited to list TITLE columns.
  • Always use as truncation suffix in human list output.
  • Preserve db-worker payload contracts and thread API names.
  • Preserve JSON and EDN full title output.
  • Ensure multiline table behavior is not regressed.
  • Document human-output-only truncation and config override in CLI docs.

Question

No blocking question for implementation.