patch 9.1.1485: missing Wayland clipboard support

Problem:  missing Wayland clipboard support
Solution: make it work (Foxe Chen)

fixes: #5157
closes: #17097

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Foxe Chen
2025-06-27 21:10:35 +02:00
committed by Christian Brabandt
parent 03125277e9
commit b90c2395b2
68 changed files with 7520 additions and 226 deletions

View File

@ -29,7 +29,6 @@ jobs:
LOG_DIR: ${{ github.workspace }}/logs
TERM: xterm
DISPLAY: ':99'
WAYLAND_DISPLAY: 'wayland-1'
DEBIAN_FRONTEND: noninteractive
strategy:
@ -125,6 +124,10 @@ jobs:
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
PKGS=( \
gettext \
x11-utils \
labwc \
wl-clipboard \
wayland-utils \
libgtk-3-dev:${{ matrix.architecture }} \
libgtk-3-bin:${{ matrix.architecture }} \
desktop-file-utils \
@ -141,7 +144,6 @@ jobs:
libwayland-cursor0:${{ matrix.architecture }} \
locales-all \
software-properties-common \
sway \
)
if ${{ contains(matrix.extra, 'asan') }} && ${{ contains(matrix.architecture, 'native') }}; then
PKGS+=( \
@ -270,8 +272,6 @@ jobs:
sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0
sudo usermod -a -G audio "${USER}"
sudo bash ci/setup-xvfb.sh
# Sway requires user session
bash ci/setup-sway.sh
- name: Check autoconf
if: contains(matrix.extra, 'unittests')

2
.gitignore vendored
View File

@ -22,6 +22,8 @@ src/auto/osdef.h
src/auto/link.log
src/auto/link.sed
src/auto/pathdef.c
src/auto/wayland/*.c
src/auto/wayland/*.h
# Windows
*.exe

View File

@ -24,6 +24,8 @@ src/auto/osdef.h
src/auto/link.log
src/auto/link.sed
src/auto/pathdef.c
src/auto/wayland/*.c
src/auto/wayland/*.h
# Windows
*.exe

View File

@ -241,6 +241,7 @@ SRC_ALL = \
src/testdir/ru_RU/LC_MESSAGES/Makefile \
src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.po \
src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo \
src/testdir/window_manager.vim \
src/proto.h \
src/protodef.h \
src/proto/alloc.pro \
@ -490,6 +491,12 @@ SRC_UNIX = \
src/gui_xmebwp.h \
src/gui_x11.c \
src/gui_x11_pm.h \
src/auto/wayland/README.txt \
src/auto/wayland/Makefile \
src/auto/wayland/protocols/ext-data-control-v1.xml \
src/auto/wayland/protocols/wlr-data-control-unstable-v1.xml \
src/auto/wayland/protocols/xdg-shell.xml \
src/auto/wayland/protocols/primary-selection-unstable-v1.xml \
src/if_xcmdsrv.c \
src/link.sh \
src/installman.sh \
@ -508,6 +515,7 @@ SRC_UNIX = \
src/proto/gui_motif.pro \
src/proto/gui_xmdlg.pro \
src/proto/gui_x11.pro \
src/proto/wayland.pro \
src/proto/if_xcmdsrv.pro \
src/proto/os_unix.pro \
src/proto/pty.pro \
@ -519,7 +527,9 @@ SRC_UNIX = \
src/vim_mask.xbm \
src/vimtutor \
src/gvimtutor \
src/wayland.c \
src/which.sh \
src/gen-wayland-protocols.sh \
src/xxd/Makefile \
# Source files for both MS Windows and Unix-like.

View File

@ -1,7 +0,0 @@
#!/bin/bash
set -e
# Using a systemd user service doesn't work because it seems like github actions
# doesn't support user sessions? Just run sway in the background and disown it.
WLR_BACKENDS=headless sway &
disown

View File

@ -153,6 +153,7 @@ DOCS = \
vim9class.txt \
visual.txt \
vietnamese.txt \
wayland.txt \
windows.txt \
workshop.txt
@ -309,6 +310,7 @@ HTMLS = \
vim9.html \
vim9class.html \
visual.html \
wayland.html \
windows.html \
workshop.html

View File

@ -1,4 +1,4 @@
*builtin.txt* For Vim version 9.1. Last change: 2025 Jun 23
*builtin.txt* For Vim version 9.1. Last change: 2025 Jun 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -13038,6 +13038,8 @@ vms VMS version of Vim.
vreplace Compiled with |gR| and |gr| commands. (always true)
vtp Compiled for vcon support |+vtp| (check vcon to find
out if it works in the current console).
wayland Compiled with Wayland protocol support.
wayland_clipboard Compiled with support for Wayland selections/clipboard
wildignore Compiled with 'wildignore' option.
wildmenu Compiled with 'wildmenu' option.
win16 old version for MS-Windows 3.1 (always false)

View File

@ -1,4 +1,4 @@
*eval.txt* For Vim version 9.1. Last change: 2025 Jun 04
*eval.txt* For Vim version 9.1. Last change: 2025 Jun 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -2240,6 +2240,15 @@ v:charconvert_to
The name of the character encoding of a file after conversion.
Only valid while evaluating the 'charconvert' option.
*v:clipmethod*
v:clipmethod The current method of accessing the clipboard that is being
used. Can either have the value of:
wayland The Wayland protocol is being used.
x11 X11 selections are being used.
none The above methods are unavailable
or cannot be used.
See 'clipmethod' for more details.
*v:cmdarg* *cmdarg-variable*
v:cmdarg This variable is used for two purposes:
1. The extra arguments given to a file read/write command.
@ -2969,6 +2978,12 @@ v:vim_did_enter Zero until most of startup is done. It is set to one just
*v:warningmsg* *warningmsg-variable*
v:warningmsg Last given warning message. It's allowed to set this variable.
*v:wayland_display*
v:wayland_display
The name of the Wayland display that Vim is connected to.
Equivalent to the $WAYLAND_DISPLAY environment variable.
If this is empty, then Vim is not connected to any display.
*v:windowid* *windowid-variable*
v:windowid When any X11/Wayland based GUI is running or when running in a
terminal and Vim connects to the X server (|-X|) this will be

View File

@ -1,4 +1,4 @@
*help.txt* For Vim version 9.1. Last change: 2024 Dec 06
*help.txt* For Vim version 9.1. Last change: 2025 Jun 27
VIM - main help file
k
@ -187,6 +187,9 @@ GUI ~
|gui_w32.txt| Win32 GUI
|gui_x11.txt| X11 GUI
System Integration ~
|wayland.txt| Wayland protocol support
Interfaces ~
|if_cscop.txt| using Cscope with Vim
|if_lua.txt| Lua interface

View File

@ -1,4 +1,4 @@
*index.txt* For Vim version 9.1. Last change: 2025 Jun 23
*index.txt* For Vim version 9.1. Last change: 2025 Jun 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1587,6 +1587,7 @@ tag command action ~
|:redrawtabpanel| :redrawtabp[anel] force a redraw of the tabpanel
|:registers| :reg[isters] display the contents of registers
|:resize| :res[ize] change current window height
|:clipreset| :clip[reset] reset 'clipmethod'
|:retab| :ret[ab] change tab size
|:return| :retu[rn] return from a user function
|:rewind| :rew[ind] go to the first file in the argument list
@ -1777,6 +1778,7 @@ tag command action ~
|:winsize| :wi[nsize] get or set window size (obsolete)
|:wincmd| :winc[md] execute a Window (CTRL-W) command
|:winpos| :winp[os] get or set window position
|:wlrestore| :wl[restore] restore the Wayland compositor connection
|:wnext| :wn[ext] write to a file and go to next file in
argument list
|:wprevious| :wp[revious] write to a file and go to previous file in

View File

@ -1,4 +1,4 @@
*options.txt* For Vim version 9.1. Last change: 2025 Jun 18
*options.txt* For Vim version 9.1. Last change: 2025 Jun 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1785,7 +1785,7 @@ A jump table for the options with a short description can be found at |Q_op|.
for X-windows, "" otherwise)
global
{only in GUI versions or when the |+xterm_clipboard|
feature is included}
or |+wayland_clipboard| features are included}
This option is a list of comma-separated names.
Note: if one of the items is "exclude:", then you can't add an item
after that. Therefore do not append an item with += but use ^= to
@ -1812,10 +1812,13 @@ A jump table for the options with a short description can be found at |Q_op|.
register. When "unnamed" is also included to the
option, yank operations (but not delete, change or
put) will additionally copy the text into register
'*'.
Only available with the |+X11| feature.
Availability can be checked with: >
if has('unnamedplus')
'*'. If wayland is being used and the compositor does
not support the primary-selection-unstable-v1
protocol, then the regular selection is used in its
place. Only available with the |+X11| or
|+wayland_clipboard| feature. Availability can be
checked with: >
if has('unnamedplus')
<
*clipboard-autoselect*
autoselect Works like the 'a' flag in 'guioptions': If present,
@ -1852,24 +1855,54 @@ A jump table for the options with a short description can be found at |Q_op|.
exclude:{pattern}
Defines a pattern that is matched against the name of
the terminal 'term'. If there is a match, no
connection will be made to the X server. This is
useful in this situation:
connection will be made to the X server or wayland
compositor. This is useful in this situation:
- Running Vim in a console.
- $DISPLAY is set to start applications on another
display.
- You do not want to connect to the X server in the
console, but do want this in a terminal emulator.
To never connect to the X server use: >
- $DISPLAY/$WAYLAND_DISPLAY is set to start
applications on another display.
- You do not want to connect to the X server/Wayland
compositor in the console, but do want this in a
terminal emulator.
To never connect to the X server/Wayland compositor
use: >
exclude:.*
< This has the same effect as using the |-X| argument.
< This has the same effect as using the |-X| or |-Y| argument.
Note that when there is no connection to the X server
the window title won't be restored and the clipboard
cannot be accessed.
cannot be accessed. This is the same for Wayland,
except there is no title restoring.
The value of 'magic' is ignored, {pattern} is
interpreted as if 'magic' was on.
The rest of the option value will be used for
{pattern}, this must be the last entry.
*'clipmethod'* *'cpm'*
'clipmethod' 'cpm' string (default for Unix: "wayland,x11",
for VMS: "x11",
otherwise: "")
global
{only when the |+xterm_clipboard| or |+wayland_clipboard|
features are included}
Specifies which method of accessing the system clipboard is used,
depending on which method works first or is available. Supported
methods are:
wayland Wayland selections
x11 X11 selections
Note: This option is ignored when either the GUI is running or if Vim
is run on a system without wayland or X11 support, such as Windows or
macOS. The GUI or system way of accessing the clipboard is always
used instead.
The option value is a list of comma separated items. The list is parsed
left to right in order, and the first method that Vim determines is
available or is working is used as the actual method for accessing the
clipboard.
The current method that is being used can be found in the |v:clipmethod|
variable.
*'cmdheight'* *'ch'*
'cmdheight' 'ch' number (default 1)
global or local to tab page
@ -4586,9 +4619,9 @@ 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-VisualNOS| V Visual mode when Vim is "Not Owning the
Selection" Only X11 Gui's |gui-x11|,
|xterm-clipboard| and |wayland-selections|
|hl-WarningMsg| w warning messages
|hl-WildMenu| W wildcard matches displayed for 'wildmenu'
|hl-Folded| f line used for closed folds
@ -10043,6 +10076,40 @@ A jump table for the options with a short description can be found at |Q_op|.
'winwidth' applies to the current window. Use 'winminwidth' to set
the minimal width for other windows.
*'wlseat'* *'wse'*
'wlseat' 'wse' string (default "")
global
{only when the |+wayland| feature is included}
Specifies the Wayland seat to use for Wayland functionality,
specifically the clipboard. If the seat does not exist, then the
option will still be set to the new value, with the Wayland clipboard
being unavailable as a result. If an empty value is passed then Vim
will attempt to use the value of $XDG_SEAT if it exists, if not then
it resorts to using the first seat found available. Updating this
option will also update |v:clipmethod|.
*'wlsteal'* *'wst'* *'nowlsteal'* *'nowst'*
'wlsteal' 'wst' boolean (default off)
global
{only when the |+wayland_clipboard| feature is included}
When enabled, then allow Vim to steal focus by creating a temporary
surface, in order to access the clipboard. For more information see
|wayland-focus-steal|.
*'wltimeoutlen'* *'wtm'*
'wltimeoutlen' 'wtm' number (default 500)
global
{only when the |+wayland| feature is included}
The timeout in milliseconds before Vim gives up on waiting for the
Wayland compositor. While Vim waits on the compositor, it is
unresponsive to input and does not update the screen. Therefore
setting this to a lower value may make Vim feel more responsive in
some cases. On the other hand, it may also mean you receive errors
when the compositor takes more time to respond than usual.
Additionally, this option is also used as the maximum timeout when
waiting for a surface to gain focus, see |wayland-focus-steal|.
*'wrap'* *'nowrap'*
'wrap' boolean (default on)
local to window

View File

@ -1,4 +1,4 @@
*quickref.txt* For Vim version 9.1. Last change: 2025 Jun 12
*quickref.txt* For Vim version 9.1. Last change: 2025 Jun 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -646,6 +646,7 @@ Short explanation of each option: *option-list*
'cinscopedecls' 'cinsd' words that are recognized by 'cino-g'
'cinwords' 'cinw' words where 'si' and 'cin' add an indent
'clipboard' 'cb' use the clipboard as the unnamed register
'clipmethod' 'cpm' specify order of what clipboard methods to use
'cmdheight' 'ch' number of lines to use for the command-line
'cmdwinheight' 'cwh' height of the command-line window
'colorcolumn' 'cc' columns to highlight
@ -1018,6 +1019,9 @@ Short explanation of each option: *option-list*
'winminwidth' 'wmw' minimal number of columns for any window
'winptydll' name of the winpty dynamic library
'winwidth' 'wiw' minimal number of columns for current window
'wlseat' 'wse' the wayland seat to use
'wlsteal' 'wst' allow focus stealing functionality for wayland
'wltimeoutlen' 'wtm' timeout to use when polling in wayland
'wrap' long lines wrap and continue on the next line
'wrapmargin' 'wm' chars from the right where wrapping starts
'wrapscan' 'ws' searches wrap around the end of the file

View File

@ -1,4 +1,4 @@
*starting.txt* For Vim version 9.1. Last change: 2025 Feb 27
*starting.txt* For Vim version 9.1. Last change: 2025 Jun 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -559,6 +559,12 @@ a slash. Thus "-R" means recovery and "-/R" readonly.
client-server messages), call the |serverlist()| function.
This does not enable the XSMP handler though.
*-Y*
-Y Do not try connecting to the Wayland compositor. Is only
relevant for Unix when compiled with the |+wayland| feature,
otherwise it's ignored. Note that this will make any feature
that uses Wayland unavailable, such as the clipboard.
*-s*
-s {scriptin} The script file "scriptin" is read. The characters in the
file are interpreted as if you had typed them. The same can

View File

@ -149,6 +149,7 @@ $quote eval.txt /*$quote*
'cinw' options.txt /*'cinw'*
'cinwords' options.txt /*'cinwords'*
'clipboard' options.txt /*'clipboard'*
'clipmethod' options.txt /*'clipmethod'*
'cm' options.txt /*'cm'*
'cmdheight' options.txt /*'cmdheight'*
'cmdwinheight' options.txt /*'cmdwinheight'*
@ -178,6 +179,7 @@ $quote eval.txt /*$quote*
'copyindent' options.txt /*'copyindent'*
'cot' options.txt /*'cot'*
'cp' options.txt /*'cp'*
'cpm' options.txt /*'cpm'*
'cpo' options.txt /*'cpo'*
'cpoptions' options.txt /*'cpoptions'*
'cpp' options.txt /*'cpp'*
@ -803,6 +805,7 @@ $quote eval.txt /*$quote*
'nowinfixheight' options.txt /*'nowinfixheight'*
'nowinfixwidth' options.txt /*'nowinfixwidth'*
'nowiv' options.txt /*'nowiv'*
'nowlsteal' options.txt /*'nowlsteal'*
'nowmnu' options.txt /*'nowmnu'*
'nowrap' options.txt /*'nowrap'*
'nowrapscan' options.txt /*'nowrapscan'*
@ -810,6 +813,7 @@ $quote eval.txt /*$quote*
'nowriteany' options.txt /*'nowriteany'*
'nowritebackup' options.txt /*'nowritebackup'*
'nows' options.txt /*'nows'*
'nowst' options.txt /*'nowst'*
'noxtermcodes' options.txt /*'noxtermcodes'*
'nrformats' options.txt /*'nrformats'*
'nu' options.txt /*'nu'*
@ -1334,6 +1338,9 @@ $quote eval.txt /*$quote*
'winwidth' options.txt /*'winwidth'*
'wiv' options.txt /*'wiv'*
'wiw' options.txt /*'wiw'*
'wlseat' options.txt /*'wlseat'*
'wlsteal' options.txt /*'wlsteal'*
'wltimeoutlen' options.txt /*'wltimeoutlen'*
'wm' options.txt /*'wm'*
'wmh' options.txt /*'wmh'*
'wmnu' options.txt /*'wmnu'*
@ -1347,6 +1354,9 @@ $quote eval.txt /*$quote*
'writebackup' options.txt /*'writebackup'*
'writedelay' options.txt /*'writedelay'*
'ws' options.txt /*'ws'*
'wse' options.txt /*'wse'*
'wst' options.txt /*'wst'*
'wtm' options.txt /*'wtm'*
'ww' options.txt /*'ww'*
'xtermcodes' options.txt /*'xtermcodes'*
'{ motion.txt /*'{*
@ -1512,6 +1522,8 @@ $quote eval.txt /*$quote*
+visualextra various.txt /*+visualextra*
+vreplace various.txt /*+vreplace*
+vtp various.txt /*+vtp*
+wayland various.txt /*+wayland*
+wayland_clipboard various.txt /*+wayland_clipboard*
+wildignore various.txt /*+wildignore*
+wildmenu various.txt /*+wildmenu*
+windows various.txt /*+windows*
@ -1582,6 +1594,7 @@ $quote eval.txt /*$quote*
-V starting.txt /*-V*
-W starting.txt /*-W*
-X starting.txt /*-X*
-Y starting.txt /*-Y*
-Z starting.txt /*-Z*
-b starting.txt /*-b*
-background gui_x11.txt /*-background*
@ -2404,6 +2417,8 @@ $quote eval.txt /*$quote*
:clast quickfix.txt /*:clast*
:cle motion.txt /*:cle*
:clearjumps motion.txt /*:clearjumps*
:clip various.txt /*:clip*
:clipreset various.txt /*:clipreset*
:clist quickfix.txt /*:clist*
:clo windows.txt /*:clo*
:close windows.txt /*:close*
@ -3652,6 +3667,8 @@ $quote eval.txt /*$quote*
:winp gui.txt /*:winp*
:winpos gui.txt /*:winpos*
:winsize gui.txt /*:winsize*
:wl wayland.txt /*:wl*
:wlrestore wayland.txt /*:wlrestore*
:wn editing.txt /*:wn*
:wnext editing.txt /*:wnext*
:wp editing.txt /*:wp*
@ -4646,6 +4663,7 @@ E154 helphelp.txt /*E154*
E1540 eval.txt /*E1540*
E1541 vi_diff.txt /*E1541*
E1547 various.txt /*E1547*
E1548 wayland.txt /*E1548*
E155 sign.txt /*E155*
E156 sign.txt /*E156*
E157 sign.txt /*E157*
@ -11094,6 +11112,7 @@ v:beval_winnr eval.txt /*v:beval_winnr*
v:char eval.txt /*v:char*
v:charconvert_from eval.txt /*v:charconvert_from*
v:charconvert_to eval.txt /*v:charconvert_to*
v:clipmethod eval.txt /*v:clipmethod*
v:cmdarg eval.txt /*v:cmdarg*
v:cmdbang eval.txt /*v:cmdbang*
v:collate eval.txt /*v:collate*
@ -11197,6 +11216,7 @@ v:version eval.txt /*v:version*
v:versionlong eval.txt /*v:versionlong*
v:vim_did_enter eval.txt /*v:vim_did_enter*
v:warningmsg eval.txt /*v:warningmsg*
v:wayland_display eval.txt /*v:wayland_display*
v:windowid eval.txt /*v:windowid*
v_! change.txt /*v_!*
v_$ visual.txt /*v_$*
@ -11555,6 +11575,17 @@ w:quickfix_title quickfix.txt /*w:quickfix_title*
w:var eval.txt /*w:var*
waittime channel.txt /*waittime*
warningmsg-variable eval.txt /*warningmsg-variable*
wayland wayland.txt /*wayland*
wayland-and-x11 wayland.txt /*wayland-and-x11*
wayland-focus-steal wayland.txt /*wayland-focus-steal*
wayland-gnome wayland.txt /*wayland-gnome*
wayland-gui wayland.txt /*wayland-gui*
wayland-persist wayland.txt /*wayland-persist*
wayland-primary-selection wayland.txt /*wayland-primary-selection*
wayland-seat wayland.txt /*wayland-seat*
wayland-selections wayland.txt /*wayland-selections*
wayland-useful wayland.txt /*wayland-useful*
wayland.txt wayland.txt /*wayland.txt*
wdl-syntax syntax.txt /*wdl-syntax*
wdl.vim syntax.txt /*wdl.vim*
white-space pattern.txt /*white-space*

View File

@ -1,4 +1,4 @@
*various.txt* For Vim version 9.1. Last change: 2025 Jun 10
*various.txt* For Vim version 9.1. Last change: 2025 Jun 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -524,6 +524,8 @@ T *+visual* Visual mode |Visual-mode| Always enabled since 7.4.200.
T *+visualextra* extra Visual mode commands |blockwise-operators|
T *+vreplace* |gR| and |gr|
*+vtp* on MS-Windows console: support for 'termguicolors'
N *+wayland* Unix only: support for the Wayland protocol.
N *+wayland_clipboard* Unix only: support for Wayland selections/clipboard.
T *+wildignore* |'wildignore'| Always enabled since 9.0.0278
T *+wildmenu* |'wildmenu'| Always enabled since 9.0.0279
T *+windows* more than one window; Always enabled since 8.0.1118.
@ -791,7 +793,15 @@ K Run a program to lookup the keyword under the
was used for the previous execution of this command.
If the value was never specified, then it uses the
value of $DISPLAY environment variable as it was when
Vim was started.
Vim was started. This will also update |v:clipmethod|.
{only available when compiled with the |+xterm_clipboard|
feature}
*:clipreset* *:clip*
:clip[reset] Attempts to choose a new method for accessing the
clipboard, using the 'clipmethod' option. This is
useful when the current method has become unavailable,
and you want to try using another method.
{only available when compiled with the |+clipboard|
feature}

View File

@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2025 Jun 23
*version9.txt* For Vim version 9.1. Last change: 2025 Jun 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -41571,7 +41571,7 @@ Other new features ~
The new packages |package-comment|, |package-nohlsearch| and |package-hlyank|
are included.
Support for Wayland UI.
Support for Wayland UI and support for the Wayland clipboard
Support for the XDG Desktop Specification |xdg-base-dir|

View File

@ -1,4 +1,4 @@
.TH VIM 1 "2024 Aug 12"
.TH VIM 1 "2025 Jun 27"
.SH NAME
vim \- Vi IMproved, a programmer's text editor
.SH SYNOPSIS
@ -404,6 +404,9 @@ Will prompt for a crypt key.
Don't connect to the X server. Shortens startup time in a terminal, but the
window title and clipboard will not be used.
.TP
\-Y
Don't connect to the wayland compositor
.TP
\-y
Start
.B Vim

View File

@ -36,11 +36,11 @@ DESCRIPTION
vim [options] [filelist]
If the filelist is missing, the editor will start with an empty buffer.
Otherwise exactly one out of the following four may be used to choose
Otherwise exactly one out of the following four may be used to choose
one or more files to be edited.
file .. A list of filenames. The first one will be the current
file and read into the buffer. The cursor will be posi
file .. A list of filenames. The first one will be the current
file and read into the buffer. The cursor will be posi
tioned on the first line of the buffer. You can get to the
other files with the ":next" command. To edit a file that
starts with a dash, precede the filelist with "--".
@ -49,18 +49,18 @@ DESCRIPTION
from stderr, which should be a tty.
-t {tag} The file to edit and the initial cursor position depends on
a "tag", a sort of goto label. {tag} is looked up in the
a "tag", a sort of goto label. {tag} is looked up in the
tags file, the associated file becomes the current file and
the associated command is executed. Mostly this is used
for C programs, in which case {tag} could be a function
name. The effect is that the file containing that function
becomes the current file and the cursor is positioned on
becomes the current file and the cursor is positioned on
the start of the function. See ":help tag-commands".
-q [errorfile]
Start in quickFix mode. The file [errorfile] is read and
the first error is displayed. If [errorfile] is omitted,
the filename is obtained from the 'errorfile' option (de
Start in quickFix mode. The file [errorfile] is read and
the first error is displayed. If [errorfile] is omitted,
the filename is obtained from the 'errorfile' option (de
faults to "AztecC.Err" for the Amiga, "errors.err" on other
systems). Further errors can be jumped to with the ":cn"
command. See ":help quickfix".
@ -70,10 +70,10 @@ DESCRIPTION
vim The "normal" way, everything is default.
ex Start in Ex mode. Go to Normal mode with the ":vi" command.
ex Start in Ex mode. Go to Normal mode with the ":vi" command.
Can also be done with the "-e" argument.
view Start in read-only mode. You will be protected from writing
view Start in read-only mode. You will be protected from writing
the files. Can also be done with the "-R" argument.
gvim gview
@ -124,72 +124,72 @@ OPTIONS
ists.
-d Start in diff mode. There should between two to eight file
name arguments. Vim will open all the files and show dif
name arguments. Vim will open all the files and show dif
ferences between them. Works like vimdiff(1).
-d {device}, -dev {device}
Open {device} for use as a terminal. Only on the Amiga.
Open {device} for use as a terminal. Only on the Amiga.
Example: "-d con:20/30/600/150".
-D Debugging. Go to debugging mode when executing the first
-D Debugging. Go to debugging mode when executing the first
command from a script.
-e Start Vim in Ex mode, just like the executable was called
-e Start Vim in Ex mode, just like the executable was called
"ex".
-E Start Vim in improved Ex mode, just like the executable was
called "exim".
-f Foreground. For the GUI version, Vim will not fork and de
tach from the shell it was started in. On the Amiga, Vim
is not restarted to open a new window. This option should
be used when Vim is executed by a program that will wait
for the edit session to finish (e.g. mail). On the Amiga
tach from the shell it was started in. On the Amiga, Vim
is not restarted to open a new window. This option should
be used when Vim is executed by a program that will wait
for the edit session to finish (e.g. mail). On the Amiga
the ":sh" and ":!" commands will not work.
-F If Vim has been compiled with FKMAP support for editing
right-to-left oriented files and Farsi keyboard mapping,
this option starts Vim in Farsi mode, i.e. 'fkmap' and
'rightleft' are set. Otherwise an error message is given
-F If Vim has been compiled with FKMAP support for editing
right-to-left oriented files and Farsi keyboard mapping,
this option starts Vim in Farsi mode, i.e. 'fkmap' and
'rightleft' are set. Otherwise an error message is given
and Vim aborts.
Note: Farsi support has been removed in patch 8.1.0932.
-g If Vim has been compiled with GUI support, this option en
-g If Vim has been compiled with GUI support, this option en
ables the GUI. If no GUI support was compiled in, an error
message is given and Vim aborts.
-H If Vim has been compiled with RIGHTLEFT support for editing
right-to-left oriented files and Hebrew keyboard mapping,
this option starts Vim in Hebrew mode, i.e. 'hkmap' and
'rightleft' are set. Otherwise an error message is given
right-to-left oriented files and Hebrew keyboard mapping,
this option starts Vim in Hebrew mode, i.e. 'hkmap' and
'rightleft' are set. Otherwise an error message is given
and Vim aborts.
-i {viminfo}
Specifies the filename to use when reading or writing the
viminfo file, instead of the default "~/.viminfo". This
can also be used to skip the use of the .viminfo file, by
Specifies the filename to use when reading or writing the
viminfo file, instead of the default "~/.viminfo". This
can also be used to skip the use of the .viminfo file, by
giving the name "NONE".
-l Lisp mode. Sets the 'lisp' and 'showmatch' options on.
-L Same as -r.
-m Modifying files is disabled. Resets the 'write' option.
You can still modify the buffer, but writing a file is not
-m Modifying files is disabled. Resets the 'write' option.
You can still modify the buffer, but writing a file is not
possible.
-M Modifications not allowed. The 'modifiable' and 'write'
options will be unset, so that changes are not allowed and
files can not be written. Note that these options can be
-M Modifications not allowed. The 'modifiable' and 'write'
options will be unset, so that changes are not allowed and
files can not be written. Note that these options can be
set to enable making modifications.
-n No swap file will be used. Recovery after a crash will be
impossible. Handy if you want to edit a file on a very
slow medium (e.g. floppy). Can also be done with ":set
-n No swap file will be used. Recovery after a crash will be
impossible. Handy if you want to edit a file on a very
slow medium (e.g. floppy). Can also be done with ":set
uc=0". Can be undone with ":set uc=200".
-N No-compatible mode. Resets the 'compatible' option. This
will make Vim behave a bit better, but less Vi compatible,
-N No-compatible mode. Resets the 'compatible' option. This
will make Vim behave a bit better, but less Vi compatible,
even though a .vimrc file does not exist.
-nb Become an editor server for NetBeans. See the docs for de
@ -198,7 +198,7 @@ OPTIONS
-o[N] Open N windows stacked. When N is omitted, open one window
for each file.
-O[N] Open N windows side by side. When N is omitted, open one
-O[N] Open N windows side by side. When N is omitted, open one
window for each file.
-p[N] Open N tab pages. When N is omitted, open one tab page for
@ -209,15 +209,15 @@ OPTIONS
tion. When possible, Vim will run in an MDI window inside
the application. {parent-title} must appear in the window
title of the parent application. Make sure that it is spe
cific enough. Note that the implementation is still primi
tive. It won't work with all applications and the menu
cific enough. Note that the implementation is still primi
tive. It won't work with all applications and the menu
doesn't work.
-r List swap files, with information about using them for re
-r List swap files, with information about using them for re
covery.
-r {file} Recovery mode. The swap file is used to recover a crashed
editing session. The swap file is a file with the same
-r {file} Recovery mode. The swap file is used to recover a crashed
editing session. The swap file is a file with the same
filename as the text file with ".swp" appended. See ":help
recovery".
@ -272,15 +272,15 @@ OPTIONS
-V[N]{filename}
Like -V and set 'verbosefile' to {filename}. The result is
that messages are not displayed but written to the file
that messages are not displayed but written to the file
{filename}. {filename} must not start with a digit.
-w{number} Set the 'window' option to {number}.
-w {scriptout}
All the characters that you type are recorded in the file
{scriptout}, until you exit Vim. This is useful if you
want to create a script file to be used with "vim -s" or
All the characters that you type are recorded in the file
{scriptout}, until you exit Vim. This is useful if you
want to create a script file to be used with "vim -s" or
":source!". If the {scriptout} file exists, characters are
appended.
@ -294,33 +294,35 @@ OPTIONS
terminal, but the window title and clipboard will not be
used.
-Y Don't connect to the wayland compositor
-y Start Vim in easy mode, just like the executable was called
"evim" or "eview". Makes Vim behave like a click-and-type
"evim" or "eview". Makes Vim behave like a click-and-type
editor.
-Z Restricted mode. Works like the executable starts with
-Z Restricted mode. Works like the executable starts with
"r".
-- Denotes the end of the options. Arguments after this will
be handled as a file name. This can be used to edit a
-- Denotes the end of the options. Arguments after this will
be handled as a file name. This can be used to edit a
filename that starts with a '-'.
--clean Do not use any personal configuration (vimrc, plugins,
etc.). Useful to see if a problem reproduces with a clean
--clean Do not use any personal configuration (vimrc, plugins,
etc.). Useful to see if a problem reproduces with a clean
Vim setup.
--cmd {command}
Like using "-c", but the command is executed just before
processing any vimrc file. You can use up to 10 of these
Like using "-c", but the command is executed just before
processing any vimrc file. You can use up to 10 of these
commands, independently from "-c" commands.
--echo-wid GTK GUI only: Echo the Window ID on stdout.
--gui-dialog-file {name}
When using the GUI, instead of showing a dialog, write the
title and message of the dialog to file {name}. The file
is created or appended to. Only useful for testing, to
avoid that the test gets stuck on a dialog that can't be
When using the GUI, instead of showing a dialog, write the
title and message of the dialog to file {name}. The file
is created or appended to. Only useful for testing, to
avoid that the test gets stuck on a dialog that can't be
seen. Without the GUI the argument is ignored.
--help, -h, -?
@ -374,7 +376,7 @@ OPTIONS
List the names of all Vim servers that can be found.
--servername {name}
Use {name} as the server name. Used for the current Vim,
Use {name} as the server name. Used for the current Vim,
unless used with a --remote argument, then it's the name of
the server to connect to.
@ -404,12 +406,12 @@ ON-LINE HELP
FILES
/usr/local/share/vim/vim??/doc/*.txt
The Vim documentation files. Use ":help doc-file-list"
The Vim documentation files. Use ":help doc-file-list"
to get the complete list.
vim?? is short version number, like vim91 for Vim 9.1
/usr/local/share/vim/vim??/doc/tags
The tags file used for finding information in the docu
The tags file used for finding information in the docu
mentation files.
/usr/local/share/vim/vim??/syntax/syntax.vim
@ -422,18 +424,18 @@ FILES
System wide Vim initializations.
~/.vimrc, ~/.vim/vimrc, $XDG_CONFIG_HOME/vim/vimrc
Your personal Vim initializations (first one found is
Your personal Vim initializations (first one found is
used).
/usr/local/share/vim/gvimrc
System wide gvim initializations.
~/.gvimrc, ~/.vim/gvimrc, $XDG_CONFIG_HOME/vim/gvimrc
Your personal gVim initializations (first one found is
Your personal gVim initializations (first one found is
used).
/usr/local/share/vim/vim??/optwin.vim
Script used for the ":options" command, a nice way to
Script used for the ":options" command, a nice way to
view and set options.
/usr/local/share/vim/vim??/menu.vim
@ -443,11 +445,11 @@ FILES
Script to generate a bug report. See ":help bugs".
/usr/local/share/vim/vim??/filetype.vim
Script to detect the type of a file by its name. See
Script to detect the type of a file by its name. See
":help 'filetype'".
/usr/local/share/vim/vim??/scripts.vim
Script to detect the type of a file by its contents.
Script to detect the type of a file by its contents.
See ":help 'filetype'".
/usr/local/share/vim/vim??/print/*.ps
@ -475,4 +477,4 @@ BUGS
vi_diff.txt when in Vim). Also have a look at the 'compatible' and
'cpoptions' options.
2024 Aug 12 VIM(1)
2025 Jun 27 VIM(1)

117
runtime/doc/wayland.txt Normal file
View File

@ -0,0 +1,117 @@
*wayland.txt* For Vim version 9.1. Last change: 2025 Jun 27
VIM REFERENCE MANUAL by Bram Moolenaar
Wayland Protocol Support *wayland*
1. Useful Wayland information |wayland-useful|
2. Wayland selections |wayland-selections|
==============================================================================
1. Useful Wayland information *wayland-useful*
*wayland-seat*
Functionality such as the clipboard for Wayland requires a seat to use. A
Wayland seat can consist of a keyboard, pointer, and touch device(s). The
seat to use can be set with the 'wlseat' option. Only useful if you use
multiple Wayland seats in the same Wayland session.
*wayland-gui*
See |gui-wayland|. Please note that when using the GUI, Vim uses the toolkit
such as GTK for accessing the clipboard, and does not access the clipboard
though Wayland. You can check this though the |v:clipmethod| variable, which
should equal to "none" when running the GUI.
Wayland commands:
*:wlrestore* *:wl*
:wl[estore] [display] Reinitializes the connection to the wayland compositor.
Useful when running Vim in a screen/tmux session that
continues running after the Wayland compositor
restarts.
[display] should be in the format of the
$WAYLAND_DISPLAY environment variable (e.g.
"wayland-0"). If [display] is omitted, then it
reinitializes the connection using the same value as
was used for the previous execution of this command.
If the value was never specified, then it uses the
value of $WAYLAND_DISPLAY environment variable. This
will also update |v:clipmethod|.
{only available when compiled with the |+wayland| feature}
Wayland errors:
*E1548*
Vim failed communicating with the wayland compositor. This is likely due to
the Wayland compositor process being killed. Try the `:wlrestore` command to
try connecting again.
==============================================================================
2. Wayland Selections *wayland-selections*
Vim supports the wlr-data-control-unstable-v1 and ext-data-control-v1
protocols, for accessing the current Wayland selection. These are the best
case scenario protocols, see |wayland-focus-steal|. Selection in this case
essentially means the "clipboard." You can check if your Wayland compositor
supports either of these protocols by running the wayland-info command, which
should be bunded with libwayland on your system: >
wayland-info | grep -E '(ext_data_control|zwlr_data_control)'
<If grep finds a match, then you have either or both protocols on your system.
If you don't get any match, then please see |wayland-focus-steal| for more
information.
If you come from X11, then the regular wayland selection is equivalent to the
CLIPBOARD selection in X11, and the primary wayland selection equates to the
X11 primary selection. Accessing these selections is the same as X11 in Vim,
in which the + register is the regular selection, and the * register is the
primary selection, note that your compositor may not support primary
selections, see |wayland-primary-selection| for more details.
*wayland-persist*
If you use X11 cut buffers, no such things exist on Wayland. Instead to
emulate such functionality, a separate clipboard manager must be used in order
to persist selection data when a Wayland client exists.
*wayland-and-x11*
If your version of Vim comes compiled with both X11 and Wayland support, then
Vim determines which one to use when accessing the clipboard using the
'clipmethod' option.
*wayland-primary-selection*
If you find X11 style primary selections useful, Wayland also implements this
behaviour in its own protocols:
- The primary selection protocol is the most widely supported, but requires
focus in order to be used, see |wayland-focus-steal|.
- Data control protocol available on your system, such as the ext or wlr
protocols, then primary selection is also supported. This is unless you are
using version 1 (not the same as the 'v1' in the protocol name), of the
wlr-data-control protocol. Then the primary selection protocol will be used
as a fallback.
*wayland-focus-steal* *wayland-gnome*
If you are using the GNOME desktop environment on Wayland, as of this writing,
there is no method of accessing/modifying the clipboard for external clients
such as Vim without being focused. Focused in this case means the client has
received some sort of input event, such as a window being focused. This is
what the wlr-data-control-unstable-v1 and ext-data-control-v1 protocols solve.
If your Wayland compositor does not support the above protocols, then the
above explanation applies.
To solve this problem, Vim implements a way of gaining focus in order to
access the clipboard, by creating a temporary transparent top-level surface.
This is by default disabled and can be enabled via the 'wlsteal' option.
Moreover, a seat that has a keyboard is also required, see 'wlseat', and the
xdg-shell protocol must be available.
Note that this method can have several side effects from the result of focus
stealing. For example, if you have a taskbar that shows currently opened apps
in your desktop environment, then when Vim attempts to steal focus, it may
"flicker," as if a window was opened then immediately closed after.
Additionally, if you are in fullscreen mode, this focus stealing won't work,
because the created surface won't ever gain focus. If this happens, Vim will
seem to freeze temporarily, see 'wltimeoutlen' for more information.
vim:tw=78:sw=4:ts=8:noet:ft=help:norl:js

View File

@ -806,6 +806,20 @@ call <SID>OptionG("slm", &slm)
if has("clipboard")
call <SID>AddOption("clipboard", gettext("\"unnamed\" to use the * register like unnamed register\n\"autoselect\" to always put selected text on the clipboard"))
call <SID>OptionG("cb", &cb)
call <SID>AddOption("clipmethod", gettext("Ordered list of possible methods for accessing the clipboard"))
call <SID>OptionG("cpm", &cpm)
endif
if has("wayland_clipboard")
call <SID>AddOption("wltimeoutlen", gettext("Timeout to use when polling for data to read or write in wayland"))
call <SID>OptionG("wtm", &wtm)
endif
if has('wayland')
call <SID>AddOption("wlseat", gettext("Wayland seat to use"))
call <SID>OptionG("wse", &wse)
endif
if has("wayland_clipboard")
call <SID>AddOption("wlsteal", gettext("Enable wayland focus stealing functionality in order to access the clipboard"))
call <SID>BinOptionG("wst", &wst)
endif
call <SID>AddOption("keymodel", gettext("\"startsel\" and/or \"stopsel\"; what special keys can do"))
call <SID>OptionG("km", &km)

View File

@ -2,7 +2,7 @@
" Language: Vim script
" Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com>
" Doug Kearns <dougkearns@gmail.com>
" Last Change: 2025 Jun 25
" Last Change: 2025 Jun 27
" Former Maintainer: Charles E. Campbell
" DO NOT CHANGE DIRECTLY.
@ -33,12 +33,12 @@ syn cluster vimCommentGroup contains=vimTodo,@Spell
" regular vim commands {{{2
" GEN_SYN_VIM: vimCommand normal, START_STR='syn keyword vimCommand contained', END_STR='nextgroup=vimBang'
syn keyword vimCommand contained abo[veleft] al[l] ar[gs] arga[dd] argd[elete] argdo argded[upe] arge[dit] argg[lobal] argl[ocal] argu[ment] as[cii] b[uffer] bN[ext] ba[ll] bad[d] balt bd[elete] bel[owright] bf[irst] bl[ast] bm[odified] bn[ext] bo[tright] bp[revious] br[ewind] brea[k] breaka[dd] breakd[el] breakl[ist] bro[wse] buffers bufd[o] bun[load] bw[ipeout] c[hange] cN[ext] cNf[ile] cabo[ve] cad[dbuffer] cadde[xpr] caddf[ile] caf[ter] cb[uffer] cbe[fore] cbel[ow] cbo[ttom] cc ccl[ose] cd cdo ce[nter] cex[pr] cf[ile] cfd[o] cfir[st] cg[etfile] cgetb[uffer] cgete[xpr] chd[ir] changes che[ckpath] checkt[ime] chi[story] cl[ist] cla[st] clo[se] cle[arjumps] cn[ext] cnew[er] cnf[ile] co[py] col[der] colo[rscheme] com[mand] comc[lear] comp[iler] con[tinue] conf[irm] nextgroup=vimBang
syn keyword vimCommand contained cons[t] cope[n] cp[revious] cpf[ile] cq[uit] cr[ewind] cs[cope] cst[ag] cw[indow] d[elete] delm[arks] deb[ug] defc[ompile] defe[r] di[splay] dif[fupdate] diffg[et] diffo[ff] diffp[atch] diffpu[t] diffs[plit] difft[his] dig[raphs] disa[ssemble] dj[ump] dli[st] dr[op] ds[earch] dsp[lit] e[dit] ea[rlier] em[enu] endfo[r] endt[ry] endw[hile] ene[w] ev[al] ex exi[t] exu[sage] f[ile] files filet[ype] fin[d] fina[lly] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] foldd[oopen] folddoc[losed] foldo[pen] g[lobal] go[to] gu[i] gv[im] h[elp] helpc[lose] helpf[ind] helpt[ags] ha[rdcopy] hi[ghlight] hid[e] his[tory] hor[izontal] ij[ump] il[ist] int[ro] ip[ut] is[earch] isp[lit] j[oin] ju[mps] kee[pmarks] keepj[umps] keepp[atterns] keepa[lt] l[ist] nextgroup=vimBang
syn keyword vimCommand contained lN[ext] lNf[ile] la[st] lab[ove] lan[guage] lad[dexpr] laddb[uffer] laddf[ile] laf[ter] lat[er] lb[uffer] lbe[fore] lbel[ow] lbo[ttom] lc[d] lch[dir] lcl[ose] lcs[cope] ld[o] le[ft] lefta[bove] lex[pr] leg[acy] lf[ile] lfd[o] lfir[st] lg[etfile] lgetb[uffer] lgete[xpr] lgr[ep] lgrepa[dd] lhi[story] ll lla[st] lli[st] lmak[e] lne[xt] lnew[er] lnf[ile] lo[adview] loc[kmarks] lockv[ar] lol[der] lop[en] lp[revious] lpf[ile] lr[ewind] lt[ag] lw[indow] ls m[ove] marks menut[ranslate] mes[sages] mk[exrc] mks[ession] mksp[ell] mkv[imrc] mkvie[w] mod[e] n[ext] nb[key] nbc[lose] nbs[tart] noa[utocmd] noh[lsearch] nos[wapfile] nu[mber] o[pen] ol[dfiles] on[ly] opt[ions] ow[nsyntax] p[rint] pa[ckadd] packl[oadall] pb[uffer] pc[lose] ped[it] nextgroup=vimBang
syn keyword vimCommand contained po[p] pp[op] pre[serve] prev[ious] pro[mptfind] promptr[epl] ps[earch] pt[ag] ptN[ext] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pw[d] q[uit] quita[ll] qa[ll] r[ead] rec[over] red[o] redr[aw] redraws[tatus] redrawt[abline] redrawtabp[anel] reg[isters] res[ize] ret[ab] rew[ind] ri[ght] rightb[elow] ru[ntime] rub[y] rubyd[o] rubyf[ile] rund[o] rv[iminfo] sN[ext] sa[rgument] sal[l] san[dbox] sav[eas] sb[uffer] sbN[ext] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbp[revious] sbr[ewind] scr[iptnames] scripte[ncoding] scriptv[ersion] scs[cope] setf[iletype] sf[ind] sfir[st] sh[ell] sim[alt] sig[n] sil[ent] sla[st] sn[ext] so[urce] sp[lit] spe[llgood] spelld[ump] spelli[nfo] spellr[epall] spellra[re] nextgroup=vimBang
syn keyword vimCommand contained spellu[ndo] spellw[rong] spr[evious] sre[wind] st[op] sta[g] star[tinsert] startg[replace] startr[eplace] stopi[nsert] stj[ump] sts[elect] sun[hide] sus[pend] sv[iew] sw[apname] synti[me] sync[bind] smi[le] t tN[ext] ta[g] tags tab tabc[lose] tabd[o] tabe[dit] tabf[ind] tabfir[st] tabm[ove] tabl[ast] tabn[ext] tabnew tabo[nly] tabp[revious] tabN[ext] tabr[ewind] tabs tc[d] tch[dir] te[aroff] ter[minal] tf[irst] tj[ump] tl[ast] tn[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] u[ndo] undoj[oin] undol[ist] unh[ide] unlo[ckvar] uns[ilent] up[date] v[global] ve[rsion] verb[ose] vert[ical] vi[sual] vie[w] vim9[cmd] viu[sage] vne[w] vs[plit] w[rite] wN[ext] wa[ll] wi[nsize] winc[md] wind[o] winp[os] wn[ext] wp[revious] wq wqa[ll] nextgroup=vimBang
syn keyword vimCommand contained wu[ndo] wv[iminfo] x[it] xa[ll] xr[estore] y[ank] z dl dell delel deletl deletel dp dep delp delep deletp deletep a i nextgroup=vimBang
syn keyword vimCommand contained abo[veleft] al[l] ar[gs] arga[dd] argd[elete] argdo argded[upe] arge[dit] argg[lobal] argl[ocal] argu[ment] as[cii] b[uffer] bN[ext] ba[ll] bad[d] balt bd[elete] bel[owright] bf[irst] bl[ast] bm[odified] bn[ext] bo[tright] bp[revious] br[ewind] brea[k] breaka[dd] breakd[el] breakl[ist] bro[wse] buffers bufd[o] bun[load] bw[ipeout] c[hange] cN[ext] cNf[ile] cabo[ve] cad[dbuffer] cadde[xpr] caddf[ile] caf[ter] cb[uffer] cbe[fore] cbel[ow] cbo[ttom] cc ccl[ose] cd cdo ce[nter] cex[pr] cf[ile] cfd[o] cfir[st] cg[etfile] cgetb[uffer] cgete[xpr] chd[ir] changes che[ckpath] checkt[ime] chi[story] cl[ipreset] clis[t] cla[st] clo[se] cle[arjumps] cn[ext] cnew[er] cnf[ile] co[py] col[der] colo[rscheme] com[mand] comc[lear] comp[iler] con[tinue] nextgroup=vimBang
syn keyword vimCommand contained conf[irm] cons[t] cope[n] cp[revious] cpf[ile] cq[uit] cr[ewind] cs[cope] cst[ag] cw[indow] d[elete] delm[arks] deb[ug] defc[ompile] defe[r] di[splay] dif[fupdate] diffg[et] diffo[ff] diffp[atch] diffpu[t] diffs[plit] difft[his] dig[raphs] disa[ssemble] dj[ump] dli[st] dr[op] ds[earch] dsp[lit] e[dit] ea[rlier] em[enu] endfo[r] endt[ry] endw[hile] ene[w] ev[al] ex exi[t] exu[sage] f[ile] files filet[ype] fin[d] fina[lly] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] foldd[oopen] folddoc[losed] foldo[pen] g[lobal] go[to] gu[i] gv[im] h[elp] helpc[lose] helpf[ind] helpt[ags] ha[rdcopy] hi[ghlight] hid[e] his[tory] hor[izontal] ij[ump] il[ist] int[ro] ip[ut] is[earch] isp[lit] j[oin] ju[mps] kee[pmarks] keepj[umps] keepp[atterns] keepa[lt] nextgroup=vimBang
syn keyword vimCommand contained l[ist] lN[ext] lNf[ile] la[st] lab[ove] lan[guage] lad[dexpr] laddb[uffer] laddf[ile] laf[ter] lat[er] lb[uffer] lbe[fore] lbel[ow] lbo[ttom] lc[d] lch[dir] lcl[ose] lcs[cope] ld[o] le[ft] lefta[bove] lex[pr] leg[acy] lf[ile] lfd[o] lfir[st] lg[etfile] lgetb[uffer] lgete[xpr] lgr[ep] lgrepa[dd] lhi[story] ll lla[st] lli[st] lmak[e] lne[xt] lnew[er] lnf[ile] lo[adview] loc[kmarks] lockv[ar] lol[der] lop[en] lp[revious] lpf[ile] lr[ewind] lt[ag] lw[indow] ls m[ove] marks menut[ranslate] mes[sages] mk[exrc] mks[ession] mksp[ell] mkv[imrc] mkvie[w] mod[e] n[ext] nb[key] nbc[lose] nbs[tart] noa[utocmd] noh[lsearch] nos[wapfile] nu[mber] o[pen] ol[dfiles] on[ly] opt[ions] ow[nsyntax] p[rint] pa[ckadd] packl[oadall] pb[uffer] pc[lose] nextgroup=vimBang
syn keyword vimCommand contained ped[it] po[p] pp[op] pre[serve] prev[ious] pro[mptfind] promptr[epl] ps[earch] pt[ag] ptN[ext] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pw[d] q[uit] quita[ll] qa[ll] r[ead] rec[over] red[o] redr[aw] redraws[tatus] redrawt[abline] redrawtabp[anel] reg[isters] res[ize] ret[ab] rew[ind] ri[ght] rightb[elow] ru[ntime] rub[y] rubyd[o] rubyf[ile] rund[o] rv[iminfo] sN[ext] sa[rgument] sal[l] san[dbox] sav[eas] sb[uffer] sbN[ext] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbp[revious] sbr[ewind] scr[iptnames] scripte[ncoding] scriptv[ersion] scs[cope] setf[iletype] sf[ind] sfir[st] sh[ell] sim[alt] sig[n] sil[ent] sla[st] sn[ext] so[urce] sp[lit] spe[llgood] spelld[ump] spelli[nfo] spellr[epall] nextgroup=vimBang
syn keyword vimCommand contained spellra[re] spellu[ndo] spellw[rong] spr[evious] sre[wind] st[op] sta[g] star[tinsert] startg[replace] startr[eplace] stopi[nsert] stj[ump] sts[elect] sun[hide] sus[pend] sv[iew] sw[apname] synti[me] sync[bind] smi[le] t tN[ext] ta[g] tags tab tabc[lose] tabd[o] tabe[dit] tabf[ind] tabfir[st] tabm[ove] tabl[ast] tabn[ext] tabnew tabo[nly] tabp[revious] tabN[ext] tabr[ewind] tabs tc[d] tch[dir] te[aroff] ter[minal] tf[irst] tj[ump] tl[ast] tn[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] u[ndo] undoj[oin] undol[ist] unh[ide] unlo[ckvar] uns[ilent] up[date] v[global] ve[rsion] verb[ose] vert[ical] vi[sual] vie[w] vim9[cmd] viu[sage] vne[w] vs[plit] w[rite] wN[ext] wa[ll] wi[nsize] winc[md] wind[o] winp[os] wl[restore] wn[ext] nextgroup=vimBang
syn keyword vimCommand contained wp[revious] wq wqa[ll] wu[ndo] wv[iminfo] x[it] xa[ll] xr[estore] y[ank] z dl dell delel deletl deletel dp dep delp delep deletp deletep a i nextgroup=vimBang
" Lower priority for _new_ to distinguish constructors from the command.
syn match vimCommand contained "\<new\>(\@!"
@ -47,29 +47,29 @@ syn keyword vimStdPlugin contained Arguments Asm Break Cfilter Clear Continue Di
" vimOptions are caught only when contained in a vimSet {{{2
" GEN_SYN_VIM: vimOption normal, START_STR='syn keyword vimOption contained', END_STR='skipwhite nextgroup=vimSetEqual,vimSetMod'
syn keyword vimOption contained al aleph ari allowrevins ambw ambiwidth arab arabic arshape arabicshape acd autochdir ai autoindent ar autoread asd autoshelldir aw autowrite awa autowriteall bg background bs backspace bk backup bkc backupcopy bdir backupdir bex backupext bsk backupskip bdlay balloondelay beval ballooneval bevalterm balloonevalterm bexpr balloonexpr bo belloff bin binary bomb brk breakat bri breakindent briopt breakindentopt bsdir browsedir bh bufhidden bl buflisted bt buftype cmp casemap cdh cdhome cd cdpath cedit ccv charconvert chi chistory cin cindent cink cinkeys cino cinoptions cinsd cinscopedecls cinw cinwords cb clipboard ch cmdheight cwh cmdwinheight cc colorcolumn co columns com comments cms commentstring cp compatible cpt complete cfu completefunc skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained cfc completefuzzycollect cia completeitemalign cot completeopt cpp completepopup csl completeslash cocu concealcursor cole conceallevel cf confirm ci copyindent cpo cpoptions cm cryptmethod cspc cscopepathcomp csprg cscopeprg csqf cscopequickfix csre cscoperelative cst cscopetag csto cscopetagorder csverb cscopeverbose crb cursorbind cuc cursorcolumn cul cursorline culopt cursorlineopt debug def define deco delcombine dict dictionary diff dex diffexpr dip diffopt dg digraph dir directory dy display ead eadirection ed edcompatible emo emoji enc encoding eof endoffile eol endofline ea equalalways ep equalprg eb errorbells ef errorfile efm errorformat ek esckeys ei eventignore eiw eventignorewin et expandtab ex exrc fenc fileencoding skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained fencs fileencodings ff fileformat ffs fileformats fic fileignorecase ft filetype fcs fillchars ffu findfunc fixeol fixendofline fcl foldclose fdc foldcolumn fen foldenable fde foldexpr fdi foldignore fdl foldlevel fdls foldlevelstart fmr foldmarker fdm foldmethod fml foldminlines fdn foldnestmax fdo foldopen fdt foldtext fex formatexpr flp formatlistpat fo formatoptions fp formatprg fs fsync gd gdefault gfm grepformat gp grepprg gcr guicursor gfn guifont gfs guifontset gfw guifontwide ghr guiheadroom gli guiligatures go guioptions guipty gtl guitablabel gtt guitabtooltip hf helpfile hh helpheight hlg helplang hid hidden hl highlight hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring ic ignorecase imaf imactivatefunc imak imactivatekey skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained imc imcmdline imd imdisable imi iminsert ims imsearch imsf imstatusfunc imst imstyle inc include inex includeexpr is incsearch inde indentexpr indk indentkeys inf infercase im insertmode ise isexpand isf isfname isi isident isk iskeyword isp isprint js joinspaces jop jumpoptions key kmp keymap km keymodel kpc keyprotocol kp keywordprg lmap langmap lm langmenu lnr langnoremap lrm langremap ls laststatus lz lazyredraw lhi lhistory lbr linebreak lines lsp linespace lisp lop lispoptions lw lispwords list lcs listchars lpl loadplugins luadll magic mef makeef menc makeencoding mp makeprg mps matchpairs mat matchtime mco maxcombine mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot mis menuitems mopt messagesopt skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable mod modified more mouse mousef mousefocus mh mousehide mousem mousemodel mousemev mousemoveevent mouses mouseshape mouset mousetime mzq mzquantum mzschemedll mzschemegcdll nf nrformats nu number nuw numberwidth ofu omnifunc odev opendevice opfunc operatorfunc pp packpath para paragraphs paste pt pastetoggle pex patchexpr pm patchmode pa path perldll pi preserveindent pvh previewheight pvp previewpopup pvw previewwindow pdev printdevice penc printencoding pexpr printexpr pfn printfont pheader printheader pmbcs printmbcharset pmbfn printmbfont popt printoptions prompt ph pumheight pmw pummaxwidth pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber remap rop renderoptions report rs restorescreen ri revins rl rightleft rlc rightleftcmd rubydll ru ruler ruf rulerformat rtp runtimepath scr scroll scb scrollbind scf scrollfocus sj scrolljump so scrolloff sbo scrollopt sect sections secure sel selection slm selectmode ssop sessionoptions sh shell shcf shellcmdflag sp shellpipe shq shellquote srr shellredir ssl shellslash stmp shelltemp st shelltype sxe shellxescape sxq shellxquote sr shiftround sw shiftwidth shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline stpl showtabpanel ss sidescroll siso sidescrolloff skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax tpl tabpanel tplo tabpanelopt ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight wmh winminheight wmw winminwidth winptydll wiw winwidth wrap wm wrapmargin ws wrapscan write wa writeany skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained wb writebackup wd writedelay xtermcodes skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained al aleph ari allowrevins ambw ambiwidth arab arabic arshape arabicshape acd autochdir ai autoindent ar autoread asd autoshelldir aw autowrite awa autowriteall bg background bs backspace bk backup bkc backupcopy bdir backupdir bex backupext bsk backupskip bdlay balloondelay beval ballooneval bevalterm balloonevalterm bexpr balloonexpr bo belloff bin binary bomb brk breakat bri breakindent briopt breakindentopt bsdir browsedir bh bufhidden bl buflisted bt buftype cmp casemap cdh cdhome cd cdpath cedit ccv charconvert chi chistory cin cindent cink cinkeys cino cinoptions cinsd cinscopedecls cinw cinwords cb clipboard cpm clipmethod ch cmdheight cwh cmdwinheight cc colorcolumn co columns com comments cms commentstring cp compatible skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained cpt complete cfu completefunc cfc completefuzzycollect cia completeitemalign cot completeopt cpp completepopup csl completeslash cocu concealcursor cole conceallevel cf confirm ci copyindent cpo cpoptions cm cryptmethod cspc cscopepathcomp csprg cscopeprg csqf cscopequickfix csre cscoperelative cst cscopetag csto cscopetagorder csverb cscopeverbose crb cursorbind cuc cursorcolumn cul cursorline culopt cursorlineopt debug def define deco delcombine dict dictionary diff dex diffexpr dip diffopt dg digraph dir directory dy display ead eadirection ed edcompatible emo emoji enc encoding eof endoffile eol endofline ea equalalways ep equalprg eb errorbells ef errorfile efm errorformat ek esckeys ei eventignore eiw eventignorewin et expandtab skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained ex exrc fenc fileencoding fencs fileencodings ff fileformat ffs fileformats fic fileignorecase ft filetype fcs fillchars ffu findfunc fixeol fixendofline fcl foldclose fdc foldcolumn fen foldenable fde foldexpr fdi foldignore fdl foldlevel fdls foldlevelstart fmr foldmarker fdm foldmethod fml foldminlines fdn foldnestmax fdo foldopen fdt foldtext fex formatexpr flp formatlistpat fo formatoptions fp formatprg fs fsync gd gdefault gfm grepformat gp grepprg gcr guicursor gfn guifont gfs guifontset gfw guifontwide ghr guiheadroom gli guiligatures go guioptions guipty gtl guitablabel gtt guitabtooltip hf helpfile hh helpheight hlg helplang hid hidden hl highlight hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring ic ignorecase skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained imaf imactivatefunc imak imactivatekey imc imcmdline imd imdisable imi iminsert ims imsearch imsf imstatusfunc imst imstyle inc include inex includeexpr is incsearch inde indentexpr indk indentkeys inf infercase im insertmode ise isexpand isf isfname isi isident isk iskeyword isp isprint js joinspaces jop jumpoptions key kmp keymap km keymodel kpc keyprotocol kp keywordprg lmap langmap lm langmenu lnr langnoremap lrm langremap ls laststatus lz lazyredraw lhi lhistory lbr linebreak lines lsp linespace lisp lop lispoptions lw lispwords list lcs listchars lpl loadplugins luadll magic mef makeef menc makeencoding mp makeprg mps matchpairs mat matchtime mco maxcombine mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable mod modified more mouse mousef mousefocus mh mousehide mousem mousemodel mousemev mousemoveevent mouses mouseshape mouset mousetime mzq mzquantum mzschemedll mzschemegcdll nf nrformats nu number nuw numberwidth ofu omnifunc odev opendevice opfunc operatorfunc pp packpath para paragraphs paste pt pastetoggle pex patchexpr pm patchmode pa path perldll pi preserveindent pvh previewheight pvp previewpopup pvw previewwindow pdev printdevice penc printencoding pexpr printexpr pfn printfont pheader printheader pmbcs printmbcharset pmbfn printmbfont popt printoptions prompt ph pumheight pmw pummaxwidth pw pumwidth pythondll pythonhome skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber remap rop renderoptions report rs restorescreen ri revins rl rightleft rlc rightleftcmd rubydll ru ruler ruf rulerformat rtp runtimepath scr scroll scb scrollbind scf scrollfocus sj scrolljump so scrolloff sbo scrollopt sect sections secure sel selection slm selectmode ssop sessionoptions sh shell shcf shellcmdflag sp shellpipe shq shellquote srr shellredir ssl shellslash stmp shelltemp st shelltype sxe shellxescape sxq shellxquote sr shiftround sw shiftwidth shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline stpl showtabpanel skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax tpl tabpanel tplo tabpanelopt ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight wmh winminheight wmw winminwidth winptydll wiw winwidth wse wlseat wst wlsteal skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained wtm wltimeoutlen wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes skipwhite nextgroup=vimSetEqual,vimSetMod
" vimOptions: These are the turn-off setting variants {{{2
" GEN_SYN_VIM: vimOption turn-off, START_STR='syn keyword vimOption contained', END_STR=''
syn keyword vimOption contained noari noallowrevins noarab noarabic noarshape noarabicshape noacd noautochdir noai noautoindent noar noautoread noasd noautoshelldir noaw noautowrite noawa noautowriteall nobk nobackup nobeval noballooneval nobevalterm noballoonevalterm nobin nobinary nobomb nobri nobreakindent nobl nobuflisted nocdh nocdhome nocin nocindent nocp nocompatible nocf noconfirm noci nocopyindent nocsre nocscoperelative nocst nocscopetag nocsverb nocscopeverbose nocrb nocursorbind nocuc nocursorcolumn nocul nocursorline nodeco nodelcombine nodiff nodg nodigraph noed noedcompatible noemo noemoji noeof noendoffile noeol noendofline noea noequalalways noeb noerrorbells noek noesckeys noet noexpandtab noex noexrc nofic nofileignorecase nofixeol nofixendofline
syn keyword vimOption contained nofen nofoldenable nofs nofsync nogd nogdefault noguipty nohid nohidden nohk nohkmap nohkp nohkmapp nohls nohlsearch noicon noic noignorecase noimc noimcmdline noimd noimdisable nois noincsearch noinf noinfercase noim noinsertmode nojs nojoinspaces nolnr nolangnoremap nolrm nolangremap nolz nolazyredraw nolbr nolinebreak nolisp nolist nolpl noloadplugins nomagic noml nomodeline nomle nomodelineexpr noma nomodifiable nomod nomodified nomore nomousef nomousefocus nomh nomousehide nomousemev nomousemoveevent nonu nonumber noodev noopendevice nopaste nopi nopreserveindent nopvw nopreviewwindow noprompt noro noreadonly nornu norelativenumber noremap nors norestorescreen nori norevins norl norightleft noru noruler noscb noscrollbind noscf noscrollfocus
syn keyword vimOption contained nosecure nossl noshellslash nostmp noshelltemp nosr noshiftround nosn noshortname nosc noshowcmd nosft noshowfulltag nosm noshowmatch nosmd noshowmode noscs nosmartcase nosi nosmartindent nosta nosmarttab nosms nosmoothscroll nospell nosb nosplitbelow nospr nosplitright nosol nostartofline noswf noswapfile notbs notagbsearch notr notagrelative notgst notagstack notbidi notermbidi notgc notermguicolors noterse nota notextauto notx notextmode notop notildeop noto notimeout notitle nottimeout notbi nottybuiltin notf nottyfast noudf noundofile novb novisualbell nowarn nowiv noweirdinvert nowic nowildignorecase nowmnu nowildmenu nowfb nowinfixbuf nowfh nowinfixheight nowfw nowinfixwidth nowrap nows nowrapscan nowrite nowa nowriteany
syn keyword vimOption contained nowb nowritebackup noxtermcodes
syn keyword vimOption contained nosecure nossl noshellslash nostmp noshelltemp nosr noshiftround nosn noshortname nosc noshowcmd nosft noshowfulltag nosm noshowmatch nosmd noshowmode noscs nosmartcase nosi nosmartindent nosta nosmarttab nosms nosmoothscroll nospell nosb nosplitbelow nospr nosplitright nosol nostartofline noswf noswapfile notbs notagbsearch notr notagrelative notgst notagstack notbidi notermbidi notgc notermguicolors noterse nota notextauto notx notextmode notop notildeop noto notimeout notitle nottimeout notbi nottybuiltin notf nottyfast noudf noundofile novb novisualbell nowarn nowiv noweirdinvert nowic nowildignorecase nowmnu nowildmenu nowfb nowinfixbuf nowfh nowinfixheight nowfw nowinfixwidth nowst nowlsteal nowrap nows nowrapscan nowrite
syn keyword vimOption contained nowa nowriteany nowb nowritebackup noxtermcodes
" vimOptions: These are the invertible variants {{{2
" GEN_SYN_VIM: vimOption invertible, START_STR='syn keyword vimOption contained', END_STR=''
syn keyword vimOption contained invari invallowrevins invarab invarabic invarshape invarabicshape invacd invautochdir invai invautoindent invar invautoread invasd invautoshelldir invaw invautowrite invawa invautowriteall invbk invbackup invbeval invballooneval invbevalterm invballoonevalterm invbin invbinary invbomb invbri invbreakindent invbl invbuflisted invcdh invcdhome invcin invcindent invcp invcompatible invcf invconfirm invci invcopyindent invcsre invcscoperelative invcst invcscopetag invcsverb invcscopeverbose invcrb invcursorbind invcuc invcursorcolumn invcul invcursorline invdeco invdelcombine invdiff invdg invdigraph inved invedcompatible invemo invemoji inveof invendoffile inveol invendofline invea invequalalways inveb inverrorbells invek invesckeys
syn keyword vimOption contained invet invexpandtab invex invexrc invfic invfileignorecase invfixeol invfixendofline invfen invfoldenable invfs invfsync invgd invgdefault invguipty invhid invhidden invhk invhkmap invhkp invhkmapp invhls invhlsearch invicon invic invignorecase invimc invimcmdline invimd invimdisable invis invincsearch invinf invinfercase invim invinsertmode invjs invjoinspaces invlnr invlangnoremap invlrm invlangremap invlz invlazyredraw invlbr invlinebreak invlisp invlist invlpl invloadplugins invmagic invml invmodeline invmle invmodelineexpr invma invmodifiable invmod invmodified invmore invmousef invmousefocus invmh invmousehide invmousemev invmousemoveevent invnu invnumber invodev invopendevice invpaste invpi invpreserveindent invpvw invpreviewwindow
syn keyword vimOption contained invprompt invro invreadonly invrnu invrelativenumber invremap invrs invrestorescreen invri invrevins invrl invrightleft invru invruler invscb invscrollbind invscf invscrollfocus invsecure invssl invshellslash invstmp invshelltemp invsr invshiftround invsn invshortname invsc invshowcmd invsft invshowfulltag invsm invshowmatch invsmd invshowmode invscs invsmartcase invsi invsmartindent invsta invsmarttab invsms invsmoothscroll invspell invsb invsplitbelow invspr invsplitright invsol invstartofline invswf invswapfile invtbs invtagbsearch invtr invtagrelative invtgst invtagstack invtbidi invtermbidi invtgc invtermguicolors invterse invta invtextauto invtx invtextmode invtop invtildeop invto invtimeout invtitle invttimeout invtbi invttybuiltin
syn keyword vimOption contained invtf invttyfast invudf invundofile invvb invvisualbell invwarn invwiv invweirdinvert invwic invwildignorecase invwmnu invwildmenu invwfb invwinfixbuf invwfh invwinfixheight invwfw invwinfixwidth invwrap invws invwrapscan invwrite invwa invwriteany invwb invwritebackup invxtermcodes
syn keyword vimOption contained invtf invttyfast invudf invundofile invvb invvisualbell invwarn invwiv invweirdinvert invwic invwildignorecase invwmnu invwildmenu invwfb invwinfixbuf invwfh invwinfixheight invwfw invwinfixwidth invwst invwlsteal invwrap invws invwrapscan invwrite invwa invwriteany invwb invwritebackup invxtermcodes
" termcap codes (which can also be set) {{{2
" GEN_SYN_VIM: vimOption term output code, START_STR='syn keyword vimOption contained', END_STR='skipwhite nextgroup=vimSetEqual,vimSetMod'
syn keyword vimOption contained t_AB t_AF t_AU t_AL t_al t_bc t_BE t_BD t_cd t_ce t_Ce t_CF t_cl t_cm t_Co t_CS t_Cs t_cs t_CV t_da t_db t_DL t_dl t_ds t_Ds t_EC t_EI t_fs t_fd t_fe t_GP t_IE t_IS t_ke t_ks t_le t_mb t_md t_me t_mr t_ms t_nd t_op t_RF t_RB t_RC t_RI t_Ri t_RK t_RS t_RT t_RV t_Sb t_SC t_se t_Sf t_SH t_SI t_Si t_so t_SR t_sr t_ST t_Te t_te t_TE t_ti t_TI t_Ts t_ts t_u7 t_ue t_us t_Us t_ut t_vb t_ve t_vi t_VS t_vs t_WP t_WS t_XM t_xn t_xs t_ZH t_ZR t_8f t_8b t_8u t_xo skipwhite nextgroup=vimSetEqual,vimSetMod
@ -86,15 +86,15 @@ syn match vimOption contained "t_k;"
" vimOptions: These are the variable names {{{2
" GEN_SYN_VIM: vimOption normal variable, START_STR='syn keyword vimOptionVarName contained', END_STR=''
syn keyword vimOptionVarName contained al aleph ari allowrevins ambw ambiwidth arab arabic arshape arabicshape acd autochdir ai autoindent ar autoread asd autoshelldir aw autowrite awa autowriteall bg background bs backspace bk backup bkc backupcopy bdir backupdir bex backupext bsk backupskip bdlay balloondelay beval ballooneval bevalterm balloonevalterm bexpr balloonexpr bo belloff bin binary bomb brk breakat bri breakindent briopt breakindentopt bsdir browsedir bh bufhidden bl buflisted bt buftype cmp casemap cdh cdhome cd cdpath cedit ccv charconvert chi chistory cin cindent cink cinkeys cino cinoptions cinsd cinscopedecls cinw cinwords cb clipboard ch cmdheight cwh cmdwinheight cc colorcolumn co columns com comments cms commentstring cp compatible cpt complete
syn keyword vimOptionVarName contained cfu completefunc cfc completefuzzycollect cia completeitemalign cot completeopt cpp completepopup csl completeslash cocu concealcursor cole conceallevel cf confirm ci copyindent cpo cpoptions cm cryptmethod cspc cscopepathcomp csprg cscopeprg csqf cscopequickfix csre cscoperelative cst cscopetag csto cscopetagorder csverb cscopeverbose crb cursorbind cuc cursorcolumn cul cursorline culopt cursorlineopt debug def define deco delcombine dict dictionary diff dex diffexpr dip diffopt dg digraph dir directory dy display ead eadirection ed edcompatible emo emoji enc encoding eof endoffile eol endofline ea equalalways ep equalprg eb errorbells ef errorfile efm errorformat ek esckeys ei eventignore eiw eventignorewin et expandtab
syn keyword vimOptionVarName contained ex exrc fenc fileencoding fencs fileencodings ff fileformat ffs fileformats fic fileignorecase ft filetype fcs fillchars ffu findfunc fixeol fixendofline fcl foldclose fdc foldcolumn fen foldenable fde foldexpr fdi foldignore fdl foldlevel fdls foldlevelstart fmr foldmarker fdm foldmethod fml foldminlines fdn foldnestmax fdo foldopen fdt foldtext fex formatexpr flp formatlistpat fo formatoptions fp formatprg fs fsync gd gdefault gfm grepformat gp grepprg gcr guicursor gfn guifont gfs guifontset gfw guifontwide ghr guiheadroom gli guiligatures go guioptions guipty gtl guitablabel gtt guitabtooltip hf helpfile hh helpheight hlg helplang hid hidden hl highlight hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring ic ignorecase
syn keyword vimOptionVarName contained imaf imactivatefunc imak imactivatekey imc imcmdline imd imdisable imi iminsert ims imsearch imsf imstatusfunc imst imstyle inc include inex includeexpr is incsearch inde indentexpr indk indentkeys inf infercase im insertmode ise isexpand isf isfname isi isident isk iskeyword isp isprint js joinspaces jop jumpoptions key kmp keymap km keymodel kpc keyprotocol kp keywordprg lmap langmap lm langmenu lnr langnoremap lrm langremap ls laststatus lz lazyredraw lhi lhistory lbr linebreak lines lsp linespace lisp lop lispoptions lw lispwords list lcs listchars lpl loadplugins luadll magic mef makeef menc makeencoding mp makeprg mps matchpairs mat matchtime mco maxcombine mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern
syn keyword vimOptionVarName contained al aleph ari allowrevins ambw ambiwidth arab arabic arshape arabicshape acd autochdir ai autoindent ar autoread asd autoshelldir aw autowrite awa autowriteall bg background bs backspace bk backup bkc backupcopy bdir backupdir bex backupext bsk backupskip bdlay balloondelay beval ballooneval bevalterm balloonevalterm bexpr balloonexpr bo belloff bin binary bomb brk breakat bri breakindent briopt breakindentopt bsdir browsedir bh bufhidden bl buflisted bt buftype cmp casemap cdh cdhome cd cdpath cedit ccv charconvert chi chistory cin cindent cink cinkeys cino cinoptions cinsd cinscopedecls cinw cinwords cb clipboard cpm clipmethod ch cmdheight cwh cmdwinheight cc colorcolumn co columns com comments cms commentstring cp compatible
syn keyword vimOptionVarName contained cpt complete cfu completefunc cfc completefuzzycollect cia completeitemalign cot completeopt cpp completepopup csl completeslash cocu concealcursor cole conceallevel cf confirm ci copyindent cpo cpoptions cm cryptmethod cspc cscopepathcomp csprg cscopeprg csqf cscopequickfix csre cscoperelative cst cscopetag csto cscopetagorder csverb cscopeverbose crb cursorbind cuc cursorcolumn cul cursorline culopt cursorlineopt debug def define deco delcombine dict dictionary diff dex diffexpr dip diffopt dg digraph dir directory dy display ead eadirection ed edcompatible emo emoji enc encoding eof endoffile eol endofline ea equalalways ep equalprg eb errorbells ef errorfile efm errorformat ek esckeys ei eventignore eiw eventignorewin
syn keyword vimOptionVarName contained et expandtab ex exrc fenc fileencoding fencs fileencodings ff fileformat ffs fileformats fic fileignorecase ft filetype fcs fillchars ffu findfunc fixeol fixendofline fcl foldclose fdc foldcolumn fen foldenable fde foldexpr fdi foldignore fdl foldlevel fdls foldlevelstart fmr foldmarker fdm foldmethod fml foldminlines fdn foldnestmax fdo foldopen fdt foldtext fex formatexpr flp formatlistpat fo formatoptions fp formatprg fs fsync gd gdefault gfm grepformat gp grepprg gcr guicursor gfn guifont gfs guifontset gfw guifontwide ghr guiheadroom gli guiligatures go guioptions guipty gtl guitablabel gtt guitabtooltip hf helpfile hh helpheight hlg helplang hid hidden hl highlight hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring
syn keyword vimOptionVarName contained ic ignorecase imaf imactivatefunc imak imactivatekey imc imcmdline imd imdisable imi iminsert ims imsearch imsf imstatusfunc imst imstyle inc include inex includeexpr is incsearch inde indentexpr indk indentkeys inf infercase im insertmode ise isexpand isf isfname isi isident isk iskeyword isp isprint js joinspaces jop jumpoptions key kmp keymap km keymodel kpc keyprotocol kp keywordprg lmap langmap lm langmenu lnr langnoremap lrm langremap ls laststatus lz lazyredraw lhi lhistory lbr linebreak lines lsp linespace lisp lop lispoptions lw lispwords list lcs listchars lpl loadplugins luadll magic mef makeef menc makeencoding mp makeprg mps matchpairs mat matchtime mco maxcombine mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern
syn keyword vimOptionVarName contained mmt maxmemtot mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable mod modified more mouse mousef mousefocus mh mousehide mousem mousemodel mousemev mousemoveevent mouses mouseshape mouset mousetime mzq mzquantum mzschemedll mzschemegcdll nf nrformats nu number nuw numberwidth ofu omnifunc odev opendevice opfunc operatorfunc pp packpath para paragraphs paste pt pastetoggle pex patchexpr pm patchmode pa path perldll pi preserveindent pvh previewheight pvp previewpopup pvw previewwindow pdev printdevice penc printencoding pexpr printexpr pfn printfont pheader printheader pmbcs printmbcharset pmbfn printmbfont popt printoptions prompt ph pumheight pmw pummaxwidth pw pumwidth
syn keyword vimOptionVarName contained pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber remap rop renderoptions report rs restorescreen ri revins rl rightleft rlc rightleftcmd rubydll ru ruler ruf rulerformat rtp runtimepath scr scroll scb scrollbind scf scrollfocus sj scrolljump so scrolloff sbo scrollopt sect sections secure sel selection slm selectmode ssop sessionoptions sh shell shcf shellcmdflag sp shellpipe shq shellquote srr shellredir ssl shellslash stmp shelltemp st shelltype sxe shellxescape sxq shellxquote sr shiftround sw shiftwidth shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode
syn keyword vimOptionVarName contained stal showtabline stpl showtabpanel ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax tpl tabpanel tplo tabpanelopt ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode
syn keyword vimOptionVarName contained tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight wmh winminheight wmw winminwidth
syn keyword vimOptionVarName contained winptydll wiw winwidth wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes
syn keyword vimOptionVarName contained winptydll wiw winwidth wse wlseat wst wlsteal wtm wltimeoutlen wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes
" GEN_SYN_VIM: vimOption term output code variable, START_STR='syn keyword vimOptionVarName contained', END_STR=''
syn keyword vimOptionVarName contained t_AB t_AF t_AU t_AL t_al t_bc t_BE t_BD t_cd t_ce t_Ce t_CF t_cl t_cm t_Co t_CS t_Cs t_cs t_CV t_da t_db t_DL t_dl t_ds t_Ds t_EC t_EI t_fs t_fd t_fe t_GP t_IE t_IS t_ke t_ks t_le t_mb t_md t_me t_mr t_ms t_nd t_op t_RF t_RB t_RC t_RI t_Ri t_RK t_RS t_RT t_RV t_Sb t_SC t_se t_Sf t_SH t_SI t_Si t_so t_SR t_sr t_ST t_Te t_te t_TE t_ti t_TI t_Ts t_ts t_u7 t_ue t_us t_Us t_ut t_vb t_ve t_vi t_VS t_vs t_WP t_WS t_XM t_xn t_xs t_ZH t_ZR t_8f t_8b t_8u t_xo
syn keyword vimOptionVarName contained t_F1 t_F2 t_F3 t_F4 t_F5 t_F6 t_F7 t_F8 t_F9 t_k1 t_K1 t_k2 t_k3 t_K3 t_k4 t_K4 t_k5 t_K5 t_k6 t_K6 t_k7 t_K7 t_k8 t_K8 t_k9 t_K9 t_KA t_kb t_kB t_KB t_KC t_kd t_kD t_KD t_KE t_KF t_KG t_kh t_KH t_kI t_KI t_KJ t_KK t_kl t_KL t_kN t_kP t_kr t_ku
@ -147,7 +147,7 @@ syn keyword vimFuncName contained win_id2tabwin win_id2win win_move_separator wi
" Predefined variable names {{{2
" GEN_SYN_VIM: vimVarName, START_STR='syn keyword vimVimVarName contained', END_STR=''
syn keyword vimVimVarName contained count count1 prevcount errmsg warningmsg statusmsg shell_error this_session version lnum termresponse fname lang lc_time ctype charconvert_from charconvert_to fname_in fname_out fname_new fname_diff cmdarg foldstart foldend folddashes foldlevel progname servername dying exception throwpoint register cmdbang insertmode val key profiling fcs_reason fcs_choice beval_bufnr beval_winnr beval_winid beval_lnum beval_col beval_text scrollstart swapname swapchoice swapcommand char mouse_win mouse_winid mouse_lnum mouse_col operator searchforward hlsearch oldfiles windowid progpath completed_item option_new option_old option_oldlocal option_oldglobal option_command option_type errors false true none null numbermax numbermin numbersize
syn keyword vimVimVarName contained vim_did_enter testing t_number t_string t_func t_list t_dict t_float t_bool t_none t_job t_channel t_blob t_class t_object termrfgresp termrbgresp termu7resp termstyleresp termblinkresp event versionlong echospace argv collate exiting colornames sizeofint sizeoflong sizeofpointer maxcol python3_version t_typealias t_enum t_enumvalue stacktrace t_tuple
syn keyword vimVimVarName contained vim_did_enter testing t_number t_string t_func t_list t_dict t_float t_bool t_none t_job t_channel t_blob t_class t_object termrfgresp termrbgresp termu7resp termstyleresp termblinkresp event versionlong echospace argv collate exiting colornames sizeofint sizeoflong sizeofpointer maxcol python3_version t_typealias t_enum t_enumvalue stacktrace t_tuple wayland_display clipmethod
"--- syntax here and above generated by runtime/syntax/generator/gen_syntax_vim.vim ---

View File

@ -1404,6 +1404,7 @@ ALL_LIBS = \
$(GUI_LIBS2) \
$(X_PRE_LIBS) \
$(X_LIBS) \
$(WAYLAND_LIBS) \
$(X_EXTRA_LIBS) \
$(MZSCHEME_LIBS) \
$(LIBS) \
@ -1614,13 +1615,23 @@ SRC = $(BASIC_SRC) \
$(PERL_SRC) \
$(PYTHON_SRC) $(PYTHON3_SRC) \
$(TCL_SRC) \
$(RUBY_SRC)
$(RUBY_SRC) \
$(WAYLAND_SRC)
EXTRA_SRC = if_lua.c if_mzsch.c auto/if_perl.c if_perlsfio.c \
if_python.c if_python3.c if_tcl.c if_ruby.c \
gui_beval.c netbeans.c job.c channel.c \
$(GRESOURCE_SRC)
$(WAYLAND_SRC):
cd auto/wayland; $(MAKE)
# Needed for parallel jobs to work
auto/wayland/ext-data-control-v1.h: auto/wayland/ext-data-control-v1.c
auto/wayland/wlr-data-control-unstable-v1.h: auto/wayland/wlr-data-control-unstable-v1.c
auto/wayland/primary-selection-unstable-v1.h: auto/wayland/primary-selection-unstable-v1.c
auto/wayland/xdg-shell.h: auto/wayland/xdg-shell.c
# Unittest files
JSON_TEST_SRC = json_test.c
JSON_TEST_TARGET = json_test$(EXEEXT)
@ -1636,7 +1647,8 @@ UNITTEST_TARGETS = $(JSON_TEST_TARGET) $(KWORD_TEST_TARGET) $(MEMFILE_TEST_TARGE
RUN_UNITTESTS = run_json_test run_kword_test run_memfile_test run_message_test
# All sources, also the ones that are not configured
ALL_LOCAL_SRC = $(BASIC_SRC) $(ALL_GUI_SRC) $(UNITTEST_SRC) $(EXTRA_SRC)
ALL_LOCAL_SRC = $(BASIC_SRC) $(ALL_GUI_SRC) $(UNITTEST_SRC) $(EXTRA_SRC) \
$(WAYLAND_SRC)
ALL_SRC = $(ALL_LOCAL_SRC) $(TERM_SRC) $(XDIFF_SRC)
# Which files to check with lint. Select one of these three lines. ALL_SRC
@ -1777,7 +1789,8 @@ OBJ_COMMON = \
$(OS_EXTRA_OBJ) \
$(NETBEANS_OBJ) \
$(CHANNEL_OBJ) \
$(XDIFF_OBJS_USED)
$(XDIFF_OBJS_USED) \
$(WAYLAND_OBJ)
# The files included by tests are not in OBJ_COMMON.
OBJ_MAIN = \
@ -2954,6 +2967,7 @@ clean celan: testclean
cd $(PODIR); $(MAKE) prefix=$(DESTDIR)$(prefix) clean; \
fi
cd xxd; $(MAKE) clean
cd auto/wayland; $(MAKE) clean
# Make a shadow directory for compilation on another system or with different
# features:
@ -2982,6 +2996,8 @@ shadow: runtime pixmaps
$(MKDIR_P) $(SHADOWDIR)
cd $(SHADOWDIR); ln -s $(LINKEDFILES) .
mkdir $(SHADOWDIR)/auto
mkdir $(SHADOWDIR)/auto/wayland
cd $(SHADOWDIR)/auto/wayland; ln -s ../../../auto/wayland/* .
cd $(SHADOWDIR)/auto; ln -s ../../auto/configure .
$(MKDIR_P) $(SHADOWDIR)/po
cd $(SHADOWDIR)/po; ln -s ../../po/*.po ../../po/*.mak ../../po/*.vim ../../po/*.in ../../po/Makefile ../../po/*.c .
@ -3628,6 +3644,21 @@ objects/viminfo.o: viminfo.c
objects/window.o: window.c
$(CCC) -o $@ window.c
objects/wayland.o: wayland.c
$(CCC) -o $@ wayland.c
objects/wlr-data-control-unstable-v1.o: auto/wayland/wlr-data-control-unstable-v1.c
$(CCC) -o $@ auto/wayland/wlr-data-control-unstable-v1.c
objects/ext-data-control-v1.o: auto/wayland/ext-data-control-v1.c
$(CCC) -o $@ auto/wayland/ext-data-control-v1.c
objects/xdg-shell.o: auto/wayland/xdg-shell.c
$(CCC) -o $@ auto/wayland/xdg-shell.c
objects/primary-selection-unstable-v1.o: auto/wayland/primary-selection-unstable-v1.c
$(CCC) -o $@ auto/wayland/primary-selection-unstable-v1.c
objects/netbeans.o: netbeans.c
$(CCC) -o $@ netbeans.c
@ -4500,6 +4531,20 @@ objects/channel.o: channel.c vim.h protodef.h auto/config.h feature.h os_unix.h
proto/gui_beval.pro structs.h regexp.h gui.h libvterm/include/vterm.h \
libvterm/include/vterm_keycodes.h alloc.h ex_cmds.h spell.h proto.h \
globals.h errors.h
objects/wlr-data-control-unstable-v1.o: \
auto/wayland/wlr-data-control-unstable-v1.c
objects/ext-data-control-v1.o: auto/wayland/ext-data-control-v1.c
objects/xdg-shell.o: auto/wayland/xdg-shell.c
objects/primary-selection-unstable-v1.o: \
auto/wayland/primary-selection-unstable-v1.c
objects/wayland.o: wayland.c vim.h protodef.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \
structs.h regexp.h gui.h libvterm/include/vterm.h \
libvterm/include/vterm_keycodes.h xdiff/xdiff.h xdiff/../vim.h alloc.h \
ex_cmds.h spell.h proto.h globals.h errors.h \
auto/wayland/wlr-data-control-unstable-v1.h \
auto/wayland/ext-data-control-v1.h auto/wayland/xdg-shell.h \
auto/wayland/primary-selection-unstable-v1.h
objects/gui_gtk_gresources.o: auto/gui_gtk_gresources.c
objects/vterm_encoding.o: libvterm/src/encoding.c libvterm/src/vterm_internal.h \
libvterm/include/vterm.h libvterm/include/vterm_keycodes.h \

157
src/auto/configure vendored
View File

@ -676,6 +676,9 @@ X_PRE_LIBS
X_CFLAGS
XMKMF
xmkmfpath
WAYLAND_OBJ
WAYLAND_SRC
WAYLAND_LIBS
TERM_TEST
TERM_OBJ
TERM_SRC
@ -854,6 +857,7 @@ enable_arabic
enable_farsi
enable_xim
enable_fontset
with_wayland
with_x
enable_gui
enable_gtk2_check
@ -1575,6 +1579,7 @@ Optional Packages:
--with-python3-config-dir=PATH Python's config directory (deprecated)
--with-tclsh=PATH which tclsh to use (default: tclsh8.0)
--with-ruby-command=RUBY name of the Ruby command (default: ruby)
--with-wayland Include support for the Wayland protocol.
--with-x use the X Window System
--with-gnome-includes=DIR Specify location of GNOME headers
--with-gnome-libs=DIR Specify location of GNOME libs
@ -9058,6 +9063,158 @@ fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_fontset" >&5
printf "%s\n" "$enable_fontset" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if shm_open is available" >&5
printf %s "checking if shm_open is available... " >&6; }
cppflags_save=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
int
main (void)
{
shm_open("/test", O_CREAT, 0600);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }; printf "%s\n" "#define HAVE_SHM_OPEN 1" >>confdefs.h
else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; } ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CPPFLAGS=$cppflags_save
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --with-wayland argument" >&5
printf %s "checking --with-wayland argument... " >&6; }
# Check whether --with-wayland was given.
if test ${with_wayland+y}
then :
withval=$with_wayland;
fi
test -z "$with_wayland" && with_wayland=yes
if test "$with_wayland" = yes; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if wayland client header files can be found" >&5
printf %s "checking if wayland client header files can be found... " >&6; }
cppflags_save=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <wayland-client.h>
int
main (void)
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }; no_wl=yes ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CPPFLAGS=$cppflags_save
if test "$no_wl" = yes; then
with_wayland=no
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wl_display_connect in -lwayland-client" >&5
printf %s "checking for wl_display_connect in -lwayland-client... " >&6; }
if test ${ac_cv_lib_wayland_client_wl_display_connect+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) ac_check_lib_save_LIBS=$LIBS
LIBS="-lwayland-client $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply.
The 'extern "C"' is for builds by C++ compilers;
although this is not generally supported in C code supporting it here
has little cost and some practical benefit (sr 110532). */
#ifdef __cplusplus
extern "C"
#endif
char wl_display_connect (void);
int
main (void)
{
return wl_display_connect ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_wayland_client_wl_display_connect=yes
else case e in #(
e) ac_cv_lib_wayland_client_wl_display_connect=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wayland_client_wl_display_connect" >&5
printf "%s\n" "$ac_cv_lib_wayland_client_wl_display_connect" >&6; }
if test "x$ac_cv_lib_wayland_client_wl_display_connect" = xyes
then :
no_wl=no
fi
if test "$no_wl" = no; then
printf "%s\n" "#define HAVE_WAYLAND 1" >>confdefs.h
WAYLAND_LIBS="-lwayland-client";
WAYLAND_SRC=" \
auto/wayland/wlr-data-control-unstable-v1.c \
auto/wayland/ext-data-control-v1.c \
auto/wayland/xdg-shell.c \
auto/wayland/primary-selection-unstable-v1.c \
wayland.c"
WAYLAND_OBJ=" \
objects/wlr-data-control-unstable-v1.o \
objects/ext-data-control-v1.o \
objects/xdg-shell.o \
objects/primary-selection-unstable-v1.o \
objects/wayland.o"
else
with_wayland=no
fi
fi
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
test -z "$with_x" && with_x=yes
test "${enable_gui-yes}" != no -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" && with_x=yes
if test "$with_x" = no; then

