microsoft / microsoft/inshellisense

description box: right border is offset for CJK / wide characters (padded by code units, not display width)

Open Beginner friendly
#477 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
10.7k
Forks
256
Avg merge
1d 23h
Merged PRs (30d)
11

Description

Describe the bug

The suggestion description box (the right-hand box) is padded with String.prototype.padEnd, which counts UTF-16 code units, while renderBox() draws the border assuming the row occupies exactly width terminal columns. Whenever a description contains characters whose display width differs from their code-unit length — CJK text, BMP-wide emoji (e.g. U+2B50), ZWJ emoji sequences — the right border is offset: pushed out for wide characters, pulled in for ZWJ sequences.

The suggestion name box is unaffected, because truncateText() already pads with wcPadEnd()/wcswidth().

To Reproduce
  1. Add a local spec via specs.path:

~/.config/inshellisense/rc.toml

[specs]
path = ["/Users/<you>/.config/inshellisense/specs"]

~/.config/inshellisense/specs/index.js

const specs = ["opencode"];
const diffVersionedCompletions = [];
export { specs as default, diffVersionedCompletions };

~/.config/inshellisense/specs/opencode.js

export default {
  name: "opencode",
  description: "OpenCode command line interface",
  subcommands: [
    { name: ["upgrade", "update"], description: "⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐" },
    { name: "auth", description: "以一条消息运行 OpenCode" },
  ],
};
  1. Start is and type opencode up
Actual behaviour

The description box's right border does not line up with the top border. With 10 × U+2B50 the row is padded to 38 columns instead of 28:

wide characters break the description box right border

Expected behaviour

Every row is padded to width display columns, so the box borders stay aligned, exactly like the name box.

Root cause

src/ui/utils.ts:37

return truncatedLines.map((line) => line.padEnd(width));

padEnd pads to width code units, but renderBox() (line 15) emits "│" + row + "│" assuming row is width columns wide. Measured with the repo's own wcswidth() (width = 28, i.e. descriptionWidth - borderWidth):

sample code units display cells padEnd → cells wcPadEnd → cells
Run OpenCode with a message 27 27 28 ✓ 28 ✓
以一条消息运行 OpenCode 16 23 35 28 ✓
⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ (U+2B50) 10 20 38 28 ✓
🚀🚀🚀🚀🚀🚀🚀🚀 (U+1F680) 16 16 28 ✓ (coincidence) 28 ✓
👨‍👩‍👧👨‍👩‍👧👨‍👩‍👧 24 18 22 28 ✓

Note that astral emoji happen to match (2 code units = 2 columns), which is why the bug can look like it only affects CJK; ZWJ sequences fail in the opposite direction.

Suggested fix

Use the display-width helper that already exists in the same file and is already used by truncateText():

return truncatedLines.map((line) => wcPadEnd(line, width));

ASCII descriptions are unaffected (wcswidth(text) === text.length for them). PR to follow.

Environment
  • inshellisense 0.0.4 (Homebrew), is --version0.0.4
  • macOS 27.0 (26A428)
  • zsh
  • VS Code integrated terminal

Related: #175, #302

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/ui/utils.ts at line 37 and read renderBox() near line 15, then compare the description padding with truncateText() and the existing wcswidth() helper. Reproduce with the CJK, wide-star, and ZWJ descriptions from the issue. Done means every description row occupies the configured display width and the right border aligns with the top border.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Bug
Difficulty
1/5
Estimated time
Under an hour
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
92/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.