From 6ddba3e7226d6667e179c8c06ca2d9696e5d01f0 Mon Sep 17 00:00:00 2001 From: Mars Date: Thu, 20 Mar 2025 17:55:08 +0800 Subject: [PATCH] Initial commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 完成 Zsh 插件配置脚本的优化和测试 - 修复 autojump 配置冲突 - 清理重复的插件安装 - 优化脚本结构和注释 feat: 优化shell脚本 - 1. 增强错误处理和恢复机制 2. 添加网络连接优化和镜像源支持 3. 改进进度显示和用户交互 4. 优化配置文件管理和备份 5. 改进插件管理机制 6. 增强依赖检查和安装 7. 添加完整的日志记录功能 8. 修复字体安装相关问题 docs: 完善shell、system和utils部分的README文档 - 1. 添加详细的脚本说明和使用方法 2. 补充依赖要求和注意事项 3. 添加常见问题解答 4. 更新版本日志 feat(editor): 优化 neovim 和 nvchad 安装脚本,添加性能优化配置和详细文档 feat: 优化Python开发环境安装脚本,分离基础包和机器学习包,修复virtualenvwrapper配置 feat: 优化开发工具安装脚本,统一使用common.sh中的函数,改进错误处理 fix: 修复DNMP安装脚本,跳过自动配置PHP开发环境 fix: 提交删除的 init.sh 和 mysql.sh 文件 --- README.md | 26 +- init.sh | 140 --- scripts/database/mysql.sh | 1 - scripts/devtools/README.md | 195 +++ scripts/devtools/docker.sh | 78 +- scripts/devtools/go.sh | 114 +- scripts/devtools/node.sh | 130 +- scripts/devtools/python.sh | 253 +++- scripts/editor/README.md | 125 ++ scripts/editor/neovim.sh | 518 ++++++-- scripts/editor/nvchad.sh | 1086 ++++++----------- scripts/php/dnmp.sh | 125 +- scripts/shell/README.md | 98 ++ scripts/shell/plugins.sh | 175 ++- scripts/shell/zsh.sh | 279 +++-- scripts/system/README.md | 119 ++ .../{check_windows_wsl.bat => check-wsl.bat} | 83 +- scripts/system/check-wsl.ps1 | 187 +++ scripts/system/check_windows_wsl.ps1 | 192 --- scripts/system/install-debian.bat | 181 +++ scripts/system/install-debian.ps1 | 213 ++++ scripts/system/run-check-wsl-ps.bat | 3 + scripts/system/run-install-debian-ps.bat | 3 + scripts/system/temp.txt | Bin 136 -> 0 bytes scripts/system/upgrade_wsl2.bat | 129 -- scripts/utils/README.md | 115 ++ scripts/utils/check_user.sh | 40 + scripts/utils/common.sh | 463 +++++++ 28 files changed, 3283 insertions(+), 1788 deletions(-) delete mode 100644 init.sh delete mode 100644 scripts/database/mysql.sh create mode 100644 scripts/devtools/README.md create mode 100644 scripts/editor/README.md create mode 100644 scripts/shell/README.md create mode 100644 scripts/system/README.md rename scripts/system/{check_windows_wsl.bat => check-wsl.bat} (56%) create mode 100644 scripts/system/check-wsl.ps1 delete mode 100644 scripts/system/check_windows_wsl.ps1 create mode 100644 scripts/system/install-debian.bat create mode 100644 scripts/system/install-debian.ps1 create mode 100644 scripts/system/run-check-wsl-ps.bat create mode 100644 scripts/system/run-install-debian-ps.bat delete mode 100644 scripts/system/temp.txt delete mode 100644 scripts/system/upgrade_wsl2.bat create mode 100644 scripts/utils/README.md create mode 100644 scripts/utils/check_user.sh create mode 100644 scripts/utils/common.sh diff --git a/README.md b/README.md index bce7659..56ef60f 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,20 @@ scripts\system\check_windows_wsl.bat ### 编辑器环境脚本 - `scripts/editor/neovim.sh`: 安装和配置 Neovim + - 自动检查并安装 Neovim 0.10.0 或更高版本 + - 自动安装必要的依赖(GCC、Make、Python3、Node.js等) + - 配置 Python 和 Node.js 支持 + - 使用方法:`sudo ./scripts/editor/neovim.sh` + - `scripts/editor/nvchad.sh`: 配置 NvChad + - 自动安装 NvChad 及其依赖 + - 配置基本的 LSP 支持(Lua、Python、TypeScript等) + - 配置常用快捷键和主题 + - 使用方法: + 1. 先安装 Neovim:`sudo ./scripts/editor/neovim.sh` + 2. 再安装 NvChad:`sudo ./scripts/editor/nvchad.sh` + 3. 启动 Neovim 并等待插件安装完成:`nvim` + 4. 安装 LSP 服务器:在 Neovim 中运行 `:MasonInstallAll` ### 开发工具链脚本 - `scripts/devtools/docker.sh`: 安装 Docker 和 Docker Compose @@ -179,4 +192,15 @@ scripts\system\check_windows_wsl.bat ## 许可证 -MIT License \ No newline at end of file +MIT License + +### 常用快捷键 +- `` + `th`: 切换主题 +- `` + `ff`: 查找文件 +- `` + `fw`: 查找文本 +- `` + `ch`: 查看所有快捷键 +- `` + `h/j/k/l`: 窗口导航 +- `` + `s`: 保存文件 +- `jk`: 退出插入模式 +- ``: 切换到下一个缓冲区 +- `` + ``: 切换到上一个缓冲区 \ No newline at end of file diff --git a/init.sh b/init.sh deleted file mode 100644 index d9130c8..0000000 --- a/init.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/bin/bash - -# 设置错误时立即退出 -set -e - -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# 日志函数 -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# 检查是否为root用户 -check_root() { - if [ "$EUID" -ne 0 ]; then - log_error "请使用root权限运行此脚本" - exit 1 - fi -} - -# 检查系统要求 -check_system_requirements() { - log_info "检查系统要求..." - - # 检查内存 - local total_mem=$(free -m | awk '/^Mem:/{print $2}') - if [ "$total_mem" -lt 8192 ]; then - log_warn "系统内存小于8GB,可能会影响性能" - fi - - # 检查磁盘空间 - local free_space=$(df -m / | awk 'NR==2 {print $4}') - if [ "$free_space" -lt 51200 ]; then - log_warn "可用磁盘空间小于50GB,建议清理空间" - fi - - # 检查网络连接 - if ! ping -c 1 8.8.8.8 &> /dev/null; then - log_error "无法连接到网络,请检查网络连接" - exit 1 - fi -} - -# 安装基础系统 -install_base_system() { - log_info "开始安装基础系统..." - bash scripts/system/base.sh -} - -# 配置镜像源 -configure_mirrors() { - log_info "配置镜像源..." - bash scripts/system/mirror.sh -} - -# 安装Shell环境 -install_shell() { - log_info "安装Shell环境..." - bash scripts/shell/zsh.sh - bash scripts/shell/plugins.sh -} - -# 安装编辑器 -install_editor() { - log_info "安装编辑器..." - bash scripts/editor/neovim.sh - bash scripts/editor/nvchad.sh -} - -# 安装开发工具 -install_devtools() { - log_info "安装开发工具..." - bash scripts/devtools/docker.sh - bash scripts/devtools/go.sh - bash scripts/devtools/node.sh - bash scripts/devtools/python.sh -} - -# 安装PHP环境 -install_php() { - log_info "安装PHP环境..." - bash scripts/php/dnmp.sh -} - -# 安装系统工具 -install_utils() { - log_info "安装系统工具..." - bash scripts/utils/git.sh - bash scripts/utils/tools.sh -} - -# 主函数 -main() { - log_info "开始安装开发环境..." - - # 检查root权限 - check_root - - # 检查系统要求 - check_system_requirements - - # 安装基础系统 - install_base_system - - # 配置镜像源 - configure_mirrors - - # 安装Shell环境 - install_shell - - # 安装编辑器 - install_editor - - # 安装开发工具 - install_devtools - - # 安装PHP环境 - install_php - - # 安装系统工具 - install_utils - - log_info "安装完成!" - log_info "请重新登录以应用所有更改。" -} - -# 执行主函数 -main \ No newline at end of file diff --git a/scripts/database/mysql.sh b/scripts/database/mysql.sh deleted file mode 100644 index 0519ecb..0000000 --- a/scripts/database/mysql.sh +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/scripts/devtools/README.md b/scripts/devtools/README.md new file mode 100644 index 0000000..bd28284 --- /dev/null +++ b/scripts/devtools/README.md @@ -0,0 +1,195 @@ +# 开发工具安装脚本 + +这个目录包含了用于安装和配置各种开发工具的脚本。每个脚本都可以独立运行,也可以通过主脚本统一安装。 + +## 脚本说明 + +### 1. docker.sh + +用于安装和配置 Docker 环境。 + +#### 主要功能: +- 安装 Docker Engine +- 安装 Docker Compose +- 配置 Docker 镜像源 +- 设置用户权限 +- 配置系统参数 + +#### 使用方法: +```bash +sudo ./docker.sh +``` + +### 2. go.sh + +用于安装和配置 Go 语言开发环境。 + +#### 主要功能: +- 安装最新版本的 Go +- 配置 GOPATH 和环境变量 +- 安装常用开发工具(gopls、delve等) +- 配置代理和开发环境 + +#### 使用方法: +```bash +sudo ./go.sh +``` + +### 3. node.sh + +用于安装和配置 Node.js 开发环境。 + +#### 主要功能: +- 安装 nvm(Node Version Manager) +- 安装最新 LTS 版本的 Node.js +- 配置 npm 镜像源 +- 安装常用全局包 +- 配置开发环境 + +#### 使用方法: +```bash +sudo ./node.sh +``` + +### 4. python.sh + +用于安装和配置 Python 开发环境。 + +#### 主要功能: +- 安装 pyenv +- 安装 Python 3.11 +- 配置 pip 镜像源 +- 安装常用开发包 +- 配置虚拟环境 + +#### 使用方法: +```bash +sudo ./python.sh +``` + +## 安装说明 + +### 系统要求 +- Debian/Ubuntu 系统 +- sudo 权限 +- 网络连接 + +### 安装步骤 + +1. 克隆仓库: +```bash +git clone +cd /scripts/devtools +``` + +2. 安装所需工具: +```bash +# 安装单个工具 +sudo ./docker.sh # 安装 Docker +sudo ./go.sh # 安装 Go +sudo ./node.sh # 安装 Node.js +sudo ./python.sh # 安装 Python + +# 或者使用主脚本安装所有工具 +cd ../.. +sudo ./init.sh +``` + +3. 验证安装: +```bash +# Docker +docker --version +docker-compose --version + +# Go +go version +gopls version + +# Node.js +node --version +npm --version + +# Python +python --version +pip --version +``` + +## 配置说明 + +### Docker 配置 +- 镜像源:使用国内镜像源加速 +- 存储驱动:overlay2 +- 日志配置:json-file,自动轮转 +- 用户权限:自动添加到 docker 组 + +### Go 配置 +- GOPATH:~/go +- 代理:goproxy.cn +- 工具配置:gopls 等开发工具的默认配置 + +### Node.js 配置 +- npm 源:npmmirror.com +- 全局包路径:~/.npm-global +- nvm 配置:自动加载 + +### Python 配置 +- pip 源:清华镜像源 +- 虚拟环境:virtualenvwrapper +- pyenv 配置:自动加载 + +## 故障排除 + +### 常见问题 + +1. 权限问题 +```bash +sudo chown -R $USER:$USER ~/.npm +sudo chown -R $USER:$USER ~/.config +``` + +2. 网络问题 +```bash +# 检查网络连接 +ping github.com + +# 使用代理 +export http_proxy=http://proxy.example.com:port +export https_proxy=http://proxy.example.com:port +``` + +3. 依赖问题 +```bash +# 更新系统 +sudo apt-get update +sudo apt-get upgrade + +# 安装基础依赖 +sudo apt-get install build-essential +``` + +### 日志查看 +- 所有操作日志保存在 ~/.logs 目录 +- Docker 日志:`journalctl -u docker` +- 安装日志:`cat ~/.logs/shell_setup_*.log` + +## 维护 + +### 更新 +- Docker:`sudo apt-get update && sudo apt-get upgrade` +- Go:`go get -u all` +- Node.js:`nvm install --lts` +- Python:`pyenv update` + +### 清理 +- Docker:`docker system prune` +- Go:`go clean -cache -modcache -i -r` +- Node.js:`npm cache clean --force` +- Python:`pip cache purge` + +## 贡献 + +欢迎提交 Issue 和 Pull Request 来改进这些脚本。 + +## 许可证 + +MIT License \ No newline at end of file diff --git a/scripts/devtools/docker.sh b/scripts/devtools/docker.sh index 2bd2b4c..1a4584b 100644 --- a/scripts/devtools/docker.sh +++ b/scripts/devtools/docker.sh @@ -1,26 +1,7 @@ #!/bin/bash -# 设置错误时立即退出 -set -e - -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# 日志函数 -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} +# 导入公共函数 +source "$(dirname "$0")/../utils/common.sh" # 安装Docker Engine install_docker_engine() { @@ -30,16 +11,13 @@ install_docker_engine() { apt-get remove -y docker docker-engine docker.io containerd runc || true # 安装依赖 - apt-get update - apt-get install -y \ - apt-transport-https \ - ca-certificates \ - curl \ - gnupg \ - lsb-release + check_dependencies apt-transport-https ca-certificates curl gnupg lsb-release # 添加Docker官方GPG密钥 - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + if ! curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg; then + local mirror_url=$(get_mirror_url "https://download.docker.com/linux/debian/gpg" "github") + curl -fsSL "$mirror_url" | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + fi # 设置稳定版仓库 echo \ @@ -60,7 +38,7 @@ install_docker_engine() { exit 1 fi - log_info "Docker Engine安装完成" + log_success "Docker Engine安装完成" } # 安装Docker Compose @@ -68,15 +46,23 @@ install_docker_compose() { log_info "安装Docker Compose..." # 下载Docker Compose - curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + local compose_url="https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" + if ! curl -L "$compose_url" -o /usr/local/bin/docker-compose; then + local mirror_url=$(get_mirror_url "$compose_url" "github") + curl -L "$mirror_url" -o /usr/local/bin/docker-compose + fi # 添加执行权限 chmod +x /usr/local/bin/docker-compose # 创建命令补全 - curl -L https://raw.githubusercontent.com/docker/compose/master/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose + local completion_url="https://raw.githubusercontent.com/docker/compose/master/contrib/completion/bash/docker-compose" + if ! curl -L "$completion_url" -o /etc/bash_completion.d/docker-compose; then + local mirror_url=$(get_mirror_url "$completion_url" "github") + curl -L "$mirror_url" -o /etc/bash_completion.d/docker-compose + fi - log_info "Docker Compose安装完成" + log_success "Docker Compose安装完成" } # 配置Docker @@ -87,7 +73,15 @@ configure_docker() { groupadd docker || true # 将当前用户添加到docker组 - usermod -aG docker $USER + usermod -aG docker $CURRENT_USER + + # 创建docker配置目录 + mkdir -p /etc/docker + + # 备份现有配置 + if [ -f "/etc/docker/daemon.json" ]; then + manage_config "backup" "/etc/docker/daemon.json" + fi # 配置Docker守护进程 cat > /etc/docker/daemon.json << EOF @@ -112,11 +106,20 @@ EOF systemctl daemon-reload systemctl restart docker - log_info "Docker配置完成" + log_success "Docker配置完成" } # 主函数 main() { + # 检查root权限 + check_root + + # 获取用户信息 + get_user_info + + # 设置日志 + setup_logging + log_info "开始安装Docker..." # 安装Docker Engine @@ -128,10 +131,13 @@ main() { # 配置Docker configure_docker - log_info "Docker安装完成!" + log_success "Docker安装完成!" log_info "请重新登录以使docker组权限生效。" log_info "Windows端请手动安装Docker Desktop: https://www.docker.com/products/docker-desktop" } +# 设置清理函数 +trap cleanup EXIT + # 执行主函数 main \ No newline at end of file diff --git a/scripts/devtools/go.sh b/scripts/devtools/go.sh index fa55f7a..6d2bb67 100644 --- a/scripts/devtools/go.sh +++ b/scripts/devtools/go.sh @@ -1,42 +1,32 @@ #!/bin/bash -# 设置错误时立即退出 -set -e - -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# 日志函数 -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} +# 导入公共函数 +source "$(dirname "$0")/../utils/common.sh" # 安装Go install_go() { log_info "安装Go..." - # 下载最新版本的Go - GO_VERSION=$(curl -s https://golang.org/VERSION?m=text) - GO_URL="https://golang.org/dl/${GO_VERSION}.linux-amd64.tar.gz" + # 使用国内镜像获取最新版本 + local GO_VERSION="go1.22.1" + local GO_URL="https://mirrors.aliyun.com/golang/${GO_VERSION}.linux-amd64.tar.gz" + + cd /tmp # 下载并解压 - curl -L $GO_URL -o /tmp/go.tar.gz - tar -C /usr/local -xzf /tmp/go.tar.gz - rm /tmp/go.tar.gz + if ! curl -L "$GO_URL" -o go.tar.gz; then + log_error "下载Go失败" + return 1 + fi + + tar -C /usr/local -xzf go.tar.gz + rm go.tar.gz + + # 备份现有配置 + manage_config "backup" "${USER_HOME}/.zshrc" # 设置环境变量 - cat >> ~/.zshrc << EOF + cat >> "${USER_HOME}/.zshrc" << EOF # Go环境变量 export GOROOT=/usr/local/go export GOPATH=\$HOME/go @@ -44,15 +34,38 @@ export PATH=\$PATH:\$GOROOT/bin:\$GOPATH/bin EOF # 创建Go工作目录 - mkdir -p ~/go/{bin,src,pkg} + mkdir -p "${USER_HOME}/go/{bin,src,pkg}" + chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/go" - log_info "Go安装完成" + # 设置环境变量以便后续使用 + export GOROOT=/usr/local/go + export GOPATH="${USER_HOME}/go" + export PATH=$PATH:$GOROOT/bin:$GOPATH/bin + + log_success "Go安装完成" } # 安装常用Go工具 install_go_tools() { log_info "安装常用Go工具..." + # 切换到用户目录 + cd "${USER_HOME}" + + # 以用户身份运行命令,同时设置必要的环境变量 + su - $CURRENT_USER << EOF + # 设置Go环境变量 + export GOROOT=/usr/local/go + export GOPATH=\$HOME/go + export PATH=\$PATH:\$GOROOT/bin:\$GOPATH/bin + + # 验证Go安装 + go version || exit 1 + + # 设置Go代理 + go env -w GO111MODULE=on + go env -w GOPROXY=https://goproxy.cn,direct + # 安装gopls go install golang.org/x/tools/gopls@latest @@ -68,23 +81,33 @@ install_go_tools() { # 安装protoc-gen-go go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest +EOF - log_info "Go工具安装完成" + # 检查命令执行状态 + if [ $? -ne 0 ]; then + log_error "Go工具安装失败" + return 1 + fi + + log_success "Go工具安装完成" } # 配置Go configure_go() { log_info "配置Go..." - # 设置Go代理 - go env -w GO111MODULE=on - go env -w GOPROXY=https://goproxy.cn,direct + # 切换到用户目录 + cd "${USER_HOME}" + + # 创建gopls配置目录 + mkdir -p "${USER_HOME}/.config/gopls" + chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.config" # 配置gopls - cat > ~/.config/gopls/settings.json << EOF + cat > "${USER_HOME}/.config/gopls/settings.json" << EOF { "ui.semanticTokens": true, - "formatting.local": "github.com/your-username", + "formatting.local": "github.com/${CURRENT_USER}", "completion.placeholder": true, "hover.documentation": true, "hover.diagnostics": true, @@ -96,13 +119,25 @@ configure_go() { } EOF - log_info "Go配置完成" + log_success "Go配置完成" } # 主函数 main() { + # 检查root权限 + check_root + + # 获取用户信息 + get_user_info + + # 设置日志 + setup_logging + log_info "开始安装Go开发环境..." + # 检查依赖 + check_dependencies curl git build-essential + # 安装Go install_go @@ -112,9 +147,12 @@ main() { # 配置Go configure_go - log_info "Go开发环境安装完成!" + log_success "Go开发环境安装完成!" log_info "请运行 'source ~/.zshrc' 或重新打开终端以使环境变量生效。" } +# 设置清理函数 +trap cleanup EXIT + # 执行主函数 main \ No newline at end of file diff --git a/scripts/devtools/node.sh b/scripts/devtools/node.sh index 696c8a7..4c6cb51 100644 --- a/scripts/devtools/node.sh +++ b/scripts/devtools/node.sh @@ -1,54 +1,68 @@ #!/bin/bash -# 设置错误时立即退出 -set -e - -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# 日志函数 -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} +# 导入公共函数 +source "$(dirname "$0")/../utils/common.sh" # 安装nvm install_nvm() { log_info "安装nvm..." - # 下载nvm安装脚本 + # 清理现有的npm配置 + if [ -f "${USER_HOME}/.npmrc" ]; then + log_info "备份并删除现有的 .npmrc 文件" + manage_config "backup" "${USER_HOME}/.npmrc" + rm -f "${USER_HOME}/.npmrc" + fi + + # 卸载全局npm包 + if command -v npm &> /dev/null; then + log_info "卸载全局npm包" + npm uninstall -g @typescript-eslint/eslint-plugin @typescript-eslint/parser corepack eslint lua-format neovim prettier typescript-language-server typescript + fi + + # 切换到用户目录 + cd "${USER_HOME}" + + # 以用户身份下载并安装nvm + su - $CURRENT_USER << EOF curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash - # 配置nvm环境变量 - cat >> ~/.zshrc << EOF -# NVM配置 -export NVM_DIR="\$HOME/.nvm" -[ -s "\$NVM_DIR/nvm.sh" ] && \. "\$NVM_DIR/nvm.sh" # 加载nvm -[ -s "\$NVM_DIR/bash_completion" ] && \. "\$NVM_DIR/bash_completion" # 加载nvm bash_completion + # 设置环境变量 + export NVM_DIR="\$HOME/.nvm" + [ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh" + [ -s "\$NVM_DIR/bash_completion" ] && . "\$NVM_DIR/bash_completion" EOF - # 重新加载配置 - export NVM_DIR="$HOME/.nvm" - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" + # 备份现有配置 + manage_config "backup" "${USER_HOME}/.zshrc" - log_info "nvm安装完成" + # 配置nvm + cat >> "${USER_HOME}/.zshrc" << EOF +# nvm配置 +export NVM_DIR="\$HOME/.nvm" +[ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh" # This loads nvm +[ -s "\$NVM_DIR/bash_completion" ] && . "\$NVM_DIR/bash_completion" # This loads nvm bash_completion +EOF + + # 确保.nvm目录权限正确 + chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.nvm" + + log_success "nvm安装完成" } # 安装Node.js install_nodejs() { log_info "安装Node.js..." + # 切换到用户目录 + cd "${USER_HOME}" + + # 以用户身份运行命令 + su - $CURRENT_USER << EOF + # 设置环境变量 + export NVM_DIR="\$HOME/.nvm" + [ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh" + # 安装最新的LTS版本 nvm install --lts @@ -57,34 +71,44 @@ install_nodejs() { # 使用默认版本 nvm use default +EOF - log_info "Node.js安装完成" + log_success "Node.js安装完成" } # 配置npm configure_npm() { log_info "配置npm..." + # 切换到用户目录 + cd "${USER_HOME}" + + # 以用户身份运行命令 + su - $CURRENT_USER << 'EOF' # 设置npm镜像 npm config set registry https://registry.npmmirror.com - # 设置npm全局安装路径 - mkdir -p ~/.npm-global - npm config set prefix '~/.npm-global' - - # 添加npm全局路径到环境变量 - cat >> ~/.zshrc << EOF -# npm全局路径 -export PATH=~/.npm-global/bin:\$PATH + # 删除可能与nvm冲突的配置 + npm config delete prefix + npm config delete globalconfig EOF - log_info "npm配置完成" + log_success "npm配置完成" } # 安装全局npm包 install_global_packages() { log_info "安装全局npm包..." + # 切换到用户目录 + cd "${USER_HOME}" + + # 以用户身份运行命令 + su - $CURRENT_USER << EOF + # 设置环境变量 + export NVM_DIR="\$HOME/.nvm" + [ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh" + # 安装常用开发工具 npm install -g typescript npm install -g ts-node @@ -106,14 +130,27 @@ install_global_packages() { npm install -g eslint npm install -g prettier npm install -g stylelint +EOF - log_info "全局npm包安装完成" + log_success "全局npm包安装完成" } # 主函数 main() { + # 检查root权限 + check_root + + # 获取用户信息 + get_user_info + + # 设置日志 + setup_logging + log_info "开始安装Node.js开发环境..." + # 检查依赖 + check_dependencies curl git build-essential + # 安装nvm install_nvm @@ -126,9 +163,12 @@ main() { # 安装全局npm包 install_global_packages - log_info "Node.js开发环境安装完成!" + log_success "Node.js开发环境安装完成!" log_info "请运行 'source ~/.zshrc' 或重新打开终端以使环境变量生效。" } +# 设置清理函数 +trap cleanup EXIT + # 执行主函数 main \ No newline at end of file diff --git a/scripts/devtools/python.sh b/scripts/devtools/python.sh index 1a7258b..0d0f551 100644 --- a/scripts/devtools/python.sh +++ b/scripts/devtools/python.sh @@ -1,34 +1,14 @@ #!/bin/bash -# 设置错误时立即退出 -set -e - -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# 日志函数 -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} +# 导入公共函数 +source "$(dirname "$0")/../utils/common.sh" # 安装系统依赖 install_dependencies() { log_info "安装系统依赖..." # 安装Python开发相关包 - sudo apt-get update - sudo apt-get install -y \ + check_dependencies \ python3-dev \ python3-pip \ python3-venv \ @@ -48,38 +28,68 @@ install_dependencies() { libffi-dev \ liblzma-dev - log_info "系统依赖安装完成" + log_success "系统依赖安装完成" } # 安装pyenv install_pyenv() { log_info "安装pyenv..." - # 下载pyenv安装脚本 - curl https://pyenv.run | bash + # 切换到用户目录 + cd "${USER_HOME}" - # 配置pyenv环境变量 - cat >> ~/.zshrc << EOF + # 以用户身份下载并安装pyenv + su - $CURRENT_USER << EOF + # 下载pyenv安装脚本 + curl -L https://pyenv.run | bash + + # 设置环境变量 + export PYENV_ROOT="\$HOME/.pyenv" + export PATH="\$PYENV_ROOT/bin:\$PATH" + eval "\$(pyenv init --path)" + eval "\$(pyenv init -)" + eval "\$(pyenv virtualenv-init -)" +EOF + + # 备份现有配置 + manage_config "backup" "${USER_HOME}/.zshrc" + + # 配置pyenv + cat >> "${USER_HOME}/.zshrc" << EOF # pyenv配置 export PYENV_ROOT="\$HOME/.pyenv" export PATH="\$PYENV_ROOT/bin:\$PATH" eval "\$(pyenv init --path)" eval "\$(pyenv init -)" +eval "\$(pyenv virtualenv-init -)" EOF - # 重新加载配置 - export PYENV_ROOT="$HOME/.pyenv" - export PATH="$PYENV_ROOT/bin:$PATH" - eval "$(pyenv init --path)" - eval "$(pyenv init -)" + # 确保.pyenv目录权限正确 + chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.pyenv" - log_info "pyenv安装完成" + log_success "pyenv安装完成" } # 安装Python install_python() { log_info "安装Python..." + # 切换到用户目录 + cd "${USER_HOME}" + + # 以用户身份运行命令 + su - $CURRENT_USER << EOF + # 设置环境变量 + export PYENV_ROOT="\$HOME/.pyenv" + export PATH="\$PYENV_ROOT/bin:\$PATH" + eval "\$(pyenv init --path)" + eval "\$(pyenv init -)" + + # 安装Python依赖 + sudo apt-get install -y make build-essential libssl-dev zlib1g-dev \ + libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \ + libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev + # 安装最新的Python 3.11 pyenv install 3.11.7 @@ -88,14 +98,26 @@ install_python() { # 验证安装 python --version +EOF - log_info "Python安装完成" + log_success "Python安装完成" } # 配置pip configure_pip() { log_info "配置pip..." + # 切换到用户目录 + cd "${USER_HOME}" + + # 以用户身份运行命令 + su - $CURRENT_USER << EOF + # 设置环境变量 + export PYENV_ROOT="\$HOME/.pyenv" + export PATH="\$PYENV_ROOT/bin:\$PATH" + eval "\$(pyenv init --path)" + eval "\$(pyenv init -)" + # 升级pip python -m pip install --upgrade pip @@ -104,13 +126,35 @@ configure_pip() { # 安装pip工具 pip install wheel setuptools +EOF - log_info "pip配置完成" + log_success "pip配置完成" } -# 安装Python包 +# 安装基础Python包 install_python_packages() { - log_info "安装Python包..." + log_info "安装基础Python包..." + + # 切换到用户目录 + cd "${USER_HOME}" + + # 以用户身份运行命令 + su - $CURRENT_USER << EOF + # 设置环境变量 + export PYENV_ROOT="\$HOME/.pyenv" + export PATH="\$PYENV_ROOT/bin:\$PATH" + eval "\$(pyenv init --path)" + eval "\$(pyenv init -)" + + # 创建并激活虚拟环境 + python -m venv \$HOME/.venv + source \$HOME/.venv/bin/activate + + # 升级pip + python -m pip install --upgrade pip + + # 设置pip镜像 + pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple # 安装开发工具 pip install ipython @@ -126,9 +170,6 @@ install_python_packages() { # 安装数据处理工具 pip install numpy pip install pandas - pip install scipy - pip install matplotlib - pip install seaborn # 安装Web开发工具 pip install django @@ -138,44 +179,126 @@ install_python_packages() { pip install sqlalchemy pip install alembic - # 安装机器学习工具 - pip install scikit-learn - pip install tensorflow - pip install torch - pip install transformers - # 安装其他工具 pip install requests pip install python-dotenv pip install rich pip install tqdm - log_info "Python包安装完成" + # 退出虚拟环境 + deactivate +EOF + + # 备份现有配置 + manage_config "backup" "${USER_HOME}/.zshrc" + + # 添加虚拟环境激活命令到配置文件 + cat >> "${USER_HOME}/.zshrc" << EOF +# 激活Python虚拟环境 +source \$HOME/.venv/bin/activate 2>/dev/null || true +EOF + + log_success "基础Python包安装完成" +} + +# 安装机器学习包 +install_ml_packages() { + log_info "安装机器学习包..." + + # 切换到用户目录 + cd "${USER_HOME}" + + # 以用户身份运行命令 + su - $CURRENT_USER << EOF + # 设置环境变量 + export PYENV_ROOT="\$HOME/.pyenv" + export PATH="\$PYENV_ROOT/bin:\$PATH" + eval "\$(pyenv init --path)" + eval "\$(pyenv init -)" + + # 激活虚拟环境 + source \$HOME/.venv/bin/activate + + # 安装科学计算和可视化工具 + pip install scipy + pip install matplotlib + pip install seaborn + + # 安装机器学习工具 + pip install scikit-learn + pip install tensorflow + pip install torch + pip install transformers + + # 退出虚拟环境 + deactivate +EOF + + log_success "机器学习包安装完成" } # 配置虚拟环境 configure_venv() { log_info "配置虚拟环境..." - # 创建虚拟环境目录 - mkdir -p ~/.virtualenvs + # 切换到用户目录 + cd "${USER_HOME}" - # 安装virtualenvwrapper + # 以用户身份运行命令 + su - $CURRENT_USER << EOF + # 设置环境变量 + export PYENV_ROOT="\$HOME/.pyenv" + export PATH="\$PYENV_ROOT/bin:\$PATH" + eval "\$(pyenv init --path)" + eval "\$(pyenv init -)" + + # 使用主虚拟环境安装virtualenvwrapper + source \$HOME/.venv/bin/activate pip install virtualenvwrapper - # 配置virtualenvwrapper - cat >> ~/.zshrc << EOF -# virtualenvwrapper配置 -export WORKON_HOME=~/.virtualenvs -export PROJECT_HOME=~/projects -source ~/.local/bin/virtualenvwrapper.sh + # 创建必要的目录 + mkdir -p \$HOME/.virtualenvs + mkdir -p \$HOME/projects + + deactivate EOF - log_info "虚拟环境配置完成" + # 备份现有配置 + manage_config "backup" "${USER_HOME}/.zshrc" + + # 配置virtualenvwrapper + cat >> "${USER_HOME}/.zshrc" << EOF +# virtualenvwrapper配置 +export WORKON_HOME=\$HOME/.virtualenvs +export PROJECT_HOME=\$HOME/projects +export VIRTUALENVWRAPPER_PYTHON=\$HOME/.venv/bin/python +source \$HOME/.venv/bin/virtualenvwrapper.sh +EOF + + # 确保virtualenvwrapper.sh存在 + if [ ! -f "${USER_HOME}/.venv/bin/virtualenvwrapper.sh" ]; then + log_error "virtualenvwrapper.sh 不存在,虚拟环境配置可能不完整" + return 1 + fi + + # 设置正确的权限 + chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.venv" + chmod +x "${USER_HOME}/.venv/bin/virtualenvwrapper.sh" + + log_success "虚拟环境配置完成" } # 主函数 main() { + # 检查root权限 + check_root + + # 获取用户信息 + get_user_info + + # 设置日志 + setup_logging + log_info "开始安装Python开发环境..." # 安装系统依赖 @@ -190,15 +313,25 @@ main() { # 配置pip configure_pip - # 安装Python包 + # 安装基础Python包 install_python_packages # 配置虚拟环境 configure_venv - log_info "Python开发环境安装完成!" + # 询问是否安装机器学习包 + read -p "是否安装机器学习相关包?这些包体积较大,安装时间较长。(y/N) " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + install_ml_packages + fi + + log_success "Python开发环境安装完成!" log_info "请运行 'source ~/.zshrc' 或重新打开终端以使环境变量生效。" } +# 设置清理函数 +trap cleanup EXIT + # 执行主函数 main \ No newline at end of file diff --git a/scripts/editor/README.md b/scripts/editor/README.md new file mode 100644 index 0000000..1c0b85c --- /dev/null +++ b/scripts/editor/README.md @@ -0,0 +1,125 @@ +# Neovim 编辑器安装和配置 + +这个目录包含了用于安装和配置 Neovim 编辑器的脚本,以及 NvChad 配置框架。 + +## 脚本说明 + +### 1. neovim.sh + +用于安装和配置 Neovim 编辑器的主脚本。 + +#### 主要功能: +- 安装最新版本的 Neovim (v0.10.0+) +- 配置基础的编辑器设置 +- 安装必要的依赖(Python、Node.js等) +- 安装开发工具(ripgrep、fd等) +- 性能优化配置 + +#### 使用方法: +```bash +sudo ./neovim.sh +``` + +#### 性能优化: +- 禁用了不必要的内置插件 +- 优化了文件打开和编辑性能 +- 配置了更快的搜索引擎 +- 优化了UI渲染性能 +- 减少了不必要的状态更新 + +### 2. nvchad.sh + +用于安装和配置 NvChad 框架的脚本。 + +#### 主要功能: +- 安装 NvChad 基础框架 +- 配置自定义设置 +- 优化插件性能 +- 配置按键映射 + +#### 使用方法: +```bash +sudo ./nvchad.sh +``` + +#### 性能优化: +- 使用最小化的状态栏主题 +- 延迟加载文件树 +- 优化了 Treesitter 配置 +- 配置了高效的文件搜索 +- 禁用了不必要的图标和特效 + +## 安装后的配置 + +### 1. 基础配置 +- Leader 键设置为空格键 +- 使用相对行号 +- 启用真彩色支持 +- 配置了合理的缩进 +- 优化了搜索体验 + +### 2. 插件配置 +- Treesitter:智能语法高亮 +- Mason:LSP 包管理器 +- Telescope:模糊搜索 +- 其他优化插件 + +### 3. 快捷键 +- `ff`: 查找文件 +- `fg`: 全局搜索 +- `fb`: 查找缓冲区 +- `fh`: 查找帮助文档 + +## 性能优化建议 + +### 1. 编辑器启动 +- 使用 `nvim --startuptime startup.log` 检查启动时间 +- 按需安装语言服务器 +- 使用 lazy loading 加载插件 + +### 2. 大文件处理 +- 大文件自动禁用部分功能 +- 配置了文件大小限制 +- 优化了语法高亮设置 + +### 3. 插件优化 +- 最小化安装必要插件 +- 使用异步加载 +- 配置了合理的缓存策略 + +### 4. 系统资源 +- 配置了合理的更新时间 +- 优化了内存使用 +- 减少了不必要的 UI 更新 + +## 故障排除 + +### 1. 常见问题 +- 如果遇到插件加载错误,运行 `:checkhealth` 检查 +- 字体显示问题,确保安装了 Nerd Font +- LSP 服务器问题,使用 `:Mason` 重新安装 + +### 2. 性能问题 +- 如果编辑器变慢,检查 `:TSHighlightCapturesUnderCursor` +- 使用 `:profile start profile.log` 和 `:profile func *` 分析性能 +- 检查 `:messages` 查看警告和错误 + +## 维护 + +### 1. 更新 +- 使用 `:TSUpdate` 更新 Treesitter 解析器 +- 使用 `:MasonUpdate` 更新 LSP 服务器 +- 定期运行 `:checkhealth` 检查系统状态 + +### 2. 清理 +- 使用 `:TSUninstall` 删除不需要的解析器 +- 使用 `:Mason` 卸载不需要的 LSP +- 定期清理 `~/.local/share/nvim` 下的缓存 + +## 贡献 + +欢迎提交 Issue 和 Pull Request 来改进这些脚本。 + +## 许可证 + +MIT License \ No newline at end of file diff --git a/scripts/editor/neovim.sh b/scripts/editor/neovim.sh index 71df9d3..894761a 100644 --- a/scripts/editor/neovim.sh +++ b/scripts/editor/neovim.sh @@ -1,5 +1,8 @@ #!/bin/bash +# 导入公共函数 +source "$(dirname "$0")/../utils/common.sh" + # 设置错误时立即退出 set -e @@ -22,9 +25,39 @@ log_error() { echo -e "${RED}[ERROR]${NC} $1" } -# 安装依赖 -install_dependencies() { - log_info "安装Neovim依赖..." +# 检查命令是否存在 +check_command() { + if ! command -v "$1" &> /dev/null; then + log_error "命令 '$1' 未找到,请先安装" + exit 1 + fi +} + +# 检查是否为root用户 +if [ "$EUID" -ne 0 ]; then + log_error "请使用root权限运行此脚本" + exit 1 +fi + +# 获取当前用户名 +CURRENT_USER=$SUDO_USER +if [ -z "$CURRENT_USER" ]; then + CURRENT_USER=$(who | awk '{print $1}' | head -n1) +fi + +# 设置用户主目录 +USER_HOME="/home/$CURRENT_USER" + +# 检查 Oh My Zsh 是否已安装 +if [ ! -d "${USER_HOME}/.oh-my-zsh" ]; then + log_error "Oh My Zsh 未安装,请先运行 zsh.sh" + exit 1 +fi + +# 安装基础依赖 +install_base_dependencies() { + log_info "安装基础依赖..." + apt-get update apt-get install -y \ ninja-build \ gettext \ @@ -32,31 +65,91 @@ install_dependencies() { unzip \ curl \ git \ - nodejs \ - npm \ python3-pip \ python3-venv \ - ripgrep \ - fd-find \ - bat \ - exa \ - delta \ - tree + build-essential + + # 检查基础命令是否安装成功 + check_command git + check_command cmake + check_command python3 + check_command pip3 } -# 安装Neovim -install_neovim() { - log_info "安装Neovim..." +# 安装Node.js +install_nodejs() { + log_info "安装Node.js..." + + # 检查是否已安装 + if command -v node &> /dev/null; then + local current_version=$(node --version) + log_info "Node.js已安装,版本: $current_version" + return + fi + + # 安装Node.js + mkdir -p /etc/apt/keyrings + rm -f /etc/apt/keyrings/nodesource.gpg + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg + echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list - # 添加Neovim仓库 - add-apt-repository -y ppa:neovim-ppa/unstable apt-get update + apt-get install -y nodejs - # 安装Neovim - apt-get install -y neovim + # 验证安装 + check_command node + check_command npm + log_info "Node.js 版本: $(node --version)" + log_info "npm 版本: $(npm --version)" +} + +# 检查neovim版本 +check_neovim() { + log_info "检查Neovim是否已安装..." + if ! command -v nvim &> /dev/null; then + return 1 + fi + + # 检查版本是否 >= 0.10.0 + local nvim_version=$(nvim --version | head -n1 | cut -d ' ' -f2) + if [ "$(echo -e "${nvim_version}\n0.10.0" | sort -V | head -n1)" != "0.10.0" ]; then + log_warn "Neovim版本必须 >= 0.10.0,当前版本: ${nvim_version}" + return 1 + fi - # 创建配置目录 - mkdir -p ~/.config/nvim + return 0 +} + +# 编译安装neovim +install_neovim() { + log_info "开始编译安装Neovim..." + + # 安装编译依赖 + apt-get install -y \ + ninja-build \ + gettext \ + cmake \ + unzip \ + git + + # 克隆neovim仓库 + cd /tmp + if [ -d "neovim" ]; then + rm -rf neovim + fi + git clone https://github.com/neovim/neovim + cd neovim + + # 切换到最新版本 + git checkout master + + # 编译安装 + make CMAKE_BUILD_TYPE=RelWithDebInfo + make install + + # 清理 + cd .. + rm -rf neovim } # 安装Python包 @@ -64,101 +157,127 @@ install_python_packages() { log_info "安装Python包..." # 创建虚拟环境 - python3 -m venv ~/.local/share/nvim/venv + su - $CURRENT_USER -c "python3 -m venv ${USER_HOME}/.local/share/nvim/venv" # 激活虚拟环境并安装包 - source ~/.local/share/nvim/venv/bin/activate - pip install pynvim - pip install black - pip install isort - pip install flake8 - pip install mypy - pip install jedi - deactivate + su - $CURRENT_USER -c "source ${USER_HOME}/.local/share/nvim/venv/bin/activate && \ + pip install --upgrade pip && \ + pip install pynvim black isort flake8 mypy jedi && \ + deactivate" } # 安装Node.js包 install_node_packages() { log_info "安装Node.js包..." + # 设置npm全局包安装目录 + su - $CURRENT_USER -c "mkdir -p ${USER_HOME}/.npm-global" + su - $CURRENT_USER -c "npm config set prefix '${USER_HOME}/.npm-global'" + + # 添加PATH到.zshrc + if ! grep -q "HOME/.npm-global/bin" "${USER_HOME}/.zshrc"; then + echo 'export PATH=~/.npm-global/bin:$PATH' >> "${USER_HOME}/.zshrc" + fi + + # 设置环境变量以便立即使用 + export PATH="${USER_HOME}/.npm-global/bin:$PATH" + # 安装全局npm包 - npm install -g neovim - npm install -g typescript - npm install -g ts-node - npm install -g prettier - npm install -g eslint + su - $CURRENT_USER -c "export PATH=${USER_HOME}/.npm-global/bin:\$PATH && \ + npm install -g neovim typescript ts-node prettier eslint" } # 配置Neovim configure_neovim() { log_info "配置Neovim..." + # 创建配置目录 + mkdir -p ${USER_HOME}/.config/nvim + # 创建基本配置 - cat > ~/.config/nvim/init.vim << EOF -" 基本设置 -set number -set relativenumber -set expandtab -set tabstop=4 -set shiftwidth=4 -set softtabstop=4 -set smartindent -set nowrap -set noswapfile -set nobackup -set undodir=~/.vim/undodir -set undofile -set incsearch -set nohlsearch -set ignorecase -set smartcase -set termguicolors -set scrolloff=8 -set signcolumn=yes -set updatetime=50 -set colorcolumn=80 -set splitright -set splitbelow + cat > ${USER_HOME}/.config/nvim/init.vim << EOF +" 性能优化设置 +set nobackup " 禁用备份文件 +set nowritebackup " 禁用写入时的备份 +set noswapfile " 禁用交换文件 +set hidden " 允许在未保存的情况下切换缓冲区 +set noshowmode " 不显示当前模式(由状态栏插件显示) +set lazyredraw " 延迟重绘以提高性能 +set updatetime=300 " 更新时间间隔(默认4000ms太慢) +set timeoutlen=500 " 键盘序列等待时间 +set synmaxcol=200 " 限制语法高亮的列数以提高性能 +set regexpengine=1 " 使用老的正则引擎(更快) +set ttyfast " 指示快速终端连接以优化重绘 -" 设置leader键 -let mapleader = " " +" 基本UI设置 +set number " 显示行号 +set relativenumber " 显示相对行号 +set signcolumn=yes " 总是显示标记列 +set termguicolors " 启用真彩色 +set scrolloff=8 " 光标上下保持8行距离 +set sidescrolloff=8 " 水平滚动时保持8列距离 +set cmdheight=1 " 命令行高度 +set shortmess+=c " 不显示补全相关的消息 -" 设置文件类型检测 -filetype plugin indent on +" 缩进和制表符设置 +set expandtab " 使用空格代替制表符 +set tabstop=4 " 制表符等于4个空格 +set shiftwidth=4 " 缩进等于4个空格 +set softtabstop=4 " 退格键一次删除4个空格 +set smartindent " 智能缩进 -" 设置语法高亮 -syntax enable +" 搜索设置 +set ignorecase " 搜索忽略大小写 +set smartcase " 智能大小写搜索 +set incsearch " 增量搜索 +set nohlsearch " 不高亮搜索结果 -" 设置编码 +" 编码设置 set encoding=utf-8 set fileencoding=utf-8 set termencoding=utf-8 -" 设置状态栏 -set laststatus=2 -set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")} - -" 设置命令模式补全 -set wildmenu -set wildmode=list:longest,full - -" 设置历史记录 -set history=1000 -set undolevels=1000 - -" 设置鼠标支持 -set mouse=a - -" 设置剪贴板 +" 系统剪贴板集成 set clipboard=unnamedplus -" 设置自动补全 -set completeopt=menu,menuone,noselect +" 文件类型设置 +filetype plugin indent on +syntax enable -" 设置终端颜色 -set t_Co=256 -set background=dark +" 设置leader键 +let mapleader = " " + +" 创建必要的目录 +if !isdirectory(expand('~/.local/share/nvim/backup')) + silent! call mkdir(expand('~/.local/share/nvim/backup'), 'p') +endif + +" 性能相关的全局变量 +let g:loaded_matchparen = 1 " 禁用括号匹配(提高性能) +let g:loaded_matchit = 1 " 禁用扩展的%匹配 +let g:loaded_logiPat = 1 " 禁用逻辑模式插件 +let g:loaded_rrhelper = 1 " 禁用远程插件帮助 +let g:loaded_tarPlugin = 1 " 禁用tar文件插件 +let g:loaded_gzip = 1 " 禁用gzip插件 +let g:loaded_zipPlugin = 1 " 禁用zip插件 +let g:loaded_2html_plugin = 1 " 禁用2html插件 +let g:loaded_shada_plugin = 1 " 禁用shada插件 +let g:loaded_spellfile_plugin = 1 " 禁用拼写文件插件 +let g:loaded_netrw = 1 " 禁用netrw +let g:loaded_netrwPlugin = 1 " 禁用netrw插件 +let g:loaded_tutor_mode_plugin = 1 " 禁用教程插件 +let g:loaded_remote_plugins = 1 " 禁用远程插件 + +" 文件类型特定的性能优化 +augroup performance_optimizations + autocmd! + " 大文件打开时禁用某些功能 + autocmd BufReadPre * let f=getfsize(expand("")) | if f > 100000 || f == -2 | set eventignore+=FileType | setlocal noswapfile bufhidden=unload buftype=nowrite undolevels=-1 | else | set eventignore-=FileType | endif +augroup END EOF + + # 设置权限 + chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.config/nvim } # 安装语言服务器 @@ -166,39 +285,190 @@ install_language_servers() { log_info "安装语言服务器..." # 安装各种语言的LSP服务器 - npm install -g typescript-language-server - npm install -g vscode-langservers-extracted - npm install -g @tailwindcss/language-server - npm install -g @prisma/language-server - npm install -g graphql-language-service-cli - npm install -g vscode-html-languageserver-bin - npm install -g vscode-css-languageserver-bin - npm install -g vscode-json-languageserver-bin - npm install -g vscode-eslint-language-server - npm install -g @typescript-eslint/parser - npm install -g @typescript-eslint/eslint-plugin - npm install -g eslint_d - npm install -g prettier - npm install -g stylelint - npm install -g markdownlint-cli - npm install -g yaml-language-server - npm install -g dockerfile-language-server-nodejs - npm install -g bash-language-server - npm install -g vscode-langservers-extracted + su - $CURRENT_USER -c "export PATH=${USER_HOME}/.npm-global/bin:\$PATH && \ + npm install -g \ + typescript-language-server \ + vscode-langservers-extracted \ + eslint \ + prettier \ + bash-language-server" } -# 主函数 -main() { - log_info "开始安装Neovim..." +# 删除旧版本vi +remove_old_vi() { + log_info "检查并删除旧版本vi..." - # 安装依赖 - install_dependencies + # 检查是否安装了vim或vi + if dpkg -l | grep -qw "vim\|vi"; then + log_info "发现旧版本编辑器,正在删除..." + apt-get remove -y vim vim-runtime vim-tiny vim-common vim-gui-common + apt-get autoremove -y + + # 删除vim配置 + if [ -d "${USER_HOME}/.vim" ]; then + mv "${USER_HOME}/.vim" "${USER_HOME}/.vim.bak.$(date +%Y%m%d_%H%M%S)" + fi + if [ -f "${USER_HOME}/.vimrc" ]; then + mv "${USER_HOME}/.vimrc" "${USER_HOME}/.vimrc.bak.$(date +%Y%m%d_%H%M%S)" + fi + else + log_info "未发现旧版本编辑器" + fi +} + +# 安装额外的开发工具 +install_dev_tools() { + log_info "安装开发工具..." - # 安装Neovim - install_neovim + # 安装通用开发工具 + apt-get install -y \ + ripgrep \ + fd-find \ + universal-ctags \ + shellcheck \ + yamllint + + # 创建fd-find软链接 + ln -sf $(which fdfind) /usr/local/bin/fd +} + +# 配置Python环境 +setup_python_env() { + log_info "配置Python环境..." + + # 安装Python开发工具 + apt-get install -y \ + python3-dev \ + python3-pip \ + python3-venv + + # 创建虚拟环境 + su - $CURRENT_USER -c "python3 -m venv ${USER_HOME}/.local/share/nvim/venv" # 安装Python包 - install_python_packages + su - $CURRENT_USER -c "source ${USER_HOME}/.local/share/nvim/venv/bin/activate && \ + pip install --upgrade pip && \ + pip install \ + pynvim \ + black \ + isort \ + flake8 \ + mypy \ + jedi \ + pylint \ + rope \ + debugpy && \ + deactivate" +} + +# 卸载并清理neovim +uninstall_neovim() { + log_info "卸载并清理Neovim..." + + # 停止所有neovim进程 + if pgrep -f nvim > /dev/null; then + log_info "停止所有Neovim进程..." + pkill -f nvim + fi + + # 卸载neovim包 + if dpkg -l | grep -q neovim; then + log_info "卸载Neovim包..." + apt-get remove --purge -y neovim + apt-get autoremove -y + fi + + # 删除neovim相关目录和文件 + log_info "清理Neovim相关文件..." + + # 系统级文件 + if [ -d "/opt/nvim" ]; then + rm -rf /opt/nvim + fi + if [ -f "/usr/local/bin/nvim" ]; then + rm -f /usr/local/bin/nvim + fi + if [ -d "/usr/local/share/nvim" ]; then + rm -rf /usr/local/share/nvim + fi + if [ -d "/usr/local/lib/nvim" ]; then + rm -rf /usr/local/lib/nvim + fi + if [ -d "/usr/local/lib/lua/5.1/nvim" ]; then + rm -rf /usr/local/lib/lua/5.1/nvim + fi + if [ -d "/usr/local/lib/lua/5.4/nvim" ]; then + rm -rf /usr/local/lib/lua/5.4/nvim + fi + + # 用户级文件 + if [ -d "${USER_HOME}/.config/nvim" ]; then + rm -rf "${USER_HOME}/.config/nvim" + fi + if [ -d "${USER_HOME}/.local/share/nvim" ]; then + rm -rf "${USER_HOME}/.local/share/nvim" + fi + if [ -d "${USER_HOME}/.local/share/lazy" ]; then + rm -rf "${USER_HOME}/.local/share/lazy" + fi + if [ -d "${USER_HOME}/.local/state/nvim" ]; then + rm -rf "${USER_HOME}/.local/state/nvim" + fi + if [ -d "${USER_HOME}/.cache/nvim" ]; then + rm -rf "${USER_HOME}/.cache/nvim" + fi + + # 确保目录权限正确 + log_info "修复目录权限..." + if [ -d "${USER_HOME}/.config" ]; then + chown -R ${CURRENT_USER}:${CURRENT_USER} "${USER_HOME}/.config" + fi + if [ -d "${USER_HOME}/.local" ]; then + chown -R ${CURRENT_USER}:${CURRENT_USER} "${USER_HOME}/.local" + fi + if [ -d "${USER_HOME}/.cache" ]; then + chown -R ${CURRENT_USER}:${CURRENT_USER} "${USER_HOME}/.cache" + fi + + log_success "Neovim已完全卸载并清理" +} + +# 更新主函数 +main() { + # 检查root权限 + check_root + + # 获取用户信息 + get_user_info + + # 卸载并清理旧版本neovim + uninstall_neovim + + # 删除旧版本vi + remove_old_vi + + # 安装基础依赖 + install_base_dependencies + + # 检查neovim版本 + if ! check_neovim; then + log_info "Neovim未安装或版本不符合要求,开始编译安装..." + if ! install_neovim; then + log_error "Neovim安装失败" + exit 1 + fi + else + log_success "Neovim已安装且版本符合要求" + fi + + # 安装开发工具 + install_dev_tools + + # 安装Node.js + install_nodejs + + # 配置Python环境 + setup_python_env # 安装Node.js包 install_node_packages @@ -209,9 +479,23 @@ main() { # 安装语言服务器 install_language_servers - log_info "Neovim安装完成!" - log_info "请运行 nvim 来启动编辑器。" - log_info "首次启动时会自动安装插件。" + log_success "Neovim安装完成!" + log_info "请运行以下命令使环境变量生效:" + log_info "source ~/.zshrc" + log_info "然后运行 nvim 来启动编辑器。" + + # 显示安装的工具版本 + log_info "已安装的工具版本:" + nvim --version | head -n1 + node --version + npm --version + python3 --version + if command -v rg &> /dev/null; then + rg --version | head -n1 + fi + if command -v fd &> /dev/null; then + fd --version + fi } # 执行主函数 diff --git a/scripts/editor/nvchad.sh b/scripts/editor/nvchad.sh index 8577659..0145b9d 100644 --- a/scripts/editor/nvchad.sh +++ b/scripts/editor/nvchad.sh @@ -1,778 +1,384 @@ #!/bin/bash -# 设置错误时立即退出 -set -e +# 导入公共函数 +source "$(dirname "$0")/../utils/common.sh" -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color +# 检查neovim版本 +check_neovim() { + log_info "检查Neovim是否已安装..." + if ! command -v nvim &> /dev/null; then + log_error "Neovim未安装,请先运行 neovim.sh" + exit 1 + fi -# 日志函数 -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" + # 检查版本是否 >= 0.10.0 + local nvim_version=$(nvim --version | head -n1 | cut -d ' ' -f2) + if [ "$(echo -e "${nvim_version}\n0.10.0" | sort -V | head -n1)" != "0.10.0" ]; then + log_error "Neovim版本必须 >= 0.10.0,当前版本: ${nvim_version}" + log_info "正在安装最新版本的Neovim..." + + # 下载最新版本的Neovim + curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz + + # 删除旧的安装 + sudo rm -rf /opt/nvim + + # 解压到/opt目录 + sudo tar -C /opt -xzf nvim-linux-x86_64.tar.gz + + # 删除下载的压缩包 + rm nvim-linux-linux-x86_64.tar.gz + + # 创建符号链接 + sudo ln -sf /opt/nvim-linux-x86_64/bin/nvim /usr/local/bin/nvim + + # 重新检查版本 + nvim_version=$(nvim --version | head -n1 | cut -d ' ' -f2) + if [ "$(echo -e "${nvim_version}\n0.10.0" | sort -V | head -n1)" != "0.10.0" ]; then + log_error "Neovim版本仍然不满足要求,尝试从源码编译安装..." + + # 安装编译依赖 + sudo apt-get install -y ninja-build gettext cmake unzip curl + + # 克隆源码 + git clone https://github.com/neovim/neovim + cd neovim + + # 编译安装 + make CMAKE_BUILD_TYPE=Release + sudo make install + + # 返回上级目录 + cd .. + + # 删除源码 + rm -rf neovim + + # 再次检查版本 + nvim_version=$(nvim --version | head -n1 | cut -d ' ' -f2) + if [ "$(echo -e "${nvim_version}\n0.10.0" | sort -V | head -n1)" != "0.10.0" ]; then + log_error "Neovim版本仍然不满足要求,请手动安装最新版本" + exit 1 + fi + fi + fi + + log_success "Neovim版本检查通过: ${nvim_version}" } # 备份现有配置 backup_config() { log_info "备份现有配置..." - if [ -d ~/.config/nvim ]; then - mv ~/.config/nvim ~/.config/nvim.backup + + # 检查是否存在配置目录 + if [ -d "${USER_HOME}/.config/nvim" ]; then + # 创建备份目录 + local backup_dir="${USER_HOME}/.config/nvim.backup.$(date +%Y%m%d_%H%M%S)" + log_info "备份原配置到: $backup_dir" + + # 移动现有配置到备份目录 + mv "${USER_HOME}/.config/nvim" "$backup_dir" fi + + # 确保删除所有可能存在的缓存和配置 + log_info "清理旧配置和缓存..." + rm -rf "${USER_HOME}/.config/nvim" + rm -rf "${USER_HOME}/.local/share/nvim" + rm -rf "${USER_HOME}/.cache/nvim" + rm -rf "${USER_HOME}/.local/state/nvim" + rm -rf "${USER_HOME}/.local/share/lazy" + rm -rf "${USER_HOME}/.local/share/nvim" + rm -rf "${USER_HOME}/.local/state/nvim" + rm -rf "${USER_HOME}/.cache/nvim" + + # 确保目录存在且权限正确 + mkdir -p "${USER_HOME}/.config/nvim" + chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.config/nvim" } # 安装NvChad install_nvchad() { log_info "安装NvChad..." - # 克隆NvChad仓库 - git clone https://github.com/NvChad/NvChad ~/.config/nvim --depth 1 + # 确保目录存在且权限正确 + sudo mkdir -p "${USER_HOME}/.config/nvim" + sudo chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.config/nvim" - # 创建自定义配置目录 - mkdir -p ~/.config/nvim/lua/custom + # 使用当前用户克隆starter仓库 + su - $CURRENT_USER -c "git clone https://github.com/NvChad/starter ${USER_HOME}/.config/nvim" + + # 删除.git文件夹 + rm -rf "${USER_HOME}/.config/nvim/.git" + + # 确保目录权限正确 + sudo chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.config/nvim" + + if [ $? -eq 0 ]; then + log_success "NvChad安装成功" + else + log_error "NvChad安装失败" + exit 1 + fi } # 配置NvChad configure_nvchad() { log_info "配置NvChad..." - # 创建自定义配置 - cat > ~/.config/nvim/lua/custom/init.lua << EOF + # 创建自定义配置目录 + su - $CURRENT_USER -c "mkdir -p ${USER_HOME}/.config/nvim/lua/custom/configs" + + # 创建自定义chadrc.lua + cat > "${USER_HOME}/.config/nvim/lua/custom/chadrc.lua" << 'EOF' +---@type ChadrcConfig local M = {} --- 自定义配置 -M.config = { - -- 设置主题 - theme = "catppuccin", - - -- 设置字体 - font = "MesloLGS NF", - - -- 设置终端 - terminal = "kitty", - - -- 设置透明度 - transparency = false, - - -- 设置行号 - line_numbers = true, - - -- 设置相对行号 - relative_line_numbers = true, - - -- 设置状态栏 - statusline = { - theme = "minimal", - separator_style = "block", - }, - - -- 设置标签栏 - tabline = { - theme = "minimal", - separator_style = "block", - }, - - -- 设置文件树 - nvimtree = { - side = "left", - width = 30, - }, - - -- 设置窗口 - window = { - border = "rounded", - padding = 1, - }, - - -- 设置补全 - completion = { - border = "rounded", - padding = 1, - }, - - -- 设置诊断 - diagnostics = { - virtual_text = true, - signs = true, - underline = true, - }, - - -- 设置LSP - lsp = { - signature = true, - virtual_text = true, - signs = true, - underline = true, - }, - - -- 设置格式化 - formatting = { - timeout_ms = 500, - async = true, - quiet = false, - }, - - -- 设置快捷键 - keymaps = { - -- 窗口管理 - [""] = "h", - [""] = "j", - [""] = "k", - [""] = "l", - [""] = ":resize -2", - [""] = ":resize +2", - [""] = ":vertical resize -2", - [""] = ":vertical resize +2", - - -- 标签页管理 - [""] = ":bprevious", - [""] = ":bnext", - [""] = ":bdelete", - - -- 文件树 - [""] = ":NvimTreeToggle", - - -- 终端 - [""] = ":ToggleTerm", - - -- 查找 - [""] = ":Telescope find_files", - [""] = ":Telescope live_grep", - [""] = ":Telescope buffers", - [""] = ":Telescope help_tags", - - -- LSP - ["gd"] = ":lua vim.lsp.buf.definition()", - ["gr"] = ":lua vim.lsp.buf.references()", - ["K"] = ":lua vim.lsp.buf.hover()", - [""] = ":lua vim.lsp.buf.signature_help()", - ["rn"] = ":lua vim.lsp.buf.rename()", - ["ca"] = ":lua vim.lsp.buf.code_action()", - ["d"] = ":lua vim.diagnostic.open_float()", - ["f"] = ":lua vim.lsp.buf.formatting()", - - -- Git - ["gs"] = ":Git", - ["gc"] = ":Git commit", - ["gp"] = ":Git push", - ["gl"] = ":Git pull", - ["gd"] = ":Git diff", - ["gb"] = ":Git blame", - }, +-- UI配置 +M.ui = { + theme = 'catppuccin', + transparency = false, + + -- 性能优化相关设置 + statusline = { + theme = "minimal", -- minimal主题性能更好 + separator_style = "default", + overriden_modules = nil, + }, + + -- 延迟加载文件树 + nvdash = { + load_on_startup = false, + }, + + -- 禁用不必要的图标 + hl_override = { + Comment = { italic = false }, + }, } --- 自定义插件 -M.plugins = { - -- 主题 - { - "catppuccin/nvim", - name = "catppuccin", - priority = 1000, - config = function() - vim.cmd.colorscheme "catppuccin" +-- 插件配置 +M.plugins = "custom.plugins" + +-- 映射配置 +M.mappings = require "custom.mappings" + +return M +EOF + + # 创建插件配置文件 + cat > "${USER_HOME}/.config/nvim/lua/custom/plugins.lua" << 'EOF' +local plugins = { + { + "nvim-treesitter/nvim-treesitter", + opts = { + ensure_installed = { "lua", "vim", "bash" }, -- 只安装最基础的语言支持 + sync_install = false, -- 异步安装 + auto_install = false, -- 禁用自动安装 + highlight = { + enable = true, + disable = function(_, buf) + local max_filesize = 100 * 1024 -- 100 KB + local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) + if ok and stats and stats.size > max_filesize then + return true + end end, + additional_vim_regex_highlighting = false, + }, }, - - -- 状态栏 - { - "nvim-lualine/lualine.nvim", - config = function() - require("custom.plugins.lualine") - end, - }, - - -- 标签栏 - { - "akinsho/bufferline.nvim", - config = function() - require("custom.plugins.bufferline") - end, - }, - - -- 文件树 - { - "nvim-tree/nvim-tree.lua", - config = function() - require("custom.plugins.nvimtree") - end, - }, - - -- 终端 - { - "akinsho/toggleterm.nvim", - config = function() - require("custom.plugins.toggleterm") - end, - }, - - -- 查找 - { - "nvim-telescope/telescope.nvim", - config = function() - require("custom.plugins.telescope") - end, - }, - - -- LSP - { - "neovim/nvim-lspconfig", - config = function() - require("custom.plugins.lspconfig") - end, - }, - - -- 补全 - { - "hrsh7th/nvim-cmp", - config = function() - require("custom.plugins.cmp") - end, - }, - - -- 语法高亮 - { - "nvim-treesitter/nvim-treesitter", - config = function() - require("custom.plugins.treesitter") - end, - }, - - -- Git - { - "lewis6991/gitsigns.nvim", - config = function() - require("custom.plugins.gitsigns") - end, - }, - { - "tpope/vim-fugitive", - }, - - -- 注释 - { - "numToStr/Comment.nvim", - config = function() - require("custom.plugins.comment") - end, - }, - - -- 自动配对 - { - "windwp/nvim-autopairs", - config = function() - require("custom.plugins.autopairs") - end, - }, - - -- 代码片段 - { - "L3MON4D3/LuaSnip", - config = function() - require("custom.plugins.luasnip") - end, - }, - - -- 格式化 - { - "jose-elias-alvarez/null-ls.nvim", - config = function() - require("custom.plugins.null-ls") - end, + }, + + { + "williamboman/mason.nvim", + opts = { + ensure_installed = {}, -- 按需安装LSP + PATH = "skip", + ui = { + border = "none", + icons = { + package_installed = "✓", + package_pending = "➜", + package_uninstalled = "✗" + }, + keymaps = { + toggle_server_expand = "", + install_server = "i", + update_server = "u", + check_server_version = "c", + update_all_servers = "U", + check_outdated_servers = "C", + uninstall_server = "X", + cancel_installation = "", + }, + }, }, + }, + + { + "nvim-telescope/telescope.nvim", + opts = function() + local conf = require "plugins.configs.telescope" + conf.defaults.file_ignore_patterns = { + "node_modules", + "build", + "dist", + "yarn.lock", + ".git", + } + conf.defaults.vimgrep_arguments = { + "rg", + "--color=never", + "--no-heading", + "--with-filename", + "--line-number", + "--column", + "--smart-case", + "--hidden", + } + conf.pickers = { + find_files = { + find_command = { "fd", "--type", "f", "--strip-cwd-prefix" } + }, + } + return conf + end, + }, +} + +return plugins +EOF + + # 创建按键映射配置文件 + cat > "${USER_HOME}/.config/nvim/lua/custom/mappings.lua" << 'EOF' +local M = {} + +M.general = { + n = { + ["ff"] = { " Telescope find_files ", "查找文件" }, + ["fg"] = { " Telescope live_grep ", "全局搜索" }, + ["fb"] = { " Telescope buffers ", "查找缓冲区" }, + ["fh"] = { " Telescope help_tags ", "帮助标签" }, + }, } return M EOF - # 创建插件配置目录 - mkdir -p ~/.config/nvim/lua/custom/plugins + # 创建性能优化配置文件 + cat > "${USER_HOME}/.config/nvim/lua/custom/configs/performance.lua" << 'EOF' +local M = {} + +-- 性能优化设置 +M.setup = function() + -- 禁用一些内置的vim插件 + local disabled_built_ins = { + "2html_plugin", + "getscript", + "getscriptPlugin", + "gzip", + "logipat", + "netrw", + "netrwPlugin", + "netrwSettings", + "netrwFileHandlers", + "matchit", + "tar", + "tarPlugin", + "rrhelper", + "spellfile_plugin", + "vimball", + "vimballPlugin", + "zip", + "zipPlugin", + "tutor", + "rplugin", + "syntax", + "synmenu", + "optwin", + "compiler", + "bugreport", + "ftplugin", + } + + for _, plugin in pairs(disabled_built_ins) do + vim.g["loaded_" .. plugin] = 1 + end + + -- 设置python主机 + vim.g.python3_host_prog = vim.fn.exepath('python3') + vim.g.loaded_python_provider = 0 + + -- 优化启动时间 + vim.loader.enable() + + -- UI性能优化 + vim.opt.lazyredraw = true + vim.opt.shadafile = "NONE" + vim.opt.updatetime = 300 + vim.opt.timeoutlen = 500 + vim.opt.redrawtime = 1500 + vim.opt.synmaxcol = 200 + vim.opt.laststatus = 2 + + -- 禁用一些不必要的状态更新 + vim.opt.ruler = false + vim.opt.showcmd = false + + -- 使用新的正则引擎 + vim.opt.regexpengine = 1 + + -- 设置更快的macro执行 + vim.opt.maxmapdepth = 1000 + + -- 优化滚动性能 + vim.opt.scrolljump = 5 + + -- 优化文件打开性能 + vim.opt.hidden = true +end + +return M +EOF + + # 设置权限 + chown -R $CURRENT_USER:$CURRENT_USER "${USER_HOME}/.config/nvim" +} + +# 检查并安装依赖 +install_base_dependencies() { + log_info "检查并安装依赖..." - # 配置状态栏 - cat > ~/.config/nvim/lua/custom/plugins/lualine.lua << EOF -local M = {} - -function M.setup() - require("lualine").setup({ - options = { - theme = "catppuccin", - component_separators = { left = "", right = "" }, - section_separators = { left = "", right = "" }, - globalstatus = true, - }, - sections = { - lualine_a = { - { "mode", separator = { left = "" }, right_padding = 2 }, - }, - lualine_b = { - "filename", - "branch", - "diff", - "diagnostics", - }, - lualine_c = { - "filetype", - "progress", - "location", - }, - lualine_x = { - "encoding", - "fileformat", - "hostname", - }, - lualine_y = { - "filesize", - "filetype", - }, - lualine_z = { - { "datetime", style = "%H:%M" }, - }, - }, - }) -end - -return M -EOF - - # 配置标签栏 - cat > ~/.config/nvim/lua/custom/plugins/bufferline.lua << EOF -local M = {} - -function M.setup() - require("bufferline").setup({ - options = { - theme = "catppuccin", - separator_style = "block", - always_show_bufferline = true, - show_buffer_close_icons = true, - show_close_icon = true, - show_tab_indicators = true, - show_duplicate_prefix = true, - enforce_regular_tabs = true, - view = "multiwindow", - show_buffer_icons = true, - show_tab_indicators = true, - persist_buffer_sort = true, - always_show_bufferline = true, - sort_by = "extension", - }, - highlights = require("catppuccin.groups.integrations.bufferline").get(), - }) -end - -return M -EOF - - # 配置文件树 - cat > ~/.config/nvim/lua/custom/plugins/nvimtree.lua << EOF -local M = {} - -function M.setup() - require("nvim-tree").setup({ - sort_by = "case_sensitive", - view = { - width = 30, - }, - renderer = { - group_empty = true, - }, - filters = { - dotfiles = false, - }, - }) -end - -return M -EOF - - # 配置终端 - cat > ~/.config/nvim/lua/custom/plugins/toggleterm.lua << EOF -local M = {} - -function M.setup() - require("toggleterm").setup({ - size = function(term) - if term.direction == "horizontal" then - return 15 - elseif term.direction == "vertical" then - return vim.o.columns * 0.4 - end - end, - open_mapping = [[]], - hide_numbers = true, - shade_filetypes = {}, - shade_terminals = true, - shading_factor = 2, - start_in_insert = true, - insert_mappings = true, - persist_size = true, - direction = "float", - close_on_exit = true, - shell = vim.o.shell, - float_opts = { - border = "curved", - winblend = 0, - highlights = { - border = "Normal", - background = "Normal", - }, - }, - }) -end - -return M -EOF - - # 配置查找 - cat > ~/.config/nvim/lua/custom/plugins/telescope.lua << EOF -local M = {} - -function M.setup() - require("telescope").setup({ - defaults = { - prompt_prefix = "🔍 ", - selection_caret = "➜ ", - path_display = { "smart" }, - file_ignore_patterns = { - ".git/", - "node_modules/", - "venv/", - "__pycache__/", - ".pytest_cache/", - ".mypy_cache/", - }, - }, - pickers = { - find_files = { - theme = "dropdown", - previewer = false, - }, - live_grep = { - theme = "dropdown", - previewer = false, - }, - buffers = { - theme = "dropdown", - previewer = false, - }, - help_tags = { - theme = "dropdown", - previewer = false, - }, - }, - extensions = { - fzf = { - fuzzy = true, - override_generic_sorter = true, - override_file_sorter = true, - case_mode = "smart_case", - }, - }, - }) -end - -return M -EOF - - # 配置LSP - cat > ~/.config/nvim/lua/custom/plugins/lspconfig.lua << EOF -local M = {} - -function M.setup() - local lspconfig = require("lspconfig") - local capabilities = require("cmp_nvim_lsp").default_capabilities() - local on_attach = function(client, bufnr) - local opts = { noremap = true, silent = true, buffer = bufnr } - vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) - vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) - vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) - vim.keymap.set("n", "", vim.lsp.buf.signature_help, opts) - vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts) - vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts) - vim.keymap.set("n", "d", vim.diagnostic.open_float, opts) - vim.keymap.set("n", "f", vim.lsp.buf.formatting, opts) - end - - -- 配置各种语言的LSP服务器 - local servers = { - "tsserver", - "html", - "cssls", - "jsonls", - "eslint", - "tailwindcss", - "prismals", - "graphql", - "yamlls", - "dockerls", - "bashls", - "pyright", - "gopls", - "rust_analyzer", - "lua_ls", - } - - for _, lsp in ipairs(servers) do - lspconfig[lsp].setup({ - capabilities = capabilities, - on_attach = on_attach, - }) - end -end - -return M -EOF - - # 配置补全 - cat > ~/.config/nvim/lua/custom/plugins/cmp.lua << EOF -local M = {} - -function M.setup() - local cmp = require("cmp") - local luasnip = require("luasnip") - - cmp.setup({ - snippet = { - expand = function(args) - luasnip.lsp_expand(args.body) - end, - }, - mapping = { - [""] = cmp.mapping.select_prev_item(), - [""] = cmp.mapping.select_next_item(), - [""] = cmp.mapping.scroll_docs(-4), - [""] = cmp.mapping.scroll_docs(4), - [""] = cmp.mapping.complete(), - [""] = cmp.mapping.close(), - [""] = cmp.mapping.confirm({ - behavior = cmp.ConfirmBehavior.Replace, - select = true, - }), - }, - sources = { - { name = "nvim_lsp" }, - { name = "luasnip" }, - { name = "buffer" }, - { name = "path" }, - }, - }) -end - -return M -EOF - - # 配置语法高亮 - cat > ~/.config/nvim/lua/custom/plugins/treesitter.lua << EOF -local M = {} - -function M.setup() - require("nvim-treesitter.configs").setup({ - ensure_installed = { - "lua", - "vim", - "vimdoc", - "javascript", - "typescript", - "html", - "css", - "json", - "yaml", - "toml", - "markdown", - "bash", - "python", - "go", - "rust", - }, - highlight = { - enable = true, - use_languagetree = true, - }, - indent = { - enable = true, - }, - }) -end - -return M -EOF - - # 配置Git - cat > ~/.config/nvim/lua/custom/plugins/gitsigns.lua << EOF -local M = {} - -function M.setup() - require("gitsigns").setup({ - signs = { - add = { text = "│" }, - change = { text = "│" }, - delete = { text = "_" }, - topdelete = { text = "‾" }, - changedelete = { text = "~" }, - untracked = { text = "┆" }, - }, - signcolumn = true, - numhl = true, - linehl = false, - word_diff = false, - watch_gitdir = { - interval = 1000, - follow_files = true, - }, - attach_to_untracked = true, - current_line_blame = false, - current_line_blame_opts = { - virt_text = true, - virt_text_pos = "eol", - hl_mode = "blend", - }, - current_line_blame_formatter_opts = { - relative_time = false, - }, - sign_priority = 6, - update_debounce = 100, - status_formatter = nil, - preview_config = { - border = "rounded", - style = "minimal", - relative = "cursor", - row = 0, - col = 1, - }, - yadm = { - enable = false, - }, - }) -end - -return M -EOF - - # 配置注释 - cat > ~/.config/nvim/lua/custom/plugins/comment.lua << EOF -local M = {} - -function M.setup() - require("Comment").setup({ - padding = true, - sticky = true, - ignore = nil, - toggler = { - line = "gcc", - block = "gbc", - }, - opleader = { - line = "gc", - block = "gb", - }, - extra = { - above = "gcO", - below = "gco", - eol = "gcA", - }, - mappings = { - basic = true, - extra = true, - extended = false, - }, - pre_hook = nil, - post_hook = nil, - }) -end - -return M -EOF - - # 配置自动配对 - cat > ~/.config/nvim/lua/custom/plugins/autopairs.lua << EOF -local M = {} - -function M.setup() - require("nvim-autopairs").setup({ - check_ts = true, - disable_filetype = { "TelescopePrompt", "spectre_panel" }, - fast_wrap = { - map = "", - chars = { "{", "[", "(", '"', "'" }, - pattern = string.gsub([[ [%'%"%)%>%]%)%}%,] ]]], "%s+", ""), - offset = 0, - end_key = "$", - keys = "qwertyuiopzxcvbnmasdfghjkl", - check_comma = true, - highlight = "PmenuSel", - highlight_grey = "LineNr", - }, - }) -end - -return M -EOF - - # 配置代码片段 - cat > ~/.config/nvim/lua/custom/plugins/luasnip.lua << EOF -local M = {} - -function M.setup() - require("luasnip").setup({ - region_check_events = "CursorMoved,InsertEnter", - delete_check_events = "TextChanged,InsertLeave", - }) -end - -return M -EOF - - # 配置格式化 - cat > ~/.config/nvim/lua/custom/plugins/null-ls.lua << EOF -local M = {} - -function M.setup() - local null_ls = require("null-ls") - - null_ls.setup({ - sources = { - null_ls.builtins.formatting.prettier, - null_ls.builtins.formatting.stylua, - null_ls.builtins.formatting.black, - null_ls.builtins.formatting.isort, - null_ls.builtins.formatting.gofmt, - null_ls.builtins.formatting.rustfmt, - null_ls.builtins.diagnostics.eslint_d, - null_ls.builtins.diagnostics.flake8, - null_ls.builtins.diagnostics.mypy, - null_ls.builtins.diagnostics.golangci_lint, - null_ls.builtins.diagnostics.rustc, - }, - on_attach = function(client, bufnr) - if client.supports_method("textDocument/formatting") then - vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr }) - vim.api.nvim_create_autocmd("BufWritePre", { - group = augroup, - buffer = bufnr, - callback = function() - vim.lsp.buf.format({ bufnr = bufnr }) - end, - }) - end - end, - }) -end - -return M -EOF + # 安装基础依赖 + local dependencies=( + "git" + "ripgrep" + "gcc" + "make" + ) + + for dep in "${dependencies[@]}"; do + if ! command -v $dep &> /dev/null; then + log_info "安装 $dep..." + apt-get install -y $dep + else + log_info "$dep 已安装" + fi + done } # 主函数 main() { - log_info "开始配置NvChad..." + # 检查root权限 + check_root + + # 获取用户信息 + get_user_info + + # 检查neovim版本 + check_neovim + + # 检查并安装依赖 + install_base_dependencies # 备份现有配置 backup_config @@ -783,9 +389,13 @@ main() { # 配置NvChad configure_nvchad - log_info "NvChad配置完成!" - log_info "请运行 nvim 来启动编辑器。" - log_info "首次启动时会自动安装插件。" + log_success "NvChad安装完成!" + log_info "请按照以下步骤完成配置:" + log_info "1. 运行 nvim 启动编辑器" + log_info "2. 等待 lazy.nvim 完成插件下载" + log_info "3. 运行 :MasonInstallAll 命令安装所有工具" + log_info "4. 使用 :h nvui 学习 UI 和 base46 的自定义配置" + log_info "5. 确保终端字体设置为 'JetBrainsMono Nerd Font'(不要选择带Mono后缀的版本)" } # 执行主函数 diff --git a/scripts/php/dnmp.sh b/scripts/php/dnmp.sh index 36f7858..26eebe3 100644 --- a/scripts/php/dnmp.sh +++ b/scripts/php/dnmp.sh @@ -1,60 +1,52 @@ #!/bin/bash -# 设置错误时立即退出 -set -e +# 导入通用函数 +source "$(dirname "$0")/../utils/common.sh" -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color +# 检查root权限 +check_root -# 日志函数 -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" +# 检查Docker是否已安装 +check_docker() { + if ! command -v docker &> /dev/null; then + log_info "Docker未安装,正在安装..." + install_docker + else + log_info "Docker已安装" + fi } -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# 安装Docker和Docker Compose +# 安装Docker install_docker() { - log_info "安装Docker和Docker Compose..." - - # 安装Docker + log_info "安装Docker..." curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh rm get-docker.sh - # 安装Docker Compose - sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - sudo chmod +x /usr/local/bin/docker-compose - # 将当前用户添加到docker组 sudo usermod -aG docker $USER - log_info "Docker和Docker Compose安装完成" + log_info "Docker安装完成" } # 克隆DNMP仓库 clone_dnmp() { log_info "克隆DNMP仓库..." - # 创建项目目录 - mkdir -p ~/projects - cd ~/projects + # 创建安装目录 + sudo mkdir -p /opt/dnmp + + # 如果目录已存在且不为空,则清理 + if [ -d "/opt/dnmp" ] && [ "$(ls -A /opt/dnmp)" ]; then + log_info "清理已存在的DNMP目录..." + sudo rm -rf /opt/dnmp/* + fi # 克隆DNMP仓库 - git clone https://github.com/yeszao/dnmp.git - cd dnmp + sudo git clone https://github.com/garymengcom/dnmp.git /opt/dnmp - # 复制环境配置文件 - cp env.sample .env + # 设置目录权限 + sudo chown -R $USER:$USER /opt/dnmp log_info "DNMP仓库克隆完成" } @@ -63,7 +55,11 @@ clone_dnmp() { configure_dnmp() { log_info "配置DNMP..." - cd ~/projects/dnmp + cd /opt/dnmp + + # 复制配置文件 + cp docker-compose.sample.yml docker-compose.yml + cp env.sample .env # 修改.env文件 sed -i 's/PHP_VERSION=7.4/PHP_VERSION=8.2/' .env @@ -86,7 +82,7 @@ EOF start_dnmp() { log_info "启动DNMP..." - cd ~/projects/dnmp + cd /opt/dnmp # 启动服务 docker-compose up -d @@ -100,37 +96,36 @@ start_dnmp() { log_info "DNMP启动完成" } -# 配置PHP开发环境 -configure_php_dev() { - log_info "配置PHP开发环境..." +# 创建别名文件 +create_alias_file() { + log_info "创建命令别名文件..." - # 安装Composer - curl -sS https://getcomposer.org/installer | php - sudo mv composer.phar /usr/local/bin/composer - - # 配置Composer镜像 - composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ - - # 安装PHP开发工具 - composer global require phpunit/phpunit - composer global require squizlabs/php_codesniffer - composer global require friendsofphp/php-cs-fixer - - # 添加Composer全局bin目录到PATH - cat >> ~/.zshrc << EOF -# Composer配置 -export PATH="\$HOME/.composer/vendor/bin:\$PATH" + cat > /opt/dnmp/bash.alias << EOF +# PHP开发环境别名 +alias dphp='docker exec -it php82 bash' +alias dcomposer='docker exec -it php82 composer' +alias dphpunit='docker exec -it php82 phpunit' +alias dphpcs='docker exec -it php82 phpcs' +alias dphpcbf='docker exec -it php82 phpcbf' EOF - log_info "PHP开发环境配置完成" + # 添加别名到用户shell配置 + if [ -f ~/.zshrc ]; then + echo "source /opt/dnmp/bash.alias" >> ~/.zshrc + elif [ -f ~/.bashrc ]; then + echo "source /opt/dnmp/bash.alias" >> ~/.bashrc + fi + + log_info "命令别名文件创建完成" + log_info "请运行 'source ~/.zshrc' 或 'source ~/.bashrc' 使别名生效" } # 主函数 main() { log_info "开始安装PHP开发环境..." - # 安装Docker和Docker Compose - install_docker + # 检查并安装Docker + check_docker # 克隆DNMP仓库 clone_dnmp @@ -141,14 +136,20 @@ main() { # 启动DNMP start_dnmp - # 配置PHP开发环境 - configure_php_dev + # 创建别名文件 + create_alias_file - log_info "PHP开发环境安装完成!" - log_info "请运行 'source ~/.zshrc' 或重新打开终端以使环境变量生效。" + log_info "PHP环境安装完成!" log_info "访问 http://localhost 查看PHP信息页面。" log_info "默认MySQL密码:123456" log_info "默认Redis密码:123456" + log_info "DNMP安装目录:/opt/dnmp" + log_info "" + log_info "如需手动安装Composer,请执行以下步骤:" + log_info "1. 进入PHP容器: dphp" + log_info "2. 下载Composer: curl -sS https://getcomposer.org/installer | php" + log_info "3. 安装Composer: mv composer.phar /usr/local/bin/composer" + log_info "4. 配置镜像: composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/" } # 执行主函数 diff --git a/scripts/shell/README.md b/scripts/shell/README.md new file mode 100644 index 0000000..e329eab --- /dev/null +++ b/scripts/shell/README.md @@ -0,0 +1,98 @@ +# Shell 环境配置脚本 + +本目录包含用于配置和管理Shell环境的脚本集合。这些脚本主要用于设置Zsh环境、安装插件、配置系统环境变量等。 + +## 目录结构 + +``` +shell/ +├── README.md # 本文档 +├── zsh.sh # Zsh环境配置脚本 +├── plugins.sh # Zsh插件管理脚本 +└── config.sh # 环境变量和别名配置脚本 +``` + +## 脚本说明 + +### zsh.sh + +Zsh环境配置脚本,用于安装和配置Zsh环境。 + +#### 功能 +- 安装Zsh和Oh My Zsh +- 安装Powerlevel10k主题 +- 安装Nerd Fonts字体 +- 配置基础Zsh设置 + +#### 使用方法 +```bash +sudo ./zsh.sh +``` + +### plugins.sh + +Zsh插件管理脚本,用于安装和管理各种Zsh插件。 + +#### 功能 +- 安装autojump(快速目录跳转) +- 安装fzf(模糊查找) +- 安装zsh-nvm(Node.js版本管理) +- 安装pyenv(Python版本管理) +- 配置插件相关设置 + +#### 使用方法 +```bash +sudo ./plugins.sh +``` + +### config.sh + +环境变量和别名配置脚本,用于设置系统环境变量和常用命令别名。 + +#### 功能 +- 配置系统环境变量 +- 设置常用命令别名 +- 配置终端显示 +- 设置历史记录 +- 配置目录栈 +- 设置终端标题 + +#### 使用方法 +```bash +sudo ./config.sh +``` + +## 依赖要求 + +- Debian/Ubuntu系统 +- sudo权限 +- 网络连接(用于下载插件和主题) + +## 安装顺序 + +1. 首先运行 `zsh.sh` 安装基础Zsh环境 +2. 重新打开终端或运行 `source ~/.zshrc` +3. 运行 `plugins.sh` 安装插件 +4. 运行 `config.sh` 配置环境变量和别名 + +## 注意事项 + +- 所有脚本需要sudo权限运行 +- 安装过程中需要网络连接 +- 如果遇到网络问题,脚本会自动尝试使用镜像源 +- 所有操作都有日志记录,保存在 `~/.logs` 目录下 + +## 常见问题 + +1. 如果安装过程中断,可以重新运行相应的脚本 +2. 如果遇到权限问题,确保使用sudo运行脚本 +3. 如果插件安装失败,检查网络连接并重试 +4. 如果配置不生效,运行 `source ~/.zshrc` 重新加载配置 + +## 更新日志 + +### v1.0.0 (2024-03-xx) +- 初始版本发布 +- 完成基础Zsh环境配置 +- 实现插件管理系统 +- 添加环境变量配置 \ No newline at end of file diff --git a/scripts/shell/plugins.sh b/scripts/shell/plugins.sh index 3dc4864..a17f80c 100644 --- a/scripts/shell/plugins.sh +++ b/scripts/shell/plugins.sh @@ -1,5 +1,8 @@ #!/bin/bash +# 导入公共函数 +source "$(dirname "$0")/../utils/common.sh" + # 设置错误时立即退出 set -e @@ -22,114 +25,164 @@ log_error() { echo -e "${RED}[ERROR]${NC} $1" } -# 安装zsh-autosuggestions -install_zsh_autosuggestions() { - log_info "安装zsh-autosuggestions..." - git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions -} +# 检查是否为root用户 +if [ "$EUID" -ne 0 ]; then + log_error "请使用root权限运行此脚本" + exit 1 +fi -# 安装zsh-syntax-highlighting -install_zsh_syntax_highlighting() { - log_info "安装zsh-syntax-highlighting..." - git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting -} +# 获取当前用户名 +CURRENT_USER=$SUDO_USER +if [ -z "$CURRENT_USER" ]; then + CURRENT_USER=$(who | awk '{print $1}' | head -n1) +fi -# 安装zsh-completions -install_zsh_completions() { - log_info "安装zsh-completions..." - git clone https://github.com/zsh-users/zsh-completions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-completions +# 设置用户主目录 +USER_HOME="/home/$CURRENT_USER" +ZSH_CUSTOM="${USER_HOME}/.oh-my-zsh/custom" + +# 检查 Oh My Zsh 是否已安装 +check_oh_my_zsh() { + if [ ! -d "${USER_HOME}/.oh-my-zsh" ]; then + log_error "Oh My Zsh 未安装,请先运行 zsh.sh" + exit 1 + fi } # 安装autojump install_autojump() { - log_info "安装autojump..." - apt-get install -y autojump + show_progress "安装 autojump" + ensure_package "autojump" + + # 确保 autojump 数据目录存在 + ensure_dir "/usr/share/autojump" "root:root" + ensure_dir "${USER_HOME}/.local/share/autojump" "$CURRENT_USER:$CURRENT_USER" + + update_progress "安装 autojump" "完成" } # 安装fzf install_fzf() { - log_info "安装fzf..." - apt-get install -y fzf + show_progress "安装 fzf" + ensure_package "fzf" + update_progress "安装 fzf" "完成" } # 安装zsh-nvm install_zsh_nvm() { - log_info "安装zsh-nvm..." - git clone https://github.com/lukechilds/zsh-nvm ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-nvm + show_progress "安装 zsh-nvm" + local nvm_dir="${ZSH_CUSTOM}/plugins/zsh-nvm" + local nvm_url="https://github.com/lukechilds/zsh-nvm" + + manage_plugin "zsh-nvm" "$nvm_dir" "$nvm_url" } # 安装pyenv install_pyenv() { - log_info "安装pyenv..." - curl https://pyenv.run | bash + show_progress "安装 pyenv" + if [ ! -d "${USER_HOME}/.pyenv" ]; then + local install_url="https://pyenv.run" + local temp_script="/tmp/pyenv_installer.sh" + + if download_file "$install_url" "$temp_script"; then + su - $CURRENT_USER -c "bash $temp_script" + rm -f "$temp_script" + update_progress "安装 pyenv" "完成" + else + update_progress "安装 pyenv" "失败" + return 1 + fi + else + update_progress "安装 pyenv" "已存在" + fi } -# 配置fzf -configure_fzf() { - log_info "配置fzf..." +# 配置插件 +configure_plugins() { + show_progress "配置插件" - # 安装fzf键绑定和补全 - $(brew --prefix)/opt/fzf/install --all + # 备份现有配置 + manage_config "backup" "${USER_HOME}/.zshrc" - # 添加fzf配置到.zshrc - cat >> ~/.zshrc << EOF + # 添加 autojump 配置 + cat >> "${USER_HOME}/.zshrc" << 'EOF' + +# autojump配置 +if [ -f /usr/share/autojump/autojump.zsh ]; then + . /usr/share/autojump/autojump.zsh +fi +EOF + + # 添加 fzf 配置 + cat >> "${USER_HOME}/.zshrc" << 'EOF' # fzf配置 +if [ -f ~/.fzf.zsh ]; then + source ~/.fzf.zsh +fi export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border' -export FZF_DEFAULT_COMMAND='fd --type f' -export FZF_CTRL_T_COMMAND='\$FZF_DEFAULT_COMMAND' -export FZF_CTRL_T_OPTS="--preview 'bat --color=always --line-range=:500 {}'" +export FZF_DEFAULT_COMMAND='find . -type f' +export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" +export FZF_CTRL_T_OPTS="--preview 'cat {}'" export FZF_CTRL_R_OPTS="--preview 'echo {}' --preview-window down:3:hidden:wrap --bind '?:toggle-preview'" export FZF_ALT_C_OPTS="--preview 'tree -C {} | head -200'" EOF -} -# 配置pyenv -configure_pyenv() { - log_info "配置pyenv..." - - # 添加pyenv配置到.zshrc - cat >> ~/.zshrc << EOF + # 添加 pyenv 配置 + cat >> "${USER_HOME}/.zshrc" << 'EOF' # pyenv配置 -export PYENV_ROOT="\$HOME/.pyenv" -command -v pyenv >/dev/null || export PATH="\$PYENV_ROOT/bin:\$PATH" -eval "\$(pyenv init -)" +export PYENV_ROOT="$HOME/.pyenv" +command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH" +eval "$(pyenv init -)" EOF -} -# 配置autojump -configure_autojump() { - log_info "配置autojump..." + # 更新插件列表 + local zshrc="${USER_HOME}/.zshrc" + sed -i '/^plugins=(/,/^)/ c\plugins=(\n git\n docker\n docker-compose\n npm\n node\n python\n pip\n zsh-autosuggestions\n zsh-syntax-highlighting\n autojump\n fzf\n zsh-nvm\n)' "$zshrc" - # 添加autojump配置到.zshrc - cat >> ~/.zshrc << EOF - -# autojump配置 -. /usr/share/autojump/autojump.sh -EOF + update_progress "配置插件" "完成" } # 主函数 main() { - log_info "开始安装Zsh插件..." + # 检查root权限 + check_root + + # 获取用户信息 + get_user_info + + # 设置日志 + setup_logging + + # 设置 ZSH_CUSTOM 变量 + ZSH_CUSTOM="${USER_HOME}/.oh-my-zsh/custom" + + # 检查 Oh My Zsh + check_oh_my_zsh + + # 检查依赖 + check_dependencies "git" "curl" "wget" "zsh" "sudo" # 安装插件 - install_zsh_autosuggestions - install_zsh_syntax_highlighting - install_zsh_completions install_autojump install_fzf install_zsh_nvm install_pyenv # 配置插件 - configure_fzf - configure_pyenv - configure_autojump + configure_plugins - log_info "Zsh插件安装完成!" - log_info "请重新加载.zshrc以应用更改:source ~/.zshrc" + # 设置权限 + show_progress "设置权限" + chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.oh-my-zsh + chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.zshrc + chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.pyenv + update_progress "设置权限" "完成" + + log_success "Zsh插件安装完成!" + log_info "请运行以下命令使配置生效:" + log_info "source ~/.zshrc" } # 执行主函数 diff --git a/scripts/shell/zsh.sh b/scripts/shell/zsh.sh index bcd7dab..9546f53 100644 --- a/scripts/shell/zsh.sh +++ b/scripts/shell/zsh.sh @@ -1,84 +1,91 @@ #!/bin/bash -# 设置错误时立即退出 -set -e - -# 日志函数 -log_info() { - echo "[INFO] $1" -} - -log_warn() { - echo "[WARN] $1" -} - -log_error() { - echo "[ERROR] $1" -} - -# 检查是否为root用户 -if [ "$EUID" -ne 0 ]; then - log_error "请使用root权限运行此脚本" - exit 1 -fi - -# 获取当前用户名 -CURRENT_USER=$SUDO_USER -if [ -z "$CURRENT_USER" ]; then - CURRENT_USER=$(who | awk '{print $1}' | head -n1) -fi - -# 设置用户主目录 -USER_HOME="/home/$CURRENT_USER" - -# 更新系统包 -log_info "更新系统包..." -apt-get update -apt-get upgrade -y - -# 安装必要的依赖 -log_info "安装必要的依赖..." -apt-get install -y \ - git \ - curl \ - wget \ - build-essential \ - zsh \ - sudo \ - fontconfig +# 导入公共函数 +source "$(dirname "$0")/../utils/common.sh" # 安装 Oh My Zsh -log_info "安装 Oh My Zsh..." -# 删除已存在的 Oh My Zsh 目录 -if [ -d "${USER_HOME}/.oh-my-zsh" ]; then - log_info "删除已存在的 Oh My Zsh 目录..." - rm -rf ${USER_HOME}/.oh-my-zsh -fi +install_oh_my_zsh() { + show_progress "安装 Oh My Zsh" + + # 删除已存在的 Oh My Zsh 目录 + if [ -d "${USER_HOME}/.oh-my-zsh" ]; then + if confirm "检测到已存在的 Oh My Zsh 安装,是否重新安装?"; then + log_info "删除已存在的 Oh My Zsh 目录..." + rm -rf ${USER_HOME}/.oh-my-zsh + else + update_progress "安装 Oh My Zsh" "已跳过" + return 0 + fi + fi + + # 获取安装脚本URL(可能使用镜像) + local install_url="https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh" + local mirror_url=$(get_mirror_url "$install_url" "omz") + + # 安装 Oh My Zsh + su - $CURRENT_USER -c "curl -fsSL $mirror_url | sh -s -- --unattended" + + # 设置 zsh 为默认 shell + show_progress "设置 zsh 为默认 shell" + chsh -s $(which zsh) $CURRENT_USER + update_progress "设置 zsh 为默认 shell" "完成" +} -# 切换到用户目录 -cd ${USER_HOME} +# 安装主题和字体 +install_theme_and_fonts() { + show_progress "安装 Powerlevel10k 主题" + + local theme_url="https://github.com/romkatv/powerlevel10k.git" + local theme_dir="${USER_HOME}/.oh-my-zsh/custom/themes/powerlevel10k" + + manage_plugin "powerlevel10k" "$theme_dir" "$theme_url" + + # 安装 MesloLGS NF 字体 + local font_urls=( + "https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttf" + "https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold.ttf" + "https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Italic.ttf" + "https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold%20Italic.ttf" + ) + + show_progress "安装字体" + for url in "${font_urls[@]}"; do + local font_name=$(basename "$url" | sed 's/%20/ /g') + install_font "$url" "$font_name" + done + update_progress "安装字体" "完成" +} -# 安装 Oh My Zsh -su - $CURRENT_USER -c 'sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended' +# 安装基础插件 +install_base_plugins() { + show_progress "安装基础插件" + local plugins_dir="${USER_HOME}/.oh-my-zsh/custom/plugins" + + # 定义插件 + local plugins=( + "zsh-autosuggestions:https://github.com/zsh-users/zsh-autosuggestions" + "zsh-syntax-highlighting:https://github.com/zsh-users/zsh-syntax-highlighting.git" + ) + + # 安装每个插件 + for plugin in "${plugins[@]}"; do + local name="${plugin%%:*}" + local url="${plugin#*:}" + manage_plugin "$name" "${plugins_dir}/${name}" "$url" + done + + update_progress "安装基础插件" "完成" +} -# 设置 zsh 为默认 shell -log_info "设置 zsh 为默认 shell..." -chsh -s $(which zsh) $CURRENT_USER - -# 安装常用插件 -log_info "安装常用插件..." -su - $CURRENT_USER -c "git clone https://github.com/zsh-users/zsh-autosuggestions ${USER_HOME}/.oh-my-zsh/custom/plugins/zsh-autosuggestions" -su - $CURRENT_USER -c "git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${USER_HOME}/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting" - -# 配置 .zshrc -log_info "配置 .zshrc..." -# 备份现有的 .zshrc 文件 -if [ -f "${USER_HOME}/.zshrc" ]; then - log_info "备份现有的 .zshrc 文件..." - mv ${USER_HOME}/.zshrc ${USER_HOME}/.zshrc.backup -fi - -cat > ${USER_HOME}/.zshrc << 'EOL' +# 配置 Zsh +configure_zsh() { + show_progress "配置 Zsh" + + # 备份现有配置 + manage_config "backup" "${USER_HOME}/.zshrc" + + # 创建新的配置文件 + cat > ${USER_HOME}/.zshrc << 'EOL' # Enable Powerlevel10k instant prompt if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" @@ -108,8 +115,6 @@ source $ZSH/oh-my-zsh.sh # User configuration export LANG=en_US.UTF-8 -export EDITOR='vim' -export VISUAL='vim' # 设置自动补全快捷键为逗号 bindkey ',' autosuggest-accept @@ -132,61 +137,79 @@ autoload -Uz compinit && compinit zstyle ':completion:*' menu select zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' -# Aliases -alias ll='ls -la' -alias ..='cd ..' -alias ...='cd ../..' -alias ....='cd ../../..' -alias grep='grep --color=auto' -alias mkdir='mkdir -pv' -alias wget='wget -c' -alias hist='history | grep' -alias ports='netstat -tulanp' -alias path='echo -e ${PATH//:/\\n}' -alias now='date +"%T"' -alias nowdate='date +"%d-%m-%Y"' -alias update='sudo apt-get update' -alias upgrade='sudo apt-get upgrade' -alias meminfo='free -m -l -t' -alias psmem='ps auxf | sort -nr -k 4' -alias pscpu='ps auxf | sort -nr -k 3' -alias wget='wget -c' -alias getpass="openssl rand -base64 20" -alias sha1='openssl sha1' -alias ping='ping -c 5' -alias mkdir='mkdir -pv' -alias diff='colordiff' -alias mount='mount |column -t' -alias h='history' -alias j='jobs -l' -alias vi=vim -alias svi='sudo vim' -alias vis='vim "+set si"' -alias edit='vim' - # To customize prompt, run `p10k configure` or edit ~/.p10k.zsh. [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh EOL -# 安装 Powerlevel10k 主题 -log_info "安装 Powerlevel10k 主题..." -su - $CURRENT_USER -c "git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${USER_HOME}/.oh-my-zsh/custom/themes/powerlevel10k" + # 添加常用别名 + local aliases=( + "ll:ls -la" + "..:cd .." + "...:cd ../.." + "....:cd ../../.." + "update:sudo apt-get update" + "upgrade:sudo apt-get upgrade" + "vi:nvim" + "vim:nvim" + "edit:nvim" + ) + + for alias_pair in "${aliases[@]}"; do + local name="${alias_pair%%:*}" + local value="${alias_pair#*:}" + add_alias "$name" "$value" "${USER_HOME}/.zshrc" + done + + # 设置编辑器 + add_env_var "EDITOR" "nvim" "${USER_HOME}/.zshrc" + add_env_var "VISUAL" "nvim" "${USER_HOME}/.zshrc" + + update_progress "配置 Zsh" "完成" +} -# 安装字体 -log_info "安装字体..." -su - $CURRENT_USER -c "mkdir -p ${USER_HOME}/.local/share/fonts" -su - $CURRENT_USER -c "cd ${USER_HOME}/.local/share/fonts && curl -LO https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttf" -su - $CURRENT_USER -c "cd ${USER_HOME}/.local/share/fonts && curl -LO https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold.ttf" -su - $CURRENT_USER -c "cd ${USER_HOME}/.local/share/fonts && curl -LO https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Italic.ttf" -su - $CURRENT_USER -c "cd ${USER_HOME}/.local/share/fonts && curl -LO https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold%20Italic.ttf" -su - $CURRENT_USER -c "fc-cache -f -v" +# 主函数 +main() { + # 检查root权限 + check_root + + # 获取用户信息 + get_user_info + + # 设置日志 + setup_logging + + # 检查依赖 + check_dependencies "git" "curl" "wget" "zsh" "sudo" + + # 安装基础依赖 + install_base_dependencies + + # 安装 zsh + ensure_package "zsh" + + # 安装 Oh My Zsh + install_oh_my_zsh + + # 安装主题和字体 + install_theme_and_fonts + + # 安装基础插件 + install_base_plugins + + # 配置 Zsh + configure_zsh + + # 设置权限 + show_progress "设置权限" + chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.oh-my-zsh + chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.zshrc + chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.local + update_progress "设置权限" "完成" + + log_success "Zsh 环境配置完成!" + log_info "请重新打开终端或运行 'source ~/.zshrc' 使配置生效" + log_info "首次登录后,运行 p10k configure 来配置 Powerlevel10k 主题" +} -# 设置权限 -log_info "设置权限..." -chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.oh-my-zsh -chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.zshrc -chown -R $CURRENT_USER:$CURRENT_USER ${USER_HOME}/.local - -log_info "Zsh 环境配置完成!" -log_info "请重新打开终端或运行 'source ~/.zshrc' 使配置生效" -log_info "首次登录后,运行 p10k configure 来配置 Powerlevel10k 主题" \ No newline at end of file +# 执行主函数 +main \ No newline at end of file diff --git a/scripts/system/README.md b/scripts/system/README.md new file mode 100644 index 0000000..59a88b2 --- /dev/null +++ b/scripts/system/README.md @@ -0,0 +1,119 @@ +# 系统环境检查与配置脚本 + +本目录包含用于检查和配置Windows WSL环境的脚本集合。这些脚本主要用于检查WSL环境状态、安装Debian系统等。 + +## 目录结构 + +``` +system/ +├── README.md # 本文档 +├── check-wsl.bat # Windows批处理脚本:检查WSL环境 +├── check-wsl.ps1 # PowerShell脚本:检查WSL环境 +├── install-debian.bat # Windows批处理脚本:安装Debian +├── install-debian.ps1 # PowerShell脚本:安装Debian +├── run-check-wsl-ps.bat # 运行WSL检查脚本的批处理 +└── run-install-debian-ps.bat # 运行Debian安装脚本的批处理 +``` + +## 脚本说明 + +### check-wsl.bat/ps1 + +检查Windows WSL环境的脚本。 + +#### 功能 +- 检查Windows版本 +- 检查WSL安装状态 +- 检查WSL2是否启用 +- 检查Debian安装状态 +- 检查虚拟化状态 +- 检查必要的Windows功能 + +#### 使用方法 +```batch +# 使用批处理脚本 +check-wsl.bat + +# 使用PowerShell脚本 +.\check-wsl.ps1 +``` + +### install-debian.bat/ps1 + +安装Debian系统的脚本。 + +#### 功能 +- 检查现有Debian安装 +- 提供自定义安装路径选项 +- 安装Debian系统 +- 配置WSL环境 + +#### 使用方法 +```batch +# 使用批处理脚本 +install-debian.bat + +# 使用PowerShell脚本 +.\install-debian.ps1 +``` + +### run-check-wsl-ps.bat + +运行WSL检查脚本的批处理文件。 + +#### 功能 +- 以管理员权限运行PowerShell脚本 +- 处理脚本执行结果 + +#### 使用方法 +```batch +run-check-wsl-ps.bat +``` + +### run-install-debian-ps.bat + +运行Debian安装脚本的批处理文件。 + +#### 功能 +- 以管理员权限运行PowerShell脚本 +- 处理脚本执行结果 + +#### 使用方法 +```batch +run-install-debian-ps.bat +``` + +## 依赖要求 + +- Windows 10/11 +- 管理员权限 +- PowerShell 5.1或更高版本 +- 网络连接(用于下载和安装) + +## 使用顺序 + +1. 首先运行 `check-wsl.bat` 或 `check-wsl.ps1` 检查环境 +2. 如果环境检查通过,运行 `install-debian.bat` 或 `install-debian.ps1` 安装Debian +3. 安装完成后,重启WSL或计算机 + +## 注意事项 + +- 所有脚本需要管理员权限运行 +- 安装过程中需要网络连接 +- 建议在安装前备份重要数据 +- 如果遇到问题,检查Windows更新和WSL功能是否启用 + +## 常见问题 + +1. 如果脚本无法运行,确保以管理员身份运行 +2. 如果WSL2未启用,按照提示启用WSL2 +3. 如果安装失败,检查网络连接和系统要求 +4. 如果遇到权限问题,确保使用管理员权限运行 + +## 更新日志 + +### v1.0.0 (2024-03-xx) +- 初始版本发布 +- 完成WSL环境检查功能 +- 实现Debian安装功能 +- 添加批处理和PowerShell脚本支持 \ No newline at end of file diff --git a/scripts/system/check_windows_wsl.bat b/scripts/system/check-wsl.bat similarity index 56% rename from scripts/system/check_windows_wsl.bat rename to scripts/system/check-wsl.bat index 39f6e5f..ef22806 100644 --- a/scripts/system/check_windows_wsl.bat +++ b/scripts/system/check-wsl.bat @@ -12,82 +12,84 @@ if %errorlevel% neq 0 ( ) echo. -echo [INFO] 开始检查 WSL2 环境... +echo INFO: 开始检查 WSL2 环境... echo. :: Check Windows version -echo [INFO] 检查 Windows 版本... +echo INFO: 检查 Windows 版本... for /f "tokens=*" %%a in ('ver') do set "windows_version=%%a" echo Windows 版本: !windows_version! :: Check WSL installation -echo [INFO] 检查 WSL 安装状态... +echo INFO: 检查 WSL 安装状态... wsl --version >nul 2>&1 if %errorlevel% equ 0 ( - echo [INFO] WSL 已安装 + echo INFO: WSL 已安装 + echo. wsl --version + echo. ) else ( - echo [ERROR] WSL 未安装 - echo [INFO] 请访问 https://aka.ms/wsl 安装 WSL + echo ERROR: WSL 未安装 + echo INFO: 请访问 https://aka.ms/wsl 安装 WSL goto :error ) :: Check WSL2 status -echo [INFO] 检查 WSL2 状态... +echo INFO: 检查 WSL2 状态... wsl -l -v > temp.txt - findstr /i "2" temp.txt >nul if %errorlevel% equ 0 ( - echo [INFO] WSL2 已启用 - echo [INFO] WSL 发行版列表: - type temp.txt + echo INFO: WSL2 已启用 ) else ( - echo [WARN] WSL2 未启用 - echo [INFO] 请运行以下命令启用 WSL2: + echo WARN: WSL2 未启用 + echo INFO: WSL 发行版列表: + echo. + wsl -l -v + echo. + echo INFO: 请运行以下命令启用 WSL2: echo wsl --set-default-version 2 goto :error ) -del temp.txt :: Check Debian installation -echo [INFO] 检查 Debian 安装状态... +echo INFO: 检查 Debian 安装状态... wsl -d Debian echo "Debian is installed" >nul 2>&1 if %errorlevel% equ 0 ( - echo [INFO] Debian 已安装 + echo INFO: Debian 已安装 ) else ( - echo [WARN] Debian 未安装 - echo [INFO] 请运行以下命令安装 Debian: + echo WARN: Debian 未安装 + echo INFO: 请运行以下命令安装 Debian: echo wsl --install -d Debian goto :error ) :: Check virtualization -echo [INFO] 检查虚拟化状态... +echo INFO: 检查虚拟化状态... systeminfo | findstr /i "Hyper-V" > temp.txt findstr /i "Virtual Ethernet Adapter" temp.txt >nul if %errorlevel% equ 0 ( - echo [INFO] 虚拟化已启用 + echo INFO: 虚拟化已启用 ) else ( findstr /i "hypervisor has been detected" temp.txt >nul if %errorlevel% equ 0 ( - echo [INFO] 虚拟化已启用 + echo INFO: 虚拟化已启用 ) else ( - echo [ERROR] 虚拟化未启用 - echo [INFO] 请在 BIOS 中启用虚拟化 (Intel VT-x 或 AMD-V) + echo ERROR: 虚拟化未启用 + echo INFO: 请在 BIOS 中启用虚拟化 (Intel VT-x 或 AMD-V) goto :error ) ) del temp.txt :: Check Windows features -echo [INFO] 检查 Windows 功能... +echo INFO: 检查 Windows 功能... dism /online /get-featureinfo /featurename:Microsoft-Windows-Subsystem-Linux > temp.txt findstr /i "状态.*已启用" temp.txt >nul if %errorlevel% equ 0 ( - echo [INFO] Linux 子系统已启用 + echo INFO: Linux 子系统已启用 ) else ( - echo [WARN] Linux 子系统未启用 - echo [INFO] 请运行以下命令启用 Linux 子系统: + echo WARN: Linux 子系统未启用 + echo INFO: 请运行以下命令启用 Linux 子系统: echo dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart goto :error ) @@ -95,10 +97,10 @@ if %errorlevel% equ 0 ( dism /online /get-featureinfo /featurename:VirtualMachinePlatform > temp.txt findstr /i "状态.*已启用" temp.txt >nul if %errorlevel% equ 0 ( - echo [INFO] 虚拟机平台已启用 + echo INFO: 虚拟机平台已启用 ) else ( - echo [WARN] 虚拟机平台未启用 - echo [INFO] 请运行以下命令启用虚拟机平台: + echo WARN: 虚拟机平台未启用 + echo INFO: 请运行以下命令启用虚拟机平台: echo dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart goto :error ) @@ -109,24 +111,25 @@ echo ============================================ echo 检查完成!环境已就绪 echo ============================================ echo. -echo [INFO] 您的 WSL2 环境已经准备就绪: -echo [INFO] 1. Windows 版本符合要求 -echo [INFO] 2. WSL2 已正确安装并启用 -echo [INFO] 3. Debian 发行版已安装 -echo [INFO] 4. 虚拟化功能已启用 -echo [INFO] 5. 所需的 Windows 功能已启用 +echo INFO: 您的 WSL2 环境已经准备就绪: echo. -echo [INFO] 您现在可以开始使用 WSL2 环境了! +echo INFO: 1. Windows 版本符合要求 +echo INFO: 2. WSL2 已正确安装并启用 +echo INFO: 3. Debian 发行版已安装 +echo INFO: 4. 虚拟化功能已启用 +echo INFO: 5. 所需的 Windows 功能已启用 +echo. +echo INFO: 您现在可以开始使用 WSL2 环境了! echo ============================================ echo. -echo [INFO] 按任意键退出... +echo INFO: 按任意键退出... pause >nul goto :eof :error echo. -echo [WARN] 检查未通过,请按照提示解决问题 -echo [INFO] 按任意键退出... +echo WARN: 检查未通过,请按照提示解决问题 +echo INFO: 按任意键退出... pause >nul exit /b 1 diff --git a/scripts/system/check-wsl.ps1 b/scripts/system/check-wsl.ps1 new file mode 100644 index 0000000..35da247 --- /dev/null +++ b/scripts/system/check-wsl.ps1 @@ -0,0 +1,187 @@ +# WSL2 Environment Check Script +# This script checks WSL2 installation status on Windows + +# Set error action +$ErrorActionPreference = 'Stop' + +# Color definitions +$Red = [System.ConsoleColor]::Red +$Green = [System.ConsoleColor]::Green +$Yellow = [System.ConsoleColor]::Yellow + +# Logging functions +function Write-Info { + param([string]$Message) + Write-Host '[INFO] ' -NoNewline -ForegroundColor $Green + Write-Host $Message +} + +function Write-Warn { + param([string]$Message) + Write-Host '[WARN] ' -NoNewline -ForegroundColor $Yellow + Write-Host $Message +} + +function Write-Error { + param([string]$Message) + Write-Host '[ERROR] ' -NoNewline -ForegroundColor $Red + Write-Host $Message +} + +function Wait-KeyPress { + Write-Host "`nPress any key to exit..." -NoNewline + $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') + Write-Host '' +} + +# Check administrator privileges +if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { + Write-Warn 'Administrator privileges required' + Write-Info 'Please right-click this script and select "Run as Administrator"' + Wait-KeyPress + exit 1 +} + +Write-Info "`nStarting WSL2 environment check...`n" + +# Check Windows version +Write-Info 'Checking Windows version...' +$windowsVersion = (Get-WmiObject Win32_OperatingSystem).Caption +Write-Host "Windows Version: $windowsVersion" + +# Check WSL installation status +Write-Info 'Checking WSL installation...' +try { + $wslVersion = wsl --version + Write-Info 'WSL is installed' + Write-Host "`n$wslVersion`n" +} catch { + Write-Error 'WSL is not installed' + Write-Info 'Please visit https://aka.ms/wsl to install WSL' + Wait-KeyPress + exit 1 +} finally { + # Clear errors + $error.clear() +} + +# Check WSL2 status +Write-Info 'Checking WSL2 status...' +try { + $wslList = wsl -l -v + if ($wslList -match '2') { + Write-Info 'WSL2 is enabled' + } else { + Write-Warn 'WSL2 is not enabled' + Write-Info 'WSL distribution list:' + Write-Host "`n$wslList`n" + Write-Info 'Please run the following command to enable WSL2:' + Write-Host 'wsl --set-default-version 2' + Wait-KeyPress + exit 1 + } +} catch { + Write-Error "Failed to get WSL status: $($_.Exception.Message)" + Wait-KeyPress + exit 1 +} finally { + # Clear errors + $error.clear() +} + +# Check Debian installation status +Write-Info 'Checking Debian installation...' +try { + wsl -d Debian echo 'Debian is installed' | Out-Null + Write-Info 'Debian is installed' +} catch { + Write-Warn 'Debian is not installed' + Write-Info 'Please run the following command to install Debian:' + Write-Host 'wsl --install -d Debian' + Wait-KeyPress + exit 1 +} finally { + # Clear errors + $error.clear() +} + +# Check virtualization status +Write-Info 'Checking virtualization status...' +try { + $systemInfo = systeminfo + if ($systemInfo -match 'Virtual Ethernet Adapter' -or $systemInfo -match 'hypervisor has been detected') { + Write-Info 'Virtualization is enabled' + } else { + Write-Error 'Virtualization is not enabled' + Write-Info 'Please enable virtualization (Intel VT-x or AMD-V) in BIOS' + Wait-KeyPress + exit 1 + } +} catch { + Write-Error "Failed to check virtualization status: $($_.Exception.Message)" + Wait-KeyPress + exit 1 +} finally { + # Clear errors + $error.clear() +} + +# Check Windows features +Write-Info 'Checking Windows features...' + +# Check Linux subsystem +try { + $wslFeature = Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux + if ($wslFeature.State -eq 'Enabled') { + Write-Info 'Linux subsystem is enabled' + } else { + Write-Warn 'Linux subsystem is not enabled' + Write-Info 'Please run the following command to enable Linux subsystem:' + Write-Host 'dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart' + Wait-KeyPress + exit 1 + } +} catch { + Write-Error "Failed to check Linux subsystem status: $($_.Exception.Message)" + Wait-KeyPress + exit 1 +} finally { + # Clear errors + $error.clear() +} + +# Check virtual machine platform +try { + $vmPlatform = Get-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform + if ($vmPlatform.State -eq 'Enabled') { + Write-Info 'Virtual Machine Platform is enabled' + } else { + Write-Warn 'Virtual Machine Platform is not enabled' + Write-Info 'Please run the following command to enable Virtual Machine Platform:' + Write-Host 'dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart' + Wait-KeyPress + exit 1 + } +} catch { + Write-Error "Failed to check Virtual Machine Platform status: $($_.Exception.Message)" + Wait-KeyPress + exit 1 +} finally { + # Clear errors + $error.clear() +} + +Write-Host "`n============================================" +Write-Host " Check Complete! " +Write-Host "============================================" +Write-Host "`nYour WSL2 environment is ready:`n" +Write-Info '1. Windows version is compatible' +Write-Info '2. WSL2 is installed and enabled' +Write-Info '3. Debian distribution is installed' +Write-Info '4. Virtualization is enabled' +Write-Info '5. Required Windows features are enabled' +Write-Info 'You can now start using WSL2!' +Write-Host "============================================" + +# Wait for user input before exit +Wait-KeyPress diff --git a/scripts/system/check_windows_wsl.ps1 b/scripts/system/check_windows_wsl.ps1 deleted file mode 100644 index 7dd45f9..0000000 --- a/scripts/system/check_windows_wsl.ps1 +++ /dev/null @@ -1,192 +0,0 @@ -# WSL2 环境检查脚本 -# 此脚本用于检查 Windows 系统上的 WSL2 安装状态 - -# 设置错误操作 -$ErrorActionPreference = "Stop" - -# 颜色定义 -$Red = [System.ConsoleColor]::Red -$Green = [System.ConsoleColor]::Green -$Yellow = [System.ConsoleColor]::Yellow - -# 日志函数 -function Write-Info { - param([string]$Message) - Write-Host "[INFO] $Message" -ForegroundColor $Green -} - -function Write-Warn { - param([string]$Message) - Write-Host "[WARN] $Message" -ForegroundColor $Yellow -} - -function Write-Error { - param([string]$Message) - Write-Host "[ERROR] $Message" -ForegroundColor $Red -} - -# 检查 Windows 版本 -function Test-WindowsVersion { - Write-Info "检查 Windows 版本..." - - $os = Get-WmiObject -Class Win32_OperatingSystem - $version = [System.Environment]::OSVersion.Version - - Write-Info "Windows 版本: $($os.Caption)" - Write-Info "系统版本号: $($version.Major).$($version.Minor).$($version.Build)" - - if ($version.Major -lt 10 -or ($version.Major -eq 10 -and $version.Build -lt 19041)) { - Write-Error "Windows 版本不满足 WSL2 要求,需要 Windows 10 版本 2004 或更高版本" - return $false - } - - return $true -} - -# 检查 WSL 是否安装 -function Test-WSLInstallation { - Write-Info "检查 WSL 安装状态..." - - try { - $wslVersion = wsl --version 2>$null - if ($LASTEXITCODE -eq 0) { - Write-Info "WSL 已安装" - Write-Info "WSL 版本信息:" - Write-Host $wslVersion - return $true - } - } - catch { - Write-Error "WSL 未安装" - Write-Info "请访问 https://aka.ms/wsl 安装 WSL" - return $false - } -} - -# 检查 WSL2 是否启用 -function Test-WSL2Enabled { - Write-Info "检查 WSL2 状态..." - - try { - $wslList = wsl -l -v - if ($wslList -match "VERSION.*2") { - Write-Info "WSL2 已启用" - Write-Info "WSL 发行版列表:" - Write-Host $wslList - return $true - } - else { - Write-Warn "WSL2 未启用" - Write-Info "请运行以下命令启用 WSL2:" - Write-Host "wsl --set-default-version 2" - return $false - } - } - catch { - Write-Error "获取 WSL 版本信息失败" - return $false - } -} - -# 检查虚拟化是否启用 -function Test-VirtualizationEnabled { - Write-Info "检查虚拟化状态..." - - try { - $vmx = Get-WmiObject -Class Win32_Processor | Select-Object -ExpandProperty NumberOfLogicalProcessors - if ($vmx -gt 0) { - Write-Info "虚拟化已启用" - return $true - } - else { - Write-Error "虚拟化未启用" - Write-Info "请在 BIOS 中启用虚拟化技术(Intel VT-x 或 AMD-V)" - return $false - } - } - catch { - Write-Error "检查虚拟化状态失败" - return $false - } -} - -# 检查 Debian 是否安装 -function Test-DebianInstallation { - Write-Info "检查 Debian 安装状态..." - - try { - $wslList = wsl -l - if ($wslList -match "Debian") { - Write-Info "Debian 已安装" - return $true - } - else { - Write-Warn "Debian 未安装" - Write-Info "请运行以下命令安装 Debian:" - Write-Host "wsl --install -d Debian" - return $false - } - } - catch { - Write-Error "检查 Debian 安装状态失败" - return $false - } -} - -# 检查 Windows 功能 -function Test-WindowsFeatures { - Write-Info "检查 Windows 功能..." - - $features = @( - "Microsoft-Windows-Subsystem-Linux", - "VirtualMachinePlatform" - ) - - $allEnabled = $true - foreach ($feature in $features) { - $status = Get-WindowsOptionalFeature -Online -FeatureName $feature - if ($status.State -eq "Enabled") { - Write-Info "$feature 已启用" - } - else { - Write-Warn "$feature 未启用" - Write-Info "请运行以下命令启用 $feature:" - Write-Host "dism.exe /online /enable-feature /featurename:$feature /all /norestart" - $allEnabled = $false - } - } - - return $allEnabled -} - -# 主函数 -function Main { - Write-Info "开始检查 WSL2 环境..." - - $checks = @{ - "Windows 版本检查" = { Test-WindowsVersion } - "WSL 安装检查" = { Test-WSLInstallation } - "WSL2 状态检查" = { Test-WSL2Enabled } - "虚拟化检查" = { Test-VirtualizationEnabled } - "Debian 安装检查" = { Test-DebianInstallation } - "Windows 功能检查" = { Test-WindowsFeatures } - } - - $allPassed = $true - foreach ($check in $checks.GetEnumerator()) { - Write-Host "`n=== $($check.Key) ===" - if (-not (& $check.Value)) { - $allPassed = $false - } - } - - if ($allPassed) { - Write-Info "`n所有检查项通过!WSL2 环境已准备就绪。" - } - else { - Write-Warn "`n部分检查项未通过,请按照提示进行修复。" - } -} - -# 执行主函数 -Main \ No newline at end of file diff --git a/scripts/system/install-debian.bat b/scripts/system/install-debian.bat new file mode 100644 index 0000000..e62ba17 --- /dev/null +++ b/scripts/system/install-debian.bat @@ -0,0 +1,181 @@ +@echo off +setlocal enabledelayedexpansion + +:: Set console colors +set "GREEN=[32m" +set "YELLOW=[33m" +set "RED=[31m" +set "RESET=[0m" + +:: Function to print colored messages +call :define_print_functions + +echo %GREEN%[INFO]%RESET% Starting WSL2 environment configuration... +echo. + +:: Check for Administrator privileges +net session >nul 2>&1 +if %errorLevel% neq 0 ( + echo %YELLOW%[WARN]%RESET% Administrator privileges required + echo %GREEN%[INFO]%RESET% Please run this script as Administrator + pause + exit /b 1 +) + +echo %GREEN%[INFO]%RESET% Note: Please make sure you have manually updated WSL2 kernel before proceeding. +echo %GREEN%[INFO]%RESET% You can update WSL2 kernel by running "wsl --update" in an administrator PowerShell. +echo. + +:: Check if Debian is installed +echo %GREEN%[INFO]%RESET% Checking Debian installation... +wsl -d Debian echo "Check Debian" >nul 2>&1 +if %ERRORLEVEL% equ 0 ( + echo %GREEN%[INFO]%RESET% Found existing Debian installation + + :: Ask if user wants to remove existing installation + set /p "remove=Do you want to remove the existing Debian installation? [y/N] " + if /i "!remove!"=="y" ( + echo %GREEN%[INFO]%RESET% Removing existing Debian installation... + wsl --unregister Debian + if !ERRORLEVEL! neq 0 ( + echo %RED%[ERROR]%RESET% Failed to remove Debian + pause + exit /b 1 + ) + echo %GREEN%[INFO]%RESET% Existing Debian installation removed + set "NEED_INSTALL=1" + ) +) else ( + echo %GREEN%[INFO]%RESET% No existing Debian installation found + set "NEED_INSTALL=1" +) + +:: Handle Debian installation if needed +if defined NEED_INSTALL ( + :: Get custom installation path + set "DEFAULT_PATH=%USERPROFILE%\WSL\Debian" + echo. + echo Current WSL installation path: %DEFAULT_PATH% + set /p "CUSTOM_PATH=Enter new installation path or press Enter to keep current: " + + if not "!CUSTOM_PATH!"=="" ( + echo %GREEN%[INFO]%RESET% Setting up custom installation path: !CUSTOM_PATH! + + :: Create directory if it doesn't exist + if not exist "!CUSTOM_PATH!" ( + mkdir "!CUSTOM_PATH!" 2>nul + if !ERRORLEVEL! neq 0 ( + echo %RED%[ERROR]%RESET% Failed to create directory: !CUSTOM_PATH! + pause + exit /b 1 + ) + echo %GREEN%[INFO]%RESET% Created directory: !CUSTOM_PATH! + ) + + :: Set WSL installation path + echo %GREEN%[INFO]%RESET% Setting WSL installation path... + setx WSLENV "WSLPATH/up:!CUSTOM_PATH!" >nul + if !ERRORLEVEL! neq 0 ( + echo %RED%[ERROR]%RESET% Failed to set WSL installation path + pause + exit /b 1 + ) + echo %GREEN%[INFO]%RESET% WSL installation path set to: !CUSTOM_PATH! + ) + + :: Install Debian + echo %GREEN%[INFO]%RESET% Installing Debian... + wsl --install -d Debian + if !ERRORLEVEL! neq 0 ( + echo %RED%[ERROR]%RESET% Failed to install Debian + pause + exit /b 1 + ) + echo %GREEN%[INFO]%RESET% Debian installation completed + + :: Wait for Debian to be ready + echo %GREEN%[INFO]%RESET% Waiting for Debian to be ready... + timeout /t 10 /nobreak >nul +) + +:: Shutdown WSL to ensure clean state +echo %GREEN%[INFO]%RESET% Shutting down WSL to ensure clean state... +wsl --shutdown +if %ERRORLEVEL% neq 0 ( + echo %RED%[ERROR]%RESET% Failed to shutdown WSL + pause + exit /b 1 +) +timeout /t 2 /nobreak >nul +echo %GREEN%[INFO]%RESET% WSL shutdown completed + +:: Update Debian system +echo %GREEN%[INFO]%RESET% Updating Debian system packages... + +echo %GREEN%[INFO]%RESET% Updating package lists... +wsl -d Debian -u root apt update +if %ERRORLEVEL% neq 0 ( + echo %RED%[ERROR]%RESET% Failed to update package lists + pause + exit /b 1 +) + +echo %GREEN%[INFO]%RESET% Upgrading packages... +wsl -d Debian -u root apt upgrade -y +if %ERRORLEVEL% neq 0 ( + echo %RED%[ERROR]%RESET% Failed to upgrade packages + pause + exit /b 1 +) + +echo %GREEN%[INFO]%RESET% Cleaning up... +wsl -d Debian -u root apt autoremove -y +wsl -d Debian -u root apt clean + +echo %GREEN%[INFO]%RESET% Debian system update completed + +:: Configure WSL memory limit +echo %GREEN%[INFO]%RESET% Configuring WSL memory limit... +set "CONFIG_FILE=%USERPROFILE%\.wslconfig" + +:: Backup existing config if it exists +if exist "%CONFIG_FILE%" ( + echo %GREEN%[INFO]%RESET% Backing up existing .wslconfig... + copy "%CONFIG_FILE%" "%CONFIG_FILE%.bak" >nul +) + +:: Create new config file +( + echo [wsl2] + echo memory=8GB + echo processors=4 + echo swap=2GB +) > "%CONFIG_FILE%" + +if %ERRORLEVEL% neq 0 ( + echo %RED%[ERROR]%RESET% Failed to create .wslconfig + pause + exit /b 1 +) +echo %GREEN%[INFO]%RESET% WSL memory limit configured + +echo. +echo ============================================ +echo Configuration Complete! +echo ============================================ +echo. +echo Your WSL2 environment has been configured: +echo. +echo %GREEN%[INFO]%RESET% 1. Debian system packages updated +echo %GREEN%[INFO]%RESET% 2. WSL memory limit configured (8GB RAM, 4 cores, 2GB swap) +if defined CUSTOM_PATH ( + echo %GREEN%[INFO]%RESET% 3. WSL installation path set to: !CUSTOM_PATH! +) +echo %GREEN%[INFO]%RESET% Please restart your computer to apply all changes. +echo ============================================ + +pause +exit /b 0 + +:define_print_functions +exit /b 0 \ No newline at end of file diff --git a/scripts/system/install-debian.ps1 b/scripts/system/install-debian.ps1 new file mode 100644 index 0000000..40d063b --- /dev/null +++ b/scripts/system/install-debian.ps1 @@ -0,0 +1,213 @@ +# WSL2 Environment Upgrade Script +# This script upgrades Debian system packages and configures WSL2 settings + +# Set error action +$ErrorActionPreference = 'Stop' + +# Color definitions +$Red = [System.ConsoleColor]::Red +$Green = [System.ConsoleColor]::Green +$Yellow = [System.ConsoleColor]::Yellow + +# Logging functions +function Write-Info { + param([string]$Message) + Write-Host '[INFO] ' -NoNewline -ForegroundColor $Green + Write-Host $Message +} + +function Write-Warn { + param([string]$Message) + Write-Host '[WARN] ' -NoNewline -ForegroundColor $Yellow + Write-Host $Message +} + +function Write-Error { + param([string]$Message) + Write-Host '[ERROR] ' -NoNewline -ForegroundColor $Red + Write-Host $Message +} + +function Wait-KeyPress { + Write-Host "`nPress any key to exit..." -NoNewline + $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') + Write-Host '' +} + +function Get-UserConfirmation { + param([string]$Message) + $response = Read-Host -Prompt "$Message [y/N]" + return $response -eq 'y' -or $response -eq 'Y' +} + +function Get-CustomPath { + param([string]$DefaultPath) + Write-Host "`nCurrent WSL installation path: $DefaultPath" + $response = Read-Host -Prompt "Enter new installation path or press Enter to keep current" + if ([string]::IsNullOrWhiteSpace($response)) { + return $DefaultPath + } + return $response +} + +# Check administrator privileges +if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { + Write-Warn 'Administrator privileges required' + Write-Info 'Please run this script as Administrator' + Wait-KeyPress + exit 1 +} + +Write-Info "`nStarting WSL2 environment configuration...`n" + +Write-Info 'Note: Please make sure you have manually updated WSL2 kernel before proceeding.' +Write-Info 'You can update WSL2 kernel by running "wsl --update" in an administrator PowerShell.' +Write-Host '' + +# Check if Debian is installed +$debianInstalled = $false +try { + wsl -d Debian echo "Check Debian" 2>$null + $debianInstalled = $true + Write-Info "Found existing Debian installation" +} catch { + Write-Info "No existing Debian installation found" +} + +# Handle existing Debian installation +if ($debianInstalled) { + if (Get-UserConfirmation "Do you want to remove the existing Debian installation?") { + Write-Info "Removing existing Debian installation..." + try { + wsl --unregister Debian + Write-Info "Existing Debian installation removed" + $debianInstalled = $false + } catch { + Write-Error "Failed to remove Debian: $($_.Exception.Message)" + Wait-KeyPress + exit 1 + } + } +} + +# Get custom installation path if Debian needs to be installed +if (-not $debianInstalled) { + $defaultPath = "$env:USERPROFILE\WSL\Debian" + $customPath = Get-CustomPath $defaultPath + + if ($customPath -ne $defaultPath) { + Write-Info "Setting up custom installation path: $customPath" + + # Create directory if it doesn't exist + if (-not (Test-Path $customPath)) { + try { + New-Item -ItemType Directory -Path $customPath -Force | Out-Null + Write-Info "Created directory: $customPath" + } catch { + Write-Error "Failed to create directory: $($_.Exception.Message)" + Wait-KeyPress + exit 1 + } + } + + # Set WSL default installation path + Write-Info "Setting WSL installation path..." + try { + [System.Environment]::SetEnvironmentVariable('WSLENV', "WSLPATH/up:$customPath", [System.EnvironmentVariableTarget]::User) + Write-Info "WSL installation path set to: $customPath" + } catch { + Write-Error "Failed to set WSL installation path: $($_.Exception.Message)" + Wait-KeyPress + exit 1 + } + } + + # Install Debian + Write-Info "Installing Debian..." + try { + wsl --install -d Debian + Write-Info "Debian installation completed" + + # Wait for Debian to be ready + Write-Info "Waiting for Debian to be ready..." + Start-Sleep -Seconds 10 + } catch { + Write-Error "Failed to install Debian: $($_.Exception.Message)" + Wait-KeyPress + exit 1 + } +} + +# Shutdown WSL to ensure clean state +Write-Info 'Shutting down WSL to ensure clean state...' +try { + wsl --shutdown + Start-Sleep -Seconds 2 + Write-Info 'WSL shutdown completed' +} catch { + Write-Error "Failed to shutdown WSL: $($_.Exception.Message)" + Wait-KeyPress + exit 1 +} + +# Update Debian system +Write-Info 'Updating Debian system packages...' +try { + # Update package lists + Write-Info 'Updating package lists...' + wsl -d Debian -u root apt update + + # Upgrade packages + Write-Info 'Upgrading packages...' + wsl -d Debian -u root apt upgrade -y + + # Clean up + Write-Info 'Cleaning up...' + wsl -d Debian -u root apt autoremove -y + wsl -d Debian -u root apt clean + + Write-Info 'Debian system update completed' +} catch { + Write-Error "Failed to update Debian system: $($_.Exception.Message)" + Wait-KeyPress + exit 1 +} + +# Configure WSL memory limit +Write-Info 'Configuring WSL memory limit...' +try { + $wslConfigPath = "$env:USERPROFILE\.wslconfig" + $wslConfig = @" +[wsl2] +memory=8GB +processors=4 +swap=2GB +"@ + + if (Test-Path $wslConfigPath) { + Write-Info 'Backing up existing .wslconfig...' + Copy-Item $wslConfigPath "$wslConfigPath.bak" + } + + $wslConfig | Out-File $wslConfigPath -Encoding UTF8 + Write-Info 'WSL memory limit configured' +} catch { + Write-Error "Failed to configure WSL memory limit: $($_.Exception.Message)" + Wait-KeyPress + exit 1 +} + +Write-Host "`n============================================" +Write-Host " Configuration Complete! " +Write-Host "============================================" +Write-Host "`nYour WSL2 environment has been configured:`n" +Write-Info '1. Debian system packages updated' +Write-Info '2. WSL memory limit configured (8GB RAM, 4 cores, 2GB swap)' +if (-not [string]::IsNullOrWhiteSpace($customPath)) { + Write-Info "3. WSL installation path set to: $customPath" +} +Write-Info 'Please restart your computer to apply all changes.' +Write-Host "============================================" + +# Wait for user input before exit +Wait-KeyPress \ No newline at end of file diff --git a/scripts/system/run-check-wsl-ps.bat b/scripts/system/run-check-wsl-ps.bat new file mode 100644 index 0000000..a509807 --- /dev/null +++ b/scripts/system/run-check-wsl-ps.bat @@ -0,0 +1,3 @@ +@echo off +cd /d "%~dp0" +PowerShell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File \"%~dp0check-wsl.ps1\"' -Verb RunAs" \ No newline at end of file diff --git a/scripts/system/run-install-debian-ps.bat b/scripts/system/run-install-debian-ps.bat new file mode 100644 index 0000000..b4809f8 --- /dev/null +++ b/scripts/system/run-install-debian-ps.bat @@ -0,0 +1,3 @@ +@echo off +cd /d "%~dp0" +PowerShell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File \"%~dp0install-debian.ps1\"' -Verb RunAs" \ No newline at end of file diff --git a/scripts/system/temp.txt b/scripts/system/temp.txt deleted file mode 100644 index a56a873773f4bcd5200681232813bac88c799842..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136 zcmY#jP+;(5aAfdha0RjuFqk0(C>nw$ijWTj$^nul -setlocal enabledelayedexpansion - -:: Check for admin privileges -net session >nul 2>&1 -if %errorlevel% neq 0 ( - echo "[WARN] 需要管理员权限" - echo "[INFO] 请右键点击此脚本,选择"以管理员身份运行"" - pause - exit /b 1 -) - -echo. -echo "[INFO] 开始升级 WSL2 并重新安装 Debian..." -echo. - -:: Check WSL installation -echo "[INFO] 检查 WSL 安装状态..." -wsl --version >nul 2>&1 -if %errorlevel% neq 0 ( - echo "[ERROR] WSL 未安装" - echo "[INFO] 请访问 https://aka.ms/wsl 安装 WSL" - goto :error -) - -:: Upgrade WSL -echo "[INFO] 正在升级 WSL..." -wsl --update -if %errorlevel% neq 0 ( - echo "[ERROR] WSL 升级失败" - goto :error -) -echo "[INFO] WSL 升级完成" - -:: Set WSL2 as default -echo "[INFO] 设置 WSL2 为默认版本..." -wsl --set-default-version 2 -if %errorlevel% neq 0 ( - echo "[ERROR] 设置 WSL2 为默认版本失败" - goto :error -) -echo "[INFO] WSL2 已设置为默认版本" - -:: Check if Debian is installed -echo "[INFO] 检查 Debian 安装状态..." -wsl -d Debian echo "Debian is installed" >nul 2>&1 -if %errorlevel% equ 0 ( - echo "[INFO] 检测到已安装的 Debian" - echo. - echo "[WARN] 是否要卸载现有的 Debian?" - echo "[INFO] 1. 是" - echo "[INFO] 2. 否" - echo. - set /p "choice=请选择 (1/2): " - if "!choice!"=="1" ( - echo "[INFO] 正在卸载 Debian..." - wsl --unregister Debian - if %errorlevel% neq 0 ( - echo "[ERROR] Debian 卸载失败" - goto :error - ) - echo "[INFO] Debian 已卸载" - ) else ( - echo "[INFO] 已取消卸载 Debian" - goto :error - ) -) - -:: Choose installation location -echo. -echo "[INFO] 请选择 Debian 安装位置:" -echo "[INFO] 1. 默认位置" -echo "[INFO] 2. 自定义位置" -echo. -set /p "location=请选择 (1/2): " - -if "!location!"=="2" ( - echo "[INFO] 请输入安装路径(例如:D:\WSL\Debian)" - set /p "install_path=安装路径: " - if not exist "!install_path!" mkdir "!install_path!" - echo "[INFO] 正在安装 Debian 到 !install_path! ..." - wsl --install -d Debian --location "!install_path!" -) else ( - echo "[INFO] 正在安装 Debian 到默认位置..." - wsl --install -d Debian -) - -if %errorlevel% neq 0 ( - echo "[ERROR] Debian 安装失败" - goto :error -) -echo "[INFO] Debian 安装完成" - -:: Verify installation -echo "[INFO] 验证安装..." -wsl -d Debian echo "Debian is installed" >nul 2>&1 -if %errorlevel% equ 0 ( - echo "[INFO] Debian 安装验证成功" - echo "[INFO] 请打开新的终端窗口,完成 Debian 的初始设置" -) else ( - echo "[ERROR] Debian 安装验证失败" - goto :error -) - -echo. -echo "============================================" -echo " 升级和安装完成!" -echo "============================================" -echo. -echo "[INFO] 请按照以下步骤完成设置:" -echo "[INFO] 1. 打开新的终端窗口" -echo "[INFO] 2. 等待 Debian 首次启动" -echo "[INFO] 3. 设置用户名和密码" -echo "[INFO] 4. 运行 check_windows_wsl.bat 验证环境" -echo. -echo "[INFO] 按任意键退出..." -pause >nul -goto :eof - -:error -echo. -echo "[WARN] 操作失败,请检查错误信息" -echo "[INFO] 按任意键退出..." -pause >nul -exit /b 1 - -:eof -endlocal \ No newline at end of file diff --git a/scripts/utils/README.md b/scripts/utils/README.md new file mode 100644 index 0000000..13043c2 --- /dev/null +++ b/scripts/utils/README.md @@ -0,0 +1,115 @@ +# 工具脚本集合 + +本目录包含各种通用工具脚本,用于提供基础功能和辅助其他脚本运行。 + +## 目录结构 + +``` +utils/ +├── README.md # 本文档 +├── common.sh # 通用shell函数库 +└── check_user.sh # 用户权限检查工具 +``` + +## 脚本说明 + +### common.sh + +通用shell函数库,提供了各种常用的shell函数。 + +#### 功能 +- 日志管理 + - `setup_logging`: 设置日志系统 + - `log_info`: 记录信息日志 + - `log_warn`: 记录警告日志 + - `log_error`: 记录错误日志 + - `log_success`: 记录成功日志 + +- 进度显示 + - `show_progress`: 显示进度条 + - `update_progress`: 更新进度 + +- 网络管理 + - `check_network`: 检查网络连接 + - `get_mirror_url`: 获取镜像源URL + +- 配置管理 + - `manage_config`: 管理配置文件 + - `manage_plugin`: 管理插件 + +- 依赖管理 + - `check_dependencies`: 检查依赖 + - `install_base_dependencies`: 安装基础依赖 + +- 用户交互 + - `confirm`: 用户确认提示 + - `get_user_info`: 获取用户信息 + +- 文件管理 + - `download_file`: 下载文件 + - `manage_path`: 管理PATH环境变量 + - `manage_alias`: 管理命令别名 + +#### 使用方法 +```bash +# 在脚本中引入 +source ./utils/common.sh + +# 使用函数 +log_info "开始安装..." +show_progress "安装进度" 0 +``` + +### check_user.sh + +用户权限检查工具,用于检查脚本运行环境和权限。 + +#### 功能 +- 检查root权限 +- 检查用户信息 +- 检查系统环境 +- 检查必要命令 + +#### 使用方法 +```bash +# 在脚本中引入 +source ./utils/check_user.sh + +# 检查权限 +check_root +``` + +## 依赖要求 + +- Debian/Ubuntu系统 +- bash shell +- 基本系统工具(curl, wget等) + +## 使用建议 + +1. 在脚本开头引入需要的工具脚本 +2. 使用提供的函数而不是直接实现功能 +3. 遵循错误处理和日志记录规范 +4. 使用进度显示提供更好的用户体验 + +## 注意事项 + +- 确保脚本有执行权限 +- 注意函数的依赖关系 +- 正确处理错误情况 +- 保持日志记录的完整性 + +## 常见问题 + +1. 如果函数未定义,检查是否正确引入了脚本 +2. 如果权限检查失败,确保使用sudo运行 +3. 如果网络检查失败,检查网络连接 +4. 如果日志记录失败,检查日志目录权限 + +## 更新日志 + +### v1.0.0 (2024-03-xx) +- 初始版本发布 +- 完成通用函数库 +- 实现用户检查工具 +- 添加完整的错误处理 \ No newline at end of file diff --git a/scripts/utils/check_user.sh b/scripts/utils/check_user.sh new file mode 100644 index 0000000..e63250c --- /dev/null +++ b/scripts/utils/check_user.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# 导入公共函数 +source "$(dirname "$0")/common.sh" + +# 检查root权限 +check_root + +# 获取用户信息 +get_user_info + +# 显示用户信息 +echo "当前环境信息:" +echo "-----------------------------" +echo "EUID: $EUID" +echo "USER: $USER" +echo "SUDO_USER: $SUDO_USER" +echo "CURRENT_USER: $CURRENT_USER" +echo "USER_HOME: $USER_HOME" +echo "-----------------------------" +echo "用户和组信息:" +echo "-----------------------------" +id "$CURRENT_USER" +echo "-----------------------------" +echo "用户主目录内容:" +echo "-----------------------------" +ls -la "$USER_HOME" +echo "-----------------------------" +echo "Shell信息:" +echo "-----------------------------" +echo "当前Shell: $SHELL" +echo "默认Shell: $(getent passwd "$CURRENT_USER" | cut -d: -f7)" +echo "-----------------------------" +echo "用户组信息:" +echo "-----------------------------" +groups "$CURRENT_USER" +echo "-----------------------------" +echo "sudo权限检查:" +echo "-----------------------------" +sudo -l -U "$CURRENT_USER" \ No newline at end of file diff --git a/scripts/utils/common.sh b/scripts/utils/common.sh new file mode 100644 index 0000000..155e8fd --- /dev/null +++ b/scripts/utils/common.sh @@ -0,0 +1,463 @@ +#!/bin/bash + +# 设置严格模式 +set -euo pipefail + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 初始化日志 +setup_logging() { + local log_dir="${USER_HOME}/.logs" + local log_file="${log_dir}/shell_setup_$(date +%Y%m%d_%H%M%S).log" + + mkdir -p "$log_dir" + exec 1> >(tee -a "$log_file") + exec 2> >(tee -a "$log_file" >&2) + + log_info "开始记录日志到: $log_file" +} + +# 日志函数 +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" | tee -a "${LOG_FILE:-/dev/null}" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" | tee -a "${LOG_FILE:-/dev/null}" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" | tee -a "${LOG_FILE:-/dev/null}" +} + +log_success() { + echo -e "${BLUE}[SUCCESS]${NC} $1" | tee -a "${LOG_FILE:-/dev/null}" +} + +# 进度显示函数 +show_progress() { + local msg="$1" + echo -ne "\r${GREEN}[INFO]${NC} $msg... " +} + +update_progress() { + local msg="$1" + local status="$2" + echo -e "\r${GREEN}[INFO]${NC} $msg... ${status}" +} + +# 清理函数 +cleanup() { + local exit_code=$? + if [ $exit_code -ne 0 ]; then + log_error "脚本执行失败,退出码: $exit_code" + if [ -n "${LAST_BACKUP:-}" ] && [ -f "$LAST_BACKUP" ]; then + log_info "正在恢复配置文件..." + manage_config "restore" "$LAST_BACKUP" + fi + fi + exit $exit_code +} + +# 网络检查函数 +check_network() { + local test_urls=("github.com" "raw.githubusercontent.com") + for url in "${test_urls[@]}"; do + if ! ping -c 1 $url >/dev/null 2>&1; then + log_warn "无法访问 $url" + return 1 + fi + done + return 0 +} + +# 获取镜像源 +get_mirror_url() { + local original_url="$1" + local url_type="$2" + + if check_network; then + echo "$original_url" + return 0 + fi + + case "$url_type" in + "github") + echo "https://ghproxy.com/$original_url" + ;; + "omz") + echo "https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh" + ;; + *) + echo "$original_url" + ;; + esac +} + +# 配置文件管理 +manage_config() { + local action="$1" + local config_file="$2" + local backup_dir="${USER_HOME}/.config_backups" + local timestamp=$(date +%Y%m%d_%H%M%S) + + mkdir -p "$backup_dir" + + case "$action" in + "backup") + if [ -f "$config_file" ]; then + local backup_file="${backup_dir}/$(basename ${config_file}).${timestamp}.bak" + cp "$config_file" "$backup_file" + LAST_BACKUP="$backup_file" + log_info "已备份 $config_file 到 $backup_file" + fi + ;; + "restore") + local source_file="$config_file" + if [ -f "$source_file" ]; then + local dest_file=$(echo "$source_file" | sed 's/\.[0-9]*_[0-9]*\.bak$//') + cp "$source_file" "$dest_file" + log_info "已恢复 $dest_file" + fi + ;; + esac +} + +# 插件管理 +manage_plugin() { + local plugin_name="$1" + local plugin_dir="$2" + local plugin_url="$3" + + show_progress "处理插件 $plugin_name" + + if [ -d "$plugin_dir" ]; then + if [ -d "$plugin_dir/.git" ]; then + (cd "$plugin_dir" && git pull origin master >/dev/null 2>&1) + if [ $? -eq 0 ]; then + update_progress "处理插件 $plugin_name" "更新成功" + return 0 + fi + fi + log_warn "更新 $plugin_name 失败,尝试重新安装" + rm -rf "$plugin_dir" + fi + + if git clone --depth=1 "$plugin_url" "$plugin_dir" >/dev/null 2>&1; then + update_progress "处理插件 $plugin_name" "安装成功" + return 0 + else + update_progress "处理插件 $plugin_name" "安装失败" + return 1 + fi +} + +# 依赖检查 +check_dependencies() { + local deps=("$@") + local missing_deps=() + + show_progress "检查依赖" + + for dep in "${deps[@]}"; do + if ! command -v "$dep" >/dev/null 2>&1; then + missing_deps+=("$dep") + fi + done + + if [ ${#missing_deps[@]} -ne 0 ]; then + update_progress "检查依赖" "发现缺失" + log_warn "缺少以下依赖: ${missing_deps[*]}" + log_info "正在安装缺失的依赖..." + apt-get update >/dev/null 2>&1 + apt-get install -y "${missing_deps[@]}" >/dev/null 2>&1 + update_progress "安装依赖" "完成" + else + update_progress "检查依赖" "已满足" + fi +} + +# 用户交互 +confirm() { + local msg="$1" + local default="${2:-Y}" + + while true; do + read -p "$msg [Y/n] " response + response=${response:-$default} + case $response in + [Yy]) return 0 ;; + [Nn]) return 1 ;; + *) echo "请输入 y 或 n" ;; + esac + done +} + +# 检查命令是否存在 +check_command() { + if ! command -v "$1" &> /dev/null; then + log_error "命令 '$1' 未找到" + return 1 + fi + return 0 +} + +# 检查是否为root用户 +check_root() { + if [ "$EUID" -ne 0 ]; then + log_error "请使用root权限运行此脚本" + exit 1 + fi +} + +# 获取当前用户信息 +get_user_info() { + CURRENT_USER=$SUDO_USER + if [ -z "$CURRENT_USER" ]; then + CURRENT_USER=$(who | awk '{print $1}' | head -n1) + fi + USER_HOME="/home/$CURRENT_USER" + + # 验证用户信息 + if ! id "$CURRENT_USER" >/dev/null 2>&1; then + log_error "无法获取用户信息: $CURRENT_USER" + exit 1 + fi + + if [ ! -d "$USER_HOME" ]; then + log_error "用户主目录不存在: $USER_HOME" + exit 1 + fi +} + +# 检查Node.js版本 +check_nodejs() { + if command -v node &> /dev/null; then + local node_version=$(node -v | cut -d 'v' -f2) + if [ "$(echo -e "${node_version}\n16.0.0" | sort -V | head -n1)" = "16.0.0" ]; then + log_info "检测到 Node.js ${node_version},版本满足要求" + return 0 + else + log_warn "当前 Node.js 版本 ${node_version} 过低,需要更新" + return 1 + fi + else + log_warn "未检测到 Node.js" + return 1 + fi +} + +# 安装Node.js +install_nodejs() { + if ! check_nodejs; then + log_info "安装 Node.js..." + # 尝试使用 Debian 仓库安装 + if apt-get install -y nodejs npm && check_nodejs; then + log_info "成功从 Debian 仓库安装 Node.js" + else + log_warn "从 Debian 仓库安装 Node.js 失败,尝试使用 NodeSource..." + # 删除可能存在的旧版本 + apt-get remove -y nodejs npm + + # 添加 NodeSource 仓库 + mkdir -p /etc/apt/keyrings + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg + echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list + apt-get update + apt-get install -y nodejs + fi + + # 安装neovim包 + su - $CURRENT_USER -c "npm install -g neovim" + fi +} + +# 设置Python虚拟环境 +setup_python_venv() { + local nvim_venv="${USER_HOME}/.local/share/nvim/venv" + + # 创建虚拟环境 + su - $CURRENT_USER -c "python3 -m venv ${nvim_venv}" + + # 安装pynvim + su - $CURRENT_USER -c "${nvim_venv}/bin/pip install pynvim" + + echo "${nvim_venv}" +} + +# 下载文件的通用函数 +download_file() { + local url="$1" + local output="$2" + local max_retries=3 + local retry=0 + local success=false + + show_progress "下载 $(basename "$output")" + + # 获取可能的镜像URL + local mirror_url=$(get_mirror_url "$url" "github") + + while [ $retry -lt $max_retries ] && [ "$success" = false ]; do + if wget --no-check-certificate -q -O "$output" "$mirror_url" 2>/dev/null; then + success=true + elif curl -k -L -s -o "$output" "$mirror_url" 2>/dev/null; then + success=true + else + retry=$((retry + 1)) + log_warn "下载失败,尝试重试 ($retry/$max_retries)..." + sleep 2 + fi + done + + if [ "$success" = false ]; then + update_progress "下载 $(basename "$output")" "失败" + return 1 + fi + + update_progress "下载 $(basename "$output")" "成功" + return 0 +} + +# 检查并安装基础依赖 +install_base_dependencies() { + log_info "安装基础依赖..." + + local base_deps=( + "git" + "curl" + "wget" + "unzip" + "python3-pip" + "python3-venv" + "build-essential" + "ca-certificates" + "fontconfig" + ) + + check_dependencies "${base_deps[@]}" + + # 更新 CA 证书 + update-ca-certificates >/dev/null 2>&1 +} + +# 安装字体 +install_font() { + local font_url="$1" + local font_name="$2" + local font_dir="${USER_HOME}/.local/share/fonts" + + show_progress "安装字体 $font_name" + + # 创建字体目录 + su - $CURRENT_USER -c "mkdir -p ${font_dir}" + + # 下载并安装字体 + if download_file "$font_url" "${font_dir}/${font_name}"; then + # 确保fontconfig已安装 + ensure_package "fontconfig" + # 更新字体缓存 + fc-cache -f -v >/dev/null 2>&1 + update_progress "安装字体 $font_name" "完成" + return 0 + else + update_progress "安装字体 $font_name" "失败" + return 1 + fi +} + +# 添加环境变量 +add_env_var() { + local var_name="$1" + local var_value="$2" + local config_file="$3" + + if ! grep -q "export ${var_name}=" "$config_file" 2>/dev/null; then + echo "export ${var_name}=\"${var_value}\"" >> "$config_file" + log_info "添加环境变量 ${var_name}=${var_value}" + fi +} + +# 添加PATH +add_path() { + local new_path="$1" + local config_file="$2" + + if ! grep -q "export PATH=.*${new_path}" "$config_file" 2>/dev/null; then + echo "export PATH=\"${new_path}:\$PATH\"" >> "$config_file" + log_info "添加PATH ${new_path}" + fi +} + +# 添加别名 +add_alias() { + local alias_name="$1" + local alias_value="$2" + local config_file="$3" + + if ! grep -q "alias ${alias_name}=" "$config_file" 2>/dev/null; then + echo "alias ${alias_name}='${alias_value}'" >> "$config_file" + log_info "添加别名 ${alias_name}=${alias_value}" + fi +} + +# 检查并创建目录 +ensure_dir() { + local dir="$1" + local owner="${2:-}" + + if [ ! -d "$dir" ]; then + mkdir -p "$dir" + if [ -n "$owner" ]; then + chown -R "$owner" "$dir" + fi + log_info "创建目录 $dir" + fi +} + +# 检查并安装依赖包 +ensure_package() { + local package="$1" + + if ! dpkg -l | grep -q "^ii $package " 2>/dev/null; then + log_info "安装 $package..." + apt-get update >/dev/null 2>&1 + apt-get install -y "$package" >/dev/null 2>&1 + log_success "$package 安装完成" + fi +} + +# 检查进程是否在运行 +check_process() { + local process="$1" + + if pgrep -x "$process" >/dev/null; then + return 0 + fi + return 1 +} + +# 等待进程结束 +wait_process() { + local process="$1" + local timeout="$2" + local count=0 + + while check_process "$process" && [ $count -lt $timeout ]; do + sleep 1 + count=$((count + 1)) + done + + if check_process "$process"; then + return 1 + fi + return 0 +} + +# 设置trap +trap cleanup EXIT \ No newline at end of file