if exists('g:autoloaded_tabby') finish endif let g:autoloaded_tabby = 1 " Table of Contents " 1. Commands: Implement *:Tabby* commands " 2. Settings: Handle global *Tabby-options* " 3. Node Job: Manage node process, implement IO callbacks " 4. Scheduler: Schedule completion requests " 5. Completion UI: Show up completion, handle hotkeys " 6. Utils: Utility functions " 1. Commands " See *:Tabby* in help document for more details. " " Notable script-local variables: " - s:commmands " A dictionary contains all commands. Use name as key and function as value. " let s:commands = {} function! s:commands.status(...) call tabby#Status() endfunction function! s:commands.enable(...) call tabby#Enable() call tabby#Status() endfunction function! s:commands.disable(...) call tabby#Disable() call tabby#Status() endfunction function! s:commands.toggle(...) call tabby#Toggle() endfunction function! s:commands.help(...) let args = get(a:, 1, []) if len(args) < 1 execute 'help Tabby' return endif try execute 'help Tabby-' . join(args, '-') return catch endtry try execute 'help tabby_' . join(args, '_') return catch endtry execute 'help Tabby' endfunction function! tabby#CompleteCommands(arglead, cmd, pos) let words = split(a:cmd[0:a:pos].'#', ' ') if len(words) > 3 return [] endif if len(words) == 3 if words[1] == 'help' let candidates = ['compatibility', 'commands', 'options', 'keybindings'] else return [] endif else let candidates = keys(s:commands) endif let end_index = len(a:arglead) - 1 if end_index < 0 return candidates else return filter(candidates, { idx, val -> \ val[0:end_index] ==# a:arglead \}) endif endfunction function! tabby#Command(args) let args = split(a:args, ' ') if len(args) < 1 call tabby#Status() echo 'Use :help Tabby to see available commands.' return endif if has_key(s:commands, args[0]) call s:commands[args[0]](args[1:]) else echo 'Unknown command' endif endfunction " 2. Settings " See *Tabby-options* in help document for more details. " " Available global options: " - g:tabby_enabled " - g:tabby_suggestion_delay " - g:tabby_filetype_to_languages " - g:tabby_server_url " if !exists('g:tabby_enabled') let g:tabby_enabled = v:true endif if !exists('g:tabby_suggestion_delay') let g:tabby_suggestion_delay = 150 endif if !exists('g:tabby_filetype_to_languages') " From: vim filetype https://github.com/vim/vim/blob/master/runtime/filetype.vim " To: vscode language identifier https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers " Not listed filetype will be used as language identifier directly. let g:tabby_filetype_to_languages = { \ "bash": "shellscript", \ "cs": "csharp", \ "objc": "objective-c", \ "objcpp": "objective-cpp", \ } endif if !exists('g:tabby_server_url') let g:tabby_server_url = 'http://localhost:8080' endif if !exists('g:tabby_agent_logs') let g:tabby_agent_logs = 'error' endif " 3. Node Job " " Notable script-local variables: " - s:tabby " Stores the job id of current node process " " - s:tabby_status " Syncs with status of node agent, updated by notification from agent " " - s:errmsg " Stores error message if self check failed before starting node process " function! tabby#Enable() let g:tabby_enabled = v:true if !tabby#IsRunning() call tabby#Start() endif endfunction function! tabby#Disable() let g:tabby_enabled = v:false if tabby#IsRunning() call tabby#Stop() endif endfunction function! tabby#Toggle() if g:tabby_enabled call tabby#Disable() else call tabby#Enable() endif endfunction function! tabby#Start() if !g:tabby_enabled || tabby#IsRunning() return endif let check_job = tabby#job#Check() if !check_job.ok let s:errmsg = check_job.message return endif let check_virtual_text = tabby#virtual_text#Check() if !check_virtual_text.ok let s:errmsg = check_virtual_text.message return endif call tabby#virtual_text#Init() if !executable('node') let s:errmsg = 'Tabby requires node to be installed.' return endif let tabby_root = expand('