Help us shape the future of Go! Take the 2026 Go Developer Survey

cfmleditor-lsp

module
v0.1.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 17, 2026 License: MIT

README

cfmleditor-lsp

A Language Server Protocol (LSP) implementation for CFML / ColdFusion, written in Go.

Uses tree-sitter-cfml.

Build

go build -o cfmleditor-lsp .

Run

The server communicates over stdio using JSON-RPC 2.0 with LSP headers:

./cfmleditor-lsp

Configure your editor to launch this binary as an LSP server for .cfm, .cfc, .cfml, and .cfs files.

Configuration

Place a .cfmleditor.json file in your project root to enable daemon mode and configure workspace indexing.

{
  "workspaceName": "myproject",
  "workspacePaths": [".", "../shared-lib"],
  "mappings": {
    "models": "./src/models"
  },
  "componentResolvers": [
    {
      "match": "getService(\"$1\")",
      "resolve": "packages.$1.service",
      "prefix": "getService"
    }
  ]
}
Field Required Description
workspaceName Yes Unique project name. Used to derive the daemon socket path so multiple projects don't collide.
workspacePaths No Relative paths to folders the LSP should treat as workspace roots. Resolved relative to the config file location.
workspaceIndexGlobs No Glob patterns to filter which .cfc files are indexed.
mappings No Component path mappings. Keys are the first segment of a dot-path, values are directory paths (absolute or relative to config).
componentResolvers No Custom patterns for resolving method calls to component paths. See below.
formatting No Formatter configuration object. See below.
debug No Enable debug logging (zap.NewDevelopment). Outputs verbose logs to stderr.
Mappings

Mappings let you resolve component dot-paths that use a virtual root. For example, with "models": "./src/models", the dot-path models.User resolves to ./src/models/User.cfc.

Component resolvers

Component resolvers teach the LSP how to resolve custom factory patterns to specific CFCs. This enables goto-definition and dot-completion for variables assigned from those patterns.

"componentResolvers": [
  {
    "match": "getService(\"$1\")",
    "resolve": "packages.$1.service",
    "prefix": "getService"
  },
  {
    "match": "_parent",
    "resolve": "packages.tass.core.kernel2",
    "prefix": "_parent"
  }
]
Field Required Description
match Yes Pattern to match against the RHS of an assignment. Use $1 as a capture placeholder. Without $1, acts as an exact variable name match.
resolve Yes Component dot-path or file path template. $1 is replaced with the captured value. File paths (with / or .cfc) are normalised to dot-paths.
prefix Yes Fast-check string. Lines without this prefix are skipped entirely — avoids expensive matching on every line.

The match is case-insensitive and works regardless of qualifiers before it. For example, getService("$1") matches all of:

  • getService("timetable")
  • _parent.getService("timetable")
  • VARIABLES._parent.getService("timetable")
Formatting

The formatting object controls the built-in formatter invoked via textDocument/formatting.

"formatting": {
  "enabled": true,
  "selfCloseTags": true,
  "whitespaceOnly": true,
  "lowercaseTags": true,
  "lowercaseAttributes": true,
  "doubleQuoteAttributes": true,
  "uppercaseSqlKeywords": true,
  "scopeCase": "leave",
  "lineWidth": 100,
  "attrBreakThreshold": 4,
  "indentWidth": 4
}
Field Default Description
enabled false Enable the formatter. When false, formatting requests are ignored.
selfCloseTags true Convert void/implicit-end HTML tags to self-closing form (e.g. <br> → <br />).
whitespaceOnly true Reject formatting results that change non-whitespace content (safety guard).
lowercaseTags true Lowercase CF tag names (e.g. <CFOUTPUT> → <cfoutput>).
lowercaseAttributes true Lowercase attribute names.
doubleQuoteAttributes true Normalize attribute values to double quotes.
uppercaseSqlKeywords true Uppercase SQL keywords inside <cfquery> blocks.
scopeCase "leave" Case for CFML scope names. Values: "upper", "lower", "leave".
lineWidth 100 Soft column limit — attributes expand to separate lines when a tag exceeds this width.
attrBreakThreshold 4 Number of attributes above which they are always expanded onto separate lines.
indentWidth 4 Spaces per indentation level. Overridden by editor tabSize when provided.
debug false Enable formatter debug checks.

Note: useTabs and tabSize are taken from the editor's formatting options (sent with each formatting request), not from this config.

Daemon mode

When .cfmleditor.json is found (in the current directory or one level up), the server starts in daemon mode:

  1. The first editor session becomes the daemon, listening on a Unix socket and serving LSP over stdio.
  2. Subsequent sessions connect to the existing daemon via the socket, sharing a single index.
  3. The daemon shuts down automatically when all editor sessions disconnect.

Without a config file the server runs in standalone mode — a single session with its own index.

Indexing behaviour
  • If workspaceIndexGlobs is set, only .cfc files matching those patterns are indexed.
  • If only workspacePaths is set, all .cfc files under those folders are indexed.
  • If neither is set, the LSP falls back to indexing workspace folders reported by the editor.

Status

  • Initialize / Shutdown / Exit
  • textDocument/didOpen
  • textDocument/didChange (full sync)
  • textDocument/didClose

Local Development

Add cfmleditor-lsp to your path

sudo ln -sf ~/development/github/cfmleditor-lsp/target/release/cfmleditor-lsp /usr/local/bin/cfmleditor-lsp

Directories

Path Synopsis
cmd
cfmleditor-lsp command
Package main is the entry point for the cfmleditor-lsp server.
Package main is the entry point for the cfmleditor-lsp server.
cfparse command
Command cfparse benchmarks the cfparser against files or directories.
Command cfparse benchmarks the cfparser against files or directories.
internal
cache
Package cache provides per-file scoped completion caching.
Package cache provides per-file scoped completion caching.
cflint
Package cflint provides CFLint binary management and execution.
Package cflint provides CFLint binary management and execution.
cfparser
Package cfparser provides a hand-written recursive descent parser for CFML and CFScript that extracts function definitions, variable declarations, and component references.
Package cfparser provides a hand-written recursive descent parser for CFML and CFScript that extracts function definitions, variable declarations, and component references.
daemon
Package daemon manages multi-session daemon mode and configuration.
Package daemon manages multi-session daemon mode and configuration.
docs
Package docs provides built-in CFML tag and function documentation.
Package docs provides built-in CFML tag and function documentation.
formatter
Package formatter walks a tree-sitter concrete syntax tree produced by the cfml grammar and re-emits well-formatted CFML source.
Package formatter walks a tree-sitter concrete syntax tree produced by the cfml grammar and re-emits well-formatted CFML source.
index
Package index maintains a searchable index of CFML function definitions.
Package index maintains a searchable index of CFML function definitions.
language
Package language provides tree-sitter language and parser setup for CFML grammars.
Package language provides tree-sitter language and parser setup for CFML grammars.
path
Package path resolves CFML component dot-paths to filesystem paths.
Package path resolves CFML component dot-paths to filesystem paths.
server
Package server implements the CFML Language Server Protocol handler.
Package server implements the CFML Language Server Protocol handler.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL