阅读视图

发现新文章,点击刷新页面。
🔲 ☆

仓颉语言 Neovim 开发环境配置指南

本文档介绍如何在 openEuler (aarch64) 系统上配置 Neovim (AstroNvim) 开发环境,用于仓颉语言开发。

目录

系统要求

  • 操作系统:openEuler 2403 SP1 (aarch64)
  • GCC 版本:12.3.1 或更高
  • Neovim 版本:0.9.0 或更高

安装仓颉 SDK

  1. 从官方渠道下载仓颉 SDK (aarch64 版本)
  2. 解压到 ~/.config/cjvs/store/ 目录

目录结构示例:

1
2
3
4
5
6
7
~/.config/cjvs/
└── store/
└── 1.1.0-beta.25/
├── envsetup.sh
├── lib/
├── runtime/
└── ...

安装 Cangjie STDX

STDX 是仓颉的标准扩展库,需要单独安装:

  1. 从发布页面下载:https://gitcode.com/Cangjie/cangjie_stdx/releases/v1.1.0-beta.24.1
  2. 选择 linux_aarch64_cjnative 版本
  3. 解压到 ~/.config/cjvs/stdx/ 目录

目录结构示例:

1
2
3
4
5
6
7
8
~/.config/cjvs/
└── stdx/
└── 1.1.0-beta.24/
└── linux_aarch64_cjnative/
└── static/
└── stdx/
├── stdx.cjo
└── ...

环境变量配置

编辑 ~/.zshrc,添加以下配置:

1
2
3
4
5
# 仓颉 SDK 环境配置
source $HOME/.config/cjvs/store/1.1.0-beta.25/envsetup.sh

# STDX 路径配置
export CANGJIE_STDX_PATH="$HOME/.config/cjvs/stdx/1.1.0-beta.24/linux_aarch64_cjnative/static/stdx"

配置完成后执行:

1
source ~/.zshrc

说明

  • envsetup.sh:设置仓颉编译器所需的环境变量
  • CANGJIE_STDX_PATH:指定 STDX 库的路径

创建 GCC 运行时库符号链接

由于仓颉链接器脚本默认搜索 /lib64 目录,需要创建符号链接:

1
2
3
4
sudo ln -sf /usr/lib/gcc/aarch64-openEuler-linux/12/crtbeginS.o /lib64/crtbeginS.o
sudo ln -sf /usr/lib/gcc/aarch64-openEuler-linux/12/crtendS.o /lib64/crtendS.o
sudo ln -sf /usr/lib/gcc/aarch64-openEuler-linux/12/crtbegin.o /lib64/crtbegin.o
sudo ln -sf /usr/lib/gcc/aarch64-openEuler-linux/12/crtend.o /lib64/crtend.o

说明:解决链接时找不到 crtbeginS.o 等运行时库的问题

Neovim 配置

1. 安装 AstroNvim

1
git clone --depth 1 https://github.com/AstroNvim/AstroNvim ~/.config/nvim

2. 配置仓颉 LSP 插件

创建文件 ~/.config/nvim/lua/plugins/cangjie-lsp.lua

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
return {
"https://gitcode.com/ystyle/cangjie-nvim",
dependencies = { "neovim/nvim-lspconfig" },
opts = { auto_install = true },
config = function(plugin)
require("cangjie-nvim").setup(plugin.opts)

vim.api.nvim_create_autocmd("LspAttach", {
callback = function(args)
if vim.bo[args.buf].filetype ~= "Cangjie" then return end

local function map(mode, lhs, rhs, desc)
vim.keymap.set(mode, lhs, rhs, { buffer = args.buf, desc = desc })
end

map("n", "<leader>li", "<cmd>LspInfo<cr>", "LSP Info")
map("n", "K", vim.lsp.buf.hover, "Hover Document")
map("n", "<leader>lf", function() vim.lsp.buf.format { async = true } end, "Format Document")
map("n", "gl", vim.diagnostic.open_float, "Line Diagnostics")
map("n", "<leader>ld", vim.diagnostic.open_float, "Line Diagnostics")
map("n", "<leader>lD", vim.diagnostic.setqflist, "All Diagnostics")
map("n", "gra", vim.lsp.buf.code_action, "Code Actions")
map("n", "<leader>la", vim.lsp.buf.code_action, "Code Actions")
map("n", "<leader>lh", vim.lsp.buf.signature_help, "Signature Help")
map("n", "grn", vim.lsp.buf.rename, "Rename")
map("n", "<leader>lr", vim.lsp.buf.rename, "Rename")
map("n", "<leader>ls", vim.lsp.buf.document_symbol, "Document Symbols")
map("n", "<leader>lG", vim.lsp.buf.workspace_symbol, "Workspace Symbols")
map("n", "]d", vim.diagnostic.goto_next, "Diagnostic Next")
map("n", "[d", vim.diagnostic.goto_prev, "Diagnostics Previous")
map("n", "]e", function() vim.diagnostic.goto_next { severity = vim.diagnostic.severity.ERROR } end, "Error Next")
map("n", "[e", function() vim.diagnostic.goto_prev { severity = vim.diagnostic.severity.ERROR } end, "Error Previous")
map("n", "]w", function() vim.diagnostic.goto_next { severity = vim.diagnostic.severity.WARN } end, "Warning Next")
map("n", "[w", function() vim.diagnostic.goto_prev { severity = vim.diagnostic.severity.WARN } end, "Warning Previous")
map("n", "gD", vim.lsp.buf.declaration, "Declaration")
map("n", "gy", vim.lsp.buf.type_definition, "Type Definition")
map("n", "gd", vim.lsp.buf.definition, "Definition")
map("n", "gri", vim.lsp.buf.implementation, "Implementation")
map("n", "grr", vim.lsp.buf.references, "References")
end,
})
end,
}

