aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.ci/clang.sh43
-rw-r--r--.travis.yml10
-rw-r--r--CMakeLists.txt20
-rw-r--r--README.md4
-rw-r--r--runtime/autoload/remote/host.vim14
-rw-r--r--runtime/colors/darkblue.vim1
-rw-r--r--runtime/colors/delek.vim1
-rw-r--r--runtime/colors/desert.vim2
-rw-r--r--runtime/colors/evening.vim1
-rw-r--r--runtime/colors/morning.vim1
-rw-r--r--runtime/colors/peachpuff.vim1
-rw-r--r--runtime/colors/shine.vim1
-rw-r--r--runtime/colors/slate.vim1
-rw-r--r--runtime/doc/change.txt8
-rw-r--r--runtime/doc/eval.txt9
-rw-r--r--runtime/doc/gui.txt34
-rw-r--r--runtime/doc/gui_w32.txt6
-rw-r--r--runtime/doc/gui_x11.txt528
-rw-r--r--runtime/doc/help.txt3
-rw-r--r--runtime/doc/if_cscop.txt3
-rw-r--r--runtime/doc/message.txt2
-rw-r--r--runtime/doc/nvim_clipboard.txt29
-rw-r--r--runtime/doc/nvim_python.txt13
-rw-r--r--runtime/doc/options.txt23
-rw-r--r--runtime/doc/os_dos.txt20
-rw-r--r--runtime/doc/os_win32.txt108
-rw-r--r--runtime/doc/pi_netrw.txt2
-rw-r--r--runtime/doc/quickref.txt6
-rw-r--r--runtime/doc/syntax.txt3
-rw-r--r--runtime/doc/tips.txt7
-rw-r--r--runtime/doc/todo.txt29
-rw-r--r--runtime/doc/usr_21.txt7
-rw-r--r--runtime/doc/various.txt4
-rw-r--r--runtime/doc/vim_diff.txt4
-rw-r--r--runtime/optwin.vim2
-rw-r--r--src/nvim/CMakeLists.txt19
-rw-r--r--src/nvim/eval.c31
-rw-r--r--src/nvim/ex_cmds2.c8
-rw-r--r--src/nvim/lib/klist.h35
-rw-r--r--src/nvim/main.c1
-rw-r--r--src/nvim/memory.h1
-rw-r--r--src/nvim/msgpack_rpc/channel.c20
-rw-r--r--src/nvim/normal.c5
-rw-r--r--src/nvim/ops.c2
-rw-r--r--src/nvim/option.c5
-rw-r--r--src/nvim/option_defs.h1
-rw-r--r--src/nvim/os/event.c7
-rw-r--r--src/nvim/os/fs.c33
-rw-r--r--src/nvim/os/input.c31
-rw-r--r--src/nvim/os/job.c6
-rw-r--r--src/nvim/os/rstream.c211
-rw-r--r--src/nvim/os/rstream.h1
-rw-r--r--src/nvim/os/rstream_defs.h7
-rw-r--r--src/nvim/os/shell.c29
-rw-r--r--src/nvim/rbuffer.c205
-rw-r--r--src/nvim/rbuffer.h83
-rw-r--r--src/nvim/spell.c2
-rw-r--r--src/nvim/testdir/test86.in3
-rw-r--r--src/nvim/testdir/test87.in5
-rw-r--r--src/nvim/tui/term_input.inl55
-rw-r--r--test/functional/clipboard/clipboard_provider_spec.lua6
-rw-r--r--test/unit/buffer_spec.lua2
-rw-r--r--test/unit/fixtures/rbuffer.c28
-rw-r--r--test/unit/fixtures/rbuffer.h9
-rw-r--r--test/unit/helpers.lua7
-rw-r--r--test/unit/os/env_spec.lua3
-rw-r--r--test/unit/rbuffer_spec.lua350
-rw-r--r--test/unit/tempfile_spec.lua2
68 files changed, 1012 insertions, 1151 deletions
diff --git a/.ci/clang.sh b/.ci/clang.sh
index b2d9dd3a7a..70ed7d4764 100644
--- a/.ci/clang.sh
+++ b/.ci/clang.sh
@@ -2,26 +2,36 @@
sudo pip install cpp-coveralls
-# Use custom Clang and enable ASAN on Linux.
+# Use custom Clang and enable sanitizers on Linux.
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
- clang_version=3.4.2
- clang_suffix=x86_64-unknown-ubuntu12.04.xz
- if [ ! -d /usr/local/clang-$clang_version ]; then
- echo "Downloading clang $clang_version..."
- sudo mkdir /usr/local/clang-$clang_version
- wget -q -O - http://llvm.org/releases/$clang_version/clang+llvm-$clang_version-$clang_suffix \
- | sudo tar xJf - --strip-components=1 -C /usr/local/clang-$clang_version
+ if [ -z "$CLANG_SANITIZER" ]; then
+ echo "CLANG_SANITIZER not set."
+ exit 1
fi
- export CC=/usr/local/clang-$clang_version/bin/clang
- symbolizer=/usr/local/clang-$clang_version/bin/llvm-symbolizer
+
+ clang_version=3.6
+ echo "Installing Clang $clang_version..."
+
+ sudo add-apt-repository "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu precise main"
+ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA9EF27F
+
+ sudo add-apt-repository "deb http://llvm.org/apt/precise/ llvm-toolchain-precise-$clang_version main"
+ wget -q -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
+
+ sudo apt-get update -qq
+ sudo apt-get install -y -q clang-$clang_version
+
+ export CC=/usr/bin/clang-$clang_version
+ symbolizer=/usr/bin/llvm-symbolizer-$clang_version
export ASAN_SYMBOLIZER_PATH=$symbolizer
+ export MSAN_SYMBOLIZER_PATH=$symbolizer
export ASAN_OPTIONS="detect_leaks=1:log_path=$tmpdir/asan"
- export TSAN_OPTIONS="external_symbolizer_path=$symbolizer:log_path=$tmpdir/tsan"
+ export TSAN_OPTIONS="external_symbolizer_path=$symbolizer log_path=$tmpdir/tsan"
export UBSAN_OPTIONS="log_path=$tmpdir/ubsan" # not sure if this works
CMAKE_EXTRA_FLAGS="-DTRAVIS_CI_BUILD=ON \
-DUSE_GCOV=ON \
-DBUSTED_OUTPUT_TYPE=plainTerminal \
- -DSANITIZE=ON"
+ -DCLANG_${CLANG_SANITIZER}=ON"
else
CMAKE_EXTRA_FLAGS="-DTRAVIS_CI_BUILD=ON \
-DUSE_GCOV=ON \
@@ -38,11 +48,14 @@ build/bin/nvim --version
make unittest
# Run functional tests.
-if ! $MAKE_CMD test; then
+# FIXME (fwalch): Disabled for MSAN because of SIGPIPE error.
+if [ "$TRAVIS_OS_NAME" = linux ] && ! [ "$CLANG_SANITIZER" = MSAN ]; then
+ if ! $MAKE_CMD test; then
+ asan_check "$tmpdir"
+ exit 1
+ fi
asan_check "$tmpdir"
- exit 1
fi
-asan_check "$tmpdir"
# Run legacy tests.
if ! $MAKE_CMD oldtest; then
diff --git a/.travis.yml b/.travis.yml
index fb4c69c21b..509b13eec8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,13 +20,19 @@ env:
# Force verification of DLOG macros.
- CFLAGS='-DMIN_LOG_LEVEL=0'
matrix:
- - CI_TARGET=clang
- CI_TARGET=gcc
- CI_TARGET=gcc-32
- CI_TARGET=clint
- CI_TARGET=mingw
matrix:
include:
+ - os: linux
+ env: CI_TARGET=clang CLANG_SANITIZER=ASAN_UBSAN
+ - os: linux
+ env: CI_TARGET=clang CLANG_SANITIZER=MSAN
+ # FIXME: Re-enable TSan when tests run successfully.
+ #- os: linux
+ # env: CI_TARGET=clang CLANG_SANITIZER=TSAN
- os: osx
env: CI_TARGET=clang
compiler: clang
@@ -34,6 +40,8 @@ matrix:
env: CI_TARGET=gcc
compiler: gcc-4.9
fast_finish: true
+ allow_failures:
+ - env: CI_TARGET=clang CLANG_SANITIZER=MSAN
before_install:
# Pins the version of the java package installed on the Travis VMs
# and avoids a lengthy upgrade process for them.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88331490b8..06db4f473e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -191,13 +191,23 @@ include_directories(SYSTEM ${LIBTERMKEY_INCLUDE_DIRS})
find_package(LibVterm REQUIRED)
include_directories(SYSTEM ${LIBVTERM_INCLUDE_DIRS})
-option(SANITIZE "Enable Clang sanitizers for nvim binary" OFF)
-if(SANITIZE AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
- message(WARNING "SANITIZE is only supported for Clang, disabling")
- set(SANITIZE OFF)
+option(CLANG_ASAN_UBSAN "Enable Clang address & undefined behavior sanitizer for nvim binary." OFF)
+option(CLANG_MSAN "Enable Clang memory sanitizer for nvim binary." OFF)
+option(CLANG_TSAN "Enable Clang thread sanitizer for nvim binary." OFF)
+
+if((CLANG_ASAN_UBSAN AND CLANG_MSAN)
+ OR (CLANG_ASAN_UBSAN AND CLANG_TSAN)
+ OR (CLANG_MSAN AND CLANG_TSAN))
+ message(FATAL_ERROR "Sanitizers cannot be enabled simultaneously.")
endif()
-if(NOT SANITIZE)
+if((CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN) AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
+ message(FATAL_ERROR "Sanitizers are only supported for Clang.")
+endif()
+
+if(CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN)
+ message(STATUS "Sanitizers have been enabled; don't use jemalloc.")
+else()
find_package(JeMalloc)
if(JEMALLOC_FOUND)
include_directories(SYSTEM ${JEMALLOC_INCLUDE_DIRS})
diff --git a/README.md b/README.md
index 674a0a3845..51b919f3d5 100644
--- a/README.md
+++ b/README.md
@@ -29,9 +29,9 @@ For lots more details, see
### What's been done so far
-- [Terminal emulator](http://neovim.io/doc/user/various.html#:terminal)
+- [Terminal emulator](http://neovim.io/doc/user/nvim_terminal_emulator.html)
- [Job control](https://github.com/neovim/neovim/pull/2247)
-- msgpack remote API
+- MessagePack-based remote API
- Performance, reliability, portability
See the [progress page](https://github.com/neovim/neovim/wiki/Progress) for a comprehensive list.
diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim
index 5a3097af5d..ddbdc2d7f2 100644
--- a/runtime/autoload/remote/host.vim
+++ b/runtime/autoload/remote/host.vim
@@ -40,7 +40,11 @@ function! remote#host#Require(name)
endif
let host = s:hosts[a:name]
if !host.channel && !host.initialized
- let host.channel = call(host.factory, [a:name])
+ let host_info = {
+ \ 'name': a:name,
+ \ 'orig_name': get(host, 'orig_name', a:name)
+ \ }
+ let host.channel = call(host.factory, [host_info])
let host.initialized = 1
endif
return host.channel
@@ -189,16 +193,14 @@ endfunction
" Registration of standard hosts
" Python/Python3 {{{
-function! s:RequirePythonHost(name)
- let ver_name = has_key(s:hosts[a:name], 'orig_name') ?
- \ s:hosts[a:name].orig_name : a:name
- let ver = (ver_name ==# 'python') ? 2 : 3
+function! s:RequirePythonHost(host)
+ let ver = (a:host.orig_name ==# 'python') ? 2 : 3
" Python host arguments
let args = ['-c', 'import neovim; neovim.start_host()']
" Collect registered Python plugins into args
- let python_plugins = remote#host#PluginsForHost(a:name)
+ let python_plugins = remote#host#PluginsForHost(a:host.name)
for plugin in python_plugins
call add(args, plugin.path)
endfor
diff --git a/runtime/colors/darkblue.vim b/runtime/colors/darkblue.vim
index 4117122728..88f0bd73b9 100644
--- a/runtime/colors/darkblue.vim
+++ b/runtime/colors/darkblue.vim
@@ -17,7 +17,6 @@ let colors_name = "darkblue"
hi Normal guifg=#c0c0c0 guibg=#000040 ctermfg=gray ctermbg=black
hi ErrorMsg guifg=#ffffff guibg=#287eff ctermfg=white ctermbg=lightblue
hi Visual guifg=#8080ff guibg=fg gui=reverse ctermfg=lightblue ctermbg=fg cterm=reverse
-hi VisualNOS guifg=#8080ff guibg=fg gui=reverse,underline ctermfg=lightblue ctermbg=fg cterm=reverse,underline
hi Todo guifg=#d14a14 guibg=#1248d1 ctermfg=red ctermbg=darkblue
hi Search guifg=#90fff0 guibg=#2050d0 ctermfg=white ctermbg=darkblue cterm=underline term=underline
hi IncSearch guifg=#b0ffff guibg=#2050d0 ctermfg=darkblue ctermbg=gray
diff --git a/runtime/colors/delek.vim b/runtime/colors/delek.vim
index 8c5f7f4fe3..dd3a33a9e8 100644
--- a/runtime/colors/delek.vim
+++ b/runtime/colors/delek.vim
@@ -39,7 +39,6 @@ hi StatusLineNC cterm=bold ctermbg=blue ctermfg=black guibg=gold guifg=blue
hi Title ctermfg=DarkMagenta gui=bold guifg=Magenta
hi VertSplit cterm=reverse gui=reverse
hi Visual ctermbg=NONE cterm=reverse gui=reverse guifg=Grey guibg=fg
-hi VisualNOS cterm=underline,bold gui=underline,bold
hi WarningMsg ctermfg=DarkRed guifg=Red
hi WildMenu ctermfg=Black ctermbg=Yellow guibg=Yellow guifg=Black
diff --git a/runtime/colors/desert.vim b/runtime/colors/desert.vim
index 7166220f26..542e5ae015 100644
--- a/runtime/colors/desert.vim
+++ b/runtime/colors/desert.vim
@@ -47,7 +47,6 @@ hi StatusLine guibg=#c2bfa5 guifg=black gui=none
hi StatusLineNC guibg=#c2bfa5 guifg=grey50 gui=none
hi Title guifg=indianred
hi Visual gui=none guifg=khaki guibg=olivedrab
-"hi VisualNOS
hi WarningMsg guifg=salmon
"hi WildMenu
"hi Menu
@@ -83,7 +82,6 @@ hi StatusLineNC cterm=reverse
hi VertSplit cterm=reverse
hi Title ctermfg=5
hi Visual cterm=reverse
-hi VisualNOS cterm=bold,underline
hi WarningMsg ctermfg=1
hi WildMenu ctermfg=0 ctermbg=3
hi Folded ctermfg=darkgrey ctermbg=NONE
diff --git a/runtime/colors/evening.vim b/runtime/colors/evening.vim
index 298fd24811..5dae08280e 100644
--- a/runtime/colors/evening.vim
+++ b/runtime/colors/evening.vim
@@ -23,7 +23,6 @@ hi StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold
hi StatusLineNC term=reverse cterm=reverse gui=reverse
hi VertSplit term=reverse cterm=reverse gui=reverse
hi Visual term=reverse ctermbg=black guibg=grey60
-hi VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold
hi DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red
hi Cursor guibg=Green guifg=Black
hi lCursor guibg=Cyan guifg=Black
diff --git a/runtime/colors/morning.vim b/runtime/colors/morning.vim
index f1ab841416..fca9c2a742 100644
--- a/runtime/colors/morning.vim
+++ b/runtime/colors/morning.vim
@@ -23,7 +23,6 @@ hi StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold
hi StatusLineNC term=reverse cterm=reverse gui=reverse
hi VertSplit term=reverse cterm=reverse gui=reverse
hi Visual term=reverse ctermbg=grey guibg=grey80
-hi VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold
hi DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red
hi Cursor guibg=Green guifg=NONE
hi lCursor guibg=Cyan guifg=NONE
diff --git a/runtime/colors/peachpuff.vim b/runtime/colors/peachpuff.vim
index 3c15305b00..1c0c2390f8 100644
--- a/runtime/colors/peachpuff.vim
+++ b/runtime/colors/peachpuff.vim
@@ -34,7 +34,6 @@ hi StatusLineNC term=reverse cterm=reverse gui=bold guifg=PeachPuff guibg=Gray45
hi VertSplit term=reverse cterm=reverse gui=bold guifg=White guibg=Gray45
hi Title term=bold ctermfg=5 gui=bold guifg=DeepPink3
hi Visual term=reverse cterm=reverse gui=reverse guifg=Grey80 guibg=fg
-hi VisualNOS term=bold,underline cterm=bold,underline gui=bold,underline
hi WarningMsg term=standout ctermfg=1 gui=bold guifg=Red
hi WildMenu term=standout ctermfg=0 ctermbg=3 guifg=Black guibg=Yellow
hi Folded term=standout ctermfg=4 ctermbg=7 guifg=Black guibg=#e3c1a5
diff --git a/runtime/colors/shine.vim b/runtime/colors/shine.vim
index afc72b30fb..eedb9c9b25 100644
--- a/runtime/colors/shine.vim
+++ b/runtime/colors/shine.vim
@@ -24,7 +24,6 @@ hi StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold
hi StatusLineNC term=reverse cterm=reverse gui=reverse
hi VertSplit term=reverse cterm=reverse gui=reverse
hi Visual term=reverse cterm=reverse gui=reverse guifg=Grey guibg=fg
-hi VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold
hi DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red
hi Cursor ctermbg=Green guibg=Green guifg=Black
hi lCursor guibg=Cyan guifg=Black
diff --git a/runtime/colors/slate.vim b/runtime/colors/slate.vim
index f9a70b8777..ffc13b822a 100644
--- a/runtime/colors/slate.vim
+++ b/runtime/colors/slate.vim
@@ -45,7 +45,6 @@ let colors_name = "slate"
:hi Todo guifg=orangered guibg=yellow2
:hi Directory ctermfg=darkcyan
:hi ErrorMsg cterm=bold guifg=White guibg=Red cterm=bold ctermfg=7 ctermbg=1
-:hi VisualNOS cterm=bold,underline
:hi WildMenu ctermfg=0 ctermbg=3
:hi DiffAdd ctermbg=4
:hi DiffChange ctermbg=5
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
index 122e76d0d3..4dd515f3e0 100644
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1158,12 +1158,8 @@ register.
7. Selection and drop registers "*, "+ and "~
Use these registers for storing and retrieving the selected text for the GUI.
See |quotestar| and |quoteplus|. When the clipboard is not available or not
-working, the unnamed register is used instead. For Unix systems the clipboard
-is only available when the |+xterm_clipboard| feature is present.
-
-Note that there is only a distinction between "* and "+ for X11 systems. For
-an explanation of the difference, see |x11-selection|. Under MS-Windows, use
-of "* and "+ is actually synonymous and refers to the |gui-clipboard|.
+working, the unnamed register is used instead. For Unix systems and Mac OS X,
+see |nvim-clipboard|.
*quote_~* *quote~* *<Drop>*
The read-only "~ register stores the dropped text from the last drag'n'drop
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index e1c84d37a6..6a0fef6d55 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -6722,8 +6722,6 @@ dialog_con Compiled with console dialog support.
dialog_gui Compiled with GUI dialog support.
digraphs Compiled with support for digraphs.
dnd Compiled with support for the "~ register |quote_~|.
-dos16 16 bits DOS version of Vim.
-dos32 32 bits DOS (DJGPP) version of Vim.
eval Compiled with expression evaluation support. Always
true, of course!
ex_extra Compiled with extra Ex commands |+ex_extra|.
@@ -6824,12 +6822,10 @@ visualextra Compiled with extra Visual mode commands.
vreplace Compiled with |gR| and |gr| commands.
wildignore Compiled with 'wildignore' option.
wildmenu Compiled with 'wildmenu' option.
-win16 Win16 version of Vim (MS-Windows 3.1).
win32 Win32 version of Vim (MS-Windows 95 and later, 32 or
64 bits)
win32unix Win32 version of Vim, using Unix files (Cygwin)
win64 Win64 version of Vim (MS-Windows 64 bit).
-win95 Win32 version for MS-Windows 95/98/ME.
winaltkeys Compiled with 'winaltkeys' option.
windows Compiled with support for more than one window.
writebackup Compiled with 'writebackup' default on.
@@ -6838,11 +6834,6 @@ xim Compiled with X input method support |xim|.
xpm Compiled with pixmap support.
xpm_w32 Compiled with pixmap support for Win32. (Only for
backward compatibility. Use "xpm" instead.)
-xsmp Compiled with X session management support.
-xsmp_interact Compiled with interactive X session management support.
-xterm_clipboard Compiled with support for xterm clipboard.
-xterm_save Compiled with support for saving and restoring the
- xterm screen.
x11 Compiled with X11 support.
*string-match*
diff --git a/runtime/doc/gui.txt b/runtime/doc/gui.txt
index ba88ee242c..8c87e5e4ac 100644
--- a/runtime/doc/gui.txt
+++ b/runtime/doc/gui.txt
@@ -12,10 +12,8 @@ Vim's Graphical User Interface *gui* *GUI*
4. Making GUI Selections |gui-selections|
5. Menus |menus|
6. Extras |gui-extras|
-7. Shell Commands |gui-shell|
Other GUI documentation:
-|gui_x11.txt| For specific items of the X11 GUI.
|gui_w32.txt| For specific items of the Win32 GUI.
==============================================================================
@@ -28,9 +26,6 @@ How to start the GUI depends on the system used. Mostly you can run the
GUI version of Vim with:
gvim [options] [files...]
-The X11 version of Vim can run both in GUI and in non-GUI mode. See
-|gui-x11-start|.
-
*gui-init* *gvimrc* *.gvimrc* *_gvimrc* *$MYGVIMRC*
The gvimrc file is where GUI-specific startup commands should be placed. It
is always sourced after the |vimrc| file. If you have one then the $MYGVIMRC
@@ -97,12 +92,9 @@ The personal initialization files are searched in the order specified above
and only the first one that is found is read.
There are a number of options which only have meaning in the GUI version of
-Vim. These are 'guicursor', 'guifont', 'guipty' and 'guioptions'. They are
+Vim. These are 'guicursor', 'guifont', and 'guioptions'. They are
documented in |options.txt| with all the other options.
-If using the Motif or Athena version of the GUI (but not for the GTK+ or
-Win32 version), a number of X resources are available. See |gui-resources|.
-
Another way to set the colors for different occasions is with highlight
groups. The "Normal" group is used to set the background and foreground
colors. Example (which looks nice): >
@@ -423,8 +415,7 @@ You may make selections with the mouse (see |gui-mouse-select|), or by using
Vim's Visual mode (see |v|). If 'a' is present in 'guioptions', then
whenever a selection is started (Visual or Select mode), or when the selection
is changed, Vim becomes the owner of the windowing system's primary selection
-(on MS-Windows the |gui-clipboard| is used; under X11, the |x11-selection| is
-used - you should read whichever of these is appropriate now).
+(on MS-Windows the |gui-clipboard| is used).
*clipboard*
There is a special register for storing this selection, it is the "*
@@ -443,13 +434,9 @@ selection (contents of the clipboard): >
"*p
-When using this register under X11, also see |x11-selection|. This also
-explains the related "+ register.
-
Note that when pasting text from one Vim into another separate Vim, the type
of selection (character, line, or block) will also be copied. For other
-applications the type is always character. However, if the text gets
-transferred via the |x11-cut-buffer|, the selection type is ALWAYS lost.
+applications the type is always character.
When the "unnamed" string is included in the 'clipboard' option, the unnamed
register is the same as the "* register. Thus you can yank to and paste the
@@ -988,19 +975,4 @@ This section describes other features which are related to the GUI.
A recommended Japanese font is MS Mincho. You can find info here:
http://www.lexikan.com/mincho.htm
-==============================================================================
-7. Shell Commands *gui-shell*
-
-For the X11 GUI the external commands are executed inside the gvim window.
-See |gui-pty|.
-
-WARNING: Executing an external command from the X11 GUI will not always
-work. "normal" commands like "ls", "grep" and "make" mostly work fine.
-Commands that require an intelligent terminal like "less" and "ispell" won't
-work. Some may even hang and need to be killed from another terminal. So be
-careful!
-
-For the Win32 GUI the external commands are executed in a separate window.
-See |gui-shell-win32|.
-
vim:tw=78:sw=4:ts=8:ft=help:norl:
diff --git a/runtime/doc/gui_w32.txt b/runtime/doc/gui_w32.txt
index 9449347259..8132d47cf1 100644
--- a/runtime/doc/gui_w32.txt
+++ b/runtime/doc/gui_w32.txt
@@ -262,12 +262,6 @@ WARNING: If you close this window with the "X" button, and confirm the
question if you really want to kill the application, Vim may be killed too!
(This does not apply to commands run asynchronously with ":!start".)
-In Windows 95, the window in which the commands are executed is always 25x80
-characters, to be as DOS compatible as possible (this matters!). The default
-system font is used. On NT, the window will be the default you have set up for
-"Console" in Control Panel. On Win32s, the properties of the DOS box are
-determined by _default.pif in the windows directory.
-
*msdos-mode*
If you get a dialog that says "This program is set to run in MS-DOS mode..."
when you run an external program, you can solve this by changing the
diff --git a/runtime/doc/gui_x11.txt b/runtime/doc/gui_x11.txt
deleted file mode 100644
index 7f60ae2e10..0000000000
--- a/runtime/doc/gui_x11.txt
+++ /dev/null
@@ -1,528 +0,0 @@
-*gui_x11.txt* For Vim version 7.4. Last change: 2014 Mar 08
-
-
- VIM REFERENCE MANUAL by Bram Moolenaar
-
-
-Vim's Graphical User Interface *gui-x11* *GUI-X11*
- *Athena* *Motif*
-1. Starting the X11 GUI |gui-x11-start|
-2. GUI Resources |gui-resources|
-3. Shell Commands |gui-pty|
-4. Various |gui-x11-various|
-5. GTK version |gui-gtk|
-6. GNOME version |gui-gnome|
-7. KDE version |gui-kde|
-8. Compiling |gui-x11-compiling|
-9. X11 selection mechanism |x11-selection|
-
-Other relevant documentation:
-|gui.txt| For generic items of the GUI.
-
-==============================================================================
-1. Starting the X11 GUI *gui-x11-start* *E665*
-
-Then you can run the GUI version of Vim in either of these ways:
- gvim [options] [files...]
- vim -g [options] [files...]
-
-So if you call the executable "gvim", or make "gvim" a link to the executable,
-then the GUI version will automatically be used. Additional characters may be
-added after "gvim", for example "gvim-5".
-
-You may also start up the GUI from within the terminal version by using one of
-these commands:
- :gui [++opt] [+cmd] [-f|-b] [files...] *:gu* *:gui*
- :gvim [++opt] [+cmd] [-f|-b] [files...] *:gv* *:gvim*
-The "-f" option runs Vim in the foreground.
-The "-b" option runs Vim in the background (this is the default).
-Also see |++opt| and |+cmd|.
-
-==============================================================================
-2. GUI Resources *gui-resources* *.Xdefaults*
-
-If using the Motif or Athena version of the GUI (not for the KDE, GTK+ or Win32
-version), a number of X resources are available. You should use Vim's class
-"Vim" when setting these. They are as follows:
-
- Resource name Meaning ~
-
- reverseVideo Boolean: should reverse video be used?
- background Color of background.
- foreground Color of normal text.
- scrollBackground Color of trough portion of scrollbars.
- scrollForeground Color of slider and arrow portions of scrollbars.
- menuBackground Color of menu backgrounds.
- menuForeground Color of menu foregrounds.
- tooltipForeground Color of tooltip and balloon foreground.
- tooltipBackground Color of tooltip and balloon background.
-
- font Name of font used for normal text.
- boldFont Name of font used for bold text.
- italicFont Name of font used for italic text.
- boldItalicFont Name of font used for bold, italic text.
- menuFont Name of font used for the menus, used when compiled
- without the |+xfontset| feature
- menuFontSet Name of fontset used for the menus, used when compiled
- with the |+xfontset| feature
- tooltipFont Name of the font used for the tooltip and balloons.
- When compiled with the |+xfontset| feature this is a
- fontset name.
-
- geometry Initial geometry to use for gvim's window (default
- is same size as terminal that started it).
- scrollbarWidth Thickness of scrollbars.
- borderWidth Thickness of border around text area.
- menuHeight Height of the menu bar (only for Athena).
-
-A special font for italic, bold, and italic-bold text will only be used if
-the user has specified one via a resource. No attempt is made to guess what
-fonts should be used for these based on the normal text font.
-
-Note that the colors can also be set with the ":highlight" command, using the
-"Normal", "Menu", "Tooltip", and "Scrollbar" groups. Example: >
- :highlight Menu guibg=lightblue
- :highlight Tooltip guibg=yellow
- :highlight Scrollbar guibg=lightblue guifg=blue
- :highlight Normal guibg=grey90
-<
- *font-sizes*
-Note: All fonts (except for the menu and tooltip) must be of the same size!!!
-If you don't do this, text will disappear or mess up the display. Vim does
-not check the font sizes. It's the size in screen pixels that must be the
-same. Note that some fonts that have the same point size don't have the same
-pixel size! Additionally, the positioning of the fonts must be the same
-(ascent and descent). You can check this with "xlsfonts -l {fontname}".
-
-If any of these things are also set with Vim commands, e.g. with
-":set guifont=Screen15", then this will override the X resources (currently
-'guifont' is the only option that is supported).
-
-Here is an example of what you might put in your ~/.Xdefaults file: >
-
- Vim*useSchemes: all
- Vim*sgiMode: true
- Vim*useEnhancedFSB: true
- Vim.foreground: Black
- Vim.background: Wheat
- Vim*fontList: 7x13
-
-The first three of these are standard resources on Silicon Graphics machines
-which make Motif applications look even better, highly recommended!
-
-The "Vim*fontList" is to set the menu font for Motif. Example: >
- Vim*menuBar*fontList: -*-courier-medium-r-*-*-10-*-*-*-*-*-*-*
-With Athena: >
- Vim*menuBar*SmeBSB*font: -*-courier-medium-r-*-*-10-*-*-*-*-*-*-*
- Vim*menuBar*MenuButton*font: -*-courier-medium-r-*-*-10-*-*-*-*-*-*-*
-
-NOTE: A more portable, and indeed more correct, way to specify the menu font
-in either Motif or Athena is through the resource: >
- Vim.menuFont: -*-courier-medium-r-*-*-10-*-*-*-*-*-*-*
-Or, when compiled with the |+xfontset| feature: >
- Vim.menuFontSet: -*-courier-medium-r-*-*-10-*-*-*-*-*-*-*
-
-Don't use "Vim*geometry" in the defaults. This will break the menus. Use
-"Vim.geometry" instead.
-
-If you get an error message "Cannot allocate colormap entry for "gray60",
-try adding this to your Vim resources (change the colors to your liking): >
-
- Vim*scrollBackground: Black
- Vim*scrollForeground: Blue
-
-The resources can also be set with arguments to Vim:
-
- argument meaning ~
- *-gui*
- -display {display} Run vim on {display} *-display*
- -iconic Start vim iconified *-iconic*
- -background {color} Use {color} for the background *-background*
- -bg {color} idem *-bg*
- -foreground {color} Use {color} for normal text *-foreground*
- -fg {color} idem *-fg*
- -ul {color} idem *-ul*
- -font {font} Use {font} for normal text *-font*
- -fn {font} idem *-fn*
- -boldfont {font} Use {font} for bold text *-boldfont*
- -italicfont {font} Use {font} for italic text *-italicfont*
- -menufont {font} Use {font} for menu items *-menufont*
- -menufontset {fontset} Use {fontset} for menu items *-menufontset*
- -mf {font} idem *-mf*
- -geometry {geom} Use {geom} for initial geometry *-geometry*
- -geom {geom} idem, see |-geometry-example| *-geom*
- -borderwidth {width} Use a border width of {width} *-borderwidth*
- -bw {width} idem *-bw*
- *-scrollbarwidth*
- -scrollbarwidth {width} Use a scrollbar width of {width}
- -sw {width} idem *-sw*
- -menuheight {height} Use a menu bar height of {height} *-menuheight*
- -mh {height} idem *-mh*
- NOTE: On Motif the value is ignored, the menu height
- is computed to fit the menus.
- -reverse Use reverse video *-reverse*
- -rv idem *-rv*
- +reverse Don't use reverse video *-+reverse*
- +rv idem *-+rv*
- -xrm {resource} Set the specified resource *-xrm*
-
-Note about reverse video: Vim checks that the result is actually a light text
-on a dark background. The reason is that some X11 versions swap the colors,
-and some don't. These two examples will both give yellow text on a blue
-background:
- gvim -fg Yellow -bg Blue -reverse
- gvim -bg Yellow -fg Blue -reverse
-
- *-geometry-example*
-An example for the geometry argument: >
- gvim -geometry 80x63+8+100
-This creates a window with 80 columns and 63 lines at position 8 pixels from
-the left and 100 pixels from the top of the screen.
-
-==============================================================================
-3. Shell Commands *gui-pty*
-
-WARNING: Executing an external command from the GUI will not always work.
-"normal" commands like "ls", "grep" and "make" mostly work fine. Commands
-that require an intelligent terminal like "less" and "ispell" won't work.
-Some may even hang and need to be killed from another terminal. So be
-careful!
-
-There are two ways to do the I/O with a shell command: Pipes and a pseudo-tty.
-The default is to use a pseudo-tty. This should work best on most systems.
-
-Unfortunately, the implementation of the pseudo-tty is different on every Unix
-system. And some systems require root permission. To avoid running into
-problems with a pseudo-tty when you least expect it, test it when not editing
-a file. Be prepared to "kill" the started command or Vim. Commands like
-":r !cat" may hang!
-
-If using a pseudo-tty does not work for you, reset the 'guipty' option: >
-
- :set noguipty
-
-Using a pipe should work on any Unix system, but there are disadvantages:
-- Some shell commands will notice that a pipe is being used and behave
- differently. E.g., ":!ls" will list the files in one column.
-- The ":sh" command won't show a prompt, although it will sort of work.
-- When using ":make" it's not possible to interrupt with a CTRL-C.
-
-Typeahead while the external command is running is often lost. This happens
-both with a pipe and a pseudo-tty. This is a known problem, but it seems it
-can't be fixed (or at least, it's very difficult).
-
- *gui-pty-erase*
-When your erase character is wrong for an external command, you should fix
-this in your "~/.cshrc" file, or whatever file your shell uses for
-initializations. For example, when you want to use backspace to delete
-characters, but hitting backspaces produces "^H" instead, try adding this to
-your "~/.cshrc": >
- stty erase ^H
-The ^H is a real CTRL-H, type it as CTRL-V CTRL-H.
-
-==============================================================================
-4. Various *gui-x11-various*
-
- *gui-x11-printing*
-The "File/Print" menu simply sends the current buffer to "lpr". No options or
-whatever. If you want something else, you can define your own print command.
-For example: >
-
- :10amenu File.Print :w !lpr -Php3
- :10vmenu File.Print :w !lpr -Php3
-<
-Mouse Pointers Available in X11 *X11_mouse_shapes*
-
-By using the |'mouseshape'| option, the mouse pointer can be automatically
-changed whenever Vim enters one of its various modes (e.g., Insert or
-Command). Currently, the available pointers are:
-
- arrow an arrow pointing northwest
- beam a I-like vertical bar
- size an arrow pointing up and down
- busy a wristwatch
- blank an invisible pointer
- crosshair a thin "+" sign
- hand1 a dark hand pointing northeast
- hand2 a light hand pointing northwest
- pencil a pencil pointing southeast
- question question_arrow
- right_arrow an arrow pointing northeast
- up_arrow an arrow pointing upwards
-
-Additionally, any of the mouse pointers that are built into X11 may be
-used by specifying an integer from the X11/cursorfont.h include file.
-
-If a name is used that exists on other systems, but not in X11, the default
-"arrow" pointer is used.
-
-==============================================================================
-5. GTK version *gui-gtk* *GTK+* *GTK*
-
-The GTK version of the GUI works a little bit different.
-
-GTK does _not_ use the traditional X resource settings. Thus items in your
-~/.Xdefaults or app-defaults files are not used.
-Many of the traditional X command line arguments are not supported. (e.g.,
-stuff like -bg, -fg, etc). The ones that are supported are:
-
- command line argument resource name meaning ~
- -fn or -font .font font name for the text
- -geom or -geometry .geometry size of the gvim window
- -rv or -reverse *reverseVideo white text on black background
- -display display to be used
- -fg -foreground {color} foreground color
- -bg -background {color} background color
-
-To set the font, see |'guifont'|. For GTK, there's also a menu option that
-does this.
-
-Additionally, there are these command line arguments, which are handled by GTK
-internally. Look in the GTK documentation for how they are used:
- --sync
- --gdk-debug
- --gdk-no-debug
- --no-xshm (not in GTK+ 2)
- --xim-preedit (not in GTK+ 2)
- --xim-status (not in GTK+ 2)
- --gtk-debug
- --gtk-no-debug
- --g-fatal-warnings
- --gtk-module
- --display (GTK+ counterpart of -display; works the same way.)
- --screen (The screen number; for GTK+ 2.2 multihead support.)
-
-As for colors, Vim's color settings (for syntax highlighting) is still
-done the traditional Vim way. See |:highlight| for more help.
-
-If you want to set the colors of remaining gui components (e.g., the
-menubar, scrollbar, whatever), those are GTK specific settings and you
-need to set those up in some sort of gtkrc file. You'll have to refer
-to the GTK documentation, however little there is, on how to do this.
-See http://developer.gnome.org/doc/API/2.0/gtk/gtk-Resource-Files.html
-for more information.
-
- *gtk-tooltip-colors*
-Example, which sets the tooltip colors to black on light-yellow: >
-
- style "tooltips"
- {
- bg[NORMAL] = "#ffffcc"
- fg[NORMAL] = "#000000"
- }
-
- widget "gtk-tooltips*" style "tooltips"
-
-Write this in the file ~/.gtkrc and it will be used by GTK+. For GTK+ 2
-you might have to use the file ~/.gtkrc-2.0 instead, depending on your
-distribution.
-
-Using Vim as a GTK+ plugin *gui-gtk-socketid*
-
-When the GTK+ version of Vim starts up normally, it creates its own top level
-window (technically, a 'GtkWindow'). GTK+ provides an embedding facility with
-its GtkSocket and GtkPlug widgets. If one GTK+ application creates a
-GtkSocket widget in one of its windows, an entirely different GTK+ application
-may embed itself into the first application by creating a top-level GtkPlug
-widget using the socket's ID.
-
-If you pass Vim the command-line option '--socketid' with a decimal or
-hexadecimal value, Vim will create a GtkPlug widget using that value instead
-of the normal GtkWindow. This enables Vim to act as a GTK+ plugin.
-
-This really is a programmer's interface, and is of no use without a supporting
-application to spawn the Vim correctly. For more details on GTK+ sockets, see
-http://www.gtk.org/api/
-
-Note that this feature requires the latest GTK version. GTK 1.2.10 still has
-a small problem. The socket feature has not yet been tested with GTK+ 2 --
-feel free to volunteer.
-
-==============================================================================
-6. GNOME version *gui-gnome* *Gnome* *GNOME*
-
-The GNOME GUI works just like the GTK+ version. See |GTK+| above for how it
-works. It looks a bit different though, and implements one important feature
-that's not available in the plain GTK+ GUI: Interaction with the session
-manager. |gui-gnome-session|
-
-These are the different looks:
-- Uses GNOME dialogs (GNOME 1 only). The GNOME 2 GUI uses the same nice
- dialogs as the GTK+ 2 version.
-- Uses the GNOME dock, so that the toolbar and menubar can be moved to
- different locations other than the top (e.g., the toolbar can be placed on
- the left, right, top, or bottom). The placement of the menubar and
- toolbar is only saved in the GNOME 2 version.
-- That means the menubar and toolbar handles are back! Yeah! And the
- resizing grid still works too.
-
-GNOME is compiled with if it was found by configure and the
---enable-gnome-check argument was used.
-
-
-GNOME session support *gui-gnome-session* *gnome-session*
-
-On logout, Vim shows the well-known exit confirmation dialog if any buffers
-are modified. Clicking [Cancel] will stop the logout process. Otherwise the
-current session is stored to disk by using the |:mksession| command, and
-restored the next time you log in.
-
-The GNOME session support should also work with the KDE session manager.
-If you are experiencing any problems please report them as bugs.
-
-Note: The automatic session save works entirely transparent, in order to
-avoid conflicts with your own session files, scripts and autocommands. That
-means in detail:
-- The session file is stored to a separate directory (usually $HOME/.gnome2).
-- 'sessionoptions' is ignored, and a hardcoded set of appropriate flags is
- used instead: >
- blank,curdir,folds,globals,help,options,tabpages,winsize
-- The internal variable |v:this_session| is not changed when storing the
- session. Also, it is restored to its old value when logging in again.
-
-==============================================================================
-7. KDE version *gui-kde* *kde* *KDE* *KVim*
- *gui-x11-kde*
-There is no KDE version of Vim. There has been some work on a port using the
-Qt toolkit, but it never worked properly and it has been abandoned. Work
-continues on Yzis: https://github.com/chrizel/Yzis.
-
-==============================================================================
-8. Compiling *gui-x11-compiling*
-
-If using X11, Vim's Makefile will by default first try to find the necessary
-GTK+ files on your system. If the GTK+ files cannot be found, then the Motif
-files will be searched for. Finally, if this fails, the Athena files will be
-searched for. If all three fail, the GUI will be disabled.
-
-For GTK+, Vim's configuration process requires that GTK+ be properly
-installed. That is, the shell script 'gtk-config' must be in your PATH, and
-you can already successful compile, build, and execute a GTK+ program. The
-reason for this is that the compiler flags (CFLAGS) and link flags (LDFLAGS)
-are obtained through the 'gtk-config' shell script.
-
-If you want to build with GTK+ 2 support pass the --enable-gtk2-check argument
-to ./configure. Optionally, support for GNOME 2 will be compiled if the
---enable-gnome-check option is also given.
-
-Otherwise, if you are using Motif or Athena, when you have the Motif or Athena
-files in a directory where configure doesn't look, edit the Makefile to enter
-the names of the directories. Search for "GUI_INC_LOC" for an example to set
-the Motif directories, "CONF_OPT_X" for Athena.
-
- *gui-x11-gtk*
-At the time of this writing, GTK+ version 1.0.6 and 1.2 are outdated. It
-is suggested that you use GTK 2. The GTK 1 support will most likely be
-dropped soon.
-
-For the GTK+ 2 GUI, using the latest release of the GTK+ 2.0 or GTK+ 2.2
-series is recommended.
-
-Lastly, although GTK+ has supposedly been ported to the Win32 platform, this
-has not been tested with Vim and is also unsupported. Also, it's unlikely to
-even compile since GTK+ GUI uses parts of the generic X11 code. This might
-change in distant future; particularly because getting rid of the X11 centric
-code parts is also required for GTK+ framebuffer support.
-
- *gui-x11-motif*
-For Motif, you need at least Motif version 1.2 and/or X11R5. Motif 2.0 and
-X11R6 are OK. Motif 1.1 and X11R4 might work, no guarantee (there may be a
-few problems, but you might make it compile and run with a bit of work, please
-send me the patches if you do). The newest releases of LessTif have been
-reported to work fine too.
-
- *gui-x11-athena*
-The Athena version uses the Xaw widget set by default. If you have the 3D
-version, you might want to link with Xaw3d instead. This will make the
-menus look a bit better. Edit the Makefile and look for "XAW_LIB". The
-scrollbars will remain the same, because Vim has its own, which are already
-3D (in fact, they look more like Motif).
-
- *gui-x11-neXtaw*
-The neXtaw version is mostly like Athena, but uses different widgets.
-
- *gui-x11-misc*
-In general, do not try to mix files from different GTK+, Motif, Athena and X11
-versions. This will cause problems. For example, using header files for
-X11R5 with a library for X11R6 probably doesn't work (although the linking
-won't give an error message, Vim will crash later).
-
-==============================================================================
-9. X11 selection mechanism *x11-selection*
-
-If using X11, in either the GUI or an xterm with an X11-aware Vim, then Vim
-provides varied access to the X11 selection and clipboard. These are accessed
-by using the two selection registers "* and "+.
-
-X11 provides two basic types of global store, selections and cut-buffers,
-which differ in one important aspect: selections are "owned" by an
-application, and disappear when that application (e.g., Vim) exits, thus
-losing the data, whereas cut-buffers, are stored within the X-server itself
-and remain until written over or the X-server exits (e.g., upon logging out).
-
-The contents of selections are held by the originating application (e.g., upon
-a copy), and only passed on to another application when that other application
-asks for them (e.g., upon a paste).
-
-The contents of cut-buffers are immediately written to, and are then
-accessible directly from the X-server, without contacting the originating
-application.
-
- *quoteplus* *quote+*
-There are three documented X selections: PRIMARY (which is expected to
-represent the current visual selection - as in Vim's Visual mode), SECONDARY
-(which is ill-defined) and CLIPBOARD (which is expected to be used for
-cut, copy and paste operations).
-
-Of these three, Vim uses PRIMARY when reading and writing the "* register
-(hence when the X11 selections are available, Vim sets a default value for
-|'clipboard'| of "autoselect"), and CLIPBOARD when reading and writing the "+
-register. Vim does not access the SECONDARY selection.
-
-Examples: (assuming the default option values)
-- Select an URL in Visual mode in Vim. Go to your browser and click the
- middle mouse button in the URL text field. The selected text will be
- inserted (hopefully!). Note: in Firefox you can set the
- middlemouse.contentLoadURL preference to true in about:config, then the
- selected URL will be used when pressing middle mouse button in most places
- in the window.
-- Select some text in your browser by dragging with the mouse. Go to Vim and
- press the middle mouse button: The selected text is inserted.
-- Select some text in Vim and do "+y. Go to your browser, select some text in
- a textfield by dragging with the mouse. Now use the right mouse button and
- select "Paste" from the popup menu. The selected text is overwritten by the
- text from Vim.
-Note that the text in the "+ register remains available when making a Visual
-selection, which makes other text available in the "* register. That allows
-overwriting selected text.
- *x11-cut-buffer*
-There are, by default, 8 cut-buffers: CUT_BUFFER0 to CUT_BUFFER7. Vim only
-uses CUT_BUFFER0, which is the one that xterm uses by default.
-
-Whenever Vim is about to become unavailable (either via exiting or becoming
-suspended), and thus unable to respond to another application's selection
-request, it writes the contents of any owned selection to CUT_BUFFER0. If the
-"+ CLIPBOARD selection is owned by Vim, then this is written in preference,
-otherwise if the "* PRIMARY selection is owned by Vim, then that is written.
-
-Similarly, when Vim tries to paste from "* or "+ (either explicitly, or, in
-the case of the "* register, when the middle mouse button is clicked), if the
-requested X selection is empty or unavailable, Vim reverts to reading the
-current value of the CUT_BUFFER0.
-
-Note that when text is copied to CUT_BUFFER0 in this way, the type of
-selection (character, line or block) is always lost, even if it is a Vim which
-later pastes it.
-
-Xterm, by default, always writes visible selections to both PRIMARY and
-CUT_BUFFER0. When it pastes, it uses PRIMARY if this is available, or else
-falls back upon CUT_BUFFER0. For this reason, when cutting and pasting
-between Vim and an xterm, you should use the "* register. Xterm doesn't use
-CLIPBOARD, thus the "+ doesn't work with xterm.
-
-Most newer applications will provide their current selection via PRIMARY ("*)
-and use CLIPBOARD ("+) for cut/copy/paste operations. You thus have access to
-both by choosing to use either of the "* or "+ registers.
-
-
- vim:tw=78:sw=4:ts=8:ft=help:norl:
diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt
index 4265a81767..e1c05365f7 100644
--- a/runtime/doc/help.txt
+++ b/runtime/doc/help.txt
@@ -148,7 +148,6 @@ Special issues ~
GUI ~
|gui.txt| Graphical User Interface (GUI)
|gui_w32.txt| Win32 GUI
-|gui_x11.txt| X11 GUI
Interfaces ~
|if_cscop.txt| using Cscope with Vim
@@ -163,7 +162,7 @@ Versions ~
Remarks about specific systems ~
|os_mac.txt| Macintosh
|os_unix.txt| Unix
-|os_win32.txt| MS-Windows 95/98/NT
+|os_win32.txt| MS-Windows
*standard-plugin-list*
Standard plugins ~
|pi_getscript.txt| Downloading latest version of Vim scripts
diff --git a/runtime/doc/if_cscop.txt b/runtime/doc/if_cscop.txt
index 5f13d4d176..4f8c0e2065 100644
--- a/runtime/doc/if_cscop.txt
+++ b/runtime/doc/if_cscop.txt
@@ -360,9 +360,6 @@ cscope version for Win32 see:
http://iamphet.nm.ru/cscope/index.html
-The DJGPP-built version from http://cscope.sourceforge.net is known to not
-work with Vim.
-
Hard-coded limitation: doing a |:tjump| when |:cstag| searches the tag files
is not configurable (e.g., you can't do a tselect instead).
diff --git a/runtime/doc/message.txt b/runtime/doc/message.txt
index f5fc8ee03b..7d674ae4d7 100644
--- a/runtime/doc/message.txt
+++ b/runtime/doc/message.txt
@@ -317,7 +317,7 @@ You can switch the 'write' option on with ":set write".
*E25* >
Nvim does not have a built-in GUI
-Neovim does not have a built in GUI, so |:gvim| and |:gui| don't work.
+Neovim does not have a built in GUI, so `:gvim` and `:gui` don't work.
*E49* >
Invalid scroll size
diff --git a/runtime/doc/nvim_clipboard.txt b/runtime/doc/nvim_clipboard.txt
index cf63685499..1183ad7a3c 100644
--- a/runtime/doc/nvim_clipboard.txt
+++ b/runtime/doc/nvim_clipboard.txt
@@ -4,7 +4,13 @@
NVIM REFERENCE MANUAL by Thiago de Arruda
-Clipboard integration for Nvim *nvim-clipboard*
+Clipboard integration for Nvim *nvim-clipboard*
+
+1. Intro |nvim-clipboard-intro|
+2. X11 selection mechanism |nvim-clipboard-x11|
+
+==============================================================================
+1. Intro *nvim-clipboard-intro*
Nvim has no direct connection to the system clipboard. Instead, it is
accessible through the |nvim-provider| infrastructure, which transparently
@@ -29,4 +35,25 @@ following option:
See 'clipboard' for details and more options.
==============================================================================
+2. X11 selection mechanism *nvim-clipboard-x11* *x11-selection*
+
+The clipboard providers for X11 store text in what is known as "selections".
+Selections are "owned" by an application, so when the application is closed,
+the selection text is lost.
+
+The contents of selections are held by the originating application (e.g., upon
+a copy), and only passed on to another application when that other application
+asks for them (e.g., upon a paste).
+
+ *quoteplus* *quote+*
+
+There are three documented X11 selections: `PRIMARY`, `SECONDARY`, and `CLIPBOARD`.
+`CLIPBOARD` is typically used in X11 applications for copy/paste operations
+(`Ctrl-c`/`v`), while `PRIMARY` is used for the last selected text, which is
+generally inserted with the middle mouse button.
+
+Nvim's X11 clipboard providers only utilize the `PRIMARY` and `CLIPBOARD`
+selections, used for the '*' and '+' registers, respectively.
+
+==============================================================================
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/nvim_python.txt b/runtime/doc/nvim_python.txt
index 1117480a1a..a93e89303c 100644
--- a/runtime/doc/nvim_python.txt
+++ b/runtime/doc/nvim_python.txt
@@ -20,16 +20,25 @@ Note: For now only the old Vim 7.3 API is supported.
==============================================================================
2. Quickstart *nvim-python-quickstart*
+If you used a package manager to install Nvim, there's a good chance that
+it also provides the `neovim` Python package. If it doesn't, follow these
+steps to install the package with Python's package manager, `pip`.
+
+Note: Depending on your system, `pip` might refer to Python 2 or Python 3,
+ which is why the following instructions mention `pip2` or `pip3`
+ explicitly. If one of these is not available for you, maybe `pip`
+ is what you want.
+
To use Vim Python 2/3 plugins with Nvim, do the following:
- For Python 2 plugins, make sure an interpreter for Python 2.6 or 2.7 is
available in your `$PATH`, then install the `neovim` Python package systemwide:
>
- $ sudo pip install neovim
+ $ sudo pip2 install neovim
<
or for the current user:
>
- $ pip install --user neovim
+ $ pip2 install --user neovim
<
- For Python 3 plugins, make sure an interpreter for Python 3.3 or above is
available in your `$PATH`, then install the `neovim` Python package systemwide:
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 8f8f9ba152..6c184a5a59 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -3185,7 +3185,7 @@ A jump table for the options with a short description can be found at |Q_op|.
- Examples: >
:set guifont=courier_new:h12:w5:b:cRUSSIAN
:set guifont=Andale_Mono:h7.5:w4.5
-< See also |font-sizes|.
+<
*'guifontset'* *'gfs'*
*E250* *E252* *E234* *E597* *E598*
@@ -3361,11 +3361,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'guipty'* *'noguipty'*
-'guipty' boolean (default on)
- global
- {only available when compiled with GUI enabled}
- Only in the GUI: If on, an attempt is made to open a pseudo-tty for
- I/O to/from shell commands. See |gui-pty|.
+'guipty' Removed. |vim-differences| {Nvim}
*'guitablabel'* *'gtl'*
'guitablabel' 'gtl' string (default empty)
@@ -3496,9 +3492,6 @@ A jump table for the options with a short description can be found at |Q_op|.
|hl-Title| t Titles for output from ":set all", ":autocmd" etc.
|hl-VertSplit| c column used to separate vertically split windows
|hl-Visual| v Visual mode
- |hl-VisualNOS| V Visual mode when Vim does is "Not Owning the
- Selection" Only X11 Gui's |gui-x11| and
- |xterm-clipboard|.
|hl-WarningMsg| w warning messages
|hl-WildMenu| W wildcard matches displayed for 'wildmenu'
|hl-Folded| f line used for closed folds
@@ -5468,17 +5461,7 @@ A jump table for the options with a short description can be found at |Q_op|.
"-f" is not inside the quotes, because it is not part of the command
name. And Vim automagically recognizes the backslashes that are path
separators.
- For Dos 32 bits (DJGPP), you can set the $DJSYSFLAGS environment
- variable to change the way external commands are executed. See the
- libc.inf file of DJGPP.
- Under MS-Windows, when the executable ends in ".com" it must be
- included. Thus setting the shell to "command.com" or "4dos.com"
- works, but "command" and "4dos" do not work for all commands (e.g.,
- filtering).
- For unknown reasons, when using "4dos.com" the current directory is
- changed to "C:\". To avoid this set 'shell' like this: >
- :set shell=command.com\ /c\ 4dos
-< This option cannot be set from a |modeline| or in the |sandbox|, for
+ This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'shellcmdflag'* *'shcf'*
diff --git a/runtime/doc/os_dos.txt b/runtime/doc/os_dos.txt
index 03170cf1d8..1c80f4d7a5 100644
--- a/runtime/doc/os_dos.txt
+++ b/runtime/doc/os_dos.txt
@@ -87,15 +87,15 @@ key key code Normal/Visual mode Insert mode ~
CTRL-PageUp <M-N><M-C-D> H <C-O>H
CTRL-PageDown <M-N>v L$ <C-O>L<C-O>$
-Additionally, these keys are available for copy/cut/paste. In the Win32
-and DJGPP versions, they also use the clipboard.
+Additionally, these keys are available for copy/cut/paste.
+In the Win32 version, they also use the clipboard.
Shift-Insert paste text (from clipboard) *<S-Insert>*
CTRL-Insert copy Visual text (to clipboard) *<C-Insert>*
CTRL-Del cut Visual text (to clipboard) *<C-Del>*
Shift-Del cut Visual text (to clipboard) *<S-Del>*
-These mappings accomplish this (Win32 and DJGPP versions of Vim):
+These mappings accomplish this (Win32 version of Vim):
key key code Normal Visual Insert ~
Shift-Insert <M-N><M-T> "*P "-d"*P <C-R><C-O>*
@@ -276,18 +276,14 @@ If you are running a third-party shell, you may need to set the
|'shellcmdflag'| ('shcf') and |'shellquote'| ('shq') or |'shellxquote'|
('sxq') options. Unfortunately, this also depends on the version of Vim used.
For example, with the MKS Korn shell or with bash, the values of the options
-should be:
+on Win32 should be:
- DOS 16 bit DOS 32 bit Win32 ~
-'shellcmdflag' -c -c -c
-'shellquote' "
-'shellxquote' "
+'shellcmdflag' -c
+'shellquote' (empty)
+'shellxquote' "
-For Dos 16 bit this starts the shell as:
- <shell> -c "command name" >file
-For Win32 as:
+For Win32, this starts the shell as:
<shell> -c "command name >file"
-For DOS 32 bit, DJGPP does this internally somehow.
When starting up, Vim checks for the presence of "sh" anywhere in the 'shell'
option. If it is present, Vim sets the 'shellcmdflag' and 'shellquote' or
diff --git a/runtime/doc/os_win32.txt b/runtime/doc/os_win32.txt
index a2ee0e1255..603dbcddce 100644
--- a/runtime/doc/os_win32.txt
+++ b/runtime/doc/os_win32.txt
@@ -7,8 +7,8 @@
*win32* *Win32* *MS-Windows*
This file documents the idiosyncrasies of the Win32 version of Vim.
-The Win32 version of Vim works on Windows NT, 95, 98, ME, XP, Vista and
-Windows 7. There are both console and GUI versions.
+The Win32 version of Vim works on Windows NT, XP, Vista and Windows 7.
+There are both console and GUI versions.
The 32 bit version also runs on 64 bit MS-Windows systems.
@@ -37,23 +37,8 @@ The Win32 version was written by George V. Reilly <george@reilly.org>.
The original Windows NT port was done by Roger Knobbe <RogerK@wonderware.com>.
The GUI version was made by George V. Reilly and Robert Webb.
-For compiling see "src/INSTALLpc.txt". *win32-compiling*
-
==============================================================================
-1. Known problems *windows95* *win32-problems*
-
-There are a few known problems with running in a console on Windows 95. As
-far as we know, this is the same in Windows 98 and Windows ME.
-
-Comments from somebody working at Microsoft: "Win95 console support has always
-been and will always be flaky".
-1. Dead key support doesn't work.
-2. Resizing the window with ":set columns=nn lines=nn" works, but executing
- external commands MAY CAUSE THE SYSTEM TO HANG OR CRASH.
-3. Screen updating is slow, unless you change 'columns' or 'lines' to a
- non-DOS value. But then the second problem applies!
-
-If this bothers you, use the 32 bit MS-DOS version or the Win32 GUI version.
+1. Known problems *win32-problems*
When doing file name completion, Vim also finds matches for the short file
name. But Vim will still find and use the corresponding long file name. For
@@ -143,99 +128,12 @@ running under Win32s the following differences apply:
==============================================================================
6. Win32 mini FAQ *win32-faq*
-Q. Why does the Win32 version of Vim update the screen so slowly on Windows 95?
-A. The support for Win32 console mode applications is very buggy in Win95.
- For some unknown reason, the screen updates very slowly when Vim is run at
- one of the standard resolutions (80x25, 80x43, or 80x50) and the 16-bit DOS
- version updates the screen much more quickly than the Win32 version.
- However, if the screen is set to some other resolution, such as by ":set
- columns=100" or ":set lines=40", screen updating becomes about as fast as
- it is with the 16-bit version.
-
- WARNING: Changing 'columns' may make Windows 95 crash while updating the
- window (complaints --> Microsoft). Since this mostly works, this has not
- been disabled, but be careful with changing 'columns'.
-
- Changing the screen resolution makes updates faster, but it brings
- additional problems. External commands (e.g., ":!dir") can cause Vim to
- freeze when the screen is set to a non-standard resolution, particularly
- when 'columns' is not equal to 80. It is not possible for Vim to reliably
- set the screen resolution back to the value it had upon startup before
- running external commands, so if you change the number of 'lines' or
- 'columns', be very, very careful. In fact, Vim will not allow you to
- execute external commands when 'columns' is not equal to 80, because it is
- so likely to freeze up afterwards.
-
- None of the above applies on Windows NT. Screen updates are fast, no
- matter how many 'lines' or 'columns' the window has, and external commands
- do not cause Vim to freeze.
-
-Q. So if the Win32 version updates the screen so slowly on Windows 95 and the
- 16-bit DOS version updates the screen quickly, why would I want to run the
- Win32 version?
-A. Firstly, the Win32 version isn't that slow, especially when the screen is
- set to some non-standard number of 'lines' or 'columns'. Secondly, the
- 16-bit DOS version has some severe limitations: It can't do big changes and
- it doesn't know about long file names. The Win32 version doesn't have these
- limitations and it's faster overall (the same is true for the 32-bit DJGPP
- DOS version of Vim). The Win32 version is smarter about handling the
- screen, the mouse, and the keyboard than the DJGPP version is.
-
-Q. And what about the 16-bit DOS version versus the Win32 version on NT?
-A. There are no good reasons to run the 16-bit DOS version on NT. The Win32
- version updates the screen just as fast as the 16-bit version does when
- running on NT. All of the above disadvantages apply. Finally, DOS
- applications can take a long time to start up and will run more slowly. On
- non-Intel NT platforms, the DOS version is almost unusably slow, because it
- runs on top of an 80x86 emulator.
-
Q. How do I change the font?
A. In the GUI version, you can use the 'guifont' option. Example: >
:set guifont=Lucida_Console:h15:cDEFAULT
< In the console version, you need to set the font of the console itself.
You cannot do this from within Vim.
-Q. When I change the size of the console window with ':set lines=xx' or
- similar, the font changes! (Win95)
-A. You have the console font set to 'Auto' in Vim's (or your MS-DOS prompt's)
- properties. This makes W95 guess (badly!) what font is best. Set an explicit
- font instead.
-
-Q. Why can't I paste into Vim when running Windows 95?
-A. In the properties dialog box for the MS-DOS window, go to "MS-DOS
- Prompt/Misc/Fast pasting" and make sure that it is NOT checked. You should
- also do ":set paste" in Vim to avoid unexpected effects. |'paste'|
-
-Q. How do I type dead keys on Windows 95, in the console version?
- (A dead key is an accent key, such as acute, grave, or umlaut, that doesn't
- produce a character by itself, but when followed by another key, produces
- an accented character, such as a-acute, e-grave, u-umlaut, n-tilde, and so
- on. Very useful for most European languages. English-language keyboard
- layouts don't use dead keys, as far as we know.)
-A. You don't. The console mode input routines simply do not work correctly in
- Windows 95, and I have not been able to work around them. In the words
- of a senior developer at Microsoft:
- Win95 console support has always been and will always be flaky.
-
- The flakiness is unavoidable because we are stuck between the world of
- MS-DOS keyboard TSRs like KEYB (which wants to cook the data;
- important for international) and the world of Win32.
-
- So keys that don't "exist" in MS-DOS land (like dead keys) have a
- very tenuous existence in Win32 console land. Keys that act
- differently between MS-DOS land and Win32 console land (like
- capslock) will act flaky.
-
- Don't even _mention_ the problems with multiple language keyboard
- layouts...
-
- You may be able to fashion some sort of workaround with the digraphs
- mechanism. |digraphs|
-
- The best solution is to use the Win32 GUI version gvim.exe. Alternatively,
- you can try one of the DOS versions of Vim where dead keys reportedly do
- work.
-
Q. How do I type dead keys on Windows NT?
A. Dead keys work on NT 3.51. Just type them as you would in any other
application.
diff --git a/runtime/doc/pi_netrw.txt b/runtime/doc/pi_netrw.txt
index f7a7aa1ad5..80815a70ec 100644
--- a/runtime/doc/pi_netrw.txt
+++ b/runtime/doc/pi_netrw.txt
@@ -2060,7 +2060,7 @@ MARKED FILES: DIFF *netrw-md* {{{2
(See |netrw-mf| and |netrw-mr| for how to mark files)
(uses the global marked file list)
-Use vimdiff to visualize difference between selected files (two or
+Use |diff-mode| to visualize difference between selected files (two or
three may be selected for this). Uses the global marked file list.
MARKED FILES: EDITING *netrw-me* {{{2
diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt
index 14b241cae0..b9ee60318a 100644
--- a/runtime/doc/quickref.txt
+++ b/runtime/doc/quickref.txt
@@ -717,7 +717,6 @@ Short explanation of each option: *option-list*
'guifontwide' 'gfw' list of font names for double-wide characters
'guiheadroom' 'ghr' GUI: pixels room for window decorations
'guioptions' 'go' GUI: Which components and options are used
-'guipty' GUI: try to use a pseudo-tty for ":!" commands
'guitablabel' 'gtl' GUI: custom label for a tab page
'guitabtooltip' 'gtt' GUI: custom tooltip for a tab page
'helpfile' 'hf' full path name of the main help file
@@ -1113,8 +1112,6 @@ Context-sensitive completion on the command-line:
Most useful Vim arguments (for full list see |startup-options|)
-|-gui| -g start GUI (also allows other options)
-
|-+| +[num] put the cursor at line [num] (default: last line)
|-+c| +{command} execute {command} after loading the file
|-+/| +/{pat} {file} .. put the cursor at the first occurrence of {pat}
@@ -1342,9 +1339,6 @@ Context-sensitive completion on the command-line:
------------------------------------------------------------------------------
*Q_gu* GUI commands
-|:gui| :gui UNIX: start the GUI
-|:gui| :gui {fname} .. idem, and edit {fname} ..
-
|:menu| :menu list all menus
|:menu| :menu {mpath} list menus starting with {mpath}
|:menu| :menu {mpath} {rhs} add menu {mpath}, giving {rhs}
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 7e1488651e..6bc1b2873c 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -4836,8 +4836,7 @@ Title titles for output from ":set all", ":autocmd" etc.
*hl-Visual*
Visual Visual mode selection
*hl-VisualNOS*
-VisualNOS Visual mode selection when vim is "Not Owning the Selection".
- Only X11 Gui's |gui-x11| and |xterm-clipboard| supports this.
+VisualNOS Removed. |vim-differences| {Nvim}
*hl-WarningMsg*
WarningMsg warning messages
*hl-WildMenu*
diff --git a/runtime/doc/tips.txt b/runtime/doc/tips.txt
index e1d02da292..9ed8f1f544 100644
--- a/runtime/doc/tips.txt
+++ b/runtime/doc/tips.txt
@@ -160,13 +160,6 @@ entries similar to: >
PS: If you find any difference, someone (your sysadmin?) should better check
the complete termcap and terminfo database for consistency.
-NOTE 1: If you recompile Vim with FEAT_XTERM_SAVE defined in feature.h, the
-builtin xterm will include the mentioned "te" and "ti" entries.
-
-NOTE 2: If you want to disable the screen switching, and you don't want to
-change your termcap, you can add these lines to your .vimrc: >
- :set t_ti= t_te=
-
==============================================================================
Scrolling in Insert mode *scroll-insert*
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index ca4a2e58d7..75585e878b 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -583,9 +583,6 @@ Update Vim app icon (for Gnome). (Jakub Steiner, 2013 Dec 6)
Patch to use .png icons for the toolbar on MS-Windows. (Martin Gieseking, 2013
Apr 18)
-Patch for has('unnamedplus') docs. (Tony Mechelynck, 2011 Sep 27)
-And one for gui_x11.txt.
-
":cd" doesn't work when current directory path contains "**".
finddir() has the same problem. (Yukihiro Nakadaira, 2012 Jan 10)
Requires a rewrite of the file_file_in_path code.
@@ -1522,8 +1519,6 @@ patches by Mathias, see mail Feb 22)
Win32: compiling with normal features and OLE fails. Patch by Mathias
Michaelis, 2006 Jun 4.
-Win16: include patches to make Win16 version work. (Vince Negri, 2006 May 22)
-
Win32: after "[I" showing matches, scroll wheel messes up screen. (Tsakiridis,
2007 Feb 18)
Patch by Alex Dobrynin, 2007 Jun 3. Also fixes other scroll wheel problems.
@@ -2091,14 +2086,6 @@ MSDOS and Win32:
backslashes. (Ronald Hoellwarth)
-Windows 95:
-8 Editing a file by its short file name and writing it, makes the long file
- name disappear. Setting 'backupcopy' helps.
- Use FindFirstFile()->cAlternateFileName in fname_case() (George Reilly).
-8 Doing wildcard expansion, will match the short filename, but result in the
- long filename (both DJGPP and Win32).
-
-
Win32 console:
9 When editing a file by its short file name, it should be expanded into its
long file name, to avoid problems like these: (Mccollister)
@@ -2264,9 +2251,6 @@ Macintosh:
one for B&W printing (if that can be detected).
8 In Visual block mode with 'lbr' set, a change command doesn't insert the
text in following lines where the linebreak changes.
-9 dosinst.c: The DJGPP version can't uninstall the Uninstall registry key on
- Windows NT. How to install a .inf file on Windows NT and how to detect
- that Windows NT is being used?
8 When 'virtualedit' is "block,insert" and encoding is "utf-8", selecting a
block of one double-wide character, then "d" deletes only half of it.
8 When 'virtualedit' is set, should "I" in blockwise visual mode also insert
@@ -2298,11 +2282,6 @@ Macintosh:
Or ask for permission to overwrite it (if file can be made writable) and
restore file to readonly afterwards.
Overwriting a file for which a swap file exists is similar issue.
-7 When compiled with "xterm_clipboard", startup can be slower and might get
- error message for invalid $DISPLAY. Try connecting to the X server in the
- background (forked), so that Vim starts up quicker? Connect as soon as
- the clipboard is to be used (Visual select mode starts, paste from
- clipboard)
7 X11: Some people prefer to use CLIPBOARD instead of PRIMARY for the normal
selection. Add an "xclipboard" argument to the 'clipboard' option? (Mark
Waggoner)
@@ -2441,7 +2420,7 @@ Problems that will (probably) not be solved:
- Win32: All files created on the day of switching from winter to summer
time cause "changed since editing started" messages. It goes away when
the file is written again the next day, or the timezone is adjusted.
- DJGPP version is OK. (Zaimi) Looks like a problem with the Win32 library.
+ Looks like a problem with the Win32 library.
Rebooting doesn't help. Time stamps look OK in directory. (Penn)
Is this on FAT (stores wall clock time) or NTFS (stores UTS)?
- Win32, MS-Windows XP: $HOME uses the wrong drive when the user profiles
@@ -2573,10 +2552,6 @@ User Friendlier:
7 When Vim detects a file is being edited elsewhere and it's a gvim session
of the same user it should offer a "Raise" button, so that the other gvim
window can be displayed. (Eduard)
-8 Support saving and restoring session for X windows? It should work to do
- ":mksession" and use "-S fname" for the restart command. The
- gui_x11_wm_protocol_handler() already takes care of the rest.
- global_event_filter() for GTK.
Tab pages:
@@ -3158,8 +3133,6 @@ Performance:
8 When displaying a space with only foreground highlighting, it's the same
as a space without attributes. Avoid displaying spaces for the "~" lines
when starting up in a color terminal.
-8 Avoid alloc() for scratch buffer use, esp. in syntax.c. It's very slow on
- Win16.
8 Profiling shows that in_id_list() is used very often for C code. Can this
function be improved?
8 For an existing file, the page size of the swap file is always the
diff --git a/runtime/doc/usr_21.txt b/runtime/doc/usr_21.txt
index f7555df071..2ce23f0abf 100644
--- a/runtime/doc/usr_21.txt
+++ b/runtime/doc/usr_21.txt
@@ -77,13 +77,6 @@ better at it. You can start a new shell this way: >
This is similar to using CTRL-Z to suspend Vim. The difference is that a new
shell is started.
-When using the GUI the shell will be using the Vim window for its input and
-output. Since Vim is not a terminal emulator, this will not work perfectly.
-If you have trouble, try toggling the 'guipty' option. If this still doesn't
-work well enough, start a new terminal to run the shell in. For example with:
->
- :!xterm&
-
==============================================================================
*21.3* Remembering information; viminfo
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index fa57a91da4..7d8853f4cd 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -409,10 +409,6 @@ m *+xim* X input method |xim|
*+xfontset* X fontset support |xfontset|
*+xpm* pixmap support
m *+xpm_w32* Win32 GUI only: pixmap support |w32-xpm-support|
- *+xsmp* XSMP (X session management) support
- *+xsmp_interact* interactive XSMP (X session management) support
-N *+xterm_clipboard* Unix only: xterm clipboard handling
-m *+xterm_save* save and restore xterm screen |xterm-screens|
*/dyn* *E370* *E448*
To some of the features "/dyn" is added when the
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 19f56c4e18..6ad3dab246 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -131,7 +131,11 @@ MS-DOS support:
'bioskey'
'conskey'
+Highlight groups:
+ |hl-VisualNOS|
+
Other options:
+ 'guipty'
'macatsui'
'shelltype'
'shortname'
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index e172bbba10..636fa4b328 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -592,8 +592,6 @@ if has("gui")
call append("$", "guiheadroom\troom (in pixels) left above/below the window")
call append("$", " \tset ghr=" . &ghr)
endif
- call append("$", "guipty\tuse a pseudo-tty for I/O to external commands")
- call <SID>BinOptionG("guipty", &guipty)
if has("browse")
call append("$", "browsedir\t\"last\", \"buffer\" or \"current\": which directory used for the file browser")
call <SID>OptionG("bsdir", &bsdir)
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 2e45b5e9d6..ad5bac1898 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -40,6 +40,7 @@ file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/tui)
file(GLOB NEOVIM_SOURCES *.c os/*.c api/*.c api/private/*.c msgpack_rpc/*.c
tui/*.c)
file(GLOB_RECURSE NEOVIM_HEADERS *.h)
+file(GLOB UNIT_TEST_FIXTURES ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c)
foreach(sfile ${NEOVIM_SOURCES})
get_filename_component(f ${sfile} NAME)
@@ -94,7 +95,7 @@ foreach(gen_cdef ${gen_cdefs} DO_NOT_DEFINE_EMPTY_ATTRIBUTES)
list(APPEND gen_cflags "-D${gen_cdef}")
endif()
endforeach()
-if (SANITIZE)
+if(CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN)
list(APPEND gen_cflags "-DEXITFREE")
endif()
@@ -189,11 +190,21 @@ add_executable(nvim ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES}
target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES})
install_helper(TARGETS nvim)
-if(SANITIZE)
- message(STATUS "Enabling Clang sanitizers for nvim")
+if(CLANG_ASAN_UBSAN)
+ message(STATUS "Enabling Clang address sanitizer and undefined behavior sanitizer for nvim.")
set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ")
set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-fno-sanitize-recover -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address -fsanitize=undefined ")
set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=address -fsanitize=undefined ")
+elseif(CLANG_MSAN)
+ message(STATUS "Enabling Clang memory sanitizer for nvim.")
+ set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ")
+ set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
+ set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=memory -fsanitize-memory-track-origins ")
+elseif(CLANG_TSAN)
+ message(STATUS "Enabling Clang thread sanitizer for nvim.")
+ set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ")
+ set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-fsanitize=thread ")
+ set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=thread ")
endif()
add_library(libnvim STATIC EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES}
@@ -205,7 +216,7 @@ set_target_properties(libnvim PROPERTIES
set_property(TARGET libnvim APPEND_STRING PROPERTY COMPILE_FLAGS " -DMAKE_LIB ")
add_library(nvim-test MODULE EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES}
- ${NEOVIM_SOURCES} ${NEOVIM_HEADERS})
+ ${NEOVIM_SOURCES} ${UNIT_TEST_FIXTURES} ${NEOVIM_HEADERS})
target_link_libraries(nvim-test ${NVIM_LINK_LIBRARIES})
set_property(TARGET nvim-test APPEND_STRING PROPERTY COMPILE_FLAGS -DUNIT_TESTING)
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 93590445c9..d3ab47a505 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -20341,19 +20341,19 @@ static inline void push_job_event(Job *job, ufunc_T *callback,
}, !disable_job_defer);
}
-static void on_job_stdout(RStream *rstream, void *job, bool eof)
+static void on_job_stdout(RStream *rstream, RBuffer *buf, void *job, bool eof)
{
TerminalJobData *data = job_data(job);
- on_job_output(rstream, job, eof, data->on_stdout, "stdout");
+ on_job_output(rstream, job, buf, eof, data->on_stdout, "stdout");
}
-static void on_job_stderr(RStream *rstream, void *job, bool eof)
+static void on_job_stderr(RStream *rstream, RBuffer *buf, void *job, bool eof)
{
TerminalJobData *data = job_data(job);
- on_job_output(rstream, job, eof, data->on_stderr, "stderr");
+ on_job_output(rstream, job, buf, eof, data->on_stderr, "stderr");
}
-static void on_job_output(RStream *rstream, Job *job, bool eof,
+static void on_job_output(RStream *rstream, Job *job, RBuffer *buf, bool eof,
ufunc_T *callback, const char *type)
{
if (eof) {
@@ -20361,20 +20361,19 @@ static void on_job_output(RStream *rstream, Job *job, bool eof,
}
TerminalJobData *data = job_data(job);
- char *ptr = rstream_read_ptr(rstream);
- size_t len = rstream_pending(rstream);
+ RBUFFER_UNTIL_EMPTY(buf, ptr, len) {
+ // The order here matters, the terminal must receive the data first because
+ // push_job_event will modify the read buffer(convert NULs into NLs)
+ if (data->term) {
+ terminal_receive(data->term, ptr, len);
+ }
- // The order here matters, the terminal must receive the data first because
- // push_job_event will modify the read buffer(convert NULs into NLs)
- if (data->term) {
- terminal_receive(data->term, ptr, len);
- }
+ if (callback) {
+ push_job_event(job, callback, type, ptr, len, 0);
+ }
- if (callback) {
- push_job_event(job, callback, type, ptr, len, 0);
+ rbuffer_consumed(buf, len);
}
-
- rbuffer_consumed(rstream_buffer(rstream), len);
}
static void on_job_exit(Job *job, int status, void *d)
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index e7029b8762..d9a8dc2d69 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -2992,12 +2992,8 @@ void ex_checktime(exarg_T *eap)
static char *get_locale_val(int what)
{
- char *loc;
-
- /* Obtain the locale value from the libraries. For DJGPP this is
- * redefined and it doesn't use the arguments. */
- loc = setlocale(what, NULL);
-
+ // Obtain the locale value from the libraries.
+ char *loc = setlocale(what, NULL);
return loc;
}
diff --git a/src/nvim/lib/klist.h b/src/nvim/lib/klist.h
index 7df809f07b..10d6846133 100644
--- a/src/nvim/lib/klist.h
+++ b/src/nvim/lib/klist.h
@@ -27,10 +27,12 @@
#define _AC_KLIST_H
#include <stdlib.h>
+#include <assert.h>
#include "nvim/memory.h"
#include "nvim/func_attr.h"
+
#define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \
typedef struct { \
size_t cnt, n, max; \
@@ -95,23 +97,27 @@
kmp_free(name, kl->mp, p); \
kmp_free(name, kl->mp, p); \
kmp_destroy(name, kl->mp); \
- xfree(kl); \
+ xfree(kl); \
} \
- static inline kltype_t *kl_pushp_##name(kl_##name##_t *kl) { \
+ static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \
kl1_##name *q, *p = kmp_alloc(name, kl->mp); \
q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \
++kl->size; \
- return &q->data; \
+ q->data = d; \
} \
- static inline int kl_shift_##name(kl_##name##_t *kl, kltype_t *d) { \
+ static inline kltype_t kl_shift_at_##name(kl_##name##_t *kl, \
+ kl1_##name **n) { \
+ assert((*n)->next); \
kl1_##name *p; \
- if (kl->head->next == 0) return -1; \
--kl->size; \
- p = kl->head; kl->head = kl->head->next; \
- if (d) *d = p->data; \
+ p = *n; \
+ *n = (*n)->next; \
+ if (p == kl->head) kl->head = *n; \
+ kltype_t d = p->data; \
kmp_free(name, kl->mp, p); \
- return 0; \
- }
+ return d; \
+ } \
+
#define kliter_t(name) kl1_##name
#define klist_t(name) kl_##name##_t
@@ -122,7 +128,14 @@
#define kl_init(name) kl_init_##name()
#define kl_destroy(name, kl) kl_destroy_##name(kl)
-#define kl_pushp(name, kl) kl_pushp_##name(kl)
-#define kl_shift(name, kl, d) kl_shift_##name(kl, d)
+#define kl_push(name, kl, d) kl_push_##name(kl, d)
+#define kl_shift_at(name, kl, node) kl_shift_at_##name(kl, node)
+#define kl_shift(name, kl) kl_shift_at(name, kl, &kl->head)
#define kl_empty(kl) ((kl)->size == 0)
+// Iteration macros. It's ok to modify the list while iterating as long as a
+// `break` statement is executed before the next iteration.
+#define kl_iter(name, kl, p) kl_iter_at(name, kl, p, NULL)
+#define kl_iter_at(name, kl, p, h) \
+ for (kl1_##name *p = h ? h : kl->head; p != kl->tail; p = p->next)
+
#endif
diff --git a/src/nvim/main.c b/src/nvim/main.c
index e1bb2d0b66..50c16c51d6 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -138,6 +138,7 @@ static const char *err_extra_cmd =
/// Needed for unit tests. Must be called after `time_init()`.
void early_init(void)
{
+ fs_init();
handle_init();
(void)mb_init(); // init mb_bytelen_tab[] to ones
diff --git a/src/nvim/memory.h b/src/nvim/memory.h
index 4ff31ff732..7b477da2f5 100644
--- a/src/nvim/memory.h
+++ b/src/nvim/memory.h
@@ -1,6 +1,7 @@
#ifndef NVIM_MEMORY_H
#define NVIM_MEMORY_H
+#include <stdint.h> // for uint8_t
#include <stddef.h> // for size_t
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index df78f822d6..2a81b4f160 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -328,19 +328,17 @@ static void channel_from_stdio(void)
channel->data.streams.uv = NULL;
}
-static void job_out(RStream *rstream, void *data, bool eof)
+static void job_out(RStream *rstream, RBuffer *buf, void *data, bool eof)
{
Job *job = data;
- parse_msgpack(rstream, job_data(job), eof);
+ parse_msgpack(rstream, buf, job_data(job), eof);
}
-static void job_err(RStream *rstream, void *data, bool eof)
+static void job_err(RStream *rstream, RBuffer *rbuf, void *data, bool eof)
{
- size_t count;
- char buf[256];
-
- while ((count = rstream_pending(rstream))) {
- size_t read = rstream_read(rstream, buf, sizeof(buf) - 1);
+ while (rbuffer_size(rbuf)) {
+ char buf[256];
+ size_t read = rbuffer_read(rbuf, buf, sizeof(buf) - 1);
buf[read] = NUL;
ELOG("Channel %" PRIu64 " stderr: %s",
((Channel *)job_data(data))->id, buf);
@@ -352,7 +350,7 @@ static void job_exit(Job *job, int status, void *data)
decref(data);
}
-static void parse_msgpack(RStream *rstream, void *data, bool eof)
+static void parse_msgpack(RStream *rstream, RBuffer *rbuf, void *data, bool eof)
{
Channel *channel = data;
incref(channel);
@@ -363,14 +361,14 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof)
goto end;
}
- size_t count = rstream_pending(rstream);
+ size_t count = rbuffer_size(rbuf);
DLOG("Feeding the msgpack parser with %u bytes of data from RStream(%p)",
count,
rstream);
// Feed the unpacker with data
msgpack_unpacker_reserve_buffer(channel->unpacker, count);
- rstream_read(rstream, msgpack_unpacker_buffer(channel->unpacker), count);
+ rbuffer_read(rbuf, msgpack_unpacker_buffer(channel->unpacker), count);
msgpack_unpacker_buffer_consumed(channel->unpacker, count);
msgpack_unpacked unpacked;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 7b42467184..92734e404a 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -7278,7 +7278,10 @@ static void nv_put(cmdarg_T *cap)
*/
was_visual = true;
regname = cap->oap->regname;
- if (regname == 0 || regname == '"'
+ // '+' and '*' could be the same selection
+ bool clipoverwrite = (regname == '+' || regname == '*')
+ && (cb_flags & CB_UNNAMEDMASK);
+ if (regname == 0 || regname == '"' || clipoverwrite
|| ascii_isdigit(regname) || regname == '-') {
// The delete might overwrite the register we want to put, save it first
savereg = copy_register(regname);
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index d8df6ae72d..063ad154f1 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -67,8 +67,6 @@
#define PLUS_REGISTER 38
#define NUM_REGISTERS 39
-#define CB_UNNAMEDMASK (CB_UNNAMED | CB_UNNAMEDPLUS)
-
static yankreg_T y_regs[NUM_REGISTERS];
static yankreg_T *y_previous = NULL; /* ptr to last written yankreg */
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 8ec5640b7a..113c47f112 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -366,7 +366,7 @@ typedef struct vimoption {
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText," \
"d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr," \
"N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title," \
- "v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn," \
+ "v:Visual,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn," \
"A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal," \
"B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel," \
"x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill," \
@@ -842,9 +842,6 @@ static vimoption_T
(char_u *)NULL, PV_NONE,
{(char_u *)NULL, (char_u *)0L}
SCRIPTID_INIT},
- {"guipty", NULL, P_BOOL|P_VI_DEF,
- (char_u *)NULL, PV_NONE,
- {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
{"guitablabel", "gtl", P_STRING|P_VI_DEF|P_RWIN,
(char_u *)NULL, PV_NONE,
{(char_u *)NULL, (char_u *)0L}
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 80f2373a85..b13ead9cbb 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -318,6 +318,7 @@ static char *(p_cb_values[]) = {"unnamed", "unnamedplus", NULL};
#endif
# define CB_UNNAMED 0x001
# define CB_UNNAMEDPLUS 0x002
+# define CB_UNNAMEDMASK (CB_UNNAMED | CB_UNNAMEDPLUS)
EXTERN long p_cwh; /* 'cmdwinheight' */
EXTERN long p_ch; /* 'cmdheight' */
EXTERN int p_confirm; /* 'confirm' */
diff --git a/src/nvim/os/event.c b/src/nvim/os/event.c
index 4c3a4581c3..56874b495d 100644
--- a/src/nvim/os/event.c
+++ b/src/nvim/os/event.c
@@ -149,7 +149,7 @@ void event_push(Event event, bool deferred)
// returns(user hits a key for example). To avoid this scenario, we call
// uv_stop when a event is enqueued.
uv_stop(uv_default_loop());
- *kl_pushp(Event, deferred ? deferred_events : immediate_events) = event;
+ kl_push(Event, deferred ? deferred_events : immediate_events, event);
}
void event_process(void)
@@ -159,9 +159,8 @@ void event_process(void)
static void process_events_from(klist_t(Event) *queue)
{
- Event event;
-
- while (kl_shift(Event, queue, &event) == 0) {
+ while (!kl_empty(queue)) {
+ Event event = kl_shift(Event, queue);
event.handler(event);
}
}
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 52c10d0ca7..553dda5e88 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -19,6 +19,15 @@
// Many fs functions from libuv return that value on success.
static const int kLibuvSuccess = 0;
+static uv_loop_t fs_loop;
+
+
+// Initialize the fs module
+void fs_init(void)
+{
+ uv_loop_init(&fs_loop);
+}
+
/// Change to the given directory.
///
@@ -184,7 +193,7 @@ int os_open(const char* path, int flags, int mode)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t open_req;
- int r = uv_fs_open(uv_default_loop(), &open_req, path, flags, mode, NULL);
+ int r = uv_fs_open(&fs_loop, &open_req, path, flags, mode, NULL);
uv_fs_req_cleanup(&open_req);
// r is the same as open_req.result (except for OOM: then only r is set).
return r;
@@ -197,7 +206,7 @@ static bool os_stat(const char *name, uv_stat_t *statbuf)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- int result = uv_fs_stat(uv_default_loop(), &request, name, NULL);
+ int result = uv_fs_stat(&fs_loop, &request, name, NULL);
*statbuf = request.statbuf;
uv_fs_req_cleanup(&request);
return (result == kLibuvSuccess);
@@ -224,7 +233,7 @@ int os_setperm(const char_u *name, int perm)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- int result = uv_fs_chmod(uv_default_loop(), &request,
+ int result = uv_fs_chmod(&fs_loop, &request,
(const char*)name, perm, NULL);
uv_fs_req_cleanup(&request);
@@ -245,7 +254,7 @@ int os_fchown(int file_descriptor, uv_uid_t owner, uv_gid_t group)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- int result = uv_fs_fchown(uv_default_loop(), &request, file_descriptor,
+ int result = uv_fs_fchown(&fs_loop, &request, file_descriptor,
owner, group, NULL);
uv_fs_req_cleanup(&request);
return result;
@@ -294,7 +303,7 @@ int os_rename(const char_u *path, const char_u *new_path)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- int result = uv_fs_rename(uv_default_loop(), &request,
+ int result = uv_fs_rename(&fs_loop, &request,
(const char *)path, (const char *)new_path, NULL);
uv_fs_req_cleanup(&request);
@@ -312,7 +321,7 @@ int os_mkdir(const char *path, int32_t mode)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- int result = uv_fs_mkdir(uv_default_loop(), &request, path, mode, NULL);
+ int result = uv_fs_mkdir(&fs_loop, &request, path, mode, NULL);
uv_fs_req_cleanup(&request);
return result;
}
@@ -328,7 +337,7 @@ int os_mkdtemp(const char *template, char *path)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- int result = uv_fs_mkdtemp(uv_default_loop(), &request, template, NULL);
+ int result = uv_fs_mkdtemp(&fs_loop, &request, template, NULL);
if (result == kLibuvSuccess) {
STRNCPY(path, request.path, TEMP_FILE_PATH_MAXLEN);
}
@@ -343,7 +352,7 @@ int os_rmdir(const char *path)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- int result = uv_fs_rmdir(uv_default_loop(), &request, path, NULL);
+ int result = uv_fs_rmdir(&fs_loop, &request, path, NULL);
uv_fs_req_cleanup(&request);
return result;
}
@@ -356,7 +365,7 @@ int os_rmdir(const char *path)
bool os_scandir(Directory *dir, const char *path)
FUNC_ATTR_NONNULL_ALL
{
- int r = uv_fs_scandir(uv_default_loop(), &dir->request, path, 0, NULL);
+ int r = uv_fs_scandir(&fs_loop, &dir->request, path, 0, NULL);
if (r <= 0) {
os_closedir(dir);
}
@@ -388,7 +397,7 @@ int os_remove(const char *path)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- int result = uv_fs_unlink(uv_default_loop(), &request, path, NULL);
+ int result = uv_fs_unlink(&fs_loop, &request, path, NULL);
uv_fs_req_cleanup(&request);
return result;
}
@@ -413,7 +422,7 @@ bool os_fileinfo_link(const char *path, FileInfo *file_info)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- int result = uv_fs_lstat(uv_default_loop(), &request, path, NULL);
+ int result = uv_fs_lstat(&fs_loop, &request, path, NULL);
file_info->stat = request.statbuf;
uv_fs_req_cleanup(&request);
return (result == kLibuvSuccess);
@@ -428,7 +437,7 @@ bool os_fileinfo_fd(int file_descriptor, FileInfo *file_info)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- int result = uv_fs_fstat(uv_default_loop(), &request, file_descriptor, NULL);
+ int result = uv_fs_fstat(&fs_loop, &request, file_descriptor, NULL);
file_info->stat = request.statbuf;
uv_fs_req_cleanup(&request);
return (result == kLibuvSuccess);
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c
index 74a5d3bc2e..726335bd9a 100644
--- a/src/nvim/os/input.c
+++ b/src/nvim/os/input.c
@@ -79,7 +79,7 @@ void input_stop(void)
// Low level input function
int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
{
- if (rbuffer_pending(input_buffer)) {
+ if (rbuffer_size(input_buffer)) {
return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen);
}
@@ -108,7 +108,7 @@ int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
return 0;
}
- if (rbuffer_pending(input_buffer)) {
+ if (rbuffer_size(input_buffer)) {
// Safe to convert rbuffer_read to int, it will never overflow since we use
// relatively small buffers.
return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen);
@@ -153,7 +153,7 @@ size_t input_enqueue(String keys)
{
char *ptr = keys.data, *end = ptr + keys.size;
- while (rbuffer_available(input_buffer) >= 6 && ptr < end) {
+ while (rbuffer_space(input_buffer) >= 6 && ptr < end) {
uint8_t buf[6] = {0};
unsigned int new_size = trans_special((uint8_t **)&ptr, buf, true);
@@ -309,16 +309,17 @@ static InbufPollResult inbuf_poll(int ms)
return input_eof ? kInputEof : kInputNone;
}
-static void read_cb(RStream *rstream, void *data, bool at_eof)
+static void read_cb(RStream *rstream, RBuffer *buf, void *data, bool at_eof)
{
if (at_eof) {
input_eof = true;
}
- char *buf = rbuffer_read_ptr(read_buffer);
- size_t buf_size = rbuffer_pending(read_buffer);
- (void)rbuffer_write(input_buffer, buf, buf_size);
- rbuffer_consumed(read_buffer, buf_size);
+ assert(rbuffer_space(input_buffer) >= rbuffer_size(read_buffer));
+ RBUFFER_UNTIL_EMPTY(read_buffer, ptr, len) {
+ (void)rbuffer_write(input_buffer, ptr, len);
+ rbuffer_consumed(read_buffer, len);
+ }
}
static void process_interrupts(void)
@@ -327,18 +328,16 @@ static void process_interrupts(void)
return;
}
- char *inbuf = rbuffer_read_ptr(input_buffer);
- size_t count = rbuffer_pending(input_buffer), consume_count = 0;
-
- for (int i = (int)count - 1; i >= 0; i--) {
- if (inbuf[i] == 3) {
+ size_t consume_count = 0;
+ RBUFFER_EACH_REVERSE(input_buffer, c, i) {
+ if ((uint8_t)c == 3) {
got_int = true;
- consume_count = (size_t)i;
+ consume_count = i;
break;
}
}
- if (got_int) {
+ if (got_int && consume_count) {
// Remove everything typed before the CTRL-C
rbuffer_consumed(input_buffer, consume_count);
}
@@ -362,7 +361,7 @@ static int push_event_key(uint8_t *buf, int maxlen)
static bool input_ready(void)
{
return typebuf_was_filled || // API call filled typeahead
- rbuffer_pending(input_buffer) > 0 || // Input buffer filled
+ rbuffer_size(input_buffer) || // Input buffer filled
event_has_deferred(); // Events must be processed
}
diff --git a/src/nvim/os/job.c b/src/nvim/os/job.c
index 038d0e3c26..4769ee4d2f 100644
--- a/src/nvim/os/job.c
+++ b/src/nvim/os/job.c
@@ -404,17 +404,17 @@ static void job_stop_timer_cb(uv_timer_t *handle)
}
// Wraps the call to std{out,err}_cb and emits a JobExit event if necessary.
-static void read_cb(RStream *rstream, void *data, bool eof)
+static void read_cb(RStream *rstream, RBuffer *buf, void *data, bool eof)
{
Job *job = data;
if (rstream == job->out) {
- job->opts.stdout_cb(rstream, data, eof);
+ job->opts.stdout_cb(rstream, buf, data, eof);
if (eof) {
close_job_out(job);
}
} else {
- job->opts.stderr_cb(rstream, data, eof);
+ job->opts.stderr_cb(rstream, buf, data, eof);
if (eof) {
close_job_err(job);
}
diff --git a/src/nvim/os/rstream.c b/src/nvim/os/rstream.c
index 702f282d53..af84288f0f 100644
--- a/src/nvim/os/rstream.c
+++ b/src/nvim/os/rstream.c
@@ -14,12 +14,6 @@
#include "nvim/log.h"
#include "nvim/misc1.h"
-struct rbuffer {
- char *data;
- size_t capacity, rpos, wpos;
- RStream *rstream;
-};
-
struct rstream {
void *data;
uv_buf_t uvbuf;
@@ -37,135 +31,6 @@ struct rstream {
# include "os/rstream.c.generated.h"
#endif
-/// Creates a new `RBuffer` instance.
-RBuffer *rbuffer_new(size_t capacity)
-{
- RBuffer *rv = xmalloc(sizeof(RBuffer));
- rv->data = xmalloc(capacity);
- rv->capacity = capacity;
- rv->rpos = rv->wpos = 0;
- rv->rstream = NULL;
- return rv;
-}
-
-/// Advances `rbuffer` read pointers to consume data. If the associated
-/// RStream had stopped because the buffer was full, this will restart it.
-///
-/// This is called automatically by rbuffer_read, but when using
-/// `rbuffer_read_ptr` directly, this needs to called after the data was
-/// consumed.
-void rbuffer_consumed(RBuffer *rbuffer, size_t count)
-{
- rbuffer->rpos += count;
- if (count && rbuffer->wpos == rbuffer->capacity) {
- // `wpos` is at the end of the buffer, so free some space by moving unread
- // data...
- rbuffer_relocate(rbuffer);
- if (rbuffer->rstream) {
- // restart the associated RStream
- rstream_start(rbuffer->rstream);
- }
- }
-}
-
-/// Advances `rbuffer` write pointers. If the internal buffer becomes full,
-/// this will stop the associated RStream instance.
-void rbuffer_produced(RBuffer *rbuffer, size_t count)
-{
- rbuffer->wpos += count;
- DLOG("Received %u bytes from RStream(%p)", (size_t)count, rbuffer->rstream);
-
- rbuffer_relocate(rbuffer);
- if (rbuffer->rstream && rbuffer->wpos == rbuffer->capacity) {
- // The last read filled the buffer, stop reading for now
- //
- rstream_stop(rbuffer->rstream);
- DLOG("Buffer for RStream(%p) is full, stopping it", rbuffer->rstream);
- }
-}
-
-/// Reads data from a `RBuffer` instance into a raw buffer.
-///
-/// @param rbuffer The `RBuffer` instance
-/// @param buffer The buffer which will receive the data
-/// @param count Number of bytes that `buffer` can accept
-/// @return The number of bytes copied into `buffer`
-size_t rbuffer_read(RBuffer *rbuffer, char *buffer, size_t count)
-{
- size_t read_count = rbuffer_pending(rbuffer);
-
- if (count < read_count) {
- read_count = count;
- }
-
- if (read_count > 0) {
- memcpy(buffer, rbuffer_read_ptr(rbuffer), read_count);
- rbuffer_consumed(rbuffer, read_count);
- }
-
- return read_count;
-}
-
-/// Copies data to `rbuffer` read queue.
-///
-/// @param rbuffer the `RBuffer` instance
-/// @param buffer The buffer containing data to be copied
-/// @param count Number of bytes that should be copied
-/// @return The number of bytes actually copied
-size_t rbuffer_write(RBuffer *rbuffer, char *buffer, size_t count)
-{
- size_t write_count = rbuffer_available(rbuffer);
-
- if (count < write_count) {
- write_count = count;
- }
-
- if (write_count > 0) {
- memcpy(rbuffer_write_ptr(rbuffer), buffer, write_count);
- rbuffer_produced(rbuffer, write_count);
- }
-
- return write_count;
-}
-
-/// Returns a pointer to a raw buffer containing the first byte available for
-/// reading.
-char *rbuffer_read_ptr(RBuffer *rbuffer)
-{
- return rbuffer->data + rbuffer->rpos;
-}
-
-/// Returns a pointer to a raw buffer containing the first byte available for
-/// write.
-char *rbuffer_write_ptr(RBuffer *rbuffer)
-{
- return rbuffer->data + rbuffer->wpos;
-}
-
-/// Returns the number of bytes ready for consumption in `rbuffer`
-///
-/// @param rbuffer The `RBuffer` instance
-/// @return The number of bytes ready for consumption
-size_t rbuffer_pending(RBuffer *rbuffer)
-{
- return rbuffer->wpos - rbuffer->rpos;
-}
-
-/// Returns available space in `rbuffer`
-///
-/// @param rbuffer The `RBuffer` instance
-/// @return The space available in number of bytes
-size_t rbuffer_available(RBuffer *rbuffer)
-{
- return rbuffer->capacity - rbuffer->wpos;
-}
-
-void rbuffer_free(RBuffer *rbuffer)
-{
- xfree(rbuffer->data);
- xfree(rbuffer);
-}
-
/// Creates a new RStream instance. A RStream encapsulates all the boilerplate
/// necessary for reading from a libuv stream.
///
@@ -177,8 +42,10 @@ void rbuffer_free(RBuffer *rbuffer)
RStream * rstream_new(rstream_cb cb, RBuffer *buffer, void *data)
{
RStream *rv = xmalloc(sizeof(RStream));
+ buffer->data = rv;
+ buffer->full_cb = on_rbuffer_full;
+ buffer->nonfull_cb = on_rbuffer_nonfull;
rv->buffer = buffer;
- rv->buffer->rstream = rv;
rv->fpos = 0;
rv->data = data;
rv->cb = cb;
@@ -190,16 +57,14 @@ RStream * rstream_new(rstream_cb cb, RBuffer *buffer, void *data)
return rv;
}
-/// Returns the read pointer used by the rstream.
-char *rstream_read_ptr(RStream *rstream)
+static void on_rbuffer_full(RBuffer *buf, void *data)
{
- return rbuffer_read_ptr(rstream->buffer);
+ rstream_stop(data);
}
-/// Returns the number of bytes before the rstream is full.
-size_t rstream_available(RStream *rstream)
+static void on_rbuffer_nonfull(RBuffer *buf, void *data)
{
- return rbuffer_available(rstream->buffer);
+ rstream_start(data);
}
/// Frees all memory allocated for a RStream instance
@@ -297,37 +162,13 @@ void rstream_stop(RStream *rstream)
}
}
-/// Returns the number of bytes ready for consumption in `rstream`
-size_t rstream_pending(RStream *rstream)
-{
- return rbuffer_pending(rstream->buffer);
-}
-
-/// Reads data from a `RStream` instance into a buffer.
-///
-/// @param rstream The `RStream` instance
-/// @param buffer The buffer which will receive the data
-/// @param count Number of bytes that `buffer` can accept
-/// @return The number of bytes copied into `buffer`
-size_t rstream_read(RStream *rstream, char *buffer, size_t count)
-{
- return rbuffer_read(rstream->buffer, buffer, count);
-}
-
-RBuffer *rstream_buffer(RStream *rstream)
-{
- return rstream->buffer;
-}
-
// Callbacks used by libuv
// Called by libuv to allocate memory for reading.
static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
{
RStream *rstream = handle_get_rstream(handle);
-
- buf->len = rbuffer_available(rstream->buffer);
- buf->base = rbuffer_write_ptr(rstream->buffer);
+ buf->base = rbuffer_write_ptr(rstream->buffer, &buf->len);
}
// Callback invoked by libuv after it copies the data into the buffer provided
@@ -338,23 +179,30 @@ static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
RStream *rstream = handle_get_rstream((uv_handle_t *)stream);
if (cnt <= 0) {
- if (cnt != UV_ENOBUFS) {
- DLOG("Closing RStream(%p)", rstream);
+ if (cnt != UV_ENOBUFS
+ // cnt == 0 means libuv asked for a buffer and decided it wasn't needed:
+ // http://docs.libuv.org/en/latest/stream.html#c.uv_read_start.
+ //
+ // We don't need to do anything with the RBuffer because the next call
+ // to `alloc_cb` will return the same unused pointer(`rbuffer_produced`
+ // won't be called)
+ && cnt != 0) {
+ DLOG("Closing RStream(%p) because of %s(%zd)", rstream,
+ uv_strerror((int)cnt), cnt);
// Read error or EOF, either way stop the stream and invoke the callback
// with eof == true
uv_read_stop(stream);
- rstream->cb(rstream, rstream->data, true);
+ rstream->cb(rstream, rstream->buffer, rstream->data, true);
}
return;
}
// at this point we're sure that cnt is positive, no error occurred
- size_t nread = (size_t) cnt;
-
+ size_t nread = (size_t)cnt;
// Data was already written, so all we need is to update 'wpos' to reflect
// the space actually used in the buffer.
rbuffer_produced(rstream->buffer, nread);
- rstream->cb(rstream, rstream->data, false);
+ rstream->cb(rstream, rstream->buffer, rstream->data, false);
}
// Called by the by the 'idle' handle to emulate a reading event
@@ -363,8 +211,7 @@ static void fread_idle_cb(uv_idle_t *handle)
uv_fs_t req;
RStream *rstream = handle_get_rstream((uv_handle_t *)handle);
- rstream->uvbuf.len = rbuffer_available(rstream->buffer);
- rstream->uvbuf.base = rbuffer_write_ptr(rstream->buffer);
+ rstream->uvbuf.base = rbuffer_write_ptr(rstream->buffer, &rstream->uvbuf.len);
// the offset argument to uv_fs_read is int64_t, could someone really try
// to read more than 9 quintillion (9e18) bytes?
@@ -389,7 +236,7 @@ static void fread_idle_cb(uv_idle_t *handle)
if (req.result <= 0) {
uv_idle_stop(rstream->fread_idle);
- rstream->cb(rstream, rstream->data, true);
+ rstream->cb(rstream, rstream->buffer, rstream->data, true);
return;
}
@@ -404,15 +251,3 @@ static void close_cb(uv_handle_t *handle)
xfree(handle->data);
xfree(handle);
}
-
-static void rbuffer_relocate(RBuffer *rbuffer)
-{
- assert(rbuffer->rpos <= rbuffer->wpos);
- // Move data ...
- memmove(
- rbuffer->data, // ...to the beginning of the buffer(rpos 0)
- rbuffer->data + rbuffer->rpos, // ...From the first unread position
- rbuffer->wpos - rbuffer->rpos); // ...By the number of unread bytes
- rbuffer->wpos -= rbuffer->rpos;
- rbuffer->rpos = 0;
-}
diff --git a/src/nvim/os/rstream.h b/src/nvim/os/rstream.h
index 713d1e77e6..3e24724573 100644
--- a/src/nvim/os/rstream.h
+++ b/src/nvim/os/rstream.h
@@ -5,7 +5,6 @@
#include <stdint.h>
#include <uv.h>
#include "nvim/os/event_defs.h"
-
#include "nvim/os/rstream_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/os/rstream_defs.h b/src/nvim/os/rstream_defs.h
index 1d71160963..45dced0b62 100644
--- a/src/nvim/os/rstream_defs.h
+++ b/src/nvim/os/rstream_defs.h
@@ -3,15 +3,18 @@
#include <stdbool.h>
-typedef struct rbuffer RBuffer;
+#include "nvim/rbuffer.h"
+
typedef struct rstream RStream;
/// Type of function called when the RStream receives data
///
/// @param rstream The RStream instance
+/// @param rbuffer The associated RBuffer instance
/// @param data State associated with the RStream instance
/// @param eof If the stream reached EOF.
-typedef void (*rstream_cb)(RStream *rstream, void *data, bool eof);
+typedef void (*rstream_cb)(RStream *rstream, RBuffer *buf, void *data,
+ bool eof);
#endif // NVIM_OS_RSTREAM_DEFS_H
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 2de3b1aeed..48174533a6 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -283,25 +283,28 @@ static void dynamic_buffer_ensure(DynamicBuffer *buf, size_t desired)
buf->data = xrealloc(buf->data, buf->cap);
}
-static void system_data_cb(RStream *rstream, void *data, bool eof)
+static void system_data_cb(RStream *rstream, RBuffer *buf, void *data, bool eof)
{
Job *job = data;
- DynamicBuffer *buf = job_data(job);
+ DynamicBuffer *dbuf = job_data(job);
- size_t nread = rstream_pending(rstream);
-
- dynamic_buffer_ensure(buf, buf->len + nread + 1);
- rstream_read(rstream, buf->data + buf->len, nread);
-
- buf->len += nread;
+ size_t nread = buf->size;
+ dynamic_buffer_ensure(dbuf, dbuf->len + nread + 1);
+ rbuffer_read(buf, dbuf->data + dbuf->len, nread);
+ dbuf->len += nread;
}
-static void out_data_cb(RStream *rstream, void *data, bool eof)
+static void out_data_cb(RStream *rstream, RBuffer *buf, void *data, bool eof)
{
- RBuffer *rbuffer = rstream_buffer(rstream);
- size_t written = write_output(rbuffer_read_ptr(rbuffer),
- rbuffer_pending(rbuffer), false, eof);
- rbuffer_consumed(rbuffer, written);
+ RBUFFER_UNTIL_EMPTY(buf, ptr, len) {
+ size_t written = write_output(ptr, len, false,
+ eof && len <= rbuffer_size(buf));
+ if (written) {
+ rbuffer_consumed(buf, written);
+ } else {
+ break;
+ }
+ }
}
/// Parses a command string into a sequence of words, taking quotes into
diff --git a/src/nvim/rbuffer.c b/src/nvim/rbuffer.c
new file mode 100644
index 0000000000..9cf681585b
--- /dev/null
+++ b/src/nvim/rbuffer.c
@@ -0,0 +1,205 @@
+#include <assert.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "nvim/memory.h"
+#include "nvim/vim.h"
+#include "nvim/rbuffer.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "rbuffer.c.generated.h"
+#endif
+
+/// Creates a new `RBuffer` instance.
+RBuffer *rbuffer_new(size_t capacity)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
+{
+ if (!capacity) {
+ capacity = 0xffff;
+ }
+
+ RBuffer *rv = xmalloc(sizeof(RBuffer) + capacity);
+ rv->full_cb = rv->nonfull_cb = NULL;
+ rv->data = NULL;
+ rv->size = 0;
+ rv->write_ptr = rv->read_ptr = rv->start_ptr;
+ rv->end_ptr = rv->start_ptr + capacity;
+ return rv;
+}
+
+void rbuffer_free(RBuffer *buf)
+{
+ xfree(buf);
+}
+
+size_t rbuffer_size(RBuffer *buf) FUNC_ATTR_NONNULL_ALL
+{
+ return buf->size;
+}
+
+size_t rbuffer_capacity(RBuffer *buf) FUNC_ATTR_NONNULL_ALL
+{
+ return (size_t)(buf->end_ptr - buf->start_ptr);
+}
+
+size_t rbuffer_space(RBuffer *buf) FUNC_ATTR_NONNULL_ALL
+{
+ return rbuffer_capacity(buf) - buf->size;
+}
+
+/// Return a pointer to a raw buffer containing the first empty slot available
+/// for writing. The second argument is a pointer to the maximum number of
+/// bytes that could be written.
+///
+/// It is necessary to call this function twice to ensure all empty space was
+/// used. See RBUFFER_UNTIL_FULL for a macro that simplifies this task.
+char *rbuffer_write_ptr(RBuffer *buf, size_t *write_count) FUNC_ATTR_NONNULL_ALL
+{
+ if (buf->size == rbuffer_capacity(buf)) {
+ *write_count = 0;
+ return NULL;
+ }
+
+ if (buf->write_ptr >= buf->read_ptr) {
+ *write_count = (size_t)(buf->end_ptr - buf->write_ptr);
+ } else {
+ *write_count = (size_t)(buf->read_ptr - buf->write_ptr);
+ }
+
+ return buf->write_ptr;
+}
+
+/// Adjust `rbuffer` write pointer to reflect produced data. This is called
+/// automatically by `rbuffer_write`, but when using `rbuffer_write_ptr`
+/// directly, this needs to called after the data was copied to the internal
+/// buffer. The write pointer will be wrapped if required.
+void rbuffer_produced(RBuffer *buf, size_t count) FUNC_ATTR_NONNULL_ALL
+{
+ assert(count && count <= rbuffer_space(buf));
+
+ buf->write_ptr += count;
+ if (buf->write_ptr >= buf->end_ptr) {
+ // wrap around
+ buf->write_ptr -= rbuffer_capacity(buf);
+ }
+
+ buf->size += count;
+ if (buf->full_cb && !rbuffer_space(buf)) {
+ buf->full_cb(buf, buf->data);
+ }
+}
+
+/// Return a pointer to a raw buffer containing the first byte available
+/// for reading. The second argument is a pointer to the maximum number of
+/// bytes that could be read.
+///
+/// It is necessary to call this function twice to ensure all available bytes
+/// were read. See RBUFFER_UNTIL_EMPTY for a macro that simplifies this task.
+char *rbuffer_read_ptr(RBuffer *buf, size_t *read_count) FUNC_ATTR_NONNULL_ALL
+{
+ if (!buf->size) {
+ *read_count = 0;
+ return NULL;
+ }
+
+ if (buf->read_ptr < buf->write_ptr) {
+ *read_count = (size_t)(buf->write_ptr - buf->read_ptr);
+ } else {
+ *read_count = (size_t)(buf->end_ptr - buf->read_ptr);
+ }
+
+ return buf->read_ptr;
+}
+
+/// Adjust `rbuffer` read pointer to reflect consumed data. This is called
+/// automatically by `rbuffer_read`, but when using `rbuffer_read_ptr`
+/// directly, this needs to called after the data was copied from the internal
+/// buffer. The read pointer will be wrapped if required.
+void rbuffer_consumed(RBuffer *buf, size_t count)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(count && count <= buf->size);
+
+ buf->read_ptr += count;
+ if (buf->read_ptr >= buf->end_ptr) {
+ buf->read_ptr -= rbuffer_capacity(buf);
+ }
+
+ bool was_full = buf->size == rbuffer_capacity(buf);
+ buf->size -= count;
+ if (buf->nonfull_cb && was_full) {
+ buf->nonfull_cb(buf, buf->data);
+ }
+}
+
+// Higher level functions for copying from/to RBuffer instances and data
+// pointers
+size_t rbuffer_write(RBuffer *buf, char *src, size_t src_size)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t size = src_size;
+
+ RBUFFER_UNTIL_FULL(buf, wptr, wcnt) {
+ size_t copy_count = MIN(src_size, wcnt);
+ memcpy(wptr, src, copy_count);
+ rbuffer_produced(buf, copy_count);
+
+ if (!(src_size -= copy_count)) {
+ return size;
+ }
+
+ src += copy_count;
+ }
+
+ return size - src_size;
+}
+
+size_t rbuffer_read(RBuffer *buf, char *dst, size_t dst_size)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t size = dst_size;
+
+ RBUFFER_UNTIL_EMPTY(buf, rptr, rcnt) {
+ size_t copy_count = MIN(dst_size, rcnt);
+ memcpy(dst, rptr, copy_count);
+ rbuffer_consumed(buf, copy_count);
+
+ if (!(dst_size -= copy_count)) {
+ return size;
+ }
+
+ dst += copy_count;
+ }
+
+ return size - dst_size;
+}
+
+char *rbuffer_get(RBuffer *buf, size_t index)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
+{
+ assert(index < buf->size);
+ char *rptr = buf->read_ptr + index;
+ if (rptr >= buf->end_ptr) {
+ rptr -= rbuffer_capacity(buf);
+ }
+ return rptr;
+}
+
+int rbuffer_cmp(RBuffer *buf, const char *str, size_t count)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(count <= buf->size);
+ size_t rcnt;
+ (void)rbuffer_read_ptr(buf, &rcnt);
+ size_t n = MIN(count, rcnt);
+ int rv = memcmp(str, buf->read_ptr, n);
+ count -= n;
+ size_t remaining = buf->size - rcnt;
+
+ if (rv || !count || !remaining) {
+ return rv;
+ }
+
+ return memcmp(str + n, buf->start_ptr, count);
+}
+
diff --git a/src/nvim/rbuffer.h b/src/nvim/rbuffer.h
new file mode 100644
index 0000000000..b205db0b5a
--- /dev/null
+++ b/src/nvim/rbuffer.h
@@ -0,0 +1,83 @@
+// Ring buffer implementation. This is basically an array that wraps read/write
+// pointers around the memory region. It should be more efficient than the old
+// RBuffer which required memmove() calls to relocate read/write positions.
+//
+// The main purpose of RBuffer is simplify memory management when reading from
+// uv_stream_t instances:
+//
+// - The event loop writes data to a RBuffer, advancing the write pointer
+// - The main loop reads data, advancing the read pointer
+// - If the buffer becomes full(size == capacity) the rstream is temporarily
+// stopped(automatic backpressure handling)
+//
+// Reference: http://en.wikipedia.org/wiki/Circular_buffer
+#ifndef NVIM_RBUFFER_H
+#define NVIM_RBUFFER_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+// Macros that simplify working with the read/write pointers directly by hiding
+// ring buffer wrap logic. Some examples:
+//
+// - Pass the write pointer to a function(write_data) that incrementally
+// produces data, returning the number of bytes actually written to the
+// ring buffer:
+//
+// RBUFFER_UNTIL_FULL(rbuf, ptr, cnt)
+// rbuffer_produced(rbuf, write_data(state, ptr, cnt));
+//
+// - Pass the read pointer to a function(read_data) that incrementally
+// consumes data, returning the number of bytes actually read from the
+// ring buffer:
+//
+// RBUFFER_UNTIL_EMPTY(rbuf, ptr, cnt)
+// rbuffer_consumed(rbuf, read_data(state, ptr, cnt));
+//
+// Note that the rbuffer_{produced,consumed} calls are necessary or these macros
+// create infinite loops
+#define RBUFFER_UNTIL_EMPTY(buf, rptr, rcnt) \
+ for (size_t rcnt = 0, _r = 1; _r; _r = 0) \
+ for (char *rptr = rbuffer_read_ptr(buf, &rcnt); \
+ buf->size; \
+ rptr = rbuffer_read_ptr(buf, &rcnt))
+
+#define RBUFFER_UNTIL_FULL(buf, wptr, wcnt) \
+ for (size_t wcnt = 0, _r = 1; _r; _r = 0) \
+ for (char *wptr = rbuffer_write_ptr(buf, &wcnt); \
+ rbuffer_space(buf); \
+ wptr = rbuffer_write_ptr(buf, &wcnt))
+
+
+// Iteration
+#define RBUFFER_EACH(buf, c, i) \
+ for (size_t i = 0; i < buf->size; i = buf->size) \
+ for (char c = 0; \
+ i < buf->size ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \
+ i++)
+
+#define RBUFFER_EACH_REVERSE(buf, c, i) \
+ for (size_t i = buf->size; i != SIZE_MAX; i = SIZE_MAX) \
+ for (char c = 0; \
+ i-- > 0 ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \
+ )
+
+typedef struct rbuffer RBuffer;
+/// Type of function invoked during certain events:
+/// - When the RBuffer switches to the full state
+/// - When the RBuffer switches to the non-full state
+typedef void(*rbuffer_callback)(RBuffer *buf, void *data);
+
+struct rbuffer {
+ rbuffer_callback full_cb, nonfull_cb;
+ void *data;
+ size_t size;
+ char *end_ptr, *read_ptr, *write_ptr;
+ char start_ptr[];
+};
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "rbuffer.h.generated.h"
+#endif
+
+#endif // NVIM_RBUFFER_H
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 63fc7b80a7..f312670a96 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -4116,7 +4116,7 @@ static int badword_captype(char_u *word, char_u *end)
// Delete the internal wordlist and its .spl file.
void spell_delete_wordlist(void)
{
- char_u fname[MAXPATHL];
+ char_u fname[MAXPATHL] = {0};
if (int_wordlist != NULL) {
os_remove((char *)int_wordlist);
diff --git a/src/nvim/testdir/test86.in b/src/nvim/testdir/test86.in
index 958bd57e29..41d9a2fa32 100644
--- a/src/nvim/testdir/test86.in
+++ b/src/nvim/testdir/test86.in
@@ -1,5 +1,8 @@
Tests for various python features. vim: set ft=vim :
+This test is not run in Neovim(see the has('nvim') check below) because the
+python compatibility layer is not complete.
+
NOTE: This will cause errors when run under valgrind.
This would require recompiling Python with:
./configure --without-pymalloc
diff --git a/src/nvim/testdir/test87.in b/src/nvim/testdir/test87.in
index cad778e858..58f9ac6418 100644
--- a/src/nvim/testdir/test87.in
+++ b/src/nvim/testdir/test87.in
@@ -1,9 +1,12 @@
Tests for various python features. vim: set ft=vim :
+This test is not run in Neovim(see the has('nvim') check below) because the
+python3 compatibility layer is not complete.
+
STARTTEST
:so small.vim
:set noswapfile
-:if !has('python3') | e! test.ok | wq! test.out | endif
+:if !has('python3') || has('nvim') | e! test.ok | wq! test.out | endif
:lang C
:fun Test()
:py3 import vim
diff --git a/src/nvim/tui/term_input.inl b/src/nvim/tui/term_input.inl
index d25cbb7ba1..451ac195f2 100644
--- a/src/nvim/tui/term_input.inl
+++ b/src/nvim/tui/term_input.inl
@@ -162,11 +162,10 @@ static void timer_cb(uv_timer_t *handle)
static bool handle_bracketed_paste(TermInput *input)
{
- char *ptr = rbuffer_read_ptr(input->read_buffer);
- size_t len = rbuffer_pending(input->read_buffer);
- if (len > 5 && (!strncmp(ptr, "\x1b[200~", 6)
- || !strncmp(ptr, "\x1b[201~", 6))) {
- bool enable = ptr[4] == '0';
+ if (rbuffer_size(input->read_buffer) > 5 &&
+ (!rbuffer_cmp(input->read_buffer, "\x1b[200~", 6) ||
+ !rbuffer_cmp(input->read_buffer, "\x1b[201~", 6))) {
+ bool enable = *rbuffer_get(input->read_buffer, 4) == '0';
// Advance past the sequence
rbuffer_consumed(input->read_buffer, 6);
if (input->paste_enabled == enable) {
@@ -195,11 +194,11 @@ static bool handle_bracketed_paste(TermInput *input)
static bool handle_forced_escape(TermInput *input)
{
- char *ptr = rbuffer_read_ptr(input->read_buffer);
- size_t len = rbuffer_pending(input->read_buffer);
- if (len > 1 && ptr[0] == ESC && ptr[1] == NUL) {
+ if (rbuffer_size(input->read_buffer) > 1
+ && !rbuffer_cmp(input->read_buffer, "\x1b\x00", 2)) {
// skip the ESC and NUL and push one <esc> to the input buffer
- termkey_push_bytes(input->tk, ptr, 1);
+ size_t rcnt;
+ termkey_push_bytes(input->tk, rbuffer_read_ptr(input->read_buffer, &rcnt), 1);
rbuffer_consumed(input->read_buffer, 2);
tk_getkeys(input, true);
return true;
@@ -207,9 +206,9 @@ static bool handle_forced_escape(TermInput *input)
return false;
}
-static void read_cb(RStream *rstream, void *rstream_data, bool eof)
+static void read_cb(RStream *rstream, RBuffer *buf, void *data, bool eof)
{
- TermInput *input = rstream_data;
+ TermInput *input = data;
if (eof) {
if (input->in_fd == 0 && !os_isatty(0) && os_isatty(2)) {
@@ -236,19 +235,33 @@ static void read_cb(RStream *rstream, void *rstream_data, bool eof)
if (handle_bracketed_paste(input) || handle_forced_escape(input)) {
continue;
}
- char *ptr = rbuffer_read_ptr(input->read_buffer);
- size_t len = rbuffer_pending(input->read_buffer);
- // Find the next 'esc' and push everything up to it(excluding)
- size_t i;
- for (i = ptr[0] == ESC ? 1 : 0; i < len; i++) {
- if (ptr[i] == '\x1b') {
+
+ // Find the next 'esc' and push everything up to it(excluding). This is done
+ // so the `handle_bracketed_paste`/`handle_forced_escape` calls above work
+ // as expected.
+ size_t count = 0;
+ RBUFFER_EACH(input->read_buffer, c, i) {
+ count = i + 1;
+ if (c == '\x1b' && count > 1) {
+ break;
+ }
+ }
+
+ RBUFFER_UNTIL_EMPTY(input->read_buffer, ptr, len) {
+ size_t consumed = termkey_push_bytes(input->tk, ptr, MIN(count, len));
+ // termkey_push_bytes can return (size_t)-1, so it is possible that
+ // `consumed > input->read_buffer->size`, but since tk_getkeys is called
+ // soon, it shouldn't happen
+ assert(consumed <= input->read_buffer->size);
+ rbuffer_consumed(input->read_buffer, consumed);
+ // Need to process the keys now since there's no guarantee "count" will
+ // fit into libtermkey's input buffer.
+ tk_getkeys(input, false);
+ if (!(count -= consumed)) {
break;
}
}
- size_t consumed = termkey_push_bytes(input->tk, ptr, i);
- rbuffer_consumed(input->read_buffer, consumed);
- tk_getkeys(input, false);
- } while (rbuffer_pending(input->read_buffer));
+ } while (rbuffer_size(input->read_buffer));
}
static TermInput *term_input_new(void)
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua
index 716bd88242..9282a66240 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/clipboard/clipboard_provider_spec.lua
@@ -253,6 +253,12 @@ describe('clipboard usage', function()
feed("viwp")
eq({{'visual'}, 'v'}, eval("g:test_clip['*']"))
expect("indeed clipboard")
+
+ -- explicit "* should do the same
+ execute("let g:test_clip['*'] = [['star'], 'c']")
+ feed('viw"*p')
+ eq({{'clipboard'}, 'v'}, eval("g:test_clip['*']"))
+ expect("indeed star")
end)
end)
diff --git a/test/unit/buffer_spec.lua b/test/unit/buffer_spec.lua
index 5244c2af86..e0e2b827e9 100644
--- a/test/unit/buffer_spec.lua
+++ b/test/unit/buffer_spec.lua
@@ -3,8 +3,6 @@ local helpers = require("test.unit.helpers")
local to_cstr = helpers.to_cstr
local eq = helpers.eq
-helpers.vim_init()
-
local buffer = helpers.cimport("./src/nvim/buffer.h")
local window = helpers.cimport("./src/nvim/window.h")
local option = helpers.cimport("./src/nvim/option.h")
diff --git a/test/unit/fixtures/rbuffer.c b/test/unit/fixtures/rbuffer.c
new file mode 100644
index 0000000000..d587d6b054
--- /dev/null
+++ b/test/unit/fixtures/rbuffer.c
@@ -0,0 +1,28 @@
+#include "nvim/rbuffer.h"
+#include "rbuffer.h"
+
+
+void ut_rbuffer_each_read_chunk(RBuffer *buf, each_ptr_cb cb)
+{
+ RBUFFER_UNTIL_EMPTY(buf, rptr, rcnt) {
+ cb(rptr, rcnt);
+ rbuffer_consumed(buf, rcnt);
+ }
+}
+
+void ut_rbuffer_each_write_chunk(RBuffer *buf, each_ptr_cb cb)
+{
+ RBUFFER_UNTIL_FULL(buf, wptr, wcnt) {
+ cb(wptr, wcnt);
+ rbuffer_produced(buf, wcnt);
+ }
+}
+void ut_rbuffer_each(RBuffer *buf, each_cb cb)
+{
+ RBUFFER_EACH(buf, c, i) cb(c, i);
+}
+
+void ut_rbuffer_each_reverse(RBuffer *buf, each_cb cb)
+{
+ RBUFFER_EACH_REVERSE(buf, c, i) cb(c, i);
+}
diff --git a/test/unit/fixtures/rbuffer.h b/test/unit/fixtures/rbuffer.h
new file mode 100644
index 0000000000..640092c627
--- /dev/null
+++ b/test/unit/fixtures/rbuffer.h
@@ -0,0 +1,9 @@
+#include "nvim/rbuffer.h"
+
+typedef void(*each_ptr_cb)(char *ptr, size_t cnt);
+typedef void(*each_cb)(char c, size_t i);
+
+void ut_rbuffer_each_read_chunk(RBuffer *buf, each_ptr_cb cb);
+void ut_rbuffer_each_write_chunk(RBuffer *buf, each_ptr_cb cb);
+void ut_rbuffer_each(RBuffer *buf, each_cb cb);
+void ut_rbuffer_each_reverse(RBuffer *buf, each_cb cb);
diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua
index 708e7a94ab..5bcc661226 100644
--- a/test/unit/helpers.lua
+++ b/test/unit/helpers.lua
@@ -136,15 +136,11 @@ end
-- initialize some global variables, this is still necessary to unit test
-- functions that rely on global state.
-local function vim_init()
- if vim_init_called ~= nil then
- return
- end
+do
local main = cimport('./src/nvim/main.h')
local time = cimport('./src/nvim/os/time.h')
time.time_init()
main.early_init()
- vim_init_called = true
end
-- C constants.
@@ -167,7 +163,6 @@ return {
lib = libnvim,
cstr = cstr,
to_cstr = to_cstr,
- vim_init = vim_init,
NULL = NULL,
OK = OK,
FAIL = FAIL
diff --git a/test/unit/os/env_spec.lua b/test/unit/os/env_spec.lua
index 9d936c2564..8e18c599d9 100644
--- a/test/unit/os/env_spec.lua
+++ b/test/unit/os/env_spec.lua
@@ -12,9 +12,6 @@ local NULL = helpers.NULL
require('lfs')
--- Needed because expand_env_esc uses the char table
-helpers.vim_init()
-
local env = cimport('./src/nvim/os/os.h')
describe('env function', function()
diff --git a/test/unit/rbuffer_spec.lua b/test/unit/rbuffer_spec.lua
new file mode 100644
index 0000000000..89136410d3
--- /dev/null
+++ b/test/unit/rbuffer_spec.lua
@@ -0,0 +1,350 @@
+local helpers = require("test.unit.helpers")
+
+local ffi = helpers.ffi
+local eq = helpers.eq
+local cstr = helpers.cstr
+local to_cstr = helpers.to_cstr
+
+local rbuffer = helpers.cimport("./test/unit/fixtures/rbuffer.h")
+
+describe('rbuffer functions', function()
+ local capacity = 16
+ local rbuf
+
+ local function inspect()
+ return ffi.string(rbuf.start_ptr, capacity)
+ end
+
+ local function write(str)
+ local buf = to_cstr(str)
+ return rbuffer.rbuffer_write(rbuf, buf, #str)
+ end
+
+ local function read(len)
+ local buf = cstr(len)
+ len = rbuffer.rbuffer_read(rbuf, buf, len)
+ return ffi.string(buf, len)
+ end
+
+ local function get(idx)
+ return ffi.string(rbuffer.rbuffer_get(rbuf, idx), 1)
+ end
+
+ before_each(function()
+ rbuf = ffi.gc(rbuffer.rbuffer_new(capacity), rbuffer.rbuffer_free)
+ -- fill the internal buffer with the character '0' to simplify inspecting
+ ffi.C.memset(rbuf.start_ptr, string.byte('0'), capacity)
+ end)
+
+ describe('RBUFFER_UNTIL_FULL', function()
+ local chunks
+
+ local function collect_write_chunks()
+ rbuffer.ut_rbuffer_each_write_chunk(rbuf, function(wptr, wcnt)
+ table.insert(chunks, ffi.string(wptr, wcnt))
+ end)
+ end
+
+ before_each(function()
+ chunks = {}
+ end)
+
+ describe('with empty buffer in one contiguous chunk', function()
+ it('is called once with the empty chunk', function()
+ collect_write_chunks()
+ eq({'0000000000000000'}, chunks)
+ end)
+ end)
+
+ describe('with partially empty buffer in one contiguous chunk', function()
+ before_each(function()
+ write('string')
+ end)
+
+ it('is called once with the empty chunk', function()
+ collect_write_chunks()
+ eq({'0000000000'}, chunks)
+ end)
+ end)
+
+ describe('with filled buffer in one contiguous chunk', function()
+ before_each(function()
+ write('abcdefghijklmnopq')
+ end)
+
+ it('is not called', function()
+ collect_write_chunks()
+ eq({}, chunks)
+ end)
+ end)
+
+ describe('with buffer partially empty in two contiguous chunks', function()
+ before_each(function()
+ write('1234567890')
+ read(8)
+ end)
+
+ it('is called twice with each filled chunk', function()
+ collect_write_chunks()
+ eq({'000000', '12345678'}, chunks)
+ end)
+ end)
+
+ describe('with buffer empty in two contiguous chunks', function()
+ before_each(function()
+ write('12345678')
+ read(8)
+ end)
+
+ it('is called twice with each filled chunk', function()
+ collect_write_chunks()
+ eq({'00000000', '12345678'}, chunks)
+ end)
+ end)
+
+ describe('with buffer filled in two contiguous chunks', function()
+ before_each(function()
+ write('12345678')
+ read(8)
+ write('abcdefghijklmnopq')
+ end)
+
+ it('is not called', function()
+ collect_write_chunks()
+ eq({}, chunks)
+ end)
+ end)
+ end)
+
+ describe('RBUFFER_UNTIL_EMPTY', function()
+ local chunks
+
+ local function collect_read_chunks()
+ rbuffer.ut_rbuffer_each_read_chunk(rbuf, function(rptr, rcnt)
+ table.insert(chunks, ffi.string(rptr, rcnt))
+ end)
+ end
+
+ before_each(function()
+ chunks = {}
+ end)
+
+ describe('with empty buffer', function()
+ it('is not called', function()
+ collect_read_chunks()
+ eq({}, chunks)
+ end)
+ end)
+
+ describe('with partially filled buffer in one contiguous chunk', function()
+ before_each(function()
+ write('string')
+ end)
+
+ it('is called once with the filled chunk', function()
+ collect_read_chunks()
+ eq({'string'}, chunks)
+ end)
+ end)
+
+ describe('with filled buffer in one contiguous chunk', function()
+ before_each(function()
+ write('abcdefghijklmnopq')
+ end)
+
+ it('is called once with the filled chunk', function()
+ collect_read_chunks()
+ eq({'abcdefghijklmnop'}, chunks)
+ end)
+ end)
+
+ describe('with buffer partially filled in two contiguous chunks', function()
+ before_each(function()
+ write('1234567890')
+ read(10)
+ write('long string')
+ end)
+
+ it('is called twice with each filled chunk', function()
+ collect_read_chunks()
+ eq({'long s', 'tring'}, chunks)
+ end)
+ end)
+
+ describe('with buffer filled in two contiguous chunks', function()
+ before_each(function()
+ write('12345678')
+ read(8)
+ write('abcdefghijklmnopq')
+ end)
+
+ it('is called twice with each filled chunk', function()
+ collect_read_chunks()
+ eq({'abcdefgh', 'ijklmnop'}, chunks)
+ end)
+ end)
+ end)
+
+ describe('RBUFFER_EACH', function()
+ local chars
+
+ local function collect_chars()
+ rbuffer.ut_rbuffer_each(rbuf, function(c, i)
+ table.insert(chars, {string.char(c), tonumber(i)})
+ end)
+ end
+ before_each(function()
+ chars = {}
+ end)
+
+ describe('with empty buffer', function()
+ it('is not called', function()
+ collect_chars()
+ eq({}, chars)
+ end)
+ end)
+
+ describe('with buffer filled in two contiguous chunks', function()
+ before_each(function()
+ write('1234567890')
+ read(10)
+ write('long string')
+ end)
+
+ it('collects each character and index', function()
+ collect_chars()
+ eq({{'l', 0}, {'o', 1}, {'n', 2}, {'g', 3}, {' ', 4}, {'s', 5},
+ {'t', 6}, {'r', 7}, {'i', 8}, {'n', 9}, {'g', 10}}, chars)
+ end)
+ end)
+ end)
+
+ describe('RBUFFER_EACH_REVERSE', function()
+ local chars
+
+ local function collect_chars()
+ rbuffer.ut_rbuffer_each_reverse(rbuf, function(c, i)
+ table.insert(chars, {string.char(c), tonumber(i)})
+ end)
+ end
+ before_each(function()
+ chars = {}
+ end)
+
+ describe('with empty buffer', function()
+ it('is not called', function()
+ collect_chars()
+ eq({}, chars)
+ end)
+ end)
+
+ describe('with buffer filled in two contiguous chunks', function()
+ before_each(function()
+ write('1234567890')
+ read(10)
+ write('long string')
+ end)
+
+ it('collects each character and index', function()
+ collect_chars()
+ eq({{'g', 10}, {'n', 9}, {'i', 8}, {'r', 7}, {'t', 6}, {'s', 5},
+ {' ', 4}, {'g', 3}, {'n', 2}, {'o', 1}, {'l', 0}}, chars)
+ end)
+ end)
+ end)
+
+ describe('rbuffer_cmp', function()
+ local function cmp(str)
+ local rv = rbuffer.rbuffer_cmp(rbuf, to_cstr(str), #str)
+ if rv == 0 then
+ return 0
+ else
+ return rv / math.abs(rv)
+ end
+ end
+
+ describe('with buffer filled in two contiguous chunks', function()
+ before_each(function()
+ write('1234567890')
+ read(10)
+ write('long string')
+ end)
+
+ it('compares the common longest sequence', function()
+ eq(0, cmp('long string'))
+ eq(0, cmp('long strin'))
+ eq(-1, cmp('long striM'))
+ eq(1, cmp('long strio'))
+ eq(0, cmp('long'))
+ eq(-1, cmp('lonG'))
+ eq(1, cmp('lonh'))
+ end)
+ end)
+
+ describe('with empty buffer', function()
+ it('returns 0 since no characters are compared', function()
+ eq(0, cmp(''))
+ end)
+ end)
+ end)
+
+ describe('rbuffer_write', function()
+ it('fills the internal buffer and returns the write count', function()
+ eq(12, write('short string'))
+ eq('short string0000', inspect())
+ end)
+
+ it('wont write beyond capacity', function()
+ eq(16, write('very very long string'))
+ eq('very very long s', inspect())
+ end)
+ end)
+
+ describe('rbuffer_read', function()
+ it('reads what was previously written', function()
+ write('to read')
+ eq('to read', read(20))
+ end)
+
+ it('reads nothing if the buffer is empty', function()
+ eq('', read(20))
+ write('empty')
+ eq('empty', read(20))
+ eq('', read(20))
+ end)
+ end)
+
+ describe('rbuffer_get', function()
+ it('fetch the pointer at offset, wrapping if required', function()
+ write('1234567890')
+ read(10)
+ write('long string')
+ eq('l', get(0))
+ eq('o', get(1))
+ eq('n', get(2))
+ eq('g', get(3))
+ eq(' ', get(4))
+ eq('s', get(5))
+ eq('t', get(6))
+ eq('r', get(7))
+ eq('i', get(8))
+ eq('n', get(9))
+ eq('g', get(10))
+ end)
+ end)
+
+ describe('wrapping behavior', function()
+ it('writing/reading wraps across the end of the internal buffer', function()
+ write('1234567890')
+ eq('1234', read(4))
+ eq('5678', read(4))
+ write('987654321')
+ eq('3214567890987654', inspect())
+ eq('90987654321', read(20))
+ eq('', read(4))
+ write('abcdefghijklmnopqrs')
+ eq('nopabcdefghijklm', inspect())
+ eq('abcdefghijklmnop', read(20))
+ end)
+ end)
+end)
diff --git a/test/unit/tempfile_spec.lua b/test/unit/tempfile_spec.lua
index 6484a98b8f..e558ff04c8 100644
--- a/test/unit/tempfile_spec.lua
+++ b/test/unit/tempfile_spec.lua
@@ -4,8 +4,6 @@ local helpers = require 'test.unit.helpers'
local os = helpers.cimport './src/nvim/os/os.h'
local tempfile = helpers.cimport './src/nvim/tempfile.h'
-helpers.vim_init()
-
describe('tempfile related functions', function()
after_each(function()
tempfile.vim_deltempdir()