description box: right border is offset for CJK / wide characters (padded by code units, not display width)
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
- 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" },
],
};- Start
isand typeopencode 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:

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 --version→0.0.4 - macOS 27.0 (26A428)
- zsh
- VS Code integrated terminal
Related: #175, #302
Source: microsoft/inshellisense