Skip to content

Configuration Reference

Complete .wowluarc.json schema. For practical guidance, see the Configuration guide.

Editor support

A JSON Schema is provided for autocompletion and validation. The VS Code extension registers it automatically. For other editors, add a $schema property to your config file:

json
{
  "$schema": "https://raw.githubusercontent.com/TradeSkillMaster/wowlua-ls/main/editors/vscode/wowluarc.schema.json",
  "flavors": ["retail"]
}

Schema

json
{
  "addon_root": false,
  "ignore": ["string"],
  "library": ["string"],
  "framexml": true,
  "flavors": ["retail", "classic", "classic_era"],
  "globals": {
    "read": ["string"],
    "write": ["string"],
    "allow_slash_commands": true,
    "allow_binding_globals": true
  },
  "inference": {
    "backward_param_types": true,
    "correlated_return_overloads": true,
    "implicit_protected_prefix": false
  },
  "hint": {
    "enable": true,
    "parameterNames": true,
    "variableTypes": true,
    "functionReturnTypes": false,
    "forVariableTypes": true,
    "parameterTypes": false,
    "chainedReturnTypes": false
  },
  "codeLens": {
    "enable": true,
    "references": true,
    "implementations": true,
    "overrides": true
  },
  "editor": {
    "autoInsertEnd": true
  },
  "plugins": ["string"],
  "diagnostics": {
    "disable": ["string"],
    "enable": ["string"],
    "severity": {
      "diagnostic-code": "warning | info | hint"
    }
  }
}

Fields

addon_root

  • Type: boolean
  • Default: false

Marks this directory as a separate addon root. In multi-addon workspaces, each addon root gets its own isolated addon namespace table (local _, ns = ...), so fields defined in one addon aren't visible in another. Lua globals remain shared across all addon roots.

json
{ "addon_root": true }

Not needed for single-addon projects.

plugins

  • Type: string[]
  • Default: []

Paths to Lua diagnostic plugin scripts. Relative to the config file's directory. Isolated per file: only the plugins declared by a file's nearest config run against it — plugin lists are not inherited from parent configs. See the Diagnostic Plugins guide for the full API.

json
{ "plugins": [".wowlua-ls/my-check.lua"] }

ignore

  • Type: string[]
  • Default: []

Path prefixes to exclude from scanning. Relative to the config file's directory. Patterns ending with / match directory prefixes. Entries may also use glob wildcards: * (any characters within a path component), ? (single character), and ** (any number of directory levels).

json
{ "ignore": ["Libs/", "External/*.lua", "Generated/**/*.lua"] }

library

  • Type: string[]
  • Default: []

Paths to scan for type information but with all diagnostics suppressed. Useful for third-party libraries where you want classes, globals, and type information available to the rest of your project, but can't fix any diagnostic issues in the library code. Relative entries use the same pattern syntax as ignore. Absolute paths are also supported for libraries outside the workspace.

json
{ "library": ["Libs/", "/home/user/shared-libs/"] }

Unlike ignore (which skips files entirely), library files are fully scanned and analyzed — their @class, @alias, global functions, and other type information are available throughout the workspace. Only diagnostic output is suppressed.

Absolute paths are automatically added as extra scan directories, so external libraries don't need to be inside your workspace.

framexml

  • Type: boolean
  • Default: true

Whether FrameXML API globals are available. Set to false to treat FrameXML-specific globals as undefined.

flavors

  • Type: string[]
  • Default: [] (flavor filtering disabled)
  • Values: "retail" (alias "mainline"), "classic", "classic_era"

WoW flavor names the project targets. Enables wrong-flavor-api diagnostic when non-empty.

Note: Flavor filtering can also be derived automatically from .toc file listings — see the Flavor Filtering guide. When both sources are present, the effective flavor for each file is the intersection of the project-level flavors and the TOC-derived per-file flavor.

globals.read

  • Type: string[]
  • Default: []

Global names that may be accessed without triggering undefined-global. Entries may use glob wildcards: * (any characters) and ? (single character).

json
{ "globals": { "read": ["LibStub", "MyAddon*Mixin"] } }

Tip: SavedVariables and SavedVariablesPerCharacter declared in .toc files are automatically added to both globals.read and globals.write — no manual configuration needed.

globals.write

  • Type: string[]
  • Default: []

Global names that may be created/assigned without triggering create-global. Entries may use glob wildcards: * (any characters) and ? (single character).

json
{ "globals": { "write": ["MyAddon*", "SavedVar*"] } }

globals.allow_slash_commands

  • Type: boolean
  • Default: true

Automatically treat globals matching SLASH_* as allowed write/read globals. WoW slash commands are defined by assigning SLASH_COMMANDNAME1, SLASH_COMMANDNAME2, etc. to global variables, so these are always intentional. Set to false to require explicit listing in globals.write.

globals.allow_binding_globals

  • Type: boolean
  • Default: true

Automatically treat globals matching BINDING_HEADER_* and BINDING_NAME_* as allowed write/read globals. WoW keybinding labels are defined by assigning BINDING_HEADER_ADDON and BINDING_NAME_ACTION to global variables, and the binding system reads them at runtime. Set to false to require explicit listing in globals.write.

