forked from aniani/vim
patch 8.0.1660: the terminal API "drop" command doesn't support options
Problem: The terminal API "drop" command doesn't support options. Solution: Implement the options.
This commit is contained in:
parent
1f8495cf48
commit
333b80acf3
@ -25,7 +25,7 @@ If the result is "1" you have it.
|
|||||||
MS-Windows |terminal-ms-windows|
|
MS-Windows |terminal-ms-windows|
|
||||||
2. Terminal communication |terminal-communication|
|
2. Terminal communication |terminal-communication|
|
||||||
Vim to job: term_sendkeys() |terminal-to-job|
|
Vim to job: term_sendkeys() |terminal-to-job|
|
||||||
Job to Vim: JSON API |terminal-api|
|
Job to Vim: JSON API |terminal-api|
|
||||||
Using the client-server feature |terminal-client-server|
|
Using the client-server feature |terminal-client-server|
|
||||||
3. Remote testing |terminal-testing|
|
3. Remote testing |terminal-testing|
|
||||||
4. Diffing screen dumps |terminal-diff|
|
4. Diffing screen dumps |terminal-diff|
|
||||||
@ -352,7 +352,7 @@ On Unix a pty is used to make it possible to run all kinds of commands. You
|
|||||||
can even run Vim in the terminal! That's used for debugging, see below.
|
can even run Vim in the terminal! That's used for debugging, see below.
|
||||||
|
|
||||||
Environment variables are used to pass information to the running job:
|
Environment variables are used to pass information to the running job:
|
||||||
TERM name of the terminal, 'term'
|
TERM name of the terminal, from the 'term' option
|
||||||
ROWS number of rows in the terminal initially
|
ROWS number of rows in the terminal initially
|
||||||
LINES same as ROWS
|
LINES same as ROWS
|
||||||
COLUMNS number of columns in the terminal initially
|
COLUMNS number of columns in the terminal initially
|
||||||
@ -443,11 +443,25 @@ Currently supported commands:
|
|||||||
< Output from `:echo` may be erased by a redraw, use `:echomsg`
|
< Output from `:echo` may be erased by a redraw, use `:echomsg`
|
||||||
to be able to see it with `:messages`.
|
to be able to see it with `:messages`.
|
||||||
|
|
||||||
drop {filename}
|
drop {filename} [options]
|
||||||
|
|
||||||
Let Vim open a file, like the `:drop` command. If {filename}
|
Let Vim open a file, like the `:drop` command. If {filename}
|
||||||
is already open in a window, switch to that window. Otherwise
|
is already open in a window, switch to that window. Otherwise
|
||||||
open a new window to edit {filename}.
|
open a new window to edit {filename}.
|
||||||
|
|
||||||
|
[options] is only used when opening a new window. If present,
|
||||||
|
it must be a Dict. Similarly to |++opt|, These entries are recognized:
|
||||||
|
"ff" file format: "dos", "mac" or "unix"
|
||||||
|
"fileformat" idem
|
||||||
|
"enc" overrides 'fileencoding'
|
||||||
|
"encoding" idem
|
||||||
|
"bin" sets 'binary'
|
||||||
|
"binary" idem
|
||||||
|
"nobin" resets 'binary'
|
||||||
|
"nobinary" idem
|
||||||
|
"bad" specifies behavior for bad characters, see
|
||||||
|
|++bad|
|
||||||
|
|
||||||
Example in JSON: >
|
Example in JSON: >
|
||||||
["drop", "path/file.txt", {"ff": "dos"}]
|
["drop", "path/file.txt", {"ff": "dos"}]
|
||||||
|
|
||||||
|
@ -6590,7 +6590,7 @@ set_cmdarg(exarg_T *eap, char_u *oldarg)
|
|||||||
len += 7;
|
len += 7;
|
||||||
|
|
||||||
if (eap->force_ff != 0)
|
if (eap->force_ff != 0)
|
||||||
len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
|
len += 10; /* " ++ff=unix" */
|
||||||
# ifdef FEAT_MBYTE
|
# ifdef FEAT_MBYTE
|
||||||
if (eap->force_enc != 0)
|
if (eap->force_enc != 0)
|
||||||
len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
|
len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
|
||||||
@ -6614,7 +6614,9 @@ set_cmdarg(exarg_T *eap, char_u *oldarg)
|
|||||||
|
|
||||||
if (eap->force_ff != 0)
|
if (eap->force_ff != 0)
|
||||||
sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
|
sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
|
||||||
eap->cmd + eap->force_ff);
|
eap->force_ff == 'u' ? "unix"
|
||||||
|
: eap->force_ff == 'd' ? "dos"
|
||||||
|
: "mac");
|
||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
if (eap->force_enc != 0)
|
if (eap->force_enc != 0)
|
||||||
sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
|
sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
|
||||||
|
@ -1778,7 +1778,7 @@ struct exarg
|
|||||||
int regname; /* register name (NUL if none) */
|
int regname; /* register name (NUL if none) */
|
||||||
int force_bin; /* 0, FORCE_BIN or FORCE_NOBIN */
|
int force_bin; /* 0, FORCE_BIN or FORCE_NOBIN */
|
||||||
int read_edit; /* ++edit argument */
|
int read_edit; /* ++edit argument */
|
||||||
int force_ff; /* ++ff= argument (index in cmd[]) */
|
int force_ff; /* ++ff= argument (first char of argument) */
|
||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
int force_enc; /* ++enc= argument (index in cmd[]) */
|
int force_enc; /* ++enc= argument (index in cmd[]) */
|
||||||
int bad_char; /* BAD_KEEP, BAD_DROP or replacement byte */
|
int bad_char; /* BAD_KEEP, BAD_DROP or replacement byte */
|
||||||
|
@ -5308,6 +5308,18 @@ skip_cmd_arg(
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_bad_opt(char_u *p, exarg_T *eap)
|
||||||
|
{
|
||||||
|
if (STRICMP(p, "keep") == 0)
|
||||||
|
eap->bad_char = BAD_KEEP;
|
||||||
|
else if (STRICMP(p, "drop") == 0)
|
||||||
|
eap->bad_char = BAD_DROP;
|
||||||
|
else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
|
||||||
|
eap->bad_char = *p;
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get "++opt=arg" argument.
|
* Get "++opt=arg" argument.
|
||||||
* Return FAIL or OK.
|
* Return FAIL or OK.
|
||||||
@ -5387,6 +5399,7 @@ getargopt(exarg_T *eap)
|
|||||||
#endif
|
#endif
|
||||||
if (check_ff_value(eap->cmd + eap->force_ff) == FAIL)
|
if (check_ff_value(eap->cmd + eap->force_ff) == FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
eap->force_ff = eap->cmd[eap->force_ff];
|
||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
}
|
}
|
||||||
else if (pp == &eap->force_enc)
|
else if (pp == &eap->force_enc)
|
||||||
@ -5399,14 +5412,7 @@ getargopt(exarg_T *eap)
|
|||||||
{
|
{
|
||||||
/* Check ++bad= argument. Must be a single-byte character, "keep" or
|
/* Check ++bad= argument. Must be a single-byte character, "keep" or
|
||||||
* "drop". */
|
* "drop". */
|
||||||
p = eap->cmd + bad_char_idx;
|
if (get_bad_opt(eap->cmd + bad_char_idx, eap) == FAIL)
|
||||||
if (STRICMP(p, "keep") == 0)
|
|
||||||
eap->bad_char = BAD_KEEP;
|
|
||||||
else if (STRICMP(p, "drop") == 0)
|
|
||||||
eap->bad_char = BAD_DROP;
|
|
||||||
else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
|
|
||||||
eap->bad_char = *p;
|
|
||||||
else
|
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
14
src/fileio.c
14
src/fileio.c
@ -2779,22 +2779,22 @@ readfile_linenr(
|
|||||||
int
|
int
|
||||||
prep_exarg(exarg_T *eap, buf_T *buf)
|
prep_exarg(exarg_T *eap, buf_T *buf)
|
||||||
{
|
{
|
||||||
eap->cmd = alloc((unsigned)(STRLEN(buf->b_p_ff)
|
eap->cmd = alloc(15
|
||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
+ STRLEN(buf->b_p_fenc)
|
+ (unsigned)STRLEN(buf->b_p_fenc)
|
||||||
#endif
|
#endif
|
||||||
+ 15));
|
);
|
||||||
if (eap->cmd == NULL)
|
if (eap->cmd == NULL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
sprintf((char *)eap->cmd, "e ++ff=%s ++enc=%s", buf->b_p_ff, buf->b_p_fenc);
|
sprintf((char *)eap->cmd, "e ++enc=%s", buf->b_p_fenc);
|
||||||
eap->force_enc = 14 + (int)STRLEN(buf->b_p_ff);
|
eap->force_enc = 8;
|
||||||
eap->bad_char = buf->b_bad_char;
|
eap->bad_char = buf->b_bad_char;
|
||||||
#else
|
#else
|
||||||
sprintf((char *)eap->cmd, "e ++ff=%s", buf->b_p_ff);
|
sprintf((char *)eap->cmd, "e");
|
||||||
#endif
|
#endif
|
||||||
eap->force_ff = 7;
|
eap->force_ff = *buf->b_p_ff;
|
||||||
|
|
||||||
eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN;
|
eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN;
|
||||||
eap->read_edit = FALSE;
|
eap->read_edit = FALSE;
|
||||||
|
@ -3161,7 +3161,7 @@ get_fileformat_force(
|
|||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (eap != NULL && eap->force_ff != 0)
|
if (eap != NULL && eap->force_ff != 0)
|
||||||
c = eap->cmd[eap->force_ff];
|
c = eap->force_ff;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((eap != NULL && eap->force_bin != 0)
|
if ((eap != NULL && eap->force_bin != 0)
|
||||||
|
@ -12,6 +12,7 @@ char_u *skip_range(char_u *cmd, int *ctx);
|
|||||||
void ex_ni(exarg_T *eap);
|
void ex_ni(exarg_T *eap);
|
||||||
int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp);
|
int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp);
|
||||||
void separate_nextcmd(exarg_T *eap);
|
void separate_nextcmd(exarg_T *eap);
|
||||||
|
int get_bad_opt(char_u *p, exarg_T *eap);
|
||||||
int ends_excmd(int c);
|
int ends_excmd(int c);
|
||||||
char_u *find_nextcmd(char_u *p);
|
char_u *find_nextcmd(char_u *p);
|
||||||
char_u *check_nextcmd(char_u *p);
|
char_u *check_nextcmd(char_u *p);
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
* in tl_scrollback are no longer used.
|
* in tl_scrollback are no longer used.
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - For the "drop" command accept another argument for options.
|
|
||||||
* - Add a way to set the 16 ANSI colors, to be used for 'termguicolors' and in
|
* - Add a way to set the 16 ANSI colors, to be used for 'termguicolors' and in
|
||||||
* the GUI.
|
* the GUI.
|
||||||
* - Win32: Make terminal used for :!cmd in the GUI work better. Allow for
|
* - Win32: Make terminal used for :!cmd in the GUI work better. Allow for
|
||||||
@ -3152,10 +3151,12 @@ init_default_colors(term_T *term)
|
|||||||
handle_drop_command(listitem_T *item)
|
handle_drop_command(listitem_T *item)
|
||||||
{
|
{
|
||||||
char_u *fname = get_tv_string(&item->li_tv);
|
char_u *fname = get_tv_string(&item->li_tv);
|
||||||
|
listitem_T *opt_item = item->li_next;
|
||||||
int bufnr;
|
int bufnr;
|
||||||
win_T *wp;
|
win_T *wp;
|
||||||
tabpage_T *tp;
|
tabpage_T *tp;
|
||||||
exarg_T ea;
|
exarg_T ea;
|
||||||
|
char_u *tofree = NULL;
|
||||||
|
|
||||||
bufnr = buflist_add(fname, BLN_LISTED | BLN_NOOPT);
|
bufnr = buflist_add(fname, BLN_LISTED | BLN_NOOPT);
|
||||||
FOR_ALL_TAB_WINDOWS(tp, wp)
|
FOR_ALL_TAB_WINDOWS(tp, wp)
|
||||||
@ -3168,10 +3169,60 @@ handle_drop_command(listitem_T *item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open in new window, like ":sbuffer N" */
|
|
||||||
vim_memset(&ea, 0, sizeof(ea));
|
vim_memset(&ea, 0, sizeof(ea));
|
||||||
ea.cmd = (char_u *)"sbuffer";
|
|
||||||
goto_buffer(&ea, DOBUF_FIRST, FORWARD, bufnr);
|
if (opt_item != NULL && opt_item->li_tv.v_type == VAR_DICT
|
||||||
|
&& opt_item->li_tv.vval.v_dict != NULL)
|
||||||
|
{
|
||||||
|
dict_T *dict = opt_item->li_tv.vval.v_dict;
|
||||||
|
char_u *p;
|
||||||
|
|
||||||
|
p = get_dict_string(dict, (char_u *)"ff", FALSE);
|
||||||
|
if (p == NULL)
|
||||||
|
p = get_dict_string(dict, (char_u *)"fileformat", FALSE);
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
if (check_ff_value(p) == FAIL)
|
||||||
|
ch_log(NULL, "Invalid ff argument to drop: %s", p);
|
||||||
|
else
|
||||||
|
ea.force_ff = *p;
|
||||||
|
}
|
||||||
|
p = get_dict_string(dict, (char_u *)"enc", FALSE);
|
||||||
|
if (p == NULL)
|
||||||
|
p = get_dict_string(dict, (char_u *)"encoding", FALSE);
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
ea.cmd = alloc((int)STRLEN(p) + 10);
|
||||||
|
if (ea.cmd != NULL)
|
||||||
|
{
|
||||||
|
sprintf((char *)ea.cmd, "sbuf ++enc=%s", p);
|
||||||
|
ea.force_enc = 11;
|
||||||
|
tofree = ea.cmd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = get_dict_string(dict, (char_u *)"bad", FALSE);
|
||||||
|
if (p != NULL)
|
||||||
|
get_bad_opt(p, &ea);
|
||||||
|
|
||||||
|
if (dict_find(dict, (char_u *)"bin", -1) != NULL)
|
||||||
|
ea.force_bin = FORCE_BIN;
|
||||||
|
if (dict_find(dict, (char_u *)"binary", -1) != NULL)
|
||||||
|
ea.force_bin = FORCE_BIN;
|
||||||
|
if (dict_find(dict, (char_u *)"nobin", -1) != NULL)
|
||||||
|
ea.force_bin = FORCE_NOBIN;
|
||||||
|
if (dict_find(dict, (char_u *)"nobinary", -1) != NULL)
|
||||||
|
ea.force_bin = FORCE_NOBIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open in new window, like ":split fname" */
|
||||||
|
if (ea.cmd == NULL)
|
||||||
|
ea.cmd = (char_u *)"split";
|
||||||
|
ea.arg = fname;
|
||||||
|
ea.cmdidx = CMD_split;
|
||||||
|
ex_splitview(&ea);
|
||||||
|
|
||||||
|
vim_free(tofree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1049,17 +1049,14 @@ func Test_terminal_dumpdiff_options()
|
|||||||
set laststatus&
|
set laststatus&
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_terminal_api_drop_newwin()
|
func Api_drop_common(options)
|
||||||
if !CanRunVimInTerminal()
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call assert_equal(1, winnr('$'))
|
call assert_equal(1, winnr('$'))
|
||||||
|
|
||||||
" Use the title termcap entries to output the escape sequence.
|
" Use the title termcap entries to output the escape sequence.
|
||||||
call writefile([
|
call writefile([
|
||||||
\ 'set title',
|
\ 'set title',
|
||||||
\ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
|
\ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
|
||||||
\ 'let &titlestring = ''["drop","Xtextfile"]''',
|
\ 'let &titlestring = ''["drop","Xtextfile"' . a:options . ']''',
|
||||||
\ 'redraw',
|
\ 'redraw',
|
||||||
\ "set t_ts=",
|
\ "set t_ts=",
|
||||||
\ ], 'Xscript')
|
\ ], 'Xscript')
|
||||||
@ -1067,6 +1064,116 @@ func Test_terminal_api_drop_newwin()
|
|||||||
call WaitFor({-> bufnr('Xtextfile') > 0})
|
call WaitFor({-> bufnr('Xtextfile') > 0})
|
||||||
call assert_equal('Xtextfile', expand('%:t'))
|
call assert_equal('Xtextfile', expand('%:t'))
|
||||||
call assert_true(winnr('$') >= 3)
|
call assert_true(winnr('$') >= 3)
|
||||||
|
return buf
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_api_drop_newwin()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let buf = Api_drop_common('')
|
||||||
|
call assert_equal(0, &bin)
|
||||||
|
call assert_equal('', &fenc)
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xscript')
|
||||||
|
bwipe Xtextfile
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_api_drop_newwin_bin()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let buf = Api_drop_common(',{"bin":1}')
|
||||||
|
call assert_equal(1, &bin)
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xscript')
|
||||||
|
bwipe Xtextfile
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_api_drop_newwin_binary()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let buf = Api_drop_common(',{"binary":1}')
|
||||||
|
call assert_equal(1, &bin)
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xscript')
|
||||||
|
bwipe Xtextfile
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_api_drop_newwin_nobin()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
set binary
|
||||||
|
let buf = Api_drop_common(',{"nobin":1}')
|
||||||
|
call assert_equal(0, &bin)
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xscript')
|
||||||
|
bwipe Xtextfile
|
||||||
|
set nobinary
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_api_drop_newwin_nobinary()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
set binary
|
||||||
|
let buf = Api_drop_common(',{"nobinary":1}')
|
||||||
|
call assert_equal(0, &bin)
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xscript')
|
||||||
|
bwipe Xtextfile
|
||||||
|
set nobinary
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_api_drop_newwin_ff()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let buf = Api_drop_common(',{"ff":"dos"}')
|
||||||
|
call assert_equal("dos", &ff)
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xscript')
|
||||||
|
bwipe Xtextfile
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_api_drop_newwin_fileformat()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let buf = Api_drop_common(',{"fileformat":"dos"}')
|
||||||
|
call assert_equal("dos", &ff)
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xscript')
|
||||||
|
bwipe Xtextfile
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_api_drop_newwin_enc()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let buf = Api_drop_common(',{"enc":"utf-16"}')
|
||||||
|
call assert_equal("utf-16", &fenc)
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xscript')
|
||||||
|
bwipe Xtextfile
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_api_drop_newwin_encoding()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let buf = Api_drop_common(',{"encoding":"utf-16"}')
|
||||||
|
call assert_equal("utf-16", &fenc)
|
||||||
|
|
||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
call delete('Xscript')
|
call delete('Xscript')
|
||||||
|
@ -762,6 +762,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1660,
|
||||||
/**/
|
/**/
|
||||||
1659,
|
1659,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user