aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/change.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/change.c')
-rw-r--r--src/nvim/change.c237
1 files changed, 116 insertions, 121 deletions
diff --git a/src/nvim/change.c b/src/nvim/change.c
index c0183d4317..4ac5edeaa9 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -12,16 +12,17 @@
#include "nvim/diff.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/extmark.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/mark.h"
-#include "nvim/extmark.h"
#include "nvim/memline.h"
#include "nvim/misc1.h"
#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/plines.h"
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/state.h"
@@ -40,25 +41,25 @@
/// "col" is the column for the message; non-zero when in insert mode and
/// 'showmode' is on.
/// Careful: may trigger autocommands that reload the buffer.
-void change_warning(int col)
+void change_warning(buf_T *buf, int col)
{
static char *w_readonly = N_("W10: Warning: Changing a readonly file");
- if (curbuf->b_did_warn == false
+ if (buf->b_did_warn == false
&& curbufIsChanged() == 0
&& !autocmd_busy
- && curbuf->b_p_ro) {
- curbuf_lock++;
- apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, false, curbuf);
- curbuf_lock--;
- if (!curbuf->b_p_ro) {
- return;
+ && buf->b_p_ro) {
+ buf->b_ro_locked++;
+ apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, false, buf);
+ buf->b_ro_locked--;
+ if (!buf->b_p_ro) {
+ return;
}
// Do what msg() does, but with a column offset if the warning should
// be after the mode message.
msg_start();
if (msg_row == Rows - 1) {
- msg_col = col;
+ msg_col = col;
}
msg_source(HL_ATTR(HLF_W));
msg_ext_set_kind("wmsg");
@@ -70,10 +71,10 @@ void change_warning(int col)
ui_flush();
os_delay(1002L, true); // give the user time to think about it
}
- curbuf->b_did_warn = true;
+ buf->b_did_warn = true;
redraw_cmdline = false; // don't redraw and erase the message
if (msg_row < Rows - 1) {
- showmode();
+ showmode();
}
}
}
@@ -91,14 +92,13 @@ void changed(void)
// Give a warning about changing a read-only file. This may also
// check-out the file, thus change "curbuf"!
- change_warning(0);
+ change_warning(curbuf, 0);
// Create a swap file if that is wanted.
// Don't do this for "nofile" and "nowrite" buffer types.
if (curbuf->b_may_swap
- && !bt_dontwrite(curbuf)
- ) {
- int save_need_wait_return = need_wait_return;
+ && !bt_dontwrite(curbuf)) {
+ bool save_need_wait_return = need_wait_return;
need_wait_return = false;
ml_open_file(curbuf);
@@ -139,11 +139,10 @@ void changed_internal(void)
/// Common code for when a change was made.
/// See changed_lines() for the arguments.
/// Careful: may trigger autocommands that reload the buffer.
-static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
- long xtra)
+static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra)
{
int i;
- pos_T *p;
+ pos_T *p;
int add;
// mark the buffer as modified
@@ -161,18 +160,18 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
// don't have an entry yet.
if (curbuf->b_new_change || curbuf->b_changelistlen == 0) {
if (curbuf->b_changelistlen == 0) {
- add = true;
+ add = true;
} else {
// Don't create a new entry when the line number is the same
// as the last one and the column is not too far away. Avoids
// creating many entries for typing "xxxxx".
p = &curbuf->b_changelist[curbuf->b_changelistlen - 1].mark;
if (p->lnum != lnum) {
- add = true;
+ add = true;
} else {
int cols = comp_textwidth(false);
if (cols == 0) {
- cols = 79;
+ cols = 79;
}
add = (p->col + cols < col || col + cols < p->col);
}
@@ -218,7 +217,7 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
if (wp->w_buffer == curbuf) {
// Mark this window to be redrawn later.
if (wp->w_redr_type < VALID) {
- wp->w_redr_type = VALID;
+ wp->w_redr_type = VALID;
}
// Check if a change in the buffer has invalidated the cached
@@ -234,11 +233,11 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
// inserting lines just above a closed fold. */
bool folded = hasFoldingWin(wp, lnum, &lnum, NULL, false, NULL);
if (wp->w_cursor.lnum == lnum) {
- wp->w_cline_folded = folded;
+ wp->w_cline_folded = folded;
}
folded = hasFoldingWin(wp, lnume, NULL, &lnume, false, NULL);
if (wp->w_cursor.lnum == lnume) {
- wp->w_cline_folded = folded;
+ wp->w_cline_folded = folded;
}
// If the changed line is in a range of previously folded lines,
@@ -246,14 +245,14 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
if (wp->w_cursor.lnum <= lnum) {
i = find_wl_entry(wp, lnum);
if (i >= 0 && wp->w_cursor.lnum > wp->w_lines[i].wl_lnum) {
- changed_line_abv_curs_win(wp);
+ changed_line_abv_curs_win(wp);
}
}
if (wp->w_cursor.lnum > lnum) {
- changed_line_abv_curs_win(wp);
+ changed_line_abv_curs_win(wp);
} else if (wp->w_cursor.lnum == lnum && wp->w_cursor.col >= col) {
- changed_cline_bef_curs_win(wp);
+ changed_cline_bef_curs_win(wp);
}
if (wp->w_botline >= lnum) {
// Assume that botline doesn't change (inserted lines make
@@ -290,13 +289,21 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
set_topline(wp, wp->w_topline);
}
- // Relative numbering may require updating more. Cursor line
- // highlighting probably needs to be updated if it's below the
- // change.
- if (wp->w_p_rnu
- || (wp->w_p_cul && lnum <= wp->w_last_cursorline)) {
+ // Relative numbering may require updating more.
+ if (wp->w_p_rnu) {
redraw_later(wp, SOME_VALID);
}
+
+ // Cursor line highlighting probably need to be updated with
+ // "VALID" if it's below the change.
+ // If the cursor line is inside the change we need to redraw more.
+ if (wp->w_p_cul) {
+ if (xtra == 0) {
+ redraw_later(wp, VALID);
+ } else if (lnum <= wp->w_last_cursorline) {
+ redraw_later(wp, SOME_VALID);
+ }
+ }
}
}
@@ -318,9 +325,9 @@ static void changedOneline(buf_T *buf, linenr_T lnum)
if (buf->b_mod_set) {
// find the maximum area that must be redisplayed
if (lnum < buf->b_mod_top) {
- buf->b_mod_top = lnum;
+ buf->b_mod_top = lnum;
} else if (lnum >= buf->b_mod_bot) {
- buf->b_mod_bot = lnum + 1;
+ buf->b_mod_bot = lnum + 1;
}
} else {
// set the area that must be redisplayed to one line
@@ -352,7 +359,7 @@ void changed_bytes(linenr_T lnum, colnr_T col)
redraw_later(wp, VALID);
wlnum = diff_lnum_win(lnum, wp);
if (wlnum > 0) {
- changedOneline(wp->w_buffer, wlnum);
+ changedOneline(wp->w_buffer, wlnum);
}
}
}
@@ -454,17 +461,15 @@ void changed_lines_buf(buf_T *buf, linenr_T lnum, linenr_T lnume, long xtra)
/// When only inserting lines, "lnum" and "lnume" are equal.
/// Takes care of calling changed() and updating b_mod_*.
/// Careful: may trigger autocommands that reload the buffer.
-void
-changed_lines(
- linenr_T lnum, // first line with change
- colnr_T col, // column in first line with change
- linenr_T lnume, // line below last changed line
- long xtra, // number of extra lines (negative when deleting)
- bool do_buf_event // some callers like undo/redo call changed_lines()
- // and then increment changedtick *again*. This flag
- // allows these callers to send the nvim_buf_lines_event
- // events after they're done modifying changedtick.
-)
+///
+/// @param lnum first line with change
+/// @param col column in first line with change
+/// @param lnume line below last changed line
+/// @param xtra number of extra lines (negative when deleting)
+/// @param do_buf_event some callers like undo/redo call changed_lines() and
+/// then increment changedtick *again*. This flag allows these callers to send
+/// the nvim_buf_lines_event events after they're done modifying changedtick.
+void changed_lines(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra, bool do_buf_event)
{
changed_lines_buf(curbuf, lnum, lnume, xtra);
@@ -585,9 +590,9 @@ void ins_char_bytes(char_u *buf, size_t charlen)
// cells. May result in adding spaces to fill a gap.
colnr_T vcol;
getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL);
- colnr_T new_vcol = vcol + chartabsize(buf, vcol);
+ colnr_T new_vcol = vcol + win_chartabsize(curwin, buf, vcol);
while (oldp[col + oldlen] != NUL && vcol < new_vcol) {
- vcol += chartabsize(oldp + col + oldlen, vcol);
+ vcol += win_chartabsize(curwin, oldp + col + oldlen, vcol);
// Don't need to remove a TAB that takes us to the right
// position.
if (vcol > new_vcol && oldp[col + oldlen] == TAB) {
@@ -600,7 +605,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
}
}
curwin->w_p_list = old_list;
- } else if (oldp[col] != NUL) {
+ } else if (oldp[col] != NUL) {
// normal replace
oldlen = (size_t)(*mb_ptr2len)(oldp + col);
}
@@ -648,8 +653,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
// show the match for right parens and braces.
if (p_sm && (State & INSERT)
&& msg_silent == 0
- && !ins_compl_active()
- ) {
+ && !ins_compl_active()) {
showmatch(utf_ptr2char(buf));
}
@@ -665,7 +669,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
/// Caller must have prepared for undo.
void ins_str(char_u *s)
{
- char_u *oldp, *newp;
+ char_u *oldp, *newp;
int newlen = (int)STRLEN(s);
int oldlen;
colnr_T col;
@@ -712,7 +716,7 @@ int del_chars(long count, int fixpos)
{
int bytes = 0;
long i;
- char_u *p;
+ char_u *p;
int l;
p = get_cursor_pos_ptr();
@@ -779,11 +783,10 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
int movelen = oldlen - col - count + 1; // includes trailing NUL
if (movelen <= 1) {
// If we just took off the last character of a non-blank line, and
- // fixpos is TRUE, we don't want to end up positioned at the NUL,
+ // fixpos is true, we don't want to end up positioned at the NUL,
// unless "restart_edit" is set or 'virtualedit' contains "onemore".
if (col > 0 && fixpos && restart_edit == 0
- && (ve_flags & VE_ONEMORE) == 0
- ) {
+ && (ve_flags & VE_ONEMORE) == 0) {
curwin->w_cursor.col--;
curwin->w_cursor.coladd = 0;
curwin->w_cursor.col -= utf_head_off(oldp, oldp + curwin->w_cursor.col);
@@ -947,12 +950,10 @@ int copy_indent(int size, char_u *src)
/// "second_line_indent": indent for after ^^D in Insert mode or if flag
/// OPENLINE_COM_LIST
///
+/// @param dir FORWARD or BACKWARD
+///
/// @return true on success, false on failure
-int open_line(
- int dir, // FORWARD or BACKWARD
- int flags,
- int second_line_indent
-)
+int open_line(int dir, int flags, int second_line_indent)
{
char_u *next_line = NULL; // copy of the next line
char_u *p_extra = NULL; // what goes to next line
@@ -994,9 +995,9 @@ int open_line(
// the line, replacing what was there before and pushing the right
// stuff onto the replace stack. -- webb.
if (curwin->w_cursor.lnum < orig_line_count) {
- next_line = vim_strsave(ml_get(curwin->w_cursor.lnum + 1));
+ next_line = vim_strsave(ml_get(curwin->w_cursor.lnum + 1));
} else {
- next_line = vim_strsave((char_u *)"");
+ next_line = vim_strsave((char_u *)"");
}
// In VREPLACE mode, a NL replaces the rest of the line, and starts
@@ -1014,8 +1015,7 @@ int open_line(
}
if ((State & INSERT)
- && !(State & VREPLACE_FLAG)
- ) {
+ && !(State & VREPLACE_FLAG)) {
p_extra = saved_line + curwin->w_cursor.col;
if (do_si) { // need first char after new line break
p = skipwhite(p_extra);
@@ -1034,14 +1034,13 @@ int open_line(
// the prior line, and it should be truncated. Do this even if 'ai' is not
// set because automatically inserting a comment leader also sets did_ai.
if (dir == FORWARD && did_ai) {
- trunc_line = true;
+ trunc_line = true;
}
// If 'autoindent' and/or 'smartindent' is set, try to figure out what
// indent to use for the new line.
if (curbuf->b_p_ai
- || do_si
- ) {
+ || do_si) {
// count white space on current line
newindent = get_indent_str_vtab(saved_line,
curbuf->b_p_ts,
@@ -1057,15 +1056,15 @@ int open_line(
// "if (condition) {"
if (!trunc_line && do_si && *saved_line != NUL
&& (p_extra == NULL || first_char != '{')) {
- char_u *ptr;
+ char_u *ptr;
char_u last_char;
old_cursor = curwin->w_cursor;
ptr = saved_line;
if (flags & OPENLINE_DO_COM) {
- lead_len = get_leader_len(ptr, NULL, false, true);
+ lead_len = get_leader_len(ptr, NULL, false, true);
} else {
- lead_len = 0;
+ lead_len = 0;
}
if (dir == FORWARD) {
// Skip preprocessor directives, unless they are
@@ -1110,17 +1109,17 @@ int open_line(
// Find last non-blank in line
p = ptr + STRLEN(ptr) - 1;
while (p > ptr && ascii_iswhite(*p)) {
- p--;
+ p--;
}
last_char = *p;
// find the character just before the '{' or ';'
if (last_char == '{' || last_char == ';') {
if (p > ptr) {
- p--;
+ p--;
}
while (p > ptr && ascii_iswhite(*p)) {
- p--;
+ p--;
}
}
// Try to catch lines that are split over multiple
@@ -1142,12 +1141,12 @@ int open_line(
if (last_char == '{') {
did_si = true; // do indent
no_si = true; // don't delete it when '{' typed
- // Look for "if" and the like, use 'cinwords'.
- // Don't do this if the previous line ended in ';' or
- // '}'.
+ // Look for "if" and the like, use 'cinwords'.
+ // Don't do this if the previous line ended in ';' or
+ // '}'.
} else if (last_char != ';' && last_char != '}'
&& cin_is_cinword(ptr)) {
- did_si = true;
+ did_si = true;
}
}
} else { // dir == BACKWARD
@@ -1196,15 +1195,15 @@ int open_line(
lead_len = 0;
}
if (lead_len > 0) {
- char_u *lead_repl = NULL; // replaces comment leader
+ char_u *lead_repl = NULL; // replaces comment leader
int lead_repl_len = 0; // length of *lead_repl
char_u lead_middle[COM_MAX_LEN]; // middle-comment string
char_u lead_end[COM_MAX_LEN]; // end-comment string
- char_u *comment_end = NULL; // where lead_end has been found
+ char_u *comment_end = NULL; // where lead_end has been found
int extra_space = false; // append extra space
int current_flag;
int require_blank = false; // requires blank after middle
- char_u *p2;
+ char_u *p2;
// If the comment leader has the start, middle or end flag, it may not
// be used or may be replaced with the middle leader.
@@ -1295,7 +1294,7 @@ int open_line(
// Doing "O" on the end of a comment inserts the middle leader.
// Find the string for the middle leader, searching backwards.
while (p > curbuf->b_p_com && *p != ',') {
- p--;
+ p--;
}
for (lead_repl = p; lead_repl > curbuf->b_p_com
&& lead_repl[-1] != ':'; lead_repl--) {
@@ -1309,13 +1308,13 @@ int open_line(
// Check whether we allow automatic ending of comments
for (p2 = p; *p2 && *p2 != ':'; p2++) {
if (*p2 == COM_AUTO_END) {
- end_comment_pending = -1; // means we want to set it
+ end_comment_pending = -1; // means we want to set it
}
}
if (end_comment_pending == -1) {
// Find last character in end-comment string
while (*p2 && *p2 != ',') {
- p2++;
+ p2++;
}
end_comment_pending = p2[-1];
}
@@ -1325,7 +1324,7 @@ int open_line(
// Comment leader for first line only: Don't repeat leader
// when using "O", blank out leader when using "o".
if (dir == BACKWARD) {
- lead_len = 0;
+ lead_len = 0;
} else {
lead_repl = (char_u *)"";
lead_repl_len = 0;
@@ -1336,11 +1335,11 @@ int open_line(
if (lead_len > 0) {
// allocate buffer (may concatenate p_extra later)
int bytes = lead_len
- + lead_repl_len
- + extra_space
- + extra_len
- + (second_line_indent > 0 ? second_line_indent : 0)
- + 1;
+ + lead_repl_len
+ + extra_space
+ + extra_len
+ + (second_line_indent > 0 ? second_line_indent : 0)
+ + 1;
assert(bytes >= 0);
leader = xmalloc((size_t)bytes);
allocated = leader; // remember to free it later
@@ -1354,11 +1353,11 @@ int open_line(
for (p = lead_flags; *p != NUL && *p != ':'; ) {
if (*p == COM_RIGHT || *p == COM_LEFT) {
- c = *p++;
+ c = *p++;
} else if (ascii_isdigit(*p) || *p == '-') {
- off = getdigits_int(&p, true, 0);
+ off = getdigits_int(&p, true, 0);
} else {
- p++;
+ p++;
}
}
if (c == COM_RIGHT) { // right adjusted leader
@@ -1374,7 +1373,7 @@ int open_line(
int repl_size = vim_strnsize(lead_repl,
lead_repl_len);
int old_size = 0;
- char_u *endp = p;
+ char_u *endp = p;
int l;
while (old_size < repl_size && p > leader) {
@@ -1383,14 +1382,14 @@ int open_line(
}
l = lead_repl_len - (int)(endp - p);
if (l != 0) {
- memmove(endp + l, endp,
- (size_t)((leader + lead_len) - endp));
+ memmove(endp + l, endp,
+ (size_t)((leader + lead_len) - endp));
}
lead_len += l;
}
memmove(p, lead_repl, (size_t)lead_repl_len);
if (p + lead_repl_len > leader + lead_len) {
- p[lead_repl_len] = NUL;
+ p[lead_repl_len] = NUL;
}
// blank-out any other chars from the old leader.
@@ -1408,7 +1407,7 @@ int open_line(
lead_len -= l;
*p = ' ';
} else if (!ascii_iswhite(*p)) {
- *p = ' ';
+ *p = ' ';
}
}
} else { // left adjusted leader
@@ -1425,12 +1424,12 @@ int open_line(
for (i = 0; i < lead_len && p[i] != NUL; i += l) {
l = (*mb_ptr2len)(p + i);
if (vim_strnsize(p, i + l) > repl_size) {
- break;
+ break;
}
}
if (i != lead_repl_len) {
- memmove(p + lead_repl_len, p + i,
- (size_t)(lead_len - i - (p - leader)));
+ memmove(p + lead_repl_len, p + i,
+ (size_t)(lead_len - i - (p - leader)));
lead_len += lead_repl_len - i;
}
}
@@ -1467,8 +1466,7 @@ int open_line(
// Recompute the indent, it may have changed.
if (curbuf->b_p_ai
- || do_si
- ) {
+ || do_si) {
newindent = get_indent_str_vtab(leader,
curbuf->b_p_ts,
curbuf->b_p_vts_array, false);
@@ -1488,7 +1486,7 @@ int open_line(
&& leader[lead_len - 1] == ' ') {
// Don't do it when there is a tab before the space
if (vim_strchr(skipwhite(leader), '\t') != NULL) {
- break;
+ break;
}
lead_len--;
off--;
@@ -1497,7 +1495,7 @@ int open_line(
// If the leader ends in white space, don't add an
// extra space
if (lead_len > 0 && ascii_iswhite(leader[lead_len - 1])) {
- extra_space = false;
+ extra_space = false;
}
leader[lead_len] = NUL;
}
@@ -1512,8 +1510,7 @@ int open_line(
// if a new indent will be set below, remove the indent that
// is in the comment leader
if (newindent
- || did_si
- ) {
+ || did_si) {
while (lead_len && ascii_iswhite(*leader)) {
lead_len--;
newcol--;
@@ -1550,7 +1547,7 @@ int open_line(
// When in REPLACE mode, put the deleted blanks on the replace stack,
// preceded by a NUL, so they can be put back when a BS is entered.
if (REPLACE_NORMAL(State)) {
- replace_push(NUL); // end of extra blanks
+ replace_push(NUL); // end of extra blanks
}
if (curbuf->b_p_ai || (flags & OPENLINE_DELSPACES)) {
while ((*p_extra == ' ' || *p_extra == '\t')
@@ -1568,7 +1565,7 @@ int open_line(
}
if (p_extra == NULL) {
- p_extra = (char_u *)""; // append empty line
+ p_extra = (char_u *)""; // append empty line
}
// concatenate leader and p_extra, if there is a leader
@@ -1632,8 +1629,7 @@ int open_line(
inhibit_delete_count++;
if (newindent
- || did_si
- ) {
+ || did_si) {
curwin->w_cursor.lnum++;
if (did_si) {
int sw = get_sw_value(curbuf);
@@ -1697,9 +1693,8 @@ int open_line(
// TODO(vigoux): maybe there is issues there with expandtabs ?
int cols_spliced = 0;
if (new_len < curwin->w_cursor.col) {
- extmark_splice_cols(
- curbuf, (int)curwin->w_cursor.lnum - 1,
- new_len, curwin->w_cursor.col - new_len, 0, kExtmarkUndo);
+ extmark_splice_cols(curbuf, (int)curwin->w_cursor.lnum - 1,
+ new_len, curwin->w_cursor.col - new_len, 0, kExtmarkUndo);
cols_spliced = curwin->w_cursor.col - new_len;
}
@@ -1732,7 +1727,7 @@ int open_line(
}
if (did_append) {
changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L, true);
- // bail out and just get the final lenght of the line we just manipulated
+ // bail out and just get the final length of the line we just manipulated
bcount_t extra = (bcount_t)STRLEN(ml_get(curwin->w_cursor.lnum));
extmark_splice(curbuf, (int)curwin->w_cursor.lnum-1, 0,
0, 0, 0, 1, 0, 1+extra, kExtmarkUndo);
@@ -1806,7 +1801,7 @@ theend:
/// If "fixpos" is true fix the cursor position when done.
void truncate_line(int fixpos)
{
- char_u *newp;
+ char_u *newp;
linenr_T lnum = curwin->w_cursor.lnum;
colnr_T col = curwin->w_cursor.col;
@@ -1828,18 +1823,18 @@ void truncate_line(int fixpos)
/// Delete "nlines" lines at the cursor.
/// Saves the lines for undo first if "undo" is true.
-void del_lines(long nlines, int undo)
+void del_lines(long nlines, bool undo)
{
long n;
linenr_T first = curwin->w_cursor.lnum;
if (nlines <= 0) {
- return;
+ return;
}
// save the deleted lines for undo
if (undo && u_savedel(first, nlines) == FAIL) {
- return;
+ return;
}
for (n = 0; n < nlines; ) {
@@ -1852,7 +1847,7 @@ void del_lines(long nlines, int undo)
// If we delete the last line in the file, stop
if (first > curbuf->b_ml.ml_line_count) {
- break;
+ break;
}
}