mirror of
https://oauth2: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@github.com/m1ngsama/chopsticks.git
synced 2026-05-10 19:10:59 +08:00
Compare commits
No commits in common. "97ca2be139553be185cd8c3e724a4c862d4af2b1" and "4fb20177ef66d1aa17cc06cf5e2be1c9ee640aca" have entirely different histories.
97ca2be139
...
4fb20177ef
26 changed files with 1771 additions and 1811 deletions
23
.github/ISSUE_TEMPLATE/bug_report.md
vendored
23
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -1,23 +0,0 @@
|
||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Something broken or unexpected
|
|
||||||
labels: bug
|
|
||||||
---
|
|
||||||
|
|
||||||
**What happened**
|
|
||||||
|
|
||||||
|
|
||||||
**What you expected**
|
|
||||||
|
|
||||||
|
|
||||||
**Steps to reproduce**
|
|
||||||
1.
|
|
||||||
2.
|
|
||||||
3.
|
|
||||||
|
|
||||||
**Environment**
|
|
||||||
- OS:
|
|
||||||
- Vim version (`vim --version | head -1`):
|
|
||||||
- Terminal:
|
|
||||||
- SSH: yes / no
|
|
||||||
- TTY mode (`echo g:is_tty` inside vim):
|
|
||||||
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
|
@ -1,14 +0,0 @@
|
||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest a plugin, mapping, or improvement
|
|
||||||
labels: enhancement
|
|
||||||
---
|
|
||||||
|
|
||||||
**What problem does this solve?**
|
|
||||||
|
|
||||||
|
|
||||||
**What does the solution look like?**
|
|
||||||
|
|
||||||
|
|
||||||
**Alternatives you considered**
|
|
||||||
|
|
||||||
13
.github/PULL_REQUEST_TEMPLATE.md
vendored
13
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
|
@ -1,13 +0,0 @@
|
||||||
## What
|
|
||||||
|
|
||||||
<!-- One sentence: what does this PR do? -->
|
|
||||||
|
|
||||||
## Why
|
|
||||||
|
|
||||||
<!-- Why is this change needed? -->
|
|
||||||
|
|
||||||
## Test
|
|
||||||
|
|
||||||
- [ ] `vim --startuptime` shows no regression
|
|
||||||
- [ ] Tested on macOS / Linux
|
|
||||||
- [ ] `,?` cheat sheet still accurate
|
|
||||||
BIN
.github/demo.gif
vendored
BIN
.github/demo.gif
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 460 KiB |
47
.github/demo.tape
vendored
47
.github/demo.tape
vendored
|
|
@ -1,47 +0,0 @@
|
||||||
Output .github/demo.gif
|
|
||||||
Set Shell bash
|
|
||||||
Set FontSize 14
|
|
||||||
Set Width 960
|
|
||||||
Set Height 540
|
|
||||||
Set Theme "Builtin Solarized Dark"
|
|
||||||
Set TypingSpeed 50ms
|
|
||||||
Set Padding 10
|
|
||||||
|
|
||||||
Type "vim ~/.vim/modules/core.vim"
|
|
||||||
Enter
|
|
||||||
Sleep 1.5s
|
|
||||||
|
|
||||||
# Show the code with solarized theme and statusline
|
|
||||||
Sleep 1s
|
|
||||||
|
|
||||||
# Use Ctrl+p for fuzzy find
|
|
||||||
Type "\x10"
|
|
||||||
Sleep 1s
|
|
||||||
Type "lsp"
|
|
||||||
Sleep 1s
|
|
||||||
Escape
|
|
||||||
Sleep 0.5s
|
|
||||||
|
|
||||||
# Go to definition
|
|
||||||
Type "gg"
|
|
||||||
Sleep 0.3s
|
|
||||||
Type "/mapleader"
|
|
||||||
Enter
|
|
||||||
Sleep 1s
|
|
||||||
|
|
||||||
# Show cheat sheet
|
|
||||||
Type ",?"
|
|
||||||
Sleep 2s
|
|
||||||
Type "q"
|
|
||||||
Sleep 0.5s
|
|
||||||
|
|
||||||
# Open file browser
|
|
||||||
Type ",e"
|
|
||||||
Sleep 1.5s
|
|
||||||
Escape
|
|
||||||
Sleep 0.5s
|
|
||||||
|
|
||||||
# Quit
|
|
||||||
Type ":qa!"
|
|
||||||
Enter
|
|
||||||
Sleep 0.5s
|
|
||||||
66
.github/workflows/test.yml
vendored
66
.github/workflows/test.yml
vendored
|
|
@ -1,66 +0,0 @@
|
||||||
name: test
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
startup:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macos-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install Vim
|
|
||||||
run: |
|
|
||||||
if [ "$(uname)" = "Darwin" ]; then
|
|
||||||
brew install vim
|
|
||||||
else
|
|
||||||
sudo apt-get update && sudo apt-get install -y vim
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Install vim-plug
|
|
||||||
run: |
|
|
||||||
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
|
|
||||||
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
|
|
||||||
|
|
||||||
- name: Symlink config
|
|
||||||
run: |
|
|
||||||
ln -sf "$PWD" ~/.vim/chopsticks-src
|
|
||||||
ln -sf "$PWD/.vimrc" ~/.vimrc
|
|
||||||
mkdir -p ~/.vim/modules
|
|
||||||
cp modules/*.vim ~/.vim/modules/
|
|
||||||
|
|
||||||
- name: Install plugins
|
|
||||||
run: vim -es -u .vimrc -c 'PlugInstall --sync' -c 'qa!' 2>&1 || true
|
|
||||||
|
|
||||||
- name: Test startup
|
|
||||||
run: |
|
|
||||||
vim -u .vimrc -es -N -c 'qa!' 2>&1
|
|
||||||
echo "Vim exited cleanly"
|
|
||||||
|
|
||||||
- name: Verify modules load
|
|
||||||
run: |
|
|
||||||
vim -u .vimrc -N -c 'redir! > /tmp/test.txt | echo len(g:plugs) | redir END | qa!' 2>/dev/null
|
|
||||||
PLUGS=$(cat /tmp/test.txt | tr -d '[:space:]')
|
|
||||||
echo "Plugins registered: $PLUGS"
|
|
||||||
if [ "$PLUGS" -lt 25 ]; then
|
|
||||||
echo "FAIL: expected 25+ plugins, got $PLUGS"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Measure startup time
|
|
||||||
run: |
|
|
||||||
vim -u .vimrc --startuptime /tmp/startup.log -c 'qa!' 2>/dev/null
|
|
||||||
tail -1 /tmp/startup.log
|
|
||||||
|
|
||||||
shellcheck:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Shellcheck install.sh
|
|
||||||
run: shellcheck install.sh get.sh
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,3 +1,5 @@
|
||||||
|
*.json
|
||||||
|
!coc-settings.json
|
||||||
*.swp
|
*.swp
|
||||||
*.swo
|
*.swo
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# Contributing
|
|
||||||
|
|
||||||
## Rules
|
|
||||||
|
|
||||||
1. **No Node.js dependencies.** The LSP engine is pure VimScript. Some language servers need Node — that's fine. The config itself must not.
|
|
||||||
2. **Startup matters.** Run `vim --startuptime /tmp/s.log -c qa!` before and after. If your change adds >1ms, it needs a good reason.
|
|
||||||
3. **Works on TTY.** Test over SSH. If it breaks in a terminal without true color, fix it or gate it behind `g:is_tty`.
|
|
||||||
4. **One module, one concern.** Don't put git config in lsp.vim.
|
|
||||||
|
|
||||||
## Adding a plugin
|
|
||||||
|
|
||||||
1. Add the `Plug` line to `modules/plugins.vim`
|
|
||||||
2. If it's not needed at startup, lazy-load it: `Plug 'foo/bar', { 'on': 'FooCommand' }`
|
|
||||||
3. Put config in the appropriate module
|
|
||||||
4. Update the cheat sheet in `modules/tools.vim` if you add keybindings
|
|
||||||
5. Test on both macOS and Linux
|
|
||||||
|
|
||||||
## Reporting bugs
|
|
||||||
|
|
||||||
Open an issue. Include:
|
|
||||||
- OS and Vim version
|
|
||||||
- Whether you're on SSH/TTY
|
|
||||||
- Steps to reproduce
|
|
||||||
|
|
||||||
## Code style
|
|
||||||
|
|
||||||
- Named augroups with `autocmd!`
|
|
||||||
- No comments explaining *what* — only *why*
|
|
||||||
- `exists('g:plugs["..."]')` guards for plugin-dependent config
|
|
||||||
- Test with `vim -u .vimrc --startuptime /tmp/s.log -c qa!`
|
|
||||||
261
QUICKSTART.md
261
QUICKSTART.md
|
|
@ -1,96 +1,221 @@
|
||||||
# Quick Start
|
# Quick Start
|
||||||
|
|
||||||
Five minutes from zero to a working Vim setup.
|
Five minutes from zero to a working Vim environment.
|
||||||
|
|
||||||
## Install
|
---
|
||||||
|
|
||||||
|
## Step 0: Vim Basics (2 minutes)
|
||||||
|
|
||||||
|
> **When confused, press `Esc` until things feel normal again.**
|
||||||
|
|
||||||
|
Vim is **modal** — the keyboard behaves differently depending on which mode you are in.
|
||||||
|
|
||||||
|
| Mode | Purpose | Enter | Leave |
|
||||||
|
|------|---------|-------|-------|
|
||||||
|
| **Normal** | Navigate and run commands | default on startup | — |
|
||||||
|
| **Insert** | Type text | `i` before / `a` after / `o` new line | `Esc` or `jk` |
|
||||||
|
| **Visual** | Select text | `v` char / `V` line | `Esc` |
|
||||||
|
|
||||||
|
### 4 commands that get you out of any jam
|
||||||
|
|
||||||
|
| Command | Action |
|
||||||
|
|---------|--------|
|
||||||
|
| `Esc` or `jk` | Exit insert / visual mode → Normal |
|
||||||
|
| `:q!` then `Enter` | Force quit without saving |
|
||||||
|
| `,x` | Save and quit |
|
||||||
|
| `,w` or `Ctrl+s` | Save |
|
||||||
|
|
||||||
|
Once in Normal mode, press `,?` to open the cheat sheet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 1: Install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
Open vim. Plugins install automatically on first launch (30-60s). Restart vim.
|
Traditional:
|
||||||
|
```bash
|
||||||
## Modes
|
git clone https://github.com/m1ngsama/chopsticks.git ~/.vim
|
||||||
|
cd ~/.vim && ./install.sh
|
||||||
| Mode | Enter | Leave |
|
|
||||||
|------|-------|-------|
|
|
||||||
| Normal | startup default | — |
|
|
||||||
| Insert | `i` / `a` / `o` | `Esc` or `jk` |
|
|
||||||
| Visual | `v` / `V` | `Esc` |
|
|
||||||
|
|
||||||
## Survival
|
|
||||||
|
|
||||||
```
|
|
||||||
Esc / jk back to Normal
|
|
||||||
,w save
|
|
||||||
,x save + quit
|
|
||||||
:q! force quit
|
|
||||||
Ctrl+s save from any mode
|
|
||||||
,? cheat sheet
|
|
||||||
:ChopsticksLearn interactive tutorial
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Find things
|
Non-interactive / CI:
|
||||||
|
```bash
|
||||||
```
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --yes
|
||||||
Ctrl+p fuzzy find file (git-aware)
|
|
||||||
,rg ripgrep project
|
|
||||||
,b search buffers
|
|
||||||
,fh recent files
|
|
||||||
,e file browser
|
|
||||||
,, last file
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Write code
|
---
|
||||||
|
|
||||||
```
|
## Step 2: Open Vim
|
||||||
gd go to definition
|
|
||||||
K hover docs
|
```bash
|
||||||
,rn rename symbol
|
vim # startup dashboard (recent files + sessions)
|
||||||
,ca code action
|
vim . # startup dashboard, current directory listed
|
||||||
,f format
|
vim myfile # edit a specific file
|
||||||
,cr run current file
|
|
||||||
Tab / S-Tab cycle completions
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Install language servers with `:LspInstallServer` (auto-detects filetype).
|
> **First launch:** Vim will automatically install plugins on the first open
|
||||||
|
> (takes 30–60 seconds depending on network). This is normal — wait for it
|
||||||
|
> to finish, then restart Vim.
|
||||||
|
|
||||||
## Git
|
---
|
||||||
|
|
||||||
```
|
## Step 3: Set Up LSP
|
||||||
,gs status (s=stage, cc=commit)
|
|
||||||
,gd diff
|
Open a source file, then run:
|
||||||
,gb blame
|
|
||||||
,gp push
|
```vim
|
||||||
]x / [x conflict markers
|
:LspInstallServer
|
||||||
```
|
```
|
||||||
|
|
||||||
## Edit
|
This auto-detects the filetype and installs the correct language server.
|
||||||
|
vim-lsp itself runs on pure VimScript — no Node.js required. However,
|
||||||
|
some language servers (JS/TS, HTML, CSS, JSON, YAML) are npm packages
|
||||||
|
that need Node.js to run. Python, Go, and Rust servers don't need it.
|
||||||
|
|
||||||
```
|
Check status:
|
||||||
s + 2 chars EasyMotion jump
|
```vim
|
||||||
gc toggle comment
|
:LspStatus
|
||||||
cs"' change surrounding " to '
|
|
||||||
Alt+j / Alt+k move line
|
|
||||||
,u undo tree
|
|
||||||
,y clipboard yank
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Navigate
|
**Markdown LSP** (`marksman`) needs a standalone binary:
|
||||||
|
```bash
|
||||||
```
|
brew install marksman # macOS
|
||||||
Ctrl+h/j/k/l splits + tmux panes
|
sudo pacman -S marksman # Arch
|
||||||
,h / ,l prev / next buffer
|
# install.sh handles this automatically
|
||||||
,z maximize window
|
|
||||||
,tv / ,th terminal
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Write prose
|
---
|
||||||
|
|
||||||
|
## The Keys That Matter
|
||||||
|
|
||||||
```
|
```
|
||||||
,zen zen mode (Goyo + Limelight)
|
,? Open cheat sheet (all bindings in one place)
|
||||||
,mp markdown preview in browser
|
Esc / jk Exit insert mode → Normal
|
||||||
,mt table of contents
|
Ctrl+s Save
|
||||||
|
Ctrl+p Fuzzy find file
|
||||||
|
,e File browser (netrw)
|
||||||
|
gd Go to definition
|
||||||
|
K Show documentation
|
||||||
|
[g / ]g Prev / next LSP diagnostic
|
||||||
|
,rn Rename symbol
|
||||||
|
,rG Search word under cursor (ripgrep)
|
||||||
|
,gs Git status
|
||||||
|
,mp Markdown live preview in browser
|
||||||
|
,w / ,x Save / Save+quit
|
||||||
```
|
```
|
||||||
|
|
||||||
See [README](README.md) for the full reference. See the [wiki](https://github.com/m1ngsama/chopsticks/wiki) for deep dives.
|
---
|
||||||
|
|
||||||
|
## Daily Use
|
||||||
|
|
||||||
|
### Navigate Code
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `gd` | Go to definition |
|
||||||
|
| `gy` | Go to type definition |
|
||||||
|
| `gi` | Go to implementation |
|
||||||
|
| `gr` | List references |
|
||||||
|
| `K` | Docs for symbol under cursor |
|
||||||
|
| `Ctrl+o` | Jump back |
|
||||||
|
| `Ctrl+i` | Jump forward |
|
||||||
|
|
||||||
|
### Edit Code
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `Tab` | Select next completion item |
|
||||||
|
| `Enter` | Confirm completion |
|
||||||
|
| `gc` | Toggle comment (visual mode too) |
|
||||||
|
| `cs"'` | Change surrounding `"` to `'` |
|
||||||
|
| `ds(` | Delete surrounding `(` |
|
||||||
|
| `s` + 2 chars | EasyMotion: jump anywhere |
|
||||||
|
|
||||||
|
### Manage Errors
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `]g` | Jump to next LSP diagnostic |
|
||||||
|
| `[g` | Jump to previous diagnostic |
|
||||||
|
| `K` | Read the error message |
|
||||||
|
| `,ca` | Apply code action / auto-fix |
|
||||||
|
|
||||||
|
### Markdown
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `,mp` | Open live preview in browser |
|
||||||
|
| `,mt` | Table of contents (side window) |
|
||||||
|
| `zr` / `zm` | Unfold / fold all headings |
|
||||||
|
|
||||||
|
Formatting in the buffer is live: `**bold**` renders as bold,
|
||||||
|
headings hide their `#` markers. Raw syntax reappears when
|
||||||
|
the cursor enters that line.
|
||||||
|
|
||||||
|
### Git Workflow
|
||||||
|
|
||||||
|
```
|
||||||
|
,gs git status (stage with 's', commit with 'cc')
|
||||||
|
,gd diff current file
|
||||||
|
,gb blame
|
||||||
|
,gc commit
|
||||||
|
,gp push
|
||||||
|
,gl pull
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Reference Card
|
||||||
|
|
||||||
|
```
|
||||||
|
BASICS
|
||||||
|
Esc / jk Exit insert mode → Normal
|
||||||
|
Ctrl+s Save
|
||||||
|
:q! + Enter Emergency quit
|
||||||
|
,? Open cheat sheet
|
||||||
|
|
||||||
|
FILES
|
||||||
|
Ctrl+p Fuzzy find file (git-aware)
|
||||||
|
,e File browser (netrw)
|
||||||
|
,b Search open buffers
|
||||||
|
,rg Search file contents (ripgrep)
|
||||||
|
,rG Ripgrep word under cursor
|
||||||
|
,w Save | ,q Quit | ,x Save+quit
|
||||||
|
,wa Save all buffers
|
||||||
|
,, Switch to last file
|
||||||
|
|
||||||
|
CODE
|
||||||
|
gd Definition | gy Type def | gi Impl | gr References
|
||||||
|
K Show documentation
|
||||||
|
[g / ]g Prev / next LSP diagnostic
|
||||||
|
[e / ]e Prev / next ALE error
|
||||||
|
,rn Rename symbol
|
||||||
|
,ca Code action
|
||||||
|
,f Format buffer / selection
|
||||||
|
|
||||||
|
MARKDOWN
|
||||||
|
,mp Live preview | ,mt Table of contents
|
||||||
|
|
||||||
|
GIT
|
||||||
|
,gs Status | ,gd Diff | ,gb Blame
|
||||||
|
,gc Commit | ,gp Push | ,gl Pull
|
||||||
|
|
||||||
|
WINDOWS / PANES
|
||||||
|
Ctrl+h/j/k/l Move between Vim windows or tmux panes
|
||||||
|
,h / ,l Prev / next buffer
|
||||||
|
,tv / ,th Terminal (vertical / horizontal)
|
||||||
|
Esc Esc Exit terminal mode
|
||||||
|
,u Undo tree
|
||||||
|
|
||||||
|
SEARCH
|
||||||
|
/text Forward | ?text Backward | n next | N prev
|
||||||
|
// Search visually selected text
|
||||||
|
,* Replace word under cursor (file-wide)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
See [README.md](README.md) for the complete reference.
|
||||||
|
|
|
||||||
536
README.md
536
README.md
|
|
@ -1,22 +1,14 @@
|
||||||
<p align="center">
|
# chopsticks
|
||||||
<img src=".github/demo.gif" alt="chopsticks demo" width="720">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h1 align="center">chopsticks</h1>
|
> Flowing vim for any machine — SSH servers included.
|
||||||
|
> Solarized · vim-lsp (no Node.js) · Markdown-first · One-command install.
|
||||||
|
|
||||||
<p align="center">
|
[](LICENSE)
|
||||||
<strong>Vim for engineers. 29 plugins, 19ms startup, works over SSH.</strong>
|
[](https://www.vim.org/)
|
||||||
</p>
|
[](#installation)
|
||||||
|
[](https://github.com/m1ngsama/chopsticks/releases)
|
||||||
<p align="center">
|
[](https://github.com/m1ngsama/chopsticks/commits/main)
|
||||||
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="MIT License"></a>
|
[](https://github.com/m1ngsama/chopsticks/stargazers)
|
||||||
<a href="https://www.vim.org/"><img src="https://img.shields.io/badge/Vim-8.0%2B-brightgreen?style=flat-square" alt="Vim 8.0+"></a>
|
|
||||||
<a href="#install"><img src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey?style=flat-square" alt="Platform"></a>
|
|
||||||
<a href="https://github.com/m1ngsama/chopsticks/actions"><img src="https://img.shields.io/github/actions/workflow/status/m1ngsama/chopsticks/test.yml?style=flat-square&label=tests" alt="Tests"></a>
|
|
||||||
<a href="https://github.com/m1ngsama/chopsticks/releases"><img src="https://img.shields.io/github/v/release/m1ngsama/chopsticks?style=flat-square&color=orange" alt="Release"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
||||||
|
|
@ -24,157 +16,437 @@ curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | b
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Why
|
## Contents
|
||||||
|
|
||||||
You SSH into a server. You need to edit code. You want LSP, fuzzy find, git integration, format-on-save — not a 20-minute setup.
|
- [Design Principles](#design-principles)
|
||||||
|
- [Requirements](#requirements)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [LSP](#lsp)
|
||||||
|
- [Key Mappings](#key-mappings)
|
||||||
|
- [Markdown](#markdown)
|
||||||
|
- [Features](#features)
|
||||||
|
- [Plugins](#plugins)
|
||||||
|
- [Customization](#customization)
|
||||||
|
- [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
chopsticks gives you a production-ready Vim config in one command. Pure VimScript — no Node.js for the core. Degrades gracefully on TTY. Works the same on your MacBook and your headless Arch box.
|
---
|
||||||
|
|
||||||
**19ms startup** with 29 plugins, LSP, linting, and a hand-built statusline. Faster than most people's empty vimrc.
|
## Design Principles
|
||||||
|
|
||||||
## What's in the box
|
| Principle | What it means |
|
||||||
|
|-----------|--------------|
|
||||||
|
| **Flowing writing** | Every plugin earns its place by reducing interruptions to thought |
|
||||||
|
| **No Node.js** | vim-lsp runs on pure VimScript — works on any machine, including SSH servers |
|
||||||
|
| **Solarized** | One palette, everywhere — vim statusline matches tmux bar exactly |
|
||||||
|
| **TTY-aware** | SSH and console environments degrade gracefully without breaking |
|
||||||
|
| **KISS** | No icon fonts, no Nerd Font glyphs — plain ASCII throughout |
|
||||||
|
|
||||||
| | |
|
---
|
||||||
|-|-|
|
|
||||||
| **LSP** | completion, go-to-def, hover, rename, code actions — pure VimScript ([vim-lsp](https://github.com/prabirshrestha/vim-lsp)) |
|
|
||||||
| **Lint + format** | [ALE](https://github.com/dense-analysis/ale) runs black, prettier, gofmt, rustfmt on save |
|
|
||||||
| **Fuzzy find** | files, buffers, grep, tags, marks, commands — [FZF](https://github.com/junegunn/fzf.vim) |
|
|
||||||
| **Git** | status, diff, blame, push, pull, conflict markers — [fugitive](https://github.com/tpope/vim-fugitive) + [gitgutter](https://github.com/airblade/vim-gitgutter) |
|
|
||||||
| **Zen mode** | `,zen` — [Goyo](https://github.com/junegunn/goyo.vim) + [Limelight](https://github.com/junegunn/limelight.vim) |
|
|
||||||
| **Run file** | `,cr` — auto-detects Python, Go, Rust, JS, C, Shell, and more |
|
|
||||||
| **TTY-aware** | degrades gracefully on SSH, console, slow links — never breaks |
|
|
||||||
| **19ms startup** | lazy-loaded plugins, deferred LSP init, zero redundant work |
|
|
||||||
|
|
||||||
## Install
|
## Requirements
|
||||||
|
|
||||||
|
| Tool | Role |
|
||||||
|
|------|------|
|
||||||
|
| Vim 8.0+ | Required — `install.sh` installs it if missing |
|
||||||
|
| git | Required |
|
||||||
|
| curl | Required |
|
||||||
|
| ripgrep | Recommended — enables `,rg` project search |
|
||||||
|
| fzf | Recommended — enables `Ctrl+p` fuzzy finder |
|
||||||
|
| Node.js | Optional — enables npm formatters (prettier, eslint) |
|
||||||
|
|
||||||
|
`install.sh` detects your environment and installs missing dependencies.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### One command
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
Or manually:
|
Non-interactive / CI:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --yes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Git clone
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/m1ngsama/chopsticks.git ~/.vim
|
git clone https://github.com/m1ngsama/chopsticks.git ~/.vim
|
||||||
cd ~/.vim && ./install.sh
|
cd ~/.vim && ./install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Supports macOS (brew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf).
|
### What the installer does
|
||||||
|
|
||||||
First launch installs plugins automatically (30-60s). Restart vim when done.
|
1. Detects OS and package manager
|
||||||
|
2. Verifies or installs `curl`, `git`, `vim`
|
||||||
|
3. Backs up existing `~/.vimrc`, then symlinks `~/.vimrc → ~/.vim/.vimrc`
|
||||||
|
4. Installs vim-plug and runs `:PlugInstall`
|
||||||
|
5. Offers to install system tools (ripgrep, fzf, ctags, shellcheck, hadolint, marksman)
|
||||||
|
6. Offers to install npm formatters (prettier, eslint, etc.) — requires Node.js
|
||||||
|
7. Offers to install Python formatters/linters (black, isort, flake8, etc.)
|
||||||
|
8. Offers to install Go tools (gopls, goimports, staticcheck)
|
||||||
|
9. Offers to append vim-tmux-navigator bindings to `~/.tmux.conf`
|
||||||
|
|
||||||
## Keys
|
**Supported platforms:** macOS (Homebrew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf).
|
||||||
|
|
||||||
Leader: `,` — press `,?` for the full cheat sheet inside vim.
|
---
|
||||||
|
|
||||||
```
|
|
||||||
Ctrl+p fuzzy find file gd go to definition
|
|
||||||
,rg ripgrep project K hover docs
|
|
||||||
,gs git status ,cr run current file
|
|
||||||
,zen zen mode ,f format
|
|
||||||
,w save ,q quit
|
|
||||||
jk exit insert mode ,? cheat sheet
|
|
||||||
```
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><strong>All keybindings</strong></summary>
|
|
||||||
|
|
||||||
### Files
|
|
||||||
|
|
||||||
`Ctrl+p` find | `,b` buffers | `,rg` grep | `,rG` grep word | `,fh` recent | `,e` browser | `,,` last file
|
|
||||||
|
|
||||||
### Code
|
|
||||||
|
|
||||||
`gd` def | `gy` type | `gi` impl | `gr` refs | `K` docs | `[g` `]g` diagnostics | `,rn` rename | `,ca` action | `,o` outline | `,cr` run
|
|
||||||
|
|
||||||
### Edit
|
|
||||||
|
|
||||||
`s`+2ch jump | `gc` comment | `cs"'` surround | `Alt+j/k` move line | `,u` undo tree | `,y` clipboard | `,*` replace word
|
|
||||||
|
|
||||||
### Git
|
|
||||||
|
|
||||||
`,gs` status | `,gd` diff | `,gb` blame | `,gc` commit | `,gp` push | `]x` `[x` conflict
|
|
||||||
|
|
||||||
### Windows
|
|
||||||
|
|
||||||
`Ctrl+hjkl` navigate (+ tmux) | `,z` maximize | `,h` `,l` buffers | `,tv` terminal | `Esc Esc` exit terminal
|
|
||||||
|
|
||||||
### Writing
|
|
||||||
|
|
||||||
`,zen` zen mode | `,mp` markdown preview | `,mt` table of contents
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## LSP
|
## LSP
|
||||||
|
|
||||||
```vim
|
Code intelligence is provided by **vim-lsp** — a pure VimScript LSP client with no
|
||||||
:LspInstallServer " auto-detects filetype
|
Node.js dependency. It works on any machine, including servers accessed via SSH.
|
||||||
:LspStatus " check what's running
|
|
||||||
```
|
|
||||||
|
|
||||||
pylsp, gopls, rust-analyzer, clangd, marksman, sqls — no Node.js. JS/TS servers need Node.
|
Install a language server for the current file:
|
||||||
|
|
||||||
ALE and vim-lsp coexist cleanly (`ale_disable_lsp=1`). ALE handles linting + formatting. vim-lsp handles everything else.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
```
|
|
||||||
~/.vim/
|
|
||||||
├── .vimrc thin loader (12 lines)
|
|
||||||
├── modules/
|
|
||||||
│ ├── env.vim TTY detection, truecolor
|
|
||||||
│ ├── plugins.vim vim-plug + 29 plugins
|
|
||||||
│ ├── core.vim settings, keymaps, performance
|
|
||||||
│ ├── ui.vim solarized, statusline, startify
|
|
||||||
│ ├── editing.vim easymotion, yank highlight
|
|
||||||
│ ├── navigation.vim fzf, netrw, windows, terminal
|
|
||||||
│ ├── lsp.vim vim-lsp, asyncomplete
|
|
||||||
│ ├── lint.vim ale, format-on-save
|
|
||||||
│ ├── git.vim fugitive, gitgutter
|
|
||||||
│ ├── writing.vim markdown, previm, zen mode
|
|
||||||
│ ├── languages.vim vim-go, filetype settings
|
|
||||||
│ └── tools.vim cheat sheet, run file, helpers
|
|
||||||
└── tutor/
|
|
||||||
└── chopsticks.tutor
|
|
||||||
```
|
|
||||||
|
|
||||||
Each module is self-contained. Comment out one line in `.vimrc` to disable it. Add your own with `call s:load('mine')`.
|
|
||||||
|
|
||||||
## Learn
|
|
||||||
|
|
||||||
```vim
|
```vim
|
||||||
:ChopsticksLearn " interactive tutorial — 10 lessons
|
:LspInstallServer " auto-detects filetype and installs the correct server
|
||||||
,? " cheat sheet (every binding)
|
:LspStatus " check server status
|
||||||
```
|
```
|
||||||
|
|
||||||
## Performance
|
Supported languages and their servers:
|
||||||
|
|
||||||
| Metric | Value |
|
| Language | Server |
|
||||||
|--------|-------|
|
|----------|--------|
|
||||||
| Startup time | **19ms** (29 plugins loaded) |
|
| Python | pylsp / pyright |
|
||||||
| Lazy-loaded | 8 plugins (on command or filetype) |
|
| JavaScript / TypeScript | typescript-language-server |
|
||||||
| Built-in plugins skipped | 10 (gzip, tar, zip, vimball, etc.) |
|
| Go | gopls |
|
||||||
| Runtime lint delay | 200ms (no thrashing during edits) |
|
| Rust | rust-analyzer |
|
||||||
| Large file threshold | 10MB (auto-disables syntax + undo) |
|
| C / C++ | clangd |
|
||||||
| TTY large file | 500KB (syntax disabled) |
|
| Shell | bash-language-server |
|
||||||
|
| HTML | vscode-html-language-server |
|
||||||
|
| CSS / SCSS | vscode-css-language-server |
|
||||||
|
| JSON | vscode-json-language-server |
|
||||||
|
| YAML | yaml-language-server |
|
||||||
|
| Markdown | marksman |
|
||||||
|
| SQL | sqls |
|
||||||
|
|
||||||
Measured with `vim --startuptime`. We benchmark every change.
|
**Note:** While vim-lsp itself needs no Node.js, some language servers (TypeScript,
|
||||||
|
HTML, CSS, JSON, YAML) are npm packages that require Node.js to run. Python (pylsp),
|
||||||
|
Go (gopls), and Rust (rust-analyzer) language servers do not need Node.js.
|
||||||
|
|
||||||
|
**Markdown LSP** requires `marksman` as a standalone binary:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
brew install marksman # macOS
|
||||||
|
sudo pacman -S marksman # Arch
|
||||||
|
# or: install.sh handles it automatically
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Mappings
|
||||||
|
|
||||||
|
**Leader key:** `,` (comma)
|
||||||
|
|
||||||
|
Press `,?` at any time to open the built-in cheat sheet.
|
||||||
|
|
||||||
|
### Files and Buffers
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `Ctrl+p` | Fuzzy file search — git-aware (FZF) |
|
||||||
|
| `,e` | Open netrw file browser |
|
||||||
|
| `,E` | Open netrw in vertical split |
|
||||||
|
| `,b` | Search open buffers (FZF) |
|
||||||
|
| `,rg` | Project-wide search (ripgrep + FZF) |
|
||||||
|
| `,rG` | Ripgrep word under cursor (fixed-string) |
|
||||||
|
| `,,` | Switch to last file |
|
||||||
|
| `,l` / `,h` | Next / previous buffer |
|
||||||
|
| `,bd` | Close current buffer (preserves window layout) |
|
||||||
|
| `,wa` | Save all open buffers |
|
||||||
|
| `,cd` | Change working directory to current file's directory |
|
||||||
|
|
||||||
|
### Code Intelligence (vim-lsp)
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `gd` | Go to definition |
|
||||||
|
| `gy` | Go to type definition |
|
||||||
|
| `gi` | Go to implementation |
|
||||||
|
| `gr` | Show references |
|
||||||
|
| `K` | Hover documentation |
|
||||||
|
| `[g` / `]g` | Previous / next LSP diagnostic |
|
||||||
|
| `[e` / `]e` | Previous / next ALE error |
|
||||||
|
| `,rn` | Rename symbol |
|
||||||
|
| `,f` | Format buffer / selection |
|
||||||
|
| `,ca` | Code action |
|
||||||
|
| `,o` | File outline (symbols) |
|
||||||
|
| `,ws` | Workspace symbols |
|
||||||
|
| `Tab` / `Shift+Tab` | Navigate completion popup |
|
||||||
|
| `Enter` | Confirm completion |
|
||||||
|
|
||||||
|
### Markdown
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `,mp` | Open live preview in browser (previm) |
|
||||||
|
| `,mt` | Table of contents (side window) |
|
||||||
|
| `zr` / `zm` | Unfold / fold all headings |
|
||||||
|
|
||||||
|
### Git (vim-fugitive)
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `,gs` | Git status |
|
||||||
|
| `,gc` | Git commit |
|
||||||
|
| `,gp` | Git push |
|
||||||
|
| `,gl` | Git pull |
|
||||||
|
| `,gd` | Git diff |
|
||||||
|
| `,gb` | Git blame |
|
||||||
|
|
||||||
|
### Editing
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `s` + 2 chars | EasyMotion — jump anywhere on screen |
|
||||||
|
| `gc` | Toggle comment (visual mode too) |
|
||||||
|
| `Space` | Toggle code fold |
|
||||||
|
| `Y` | Yank to end of line |
|
||||||
|
| `Ctrl+d` / `Ctrl+u` | Half-page scroll, cursor centred |
|
||||||
|
| `Alt+j` / `Alt+k` | Move line down / up (normal and visual) |
|
||||||
|
| `,u` | Undo tree (visual branch history) |
|
||||||
|
| `F2` | Toggle paste mode |
|
||||||
|
| `F3` / `F4` | Toggle line numbers / relative numbers |
|
||||||
|
| `F5` | Toggle undo tree |
|
||||||
|
| `F6` | Toggle invisible characters |
|
||||||
|
| `gV` | Reselect last paste |
|
||||||
|
| `//` | Search visual selection |
|
||||||
|
|
||||||
|
### Survival
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `jk` | Exit insert mode |
|
||||||
|
| `Esc` | Exit insert / visual mode |
|
||||||
|
| `jk` | Exit insert mode |
|
||||||
|
| `Ctrl+s` | Save (any mode) |
|
||||||
|
| `,w` | Save |
|
||||||
|
| `,x` | Save and quit |
|
||||||
|
| `,q` | Quit |
|
||||||
|
| `,?` | Open cheat sheet |
|
||||||
|
|
||||||
|
### Windows, Tabs, tmux
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `Ctrl+h/j/k/l` | Navigate Vim splits **and** tmux panes |
|
||||||
|
| `,tv` / `,th` | Open terminal (vertical / horizontal split) |
|
||||||
|
| `Esc Esc` | Exit terminal mode |
|
||||||
|
| `,tn` / `,tc` | New tab / close tab |
|
||||||
|
| `,tl` | Toggle to last tab |
|
||||||
|
| `,ev` / `,sv` | Edit / reload `~/.vimrc` |
|
||||||
|
| `,cp` / `,cf` | Copy file path / filename to clipboard |
|
||||||
|
| `,*` | Search and replace word under cursor |
|
||||||
|
| `,F` | Re-indent entire file |
|
||||||
|
| `,W` | Strip trailing whitespace |
|
||||||
|
| `,ms` | Open scratch markdown buffer |
|
||||||
|
| `,ss` | Toggle spell checking |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Markdown
|
||||||
|
|
||||||
|
chopsticks treats Markdown as a first-class language.
|
||||||
|
|
||||||
|
### In-buffer rendering (concealment)
|
||||||
|
|
||||||
|
`vim-markdown` hides syntax markers and renders formatting inline:
|
||||||
|
- `**bold**` displays as bold text
|
||||||
|
- `# Heading` hides the `#` characters
|
||||||
|
- Tables align automatically
|
||||||
|
|
||||||
|
The raw syntax reappears when the cursor enters that line.
|
||||||
|
|
||||||
|
### Live browser preview (previm)
|
||||||
|
|
||||||
|
```vim
|
||||||
|
,mp " open rendered preview in browser — updates on every save
|
||||||
|
```
|
||||||
|
|
||||||
|
No Node.js required. Uses `open` (macOS) or `xdg-open` (Linux).
|
||||||
|
|
||||||
|
### Table of contents
|
||||||
|
|
||||||
|
```vim
|
||||||
|
,mt " open TOC in a side window — press Enter to jump to heading
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Statusline
|
||||||
|
|
||||||
|
A native, hand-written statusline using the Solarized palette:
|
||||||
|
|
||||||
|
```
|
||||||
|
N ~/.vimrc [+] main [vim] 42:7 68%
|
||||||
|
```
|
||||||
|
|
||||||
|
- Mode block changes colour by mode (Normal=yellow, Insert=blue, Visual=magenta, Replace=red)
|
||||||
|
- Git branch via vim-fugitive
|
||||||
|
- Background matches tmux status bar for a seamless bottom band
|
||||||
|
|
||||||
|
### Session Management
|
||||||
|
|
||||||
|
```vim
|
||||||
|
:Obsess " start tracking the current session
|
||||||
|
:Obsess! " stop tracking
|
||||||
|
```
|
||||||
|
|
||||||
|
Sessions auto-restore when you open Vim in the same directory.
|
||||||
|
|
||||||
|
### Project-Local Config
|
||||||
|
|
||||||
|
Drop a `.vimrc` in any project root to override settings:
|
||||||
|
|
||||||
|
```vim
|
||||||
|
" my-project/.vimrc
|
||||||
|
set shiftwidth=2
|
||||||
|
let g:ale_python_black_options = '--line-length=100'
|
||||||
|
```
|
||||||
|
|
||||||
|
### tmux Integration
|
||||||
|
|
||||||
|
`Ctrl+h/j/k/l` navigates seamlessly between Vim splits and tmux panes.
|
||||||
|
|
||||||
|
Add to `~/.tmux.conf` (or let `install.sh` append it):
|
||||||
|
|
||||||
|
```tmux
|
||||||
|
is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\S+\/)?g?(view|n?vim?x?)(diff)?$'"
|
||||||
|
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
|
||||||
|
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
|
||||||
|
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
|
||||||
|
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
|
||||||
|
```
|
||||||
|
|
||||||
|
### TTY / SSH Support
|
||||||
|
|
||||||
|
Detected automatically when `$TERM` is unset, `dumb`, `linux`, `screen`, or contains `builtin`. In TTY mode:
|
||||||
|
|
||||||
|
- True colour and cursorline disabled
|
||||||
|
- FZF preview windows disabled
|
||||||
|
- IndentLine guides disabled
|
||||||
|
- Simplified statusline (no colour)
|
||||||
|
- Syntax column limit reduced to 120 characters
|
||||||
|
|
||||||
|
### Large File Handling
|
||||||
|
|
||||||
|
Files over 10 MB automatically disable syntax highlighting, undo history, and
|
||||||
|
linting to prevent stalling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
### Navigation
|
||||||
|
- **fzf + fzf.vim** — fuzzy finder for files, buffers, tags, ripgrep
|
||||||
|
|
||||||
|
### Git
|
||||||
|
- **vim-fugitive** — full Git integration
|
||||||
|
- **vim-gitgutter** — diff signs in the sign column
|
||||||
|
|
||||||
|
### LSP and Completion
|
||||||
|
- **vim-lsp** — pure VimScript LSP client
|
||||||
|
- **vim-lsp-settings** — auto-configures language servers
|
||||||
|
- **asyncomplete.vim** — async completion engine
|
||||||
|
- **asyncomplete-lsp.vim** — LSP completion source
|
||||||
|
|
||||||
|
### Linting and Formatting
|
||||||
|
- **ALE** — async linting and format-on-save
|
||||||
|
|
||||||
|
### Markdown
|
||||||
|
- **vim-markdown** — folding, concealment, table alignment
|
||||||
|
- **previm** — live browser preview
|
||||||
|
|
||||||
|
### Language Syntax
|
||||||
|
- **vim-javascript** — enhanced JS syntax
|
||||||
|
- **yats.vim** — TypeScript syntax
|
||||||
|
- **vim-go** — Go syntax and tooling
|
||||||
|
|
||||||
|
### Editing
|
||||||
|
- **vim-surround** — change/delete/add surroundings
|
||||||
|
- **vim-commentary** — `gc` to toggle comments
|
||||||
|
- **vim-repeat** — repeat plugin maps with `.`
|
||||||
|
- **vim-unimpaired** — bracket shortcut pairs
|
||||||
|
- **targets.vim** — additional text objects
|
||||||
|
- **auto-pairs** — auto-close brackets and quotes
|
||||||
|
- **vim-easymotion** — `s` + 2 chars to jump anywhere
|
||||||
|
|
||||||
|
### UI
|
||||||
|
- **vim-colors-solarized** — color scheme
|
||||||
|
- **undotree** — visual undo branch history
|
||||||
|
- **vim-startify** — startup dashboard and session list
|
||||||
|
- **indentLine** — indent guides (non-TTY)
|
||||||
|
|
||||||
|
### Session and Navigation
|
||||||
|
- **vim-obsession** — session tracking
|
||||||
|
- **vim-tmux-navigator** — seamless Vim/tmux pane navigation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
### Per-project overrides
|
||||||
|
|
||||||
|
Create `.vimrc` in your project root:
|
||||||
|
|
||||||
|
```vim
|
||||||
|
" project/.vimrc
|
||||||
|
set shiftwidth=2
|
||||||
|
let g:ale_python_black_options = '--line-length=120'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Modify keybindings
|
||||||
|
|
||||||
|
Edit `~/.vimrc` directly (`,ev` opens it from inside Vim). Reload with `,sv`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
| Problem | Fix |
|
**Plugins not loading**
|
||||||
|---------|-----|
|
|
||||||
| Plugins not loading | `:PlugInstall` then `:PlugUpdate` |
|
|
||||||
| LSP not starting | `:LspInstallServer` for current filetype |
|
|
||||||
| Colors wrong | `export COLORTERM=truecolor` in shell rc |
|
|
||||||
| `Ctrl+s` freezes | `stty -ixon` in shell rc |
|
|
||||||
| Everything slow | Large file? Auto-disabled >10MB |
|
|
||||||
|
|
||||||
More in the [wiki](https://github.com/m1ngsama/chopsticks/wiki).
|
```vim
|
||||||
|
:PlugInstall " install missing plugins
|
||||||
|
:PlugUpdate " update all plugins
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing
|
**LSP server not starting**
|
||||||
|
|
||||||
See [CONTRIBUTING.md](CONTRIBUTING.md). The two rules that matter: no Node.js dependencies, and don't regress startup time.
|
```vim
|
||||||
|
:LspInstallServer " install server for current filetype
|
||||||
|
:LspStatus " check server status
|
||||||
|
```
|
||||||
|
|
||||||
|
**Markdown preview not opening**
|
||||||
|
|
||||||
|
`previm` uses `open` (macOS) or `xdg-open` (Linux). Make sure a browser is
|
||||||
|
set as the default handler for HTML files.
|
||||||
|
|
||||||
|
**Colors look wrong**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export TERM=xterm-256color # add to ~/.bashrc or ~/.zshrc
|
||||||
|
export COLORTERM=truecolor # for true colour
|
||||||
|
```
|
||||||
|
|
||||||
|
**ALE linters not found**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
which flake8 black prettier eslint # verify tools are on PATH
|
||||||
|
```
|
||||||
|
|
||||||
|
**`Ctrl+s` freezes the terminal**
|
||||||
|
|
||||||
|
Add `stty -ixon` to your `~/.bashrc`, `~/.zshrc`, or `~/.config/fish/config.fish`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](LICENSE)
|
[MIT](LICENSE) © m1ng
|
||||||
|
|
|
||||||
10
coc-settings.json
Normal file
10
coc-settings.json
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"languageserver": {
|
||||||
|
"marksman": {
|
||||||
|
"command": "marksman",
|
||||||
|
"args": ["server"],
|
||||||
|
"filetypes": ["markdown"],
|
||||||
|
"rootPatterns": [".git", ".marksman.toml"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
install.sh
14
install.sh
|
|
@ -380,6 +380,18 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "$HOME/.vim"
|
mkdir -p "$HOME/.vim"
|
||||||
|
COC_CFG="$HOME/.vim/coc-settings.json"
|
||||||
|
if [ -f "$COC_CFG" ] && [ ! -L "$COC_CFG" ]; then
|
||||||
|
TS=$(date +%Y%m%d_%H%M%S)
|
||||||
|
warn "Backing up existing coc-settings.json → $COC_CFG.backup.$TS"
|
||||||
|
mv "$COC_CFG" "$COC_CFG.backup.$TS"
|
||||||
|
fi
|
||||||
|
ln -sf "$SCRIPT_DIR/coc-settings.json" "$COC_CFG"
|
||||||
|
if [[ -L "$COC_CFG" ]]; then
|
||||||
|
ok "$HOME/.vim/coc-settings.json → $SCRIPT_DIR/coc-settings.json"
|
||||||
|
else
|
||||||
|
warn "coc-settings.json symlink failed (non-fatal)"
|
||||||
|
fi
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# 3. vim-plug + Plugins
|
# 3. vim-plug + Plugins
|
||||||
|
|
@ -429,7 +441,7 @@ fi
|
||||||
_vim_run +'PlugClean!' +qall || true # remove plugins no longer in vimrc; ignore exit code (none expected)
|
_vim_run +'PlugClean!' +qall || true # remove plugins no longer in vimrc; ignore exit code (none expected)
|
||||||
_vim_run +'PlugInstall --sync' +qall || true # fzf post-install hook may exit non-zero; harmless
|
_vim_run +'PlugInstall --sync' +qall || true # fzf post-install hook may exit non-zero; harmless
|
||||||
|
|
||||||
_plug_count=$(find "$HOME/.vim/plugged" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
|
_plug_count=$(ls -1 "$HOME/.vim/plugged" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
if [[ $_plug_count -eq 0 ]]; then
|
if [[ $_plug_count -eq 0 ]]; then
|
||||||
die "Plugin installation failed — ~/.vim/plugged is empty. Check network and retry."
|
die "Plugin installation failed — ~/.vim/plugged is empty. Check network and retry."
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
216
modules/core.vim
216
modules/core.vim
|
|
@ -1,216 +0,0 @@
|
||||||
" core.vim — general settings, basic keymaps, performance, indentation
|
|
||||||
" filetype/syntax already enabled by plug#end() in plugins.vim
|
|
||||||
|
|
||||||
set number
|
|
||||||
set relativenumber
|
|
||||||
|
|
||||||
if !g:is_tty
|
|
||||||
set cursorline
|
|
||||||
endif
|
|
||||||
|
|
||||||
set nobackup
|
|
||||||
set scrolloff=10
|
|
||||||
set nowrap
|
|
||||||
set incsearch
|
|
||||||
set ignorecase
|
|
||||||
set smartcase
|
|
||||||
set showcmd
|
|
||||||
set showmode
|
|
||||||
set hlsearch
|
|
||||||
set history=1000
|
|
||||||
set wildmenu
|
|
||||||
set wildmode=list:longest
|
|
||||||
set wildignorecase
|
|
||||||
set wildignore=*.docx,*.jpg,*.png,*.gif,*.pdf,*.pyc,*.exe,*.flv,*.img,*.xlsx
|
|
||||||
set wildignore+=*/node_modules/*,*/.git/*,*/__pycache__/*,*/dist/*,*/build/*
|
|
||||||
set mouse=a
|
|
||||||
set encoding=utf-8
|
|
||||||
set foldmethod=indent
|
|
||||||
set foldlevel=99
|
|
||||||
set splitbelow
|
|
||||||
set splitright
|
|
||||||
set backspace=indent,eol,start
|
|
||||||
set nrformats-=octal
|
|
||||||
set autoread
|
|
||||||
set cmdheight=1
|
|
||||||
set hidden
|
|
||||||
set whichwrap+=<,>,h,l
|
|
||||||
set magic
|
|
||||||
set showmatch
|
|
||||||
set mat=2
|
|
||||||
set noerrorbells
|
|
||||||
set novisualbell
|
|
||||||
set t_vb=
|
|
||||||
set ttimeout
|
|
||||||
set ttimeoutlen=10
|
|
||||||
|
|
||||||
if $COLORTERM ==# 'gnome-terminal'
|
|
||||||
set t_Co=256
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has("gui_running")
|
|
||||||
set guioptions-=T
|
|
||||||
set guioptions-=e
|
|
||||||
set t_Co=256
|
|
||||||
set guitablabel=%M\ %t
|
|
||||||
endif
|
|
||||||
|
|
||||||
set display+=lastline
|
|
||||||
set ffs=unix,dos,mac
|
|
||||||
set nowb
|
|
||||||
set noswapfile
|
|
||||||
|
|
||||||
if has('persistent_undo')
|
|
||||||
set undofile
|
|
||||||
let &undodir = expand('~/.vim/.undo')
|
|
||||||
silent! call mkdir(&undodir, 'p', 0700)
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── Text, Tab and Indent ────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
if g:is_tty
|
|
||||||
set listchars=tab:>-,trail:.,extends:>,precedes:<,nbsp:_
|
|
||||||
else
|
|
||||||
set listchars=tab:→\ ,trail:·,extends:▸,precedes:◂,nbsp:·
|
|
||||||
endif
|
|
||||||
|
|
||||||
set expandtab
|
|
||||||
set smarttab
|
|
||||||
set shiftwidth=4
|
|
||||||
set tabstop=4
|
|
||||||
set lbr
|
|
||||||
set tw=0
|
|
||||||
set autoindent
|
|
||||||
set smartindent
|
|
||||||
|
|
||||||
" ── Leader ──────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
let mapleader = ","
|
|
||||||
|
|
||||||
" ── Basic Keymaps ───────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
nnoremap <leader>w :w!<cr>
|
|
||||||
nnoremap <leader>q :q<cr>
|
|
||||||
nnoremap <leader>x :x<cr>
|
|
||||||
|
|
||||||
nnoremap <silent> <leader><cr> :noh<cr>
|
|
||||||
|
|
||||||
nnoremap <leader>bd :Bclose<cr>
|
|
||||||
nnoremap <leader>ba :bufdo bd<cr>
|
|
||||||
nnoremap <leader>l :bnext<cr>
|
|
||||||
nnoremap <leader>h :bprevious<cr>
|
|
||||||
|
|
||||||
nnoremap <leader>tn :tabnew<cr>
|
|
||||||
nnoremap <leader>to :tabonly<cr>
|
|
||||||
nnoremap <leader>tc :tabclose<cr>
|
|
||||||
nnoremap <leader>tm :tabmove
|
|
||||||
nnoremap <leader>t<leader> :tabnext<cr>
|
|
||||||
|
|
||||||
let g:lasttab = 1
|
|
||||||
nnoremap <Leader>tl :exe "tabn ".g:lasttab<CR>
|
|
||||||
augroup ChopstickTabHistory
|
|
||||||
autocmd!
|
|
||||||
autocmd TabLeave * let g:lasttab = tabpagenr()
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
nnoremap <leader>te :tabedit <C-r>=expand("%:p:h")<cr>/
|
|
||||||
nnoremap <leader>cd :lcd %:p:h<cr>:pwd<cr>
|
|
||||||
|
|
||||||
nnoremap 0 ^
|
|
||||||
nnoremap gV `[v`]
|
|
||||||
|
|
||||||
cnoremap <C-p> <Up>
|
|
||||||
cnoremap <C-n> <Down>
|
|
||||||
|
|
||||||
nnoremap <M-j> :m .+1<CR>==
|
|
||||||
nnoremap <M-k> :m .-2<CR>==
|
|
||||||
vnoremap <M-j> :m '>+1<CR>gv=gv
|
|
||||||
vnoremap <M-k> :m '<-2<CR>gv=gv
|
|
||||||
|
|
||||||
nnoremap <leader>ss :setlocal spell!<cr>
|
|
||||||
nnoremap <leader>sn ]s
|
|
||||||
nnoremap <leader>sp [s
|
|
||||||
nnoremap <leader>sa zg
|
|
||||||
nnoremap <leader>s? z=
|
|
||||||
|
|
||||||
set pastetoggle=<F2>
|
|
||||||
nnoremap <F3> :set invnumber<CR>
|
|
||||||
nnoremap <F4> :set invrelativenumber<CR>
|
|
||||||
nnoremap <F6> :set list!<CR>
|
|
||||||
|
|
||||||
nnoremap <space> za
|
|
||||||
|
|
||||||
nnoremap Y y$
|
|
||||||
nnoremap Q <nop>
|
|
||||||
|
|
||||||
inoremap jk <Esc>
|
|
||||||
|
|
||||||
vnoremap < <gv
|
|
||||||
vnoremap > >gv
|
|
||||||
|
|
||||||
nnoremap n nzzzv
|
|
||||||
nnoremap N Nzzzv
|
|
||||||
|
|
||||||
vnoremap // y/\V<C-r>=escape(@",'/\')<CR><CR>
|
|
||||||
|
|
||||||
nnoremap <silent> <C-s> :w<CR>
|
|
||||||
inoremap <silent> <C-s> <C-o>:w<CR>
|
|
||||||
|
|
||||||
nnoremap <C-d> <C-d>zz
|
|
||||||
nnoremap <C-u> <C-u>zz
|
|
||||||
|
|
||||||
if has('clipboard')
|
|
||||||
nnoremap <leader>y "+y
|
|
||||||
vnoremap <leader>y "+y
|
|
||||||
nnoremap <leader>Y "+Y
|
|
||||||
nnoremap <leader>p "+p
|
|
||||||
nnoremap <leader>P "+P
|
|
||||||
endif
|
|
||||||
|
|
||||||
nnoremap <leader>qo :copen<CR>
|
|
||||||
nnoremap <leader>qc :cclose<CR>
|
|
||||||
|
|
||||||
augroup ChopstickResize
|
|
||||||
autocmd!
|
|
||||||
autocmd VimResized * wincmd =
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
" ── Performance ─────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
set synmaxcol=200
|
|
||||||
set ttyfast
|
|
||||||
set lazyredraw
|
|
||||||
set complete-=i
|
|
||||||
set updatetime=300
|
|
||||||
set shortmess+=cI
|
|
||||||
|
|
||||||
if g:is_tty
|
|
||||||
set signcolumn=auto
|
|
||||||
set synmaxcol=120
|
|
||||||
else
|
|
||||||
if has("patch-8.1.1564")
|
|
||||||
set signcolumn=number
|
|
||||||
else
|
|
||||||
set signcolumn=yes
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── Project-Local Config ────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
set exrc
|
|
||||||
set secure
|
|
||||||
set sessionoptions=blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal
|
|
||||||
|
|
||||||
" ── Format Options ──────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
augroup ChopstickFormatOptions
|
|
||||||
autocmd!
|
|
||||||
autocmd FileType * setlocal formatoptions-=c formatoptions-=r formatoptions-=o formatoptions+=j
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ChopstickPaste
|
|
||||||
autocmd!
|
|
||||||
autocmd InsertLeave * set nopaste
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
set timeoutlen=500
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
" editing.vim — EasyMotion, yank highlight, search auto-clear, undotree
|
|
||||||
|
|
||||||
" ── EasyMotion ──────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
let g:EasyMotion_do_mapping = 0
|
|
||||||
let g:EasyMotion_smartcase = 1
|
|
||||||
|
|
||||||
if exists('g:plugs["vim-easymotion"]')
|
|
||||||
nmap s <Plug>(easymotion-overwin-f2)
|
|
||||||
nmap <Leader>j <Plug>(easymotion-j)
|
|
||||||
nmap <Leader>k <Plug>(easymotion-k)
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── UndoTree ────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
if exists('g:plugs["undotree"]')
|
|
||||||
nnoremap <F5> :UndotreeToggle<CR>
|
|
||||||
nnoremap <leader>u :UndotreeToggle<CR>
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── Yank Highlight ──────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
if exists('##TextYankPost') && has('timers')
|
|
||||||
function! s:YankHighlight() abort
|
|
||||||
if v:event.operator !=# 'y' | return | endif
|
|
||||||
let l:m = matchadd('IncSearch',
|
|
||||||
\ printf('\%%>%dl\%%<%dl', line("'[") - 1, line("']") + 1))
|
|
||||||
call timer_start(150, {-> matchdelete(l:m)})
|
|
||||||
endfunction
|
|
||||||
augroup ChopstickYankHL
|
|
||||||
autocmd!
|
|
||||||
autocmd TextYankPost * call s:YankHighlight()
|
|
||||||
augroup END
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── Blank Line Insertion (replaces vim-unimpaired) ──────────────────────────
|
|
||||||
|
|
||||||
nnoremap <silent> [<Space> :<C-u>put! =repeat(nr2char(10), v:count1)<CR>'[
|
|
||||||
nnoremap <silent> ]<Space> :<C-u>put =repeat(nr2char(10), v:count1)<CR>
|
|
||||||
|
|
||||||
" ── Auto-Clear Search Highlight ─────────────────────────────────────────────
|
|
||||||
|
|
||||||
augroup ChopstickSearchHL
|
|
||||||
autocmd!
|
|
||||||
autocmd CursorHold * if get(v:, 'hlsearch', 0) | let v:hlsearch = 0 | endif
|
|
||||||
augroup END
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
" env.vim — environment detection (must load first)
|
|
||||||
|
|
||||||
set nocompatible
|
|
||||||
|
|
||||||
let g:is_tty = empty($TERM) || $TERM ==# 'dumb' || $TERM =~# 'linux'
|
|
||||||
\ || $TERM =~# 'screen' || &term =~# 'builtin'
|
|
||||||
let g:has_true_color = ($COLORTERM ==# 'truecolor' || $COLORTERM ==# '24bit')
|
|
||||||
|
|
||||||
" Skip built-in plugins we never use
|
|
||||||
let g:loaded_2html_plugin = 1
|
|
||||||
let g:loaded_getscriptPlugin = 1
|
|
||||||
let g:loaded_gzip = 1
|
|
||||||
let g:loaded_logipat = 1
|
|
||||||
let g:loaded_rrhelper = 1
|
|
||||||
let g:loaded_tarPlugin = 1
|
|
||||||
let g:loaded_vimballPlugin = 1
|
|
||||||
let g:loaded_zipPlugin = 1
|
|
||||||
let g:loaded_tutor_mode_plugin = 1
|
|
||||||
let g:loaded_spellfile_plugin = 1
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
" git.vim — Fugitive mappings, GitGutter config, conflict navigation
|
|
||||||
|
|
||||||
" ── GitGutter ───────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
let g:gitgutter_map_keys = 0
|
|
||||||
let g:gitgutter_sign_added = '+'
|
|
||||||
let g:gitgutter_sign_modified = '~'
|
|
||||||
let g:gitgutter_sign_removed = '-'
|
|
||||||
let g:gitgutter_sign_removed_first_line = '^'
|
|
||||||
let g:gitgutter_sign_modified_removed = '~'
|
|
||||||
|
|
||||||
" ── Fugitive ────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
if exists('g:plugs["vim-fugitive"]')
|
|
||||||
nnoremap <leader>gs :Git status<CR>
|
|
||||||
nnoremap <leader>gc :Git commit<CR>
|
|
||||||
nnoremap <leader>gp :Git push<CR>
|
|
||||||
nnoremap <leader>gl :Git pull<CR>
|
|
||||||
nnoremap <leader>gd :Gdiffsplit<CR>
|
|
||||||
nnoremap <leader>gb :Git blame<CR>
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── Conflict Navigation ────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
nnoremap <silent> ]x /^\(<<<<<<<\\|=======\\|>>>>>>>\)<CR>
|
|
||||||
nnoremap <silent> [x ?^\(<<<<<<<\\|=======\\|>>>>>>>\)<CR>
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
" languages.vim — vim-go config, per-filetype autocmds
|
|
||||||
|
|
||||||
" ── vim-go (syntax only — vim-lsp handles intelligence) ─────────────────────
|
|
||||||
|
|
||||||
let g:go_gopls_enabled = 0
|
|
||||||
let g:go_code_completion_enabled = 0
|
|
||||||
let g:go_fmt_autosave = 0
|
|
||||||
let g:go_imports_autosave = 0
|
|
||||||
let g:go_highlight_types = 1
|
|
||||||
let g:go_highlight_fields = 1
|
|
||||||
let g:go_highlight_functions = 1
|
|
||||||
let g:go_highlight_function_calls = 1
|
|
||||||
|
|
||||||
" ── Filetype Detection ──────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
augroup ChopstickFiletype
|
|
||||||
autocmd!
|
|
||||||
|
|
||||||
autocmd BufReadPost *
|
|
||||||
\ if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
|
|
||||||
|
|
||||||
autocmd FileType python
|
|
||||||
\ setlocal expandtab shiftwidth=4 tabstop=4 textwidth=88 colorcolumn=+1
|
|
||||||
autocmd FileType javascript,typescript
|
|
||||||
\ setlocal expandtab shiftwidth=2 tabstop=2 textwidth=100 colorcolumn=+1
|
|
||||||
autocmd FileType go
|
|
||||||
\ setlocal noexpandtab shiftwidth=4 tabstop=4 textwidth=120 colorcolumn=+1
|
|
||||||
autocmd FileType rust
|
|
||||||
\ setlocal expandtab shiftwidth=4 tabstop=4 textwidth=100 colorcolumn=+1
|
|
||||||
autocmd FileType c,cpp
|
|
||||||
\ setlocal expandtab shiftwidth=4 tabstop=4 textwidth=80 colorcolumn=+1
|
|
||||||
autocmd FileType html,css
|
|
||||||
\ setlocal expandtab shiftwidth=2 tabstop=2
|
|
||||||
autocmd FileType yaml
|
|
||||||
\ setlocal expandtab shiftwidth=2 tabstop=2
|
|
||||||
autocmd FileType markdown
|
|
||||||
\ setlocal wrap linebreak spell textwidth=0 colorcolumn=0 conceallevel=2
|
|
||||||
autocmd FileType sh
|
|
||||||
\ setlocal expandtab shiftwidth=2 tabstop=2 textwidth=80 colorcolumn=+1
|
|
||||||
autocmd FileType make
|
|
||||||
\ setlocal noexpandtab shiftwidth=8 tabstop=8
|
|
||||||
autocmd FileType json
|
|
||||||
\ setlocal expandtab shiftwidth=2 tabstop=2
|
|
||||||
autocmd FileType dockerfile
|
|
||||||
\ setlocal expandtab shiftwidth=2 tabstop=2
|
|
||||||
augroup END
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
" lint.vim — ALE async linting and format-on-save
|
|
||||||
|
|
||||||
let g:ale_disable_lsp = 1
|
|
||||||
|
|
||||||
let g:ale_linters = {
|
|
||||||
\ 'python': ['flake8', 'pylint'],
|
|
||||||
\ 'javascript': ['eslint'],
|
|
||||||
\ 'typescript': ['eslint'],
|
|
||||||
\ 'go': ['staticcheck'],
|
|
||||||
\ 'rust': ['cargo'],
|
|
||||||
\ 'c': ['cc'],
|
|
||||||
\ 'sh': ['shellcheck'],
|
|
||||||
\ 'yaml': ['yamllint'],
|
|
||||||
\ 'dockerfile': ['hadolint'],
|
|
||||||
\ 'css': ['stylelint'],
|
|
||||||
\ 'scss': ['stylelint'],
|
|
||||||
\ 'markdown': ['markdownlint'],
|
|
||||||
\ 'sql': ['sqlfluff'],
|
|
||||||
\}
|
|
||||||
|
|
||||||
let g:ale_fixers = {
|
|
||||||
\ '*': ['remove_trailing_lines', 'trim_whitespace'],
|
|
||||||
\ 'python': ['black', 'isort'],
|
|
||||||
\ 'javascript': ['prettier', 'eslint'],
|
|
||||||
\ 'typescript': ['prettier', 'eslint'],
|
|
||||||
\ 'go': ['goimports'],
|
|
||||||
\ 'rust': ['rustfmt'],
|
|
||||||
\ 'c': ['clang-format'],
|
|
||||||
\ 'json': ['prettier'],
|
|
||||||
\ 'yaml': ['prettier'],
|
|
||||||
\ 'html': ['prettier'],
|
|
||||||
\ 'css': ['prettier'],
|
|
||||||
\ 'scss': ['prettier'],
|
|
||||||
\ 'less': ['prettier'],
|
|
||||||
\ 'markdown': ['prettier'],
|
|
||||||
\ 'sql': ['sqlfluff'],
|
|
||||||
\}
|
|
||||||
|
|
||||||
let g:ale_fix_on_save = 1
|
|
||||||
let g:ale_python_isort_options = '--profile black'
|
|
||||||
let g:ale_sign_error = 'X'
|
|
||||||
let g:ale_sign_warning = '!'
|
|
||||||
let g:ale_lint_on_text_changed = 'normal'
|
|
||||||
let g:ale_lint_on_insert_leave = 1
|
|
||||||
let g:ale_lint_on_enter = 1
|
|
||||||
let g:ale_lint_delay = 200
|
|
||||||
let g:ale_echo_delay = 100
|
|
||||||
|
|
||||||
if exists('g:plugs["ale"]')
|
|
||||||
nnoremap <silent> [e :ALEPrevious<cr>
|
|
||||||
nnoremap <silent> ]e :ALENext<cr>
|
|
||||||
nnoremap <silent> <leader>aD :ALEDetail<cr>
|
|
||||||
endif
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
" lsp.vim — vim-lsp settings, asyncomplete, LSP buffer keymaps
|
|
||||||
|
|
||||||
let g:lsp_settings_lazyload = 1
|
|
||||||
|
|
||||||
let g:lsp_settings_filetype_python = ['pylsp']
|
|
||||||
let g:lsp_settings_filetype_go = ['gopls']
|
|
||||||
let g:lsp_settings_filetype_rust = ['rust-analyzer']
|
|
||||||
let g:lsp_settings_filetype_typescript = ['typescript-language-server']
|
|
||||||
let g:lsp_settings_filetype_javascript = ['typescript-language-server']
|
|
||||||
let g:lsp_settings_filetype_c = ['clangd']
|
|
||||||
let g:lsp_settings_filetype_sh = ['bash-language-server']
|
|
||||||
let g:lsp_settings_filetype_html = ['vscode-html-language-server']
|
|
||||||
let g:lsp_settings_filetype_css = ['vscode-css-language-server']
|
|
||||||
let g:lsp_settings_filetype_scss = ['vscode-css-language-server']
|
|
||||||
let g:lsp_settings_filetype_json = ['vscode-json-language-server']
|
|
||||||
let g:lsp_settings_filetype_yaml = ['yaml-language-server']
|
|
||||||
let g:lsp_settings_filetype_markdown = ['marksman']
|
|
||||||
let g:lsp_settings_filetype_sql = ['sqls']
|
|
||||||
|
|
||||||
let g:lsp_diagnostics_virtual_text_enabled = !g:is_tty
|
|
||||||
let g:lsp_diagnostics_virtual_text_delay = 200
|
|
||||||
let g:lsp_diagnostics_highlights_enabled = !g:is_tty
|
|
||||||
let g:lsp_document_highlight_enabled = !g:is_tty
|
|
||||||
let g:lsp_document_highlight_delay = 200
|
|
||||||
let g:lsp_signs_enabled = 1
|
|
||||||
let g:lsp_diagnostics_echo_cursor = 1
|
|
||||||
let g:lsp_diagnostics_echo_delay = 100
|
|
||||||
let g:lsp_completion_documentation_enabled = 1
|
|
||||||
|
|
||||||
let g:lsp_signs_error = {'text': 'X'}
|
|
||||||
let g:lsp_signs_warning = {'text': '!'}
|
|
||||||
let g:lsp_signs_information = {'text': 'i'}
|
|
||||||
let g:lsp_signs_hint = {'text': '>'}
|
|
||||||
|
|
||||||
" ── Completion ──────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
if has('patch-8.1.1517')
|
|
||||||
set completeopt=menuone,noinsert,noselect,popup
|
|
||||||
else
|
|
||||||
set completeopt=menuone,noinsert,noselect
|
|
||||||
endif
|
|
||||||
set pumheight=15
|
|
||||||
let g:asyncomplete_auto_popup = 1
|
|
||||||
let g:asyncomplete_auto_completeopt = 0
|
|
||||||
let g:asyncomplete_popup_delay = 50
|
|
||||||
|
|
||||||
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
|
|
||||||
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
|
|
||||||
inoremap <expr> <CR> pumvisible() ? asyncomplete#close_popup() : "\<CR>"
|
|
||||||
|
|
||||||
" ── Buffer Keymaps ──────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function! s:on_lsp_buffer_enabled() abort
|
|
||||||
setlocal omnifunc=lsp#complete
|
|
||||||
setlocal signcolumn=yes
|
|
||||||
|
|
||||||
nmap <buffer> gd <plug>(lsp-definition)
|
|
||||||
nmap <buffer> gy <plug>(lsp-type-definition)
|
|
||||||
nmap <buffer> gi <plug>(lsp-implementation)
|
|
||||||
nmap <buffer> gr <plug>(lsp-references)
|
|
||||||
nmap <buffer> [g <plug>(lsp-previous-diagnostic)
|
|
||||||
nmap <buffer> ]g <plug>(lsp-next-diagnostic)
|
|
||||||
|
|
||||||
nmap <buffer> K <plug>(lsp-hover)
|
|
||||||
|
|
||||||
nmap <buffer> <leader>rn <plug>(lsp-rename)
|
|
||||||
nmap <buffer> <leader>ca <plug>(lsp-code-action)
|
|
||||||
nmap <buffer> <leader>f <plug>(lsp-document-format)
|
|
||||||
xmap <buffer> <leader>f <plug>(lsp-document-range-format)
|
|
||||||
|
|
||||||
nmap <buffer> <leader>o <plug>(lsp-document-symbol-search)
|
|
||||||
nmap <buffer> <leader>ws <plug>(lsp-workspace-symbol-search)
|
|
||||||
nmap <buffer> <leader>cD <plug>(lsp-document-diagnostics)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
augroup lsp_install
|
|
||||||
autocmd!
|
|
||||||
autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled()
|
|
||||||
augroup END
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
" navigation.vim — FZF, netrw, buffer/window management, terminal
|
|
||||||
|
|
||||||
" ── netrw (built-in file browser) ───────────────────────────────────────────
|
|
||||||
|
|
||||||
let g:netrw_liststyle = 3
|
|
||||||
let g:netrw_banner = 0
|
|
||||||
let g:netrw_browse_split = 0
|
|
||||||
let g:netrw_winsize = 25
|
|
||||||
let g:netrw_list_hide = '\(^\|\s\s\)\zs\.\S\+'
|
|
||||||
let g:netrw_list_hide .= ',\.pyc$,node_modules,\.git,__pycache__,\.DS_Store'
|
|
||||||
|
|
||||||
nnoremap <leader>e :Explore<CR>
|
|
||||||
nnoremap <leader>E :Vexplore<CR>
|
|
||||||
|
|
||||||
" ── FZF ─────────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function! s:SmartFiles() abort
|
|
||||||
if isdirectory('.git') || finddir('.git', '.;') !=# ''
|
|
||||||
GFiles
|
|
||||||
else
|
|
||||||
Files
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
if exists('g:plugs["fzf.vim"]')
|
|
||||||
nnoremap <C-p> :call <SID>SmartFiles()<CR>
|
|
||||||
nnoremap <leader>b :Buffers<CR>
|
|
||||||
nnoremap <leader>rg :Rg<CR>
|
|
||||||
nnoremap <leader>rG :RgWord<CR>
|
|
||||||
nnoremap <leader>rt :Tags<CR>
|
|
||||||
nnoremap <leader>gF :GFiles<CR>
|
|
||||||
nnoremap <leader>fh :History<CR>
|
|
||||||
nnoremap <leader>fc :Commands<CR>
|
|
||||||
nnoremap <leader>fm :Marks<CR>
|
|
||||||
nnoremap <leader>fl :BLines<CR>
|
|
||||||
nnoremap <leader>fL :Lines<CR>
|
|
||||||
nnoremap <leader>f/ :History/<CR>
|
|
||||||
nnoremap <leader>f: :History:<CR>
|
|
||||||
endif
|
|
||||||
|
|
||||||
let g:fzf_layout = { 'down': '40%' }
|
|
||||||
|
|
||||||
if g:is_tty
|
|
||||||
let g:fzf_preview_window = []
|
|
||||||
else
|
|
||||||
let g:fzf_preview_window = ['right:50%', 'ctrl-/']
|
|
||||||
endif
|
|
||||||
|
|
||||||
if g:is_tty
|
|
||||||
command! -bang -nargs=* Rg
|
|
||||||
\ call fzf#vim#grep(
|
|
||||||
\ 'rg --column --line-number --no-heading --color=always --smart-case -- '
|
|
||||||
\ .shellescape(<q-args>), 1, <bang>0)
|
|
||||||
command! -bang GFiles call fzf#vim#gitfiles('', <bang>0)
|
|
||||||
else
|
|
||||||
command! -bang -nargs=* Rg
|
|
||||||
\ call fzf#vim#grep(
|
|
||||||
\ 'rg --column --line-number --no-heading --color=always --smart-case -- '
|
|
||||||
\ .shellescape(<q-args>), 1, fzf#vim#with_preview(), <bang>0)
|
|
||||||
command! -bang GFiles call fzf#vim#gitfiles('', fzf#vim#with_preview(), <bang>0)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if g:is_tty
|
|
||||||
command! -bang -nargs=* RgWord
|
|
||||||
\ call fzf#vim#grep(
|
|
||||||
\ 'rg --column --line-number --no-heading --color=always --smart-case -F -- '
|
|
||||||
\ .shellescape(expand('<cword>')), 1, <bang>0)
|
|
||||||
else
|
|
||||||
command! -bang -nargs=* RgWord
|
|
||||||
\ call fzf#vim#grep(
|
|
||||||
\ 'rg --column --line-number --no-heading --color=always --smart-case -F -- '
|
|
||||||
\ .shellescape(expand('<cword>')), 1, fzf#vim#with_preview(), <bang>0)
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── Window Maximize Toggle ──────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function! s:ToggleMaximize() abort
|
|
||||||
if exists('t:maximize_session')
|
|
||||||
execute t:maximize_session
|
|
||||||
unlet t:maximize_session
|
|
||||||
else
|
|
||||||
let t:maximize_session = winrestcmd()
|
|
||||||
resize | vertical resize
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
nnoremap <silent> <leader>z :call <SID>ToggleMaximize()<CR>
|
|
||||||
|
|
||||||
" ── Terminal ────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
if has('terminal')
|
|
||||||
nnoremap <leader>tv :terminal<CR>
|
|
||||||
nnoremap <leader>th :terminal ++rows=10<CR>
|
|
||||||
tnoremap <Esc><Esc> <C-\><C-n>
|
|
||||||
tnoremap <C-h> <C-\><C-n><C-w>h
|
|
||||||
tnoremap <C-j> <C-\><C-n><C-w>j
|
|
||||||
tnoremap <C-k> <C-\><C-n><C-w>k
|
|
||||||
tnoremap <C-l> <C-\><C-n><C-w>l
|
|
||||||
endif
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
" plugins.vim — vim-plug declarations
|
|
||||||
|
|
||||||
let data_dir = has('nvim') ? stdpath('data') . '/site' : '~/.vim'
|
|
||||||
if empty(glob(data_dir . '/autoload/plug.vim'))
|
|
||||||
silent execute '!curl -fLo '.data_dir.'/autoload/plug.vim --create-dirs '
|
|
||||||
\ . 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
|
|
||||||
augroup PlugBootstrap
|
|
||||||
autocmd!
|
|
||||||
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
|
|
||||||
augroup END
|
|
||||||
endif
|
|
||||||
|
|
||||||
call plug#begin('~/.vim/plugged')
|
|
||||||
|
|
||||||
" ── Navigation & Search ──────────────────────────────────────────────────────
|
|
||||||
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
|
|
||||||
Plug 'junegunn/fzf.vim'
|
|
||||||
|
|
||||||
" ── Git ──────────────────────────────────────────────────────────────────────
|
|
||||||
Plug 'tpope/vim-fugitive'
|
|
||||||
Plug 'airblade/vim-gitgutter'
|
|
||||||
|
|
||||||
" ── Editing ──────────────────────────────────────────────────────────────────
|
|
||||||
Plug 'tpope/vim-surround'
|
|
||||||
Plug 'tpope/vim-commentary'
|
|
||||||
Plug 'tpope/vim-repeat'
|
|
||||||
" tpope/vim-unimpaired removed: 2.5ms startup cost, we define our own
|
|
||||||
" [q/]q (quickfix), [e/]e (ALE), [x/]x (conflict) — unimpaired's [b/]b
|
|
||||||
" is covered by ,h/,l. Blank line insertion ([<Space>) added below.
|
|
||||||
|
|
||||||
Plug 'tpope/vim-sleuth'
|
|
||||||
Plug 'wellle/targets.vim'
|
|
||||||
Plug 'jiangmiao/auto-pairs'
|
|
||||||
Plug 'easymotion/vim-easymotion', { 'on': '<Plug>(easymotion' }
|
|
||||||
|
|
||||||
" ── Linting & Formatting ────────────────────────────────────────────────────
|
|
||||||
Plug 'dense-analysis/ale'
|
|
||||||
|
|
||||||
" ── LSP + Completion (no Node.js required) ──────────────────────────────────
|
|
||||||
Plug 'prabirshrestha/vim-lsp'
|
|
||||||
Plug 'mattn/vim-lsp-settings'
|
|
||||||
Plug 'prabirshrestha/asyncomplete.vim'
|
|
||||||
Plug 'prabirshrestha/asyncomplete-lsp.vim'
|
|
||||||
|
|
||||||
" ── Language Syntax ──────────────────────────────────────────────────────────
|
|
||||||
Plug 'pangloss/vim-javascript', { 'for': ['javascript', 'javascript.jsx'] }
|
|
||||||
Plug 'HerringtonDarkholme/yats.vim', { 'for': ['typescript', 'typescript.tsx'] }
|
|
||||||
Plug 'preservim/vim-markdown', { 'for': 'markdown' }
|
|
||||||
Plug 'fatih/vim-go', { 'for': 'go' }
|
|
||||||
|
|
||||||
" ── Markdown Preview & Writing ───────────────────────────────────────────────
|
|
||||||
Plug 'previm/previm', { 'on': 'PrevimOpen' }
|
|
||||||
Plug 'junegunn/goyo.vim', { 'on': 'Goyo' }
|
|
||||||
Plug 'junegunn/limelight.vim', { 'on': ['Limelight', 'Limelight!'] }
|
|
||||||
|
|
||||||
" ── UI ───────────────────────────────────────────────────────────────────────
|
|
||||||
Plug 'mbbill/undotree', { 'on': 'UndotreeToggle' }
|
|
||||||
Plug 'mhinz/vim-startify'
|
|
||||||
Plug 'lifepillar/vim-solarized8'
|
|
||||||
if !g:is_tty
|
|
||||||
Plug 'Yggdroot/indentLine'
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── Session & Navigation ────────────────────────────────────────────────────
|
|
||||||
Plug 'tpope/vim-obsession'
|
|
||||||
Plug 'christoomey/vim-tmux-navigator'
|
|
||||||
|
|
||||||
call plug#end()
|
|
||||||
|
|
@ -1,260 +0,0 @@
|
||||||
" tools.vim — cheat sheet, run file, sudo save, quickfix, helpers
|
|
||||||
|
|
||||||
" ── Helper Functions ────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function! HasPaste()
|
|
||||||
if &paste | return 'PASTE MODE ' | endif
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
command! Bclose call <SID>BufcloseCloseIt()
|
|
||||||
function! <SID>BufcloseCloseIt()
|
|
||||||
let l:currentBufNum = bufnr("%")
|
|
||||||
let l:alternateBufNum = bufnr("#")
|
|
||||||
if buflisted(l:alternateBufNum)
|
|
||||||
buffer #
|
|
||||||
else
|
|
||||||
bnext
|
|
||||||
endif
|
|
||||||
if bufnr("%") == l:currentBufNum
|
|
||||||
new
|
|
||||||
endif
|
|
||||||
if buflisted(l:currentBufNum)
|
|
||||||
execute("bdelete! " . l:currentBufNum)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
fun! CleanExtraSpaces()
|
|
||||||
let save_cursor = getpos(".")
|
|
||||||
let old_query = getreg('/')
|
|
||||||
silent! %s/\s\+$//e
|
|
||||||
call setpos('.', save_cursor)
|
|
||||||
call setreg('/', old_query)
|
|
||||||
endfun
|
|
||||||
|
|
||||||
function! ToggleNumber()
|
|
||||||
if(&relativenumber == 1)
|
|
||||||
set norelativenumber
|
|
||||||
set number
|
|
||||||
else
|
|
||||||
set relativenumber
|
|
||||||
endif
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
" ── Additional Utilities ────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
nnoremap <leader>F gg=G``
|
|
||||||
nnoremap <leader>wa :wa<CR>
|
|
||||||
|
|
||||||
nnoremap <silent> <Leader>= :exe "resize " . (winheight(0) * 3/2)<CR>
|
|
||||||
nnoremap <silent> <Leader>- :exe "resize " . (winheight(0) * 2/3)<CR>
|
|
||||||
nnoremap <silent> <Leader>+ :exe "vertical resize " . (winwidth(0) * 3/2)<CR>
|
|
||||||
nnoremap <silent> <Leader>_ :exe "vertical resize " . (winwidth(0) * 2/3)<CR>
|
|
||||||
|
|
||||||
nnoremap <leader><leader> <c-^>
|
|
||||||
|
|
||||||
nnoremap <leader>W :%s/\s\+$//<CR>:let @/=''<CR>
|
|
||||||
|
|
||||||
nnoremap <leader>so :if &filetype ==# 'vim' <Bar> source % <Bar> echo "Sourced " . expand('%') <Bar> else <Bar> echo "Not a vim file" <Bar> endif<CR>
|
|
||||||
nnoremap <leader>ev :edit $MYVIMRC<CR>
|
|
||||||
nnoremap <leader>sv :source $MYVIMRC<CR>:echo "vimrc reloaded"<CR>
|
|
||||||
|
|
||||||
nnoremap <leader>* :%s/\<<C-r><C-w>\>//g<Left><Left>
|
|
||||||
|
|
||||||
if has('clipboard')
|
|
||||||
nnoremap <leader>cp :let @+ = expand("%:p")<CR>:echo "Copied: " . expand("%:p")<CR>
|
|
||||||
nnoremap <leader>cf :let @+ = expand("%:t")<CR>:echo "Copied: " . expand("%:t")<CR>
|
|
||||||
endif
|
|
||||||
|
|
||||||
nnoremap <leader>ms :e ~/buffer.md<cr>
|
|
||||||
|
|
||||||
" ── Auto-Create Directories ─────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function! s:MkNonExDir(file, buf)
|
|
||||||
if empty(getbufvar(a:buf, '&buftype')) && a:file !~# '\v^\w+\:\/'
|
|
||||||
let dir = fnamemodify(a:file, ':h')
|
|
||||||
if !isdirectory(dir)
|
|
||||||
call mkdir(dir, 'p')
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
augroup BWCCreateDir
|
|
||||||
autocmd!
|
|
||||||
autocmd BufWritePre *
|
|
||||||
\ if !empty(expand('<afile>')) |
|
|
||||||
\ call s:MkNonExDir(expand('<afile>'), +expand('<abuf>')) |
|
|
||||||
\ endif
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
" ── Large File Handling ──────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
let g:LargeFile = 1024 * 1024 * 10
|
|
||||||
let s:tty_large = g:is_tty ? 512000 : g:LargeFile
|
|
||||||
|
|
||||||
augroup ChopstickLargeFile
|
|
||||||
autocmd!
|
|
||||||
autocmd BufReadPre *
|
|
||||||
\ if !empty(expand('<afile>')) |
|
|
||||||
\ let s:fsize = getfsize(expand('<afile>')) |
|
|
||||||
\ if s:fsize > g:LargeFile || s:fsize == -2 |
|
|
||||||
\ setlocal bufhidden=unload undolevels=-1 noswapfile syntax= |
|
|
||||||
\ let b:ale_enabled = 0 |
|
|
||||||
\ elseif g:is_tty && s:fsize > s:tty_large |
|
|
||||||
\ setlocal syntax= |
|
|
||||||
\ endif |
|
|
||||||
\ endif
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
if g:is_tty && !exists("g:tty_message_shown")
|
|
||||||
augroup TTYMessage
|
|
||||||
autocmd!
|
|
||||||
autocmd VimEnter * echom "TTY mode — visual features disabled"
|
|
||||||
augroup END
|
|
||||||
let g:tty_message_shown = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── Run Current File (,cr) ──────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function! s:RunFile() abort
|
|
||||||
write
|
|
||||||
let l:ft = &filetype
|
|
||||||
let l:file = shellescape(expand('%:p'))
|
|
||||||
if l:ft ==# 'python' | execute '!python3 ' . l:file
|
|
||||||
elseif l:ft ==# 'javascript' | execute '!node ' . l:file
|
|
||||||
elseif l:ft ==# 'typescript' | execute '!npx ts-node ' . l:file
|
|
||||||
elseif l:ft ==# 'go' | execute '!go run ' . l:file
|
|
||||||
elseif l:ft ==# 'rust' | execute '!cargo run'
|
|
||||||
elseif l:ft ==# 'sh' | execute '!bash ' . l:file
|
|
||||||
elseif l:ft ==# 'c' | execute '!gcc -o /tmp/a.out ' . l:file . ' && /tmp/a.out'
|
|
||||||
elseif l:ft ==# 'lua' | execute '!lua ' . l:file
|
|
||||||
elseif l:ft ==# 'ruby' | execute '!ruby ' . l:file
|
|
||||||
elseif l:ft ==# 'perl' | execute '!perl ' . l:file
|
|
||||||
else | echo 'No runner for filetype: ' . l:ft
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
nnoremap <leader>cr :call <SID>RunFile()<CR>
|
|
||||||
|
|
||||||
" ── Sudo Save ───────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
cnoremap w!! w !sudo tee > /dev/null %
|
|
||||||
|
|
||||||
" ── QuickFix Improvements ───────────────────────────────────────────────────
|
|
||||||
|
|
||||||
augroup ChopstickQF
|
|
||||||
autocmd!
|
|
||||||
autocmd QuickFixCmdPost [^l]* cwindow
|
|
||||||
autocmd QuickFixCmdPost l* lwindow
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
nnoremap <silent> ]q :cnext<CR>
|
|
||||||
nnoremap <silent> [q :cprev<CR>
|
|
||||||
|
|
||||||
" ── Debug Helpers ───────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
nnoremap <leader>sh :call <SID>SynStack()<CR>
|
|
||||||
function! <SID>SynStack()
|
|
||||||
if !exists("*synstack") | return | endif
|
|
||||||
echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
" ── Cheat Sheet (,?) ────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function! s:CheatSheet() abort
|
|
||||||
let l:name = '__ChopsticksCheatSheet__'
|
|
||||||
if bufwinnr(l:name) > 0
|
|
||||||
execute bufwinnr(l:name) . 'wincmd w'
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
execute 'botright new ' . l:name
|
|
||||||
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile
|
|
||||||
call setline(1, [
|
|
||||||
\ '=== chopsticks — Quick Reference ===',
|
|
||||||
\ '',
|
|
||||||
\ 'SURVIVAL',
|
|
||||||
\ ' Esc / jk Exit insert or visual mode',
|
|
||||||
\ ' :q! + Enter Quit without saving',
|
|
||||||
\ ' ,x Save+quit ,w Save Ctrl+s Save (any mode)',
|
|
||||||
\ ' :w!! Sudo save (when you forgot to open as root)',
|
|
||||||
\ '',
|
|
||||||
\ 'FILES & SEARCH',
|
|
||||||
\ ' Ctrl+p Fuzzy find file (git-aware)',
|
|
||||||
\ ' ,e / ,E File browser / vertical split',
|
|
||||||
\ ' ,b Search open buffers',
|
|
||||||
\ ' ,rg Search project contents (ripgrep)',
|
|
||||||
\ ' ,rG Ripgrep word under cursor',
|
|
||||||
\ ' ,fh Recent files history',
|
|
||||||
\ ' ,fl / ,fL Search lines in buffer / all buffers',
|
|
||||||
\ ' ,fc Commands | ,fm Marks',
|
|
||||||
\ ' ,f/ / ,f: Search / command history',
|
|
||||||
\ ' ,, Switch to last file (Ctrl+^)',
|
|
||||||
\ '',
|
|
||||||
\ 'CODE INTELLIGENCE (vim-lsp)',
|
|
||||||
\ ' gd Definition gy Type def gi Impl gr Refs',
|
|
||||||
\ ' K Hover documentation',
|
|
||||||
\ ' [g / ]g Prev / next LSP diagnostic',
|
|
||||||
\ ' [e / ]e Prev / next ALE error',
|
|
||||||
\ ' ,ca Code action ,rn Rename ,f Format',
|
|
||||||
\ ' ,o File outline ,ws Workspace symbols',
|
|
||||||
\ ' ,cr Run current file',
|
|
||||||
\ '',
|
|
||||||
\ 'MARKDOWN & WRITING',
|
|
||||||
\ ' ,mp Live browser preview (previm)',
|
|
||||||
\ ' ,mt Table of contents',
|
|
||||||
\ ' ,zen Zen mode (Goyo + Limelight)',
|
|
||||||
\ ' zr / zm Unfold / fold all headings',
|
|
||||||
\ '',
|
|
||||||
\ 'EDITING',
|
|
||||||
\ ' gc Toggle comment (visual mode too)',
|
|
||||||
\ ' s + 2 chars EasyMotion jump anywhere',
|
|
||||||
\ ' ,u / F5 Undo tree',
|
|
||||||
\ ' ,y / ,Y Yank to system clipboard',
|
|
||||||
\ ' Alt+j / Alt+k Move line down / up',
|
|
||||||
\ ' ,F Re-indent file ,W Strip trailing whitespace',
|
|
||||||
\ ' ,* Search and replace word under cursor',
|
|
||||||
\ '',
|
|
||||||
\ 'GIT',
|
|
||||||
\ ' ,gs Status ,gd Diff ,gb Blame',
|
|
||||||
\ ' ,gc Commit ,gp Push ,gl Pull',
|
|
||||||
\ ' [x / ]x Navigate git conflict markers',
|
|
||||||
\ '',
|
|
||||||
\ 'WINDOWS & PANES',
|
|
||||||
\ ' Ctrl+h/j/k/l Navigate splits and tmux panes',
|
|
||||||
\ ' ,h / ,l Prev / next buffer ,bd Close buffer',
|
|
||||||
\ ' ,z Maximize / restore current window',
|
|
||||||
\ ' ,tv / ,th Terminal (vertical / horizontal)',
|
|
||||||
\ ' Esc Esc Exit terminal mode',
|
|
||||||
\ ' ,= / ,- Resize height ,+ / ,_ Resize width',
|
|
||||||
\ '',
|
|
||||||
\ 'QUICKFIX',
|
|
||||||
\ ' ,qo / ,qc Open / close quickfix',
|
|
||||||
\ ' ]q / [q Next / prev quickfix entry',
|
|
||||||
\ '',
|
|
||||||
\ 'UTILITIES',
|
|
||||||
\ ' ,ev / ,sv Edit / reload ~/.vimrc',
|
|
||||||
\ ' ,cp / ,cf Copy file path / filename to clipboard',
|
|
||||||
\ ' ,ms Scratch buffer ,cd CD to file dir',
|
|
||||||
\ ' ,ss Toggle spell ,so Source current vim file',
|
|
||||||
\ ' F2 Paste F3 Line# F4 Relative# F6 Invisible',
|
|
||||||
\ '',
|
|
||||||
\ '(press q to close)',
|
|
||||||
\ ])
|
|
||||||
setlocal nomodifiable readonly
|
|
||||||
nnoremap <buffer> <silent> q :bd<CR>
|
|
||||||
endfunction
|
|
||||||
nnoremap <silent> <leader>? :call <SID>CheatSheet()<CR>
|
|
||||||
|
|
||||||
" ── Interactive Tutorial ────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function! s:ChopsticksLearn() abort
|
|
||||||
let l:tutor = g:chopsticks_dir . '/tutor/chopsticks.tutor'
|
|
||||||
if !filereadable(l:tutor)
|
|
||||||
echo "Tutorial not found: " . l:tutor
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
execute 'edit ' . fnameescape(l:tutor)
|
|
||||||
setlocal nomodifiable readonly
|
|
||||||
setlocal buftype=nofile bufhidden=wipe
|
|
||||||
setlocal filetype=text
|
|
||||||
setlocal wrap linebreak
|
|
||||||
endfunction
|
|
||||||
command! ChopsticksLearn call s:ChopsticksLearn()
|
|
||||||
164
modules/ui.vim
164
modules/ui.vim
|
|
@ -1,164 +0,0 @@
|
||||||
" ui.vim — colorscheme, statusline, startify, indentline
|
|
||||||
|
|
||||||
" ── Colorscheme (Solarized Dark — matches tmux palette) ────────────────────
|
|
||||||
|
|
||||||
if g:has_true_color && has('termguicolors') && !g:is_tty
|
|
||||||
let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
|
|
||||||
let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
|
|
||||||
set termguicolors
|
|
||||||
endif
|
|
||||||
|
|
||||||
set background=dark
|
|
||||||
|
|
||||||
if !g:is_tty
|
|
||||||
try
|
|
||||||
colorscheme solarized8
|
|
||||||
catch
|
|
||||||
colorscheme default
|
|
||||||
endtry
|
|
||||||
else
|
|
||||||
colorscheme default
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has("gui_running")
|
|
||||||
if has("gui_gtk2") || has("gui_gtk3")
|
|
||||||
set guifont=Hack\ 12,Source\ Code\ Pro\ 12,Monospace\ 12
|
|
||||||
elseif has("gui_win32")
|
|
||||||
set guifont=Consolas:h11:cANSI
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── IndentLine (non-TTY only) ───────────────────────────────────────────────
|
|
||||||
|
|
||||||
if !g:is_tty && exists('g:plugs["indentLine"]')
|
|
||||||
let g:indentLine_char = '|'
|
|
||||||
let g:indentLine_first_char = '|'
|
|
||||||
let g:indentLine_showFirstIndentLevel = 1
|
|
||||||
let g:indentLine_fileTypeExclude = ['text', 'help', 'startify', 'markdown']
|
|
||||||
let g:indentLine_bufTypeExclude = ['help', 'terminal', 'nofile']
|
|
||||||
let g:indentLine_setConceal = 2
|
|
||||||
let g:indentLine_concealcursor = ''
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── Startify ────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
if exists('g:plugs["vim-startify"]')
|
|
||||||
let g:startify_custom_header = [
|
|
||||||
\ ' ██████╗██╗ ██╗ ██████╗ ██████╗ ███████╗████████╗██╗ ██████╗██╗ ██╗███████╗',
|
|
||||||
\ ' ██╔════╝██║ ██║██╔═══██╗██╔══██╗██╔════╝╚══██╔══╝██║██╔════╝██║ ██╔╝██╔════╝',
|
|
||||||
\ ' ██║ ███████║██║ ██║██████╔╝███████╗ ██║ ██║██║ █████╔╝ ███████╗',
|
|
||||||
\ ' ██║ ██╔══██║██║ ██║██╔═══╝ ╚════██║ ██║ ██║██║ ██╔═██╗ ╚════██║',
|
|
||||||
\ ' ╚██████╗██║ ██║╚██████╔╝██║ ███████║ ██║ ██║╚██████╗██║ ██╗███████║',
|
|
||||||
\ ' ╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝',
|
|
||||||
\ '',
|
|
||||||
\ ]
|
|
||||||
|
|
||||||
let g:startify_lists = [
|
|
||||||
\ { 'type': 'sessions', 'header': [' Sessions'] },
|
|
||||||
\ { 'type': 'files', 'header': [' Recent Files'] },
|
|
||||||
\ { 'type': 'dir', 'header': [' Current Dir'] },
|
|
||||||
\ { 'type': 'bookmarks', 'header': [' Bookmarks'] },
|
|
||||||
\ ]
|
|
||||||
|
|
||||||
let g:startify_bookmarks = [{'v': '~/.vimrc'}]
|
|
||||||
if filereadable(expand('~/.zshrc'))
|
|
||||||
call add(g:startify_bookmarks, {'z': '~/.zshrc'})
|
|
||||||
endif
|
|
||||||
if filereadable(expand('~/.bashrc'))
|
|
||||||
call add(g:startify_bookmarks, {'b': '~/.bashrc'})
|
|
||||||
endif
|
|
||||||
if filereadable(expand('~/.config/fish/config.fish'))
|
|
||||||
call add(g:startify_bookmarks, {'f': '~/.config/fish/config.fish'})
|
|
||||||
endif
|
|
||||||
|
|
||||||
let g:startify_session_persistence = 1
|
|
||||||
let g:startify_session_autoload = 1
|
|
||||||
let g:startify_change_to_vcs_root = 1
|
|
||||||
let g:startify_fortune_use_unicode = 0
|
|
||||||
let g:startify_enable_special = 0
|
|
||||||
let g:startify_files_number = 8
|
|
||||||
let g:startify_padding_left = 4
|
|
||||||
|
|
||||||
if !g:is_tty
|
|
||||||
augroup ChopstickStartup
|
|
||||||
autocmd!
|
|
||||||
autocmd StdinReadPre * let s:std_in = 1
|
|
||||||
autocmd VimEnter *
|
|
||||||
\ if argc() == 1 && isdirectory(argv()[0]) && !exists('s:std_in') |
|
|
||||||
\ exe 'cd ' . fnameescape(argv()[0]) |
|
|
||||||
\ if exists(':Startify') == 2 | Startify | else | enew | endif |
|
|
||||||
\ endif
|
|
||||||
augroup END
|
|
||||||
endif
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── Status Line (native — Solarized palette, seamless with tmux bar) ───────
|
|
||||||
|
|
||||||
set laststatus=2
|
|
||||||
set noshowmode
|
|
||||||
|
|
||||||
function! s:SLDefineColors() abort
|
|
||||||
hi SLNormal ctermbg=136 ctermfg=234 cterm=bold guibg=#b58900 guifg=#002b36 gui=bold
|
|
||||||
hi SLInsert ctermbg=33 ctermfg=234 cterm=bold guibg=#268bd2 guifg=#002b36 gui=bold
|
|
||||||
hi SLVisual ctermbg=125 ctermfg=234 cterm=bold guibg=#d33682 guifg=#002b36 gui=bold
|
|
||||||
hi SLReplace ctermbg=160 ctermfg=234 cterm=bold guibg=#dc322f guifg=#002b36 gui=bold
|
|
||||||
hi SLCommand ctermbg=37 ctermfg=234 cterm=bold guibg=#2aa198 guifg=#002b36 gui=bold
|
|
||||||
hi SLBody ctermbg=235 ctermfg=245 cterm=none guibg=#073642 guifg=#93a1a1
|
|
||||||
hi SLFlag ctermbg=235 ctermfg=136 cterm=none guibg=#073642 guifg=#b58900
|
|
||||||
hi SLRight ctermbg=235 ctermfg=240 cterm=none guibg=#073642 guifg=#586e75
|
|
||||||
hi SLGit ctermbg=235 ctermfg=37 cterm=none guibg=#073642 guifg=#2aa198
|
|
||||||
hi SLFtype ctermbg=235 ctermfg=244 cterm=none guibg=#073642 guifg=#839496
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
augroup SLColors
|
|
||||||
autocmd!
|
|
||||||
autocmd ColorScheme * call s:SLDefineColors()
|
|
||||||
augroup END
|
|
||||||
call s:SLDefineColors()
|
|
||||||
|
|
||||||
function! SLMode() abort
|
|
||||||
let l:m = mode()
|
|
||||||
if l:m ==# 'n' | return [' N ', 'SLNormal' ]
|
|
||||||
elseif l:m ==# 'i' | return [' I ', 'SLInsert' ]
|
|
||||||
elseif l:m =~# '[vV]' || l:m ==# "\<C-v>" | return [' V ', 'SLVisual' ]
|
|
||||||
elseif l:m ==# 'R' | return [' R ', 'SLReplace']
|
|
||||||
elseif l:m ==# 'c' | return [' C ', 'SLCommand']
|
|
||||||
elseif l:m ==# 't' | return [' T ', 'SLInsert' ]
|
|
||||||
else | return [' ' . l:m . ' ', 'SLNormal']
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! SLGit() abort
|
|
||||||
if !exists('*FugitiveHead') | return '' | endif
|
|
||||||
let l:b = FugitiveHead()
|
|
||||||
return empty(l:b) ? '' : ' ' . l:b . ' '
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! SLAle() abort
|
|
||||||
if !exists('*ale#statusline#Count') | return '' | endif
|
|
||||||
let l:c = ale#statusline#Count(bufnr(''))
|
|
||||||
let l:e = l:c.error + l:c.style_error
|
|
||||||
let l:w = l:c.warning + l:c.style_warning
|
|
||||||
if l:e == 0 && l:w == 0 | return '' | endif
|
|
||||||
return printf(' E:%d W:%d ', l:e, l:w)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! SLBuild() abort
|
|
||||||
let [l:label, l:hl] = SLMode()
|
|
||||||
let l:s = '%#' . l:hl . '#' . l:label
|
|
||||||
let l:s .= '%#SLBody# %f '
|
|
||||||
let l:s .= '%#SLFlag#%m%r'
|
|
||||||
let l:s .= '%#SLBody#%='
|
|
||||||
let l:s .= '%#SLFlag#' . SLAle()
|
|
||||||
let l:s .= '%#SLGit#' . SLGit()
|
|
||||||
let l:s .= '%#SLFtype# %y '
|
|
||||||
let l:s .= '%#SLRight# %l:%c %P '
|
|
||||||
return l:s
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
set statusline=%!SLBuild()
|
|
||||||
|
|
||||||
if g:is_tty
|
|
||||||
set statusline=%f\ %h%w%m%r\ %=%(%l,%c%V\ %=\ %P%)
|
|
||||||
endif
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
" writing.vim — vim-markdown, previm, goyo + limelight zen mode
|
|
||||||
|
|
||||||
" ── vim-markdown ────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
let g:vim_markdown_conceal = 1
|
|
||||||
let g:vim_markdown_conceal_code_blocks = 0
|
|
||||||
let g:vim_markdown_folding_disabled = 0
|
|
||||||
let g:vim_markdown_folding_level = 2
|
|
||||||
let g:vim_markdown_frontmatter = 1
|
|
||||||
let g:vim_markdown_toml_frontmatter = 1
|
|
||||||
let g:vim_markdown_json_frontmatter = 1
|
|
||||||
let g:vim_markdown_follow_anchor = 1
|
|
||||||
let g:vim_markdown_new_list_item_indent = 2
|
|
||||||
let g:vim_markdown_strikethrough = 1
|
|
||||||
|
|
||||||
if exists('g:plugs["vim-markdown"]')
|
|
||||||
nnoremap <leader>mt :Toc<CR>
|
|
||||||
endif
|
|
||||||
|
|
||||||
" ── previm (Markdown browser preview) ───────────────────────────────────────
|
|
||||||
|
|
||||||
if has('macunix')
|
|
||||||
let g:previm_open_cmd = '/usr/bin/open'
|
|
||||||
elseif executable('xdg-open')
|
|
||||||
let g:previm_open_cmd = 'xdg-open'
|
|
||||||
endif
|
|
||||||
if exists('g:plugs["previm"]')
|
|
||||||
nnoremap <leader>mp :PrevimOpen<CR>
|
|
||||||
endif
|
|
||||||
let g:previm_enable_realtime = 1
|
|
||||||
|
|
||||||
" ── Goyo + Limelight (zen mode) ────────────────────────────────────────────
|
|
||||||
|
|
||||||
if exists('g:plugs["goyo.vim"]')
|
|
||||||
let g:goyo_width = 80
|
|
||||||
let g:goyo_height = '85%'
|
|
||||||
nnoremap <leader>zen :Goyo<CR>
|
|
||||||
|
|
||||||
function! s:goyo_enter()
|
|
||||||
if exists('g:plugs["limelight.vim"]') | Limelight | endif
|
|
||||||
set wrap linebreak scrolloff=999
|
|
||||||
endfunction
|
|
||||||
function! s:goyo_leave()
|
|
||||||
if exists('g:plugs["limelight.vim"]') | Limelight! | endif
|
|
||||||
set nowrap nolinebreak scrolloff=10
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
augroup ChopstickGoyo
|
|
||||||
autocmd!
|
|
||||||
autocmd User GoyoEnter nested call s:goyo_enter()
|
|
||||||
autocmd User GoyoLeave nested call s:goyo_leave()
|
|
||||||
augroup END
|
|
||||||
endif
|
|
||||||
|
|
||||||
let g:limelight_conceal_ctermfg = 240
|
|
||||||
let g:limelight_conceal_guifg = '#586e75'
|
|
||||||
|
|
@ -1,269 +0,0 @@
|
||||||
================================================================================
|
|
||||||
= C H O P S T I C K S I N T E R A C T I V E T U T O R =
|
|
||||||
================================================================================
|
|
||||||
|
|
||||||
This tutorial teaches the key features of the chopsticks Vim configuration.
|
|
||||||
It assumes you already know basic Vim (if not, run :Tutor first).
|
|
||||||
|
|
||||||
Leader key is , (comma) throughout this tutorial.
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Lesson 1: SURVIVAL BASICS
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
These four commands get you out of any situation:
|
|
||||||
|
|
||||||
1. Press Esc or type jk to return to Normal mode
|
|
||||||
2. Type ,w to save the current file
|
|
||||||
3. Type ,x to save and quit
|
|
||||||
4. Type ,q to quit (without saving)
|
|
||||||
|
|
||||||
TIP: You can also press Ctrl+s to save from ANY mode (normal, insert,
|
|
||||||
or visual). Try it now — press i to enter insert mode, then Ctrl+s
|
|
||||||
to save without leaving insert mode.
|
|
||||||
|
|
||||||
When completely lost, press ,? to open the cheat sheet with every
|
|
||||||
keybinding. Press q to close it.
|
|
||||||
|
|
||||||
>>> Try it now: press ,? then read through the sheet, then press q
|
|
||||||
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Lesson 2: FINDING FILES
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
chopsticks uses FZF (fuzzy finder) for fast navigation.
|
|
||||||
|
|
||||||
Ctrl+p Fuzzy find files (git-aware — ignores .gitignore'd files)
|
|
||||||
,b Search open buffers
|
|
||||||
,fh Recent file history
|
|
||||||
,rg Search file contents with ripgrep
|
|
||||||
,rG Search for the word under your cursor
|
|
||||||
|
|
||||||
>>> Try it now: press Ctrl+p and start typing a filename
|
|
||||||
|
|
||||||
You can also browse files with the built-in file browser:
|
|
||||||
|
|
||||||
,e Open netrw file browser in current window
|
|
||||||
,E Open netrw in a vertical split
|
|
||||||
|
|
||||||
Inside netrw:
|
|
||||||
Enter Open file
|
|
||||||
- Go up one directory
|
|
||||||
% Create new file
|
|
||||||
d Create new directory
|
|
||||||
gh Toggle hidden files
|
|
||||||
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Lesson 3: CODE INTELLIGENCE
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
chopsticks uses vim-lsp for code intelligence — no Node.js required.
|
|
||||||
|
|
||||||
First, install a language server for your filetype:
|
|
||||||
|
|
||||||
:LspInstallServer (auto-detects the language)
|
|
||||||
:LspStatus (check if it's running)
|
|
||||||
|
|
||||||
Once a server is running, these keys become available:
|
|
||||||
|
|
||||||
gd Go to definition
|
|
||||||
gy Go to type definition
|
|
||||||
gi Go to implementation
|
|
||||||
gr List all references
|
|
||||||
K Show hover documentation
|
|
||||||
|
|
||||||
[g / ]g Jump to previous / next diagnostic
|
|
||||||
,rn Rename symbol under cursor
|
|
||||||
,ca Code action (auto-fix)
|
|
||||||
,f Format buffer (or selection in visual mode)
|
|
||||||
,o File outline (symbols)
|
|
||||||
|
|
||||||
>>> Open a source file and try: gd on a function call, then Ctrl+o
|
|
||||||
to jump back
|
|
||||||
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Lesson 4: EDITING POWER
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
These editing features make chopsticks faster than vanilla Vim.
|
|
||||||
|
|
||||||
EASYMOTION — jump anywhere on screen:
|
|
||||||
Press s then type two characters from your target location.
|
|
||||||
Matching positions light up — press the highlighted letter to jump.
|
|
||||||
|
|
||||||
>>> Try it now: press s then type two letters you can see on screen
|
|
||||||
|
|
||||||
MOVE LINES — rearrange code without cut/paste:
|
|
||||||
Alt+j Move current line down
|
|
||||||
Alt+k Move current line up
|
|
||||||
(Works in visual mode too — select lines first with V )
|
|
||||||
|
|
||||||
SURROUND — change surrounding characters:
|
|
||||||
cs"' Change surrounding " to '
|
|
||||||
cs'<div> Change surrounding ' to <div>...</div>
|
|
||||||
ds( Delete surrounding parentheses
|
|
||||||
ysiw" Surround word with "
|
|
||||||
|
|
||||||
COMMENT — toggle comments:
|
|
||||||
gc Toggle comment (works in visual mode on selections)
|
|
||||||
gcc Toggle comment on current line
|
|
||||||
|
|
||||||
VISUAL FEEDBACK:
|
|
||||||
- Yanked text flashes briefly so you know what was copied
|
|
||||||
- Search highlights auto-clear after you stop moving
|
|
||||||
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Lesson 5: GIT WORKFLOW
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
All git operations through vim-fugitive:
|
|
||||||
|
|
||||||
,gs Git status (press s to stage, press cc to commit)
|
|
||||||
,gd Diff current file (side-by-side split)
|
|
||||||
,gb Git blame (who changed each line)
|
|
||||||
,gc Git commit
|
|
||||||
,gp Git push
|
|
||||||
,gl Git pull
|
|
||||||
|
|
||||||
GitGutter shows changes in the sign column (left margin):
|
|
||||||
+ Added line
|
|
||||||
~ Modified line
|
|
||||||
- Deleted line
|
|
||||||
|
|
||||||
Navigate git conflict markers:
|
|
||||||
]x Jump to next conflict marker
|
|
||||||
[x Jump to previous conflict marker
|
|
||||||
|
|
||||||
>>> Try ,gs in a git repository to see the status view
|
|
||||||
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Lesson 6: MARKDOWN & WRITING
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Markdown files get special treatment automatically:
|
|
||||||
- Word wrap enabled
|
|
||||||
- Spell checking enabled
|
|
||||||
- Syntax concealment (bold renders as bold, headings hide # markers)
|
|
||||||
- Folding by heading level
|
|
||||||
|
|
||||||
Key bindings for markdown:
|
|
||||||
|
|
||||||
,mp Open live browser preview (auto-refreshes as you type)
|
|
||||||
,mt Table of contents in a side window
|
|
||||||
,zen Enter zen mode — Goyo + Limelight
|
|
||||||
(distraction-free writing, only current paragraph highlighted)
|
|
||||||
zr Unfold all headings
|
|
||||||
zm Fold all headings
|
|
||||||
|
|
||||||
>>> Open a .md file and try ,zen to enter zen mode.
|
|
||||||
Press ,zen again to leave.
|
|
||||||
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Lesson 7: WINDOW MANAGEMENT
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Navigate between splits (works with tmux panes too):
|
|
||||||
|
|
||||||
Ctrl+h Move to left split
|
|
||||||
Ctrl+j Move to split below
|
|
||||||
Ctrl+k Move to split above
|
|
||||||
Ctrl+l Move to right split
|
|
||||||
|
|
||||||
Buffer navigation:
|
|
||||||
|
|
||||||
,h Previous buffer
|
|
||||||
,l Next buffer
|
|
||||||
,bd Close buffer (keeps window layout)
|
|
||||||
,, Switch to last file (toggle between two files)
|
|
||||||
|
|
||||||
Window tricks:
|
|
||||||
|
|
||||||
,z Maximize current window (press again to restore)
|
|
||||||
,= / ,- Resize window height (bigger / smaller)
|
|
||||||
,+ / ,_ Resize window width (bigger / smaller)
|
|
||||||
|
|
||||||
Terminal:
|
|
||||||
|
|
||||||
,tv Open terminal (vertical split)
|
|
||||||
,th Open terminal (horizontal, 10 rows)
|
|
||||||
Esc Esc Exit terminal mode back to normal
|
|
||||||
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Lesson 8: LINTING & FORMATTING
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
ALE runs linters and formatters automatically:
|
|
||||||
|
|
||||||
- Linting happens as you type (normal mode) and on save
|
|
||||||
- Format-on-save is enabled by default (black, prettier, gofmt, etc.)
|
|
||||||
|
|
||||||
Navigate errors:
|
|
||||||
|
|
||||||
[e / ]e Previous / next ALE error
|
|
||||||
,aD Show error detail in a popup
|
|
||||||
|
|
||||||
Supported out of the box:
|
|
||||||
Python: flake8 + pylint (lint), black + isort (format)
|
|
||||||
JS/TS: eslint (lint), prettier + eslint (format)
|
|
||||||
Go: staticcheck (lint), goimports (format)
|
|
||||||
Rust: cargo (lint), rustfmt (format)
|
|
||||||
Shell: shellcheck (lint)
|
|
||||||
And more: yaml, dockerfile, css, markdown, sql
|
|
||||||
|
|
||||||
>>> Write some intentionally bad code and watch the sign column
|
|
||||||
light up with X (error) and ! (warning) markers
|
|
||||||
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Lesson 9: RUNNING CODE
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Press ,cr to run the current file. It auto-detects the language:
|
|
||||||
|
|
||||||
Python → python3 file.py
|
|
||||||
JavaScript → node file.js
|
|
||||||
TypeScript → npx ts-node file.ts
|
|
||||||
Go → go run file.go
|
|
||||||
Rust → cargo run
|
|
||||||
Shell → bash file.sh
|
|
||||||
C → gcc + run
|
|
||||||
Lua, Ruby, Perl also supported
|
|
||||||
|
|
||||||
>>> Create a test file (e.g. test.py with: print("hello"))
|
|
||||||
and press ,cr to run it
|
|
||||||
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Lesson 10: DAILY TIPS
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
SEARCH AND REPLACE:
|
|
||||||
,* Replace word under cursor throughout the file
|
|
||||||
// In visual mode, search for selected text
|
|
||||||
|
|
||||||
USEFUL SHORTCUTS:
|
|
||||||
Y Yank to end of line (consistent with D and C)
|
|
||||||
,y / ,Y Yank to system clipboard
|
|
||||||
,F Re-indent entire file
|
|
||||||
,W Strip all trailing whitespace
|
|
||||||
:w!! Sudo save (when you forgot to open as root)
|
|
||||||
,ev Edit your vimrc
|
|
||||||
,sv Reload your vimrc
|
|
||||||
|
|
||||||
SESSIONS:
|
|
||||||
:Obsess Start recording session (auto-restores next time)
|
|
||||||
:Obsess! Stop recording
|
|
||||||
|
|
||||||
The startup screen (Startify) shows recent files, sessions, and bookmarks.
|
|
||||||
|
|
||||||
>>> Press ,? one more time to review the full cheat sheet.
|
|
||||||
You now know the essential chopsticks features. Happy editing!
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
Loading…
Reference in a new issue