52
src/auto/wayland/Makefile Normal file
View File

@ -0,0 +1,52 @@
# List of files to generate
GEN_XML = protocols/ext-data-control-v1.xml \
protocols/primary-selection-unstable-v1.xml \
protocols/wlr-data-control-unstable-v1.xml \
protocols/xdg-shell.xml
GEN_SRC = ext-data-control-v1.c \
primary-selection-unstable-v1.c \
wlr-data-control-unstable-v1.c \
xdg-shell.c
GEN_INCLUDE = ext-data-control-v1.h \
primary-selection-unstable-v1.h \
wlr-data-control-unstable-v1.h \
xdg-shell.h
# Default target
all: $(GEN_SRC) $(GEN_INCLUDE)
@if ! command -v wayland-scanner 2>&1 > /dev/null ; then \
echo "wayland-scanner not available, cannot generate protocol files"; \
false; \
fi
ext-data-control-v1.c:
wayland-scanner private-code protocols/ext-data-control-v1.xml $@
ext-data-control-v1.h:
wayland-scanner client-header protocols/ext-data-control-v1.xml $@
wlr-data-control-unstable-v1.c:
wayland-scanner private-code protocols/wlr-data-control-unstable-v1.xml $@
wlr-data-control-unstable-v1.h:
wayland-scanner client-header protocols/wlr-data-control-unstable-v1.xml $@
primary-selection-unstable-v1.c:
wayland-scanner private-code protocols/primary-selection-unstable-v1.xml $@
primary-selection-unstable-v1.h:
wayland-scanner client-header protocols/primary-selection-unstable-v1.xml $@
xdg-shell.c:
wayland-scanner private-code protocols/xdg-shell.xml $@
xdg-shell.h:
wayland-scanner client-header protocols/xdg-shell.xml $@
$(GEN_SRC) $(GEN_INCLUDE): $(GEN_XML)
$(GEN_XML):
# Clean rule
clean:
rm -f *.c *.h
.PHONY: all clean
# vim:ts=8:sw=8:tw=78