3. 启动 Neovim 并安装插件

1
nvim

AstroNvim 会自动检测并安装 cangjie-nvim 插件。首次打开 .cj 文件时,插件会自动下载 LSP wrapper 二进制文件。

LSP Wrapper 地址

常见问题

1. 链接错误:cannot find crtbeginS.o

错误信息

1
/usr/bin/ld: cannot find crtbeginS.o: No such file or directory

解决方案
创建 GCC 运行时库符号链接:

1
2
3
4
sudo ln -sf /usr/lib/gcc/aarch64-openEuler-linux/12/crtbeginS.o /lib64/crtbeginS.o
sudo ln -sf /usr/lib/gcc/aarch64-openEuler-linux/12/crtendS.o /lib64/crtendS.o
sudo ln -sf /usr/lib/gcc/aarch64-openEuler-linux/12/crtbegin.o /lib64/crtbegin.o
sudo ln -sf /usr/lib/gcc/aarch64-openEuler-linux/12/crtend.o /lib64/crtend.o

2. LSP 不工作

检查步骤

  1. 确认仓颉 SDK 环境变量已加载:echo $CANGJIE_HOME
  2. 确认 LSP wrapper 已下载:ls ~/.local/share/nvim/data/cangjie-nvim/bin/
  3. 手动安装 LSP wrapper:
    1
    :lua require("cangjie-nvim").install()

3. 找不到 STDX

错误信息

1
error: cannot find stdx module

解决方案
确认 CANGJIE_STDX_PATH 环境变量指向正确的目录:

1
2
ls $CANGJIE_STDX_PATH
# 应该能看到 stdx.cjo 文件

4. 快速事件上下文错误

错误信息

1
E5560: nvim_create_namespace must not be called in a fast event context

解决方案
此问题已在 cangjie-nvim 插件中修复,请确保使用最新版本。

键位映射

快捷键功能
K显示悬停文档
gd跳转到定义
gD跳转到声明
gy跳转到类型定义
gri跳转到实现
grr查找引用
grn重命名
<leader>lf格式化文档
<leader>la代码操作
<leader>liLSP 信息
]d / [d下一个/上一个诊断
]e / [e下一个/上一个错误
]w / [w下一个/上一个警告

参考链接

🔲 ☆

鸿蒙PC Matebook Pro上安装仓颉编译器每日构建版

使用示例
使用示例

准备工作

从CodeArts IDE提取签名工具

打开IDE, 随便创建一个项目打开,在终端执行以下命令

1
2
3
4
5
6
7
8
9
10
11
12
# 复制签名工具
cp /data/app/toolchains.org/toolchains_1.0/lib//binary-sign-tool .
# 对签名工具签名
binary-sign-tool sign -inFile "./binary-sign-tool" -outFile "./binary-sign-tool-signed" -selfSign 1
# 添加可执行权限
chmod +x binary-sign-tool-signed
# 测试,如果没弹授权弹窗和帮忙输出,需要重新签名和添加可执行权限
./binary-sign-tool-signed

# 复制到用户安装目录
mkdir -p ~/.local/bin
cp ./binary-sign-tool-signed ~/.local/bin/binary-sign-tool

最后在~/.zshrc添加export PATH=$HOME/.local/bin:$PATH

安装仓颉编译器

  • 把下载的仓颉编译器复制到个人目录(文件管器和下载目录同级)
  • 打开终端解压 tar -xzf cangjie-sdk-ohos-aarch64-1.1.0-alpha.2025xxxxxxxxxxxxx.tar.gz 换自己下载的版本
  • 打开cangjie/envsetup.sh把首行的#!/bin/bash换成#!/bin/sh
  • 把以下脚本保存为sign-cangjie.sh并复制到cangjie目录下和envsetup.sh同级

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #!/bin/sh

    # 递归查询当前目录及其子目录下的所有文件
    find . -type f | while read -r file; do
    # 使用 file 命令检查文件类型
    if file "$file" | grep "shared object"; then
    echo "Found executable or shared object: $file"

    # 确保文件具有可执行权限
    chmod +x "$file"

    # 签名文件
    echo "Signing file: $file"
    binary-sign-tool sign -inFile "$file" -outFile "$file" -selfSign 1
    fi
    done
  • 在终端切换到cangjie目录下,执行chmod +x sign-cangjie.sh 并执行 ./sign-cangjie.sh

  • 终端切换到third_party/llvm/bin 目录, 执行 rm ld.lld && cp lld ld.lld
    • 这一步是为了解决 cjc 编译过程中找不到ld.lld的问题, 原因是仓颉编译器看不到软链接的 ld.lld

使用仓颉编译器

现在就可以按仓颉教程的两种方法使用仓颉了

  • 第一种,临时使用

    • 打开终端 source ~/.cangjie/envsetup.sh 然后就可以在当前终端窗口执行cjc -v
  • 第二种,永远使用

    • source $HOME/.cangjie/envsetup.sh 添加到 ~/.zshrc 里,之后打开的新终端都可以使用仓颉命令了

编译并执行项目

  • 写一个hello_world.cj

    1
    2
    3
    main(){
    println("你好,仓颉\n你好鸿蒙")
    }
  • 编译 cjc hello_world.cj

  • 签名 binary-sign-tool sign -inFile "./main" -outFile "./main-signed" -selfSign 1
  • 授权 chmod +x ./main-signed
  • 执行 ./main-signed , 如无意外就能看到输出了
❌