mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 02:34:59 -07:00
Compare commits
189 Commits
772ecd9ead
...
045b1d7f90
Author | SHA1 | Date | |
---|---|---|---|
|
045b1d7f90 | ||
|
e340b4e113 | ||
|
f7890bb005 | ||
|
4c346f677e | ||
|
51c380238c | ||
|
b7da54aa9e | ||
|
2f7b385f2e | ||
|
c830901e8c | ||
|
0dd933265f | ||
|
df367cf91c | ||
|
6bf2a6fc5b | ||
|
b03e790cdd | ||
|
15153c4cd5 | ||
|
137308a3c9 | ||
|
7d082d4816 | ||
|
59f38ef3c4 | ||
|
98e3610316 | ||
|
022449b522 | ||
|
fb8372adb3 | ||
|
47f2769b46 | ||
|
b5c0290803 | ||
|
6c975515c5 | ||
|
798f928479 | ||
|
167a2383b9 | ||
|
2d6f57b289 | ||
|
9c6a3703bb | ||
|
01a97d2ad7 | ||
|
cc38630d39 | ||
|
6c2c77b128 | ||
|
820984daea | ||
|
852b6a6bce | ||
|
805b84c619 | ||
|
3406b00911 | ||
|
caa93b5e1e | ||
|
433b342baa | ||
|
f9dd682621 | ||
|
65b1733405 | ||
|
9c20342297 | ||
|
7940ec6913 | ||
|
c0ae39ee53 | ||
|
1386d36e76 | ||
|
8a0b203875 | ||
|
3e3a984300 | ||
|
2e73ba102a | ||
|
17383870dd | ||
|
de794f2d24 | ||
|
130f4344cf | ||
|
5eda7aafe9 | ||
|
21961967ff | ||
|
442d338cb5 | ||
|
ff1791c9e5 | ||
|
3dfb9e6f60 | ||
|
492ae57aa6 | ||
|
3f1d09bc94 | ||
|
ca760e645b | ||
|
c87ca1e2eb | ||
|
4182e98752 | ||
|
c3899419d4 | ||
|
d1fd674df3 | ||
|
98694c3675 | ||
|
e4bb185441 | ||
|
6c81c16e1b | ||
|
7a7ed0c8ac | ||
|
ac230370f3 | ||
|
2336389d23 | ||
|
4889935a7a | ||
|
1b90f4a9c4 | ||
|
3bb2d02759 | ||
|
30726c778c | ||
|
3d318be8cd | ||
|
d7b3add63e | ||
|
84d9f4f9f9 | ||
|
4bfdd1ee9d | ||
|
ca4f688ad4 | ||
|
fe1e2eff06 | ||
|
7008487b83 | ||
|
bf7e534c88 | ||
|
99a24d511f | ||
|
5549115bee | ||
|
4fcc5cd34a | ||
|
96329910b0 | ||
|
f3fa6507f2 | ||
|
668d2569b4 | ||
|
b52ffd0a59 | ||
|
4817547ec4 | ||
|
92e61072ac | ||
|
c63e49cce2 | ||
|
5c245ec3e9 | ||
|
bdfba8598b | ||
|
c2bf09ddff | ||
|
9c278af7cc | ||
|
ec94c2704f | ||
|
517ecb85f5 | ||
|
fac96b72a5 | ||
|
2550b5e9bd | ||
|
ba7370a902 | ||
|
f0ea38a4bc | ||
|
b8c75a31e6 | ||
|
e8e3b443f8 | ||
|
1077843b9b | ||
|
367182abd5 | ||
|
e788d1a3a9 | ||
|
e9f4ceeb74 | ||
|
c4f76299f0 | ||
|
812d029702 | ||
|
bf5c1346c5 | ||
|
fd902b1cb2 | ||
|
12901447cb | ||
|
fccef5ec35 | ||
|
c57397f981 | ||
|
3abd7ed4a4 | ||
|
845e563421 | ||
|
8323398bc6 | ||
|
6a929b15c9 | ||
|
2f5e7cbac4 | ||
|
540def7d2c | ||
|
5413c6475e | ||
|
8f84167c30 | ||
|
0a15cd2500 | ||
|
52481eecf0 | ||
|
7579af3c51 | ||
|
6586645d78 | ||
|
e2a91876ac | ||
|
6551e30630 | ||
|
734dba04d1 | ||
|
56d11b494b | ||
|
3cb1e825e6 | ||
|
e56437cd48 | ||
|
b079a9d2e7 | ||
|
ae93c7f369 | ||
|
2495e7e22a | ||
|
0e299ebf75 | ||
|
48bdbf12d0 | ||
|
c410375d4d | ||
|
9123bc0f3f | ||
|
25bd2782a5 | ||
|
e5d96a69fd | ||
|
05dd41f3e9 | ||
|
747e84a256 | ||
|
588ca99e12 | ||
|
7a367c6967 | ||
|
3d3a99e69c | ||
|
49d6cd1da8 | ||
|
c7ec010ade | ||
|
9d0117fd30 | ||
|
716adbcc45 | ||
|
c1378413c1 | ||
|
36b714e9b7 | ||
|
6cdcac4492 | ||
|
8de1dc6923 | ||
|
fb689d7ebd | ||
|
feb62d5429 | ||
|
ab9cfc4dc3 | ||
|
9d174a7dac | ||
|
1af1e918d3 | ||
|
d512479115 | ||
|
4426a326e2 | ||
|
fd865fbd92 | ||
|
2833925cfc | ||
|
3056115785 | ||
|
a1e313ded6 | ||
|
c867a4f5e3 | ||
|
e74316bf48 | ||
|
b1c907f219 | ||
|
1536f79d86 | ||
|
27965627a4 | ||
|
cfa8418c21 | ||
|
8d7d225caa | ||
|
731f83ea4a | ||
|
146b8300a1 | ||
|
864f25d6b0 | ||
|
344923fe9a | ||
|
5897994cb7 | ||
|
76dcc7029b | ||
|
203e7a43d1 | ||
|
c24e6e66dd | ||
|
078e8e57d3 | ||
|
d460928263 | ||
|
99b5ffd688 | ||
|
e8450ef236 | ||
|
3d707e6f14 | ||
|
66bb1e577c | ||
|
c644228e1d | ||
|
f81131cca2 | ||
|
29c72cdf4a | ||
|
8d55cc218c | ||
|
99e7323aa3 | ||
|
165b099fa3 | ||
|
a811d4babd |
1
.github/scripts/reviewers_add.js
vendored
1
.github/scripts/reviewers_add.js
vendored
@ -57,7 +57,6 @@ module.exports = async ({ github, context }) => {
|
||||
|
||||
if (labels.includes("lsp")) {
|
||||
reviewers.add("MariaSolOs");
|
||||
reviewers.add("mfussenegger");
|
||||
}
|
||||
|
||||
if (labels.includes("netrw")) {
|
||||
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -89,7 +89,9 @@ jobs:
|
||||
for d in *; do (cd "$d"; rm -rf ./autom4te.cache; make clean || true; make distclean || true); done
|
||||
|
||||
- name: Re-build bundled dependencies with no network access
|
||||
run: unshare --map-root-user --net make deps DEPS_CMAKE_FLAGS=-DUSE_EXISTING_SRC_DIR=ON
|
||||
run: |
|
||||
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
|
||||
unshare --map-root-user --net make deps DEPS_CMAKE_FLAGS=-DUSE_EXISTING_SRC_DIR=ON
|
||||
|
||||
- name: Build
|
||||
run: make CMAKE_FLAGS="-D CI_BUILD=ON"
|
||||
|
21
.github/workflows/test.yml
vendored
21
.github/workflows/test.yml
vendored
@ -106,7 +106,7 @@ jobs:
|
||||
[
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: asan, cc: clang, flags: -D ENABLE_ASAN_UBSAN=ON },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: tsan, cc: clang, flags: -D ENABLE_TSAN=ON },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, cc: gcc },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: release, cc: gcc, flags: -D CMAKE_BUILD_TYPE=Release },
|
||||
{ runner: macos-13, os: macos, flavor: intel, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER },
|
||||
{ runner: macos-15, os: macos, flavor: arm, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: puc-lua, cc: gcc, deps_flags: -D USE_BUNDLED_LUAJIT=OFF -D USE_BUNDLED_LUA=ON, flags: -D PREFER_LUA=ON },
|
||||
@ -145,6 +145,10 @@ jobs:
|
||||
sudo cpanm -n Neovim::Ext || cat "$HOME/.cpanm/build.log"
|
||||
perl -W -e 'use Neovim::Ext; print $Neovim::Ext::VERSION'
|
||||
|
||||
- name: Remove .git directory
|
||||
if: ${{ matrix.build.os == 'ubuntu' }}
|
||||
run: cmake -E rm -rf -- .git
|
||||
|
||||
- name: Build third-party deps
|
||||
run: |
|
||||
cmake -S cmake.deps --preset ci -D CMAKE_BUILD_TYPE=Debug ${{ matrix.build.deps_flags }}
|
||||
@ -155,9 +159,15 @@ jobs:
|
||||
cmake --preset ci -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.build.flags }}
|
||||
cmake --build build
|
||||
|
||||
- name: ${{ matrix.test }}
|
||||
- if: ${{ matrix.test == 'oldtest' }}
|
||||
name: ${{ matrix.test }}
|
||||
timeout-minutes: 20
|
||||
run: make ${{ matrix.test }}
|
||||
run: make -C test/old/testdir NVIM_PRG=$(realpath build)/bin/nvim
|
||||
|
||||
- if: ${{ matrix.test != 'oldtest' }}
|
||||
name: ${{ matrix.test }}
|
||||
timeout-minutes: 20
|
||||
run: cmake --build build --target ${{ matrix.test }}
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
@ -194,7 +204,7 @@ jobs:
|
||||
uses: ./.github/workflows/test_windows.yml
|
||||
|
||||
# This job tests the following things:
|
||||
# - Check if Release, MinSizeRel and RelWithDebInfo compiles correctly.
|
||||
# - Check if MinSizeRel and RelWithDebInfo compiles correctly.
|
||||
# - Test the above build types with the GCC compiler specifically.
|
||||
# Empirically the difference in warning levels between GCC and other
|
||||
# compilers is particularly big.
|
||||
@ -218,9 +228,6 @@ jobs:
|
||||
- name: Configure
|
||||
run: cmake --preset ci -G "Ninja Multi-Config"
|
||||
|
||||
- name: Release
|
||||
run: cmake --build build --config Release
|
||||
|
||||
- name: RelWithDebInfo
|
||||
run: cmake --build build --config RelWithDebInfo
|
||||
|
||||
|
@ -187,6 +187,7 @@ if(NOT PREFER_LUA)
|
||||
find_program(LUA_PRG NAMES luajit)
|
||||
endif()
|
||||
find_program(LUA_PRG NAMES lua5.1 lua5.2 lua)
|
||||
mark_as_advanced(LUA_PRG)
|
||||
if(NOT LUA_PRG)
|
||||
message(FATAL_ERROR "Failed to find a Lua 5.1-compatible interpreter")
|
||||
endif()
|
||||
@ -200,6 +201,7 @@ message(STATUS "Using Lua interpreter: ${LUA_PRG}")
|
||||
if(NOT LUA_GEN_PRG)
|
||||
set(LUA_GEN_PRG "${LUA_PRG}" CACHE FILEPATH "Path to the lua used for code generation.")
|
||||
endif()
|
||||
mark_as_advanced(LUA_GEN_PRG)
|
||||
message(STATUS "Using Lua interpreter for code generation: ${LUA_GEN_PRG}")
|
||||
|
||||
option(COMPILE_LUA "Pre-compile Lua sources into bytecode (for sources that are included in the binary)" ON)
|
||||
@ -219,6 +221,7 @@ if(COMPILE_LUA AND NOT WIN32)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(LUAC_PRG)
|
||||
if(LUAC_PRG)
|
||||
message(STATUS "Using Lua compiler: ${LUAC_PRG}")
|
||||
endif()
|
||||
@ -229,7 +232,9 @@ if(CI_LINT)
|
||||
set(LINT_REQUIRED "REQUIRED")
|
||||
endif()
|
||||
find_program(SHELLCHECK_PRG shellcheck ${LINT_REQUIRED})
|
||||
mark_as_advanced(SHELLCHECK_PRG)
|
||||
find_program(STYLUA_PRG stylua ${LINT_REQUIRED})
|
||||
mark_as_advanced(STYLUA_PRG)
|
||||
|
||||
set(STYLUA_DIRS runtime scripts src test contrib)
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
LIBUV_URL https://github.com/libuv/libuv/archive/v1.49.2.tar.gz
|
||||
LIBUV_SHA256 388ffcf3370d4cf7c4b3a3205504eea06c4be5f9e80d2ab32d19f8235accc1cf
|
||||
|
||||
LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/fe71d0fb54ceadfb5b5f3b6baf29e486d97f6059.tar.gz
|
||||
LUAJIT_SHA256 92325f209b21aaf0a67b099bc73cf9bbac5789a9749bdc3898d4a990abb4f36e
|
||||
LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/f73e649a954b599fc184726c376476e7a5c439ca.tar.gz
|
||||
LUAJIT_SHA256 bc992b3ae0a8f5f0ebbf141626b7c99fac794c94ec6896d973582525c7ef868d
|
||||
|
||||
LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz
|
||||
LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
|
||||
@ -50,8 +50,8 @@ TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/a
|
||||
TREESITTER_QUERY_SHA256 d3a423ab66dc62b2969625e280116678a8a22582b5ff087795222108db2f6a6e
|
||||
TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.3.2.tar.gz
|
||||
TREESITTER_MARKDOWN_SHA256 5dac48a6d971eb545aab665d59a18180d21963afc781bbf40f9077c06cb82ae5
|
||||
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/e3c82633389256ccc2c5ab2e509046cbf20453d3.tar.gz
|
||||
TREESITTER_SHA256 61a21f5d83cfe256472bfa941123a6941fb45073784ee7ec0bc32fdd52f7a4e4
|
||||
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.24.5.tar.gz
|
||||
TREESITTER_SHA256 b5ac48acf5a04fd82ccd4246ad46354d9c434be26c9606233917549711e4252c
|
||||
|
||||
WASMTIME_URL https://github.com/bytecodealliance/wasmtime/archive/v25.0.2.tar.gz
|
||||
WASMTIME_SHA256 6d1c17c756b83f29f629963228e5fa208ba9d6578421ba2cd07132b6a120accb
|
||||
|
@ -19,6 +19,7 @@ if(APPLE)
|
||||
endif()
|
||||
|
||||
find_program(CACHE_PRG NAMES ccache sccache)
|
||||
mark_as_advanced(CACHE_PRG)
|
||||
if(CACHE_PRG)
|
||||
set(CMAKE_C_COMPILER_LAUNCHER ${CMAKE_COMMAND} -E env CCACHE_SLOPPINESS=pch_defines,time_macros ${CACHE_PRG})
|
||||
list(APPEND DEPS_CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER_LAUNCHER:STRING=${CMAKE_C_COMPILER_LAUNCHER})
|
||||
@ -27,6 +28,7 @@ endif()
|
||||
# MAKE_PRG
|
||||
if(UNIX)
|
||||
find_program(MAKE_PRG NAMES gmake make)
|
||||
mark_as_advanced(MAKE_PRG)
|
||||
if(NOT MAKE_PRG)
|
||||
message(FATAL_ERROR "GNU Make is required to build the dependencies.")
|
||||
else()
|
||||
|
@ -167,13 +167,15 @@ function! s:Spawn(server_cmd, client_cmd, server_addr, reconnect)
|
||||
if type(a:server_cmd) == type('')
|
||||
" spawn gdbserver in a vertical split
|
||||
let server = s:GdbServer.new(gdb)
|
||||
vsp | enew | let gdb._server_id = termopen(a:server_cmd, server)
|
||||
server.term = v:true
|
||||
vsp | enew | let gdb._server_id = jobstart(a:server_cmd, server)
|
||||
let gdb._jump_window = 2
|
||||
let gdb._server_buf = bufnr('%')
|
||||
endif
|
||||
" go to the bottom window and spawn gdb client
|
||||
wincmd j
|
||||
enew | let gdb._client_id = termopen(a:client_cmd, gdb)
|
||||
gdb.term = v:true
|
||||
enew | let gdb._client_id = jobstart(a:client_cmd, gdb)
|
||||
let gdb._client_buf = bufnr('%')
|
||||
tnoremap <silent> <f8> <c-\><c-n>:GdbContinue<cr>i
|
||||
tnoremap <silent> <f10> <c-\><c-n>:GdbNext<cr>i
|
||||
|
@ -1,6 +1,6 @@
|
||||
" Vim autoload file for editing compressed files.
|
||||
" Maintainer: The Vim Project <https://github.com/vim/vim>
|
||||
" Last Change: 2023 Aug 10
|
||||
" Last Change: 2024 Nov 25
|
||||
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
|
||||
" These functions are used by the gzip plugin.
|
||||
@ -148,6 +148,9 @@ fun gzip#read(cmd)
|
||||
else
|
||||
let fname = escape(expand("%:r"), " \t\n*?[{`$\\%#'\"|!<")
|
||||
endif
|
||||
if filereadable(undofile(expand("%")))
|
||||
exe "sil rundo " . fnameescape(undofile(expand("%")))
|
||||
endif
|
||||
if &verbose >= 8
|
||||
execute "doau BufReadPost " . fname
|
||||
else
|
||||
|
@ -38,6 +38,9 @@
|
||||
" 2024 Nov 14 by Vim Project: small fixes to netrw#BrowseX (#16056)
|
||||
" 2024 Nov 23 by Vim Project: update decompress defaults (#16104)
|
||||
" 2024 Nov 23 by Vim Project: fix powershell escaping issues (#16094)
|
||||
" 2024 Dec 04 by Vim Project: do not detach for gvim (#16168)
|
||||
" 2024 Dec 08 by Vim Project: check the first arg of netrw_browsex_viewer for being executable (#16185)
|
||||
" 2024 Dec 12 by Vim Project: do not pollute the search history (#16206)
|
||||
" }}}
|
||||
" Former Maintainer: Charles E Campbell
|
||||
" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
|
||||
@ -5040,7 +5043,7 @@ if has('unix')
|
||||
endfun
|
||||
else
|
||||
fun! netrw#Launch(args)
|
||||
exe ':silent ! nohup' a:args s:redir() '&' | redraw!
|
||||
exe ':silent ! nohup' a:args s:redir() (has('gui_running') ? '' : '&') | redraw!
|
||||
endfun
|
||||
endif
|
||||
elseif has('win32')
|
||||
@ -5070,7 +5073,9 @@ elseif executable('open')
|
||||
endif
|
||||
|
||||
fun! s:viewer()
|
||||
if exists('g:netrw_browsex_viewer') && executable(g:netrw_browsex_viewer)
|
||||
" g:netrw_browsex_viewer could be a string of program + its arguments,
|
||||
" test if first argument is executable
|
||||
if exists('g:netrw_browsex_viewer') && executable(split(g:netrw_browsex_viewer)[0])
|
||||
" extract any viewing options. Assumes that they're set apart by spaces.
|
||||
" call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
|
||||
if g:netrw_browsex_viewer =~ '\s'
|
||||
@ -11755,7 +11760,8 @@ endfun
|
||||
" s:ShowLink: used to modify thin and tree listings to show links {{{2
|
||||
fun! s:ShowLink()
|
||||
if exists("b:netrw_curdir")
|
||||
norm! $?\a
|
||||
keepp :norm! $?\a
|
||||
"call histdel("/",-1)
|
||||
if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treetop")
|
||||
let basedir = s:NetrwTreePath(w:netrw_treetop)
|
||||
else
|
||||
|
@ -158,7 +158,7 @@ function! provider#clipboard#Executable() abort
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'termux-clipboard'
|
||||
elseif !empty($TMUX) && executable('tmux')
|
||||
elseif executable('tmux') && (!empty($TMUX) || 0 == jobwait([jobstart(['tmux', 'list-buffers'])], 2000)[0])
|
||||
let tmux_v = v:lua.vim.version.parse(system(['tmux', '-V']))
|
||||
if !empty(tmux_v) && !v:lua.vim.version.lt(tmux_v, [3,2,0])
|
||||
let s:copy['+'] = ['tmux', 'load-buffer', '-w', '-']
|
||||
|
250
runtime/autoload/spotbugs.vim
Normal file
250
runtime/autoload/spotbugs.vim
Normal file
@ -0,0 +1,250 @@
|
||||
" Default pre- and post-compiler actions for SpotBugs
|
||||
" Maintainers: @konfekt and @zzzyxwvut
|
||||
" Last Change: 2024 Nov 27
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
if v:version > 900
|
||||
|
||||
function! spotbugs#DeleteClassFiles() abort
|
||||
if !exists('b:spotbugs_class_files')
|
||||
return
|
||||
endif
|
||||
|
||||
for pathname in b:spotbugs_class_files
|
||||
let classname = pathname =~# "^'.\\+\\.class'$"
|
||||
\ ? eval(pathname)
|
||||
\ : pathname
|
||||
|
||||
if classname =~# '\.class$' && filereadable(classname)
|
||||
" Since v9.0.0795.
|
||||
let octad = readblob(classname, 0, 8)
|
||||
|
||||
" Test the magic number and the major version number (45 for v1.0).
|
||||
" Since v9.0.2027.
|
||||
if len(octad) == 8 && octad[0 : 3] == 0zcafe.babe &&
|
||||
\ or((octad[6] << 8), octad[7]) >= 45
|
||||
echomsg printf('Deleting %s: %d', classname, delete(classname))
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
let b:spotbugs_class_files = []
|
||||
endfunction
|
||||
|
||||
else
|
||||
|
||||
function! s:DeleteClassFilesWithNewLineCodes(classname) abort
|
||||
" The distribution of "0a"s in class file versions 2560 and 2570:
|
||||
"
|
||||
" 0zca.fe.ba.be.00.00.0a.00 0zca.fe.ba.be.00.00.0a.0a
|
||||
" 0zca.fe.ba.be.00.0a.0a.00 0zca.fe.ba.be.00.0a.0a.0a
|
||||
" 0zca.fe.ba.be.0a.00.0a.00 0zca.fe.ba.be.0a.00.0a.0a
|
||||
" 0zca.fe.ba.be.0a.0a.0a.00 0zca.fe.ba.be.0a.0a.0a.0a
|
||||
let numbers = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
let offset = 0
|
||||
let lines = readfile(a:classname, 'b', 4)
|
||||
|
||||
" Track NL byte counts to handle files of less than 8 bytes.
|
||||
let nl_cnt = len(lines)
|
||||
" Track non-NL byte counts for "0zca.fe.ba.be.0a.0a.0a.0a".
|
||||
let non_nl_cnt = 0
|
||||
|
||||
for line in lines
|
||||
for idx in range(strlen(line))
|
||||
" Remap NLs to Nuls.
|
||||
let numbers[offset] = (line[idx] == "\n") ? 0 : char2nr(line[idx]) % 256
|
||||
let non_nl_cnt += 1
|
||||
let offset += 1
|
||||
|
||||
if offset > 7
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
let nl_cnt -= 1
|
||||
|
||||
if offset > 7 || (nl_cnt < 1 && non_nl_cnt > 4)
|
||||
break
|
||||
endif
|
||||
|
||||
" Reclaim NLs.
|
||||
let numbers[offset] = 10
|
||||
let offset += 1
|
||||
|
||||
if offset > 7
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Test the magic number and the major version number (45 for v1.0).
|
||||
if offset > 7 && numbers[0] == 0xca && numbers[1] == 0xfe &&
|
||||
\ numbers[2] == 0xba && numbers[3] == 0xbe &&
|
||||
\ (numbers[6] * 256 + numbers[7]) >= 45
|
||||
echomsg printf('Deleting %s: %d', a:classname, delete(a:classname))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! spotbugs#DeleteClassFiles() abort
|
||||
if !exists('b:spotbugs_class_files')
|
||||
return
|
||||
endif
|
||||
|
||||
let encoding = &encoding
|
||||
|
||||
try
|
||||
set encoding=latin1
|
||||
|
||||
for pathname in b:spotbugs_class_files
|
||||
let classname = pathname =~# "^'.\\+\\.class'$"
|
||||
\ ? eval(pathname)
|
||||
\ : pathname
|
||||
|
||||
if classname =~# '\.class$' && filereadable(classname)
|
||||
let line = get(readfile(classname, 'b', 1), 0, '')
|
||||
let length = strlen(line)
|
||||
|
||||
" Test the magic number and the major version number (45 for v1.0).
|
||||
if length > 3 && line[0 : 3] == "\xca\xfe\xba\xbe"
|
||||
if length > 7 && ((line[6] == "\n" ? 0 : char2nr(line[6]) % 256) * 256 +
|
||||
\ (line[7] == "\n" ? 0 : char2nr(line[7]) % 256)) >= 45
|
||||
echomsg printf('Deleting %s: %d', classname, delete(classname))
|
||||
else
|
||||
call s:DeleteClassFilesWithNewLineCodes(classname)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
finally
|
||||
let &encoding = encoding
|
||||
endtry
|
||||
|
||||
let b:spotbugs_class_files = []
|
||||
endfunction
|
||||
|
||||
endif
|
||||
|
||||
function! spotbugs#DefaultPostCompilerAction() abort
|
||||
" Since v7.4.191.
|
||||
make %:S
|
||||
endfunction
|
||||
|
||||
" Look for "spotbugs#compiler" in "ftplugin/java.vim".
|
||||
let s:compiler = exists('spotbugs#compiler') ? spotbugs#compiler : ''
|
||||
let s:readable = filereadable($VIMRUNTIME . '/compiler/' . s:compiler . '.vim')
|
||||
|
||||
if s:readable && s:compiler ==# 'maven' && executable('mvn')
|
||||
|
||||
function! spotbugs#DefaultPreCompilerAction() abort
|
||||
call spotbugs#DeleteClassFiles()
|
||||
compiler maven
|
||||
make compile
|
||||
endfunction
|
||||
|
||||
function! spotbugs#DefaultPreCompilerTestAction() abort
|
||||
call spotbugs#DeleteClassFiles()
|
||||
compiler maven
|
||||
make test-compile
|
||||
endfunction
|
||||
|
||||
function! spotbugs#DefaultProperties() abort
|
||||
return {
|
||||
\ 'PreCompilerAction':
|
||||
\ function('spotbugs#DefaultPreCompilerAction'),
|
||||
\ 'PreCompilerTestAction':
|
||||
\ function('spotbugs#DefaultPreCompilerTestAction'),
|
||||
\ 'PostCompilerAction':
|
||||
\ function('spotbugs#DefaultPostCompilerAction'),
|
||||
\ 'sourceDirPath': 'src/main/java',
|
||||
\ 'classDirPath': 'target/classes',
|
||||
\ 'testSourceDirPath': 'src/test/java',
|
||||
\ 'testClassDirPath': 'target/test-classes',
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
unlet s:readable s:compiler
|
||||
elseif s:readable && s:compiler ==# 'ant' && executable('ant')
|
||||
|
||||
function! spotbugs#DefaultPreCompilerAction() abort
|
||||
call spotbugs#DeleteClassFiles()
|
||||
compiler ant
|
||||
make compile
|
||||
endfunction
|
||||
|
||||
function! spotbugs#DefaultPreCompilerTestAction() abort
|
||||
call spotbugs#DeleteClassFiles()
|
||||
compiler ant
|
||||
make compile-test
|
||||
endfunction
|
||||
|
||||
function! spotbugs#DefaultProperties() abort
|
||||
return {
|
||||
\ 'PreCompilerAction':
|
||||
\ function('spotbugs#DefaultPreCompilerAction'),
|
||||
\ 'PreCompilerTestAction':
|
||||
\ function('spotbugs#DefaultPreCompilerTestAction'),
|
||||
\ 'PostCompilerAction':
|
||||
\ function('spotbugs#DefaultPostCompilerAction'),
|
||||
\ 'sourceDirPath': 'src',
|
||||
\ 'classDirPath': 'build/classes',
|
||||
\ 'testSourceDirPath': 'test',
|
||||
\ 'testClassDirPath': 'build/test/classes',
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
unlet s:readable s:compiler
|
||||
elseif s:readable && s:compiler ==# 'javac' && executable('javac')
|
||||
|
||||
function! spotbugs#DefaultPreCompilerAction() abort
|
||||
call spotbugs#DeleteClassFiles()
|
||||
compiler javac
|
||||
|
||||
if get(b:, 'javac_makeprg_params', get(g:, 'javac_makeprg_params', '')) =~ '\s@\S'
|
||||
" Read options and filenames from @options [@sources ...].
|
||||
make
|
||||
else
|
||||
" Let Javac figure out what files to compile.
|
||||
execute 'make ' . join(map(filter(copy(v:argv),
|
||||
\ "v:val =~# '\\.java\\=$'"),
|
||||
\ 'shellescape(v:val)'), ' ')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! spotbugs#DefaultPreCompilerTestAction() abort
|
||||
call spotbugs#DefaultPreCompilerAction()
|
||||
endfunction
|
||||
|
||||
function! spotbugs#DefaultProperties() abort
|
||||
return {
|
||||
\ 'PreCompilerAction':
|
||||
\ function('spotbugs#DefaultPreCompilerAction'),
|
||||
\ 'PreCompilerTestAction':
|
||||
\ function('spotbugs#DefaultPreCompilerTestAction'),
|
||||
\ 'PostCompilerAction':
|
||||
\ function('spotbugs#DefaultPostCompilerAction'),
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
unlet s:readable s:compiler
|
||||
else
|
||||
|
||||
function! spotbugs#DefaultPreCompilerAction() abort
|
||||
echomsg printf('Not supported: "%s"', s:compiler)
|
||||
endfunction
|
||||
|
||||
function! spotbugs#DefaultPreCompilerTestAction() abort
|
||||
call spotbugs#DefaultPreCompilerAction()
|
||||
endfunction
|
||||
|
||||
function! spotbugs#DefaultProperties() abort
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
unlet s:readable
|
||||
endif
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim: set foldmethod=syntax shiftwidth=2 expandtab:
|
@ -1,6 +1,7 @@
|
||||
" Language: Typst
|
||||
" Maintainer: Gregory Anders
|
||||
" Last Change: 2024 Nov 02
|
||||
" Previous Maintainer: Gregory Anders
|
||||
" Maintainer: Luca Saccarola <github.e41mv@aleeas.com>
|
||||
" Last Change: 2024 Dec 09
|
||||
" Based on: https://github.com/kaarmu/typst.vim
|
||||
|
||||
function! typst#indentexpr() abort
|
||||
|
@ -60,6 +60,7 @@ hi('PmenuMatch', { link = 'Pmenu' })
|
||||
hi('PmenuMatchSel', { link = 'PmenuSel' })
|
||||
hi('PmenuExtra', { link = 'Pmenu' })
|
||||
hi('PmenuExtraSel', { link = 'PmenuSel' })
|
||||
hi('ComplMatchIns', { link = 'Normal' })
|
||||
hi('Substitute', { link = 'Search' })
|
||||
hi('Whitespace', { link = 'NonText' })
|
||||
hi('MsgSeparator', { link = 'StatusLine' })
|
||||
|
@ -1,13 +1,12 @@
|
||||
" Vim compiler file
|
||||
" Compiler: ESLint for JavaScript
|
||||
" Maintainer: Romain Lafourcade <romainlafourcade@gmail.com>
|
||||
" Last Change: 2020 August 20
|
||||
" 2024 Apr 03 by The Vim Project (removed :CompilerSet definition)
|
||||
" Last Change: 2024 Nov 30
|
||||
|
||||
if exists("current_compiler")
|
||||
finish
|
||||
endif
|
||||
let current_compiler = "eslint"
|
||||
|
||||
CompilerSet makeprg=npx\ eslint\ --format\ compact
|
||||
CompilerSet errorformat=%f:\ line\ %l\\,\ col\ %c\\,\ %m,%-G%.%#
|
||||
CompilerSet makeprg=npx\ eslint\ --format\ stylish
|
||||
CompilerSet errorformat=%-P%f,\%\\s%#%l:%c\ %#\ %trror\ \ %m,\%\\s%#%l:%c\ %#\ %tarning\ \ %m,\%-Q,\%-G%.%#,
|
||||
|
@ -1,7 +1,7 @@
|
||||
" Vim compiler file
|
||||
" Compiler: Java Development Kit Compiler
|
||||
" Maintainer: Doug Kearns <dougkearns@gmail.com>
|
||||
" Last Change: 2024 Jun 14
|
||||
" Last Change: 2024 Nov 19 (enable local javac_makeprg_params)
|
||||
|
||||
if exists("current_compiler")
|
||||
finish
|
||||
@ -11,11 +11,7 @@ let current_compiler = "javac"
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
if exists("g:javac_makeprg_params")
|
||||
execute $'CompilerSet makeprg=javac\ {escape(g:javac_makeprg_params, ' \|"')}'
|
||||
else
|
||||
CompilerSet makeprg=javac
|
||||
endif
|
||||
execute $'CompilerSet makeprg=javac\ {escape(get(b:, 'javac_makeprg_params', get(g:, 'javac_makeprg_params', '')), ' \|"')}'
|
||||
|
||||
CompilerSet errorformat=%E%f:%l:\ error:\ %m,
|
||||
\%W%f:%l:\ warning:\ %m,
|
||||
|
@ -14,7 +14,7 @@ if exists("current_compiler")
|
||||
endif
|
||||
let current_compiler = "maven"
|
||||
|
||||
CompilerSet makeprg=mvn\ --batch-mode
|
||||
execute $'CompilerSet makeprg=mvn\ --batch-mode\ {escape(get(b:, 'maven_makeprg_params', get(g:, 'maven_makeprg_params', '')), ' \|"')}'
|
||||
|
||||
" Error message for POM
|
||||
CompilerSet errorformat=[FATAL]\ Non-parseable\ POM\ %f:\ %m%\\s%\\+@%.%#line\ %l\\,\ column\ %c%.%#,
|
||||
|
103
runtime/compiler/pytest.vim
Normal file
103
runtime/compiler/pytest.vim
Normal file
@ -0,0 +1,103 @@
|
||||
" Vim compiler file
|
||||
" Compiler: Pytest (Python testing framework)
|
||||
" Maintainer: @Konfekt and @mgedmin
|
||||
" Last Change: 2024 Nov 28
|
||||
|
||||
if exists("current_compiler") | finish | endif
|
||||
let current_compiler = "pytest"
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" CompilerSet makeprg=pytest
|
||||
if has('unix')
|
||||
execute $'CompilerSet makeprg=/usr/bin/env\ PYTHONWARNINGS=ignore\ pytest\ {escape(get(b:, 'pytest_makeprg_params', get(g:, 'pytest_makeprg_params', '--tb=short --quiet')), ' \|"')}'
|
||||
elseif has('win32')
|
||||
execute $'CompilerSet makeprg=set\ PYTHONWARNINGS=ignore\ &&\ pytest\ {escape(get(b:, 'pytest_makeprg_params', get(g:, 'pytest_makeprg_params', '--tb=short --quiet')), ' \|"')}'
|
||||
else
|
||||
CompilerSet makeprg=pytest\ --tb=short\ --quiet
|
||||
execute $'CompilerSet makeprg=pytest\ {escape(get(b:, 'pytest_makeprg_params', get(g:, 'pytest_makeprg_params', '--tb=short --quiet')), ' \|"')}'
|
||||
endif
|
||||
|
||||
" Pytest syntax errors {{{2
|
||||
|
||||
" Reset error format so that sourcing .vimrc again and again doesn't grow it
|
||||
" without bounds
|
||||
setlocal errorformat&
|
||||
|
||||
" For the record, the default errorformat is this:
|
||||
"
|
||||
" %*[^"]"%f"%*\D%l: %m
|
||||
" "%f"%*\D%l: %m
|
||||
" %-G%f:%l: (Each undeclared identifier is reported only once
|
||||
" %-G%f:%l: for each function it appears in.)
|
||||
" %-GIn file included from %f:%l:%c:
|
||||
" %-GIn file included from %f:%l:%c\,
|
||||
" %-GIn file included from %f:%l:%c
|
||||
" %-GIn file included from %f:%l
|
||||
" %-G%*[ ]from %f:%l:%c
|
||||
" %-G%*[ ]from %f:%l:
|
||||
" %-G%*[ ]from %f:%l\,
|
||||
" %-G%*[ ]from %f:%l
|
||||
" %f:%l:%c:%m
|
||||
" %f(%l):%m
|
||||
" %f:%l:%m
|
||||
" "%f"\, line %l%*\D%c%*[^ ] %m
|
||||
" %D%*\a[%*\d]: Entering directory %*[`']%f'
|
||||
" %X%*\a[%*\d]: Leaving directory %*[`']%f'
|
||||
" %D%*\a: Entering directory %*[`']%f'
|
||||
" %X%*\a: Leaving directory %*[`']%f'
|
||||
" %DMaking %*\a in %f
|
||||
" %f|%l| %m
|
||||
"
|
||||
" and sometimes it misfires, so let's fix it up a bit
|
||||
" (TBH I don't even know what compiler produces filename(lineno) so why even
|
||||
" have it?)
|
||||
setlocal errorformat-=%f(%l):%m
|
||||
|
||||
" Sometimes Vim gets confused about ISO-8601 timestamps and thinks they're
|
||||
" filenames; this is a big hammer that ignores anything filename-like on lines
|
||||
" that start with at least two spaces, possibly preceded by a number and
|
||||
" optional punctuation
|
||||
setlocal errorformat^=%+G%\\d%#%.%\\=\ \ %.%#
|
||||
|
||||
" Similar, but when the entire line starts with a date
|
||||
setlocal errorformat^=%+G\\d\\d\\d\\d-\\d\\d-\\d\\d\ \\d\\d:\\d\\d%.%#
|
||||
|
||||
" make: *** [Makefile:14: target] Error 1
|
||||
setlocal errorformat^=%+Gmake:\ ***\ %.%#
|
||||
|
||||
" FAILED tests.py::test_with_params[YYYY-MM-DD:HH:MM:SS] - Exception: bla bla
|
||||
setlocal errorformat^=%+GFAILED\ %.%#
|
||||
|
||||
" AssertionError: assert ...YYYY-MM-DD:HH:MM:SS...
|
||||
setlocal errorformat^=%+GAssertionError:\ %.%#
|
||||
|
||||
" --- /path/to/file:before YYYY-MM-DD HH:MM:SS.ssssss
|
||||
setlocal errorformat^=---%f:%m
|
||||
|
||||
" +++ /path/to/file:before YYYY-MM-DD HH:MM:SS.ssssss
|
||||
setlocal errorformat^=+++%f:%m
|
||||
|
||||
" Sometimes pytest prepends an 'E' marker at the beginning of a traceback line
|
||||
setlocal errorformat+=E\ %#File\ \"%f\"\\,\ line\ %l%.%#
|
||||
|
||||
" Python tracebacks (unittest + doctest output) {{{2
|
||||
|
||||
" This collapses the entire traceback into just the last file+lineno,
|
||||
" which is convenient when you want to jump to the line that failed (and not
|
||||
" the top-level entry point), but it makes it impossible to see the full
|
||||
" traceback, which sucks.
|
||||
""setlocal errorformat+=
|
||||
"" \File\ \"%f\"\\,\ line\ %l%.%#,
|
||||
"" \%C\ %.%#,
|
||||
"" \%-A\ \ File\ \"unittest%.py\"\\,\ line\ %.%#,
|
||||
"" \%-A\ \ File\ \"%f\"\\,\ line\ 0%.%#,
|
||||
"" \%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,
|
||||
"" \%Z%[%^\ ]%\\@=%m
|
||||
setlocal errorformat+=File\ \"%f\"\\,\ line\ %l\\,%#%m
|
||||
|
||||
exe 'CompilerSet errorformat='..escape(&l:errorformat, ' \|"')
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
189
runtime/compiler/spotbugs.vim
Normal file
189
runtime/compiler/spotbugs.vim
Normal file
@ -0,0 +1,189 @@
|
||||
" Vim compiler file
|
||||
" Compiler: Spotbugs (Java static checker; needs javac compiled classes)
|
||||
" Maintainer: @konfekt and @zzzyxwvut
|
||||
" Last Change: 2024 Nov 27
|
||||
|
||||
if exists('g:current_compiler') || bufname() !~# '\.java\=$' || wordcount().chars < 9
|
||||
finish
|
||||
endif
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Unfortunately Spotbugs does not output absolute paths, so you need to
|
||||
" pass the directory of the files being checked as `-sourcepath` parameter.
|
||||
" The regex, auxpath and glob try to include all dependent classes of the
|
||||
" current buffer. See https://github.com/spotbugs/spotbugs/issues/856
|
||||
|
||||
" FIXME: When "search()" is used with the "e" flag, it makes no _further_
|
||||
" progress after claiming an EOL match (i.e. "\_" or "\n", but not "$").
|
||||
" XXX: Omit anonymous class declarations
|
||||
let s:keywords = '\C\<\%(\.\@1<!class\|@\=interface\|enum\|record\|package\)\%(\s\|$\)'
|
||||
let s:type_names = '\C\<\%(\.\@1<!class\|@\=interface\|enum\|record\)\s*\(\K\k*\)\>'
|
||||
" Capture ";" for counting a class file directory (see s:package_dir_heads below)
|
||||
let s:package_names = '\C\<package\s*\(\K\%(\k*\.\=\)\+;\)'
|
||||
let s:package = ''
|
||||
|
||||
if has('syntax') && exists('g:syntax_on') && exists('b:current_syntax') &&
|
||||
\ b:current_syntax == 'java' && hlexists('javaClassDecl')
|
||||
|
||||
function! s:GetDeclaredTypeNames() abort
|
||||
if bufname() =~# '\<\%(module\|package\)-info\.java\=$'
|
||||
return [expand('%:t:r')]
|
||||
endif
|
||||
defer execute('silent! normal! g``')
|
||||
call cursor(1, 1)
|
||||
let type_names = []
|
||||
let lnum = search(s:keywords, 'eW')
|
||||
while lnum > 0
|
||||
let name_attr = synIDattr(synID(lnum, (col('.') - 1), 0), 'name')
|
||||
if name_attr ==# 'javaClassDecl'
|
||||
let tokens = matchlist(getline(lnum)..getline(lnum + 1), s:type_names)
|
||||
if !empty(tokens) | call add(type_names, tokens[1]) | endif
|
||||
elseif name_attr ==# 'javaExternal'
|
||||
let tokens = matchlist(getline(lnum)..getline(lnum + 1), s:package_names)
|
||||
if !empty(tokens) | let s:package = tokens[1] | endif
|
||||
endif
|
||||
let lnum = search(s:keywords, 'eW')
|
||||
endwhile
|
||||
return type_names
|
||||
endfunction
|
||||
|
||||
else
|
||||
function! s:GetDeclaredTypeNames() abort
|
||||
if bufname() =~# '\<\%(module\|package\)-info\.java\=$'
|
||||
return [expand('%:t:r')]
|
||||
endif
|
||||
" Undo the unsetting of &hls, see below
|
||||
if &hls
|
||||
defer execute('set hls')
|
||||
endif
|
||||
" Possibly restore the current values for registers '"' and "y", see below
|
||||
defer call('setreg', ['"', getreg('"'), getregtype('"')])
|
||||
defer call('setreg', ['y', getreg('y'), getregtype('y')])
|
||||
defer execute('silent bwipeout')
|
||||
" Copy buffer contents for modification
|
||||
silent %y y
|
||||
new
|
||||
" Apply ":help scratch-buffer" effects and match "$" in Java (generated)
|
||||
" type names (see s:type_names)
|
||||
setlocal iskeyword+=$ buftype=nofile bufhidden=hide noswapfile nohls
|
||||
0put y
|
||||
" Discard text blocks and strings
|
||||
silent keeppatterns %s/\\\@<!"""\_.\{-}\\\@<!"""\|\\"//ge
|
||||
silent keeppatterns %s/".*"//ge
|
||||
" Discard comments
|
||||
silent keeppatterns %s/\/\/.\+$//ge
|
||||
silent keeppatterns %s/\/\*\_.\{-}\*\///ge
|
||||
call cursor(1, 1)
|
||||
let type_names = []
|
||||
let lnum = search(s:keywords, 'eW')
|
||||
while lnum > 0
|
||||
let line = getline(lnum)
|
||||
if line =~# '\<package\>'
|
||||
let tokens = matchlist(line..getline(lnum + 1), s:package_names)
|
||||
if !empty(tokens) | let s:package = tokens[1] | endif
|
||||
else
|
||||
let tokens = matchlist(line..getline(lnum + 1), s:type_names)
|
||||
if !empty(tokens) | call add(type_names, tokens[1]) | endif
|
||||
endif
|
||||
let lnum = search(s:keywords, 'eW')
|
||||
endwhile
|
||||
return type_names
|
||||
endfunction
|
||||
endif
|
||||
|
||||
if has('win32')
|
||||
|
||||
function! s:GlobClassFiles(src_type_name) abort
|
||||
return glob(a:src_type_name..'$*.class', 1, 1)
|
||||
endfunction
|
||||
|
||||
else
|
||||
function! s:GlobClassFiles(src_type_name) abort
|
||||
return glob(a:src_type_name..'\$*.class', 1, 1)
|
||||
endfunction
|
||||
endif
|
||||
|
||||
if exists('g:spotbugs_properties') &&
|
||||
\ (has_key(g:spotbugs_properties, 'sourceDirPath') &&
|
||||
\ has_key(g:spotbugs_properties, 'classDirPath')) ||
|
||||
\ (has_key(g:spotbugs_properties, 'testSourceDirPath') &&
|
||||
\ has_key(g:spotbugs_properties, 'testClassDirPath'))
|
||||
|
||||
function! s:FindClassFiles(src_type_name) abort
|
||||
let class_files = []
|
||||
" Match pairwise the components of source and class pathnames
|
||||
for [src_dir, bin_dir] in filter([
|
||||
\ [get(g:spotbugs_properties, 'sourceDirPath', ''),
|
||||
\ get(g:spotbugs_properties, 'classDirPath', '')],
|
||||
\ [get(g:spotbugs_properties, 'testSourceDirPath', ''),
|
||||
\ get(g:spotbugs_properties, 'testClassDirPath', '')]],
|
||||
\ '!(empty(v:val[0]) || empty(v:val[1]))')
|
||||
" Since only the rightmost "src" is sought, while there can be any number of
|
||||
" such filenames, no "fnamemodify(a:src_type_name, ':p:s?src?bin?')" is used
|
||||
let tail_idx = strridx(a:src_type_name, src_dir)
|
||||
" No such directory or no such inner type (i.e. without "$")
|
||||
if tail_idx < 0 | continue | endif
|
||||
" Substitute "bin_dir" for the rightmost "src_dir"
|
||||
let candidate_type_name = strpart(a:src_type_name, 0, tail_idx)..
|
||||
\ bin_dir..
|
||||
\ strpart(a:src_type_name, (tail_idx + strlen(src_dir)))
|
||||
for candidate in insert(s:GlobClassFiles(candidate_type_name),
|
||||
\ candidate_type_name..'.class')
|
||||
if filereadable(candidate) | call add(class_files, shellescape(candidate)) | endif
|
||||
endfor
|
||||
if !empty(class_files) | break | endif
|
||||
endfor
|
||||
return class_files
|
||||
endfunction
|
||||
|
||||
else
|
||||
function! s:FindClassFiles(src_type_name) abort
|
||||
let class_files = []
|
||||
for candidate in insert(s:GlobClassFiles(a:src_type_name),
|
||||
\ a:src_type_name..'.class')
|
||||
if filereadable(candidate) | call add(class_files, shellescape(candidate)) | endif
|
||||
endfor
|
||||
return class_files
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:CollectClassFiles() abort
|
||||
" Get a platform-independent pathname prefix, cf. "expand('%:p:h')..'/'"
|
||||
let pathname = expand('%:p')
|
||||
let tail_idx = strridx(pathname, expand('%:t'))
|
||||
let src_pathname = strpart(pathname, 0, tail_idx)
|
||||
let all_class_files = []
|
||||
" Get all type names in the current buffer and let the filename globbing
|
||||
" discover inner type names from arbitrary type names
|
||||
for type_name in s:GetDeclaredTypeNames()
|
||||
call extend(all_class_files, s:FindClassFiles(src_pathname..type_name))
|
||||
endfor
|
||||
return all_class_files
|
||||
endfunction
|
||||
|
||||
" Expose class files for removal etc.
|
||||
let b:spotbugs_class_files = s:CollectClassFiles()
|
||||
let s:package_dir_heads = repeat(':h', (1 + strlen(substitute(s:package, '[^.;]', '', 'g'))))
|
||||
let g:current_compiler = 'spotbugs'
|
||||
" CompilerSet makeprg=spotbugs
|
||||
let &l:makeprg = 'spotbugs'..(has('win32') ? '.bat' : '')..' '..
|
||||
\ get(b:, 'spotbugs_makeprg_params', get(g:, 'spotbugs_makeprg_params', '-workHard -experimental'))..
|
||||
\ ' -textui -emacs -auxclasspath %:p'..s:package_dir_heads..':S -sourcepath %:p'..s:package_dir_heads..':S '..
|
||||
\ join(b:spotbugs_class_files, ' ')
|
||||
" Emacs expects doubled line numbers
|
||||
setlocal errorformat=%f:%l:%*[0-9]\ %m,%f:-%*[0-9]:-%*[0-9]\ %m
|
||||
|
||||
" " This compiler is meant to be used for a single buffer only
|
||||
" exe 'CompilerSet makeprg='..escape(&l:makeprg, ' \|"')
|
||||
" exe 'CompilerSet errorformat='..escape(&l:errorformat, ' \|"')
|
||||
|
||||
delfunction s:CollectClassFiles
|
||||
delfunction s:FindClassFiles
|
||||
delfunction s:GlobClassFiles
|
||||
delfunction s:GetDeclaredTypeNames
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:package_dir_heads s:package s:package_names s:type_names s:keywords s:cpo_save
|
||||
|
||||
" vim: set foldmethod=syntax shiftwidth=2 expandtab:
|
@ -1,7 +1,8 @@
|
||||
" Vim compiler file
|
||||
" Language: Typst
|
||||
" Maintainer: Gregory Anders
|
||||
" Last Change: 2024-07-14
|
||||
" Previous Maintainer: Gregory Anders
|
||||
" Maintainer: Luca Saccarola <github.e41mv@aleeas.com>
|
||||
" Last Change: 2024 Dec 09
|
||||
" Based on: https://github.com/kaarmu/typst.vim
|
||||
|
||||
if exists('current_compiler')
|
||||
|
@ -1114,7 +1114,7 @@ nvim_open_term({buffer}, {opts}) *nvim_open_term()*
|
||||
Open a terminal instance in a buffer
|
||||
|
||||
By default (and currently the only option) the terminal will not be
|
||||
connected to an external process. Instead, input send on the channel will
|
||||
connected to an external process. Instead, input sent on the channel will
|
||||
be echoed directly by the terminal. This is useful to display ANSI
|
||||
terminal sequences returned as part of a rpc message, or similar.
|
||||
|
||||
@ -1125,6 +1125,17 @@ nvim_open_term({buffer}, {opts}) *nvim_open_term()*
|
||||
|nvim_chan_send()| can be called immediately to process sequences in a
|
||||
virtual terminal having the intended size.
|
||||
|
||||
Example: this `TermHl` command can be used to display and highlight raw
|
||||
ANSI termcodes, so you can use Nvim as a "scrollback pager" (for terminals
|
||||
like kitty): *terminal-scrollback-pager* >lua
|
||||
vim.api.nvim_create_user_command('TermHl', function()
|
||||
local b = vim.api.nvim_create_buf(false, true)
|
||||
local chan = vim.api.nvim_open_term(b, {})
|
||||
vim.api.nvim_chan_send(chan, table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), '\n'))
|
||||
vim.api.nvim_win_set_buf(0, b)
|
||||
end, { desc = 'Highlights ANSI termcodes in curbuf' })
|
||||
<
|
||||
|
||||
Attributes: ~
|
||||
not allowed when |textlock| is active
|
||||
|
||||
@ -1636,11 +1647,9 @@ nvim_command({command}) *nvim_command()*
|
||||
|
||||
On execution error: fails with Vimscript error, updates v:errmsg.
|
||||
|
||||
Prefer using |nvim_cmd()| or |nvim_exec2()| over this. To evaluate
|
||||
multiple lines of Vim script or an Ex command directly, use
|
||||
|nvim_exec2()|. To construct an Ex command using a structured format and
|
||||
then execute it, use |nvim_cmd()|. To modify an Ex command before
|
||||
evaluating it, use |nvim_parse_cmd()| in conjunction with |nvim_cmd()|.
|
||||
Prefer |nvim_cmd()| or |nvim_exec2()| instead. To modify an Ex command in
|
||||
a structured way before executing it, modify the result of
|
||||
|nvim_parse_cmd()| then pass it to |nvim_cmd()|.
|
||||
|
||||
Parameters: ~
|
||||
• {command} Ex command string
|
||||
@ -2161,12 +2170,12 @@ nvim_buf_call({buffer}, {fun}) *nvim_buf_call()*
|
||||
This temporarily switches current buffer to "buffer". If the current
|
||||
window already shows "buffer", the window is not switched. If a window
|
||||
inside the current tabpage (including a float) already shows the buffer,
|
||||
then one of these windows will be set as current window temporarily.
|
||||
then one of those windows will be set as current window temporarily.
|
||||
Otherwise a temporary scratch window (called the "autocmd window" for
|
||||
historical reasons) will be used.
|
||||
|
||||
This is useful e.g. to call Vimscript functions that only work with the
|
||||
current buffer/window currently, like |termopen()|.
|
||||
current buffer/window currently, like `jobstart(…, {'term': v:true})`.
|
||||
|
||||
Attributes: ~
|
||||
Lua |vim.api| only
|
||||
@ -3483,9 +3492,9 @@ nvim_create_autocmd({event}, {opts}) *nvim_create_autocmd()*
|
||||
• event: (string) name of the triggered event
|
||||
|autocmd-events|
|
||||
• group: (number|nil) autocommand group id, if any
|
||||
• match: (string) expanded value of <amatch>
|
||||
• buf: (number) expanded value of <abuf>
|
||||
• file: (string) expanded value of <afile>
|
||||
• file: (string) <afile> (not expanded to a full path)
|
||||
• match: (string) <amatch> (expanded to a full path)
|
||||
• buf: (number) <abuf>
|
||||
• data: (any) arbitrary data passed from
|
||||
|nvim_exec_autocmds()| *event-data*
|
||||
• command (string) optional: Vim command to execute on event.
|
||||
|
@ -463,6 +463,10 @@ CompleteDone After Insert mode completion is done. Either
|
||||
|v:completed_item| gives the completed item.
|
||||
|
||||
Sets these |v:event| keys:
|
||||
complete_word The word that was
|
||||
selected, empty if
|
||||
abandoned complete.
|
||||
complete_type |complete_info_mode|
|
||||
reason Reason for completion being
|
||||
done. Can be one of:
|
||||
- "accept": completion was
|
||||
|
233
runtime/doc/builtin.txt
generated
233
runtime/doc/builtin.txt
generated
@ -1305,10 +1305,10 @@ copy({expr}) *copy()*
|
||||
Also see |deepcopy()|.
|
||||
|
||||
Parameters: ~
|
||||
• {expr} (`any`)
|
||||
• {expr} (`T`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`T`)
|
||||
|
||||
cos({expr}) *cos()*
|
||||
Return the cosine of {expr}, measured in radians, as a |Float|.
|
||||
@ -1407,7 +1407,7 @@ ctxset({context} [, {index}]) *ctxset()*
|
||||
• {index} (`integer?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
ctxsize() *ctxsize()*
|
||||
Returns the size of the |context-stack|.
|
||||
@ -1490,11 +1490,11 @@ deepcopy({expr} [, {noref}]) *deepcopy()* *E69
|
||||
Also see |copy()|.
|
||||
|
||||
Parameters: ~
|
||||
• {expr} (`any`)
|
||||
• {expr} (`T`)
|
||||
• {noref} (`boolean?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`T`)
|
||||
|
||||
delete({fname} [, {flags}]) *delete()*
|
||||
Without {flags} or with {flags} empty: Deletes the file by the
|
||||
@ -1618,7 +1618,7 @@ did_filetype() *did_filetype()*
|
||||
file.
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
diff_filler({lnum}) *diff_filler()*
|
||||
Returns the number of filler lines above line {lnum}.
|
||||
@ -1633,7 +1633,7 @@ diff_filler({lnum}) *diff_filler()*
|
||||
• {lnum} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
diff_hlID({lnum}, {col}) *diff_hlID()*
|
||||
Returns the highlight ID for diff mode at line {lnum} column
|
||||
@ -1674,7 +1674,7 @@ digraph_get({chars}) *digraph_get()* *E121
|
||||
• {chars} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
digraph_getlist([{listall}]) *digraph_getlist()*
|
||||
Return a list of digraphs. If the {listall} argument is given
|
||||
@ -1695,7 +1695,7 @@ digraph_getlist([{listall}]) *digraph_getlist()*
|
||||
• {listall} (`boolean?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string[][]`)
|
||||
|
||||
digraph_set({chars}, {digraph}) *digraph_set()*
|
||||
Add digraph {chars} to the list. {chars} must be a string
|
||||
@ -1756,7 +1756,7 @@ empty({expr}) *empty()*
|
||||
• {expr} (`any`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
environ() *environ()*
|
||||
Return all of environment variables as dictionary. You can
|
||||
@ -1783,7 +1783,7 @@ escape({string}, {chars}) *escape()*
|
||||
• {chars} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
eval({string}) *eval()*
|
||||
Evaluate {string} and return the result. Especially useful to
|
||||
@ -2666,7 +2666,7 @@ foreach({expr1}, {expr2}) *foreach()*
|
||||
• {expr2} (`string|function`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string|table`)
|
||||
|
||||
fullcommand({name}) *fullcommand()*
|
||||
Get the full command name from a short abbreviated command
|
||||
@ -2997,10 +2997,10 @@ getbufline({buf}, {lnum} [, {end}]) *getbufline()*
|
||||
Parameters: ~
|
||||
• {buf} (`integer|string`)
|
||||
• {lnum} (`integer`)
|
||||
• {end_} (`integer?`)
|
||||
• {end} (`integer?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string[]`)
|
||||
|
||||
getbufoneline({buf}, {lnum}) *getbufoneline()*
|
||||
Just like `getbufline()` but only get one line and return it
|
||||
@ -3295,7 +3295,7 @@ getcmdscreenpos() *getcmdscreenpos()*
|
||||
|setcmdline()|.
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
getcmdtype() *getcmdtype()*
|
||||
Return the current command-line type. Possible return values
|
||||
@ -3635,7 +3635,7 @@ getline({lnum} [, {end}]) *getline()*
|
||||
|
||||
Parameters: ~
|
||||
• {lnum} (`integer|string`)
|
||||
• {end_} (`nil|false?`)
|
||||
• {end} (`nil|false?`)
|
||||
|
||||
Return: ~
|
||||
(`string`)
|
||||
@ -4299,7 +4299,7 @@ gettext({text}) *gettext()*
|
||||
• {text} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
getwininfo([{winid}]) *getwininfo()*
|
||||
Returns information about windows as a |List| with Dictionaries.
|
||||
@ -4315,6 +4315,8 @@ getwininfo([{winid}]) *getwininfo()*
|
||||
botline last complete displayed buffer line
|
||||
bufnr number of buffer in the window
|
||||
height window height (excluding winbar)
|
||||
leftcol first column displayed; only used when
|
||||
'wrap' is off
|
||||
loclist 1 if showing a location list
|
||||
quickfix 1 if quickfix or location list window
|
||||
terminal 1 if a terminal window
|
||||
@ -4465,7 +4467,7 @@ glob2regpat({string}) *glob2regpat()*
|
||||
• {string} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
globpath({path}, {expr} [, {nosuf} [, {list} [, {allinks}]]]) *globpath()*
|
||||
Perform glob() for String {expr} on all directories in {path}
|
||||
@ -4822,7 +4824,7 @@ iconv({string}, {from}, {to}) *iconv()*
|
||||
• {to} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
id({expr}) *id()*
|
||||
Returns a |String| which is a unique identifier of the
|
||||
@ -4845,7 +4847,7 @@ id({expr}) *id()*
|
||||
• {expr} (`any`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
indent({lnum}) *indent()*
|
||||
The result is a Number, which is indent of line {lnum} in the
|
||||
@ -4895,7 +4897,7 @@ index({object}, {expr} [, {start} [, {ic}]]) *index()*
|
||||
• {ic} (`boolean?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
indexof({object}, {expr} [, {opts}]) *indexof()*
|
||||
Returns the index of an item in {object} where {expr} is
|
||||
@ -4942,7 +4944,7 @@ indexof({object}, {expr} [, {opts}]) *indexof()*
|
||||
• {opts} (`table?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
input({prompt} [, {text} [, {completion}]]) *input()*
|
||||
|
||||
@ -4952,7 +4954,7 @@ input({prompt} [, {text} [, {completion}]]) *input()*
|
||||
• {completion} (`string?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
input({opts})
|
||||
The result is a String, which is whatever the user typed on
|
||||
@ -5069,7 +5071,7 @@ input({opts})
|
||||
• {opts} (`table`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
inputlist({textlist}) *inputlist()*
|
||||
{textlist} must be a |List| of strings. This |List| is
|
||||
@ -5101,7 +5103,7 @@ inputrestore() *inputrestore()*
|
||||
Returns TRUE when there is nothing to restore, FALSE otherwise.
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
inputsave() *inputsave()*
|
||||
Preserve typeahead (also from mappings) and clear it, so that
|
||||
@ -5112,7 +5114,7 @@ inputsave() *inputsave()*
|
||||
Returns TRUE when out of memory, FALSE otherwise.
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
inputsecret({prompt} [, {text}]) *inputsecret()*
|
||||
This function acts much like the |input()| function with but
|
||||
@ -5130,7 +5132,7 @@ inputsecret({prompt} [, {text}]) *inputsecret()*
|
||||
• {text} (`string?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
insert({object}, {item} [, {idx}]) *insert()*
|
||||
When {object} is a |List| or a |Blob| insert {item} at the start
|
||||
@ -5181,10 +5183,10 @@ invert({expr}) *invert()*
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {expr} (`number`)
|
||||
• {expr} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
isabsolutepath({path}) *isabsolutepath()*
|
||||
The result is a Number, which is |TRUE| when {path} is an
|
||||
@ -5279,7 +5281,7 @@ items({dict}) *items()*
|
||||
the index.
|
||||
|
||||
Parameters: ~
|
||||
• {dict} (`any`)
|
||||
• {dict} (`table`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
@ -5307,7 +5309,7 @@ jobresize({job}, {width}, {height}) *jobresize()*
|
||||
(`any`)
|
||||
|
||||
jobstart({cmd} [, {opts}]) *jobstart()*
|
||||
Note: Prefer |vim.system()| in Lua (unless using the `pty` option).
|
||||
Note: Prefer |vim.system()| in Lua (unless using `rpc`, `pty`, or `term`).
|
||||
|
||||
Spawns {cmd} as a job.
|
||||
If {cmd} is a List it runs directly (no 'shell').
|
||||
@ -5381,6 +5383,10 @@ jobstart({cmd} [, {opts}]) *jobstart()*
|
||||
stdin: (string) Either "pipe" (default) to connect the
|
||||
job's stdin to a channel or "null" to disconnect
|
||||
stdin.
|
||||
term: (boolean) Spawns {cmd} in a new pseudo-terminal session
|
||||
connected to the current (unmodified) buffer. Implies "pty".
|
||||
Default "height" and "width" are set to the current window
|
||||
dimensions. |jobstart()|. Defaults $TERM to "xterm-256color".
|
||||
width: (number) Width of the `pty` terminal.
|
||||
|
||||
{opts} is passed as |self| dictionary to the callback; the
|
||||
@ -5397,7 +5403,7 @@ jobstart({cmd} [, {opts}]) *jobstart()*
|
||||
• {opts} (`table?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
jobstop({id}) *jobstop()*
|
||||
Stop |job-id| {id} by sending SIGTERM to the job process. If
|
||||
@ -5413,7 +5419,7 @@ jobstop({id}) *jobstop()*
|
||||
• {id} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
jobwait({jobs} [, {timeout}]) *jobwait()*
|
||||
Waits for jobs and their |on_exit| handlers to complete.
|
||||
@ -5441,7 +5447,7 @@ jobwait({jobs} [, {timeout}]) *jobwait()*
|
||||
• {timeout} (`integer?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer[]`)
|
||||
|
||||
join({list} [, {sep}]) *join()*
|
||||
Join the items in {list} together into one String.
|
||||
@ -5459,7 +5465,7 @@ join({list} [, {sep}]) *join()*
|
||||
• {sep} (`string?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
json_decode({expr}) *json_decode()*
|
||||
Convert {expr} from JSON object. Accepts |readfile()|-style
|
||||
@ -5498,7 +5504,7 @@ json_encode({expr}) *json_encode()*
|
||||
• {expr} (`any`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
keys({dict}) *keys()*
|
||||
Return a |List| with all the keys of {dict}. The |List| is in
|
||||
@ -5508,7 +5514,7 @@ keys({dict}) *keys()*
|
||||
• {dict} (`table`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string[]`)
|
||||
|
||||
keytrans({string}) *keytrans()*
|
||||
Turn the internal byte representation of keys into a form that
|
||||
@ -5521,7 +5527,7 @@ keytrans({string}) *keytrans()*
|
||||
• {string} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
len({expr}) *len()* *E701*
|
||||
The result is a Number, which is the length of the argument.
|
||||
@ -5535,10 +5541,10 @@ len({expr}) *len()* *E70
|
||||
Otherwise an error is given and returns zero.
|
||||
|
||||
Parameters: ~
|
||||
• {expr} (`any`)
|
||||
• {expr} (`any[]`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
libcall({libname}, {funcname}, {argument}) *libcall()* *E364* *E368*
|
||||
Call function {funcname} in the run-time library {libname}
|
||||
@ -5664,7 +5670,7 @@ lispindent({lnum}) *lispindent()*
|
||||
• {lnum} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
list2blob({list}) *list2blob()*
|
||||
Return a Blob concatenating all the number values in {list}.
|
||||
@ -5680,7 +5686,7 @@ list2blob({list}) *list2blob()*
|
||||
• {list} (`any[]`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
list2str({list} [, {utf8}]) *list2str()*
|
||||
Convert each number in {list} to a character string can
|
||||
@ -5703,14 +5709,14 @@ list2str({list} [, {utf8}]) *list2str()*
|
||||
• {utf8} (`boolean?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
localtime() *localtime()*
|
||||
Return the current time, measured as seconds since 1st Jan
|
||||
1970. See also |strftime()|, |strptime()| and |getftime()|.
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
log({expr}) *log()*
|
||||
Return the natural logarithm (base e) of {expr} as a |Float|.
|
||||
@ -5727,7 +5733,7 @@ log({expr}) *log()*
|
||||
• {expr} (`number`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`number`)
|
||||
|
||||
log10({expr}) *log10()*
|
||||
Return the logarithm of Float {expr} to base 10 as a |Float|.
|
||||
@ -5743,7 +5749,7 @@ log10({expr}) *log10()*
|
||||
• {expr} (`number`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`number`)
|
||||
|
||||
luaeval({expr} [, {expr}]) *luaeval()*
|
||||
Evaluate Lua expression {expr} and return its result converted
|
||||
@ -6290,7 +6296,7 @@ matchbufline({buf}, {pat}, {lnum}, {end}, [, {dict}]) *matchbufline()*
|
||||
• {buf} (`string|integer`)
|
||||
• {pat} (`string`)
|
||||
• {lnum} (`string|integer`)
|
||||
• {end_} (`string|integer`)
|
||||
• {end} (`string|integer`)
|
||||
• {dict} (`table?`)
|
||||
|
||||
Return: ~
|
||||
@ -6565,7 +6571,7 @@ max({expr}) *max()*
|
||||
• {expr} (`any`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`number`)
|
||||
|
||||
menu_get({path} [, {modes}]) *menu_get()*
|
||||
Returns a |List| of |Dictionaries| describing |menus| (defined
|
||||
@ -6712,7 +6718,7 @@ min({expr}) *min()*
|
||||
• {expr} (`any`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`number`)
|
||||
|
||||
mkdir({name} [, {flags} [, {prot}]]) *mkdir()* *E739*
|
||||
Create directory {name}.
|
||||
@ -6760,7 +6766,7 @@ mkdir({name} [, {flags} [, {prot}]]) *mkdir()* *E73
|
||||
• {prot} (`string?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
mode([{expr}]) *mode()*
|
||||
Return a string that indicates the current mode.
|
||||
@ -6935,7 +6941,7 @@ nextnonblank({lnum}) *nextnonblank()*
|
||||
• {lnum} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
nr2char({expr} [, {utf8}]) *nr2char()*
|
||||
Return a string with a single character, which has the number
|
||||
@ -6957,7 +6963,7 @@ nr2char({expr} [, {utf8}]) *nr2char()*
|
||||
• {utf8} (`boolean?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
nvim_...({...}) *nvim_...()* *E5555* *eval-api*
|
||||
Call nvim |api| functions. The type checking of arguments will
|
||||
@ -7014,7 +7020,7 @@ pathshorten({path} [, {len}]) *pathshorten()*
|
||||
• {len} (`integer?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
perleval({expr}) *perleval()*
|
||||
Evaluate |perl| expression {expr} and return its result
|
||||
@ -7054,7 +7060,7 @@ pow({x}, {y}) *pow()*
|
||||
• {y} (`number`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`number`)
|
||||
|
||||
prevnonblank({lnum}) *prevnonblank()*
|
||||
Return the line number of the first line at or above {lnum}
|
||||
@ -7069,7 +7075,7 @@ prevnonblank({lnum}) *prevnonblank()*
|
||||
• {lnum} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
printf({fmt}, {expr1} ...) *printf()*
|
||||
Return a String with {fmt}, where "%" items are replaced by
|
||||
@ -7731,11 +7737,11 @@ reduce({object}, {func} [, {initial}]) *reduce()* *E99
|
||||
|
||||
Parameters: ~
|
||||
• {object} (`any`)
|
||||
• {func} (`function`)
|
||||
• {func} (`fun(accumulator: T, current: any): any`)
|
||||
• {initial} (`any?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`T`)
|
||||
|
||||
reg_executing() *reg_executing()*
|
||||
Returns the single letter name of the register being executed.
|
||||
@ -7784,7 +7790,7 @@ reltime({start}, {end})
|
||||
|
||||
Parameters: ~
|
||||
• {start} (`any?`)
|
||||
• {end_} (`any?`)
|
||||
• {end} (`any?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
@ -7845,7 +7851,7 @@ remove({list}, {idx}, {end})
|
||||
Parameters: ~
|
||||
• {list} (`any[]`)
|
||||
• {idx} (`integer`)
|
||||
• {end_} (`integer?`)
|
||||
• {end} (`integer?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
@ -7867,7 +7873,7 @@ remove({blob}, {idx}, {end})
|
||||
Parameters: ~
|
||||
• {blob} (`any`)
|
||||
• {idx} (`integer`)
|
||||
• {end_} (`integer?`)
|
||||
• {end} (`integer?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
@ -7899,7 +7905,7 @@ rename({from}, {to}) *rename()*
|
||||
• {to} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
repeat({expr}, {count}) *repeat()*
|
||||
Repeat {expr} {count} times and return the concatenated
|
||||
@ -7935,7 +7941,7 @@ resolve({filename}) *resolve()* *E65
|
||||
• {filename} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
reverse({object}) *reverse()*
|
||||
Reverse the order of items in {object}. {object} can be a
|
||||
@ -7949,10 +7955,10 @@ reverse({object}) *reverse()*
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {object} (`any`)
|
||||
• {object} (`T[]`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`T[]`)
|
||||
|
||||
round({expr}) *round()*
|
||||
Round off {expr} to the nearest integral value and return it
|
||||
@ -7972,7 +7978,7 @@ round({expr}) *round()*
|
||||
• {expr} (`number`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`number`)
|
||||
|
||||
rpcnotify({channel}, {event} [, {args}...]) *rpcnotify()*
|
||||
Sends {event} to {channel} via |RPC| and returns immediately.
|
||||
@ -7984,10 +7990,10 @@ rpcnotify({channel}, {event} [, {args}...]) *rpcnotify()*
|
||||
Parameters: ~
|
||||
• {channel} (`integer`)
|
||||
• {event} (`string`)
|
||||
• {args} (`any?`)
|
||||
• {...} (`any`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
rpcrequest({channel}, {method} [, {args}...]) *rpcrequest()*
|
||||
Sends a request to {channel} to invoke {method} via
|
||||
@ -7999,7 +8005,7 @@ rpcrequest({channel}, {method} [, {args}...]) *rpcrequest()*
|
||||
Parameters: ~
|
||||
• {channel} (`integer`)
|
||||
• {method} (`string`)
|
||||
• {args} (`any?`)
|
||||
• {...} (`any`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
@ -8031,7 +8037,7 @@ screenattr({row}, {col}) *screenattr()*
|
||||
• {col} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
screenchar({row}, {col}) *screenchar()*
|
||||
The result is a Number, which is the character at position
|
||||
@ -8048,7 +8054,7 @@ screenchar({row}, {col}) *screenchar()*
|
||||
• {col} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
screenchars({row}, {col}) *screenchars()*
|
||||
The result is a |List| of Numbers. The first number is the same
|
||||
@ -8062,7 +8068,7 @@ screenchars({row}, {col}) *screenchars()*
|
||||
• {col} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer[]`)
|
||||
|
||||
screencol() *screencol()*
|
||||
The result is a Number, which is the current screen column of
|
||||
@ -8080,7 +8086,7 @@ screencol() *screencol()*
|
||||
<
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer[]`)
|
||||
|
||||
screenpos({winid}, {lnum}, {col}) *screenpos()*
|
||||
The result is a Dict with the screen position of the text
|
||||
@ -8123,7 +8129,7 @@ screenrow() *screenrow()*
|
||||
Note: Same restrictions as with |screencol()|.
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
screenstring({row}, {col}) *screenstring()*
|
||||
The result is a String that contains the base character and
|
||||
@ -8138,7 +8144,7 @@ screenstring({row}, {col}) *screenstring()*
|
||||
• {col} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
search({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]]) *search()*
|
||||
Search for regexp pattern {pattern}. The search starts at the
|
||||
@ -8498,7 +8504,7 @@ searchpair({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline} [, {timeo
|
||||
Parameters: ~
|
||||
• {start} (`string`)
|
||||
• {middle} (`string`)
|
||||
• {end_} (`string`)
|
||||
• {end} (`string`)
|
||||
• {flags} (`string?`)
|
||||
• {skip} (`string|function?`)
|
||||
• {stopline} (`integer?`)
|
||||
@ -8522,7 +8528,7 @@ searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline} [, {ti
|
||||
Parameters: ~
|
||||
• {start} (`string`)
|
||||
• {middle} (`string`)
|
||||
• {end_} (`string`)
|
||||
• {end} (`string`)
|
||||
• {flags} (`string?`)
|
||||
• {skip} (`string|function?`)
|
||||
• {stopline} (`integer?`)
|
||||
@ -8565,7 +8571,7 @@ serverlist() *serverlist()*
|
||||
<
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string[]`)
|
||||
|
||||
serverstart([{address}]) *serverstart()*
|
||||
Opens a socket or named pipe at {address} and listens for
|
||||
@ -8605,7 +8611,7 @@ serverstart([{address}]) *serverstart()*
|
||||
• {address} (`string?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
serverstop({address}) *serverstop()*
|
||||
Closes the pipe or socket at {address}.
|
||||
@ -8617,7 +8623,7 @@ serverstop({address}) *serverstop()*
|
||||
• {address} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
setbufline({buf}, {lnum}, {text}) *setbufline()*
|
||||
Set line {lnum} to {text} in buffer {buf}. This works like
|
||||
@ -8650,7 +8656,7 @@ setbufline({buf}, {lnum}, {text}) *setbufline()*
|
||||
• {text} (`string|string[]`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
setbufvar({buf}, {varname}, {val}) *setbufvar()*
|
||||
Set option or local variable {varname} in buffer {buf} to
|
||||
@ -8770,7 +8776,7 @@ setcmdline({str} [, {pos}]) *setcmdline()*
|
||||
• {pos} (`integer?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
setcmdpos({pos}) *setcmdpos()*
|
||||
Set the cursor position in the command line to byte position
|
||||
@ -9102,7 +9108,7 @@ setqflist({list} [, {action} [, {what}]]) *setqflist()*
|
||||
• {what} (`vim.fn.setqflist.what?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
setreg({regname}, {value} [, {options}]) *setreg()*
|
||||
Set the register {regname} to {value}.
|
||||
@ -9273,7 +9279,7 @@ sha256({string}) *sha256()*
|
||||
• {string} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
shellescape({string} [, {special}]) *shellescape()*
|
||||
Escape {string} for use as a shell command argument.
|
||||
@ -9312,7 +9318,7 @@ shellescape({string} [, {special}]) *shellescape()*
|
||||
• {special} (`boolean?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
shiftwidth([{col}]) *shiftwidth()*
|
||||
Returns the effective value of 'shiftwidth'. This is the
|
||||
@ -9790,7 +9796,7 @@ simplify({filename}) *simplify()*
|
||||
• {filename} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
sin({expr}) *sin()*
|
||||
Return the sine of {expr}, measured in radians, as a |Float|.
|
||||
@ -9806,7 +9812,7 @@ sin({expr}) *sin()*
|
||||
• {expr} (`number`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`number`)
|
||||
|
||||
sinh({expr}) *sinh()*
|
||||
Return the hyperbolic sine of {expr} as a |Float| in the range
|
||||
@ -9838,7 +9844,7 @@ slice({expr}, {start} [, {end}]) *slice()*
|
||||
Parameters: ~
|
||||
• {expr} (`any`)
|
||||
• {start} (`integer`)
|
||||
• {end_} (`integer?`)
|
||||
• {end} (`integer?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
@ -9950,12 +9956,12 @@ sort({list} [, {how} [, {dict}]]) *sort()* *E70
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {list} (`any`)
|
||||
• {list} (`T[]`)
|
||||
• {how} (`string|function?`)
|
||||
• {dict} (`any?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`T[]`)
|
||||
|
||||
soundfold({word}) *soundfold()*
|
||||
Return the sound-folded equivalent of {word}. Uses the first
|
||||
@ -9969,7 +9975,7 @@ soundfold({word}) *soundfold()*
|
||||
• {word} (`string`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
spellbadword([{sentence}]) *spellbadword()*
|
||||
Without argument: The result is the badly spelled word under
|
||||
@ -10028,7 +10034,7 @@ spellsuggest({word} [, {max} [, {capital}]]) *spellsuggest()*
|
||||
• {capital} (`boolean?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string[]`)
|
||||
|
||||
split({string} [, {pattern} [, {keepempty}]]) *split()*
|
||||
Make a |List| out of {string}. When {pattern} is omitted or
|
||||
@ -10061,7 +10067,7 @@ split({string} [, {pattern} [, {keepempty}]]) *split()*
|
||||
• {keepempty} (`boolean?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string[]`)
|
||||
|
||||
sqrt({expr}) *sqrt()*
|
||||
Return the non-negative square root of Float {expr} as a
|
||||
@ -10232,6 +10238,7 @@ str2list({string} [, {utf8}]) *str2list()*
|
||||
and exists only for backwards-compatibility.
|
||||
With UTF-8 composing characters are handled properly: >vim
|
||||
echo str2list("á") " returns [97, 769]
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {string} (`string`)
|
||||
@ -11165,28 +11172,6 @@ tempname() *tempname()*
|
||||
Return: ~
|
||||
(`string`)
|
||||
|
||||
termopen({cmd} [, {opts}]) *termopen()*
|
||||
Spawns {cmd} in a new pseudo-terminal session connected
|
||||
to the current (unmodified) buffer. Parameters and behavior
|
||||
are the same as |jobstart()| except "pty", "width", "height",
|
||||
and "TERM" are ignored: "height" and "width" are taken from
|
||||
the current window. Note that termopen() implies a "pty" arg
|
||||
to jobstart(), and thus has the implications documented at
|
||||
|jobstart()|.
|
||||
|
||||
Returns the same values as jobstart().
|
||||
|
||||
Terminal environment is initialized as in |jobstart-env|,
|
||||
except $TERM is set to "xterm-256color". Full behavior is
|
||||
described in |terminal|.
|
||||
|
||||
Parameters: ~
|
||||
• {cmd} (`string|string[]`)
|
||||
• {opts} (`table?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
|
||||
test_garbagecollect_now() *test_garbagecollect_now()*
|
||||
Like |garbagecollect()|, but executed right away. This must
|
||||
only be called directly to avoid any structure to exist
|
||||
@ -11646,7 +11631,7 @@ virtcol2col({winid}, {lnum}, {col}) *virtcol2col()*
|
||||
• {col} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
visualmode([{expr}]) *visualmode()*
|
||||
The result is a String, which describes the last Visual mode
|
||||
@ -11670,7 +11655,7 @@ visualmode([{expr}]) *visualmode()*
|
||||
• {expr} (`boolean?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
wait({timeout}, {condition} [, {interval}]) *wait()*
|
||||
Waits until {condition} evaluates to |TRUE|, where {condition}
|
||||
@ -11812,7 +11797,7 @@ win_id2win({expr}) *win_id2win()*
|
||||
• {expr} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
win_move_separator({nr}, {offset}) *win_move_separator()*
|
||||
Move window {nr}'s vertical separator (i.e., the right border)
|
||||
@ -11989,7 +11974,7 @@ winlayout([{tabnr}]) *winlayout()*
|
||||
• {tabnr} (`integer?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`any[]`)
|
||||
|
||||
winline() *winline()*
|
||||
The result is a Number, which is the screen line of the cursor
|
||||
@ -12037,7 +12022,7 @@ winnr([{arg}]) *winnr()*
|
||||
• {arg} (`string|integer?`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
winrestcmd() *winrestcmd()*
|
||||
Returns a sequence of |:resize| commands that should restore
|
||||
@ -12051,7 +12036,7 @@ winrestcmd() *winrestcmd()*
|
||||
<
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`string`)
|
||||
|
||||
winrestview({dict}) *winrestview()*
|
||||
Uses the |Dictionary| returned by |winsaveview()| to restore
|
||||
@ -12123,7 +12108,7 @@ winwidth({nr}) *winwidth()*
|
||||
• {nr} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
wordcount() *wordcount()*
|
||||
The result is a dictionary of byte/chars/word statistics for
|
||||
@ -12213,11 +12198,11 @@ xor({expr}, {expr}) *xor()*
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {expr} (`number`)
|
||||
• {expr1} (`number`)
|
||||
• {expr} (`integer`)
|
||||
• {expr1} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`any`)
|
||||
(`integer`)
|
||||
|
||||
==============================================================================
|
||||
2. Matching a pattern in a String *string-match*
|
||||
|
@ -1443,18 +1443,17 @@ since formatting is highly dependent on the type of file. It makes
|
||||
sense to use an |autoload| script, so the corresponding script is only loaded
|
||||
when actually needed and the script should be called <filetype>format.vim.
|
||||
|
||||
For example, the XML filetype plugin distributed with Vim in the $VIMRUNTIME
|
||||
directory, sets the 'formatexpr' option to: >
|
||||
For example, the XML filetype plugin distributed with Vim in the
|
||||
$VIMRUNTIME/ftplugin directory, sets the 'formatexpr' option to: >
|
||||
|
||||
setlocal formatexpr=xmlformat#Format()
|
||||
|
||||
That means, you will find the corresponding script, defining the
|
||||
xmlformat#Format() function, in the directory:
|
||||
`$VIMRUNTIME/autoload/xmlformat.vim`
|
||||
xmlformat#Format() function, in the file `$VIMRUNTIME/autoload/xmlformat.vim`
|
||||
|
||||
Here is an example script that removes trailing whitespace from the selected
|
||||
text. Put it in your autoload directory, e.g. ~/.vim/autoload/format.vim: >
|
||||
|
||||
text. Put it in your autoload directory, e.g. ~/.vim/autoload/format.vim:
|
||||
>vim
|
||||
func! format#Format()
|
||||
" only reformat on explicit gq command
|
||||
if mode() != 'n'
|
||||
@ -1487,7 +1486,7 @@ debugging it helps to set the 'debug' option.
|
||||
|
||||
*right-justify*
|
||||
There is no command in Vim to right justify text. You can do it with
|
||||
an external command, like "par" (e.g.: "!}par" to format until the end of the
|
||||
an external command, like "par" (e.g.: `:.,}!par` to format until the end of the
|
||||
paragraph) or set 'formatprg' to "par".
|
||||
|
||||
*format-comments*
|
||||
@ -1553,7 +1552,7 @@ type of comment string. A part consists of:
|
||||
some indent for the start or end part that can be removed.
|
||||
|
||||
When a string has none of the 'f', 's', 'm' or 'e' flags, Vim assumes the
|
||||
comment string repeats at the start of each line. The flags field may be
|
||||
comment string repeats at the start of each line. The {flags} field may be
|
||||
empty.
|
||||
|
||||
Any blank space in the text before and after the {string} is part of the
|
||||
|
@ -20,8 +20,8 @@ There are several ways to open a channel:
|
||||
|
||||
2. Through stdin, stdout and stderr of a process spawned by |jobstart()|.
|
||||
|
||||
3. Through the PTY master end of a PTY opened with
|
||||
`jobstart(..., {'pty': v:true})` or |termopen()|.
|
||||
3. Through the PTY master end of a PTY opened with |nvim_open_term()| or
|
||||
`jobstart(…, {'pty': v:true})`.
|
||||
|
||||
4. By connecting to a TCP/IP socket or named pipe with |sockconnect()|.
|
||||
|
||||
|
@ -41,15 +41,19 @@ thus you cannot edit beyond that.
|
||||
The command-lines that you enter are remembered in a history table. You can
|
||||
recall them with the up and down cursor keys. There are actually five
|
||||
history tables:
|
||||
|
||||
- one for ':' commands
|
||||
- one for search strings
|
||||
- one for expressions
|
||||
- one for input lines, typed for the |input()| function.
|
||||
- one for debug mode commands
|
||||
|
||||
These are completely separate. Each history can only be accessed when
|
||||
entering the same type of line.
|
||||
Use the 'history' option to set the number of lines that are remembered.
|
||||
|
||||
Notes:
|
||||
|
||||
- When you enter a command-line that is exactly the same as an older one, the
|
||||
old one is removed (to avoid repeated commands moving older commands out of
|
||||
the history).
|
||||
|
@ -1,11 +1,118 @@
|
||||
*backers.txt* Nvim
|
||||
*credits.txt* Nvim
|
||||
|
||||
|
||||
NVIM REFERENCE MANUAL
|
||||
|
||||
|
||||
==============================================================================
|
||||
Fundraiser Backers
|
||||
Credits *credits*
|
||||
|
||||
Most of Vim was written by Bram Moolenaar <Bram@vim.org> |Bram-Moolenaar|.
|
||||
|
||||
Parts of the documentation come from several Vi manuals, written by:
|
||||
W.N. Joy
|
||||
Alan P.W. Hewett
|
||||
Mark Horton
|
||||
|
||||
The Vim editor is based on Stevie and includes (ideas from) other software,
|
||||
worked on by the people mentioned here. Other people helped by sending me
|
||||
patches, suggestions and giving feedback about what is good and bad in Vim.
|
||||
|
||||
Vim would never have become what it is now, without the help of these people!
|
||||
|
||||
Ron Aaron Win32 GUI changes
|
||||
Mohsin Ahmed encryption
|
||||
Zoltan Arpadffy work on VMS port
|
||||
Tony Andrews Stevie
|
||||
Gert van Antwerpen changes for DJGPP on MS-DOS
|
||||
Berkeley DB(3) ideas for swap file implementation
|
||||
Keith Bostic Nvi
|
||||
Walter Briscoe Makefile updates, various patches
|
||||
Ralf Brown SPAWNO library for MS-DOS
|
||||
Robert Colon many useful remarks
|
||||
Marcin Dalecki GTK+ GUI port, toolbar icons, gettext()
|
||||
Kayhan Demirel sent me news in Uganda
|
||||
Chris & John Downey xvi (ideas for multi-windows version)
|
||||
Henk Elbers first VMS port
|
||||
Daniel Elstner GTK+ 2 port
|
||||
Eric Fischer Mac port, 'cindent', and other improvements
|
||||
Benji Fisher Answering lots of user questions
|
||||
Bill Foster Athena GUI port (later removed)
|
||||
Google Let Bram work on Vim one day a week
|
||||
Loic Grenie xvim (ideas for multi windows version)
|
||||
Sven Guckes Vim promoter and previous WWW page maintainer
|
||||
Darren Hiebert Exuberant ctags
|
||||
Jason Hildebrand GTK+ 2 port
|
||||
Bruce Hunsaker improvements for VMS port
|
||||
Andy Kahn Cscope support, GTK+ GUI port
|
||||
Oezguer Kesim Maintainer of Vim Mailing Lists
|
||||
Axel Kielhorn work on the Macintosh port
|
||||
Steve Kirkendall Elvis
|
||||
Roger Knobbe original port to Windows NT
|
||||
Sergey Laskavy Vim's help from Moscow
|
||||
Felix von Leitner Previous maintainer of Vim Mailing Lists
|
||||
David Leonard Port of Python extensions to Unix
|
||||
Avner Lottem Edit in right-to-left windows
|
||||
Flemming Madsen X11 client-server, various features and patches
|
||||
Tony Mechelynck answers many user questions
|
||||
Paul Moore Python interface extensions, many patches
|
||||
Katsuhito Nagano Work on multibyte versions
|
||||
Sung-Hyun Nam Work on multibyte versions
|
||||
Vince Negri Win32 GUI and generic console enhancements
|
||||
Steve Oualline Author of the first Vim book |frombook|
|
||||
Dominique Pelle Valgrind reports and many fixes
|
||||
A.Politz Many bug reports and some fixes
|
||||
George V. Reilly Win32 port, Win32 GUI start-off
|
||||
Stephen Riehm bug collector
|
||||
Stefan Roemer various patches and help to users
|
||||
Ralf Schandl IBM OS/390 port
|
||||
Olaf Seibert DICE and BeBox version, regexp improvements
|
||||
Mortaza Shiran Farsi patches
|
||||
Peter da Silva termlib
|
||||
Paul Slootman OS/2 port
|
||||
Henry Spencer regular expressions
|
||||
Dany St-Amant Macintosh port
|
||||
Tim Thompson Stevie
|
||||
G. R. (Fred) Walter Stevie
|
||||
Sven Verdoolaege Perl interface
|
||||
Robert Webb Command-line completion, GUI versions, and
|
||||
lots of patches
|
||||
Ingo Wilken Tcl interface
|
||||
Mike Williams PostScript printing
|
||||
Juergen Weigert Lattice version, AUX improvements, Unix and
|
||||
MS-DOS ports, autoconf
|
||||
Stefan 'Sec' Zehl Maintainer of vim.org
|
||||
Yasuhiro Matsumoto many MS-Windows improvements
|
||||
Ken Takata fixes and features
|
||||
Kazunobu Kuriyama GTK 3
|
||||
Christian Brabandt many fixes, features, user support, etc.
|
||||
Yegappan Lakshmanan many quickfix features
|
||||
|
||||
I wish to thank all the people that sent me bug reports and suggestions. The
|
||||
list is too long to mention them all here. Vim would not be the same without
|
||||
the ideas from all these people: They keep Vim alive!
|
||||
*love* *peace* *friendship* *gross-national-happiness*
|
||||
|
||||
|
||||
Documentation may refer to other versions of Vi:
|
||||
*Vi* *vi*
|
||||
Vi "the original". Without further remarks this is the version
|
||||
of Vi that appeared in Sun OS 4.x. ":version" returns
|
||||
"Version 3.7, 6/7/85". Source code only available with a license.
|
||||
*Nvi*
|
||||
Nvi The "New" Vi. The version of Vi that comes with BSD 4.4 and FreeBSD.
|
||||
Very good compatibility with the original Vi, with a few extensions.
|
||||
The version used is 1.79. ":version" returns "Version 1.79
|
||||
(10/23/96)". Source code is freely available.
|
||||
*Elvis*
|
||||
Elvis Another Vi clone, made by Steve Kirkendall. Very compact but isn't
|
||||
as flexible as Vim. Source code is freely available.
|
||||
|
||||
Vim Nvim is based on Vim. https://www.vim.org/
|
||||
|
||||
|
||||
==============================================================================
|
||||
Neovim fundraiser backers *backers.txt*
|
||||
|
||||
Thank you to everyone who backed the original Neovim Fundraiser.
|
||||
|
@ -16,45 +16,34 @@ Deprecated features
|
||||
DEPRECATED IN 0.11 *deprecated-0.11*
|
||||
|
||||
API
|
||||
- nvim_subscribe() Plugins must maintain their own "multicast" channels list.
|
||||
- nvim_unsubscribe() Plugins must maintain their own "multicast" channels list.
|
||||
|
||||
LUA
|
||||
- vim.region() Use |getregionpos()| instead.
|
||||
- *vim.highlight* Renamed to |vim.hl|.
|
||||
- vim.validate(opts: table) Use form 1. See |vim.validate()|.
|
||||
• nvim_subscribe() Plugins must maintain their own "multicast" channels list.
|
||||
• nvim_unsubscribe() Plugins must maintain their own "multicast" channels list.
|
||||
|
||||
DIAGNOSTICS
|
||||
- *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count=1, float=true}` instead.
|
||||
- *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count=-1, float=true}` instead.
|
||||
- *vim.diagnostic.get_next_pos()*
|
||||
Use the "lnum" and "col" fields from the return value of
|
||||
|vim.diagnostic.get_next()| instead.
|
||||
- *vim.diagnostic.get_prev_pos()*
|
||||
Use the "lnum" and "col" fields from the return value of
|
||||
|vim.diagnostic.get_prev()| instead.
|
||||
- The "win_id" parameter used by various functions is deprecated in favor of
|
||||
• *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count=1, float=true}` instead.
|
||||
• *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count=-1, float=true}` instead.
|
||||
• *vim.diagnostic.get_next_pos()* Use the "lnum" and "col" fields from the
|
||||
return value of |vim.diagnostic.get_next()| instead.
|
||||
• *vim.diagnostic.get_prev_pos()* Use the "lnum" and "col" fields from the
|
||||
return value of |vim.diagnostic.get_prev()| instead.
|
||||
• The "win_id" parameter used by various functions is deprecated in favor of
|
||||
"winid" |winid|
|
||||
- The "cursor_position" parameter of |vim.diagnostic.JumpOpts| is renamed to
|
||||
"pos"
|
||||
• |vim.diagnostic.JumpOpts| renamed its "cursor_position" field to "pos".
|
||||
|
||||
TREESITTER
|
||||
• *TSNode:child_containing_descendant()* Use
|
||||
|TSNode:child_with_descendant()| instead; it is identical except that it can
|
||||
return the descendant itself.
|
||||
HIGHLIGHTS
|
||||
• *TermCursorNC* Unfocused |terminal| windows do not have a cursor.
|
||||
|
||||
LSP
|
||||
• *vim.lsp.util.jump_to_location* Use |vim.lsp.util.show_document()| with
|
||||
`{focus=true}` instead.
|
||||
`{focus=true}` instead.
|
||||
• *vim.lsp.buf.execute_command* Use |Client:exec_cmd()| instead.
|
||||
• *vim.lsp.buf.completion* Use |vim.lsp.completion.trigger()| instead.
|
||||
• vim.lsp.buf_request_all The `error` key has been renamed to `err` inside
|
||||
the result parameter of the handler.
|
||||
• *vim.lsp.with()* Pass configuration to equivalent
|
||||
functions in `vim.lsp.buf.*`.
|
||||
• |vim.lsp.handlers|
|
||||
No longer support client to server response handlers. Only server to
|
||||
client requests/notification handlers are supported.
|
||||
• |vim.lsp.handlers| Does not support client-to-server response handlers. Only
|
||||
supports server-to-client requests/notification handlers.
|
||||
• *vim.lsp.handlers.signature_help()* Use |vim.lsp.buf.signature_help()| instead.
|
||||
• `client.request()` Use |Client:request()| instead.
|
||||
• `client.request_sync()` Use |Client:request_sync()| instead.
|
||||
@ -64,6 +53,19 @@ LSP
|
||||
• `client.is_stopped()` Use |Client:is_stopped()| instead.
|
||||
• `client.supports_method()` Use |Client:supports_method()| instead.
|
||||
• `client.on_attach()` Use |Client:on_attach()| instead.
|
||||
• `vim.lsp.start_client()` Use |vim.lsp.start()| instead.
|
||||
|
||||
LUA
|
||||
• vim.region() Use |getregionpos()| instead.
|
||||
• *vim.highlight* Renamed to |vim.hl|.
|
||||
• vim.validate(opts: table) Use form 1. See |vim.validate()|.
|
||||
|
||||
TREESITTER
|
||||
• *TSNode:child_containing_descendant()* Use |TSNode:child_with_descendant()|
|
||||
instead; it is identical except that it can return the descendant itself.
|
||||
|
||||
VIMSCRIPT
|
||||
• *termopen()* Use |jobstart() with `{term: v:true}`.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
DEPRECATED IN 0.10 *deprecated-0.10*
|
||||
@ -125,198 +127,198 @@ TREESITTER
|
||||
DEPRECATED IN 0.9 *deprecated-0.9*
|
||||
|
||||
API
|
||||
- *nvim_get_hl_by_name()* Use |nvim_get_hl()| instead.
|
||||
- *nvim_get_hl_by_id()* Use |nvim_get_hl()| instead.
|
||||
• *nvim_get_hl_by_name()* Use |nvim_get_hl()| instead.
|
||||
• *nvim_get_hl_by_id()* Use |nvim_get_hl()| instead.
|
||||
|
||||
TREESITTER
|
||||
- *vim.treesitter.language.require_language()* Use |vim.treesitter.language.add()| instead.
|
||||
- *vim.treesitter.get_node_at_pos()* Use |vim.treesitter.get_node()| instead.
|
||||
- *vim.treesitter.get_node_at_cursor()* Use |vim.treesitter.get_node()|
|
||||
• *vim.treesitter.language.require_language()* Use |vim.treesitter.language.add()| instead.
|
||||
• *vim.treesitter.get_node_at_pos()* Use |vim.treesitter.get_node()| instead.
|
||||
• *vim.treesitter.get_node_at_cursor()* Use |vim.treesitter.get_node()|
|
||||
and |TSNode:type()| instead.
|
||||
• The following top level Treesitter functions have been moved:
|
||||
- *vim.treesitter.inspect_language()* -> |vim.treesitter.language.inspect()|
|
||||
- *vim.treesitter.get_query_files()* -> |vim.treesitter.query.get_files()|
|
||||
- *vim.treesitter.set_query()* -> |vim.treesitter.query.set()|
|
||||
- *vim.treesitter.query.set_query()* -> |vim.treesitter.query.set()|
|
||||
- *vim.treesitter.get_query()* -> |vim.treesitter.query.get()|
|
||||
- *vim.treesitter.query.get_query()* -> |vim.treesitter.query.get()|
|
||||
- *vim.treesitter.parse_query()* -> |vim.treesitter.query.parse()|
|
||||
- *vim.treesitter.query.parse_query()* -> |vim.treesitter.query.parse()|
|
||||
- *vim.treesitter.add_predicate()* -> |vim.treesitter.query.add_predicate()|
|
||||
- *vim.treesitter.add_directive()* -> |vim.treesitter.query.add_directive()|
|
||||
- *vim.treesitter.list_predicates()* -> |vim.treesitter.query.list_predicates()|
|
||||
- *vim.treesitter.list_directives()* -> |vim.treesitter.query.list_directives()|
|
||||
- *vim.treesitter.query.get_range()* -> |vim.treesitter.get_range()|
|
||||
- *vim.treesitter.query.get_node_text()* -> |vim.treesitter.get_node_text()|
|
||||
• *vim.treesitter.inspect_language()* -> |vim.treesitter.language.inspect()|
|
||||
• *vim.treesitter.get_query_files()* -> |vim.treesitter.query.get_files()|
|
||||
• *vim.treesitter.set_query()* -> |vim.treesitter.query.set()|
|
||||
• *vim.treesitter.query.set_query()* -> |vim.treesitter.query.set()|
|
||||
• *vim.treesitter.get_query()* -> |vim.treesitter.query.get()|
|
||||
• *vim.treesitter.query.get_query()* -> |vim.treesitter.query.get()|
|
||||
• *vim.treesitter.parse_query()* -> |vim.treesitter.query.parse()|
|
||||
• *vim.treesitter.query.parse_query()* -> |vim.treesitter.query.parse()|
|
||||
• *vim.treesitter.add_predicate()* -> |vim.treesitter.query.add_predicate()|
|
||||
• *vim.treesitter.add_directive()* -> |vim.treesitter.query.add_directive()|
|
||||
• *vim.treesitter.list_predicates()* -> |vim.treesitter.query.list_predicates()|
|
||||
• *vim.treesitter.list_directives()* -> |vim.treesitter.query.list_directives()|
|
||||
• *vim.treesitter.query.get_range()* -> |vim.treesitter.get_range()|
|
||||
• *vim.treesitter.query.get_node_text()* -> |vim.treesitter.get_node_text()|
|
||||
|
||||
LUA
|
||||
- *nvim_exec()* Use |nvim_exec2()| instead.
|
||||
- *vim.pretty_print()* Use |vim.print()| instead.
|
||||
• *nvim_exec()* Use |nvim_exec2()| instead.
|
||||
• *vim.pretty_print()* Use |vim.print()| instead.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
DEPRECATED IN 0.8 OR EARLIER
|
||||
|
||||
API
|
||||
- *nvim_buf_clear_highlight()* Use |nvim_buf_clear_namespace()| instead.
|
||||
- *nvim_buf_set_virtual_text()* Use |nvim_buf_set_extmark()| instead.
|
||||
- *nvim_command_output()* Use |nvim_exec2()| instead.
|
||||
- *nvim_execute_lua()* Use |nvim_exec_lua()| instead.
|
||||
- *nvim_get_option_info()* Use |nvim_get_option_info2()| instead.
|
||||
• *nvim_buf_clear_highlight()* Use |nvim_buf_clear_namespace()| instead.
|
||||
• *nvim_buf_set_virtual_text()* Use |nvim_buf_set_extmark()| instead.
|
||||
• *nvim_command_output()* Use |nvim_exec2()| instead.
|
||||
• *nvim_execute_lua()* Use |nvim_exec_lua()| instead.
|
||||
• *nvim_get_option_info()* Use |nvim_get_option_info2()| instead.
|
||||
|
||||
COMMANDS
|
||||
- *:rv* *:rviminfo* Deprecated alias to |:rshada| command.
|
||||
- *:wv* *:wviminfo* Deprecated alias to |:wshada| command.
|
||||
• *:rv* *:rviminfo* Deprecated alias to |:rshada| command.
|
||||
• *:wv* *:wviminfo* Deprecated alias to |:wshada| command.
|
||||
|
||||
ENVIRONMENT VARIABLES
|
||||
- *$NVIM_LISTEN_ADDRESS*
|
||||
- Deprecated way to:
|
||||
- set the server name (use |--listen| or |serverstart()| instead)
|
||||
- get the server name (use |v:servername| instead)
|
||||
- detect a parent Nvim (use |$NVIM| instead)
|
||||
- Ignored if --listen is given.
|
||||
- Unset by |terminal| and |jobstart()| unless explicitly given by the "env"
|
||||
• *$NVIM_LISTEN_ADDRESS*
|
||||
• Deprecated way to:
|
||||
• set the server name (use |--listen| or |serverstart()| instead)
|
||||
• get the server name (use |v:servername| instead)
|
||||
• detect a parent Nvim (use |$NVIM| instead)
|
||||
• Ignored if --listen is given.
|
||||
• Unset by |terminal| and |jobstart()| unless explicitly given by the "env"
|
||||
option. Example: >vim
|
||||
call jobstart(['foo'], { 'env': { 'NVIM_LISTEN_ADDRESS': v:servername } })
|
||||
<
|
||||
|
||||
EVENTS
|
||||
- *BufCreate* Use |BufAdd| instead.
|
||||
- *EncodingChanged* Never fired; 'encoding' is always "utf-8".
|
||||
- *FileEncoding* Never fired; equivalent to |EncodingChanged|.
|
||||
- *GUIEnter* Never fired; use |UIEnter| instead.
|
||||
- *GUIFailed* Never fired.
|
||||
• *BufCreate* Use |BufAdd| instead.
|
||||
• *EncodingChanged* Never fired; 'encoding' is always "utf-8".
|
||||
• *FileEncoding* Never fired; equivalent to |EncodingChanged|.
|
||||
• *GUIEnter* Never fired; use |UIEnter| instead.
|
||||
• *GUIFailed* Never fired.
|
||||
|
||||
KEYCODES
|
||||
- *<MouseDown>* Use <ScrollWheelUp> instead.
|
||||
- *<MouseUp>* Use <ScrollWheelDown> instead.
|
||||
|
||||
FUNCTIONS
|
||||
- *buffer_exists()* Obsolete name for |bufexists()|.
|
||||
- *buffer_name()* Obsolete name for |bufname()|.
|
||||
- *buffer_number()* Obsolete name for |bufnr()|.
|
||||
- *file_readable()* Obsolete name for |filereadable()|.
|
||||
- *highlight_exists()* Obsolete name for |hlexists()|.
|
||||
- *highlightID()* Obsolete name for |hlID()|.
|
||||
- *inputdialog()* Use |input()| instead.
|
||||
- *jobclose()* Obsolete name for |chanclose()|
|
||||
- *jobsend()* Obsolete name for |chansend()|
|
||||
- *last_buffer_nr()* Obsolete name for bufnr("$").
|
||||
- *rpcstart()* Use |jobstart()| with `{'rpc': v:true}` instead.
|
||||
- *rpcstop()* Use |jobstop()| instead to stop any job, or
|
||||
`chanclose(id, "rpc")` to close RPC communication
|
||||
without stopping the job. Use chanclose(id) to close
|
||||
any socket.
|
||||
• *<MouseDown>* Use <ScrollWheelUp> instead.
|
||||
• *<MouseUp>* Use <ScrollWheelDown> instead.
|
||||
|
||||
HIGHLIGHTS
|
||||
- *hl-VertSplit* Use |hl-WinSeparator| instead.
|
||||
• *hl-VertSplit* Use |hl-WinSeparator| instead.
|
||||
|
||||
LSP DIAGNOSTICS
|
||||
For each of the functions below, use the corresponding function in
|
||||
|vim.diagnostic| instead (unless otherwise noted). For example, use
|
||||
|vim.diagnostic.get()| instead of |vim.lsp.diagnostic.get()|.
|
||||
|
||||
- *vim.lsp.diagnostic.clear()* Use |vim.diagnostic.hide()| instead.
|
||||
- *vim.lsp.diagnostic.disable()* Use |vim.diagnostic.enable()| instead.
|
||||
- *vim.lsp.diagnostic.display()* Use |vim.diagnostic.show()| instead.
|
||||
- *vim.lsp.diagnostic.enable()*
|
||||
- *vim.lsp.diagnostic.get()*
|
||||
- *vim.lsp.diagnostic.get_all()* Use |vim.diagnostic.get()| instead.
|
||||
- *vim.lsp.diagnostic.get_count()* Use |vim.diagnostic.count()| instead.
|
||||
- *vim.lsp.diagnostic.get_line_diagnostics()* Use |vim.diagnostic.get()| instead.
|
||||
- *vim.lsp.diagnostic.get_next()*
|
||||
- *vim.lsp.diagnostic.get_next_pos()*
|
||||
- *vim.lsp.diagnostic.get_prev()*
|
||||
- *vim.lsp.diagnostic.get_prev_pos()*
|
||||
- *vim.lsp.diagnostic.get_virtual_text_chunks_for_line()* No replacement. Use
|
||||
• *vim.lsp.diagnostic.clear()* Use |vim.diagnostic.hide()| instead.
|
||||
• *vim.lsp.diagnostic.disable()* Use |vim.diagnostic.enable()| instead.
|
||||
• *vim.lsp.diagnostic.display()* Use |vim.diagnostic.show()| instead.
|
||||
• *vim.lsp.diagnostic.enable()*
|
||||
• *vim.lsp.diagnostic.get()*
|
||||
• *vim.lsp.diagnostic.get_all()* Use |vim.diagnostic.get()| instead.
|
||||
• *vim.lsp.diagnostic.get_count()* Use |vim.diagnostic.count()| instead.
|
||||
• *vim.lsp.diagnostic.get_line_diagnostics()* Use |vim.diagnostic.get()| instead.
|
||||
• *vim.lsp.diagnostic.get_next()*
|
||||
• *vim.lsp.diagnostic.get_next_pos()*
|
||||
• *vim.lsp.diagnostic.get_prev()*
|
||||
• *vim.lsp.diagnostic.get_prev_pos()*
|
||||
• *vim.lsp.diagnostic.get_virtual_text_chunks_for_line()* No replacement. Use
|
||||
options provided by |vim.diagnostic.config()| to customize virtual text.
|
||||
- *vim.lsp.diagnostic.goto_next()*
|
||||
- *vim.lsp.diagnostic.goto_prev()*
|
||||
- *vim.lsp.diagnostic.redraw()* Use |vim.diagnostic.show()| instead.
|
||||
- *vim.lsp.diagnostic.reset()*
|
||||
- *vim.lsp.diagnostic.save()* Use |vim.diagnostic.set()| instead.
|
||||
- *vim.lsp.diagnostic.set_loclist()* Use |vim.diagnostic.setloclist()| instead.
|
||||
- *vim.lsp.diagnostic.set_qflist()* Use |vim.diagnostic.setqflist()| instead.
|
||||
- *vim.lsp.diagnostic.show_line_diagnostics()* Use |vim.diagnostic.open_float()| instead.
|
||||
- *vim.lsp.diagnostic.show_position_diagnostics()* Use |vim.diagnostic.open_float()| instead.
|
||||
• *vim.lsp.diagnostic.goto_next()*
|
||||
• *vim.lsp.diagnostic.goto_prev()*
|
||||
• *vim.lsp.diagnostic.redraw()* Use |vim.diagnostic.show()| instead.
|
||||
• *vim.lsp.diagnostic.reset()*
|
||||
• *vim.lsp.diagnostic.save()* Use |vim.diagnostic.set()| instead.
|
||||
• *vim.lsp.diagnostic.set_loclist()* Use |vim.diagnostic.setloclist()| instead.
|
||||
• *vim.lsp.diagnostic.set_qflist()* Use |vim.diagnostic.setqflist()| instead.
|
||||
• *vim.lsp.diagnostic.show_line_diagnostics()* Use |vim.diagnostic.open_float()| instead.
|
||||
• *vim.lsp.diagnostic.show_position_diagnostics()* Use |vim.diagnostic.open_float()| instead.
|
||||
|
||||
The following are deprecated without replacement. These functions are moved
|
||||
internally and are no longer exposed as part of the API. Instead, use
|
||||
|vim.diagnostic.config()| and |vim.diagnostic.show()|.
|
||||
|
||||
- *vim.lsp.diagnostic.set_signs()*
|
||||
- *vim.lsp.diagnostic.set_underline()*
|
||||
- *vim.lsp.diagnostic.set_virtual_text()*
|
||||
• *vim.lsp.diagnostic.set_signs()*
|
||||
• *vim.lsp.diagnostic.set_underline()*
|
||||
• *vim.lsp.diagnostic.set_virtual_text()*
|
||||
|
||||
LSP FUNCTIONS
|
||||
- *vim.lsp.buf.server_ready()*
|
||||
• *vim.lsp.buf.server_ready()*
|
||||
Use |LspAttach| instead, depending on your use-case. "Server ready" is not
|
||||
part of the LSP spec, so the Nvim LSP client cannot meaningfully implement
|
||||
it. "Ready" is ambiguous because:
|
||||
- Language servers may finish analyzing the workspace, but edits can always
|
||||
• Language servers may finish analyzing the workspace, but edits can always
|
||||
re-trigger analysis/builds.
|
||||
- Language servers can serve some requests even while processing changes.
|
||||
- *vim.lsp.buf.range_code_action()* Use |vim.lsp.buf.code_action()| with
|
||||
• Language servers can serve some requests even while processing changes.
|
||||
• *vim.lsp.buf.range_code_action()* Use |vim.lsp.buf.code_action()| with
|
||||
the `range` parameter.
|
||||
- *vim.lsp.util.diagnostics_to_items()* Use |vim.diagnostic.toqflist()| instead.
|
||||
- *vim.lsp.util.set_qflist()* Use |setqflist()| instead.
|
||||
- *vim.lsp.util.set_loclist()* Use |setloclist()| instead.
|
||||
- *vim.lsp.buf_get_clients()* Use |vim.lsp.get_clients()| with
|
||||
• *vim.lsp.util.diagnostics_to_items()* Use |vim.diagnostic.toqflist()| instead.
|
||||
• *vim.lsp.util.set_qflist()* Use |setqflist()| instead.
|
||||
• *vim.lsp.util.set_loclist()* Use |setloclist()| instead.
|
||||
• *vim.lsp.buf_get_clients()* Use |vim.lsp.get_clients()| with
|
||||
{buffer=bufnr} instead.
|
||||
- *vim.lsp.buf.formatting()* Use |vim.lsp.buf.format()| with
|
||||
• *vim.lsp.buf.formatting()* Use |vim.lsp.buf.format()| with
|
||||
{async=true} instead.
|
||||
- *vim.lsp.buf.formatting_sync()* Use |vim.lsp.buf.format()| with
|
||||
• *vim.lsp.buf.formatting_sync()* Use |vim.lsp.buf.format()| with
|
||||
{async=false} instead.
|
||||
- *vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()|
|
||||
• *vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()|
|
||||
or |vim.lsp.buf.format()| instead.
|
||||
|
||||
LUA
|
||||
- vim.register_keystroke_callback() Use |vim.on_key()| instead.
|
||||
• vim.register_keystroke_callback() Use |vim.on_key()| instead.
|
||||
|
||||
NORMAL COMMANDS
|
||||
- *]f* *[f* Same as "gf".
|
||||
• *]f* *[f* Same as "gf".
|
||||
|
||||
OPTIONS
|
||||
- *cpo-<* *:menu-<special>* *:menu-special* *:map-<special>* *:map-special*
|
||||
• *cpo-<* *:menu-<special>* *:menu-special* *:map-<special>* *:map-special*
|
||||
`<>` notation is always enabled.
|
||||
- *'fe'* 'fenc'+'enc' before Vim 6.0; no longer used.
|
||||
- *'highlight'* *'hl'* Names of builtin |highlight-groups| cannot be changed.
|
||||
- *'langnoremap'* Deprecated alias to 'nolangremap'.
|
||||
- 'sessionoptions' Flags "unix", "slash" are ignored and always enabled.
|
||||
- *'vi'*
|
||||
- 'viewoptions' Flags "unix", "slash" are ignored and always enabled.
|
||||
- *'viminfo'* Deprecated alias to 'shada' option.
|
||||
- *'viminfofile'* Deprecated alias to 'shadafile' option.
|
||||
- *'paste'* *'nopaste'* Just Paste It.™ The 'paste' option is obsolete:
|
||||
• *'fe'* 'fenc'+'enc' before Vim 6.0; no longer used.
|
||||
• *'highlight'* *'hl'* Names of builtin |highlight-groups| cannot be changed.
|
||||
• *'langnoremap'* Deprecated alias to 'nolangremap'.
|
||||
• 'sessionoptions' Flags "unix", "slash" are ignored and always enabled.
|
||||
• *'vi'*
|
||||
• 'viewoptions' Flags "unix", "slash" are ignored and always enabled.
|
||||
• *'viminfo'* Deprecated alias to 'shada' option.
|
||||
• *'viminfofile'* Deprecated alias to 'shadafile' option.
|
||||
• *'paste'* *'nopaste'* Just Paste It.™ The 'paste' option is obsolete:
|
||||
|paste| is handled automatically when you paste text
|
||||
using your terminal's or GUI's paste feature
|
||||
(CTRL-SHIFT-v, CMD-v (macOS), middle-click, …).
|
||||
Enables "paste mode":
|
||||
- Disables mappings in Insert, Cmdline mode.
|
||||
- Disables abbreviations.
|
||||
- Resets 'autoindent' 'expandtab' 'revins' 'ruler'
|
||||
• Disables mappings in Insert, Cmdline mode.
|
||||
• Disables abbreviations.
|
||||
• Resets 'autoindent' 'expandtab' 'revins' 'ruler'
|
||||
'showmatch' 'smartindent' 'smarttab' 'softtabstop'
|
||||
'textwidth' 'wrapmargin'.
|
||||
- Treats 'formatoptions' as empty.
|
||||
- Disables the effect of these options:
|
||||
- 'cindent'
|
||||
- 'indentexpr'
|
||||
- 'lisp'
|
||||
• Treats 'formatoptions' as empty.
|
||||
• Disables the effect of these options:
|
||||
• 'cindent'
|
||||
• 'indentexpr'
|
||||
• 'lisp'
|
||||
|
||||
UI EXTENSIONS
|
||||
- *ui-wildmenu* Use |ui-cmdline| with |ui-popupmenu| instead. Enabled
|
||||
• *ui-wildmenu* Use |ui-cmdline| with |ui-popupmenu| instead. Enabled
|
||||
by the `ext_wildmenu` |ui-option|. Emits these events:
|
||||
- `["wildmenu_show", items]`
|
||||
- `["wildmenu_select", selected]`
|
||||
- `["wildmenu_hide"]`
|
||||
- *term_background* Unused. The terminal background color is now detected
|
||||
• `["wildmenu_show", items]`
|
||||
• `["wildmenu_select", selected]`
|
||||
• `["wildmenu_hide"]`
|
||||
• *term_background* Unused. The terminal background color is now detected
|
||||
by the Nvim core directly instead of the TUI.
|
||||
|
||||
VARIABLES
|
||||
- *b:terminal_job_pid* Use `jobpid(&channel)` instead.
|
||||
- *b:terminal_job_id* Use `&channel` instead. To access in non-current buffer:
|
||||
- Lua: `vim.bo[bufnr].channel`
|
||||
- Vimscript: `getbufvar(bufnr, '&channel')`
|
||||
• *b:terminal_job_pid* Use `jobpid(&channel)` instead.
|
||||
• *b:terminal_job_id* Use `&channel` instead. To access in non-current buffer:
|
||||
• Lua: `vim.bo[bufnr].channel`
|
||||
• Vimscript: `getbufvar(bufnr, '&channel')`
|
||||
|
||||
VIMSCRIPT
|
||||
• *buffer_exists()* Obsolete name for |bufexists()|.
|
||||
• *buffer_name()* Obsolete name for |bufname()|.
|
||||
• *buffer_number()* Obsolete name for |bufnr()|.
|
||||
• *file_readable()* Obsolete name for |filereadable()|.
|
||||
• *highlight_exists()* Obsolete name for |hlexists()|.
|
||||
• *highlightID()* Obsolete name for |hlID()|.
|
||||
• *inputdialog()* Use |input()| instead.
|
||||
• *jobclose()* Obsolete name for |chanclose()|
|
||||
• *jobsend()* Obsolete name for |chansend()|
|
||||
• *last_buffer_nr()* Obsolete name for bufnr("$").
|
||||
• *rpcstart()* Use |jobstart()| with `{'rpc': v:true}` instead.
|
||||
• *rpcstop()* Use |jobstop()| instead to stop any job, or
|
||||
`chanclose(id, "rpc")` to close RPC communication
|
||||
without stopping the job. Use chanclose(id) to close
|
||||
any socket.
|
||||
|
||||
|
||||
vim:noet:tw=78:ts=8:ft=help:norl:
|
||||
|
@ -46,11 +46,11 @@ Remember to bump NVIM_API_LEVEL if it wasn't already during this development
|
||||
cycle.
|
||||
|
||||
Other references:
|
||||
* |msgpack-rpc|
|
||||
* |ui|
|
||||
* https://github.com/neovim/neovim/pull/3246
|
||||
* https://github.com/neovim/neovim/pull/18375
|
||||
* https://github.com/neovim/neovim/pull/21605
|
||||
- |msgpack-rpc|
|
||||
- |ui|
|
||||
- https://github.com/neovim/neovim/pull/3246
|
||||
- https://github.com/neovim/neovim/pull/18375
|
||||
- https://github.com/neovim/neovim/pull/21605
|
||||
|
||||
|
||||
|
||||
|
@ -300,7 +300,7 @@ vim.paste in runtime/lua/vim/_editor.lua like this: >
|
||||
--- @returns false if client should cancel the paste.
|
||||
|
||||
|
||||
LUA STDLIB DESIGN GUIDELINES *dev-lua*
|
||||
STDLIB DESIGN GUIDELINES *dev-lua*
|
||||
|
||||
See also |dev-naming|.
|
||||
|
||||
@ -337,7 +337,7 @@ preference):
|
||||
way. Advantage is that propagation happens for free and it's harder to
|
||||
accidentally swallow errors. (E.g. using
|
||||
`uv_handle/pipe:write()` without checking return values is common.)
|
||||
4. `on_error` parameter
|
||||
4. `on_error` callback
|
||||
- For async and "visitors" traversing a graph, where many errors may be
|
||||
collected while work continues.
|
||||
5. `vim.notify` (sometimes with optional `opts.silent` (async, visitors ^))
|
||||
@ -434,7 +434,9 @@ Use existing common {verb} names (actions) if possible:
|
||||
- eval: Evaluates an expression
|
||||
- exec: Executes code, may return a result
|
||||
- fmt: Formats
|
||||
- get: Gets things (often by a query)
|
||||
- get: Gets things. Two variants (overloads):
|
||||
1. `get<T>(id: int): T` returns one item.
|
||||
2. `get<T>(filter: dict): T[]` returns a list.
|
||||
- inspect: Presents a high-level, often interactive, view
|
||||
- is_enabled: Checks if functionality is enabled.
|
||||
- open: Opens something (a buffer, window, …)
|
||||
|
@ -163,6 +163,33 @@ show a sign for the highest severity diagnostic on a given line: >lua
|
||||
}
|
||||
<
|
||||
|
||||
*diagnostic-loclist-example*
|
||||
Whenever the |location-list| is opened, the following `show` handler will show
|
||||
the most recent diagnostics: >lua
|
||||
|
||||
vim.diagnostic.handlers.loclist = {
|
||||
show = function(_, _, _, opts)
|
||||
-- Generally don't want it to open on every update
|
||||
opts.loclist.open = opts.loclist.open or false
|
||||
local winid = vim.api.nvim_get_current_win()
|
||||
vim.diagnostic.setloclist(opts.loclist)
|
||||
vim.api.nvim_set_current_win(winid)
|
||||
end
|
||||
}
|
||||
<
|
||||
|
||||
The handler accepts the same options as |vim.diagnostic.setloclist()| and can be
|
||||
configured using |vim.diagnostic.config()|: >lua
|
||||
|
||||
-- Open the location list on every diagnostic change (warnings/errors only).
|
||||
vim.diagnostic.config({
|
||||
loclist = {
|
||||
open = true,
|
||||
severity = { min = vim.diagnostic.severity.WARN },
|
||||
}
|
||||
})
|
||||
<
|
||||
|
||||
==============================================================================
|
||||
HIGHLIGHTS *diagnostic-highlights*
|
||||
|
||||
@ -847,7 +874,8 @@ setqflist({opts}) *vim.diagnostic.setqflist()*
|
||||
• {open}? (`boolean`, default: `true`) Open quickfix list
|
||||
after setting.
|
||||
• {title}? (`string`) Title of quickfix list. Defaults to
|
||||
"Diagnostics".
|
||||
"Diagnostics". If there's already a quickfix list with this
|
||||
title, it's updated. If not, a new quickfix list is created.
|
||||
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
||||
|diagnostic-severity|.
|
||||
|
||||
|
@ -597,7 +597,7 @@ To disable this behavior, set the following variable in your vimrc: >
|
||||
let g:gdscript_recommended_style = 0
|
||||
|
||||
|
||||
GIT COMMIT *ft-gitcommit-plugin*
|
||||
GIT COMMIT *ft-gitcommit-plugin*
|
||||
|
||||
One command, :DiffGitCached, is provided to show a diff of the current commit
|
||||
in the preview window. It is equivalent to calling "git diff --cached" plus
|
||||
@ -778,7 +778,7 @@ An alternative to using `MANPAGER` in shell can be redefined `man`, for example:
|
||||
nvim "+hide Man $1"
|
||||
}
|
||||
|
||||
MARKDOWN *ft-markdown-plugin*
|
||||
MARKDOWN *ft-markdown-plugin*
|
||||
|
||||
To enable folding use this: >
|
||||
let g:markdown_folding = 1
|
||||
@ -870,7 +870,7 @@ To enable this behavior, set the following variable in your vimrc: >
|
||||
let g:rst_style = 1
|
||||
|
||||
|
||||
RNOWEB *ft-rnoweb-plugin*
|
||||
RNOWEB *ft-rnoweb-plugin*
|
||||
|
||||
The 'formatexpr' option is set dynamically with different values for R code
|
||||
and for LaTeX code. If you prefer that 'formatexpr' is not set, add to your
|
||||
|
@ -82,9 +82,11 @@ The most efficient is to call a function without arguments: >
|
||||
The function must use v:lnum. See |expr-option-function|.
|
||||
|
||||
These are the conditions with which the expression is evaluated:
|
||||
|
||||
- The current buffer and window are set for the line.
|
||||
- The variable "v:lnum" is set to the line number.
|
||||
- The result is used for the fold level in this way:
|
||||
|
||||
The result of foldexpr then determines the fold level as follows:
|
||||
value meaning ~
|
||||
0 the line is not in a fold
|
||||
1, 2, .. the line is in a fold with this level
|
||||
@ -99,6 +101,8 @@ These are the conditions with which the expression is evaluated:
|
||||
"<1", "<2", .. a fold with this level ends at this line
|
||||
">1", ">2", .. a fold with this level starts at this line
|
||||
|
||||
The result values "=", "s" and "a" are more expensive, please see |fold-expr-slow|.
|
||||
|
||||
It is not required to mark the start (end) of a fold with ">1" ("<1"), a fold
|
||||
will also start (end) when the fold level is higher (lower) than the fold
|
||||
level of the previous line.
|
||||
@ -112,12 +116,6 @@ recognized, there is no error message and the fold level will be zero.
|
||||
For debugging the 'debug' option can be set to "msg", the error messages will
|
||||
be visible then.
|
||||
|
||||
Note: Since the expression has to be evaluated for every line, this fold
|
||||
method can be very slow!
|
||||
|
||||
Try to avoid the "=", "a" and "s" return values, since Vim often has to search
|
||||
backwards for a line for which the fold level is defined. This can be slow.
|
||||
|
||||
If the 'foldexpr' expression starts with s: or |<SID>|, then it is replaced
|
||||
with the script ID (|local-function|). Examples: >
|
||||
set foldexpr=s:MyFoldExpr()
|
||||
@ -143,6 +141,35 @@ end in that line.
|
||||
It may happen that folds are not updated properly. You can use |zx| or |zX|
|
||||
to force updating folds.
|
||||
|
||||
Minimizing Computational Cost *fold-expr-slow*
|
||||
|
||||
Due to its computational cost, this fold method can make Vim unresponsive,
|
||||
especially when the fold level of all lines have to be initially computed.
|
||||
Afterwards, after each change, Vim restricts the computation of foldlevels
|
||||
to those lines whose fold level was affected by it (and reuses the known
|
||||
foldlevels of all the others).
|
||||
|
||||
The fold expression should therefore strive to minimize the number of dependent
|
||||
lines needed for the computation of a given line: For example, try to avoid the
|
||||
"=", "a" and "s" return values, because these will require the evaluation of the
|
||||
fold levels on previous lines until an independent fold level is found.
|
||||
|
||||
If this proves difficult, the next best thing could be to cache all fold levels
|
||||
in a buffer-local variable (b:foldlevels) that is only updated on |b:changedtick|:
|
||||
>vim
|
||||
func MyFoldFunc()
|
||||
if b:lasttick == b:changedtick
|
||||
return b:foldlevels[v:lnum - 1]
|
||||
endif
|
||||
let b:lasttick = b:changedtick
|
||||
let b:foldlevels = []
|
||||
" compute foldlevels ...
|
||||
return b:foldlevels[v:lnum - 1]
|
||||
enddef
|
||||
set foldexpr=s:MyFoldFunc()
|
||||
<
|
||||
In above example further speedup was gained by using a function without
|
||||
arguments (that must still use v:lnum). See |expr-option-function|.
|
||||
|
||||
SYNTAX *fold-syntax*
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
*gui.txt* Nvim
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
|
||||
|
||||
Nvim Graphical User Interface *gui* *GUI*
|
||||
Nvim Graphical User Interface *gui* *GUI*
|
||||
|
||||
Any client that supports the Nvim |ui-protocol| can be used as a UI for Nvim.
|
||||
And multiple UIs can connect to the same Nvim instance! The terms "UI" and
|
||||
@ -20,8 +20,9 @@ features, whereas help tags with the "ui-" prefix refer to the |ui-protocol|.
|
||||
Nvim provides a default, builtin UI (the |TUI|), but there are many other
|
||||
(third-party) GUIs that you can use instead:
|
||||
|
||||
- Firenvim (Nvim in your web browser!) https://github.com/glacambre/firenvim
|
||||
*vscode*
|
||||
- vscode-neovim (Nvim in VSCode!) https://github.com/vscode-neovim/vscode-neovim
|
||||
- Firenvim (Nvim in your web browser!) https://github.com/glacambre/firenvim
|
||||
- Neovide https://neovide.dev/
|
||||
- Goneovim https://github.com/akiyosi/goneovim
|
||||
- Nvy https://github.com/RMichelsen/Nvy
|
||||
@ -32,71 +33,71 @@ Nvim provides a default, builtin UI (the |TUI|), but there are many other
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
Starting the GUI *gui-config* *gui-start*
|
||||
Starting the GUI *gui-config* *gui-start*
|
||||
|
||||
*ginit.vim* *gui-init* *gvimrc* *$MYGVIMRC*
|
||||
*ginit.vim* *gui-init* *gvimrc* *$MYGVIMRC*
|
||||
For GUI-specific configuration Nvim provides the |UIEnter| event. This
|
||||
happens after other |initialization|s, or whenever a UI attaches (multiple UIs
|
||||
can connect to any Nvim instance).
|
||||
|
||||
Example: this sets "g:gui" to the value of the UI's "rgb" field: >
|
||||
:autocmd UIEnter * let g:gui = filter(nvim_list_uis(),{k,v-> v.chan==v:event.chan})[0].rgb
|
||||
:autocmd UIEnter * let g:gui = filter(nvim_list_uis(),{k,v-> v.chan==v:event.chan})[0].rgb
|
||||
<
|
||||
|
||||
*:winp* *:winpos* *E188*
|
||||
*:winp* *:winpos* *E188*
|
||||
:winp[os]
|
||||
Display current position of the top left corner of the GUI vim
|
||||
window in pixels. Does not work in all versions.
|
||||
Also see |getwinpos()|, |getwinposx()| and |getwinposy()|.
|
||||
Display current position of the top left corner of the GUI vim
|
||||
window in pixels. Does not work in all versions.
|
||||
Also see |getwinpos()|, |getwinposx()| and |getwinposy()|.
|
||||
|
||||
:winp[os] {X} {Y} *E466*
|
||||
Put the GUI vim window at the given {X} and {Y} coordinates.
|
||||
The coordinates should specify the position in pixels of the
|
||||
top left corner of the window.
|
||||
When the GUI window has not been opened yet, the values are
|
||||
remembered until the window is opened. The position is
|
||||
adjusted to make the window fit on the screen (if possible).
|
||||
:winp[os] {X} {Y} *E466*
|
||||
Put the GUI vim window at the given {X} and {Y} coordinates.
|
||||
The coordinates should specify the position in pixels of the
|
||||
top left corner of the window.
|
||||
When the GUI window has not been opened yet, the values are
|
||||
remembered until the window is opened. The position is
|
||||
adjusted to make the window fit on the screen (if possible).
|
||||
|
||||
*:wi* *:win* *:winsize* *E465*
|
||||
*:wi* *:win* *:winsize* *E465*
|
||||
:win[size] {width} {height}
|
||||
Set the window height to {width} by {height} characters.
|
||||
Obsolete, use ":set lines=11 columns=22".
|
||||
Set the window height to {width} by {height} characters.
|
||||
Obsolete, use ":set lines=11 columns=22".
|
||||
|
||||
==============================================================================
|
||||
Scrollbars *gui-scrollbars*
|
||||
Scrollbars *gui-scrollbars*
|
||||
|
||||
There are vertical scrollbars and a horizontal scrollbar. You may
|
||||
configure which ones appear with the 'guioptions' option.
|
||||
|
||||
The interface looks like this (with `:set guioptions=mlrb`):
|
||||
>
|
||||
+------------------------------+ `
|
||||
| File Edit Help | <- Menu bar (m) `
|
||||
+-+--------------------------+-+ `
|
||||
|^| |^| `
|
||||
|#| Text area. |#| `
|
||||
| | | | `
|
||||
|v|__________________________|v| `
|
||||
Normal status line -> |-+ File.c 5,2 +-| `
|
||||
+------------------------------+ `
|
||||
| File Edit Help | <- Menu bar (m) `
|
||||
+-+--------------------------+-+ `
|
||||
|^| |^| `
|
||||
|#| Text area. |#| `
|
||||
| | | | `
|
||||
|v|__________________________|v| `
|
||||
Normal status line -> |-+ File.c 5,2 +-| `
|
||||
between Vim windows |^|""""""""""""""""""""""""""|^| `
|
||||
| | | | `
|
||||
| | Another file buffer. | | `
|
||||
| | | | `
|
||||
|#| |#| `
|
||||
Left scrollbar (l) -> |#| |#| <- Right `
|
||||
|#| |#| scrollbar (r) `
|
||||
| | | | `
|
||||
|v| |v| `
|
||||
+-+--------------------------+-+ `
|
||||
| |< #### >| | <- Bottom `
|
||||
+-+--------------------------+-+ scrollbar (b) `
|
||||
| | | | `
|
||||
| | Another file buffer. | | `
|
||||
| | | | `
|
||||
|#| |#| `
|
||||
Left scrollbar (l) -> |#| |#| <- Right `
|
||||
|#| |#| scrollbar (r) `
|
||||
| | | | `
|
||||
|v| |v| `
|
||||
+-+--------------------------+-+ `
|
||||
| |< #### >| | <- Bottom `
|
||||
+-+--------------------------+-+ scrollbar (b) `
|
||||
<
|
||||
Any of the scrollbar or menu components may be turned off by not putting the
|
||||
appropriate letter in the 'guioptions' string. The bottom scrollbar is
|
||||
only useful when 'nowrap' is set.
|
||||
|
||||
|
||||
VERTICAL SCROLLBARS *gui-vert-scroll*
|
||||
VERTICAL SCROLLBARS *gui-vert-scroll*
|
||||
|
||||
Each Vim window has a scrollbar next to it which may be scrolled up and down
|
||||
to move through the text in that buffer. The size of the scrollbar-thumb
|
||||
@ -115,7 +116,7 @@ is on the left half, the right scrollbar column will contain scrollbars for
|
||||
the rightmost windows. The same happens on the other side.
|
||||
|
||||
|
||||
HORIZONTAL SCROLLBARS *gui-horiz-scroll*
|
||||
HORIZONTAL SCROLLBARS *gui-horiz-scroll*
|
||||
|
||||
The horizontal scrollbar (at the bottom of the Vim GUI) may be used to
|
||||
scroll text sideways when the 'wrap' option is turned off. The
|
||||
@ -131,7 +132,7 @@ include the 'h' flag in 'guioptions'. Then the scrolling is limited by the
|
||||
text of the current cursor line.
|
||||
|
||||
==============================================================================
|
||||
Drag and drop *drag-n-drop*
|
||||
Drag and drop *drag-n-drop*
|
||||
|
||||
You can drag and drop one or more files into the Vim window, where they will
|
||||
be opened as if a |:drop| command was used.
|
||||
@ -150,12 +151,12 @@ names with any Ex command. Special characters (space, tab, double quote and
|
||||
"|"; backslash on non-MS-Windows systems) will be escaped.
|
||||
|
||||
==============================================================================
|
||||
Menus *menus*
|
||||
Menus *menus*
|
||||
|
||||
For an introduction see |usr_42.txt| in the user manual.
|
||||
|
||||
|
||||
Using Menus *using-menus*
|
||||
Using Menus *using-menus*
|
||||
|
||||
Basically, menus can be used just like mappings. You can define your own
|
||||
menus, as many as you like.
|
||||
@ -165,45 +166,45 @@ what the key sequence was.
|
||||
|
||||
For creating menus in a different language, see |:menutrans|.
|
||||
|
||||
*menu.vim*
|
||||
*menu.vim*
|
||||
The default menus are read from the file "$VIMRUNTIME/menu.vim". See
|
||||
|$VIMRUNTIME| for where the path comes from. You can set up your own menus.
|
||||
Starting off with the default set is a good idea. You can add more items, or,
|
||||
if you don't like the defaults at all, start with removing all menus
|
||||
|:unmenu-all|. You can also avoid the default menus being loaded by adding
|
||||
this line to your vimrc file (NOT your gvimrc file!): >
|
||||
:let did_install_default_menus = 1
|
||||
:let did_install_default_menus = 1
|
||||
If you also want to avoid the Syntax menu: >
|
||||
:let did_install_syntax_menu = 1
|
||||
:let did_install_syntax_menu = 1
|
||||
The first item in the Syntax menu can be used to show all available filetypes
|
||||
in the menu (which can take a bit of time to load). If you want to have all
|
||||
filetypes already present at startup, add: >
|
||||
:let do_syntax_sel_menu = 1
|
||||
:let do_syntax_sel_menu = 1
|
||||
|
||||
Note that the menu.vim is sourced when `:syntax on` or `:filetype on` is
|
||||
executed or after your .vimrc file is sourced. This means that the 'encoding'
|
||||
option and the language of messages (`:language messages`) must be set before
|
||||
that (if you want to change them).
|
||||
|
||||
*console-menus*
|
||||
*console-menus*
|
||||
Although this documentation is in the GUI section, you can actually use menus
|
||||
in console mode too. You will have to load |menu.vim| explicitly then, it is
|
||||
not done by default. You can use the |:emenu| command and command-line
|
||||
completion with 'wildmenu' to access the menu entries almost like a real menu
|
||||
system. To do this, put these commands in your vimrc file: >
|
||||
:source $VIMRUNTIME/menu.vim
|
||||
:set wildmenu
|
||||
:set cpo-=<
|
||||
:set wcm=<C-Z>
|
||||
:map <F4> :emenu <C-Z>
|
||||
:source $VIMRUNTIME/menu.vim
|
||||
:set wildmenu
|
||||
:set cpo-=<
|
||||
:set wcm=<C-Z>
|
||||
:map <F4> :emenu <C-Z>
|
||||
Pressing <F4> will start the menu. You can now use the cursor keys to select
|
||||
a menu entry. Hit <Enter> to execute it. Hit <Esc> if you want to cancel.
|
||||
|
||||
Creating New Menus *creating-menus*
|
||||
Creating New Menus *creating-menus*
|
||||
|
||||
*:me* *:menu* *:noreme* *:noremenu*
|
||||
*E330* *E327* *E331* *E336* *E333*
|
||||
*E328* *E329* *E337* *E792*
|
||||
*:me* *:menu* *:noreme* *:noremenu*
|
||||
*E330* *E327* *E331* *E336* *E333*
|
||||
*E328* *E329* *E337* *E792*
|
||||
To create a new menu item, use the ":menu" commands. They are mostly like
|
||||
the ":map" set of commands (see |map-modes|), but the first argument is a menu
|
||||
item name, given as a path of menus and submenus with a '.' between them,
|
||||
@ -224,15 +225,16 @@ tooltips for menus. See |terminal-input|.
|
||||
|
||||
Special characters in a menu name:
|
||||
|
||||
*menu-shortcut*
|
||||
& The next character is the shortcut key. Make sure each
|
||||
shortcut key is only used once in a (sub)menu. If you want to
|
||||
insert a literal "&" in the menu name use "&&".
|
||||
*menu-text*
|
||||
<Tab> Separates the menu name from right-aligned text. This can be
|
||||
used to show the equivalent typed command. The text "<Tab>"
|
||||
can be used here for convenience. If you are using a real
|
||||
tab, don't forget to put a backslash before it!
|
||||
*menu-shortcut*
|
||||
- & The next character is the shortcut key. Make sure each shortcut key is
|
||||
only used once in a (sub)menu. If you want to insert a literal "&" in the
|
||||
menu name use "&&".
|
||||
*menu-text*
|
||||
- <Tab> Separates the menu name from right-aligned text. This can be used to
|
||||
show the equivalent typed command. The text "<Tab>" can be used here for
|
||||
convenience. If you are using a real tab, don't forget to put a backslash
|
||||
before it!
|
||||
|
||||
Example: >
|
||||
|
||||
:amenu &File.&Open<Tab>:e :browse e<CR>
|
||||
@ -242,99 +244,99 @@ With the shortcut "F" (while keeping the <Alt> key pressed), and then "O",
|
||||
this menu can be used. The second part is shown as "Open :e". The ":e"
|
||||
is right aligned, and the "O" is underlined, to indicate it is the shortcut.
|
||||
|
||||
*:am* *:amenu* *:an* *:anoremenu*
|
||||
*:am* *:amenu* *:an* *:anoremenu*
|
||||
The ":amenu" command can be used to define menu entries for all modes at once,
|
||||
except for Terminal mode. To make the command work correctly, a character is
|
||||
automatically inserted for some modes:
|
||||
mode inserted appended ~
|
||||
Normal nothing nothing
|
||||
Visual <C-C> <C-\><C-G>
|
||||
Insert <C-\><C-O>
|
||||
Cmdline <C-C> <C-\><C-G>
|
||||
Op-pending <C-C> <C-\><C-G>
|
||||
|
||||
automatically inserted for some modes: >
|
||||
mode inserted appended
|
||||
Normal nothing nothing
|
||||
Visual <C-C> <C-\><C-G>
|
||||
Insert <C-\><C-O>
|
||||
Cmdline <C-C> <C-\><C-G>
|
||||
Op-pending <C-C> <C-\><C-G>
|
||||
<
|
||||
Example: >
|
||||
|
||||
:amenu File.Next :next^M
|
||||
:amenu File.Next :next^M
|
||||
|
||||
is equal to: >
|
||||
|
||||
:nmenu File.Next :next^M
|
||||
:vmenu File.Next ^C:next^M^\^G
|
||||
:imenu File.Next ^\^O:next^M
|
||||
:cmenu File.Next ^C:next^M^\^G
|
||||
:omenu File.Next ^C:next^M^\^G
|
||||
:nmenu File.Next :next^M
|
||||
:vmenu File.Next ^C:next^M^\^G
|
||||
:imenu File.Next ^\^O:next^M
|
||||
:cmenu File.Next ^C:next^M^\^G
|
||||
:omenu File.Next ^C:next^M^\^G
|
||||
|
||||
Careful: In Insert mode this only works for a SINGLE Normal mode command,
|
||||
because of the CTRL-O. If you have two or more commands, you will need to use
|
||||
the ":imenu" command. For inserting text in any mode, you can use the
|
||||
expression register: >
|
||||
|
||||
:amenu Insert.foobar "='foobar'<CR>P
|
||||
:amenu Insert.foobar "='foobar'<CR>P
|
||||
|
||||
The special text <Cmd> begins a "command menu", it executes the command
|
||||
directly without changing modes. Where you might use ":...<CR>" you can
|
||||
instead use "<Cmd>...<CR>". See |<Cmd>| for more info. Example: >
|
||||
anoremenu File.Next <Cmd>next<CR>
|
||||
anoremenu File.Next <Cmd>next<CR>
|
||||
|
||||
Note that <Esc> in Cmdline mode executes the command, like in a mapping. This
|
||||
is Vi compatible. Use CTRL-C to quit Cmdline mode.
|
||||
|
||||
*:nme* *:nmenu* *:nnoreme* *:nnoremenu* *:nunme* *:nunmenu*
|
||||
*:nme* *:nmenu* *:nnoreme* *:nnoremenu* *:nunme* *:nunmenu*
|
||||
Menu commands starting with "n" work in Normal mode. |mapmode-n|
|
||||
|
||||
*:ome* *:omenu* *:onoreme* *:onoremenu* *:ounme* *:ounmenu*
|
||||
*:ome* *:omenu* *:onoreme* *:onoremenu* *:ounme* *:ounmenu*
|
||||
Menu commands starting with "o" work in Operator-pending mode. |mapmode-o|
|
||||
|
||||
*:vme* *:vmenu* *:vnoreme* *:vnoremenu* *:vunme* *:vunmenu*
|
||||
*:vme* *:vmenu* *:vnoreme* *:vnoremenu* *:vunme* *:vunmenu*
|
||||
Menu commands starting with "v" work in Visual mode. |mapmode-v|
|
||||
|
||||
*:xme* *:xmenu* *:xnoreme* *:xnoremenu* *:xunme* *:xunmenu*
|
||||
*:xme* *:xmenu* *:xnoreme* *:xnoremenu* *:xunme* *:xunmenu*
|
||||
Menu commands starting with "x" work in Visual and Select mode. |mapmode-x|
|
||||
|
||||
*:sme* *:smenu* *:snoreme* *:snoremenu* *:sunme* *:sunmenu*
|
||||
*:sme* *:smenu* *:snoreme* *:snoremenu* *:sunme* *:sunmenu*
|
||||
Menu commands starting with "s" work in Select mode. |mapmode-s|
|
||||
|
||||
*:ime* *:imenu* *:inoreme* *:inoremenu* *:iunme* *:iunmenu*
|
||||
*:ime* *:imenu* *:inoreme* *:inoremenu* *:iunme* *:iunmenu*
|
||||
Menu commands starting with "i" work in Insert mode. |mapmode-i|
|
||||
|
||||
*:cme* *:cmenu* *:cnoreme* *:cnoremenu* *:cunme* *:cunmenu*
|
||||
*:cme* *:cmenu* *:cnoreme* *:cnoremenu* *:cunme* *:cunmenu*
|
||||
Menu commands starting with "c" work in Cmdline mode. |mapmode-c|
|
||||
|
||||
*:tlm* *:tlmenu* *:tln* *:tlnoremenu* *:tlu* *:tlunmenu*
|
||||
*:tlm* *:tlmenu* *:tln* *:tlnoremenu* *:tlu* *:tlunmenu*
|
||||
Menu commands starting with "tl" work in Terminal mode. |mapmode-t|
|
||||
|
||||
*:menu-<silent>* *:menu-silent*
|
||||
*:menu-<silent>* *:menu-silent*
|
||||
To define a menu which will not be echoed on the command line, add
|
||||
"<silent>" as the first argument. Example: >
|
||||
:menu <silent> Settings.Ignore\ case :set ic<CR>
|
||||
:menu <silent> Settings.Ignore\ case :set ic<CR>
|
||||
The ":set ic" will not be echoed when using this menu. Messages from the
|
||||
executed command are still given though. To shut them up too, add a ":silent"
|
||||
in the executed command: >
|
||||
:menu <silent> Search.Header :exe ":silent normal /Header\r"<CR>
|
||||
:menu <silent> Search.Header :exe ":silent normal /Header\r"<CR>
|
||||
"<silent>" may also appear just after "<script>".
|
||||
|
||||
*:menu-<script>* *:menu-script*
|
||||
*:menu-<script>* *:menu-script*
|
||||
The "to" part of the menu will be inspected for mappings. If you don't want
|
||||
this, use the ":noremenu" command (or the similar one for a specific mode).
|
||||
If you do want to use script-local mappings, add "<script>" as the very first
|
||||
argument to the ":menu" command or just after "<silent>".
|
||||
|
||||
*menu-priority*
|
||||
*menu-priority*
|
||||
You can give a priority to a menu. Menus with a higher priority go more to
|
||||
the right. The priority is given as a number before the ":menu" command.
|
||||
Example: >
|
||||
:80menu Buffer.next :bn<CR>
|
||||
|
||||
The default menus have these priorities:
|
||||
File 10
|
||||
Edit 20
|
||||
Tools 40
|
||||
Syntax 50
|
||||
Buffers 60
|
||||
Window 70
|
||||
Help 9999
|
||||
:80menu Buffer.next :bn<CR>
|
||||
|
||||
The default menus have these priorities: >
|
||||
File 10
|
||||
Edit 20
|
||||
Tools 40
|
||||
Syntax 50
|
||||
Buffers 60
|
||||
Window 70
|
||||
Help 9999
|
||||
<
|
||||
When no or zero priority is given, 500 is used.
|
||||
The priority for the PopUp menu is not used.
|
||||
|
||||
@ -342,18 +344,18 @@ You can use a priority higher than 9999, to make it go after the Help menu,
|
||||
but that is non-standard and is discouraged. The highest possible priority is
|
||||
about 32000. The lowest is 1.
|
||||
|
||||
*sub-menu-priority*
|
||||
*sub-menu-priority*
|
||||
The same mechanism can be used to position a sub-menu. The priority is then
|
||||
given as a dot-separated list of priorities, before the menu name: >
|
||||
:menu 80.500 Buffer.next :bn<CR>
|
||||
:menu 80.500 Buffer.next :bn<CR>
|
||||
Giving the sub-menu priority is only needed when the item is not to be put
|
||||
in a normal position. For example, to put a sub-menu before the other items: >
|
||||
:menu 80.100 Buffer.first :brew<CR>
|
||||
:menu 80.100 Buffer.first :brew<CR>
|
||||
Or to put a sub-menu after the other items, and further items with default
|
||||
priority will be put before it: >
|
||||
:menu 80.900 Buffer.last :blast<CR>
|
||||
:menu 80.900 Buffer.last :blast<CR>
|
||||
When a number is missing, the default value 500 will be used: >
|
||||
:menu .900 myMenu.test :echo "text"<CR>
|
||||
:menu .900 myMenu.test :echo "text"<CR>
|
||||
The menu priority is only used when creating a new menu. When it already
|
||||
existed, e.g., in another mode, the priority will not change. Thus, the
|
||||
priority only needs to be given the first time a menu is used.
|
||||
@ -363,49 +365,49 @@ menus can be different. This is different from menu-bar menus, which have
|
||||
the same order for all modes.
|
||||
NOTE: sub-menu priorities currently don't work for all versions of the GUI.
|
||||
|
||||
*menu-separator* *E332*
|
||||
*menu-separator* *E332*
|
||||
Menu items can be separated by a special item that inserts some space between
|
||||
items. Depending on the system this is displayed as a line or a dotted line.
|
||||
These items must start with a '-' and end in a '-'. The part in between is
|
||||
used to give it a unique name. Priorities can be used as with normal items.
|
||||
Example: >
|
||||
:menu Example.item1 :do something
|
||||
:menu Example.-Sep- :
|
||||
:menu Example.item2 :do something different
|
||||
:menu Example.item1 :do something
|
||||
:menu Example.-Sep- :
|
||||
:menu Example.item2 :do something different
|
||||
Note that the separator also requires a rhs. It doesn't matter what it is,
|
||||
because the item will never be selected. Use a single colon to keep it
|
||||
simple.
|
||||
|
||||
*gui-toolbar*
|
||||
*gui-toolbar*
|
||||
The default toolbar is setup in menu.vim. The display of the toolbar is
|
||||
controlled by the 'guioptions' letter 'T'. You can thus have menu & toolbar
|
||||
together, or either on its own, or neither. The appearance is controlled by
|
||||
the 'toolbar' option. You can choose between an image, text or both.
|
||||
|
||||
*toolbar-icon*
|
||||
*toolbar-icon*
|
||||
The toolbar is defined as a special menu called ToolBar, which only has one
|
||||
level. Vim interprets the items in this menu as follows:
|
||||
1) If an "icon=" argument was specified, the file with this name is used.
|
||||
- 1 If an "icon=" argument was specified, the file with this name is used.
|
||||
The file can either be specified with the full path or with the base name.
|
||||
In the last case it is searched for in the "bitmaps" directory in
|
||||
'runtimepath', like in point 3. Examples: >
|
||||
:amenu icon=/usr/local/pixmaps/foo_icon.xpm ToolBar.Foo :echo "Foo"<CR>
|
||||
:amenu icon=FooIcon ToolBar.Foo :echo "Foo"<CR>
|
||||
:amenu icon=/usr/local/pixmaps/foo_icon.xpm ToolBar.Foo :echo "Foo"<CR>
|
||||
:amenu icon=FooIcon ToolBar.Foo :echo "Foo"<CR>
|
||||
< Note that in the first case the extension is included, while in the second
|
||||
case it is omitted.
|
||||
If the file cannot be opened the next points are tried.
|
||||
A space in the file name must be escaped with a backslash.
|
||||
A menu priority must come _after_ the icon argument: >
|
||||
:amenu icon=foo 1.42 ToolBar.Foo :echo "42!"<CR>
|
||||
2) An item called 'BuiltIn##', where ## is a number, is taken as number ## of
|
||||
:amenu icon=foo 1.42 ToolBar.Foo :echo "42!"<CR>
|
||||
- 2 An item called 'BuiltIn##', where ## is a number, is taken as number ## of
|
||||
the built-in bitmaps available in Vim. Currently there are 31 numbered
|
||||
from 0 to 30 which cover most common editing operations |builtin-tools|. >
|
||||
:amenu ToolBar.BuiltIn22 :call SearchNext("back")<CR>
|
||||
3) An item with another name is first searched for in the directory
|
||||
:amenu ToolBar.BuiltIn22 :call SearchNext("back")<CR>
|
||||
- 3 An item with another name is first searched for in the directory
|
||||
"bitmaps" in 'runtimepath'. If found, the bitmap file is used as the
|
||||
toolbar button image. Note that the exact filename is OS-specific: For
|
||||
example, under Win32 the command >
|
||||
:amenu ToolBar.Hello :echo "hello"<CR>
|
||||
:amenu ToolBar.Hello :echo "hello"<CR>
|
||||
< would find the file 'hello.bmp'. Under X11 it is 'Hello.xpm'.
|
||||
For MS-Windows and the bitmap is scaled to fit the button. For
|
||||
MS-Windows a size of 18 by 18 pixels works best.
|
||||
@ -413,55 +415,56 @@ level. Vim interprets the items in this menu as follows:
|
||||
The light grey pixels will be changed to the Window frame color and the
|
||||
dark grey pixels to the window shadow color. More colors might also work,
|
||||
depending on your system.
|
||||
4) If the bitmap is still not found, Vim checks for a match against its list
|
||||
- 4 If the bitmap is still not found, Vim checks for a match against its list
|
||||
of built-in names. Each built-in button image has a name.
|
||||
So the command >
|
||||
:amenu ToolBar.Open :e
|
||||
:amenu ToolBar.Open :e
|
||||
< will show the built-in "open a file" button image if no open.bmp exists.
|
||||
All the built-in names can be seen used in menu.vim.
|
||||
5) If all else fails, a blank, but functioning, button is displayed.
|
||||
- 5 If all else fails, a blank, but functioning, button is displayed.
|
||||
|
||||
*builtin-tools*
|
||||
nr Name Normal action ~
|
||||
00 New open new window
|
||||
01 Open browse for file to open in current window
|
||||
02 Save write buffer to file
|
||||
03 Undo undo last change
|
||||
04 Redo redo last undone change
|
||||
05 Cut delete selected text to clipboard
|
||||
06 Copy copy selected text to clipboard
|
||||
07 Paste paste text from clipboard
|
||||
08 Print print current buffer
|
||||
09 Help open a buffer on Vim's builtin help
|
||||
10 Find start a search command
|
||||
11 SaveAll write all modified buffers to file
|
||||
12 SaveSesn write session file for current situation
|
||||
13 NewSesn write new session file
|
||||
14 LoadSesn load session file
|
||||
15 RunScript browse for file to run as a Vim script
|
||||
16 Replace prompt for substitute command
|
||||
17 WinClose close current window
|
||||
18 WinMax make current window use many lines
|
||||
19 WinMin make current window use few lines
|
||||
20 WinSplit split current window
|
||||
21 Shell start a shell
|
||||
22 FindPrev search again, backward
|
||||
23 FindNext search again, forward
|
||||
24 FindHelp prompt for word to search help for
|
||||
25 Make run make and jump to first error
|
||||
26 TagJump jump to tag under the cursor
|
||||
27 RunCtags build tags for files in current directory
|
||||
28 WinVSplit split current window vertically
|
||||
29 WinMaxWidth make current window use many columns
|
||||
30 WinMinWidth make current window use few columns
|
||||
|
||||
*hidden-menus* *win32-hidden-menus*
|
||||
*builtin-tools*
|
||||
>
|
||||
nr Name Normal action
|
||||
00 New open new window
|
||||
01 Open browse for file to open in current window
|
||||
02 Save write buffer to file
|
||||
03 Undo undo last change
|
||||
04 Redo redo last undone change
|
||||
05 Cut delete selected text to clipboard
|
||||
06 Copy copy selected text to clipboard
|
||||
07 Paste paste text from clipboard
|
||||
08 Print print current buffer
|
||||
09 Help open a buffer on Vim's builtin help
|
||||
10 Find start a search command
|
||||
11 SaveAll write all modified buffers to file
|
||||
12 SaveSesn write session file for current situation
|
||||
13 NewSesn write new session file
|
||||
14 LoadSesn load session file
|
||||
15 RunScript browse for file to run as a Vim script
|
||||
16 Replace prompt for substitute command
|
||||
17 WinClose close current window
|
||||
18 WinMax make current window use many lines
|
||||
19 WinMin make current window use few lines
|
||||
20 WinSplit split current window
|
||||
21 Shell start a shell
|
||||
22 FindPrev search again, backward
|
||||
23 FindNext search again, forward
|
||||
24 FindHelp prompt for word to search help for
|
||||
25 Make run make and jump to first error
|
||||
26 TagJump jump to tag under the cursor
|
||||
27 RunCtags build tags for files in current directory
|
||||
28 WinVSplit split current window vertically
|
||||
29 WinMaxWidth make current window use many columns
|
||||
30 WinMinWidth make current window use few columns
|
||||
<
|
||||
*hidden-menus* *win32-hidden-menus*
|
||||
In the Win32 GUI, starting a menu name with ']' excludes that menu from the
|
||||
main menu bar. You must then use the |:popup| command to display it.
|
||||
|
||||
When splitting the window the window toolbar is not copied to the new window.
|
||||
|
||||
*popup-menu*
|
||||
*popup-menu*
|
||||
You can define the special menu "PopUp". This is the menu that is displayed
|
||||
when the right mouse button is pressed, if 'mousemodel' is set to popup or
|
||||
popup_setpos.
|
||||
@ -483,7 +486,7 @@ The default "PopUp" menu is: >vim
|
||||
anoremenu PopUp.How-to\ disable\ mouse <Cmd>help disable-mouse<CR>
|
||||
<
|
||||
|
||||
Showing What Menus Are Mapped To *showing-menus*
|
||||
Showing What Menus Are Mapped To *showing-menus*
|
||||
|
||||
To see what an existing menu is mapped to, use just one argument after the
|
||||
menu commands (just like you would with the ":map" commands). If the menu
|
||||
@ -502,25 +505,25 @@ Note that hitting <Tab> while entering a menu name after a menu command may
|
||||
be used to complete the name of the menu item.
|
||||
|
||||
|
||||
Executing Menus *execute-menus*
|
||||
Executing Menus *execute-menus*
|
||||
|
||||
*:em* *:emenu* *E334* *E335*
|
||||
:[range]em[enu] {menu} Execute {menu} from the command line.
|
||||
The default is to execute the Normal mode
|
||||
menu. If a range is specified, it executes
|
||||
the Visual mode menu.
|
||||
If used from <c-o>, it executes the
|
||||
insert-mode menu Eg: >
|
||||
:emenu File.Exit
|
||||
*:em* *:emenu* *E334* *E335*
|
||||
:[range]em[enu] {menu} Execute {menu} from the command line.
|
||||
The default is to execute the Normal mode
|
||||
menu. If a range is specified, it executes
|
||||
the Visual mode menu.
|
||||
If used from <c-o>, it executes the
|
||||
insert-mode menu Eg: >
|
||||
:emenu File.Exit
|
||||
|
||||
:[range]em[enu] {mode} {menu} Like above, but execute the menu for {mode}:
|
||||
'n': |:nmenu| Normal mode
|
||||
'v': |:vmenu| Visual mode
|
||||
's': |:smenu| Select mode
|
||||
'o': |:omenu| Operator-pending mode
|
||||
't': |:tlmenu| Terminal mode
|
||||
'i': |:imenu| Insert mode
|
||||
'c': |:cmenu| Cmdline mode
|
||||
:[range]em[enu] {mode} {menu} Like above, but execute the menu for {mode}:
|
||||
- 'n': |:nmenu| Normal mode
|
||||
- 'v': |:vmenu| Visual mode
|
||||
- 's': |:smenu| Select mode
|
||||
- 'o': |:omenu| Operator-pending mode
|
||||
- 't': |:tlmenu| Terminal mode
|
||||
- 'i': |:imenu| Insert mode
|
||||
- 'c': |:cmenu| Cmdline mode
|
||||
|
||||
|
||||
You can use :emenu to access useful menu items you may have got used to from
|
||||
@ -531,10 +534,10 @@ When using a range, if the lines match with '<,'>, then the menu is executed
|
||||
using the last visual selection.
|
||||
|
||||
|
||||
Deleting Menus *delete-menus*
|
||||
Deleting Menus *delete-menus*
|
||||
|
||||
*:unme* *:unmenu*
|
||||
*:aun* *:aunmenu*
|
||||
*:unme* *:unmenu*
|
||||
*:aun* *:aunmenu*
|
||||
To delete a menu item or a whole submenu, use the unmenu commands, which are
|
||||
analogous to the unmap commands. Eg: >
|
||||
:unmenu! Edit.Paste
|
||||
@ -545,26 +548,26 @@ Command-line modes.
|
||||
Note that hitting <Tab> while entering a menu name after an umenu command
|
||||
may be used to complete the name of the menu item for the appropriate mode.
|
||||
|
||||
To remove all menus use: *:unmenu-all* >
|
||||
:unmenu * " remove all menus in Normal and visual mode
|
||||
:unmenu! * " remove all menus in Insert and Command-line mode
|
||||
:aunmenu * " remove all menus in all modes, except for Terminal
|
||||
" mode
|
||||
:tlunmenu * " remove all menus in Terminal mode
|
||||
To remove all menus use: *:unmenu-all* >
|
||||
:unmenu * " remove all menus in Normal and visual mode
|
||||
:unmenu! * " remove all menus in Insert and Command-line mode
|
||||
:aunmenu * " remove all menus in all modes, except for Terminal
|
||||
" mode
|
||||
:tlunmenu * " remove all menus in Terminal mode
|
||||
|
||||
If you want to get rid of the menu bar: >
|
||||
:set guioptions-=m
|
||||
:set guioptions-=m
|
||||
|
||||
|
||||
Disabling Menus *disable-menus*
|
||||
Disabling Menus *disable-menus*
|
||||
|
||||
*:menu-disable* *:menu-enable*
|
||||
*:menu-disable* *:menu-enable*
|
||||
If you do not want to remove a menu, but disable it for a moment, this can be
|
||||
done by adding the "enable" or "disable" keyword to a ":menu" command.
|
||||
Examples: >
|
||||
:menu disable &File.&Open\.\.\.
|
||||
:amenu enable *
|
||||
:amenu disable &Tools.*
|
||||
:menu disable &File.&Open\.\.\.
|
||||
:amenu enable *
|
||||
:amenu disable &Tools.*
|
||||
|
||||
The command applies to the modes as used with all menu commands. Note that
|
||||
characters like "&" need to be included for translated names to be found.
|
||||
@ -572,36 +575,36 @@ When the argument is "*", all menus are affected. Otherwise the given menu
|
||||
name and all existing submenus below it are affected.
|
||||
|
||||
|
||||
Examples for Menus *menu-examples*
|
||||
Examples for Menus *menu-examples*
|
||||
|
||||
Here is an example on how to add menu items with menus! You can add a menu
|
||||
item for the keyword under the cursor. The register "z" is used. >
|
||||
|
||||
:nmenu Words.Add\ Var wb"zye:menu! Words.<C-R>z <C-R>z<CR>
|
||||
:nmenu Words.Remove\ Var wb"zye:unmenu! Words.<C-R>z<CR>
|
||||
:vmenu Words.Add\ Var "zy:menu! Words.<C-R>z <C-R>z <CR>
|
||||
:vmenu Words.Remove\ Var "zy:unmenu! Words.<C-R>z<CR>
|
||||
:imenu Words.Add\ Var <Esc>wb"zye:menu! Words.<C-R>z <C-R>z<CR>a
|
||||
:imenu Words.Remove\ Var <Esc>wb"zye:unmenu! Words.<C-R>z<CR>a
|
||||
:nmenu Words.Add\ Var wb"zye:menu! Words.<C-R>z <C-R>z<CR>
|
||||
:nmenu Words.Remove\ Var wb"zye:unmenu! Words.<C-R>z<CR>
|
||||
:vmenu Words.Add\ Var "zy:menu! Words.<C-R>z <C-R>z <CR>
|
||||
:vmenu Words.Remove\ Var "zy:unmenu! Words.<C-R>z<CR>
|
||||
:imenu Words.Add\ Var <Esc>wb"zye:menu! Words.<C-R>z <C-R>z<CR>a
|
||||
:imenu Words.Remove\ Var <Esc>wb"zye:unmenu! Words.<C-R>z<CR>a
|
||||
|
||||
(the rhs is in <> notation, you can copy/paste this text to try out the
|
||||
mappings, or put these lines in your gvimrc; "<C-R>" is CTRL-R, "<CR>" is
|
||||
the <CR> key. |<>|)
|
||||
|
||||
*tooltips* *menu-tips*
|
||||
*tooltips* *menu-tips*
|
||||
Tooltips & Menu tips
|
||||
|
||||
See section |42.4| in the user manual.
|
||||
|
||||
*:tmenu*
|
||||
:tm[enu] {menupath} {rhs} Define a tip for a menu or tool. (only in
|
||||
X11 and Win32 GUI)
|
||||
*:tmenu*
|
||||
:tm[enu] {menupath} {rhs} Define a tip for a menu or tool. (only in
|
||||
X11 and Win32 GUI)
|
||||
|
||||
:tm[enu] [menupath] List menu tips. (only in X11 and Win32 GUI)
|
||||
:tm[enu] [menupath] List menu tips. (only in X11 and Win32 GUI)
|
||||
|
||||
*:tunmenu*
|
||||
:tu[nmenu] {menupath} Remove a tip for a menu or tool.
|
||||
(only in X11 and Win32 GUI)
|
||||
*:tunmenu*
|
||||
:tu[nmenu] {menupath} Remove a tip for a menu or tool.
|
||||
(only in X11 and Win32 GUI)
|
||||
|
||||
Note: To create menus for terminal mode, use |:tlmenu| instead.
|
||||
|
||||
@ -615,11 +618,11 @@ highlight group to change its colors.
|
||||
|
||||
A "tip" can be defined for each menu item. For example, when defining a menu
|
||||
item like this: >
|
||||
:amenu MyMenu.Hello :echo "Hello"<CR>
|
||||
:amenu MyMenu.Hello :echo "Hello"<CR>
|
||||
The tip is defined like this: >
|
||||
:tmenu MyMenu.Hello Displays a greeting.
|
||||
:tmenu MyMenu.Hello Displays a greeting.
|
||||
And delete it with: >
|
||||
:tunmenu MyMenu.Hello
|
||||
:tunmenu MyMenu.Hello
|
||||
|
||||
Tooltips are currently only supported for the X11 and Win32 GUI. However, they
|
||||
should appear for the other gui platforms in the not too distant future.
|
||||
@ -638,24 +641,24 @@ a menu item - you don't need to do a :tunmenu as well.
|
||||
You can cause a menu to popup at the cursor. This behaves similarly to the
|
||||
PopUp menus except that any menu tree can be popped up.
|
||||
|
||||
*:popup* *:popu*
|
||||
:popu[p] {name} Popup the menu {name}. The menu named must
|
||||
have at least one subentry, but need not
|
||||
appear on the menu-bar (see |hidden-menus|).
|
||||
*:popup* *:popu*
|
||||
:popu[p] {name} Popup the menu {name}. The menu named must
|
||||
have at least one subentry, but need not
|
||||
appear on the menu-bar (see |hidden-menus|).
|
||||
|
||||
:popu[p]! {name} Like above, but use the position of the mouse
|
||||
pointer instead of the cursor.
|
||||
:popu[p]! {name} Like above, but use the position of the mouse
|
||||
pointer instead of the cursor.
|
||||
|
||||
Example: >
|
||||
:popup File
|
||||
:popup File
|
||||
will make the "File" menu (if there is one) appear at the text cursor (mouse
|
||||
pointer if ! was used). >
|
||||
|
||||
:amenu ]Toolbar.Make :make<CR>
|
||||
:popup ]Toolbar
|
||||
:amenu ]Toolbar.Make :make<CR>
|
||||
:popup ]Toolbar
|
||||
This creates a popup menu that doesn't exist on the main menu-bar.
|
||||
|
||||
Note that a menu that starts with ']' will not be displayed.
|
||||
|
||||
|
||||
vim:tw=78:sw=4:ts=8:noet:ft=help:norl:
|
||||
vim:tw=78:sw=4:ts=8:et:ft=help:norl:
|
||||
|
@ -150,6 +150,7 @@ LANGUAGE SUPPORT
|
||||
|arabic.txt| Arabic language support and editing
|
||||
|hebrew.txt| Hebrew language support and editing
|
||||
|russian.txt| Russian language support and editing
|
||||
|vietnamese.txt| Vietnamese language support and editing
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
INTEROP
|
||||
|
@ -1472,6 +1472,7 @@ tag command action ~
|
||||
|:ownsyntax| :ow[nsyntax] set new local syntax highlight for this window
|
||||
|:packadd| :pa[ckadd] add a plugin from 'packpath'
|
||||
|:packloadall| :packl[oadall] load all packages under 'packpath'
|
||||
|:pbuffer| :pb[uffer] edit buffer in the preview window
|
||||
|:pclose| :pc[lose] close preview window
|
||||
|:pedit| :ped[it] edit file in the preview window
|
||||
|:perl| :pe[rl] execute perl command
|
||||
@ -1569,6 +1570,8 @@ tag command action ~
|
||||
|:sign| :sig[n] manipulate signs
|
||||
|:silent| :sil[ent] run a command silently
|
||||
|:sleep| :sl[eep] do nothing for a few seconds
|
||||
|:sleep!| :sl[eep]! do nothing for a few seconds, without the
|
||||
cursor visible
|
||||
|:slast| :sla[st] split window and go to last file in the
|
||||
argument list
|
||||
|:smagic| :sm[agic] :substitute with 'magic'
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,31 +28,114 @@ Follow these steps to get LSP features:
|
||||
upstream installation instructions. You can find language servers here:
|
||||
https://microsoft.github.io/language-server-protocol/implementors/servers/
|
||||
|
||||
2. Use |vim.lsp.start()| to start the LSP server (or attach to an existing
|
||||
one) when a file is opened. Example: >lua
|
||||
-- Create an event handler for the FileType autocommand
|
||||
vim.api.nvim_create_autocmd('FileType', {
|
||||
-- This handler will fire when the buffer's 'filetype' is "python"
|
||||
pattern = 'python',
|
||||
callback = function(args)
|
||||
vim.lsp.start({
|
||||
name = 'my-server-name',
|
||||
cmd = {'name-of-language-server-executable', '--option', 'arg1', 'arg2'},
|
||||
2. Use |vim.lsp.config()| to define a configuration for an LSP client.
|
||||
Example: >lua
|
||||
vim.lsp.config['luals'] = {
|
||||
-- Command and arguments to start the server.
|
||||
cmd = { 'lua-language-server' }
|
||||
|
||||
-- Set the "root directory" to the parent directory of the file in the
|
||||
-- current buffer (`args.buf`) that contains either a "setup.py" or a
|
||||
-- "pyproject.toml" file. Files that share a root directory will reuse
|
||||
-- the connection to the same LSP server.
|
||||
root_dir = vim.fs.root(args.buf, {'setup.py', 'pyproject.toml'}),
|
||||
})
|
||||
end,
|
||||
})
|
||||
-- Filetypes to automatically attach to.
|
||||
filetypes = { 'lua' },
|
||||
|
||||
-- Sets the "root directory" to the parent directory of the file in the
|
||||
-- current buffer that contains either a ".luarc.json" or a
|
||||
-- ".luarc.jsonc" file. Files that share a root directory will reuse
|
||||
-- the connection to the same LSP server.
|
||||
root_markers = { '.luarc.json', '.luarc.jsonc' },
|
||||
|
||||
-- Specific settings to send to the server. The schema for this is
|
||||
-- defined by the server. For example the schema for lua-language-server
|
||||
-- can be found here https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json
|
||||
settings = {
|
||||
Lua = {
|
||||
runtime = {
|
||||
version = 'LuaJIT',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<
|
||||
3. Check that the buffer is attached to the server: >vim
|
||||
:checkhealth lsp
|
||||
3. Use |vim.lsp.enable()| to enable a configuration.
|
||||
Example: >lua
|
||||
vim.lsp.enable('luals')
|
||||
<
|
||||
4. Check that the buffer is attached to the server: >vim
|
||||
:checkhealth vim.lsp
|
||||
<
|
||||
5. (Optional) Configure keymaps and autocommands to use LSP features.
|
||||
|lsp-attach|
|
||||
|
||||
4. (Optional) Configure keymaps and autocommands to use LSP features. |lsp-config|
|
||||
*lsp-config*
|
||||
|
||||
Configurations for LSP clients is done via |vim.lsp.config()|.
|
||||
|
||||
When an LSP client starts, it resolves a configuration by merging
|
||||
configurations, in increasing priority, from the following:
|
||||
|
||||
1. Configuration defined for the `'*'` name.
|
||||
|
||||
2. Configuration from the result of sourcing all `lsp/<name>.lua` files
|
||||
in 'runtimepath' for a server of name `name`.
|
||||
|
||||
Note: because of this, calls to |vim.lsp.config()| in `lsp/*.lua` are
|
||||
treated independently to other calls. This ensures configurations
|
||||
defined in `lsp/*.lua` have a lower priority.
|
||||
|
||||
3. Configurations defined anywhere else.
|
||||
|
||||
Note: The merge semantics of configurations follow the behaviour of
|
||||
|vim.tbl_deep_extend()|.
|
||||
|
||||
Example:
|
||||
|
||||
Given: >lua
|
||||
-- Defined in init.lua
|
||||
vim.lsp.config('*', {
|
||||
capabilities = {
|
||||
textDocument = {
|
||||
semanticTokens = {
|
||||
multilineTokenSupport = true,
|
||||
}
|
||||
}
|
||||
}
|
||||
root_markers = { '.git' },
|
||||
})
|
||||
|
||||
-- Defined in ../lsp/clangd.lua
|
||||
vim.lsp.config('clangd', {
|
||||
cmd = { 'clangd' },
|
||||
root_markers = { '.clangd', 'compile_commands.json' },
|
||||
filetypes = { 'c', 'cpp' },
|
||||
})
|
||||
|
||||
-- Defined in init.lua
|
||||
vim.lsp.config('clangd', {
|
||||
filetypes = { 'c' },
|
||||
})
|
||||
<
|
||||
Results in the configuration: >lua
|
||||
{
|
||||
-- From the clangd configuration in <rtp>/lsp/clangd.lua
|
||||
cmd = { 'clangd' },
|
||||
|
||||
-- From the clangd configuration in <rtp>/lsp/clangd.lua
|
||||
-- Overrides the * configuration in init.lua
|
||||
root_markers = { '.clangd', 'compile_commands.json' },
|
||||
|
||||
-- From the clangd configuration in init.lua
|
||||
-- Overrides the * configuration in init.lua
|
||||
filetypes = { 'c' },
|
||||
|
||||
-- From the * configuration in init.lua
|
||||
capabilities = {
|
||||
textDocument = {
|
||||
semanticTokens = {
|
||||
multilineTokenSupport = true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<
|
||||
*lsp-defaults*
|
||||
When the Nvim LSP client starts it enables diagnostics |vim.diagnostic| (see
|
||||
|vim.diagnostic.config()| to customize). It also sets various default options,
|
||||
@ -98,7 +181,7 @@ To override or delete any of the above defaults, set or unset the options on
|
||||
end,
|
||||
})
|
||||
<
|
||||
*lsp-config*
|
||||
*lsp-attach*
|
||||
To use other LSP features, set keymaps and other buffer options on
|
||||
|LspAttach|. Not all language servers provide the same capabilities. Use
|
||||
capability checks to ensure you only use features supported by the language
|
||||
@ -107,16 +190,16 @@ server. Example: >lua
|
||||
vim.api.nvim_create_autocmd('LspAttach', {
|
||||
callback = function(args)
|
||||
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||
if client.supports_method('textDocument/implementation') then
|
||||
if client:supports_method('textDocument/implementation') then
|
||||
-- Create a keymap for vim.lsp.buf.implementation
|
||||
end
|
||||
|
||||
if client.supports_method('textDocument/completion') then
|
||||
if client:supports_method('textDocument/completion') then
|
||||
-- Enable auto-completion
|
||||
vim.lsp.completion.enable(true, client.id, args.buf, {autotrigger = true})
|
||||
end
|
||||
|
||||
if client.supports_method('textDocument/formatting') then
|
||||
if client:supports_method('textDocument/formatting') then
|
||||
-- Format the current buffer on save
|
||||
vim.api.nvim_create_autocmd('BufWritePre', {
|
||||
buffer = args.buf,
|
||||
@ -204,6 +287,7 @@ won't run if your server doesn't support them.
|
||||
- `'textDocument/diagnostic'`
|
||||
- `'textDocument/documentHighlight'`
|
||||
- `'textDocument/documentSymbol'`
|
||||
- `'textDocument/foldingRange'`
|
||||
- `'textDocument/formatting'`
|
||||
- `'textDocument/hover'`
|
||||
- `'textDocument/implementation'`
|
||||
@ -464,7 +548,7 @@ EVENTS *lsp-events*
|
||||
LspAttach *LspAttach*
|
||||
After an LSP client attaches to a buffer. The |autocmd-pattern| is the
|
||||
name of the buffer. When used from Lua, the client ID is passed to the
|
||||
callback in the "data" table. See |lsp-config| for an example.
|
||||
callback in the "data" table. See |lsp-attach| for an example.
|
||||
|
||||
LspDetach *LspDetach*
|
||||
Just before an LSP client detaches from a buffer. The |autocmd-pattern|
|
||||
@ -477,7 +561,7 @@ LspDetach *LspDetach*
|
||||
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||
|
||||
-- Remove the autocommand to format the buffer on save, if it exists
|
||||
if client.supports_method('textDocument/formatting') then
|
||||
if client:supports_method('textDocument/formatting') then
|
||||
vim.api.nvim_clear_autocmds({
|
||||
event = 'BufWritePre',
|
||||
buffer = args.buf,
|
||||
@ -589,6 +673,27 @@ LspTokenUpdate *LspTokenUpdate*
|
||||
==============================================================================
|
||||
Lua module: vim.lsp *lsp-core*
|
||||
|
||||
*vim.lsp.Config*
|
||||
Extends: |vim.lsp.ClientConfig|
|
||||
|
||||
|
||||
Fields: ~
|
||||
• {cmd}? (`string[]|fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient`)
|
||||
See `cmd` in |vim.lsp.ClientConfig|.
|
||||
• {filetypes}? (`string[]`) Filetypes the client will attach to, if
|
||||
activated by `vim.lsp.enable()`. If not provided,
|
||||
then the client will attach to all filetypes.
|
||||
• {root_markers}? (`string[]`) Directory markers (.e.g. '.git/') where
|
||||
the LSP server will base its workspaceFolders,
|
||||
rootUri, and rootPath on initialization. Unused if
|
||||
`root_dir` is provided.
|
||||
• {reuse_client}? (`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean`)
|
||||
Predicate used to decide if a client should be
|
||||
re-used. Used on all running clients. The default
|
||||
implementation re-uses a client if name and root_dir
|
||||
matches.
|
||||
|
||||
|
||||
buf_attach_client({bufnr}, {client_id}) *vim.lsp.buf_attach_client()*
|
||||
Implements the `textDocument/did…` notifications required to track a
|
||||
buffer for any language server.
|
||||
@ -688,7 +793,7 @@ commands *vim.lsp.commands*
|
||||
value is a function which is called if any LSP action (code action, code
|
||||
lenses, ...) triggers the command.
|
||||
|
||||
If a LSP response contains a command for which no matching entry is
|
||||
If an LSP response contains a command for which no matching entry is
|
||||
available in this registry, the command will be executed via the LSP
|
||||
server using `workspace/executeCommand`.
|
||||
|
||||
@ -697,6 +802,107 @@ commands *vim.lsp.commands*
|
||||
|
||||
The second argument is the `ctx` of |lsp-handler|
|
||||
|
||||
config({name}, {cfg}) *vim.lsp.config()*
|
||||
Update the configuration for an LSP client.
|
||||
|
||||
Use name '*' to set default configuration for all clients.
|
||||
|
||||
Can also be table-assigned to redefine the configuration for a client.
|
||||
|
||||
Examples:
|
||||
• Add a root marker for all clients: >lua
|
||||
vim.lsp.config('*', {
|
||||
root_markers = { '.git' },
|
||||
})
|
||||
<
|
||||
• Add additional capabilities to all clients: >lua
|
||||
vim.lsp.config('*', {
|
||||
capabilities = {
|
||||
textDocument = {
|
||||
semanticTokens = {
|
||||
multilineTokenSupport = true,
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
<
|
||||
• (Re-)define the configuration for clangd: >lua
|
||||
vim.lsp.config.clangd = {
|
||||
cmd = {
|
||||
'clangd',
|
||||
'--clang-tidy',
|
||||
'--background-index',
|
||||
'--offset-encoding=utf-8',
|
||||
},
|
||||
root_markers = { '.clangd', 'compile_commands.json' },
|
||||
filetypes = { 'c', 'cpp' },
|
||||
}
|
||||
<
|
||||
• Get configuration for luals: >lua
|
||||
local cfg = vim.lsp.config.luals
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {name} (`string`)
|
||||
• {cfg} (`vim.lsp.Config`) See |vim.lsp.Config|.
|
||||
|
||||
enable({name}, {enable}) *vim.lsp.enable()*
|
||||
Enable an LSP server to automatically start when opening a buffer.
|
||||
|
||||
Uses configuration defined with `vim.lsp.config`.
|
||||
|
||||
Examples: >lua
|
||||
vim.lsp.enable('clangd')
|
||||
|
||||
vim.lsp.enable({'luals', 'pyright'})
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {name} (`string|string[]`) Name(s) of client(s) to enable.
|
||||
• {enable} (`boolean?`) `true|nil` to enable, `false` to disable.
|
||||
|
||||
foldclose({kind}, {winid}) *vim.lsp.foldclose()*
|
||||
Close all {kind} of folds in the the window with {winid}.
|
||||
|
||||
To automatically fold imports when opening a file, you can use an autocmd: >lua
|
||||
vim.api.nvim_create_autocmd('LspNotify', {
|
||||
callback = function(args)
|
||||
if args.data.method == 'textDocument/didOpen' then
|
||||
vim.lsp.foldclose('imports', vim.fn.bufwinid(args.buf))
|
||||
end
|
||||
end,
|
||||
})
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {kind} (`lsp.FoldingRangeKind`) Kind to close, one of "comment",
|
||||
"imports" or "region".
|
||||
• {winid} (`integer?`) Defaults to the current window.
|
||||
|
||||
foldexpr({lnum}) *vim.lsp.foldexpr()*
|
||||
Provides an interface between the built-in client and a `foldexpr`
|
||||
function.
|
||||
|
||||
To use, check for the "textDocument/foldingRange" capability in an
|
||||
|LspAttach| autocommand. Example: >lua
|
||||
vim.api.nvim_create_autocommand('LspAttach', {
|
||||
callback = function(args)
|
||||
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||
if client:supports_method('textDocument/foldingRange') then
|
||||
vim.wo.foldmethod = 'expr'
|
||||
vim.wo.foldexpr = 'v:lua.vim.lsp.foldexpr()'
|
||||
end
|
||||
end,
|
||||
})
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {lnum} (`integer`) line number
|
||||
|
||||
foldtext() *vim.lsp.foldtext()*
|
||||
Provides a `foldtext` function that shows the `collapsedText` retrieved,
|
||||
defaults to the first folded line if `collapsedText` is not provided.
|
||||
|
||||
formatexpr({opts}) *vim.lsp.formatexpr()*
|
||||
Provides an interface between the built-in client and a `formatexpr`
|
||||
function.
|
||||
@ -798,12 +1004,11 @@ start({config}, {opts}) *vim.lsp.start()*
|
||||
})
|
||||
<
|
||||
|
||||
See |vim.lsp.start_client()| for all available options. The most important
|
||||
See |vim.lsp.ClientConfig| for all available options. The most important
|
||||
are:
|
||||
• `name` arbitrary name for the LSP client. Should be unique per language
|
||||
server.
|
||||
• `cmd` command string[] or function, described at
|
||||
|vim.lsp.start_client()|.
|
||||
• `cmd` command string[] or function.
|
||||
• `root_dir` path to the project root. By default this is used to decide
|
||||
if an existing client should be re-used. The example above uses
|
||||
|vim.fs.root()| to detect the root by traversing the file system upwards
|
||||
@ -825,33 +1030,25 @@ start({config}, {opts}) *vim.lsp.start()*
|
||||
Parameters: ~
|
||||
• {config} (`vim.lsp.ClientConfig`) Configuration for the server. See
|
||||
|vim.lsp.ClientConfig|.
|
||||
• {opts} (`table?`) Optional keyword arguments
|
||||
• {opts} (`table?`) Optional keyword arguments.
|
||||
• {reuse_client}?
|
||||
(`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean`)
|
||||
Predicate used to decide if a client should be re-used.
|
||||
Used on all running clients. The default implementation
|
||||
re-uses a client if name and root_dir matches.
|
||||
re-uses a client if it has the same name and if the given
|
||||
workspace folders (or root_dir) are all included in the
|
||||
client's workspace folders.
|
||||
• {bufnr}? (`integer`) Buffer handle to attach to if
|
||||
starting or re-using a client (0 for current).
|
||||
• {attach}? (`boolean`) Whether to attach the client to a
|
||||
buffer (default true). If set to `false`, `reuse_client`
|
||||
and `bufnr` will be ignored.
|
||||
• {silent}? (`boolean`) Suppress error reporting if the LSP
|
||||
server fails to start (default false).
|
||||
|
||||
Return: ~
|
||||
(`integer?`) client_id
|
||||
|
||||
start_client({config}) *vim.lsp.start_client()*
|
||||
Starts and initializes a client with the given configuration.
|
||||
|
||||
Parameters: ~
|
||||
• {config} (`vim.lsp.ClientConfig`) Configuration for the server. See
|
||||
|vim.lsp.ClientConfig|.
|
||||
|
||||
Return (multiple): ~
|
||||
(`integer?`) client_id |vim.lsp.get_client_by_id()| Note: client may
|
||||
not be fully initialized. Use `on_init` to do any actions once the
|
||||
client has been initialized.
|
||||
(`string?`) Error message, if any
|
||||
|
||||
status() *vim.lsp.status()*
|
||||
Consumes the latest progress messages from all clients and formats them as
|
||||
a string. Empty if there are no clients or if no new messages
|
||||
@ -904,14 +1101,15 @@ Lua module: vim.lsp.client *lsp-client*
|
||||
• {rpc} (`vim.lsp.rpc.PublicClient`) RPC client
|
||||
object, for low level interaction with the
|
||||
client. See |vim.lsp.rpc.start()|.
|
||||
• {offset_encoding} (`string`) The encoding used for communicating
|
||||
with the server. You can modify this in the
|
||||
• {offset_encoding} (`string`) Called "position encoding" in LSP
|
||||
spec, the encoding used for communicating with
|
||||
the server. You can modify this in the
|
||||
`config`'s `on_init` method before text is
|
||||
sent to the server.
|
||||
• {handlers} (`table<string,lsp.Handler>`) The handlers
|
||||
used by the client as described in
|
||||
|lsp-handler|.
|
||||
• {requests} (`table<integer,{ type: string, bufnr: integer, method: string}>`)
|
||||
• {requests} (`table<integer,{ type: string, bufnr: integer, method: string}?>`)
|
||||
The current pending requests in flight to the
|
||||
server. Entries are key-value pairs with the
|
||||
key being the request id while the value is a
|
||||
@ -924,8 +1122,7 @@ Lua module: vim.lsp.client *lsp-client*
|
||||
server.
|
||||
• {config} (`vim.lsp.ClientConfig`) copy of the table
|
||||
that was passed by the user to
|
||||
|vim.lsp.start_client()|. See
|
||||
|vim.lsp.ClientConfig|.
|
||||
|vim.lsp.start()|. See |vim.lsp.ClientConfig|.
|
||||
• {server_capabilities} (`lsp.ServerCapabilities?`) Response from the
|
||||
server sent on `initialize` describing the
|
||||
server's capabilities.
|
||||
@ -948,9 +1145,9 @@ Lua module: vim.lsp.client *lsp-client*
|
||||
lenses, ...) triggers the command. Client
|
||||
commands take precedence over the global
|
||||
command registry.
|
||||
• {settings} (`table`) Map with language server specific
|
||||
settings. These are returned to the language
|
||||
server if requested via
|
||||
• {settings} (`lsp.LSPObject`) Map with language server
|
||||
specific settings. These are returned to the
|
||||
language server if requested via
|
||||
`workspace/configuration`. Keys are
|
||||
case-sensitive.
|
||||
• {flags} (`table`) A table with flags for the client.
|
||||
@ -974,7 +1171,7 @@ Lua module: vim.lsp.client *lsp-client*
|
||||
• {dynamic_capabilities} (`lsp.DynamicCapabilities`)
|
||||
• {request} (`fun(self: vim.lsp.Client, method: string, params: table?, handler: lsp.Handler?, bufnr: integer?): boolean, integer?`)
|
||||
See |Client:request()|.
|
||||
• {request_sync} (`fun(self: vim.lsp.Client, method: string, params: table, timeout_ms: integer?, bufnr: integer): {err: lsp.ResponseError?, result:any}?, string?`)
|
||||
• {request_sync} (`fun(self: vim.lsp.Client, method: string, params: table, timeout_ms: integer?, bufnr: integer?): {err: lsp.ResponseError?, result:any}?, string?`)
|
||||
See |Client:request_sync()|.
|
||||
• {notify} (`fun(self: vim.lsp.Client, method: string, params: table?): boolean`)
|
||||
See |Client:notify()|.
|
||||
@ -1043,28 +1240,30 @@ Lua module: vim.lsp.client *lsp-client*
|
||||
an array.
|
||||
• {handlers}? (`table<string,function>`) Map of language
|
||||
server method names to |lsp-handler|
|
||||
• {settings}? (`table`) Map with language server specific
|
||||
settings. See the {settings} in
|
||||
• {settings}? (`lsp.LSPObject`) Map with language server
|
||||
specific settings. See the {settings} in
|
||||
|vim.lsp.Client|.
|
||||
• {commands}? (`table<string,fun(command: lsp.Command, ctx: table)>`)
|
||||
Table that maps string of clientside commands to
|
||||
user-defined functions. Commands passed to
|
||||
start_client take precedence over the global
|
||||
`start()` take precedence over the global
|
||||
command registry. Each key must be a unique
|
||||
command name, and the value is a function which
|
||||
is called if any LSP action (code action, code
|
||||
lenses, ...) triggers the command.
|
||||
• {init_options}? (`table`) Values to pass in the initialization
|
||||
request as `initializationOptions`. See
|
||||
`initialize` in the LSP spec.
|
||||
• {init_options}? (`lsp.LSPObject`) Values to pass in the
|
||||
initialization request as
|
||||
`initializationOptions`. See `initialize` in the
|
||||
LSP spec.
|
||||
• {name}? (`string`, default: client-id) Name in log
|
||||
messages.
|
||||
• {get_language_id}? (`fun(bufnr: integer, filetype: string): string`)
|
||||
Language ID as string. Defaults to the buffer
|
||||
filetype.
|
||||
• {offset_encoding}? (`'utf-8'|'utf-16'|'utf-32'`) The encoding that
|
||||
the LSP server expects. Client does not verify
|
||||
this is correct.
|
||||
• {offset_encoding}? (`'utf-8'|'utf-16'|'utf-32'`) Called "position
|
||||
encoding" in LSP spec, the encoding that the LSP
|
||||
server expects. Client does not verify this is
|
||||
correct.
|
||||
• {on_error}? (`fun(code: integer, err: string)`) Callback
|
||||
invoked when the client operation throws an
|
||||
error. `code` is a number describing the error.
|
||||
@ -1077,9 +1276,9 @@ Lua module: vim.lsp.client *lsp-client*
|
||||
Callback invoked before the LSP "initialize"
|
||||
phase, where `params` contains the parameters
|
||||
being sent to the server and `config` is the
|
||||
config that was passed to
|
||||
|vim.lsp.start_client()|. You can use this to
|
||||
modify parameters before they are sent.
|
||||
config that was passed to |vim.lsp.start()|. You
|
||||
can use this to modify parameters before they
|
||||
are sent.
|
||||
• {on_init}? (`elem_or_list<fun(client: vim.lsp.Client, initialize_result: lsp.InitializeResult)>`)
|
||||
Callback invoked after LSP "initialize", where
|
||||
`result` is a table of `capabilities` and
|
||||
@ -1177,7 +1376,7 @@ Client:request({method}, {params}, {handler}, {bufnr})
|
||||
• {method} (`string`) LSP method name.
|
||||
• {params} (`table?`) LSP request params.
|
||||
• {handler} (`lsp.Handler?`) Response |lsp-handler| for this method.
|
||||
• {bufnr} (`integer?`) Buffer handle. 0 for current (default).
|
||||
• {bufnr} (`integer?`) (default: 0) Buffer handle, or 0 for current.
|
||||
|
||||
Return (multiple): ~
|
||||
(`boolean`) status indicates whether the request was successful. If it
|
||||
@ -1199,7 +1398,8 @@ Client:request_sync({method}, {params}, {timeout_ms}, {bufnr})
|
||||
• {params} (`table`) LSP request params.
|
||||
• {timeout_ms} (`integer?`) Maximum time in milliseconds to wait for a
|
||||
result. Defaults to 1000
|
||||
• {bufnr} (`integer`) Buffer handle (0 for current).
|
||||
• {bufnr} (`integer?`) (default: 0) Buffer handle, or 0 for
|
||||
current.
|
||||
|
||||
Return (multiple): ~
|
||||
(`{err: lsp.ResponseError?, result:any}?`) `result` and `err` from the
|
||||
@ -1383,7 +1583,7 @@ format({opts}) *vim.lsp.buf.format()*
|
||||
predicate are included. Example: >lua
|
||||
-- Never request typescript-language-server for formatting
|
||||
vim.lsp.buf.format {
|
||||
filter = function(client) return client.name ~= "tsserver" end
|
||||
filter = function(client) return client.name ~= "ts_ls" end
|
||||
}
|
||||
<
|
||||
• {async}? (`boolean`, default: false) If true the method
|
||||
@ -1446,7 +1646,7 @@ references({context}, {opts}) *vim.lsp.buf.references()*
|
||||
window.
|
||||
|
||||
Parameters: ~
|
||||
• {context} (`table?`) Context for the request
|
||||
• {context} (`lsp.ReferenceContext?`) Context for the request
|
||||
• {opts} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|.
|
||||
|
||||
See also: ~
|
||||
@ -1532,12 +1732,13 @@ get_namespace({client_id}, {is_pull})
|
||||
client. Defaults to push
|
||||
|
||||
*vim.lsp.diagnostic.on_diagnostic()*
|
||||
on_diagnostic({_}, {result}, {ctx})
|
||||
on_diagnostic({error}, {result}, {ctx})
|
||||
|lsp-handler| for the method "textDocument/diagnostic"
|
||||
|
||||
See |vim.diagnostic.config()| for configuration options.
|
||||
|
||||
Parameters: ~
|
||||
• {error} (`lsp.ResponseError?`)
|
||||
• {result} (`lsp.DocumentDiagnosticReport`)
|
||||
• {ctx} (`lsp.HandlerContext`)
|
||||
|
||||
@ -1840,7 +2041,7 @@ Lua module: vim.lsp.util *lsp-util*
|
||||
|
||||
|
||||
*vim.lsp.util.apply_text_document_edit()*
|
||||
apply_text_document_edit({text_document_edit}, {index}, {offset_encoding})
|
||||
apply_text_document_edit({text_document_edit}, {index}, {position_encoding})
|
||||
Applies a `TextDocumentEdit`, which is a list of changes to a single
|
||||
document.
|
||||
|
||||
@ -1848,30 +2049,30 @@ apply_text_document_edit({text_document_edit}, {index}, {offset_encoding})
|
||||
• {text_document_edit} (`lsp.TextDocumentEdit`)
|
||||
• {index} (`integer?`) Optional index of the edit, if from
|
||||
a list of edits (or nil, if not from a list)
|
||||
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'?`)
|
||||
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'?`)
|
||||
|
||||
See also: ~
|
||||
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit
|
||||
|
||||
*vim.lsp.util.apply_text_edits()*
|
||||
apply_text_edits({text_edits}, {bufnr}, {offset_encoding})
|
||||
apply_text_edits({text_edits}, {bufnr}, {position_encoding})
|
||||
Applies a list of text edits to a buffer.
|
||||
|
||||
Parameters: ~
|
||||
• {text_edits} (`lsp.TextEdit[]`)
|
||||
• {bufnr} (`integer`) Buffer id
|
||||
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
|
||||
• {text_edits} (`lsp.TextEdit[]`)
|
||||
• {bufnr} (`integer`) Buffer id
|
||||
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
|
||||
|
||||
See also: ~
|
||||
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit
|
||||
|
||||
*vim.lsp.util.apply_workspace_edit()*
|
||||
apply_workspace_edit({workspace_edit}, {offset_encoding})
|
||||
apply_workspace_edit({workspace_edit}, {position_encoding})
|
||||
Applies a `WorkspaceEdit`.
|
||||
|
||||
Parameters: ~
|
||||
• {workspace_edit} (`lsp.WorkspaceEdit`)
|
||||
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`) (required)
|
||||
• {workspace_edit} (`lsp.WorkspaceEdit`)
|
||||
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`) (required)
|
||||
|
||||
See also: ~
|
||||
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit
|
||||
@ -1883,13 +2084,13 @@ buf_clear_references({bufnr}) *vim.lsp.util.buf_clear_references()*
|
||||
• {bufnr} (`integer?`) Buffer id
|
||||
|
||||
*vim.lsp.util.buf_highlight_references()*
|
||||
buf_highlight_references({bufnr}, {references}, {offset_encoding})
|
||||
buf_highlight_references({bufnr}, {references}, {position_encoding})
|
||||
Shows a list of document highlights for a certain buffer.
|
||||
|
||||
Parameters: ~
|
||||
• {bufnr} (`integer`) Buffer id
|
||||
• {references} (`lsp.DocumentHighlight[]`) objects to highlight
|
||||
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
|
||||
• {bufnr} (`integer`) Buffer id
|
||||
• {references} (`lsp.DocumentHighlight[]`) objects to highlight
|
||||
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
|
||||
|
||||
See also: ~
|
||||
• https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent
|
||||
@ -1964,7 +2165,7 @@ get_effective_tabstop({bufnr}) *vim.lsp.util.get_effective_tabstop()*
|
||||
• 'shiftwidth'
|
||||
|
||||
*vim.lsp.util.locations_to_items()*
|
||||
locations_to_items({locations}, {offset_encoding})
|
||||
locations_to_items({locations}, {position_encoding})
|
||||
Returns the items with the byte position calculated correctly and in
|
||||
sorted order, for display in quickfix and location lists.
|
||||
|
||||
@ -1975,9 +2176,9 @@ locations_to_items({locations}, {offset_encoding})
|
||||
|setloclist()|.
|
||||
|
||||
Parameters: ~
|
||||
• {locations} (`lsp.Location[]|lsp.LocationLink[]`)
|
||||
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) default to first
|
||||
client of buffer
|
||||
• {locations} (`lsp.Location[]|lsp.LocationLink[]`)
|
||||
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) default to first
|
||||
client of buffer
|
||||
|
||||
Return: ~
|
||||
(`vim.quickfix.entry[]`) See |setqflist()| for the format
|
||||
@ -2012,33 +2213,33 @@ make_formatting_params({options})
|
||||
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting
|
||||
|
||||
*vim.lsp.util.make_given_range_params()*
|
||||
make_given_range_params({start_pos}, {end_pos}, {bufnr}, {offset_encoding})
|
||||
make_given_range_params({start_pos}, {end_pos}, {bufnr}, {position_encoding})
|
||||
Using the given range in the current buffer, creates an object that is
|
||||
similar to |vim.lsp.util.make_range_params()|.
|
||||
|
||||
Parameters: ~
|
||||
• {start_pos} (`[integer,integer]?`) {row,col} mark-indexed
|
||||
position. Defaults to the start of the last visual
|
||||
selection.
|
||||
• {end_pos} (`[integer,integer]?`) {row,col} mark-indexed
|
||||
position. Defaults to the end of the last visual
|
||||
selection.
|
||||
• {bufnr} (`integer?`) buffer handle or 0 for current,
|
||||
defaults to current
|
||||
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
|
||||
• {start_pos} (`[integer,integer]?`) {row,col} mark-indexed
|
||||
position. Defaults to the start of the last
|
||||
visual selection.
|
||||
• {end_pos} (`[integer,integer]?`) {row,col} mark-indexed
|
||||
position. Defaults to the end of the last visual
|
||||
selection.
|
||||
• {bufnr} (`integer?`) buffer handle or 0 for current,
|
||||
defaults to current
|
||||
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
|
||||
|
||||
Return: ~
|
||||
(`{ textDocument: { uri: lsp.DocumentUri }, range: lsp.Range }`)
|
||||
|
||||
*vim.lsp.util.make_position_params()*
|
||||
make_position_params({window}, {offset_encoding})
|
||||
make_position_params({window}, {position_encoding})
|
||||
Creates a `TextDocumentPositionParams` object for the current buffer and
|
||||
cursor position.
|
||||
|
||||
Parameters: ~
|
||||
• {window} (`integer?`) window handle or 0 for current,
|
||||
defaults to current
|
||||
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
|
||||
• {window} (`integer?`) window handle or 0 for current,
|
||||
defaults to current
|
||||
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
|
||||
|
||||
Return: ~
|
||||
(`lsp.TextDocumentPositionParams`)
|
||||
@ -2047,16 +2248,16 @@ make_position_params({window}, {offset_encoding})
|
||||
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams
|
||||
|
||||
*vim.lsp.util.make_range_params()*
|
||||
make_range_params({window}, {offset_encoding})
|
||||
make_range_params({window}, {position_encoding})
|
||||
Using the current position in the current buffer, creates an object that
|
||||
can be used as a building block for several LSP requests, such as
|
||||
`textDocument/codeAction`, `textDocument/colorPresentation`,
|
||||
`textDocument/rangeFormatting`.
|
||||
|
||||
Parameters: ~
|
||||
• {window} (`integer?`) window handle or 0 for current,
|
||||
defaults to current
|
||||
• {offset_encoding} (`"utf-8"|"utf-16"|"utf-32"`)
|
||||
• {window} (`integer?`) window handle or 0 for current,
|
||||
defaults to current
|
||||
• {position_encoding} (`"utf-8"|"utf-16"|"utf-32"`)
|
||||
|
||||
Return: ~
|
||||
(`{ textDocument: { uri: lsp.DocumentUri }, range: lsp.Range }`)
|
||||
@ -2138,17 +2339,17 @@ rename({old_fname}, {new_fname}, {opts}) *vim.lsp.util.rename()*
|
||||
• {ignoreIfExists}? (`boolean`)
|
||||
|
||||
*vim.lsp.util.show_document()*
|
||||
show_document({location}, {offset_encoding}, {opts})
|
||||
show_document({location}, {position_encoding}, {opts})
|
||||
Shows document and optionally jumps to the location.
|
||||
|
||||
Parameters: ~
|
||||
• {location} (`lsp.Location|lsp.LocationLink`)
|
||||
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'?`)
|
||||
• {opts} (`table?`) A table with the following fields:
|
||||
• {reuse_win}? (`boolean`) Jump to existing window
|
||||
if buffer is already open.
|
||||
• {focus}? (`boolean`) Whether to focus/jump to
|
||||
location if possible. (defaults: true)
|
||||
• {location} (`lsp.Location|lsp.LocationLink`)
|
||||
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'?`)
|
||||
• {opts} (`table?`) A table with the following fields:
|
||||
• {reuse_win}? (`boolean`) Jump to existing
|
||||
window if buffer is already open.
|
||||
• {focus}? (`boolean`) Whether to focus/jump to
|
||||
location if possible. (defaults: true)
|
||||
|
||||
Return: ~
|
||||
(`boolean`) `true` if succeeded
|
||||
@ -2232,14 +2433,15 @@ should_log({level}) *vim.lsp.log.should_log()*
|
||||
Lua module: vim.lsp.rpc *lsp-rpc*
|
||||
|
||||
*vim.lsp.rpc.PublicClient*
|
||||
Client RPC object
|
||||
|
||||
Fields: ~
|
||||
• {request} (`fun(method: string, params: table?, callback: fun(err: lsp.ResponseError?, result: any), notify_reply_callback: fun(message_id: integer)?):boolean,integer?`)
|
||||
see |vim.lsp.rpc.request()|
|
||||
• {notify} (`fun(method: string, params: any):boolean`) see
|
||||
• {request} (`fun(method: string, params: table?, callback: fun(err?: lsp.ResponseError, result: any), notify_reply_callback?: fun(message_id: integer)):boolean,integer?`)
|
||||
See |vim.lsp.rpc.request()|
|
||||
• {notify} (`fun(method: string, params: any): boolean`) See
|
||||
|vim.lsp.rpc.notify()|
|
||||
• {is_closing} (`fun(): boolean`)
|
||||
• {terminate} (`fun()`)
|
||||
• {is_closing} (`fun(): boolean`) Indicates if the RPC is closing.
|
||||
• {terminate} (`fun()`) Terminates the RPC client.
|
||||
|
||||
|
||||
connect({host_or_path}, {port}) *vim.lsp.rpc.connect()*
|
||||
@ -2249,7 +2451,7 @@ connect({host_or_path}, {port}) *vim.lsp.rpc.connect()*
|
||||
• a host and port via TCP
|
||||
|
||||
Return a function that can be passed to the `cmd` field for
|
||||
|vim.lsp.start_client()| or |vim.lsp.start()|.
|
||||
|vim.lsp.start()|.
|
||||
|
||||
Parameters: ~
|
||||
• {host_or_path} (`string`) host to connect to or path to a pipe/domain
|
||||
@ -2340,12 +2542,7 @@ start({cmd}, {dispatchers}, {extra_spawn_params}) *vim.lsp.rpc.start()*
|
||||
See |vim.system()|
|
||||
|
||||
Return: ~
|
||||
(`vim.lsp.rpc.PublicClient`) Client RPC object, with these methods:
|
||||
• `notify()` |vim.lsp.rpc.notify()|
|
||||
• `request()` |vim.lsp.rpc.request()|
|
||||
• `is_closing()` returns a boolean indicating if the RPC is closing.
|
||||
• `terminate()` terminates the RPC client. See
|
||||
|vim.lsp.rpc.PublicClient|.
|
||||
(`vim.lsp.rpc.PublicClient`) See |vim.lsp.rpc.PublicClient|.
|
||||
|
||||
|
||||
==============================================================================
|
||||
|
@ -17,9 +17,9 @@ get an idea of what lurks beneath: >vim
|
||||
:lua vim.print(package.loaded)
|
||||
|
||||
Nvim includes a "standard library" |lua-stdlib| for Lua. It complements the
|
||||
"editor stdlib" (|builtin-functions| and |Ex-commands|) and the |API|, all of
|
||||
which can be used from Lua code (|lua-vimscript| |vim.api|). Together these
|
||||
"namespaces" form the Nvim programming interface.
|
||||
"editor stdlib" (|vimscript-functions| + |Ex-commands|) and the |API|, all of
|
||||
which can be used from Lua code (|lua-vimscript| |vim.api|). These three
|
||||
namespaces form the Nvim programming interface.
|
||||
|
||||
Lua plugins and user config are automatically discovered and loaded, just like
|
||||
Vimscript. See |lua-guide| for practical guidance.
|
||||
@ -811,11 +811,14 @@ vim.json.decode({str}, {opts}) *vim.json.decode()*
|
||||
Return: ~
|
||||
(`any`)
|
||||
|
||||
vim.json.encode({obj}) *vim.json.encode()*
|
||||
vim.json.encode({obj}, {opts}) *vim.json.encode()*
|
||||
Encodes (or "packs") Lua object {obj} as JSON in a Lua string.
|
||||
|
||||
Parameters: ~
|
||||
• {obj} (`any`)
|
||||
• {obj} (`any`)
|
||||
• {opts} (`table<string,any>?`) Options table with keys:
|
||||
• escape_slash: (boolean) (default false) When true, escapes
|
||||
`/` character in JSON strings
|
||||
|
||||
Return: ~
|
||||
(`string`)
|
||||
@ -1911,6 +1914,11 @@ vim.show_pos({bufnr}, {row}, {col}, {filter}) *vim.show_pos()*
|
||||
|
||||
Can also be shown with `:Inspect`. *:Inspect*
|
||||
|
||||
Example: To bind this function to the vim-scriptease inspired `zS` in
|
||||
Normal mode: >lua
|
||||
vim.keymap.set('n', 'zS', vim.show_pos)
|
||||
<
|
||||
|
||||
Attributes: ~
|
||||
Since: 0.9.0
|
||||
|
||||
@ -2469,7 +2477,7 @@ vim.validate({name}, {value}, {validator}, {optional}, {message})
|
||||
|
||||
Parameters: ~
|
||||
• {name} (`string`) Argument name
|
||||
• {value} (`string`) Argument value
|
||||
• {value} (`any`) Argument value
|
||||
• {validator} (`vim.validate.Validator`)
|
||||
• (`string|string[]`): Any value that can be returned
|
||||
from |lua-type()| in addition to `'callable'`:
|
||||
@ -2485,22 +2493,24 @@ vim.validate({name}, {value}, {validator}, {optional}, {message})
|
||||
==============================================================================
|
||||
Lua module: vim.loader *vim.loader*
|
||||
|
||||
vim.loader.disable() *vim.loader.disable()*
|
||||
vim.loader.enable({enable}) *vim.loader.enable()*
|
||||
WARNING: This feature is experimental/unstable.
|
||||
|
||||
Disables the experimental Lua module loader:
|
||||
• removes the loaders
|
||||
• adds the default Nvim loader
|
||||
Enables or disables the experimental Lua module loader:
|
||||
|
||||
vim.loader.enable() *vim.loader.enable()*
|
||||
WARNING: This feature is experimental/unstable.
|
||||
|
||||
Enables the experimental Lua module loader:
|
||||
• overrides loadfile
|
||||
Enable (`enable=true`):
|
||||
• overrides |loadfile()|
|
||||
• adds the Lua loader using the byte-compilation cache
|
||||
• adds the libs loader
|
||||
• removes the default Nvim loader
|
||||
|
||||
Disable (`enable=false`):
|
||||
• removes the loaders
|
||||
• adds the default Nvim loader
|
||||
|
||||
Parameters: ~
|
||||
• {enable} (`boolean?`) true/nil to enable, false to disable
|
||||
|
||||
vim.loader.find({modname}, {opts}) *vim.loader.find()*
|
||||
WARNING: This feature is experimental/unstable.
|
||||
|
||||
@ -2924,6 +2934,17 @@ vim.keymap.set({mode}, {lhs}, {rhs}, {opts}) *vim.keymap.set()*
|
||||
==============================================================================
|
||||
Lua module: vim.fs *vim.fs*
|
||||
|
||||
|
||||
*vim.fs.exists()*
|
||||
Use |uv.fs_stat()| to check a file's type, and whether it exists.
|
||||
|
||||
Example: >lua
|
||||
if vim.uv.fs_stat(file) then
|
||||
vim.print("file exists")
|
||||
end
|
||||
<
|
||||
|
||||
|
||||
vim.fs.basename({file}) *vim.fs.basename()*
|
||||
Return the basename of the given path
|
||||
|
||||
|
@ -12,7 +12,7 @@ manual.
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
1. Key mapping *key-mapping* *mapping* *macro*
|
||||
1. Key mapping *keybind* *key-mapping* *mapping* *macro*
|
||||
|
||||
Key mapping is used to change the meaning of typed keys. The most common use
|
||||
is to define a sequence of commands for a function key. Example: >
|
||||
|
@ -27,7 +27,7 @@ depends on the 'shortmess' option.
|
||||
Clear messages, keeping only the {count} most
|
||||
recent ones.
|
||||
|
||||
The number of remembered messages is fixed at 200.
|
||||
The number of remembered messages is determined by the 'messagesopt' option.
|
||||
|
||||
*g<*
|
||||
The "g<" command can be used to see the last page of previous command output.
|
||||
@ -789,6 +789,7 @@ If you accidentally hit <Enter> or <Space> and you want to see the displayed
|
||||
text then use |g<|. This only works when 'more' is set.
|
||||
|
||||
To reduce the number of hit-enter prompts:
|
||||
- Set 'messagesopt'.
|
||||
- Set 'cmdheight' to 2 or higher.
|
||||
- Add flags to 'shortmess'.
|
||||
- Reset 'showcmd' and/or 'ruler'.
|
||||
|
@ -115,6 +115,12 @@ This cannot be repeated: >
|
||||
endif<CR>
|
||||
Note that when using ":" any motion becomes charwise exclusive.
|
||||
|
||||
*inclusive-motion-selection-exclusive*
|
||||
When 'selection' is "exclusive", |Visual| mode is active and an inclusive
|
||||
motion has been used, the cursor position will be adjusted by another
|
||||
character to the right, so that the Visual selection includes the expected
|
||||
text and can be acted upon.
|
||||
|
||||
*forced-motion*
|
||||
FORCING A MOTION TO BE LINEWISE, CHARWISE OR BLOCKWISE
|
||||
|
||||
|
@ -11,16 +11,21 @@ For changes in the previous release, see |news-0.10|.
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
BREAKING CHANGES IN HEAD *news-breaking-dev*
|
||||
BREAKING CHANGES IN HEAD OR EXPERIMENTAL *news-breaking-dev*
|
||||
|
||||
====== Remove this section before release. ======
|
||||
|
||||
The following changes to UNRELEASED features were made during the development
|
||||
cycle (Nvim HEAD, the "master" branch).
|
||||
|
||||
EXPERIMENTS
|
||||
|
||||
• Removed `vim.loader.disable()`. Use `vim.loader.enable(false)` instead.
|
||||
|
||||
OPTIONS
|
||||
|
||||
• 'jumpoptions' flag "unload" has been renamed to "clean".
|
||||
• The `msghistory` option has been removed in favor of 'messagesopt'.
|
||||
|
||||
==============================================================================
|
||||
BREAKING CHANGES *news-breaking*
|
||||
@ -54,6 +59,9 @@ DEFAULTS
|
||||
• |]d-default| and |[d-default| accept a count.
|
||||
• |[D-default| and |]D-default| jump to the first and last diagnostic in the
|
||||
current buffer, respectively.
|
||||
• 'number', 'relativenumber', 'signcolumn', and 'foldcolumn' are disabled in
|
||||
|terminal| buffers. See |terminal-config| for an example of changing these defaults.
|
||||
• |vim.json.encode()| no longer escapes the forward slash symbol by default
|
||||
|
||||
DIAGNOSTICS
|
||||
|
||||
@ -79,6 +87,11 @@ EVENTS
|
||||
• |vim.ui_attach()| callbacks for |ui-messages| `msg_show` events are executed in
|
||||
|api-fast| context.
|
||||
|
||||
HIGHLIGHTS
|
||||
|
||||
• |TermCursorNC| is removed and no longer supported. Unfocused terminals no
|
||||
longer have a cursor.
|
||||
|
||||
LSP
|
||||
|
||||
• Improved rendering of LSP hover docs. |K-lsp-default|
|
||||
@ -100,7 +113,7 @@ LSP
|
||||
vim.diagnostic.config(config, vim.lsp.diagnostic.get_namespace(client_id))
|
||||
<
|
||||
• |vim.lsp.util.make_position_params()|, |vim.lsp.util.make_range_params()|
|
||||
and |vim.lsp.util.make_given_range_params()| now require the `offset_encoding`
|
||||
and |vim.lsp.util.make_given_range_params()| now require the `position_encoding`
|
||||
parameter.
|
||||
|
||||
LUA
|
||||
@ -163,6 +176,7 @@ The following new features were added.
|
||||
API
|
||||
|
||||
• |nvim__ns_set()| can set properties for a namespace
|
||||
• |vim.json.encode()| has an option to enable forward slash escaping
|
||||
|
||||
DEFAULTS
|
||||
|
||||
@ -202,6 +216,7 @@ EDITOR
|
||||
• On Windows, filename arguments on the command-line prefixed with "~\" or
|
||||
"~/" are now expanded to the user's profile directory, not a relative path
|
||||
to a literal "~" directory.
|
||||
• |hl-ComplMatchIns| shows matched text of the currently inserted completion.
|
||||
• |hl-PmenuMatch| and |hl-PmenuMatchSel| show matched text in completion popup.
|
||||
|
||||
EVENTS
|
||||
@ -226,6 +241,11 @@ LSP
|
||||
• |vim.lsp.buf.hover()| now highlights hover ranges using the
|
||||
|hl-LspReferenceTarget| highlight group.
|
||||
• Functions in |vim.lsp.Client| can now be called as methods.
|
||||
• Implemented LSP folding: |vim.lsp.foldexpr()|
|
||||
https://microsoft.github.io/language-server-protocol/specification/#textDocument_foldingRange
|
||||
• |vim.lsp.config()| has been added to define default configurations for
|
||||
servers. In addition, configurations can be specified in `lsp/<name>.lua`.
|
||||
• |vim.lsp.enable()| has been added to enable servers.
|
||||
|
||||
LUA
|
||||
|
||||
@ -238,12 +258,13 @@ LUA
|
||||
OPTIONS
|
||||
|
||||
• 'completeopt' flag "fuzzy" enables |fuzzy-matching| during |ins-completion|.
|
||||
• 'msghistory' controls maximum number of messages to remember.
|
||||
• 'messagesopt' configures |:messages| and |hit-enter| prompt.
|
||||
• 'tabclose' controls which tab page to focus when closing a tab page.
|
||||
|
||||
PERFORMANCE
|
||||
|
||||
• TODO
|
||||
• Significantly reduced redraw time for long lines with treesitter
|
||||
highlighting.
|
||||
|
||||
PLUGINS
|
||||
|
||||
@ -266,12 +287,22 @@ TERMINAL
|
||||
'scrollback' are not reflown.
|
||||
• The |terminal| now supports OSC 8 escape sequences and will display
|
||||
hyperlinks in supporting host terminals.
|
||||
• The |terminal| now uses the actual cursor, rather than a "virtual" cursor.
|
||||
This means that escape codes sent by applications running in a terminal
|
||||
buffer can change the cursor shape and visibility. However, it also
|
||||
means that the |TermCursorNC| highlight group is no longer supported: an
|
||||
unfocused terminal window will have no cursor at all (so there is nothing to
|
||||
highlight).
|
||||
• |jobstart()| gained the "term" flag.
|
||||
|
||||
TREESITTER
|
||||
|
||||
• |LanguageTree:node_for_range()| gets anonymous and named nodes for a range
|
||||
• |vim.treesitter.get_node()| now takes an option `include_anonymous`, default
|
||||
false, which allows it to return anonymous nodes as well as named nodes.
|
||||
• |treesitter-directive-trim!| can trim all whitespace (not just empty lines)
|
||||
from both sides of a node.
|
||||
• |vim.treesitter.get_captures_at_pos()| now returns the `id` of each capture
|
||||
|
||||
TUI
|
||||
|
||||
@ -280,6 +311,8 @@ TUI
|
||||
:lua =vim.api.nvim_get_chan_info(vim.api.nvim_list_uis()[1].chan)
|
||||
• |log| messages written by the builtin UI client (TUI, |--remote-ui|) are
|
||||
now prefixed with "ui" instead of "?".
|
||||
• The TUI will re-query the terminal's background color when a theme update
|
||||
notification is received and Nvim will update 'background' accordingly.
|
||||
|
||||
UI
|
||||
|
||||
@ -287,7 +320,7 @@ UI
|
||||
which controls the tool used to open the given path or URL. If you want to
|
||||
globally set this, you can override vim.ui.open using the same approach
|
||||
described at |vim.paste()|.
|
||||
- `vim.ui.open()` now supports
|
||||
• `vim.ui.open()` now supports
|
||||
[lemonade](https://github.com/lemonade-command/lemonade) as an option for
|
||||
opening urls/files. This is handy if you are in an ssh connection and use
|
||||
`lemonade`.
|
||||
@ -295,7 +328,8 @@ UI
|
||||
|hl-PmenuSel| and |hl-PmenuMatch| both inherit from |hl-Pmenu|, and
|
||||
|hl-PmenuMatchSel| inherits highlights from both |hl-PmenuSel| and
|
||||
|hl-PmenuMatch|.
|
||||
|
||||
• |vim.diagnostic.setqflist()| updates an existing quickfix list with the
|
||||
given title if found
|
||||
• |ui-messages| content chunks now also contain the highlight group ID.
|
||||
|
||||
==============================================================================
|
||||
@ -317,9 +351,9 @@ These existing features changed their behavior.
|
||||
more emoji characters than before, including those encoded with multiple
|
||||
emoji codepoints combined with ZWJ (zero width joiner) codepoints.
|
||||
|
||||
• Text in the 'statusline', 'tabline', and 'winbar' now inherits highlights
|
||||
from the respective |hl-StatusLine|, |hl-TabLine|, and |hl-WinBar| highlight
|
||||
groups.
|
||||
• Custom highlights in 'rulerformat', 'statuscolumn', 'statusline', 'tabline',
|
||||
'winbar' and the number column (through |:sign-define| `numhl`) now combine
|
||||
with their respective highlight groups, as opposed to |hl-Normal|.
|
||||
|
||||
• |vim.on_key()| callbacks won't be invoked recursively when a callback itself
|
||||
consumes input.
|
||||
|
@ -6,21 +6,23 @@
|
||||
|
||||
Nvim *nvim* *neovim* *nvim-intro*
|
||||
|
||||
Nvim is based on Vim by Bram Moolenaar.
|
||||
Nvim is based on Vim by Bram Moolenaar. Nvim is emphatically a fork of Vim,
|
||||
not a clone: compatibility with Vim (especially editor and Vimscript features,
|
||||
except |Vim9script|) is maintained where possible. See |vim-differences| for
|
||||
the complete reference.
|
||||
|
||||
If you already use Vim see |nvim-from-vim| for a quickstart.
|
||||
If you are new to Vim, try the 30-minute tutorial: >vim
|
||||
If you already use Vim, see |nvim-from-vim| for a quickstart. If you just
|
||||
installed Nvim and have never used it before, watch this 10-minute
|
||||
video: https://youtu.be/TQn2hJeHQbM .
|
||||
|
||||
To learn how to use Vim in 30 minutes, try the tutorial: >vim
|
||||
|
||||
:Tutor<Enter>
|
||||
|
||||
Nvim is emphatically a fork of Vim, not a clone: compatibility with Vim
|
||||
(especially editor and Vimscript features) is maintained where possible. See
|
||||
|vim-differences| for the complete reference of differences from Vim.
|
||||
|
||||
<
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
Transitioning from Vim *nvim-from-vim*
|
||||
Transitioning from Vim *nvim-from-vim*
|
||||
|
||||
1. To start the transition, create your |init.vim| (user config) file: >vim
|
||||
|
||||
@ -70,5 +72,21 @@ the same Nvim configuration on all of your machines, by creating
|
||||
~/AppData/Local/nvim/init.vim containing just this line: >vim
|
||||
source ~/.config/nvim/init.vim
|
||||
|
||||
==============================================================================
|
||||
What next? *nvim-quickstart*
|
||||
|
||||
If you are just trying out Nvim for a few minutes, and want to see the
|
||||
extremes of what it can do, try one of these popular "extension packs" or
|
||||
"distributions" (Note: Nvim is not affiliated with these projects, and does
|
||||
not support them):
|
||||
|
||||
- *kickstart* https://github.com/nvim-lua/kickstart.nvim
|
||||
- *lazyvim* https://www.lazyvim.org/
|
||||
- *nvchad* https://nvchad.com/
|
||||
|
||||
However, in general, we recommend (eventually) taking time to learn Nvim from
|
||||
its stock configuration, and incrementally setting options and adding plugins
|
||||
to your |config| as you find an explicit need to do so.
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:et:ft=help:norl:
|
||||
|
@ -1559,9 +1559,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
a match from the menu. Only works in combination with
|
||||
"menu" or "menuone". No effect if "longest" is present.
|
||||
|
||||
noselect Do not select a match in the menu, force the user to
|
||||
select one from the menu. Only works in combination with
|
||||
"menu" or "menuone".
|
||||
noselect Same as "noinsert", except that no menu item is
|
||||
pre-selected. If both "noinsert" and "noselect" are present,
|
||||
"noselect" has precedence.
|
||||
|
||||
fuzzy Enable |fuzzy-matching| for completion candidates. This
|
||||
allows for more flexible and intuitive matching, where
|
||||
@ -2977,7 +2977,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
An |OptionSet| autocmd can be used to set it up to match automatically.
|
||||
|
||||
*'guicursor'* *'gcr'* *E545* *E546* *E548* *E549*
|
||||
'guicursor' 'gcr' string (default "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20")
|
||||
'guicursor' 'gcr' string (default "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20,t:block-blinkon500-blinkoff500-TermCursor")
|
||||
global
|
||||
Configures the cursor style for each mode. Works in the GUI and many
|
||||
terminals. See |tui-cursor-shape|.
|
||||
@ -3005,6 +3005,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
ci Command-line Insert mode
|
||||
cr Command-line Replace mode
|
||||
sm showmatch in Insert mode
|
||||
t Terminal mode
|
||||
a all modes
|
||||
The argument-list is a dash separated list of these arguments:
|
||||
hor{N} horizontal bar, {N} percent of the character height
|
||||
@ -3021,7 +3022,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
cursor is not shown. Times are in msec. When one of
|
||||
the numbers is zero, there is no blinking. E.g.: >vim
|
||||
set guicursor=n:blinkon0
|
||||
< - Default is "blinkon0" for each mode.
|
||||
<
|
||||
Default is "blinkon0" for each mode.
|
||||
{group-name}
|
||||
Highlight group that decides the color and font of the
|
||||
cursor.
|
||||
@ -3197,7 +3199,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
global
|
||||
A history of ":" commands, and a history of previous search patterns
|
||||
is remembered. This option decides how many entries may be stored in
|
||||
each of these histories (see |cmdline-editing| and 'msghistory' for
|
||||
each of these histories (see |cmdline-editing| and 'messagesopt' for
|
||||
the number of messages to remember).
|
||||
The maximum value is 10000.
|
||||
|
||||
@ -4045,6 +4047,28 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
generated from a list of items, e.g., the Buffers menu. Changing this
|
||||
option has no direct effect, the menu must be refreshed first.
|
||||
|
||||
*'messagesopt'* *'mopt'*
|
||||
'messagesopt' 'mopt' string (default "hit-enter,history:500")
|
||||
global
|
||||
Option settings for outputting messages. It can consist of the
|
||||
following items. Items must be separated by a comma.
|
||||
|
||||
hit-enter Use a |hit-enter| prompt when the message is longer than
|
||||
'cmdheight' size.
|
||||
|
||||
wait:{n} Instead of using a |hit-enter| prompt, simply wait for
|
||||
{n} milliseconds so that the user has a chance to read
|
||||
the message. The maximum value of {n} is 10000. Use
|
||||
0 to disable the wait (but then the user may miss an
|
||||
important message).
|
||||
This item is ignored when "hit-enter" is present, but
|
||||
required when "hit-enter" is not present.
|
||||
|
||||
history:{n} Determines how many entries are remembered in the
|
||||
|:messages| history. The maximum value is 10000.
|
||||
Setting it to zero clears the message history.
|
||||
This item must always be present.
|
||||
|
||||
*'mkspellmem'* *'msm'*
|
||||
'mkspellmem' 'msm' string (default "460000,2000,500")
|
||||
global
|
||||
@ -4290,13 +4314,6 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
Defines the maximum time in msec between two mouse clicks for the
|
||||
second click to be recognized as a multi click.
|
||||
|
||||
*'msghistory'* *'mhi'*
|
||||
'msghistory' 'mhi' number (default 500)
|
||||
global
|
||||
Determines how many entries are remembered in the |:messages| history.
|
||||
The maximum value is 10000.
|
||||
Setting it to zero clears the message history.
|
||||
|
||||
*'nrformats'* *'nf'*
|
||||
'nrformats' 'nf' string (default "bin,hex")
|
||||
local to buffer
|
||||
@ -4795,6 +4812,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
indent/ indent scripts |indent-expression|
|
||||
keymap/ key mapping files |mbyte-keymap|
|
||||
lang/ menu translations |:menutrans|
|
||||
lsp/ LSP client configurations |lsp-config|
|
||||
lua/ |Lua| plugins
|
||||
menu.vim GUI menus |menu.vim|
|
||||
pack/ packages |:packadd|
|
||||
@ -4966,6 +4984,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
selection.
|
||||
When "old" is used and 'virtualedit' allows the cursor to move past
|
||||
the end of line the line break still isn't included.
|
||||
When "exclusive" is used, cursor position in visual mode will be
|
||||
adjusted for inclusive motions |inclusive-motion-selection-exclusive|.
|
||||
Note that when "exclusive" is used and selecting from the end
|
||||
backwards, you cannot include the last character of a line, when
|
||||
starting in Normal mode and 'virtualedit' empty.
|
||||
@ -5917,6 +5937,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
All fields except the {item} are optional. A single percent sign can
|
||||
be given as "%%".
|
||||
|
||||
*stl-%!*
|
||||
When the option starts with "%!" then it is used as an expression,
|
||||
evaluated and the result is used as the option value. Example: >vim
|
||||
set statusline=%!MyStatusLine()
|
||||
|
@ -193,7 +193,7 @@ registers. Nvim looks for these clipboard tools, in order of priority:
|
||||
- xclip (if $DISPLAY is set)
|
||||
- lemonade (for SSH) https://github.com/pocke/lemonade
|
||||
- doitclient (for SSH) https://www.chiark.greenend.org.uk/~sgtatham/doit/
|
||||
- win32yank (Windows)
|
||||
- *win32yank* (Windows)
|
||||
- putclip, getclip (Windows) https://cygwin.com/packages/summary/cygutils.html
|
||||
- clip, powershell (Windows) https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/clip
|
||||
- termux (via termux-clipboard-set, termux-clipboard-set)
|
||||
|
@ -1317,9 +1317,117 @@ g:compiler_gcc_ignore_unmatched_lines
|
||||
JAVAC *compiler-javac*
|
||||
|
||||
Commonly used compiler options can be added to 'makeprg' by setting the
|
||||
g:javac_makeprg_params variable. For example: >
|
||||
b/g:javac_makeprg_params variable. For example: >
|
||||
|
||||
let g:javac_makeprg_params = "-Xlint:all -encoding utf-8"
|
||||
<
|
||||
|
||||
MAVEN *compiler-maven*
|
||||
|
||||
Commonly used compiler options can be added to 'makeprg' by setting the
|
||||
b/g:maven_makeprg_params variable. For example: >
|
||||
|
||||
let g:maven_makeprg_params = "-DskipTests -U -X"
|
||||
|
||||
SPOTBUGS *compiler-spotbugs*
|
||||
|
||||
SpotBugs is a static analysis tool that can be used to find bugs in Java.
|
||||
It scans the Java bytecode of all classes in the currently open buffer.
|
||||
(Therefore, `:compiler! spotbugs` is not supported.)
|
||||
|
||||
Commonly used compiler options can be added to 'makeprg' by setting the
|
||||
"b:" or "g:spotbugs_makeprg_params" variable. For example: >
|
||||
|
||||
let b:spotbugs_makeprg_params = "-longBugCodes -effort:max -low"
|
||||
|
||||
The global default is "-workHard -experimental".
|
||||
|
||||
By default, the class files are searched in the directory where the source
|
||||
files are placed. However, typical Java projects use distinct directories
|
||||
for source files and class files. To make both known to SpotBugs, assign
|
||||
their paths (distinct and relative to their common root directory) to the
|
||||
following properties (using the example of a common Maven project): >
|
||||
|
||||
let g:spotbugs_properties = {
|
||||
\ 'sourceDirPath': 'src/main/java',
|
||||
\ 'classDirPath': 'target/classes',
|
||||
\ 'testSourceDirPath': 'src/test/java',
|
||||
\ 'testClassDirPath': 'target/test-classes',
|
||||
\ }
|
||||
|
||||
Note that values for the path keys describe only for SpotBugs where to look
|
||||
for files; refer to the documentation for particular compiler plugins for more
|
||||
information.
|
||||
|
||||
The default pre- and post-compiler actions are provided for Ant, Maven, and
|
||||
Javac compiler plugins and can be selected by assigning the name of a compiler
|
||||
plugin to the "compiler" key: >
|
||||
|
||||
let g:spotbugs_properties = {
|
||||
\ 'compiler': 'maven',
|
||||
\ }
|
||||
|
||||
This single setting is essentially equivalent to all the settings below, with
|
||||
the exception made for the "PreCompilerAction" and "PreCompilerTestAction"
|
||||
values: their listed |Funcref|s will obtain no-op implementations whereas the
|
||||
implicit Funcrefs of the "compiler" key will obtain the requested defaults if
|
||||
available. >
|
||||
|
||||
let g:spotbugs_properties = {
|
||||
\ 'PreCompilerAction':
|
||||
\ function('spotbugs#DefaultPreCompilerAction'),
|
||||
\ 'PreCompilerTestAction':
|
||||
\ function('spotbugs#DefaultPreCompilerTestAction'),
|
||||
\ 'PostCompilerAction':
|
||||
\ function('spotbugs#DefaultPostCompilerAction'),
|
||||
\ 'sourceDirPath': 'src/main/java',
|
||||
\ 'classDirPath': 'target/classes',
|
||||
\ 'testSourceDirPath': 'src/test/java',
|
||||
\ 'testClassDirPath': 'target/test-classes',
|
||||
\ }
|
||||
|
||||
With default actions, the compiler of choice will attempt to rebuild the class
|
||||
files for the buffer (and possibly for the whole project) as soon as a Java
|
||||
syntax file is loaded; then, `spotbugs` will attempt to analyze the quality of
|
||||
the compilation unit of the buffer.
|
||||
|
||||
When default actions are not suited to a desired workflow, consider writing
|
||||
arbitrary functions yourself and matching their |Funcref|s to the supported
|
||||
keys: "PreCompilerAction", "PreCompilerTestAction", and "PostCompilerAction".
|
||||
|
||||
The next example re-implements the default pre-compiler actions for a Maven
|
||||
project and requests other default Maven settings with the "compiler" entry: >
|
||||
|
||||
function! MavenPreCompilerAction() abort
|
||||
call spotbugs#DeleteClassFiles()
|
||||
compiler maven
|
||||
make compile
|
||||
endfunction
|
||||
|
||||
function! MavenPreCompilerTestAction() abort
|
||||
call spotbugs#DeleteClassFiles()
|
||||
compiler maven
|
||||
make test-compile
|
||||
endfunction
|
||||
|
||||
let g:spotbugs_properties = {
|
||||
\ 'compiler': 'maven',
|
||||
\ 'PreCompilerAction':
|
||||
\ function('MavenPreCompilerAction'),
|
||||
\ 'PreCompilerTestAction':
|
||||
\ function('MavenPreCompilerTestAction'),
|
||||
\ }
|
||||
|
||||
Note that all entered custom settings will take precedence over the matching
|
||||
default settings in "g:spotbugs_properties".
|
||||
|
||||
The "g:spotbugs_properties" variable is consulted by the Java filetype plugin
|
||||
(|ft-java-plugin|) to arrange for the described automation, and, therefore, it
|
||||
must be defined before |FileType| events can take place for the buffers loaded
|
||||
with Java source files. It could, for example, be set in a project-local
|
||||
|vimrc| loaded by [0].
|
||||
|
||||
[0] https://github.com/MarcWeber/vim-addon-local-vimrc/
|
||||
|
||||
GNU MAKE *compiler-make*
|
||||
|
||||
Since the default make program is "make", the compiler plugin for make,
|
||||
@ -1409,6 +1517,13 @@ Useful values for the 'makeprg' options therefore are:
|
||||
setlocal makeprg=./alltests.py " Run a testsuite
|
||||
setlocal makeprg=python\ %:S " Run a single testcase
|
||||
|
||||
PYTEST COMPILER *compiler-pytest*
|
||||
Commonly used compiler options can be added to 'makeprg' by setting the
|
||||
b/g:pytest_makeprg_params variable. For example: >
|
||||
|
||||
let b:pytest_makeprg_params = "--verbose --no-summary --disable-warnings"
|
||||
|
||||
The global default is "--tb=short --quiet"; Python warnings are suppressed.
|
||||
|
||||
TEX COMPILER *compiler-tex*
|
||||
|
||||
|
@ -10,7 +10,7 @@ Sign Support Features *sign-support*
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
1. Introduction *sign-intro* *signs*
|
||||
1. Introduction *sign-intro* *signs* *gutter*
|
||||
|
||||
When a debugger or other IDE tool is driving an editor it needs to be able
|
||||
to give specific highlights which quickly tell the user useful information
|
||||
|
@ -414,12 +414,15 @@ There are many types of assembly languages that all use the same file name
|
||||
extensions. Therefore you will have to select the type yourself, or add a
|
||||
line in the assembly file that Vim will recognize. Currently these syntax
|
||||
files are included:
|
||||
asm GNU assembly (the default)
|
||||
asm GNU assembly (usually have .s or .S extension and were
|
||||
already built using C compiler such as GCC or CLANG)
|
||||
asm68k Motorola 680x0 assembly
|
||||
asmh8300 Hitachi H-8300 version of GNU assembly
|
||||
ia64 Intel Itanium 64
|
||||
fasm Flat assembly (https://flatassembler.net)
|
||||
masm Microsoft assembly (probably works for any 80x86)
|
||||
masm Microsoft assembly (.masm files are compiled with
|
||||
Microsoft's Macro Assembler. This is only supported
|
||||
for x86, x86_64, ARM and AARCH64 CPU families)
|
||||
nasm Netwide assembly
|
||||
tasm Turbo Assembly (with opcodes 80x86 up to Pentium, and
|
||||
MMX)
|
||||
@ -5159,8 +5162,6 @@ EndOfBuffer Filler lines (~) after the end of the buffer.
|
||||
By default, this is highlighted like |hl-NonText|.
|
||||
*hl-TermCursor*
|
||||
TermCursor Cursor in a focused terminal.
|
||||
*hl-TermCursorNC*
|
||||
TermCursorNC Cursor in an unfocused terminal.
|
||||
*hl-ErrorMsg*
|
||||
ErrorMsg Error messages on the command line.
|
||||
*hl-WinSeparator*
|
||||
@ -5242,6 +5243,8 @@ PmenuMatch Popup menu: Matched text in normal item. Combined with
|
||||
*hl-PmenuMatchSel*
|
||||
PmenuMatchSel Popup menu: Matched text in selected item. Combined with
|
||||
|hl-PmenuMatch| and |hl-PmenuSel|.
|
||||
*hl-ComplMatchIns*
|
||||
ComplMatchIns Matched text of the currently inserted completion.
|
||||
*hl-Question*
|
||||
Question |hit-enter| prompt and yes/no questions.
|
||||
*hl-QuickFixLine*
|
||||
|
@ -26,7 +26,7 @@ Start *terminal-start*
|
||||
There are several ways to create a terminal buffer:
|
||||
|
||||
- Run the |:terminal| command.
|
||||
- Call the |nvim_open_term()| or |termopen()| function.
|
||||
- Call |nvim_open_term()| or `jobstart(…, {'term': v:true})`.
|
||||
- Edit a "term://" buffer. Examples: >vim
|
||||
:edit term://bash
|
||||
:vsplit term://top
|
||||
@ -101,13 +101,17 @@ Configuration *terminal-config*
|
||||
|
||||
Options: 'modified', 'scrollback'
|
||||
Events: |TermOpen|, |TermEnter|, |TermLeave|, |TermClose|
|
||||
Highlight groups: |hl-TermCursor|, |hl-TermCursorNC|
|
||||
Highlight groups: |hl-TermCursor|
|
||||
|
||||
Terminal sets local defaults for some options, which may differ from your
|
||||
global configuration.
|
||||
|
||||
- 'list' is disabled
|
||||
- 'wrap' is disabled
|
||||
- 'number' is disabled
|
||||
- 'relativenumber' is disabled
|
||||
- 'signcolumn' is set to "no"
|
||||
- 'foldcolumn' is set to "0"
|
||||
|
||||
You can change the defaults with a TermOpen autocommand: >vim
|
||||
au TermOpen * setlocal list
|
||||
|
@ -245,15 +245,32 @@ The following directives are built in:
|
||||
(#gsub! @_node ".*%.(.*)" "%1")
|
||||
<
|
||||
`trim!` *treesitter-directive-trim!*
|
||||
Trim blank lines from the end of the node. This will set a new
|
||||
`metadata[capture_id].range`.
|
||||
Trims whitespace from the node. Sets a new
|
||||
`metadata[capture_id].range`. Takes a capture ID and, optionally, four
|
||||
integers to customize trimming behavior (`1` meaning trim, `0` meaning
|
||||
don't trim). When only given a capture ID, trims blank lines (lines
|
||||
that contain only whitespace, or are empty) from the end of the node
|
||||
(for backwards compatibility). Can trim all whitespace from both sides
|
||||
of the node if parameters are given.
|
||||
|
||||
Examples: >query
|
||||
; only trim blank lines from the end of the node
|
||||
; (equivalent to (#trim! @fold 0 0 1 0))
|
||||
(#trim! @fold)
|
||||
|
||||
; trim blank lines from both sides of the node
|
||||
(#trim! @fold 1 0 1 0)
|
||||
|
||||
; trim all whitespace around the node
|
||||
(#trim! @fold 1 1 1 1)
|
||||
<
|
||||
Parameters: ~
|
||||
{capture_id}
|
||||
{trim_start_linewise}
|
||||
{trim_start_charwise}
|
||||
{trim_end_linewise} (default `1` if only given {capture_id})
|
||||
{trim_end_charwise}
|
||||
|
||||
Example: >query
|
||||
(#trim! @fold)
|
||||
<
|
||||
Further directives can be added via |vim.treesitter.query.add_directive()|.
|
||||
Use |vim.treesitter.query.list_directives()| to list all available directives.
|
||||
|
||||
@ -885,8 +902,8 @@ get_captures_at_pos({bufnr}, {row}, {col})
|
||||
Returns a list of highlight captures at the given position
|
||||
|
||||
Each capture is represented by a table containing the capture name as a
|
||||
string as well as a table of metadata (`priority`, `conceal`, ...; empty
|
||||
if none are defined).
|
||||
string, the capture's language, a table of metadata (`priority`,
|
||||
`conceal`, ...; empty if none are defined), and the id of the capture.
|
||||
|
||||
Parameters: ~
|
||||
• {bufnr} (`integer`) Buffer number (0 for current buffer)
|
||||
@ -894,7 +911,7 @@ get_captures_at_pos({bufnr}, {row}, {col})
|
||||
• {col} (`integer`) Position column
|
||||
|
||||
Return: ~
|
||||
(`{capture: string, lang: string, metadata: vim.treesitter.query.TSMetadata}[]`)
|
||||
(`{capture: string, lang: string, metadata: vim.treesitter.query.TSMetadata, id: integer}[]`)
|
||||
|
||||
get_node({opts}) *vim.treesitter.get_node()*
|
||||
Returns the smallest named node at the given position
|
||||
|
@ -788,7 +788,8 @@ must handle.
|
||||
|
||||
kind
|
||||
Name indicating the message kind:
|
||||
"" (empty) Unknown (consider a feature-request: |bugs|)
|
||||
"" (empty) Unknown (consider a |feature-request|)
|
||||
"bufwrite" |:write| message
|
||||
"confirm" |confirm()| or |:confirm| dialog
|
||||
"confirm_sub" |:substitute| confirm dialog |:s_c|
|
||||
"emsg" Error (|errors|, internal error, |:throw|, …)
|
||||
@ -804,6 +805,7 @@ must handle.
|
||||
"quickfix" Quickfix navigation message
|
||||
"search_cmd" Entered search command
|
||||
"search_count" Search count message ("S" flag of 'shortmess')
|
||||
"undo" |:undo| and |:redo| message
|
||||
"wildlist" 'wildmode' "list" message
|
||||
"wmsg" Warning ("search hit BOTTOM", |W10|, …)
|
||||
New kinds may be added in the future; clients should treat unknown
|
||||
|
@ -534,7 +534,8 @@ gO Show a filetype-specific, navigable "outline" of the
|
||||
current buffer. For example, in a |help| buffer this
|
||||
shows the table of contents.
|
||||
|
||||
Currently works in |help| and |:Man| buffers.
|
||||
Works in |help| and |:Man| buffers, or any buffer with
|
||||
an active |LSP| client (|lsp-defaults|).
|
||||
|
||||
[N]gs *gs* *:sl* *:sleep*
|
||||
:[N]sl[eep] [N][m] Do nothing for [N] seconds, or [N] milliseconds if [m]
|
||||
@ -551,8 +552,7 @@ gO Show a filetype-specific, navigable "outline" of the
|
||||
Queued messages are processed during the sleep.
|
||||
|
||||
*:sl!* *:sleep!*
|
||||
:[N]sl[eep]! [N][m] Same as above. Unlike Vim, it does not hide the
|
||||
cursor. |vim-differences|
|
||||
:[N]sl[eep]! [N][m] Same as above, but hide the cursor.
|
||||
|
||||
==============================================================================
|
||||
2. Using Vim like less or more *less*
|
||||
|
73
runtime/doc/vietnamese.txt
Normal file
73
runtime/doc/vietnamese.txt
Normal file
@ -0,0 +1,73 @@
|
||||
*vietnamese.txt* Nvim
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Phạm Bình An
|
||||
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
===============================================================================
|
||||
1. Introduction
|
||||
*vietnamese-intro*
|
||||
Vim supports Vietnamese language in the following ways:
|
||||
|
||||
- Built-in |vietnamese-keymap|, which allows you to type Vietnamese characters
|
||||
in |Insert-mode| and |search-commands| using US keyboard layout.
|
||||
- Localization in Vietnamese. See |vietnamese-l10n|
|
||||
|
||||
===============================================================================
|
||||
2. Vietnamese keymaps
|
||||
*vietnamese-keymap*
|
||||
To switch between languages you can use your system native keyboard switcher,
|
||||
or use one of the Vietnamese keymaps included in the Vim distribution, like
|
||||
below >
|
||||
:set keymap=vietnamese-telex_utf-8
|
||||
<
|
||||
See |'keymap'| for more information.
|
||||
|
||||
In the latter case, you can type Vietnamese even if you do not have a
|
||||
Vietnamese input method engine (IME) or you want Vim to be independent from a
|
||||
system-wide keyboard settings (when |'imdisable'| is set). You can also |:map|
|
||||
a key to switch between keyboards.
|
||||
|
||||
Vim comes with the following Vietnamese keymaps:
|
||||
- *vietnamese-telex_utf-8* Telex input method, |UTF-8| encoding.
|
||||
- *vietnamese-viqr_utf-8* VIQR input method, |UTF-8| encoding.
|
||||
- *vietnamese-vni_utf-8* VNI input method, |UTF-8| encoding.
|
||||
|
||||
*vietnamese-ime_diff*
|
||||
Since these keymaps were designed to be minimalistic, they do not support all
|
||||
features of the corresponding input methods. The differences are described
|
||||
below:
|
||||
|
||||
- You can only type each character individually, entering the base letter first
|
||||
and then the diacritics later. For example, to type the word `nến` using
|
||||
|vietnamese-vni_utf-8|, you must type `ne61n`, not `nen61` or `ne6n1`
|
||||
- For characters with more than 1 diacritic, you need to type vowel mark before
|
||||
tone mark. For example, to type `ồ` using |vietnamese-telex_utf-8|, you need
|
||||
to type `oof`, not `ofo`.
|
||||
- With |vietnamese-telex_utf-8|, you need to type all uppercase letters to
|
||||
produce uppercase characters with diacritics. For example, `Ừ` must be typed
|
||||
as `UWF`.
|
||||
- With |vietnamese-telex_utf-8|, the escape character `\` from VNI is added,
|
||||
hence the confusing `ooo` input to type `oo` is removed, which could lead to
|
||||
ambiguities. For example, to type the word `Đoòng`, you would type
|
||||
`DDo\ofng`.
|
||||
- Simple Telex (both v1 and v2), including the `w[]{}` style, is not
|
||||
supported.
|
||||
- Removing diacritics using `z` in Telex or `0` in VNI and VIQR is not supported.
|
||||
|
||||
===============================================================================
|
||||
3. Localization
|
||||
*vietnamese-l10n*
|
||||
Vim |messages| are also available in Vietnamese. If you wish to see messages
|
||||
in Vietnamese, you can run the command |:language| with an argument being the
|
||||
name of the Vietnamese locale. For example, >
|
||||
:language vi_VN
|
||||
< or >
|
||||
:language vi_VN.utf-8
|
||||
<
|
||||
Note that the name of the Vietnamese locale may vary depending on your system.
|
||||
See |mbyte-first| for details.
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
@ -39,7 +39,6 @@ Defaults *nvim-defaults*
|
||||
- 'autoindent' is enabled
|
||||
- 'autoread' is enabled (works in all UIs, including terminal)
|
||||
- 'background' defaults to "dark" (unless set automatically by the terminal/UI)
|
||||
- 'backspace' defaults to "indent,eol,start"
|
||||
- 'backupdir' defaults to .,~/.local/state/nvim/backup// (|xdg|), auto-created
|
||||
- 'belloff' defaults to "all"
|
||||
- 'comments' includes "fb:•"
|
||||
@ -187,6 +186,10 @@ nvim_terminal:
|
||||
- 'textwidth' set to 0
|
||||
- 'nowrap'
|
||||
- 'nolist'
|
||||
- 'nonumber'
|
||||
- 'norelativenumber'
|
||||
- 'signcolumn' set to "no"
|
||||
- 'foldcolumn' set to "0"
|
||||
- 'winhighlight' uses |hl-StatusLineTerm| and |hl-StatusLineTermNC| in
|
||||
place of |hl-StatusLine| and |hl-StatusLineNC|
|
||||
|
||||
@ -322,7 +325,6 @@ Highlight groups:
|
||||
- |hl-MsgSeparator| highlights separator for scrolled messages
|
||||
- |hl-Substitute|
|
||||
- |hl-TermCursor|
|
||||
- |hl-TermCursorNC|
|
||||
- |hl-WinSeparator| highlights window separators
|
||||
- |hl-Whitespace| highlights 'listchars' whitespace
|
||||
- |hl-WinBar| highlights 'winbar'
|
||||
@ -667,7 +669,6 @@ Commands:
|
||||
- :promptrepl
|
||||
- :scriptversion (always version 1)
|
||||
- :shell
|
||||
- :sleep! (does not hide the cursor; same as :sleep)
|
||||
- :smile
|
||||
- :tearoff
|
||||
- :cstag
|
||||
@ -687,7 +688,7 @@ Cscope:
|
||||
https://github.com/dhananjaylatkar/cscope_maps.nvim
|
||||
|
||||
Eval:
|
||||
- Vim9script
|
||||
- *Vim9script* (the Vim 9+ flavor of Vimscript) is not supported.
|
||||
- *cscope_connection()*
|
||||
- *err_teapot()*
|
||||
- *js_encode()*
|
||||
|
@ -189,6 +189,8 @@ v:event
|
||||
changing window (or tab) on |DirChanged|.
|
||||
status Job status or exit code, -1 means "unknown". |TermClose|
|
||||
reason Reason for completion being done. |CompleteDone|
|
||||
complete_word The word that was selected, empty if abandoned complete.
|
||||
complete_type See |complete_info_mode|
|
||||
|
||||
*v:exception* *exception-variable*
|
||||
v:exception
|
||||
|
@ -978,6 +978,13 @@ CTRL-W g } *CTRL-W_g}*
|
||||
it. Make the new Preview window (if required) N high. If N is
|
||||
not given, 'previewheight' is used.
|
||||
|
||||
*:pb* *:pbuffer*
|
||||
:[N]pb[uffer][!] [+cmd] [N]
|
||||
Edit buffer [N] from the buffer list in the preview window.
|
||||
If [N] is not given, the current buffer remains being edited.
|
||||
See |:buffer-!| for [!]. This will also edit a buffer that is
|
||||
not in the buffer list, without setting the 'buflisted' flag.
|
||||
|
||||
*:ped* *:pedit*
|
||||
:ped[it][!] [++opt] [+cmd] {file}
|
||||
Edit {file} in the preview window. The preview window is
|
||||
@ -985,6 +992,8 @@ CTRL-W g } *CTRL-W_g}*
|
||||
position isn't changed. Useful example: >
|
||||
:pedit +/fputc /usr/include/stdio.h
|
||||
<
|
||||
Also see |++opt| and |+cmd|.
|
||||
|
||||
*:ps* *:psearch*
|
||||
:[range]ps[earch][!] [count] [/]pattern[/]
|
||||
Works like |:ijump| but shows the found match in the preview
|
||||
|
@ -13,8 +13,8 @@ vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile', 'StdinReadPost' }, {
|
||||
end
|
||||
local ft, on_detect = vim.filetype.match({
|
||||
-- The unexpanded file name is needed here. #27914
|
||||
-- Neither args.file nor args.match are guaranteed to be unexpanded.
|
||||
filename = vim.fn.bufname(args.buf),
|
||||
-- However, bufname() can't be used, as it doesn't work with :doautocmd. #31306
|
||||
filename = args.file,
|
||||
buf = args.buf,
|
||||
})
|
||||
if not ft then
|
||||
|
@ -3,7 +3,7 @@
|
||||
" Maintainer: Aliaksei Budavei <0x000c70 AT gmail DOT com>
|
||||
" Former Maintainer: Dan Sharp
|
||||
" Repository: https://github.com/zzzyxwvut/java-vim.git
|
||||
" Last Change: 2024 Sep 26
|
||||
" Last Change: 2024 Nov 24
|
||||
" 2024 Jan 14 by Vim Project (browsefilter)
|
||||
" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
|
||||
|
||||
@ -90,10 +90,127 @@ if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
|
||||
endif
|
||||
endif
|
||||
|
||||
" The support for pre- and post-compiler actions for SpotBugs.
|
||||
if exists("g:spotbugs_properties") && has_key(g:spotbugs_properties, 'compiler')
|
||||
try
|
||||
let spotbugs#compiler = g:spotbugs_properties.compiler
|
||||
let g:spotbugs_properties = extend(
|
||||
\ spotbugs#DefaultProperties(),
|
||||
\ g:spotbugs_properties,
|
||||
\ 'force')
|
||||
catch
|
||||
echomsg v:errmsg
|
||||
finally
|
||||
call remove(g:spotbugs_properties, 'compiler')
|
||||
endtry
|
||||
endif
|
||||
|
||||
if exists("g:spotbugs_properties") &&
|
||||
\ filereadable($VIMRUNTIME . '/compiler/spotbugs.vim')
|
||||
let s:request = 0
|
||||
|
||||
if has_key(g:spotbugs_properties, 'PreCompilerAction')
|
||||
let s:dispatcher = 'call g:spotbugs_properties.PreCompilerAction() | '
|
||||
let s:request += 1
|
||||
endif
|
||||
|
||||
if has_key(g:spotbugs_properties, 'PreCompilerTestAction')
|
||||
let s:dispatcher = 'call g:spotbugs_properties.PreCompilerTestAction() | '
|
||||
let s:request += 2
|
||||
endif
|
||||
|
||||
if has_key(g:spotbugs_properties, 'PostCompilerAction')
|
||||
let s:request += 4
|
||||
endif
|
||||
|
||||
if (s:request == 3 || s:request == 7) &&
|
||||
\ has_key(g:spotbugs_properties, 'sourceDirPath') &&
|
||||
\ has_key(g:spotbugs_properties, 'testSourceDirPath')
|
||||
function! s:DispatchAction(path_action_pairs) abort
|
||||
let name = expand('%:p')
|
||||
|
||||
for [path, Action] in a:path_action_pairs
|
||||
if name =~# (path . '.\{-}\.java\=$')
|
||||
call Action()
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
let s:dispatcher = printf('call s:DispatchAction(%s) | ',
|
||||
\ string([[g:spotbugs_properties.sourceDirPath,
|
||||
\ g:spotbugs_properties.PreCompilerAction],
|
||||
\ [g:spotbugs_properties.testSourceDirPath,
|
||||
\ g:spotbugs_properties.PreCompilerTestAction]]))
|
||||
endif
|
||||
|
||||
if s:request
|
||||
if exists("b:spotbugs_syntax_once")
|
||||
let s:actions = [{'event': 'BufWritePost'}]
|
||||
else
|
||||
" XXX: Handle multiple FileType events when vimrc contains more
|
||||
" than one filetype setting for the language, e.g.:
|
||||
" :filetype plugin indent on
|
||||
" :autocmd BufRead,BufNewFile *.java setlocal filetype=java ...
|
||||
" XXX: DO NOT ADD b:spotbugs_syntax_once TO b:undo_ftplugin !
|
||||
let b:spotbugs_syntax_once = 1
|
||||
let s:actions = [{
|
||||
\ 'event': 'Syntax',
|
||||
\ 'once': 1,
|
||||
\ }, {
|
||||
\ 'event': 'BufWritePost',
|
||||
\ }]
|
||||
endif
|
||||
|
||||
for s:idx in range(len(s:actions))
|
||||
if s:request == 7 || s:request == 6 || s:request == 5
|
||||
let s:actions[s:idx].cmd = s:dispatcher . 'compiler spotbugs | ' .
|
||||
\ 'call g:spotbugs_properties.PostCompilerAction()'
|
||||
elseif s:request == 4
|
||||
let s:actions[s:idx].cmd = 'compiler spotbugs | ' .
|
||||
\ 'call g:spotbugs_properties.PostCompilerAction()'
|
||||
elseif s:request == 3 || s:request == 2 || s:request == 1
|
||||
let s:actions[s:idx].cmd = s:dispatcher . 'compiler spotbugs'
|
||||
else
|
||||
let s:actions[s:idx].cmd = ''
|
||||
endif
|
||||
endfor
|
||||
|
||||
if !exists("#java_spotbugs")
|
||||
augroup java_spotbugs
|
||||
augroup END
|
||||
endif
|
||||
|
||||
" The events are defined in s:actions.
|
||||
silent! autocmd! java_spotbugs BufWritePost <buffer>
|
||||
silent! autocmd! java_spotbugs Syntax <buffer>
|
||||
|
||||
for s:action in s:actions
|
||||
execute printf('autocmd java_spotbugs %s <buffer> %s',
|
||||
\ s:action.event,
|
||||
\ s:action.cmd . (has_key(s:action, 'once')
|
||||
\ ? printf(' | autocmd! java_spotbugs %s <buffer>',
|
||||
\ s:action.event)
|
||||
\ : ''))
|
||||
endfor
|
||||
|
||||
unlet! s:action s:actions s:idx s:dispatcher
|
||||
endif
|
||||
|
||||
unlet s:request
|
||||
endif
|
||||
|
||||
function! JavaFileTypeCleanUp() abort
|
||||
setlocal suffixes< suffixesadd< formatoptions< comments< commentstring< path< includeexpr<
|
||||
unlet! b:browsefilter
|
||||
|
||||
" The concatenated removals may be misparsed as a BufWritePost autocmd.
|
||||
silent! autocmd! java_spotbugs BufWritePost <buffer>
|
||||
silent! autocmd! java_spotbugs Syntax <buffer>
|
||||
endfunction
|
||||
|
||||
" Undo the stuff we changed.
|
||||
let b:undo_ftplugin = "setlocal suffixes< suffixesadd<" .
|
||||
\ " formatoptions< comments< commentstring< path< includeexpr<" .
|
||||
\ " | unlet! b:browsefilter"
|
||||
let b:undo_ftplugin = 'call JavaFileTypeCleanUp() | delfunction JavaFileTypeCleanUp'
|
||||
|
||||
" See ":help vim9-mix".
|
||||
if !has("vim9script")
|
||||
@ -114,6 +231,19 @@ if exists("s:zip_func_upgradable")
|
||||
setlocal suffixesadd<
|
||||
endif
|
||||
|
||||
if exists("*s:DispatchAction")
|
||||
def! s:DispatchAction(path_action_pairs: list<list<any>>)
|
||||
const name: string = expand('%:p')
|
||||
|
||||
for [path: string, Action: func: any] in path_action_pairs
|
||||
if name =~# (path .. '.\{-}\.java\=$')
|
||||
Action()
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
enddef
|
||||
endif
|
||||
|
||||
" Restore the saved compatibility options.
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
18
runtime/ftplugin/proto.vim
Normal file
18
runtime/ftplugin/proto.vim
Normal file
@ -0,0 +1,18 @@
|
||||
" Vim filetype plugin
|
||||
" Language: Protobuf
|
||||
" Maintainer: David Pedersen <limero@me.com>
|
||||
" Last Change: 2024 Dec 09
|
||||
|
||||
if exists('b:did_ftplugin')
|
||||
finish
|
||||
endif
|
||||
let b:did_ftplugin = 1
|
||||
|
||||
setlocal formatoptions-=t formatoptions+=croql
|
||||
|
||||
setlocal comments=s1:/*,mb:*,ex:*/,://
|
||||
setlocal commentstring=//\ %s
|
||||
|
||||
let b:undo_ftplugin = "setlocal formatoptions< comments< commentstring<"
|
||||
|
||||
" vim: sw=2 sts=2 et
|
16
runtime/ftplugin/ptx.vim
Normal file
16
runtime/ftplugin/ptx.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Vim filetype plugin file
|
||||
" Language: Nvidia PTX (Parellel Thread Execution)
|
||||
" Maintainer: Yinzuo Jiang <jiangyinzuo@foxmail.com>
|
||||
" Last Change: 2024-12-05
|
||||
|
||||
if exists("b:did_ftplugin")
|
||||
finish
|
||||
endif
|
||||
|
||||
let b:did_ftplugin = 1
|
||||
|
||||
" Comments in PTX follow C/C++ syntax
|
||||
" See: https://docs.nvidia.com/cuda/parallel-thread-execution/#syntax
|
||||
setlocal commentstring=//\ %s
|
||||
|
||||
let b:undo_ftplugin = 'setl commentstring<'
|
@ -3,8 +3,9 @@
|
||||
" Maintainer: Tom Picton <tom@tompicton.com>
|
||||
" Previous Maintainer: James Sully <sullyj3@gmail.com>
|
||||
" Previous Maintainer: Johannes Zellner <johannes@zellner.org>
|
||||
" Last Change: 2024/05/13
|
||||
" https://github.com/tpict/vim-ftplugin-python
|
||||
" Repository: https://github.com/tpict/vim-ftplugin-python
|
||||
" Last Change: 2024/05/13
|
||||
" 2024 Nov 30 use pytest compiler (#16130)
|
||||
|
||||
if exists("b:did_ftplugin") | finish | endif
|
||||
let b:did_ftplugin = 1
|
||||
@ -134,6 +135,11 @@ elseif executable('python')
|
||||
setlocal keywordprg=python\ -m\ pydoc
|
||||
endif
|
||||
|
||||
if expand('%:t') =~# '\v^test_.*\.py$|_test\.py$' && executable('pytest')
|
||||
compiler pytest
|
||||
let &l:makeprg .= ' %:S'
|
||||
endif
|
||||
|
||||
" Script for filetype switching to undo the local stuff we may have changed
|
||||
let b:undo_ftplugin = 'setlocal cinkeys<'
|
||||
\ . '|setlocal comments<'
|
||||
@ -148,6 +154,7 @@ let b:undo_ftplugin = 'setlocal cinkeys<'
|
||||
\ . '|setlocal softtabstop<'
|
||||
\ . '|setlocal suffixesadd<'
|
||||
\ . '|setlocal tabstop<'
|
||||
\ . '|setlocal makeprg<'
|
||||
\ . '|silent! nunmap <buffer> [M'
|
||||
\ . '|silent! nunmap <buffer> [['
|
||||
\ . '|silent! nunmap <buffer> []'
|
||||
|
@ -1,7 +1,8 @@
|
||||
" Vim filetype plugin file
|
||||
" Language: Typst
|
||||
" Maintainer: Gregory Anders
|
||||
" Last Change: 2024 Oct 21
|
||||
" Previous Maintainer: Gregory Anders
|
||||
" Maintainer: Luca Saccarola <github.e41mv@aleeas.com>
|
||||
" Last Change: 2024 Dec 09
|
||||
" Based on: https://github.com/kaarmu/typst.vim
|
||||
|
||||
if exists('b:did_ftplugin')
|
||||
@ -11,10 +12,14 @@ let b:did_ftplugin = 1
|
||||
|
||||
setlocal commentstring=//\ %s
|
||||
setlocal comments=s1:/*,mb:*,ex:*/,://
|
||||
setlocal formatoptions+=croq
|
||||
setlocal formatoptions+=croqn
|
||||
" Numbered Lists
|
||||
setlocal formatlistpat=^\\s*\\d\\+[\\]:.)}\\t\ ]\\s*
|
||||
" Unordered (-), Ordered (+) and definition (/) Lists
|
||||
setlocal formatlistpat+=\\\|^\\s*[-+/\]\\s\\+
|
||||
setlocal suffixesadd=.typ
|
||||
|
||||
let b:undo_ftplugin = 'setl cms< com< fo< sua<'
|
||||
let b:undo_ftplugin = 'setl cms< com< fo< flp< sua<'
|
||||
|
||||
if get(g:, 'typst_conceal', 0)
|
||||
setlocal conceallevel=2
|
||||
|
@ -1,7 +1,8 @@
|
||||
" Vim indent file
|
||||
" Language: Typst
|
||||
" Maintainer: Gregory Anders <greg@gpanders.com>
|
||||
" Last Change: 2024-07-14
|
||||
" Previous Maintainer: Gregory Anders
|
||||
" Maintainer: Luca Saccarola <github.e41mv@aleeas.com>
|
||||
" Last Change: 2024 Dec 09
|
||||
" Based on: https://github.com/kaarmu/typst.vim
|
||||
|
||||
if exists('b:did_indent')
|
||||
|
@ -21,9 +21,12 @@ end
|
||||
local function system(cmd, silent, env)
|
||||
local r = vim.system(cmd, { env = env, timeout = 10000 }):wait()
|
||||
|
||||
if r.code ~= 0 and not silent then
|
||||
local cmd_str = table.concat(cmd, ' ')
|
||||
man_error(string.format("command error '%s': %s", cmd_str, r.stderr))
|
||||
if not silent then
|
||||
if r.code ~= 0 then
|
||||
local cmd_str = table.concat(cmd, ' ')
|
||||
man_error(string.format("command error '%s': %s", cmd_str, r.stderr))
|
||||
end
|
||||
assert(r.stdout ~= '')
|
||||
end
|
||||
|
||||
return assert(r.stdout)
|
||||
|
@ -49,10 +49,10 @@ do
|
||||
|
||||
vim.keymap.set('x', '*', function()
|
||||
return _visual_search('/')
|
||||
end, { desc = ':help v_star-default', expr = true, silent = true })
|
||||
end, { desc = ':help v_star-default', expr = true, replace_keycodes = false })
|
||||
vim.keymap.set('x', '#', function()
|
||||
return _visual_search('?')
|
||||
end, { desc = ':help v_#-default', expr = true, silent = true })
|
||||
end, { desc = ':help v_#-default', expr = true, replace_keycodes = false })
|
||||
end
|
||||
|
||||
--- Map Y to y$. This mimics the behavior of D and C. See |Y-default|
|
||||
@ -222,8 +222,8 @@ do
|
||||
--- Execute a command and print errors without a stacktrace.
|
||||
--- @param opts table Arguments to |nvim_cmd()|
|
||||
local function cmd(opts)
|
||||
local _, err = pcall(vim.api.nvim_cmd, opts, {})
|
||||
if err then
|
||||
local ok, err = pcall(vim.api.nvim_cmd, opts, {})
|
||||
if not ok then
|
||||
vim.api.nvim_err_writeln(err:sub(#'Vim:' + 1))
|
||||
end
|
||||
end
|
||||
@ -435,7 +435,7 @@ do
|
||||
group = nvim_terminal_augroup,
|
||||
desc = 'Treat term:// buffers as terminal buffers',
|
||||
nested = true,
|
||||
command = "if !exists('b:term_title')|call termopen(matchstr(expand(\"<amatch>\"), '\\c\\mterm://\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), {'cwd': expand(get(matchlist(expand(\"<amatch>\"), '\\c\\mterm://\\(.\\{-}\\)//'), 1, ''))})",
|
||||
command = "if !exists('b:term_title')|call jobstart(matchstr(expand(\"<amatch>\"), '\\c\\mterm://\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), {'term': v:true, 'cwd': expand(get(matchlist(expand(\"<amatch>\"), '\\c\\mterm://\\(.\\{-}\\)//'), 1, ''))})",
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd({ 'TermClose' }, {
|
||||
@ -492,6 +492,10 @@ do
|
||||
vim.bo.textwidth = 0
|
||||
vim.wo[0][0].wrap = false
|
||||
vim.wo[0][0].list = false
|
||||
vim.wo[0][0].number = false
|
||||
vim.wo[0][0].relativenumber = false
|
||||
vim.wo[0][0].signcolumn = 'no'
|
||||
vim.wo[0][0].foldcolumn = '0'
|
||||
|
||||
-- This is gross. Proper list options support when?
|
||||
local winhl = vim.o.winhighlight
|
||||
@ -546,8 +550,9 @@ do
|
||||
---
|
||||
--- @param option string Option name
|
||||
--- @param value any Option value
|
||||
local function setoption(option, value)
|
||||
if vim.api.nvim_get_option_info2(option, {}).was_set then
|
||||
--- @param force boolean? Always set the value, even if already set
|
||||
local function setoption(option, value, force)
|
||||
if not force and vim.api.nvim_get_option_info2(option, {}).was_set then
|
||||
-- Don't do anything if option is already set
|
||||
return
|
||||
end
|
||||
@ -563,7 +568,7 @@ do
|
||||
once = true,
|
||||
nested = true,
|
||||
callback = function()
|
||||
setoption(option, value)
|
||||
setoption(option, value, force)
|
||||
end,
|
||||
})
|
||||
end
|
||||
@ -645,11 +650,15 @@ do
|
||||
return nil, nil, nil
|
||||
end
|
||||
|
||||
local timer = assert(vim.uv.new_timer())
|
||||
|
||||
-- This autocommand updates the value of 'background' anytime we receive
|
||||
-- an OSC 11 response from the terminal emulator. If the user has set
|
||||
-- 'background' explictly then we will delete this autocommand,
|
||||
-- effectively disabling automatic background setting.
|
||||
local force = false
|
||||
local id = vim.api.nvim_create_autocmd('TermResponse', {
|
||||
group = group,
|
||||
nested = true,
|
||||
desc = "Update the value of 'background' automatically based on the terminal emulator's background color",
|
||||
callback = function(args)
|
||||
local resp = args.data ---@type string
|
||||
local r, g, b = parseosc11(resp)
|
||||
@ -661,27 +670,33 @@ do
|
||||
if rr and gg and bb then
|
||||
local luminance = (0.299 * rr) + (0.587 * gg) + (0.114 * bb)
|
||||
local bg = luminance < 0.5 and 'dark' or 'light'
|
||||
setoption('background', bg)
|
||||
end
|
||||
setoption('background', bg, force)
|
||||
|
||||
return true
|
||||
-- On the first query response, don't force setting the option in
|
||||
-- case the user has already set it manually. If they have, then
|
||||
-- this autocommand will be deleted. If they haven't, then we do
|
||||
-- want to force setting the option to override the value set by
|
||||
-- this autocommand.
|
||||
if not force then
|
||||
force = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd('VimEnter', {
|
||||
group = group,
|
||||
nested = true,
|
||||
once = true,
|
||||
callback = function()
|
||||
if vim.api.nvim_get_option_info2('background', {}).was_set then
|
||||
vim.api.nvim_del_autocmd(id)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
io.stdout:write('\027]11;?\007')
|
||||
|
||||
timer:start(1000, 0, function()
|
||||
-- Delete the autocommand if no response was received
|
||||
vim.schedule(function()
|
||||
-- Suppress error if autocommand has already been deleted
|
||||
pcall(vim.api.nvim_del_autocmd, id)
|
||||
end)
|
||||
|
||||
if not timer:is_closing() then
|
||||
timer:close()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- If the TUI (term_has_truecolor) was able to determine that the host
|
||||
|
@ -53,7 +53,7 @@ function vim.inspect_pos(bufnr, row, col, filter)
|
||||
local cursor = vim.api.nvim_win_get_cursor(win)
|
||||
row, col = cursor[1] - 1, cursor[2]
|
||||
end
|
||||
bufnr = bufnr == 0 and vim.api.nvim_get_current_buf() or bufnr
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
local results = {
|
||||
treesitter = {}, --- @type table[]
|
||||
@ -146,6 +146,13 @@ end
|
||||
---
|
||||
---Can also be shown with `:Inspect`. [:Inspect]()
|
||||
---
|
||||
---Example: To bind this function to the vim-scriptease
|
||||
---inspired `zS` in Normal mode:
|
||||
---
|
||||
---```lua
|
||||
---vim.keymap.set('n', 'zS', vim.show_pos)
|
||||
---```
|
||||
---
|
||||
---@since 11
|
||||
---@param bufnr? integer defaults to the current buffer
|
||||
---@param row? integer row to inspect, 0-based. Defaults to the row of the current cursor
|
||||
@ -171,7 +178,7 @@ function vim.show_pos(bufnr, row, col, filter)
|
||||
if data.hl_group ~= data.hl_group_link then
|
||||
append('links to ', 'MoreMsg')
|
||||
append(data.hl_group_link, data.hl_group_link)
|
||||
append(' ')
|
||||
append(' ')
|
||||
end
|
||||
if comment then
|
||||
append(comment, 'Comment')
|
||||
@ -184,7 +191,14 @@ function vim.show_pos(bufnr, row, col, filter)
|
||||
append('Treesitter', 'Title')
|
||||
nl()
|
||||
for _, capture in ipairs(items.treesitter) do
|
||||
item(capture, capture.lang)
|
||||
item(
|
||||
capture,
|
||||
string.format(
|
||||
'priority: %d language: %s',
|
||||
capture.metadata.priority or vim.hl.priorities.treesitter,
|
||||
capture.lang
|
||||
)
|
||||
)
|
||||
end
|
||||
nl()
|
||||
end
|
||||
|
32
runtime/lua/vim/_meta/api.lua
generated
32
runtime/lua/vim/_meta/api.lua
generated
@ -272,12 +272,12 @@ function vim.api.nvim_buf_attach(buffer, send_buffer, opts) end
|
||||
--- This temporarily switches current buffer to "buffer".
|
||||
--- If the current window already shows "buffer", the window is not switched.
|
||||
--- If a window inside the current tabpage (including a float) already shows the
|
||||
--- buffer, then one of these windows will be set as current window temporarily.
|
||||
--- buffer, then one of those windows will be set as current window temporarily.
|
||||
--- Otherwise a temporary scratch window (called the "autocmd window" for
|
||||
--- historical reasons) will be used.
|
||||
---
|
||||
--- This is useful e.g. to call Vimscript functions that only work with the
|
||||
--- current buffer/window currently, like `termopen()`.
|
||||
--- current buffer/window currently, like `jobstart(…, {'term': v:true})`.
|
||||
---
|
||||
--- @param buffer integer Buffer handle, or 0 for current buffer
|
||||
--- @param fun function Function to call inside the buffer (currently Lua callable
|
||||
@ -885,10 +885,8 @@ function vim.api.nvim_cmd(cmd, opts) end
|
||||
---
|
||||
--- On execution error: fails with Vimscript error, updates v:errmsg.
|
||||
---
|
||||
--- Prefer using `nvim_cmd()` or `nvim_exec2()` over this. To evaluate multiple lines of Vim script
|
||||
--- or an Ex command directly, use `nvim_exec2()`. To construct an Ex command using a structured
|
||||
--- format and then execute it, use `nvim_cmd()`. To modify an Ex command before evaluating it, use
|
||||
--- `nvim_parse_cmd()` in conjunction with `nvim_cmd()`.
|
||||
--- Prefer `nvim_cmd()` or `nvim_exec2()` instead. To modify an Ex command in a structured way
|
||||
--- before executing it, modify the result of `nvim_parse_cmd()` then pass it to `nvim_cmd()`.
|
||||
---
|
||||
--- @param command string Ex command string
|
||||
function vim.api.nvim_command(command) end
|
||||
@ -963,9 +961,9 @@ function vim.api.nvim_create_augroup(name, opts) end
|
||||
--- - id: (number) autocommand id
|
||||
--- - event: (string) name of the triggered event `autocmd-events`
|
||||
--- - group: (number|nil) autocommand group id, if any
|
||||
--- - match: (string) expanded value of [<amatch>]
|
||||
--- - buf: (number) expanded value of [<abuf>]
|
||||
--- - file: (string) expanded value of [<afile>]
|
||||
--- - file: (string) [<afile>] (not expanded to a full path)
|
||||
--- - match: (string) [<amatch>] (expanded to a full path)
|
||||
--- - buf: (number) [<abuf>]
|
||||
--- - data: (any) arbitrary data passed from [nvim_exec_autocmds()] [event-data]()
|
||||
--- - command (string) optional: Vim command to execute on event. Cannot be used with
|
||||
--- {callback}
|
||||
@ -1012,7 +1010,7 @@ function vim.api.nvim_create_namespace(name) end
|
||||
--- ```
|
||||
---
|
||||
--- @param name string Name of the new user command. Must begin with an uppercase letter.
|
||||
--- @param command any Replacement command to execute when this user command is executed. When called
|
||||
--- @param command string|fun(args: vim.api.keyset.create_user_command.command_args) Replacement command to execute when this user command is executed. When called
|
||||
--- from Lua, the command can also be a Lua function. The function is called with a
|
||||
--- single table argument that contains the following keys:
|
||||
--- - name: (string) Command name
|
||||
@ -1654,7 +1652,7 @@ function vim.api.nvim_notify(msg, log_level, opts) end
|
||||
--- Open a terminal instance in a buffer
|
||||
---
|
||||
--- By default (and currently the only option) the terminal will not be
|
||||
--- connected to an external process. Instead, input send on the channel
|
||||
--- connected to an external process. Instead, input sent on the channel
|
||||
--- will be echoed directly by the terminal. This is useful to display
|
||||
--- ANSI terminal sequences returned as part of a rpc message, or similar.
|
||||
---
|
||||
@ -1665,6 +1663,18 @@ function vim.api.nvim_notify(msg, log_level, opts) end
|
||||
--- Then `nvim_chan_send()` can be called immediately to process sequences
|
||||
--- in a virtual terminal having the intended size.
|
||||
---
|
||||
--- Example: this `TermHl` command can be used to display and highlight raw ANSI termcodes, so you
|
||||
--- can use Nvim as a "scrollback pager" (for terminals like kitty): [terminal-scrollback-pager]()
|
||||
---
|
||||
--- ```lua
|
||||
--- vim.api.nvim_create_user_command('TermHl', function()
|
||||
--- local b = vim.api.nvim_create_buf(false, true)
|
||||
--- local chan = vim.api.nvim_open_term(b, {})
|
||||
--- vim.api.nvim_chan_send(chan, table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), '\n'))
|
||||
--- vim.api.nvim_win_set_buf(0, b)
|
||||
--- end, { desc = 'Highlights ANSI termcodes in curbuf' })
|
||||
--- ```
|
||||
---
|
||||
--- @param buffer integer the buffer to use (expected to be empty)
|
||||
--- @param opts vim.api.keyset.open_term Optional parameters.
|
||||
--- - on_input: Lua callback for input sent, i e keypresses in terminal
|
||||
|
100
runtime/lua/vim/_meta/api_keysets.lua
generated
100
runtime/lua/vim/_meta/api_keysets.lua
generated
@ -4,11 +4,11 @@
|
||||
error('Cannot require a meta file')
|
||||
|
||||
--- @class vim.api.keyset.buf_attach
|
||||
--- @field on_lines? function
|
||||
--- @field on_bytes? function
|
||||
--- @field on_changedtick? function
|
||||
--- @field on_detach? function
|
||||
--- @field on_reload? function
|
||||
--- @field on_lines? fun(_: "lines", bufnr: integer, changedtick: integer, first: integer, last_old: integer, last_new: integer, byte_count: integer, deleted_codepoints?: integer, deleted_codeunits?: integer): boolean?
|
||||
--- @field on_bytes? fun(_: "bytes", bufnr: integer, changedtick: integer, start_row: integer, start_col: integer, start_byte: integer, old_end_row: integer, old_end_col: integer, old_end_byte: integer, new_end_row: integer, new_end_col: integer, new_end_byte: integer): boolean?
|
||||
--- @field on_changedtick? fun(_: "changedtick", bufnr: integer, changedtick: integer)
|
||||
--- @field on_detach? fun(_: "detach", bufnr: integer)
|
||||
--- @field on_reload? fun(_: "reload", bufnr: integer)
|
||||
--- @field utf_sizes? boolean
|
||||
--- @field preview? boolean
|
||||
|
||||
@ -18,9 +18,9 @@ error('Cannot require a meta file')
|
||||
|
||||
--- @class vim.api.keyset.clear_autocmds
|
||||
--- @field buffer? integer
|
||||
--- @field event? any
|
||||
--- @field group? any
|
||||
--- @field pattern? any
|
||||
--- @field event? string|string[]
|
||||
--- @field group? integer|string
|
||||
--- @field pattern? string|string[]
|
||||
|
||||
--- @class vim.api.keyset.cmd
|
||||
--- @field cmd? string
|
||||
@ -28,12 +28,12 @@ error('Cannot require a meta file')
|
||||
--- @field count? integer
|
||||
--- @field reg? string
|
||||
--- @field bang? boolean
|
||||
--- @field args? any[]
|
||||
--- @field args? string[]
|
||||
--- @field magic? table<string,any>
|
||||
--- @field mods? table<string,any>
|
||||
--- @field nargs? any
|
||||
--- @field addr? any
|
||||
--- @field nextcmd? any
|
||||
--- @field nargs? integer|string
|
||||
--- @field addr? string
|
||||
--- @field nextcmd? string
|
||||
|
||||
--- @class vim.api.keyset.cmd_magic
|
||||
--- @field file? boolean
|
||||
@ -72,20 +72,20 @@ error('Cannot require a meta file')
|
||||
--- @field info? string
|
||||
|
||||
--- @class vim.api.keyset.context
|
||||
--- @field types? any[]
|
||||
--- @field types? string[]
|
||||
|
||||
--- @class vim.api.keyset.create_augroup
|
||||
--- @field clear? any
|
||||
--- @field clear? boolean
|
||||
|
||||
--- @class vim.api.keyset.create_autocmd
|
||||
--- @field buffer? integer
|
||||
--- @field callback? any
|
||||
--- @field callback? string|(fun(args: vim.api.keyset.create_autocmd.callback_args): boolean?)
|
||||
--- @field command? string
|
||||
--- @field desc? string
|
||||
--- @field group? any
|
||||
--- @field group? integer|string
|
||||
--- @field nested? boolean
|
||||
--- @field once? boolean
|
||||
--- @field pattern? any
|
||||
--- @field pattern? string|string[]
|
||||
|
||||
--- @class vim.api.keyset.echo_opts
|
||||
--- @field verbose? boolean
|
||||
@ -103,19 +103,19 @@ error('Cannot require a meta file')
|
||||
|
||||
--- @class vim.api.keyset.exec_autocmds
|
||||
--- @field buffer? integer
|
||||
--- @field group? any
|
||||
--- @field group? integer|string
|
||||
--- @field modeline? boolean
|
||||
--- @field pattern? any
|
||||
--- @field pattern? string|string[]
|
||||
--- @field data? any
|
||||
|
||||
--- @class vim.api.keyset.exec_opts
|
||||
--- @field output? boolean
|
||||
|
||||
--- @class vim.api.keyset.get_autocmds
|
||||
--- @field event? any
|
||||
--- @field group? any
|
||||
--- @field pattern? any
|
||||
--- @field buffer? any
|
||||
--- @field event? string|string[]
|
||||
--- @field group? integer|string
|
||||
--- @field pattern? string|string[]
|
||||
--- @field buffer? integer|integer[]
|
||||
|
||||
--- @class vim.api.keyset.get_commands
|
||||
--- @field builtin? boolean
|
||||
@ -154,17 +154,17 @@ error('Cannot require a meta file')
|
||||
--- @field altfont? boolean
|
||||
--- @field nocombine? boolean
|
||||
--- @field default? boolean
|
||||
--- @field cterm? any
|
||||
--- @field foreground? any
|
||||
--- @field fg? any
|
||||
--- @field background? any
|
||||
--- @field bg? any
|
||||
--- @field ctermfg? any
|
||||
--- @field ctermbg? any
|
||||
--- @field special? any
|
||||
--- @field sp? any
|
||||
--- @field link? any
|
||||
--- @field global_link? any
|
||||
--- @field cterm? integer|string
|
||||
--- @field foreground? integer|string
|
||||
--- @field fg? integer|string
|
||||
--- @field background? integer|string
|
||||
--- @field bg? integer|string
|
||||
--- @field ctermfg? integer|string
|
||||
--- @field ctermbg? integer|string
|
||||
--- @field special? integer|string
|
||||
--- @field sp? integer|string
|
||||
--- @field link? integer|string
|
||||
--- @field global_link? integer|string
|
||||
--- @field fallback? boolean
|
||||
--- @field blend? integer
|
||||
--- @field fg_indexed? boolean
|
||||
@ -201,7 +201,7 @@ error('Cannot require a meta file')
|
||||
--- @field wins? any[]
|
||||
|
||||
--- @class vim.api.keyset.open_term
|
||||
--- @field on_input? function
|
||||
--- @field on_input? fun(_: "input", term: integer, bufnr: integer, data: any)
|
||||
--- @field force_crlf? boolean
|
||||
|
||||
--- @class vim.api.keyset.option
|
||||
@ -227,20 +227,20 @@ error('Cannot require a meta file')
|
||||
--- @field do_source? boolean
|
||||
|
||||
--- @class vim.api.keyset.set_decoration_provider
|
||||
--- @field on_start? function
|
||||
--- @field on_buf? function
|
||||
--- @field on_win? function
|
||||
--- @field on_line? function
|
||||
--- @field on_end? function
|
||||
--- @field _on_hl_def? function
|
||||
--- @field _on_spell_nav? function
|
||||
--- @field on_start? fun(_: "start", tick: integer)
|
||||
--- @field on_buf? fun(_: "buf", bufnr: integer, tick: integer)
|
||||
--- @field on_win? fun(_: "win", winid: integer, bufnr: integer, toprow: integer, botrow: integer)
|
||||
--- @field on_line? fun(_: "line", winid: integer, bufnr: integer, row: integer)
|
||||
--- @field on_end? fun(_: "end", tick: integer)
|
||||
--- @field _on_hl_def? fun(_: "hl_def")
|
||||
--- @field _on_spell_nav? fun(_: "spell_nav")
|
||||
|
||||
--- @class vim.api.keyset.set_extmark
|
||||
--- @field id? integer
|
||||
--- @field end_line? integer
|
||||
--- @field end_row? integer
|
||||
--- @field end_col? integer
|
||||
--- @field hl_group? number|string
|
||||
--- @field hl_group? integer|string
|
||||
--- @field virt_text? any[]
|
||||
--- @field virt_text_pos? string
|
||||
--- @field virt_text_win_col? integer
|
||||
@ -258,10 +258,10 @@ error('Cannot require a meta file')
|
||||
--- @field virt_lines_leftcol? boolean
|
||||
--- @field strict? boolean
|
||||
--- @field sign_text? string
|
||||
--- @field sign_hl_group? number|string
|
||||
--- @field number_hl_group? number|string
|
||||
--- @field line_hl_group? number|string
|
||||
--- @field cursorline_hl_group? number|string
|
||||
--- @field sign_hl_group? integer|string
|
||||
--- @field number_hl_group? integer|string
|
||||
--- @field line_hl_group? integer|string
|
||||
--- @field cursorline_hl_group? integer|string
|
||||
--- @field conceal? string
|
||||
--- @field spell? boolean
|
||||
--- @field ui_watched? boolean
|
||||
@ -292,7 +292,7 @@ error('Cannot require a meta file')
|
||||
--- @field relative? string
|
||||
--- @field split? string
|
||||
--- @field win? integer
|
||||
--- @field bufpos? any[]
|
||||
--- @field bufpos? integer[]
|
||||
--- @field external? boolean
|
||||
--- @field focusable? boolean
|
||||
--- @field mouse? boolean
|
||||
@ -315,12 +315,12 @@ error('Cannot require a meta file')
|
||||
--- @field end_vcol? integer
|
||||
|
||||
--- @class vim.api.keyset.xdl_diff
|
||||
--- @field on_hunk? function
|
||||
--- @field on_hunk? fun(start_a: integer, count_a: integer, start_b: integer, count_b: integer): integer?
|
||||
--- @field result_type? string
|
||||
--- @field algorithm? string
|
||||
--- @field ctxlen? integer
|
||||
--- @field interhunkctxlen? integer
|
||||
--- @field linematch? any
|
||||
--- @field linematch? boolean|integer
|
||||
--- @field ignore_whitespace? boolean
|
||||
--- @field ignore_whitespace_change? boolean
|
||||
--- @field ignore_whitespace_change_at_eol? boolean
|
||||
|
@ -73,6 +73,51 @@ error('Cannot require a meta file')
|
||||
--- @field buflocal? boolean
|
||||
--- @field buffer? integer
|
||||
|
||||
--- @class vim.api.keyset.create_autocmd.callback_args
|
||||
--- @field id integer autocommand id
|
||||
--- @field event string name of the triggered event |autocmd-events|
|
||||
--- @field group? integer autocommand group id, if any
|
||||
--- @field match string expanded value of <amatch>
|
||||
--- @field buf integer expanded value of <abuf>
|
||||
--- @field file string expanded value of <afile>
|
||||
--- @field data? any arbitrary data passed from |nvim_exec_autocmds()| *event-data*
|
||||
|
||||
--- @class vim.api.keyset.create_user_command.command_args
|
||||
--- @field name string Command name
|
||||
---
|
||||
--- The args passed to the command, if any <args>
|
||||
--- @field args string
|
||||
---
|
||||
--- The args split by unescaped whitespace
|
||||
--- (when more than one argument is allowed), if any <f-args>
|
||||
--- @field fargs string[]
|
||||
---
|
||||
--- Number of arguments |:command-nargs|
|
||||
--- @field nargs string
|
||||
---
|
||||
--- "true" if the command was executed with a ! modifier <bang>
|
||||
--- @field bang boolean
|
||||
---
|
||||
--- The starting line of the command range <line1>
|
||||
--- @field line1 integer
|
||||
---
|
||||
--- The final line of the command range <line2>
|
||||
--- @field line2 integer
|
||||
---
|
||||
--- The number of items in the command range: 0, 1, or 2 <range>
|
||||
--- @field range integer
|
||||
---
|
||||
--- Any count supplied <count>
|
||||
--- @field count integer
|
||||
--- The optional register, if specified <reg>
|
||||
--- @field reg string
|
||||
--- Command modifiers, if any <mods>
|
||||
--- @field mods string
|
||||
---
|
||||
--- Command modifiers in a structured format. Has the same structure as the
|
||||
--- "mods" key of |nvim_parse_cmd()|.
|
||||
--- @field smods table
|
||||
|
||||
--- @class vim.api.keyset.command_info
|
||||
--- @field name string
|
||||
--- @field definition string
|
||||
@ -114,6 +159,7 @@ error('Cannot require a meta file')
|
||||
--- @field bg? integer
|
||||
--- @field sp? integer
|
||||
--- @field default? true
|
||||
--- @field link? string
|
||||
--- @field blend? integer
|
||||
--- @field cterm? vim.api.keyset.hl_info.cterm
|
||||
|
||||
|
@ -35,5 +35,8 @@ function vim.json.decode(str, opts) end
|
||||
|
||||
--- Encodes (or "packs") Lua object {obj} as JSON in a Lua string.
|
||||
---@param obj any
|
||||
---@param opts? table<string,any> Options table with keys:
|
||||
--- - escape_slash: (boolean) (default false) When true, escapes `/`
|
||||
--- character in JSON strings
|
||||
---@return string
|
||||
function vim.json.encode(obj) end
|
||||
function vim.json.encode(obj, opts) end
|
||||
|
53
runtime/lua/vim/_meta/options.lua
generated
53
runtime/lua/vim/_meta/options.lua
generated
@ -1086,9 +1086,9 @@ vim.go.cia = vim.go.completeitemalign
|
||||
--- a match from the menu. Only works in combination with
|
||||
--- "menu" or "menuone". No effect if "longest" is present.
|
||||
---
|
||||
--- noselect Do not select a match in the menu, force the user to
|
||||
--- select one from the menu. Only works in combination with
|
||||
--- "menu" or "menuone".
|
||||
--- noselect Same as "noinsert", except that no menu item is
|
||||
--- pre-selected. If both "noinsert" and "noselect" are present,
|
||||
--- "noselect" has precedence.
|
||||
---
|
||||
--- fuzzy Enable `fuzzy-matching` for completion candidates. This
|
||||
--- allows for more flexible and intuitive matching, where
|
||||
@ -2783,6 +2783,7 @@ vim.go.gp = vim.go.grepprg
|
||||
--- ci Command-line Insert mode
|
||||
--- cr Command-line Replace mode
|
||||
--- sm showmatch in Insert mode
|
||||
--- t Terminal mode
|
||||
--- a all modes
|
||||
--- The argument-list is a dash separated list of these arguments:
|
||||
--- hor{N} horizontal bar, {N} percent of the character height
|
||||
@ -2802,7 +2803,8 @@ vim.go.gp = vim.go.grepprg
|
||||
--- ```vim
|
||||
--- set guicursor=n:blinkon0
|
||||
--- ```
|
||||
--- - Default is "blinkon0" for each mode.
|
||||
---
|
||||
--- Default is "blinkon0" for each mode.
|
||||
--- {group-name}
|
||||
--- Highlight group that decides the color and font of the
|
||||
--- cursor.
|
||||
@ -2848,7 +2850,7 @@ vim.go.gp = vim.go.grepprg
|
||||
---
|
||||
---
|
||||
--- @type string
|
||||
vim.o.guicursor = "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20"
|
||||
vim.o.guicursor = "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20,t:block-blinkon500-blinkoff500-TermCursor"
|
||||
vim.o.gcr = vim.o.guicursor
|
||||
vim.go.guicursor = vim.o.guicursor
|
||||
vim.go.gcr = vim.go.guicursor
|
||||
@ -3016,7 +3018,7 @@ vim.go.hid = vim.go.hidden
|
||||
|
||||
--- A history of ":" commands, and a history of previous search patterns
|
||||
--- is remembered. This option decides how many entries may be stored in
|
||||
--- each of these histories (see `cmdline-editing` and 'msghistory' for
|
||||
--- each of these histories (see `cmdline-editing` and 'messagesopt' for
|
||||
--- the number of messages to remember).
|
||||
--- The maximum value is 10000.
|
||||
---
|
||||
@ -4084,6 +4086,31 @@ vim.o.mis = vim.o.menuitems
|
||||
vim.go.menuitems = vim.o.menuitems
|
||||
vim.go.mis = vim.go.menuitems
|
||||
|
||||
--- Option settings for outputting messages. It can consist of the
|
||||
--- following items. Items must be separated by a comma.
|
||||
---
|
||||
--- hit-enter Use a `hit-enter` prompt when the message is longer than
|
||||
--- 'cmdheight' size.
|
||||
---
|
||||
--- wait:{n} Instead of using a `hit-enter` prompt, simply wait for
|
||||
--- {n} milliseconds so that the user has a chance to read
|
||||
--- the message. The maximum value of {n} is 10000. Use
|
||||
--- 0 to disable the wait (but then the user may miss an
|
||||
--- important message).
|
||||
--- This item is ignored when "hit-enter" is present, but
|
||||
--- required when "hit-enter" is not present.
|
||||
---
|
||||
--- history:{n} Determines how many entries are remembered in the
|
||||
--- `:messages` history. The maximum value is 10000.
|
||||
--- Setting it to zero clears the message history.
|
||||
--- This item must always be present.
|
||||
---
|
||||
--- @type string
|
||||
vim.o.messagesopt = "hit-enter,history:500"
|
||||
vim.o.mopt = vim.o.messagesopt
|
||||
vim.go.messagesopt = vim.o.messagesopt
|
||||
vim.go.mopt = vim.go.messagesopt
|
||||
|
||||
--- Parameters for `:mkspell`. This tunes when to start compressing the
|
||||
--- word tree. Compression can be slow when there are many words, but
|
||||
--- it's needed to avoid running out of memory. The amount of memory used
|
||||
@ -4379,16 +4406,6 @@ vim.o.mouset = vim.o.mousetime
|
||||
vim.go.mousetime = vim.o.mousetime
|
||||
vim.go.mouset = vim.go.mousetime
|
||||
|
||||
--- Determines how many entries are remembered in the `:messages` history.
|
||||
--- The maximum value is 10000.
|
||||
--- Setting it to zero clears the message history.
|
||||
---
|
||||
--- @type integer
|
||||
vim.o.msghistory = 500
|
||||
vim.o.mhi = vim.o.msghistory
|
||||
vim.go.msghistory = vim.o.msghistory
|
||||
vim.go.mhi = vim.go.msghistory
|
||||
|
||||
--- This defines what bases Vim will consider for numbers when using the
|
||||
--- CTRL-A and CTRL-X commands for adding to and subtracting from a number
|
||||
--- respectively; see `CTRL-A` for more info on these commands.
|
||||
@ -4995,6 +5012,7 @@ vim.go.ruf = vim.go.rulerformat
|
||||
--- indent/ indent scripts `indent-expression`
|
||||
--- keymap/ key mapping files `mbyte-keymap`
|
||||
--- lang/ menu translations `:menutrans`
|
||||
--- lsp/ LSP client configurations `lsp-config`
|
||||
--- lua/ `Lua` plugins
|
||||
--- menu.vim GUI menus `menu.vim`
|
||||
--- pack/ packages `:packadd`
|
||||
@ -5198,6 +5216,8 @@ vim.go.sect = vim.go.sections
|
||||
--- selection.
|
||||
--- When "old" is used and 'virtualedit' allows the cursor to move past
|
||||
--- the end of line the line break still isn't included.
|
||||
--- When "exclusive" is used, cursor position in visual mode will be
|
||||
--- adjusted for inclusive motions `inclusive-motion-selection-exclusive`.
|
||||
--- Note that when "exclusive" is used and selecting from the end
|
||||
--- backwards, you cannot include the last character of a line, when
|
||||
--- starting in Normal mode and 'virtualedit' empty.
|
||||
@ -6311,6 +6331,7 @@ vim.wo.stc = vim.wo.statuscolumn
|
||||
--- All fields except the {item} are optional. A single percent sign can
|
||||
--- be given as "%%".
|
||||
---
|
||||
--- *stl-%!*
|
||||
--- When the option starts with "%!" then it is used as an expression,
|
||||
--- evaluated and the result is used as the option value. Example:
|
||||
---
|
||||
|
219
runtime/lua/vim/_meta/vimfn.lua
generated
219
runtime/lua/vim/_meta/vimfn.lua
generated
@ -1147,8 +1147,9 @@ function vim.fn.confirm(msg, choices, default, type) end
|
||||
--- A |Dictionary| is copied in a similar way as a |List|.
|
||||
--- Also see |deepcopy()|.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @return any
|
||||
--- @generic T
|
||||
--- @param expr T
|
||||
--- @return T
|
||||
function vim.fn.copy(expr) end
|
||||
|
||||
--- Return the cosine of {expr}, measured in radians, as a |Float|.
|
||||
@ -1228,7 +1229,7 @@ function vim.fn.ctxpush(types) end
|
||||
---
|
||||
--- @param context table
|
||||
--- @param index? integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.ctxset(context, index) end
|
||||
|
||||
--- Returns the size of the |context-stack|.
|
||||
@ -1308,9 +1309,10 @@ function vim.fn.debugbreak(pid) end
|
||||
--- {noref} set to 1 will fail.
|
||||
--- Also see |copy()|.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @generic T
|
||||
--- @param expr T
|
||||
--- @param noref? boolean
|
||||
--- @return any
|
||||
--- @return T
|
||||
function vim.fn.deepcopy(expr, noref) end
|
||||
|
||||
--- Without {flags} or with {flags} empty: Deletes the file by the
|
||||
@ -1421,7 +1423,7 @@ function vim.fn.dictwatcherdel(dict, pattern, callback) end
|
||||
--- editing another buffer to set 'filetype' and load a syntax
|
||||
--- file.
|
||||
---
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.did_filetype() end
|
||||
|
||||
--- Returns the number of filler lines above line {lnum}.
|
||||
@ -1433,7 +1435,7 @@ function vim.fn.did_filetype() end
|
||||
--- Returns 0 if the current window is not in diff mode.
|
||||
---
|
||||
--- @param lnum integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.diff_filler(lnum) end
|
||||
|
||||
--- Returns the highlight ID for diff mode at line {lnum} column
|
||||
@ -1468,7 +1470,7 @@ function vim.fn.diff_hlID(lnum, col) end
|
||||
--- <
|
||||
---
|
||||
--- @param chars string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.digraph_get(chars) end
|
||||
|
||||
--- Return a list of digraphs. If the {listall} argument is given
|
||||
@ -1486,7 +1488,7 @@ function vim.fn.digraph_get(chars) end
|
||||
--- <
|
||||
---
|
||||
--- @param listall? boolean
|
||||
--- @return any
|
||||
--- @return string[][]
|
||||
function vim.fn.digraph_getlist(listall) end
|
||||
|
||||
--- Add digraph {chars} to the list. {chars} must be a string
|
||||
@ -1538,7 +1540,7 @@ function vim.fn.digraph_setlist(digraphlist) end
|
||||
--- - A |Blob| is empty when its length is zero.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.empty(expr) end
|
||||
|
||||
--- Return all of environment variables as dictionary. You can
|
||||
@ -1561,7 +1563,7 @@ function vim.fn.environ() end
|
||||
---
|
||||
--- @param string string
|
||||
--- @param chars string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.escape(string, chars) end
|
||||
|
||||
--- Evaluate {string} and return the result. Especially useful to
|
||||
@ -2368,7 +2370,7 @@ function vim.fn.foldtextresult(lnum) end
|
||||
---
|
||||
--- @param expr1 string|table
|
||||
--- @param expr2 string|function
|
||||
--- @return any
|
||||
--- @return string|table
|
||||
function vim.fn.foreach(expr1, expr2) end
|
||||
|
||||
--- Get the full command name from a short abbreviated command
|
||||
@ -2675,7 +2677,7 @@ function vim.fn.getbufinfo(dict) end
|
||||
--- @param buf integer|string
|
||||
--- @param lnum integer
|
||||
--- @param end_? integer
|
||||
--- @return any
|
||||
--- @return string[]
|
||||
function vim.fn.getbufline(buf, lnum, end_) end
|
||||
|
||||
--- Just like `getbufline()` but only get one line and return it
|
||||
@ -2943,7 +2945,7 @@ function vim.fn.getcmdprompt() end
|
||||
--- Also see |getcmdpos()|, |setcmdpos()|, |getcmdline()| and
|
||||
--- |setcmdline()|.
|
||||
---
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.getcmdscreenpos() end
|
||||
|
||||
--- Return the current command-line type. Possible return values
|
||||
@ -3869,7 +3871,7 @@ function vim.fn.gettagstack(winnr) end
|
||||
--- strings.
|
||||
---
|
||||
--- @param text string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.gettext(text) end
|
||||
|
||||
--- Returns information about windows as a |List| with Dictionaries.
|
||||
@ -3885,6 +3887,8 @@ function vim.fn.gettext(text) end
|
||||
--- botline last complete displayed buffer line
|
||||
--- bufnr number of buffer in the window
|
||||
--- height window height (excluding winbar)
|
||||
--- leftcol first column displayed; only used when
|
||||
--- 'wrap' is off
|
||||
--- loclist 1 if showing a location list
|
||||
--- quickfix 1 if quickfix or location list window
|
||||
--- terminal 1 if a terminal window
|
||||
@ -4018,7 +4022,7 @@ function vim.fn.glob(expr, nosuf, list, alllinks) end
|
||||
--- a backslash usually means a path separator.
|
||||
---
|
||||
--- @param string string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.glob2regpat(string) end
|
||||
|
||||
--- Perform glob() for String {expr} on all directories in {path}
|
||||
@ -4352,7 +4356,7 @@ function vim.fn.hostname() end
|
||||
--- @param string string
|
||||
--- @param from string
|
||||
--- @param to string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.iconv(string, from, to) end
|
||||
|
||||
--- Returns a |String| which is a unique identifier of the
|
||||
@ -4372,7 +4376,7 @@ function vim.fn.iconv(string, from, to) end
|
||||
--- reuse identifiers of the garbage-collected ones.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.id(expr) end
|
||||
|
||||
--- The result is a Number, which is indent of line {lnum} in the
|
||||
@ -4416,7 +4420,7 @@ function vim.fn.indent(lnum) end
|
||||
--- @param expr any
|
||||
--- @param start? integer
|
||||
--- @param ic? boolean
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.index(object, expr, start, ic) end
|
||||
|
||||
--- Returns the index of an item in {object} where {expr} is
|
||||
@ -4460,14 +4464,14 @@ function vim.fn.index(object, expr, start, ic) end
|
||||
--- @param object any
|
||||
--- @param expr any
|
||||
--- @param opts? table
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.indexof(object, expr, opts) end
|
||||
|
||||
---
|
||||
--- @param prompt string
|
||||
--- @param text? string
|
||||
--- @param completion? string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.input(prompt, text, completion) end
|
||||
|
||||
--- The result is a String, which is whatever the user typed on
|
||||
@ -4581,7 +4585,7 @@ function vim.fn.input(prompt, text, completion) end
|
||||
--- <
|
||||
---
|
||||
--- @param opts table
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.input(opts) end
|
||||
|
||||
--- @deprecated
|
||||
@ -4616,7 +4620,7 @@ function vim.fn.inputlist(textlist) end
|
||||
--- called. Calling it more often is harmless though.
|
||||
--- Returns TRUE when there is nothing to restore, FALSE otherwise.
|
||||
---
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.inputrestore() end
|
||||
|
||||
--- Preserve typeahead (also from mappings) and clear it, so that
|
||||
@ -4626,7 +4630,7 @@ function vim.fn.inputrestore() end
|
||||
--- many inputrestore() calls.
|
||||
--- Returns TRUE when out of memory, FALSE otherwise.
|
||||
---
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.inputsave() end
|
||||
|
||||
--- This function acts much like the |input()| function with but
|
||||
@ -4641,7 +4645,7 @@ function vim.fn.inputsave() end
|
||||
---
|
||||
--- @param prompt string
|
||||
--- @param text? string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.inputsecret(prompt, text) end
|
||||
|
||||
--- When {object} is a |List| or a |Blob| insert {item} at the start
|
||||
@ -4687,8 +4691,8 @@ function vim.fn.interrupt() end
|
||||
--- let bits = invert(bits)
|
||||
--- <
|
||||
---
|
||||
--- @param expr number
|
||||
--- @return any
|
||||
--- @param expr integer
|
||||
--- @return integer
|
||||
function vim.fn.invert(expr) end
|
||||
|
||||
--- The result is a Number, which is |TRUE| when {path} is an
|
||||
@ -4767,7 +4771,7 @@ function vim.fn.isnan(expr) end
|
||||
--- cases, items() returns a List with the index and the value at
|
||||
--- the index.
|
||||
---
|
||||
--- @param dict any
|
||||
--- @param dict table
|
||||
--- @return any
|
||||
function vim.fn.items(dict) end
|
||||
|
||||
@ -4801,7 +4805,7 @@ function vim.fn.jobresize(job, width, height) end
|
||||
--- @return any
|
||||
function vim.fn.jobsend(...) end
|
||||
|
||||
--- Note: Prefer |vim.system()| in Lua (unless using the `pty` option).
|
||||
--- Note: Prefer |vim.system()| in Lua (unless using `rpc`, `pty`, or `term`).
|
||||
---
|
||||
--- Spawns {cmd} as a job.
|
||||
--- If {cmd} is a List it runs directly (no 'shell').
|
||||
@ -4875,6 +4879,10 @@ function vim.fn.jobsend(...) end
|
||||
--- stdin: (string) Either "pipe" (default) to connect the
|
||||
--- job's stdin to a channel or "null" to disconnect
|
||||
--- stdin.
|
||||
--- term: (boolean) Spawns {cmd} in a new pseudo-terminal session
|
||||
--- connected to the current (unmodified) buffer. Implies "pty".
|
||||
--- Default "height" and "width" are set to the current window
|
||||
--- dimensions. |jobstart()|. Defaults $TERM to "xterm-256color".
|
||||
--- width: (number) Width of the `pty` terminal.
|
||||
---
|
||||
--- {opts} is passed as |self| dictionary to the callback; the
|
||||
@ -4888,7 +4896,7 @@ function vim.fn.jobsend(...) end
|
||||
---
|
||||
--- @param cmd string|string[]
|
||||
--- @param opts? table
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.jobstart(cmd, opts) end
|
||||
|
||||
--- Stop |job-id| {id} by sending SIGTERM to the job process. If
|
||||
@ -4901,7 +4909,7 @@ function vim.fn.jobstart(cmd, opts) end
|
||||
--- exited or stopped.
|
||||
---
|
||||
--- @param id integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.jobstop(id) end
|
||||
|
||||
--- Waits for jobs and their |on_exit| handlers to complete.
|
||||
@ -4926,7 +4934,7 @@ function vim.fn.jobstop(id) end
|
||||
---
|
||||
--- @param jobs integer[]
|
||||
--- @param timeout? integer
|
||||
--- @return any
|
||||
--- @return integer[]
|
||||
function vim.fn.jobwait(jobs, timeout) end
|
||||
|
||||
--- Join the items in {list} together into one String.
|
||||
@ -4941,7 +4949,7 @@ function vim.fn.jobwait(jobs, timeout) end
|
||||
---
|
||||
--- @param list any[]
|
||||
--- @param sep? string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.join(list, sep) end
|
||||
|
||||
--- Convert {expr} from JSON object. Accepts |readfile()|-style
|
||||
@ -4974,14 +4982,14 @@ function vim.fn.json_decode(expr) end
|
||||
--- |Blob|s are converted to arrays of the individual bytes.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.json_encode(expr) end
|
||||
|
||||
--- Return a |List| with all the keys of {dict}. The |List| is in
|
||||
--- arbitrary order. Also see |items()| and |values()|.
|
||||
---
|
||||
--- @param dict table
|
||||
--- @return any
|
||||
--- @return string[]
|
||||
function vim.fn.keys(dict) end
|
||||
|
||||
--- Turn the internal byte representation of keys into a form that
|
||||
@ -4991,7 +4999,7 @@ function vim.fn.keys(dict) end
|
||||
--- < <C-Home>
|
||||
---
|
||||
--- @param string string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.keytrans(string) end
|
||||
|
||||
--- @deprecated
|
||||
@ -5010,8 +5018,8 @@ function vim.fn.last_buffer_nr() end
|
||||
--- |Dictionary| is returned.
|
||||
--- Otherwise an error is given and returns zero.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @return any
|
||||
--- @param expr any[]
|
||||
--- @return integer
|
||||
function vim.fn.len(expr) end
|
||||
|
||||
--- Call function {funcname} in the run-time library {libname}
|
||||
@ -5122,7 +5130,7 @@ function vim.fn.line2byte(lnum) end
|
||||
--- When {lnum} is invalid, -1 is returned.
|
||||
---
|
||||
--- @param lnum integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.lispindent(lnum) end
|
||||
|
||||
--- Return a Blob concatenating all the number values in {list}.
|
||||
@ -5135,7 +5143,7 @@ function vim.fn.lispindent(lnum) end
|
||||
--- |blob2list()| does the opposite.
|
||||
---
|
||||
--- @param list any[]
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.list2blob(list) end
|
||||
|
||||
--- Convert each number in {list} to a character string can
|
||||
@ -5155,13 +5163,13 @@ function vim.fn.list2blob(list) end
|
||||
---
|
||||
--- @param list any[]
|
||||
--- @param utf8? boolean
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.list2str(list, utf8) end
|
||||
|
||||
--- Return the current time, measured as seconds since 1st Jan
|
||||
--- 1970. See also |strftime()|, |strptime()| and |getftime()|.
|
||||
---
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.localtime() end
|
||||
|
||||
--- Return the natural logarithm (base e) of {expr} as a |Float|.
|
||||
@ -5175,7 +5183,7 @@ function vim.fn.localtime() end
|
||||
--- < 5.0
|
||||
---
|
||||
--- @param expr number
|
||||
--- @return any
|
||||
--- @return number
|
||||
function vim.fn.log(expr) end
|
||||
|
||||
--- Return the logarithm of Float {expr} to base 10 as a |Float|.
|
||||
@ -5188,7 +5196,7 @@ function vim.fn.log(expr) end
|
||||
--- < -2.0
|
||||
---
|
||||
--- @param expr number
|
||||
--- @return any
|
||||
--- @return number
|
||||
function vim.fn.log10(expr) end
|
||||
|
||||
--- {expr1} must be a |List|, |String|, |Blob| or |Dictionary|.
|
||||
@ -5950,7 +5958,7 @@ function vim.fn.matchstrpos(expr, pat, start, count) end
|
||||
--- an error. An empty |List| or |Dictionary| results in zero.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @return any
|
||||
--- @return number
|
||||
function vim.fn.max(expr) end
|
||||
|
||||
--- Returns a |List| of |Dictionaries| describing |menus| (defined
|
||||
@ -6088,7 +6096,7 @@ function vim.fn.menu_info(name, mode) end
|
||||
--- an error. An empty |List| or |Dictionary| results in zero.
|
||||
---
|
||||
--- @param expr any
|
||||
--- @return any
|
||||
--- @return number
|
||||
function vim.fn.min(expr) end
|
||||
|
||||
--- Create directory {name}.
|
||||
@ -6133,7 +6141,7 @@ function vim.fn.min(expr) end
|
||||
--- @param name string
|
||||
--- @param flags? string
|
||||
--- @param prot? string
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.mkdir(name, flags, prot) end
|
||||
|
||||
--- Return a string that indicates the current mode.
|
||||
@ -6296,7 +6304,7 @@ function vim.fn.msgpackparse(data) end
|
||||
--- See also |prevnonblank()|.
|
||||
---
|
||||
--- @param lnum integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.nextnonblank(lnum) end
|
||||
|
||||
--- Return a string with a single character, which has the number
|
||||
@ -6315,7 +6323,7 @@ function vim.fn.nextnonblank(lnum) end
|
||||
---
|
||||
--- @param expr integer
|
||||
--- @param utf8? boolean
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.nr2char(expr, utf8) end
|
||||
|
||||
--- Bitwise OR on the two arguments. The arguments are converted
|
||||
@ -6349,7 +6357,7 @@ vim.fn['or'] = function(expr, expr1) end
|
||||
---
|
||||
--- @param path string
|
||||
--- @param len? integer
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.pathshorten(path, len) end
|
||||
|
||||
--- Evaluate |perl| expression {expr} and return its result
|
||||
@ -6383,7 +6391,7 @@ function vim.fn.perleval(expr) end
|
||||
---
|
||||
--- @param x number
|
||||
--- @param y number
|
||||
--- @return any
|
||||
--- @return number
|
||||
function vim.fn.pow(x, y) end
|
||||
|
||||
--- Return the line number of the first line at or above {lnum}
|
||||
@ -6395,7 +6403,7 @@ function vim.fn.pow(x, y) end
|
||||
--- Also see |nextnonblank()|.
|
||||
---
|
||||
--- @param lnum integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.prevnonblank(lnum) end
|
||||
|
||||
--- Return a String with {fmt}, where "%" items are replaced by
|
||||
@ -7014,10 +7022,11 @@ function vim.fn.readfile(fname, type, max) end
|
||||
--- echo reduce('xyz', { acc, val -> acc .. ',' .. val })
|
||||
--- <
|
||||
---
|
||||
--- @generic T
|
||||
--- @param object any
|
||||
--- @param func function
|
||||
--- @param func fun(accumulator: T, current: any): any
|
||||
--- @param initial? any
|
||||
--- @return any
|
||||
--- @return T
|
||||
function vim.fn.reduce(object, func, initial) end
|
||||
|
||||
--- Returns the single letter name of the register being executed.
|
||||
@ -7170,7 +7179,7 @@ function vim.fn.remove(dict, key) end
|
||||
---
|
||||
--- @param from string
|
||||
--- @param to string
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.rename(from, to) end
|
||||
|
||||
--- Repeat {expr} {count} times and return the concatenated
|
||||
@ -7200,7 +7209,7 @@ vim.fn['repeat'] = function(expr, count) end
|
||||
--- path name) and also keeps a trailing path separator.
|
||||
---
|
||||
--- @param filename string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.resolve(filename) end
|
||||
|
||||
--- Reverse the order of items in {object}. {object} can be a
|
||||
@ -7213,8 +7222,9 @@ function vim.fn.resolve(filename) end
|
||||
--- let revlist = reverse(copy(mylist))
|
||||
--- <
|
||||
---
|
||||
--- @param object any
|
||||
--- @return any
|
||||
--- @generic T
|
||||
--- @param object T[]
|
||||
--- @return T[]
|
||||
function vim.fn.reverse(object) end
|
||||
|
||||
--- Round off {expr} to the nearest integral value and return it
|
||||
@ -7231,7 +7241,7 @@ function vim.fn.reverse(object) end
|
||||
--- < -5.0
|
||||
---
|
||||
--- @param expr number
|
||||
--- @return any
|
||||
--- @return number
|
||||
function vim.fn.round(expr) end
|
||||
|
||||
--- Sends {event} to {channel} via |RPC| and returns immediately.
|
||||
@ -7242,9 +7252,9 @@ function vim.fn.round(expr) end
|
||||
---
|
||||
--- @param channel integer
|
||||
--- @param event string
|
||||
--- @param args? any
|
||||
--- @return any
|
||||
function vim.fn.rpcnotify(channel, event, args) end
|
||||
--- @param ... any
|
||||
--- @return integer
|
||||
function vim.fn.rpcnotify(channel, event, ...) end
|
||||
|
||||
--- Sends a request to {channel} to invoke {method} via
|
||||
--- |RPC| and blocks until a response is received.
|
||||
@ -7254,9 +7264,9 @@ function vim.fn.rpcnotify(channel, event, args) end
|
||||
---
|
||||
--- @param channel integer
|
||||
--- @param method string
|
||||
--- @param args? any
|
||||
--- @param ... any
|
||||
--- @return any
|
||||
function vim.fn.rpcrequest(channel, method, args) end
|
||||
function vim.fn.rpcrequest(channel, method, ...) end
|
||||
|
||||
--- @deprecated
|
||||
--- Deprecated. Replace >vim
|
||||
@ -7300,7 +7310,7 @@ function vim.fn.rubyeval(expr) end
|
||||
---
|
||||
--- @param row integer
|
||||
--- @param col integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.screenattr(row, col) end
|
||||
|
||||
--- The result is a Number, which is the character at position
|
||||
@ -7314,7 +7324,7 @@ function vim.fn.screenattr(row, col) end
|
||||
---
|
||||
--- @param row integer
|
||||
--- @param col integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.screenchar(row, col) end
|
||||
|
||||
--- The result is a |List| of Numbers. The first number is the same
|
||||
@ -7325,7 +7335,7 @@ function vim.fn.screenchar(row, col) end
|
||||
---
|
||||
--- @param row integer
|
||||
--- @param col integer
|
||||
--- @return any
|
||||
--- @return integer[]
|
||||
function vim.fn.screenchars(row, col) end
|
||||
|
||||
--- The result is a Number, which is the current screen column of
|
||||
@ -7342,7 +7352,7 @@ function vim.fn.screenchars(row, col) end
|
||||
--- noremap GG <Cmd>echom screencol()<CR>
|
||||
--- <
|
||||
---
|
||||
--- @return any
|
||||
--- @return integer[]
|
||||
function vim.fn.screencol() end
|
||||
|
||||
--- The result is a Dict with the screen position of the text
|
||||
@ -7381,7 +7391,7 @@ function vim.fn.screenpos(winid, lnum, col) end
|
||||
---
|
||||
--- Note: Same restrictions as with |screencol()|.
|
||||
---
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.screenrow() end
|
||||
|
||||
--- The result is a String that contains the base character and
|
||||
@ -7393,7 +7403,7 @@ function vim.fn.screenrow() end
|
||||
---
|
||||
--- @param row integer
|
||||
--- @param col integer
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.screenstring(row, col) end
|
||||
|
||||
--- Search for regexp pattern {pattern}. The search starts at the
|
||||
@ -7798,7 +7808,7 @@ function vim.fn.searchpos(pattern, flags, stopline, timeout, skip) end
|
||||
--- echo serverlist()
|
||||
--- <
|
||||
---
|
||||
--- @return any
|
||||
--- @return string[]
|
||||
function vim.fn.serverlist() end
|
||||
|
||||
--- Opens a socket or named pipe at {address} and listens for
|
||||
@ -7835,7 +7845,7 @@ function vim.fn.serverlist() end
|
||||
--- <
|
||||
---
|
||||
--- @param address? string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.serverstart(address) end
|
||||
|
||||
--- Closes the pipe or socket at {address}.
|
||||
@ -7844,7 +7854,7 @@ function vim.fn.serverstart(address) end
|
||||
--- address in |serverlist()|.
|
||||
---
|
||||
--- @param address string
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.serverstop(address) end
|
||||
|
||||
--- Set line {lnum} to {text} in buffer {buf}. This works like
|
||||
@ -7874,7 +7884,7 @@ function vim.fn.serverstop(address) end
|
||||
--- @param buf integer|string
|
||||
--- @param lnum integer
|
||||
--- @param text string|string[]
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.setbufline(buf, lnum, text) end
|
||||
|
||||
--- Set option or local variable {varname} in buffer {buf} to
|
||||
@ -7979,7 +7989,7 @@ function vim.fn.setcharsearch(dict) end
|
||||
---
|
||||
--- @param str string
|
||||
--- @param pos? integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.setcmdline(str, pos) end
|
||||
|
||||
--- Set the cursor position in the command line to byte position
|
||||
@ -8289,7 +8299,7 @@ function vim.fn.setpos(expr, list) end
|
||||
--- @param list vim.quickfix.entry[]
|
||||
--- @param action? string
|
||||
--- @param what? vim.fn.setqflist.what
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.setqflist(list, action, what) end
|
||||
|
||||
--- Set the register {regname} to {value}.
|
||||
@ -8442,7 +8452,7 @@ function vim.fn.setwinvar(nr, varname, val) end
|
||||
--- checksum of {string}.
|
||||
---
|
||||
--- @param string string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.sha256(string) end
|
||||
|
||||
--- Escape {string} for use as a shell command argument.
|
||||
@ -8478,7 +8488,7 @@ function vim.fn.sha256(string) end
|
||||
---
|
||||
--- @param string string
|
||||
--- @param special? boolean
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.shellescape(string, special) end
|
||||
|
||||
--- Returns the effective value of 'shiftwidth'. This is the
|
||||
@ -8930,7 +8940,7 @@ function vim.fn.sign_unplacelist(list) end
|
||||
--- links before simplifying the path name, use |resolve()|.
|
||||
---
|
||||
--- @param filename string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.simplify(filename) end
|
||||
|
||||
--- Return the sine of {expr}, measured in radians, as a |Float|.
|
||||
@ -8943,7 +8953,7 @@ function vim.fn.simplify(filename) end
|
||||
--- < 0.763301
|
||||
---
|
||||
--- @param expr number
|
||||
--- @return any
|
||||
--- @return number
|
||||
function vim.fn.sin(expr) end
|
||||
|
||||
--- Return the hyperbolic sine of {expr} as a |Float| in the range
|
||||
@ -9077,10 +9087,11 @@ function vim.fn.sockconnect(mode, address, opts) end
|
||||
--- eval mylist->sort({i1, i2 -> i1 - i2})
|
||||
--- <
|
||||
---
|
||||
--- @param list any
|
||||
--- @generic T
|
||||
--- @param list T[]
|
||||
--- @param how? string|function
|
||||
--- @param dict? any
|
||||
--- @return any
|
||||
--- @return T[]
|
||||
function vim.fn.sort(list, how, dict) end
|
||||
|
||||
--- Return the sound-folded equivalent of {word}. Uses the first
|
||||
@ -9091,7 +9102,7 @@ function vim.fn.sort(list, how, dict) end
|
||||
--- the method can be quite slow.
|
||||
---
|
||||
--- @param word string
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.soundfold(word) end
|
||||
|
||||
--- Without argument: The result is the badly spelled word under
|
||||
@ -9144,7 +9155,7 @@ function vim.fn.spellbadword(sentence) end
|
||||
--- @param word string
|
||||
--- @param max? integer
|
||||
--- @param capital? boolean
|
||||
--- @return any
|
||||
--- @return string[]
|
||||
function vim.fn.spellsuggest(word, max, capital) end
|
||||
|
||||
--- Make a |List| out of {string}. When {pattern} is omitted or
|
||||
@ -9174,7 +9185,7 @@ function vim.fn.spellsuggest(word, max, capital) end
|
||||
--- @param string string
|
||||
--- @param pattern? string
|
||||
--- @param keepempty? boolean
|
||||
--- @return any
|
||||
--- @return string[]
|
||||
function vim.fn.split(string, pattern, keepempty) end
|
||||
|
||||
--- Return the non-negative square root of Float {expr} as a
|
||||
@ -9326,6 +9337,7 @@ function vim.fn.str2float(string, quoted) end
|
||||
--- and exists only for backwards-compatibility.
|
||||
--- With UTF-8 composing characters are handled properly: >vim
|
||||
--- echo str2list("á") " returns [97, 769]
|
||||
--- <
|
||||
---
|
||||
--- @param string string
|
||||
--- @param utf8? boolean
|
||||
@ -10160,23 +10172,12 @@ function vim.fn.tanh(expr) end
|
||||
--- @return string
|
||||
function vim.fn.tempname() end
|
||||
|
||||
--- Spawns {cmd} in a new pseudo-terminal session connected
|
||||
--- to the current (unmodified) buffer. Parameters and behavior
|
||||
--- are the same as |jobstart()| except "pty", "width", "height",
|
||||
--- and "TERM" are ignored: "height" and "width" are taken from
|
||||
--- the current window. Note that termopen() implies a "pty" arg
|
||||
--- to jobstart(), and thus has the implications documented at
|
||||
--- |jobstart()|.
|
||||
---
|
||||
--- Returns the same values as jobstart().
|
||||
---
|
||||
--- Terminal environment is initialized as in |jobstart-env|,
|
||||
--- except $TERM is set to "xterm-256color". Full behavior is
|
||||
--- described in |terminal|.
|
||||
--- @deprecated
|
||||
--- Use |jobstart()| with `{term: v:true}` instead.
|
||||
---
|
||||
--- @param cmd string|string[]
|
||||
--- @param opts? table
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.termopen(cmd, opts) end
|
||||
|
||||
--- Return a list with information about timers.
|
||||
@ -10576,7 +10577,7 @@ function vim.fn.virtcol(expr, list, winid) end
|
||||
--- @param winid integer
|
||||
--- @param lnum integer
|
||||
--- @param col integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.virtcol2col(winid, lnum, col) end
|
||||
|
||||
--- The result is a String, which describes the last Visual mode
|
||||
@ -10597,7 +10598,7 @@ function vim.fn.virtcol2col(winid, lnum, col) end
|
||||
--- the old value is returned. See |non-zero-arg|.
|
||||
---
|
||||
--- @param expr? boolean
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.visualmode(expr) end
|
||||
|
||||
--- Waits until {condition} evaluates to |TRUE|, where {condition}
|
||||
@ -10714,7 +10715,7 @@ function vim.fn.win_id2tabwin(expr) end
|
||||
--- Return 0 if the window cannot be found in the current tabpage.
|
||||
---
|
||||
--- @param expr integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.win_id2win(expr) end
|
||||
|
||||
--- Move window {nr}'s vertical separator (i.e., the right border)
|
||||
@ -10868,7 +10869,7 @@ function vim.fn.winheight(nr) end
|
||||
--- <
|
||||
---
|
||||
--- @param tabnr? integer
|
||||
--- @return any
|
||||
--- @return any[]
|
||||
function vim.fn.winlayout(tabnr) end
|
||||
|
||||
--- The result is a Number, which is the screen line of the cursor
|
||||
@ -10912,7 +10913,7 @@ function vim.fn.winline() end
|
||||
--- <
|
||||
---
|
||||
--- @param arg? string|integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.winnr(arg) end
|
||||
|
||||
--- Returns a sequence of |:resize| commands that should restore
|
||||
@ -10925,7 +10926,7 @@ function vim.fn.winnr(arg) end
|
||||
--- exe cmd
|
||||
--- <
|
||||
---
|
||||
--- @return any
|
||||
--- @return string
|
||||
function vim.fn.winrestcmd() end
|
||||
|
||||
--- Uses the |Dictionary| returned by |winsaveview()| to restore
|
||||
@ -10990,7 +10991,7 @@ function vim.fn.winsaveview() end
|
||||
--- option.
|
||||
---
|
||||
--- @param nr integer
|
||||
--- @return any
|
||||
--- @return integer
|
||||
function vim.fn.winwidth(nr) end
|
||||
|
||||
--- The result is a dictionary of byte/chars/word statistics for
|
||||
@ -11075,7 +11076,7 @@ function vim.fn.writefile(object, fname, flags) end
|
||||
--- let bits = xor(bits, 0x80)
|
||||
--- <
|
||||
---
|
||||
--- @param expr number
|
||||
--- @param expr1 number
|
||||
--- @return any
|
||||
--- @param expr integer
|
||||
--- @param expr1 integer
|
||||
--- @return integer
|
||||
function vim.fn.xor(expr, expr1) end
|
||||
|
22
runtime/lua/vim/_meta/vvars.lua
generated
22
runtime/lua/vim/_meta/vvars.lua
generated
@ -15,7 +15,7 @@ vim.v.argv = ...
|
||||
--- Argument for evaluating 'formatexpr' and used for the typed
|
||||
--- character when using <expr> in an abbreviation `:map-<expr>`.
|
||||
--- It is also used by the `InsertCharPre` and `InsertEnter` events.
|
||||
--- @type any
|
||||
--- @type string
|
||||
vim.v.char = ...
|
||||
|
||||
--- The name of the character encoding of a file to be converted.
|
||||
@ -60,7 +60,7 @@ vim.v.collate = ...
|
||||
--- mode.
|
||||
--- Note: Plugins can modify the value to emulate the builtin
|
||||
--- `CompleteDone` event behavior.
|
||||
--- @type any
|
||||
--- @type vim.v.completed_item
|
||||
vim.v.completed_item = ...
|
||||
|
||||
--- The count given for the last Normal mode command. Can be used
|
||||
@ -90,7 +90,7 @@ vim.v.count1 = ...
|
||||
--- This variable can not be set directly, use the `:language`
|
||||
--- command.
|
||||
--- See `multi-lang`.
|
||||
--- @type any
|
||||
--- @type string
|
||||
vim.v.ctype = ...
|
||||
|
||||
--- Normally zero. When a deadly signal is caught it's set to
|
||||
@ -197,7 +197,9 @@ vim.v.errors = ...
|
||||
--- changing window (or tab) on `DirChanged`.
|
||||
--- status Job status or exit code, -1 means "unknown". `TermClose`
|
||||
--- reason Reason for completion being done. `CompleteDone`
|
||||
--- @type any
|
||||
--- complete_word The word that was selected, empty if abandoned complete.
|
||||
--- complete_type See `complete_info_mode`
|
||||
--- @type vim.v.event
|
||||
vim.v.event = ...
|
||||
|
||||
--- The value of the exception most recently caught and not
|
||||
@ -223,7 +225,7 @@ vim.v.exception = ...
|
||||
--- ```vim
|
||||
--- :au VimLeave * echo "Exit value is " .. v:exiting
|
||||
--- ```
|
||||
--- @type any
|
||||
--- @type integer?
|
||||
vim.v.exiting = ...
|
||||
|
||||
--- Special value used to put "false" in JSON and msgpack. See
|
||||
@ -419,7 +421,7 @@ vim.v.mouse_winid = ...
|
||||
--- and `msgpackdump()`. All types inside dictionary are fixed
|
||||
--- (not editable) empty lists. To check whether some list is one
|
||||
--- of msgpack types, use `is` operator.
|
||||
--- @type any
|
||||
--- @type table
|
||||
vim.v.msgpack_types = ...
|
||||
|
||||
--- Special value used to put "null" in JSON and NIL in msgpack.
|
||||
@ -563,7 +565,7 @@ vim.v.relnum = ...
|
||||
--- typed command.
|
||||
--- This can be used to find out why your script causes the
|
||||
--- hit-enter prompt.
|
||||
--- @type any
|
||||
--- @type string
|
||||
vim.v.scrollstart = ...
|
||||
|
||||
--- Search direction: 1 after a forward search, 0 after a
|
||||
@ -705,13 +707,13 @@ vim.v.termrequest = ...
|
||||
vim.v.termresponse = ...
|
||||
|
||||
--- Must be set before using `test_garbagecollect_now()`.
|
||||
--- @type any
|
||||
--- @type integer
|
||||
vim.v.testing = ...
|
||||
|
||||
--- Full filename of the last loaded or saved session file.
|
||||
--- Empty when no session file has been saved. See `:mksession`.
|
||||
--- Modifiable (can be set).
|
||||
--- @type any
|
||||
--- @type string
|
||||
vim.v.this_session = ...
|
||||
|
||||
--- The point where the exception most recently caught and not
|
||||
@ -728,7 +730,7 @@ vim.v.this_session = ...
|
||||
--- ```
|
||||
---
|
||||
--- Output: "Exception from test.vim, line 2"
|
||||
--- @type any
|
||||
--- @type string
|
||||
vim.v.throwpoint = ...
|
||||
|
||||
--- Special value used to put "true" in JSON and msgpack. See
|
||||
|
77
runtime/lua/vim/_meta/vvars_extra.lua
Normal file
77
runtime/lua/vim/_meta/vvars_extra.lua
Normal file
@ -0,0 +1,77 @@
|
||||
--- @meta _
|
||||
error('Cannot require a meta file')
|
||||
|
||||
--- Extra types for vim.v dictionary fields
|
||||
|
||||
--- @class vim.v.completed_item
|
||||
--- @field word? string the text that will be inserted, mandatory
|
||||
--- abbreviation of "word"; when not empty it is used in the menu instead of "word"
|
||||
--- @field abbr? string
|
||||
--- extra text for the popup menu, displayed after "word" or "abbr"
|
||||
--- @field menu? string
|
||||
--- more information about the item, can be displayed in a preview window
|
||||
--- @field info? string
|
||||
--- @field kind? string single letter indicating the type of completion
|
||||
--- when non-zero case is to be ignored when comparing items to be equal; when
|
||||
--- omitted zero is used, thus items that only differ in case are added
|
||||
--- @field icase? integer
|
||||
--- when non-zero, always treat this item to be equal when comparing. Which
|
||||
--- means, "equal=1" disables filtering of this item.
|
||||
--- @field equal? integer
|
||||
--- when non-zero this match will be added even when an item with the same word
|
||||
--- is already present.
|
||||
--- @field dup? integer
|
||||
--- when non-zero this match will be added even when it is an empty string
|
||||
--- @field empty? integer
|
||||
--- custom data which is associated with the item and available
|
||||
--- in |v:completed_item|; it can be any type; defaults to an empty string
|
||||
--- @field user_data? any
|
||||
--- an additional highlight group whose attributes are combined
|
||||
--- with |hl-PmenuSel| and |hl-Pmenu| or |hl-PmenuMatchSel| and |hl-PmenuMatch|
|
||||
--- highlight attributes in the popup menu to apply cterm and gui properties
|
||||
--- (with higher priority) like strikethrough to the completion items abbreviation
|
||||
--- @field abbr_hlgroup? string
|
||||
--- an additional highlight group specifically for setting the highlight
|
||||
--- attributes of the completion kind. When this field is present, it will
|
||||
--- override the |hl-PmenuKind| highlight group, allowing for the customization
|
||||
--- of ctermfg and guifg properties for the completion kind
|
||||
--- @field kind_hlgroup? string
|
||||
|
||||
--- @class vim.v.event
|
||||
--- Whether the event triggered during an aborting condition (e.g. |c_Esc| or
|
||||
--- |c_CTRL-C| for |CmdlineLeave|).
|
||||
--- @field abort? boolean
|
||||
--- @field chan? integer See |channel-id|
|
||||
--- @field info? table Dict of arbitrary event data.
|
||||
--- @field cmdlevel? integer Level of cmdline.
|
||||
--- @field cmdtype? string Type of cmdline, |cmdline-char|.
|
||||
--- @field cwd? string Current working directory.
|
||||
--- @field inclusive? boolean Motion is |inclusive|, else exclusive.
|
||||
--- @field scope? string Event-specific scope name.
|
||||
--- Current |operator|. Also set for Ex commands (unlike |v:operator|). For
|
||||
--- example if |TextYankPost| is triggered by the |:yank| Ex command then
|
||||
--- `v:event.operator` is "y".
|
||||
--- @field operator? string
|
||||
--- Text stored in the register as a |readfile()|-style list of lines.
|
||||
--- @field regcontents? string
|
||||
--- Requested register (e.g "x" for "xyy) or the empty string for an unnamed operation.
|
||||
--- @field regname? string
|
||||
--- @field regtype? string Type of register as returned by |getregtype()|.
|
||||
--- @field visual? boolean Selection is visual (as opposed to, e.g., via motion).
|
||||
--- @field completed_item? vim.v.completed_item
|
||||
--- Current selected complete item on |CompleteChanged|, Is `{}` when no
|
||||
--- complete item selected.
|
||||
--- @field height? integer
|
||||
--- @field width? integer Height of popup menu on |CompleteChanged|
|
||||
--- @field row? integer Width of popup menu on |CompleteChanged|
|
||||
--- Col count of popup menu on |CompleteChanged|, relative to screen.
|
||||
--- @field col? integer
|
||||
--- @field size? integer Total number of completion items on |CompleteChanged|.
|
||||
--- Is |v:true| if popup menu have scrollbar, or |v:false| if not.
|
||||
--- @field scrollbar? boolean
|
||||
--- Is |v:true| if the event fired while changing window (or tab) on |DirChanged|.
|
||||
--- @field changed_window? boolean
|
||||
--- @field status? boolean Job status or exit code, -1 means "unknown". |TermClose|
|
||||
--- @field reason? string Reason for completion being done. |CompleteDone|
|
||||
--- The word that was selected, empty if abandoned complete. @field complete_word? string
|
||||
--- @field complete_type? string See |complete_info_mode|
|
@ -47,15 +47,6 @@ local function close_handle(handle)
|
||||
end
|
||||
end
|
||||
|
||||
---@param state vim.SystemState
|
||||
local function close_handles(state)
|
||||
close_handle(state.handle)
|
||||
close_handle(state.stdin)
|
||||
close_handle(state.stdout)
|
||||
close_handle(state.stderr)
|
||||
close_handle(state.timer)
|
||||
end
|
||||
|
||||
--- @class vim.SystemObj
|
||||
--- @field cmd string[]
|
||||
--- @field pid integer
|
||||
@ -132,9 +123,7 @@ function SystemObj:write(data)
|
||||
-- (https://github.com/neovim/neovim/pull/17620#discussion_r820775616)
|
||||
stdin:write('', function()
|
||||
stdin:shutdown(function()
|
||||
if stdin then
|
||||
stdin:close()
|
||||
end
|
||||
close_handle(stdin)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@ -146,25 +135,52 @@ function SystemObj:is_closing()
|
||||
return handle == nil or handle:is_closing() or false
|
||||
end
|
||||
|
||||
---@param output fun(err:string?, data: string?)|false
|
||||
---@return uv.uv_stream_t?
|
||||
---@return fun(err:string?, data: string?)? Handler
|
||||
local function setup_output(output)
|
||||
if output == nil then
|
||||
return assert(uv.new_pipe(false)), nil
|
||||
--- @param output? uv.read_start.callback|false
|
||||
--- @param text? boolean
|
||||
--- @return uv.uv_stream_t? pipe
|
||||
--- @return uv.read_start.callback? handler
|
||||
--- @return string[]? data
|
||||
local function setup_output(output, text)
|
||||
if output == false then
|
||||
return
|
||||
end
|
||||
|
||||
local bucket --- @type string[]?
|
||||
local handler --- @type uv.read_start.callback
|
||||
|
||||
if type(output) == 'function' then
|
||||
return assert(uv.new_pipe(false)), output
|
||||
handler = output
|
||||
else
|
||||
bucket = {}
|
||||
handler = function(err, data)
|
||||
if err then
|
||||
error(err)
|
||||
end
|
||||
if text and data then
|
||||
bucket[#bucket + 1] = data:gsub('\r\n', '\n')
|
||||
else
|
||||
bucket[#bucket + 1] = data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assert(output == false)
|
||||
return nil, nil
|
||||
local pipe = assert(uv.new_pipe(false))
|
||||
|
||||
--- @type uv.read_start.callback
|
||||
local function handler_with_close(err, data)
|
||||
handler(err, data)
|
||||
if data == nil then
|
||||
pipe:read_stop()
|
||||
pipe:close()
|
||||
end
|
||||
end
|
||||
|
||||
return pipe, handler_with_close, bucket
|
||||
end
|
||||
|
||||
---@param input string|string[]|true|nil
|
||||
---@return uv.uv_stream_t?
|
||||
---@return string|string[]?
|
||||
--- @param input? string|string[]|boolean
|
||||
--- @return uv.uv_stream_t?
|
||||
--- @return string|string[]?
|
||||
local function setup_input(input)
|
||||
if not input then
|
||||
return
|
||||
@ -208,28 +224,6 @@ local function setup_env(env, clear_env)
|
||||
return renv
|
||||
end
|
||||
|
||||
--- @param stream uv.uv_stream_t
|
||||
--- @param text? boolean
|
||||
--- @param bucket string[]
|
||||
--- @return fun(err: string?, data: string?)
|
||||
local function default_handler(stream, text, bucket)
|
||||
return function(err, data)
|
||||
if err then
|
||||
error(err)
|
||||
end
|
||||
if data ~= nil then
|
||||
if text then
|
||||
bucket[#bucket + 1] = data:gsub('\r\n', '\n')
|
||||
else
|
||||
bucket[#bucket + 1] = data
|
||||
end
|
||||
else
|
||||
stream:read_stop()
|
||||
stream:close()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local is_win = vim.fn.has('win32') == 1
|
||||
|
||||
local M = {}
|
||||
@ -255,9 +249,9 @@ local function spawn(cmd, opts, on_exit, on_error)
|
||||
return handle, pid_or_err --[[@as integer]]
|
||||
end
|
||||
|
||||
---@param timeout integer
|
||||
---@param cb fun()
|
||||
---@return uv.uv_timer_t
|
||||
--- @param timeout integer
|
||||
--- @param cb fun()
|
||||
--- @return uv.uv_timer_t
|
||||
local function timer_oneshot(timeout, cb)
|
||||
local timer = assert(uv.new_timer())
|
||||
timer:start(timeout, 0, function()
|
||||
@ -273,7 +267,12 @@ end
|
||||
--- @param signal integer
|
||||
--- @param on_exit fun(result: vim.SystemCompleted)?
|
||||
local function _on_exit(state, code, signal, on_exit)
|
||||
close_handles(state)
|
||||
close_handle(state.handle)
|
||||
close_handle(state.stdin)
|
||||
close_handle(state.timer)
|
||||
|
||||
-- #30846: Do not close stdout/stderr here, as they may still have data to
|
||||
-- read. They will be closed in uv.read_start on EOF.
|
||||
|
||||
local check = assert(uv.new_check())
|
||||
check:start(function()
|
||||
@ -311,6 +310,15 @@ local function _on_exit(state, code, signal, on_exit)
|
||||
end)
|
||||
end
|
||||
|
||||
--- @param state vim.SystemState
|
||||
local function _on_error(state)
|
||||
close_handle(state.handle)
|
||||
close_handle(state.stdin)
|
||||
close_handle(state.stdout)
|
||||
close_handle(state.stderr)
|
||||
close_handle(state.timer)
|
||||
end
|
||||
|
||||
--- Run a system command
|
||||
---
|
||||
--- @param cmd string[]
|
||||
@ -324,8 +332,8 @@ function M.run(cmd, opts, on_exit)
|
||||
|
||||
opts = opts or {}
|
||||
|
||||
local stdout, stdout_handler = setup_output(opts.stdout)
|
||||
local stderr, stderr_handler = setup_output(opts.stderr)
|
||||
local stdout, stdout_handler, stdout_data = setup_output(opts.stdout, opts.text)
|
||||
local stderr, stderr_handler, stderr_data = setup_output(opts.stderr, opts.text)
|
||||
local stdin, towrite = setup_input(opts.stdin)
|
||||
|
||||
--- @type vim.SystemState
|
||||
@ -335,7 +343,9 @@ function M.run(cmd, opts, on_exit)
|
||||
timeout = opts.timeout,
|
||||
stdin = stdin,
|
||||
stdout = stdout,
|
||||
stdout_data = stdout_data,
|
||||
stderr = stderr,
|
||||
stderr_data = stderr_data,
|
||||
}
|
||||
|
||||
--- @diagnostic disable-next-line:missing-fields
|
||||
@ -350,17 +360,15 @@ function M.run(cmd, opts, on_exit)
|
||||
}, function(code, signal)
|
||||
_on_exit(state, code, signal, on_exit)
|
||||
end, function()
|
||||
close_handles(state)
|
||||
_on_error(state)
|
||||
end)
|
||||
|
||||
if stdout then
|
||||
state.stdout_data = {}
|
||||
stdout:read_start(stdout_handler or default_handler(stdout, opts.text, state.stdout_data))
|
||||
if stdout and stdout_handler then
|
||||
stdout:read_start(stdout_handler)
|
||||
end
|
||||
|
||||
if stderr then
|
||||
state.stderr_data = {}
|
||||
stderr:read_start(stderr_handler or default_handler(stderr, opts.text, state.stderr_data))
|
||||
if stderr and stderr_handler then
|
||||
stderr:read_start(stderr_handler)
|
||||
end
|
||||
|
||||
local obj = new_systemobj(state)
|
||||
|
@ -2,6 +2,20 @@ local api, if_nil = vim.api, vim.F.if_nil
|
||||
|
||||
local M = {}
|
||||
|
||||
--- @param title string
|
||||
--- @return integer?
|
||||
local function get_qf_id_for_title(title)
|
||||
local lastqflist = vim.fn.getqflist({ nr = '$' })
|
||||
for i = 1, lastqflist.nr do
|
||||
local qflist = vim.fn.getqflist({ nr = i, id = 0, title = 0 })
|
||||
if qflist.title == title then
|
||||
return qflist.id
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- [diagnostic-structure]()
|
||||
---
|
||||
--- Diagnostics use the same indexing as the rest of the Nvim API (i.e. 0-based
|
||||
@ -571,13 +585,6 @@ local underline_highlight_map = make_highlight_map('Underline')
|
||||
local floating_highlight_map = make_highlight_map('Floating')
|
||||
local sign_highlight_map = make_highlight_map('Sign')
|
||||
|
||||
local function get_bufnr(bufnr)
|
||||
if not bufnr or bufnr == 0 then
|
||||
return api.nvim_get_current_buf()
|
||||
end
|
||||
return bufnr
|
||||
end
|
||||
|
||||
--- @param diagnostics vim.Diagnostic[]
|
||||
--- @return table<integer,vim.Diagnostic[]>
|
||||
local function diagnostic_lines(diagnostics)
|
||||
@ -640,7 +647,7 @@ end
|
||||
--- @param namespace integer
|
||||
--- @param bufnr? integer
|
||||
local function save_extmarks(namespace, bufnr)
|
||||
bufnr = get_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
if not diagnostic_attached_buffers[bufnr] then
|
||||
api.nvim_buf_attach(bufnr, false, {
|
||||
on_lines = function(_, _, _, _, _, last)
|
||||
@ -812,7 +819,7 @@ local function get_diagnostics(bufnr, opts, clamp)
|
||||
end
|
||||
end
|
||||
elseif namespace == nil then
|
||||
bufnr = get_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
for iter_namespace in pairs(diagnostic_cache[bufnr]) do
|
||||
add_all_diags(bufnr, diagnostic_cache[bufnr][iter_namespace])
|
||||
end
|
||||
@ -823,7 +830,7 @@ local function get_diagnostics(bufnr, opts, clamp)
|
||||
end
|
||||
end
|
||||
else
|
||||
bufnr = get_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
for _, iter_namespace in ipairs(namespace) do
|
||||
add_all_diags(bufnr, diagnostic_cache[bufnr][iter_namespace] or {})
|
||||
end
|
||||
@ -847,13 +854,33 @@ local function set_list(loclist, opts)
|
||||
-- numbers beyond the end of the buffer
|
||||
local diagnostics = get_diagnostics(bufnr, opts --[[@as vim.diagnostic.GetOpts]], false)
|
||||
local items = M.toqflist(diagnostics)
|
||||
local qf_id = nil
|
||||
if loclist then
|
||||
vim.fn.setloclist(winnr, {}, ' ', { title = title, items = items })
|
||||
vim.fn.setloclist(winnr, {}, 'u', { title = title, items = items })
|
||||
else
|
||||
vim.fn.setqflist({}, ' ', { title = title, items = items })
|
||||
qf_id = get_qf_id_for_title(title)
|
||||
|
||||
-- If we already have a diagnostics quickfix, update it rather than creating a new one.
|
||||
-- This avoids polluting the finite set of quickfix lists, and preserves the currently selected
|
||||
-- entry.
|
||||
vim.fn.setqflist({}, qf_id and 'u' or ' ', {
|
||||
title = title,
|
||||
items = items,
|
||||
id = qf_id,
|
||||
})
|
||||
end
|
||||
|
||||
if open then
|
||||
api.nvim_command(loclist and 'lwindow' or 'botright cwindow')
|
||||
if not loclist then
|
||||
-- First navigate to the diagnostics quickfix list.
|
||||
local nr = vim.fn.getqflist({ id = qf_id, nr = 0 }).nr
|
||||
api.nvim_command(nr .. 'chistory')
|
||||
|
||||
-- Now open the quickfix list.
|
||||
api.nvim_command('botright cwindow')
|
||||
else
|
||||
api.nvim_command('lwindow')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1081,7 +1108,7 @@ function M.set(namespace, bufnr, diagnostics, opts)
|
||||
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
|
||||
vim.validate('opts', opts, 'table', true)
|
||||
|
||||
bufnr = get_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
if vim.tbl_isempty(diagnostics) then
|
||||
diagnostic_cache[bufnr][namespace] = nil
|
||||
@ -1361,7 +1388,7 @@ M.handlers.signs = {
|
||||
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
|
||||
vim.validate('opts', opts, 'table', true)
|
||||
|
||||
bufnr = get_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
opts = opts or {}
|
||||
|
||||
if not api.nvim_buf_is_loaded(bufnr) then
|
||||
@ -1467,7 +1494,7 @@ M.handlers.underline = {
|
||||
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
|
||||
vim.validate('opts', opts, 'table', true)
|
||||
|
||||
bufnr = get_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
opts = opts or {}
|
||||
|
||||
if not vim.api.nvim_buf_is_loaded(bufnr) then
|
||||
@ -1531,7 +1558,7 @@ M.handlers.virtual_text = {
|
||||
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
|
||||
vim.validate('opts', opts, 'table', true)
|
||||
|
||||
bufnr = get_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
opts = opts or {}
|
||||
|
||||
if not vim.api.nvim_buf_is_loaded(bufnr) then
|
||||
@ -1656,7 +1683,7 @@ function M.hide(namespace, bufnr)
|
||||
vim.validate('namespace', namespace, 'number', true)
|
||||
vim.validate('bufnr', bufnr, 'number', true)
|
||||
|
||||
local buffers = bufnr and { get_bufnr(bufnr) } or vim.tbl_keys(diagnostic_cache)
|
||||
local buffers = bufnr and { vim._resolve_bufnr(bufnr) } or vim.tbl_keys(diagnostic_cache)
|
||||
for _, iter_bufnr in ipairs(buffers) do
|
||||
local namespaces = namespace and { namespace } or vim.tbl_keys(diagnostic_cache[iter_bufnr])
|
||||
for _, iter_namespace in ipairs(namespaces) do
|
||||
@ -1683,7 +1710,7 @@ function M.is_enabled(filter)
|
||||
return vim.tbl_isempty(diagnostic_disabled) and not diagnostic_disabled[1]
|
||||
end
|
||||
|
||||
local bufnr = get_bufnr(filter.bufnr)
|
||||
local bufnr = vim._resolve_bufnr(filter.bufnr)
|
||||
if type(diagnostic_disabled[bufnr]) == 'table' then
|
||||
return not diagnostic_disabled[bufnr][filter.ns_id]
|
||||
end
|
||||
@ -1724,7 +1751,7 @@ function M.show(namespace, bufnr, diagnostics, opts)
|
||||
end
|
||||
else
|
||||
-- namespace is nil
|
||||
bufnr = get_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
for iter_namespace in pairs(diagnostic_cache[bufnr]) do
|
||||
M.show(iter_namespace, bufnr, nil, opts)
|
||||
end
|
||||
@ -1791,7 +1818,7 @@ function M.open_float(opts, ...)
|
||||
end
|
||||
|
||||
opts = opts or {}
|
||||
bufnr = get_bufnr(bufnr or opts.bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr or opts.bufnr)
|
||||
|
||||
do
|
||||
-- Resolve options with user settings from vim.diagnostic.config
|
||||
@ -1962,6 +1989,7 @@ function M.open_float(opts, ...)
|
||||
opts.focus_id = scope
|
||||
end
|
||||
local float_bufnr, winnr = vim.lsp.util.open_floating_preview(lines, 'plaintext', opts)
|
||||
vim.bo[float_bufnr].path = vim.bo[bufnr].path
|
||||
for i, hl in ipairs(highlights) do
|
||||
local line = lines[i]
|
||||
local prefix_len = hl.prefix and hl.prefix.length or 0
|
||||
@ -1993,7 +2021,7 @@ function M.reset(namespace, bufnr)
|
||||
vim.validate('namespace', namespace, 'number', true)
|
||||
vim.validate('bufnr', bufnr, 'number', true)
|
||||
|
||||
local buffers = bufnr and { get_bufnr(bufnr) } or vim.tbl_keys(diagnostic_cache)
|
||||
local buffers = bufnr and { vim._resolve_bufnr(bufnr) } or vim.tbl_keys(diagnostic_cache)
|
||||
for _, iter_bufnr in ipairs(buffers) do
|
||||
local namespaces = namespace and { namespace } or vim.tbl_keys(diagnostic_cache[iter_bufnr])
|
||||
for _, iter_namespace in ipairs(namespaces) do
|
||||
@ -2024,7 +2052,8 @@ end
|
||||
--- (default: `true`)
|
||||
--- @field open? boolean
|
||||
---
|
||||
--- Title of quickfix list. Defaults to "Diagnostics".
|
||||
--- Title of quickfix list. Defaults to "Diagnostics". If there's already a quickfix list with this
|
||||
--- title, it's updated. If not, a new quickfix list is created.
|
||||
--- @field title? string
|
||||
---
|
||||
--- See |diagnostic-severity|.
|
||||
@ -2131,7 +2160,7 @@ function M.enable(enable, filter)
|
||||
ns.disabled = not enable
|
||||
end
|
||||
else
|
||||
bufnr = get_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
if not ns_id then
|
||||
diagnostic_disabled[bufnr] = (not enable) and true or nil
|
||||
else
|
||||
|
@ -672,6 +672,7 @@ local extension = {
|
||||
k = 'kwt',
|
||||
ACE = 'lace',
|
||||
ace = 'lace',
|
||||
lalrpop = 'lalrpop',
|
||||
latte = 'latte',
|
||||
lte = 'latte',
|
||||
ld = 'ld',
|
||||
@ -743,6 +744,7 @@ local extension = {
|
||||
mkd = detect.markdown,
|
||||
markdown = detect.markdown,
|
||||
mdown = detect.markdown,
|
||||
masm = 'masm',
|
||||
mhtml = 'mason',
|
||||
mason = 'mason',
|
||||
master = 'master',
|
||||
@ -805,6 +807,7 @@ local extension = {
|
||||
n1ql = 'n1ql',
|
||||
nql = 'n1ql',
|
||||
nanorc = 'nanorc',
|
||||
nasm = 'nasm',
|
||||
NSA = 'natural',
|
||||
NSC = 'natural',
|
||||
NSG = 'natural',
|
||||
@ -958,11 +961,14 @@ local extension = {
|
||||
ps1xml = 'ps1xml',
|
||||
psf = 'psf',
|
||||
psl = 'psl',
|
||||
ptx = 'ptx',
|
||||
pug = 'pug',
|
||||
purs = 'purescript',
|
||||
arr = 'pyret',
|
||||
pxd = 'pyrex',
|
||||
pxi = 'pyrex',
|
||||
pyx = 'pyrex',
|
||||
['pyx+'] = 'pyrex',
|
||||
pyw = 'python',
|
||||
py = 'python',
|
||||
pyi = 'python',
|
||||
@ -1869,8 +1875,11 @@ local filename = {
|
||||
['.clangd'] = 'yaml',
|
||||
['.clang-format'] = 'yaml',
|
||||
['.clang-tidy'] = 'yaml',
|
||||
['pixi.lock'] = 'yaml',
|
||||
['yarn.lock'] = 'yaml',
|
||||
matplotlibrc = 'yaml',
|
||||
['.condarc'] = 'yaml',
|
||||
condarc = 'yaml',
|
||||
zathurarc = 'zathurarc',
|
||||
['/etc/zprofile'] = 'zsh',
|
||||
['.zlogin'] = 'zsh',
|
||||
|
@ -1,3 +1,15 @@
|
||||
--- @brief <pre>help
|
||||
--- *vim.fs.exists()*
|
||||
--- Use |uv.fs_stat()| to check a file's type, and whether it exists.
|
||||
---
|
||||
--- Example:
|
||||
---
|
||||
--- >lua
|
||||
--- if vim.uv.fs_stat(file) then
|
||||
--- vim.print("file exists")
|
||||
--- end
|
||||
--- <
|
||||
|
||||
local uv = vim.uv
|
||||
|
||||
local M = {}
|
||||
|
@ -399,50 +399,57 @@ function M.reset(path)
|
||||
end
|
||||
end
|
||||
|
||||
--- Enables the experimental Lua module loader:
|
||||
--- * overrides loadfile
|
||||
--- Enables or disables the experimental Lua module loader:
|
||||
---
|
||||
--- Enable (`enable=true`):
|
||||
--- * overrides |loadfile()|
|
||||
--- * adds the Lua loader using the byte-compilation cache
|
||||
--- * adds the libs loader
|
||||
--- * removes the default Nvim loader
|
||||
---
|
||||
--- @since 0
|
||||
function M.enable()
|
||||
if M.enabled then
|
||||
return
|
||||
end
|
||||
M.enabled = true
|
||||
vim.fn.mkdir(vim.fn.fnamemodify(M.path, ':p'), 'p')
|
||||
_G.loadfile = loadfile_cached
|
||||
-- add Lua loader
|
||||
table.insert(loaders, 2, loader_cached)
|
||||
-- add libs loader
|
||||
table.insert(loaders, 3, loader_lib_cached)
|
||||
-- remove Nvim loader
|
||||
for l, loader in ipairs(loaders) do
|
||||
if loader == vim._load_package then
|
||||
table.remove(loaders, l)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Disables the experimental Lua module loader:
|
||||
--- Disable (`enable=false`):
|
||||
--- * removes the loaders
|
||||
--- * adds the default Nvim loader
|
||||
---
|
||||
--- @since 0
|
||||
function M.disable()
|
||||
if not M.enabled then
|
||||
---
|
||||
--- @param enable? (boolean) true/nil to enable, false to disable
|
||||
function M.enable(enable)
|
||||
enable = enable == nil and true or enable
|
||||
if enable == M.enabled then
|
||||
return
|
||||
end
|
||||
M.enabled = false
|
||||
_G.loadfile = _loadfile
|
||||
for l, loader in ipairs(loaders) do
|
||||
if loader == loader_cached or loader == loader_lib_cached then
|
||||
table.remove(loaders, l)
|
||||
M.enabled = enable
|
||||
|
||||
if enable then
|
||||
vim.fn.mkdir(vim.fn.fnamemodify(M.path, ':p'), 'p')
|
||||
_G.loadfile = loadfile_cached
|
||||
-- add Lua loader
|
||||
table.insert(loaders, 2, loader_cached)
|
||||
-- add libs loader
|
||||
table.insert(loaders, 3, loader_lib_cached)
|
||||
-- remove Nvim loader
|
||||
for l, loader in ipairs(loaders) do
|
||||
if loader == vim._load_package then
|
||||
table.remove(loaders, l)
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
_G.loadfile = _loadfile
|
||||
for l, loader in ipairs(loaders) do
|
||||
if loader == loader_cached or loader == loader_lib_cached then
|
||||
table.remove(loaders, l)
|
||||
end
|
||||
end
|
||||
table.insert(loaders, 2, vim._load_package)
|
||||
end
|
||||
table.insert(loaders, 2, vim._load_package)
|
||||
end
|
||||
|
||||
--- @deprecated
|
||||
function M.disable()
|
||||
vim.deprecate('vim.loader.disable', 'vim.loader.enable(false)', '0.12')
|
||||
vim.loader.enable(false)
|
||||
end
|
||||
|
||||
--- Tracks the time spent in a function
|
||||
|
@ -3,6 +3,7 @@ local validate = vim.validate
|
||||
|
||||
local lsp = vim._defer_require('vim.lsp', {
|
||||
_changetracking = ..., --- @module 'vim.lsp._changetracking'
|
||||
_folding_range = ..., --- @module 'vim.lsp._folding_range'
|
||||
_snippet_grammar = ..., --- @module 'vim.lsp._snippet_grammar'
|
||||
_tagfunc = ..., --- @module 'vim.lsp._tagfunc'
|
||||
_watchfiles = ..., --- @module 'vim.lsp._watchfiles'
|
||||
@ -57,6 +58,7 @@ lsp._request_name_to_capability = {
|
||||
[ms.textDocument_documentHighlight] = { 'documentHighlightProvider' },
|
||||
[ms.textDocument_documentLink] = { 'documentLinkProvider' },
|
||||
[ms.textDocument_documentSymbol] = { 'documentSymbolProvider' },
|
||||
[ms.textDocument_foldingRange] = { 'foldingRangeProvider' },
|
||||
[ms.textDocument_formatting] = { 'documentFormattingProvider' },
|
||||
[ms.textDocument_hover] = { 'hoverProvider' },
|
||||
[ms.textDocument_implementation] = { 'implementationProvider' },
|
||||
@ -87,18 +89,6 @@ lsp._request_name_to_capability = {
|
||||
|
||||
-- TODO improve handling of scratch buffers with LSP attached.
|
||||
|
||||
--- Returns the buffer number for the given {bufnr}.
|
||||
---
|
||||
---@param bufnr (integer|nil) Buffer number to resolve. Defaults to current buffer
|
||||
---@return integer bufnr
|
||||
local function resolve_bufnr(bufnr)
|
||||
validate('bufnr', bufnr, 'number', true)
|
||||
if bufnr == nil or bufnr == 0 then
|
||||
return api.nvim_get_current_buf()
|
||||
end
|
||||
return bufnr
|
||||
end
|
||||
|
||||
---@private
|
||||
--- Called by the client when trying to call a method that's not
|
||||
--- supported in any of the servers registered for the current buffer.
|
||||
@ -112,6 +102,22 @@ function lsp._unsupported_method(method)
|
||||
return msg
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param workspace_folders string|lsp.WorkspaceFolder[]?
|
||||
---@return lsp.WorkspaceFolder[]?
|
||||
function lsp._get_workspace_folders(workspace_folders)
|
||||
if type(workspace_folders) == 'table' then
|
||||
return workspace_folders
|
||||
elseif type(workspace_folders) == 'string' then
|
||||
return {
|
||||
{
|
||||
uri = vim.uri_from_fname(workspace_folders),
|
||||
name = workspace_folders,
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local wait_result_reason = { [-1] = 'timeout', [-2] = 'interrupted', [-3] = 'error' }
|
||||
|
||||
local format_line_ending = {
|
||||
@ -194,34 +200,381 @@ local function reuse_client_default(client, config)
|
||||
return false
|
||||
end
|
||||
|
||||
if config.root_dir then
|
||||
local root = vim.uri_from_fname(config.root_dir)
|
||||
for _, dir in ipairs(client.workspace_folders or {}) do
|
||||
-- note: do not need to check client.root_dir since that should be client.workspace_folders[1]
|
||||
if root == dir.uri then
|
||||
return true
|
||||
local config_folders = lsp._get_workspace_folders(config.workspace_folders or config.root_dir)
|
||||
|
||||
if not config_folders or not next(config_folders) then
|
||||
-- Reuse if the client was configured with no workspace folders
|
||||
local client_config_folders =
|
||||
lsp._get_workspace_folders(client.config.workspace_folders or client.config.root_dir)
|
||||
return not client_config_folders or not next(client_config_folders)
|
||||
end
|
||||
|
||||
for _, config_folder in ipairs(config_folders) do
|
||||
local found = false
|
||||
for _, client_folder in ipairs(client.workspace_folders) do
|
||||
if config_folder.uri == client_folder.uri then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO(lewis6991): also check config.workspace_folders
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
--- Reset defaults set by `set_defaults`.
|
||||
--- Must only be called if the last client attached to a buffer exits.
|
||||
local function reset_defaults(bufnr)
|
||||
if vim.bo[bufnr].tagfunc == 'v:lua.vim.lsp.tagfunc' then
|
||||
vim.bo[bufnr].tagfunc = nil
|
||||
end
|
||||
if vim.bo[bufnr].omnifunc == 'v:lua.vim.lsp.omnifunc' then
|
||||
vim.bo[bufnr].omnifunc = nil
|
||||
end
|
||||
if vim.bo[bufnr].formatexpr == 'v:lua.vim.lsp.formatexpr()' then
|
||||
vim.bo[bufnr].formatexpr = nil
|
||||
end
|
||||
vim._with({ buf = bufnr }, function()
|
||||
local keymap = vim.fn.maparg('K', 'n', false, true)
|
||||
if keymap and keymap.callback == vim.lsp.buf.hover and keymap.buffer == 1 then
|
||||
vim.keymap.del('n', 'K', { buffer = bufnr })
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- @param code integer
|
||||
--- @param signal integer
|
||||
--- @param client_id integer
|
||||
local function on_client_exit(code, signal, client_id)
|
||||
local client = all_clients[client_id]
|
||||
|
||||
vim.schedule(function()
|
||||
for bufnr in pairs(client.attached_buffers) do
|
||||
if client and client.attached_buffers[bufnr] and api.nvim_buf_is_valid(bufnr) then
|
||||
api.nvim_exec_autocmds('LspDetach', {
|
||||
buffer = bufnr,
|
||||
modeline = false,
|
||||
data = { client_id = client_id },
|
||||
})
|
||||
end
|
||||
|
||||
client.attached_buffers[bufnr] = nil
|
||||
|
||||
if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then
|
||||
reset_defaults(bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
local namespace = vim.lsp.diagnostic.get_namespace(client_id)
|
||||
vim.diagnostic.reset(namespace)
|
||||
end)
|
||||
|
||||
local name = client.name or 'unknown'
|
||||
|
||||
-- Schedule the deletion of the client object so that it exists in the execution of LspDetach
|
||||
-- autocommands
|
||||
vim.schedule(function()
|
||||
all_clients[client_id] = nil
|
||||
|
||||
-- Client can be absent if executable starts, but initialize fails
|
||||
-- init/attach won't have happened
|
||||
if client then
|
||||
changetracking.reset(client)
|
||||
end
|
||||
if code ~= 0 or (signal ~= 0 and signal ~= 15) then
|
||||
local msg = string.format(
|
||||
'Client %s quit with exit code %s and signal %s. Check log for errors: %s',
|
||||
name,
|
||||
code,
|
||||
signal,
|
||||
lsp.get_log_path()
|
||||
)
|
||||
vim.notify(msg, vim.log.levels.WARN)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- Creates and initializes a client with the given configuration.
|
||||
--- @param config vim.lsp.ClientConfig Configuration for the server.
|
||||
--- @return integer? client_id |vim.lsp.get_client_by_id()| Note: client may not be
|
||||
--- fully initialized. Use `on_init` to do any actions once
|
||||
--- the client has been initialized.
|
||||
--- @return string? # Error message, if any
|
||||
local function create_and_initialize_client(config)
|
||||
local ok, res = pcall(require('vim.lsp.client').create, config)
|
||||
if not ok then
|
||||
return nil, res --[[@as string]]
|
||||
end
|
||||
|
||||
local client = assert(res)
|
||||
|
||||
--- @diagnostic disable-next-line: invisible
|
||||
table.insert(client._on_exit_cbs, on_client_exit)
|
||||
|
||||
all_clients[client.id] = client
|
||||
|
||||
client:initialize()
|
||||
|
||||
return client.id, nil
|
||||
end
|
||||
|
||||
--- @class vim.lsp.Config : vim.lsp.ClientConfig
|
||||
---
|
||||
--- See `cmd` in [vim.lsp.ClientConfig].
|
||||
--- @field cmd? string[]|fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient
|
||||
---
|
||||
--- Filetypes the client will attach to, if activated by `vim.lsp.enable()`.
|
||||
--- If not provided, then the client will attach to all filetypes.
|
||||
--- @field filetypes? string[]
|
||||
---
|
||||
--- Directory markers (.e.g. '.git/') where the LSP server will base its workspaceFolders,
|
||||
--- rootUri, and rootPath on initialization. Unused if `root_dir` is provided.
|
||||
--- @field root_markers? string[]
|
||||
---
|
||||
--- Predicate used to decide if a client should be re-used. Used on all
|
||||
--- running clients. The default implementation re-uses a client if name and
|
||||
--- root_dir matches.
|
||||
--- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean
|
||||
|
||||
--- Update the configuration for an LSP client.
|
||||
---
|
||||
--- Use name '*' to set default configuration for all clients.
|
||||
---
|
||||
--- Can also be table-assigned to redefine the configuration for a client.
|
||||
---
|
||||
--- Examples:
|
||||
---
|
||||
--- - Add a root marker for all clients:
|
||||
--- ```lua
|
||||
--- vim.lsp.config('*', {
|
||||
--- root_markers = { '.git' },
|
||||
--- })
|
||||
--- ```
|
||||
--- - Add additional capabilities to all clients:
|
||||
--- ```lua
|
||||
--- vim.lsp.config('*', {
|
||||
--- capabilities = {
|
||||
--- textDocument = {
|
||||
--- semanticTokens = {
|
||||
--- multilineTokenSupport = true,
|
||||
--- }
|
||||
--- }
|
||||
--- }
|
||||
--- })
|
||||
--- ```
|
||||
--- - (Re-)define the configuration for clangd:
|
||||
--- ```lua
|
||||
--- vim.lsp.config.clangd = {
|
||||
--- cmd = {
|
||||
--- 'clangd',
|
||||
--- '--clang-tidy',
|
||||
--- '--background-index',
|
||||
--- '--offset-encoding=utf-8',
|
||||
--- },
|
||||
--- root_markers = { '.clangd', 'compile_commands.json' },
|
||||
--- filetypes = { 'c', 'cpp' },
|
||||
--- }
|
||||
--- ```
|
||||
--- - Get configuration for luals:
|
||||
--- ```lua
|
||||
--- local cfg = vim.lsp.config.luals
|
||||
--- ```
|
||||
---
|
||||
--- @param name string
|
||||
--- @param cfg vim.lsp.Config
|
||||
--- @diagnostic disable-next-line:assign-type-mismatch
|
||||
function lsp.config(name, cfg)
|
||||
local _, _ = name, cfg -- ignore unused
|
||||
-- dummy proto for docs
|
||||
end
|
||||
|
||||
lsp._enabled_configs = {} --- @type table<string,{resolved_config:vim.lsp.Config?}>
|
||||
|
||||
--- If a config in vim.lsp.config() is accessed then the resolved config becomes invalid.
|
||||
--- @param name string
|
||||
local function invalidate_enabled_config(name)
|
||||
if name == '*' then
|
||||
for _, v in pairs(lsp._enabled_configs) do
|
||||
v.resolved_config = nil
|
||||
end
|
||||
elseif lsp._enabled_configs[name] then
|
||||
lsp._enabled_configs[name].resolved_config = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- @nodoc
|
||||
--- @class vim.lsp.config
|
||||
--- @field [string] vim.lsp.Config
|
||||
--- @field package _configs table<string,vim.lsp.Config>
|
||||
lsp.config = setmetatable({ _configs = {} }, {
|
||||
--- @param self vim.lsp.config
|
||||
--- @param name string
|
||||
--- @return vim.lsp.Config
|
||||
__index = function(self, name)
|
||||
validate('name', name, 'string')
|
||||
invalidate_enabled_config(name)
|
||||
self._configs[name] = self._configs[name] or {}
|
||||
return self._configs[name]
|
||||
end,
|
||||
|
||||
--- @param self vim.lsp.config
|
||||
--- @param name string
|
||||
--- @param cfg vim.lsp.Config
|
||||
__newindex = function(self, name, cfg)
|
||||
validate('name', name, 'string')
|
||||
validate('cfg', cfg, 'table')
|
||||
invalidate_enabled_config(name)
|
||||
self._configs[name] = cfg
|
||||
end,
|
||||
|
||||
--- @param self vim.lsp.config
|
||||
--- @param name string
|
||||
--- @param cfg vim.lsp.Config
|
||||
__call = function(self, name, cfg)
|
||||
validate('name', name, 'string')
|
||||
validate('cfg', cfg, 'table')
|
||||
invalidate_enabled_config(name)
|
||||
self[name] = vim.tbl_deep_extend('force', self._configs[name] or {}, cfg)
|
||||
end,
|
||||
})
|
||||
|
||||
--- @private
|
||||
--- @param name string
|
||||
--- @return vim.lsp.Config
|
||||
function lsp._resolve_config(name)
|
||||
local econfig = lsp._enabled_configs[name] or {}
|
||||
|
||||
if not econfig.resolved_config then
|
||||
-- Resolve configs from lsp/*.lua
|
||||
-- Calls to vim.lsp.config in lsp/* have a lower precedence than calls from other sites.
|
||||
local orig_configs = lsp.config._configs
|
||||
lsp.config._configs = {}
|
||||
pcall(vim.cmd.runtime, { ('lsp/%s.lua'):format(name), bang = true })
|
||||
local rtp_configs = lsp.config._configs
|
||||
lsp.config._configs = orig_configs
|
||||
|
||||
local config = vim.tbl_deep_extend(
|
||||
'force',
|
||||
lsp.config._configs['*'] or {},
|
||||
rtp_configs[name] or {},
|
||||
lsp.config._configs[name] or {}
|
||||
)
|
||||
|
||||
config.name = name
|
||||
|
||||
validate('cmd', config.cmd, { 'function', 'table' })
|
||||
validate('cmd', config.reuse_client, 'function', true)
|
||||
-- All other fields are validated in client.create
|
||||
|
||||
econfig.resolved_config = config
|
||||
end
|
||||
|
||||
return assert(econfig.resolved_config)
|
||||
end
|
||||
|
||||
local lsp_enable_autocmd_id --- @type integer?
|
||||
|
||||
--- @param bufnr integer
|
||||
local function lsp_enable_callback(bufnr)
|
||||
-- Only ever attach to buffers that represent an actual file.
|
||||
if vim.bo[bufnr].buftype ~= '' then
|
||||
return
|
||||
end
|
||||
|
||||
--- @param config vim.lsp.Config
|
||||
local function can_start(config)
|
||||
if config.filetypes and not vim.tbl_contains(config.filetypes, vim.bo[bufnr].filetype) then
|
||||
return false
|
||||
elseif type(config.cmd) == 'table' and vim.fn.executable(config.cmd[1]) == 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
for name in vim.spairs(lsp._enabled_configs) do
|
||||
local config = lsp._resolve_config(name)
|
||||
|
||||
if can_start(config) then
|
||||
-- Deepcopy config so changes done in the client
|
||||
-- do not propagate back to the enabled configs.
|
||||
config = vim.deepcopy(config)
|
||||
|
||||
vim.lsp.start(config, {
|
||||
bufnr = bufnr,
|
||||
reuse_client = config.reuse_client,
|
||||
_root_markers = config.root_markers,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Enable an LSP server to automatically start when opening a buffer.
|
||||
---
|
||||
--- Uses configuration defined with `vim.lsp.config`.
|
||||
---
|
||||
--- Examples:
|
||||
---
|
||||
--- ```lua
|
||||
--- vim.lsp.enable('clangd')
|
||||
---
|
||||
--- vim.lsp.enable({'luals', 'pyright'})
|
||||
--- ```
|
||||
---
|
||||
--- @param name string|string[] Name(s) of client(s) to enable.
|
||||
--- @param enable? boolean `true|nil` to enable, `false` to disable.
|
||||
function lsp.enable(name, enable)
|
||||
validate('name', name, { 'string', 'table' })
|
||||
|
||||
local names = vim._ensure_list(name) --[[@as string[] ]]
|
||||
for _, nm in ipairs(names) do
|
||||
if nm == '*' then
|
||||
error('Invalid name')
|
||||
end
|
||||
lsp._enabled_configs[nm] = enable == false and nil or {}
|
||||
end
|
||||
|
||||
if not next(lsp._enabled_configs) then
|
||||
if lsp_enable_autocmd_id then
|
||||
api.nvim_del_autocmd(lsp_enable_autocmd_id)
|
||||
lsp_enable_autocmd_id = nil
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Only ever create autocmd once to reuse computation of config merging.
|
||||
lsp_enable_autocmd_id = lsp_enable_autocmd_id
|
||||
or api.nvim_create_autocmd('FileType', {
|
||||
group = api.nvim_create_augroup('nvim.lsp.enable', {}),
|
||||
callback = function(args)
|
||||
lsp_enable_callback(args.buf)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
--- @class vim.lsp.start.Opts
|
||||
--- @inlinedoc
|
||||
---
|
||||
--- Predicate used to decide if a client should be re-used. Used on all
|
||||
--- running clients. The default implementation re-uses a client if name and
|
||||
--- root_dir matches.
|
||||
--- running clients. The default implementation re-uses a client if it has the
|
||||
--- same name and if the given workspace folders (or root_dir) are all included
|
||||
--- in the client's workspace folders.
|
||||
--- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean
|
||||
---
|
||||
--- Buffer handle to attach to if starting or re-using a client (0 for current).
|
||||
--- @field bufnr? integer
|
||||
---
|
||||
--- Whether to attach the client to a buffer (default true).
|
||||
--- If set to `false`, `reuse_client` and `bufnr` will be ignored.
|
||||
--- @field attach? boolean
|
||||
---
|
||||
--- Suppress error reporting if the LSP server fails to start (default false).
|
||||
--- @field silent? boolean
|
||||
---
|
||||
--- @field package _root_markers? string[]
|
||||
|
||||
--- Create a new LSP client and start a language server or reuses an already
|
||||
--- running client if one is found matching `name` and `root_dir`.
|
||||
@ -237,10 +590,10 @@ end
|
||||
--- })
|
||||
--- ```
|
||||
---
|
||||
--- See |vim.lsp.start_client()| for all available options. The most important are:
|
||||
--- See |vim.lsp.ClientConfig| for all available options. The most important are:
|
||||
---
|
||||
--- - `name` arbitrary name for the LSP client. Should be unique per language server.
|
||||
--- - `cmd` command string[] or function, described at |vim.lsp.start_client()|.
|
||||
--- - `cmd` command string[] or function.
|
||||
--- - `root_dir` path to the project root. By default this is used to decide if an existing client
|
||||
--- should be re-used. The example above uses |vim.fs.root()| to detect the root by traversing
|
||||
--- the file system upwards starting from the current directory until either a `pyproject.toml`
|
||||
@ -260,36 +613,46 @@ end
|
||||
--- `ftplugin/<filetype_name>.lua` (See |ftplugin-name|)
|
||||
---
|
||||
--- @param config vim.lsp.ClientConfig Configuration for the server.
|
||||
--- @param opts vim.lsp.start.Opts? Optional keyword arguments
|
||||
--- @param opts vim.lsp.start.Opts? Optional keyword arguments.
|
||||
--- @return integer? client_id
|
||||
function lsp.start(config, opts)
|
||||
opts = opts or {}
|
||||
local reuse_client = opts.reuse_client or reuse_client_default
|
||||
local bufnr = resolve_bufnr(opts.bufnr)
|
||||
local bufnr = vim._resolve_bufnr(opts.bufnr)
|
||||
|
||||
if not config.root_dir and opts._root_markers then
|
||||
config = vim.deepcopy(config)
|
||||
config.root_dir = vim.fs.root(bufnr, opts._root_markers)
|
||||
end
|
||||
|
||||
for _, client in pairs(all_clients) do
|
||||
if reuse_client(client, config) then
|
||||
if opts.attach == false then
|
||||
return client.id
|
||||
end
|
||||
|
||||
if lsp.buf_attach_client(bufnr, client.id) then
|
||||
return client.id
|
||||
else
|
||||
return nil
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local client_id, err = lsp.start_client(config)
|
||||
local client_id, err = create_and_initialize_client(config)
|
||||
if err then
|
||||
if not opts.silent then
|
||||
vim.notify(err, vim.log.levels.WARN)
|
||||
end
|
||||
return nil
|
||||
return
|
||||
end
|
||||
|
||||
if opts.attach == false then
|
||||
return client_id
|
||||
end
|
||||
|
||||
if client_id and lsp.buf_attach_client(bufnr, client_id) then
|
||||
return client_id
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Consumes the latest progress messages from all clients and formats them as a string.
|
||||
@ -381,78 +744,7 @@ function lsp._set_defaults(client, bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
--- Reset defaults set by `set_defaults`.
|
||||
--- Must only be called if the last client attached to a buffer exits.
|
||||
local function reset_defaults(bufnr)
|
||||
if vim.bo[bufnr].tagfunc == 'v:lua.vim.lsp.tagfunc' then
|
||||
vim.bo[bufnr].tagfunc = nil
|
||||
end
|
||||
if vim.bo[bufnr].omnifunc == 'v:lua.vim.lsp.omnifunc' then
|
||||
vim.bo[bufnr].omnifunc = nil
|
||||
end
|
||||
if vim.bo[bufnr].formatexpr == 'v:lua.vim.lsp.formatexpr()' then
|
||||
vim.bo[bufnr].formatexpr = nil
|
||||
end
|
||||
vim._with({ buf = bufnr }, function()
|
||||
local keymap = vim.fn.maparg('K', 'n', false, true)
|
||||
if keymap and keymap.callback == vim.lsp.buf.hover and keymap.buffer == 1 then
|
||||
vim.keymap.del('n', 'K', { buffer = bufnr })
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- @param code integer
|
||||
--- @param signal integer
|
||||
--- @param client_id integer
|
||||
local function on_client_exit(code, signal, client_id)
|
||||
local client = all_clients[client_id]
|
||||
|
||||
vim.schedule(function()
|
||||
for bufnr in pairs(client.attached_buffers) do
|
||||
if client and client.attached_buffers[bufnr] and api.nvim_buf_is_valid(bufnr) then
|
||||
api.nvim_exec_autocmds('LspDetach', {
|
||||
buffer = bufnr,
|
||||
modeline = false,
|
||||
data = { client_id = client_id },
|
||||
})
|
||||
end
|
||||
|
||||
client.attached_buffers[bufnr] = nil
|
||||
|
||||
if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then
|
||||
reset_defaults(bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
local namespace = vim.lsp.diagnostic.get_namespace(client_id)
|
||||
vim.diagnostic.reset(namespace)
|
||||
end)
|
||||
|
||||
local name = client.name or 'unknown'
|
||||
|
||||
-- Schedule the deletion of the client object so that it exists in the execution of LspDetach
|
||||
-- autocommands
|
||||
vim.schedule(function()
|
||||
all_clients[client_id] = nil
|
||||
|
||||
-- Client can be absent if executable starts, but initialize fails
|
||||
-- init/attach won't have happened
|
||||
if client then
|
||||
changetracking.reset(client)
|
||||
end
|
||||
if code ~= 0 or (signal ~= 0 and signal ~= 15) then
|
||||
local msg = string.format(
|
||||
'Client %s quit with exit code %s and signal %s. Check log for errors: %s',
|
||||
name,
|
||||
code,
|
||||
signal,
|
||||
lsp.get_log_path()
|
||||
)
|
||||
vim.notify(msg, vim.log.levels.WARN)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- @deprecated
|
||||
--- Starts and initializes a client with the given configuration.
|
||||
--- @param config vim.lsp.ClientConfig Configuration for the server.
|
||||
--- @return integer? client_id |vim.lsp.get_client_by_id()| Note: client may not be
|
||||
@ -460,27 +752,14 @@ end
|
||||
--- the client has been initialized.
|
||||
--- @return string? # Error message, if any
|
||||
function lsp.start_client(config)
|
||||
local ok, res = pcall(require('vim.lsp.client').create, config)
|
||||
if not ok then
|
||||
return nil, res --[[@as string]]
|
||||
end
|
||||
|
||||
local client = assert(res)
|
||||
|
||||
--- @diagnostic disable-next-line: invisible
|
||||
table.insert(client._on_exit_cbs, on_client_exit)
|
||||
|
||||
all_clients[client.id] = client
|
||||
|
||||
client:initialize()
|
||||
|
||||
return client.id, nil
|
||||
vim.deprecate('vim.lsp.start_client()', 'vim.lsp.start()', '0.13')
|
||||
return create_and_initialize_client(config)
|
||||
end
|
||||
|
||||
---Buffer lifecycle handler for textDocument/didSave
|
||||
--- @param bufnr integer
|
||||
local function text_document_did_save_handler(bufnr)
|
||||
bufnr = resolve_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
local uri = vim.uri_from_bufnr(bufnr)
|
||||
local text = once(lsp._buf_get_full_text)
|
||||
for _, client in ipairs(lsp.get_clients({ bufnr = bufnr })) do
|
||||
@ -641,7 +920,7 @@ end
|
||||
function lsp.buf_attach_client(bufnr, client_id)
|
||||
validate('bufnr', bufnr, 'number', true)
|
||||
validate('client_id', client_id, 'number')
|
||||
bufnr = resolve_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
if not api.nvim_buf_is_loaded(bufnr) then
|
||||
log.warn(string.format('buf_attach_client called on unloaded buffer (id: %d): ', bufnr))
|
||||
return false
|
||||
@ -678,7 +957,7 @@ end
|
||||
function lsp.buf_detach_client(bufnr, client_id)
|
||||
validate('bufnr', bufnr, 'number', true)
|
||||
validate('client_id', client_id, 'number')
|
||||
bufnr = resolve_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
local client = all_clients[client_id]
|
||||
if not client or not client.attached_buffers[bufnr] then
|
||||
@ -784,7 +1063,7 @@ function lsp.get_clients(filter)
|
||||
|
||||
local clients = {} --- @type vim.lsp.Client[]
|
||||
|
||||
local bufnr = filter.bufnr and resolve_bufnr(filter.bufnr)
|
||||
local bufnr = filter.bufnr and vim._resolve_bufnr(filter.bufnr)
|
||||
|
||||
for _, client in pairs(all_clients) do
|
||||
if
|
||||
@ -880,7 +1159,7 @@ function lsp.buf_request(bufnr, method, params, handler, on_unsupported)
|
||||
validate('handler', handler, 'function', true)
|
||||
validate('on_unsupported', on_unsupported, 'function', true)
|
||||
|
||||
bufnr = resolve_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
local method_supported = false
|
||||
local clients = lsp.get_clients({ bufnr = bufnr })
|
||||
local client_request_ids = {} --- @type table<integer,integer>
|
||||
@ -1094,6 +1373,54 @@ function lsp.tagfunc(pattern, flags)
|
||||
return vim.lsp._tagfunc(pattern, flags)
|
||||
end
|
||||
|
||||
--- Provides an interface between the built-in client and a `foldexpr` function.
|
||||
---
|
||||
--- To use, check for the "textDocument/foldingRange" capability in an
|
||||
--- |LspAttach| autocommand. Example:
|
||||
---
|
||||
--- ```lua
|
||||
--- vim.api.nvim_create_autocommand('LspAttach', {
|
||||
--- callback = function(args)
|
||||
--- local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||
--- if client:supports_method('textDocument/foldingRange') then
|
||||
--- vim.wo.foldmethod = 'expr'
|
||||
--- vim.wo.foldexpr = 'v:lua.vim.lsp.foldexpr()'
|
||||
--- end
|
||||
--- end,
|
||||
--- })
|
||||
--- ```
|
||||
---
|
||||
---@param lnum integer line number
|
||||
function lsp.foldexpr(lnum)
|
||||
return vim.lsp._folding_range.foldexpr(lnum)
|
||||
end
|
||||
|
||||
--- Close all {kind} of folds in the the window with {winid}.
|
||||
---
|
||||
--- To automatically fold imports when opening a file, you can use an autocmd:
|
||||
---
|
||||
--- ```lua
|
||||
--- vim.api.nvim_create_autocmd('LspNotify', {
|
||||
--- callback = function(args)
|
||||
--- if args.data.method == 'textDocument/didOpen' then
|
||||
--- vim.lsp.foldclose('imports', vim.fn.bufwinid(args.buf))
|
||||
--- end
|
||||
--- end,
|
||||
--- })
|
||||
--- ```
|
||||
---
|
||||
---@param kind lsp.FoldingRangeKind Kind to close, one of "comment", "imports" or "region".
|
||||
---@param winid? integer Defaults to the current window.
|
||||
function lsp.foldclose(kind, winid)
|
||||
return vim.lsp._folding_range.foldclose(kind, winid)
|
||||
end
|
||||
|
||||
--- Provides a `foldtext` function that shows the `collapsedText` retrieved,
|
||||
--- defaults to the first folded line if `collapsedText` is not provided.
|
||||
function lsp.foldtext()
|
||||
return vim.lsp._folding_range.foldtext()
|
||||
end
|
||||
|
||||
---Checks whether a client is stopped.
|
||||
---
|
||||
---@param client_id (integer)
|
||||
@ -1112,7 +1439,7 @@ end
|
||||
function lsp.buf_get_clients(bufnr)
|
||||
vim.deprecate('vim.lsp.buf_get_clients()', 'vim.lsp.get_clients()', '0.12')
|
||||
local result = {} --- @type table<integer,vim.lsp.Client>
|
||||
for _, client in ipairs(lsp.get_clients({ bufnr = resolve_bufnr(bufnr) })) do
|
||||
for _, client in ipairs(lsp.get_clients({ bufnr = vim._resolve_bufnr(bufnr) })) do
|
||||
result[client.id] = client
|
||||
end
|
||||
return result
|
||||
@ -1166,7 +1493,7 @@ function lsp.for_each_buffer_client(bufnr, fn)
|
||||
'lsp.get_clients({ bufnr = bufnr }) with regular loop',
|
||||
'0.12'
|
||||
)
|
||||
bufnr = resolve_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
for _, client in pairs(lsp.get_clients({ bufnr = bufnr })) do
|
||||
fn(client, client.id, bufnr)
|
||||
@ -1183,44 +1510,6 @@ function lsp.with(handler, override_config)
|
||||
end
|
||||
end
|
||||
|
||||
--- Helper function to use when implementing a handler.
|
||||
--- This will check that all of the keys in the user configuration
|
||||
--- are valid keys and make sense to include for this handler.
|
||||
---
|
||||
--- Will error on invalid keys (i.e. keys that do not exist in the options)
|
||||
--- @param name string
|
||||
--- @param options table<string,any>
|
||||
--- @param user_config table<string,any>
|
||||
function lsp._with_extend(name, options, user_config)
|
||||
user_config = user_config or {}
|
||||
|
||||
local resulting_config = {} --- @type table<string,any>
|
||||
for k, v in pairs(user_config) do
|
||||
if options[k] == nil then
|
||||
error(
|
||||
debug.traceback(
|
||||
string.format(
|
||||
'Invalid option for `%s`: %s. Valid options are:\n%s',
|
||||
name,
|
||||
k,
|
||||
vim.inspect(vim.tbl_keys(options))
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
resulting_config[k] = v
|
||||
end
|
||||
|
||||
for k, v in pairs(options) do
|
||||
if resulting_config[k] == nil then
|
||||
resulting_config[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
return resulting_config
|
||||
end
|
||||
|
||||
--- Registry for client side commands.
|
||||
--- This is an extension point for plugins to handle custom commands which are
|
||||
--- not part of the core language server protocol specification.
|
||||
@ -1229,7 +1518,7 @@ end
|
||||
--- and the value is a function which is called if any LSP action
|
||||
--- (code action, code lenses, ...) triggers the command.
|
||||
---
|
||||
--- If a LSP response contains a command for which no matching entry is
|
||||
--- If an LSP response contains a command for which no matching entry is
|
||||
--- available in this registry, the command will be executed via the LSP server
|
||||
--- using `workspace/executeCommand`.
|
||||
---
|
||||
|
@ -18,14 +18,14 @@ local M = {}
|
||||
---
|
||||
--- None: One group for all clients
|
||||
--- Full: One group for all clients
|
||||
--- Incremental: One group per `offset_encoding`
|
||||
--- Incremental: One group per `position_encoding`
|
||||
---
|
||||
--- Sending changes can be debounced per buffer. To simplify the implementation the
|
||||
--- smallest debounce interval is used and we don't group clients by different intervals.
|
||||
---
|
||||
--- @class vim.lsp.CTGroup
|
||||
--- @field sync_kind integer TextDocumentSyncKind, considers config.flags.allow_incremental_sync
|
||||
--- @field offset_encoding "utf-8"|"utf-16"|"utf-32"
|
||||
--- @field position_encoding "utf-8"|"utf-16"|"utf-32"
|
||||
---
|
||||
--- @class vim.lsp.CTBufferState
|
||||
--- @field name string name of the buffer
|
||||
@ -46,7 +46,7 @@ local M = {}
|
||||
---@return string
|
||||
local function group_key(group)
|
||||
if group.sync_kind == protocol.TextDocumentSyncKind.Incremental then
|
||||
return tostring(group.sync_kind) .. '\0' .. group.offset_encoding
|
||||
return tostring(group.sync_kind) .. '\0' .. group.position_encoding
|
||||
end
|
||||
return tostring(group.sync_kind)
|
||||
end
|
||||
@ -72,7 +72,7 @@ local function get_group(client)
|
||||
end
|
||||
return {
|
||||
sync_kind = sync_kind,
|
||||
offset_encoding = client.offset_encoding,
|
||||
position_encoding = client.offset_encoding,
|
||||
}
|
||||
end
|
||||
|
||||
@ -310,7 +310,7 @@ local function send_changes_for_group(bufnr, firstline, lastline, new_lastline,
|
||||
-- The contents would further change and startline/endline may no longer fit
|
||||
local changes = incremental_changes(
|
||||
buf_state,
|
||||
group.offset_encoding,
|
||||
group.position_encoding,
|
||||
bufnr,
|
||||
firstline,
|
||||
lastline,
|
||||
|
373
runtime/lua/vim/lsp/_folding_range.lua
Normal file
373
runtime/lua/vim/lsp/_folding_range.lua
Normal file
@ -0,0 +1,373 @@
|
||||
local util = require('vim.lsp.util')
|
||||
local log = require('vim.lsp.log')
|
||||
local ms = require('vim.lsp.protocol').Methods
|
||||
local api = vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
---@class (private) vim.lsp.folding_range.BufState
|
||||
---
|
||||
---@field version? integer
|
||||
---
|
||||
--- Never use this directly, `renew()` the cached foldinfo
|
||||
--- then use on demand via `row_*` fields.
|
||||
---
|
||||
--- Index In the form of client_id -> ranges
|
||||
---@field client_ranges table<integer, lsp.FoldingRange[]?>
|
||||
---
|
||||
--- Index in the form of row -> [foldlevel, mark]
|
||||
---@field row_level table<integer, [integer, ">" | "<"?]?>
|
||||
---
|
||||
--- Index in the form of start_row -> kinds
|
||||
---@field row_kinds table<integer, table<lsp.FoldingRangeKind, true?>?>>
|
||||
---
|
||||
--- Index in the form of start_row -> collapsed_text
|
||||
---@field row_text table<integer, string?>
|
||||
|
||||
---@type table<integer, vim.lsp.folding_range.BufState?>
|
||||
local bufstates = {}
|
||||
|
||||
--- Renew the cached foldinfo in the buffer.
|
||||
---@param bufnr integer
|
||||
local function renew(bufnr)
|
||||
local bufstate = assert(bufstates[bufnr])
|
||||
|
||||
---@type table<integer, [integer, ">" | "<"?]?>
|
||||
local row_level = {}
|
||||
---@type table<integer, table<lsp.FoldingRangeKind, true?>?>>
|
||||
local row_kinds = {}
|
||||
---@type table<integer, string?>
|
||||
local row_text = {}
|
||||
|
||||
for _, ranges in pairs(bufstate.client_ranges) do
|
||||
for _, range in ipairs(ranges) do
|
||||
local start_row = range.startLine
|
||||
local end_row = range.endLine
|
||||
-- Adding folds within a single line is not supported by Nvim.
|
||||
if start_row ~= end_row then
|
||||
row_text[start_row] = range.collapsedText
|
||||
|
||||
local kind = range.kind
|
||||
if kind then
|
||||
local kinds = row_kinds[start_row] or {}
|
||||
kinds[kind] = true
|
||||
row_kinds[start_row] = kinds
|
||||
end
|
||||
|
||||
for row = start_row, end_row do
|
||||
local level = row_level[row] or { 0 }
|
||||
level[1] = level[1] + 1
|
||||
row_level[row] = level
|
||||
end
|
||||
row_level[start_row][2] = '>'
|
||||
row_level[end_row][2] = '<'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
bufstate.row_level = row_level
|
||||
bufstate.row_kinds = row_kinds
|
||||
bufstate.row_text = row_text
|
||||
end
|
||||
|
||||
--- Renew the cached foldinfo then force `foldexpr()` to be re-evaluated,
|
||||
--- without opening folds.
|
||||
---@param bufnr integer
|
||||
local function foldupdate(bufnr)
|
||||
renew(bufnr)
|
||||
for _, winid in ipairs(vim.fn.win_findbuf(bufnr)) do
|
||||
local wininfo = vim.fn.getwininfo(winid)[1]
|
||||
if wininfo and wininfo.tabnr == vim.fn.tabpagenr() then
|
||||
if vim.wo[winid].foldmethod == 'expr' then
|
||||
vim._foldupdate(winid, 0, api.nvim_buf_line_count(bufnr))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Whether `foldupdate()` is scheduled for the buffer with `bufnr`.
|
||||
---
|
||||
--- Index in the form of bufnr -> true?
|
||||
---@type table<integer, true?>
|
||||
local scheduled_foldupdate = {}
|
||||
|
||||
--- Schedule `foldupdate()` after leaving insert mode.
|
||||
---@param bufnr integer
|
||||
local function schedule_foldupdate(bufnr)
|
||||
if not scheduled_foldupdate[bufnr] then
|
||||
scheduled_foldupdate[bufnr] = true
|
||||
api.nvim_create_autocmd('InsertLeave', {
|
||||
buffer = bufnr,
|
||||
once = true,
|
||||
callback = function()
|
||||
foldupdate(bufnr)
|
||||
scheduled_foldupdate[bufnr] = nil
|
||||
end,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
---@param results table<integer,{err: lsp.ResponseError?, result: lsp.FoldingRange[]?}>
|
||||
---@type lsp.MultiHandler
|
||||
local function multi_handler(results, ctx)
|
||||
local bufnr = assert(ctx.bufnr)
|
||||
-- Handling responses from outdated buffer only causes performance overhead.
|
||||
if util.buf_versions[bufnr] ~= ctx.version then
|
||||
return
|
||||
end
|
||||
|
||||
local bufstate = assert(bufstates[bufnr])
|
||||
for client_id, result in pairs(results) do
|
||||
if result.err then
|
||||
log.error(result.err)
|
||||
else
|
||||
bufstate.client_ranges[client_id] = result.result
|
||||
end
|
||||
end
|
||||
bufstate.version = ctx.version
|
||||
|
||||
if api.nvim_get_mode().mode:match('^i') then
|
||||
-- `foldUpdate()` is guarded in insert mode.
|
||||
schedule_foldupdate(bufnr)
|
||||
else
|
||||
foldupdate(bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
---@param result lsp.FoldingRange[]?
|
||||
---@type lsp.Handler
|
||||
local function handler(err, result, ctx)
|
||||
multi_handler({ [ctx.client_id] = { err = err, result = result } }, ctx)
|
||||
end
|
||||
|
||||
--- Request `textDocument/foldingRange` from the server.
|
||||
--- `foldupdate()` is scheduled once after the request is completed.
|
||||
---@param bufnr integer
|
||||
---@param client? vim.lsp.Client The client whose server supports `foldingRange`.
|
||||
local function request(bufnr, client)
|
||||
---@type lsp.FoldingRangeParams
|
||||
local params = { textDocument = util.make_text_document_params(bufnr) }
|
||||
|
||||
if client then
|
||||
client:request(ms.textDocument_foldingRange, params, handler, bufnr)
|
||||
return
|
||||
end
|
||||
|
||||
if not next(vim.lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_foldingRange })) then
|
||||
return
|
||||
end
|
||||
|
||||
vim.lsp.buf_request_all(bufnr, ms.textDocument_foldingRange, params, multi_handler)
|
||||
end
|
||||
|
||||
-- NOTE:
|
||||
-- `bufstate` and event hooks are interdependent:
|
||||
-- * `bufstate` needs event hooks for correctness.
|
||||
-- * event hooks require the previous `bufstate` for updates.
|
||||
-- Since they are manually created and destroyed,
|
||||
-- we ensure their lifecycles are always synchronized.
|
||||
--
|
||||
-- TODO(ofseed):
|
||||
-- 1. Implement clearing `bufstate` and event hooks
|
||||
-- when no clients in the buffer support the corresponding method.
|
||||
-- 2. Then generalize this state management to other LSP modules.
|
||||
local augroup_setup = api.nvim_create_augroup('vim_lsp_folding_range/setup', {})
|
||||
|
||||
--- Initialize `bufstate` and event hooks, then request folding ranges.
|
||||
--- Manage their lifecycle within this function.
|
||||
---@param bufnr integer
|
||||
---@return vim.lsp.folding_range.BufState?
|
||||
local function setup(bufnr)
|
||||
if not api.nvim_buf_is_loaded(bufnr) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Register the new `bufstate`.
|
||||
bufstates[bufnr] = {
|
||||
client_ranges = {},
|
||||
row_level = {},
|
||||
row_kinds = {},
|
||||
row_text = {},
|
||||
}
|
||||
|
||||
-- Event hooks from `buf_attach` can't be removed externally.
|
||||
-- Hooks and `bufstate` share the same lifecycle;
|
||||
-- they should self-destroy if `bufstate == nil`.
|
||||
api.nvim_buf_attach(bufnr, false, {
|
||||
-- `on_detach` also runs on buffer reload (`:e`).
|
||||
-- Ensure `bufstate` and hooks are cleared to avoid duplication or leftover states.
|
||||
on_detach = function()
|
||||
bufstates[bufnr] = nil
|
||||
api.nvim_clear_autocmds({ buffer = bufnr, group = augroup_setup })
|
||||
end,
|
||||
-- Reset `bufstate` and request folding ranges.
|
||||
on_reload = function()
|
||||
bufstates[bufnr] = {
|
||||
client_ranges = {},
|
||||
row_level = {},
|
||||
row_kinds = {},
|
||||
row_text = {},
|
||||
}
|
||||
request(bufnr)
|
||||
end,
|
||||
--- Sync changed rows with their previous foldlevels before applying new ones.
|
||||
on_bytes = function(_, _, _, start_row, _, _, old_row, _, _, new_row, _, _)
|
||||
if bufstates[bufnr] == nil then
|
||||
return true
|
||||
end
|
||||
local row_level = bufstates[bufnr].row_level
|
||||
if next(row_level) == nil then
|
||||
return
|
||||
end
|
||||
local row = new_row - old_row
|
||||
if row > 0 then
|
||||
vim._list_insert(row_level, start_row, start_row + math.abs(row) - 1, { -1 })
|
||||
-- If the previous row ends a fold,
|
||||
-- Nvim treats the first row after consecutive `-1`s as a new fold start,
|
||||
-- which is not the desired behavior.
|
||||
local prev_level = row_level[start_row - 1]
|
||||
if prev_level and prev_level[2] == '<' then
|
||||
row_level[start_row] = { prev_level[1] - 1 }
|
||||
end
|
||||
elseif row < 0 then
|
||||
vim._list_remove(row_level, start_row, start_row + math.abs(row) - 1)
|
||||
end
|
||||
end,
|
||||
})
|
||||
api.nvim_create_autocmd('LspDetach', {
|
||||
group = augroup_setup,
|
||||
buffer = bufnr,
|
||||
callback = function(args)
|
||||
if not api.nvim_buf_is_loaded(bufnr) then
|
||||
return
|
||||
end
|
||||
|
||||
---@type integer
|
||||
local client_id = args.data.client_id
|
||||
bufstates[bufnr].client_ranges[client_id] = nil
|
||||
|
||||
---@type vim.lsp.Client[]
|
||||
local clients = vim
|
||||
.iter(vim.lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_foldingRange }))
|
||||
---@param client vim.lsp.Client
|
||||
:filter(function(client)
|
||||
return client.id ~= client_id
|
||||
end)
|
||||
:totable()
|
||||
if #clients == 0 then
|
||||
bufstates[bufnr] = {
|
||||
client_ranges = {},
|
||||
row_level = {},
|
||||
row_kinds = {},
|
||||
row_text = {},
|
||||
}
|
||||
end
|
||||
|
||||
foldupdate(bufnr)
|
||||
end,
|
||||
})
|
||||
api.nvim_create_autocmd('LspAttach', {
|
||||
group = augroup_setup,
|
||||
buffer = bufnr,
|
||||
callback = function(args)
|
||||
local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
|
||||
if client:supports_method(vim.lsp.protocol.Methods.textDocument_foldingRange, bufnr) then
|
||||
request(bufnr, client)
|
||||
end
|
||||
end,
|
||||
})
|
||||
api.nvim_create_autocmd('LspNotify', {
|
||||
group = augroup_setup,
|
||||
buffer = bufnr,
|
||||
callback = function(args)
|
||||
local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
|
||||
if
|
||||
client:supports_method(ms.textDocument_foldingRange, bufnr)
|
||||
and (
|
||||
args.data.method == ms.textDocument_didChange
|
||||
or args.data.method == ms.textDocument_didOpen
|
||||
)
|
||||
then
|
||||
request(bufnr, client)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
request(bufnr)
|
||||
|
||||
return bufstates[bufnr]
|
||||
end
|
||||
|
||||
---@param kind lsp.FoldingRangeKind
|
||||
---@param winid integer
|
||||
local function foldclose(kind, winid)
|
||||
vim._with({ win = winid }, function()
|
||||
local bufnr = api.nvim_win_get_buf(winid)
|
||||
local row_kinds = bufstates[bufnr].row_kinds
|
||||
-- Reverse traverse to ensure that the smallest ranges are closed first.
|
||||
for row = api.nvim_buf_line_count(bufnr) - 1, 0, -1 do
|
||||
local kinds = row_kinds[row]
|
||||
if kinds and kinds[kind] then
|
||||
vim.cmd(row + 1 .. 'foldclose')
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
---@param kind lsp.FoldingRangeKind
|
||||
---@param winid? integer
|
||||
function M.foldclose(kind, winid)
|
||||
vim.validate('kind', kind, 'string')
|
||||
vim.validate('winid', winid, 'number', true)
|
||||
|
||||
winid = winid or api.nvim_get_current_win()
|
||||
local bufnr = api.nvim_win_get_buf(winid)
|
||||
local bufstate = bufstates[bufnr]
|
||||
if not bufstate then
|
||||
return
|
||||
end
|
||||
|
||||
if bufstate.version == util.buf_versions[bufnr] then
|
||||
foldclose(kind, winid)
|
||||
return
|
||||
end
|
||||
-- Schedule `foldclose()` if the buffer is not up-to-date.
|
||||
|
||||
if not next(vim.lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_foldingRange })) then
|
||||
return
|
||||
end
|
||||
---@type lsp.FoldingRangeParams
|
||||
local params = { textDocument = util.make_text_document_params(bufnr) }
|
||||
vim.lsp.buf_request_all(bufnr, ms.textDocument_foldingRange, params, function(...)
|
||||
multi_handler(...)
|
||||
foldclose(kind, winid)
|
||||
end)
|
||||
end
|
||||
|
||||
---@return string
|
||||
function M.foldtext()
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
local lnum = vim.v.foldstart
|
||||
local row = lnum - 1
|
||||
local bufstate = bufstates[bufnr]
|
||||
if bufstate and bufstate.row_text[row] then
|
||||
return bufstate.row_text[row]
|
||||
end
|
||||
return vim.fn.getline(lnum)
|
||||
end
|
||||
|
||||
---@param lnum? integer
|
||||
---@return string level
|
||||
function M.foldexpr(lnum)
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
local bufstate = bufstates[bufnr] or setup(bufnr)
|
||||
if not bufstate then
|
||||
return '0'
|
||||
end
|
||||
|
||||
local row = (lnum or vim.v.lnum) - 1
|
||||
local level = bufstate.row_level[row]
|
||||
return level and (level[2] or '') .. (level[1] or '0') or '0'
|
||||
end
|
||||
|
||||
return M
|
@ -6,12 +6,12 @@ local ms = lsp.protocol.Methods
|
||||
---@param name string
|
||||
---@param range lsp.Range
|
||||
---@param uri string
|
||||
---@param offset_encoding string
|
||||
---@param position_encoding string
|
||||
---@return {name: string, filename: string, cmd: string, kind?: string}
|
||||
local function mk_tag_item(name, range, uri, offset_encoding)
|
||||
local function mk_tag_item(name, range, uri, position_encoding)
|
||||
local bufnr = vim.uri_to_bufnr(uri)
|
||||
-- This is get_line_byte_from_position is 0-indexed, call cursor expects a 1-indexed position
|
||||
local byte = util._get_line_byte_from_position(bufnr, range.start, offset_encoding) + 1
|
||||
local byte = util._get_line_byte_from_position(bufnr, range.start, position_encoding) + 1
|
||||
return {
|
||||
name = name,
|
||||
filename = vim.uri_to_fname(uri),
|
||||
@ -32,9 +32,9 @@ local function query_definition(pattern)
|
||||
|
||||
--- @param range lsp.Range
|
||||
--- @param uri string
|
||||
--- @param offset_encoding string
|
||||
local add = function(range, uri, offset_encoding)
|
||||
table.insert(results, mk_tag_item(pattern, range, uri, offset_encoding))
|
||||
--- @param position_encoding string
|
||||
local add = function(range, uri, position_encoding)
|
||||
table.insert(results, mk_tag_item(pattern, range, uri, position_encoding))
|
||||
end
|
||||
|
||||
local remaining = #clients
|
||||
@ -78,11 +78,11 @@ local function query_workspace_symbols(pattern)
|
||||
local results = {}
|
||||
for client_id, responses in pairs(assert(results_by_client)) do
|
||||
local client = lsp.get_client_by_id(client_id)
|
||||
local offset_encoding = client and client.offset_encoding or 'utf-16'
|
||||
local position_encoding = client and client.offset_encoding or 'utf-16'
|
||||
local symbols = responses.result --[[@as lsp.SymbolInformation[]|nil]]
|
||||
for _, symbol in pairs(symbols or {}) do
|
||||
local loc = symbol.location
|
||||
local item = mk_tag_item(symbol.name, loc.range, loc.uri, offset_encoding)
|
||||
local item = mk_tag_item(symbol.name, loc.range, loc.uri, position_encoding)
|
||||
item.kind = lsp.protocol.SymbolKind[symbol.kind] or 'Unknown'
|
||||
table.insert(results, item)
|
||||
end
|
||||
|
182
runtime/lua/vim/lsp/_transport.lua
Normal file
182
runtime/lua/vim/lsp/_transport.lua
Normal file
@ -0,0 +1,182 @@
|
||||
local uv = vim.uv
|
||||
local log = require('vim.lsp.log')
|
||||
|
||||
local is_win = vim.fn.has('win32') == 1
|
||||
|
||||
--- Checks whether a given path exists and is a directory.
|
||||
---@param filename string path to check
|
||||
---@return boolean
|
||||
local function is_dir(filename)
|
||||
local stat = uv.fs_stat(filename)
|
||||
return stat and stat.type == 'directory' or false
|
||||
end
|
||||
|
||||
--- @class (private) vim.lsp.rpc.Transport
|
||||
--- @field write fun(self: vim.lsp.rpc.Transport, msg: string)
|
||||
--- @field is_closing fun(self: vim.lsp.rpc.Transport): boolean
|
||||
--- @field terminate fun(self: vim.lsp.rpc.Transport)
|
||||
|
||||
--- @class (private,exact) vim.lsp.rpc.Transport.Run : vim.lsp.rpc.Transport
|
||||
--- @field new fun(): vim.lsp.rpc.Transport.Run
|
||||
--- @field sysobj? vim.SystemObj
|
||||
local TransportRun = {}
|
||||
|
||||
--- @return vim.lsp.rpc.Transport.Run
|
||||
function TransportRun.new()
|
||||
return setmetatable({}, { __index = TransportRun })
|
||||
end
|
||||
|
||||
--- @param cmd string[] Command to start the LSP server.
|
||||
--- @param extra_spawn_params? vim.lsp.rpc.ExtraSpawnParams
|
||||
--- @param on_read fun(err: any, data: string)
|
||||
--- @param on_exit fun(code: integer, signal: integer)
|
||||
function TransportRun:run(cmd, extra_spawn_params, on_read, on_exit)
|
||||
local function on_stderr(_, chunk)
|
||||
if chunk then
|
||||
log.error('rpc', cmd[1], 'stderr', chunk)
|
||||
end
|
||||
end
|
||||
|
||||
extra_spawn_params = extra_spawn_params or {}
|
||||
|
||||
if extra_spawn_params.cwd then
|
||||
assert(is_dir(extra_spawn_params.cwd), 'cwd must be a directory')
|
||||
end
|
||||
|
||||
local detached = not is_win
|
||||
if extra_spawn_params.detached ~= nil then
|
||||
detached = extra_spawn_params.detached
|
||||
end
|
||||
|
||||
local ok, sysobj_or_err = pcall(vim.system, cmd, {
|
||||
stdin = true,
|
||||
stdout = on_read,
|
||||
stderr = on_stderr,
|
||||
cwd = extra_spawn_params.cwd,
|
||||
env = extra_spawn_params.env,
|
||||
detach = detached,
|
||||
}, function(obj)
|
||||
on_exit(obj.code, obj.signal)
|
||||
end)
|
||||
|
||||
if not ok then
|
||||
local err = sysobj_or_err --[[@as string]]
|
||||
local sfx = err:match('ENOENT')
|
||||
and '. The language server is either not installed, missing from PATH, or not executable.'
|
||||
or string.format(' with error message: %s', err)
|
||||
|
||||
error(('Spawning language server with cmd: `%s` failed%s'):format(vim.inspect(cmd), sfx))
|
||||
end
|
||||
|
||||
self.sysobj = sysobj_or_err --[[@as vim.SystemObj]]
|
||||
end
|
||||
|
||||
function TransportRun:write(msg)
|
||||
assert(self.sysobj):write(msg)
|
||||
end
|
||||
|
||||
function TransportRun:is_closing()
|
||||
return self.sysobj == nil or self.sysobj:is_closing()
|
||||
end
|
||||
|
||||
function TransportRun:terminate()
|
||||
assert(self.sysobj):kill(15)
|
||||
end
|
||||
|
||||
--- @class (private,exact) vim.lsp.rpc.Transport.Connect : vim.lsp.rpc.Transport
|
||||
--- @field new fun(): vim.lsp.rpc.Transport.Connect
|
||||
--- @field handle? uv.uv_pipe_t|uv.uv_tcp_t
|
||||
--- Connect returns a PublicClient synchronously so the caller
|
||||
--- can immediately send messages before the connection is established
|
||||
--- -> Need to buffer them until that happens
|
||||
--- @field connected boolean
|
||||
--- @field closing boolean
|
||||
--- @field msgbuf vim.Ringbuf
|
||||
--- @field on_exit? fun(code: integer, signal: integer)
|
||||
local TransportConnect = {}
|
||||
|
||||
--- @return vim.lsp.rpc.Transport.Connect
|
||||
function TransportConnect.new()
|
||||
return setmetatable({
|
||||
connected = false,
|
||||
-- size should be enough because the client can't really do anything until initialization is done
|
||||
-- which required a response from the server - implying the connection got established
|
||||
msgbuf = vim.ringbuf(10),
|
||||
closing = false,
|
||||
}, { __index = TransportConnect })
|
||||
end
|
||||
|
||||
--- @param host_or_path string
|
||||
--- @param port? integer
|
||||
--- @param on_read fun(err: any, data: string)
|
||||
--- @param on_exit? fun(code: integer, signal: integer)
|
||||
function TransportConnect:connect(host_or_path, port, on_read, on_exit)
|
||||
self.on_exit = on_exit
|
||||
self.handle = (
|
||||
port and assert(uv.new_tcp(), 'Could not create new TCP socket')
|
||||
or assert(uv.new_pipe(false), 'Pipe could not be opened.')
|
||||
)
|
||||
|
||||
local function on_connect(err)
|
||||
if err then
|
||||
local address = not port and host_or_path or (host_or_path .. ':' .. port)
|
||||
vim.schedule(function()
|
||||
vim.notify(
|
||||
string.format('Could not connect to %s, reason: %s', address, vim.inspect(err)),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
end)
|
||||
return
|
||||
end
|
||||
self.handle:read_start(on_read)
|
||||
self.connected = true
|
||||
for msg in self.msgbuf do
|
||||
self.handle:write(msg)
|
||||
end
|
||||
end
|
||||
|
||||
if not port then
|
||||
self.handle:connect(host_or_path, on_connect)
|
||||
return
|
||||
end
|
||||
|
||||
--- @diagnostic disable-next-line:param-type-mismatch bad UV typing
|
||||
local info = uv.getaddrinfo(host_or_path, nil)
|
||||
local resolved_host = info and info[1] and info[1].addr or host_or_path
|
||||
self.handle:connect(resolved_host, port, on_connect)
|
||||
end
|
||||
|
||||
function TransportConnect:write(msg)
|
||||
if self.connected then
|
||||
local _, err = self.handle:write(msg)
|
||||
if err and not self.closing then
|
||||
log.error('Error on handle:write: %q', err)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
self.msgbuf:push(msg)
|
||||
end
|
||||
|
||||
function TransportConnect:is_closing()
|
||||
return self.closing
|
||||
end
|
||||
|
||||
function TransportConnect:terminate()
|
||||
if self.closing then
|
||||
return
|
||||
end
|
||||
self.closing = true
|
||||
if self.handle then
|
||||
self.handle:shutdown()
|
||||
self.handle:close()
|
||||
end
|
||||
if self.on_exit then
|
||||
self.on_exit(0, 0)
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
TransportRun = TransportRun,
|
||||
TransportConnect = TransportConnect,
|
||||
}
|
@ -487,7 +487,7 @@ end
|
||||
--- ```lua
|
||||
--- -- Never request typescript-language-server for formatting
|
||||
--- vim.lsp.buf.format {
|
||||
--- filter = function(client) return client.name ~= "tsserver" end
|
||||
--- filter = function(client) return client.name ~= "ts_ls" end
|
||||
--- }
|
||||
--- ```
|
||||
--- @field filter? fun(client: vim.lsp.Client): boolean?
|
||||
@ -519,7 +519,7 @@ end
|
||||
--- @param opts? vim.lsp.buf.format.Opts
|
||||
function M.format(opts)
|
||||
opts = opts or {}
|
||||
local bufnr = opts.bufnr or api.nvim_get_current_buf()
|
||||
local bufnr = vim._resolve_bufnr(opts.bufnr)
|
||||
local mode = api.nvim_get_mode().mode
|
||||
local range = opts.range
|
||||
-- Try to use visual selection if no range is given
|
||||
@ -617,7 +617,7 @@ end
|
||||
---@param opts? vim.lsp.buf.rename.Opts Additional options:
|
||||
function M.rename(new_name, opts)
|
||||
opts = opts or {}
|
||||
local bufnr = opts.bufnr or api.nvim_get_current_buf()
|
||||
local bufnr = vim._resolve_bufnr(opts.bufnr)
|
||||
local clients = lsp.get_clients({
|
||||
bufnr = bufnr,
|
||||
name = opts.name,
|
||||
@ -638,14 +638,14 @@ function M.rename(new_name, opts)
|
||||
local cword = vim.fn.expand('<cword>')
|
||||
|
||||
--- @param range lsp.Range
|
||||
--- @param offset_encoding string
|
||||
local function get_text_at_range(range, offset_encoding)
|
||||
--- @param position_encoding string
|
||||
local function get_text_at_range(range, position_encoding)
|
||||
return api.nvim_buf_get_text(
|
||||
bufnr,
|
||||
range.start.line,
|
||||
util._get_line_byte_from_position(bufnr, range.start, offset_encoding),
|
||||
util._get_line_byte_from_position(bufnr, range.start, position_encoding),
|
||||
range['end'].line,
|
||||
util._get_line_byte_from_position(bufnr, range['end'], offset_encoding),
|
||||
util._get_line_byte_from_position(bufnr, range['end'], position_encoding),
|
||||
{}
|
||||
)[1]
|
||||
end
|
||||
@ -736,7 +736,7 @@ end
|
||||
|
||||
--- Lists all the references to the symbol under the cursor in the quickfix window.
|
||||
---
|
||||
---@param context (table|nil) Context for the request
|
||||
---@param context lsp.ReferenceContext? Context for the request
|
||||
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
|
||||
---@param opts? vim.lsp.ListOpts
|
||||
function M.references(context, opts)
|
||||
|
@ -75,17 +75,17 @@ local validate = vim.validate
|
||||
---
|
||||
--- Map with language server specific settings.
|
||||
--- See the {settings} in |vim.lsp.Client|.
|
||||
--- @field settings? table
|
||||
--- @field settings? lsp.LSPObject
|
||||
---
|
||||
--- Table that maps string of clientside commands to user-defined functions.
|
||||
--- Commands passed to start_client take precedence over the global command registry. Each key
|
||||
--- Commands passed to `start()` take precedence over the global command registry. Each key
|
||||
--- must be a unique command name, and the value is a function which is called if any LSP action
|
||||
--- (code action, code lenses, ...) triggers the command.
|
||||
--- @field commands? table<string,fun(command: lsp.Command, ctx: table)>
|
||||
---
|
||||
--- Values to pass in the initialization request as `initializationOptions`. See `initialize` in
|
||||
--- the LSP spec.
|
||||
--- @field init_options? table
|
||||
--- @field init_options? lsp.LSPObject
|
||||
---
|
||||
--- Name in log messages.
|
||||
--- (default: client-id)
|
||||
@ -94,7 +94,8 @@ local validate = vim.validate
|
||||
--- Language ID as string. Defaults to the buffer filetype.
|
||||
--- @field get_language_id? fun(bufnr: integer, filetype: string): string
|
||||
---
|
||||
--- The encoding that the LSP server expects. Client does not verify this is correct.
|
||||
--- Called "position encoding" in LSP spec, the encoding that the LSP server expects.
|
||||
--- Client does not verify this is correct.
|
||||
--- @field offset_encoding? 'utf-8'|'utf-16'|'utf-32'
|
||||
---
|
||||
--- Callback invoked when the client operation throws an error. `code` is a number describing the error.
|
||||
@ -103,7 +104,7 @@ local validate = vim.validate
|
||||
--- @field on_error? fun(code: integer, err: string)
|
||||
---
|
||||
--- Callback invoked before the LSP "initialize" phase, where `params` contains the parameters
|
||||
--- being sent to the server and `config` is the config that was passed to |vim.lsp.start_client()|.
|
||||
--- being sent to the server and `config` is the config that was passed to |vim.lsp.start()|.
|
||||
--- You can use this to modify parameters before they are sent.
|
||||
--- @field before_init? fun(params: lsp.InitializeParams, config: vim.lsp.ClientConfig)
|
||||
---
|
||||
@ -148,8 +149,10 @@ local validate = vim.validate
|
||||
--- See |vim.lsp.rpc.start()|.
|
||||
--- @field rpc vim.lsp.rpc.PublicClient
|
||||
---
|
||||
--- The encoding used for communicating with the server. You can modify this in
|
||||
--- the `config`'s `on_init` method before text is sent to the server.
|
||||
--- Called "position encoding" in LSP spec,
|
||||
--- the encoding used for communicating with the server.
|
||||
--- You can modify this in the `config`'s `on_init` method
|
||||
--- before text is sent to the server.
|
||||
--- @field offset_encoding string
|
||||
---
|
||||
--- The handlers used by the client as described in |lsp-handler|.
|
||||
@ -161,10 +164,10 @@ local validate = vim.validate
|
||||
--- for an active request, or "cancel" for a cancel request. It will be
|
||||
--- "complete" ephemerally while executing |LspRequest| autocmds when replies
|
||||
--- are received from the server.
|
||||
--- @field requests table<integer,{ type: string, bufnr: integer, method: string}>
|
||||
--- @field requests table<integer,{ type: string, bufnr: integer, method: string}?>
|
||||
---
|
||||
--- copy of the table that was passed by the user
|
||||
--- to |vim.lsp.start_client()|.
|
||||
--- to |vim.lsp.start()|.
|
||||
--- @field config vim.lsp.ClientConfig
|
||||
---
|
||||
--- Response from the server sent on `initialize` describing the server's
|
||||
@ -186,9 +189,6 @@ local validate = vim.validate
|
||||
---
|
||||
--- @field attached_buffers table<integer,true>
|
||||
---
|
||||
--- Buffers that should be attached to upon initialize()
|
||||
--- @field package _buffers_to_attach table<integer,true>
|
||||
---
|
||||
--- @field private _log_prefix string
|
||||
---
|
||||
--- Track this so that we can escalate automatically if we've already tried a
|
||||
@ -207,7 +207,7 @@ local validate = vim.validate
|
||||
--- Map with language server specific settings. These are returned to the
|
||||
--- language server if requested via `workspace/configuration`. Keys are
|
||||
--- case-sensitive.
|
||||
--- @field settings table
|
||||
--- @field settings lsp.LSPObject
|
||||
---
|
||||
--- A table with flags for the client. The current (experimental) flags are:
|
||||
--- @field flags vim.lsp.Client.Flags
|
||||
@ -262,9 +262,6 @@ local valid_encodings = {
|
||||
['utf8'] = 'utf-8',
|
||||
['utf16'] = 'utf-16',
|
||||
['utf32'] = 'utf-32',
|
||||
UTF8 = 'utf-8',
|
||||
UTF16 = 'utf-16',
|
||||
UTF32 = 'utf-32',
|
||||
}
|
||||
|
||||
--- Normalizes {encoding} to valid LSP encoding names.
|
||||
@ -273,12 +270,12 @@ local valid_encodings = {
|
||||
local function validate_encoding(encoding)
|
||||
validate('encoding', encoding, 'string', true)
|
||||
if not encoding then
|
||||
return valid_encodings.UTF16
|
||||
return valid_encodings.utf16
|
||||
end
|
||||
return valid_encodings[encoding:lower()]
|
||||
or error(
|
||||
string.format(
|
||||
"Invalid offset encoding %q. Must be one of: 'utf-8', 'utf-16', 'utf-32'",
|
||||
"Invalid position encoding %q. Must be one of: 'utf-8', 'utf-16', 'utf-32'",
|
||||
encoding
|
||||
)
|
||||
)
|
||||
@ -304,7 +301,7 @@ local function default_get_language_id(_bufnr, filetype)
|
||||
return filetype
|
||||
end
|
||||
|
||||
--- Validates a client configuration as given to |vim.lsp.start_client()|.
|
||||
--- Validates a client configuration as given to |vim.lsp.start()|.
|
||||
--- @param config vim.lsp.ClientConfig
|
||||
local function validate_config(config)
|
||||
validate('config', config, 'table')
|
||||
@ -362,31 +359,6 @@ local function get_name(id, config)
|
||||
return tostring(id)
|
||||
end
|
||||
|
||||
--- @param workspace_folders string|lsp.WorkspaceFolder[]?
|
||||
--- @return lsp.WorkspaceFolder[]?
|
||||
local function get_workspace_folders(workspace_folders)
|
||||
if type(workspace_folders) == 'table' then
|
||||
return workspace_folders
|
||||
elseif type(workspace_folders) == 'string' then
|
||||
return {
|
||||
{
|
||||
uri = vim.uri_from_fname(workspace_folders),
|
||||
name = workspace_folders,
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
--- @generic T
|
||||
--- @param x elem_or_list<T>?
|
||||
--- @return T[]
|
||||
local function ensure_list(x)
|
||||
if type(x) == 'table' then
|
||||
return x
|
||||
end
|
||||
return { x }
|
||||
end
|
||||
|
||||
--- @nodoc
|
||||
--- @param config vim.lsp.ClientConfig
|
||||
--- @return vim.lsp.Client?
|
||||
@ -413,13 +385,13 @@ function Client.create(config)
|
||||
settings = config.settings or {},
|
||||
flags = config.flags or {},
|
||||
get_language_id = config.get_language_id or default_get_language_id,
|
||||
capabilities = config.capabilities or lsp.protocol.make_client_capabilities(),
|
||||
workspace_folders = get_workspace_folders(config.workspace_folders or config.root_dir),
|
||||
capabilities = config.capabilities,
|
||||
workspace_folders = lsp._get_workspace_folders(config.workspace_folders or config.root_dir),
|
||||
root_dir = config.root_dir,
|
||||
_before_init_cb = config.before_init,
|
||||
_on_init_cbs = ensure_list(config.on_init),
|
||||
_on_exit_cbs = ensure_list(config.on_exit),
|
||||
_on_attach_cbs = ensure_list(config.on_attach),
|
||||
_on_init_cbs = vim._ensure_list(config.on_init),
|
||||
_on_exit_cbs = vim._ensure_list(config.on_exit),
|
||||
_on_attach_cbs = vim._ensure_list(config.on_attach),
|
||||
_on_error_cb = config.on_error,
|
||||
_trace = get_trace(config.trace),
|
||||
|
||||
@ -435,6 +407,9 @@ function Client.create(config)
|
||||
messages = { name = name, messages = {}, progress = {}, status = {} },
|
||||
}
|
||||
|
||||
self.capabilities =
|
||||
vim.tbl_deep_extend('force', lsp.protocol.make_client_capabilities(), self.capabilities or {})
|
||||
|
||||
--- @class lsp.DynamicCapabilities
|
||||
--- @nodoc
|
||||
self.dynamic_capabilities = {
|
||||
@ -616,16 +591,55 @@ function Client:_resolve_handler(method)
|
||||
return self.handlers[method] or lsp.handlers[method]
|
||||
end
|
||||
|
||||
--- Returns the buffer number for the given {bufnr}.
|
||||
---
|
||||
--- @param bufnr integer? Buffer number to resolve. Defaults to current buffer
|
||||
--- @return integer bufnr
|
||||
local function resolve_bufnr(bufnr)
|
||||
validate('bufnr', bufnr, 'number', true)
|
||||
if bufnr == nil or bufnr == 0 then
|
||||
return api.nvim_get_current_buf()
|
||||
--- @private
|
||||
--- @param id integer
|
||||
--- @param req_type 'pending'|'complete'|'cancel'|
|
||||
--- @param bufnr? integer (only required for req_type='pending')
|
||||
--- @param method? string (only required for req_type='pending')
|
||||
function Client:_process_request(id, req_type, bufnr, method)
|
||||
local pending = req_type == 'pending'
|
||||
|
||||
validate('id', id, 'number')
|
||||
if pending then
|
||||
validate('bufnr', bufnr, 'number')
|
||||
validate('method', method, 'string')
|
||||
end
|
||||
return bufnr
|
||||
|
||||
local cur_request = self.requests[id]
|
||||
|
||||
if pending and cur_request then
|
||||
log.error(
|
||||
self._log_prefix,
|
||||
('Cannot create request with id %d as one already exists'):format(id)
|
||||
)
|
||||
return
|
||||
elseif not pending and not cur_request then
|
||||
log.error(
|
||||
self._log_prefix,
|
||||
('Cannot find request with id %d whilst attempting to %s'):format(id, req_type)
|
||||
)
|
||||
return
|
||||
end
|
||||
|
||||
if cur_request then
|
||||
bufnr = cur_request.bufnr
|
||||
method = cur_request.method
|
||||
end
|
||||
|
||||
assert(bufnr and method)
|
||||
|
||||
local request = { type = req_type, bufnr = bufnr, method = method }
|
||||
|
||||
-- Clear 'complete' requests
|
||||
-- Note 'pending' and 'cancelled' requests are cleared when the server sends a response
|
||||
-- which is processed via the notify_reply_callback argument to rpc.request.
|
||||
self.requests[id] = req_type ~= 'complete' and request or nil
|
||||
|
||||
api.nvim_exec_autocmds('LspRequest', {
|
||||
buffer = api.nvim_buf_is_valid(bufnr) and bufnr or nil,
|
||||
modeline = false,
|
||||
data = { client_id = self.id, request_id = id, request = request },
|
||||
})
|
||||
end
|
||||
|
||||
--- Sends a request to the server.
|
||||
@ -636,7 +650,7 @@ end
|
||||
--- @param method string LSP method name.
|
||||
--- @param params? table LSP request params.
|
||||
--- @param handler? lsp.Handler Response |lsp-handler| for this method.
|
||||
--- @param bufnr? integer Buffer handle. 0 for current (default).
|
||||
--- @param bufnr? integer (default: 0) Buffer handle, or 0 for current.
|
||||
--- @return boolean status indicates whether the request was successful.
|
||||
--- If it is `false`, then it will always be `false` (the client has shutdown).
|
||||
--- @return integer? request_id Can be used with |Client:cancel_request()|.
|
||||
@ -652,37 +666,24 @@ function Client:request(method, params, handler, bufnr)
|
||||
end
|
||||
-- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state
|
||||
changetracking.flush(self, bufnr)
|
||||
bufnr = resolve_bufnr(bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
local version = lsp.util.buf_versions[bufnr]
|
||||
log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr)
|
||||
local success, request_id = self.rpc.request(method, params, function(err, result)
|
||||
local context = {
|
||||
handler(err, result, {
|
||||
method = method,
|
||||
client_id = self.id,
|
||||
bufnr = bufnr,
|
||||
params = params,
|
||||
version = version,
|
||||
}
|
||||
handler(err, result, context)
|
||||
end, function(request_id)
|
||||
local request = self.requests[request_id]
|
||||
request.type = 'complete'
|
||||
api.nvim_exec_autocmds('LspRequest', {
|
||||
buffer = api.nvim_buf_is_valid(bufnr) and bufnr or nil,
|
||||
modeline = false,
|
||||
data = { client_id = self.id, request_id = request_id, request = request },
|
||||
})
|
||||
self.requests[request_id] = nil
|
||||
end, function(request_id)
|
||||
-- Called when the server sends a response to the request (including cancelled acknowledgment).
|
||||
self:_process_request(request_id, 'complete')
|
||||
end)
|
||||
|
||||
if success and request_id then
|
||||
local request = { type = 'pending', bufnr = bufnr, method = method }
|
||||
self.requests[request_id] = request
|
||||
api.nvim_exec_autocmds('LspRequest', {
|
||||
buffer = api.nvim_buf_is_valid(bufnr) and bufnr or nil,
|
||||
modeline = false,
|
||||
data = { client_id = self.id, request_id = request_id, request = request },
|
||||
})
|
||||
self:_process_request(request_id, 'pending', bufnr, method)
|
||||
end
|
||||
|
||||
return success, request_id
|
||||
@ -715,7 +716,7 @@ end
|
||||
--- @param params table LSP request params.
|
||||
--- @param timeout_ms integer? Maximum time in milliseconds to wait for
|
||||
--- a result. Defaults to 1000
|
||||
--- @param bufnr integer Buffer handle (0 for current).
|
||||
--- @param bufnr? integer (default: 0) Buffer handle, or 0 for current.
|
||||
--- @return {err: lsp.ResponseError?, result:any}? `result` and `err` from the |lsp-handler|.
|
||||
--- `nil` is the request was unsuccessful
|
||||
--- @return string? err On timeout, cancel or error, where `err` is a
|
||||
@ -780,16 +781,7 @@ end
|
||||
--- @return boolean status indicating if the notification was successful.
|
||||
--- @see |Client:notify()|
|
||||
function Client:cancel_request(id)
|
||||
validate('id', id, 'number')
|
||||
local request = self.requests[id]
|
||||
if request and request.type == 'pending' then
|
||||
request.type = 'cancel'
|
||||
api.nvim_exec_autocmds('LspRequest', {
|
||||
buffer = api.nvim_buf_is_valid(request.bufnr) and request.bufnr or nil,
|
||||
modeline = false,
|
||||
data = { client_id = self.id, request_id = id, request = request },
|
||||
})
|
||||
end
|
||||
self:_process_request(id, 'cancel')
|
||||
return self.rpc.notify(ms.dollar_cancelRequest, { id = id })
|
||||
end
|
||||
|
||||
@ -903,7 +895,7 @@ end
|
||||
--- @param bufnr? integer
|
||||
--- @return lsp.Registration?
|
||||
function Client:_get_registration(method, bufnr)
|
||||
bufnr = bufnr or vim.api.nvim_get_current_buf()
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
for _, reg in ipairs(self.registrations[method] or {}) do
|
||||
if not reg.registerOptions or not reg.registerOptions.documentSelector then
|
||||
return reg
|
||||
@ -940,7 +932,7 @@ end
|
||||
--- @param handler? lsp.Handler only called if a server command
|
||||
function Client:exec_cmd(command, context, handler)
|
||||
context = vim.deepcopy(context or {}, true) --[[@as lsp.HandlerContext]]
|
||||
context.bufnr = context.bufnr or api.nvim_get_current_buf()
|
||||
context.bufnr = vim._resolve_bufnr(context.bufnr)
|
||||
context.client_id = self.id
|
||||
local cmdname = command.command
|
||||
local fn = self.commands[cmdname] or lsp.commands[cmdname]
|
||||
@ -1171,7 +1163,7 @@ function Client:_add_workspace_folder(dir)
|
||||
end
|
||||
end
|
||||
|
||||
local wf = assert(get_workspace_folders(dir))
|
||||
local wf = assert(lsp._get_workspace_folders(dir))
|
||||
|
||||
self:notify(ms.workspace_didChangeWorkspaceFolders, {
|
||||
event = { added = wf, removed = {} },
|
||||
@ -1186,7 +1178,7 @@ end
|
||||
--- Remove a directory to the workspace folders.
|
||||
--- @param dir string?
|
||||
function Client:_remove_workspace_folder(dir)
|
||||
local wf = assert(get_workspace_folders(dir))
|
||||
local wf = assert(lsp._get_workspace_folders(dir))
|
||||
|
||||
self:notify(ms.workspace_didChangeWorkspaceFolders, {
|
||||
event = { added = {}, removed = wf },
|
||||
|
@ -104,16 +104,12 @@ function M.run()
|
||||
end
|
||||
end
|
||||
|
||||
local function resolve_bufnr(bufnr)
|
||||
return bufnr == 0 and api.nvim_get_current_buf() or bufnr
|
||||
end
|
||||
|
||||
--- Clear the lenses
|
||||
---
|
||||
---@param client_id integer|nil filter by client_id. All clients if nil
|
||||
---@param bufnr integer|nil filter by buffer. All buffers if nil, 0 for current buffer
|
||||
function M.clear(client_id, bufnr)
|
||||
bufnr = bufnr and resolve_bufnr(bufnr)
|
||||
bufnr = bufnr and vim._resolve_bufnr(bufnr)
|
||||
local buffers = bufnr and { bufnr }
|
||||
or vim.tbl_filter(api.nvim_buf_is_loaded, api.nvim_list_bufs())
|
||||
for _, iter_bufnr in pairs(buffers) do
|
||||
@ -296,7 +292,7 @@ end
|
||||
--- @param opts? vim.lsp.codelens.refresh.Opts Optional fields
|
||||
function M.refresh(opts)
|
||||
opts = opts or {}
|
||||
local bufnr = opts.bufnr and resolve_bufnr(opts.bufnr)
|
||||
local bufnr = opts.bufnr and vim._resolve_bufnr(opts.bufnr)
|
||||
local buffers = bufnr and { bufnr }
|
||||
or vim.tbl_filter(api.nvim_buf_is_loaded, api.nvim_list_bufs())
|
||||
|
||||
|
@ -550,7 +550,7 @@ local function on_complete_done()
|
||||
return
|
||||
end
|
||||
|
||||
local offset_encoding = client.offset_encoding or 'utf-16'
|
||||
local position_encoding = client.offset_encoding or 'utf-16'
|
||||
local resolve_provider = (client.server_capabilities.completionProvider or {}).resolveProvider
|
||||
|
||||
local function clear_word()
|
||||
@ -576,7 +576,7 @@ local function on_complete_done()
|
||||
|
||||
if completion_item.additionalTextEdits and next(completion_item.additionalTextEdits) then
|
||||
clear_word()
|
||||
lsp.util.apply_text_edits(completion_item.additionalTextEdits, bufnr, offset_encoding)
|
||||
lsp.util.apply_text_edits(completion_item.additionalTextEdits, bufnr, position_encoding)
|
||||
apply_snippet_and_command()
|
||||
elseif resolve_provider and type(completion_item) == 'table' then
|
||||
local changedtick = vim.b[bufnr].changedtick
|
||||
@ -591,7 +591,7 @@ local function on_complete_done()
|
||||
if err then
|
||||
vim.notify_once(err.message, vim.log.levels.WARN)
|
||||
elseif result and result.additionalTextEdits then
|
||||
lsp.util.apply_text_edits(result.additionalTextEdits, bufnr, offset_encoding)
|
||||
lsp.util.apply_text_edits(result.additionalTextEdits, bufnr, position_encoding)
|
||||
if result.command then
|
||||
completion_item.command = result.command
|
||||
end
|
||||
@ -716,7 +716,7 @@ end
|
||||
--- @param bufnr integer Buffer handle, or 0 for the current buffer
|
||||
--- @param opts? vim.lsp.completion.BufferOpts
|
||||
function M.enable(enable, client_id, bufnr, opts)
|
||||
bufnr = (bufnr == 0 and api.nvim_get_current_buf()) or bufnr
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
if enable then
|
||||
enable_completions(client_id, bufnr, opts or {})
|
||||
|
@ -77,7 +77,7 @@ end
|
||||
local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
|
||||
local buf_lines = get_buf_lines(bufnr)
|
||||
local client = vim.lsp.get_client_by_id(client_id)
|
||||
local offset_encoding = client and client.offset_encoding or 'utf-16'
|
||||
local position_encoding = client and client.offset_encoding or 'utf-16'
|
||||
--- @param diagnostic lsp.Diagnostic
|
||||
--- @return vim.Diagnostic
|
||||
return vim.tbl_map(function(diagnostic)
|
||||
@ -95,9 +95,9 @@ local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
|
||||
--- @type vim.Diagnostic
|
||||
return {
|
||||
lnum = start.line,
|
||||
col = vim.str_byteindex(line, offset_encoding, start.character, false),
|
||||
col = vim.str_byteindex(line, position_encoding, start.character, false),
|
||||
end_lnum = _end.line,
|
||||
end_col = vim.str_byteindex(line, offset_encoding, _end.character, false),
|
||||
end_col = vim.str_byteindex(line, position_encoding, _end.character, false),
|
||||
severity = severity_lsp_to_vim(diagnostic.severity),
|
||||
message = message,
|
||||
source = diagnostic.source,
|
||||
@ -246,10 +246,18 @@ end
|
||||
---
|
||||
--- See |vim.diagnostic.config()| for configuration options.
|
||||
---
|
||||
---@param _ lsp.ResponseError?
|
||||
---@param error lsp.ResponseError?
|
||||
---@param result lsp.DocumentDiagnosticReport
|
||||
---@param ctx lsp.HandlerContext
|
||||
function M.on_diagnostic(_, result, ctx)
|
||||
function M.on_diagnostic(error, result, ctx)
|
||||
if error ~= nil and error.code == protocol.ErrorCodes.ServerCancelled then
|
||||
if error.data == nil or error.data.retriggerRequest ~= false then
|
||||
local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
|
||||
client:request(ctx.method, ctx.params)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if result == nil or result.kind == 'unchanged' then
|
||||
return
|
||||
end
|
||||
@ -348,9 +356,7 @@ end
|
||||
---@param bufnr (integer) Buffer handle, or 0 for current
|
||||
---@private
|
||||
function M._enable(bufnr)
|
||||
if bufnr == nil or bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
if not bufstates[bufnr] then
|
||||
bufstates[bufnr] = { enabled = true }
|
||||
|
@ -659,7 +659,8 @@ for k, fn in pairs(M) do
|
||||
})
|
||||
end
|
||||
|
||||
if err then
|
||||
-- ServerCancelled errors should be propagated to the request handler
|
||||
if err and err.code ~= protocol.ErrorCodes.ServerCancelled then
|
||||
-- LSP spec:
|
||||
-- interface ResponseError:
|
||||
-- code: integer;
|
||||
|
@ -28,42 +28,45 @@ local function check_log()
|
||||
report_fn(string.format('Log size: %d KB', log_size / 1000))
|
||||
end
|
||||
|
||||
--- @param f function
|
||||
--- @return string
|
||||
local function func_tostring(f)
|
||||
local info = debug.getinfo(f, 'S')
|
||||
return ('<function %s:%s>'):format(info.source, info.linedefined)
|
||||
end
|
||||
|
||||
local function check_active_clients()
|
||||
vim.health.start('vim.lsp: Active Clients')
|
||||
local clients = vim.lsp.get_clients()
|
||||
if next(clients) then
|
||||
for _, client in pairs(clients) do
|
||||
local cmd ---@type string
|
||||
if type(client.config.cmd) == 'table' then
|
||||
cmd = table.concat(client.config.cmd --[[@as table]], ' ')
|
||||
elseif type(client.config.cmd) == 'function' then
|
||||
cmd = tostring(client.config.cmd)
|
||||
local ccmd = client.config.cmd
|
||||
if type(ccmd) == 'table' then
|
||||
cmd = vim.inspect(ccmd)
|
||||
elseif type(ccmd) == 'function' then
|
||||
cmd = func_tostring(ccmd)
|
||||
end
|
||||
local dirs_info ---@type string
|
||||
if client.workspace_folders and #client.workspace_folders > 1 then
|
||||
dirs_info = string.format(
|
||||
' Workspace folders:\n %s',
|
||||
vim
|
||||
.iter(client.workspace_folders)
|
||||
---@param folder lsp.WorkspaceFolder
|
||||
:map(function(folder)
|
||||
return folder.name
|
||||
end)
|
||||
:join('\n ')
|
||||
)
|
||||
local wfolders = {} --- @type string[]
|
||||
for _, dir in ipairs(client.workspace_folders) do
|
||||
wfolders[#wfolders + 1] = dir.name
|
||||
end
|
||||
dirs_info = ('- Workspace folders:\n %s'):format(table.concat(wfolders, '\n '))
|
||||
else
|
||||
dirs_info = string.format(
|
||||
' Root directory: %s',
|
||||
'- Root directory: %s',
|
||||
client.root_dir and vim.fn.fnamemodify(client.root_dir, ':~')
|
||||
) or nil
|
||||
end
|
||||
report_info(table.concat({
|
||||
string.format('%s (id: %d)', client.name, client.id),
|
||||
dirs_info,
|
||||
string.format(' Command: %s', cmd),
|
||||
string.format(' Settings: %s', vim.inspect(client.settings, { newline = '\n ' })),
|
||||
string.format('- Command: %s', cmd),
|
||||
string.format('- Settings: %s', vim.inspect(client.settings, { newline = '\n ' })),
|
||||
string.format(
|
||||
' Attached buffers: %s',
|
||||
'- Attached buffers: %s',
|
||||
vim.iter(pairs(client.attached_buffers)):map(tostring):join(', ')
|
||||
),
|
||||
}, '\n'))
|
||||
@ -174,10 +177,45 @@ local function check_position_encodings()
|
||||
end
|
||||
end
|
||||
|
||||
local function check_enabled_configs()
|
||||
vim.health.start('vim.lsp: Enabled Configurations')
|
||||
|
||||
for name in vim.spairs(vim.lsp._enabled_configs) do
|
||||
local config = vim.lsp._resolve_config(name)
|
||||
local text = {} --- @type string[]
|
||||
text[#text + 1] = ('%s:'):format(name)
|
||||
for k, v in
|
||||
vim.spairs(config --[[@as table<string,any>]])
|
||||
do
|
||||
local v_str --- @type string?
|
||||
if k == 'name' then
|
||||
v_str = nil
|
||||
elseif k == 'filetypes' or k == 'root_markers' then
|
||||
v_str = table.concat(v, ', ')
|
||||
elseif type(v) == 'function' then
|
||||
v_str = func_tostring(v)
|
||||
else
|
||||
v_str = vim.inspect(v, { newline = '\n ' })
|
||||
end
|
||||
|
||||
if k == 'cmd' and type(v) == 'table' and vim.fn.executable(v[1]) == 0 then
|
||||
report_warn(("'%s' is not executable. Configuration will not be used."):format(v[1]))
|
||||
end
|
||||
|
||||
if v_str then
|
||||
text[#text + 1] = ('- %s: %s'):format(k, v_str)
|
||||
end
|
||||
end
|
||||
text[#text + 1] = ''
|
||||
report_info(table.concat(text, '\n'))
|
||||
end
|
||||
end
|
||||
|
||||
--- Performs a healthcheck for LSP
|
||||
function M.check()
|
||||
check_log()
|
||||
check_active_clients()
|
||||
check_enabled_configs()
|
||||
check_watcher()
|
||||
check_position_encodings()
|
||||
end
|
||||
|
@ -149,8 +149,8 @@ function M.get(filter)
|
||||
vim.list_extend(hints, M.get(vim.tbl_extend('keep', { bufnr = buf }, filter)))
|
||||
end, vim.api.nvim_list_bufs())
|
||||
return hints
|
||||
elseif bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
else
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
end
|
||||
|
||||
local bufstate = bufstates[bufnr]
|
||||
@ -203,9 +203,7 @@ end
|
||||
--- Clear inlay hints
|
||||
---@param bufnr (integer) Buffer handle, or 0 for current
|
||||
local function clear(bufnr)
|
||||
if bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
local bufstate = bufstates[bufnr]
|
||||
local client_lens = (bufstate or {}).client_hints or {}
|
||||
local client_ids = vim.tbl_keys(client_lens) --- @type integer[]
|
||||
@ -221,9 +219,7 @@ end
|
||||
--- Disable inlay hints for a buffer
|
||||
---@param bufnr (integer) Buffer handle, or 0 for current
|
||||
local function _disable(bufnr)
|
||||
if bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
clear(bufnr)
|
||||
bufstates[bufnr] = nil
|
||||
bufstates[bufnr].enabled = false
|
||||
@ -242,9 +238,7 @@ end
|
||||
--- Enable inlay hints for a buffer
|
||||
---@param bufnr (integer) Buffer handle, or 0 for current
|
||||
local function _enable(bufnr)
|
||||
if bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
bufstates[bufnr] = nil
|
||||
bufstates[bufnr].enabled = true
|
||||
_refresh(bufnr)
|
||||
@ -371,13 +365,10 @@ function M.is_enabled(filter)
|
||||
filter = filter or {}
|
||||
local bufnr = filter.bufnr
|
||||
|
||||
vim.validate('bufnr', bufnr, 'number', true)
|
||||
if bufnr == nil then
|
||||
return globalstate.enabled
|
||||
elseif bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
return bufstates[bufnr].enabled
|
||||
return bufstates[vim._resolve_bufnr(bufnr)].enabled
|
||||
end
|
||||
|
||||
--- Optional filters |kwargs|, or `nil` for all.
|
||||
|
@ -174,6 +174,7 @@ local constants = {
|
||||
-- Defined by the protocol.
|
||||
RequestCancelled = -32800,
|
||||
ContentModified = -32801,
|
||||
ServerCancelled = -32802,
|
||||
},
|
||||
|
||||
-- Describes the content type that a client supports in various
|
||||
@ -439,6 +440,13 @@ function protocol.make_client_capabilities()
|
||||
properties = { 'command' },
|
||||
},
|
||||
},
|
||||
foldingRange = {
|
||||
dynamicRegistration = false,
|
||||
lineFoldingOnly = true,
|
||||
foldingRange = {
|
||||
collapsedText = true,
|
||||
},
|
||||
},
|
||||
formatting = {
|
||||
dynamicRegistration = true,
|
||||
},
|
||||
|
@ -1,18 +1,8 @@
|
||||
local uv = vim.uv
|
||||
local log = require('vim.lsp.log')
|
||||
local protocol = require('vim.lsp.protocol')
|
||||
local lsp_transport = require('vim.lsp._transport')
|
||||
local validate, schedule_wrap = vim.validate, vim.schedule_wrap
|
||||
|
||||
local is_win = vim.fn.has('win32') == 1
|
||||
|
||||
--- Checks whether a given path exists and is a directory.
|
||||
---@param filename string path to check
|
||||
---@return boolean
|
||||
local function is_dir(filename)
|
||||
local stat = uv.fs_stat(filename)
|
||||
return stat and stat.type == 'directory' or false
|
||||
end
|
||||
|
||||
--- Embeds the given string into a table and correctly computes `Content-Length`.
|
||||
---
|
||||
---@param message string
|
||||
@ -242,8 +232,11 @@ local default_dispatchers = {
|
||||
end,
|
||||
}
|
||||
|
||||
---@private
|
||||
function M.create_read_loop(handle_body, on_no_chunk, on_error)
|
||||
--- @private
|
||||
--- @param handle_body fun(body: string)
|
||||
--- @param on_exit? fun()
|
||||
--- @param on_error fun(err: any)
|
||||
function M.create_read_loop(handle_body, on_exit, on_error)
|
||||
local parse_chunk = coroutine.wrap(request_parser_loop) --[[@as fun(chunk: string?): vim.lsp.rpc.Headers?, string?]]
|
||||
parse_chunk()
|
||||
return function(err, chunk)
|
||||
@ -253,8 +246,8 @@ function M.create_read_loop(handle_body, on_no_chunk, on_error)
|
||||
end
|
||||
|
||||
if not chunk then
|
||||
if on_no_chunk then
|
||||
on_no_chunk()
|
||||
if on_exit then
|
||||
on_exit()
|
||||
end
|
||||
return
|
||||
end
|
||||
@ -262,7 +255,7 @@ function M.create_read_loop(handle_body, on_no_chunk, on_error)
|
||||
while true do
|
||||
local headers, body = parse_chunk(chunk)
|
||||
if headers then
|
||||
handle_body(body)
|
||||
handle_body(assert(body))
|
||||
chunk = ''
|
||||
else
|
||||
break
|
||||
@ -282,14 +275,14 @@ local Client = {}
|
||||
---@private
|
||||
function Client:encode_and_send(payload)
|
||||
log.debug('rpc.send', payload)
|
||||
if self.transport.is_closing() then
|
||||
if self.transport:is_closing() then
|
||||
return false
|
||||
end
|
||||
local jsonstr = assert(
|
||||
vim.json.encode(payload),
|
||||
string.format("Couldn't encode payload '%s'", vim.inspect(payload))
|
||||
)
|
||||
self.transport.write(format_message_with_content_length(jsonstr))
|
||||
self.transport:write(format_message_with_content_length(jsonstr))
|
||||
return true
|
||||
end
|
||||
|
||||
@ -323,7 +316,7 @@ end
|
||||
---@param method string The invoked LSP method
|
||||
---@param params table? Parameters for the invoked LSP method
|
||||
---@param callback fun(err?: lsp.ResponseError, result: any) Callback to invoke
|
||||
---@param notify_reply_callback fun(message_id: integer)|nil Callback to invoke as soon as a request is no longer pending
|
||||
---@param notify_reply_callback? fun(message_id: integer) Callback to invoke as soon as a request is no longer pending
|
||||
---@return boolean success `true` if request could be sent, `false` if not
|
||||
---@return integer? message_id if request could be sent, `nil` if not
|
||||
function Client:request(method, params, callback, notify_reply_callback)
|
||||
@ -337,21 +330,16 @@ function Client:request(method, params, callback, notify_reply_callback)
|
||||
method = method,
|
||||
params = params,
|
||||
})
|
||||
local message_callbacks = self.message_callbacks
|
||||
local notify_reply_callbacks = self.notify_reply_callbacks
|
||||
if result then
|
||||
if message_callbacks then
|
||||
message_callbacks[message_id] = schedule_wrap(callback)
|
||||
else
|
||||
return false, nil
|
||||
end
|
||||
if notify_reply_callback and notify_reply_callbacks then
|
||||
notify_reply_callbacks[message_id] = schedule_wrap(notify_reply_callback)
|
||||
end
|
||||
return result, message_id
|
||||
else
|
||||
return false, nil
|
||||
|
||||
if not result then
|
||||
return false
|
||||
end
|
||||
|
||||
self.message_callbacks[message_id] = schedule_wrap(callback)
|
||||
if notify_reply_callback then
|
||||
self.notify_reply_callbacks[message_id] = schedule_wrap(notify_reply_callback)
|
||||
end
|
||||
return result, message_id
|
||||
end
|
||||
|
||||
---@package
|
||||
@ -370,7 +358,7 @@ end
|
||||
---@param ... any
|
||||
---@return boolean status
|
||||
---@return any head
|
||||
---@return any|nil ...
|
||||
---@return any? ...
|
||||
function Client:pcall_handler(errkind, status, head, ...)
|
||||
if not status then
|
||||
self:on_error(errkind, head, ...)
|
||||
@ -385,7 +373,7 @@ end
|
||||
---@param ... any
|
||||
---@return boolean status
|
||||
---@return any head
|
||||
---@return any|nil ...
|
||||
---@return any? ...
|
||||
function Client:try_call(errkind, fn, ...)
|
||||
return self:pcall_handler(errkind, pcall(fn, ...))
|
||||
end
|
||||
@ -394,7 +382,8 @@ end
|
||||
-- time and log them. This would require storing the timestamp. I could call
|
||||
-- them with an error then, perhaps.
|
||||
|
||||
---@package
|
||||
--- @package
|
||||
--- @param body string
|
||||
function Client:handle_body(body)
|
||||
local ok, decoded = pcall(vim.json.decode, body, { luanil = { object = true } })
|
||||
if not ok then
|
||||
@ -406,7 +395,7 @@ function Client:handle_body(body)
|
||||
if type(decoded) ~= 'table' then
|
||||
self:on_error(M.client_errors.INVALID_SERVER_MESSAGE, decoded)
|
||||
elseif type(decoded.method) == 'string' and decoded.id then
|
||||
local err --- @type lsp.ResponseError|nil
|
||||
local err --- @type lsp.ResponseError?
|
||||
-- Schedule here so that the users functions don't trigger an error and
|
||||
-- we can still use the result.
|
||||
vim.schedule(coroutine.wrap(function()
|
||||
@ -453,45 +442,36 @@ function Client:handle_body(body)
|
||||
local result_id = assert(tonumber(decoded.id), 'response id must be a number')
|
||||
|
||||
-- Notify the user that a response was received for the request
|
||||
local notify_reply_callbacks = self.notify_reply_callbacks
|
||||
local notify_reply_callback = notify_reply_callbacks and notify_reply_callbacks[result_id]
|
||||
local notify_reply_callback = self.notify_reply_callbacks[result_id]
|
||||
if notify_reply_callback then
|
||||
validate('notify_reply_callback', notify_reply_callback, 'function')
|
||||
notify_reply_callback(result_id)
|
||||
notify_reply_callbacks[result_id] = nil
|
||||
self.notify_reply_callbacks[result_id] = nil
|
||||
end
|
||||
|
||||
local message_callbacks = self.message_callbacks
|
||||
|
||||
-- Do not surface RequestCancelled to users, it is RPC-internal.
|
||||
if decoded.error then
|
||||
local mute_error = false
|
||||
assert(type(decoded.error) == 'table')
|
||||
if decoded.error.code == protocol.ErrorCodes.RequestCancelled then
|
||||
log.debug('Received cancellation ack', decoded)
|
||||
mute_error = true
|
||||
end
|
||||
|
||||
if mute_error then
|
||||
-- Clear any callback since this is cancelled now.
|
||||
-- This is safe to do assuming that these conditions hold:
|
||||
-- - The server will not send a result callback after this cancellation.
|
||||
-- - If the server sent this cancellation ACK after sending the result, the user of this RPC
|
||||
-- client will ignore the result themselves.
|
||||
if result_id and message_callbacks then
|
||||
message_callbacks[result_id] = nil
|
||||
if result_id then
|
||||
self.message_callbacks[result_id] = nil
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local callback = message_callbacks and message_callbacks[result_id]
|
||||
local callback = self.message_callbacks[result_id]
|
||||
if callback then
|
||||
message_callbacks[result_id] = nil
|
||||
self.message_callbacks[result_id] = nil
|
||||
validate('callback', callback, 'function')
|
||||
if decoded.error then
|
||||
decoded.error = setmetatable(decoded.error, {
|
||||
__tostring = M.format_rpc_error,
|
||||
})
|
||||
setmetatable(decoded.error, { __tostring = M.format_rpc_error })
|
||||
end
|
||||
self:try_call(
|
||||
M.client_errors.SERVER_RESULT_CALLBACK_ERROR,
|
||||
@ -517,11 +497,6 @@ function Client:handle_body(body)
|
||||
end
|
||||
end
|
||||
|
||||
---@class (private) vim.lsp.rpc.Transport
|
||||
---@field write fun(msg: string)
|
||||
---@field is_closing fun(): boolean
|
||||
---@field terminate fun()
|
||||
|
||||
---@param dispatchers vim.lsp.rpc.Dispatchers
|
||||
---@param transport vim.lsp.rpc.Transport
|
||||
---@return vim.lsp.rpc.Client
|
||||
@ -536,11 +511,20 @@ local function new_client(dispatchers, transport)
|
||||
return setmetatable(state, { __index = Client })
|
||||
end
|
||||
|
||||
---@class vim.lsp.rpc.PublicClient
|
||||
---@field request fun(method: string, params: table?, callback: fun(err: lsp.ResponseError|nil, result: any), notify_reply_callback: fun(message_id: integer)|nil):boolean,integer? see |vim.lsp.rpc.request()|
|
||||
---@field notify fun(method: string, params: any):boolean see |vim.lsp.rpc.notify()|
|
||||
---@field is_closing fun(): boolean
|
||||
---@field terminate fun()
|
||||
--- Client RPC object
|
||||
--- @class vim.lsp.rpc.PublicClient
|
||||
---
|
||||
--- See [vim.lsp.rpc.request()]
|
||||
--- @field request fun(method: string, params: table?, callback: fun(err?: lsp.ResponseError, result: any), notify_reply_callback?: fun(message_id: integer)):boolean,integer?
|
||||
---
|
||||
--- See [vim.lsp.rpc.notify()]
|
||||
--- @field notify fun(method: string, params: any): boolean
|
||||
---
|
||||
--- Indicates if the RPC is closing.
|
||||
--- @field is_closing fun(): boolean
|
||||
---
|
||||
--- Terminates the RPC client.
|
||||
--- @field terminate fun()
|
||||
|
||||
---@param client vim.lsp.rpc.Client
|
||||
---@return vim.lsp.rpc.PublicClient
|
||||
@ -551,20 +535,20 @@ local function public_client(client)
|
||||
|
||||
---@private
|
||||
function result.is_closing()
|
||||
return client.transport.is_closing()
|
||||
return client.transport:is_closing()
|
||||
end
|
||||
|
||||
---@private
|
||||
function result.terminate()
|
||||
client.transport.terminate()
|
||||
client.transport:terminate()
|
||||
end
|
||||
|
||||
--- Sends a request to the LSP server and runs {callback} upon response.
|
||||
---
|
||||
---@param method (string) The invoked LSP method
|
||||
---@param params (table?) Parameters for the invoked LSP method
|
||||
---@param callback fun(err: lsp.ResponseError|nil, result: any) Callback to invoke
|
||||
---@param notify_reply_callback fun(message_id: integer)|nil Callback to invoke as soon as a request is no longer pending
|
||||
---@param callback fun(err: lsp.ResponseError?, result: any) Callback to invoke
|
||||
---@param notify_reply_callback? fun(message_id: integer) Callback to invoke as soon as a request is no longer pending
|
||||
---@return boolean success `true` if request could be sent, `false` if not
|
||||
---@return integer? message_id if request could be sent, `nil` if not
|
||||
function result.request(method, params, callback, notify_reply_callback)
|
||||
@ -610,6 +594,21 @@ local function merge_dispatchers(dispatchers)
|
||||
return merged
|
||||
end
|
||||
|
||||
--- @param client vim.lsp.rpc.Client
|
||||
--- @param on_exit? fun()
|
||||
local function create_client_read_loop(client, on_exit)
|
||||
--- @param body string
|
||||
local function handle_body(body)
|
||||
client:handle_body(body)
|
||||
end
|
||||
|
||||
local function on_error(err)
|
||||
client:on_error(M.client_errors.READ_ERROR, err)
|
||||
end
|
||||
|
||||
return M.create_read_loop(handle_body, on_exit, on_error)
|
||||
end
|
||||
|
||||
--- Create a LSP RPC client factory that connects to either:
|
||||
---
|
||||
--- - a named pipe (windows)
|
||||
@ -617,83 +616,26 @@ end
|
||||
--- - a host and port via TCP
|
||||
---
|
||||
--- Return a function that can be passed to the `cmd` field for
|
||||
--- |vim.lsp.start_client()| or |vim.lsp.start()|.
|
||||
--- |vim.lsp.start()|.
|
||||
---
|
||||
---@param host_or_path string host to connect to or path to a pipe/domain socket
|
||||
---@param port integer? TCP port to connect to. If absent the first argument must be a pipe
|
||||
---@return fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient
|
||||
function M.connect(host_or_path, port)
|
||||
validate('host_or_path', host_or_path, 'string')
|
||||
validate('port', port, 'number', true)
|
||||
|
||||
return function(dispatchers)
|
||||
validate('dispatchers', dispatchers, 'table', true)
|
||||
|
||||
dispatchers = merge_dispatchers(dispatchers)
|
||||
local handle = (
|
||||
port == nil
|
||||
and assert(
|
||||
uv.new_pipe(false),
|
||||
string.format('Pipe with name %s could not be opened.', host_or_path)
|
||||
)
|
||||
or assert(uv.new_tcp(), 'Could not create new TCP socket')
|
||||
)
|
||||
local closing = false
|
||||
-- Connect returns a PublicClient synchronously so the caller
|
||||
-- can immediately send messages before the connection is established
|
||||
-- -> Need to buffer them until that happens
|
||||
local connected = false
|
||||
-- size should be enough because the client can't really do anything until initialization is done
|
||||
-- which required a response from the server - implying the connection got established
|
||||
local msgbuf = vim.ringbuf(10)
|
||||
local transport = {
|
||||
write = function(msg)
|
||||
if connected then
|
||||
local _, err = handle:write(msg)
|
||||
if err and not closing then
|
||||
log.error('Error on handle:write: %q', err)
|
||||
end
|
||||
else
|
||||
msgbuf:push(msg)
|
||||
end
|
||||
end,
|
||||
is_closing = function()
|
||||
return closing
|
||||
end,
|
||||
terminate = function()
|
||||
if not closing then
|
||||
closing = true
|
||||
handle:shutdown()
|
||||
handle:close()
|
||||
dispatchers.on_exit(0, 0)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
local transport = lsp_transport.TransportConnect.new()
|
||||
local client = new_client(dispatchers, transport)
|
||||
local function on_connect(err)
|
||||
if err then
|
||||
local address = port == nil and host_or_path or (host_or_path .. ':' .. port)
|
||||
vim.schedule(function()
|
||||
vim.notify(
|
||||
string.format('Could not connect to %s, reason: %s', address, vim.inspect(err)),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
end)
|
||||
return
|
||||
end
|
||||
local handle_body = function(body)
|
||||
client:handle_body(body)
|
||||
end
|
||||
handle:read_start(M.create_read_loop(handle_body, transport.terminate, function(read_err)
|
||||
client:on_error(M.client_errors.READ_ERROR, read_err)
|
||||
end))
|
||||
connected = true
|
||||
for msg in msgbuf do
|
||||
handle:write(msg)
|
||||
end
|
||||
end
|
||||
if port == nil then
|
||||
handle:connect(host_or_path, on_connect)
|
||||
else
|
||||
local info = uv.getaddrinfo(host_or_path, nil)
|
||||
local resolved_host = info and info[1] and info[1].addr or host_or_path
|
||||
handle:connect(resolved_host, port, on_connect)
|
||||
end
|
||||
local on_read = create_client_read_loop(client, function()
|
||||
transport:terminate()
|
||||
end)
|
||||
transport:connect(host_or_path, port, on_read, dispatchers.on_exit)
|
||||
|
||||
return public_client(client)
|
||||
end
|
||||
@ -713,83 +655,19 @@ end
|
||||
--- @param cmd string[] Command to start the LSP server.
|
||||
--- @param dispatchers? vim.lsp.rpc.Dispatchers
|
||||
--- @param extra_spawn_params? vim.lsp.rpc.ExtraSpawnParams
|
||||
--- @return vim.lsp.rpc.PublicClient : Client RPC object, with these methods:
|
||||
--- - `notify()` |vim.lsp.rpc.notify()|
|
||||
--- - `request()` |vim.lsp.rpc.request()|
|
||||
--- - `is_closing()` returns a boolean indicating if the RPC is closing.
|
||||
--- - `terminate()` terminates the RPC client.
|
||||
--- @return vim.lsp.rpc.PublicClient
|
||||
function M.start(cmd, dispatchers, extra_spawn_params)
|
||||
log.info('Starting RPC client', { cmd = cmd, extra = extra_spawn_params })
|
||||
|
||||
validate('cmd', cmd, 'table')
|
||||
validate('dispatchers', dispatchers, 'table', true)
|
||||
|
||||
extra_spawn_params = extra_spawn_params or {}
|
||||
|
||||
if extra_spawn_params.cwd then
|
||||
assert(is_dir(extra_spawn_params.cwd), 'cwd must be a directory')
|
||||
end
|
||||
|
||||
dispatchers = merge_dispatchers(dispatchers)
|
||||
|
||||
local sysobj ---@type vim.SystemObj
|
||||
|
||||
local client = new_client(dispatchers, {
|
||||
write = function(msg)
|
||||
sysobj:write(msg)
|
||||
end,
|
||||
is_closing = function()
|
||||
return sysobj == nil or sysobj:is_closing()
|
||||
end,
|
||||
terminate = function()
|
||||
sysobj:kill(15)
|
||||
end,
|
||||
})
|
||||
|
||||
local handle_body = function(body)
|
||||
client:handle_body(body)
|
||||
end
|
||||
|
||||
local stdout_handler = M.create_read_loop(handle_body, nil, function(err)
|
||||
client:on_error(M.client_errors.READ_ERROR, err)
|
||||
end)
|
||||
|
||||
local stderr_handler = function(_, chunk)
|
||||
if chunk then
|
||||
log.error('rpc', cmd[1], 'stderr', chunk)
|
||||
end
|
||||
end
|
||||
|
||||
local detached = not is_win
|
||||
if extra_spawn_params.detached ~= nil then
|
||||
detached = extra_spawn_params.detached
|
||||
end
|
||||
|
||||
local ok, sysobj_or_err = pcall(vim.system, cmd, {
|
||||
stdin = true,
|
||||
stdout = stdout_handler,
|
||||
stderr = stderr_handler,
|
||||
cwd = extra_spawn_params.cwd,
|
||||
env = extra_spawn_params.env,
|
||||
detach = detached,
|
||||
}, function(obj)
|
||||
dispatchers.on_exit(obj.code, obj.signal)
|
||||
end)
|
||||
|
||||
if not ok then
|
||||
local err = sysobj_or_err --[[@as string]]
|
||||
local sfx --- @type string
|
||||
if string.match(err, 'ENOENT') then
|
||||
sfx = '. The language server is either not installed, missing from PATH, or not executable.'
|
||||
else
|
||||
sfx = string.format(' with error message: %s', err)
|
||||
end
|
||||
local msg =
|
||||
string.format('Spawning language server with cmd: `%s` failed%s', vim.inspect(cmd), sfx)
|
||||
error(msg)
|
||||
end
|
||||
|
||||
sysobj = sysobj_or_err --[[@as vim.SystemObj]]
|
||||
local transport = lsp_transport.TransportRun.new()
|
||||
local client = new_client(dispatchers, transport)
|
||||
local on_read = create_client_read_loop(client)
|
||||
transport:run(cmd, extra_spawn_params, on_read, dispatchers.on_exit)
|
||||
|
||||
return public_client(client)
|
||||
end
|
||||
|
@ -600,9 +600,7 @@ function M.start(bufnr, client_id, opts)
|
||||
vim.validate('bufnr', bufnr, 'number')
|
||||
vim.validate('client_id', client_id, 'number')
|
||||
|
||||
if bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
opts = opts or {}
|
||||
assert(
|
||||
@ -655,9 +653,7 @@ function M.stop(bufnr, client_id)
|
||||
vim.validate('bufnr', bufnr, 'number')
|
||||
vim.validate('client_id', client_id, 'number')
|
||||
|
||||
if bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
local highlighter = STHighlighter.active[bufnr]
|
||||
if not highlighter then
|
||||
@ -691,9 +687,7 @@ end
|
||||
--- - modifiers (table) token modifiers as a set. E.g., { static = true, readonly = true }
|
||||
--- - client_id (integer)
|
||||
function M.get_at_pos(bufnr, row, col)
|
||||
if bufnr == nil or bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
local highlighter = STHighlighter.active[bufnr]
|
||||
if not highlighter then
|
||||
@ -739,8 +733,7 @@ function M.force_refresh(bufnr)
|
||||
vim.validate('bufnr', bufnr, 'number', true)
|
||||
|
||||
local buffers = bufnr == nil and vim.tbl_keys(STHighlighter.active)
|
||||
or bufnr == 0 and { api.nvim_get_current_buf() }
|
||||
or { bufnr }
|
||||
or { vim._resolve_bufnr(bufnr) }
|
||||
|
||||
for _, buffer in ipairs(buffers) do
|
||||
local highlighter = STHighlighter.active[buffer]
|
||||
@ -770,9 +763,7 @@ end
|
||||
---@param hl_group (string) Highlight group name
|
||||
---@param opts? vim.lsp.semantic_tokens.highlight_token.Opts Optional parameters:
|
||||
function M.highlight_token(token, bufnr, client_id, hl_group, opts)
|
||||
if bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
local highlighter = STHighlighter.active[bufnr]
|
||||
if not highlighter then
|
||||
return
|
||||
|
@ -48,21 +48,21 @@ local str_utfindex = vim.str_utfindex
|
||||
local str_utf_start = vim.str_utf_start
|
||||
local str_utf_end = vim.str_utf_end
|
||||
|
||||
-- Given a line, byte idx, alignment, and offset_encoding convert to the aligned
|
||||
-- Given a line, byte idx, alignment, and position_encoding convert to the aligned
|
||||
-- utf-8 index and either the utf-16, or utf-32 index.
|
||||
---@param line string the line to index into
|
||||
---@param byte integer the byte idx
|
||||
---@param offset_encoding string utf-8|utf-16|utf-32|nil (default: utf-8)
|
||||
---@param position_encoding string utf-8|utf-16|utf-32|nil (default: utf-8)
|
||||
---@return integer byte_idx of first change position
|
||||
---@return integer char_idx of first change position
|
||||
local function align_end_position(line, byte, offset_encoding)
|
||||
local function align_end_position(line, byte, position_encoding)
|
||||
local char --- @type integer
|
||||
-- If on the first byte, or an empty string: the trivial case
|
||||
if byte == 1 or #line == 0 then
|
||||
char = byte
|
||||
-- Called in the case of extending an empty line "" -> "a"
|
||||
elseif byte == #line + 1 then
|
||||
char = str_utfindex(line, offset_encoding) + 1
|
||||
char = str_utfindex(line, position_encoding) + 1
|
||||
else
|
||||
-- Modifying line, find the nearest utf codepoint
|
||||
local offset = str_utf_start(line, byte)
|
||||
@ -73,9 +73,9 @@ local function align_end_position(line, byte, offset_encoding)
|
||||
end
|
||||
if byte <= #line then
|
||||
--- Convert to 0 based for input, and from 0 based for output
|
||||
char = str_utfindex(line, offset_encoding, byte - 1) + 1
|
||||
char = str_utfindex(line, position_encoding, byte - 1) + 1
|
||||
else
|
||||
char = str_utfindex(line, offset_encoding) + 1
|
||||
char = str_utfindex(line, position_encoding) + 1
|
||||
end
|
||||
-- Extending line, find the nearest utf codepoint for the last valid character
|
||||
end
|
||||
@ -93,7 +93,7 @@ end
|
||||
---@param firstline integer firstline from on_lines, adjusted to 1-index
|
||||
---@param lastline integer lastline from on_lines, adjusted to 1-index
|
||||
---@param new_lastline integer new_lastline from on_lines, adjusted to 1-index
|
||||
---@param offset_encoding string utf-8|utf-16|utf-32|nil (fallback to utf-8)
|
||||
---@param position_encoding string utf-8|utf-16|utf-32|nil (fallback to utf-8)
|
||||
---@return vim.lsp.sync.Range result table include line_idx, byte_idx, and char_idx of first change position
|
||||
local function compute_start_range(
|
||||
prev_lines,
|
||||
@ -101,7 +101,7 @@ local function compute_start_range(
|
||||
firstline,
|
||||
lastline,
|
||||
new_lastline,
|
||||
offset_encoding
|
||||
position_encoding
|
||||
)
|
||||
local char_idx --- @type integer?
|
||||
local byte_idx --- @type integer?
|
||||
@ -115,7 +115,7 @@ local function compute_start_range(
|
||||
if line then
|
||||
line_idx = firstline - 1
|
||||
byte_idx = #line + 1
|
||||
char_idx = str_utfindex(line, offset_encoding) + 1
|
||||
char_idx = str_utfindex(line, position_encoding) + 1
|
||||
else
|
||||
line_idx = firstline
|
||||
byte_idx = 1
|
||||
@ -152,11 +152,11 @@ local function compute_start_range(
|
||||
char_idx = 1
|
||||
elseif start_byte_idx == #prev_line + 1 then
|
||||
byte_idx = start_byte_idx
|
||||
char_idx = str_utfindex(prev_line, offset_encoding) + 1
|
||||
char_idx = str_utfindex(prev_line, position_encoding) + 1
|
||||
else
|
||||
byte_idx = start_byte_idx + str_utf_start(prev_line, start_byte_idx)
|
||||
--- Convert to 0 based for input, and from 0 based for output
|
||||
char_idx = vim.str_utfindex(prev_line, offset_encoding, byte_idx - 1) + 1
|
||||
char_idx = vim.str_utfindex(prev_line, position_encoding, byte_idx - 1) + 1
|
||||
end
|
||||
|
||||
-- Return the start difference (shared for new and prev lines)
|
||||
@ -174,7 +174,7 @@ end
|
||||
---@param firstline integer
|
||||
---@param lastline integer
|
||||
---@param new_lastline integer
|
||||
---@param offset_encoding string
|
||||
---@param position_encoding string
|
||||
---@return vim.lsp.sync.Range prev_end_range
|
||||
---@return vim.lsp.sync.Range curr_end_range
|
||||
local function compute_end_range(
|
||||
@ -184,7 +184,7 @@ local function compute_end_range(
|
||||
firstline,
|
||||
lastline,
|
||||
new_lastline,
|
||||
offset_encoding
|
||||
position_encoding
|
||||
)
|
||||
-- A special case for the following `firstline == new_lastline` case where lines are deleted.
|
||||
-- Even if the buffer has become empty, nvim behaves as if it has an empty line with eol.
|
||||
@ -193,7 +193,7 @@ local function compute_end_range(
|
||||
return {
|
||||
line_idx = lastline - 1,
|
||||
byte_idx = #prev_line + 1,
|
||||
char_idx = str_utfindex(prev_line, offset_encoding) + 1,
|
||||
char_idx = str_utfindex(prev_line, position_encoding) + 1,
|
||||
}, { line_idx = 1, byte_idx = 1, char_idx = 1 }
|
||||
end
|
||||
-- If firstline == new_lastline, the first change occurred on a line that was deleted.
|
||||
@ -259,7 +259,7 @@ local function compute_end_range(
|
||||
prev_end_byte_idx = 1
|
||||
end
|
||||
local prev_byte_idx, prev_char_idx =
|
||||
align_end_position(prev_line, prev_end_byte_idx, offset_encoding)
|
||||
align_end_position(prev_line, prev_end_byte_idx, position_encoding)
|
||||
local prev_end_range =
|
||||
{ line_idx = prev_line_idx, byte_idx = prev_byte_idx, char_idx = prev_char_idx }
|
||||
|
||||
@ -274,7 +274,7 @@ local function compute_end_range(
|
||||
curr_end_byte_idx = 1
|
||||
end
|
||||
local curr_byte_idx, curr_char_idx =
|
||||
align_end_position(curr_line, curr_end_byte_idx, offset_encoding)
|
||||
align_end_position(curr_line, curr_end_byte_idx, position_encoding)
|
||||
curr_end_range =
|
||||
{ line_idx = curr_line_idx, byte_idx = curr_byte_idx, char_idx = curr_char_idx }
|
||||
end
|
||||
@ -317,7 +317,7 @@ local function extract_text(lines, start_range, end_range, line_ending)
|
||||
end
|
||||
end
|
||||
|
||||
-- rangelength depends on the offset encoding
|
||||
-- rangelength depends on the position encoding
|
||||
-- bytes for utf-8 (clangd with extension)
|
||||
-- codepoints for utf-16
|
||||
-- codeunits for utf-32
|
||||
@ -326,10 +326,10 @@ end
|
||||
---@param lines string[]
|
||||
---@param start_range vim.lsp.sync.Range
|
||||
---@param end_range vim.lsp.sync.Range
|
||||
---@param offset_encoding string
|
||||
---@param position_encoding string
|
||||
---@param line_ending string
|
||||
---@return integer
|
||||
local function compute_range_length(lines, start_range, end_range, offset_encoding, line_ending)
|
||||
local function compute_range_length(lines, start_range, end_range, position_encoding, line_ending)
|
||||
local line_ending_length = #line_ending
|
||||
-- Single line case
|
||||
if start_range.line_idx == end_range.line_idx then
|
||||
@ -339,7 +339,7 @@ local function compute_range_length(lines, start_range, end_range, offset_encodi
|
||||
local start_line = lines[start_range.line_idx]
|
||||
local range_length --- @type integer
|
||||
if start_line and #start_line > 0 then
|
||||
range_length = str_utfindex(start_line, offset_encoding)
|
||||
range_length = str_utfindex(start_line, position_encoding)
|
||||
- start_range.char_idx
|
||||
+ 1
|
||||
+ line_ending_length
|
||||
@ -352,7 +352,7 @@ local function compute_range_length(lines, start_range, end_range, offset_encodi
|
||||
for idx = start_range.line_idx + 1, end_range.line_idx - 1 do
|
||||
-- Length full line plus newline character
|
||||
if #lines[idx] > 0 then
|
||||
range_length = range_length + str_utfindex(lines[idx], offset_encoding) + #line_ending
|
||||
range_length = range_length + str_utfindex(lines[idx], position_encoding) + #line_ending
|
||||
else
|
||||
range_length = range_length + line_ending_length
|
||||
end
|
||||
@ -372,7 +372,7 @@ end
|
||||
---@param firstline integer line to begin search for first difference
|
||||
---@param lastline integer line to begin search in old_lines for last difference
|
||||
---@param new_lastline integer line to begin search in new_lines for last difference
|
||||
---@param offset_encoding string encoding requested by language server
|
||||
---@param position_encoding string encoding requested by language server
|
||||
---@param line_ending string
|
||||
---@return lsp.TextDocumentContentChangeEvent : see https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent
|
||||
function M.compute_diff(
|
||||
@ -381,7 +381,7 @@ function M.compute_diff(
|
||||
firstline,
|
||||
lastline,
|
||||
new_lastline,
|
||||
offset_encoding,
|
||||
position_encoding,
|
||||
line_ending
|
||||
)
|
||||
-- Find the start of changes between the previous and current buffer. Common between both.
|
||||
@ -393,7 +393,7 @@ function M.compute_diff(
|
||||
firstline + 1,
|
||||
lastline + 1,
|
||||
new_lastline + 1,
|
||||
offset_encoding
|
||||
position_encoding
|
||||
)
|
||||
-- Find the last position changed in the previous and current buffer.
|
||||
-- prev_end_range is sent to the server as as the end of the changed range.
|
||||
@ -405,7 +405,7 @@ function M.compute_diff(
|
||||
firstline + 1,
|
||||
lastline + 1,
|
||||
new_lastline + 1,
|
||||
offset_encoding
|
||||
position_encoding
|
||||
)
|
||||
|
||||
-- Grab the changed text of from start_range to curr_end_range in the current buffer.
|
||||
@ -414,7 +414,7 @@ function M.compute_diff(
|
||||
|
||||
-- Compute the range of the replaced text. Deprecated but still required for certain language servers
|
||||
local range_length =
|
||||
compute_range_length(prev_lines, start_range, prev_end_range, offset_encoding, line_ending)
|
||||
compute_range_length(prev_lines, start_range, prev_end_range, position_encoding, line_ending)
|
||||
|
||||
-- convert to 0 based indexing
|
||||
local result = {
|
||||
|
@ -192,9 +192,7 @@ local function get_lines(bufnr, rows)
|
||||
rows = type(rows) == 'table' and rows or { rows }
|
||||
|
||||
-- This is needed for bufload and bufloaded
|
||||
if bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
local function buf_lines()
|
||||
local lines = {} --- @type table<integer,string>
|
||||
@ -277,9 +275,9 @@ end
|
||||
|
||||
--- Position is a https://microsoft.github.io/language-server-protocol/specifications/specification-current/#position
|
||||
---@param position lsp.Position
|
||||
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@return integer
|
||||
local function get_line_byte_from_position(bufnr, position, offset_encoding)
|
||||
local function get_line_byte_from_position(bufnr, position, position_encoding)
|
||||
-- LSP's line and characters are 0-indexed
|
||||
-- Vim's line and columns are 1-indexed
|
||||
local col = position.character
|
||||
@ -287,7 +285,7 @@ local function get_line_byte_from_position(bufnr, position, offset_encoding)
|
||||
-- character
|
||||
if col > 0 then
|
||||
local line = get_line(bufnr, position.line) or ''
|
||||
return vim.str_byteindex(line, offset_encoding, col, false)
|
||||
return vim.str_byteindex(line, position_encoding, col, false)
|
||||
end
|
||||
return col
|
||||
end
|
||||
@ -295,12 +293,12 @@ end
|
||||
--- Applies a list of text edits to a buffer.
|
||||
---@param text_edits lsp.TextEdit[]
|
||||
---@param bufnr integer Buffer id
|
||||
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit
|
||||
function M.apply_text_edits(text_edits, bufnr, offset_encoding)
|
||||
function M.apply_text_edits(text_edits, bufnr, position_encoding)
|
||||
validate('text_edits', text_edits, 'table', false)
|
||||
validate('bufnr', bufnr, 'number', false)
|
||||
validate('offset_encoding', offset_encoding, 'string', false)
|
||||
validate('position_encoding', position_encoding, 'string', false)
|
||||
|
||||
if not next(text_edits) then
|
||||
return
|
||||
@ -359,9 +357,9 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
|
||||
|
||||
-- Convert from LSP style ranges to Neovim style ranges.
|
||||
local start_row = text_edit.range.start.line
|
||||
local start_col = get_line_byte_from_position(bufnr, text_edit.range.start, offset_encoding)
|
||||
local start_col = get_line_byte_from_position(bufnr, text_edit.range.start, position_encoding)
|
||||
local end_row = text_edit.range['end'].line
|
||||
local end_col = get_line_byte_from_position(bufnr, text_edit.range['end'], offset_encoding)
|
||||
local end_col = get_line_byte_from_position(bufnr, text_edit.range['end'], position_encoding)
|
||||
local text = vim.split(text_edit.newText, '\n', { plain = true })
|
||||
|
||||
local max = api.nvim_buf_line_count(bufnr)
|
||||
@ -430,14 +428,14 @@ end
|
||||
---
|
||||
---@param text_document_edit lsp.TextDocumentEdit
|
||||
---@param index? integer: Optional index of the edit, if from a list of edits (or nil, if not from a list)
|
||||
---@param offset_encoding? 'utf-8'|'utf-16'|'utf-32'
|
||||
---@param position_encoding? 'utf-8'|'utf-16'|'utf-32'
|
||||
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit
|
||||
function M.apply_text_document_edit(text_document_edit, index, offset_encoding)
|
||||
function M.apply_text_document_edit(text_document_edit, index, position_encoding)
|
||||
local text_document = text_document_edit.textDocument
|
||||
local bufnr = vim.uri_to_bufnr(text_document.uri)
|
||||
if offset_encoding == nil then
|
||||
if position_encoding == nil then
|
||||
vim.notify_once(
|
||||
'apply_text_document_edit must be called with valid offset encoding',
|
||||
'apply_text_document_edit must be called with valid position encoding',
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
return
|
||||
@ -459,7 +457,7 @@ function M.apply_text_document_edit(text_document_edit, index, offset_encoding)
|
||||
return
|
||||
end
|
||||
|
||||
M.apply_text_edits(text_document_edit.edits, bufnr, offset_encoding)
|
||||
M.apply_text_edits(text_document_edit.edits, bufnr, position_encoding)
|
||||
end
|
||||
|
||||
local function path_components(path)
|
||||
@ -619,12 +617,12 @@ end
|
||||
--- Applies a `WorkspaceEdit`.
|
||||
---
|
||||
---@param workspace_edit lsp.WorkspaceEdit
|
||||
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32' (required)
|
||||
---@param position_encoding 'utf-8'|'utf-16'|'utf-32' (required)
|
||||
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit
|
||||
function M.apply_workspace_edit(workspace_edit, offset_encoding)
|
||||
if offset_encoding == nil then
|
||||
function M.apply_workspace_edit(workspace_edit, position_encoding)
|
||||
if position_encoding == nil then
|
||||
vim.notify_once(
|
||||
'apply_workspace_edit must be called with valid offset encoding',
|
||||
'apply_workspace_edit must be called with valid position encoding',
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
return
|
||||
@ -641,7 +639,7 @@ function M.apply_workspace_edit(workspace_edit, offset_encoding)
|
||||
elseif change.kind then --- @diagnostic disable-line:undefined-field
|
||||
error(string.format('Unsupported change: %q', vim.inspect(change)))
|
||||
else
|
||||
M.apply_text_document_edit(change, idx, offset_encoding)
|
||||
M.apply_text_document_edit(change, idx, position_encoding)
|
||||
end
|
||||
end
|
||||
return
|
||||
@ -654,7 +652,7 @@ function M.apply_workspace_edit(workspace_edit, offset_encoding)
|
||||
|
||||
for uri, changes in pairs(all_changes) do
|
||||
local bufnr = vim.uri_to_bufnr(uri)
|
||||
M.apply_text_edits(changes, bufnr, offset_encoding)
|
||||
M.apply_text_edits(changes, bufnr, position_encoding)
|
||||
end
|
||||
end
|
||||
|
||||
@ -904,17 +902,20 @@ end
|
||||
--- Shows document and optionally jumps to the location.
|
||||
---
|
||||
---@param location lsp.Location|lsp.LocationLink
|
||||
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'?
|
||||
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'?
|
||||
---@param opts? vim.lsp.util.show_document.Opts
|
||||
---@return boolean `true` if succeeded
|
||||
function M.show_document(location, offset_encoding, opts)
|
||||
function M.show_document(location, position_encoding, opts)
|
||||
-- location may be Location or LocationLink
|
||||
local uri = location.uri or location.targetUri
|
||||
if uri == nil then
|
||||
return false
|
||||
end
|
||||
if offset_encoding == nil then
|
||||
vim.notify_once('show_document must be called with valid offset encoding', vim.log.levels.WARN)
|
||||
if position_encoding == nil then
|
||||
vim.notify_once(
|
||||
'show_document must be called with valid position encoding',
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
return false
|
||||
end
|
||||
local bufnr = vim.uri_to_bufnr(uri)
|
||||
@ -946,7 +947,7 @@ function M.show_document(location, offset_encoding, opts)
|
||||
if range then
|
||||
-- Jump to new location (adjusting for encoding of characters)
|
||||
local row = range.start.line
|
||||
local col = get_line_byte_from_position(bufnr, range.start, offset_encoding)
|
||||
local col = get_line_byte_from_position(bufnr, range.start, position_encoding)
|
||||
api.nvim_win_set_cursor(win, { row + 1, col })
|
||||
vim._with({ win = win }, function()
|
||||
-- Open folds under the cursor
|
||||
@ -961,12 +962,12 @@ end
|
||||
---
|
||||
---@deprecated use `vim.lsp.util.show_document` with `{focus=true}` instead
|
||||
---@param location lsp.Location|lsp.LocationLink
|
||||
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'?
|
||||
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'?
|
||||
---@param reuse_win boolean? Jump to existing window if buffer is already open.
|
||||
---@return boolean `true` if the jump succeeded
|
||||
function M.jump_to_location(location, offset_encoding, reuse_win)
|
||||
function M.jump_to_location(location, position_encoding, reuse_win)
|
||||
vim.deprecate('vim.lsp.util.jump_to_location', nil, '0.12')
|
||||
return M.show_document(location, offset_encoding, { reuse_win = reuse_win, focus = true })
|
||||
return M.show_document(location, position_encoding, { reuse_win = reuse_win, focus = true })
|
||||
end
|
||||
|
||||
--- Previews a location in a floating window
|
||||
@ -1661,18 +1662,18 @@ do --[[ References ]]
|
||||
---
|
||||
---@param bufnr integer Buffer id
|
||||
---@param references lsp.DocumentHighlight[] objects to highlight
|
||||
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@see https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent
|
||||
function M.buf_highlight_references(bufnr, references, offset_encoding)
|
||||
function M.buf_highlight_references(bufnr, references, position_encoding)
|
||||
validate('bufnr', bufnr, 'number', true)
|
||||
validate('offset_encoding', offset_encoding, 'string', false)
|
||||
validate('position_encoding', position_encoding, 'string', false)
|
||||
for _, reference in ipairs(references) do
|
||||
local range = reference.range
|
||||
local start_line = range.start.line
|
||||
local end_line = range['end'].line
|
||||
|
||||
local start_idx = get_line_byte_from_position(bufnr, range.start, offset_encoding)
|
||||
local end_idx = get_line_byte_from_position(bufnr, range['end'], offset_encoding)
|
||||
local start_idx = get_line_byte_from_position(bufnr, range.start, position_encoding)
|
||||
local end_idx = get_line_byte_from_position(bufnr, range['end'], position_encoding)
|
||||
|
||||
local document_highlight_kind = {
|
||||
[protocol.DocumentHighlightKind.Text] = 'LspReferenceText',
|
||||
@ -1706,16 +1707,16 @@ end)
|
||||
--- |setloclist()|.
|
||||
---
|
||||
---@param locations lsp.Location[]|lsp.LocationLink[]
|
||||
---@param offset_encoding? 'utf-8'|'utf-16'|'utf-32'
|
||||
---@param position_encoding? 'utf-8'|'utf-16'|'utf-32'
|
||||
--- default to first client of buffer
|
||||
---@return vim.quickfix.entry[] # See |setqflist()| for the format
|
||||
function M.locations_to_items(locations, offset_encoding)
|
||||
if offset_encoding == nil then
|
||||
function M.locations_to_items(locations, position_encoding)
|
||||
if position_encoding == nil then
|
||||
vim.notify_once(
|
||||
'locations_to_items must be called with valid offset encoding',
|
||||
'locations_to_items must be called with valid position encoding',
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
offset_encoding = vim.lsp.get_clients({ bufnr = 0 })[1].offset_encoding
|
||||
position_encoding = vim.lsp.get_clients({ bufnr = 0 })[1].offset_encoding
|
||||
end
|
||||
|
||||
local items = {} --- @type vim.quickfix.entry[]
|
||||
@ -1752,8 +1753,8 @@ function M.locations_to_items(locations, offset_encoding)
|
||||
local end_row = end_pos.line
|
||||
local line = lines[row] or ''
|
||||
local end_line = lines[end_row] or ''
|
||||
local col = vim.str_byteindex(line, offset_encoding, pos.character, false)
|
||||
local end_col = vim.str_byteindex(end_line, offset_encoding, end_pos.character, false)
|
||||
local col = vim.str_byteindex(line, position_encoding, pos.character, false)
|
||||
local end_col = vim.str_byteindex(end_line, position_encoding, end_pos.character, false)
|
||||
|
||||
items[#items + 1] = {
|
||||
filename = filename,
|
||||
@ -1864,8 +1865,8 @@ function M.try_trim_markdown_code_blocks(lines)
|
||||
end
|
||||
|
||||
---@param window integer?: window handle or 0 for current, defaults to current
|
||||
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
local function make_position_param(window, offset_encoding)
|
||||
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
local function make_position_param(window, position_encoding)
|
||||
window = window or 0
|
||||
local buf = api.nvim_win_get_buf(window)
|
||||
local row, col = unpack(api.nvim_win_get_cursor(window))
|
||||
@ -1875,7 +1876,7 @@ local function make_position_param(window, offset_encoding)
|
||||
return { line = 0, character = 0 }
|
||||
end
|
||||
|
||||
col = vim.str_utfindex(line, offset_encoding, col, false)
|
||||
col = vim.str_utfindex(line, position_encoding, col, false)
|
||||
|
||||
return { line = row, character = col }
|
||||
end
|
||||
@ -1883,22 +1884,22 @@ end
|
||||
--- Creates a `TextDocumentPositionParams` object for the current buffer and cursor position.
|
||||
---
|
||||
---@param window integer?: window handle or 0 for current, defaults to current
|
||||
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@return lsp.TextDocumentPositionParams
|
||||
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams
|
||||
function M.make_position_params(window, offset_encoding)
|
||||
function M.make_position_params(window, position_encoding)
|
||||
window = window or 0
|
||||
local buf = api.nvim_win_get_buf(window)
|
||||
if offset_encoding == nil then
|
||||
if position_encoding == nil then
|
||||
vim.notify_once(
|
||||
'warning: offset_encoding is required, using the offset_encoding from the first client',
|
||||
'position_encoding param is required in vim.lsp.util.make_position_params. Defaulting to position encoding of the first client.',
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
offset_encoding = M._get_offset_encoding(buf)
|
||||
position_encoding = M._get_offset_encoding(buf)
|
||||
end
|
||||
return {
|
||||
textDocument = M.make_text_document_params(buf),
|
||||
position = make_position_param(window, offset_encoding),
|
||||
position = make_position_param(window, position_encoding),
|
||||
}
|
||||
end
|
||||
|
||||
@ -1941,18 +1942,18 @@ end
|
||||
--- `textDocument/rangeFormatting`.
|
||||
---
|
||||
---@param window integer? window handle or 0 for current, defaults to current
|
||||
---@param offset_encoding "utf-8"|"utf-16"|"utf-32"
|
||||
---@param position_encoding "utf-8"|"utf-16"|"utf-32"
|
||||
---@return { textDocument: { uri: lsp.DocumentUri }, range: lsp.Range }
|
||||
function M.make_range_params(window, offset_encoding)
|
||||
function M.make_range_params(window, position_encoding)
|
||||
local buf = api.nvim_win_get_buf(window or 0)
|
||||
if offset_encoding == nil then
|
||||
if position_encoding == nil then
|
||||
vim.notify_once(
|
||||
'warning: offset_encoding is required, using the offset_encoding from the first client',
|
||||
'position_encoding param is required in vim.lsp.util.make_range_params. Defaulting to position encoding of the first client.',
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
offset_encoding = M._get_offset_encoding(buf)
|
||||
position_encoding = M._get_offset_encoding(buf)
|
||||
end
|
||||
local position = make_position_param(window, offset_encoding)
|
||||
local position = make_position_param(window, position_encoding)
|
||||
return {
|
||||
textDocument = M.make_text_document_params(buf),
|
||||
range = { start = position, ['end'] = position },
|
||||
@ -1967,19 +1968,19 @@ end
|
||||
---@param end_pos [integer,integer]? {row,col} mark-indexed position.
|
||||
--- Defaults to the end of the last visual selection.
|
||||
---@param bufnr integer? buffer handle or 0 for current, defaults to current
|
||||
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@return { textDocument: { uri: lsp.DocumentUri }, range: lsp.Range }
|
||||
function M.make_given_range_params(start_pos, end_pos, bufnr, offset_encoding)
|
||||
function M.make_given_range_params(start_pos, end_pos, bufnr, position_encoding)
|
||||
validate('start_pos', start_pos, 'table', true)
|
||||
validate('end_pos', end_pos, 'table', true)
|
||||
validate('offset_encoding', offset_encoding, 'string', true)
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
if offset_encoding == nil then
|
||||
validate('position_encoding', position_encoding, 'string', true)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
if position_encoding == nil then
|
||||
vim.notify_once(
|
||||
'warning: offset_encoding is required, using the offset_encoding from the first client',
|
||||
'position_encoding param is required in vim.lsp.util.make_given_range_params. Defaulting to position encoding of the first client.',
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
offset_encoding = M._get_offset_encoding(bufnr)
|
||||
position_encoding = M._get_offset_encoding(bufnr)
|
||||
end
|
||||
--- @type [integer, integer]
|
||||
local A = { unpack(start_pos or api.nvim_buf_get_mark(bufnr, '<')) }
|
||||
@ -1988,12 +1989,12 @@ function M.make_given_range_params(start_pos, end_pos, bufnr, offset_encoding)
|
||||
-- convert to 0-index
|
||||
A[1] = A[1] - 1
|
||||
B[1] = B[1] - 1
|
||||
-- account for offset_encoding.
|
||||
-- account for position_encoding.
|
||||
if A[2] > 0 then
|
||||
A[2] = M.character_offset(bufnr, A[1], A[2], offset_encoding)
|
||||
A[2] = M.character_offset(bufnr, A[1], A[2], position_encoding)
|
||||
end
|
||||
if B[2] > 0 then
|
||||
B[2] = M.character_offset(bufnr, B[1], B[2], offset_encoding)
|
||||
B[2] = M.character_offset(bufnr, B[1], B[2], position_encoding)
|
||||
end
|
||||
-- we need to offset the end character position otherwise we loose the last
|
||||
-- character of the selection, as LSP end position is exclusive
|
||||
@ -2100,9 +2101,9 @@ end
|
||||
---@param bufnr integer
|
||||
---@param start_line integer
|
||||
---@param end_line integer
|
||||
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
|
||||
---@return lsp.Range
|
||||
local function make_line_range_params(bufnr, start_line, end_line, offset_encoding)
|
||||
local function make_line_range_params(bufnr, start_line, end_line, position_encoding)
|
||||
local last_line = api.nvim_buf_line_count(bufnr) - 1
|
||||
|
||||
---@type lsp.Position
|
||||
@ -2111,7 +2112,12 @@ local function make_line_range_params(bufnr, start_line, end_line, offset_encodi
|
||||
if end_line == last_line and not vim.bo[bufnr].endofline then
|
||||
end_pos = {
|
||||
line = end_line,
|
||||
character = M.character_offset(bufnr, end_line, #get_line(bufnr, end_line), offset_encoding),
|
||||
character = M.character_offset(
|
||||
bufnr,
|
||||
end_line,
|
||||
#get_line(bufnr, end_line),
|
||||
position_encoding
|
||||
),
|
||||
}
|
||||
else
|
||||
end_pos = { line = end_line + 1, character = 0 }
|
||||
@ -2135,10 +2141,7 @@ end
|
||||
---@param opts? vim.lsp.util._refresh.Opts Options table
|
||||
function M._refresh(method, opts)
|
||||
opts = opts or {}
|
||||
local bufnr = opts.bufnr
|
||||
if bufnr == nil or bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
local bufnr = vim._resolve_bufnr(opts.bufnr)
|
||||
|
||||
local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method, id = opts.client_id })
|
||||
|
||||
@ -2154,6 +2157,11 @@ function M._refresh(method, opts)
|
||||
local first = vim.fn.line('w0', window)
|
||||
local last = vim.fn.line('w$', window)
|
||||
for _, client in ipairs(clients) do
|
||||
for rid, req in pairs(client.requests) do
|
||||
if req.method == method and req.type == 'pending' and req.bufnr == bufnr then
|
||||
client:cancel_request(rid)
|
||||
end
|
||||
end
|
||||
client:request(method, {
|
||||
textDocument = textDocument,
|
||||
range = make_line_range_params(bufnr, first - 1, last - 1, client.offset_encoding),
|
||||
|
@ -737,6 +737,51 @@ function vim.list_slice(list, start, finish)
|
||||
return new_list
|
||||
end
|
||||
|
||||
--- Efficiently insert items into the middle of a list.
|
||||
---
|
||||
--- Calling table.insert() in a loop will re-index the tail of the table on
|
||||
--- every iteration, instead this function will re-index the table exactly
|
||||
--- once.
|
||||
---
|
||||
--- Based on https://stackoverflow.com/questions/12394841/safely-remove-items-from-an-array-table-while-iterating/53038524#53038524
|
||||
---
|
||||
---@param t any[]
|
||||
---@param first integer
|
||||
---@param last integer
|
||||
---@param v any
|
||||
function vim._list_insert(t, first, last, v)
|
||||
local n = #t
|
||||
|
||||
-- Shift table forward
|
||||
for i = n - first, 0, -1 do
|
||||
t[last + 1 + i] = t[first + i]
|
||||
end
|
||||
|
||||
-- Fill in new values
|
||||
for i = first, last do
|
||||
t[i] = v
|
||||
end
|
||||
end
|
||||
|
||||
--- Efficiently remove items from middle of a list.
|
||||
---
|
||||
--- Calling table.remove() in a loop will re-index the tail of the table on
|
||||
--- every iteration, instead this function will re-index the table exactly
|
||||
--- once.
|
||||
---
|
||||
--- Based on https://stackoverflow.com/questions/12394841/safely-remove-items-from-an-array-table-while-iterating/53038524#53038524
|
||||
---
|
||||
---@param t any[]
|
||||
---@param first integer
|
||||
---@param last integer
|
||||
function vim._list_remove(t, first, last)
|
||||
local n = #t
|
||||
for i = 0, n - first do
|
||||
t[first + i] = t[last + 1 + i]
|
||||
t[last + 1 + i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Trim whitespace (Lua pattern "%s") from both sides of a string.
|
||||
---
|
||||
---@see |lua-patterns|
|
||||
@ -968,7 +1013,7 @@ do
|
||||
--- best performance.
|
||||
---
|
||||
--- @param name string Argument name
|
||||
--- @param value string Argument value
|
||||
--- @param value any Argument value
|
||||
--- @param validator vim.validate.Validator
|
||||
--- - (`string|string[]`): Any value that can be returned from |lua-type()| in addition to
|
||||
--- `'callable'`: `'boolean'`, `'callable'`, `'function'`, `'nil'`, `'number'`, `'string'`, `'table'`,
|
||||
@ -1354,4 +1399,24 @@ function vim._with(context, f)
|
||||
return vim._with_c(context, callback)
|
||||
end
|
||||
|
||||
--- @param bufnr? integer
|
||||
--- @return integer
|
||||
function vim._resolve_bufnr(bufnr)
|
||||
if bufnr == nil or bufnr == 0 then
|
||||
return vim.api.nvim_get_current_buf()
|
||||
end
|
||||
vim.validate('bufnr', bufnr, 'number')
|
||||
return bufnr
|
||||
end
|
||||
|
||||
--- @generic T
|
||||
--- @param x elem_or_list<T>?
|
||||
--- @return T[]
|
||||
function vim._ensure_list(x)
|
||||
if type(x) == 'table' then
|
||||
return x
|
||||
end
|
||||
return { x }
|
||||
end
|
||||
|
||||
return vim
|
||||
|
@ -2,6 +2,18 @@
|
||||
|
||||
local M = {}
|
||||
|
||||
local alphabet = '0123456789ABCDEF'
|
||||
local atoi = {} ---@type table<string, integer>
|
||||
local itoa = {} ---@type table<integer, string>
|
||||
do
|
||||
for i = 1, #alphabet do
|
||||
local char = alphabet:sub(i, i)
|
||||
itoa[i - 1] = char
|
||||
atoi[char] = i - 1
|
||||
atoi[char:lower()] = i - 1
|
||||
end
|
||||
end
|
||||
|
||||
--- Hex encode a string.
|
||||
---
|
||||
--- @param str string String to encode
|
||||
@ -9,7 +21,9 @@ local M = {}
|
||||
function M.hexencode(str)
|
||||
local enc = {} ---@type string[]
|
||||
for i = 1, #str do
|
||||
enc[i] = string.format('%02X', str:byte(i, i + 1))
|
||||
local byte = str:byte(i)
|
||||
enc[2 * i - 1] = itoa[math.floor(byte / 16)]
|
||||
enc[2 * i] = itoa[byte % 16]
|
||||
end
|
||||
return table.concat(enc)
|
||||
end
|
||||
@ -26,8 +40,12 @@ function M.hexdecode(enc)
|
||||
|
||||
local str = {} ---@type string[]
|
||||
for i = 1, #enc, 2 do
|
||||
local n = assert(tonumber(enc:sub(i, i + 1), 16))
|
||||
str[#str + 1] = string.char(n)
|
||||
local u = atoi[enc:sub(i, i)]
|
||||
local l = atoi[enc:sub(i + 1, i + 1)]
|
||||
if not u or not l then
|
||||
return nil, 'string must contain only hex characters'
|
||||
end
|
||||
str[(i + 1) / 2] = string.char(u * 16 + l)
|
||||
end
|
||||
return table.concat(str), nil
|
||||
end
|
||||
|
@ -32,9 +32,7 @@ M.minimum_language_version = vim._ts_get_minimum_language_version()
|
||||
---
|
||||
---@return vim.treesitter.LanguageTree object to use for parsing
|
||||
function M._create_parser(bufnr, lang, opts)
|
||||
if bufnr == 0 then
|
||||
bufnr = vim.api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
vim.fn.bufload(bufnr)
|
||||
|
||||
@ -90,9 +88,7 @@ function M.get_parser(bufnr, lang, opts)
|
||||
opts = opts or {}
|
||||
local should_error = opts.error == nil or opts.error
|
||||
|
||||
if bufnr == nil or bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
if not valid_lang(lang) then
|
||||
lang = M.language.get_lang(vim.bo[bufnr].filetype)
|
||||
@ -249,18 +245,17 @@ end
|
||||
|
||||
--- Returns a list of highlight captures at the given position
|
||||
---
|
||||
--- Each capture is represented by a table containing the capture name as a string as
|
||||
--- well as a table of metadata (`priority`, `conceal`, ...; empty if none are defined).
|
||||
--- Each capture is represented by a table containing the capture name as a string, the capture's
|
||||
--- language, a table of metadata (`priority`, `conceal`, ...; empty if none are defined), and the
|
||||
--- id of the capture.
|
||||
---
|
||||
---@param bufnr integer Buffer number (0 for current buffer)
|
||||
---@param row integer Position row
|
||||
---@param col integer Position column
|
||||
---
|
||||
---@return {capture: string, lang: string, metadata: vim.treesitter.query.TSMetadata}[]
|
||||
---@return {capture: string, lang: string, metadata: vim.treesitter.query.TSMetadata, id: integer}[]
|
||||
function M.get_captures_at_pos(bufnr, row, col)
|
||||
if bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
local buf_highlighter = M.highlighter.active[bufnr]
|
||||
|
||||
if not buf_highlighter then
|
||||
@ -291,12 +286,15 @@ function M.get_captures_at_pos(bufnr, row, col)
|
||||
|
||||
local iter = q:query():iter_captures(root, buf_highlighter.bufnr, row, row + 1)
|
||||
|
||||
for capture, node, metadata in iter do
|
||||
for id, node, metadata in iter do
|
||||
if M.is_in_node_range(node, row, col) then
|
||||
---@diagnostic disable-next-line: invisible
|
||||
local c = q._query.captures[capture] -- name of the capture in the query
|
||||
if c ~= nil then
|
||||
table.insert(matches, { capture = c, metadata = metadata, lang = tree:lang() })
|
||||
local capture = q._query.captures[id] -- name of the capture in the query
|
||||
if capture ~= nil then
|
||||
table.insert(
|
||||
matches,
|
||||
{ capture = capture, metadata = metadata, lang = tree:lang(), id = id }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -361,11 +359,7 @@ end
|
||||
function M.get_node(opts)
|
||||
opts = opts or {}
|
||||
|
||||
local bufnr = opts.bufnr
|
||||
|
||||
if not bufnr or bufnr == 0 then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
local bufnr = vim._resolve_bufnr(opts.bufnr)
|
||||
|
||||
local row, col --- @type integer, integer
|
||||
if opts.pos then
|
||||
@ -417,7 +411,7 @@ end
|
||||
---@param bufnr (integer|nil) Buffer to be highlighted (default: current buffer)
|
||||
---@param lang (string|nil) Language of the parser (default: from buffer filetype)
|
||||
function M.start(bufnr, lang)
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
local parser = assert(M.get_parser(bufnr, lang, { error = false }))
|
||||
M.highlighter.new(parser)
|
||||
end
|
||||
@ -426,7 +420,7 @@ end
|
||||
---
|
||||
---@param bufnr (integer|nil) Buffer to stop highlighting (default: current buffer)
|
||||
function M.stop(bufnr)
|
||||
bufnr = (bufnr and bufnr ~= 0) and bufnr or api.nvim_get_current_buf()
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
|
||||
if M.highlighter.active[bufnr] then
|
||||
M.highlighter.active[bufnr]:destroy()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user