View File

@ -0,0 +1,11 @@
This directory contains the auto-generated protocol files for the Wayland
System Integration.
To re-generate them run make.
It requires wayland-scanner to be installed, which is generally found as
wayland-utils package in Linux distributions.
Included as of Vim patch v9.1.1485 (2025 Jun 27).
Initial work done by Foxe Chen.

View File

@ -0,0 +1,276 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="ext_data_control_v1">
<copyright>
Copyright © 2018 Simon Ser
Copyright © 2019 Ivan Molodetskikh
Copyright © 2024 Neal Gompa
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
the copyright holders not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission. The copyright holders make no
representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
</copyright>
<description summary="control data devices">
This protocol allows a privileged client to control data devices. In
particular, the client will be able to manage the current selection and take
the role of a clipboard manager.
Warning! The protocol described in this file is currently in the testing
phase. Backward compatible changes may be added together with the
corresponding interface version bump. Backward incompatible changes can
only be done by creating a new major version of the extension.
</description>
<interface name="ext_data_control_manager_v1" version="1">
<description summary="manager to control data devices">
This interface is a manager that allows creating per-seat data device
controls.
</description>
<request name="create_data_source">
<description summary="create a new data source">
Create a new data source.
</description>
<arg name="id" type="new_id" interface="ext_data_control_source_v1"
summary="data source to create"/>
</request>
<request name="get_data_device">
<description summary="get a data device for a seat">
Create a data device that can be used to manage a seat's selection.
</description>
<arg name="id" type="new_id" interface="ext_data_control_device_v1"/>
<arg name="seat" type="object" interface="wl_seat"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the manager">
All objects created by the manager will still remain valid, until their
appropriate destroy request has been called.
</description>
</request>
</interface>
<interface name="ext_data_control_device_v1" version="1">
<description summary="manage a data device for a seat">
This interface allows a client to manage a seat's selection.
When the seat is destroyed, this object becomes inert.
</description>
<request name="set_selection">
<description summary="copy data to the selection">
This request asks the compositor to set the selection to the data from
the source on behalf of the client.
The given source may not be used in any further set_selection or
set_primary_selection requests. Attempting to use a previously used
source triggers the used_source protocol error.
To unset the selection, set the source to NULL.
</description>
<arg name="source" type="object" interface="ext_data_control_source_v1"
allow-null="true"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy this data device">
Destroys the data device object.
</description>
</request>
<event name="data_offer">
<description summary="introduce a new ext_data_control_offer">
The data_offer event introduces a new ext_data_control_offer object,
which will subsequently be used in either the
ext_data_control_device.selection event (for the regular clipboard
selections) or the ext_data_control_device.primary_selection event (for
the primary clipboard selections). Immediately following the
ext_data_control_device.data_offer event, the new data_offer object
will send out ext_data_control_offer.offer events to describe the MIME
types it offers.
</description>
<arg name="id" type="new_id" interface="ext_data_control_offer_v1"/>
</event>
<event name="selection">
<description summary="advertise new selection">
The selection event is sent out to notify the client of a new
ext_data_control_offer for the selection for this device. The
ext_data_control_device.data_offer and the ext_data_control_offer.offer
events are sent out immediately before this event to introduce the data
offer object. The selection event is sent to a client when a new
selection is set. The ext_data_control_offer is valid until a new
ext_data_control_offer or NULL is received. The client must destroy the
previous selection ext_data_control_offer, if any, upon receiving this
event. Regardless, the previous selection will be ignored once a new
selection ext_data_control_offer is received.
The first selection event is sent upon binding the
ext_data_control_device object.
</description>
<arg name="id" type="object" interface="ext_data_control_offer_v1"
allow-null="true"/>
</event>
<event name="finished">
<description summary="this data control is no longer valid">
This data control object is no longer valid and should be destroyed by
the client.
</description>
</event>
<event name="primary_selection">
<description summary="advertise new primary selection">
The primary_selection event is sent out to notify the client of a new
ext_data_control_offer for the primary selection for this device. The
ext_data_control_device.data_offer and the ext_data_control_offer.offer
events are sent out immediately before this event to introduce the data
offer object. The primary_selection event is sent to a client when a
new primary selection is set. The ext_data_control_offer is valid until
a new ext_data_control_offer or NULL is received. The client must
destroy the previous primary selection ext_data_control_offer, if any,
upon receiving this event. Regardless, the previous primary selection
will be ignored once a new primary selection ext_data_control_offer is
received.
If the compositor supports primary selection, the first
primary_selection event is sent upon binding the
ext_data_control_device object.
</description>
<arg name="id" type="object" interface="ext_data_control_offer_v1"
allow-null="true"/>
</event>
<request name="set_primary_selection">
<description summary="copy data to the primary selection">
This request asks the compositor to set the primary selection to the
data from the source on behalf of the client.
The given source may not be used in any further set_selection or
set_primary_selection requests. Attempting to use a previously used
source triggers the used_source protocol error.
To unset the primary selection, set the source to NULL.
The compositor will ignore this request if it does not support primary
selection.
</description>
<arg name="source" type="object" interface="ext_data_control_source_v1"
allow-null="true"/>
</request>
<enum name="error">
<entry name="used_source" value="1"
summary="source given to set_selection or set_primary_selection was already used before"/>
</enum>
</interface>
<interface name="ext_data_control_source_v1" version="1">
<description summary="offer to transfer data">
The ext_data_control_source object is the source side of a
ext_data_control_offer. It is created by the source client in a data
transfer and provides a way to describe the offered data and a way to
respond to requests to transfer the data.
</description>
<enum name="error">
<entry name="invalid_offer" value="1"
summary="offer sent after ext_data_control_device.set_selection"/>
</enum>
<request name="offer">
<description summary="add an offered MIME type">
This request adds a MIME type to the set of MIME types advertised to
targets. Can be called several times to offer multiple types.
Calling this after ext_data_control_device.set_selection is a protocol
error.
</description>
<arg name="mime_type" type="string"
summary="MIME type offered by the data source"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy this source">
Destroys the data source object.
</description>
</request>
<event name="send">
<description summary="send the data">
Request for data from the client. Send the data as the specified MIME
type over the passed file descriptor, then close it.
</description>
<arg name="mime_type" type="string" summary="MIME type for the data"/>
<arg name="fd" type="fd" summary="file descriptor for the data"/>
</event>
<event name="cancelled">
<description summary="selection was cancelled">
This data source is no longer valid. The data source has been replaced
by another data source.
The client should clean up and destroy this data source.
</description>
</event>
</interface>
<interface name="ext_data_control_offer_v1" version="1">
<description summary="offer to transfer data">
A ext_data_control_offer represents a piece of data offered for transfer
by another client (the source client). The offer describes the different
MIME types that the data can be converted to and provides the mechanism
for transferring the data directly from the source client.
</description>
<request name="receive">
<description summary="request that the data is transferred">
To transfer the offered data, the client issues this request and
indicates the MIME type it wants to receive. The transfer happens
through the passed file descriptor (typically created with the pipe
system call). The source client writes the data in the MIME type
representation requested and then closes the file descriptor.
The receiving client reads from the read end of the pipe until EOF and
then closes its end, at which point the transfer is complete.
This request may happen multiple times for different MIME types.
</description>
<arg name="mime_type" type="string"
summary="MIME type desired by receiver"/>
<arg name="fd" type="fd" summary="file descriptor for data transfer"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy this offer">
Destroys the data offer object.
</description>
</request>
<event name="offer">
<description summary="advertise offered MIME type">
Sent immediately after creating the ext_data_control_offer object.
One event per offered MIME type.
</description>
<arg name="mime_type" type="string" summary="offered MIME type"/>
</event>
</interface>
</protocol>

