Compare commits

...

6 Commits

Author SHA1 Message Date
Foxe Chen
beeea8a1ce patch 9.1.1986: clipboard provider does not work when redirecting messages
Problem:  clipboard provider does not work when redirecting messages
          (BenYip, after v9.1.1972)
Solution: Adjust ifdefs in ex_redir()

fixes:  #18937
closes: #18939

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
2025-12-16 20:02:20 +01:00
Victorhck
bbf616a9d6 runtime(tutor): Improve Spanish translations
This change does the following:
- fix lesson number in tutor 1
- added and explanation about how get vimtutor lesson 2
- fix credits to authors in lesson 2

closes: #18940

Signed-off-by: Victorhck <victorhck@mailbox.org>
Signed-off-by: Christian Brabandt <cb@256bit.org>
2025-12-16 19:56:59 +01:00
Muraoka Taro
878d00bb3a patch 9.1.1985: tests: test_sound.vim fails on Windows
Problem:  tests: test_sound.vim fails when run locally on Windows
Solution: Skip Test_play_silent in Windows non-GUI environments.

Cause: There are two causes:

1) The global variable g:id is undefined, causing an undefined
   reference. Due to the execution order of test cases, g:id is defined in
   Test_play_event. However, on Windows, this test is skipped, so g:id is
   not defined. It is referenced in Test_play_silent's WaitForAssert()
   without being defined, resulting in an undefined error.

   Solution: Define g:id at the beginning of Test_play_silent.

2) In the non-GUI Windows version of vim, there is no message loop,
   so the callback when play file sound ends does not occur, and
   Test_play_silent's WaitForAssert times out and fails. In CI,
   sound_playfile() returns 0, so Test_play_silent is skipped. The
   reason for this is unknown, but it may be because CI is running on
   Windows Server or something like that.

   Solution: Skip Test_play_silent in Windows non-GUI environments.

Signed-off-by: Muraoka Taro <koron.kaoriya@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>

closes: #18941
2025-12-16 19:51:26 +01:00
Foxe Chen
02b8ec7da5 patch 9.1.1984: terminal OSC52 support can be improved
Problem:  terminal OSC52 support to access the clipboard can be improved
Solution: Include and package the optional osc52 package, note: this
          requires a Vim with clipboard provider feature (Foxe Chen).

related: #14995
closes: #18575

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
2025-12-15 21:52:32 +01:00
John Marriott
2019321e0b patch 9.1.1983: Vim9: class_name definition can be improved
Problem:  Vim9: class_name definition can be improved
Solution: Use string_T to store class_name, avoid using STRLEN() calls,
          simplify code, remove unused definition of struct
          oc_newmember_S (John Marriott)

Use struct string_T to store the field class_name in struct class_T,
which means we can just use the .length field in struct string_T
instead of measuring it.

In addition:
1. In eval.c use string_T to store class_name and s in function
   class_tv2string().
2. In vim9type.c change some calls from ga_concat() to ga_concat_len()
   where the length is known.
3. In vim9class.c remove unused struct definition oc_newmember_S.
   Change some calls from ga_concat() to ga_concat_len() where the
   length is known.
4. In scriptfile.c use string_T to store type_name, class_name and
   es_name in function estack_sfile().
5. In function estack_sfile() simplify construction of the grow array ga
   and change some calls from ga_concat() to ga_concat_len() when the
   length is known.

closes: #18925

Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
2025-12-15 21:09:29 +01:00
Foxe Chen
eb5995a876 patch 9.1.1982: Use after free with redraw_listener_add()
Problem:  Use after free with redraw_listener_add() (after: v9.1.1976)
Solution: Copy Callbacks into listener struct (Foxe Chen)

closes: #18926

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
2025-12-15 19:58:54 +01:00
34 changed files with 634 additions and 137 deletions

View File

@@ -856,7 +856,11 @@ RT_ALL = \
runtime/pack/dist/opt/netrw/autoload/netrw_gitignore.vim \
runtime/pack/dist/opt/netrw/doc/netrw.txt \
runtime/pack/dist/opt/netrw/plugin/netrwPlugin.vim \
runtime/pack/dist/opt/netrw/syntax/netrw.vim
runtime/pack/dist/opt/netrw/syntax/netrw.vim \
runtime/pack/dist/opt/osc52/plugin/osc52.vim \
runtime/pack/dist/opt/osc52/autoload/osc52.vim \
runtime/pack/dist/opt/osc52/doc/osc52.txt \
runtime/pack/dist/opt/osc52/doc/tags
# Runtime files for all distributions without CR/LF translation.
RT_ALL_BIN = \

View File

