org-mode tag 有中文时的对齐问题

我估计大家看到标题就知道说的是啥了
一般中文字体像素宽度是英文的 1.5 倍,
但是宽度是 2 倍
当然有字体是让中文字符变为英文两倍宽的, 就能解决一切问题, 但是真的难看

(string-width "啊") => 2

就导致 markdown 和 org 的 table, elfeed, org 的 tag, 等等一大堆涉及到对齐的东西都很难受
现在第一个可以用 valign 这个包, 第二个也有解决方案(变量 elfeed-search-print-entry-function)
那第三个如何解决?

还有如果有可能的话, 能不能让 tag 对齐到 buffer 右边, 而不是一个特定的列

tag 最烦的是在用 variable-pitch-mode 的时候,根本对不齐,只能把它放在 buffer 右边。

(add-hook 'org-mode-hook (lambda () (font-lock-add-keywords 'org-mode '(yant/org-align-tags) t)) 100)
(add-hook 'org-mode-hook (lambda () (add-to-list 'font-lock-extra-managed-props 'org-tag-aligned)))

(defun yant/org-align-tags (limit &optional force)
    "Align all the tags in org buffer."
    (save-match-data
      (when (eq major-mode 'org-mode)
	(while (re-search-forward "^\\*+ \\(.+?\\)\\([ \t]+\\)\\(:\\(?:[^ \n]+:\\)+\\)$" limit t)
	  (when (and (match-string 2)
		     (or force
			 (not (get-text-property (match-beginning 2) 'org-tag-aligned))))
	    (with-silent-modifications
              (put-text-property (match-beginning 2) (match-end 2) 'org-tag-aligned t)
	      (put-text-property (if (>= 2 (- (match-end 2) (match-beginning 2)))
				     (match-beginning 2)
				   ;; multiple whitespaces may mean that we are in process of typing
				   (1+ (match-beginning 2)))
				 (match-end 2)
				 'display
				 `(space . (:align-to (- right
							 (,(+ 3 ;; no idea, but otherwise it is sometimes not enough
							      (string-display-pixel-width org-ellipsis)
							      (string-display-pixel-width (or (match-string 3)
											      ""))))))))))))))

(defun string-display-pixel-width (string &optional mode)
  "Calculate pixel width of STRING.
Optional MODE specifies major mode used for display."
  (with-temp-buffer
    (with-silent-modifications
      (setf (buffer-string) string))
    (when (fboundp mode)
      (funcall mode)
      (font-lock-fontify-buffer))
    (if (get-buffer-window (current-buffer))
	(car (window-text-pixel-size nil (line-beginning-position) (point)))
      (set-window-buffer nil (current-buffer))
      (car (window-text-pixel-size nil (line-beginning-position) (point))))))

详见:variable-pitch-mode misaligns org-mode heading tags

2 个赞

?

Error during redisplay: (jit-lock-function 1) signaled (wrong-type-argument char-or-string-p nil)
Error during redisplay: (jit-lock-function 1501) signaled (wrong-type-argument char-or-string-p nil)

你用的是 Doom ?可以开 toggle-debug-on-error,把详细信息贴出来。

nil 是从这个地方传进来的
我把那块注释掉了就好使了,
谢谢啦

因为 org-ellipsis 也会占字符宽度,加上一般都会设,所以没加判断 :joy:

请问这里的org-tag-aligned是自定义函数么?我没在org代码里找到。

它就是个文本属性,用来帮助判断的,表示已对齐

明白了。我这边没效果,后面再排查一下原因。感谢感谢。