View File

@ -0,0 +1,225 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="wp_primary_selection_unstable_v1">
<copyright>
Copyright © 2015, 2016 Red Hat
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<description summary="Primary selection protocol">
This protocol provides the ability to have a primary selection device to
match that of the X server. This primary selection is a shortcut to the
common clipboard selection, where text just needs to be selected in order
to allow copying it elsewhere. The de facto way to perform this action
is the middle mouse button, although it is not limited to this one.
Clients wishing to honor primary selection should create a primary
selection source and set it as the selection through
wp_primary_selection_device.set_selection whenever the text selection
changes. In order to minimize calls in pointer-driven text selection,
it should happen only once after the operation finished. Similarly,
a NULL source should be set when text is unselected.
wp_primary_selection_offer objects are first announced through the
wp_primary_selection_device.data_offer event. Immediately after this event,
the primary data offer will emit wp_primary_selection_offer.offer events
to let know of the mime types being offered.
When the primary selection changes, the client with the keyboard focus
will receive wp_primary_selection_device.selection events. Only the client
with the keyboard focus will receive such events with a non-NULL
wp_primary_selection_offer. Across keyboard focus changes, previously
focused clients will receive wp_primary_selection_device.events with a
NULL wp_primary_selection_offer.
In order to request the primary selection data, the client must pass
a recent serial pertaining to the press event that is triggering the
operation, if the compositor deems the serial valid and recent, the
wp_primary_selection_source.send event will happen in the other end
to let the transfer begin. The client owning the primary selection
should write the requested data, and close the file descriptor
immediately.
If the primary selection owner client disappeared during the transfer,
the client reading the data will receive a
wp_primary_selection_device.selection event with a NULL
wp_primary_selection_offer, the client should take this as a hint
to finish the reads related to the no longer existing offer.
The primary selection owner should be checking for errors during
writes, merely cancelling the ongoing transfer if any happened.
</description>
<interface name="zwp_primary_selection_device_manager_v1" version="1">
<description summary="X primary selection emulation">
The primary selection device manager is a singleton global object that
provides access to the primary selection. It allows to create
wp_primary_selection_source objects, as well as retrieving the per-seat
wp_primary_selection_device objects.
</description>
<request name="create_source">
<description summary="create a new primary selection source">
Create a new primary selection source.
</description>
<arg name="id" type="new_id" interface="zwp_primary_selection_source_v1"/>
</request>
<request name="get_device">
<description summary="create a new primary selection device">
Create a new data device for a given seat.
</description>
<arg name="id" type="new_id" interface="zwp_primary_selection_device_v1"/>
<arg name="seat" type="object" interface="wl_seat"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the primary selection device manager">
Destroy the primary selection device manager.
</description>
</request>
</interface>
<interface name="zwp_primary_selection_device_v1" version="1">
<request name="set_selection">
<description summary="set the primary selection">
Replaces the current selection. The previous owner of the primary
selection will receive a wp_primary_selection_source.cancelled event.
To unset the selection, set the source to NULL.
</description>
<arg name="source" type="object" interface="zwp_primary_selection_source_v1" allow-null="true"/>
<arg name="serial" type="uint" summary="serial of the event that triggered this request"/>
</request>
<event name="data_offer">
<description summary="introduce a new wp_primary_selection_offer">
Introduces a new wp_primary_selection_offer object that may be used
to receive the current primary selection. Immediately following this
event, the new wp_primary_selection_offer object will send
wp_primary_selection_offer.offer events to describe the offered mime
types.
</description>
<arg name="offer" type="new_id" interface="zwp_primary_selection_offer_v1"/>
</event>
<event name="selection">
<description summary="advertise a new primary selection">
The wp_primary_selection_device.selection event is sent to notify the
client of a new primary selection. This event is sent after the
wp_primary_selection.data_offer event introducing this object, and after
the offer has announced its mimetypes through
wp_primary_selection_offer.offer.
The data_offer is valid until a new offer or NULL is received
or until the client loses keyboard focus. The client must destroy the
previous selection data_offer, if any, upon receiving this event.
</description>
<arg name="id" type="object" interface="zwp_primary_selection_offer_v1" allow-null="true"/>
</event>
<request name="destroy" type="destructor">
<description summary="destroy the primary selection device">
Destroy the primary selection device.
</description>
</request>
</interface>
<interface name="zwp_primary_selection_offer_v1" version="1">
<description summary="offer to transfer primary selection contents">
A wp_primary_selection_offer represents an offer to transfer the contents
of the primary selection clipboard to the client. Similar to
wl_data_offer, the offer also describes the mime types that the data can
be converted to and provides the mechanisms for transferring the data
directly to the client.
</description>
<request name="receive">
<description summary="request that the data is transferred">
To transfer the contents of the primary selection clipboard, the client
issues this request and indicates the mime type that it wants to
receive. The transfer happens through the passed file descriptor
(typically created with the pipe system call). The source client writes
the data in the mime type representation requested and then closes the
file descriptor.
The receiving client reads from the read end of the pipe until EOF and
closes its end, at which point the transfer is complete.
</description>
<arg name="mime_type" type="string"/>
<arg name="fd" type="fd"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the primary selection offer">
Destroy the primary selection offer.
</description>
</request>
<event name="offer">
<description summary="advertise offered mime type">
Sent immediately after creating announcing the
wp_primary_selection_offer through
wp_primary_selection_device.data_offer. One event is sent per offered
mime type.
</description>
<arg name="mime_type" type="string"/>
</event>
</interface>
<interface name="zwp_primary_selection_source_v1" version="1">
<description summary="offer to replace the contents of the primary selection">
The source side of a wp_primary_selection_offer, it provides a way to
describe the offered data and respond to requests to transfer the
requested contents of the primary selection clipboard.
</description>
<request name="offer">
<description summary="add an offered mime type">
This request adds a mime type to the set of mime types advertised to
targets. Can be called several times to offer multiple types.
</description>
<arg name="mime_type" type="string"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the primary selection source">
Destroy the primary selection source.
</description>
</request>
<event name="send">
<description summary="send the primary selection contents">
Request for the current primary selection contents from the client.
Send the specified mime type over the passed file descriptor, then
close it.
</description>
<arg name="mime_type" type="string"/>
<arg name="fd" type="fd"/>
</event>
<event name="cancelled">
<description summary="request for primary selection contents was canceled">
This primary selection source is no longer valid. The client should
clean up and destroy this primary selection source.
</description>
</event>
</interface>
</protocol>

