All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
1 " Author: w0rp <devw0rp@gmail.com>
2 " Description: Main entry point for the plugin: sets up prefs and autocommands
3 " Preferences can be set in vimrc files and so on to configure ale
7 if exists('g:loaded_ale_dont_use_this_in_other_plugins_please')
11 " Set a special flag used only by this plugin for preventing doubly
13 let g:loaded_ale_dont_use_this_in_other_plugins_please = 1
15 " A flag for detecting if the required features are set.
17 " We check for Neovim 0.2.0+, but we only officially support NeoVim 0.7.0
18 let s:has_features = has('timers') && has('nvim-0.2.0')
20 " Check if Job and Channel functions are available, instead of the
21 " features. This works better on old MacVim versions.
22 let s:has_features = has('timers') && exists('*job_start') && exists('*ch_close_in')
26 " Only output a warning if editing some special files.
27 if index(['', 'gitcommit'], &filetype) == -1
29 echoerr 'ALE requires NeoVim >= 0.7.0 or Vim 8 with +timers +job +channel'
31 echoerr 'Please update your editor appropriately.'
34 " Stop here, as it won't work.
38 " Set this flag so that other plugins can use it, like airline.
41 " This global variable is used internally by ALE for tracking information for
42 " each buffer which linters are being run against.
43 let g:ale_buffer_info = {}
44 " This global Dictionary tracks data for fixing code. Don't mess with it.
45 let g:ale_fix_buffer_data = {}
49 " This option prevents ALE autocmd commands from being run for particular
50 " filetypes which can cause issues.
51 let g:ale_filetype_blacklist = [
59 " This Dictionary configures which linters are enabled for which languages.
60 let g:ale_linters = get(g:, 'ale_linters', {})
61 " This option can be changed to only enable explicitly selected linters.
62 let g:ale_linters_explicit = get(g:, 'ale_linters_explicit', v:false)
63 " Ignoring linters, for disabling some, or ignoring LSP diagnostics.
64 let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
65 " Disabling all language server functionality.
66 let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 'auto')
68 " This Dictionary configures which functions will be used for fixing problems.
69 let g:ale_fixers = get(g:, 'ale_fixers', {})
71 " This Dictionary allows users to set up filetype aliases for new filetypes.
72 let g:ale_linter_aliases = get(g:, 'ale_linter_aliases', {})
74 " This flag can be set with a number of milliseconds for delaying the
75 " execution of a linter when text is changed. The timeout will be set and
76 " cleared each time text is changed, so repeated edits won't trigger the
77 " jobs for linting until enough time has passed after editing is done.
78 let g:ale_lint_delay = get(g:, 'ale_lint_delay', 200)
80 " This flag can be set to 'never' to disable linting when text is changed.
81 " This flag can also be set to 'always' or 'insert' to lint when text is
82 " changed in both normal and insert mode, or only in insert mode respectively.
83 let g:ale_lint_on_text_changed = get(g:, 'ale_lint_on_text_changed', 'normal')
85 " This flag can be set to true or 1 to enable linting when leaving insert mode.
86 let g:ale_lint_on_insert_leave = get(g:, 'ale_lint_on_insert_leave', v:true)
88 " When true or 1 linting is done when a buffer is entered.
89 let g:ale_lint_on_enter = get(g:, 'ale_lint_on_enter', v:true)
91 " When true or 1 linting is done when a buffer is written.
92 let g:ale_lint_on_save = get(g:, 'ale_lint_on_save', v:true)
94 " When true or 1 linting is done when the filetype changes.
95 let g:ale_lint_on_filetype_changed = get(g:, 'ale_lint_on_filetype_changed', v:true)
97 " If set to true or 1, suggestions from LSP servers and tsserver will be shown.
98 let g:ale_lsp_suggestions = get(g:, 'ale_lsp_suggestions', v:false)
100 " When true or 1 files are automatically fixed on save.
101 let g:ale_fix_on_save = get(g:, 'ale_fix_on_save', v:false)
103 " When true or 1 ALE linting is enabled.
104 " Disabling ALE linting does not disable fixing of files.
105 let g:ale_enabled = get(g:, 'ale_enabled', 1)
107 " A Dictionary mapping linter or fixer names to Arrays of two-item Arrays
108 " mapping filename paths from one system to another.
109 let g:ale_filename_mappings = get(g:, 'ale_filename_mappings', {})
111 " This Dictionary configures the default project roots for various linters.
112 let g:ale_root = get(g:, 'ale_root', {})
114 " These flags dictates if ale uses the quickfix or the loclist (loclist is the
115 " default, quickfix overrides loclist).
116 let g:ale_set_loclist = get(g:, 'ale_set_loclist', v:true)
117 let g:ale_set_quickfix = get(g:, 'ale_set_quickfix', v:false)
119 " This flag can be set to 0 to disable setting signs.
120 " This is enabled by default only if the 'signs' feature exists.
121 let g:ale_set_signs = get(g:, 'ale_set_signs', has('signs') ? v:true : v:false)
123 " This flag can be set to 0 to disable setting error highlights.
124 let g:ale_set_highlights = get(g:, 'ale_set_highlights', has('syntax') ? v:true : v:false)
126 " This List can be configured to exclude particular highlights.
127 let g:ale_exclude_highlights = get(g:, 'ale_exclude_highlights', [])
129 " When set to true or 1 problems on lines are echoed when the cursor moves.
130 let g:ale_echo_cursor = get(g:, 'ale_echo_cursor', v:true)
132 " If set to true or 1 automatically show errors in the preview window.
133 let g:ale_cursor_detail = get(g:, 'ale_cursor_detail', v:false)
135 " This flag can be changed to disable/enable virtual text.
136 let g:ale_virtualtext_cursor = get(g:, 'ale_virtualtext_cursor', (has('nvim-0.3.2') || has('patch-9.0.0297') && has('textprop') && has('popupwin')) ? 'all' : 'disabled')
138 " When set to true or 1 LSP hover messages are shown at the cursor.
139 let g:ale_hover_cursor = get(g:, 'ale_hover_cursor', v:true)
141 " When true or 1 to close the preview window on entering Insert Mode.
142 let g:ale_close_preview_on_insert = get(g:, 'ale_close_preview_on_insert', v:false)
144 " When set to true or 1 balloon support is enabled.
145 let g:ale_set_balloons = get(g:, 'ale_set_balloons', (has('balloon_eval') && has('gui_running')) ? v:true : v:false)
147 " When set to true or 1 use the preview window for showing hover messages.
148 let g:ale_hover_to_preview = get(g:, 'ale_hover_to_preview', v:false)
150 " When set to true or 1 use floating preview windows in Neovim.
151 let g:ale_floating_preview = get(g:, 'ale_floating_preview', v:false)
153 " When set to true or 1 show hove messages in floating windows in Neovim.
154 let g:ale_hover_to_floating_preview = get(g:, 'ale_hover_to_floating_preview', v:false)
156 " When set to true or 1 details are shown in floating windows in Neovim.
157 let g:ale_detail_to_floating_preview = get(g:, 'ale_detail_to_floating_preview', v:false)
159 " Border setting for floating preview windows
161 " The elements in the list set the characters for the left, top, top-left,
162 " top-right, bottom-right, bottom-left, right, and bottom of the border
164 let g:ale_floating_window_border = get(g:, 'ale_floating_window_border', ['|', '-', '+', '+', '+', '+', '|', '-'])
166 " When set to true or 1 warnings for trailing whitespace are shown.
167 let g:ale_warn_about_trailing_whitespace = get(g:, 'ale_warn_about_trailing_whitespace', v:true)
168 " When set to true or 1 warnings for trailing blank lines are shown.
169 let g:ale_warn_about_trailing_blank_lines = get(g:, 'ale_warn_about_trailing_blank_lines', v:true)
171 " When set to true or 1 the command history is logged.
172 let g:ale_history_enabled = get(g:, 'ale_history_enabled', v:true)
174 " When set to true or 1 the full output of commands is logged.
175 let g:ale_history_log_output = get(g:, 'ale_history_log_output', v:true)
177 " When set to true or 1 enable ALE's built-in autocompletion functionality.
178 let g:ale_completion_enabled = get(g:, 'ale_completion_enabled', v:false)
180 " When set to true or 1 enable automatic detection of pipenv for Python.
181 let g:ale_python_auto_pipenv = get(g:, 'ale_python_auto_pipenv', v:false)
183 " When set to true or 1 enable automatic detection of poetry for Python.
184 let g:ale_python_auto_poetry = get(g:, 'ale_python_auto_poetry', v:false)
186 " When set to true or 1 enable automatic detection of uv for Python.
187 let g:ale_python_auto_uv = get(g:, 'ale_python_auto_uv', v:false)
189 " When set to true or 1 enable automatically updating environment variables
190 " for running Python linters from virtualenv directories.
192 " The variables are set based on ALE's virtualenv detection.
193 let g:ale_python_auto_virtualenv = get(g:, 'ale_python_auto_virtualenv', v:false)
195 " This variable can be overridden to set the GO111MODULE environment variable.
196 let g:ale_go_go111module = get(g:, 'ale_go_go111module', '')
198 " The default executable for deno. Must be set before ALE lints any buffers.
199 let g:ale_deno_executable = get(g:, 'ale_deno_executable', 'deno')
201 " If true or 1, enable a popup menu for commands.
202 let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui_running') ? v:true : v:false)
204 " If true or 1, save hidden files when code actions are applied.
205 let g:ale_save_hidden = get(g:, 'ale_save_hidden', v:false)
207 " If true or 1, disables ALE's built in error display.
209 " Instead, all errors are piped to the Neovim diagnostics API.
210 let g:ale_use_neovim_diagnostics_api = get(g:, 'ale_use_neovim_diagnostics_api', has('nvim-0.7') ? v:true : v:false)
212 if g:ale_use_neovim_diagnostics_api && !has('nvim-0.7')
214 echoerr('Setting g:ale_use_neovim_diagnostics_api to true or 1 requires Neovim 0.7+.')
217 " If true or 1, uses Neovim's built-in LSP client to integrate with LSP, which
218 " improves ALE's integration with built-in Neovim tools and other plugins.
219 let g:ale_use_neovim_lsp_api = get(g:, 'ale_use_neovim_lsp_api', has('nvim-0.8') ? v:true : v:false)
221 " If 1, replaces ALE's use of jobs and channels to connect to language
222 " servers, plus the custom code, and instead hooks ALE into Neovim's built-in
223 " language server tools.
224 if g:ale_use_neovim_lsp_api && !has('nvim-0.8')
226 echoerr('Setting g:ale_use_neovim_lsp_api to true or 1 requires Neovim 0.8+.')
229 if g:ale_set_balloons || g:ale_set_balloons is# 'hover'
230 call ale#balloon#Enable()
233 if g:ale_completion_enabled
234 call ale#completion#Enable()
237 if g:ale_popup_menu_enabled
238 call ale#code_action#EnablePopUpMenu()
241 " Define commands for moving through warnings and errors.
242 command! -bar -nargs=* ALEPrevious
243 \ :call ale#loclist_jumping#WrapJump('before', <q-args>)
244 command! -bar -nargs=* ALENext
245 \ :call ale#loclist_jumping#WrapJump('after', <q-args>)
247 command! -bar ALEPreviousWrap :call ale#loclist_jumping#Jump('before', 1)
248 command! -bar ALENextWrap :call ale#loclist_jumping#Jump('after', 1)
249 command! -bar ALEFirst :call ale#loclist_jumping#JumpToIndex(0)
250 command! -bar ALELast :call ale#loclist_jumping#JumpToIndex(-1)
252 " A command for showing error details.
253 command! -bar ALEDetail :call ale#cursor#ShowCursorDetail()
255 " Define commands for turning ALE on or off.
256 command! -bar ALEToggle :call ale#toggle#Toggle()
257 command! -bar ALEEnable :call ale#toggle#Enable()
258 command! -bar ALEDisable :call ale#toggle#Disable()
259 command! -bar ALEReset :call ale#toggle#Reset()
260 " Commands for turning ALE on or off for a buffer.
261 command! -bar ALEToggleBuffer :call ale#toggle#ToggleBuffer(bufnr(''))
262 command! -bar ALEEnableBuffer :call ale#toggle#EnableBuffer(bufnr(''))
263 command! -bar ALEDisableBuffer :call ale#toggle#DisableBuffer(bufnr(''))
264 command! -bar ALEResetBuffer :call ale#toggle#ResetBuffer(bufnr(''))
265 " A command to stop all LSP-like clients, including tsserver.
266 command! -bar ALEStopAllLSPs :call ale#lsp#reset#StopAllLSPs()
267 " A command to stop a specific language server, or tsseserver.
268 command! -bar -bang -nargs=1 -complete=customlist,ale#lsp#reset#Complete ALEStopLSP :call ale#lsp#reset#StopLSP(<f-args>, '<bang>')
270 " A command for linting manually.
271 command! -bar ALELint :call ale#Queue(0, 'lint_file')
272 " Stop current jobs when linting.
273 command! -bar ALELintStop :call ale#engine#Stop(bufnr(''))
275 " Commands to manually populate the quickfixes.
276 command! -bar ALEPopulateQuickfix :call ale#list#ForcePopulateErrorList(1)
277 command! -bar ALEPopulateLocList :call ale#list#ForcePopulateErrorList(0)
279 " Define a command to get information about current filetype.
280 command! -bar -nargs=* ALEInfo :call ale#debugging#InfoCommand(<f-args>)
281 " Deprecated and scheduled for removal in 4.0.0.
282 command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboardDeprecatedCommand()
283 " Copy ALE information to a file.
284 command! -bar -nargs=1 ALEInfoToFile :call ale#debugging#InfoToFile(<f-args>)
286 " Fix problems in files.
287 command! -bar -bang -nargs=* -complete=customlist,ale#fix#registry#CompleteFixers ALEFix :call ale#fix#Fix(bufnr(''), '<bang>', <f-args>)
288 " Suggest registered functions to use for fixing problems.
289 command! -bar ALEFixSuggest :call ale#fix#registry#Suggest(&filetype)
291 " Go to definition for tsserver and LSP
292 command! -bar -nargs=* ALEGoToDefinition :call ale#definition#GoToCommandHandler('', <f-args>)
294 " Go to type definition for tsserver and LSP
295 command! -bar -nargs=* ALEGoToTypeDefinition :call ale#definition#GoToCommandHandler('type', <f-args>)
297 " Go to implementation for tsserver and LSP
298 command! -bar -nargs=* ALEGoToImplementation :call ale#definition#GoToCommandHandler('implementation', <f-args>)
300 " Repeat a previous selection in the preview window
301 command! -bar ALERepeatSelection :call ale#preview#RepeatSelection()
303 " Find references for tsserver and LSP
304 command! -bar -nargs=* ALEFindReferences :call ale#references#Find(<f-args>)
306 " Show summary information for the cursor.
307 command! -bar ALEHover :call ale#hover#ShowAtCursor()
309 " Show documentation for the cursor.
310 command! -bar ALEDocumentation :call ale#hover#ShowDocumentationAtCursor()
312 " Search for appearances of a symbol, such as a type name or function name.
313 command! -nargs=1 ALESymbolSearch :call ale#symbol#Search(<q-args>)
315 " Complete text with tsserver and LSP
316 command! -bar ALEComplete :call ale#completion#GetCompletions('ale-manual')
318 " Try to find completions for the current symbol that add additional text.
319 command! -bar ALEImport :call ale#completion#Import()
321 " Rename symbols using tsserver and LSP
322 command! -bar -bang ALERename :call ale#rename#Execute()
324 " Rename file using tsserver
325 command! -bar -bang ALEFileRename :call ale#filerename#Execute()
327 " Apply code actions to a range.
328 command! -bar -range ALECodeAction :call ale#codefix#Execute(<range>)
330 " Organize import statements using tsserver
331 command! -bar ALEOrganizeImports :call ale#organize_imports#Execute()
333 " <Plug> mappings for commands
334 nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return>
335 nnoremap <silent> <Plug>(ale_previous_wrap) :ALEPreviousWrap<Return>
336 nnoremap <silent> <Plug>(ale_previous_error) :ALEPrevious -error<Return>
337 nnoremap <silent> <Plug>(ale_previous_wrap_error) :ALEPrevious -wrap -error<Return>
338 nnoremap <silent> <Plug>(ale_previous_warning) :ALEPrevious -warning<Return>
339 nnoremap <silent> <Plug>(ale_previous_wrap_warning) :ALEPrevious -wrap -warning<Return>
340 nnoremap <silent> <Plug>(ale_next) :ALENext<Return>
341 nnoremap <silent> <Plug>(ale_next_wrap) :ALENextWrap<Return>
342 nnoremap <silent> <Plug>(ale_next_error) :ALENext -error<Return>
343 nnoremap <silent> <Plug>(ale_next_wrap_error) :ALENext -wrap -error<Return>
344 nnoremap <silent> <Plug>(ale_next_warning) :ALENext -warning<Return>
345 nnoremap <silent> <Plug>(ale_next_wrap_warning) :ALENext -wrap -warning<Return>
346 nnoremap <silent> <Plug>(ale_first) :ALEFirst<Return>
347 nnoremap <silent> <Plug>(ale_last) :ALELast<Return>
348 nnoremap <silent> <Plug>(ale_toggle) :ALEToggle<Return>
349 nnoremap <silent> <Plug>(ale_enable) :ALEEnable<Return>
350 nnoremap <silent> <Plug>(ale_disable) :ALEDisable<Return>
351 nnoremap <silent> <Plug>(ale_reset) :ALEReset<Return>
352 nnoremap <silent> <Plug>(ale_toggle_buffer) :ALEToggleBuffer<Return>
353 nnoremap <silent> <Plug>(ale_enable_buffer) :ALEEnableBuffer<Return>
354 nnoremap <silent> <Plug>(ale_disable_buffer) :ALEDisableBuffer<Return>
355 nnoremap <silent> <Plug>(ale_reset_buffer) :ALEResetBuffer<Return>
356 nnoremap <silent> <Plug>(ale_lint) :ALELint<Return>
357 nnoremap <silent> <Plug>(ale_detail) :ALEDetail<Return>
358 nnoremap <silent> <Plug>(ale_fix) :ALEFix<Return>
359 nnoremap <silent> <Plug>(ale_go_to_definition) :ALEGoToDefinition<Return>
360 nnoremap <silent> <Plug>(ale_go_to_definition_in_tab) :ALEGoToDefinition -tab<Return>
361 nnoremap <silent> <Plug>(ale_go_to_definition_in_split) :ALEGoToDefinition -split<Return>
362 nnoremap <silent> <Plug>(ale_go_to_definition_in_vsplit) :ALEGoToDefinition -vsplit<Return>
363 nnoremap <silent> <Plug>(ale_go_to_type_definition) :ALEGoToTypeDefinition<Return>
364 nnoremap <silent> <Plug>(ale_go_to_type_definition_in_tab) :ALEGoToTypeDefinition -tab<Return>
365 nnoremap <silent> <Plug>(ale_go_to_type_definition_in_split) :ALEGoToTypeDefinition -split<Return>
366 nnoremap <silent> <Plug>(ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinition -vsplit<Return>
367 nnoremap <silent> <Plug>(ale_go_to_implementation) :ALEGoToImplementation<Return>
368 nnoremap <silent> <Plug>(ale_go_to_implementation_in_tab) :ALEGoToImplementation -tab<Return>
369 nnoremap <silent> <Plug>(ale_go_to_implementation_in_split) :ALEGoToImplementation -split<Return>
370 nnoremap <silent> <Plug>(ale_go_to_implementation_in_vsplit) :ALEGoToImplementation -vsplit<Return>
371 nnoremap <silent> <Plug>(ale_find_references) :ALEFindReferences<Return>
372 nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return>
373 nnoremap <silent> <Plug>(ale_documentation) :ALEDocumentation<Return>
374 inoremap <silent> <Plug>(ale_complete) <C-\><C-O>:ALEComplete<Return>
375 nnoremap <silent> <Plug>(ale_import) :ALEImport<Return>
376 nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
377 nnoremap <silent> <Plug>(ale_filerename) :ALEFileRename<Return>
378 nnoremap <silent> <Plug>(ale_code_action) :ALECodeAction<Return>
379 nnoremap <silent> <Plug>(ale_repeat_selection) :ALERepeatSelection<Return>
380 nnoremap <silent> <Plug>(ale_info) :ALEInfo<Return>
381 nnoremap <silent> <Plug>(ale_info_echo) :ALEInfo -echo<Return>
382 nnoremap <silent> <Plug>(ale_info_clipboard) :ALEInfo -clipboard<Return>
383 nnoremap <silent> <Plug>(ale_info_preview) :ALEInfo -preview<Return>
385 " Set up autocmd groups now.
386 call ale#events#Init()
390 augroup ALECleanupGroup
392 " Clean up buffers automatically when they are unloaded.
393 autocmd BufDelete * if exists('*ale#engine#Cleanup') | call ale#engine#Cleanup(str2nr(expand('<abuf>'))) | endif
394 autocmd QuitPre * call ale#events#QuitEvent(str2nr(expand('<abuf>')))
396 if exists('##VimSuspend')
397 autocmd VimSuspend * if exists('*ale#engine#CleanupEveryBuffer') | call ale#engine#CleanupEveryBuffer() | endif