Overview
EmmyLua Analyzer implements the Language Server Protocol (LSP), making it compatible with any editor that supports LSP. This guide covers setup for popular editors beyond VS Code, Neovim, and IntelliJ.
Prerequisites :
EmmyLua Analyzer installed: cargo install emmylua_ls
An LSP client plugin for your editor
Basic familiarity with your editor’s configuration
Universal LSP Configuration
All LSP clients need these basic settings:
{
"command" : "emmylua_ls" ,
"args" : [],
"filetypes" : [ "lua" ],
"rootPatterns" : [ ".emmyrc.json" , ".luarc.json" , ".git" ],
"settings" : {
"Lua" : {
"runtime" : {
"version" : "LuaLatest"
},
"diagnostics" : {
"enable" : true
},
"completion" : {
"enable" : true
}
}
}
}
Sublime Text
Setup with LSP Package
Install Package Control
If not already installed:
Open Sublime Text
Press Ctrl+Shift+P (Cmd+Shift+P on macOS)
Type “Install Package Control” and press Enter
Wait for installation to complete
Install LSP Package
Press Ctrl+Shift+P
Type “Package Control: Install Package”
Search for “LSP”
Install the LSP package
Configure EmmyLua LSP
Create LSP client configuration:
Go to Preferences → Package Settings → LSP → Settings
Add to user settings:
{
"clients" : {
"emmylua" : {
"enabled" : true ,
"command" : [ "emmylua_ls" ],
"selector" : "source.lua" ,
"settings" : {
"Lua" : {
"runtime" : {
"version" : "LuaLatest" ,
"path" : [ "?.lua" , "?/init.lua" ]
},
"diagnostics" : {
"enable" : true ,
"globals" : []
},
"completion" : {
"enable" : true ,
"callSnippet" : "Replace"
},
"workspace" : {
"library" : [],
"ignoreDir" : [ ".git" , "node_modules" ]
}
}
}
}
}
}
Enable for Lua Files
Open a Lua file
LSP should start automatically
Check status in the status bar (bottom-right)
Keyboard Shortcuts (Sublime Text)
[
{ "keys" : [ "ctrl+." ], "command" : "lsp_code_actions" },
{ "keys" : [ "f12" ], "command" : "lsp_symbol_definition" },
{ "keys" : [ "shift+f12" ], "command" : "lsp_symbol_references" },
{ "keys" : [ "ctrl+k" , "ctrl+r" ], "command" : "lsp_symbol_rename" },
{ "keys" : [ "ctrl+k" , "ctrl+d" ], "command" : "lsp_hover" },
{ "keys" : [ "ctrl+shift+space" ], "command" : "lsp_signature_help" }
]
Emacs
Setup with lsp-mode
Install lsp-mode
Add to your init.el: ;; Using use-package
( use-package lsp-mode
:ensure t
:hook ((lua-mode . lsp))
:commands lsp
:config
( setq lsp-keymap-prefix "C-c l" ))
;; Optional: UI improvements
( use-package lsp-ui
:ensure t
:commands lsp-ui-mode)
;; Optional: Company mode for completion
( use-package company
:ensure t
:config
(global-company-mode))
Configure EmmyLua LSP
Add EmmyLua server configuration: ( with-eval-after-load 'lsp-mode
( add-to-list 'lsp-language-id-configuration '(lua-mode . "lua" ))
(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection "emmylua_ls" )
:major-modes '(lua-mode)
:server-id 'emmylua-ls
:initialization-options
'((runtime (( version . "LuaLatest" )))
(diagnostics ((enable . t )))
(completion ((enable . t ))))
:priority 1 )))
Set Keybindings
Customize LSP keybindings: ( with-eval-after-load 'lsp-mode
( define-key lsp-mode-map ( kbd "C-c l r" ) 'lsp-rename )
( define-key lsp-mode-map ( kbd "C-c l a" ) 'lsp-execute-code-action )
( define-key lsp-mode-map ( kbd "C-c l d" ) 'lsp-describe-thing-at-point )
( define-key lsp-mode-map ( kbd "C-c l f" ) 'lsp-format-buffer )
( define-key lsp-mode-map ( kbd "C-c l g g" ) 'lsp-find-definition )
( define-key lsp-mode-map ( kbd "C-c l g r" ) 'lsp-find-references ))
Setup with eglot (Alternative)
;; Simpler alternative to lsp-mode
( use-package eglot
:ensure t
:hook (lua-mode . eglot-ensure)
:config
( add-to-list 'eglot-server-programs
'(lua-mode . ( "emmylua_ls" ))))
;; Optional: company completion
( use-package company
:ensure t
:hook (eglot-managed-mode . company-mode))
Vim (Classic)
Setup with vim-lsp
Install Plugin Manager
Using vim-plug, add to .vimrc: call plug#begin ( '~/.vim/plugged' )
Plug 'prabirshrestha/vim-lsp'
Plug 'mattn/vim-lsp-settings'
Plug 'prabirshrestha/asyncomplete.vim'
Plug 'prabirshrestha/asyncomplete-lsp.vim'
call plug#end ()
Then run :PlugInstall
Configure EmmyLua LSP
Add to .vimrc: if executable ( 'emmylua_ls' )
au User lsp_setup call lsp#register_server ({
\ 'name' : 'emmylua_ls' ,
\ 'cmd' : {server_info->[ 'emmylua_ls' ]},
\ 'whitelist' : [ 'lua' ],
\ 'workspace_config' : {
\ 'Lua' : {
\ 'runtime' : { 'version' : 'LuaLatest' },
\ 'diagnostics' : { 'enable' : v: true },
\ 'completion' : { 'enable' : v: true }
\ }
\ }
\ })
endif
Set Keybindings
function ! s:on_lsp_buffer_enabled () abort
setlocal omnifunc = lsp # complete
setlocal signcolumn = yes
nmap < buffer > gd < plug >( lsp -definition)
nmap < buffer > gr < plug >( lsp -references)
nmap < buffer > gi < plug >( lsp -implementation)
nmap < buffer > < leader >rn < plug >( lsp -rename)
nmap < buffer > K < plug >( lsp -hover)
nmap < buffer > [g < plug >( lsp -previous-diagnostic)
nmap < buffer > ]g < plug >( lsp -next-diagnostic)
endfunction
augroup lsp_install
au!
autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled ()
augroup END
Setup with coc.nvim (Also works in Vim)
" Install coc.nvim
Plug 'neoclide/coc.nvim' , { 'branch' : 'release' }
" Configure after plugin installation
" :CocConfig to edit coc-settings.json
{
"languageserver" : {
"emmylua" : {
"command" : "emmylua_ls" ,
"filetypes" : [ "lua" ],
"rootPatterns" : [ ".emmyrc.json" , ".git" ],
"settings" : {
"Lua" : {
"runtime" : { "version" : "LuaLatest" },
"diagnostics" : { "enable" : true }
}
}
}
}
}
VSCodium
VSCodium is a free/libre version of VS Code without Microsoft telemetry.
Setup
Install EmmyLua Extension
The VS Code extension works in VSCodium: codium --install-extension tangzx.emmylua
Or download from Open VSX Registry
Configure
Follow the same configuration as VS Code setup : {
"emmylua.languageServer.path" : "/path/to/emmylua_ls" ,
"emmylua.completion.enable" : true ,
"emmylua.diagnostics.enable" : true
}
Helix
Setup
Helix has built-in LSP support:
Configure Language Server
Edit ~/.config/helix/languages.toml: [[ language ]]
name = "lua"
scope = "source.lua"
injection-regex = "lua"
file-types = [ "lua" ]
roots = [ ".emmyrc.json" , ".luarc.json" , ".git" ]
comment-token = "--"
indent = { tab-width = 4 , unit = " " }
[ language-server . emmylua_ls ]
command = "emmylua_ls"
[ language-server . emmylua_ls . config . Lua ]
runtime = { version = "LuaLatest" }
diagnostics = { enable = true , globals = [] }
completion = { enable = true , callSnippet = "Replace" }
Verify Setup
Open a Lua file and check LSP status: Press Space + w + d to see diagnostics
Helix Keybindings
Action Key Go to definition gdGo to references grHover Space + kRename Space + rCode action Space + aFormat Space + f
Kate
Setup
Enable LSP Plugin
Go to Settings → Configure Kate → Plugins
Enable “LSP Client”
Click OK
Configure LSP
Go to Settings → Configure Kate → LSP Client
Click “User Server Settings”
Add configuration:
{
"servers" : {
"lua" : {
"command" : [ "emmylua_ls" ],
"rootIndicationFileNames" : [ ".emmyrc.json" , ".git" ],
"settings" : {
"Lua" : {
"runtime" : { "version" : "LuaLatest" },
"diagnostics" : { "enable" : true }
}
}
}
}
}
Lapce
Lapce has built-in LSP support:
Setup
Open Settings (Ctrl+,)
Search for “LSP”
Add Lua configuration:
{
"lsp" : {
"lua" : {
"command" : "emmylua_ls" ,
"options" : {
"Lua" : {
"runtime" : { "version" : "LuaLatest" },
"diagnostics" : { "enable" : true }
}
}
}
}
}
Troubleshooting
Language server not found
Solution :
Verify installation:
which emmylua_ls
emmylua_ls --version
Add to PATH:
export PATH = " $HOME /.cargo/bin: $PATH "
Use absolute path in configuration:
{
"command" : "/home/user/.cargo/bin/emmylua_ls"
}
LSP not starting automatically
Solution :
Check file association (file must be recognized as Lua)
Verify root pattern matches your project:
Add .emmyrc.json to project root
Or adjust rootPatterns in config
Restart editor and reopen file
Check editor’s LSP logs for errors
Solution :
Verify LSP is running (check status bar/logs)
Ensure completion is enabled:
{
"settings" : {
"Lua" : {
"completion" : { "enable" : true }
}
}
}
Check if completion plugin is installed (editor-specific)
Try manual completion trigger (usually Ctrl+Space)
Solution :
Enable diagnostics:
{
"settings" : {
"Lua" : {
"diagnostics" : { "enable" : true }
}
}
}
Check if editor displays diagnostics (some require plugins)
Look for errors in LSP logs
Verify file has actual issues to diagnose
Configuration not taking effect
Solution :
Restart the language server
Check configuration syntax (JSON/TOML/etc. must be valid)
Create .emmyrc.json in project root:
{
"runtime" : { "version" : "LuaLatest" },
"diagnostics" : { "enable" : true }
}
Check if editor-level config overrides project config
Generic LSP Client Configuration
For editors not listed above, use this generic configuration as a starting point:
Minimum Required Settings
{
"command" : "emmylua_ls" ,
"args" : [],
"filetypes" : [ "lua" ],
"rootPatterns" : [ ".emmyrc.json" , ".git" ]
}
Full Configuration Template
{
"command" : "emmylua_ls" ,
"args" : [],
"filetypes" : [ "lua" ],
"rootPatterns" : [ ".emmyrc.json" , ".luarc.json" , ".git" ],
"initializationOptions" : {},
"settings" : {
"Lua" : {
"runtime" : {
"version" : "LuaLatest" ,
"path" : [ "?.lua" , "?/init.lua" ]
},
"diagnostics" : {
"enable" : true ,
"globals" : []
},
"completion" : {
"enable" : true ,
"callSnippet" : "Replace" ,
"autoRequire" : true
},
"hover" : {
"enable" : true
},
"hint" : {
"enable" : true ,
"paramHint" : true
},
"workspace" : {
"library" : [],
"ignoreDir" : [ ".git" , "node_modules" ]
},
"semanticTokens" : {
"enable" : true
}
}
}
}
TCP Mode (Remote Development)
For remote development or debugging:
Start Server in TCP Mode
emmylua_ls -c tcp --port 5007
{
"command" : "emmylua_ls" ,
"args" : [ "-c" , "tcp" , "--port" , "5007" ],
"tcp" : {
"host" : "localhost" ,
"port" : 5007
}
}
Project Configuration
Create .emmyrc.json in your project root for consistent settings across all editors:
{
"$schema" : "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json" ,
"runtime" : {
"version" : "Lua5.4" ,
"requireLikeFunction" : [ "require" , "import" ]
},
"diagnostics" : {
"enable" : true ,
"globals" : [ "vim" , "love" ],
"severity" : {
"unused" : "hint"
}
},
"workspace" : {
"library" : [ "./libs" ],
"ignoreDir" : [ "build" , "test" ]
}
}
Next Steps
Configuration Explore all configuration options
VS Code Detailed VS Code setup guide
Neovim Comprehensive Neovim integration
Annotations Learn about type annotations