View File

@ -0,0 +1,278 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="wlr_data_control_unstable_v1">
<copyright>
Copyright © 2018 Simon Ser
Copyright © 2019 Ivan Molodetskikh
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
the copyright holders not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission. The copyright holders make no
representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
</copyright>
<description summary="control data devices">
This protocol allows a privileged client to control data devices. In
particular, the client will be able to manage the current selection and take
the role of a clipboard manager.
Warning! The protocol described in this file is experimental and
backward incompatible changes may be made. Backward compatible changes
may be added together with the corresponding interface version bump.
Backward incompatible changes are done by bumping the version number in
the protocol and interface names and resetting the interface version.
Once the protocol is to be declared stable, the 'z' prefix and the
version number in the protocol and interface names are removed and the
interface version number is reset.
</description>
<interface name="zwlr_data_control_manager_v1" version="2">
<description summary="manager to control data devices">
This interface is a manager that allows creating per-seat data device
controls.
</description>
<request name="create_data_source">
<description summary="create a new data source">
Create a new data source.
</description>
<arg name="id" type="new_id" interface="zwlr_data_control_source_v1"
summary="data source to create"/>
</request>
<request name="get_data_device">
<description summary="get a data device for a seat">
Create a data device that can be used to manage a seat's selection.
</description>
<arg name="id" type="new_id" interface="zwlr_data_control_device_v1"/>
<arg name="seat" type="object" interface="wl_seat"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the manager">
All objects created by the manager will still remain valid, until their
appropriate destroy request has been called.
</description>
</request>
</interface>
<interface name="zwlr_data_control_device_v1" version="2">
<description summary="manage a data device for a seat">
This interface allows a client to manage a seat's selection.
When the seat is destroyed, this object becomes inert.
</description>
<request name="set_selection">
<description summary="copy data to the selection">
This request asks the compositor to set the selection to the data from
the source on behalf of the client.
The given source may not be used in any further set_selection or
set_primary_selection requests. Attempting to use a previously used
source is a protocol error.
To unset the selection, set the source to NULL.
</description>
<arg name="source" type="object" interface="zwlr_data_control_source_v1"
allow-null="true"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy this data device">
Destroys the data device object.
</description>
</request>
<event name="data_offer">
<description summary="introduce a new wlr_data_control_offer">
The data_offer event introduces a new wlr_data_control_offer object,
which will subsequently be used in either the
wlr_data_control_device.selection event (for the regular clipboard
selections) or the wlr_data_control_device.primary_selection event (for
the primary clipboard selections). Immediately following the
wlr_data_control_device.data_offer event, the new data_offer object
will send out wlr_data_control_offer.offer events to describe the MIME
types it offers.
</description>
<arg name="id" type="new_id" interface="zwlr_data_control_offer_v1"/>
</event>
<event name="selection">
<description summary="advertise new selection">
The selection event is sent out to notify the client of a new
wlr_data_control_offer for the selection for this device. The
wlr_data_control_device.data_offer and the wlr_data_control_offer.offer
events are sent out immediately before this event to introduce the data
offer object. The selection event is sent to a client when a new
selection is set. The wlr_data_control_offer is valid until a new
wlr_data_control_offer or NULL is received. The client must destroy the
previous selection wlr_data_control_offer, if any, upon receiving this
event.
The first selection event is sent upon binding the
wlr_data_control_device object.
</description>
<arg name="id" type="object" interface="zwlr_data_control_offer_v1"
allow-null="true"/>
</event>
<event name="finished">
<description summary="this data control is no longer valid">
This data control object is no longer valid and should be destroyed by
the client.
</description>
</event>
<!-- Version 2 additions -->
<event name="primary_selection" since="2">
<description summary="advertise new primary selection">
The primary_selection event is sent out to notify the client of a new
wlr_data_control_offer for the primary selection for this device. The
wlr_data_control_device.data_offer and the wlr_data_control_offer.offer
events are sent out immediately before this event to introduce the data
offer object. The primary_selection event is sent to a client when a
new primary selection is set. The wlr_data_control_offer is valid until
a new wlr_data_control_offer or NULL is received. The client must
destroy the previous primary selection wlr_data_control_offer, if any,
upon receiving this event.
If the compositor supports primary selection, the first
primary_selection event is sent upon binding the
wlr_data_control_device object.
</description>
<arg name="id" type="object" interface="zwlr_data_control_offer_v1"
allow-null="true"/>
</event>
<request name="set_primary_selection" since="2">
<description summary="copy data to the primary selection">
This request asks the compositor to set the primary selection to the
data from the source on behalf of the client.
The given source may not be used in any further set_selection or
set_primary_selection requests. Attempting to use a previously used
source is a protocol error.
To unset the primary selection, set the source to NULL.
The compositor will ignore this request if it does not support primary
selection.
</description>
<arg name="source" type="object" interface="zwlr_data_control_source_v1"
allow-null="true"/>
</request>
<enum name="error" since="2">
<entry name="used_source" value="1"
summary="source given to set_selection or set_primary_selection was already used before"/>
</enum>
</interface>
<interface name="zwlr_data_control_source_v1" version="1">
<description summary="offer to transfer data">
The wlr_data_control_source object is the source side of a
wlr_data_control_offer. It is created by the source client in a data
transfer and provides a way to describe the offered data and a way to
respond to requests to transfer the data.
</description>
<enum name="error">
<entry name="invalid_offer" value="1"
summary="offer sent after wlr_data_control_device.set_selection"/>
</enum>
<request name="offer">
<description summary="add an offered MIME type">
This request adds a MIME type to the set of MIME types advertised to
targets. Can be called several times to offer multiple types.
Calling this after wlr_data_control_device.set_selection is a protocol
error.
</description>
<arg name="mime_type" type="string"
summary="MIME type offered by the data source"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy this source">
Destroys the data source object.
</description>
</request>
<event name="send">
<description summary="send the data">
Request for data from the client. Send the data as the specified MIME
type over the passed file descriptor, then close it.
</description>
<arg name="mime_type" type="string" summary="MIME type for the data"/>
<arg name="fd" type="fd" summary="file descriptor for the data"/>
</event>
<event name="cancelled">
<description summary="selection was cancelled">
This data source is no longer valid. The data source has been replaced
by another data source.
The client should clean up and destroy this data source.
</description>
</event>
</interface>
<interface name="zwlr_data_control_offer_v1" version="1">
<description summary="offer to transfer data">
A wlr_data_control_offer represents a piece of data offered for transfer
by another client (the source client). The offer describes the different
MIME types that the data can be converted to and provides the mechanism
for transferring the data directly from the source client.
</description>
<request name="receive">
<description summary="request that the data is transferred">
To transfer the offered data, the client issues this request and
indicates the MIME type it wants to receive. The transfer happens
through the passed file descriptor (typically created with the pipe
system call). The source client writes the data in the MIME type
representation requested and then closes the file descriptor.
The receiving client reads from the read end of the pipe until EOF and
then closes its end, at which point the transfer is complete.
This request may happen multiple times for different MIME types.
</description>
<arg name="mime_type" type="string"
summary="MIME type desired by receiver"/>
<arg name="fd" type="fd" summary="file descriptor for data transfer"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy this offer">
Destroys the data offer object.
</description>
</request>
<event name="offer">
<description summary="advertise offered MIME type">
Sent immediately after creating the wlr_data_control_offer object.
One event per offered MIME type.
</description>
<arg name="mime_type" type="string" summary="offered MIME type"/>
</event>
</interface>
</protocol>

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,32 @@
#if defined(FEAT_CLIPBOARD) || defined(PROTO)
#if defined(FEAT_WAYLAND_CLIPBOARD)
// Mime types we support sending and receiving
// Mimes with a lower index in the array are prioritized first when we are
// receiving data.
static const char *supported_mimes[] = {
VIMENC_ATOM_NAME,
VIM_ATOM_NAME,
"text/plain;charset=utf-8",
"text/plain",
"UTF8_STRING",
"STRING",
"TEXT"
};
static void clip_wl_receive_data(Clipboard_T *cbd,
const char *mime_type, int fd);
static void clip_wl_send_data(const char *mime_type, int fd,
wayland_selection_T);
static void clip_wl_selection_cancelled(wayland_selection_T selection);
#if defined(USE_SYSTEM) && defined(PROTO)
static int clip_wl_owner_exists(Clipboard_T *cbd);
#endif
#endif
/*
* Selection stuff using Visual mode, for cutting and pasting text to other
* windows.
@ -50,6 +76,10 @@ clip_init(int can_use)
cb = &clip_star;
for (;;)
{
// No need to init again if cbd is already available
if (can_use && cb->available)
goto skip;
cb->available = can_use;
cb->owned = FALSE;
cb->start.lnum = 0;
@ -58,6 +88,7 @@ clip_init(int can_use)
cb->end.col = 0;
cb->state = SELECT_CLEARED;
skip:
if (cb == &clip_plus)
break;
cb = &clip_plus;
@ -109,13 +140,27 @@ clip_update_selection(Clipboard_T *clip)
static int
clip_gen_own_selection(Clipboard_T *cbd)
{
#ifdef FEAT_XCLIPBOARD
#if defined(FEAT_XCLIPBOARD) || defined(FEAT_WAYLAND_CLIPBOARD)
# ifdef FEAT_GUI
if (gui.in_use)
return clip_mch_own_selection(cbd);
else
# endif
return clip_xterm_own_selection(cbd);
{
if (clipmethod == CLIPMETHOD_WAYLAND)
{
#ifdef FEAT_WAYLAND_CLIPBOARD
return clip_wl_own_selection(cbd);
#endif
}
else if (clipmethod == CLIPMETHOD_X11)
{
#ifdef FEAT_XCLIPBOARD
return clip_xterm_own_selection(cbd);
#endif
}
}
return FAIL;
#else
return clip_mch_own_selection(cbd);
#endif
@ -128,7 +173,7 @@ clip_own_selection(Clipboard_T *cbd)
* Also want to check somehow that we are reading from the keyboard rather
* than a mapping etc.
*/
#ifdef FEAT_X11
#if defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD)
// Always own the selection, we might have lost it without being
// notified, e.g. during a ":sh" command.
if (cbd->available)
@ -160,13 +205,26 @@ clip_own_selection(Clipboard_T *cbd)
static void
clip_gen_lose_selection(Clipboard_T *cbd)
{
#ifdef FEAT_XCLIPBOARD
#if defined(FEAT_XCLIPBOARD) || defined(FEAT_WAYLAND_CLIPBOARD)
# ifdef FEAT_GUI
if (gui.in_use)
clip_mch_lose_selection(cbd);
else
# endif
clip_xterm_lose_selection(cbd);
{
if (clipmethod == CLIPMETHOD_WAYLAND)
{
#ifdef FEAT_WAYLAND_CLIPBOARD
clip_wl_lose_selection(cbd);
#endif
}
else if (clipmethod == CLIPMETHOD_X11)
{
#ifdef FEAT_XCLIPBOARD
clip_xterm_lose_selection(cbd);
#endif
}
}
#else
clip_mch_lose_selection(cbd);
#endif
@ -196,9 +254,9 @@ clip_lose_selection(Clipboard_T *cbd)
// windows on the current buffer.
if (was_owned
&& (get_real_state() == MODE_VISUAL
|| get_real_state() == MODE_SELECT)
|| get_real_state() == MODE_SELECT)
&& (cbd == &clip_star ?
clip_isautosel_star() : clip_isautosel_plus())
clip_isautosel_star() : clip_isautosel_plus())
&& HL_ATTR(HLF_V) != HL_ATTR(HLF_VNC)
&& !exiting)
{
@ -1195,13 +1253,26 @@ clip_gen_set_selection(Clipboard_T *cbd)
return;
}
}
#ifdef FEAT_XCLIPBOARD
#if defined(FEAT_XCLIPBOARD) || defined(FEAT_WAYLAND_CLIPBOARD)
# ifdef FEAT_GUI
if (gui.in_use)
clip_mch_set_selection(cbd);
else
# endif
clip_xterm_set_selection(cbd);
{
if (clipmethod == CLIPMETHOD_WAYLAND)
{
#ifdef FEAT_WAYLAND_CLIPBOARD
clip_wl_set_selection(cbd);
#endif
}
else if (clipmethod == CLIPMETHOD_X11)
{
#ifdef FEAT_XCLIPBOARD
clip_xterm_set_selection(cbd);
#endif
}
}
#else
clip_mch_set_selection(cbd);
#endif
@ -1210,13 +1281,26 @@ clip_gen_set_selection(Clipboard_T *cbd)
static void
clip_gen_request_selection(Clipboard_T *cbd)
{
#ifdef FEAT_XCLIPBOARD
#if defined(FEAT_XCLIPBOARD) || defined(FEAT_WAYLAND_CLIPBOARD)
# ifdef FEAT_GUI
if (gui.in_use)
clip_mch_request_selection(cbd);
else
# endif
clip_xterm_request_selection(cbd);
{
if (clipmethod == CLIPMETHOD_WAYLAND)
{
#ifdef FEAT_WAYLAND_CLIPBOARD
clip_wl_request_selection(cbd);
#endif
}
else if (clipmethod == CLIPMETHOD_X11)
{
#ifdef FEAT_XCLIPBOARD
clip_xterm_request_selection(cbd);
#endif
}
}
#else
clip_mch_request_selection(cbd);
#endif
@ -1231,7 +1315,8 @@ clip_x11_owner_exists(Clipboard_T *cbd)
}
#endif
#if (defined(FEAT_X11) && defined(USE_SYSTEM)) || defined(PROTO)
#if ((defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD)) \
&& defined(USE_SYSTEM)) || defined(PROTO)
int
clip_gen_owner_exists(Clipboard_T *cbd UNUSED)
{
@ -1241,7 +1326,22 @@ clip_gen_owner_exists(Clipboard_T *cbd UNUSED)
return clip_gtk_owner_exists(cbd);
else
# endif
return clip_x11_owner_exists(cbd);
{
if (clipmethod == CLIPMETHOD_WAYLAND)
{
#ifdef FEAT_WAYLAND_CLIPBOARD
return clip_wl_owner_exists(cbd);
#endif
}
else if (clipmethod == CLIPMETHOD_X11)
{
#ifdef FEAT_XCLIPBOARD
return clip_x11_owner_exists(cbd);
#endif
}
else
return FALSE;
}
#else
return TRUE;
#endif
@ -2228,4 +2328,550 @@ adjust_clip_reg(int *rp)
}
}
#if defined(FEAT_WAYLAND_CLIPBOARD) || defined(PROTO)
/*
* Read data from a file descriptor and write it to the given clipboard.
*/
static void
clip_wl_receive_data(Clipboard_T *cbd, const char *mime_type, int fd)
{
char_u *start, *buf, *tmp, *final, *enc;
int motion_type = MAUTO;
ssize_t r = 0;
size_t total = 0, max_total = 4096; // Initial buffer size, 4096
// bytes seems reasonable.
#ifndef HAVE_SELECT
struct pollfd pfd
pfd.fd = fd,
pfd.events = POLLIN
#else
fd_set rfds;
struct timeval tv;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = p_wtm * 1000;
#endif
// Make pipe (read end) non-blocking
if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) == -1)
return;
if ((buf = alloc_clear(max_total)) == NULL)
return;
start = buf;
// Only poll before reading when we first start, then we do non-blocking
// reads and check for EAGAIN or EINTR to signal to poll again.
goto poll_data;
while (errno = 0, TRUE)
{
r = read(fd, start, max_total - 1 - total);
if (r == 0)
break;
else if (r < 0)
{
if (errno == EAGAIN || errno == EINTR)
{
poll_data:
#ifndef HAVE_SELECT
if (poll(&pfd, 1, p_wtm) > 0)
#else
if (select(fd + 1, &rfds, NULL, NULL, &tv) > 0)
#endif
continue;
}
break;
}
start += r;
total += (size_t)r;
// Realloc if we are at the end of the buffer
if (total >= max_total - 1)
{
tmp = vim_realloc(buf, max_total * 2);
if (tmp == NULL)
break;
max_total *= 2; // Double buffer size each time
buf = tmp;
start = buf + total;
// Zero out the newly allocated memory part
vim_memset(buf + total, 0, max_total - total);
}
}
if (total == 0)
{
clip_free_selection(cbd); // Nothing received, clear register
vim_free(buf);
return;
}
final = buf;
if (STRCMP(mime_type, VIM_ATOM_NAME) == 0 && total >= 2)
{
motion_type = *final++;;
total--;
}
else if (STRCMP(mime_type, VIMENC_ATOM_NAME) == 0 && total >= 3)
{
vimconv_T conv;
int convlen;
// first byte is motion type
motion_type = *final++;
total--;
// Get encoding of selection
enc = final;
// Skip the encoding type including null terminator in final text
final += STRLEN(final) + 1;
// Subtract pointers to get length of encoding;
total -= final - enc;
conv.vc_type = CONV_NONE;
convert_setup(&conv, enc, p_enc);
if (conv.vc_type != CONV_NONE)
{
convlen = total;
tmp = string_convert(&conv, final, &convlen);
total = convlen;
if (tmp != NULL)
final = tmp;
convert_setup(&conv, NULL, NULL);
}
}
clip_yank_selection(motion_type, final, (long)total, cbd);
vim_free(buf);
}
/*
* Get the current selection and fill the respective register for cbd with the
* data.
*/
void
clip_wl_request_selection(Clipboard_T *cbd)
{
wayland_selection_T selection;
garray_T *mime_types;
int len;
int fd;
const char *chosen_mime = NULL;
if (cbd == &clip_star)
selection = WAYLAND_SELECTION_PRIMARY;
else if (cbd == &clip_plus)
selection = WAYLAND_SELECTION_REGULAR;
else
return;
// Get mime types that the source client offers
mime_types = wayland_cb_get_mime_types(selection);
if (mime_types == NULL || mime_types->ga_len == 0)
{
// Selection is empty/cleared
clip_free_selection(cbd);
return;
}
len = ARRAY_LENGTH(supported_mimes);
// Loop through and pick the one we want to receive from
for (int i = 0; i < len && chosen_mime == NULL; i++)
{
for (int k = 0; k < mime_types->ga_len && chosen_mime == NULL; k++)
{
char *mime_type = ((char**)mime_types->ga_data)[k];
if (STRCMP(mime_type, supported_mimes[i]) == 0)
chosen_mime = supported_mimes[i];
}
}
if (chosen_mime == NULL)
return;
fd = wayland_cb_receive_data(chosen_mime, selection);
if (fd == -1)
return;
// Start reading the file descriptor returned
clip_wl_receive_data(cbd, chosen_mime, fd);
close(fd);
}
/*
* Write data from either the clip or plus register, depending on the given
* selection, to the file descriptor that the receiving client will read from.
*/
static void
clip_wl_send_data(
const char *mime_type,
int fd,
wayland_selection_T selection)
{
Clipboard_T *cbd;
long_u length;
char_u *string;
ssize_t written = 0;
size_t total = 0;
int did_vimenc = TRUE;
int did_motion_type = TRUE;
int motion_type;
int skip_len_check = FALSE;
#ifndef HAVE_SELECT
struct pollfd pfd
pfd.fd = fd,
pfd.events = POLLOUT
#else
fd_set wfds;
struct timeval tv;
FD_ZERO(&wfds);
FD_SET(fd, &wfds);
tv.tv_sec = 0;
tv.tv_usec = p_wtm * 1000;
#endif
if (selection == WAYLAND_SELECTION_REGULAR)
cbd = &clip_plus;
else if (selection == WAYLAND_SELECTION_PRIMARY)
cbd = &clip_star;
else
return;
// Shouldn't happen unless there is a bug.
if (!cbd->owned)
return;
// Get the current selection
clip_get_selection(cbd);
motion_type = clip_convert_selection(&string, &length, cbd);
if (motion_type < 0)
goto exit;
if (STRCMP(mime_type, VIMENC_ATOM_NAME) == 0)
{
did_vimenc = FALSE;
did_motion_type = FALSE;
}
else if (STRCMP(mime_type, VIM_ATOM_NAME) == 0)
did_motion_type = FALSE;
while ((total < (size_t)length || skip_len_check) &&
#ifndef HAVE_SELECT
poll(&pfd, 1, p_wtm) > 0)
#else
select(fd + 1, NULL, &wfds, NULL, &tv) > 0)
#endif
{
// First byte sent is motion type for vim specific formats
if (!did_motion_type)
{
if (total == 1)
{
total = 0;
did_motion_type = TRUE;
continue;
}
// We cast to char so that we only send one byte
written = write( fd, (char_u*)&motion_type, 1);
skip_len_check = TRUE;
}
else if (!did_vimenc)
{
// For the vimenc format, after the first byte is the encoding type,
// which is null terminated. Make sure we write that before writing
// the actual selection.
if (total == STRLEN(p_enc) + 1)
{
total = 0;
did_vimenc = TRUE;
continue;
}
// Include null terminator
written = write(fd, p_enc + total, STRLEN(p_enc) + 1 - total);
skip_len_check = TRUE;
}
else
{
// write the actual selection to the fd
written = write(fd, string + total, length - total);
if (skip_len_check)
skip_len_check = FALSE;
}
if (written == -1)
break;
total += written;
}
exit:
vim_free(string);
}
/*
* Called if another client gains ownership of the given selection. If so then
* lose the selection internally.
*/
static void
clip_wl_selection_cancelled(wayland_selection_T selection)
{
if (selection == WAYLAND_SELECTION_REGULAR)
clip_lose_selection(&clip_plus);
else if (selection == WAYLAND_SELECTION_PRIMARY)
clip_lose_selection(&clip_star);
}
/*
* Own the selection that cbd corresponds to. Start listening for requests from
* other Wayland clients so they can receive data from us. Returns OK on success
* and FAIL on failure.
*/
int
clip_wl_own_selection(Clipboard_T *cbd)
{
wayland_selection_T selection;
if (cbd == &clip_star)
selection = WAYLAND_SELECTION_PRIMARY;
else if (cbd == &clip_plus)
selection = WAYLAND_SELECTION_REGULAR;
else
return FAIL;
return wayland_cb_own_selection(
clip_wl_send_data,
clip_wl_selection_cancelled,
supported_mimes,
sizeof(supported_mimes)/sizeof(*supported_mimes),
selection);
}
/*
* Disown the selection that cbd corresponds to. Note that the the cancelled
* event is not sent when the data source is destroyed.
*/
void
clip_wl_lose_selection(Clipboard_T *cbd)
{
if (cbd == &clip_plus)
wayland_cb_lose_selection(WAYLAND_SELECTION_REGULAR);
else if (cbd == &clip_star)
wayland_cb_lose_selection(WAYLAND_SELECTION_PRIMARY);
/* wayland_cb_lose_selection(selection); */
}
/*
* Send the current selection to the clipboard. Do nothing for wayland because
* we will fill in the selection only when requested by another client.
*/
void
clip_wl_set_selection(Clipboard_T *cbd UNUSED)
{
}
#if defined(USE_SYSTEM) && defined(PROTO)
/*
* Return TRUE if we own the selection corresponding to cbd
*/
static int
clip_wl_owner_exists(Clipboard_T *cbd)
{
if (cbd == &clip_plus)
return wayland_cb_selection_is_owned(WAYLAND_SELECTION_REGULAR);
else if (cbd == &clip_star)
return wayland_cb_selection_is_owned(WAYLAND_SELECTION_PRIMARY);
}
#endif
#endif // FEAT_WAYLAND_CLIPBOARD
/*
* Returns the first method for accessing the clipboard that is available/works,
* depending on the order of values in str.
*/
static clipmethod_T
get_clipmethod(char_u *str)
{
int len = (int)STRLEN(str) + 1;
char_u *buf = alloc(len);
if (buf == NULL)
return CLIPMETHOD_FAIL;
clipmethod_T ret = CLIPMETHOD_FAIL;
char_u *p = str;
while (*p != NUL)
{
clipmethod_T method = CLIPMETHOD_NONE;
(void)copy_option_part(&p, buf, len, ",");
if (STRCMP(buf, "wayland") == 0)
{
#ifdef FEAT_WAYLAND_CLIPBOARD
if (wayland_cb_is_ready())
method = CLIPMETHOD_WAYLAND;
#endif
}
else if (STRCMP(buf, "x11") == 0)
{
#ifdef FEAT_XCLIPBOARD
// x_IOerror_handler() in os_unix.c should set xterm_dpy to NULL if
// we lost connection to the X server.
if (xterm_dpy != NULL)
{
// If the X connection is lost then that handler will longjmp
// somewhere else, in that case we will call choose_clipmethod()
// again from there, and this if block won't be executed since
// xterm_dpy will be set to NULL.
xterm_update();
method = CLIPMETHOD_X11;
}
#endif
}
else
{
ret = CLIPMETHOD_FAIL;
goto exit;
}
// Keep on going in order to catch errors
if (method != CLIPMETHOD_NONE && ret == CLIPMETHOD_FAIL)
ret = method;
}
// No match found, use "none".
ret = (ret == CLIPMETHOD_FAIL) ? CLIPMETHOD_NONE : ret;
exit:
vim_free(buf);
return ret;
}
/*
* Returns name of clipmethod in a statically allocated string.
*/
static char *
clipmethod_to_str(clipmethod_T method)
{
switch(method)
{
case CLIPMETHOD_WAYLAND:
return "wayland";
case CLIPMETHOD_X11:
return "x11";
default:
return "none";
}
}
/*
* Sets the current clipmethod to use given by `get_clipmethod()`. Returns an
* error message on failure else NULL.
*/
char *
choose_clipmethod(void)
{
// We call get_clipmethod first so that we can catch any errors, even if
// clipmethod is useless
clipmethod_T method = get_clipmethod(p_cpm);
if (method == CLIPMETHOD_FAIL)
return e_invalid_argument;
// If GUI is running or we are not on a system with wayland or x11, then always
// return CLIPMETHOD_NONE. System or GUI clipboard handling always overrides.
#if defined(FEAT_XCLIPBOARD) || defined(FEAT_WAYLAND_CLIPBOARD)
#if defined(FEAT_GUI)
if (gui.in_use)
{
#ifdef FEAT_WAYLAND
// We only interact with wayland for the clipboard, we can just deinit
// everything.
wayland_uninit_client();
#endif
method = CLIPMETHOD_NONE;
goto lose_sel_exit;
}
#endif
#else
// If on a system like windows or macos, then clipmethod is irrelevant, we
// use their way of accessing the clipboard.
method = CLIPMETHOD_NONE;
goto exit;
#endif
// Deinitialize clipboard if there is no way to access clipboard
if (method == CLIPMETHOD_NONE)
clip_init(FALSE);
// If we have a clipmethod that works now, then initialize clipboard
else if (clipmethod == CLIPMETHOD_NONE
&& method != CLIPMETHOD_NONE)
{
clip_init(TRUE);
did_warn_clipboard = FALSE;
}
// Disown clipboard if we are switching to a new method
if (clipmethod != CLIPMETHOD_NONE && method != clipmethod)
{
#if (defined(FEAT_XCLIPBOARD) || defined(FEAT_WAYLAND_CLIPBOARD)) \
&& defined(FEAT_GUI)
lose_sel_exit:
#endif
if (clip_star.owned)
clip_lose_selection(&clip_star);
if (clip_plus.owned)
clip_lose_selection(&clip_plus);
}
#if !defined(FEAT_XCLIPBOARD) && !defined(FEAT_WAYLAND_CLIPBOARD)
exit:
#endif
clipmethod = method;
#ifdef FEAT_EVAL
set_vim_var_string(VV_CLIPMETHOD, (char_u*)clipmethod_to_str(method), -1);
#endif
return NULL;
}
/*
* Call choose_clipmethod().
*/
void
ex_clipreset(exarg_T *eap UNUSED)
{
clipmethod_T prev = clipmethod;
choose_clipmethod();
if (clipmethod == CLIPMETHOD_NONE)
smsg(_("Could not find a way to access the clipboard."));
else if (clipmethod != prev)
smsg(_("Switched to clipboard method '%s'."),
clipmethod_to_str(clipmethod));
}
#endif // FEAT_CLIPBOARD

