or run

tessl search
Log in

Version

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/coc.nvim@0.0.x

docs

index.md
tile.json

tessl/npm-coc-nvim

tessl install tessl/npm-coc-nvim@0.0.0

LSP based intellisense engine for neovim & vim8.

autocmds.mddocs/reference/

Autocmd Events [Intermediate]

Complexity: Intermediate | Category: Reference | Keywords: autocmd, events, hooks, integration, callbacks

Common Tasks: Initialize on startup | Update statusline | Handle diagnostics | Track navigation | Respond to UI events

Integration points via User autocmd events for responding to coc.nvim lifecycle and state changes. Use these events to customize behavior and integrate with other plugins.

Table of Contents

  • Common Tasks
  • Service Events
  • Status Events
  • Navigation Events
  • Snippet Events
  • UI Events
  • Usage Examples
  • Error Handling
  • Troubleshooting
  • See Also

Common Tasks

Run Code After Initialization

autocmd User CocNvimInit call MyInitFunction()

Execute custom setup after coc.nvim starts.

Update Statusline on Changes

autocmd User CocStatusChange,CocDiagnosticChange call lightline#update()

Refresh statusline when status or diagnostics change.

Auto-Show Signature Help in Snippets

autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')

Display signature help when jumping between snippet placeholders.

Auto-Open Location List

autocmd User CocLocationsChange CocList --normal location

Open location list when jump results are available.

Close Float on Cursor Move

autocmd User CocOpenFloat autocmd CursorMoved * ++once call coc#float#close_all()

Automatically close floating windows when cursor moves.

Service Events

User CocNvimInit

autocmd User CocNvimInit {command}

Triggered when coc.nvim has finished initializing and is ready for use.

When Triggered: After service startup completes

Use Cases:

  • Run initialization code
  • Configure settings programmatically
  • Register custom commands
  • Load extensions that depend on coc

Example:

autocmd User CocNvimInit call s:CocInit()

function! s:CocInit() abort
  echo 'Coc initialized'

  " Register custom commands
  call coc#add_command('mycommand', 'echo "Hello"', 'My custom command')

  " Configure settings
  call coc#config('suggest.noselect', v:true)
  call coc#config('diagnostic.errorSign', '✗')

  " Enable extensions
  call coc#add_extension('coc-json', 'coc-tsserver')
endfunction

Integration Examples:

" Initialize custom features
autocmd User CocNvimInit call InitMyFeatures()

" Set up buffer-local mappings
autocmd User CocNvimInit autocmd FileType * call SetupCocMappings()

" Start tracking coc state
autocmd User CocNvimInit let g:coc_ready = 1

Status Events

User CocStatusChange

autocmd User CocStatusChange {command}

Triggered when the status string (g:coc_status) changes.

When Triggered: Status line text updates (extension messages, loading indicators)

Use Cases:

  • Update statusline display
  • Show notifications
  • Log status changes
  • Track extension activity

Example:

" Lightline integration
autocmd User CocStatusChange call lightline#update()

" Airline integration
autocmd User CocStatusChange call airline#update_statusline()

" Custom statusline (force redraw)
autocmd User CocStatusChange let &ro = &ro

" Log status changes
autocmd User CocStatusChange call s:LogStatus()

function! s:LogStatus() abort
  let status = get(g:, 'coc_status', '')
  if !empty(status)
    echom strftime('%H:%M:%S') . ' - Coc: ' . status
  endif
endfunction

Statusline Functions:

function! CocStatusline() abort
  let status = get(g:, 'coc_status', '')
  let func = get(b:, 'coc_current_function', '')

  let parts = []
  if !empty(func)
    call add(parts, func)
  endif
  if !empty(status)
    call add(parts, status)
  endif

  return join(parts, ' ')
endfunction

autocmd User CocStatusChange call lightline#update()

User CocDiagnosticChange

autocmd User CocDiagnosticChange {command}

Triggered when diagnostics are updated for any buffer.

When Triggered:

  • Diagnostics received from language server
  • Diagnostics cleared
  • Buffer diagnostics refreshed

Use Cases:

  • Update statusline with diagnostic counts
  • Show notifications for errors
  • Update UI indicators
  • Track code quality

Example:

autocmd User CocDiagnosticChange call s:UpdateDiagnostics()

function! s:UpdateDiagnostics() abort
  let info = get(b:, 'coc_diagnostic_info', {})
  let errors = get(info, 'error', 0)
  let warnings = get(info, 'warning', 0)

  " Show notification for new errors
  if errors > 0
    echohl ErrorMsg
    echo printf('Errors: %d', errors)
    echohl None
  endif

  " Update statusline
  let &ro = &ro
