diff --git a/init.lua b/init.lua index 2769ee54..a300e034 100644 --- a/init.lua +++ b/init.lua @@ -151,12 +151,12 @@ require('lazy').setup({ 'numToStr/Comment.nvim', opts = { toggler = { - line = '/', -- Changed from - block = 'b', -- Changed from + line = 'gc', + block = 'gb', }, opleader = { - line = '/', -- Optional - block = 'B', -- Optional + line = 'gc', + block = 'gb', }, } }, @@ -216,6 +216,15 @@ vim.o.softtabstop = 2 vim.o.shiftwidth = 2 vim.o.expandtab = true +vim.api.nvim_create_autocmd('FileType', { + pattern = { 'python' }, + callback = function() + vim.bo.tabstop = 4 + vim.bo.softtabstop = 4 + vim.bo.shiftwidth = 4 + end, +}) + -- Basic keymaps vim.keymap.set({ 'n', 'v' }, '', '', { silent = true }) vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true }) @@ -257,7 +266,27 @@ end, { desc = '[/] Fuzzily search in current buffer' }) -- Treesitter configuration vim.defer_fn(function() require('nvim-treesitter.configs').setup { - ensure_installed = { 'c', 'cpp', 'go', 'lua', 'python', 'rust', 'tsx', 'javascript', 'typescript', 'vimdoc', 'vim', 'bash' }, + ensure_installed = { + 'c', + 'cpp', + 'go', + 'lua', + 'python', + 'rust', + 'tsx', + 'javascript', + 'typescript', + 'vimdoc', + 'vim', + 'bash', + 'html', + 'css', + 'json', + 'toml', + 'yaml', + 'dockerfile', + 'htmldjango', + }, auto_install = false, highlight = { enable = true }, indent = { enable = true }, @@ -357,12 +386,54 @@ end require('mason').setup() require('mason-lspconfig').setup() -local servers = { lua_ls = { Lua = { workspace = { checkThirdParty = false }, telemetry = { enable = false } } } } +local lspconfig = require 'lspconfig' +local servers = { + pyright = { + python = { + analysis = { + autoSearchPaths = true, + diagnosticMode = 'openFilesOnly', + useLibraryCodeForTypes = true, + }, + }, + }, + lua_ls = { + Lua = { + workspace = { checkThirdParty = false }, + telemetry = { enable = false }, + }, + }, +} local capabilities = require('cmp_nvim_lsp').default_capabilities(vim.lsp.protocol.make_client_capabilities()) local mason_lspconfig = require 'mason-lspconfig' mason_lspconfig.setup { ensure_installed = vim.tbl_keys(servers) } mason_lspconfig.setup_handlers { function(server_name) require('lspconfig')[server_name].setup { capabilities = capabilities, on_attach = on_attach, settings = servers[server_name], filetypes = (servers[server_name] or {}).filetypes, } end } +-- Ruff installation via Mason can fail on some Python setups. +-- If a system ruff binary exists, attach Ruff LSP directly. +local ruff_server = nil +if lspconfig.ruff then + ruff_server = 'ruff' +elseif lspconfig.ruff_lsp then + ruff_server = 'ruff_lsp' +end + +if vim.fn.executable 'ruff' == 1 and ruff_server then + lspconfig[ruff_server].setup { + capabilities = capabilities, + on_attach = on_attach, + } +end + +vim.api.nvim_create_autocmd('LspAttach', { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + if client and (client.name == 'ruff' or client.name == 'ruff_lsp') then + client.server_capabilities.hoverProvider = false + end + end, +}) + -- CMP setup local cmp = require 'cmp' local luasnip = require 'luasnip' @@ -408,13 +479,10 @@ cmp.setup { { name = 'nvim_lsp' }, { name = 'luasnip' }, }, -} - -require("cmp").setup({ formatting = { - format = require("tailwindcss-colorizer-cmp").formatter - } -}) + format = require('tailwindcss-colorizer-cmp').formatter, + }, +} require("colorizer").setup { user_default_options = { diff --git a/lua/custom/plugins/init.lua b/lua/custom/plugins/init.lua index 0542cd3a..1befe2d3 100644 --- a/lua/custom/plugins/init.lua +++ b/lua/custom/plugins/init.lua @@ -4,13 +4,6 @@ -- See the kickstart.nvim README for more information return { - { - 'neovim/nvim-lspconfig', - config = function() - require('custom.plugins.lspconfig') -- This simply loads the lspconfig.lua file - end, - }, - -- nvim-autopairs configuration { "windwp/nvim-autopairs", diff --git a/lua/kickstart/plugins/autoformat.lua b/lua/kickstart/plugins/autoformat.lua index d06e0c94..55abf562 100644 --- a/lua/kickstart/plugins/autoformat.lua +++ b/lua/kickstart/plugins/autoformat.lua @@ -4,18 +4,18 @@ -- Adds additional commands as well to manage the behavior return { - 'neovim/nvim-lspconfig', - 'jose-elias-alvarez/null-ls.nvim', + 'stevearc/conform.nvim', + event = { 'BufReadPre', 'BufNewFile' }, + cmd = { 'ConformInfo' }, config = function() -- Force .html files to be recognized as htmldjango for Jinja compatibility - vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, { - pattern = "*.html", + vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile' }, { + pattern = '*.html', callback = function() - vim.bo.filetype = "htmldjango" + vim.bo.filetype = 'htmldjango' end, }) - -- Switch for controlling whether you want autoformatting. -- Use :KickstartFormatToggle to toggle autoformatting on or off local format_is_enabled = true vim.api.nvim_create_user_command('KickstartFormatToggle', function() @@ -23,71 +23,28 @@ return { print('Setting autoformatting to: ' .. tostring(format_is_enabled)) end, {}) - -- Create an augroup that is used for managing our formatting autocmds. - -- We need one augroup per client to make sure that multiple clients - -- can attach to the same buffer without interfering with each other. - local _augroups = {} - local get_augroup = function(client) - if not _augroups[client.id] then - local group_name = 'kickstart-lsp-format-' .. client.name - local id = vim.api.nvim_create_augroup(group_name, { clear = true }) - _augroups[client.id] = id - end - - return _augroups[client.id] - end - - -- Whenever an LSP attaches to a buffer, we will run this function. - -- - -- See `:help LspAttach` for more information about this autocmd event. - vim.api.nvim_create_autocmd('LspAttach', { - group = vim.api.nvim_create_augroup('kickstart-lsp-attach-format', { clear = true }), - -- This is where we attach the autoformatting for reasonable clients - callback = function(args) - local client_id = args.data.client_id - local client = vim.lsp.get_client_by_id(client_id) - local bufnr = args.buf - - -- Only attach to clients that support document formatting - if not client.server_capabilities.documentFormattingProvider then - return - end - - -- Tsserver usually works poorly. Sorry you work with bad languages - -- You can remove this line if you know what you're doing :) - if client.name == 'tsserver' then - return - end - - -- Create an autocmd that will run *before* we save the buffer. - -- Run the formatting command for the LSP that has just attached. - vim.api.nvim_create_autocmd('BufWritePre', { - group = get_augroup(client), - buffer = bufnr, - callback = function() - if not format_is_enabled then - return - end - - vim.lsp.buf.format { - async = false, - filter = function(c) - return c.id == client.id - end, - } - end, - }) - end, - }) - - -- Set up null-ls for additional formatting needs - null_ls.setup({ - sources = { - null_ls.builtins.formatting.prettier.with({ - filetypes = { "html", "jinja", "htmldjango" }, - }), + require('conform').setup { + formatters_by_ft = { + python = { 'ruff_organize_imports', 'ruff_format' }, + htmldjango = { 'djlint' }, + html = { 'prettier' }, + css = { 'prettier' }, + javascript = { 'prettier' }, + json = { 'prettier' }, + yaml = { 'prettier' }, }, - }) + format_on_save = function(bufnr) + if not format_is_enabled then + return nil + end + + return { + timeout_ms = 1000, + lsp_format = 'fallback', + bufnr = bufnr, + } + end, + } end, } diff --git a/lua/kickstart/plugins/debug.lua b/lua/kickstart/plugins/debug.lua index 7fc783fa..b9095b7c 100644 --- a/lua/kickstart/plugins/debug.lua +++ b/lua/kickstart/plugins/debug.lua @@ -20,6 +20,7 @@ return { -- Add your own debuggers here 'leoluz/nvim-dap-go', + 'mfussenegger/nvim-dap-python', }, config = function() local dap = require 'dap' @@ -39,6 +40,7 @@ return { ensure_installed = { -- Update this to ensure that you have the debuggers for the langs you want 'delve', + 'debugpy', }, } @@ -83,5 +85,6 @@ return { -- Install golang specific config require('dap-go').setup() + require('dap-python').setup(vim.fn.exepath 'python3') end, } diff --git a/pack/kite/start/vim-plugin/.travis.yml b/pack/kite/start/vim-plugin/.travis.yml deleted file mode 100644 index 2ab9a273..00000000 --- a/pack/kite/start/vim-plugin/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -dist: trusty - -env: - global: - - DEPS=$HOME/deps - - PATH=$DEPS/bin:$PATH - -before_install: - - sudo apt-get install python-pip - - pip install --user awscli - - export PATH="$PATH:$HOME/.local/bin" - - curl --silent -L "https://s3-us-west-1.amazonaws.com/kite-data/tensorflow/libtensorflow-cpu-linux-x86_64-1.9.0.tar.gz" | tar -C $HOME -xz - - curl --silent --compressed --output "$HOME/kited-test" "https://s3-us-west-1.amazonaws.com/kited-test/linux/kited-test" - - chmod u+x "$HOME/kited-test" - -install: | - git config --global user.email "you@example.com" - git config --global user.name "Your Name" - C_OPTS="--prefix=$DEPS --with-features=huge --disable-gui " - git clone --depth 1 https://github.com/vim/vim - cd vim - export PATH=/usr/bin:$PATH - ./configure $C_OPTS - make - make install - cd - - export PATH=$DEPS/bin:$PATH - export VIM="$(which vim)" - - -script: - - vim --version - - cd test && bash test - - export LD_LIBRARY_PATH="$HOME/lib:$LD_LIBRARY_PATH" - - echo "Running tests with kited-local --------------" && $HOME/kited-test > ~/kite.log 2>&1 & sleep 20 && bash editor_tests && killall kited-test - diff --git a/pack/kite/start/vim-plugin/LICENSE b/pack/kite/start/vim-plugin/LICENSE deleted file mode 100644 index 5d273303..00000000 --- a/pack/kite/start/vim-plugin/LICENSE +++ /dev/null @@ -1,4 +0,0 @@ -Copyright (c) 2017 Manhattan Engineering, Inc - All Rights Reserved - -Reproduction of this material is strictly forbidden unless prior written -permission is obtained from Manhattan Engineering, Inc. diff --git a/pack/kite/start/vim-plugin/autoload/kite/docs.vim b/pack/kite/start/vim-plugin/autoload/kite/docs.vim deleted file mode 100644 index 8557df7c..00000000 --- a/pack/kite/start/vim-plugin/autoload/kite/docs.vim +++ /dev/null @@ -1,24 +0,0 @@ -function! kite#docs#docs() - if &filetype != 'python' - call kite#utils#warn('Docs are only available for Python') - return - endif - - if empty(expand('')) | return | endif - - let b:kite_id = '' - - call kite#hover#hover() - - while b:kite_id == '' - sleep 5m - endwhile - - if b:kite_id == -1 - call kite#utils#info('No documentation available.') - return - endif - - call kite#client#docs(b:kite_id) -endfunction - diff --git a/pack/kite/start/vim-plugin/autoload/kite/events.vim b/pack/kite/start/vim-plugin/autoload/kite/events.vim deleted file mode 100644 index a6628845..00000000 --- a/pack/kite/start/vim-plugin/autoload/kite/events.vim +++ /dev/null @@ -1,46 +0,0 @@ -let s:events_pending = 0 - -function! kite#events#any_events_pending() - return s:events_pending > 0 -endfunction - - -function! kite#events#event(action) - let filename = kite#utils#filepath(0) - - if wordcount().bytes < kite#max_file_size() - let action = a:action - let text = kite#utils#buffer_contents() - else - let action = 'skip' - let text = '' - endif - - let [sel_start, sel_end] = kite#utils#selected_region_characters() - if [sel_start, sel_end] == [-1, -1] - return - endif - let selections = [{ 'start': sel_start, 'end': sel_end, 'encoding': 'utf-32' }] - - let json = json_encode({ - \ 'source': 'vim', - \ 'filename': filename, - \ 'text': text, - \ 'action': action, - \ 'selections': selections, - \ 'editor_version': kite#utils#vim_version(), - \ 'plugin_version': kite#utils#plugin_version() - \ }) - - let s:events_pending += 1 - - call kite#client#post_event(json, function('kite#events#handler', [bufnr('')])) -endfunction - - -function! kite#events#handler(bufnr, response) - let s:events_pending -= 1 - - call setbufvar(a:bufnr, 'kite_skip', (a:response.status == 0 || a:response.status == 403)) -endfunction - diff --git a/pack/kite/start/vim-plugin/autoload/kite/languages.vim b/pack/kite/start/vim-plugin/autoload/kite/languages.vim deleted file mode 100644 index dedf7cb7..00000000 --- a/pack/kite/start/vim-plugin/autoload/kite/languages.vim +++ /dev/null @@ -1,65 +0,0 @@ -let s:languages_supported_by_kited = [] - -" Returns true if we want Kite completions for the current buffer, false otherwise. -function! kite#languages#supported_by_plugin() - " Return false if the file extension is not recognised by kited. - let recognised_extensions = [ - \ 'c', - \ 'cc', - \ 'cpp', - \ 'cs', - \ 'css', - \ 'go', - \ 'h', - \ 'hpp', - \ 'html', - \ 'java', - \ 'js', - \ 'jsx', - \ 'kt', - \ 'less', - \ 'm', - \ 'php', - \ 'py', - \ 'pyw', - \ 'rb', - \ 'scala', - \ 'sh', - \ 'ts', - \ 'tsx', - \ 'vue', - \ ] - if index(recognised_extensions, expand('%:e')) == -1 - return 0 - endif - - if g:kite_supported_languages == ['*'] - return 1 - endif - - " Return false if the buffer's language is not one for which we want Kite completions. - if index(g:kite_supported_languages, &filetype) == -1 - return 0 - endif - - return 1 -endfunction - - -" Returns true if the current buffer's language is supported by kited, false otherwise. -function! kite#languages#supported_by_kited() - " Only check kited's languages once. - if empty(s:languages_supported_by_kited) - " A list of language names, e.g. ['bash', 'c', 'javascript', 'ruby', ...] - let s:languages_supported_by_kited = kite#client#languages(function('kite#languages#handler')) - endif - - return index(s:languages_supported_by_kited, &filetype) != -1 -endfunction - - -function! kite#languages#handler(response) - if a:response.status != 200 | return [] | endif - - return json_decode(a:response.body) -endfunction diff --git a/pack/kite/start/vim-plugin/autoload/kite/signature.vim b/pack/kite/start/vim-plugin/autoload/kite/signature.vim deleted file mode 100644 index c9a08720..00000000 --- a/pack/kite/start/vim-plugin/autoload/kite/signature.vim +++ /dev/null @@ -1,209 +0,0 @@ -let s:completion_counter = 0 - -function! kite#signature#increment_completion_counter() - let s:completion_counter = s:completion_counter + 1 -endfunction - -function! kite#signature#completion_counter() - return s:completion_counter -endfunction - - -function! kite#signature#handler(counter, startcol, response) abort - call kite#utils#log('signature: '.a:response.status) - - " Ignore old completion results. - if a:counter != s:completion_counter - return - endif - - if a:response.status != 200 - return - endif - - let json = json_decode(a:response.body) - let call = g:kite#document#Document.New(json.calls[0]) - - let function_name = call.dig('func_name', '') - if empty(function_name) - let function_name = call.dig('callee.repr', '') - endif - let function_name = split(function_name, '\.')[-1] - - let spacer = {'word': '', 'empty': 1, 'dup': 1} - let indent = ' ' - let completions = [] - let wrap_width = 50 - - - " - " Signature - " - let parameters = [] - let return_type = '' - let [current_arg, in_kwargs] = [call.dig('arg_index', 0), call.dig('language_details.python.in_kwargs', 0)] - let kind = call.dig('callee.kind', '') - - " 1. Name of function with parameters. - if kind ==# 'function' - " 1.b.1. Parameters - for parameter in call.dig('callee.details.function.parameters', []) - " 1.b.1.a. Name - let name = parameter.name - " 1.b.1.b. Default value - if kite#utils#present(parameter.language_details.python, 'default_value') - let name .= '='.parameter.language_details.python.default_value[0].repr - endif - " 2. Highlight current argument - if !in_kwargs && len(parameters) == current_arg - let name = '*'.name.'*' - endif - call add(parameters, name) - endfor - " 1.b.2. vararg indicator - let vararg = call.dig('callee.details.function.language_details.python.vararg', {}) - if !empty(vararg) - call add(parameters, '*'.vararg.name) - endif - " 1.b.3. keyword arguments indicator - let kwarg = call.dig('callee.details.function.language_details.python.kwarg', {}) - if !empty(kwarg) - call add(parameters, '**'.kwarg.name) - endif - " 1.b.4. Return type - let return_value = call.dig('callee.details.function.return_value', []) - if !empty(return_value) - let return_type = ' -> '.return_value[0].type - endif - - elseif kind ==# 'type' - " 1.c.1. Parameters - for parameter in call.dig('callee.details.type.language_details.python.constructor.parameters', []) - " 1.c.1.a. Name - let name = parameter.name - " 1.c.1.b. Default value - if kite#utils#present(parameter.language_details.python, 'default_value') - let name .= '='.parameter.language_details.python.default_value[0].repr - endif - " 2. Highlight current argument - if !in_kwargs && len(parameters) == current_arg - let name = '*'.name.'*' - endif - call add(parameters, name) - endfor - " 1.c.2. vararg indicator - let vararg = call.dig('callee.details.type.language_details.python.constructor.language_details.python.vararg', {}) - if !empty(vararg) - call add(parameters, '*'.vararg.name) - endif - " 1.c.3. keyword arguments indicator - let kwarg = call.dig('callee.details.type.language_details.python.constructor.language_details.python.kwarg', {}) - if !empty(kwarg) - call add(parameters, '*'.kwarg.name) - endif - " 1.c.4. Return type - let return_type = ' -> '.function_name - endif - - " The completion popup does not wrap long lines so we wrap manually. - for line in kite#utils#wrap(kite#symbol().' '.function_name.'('.join(parameters, ', ').')'.return_type, wrap_width, 4) - let completion = { - \ 'word': '', - \ 'abbr': line, - \ 'empty': 1, - \ 'dup': 1 - \ } - call add(completions, completion) - endfor - - - " 3. Keyword arguments - let kwarg_parameters = call.dig('callee.details.function.kwarg_parameters', []) - if !empty(kwarg_parameters) - call add(completions, spacer) - call add(completions, s:heading('**kw')) - - for kwarg in kwarg_parameters - let name = kwarg.name - let types = kite#utils#map_join(kwarg.inferred_value, 'repr', '|') - if empty(types) - let types = '' - endif - - call add(completions, { - \ 'word': name.'=', - \ 'abbr': indent.name, - \ 'menu': types, - \ 'empty': 1, - \ 'dup': 1 - \ }) - endfor - endif - - - " 4. Popular patterns - if kite#signature#should_show_popular_patterns() - let signatures = call.dig('signatures', []) - if len(signatures) > 0 - call add(completions, spacer) - call add(completions, s:heading('How Others Used This')) - endif - - for signature in signatures - let sigdoc = g:kite#document#Document.New(signature) - - " b. Arguments - let arguments = [] - for arg in sigdoc.dig('args', []) - call add(arguments, arg.name) - endfor - - " c. Keyword arguments - for kwarg in sigdoc.dig('language_details.python.kwargs', []) - let name = kwarg.name - let examples = kite#utils#coerce(kwarg.types[0], 'examples', []) - if len(examples) > 0 - let name .= '='.examples[0] - endif - call add(arguments, name) - endfor - - - for line in kite#utils#wrap(function_name.'('.join(arguments, ', ').')', wrap_width, 2) - let completion = { - \ 'word': '', - \ 'abbr': indent.line, - \ 'empty': 1, - \ 'equal': 1, - \ 'dup': 1 - \ } - call add(completions, completion) - endfor - endfor - endif - - if mode(1) ==# 'i' - call complete(a:startcol+1, completions) - endif -endfunction - - -function! kite#signature#should_show_popular_patterns() - return kite#utils#get_setting('show_popular_patterns', 0) -endfunction - - - -function! kite#signature#show_popular_patterns() - call kite#utils#set_setting('show_popular_patterns', 1) -endfunction - - -function! kite#signature#hide_popular_patterns() - call kite#utils#set_setting('show_popular_patterns', 0) -endfunction - - -function s:heading(text) - return {'abbr': a:text.':', 'word': '', 'empty': 1, 'dup': 1} -endfunction diff --git a/pack/kite/start/vim-plugin/autoload/kite/snippet.vim b/pack/kite/start/vim-plugin/autoload/kite/snippet.vim deleted file mode 100644 index a327228b..00000000 --- a/pack/kite/start/vim-plugin/autoload/kite/snippet.vim +++ /dev/null @@ -1,413 +0,0 @@ -function! s:setup_stack() - if exists('b:kite_stack') | return | endif - - " stack: - " [ - " { index: 0, placeholders: { ... } }, <-- depth 0 - " { index: 0, placeholders: { ... } }, <-- depth 1 - " ... <-- depth n - " ] - " - " index - the currently active placeholder at that depth - let b:kite_stack = {'stack': []} - - function! b:kite_stack.pop() - return remove(self.stack, -1) - endfunction - - function! b:kite_stack.peek() - return get(self.stack, -1) - endfunction - - function! b:kite_stack.push(item) - call add(self.stack, a:item) - endfunction - - function! b:kite_stack.is_empty() - return empty(self.stack) - endfunction - - function! b:kite_stack.empty() - let self.stack = [] - endfunction -endfunction - - -function! kite#snippet#complete_done() - if empty(v:completed_item) | return | endif - call s:setup_stack() - - if has_key(v:completed_item, 'user_data') && !empty(v:completed_item.user_data) - let placeholders = json_decode(v:completed_item.user_data).placeholders - elseif exists('b:kite_completions') && has_key(b:kite_completions, v:completed_item.word) - let placeholders = json_decode(b:kite_completions[v:completed_item.word]).placeholders - let b:kite_completions = {} - else - return - endif - - " Send the edit event. Normally this is sent automatically on TextChanged(I). - " But for some reason this doesn't fire when a completion has a snippet placeholder. - call kite#events#event('edit') - - if empty(placeholders) - if b:kite_stack.is_empty() - return - else - call kite#snippet#next_placeholder() - return - endif - endif - - let b:kite_linenr = line('.') - let b:kite_line_length = col('$') - - call s:setup_maps() - call s:setup_autocmds() - - " Calculate column number (col_begin) of start of each placeholder, and placeholder length. - let inserted_text = v:completed_item.word - let insertion_start = col('.') - strdisplaywidth(inserted_text) - let b:kite_insertion_end = col('.') - - for ph in placeholders - let ph.col_begin = insertion_start + ph.begin - let ph.length = ph.end - ph.begin - unlet ph.begin ph.end - endfor - - " Update placeholder locations. - " - " todo move this into the push() function? - " note this is very similar to s:update_placeholder_locations() - if !b:kite_stack.is_empty() - " current placeholder which has just been completed - let level = b:kite_stack.peek() - let ph = level.placeholders[level.index] - let ph_new_length = col('.') - ph.col_begin - let ph_length_delta = ph_new_length - ph.length - let ph.length = ph_new_length - let marker = ph.col_begin - - " following placeholders at same level - for ph in level.placeholders[level.index+1:] - let ph.col_begin += ph_length_delta - endfor - - " placeholders at outer levels - for level in b:kite_stack.stack[:-2] - for ph in level.placeholders - if ph.col_begin > marker - let ph.col_begin += ph_length_delta - endif - endfor - endfor - endif - - call b:kite_stack.push({'placeholders': placeholders, 'index': 0}) - - " Move to first placeholder. - call s:placeholder(0) -endfunction - - -" Go to next placeholder at current level, if there is one, or first placeholder at next level otherwise. -function! kite#snippet#next_placeholder() - call s:update_placeholder_locations() - call s:placeholder(b:kite_stack.peek().index + 1) -endfunction - - - -function! kite#snippet#previous_placeholder(...) - call s:placeholder(b:kite_stack.peek().index - 1 - (a:0 ? a:1 : 0)) -endfunction - - -" Move to the placeholder at index and select its text. -function! s:placeholder(index) - let index = a:index - - let level = b:kite_stack.peek() - let placeholders = level.placeholders - - " Clear highlights before we pop the stack. - call s:clear_all_placeholder_highlights() - - if index < 0 - " If no other levels in stack - if len(b:kite_stack.stack) == 1 - " Stay with first placeholder and proceed - let index = 0 - else - call b:kite_stack.pop() - call s:placeholder(b:kite_stack.peek().index - 1) - return - endif - endif - - " if navigating forward from last placeholder of current level - if index == len(placeholders) - " If no other levels in stack - if len(b:kite_stack.stack) == 1 - call s:goto_initial_completion_end() - else - call b:kite_stack.pop() - call s:placeholder(b:kite_stack.peek().index + 1) - endif - return - endif - - call s:highlight_current_level_placeholders() - - let level.index = index - let ph = placeholders[index] - - " store line length before placeholder gets changed by user - " let b:kite_line_length = col('$') - - if ph.length == 0 - normal! h - return - endif - - " insert mode -> normal mode - stopinsert - - let linenr = line('.') - call setpos("'<", [0, linenr, ph.col_begin]) - call setpos("'>", [0, linenr, ph.col_begin + ph.length - (mode() == 'n' ? 1 : 0)]) - " normal mode -> visual mode -> select mode - execute "normal! gv\" - if mode() ==# 'S' - execute "normal! \gh" - endif -endfunction - - -function! s:goto_initial_completion_end() - " call setpos('.', [0, b:kite_linenr, b:kite_insertion_end + col('$') - b:kite_line_length - 1]) - call setpos('.', [0, b:kite_linenr, col('$')]) - startinsert! - call s:teardown() -endfunction - - -" Adjust current and subsequent placeholders for the amount of text entered -" at the placeholder we are leaving. -function! s:update_placeholder_locations() - if !exists('b:kite_line_length') | return | endif - - let line_length_delta = col('$') - b:kite_line_length - - " current placeholder - let level = b:kite_stack.peek() - let ph = level.placeholders[level.index] - let marker = ph.col_begin - let ph.length += line_length_delta - - " subsequent placeholders at current level - for ph in level.placeholders[level.index+1:] - let ph.col_begin += line_length_delta - endfor - - " placeholders at outer levels - for level in b:kite_stack.stack[:-2] - for ph in level.placeholders - if ph.col_begin > marker - let ph.col_begin += line_length_delta - endif - endfor - endfor - - let b:kite_line_length = col('$') -endfunction - - -function! s:highlight_current_level_placeholders() - let group = s:highlight_group_for_placeholders() - if empty(group) | return | endif - - let linenr = line('.') - for ph in b:kite_stack.peek().placeholders - let ph.matchid = matchaddpos(group, [[linenr, ph.col_begin, ph.length]]) - endfor -endfunction - - -" Clears highlights of placeholders in the stack. -" -" Note: if we need a way to clear highlights of placeholders which are no -" longer in the stack (because they have been popped) we could use a custom -" highlight group (e.g. KiteUnderline linked to Underline), call getmatches(), -" and remove all matches using the custom highlight group. -function! s:clear_all_placeholder_highlights() - for level in b:kite_stack.stack - for ph in level.placeholders - if has_key(ph, 'matchid') - call matchdelete(ph.matchid) - unlet ph.matchid - endif - endfor - endfor -endfunction - - -" Many plugins use vmap for visual-mode mappings but vmap maps both -" visual-mode and select-mode (they should use xmap instead). Assume any -" visual-mode mappings for printable characters are not wanted and remove them -" (but remember them so we can restore them afterwards). Similarly for map. -" Assume any select-only-mode maps are deliberate. -" -" :help mapmode-s -" :help Select-mode-mapping -function! s:remove_smaps_for_printable_characters() - let b:kite_maps = [] - let printable_keycodes = [ - \ '', - \ '', - \ '', - \ '', - \ '', - \ '', - \ '', - \ '', - \ '' - \ ] - - " Get a list of maps active in select mode. - for scope in ['', ''] - redir => maps | silent execute 'smap' scope | redir END - - let mappings = split(maps, "\n") - - " 'No mapping found' or localised equivalent (starts with capital letter). - if len(mappings) == 1 && mappings[0][0] =~ '\u' | continue | endif - - " Assume select-mode maps are deliberate and ignore them. - call filter(mappings, 'v:val[0:2] !~# "s"') - - for mapping in mappings - let lhs = matchlist(mapping, '\v^...(\S+)\s.*')[1] - " ^^^ ^^^ - " mode lhs - - " Ignore keycodes for non-printable characters, e.g. - if lhs[0] == '<' && index(printable_keycodes, lhs) == -1 | continue | endif - - " Remember the mapping so we can restore it later. - call add(b:kite_maps, maparg(lhs, 's', 0, 1)) - - " Remove the mapping. - silent! execute 'sunmap' scope lhs - endfor - endfor -endfunction - - -function! s:restore_smaps() - for mapping in b:kite_maps - silent! execute mapping.mode . (mapping.noremap ? 'nore' : '') . 'map ' - \ . (mapping.buffer ? ' ' : '') - \ . (mapping.expr ? ' ' : '') - \ . (mapping.nowait ? ' ' : '') - \ . (mapping.silent ? ' ' : '') - \ . mapping.lhs . ' ' - \ . substitute(mapping.rhs, '', ''.mapping.sid.'_', 'g') - endfor - - unlet! b:kite_maps -endfunction - - -function! s:setup_maps() - execute 'inoremap ' g:kite_next_placeholder 'pumvisible() ? "" : ":call kite#snippet#next_placeholder()"' - execute 'inoremap ' g:kite_previous_placeholder 'pumvisible() ? ":call kite#snippet#previous_placeholder(2)" : ":call kite#snippet#previous_placeholder()"' - execute 'snoremap ' g:kite_next_placeholder ':call kite#snippet#next_placeholder()' - execute 'snoremap ' g:kite_previous_placeholder ':call kite#snippet#previous_placeholder()' - - call s:remove_smaps_for_printable_characters() -endfunction - - -function! kite#snippet#teardown_maps() - execute 'silent! iunmap ' g:kite_next_placeholder - execute 'silent! iunmap ' g:kite_previous_placeholder - execute 'silent! sunmap ' g:kite_next_placeholder - execute 'silent! sunmap ' g:kite_previous_placeholder -endfunction - - -function! s:setup_autocmds() - augroup KiteSnippets - autocmd! * - - autocmd CursorMovedI - \ call s:update_placeholder_locations() | - \ call s:clear_all_placeholder_highlights() | - \ call s:highlight_current_level_placeholders() - autocmd CursorMoved,CursorMovedI call s:cursormoved() - autocmd InsertLeave call s:insertleave() - augroup END -endfunction - - -function! s:teardown_autocmds() - autocmd! KiteSnippets * -endfunction - - -" Called to deactivate all placeholders. -function! s:teardown() - call s:clear_all_placeholder_highlights() - call kite#snippet#teardown_maps() - call s:teardown_autocmds() - call s:restore_smaps() - call b:kite_stack.empty() - unlet! b:kite_linenr b:kite_line_length b:kite_insertion_end -endfunction - - -function! s:highlight_group_for_placeholders() - for group in ['Special', 'SpecialKey', 'Underline', 'DiffChange'] - if hlexists(group) - return group - endif - endfor - return '' -endfunction - - -function! s:cursormoved() - if !exists('b:kite_linenr') | return | endif - if b:kite_linenr == line('.') | return | endif - - " TODO check whether the cursor is outside the bounds of the completion? - - call s:teardown() -endfunction - - -function! s:insertleave() - " Modes established by experimentation. - if mode(1) !=# 's' && mode(1) !=# ((has('patch-8.1.0225') || has('nvim-0.4.0')) ? 'niI' : 'n') - call s:teardown() - endif -endfunction - - -function! s:debug_stack() - if b:kite_stack.is_empty() - echom 'stack empty' - return - endif - let i = 0 - for level in b:kite_stack.stack - echom 'level' i - echom ' index' level.index - for pholder in level.placeholders - echom ' '.string(pholder) - endfor - let i += 1 - endfor -endfunction diff --git a/pack/kite/start/vim-plugin/autoload/kite/status.vim b/pack/kite/start/vim-plugin/autoload/kite/status.vim deleted file mode 100644 index 202c6c5f..00000000 --- a/pack/kite/start/vim-plugin/autoload/kite/status.vim +++ /dev/null @@ -1,62 +0,0 @@ -" Updates the status of the current buffer. -" -" Optional argument is a timer id (when called by a timer). -function! kite#status#status(...) - if !s:status_in_status_line() | return | endif - - let buf = bufnr('') - let msg = 'NOT SET' - - " Check kited status (installed / running) every 10 file status checks. - let counter = getbufvar(buf, 'kite_status_counter', 0) - if counter == 0 - if !kite#utils#kite_running() - let msg = 'Kite: not running' - if !kite#utils#kite_installed() - let msg = 'Kite: not installed' - endif - endif - endif - call setbufvar(buf, 'kite_status_counter', (counter + 1) % 10) - - if wordcount().bytes > kite#max_file_size() - let msg = 'Kite: file too large' - endif - - if msg !=# 'NOT SET' - if msg !=# getbufvar(buf, 'kite_status') - call setbufvar(buf, 'kite_status', msg) - redrawstatus - endif - return - endif - - let filename = kite#utils#filepath(0) - call kite#client#status(filename, function('kite#status#handler', [buf])) -endfunction - - -function! kite#status#handler(buffer, response) - call kite#utils#log('kite status status: '.a:response.status.', body: '.a:response.body) - if a:response.status != 200 | return | endif - - let json = json_decode(a:response.body) - - let msg = '' - - let suffix = get(json, 'short', 'FIELD MISSING') - if suffix !=# 'FIELD MISSING' - let msg = join(['Kite: ', suffix], '') - endif - - if msg !=# getbufvar(a:buffer, 'kite_status') - call setbufvar(a:buffer, 'kite_status', msg) - redrawstatus - endif -endfunction - - -function! s:status_in_status_line() - return stridx(&statusline, 'kite#statusline()') != -1 -endfunction - diff --git a/pack/kite/start/vim-plugin/doc/kite.txt b/pack/kite/start/vim-plugin/doc/kite.txt deleted file mode 100644 index 7b6d8eb2..00000000 --- a/pack/kite/start/vim-plugin/doc/kite.txt +++ /dev/null @@ -1,35 +0,0 @@ -*kite.txt* Kite for VIM - - -Kite for VIM -============ - -VIM is now integrated with Kite! To get a taste of what Kite can do, open a -saved Python file and start coding away. - -1. Autocompletions - -As you code, Kite will provide autocompletion suggestions ranked by popularity -using all the open source code on GitHub. - -2. Documentation - -Press |K| when your cursor is over a identifier to open a split window with -documentation about the identifier. In addition to documentation, Kite also -provides information about where you've used the identifier in your codebase, -as well as curated code examples showing you how to use the identifier. - -3. Goto Definition - -Press |C-]| to jump to a method's defintion. - -4. Copilot integration - -While you code in VIM, the Copilot will automatically show you information -about the code that you're currently working with. To open the Copilot, click -on the Kite menubar icon and select "Open Copilot". - -To learn more about Kite and how to use the VIM plugin, visit our [help -page](http://help.kite.com). - - vim:tw=78:et:ft=help:norl