neoclide / coc.nvim

Nodejs extension host for vim & neovim, load extensions like VSCode and host language servers.
Other
24.16k stars 954 forks source link

fix(markdown): incorrect list indentation alignment in markdown parser #4884

Closed hexh250786313 closed 3 months ago

hexh250786313 commented 5 months ago

fix https://github.com/neoclide/coc.nvim/issues/4882

fannheyward commented 4 months ago

This breaks src/__tests__/markdown/index.test.ts.

hexh250786313 commented 4 months ago

尝试重构了下 listItem 的渲染部分,不好改,先搁置

fannheyward commented 4 months ago

尝试重构了下 listItem 的渲染部分,不好改,先搁置

Converted the PR to Draft.

hexh250786313 commented 3 months ago

(Sorry for using chinese. It is hard to descript my question by my poor English)

https://github.com/neoclide/coc.nvim/blob/574c12cad58065b6866dddd0f438c92fde16f1ae/src/markdown/renderer.ts#L96-L99

@fannheyward issue 提到的这个问题的核心原因在于上面的函数对某些行多次调用,导致重复插入了多余的空格。而 marked 遍历 list item 是每次从最里层遍历整个层级一直遍历到最外层,这样会导致有些行会被 bulletPointLine 重复处理,举个例子:

- foo
  - hello
    - me
      you
      them

遍历结果: 第一次结果提取出第三层也就是 ['me', 'you', 'them'],排除 'me',因为 'me' 是有 - 标记的行,然后把 ['you', 'them'] 分别经过 bulletPointLine 处理,添加空格 第二次结果提取出第二层也就是 ['hello', 'me', 'you', 'them'],排除 'hello''me',然后把剩余的放入 bulletPointLine 进行处理 第三次也类似,最后 'you''them' 这两个没有标记 - 的行会再次被添加空格

简单来说就是在遍历的过程中,那些没有 - 标记的行会不断经过 bulletPointLine 添加空格,导致层级越深,这些行就越往右边缩进。原因就是上面所述的

而正确的处理应该是对于没有 - 标记的行,只需要被执行一次 bulletPointLine,添加一次空格就可以了

那么这个问题的关键就在于如何区分哪些行是已经添加过空格的,这里我有两个方案

还有一种就是把处理过的行存起来,然后遍历的时候,再通过对比进行判断,但是这个方案需要考虑的东西太多,例如如何正确判断当前行是已经处理过的行,如果正好有一样的文本怎么办,所以我个人认为这种也不可取

第一个方案是理论最可行的,但是他的实现并不优雅

这个问题不是什么大问题,不影响功能,只是个展示样式的错位,不过要处理起来也感觉也并不简单。有空研究下提供下意见

fannheyward commented 3 months ago

对于没有 - 标记的行,只需要被执行一次 bulletPointLine,添加一次空格就可以

这个不对吧,比如 you 这个,就是要增加两次空格:

  1. 第三层处理的时候,增加一次空格
  2. 第二层,hello 这一层,也要增加一次空格,如果不增加,是不是就变成下面了?
- hello
  - me
  you
hexh250786313 commented 3 months ago

@fannheyward 他这个函数是用来处理对齐 - 的,是为了保持当前层级和有 - 标记的行(也就是层级的第一行)保持对齐,而整个层级的缩进已经在 marked 的其他部分处理过了

假设 renderer 的 list item 的 - 标记 BULLET_POINT 设置为 *** (共 4 个字符)

*** hello
  *** me
  ~~~~              计算出 list item 层级的 BULLET_POINT 字符数为 4
      you
  ~~~~              bulletPointLine 给每一个当前层级没有 BULLET_POINT 标记的行添加 4 格缩进

所以这个地方不是处理整个层级缩进的,只处理层级自身的缩进对齐

codecov[bot] commented 3 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 98.58%. Comparing base (0d66554) to head (83c6d2f).

:exclamation: Current head 83c6d2f differs from pull request most recent head e949328. Consider uploading reports for the commit e949328 to get more accurate results

Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #4884 +/- ## ========================================== + Coverage 98.55% 98.58% +0.02% ========================================== Files 273 273 Lines 26077 26088 +11 Branches 5392 5393 +1 ========================================== + Hits 25701 25718 +17 + Misses 222 216 -6 Partials 154 154 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

hexh250786313 commented 3 months ago

按照第一个方案改了一个版本,缺点是需要在每一个 marked.setOptions 都要加上 hooks 来处理最终文本:

  marked.setOptions({
    renderer: new Renderer(),
    hooks: Renderer.hooks,
  })
fannheyward commented 3 months ago

https://github.com/neoclide/coc.nvim/pull/4947 更新到了 marked 7,辛苦 rebase 测试一下

hexh250786313 commented 3 months ago

辛苦 rebase 测试一下

@fannheyward Done.