endfunction

Diagnostic Tracking:

" Track diagnostic history
let g:diagnostic_history = []

autocmd User CocDiagnosticChange call s:TrackDiagnostics()

function! s:TrackDiagnostics() abort
  let info = get(b:, 'coc_diagnostic_info', {})
  call add(g:diagnostic_history, {
    \ 'time': strftime('%H:%M:%S'),
    \ 'buffer': bufnr('%'),
    \ 'errors': get(info, 'error', 0),
    \ 'warnings': get(info, 'warning', 0)
    \ })

  " Keep only last 100 entries
  if len(g:diagnostic_history) > 100
    call remove(g:diagnostic_history, 0, len(g:diagnostic_history) - 100)
  endif
endfunction

command! DiagnosticHistory echo g:diagnostic_history

Notification Example:

let g:diagnostic_notify_threshold = 5

autocmd User CocDiagnosticChange call s:NotifyDiagnostics()

function! s:NotifyDiagnostics() abort
  let info = get(b:, 'coc_diagnostic_info', {})
  let errors = get(info, 'error', 0)

  if errors >= g:diagnostic_notify_threshold
    echohl ErrorMsg
    echo printf('Warning: %d errors in current buffer!', errors)
    echohl None
  endif
endfunction

Navigation Events

User CocLocationsChange

autocmd User CocLocationsChange {command}

Triggered when the location list is updated after jump operations (definition, references, etc.).

When Triggered:

  • After :CocList location
  • After jump to definition/references
  • Location list populated

Use Cases:

  • Open location list window
  • Process jump results
  • Track navigation history
  • Show location count

Example:

autocmd User CocLocationsChange call s:HandleLocations()

function! s:HandleLocations() abort
  let locations = get(g:, 'coc_jump_locations', [])

  if len(locations) > 1
    " Multiple locations - open location list
    CocList --normal location
  elseif len(locations) == 1
    " Single location - already jumped
    echo 'Jumped to single location'
  else
    " No locations found
    echo 'No locations found'
  endif
endfunction

Auto-Open Location List:

" Always open location list for multiple results
autocmd User CocLocationsChange call s:AutoLocationList()

function! s:AutoLocationList() abort
  let locations = get(g:, 'coc_jump_locations', [])

  if len(locations) > 1
    " Show in location list with preview
    CocList --normal location
    echo printf('Found %d locations', len(locations))
  endif
endfunction

Navigation History:

let g:coc_nav_history = []

autocmd User CocLocationsChange call s:TrackNavigation()

function! s:TrackNavigation() abort
  let locations = get(g:, 'coc_jump_locations', [])

  call add(g:coc_nav_history, {
    \ 'time': strftime('%H:%M:%S'),
    \ 'count': len(locations),
    \ 'file': expand('%:p')
    \ })

  " Keep last 50
  if len(g:coc_nav_history) > 50
    call remove(g:coc_nav_history, 0, len(g:coc_nav_history) - 50)
  endif
endfunction

command! NavHistory echo g:coc_nav_history

Snippet Events

User CocJumpPlaceholder

autocmd User CocJumpPlaceholder {command}

Triggered when jumping to a snippet placeholder.

When Triggered:

  • Tab key pressed in snippet
  • coc#snippet#next() or coc#snippet#prev() called
  • Placeholder navigation occurs

Use Cases:

  • Show signature help at parameter positions
  • Update UI for snippet mode
  • Trigger completion
  • Track snippet usage

Example:

" Auto-show signature help in function parameters
autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')

" Or with condition
autocmd User CocJumpPlaceholder call s:OnPlaceholderJump()

function! s:OnPlaceholderJump() abort
  " Show signature help if available
  if CocAction('hasProvider', 'signature')
    call CocActionAsync('showSignatureHelp')
  endif

  " Or trigger completion
  " call coc#refresh()
endfunction

Advanced Snippet Handling:

autocmd User CocJumpPlaceholder call s:SnippetJump()

function! s:SnippetJump() abort
  " Show signature help for function parameters
  if CocAction('hasProvider', 'signature')
    call CocActionAsync('showSignatureHelp')
  endif

  " Auto-trigger completion if not whitespace
  if col('.') > 1 && getline('.')[col('.')-2] !~# '\s'
    call coc#refresh()
  endif

  " Update statusline
  let &ro = &ro
endfunction

Snippet Tracking:

let g:snippet_jump_count = 0

autocmd User CocJumpPlaceholder let g:snippet_jump_count += 1

