给emacs的行号添加右边距使其样式看上去像vscode

这是vscode的行号

这是emacs的行号

对比可以发现,emacs的行号离代码的距离有些太近了,显得太紧凑了,没有vscode中看上去令人舒服。(当然,喜好因人而异)

为了让emacs的行号更像vscode,我们需要增大emacs行号的右边距。可是,emacs中并没有调节行号右边距的变量。

一番搜索下来,我找到了这篇stackexchange的回答。

总结来说,emacs的行号是由 位于 $emacs_repo/src/xdisp.c 中的这两个函数生成的。

pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
strcat (lnum_buf, " ");

其中,第一个函数将行号字符串存在变量 lnum_buf 中,第二个函数给这个字符串右边添加一个空格。我们只需要给第二和函数的空格增多一些,就能增加行号的右边距。

pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
strcat (lnum_buf, "   ");

实践下来,3个空格的右边距是类似vscode的。

改完这段代码后,重新编译emacs,安装,启动。

整体效果如图所示:

当然,为了更接近vscode的效果,你还可以调节display-highlight-line group中的变量,比如把 Display Line Numbers Width 的值调成4。

4 个赞

当然,通过改emacs的代码来调节行号右边距也太离谱了,而且这种配置也不能保存到配置文件中方便部署。所以说,这只能是一个没什么用的小技巧。如果有可能,我还是希望有一个内部变量可以调节。

1 个赞

可以给emacs发个补丁,把这个做成选项。

1 个赞

我目前还不知道这个C文件里的变量是怎么一步步最终由一个custom变量决定的,不过我可以研究。

但是,如果把这个做成选项的话,怎么命名合适呢?如果把这个变量叫做“右边距”,那其他变量的名字看上去会不会有一些不合理?是不是都要修改?

而且还要考虑像r2l文字这种事情

(忽略里面的configed应该为configured的拼写错误)

起名字这种事情,ChatGPT最擅长了,哈哈哈哈

赞👍🏻️ 我也一直想要这个功能

忍耐不住已经自己 patch 上了(

期待LZ完全体实现早日合入主线

diff --git a/src/xdisp.c b/src/xdisp.c
index 11417070804..39d8fb5894f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -24437,7 +24437,7 @@ maybe_produce_line_number (struct it *it)
 
   /* Produce the glyphs for the line number.  */
   struct it tem_it;
-  char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
+  char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 10];
   bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false;
   ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
   int lnum_face_id = merge_faces (it->w, Qline_number, 0, DEFAULT_FACE_ID);
@@ -24507,7 +24507,7 @@ maybe_produce_line_number (struct it *it)
      following line, so the paragraph direction might be unknown.
      Therefore we cheat and add 2 blanks, one on either side.  */
   pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
-  strcat (lnum_buf, " ");
+  strncat (lnum_buf, "          ", max (0, min (10, line_number_extra_spaces)));
 
   /* Setup for producing the glyphs.  */
   init_iterator (&tem_it, it->w, -1, -1, &scratch_glyph_row,
@@ -36781,6 +36781,11 @@ syms_of_xdisp (void)
 line number may be omitted from the mode line.  */);
   line_number_display_limit_width = 200;
 
+  DEFVAR_INT ("line-number-extra-spaces",
+	      line_number_extra_spaces,
+    doc: /* The number of spaces attached after the line number. */);
+  line_number_extra_spaces = 1;
+
   DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
     doc: /* Non-nil means highlight active region even in nonselected windows.
 When nil (the default), the active region is only highlighted when

update: 避免 buffer overflow

7 个赞

1、请在句号后加上两个空格字符。

2、为什么要强制选项的最高值呢?

3、你这样容易写出 lnum_buf,因为目前大小是 INT_STRLEN_BOUND (ptrdiff_t) + 1。

4 个赞

好的,下次注意hhh 自己用的没那么讲究

@A7R7 我修改了标题。去掉了「没什么用的小技巧」,不要否定自己的努力。

@oldosfan 如果想在行号末尾加分隔符,比如添加竖线 (#x2502) 该怎么做?

1 个赞

这个我不太清楚,应该问 Eli Zaretskii

这个直接把strcat (lnum_buf, " ");改成 strcat (lnum_buf, " │");或许可以?我待会试试

window左侧的边缘本身是有边界的,要让边界更鲜明,自己改一下行号对应的face就是,没必要另外加unicode字符,终端还得另外处理

哈哈哈,我还想让 vscode 的行号边距像 emacs/vim 一样紧凑点呢

我连行号都关了 :sweat_smile:,太占地方,其实平时不怎么看行号。vim 用户估计离不开行号。

1 个赞

我也是,关了行号,感觉太占空间,然后把mode-line和header-line的第一个字符都设成了行号

字数也不是越多越好,还是要取得一个视觉上的平衡。

我的屏幕宽度 1280,水平分割之后 900,我觉得 4 位数的行号是可以接受的。不然正文太靠近屏幕边缘,看着有点压抑。

如果是台式机大屏幕,行号的宽度应该更宽,才不会视觉失衡。

1 个赞

我不用行号,而且我觉得紧凑一点不更好嘛。

我认为跟face和margin/fringe也有一定关系。left fringe/margin 加大一点,行号配色暗一点,这样看起来也会协调不少。不一定非要像vscode一样。要节约宝贵的屏幕空间啊 :joy:

当然,多个配置选项是最好了,就像以前的linum一样。

image

确实, left fringe 和 margin 可以调节左边距。但我同时还很喜欢用 olivetti-mode,可以让界面看上去像word和typora,这个mode把 left fringe 和 margin 给自动设置好了,这样要再调节行号宽度(左边距)的话,就只有 display-line-numbers-width 可以调了。

其实我的真实想法并不是把行号配得像vscode ,而是更夸张一点 :sunglasses:,把行号放窗口最左边,文字放到屏幕正中间,文字和行号隔挺大一片距离。因此我研究了一下增大行号右边距的方法。不过这么做会break很多东西。

anyway我只是把搜到的东西分享给大家瞧一瞧看一看,至于怎么做当然是一千个哈姆雷特

1 个赞