모드 라인에서 버퍼 이름을 고정 폭으로 채워서 뒤에 오는 것들이 줄 맞게 해 뒀는데, 꽤 오랫동안 잘 됐어요(정확히는 제가 우연히 열어 본 버퍼들에서는요).
(defun my/pad-name (name width)
(concat name (make-string (max 0 (- width (length name))) ?\s)))
그러다 회의록.org를 열었더니 그 오른쪽이 전부 세 칸 밀렸어요. length는 문자 수를 세는데, 한글 음절 세 개는 문자로는 세 개지만 화면에서는 하나가 두 칸씩 차지하거든요. (string-width "회의록")은 6, (length "회의록")은 3이에요. (M-:로 둘 다 쳐 보면 바로 보여요.)
처음부터 칸 단위로 세는 함수를 쓰면 해결돼요.
(defun my/pad-name (name width)
(truncate-string-to-width name width nil ?\s))
짧은 이름은 채우고 긴 이름은 잘라서 같은 폭으로 맞춰 줘요. (매뉴얼에도 string-width는 근삿값이라고 솔직하게 적혀 있어요. 조합 문자나 글꼴에 따라 틀릴 수 있지만 한글 음절은 제대로 나와요.) 앞으로의 대충의 원칙은, 화면에 나갈 건 length가 아니라 string-width로 잰다는 거예요.
영어에서 번역·원문 보기Padded the buffer name in my mode line to a fixed width so the bits after it line up, and it worked for a long while (well, in every buffer I happened to open).
(defun my/pad-name (name width)
(concat name (make-string (max 0 (- width (length name))) ?\s)))
Then I opened 회의록.org and everything to the right of it slid over by three columns. length counts characters, and three Hangul syllables are three characters, but each one takes two columns on screen. (string-width "회의록") says 6, (length "회의록") says 3. (M-: both and you'll see it straight away.)
The fix is a function that counts columns to begin with.
(defun my/pad-name (name width)
(truncate-string-to-width name width nil ?\s))
It pads short names and cuts long ones to the same width. (The manual is upfront that string-width is an approximation, composed characters and fonts can still fool it, but Hangul syllables come out right.) Rough rule from here on, anything headed for the screen gets measured with string-width and never with length.