mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
buffer: use aucmd_prepbuf() instead of switch_to_win_for_buf()
This commit is contained in:
parent
2816bc8620
commit
f5d5da3917
@ -380,8 +380,6 @@ void nvim_buf_set_lines(uint64_t channel_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
win_T *save_curwin = NULL;
|
|
||||||
tabpage_T *save_curtab = NULL;
|
|
||||||
size_t new_len = replacement.size;
|
size_t new_len = replacement.size;
|
||||||
size_t old_len = (size_t)(end - start);
|
size_t old_len = (size_t)(end - start);
|
||||||
ptrdiff_t extra = 0; // lines added to text, can be negative
|
ptrdiff_t extra = 0; // lines added to text, can be negative
|
||||||
@ -397,8 +395,8 @@ void nvim_buf_set_lines(uint64_t channel_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
try_start();
|
try_start();
|
||||||
bufref_T save_curbuf = { NULL, 0, 0 };
|
aco_save_T aco;
|
||||||
switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
|
aucmd_prepbuf(&aco, (buf_T *)buf);
|
||||||
|
|
||||||
if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) {
|
if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) {
|
||||||
api_set_error(err, kErrorTypeException, "Failed to save undo information");
|
api_set_error(err, kErrorTypeException, "Failed to save undo information");
|
||||||
@ -465,27 +463,21 @@ void nvim_buf_set_lines(uint64_t channel_id,
|
|||||||
// changed range, and move any in the remainder of the buffer.
|
// changed range, and move any in the remainder of the buffer.
|
||||||
// Only adjust marks if we managed to switch to a window that holds
|
// Only adjust marks if we managed to switch to a window that holds
|
||||||
// the buffer, otherwise line numbers will be invalid.
|
// the buffer, otherwise line numbers will be invalid.
|
||||||
if (save_curbuf.br_buf == NULL) {
|
mark_adjust((linenr_T)start,
|
||||||
mark_adjust((linenr_T)start,
|
(linenr_T)(end - 1),
|
||||||
(linenr_T)(end - 1),
|
MAXLNUM,
|
||||||
MAXLNUM,
|
(long)extra,
|
||||||
(long)extra,
|
false);
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra, true);
|
changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra, true);
|
||||||
|
|
||||||
if (save_curbuf.br_buf == NULL) {
|
|
||||||
fix_cursor((linenr_T)start, (linenr_T)end, (linenr_T)extra);
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
for (size_t i = 0; i < new_len; i++) {
|
for (size_t i = 0; i < new_len; i++) {
|
||||||
xfree(lines[i]);
|
xfree(lines[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree(lines);
|
xfree(lines);
|
||||||
restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
|
aucmd_restbuf(&aco);
|
||||||
try_end(err);
|
try_end(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1109,28 +1101,6 @@ free_exit:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if deleting lines made the cursor position invalid.
|
|
||||||
// Changed the lines from "lo" to "hi" and added "extra" lines (negative if
|
|
||||||
// deleted).
|
|
||||||
static void fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
|
|
||||||
{
|
|
||||||
if (curwin->w_cursor.lnum >= lo) {
|
|
||||||
// Adjust the cursor position if it's in/after the changed
|
|
||||||
// lines.
|
|
||||||
if (curwin->w_cursor.lnum >= hi) {
|
|
||||||
curwin->w_cursor.lnum += extra;
|
|
||||||
check_cursor_col();
|
|
||||||
} else if (extra < 0) {
|
|
||||||
curwin->w_cursor.lnum = lo;
|
|
||||||
check_cursor();
|
|
||||||
} else {
|
|
||||||
check_cursor_col();
|
|
||||||
}
|
|
||||||
changed_cline_bef_curs();
|
|
||||||
}
|
|
||||||
invalidate_botline();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalizes 0-based indexes to buffer line numbers
|
// Normalizes 0-based indexes to buffer line numbers
|
||||||
static int64_t normalize_index(buf_T *buf, int64_t index, bool *oob)
|
static int64_t normalize_index(buf_T *buf, int64_t index, bool *oob)
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "nvim/edit.h"
|
#include "nvim/edit.h"
|
||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
#include "nvim/eval/typval.h"
|
#include "nvim/eval/typval.h"
|
||||||
|
#include "nvim/fileio.h"
|
||||||
#include "nvim/option.h"
|
#include "nvim/option.h"
|
||||||
#include "nvim/state.h"
|
#include "nvim/state.h"
|
||||||
#include "nvim/syntax.h"
|
#include "nvim/syntax.h"
|
||||||
@ -978,11 +979,12 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (scratch) {
|
if (scratch) {
|
||||||
WITH_BUFFER(buf, {
|
aco_save_T aco;
|
||||||
set_option_value("bh", 0L, "hide", OPT_LOCAL);
|
aucmd_prepbuf(&aco, buf);
|
||||||
set_option_value("bt", 0L, "nofile", OPT_LOCAL);
|
set_option_value("bh", 0L, "hide", OPT_LOCAL);
|
||||||
set_option_value("swf", 0L, NULL, OPT_LOCAL);
|
set_option_value("bt", 0L, "nofile", OPT_LOCAL);
|
||||||
});
|
set_option_value("swf", 0L, NULL, OPT_LOCAL);
|
||||||
|
aucmd_restbuf(&aco);
|
||||||
}
|
}
|
||||||
return buf->b_fnum;
|
return buf->b_fnum;
|
||||||
}
|
}
|
||||||
|
@ -63,35 +63,6 @@ enum bfa_values {
|
|||||||
# include "buffer.h.generated.h"
|
# include "buffer.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Find a window that contains "buf" and switch to it.
|
|
||||||
// If there is no such window, use the current window and change "curbuf".
|
|
||||||
// Caller must initialize save_curbuf to NULL.
|
|
||||||
// restore_win_for_buf() MUST be called later!
|
|
||||||
static inline void switch_to_win_for_buf(buf_T *buf,
|
|
||||||
win_T **save_curwinp,
|
|
||||||
tabpage_T **save_curtabp,
|
|
||||||
bufref_T *save_curbuf)
|
|
||||||
{
|
|
||||||
win_T *wp;
|
|
||||||
tabpage_T *tp;
|
|
||||||
|
|
||||||
if (!find_win_for_buf(buf, &wp, &tp)
|
|
||||||
|| switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL) {
|
|
||||||
switch_buffer(save_curbuf, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void restore_win_for_buf(win_T *save_curwin,
|
|
||||||
tabpage_T *save_curtab,
|
|
||||||
bufref_T *save_curbuf)
|
|
||||||
{
|
|
||||||
if (save_curbuf->br_buf == NULL) {
|
|
||||||
restore_win(save_curwin, save_curtab, true);
|
|
||||||
} else {
|
|
||||||
restore_buffer(save_curbuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void buf_set_changedtick(buf_T *const buf,
|
static inline void buf_set_changedtick(buf_T *const buf,
|
||||||
const varnumber_T changedtick)
|
const varnumber_T changedtick)
|
||||||
REAL_FATTR_NONNULL_ALL REAL_FATTR_ALWAYS_INLINE;
|
REAL_FATTR_NONNULL_ALL REAL_FATTR_ALWAYS_INLINE;
|
||||||
@ -145,15 +116,4 @@ static inline void buf_inc_changedtick(buf_T *const buf)
|
|||||||
buf_set_changedtick(buf, buf_get_changedtick(buf) + 1);
|
buf_set_changedtick(buf, buf_get_changedtick(buf) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WITH_BUFFER(b, code) \
|
|
||||||
do { \
|
|
||||||
win_T *save_curwin = NULL; \
|
|
||||||
tabpage_T *save_curtab = NULL; \
|
|
||||||
bufref_T save_curbuf = { NULL, 0, 0 }; \
|
|
||||||
switch_to_win_for_buf(b, &save_curwin, &save_curtab, &save_curbuf); \
|
|
||||||
code; \
|
|
||||||
restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#endif // NVIM_BUFFER_H
|
#endif // NVIM_BUFFER_H
|
||||||
|
@ -1112,11 +1112,15 @@ static void refresh_terminal(Terminal *term)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long ml_before = buf->b_ml.ml_line_count;
|
long ml_before = buf->b_ml.ml_line_count;
|
||||||
WITH_BUFFER(buf, {
|
|
||||||
refresh_size(term, buf);
|
// refresh_ functions assume the terminal buffer is current
|
||||||
refresh_scrollback(term, buf);
|
aco_save_T aco;
|
||||||
refresh_screen(term, buf);
|
aucmd_prepbuf(&aco, buf);
|
||||||
});
|
refresh_size(term, buf);
|
||||||
|
refresh_scrollback(term, buf);
|
||||||
|
refresh_screen(term, buf);
|
||||||
|
aucmd_restbuf(&aco);
|
||||||
|
|
||||||
long ml_added = buf->b_ml.ml_line_count - ml_before;
|
long ml_added = buf->b_ml.ml_line_count - ml_before;
|
||||||
adjust_topline(term, buf, ml_added);
|
adjust_topline(term, buf, ml_added);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
local helpers = require('test.functional.helpers')(after_each)
|
local helpers = require('test.functional.helpers')(after_each)
|
||||||
|
local Screen = require('test.functional.ui.screen')
|
||||||
local clear, nvim, buffer = helpers.clear, helpers.nvim, helpers.buffer
|
local clear, nvim, buffer = helpers.clear, helpers.nvim, helpers.buffer
|
||||||
local curbuf, curwin, eq = helpers.curbuf, helpers.curwin, helpers.eq
|
local curbuf, curwin, eq = helpers.curbuf, helpers.curwin, helpers.eq
|
||||||
local curbufmeths, ok = helpers.curbufmeths, helpers.ok
|
local curbufmeths, ok = helpers.curbufmeths, helpers.ok
|
||||||
|
local meths = helpers.meths
|
||||||
local funcs = helpers.funcs
|
local funcs = helpers.funcs
|
||||||
local request = helpers.request
|
local request = helpers.request
|
||||||
local exc_exec = helpers.exc_exec
|
local exc_exec = helpers.exc_exec
|
||||||
@ -11,6 +13,7 @@ local NIL = helpers.NIL
|
|||||||
local meth_pcall = helpers.meth_pcall
|
local meth_pcall = helpers.meth_pcall
|
||||||
local command = helpers.command
|
local command = helpers.command
|
||||||
local bufmeths = helpers.bufmeths
|
local bufmeths = helpers.bufmeths
|
||||||
|
local feed = helpers.feed
|
||||||
|
|
||||||
describe('api/buf', function()
|
describe('api/buf', function()
|
||||||
before_each(clear)
|
before_each(clear)
|
||||||
@ -299,6 +302,38 @@ describe('api/buf', function()
|
|||||||
local retval = exc_exec("call nvim_buf_set_lines(1, 0, 1, v:false, ['test'])")
|
local retval = exc_exec("call nvim_buf_set_lines(1, 0, 1, v:false, ['test'])")
|
||||||
eq(0, retval)
|
eq(0, retval)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("set_lines of invisible buffer doesn't move cursor in current window", function()
|
||||||
|
local screen = Screen.new(20, 5)
|
||||||
|
screen:set_default_attr_ids({
|
||||||
|
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
||||||
|
[2] = {bold = true},
|
||||||
|
})
|
||||||
|
screen:attach()
|
||||||
|
|
||||||
|
insert([[
|
||||||
|
Who would win?
|
||||||
|
A real window
|
||||||
|
with proper text]])
|
||||||
|
local buf = meths.create_buf(false,true)
|
||||||
|
screen:expect([[
|
||||||
|
Who would win? |
|
||||||
|
A real window |
|
||||||
|
with proper tex^t |
|
||||||
|
{1:~ }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
|
||||||
|
meths.buf_set_lines(buf, 0, -1, true, {'or some', 'scratchy text'})
|
||||||
|
feed('i') -- provoke redraw
|
||||||
|
screen:expect([[
|
||||||
|
Who would win? |
|
||||||
|
A real window |
|
||||||
|
with proper tex^t |
|
||||||
|
{1:~ }|
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('get_offset', function()
|
describe('get_offset', function()
|
||||||
|
@ -1359,6 +1359,9 @@ describe('API', function()
|
|||||||
eq({id=1}, meths.get_current_buf())
|
eq({id=1}, meths.get_current_buf())
|
||||||
|
|
||||||
local screen = Screen.new(20, 4)
|
local screen = Screen.new(20, 4)
|
||||||
|
screen:set_default_attr_ids({
|
||||||
|
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
||||||
|
})
|
||||||
screen:attach()
|
screen:attach()
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -1373,7 +1376,7 @@ describe('API', function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Visiting a scratch-buffer DOES change its properties.
|
-- Visiting a scratch-buffer DOES NOT change its properties.
|
||||||
--
|
--
|
||||||
meths.set_current_buf(edited_buf)
|
meths.set_current_buf(edited_buf)
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
@ -1381,12 +1384,19 @@ describe('API', function()
|
|||||||
{1:~ }|
|
{1:~ }|
|
||||||
{1:~ }|
|
{1:~ }|
|
||||||
|
|
|
|
||||||
]], {
|
]])
|
||||||
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
eq('nofile', meths.buf_get_option(edited_buf, 'buftype'))
|
||||||
})
|
eq('hide', meths.buf_get_option(edited_buf, 'bufhidden'))
|
||||||
eq('', meths.buf_get_option(edited_buf, 'buftype'))
|
|
||||||
eq('', meths.buf_get_option(edited_buf, 'bufhidden'))
|
|
||||||
eq(false, meths.buf_get_option(edited_buf, 'swapfile'))
|
eq(false, meths.buf_get_option(edited_buf, 'swapfile'))
|
||||||
|
|
||||||
|
-- scratch buffer can be wiped without error
|
||||||
|
command('bwipe')
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
@ -504,7 +504,7 @@ describe('floating windows', function()
|
|||||||
local win = meths.open_win(buf, false, 15, 4, {relative='editor', row=2, col=10})
|
local win = meths.open_win(buf, false, 15, 4, {relative='editor', row=2, col=10})
|
||||||
meths.win_set_option(win , 'winhl', 'Normal:PMenu')
|
meths.win_set_option(win , 'winhl', 'Normal:PMenu')
|
||||||
local expected_pos = {
|
local expected_pos = {
|
||||||
[3]={{id=1001}, 'NW', 1, 2, 10, true},
|
[4]={{id=1002}, 'NW', 1, 2, 10, true},
|
||||||
}
|
}
|
||||||
if multigrid then
|
if multigrid then
|
||||||
screen:expect{grid=[[
|
screen:expect{grid=[[
|
||||||
@ -523,7 +523,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:such }|
|
{1:such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -555,7 +555,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:such }|
|
{1:such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -583,7 +583,7 @@ describe('floating windows', function()
|
|||||||
^ |
|
^ |
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:such }|
|
{1:such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -608,7 +608,7 @@ describe('floating windows', function()
|
|||||||
## grid 2
|
## grid 2
|
||||||
^ |
|
^ |
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:such }|
|
{1:such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -631,7 +631,7 @@ describe('floating windows', function()
|
|||||||
## grid 2
|
## grid 2
|
||||||
|
|
|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:such }|
|
{1:such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:^float }|
|
{1:^float }|
|
||||||
@ -663,7 +663,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:such }|
|
{1:such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:^float }|
|
{1:^float }|
|
||||||
@ -700,7 +700,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:^such }|
|
{1:^such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -735,7 +735,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:^such }|
|
{1:^such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -770,7 +770,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:^such }|
|
{1:^such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -805,7 +805,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:^such }|
|
{1:^such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -840,7 +840,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:^such }|
|
{1:^such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -875,7 +875,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:^such }|
|
{1:^such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -910,7 +910,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:^such }|
|
{1:^such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -945,7 +945,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:^such }|
|
{1:^such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -971,7 +971,7 @@ describe('floating windows', function()
|
|||||||
|
|
|
|
||||||
## grid 2
|
## grid 2
|
||||||
|
|
|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:^such }|
|
{1:^such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
@ -1001,7 +1001,7 @@ describe('floating windows', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
## grid 3
|
## grid 4
|
||||||
{1:^such }|
|
{1:^such }|
|
||||||
{1:very }|
|
{1:very }|
|
||||||
{1:float }|
|
{1:float }|
|
||||||
|
Loading…
Reference in New Issue
Block a user