View File

@ -9,6 +9,9 @@
/* Define unless no X support found */
#undef HAVE_X11
/* Define unless no Wayland support found */
#undef HAVE_WAYLAND
/* Define when terminfo support found */
#undef TERMINFO
@ -505,6 +508,9 @@
/* Define if we have flock() */
#undef HAVE_FLOCK
/* Define if we have shm_open() */
#undef HAVE_SHM_OPEN
/* Define to inline symbol or empty */
#undef inline

View File

@ -37,6 +37,10 @@ X_PRE_LIBS = @X_PRE_LIBS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LIBS = @X_LIB@
WAYLAND_LIBS = @WAYLAND_LIBS@
WAYLAND_SRC = @WAYLAND_SRC@
WAYLAND_OBJ = @WAYLAND_OBJ@
XDIFF_OBJS_USED = @XDIFF_OBJS_USED@
LUA_LIBS = @LUA_LIBS@

View File

@ -2389,6 +2389,64 @@ AC_ARG_ENABLE(fontset,
AC_MSG_RESULT($enable_fontset)
dnl defining FEAT_XFONTSET is delayed, so that it can be disabled for no GUI
AC_MSG_CHECKING(if shm_open is available)
cppflags_save=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>], [shm_open("/test", O_CREAT, 0600);])],
AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SHM_OPEN),
AC_MSG_RESULT(no))
CPPFLAGS=$cppflags_save
AC_MSG_CHECKING(--with-wayland argument)
AC_ARG_WITH(wayland,
[ --with-wayland Include support for the Wayland protocol.])
test -z "$with_wayland" && with_wayland=yes
if test "$with_wayland" = yes; then
AC_MSG_RESULT(yes)
AC_MSG_CHECKING(if wayland client header files can be found)
cppflags_save=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <wayland-client.h>], )],
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no); no_wl=yes)
CPPFLAGS=$cppflags_save
if test "$no_wl" = yes; then
with_wayland=no
else
AC_CHECK_LIB(wayland-client, wl_display_connect,[no_wl=no])
if test "$no_wl" = no; then
AC_DEFINE(HAVE_WAYLAND)
WAYLAND_LIBS="-lwayland-client";
AC_SUBST(WAYLAND_LIBS)
WAYLAND_SRC=" \
auto/wayland/wlr-data-control-unstable-v1.c \
auto/wayland/ext-data-control-v1.c \
auto/wayland/xdg-shell.c \
auto/wayland/primary-selection-unstable-v1.c \
wayland.c"
AC_SUBST(WAYLAND_SRC)
WAYLAND_OBJ=" \
objects/wlr-data-control-unstable-v1.o \
objects/ext-data-control-v1.o \
objects/xdg-shell.o \
objects/primary-selection-unstable-v1.o \
objects/wayland.o"
AC_SUBST(WAYLAND_OBJ)
else
with_wayland=no
fi
fi
else
AC_MSG_RESULT(no)
fi
test -z "$with_x" && with_x=yes
test "${enable_gui-yes}" != no -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" && with_x=yes
if test "$with_x" = no; then

View File

@ -3732,3 +3732,7 @@ EXTERN char e_cannot_switch_to_a_closing_buffer[]
INIT(= N_("E1546: Cannot switch to a closing buffer"));
EXTERN char e_cannot_not_support_redrawtabpanel[]
INIT(= N_("E1547: This version of Vim does support :redrawtabpanel"));
#ifdef FEAT_WAYLAND
EXTERN char e_wayland_connection_unavailable[]
INIT(= N_("E1548: Wayland connection is unavailable"));
#endif

View File

@ -7489,7 +7489,8 @@ f_has(typval_T *argvars, typval_T *rettv)
#endif
},
{"unnamedplus",
#if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
#if defined(FEAT_CLIPBOARD) && (defined(FEAT_X11) \
|| defined(FEAT_WAYLAND_CLIPBOARD))
1
#else
0
@ -7526,6 +7527,20 @@ f_has(typval_T *argvars, typval_T *rettv)
1
#else
0
#endif
},
{"wayland",
#ifdef FEAT_WAYLAND
1
#else
0
#endif
},
{"wayland_clipboard",
#ifdef FEAT_WAYLAND_CLIPBOARD
1
#else
0
#endif
},
{"wildignore", 1},

View File

@ -163,6 +163,8 @@ static struct vimvar
{VV_NAME("t_enumvalue", VAR_NUMBER), NULL, VV_RO},
{VV_NAME("stacktrace", VAR_LIST), &t_list_dict_any, VV_RO},
{VV_NAME("t_tuple", VAR_NUMBER), NULL, VV_RO},
{VV_NAME("wayland_display", VAR_STRING), NULL, VV_RO},
{VV_NAME("clipmethod", VAR_STRING), NULL, VV_RO},
};
// shorthand

View File

@ -8,29 +8,29 @@ static const unsigned short cmdidxs1[26] =
/* a */ 0,
/* b */ 21,
/* c */ 45,
/* d */ 112,
/* e */ 138,
/* f */ 167,
/* g */ 184,
/* h */ 190,
/* i */ 200,
/* j */ 221,
/* k */ 223,
/* l */ 228,
/* m */ 291,
/* n */ 309,
/* o */ 329,
/* p */ 341,
/* q */ 382,
/* r */ 385,
/* s */ 406,
/* t */ 476,
/* u */ 523,
/* v */ 535,
/* w */ 556,
/* x */ 570,
/* y */ 580,
/* z */ 581
/* d */ 113,
/* e */ 139,
/* f */ 168,
/* g */ 185,
/* h */ 191,
/* i */ 201,
/* j */ 222,
/* k */ 224,
/* l */ 229,
/* m */ 292,
/* n */ 310,
/* o */ 330,
/* p */ 342,
/* q */ 383,
/* r */ 386,
/* s */ 407,
/* t */ 477,
/* u */ 524,
/* v */ 536,
/* w */ 557,
/* x */ 572,
/* y */ 582,
/* z */ 583
};
/*
@ -43,7 +43,7 @@ static const unsigned char cmdidxs2[26][26] =
{ /* a b c d e f g h i j k l m n o p q r s t u v w x y z */
/* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, 8, 17, 0, 18, 0, 0, 0, 0, 0 },
/* b */ { 2, 0, 0, 5, 6, 8, 0, 0, 0, 0, 0, 9, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 23, 0, 0, 0 },
/* c */ { 3, 12, 16, 18, 20, 22, 25, 0, 0, 0, 0, 33, 38, 41, 47, 57, 59, 60, 61, 0, 63, 0, 66, 0, 0, 0 },
/* c */ { 3, 12, 16, 18, 20, 22, 25, 0, 0, 0, 0, 33, 39, 42, 48, 58, 60, 61, 62, 0, 64, 0, 67, 0, 0, 0 },
/* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 9, 19, 0, 20, 0, 0, 21, 0, 0, 23, 24, 0, 0, 0, 0, 0, 0, 0 },
/* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 9, 11, 12, 0, 0, 0, 0, 0, 0, 0, 23, 0, 24, 0, 0 },
/* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0 },
@ -63,10 +63,10 @@ static const unsigned char cmdidxs2[26][26] =
/* t */ { 2, 0, 19, 0, 24, 26, 0, 27, 0, 29, 0, 30, 34, 37, 39, 40, 0, 41, 43, 0, 44, 0, 0, 0, 46, 0 },
/* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* v */ { 1, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 12, 15, 0, 0, 0, 0, 18, 0, 19, 0, 0, 0, 0, 0 },
/* w */ { 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 12, 13, 0, 0, 0, 0 },
/* w */ { 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 8, 0, 9, 0, 10, 11, 0, 0, 0, 13, 14, 0, 0, 0, 0 },
/* x */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0 },
/* y */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
static const int command_count = 598;
static const int command_count = 600;

View File

@ -350,6 +350,9 @@ EXCMD(CMD_checktime, "checktime", ex_checktime,
EXCMD(CMD_chistory, "chistory", qf_history,
EX_RANGE|EX_COUNT|EX_TRLBAR,
ADDR_UNSIGNED),
EXCMD(CMD_clipreset, "clipreset", ex_clipreset,
EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
ADDR_NONE),
EXCMD(CMD_clist, "clist", qf_list,
EX_BANG|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
ADDR_NONE),
@ -1808,6 +1811,9 @@ EXCMD(CMD_windo, "windo", ex_listdo,
EXCMD(CMD_winpos, "winpos", ex_winpos,
EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
ADDR_NONE),
EXCMD(CMD_wlrestore, "wlrestore", ex_wlrestore,
EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_BANG,
ADDR_NONE),
EXCMD(CMD_wnext, "wnext", ex_wnext,
EX_RANGE|EX_BANG|EX_FILE1|EX_ARGOPT|EX_TRLBAR,
ADDR_OTHER),

View File

@ -373,6 +373,12 @@ static void ex_folddo(exarg_T *eap);
#if !defined(FEAT_X11) || !defined(FEAT_XCLIPBOARD)
# define ex_xrestore ex_ni
#endif
#if !defined(FEAT_WAYLAND)
# define ex_wlrestore ex_ni
#endif
#if !defined(FEAT_CLIPBOARD)
# define ex_clipreset ex_ni
#endif
#if !defined(FEAT_PROP_POPUP)
# define ex_popupclear ex_ni
#endif

View File

@ -812,6 +812,14 @@
# define WANT_X11
#endif
/*
* +wayland Unix only. Include code for the wayland protocol,
* only works if HAVE_WAYLAND is defined.
*/
#if defined(FEAT_NORMAL) && defined(UNIX)
# define WANT_WAYLAND
#endif
/*
* XSMP - X11 Session Management Protocol
* It may be preferred to disable this if the GUI supports it (e.g.,
@ -912,6 +920,14 @@
# endif
#endif
#if defined(FEAT_NORMAL) && defined(UNIX) \
&& defined(HAVE_WAYLAND) && defined(WANT_WAYLAND)
# define FEAT_WAYLAND_CLIPBOARD
# ifndef FEAT_CLIPBOARD
# define FEAT_CLIPBOARD
# endif
#endif
/*
* +dnd Drag'n'drop support. Always used for the GTK+ GUI.
*/

View File

@ -971,9 +971,9 @@ EXTERN int gui_win_y INIT(= -1);
#endif
#ifdef FEAT_CLIPBOARD
EXTERN Clipboard_T clip_star; // PRIMARY selection in X11
# ifdef FEAT_X11
EXTERN Clipboard_T clip_plus; // CLIPBOARD selection in X11
EXTERN Clipboard_T clip_star; // PRIMARY selection in X11/Wayland
# if defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD)
EXTERN Clipboard_T clip_plus; // CLIPBOARD selection in X11/Wayland
# else
# define clip_plus clip_star // there is only one clipboard
# define ONE_CLIPBOARD
@ -2069,3 +2069,23 @@ EXTERN char_u showcmd_buf[SHOWCMD_BUFLEN];
#ifdef FEAT_TERMGUICOLORS
EXTERN int p_tgc_set INIT(= FALSE);
#endif
// If we've already warned about missing/unavailable clipboard
EXTERN int did_warn_clipboard INIT(= FALSE);
#ifdef FEAT_CLIPBOARD
EXTERN clipmethod_T clipmethod INIT(= CLIPMETHOD_NONE);
#endif
#ifdef FEAT_WAYLAND
// Don't connect to wayland compositor if TRUE
EXTERN int wayland_no_connect INIT(= FALSE);
// Wayland display name (ex. wayland-0). Can be NULL
EXTERN char *wayland_display_name INIT(= NULL);
// Wayland display file descriptor; set by wayland_init_client()
EXTERN int wayland_display_fd;
#endif

View File

@ -146,6 +146,9 @@ gui_start(char_u *arg UNUSED)
emsg(msg);
#endif
}
else
// Reset clipmethod to CLIPMETHOD_NONE
choose_clipmethod();
vim_free(old_term);

View File

@ -449,7 +449,7 @@ main
#endif // NO_VIM_MAIN
#endif // PROTO
#if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
#if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD) && defined(FEAT_CLIPBOARD)
/*
* Restore the state after a fatal X error.
*/
@ -475,6 +475,7 @@ x_restore_state(void)
starttermcap();
scroll_start();
redraw_later_clear();
choose_clipmethod();
}
#endif
@ -667,7 +668,7 @@ vim_main2(void)
# endif
{
setup_term_clip();
TIME_MSG("setup clipboard");
TIME_MSG("setup x11 clipboard");
}
#endif
@ -676,6 +677,27 @@ vim_main2(void)
prepare_server(&params);
#endif
#ifdef FEAT_WAYLAND
# ifdef FEAT_GUI
if (!gui.in_use)
# endif
{
if (wayland_init_client(wayland_display_name) == OK)
{
TIME_MSG("connected to wayland display");
# ifdef FEAT_WAYLAND_CLIPBOARD
if (wayland_cb_init((char*)p_wse) == OK)
TIME_MSG("setup wayland clipboard");
}
# endif
}
#endif
#ifdef FEAT_CLIPBOARD
choose_clipmethod();
#endif
/*
* If "-" argument given: Read file from stdin.
* Do this before starting Raw mode, because it may change things that the
@ -2458,6 +2480,11 @@ command_line_scan(mparm_T *parmp)
case 'X': // "-X" don't connect to X server
#if (defined(UNIX) || defined(VMS)) && defined(FEAT_X11)
x_no_connect = TRUE;
#endif
break;
case 'Y': // "-Y" don't connect to wayland compositor
#if defined(FEAT_WAYLAND)
wayland_no_connect = TRUE;
#endif
break;
@ -3665,6 +3692,9 @@ usage(void)
# endif
main_msg(_("-X\t\t\tDo not connect to X server"));
#endif
#if defined(FEAT_WAYLAND)
main_msg(_("-Y\t\t\tDo not connect to wayland compositor"));
#endif
#ifdef FEAT_CLIENTSERVER
main_msg(_("--remote <files>\tEdit <files> in a Vim server if possible"));
main_msg(_("--remote-silent <files> Same, don't complain if there is no server"));

View File

@ -71,8 +71,6 @@ static int msg_wait = 0;
static FILE *verbose_fd = NULL;
static int verbose_did_open = FALSE;
static int did_warn_clipboard = FALSE;
/*
* When writing messages to the screen, there are many different situations.
* A number of variables is used to remember the current state:

View File

@ -4723,6 +4723,36 @@ did_set_winwidth(optset_T *args UNUSED)
return errmsg;
}
#ifdef FEAT_WAYLAND_CLIPBOARD
/*
* Process the new 'wlsteal' option value.
*/
char *
did_set_wlsteal(optset_T *args UNUSED)
{
wayland_cb_reload();
return NULL;
}
#endif
#ifdef FEAT_WAYLAND
/*
* Process the new 'wltimeoutlen' option value.
*/
char *
did_set_wltimeoutlen(optset_T *args)
{
if (p_wtm < 0)
{
p_wtm = args->os_oldval.number;
return e_argument_must_be_positive;
}
return NULL;
}
#endif
/*
* Process the updated 'wrap' option value.
*/

View File

@ -504,6 +504,7 @@ EXTERN char_u *p_cedit; // 'cedit'
EXTERN long p_cwh; // 'cmdwinheight'
#ifdef FEAT_CLIPBOARD
EXTERN char_u *p_cb; // 'clipboard'
EXTERN char_u *p_cpm; // 'clipmethod'
#endif
EXTERN long p_ch; // 'cmdheight'
#ifdef FEAT_FOLDING
@ -1132,6 +1133,13 @@ EXTERN long p_wh; // 'winheight'
EXTERN long p_wmh; // 'winminheight'
EXTERN long p_wmw; // 'winminwidth'
EXTERN long p_wiw; // 'winwidth'
#ifdef FEAT_WAYLAND
EXTERN char_u *p_wse; // 'wlseat'
# ifdef FEAT_WAYLAND_CLIPBOARD
EXTERN int p_wst; // 'wlsteal'
# endif
EXTERN long p_wtm; // 'wltimeoutlen'
#endif
#if defined(MSWIN) && defined(FEAT_TERMINAL)
EXTERN char_u *p_winptydll; // 'winptydll'
#endif

View File

@ -608,7 +608,7 @@ static struct vimoption options[] =
{"clipboard", "cb", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
#ifdef FEAT_CLIPBOARD
(char_u *)&p_cb, PV_NONE, did_set_clipboard, expand_set_clipboard,
# ifdef FEAT_XCLIPBOARD
# if defined(FEAT_XCLIPBOARD) || defined(FEAT_WAYLAND_CLIPBOARD)
{(char_u *)"autoselect,exclude:cons\\|linux",
(char_u *)0L}
# else
@ -617,6 +617,21 @@ static struct vimoption options[] =
#else
(char_u *)NULL, PV_NONE, NULL, NULL,
{(char_u *)"", (char_u *)0L}
#endif
SCTX_INIT},
{"clipmethod", "cpm", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
#ifdef FEAT_CLIPBOARD
(char_u *)&p_cpm, PV_NONE, did_set_clipmethod, expand_set_clipmethod,
# ifdef UNIX
{(char_u *)"wayland,x11", (char_u *)0L}
# elif defined(VMS)
{(char_u *)"x11", (char_u *)0L}
# else
{(char_u *)"", (char_u *)0L}
# endif
#else
(char_u *)NULL, PV_NONE, NULL, NULL,
{(char_u *)NULL, (char_u *)0L}
#endif
SCTX_INIT},
{"cmdheight", "ch", P_NUM|P_VI_DEF|P_RALL,
@ -2960,6 +2975,33 @@ static struct vimoption options[] =
{"winwidth", "wiw", P_NUM|P_VI_DEF,
(char_u *)&p_wiw, PV_NONE, did_set_winwidth, NULL,
{(char_u *)20L, (char_u *)0L} SCTX_INIT},
{"wlseat", "wse", P_STRING|P_VI_DEF,
#ifdef FEAT_WAYLAND
(char_u *)&p_wse, PV_NONE, did_set_wlseat, NULL,
{(char_u *)"", (char_u *)0L}
#else
(char_u *)NULL, PV_NONE, NULL, NULL,
{(char_u *)NULL, (char_u *)0L}
#endif
SCTX_INIT},
{"wlsteal", "wst", P_BOOL|P_VI_DEF,
#ifdef FEAT_WAYLAND_CLIPBOARD
(char_u *)&p_wst, PV_NONE, did_set_wlsteal, NULL,
{(char_u *)FALSE, (char_u *)0L}
#else
(char_u *)NULL, PV_NONE, NULL, NULL,
{(char_u *)NULL, (char_u *)0L}
#endif
SCTX_INIT},
{"wltimeoutlen", "wtm", P_NUM|P_VI_DEF,
#ifdef FEAT_WAYLAND
(char_u *)&p_wtm, PV_NONE, did_set_wltimeoutlen, NULL,
{(char_u *)500L, (char_u *)0L}
#else
(char_u *)NULL, PV_NONE, NULL, NULL,
{(char_u *)NULL, (char_u *)0L}
#endif
SCTX_INIT},
{"wrap", NULL, P_BOOL|P_VI_DEF|P_RWIN,
(char_u *)VAR_WIN, PV_WRAP, did_set_wrap, NULL,
{(char_u *)TRUE, (char_u *)0L} SCTX_INIT},

View File

@ -44,6 +44,8 @@ static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
#ifdef FEAT_CLIPBOARD
// Note: Keep this in sync with did_set_clipboard()
static char *(p_cb_values[]) = {"unnamed", "unnamedplus", "autoselect", "autoselectplus", "autoselectml", "html", "exclude:", NULL};
// Note: Keep this in sync with get_clipmethod()
static char *(p_cpm_values[]) = {"wayland", "x11", NULL};
#endif
#ifdef FEAT_CRYPT
static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2",
@ -1384,6 +1386,23 @@ expand_set_clipboard(optexpand_T *args, int *numMatches, char_u ***matches)
numMatches,
matches);
}
char *
did_set_clipmethod(optset_T *args UNUSED)
{
return choose_clipmethod();
}
int
expand_set_clipmethod(optexpand_T *args, int *numMatches, char_u ***matches)
{
return expand_set_opt_string(
args,
p_cpm_values,
ARRAY_LENGTH(p_cpm_values) - 1,
numMatches,
matches);
}
#endif
/*
@ -3624,6 +3643,21 @@ expand_set_scrollopt(optexpand_T *args, int *numMatches, char_u ***matches)
matches);
}
/*
* The 'wlseat' option is changed
*/
char *
did_set_wlseat(optset_T *args UNUSED)
{
#ifdef FEAT_WAYLAND_CLIPBOARD
// If there isn't any seat named 'wlseat', then let the wayland clipboard be
// unavailable. Ignore errors returned.
wayland_cb_reload();
#endif
return NULL;
}
/*
* The 'selection' option is changed.
*/

