ALE (Asynchronous Lint Engine)

repository·master·Indexed 12 days ago

https://github.com/dense-analysis/ale

A lightweight, asynchronous plugin for Vim and Neovim that provides real-time linting, fixing, and Language Server Protocol (LSP) client capabilities. It allows users to see syntax and semantic errors as they type and includes features for code completion, automatic fixing via :ALEFix, and integration with tools like cspell and nvim-lspconfig.

Tokens
2.7K
Snippets
12
Records
14
Agent score
46%

What's inside ALE

  1. Integrate ALE with other LSP clients

    master

    ALE includes its own LSP functionality, but it can coexist with other clients like coc.nvim or vim-lsp.

    • Neovim nvim-lspconfig: ALE automatically disables its LSP functionality for any language servers configured with nvim-lspconfig by default (g:ale_disable_lsp = 'auto').
    • coc.nvim: To use both, configure coc.nvim to send diagnostics to ALE by adding "diagnostic.displayByAle": true to your .coc-settings.json. You should also disable ALE's LSP features (g:ale_disable_lsp = 1) to avoid duplication.
    • Neovim Diagnostics: For Neovim 0.7+, use let g:ale_use_neovim_diagnostics_api = 1 to display errors via the native Neovim API.
    // In .coc-settings.json
    {
      "diagnostic.displayByAle": true
    }
  2. Navigate between errors and warnings

    master

    You can move quickly between problems using ALE's <Plug> keybinds. A common pattern is to map these to keys like Ctrl-j and Ctrl-k.

    " Map keys to navigate between wrapped errors/warnings
    nmap <silent> <C-k> <Plug>(ale_previous_wrap)
    nmap <silent> <C-j> <Plug>(ale_next_wrap)
  3. Install ALE

    master

    ALE can be installed using standard Vim/Neovim plugin managers or by manually cloning the repository into your runtime path.

    Using Plugin Managers

    vim-plug

    Plug 'dense-analysis/ale'

    Vundle

    Plugin 'dense-analysis/ale'

    lazy.nvim

    {
        'dense-analysis/ale',
        config = function()
            -- Configuration goes here.
            local g = vim.g
    
            g.ale_ruby_rubocop_auto_correct_all = 1
    
            g.ale_linters = {
                ruby = {'rubocop', 'ruby'},
                lua = {'lua_language_server'}
            }
        end
    }

    Manual Installation (Packload)

    Vim

    mkdir -p ~/.vim/pack/git-plugins/start
    git clone --depth 1 https://github.com/dense-analysis/ale.git ~/.vim/pack/git-plugins/start/ale

    Neovim

    mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start
    git clone --depth 1 https://github.com/dense-analysis/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale

    Windows (Git Bash)

    mkdir -p ~/vimfiles/pack/git-plugins/start
    git clone --depth 1 https://github.com/dense-analysis/ale.git ~/vimfiles/pack/git-plugins/start/ale

    Pathogen

    git clone https://github.com/dense-analysis/ale ~/.vim/bundle/ale

    If you encounter issues reading the help documentation after installation, run:

    packloadall | silent! helptags ALL
    Plug 'dense-analysis/ale'
  4. Optimize ALE for performance and battery life

    master

    If ALE is consuming too much CPU/battery, you can adjust its execution frequency:

    1. Increase delay: Adjust g:ale_lint_delay to run linters less frequently while typing.
    2. Disable linting on text change: Set g:ale_lint_on_text_changed = 'never' to stop continuous checking.
    3. Disable linting on enter: Set g:ale_lint_on_enter = 0.
    4. Manual mode: Turn off all automatic linting and run it manually using the :ALELint command.
    " Only run linters when saving files
    let g:ale_lint_on_text_changed = 'never'
    let g:ale_lint_on_insert_leave = 0
    let g:ale_lint_on_enter = 0
  5. Use Quickfix or Loclist for ALE problems

    master

    ALE defaults to using the loclist to display problems. To switch to the quickfix list, set g:ale_set_quickfix = 1 and optionally disable the loclist with g:ale_set_loclist = 0.

    You can also automate opening the list when problems are found using g:ale_open_list = 1 and keep it open with g:ale_keep_list_window_open = 1.

    " Use quickfix instead of loclist
    let g:ale_set_loclist = 0
    let g:ale_set_quickfix = 1
    
    " Automatically open the list
    let g:ale_open_list = 1
  6. Customize echo message format

    master

    You can customize the message shown in the echo area using g:ale_echo_msg_format.

    Available placeholders:

    • %s: The error message.
    • %...code...%: An optional error code.
    • %linter%: The name of the linter.
    • %severity%: The severity type.

    Use g:ale_echo_msg_error_str and g:ale_echo_msg_warning_str to define the strings used for error and warning severities.

    let g:ale_echo_msg_error_str = 'E'
    let g:ale_echo_msg_warning_str = 'W'
    let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
  7. Configure or disable specific linters

    master

    By default, ALE runs all available tools for all supported languages. You can select a subset of tools using b:ale_linters (buffer-local) or g:ale_linters (global).

    Recommended approach: Define a List in an ftplugin file for specific filetypes.

    To prevent ALE from running any linters except those explicitly listed in your configuration, set g:ale_linters_explicit to 1.

    " In ~/.vim/ftplugin/javascript.vim
    " Enable ESLint only for JavaScript
    let b:ale_linters = ['eslint']
    
    " Or using a dictionary in ~/.vim/vimrc
    let g:ale_linters = {
    \   'javascript': ['eslint'],
    \}
    
    " Only run linters named in ale_linters settings
    let g:ale_linters_explicit = 1
  8. Configure ALE completion

    master

    ALE supports code completion via Language Server Protocol (LSP) or tsserver.

    Using ALE with Deoplete

    If you use the Deoplete plugin, you can add 'ale' as a completion source:

    call deoplete#custom#option('sources', {
    \ '_': ['ale', 'foobar'],
    \})

    Built-in ALE Completion

    ALE has its own automatic completion support that does not require external plugins. Note: This should only be used if you are NOT using ALE as a source for other completion plugins (like Deoplete).

    " Enable built-in completion (must be set before ALE is loaded)
    let g:ale_completion_enabled = 1

    Manual Omni-completion

    To trigger ALE's completion manually using <C-x><C-o>, set the omnifunc:

    set omnifunc=ale#completion#OmniFunc

    Auto-imports

    ALE supports automatic imports from external modules by default. To disable this:

    let g:ale_completion_autoimport = 0
    let g:ale_completion_enabled = 1
  9. Customize virtual text and floating windows

    master

    ALE displays errors/warnings as virtual text at the end of lines.

    • Virtual Text: Use g:ale_virtualtext_cursor to control visibility. Options are 'current' (only show for the line under the cursor) or 'disabled' (hide completely).
    • Floating Windows: Borders for floating preview windows can be configured via g:ale_floating_window_border. You can pass an empty list [] to disable them or a list of characters for Unicode borders.
    " Only show virtual text for the current line
    let g:ale_virtualtext_cursor = 'current'
    
    " Disable virtual text
    let g:ale_virtualtext_cursor = 'disabled'
    
    " Use Unicode borders for floating windows
    let g:ale_floating_window_border = ['│', '─', '╭', '╮', '╯', '╰', '│', '─']
  10. Customize ALE signs and highlights

    master

    ALE uses signs in the gutter and text highlights to indicate problems.

    • Signs: Customize the text used for error and warning signs using g:ale_sign_error and g:ale_sign_warning. You can also force the sign column to be open at all times with g:ale_sign_column_always.
    • Highlights: ALE links highlights to SpellBad, SpellCap, error, and todo groups. You can disable all highlighting with g:ale_set_highlights = 0 or customize specific groups (e.g., highlight ALEWarning ctermbg=DarkMagenta).
    " Customize sign text
    let g:ale_sign_error = '>>'
    let g:ale_sign_warning = '--'
    
    " Always show sign column
    let g:ale_sign_column_always = 1
    
    " Disable highlighting completely
    let g:ale_set_highlights = 0
  11. Configure ALE fixers

    master

    ALE provides the :ALEFix command to fix code using command-line tools (e.g., prettier, eslint, autopep8). Fixers can be configured globally or per-buffer.

    Global Configuration

    Use g:ale_fixers in your vimrc. It must be a Dictionary. Use the '*' key to apply fixers to all filetypes not explicitly defined.

    " In ~/.vim/vimrc
    let g:ale_fixers = {
    \   '*': ['remove_trailing_lines', 'trim_whitespace'],
    \   'javascript': ['eslint'],
    \}

    Buffer-local Configuration

    Use b:ale_fixers in an ftplugin file for specific languages. This can be a List or a Dictionary.

    " In ~/.vim/ftplugin/javascript.vim
    let b:ale_fixers = ['prettier', 'eslint']
    
    " Or using a dictionary for specific filetypes within the buffer
    let b:ale_fixers = {'javascript': ['prettier', 'eslint']}

    Automatic Fixing on Save

    To automatically run fixers whenever you save a file, set g:ale_fix_on_save to 1 in your vimrc:

    let g:ale_fix_on_save = 1

    Useful Commands

    • :ALEFix: Runs configured fixers.
    • :ALEFixSuggest: Suggests supported fixing tools for the current buffer.
    let g:ale_fix_on_save = 1
  12. Use ALE Language Server Protocol (LSP) features

    master

    ALE acts as a language client for various LSP-compatible tools. When a language server is active, you can use the following commands:

    • Go To Definition: :ALEGoToDefinition (In Neovim 0.8+, native gd also works).
    • Find References: :ALEFindReferences.
    • Hover Information: :ALEHover (Displays brief information about the symbol under the cursor).
    • Symbol Search: :ALESymbolSearch (Searches for functions, types, etc., in the workspace).
    • Rename Symbol: :ALERename (Renames variables or class names).
    • Code Actions: :ALECodeAction (Executes actions like automatically fixing errors on the cursor or selection).
    • File Rename: ALEFileRename (Renames the file and fixes import paths; tsserver only).