@@ -9616,6 +9616,7 @@ os_risc.txt os_risc.txt /*os_risc.txt*
os_unix.txt os_unix.txt /*os_unix.txt*
os_vms.txt os_vms.txt /*os_vms.txt*
os_win32.txt os_win32.txt /*os_win32.txt*
osc52-install usr_05.txt /*osc52-install*
other-features vi_diff.txt /*other-features*
out_buf channel.txt /*out_buf*
out_cb channel.txt /*out_cb*
@@ -9640,6 +9641,7 @@ package-justify usr_25.txt /*package-justify*
package-matchit usr_05.txt /*package-matchit*
package-nohlsearch usr_05.txt /*package-nohlsearch*
package-open eval.txt /*package-open*
package-osc52 usr_05.txt /*package-osc52*
package-termdebug terminal.txt /*package-termdebug*
package-translate_example repeat.txt /*package-translate_example*
package-translation repeat.txt /*package-translation*

View File

@@ -1,4 +1,4 @@
*usr_05.txt* For Vim version 9.1. Last change: 2025 Nov 09
*usr_05.txt* For Vim version 9.1. Last change: 2025 Dec 15
VIM USER MANUAL by Bram Moolenaar
@@ -399,13 +399,17 @@ The ":map" command (with no arguments) lists your current mappings. At
least the ones for Normal mode. More about mappings in section |40.1|.
==============================================================================
*05.5* Adding a package *add-package* *matchit-install* *package-matchit*
*05.5* Adding a package *add-package*
A package is a set of files that you can add to Vim. There are two kinds of
packages: optional and automatically loaded on startup.
The Vim distribution comes with a few packages that you can optionally use.
For example, the matchit plugin. This plugin makes the "%" command jump to
------------------------------------------------------------------------------
Adding the matchit package *matchit-install* *package-matchit*
------------------------------------------------------------------------------
For example, the matchit package This plugin makes the "%" command jump to
matching HTML tags, if/else/endif in Vim scripts, etc. Very useful, although
it's not backwards compatible (that's why it is not enabled by default).
@@ -434,7 +438,9 @@ an archive or as a repository. For an archive you can follow these steps:
Here "fancytext" is the name of the package, it can be anything
else.
------------------------------------------------------------------------------
Adding the editorconfig package *editorconfig-install* *package-editorconfig*
------------------------------------------------------------------------------
Similar to the matchit package, to load the distributed editorconfig plugin
when Vim starts, add the following line to your vimrc file: >
@@ -444,7 +450,9 @@ After restarting your Vim, the plugin is active and you can read about it at: >
:h editorconfig.txt
------------------------------------------------------------------------------
Adding the comment package *comment-install* *package-comment*
------------------------------------------------------------------------------
Load the plugin with this command: >
packadd comment
@@ -457,7 +465,9 @@ the package loaded. Once the package is loaded, read about it at: >
:h comment.txt
------------------------------------------------------------------------------
Adding the nohlsearch package *nohlsearch-install* *package-nohlsearch*
------------------------------------------------------------------------------
Load the plugin with this command: >
packadd nohlsearch
@@ -471,7 +481,9 @@ To disable the effect of the plugin after it has been loaded: >
au! nohlsearch
<
------------------------------------------------------------------------------
Adding the highlight-yank package *hlyank-install* *package-hlyank*
------------------------------------------------------------------------------
Load the plugin with this command: >
packadd hlyank
@@ -497,6 +509,20 @@ To highlight in visual mode, use: >
To disable the effect of the plugin after it has been loaded: >
au! hlyank
------------------------------------------------------------------------------
Adding the osc52 package *osc52-install* *package-osc52*
------------------------------------------------------------------------------
Load the plugin with this command: >
packadd osc52
<
The osc52.vim package provides support for the OSC 52 terminal command, which
allows an application to access the clipboard by communicating directly with
your terminal.
Once the package is loaded, read about it at: >
:h osc52.txt
More information about packages can be found here: |packages|.
==============================================================================

View File

@@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2025 Dec 14
*version9.txt* For Vim version 9.1. Last change: 2025 Dec 15
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -41627,8 +41627,9 @@ Other new features ~
------------------
- Support for Super key mappings in GTK using <D-Key>.
- The new packages |package-comment|, |package-nohlsearch|, |package-hlyank| and
|help-TOC| are included.
- The new optional packages |package-comment|, |package-nohlsearch|,
|package-hlyank|, |help-TOC|, |package-helpcurwin| and |package-osc52| are
included.
- An interactive tutor plugin has been included |vim-tutor-mode| and can be
started via |:Tutor|.

View File

@@ -0,0 +1,92 @@
vim9script
export var allowed: bool = false
export def Available(): bool
if get(g:, 'osc52_force_avail', 0)
return true
endif
return allowed
enddef
var sent_message: bool = false
def OSCMessage(id: number)
echom "Waiting for OSC52 response... Press CTRL-C to cancel"
sent_message = true
enddef
export def Paste(reg: string): tuple<string, list<string>>
# Check if user has indicated that the terminal does not support OSC 52 paste
# (or has disabled it)
if get(g:, 'osc52_disable_paste', 0)
return ("c", [""])
endif
# Some terminals like Kitty respect the selection type parameter on both X11
# and Wayland. If the terminal doesn't then the selection type parameter
# should be ignored (no-op)
if reg == "+"
echoraw("\<Esc>]52;c;?\<Esc>\\")
else
echoraw("\<Esc>]52;p;?\<Esc>\\")
endif
var timerid: number = timer_start(1000, OSCMessage)
var interrupt: bool = false
# Wait for response from terminal. If we got interrupted (Ctrl-C), then do a
# redraw if we already sent the message, and return an empty string.
try
while true
var key: string = getcharstr(-1, {cursor: "hide"})
if key == "\<xOSC>" && match(v:termosc, '52;') != -1
break
elseif key == "\<C-c>"
interrupt = true
break
endif
endwhile
# This doesn't seem to catch Ctrl-C sent via term_sendkeys(), which is used in
# tests. So also check the result of getcharstr()/getchar().
catch /^Vim:Interrupt$/
interrupt = true
finally
timer_stop(timerid)
if sent_message
sent_message = false
:redraw!
endif
endtry
if interrupt
echo "Interrupted while waiting for OSC 52 response"
return ("c", [""])
endif
# Extract the base64 stuff
var stuff: string = matchstr(v:termosc, '52;.\+;\zs[A-Za-z0-9+/=]\+')
var decoded: blob
# "stuff" may be an invalid base64 string, so catch any errors
try
decoded = base64_decode(stuff)
catch /:E475/
decoded = null_blob
echo "Invalid OSC 52 response received"
endtry
return ("", blob2str(decoded))
enddef
export def Copy(reg: string, type: string, lines: list<string>): void
if reg == "+"
echoraw("\<Esc>]52;c;" .. base64_encode(str2blob(lines)) .. "\<Esc>\\")
else
echoraw("\<Esc>]52;p;" .. base64_encode(str2blob(lines)) .. "\<Esc>\\")
endif
enddef
# vim: set sw=2 sts=2 :

View File

@@ -0,0 +1,64 @@
*osc52.txt* For Vim version 9.1. Last change: 2025 Dec 15
VIM REFERENCE MANUAL
Use the OSC 52 terminal command for clipboard support
==============================================================================
1. OVERVIEW *osc52-overview*
The osc52.vim plugin provides support for the OSC 52 terminal command, which
allows an application to access the clipboard by communicating with the
terminal. This is useful in situations such as if you are in a SSH session.
*osc52-support*
In order for this plugin to work, the terminal Vim is running in must
recognize and handle the OSC 52 escape sequence. You can easily check this
online. Additionally, while yanking is guaranteed to work, some terminals
don't implement the paste functionality. If the terminal doesn't support
pasting, then Vim will just block waiting for the data which will never come.
In this case just press Ctrl-C to cancel the operation.
*osc52-selections*
Note that this only applies to users on Wayland or X11 platforms
Some terminals support the selection type parameter in the OSC 52 command.
This originates from X11, and some terminals check this parameter and handle
it accordingly. If your terminal handles this parameter, then the "+"
register corresponds to the regular selection, and the "*" register
corresponds to the primary selection. If your terminal does not handle it,
then it is up to the terminal to handle what selection to use.
2. HOW TO USE THE PLUGIN *osc52-how-to-use*
The osc52.vim plugin relies on Vim's clipboard provider functionality, see
|clipboard-providers|. In short, add these commands to your vimrc to get
everything working: >vim
packadd osc52
set clipmethod+=osc52
<
This will make the osc52.vim provider the last resort if there are other
values in |clipmethod|. This allows Vim, for example, to access the system
clipboard directly if it can, but automatically switch to OSC 52 if it cannot
(e.g. in an SSH session). Note that this does not happen when on a platform
that doesn't use |clipmethod| for system clipboard functionality (MacOS,
Windows). If OSC 52 support is detected, then it will always be used if set
in |clipmethod| when it is the only value/method.
*g:osc52_force_avail*
In most cases, the plugin should automatically detect and work if your
terminal supports the OSC 52 command. Internally, it does this via a Primary
Device Attributes (DA1) query. You may force enable the plugin by setting
|g:osc52_force_avail| to true. You may check if the osc52.vim plugin is being
used if the value of |v:clipmethod| is "osc52". Note that using a terminal
multiplexer such as tmux, may prevent automatic OSC 52 detection.
*g:osc52_disable_paste*
If your terminal does not support pasting via OSC 52, or has it disabled, then
it is a good idea to set g:osc52_disable_paste to TRUE. This will cause an
empty string to be returned when Vim attempts to query the osc52.vim provider,
instead of doing a blocking wait, as said in |osc52-support|.
==============================================================================
vim:tw=78:ts=8:fo=tcq2:ft=help:

7
runtime/pack/dist/opt/osc52/doc/tags vendored Normal file
View File

@@ -0,0 +1,7 @@
g:osc52_disable_paste osc52.txt /*g:osc52_disable_paste*
g:osc52_force_avail osc52.txt /*g:osc52_force_avail*
osc52-how-to-use osc52.txt /*osc52-how-to-use*
osc52-overview osc52.txt /*osc52-overview*
osc52-selections osc52.txt /*osc52-selections*
osc52-support osc52.txt /*osc52-support*
osc52.txt osc52.txt /*osc52.txt*

View File

@@ -0,0 +1,45 @@
vim9script
# Vim plugin for OSC52 clipboard support
#
# Maintainer: The Vim Project <https://github.com/vim/vim>
# Last Change: 2025 October 14
if !has("timers")
finish
endif
import autoload "../autoload/osc52.vim" as osc
v:clipproviders["osc52"] = {
"available": osc.Available,
"paste": {
"*": osc.Paste,
"+": osc.Paste
},
"copy": {
"*": osc.Copy,
"+": osc.Copy
},
}
augroup VimOSC52Plugin
autocmd!
# Query support for OSC 52 using a DA1 query
autocmd TermResponseAll da1 {
if match(v:termda1, '?\zs.*52\ze') != -1
osc.allowed = true
:silent! clipreset
else
osc.allowed = false
:silent! clipreset
endif
}
autocmd VimEnter * {
if !has("gui_running") && !get(g:, 'osc52_force_avail', 0)
echoraw("\<Esc>[c")
endif
}
augroup END
# vim: set sw=2 sts=2 :

View File

@@ -901,7 +901,7 @@ NOTA: Si quiere ignorar las mayúsculas y minúsculas, solo para un comando
7. Añada "no" para inhabilitar una opción: :set noic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Lección 7: OBTENER AYUDA
Lección 1.7.1: OBTENER AYUDA
** Utilice el sistema de ayuda en línea **
@@ -996,15 +996,18 @@ NOTA: El completado funciona con muchos comandos. Solo pulse CTRL-D o
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Aquí concluye el tutor de Vim. Considera continuar con Capítulo 2, que trata
Aquí concluye el tutor de Vim. Considere continuar con Capítulo 2, que trata
sobre registros, marcas y el uso de objetos de texto.
Para acceder al Capítulo 2 salga de este y ejecute en una terminal:
vimtutor -c 2
Está pensado para dar una visión breve del
editor Vim, lo suficiente para permitirle usar el editor de forma bastante
sencilla. Está muy lejos de estar completo pues Vim tiene muchísimos más
comandos.
Lee el siguiente manual de usuario: ":help user-manual".
Lea el siguiente manual de usuario: ":help user-manual".
Para lecturas y estudios posteriores se recomienda el libro:
Vim - Vi Improved - de Steve Oualline

View File

@@ -316,7 +316,7 @@ REFERENCIA: Marcas :h marks
Con esto concluye el capítulo dos del Tutor de Vim.
Este es un trabajo en progreso.
Este capítulo fue traducido por Paul D. Parker y Christian Brabandt.
Este capítulo fue escrito por Paul D. Parker y Christian Brabandt.
Traducido por Victorhck.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -3479,7 +3479,7 @@ f_redraw_listener_add(typval_T *argvars, typval_T *rettv)
vim_free(rln);
return;
}
set_callback(&rln->rl_callbacks.on_start, &cb);
copy_callback(&rln->rl_callbacks.on_start, &cb);
free_callback(&cb);
clear_tv(&tv);
got_one = true;
@@ -3496,7 +3496,7 @@ f_redraw_listener_add(typval_T *argvars, typval_T *rettv)
vim_free(rln);
return;
}
set_callback(&rln->rl_callbacks.on_end, &cb);
copy_callback(&rln->rl_callbacks.on_end, &cb);
free_callback(&cb);
clear_tv(&tv);
got_one = true;

View File

@@ -1156,7 +1156,7 @@ fill_lval_from_lval_root(lval_T *lp, lval_root_T *lr)
lp->ll_tv = &lp->ll_class->class_members_tv[m_idx];
#ifdef LOG_LOCKVAR
ch_log(NULL, "LKVAR: ... class member %s.%s",
lp->ll_class->class_name, lp->ll_name);
lp->ll_class->class_name.string, lp->ll_name);
#endif
return;
}
@@ -1205,7 +1205,7 @@ get_lval_check_access(
{
if (om->ocm_type->tt_type == VAR_OBJECT)
semsg(_(e_enumvalue_str_cannot_be_modified),
cl->class_name, om->ocm_name);
cl->class_name.string, om->ocm_name);
else
msg = e_variable_is_not_writable_str;
}
@@ -6230,7 +6230,7 @@ method_tv2string(typval_T *tv, char_u **tofree, int echo_style)
size_t len = vim_snprintf((char *)buf, sizeof(buf), "<SNR>%d_%s.%s",
pt->pt_func->uf_script_ctx.sc_sid,
pt->pt_func->uf_class->class_name,
pt->pt_func->uf_class->class_name.string,
pt->pt_func->uf_name);
if (len >= sizeof(buf))
{
@@ -6493,31 +6493,29 @@ class_tv2string(typval_T *tv, char_u **tofree)
char_u *r = NULL;
size_t rsize;
class_T *cl = tv->vval.v_class;
char_u *class_name = (char_u *)"[unknown]";
size_t class_namelen = 9;
char *s = "class";
size_t slen = 5;
string_T class_name = {(char_u *)"[unknown]", 9};
string_T s = {(char_u *)"class", 5};
if (cl != NULL)
{
class_name = cl->class_name;
class_namelen = STRLEN(cl->class_name);
class_name.string = cl->class_name.string;
class_name.length = cl->class_name.length;
if (IS_INTERFACE(cl))
{
s = "interface";
slen = 9;
s.string = (char_u *)"interface";
s.length = 9;
}
else if (IS_ENUM(cl))
{
s = "enum";
slen = 4;
s.string = (char_u *)"enum";
s.length = 4;
}
}
rsize = slen + 1 + class_namelen + 1;
rsize = s.length + 1 + class_name.length + 1;
r = *tofree = alloc(rsize);
if (r != NULL)
vim_snprintf((char *)r, rsize, "%s %s", s, (char *)class_name);
vim_snprintf((char *)r, rsize, "%s %s", s.string, (char *)class_name.string);
return r;
}
@@ -6550,11 +6548,11 @@ object_tv2string(
else if (copyID != 0 && obj->obj_copyID == copyID
&& obj->obj_class->class_obj_member_count != 0)
{
size_t n = 25 + STRLEN((char *)obj->obj_class->class_name);
size_t n = 25 + obj->obj_class->class_name.length;
r = alloc(n);
if (r != NULL)
(void)vim_snprintf((char *)r, n, "object of %s {...}",
obj->obj_class->class_name);
obj->obj_class->class_name.string);
*tofree = r;
}
else

View File

@@ -2258,7 +2258,7 @@ report_lockvar_member(char *msg, lval_T *lp)
int did_alloc = FALSE;
char_u *vname = (char_u *)"";
char_u *class_name = lp->ll_class != NULL
? lp->ll_class->class_name : (char_u *)"";
? lp->ll_class->class_name.string : (char_u *)"";
if (lp->ll_name != NULL)
{
if (lp->ll_name_end == NULL)

View File

@@ -8856,6 +8856,10 @@ ex_redir(exarg_T *eap)
close_redir();
++arg;
if (ASCII_ISALPHA(*arg)
# ifdef HAVE_CLIPMETHOD
|| (clipmethod == CLIPMETHOD_PROVIDER
&& (*arg == '*' || *arg == '+'))
# endif
# ifdef FEAT_CLIPBOARD
|| *arg == '*'
|| *arg == '+'

View File

@@ -188,51 +188,65 @@ estack_sfile(estack_arg_T which UNUSED)
entry = ((estack_T *)exestack.ga_data) + idx;
if (entry->es_name != NULL)
{
long lnum = 0;
char_u *type_name = (char_u *)"";
char_u *class_name = (char_u *)"";
long lnum = 0;
string_T type_name = {(char_u *)"", 0};
string_T class_name = {(char_u *)"", 0};
string_T es_name = {entry->es_name, STRLEN(entry->es_name)};
if (entry->es_type != last_type)
{
switch (entry->es_type)
{
case ETYPE_SCRIPT: type_name = (char_u *)"script "; break;
case ETYPE_UFUNC: type_name = (char_u *)"function "; break;
default: type_name = (char_u *)""; break;
case ETYPE_SCRIPT:
type_name.string = (char_u *)"script ";
type_name.length = 7;
break;
case ETYPE_UFUNC:
type_name.string = (char_u *)"function ";
type_name.length = 9;
break;
default:
break;
}
last_type = entry->es_type;
}
if (entry->es_type == ETYPE_UFUNC && entry->es_info.ufunc->uf_class != NULL)
class_name = entry->es_info.ufunc->uf_class->class_name;
{
class_name.string = entry->es_info.ufunc->uf_class->class_name.string;
class_name.length = entry->es_info.ufunc->uf_class->class_name.length;
}
if (idx == exestack.ga_len - 1)
lnum = which == ESTACK_STACK ? SOURCING_LNUM : 0;
else
lnum = entry->es_lnum;
len = STRLEN(entry->es_name) + STRLEN(type_name) + STRLEN(class_name) + 26;
len = es_name.length + type_name.length + class_name.length + 26;
if (ga_grow(&ga, (int)len) == FAIL)
break;
ga_concat(&ga, type_name);
if (*class_name != NUL)
{
// For class methods prepend "<class name>." to the function name.
ga_concat(&ga, (char_u *)"<SNR>");
ga.ga_len += vim_snprintf((char *)ga.ga_data + ga.ga_len, 23,
"%d_", entry->es_info.ufunc->uf_script_ctx.sc_sid);
ga_concat(&ga, class_name);
ga_append(&ga, '.');
}
ga_concat(&ga, entry->es_name);
ga_concat_len(&ga, type_name.string, type_name.length);
// For class methods prepend "<class name>." to the function name.
if (*class_name.string != NUL)
ga.ga_len += vim_snprintf_safelen(
(char *)ga.ga_data + ga.ga_len,
len - (size_t)ga.ga_len,
"<SNR>%d_%s.",
entry->es_info.ufunc->uf_script_ctx.sc_sid,
class_name.string);
ga_concat_len(&ga, es_name.string, es_name.length);
// For the bottom entry of <sfile>: do not add the line number, it is used in
// <slnum>. Also leave it out when the number is not set.
if (lnum != 0)
ga.ga_len += vim_snprintf((char *)ga.ga_data + ga.ga_len, 23, "[%ld]",
lnum);
ga.ga_len += vim_snprintf_safelen(
(char *)ga.ga_data + ga.ga_len,
len - (size_t)ga.ga_len,
"[%ld]",
lnum);
if (idx != exestack.ga_len - 1)
ga_concat(&ga, (char_u *)"..");
ga_concat_len(&ga, (char_u *)"..", 2);
}
}
ga_append(&ga, '\0');
ga_append(&ga, NUL);
return (char_u *)ga.ga_data;
#endif
}

View File

@@ -1606,7 +1606,7 @@ struct itf2class_S {
// Also used for an interface (class_flags has CLASS_INTERFACE).
struct class_S
{
char_u *class_name; // allocated
string_T class_name; // allocated
int class_flags; // CLASS_ flags
int class_refcount;

View File

@@ -249,6 +249,7 @@ NEW_TESTS = \
test_plugin_man \
test_plugin_matchparen \
test_plugin_netrw \
test_plugin_osc52 \
test_plugin_tar \
test_plugin_termdebug \
test_plugin_tohtml \
@@ -524,6 +525,7 @@ NEW_TESTS_RES = \
test_plugin_man.res \
test_plugin_matchparen.res \
test_plugin_netrw.res \
test_plugin_osc52.res \
test_plugin_tar.res \
test_plugin_termdebug.res \
test_plugin_tohtml.res \

View File

@@ -0,0 +1,20 @@
> +0&#ffffff0@74
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|W+0#0000000&|a|i|t|i|n|g| |f|o|r| |O|S|C|5|2| |r|e|s|.@2|P|r|e|s@1| |C|T|R|L|-|C| |t|o| |c|a|n|c|e|l| @10|0|,|0|-|1| @8|A|l@1|

View File

@@ -0,0 +1,20 @@
| +0&#ffffff0@74
>h|e|l@1|o| @69
|w|o|r|l|d|!| @68
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
| +0#0000000&@56|2|,|1| @10|A|l@1|

View File

@@ -0,0 +1,20 @@
| +0&#ffffff0@74
>h|e|l@1|o| @69
|w|o|r|l|d|!| @68
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|I+0#0000000&|n|v|a|l|i|d| |O|S|C| |5|2| |r|e|s|p|o|n|s|e| |r|e|c|e|i|v|e|d| @24|2|,|1| @10|A|l@1|

View File

@@ -0,0 +1,20 @@
| +0&#ffffff0@74
>h|e|l@1|o| @69
|w|o|r|l|d|!| @68
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|I+0#0000000&|n|t|e|r@1|u|p|t|e|d| |w|h|i|l|e| |w|a|i|t|i|n|g| |f|o|r| |O|S|C| |5|2| |r|e|s|p|o|n|s|e| @11|2|,|1| @10|A|l@1|

View File

@@ -783,6 +783,8 @@ func s:Copy(reg, type, lines)
endfunc
func Test_clipboard_provider_available()
CheckFeature clipboard_provider
let g:vim_cp_available = v:true
let v:clipproviders["test"] = {
@@ -810,6 +812,8 @@ func Test_clipboard_provider_available()
endfunc
func Test_clipboard_provider_paste()
CheckFeature clipboard_provider
let v:clipproviders["test"] = {
\ "paste": {
\ '+': function("s:Paste"),
@@ -860,6 +864,8 @@ func Test_clipboard_provider_paste()
endfunc
func Test_clipboard_provider_copy()
CheckFeature clipboard_provider
let v:clipproviders["test"] = {
\ "copy": {
\ '+': function("s:Copy"),
@@ -928,6 +934,7 @@ endfunc
" clipmethod is set to a provider. If not, then the plus register points to the
" star register like normal.
func Test_clipboard_provider_no_unamedplus()
CheckFeature clipboard_provider
CheckNotFeature unnamedplus
CheckFeature clipboard_working
@@ -956,6 +963,7 @@ endfunc
" Same as Test_clipboard_provider_registers() but do it when +clipboard isnt
" enabled.
func Test_clipboard_provider_no_clipboard()
CheckFeature clipboard_provider
CheckNotFeature clipboard
let v:clipproviders["test"] = {
@@ -984,6 +992,7 @@ endfunc
" Test if clipboard provider feature doesn't break existing clipboard
" functionality.
func Test_clipboard_provider_sys_clipboard()
CheckFeature clipboard_provider
CheckFeature clipboard_working
let v:clipproviders["test"] = {
@@ -1036,6 +1045,8 @@ endfunc
" Test if the provider callback are only called once per register on operations
" that may try calling them multiple times.
func Test_clipboard_provider_accessed_once()
CheckFeature clipboard_provider
let v:clipproviders["test"] = {
\ "paste": {
\ '+': function("s:Paste"),
@@ -1095,6 +1106,8 @@ endfunc
" Test if the copying does not call the paste callback, and pasting does not all
" the copy callback.
func Test_clipboard_provider_copy_paste_independent()
CheckFeature clipboard_provider
let v:clipproviders["test"] = {
\ "paste": {
\ '+': function("s:Paste"),
@@ -1152,4 +1165,33 @@ func Test_clipboard_provider_copy_paste_independent()
set clipmethod&
endfunc
" Test if clipboard provider feature works under :redir and execute()
func Test_clipboard_provider_redir_execute()
CheckFeature clipboard_provider
let v:clipproviders["test"] = {
\ "copy": {
\ '+': function("s:Copy"),
\ '*': function("s:Copy")
\ }
\ }
set clipmethod=test
redir @+
echom "testing"
redir END
call assert_equal("+",g:vim_copy.reg)
call assert_equal(["", "testing"], g:vim_copy.lines)
call assert_equal("v", g:vim_copy.type)
let @+ = execute("echom 'hello world'")
call assert_equal("+",g:vim_copy.reg)
call assert_equal(["", "hello world"], g:vim_copy.lines)
call assert_equal("v", g:vim_copy.type)
set clipmethod&
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -774,4 +774,12 @@ func Test_redraw_remove_in_callback()
call StopVimInTerminal(buf)
endfunc
func s:OnRedraw()
endfunc
" Test if partial is correctly ref'ed and doesn't cause use afte free error
func Test_redraw_listener_partial()
call redraw_listener_add(#{on_start: function("s:OnRedraw", [1])})
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -0,0 +1,95 @@
" Test for the OSC 52 plugin
CheckRunVimInTerminal
" Does not run on BSD CI test runner
CheckNotBSD
source util/screendump.vim
" Check if plugin correctly detects OSC 52 support if possible
func Test_osc52_detect()
let lines =<< trim END
packadd osc52
set clipmethod=osc52
END
call writefile(lines, "Xosc52.vim", "D")
defer delete("Xosc52result")
let buf = RunVimInTerminal("-S Xosc52.vim", {})
" The plugin creates an autocmd listening for DA1 responses
" No support
call term_sendkeys(buf, "\<Esc>[?62;22;c")
call TermWait(buf)
call term_sendkeys(buf,
\ "\<Esc>:call writefile([v:termda1, v:clipmethod], 'Xosc52result')\<CR>")
call TermWait(buf)
call WaitForAssert({->
\ assert_equal(["\<Esc>[?62;22;c", "none"], readfile('Xosc52result'))})
" Yes support
call term_sendkeys(buf, "\<Esc>[?62;2;3;4;1;52;c")
call TermWait(buf)
call term_sendkeys(buf,
\ "\<Esc>:call writefile([v:termda1, v:clipmethod], 'Xosc52result')\<CR>")
call TermWait(buf)
call WaitForAssert({-> assert_equal(["\<Esc>[?62;2;3;4;1;52;c", "osc52"],
\ readfile('Xosc52result'))})
call StopVimInTerminal(buf)
endfunc
" Test if pasting works
func Test_osc52_paste()
CheckScreendump
let lines =<< trim END
packadd osc52
set clipmethod=osc52
redraw!
END
call writefile(lines, "Xosc52.vim", "D")
let buf = RunVimInTerminal("-S Xosc52.vim", {})
call term_sendkeys(buf, "\<Esc>[?52;c")
call TermWait(buf)
call term_sendkeys(buf, "\"+p")
call TermWait(buf)
" Check to see if message is shown after a second of waiting for a response
sleep 1500m
call VerifyScreenDump(buf, 'Test_osc52_paste_01', {})
call term_sendkeys(buf, "\<Esc>]52;c;" ..
\ base64_encode(str2blob(["hello", "world!"])) .. "\<Esc>\\")
call TermWait(buf)
" Check if message is gone
call VerifyScreenDump(buf, 'Test_osc52_paste_02', {})
" Test when invalid base64 content received (should emit a message)
call term_sendkeys(buf, "\"+p")
call TermWait(buf)
call term_sendkeys(buf, "\<Esc>]52;c;abc\<Esc>\\")
call TermWait(buf)
call VerifyScreenDump(buf, 'Test_osc52_paste_03', {})
" Test if interrupt is handled and message is outputted
call term_sendkeys(buf, "\"+p")
call TermWait(buf)
call term_sendkeys(buf, "\<C-c>")
call TermWait(buf)
call VerifyScreenDump(buf, 'Test_osc52_paste_04', {})
call StopVimInTerminal(buf)
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -33,9 +33,14 @@ func Test_play_event()
endfunc
func Test_play_silent()
if has('win32') && !has('gui_running')
throw 'Skipped: Playing file with callback is not supported on Windows, non-GUI'
endif
let fname = fnamemodify('silent.wav', '%p')
let g:playcallback_count = 0
let g:result = -1
let g:id = 0
" play without callback
let id1 = sound_playfile(fname)

View File

@@ -283,7 +283,7 @@ tv_get_bool_or_number_chk(
{
class_T *cl = varp->vval.v_object->obj_class;
if (cl != NULL && IS_ENUM(cl))
semsg(_(e_using_enum_str_as_number), cl->class_name);
semsg(_(e_using_enum_str_as_number), cl->class_name.string);
else
emsg(_(e_using_object_as_number));
}
@@ -1248,7 +1248,7 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
{
class_T *cl = varp->vval.v_object->obj_class;
if (cl != NULL && IS_ENUM(cl))
semsg(_(e_using_enum_str_as_string), cl->class_name);
semsg(_(e_using_enum_str_as_string), cl->class_name.string);
else
emsg(_(e_using_object_as_string));
}

View File

@@ -4524,7 +4524,8 @@ trans_function_name_ext(
else if (lv.ll_tv->v_type == VAR_CLASS
&& lv.ll_tv->vval.v_class != NULL)
{
name = vim_strsave(lv.ll_tv->vval.v_class->class_name);
name = vim_strnsave(lv.ll_tv->vval.v_class->class_name.string,
lv.ll_tv->vval.v_class->class_name.length);
*pp = end;
}
else if (lv.ll_tv->v_type == VAR_PARTIAL
@@ -5955,7 +5956,7 @@ defcompile_function(ufunc_T *ufunc, class_T *cl)
(void)compile_def_function(ufunc, FALSE, compile_type, NULL);
else
smsg(_("Function %s%s%s does not need compiling"),
cl != NULL ? cl->class_name : (char_u *)"",
cl != NULL ? cl->class_name.string : (char_u *)"",
cl != NULL ? (char_u *)"." : (char_u *)"",
ufunc->uf_name);
}

View File

@@ -734,6 +734,16 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1986,
/**/
1985,
/**/
1984,
/**/
1983,
/**/
1982,
/**/
1981,
/**/

