Neovim plugin for sase integration. Provides filetype detection and syntax highlighting for project spec files, plus YAML language server schema configuration for sase config and xprompt files.
Automatic detection and syntax highlighting for project spec files (~/.sase/projects/<project>/<project>.gp) with
colors matching the sase ace TUI:
- Field labels (
NAME:,STATUS:,HOOKS:,RUNNING:,WORKSPACE_DIR:, etc.) - Status values with distinct colors (WIP, Draft, Ready, Mailed, Submitted, Reverted, Archived)
- Entry numbers, proposed entries, and sub-entries
- Inline process states (PASSED, FAILED, RUNNING, DEAD, KILLED, STARTING)
- Suffix badges with background colors for errors, running agents/processes, and other markers
- Timestamps, durations, URLs, file paths, and test targets
- Hook command prefixes, reviewer types, and draft markers
Insert-mode <C-t> asks the SASE xprompt LSP for completion when available, then falls back to the legacy picker
dispatcher when the server command is unavailable or disabled:
| Cursor on… | Opens… |
|---|---|
#token / #!token (xprompt reference) |
LSP completion, or legacy xprompt picker |
/skill / /partial (slash skill) |
LSP completion, or skill-filtered picker |
%directive |
LSP directive completion |
path-like token (~/foo, ./bar, a/b.c…) |
LSP file completion, or file picker |
| empty / no token | LSP recent-file completion, or recent files picker |
The keymap is opt-in — add this to your config to enable it:
require("sase").setup({
complete = {
keymap = true, -- or keymap = "<C-t>"
completion_backend = "auto", -- "auto", "lsp", or "legacy"
},
lsp = {
enabled = true,
cmd = nil, -- string/table override; otherwise SASE_XPROMPT_LSP_CMD, `sase lsp`, or `sase-xprompt-lsp`
},
})completion_backend = "auto" is the default. It uses the LSP when sase lsp --version succeeds or
sase-xprompt-lsp is executable, and otherwise keeps the existing picker behavior. Set
completion_backend = "legacy" or lsp.enabled = false to keep the old picker-only path.
The legacy xprompt picker uses sase xprompt list insertion metadata. Inline xprompts
and embeddable workflows insert as #name; standalone workflows insert as
#!name. Typing #! before <C-t> filters the picker to standalone workflows.
Typing / or /partial before <C-t> filters the picker to entries where
sase xprompt list reports is_skill = true, and inserts the selected skill as
/name.
In the recent-files picker, <C-l> (or <Enter>) inserts the highlighted path and <C-d>
removes the highlighted entry from ~/.sase/file_reference_history.json and refreshes the
picker in place. Run :SaseFileHistoryRefresh to drop the cached list so the next <C-t>
re-fetches from sase file-history list.
In the fallback file-system picker, candidates come from sase file list --path <cwd> --token <token>. Selecting a file
inserts the full path; selecting a directory drills down and re-opens the picker rooted at the chosen directory.
Typing #@ opens the xprompt picker in insert mode. Picker entries show the
same reference text that will be inserted, so standalone workflows appear as
#!sync while inline-capable prompts and workflows appear as #commit. Closing
the picker without a selection restores the original single #.
Automatically configures yamlls with schema associations for sase YAML files:
- Config schema — Applied to
sase.ymlandsase_*.ymlfiles - XPrompt workflow schema — Applied to files under
xprompts/and.xprompts/directories - XPrompt collection schema — Applied to
xprompts.yml/xprompts.yamlfiles
Schema paths are resolved asynchronously via sase path to avoid blocking Neovim startup.
The plugin can start the SASE xprompt language server for Markdown, git commit, sase, and sase_prompt buffers.
LSP-backed completion is the normal path after setup():
require("sase").setup({
complete = {
keymap = true,
completion_backend = "auto", -- default: uses LSP when available, legacy picker otherwise
},
lsp = {
enabled = true, -- default
-- cmd = { "sase", "lsp" },
},
})Command resolution prefers lsp.cmd, then SASE_XPROMPT_LSP_CMD, then a verified sase lsp, then
sase-xprompt-lsp. The LSP client uses .sase or .git as the project root when available. The #@ trigger and
:SaseXPrompts picker commands remain picker-based browse surfaces. They keep using sase xprompt list until the LSP
exposes a browse/catalog request, and file-history deletion keeps using sase file-history delete.
When the LSP is attached, normal Neovim go-to-definition works for disk-backed xprompt references. Use your existing
LSP mapping, such as gd, or call vim.lsp.buf.definition() on #foo, #!workflow, namespaced references like
#gh__review, or slash skills like /sase_plan. The plugin does not parse source paths in Lua; it relies on the
server's standard textDocument/definition response.
For troubleshooting, check Neovim's LSP log (:lua print(vim.lsp.get_log_path())) and verify the server command with
sase lsp --version or sase-xprompt-lsp --version.
- Neovim >= 0.8
saseonPATHfor picker fallback, file-history deletion, schema discovery, and the default LSP wrappersase lspsupport or a standalonesase-xprompt-lspbinary for LSP-backed completion- Optional:
nvim-telescope/telescope.nvimfor the richer picker UI. Without Telescope, pickers fall back tovim.ui.select. - Optional:
yamlls/yaml-language-serverif you want automatic sase YAML schema associations.
-- Remote
{ "sase-org/sase-nvim" }
-- Local
{
name = "sase-nvim",
dir = "~/projects/github/sase-org/sase-nvim",
}use "sase-org/sase-nvim"Plug 'sase-org/sase-nvim'Most plugin files load automatically when Neovim starts:
.gpfiletype detection and syntax highlighting#@insert-mode xprompt picker trigger:SaseXPrompts,:SaseXPromptsRefresh, and:SaseFileHistoryRefresh- YAML schema registration for
yamlls
The <C-t> completion dispatcher is opt-in:
require("sase").setup({
complete = {
keymap = true, -- binds <C-t>
},
})To use a different insert-mode mapping:
require("sase").setup({
complete = {
keymap = "<C-x><C-s>",
},
})To force the picker-only fallback:
require("sase").setup({
complete = {
keymap = true,
completion_backend = "legacy",
},
lsp = {
enabled = false,
},
})| Command | Description |
|---|---|
:SaseXPrompts |
Open the xprompt picker manually |
:SaseXPromptsRefresh |
Refresh the cached sase xprompt list results |
:SaseFileHistoryRefresh |
Refresh the cached sase file-history list data |
├── ftdetect/
│ └── sase_gp.lua # Filetype detection for .gp files under .sase/projects/
├── lua/
│ ├── sase/
│ │ ├── init.lua # require("sase").setup entry point
│ │ ├── lsp.lua # xprompt LSP client setup
│ │ ├── xprompt.lua # #@ xprompt picker core
│ │ └── complete/
│ │ ├── _picker.lua # shared insertion and insert-mode restore helpers
│ │ ├── _token.lua # legacy fallback token classification
│ │ ├── file.lua # fallback file-system picker
│ │ ├── file_history.lua # fallback recent-file picker
│ │ └── xprompt.lua # fallback xprompt picker wrapper
│ └── telescope/
│ └── _extensions/sase.lua # Telescope pickers for xprompts, files, and recent files
├── plugin/
│ ├── sase_complete.lua # completion cache command registration
│ ├── sase_xprompt.lua # #@ trigger and xprompt commands
│ └── sase_yamlls.lua # YAML language server schema configuration
└── syntax/
└── sase_gp.vim # Syntax highlighting rules
MIT