View File

@ -26,6 +26,12 @@
#include "os_unixx.h" // unix includes for os_unix.c only
#ifdef HAVE_SHM_OPEN
# include <sys/mman.h>
# include <sys/stat.h>
# include <fcntl.h>
#endif
#ifdef USE_XSMP
# include <X11/SM/SMlib.h>
#endif
@ -135,7 +141,6 @@ static void sig_sysmouse SIGPROTOARG;
# include <X11/StringDefs.h>
static Widget xterm_Shell = (Widget)0;
static void clip_update(void);
static void xterm_update(void);
# endif
Window x11_window = 0;
@ -1303,33 +1308,43 @@ sigcont_handler SIGDEFARG(sigarg)
}
#endif
#if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
# ifdef USE_SYSTEM
#if defined(FEAT_CLIPBOARD)
# if defined(USE_SYSTEM) && (defined(FEAT_X11) \
|| defined(FEAT_WAYLAND_CLIPBOARD))
static void *clip_star_save = NULL;
static void *clip_plus_save = NULL;
# endif
# if defined(FEAT_CLIPBOARD) && (defined(FEAT_X11) \
|| defined(FEAT_WAYLAND_CLIPBOARD))
/*
* Called when Vim is going to sleep or execute a shell command.
* We can't respond to requests for the X selections. Lose them, otherwise
* other applications will hang. But first copy the text to cut buffer 0.
* We can't respond to requests for the X or wayland selections.
* Lose them, otherwise other applications will hang. But first
* copy the text to cut buffer 0 (for X11). Wayland users must have
* a clipboard manager to replicate such behaviour.
*/
static void
loose_clipboard(void)
{
if (clip_star.owned || clip_plus.owned)
{
#ifdef FEAT_X11
x11_export_final_selection();
#endif
if (clip_star.owned)
clip_lose_selection(&clip_star);
if (clip_plus.owned)
clip_lose_selection(&clip_plus);
#ifdef FEAT_X11
if (x11_display != NULL)
XFlush(x11_display);
#endif
}
}
#endif
# ifdef USE_SYSTEM
# if defined(USE_SYSTEM) && (defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD))
/*
* Save clipboard text to restore later.
*/
@ -1343,7 +1358,7 @@ save_clipboard(void)
}
/*
* Restore clipboard text if no one own the X selection.
* Restore clipboard text if no one own the X/Wayland selection.
*/
static void
restore_clipboard(void)
@ -1385,7 +1400,8 @@ mch_suspend(void)
settmode(TMODE_COOK);
out_flush(); // needed to disable mouse on some systems
# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
# if defined(FEAT_CLIPBOARD) && (defined(FEAT_X11) \
|| defined(FEAT_WAYLAND_CLIPBOARD))
loose_clipboard();
# endif
# if defined(SIGCONT)
@ -1810,7 +1826,7 @@ x_IOerror_handler(Display *dpy UNUSED)
* (e.g. through tmux).
*/
static void
may_restore_clipboard(void)
may_restore_x11_clipboard(void)
{
// No point in restoring the connecting if we are exiting or dying.
if (!exiting && !v_dying && xterm_dpy_retry_count > 0)
@ -1844,13 +1860,14 @@ ex_xrestore(exarg_T *eap)
xterm_display = (char *)vim_strnsave(eap->arg, arglen);
xterm_display_allocated = TRUE;
}
smsg(_("restoring display %s"), xterm_display == NULL
smsg(_("restoring X11 display %s"), xterm_display == NULL
? (char *)mch_getenv((char_u *)"DISPLAY") : xterm_display);
clear_xterm_clip();
x11_window = 0;
xterm_dpy_retry_count = 5; // Try reconnecting five times
may_restore_clipboard();
may_restore_x11_clipboard();
choose_clipmethod();
}
#endif
@ -4836,8 +4853,11 @@ mch_call_shell_system(
if (options & SHELL_COOKED)
settmode(TMODE_COOK); // set to normal mode
# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
# if defined(FEAT_CLIPBOARD) && (defined(FEAT_X11) \
|| defined(FEAT_WAYLAND_CLIPBOARD))
# if defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD)
save_clipboard();
#endif
loose_clipboard();
# endif
@ -4899,7 +4919,8 @@ mch_call_shell_system(
settmode(TMODE_RAW); // set to raw mode
}
resettitle();
# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
# if defined(FEAT_CLIPBOARD) && (defined(FEAT_X11) \
|| defined(FEAT_WAYLAND_CLIPBOARD))
restore_clipboard();
# endif
return x;
@ -5168,7 +5189,7 @@ mch_call_shell_fork(
* different on different machines. This may cause a warning
* message with strict compilers, don't worry about it.
* Call _exit() instead of exit() to avoid closing the connection
* to the X server (esp. with GTK, which uses atexit()).
* to the X/Wayland server (esp. with GTK, which uses atexit()).
*/
execvp(argv[0], argv);
_exit(EXEC_FAILED); // exec failed, return failure code
@ -5586,6 +5607,11 @@ mch_call_shell_fork(
// Handle any X events, e.g. serving the clipboard.
clip_update();
# endif
#ifdef FEAT_WAYLAND
// Handle wayland events such as sending data as the source
// client.
wayland_client_update();
#endif
}
finished:
p_more = p_more_save;
@ -5612,7 +5638,7 @@ finished:
close(toshell_fd);
close(fromshell_fd);
}
# if defined(FEAT_XCLIPBOARD) && defined(FEAT_X11)
# if (defined(FEAT_XCLIPBOARD) && defined(FEAT_X11)) || defined(FEAT_WAYLAND)
else
{
long delay_msec = 1;
@ -5623,8 +5649,8 @@ finished:
out_str_t_TE();
/*
* Similar to the loop above, but only handle X events, no
* I/O.
* Similar to the loop above, but only handle X and Wayland
* events, no I/O.
*/
for (;;)
{
@ -5651,8 +5677,15 @@ finished:
break;
}
#if defined(FEAT_XCLIPBOARD) && defined(FEAT_X11)
// Handle any X events, e.g. serving the clipboard.
clip_update();
#endif
#ifdef FEAT_WAYLAND
// Handle wayland events such as sending data as the source
// client.
wayland_client_update();
#endif
// Wait for 1 to 10 msec. 1 is faster but gives the child
// less time, gradually wait longer.
@ -6505,8 +6538,11 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted)
#endif
#ifndef HAVE_SELECT
// each channel may use in, out and err
struct pollfd fds[6 + 3 * MAX_OPEN_CHANNELS];
struct pollfd fds[7 + 3 * MAX_OPEN_CHANNELS];
int nfd;
# ifdef FEAT_WAYLAND_CLIPBOARD
int wayland_idx = -1;
# endif
# ifdef FEAT_XCLIPBOARD
int xterm_idx = -1;
# endif
@ -6530,6 +6566,15 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted)
fds[0].events = POLLIN;
nfd = 1;
# ifdef FEAT_WAYLAND_CLIPBOARD
if (wayland_may_restore_connection())
{
wayland_idx = nfd;
fds[nfd].fd = vwl_display_fd;
fds[nfd].events = POLLIN;
nfd++;
}
# endif
# ifdef FEAT_XCLIPBOARD
may_restore_clipboard();
if (xterm_Shell != (Widget)0)
@ -6558,9 +6603,9 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted)
nfd++;
}
# endif
#ifdef FEAT_JOB_CHANNEL
# ifdef FEAT_JOB_CHANNEL
nfd = channel_poll_setup(nfd, &fds, &towait);
#endif
# endif
if (interrupted != NULL)
*interrupted = FALSE;
@ -6576,6 +6621,15 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted)
finished = FALSE;
# endif
# ifdef FEAT_WAYLAND_CLIPBOARD
// Technically we should first call wl_display_prepare_read() before
// polling the fd, then read and dispatch after we poll. However that is
// only needed for multi threaded environments to prevent deadlocks so
// we are fine.
if (fds[wayland_idx].revents & POLLIN)
wayland_client_update();
# endif
# ifdef FEAT_XCLIPBOARD
if (xterm_Shell != (Widget)0 && (fds[xterm_idx].revents & POLLIN))
{
@ -6608,11 +6662,11 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted)
finished = FALSE; // Try again
}
# endif
#ifdef FEAT_JOB_CHANNEL
# ifdef FEAT_JOB_CHANNEL
// also call when ret == 0, we may be polling a keep-open channel
if (ret >= 0)
channel_poll_check(ret, &fds);
#endif
# endif
#else // HAVE_SELECT
@ -6656,8 +6710,19 @@ select_eintr:
# endif
maxfd = fd;
# ifdef FEAT_WAYLAND_CLIPBOARD
if (wayland_may_restore_connection())
{
FD_SET(wayland_display_fd, &rfds);
if (maxfd < wayland_display_fd)
maxfd = wayland_display_fd;
}
# endif
# ifdef FEAT_XCLIPBOARD
may_restore_clipboard();
may_restore_x11_clipboard();
if (xterm_Shell != (Widget)0)
{
FD_SET(ConnectionNumber(xterm_dpy), &rfds);
@ -6745,6 +6810,15 @@ select_eintr:
finished = FALSE;
# endif
# ifdef FEAT_WAYLAND_CLIPBOARD
// Technically we should first call wl_display_prepare_read() before
// polling the fd, then read and dispatch after we poll. However that is
// only needed for multi threaded environments to prevent deadlocks so
// we are fine.
if (ret > 0 && FD_ISSET(wayland_display_fd, &rfds))
wayland_client_update();
# endif
# ifdef FEAT_XCLIPBOARD
if (ret > 0 && xterm_Shell != (Widget)0
&& FD_ISSET(ConnectionNumber(xterm_dpy), &rfds))
@ -6789,11 +6863,11 @@ select_eintr:
}
}
# endif
#ifdef FEAT_JOB_CHANNEL
# ifdef FEAT_JOB_CHANNEL
// also call when ret == 0, we may be polling a keep-open channel
if (ret >= 0)
(void)channel_select_check(ret, &rfds, &wfds);
#endif
# endif
#endif // HAVE_SELECT
@ -8295,7 +8369,7 @@ clip_update(void)
* nothing in the X event queue (& no timers pending), then we return
* immediately.
*/
static void
void
xterm_update(void)
{
XEvent event;
@ -8846,3 +8920,33 @@ start_timeout(long msec)
}
# endif // PROF_NSEC
#endif // FEAT_RELTIME
/*
* Create an anonymous/temporary file/object and return its file descriptor.
* Returns -1 on error.
*/
int
mch_create_anon_file(void)
{
int fd = -1;
#ifdef HAVE_SHM_OPEN
const char template[] = "/vimXXXXXX";
for (int i = 0; i < 100; i++)
{
mch_get_random((char_u*)template + 4, 6);
errno = 0;
fd = shm_open(template, O_CREAT | O_RDWR | O_EXCL, 0600);
if (fd >= 0 || errno != EEXIST)
break; }
// Remove object name from namespace
shm_unlink(template);
#endif
if (fd == -1)
// Last resort
fd = fileno(tmpfile());
return fd;
}

View File

@ -177,6 +177,9 @@ void mbyte_im_set_active(int active_arg);
# include "profiler.pro"
# endif
# include "quickfix.pro"
#ifdef FEAT_WAYLAND
# include "wayland.pro"
#endif
# include "regexp.pro"
# include "register.pro"
# include "scriptfile.pro"

View File

@ -35,4 +35,10 @@ int clip_convert_selection(char_u **str, long_u *len, Clipboard_T *cbd);
int may_get_selection(int regname);
void may_set_selection(void);
void adjust_clip_reg(int *rp);
void clip_wl_request_selection(Clipboard_T *cbd);
int clip_wl_own_selection(Clipboard_T *cbd);
void clip_wl_lose_selection(Clipboard_T *cbd);
void clip_wl_set_selection(Clipboard_T *cbd);
char *choose_clipmethod(void);
void ex_clipreset(exarg_T *eap);
/* vim: set ft=c : */

View File

@ -88,6 +88,8 @@ char *did_set_winheight_helpheight(optset_T *args);
char *did_set_winminheight(optset_T *args);
char *did_set_winminwidth(optset_T *args);
char *did_set_winwidth(optset_T *args);
char *did_set_wlsteal(optset_T *args);
char *did_set_wltimeoutlen(optset_T *args);
char *did_set_wrap(optset_T *args);
char *did_set_xhistory(optset_T *args);
void check_redraw(long_u flags);

View File

@ -34,6 +34,8 @@ int expand_set_buftype(optexpand_T *args, int *numMatches, char_u ***matches);
char *did_set_casemap(optset_T *args);
int expand_set_casemap(optexpand_T *args, int *numMatches, char_u ***matches);
int expand_set_clipboard(optexpand_T *args, int *numMatches, char_u ***matches);
char * did_set_clipmethod(optset_T *args);
int expand_set_clipmethod(optexpand_T *args, int *numMatches, char_u ***matches);
char *did_set_chars_option(optset_T *args);
int expand_set_chars_option(optexpand_T *args, int *numMatches, char_u ***matches);
char *did_set_cinoptions(optset_T *args);
@ -138,6 +140,7 @@ int expand_set_rightleftcmd(optexpand_T *args, int *numMatches, char_u ***matche
char *did_set_rulerformat(optset_T *args);
char *did_set_scrollopt(optset_T *args);
int expand_set_scrollopt(optexpand_T *args, int *numMatches, char_u ***matches);
char *did_set_wlseat(optset_T *args);
char *did_set_selection(optset_T *args);
int expand_set_selection(optexpand_T *args, int *numMatches, char_u ***matches);
char *did_set_selectmode(optset_T *args);

View File

@ -82,6 +82,7 @@ void setup_term_clip(void);
void start_xterm_trace(int button);
void stop_xterm_trace(void);
void clear_xterm_clip(void);
void xterm_update(void);
int clip_xterm_own_selection(Clipboard_T *cbd);
void clip_xterm_lose_selection(Clipboard_T *cbd);
void clip_xterm_request_selection(Clipboard_T *cbd);
@ -92,4 +93,5 @@ void xsmp_close(void);
void stop_timeout(void);
volatile sig_atomic_t *start_timeout(long msec);
void delete_timer(void);
int mch_create_anon_file(void);
/* vim: set ft=c : */

17
src/proto/wayland.pro Normal file
View File

@ -0,0 +1,17 @@
/* wayland.c */
int wayland_init_client(const char *display);
void wayland_uninit_client(void);
int wayland_client_is_connected(int quiet);
int wayland_client_update(void);
int wayland_cb_init(const char *seat);
void wayland_cb_uninit(void);
garray_T * wayland_cb_get_mime_types(wayland_selection_T selection);
int wayland_cb_receive_data(const char *mime_type, wayland_selection_T selection);
int wayland_cb_own_selection( wayland_cb_send_data_func_T send_cb, wayland_cb_selection_cancelled_func_T cancelled_cb, const char **mime_types, int len, wayland_selection_T selection);
void wayland_cb_lose_selection(wayland_selection_T selection);
int wayland_cb_selection_is_owned(wayland_selection_T selection);
int wayland_cb_is_ready(void);
int wayland_cb_reload(void);
int wayland_may_restore_connection(void);
void ex_wlrestore(exarg_T *eap);
/* vim: set ft=c : */

View File

@ -20,7 +20,8 @@
* 10..35 = registers 'a' to 'z' ('A' to 'Z' for appending)
* 36 = delete register '-'
* 37 = Selection register '*'. Only if FEAT_CLIPBOARD defined
* 38 = Clipboard register '+'. Only if FEAT_CLIPBOARD and FEAT_X11 defined
* 38 = Clipboard register '+'. Only if FEAT_CLIPBOARD and FEAT_X11
* or FEAT_WAYLAND_CLIPBOARD defined
*/
static yankreg_T y_regs[NUM_REGISTERS];
@ -1170,7 +1171,7 @@ op_yank(oparg_T *oap, int deleting, int mess)
linenr_T yankendlnum = oap->end.lnum;
char_u *pnew;
struct block_def bd;
#if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
#if defined(FEAT_CLIPBOARD) && (defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD))
int did_star = FALSE;
#endif
@ -1396,12 +1397,12 @@ op_yank(oparg_T *oap, int deleting, int mess)
clip_own_selection(&clip_star);
clip_gen_set_selection(&clip_star);
# ifdef FEAT_X11
# if defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD)
did_star = TRUE;
# endif
}
# ifdef FEAT_X11
# if defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD)
// If we were yanking to the '+' register, send result to selection.
// Also copy to the '*' register, in case auto-select is off. But not when
// 'clipboard' has "unnamedplus" and not "unnamed"; and not when

View File

