ac14cdd838
coc users had to hand-maintain a coc-settings.json `languageserver.nuwiki`
entry, which didn't track g:nuwiki_wikis / g:vimwiki_list / the global
shorthand and meant editing JSON per wiki. nuwiki now registers itself
programmatically: on the first .wiki buffer it calls
coc#config('languageserver.nuwiki', {…}) with the s:settings() payload
(same config the vim-lsp path sends). coc reacts to the languageserver
config change (onDidChangeConfiguration → registerClientsByConfig) and
starts the server for the open buffer.
Details:
- Reliable coc detection via :CocConfig (exists('*coc#config') can't be
trusted — it doesn't trigger autoload in Vim 9.2). The coc#config call
is wrapped in try/catch and autoloads coc.vim itself; falls back to the
printed snippet only if coc genuinely isn't there.
- Deferred to User CocNvimInit when coc's node service isn't up yet.
- Opt out with g:nuwiki_no_coc_register (then we just print the snippet).
Dogfooded in start-vim-coc.sh: dropped the manual coc-settings.json
languageserver block; the harness now relies on auto-registration from
g:nuwiki_* (real-user flow). New harness test-coc-register-vim (7 checks,
stubbed coc#config) asserts the injected payload incl. the folded global
shorthand; wired into CI. README coc section rewritten (zero-config).
Rust 573 passed, clippy clean, all harnesses green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
169 lines
6.0 KiB
Bash
Executable File
169 lines
6.0 KiB
Bash
Executable File
#!/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"
|
|
# No `languageserver.nuwiki` block here on purpose: this dogfoods nuwiki's
|
|
# *programmatic* coc registration (autoload/nuwiki/lsp.vim → coc#config). The
|
|
# plugin registers the server itself from g:nuwiki_* (set in the vimrc),
|
|
# exactly the "no hand-written coc-settings.json" flow real users get. Only
|
|
# the jump-command preference (the <CR>-opens-a-tab reproducer) lives here.
|
|
cat > "$COC_SETTINGS" <<EOF
|
|
{
|
|
"coc.preferences.jumpCommand": "$COC_JUMP"
|
|
}
|
|
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'
|
|
" nuwiki auto-registers itself with coc from these globals (no coc-settings.json
|
|
" languageserver block). Display settings exercise the global shorthand:
|
|
" :NuwikiTOC writes `== Contents ==` (level 2) and HTML export numbers headings.
|
|
let g:nuwiki_toc_header_level = 2
|
|
let g:nuwiki_html_header_numbering = 2
|
|
let g:nuwiki_html_header_numbering_sym = ' -'
|
|
|
|
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 "$@"
|