3b92b11948
Resolves the 18 findings from the parallel codebase review, tracked in development/vimwiki-gap.md. Correctness / perf: - Wiki.config -> Arc<WikiConfig> so cloning a Wiki is a refcount bump (R5) - WorkspaceIndex::remove is no longer O(n^2): a per-source contributions map limits the scan to buckets the source actually wrote into (R6) - render_color now expands color_tag_template (__STYLE__/__CONTENT__), consuming the previously-dead field; ColorNode documented as an extension point; 3 renderer tests added (R3/R4) - wiki_root_for returns empty/nil on no-match instead of falling back to the first wiki (R2); auto_header honours links_space_char (R7) Cleanup / dedup: - Remove dead #[allow(dead_code)] stubs + uncalled pub helpers, narrow imports (R10/R11) - Dedup span_of_inline x3 -> InlineNode::span() (R12) - diary_step single read lock; page_captions single pass (R13) - Lua auto_header loop -> wiki_list(); detect_current_symbol cleanup (R14/R18) Client / docs: - :VimwikiNormalizeLink Vim cmds -> <q-args> (R17); ftplugin header fix (R16); vars.vim multi-wiki limitation documented (R15) - Document 19 config options in README.md + doc/nuwiki.txt; fix list_margin/shiftwidth doc and stale comments (R1/R9) - R8 investigated, confirmed not a real bug (documented) Verified: Neovim harness 307, Vim harness 301/18/21, Rust suite 568, all 0 failed; clippy clean; fresh parallel-agent audit found no regressions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
59 lines
1.6 KiB
Rust
59 lines
1.6 KiB
Rust
//! Registry of syntax plugins.
|
|
//!
|
|
//! Plugins are stored behind `Arc<dyn SyntaxPlugin>` so the LSP layer can
|
|
//! hand a cheap clone to per-document tasks without re-locking the registry.
|
|
|
|
use std::sync::Arc;
|
|
|
|
use super::SyntaxPlugin;
|
|
|
|
#[derive(Default, Clone)]
|
|
pub struct SyntaxRegistry {
|
|
plugins: Vec<Arc<dyn SyntaxPlugin>>,
|
|
}
|
|
|
|
impl SyntaxRegistry {
|
|
pub fn new() -> Self {
|
|
Self::default()
|
|
}
|
|
|
|
/// Register a plugin owned directly. The most common shape — implementer
|
|
/// hands over a value, registry takes ownership.
|
|
pub fn register<P>(&mut self, plugin: P)
|
|
where
|
|
P: SyntaxPlugin + 'static,
|
|
{
|
|
self.plugins.push(Arc::new(plugin));
|
|
}
|
|
|
|
/// Look up a plugin by its `id`.
|
|
pub fn get(&self, id: &str) -> Option<&dyn SyntaxPlugin> {
|
|
self.plugins
|
|
.iter()
|
|
.find(|p| p.id() == id)
|
|
.map(|p| p.as_ref())
|
|
}
|
|
|
|
/// Look up a plugin by file extension. `ext` should include the leading
|
|
/// dot (e.g. `".wiki"`) — matches the plugin's `file_extensions()`.
|
|
pub fn detect_from_extension(&self, ext: &str) -> Option<&dyn SyntaxPlugin> {
|
|
self.plugins
|
|
.iter()
|
|
.find(|p| p.file_extensions().iter().any(|e| *e == ext))
|
|
.map(|p| p.as_ref())
|
|
}
|
|
|
|
/// Iterate over registered plugins in registration order.
|
|
pub fn iter(&self) -> impl Iterator<Item = &dyn SyntaxPlugin> + '_ {
|
|
self.plugins.iter().map(|p| p.as_ref())
|
|
}
|
|
|
|
pub fn len(&self) -> usize {
|
|
self.plugins.len()
|
|
}
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
self.plugins.is_empty()
|
|
}
|
|
}
|