Загрузка данных


#!/usr/bin/env bash

set -euo pipefail

info() {
  printf '\033[1;34m[INFO]\033[0m %s\n' "$*"
}

warn() {
  printf '\033[1;33m[WARN]\033[0m %s\n' "$*"
}

error() {
  printf '\033[1;31m[ERROR]\033[0m %s\n' "$*" >&2
}

if [[ ${EUID:-$(id -u)} -eq 0 ]]; then
  error "Не запускай скрипт от root. Запусти обычным пользователем."
  exit 1
fi

if [[ "$(uname -s)" != "Linux" ]]; then
  error "Этот скрипт рассчитан на Linux."
  exit 1
fi

if [[ ! -f /etc/arch-release ]]; then
  error "Этот скрипт рассчитан на Arch Linux."
  exit 1
fi

if ! command -v sudo >/dev/null 2>&1; then
  error "Не найден sudo. Сначала установи его: pacman -S sudo"
  exit 1
fi

info "Запрошу sudo для установки пакетов."
sudo -v

backup_path() {
  local path="$1"

  if [[ -e "$path" || -L "$path" ]]; then
    local stamp backup
    stamp="$(date +%Y-%m-%d_%H-%M-%S)"
    backup="${path}.backup.${stamp}"

    info "Бэкап: $path -> $backup"
    mv "$path" "$backup"
  fi
}

backup_path "$HOME/.config/nvim"
backup_path "$HOME/.local/share/nvim"
backup_path "$HOME/.cache/nvim"

mkdir -p "$HOME/.config" "$HOME/.local/share" "$HOME/.cache"

info "Обновляю базы пакетов..."
sudo pacman -Sy --noconfirm

info "Устанавливаю пакеты..."
sudo pacman -S --needed --noconfirm \
  neovim \
  git \
  clang \
  gcc \
  make \
  nodejs \
  npm \
  ripgrep \
  fd \
  unzip

if ! command -v clangd >/dev/null 2>&1; then
  warn "clangd не найден после установки пакета clang."

  if pacman -Ss '^clangd$' | grep -q .; then
    info "Пробую установить пакет clangd..."
    sudo pacman -S --needed --noconfirm clangd
  else
    warn "Пакет clangd не найден в репозиториях. Возможно, он уже входит в установленный пакет clang."
  fi
fi

if ! command -v clangd >/dev/null 2>&1; then
  warn "clangd всё ещё не найден. Автокомплит может не работать, пока не установишь clangd вручную."
fi

info "Устанавливаю LazyVim starter..."
git clone --depth=1 https://github.com/LazyVim/starter "$HOME/.config/nvim"
rm -rf "$HOME/.config/nvim/.git"
mkdir -p "$HOME/.config/nvim/lua/plugins"

info "Создаю настройку C++ для Neovim..."
cat > "$HOME/.config/nvim/lua/plugins/cpp.lua" <<'LUA_EOF'
return {
  {
    "nvim-treesitter/nvim-treesitter",
    opts = {
      ensure_installed = { "c", "cpp", "cmake", "make", "bash" },
    },
  },

  {
    "neovim/nvim-lspconfig",
    opts = {
      servers = {
        clangd = {
          cmd = {
            "clangd",
            "--background-index",
            "--header-insertion=iwyu",
            "--query-driver=/usr/bin/g++,/usr/bin/gcc,/usr/bin/clang,/usr/bin/clang++",
          },
        },
      },
    },
  },
}
LUA_EOF

info "Создаю глобальную конфигурацию clangd для одиночных C++ файлов..."
mkdir -p "$HOME/.config/clangd"

if [[ -f "$HOME/.config/clangd/config.yaml" ]]; then
  cp "$HOME/.config/clangd/config.yaml" \
    "$HOME/.config/clangd/config.yaml.backup.$(date +%Y-%m-%d_%H-%M-%S)"
fi

cat > "$HOME/.config/clangd/config.yaml" <<'CLANGD_EOF'
CompileFlags:
  Add:
    - -std=c++20
    - -Wall
    - -Wextra
    - -ferror-limit=0
Diagnostics:
  UnusedIncludes: Strict
CLANGD_EOF

TEMPLATE_DIR="$HOME/cpp-nvim-template"

if [[ ! -d "$TEMPLATE_DIR" ]]; then
  info "Создаю тестовый шаблон: $TEMPLATE_DIR"

  mkdir -p "$TEMPLATE_DIR/include"

  cat > "$TEMPLATE_DIR/compile_flags.txt" <<'FLAGS_EOF'
-std=c++20
-Wall
-Wextra
-I.
-Iinclude
FLAGS_EOF

  cat > "$TEMPLATE_DIR/main.cpp" <<'MAIN_EOF'
#include <iostream>
#include "include/hello.hpp"

int main() {
    std::cout << hello_message() << '\n';
    return 0;
}
MAIN_EOF

  cat > "$TEMPLATE_DIR/include/hello.hpp" <<'HEADER_EOF'
#pragma once
#include <string>

inline std::string hello_message() {
    return "Neovim + clangd готово";
}
HEADER_EOF
else
  info "Шаблон уже существует: $TEMPLATE_DIR"
fi

info "Пробую автоматически установить плагины Neovim..."

SYNC_LUA="$(mktemp /tmp/nvim_lazy_sync.XXXXXX)"

cat > "$SYNC_LUA" <<'SYNC_LUA_EOF'
local ok, lazy = pcall(require, "lazy")
if ok and lazy and type(lazy.sync) == "function" then
  lazy.sync({ wait = true })
end
vim.cmd("qa!")
SYNC_LUA_EOF

if timeout 900 nvim --headless -c "luafile $SYNC_LUA"; then
  info "Плагины установлены."
else
  warn "Не получилось автоматически установить плагины."
  warn "Запусти один раз вручную: nvim"
fi

rm -f "$SYNC_LUA"

info "Готово."
info ""
info "Проверка:"
info "  nvim $TEMPLATE_DIR/main.cpp"
info ""
info "Команды внутри Neovim:"
info "  :LspInfo"
info "  :checkhealth vim.lsp"
info "  :Lazy"
info ""
info "Если нужен другой стандарт, правь ~/.config/clangd/config.yaml"