惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
The Last Watchdog
The Last Watchdog
P
Proofpoint News Feed
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
S
Schneier on Security
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
I
Intezer
A
Arctic Wolf
IT之家
IT之家
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cisco Blogs
AWS News Blog
AWS News Blog
博客园 - 三生石上(FineUI控件)
C
CXSECURITY Database RSS Feed - CXSecurity.com
F
Fortinet All Blogs
Microsoft Azure Blog
Microsoft Azure Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
The Exploit Database - CXSecurity.com
Google DeepMind News
Google DeepMind News
M
MIT News - Artificial intelligence
D
Docker
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
MongoDB | Blog
MongoDB | Blog
B
Blog
博客园 - 叶小钗
V2EX - 技术
V2EX - 技术
Simon Willison's Weblog
Simon Willison's Weblog
MyScale Blog
MyScale Blog
Hugging Face - Blog
Hugging Face - Blog
Engineering at Meta
Engineering at Meta
NISL@THU
NISL@THU
WordPress大学
WordPress大学
人人都是产品经理
人人都是产品经理
Stack Overflow Blog
Stack Overflow Blog
N
Netflix TechBlog - Medium
The GitHub Blog
The GitHub Blog
V
V2EX
PCI Perspectives
PCI Perspectives
N
News | PayPal Newsroom
V
Visual Studio Blog
Vercel News
Vercel News
P
Proofpoint News Feed
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
J
Java Code Geeks
O
OpenAI News
爱范儿
爱范儿

咸糖 - 自律者自由

2025 年终总结:降噪、重构与长期主义 在新加坡和新山吃过最好的食物(持续更新) 写给还在迷茫的你:我的三本大学回忆 2024 年终总结 2022 年终总结 使用 neovim 作为 PDE(个性化开发环境) shell 是一个不错的生产力工具 使用二八法则省力地学习 awk 肉身翻墙新加坡安顿指南 使用 Docker Compose 建立你自己的开发环境 关于编写可维护的代码的一些实践与想法 我为什么使用双向链接做笔记? 关于焦虑和拖延症 Golang: 如何处理日渐膨胀的 interface 使用番茄工作法来更好的利用你的时间 Unix 如何杀死一个进程和它的子孙进程? Golang: 让你的零值更有用 使用 Mock 和 Interface 进行 Golang 单测 关于 Golang Slice 的一些细节 总结一些计算机常用的原则 重新学习英语语法 上班族近期小半年入门投资基金组合的学习与实践经历 疫情期间的肉身翻墙新加坡指南 About me 软技能:大厂底层员工打工指南 软技能:我是如何获取知识与信息的? 分布式的令牌桶算法的实现 实现一个AtomicInteger GC root 在哪里? 什么是 Minor GC/Major GC 漏桶算法的设计与实现 剑指offer 单例模式 TCP 针对面试学习 Actor 如何处理阻塞消息 Akka 源码解析 How to learn scala AES 需要限制 SEED 长度 Java 如何区分==与.equals()方法 2018年年度总结 Java 集合扩容
Neovim: No Crash Incremental Selection
xiantang · 2024-07-11 · via 咸糖 - 自律者自由

When I use neovim treesitter incremental selection, it randomly crashes, but I cannot stable reproduce it. And I found some issues and complaints about this issue, but no solution. So I decide to write a blog post to record this issue and the solution.

paste this https://github.com/xiantang/nvim-conf/blob/7c0d6cbf6d9fd7b6a8960de887db1109332419bf/lua/plugins/treesitter.lua#L62-L132 into your neovim configuration file.

sometime when I use v to expand the selection, it crashes, and it’s a Segmentation fault, and I have the report:

But I have no idea how to fix it in neovim source code. After many times I updated the neovim and treesitter, the issue still exists. So I decide to disable the incremental selection feature. And implement a new incremental selection feature by myself.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
local ts_utils = require("nvim-treesitter.ts_utils")

local node_list = {}
local current_index = nil

function start_select()
        node_list = {}
        current_index = nil
        current_index = 1
        vim.cmd("normal! v")
end

function find_expand_node(node)
        local start_row, start_col, end_row, end_col = node:range()
        local parent = node:parent()
        if parent == nil then
                return nil
        end
        local parent_start_row, parent_start_col, parent_end_row, parent_end_col = parent:range()
        if
                start_row == parent_start_row
                and start_col == parent_start_col
                and end_row == parent_end_row
                and end_col == parent_end_col
        then
                return find_expand_node(parent)
        end
        return parent
end

function select_parent_node()
        if current_index == nil then
                return
        end

        local node = node_list[current_index - 1]
        local parent = nil
        if node == nil then
                parent = ts_utils.get_node_at_cursor()
        else
                parent = find_expand_node(node)
        end
        if not parent then
                vim.cmd("normal! gv")
                return
        end

        table.insert(node_list, parent)
        current_index = current_index + 1
        local start_row, start_col, end_row, end_col = parent:range()
        vim.fn.setpos(".", { 0, start_row + 1, start_col + 1, 0 })
        vim.cmd("normal! v")
        vim.fn.setpos(".", { 0, end_row + 1, end_col, 0 })
end

function restore_last_selection()
        if not current_index or current_index <= 1 then
                return
        end

        current_index = current_index - 1
        local node = node_list[current_index]
        local start_row, start_col, end_row, end_col = node:range()
        vim.fn.setpos(".", { 0, start_row + 1, start_col + 1, 0 })
        vim.cmd("normal! v")
        vim.fn.setpos(".", { 0, end_row + 1, end_col, 0 })
end

vim.api.nvim_set_keymap("n", "v", ":lua start_select()<CR>", { noremap = true, silent = true })
vim.api.nvim_set_keymap("v", "v", ":lua select_parent_node()<CR>", { noremap = true, silent = true })
vim.api.nvim_set_keymap("v", "<BS>", ":lua restore_last_selection()<CR>", { noremap = true, silent = true })

And it works well, and I can expand the selection by v and select the parent node by v and restore the last selection by <BS>.

if there have many people have the same issue, im willing to create a new tressitter plugin that let you config this altrenative incremental selection in treesitter configuration like as below: