在Sublime Text中开发XML跨文档引用自动补全插件
Great question! Since you’re working with a custom XML spec that supports cross-document references, here are two practical approaches to build the auto-completion you need—one leveraging Sublime’s native tools, and another using a more flexible language server setup.
Option 1: Quick Win with Sublime’s Native .sublime-completions
Sublime lets you define project-specific completion rules, and you can automate the population of XML files and their symbols with a simple script.
Create a project-specific completion file
First, open your project and head toPreferences > Browse Packagesto locate theUserfolder. Create a file named[YourProjectName].sublime-completionshere. It’ll look something like this:{ "scope": "text.xml", // Only trigger in XML files "completions": [ { "trigger": "xref:", "contents": "<xref href=\"$1\" />", "annotation": "Reference XML document/symbol" }, // Auto-generated entries will go here ] }Auto-scan project XML files and symbols
Manually adding every file and symbol is tedious, so write a quick Python script (Sublime supports Python plugins) to do the heavy lifting. Here’s a simplified example:import os import xml.etree.ElementTree as ET from sublime import active_window def generate_xml_ref_completions(): # Get the current project folder project_root = active_window().folders()[0] completions = [] # Walk through all XML files in the project for root, _, files in os.walk(project_root): for file in files: if file.endswith(".xml"): # Get relative path for the reference rel_path = os.path.relpath(os.path.join(root, file), project_root) # Add completion for the file itself completions.append({ "trigger": rel_path, "contents": f"<xref href=\"{rel_path}\" />", "annotation": "XML Document" }) # Parse the file to extract your "link points" (adjust this to your spec) try: tree = ET.parse(os.path.join(root, file)) # Example: Extract symbols from <symbol id="..."> tags for symbol in tree.findall(".//symbol[@id]"): symbol_id = symbol.get("id") completions.append({ "trigger": f"{rel_path}#{symbol_id}", "contents": f"<xref href=\"{rel_path}#{symbol_id}\" />", "annotation": f"Symbol: {symbol_id}" }) except Exception as e: print(f"Failed to parse {file}: {str(e)}") # Write the completions to your project's completion file completion_file_path = os.path.join(os.path.expanduser("~"), ".config/sublime-text/Packages/User/YourProjectName.sublime-completions") with open(completion_file_path, "w") as f: import json json.dump({ "scope": "text.xml", "completions": completions }, f, indent=2)Turn this into a Sublime command (add it to a
.pyfile in thePackages/Userfolder) and bind a keyboard shortcut to run it whenever you update project files.
Option 2: More Robust Setup with LSP (Language Server Protocol)
If your XML spec is complex or you want real-time updates, use Sublime’s LSP plugin to build a custom language server.
Install the LSP plugin
Use Package Control to search for and install theLSPplugin.Build a custom language server
Write a simple server (Python works great here) that follows the LSP protocol. It needs two core features:- Workspace scanning: On startup, scan all XML files in the project and cache their paths and symbols.
- Completion handling: Respond to
textDocument/completionrequests by returning cached files/symbols when the user is typing a reference (e.g., inside<xref href=").
You can use libraries likepyglsto simplify LSP implementation—no need to handle low-level protocol details.
Configure Sublime to use your server
Add this to your project’s.sublime-projectfile:{ "settings": { "LSP": { "custom-xml-server": { "command": ["python3", "/path/to/your/language-server.py"], "selector": "text.xml", "enabled": true } } } }
Bonus Tip
If you don’t want to build everything from scratch, check out the SublimeLSP-xml plugin. It supports custom XML schemas—define your spec in an XSD file, and configure the plugin to recognize your reference attributes. This might give you basic auto-completion with minimal custom code.
内容的提问来源于stack exchange,提问作者guest_user