" Show count in statusline
function! SnippetInfo()
  if get(b:, 'coc_snippet_active', 0)
    return printf('Snippet [%d]', g:snippet_jump_count)
  endif
  return ''
endfunction

UI Events

User CocOpenFloat

autocmd User CocOpenFloat {command}

Triggered when a floating window is opened.

When Triggered:

  • Hover window shown
  • Signature help displayed
  • Diagnostic preview opened
  • Any float window created

Use Cases:

  • Customize float window appearance
  • Add custom keymaps to floats
  • Track float window state
  • Auto-close floats

Example:

autocmd User CocOpenFloat call s:OnFloatOpen()

function! s:OnFloatOpen() abort
  " Get window ID
  let winid = get(g:, 'coc_last_float_win', 0)

  if winid > 0
    " Add custom mappings if needed
    " Or customize appearance
    echo 'Float window opened: ' . winid
  endif
endfunction

Auto-Close Float:

" Close float on cursor move
autocmd User CocOpenFloat call s:AutoCloseFloat()

function! s:AutoCloseFloat() abort
  augroup CocFloatAutoClose
    autocmd!
    autocmd CursorMoved,CursorMovedI * ++once call coc#float#close_all()
  augroup END
endfunction

" Or close after timeout
autocmd User CocOpenFloat call timer_start(5000, {-> coc#float#close_all()})

Float Scroll Mappings:

autocmd User CocOpenFloat call s:FloatScroll()

function! s:FloatScroll() abort
  let winid = get(g:, 'coc_last_float_win', 0)

  if winid > 0 && nvim_win_is_valid(winid)
    " Add scroll mappings
    nnoremap <silent><nowait><buffer> <C-f> :call coc#float#scroll(1)<CR>
    nnoremap <silent><nowait><buffer> <C-b> :call coc#float#scroll(0)<CR>
  endif
endfunction

User CocOpenFloatPrompt

autocmd User CocOpenFloatPrompt {command}

Triggered when a prompt floating window is opened.

When Triggered:

  • Rename prompt shown
  • Input prompt displayed
  • Interactive prompts opened

Use Cases:

  • Customize prompt behavior
  • Add validation
  • Track prompt state
  • Pre-fill prompt input

Example:

autocmd User CocOpenFloatPrompt call s:OnPromptOpen()

function! s:OnPromptOpen() abort
  echo 'Prompt window opened'

  " Could add custom prompt handling here
  " Or validation logic
endfunction

Prompt Enhancement:

autocmd User CocOpenFloatPrompt call s:EnhancePrompt()

function! s:EnhancePrompt() abort
  " Enable autocomplete in prompt if needed
  " Or add custom validation
  let winid = get(g:, 'coc_last_float_win', 0)

  if winid > 0
    " Customize prompt window
  endif
endfunction

User CocTerminalOpen

autocmd User CocTerminalOpen {command}

Triggered when a coc terminal window is opened.

When Triggered:

  • Terminal window created
  • Build/task output shown
  • Extension opens terminal

Use Cases:

  • Configure terminal window
  • Add terminal keymaps
  • Track terminal jobs
  • Auto-enter insert mode

Example:

autocmd User CocTerminalOpen call s:ConfigureTerminal()

function! s:ConfigureTerminal() abort
  " Enter insert mode in terminal
  if &buftype ==# 'terminal'
    startinsert
  endif

  " Set terminal-specific mappings
  tnoremap <buffer> <Esc> <C-\><C-n>
  tnoremap <buffer> <C-w> <C-\><C-n><C-w>
endfunction

Advanced Terminal Setup:

autocmd User CocTerminalOpen call s:SetupTerminal()

function! s:SetupTerminal() abort
  if &buftype !=# 'terminal'
    return
  endif

  " Enter insert mode
  startinsert

  " Terminal mappings
  tnoremap <buffer> <Esc> <C-\><C-n>
  tnoremap <buffer> <C-w> <C-\><C-n><C-w>
  tnoremap <buffer> <C-q> <C-\><C-n>:close<CR>

  " Auto-close on exit
  autocmd BufLeave <buffer> if &buftype ==# 'terminal' | close | endif

  " Track terminal
  let g:coc_terminal_count = get(g:, 'coc_terminal_count', 0) + 1
endfunction

Usage Examples

Complete Event Setup

Full integration with all events:

augroup CocEvents
  autocmd!

  " Initialization
  autocmd User CocNvimInit call s:CocInit()

  " Status updates
  autocmd User CocStatusChange call s:UpdateStatus()
  autocmd User CocDiagnosticChange call s:UpdateDiagnostics()

  " Navigation
  autocmd User CocLocationsChange call s:HandleLocations()

  " Snippets
  autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')

  " UI
  autocmd User CocOpenFloat call s:OnFloatOpen()
  autocmd User CocOpenFloatPrompt call s:OnPromptOpen()
  autocmd User CocTerminalOpen call s:ConfigureTerminal()
augroup END

function! s:CocInit() abort
  echo 'Coc initialized'
  call coc#config('suggest.noselect', v:true)
endfunction

function! s:UpdateStatus() abort
  call lightline#update()
endfunction

function! s:UpdateDiagnostics() abort
  let &ro = &ro
endfunction

function! s:HandleLocations() abort
  let count = len(get(g:, 'coc_jump_locations', []))
  if count > 1
    CocList --normal location
  endif
endfunction

function! s:OnFloatOpen() abort
  " Auto-close on cursor move
  augroup CocFloatAutoClose
    autocmd!
    autocmd CursorMoved * ++once call coc#float#close_all()
  augroup END
endfunction

function! s:OnPromptOpen() abort
  " Prompt customization
endfunction

function! s:ConfigureTerminal() abort
  if &buftype ==# 'terminal'
    startinsert
  endif
endfunction

Statusline Integration

Complete statusline with all events:

function! CocStatusline() abort
  let status = get(g:, 'coc_status', '')
  let info = get(b:, 'coc_diagnostic_info', {})
  let func = get(b:, 'coc_current_function', '')
  let msgs = []

  " Diagnostic counts
  if get(info, 'error', 0)
    call add(msgs, 'E:' . info.error)
  endif
  if get(info, 'warning', 0)
    call add(msgs, 'W:' . info.warning)
  endif

  " Current function
  if !empty(func)
    call add(msgs, func)
  endif

  " Service status
  if !empty(status)
    call add(msgs, status)
  endif

  return join(msgs, ' ')
endfunction

" Update on any change
autocmd User CocStatusChange,CocDiagnosticChange call lightline#update()

" Lightline component
let g:lightline = {
  \ 'component_function': {
  \   'coc_status': 'CocStatusline'
  \ }
  \ }

Event Logging

Debug helper to log all events:

let g:coc_event_log = []

function! LogCocEvent(event) abort
  call add(g:coc_event_log, {
    \ 'event': a:event,
    \ 'time': strftime('%H:%M:%S'),
    \ 'buffer': bufnr('%'),
    \ 'file': expand('%:t')
    \ })

  " Keep only last 100 events
  if len(g:coc_event_log) > 100
    call remove(g:coc_event_log, 0, len(g:coc_event_log) - 100)
  endif

  " Optional: echo events
  " echo a:event . ' at ' . strftime('%H:%M:%S')
endfunction

augroup CocEventLogger
  autocmd!
  autocmd User CocNvimInit call LogCocEvent('Init')
  autocmd User CocStatusChange call LogCocEvent('StatusChange')
  autocmd User CocDiagnosticChange call LogCocEvent('DiagnosticChange')
  autocmd User CocLocationsChange call LogCocEvent('LocationsChange')
  autocmd User CocJumpPlaceholder call LogCocEvent('JumpPlaceholder')
  autocmd User CocOpenFloat call LogCocEvent('OpenFloat')
  autocmd User CocOpenFloatPrompt call LogCocEvent('OpenFloatPrompt')
  autocmd User CocTerminalOpen call LogCocEvent('TerminalOpen')
augroup END

command! CocEventLog call s:ShowEventLog()

function! s:ShowEventLog() abort
  echo '=== Coc Event Log ==='
  for entry in g:coc_event_log
    echo printf('[%s] %s in %s', entry.time, entry.event, entry.file)
  endfor
endfunction

Conditional Initialization

Initialize based on context:

autocmd User CocNvimInit call s:ConditionalInit()

function! s:ConditionalInit() abort
  let ft = &filetype

  " Filetype-specific settings
  if index(['javascript', 'typescript', 'python'], ft) >= 0
    call coc#config('suggest.autoTrigger', 'always')
    call coc#config('diagnostic.refreshOnInsertMode', v:true)
  else
    call coc#config('suggest.autoTrigger', 'trigger')
    call coc#config('diagnostic.refreshOnInsertMode', v:false)
  endif

  " Project-specific settings
  if filereadable('.coc-config.vim')
    source .coc-config.vim
  endif
endfunction

Debounced Event Handling

Prevent excessive updates:

let g:status_timer = -1
let g:diagnostic_timer = -1

autocmd User CocStatusChange call s:DebouncedStatusUpdate()
autocmd User CocDiagnosticChange call s:DebouncedDiagnosticUpdate()

function! s:DebouncedStatusUpdate() abort
  if g:status_timer != -1
    call timer_stop(g:status_timer)
  endif
  let g:status_timer = timer_start(100, {-> s:UpdateStatusUI()})
endfunction

function! s:DebouncedDiagnosticUpdate() abort
  if g:diagnostic_timer != -1
    call timer_stop(g:diagnostic_timer)
  endif
  let g:diagnostic_timer = timer_start(500, {-> s:UpdateDiagnosticUI()})
endfunction

function! s:UpdateStatusUI() abort
  let g:status_timer = -1
  call lightline#update()
endfunction

function! s:UpdateDiagnosticUI() abort
  let g:diagnostic_timer = -1
  let &ro = &ro
endfunction

Error Handling

Check Event Availability

Verify coc is ready:

function! SafeEventHandler() abort
  if !get(g:, 'coc_service_initialized', 0)
    return
  endif

  " Handle event
endfunction

autocmd User CocStatusChange call SafeEventHandler()

Guard Against Errors

Wrap event handlers:

function! SafeCall(func) abort
  try
    call call(a:func, [])
  catch
    echohl ErrorMsg
    echo 'Error in ' . a:func . ': ' . v:exception
    echohl None
  endtry
endfunction

autocmd User CocNvimInit call SafeCall('s:CocInit')

Validate State

Check before using state:

function! UpdateStatus() abort
  " Check service is ready
  if !exists('g:did_coc_loaded')
    return
  endif

  " Check variable exists
  let status = get(g:, 'coc_status', '')
  if empty(status)
    return
  endif

  " Update
  call lightline#update()
endfunction

Troubleshooting

Problem: Events Not Firing

Problem: Autocmd events don't trigger.

Solutions:

  1. Check coc is loaded:

    :echo exists('g:did_coc_loaded')
  2. Verify event name is correct:

    " Correct
    autocmd User CocNvimInit echo 'Init'
    
    " Wrong
    autocmd User CocInit echo 'Init'
  3. Check service is initialized:

    :echo get(g:, 'coc_service_initialized', 0)

Problem: Statusline Not Updating

Problem: Statusline doesn't refresh on events.

Solutions:

  1. Force redraw:

    autocmd User CocStatusChange let &ro = &ro
  2. Use plugin refresh:

    " Lightline
    autocmd User CocStatusChange call lightline#update()
    
    " Airline
    autocmd User CocStatusChange call airline#update_statusline()
  3. Add delay if needed:

    autocmd User CocStatusChange call timer_start(50, {-> lightline#update()})

Problem: Events Fire Too Often

Problem: Events trigger excessively causing performance issues.

Solutions:

  1. Use debouncing:

    let g:update_timer = -1
    
    function! DebouncedUpdate()
      if g:update_timer != -1
        call timer_stop(g:update_timer)
      endif
      let g:update_timer = timer_start(200, {-> lightline#update()})
    endfunction
    
    autocmd User CocStatusChange call DebouncedUpdate()
  2. Check if update is needed:

    let g:last_status = ''
    
    function! UpdateIfChanged()
      let status = get(g:, 'coc_status', '')
      if status !=# g:last_status
        let g:last_status = status
        call lightline#update()
      endif
    endfunction

Problem: Float Auto-Close Not Working

Problem: Float windows don't close on cursor move.

Solutions:

  1. Use ++once flag:

    autocmd User CocOpenFloat autocmd CursorMoved * ++once call coc#float#close_all()
  2. Use separate augroup:

    autocmd User CocOpenFloat call s:AutoClose()
    
    function! s:AutoClose()
      augroup CocFloatClose
        autocmd!
        autocmd CursorMoved * call coc#float#close_all()
        autocmd CursorMoved * autocmd! CocFloatClose
      augroup END
    endfunction

Problem: Terminal Not Entering Insert Mode

Problem: Terminal opens but stays in normal mode.

Solutions:

  1. Use startinsert with delay:

    autocmd User CocTerminalOpen call timer_start(10, {-> execute('startinsert')})
  2. Check buffer type:

    autocmd User CocTerminalOpen call s:TerminalInsert()
    
    function! s:TerminalInsert()
      if &buftype ==# 'terminal'
        startinsert
      endif
    endfunction

See Also

  • Variables - State variables updated by events
  • Service Management - Service lifecycle
  • Diagnostics - Diagnostic events
  • Float Windows - Float window events
  • Configuration - Runtime configuration