Files

185 lines
6.3 KiB
Bash
Raw Permalink Normal View History

#!/usr/bin/env bash
#
# start-vim-coc.sh — launch Vim with a minimal config that loads nuwiki
# through coc.nvim (instead of vim-lsp).
#
# The plugin's Vim path (autoload/nuwiki/lsp.vim) prefers `vim-lsp` and falls
# back to `coc.nvim`. start-vim.sh exercises the vim-lsp path; this script
# exercises the coc.nvim path. vim-lsp is deliberately kept OFF the runtimepath
# so `:LspDefinition` doesn't exist and nuwiki's coc branch is the one that runs
# (s:jump_definition() → CocActionAsync('jumpDefinition', 'edit')).
#
# This doubles as a reproducer for the "<CR> opens a new tab" regression:
# coc-settings.json sets coc.preferences.jumpCommand to `tabe`, so without the
# fix `<CR>` on a link opens a new tab. With the fix nuwiki passes 'edit'
# explicitly and the target opens in the *current* window regardless.
#
# It clones coc.nvim's prebuilt `release` branch into the dev cache on first
# run (no yarn/build needed — it just needs Node.js at runtime).
#
# Usage: ./development/start-vim-coc.sh [extra args...]
# ./development/start-vim-coc.sh # open the scratch wiki's index
# ./development/start-vim-coc.sh path/to/note.wiki # open a specific file
# NUWIKI_DEV_WIKI=/tmp/foo ./development/start-vim-coc.sh
# NUWIKI_DEV_NO_SEED=1 ./development/start-vim-coc.sh # use WIKI_DIR as-is (no scratch seeding)
# NUWIKI_DEV_SKIP_BUILD=1 ./development/start-vim-coc.sh # reuse the cached binary
# NUWIKI_DEV_COC_JUMP=edit ./development/start-vim-coc.sh # change coc.preferences.jumpCommand
#
# The release binary is rebuilt on every launch so source changes always reach
# the running LSP. `cargo build --release` is incremental, so this is a fast
# no-op when nothing changed. Set NUWIKI_DEV_SKIP_BUILD=1 to skip the build.
#
# Each launch starts clean: the scratch wiki is reseeded from a pristine
# copy and the editor state (viminfo/swap/undo, coc data) is wiped, so stale
# edits never carry over. The cached coc.nvim clone is kept. A wiki you point
# at with NUWIKI_DEV_WIKI is never wiped (seeded only if empty).
#
# Tested with Vim 9.1+ and Node 18+. State (viminfo/sessions, coc data) lives
# under $XDG_CACHE_HOME/nuwiki-dev/ so your real Vim install stays untouched.
set -euo pipefail
# Shared paths + helpers (log, ensure_binary, write_sample_wiki, seed_wiki).
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/_common.sh"
VIMRC="$DEV_DIR/vimrc-coc"
VIM_STATE="$DEV_DIR/vim-coc-state"
COC_DIR="$DEV_DIR/coc.nvim"
COC_DATA="$DEV_DIR/coc-data"
COC_SETTINGS="$DEV_DIR/coc-settings.json"
COC_JUMP="${NUWIKI_DEV_COC_JUMP:-tabe}"
ensure_node() {
if ! command -v node >/dev/null 2>&1; then
log 'node not found — coc.nvim needs Node.js at runtime; skipping'
exit 0
fi
}
ensure_coc() {
mkdir -p "$DEV_DIR"
if [[ -d "$COC_DIR/.git" ]]; then
return
fi
if ! command -v git >/dev/null 2>&1; then
log 'git not found — cannot clone coc.nvim; skipping'
exit 0
fi
log "cloning coc.nvim (release branch) → $COC_DIR"
git clone --depth 1 --branch release \
https://github.com/neoclide/coc.nvim.git "$COC_DIR" >/dev/null 2>&1
}
write_coc_settings() {
mkdir -p "$DEV_DIR"
# Mirror what the vim-lsp client sends (autoload/nuwiki/lsp.vim s:settings()):
# both `initializationOptions` (sent on initialize) and `settings.nuwiki`
# (served via workspace/configuration). Without these the server falls back
# to its own default wiki_root (~/vimwiki) instead of $WIKI_DIR, so it can't
# resolve links (e.g. Notes shows as broken) or create-on-follow correctly.
cat > "$COC_SETTINGS" <<EOF
{
"coc.preferences.jumpCommand": "$COC_JUMP",
"languageserver": {
"nuwiki": {
"command": "$REPO_ROOT/bin/nuwiki-ls",
"filetypes": ["vimwiki"],
"initializationOptions": {
"wiki_root": "$WIKI_DIR",
"file_extension": ".wiki",
"syntax": "vimwiki",
"log_level": "info",
"diagnostic": { "link_severity": "warn" }
},
"settings": {
"nuwiki": {
"wiki_root": "$WIKI_DIR",
"file_extension": ".wiki",
"syntax": "vimwiki",
"log_level": "info",
"diagnostic": { "link_severity": "warn" }
}
}
}
}
}
EOF
}
write_vimrc() {
mkdir -p "$DEV_DIR"
cat > "$VIMRC" <<EOF
" start-vim-coc.sh: generated minimal config for nuwiki development (coc.nvim).
" Regenerated on every launch; edit start-vim-coc.sh, not this file.
" Confine state to the dev cache so we never touch the user's real Vim
" install.
set viminfo='100,n${VIM_STATE}/viminfo
let &directory = '${VIM_STATE}/swap//'
let &backupdir = '${VIM_STATE}/backup//'
let &undodir = '${VIM_STATE}/undo//'
" Make Vim look for runtime paths in the dev cache. vim-lsp is intentionally
" absent so nuwiki dispatches jump-to-definition through coc.
set nocompatible
let &runtimepath = '${REPO_ROOT}' . ',' . &runtimepath
let &runtimepath .= ',${COC_DIR}'
let &runtimepath .= ',${DEV_DIR}/calendar-vim'
" Point coc at the generated settings + a private data dir.
let g:coc_config_home = '${DEV_DIR}'
let g:coc_data_home = '${COC_DATA}'
let g:nuwiki_binary_path = '${REPO_ROOT}/bin/nuwiki-ls'
let g:nuwiki_wiki_root = '${WIKI_DIR}'
let g:nuwiki_file_extension = '.wiki'
let g:nuwiki_syntax = 'vimwiki'
let g:nuwiki_diary_rel_path = 'diary'
let g:nuwiki_log_level = 'info'
filetype plugin indent on
syntax enable
set hidden
set termguicolors
set number
set signcolumn=yes
set noswapfile
set nobackup
set nowritebackup
let mapleader = ' '
" Auto-detect filetype for .wiki files (the plugin ships ftdetect, but
" --clean disables those — copy the rule here).
augroup NuwikiFtdetect
autocmd!
autocmd BufRead,BufNewFile *.wiki setfiletype vimwiki
augroup END
echo
echomsg '[nuwiki-dev] coc.preferences.jumpCommand = ' . '\$COC_JUMP'
echomsg '[nuwiki-dev] <CR> on a [[link]] should open in the CURRENT window'
echomsg '[nuwiki-dev] :CocList services for status, :messages for log'
EOF
}
main() {
ensure_node
ensure_binary
ensure_coc
ensure_calendar_vim
write_coc_settings
seed_wiki
write_vimrc
reset_dirs "$VIM_STATE" "$COC_DATA"
mkdir -p "$VIM_STATE/swap" "$VIM_STATE/backup" "$VIM_STATE/undo" "$COC_DATA"
log "launching: vim --clean -u $VIMRC"
if [[ $# -gt 0 ]]; then
exec vim --clean -u "$VIMRC" "$@"
else
exec vim --clean -u "$VIMRC" "$WIKI_DIR/index.wiki"
fi
}
main "$@"