FreeBSD15现代化Neovim生产力环境部署指南

在 FreeBSD 15 上从源码编译 Neovim 0.10+,并部署基于 lazy.nvim、NvimTree、OSC 52 和 Conform 的现代化 Lua 配置。

本文记录在 FreeBSD 15 上部署现代化 Neovim 生产力环境的完整流程,包括源码编译 Neovim 0.10+、安装 Node.js 与 Prettier,以及部署一套基于 Lua 的实用配置。

这套配置包含主题、文件树、远程复制、代码格式化和常用快捷键,适合用作 FreeBSD 服务器或桌面环境里的日常开发编辑器。

第一步:安装系统依赖与源码编译 Neovim 0.10+

FreeBSD 使用 pkg 管理二进制包,编译 Neovim 需要额外安装 gmake

# 1. 安装编译所需的工具和依赖
# 注意:FreeBSD 下编译 Neovim 建议使用 gmake
# 强制同步并更新所有软件包,这是解决 ld-elf.so.1 错误最直接的方法,确保所有依赖库版本一致。
pkg update -f
pkg upgrade -y
pkg install -y ninja cmake gettext-tools gmake unzip curl git gcc

# 2. 拉取 Neovim 源码
git clone https://github.com/neovim/neovim.git ~/neovim-src
cd ~/neovim-src
git checkout stable

# 3. 编译并全局安装
# FreeBSD 环境下必须明确使用 gmake
gmake CMAKE_BUILD_TYPE=Release -j$(sysctl -n hw.ncpu)
gmake install

# 4. 验证版本
hash -r
nvim -v

如果系统里已经安装过旧版 Neovim,建议先确认 nvim 的实际路径:

which nvim
nvim --version

第二步:安装格式化所需的环境依赖

FreeBSD 的 Node.js 包名通常带有版本号,这里选择主流 LTS 版本。

# 安装 Node.js 和 npm
pkg install -y node20 npm-node20

# 全局安装 Prettier
npm install -g prettier

安装完成后,可以验证 Node.js、npm 和 Prettier 是否可用:

node -v
npm -v
prettier -v

第三步:部署完整的 Lua 配置

FreeBSD 的用户配置目录与 Linux 一致,Neovim 配置仍然放在 ~/.config/nvim

如果已有旧配置,建议先逐个备份,确认无误后再手动清理旧目录。

# 1. 备份旧环境
test -d ~/.config/nvim && mv ~/.config/nvim ~/.config/nvim.bak.$(date +%Y%m%d%H%M%S)
test -d ~/.local/share/nvim && mv ~/.local/share/nvim ~/.local/share/nvim.bak.$(date +%Y%m%d%H%M%S)
test -d ~/.local/state/nvim && mv ~/.local/state/nvim ~/.local/state/nvim.bak.$(date +%Y%m%d%H%M%S)
test -d ~/.cache/nvim && mv ~/.cache/nvim ~/.cache/nvim.bak.$(date +%Y%m%d%H%M%S)

# 2. 创建配置目录
mkdir -p ~/.config/nvim

然后写入完整配置:

cat << 'EOF' > ~/.config/nvim/init.lua
-- [基础设置]
vim.g.mapleader = ";"
local opt = vim.opt
opt.number = true
opt.relativenumber = true
opt.cursorline = true
opt.termguicolors = true
opt.encoding = "utf-8"
opt.mouse = "a"
opt.timeoutlen = 300
opt.splitright = true
opt.splitbelow = true

-- [安装 lazy.nvim]
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git", "clone", "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git", "--branch=stable", lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)

-- [插件配置]
require("lazy").setup({
  -- 1. 主题 (Onedark)
  {
    "navarasu/onedark.nvim",
    lazy = false,
    priority = 1000,
    config = function()
      require("onedark").setup({ style = "dark" })
      require("onedark").load()

      -- 护眼模式修复
      local hl = vim.api.nvim_set_hl
      hl(0, "Normal", { bg = "#1e2127", fg = "#abb2bf" })
      hl(0, "CursorLine", { bg = "#2c313a" })
    end
  },

  -- 2. 文件树 (NvimTree)
  {
    "nvim-tree/nvim-tree.lua",
    dependencies = { "nvim-tree/nvim-web-devicons" },
    config = function()
      require("nvim-tree").setup({
        view = { width = 30 },
        renderer = { indent_markers = { enable = true } }
      })
    end
  },

  -- 3. 远程复制 (OSC 52)
  {
    "ojroques/nvim-osc52",
    config = function()
      require("osc52").setup()
      vim.api.nvim_create_autocmd("TextYankPost", {
        callback = function()
          if vim.v.event.operator == "y" and vim.v.event.regname == "" then
            require("osc52").copy_register("")
          end
        end,
      })
    end
  },

  -- 4. 代码格式化 (Conform)
  {
    "stevearc/conform.nvim",
    config = function()
      require("conform").setup({
        formatters_by_ft = {
          json = { "prettier" },
          yaml = { "prettier" },
          html = { "prettier" },
          css = { "prettier" },
          javascript = { "prettier" },
          typescript = { "prettier" },
        },
        format_on_save = { timeout_ms = 1000, lsp_fallback = true },
      })
    end
  }
})

-- [快捷键映射]
local map = vim.keymap.set

-- 基础功能
map("n", "<leader>w", ":w<CR>", { silent = true })
map("n", "<leader>q", ":q<CR>", { silent = true })
map("n", "<CR>", ":noh<CR><CR>", { silent = true })

-- 智能文件树来回切换 (;t)
map("n", "<leader>t", function()
  local view = require("nvim-tree.view")
  if view.is_visible() then
    if vim.api.nvim_get_current_win() == view.get_winnr() then
      vim.cmd("wincmd p")
    else
      vim.cmd("NvimTreeFocus")
    end
  else
    vim.cmd("NvimTreeToggle")
  end
end, { silent = true })

-- 格式化 (;f)
map({ "n", "v" }, "<leader>f", function()
  require("conform").format({ lsp_fallback = true, timeout_ms = 1000 })
  print("Format executed")
end, { silent = true })

-- 窗口导航
map("n", "<C-h>", "<C-w>h")
map("n", "<C-l>", "<C-w>l")
map("n", "<C-j>", "<C-w>j")
map("n", "<C-k>", "<C-w>k")
EOF

配置完成后,输入 nvim 启动。首次启动时,lazy.nvim 会自动下载并部署所有插件。

核心特性

  • 智能切换:使用 ;t 在文件树与代码窗口之间来回跳转。
  • 格式化:使用 ;f 手动格式化,保存文件时自动格式化。
  • 基础操作:使用 ;w 保存,;q 退出。
  • 远程复制:通过 OSC 52 支持跨终端复制粘贴,普通 y 复制即可触发。
  • 窗口导航:使用 <C-h><C-j><C-k><C-l> 在窗口之间移动。

使用建议

如果是在远程 SSH 环境中使用 OSC 52 复制,需要本地终端支持 OSC 52。iTerm2、WezTerm、Kitty、Windows Terminal 等现代终端通常都支持,部分终端可能需要额外开启相关选项。

如果 :w 保存时格式化失败,优先检查 prettier 是否在当前用户的 PATH 中:

which prettier
prettier -v

总结

这套配置的目标是保持轻量但完整:用 lazy.nvim 管理插件,用 nvim-tree 提供文件浏览,用 osc52 解决远程复制,用 conform.nvim 接入 Prettier 格式化。

完成后,FreeBSD 15 上的 Neovim 就可以作为日常开发、配置编辑和远程维护的主力编辑器使用。