From f4305709a58127c5263d6bd33698447b502afcbd Mon Sep 17 00:00:00 2001 From: atdunbg Date: Thu, 18 Jun 2026 11:36:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96dotfiles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .zshrc | 108 ++++++++++++++++++++++++++++++ hypr/.luarc.json | 5 ++ hypr/conf/animations.lua | 96 ++++++++++++++++++++++++++ hypr/conf/appearance.lua | 44 ++++++++++++ hypr/conf/autostart.lua | 12 ++++ hypr/conf/env.lua | 23 +++++++ hypr/conf/input.lua | 33 +++++++++ hypr/conf/keybinds.lua | 108 ++++++++++++++++++++++++++++++ hypr/conf/layout.lua | 24 +++++++ hypr/conf/misc.lua | 13 ++++ hypr/conf/monitors.lua | 20 ++++++ hypr/conf/plugins.lua | 16 +++++ hypr/conf/programs.lua | 11 +++ hypr/conf/rules.lua | 94 ++++++++++++++++++++++++++ hypr/hyprland.lua | 18 +++++ hypr/scripts/keymap | 40 +++++++++++ hypr/scripts/screenshot | 20 ++++++ kitty/kitty.conf | 28 ++++++++ nvim/.luarc.json | 11 +++ nvim/init.lua | 73 ++++++++++++++++++++ nvim/lazy-lock.json | 24 +++++++ nvim/lua/plugins/autopairs.lua | 11 +++ nvim/lua/plugins/cmake-tools.lua | 49 ++++++++++++++ nvim/lua/plugins/colorscheme.lua | 42 ++++++++++++ nvim/lua/plugins/completion.lua | 56 ++++++++++++++++ nvim/lua/plugins/conform.lua | 32 +++++++++ nvim/lua/plugins/dap.lua | 88 ++++++++++++++++++++++++ nvim/lua/plugins/devicons.lua | 16 +++++ nvim/lua/plugins/gitsigns.lua | 51 ++++++++++++++ nvim/lua/plugins/lsp.lua | 100 +++++++++++++++++++++++++++ nvim/lua/plugins/oil.lua | 36 ++++++++++ nvim/lua/plugins/runner.lua | 25 +++++++ nvim/lua/plugins/rustaceanvim.lua | 35 ++++++++++ nvim/lua/plugins/telescope.lua | 40 +++++++++++ nvim/lua/plugins/treesitter.lua | 31 +++++++++ nvim/lua/plugins/whichkey.lua | 16 +++++ nvim/lua/runner.lua | 91 +++++++++++++++++++++++++ 37 files changed, 1540 insertions(+) create mode 100644 .zshrc create mode 100644 hypr/.luarc.json create mode 100644 hypr/conf/animations.lua create mode 100644 hypr/conf/appearance.lua create mode 100644 hypr/conf/autostart.lua create mode 100644 hypr/conf/env.lua create mode 100644 hypr/conf/input.lua create mode 100644 hypr/conf/keybinds.lua create mode 100644 hypr/conf/layout.lua create mode 100644 hypr/conf/misc.lua create mode 100644 hypr/conf/monitors.lua create mode 100644 hypr/conf/plugins.lua create mode 100644 hypr/conf/programs.lua create mode 100644 hypr/conf/rules.lua create mode 100644 hypr/hyprland.lua create mode 100755 hypr/scripts/keymap create mode 100755 hypr/scripts/screenshot create mode 100644 kitty/kitty.conf create mode 100644 nvim/.luarc.json create mode 100644 nvim/init.lua create mode 100644 nvim/lazy-lock.json create mode 100644 nvim/lua/plugins/autopairs.lua create mode 100644 nvim/lua/plugins/cmake-tools.lua create mode 100644 nvim/lua/plugins/colorscheme.lua create mode 100644 nvim/lua/plugins/completion.lua create mode 100644 nvim/lua/plugins/conform.lua create mode 100644 nvim/lua/plugins/dap.lua create mode 100644 nvim/lua/plugins/devicons.lua create mode 100644 nvim/lua/plugins/gitsigns.lua create mode 100644 nvim/lua/plugins/lsp.lua create mode 100644 nvim/lua/plugins/oil.lua create mode 100644 nvim/lua/plugins/runner.lua create mode 100644 nvim/lua/plugins/rustaceanvim.lua create mode 100644 nvim/lua/plugins/telescope.lua create mode 100644 nvim/lua/plugins/treesitter.lua create mode 100644 nvim/lua/plugins/whichkey.lua create mode 100644 nvim/lua/runner.lua diff --git a/.zshrc b/.zshrc new file mode 100644 index 0000000..d689252 --- /dev/null +++ b/.zshrc @@ -0,0 +1,108 @@ +# If you come from bash you might have to change your $PATH. +# export PATH=$HOME/bin:$HOME/.local/bin:/usr/local/bin:$PATH + + +# Path to your Oh My Zsh installation. +export ZSH="$HOME/.oh-my-zsh" + +# Set name of the theme to load --- if set to "random", it will +# load a random theme each time Oh My Zsh is loaded, in which case, +# to know which specific one was loaded, run: echo $RANDOM_THEME +# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes +ZSH_THEME="robbyrussell" + +# Set list of themes to pick from when loading at random +# Setting this variable when ZSH_THEME=random will cause zsh to load +# a theme from this variable instead of looking in $ZSH/themes/ +# If set to an empty array, this variable will have no effect. +# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) + +# Uncomment the following line to use case-sensitive completion. +# CASE_SENSITIVE="true" + +# Uncomment the following line to use hyphen-insensitive completion. +# Case-sensitive completion must be off. _ and - will be interchangeable. +# HYPHEN_INSENSITIVE="true" + +# Uncomment one of the following lines to change the auto-update behavior +# zstyle ':omz:update' mode disabled # disable automatic updates +# zstyle ':omz:update' mode auto # update automatically without asking +# zstyle ':omz:update' mode reminder # just remind me to update when it's time + +# Uncomment the following line to change how often to auto-update (in days). +# zstyle ':omz:update' frequency 13 + +# Uncomment the following line if pasting URLs and other text is messed up. +# DISABLE_MAGIC_FUNCTIONS="true" + +# Uncomment the following line to disable colors in ls. +# DISABLE_LS_COLORS="true" + +# Uncomment the following line to disable auto-setting terminal title. +# DISABLE_AUTO_TITLE="true" + +# Uncomment the following line to enable command auto-correction. +# ENABLE_CORRECTION="true" + +# Uncomment the following line to display red dots whilst waiting for completion. +# You can also set it to another string to have that shown instead of the default red dots. +# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" +# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) +# COMPLETION_WAITING_DOTS="true" + +# Uncomment the following line if you want to disable marking untracked files +# under VCS as dirty. This makes repository status check for large repositories +# much, much faster. +# DISABLE_UNTRACKED_FILES_DIRTY="true" + +# Uncomment the following line if you want to change the command execution time +# stamp shown in the history command output. +# You can set one of the optional three formats: +# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" +# or set a custom format using the strftime function format specifications, +# see 'man strftime' for details. +# HIST_STAMPS="mm/dd/yyyy" + +# Would you like to use another custom folder than $ZSH/custom? +# ZSH_CUSTOM=/path/to/new-custom-folder + +# Which plugins would you like to load? +# Standard plugins can be found in $ZSH/plugins/ +# Custom plugins may be added to $ZSH_CUSTOM/plugins/ +# Example format: plugins=(rails git textmate ruby lighthouse) +# Add wisely, as too many plugins slow down shell startup. +plugins=(git) + +source $ZSH/oh-my-zsh.sh + +# User configuration + +# export MANPATH="/usr/local/man:$MANPATH" + +# You may need to manually set your language environment +# export LANG=en_US.UTF-8 + +# Preferred editor for local and remote sessions +if [[ -n $SSH_CONNECTION ]]; then + export EDITOR='vim' +else + export EDITOR='nvim' +fi + +# Compilation flags +# export ARCHFLAGS="-arch $(uname -m)" + +# Set personal aliases, overriding those provided by Oh My Zsh libs, +# plugins, and themes. Aliases can be placed here, though Oh My Zsh +# users are encouraged to define aliases within a top-level file in +# the $ZSH_CUSTOM folder, with .zsh extension. Examples: +# - $ZSH_CUSTOM/aliases.zsh +# - $ZSH_CUSTOM/macos.zsh +# For a full list of active aliases, run `alias`. +# +# Example aliases +# alias zshconfig="mate ~/.zshrc" +# alias ohmyzsh="mate ~/.oh-my-zsh" +export PATH="$HOME/flutter/bin:$PATH" +export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup +export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup diff --git a/hypr/.luarc.json b/hypr/.luarc.json new file mode 100644 index 0000000..12481c4 --- /dev/null +++ b/hypr/.luarc.json @@ -0,0 +1,5 @@ +{ + "diagnostics": { + "globals": ["hl"] + } +} diff --git a/hypr/conf/animations.lua b/hypr/conf/animations.lua new file mode 100644 index 0000000..24c7326 --- /dev/null +++ b/hypr/conf/animations.lua @@ -0,0 +1,96 @@ +-- 动画配置 +-- 为不同操作提供差异化的视觉反馈 + +-- ============================================ +-- 动画曲线定义 +-- ============================================ + +-- 平滑减速(通用) +hl.curve("easeOutQuint", { type = "bezier", points = { {0.23, 1}, {0.32, 1} } }) +-- 平滑加减速 +hl.curve("easeInOutCubic", { type = "bezier", points = { {0.65, 0.05}, {0.36, 1} } }) +-- 线性 +hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) +-- 近似线性(微弱加速) +hl.curve("almostLinear", { type = "bezier", points = { {0.5, 0.5}, {0.75, 1} } }) +-- 快速弹出 +hl.curve("quick", { type = "bezier", points = { {0.15, 0}, {0.1, 1} } }) +-- 弹性弹簧(窗口移动/调整) +hl.curve("easy", { type = "spring", mass = 1, stiffness = 71.2633, dampening = 15.8273644 }) +-- 轻微过冲(窗口打开时的弹性感) +hl.curve("overshot", { type = "bezier", points = { {0.05, 0.9}, {0.1, 1.1} } }) +-- Mac 风格阻尼(暂存区/抽屉) +hl.curve("macDamp", { type = "bezier", points = { {0.16, 1}, {0.3, 1} } }) + +-- ============================================ +-- 全局动画开关 +-- ============================================ +hl.animation({ leaf = "global", enabled = true, speed = 10, bezier = "default" }) + +-- ============================================ +-- 边框动画 — 焦点切换时边框颜色平滑过渡 +-- ============================================ +hl.animation({ leaf = "border", enabled = true, speed = 5.39, bezier = "easeOutQuint" }) +hl.animation({ leaf = "borderangle", enabled = false }) + +-- ============================================ +-- 窗口动画 +-- ============================================ + +-- 窗口打开:从屏幕外滑入(视觉反馈:像推方块一样挤进来) +hl.animation({ leaf = "windowsIn", enabled = true, speed = 5, bezier = "easeOutQuint", style = "slide" }) + +-- 窗口关闭:缩小+淡出(视觉反馈:窗口收缩消失) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 4, bezier = "easeOutQuint", style = "slide" }) + +-- 窗口移动/拖拽/调整大小:弹性弹簧(视觉反馈:窗口跟手且有弹性) +hl.animation({ leaf = "windows", enabled = true, speed = 4.79, spring = "easy" }) + +-- ============================================ +-- 淡入淡出动画 +-- ============================================ + +-- 窗口打开淡入(关闭,配合 slide 效果) +hl.animation({ leaf = "fadeIn", enabled = false }) + +-- 窗口关闭淡出(开启,配合缩小效果) +hl.animation({ leaf = "fadeOut", enabled = true, speed = 4, bezier = "easeOutQuint" }) + +-- 焦点切换时透明度过渡(视觉反馈:当前窗口高亮) +hl.animation({ leaf = "fade", enabled = true, speed = 3.03, bezier = "quick" }) +hl.animation({ leaf = "fadeSwitch", enabled = true, speed = 3, bezier = "almostLinear" }) +hl.animation({ leaf = "fadeShadow", enabled = true, speed = 3, bezier = "almostLinear" }) +hl.animation({ leaf = "fadeDim", enabled = true, speed = 3, bezier = "quick" }) + +-- DPMS 屏幕开关淡入淡出 +hl.animation({ leaf = "fadeDpms", enabled = true, speed = 5, bezier = "easeInOutCubic" }) + +-- ============================================ +-- 工作区切换动画 — 水平平移效果 +-- Super+1~10 切换工作区时,窗口水平滑动 +-- ============================================ +hl.animation({ leaf = "workspaces", enabled = true, speed = 5, bezier = "easeOutQuint", style = "slide" }) +hl.animation({ leaf = "workspacesIn", enabled = true, speed = 5, bezier = "easeOutQuint", style = "slide" }) +hl.animation({ leaf = "workspacesOut", enabled = true, speed = 5, bezier = "easeOutQuint", style = "slide" }) + +-- ============================================ +-- 特殊工作区(暂存区/抽屉)动画 — 垂直抽拉效果 +-- Super+S 切换暂存区时,窗口从底部弹出/收回,类似抽屉 +-- ============================================ +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 5, bezier = "macDamp", style = "slidevert" }) +hl.animation({ leaf = "specialWorkspaceIn", enabled = true, speed = 5, bezier = "macDamp", style = "slidevert" }) +hl.animation({ leaf = "specialWorkspaceOut", enabled = true, speed = 4, bezier = "easeOutQuint", style = "slidevert" }) + +-- ============================================ +-- 图层表面动画(通知/栏/启动器等) +-- ============================================ +hl.animation({ leaf = "layers", enabled = true, speed = 3.81, bezier = "easeOutQuint" }) +hl.animation({ leaf = "layersIn", enabled = true, speed = 4, bezier = "easeOutQuint", style = "fade" }) +hl.animation({ leaf = "layersOut", enabled = true, speed = 1.5, bezier = "linear", style = "fade" }) +hl.animation({ leaf = "fadeLayersIn", enabled = true, speed = 1.79, bezier = "almostLinear" }) +hl.animation({ leaf = "fadeLayersOut", enabled = true, speed = 1.39, bezier = "almostLinear" }) + +-- ============================================ +-- 缩放因子动画 +-- ============================================ +hl.animation({ leaf = "zoomFactor", enabled = true, speed = 7, bezier = "quick" }) diff --git a/hypr/conf/appearance.lua b/hypr/conf/appearance.lua new file mode 100644 index 0000000..b36cea1 --- /dev/null +++ b/hypr/conf/appearance.lua @@ -0,0 +1,44 @@ +-- 外观:间距、边框、圆角、阴影、模糊 + +hl.config({ + general = { + gaps_in = 5, -- 窗口内间距 + gaps_out = 20, -- 窗口外间距 + border_size = 2, -- 边框宽度 + + col = { + active_border = "rgba(89b4faee)", -- Catppuccin Mocha 蓝 + inactive_border = "rgba(45475aaa)", -- Catppuccin Mocha 表面0 + }, + + resize_on_border = true, -- 拖拽边框调整窗口大小 + extend_border_grab_area = 10, -- 边框可拖拽区域扩展 + allow_tearing = false, + layout = "dwindle", + }, + + decoration = { + rounding = 10, -- 圆角半径 + rounding_power = 2, + active_opacity = 1.0, -- 活动窗口不透明度 + inactive_opacity = 0.95, -- 非活动窗口微透明 + + shadow = { + enabled = true, + range = 4, -- 阴影范围 + render_power = 3, -- 阴影渲染精度 + color = 0xee1a1a1a, -- 深色半透明阴影 + }, + + blur = { + enabled = true, + size = 3, -- 模糊强度 + passes = 1, -- 模糊迭代次数(性能与效果平衡) + vibrancy = 0.1696, -- 色彩饱和度 + }, + }, + + animations = { + enabled = true, -- 动画总开关(详细配置见 animations.lua) + }, +}) diff --git a/hypr/conf/autostart.lua b/hypr/conf/autostart.lua new file mode 100644 index 0000000..a685b04 --- /dev/null +++ b/hypr/conf/autostart.lua @@ -0,0 +1,12 @@ +-- 自动启动:Hyprland 启动后运行的服务 + +hl.on("hyprland.start", function() + hl.exec_cmd("systemctl --user start hyprpolkitagent") -- hyorpokitagent 认证模块 + hl.exec_cmd("hyprpm reload -n") -- hyprpm 插件加载 + hl.exec_cmd("qs -c noctalia-shell") -- Noctalia Shell(状态栏/启动器/通知/壁纸) + hl.exec_cmd("udiskie") -- 自动挂载 U 盘 + hl.exec_cmd("fcitx5 -d") -- 中文输入法 + -- hypridle 由 systemd 管理(自动重启),不在 autostart 启动 + hl.exec_cmd("nm-applet --indicator") -- 网络托盘图标 + hl.exec_cmd("/home/atdunbg/.cargo/bin/alttabway daemon") -- Alt+Tab 窗口切换器守护进程 +end) diff --git a/hypr/conf/env.lua b/hypr/conf/env.lua new file mode 100644 index 0000000..a0faa78 --- /dev/null +++ b/hypr/conf/env.lua @@ -0,0 +1,23 @@ +-- 环境变量:输入法、光标、Wayland 兼容性 + + +hl.env("QT_QPA_PLATFORMTHEME", "qt6ct") + +-- Dolphin 部分功能问题 +hl.env("XDG_MENU_PREFIX", "plasma-") + +-- Noctalia 图标主题 +hl.env("QS_ICON_THEME", "Tela") + +-- Fcitx5 中文输入法 +hl.env("QT_IM_MODULE", "fcitx") +hl.env("XMODIFIERS", "@im=fcitx") + +-- 光标主题与大小(X11 + Hyprland 双协议) +hl.env("XCURSOR_SIZE", "24") +hl.env("XCURSOR_THEME", "Adwaita") +hl.env("HYPRCURSOR_SIZE", "24") +hl.env("HYPRCURSOR_THEME", "Adwaita") + +-- Electron 应用 Wayland 原生支持 +hl.env("ELECTRON_OZONE_PLATFORM_HINT", "auto") diff --git a/hypr/conf/input.lua b/hypr/conf/input.lua new file mode 100644 index 0000000..7bb1c54 --- /dev/null +++ b/hypr/conf/input.lua @@ -0,0 +1,33 @@ +-- 输入设备:键盘、鼠标、触控板、手势 + +hl.config({ + input = { + kb_layout = "us", -- 键盘布局 + kb_variant = "", + kb_model = "", + kb_options = "", + kb_rules = "", + + follow_mouse = 1, -- 焦点跟随鼠标 + sensitivity = 0, -- 鼠标灵敏度(0 = 系统默认) + + touchpad = { + natural_scroll = true, -- 自然滚动(反向) + disable_while_typing = true, -- 打字时禁用触控板 + clickfinger_behavior = true, -- 点击行为(非按钮区域) + }, + }, +}) + +-- 触控手势:3/4指水平滑动切换工作区 +hl.gesture({ + fingers = 3, + direction = "horizontal", + action = "workspace", +}) + +hl.gesture({ + fingers = 4, + direction = "horizontal", + action = "workspace", +}) diff --git a/hypr/conf/keybinds.lua b/hypr/conf/keybinds.lua new file mode 100644 index 0000000..b74877d --- /dev/null +++ b/hypr/conf/keybinds.lua @@ -0,0 +1,108 @@ +-- 快捷键绑定 +-- mainMod = SUPER,所有组合基于 Super 键 + +local programs = require("conf.programs") +local terminal = programs.terminal +local fileManager = programs.fileManager +local browser = programs.browser + +local mainMod = "SUPER" + +-- —— tide-island —— +hl.bind(mainMod .. " + Tab", hl.dsp.exec_cmd("qs ipc -p /usr/share/tide-island call overview toggle"), { description = "切换预览下的窗口(tide-island)" }) + + +-- ── 概览与窗口切换 ── +hl.bind(mainMod .. " + W", function() hl.plugin.hyprexpo.expo("toggle") end, { description = "工作区概览" }) + +hl.bind("ALT + Tab", hl.dsp.exec_cmd("/home/atdunbg/.cargo/bin/alttabway show --next"), { description = "切换预览下的窗口" }) +hl.bind("ALT + SHIFT + Tab", hl.dsp.exec_cmd("/home/atdunbg/.cargo/bin/alttabway show --prev"), { description = "切换预览上的窗口" }) + +-- ── 应用启动 ── +hl.bind(mainMod .. " + RETURN", hl.dsp.exec_cmd(terminal), { description = "终端 (kitty)" }) +hl.bind(mainMod .. " + E", hl.dsp.exec_cmd(fileManager), { description = "文件管理器 (dolphin)" }) +hl.bind(mainMod .. " + R", hl.dsp.exec_cmd("qs -c noctalia-shell ipc call launcher toggle"), { description = "应用启动器 (Noctalia)" }) +hl.bind(mainMod .. " + B", hl.dsp.exec_cmd(browser), { description = "浏览器 (firefox)" }) +hl.bind(mainMod .. " + SLASH", hl.dsp.exec_cmd("bash -c 'if hyprctl clients -j | grep -q keymap-float; then hyprctl dispatch focuswindow keymap-float; else kitty --class keymap-float --override window_padding_width=12 --override font_size=13 /home/atdunbg/.config/hypr/scripts/keymap; fi'"), { description = "快捷键速查" }) + +-- ── 窗口控制 ── +hl.bind(mainMod .. " + Q", hl.dsp.window.close(), { description = "关闭窗口" }) +hl.bind(mainMod .. " + F", hl.dsp.window.fullscreen({ mode = "maximized" }), { description = "最大化(保留边距)" }) +hl.bind(mainMod .. " + SHIFT + F", hl.dsp.window.fullscreen(), { description = "全屏" }) +hl.bind(mainMod .. " + V", hl.dsp.window.float({ action = "toggle" }), { description = "浮动/平铺切换" }) +hl.bind(mainMod .. " + P", hl.dsp.window.pseudo(), { description = "伪平铺" }) +hl.bind(mainMod .. " + T", hl.dsp.layout("togglesplit"), { description = "切换分割方向" }) + +-- 窗口调整大小(Super+Alt+H/J/K/L,支持长按重复) +hl.bind(mainMod .. " + ALT + H", hl.dsp.window.resize({ x = -30, y = 0, relative = true }), { repeating = true, description = "窗口缩小(左)" }) +hl.bind(mainMod .. " + ALT + L", hl.dsp.window.resize({ x = 30, y = 0, relative = true }), { repeating = true, description = "窗口扩大(右)" }) +hl.bind(mainMod .. " + ALT + K", hl.dsp.window.resize({ x = 0, y = -30, relative = true }), { repeating = true, description = "窗口缩小(上)" }) +hl.bind(mainMod .. " + ALT + J", hl.dsp.window.resize({ x = 0, y = 30, relative = true }), { repeating = true, description = "窗口扩大(下)" }) + +-- ── 布局切换(dwindle ↔ scrolling)── +hl.bind(mainMod .. " + G", function() hl.config({ general = { layout = "dwindle" } }) end, { description = "切换到 dwindle 布局" }) +hl.bind(mainMod .. " + SHIFT + G", function() hl.config({ general = { layout = "scrolling" } }) end, { description = "切换到 scrolling 布局" }) + +-- ── 焦点移动(Vim 风格 H/J/K/L)── +hl.bind(mainMod .. " + H", hl.dsp.focus({ direction = "left" }), { description = "焦点左移" }) +hl.bind(mainMod .. " + L", hl.dsp.focus({ direction = "right" }), { description = "焦点右移" }) +hl.bind(mainMod .. " + K", hl.dsp.focus({ direction = "up" }), { description = "焦点上移" }) +hl.bind(mainMod .. " + J", hl.dsp.focus({ direction = "down" }), { description = "焦点下移" }) + +-- Scrolling 布局专用快捷键 +hl.bind(mainMod .. " + CTRL + J", hl.dsp.layout("focus l"), { description = "无限平铺: 聚焦左列" }) +hl.bind(mainMod .. " + CTRL + K", hl.dsp.layout("focus r"), { description = "无限平铺: 聚焦右列" }) +hl.bind(mainMod .. " + CTRL + N", hl.dsp.layout("colresize -0.1"), { description = "无限平铺: 缩小列宽" }) +hl.bind(mainMod .. " + CTRL + M", hl.dsp.layout("colresize +0.1"), { description = "无限平铺: 增大列宽" }) + +-- ── 窗口移动(Super+Shift+H/J/K/L)── +hl.bind(mainMod .. " + SHIFT + H", hl.dsp.window.move({ direction = "left" }), { description = "窗口左移" }) +hl.bind(mainMod .. " + SHIFT + L", hl.dsp.window.move({ direction = "right" }), { description = "窗口右移" }) +hl.bind(mainMod .. " + SHIFT + K", hl.dsp.window.move({ direction = "up" }), { description = "窗口上移" }) +hl.bind(mainMod .. " + SHIFT + J", hl.dsp.window.move({ direction = "down" }), { description = "窗口下移" }) + +-- ── 工作区(1-10,0 代表 10)── +for i = 1, 10 do + local key = i % 10 + hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i }), { description = "切换工作区 " .. i }) + hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i }), { description = "移动到工作区 " .. i }) +end + +-- 相邻工作区 +hl.bind(mainMod .. " + CTRL + LEFT", hl.dsp.focus({ workspace = "e-1" }), { description = "上一个工作区" }) +hl.bind(mainMod .. " + CTRL + RIGHT", hl.dsp.focus({ workspace = "e+1" }), { description = "下一个工作区" }) + +-- ── 暂存区(抽屉式,Super+S 收放)── +hl.bind(mainMod .. " + S", hl.dsp.workspace.toggle_special("magic"), { description = "切换暂存区" }) +hl.bind(mainMod .. " + SHIFT + S", hl.dsp.window.move({ workspace = "special:magic" }), { description = "移动到暂存区" }) + +-- ── 鼠标与滚轮 ── +hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true, description = "鼠标拖动窗口" }) +hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true, description = "鼠标调整大小" }) +hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }), { description = "滚轮下一个工作区" }) +hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }), { description = "滚轮上一个工作区" }) + +-- ── 退出 ── +hl.bind(mainMod .. " + M", hl.dsp.exit(), { description = "退出 Hyprland" }) + +-- ── 多媒体键(锁屏下也可用,支持长按重复)── +hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true, repeating = true, description = "音量增加 5%" }) +hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true, repeating = true, description = "音量减少 5%" }) +hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true, repeating = true, description = "切换静音" }) +hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true, repeating = true, description = "切换麦克风" }) + +-- ── 亮度 ── +hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s +10%"), { locked = true, repeating = true, description = "亮度增加 10%" }) +hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 10%-"), { locked = true, repeating = true, description = "亮度减少 10%" }) + +-- ── 媒体控制 ── +hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true, description = "下一曲" }) +hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true, description = "播放/暂停" }) +hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true, description = "播放/暂停" }) +hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true, description = "上一曲" }) + +-- ── 截图 ── +hl.bind("Print", hl.dsp.exec_cmd("/home/atdunbg/.config/hypr/scripts/screenshot full"), { locked = true, description = "全屏截图→保存文件" }) +hl.bind(mainMod .. " + Print", hl.dsp.exec_cmd("/home/atdunbg/.config/hypr/scripts/screenshot area"), { locked = true, description = "区域截图→保存文件" }) +hl.bind(mainMod .. " + SHIFT + Print", hl.dsp.exec_cmd("grim -g \"$(slurp)\" - | wl-copy && notify-send -a 截图 已复制到剪贴板 || notify-send -a 截图 截图失败"), { locked = true, description = "区域截图→仅剪贴板" }) + diff --git a/hypr/conf/layout.lua b/hypr/conf/layout.lua new file mode 100644 index 0000000..d6ee568 --- /dev/null +++ b/hypr/conf/layout.lua @@ -0,0 +1,24 @@ +-- 布局配置:dwindle(二叉树平铺)、master(主从)、scrolling(无限平铺) + +-- dwindle:保留分割方向,避免自动合并 +hl.config({ + dwindle = { + preserve_split = true, + }, +}) + +-- master:新窗口成为 master 占左侧 +hl.config({ + master = { + new_status = "master", + mfact = 0.55, -- master 区占比 + orientation = "left", -- master 在左侧 + }, +}) + +-- scrolling:单列全屏模式 +hl.config({ + scrolling = { + fullscreen_on_one_column = true, + }, +}) diff --git a/hypr/conf/misc.lua b/hypr/conf/misc.lua new file mode 100644 index 0000000..9fab3d7 --- /dev/null +++ b/hypr/conf/misc.lua @@ -0,0 +1,13 @@ +-- 杂项:壁纸、Logo、DPMS 唤醒、XWayland 缩放 + +hl.config({ + misc = { + force_default_wallpaper = 0, -- 不强制默认壁纸(由 Noctalia 管理) + disable_hyprland_logo = true, -- 隐藏 Hyprland Logo + mouse_move_enables_dpms = true, -- 鼠标移动唤醒屏幕 + key_press_enables_dpms = true, -- 按键唤醒屏幕 + }, + xwayland = { + force_zero_scaling = true, -- XWayland 以原生分辨率渲染,避免分数缩放模糊 + }, +}) diff --git a/hypr/conf/monitors.lua b/hypr/conf/monitors.lua new file mode 100644 index 0000000..2b81501 --- /dev/null +++ b/hypr/conf/monitors.lua @@ -0,0 +1,20 @@ +-- 显示器配置 + +-- eDP-1: 内置 2560x1600@165Hz +hl.monitor({ + disabled = true, + output = "eDP-1", + mode = "2560x1600@165", + position = "auto", + scale = "1.6", +}) + + +-- HDMI-A-1: 外接 2560x1440@144Hz +hl.monitor({ + -- disabled = false, + output = "HDMI-A-1", + mode = "2560x1440@144", + position = "0x0", + scale = "1.25", +}) diff --git a/hypr/conf/plugins.lua b/hypr/conf/plugins.lua new file mode 100644 index 0000000..64c70c4 --- /dev/null +++ b/hypr/conf/plugins.lua @@ -0,0 +1,16 @@ +-- 插件配置 + +-- hyprexpo:工作区网格概览(Super+W 触发) +hl.config({ + plugin = { + hyprexpo = { + columns = 3, -- 概览网格列数 + gaps_in = 5, -- 窗口内间距 + gaps_out = 0, -- 窗口外间距 + bg_col = "rgb(111111)", -- 背景色 + workspace_method = "first 1", -- 从工作区 1 开始排列 + gesture_distance = 200, -- 手势触发距离 + show_cursor = 1, -- 显示光标 + }, + }, +}) diff --git a/hypr/conf/programs.lua b/hypr/conf/programs.lua new file mode 100644 index 0000000..01f8b0b --- /dev/null +++ b/hypr/conf/programs.lua @@ -0,0 +1,11 @@ +-- 常用程序定义(供 keybinds 等模块引用) + +local terminal = "kitty" +local fileManager = "dolphin" +local browser = "firefox" + +return { + terminal = terminal, + fileManager = fileManager, + browser = browser, +} diff --git a/hypr/conf/rules.lua b/hypr/conf/rules.lua new file mode 100644 index 0000000..bdccf8c --- /dev/null +++ b/hypr/conf/rules.lua @@ -0,0 +1,94 @@ +-- 窗口和工作区规则 + +-- ── 全局规则 ── + +-- 抑制最大化事件(避免 XWayland 窗口异常最大化) +hl.window_rule({ + name = "suppress-maximize-events", + match = { class = ".*" }, + suppress_event = "maximize", +}) + +-- 修复 XWayland 拖拽时出现幽灵窗口 +hl.window_rule({ + name = "fix-xwayland-drags", + match = { + class = "^$", + title = "^$", + xwayland = true, + float = true, + fullscreen = false, + pin = false, + }, + no_focus = true, +}) + +-- ── 浮动窗口规则 ── + +-- 快捷键速查(居中浮动) +hl.window_rule({ + name = "float-keymap", + match = { class = "keymap-float" }, + float = true, + center = true, + size = { 720, 520 }, +}) + +-- 系统工具浮动 +hl.window_rule({ + name = "float-pavucontrol", + match = { class = "pavucontrol" }, + float = true, +}) + +hl.window_rule({ + name = "float-nm-connection-editor", + match = { class = "nm-connection-editor" }, + float = true, +}) + +-- 文件对话框浮动 +hl.window_rule({ + name = "float-file-dialog", + match = { title = "Open File" }, + float = true, +}) + +hl.window_rule({ + name = "float-save-dialog", + match = { title = "Save As" }, + float = true, +}) + +-- 认证对话框浮动 +hl.window_rule({ + name = "float-auth-dialog", + match = { title = "Authentication Required" }, + float = true, +}) + +-- ── Noctalia Shell 组件规则 ── +hl.window_rule({ + name = "noctalia-wallpaper", + match = { namespace = "^noctalia-wallpaper.*" }, +}) + +hl.window_rule({ + name = "noctalia-bar", + match = { namespace = "^noctalia-bar.*" }, +}) + +hl.window_rule({ + name = "noctalia-notifications", + match = { namespace = "^noctalia-notification.*" }, +}) + +hl.window_rule({ + name = "noctalia-launcher", + match = { namespace = "^noctalia-launcher.*" }, +}) + +hl.window_rule({ + name = "noctalia-lock", + match = { namespace = "^noctalia-lock.*" }, +}) diff --git a/hypr/hyprland.lua b/hypr/hyprland.lua new file mode 100644 index 0000000..e68a7ec --- /dev/null +++ b/hypr/hyprland.lua @@ -0,0 +1,18 @@ +-- ============================================== +-- Hyprland 0.55 Lua 配置 +-- Arch Linux + Hyprland +-- ============================================== + +-- 加载各模块 +require("conf.env") -- 环境变量(最先加载) +require("conf.monitors") -- 显示器 +require("conf.programs") -- 程序定义 +require("conf.appearance") -- 外观(general/decoration) +require("conf.animations") -- 动画 +require("conf.layout") -- 布局(dwindle/master/scrolling) +require("conf.input") -- 输入设备/手势 +require("conf.misc") -- 杂项 +require("conf.plugins") -- 插件(hyprexpo等) +require("conf.keybinds") -- 快捷键 +require("conf.rules") -- 窗口规则 +require("conf.autostart") -- 自启动(最后加载) diff --git a/hypr/scripts/keymap b/hypr/scripts/keymap new file mode 100755 index 0000000..ef3e67f --- /dev/null +++ b/hypr/scripts/keymap @@ -0,0 +1,40 @@ +#!/bin/sh +# 快捷键速查 - 动态从 hyprctl binds 读取 + +modmask_to_str() { + local mask=$1 + local mods="" + # bit 0: SHIFT (1), bit 2: CTRL (4), bit 3: ALT (8), bit 6: SUPER (64) + [ $((mask & 64)) -ne 0 ] && mods="${mods}Super+" + [ $((mask & 1)) -ne 0 ] && mods="${mods}Shift+" + [ $((mask & 4)) -ne 0 ] && mods="${mods}Ctrl+" + [ $((mask & 8)) -ne 0 ] && mods="${mods}Alt+" + [ $((mask & 16)) -ne 0 ] && mods="${mods}Mod2+" + [ $((mask & 32)) -ne 0 ] && mods="${mods}Mod3+" + [ $((mask & 128)) -ne 0 ] && mods="${mods}Mod5+" + echo "${mods%+}" +} + +hyprctl binds 2>/dev/null | awk -v RS='' -F'\n' ' +/^bindd/ { + key=""; desc=""; mask=""; submap="" + for (i=2; i<=NF; i++) { + split($i, kv, ": ") + if (kv[1] ~ /^[[:space:]]*modmask$/) mask=kv[2] + if (kv[1] ~ /^[[:space:]]*key$/) key=kv[2] + if (kv[1] ~ /^[[:space:]]*description$/) desc=kv[2] + if (kv[1] ~ /^[[:space:]]*submap$/) submap=kv[2] + } + # 跳过鼠标绑定和无描述的 + if (key ~ /^mouse/ || desc == "") next + if (submap != "") next + print mask "\t" key "\t" desc +} +' | while IFS=$'\t' read -r mask key desc; do + mod_str=$(modmask_to_str "$mask") + if [ -n "$mod_str" ]; then + printf " %-28s %s\n" "${mod_str}+${key}" "${desc}" + else + printf " %-28s %s\n" "${key}" "${desc}" + fi +done | fzf --prompt " 快捷键速查 > " --reverse --no-sort --bind 'esc:abort' diff --git a/hypr/scripts/screenshot b/hypr/scripts/screenshot new file mode 100755 index 0000000..d13fafa --- /dev/null +++ b/hypr/scripts/screenshot @@ -0,0 +1,20 @@ +#!/bin/sh +# 截图保存到文件并复制到剪贴板 +# 用法: screenshot [full|area] + +dir=~/Pictures/Screenshots +mkdir -p "$dir" +file="$dir/$(date +%Y%m%d_%H%M%S).png" + +if [ "$1" = "area" ]; then + grim -g "$(slurp)" "$file" +else + grim "$file" +fi + +if [ -f "$file" ]; then + wl-copy < "$file" + notify-send -a 截图 "已保存并复制到剪贴板" -i "$file" +else + notify-send -a 截图 "截图失败" +fi diff --git a/kitty/kitty.conf b/kitty/kitty.conf new file mode 100644 index 0000000..e4284c8 --- /dev/null +++ b/kitty/kitty.conf @@ -0,0 +1,28 @@ +shell zsh + +# 字体配置(Nerd Font) +font_family JetBrainsMono Nerd Font +bold_font auto +italic_font auto +bold_italic_font auto +# font_size 12.0 + +# 背景透明度(0.0 完全透明 - 1.0 完全不透明) +background_opacity 0.85 + +# 关闭窗口时无需二次确认 +confirm_os_window_close 0 + +# 光标样式 +cursor_shape beam +cursor_blink_interval 0.5 +cursor_stop_blinking_after 15.0 + +# 光标拖尾动画 +cursor_trail 1 +cursor_trail_decay 0.1 0.4 +cursor_trail_start_threshold 2 + +# 光标颜色(Catppuccin Mocha) +cursor #f5e0dc +cursor_text_color #1e1e2e diff --git a/nvim/.luarc.json b/nvim/.luarc.json new file mode 100644 index 0000000..44106d9 --- /dev/null +++ b/nvim/.luarc.json @@ -0,0 +1,11 @@ +{ + "diagnostics": { + "globals": ["vim"] + }, + "runtime": { + "version": "Lua 5.5" + }, + "workspace": { + "checkThirdParty": false + } +} diff --git a/nvim/init.lua b/nvim/init.lua new file mode 100644 index 0000000..587af8a --- /dev/null +++ b/nvim/init.lua @@ -0,0 +1,73 @@ +-- ============================================================================ +-- Neovim 入口配置 +-- ============================================================================ + +-- Leader 键 +vim.g.mapleader = " " + +-- --------------------------------------------------------------------------- +-- 编辑器选项 +-- --------------------------------------------------------------------------- +local opt = vim.opt + +opt.number = true -- 行号 +opt.relativenumber = true -- 相对行号 +opt.tabstop = 4 -- Tab 宽度 +opt.shiftwidth = 4 -- 缩进宽度 +opt.expandtab = true -- Tab 转空格 +opt.smartindent = true -- 智能缩进 +opt.wrap = false -- 不自动换行 +opt.cursorline = true -- 高亮当前行 +opt.signcolumn = "yes" -- 始终显示符号列 +opt.updatetime = 250 -- 快速更新 +opt.timeoutlen = 300 -- 快捷键超时 +opt.splitright = true -- 垂直分屏在右侧 +opt.splitbelow = true -- 水平分屏在下方 +opt.undofile = true -- 持久化撤销 +opt.ignorecase = true -- 搜索忽略大小写 +opt.smartcase = true -- 智能大小写 +opt.wildmenu = true -- 命令行补全增强 +opt.wildmode = "longest:full,full" +opt.pumheight = 10 -- 补全菜单最大高度 +opt.clipboard = "unnamedplus" -- 系统剪贴板 +opt.termguicolors = true -- 真彩色支持 +opt.foldlevel = 99 -- 默认展开所有折叠 + +-- 全局浮动窗口圆角边框(与 blink.cmp 补全菜单一致) +vim.o.winborder = "rounded" + +-- --------------------------------------------------------------------------- +-- 基础键位 +-- --------------------------------------------------------------------------- +local keymap = vim.keymap.set + +-- 编辑器操作 +keymap("n", "w", "w", { desc = "保存" }) +keymap("n", "q", "q", { desc = "退出" }) +keymap("n", "/", "noh", { desc = "清除搜索高亮" }) + +-- 窗口导航 +keymap("n", "", "h", { desc = "跳到左边窗口" }) +keymap("n", "", "j", { desc = "跳到下面窗口" }) +keymap("n", "", "k", { desc = "跳到上面窗口" }) +keymap("n", "", "l", { desc = "跳到右边窗口" }) + +-- --------------------------------------------------------------------------- +-- lazy.nvim 插件管理器 +-- --------------------------------------------------------------------------- +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not vim.uv.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({ + spec = { { import = "plugins" } }, + defaults = { lazy = true }, + install = { colorscheme = { "default" } }, + checker = { enabled = false }, +}) diff --git a/nvim/lazy-lock.json b/nvim/lazy-lock.json new file mode 100644 index 0000000..8b99b84 --- /dev/null +++ b/nvim/lazy-lock.json @@ -0,0 +1,24 @@ +{ + "blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" }, + "cmake-tools.nvim": { "branch": "master", "commit": "98cdc162572a7b77733030425d8d045d68f2a1fd" }, + "conform.nvim": { "branch": "master", "commit": "619363c30309d29ffa631e67c8183f2a72caa373" }, + "gitsigns.nvim": { "branch": "main", "commit": "25050e4ed39e628282831d4cbecb1850454ce915" }, + "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "0a695750d747db1e7e70bcf0267ef8951c95fc83" }, + "mason-nvim-dap.nvim": { "branch": "main", "commit": "9a10e096703966335bd5c46c8c875d5b0690dade" }, + "mason.nvim": { "branch": "main", "commit": "16ba83bfc8a25f52bb545134f5bee082b195c460" }, + "nvim-autopairs": { "branch": "master", "commit": "7b9923abad60b903ece7c52940e1321d39eccc79" }, + "nvim-dap": { "branch": "master", "commit": "531771530d4f82ad2d21e436e3cc052d68d7aebb" }, + "nvim-dap-ui": { "branch": "master", "commit": "1a66cabaa4a4da0be107d5eda6d57242f0fe7e49" }, + "nvim-lspconfig": { "branch": "master", "commit": "ed19590a3a9792901553c388d1aadafce012f80d" }, + "nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" }, + "nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" }, + "nvim-web-devicons": { "branch": "master", "commit": "dfbfaa967a6f7ec50789bead7ef87e336c1fa63c" }, + "oil.nvim": { "branch": "master", "commit": "b73018b75affd13fa38e2fc94ef753b465f770d7" }, + "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" }, + "rustaceanvim": { "branch": "main", "commit": "88575b98bb9937fb9983ddec5e532b67e75ce677" }, + "telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" }, + "telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" }, + "tokyonight.nvim": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" }, + "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } +} diff --git a/nvim/lua/plugins/autopairs.lua b/nvim/lua/plugins/autopairs.lua new file mode 100644 index 0000000..7da088c --- /dev/null +++ b/nvim/lua/plugins/autopairs.lua @@ -0,0 +1,11 @@ +-- ============================================================================ +-- 自动括号补全 (nvim-autopairs) +-- ============================================================================ + +return { + { + "windwp/nvim-autopairs", + event = "InsertEnter", + opts = {}, + }, +} diff --git a/nvim/lua/plugins/cmake-tools.lua b/nvim/lua/plugins/cmake-tools.lua new file mode 100644 index 0000000..299619e --- /dev/null +++ b/nvim/lua/plugins/cmake-tools.lua @@ -0,0 +1,49 @@ +-- ============================================================================ +-- CMake 工具 (cmake-tools.nvim) +-- CMake 项目全流程:生成、构建、运行、调试 +-- ============================================================================ + +return { + { + "Civitasv/cmake-tools.nvim", + dependencies = { "nvim-lua/plenary.nvim" }, + ft = { "cmake", "c", "cpp" }, + opts = { + cmake_command = "cmake", + ctest_command = "ctest", + cmake_use_preset = true, + cmake_regenerate_on_save = true, + cmake_generate_options = { "-DCMAKE_EXPORT_COMPILE_COMMANDS=1" }, + cmake_build_directory = "build", + cmake_soft_link_compile_commands = true, + cmake_dap_configuration = { + name = "cpp", + type = "codelldb", + request = "launch", + stopOnEntry = false, + runInTerminal = true, + console = "integratedTerminal", + }, + cmake_executor = { + name = "quickfix", + opts = { + show = "always", + position = "belowright", + size = 10, + auto_close_when_success = true, + }, + }, + }, + keys = { + { "cg", "CMakeGenerate", desc = "CMake 生成" }, + { "cb", "CMakeBuild", desc = "CMake 构建" }, + { "cr", "CMakeRun", desc = "CMake 运行" }, + { "cd", "CMakeDebug", desc = "CMake 调试" }, + { "cc", "CMakeClean", desc = "CMake 清理" }, + { "cs", "CMakeSelectBuildType", desc = "选择构建类型" }, + { "ct", "CMakeSelectBuildTarget", desc = "选择构建目标" }, + { "cl", "CMakeSelectLaunchTarget", desc = "选择运行目标" }, + { "ck", "CMakeSelectKit", desc = "选择编译器" }, + }, + }, +} diff --git a/nvim/lua/plugins/colorscheme.lua b/nvim/lua/plugins/colorscheme.lua new file mode 100644 index 0000000..152ba55 --- /dev/null +++ b/nvim/lua/plugins/colorscheme.lua @@ -0,0 +1,42 @@ +-- ============================================================================ +-- 主题 (tokyonight) +-- 透明背景,与终端透明效果融合 +-- ============================================================================ + +return { + { + "folke/tokyonight.nvim", + lazy = false, + priority = 1000, + opts = { + style = "night", + transparent = true, + styles = { + sidebars = "transparent", + floats = "transparent", + }, + }, + config = function(_, opts) + require("tokyonight").setup(opts) + vim.cmd.colorscheme("tokyonight") + + -- inlay hints 去掉背景,融入透明主题 + vim.api.nvim_create_autocmd("ColorScheme", { + pattern = "tokyonight", + callback = function() + vim.api.nvim_set_hl(0, "LspInlayHint", { + bg = "NONE", + fg = "#565f89", + italic = true, + }) + end, + }) + -- 立即生效一次 + vim.api.nvim_set_hl(0, "LspInlayHint", { + bg = "NONE", + fg = "#565f89", + italic = true, + }) + end, + }, +} diff --git a/nvim/lua/plugins/completion.lua b/nvim/lua/plugins/completion.lua new file mode 100644 index 0000000..2a439b5 --- /dev/null +++ b/nvim/lua/plugins/completion.lua @@ -0,0 +1,56 @@ +-- ============================================================================ +-- 智能补全 (blink.cmp) +-- ============================================================================ + +return { + { + "saghen/blink.cmp", + version = "*", + event = { "InsertEnter", "CmdlineEnter" }, + opts = { + keymap = { + preset = "super-tab", + [""] = { "select_next" }, + [""] = { "select_prev" }, + [""] = { "scroll_documentation_up" }, + [""] = { "scroll_documentation_down" }, + -- 命令行模式:Enter 确认补全而非执行命令 + [""] = { "accept", "fallback" }, + }, + appearance = { + use_nvim_cmp_as_default = true, + nerd_font_variant = "normal", + }, + sources = { + default = { "lsp", "path", "buffer", "snippets" }, + }, + cmdline = { + enabled = true, + sources = function() + if vim.fn.getcmdline():find("/") then + return { "buffer" } + end + return { "cmdline" } + end, + completion = { menu = { auto_show = true } }, + }, + completion = { + menu = { + border = "rounded", + -- scrollbar = false, + draw = { + columns = { + { "label", "label_description", gap = 1 }, + { "source_name" }, + }, + }, + }, + documentation = { + auto_show = true, + auto_show_delay_ms = 500, + window = { border = "rounded" }, + }, + }, + }, + }, +} diff --git a/nvim/lua/plugins/conform.lua b/nvim/lua/plugins/conform.lua new file mode 100644 index 0000000..fe7586b --- /dev/null +++ b/nvim/lua/plugins/conform.lua @@ -0,0 +1,32 @@ +-- ============================================================================ +-- 自动格式化 (conform.nvim) +-- 保存时自动格式化,手动 cf 触发 +-- ============================================================================ + +return { + { + "stevearc/conform.nvim", + event = { "BufWritePre" }, + cmd = { "ConformInfo" }, + keys = { + { "cf", function() require("conform").format({ async = true }) end, desc = "格式化" }, + }, + opts = { + format_on_save = { + timeout_ms = 500, + lsp_fallback = true, + }, + formatters_by_ft = { + rust = { "rustfmt" }, + lua = { "stylua" }, + c = { "clang-format" }, + cpp = { "clang-format" }, + }, + formatters = { + ["clang-format"] = { + args = { "--style={BasedOnStyle: LLVM, IndentWidth: 4, TabWidth: 4, UseTab: Never, ColumnLimit: 0}" }, + }, + }, + }, + }, +} diff --git a/nvim/lua/plugins/dap.lua b/nvim/lua/plugins/dap.lua new file mode 100644 index 0000000..8caf94b --- /dev/null +++ b/nvim/lua/plugins/dap.lua @@ -0,0 +1,88 @@ +-- ============================================================================ +-- DAP 调试器 +-- ============================================================================ + +return { + { + "mfussenegger/nvim-dap", + dependencies = { + "rcarriga/nvim-dap-ui", + "nvim-neotest/nvim-nio", + "williamboman/mason.nvim", + }, + config = function() + local dap = require("dap") + local dapui = require("dapui") + + -- 断点图标 + vim.fn.sign_define("DapBreakpoint", { text = "●", texthl = "DapBreakpoint", linehl = "", numhl = "" }) + vim.fn.sign_define("DapBreakpointCondition", { text = "◆", texthl = "DapBreakpointCondition", linehl = "", numhl = "" }) + vim.fn.sign_define("DapStopped", { text = "▶", texthl = "DapStopped", linehl = "CursorLine", numhl = "" }) + + -- dap-ui 布局 + dapui.setup({ + layouts = { + { + elements = { + { id = "stacks", size = 0.25 }, + { id = "scopes", size = 0.25 }, + { id = "breakpoints", size = 0.25 }, + { id = "watches", size = 0.25 }, + }, + position = "left", + size = 40, + }, + { + elements = { + { id = "repl", size = 0.5 }, + { id = "console", size = 0.5 }, + }, + position = "bottom", + size = 10, + }, + }, + }) + + -- 调试会话自动打开/关闭 UI + dap.listeners.before.attach.dapui_config = function() dapui.open() end + dap.listeners.before.launch.dapui_config = function() dapui.open() end + dap.listeners.before.event_terminated.dapui_config = function() dapui.close() end + dap.listeners.before.event_exited.dapui_config = function() dapui.close() end + + -- codelldb 适配器(Mason 安装路径) + dap.adapters.codelldb = { + type = "server", + port = "${port}", + executable = { + command = vim.fn.stdpath("data") .. "/mason/bin/codelldb", + args = { "--port", "${port}" }, + }, + } + + -- C/C++ 调试配置(非 CMake 项目,CMake 项目用 rd) + dap.configurations.c = { + { + name = "Launch", + type = "codelldb", + request = "launch", + program = function() + return vim.fn.input("可执行文件路径: ", vim.fn.getcwd() .. "/", "file") + end, + cwd = "${workspaceFolder}", + stopOnEntry = false, + args = {}, + }, + } + dap.configurations.cpp = dap.configurations.c + end, + }, + + -- Mason DAP 自动安装 + { + "jay-babu/mason-nvim-dap.nvim", + dependencies = { "williamboman/mason.nvim", "mfussenegger/nvim-dap" }, + opts = { + ensure_installed = { "codelldb" }, + }, + }, +} diff --git a/nvim/lua/plugins/devicons.lua b/nvim/lua/plugins/devicons.lua new file mode 100644 index 0000000..ecda9ae --- /dev/null +++ b/nvim/lua/plugins/devicons.lua @@ -0,0 +1,16 @@ +-- ============================================================================ +-- 图标支持 (nvim-web-devicons) +-- 为 oil、telescope、状态栏等提供文件类型图标 +-- ============================================================================ + +return { + { + "nvim-tree/nvim-web-devicons", + lazy = true, + opts = { + override = { + rs = { icon = "󱘗", color = "#dea584", name = "Rust" }, + }, + }, + }, +} diff --git a/nvim/lua/plugins/gitsigns.lua b/nvim/lua/plugins/gitsigns.lua new file mode 100644 index 0000000..e7a66cf --- /dev/null +++ b/nvim/lua/plugins/gitsigns.lua @@ -0,0 +1,51 @@ +-- ============================================================================ +-- Git 集成 (gitsigns) +-- 行内 diff 标记 + hunk 操作 +-- ============================================================================ + +return { + { + "lewis6991/gitsigns.nvim", + event = "BufReadPre", + opts = { + signs = { + add = { text = "▍" }, + change = { text = "▍" }, + delete = { text = "▍" }, + topdelete = { text = "▍" }, + changedelete = { text = "▍" }, + }, + on_attach = function(bufnr) + local gs = require("gitsigns") + + -- 导航 + vim.keymap.set("n", "]h", function() gs.nav_hunk("next") end, { buffer = bufnr, desc = "下一个修改块" }) + vim.keymap.set("n", "[h", function() gs.nav_hunk("prev") end, { buffer = bufnr, desc = "上一个修改块" }) + + -- Hunk 操作 + vim.keymap.set("n", "hs", gs.stage_hunk, { buffer = bufnr, desc = "暂存修改块" }) + vim.keymap.set("n", "hr", gs.reset_hunk, { buffer = bufnr, desc = "撤销修改块" }) + vim.keymap.set("n", "hp", gs.preview_hunk, { buffer = bufnr, desc = "预览修改块" }) + + -- 文件操作 + vim.keymap.set("n", "hS", gs.stage_buffer, { buffer = bufnr, desc = "暂存文件" }) + vim.keymap.set("n", "hR", gs.reset_buffer, { buffer = bufnr, desc = "撤销文件修改" }) + + -- Blame + vim.keymap.set("n", "hb", gs.blame_line, { buffer = bufnr, desc = "查看行 blame" }) + vim.keymap.set("n", "hl", gs.toggle_current_line_blame, { buffer = bufnr, desc = "切换行 blame" }) + + -- 其他 + vim.keymap.set("n", "hw", gs.setqflist, { buffer = bufnr, desc = "列出所有 hunk" }) + vim.keymap.set("n", "hd", gs.toggle_word_diff, { buffer = bufnr, desc = "切换行内 diff" }) + end, + }, + config = function(_, opts) + require("gitsigns").setup(opts) + -- 自定义颜色 + vim.api.nvim_set_hl(0, "GitSignsAdd", { fg = "#4CAF50" }) + vim.api.nvim_set_hl(0, "GitSignsChange", { fg = "#2196F3" }) + vim.api.nvim_set_hl(0, "GitSignsDelete", { fg = "#F44336" }) + end, + }, +} diff --git a/nvim/lua/plugins/lsp.lua b/nvim/lua/plugins/lsp.lua new file mode 100644 index 0000000..782490a --- /dev/null +++ b/nvim/lua/plugins/lsp.lua @@ -0,0 +1,100 @@ +-- ============================================================================ +-- LSP 语言服务器 +-- ============================================================================ + +return { + -- Mason: 外部工具管理 (:Mason 打开管理界面) + { + "williamboman/mason.nvim", + cmd = "Mason", + opts = {}, + }, + + -- Mason 与 LSP 桥接,自动安装指定服务器 + { + "williamboman/mason-lspconfig.nvim", + dependencies = { "williamboman/mason.nvim" }, + opts = { + ensure_installed = { + "lua_ls", -- Lua + "bashls", -- Bash + "clangd", -- C/C++ + "neocmake", -- CMake + }, + }, + }, + + -- LSP 配置(Neovim 0.11+ vim.lsp.config API) + { + "neovim/nvim-lspconfig", + event = { "BufReadPre", "BufNewFile" }, + dependencies = { + "williamboman/mason.nvim", + "williamboman/mason-lspconfig.nvim", + "saghen/blink.cmp", + }, + config = function() + -- LSP 附加时自动开启 inlay hints + vim.api.nvim_create_autocmd("LspAttach", { + callback = function(args) + local map = function(keys, func, desc) + vim.keymap.set("n", keys, func, { buffer = args.buf, desc = desc }) + end + map("gd", vim.lsp.buf.definition, "跳转到定义") + map("gr", vim.lsp.buf.references, "查找引用") + map("K", vim.lsp.buf.hover, "悬浮文档") + map("rn", vim.lsp.buf.rename, "重命名") + map("", vim.lsp.buf.code_action, "代码操作") + map("d", vim.diagnostic.open_float, "行诊断") + map("[d", vim.diagnostic.goto_prev, "上一个诊断") + map("]d", vim.diagnostic.goto_next, "下一个诊断") + + -- 开启 inlay hints + vim.lsp.inlay_hint.enable(true, { bufnr = args.buf }) + end, + }) + + local caps = require("blink.cmp").get_lsp_capabilities() + + -- Lua + vim.lsp.config("lua_ls", { + cmd = { "lua-language-server" }, + capabilities = caps, + settings = { + Lua = { + runtime = { version = "Lua5.5" }, + workspace = { checkThirdParty = false }, + diagnostics = { globals = { "vim" } }, + }, + }, + }) + + -- Bash + vim.lsp.config("bashls", { + cmd = { "bash-language-server", "start" }, + capabilities = caps, + }) + + -- C/C++ (clangd) + vim.lsp.config("clangd", { + cmd = { "clangd" }, + capabilities = caps, + }) + + -- CMake + vim.lsp.config("neocmake", { + cmd = { "neocmakelsp", "stdio" }, + filetypes = { "cmake" }, + root_dir = vim.fs.root(0, { ".git", "CMakeLists.txt" }), + single_file_support = true, + init_options = { + format = { enable = true }, + lint = { enable = true }, + }, + }) + + -- 启用所有 LSP(Rust 由 rustaceanvim 管理,不在此启用) + vim.lsp.enable({ "lua_ls", "bashls", "clangd", "neocmake" }) + end, + }, +} diff --git a/nvim/lua/plugins/oil.lua b/nvim/lua/plugins/oil.lua new file mode 100644 index 0000000..767842a --- /dev/null +++ b/nvim/lua/plugins/oil.lua @@ -0,0 +1,36 @@ +-- ============================================================================ +-- 文件浏览器 (oil.nvim) +-- 缓冲区编辑模式,像编辑文本一样管理文件 +-- ============================================================================ + +return { + { + "stevearc/oil.nvim", + dependencies = { + "nvim-tree/nvim-web-devicons", + }, + opts = { + default_file_explorer = true, + keymaps = { + [""] = "actions.select", + [""] = "actions.preview", + [""] = "actions.close", + [""] = "actions.refresh", + [""] = "actions.toggle_hidden", + ["g?"] = "actions.show_help", + }, + view_options = { + show_hidden = true, + }, + float = { + padding = 2, + max_width = 90, + border = "rounded", + }, + }, + keys = { + { "-", "Oil", desc = "打开父目录" }, + { "fe", "Oil", desc = "文件浏览器" }, + }, + }, +} diff --git a/nvim/lua/plugins/runner.lua b/nvim/lua/plugins/runner.lua new file mode 100644 index 0000000..e74b666 --- /dev/null +++ b/nvim/lua/plugins/runner.lua @@ -0,0 +1,25 @@ +-- ============================================================================ +-- 统一构建/运行/调试键位 +-- 所有语言共用同一组键位,由 runner.lua 自动分发 +-- ============================================================================ + +return { + { + "mfussenegger/nvim-dap", + keys = { + -- 调试控制 + { "", function() require("dap").continue() end, desc = "继续调试" }, + { "", function() require("dap").step_over() end, desc = "单步跳过" }, + { "", function() require("dap").step_into() end, desc = "单步进入" }, + { "", function() require("dap").step_out() end, desc = "单步跳出" }, + { "b", function() require("dap").toggle_breakpoint() end, desc = "断点" }, + { "du", function() require("dapui").toggle() end, desc = "调试界面" }, + + -- 统一构建/运行/调试/测试 + { "rb", function() require("runner").build() end, desc = "构建" }, + { "rr", function() require("runner").run() end, desc = "运行" }, + { "rd", function() require("runner").debug() end, desc = "调试" }, + { "rt", function() require("runner").test() end, desc = "测试" }, + }, + }, +} diff --git a/nvim/lua/plugins/rustaceanvim.lua b/nvim/lua/plugins/rustaceanvim.lua new file mode 100644 index 0000000..3d4e552 --- /dev/null +++ b/nvim/lua/plugins/rustaceanvim.lua @@ -0,0 +1,35 @@ +-- ============================================================================ +-- Rust 工具 (rustaceanvim) +-- Rust 全流程:LSP、调试、运行、测试、宏展开 +-- ============================================================================ + +return { + { + "mrcjkb/rustaceanvim", + version = "^6", + lazy = false, + ft = { "rust" }, + config = function() + vim.g.rustaceanvim = { + -- LSP 配置 + server = { + default_settings = { + ["rust-analyzer"] = { + cargo = { allFeatures = true }, + check = { command = "clippy" }, + }, + }, + }, + -- DAP 适配器(复用 Mason 安装的 codelldb) + dap = { + adapter = function() + local codelldb_path = vim.fn.stdpath("data") .. "/mason/bin/codelldb" + local library_path = vim.fn.stdpath("data") + .. "/mason/packages/codelldb/extension/lldb/lib/liblldb.so" + return require("rustaceanvim.config").get_codelldb_adapter(codelldb_path, library_path) + end, + }, + } + end, + }, +} diff --git a/nvim/lua/plugins/telescope.lua b/nvim/lua/plugins/telescope.lua new file mode 100644 index 0000000..7f9ab12 --- /dev/null +++ b/nvim/lua/plugins/telescope.lua @@ -0,0 +1,40 @@ +-- ============================================================================ +-- 模糊搜索 (telescope) +-- ============================================================================ + +return { + { + "nvim-telescope/telescope.nvim", + branch = "0.1.x", + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-telescope/telescope-ui-select.nvim", + }, + cmd = "Telescope", + keys = { + { "ff", "Telescope find_files", desc = "查找文件" }, + { "fg", "Telescope live_grep", desc = "全局搜索" }, + { "fb", "Telescope buffers", desc = "切换缓冲区" }, + { "fh", "Telescope help_tags", desc = "帮助文档" }, + { "fk", "Telescope keymaps", desc = "查找键位" }, + { "fr", "Telescope oldfiles", desc = "最近文件" }, + }, + opts = { + defaults = { + prompt_prefix = " > ", + selection_caret = " > ", + layout_strategy = "flex", + }, + extensions = { + ["ui-select"] = { + require("telescope.themes").get_dropdown({}), + }, + }, + }, + config = function(_, opts) + local telescope = require("telescope") + telescope.setup(opts) + telescope.load_extension("ui-select") + end, + }, +} diff --git a/nvim/lua/plugins/treesitter.lua b/nvim/lua/plugins/treesitter.lua new file mode 100644 index 0000000..148f1fe --- /dev/null +++ b/nvim/lua/plugins/treesitter.lua @@ -0,0 +1,31 @@ +-- ============================================================================ +-- 语法高亮 (Tree-sitter) +-- ============================================================================ + +return { + { + "nvim-treesitter/nvim-treesitter", + event = { "BufReadPre", "BufNewFile" }, + build = ":TSUpdate", + opts = { + ensure_installed = { + "lua", -- Lua + "bash", -- Bash + "rust", -- Rust + "c", -- C + "cpp", -- C++ + "cmake", -- CMake + "python", -- Python + "java", -- Java + "go", -- Go + "json", -- JSON + "toml", -- TOML + "markdown", -- Markdown + "regex", -- 正则 + "vim", -- Vimscript + }, + highlight = { enable = true }, + indent = { enable = true }, + }, + }, +} diff --git a/nvim/lua/plugins/whichkey.lua b/nvim/lua/plugins/whichkey.lua new file mode 100644 index 0000000..0bc19ef --- /dev/null +++ b/nvim/lua/plugins/whichkey.lua @@ -0,0 +1,16 @@ +-- ============================================================================ +-- 键位提示 (which-key) +-- ============================================================================ + +return { + { + "folke/which-key.nvim", + enabled = false, + event = "VeryLazy", + opts = { + delay = 300, + icons = { breadcrumb = ">", separator = "->", group = "+" }, + spec = { { "z", hidden = true } }, + }, + }, +} diff --git a/nvim/lua/runner.lua b/nvim/lua/runner.lua new file mode 100644 index 0000000..c7c2fdc --- /dev/null +++ b/nvim/lua/runner.lua @@ -0,0 +1,91 @@ +-- ============================================================================ +-- 统一构建/运行/调试分发器 +-- 根据项目类型自动选择正确的工具 +-- ============================================================================ + +local M = {} + +--- 检测当前项目类型 +---@return "rust"|"cmake"|"python"|"go"|"unknown" +function M.detect() + local cwd = vim.fn.getcwd() + + if vim.fn.filereadable(cwd .. "/Cargo.toml") == 1 then return "rust" end + if vim.fn.filereadable(cwd .. "/CMakeLists.txt") == 1 then return "cmake" end + if vim.fn.filereadable(cwd .. "/go.mod") == 1 then return "go" end + if vim.fn.filereadable(cwd .. "/pyproject.toml") == 1 then return "python" end + if vim.fn.filereadable(cwd .. "/setup.py") == 1 then return "python" end + + return "unknown" +end + +--- 构建 +function M.build() + local project = M.detect() + + if project == "rust" then + vim.cmd("RustLsp runnables") + elseif project == "cmake" then + vim.cmd("CMakeBuild") + elseif project == "go" then + local result = vim.fn.system("go build ./...") + if vim.v.shell_error == 0 then + vim.notify("go build 成功", vim.log.levels.INFO) + else + vim.notify("go build 失败:\n" .. result, vim.log.levels.ERROR) + end + else + vim.notify("未识别的项目类型,无法自动构建", vim.log.levels.WARN) + end +end + +--- 运行 +function M.run() + local project = M.detect() + + if project == "rust" then + vim.cmd("RustLsp runnables") + elseif project == "cmake" then + vim.cmd("CMakeRun") + elseif project == "go" then + vim.cmd("terminal go run .") + elseif project == "python" then + vim.cmd("terminal python " .. vim.fn.expand("%")) + else + vim.notify("未识别的项目类型,无法自动运行", vim.log.levels.WARN) + end +end + +--- 调试 +function M.debug() + local project = M.detect() + + if project == "rust" then + vim.cmd("RustLsp debuggables") + elseif project == "cmake" then + vim.cmd("CMakeDebug") + else + -- 通用 DAP 启动 + require("dap").continue() + end +end + +--- 测试 +function M.test() + local project = M.detect() + + if project == "rust" then + vim.cmd("RustLsp testables") + elseif project == "cmake" then + vim.cmd("CMakeBuild") + vim.cmd("terminal ctest --test-dir build") + elseif project == "go" then + vim.cmd("terminal go test ./...") + elseif project == "python" then + vim.cmd("terminal pytest") + else + vim.notify("未识别的项目类型,无法自动测试", vim.log.levels.WARN) + end +end + +return M