Automatic dynamic prefix detection

In addition to the settings above, the language server automatically detects dynamic global creation via _G["PREFIX" .. key] = value (or _G[name .. "SUFFIX"]) patterns in your workspace. When detected, a wildcard glob (e.g. PREFIX*) is registered so reads of those globals don't trigger undefined-global. This requires no configuration. The prefix/suffix must be at least 3 characters to avoid overly broad matching.

inference.backward_param_types

  • Type: boolean
  • Default: true

Infer parameter types from body usage (arithmetic, concatenation, typed-function argument calls).

inference.correlated_return_overloads

  • Type: boolean
  • Default: true

Infer correlated return patterns (all-set-or-all-nil) for automatic sibling narrowing.

inference.implicit_protected_prefix

  • Type: boolean
  • Default: false

Treat runtime-discovered data fields starting with _ as implicitly protected. Does not affect explicit @field declarations or methods.

hint.enable

  • Type: boolean
  • Default: true

Master switch for inlay hints. When false, no inlay hints are shown regardless of individual category settings.

hint.parameterNames

  • Type: boolean
  • Default: true

Show parameter name hints at call sites (e.g. foo(/*name:*/ "hello")). Suppressed when the argument text already matches the parameter name.

hint.variableTypes

  • Type: boolean
  • Default: true

Show inferred type hints on local variable declarations that have no explicit @type annotation. Suppressed for nil, any, and function-valued variables.

hint.functionReturnTypes

  • Type: boolean
  • Default: false

Show inferred return type hints on function definitions that have no @return annotation.

hint.forVariableTypes

  • Type: boolean
  • Default: true

Show inferred type hints on for ... in loop variables.

hint.parameterTypes

  • Type: boolean
  • Default: false

Show inferred type hints on function parameters that have no @param annotation. Suppressed for self, any, and nil parameters.

hint.chainedReturnTypes

  • Type: boolean
  • Default: false

Show intermediate return type hints in method chains. When a method call's return value is immediately used as the receiver of another method/field access, the return type is shown after the closing ). Suppressed when the return type is any, nil, or ?.

codeLens.enable

  • Type: boolean
  • Default: true

Master switch for code lenses. When false, no code lenses are shown regardless of individual category settings.

codeLens.references

  • Type: boolean
  • Default: true

Show "N usages" lenses on function definitions.

codeLens.implementations

  • Type: boolean
  • Default: true

Show "N implementations" lenses on @class declarations.

codeLens.overrides

  • Type: boolean
  • Default: true

Show "overrides Parent" lenses on methods that override a parent class method.

editor.autoInsertEnd

  • Type: boolean
  • Default: true

Automatically insert end or until when Enter is pressed after a block-opening keyword (if … then, while … do, for … do, function, repeat). The closing keyword is only inserted when the block isn't already closed further down in the file.

json
{ "editor": { "autoInsertEnd": false } }

diagnostics.disable

  • Type: string[]
  • Default: []

Diagnostic codes to suppress.

diagnostics.enable

  • Type: string[]
  • Default: []

Diagnostic codes to enable. Used for default-off diagnostics or to override a parent's disable.

diagnostics.severity

  • Type: Record<string, "warning" | "info" | "hint">
  • Default: {}

Override severity for specific diagnostic codes.

Hierarchy behavior

When .wowluarc.json files are nested, settings combine according to one of two policies:

  • Isolated — the single nearest ancestor config fully determines the setting. Keys it does not set fall back to their default, not to a parent config's value. This applies to everything that affects diagnostics, so that running a check from a subdirectory produces the same results as running it from the project root (configs above the scan root are never consulted).
  • Inherited — the deepest config that sets the key wins, falling back to ancestor configs and then the default. This applies to editor-experience settings that do not affect diagnostics.
SettingPolicy
diagnostics.disableIsolated — nearest config's disable only
diagnostics.enableIsolated — applied after the nearest config's disable
diagnostics.severityIsolated — nearest config's severity map only
globals.readIsolated — nearest config only (includes that directory's .toc SavedVariables)
globals.writeIsolated — nearest config only
globals.allow_slash_commandsIsolated
globals.allow_binding_globalsIsolated
framexmlIsolated
flavorsIsolated (then intersected with any TOC-derived per-file mask)
inference.*Isolated
ignoreIsolated — nearest config's patterns, relative to its directory
libraryIsolated for relative patterns; absolute library directories are scanned workspace-wide
pluginsIsolated — only the nearest config's plugins run against a file
hint.*Inherited
codeLens.*Inherited
editor.*Inherited
addon_rootNearest (deepest) addon_root: true wins (structural)

Isolated settings do not inherit

If a nested directory has its own .wowluarc.json, it only inherits the inherited settings above. Any isolated setting it does not restate reverts to its default — it does not pick up the parent's value. For example, a subdirectory config that only sets diagnostics.enable will lose a parent's flavors and framexml settings unless it repeats them. This also applies to auto-discovered TOC SavedVariables globals — they are merged into the config entry for the directory containing the .toc file, so a child config in a subdirectory will not see them.