feat(windows): добавлен chezmoi-слой для pwsh, terminal и git
- Зачем: - нужно перенести стабильную Windows-конфигурацию в dotfiles без поломки существующего stow/install.sh workflow для Linux и WSL. - нужно убрать типичные проблемы Git на Windows, включая line endings, из ручной настройки машины. - Что: - добавлен отдельный source dir `chezmoi/` с tiny stub для PowerShell 7 и managed profile в `~/.config/powershell`. - добавлены идемпотентная настройка Windows Terminal и managed Git baseline с миграцией локальных настроек в `~/.gitconfig.local`. - обновлён README: описан Windows workflow, helper-функции pwsh и состав Git baseline без персональных данных. - Проверка: - `chezmoi -S "$HOME\dotfiles\chezmoi" apply` - `pwsh -NoLogo -Command ''$PSVersionTable.PSVersion.ToString(); chcp; [Console]::InputEncoding.WebName; [Console]::OutputEncoding.WebName''` - `git config --global --includes --list --show-origin`
This commit is contained in:
1 parent
22d38f80e5
commit
8fd5b9c630
8 files changed
+750
-238
No files matched your search
@@ -1,260 +1,272 @@
|
|||||||
# Dotfiles
|
# Dotfiles
|
||||||
|
|
||||||
Персональные конфигурационные файлы для настройки рабочего окружения.
|
Персональные конфигурационные файлы для настройки рабочего окружения.
|
||||||
|
|
||||||
## 📦 Содержимое
|
## 📦 Содержимое
|
||||||
|
|
||||||
### Bash
|
### Bash
|
||||||
- **Файлы:** `bash/.bash_custom`, `bash/.bash_functions`, `bash/.bash_prompt`
|
- **Файлы:** `bash/.bash_custom`, `bash/.bash_functions`, `bash/.bash_prompt`
|
||||||
- Подключение кастомных bash-файлов (функции, prompt, секреты) поверх стандартного `~/.bashrc`
|
- Подключение кастомных bash-файлов (функции, prompt, секреты) поверх стандартного `~/.bashrc`
|
||||||
- Кастомный двухстрочный prompt (подключается из `~/.bash_prompt`)
|
- Кастомный двухстрочный prompt (подключается из `~/.bash_prompt`)
|
||||||
- Поддержка цветного вывода и автодополнения
|
- Поддержка цветного вывода и автодополнения
|
||||||
|
|
||||||
### Tmux
|
### Tmux
|
||||||
- **Файл:** `tmux/.tmux.conf`
|
- **Файл:** `tmux/.tmux.conf`
|
||||||
- Два префикса: `Ctrl+b` (стандартный) и `Ctrl+Space` (удобный)
|
- Два префикса: `Ctrl+b` (стандартный) и `Ctrl+Space` (удобный)
|
||||||
- Визуальный стиль с синей цветовой схемой
|
- Визуальный стиль с синей цветовой схемой
|
||||||
- Vi-режим для копирования
|
- Vi-режим для копирования
|
||||||
- Горячие клавиши:
|
- Горячие клавиши:
|
||||||
- `|` / `-` — разделение панелей
|
- `|` / `-` — разделение панелей
|
||||||
- `Alt+стрелки` — изменение размера панелей и переключение окон
|
- `Alt+стрелки` — изменение размера панелей и переключение окон
|
||||||
- `r` — перезагрузка конфига
|
- `r` — перезагрузка конфига
|
||||||
|
|
||||||
### Vim
|
### Vim
|
||||||
- **Файл:** `vim/.vimrc`
|
- **Файл:** `vim/.vimrc`
|
||||||
- Минималистичная конфигурация без плагинов
|
- Минималистичная конфигурация без плагинов
|
||||||
- 2 пробела вместо табов (оптимально для YAML/XML)
|
- 2 пробела вместо табов (оптимально для YAML/XML)
|
||||||
- Поддержка мыши и подсветка поиска
|
- Поддержка мыши и подсветка поиска
|
||||||
- Leader key: `Space`
|
- Leader key: `Space`
|
||||||
- `<Space>w` — сохранить
|
- `<Space>w` — сохранить
|
||||||
- `<Space>h` — убрать подсветку поиска
|
- `<Space>h` — убрать подсветку поиска
|
||||||
- `<Space>p` — вставка без форматирования
|
- `<Space>p` — вставка без форматирования
|
||||||
|
|
||||||
### Zed
|
### Zed
|
||||||
- **Директория:** `zed/.config/zed/`
|
- **Директория:** `zed/.config/zed/`
|
||||||
- Структура для конфигурации Zed редактора
|
- Структура для конфигурации Zed редактора
|
||||||
|
|
||||||
### VS Code (WSL)
|
### VS Code (WSL)
|
||||||
- **Файл:** `vscode/.vscode-server/server-env-setup`
|
- **Файл:** `vscode/.vscode-server/server-env-setup`
|
||||||
- Поддержка `~/.vscode-server/server-env-setup` для VS Code Server в WSL
|
- Поддержка `~/.vscode-server/server-env-setup` для VS Code Server в WSL
|
||||||
- Подгрузка `~/.env.secrets` для расширений, задач/debug и терминалов VS Code
|
- Подгрузка `~/.env.secrets` для расширений, задач/debug и терминалов VS Code
|
||||||
- Автоматическая настройка прокси: если `hproxy.local` резолвится, выставляются `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY` (socks5), `NO_PROXY` и их lowercase-варианты
|
- Автоматическая настройка прокси: если `hproxy.local` резолвится, выставляются `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY` (socks5), `NO_PROXY` и их lowercase-варианты
|
||||||
- Режим `fail-open`: если `~/.env.secrets` отсутствует или не загружается — warning в stderr, VS Code продолжает запуск
|
- Режим `fail-open`: если `~/.env.secrets` отсутствует или не загружается — warning в stderr, VS Code продолжает запуск
|
||||||
|
|
||||||
### Opencode
|
### Opencode
|
||||||
- **Директория:** `opencode/.config/opencode/`
|
- **Директория:** `opencode/.config/opencode/`
|
||||||
- Конфигурация AI-ассистента opencode с MCP-серверами:
|
- Конфигурация AI-ассистента opencode с MCP-серверами:
|
||||||
- **context7** — документация библиотек
|
- **context7** — документация библиотек
|
||||||
- **web-reader** — чтение веб-страниц
|
- **web-reader** — чтение веб-страниц
|
||||||
- **web-search-prime** — поиск в интернете
|
- **web-search-prime** — поиск в интернете
|
||||||
- **zread** — чтение GitHub репозиториев
|
- **zread** — чтение GitHub репозиториев
|
||||||
- **playwright** — браузерная автоматизация
|
- **playwright** — браузерная автоматизация
|
||||||
- Требует переменных окружения (см. `.env.example`)
|
- Требует переменных окружения (см. `.env.example`)
|
||||||
- Скиллы берутся из общего пакета `agents/.agents/skills/` через симлинк `~/.config/opencode/skills`
|
- Скиллы берутся из общего пакета `agents/.agents/skills/` через симлинк `~/.config/opencode/skills`
|
||||||
|
|
||||||
### Agents (shared skills)
|
### Agents (shared skills)
|
||||||
- **Директория:** `agents/.agents/skills/`
|
- **Директория:** `agents/.agents/skills/`
|
||||||
- Каноничное место для общих скиллов в формате `~/.agents/skills/<name>/SKILL.md`
|
- Каноничное место для общих скиллов в формате `~/.agents/skills/<name>/SKILL.md`
|
||||||
|
|
||||||
### Codex
|
### Codex
|
||||||
- **Директория:** `codex/.codex/skills/`
|
- **Директория:** `codex/.codex/skills/`
|
||||||
- Тонкие симлинки в `~/.codex/skills/` на общие skills из `~/.agents/skills/`
|
- Тонкие симлинки в `~/.codex/skills/` на общие skills из `~/.agents/skills/`
|
||||||
|
|
||||||
### Claude
|
### Claude
|
||||||
- **Директория:** `claude/.claude/`
|
- **Директория:** `claude/.claude/`
|
||||||
- Тонкий симлинк `~/.claude/skills` на общие skills из `~/.agents/skills/`
|
- Тонкий симлинк `~/.claude/skills` на общие skills из `~/.agents/skills/`
|
||||||
- **Двухуровневые настройки:**
|
- **Двухуровневые настройки:**
|
||||||
- `settings.json` (в dotfiles, read-only) — стабильная база: permissions, statusLine
|
- `settings.json` (в dotfiles, read-only) — стабильная база: permissions, statusLine
|
||||||
- `settings.local.json` (локальный, не в git) — машинно-специфичное: model, effortLevel
|
- `settings.local.json` (локальный, не в git) — машинно-специфичное: model, effortLevel
|
||||||
- Claude Code мержит оба файла, `settings.local.json` имеет приоритет
|
- Claude Code мержит оба файла, `settings.local.json` имеет приоритет
|
||||||
- `settings.json` защищён `chmod 444`, чтобы Claude Code не перезаписывал tracked файл
|
- `settings.json` защищён `chmod 444`, чтобы Claude Code не перезаписывал tracked файл
|
||||||
|
|
||||||
### Gemini
|
### Gemini
|
||||||
- **Директория:** `gemini/.gemini/`
|
- **Директория:** `gemini/.gemini/`
|
||||||
- Политики для Gemini CLI: pre-approved readonly команды
|
- Политики для Gemini CLI: pre-approved readonly команды
|
||||||
|
|
||||||
## 🚀 Установка
|
## 🚀 Установка
|
||||||
|
|
||||||
### Автоматическая (рекомендуется)
|
### Автоматическая (рекомендуется)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt install stow
|
sudo apt install stow
|
||||||
git clone https://github.com/ddmitry/dotfiles ~/dotfiles
|
git clone https://github.com/ddmitry/dotfiles ~/dotfiles
|
||||||
cd ~/dotfiles
|
cd ~/dotfiles
|
||||||
./install.sh
|
./install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Скрипт `install.sh`:
|
Скрипт `install.sh`:
|
||||||
- Применяет все stow пакеты
|
- Применяет все stow пакеты
|
||||||
- Создаёт `~/.claude/settings.local.json` с дефолтными model/effortLevel
|
- Создаёт `~/.claude/settings.local.json` с дефолтными model/effortLevel
|
||||||
- Защищает `settings.json` от перезаписи (`chmod 444`)
|
- Защищает `settings.json` от перезаписи (`chmod 444`)
|
||||||
- Автоматически добавляет подключение bash_custom в `~/.bashrc`
|
- Автоматически добавляет подключение bash_custom в `~/.bashrc`
|
||||||
- В WSL предлагает настроить автоматический резолв `hproxy.local` (см. ниже)
|
- В WSL предлагает настроить автоматический резолв `hproxy.local` (см. ниже)
|
||||||
|
|
||||||
### Stow вручную
|
### Stow вручную
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt install stow
|
sudo apt install stow
|
||||||
cd /path/to/dotfiles
|
cd /path/to/dotfiles
|
||||||
stow bash tmux vim zed vscode agents opencode codex claude gemini
|
stow bash tmux vim zed vscode agents opencode codex claude gemini
|
||||||
```
|
```
|
||||||
|
|
||||||
После stow добавьте в `~/.bashrc` (если не используете `install.sh`):
|
После stow добавьте в `~/.bashrc` (если не используете `install.sh`):
|
||||||
```bash
|
```bash
|
||||||
[ -f ~/.bash_custom ] && source ~/.bash_custom
|
[ -f ~/.bash_custom ] && source ~/.bash_custom
|
||||||
```
|
```
|
||||||
|
|
||||||
Создайте локальные настройки Claude:
|
Создайте локальные настройки Claude:
|
||||||
```bash
|
```bash
|
||||||
cat > ~/.claude/settings.local.json <<'EOF'
|
cat > ~/.claude/settings.local.json <<'EOF'
|
||||||
{
|
{
|
||||||
"model": "opus",
|
"model": "opus",
|
||||||
"effortLevel": "high"
|
"effortLevel": "high"
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
### Windows (chezmoi)
|
### Windows (chezmoi)
|
||||||
|
|
||||||
Для Windows используется [chezmoi](https://www.chezmoi.io/) — кросс-платформенный менеджер dotfiles.
|
Для Windows предпочтителен отдельный source dir `chezmoi/` внутри этого репозитория. Это позволяет держать Windows-слой рядом с остальными dotfiles, не ломая существующий `stow`/`install.sh` workflow для Linux/WSL.
|
||||||
|
|
||||||
> 💡 **Примечание:** chezmoi также работает на Linux/WSL, но stow предпочтительнее для полной функциональности.
|
> 💡 **Примечание:** chezmoi также работает на Linux/WSL, но stow предпочтительнее для полной функциональности.
|
||||||
|
|
||||||
**⚠️ Требования:**
|
**⚠️ Требования:**
|
||||||
- Developer Mode должен быть включён (для создания симлинков)
|
- Developer Mode должен быть включён (для создания симлинков)
|
||||||
> Settings → System → For developers → Developer Mode → On
|
> Settings → System → For developers → Developer Mode → On
|
||||||
- PowerShell 5.0+ или PowerShell Core
|
- `pwsh` 7.x для повседневной работы
|
||||||
|
- `Windows PowerShell 5.1` остаётся legacy-режимом и не тюнится агрессивно
|
||||||
|
|
||||||
**Установка (два шага):**
|
**Быстрое применение из уже существующего `~/dotfiles`:**
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# 1. Установка chezmoi
|
|
||||||
winget install twpayne.chezmoi
|
winget install twpayne.chezmoi
|
||||||
|
|
||||||
# 2. Инициализация (клонирует репо)
|
# Применить только Windows-layer из репозитория
|
||||||
chezmoi init ddmitry/dotfiles
|
chezmoi -S "$HOME\dotfiles\chezmoi" apply
|
||||||
|
|
||||||
# 3. Первое применение (подготавливает структуру)
|
|
||||||
chezmoi apply
|
|
||||||
|
|
||||||
# 4. Второе применение (копирует файлы в правильные места)
|
|
||||||
chezmoi apply
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Примечания:**
|
Этот режим не требует менять глобальный source `chezmoi`: достаточно запускать `chezmoi -S "$HOME\dotfiles\chezmoi" apply` из уже существующего репозитория.
|
||||||
- После шага 4 все файлы будут на месте: `~/.vimrc`, `~/.agents/skills/`, `~/.config/opencode/`, и т.д.
|
|
||||||
- Симлинки для skills создаются автоматически только если включен Developer Mode
|
|
||||||
- Без Developer Mode AI-ассистенты будут работать с прямыми копиями skills
|
|
||||||
|
|
||||||
**Что доступно на Windows:**
|
**Что делает текущий Windows-layer:**
|
||||||
- ✅ Vim
|
- ✅ ставит маленький live-stub в `~/Documents/PowerShell/Microsoft.PowerShell_profile.ps1`
|
||||||
- ✅ Agents (shared skills)
|
- ✅ хранит основную логику `pwsh` в `~/.config/powershell/profile.ps1`
|
||||||
- ✅ Codex (с симлинками на skills)
|
- ✅ раскладывает Git на managed baseline в `~/.config/git/config` и локальные overrides в `~/.gitconfig.local`
|
||||||
- ✅ Claude (с симлинками на skills)
|
- ✅ оставляет hook'и для локальных добавок: `~/.config/powershell/profile.extra.ps1` и `~/.config/powershell/profile.d/*.ps1`
|
||||||
- ✅ Opencode (с симлинками на skills)
|
- ✅ идемпотентно приводит `Windows Terminal` к базовому состоянию без полной перезаписи всего `settings.json`
|
||||||
|
|
||||||
**Что НЕ доступно на Windows:**
|
**Какие helper-функции есть в `pwsh`:**
|
||||||
- ❌ Bash (Linux-only)
|
- `Reload-Profile` — перечитывает текущий профиль без перезапуска сессии
|
||||||
- ❌ Tmux (Linux-only)
|
- `which` — показывает все найденные команды по имени через `Get-Command -All`
|
||||||
- ❌ Zed (пути конфигурации отличаются)
|
- `touch` — создаёт файл или обновляет `LastWriteTime`
|
||||||
|
- `mkcd` — создаёт директорию и сразу переходит в неё
|
||||||
|
- `open` — открывает путь через `Invoke-Item`
|
||||||
|
- `croot` — переходит в корень текущего Git-репозитория
|
||||||
|
- `wt-here` — открывает новое окно Windows Terminal в текущей директории
|
||||||
|
- `wt-tab-here` — открывает новую вкладку Windows Terminal в текущей директории
|
||||||
|
- `wt-split-here` — открывает split-pane Windows Terminal в текущей директории
|
||||||
|
- `codevpn` — запускает `code .` с временно выставленными `HTTP_PROXY` и `HTTPS_PROXY`
|
||||||
|
|
||||||
|
**Что сознательно не делается:**
|
||||||
|
- ❌ `Windows PowerShell 5.1` не форсируется в UTF-8 и не меняется без явного запроса
|
||||||
|
- ❌ Linux/WSL-поток не переносится в chezmoi и продолжает жить через `stow`/`install.sh`
|
||||||
|
|
||||||
|
**Что фиксирует Git baseline для Windows:**
|
||||||
|
- `core.autocrlf = false`
|
||||||
|
- `core.eol = lf`
|
||||||
|
- `core.quotepath = false`
|
||||||
|
- `core.longpaths = true`
|
||||||
|
- `fetch.prune = true`
|
||||||
|
- `pull.ff = only`
|
||||||
|
- `init.defaultBranch = main`
|
||||||
|
- `user.name`, `user.email`, `core.editor` и `core.sshCommand` в baseline не входят и должны жить в `~/.gitconfig.local`
|
||||||
|
|
||||||
## 🔧 Требования
|
## 🔧 Требования
|
||||||
|
|
||||||
### Linux/WSL
|
### Linux/WSL
|
||||||
- Linux (протестировано на Ubuntu)
|
- Linux (протестировано на Ubuntu)
|
||||||
- Bash 4.0+
|
- Bash 4.0+
|
||||||
- Tmux 2.0+
|
- Tmux 2.0+
|
||||||
- Vim 8.0+
|
- Vim 8.0+
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
- Windows 10/11 с Developer Mode
|
- Windows 10/11 с Developer Mode
|
||||||
- PowerShell 5.0+ или PowerShell Core
|
- PowerShell 7.x
|
||||||
- [chezmoi](https://www.chezmoi.io/)
|
- [chezmoi](https://www.chezmoi.io/)
|
||||||
|
|
||||||
## 📝 Дополнительные файлы
|
## 📝 Дополнительные файлы
|
||||||
|
|
||||||
Для полной настройки создайте:
|
Для полной настройки создайте:
|
||||||
- `~/.bash_aliases` — персональные алиасы
|
- `~/.bash_aliases` — персональные алиасы
|
||||||
- `~/.env.secrets` — приватные переменные окружения (API ключи)
|
- `~/.env.secrets` — приватные переменные окружения (API ключи)
|
||||||
|
|
||||||
## 🔑 Переменные окружения
|
## 🔑 Переменные окружения
|
||||||
|
|
||||||
### Кастомные функции bash
|
### Кастомные функции bash
|
||||||
|
|
||||||
Файл `bash/.bash_functions` содержит пользовательские функции (proxy_on/off, myip и др.).
|
Файл `bash/.bash_functions` содержит пользовательские функции (proxy_on/off, myip и др.).
|
||||||
При использовании `stow bash` он будет доступен как `~/.bash_functions`.
|
При использовании `stow bash` он будет доступен как `~/.bash_functions`.
|
||||||
|
|
||||||
### Приватные переменные (секреты)
|
### Приватные переменные (секреты)
|
||||||
|
|
||||||
1. Скопируйте шаблон:
|
1. Скопируйте шаблон:
|
||||||
```bash
|
```bash
|
||||||
cp bash/.env.secrets.example ~/.env.secrets
|
cp bash/.env.secrets.example ~/.env.secrets
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Отредактируйте и добавьте API ключи:
|
2. Отредактируйте и добавьте API ключи:
|
||||||
```bash
|
```bash
|
||||||
# Context7 API (https://context7.com)
|
# Context7 API (https://context7.com)
|
||||||
export CONTEXT7_API_KEY="your_context7_api_key_here"
|
export CONTEXT7_API_KEY="your_context7_api_key_here"
|
||||||
|
|
||||||
# Z.AI API для LLM, поиска и чтения (https://z.ai)
|
# Z.AI API для LLM, поиска и чтения (https://z.ai)
|
||||||
export ZAI_API_KEY="your_zai_api_key_here"
|
export ZAI_API_KEY="your_zai_api_key_here"
|
||||||
```
|
```
|
||||||
|
|
||||||
Файл `~/.env.secrets` автоматически подгружается при старте shell.
|
Файл `~/.env.secrets` автоматически подгружается при старте shell.
|
||||||
|
|
||||||
### WSL: настройка hproxy.local
|
### WSL: настройка hproxy.local
|
||||||
|
|
||||||
Имя `hproxy.local` используется как алиас для хоста, на котором работает прокси-сервер. Это позволяет функциям `proxy_on`/`proxy_off` и VS Code Server не зависеть от конкретного IP-адреса.
|
Имя `hproxy.local` используется как алиас для хоста, на котором работает прокси-сервер. Это позволяет функциям `proxy_on`/`proxy_off` и VS Code Server не зависеть от конкретного IP-адреса.
|
||||||
|
|
||||||
**NAT mode** (по умолчанию в WSL2) — IP шлюза меняется при каждом запуске, поэтому нужен автоматический boot-скрипт:
|
**NAT mode** (по умолчанию в WSL2) — IP шлюза меняется при каждом запуске, поэтому нужен автоматический boot-скрипт:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Вариант 1: через install.sh (интерактивно)
|
# Вариант 1: через install.sh (интерактивно)
|
||||||
./install.sh # ответьте "y" на вопрос про wsl.conf
|
./install.sh # ответьте "y" на вопрос про wsl.conf
|
||||||
|
|
||||||
# Вариант 2: вручную
|
# Вариант 2: вручную
|
||||||
sudo tee -a /etc/wsl.conf <<'EOF'
|
sudo tee -a /etc/wsl.conf <<'EOF'
|
||||||
|
|
||||||
[boot]
|
[boot]
|
||||||
command = "/path/to/dotfiles/scripts/setup-hproxy.sh"
|
command = "/path/to/dotfiles/scripts/setup-hproxy.sh"
|
||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
После изменения `wsl.conf` перезапустите WSL: `wsl --shutdown`.
|
После изменения `wsl.conf` перезапустите WSL: `wsl --shutdown`.
|
||||||
|
|
||||||
Обновить `hproxy.local` без перезапуска WSL:
|
Обновить `hproxy.local` без перезапуска WSL:
|
||||||
```bash
|
```bash
|
||||||
sudo scripts/setup-hproxy.sh
|
sudo scripts/setup-hproxy.sh
|
||||||
# или
|
# или
|
||||||
update_hproxy # интерактивная функция из .bash_functions
|
update_hproxy # интерактивная функция из .bash_functions
|
||||||
```
|
```
|
||||||
|
|
||||||
**Mirror mode** (`networkingMode=mirrored` в `.wslconfig`) — WSL разделяет сетевой стек с хостом, IP не меняется. Достаточно один раз прописать запись в Windows hosts:
|
**Mirror mode** (`networkingMode=mirrored` в `.wslconfig`) — WSL разделяет сетевой стек с хостом, IP не меняется. Достаточно один раз прописать запись в Windows hosts:
|
||||||
|
|
||||||
```
|
```
|
||||||
# C:\Windows\System32\drivers\etc\hosts
|
# C:\Windows\System32\drivers\etc\hosts
|
||||||
192.168.1.100 hproxy.local
|
192.168.1.100 hproxy.local
|
||||||
```
|
```
|
||||||
|
|
||||||
### VS Code Server в WSL
|
### VS Code Server в WSL
|
||||||
|
|
||||||
Файл `vscode/.vscode-server/server-env-setup` выполняется при каждом старте VS Code Server в WSL и делает две вещи:
|
Файл `vscode/.vscode-server/server-env-setup` выполняется при каждом старте VS Code Server в WSL и делает две вещи:
|
||||||
|
|
||||||
1. **Загружает `~/.env.secrets`** — API ключи становятся доступны расширениям, задачам и терминалам VS Code. Если файл отсутствует или содержит ошибку, выводится warning в stderr, запуск не блокируется.
|
1. **Загружает `~/.env.secrets`** — API ключи становятся доступны расширениям, задачам и терминалам VS Code. Если файл отсутствует или содержит ошибку, выводится warning в stderr, запуск не блокируется.
|
||||||
|
|
||||||
2. **Настраивает прокси** — если `hproxy.local` резолвится (через `/etc/hosts` или DNS в режиме mirror), автоматически выставляются:
|
2. **Настраивает прокси** — если `hproxy.local` резолвится (через `/etc/hosts` или DNS в режиме mirror), автоматически выставляются:
|
||||||
- `HTTP_PROXY` / `http_proxy` → `http://hproxy.local:12334`
|
- `HTTP_PROXY` / `http_proxy` → `http://hproxy.local:12334`
|
||||||
- `HTTPS_PROXY` / `https_proxy` → `http://hproxy.local:12334`
|
- `HTTPS_PROXY` / `https_proxy` → `http://hproxy.local:12334`
|
||||||
- `ALL_PROXY` / `all_proxy` → `socks5://hproxy.local:12334`
|
- `ALL_PROXY` / `all_proxy` → `socks5://hproxy.local:12334`
|
||||||
- `NO_PROXY` / `no_proxy` → `hproxy.local,localhost,127.0.0.1,.concept-software.ru`
|
- `NO_PROXY` / `no_proxy` → `hproxy.local,localhost,127.0.0.1,.concept-software.ru`
|
||||||
|
|
||||||
После установки/обновления файла сделайте одно из действий:
|
После установки/обновления файла сделайте одно из действий:
|
||||||
- `Developer: Reload Window` в VS Code
|
- `Developer: Reload Window` в VS Code
|
||||||
- или `Remote-WSL: Reconnect to WSL`
|
- или `Remote-WSL: Reconnect to WSL`
|
||||||
|
|
||||||
Если у вас уже есть локальный `~/.vscode-server/server-env-setup`, stow может сообщить конфликт.
|
Если у вас уже есть локальный `~/.vscode-server/server-env-setup`, stow может сообщить конфликт.
|
||||||
Тогда сохраните старую версию и примените stow повторно:
|
Тогда сохраните старую версию и примените stow повторно:
|
||||||
```bash
|
```bash
|
||||||
mv ~/.vscode-server/server-env-setup ~/.vscode-server/server-env-setup.bak.$(date +%Y%m%d%H%M%S)
|
mv ~/.vscode-server/server-env-setup ~/.vscode-server/server-env-setup.bak.$(date +%Y%m%d%H%M%S)
|
||||||
stow -vt ~ vscode
|
stow -vt ~ vscode
|
||||||
```
|
```
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{{ if ne .chezmoi.os "windows" }}
|
||||||
|
AppData/**
|
||||||
|
Documents/**
|
||||||
|
dot_config/**
|
||||||
|
dot_gitconfig
|
||||||
|
{{ end }}
|
||||||
@@ -0,0 +1,267 @@
|
|||||||
|
if (-not $IsWindows) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$settingsPath = Join-Path $env:LOCALAPPDATA 'Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json'
|
||||||
|
if (-not (Test-Path -LiteralPath $settingsPath)) {
|
||||||
|
Write-Warning "Windows Terminal settings not found: $settingsPath"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$PowerShellGuid = '{574e775e-4f2a-5b96-ac1e-a2962a402336}'
|
||||||
|
$LegacyPowerShellGuid = '{61c54bbd-c2c6-5271-96e7-009a87ff44bf}'
|
||||||
|
$changed = $false
|
||||||
|
|
||||||
|
function Get-JsonPropertyValue {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
$Object,
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$Name
|
||||||
|
)
|
||||||
|
|
||||||
|
$Property = $Object.PSObject.Properties[$Name]
|
||||||
|
if ($null -eq $Property) {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Property.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-JsonValueEqual {
|
||||||
|
param(
|
||||||
|
$Left,
|
||||||
|
$Right
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($null -eq $Left -and $null -eq $Right) {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($null -eq $Left -or $null -eq $Right) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
$Left -is [System.Collections.IEnumerable] -and
|
||||||
|
-not ($Left -is [string])
|
||||||
|
) {
|
||||||
|
return (ConvertTo-Json $Left -Depth 100 -Compress) -eq (ConvertTo-Json $Right -Depth 100 -Compress)
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Left -eq $Right
|
||||||
|
}
|
||||||
|
|
||||||
|
function Set-JsonPropertyValue {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
$Object,
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$Name,
|
||||||
|
$Value
|
||||||
|
)
|
||||||
|
|
||||||
|
$Property = $Object.PSObject.Properties[$Name]
|
||||||
|
if ($null -eq $Property) {
|
||||||
|
$Object | Add-Member -NotePropertyName $Name -NotePropertyValue $Value
|
||||||
|
$script:changed = $true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-JsonValueEqual -Left $Property.Value -Right $Value)) {
|
||||||
|
$Property.Value = $Value
|
||||||
|
$script:changed = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-IsPowerShell7Profile {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
$Profile
|
||||||
|
)
|
||||||
|
|
||||||
|
$Source = [string](Get-JsonPropertyValue -Object $Profile -Name source)
|
||||||
|
$Name = [string](Get-JsonPropertyValue -Object $Profile -Name name)
|
||||||
|
$CommandLine = [string](Get-JsonPropertyValue -Object $Profile -Name commandline)
|
||||||
|
|
||||||
|
if ($Source -eq 'Windows.Terminal.PowershellCore') {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($CommandLine -match '(?i)(^|[\\/ ])pwsh(?:\.exe)?(?:\s|$)') {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Name -match '^(PowerShell|PowerShell 7)$'
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-IsDisposablePowerShell7Profile {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
$Profile
|
||||||
|
)
|
||||||
|
|
||||||
|
$Source = [string](Get-JsonPropertyValue -Object $Profile -Name source)
|
||||||
|
$Name = [string](Get-JsonPropertyValue -Object $Profile -Name name)
|
||||||
|
$CommandLine = [string](Get-JsonPropertyValue -Object $Profile -Name commandline)
|
||||||
|
|
||||||
|
return (
|
||||||
|
$Name -match '^(PowerShell|PowerShell 7)$' -and
|
||||||
|
(
|
||||||
|
$Source -eq 'Windows.Terminal.PowershellCore' -or
|
||||||
|
$CommandLine -match '(?i)(^|[\\/ ])pwsh(?:\.exe)?(?:\s|$)'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$originalSettings = Get-Content -LiteralPath $settingsPath -Raw
|
||||||
|
$settings = $originalSettings | ConvertFrom-Json
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Warning "Failed to read Windows Terminal settings: $settingsPath"
|
||||||
|
Write-Warning $_
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($null -eq (Get-JsonPropertyValue -Object $settings -Name profiles)) {
|
||||||
|
$settings | Add-Member -NotePropertyName profiles -NotePropertyValue ([pscustomobject]@{
|
||||||
|
defaults = [pscustomobject]@{}
|
||||||
|
list = @()
|
||||||
|
})
|
||||||
|
$changed = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($null -eq (Get-JsonPropertyValue -Object $settings.profiles -Name list)) {
|
||||||
|
$settings.profiles | Add-Member -NotePropertyName list -NotePropertyValue @()
|
||||||
|
$changed = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
$profiles = @($settings.profiles.list)
|
||||||
|
$powerShell7CandidateIndices = New-Object System.Collections.Generic.List[int]
|
||||||
|
$legacyPowerShellIndex = $null
|
||||||
|
|
||||||
|
for ($i = 0; $i -lt $profiles.Count; $i++) {
|
||||||
|
$profile = $profiles[$i]
|
||||||
|
$guid = [string](Get-JsonPropertyValue -Object $profile -Name guid)
|
||||||
|
$source = [string](Get-JsonPropertyValue -Object $profile -Name source)
|
||||||
|
$commandLine = [string](Get-JsonPropertyValue -Object $profile -Name commandline)
|
||||||
|
|
||||||
|
if (Test-IsPowerShell7Profile -Profile $profile) {
|
||||||
|
[void]$powerShell7CandidateIndices.Add($i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
$guid -eq $LegacyPowerShellGuid -or
|
||||||
|
$commandLine -match '(?i)WindowsPowerShell\\v1\.0\\powershell\.exe'
|
||||||
|
) {
|
||||||
|
$legacyPowerShellIndex = $i
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($source -eq 'Windows.Terminal.Azure') {
|
||||||
|
Set-JsonPropertyValue -Object $profile -Name hidden -Value $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$powerShell7Index = $null
|
||||||
|
foreach ($candidateIndex in $powerShell7CandidateIndices) {
|
||||||
|
$candidate = $profiles[$candidateIndex]
|
||||||
|
if ([string](Get-JsonPropertyValue -Object $candidate -Name source) -eq 'Windows.Terminal.PowershellCore') {
|
||||||
|
$powerShell7Index = $candidateIndex
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($null -eq $powerShell7Index -and $powerShell7CandidateIndices.Count -gt 0) {
|
||||||
|
$powerShell7Index = $powerShell7CandidateIndices[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($null -eq $powerShell7Index) {
|
||||||
|
$profiles += [pscustomobject]@{
|
||||||
|
commandline = 'pwsh.exe'
|
||||||
|
guid = $PowerShellGuid
|
||||||
|
hidden = $false
|
||||||
|
name = 'PowerShell 7'
|
||||||
|
startingDirectory = '%USERPROFILE%'
|
||||||
|
}
|
||||||
|
$powerShell7Index = $profiles.Count - 1
|
||||||
|
$changed = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
$powerShell7Profile = $profiles[$powerShell7Index]
|
||||||
|
if ([string]::IsNullOrWhiteSpace([string](Get-JsonPropertyValue -Object $powerShell7Profile -Name guid))) {
|
||||||
|
Set-JsonPropertyValue -Object $powerShell7Profile -Name guid -Value $PowerShellGuid
|
||||||
|
}
|
||||||
|
if ($null -eq (Get-JsonPropertyValue -Object $powerShell7Profile -Name commandline) -and [string](Get-JsonPropertyValue -Object $powerShell7Profile -Name source) -ne 'Windows.Terminal.PowershellCore') {
|
||||||
|
Set-JsonPropertyValue -Object $powerShell7Profile -Name commandline -Value 'pwsh.exe'
|
||||||
|
}
|
||||||
|
Set-JsonPropertyValue -Object $powerShell7Profile -Name name -Value 'PowerShell 7'
|
||||||
|
Set-JsonPropertyValue -Object $powerShell7Profile -Name hidden -Value $false
|
||||||
|
Set-JsonPropertyValue -Object $powerShell7Profile -Name startingDirectory -Value '%USERPROFILE%'
|
||||||
|
Set-JsonPropertyValue -Object $settings -Name defaultProfile -Value ([string](Get-JsonPropertyValue -Object $powerShell7Profile -Name guid))
|
||||||
|
|
||||||
|
if ($null -ne $legacyPowerShellIndex) {
|
||||||
|
$legacyPowerShellProfile = $profiles[$legacyPowerShellIndex]
|
||||||
|
Set-JsonPropertyValue -Object $legacyPowerShellProfile -Name name -Value 'Windows PowerShell 5.1 (Legacy)'
|
||||||
|
Set-JsonPropertyValue -Object $legacyPowerShellProfile -Name hidden -Value $false
|
||||||
|
}
|
||||||
|
|
||||||
|
$removedIndices = New-Object System.Collections.Generic.HashSet[int]
|
||||||
|
foreach ($candidateIndex in $powerShell7CandidateIndices) {
|
||||||
|
if ($candidateIndex -eq $powerShell7Index) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-IsDisposablePowerShell7Profile -Profile $profiles[$candidateIndex]) {
|
||||||
|
if ($removedIndices.Add($candidateIndex)) {
|
||||||
|
$changed = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderedProfiles = New-Object System.Collections.Generic.List[object]
|
||||||
|
$addedIndices = New-Object System.Collections.Generic.HashSet[int]
|
||||||
|
|
||||||
|
function Add-ProfileByIndex {
|
||||||
|
param(
|
||||||
|
[int]$Index
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($Index -lt 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($removedIndices.Contains($Index)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($addedIndices.Add($Index)) {
|
||||||
|
$orderedProfiles.Add($profiles[$Index])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Add-ProfileByIndex -Index $powerShell7Index
|
||||||
|
if ($null -ne $legacyPowerShellIndex) {
|
||||||
|
Add-ProfileByIndex -Index $legacyPowerShellIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i = 0; $i -lt $profiles.Count; $i++) {
|
||||||
|
Add-ProfileByIndex -Index $i
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderedProfilesArray = @($orderedProfiles.ToArray())
|
||||||
|
if ((ConvertTo-Json $profiles -Depth 100 -Compress) -ne (ConvertTo-Json $orderedProfilesArray -Depth 100 -Compress)) {
|
||||||
|
$changed = $true
|
||||||
|
}
|
||||||
|
$settings.profiles.list = $orderedProfilesArray
|
||||||
|
|
||||||
|
if (-not $changed) {
|
||||||
|
Write-Host 'Windows Terminal settings already match the managed baseline.'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$backupPath = '{0}.bak-{1}' -f $settingsPath, (Get-Date -Format 'yyyyMMdd-HHmmss')
|
||||||
|
Copy-Item -LiteralPath $settingsPath -Destination $backupPath -Force
|
||||||
|
$settings | ConvertTo-Json -Depth 100 | Set-Content -LiteralPath $settingsPath -Encoding utf8
|
||||||
|
Write-Host "Updated Windows Terminal settings: $settingsPath"
|
||||||
|
Write-Host "Backup saved to: $backupPath"
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
if (-not $IsWindows) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$GlobalGitConfig = Join-Path $HOME '.gitconfig'
|
||||||
|
$LocalGitConfig = Join-Path $HOME '.gitconfig.local'
|
||||||
|
$BackupPath = '{0}.pre-chezmoi.bak-{1}' -f $GlobalGitConfig, (Get-Date -Format 'yyyyMMdd-HHmmss')
|
||||||
|
$ManagedStub = @'
|
||||||
|
[include]
|
||||||
|
path = ~/.config/git/config
|
||||||
|
|
||||||
|
[include]
|
||||||
|
path = ~/.gitconfig.local
|
||||||
|
'@
|
||||||
|
|
||||||
|
$ManagedKeys = @(
|
||||||
|
'core.autocrlf',
|
||||||
|
'core.eol',
|
||||||
|
'core.quotepath',
|
||||||
|
'core.longpaths',
|
||||||
|
'fetch.prune',
|
||||||
|
'pull.ff',
|
||||||
|
'init.defaultBranch'
|
||||||
|
)
|
||||||
|
|
||||||
|
function Test-ManagedGitStub {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$Content
|
||||||
|
)
|
||||||
|
|
||||||
|
$NormalizedContent = ($Content -replace "`r", '').Trim()
|
||||||
|
$NormalizedStub = ($ManagedStub -replace "`r", '').Trim()
|
||||||
|
return $NormalizedContent -eq $NormalizedStub
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path -LiteralPath $GlobalGitConfig)) {
|
||||||
|
if (-not (Test-Path -LiteralPath $LocalGitConfig)) {
|
||||||
|
New-Item -ItemType File -Path $LocalGitConfig -Force | Out-Null
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$CurrentContent = Get-Content -LiteralPath $GlobalGitConfig -Raw
|
||||||
|
if (Test-ManagedGitStub -Content $CurrentContent) {
|
||||||
|
if (-not (Test-Path -LiteralPath $LocalGitConfig)) {
|
||||||
|
New-Item -ItemType File -Path $LocalGitConfig -Force | Out-Null
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path -LiteralPath $LocalGitConfig)) {
|
||||||
|
Copy-Item -LiteralPath $GlobalGitConfig -Destination $BackupPath -Force
|
||||||
|
Copy-Item -LiteralPath $GlobalGitConfig -Destination $LocalGitConfig -Force
|
||||||
|
|
||||||
|
foreach ($Key in $ManagedKeys) {
|
||||||
|
git config --file $LocalGitConfig --unset-all $Key 2>$null
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Migrated existing ~/.gitconfig to ~/.gitconfig.local"
|
||||||
|
Write-Host "Backup saved to: $BackupPath"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Copy-Item -LiteralPath $GlobalGitConfig -Destination $BackupPath -Force
|
||||||
|
Write-Warning "~/.gitconfig.local already exists; current ~/.gitconfig was backed up before managed stub overwrite."
|
||||||
|
Write-Host "Backup saved to: $BackupPath"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Keep the live PowerShell 7 profile tiny and stable.
|
||||||
|
$ManagedProfile = Join-Path $HOME '.config\powershell\profile.ps1'
|
||||||
|
|
||||||
|
if (Test-Path -LiteralPath $ManagedProfile) {
|
||||||
|
. $ManagedProfile
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[core]
|
||||||
|
autocrlf = false
|
||||||
|
eol = lf
|
||||||
|
quotepath = false
|
||||||
|
longpaths = true
|
||||||
|
|
||||||
|
[fetch]
|
||||||
|
prune = true
|
||||||
|
|
||||||
|
[pull]
|
||||||
|
ff = only
|
||||||
|
|
||||||
|
[init]
|
||||||
|
defaultBranch = main
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
# Keep PowerShell 7 console text I/O on UTF-8 for predictable native tool behavior.
|
||||||
|
if ($IsWindows -and $PSVersionTable.PSEdition -eq 'Core' -and $Host.Name -eq 'ConsoleHost') {
|
||||||
|
chcp 65001 > $null
|
||||||
|
$Utf8NoBom = New-Object System.Text.UTF8Encoding($false)
|
||||||
|
[Console]::InputEncoding = $Utf8NoBom
|
||||||
|
[Console]::OutputEncoding = $Utf8NoBom
|
||||||
|
$OutputEncoding = $Utf8NoBom
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep interactive editing comfortable without depending on extra prompt frameworks.
|
||||||
|
if (
|
||||||
|
$Host.Name -eq 'ConsoleHost' -and
|
||||||
|
-not [Console]::IsOutputRedirected -and
|
||||||
|
$Host.UI.SupportsVirtualTerminal -and
|
||||||
|
(Get-Module -ListAvailable -Name PSReadLine)
|
||||||
|
) {
|
||||||
|
Import-Module PSReadLine -ErrorAction SilentlyContinue
|
||||||
|
Set-PSReadLineOption -PredictionSource History -ErrorAction SilentlyContinue
|
||||||
|
Set-PSReadLineOption -PredictionViewStyle ListView -ErrorAction SilentlyContinue
|
||||||
|
Set-PSReadLineOption -HistoryNoDuplicates:$true -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
function Reload-Profile {
|
||||||
|
. $PROFILE
|
||||||
|
}
|
||||||
|
|
||||||
|
function which {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$Name
|
||||||
|
)
|
||||||
|
|
||||||
|
Get-Command -Name $Name -All | Select-Object CommandType, Name, Source
|
||||||
|
}
|
||||||
|
|
||||||
|
function touch {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true, ValueFromRemainingArguments = $true)]
|
||||||
|
[string[]]$Path
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach ($Item in $Path) {
|
||||||
|
if (Test-Path -LiteralPath $Item) {
|
||||||
|
(Get-Item -LiteralPath $Item).LastWriteTime = Get-Date
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
New-Item -ItemType File -Path $Item -Force | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mkcd {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$Path
|
||||||
|
)
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Path $Path -Force | Out-Null
|
||||||
|
Set-Location -Path $Path
|
||||||
|
}
|
||||||
|
|
||||||
|
function open {
|
||||||
|
param(
|
||||||
|
[string]$Path = '.'
|
||||||
|
)
|
||||||
|
|
||||||
|
Invoke-Item -Path $Path
|
||||||
|
}
|
||||||
|
|
||||||
|
function croot {
|
||||||
|
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Error 'git is not available in PATH.'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$Root = git rev-parse --show-toplevel 2>$null
|
||||||
|
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($Root)) {
|
||||||
|
Write-Error 'Not inside a Git repository.'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-Location -Path $Root.Trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Get-Command wt -ErrorAction SilentlyContinue) {
|
||||||
|
function wt-here {
|
||||||
|
wt -d (Get-Location).ProviderPath
|
||||||
|
}
|
||||||
|
|
||||||
|
function wt-tab-here {
|
||||||
|
wt -w 0 new-tab -d (Get-Location).ProviderPath
|
||||||
|
}
|
||||||
|
|
||||||
|
function wt-split-here {
|
||||||
|
wt -w 0 split-pane -d (Get-Location).ProviderPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function codevpn {
|
||||||
|
$PreviousHttpProxy = $env:HTTP_PROXY
|
||||||
|
$PreviousHttpsProxy = $env:HTTPS_PROXY
|
||||||
|
|
||||||
|
try {
|
||||||
|
$env:HTTP_PROXY = 'http://127.0.0.1:12334'
|
||||||
|
$env:HTTPS_PROXY = 'http://127.0.0.1:12334'
|
||||||
|
code .
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
$env:HTTP_PROXY = $PreviousHttpProxy
|
||||||
|
$env:HTTPS_PROXY = $PreviousHttpsProxy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep stable hooks for machine-local overrides and future managed fragments.
|
||||||
|
$ExtraProfile = Join-Path $HOME '.config\powershell\profile.extra.ps1'
|
||||||
|
if (Test-Path -LiteralPath $ExtraProfile) {
|
||||||
|
. $ExtraProfile
|
||||||
|
}
|
||||||
|
|
||||||
|
$ExtraProfileDir = Join-Path $HOME '.config\powershell\profile.d'
|
||||||
|
if (Test-Path -LiteralPath $ExtraProfileDir) {
|
||||||
|
foreach ($ProfileFragment in (Get-ChildItem -Path $ExtraProfileDir -Filter '*.ps1' -File | Sort-Object Name)) {
|
||||||
|
. $ProfileFragment.FullName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Import the Chocolatey Profile that contains the necessary code to enable
|
||||||
|
# tab-completions to function for `choco`.
|
||||||
|
# Be aware that if you are missing these lines from your profile, tab completion
|
||||||
|
# for `choco` will not function.
|
||||||
|
# See https://ch0.co/tab-completion for details.
|
||||||
|
$ChocolateyProfile = "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
|
||||||
|
if (Test-Path -LiteralPath $ChocolateyProfile) {
|
||||||
|
Import-Module $ChocolateyProfile
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
[include]
|
||||||
|
path = ~/.config/git/config
|
||||||
|
|
||||||
|
[include]
|
||||||
|
path = ~/.gitconfig.local
|
||||||
Reference in new issue
Block a user