Neovim 这个项目大概开始于2014年,主要目的是打造现代化的Vim. 不考虑vi和旧版本系统的兼容性。不同于Vim,官方有基于GTK的gvim, Neovim 只有 第三方的GUI.

老灯肯定是会先Golang或Rust版的。

https://github.com/Kethku/neovide 有1.5K star, clone 下来编译一把。然后发现报错了。

   Compiling skia-bindings v0.27.3
   Compiling rust-embed v5.5.1
   Compiling thiserror v1.0.19
   Compiling which v4.0.0
   Compiling tokio v0.2.20
   Compiling futures-util v0.3.4
   Compiling futures-executor v0.3.4
   Compiling futures v0.3.4
   Compiling pin-project v0.4.13
   Compiling nvim-rs v0.1.1-alpha.0 (https://github.com/ttys3/nvim-rs#acfcd741)
   Compiling skia-safe v0.27.3
   Compiling skulpin-renderer v0.3.1 (https://github.com/aclysma/skulpin#6139a1f1)
   Compiling skulpin-renderer-winit v0.3.1 (https://github.com/aclysma/skulpin#6139a1f1)
   Compiling skulpin-renderer-sdl2 v0.3.3 (https://github.com/aclysma/skulpin#6139a1f1)
   Compiling skulpin-app-winit v0.3.0 (https://github.com/aclysma/skulpin#6139a1f1)
   Compiling skulpin v0.9.4 (https://github.com/aclysma/skulpin#6139a1f1)
error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/ttys3/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/ttys3/repo/rust/neovide/target/release/deps/neovide-859e1fbe14249d62.which-4752fad7c46da7e1.which.dx3vn4zm-cgu.0.rcgu.o.rcgu.o" "-o" "/home/ttys3/repo/rust/neovide/target/release/deps/neovide-859e1fbe14249d62" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-Wl,-O1" "-nodefaultlibs" "-L" "/home/ttys3/repo/rust/neovide/target/release/deps" "-L" "/usr/lib64" "-L" "/usr/lib64" "-L" "/usr/lib64" "-L" "/usr/lib64" "-L" "/home/ttys3/repo/rust/neovide/target/release/build/libloading-e62ea45709dbd618/out" "-L" "/home/ttys3/repo/rust/neovide/target/release/build/skia-bindings-2d1116dc7243ba64/out/skia" "-L" "/home/ttys3/repo/rust/neovide/target/release/build/sdl2-sys-1bc6cf995ffc0881/out/lib" "-L" "/home/ttys3/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/tmp/rustcSwsrGo/libsdl2_sys-ab14be8f9d7d1911.rlib" "/tmp/rustcSwsrGo/libskia_bindings-1cb3591282aafaf7.rlib" "/tmp/rustcSwsrGo/liblibloading-533412b9dac9bc03.rlib" "-Wl,--start-group" "/tmp/rustcSwsrGo/libbacktrace_sys-23bdd98b0574083e.rlib" "-Wl,--end-group" "/home/ttys3/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-5a0398ee67f74664.rlib" "-Wl,-Bdynamic" "-lharfbuzz" "-lfontconfig" "-lfreetype" "-lexpat" "-lfreetype" "-ldl" "-lstdc++" "-lfontconfig" "-lfreetype" "-ldl" "-lutil" "-ldl" "-lutil" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-ldl" "-lutil"
  = note: /usr/bin/ld: /tmp/rustcSwsrGo/libsdl2_sys-ab14be8f9d7d1911.rlib(SDL_gesture.c.o):(.bss.WAYLAND_wl_proxy_get_user_data+0x0): multiple definition of `WAYLAND_wl_proxy_get_user_data'; /tmp/rustcSwsrGo/libsdl2_sys-ab14be8f9d7d1911.rlib(SDL_events.c.o):(.bss.WAYLAND_wl_proxy_get_user_data+0x0): first defined here
          /usr/bin/ld: /tmp/rustcSwsrGo/libsdl2_sys-ab14be8f9d7d1911.rlib(SDL_gesture.c.o):(.bss.WAYLAND_wl_proxy_set_user_data+0x0): multiple definition of `WAYLAND_wl_proxy_set_user_data'; /tmp/rustcSwsrGo/libsdl2_sys-ab14be8f9d7d1911.rlib(SDL_events.c.o):(.bss.WAYLAND_wl_proxy_set_user_data+0x0): first defined here
          /usr/bin/ld: /tmp/rustcSwsrGo/libsdl2_sys-ab14be8f9d7d1911.rlib(SDL_gesture.c.o):(.bss.WAYLAND_wl_proxy_add_listener+0x0): multiple definition of `WAYLAND_wl_proxy_add_listener'; /tmp/rustcSwsrGo/libsdl2_sys-ab14be8f9d7d1911.rlib(SDL_events.c.o):(.bss.WAYLAND_wl_proxy_add_listener+0x0): first defined here

Google一下,发现是这个代码没有兼容最新的GCC 10

因为老灯用的Fedora, GCC 版本是较新的:

❯ gcc --version
gcc (GCC) 10.2.1 20200723 (Red Hat 10.2.1-1)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

当然,老灯很快发现不只我一个人有遇到这个问题,https://github.com/Kethku/neovide/issues/306

有个workaround 是, cargo clean && CFLAGS="-fcommon -fPIE" cargo build

当然,要从根本上解决这个问题,还得是从上游的C绑定库 sdl2修复: https://github.com/Rust-SDL2/rust-sdl2/pull/1010

From 9781d21b57b0fb8d70d0ac58022047730b9b62a7 Mon Sep 17 00:00:00 2001
From: Jack Frost <[email protected]>
Date: Mon, 15 Jun 2020 22:03:16 +0000
Subject: [PATCH] adds necessary libs for gcc10 to work

---
 sdl2-sys/build.rs | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/sdl2-sys/build.rs b/sdl2-sys/build.rs
index 2af74b1c83..4f3a472c27 100644
--- a/sdl2-sys/build.rs
+++ b/sdl2-sys/build.rs
@@ -267,6 +267,20 @@ fn compile_sdl2(sdl2_build_path: &Path, target_os: &str) -> PathBuf {
     let mut cfg = cmake::Config::new(sdl2_build_path);
     cfg.profile("release");
 
+    #[cfg(target_os = "linux")]
+    {
+        use version_compare::Version;
+        if let Ok(version) = std::process::Command::new("cc").arg("-dumpversion").output() {
+            let local_ver = Version::from(std::str::from_utf8(&version.stdout).unwrap()).unwrap();
+            let affected_ver = Version::from("10").unwrap();
+
+            if local_ver >= affected_ver {
+                cfg.cflag("-fcommon");
+                cfg.cflag("-fPIE");
+            }
+        }
+    }
+
     if target_os == "windows-gnu" {
         cfg.define("VIDEO_OPENGLES", "OFF");
     }

而它的引入是在 https://github.com/aclysma/skulpin/blob/master/skulpin-renderer-sdl2/Cargo.toml, 因此需要改 skulpin

---
diff --git a/skulpin-renderer-sdl2/Cargo.toml b/skulpin-renderer-sdl2/Cargo.toml
index 3dec89f..b2afdea 100644
--- a/skulpin-renderer-sdl2/Cargo.toml
+++ b/skulpin-renderer-sdl2/Cargo.toml
@@ -17,6 +17,6 @@ categories = ["graphics", "gui", "multimedia", "rendering", "visualization"]
 [dependencies]
 skulpin-renderer = { version = "0.3", path = "../skulpin-renderer" }
 
-sdl2 = { version = ">=0.33" }
+sdl2 = { version = ">=0.34.3" }
 
 log="0.4"

然后 cargo clean && cargo update && cargo build

然后一跑,崩了:

❯ ./target/debug/neovide
Ignored client type property: "methods"
Ignored client type property: "attributes"
X Error of failed request:  BadDrawable (invalid Pixmap or Window parameter)
  Major opcode of failed request:  148 ()
  Minor opcode of failed request:  4
  Resource id in failed request:  0x3e0000c
  Serial number of failed request:  239
  Current serial number in output stream:  247

貌似是跟 VulkanWayland 相关。 skulpin 的描述是:

Skia + Vulkan = Skulpin This crate provides an easy option for drawing hardware-accelerated 2D by combining vulkan and skia.

根据https://rpmfusion.org/Howto/NVIDIA#Vulkan, vulkan貌似要手动安装一下的,试试看:

❯ sudo dnf list --installed | grep vulkan
[sudo] password for ttys3: 
mesa-vulkan-drivers.x86_64                         20.1.6-1.fc32                          @updates                                                      
vulkan-loader.x86_64                               1.2.135.0-1.fc32                       @updates  


❯ sudo dnf install vulkan
Scooter Software                                                                                                                                                                                              0.0  B/s |   0  B     00:00    
Last metadata expiration check: 1:10:21 ago on Sat 29 Aug 2020 04:13:18 PM CST.
Package vulkan-loader-1.2.135.0-1.fc32.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!

结果发现是已安装的。

可能是只支持Wayland吧,我现在用的从rpmfusion源安装的N卡私有驱动,只能用X11的。算了。

试试另一个 1.1K star的 https://github.com/vhakulinen/gnvim, UI主要是基于 libwebkit2gt 和 GTK. 编译很顺利。

运行发现,当一行中同时有中文和英文时,英文显示不正常。英文重叠显示在中文上了。

还是妥妥地在terminal里跑吧,别整GUI了。