@ -4831,7 +4831,7 @@ typedef enum {
#define DELETION_REGISTER 36
#ifdef FEAT_CLIPBOARD
# define STAR_REGISTER 37
# ifdef FEAT_X11
# if defined(FEAT_X11) || defined(FEAT_WAYLAND)
# define PLUS_REGISTER 38
# else
# define PLUS_REGISTER STAR_REGISTER // there is only one
@ -5187,3 +5187,23 @@ struct cellsize {
int cs_ypixel;
};
#endif
#ifdef FEAT_WAYLAND
// Wayland selections
typedef enum {
WAYLAND_SELECTION_NONE = 0x0,
WAYLAND_SELECTION_REGULAR = 0x1,
WAYLAND_SELECTION_PRIMARY = 0x2,
} wayland_selection_T;
// Callback when another client wants us to send data to them
typedef void (*wayland_cb_send_data_func_T)(
const char *mime_type,
int fd,
wayland_selection_T type);
// Callback when the selection is lost (data source object overwritten)
typedef void (*wayland_cb_selection_cancelled_func_T)(wayland_selection_T type);
#endif // FEAT_WAYLAND

View File

@ -102,6 +102,7 @@ NEW_TESTS = \
test_cindent \
test_cjk_linebreak \
test_clientserver \
test_clipmethod \
test_close_count \
test_cmd_lists \
test_cmdline \
@ -344,6 +345,7 @@ NEW_TESTS = \
test_vimscript \
test_virtualedit \
test_visual \
test_wayland \
test_winbar \
test_winbuf_close \
test_window_cmd \
@ -388,6 +390,7 @@ NEW_TESTS_RES = \
test_cindent.res \
test_cjk_linebreak.res \
test_clientserver.res \
test_clipmethod.res \
test_close_count.res \
test_cmd_lists.res \
test_cmdline.res \
@ -596,6 +599,7 @@ NEW_TESTS_RES = \
test_vimscript.res \
test_virtualedit.res \
test_visual.res \
test_wayland.res \
test_winbar.res \
test_winbuf_close.res \
test_window_cmd.res \

View File

@ -115,6 +115,7 @@ let test_values = {
\ 'winminheight': [[0, 1], [-1]],
\ 'winminwidth': [[0, 1, 10], [-1]],
\ 'winwidth': [[1, 10, 999], [-1, 0]],
\ 'wltimeoutlen': [[1, 10, 999],[-1]],
\
"\ string options
\ 'ambiwidth': [['', 'single', 'double'], ['xxx']],
@ -148,6 +149,7 @@ let test_values = {
\ 'autoselectplus', 'autoselectml', 'html', 'exclude:vimdisplay',
\ 'autoselect,unnamed', 'unnamed,exclude:.*'],
\ ['xxx', 'exclude:\\ze*', 'exclude:\\%(']],
\ 'clipmethod': [['wayland', 'x11', 'wayland,x11', ''],['xxx', '--', 'wayland,,', ',x11']],
\ 'colorcolumn': [['', '8', '+2', '1,+1,+3'], ['xxx', '-a', '1,', '1;']],
\ 'comments': [['', 'b:#', 'b:#,:%'], ['xxx', '-']],
\ 'commentstring': [['', '/*\ %s\ */'], ['xxx']],

View File

@ -0,0 +1,169 @@
" Tests for clipmethod
source check.vim
source shared.vim
source window_manager.vim
CheckFeature clipboard_working
CheckFeature xterm_clipboard
CheckFeature wayland_clipboard
CheckUnix
" Test if no available clipmethod sets v:clipmethod to none and deinits clipboard
func Test_no_clipmethod_sets_v_clipmethod_none()
CheckNotGui
set clipmethod=
call assert_equal("none", v:clipmethod)
call assert_equal(0, has('clipboard_working'))
endfunc
" Test if method chosen is in line with clipmethod order
func Test_clipmethod_order()
CheckNotGui
set cpm=wayland,x11
let l:wayland_display = StartWaylandCompositor()
let $WAYLAND_DISPLAY = l:wayland_display
exe 'wlrestore ' .. l:wayland_display
call assert_equal("wayland", v:clipmethod)
:wlrestore 1239
clipreset
call assert_equal("x11", v:clipmethod)
:xrestore 1239
clipreset
call assert_equal("none", v:clipmethod)
call assert_equal(0, has('clipboard_working'))
exe ":wlrestore " . $WAYLAND_DISPLAY
exe ":xrestore " . $DISPLAY
clipreset
call assert_equal("wayland", v:clipmethod)
call assert_equal(1, has('clipboard_working'))
set cpm=x11
call assert_equal("x11", v:clipmethod)
set cpm=wayland
call assert_equal("wayland", v:clipmethod)
call EndWaylandCompositor(l:wayland_display)
endfunc
" Test if clipmethod is set to 'none' when gui is started
func Test_clipmethod_is_none_when_gui()
CheckCanRunGui
let lines =<< trim END
set cpm=wayland,x11
call writefile([v:clipmethod != ""], 'Cbdscript')
gui -f
call writefile([v:clipmethod], 'Cbdscript', 'a')
clipreset
call writefile([v:clipmethod], 'Cbdscript', 'a')
quit
END
call writefile(lines, 'Cbdscript', 'D')
call system($'{GetVimCommand()} -S Cbdscript')
call assert_equal(['1', 'none', 'none'], readfile('Cbdscript'))
endfunc
" Test if :clipreset switches methods when current one doesn't work
func Test_clipreset_switches()
CheckNotGui
CheckFeature clientserver
CheckXServer
CheckWaylandCompositor
let l:wayland_display = StartWaylandCompositor()
set cpm=wayland,x11
exe 'wlrestore ' .. l:wayland_display
call assert_equal(l:wayland_display, v:wayland_display)
call assert_equal("wayland", v:clipmethod)
call EndWaylandCompositor(l:wayland_display)
" wlrestore updates clipmethod as well
wlrestore!
call assert_equal("", v:wayland_display)
call assert_equal("x11", v:clipmethod)
" Do the same but kill a X11 server
" X11 error handling relies on longjmp magic, but essentially if the X server
" is killed then it will simply abandon the current commands, making the test
" hang.
" This will only happen for commands given from the command line, which
" is why we cannot just directly call Vim or use the actual Vim instance thats
" doing all the testing, since main_loop() is never executed.
" Therefore we should start a separate Vim instance and communicate with it
" remotely, so we can execute the actual testing stuff with main_loop()
" running.
let l:lines =<< trim END
set cpm=x11
source shared.vim
func Test()
clipreset
if v:clipmethod ==# 'none'
return 1
endif
return 0
endfunc
func DoIt()
call WaitFor(function('Test'))
if v:clipmethod == 'none'
call writefile(['SUCCESS'], 'Xtest')
else
call writefile(['FAIL'], 'Xtest')
endif
quitall
endfunc
END
call writefile(l:lines, 'Xtester', 'D')
let l:xdisplay = StartXServer()
let l:name = 'XVIMTEST'
let l:cmd = GetVimCommand() .. ' -S Xtester --servername ' .. l:name
let l:job = job_start(l:cmd, { 'stoponexit': 'kill', 'out_io': 'null'})
call WaitForAssert({-> assert_equal("run", job_status(l:job))})
call WaitForAssert({-> assert_match(l:name, serverlist())})
" Change x server to the one that will be killed, then block until
" v:clipmethod is none.
call remote_send(l:name, ":xrestore " .. l:xdisplay ..
\ ' | call DoIt()' .. "\<CR>")
call EndXServer(l:xdisplay)
call WaitFor({-> filereadable('Xtest')})
" For some reason readfile sometimes returns an empty list despite the file
" existing, this why WaitForAssert() is used.
call WaitForAssert({-> assert_equal(['SUCCESS'], readfile('Xtest'))}, 1000)
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -523,6 +523,13 @@ func Test_set_completion_string_values()
if exists('+clipboard')
call assert_match('unnamed', getcompletion('set clipboard=', 'cmdline')[1])
endif
if exists('+clipmethod')
if has('unix') || has('vms')
call assert_match('wayland', getcompletion('set clipmethod=', 'cmdline')[1])
else
call assert_match('wayland', getcompletion('set clipmethod=', 'cmdline')[0])
endif
endif
call assert_equal('.', getcompletion('set complete=', 'cmdline')[1])
call assert_equal('menu', getcompletion('set completeopt=', 'cmdline')[1])
call assert_equal('keyword', getcompletion('set completefuzzycollect=', 'cmdline')[0])
@ -2593,6 +2600,7 @@ func Test_string_option_revert_on_failure()
endif
if has('clipboard_working')
call add(optlist, ['clipboard', 'unnamed', 'a123'])
call add(optlist, ['clipmethod', 'wayland', 'a123'])
endif
if has('win32')
call add(optlist, ['completeslash', 'slash', 'a123'])

View File

@ -1092,20 +1092,20 @@ func Test_clipboard_regs_not_working()
endfunc
" Check for W23 with a Vim with clipboard support,
" but when the connection to the X11 server does not work
" but when there is no available clipmethod
func Test_clipboard_regs_not_working2()
CheckNotMac
CheckRunVimInTerminal
CheckFeature clipboard
let display=$DISPLAY
unlet $DISPLAY
set clipmethod=
" Run in a separate Vim instance because changing 'encoding' may cause
" trouble for later tests.
let lines =<< trim END
unlet $DISPLAY
set clipmethod=
call setline(1, 'abcdefg')
let a=execute(':norm! "+yy')
call writefile([a], 'Xclipboard_result.txt')
set clipmethod&
END
call writefile(lines, 'XTest_clipboard', 'D')
let buf = RunVimInTerminal('-S XTest_clipboard', {})
@ -1113,7 +1113,7 @@ func Test_clipboard_regs_not_working2()
call StopVimInTerminal(buf)
let result = readfile('Xclipboard_result.txt')
call assert_match("^\\nW23:", result[0])
let $DISPLAY=display
set clipmethod&
endfunc
" This caused use-after-free

View File

@ -559,7 +559,7 @@ func Test_invalid_args()
CheckUnix
CheckNotGui
for opt in ['-Y', '--does-not-exist']
for opt in ['-K', '--does-not-exist']
let out = split(system(GetVimCommand() .. ' ' .. opt), "\n")
call assert_equal(1, v:shell_error)
call assert_match('^VIM - Vi IMproved .* (.*)$', out[0])

View File

@ -0,0 +1,663 @@
source check.vim
source shared.vim
source window_manager.vim
CheckFeature wayland
CheckFeature wayland_clipboard
CheckUnix
CheckFeature job
CheckWaylandCompositor
CheckNotGui
if !executable('wl-paste') || !executable('wl-copy')
throw "Skipped: wl-clipboard is not available"
endif
" Process will be killed when the test ends
let s:global_wayland_display = StartWaylandCompositor()
let s:old_wayland_display = $WAYLAND_DISPLAY
" For some reason if $WAYLAND_DISPLAY is set in the global namespace (not in a
" function), it won't actually be set if $WAYLAND_DISPLAY was not set before
" (such as in a CI environment) ? Solution is to just set it before the code of
" every test function
func s:PreTest()
let $WAYLAND_DISPLAY=s:global_wayland_display
exe 'wlrestore ' .. $WAYLAND_DISPLAY
set cpm=wayland
endfunc
func s:SetupFocusStealing()
if !executable('wayland-info')
throw "Skipped: wayland-info program not available"
endif
" Starting a headless compositor won't expose a keyboard capability for its
" seat, so we must use the user's existing Wayland session if they are in one.
let $WAYLAND_DISPLAY = s:old_wayland_display
exe 'wlrestore ' .. $WAYLAND_DISPLAY
" Check if we have keyboard capability for seat
if system("wayland-info -i wl_seat | grep capabilities") !~? "keyboard"
throw "Skipped: seat does not have keyboard"
endif
let $VIM_WAYLAND_FORCE_FS=1
wlrestore!
endfunc
func s:UnsetupFocusStealing()
unlet $VIM_WAYLAND_FORCE_FS
endfunc
" Need X connection for tests that use client server communication
func s:CheckXConnection()
if has('x11')
try
call remote_send('xxx', '')
catch
if v:exception =~ 'E240:'
throw 'Skipped: no connection to the X server'
endif
" ignore other errors
endtry
endif
endfunc
func s:EndRemoteVim(name, job)
eval remote_send(a:name, "\<Esc>:qa!\<CR>")
try
call WaitForAssert({-> assert_equal("dead", job_status(a:job))})
finally
if job_status(a:job) != 'dead'
call assert_report('Vim instance did not exit')
call job_stop(a:job, 'kill')
endif
endtry
endfunc
func Test_wayland_startup()
call s:PreTest()
call s:CheckXConnection()
let l:name = 'WLVIMTEST'
let l:cmd = GetVimCommand() .. ' --servername ' .. l:name
let l:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
call WaitForAssert({-> assert_equal("run", job_status(l:job))})
call WaitForAssert({-> assert_match(name, serverlist())})
call WaitForAssert({-> assert_equal($WAYLAND_DISPLAY,
\ remote_expr(l:name, 'v:wayland_display'))})
call s:EndRemoteVim(l:name, l:job)
" When $WAYLAND_DISPLAY is invalid
let l:job = job_start(cmd, { 'stoponexit': 'kill', 'out_io': 'null',
\ 'env': {'WAYLAND_DISPLAY': 'UNKNOWN'}})
call WaitForAssert({-> assert_equal("run", job_status(l:job))})
call WaitForAssert({-> assert_match(name, serverlist())})
call assert_equal('', remote_expr(l:name, 'v:wayland_display'))
call s:EndRemoteVim(l:name, l:job)
endfunc
func Test_wayland_wlrestore()
call s:PreTest()
let l:wayland_display = StartWaylandCompositor()
let l:env_cmd = 'WAYLAND_DISPLAY=' .. l:wayland_display .. ' '
exe "wlrestore " .. l:wayland_display
call assert_equal(l:wayland_display, v:wayland_display)
" Check if calling wlrestore without arguments uses the existing wayland
" display.
wlrestore!
call assert_equal(l:wayland_display, v:wayland_display)
" If called with invalid display
wlrestore IDONTEXIST
call assert_equal("", v:wayland_display)
wlrestore!
call assert_equal("", v:wayland_display)
exe "wlrestore " .. l:wayland_display
call assert_equal(l:wayland_display, v:wayland_display)
" Actually check if connected display is different in case of regression with
" v:wayland_display
call system('wl-copy "1"')
call system(l:env_cmd .. 'wl-copy "2"')
call assert_equal('2', getreg('+'))
" Check if wlrestore doesn't disconnect the display if not nessecary by seeing
" if Vim doesn't lose the selection
call setreg('+', 'testing', 'c')
wlrestore
call assert_match('_VIM_TEXT', system(l:env_cmd .. 'wl-paste -l'))
" Forcibly disconnect and reconnect the display
wlrestore!
call assert_notmatch('_VIM_TEXT', system(l:env_cmd .. 'wl-paste -l'))
call EndWaylandCompositor(l:wayland_display)
endfunc
" Test behaviour when wayland display connection is lost
func Test_wayland_connection_lost()
call s:PreTest()
let l:wayland_display = StartWaylandCompositor()
let l:env_cmd = 'WAYLAND_DISPLAY=' .. l:wayland_display .. ' '
exe "wlrestore " .. l:wayland_display
call system(l:env_cmd .. 'wl-copy test')
call assert_equal(l:wayland_display, v:wayland_display)
call assert_equal('test', getreg('+'))
call EndWaylandCompositor(l:wayland_display)
call assert_equal('', getreg('+'))
call assert_fails('put +', 'E353:')
call assert_fails('yank +', 'E1548:')
endfunc
" Basic paste tests
func Test_wayland_paste()
call s:PreTest()
" Prevent 'Register changed while using it' error, guessing this works because
" it makes Vim lose the selection?
wlrestore!
" Regular selection
new
call system('wl-copy "TESTING"')
put +
call assert_equal("TESTING", getline(2))
call system('printf "LINE1\nLINE2\nLINE3" | wl-copy -n')
put +
call assert_equal(["LINE1", "LINE2", "LINE3"], getline(3, 5))
bw!
" Primary selection
new
call system('wl-copy -p "TESTING"')
put *
call assert_equal("TESTING", getline(2))
call system('printf "LINE1\nLINE2\nLINE3" | wl-copy -p')
put *
call assert_equal(["LINE1", "LINE2", "LINE3"], getline(3, 5))
bw!
" Check behaviour when selecton is cleared (empty)
call system('wl-copy --clear')
call assert_fails('put +', 'E353:')
endfunc
" Basic yank/copy tests
func Test_wayland_yank()
call s:PreTest()
wlrestore!
new
call setline(1, 'testing')
yank +
call assert_equal("testing\n", system('wl-paste -n'))
call setline(2, 'testing2')
call setline(3, 'testing3')
exe '1,3yank +'
call assert_equal("testing\ntesting2\ntesting3\n", system('wl-paste -n'))
bw!
" Primary selection
new
call setline(1, 'testing')
yank *
call assert_equal("testing\n", system('wl-paste -p -n'))
call setline(2, 'testing2')
call setline(3, 'testing3')
exe '1,3yank *'
call assert_equal("testing\ntesting2\ntesting3\n", system('wl-paste -p -n'))
bw!
endfunc
" Check if correct mime types are advertised when we own the selection
func Test_wayland_mime_types_correct()
call s:PreTest()
let l:mimes = [
\ '_VIMENC_TEXT',
\ '_VIM_TEXT',
\ 'text/plain;charset=utf-8',
\ 'text/plain',
\ 'UTF8_STRING',
\ 'STRING',
\ 'TEXT'
\ ]
call setreg('+', 'text', 'c')
for mime in split(system('wl-paste -l'), "\n")
if index(l:mimes, mime) == -1
call assert_report("'" .. mime .. "' is not a supported mime type")
endif
endfor
call setreg('*', 'text', 'c')
for mime in split(system('wl-paste -p -l'), "\n")
if index(l:mimes, mime) == -1
call assert_report("'" .. mime .. "' is not a supported mime type")
endif
endfor
endfunc
" Test if the _VIM_TEXT and _VIMENC_TEXT formats are correct:
" _VIM_TEXT: preserves motion type (line/char/block wise)
" _VIMENC_TEXT: same but also indicates the encoding type
func Test_wayland_paste_vim_format_correct()
call s:PreTest()
" Vim doesn't support null characters in strings, so we use the -v flag of the
" cat program to show them in a printable way, if it is available.
call system("cat -v")
if v:shell_error != 0
throw 'Skipped: cat program does not have -v command-line flag'
endif
set encoding=utf-8
let l:GetSel = {type -> system('wl-paste -t ' .. type .. ' | cat -v')}
let l:GetSelP = {type -> system('wl-paste -p -t ' .. type .. ' | cat -v')}
" Regular selection
call setreg('+', 'text', 'c')
call assert_equal("^@text", l:GetSel('_VIM_TEXT'))
call setreg('+', 'text', 'c')
call assert_equal("^@utf-8^@text", l:GetSel('_VIMENC_TEXT'))
call setreg('+', 'text', 'l')
call assert_equal("^Atext\n", l:GetSel('_VIM_TEXT'))
call setreg('+', 'text', 'l')
call assert_equal("^Autf-8^@text\n",l:GetSel('_VIMENC_TEXT'))
call setreg('+', 'text', 'b')
call assert_equal("^Btext\n", l:GetSel('_VIM_TEXT'))
call setreg('+', 'text', 'b')
call assert_equal("^Butf-8^@text\n", l:GetSel('_VIMENC_TEXT'))
" Primary selection
call setreg('*', 'text', 'c')
call assert_equal("^@text", l:GetSelP('_VIM_TEXT'))
call setreg('*', 'text', 'c')
call assert_equal("^@utf-8^@text", l:GetSelP('_VIMENC_TEXT'))
call setreg('*', 'text', 'l')
call assert_equal("^Atext\n", l:GetSelP('_VIM_TEXT'))
call setreg('*', 'text', 'l')
call assert_equal("^Autf-8^@text\n",l:GetSelP('_VIMENC_TEXT'))
call setreg('*', 'text', 'b')
call assert_equal("^Btext\n", l:GetSelP('_VIM_TEXT'))
call setreg('*', 'text', 'b')
call assert_equal("^Butf-8^@text\n", l:GetSelP('_VIMENC_TEXT'))
set encoding&
endfunc
" Test checking if * and + registers are not the same
func Test_wayland_plus_star_not_same()
call s:PreTest()
new
call system('wl-copy "regular"')
call system('wl-copy -p "primary"')
call assert_notequal(getreg('+'), getreg('*'))
" Check if when we are the source client
call setreg('+', 'REGULAR')
call setreg('*', 'PRIMARY')
call assert_notequal(system('wl-paste -p'), system('wl-paste'))
bw!
endfunc
" Test if autoselect option in 'clipboard' works properly for wayland
func Test_wayland_autoselect_works()
call s:PreTest()
call s:CheckXConnection()
let l:lines =<< trim END
set cpm=wayland
set clipboard=autoselect
new
call setline(1, 'LINE 1')
call setline(2, 'LINE 2')
call setline(3, 'LINE 3')
call cursor(1, 1)
END
call writefile(l:lines, 'Wltester', 'D')
let l:name = 'WLVIMTEST'
let l:cmd = GetVimCommand() .. ' -S Wltester --servername ' .. l:name
let l:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
call WaitForAssert({-> assert_equal("run", job_status(l:job))})
call WaitForAssert({-> assert_match(name, serverlist())})
1
call remote_send(l:name, "ve")
call WaitForAssert({-> assert_equal('LINE', system('wl-paste -p -n'))})
call remote_send(l:name, "w")
call WaitForAssert({-> assert_equal('LINE 1', system('wl-paste -p -n'))})
call remote_send(l:name, "V")
call WaitForAssert({-> assert_equal("LINE 1\n", system('wl-paste -p -n'))})
" Reset cursor
call remote_send(l:name, "\<Esc>:call cursor(1, 1)\<CR>")
call WaitForAssert({-> assert_equal("LINE 1\n", system('wl-paste -p -n'))})
" Test visual block mode
call remote_send(l:name, "\<C-q>jjj") " \<C-v> doesn't seem to work but \<C-q>
" does...
call WaitForAssert({-> assert_equal("L\nL\nL\n", system('wl-paste -p -n'))})
eval remote_send(l:name, "\<Esc>:qa!\<CR>")
try
call WaitForAssert({-> assert_equal("dead", job_status(l:job))})
finally
if job_status(l:job) != 'dead'
call assert_report('Vim instance did not exit')
call job_stop(l:job, 'kill')
endif
endtry
endfunc
" Check if the -Y flag works properly
func Test_no_wayland_connect_cmd_flag()
call s:PreTest()
call s:CheckXConnection()
let l:name = 'WLFLAGVIMTEST'
let l:cmd = GetVimCommand() .. ' -Y --servername ' .. l:name
let l:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
call WaitForAssert({-> assert_equal("run", job_status(l:job))})
call WaitForAssert({-> assert_match(name, serverlist())})
call WaitForAssert({->assert_equal('',
\ remote_expr(l:name, 'v:wayland_display'))})
call remote_send(l:name, ":wlrestore\<CR>")
call WaitForAssert({-> assert_equal('',
\ remote_expr(l:name, 'v:wayland_display'))})
call remote_send(l:name, ":wlrestore " .. $WAYLAND_DISPLAY .. "\<CR>")
call WaitForAssert({-> assert_equal('',
\ remote_expr(l:name, 'v:wayland_display'))})
call remote_send(l:name, ":wlrestore IDONTEXIST\<CR>")
call WaitForAssert({-> assert_equal('',
\ remote_expr(l:name, 'v:wayland_display'))})
eval remote_send(l:name, "\<Esc>:qa!\<CR>")
try
call WaitForAssert({-> assert_equal("dead", job_status(l:job))})
finally
if job_status(l:job) != 'dead'
call assert_report('Vim instance did not exit')
call job_stop(l:job, 'kill')
endif
endtry
endfunc
" Test behaviour when we do something like suspend Vim
func Test_wayland_become_inactive()
call s:PreTest()
call s:CheckXConnection()
let l:name = 'WLLOSEVIMTEST'
let l:cmd = GetVimCommand() .. ' --servername ' .. l:name
let l:job = job_start(cmd, {
\ 'stoponexit': 'kill',
\ 'out_io': 'null',
\ })
call WaitForAssert({-> assert_equal("run", job_status(l:job))})
call WaitForAssert({-> assert_match(name, serverlist())})
call remote_send(l:name, "iSOME TEXT\<Esc>\"+yy")
call WaitForAssert({-> assert_equal("SOME TEXT\n",
\ system('wl-paste -n'))})
call remote_send(l:name, "\<C-z>")
call WaitForAssert({-> assert_equal("Nothing is copied\n",
\ system('wl-paste -n'))})
eval remote_send(l:name, "\<Esc>:qa!\<CR>")
try
call WaitForAssert({-> assert_equal("dead", job_status(l:job))})
finally
if job_status(l:job) != 'dead'
call assert_report('Vim instance did not exit')
call job_stop(l:job, 'kill')
endif
endtry
endfunc
" Test wlseat option
func Test_wayland_seat()
call s:PreTest()
" Don't know a way to create a virtual seat so just test using the existing
" one only
set wlseat=
call system('wl-copy "TESTING"')
call assert_equal('TESTING', getreg('+'))
set wlseat=UNKNOWN
call assert_equal('', getreg('+'))
set wlseat=idontexist
call assert_equal('', getreg('+'))
set wlseat=
call assert_equal('TESTING', getreg('+'))
set wlseat&
endfunc
" Test focus stealing
func Test_wayland_focus_steal()
call s:PreTest()
call s:SetupFocusStealing()
call system('wl-copy regular')
call assert_equal('regular', getreg('+'))
call system('wl-copy -p primary')
call assert_equal('primary', getreg('*'))
call setreg('+', 'REGULAR')
call assert_equal('REGULAR', system('wl-paste -n'))
call setreg('*', 'PRIMARY')
call assert_equal('PRIMARY', system('wl-paste -p -n'))
call s:UnsetupFocusStealing()
endfunc
" Test when environment is not suitable for Wayland
func Test_wayland_bad_environment()
call s:PreTest()
call s:CheckXConnection()
unlet $WAYLAND_DISPLAY
let l:old = $XDG_RUNTIME_DIR
unlet $XDG_RUNTIME_DIR
let l:name = 'WLVIMTEST'
let l:cmd = GetVimCommand() .. ' --servername ' .. l:name
let l:job = job_start(cmd, {
\ 'stoponexit': 'kill',
\ 'out_io': 'null',
\ })
call WaitForAssert({-> assert_equal("run", job_status(l:job))})
call WaitForAssert({-> assert_match(name, serverlist())})
call WaitForAssert({-> assert_equal('',
\ remote_expr(l:name, 'v:wayland_display'))})
eval remote_send(l:name, "\<Esc>:qa!\<CR>")
try
call WaitForAssert({-> assert_equal("dead", job_status(l:job))})
finally
if job_status(l:job) != 'dead'
call assert_report('Vim instance did not exit')
call job_stop(l:job, 'kill')
endif
endtry
let $XDG_RUNTIME_DIR = l:old
endfunc
" Test if Vim still works properly after losing the selection
func Test_wayland_lost_selection()
call s:PreTest()
call setreg('+', 'regular')
call setreg('*', 'primary')
call assert_equal('regular', getreg('+'))
call assert_equal('primary', getreg('*'))
call system('wl-copy overwrite')
call system('wl-copy -p overwrite')
call assert_equal('overwrite', getreg('+'))
call assert_equal('overwrite', getreg('*'))
call setreg('+', 'regular')
call setreg('*', 'primary')
call assert_equal('regular', getreg('+'))
call assert_equal('primary', getreg('*'))
" Test focus stealing
call s:SetupFocusStealing()
call setreg('+', 'regular')
call setreg('*', 'primary')
call assert_equal('regular', getreg('+'))
call assert_equal('primary', getreg('*'))
call system('wl-copy overwrite')
call system('wl-copy -p overwrite')
call assert_equal('overwrite', getreg('+'))
call assert_equal('overwrite', getreg('*'))
call setreg('+', 'regular')
call setreg('*', 'primary')
call assert_equal('regular', getreg('+'))
call assert_equal('primary', getreg('*'))
call s:UnsetupFocusStealing()
endfunc
" Test when there are no supported mime types for the selecftion
func Test_wayland_no_mime_types_supported()
call s:PreTest()
wlrestore!
call system('wl-copy -t image/png testing')
call assert_equal('', getreg('+'))
call assert_fails('put +', 'E353:')
endfunc
" Test behaviour with large selections in terms of data size
func Test_wayland_handle_large_data()
call s:PreTest()
call writefile([''], 'data_file', 'D')
call writefile([''], 'data_file_cmp', 'D')
call system('yes c | head -5000000 > data_file') " ~ 10 MB
call system('wl-copy -t TEXT < data_file')
edit data_file_cmp
put! +
write
call system('truncate -s -1 data_file_cmp') " Remove newline at the end
call system('cmp --silent data_file data_file_cmp')
call assert_equal(0, v:shell_error)
" copy the text
call feedkeys('gg0v$G"+yy', 'x')
call system('wl-paste -n -t TEXT > data_file')
call system('cmp --silent data_file data_file_cmp')
call assert_equal(0, v:shell_error)
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -0,0 +1,110 @@
source check.vim
source shared.vim
CheckFeature job
CheckUnix
let g:xdisplay_num = 100
" Each key is the display name and its value is the compositor/wm job
let s:wayland_displays = {}
let s:x11_displays = {}
command -nargs=0 CheckWaylandCompositor call CheckWaylandCompositor()
command -nargs=0 CheckXServer call CheckXServer()
func CheckWaylandCompositor()
CheckFeature wayland
if executable("labwc") != 1
throw "Skipped: labwc is not available"
endif
endfunc
func CheckXServer()
CheckFeature x11
if executable("Xvfb") != 1
throw "Skipped: Xvfb is not available"
endif
if executable("xdpyinfo") != 1
throw "Skipped: xdpyinfo is not available"
endif
endfunc
func s:StartCompositorOutput(channel, msg)
let l:display = matchstr(a:msg, 'WAYLAND_DISPLAY=\zs.\+')
if !empty(l:display)
let s:wayland_display_name = l:display
endif
endfunc
func s:StartCompositorExit(job, status)
if s:wayland_display_name == ""
throw "Error: Wayland compositor exited when starting up"
endif
endfunc
func StartWaylandCompositor()
let s:wayland_display_name = ""
let l:wayland_compositor_job = job_start(
\ ['labwc', '-c', 'NONE', '-d'], {
\ 'err_io': 'pipe',
\ 'err_cb': function('s:StartCompositorOutput'),
\ 'err_mode': 'nl',
\ 'exit_cb': function('s:StartCompositorExit'),
\ 'env': { 'WLR_BACKENDS': 'headless' }
\ })
call WaitForAssert({-> assert_equal("run",
\ job_status(l:wayland_compositor_job))})
call WaitForAssert({-> assert_match('.\+', s:wayland_display_name)})
let s:wayland_displays[s:wayland_display_name] = l:wayland_compositor_job
return s:wayland_display_name
endfunc
func EndWaylandCompositor(display)
let l:job = s:wayland_displays[a:display]
call job_stop(l:job, 'term')
" Block until compositor is actually gone
call WaitForAssert({-> assert_equal("dead", job_status(l:job))})
unlet s:wayland_displays[a:display]
endfunc
" Start a separate X11 server instance
func StartXServer()
let l:xdisplay = ':' .. g:xdisplay_num
let l:x11_server_job = job_start(['Xvfb', l:xdisplay], {})
call WaitForAssert({-> assert_equal("run", job_status(l:x11_server_job))})
" Check if server is ready. Not sure if this is the best way though...
call WaitFor({-> system("DISPLAY=" .. l:xdisplay .. " xdpyinfo 2> /dev/null")
\ =~? '.\+'})
g:xdisplay_num += 1
let s:x11_displays[l:xdisplay] = l:x11_server_job
return l:xdisplay
endfunc
func EndXServer(display)
let l:job = s:x11_displays[a:display]
call job_stop(l:job)
" Block until X server is actually gone
call WaitForAssert({-> assert_equal("dead", job_status(l:job))})
unlet s:x11_displays[a:display]
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -643,6 +643,16 @@ static char *(features[]) =
# else
"-vtp",
# endif
#endif
#ifdef FEAT_WAYLAND
"+wayland",
#else
"-wayland",
#endif
#ifdef FEAT_WAYLAND_CLIPBOARD
"+wayland_clipboard",
#else
"-wayland_clipboard",
#endif
"+wildignore",
"+wildmenu",
@ -709,6 +719,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1485,
/**/
1484,
/**/

View File

@ -194,6 +194,10 @@
# define FEAT_X11
#endif
#if defined(HAVE_WAYLAND) && defined(WANT_WAYLAND)
#define FEAT_WAYLAND
#endif
#ifdef NO_X11_INCLUDES
// In os_mac_conv.c and os_macosx.m NO_X11_INCLUDES is defined to avoid
// X11 headers. Disable all X11 related things to avoid conflicts.
@ -2224,7 +2228,9 @@ typedef int sock_T;
#define VV_TYPE_ENUMVALUE 109
#define VV_STACKTRACE 110
#define VV_TYPE_TUPLE 111
#define VV_LEN 112 // number of v: vars
#define VV_WAYLAND_DISPLAY 112
#define VV_CLIPMETHOD 113
#define VV_LEN 114 // number of v: vars
// used for v_number in VAR_BOOL and VAR_SPECIAL
#define VVAL_FALSE 0L // VAR_BOOL
@ -2279,6 +2285,13 @@ typedef int sock_T;
# endif
# endif
typedef enum {
CLIPMETHOD_FAIL,
CLIPMETHOD_NONE,
CLIPMETHOD_WAYLAND,
CLIPMETHOD_X11,
} clipmethod_T;
// Info about selected text
typedef struct
{

2483
src/wayland.c Normal file

File diff suppressed because it is too large Load Diff