View File

@@ -155,19 +155,6 @@ parse_member(
return OK;
}
typedef struct oc_newmember_S oc_newmember_T;
struct oc_newmember_S
{
garray_T *gap;
char_u *varname;
char_u *varname_end;
int has_public;
int has_final;
int has_type;
type_T *type;
char_u *init_expr;
};
/*
* Add a member to an object or a class.
* Returns OK when successful, "init_expr" will be consumed then.
@@ -260,7 +247,7 @@ object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl)
if (idx >= (is_method ? itf->class_obj_method_count
: itf->class_obj_member_count))
{
siemsg("index %d out of range for interface %s", idx, itf->class_name);
siemsg("index %d out of range for interface %s", idx, itf->class_name.string);
return 0;
}
@@ -293,7 +280,7 @@ object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl)
if (i2c == NULL)
{
siemsg("class %s not found on interface %s",
cl->class_name, itf->class_name);
cl->class_name.string, itf->class_name.string);
return 0;
}
@@ -319,7 +306,7 @@ validate_extends_class(
typval_T tv;
int success = FALSE;
if (STRCMP(cl->class_name, extends_name) == 0)
if (STRCMP(cl->class_name.string, extends_name) == 0)
{
semsg(_(e_cannot_extend_str), extends_name);
return success;
@@ -376,7 +363,7 @@ validate_extends_generic_method(
else
msg = e_generic_method_str_type_arguments_mismatch_in_class_str;
semsg(_(msg), cl_fp->uf_name, super_cl->class_name);
semsg(_(msg), cl_fp->uf_name, super_cl->class_name.string);
return FALSE;
}
@@ -426,7 +413,7 @@ validate_extends_methods(
// Method access is different between the super class
// and the subclass
semsg(_(e_method_str_of_class_str_has_different_access),
cl_fp[j]->uf_name, super->class_name);
cl_fp[j]->uf_name, super->class_name.string);
return FALSE;
}
@@ -916,7 +903,7 @@ add_interface_from_super_class(
char_u *intf_name;
// Add the interface name to "impl_gap"
intf_name = vim_strsave(ifcl->class_name);
intf_name = vim_strnsave(ifcl->class_name.string, ifcl->class_name.length);
if (intf_name == NULL)
return FALSE;
@@ -1723,11 +1710,11 @@ enum_parse_values(
if (init_expr == NULL)
vim_snprintf(initexpr_buf, sizeof(initexpr_buf), "%s.new()",
en->class_name);
en->class_name.string);
else
{
vim_snprintf(initexpr_buf, sizeof(initexpr_buf), "%s.new%s",
en->class_name, init_expr);
en->class_name.string, init_expr);
vim_free(init_expr);
}
if (add_member(gap, eni_name_start, eni_name_end, FALSE,
@@ -1793,18 +1780,18 @@ enum_add_values_member(
int rc = FAIL;
ga_init2(&fga, 1, 1000);
ga_concat(&fga, (char_u *)"[");
ga_concat_len(&fga, (char_u *)"[", 1);
for (int i = 0; i < num_enum_values; ++i)
{
ocmember_T *m = ((ocmember_T *)gap->ga_data) + i;
if (i > 0)
ga_concat(&fga, (char_u *)", ");
ga_concat(&fga, en->class_name);
ga_concat(&fga, (char_u *)".");
ga_concat_len(&fga, (char_u *)", ", 2);
ga_concat_len(&fga, en->class_name.string, en->class_name.length);
ga_concat_len(&fga, (char_u *)".", 1);
ga_concat(&fga, (char_u *)m->ocm_name);
}
ga_concat(&fga, (char_u *)"]");
ga_concat_len(&fga, (char_u *)"]", 1);
ga_append(&fga, NUL);
char_u *varname = (char_u *)"values";
@@ -1822,7 +1809,7 @@ enum_add_values_member(
}
rc = add_member(gap, varname, varname + 6, FALSE, FALSE, TRUE, TRUE, type,
vim_strsave((char_u *)fga.ga_data));
vim_strnsave((char_u *)fga.ga_data, fga.ga_len));
done:
vim_free(fga.ga_data);
@@ -2078,8 +2065,9 @@ early_ret:
cl->class_flags = CLASS_ABSTRACT;
cl->class_refcount = 1;
cl->class_name = vim_strnsave(name_start, name_end - name_start);
if (cl->class_name == NULL)
cl->class_name.length = (size_t)(name_end - name_start);
cl->class_name.string = vim_strnsave(name_start, cl->class_name.length);
if (cl->class_name.string == NULL)
goto cleanup;
cl->class_type.tt_type = VAR_CLASS;
@@ -2094,7 +2082,7 @@ early_ret:
tv.v_type = VAR_CLASS;
tv.vval.v_class = cl;
SOURCING_LNUM = start_lnum;
int rc = set_var_const(cl->class_name, 0, NULL, &tv, FALSE, 0, 0);
int rc = set_var_const(cl->class_name.string, 0, NULL, &tv, FALSE, 0, 0);
if (rc == FAIL)
goto cleanup;
@@ -3012,7 +3000,7 @@ call_oc_method(
{
// Protected object or class funcref variable
semsg(_(e_cannot_access_protected_variable_str), ocm->ocm_name,
cl->class_name);
cl->class_name.string);
return FAIL;
}
@@ -3570,7 +3558,7 @@ oc_var_check_ro(class_T *cl, ocmember_T *m)
if (m->ocm_flags & (OCMFLAG_FINAL | OCMFLAG_CONST))
{
semsg(_(e_cannot_change_readonly_variable_str_in_class_str),
m->ocm_name, cl->class_name);
m->ocm_name, cl->class_name.string);
return TRUE;
}
return FALSE;
@@ -3633,7 +3621,7 @@ class_free(class_T *cl)
// Freeing what the class contains may recursively come back here.
// Clear "class_name" first, if it is NULL the class does not need to
// be freed.
VIM_CLEAR(cl->class_name);
VIM_CLEAR_STRING(cl->class_name);
class_unref(cl->class_extends);
@@ -3795,7 +3783,7 @@ class_unref(class_T *cl)
--cl->class_refcount;
if (cl->class_name == NULL)
if (cl->class_name.string == NULL)
return;
if (can_free_class(cl))
@@ -3966,7 +3954,7 @@ emsg_var_cl_define(char *msg, char_u *name, size_t len, class_T *cl)
ocmember_T *m;
class_T *cl_def = class_defining_member(cl, name, len, &m);
if (cl_def != NULL)
semsg(_(msg), m->ocm_name, cl_def->class_name);
semsg(_(msg), m->ocm_name, cl_def->class_name.string);
else
emsg(_(e_internal_error_please_report_a_bug));
}
@@ -3986,7 +3974,7 @@ method_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len)
semsg(_(e_cannot_access_protected_method_str), method_name);
else
semsg(_(e_class_method_str_accessible_only_using_class_str),
method_name, cl->class_name);
method_name, cl->class_name.string);
}
else if ((v_type == VAR_CLASS)
&& (object_method_idx(cl, name, len) >= 0))
@@ -3996,11 +3984,11 @@ method_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len)
semsg(_(e_cannot_access_protected_method_str), method_name);
else
semsg(_(e_object_method_str_accessible_only_using_object_str),
method_name, cl->class_name);
method_name, cl->class_name.string);
}
else
semsg(_(e_method_not_found_on_class_str_str), method_name,
cl->class_name);
cl->class_name.string);
vim_free(method_name);
}
@@ -4016,24 +4004,24 @@ member_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len)
{
if (class_member_idx(cl, name, len) >= 0)
semsg(_(e_class_variable_str_accessible_only_using_class_str),
varname, cl->class_name);
varname, cl->class_name.string);
else
semsg(_(e_variable_not_found_on_object_str_str), varname,
cl->class_name);
cl->class_name.string);
}
else
{
if (object_member_idx(cl, name, len) >= 0)
semsg(_(e_object_variable_str_accessible_only_using_object_str),
varname, cl->class_name);
varname, cl->class_name.string);
else
{
if (IS_ENUM(cl))
semsg(_(e_enum_value_str_not_found_in_enum_str),
varname, cl->class_name);
varname, cl->class_name.string);
else
semsg(_(e_class_variable_str_not_found_in_class_str),
varname, cl->class_name);
varname, cl->class_name.string);
}
}
vim_free(varname);
@@ -4068,7 +4056,7 @@ defcompile_classes_in_script(void)
{
for (class_T *cl = first_class; cl != NULL; cl = cl->class_next_used)
{
if (eval_variable(cl->class_name, 0, 0, NULL, NULL,
if (eval_variable(cl->class_name.string, 0, 0, NULL, NULL,
EVAL_VAR_NOAUTOLOAD | EVAL_VAR_NO_FUNC) != FAIL)
defcompile_class(cl);
}
@@ -4215,28 +4203,30 @@ object2string(
if (cl != NULL && IS_ENUM(cl))
{
ga_concat(&ga, (char_u *)"enum ");
ga_concat(&ga, cl->class_name);
ga_concat_len(&ga, (char_u *)"enum ", 5);
ga_concat_len(&ga, cl->class_name.string, cl->class_name.length);
char_u *enum_name = ((typval_T *)(obj + 1))->vval.v_string;
ga_concat(&ga, (char_u *)".");
ga_concat_len(&ga, (char_u *)".", 1);
ga_concat(&ga, enum_name);
}
else
{
ga_concat(&ga, (char_u *)"object of ");
ga_concat(&ga, cl == NULL ? (char_u *)"[unknown]"
: cl->class_name);
ga_concat_len(&ga, (char_u *)"object of ", 10);
if (cl == NULL)
ga_concat_len(&ga, (char_u *)"[unknown]", 9);
else
ga_concat_len(&ga, cl->class_name.string, cl->class_name.length);
}
if (cl != NULL)
{
ga_concat(&ga, (char_u *)" {");
ga_concat_len(&ga, (char_u *)" {", 2);
for (int i = 0; i < cl->class_obj_member_count; ++i)
{
if (i > 0)
ga_concat(&ga, (char_u *)", ");
ga_concat_len(&ga, (char_u *)", ", 2);
ocmember_T *m = &cl->class_obj_members[i];
ga_concat(&ga, m->ocm_name);
ga_concat(&ga, (char_u *)": ");
ga_concat_len(&ga, (char_u *)": ", 2);
char_u *tf = NULL;
char_u *s = echo_string_core((typval_T *)(obj + 1) + i,
&tf, numbuf, copyID, echo_style,
@@ -4251,7 +4241,7 @@ object2string(
}
line_breakcheck();
}
ga_concat(&ga, (char_u *)"}");
ga_concat_len(&ga, (char_u *)"}", 1);
}
if (ok == FAIL)
{

View File

@@ -248,8 +248,8 @@ compile_lock_unlock(
if (*end != '.' && *end != '[')
{
// Push the class of the bare class variable name
name = cl->class_name;
len = (int)STRLEN(name);
name = cl->class_name.string;
len = (int)cl->class_name.length;
#ifdef LOG_LOCKVAR
ch_log(NULL, "LKVAR: ... cctx_class_member: name %s",
name);

View File

@@ -1627,7 +1627,7 @@ lhs_class_member_modifiable(lhs_T *lhs, char_u *var_start, cctx_T *cctx)
if (IS_ENUM(cl))
{
semsg(_(e_enumvalue_str_cannot_be_modified), cl->class_name,
semsg(_(e_enumvalue_str_cannot_be_modified), cl->class_name.string,
m->ocm_name);
return FALSE;
}
@@ -1758,7 +1758,7 @@ compile_lhs_class_variable(
// A class variable can be accessed without the class name
// only inside a class.
semsg(_(e_class_variable_str_accessible_only_inside_class_str),
lhs->lhs_name, defcl->class_name);
lhs->lhs_name, defcl->class_name.string);
return FAIL;
}
@@ -2055,7 +2055,7 @@ compile_lhs_set_oc_member_type(
if (!inside_class(cctx, cl))
{
semsg(_(e_enumvalue_str_cannot_be_modified),
cl->class_name, m->ocm_name);
cl->class_name.string, m->ocm_name);
return FAIL;
}
if (lhs->lhs_type->tt_type == VAR_OBJECT &&
@@ -2064,7 +2064,7 @@ compile_lhs_set_oc_member_type(
char *msg = lhs->lhs_member_idx == 0 ?
e_enum_str_name_cannot_be_modified :
e_enum_str_ordinal_cannot_be_modified;
semsg(_(msg), cl->class_name);
semsg(_(msg), cl->class_name.string);
return FAIL;
}
}

View File

@@ -3345,7 +3345,7 @@ var_any_get_oc_member(class_T *current_class, isn_T *iptr, typval_T *tv)
msg = e_variable_not_found_on_object_str_str;
else
msg = e_class_variable_str_not_found_in_class_str;
semsg(_(msg), iptr->isn_arg.string, tv_cl->class_name);
semsg(_(msg), iptr->isn_arg.string, tv_cl->class_name.string);
return FAIL;
}
@@ -7069,7 +7069,7 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
{
case ISN_CONSTRUCT:
smsg("%s%4d NEW %s size %d", pfx, current,
iptr->isn_arg.construct.construct_class->class_name,
iptr->isn_arg.construct.construct_class->class_name.string,
(int)iptr->isn_arg.construct.construct_size);
break;
case ISN_EXEC:
@@ -7381,7 +7381,7 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
smsg("%s%4d %s CLASSMEMBER %s.%s", pfx, current,
iptr->isn_type == ISN_LOAD_CLASSMEMBER
? "LOAD" : "STORE",
cl->class_name, ocm->ocm_name);
cl->class_name.string, ocm->ocm_name);
}
break;
@@ -7436,7 +7436,7 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
case ISN_PUSHCLASS:
smsg("%s%4d PUSHCLASS %s", pfx, current,
iptr->isn_arg.classarg == NULL ? "null"
: (char *)iptr->isn_arg.classarg->class_name);
: (char *)iptr->isn_arg.classarg->class_name.string);
break;
case ISN_PUSHEXC:
smsg("%s%4d PUSH v:exception", pfx, current);
@@ -7508,7 +7508,7 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
cmfunc_T *mfunc = iptr->isn_arg.mfunc;
smsg("%s%4d METHODCALL %s.%s(argc %d)", pfx, current,
mfunc->cmf_itf->class_name,
mfunc->cmf_itf->class_name.string,
mfunc->cmf_itf->class_obj_methods[
mfunc->cmf_idx]->uf_name,
mfunc->cmf_argcount);
@@ -7563,7 +7563,7 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
if (extra != NULL && extra->fre_class != NULL)
{
smsg("%s%4d FUNCREF %s.%s", pfx, current,
extra->fre_class->class_name, name);
extra->fre_class->class_name.string, name);
}
else if (extra == NULL
|| extra->fre_loopvar_info.lvi_depth == 0)
@@ -7853,7 +7853,7 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
case ISN_GET_ITF_MEMBER: smsg("%s%4d ITF_MEMBER %d on %s",
pfx, current,
(int)iptr->isn_arg.classmember.cm_idx,
iptr->isn_arg.classmember.cm_class->class_name);
iptr->isn_arg.classmember.cm_class->class_name.string);
break;
case ISN_STORE_THIS: smsg("%s%4d STORE_THIS %d", pfx, current,
(int)iptr->isn_arg.number); break;

View File

@@ -496,7 +496,7 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
// Trying to invoke an abstract method in a super class is not
// allowed.
semsg(_(e_abstract_method_str_direct), ufunc->uf_name,
ufunc->uf_defclass->class_name);
ufunc->uf_defclass->class_name.string);
goto done;
}
@@ -1052,7 +1052,7 @@ compile_load(
else
{
semsg(_(e_class_variable_str_accessible_only_inside_class_str),
name, cl->class_name);
name, cl->class_name.string);
res = FAIL;
}
}
@@ -1511,7 +1511,7 @@ compile_call(
else
{
semsg(_(e_class_method_str_accessible_only_inside_class_str),
name, cl->class_name);
name, cl->class_name.string);
res = FAIL;
}
goto theend;

View File

@@ -2626,23 +2626,27 @@ failed:
static char *
type_name_class_or_obj(char *name, type_T *type, char **tofree)
{
char_u *class_name;
string_T class_name;
if (type->tt_class != NULL)
{
class_name = type->tt_class->class_name;
class_name.string = type->tt_class->class_name.string;
class_name.length = type->tt_class->class_name.length;
if (IS_ENUM(type->tt_class))
name = "enum";
}
else
class_name = (char_u *)"any";
{
class_name.string = (char_u *)"any";
class_name.length = 3;
}
size_t len = STRLEN(name) + STRLEN(class_name) + 3;
size_t len = STRLEN(name) + class_name.length + 3;
*tofree = alloc(len);
if (*tofree == NULL)
return name;
vim_snprintf(*tofree, len, "%s<%s>", name, class_name);
vim_snprintf(*tofree, len, "%s<%s>", name, class_name.string);
return *tofree;
}
@@ -2812,7 +2816,7 @@ check_typval_is_value(typval_T *tv)
{
class_T *cl = tv->vval.v_class;
char_u *class_name = (cl == NULL) ? (char_u *)""
: cl->class_name;
: cl->class_name.string;
if (cl != NULL && IS_ENUM(cl))
semsg(_(e_using_enum_as_value_str), class_name);
else
@@ -2844,11 +2848,11 @@ check_type_is_value(type_T *type)
case VAR_CLASS:
if (type->tt_class != NULL && IS_ENUM(type->tt_class))
semsg(_(e_using_enum_as_value_str),
type->tt_class->class_name);
type->tt_class->class_name.string);
else
semsg(_(e_using_class_as_value_str),
type->tt_class == NULL ? (char_u *)""
: type->tt_class->class_name);
: type->tt_class->class_name.string);
return FAIL;
case VAR_TYPEALIAS: