summaryrefslogtreecommitdiff
path: root/data/vim/patches/8.1.0857
diff options
context:
space:
mode:
Diffstat (limited to 'data/vim/patches/8.1.0857')
-rw-r--r--data/vim/patches/8.1.08579872
1 files changed, 0 insertions, 9872 deletions
diff --git a/data/vim/patches/8.1.0857 b/data/vim/patches/8.1.0857
deleted file mode 100644
index 06d20502e..000000000
--- a/data/vim/patches/8.1.0857
+++ /dev/null
@@ -1,9872 +0,0 @@
-To: vim_dev@googlegroups.com
-Subject: Patch 8.1.0857
-Fcc: outbox
-From: Bram Moolenaar <Bram@moolenaar.net>
-Mime-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-------------
-
-Patch 8.1.0857
-Problem: Indent functionality is not separated.
-Solution: Move indent functionality into a new file. (Yegappan Lakshmanan,
- closes #3886)
-Files: Filelist, src/Make_bc5.mak, src/Make_cyg_ming.mak,
- src/Make_dice.mak, src/Make_ivc.mak, src/Make_manx.mak,
- src/Make_morph.mak, src/Make_mvc.mak, src/Make_sas.mak,
- src/Make_vms.mms, src/Makefile, src/edit.c, src/indent.c,
- src/misc1.c, src/proto.h, src/proto/edit.pro,
- src/proto/indent.pro, src/proto/misc1.pro
-
-
-*** ../vim-8.1.0856/Filelist 2019-01-26 16:20:44.256683619 +0100
---- Filelist 2019-01-31 13:43:23.348467289 +0100
-***************
-*** 49,54 ****
---- 49,55 ----
- src/gui_beval.c \
- src/hardcopy.c \
- src/hashtab.c \
-+ src/indent.c \
- src/json.c \
- src/json_test.c \
- src/kword_test.c \
-***************
-*** 175,180 ****
---- 176,182 ----
- src/proto/gui_beval.pro \
- src/proto/hardcopy.pro \
- src/proto/hashtab.pro \
-+ src/proto/indent.pro \
- src/proto/json.pro \
- src/proto/list.pro \
- src/proto/main.pro \
-*** ../vim-8.1.0856/src/Make_bc5.mak 2019-01-26 16:20:44.256683619 +0100
---- src/Make_bc5.mak 2019-01-31 13:43:23.348467289 +0100
-***************
-*** 548,553 ****
---- 548,554 ----
- $(OBJDIR)\getchar.obj \
- $(OBJDIR)\hardcopy.obj \
- $(OBJDIR)\hashtab.obj \
-+ $(OBJDIR)\indent.obj \
- $(OBJDIR)\json.obj \
- $(OBJDIR)\list.obj \
- $(OBJDIR)\main.obj \
-*** ../vim-8.1.0856/src/Make_cyg_ming.mak 2019-01-26 16:20:44.256683619 +0100
---- src/Make_cyg_ming.mak 2019-01-31 13:43:23.348467289 +0100
-***************
-*** 720,725 ****
---- 720,726 ----
- $(OUTDIR)/getchar.o \
- $(OUTDIR)/hardcopy.o \
- $(OUTDIR)/hashtab.o \
-+ $(OUTDIR)/indent.o \
- $(OUTDIR)/json.o \
- $(OUTDIR)/list.o \
- $(OUTDIR)/main.o \
-*** ../vim-8.1.0856/src/Make_dice.mak 2019-01-26 16:20:44.256683619 +0100
---- src/Make_dice.mak 2019-01-31 13:43:23.348467289 +0100
-***************
-*** 50,55 ****
---- 50,56 ----
- getchar.c \
- hardcopy.c \
- hashtab.c \
-+ indent.c \
- json.c \
- list.c \
- main.c \
-***************
-*** 108,113 ****
---- 109,115 ----
- o/getchar.o \
- o/hardcopy.o \
- o/hashtab.o \
-+ o/indent.o \
- o/json.o \
- o/list.o \
- o/main.o \
-***************
-*** 209,214 ****
---- 211,218 ----
-
- o/hashtab.o: hashtab.c $(SYMS)
-
-+ o/indent.o: indent.c $(SYMS)
-+
- o/json.o: json.c $(SYMS)
-
- o/list.o: list.c $(SYMS)
-*** ../vim-8.1.0856/src/Make_ivc.mak 2019-01-26 16:20:44.256683619 +0100
---- src/Make_ivc.mak 2019-01-31 13:43:23.348467289 +0100
-***************
-*** 234,239 ****
---- 234,240 ----
- "$(INTDIR)/getchar.obj" \
- "$(INTDIR)/hardcopy.obj" \
- "$(INTDIR)/hashtab.obj" \
-+ "$(INTDIR)/indent.obj" \
- "$(INTDIR)/json.obj" \
- "$(INTDIR)/list.obj" \
- "$(INTDIR)/main.obj" \
-***************
-*** 434,439 ****
---- 435,444 ----
- SOURCE=.\hashtab.c
- # End Source File
- # Begin Source File
-+ #
-+ SOURCE=.\indent.c
-+ # End Source File
-+ # Begin Source File
-
- SOURCE=.\gui.c
-
-*** ../vim-8.1.0856/src/Make_manx.mak 2019-01-26 16:20:44.260683581 +0100
---- src/Make_manx.mak 2019-01-31 13:43:23.348467289 +0100
-***************
-*** 60,65 ****
---- 60,66 ----
- getchar.c \
- hardcopy.c \
- hashtab.c \
-+ indent.c \
- json.c \
- list.c \
- main.c \
-***************
-*** 120,125 ****
---- 121,127 ----
- obj/getchar.o \
- obj/hardcopy.o \
- obj/hashtab.o \
-+ obj/indent.o \
- obj/json.o \
- obj/list.o \
- obj/main.o \
-***************
-*** 178,183 ****
---- 180,186 ----
- proto/getchar.pro \
- proto/hardcopy.pro \
- proto/hashtab.pro \
-+ proto/indent.pro \
- proto/json.pro \
- proto/list.pro \
- proto/main.pro \
-***************
-*** 329,334 ****
---- 332,340 ----
- obj/hashtab.o: hashtab.c
- $(CCSYM) $@ hashtab.c
-
-+ obj/indent.o: indent.c
-+ $(CCSYM) $@ indent.c
-+
- obj/json.o: json.c
- $(CCSYM) $@ json.c
-
-*** ../vim-8.1.0856/src/Make_morph.mak 2019-01-26 16:20:44.260683581 +0100
---- src/Make_morph.mak 2019-01-31 13:43:23.348467289 +0100
-***************
-*** 48,53 ****
---- 48,54 ----
- getchar.c \
- hardcopy.c \
- hashtab.c \
-+ indent.c \
- json.c \
- list.c \
- main.c \
-*** ../vim-8.1.0856/src/Make_mvc.mak 2019-01-26 16:20:44.260683581 +0100
---- src/Make_mvc.mak 2019-01-31 13:43:23.348467289 +0100
-***************
-*** 725,730 ****
---- 725,731 ----
- $(OUTDIR)\getchar.obj \
- $(OUTDIR)\hardcopy.obj \
- $(OUTDIR)\hashtab.obj \
-+ $(OUTDIR)\indent.obj \
- $(OUTDIR)\json.obj \
- $(OUTDIR)\list.obj \
- $(OUTDIR)\main.obj \
-***************
-*** 1414,1419 ****
---- 1415,1422 ----
-
- $(OUTDIR)/hashtab.obj: $(OUTDIR) hashtab.c $(INCL)
-
-+ $(OUTDIR)/indent.obj: $(OUTDIR) indent.c $(INCL)
-+
- $(OUTDIR)/gui.obj: $(OUTDIR) gui.c $(INCL) $(GUI_INCL)
-
- $(OUTDIR)/gui_beval.obj: $(OUTDIR) gui_beval.c $(INCL) $(GUI_INCL)
-***************
-*** 1645,1650 ****
---- 1648,1654 ----
- proto/getchar.pro \
- proto/hardcopy.pro \
- proto/hashtab.pro \
-+ proto/indent.pro \
- proto/json.pro \
- proto/list.pro \
- proto/main.pro \
-*** ../vim-8.1.0856/src/Make_sas.mak 2019-01-26 16:20:44.260683581 +0100
---- src/Make_sas.mak 2019-01-31 13:43:23.348467289 +0100
-***************
-*** 113,118 ****
---- 113,119 ----
- getchar.c \
- hardcopy.c \
- hashtab.c \
-+ indent.c \
- json.c \
- list.c \
- main.c \
-***************
-*** 172,177 ****
---- 173,179 ----
- getchar.o \
- hardcopy.o \
- hashtab.o \
-+ indent.o \
- json.o \
- list.o \
- main.o \
-***************
-*** 231,236 ****
---- 233,239 ----
- proto/getchar.pro \
- proto/hardcopy.pro \
- proto/hashtab.pro \
-+ proto/indent.pro \
- proto/json.pro \
- proto/list.pro \
- proto/main.pro \
-***************
-*** 368,373 ****
---- 371,378 ----
- proto/hardcopy.pro: hardcopy.c
- hashtab.o: hashtab.c
- proto/hashtab.pro: hashtab.c
-+ indent.o: indent.c
-+ proto/indent.pro: indent.c
- json.o: json.c
- proto/json.pro: json.c
- list.o: list.c
-*** ../vim-8.1.0856/src/Make_vms.mms 2019-01-26 16:20:44.260683581 +0100
---- src/Make_vms.mms 2019-01-31 13:43:23.352467260 +0100
-***************
-*** 314,320 ****
-
- SRC = arabic.c autocmd.c beval.c blob.c blowfish.c buffer.c charset.c crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c \
- evalfunc.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c if_cscope.c if_xcmdsrv.c farsi.c fileio.c fold.c \
-! getchar.c hardcopy.c hashtab.c json.c list.c main.c mark.c menu.c mbyte.c memfile.c memline.c message.c misc1.c \
- misc2.c move.c normal.c ops.c option.c popupmnu.c quickfix.c regexp.c search.c sha256.c sign.c \
- spell.c spellfile.c syntax.c tag.c term.c termlib.c textprop.c ui.c undo.c userfunc.c version.c screen.c \
- window.c os_unix.c os_vms.c pathdef.c \
---- 314,320 ----
-
- SRC = arabic.c autocmd.c beval.c blob.c blowfish.c buffer.c charset.c crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c \
- evalfunc.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c if_cscope.c if_xcmdsrv.c farsi.c fileio.c fold.c \
-! getchar.c hardcopy.c hashtab.c indent.c json.c list.c main.c mark.c menu.c mbyte.c memfile.c memline.c message.c misc1.c \
- misc2.c move.c normal.c ops.c option.c popupmnu.c quickfix.c regexp.c search.c sha256.c sign.c \
- spell.c spellfile.c syntax.c tag.c term.c termlib.c textprop.c ui.c undo.c userfunc.c version.c screen.c \
- window.c os_unix.c os_vms.c pathdef.c \
-***************
-*** 323,329 ****
-
- OBJ = arabic.obj autocmd.obj beval.obj blob.obj blowfish.obj buffer.obj charset.obj crypt.obj crypt_zip.obj dict.obj diff.obj digraph.obj \
- edit.obj eval.obj evalfunc.obj ex_cmds.obj ex_cmds2.obj ex_docmd.obj ex_eval.obj ex_getln.obj if_cscope.obj \
-! if_xcmdsrv.obj farsi.obj fileio.obj fold.obj getchar.obj hardcopy.obj hashtab.obj json.obj list.obj main.obj mark.obj \
- menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \
- move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj quickfix.obj \
- regexp.obj search.obj sha256.obj sign.obj spell.obj spellfile.obj syntax.obj tag.obj term.obj termlib.obj textprop.obj \
---- 323,329 ----
-
- OBJ = arabic.obj autocmd.obj beval.obj blob.obj blowfish.obj buffer.obj charset.obj crypt.obj crypt_zip.obj dict.obj diff.obj digraph.obj \
- edit.obj eval.obj evalfunc.obj ex_cmds.obj ex_cmds2.obj ex_docmd.obj ex_eval.obj ex_getln.obj if_cscope.obj \
-! if_xcmdsrv.obj farsi.obj fileio.obj fold.obj getchar.obj hardcopy.obj hashtab.obj indent.obj json.obj list.obj main.obj mark.obj \
- menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \
- move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj quickfix.obj \
- regexp.obj search.obj sha256.obj sign.obj spell.obj spellfile.obj syntax.obj tag.obj term.obj termlib.obj textprop.obj \
-***************
-*** 596,601 ****
---- 596,602 ----
- ascii.h keymap.h term.h macros.h option.h structs.h \
- regexp.h gui.h beval.h [.proto]gui_beval.pro ex_cmds.h proto.h \
- globals.h farsi.h arabic.h if_mzsch.h
-+ indent.obj : indent.c vim.h [.auto]config.h feature.h os_unix.h
- json.obj : json.c vim.h [.auto]config.h feature.h os_unix.h \
- ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
- [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h farsi.h \
-*** ../vim-8.1.0856/src/Makefile 2019-01-26 17:36:46.997192946 +0100
---- src/Makefile 2019-01-31 13:43:23.352467260 +0100
-***************
-*** 1599,1604 ****
---- 1598,1604 ----
- hashtab.c \
- if_cscope.c \
- if_xcmdsrv.c \
-+ indent.c \
- json.c \
- list.c \
- main.c \
-***************
-*** 1712,1717 ****
---- 1712,1718 ----
- $(HANGULIN_OBJ) \
- objects/if_cscope.o \
- objects/if_xcmdsrv.o \
-+ objects/indent.o \
- objects/list.o \
- objects/mark.o \
- objects/memline.o \
-***************
-*** 1842,1847 ****
---- 1843,1849 ----
- if_python3.pro \
- if_ruby.pro \
- if_xcmdsrv.pro \
-+ indent.pro \
- json.pro \
- list.pro \
- main.pro \
-***************
-*** 3093,3098 ****
---- 3095,3103 ----
- objects/if_tcl.o: if_tcl.c
- $(CCC_NF) $(TCL_CFLAGS) $(ALL_CFLAGS) -o $@ if_tcl.c
-
-+ objects/indent.o: indent.c
-+ $(CCC) -o $@ indent.c
-+
- objects/json.o: json.c
- $(CCC) -o $@ json.c
-
-***************
-*** 3490,3495 ****
---- 3495,3504 ----
- os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
- proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
- proto.h globals.h farsi.h arabic.h version.h
-+ objects/indent.o: indent.c vim.h protodef.h auto/config.h feature.h os_unix.h \
-+ os_mac.h ascii.h keymap.h term.h macros.h option.h beval.h structs.h \
-+ regexp.h gui.h alloc.h ex_cmds.h spell.h proto.h globals.h farsi.h \
-+ arabic.h
- objects/json.o: json.c vim.h protodef.h auto/config.h feature.h os_unix.h \
- auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
- proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
-*** ../vim-8.1.0856/src/edit.c 2019-01-26 17:28:22.220599167 +0100
---- src/edit.c 2019-01-31 13:43:23.352467260 +0100
-***************
-*** 216,224 ****
- static void replace_flush(void);
- static void replace_do_bs(int limit_col);
- static int del_char_after_col(int limit_col);
-- #ifdef FEAT_CINDENT
-- static int cindent_on(void);
-- #endif
- static void ins_reg(void);
- static void ins_ctrl_g(void);
- static void ins_ctrl_hat(void);
---- 216,221 ----
-***************
-*** 380,385 ****
---- 377,383 ----
- ins_compl_clear(); /* clear stuff for CTRL-X mode */
- #endif
-
-+ ch_log(NULL, "ENTERING Insert mode");
- /*
- * Trigger InsertEnter autocommands. Do not do this for "r<CR>" or "grx".
- */
-***************
-*** 1050,1055 ****
---- 1048,1054 ----
- if (cmdchar != 'r' && cmdchar != 'v' && c != Ctrl_C)
- ins_apply_autocmds(EVENT_INSERTLEAVE);
- did_cursorhold = FALSE;
-+ ch_log(NULL, "LEAVING Insert mode");
- return (c == Ctrl_O);
- }
- continue;
-***************
-*** 7923,8254 ****
- (void)del_char_after_col(limit_col);
- }
-
-- #ifdef FEAT_CINDENT
-- /*
-- * Return TRUE if C-indenting is on.
-- */
-- static int
-- cindent_on(void)
-- {
-- return (!p_paste && (curbuf->b_p_cin
-- # ifdef FEAT_EVAL
-- || *curbuf->b_p_inde != NUL
-- # endif
-- ));
-- }
-- #endif
--
-- #if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(PROTO)
-- /*
-- * Re-indent the current line, based on the current contents of it and the
-- * surrounding lines. Fixing the cursor position seems really easy -- I'm very
-- * confused what all the part that handles Control-T is doing that I'm not.
-- * "get_the_indent" should be get_c_indent, get_expr_indent or get_lisp_indent.
-- */
--
-- void
-- fixthisline(int (*get_the_indent)(void))
-- {
-- int amount = get_the_indent();
--
-- if (amount >= 0)
-- {
-- change_indent(INDENT_SET, amount, FALSE, 0, TRUE);
-- if (linewhite(curwin->w_cursor.lnum))
-- did_ai = TRUE; /* delete the indent if the line stays empty */
-- }
-- }
--
-- void
-- fix_indent(void)
-- {
-- if (p_paste)
-- return;
-- # ifdef FEAT_LISP
-- if (curbuf->b_p_lisp && curbuf->b_p_ai)
-- fixthisline(get_lisp_indent);
-- # endif
-- # if defined(FEAT_LISP) && defined(FEAT_CINDENT)
-- else
-- # endif
-- # ifdef FEAT_CINDENT
-- if (cindent_on())
-- do_c_expr_indent();
-- # endif
-- }
--
-- #endif
--
-- #ifdef FEAT_CINDENT
-- /*
-- * return TRUE if 'cinkeys' contains the key "keytyped",
-- * when == '*': Only if key is preceded with '*' (indent before insert)
-- * when == '!': Only if key is preceded with '!' (don't insert)
-- * when == ' ': Only if key is not preceded with '*'(indent afterwards)
-- *
-- * "keytyped" can have a few special values:
-- * KEY_OPEN_FORW
-- * KEY_OPEN_BACK
-- * KEY_COMPLETE just finished completion.
-- *
-- * If line_is_empty is TRUE accept keys with '0' before them.
-- */
-- int
-- in_cinkeys(
-- int keytyped,
-- int when,
-- int line_is_empty)
-- {
-- char_u *look;
-- int try_match;
-- int try_match_word;
-- char_u *p;
-- char_u *line;
-- int icase;
-- int i;
--
-- if (keytyped == NUL)
-- /* Can happen with CTRL-Y and CTRL-E on a short line. */
-- return FALSE;
--
-- #ifdef FEAT_EVAL
-- if (*curbuf->b_p_inde != NUL)
-- look = curbuf->b_p_indk; /* 'indentexpr' set: use 'indentkeys' */
-- else
-- #endif
-- look = curbuf->b_p_cink; /* 'indentexpr' empty: use 'cinkeys' */
-- while (*look)
-- {
-- /*
-- * Find out if we want to try a match with this key, depending on
-- * 'when' and a '*' or '!' before the key.
-- */
-- switch (when)
-- {
-- case '*': try_match = (*look == '*'); break;
-- case '!': try_match = (*look == '!'); break;
-- default: try_match = (*look != '*'); break;
-- }
-- if (*look == '*' || *look == '!')
-- ++look;
--
-- /*
-- * If there is a '0', only accept a match if the line is empty.
-- * But may still match when typing last char of a word.
-- */
-- if (*look == '0')
-- {
-- try_match_word = try_match;
-- if (!line_is_empty)
-- try_match = FALSE;
-- ++look;
-- }
-- else
-- try_match_word = FALSE;
--
-- /*
-- * does it look like a control character?
-- */
-- if (*look == '^'
-- #ifdef EBCDIC
-- && (Ctrl_chr(look[1]) != 0)
-- #else
-- && look[1] >= '?' && look[1] <= '_'
-- #endif
-- )
-- {
-- if (try_match && keytyped == Ctrl_chr(look[1]))
-- return TRUE;
-- look += 2;
-- }
-- /*
-- * 'o' means "o" command, open forward.
-- * 'O' means "O" command, open backward.
-- */
-- else if (*look == 'o')
-- {
-- if (try_match && keytyped == KEY_OPEN_FORW)
-- return TRUE;
-- ++look;
-- }
-- else if (*look == 'O')
-- {
-- if (try_match && keytyped == KEY_OPEN_BACK)
-- return TRUE;
-- ++look;
-- }
--
-- /*
-- * 'e' means to check for "else" at start of line and just before the
-- * cursor.
-- */
-- else if (*look == 'e')
-- {
-- if (try_match && keytyped == 'e' && curwin->w_cursor.col >= 4)
-- {
-- p = ml_get_curline();
-- if (skipwhite(p) == p + curwin->w_cursor.col - 4 &&
-- STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0)
-- return TRUE;
-- }
-- ++look;
-- }
--
-- /*
-- * ':' only causes an indent if it is at the end of a label or case
-- * statement, or when it was before typing the ':' (to fix
-- * class::method for C++).
-- */
-- else if (*look == ':')
-- {
-- if (try_match && keytyped == ':')
-- {
-- p = ml_get_curline();
-- if (cin_iscase(p, FALSE) || cin_isscopedecl(p) || cin_islabel())
-- return TRUE;
-- /* Need to get the line again after cin_islabel(). */
-- p = ml_get_curline();
-- if (curwin->w_cursor.col > 2
-- && p[curwin->w_cursor.col - 1] == ':'
-- && p[curwin->w_cursor.col - 2] == ':')
-- {
-- p[curwin->w_cursor.col - 1] = ' ';
-- i = (cin_iscase(p, FALSE) || cin_isscopedecl(p)
-- || cin_islabel());
-- p = ml_get_curline();
-- p[curwin->w_cursor.col - 1] = ':';
-- if (i)
-- return TRUE;
-- }
-- }
-- ++look;
-- }
--
--
-- /*
-- * Is it a key in <>, maybe?
-- */
-- else if (*look == '<')
-- {
-- if (try_match)
-- {
-- /*
-- * make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>,
-- * <:> and <!> so that people can re-indent on o, O, e, 0, <,
-- * >, *, : and ! keys if they really really want to.
-- */
-- if (vim_strchr((char_u *)"<>!*oOe0:", look[1]) != NULL
-- && keytyped == look[1])
-- return TRUE;
--
-- if (keytyped == get_special_key_code(look + 1))
-- return TRUE;
-- }
-- while (*look && *look != '>')
-- look++;
-- while (*look == '>')
-- look++;
-- }
--
-- /*
-- * Is it a word: "=word"?
-- */
-- else if (*look == '=' && look[1] != ',' && look[1] != NUL)
-- {
-- ++look;
-- if (*look == '~')
-- {
-- icase = TRUE;
-- ++look;
-- }
-- else
-- icase = FALSE;
-- p = vim_strchr(look, ',');
-- if (p == NULL)
-- p = look + STRLEN(look);
-- if ((try_match || try_match_word)
-- && curwin->w_cursor.col >= (colnr_T)(p - look))
-- {
-- int match = FALSE;
--
-- #ifdef FEAT_INS_EXPAND
-- if (keytyped == KEY_COMPLETE)
-- {
-- char_u *s;
--
-- /* Just completed a word, check if it starts with "look".
-- * search back for the start of a word. */
-- line = ml_get_curline();
-- if (has_mbyte)
-- {
-- char_u *n;
--
-- for (s = line + curwin->w_cursor.col; s > line; s = n)
-- {
-- n = mb_prevptr(line, s);
-- if (!vim_iswordp(n))
-- break;
-- }
-- }
-- else
-- for (s = line + curwin->w_cursor.col; s > line; --s)
-- if (!vim_iswordc(s[-1]))
-- break;
-- if (s + (p - look) <= line + curwin->w_cursor.col
-- && (icase
-- ? MB_STRNICMP(s, look, p - look)
-- : STRNCMP(s, look, p - look)) == 0)
-- match = TRUE;
-- }
-- else
-- #endif
-- /* TODO: multi-byte */
-- if (keytyped == (int)p[-1] || (icase && keytyped < 256
-- && TOLOWER_LOC(keytyped) == TOLOWER_LOC((int)p[-1])))
-- {
-- line = ml_get_cursor();
-- if ((curwin->w_cursor.col == (colnr_T)(p - look)
-- || !vim_iswordc(line[-(p - look) - 1]))
-- && (icase
-- ? MB_STRNICMP(line - (p - look), look, p - look)
-- : STRNCMP(line - (p - look), look, p - look))
-- == 0)
-- match = TRUE;
-- }
-- if (match && try_match_word && !try_match)
-- {
-- /* "0=word": Check if there are only blanks before the
-- * word. */
-- if (getwhitecols_curline() !=
-- (int)(curwin->w_cursor.col - (p - look)))
-- match = FALSE;
-- }
-- if (match)
-- return TRUE;
-- }
-- look = p;
-- }
--
-- /*
-- * ok, it's a boring generic character.
-- */
-- else
-- {
-- if (try_match && *look == keytyped)
-- return TRUE;
-- if (*look != NUL)
-- ++look;
-- }
--
-- /*
-- * Skip over ", ".
-- */
-- look = skip_to_option_part(look);
-- }
-- return FALSE;
-- }
-- #endif /* FEAT_CINDENT */
--
- #if defined(FEAT_RIGHTLEFT) || defined(PROTO)
- /*
- * Map Hebrew keyboard when in hkmap mode.
---- 7922,7927 ----
-*** ../vim-8.1.0856/src/indent.c 2019-01-31 13:47:08.550925126 +0100
---- src/indent.c 2019-01-31 13:43:23.352467260 +0100
-***************
-*** 0 ****
---- 1,4683 ----
-+ /* vi:set ts=8 sts=4 sw=4 noet:
-+ *
-+ * VIM - Vi IMproved by Bram Moolenaar
-+ *
-+ * Do ":help uganda" in Vim to read copying and usage conditions.
-+ * Do ":help credits" in Vim to see a list of people who contributed.
-+ * See README.txt for an overview of the Vim source code.
-+ */
-+
-+ /*
-+ * indent.c: Indentation related functions
-+ */
-+
-+ #include "vim.h"
-+
-+ #if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT)
-+
-+ /*
-+ * Return TRUE if the string "line" starts with a word from 'cinwords'.
-+ */
-+ int
-+ cin_is_cinword(char_u *line)
-+ {
-+ char_u *cinw;
-+ char_u *cinw_buf;
-+ int cinw_len;
-+ int retval = FALSE;
-+ int len;
-+
-+ cinw_len = (int)STRLEN(curbuf->b_p_cinw) + 1;
-+ cinw_buf = alloc((unsigned)cinw_len);
-+ if (cinw_buf != NULL)
-+ {
-+ line = skipwhite(line);
-+ for (cinw = curbuf->b_p_cinw; *cinw; )
-+ {
-+ len = copy_option_part(&cinw, cinw_buf, cinw_len, ",");
-+ if (STRNCMP(line, cinw_buf, len) == 0
-+ && (!vim_iswordc(line[len]) || !vim_iswordc(line[len - 1])))
-+ {
-+ retval = TRUE;
-+ break;
-+ }
-+ }
-+ vim_free(cinw_buf);
-+ }
-+ return retval;
-+ }
-+ #endif
-+
-+ #if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL)
-+
-+ static char_u *skip_string(char_u *p);
-+ static pos_T *find_start_rawstring(int ind_maxcomment);
-+
-+ /*
-+ * Find the start of a comment, not knowing if we are in a comment right now.
-+ * Search starts at w_cursor.lnum and goes backwards.
-+ * Return NULL when not inside a comment.
-+ */
-+ static pos_T *
-+ ind_find_start_comment(void) /* XXX */
-+ {
-+ return find_start_comment(curbuf->b_ind_maxcomment);
-+ }
-+
-+ pos_T *
-+ find_start_comment(int ind_maxcomment) /* XXX */
-+ {
-+ pos_T *pos;
-+ char_u *line;
-+ char_u *p;
-+ int cur_maxcomment = ind_maxcomment;
-+
-+ for (;;)
-+ {
-+ pos = findmatchlimit(NULL, '*', FM_BACKWARD, cur_maxcomment);
-+ if (pos == NULL)
-+ break;
-+
-+ /*
-+ * Check if the comment start we found is inside a string.
-+ * If it is then restrict the search to below this line and try again.
-+ */
-+ line = ml_get(pos->lnum);
-+ for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p)
-+ p = skip_string(p);
-+ if ((colnr_T)(p - line) <= pos->col)
-+ break;
-+ cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
-+ if (cur_maxcomment <= 0)
-+ {
-+ pos = NULL;
-+ break;
-+ }
-+ }
-+ return pos;
-+ }
-+
-+ /*
-+ * Find the start of a comment or raw string, not knowing if we are in a
-+ * comment or raw string right now.
-+ * Search starts at w_cursor.lnum and goes backwards.
-+ * If is_raw is given and returns start of raw_string, sets it to true.
-+ * Return NULL when not inside a comment or raw string.
-+ * "CORS" -> Comment Or Raw String
-+ */
-+ static pos_T *
-+ ind_find_start_CORS(linenr_T *is_raw) /* XXX */
-+ {
-+ static pos_T comment_pos_copy;
-+ pos_T *comment_pos;
-+ pos_T *rs_pos;
-+
-+ comment_pos = find_start_comment(curbuf->b_ind_maxcomment);
-+ if (comment_pos != NULL)
-+ {
-+ /* Need to make a copy of the static pos in findmatchlimit(),
-+ * calling find_start_rawstring() may change it. */
-+ comment_pos_copy = *comment_pos;
-+ comment_pos = &comment_pos_copy;
-+ }
-+ rs_pos = find_start_rawstring(curbuf->b_ind_maxcomment);
-+
-+ /* If comment_pos is before rs_pos the raw string is inside the comment.
-+ * If rs_pos is before comment_pos the comment is inside the raw string. */
-+ if (comment_pos == NULL || (rs_pos != NULL
-+ && LT_POS(*rs_pos, *comment_pos)))
-+ {
-+ if (is_raw != NULL && rs_pos != NULL)
-+ *is_raw = rs_pos->lnum;
-+ return rs_pos;
-+ }
-+ return comment_pos;
-+ }
-+
-+ /*
-+ * Find the start of a raw string, not knowing if we are in one right now.
-+ * Search starts at w_cursor.lnum and goes backwards.
-+ * Return NULL when not inside a raw string.
-+ */
-+ static pos_T *
-+ find_start_rawstring(int ind_maxcomment) /* XXX */
-+ {
-+ pos_T *pos;
-+ char_u *line;
-+ char_u *p;
-+ int cur_maxcomment = ind_maxcomment;
-+
-+ for (;;)
-+ {
-+ pos = findmatchlimit(NULL, 'R', FM_BACKWARD, cur_maxcomment);
-+ if (pos == NULL)
-+ break;
-+
-+ /*
-+ * Check if the raw string start we found is inside a string.
-+ * If it is then restrict the search to below this line and try again.
-+ */
-+ line = ml_get(pos->lnum);
-+ for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p)
-+ p = skip_string(p);
-+ if ((colnr_T)(p - line) <= pos->col)
-+ break;
-+ cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
-+ if (cur_maxcomment <= 0)
-+ {
-+ pos = NULL;
-+ break;
-+ }
-+ }
-+ return pos;
-+ }
-+
-+ /*
-+ * Skip to the end of a "string" and a 'c' character.
-+ * If there is no string or character, return argument unmodified.
-+ */
-+ static char_u *
-+ skip_string(char_u *p)
-+ {
-+ int i;
-+
-+ /*
-+ * We loop, because strings may be concatenated: "date""time".
-+ */
-+ for ( ; ; ++p)
-+ {
-+ if (p[0] == '\'') /* 'c' or '\n' or '\000' */
-+ {
-+ if (!p[1]) /* ' at end of line */
-+ break;
-+ i = 2;
-+ if (p[1] == '\\') /* '\n' or '\000' */
-+ {
-+ ++i;
-+ while (vim_isdigit(p[i - 1])) /* '\000' */
-+ ++i;
-+ }
-+ if (p[i] == '\'') /* check for trailing ' */
-+ {
-+ p += i;
-+ continue;
-+ }
-+ }
-+ else if (p[0] == '"') /* start of string */
-+ {
-+ for (++p; p[0]; ++p)
-+ {
-+ if (p[0] == '\\' && p[1] != NUL)
-+ ++p;
-+ else if (p[0] == '"') /* end of string */
-+ break;
-+ }
-+ if (p[0] == '"')
-+ continue; /* continue for another string */
-+ }
-+ else if (p[0] == 'R' && p[1] == '"')
-+ {
-+ /* Raw string: R"[delim](...)[delim]" */
-+ char_u *delim = p + 2;
-+ char_u *paren = vim_strchr(delim, '(');
-+
-+ if (paren != NULL)
-+ {
-+ size_t delim_len = paren - delim;
-+
-+ for (p += 3; *p; ++p)
-+ if (p[0] == ')' && STRNCMP(p + 1, delim, delim_len) == 0
-+ && p[delim_len + 1] == '"')
-+ {
-+ p += delim_len + 1;
-+ break;
-+ }
-+ if (p[0] == '"')
-+ continue; /* continue for another string */
-+ }
-+ }
-+ break; /* no string found */
-+ }
-+ if (!*p)
-+ --p; /* backup from NUL */
-+ return p;
-+ }
-+ #endif /* FEAT_CINDENT || FEAT_SYN_HL */
-+
-+ #if defined(FEAT_CINDENT) || defined(PROTO)
-+
-+ /*
-+ * Return TRUE if C-indenting is on.
-+ */
-+ int
-+ cindent_on(void)
-+ {
-+ return (!p_paste && (curbuf->b_p_cin
-+ # ifdef FEAT_EVAL
-+ || *curbuf->b_p_inde != NUL
-+ # endif
-+ ));
-+ }
-+
-+ /* Find result cache for cpp_baseclass */
-+ typedef struct {
-+ int found;
-+ lpos_T lpos;
-+ } cpp_baseclass_cache_T;
-+
-+ /*
-+ * Functions for C-indenting.
-+ * Most of this originally comes from Eric Fischer.
-+ */
-+ /*
-+ * Below "XXX" means that this function may unlock the current line.
-+ */
-+
-+ static int cin_isdefault(char_u *);
-+ static int cin_ispreproc(char_u *);
-+ static int cin_iscomment(char_u *);
-+ static int cin_islinecomment(char_u *);
-+ static int cin_isterminated(char_u *, int, int);
-+ static int cin_iselse(char_u *);
-+ static int cin_ends_in(char_u *, char_u *, char_u *);
-+ static int cin_starts_with(char_u *s, char *word);
-+ static pos_T *find_match_paren(int);
-+ static pos_T *find_match_char(int c, int ind_maxparen);
-+ static int find_last_paren(char_u *l, int start, int end);
-+ static int find_match(int lookfor, linenr_T ourscope);
-+
-+ /*
-+ * Skip over white space and C comments within the line.
-+ * Also skip over Perl/shell comments if desired.
-+ */
-+ static char_u *
-+ cin_skipcomment(char_u *s)
-+ {
-+ while (*s)
-+ {
-+ char_u *prev_s = s;
-+
-+ s = skipwhite(s);
-+
-+ /* Perl/shell # comment comment continues until eol. Require a space
-+ * before # to avoid recognizing $#array. */
-+ if (curbuf->b_ind_hash_comment != 0 && s != prev_s && *s == '#')
-+ {
-+ s += STRLEN(s);
-+ break;
-+ }
-+ if (*s != '/')
-+ break;
-+ ++s;
-+ if (*s == '/') /* slash-slash comment continues till eol */
-+ {
-+ s += STRLEN(s);
-+ break;
-+ }
-+ if (*s != '*')
-+ break;
-+ for (++s; *s; ++s) /* skip slash-star comment */
-+ if (s[0] == '*' && s[1] == '/')
-+ {
-+ s += 2;
-+ break;
-+ }
-+ }
-+ return s;
-+ }
-+
-+ /*
-+ * Return TRUE if there is no code at *s. White space and comments are
-+ * not considered code.
-+ */
-+ static int
-+ cin_nocode(char_u *s)
-+ {
-+ return *cin_skipcomment(s) == NUL;
-+ }
-+
-+ /*
-+ * Check previous lines for a "//" line comment, skipping over blank lines.
-+ */
-+ static pos_T *
-+ find_line_comment(void) /* XXX */
-+ {
-+ static pos_T pos;
-+ char_u *line;
-+ char_u *p;
-+
-+ pos = curwin->w_cursor;
-+ while (--pos.lnum > 0)
-+ {
-+ line = ml_get(pos.lnum);
-+ p = skipwhite(line);
-+ if (cin_islinecomment(p))
-+ {
-+ pos.col = (int)(p - line);
-+ return &pos;
-+ }
-+ if (*p != NUL)
-+ break;
-+ }
-+ return NULL;
-+ }
-+
-+ /*
-+ * Return TRUE if "text" starts with "key:".
-+ */
-+ static int
-+ cin_has_js_key(char_u *text)
-+ {
-+ char_u *s = skipwhite(text);
-+ int quote = -1;
-+
-+ if (*s == '\'' || *s == '"')
-+ {
-+ /* can be 'key': or "key": */
-+ quote = *s;
-+ ++s;
-+ }
-+ if (!vim_isIDc(*s)) /* need at least one ID character */
-+ return FALSE;
-+
-+ while (vim_isIDc(*s))
-+ ++s;
-+ if (*s == quote)
-+ ++s;
-+
-+ s = cin_skipcomment(s);
-+
-+ /* "::" is not a label, it's C++ */
-+ return (*s == ':' && s[1] != ':');
-+ }
-+
-+ /*
-+ * Check if string matches "label:"; move to character after ':' if true.
-+ * "*s" must point to the start of the label, if there is one.
-+ */
-+ static int
-+ cin_islabel_skip(char_u **s)
-+ {
-+ if (!vim_isIDc(**s)) /* need at least one ID character */
-+ return FALSE;
-+
-+ while (vim_isIDc(**s))
-+ (*s)++;
-+
-+ *s = cin_skipcomment(*s);
-+
-+ /* "::" is not a label, it's C++ */
-+ return (**s == ':' && *++*s != ':');
-+ }
-+
-+ /*
-+ * Recognize a label: "label:".
-+ * Note: curwin->w_cursor must be where we are looking for the label.
-+ */
-+ int
-+ cin_islabel(void) /* XXX */
-+ {
-+ char_u *s;
-+
-+ s = cin_skipcomment(ml_get_curline());
-+
-+ /*
-+ * Exclude "default" from labels, since it should be indented
-+ * like a switch label. Same for C++ scope declarations.
-+ */
-+ if (cin_isdefault(s))
-+ return FALSE;
-+ if (cin_isscopedecl(s))
-+ return FALSE;
-+
-+ if (cin_islabel_skip(&s))
-+ {
-+ /*
-+ * Only accept a label if the previous line is terminated or is a case
-+ * label.
-+ */
-+ pos_T cursor_save;
-+ pos_T *trypos;
-+ char_u *line;
-+
-+ cursor_save = curwin->w_cursor;
-+ while (curwin->w_cursor.lnum > 1)
-+ {
-+ --curwin->w_cursor.lnum;
-+
-+ /*
-+ * If we're in a comment or raw string now, skip to the start of
-+ * it.
-+ */
-+ curwin->w_cursor.col = 0;
-+ if ((trypos = ind_find_start_CORS(NULL)) != NULL) /* XXX */
-+ curwin->w_cursor = *trypos;
-+
-+ line = ml_get_curline();
-+ if (cin_ispreproc(line)) /* ignore #defines, #if, etc. */
-+ continue;
-+ if (*(line = cin_skipcomment(line)) == NUL)
-+ continue;
-+
-+ curwin->w_cursor = cursor_save;
-+ if (cin_isterminated(line, TRUE, FALSE)
-+ || cin_isscopedecl(line)
-+ || cin_iscase(line, TRUE)
-+ || (cin_islabel_skip(&line) && cin_nocode(line)))
-+ return TRUE;
-+ return FALSE;
-+ }
-+ curwin->w_cursor = cursor_save;
-+ return TRUE; /* label at start of file??? */
-+ }
-+ return FALSE;
-+ }
-+
-+ /*
-+ * Recognize structure initialization and enumerations:
-+ * "[typedef] [static|public|protected|private] enum"
-+ * "[typedef] [static|public|protected|private] = {"
-+ */
-+ static int
-+ cin_isinit(void)
-+ {
-+ char_u *s;
-+ static char *skip[] = {"static", "public", "protected", "private"};
-+
-+ s = cin_skipcomment(ml_get_curline());
-+
-+ if (cin_starts_with(s, "typedef"))
-+ s = cin_skipcomment(s + 7);
-+
-+ for (;;)
-+ {
-+ int i, l;
-+
-+ for (i = 0; i < (int)(sizeof(skip) / sizeof(char *)); ++i)
-+ {
-+ l = (int)strlen(skip[i]);
-+ if (cin_starts_with(s, skip[i]))
-+ {
-+ s = cin_skipcomment(s + l);
-+ l = 0;
-+ break;
-+ }
-+ }
-+ if (l != 0)
-+ break;
-+ }
-+
-+ if (cin_starts_with(s, "enum"))
-+ return TRUE;
-+
-+ if (cin_ends_in(s, (char_u *)"=", (char_u *)"{"))
-+ return TRUE;
-+
-+ return FALSE;
-+ }
-+
-+ /*
-+ * Recognize a switch label: "case .*:" or "default:".
-+ */
-+ int
-+ cin_iscase(
-+ char_u *s,
-+ int strict) /* Allow relaxed check of case statement for JS */
-+ {
-+ s = cin_skipcomment(s);
-+ if (cin_starts_with(s, "case"))
-+ {
-+ for (s += 4; *s; ++s)
-+ {
-+ s = cin_skipcomment(s);
-+ if (*s == ':')
-+ {
-+ if (s[1] == ':') /* skip over "::" for C++ */
-+ ++s;
-+ else
-+ return TRUE;
-+ }
-+ if (*s == '\'' && s[1] && s[2] == '\'')
-+ s += 2; /* skip over ':' */
-+ else if (*s == '/' && (s[1] == '*' || s[1] == '/'))
-+ return FALSE; /* stop at comment */
-+ else if (*s == '"')
-+ {
-+ /* JS etc. */
-+ if (strict)
-+ return FALSE; /* stop at string */
-+ else
-+ return TRUE;
-+ }
-+ }
-+ return FALSE;
-+ }
-+
-+ if (cin_isdefault(s))
-+ return TRUE;
-+ return FALSE;
-+ }
-+
-+ /*
-+ * Recognize a "default" switch label.
-+ */
-+ static int
-+ cin_isdefault(char_u *s)
-+ {
-+ return (STRNCMP(s, "default", 7) == 0
-+ && *(s = cin_skipcomment(s + 7)) == ':'
-+ && s[1] != ':');
-+ }
-+
-+ /*
-+ * Recognize a "public/private/protected" scope declaration label.
-+ */
-+ int
-+ cin_isscopedecl(char_u *s)
-+ {
-+ int i;
-+
-+ s = cin_skipcomment(s);
-+ if (STRNCMP(s, "public", 6) == 0)
-+ i = 6;
-+ else if (STRNCMP(s, "protected", 9) == 0)
-+ i = 9;
-+ else if (STRNCMP(s, "private", 7) == 0)
-+ i = 7;
-+ else
-+ return FALSE;
-+ return (*(s = cin_skipcomment(s + i)) == ':' && s[1] != ':');
-+ }
-+
-+ /* Maximum number of lines to search back for a "namespace" line. */
-+ #define FIND_NAMESPACE_LIM 20
-+
-+ /*
-+ * Recognize a "namespace" scope declaration.
-+ */
-+ static int
-+ cin_is_cpp_namespace(char_u *s)
-+ {
-+ char_u *p;
-+ int has_name = FALSE;
-+ int has_name_start = FALSE;
-+
-+ s = cin_skipcomment(s);
-+ if (STRNCMP(s, "namespace", 9) == 0 && (s[9] == NUL || !vim_iswordc(s[9])))
-+ {
-+ p = cin_skipcomment(skipwhite(s + 9));
-+ while (*p != NUL)
-+ {
-+ if (VIM_ISWHITE(*p))
-+ {
-+ has_name = TRUE; /* found end of a name */
-+ p = cin_skipcomment(skipwhite(p));
-+ }
-+ else if (*p == '{')
-+ {
-+ break;
-+ }
-+ else if (vim_iswordc(*p))
-+ {
-+ has_name_start = TRUE;
-+ if (has_name)
-+ return FALSE; /* word character after skipping past name */
-+ ++p;
-+ }
-+ else if (p[0] == ':' && p[1] == ':' && vim_iswordc(p[2]))
-+ {
-+ if (!has_name_start || has_name)
-+ return FALSE;
-+ /* C++ 17 nested namespace */
-+ p += 3;
-+ }
-+ else
-+ {
-+ return FALSE;
-+ }
-+ }
-+ return TRUE;
-+ }
-+ return FALSE;
-+ }
-+
-+ /*
-+ * Recognize a `extern "C"` or `extern "C++"` linkage specifications.
-+ */
-+ static int
-+ cin_is_cpp_extern_c(char_u *s)
-+ {
-+ char_u *p;
-+ int has_string_literal = FALSE;
-+
-+ s = cin_skipcomment(s);
-+ if (STRNCMP(s, "extern", 6) == 0 && (s[6] == NUL || !vim_iswordc(s[6])))
-+ {
-+ p = cin_skipcomment(skipwhite(s + 6));
-+ while (*p != NUL)
-+ {
-+ if (VIM_ISWHITE(*p))
-+ {
-+ p = cin_skipcomment(skipwhite(p));
-+ }
-+ else if (*p == '{')
-+ {
-+ break;
-+ }
-+ else if (p[0] == '"' && p[1] == 'C' && p[2] == '"')
-+ {
-+ if (has_string_literal)
-+ return FALSE;
-+ has_string_literal = TRUE;
-+ p += 3;
-+ }
-+ else if (p[0] == '"' && p[1] == 'C' && p[2] == '+' && p[3] == '+'
-+ && p[4] == '"')
-+ {
-+ if (has_string_literal)
-+ return FALSE;
-+ has_string_literal = TRUE;
-+ p += 5;
-+ }
-+ else
-+ {
-+ return FALSE;
-+ }
-+ }
-+ return has_string_literal ? TRUE : FALSE;
-+ }
-+ return FALSE;
-+ }
-+
-+ /*
-+ * Return a pointer to the first non-empty non-comment character after a ':'.
-+ * Return NULL if not found.
-+ * case 234: a = b;
-+ * ^
-+ */
-+ static char_u *
-+ after_label(char_u *l)
-+ {
-+ for ( ; *l; ++l)
-+ {
-+ if (*l == ':')
-+ {
-+ if (l[1] == ':') /* skip over "::" for C++ */
-+ ++l;
-+ else if (!cin_iscase(l + 1, FALSE))
-+ break;
-+ }
-+ else if (*l == '\'' && l[1] && l[2] == '\'')
-+ l += 2; /* skip over 'x' */
-+ }
-+ if (*l == NUL)
-+ return NULL;
-+ l = cin_skipcomment(l + 1);
-+ if (*l == NUL)
-+ return NULL;
-+ return l;
-+ }
-+
-+ /*
-+ * Get indent of line "lnum", skipping a label.
-+ * Return 0 if there is nothing after the label.
-+ */
-+ static int
-+ get_indent_nolabel (linenr_T lnum) /* XXX */
-+ {
-+ char_u *l;
-+ pos_T fp;
-+ colnr_T col;
-+ char_u *p;
-+
-+ l = ml_get(lnum);
-+ p = after_label(l);
-+ if (p == NULL)
-+ return 0;
-+
-+ fp.col = (colnr_T)(p - l);
-+ fp.lnum = lnum;
-+ getvcol(curwin, &fp, &col, NULL, NULL);
-+ return (int)col;
-+ }
-+
-+ /*
-+ * Find indent for line "lnum", ignoring any case or jump label.
-+ * Also return a pointer to the text (after the label) in "pp".
-+ * label: if (asdf && asdfasdf)
-+ * ^
-+ */
-+ static int
-+ skip_label(linenr_T lnum, char_u **pp)
-+ {
-+ char_u *l;
-+ int amount;
-+ pos_T cursor_save;
-+
-+ cursor_save = curwin->w_cursor;
-+ curwin->w_cursor.lnum = lnum;
-+ l = ml_get_curline();
-+ /* XXX */
-+ if (cin_iscase(l, FALSE) || cin_isscopedecl(l) || cin_islabel())
-+ {
-+ amount = get_indent_nolabel(lnum);
-+ l = after_label(ml_get_curline());
-+ if (l == NULL) /* just in case */
-+ l = ml_get_curline();
-+ }
-+ else
-+ {
-+ amount = get_indent();
-+ l = ml_get_curline();
-+ }
-+ *pp = l;
-+
-+ curwin->w_cursor = cursor_save;
-+ return amount;
-+ }
-+
-+ /*
-+ * Return the indent of the first variable name after a type in a declaration.
-+ * int a, indent of "a"
-+ * static struct foo b, indent of "b"
-+ * enum bla c, indent of "c"
-+ * Returns zero when it doesn't look like a declaration.
-+ */
-+ static int
-+ cin_first_id_amount(void)
-+ {
-+ char_u *line, *p, *s;
-+ int len;
-+ pos_T fp;
-+ colnr_T col;
-+
-+ line = ml_get_curline();
-+ p = skipwhite(line);
-+ len = (int)(skiptowhite(p) - p);
-+ if (len == 6 && STRNCMP(p, "static", 6) == 0)
-+ {
-+ p = skipwhite(p + 6);
-+ len = (int)(skiptowhite(p) - p);
-+ }
-+ if (len == 6 && STRNCMP(p, "struct", 6) == 0)
-+ p = skipwhite(p + 6);
-+ else if (len == 4 && STRNCMP(p, "enum", 4) == 0)
-+ p = skipwhite(p + 4);
-+ else if ((len == 8 && STRNCMP(p, "unsigned", 8) == 0)
-+ || (len == 6 && STRNCMP(p, "signed", 6) == 0))
-+ {
-+ s = skipwhite(p + len);
-+ if ((STRNCMP(s, "int", 3) == 0 && VIM_ISWHITE(s[3]))
-+ || (STRNCMP(s, "long", 4) == 0 && VIM_ISWHITE(s[4]))
-+ || (STRNCMP(s, "short", 5) == 0 && VIM_ISWHITE(s[5]))
-+ || (STRNCMP(s, "char", 4) == 0 && VIM_ISWHITE(s[4])))
-+ p = s;
-+ }
-+ for (len = 0; vim_isIDc(p[len]); ++len)
-+ ;
-+ if (len == 0 || !VIM_ISWHITE(p[len]) || cin_nocode(p))
-+ return 0;
-+
-+ p = skipwhite(p + len);
-+ fp.lnum = curwin->w_cursor.lnum;
-+ fp.col = (colnr_T)(p - line);
-+ getvcol(curwin, &fp, &col, NULL, NULL);
-+ return (int)col;
-+ }
-+
-+ /*
-+ * Return the indent of the first non-blank after an equal sign.
-+ * char *foo = "here";
-+ * Return zero if no (useful) equal sign found.
-+ * Return -1 if the line above "lnum" ends in a backslash.
-+ * foo = "asdf\
-+ * asdf\
-+ * here";
-+ */
-+ static int
-+ cin_get_equal_amount(linenr_T lnum)
-+ {
-+ char_u *line;
-+ char_u *s;
-+ colnr_T col;
-+ pos_T fp;
-+
-+ if (lnum > 1)
-+ {
-+ line = ml_get(lnum - 1);
-+ if (*line != NUL && line[STRLEN(line) - 1] == '\\')
-+ return -1;
-+ }
-+
-+ line = s = ml_get(lnum);
-+ while (*s != NUL && vim_strchr((char_u *)"=;{}\"'", *s) == NULL)
-+ {
-+ if (cin_iscomment(s)) /* ignore comments */
-+ s = cin_skipcomment(s);
-+ else
-+ ++s;
-+ }
-+ if (*s != '=')
-+ return 0;
-+
-+ s = skipwhite(s + 1);
-+ if (cin_nocode(s))
-+ return 0;
-+
-+ if (*s == '"') /* nice alignment for continued strings */
-+ ++s;
-+
-+ fp.lnum = lnum;
-+ fp.col = (colnr_T)(s - line);
-+ getvcol(curwin, &fp, &col, NULL, NULL);
-+ return (int)col;
-+ }
-+
-+ /*
-+ * Recognize a preprocessor statement: Any line that starts with '#'.
-+ */
-+ static int
-+ cin_ispreproc(char_u *s)
-+ {
-+ if (*skipwhite(s) == '#')
-+ return TRUE;
-+ return FALSE;
-+ }
-+
-+ /*
-+ * Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a
-+ * continuation line of a preprocessor statement. Decrease "*lnump" to the
-+ * start and return the line in "*pp".
-+ * Put the amount of indent in "*amount".
-+ */
-+ static int
-+ cin_ispreproc_cont(char_u **pp, linenr_T *lnump, int *amount)
-+ {
-+ char_u *line = *pp;
-+ linenr_T lnum = *lnump;
-+ int retval = FALSE;
-+ int candidate_amount = *amount;
-+
-+ if (*line != NUL && line[STRLEN(line) - 1] == '\\')
-+ candidate_amount = get_indent_lnum(lnum);
-+
-+ for (;;)
-+ {
-+ if (cin_ispreproc(line))
-+ {
-+ retval = TRUE;
-+ *lnump = lnum;
-+ break;
-+ }
-+ if (lnum == 1)
-+ break;
-+ line = ml_get(--lnum);
-+ if (*line == NUL || line[STRLEN(line) - 1] != '\\')
-+ break;
-+ }
-+
-+ if (lnum != *lnump)
-+ *pp = ml_get(*lnump);
-+ if (retval)
-+ *amount = candidate_amount;
-+ return retval;
-+ }
-+
-+ /*
-+ * Recognize the start of a C or C++ comment.
-+ */
-+ static int
-+ cin_iscomment(char_u *p)
-+ {
-+ return (p[0] == '/' && (p[1] == '*' || p[1] == '/'));
-+ }
-+
-+ /*
-+ * Recognize the start of a "//" comment.
-+ */
-+ static int
-+ cin_islinecomment(char_u *p)
-+ {
-+ return (p[0] == '/' && p[1] == '/');
-+ }
-+
-+ /*
-+ * Recognize a line that starts with '{' or '}', or ends with ';', ',', '{' or
-+ * '}'.
-+ * Don't consider "} else" a terminated line.
-+ * If a line begins with an "else", only consider it terminated if no unmatched
-+ * opening braces follow (handle "else { foo();" correctly).
-+ * Return the character terminating the line (ending char's have precedence if
-+ * both apply in order to determine initializations).
-+ */
-+ static int
-+ cin_isterminated(
-+ char_u *s,
-+ int incl_open, /* include '{' at the end as terminator */
-+ int incl_comma) /* recognize a trailing comma */
-+ {
-+ char_u found_start = 0;
-+ unsigned n_open = 0;
-+ int is_else = FALSE;
-+
-+ s = cin_skipcomment(s);
-+
-+ if (*s == '{' || (*s == '}' && !cin_iselse(s)))
-+ found_start = *s;
-+
-+ if (!found_start)
-+ is_else = cin_iselse(s);
-+
-+ while (*s)
-+ {
-+ /* skip over comments, "" strings and 'c'haracters */
-+ s = skip_string(cin_skipcomment(s));
-+ if (*s == '}' && n_open > 0)
-+ --n_open;
-+ if ((!is_else || n_open == 0)
-+ && (*s == ';' || *s == '}' || (incl_comma && *s == ','))
-+ && cin_nocode(s + 1))
-+ return *s;
-+ else if (*s == '{')
-+ {
-+ if (incl_open && cin_nocode(s + 1))
-+ return *s;
-+ else
-+ ++n_open;
-+ }
-+
-+ if (*s)
-+ s++;
-+ }
-+ return found_start;
-+ }
-+
-+ /*
-+ * Recognize the basic picture of a function declaration -- it needs to
-+ * have an open paren somewhere and a close paren at the end of the line and
-+ * no semicolons anywhere.
-+ * When a line ends in a comma we continue looking in the next line.
-+ * "sp" points to a string with the line. When looking at other lines it must
-+ * be restored to the line. When it's NULL fetch lines here.
-+ * "first_lnum" is where we start looking.
-+ * "min_lnum" is the line before which we will not be looking.
-+ */
-+ static int
-+ cin_isfuncdecl(
-+ char_u **sp,
-+ linenr_T first_lnum,
-+ linenr_T min_lnum)
-+ {
-+ char_u *s;
-+ linenr_T lnum = first_lnum;
-+ linenr_T save_lnum = curwin->w_cursor.lnum;
-+ int retval = FALSE;
-+ pos_T *trypos;
-+ int just_started = TRUE;
-+
-+ if (sp == NULL)
-+ s = ml_get(lnum);
-+ else
-+ s = *sp;
-+
-+ curwin->w_cursor.lnum = lnum;
-+ if (find_last_paren(s, '(', ')')
-+ && (trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
-+ {
-+ lnum = trypos->lnum;
-+ if (lnum < min_lnum)
-+ {
-+ curwin->w_cursor.lnum = save_lnum;
-+ return FALSE;
-+ }
-+
-+ s = ml_get(lnum);
-+ }
-+ curwin->w_cursor.lnum = save_lnum;
-+
-+ /* Ignore line starting with #. */
-+ if (cin_ispreproc(s))
-+ return FALSE;
-+
-+ while (*s && *s != '(' && *s != ';' && *s != '\'' && *s != '"')
-+ {
-+ if (cin_iscomment(s)) /* ignore comments */
-+ s = cin_skipcomment(s);
-+ else if (*s == ':')
-+ {
-+ if (*(s + 1) == ':')
-+ s += 2;
-+ else
-+ /* To avoid a mistake in the following situation:
-+ * A::A(int a, int b)
-+ * : a(0) // <--not a function decl
-+ * , b(0)
-+ * {...
-+ */
-+ return FALSE;
-+ }
-+ else
-+ ++s;
-+ }
-+ if (*s != '(')
-+ return FALSE; /* ';', ' or " before any () or no '(' */
-+
-+ while (*s && *s != ';' && *s != '\'' && *s != '"')
-+ {
-+ if (*s == ')' && cin_nocode(s + 1))
-+ {
-+ /* ')' at the end: may have found a match
-+ * Check for he previous line not to end in a backslash:
-+ * #if defined(x) && \
-+ * defined(y)
-+ */
-+ lnum = first_lnum - 1;
-+ s = ml_get(lnum);
-+ if (*s == NUL || s[STRLEN(s) - 1] != '\\')
-+ retval = TRUE;
-+ goto done;
-+ }
-+ if ((*s == ',' && cin_nocode(s + 1)) || s[1] == NUL || cin_nocode(s))
-+ {
-+ int comma = (*s == ',');
-+
-+ /* ',' at the end: continue looking in the next line.
-+ * At the end: check for ',' in the next line, for this style:
-+ * func(arg1
-+ * , arg2) */
-+ for (;;)
-+ {
-+ if (lnum >= curbuf->b_ml.ml_line_count)
-+ break;
-+ s = ml_get(++lnum);
-+ if (!cin_ispreproc(s))
-+ break;
-+ }
-+ if (lnum >= curbuf->b_ml.ml_line_count)
-+ break;
-+ /* Require a comma at end of the line or a comma or ')' at the
-+ * start of next line. */
-+ s = skipwhite(s);
-+ if (!just_started && (!comma && *s != ',' && *s != ')'))
-+ break;
-+ just_started = FALSE;
-+ }
-+ else if (cin_iscomment(s)) /* ignore comments */
-+ s = cin_skipcomment(s);
-+ else
-+ {
-+ ++s;
-+ just_started = FALSE;
-+ }
-+ }
-+
-+ done:
-+ if (lnum != first_lnum && sp != NULL)
-+ *sp = ml_get(first_lnum);
-+
-+ return retval;
-+ }
-+
-+ static int
-+ cin_isif(char_u *p)
-+ {
-+ return (STRNCMP(p, "if", 2) == 0 && !vim_isIDc(p[2]));
-+ }
-+
-+ static int
-+ cin_iselse(
-+ char_u *p)
-+ {
-+ if (*p == '}') /* accept "} else" */
-+ p = cin_skipcomment(p + 1);
-+ return (STRNCMP(p, "else", 4) == 0 && !vim_isIDc(p[4]));
-+ }
-+
-+ static int
-+ cin_isdo(char_u *p)
-+ {
-+ return (STRNCMP(p, "do", 2) == 0 && !vim_isIDc(p[2]));
-+ }
-+
-+ /*
-+ * Check if this is a "while" that should have a matching "do".
-+ * We only accept a "while (condition) ;", with only white space between the
-+ * ')' and ';'. The condition may be spread over several lines.
-+ */
-+ static int
-+ cin_iswhileofdo (char_u *p, linenr_T lnum) /* XXX */
-+ {
-+ pos_T cursor_save;
-+ pos_T *trypos;
-+ int retval = FALSE;
-+
-+ p = cin_skipcomment(p);
-+ if (*p == '}') /* accept "} while (cond);" */
-+ p = cin_skipcomment(p + 1);
-+ if (cin_starts_with(p, "while"))
-+ {
-+ cursor_save = curwin->w_cursor;
-+ curwin->w_cursor.lnum = lnum;
-+ curwin->w_cursor.col = 0;
-+ p = ml_get_curline();
-+ while (*p && *p != 'w') /* skip any '}', until the 'w' of the "while" */
-+ {
-+ ++p;
-+ ++curwin->w_cursor.col;
-+ }
-+ if ((trypos = findmatchlimit(NULL, 0, 0,
-+ curbuf->b_ind_maxparen)) != NULL
-+ && *cin_skipcomment(ml_get_pos(trypos) + 1) == ';')
-+ retval = TRUE;
-+ curwin->w_cursor = cursor_save;
-+ }
-+ return retval;
-+ }
-+
-+ /*
-+ * Check whether in "p" there is an "if", "for" or "while" before "*poffset".
-+ * Return 0 if there is none.
-+ * Otherwise return !0 and update "*poffset" to point to the place where the
-+ * string was found.
-+ */
-+ static int
-+ cin_is_if_for_while_before_offset(char_u *line, int *poffset)
-+ {
-+ int offset = *poffset;
-+
-+ if (offset-- < 2)
-+ return 0;
-+ while (offset > 2 && VIM_ISWHITE(line[offset]))
-+ --offset;
-+
-+ offset -= 1;
-+ if (!STRNCMP(line + offset, "if", 2))
-+ goto probablyFound;
-+
-+ if (offset >= 1)
-+ {
-+ offset -= 1;
-+ if (!STRNCMP(line + offset, "for", 3))
-+ goto probablyFound;
-+
-+ if (offset >= 2)
-+ {
-+ offset -= 2;
-+ if (!STRNCMP(line + offset, "while", 5))
-+ goto probablyFound;
-+ }
-+ }
-+ return 0;
-+
-+ probablyFound:
-+ if (!offset || !vim_isIDc(line[offset - 1]))
-+ {
-+ *poffset = offset;
-+ return 1;
-+ }
-+ return 0;
-+ }
-+
-+ /*
-+ * Return TRUE if we are at the end of a do-while.
-+ * do
-+ * nothing;
-+ * while (foo
-+ * && bar); <-- here
-+ * Adjust the cursor to the line with "while".
-+ */
-+ static int
-+ cin_iswhileofdo_end(int terminated)
-+ {
-+ char_u *line;
-+ char_u *p;
-+ char_u *s;
-+ pos_T *trypos;
-+ int i;
-+
-+ if (terminated != ';') /* there must be a ';' at the end */
-+ return FALSE;
-+
-+ p = line = ml_get_curline();
-+ while (*p != NUL)
-+ {
-+ p = cin_skipcomment(p);
-+ if (*p == ')')
-+ {
-+ s = skipwhite(p + 1);
-+ if (*s == ';' && cin_nocode(s + 1))
-+ {
-+ /* Found ");" at end of the line, now check there is "while"
-+ * before the matching '('. XXX */
-+ i = (int)(p - line);
-+ curwin->w_cursor.col = i;
-+ trypos = find_match_paren(curbuf->b_ind_maxparen);
-+ if (trypos != NULL)
-+ {
-+ s = cin_skipcomment(ml_get(trypos->lnum));
-+ if (*s == '}') /* accept "} while (cond);" */
-+ s = cin_skipcomment(s + 1);
-+ if (cin_starts_with(s, "while"))
-+ {
-+ curwin->w_cursor.lnum = trypos->lnum;
-+ return TRUE;
-+ }
-+ }
-+
-+ /* Searching may have made "line" invalid, get it again. */
-+ line = ml_get_curline();
-+ p = line + i;
-+ }
-+ }
-+ if (*p != NUL)
-+ ++p;
-+ }
-+ return FALSE;
-+ }
-+
-+ static int
-+ cin_isbreak(char_u *p)
-+ {
-+ return (STRNCMP(p, "break", 5) == 0 && !vim_isIDc(p[5]));
-+ }
-+
-+ /*
-+ * Find the position of a C++ base-class declaration or
-+ * constructor-initialization. eg:
-+ *
-+ * class MyClass :
-+ * baseClass <-- here
-+ * class MyClass : public baseClass,
-+ * anotherBaseClass <-- here (should probably lineup ??)
-+ * MyClass::MyClass(...) :
-+ * baseClass(...) <-- here (constructor-initialization)
-+ *
-+ * This is a lot of guessing. Watch out for "cond ? func() : foo".
-+ */
-+ static int
-+ cin_is_cpp_baseclass(
-+ cpp_baseclass_cache_T *cached) /* input and output */
-+ {
-+ lpos_T *pos = &cached->lpos; /* find position */
-+ char_u *s;
-+ int class_or_struct, lookfor_ctor_init, cpp_base_class;
-+ linenr_T lnum = curwin->w_cursor.lnum;
-+ char_u *line = ml_get_curline();
-+
-+ if (pos->lnum <= lnum)
-+ return cached->found; /* Use the cached result */
-+
-+ pos->col = 0;
-+
-+ s = skipwhite(line);
-+ if (*s == '#') /* skip #define FOO x ? (x) : x */
-+ return FALSE;
-+ s = cin_skipcomment(s);
-+ if (*s == NUL)
-+ return FALSE;
-+
-+ cpp_base_class = lookfor_ctor_init = class_or_struct = FALSE;
-+
-+ /* Search for a line starting with '#', empty, ending in ';' or containing
-+ * '{' or '}' and start below it. This handles the following situations:
-+ * a = cond ?
-+ * func() :
-+ * asdf;
-+ * func::foo()
-+ * : something
-+ * {}
-+ * Foo::Foo (int one, int two)
-+ * : something(4),
-+ * somethingelse(3)
-+ * {}
-+ */
-+ while (lnum > 1)
-+ {
-+ line = ml_get(lnum - 1);
-+ s = skipwhite(line);
-+ if (*s == '#' || *s == NUL)
-+ break;
-+ while (*s != NUL)
-+ {
-+ s = cin_skipcomment(s);
-+ if (*s == '{' || *s == '}'
-+ || (*s == ';' && cin_nocode(s + 1)))
-+ break;
-+ if (*s != NUL)
-+ ++s;
-+ }
-+ if (*s != NUL)
-+ break;
-+ --lnum;
-+ }
-+
-+ pos->lnum = lnum;
-+ line = ml_get(lnum);
-+ s = line;
-+ for (;;)
-+ {
-+ if (*s == NUL)
-+ {
-+ if (lnum == curwin->w_cursor.lnum)
-+ break;
-+ /* Continue in the cursor line. */
-+ line = ml_get(++lnum);
-+ s = line;
-+ }
-+ if (s == line)
-+ {
-+ /* don't recognize "case (foo):" as a baseclass */
-+ if (cin_iscase(s, FALSE))
-+ break;
-+ s = cin_skipcomment(line);
-+ if (*s == NUL)
-+ continue;
-+ }
-+
-+ if (s[0] == '"' || (s[0] == 'R' && s[1] == '"'))
-+ s = skip_string(s) + 1;
-+ else if (s[0] == ':')
-+ {
-+ if (s[1] == ':')
-+ {
-+ /* skip double colon. It can't be a constructor
-+ * initialization any more */
-+ lookfor_ctor_init = FALSE;
-+ s = cin_skipcomment(s + 2);
-+ }
-+ else if (lookfor_ctor_init || class_or_struct)
-+ {
-+ /* we have something found, that looks like the start of
-+ * cpp-base-class-declaration or constructor-initialization */
-+ cpp_base_class = TRUE;
-+ lookfor_ctor_init = class_or_struct = FALSE;
-+ pos->col = 0;
-+ s = cin_skipcomment(s + 1);
-+ }
-+ else
-+ s = cin_skipcomment(s + 1);
-+ }
-+ else if ((STRNCMP(s, "class", 5) == 0 && !vim_isIDc(s[5]))
-+ || (STRNCMP(s, "struct", 6) == 0 && !vim_isIDc(s[6])))
-+ {
-+ class_or_struct = TRUE;
-+ lookfor_ctor_init = FALSE;
-+
-+ if (*s == 'c')
-+ s = cin_skipcomment(s + 5);
-+ else
-+ s = cin_skipcomment(s + 6);
-+ }
-+ else
-+ {
-+ if (s[0] == '{' || s[0] == '}' || s[0] == ';')
-+ {
-+ cpp_base_class = lookfor_ctor_init = class_or_struct = FALSE;
-+ }
-+ else if (s[0] == ')')
-+ {
-+ /* Constructor-initialization is assumed if we come across
-+ * something like "):" */
-+ class_or_struct = FALSE;
-+ lookfor_ctor_init = TRUE;
-+ }
-+ else if (s[0] == '?')
-+ {
-+ /* Avoid seeing '() :' after '?' as constructor init. */
-+ return FALSE;
-+ }
-+ else if (!vim_isIDc(s[0]))
-+ {
-+ /* if it is not an identifier, we are wrong */
-+ class_or_struct = FALSE;
-+ lookfor_ctor_init = FALSE;
-+ }
-+ else if (pos->col == 0)
-+ {
-+ /* it can't be a constructor-initialization any more */
-+ lookfor_ctor_init = FALSE;
-+
-+ /* the first statement starts here: lineup with this one... */
-+ if (cpp_base_class)
-+ pos->col = (colnr_T)(s - line);
-+ }
-+
-+ /* When the line ends in a comma don't align with it. */
-+ if (lnum == curwin->w_cursor.lnum && *s == ',' && cin_nocode(s + 1))
-+ pos->col = 0;
-+
-+ s = cin_skipcomment(s + 1);
-+ }
-+ }
-+
-+ cached->found = cpp_base_class;
-+ if (cpp_base_class)
-+ pos->lnum = lnum;
-+ return cpp_base_class;
-+ }
-+
-+ static int
-+ get_baseclass_amount(int col)
-+ {
-+ int amount;
-+ colnr_T vcol;
-+ pos_T *trypos;
-+
-+ if (col == 0)
-+ {
-+ amount = get_indent();
-+ if (find_last_paren(ml_get_curline(), '(', ')')
-+ && (trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
-+ amount = get_indent_lnum(trypos->lnum); /* XXX */
-+ if (!cin_ends_in(ml_get_curline(), (char_u *)",", NULL))
-+ amount += curbuf->b_ind_cpp_baseclass;
-+ }
-+ else
-+ {
-+ curwin->w_cursor.col = col;
-+ getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
-+ amount = (int)vcol;
-+ }
-+ if (amount < curbuf->b_ind_cpp_baseclass)
-+ amount = curbuf->b_ind_cpp_baseclass;
-+ return amount;
-+ }
-+
-+ /*
-+ * Return TRUE if string "s" ends with the string "find", possibly followed by
-+ * white space and comments. Skip strings and comments.
-+ * Ignore "ignore" after "find" if it's not NULL.
-+ */
-+ static int
-+ cin_ends_in(char_u *s, char_u *find, char_u *ignore)
-+ {
-+ char_u *p = s;
-+ char_u *r;
-+ int len = (int)STRLEN(find);
-+
-+ while (*p != NUL)
-+ {
-+ p = cin_skipcomment(p);
-+ if (STRNCMP(p, find, len) == 0)
-+ {
-+ r = skipwhite(p + len);
-+ if (ignore != NULL && STRNCMP(r, ignore, STRLEN(ignore)) == 0)
-+ r = skipwhite(r + STRLEN(ignore));
-+ if (cin_nocode(r))
-+ return TRUE;
-+ }
-+ if (*p != NUL)
-+ ++p;
-+ }
-+ return FALSE;
-+ }
-+
-+ /*
-+ * Return TRUE when "s" starts with "word" and then a non-ID character.
-+ */
-+ static int
-+ cin_starts_with(char_u *s, char *word)
-+ {
-+ int l = (int)STRLEN(word);
-+
-+ return (STRNCMP(s, word, l) == 0 && !vim_isIDc(s[l]));
-+ }
-+
-+ /*
-+ * Skip strings, chars and comments until at or past "trypos".
-+ * Return the column found.
-+ */
-+ static int
-+ cin_skip2pos(pos_T *trypos)
-+ {
-+ char_u *line;
-+ char_u *p;
-+ char_u *new_p;
-+
-+ p = line = ml_get(trypos->lnum);
-+ while (*p && (colnr_T)(p - line) < trypos->col)
-+ {
-+ if (cin_iscomment(p))
-+ p = cin_skipcomment(p);
-+ else
-+ {
-+ new_p = skip_string(p);
-+ if (new_p == p)
-+ ++p;
-+ else
-+ p = new_p;
-+ }
-+ }
-+ return (int)(p - line);
-+ }
-+
-+ /*
-+ * Find the '{' at the start of the block we are in.
-+ * Return NULL if no match found.
-+ * Ignore a '{' that is in a comment, makes indenting the next three lines
-+ * work. */
-+ /* foo() */
-+ /* { */
-+ /* } */
-+
-+ static pos_T *
-+ find_start_brace(void) /* XXX */
-+ {
-+ pos_T cursor_save;
-+ pos_T *trypos;
-+ pos_T *pos;
-+ static pos_T pos_copy;
-+
-+ cursor_save = curwin->w_cursor;
-+ while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP, 0)) != NULL)
-+ {
-+ pos_copy = *trypos; /* copy pos_T, next findmatch will change it */
-+ trypos = &pos_copy;
-+ curwin->w_cursor = *trypos;
-+ pos = NULL;
-+ /* ignore the { if it's in a // or / * * / comment */
-+ if ((colnr_T)cin_skip2pos(trypos) == trypos->col
-+ && (pos = ind_find_start_CORS(NULL)) == NULL) /* XXX */
-+ break;
-+ if (pos != NULL)
-+ curwin->w_cursor.lnum = pos->lnum;
-+ }
-+ curwin->w_cursor = cursor_save;
-+ return trypos;
-+ }
-+
-+ /*
-+ * Find the matching '(', ignoring it if it is in a comment.
-+ * Return NULL if no match found.
-+ */
-+ static pos_T *
-+ find_match_paren(int ind_maxparen) /* XXX */
-+ {
-+ return find_match_char('(', ind_maxparen);
-+ }
-+
-+ static pos_T *
-+ find_match_char(int c, int ind_maxparen) /* XXX */
-+ {
-+ pos_T cursor_save;
-+ pos_T *trypos;
-+ static pos_T pos_copy;
-+ int ind_maxp_wk;
-+
-+ cursor_save = curwin->w_cursor;
-+ ind_maxp_wk = ind_maxparen;
-+ retry:
-+ if ((trypos = findmatchlimit(NULL, c, 0, ind_maxp_wk)) != NULL)
-+ {
-+ /* check if the ( is in a // comment */
-+ if ((colnr_T)cin_skip2pos(trypos) > trypos->col)
-+ {
-+ ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum - trypos->lnum);
-+ if (ind_maxp_wk > 0)
-+ {
-+ curwin->w_cursor = *trypos;
-+ curwin->w_cursor.col = 0; /* XXX */
-+ goto retry;
-+ }
-+ trypos = NULL;
-+ }
-+ else
-+ {
-+ pos_T *trypos_wk;
-+
-+ pos_copy = *trypos; /* copy trypos, findmatch will change it */
-+ trypos = &pos_copy;
-+ curwin->w_cursor = *trypos;
-+ if ((trypos_wk = ind_find_start_CORS(NULL)) != NULL) /* XXX */
-+ {
-+ ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum
-+ - trypos_wk->lnum);
-+ if (ind_maxp_wk > 0)
-+ {
-+ curwin->w_cursor = *trypos_wk;
-+ goto retry;
-+ }
-+ trypos = NULL;
-+ }
-+ }
-+ }
-+ curwin->w_cursor = cursor_save;
-+ return trypos;
-+ }
-+
-+ /*
-+ * Find the matching '(', ignoring it if it is in a comment or before an
-+ * unmatched {.
-+ * Return NULL if no match found.
-+ */
-+ static pos_T *
-+ find_match_paren_after_brace (int ind_maxparen) /* XXX */
-+ {
-+ pos_T *trypos = find_match_paren(ind_maxparen);
-+
-+ if (trypos != NULL)
-+ {
-+ pos_T *tryposBrace = find_start_brace();
-+
-+ /* If both an unmatched '(' and '{' is found. Ignore the '('
-+ * position if the '{' is further down. */
-+ if (tryposBrace != NULL
-+ && (trypos->lnum != tryposBrace->lnum
-+ ? trypos->lnum < tryposBrace->lnum
-+ : trypos->col < tryposBrace->col))
-+ trypos = NULL;
-+ }
-+ return trypos;
-+ }
-+
-+ /*
-+ * Return ind_maxparen corrected for the difference in line number between the
-+ * cursor position and "startpos". This makes sure that searching for a
-+ * matching paren above the cursor line doesn't find a match because of
-+ * looking a few lines further.
-+ */
-+ static int
-+ corr_ind_maxparen(pos_T *startpos)
-+ {
-+ long n = (long)startpos->lnum - (long)curwin->w_cursor.lnum;
-+
-+ if (n > 0 && n < curbuf->b_ind_maxparen / 2)
-+ return curbuf->b_ind_maxparen - (int)n;
-+ return curbuf->b_ind_maxparen;
-+ }
-+
-+ /*
-+ * Set w_cursor.col to the column number of the last unmatched ')' or '{' in
-+ * line "l". "l" must point to the start of the line.
-+ */
-+ static int
-+ find_last_paren(char_u *l, int start, int end)
-+ {
-+ int i;
-+ int retval = FALSE;
-+ int open_count = 0;
-+
-+ curwin->w_cursor.col = 0; /* default is start of line */
-+
-+ for (i = 0; l[i] != NUL; i++)
-+ {
-+ i = (int)(cin_skipcomment(l + i) - l); /* ignore parens in comments */
-+ i = (int)(skip_string(l + i) - l); /* ignore parens in quotes */
-+ if (l[i] == start)
-+ ++open_count;
-+ else if (l[i] == end)
-+ {
-+ if (open_count > 0)
-+ --open_count;
-+ else
-+ {
-+ curwin->w_cursor.col = i;
-+ retval = TRUE;
-+ }
-+ }
-+ }
-+ return retval;
-+ }
-+
-+ /*
-+ * Parse 'cinoptions' and set the values in "curbuf".
-+ * Must be called when 'cinoptions', 'shiftwidth' and/or 'tabstop' changes.
-+ */
-+ void
-+ parse_cino(buf_T *buf)
-+ {
-+ char_u *p;
-+ char_u *l;
-+ char_u *digits;
-+ int n;
-+ int divider;
-+ int fraction = 0;
-+ int sw = (int)get_sw_value(buf);
-+
-+ /*
-+ * Set the default values.
-+ */
-+ /* Spaces from a block's opening brace the prevailing indent for that
-+ * block should be. */
-+ buf->b_ind_level = sw;
-+
-+ /* Spaces from the edge of the line an open brace that's at the end of a
-+ * line is imagined to be. */
-+ buf->b_ind_open_imag = 0;
-+
-+ /* Spaces from the prevailing indent for a line that is not preceded by
-+ * an opening brace. */
-+ buf->b_ind_no_brace = 0;
-+
-+ /* Column where the first { of a function should be located }. */
-+ buf->b_ind_first_open = 0;
-+
-+ /* Spaces from the prevailing indent a leftmost open brace should be
-+ * located. */
-+ buf->b_ind_open_extra = 0;
-+
-+ /* Spaces from the matching open brace (real location for one at the left
-+ * edge; imaginary location from one that ends a line) the matching close
-+ * brace should be located. */
-+ buf->b_ind_close_extra = 0;
-+
-+ /* Spaces from the edge of the line an open brace sitting in the leftmost
-+ * column is imagined to be. */
-+ buf->b_ind_open_left_imag = 0;
-+
-+ /* Spaces jump labels should be shifted to the left if N is non-negative,
-+ * otherwise the jump label will be put to column 1. */
-+ buf->b_ind_jump_label = -1;
-+
-+ /* Spaces from the switch() indent a "case xx" label should be located. */
-+ buf->b_ind_case = sw;
-+
-+ /* Spaces from the "case xx:" code after a switch() should be located. */
-+ buf->b_ind_case_code = sw;
-+
-+ /* Lineup break at end of case in switch() with case label. */
-+ buf->b_ind_case_break = 0;
-+
-+ /* Spaces from the class declaration indent a scope declaration label
-+ * should be located. */
-+ buf->b_ind_scopedecl = sw;
-+
-+ /* Spaces from the scope declaration label code should be located. */
-+ buf->b_ind_scopedecl_code = sw;
-+
-+ /* Amount K&R-style parameters should be indented. */
-+ buf->b_ind_param = sw;
-+
-+ /* Amount a function type spec should be indented. */
-+ buf->b_ind_func_type = sw;
-+
-+ /* Amount a cpp base class declaration or constructor initialization
-+ * should be indented. */
-+ buf->b_ind_cpp_baseclass = sw;
-+
-+ /* additional spaces beyond the prevailing indent a continuation line
-+ * should be located. */
-+ buf->b_ind_continuation = sw;
-+
-+ /* Spaces from the indent of the line with an unclosed parentheses. */
-+ buf->b_ind_unclosed = sw * 2;
-+
-+ /* Spaces from the indent of the line with an unclosed parentheses, which
-+ * itself is also unclosed. */
-+ buf->b_ind_unclosed2 = sw;
-+
-+ /* Suppress ignoring spaces from the indent of a line starting with an
-+ * unclosed parentheses. */
-+ buf->b_ind_unclosed_noignore = 0;
-+
-+ /* If the opening paren is the last nonwhite character on the line, and
-+ * b_ind_unclosed_wrapped is nonzero, use this indent relative to the outer
-+ * context (for very long lines). */
-+ buf->b_ind_unclosed_wrapped = 0;
-+
-+ /* Suppress ignoring white space when lining up with the character after
-+ * an unclosed parentheses. */
-+ buf->b_ind_unclosed_whiteok = 0;
-+
-+ /* Indent a closing parentheses under the line start of the matching
-+ * opening parentheses. */
-+ buf->b_ind_matching_paren = 0;
-+
-+ /* Indent a closing parentheses under the previous line. */
-+ buf->b_ind_paren_prev = 0;
-+
-+ /* Extra indent for comments. */
-+ buf->b_ind_comment = 0;
-+
-+ /* Spaces from the comment opener when there is nothing after it. */
-+ buf->b_ind_in_comment = 3;
-+
-+ /* Boolean: if non-zero, use b_ind_in_comment even if there is something
-+ * after the comment opener. */
-+ buf->b_ind_in_comment2 = 0;
-+
-+ /* Max lines to search for an open paren. */
-+ buf->b_ind_maxparen = 20;
-+
-+ /* Max lines to search for an open comment. */
-+ buf->b_ind_maxcomment = 70;
-+
-+ /* Handle braces for java code. */
-+ buf->b_ind_java = 0;
-+
-+ /* Not to confuse JS object properties with labels. */
-+ buf->b_ind_js = 0;
-+
-+ /* Handle blocked cases correctly. */
-+ buf->b_ind_keep_case_label = 0;
-+
-+ /* Handle C++ namespace. */
-+ buf->b_ind_cpp_namespace = 0;
-+
-+ /* Handle continuation lines containing conditions of if(), for() and
-+ * while(). */
-+ buf->b_ind_if_for_while = 0;
-+
-+ /* indentation for # comments */
-+ buf->b_ind_hash_comment = 0;
-+
-+ /* Handle C++ extern "C" or "C++" */
-+ buf->b_ind_cpp_extern_c = 0;
-+
-+ for (p = buf->b_p_cino; *p; )
-+ {
-+ l = p++;
-+ if (*p == '-')
-+ ++p;
-+ digits = p; /* remember where the digits start */
-+ n = getdigits(&p);
-+ divider = 0;
-+ if (*p == '.') /* ".5s" means a fraction */
-+ {
-+ fraction = atol((char *)++p);
-+ while (VIM_ISDIGIT(*p))
-+ {
-+ ++p;
-+ if (divider)
-+ divider *= 10;
-+ else
-+ divider = 10;
-+ }
-+ }
-+ if (*p == 's') /* "2s" means two times 'shiftwidth' */
-+ {
-+ if (p == digits)
-+ n = sw; /* just "s" is one 'shiftwidth' */
-+ else
-+ {
-+ n *= sw;
-+ if (divider)
-+ n += (sw * fraction + divider / 2) / divider;
-+ }
-+ ++p;
-+ }
-+ if (l[1] == '-')
-+ n = -n;
-+
-+ /* When adding an entry here, also update the default 'cinoptions' in
-+ * doc/indent.txt, and add explanation for it! */
-+ switch (*l)
-+ {
-+ case '>': buf->b_ind_level = n; break;
-+ case 'e': buf->b_ind_open_imag = n; break;
-+ case 'n': buf->b_ind_no_brace = n; break;
-+ case 'f': buf->b_ind_first_open = n; break;
-+ case '{': buf->b_ind_open_extra = n; break;
-+ case '}': buf->b_ind_close_extra = n; break;
-+ case '^': buf->b_ind_open_left_imag = n; break;
-+ case 'L': buf->b_ind_jump_label = n; break;
-+ case ':': buf->b_ind_case = n; break;
-+ case '=': buf->b_ind_case_code = n; break;
-+ case 'b': buf->b_ind_case_break = n; break;
-+ case 'p': buf->b_ind_param = n; break;
-+ case 't': buf->b_ind_func_type = n; break;
-+ case '/': buf->b_ind_comment = n; break;
-+ case 'c': buf->b_ind_in_comment = n; break;
-+ case 'C': buf->b_ind_in_comment2 = n; break;
-+ case 'i': buf->b_ind_cpp_baseclass = n; break;
-+ case '+': buf->b_ind_continuation = n; break;
-+ case '(': buf->b_ind_unclosed = n; break;
-+ case 'u': buf->b_ind_unclosed2 = n; break;
-+ case 'U': buf->b_ind_unclosed_noignore = n; break;
-+ case 'W': buf->b_ind_unclosed_wrapped = n; break;
-+ case 'w': buf->b_ind_unclosed_whiteok = n; break;
-+ case 'm': buf->b_ind_matching_paren = n; break;
-+ case 'M': buf->b_ind_paren_prev = n; break;
-+ case ')': buf->b_ind_maxparen = n; break;
-+ case '*': buf->b_ind_maxcomment = n; break;
-+ case 'g': buf->b_ind_scopedecl = n; break;
-+ case 'h': buf->b_ind_scopedecl_code = n; break;
-+ case 'j': buf->b_ind_java = n; break;
-+ case 'J': buf->b_ind_js = n; break;
-+ case 'l': buf->b_ind_keep_case_label = n; break;
-+ case '#': buf->b_ind_hash_comment = n; break;
-+ case 'N': buf->b_ind_cpp_namespace = n; break;
-+ case 'k': buf->b_ind_if_for_while = n; break;
-+ case 'E': buf->b_ind_cpp_extern_c = n; break;
-+ }
-+ if (*p == ',')
-+ ++p;
-+ }
-+ }
-+
-+ /*
-+ * Return the desired indent for C code.
-+ * Return -1 if the indent should be left alone (inside a raw string).
-+ */
-+ int
-+ get_c_indent(void)
-+ {
-+ pos_T cur_curpos;
-+ int amount;
-+ int scope_amount;
-+ int cur_amount = MAXCOL;
-+ colnr_T col;
-+ char_u *theline;
-+ char_u *linecopy;
-+ pos_T *trypos;
-+ pos_T *comment_pos;
-+ pos_T *tryposBrace = NULL;
-+ pos_T tryposCopy;
-+ pos_T our_paren_pos;
-+ char_u *start;
-+ int start_brace;
-+ #define BRACE_IN_COL0 1 /* '{' is in column 0 */
-+ #define BRACE_AT_START 2 /* '{' is at start of line */
-+ #define BRACE_AT_END 3 /* '{' is at end of line */
-+ linenr_T ourscope;
-+ char_u *l;
-+ char_u *look;
-+ char_u terminated;
-+ int lookfor;
-+ #define LOOKFOR_INITIAL 0
-+ #define LOOKFOR_IF 1
-+ #define LOOKFOR_DO 2
-+ #define LOOKFOR_CASE 3
-+ #define LOOKFOR_ANY 4
-+ #define LOOKFOR_TERM 5
-+ #define LOOKFOR_UNTERM 6
-+ #define LOOKFOR_SCOPEDECL 7
-+ #define LOOKFOR_NOBREAK 8
-+ #define LOOKFOR_CPP_BASECLASS 9
-+ #define LOOKFOR_ENUM_OR_INIT 10
-+ #define LOOKFOR_JS_KEY 11
-+ #define LOOKFOR_COMMA 12
-+
-+ int whilelevel;
-+ linenr_T lnum;
-+ int n;
-+ int iscase;
-+ int lookfor_break;
-+ int lookfor_cpp_namespace = FALSE;
-+ int cont_amount = 0; /* amount for continuation line */
-+ int original_line_islabel;
-+ int added_to_amount = 0;
-+ int js_cur_has_key = 0;
-+ linenr_T raw_string_start = 0;
-+ cpp_baseclass_cache_T cache_cpp_baseclass = { FALSE, { MAXLNUM, 0 } };
-+
-+ /* make a copy, value is changed below */
-+ int ind_continuation = curbuf->b_ind_continuation;
-+
-+ /* remember where the cursor was when we started */
-+ cur_curpos = curwin->w_cursor;
-+
-+ /* if we are at line 1 zero indent is fine, right? */
-+ if (cur_curpos.lnum == 1)
-+ return 0;
-+
-+ /* Get a copy of the current contents of the line.
-+ * This is required, because only the most recent line obtained with
-+ * ml_get is valid! */
-+ linecopy = vim_strsave(ml_get(cur_curpos.lnum));
-+ if (linecopy == NULL)
-+ return 0;
-+
-+ /*
-+ * In insert mode and the cursor is on a ')' truncate the line at the
-+ * cursor position. We don't want to line up with the matching '(' when
-+ * inserting new stuff.
-+ * For unknown reasons the cursor might be past the end of the line, thus
-+ * check for that.
-+ */
-+ if ((State & INSERT)
-+ && curwin->w_cursor.col < (colnr_T)STRLEN(linecopy)
-+ && linecopy[curwin->w_cursor.col] == ')')
-+ linecopy[curwin->w_cursor.col] = NUL;
-+
-+ theline = skipwhite(linecopy);
-+
-+ /* move the cursor to the start of the line */
-+
-+ curwin->w_cursor.col = 0;
-+
-+ original_line_islabel = cin_islabel(); /* XXX */
-+
-+ /*
-+ * If we are inside a raw string don't change the indent.
-+ * Ignore a raw string inside a comment.
-+ */
-+ comment_pos = ind_find_start_comment();
-+ if (comment_pos != NULL)
-+ {
-+ /* findmatchlimit() static pos is overwritten, make a copy */
-+ tryposCopy = *comment_pos;
-+ comment_pos = &tryposCopy;
-+ }
-+ trypos = find_start_rawstring(curbuf->b_ind_maxcomment);
-+ if (trypos != NULL && (comment_pos == NULL
-+ || LT_POS(*trypos, *comment_pos)))
-+ {
-+ amount = -1;
-+ goto laterend;
-+ }
-+
-+ /*
-+ * #defines and so on always go at the left when included in 'cinkeys'.
-+ */
-+ if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE)))
-+ {
-+ amount = curbuf->b_ind_hash_comment;
-+ goto theend;
-+ }
-+
-+ /*
-+ * Is it a non-case label? Then that goes at the left margin too unless:
-+ * - JS flag is set.
-+ * - 'L' item has a positive value.
-+ */
-+ if (original_line_islabel && !curbuf->b_ind_js
-+ && curbuf->b_ind_jump_label < 0)
-+ {
-+ amount = 0;
-+ goto theend;
-+ }
-+
-+ /*
-+ * If we're inside a "//" comment and there is a "//" comment in a
-+ * previous line, lineup with that one.
-+ */
-+ if (cin_islinecomment(theline)
-+ && (trypos = find_line_comment()) != NULL) /* XXX */
-+ {
-+ /* find how indented the line beginning the comment is */
-+ getvcol(curwin, trypos, &col, NULL, NULL);
-+ amount = col;
-+ goto theend;
-+ }
-+
-+ /*
-+ * If we're inside a comment and not looking at the start of the
-+ * comment, try using the 'comments' option.
-+ */
-+ if (!cin_iscomment(theline) && comment_pos != NULL) /* XXX */
-+ {
-+ int lead_start_len = 2;
-+ int lead_middle_len = 1;
-+ char_u lead_start[COM_MAX_LEN]; /* start-comment string */
-+ char_u lead_middle[COM_MAX_LEN]; /* middle-comment string */
-+ char_u lead_end[COM_MAX_LEN]; /* end-comment string */
-+ char_u *p;
-+ int start_align = 0;
-+ int start_off = 0;
-+ int done = FALSE;
-+
-+ /* find how indented the line beginning the comment is */
-+ getvcol(curwin, comment_pos, &col, NULL, NULL);
-+ amount = col;
-+ *lead_start = NUL;
-+ *lead_middle = NUL;
-+
-+ p = curbuf->b_p_com;
-+ while (*p != NUL)
-+ {
-+ int align = 0;
-+ int off = 0;
-+ int what = 0;
-+
-+ while (*p != NUL && *p != ':')
-+ {
-+ if (*p == COM_START || *p == COM_END || *p == COM_MIDDLE)
-+ what = *p++;
-+ else if (*p == COM_LEFT || *p == COM_RIGHT)
-+ align = *p++;
-+ else if (VIM_ISDIGIT(*p) || *p == '-')
-+ off = getdigits(&p);
-+ else
-+ ++p;
-+ }
-+
-+ if (*p == ':')
-+ ++p;
-+ (void)copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
-+ if (what == COM_START)
-+ {
-+ STRCPY(lead_start, lead_end);
-+ lead_start_len = (int)STRLEN(lead_start);
-+ start_off = off;
-+ start_align = align;
-+ }
-+ else if (what == COM_MIDDLE)
-+ {
-+ STRCPY(lead_middle, lead_end);
-+ lead_middle_len = (int)STRLEN(lead_middle);
-+ }
-+ else if (what == COM_END)
-+ {
-+ /* If our line starts with the middle comment string, line it
-+ * up with the comment opener per the 'comments' option. */
-+ if (STRNCMP(theline, lead_middle, lead_middle_len) == 0
-+ && STRNCMP(theline, lead_end, STRLEN(lead_end)) != 0)
-+ {
-+ done = TRUE;
-+ if (curwin->w_cursor.lnum > 1)
-+ {
-+ /* If the start comment string matches in the previous
-+ * line, use the indent of that line plus offset. If
-+ * the middle comment string matches in the previous
-+ * line, use the indent of that line. XXX */
-+ look = skipwhite(ml_get(curwin->w_cursor.lnum - 1));
-+ if (STRNCMP(look, lead_start, lead_start_len) == 0)
-+ amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
-+ else if (STRNCMP(look, lead_middle,
-+ lead_middle_len) == 0)
-+ {
-+ amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
-+ break;
-+ }
-+ /* If the start comment string doesn't match with the
-+ * start of the comment, skip this entry. XXX */
-+ else if (STRNCMP(ml_get(comment_pos->lnum) + comment_pos->col,
-+ lead_start, lead_start_len) != 0)
-+ continue;
-+ }
-+ if (start_off != 0)
-+ amount += start_off;
-+ else if (start_align == COM_RIGHT)
-+ amount += vim_strsize(lead_start)
-+ - vim_strsize(lead_middle);
-+ break;
-+ }
-+
-+ /* If our line starts with the end comment string, line it up
-+ * with the middle comment */
-+ if (STRNCMP(theline, lead_middle, lead_middle_len) != 0
-+ && STRNCMP(theline, lead_end, STRLEN(lead_end)) == 0)
-+ {
-+ amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
-+ /* XXX */
-+ if (off != 0)
-+ amount += off;
-+ else if (align == COM_RIGHT)
-+ amount += vim_strsize(lead_start)
-+ - vim_strsize(lead_middle);
-+ done = TRUE;
-+ break;
-+ }
-+ }
-+ }
-+
-+ /* If our line starts with an asterisk, line up with the
-+ * asterisk in the comment opener; otherwise, line up
-+ * with the first character of the comment text.
-+ */
-+ if (done)
-+ ;
-+ else if (theline[0] == '*')
-+ amount += 1;
-+ else
-+ {
-+ /*
-+ * If we are more than one line away from the comment opener, take
-+ * the indent of the previous non-empty line. If 'cino' has "CO"
-+ * and we are just below the comment opener and there are any
-+ * white characters after it line up with the text after it;
-+ * otherwise, add the amount specified by "c" in 'cino'
-+ */
-+ amount = -1;
-+ for (lnum = cur_curpos.lnum - 1; lnum > comment_pos->lnum; --lnum)
-+ {
-+ if (linewhite(lnum)) /* skip blank lines */
-+ continue;
-+ amount = get_indent_lnum(lnum); /* XXX */
-+ break;
-+ }
-+ if (amount == -1) /* use the comment opener */
-+ {
-+ if (!curbuf->b_ind_in_comment2)
-+ {
-+ start = ml_get(comment_pos->lnum);
-+ look = start + comment_pos->col + 2; /* skip / and * */
-+ if (*look != NUL) /* if something after it */
-+ comment_pos->col = (colnr_T)(skipwhite(look) - start);
-+ }
-+ getvcol(curwin, comment_pos, &col, NULL, NULL);
-+ amount = col;
-+ if (curbuf->b_ind_in_comment2 || *look == NUL)
-+ amount += curbuf->b_ind_in_comment;
-+ }
-+ }
-+ goto theend;
-+ }
-+
-+ /*
-+ * Are we looking at a ']' that has a match?
-+ */
-+ if (*skipwhite(theline) == ']'
-+ && (trypos = find_match_char('[', curbuf->b_ind_maxparen)) != NULL)
-+ {
-+ /* align with the line containing the '['. */
-+ amount = get_indent_lnum(trypos->lnum);
-+ goto theend;
-+ }
-+
-+ /*
-+ * Are we inside parentheses or braces?
-+ */ /* XXX */
-+ if (((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL
-+ && curbuf->b_ind_java == 0)
-+ || (tryposBrace = find_start_brace()) != NULL
-+ || trypos != NULL)
-+ {
-+ if (trypos != NULL && tryposBrace != NULL)
-+ {
-+ /* Both an unmatched '(' and '{' is found. Use the one which is
-+ * closer to the current cursor position, set the other to NULL. */
-+ if (trypos->lnum != tryposBrace->lnum
-+ ? trypos->lnum < tryposBrace->lnum
-+ : trypos->col < tryposBrace->col)
-+ trypos = NULL;
-+ else
-+ tryposBrace = NULL;
-+ }
-+
-+ if (trypos != NULL)
-+ {
-+ /*
-+ * If the matching paren is more than one line away, use the indent of
-+ * a previous non-empty line that matches the same paren.
-+ */
-+ if (theline[0] == ')' && curbuf->b_ind_paren_prev)
-+ {
-+ /* Line up with the start of the matching paren line. */
-+ amount = get_indent_lnum(curwin->w_cursor.lnum - 1); /* XXX */
-+ }
-+ else
-+ {
-+ amount = -1;
-+ our_paren_pos = *trypos;
-+ for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum)
-+ {
-+ l = skipwhite(ml_get(lnum));
-+ if (cin_nocode(l)) /* skip comment lines */
-+ continue;
-+ if (cin_ispreproc_cont(&l, &lnum, &amount))
-+ continue; /* ignore #define, #if, etc. */
-+ curwin->w_cursor.lnum = lnum;
-+
-+ /* Skip a comment or raw string. XXX */
-+ if ((trypos = ind_find_start_CORS(NULL)) != NULL)
-+ {
-+ lnum = trypos->lnum + 1;
-+ continue;
-+ }
-+
-+ /* XXX */
-+ if ((trypos = find_match_paren(
-+ corr_ind_maxparen(&cur_curpos))) != NULL
-+ && trypos->lnum == our_paren_pos.lnum
-+ && trypos->col == our_paren_pos.col)
-+ {
-+ amount = get_indent_lnum(lnum); /* XXX */
-+
-+ if (theline[0] == ')')
-+ {
-+ if (our_paren_pos.lnum != lnum
-+ && cur_amount > amount)
-+ cur_amount = amount;
-+ amount = -1;
-+ }
-+ break;
-+ }
-+ }
-+ }
-+
-+ /*
-+ * Line up with line where the matching paren is. XXX
-+ * If the line starts with a '(' or the indent for unclosed
-+ * parentheses is zero, line up with the unclosed parentheses.
-+ */
-+ if (amount == -1)
-+ {
-+ int ignore_paren_col = 0;
-+ int is_if_for_while = 0;
-+
-+ if (curbuf->b_ind_if_for_while)
-+ {
-+ /* Look for the outermost opening parenthesis on this line
-+ * and check whether it belongs to an "if", "for" or "while". */
-+
-+ pos_T cursor_save = curwin->w_cursor;
-+ pos_T outermost;
-+ char_u *line;
-+
-+ trypos = &our_paren_pos;
-+ do {
-+ outermost = *trypos;
-+ curwin->w_cursor.lnum = outermost.lnum;
-+ curwin->w_cursor.col = outermost.col;
-+
-+ trypos = find_match_paren(curbuf->b_ind_maxparen);
-+ } while (trypos && trypos->lnum == outermost.lnum);
-+
-+ curwin->w_cursor = cursor_save;
-+
-+ line = ml_get(outermost.lnum);
-+
-+ is_if_for_while =
-+ cin_is_if_for_while_before_offset(line, &outermost.col);
-+ }
-+
-+ amount = skip_label(our_paren_pos.lnum, &look);
-+ look = skipwhite(look);
-+ if (*look == '(')
-+ {
-+ linenr_T save_lnum = curwin->w_cursor.lnum;
-+ char_u *line;
-+ int look_col;
-+
-+ /* Ignore a '(' in front of the line that has a match before
-+ * our matching '('. */
-+ curwin->w_cursor.lnum = our_paren_pos.lnum;
-+ line = ml_get_curline();
-+ look_col = (int)(look - line);
-+ curwin->w_cursor.col = look_col + 1;
-+ if ((trypos = findmatchlimit(NULL, ')', 0,
-+ curbuf->b_ind_maxparen))
-+ != NULL
-+ && trypos->lnum == our_paren_pos.lnum
-+ && trypos->col < our_paren_pos.col)
-+ ignore_paren_col = trypos->col + 1;
-+
-+ curwin->w_cursor.lnum = save_lnum;
-+ look = ml_get(our_paren_pos.lnum) + look_col;
-+ }
-+ if (theline[0] == ')' || (curbuf->b_ind_unclosed == 0
-+ && is_if_for_while == 0)
-+ || (!curbuf->b_ind_unclosed_noignore && *look == '('
-+ && ignore_paren_col == 0))
-+ {
-+ /*
-+ * If we're looking at a close paren, line up right there;
-+ * otherwise, line up with the next (non-white) character.
-+ * When b_ind_unclosed_wrapped is set and the matching paren is
-+ * the last nonwhite character of the line, use either the
-+ * indent of the current line or the indentation of the next
-+ * outer paren and add b_ind_unclosed_wrapped (for very long
-+ * lines).
-+ */
-+ if (theline[0] != ')')
-+ {
-+ cur_amount = MAXCOL;
-+ l = ml_get(our_paren_pos.lnum);
-+ if (curbuf->b_ind_unclosed_wrapped
-+ && cin_ends_in(l, (char_u *)"(", NULL))
-+ {
-+ /* look for opening unmatched paren, indent one level
-+ * for each additional level */
-+ n = 1;
-+ for (col = 0; col < our_paren_pos.col; ++col)
-+ {
-+ switch (l[col])
-+ {
-+ case '(':
-+ case '{': ++n;
-+ break;
-+
-+ case ')':
-+ case '}': if (n > 1)
-+ --n;
-+ break;
-+ }
-+ }
-+
-+ our_paren_pos.col = 0;
-+ amount += n * curbuf->b_ind_unclosed_wrapped;
-+ }
-+ else if (curbuf->b_ind_unclosed_whiteok)
-+ our_paren_pos.col++;
-+ else
-+ {
-+ col = our_paren_pos.col + 1;
-+ while (VIM_ISWHITE(l[col]))
-+ col++;
-+ if (l[col] != NUL) /* In case of trailing space */
-+ our_paren_pos.col = col;
-+ else
-+ our_paren_pos.col++;
-+ }
-+ }
-+
-+ /*
-+ * Find how indented the paren is, or the character after it
-+ * if we did the above "if".
-+ */
-+ if (our_paren_pos.col > 0)
-+ {
-+ getvcol(curwin, &our_paren_pos, &col, NULL, NULL);
-+ if (cur_amount > (int)col)
-+ cur_amount = col;
-+ }
-+ }
-+
-+ if (theline[0] == ')' && curbuf->b_ind_matching_paren)
-+ {
-+ /* Line up with the start of the matching paren line. */
-+ }
-+ else if ((curbuf->b_ind_unclosed == 0 && is_if_for_while == 0)
-+ || (!curbuf->b_ind_unclosed_noignore
-+ && *look == '(' && ignore_paren_col == 0))
-+ {
-+ if (cur_amount != MAXCOL)
-+ amount = cur_amount;
-+ }
-+ else
-+ {
-+ /* Add b_ind_unclosed2 for each '(' before our matching one,
-+ * but ignore (void) before the line (ignore_paren_col). */
-+ col = our_paren_pos.col;
-+ while ((int)our_paren_pos.col > ignore_paren_col)
-+ {
-+ --our_paren_pos.col;
-+ switch (*ml_get_pos(&our_paren_pos))
-+ {
-+ case '(': amount += curbuf->b_ind_unclosed2;
-+ col = our_paren_pos.col;
-+ break;
-+ case ')': amount -= curbuf->b_ind_unclosed2;
-+ col = MAXCOL;
-+ break;
-+ }
-+ }
-+
-+ /* Use b_ind_unclosed once, when the first '(' is not inside
-+ * braces */
-+ if (col == MAXCOL)
-+ amount += curbuf->b_ind_unclosed;
-+ else
-+ {
-+ curwin->w_cursor.lnum = our_paren_pos.lnum;
-+ curwin->w_cursor.col = col;
-+ if (find_match_paren_after_brace(curbuf->b_ind_maxparen)
-+ != NULL)
-+ amount += curbuf->b_ind_unclosed2;
-+ else
-+ {
-+ if (is_if_for_while)
-+ amount += curbuf->b_ind_if_for_while;
-+ else
-+ amount += curbuf->b_ind_unclosed;
-+ }
-+ }
-+ /*
-+ * For a line starting with ')' use the minimum of the two
-+ * positions, to avoid giving it more indent than the previous
-+ * lines:
-+ * func_long_name( if (x
-+ * arg && yy
-+ * ) ^ not here ) ^ not here
-+ */
-+ if (cur_amount < amount)
-+ amount = cur_amount;
-+ }
-+ }
-+
-+ /* add extra indent for a comment */
-+ if (cin_iscomment(theline))
-+ amount += curbuf->b_ind_comment;
-+ }
-+ else
-+ {
-+ /*
-+ * We are inside braces, there is a { before this line at the position
-+ * stored in tryposBrace.
-+ * Make a copy of tryposBrace, it may point to pos_copy inside
-+ * find_start_brace(), which may be changed somewhere.
-+ */
-+ tryposCopy = *tryposBrace;
-+ tryposBrace = &tryposCopy;
-+ trypos = tryposBrace;
-+ ourscope = trypos->lnum;
-+ start = ml_get(ourscope);
-+
-+ /*
-+ * Now figure out how indented the line is in general.
-+ * If the brace was at the start of the line, we use that;
-+ * otherwise, check out the indentation of the line as
-+ * a whole and then add the "imaginary indent" to that.
-+ */
-+ look = skipwhite(start);
-+ if (*look == '{')
-+ {
-+ getvcol(curwin, trypos, &col, NULL, NULL);
-+ amount = col;
-+ if (*start == '{')
-+ start_brace = BRACE_IN_COL0;
-+ else
-+ start_brace = BRACE_AT_START;
-+ }
-+ else
-+ {
-+ /* That opening brace might have been on a continuation
-+ * line. if so, find the start of the line. */
-+ curwin->w_cursor.lnum = ourscope;
-+
-+ /* Position the cursor over the rightmost paren, so that
-+ * matching it will take us back to the start of the line. */
-+ lnum = ourscope;
-+ if (find_last_paren(start, '(', ')')
-+ && (trypos = find_match_paren(curbuf->b_ind_maxparen))
-+ != NULL)
-+ lnum = trypos->lnum;
-+
-+ /* It could have been something like
-+ * case 1: if (asdf &&
-+ * ldfd) {
-+ * }
-+ */
-+ if ((curbuf->b_ind_js || curbuf->b_ind_keep_case_label)
-+ && cin_iscase(skipwhite(ml_get_curline()), FALSE))
-+ amount = get_indent();
-+ else if (curbuf->b_ind_js)
-+ amount = get_indent_lnum(lnum);
-+ else
-+ amount = skip_label(lnum, &l);
-+
-+ start_brace = BRACE_AT_END;
-+ }
-+
-+ /* For Javascript check if the line starts with "key:". */
-+ if (curbuf->b_ind_js)
-+ js_cur_has_key = cin_has_js_key(theline);
-+
-+ /*
-+ * If we're looking at a closing brace, that's where
-+ * we want to be. otherwise, add the amount of room
-+ * that an indent is supposed to be.
-+ */
-+ if (theline[0] == '}')
-+ {
-+ /*
-+ * they may want closing braces to line up with something
-+ * other than the open brace. indulge them, if so.
-+ */
-+ amount += curbuf->b_ind_close_extra;
-+ }
-+ else
-+ {
-+ /*
-+ * If we're looking at an "else", try to find an "if"
-+ * to match it with.
-+ * If we're looking at a "while", try to find a "do"
-+ * to match it with.
-+ */
-+ lookfor = LOOKFOR_INITIAL;
-+ if (cin_iselse(theline))
-+ lookfor = LOOKFOR_IF;
-+ else if (cin_iswhileofdo(theline, cur_curpos.lnum)) /* XXX */
-+ lookfor = LOOKFOR_DO;
-+ if (lookfor != LOOKFOR_INITIAL)
-+ {
-+ curwin->w_cursor.lnum = cur_curpos.lnum;
-+ if (find_match(lookfor, ourscope) == OK)
-+ {
-+ amount = get_indent(); /* XXX */
-+ goto theend;
-+ }
-+ }
-+
-+ /*
-+ * We get here if we are not on an "while-of-do" or "else" (or
-+ * failed to find a matching "if").
-+ * Search backwards for something to line up with.
-+ * First set amount for when we don't find anything.
-+ */
-+
-+ /*
-+ * if the '{' is _really_ at the left margin, use the imaginary
-+ * location of a left-margin brace. Otherwise, correct the
-+ * location for b_ind_open_extra.
-+ */
-+
-+ if (start_brace == BRACE_IN_COL0) /* '{' is in column 0 */
-+ {
-+ amount = curbuf->b_ind_open_left_imag;
-+ lookfor_cpp_namespace = TRUE;
-+ }
-+ else if (start_brace == BRACE_AT_START &&
-+ lookfor_cpp_namespace) /* '{' is at start */
-+ {
-+
-+ lookfor_cpp_namespace = TRUE;
-+ }
-+ else
-+ {
-+ if (start_brace == BRACE_AT_END) /* '{' is at end of line */
-+ {
-+ amount += curbuf->b_ind_open_imag;
-+
-+ l = skipwhite(ml_get_curline());
-+ if (cin_is_cpp_namespace(l))
-+ amount += curbuf->b_ind_cpp_namespace;
-+ else if (cin_is_cpp_extern_c(l))
-+ amount += curbuf->b_ind_cpp_extern_c;
-+ }
-+ else
-+ {
-+ /* Compensate for adding b_ind_open_extra later. */
-+ amount -= curbuf->b_ind_open_extra;
-+ if (amount < 0)
-+ amount = 0;
-+ }
-+ }
-+
-+ lookfor_break = FALSE;
-+
-+ if (cin_iscase(theline, FALSE)) /* it's a switch() label */
-+ {
-+ lookfor = LOOKFOR_CASE; /* find a previous switch() label */
-+ amount += curbuf->b_ind_case;
-+ }
-+ else if (cin_isscopedecl(theline)) /* private:, ... */
-+ {
-+ lookfor = LOOKFOR_SCOPEDECL; /* class decl is this block */
-+ amount += curbuf->b_ind_scopedecl;
-+ }
-+ else
-+ {
-+ if (curbuf->b_ind_case_break && cin_isbreak(theline))
-+ /* break; ... */
-+ lookfor_break = TRUE;
-+
-+ lookfor = LOOKFOR_INITIAL;
-+ /* b_ind_level from start of block */
-+ amount += curbuf->b_ind_level;
-+ }
-+ scope_amount = amount;
-+ whilelevel = 0;
-+
-+ /*
-+ * Search backwards. If we find something we recognize, line up
-+ * with that.
-+ *
-+ * If we're looking at an open brace, indent
-+ * the usual amount relative to the conditional
-+ * that opens the block.
-+ */
-+ curwin->w_cursor = cur_curpos;
-+ for (;;)
-+ {
-+ curwin->w_cursor.lnum--;
-+ curwin->w_cursor.col = 0;
-+
-+ /*
-+ * If we went all the way back to the start of our scope, line
-+ * up with it.
-+ */
-+ if (curwin->w_cursor.lnum <= ourscope)
-+ {
-+ /* We reached end of scope:
-+ * If looking for a enum or structure initialization
-+ * go further back:
-+ * If it is an initializer (enum xxx or xxx =), then
-+ * don't add ind_continuation, otherwise it is a variable
-+ * declaration:
-+ * int x,
-+ * here; <-- add ind_continuation
-+ */
-+ if (lookfor == LOOKFOR_ENUM_OR_INIT)
-+ {
-+ if (curwin->w_cursor.lnum == 0
-+ || curwin->w_cursor.lnum
-+ < ourscope - curbuf->b_ind_maxparen)
-+ {
-+ /* nothing found (abuse curbuf->b_ind_maxparen as
-+ * limit) assume terminated line (i.e. a variable
-+ * initialization) */
-+ if (cont_amount > 0)
-+ amount = cont_amount;
-+ else if (!curbuf->b_ind_js)
-+ amount += ind_continuation;
-+ break;
-+ }
-+
-+ l = ml_get_curline();
-+
-+ /*
-+ * If we're in a comment or raw string now, skip to
-+ * the start of it.
-+ */
-+ trypos = ind_find_start_CORS(NULL);
-+ if (trypos != NULL)
-+ {
-+ curwin->w_cursor.lnum = trypos->lnum + 1;
-+ curwin->w_cursor.col = 0;
-+ continue;
-+ }
-+
-+ /*
-+ * Skip preprocessor directives and blank lines.
-+ */
-+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum,
-+ &amount))
-+ continue;
-+
-+ if (cin_nocode(l))
-+ continue;
-+
-+ terminated = cin_isterminated(l, FALSE, TRUE);
-+
-+ /*
-+ * If we are at top level and the line looks like a
-+ * function declaration, we are done
-+ * (it's a variable declaration).
-+ */
-+ if (start_brace != BRACE_IN_COL0
-+ || !cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0))
-+ {
-+ /* if the line is terminated with another ','
-+ * it is a continued variable initialization.
-+ * don't add extra indent.
-+ * TODO: does not work, if a function
-+ * declaration is split over multiple lines:
-+ * cin_isfuncdecl returns FALSE then.
-+ */
-+ if (terminated == ',')
-+ break;
-+
-+ /* if it es a enum declaration or an assignment,
-+ * we are done.
-+ */
-+ if (terminated != ';' && cin_isinit())
-+ break;
-+
-+ /* nothing useful found */
-+ if (terminated == 0 || terminated == '{')
-+ continue;
-+ }
-+
-+ if (terminated != ';')
-+ {
-+ /* Skip parens and braces. Position the cursor
-+ * over the rightmost paren, so that matching it
-+ * will take us back to the start of the line.
-+ */ /* XXX */
-+ trypos = NULL;
-+ if (find_last_paren(l, '(', ')'))
-+ trypos = find_match_paren(
-+ curbuf->b_ind_maxparen);
-+
-+ if (trypos == NULL && find_last_paren(l, '{', '}'))
-+ trypos = find_start_brace();
-+
-+ if (trypos != NULL)
-+ {
-+ curwin->w_cursor.lnum = trypos->lnum + 1;
-+ curwin->w_cursor.col = 0;
-+ continue;
-+ }
-+ }
-+
-+ /* it's a variable declaration, add indentation
-+ * like in
-+ * int a,
-+ * b;
-+ */
-+ if (cont_amount > 0)
-+ amount = cont_amount;
-+ else
-+ amount += ind_continuation;
-+ }
-+ else if (lookfor == LOOKFOR_UNTERM)
-+ {
-+ if (cont_amount > 0)
-+ amount = cont_amount;
-+ else
-+ amount += ind_continuation;
-+ }
-+ else
-+ {
-+ if (lookfor != LOOKFOR_TERM
-+ && lookfor != LOOKFOR_CPP_BASECLASS
-+ && lookfor != LOOKFOR_COMMA)
-+ {
-+ amount = scope_amount;
-+ if (theline[0] == '{')
-+ {
-+ amount += curbuf->b_ind_open_extra;
-+ added_to_amount = curbuf->b_ind_open_extra;
-+ }
-+ }
-+
-+ if (lookfor_cpp_namespace)
-+ {
-+ /*
-+ * Looking for C++ namespace, need to look further
-+ * back.
-+ */
-+ if (curwin->w_cursor.lnum == ourscope)
-+ continue;
-+
-+ if (curwin->w_cursor.lnum == 0
-+ || curwin->w_cursor.lnum
-+ < ourscope - FIND_NAMESPACE_LIM)
-+ break;
-+
-+ l = ml_get_curline();
-+
-+ /* If we're in a comment or raw string now, skip
-+ * to the start of it. */
-+ trypos = ind_find_start_CORS(NULL);
-+ if (trypos != NULL)
-+ {
-+ curwin->w_cursor.lnum = trypos->lnum + 1;
-+ curwin->w_cursor.col = 0;
-+ continue;
-+ }
-+
-+ /* Skip preprocessor directives and blank lines. */
-+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum,
-+ &amount))
-+ continue;
-+
-+ /* Finally the actual check for "namespace". */
-+ if (cin_is_cpp_namespace(l))
-+ {
-+ amount += curbuf->b_ind_cpp_namespace
-+ - added_to_amount;
-+ break;
-+ }
-+ else if (cin_is_cpp_extern_c(l))
-+ {
-+ amount += curbuf->b_ind_cpp_extern_c
-+ - added_to_amount;
-+ break;
-+ }
-+
-+ if (cin_nocode(l))
-+ continue;
-+ }
-+ }
-+ break;
-+ }
-+
-+ /*
-+ * If we're in a comment or raw string now, skip to the start
-+ * of it.
-+ */ /* XXX */
-+ if ((trypos = ind_find_start_CORS(&raw_string_start)) != NULL)
-+ {
-+ curwin->w_cursor.lnum = trypos->lnum + 1;
-+ curwin->w_cursor.col = 0;
-+ continue;
-+ }
-+
-+ l = ml_get_curline();
-+
-+ /*
-+ * If this is a switch() label, may line up relative to that.
-+ * If this is a C++ scope declaration, do the same.
-+ */
-+ iscase = cin_iscase(l, FALSE);
-+ if (iscase || cin_isscopedecl(l))
-+ {
-+ /* we are only looking for cpp base class
-+ * declaration/initialization any longer */
-+ if (lookfor == LOOKFOR_CPP_BASECLASS)
-+ break;
-+
-+ /* When looking for a "do" we are not interested in
-+ * labels. */
-+ if (whilelevel > 0)
-+ continue;
-+
-+ /*
-+ * case xx:
-+ * c = 99 + <- this indent plus continuation
-+ *-> here;
-+ */
-+ if (lookfor == LOOKFOR_UNTERM
-+ || lookfor == LOOKFOR_ENUM_OR_INIT)
-+ {
-+ if (cont_amount > 0)
-+ amount = cont_amount;
-+ else
-+ amount += ind_continuation;
-+ break;
-+ }
-+
-+ /*
-+ * case xx: <- line up with this case
-+ * x = 333;
-+ * case yy:
-+ */
-+ if ( (iscase && lookfor == LOOKFOR_CASE)
-+ || (iscase && lookfor_break)
-+ || (!iscase && lookfor == LOOKFOR_SCOPEDECL))
-+ {
-+ /*
-+ * Check that this case label is not for another
-+ * switch()
-+ */ /* XXX */
-+ if ((trypos = find_start_brace()) == NULL
-+ || trypos->lnum == ourscope)
-+ {
-+ amount = get_indent(); /* XXX */
-+ break;
-+ }
-+ continue;
-+ }
-+
-+ n = get_indent_nolabel(curwin->w_cursor.lnum); /* XXX */
-+
-+ /*
-+ * case xx: if (cond) <- line up with this if
-+ * y = y + 1;
-+ * -> s = 99;
-+ *
-+ * case xx:
-+ * if (cond) <- line up with this line
-+ * y = y + 1;
-+ * -> s = 99;
-+ */
-+ if (lookfor == LOOKFOR_TERM)
-+ {
-+ if (n)
-+ amount = n;
-+
-+ if (!lookfor_break)
-+ break;
-+ }
-+
-+ /*
-+ * case xx: x = x + 1; <- line up with this x
-+ * -> y = y + 1;
-+ *
-+ * case xx: if (cond) <- line up with this if
-+ * -> y = y + 1;
-+ */
-+ if (n)
-+ {
-+ amount = n;
-+ l = after_label(ml_get_curline());
-+ if (l != NULL && cin_is_cinword(l))
-+ {
-+ if (theline[0] == '{')
-+ amount += curbuf->b_ind_open_extra;
-+ else
-+ amount += curbuf->b_ind_level
-+ + curbuf->b_ind_no_brace;
-+ }
-+ break;
-+ }
-+
-+ /*
-+ * Try to get the indent of a statement before the switch
-+ * label. If nothing is found, line up relative to the
-+ * switch label.
-+ * break; <- may line up with this line
-+ * case xx:
-+ * -> y = 1;
-+ */
-+ scope_amount = get_indent() + (iscase /* XXX */
-+ ? curbuf->b_ind_case_code
-+ : curbuf->b_ind_scopedecl_code);
-+ lookfor = curbuf->b_ind_case_break
-+ ? LOOKFOR_NOBREAK : LOOKFOR_ANY;
-+ continue;
-+ }
-+
-+ /*
-+ * Looking for a switch() label or C++ scope declaration,
-+ * ignore other lines, skip {}-blocks.
-+ */
-+ if (lookfor == LOOKFOR_CASE || lookfor == LOOKFOR_SCOPEDECL)
-+ {
-+ if (find_last_paren(l, '{', '}')
-+ && (trypos = find_start_brace()) != NULL)
-+ {
-+ curwin->w_cursor.lnum = trypos->lnum + 1;
-+ curwin->w_cursor.col = 0;
-+ }
-+ continue;
-+ }
-+
-+ /*
-+ * Ignore jump labels with nothing after them.
-+ */
-+ if (!curbuf->b_ind_js && cin_islabel())
-+ {
-+ l = after_label(ml_get_curline());
-+ if (l == NULL || cin_nocode(l))
-+ continue;
-+ }
-+
-+ /*
-+ * Ignore #defines, #if, etc.
-+ * Ignore comment and empty lines.
-+ * (need to get the line again, cin_islabel() may have
-+ * unlocked it)
-+ */
-+ l = ml_get_curline();
-+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)
-+ || cin_nocode(l))
-+ continue;
-+
-+ /*
-+ * Are we at the start of a cpp base class declaration or
-+ * constructor initialization?
-+ */ /* XXX */
-+ n = FALSE;
-+ if (lookfor != LOOKFOR_TERM && curbuf->b_ind_cpp_baseclass > 0)
-+ {
-+ n = cin_is_cpp_baseclass(&cache_cpp_baseclass);
-+ l = ml_get_curline();
-+ }
-+ if (n)
-+ {
-+ if (lookfor == LOOKFOR_UNTERM)
-+ {
-+ if (cont_amount > 0)
-+ amount = cont_amount;
-+ else
-+ amount += ind_continuation;
-+ }
-+ else if (theline[0] == '{')
-+ {
-+ /* Need to find start of the declaration. */
-+ lookfor = LOOKFOR_UNTERM;
-+ ind_continuation = 0;
-+ continue;
-+ }
-+ else
-+ /* XXX */
-+ amount = get_baseclass_amount(
-+ cache_cpp_baseclass.lpos.col);
-+ break;
-+ }
-+ else if (lookfor == LOOKFOR_CPP_BASECLASS)
-+ {
-+ /* only look, whether there is a cpp base class
-+ * declaration or initialization before the opening brace.
-+ */
-+ if (cin_isterminated(l, TRUE, FALSE))
-+ break;
-+ else
-+ continue;
-+ }
-+
-+ /*
-+ * What happens next depends on the line being terminated.
-+ * If terminated with a ',' only consider it terminating if
-+ * there is another unterminated statement behind, eg:
-+ * 123,
-+ * sizeof
-+ * here
-+ * Otherwise check whether it is a enumeration or structure
-+ * initialisation (not indented) or a variable declaration
-+ * (indented).
-+ */
-+ terminated = cin_isterminated(l, FALSE, TRUE);
-+
-+ if (js_cur_has_key)
-+ {
-+ js_cur_has_key = 0; /* only check the first line */
-+ if (curbuf->b_ind_js && terminated == ',')
-+ {
-+ /* For Javascript we might be inside an object:
-+ * key: something, <- align with this
-+ * key: something
-+ * or:
-+ * key: something + <- align with this
-+ * something,
-+ * key: something
-+ */
-+ lookfor = LOOKFOR_JS_KEY;
-+ }
-+ }
-+ if (lookfor == LOOKFOR_JS_KEY && cin_has_js_key(l))
-+ {
-+ amount = get_indent();
-+ break;
-+ }
-+ if (lookfor == LOOKFOR_COMMA)
-+ {
-+ if (tryposBrace != NULL && tryposBrace->lnum
-+ >= curwin->w_cursor.lnum)
-+ break;
-+ if (terminated == ',')
-+ /* line below current line is the one that starts a
-+ * (possibly broken) line ending in a comma. */
-+ break;
-+ else
-+ {
-+ amount = get_indent();
-+ if (curwin->w_cursor.lnum - 1 == ourscope)
-+ /* line above is start of the scope, thus current
-+ * line is the one that stars a (possibly broken)
-+ * line ending in a comma. */
-+ break;
-+ }
-+ }
-+
-+ if (terminated == 0 || (lookfor != LOOKFOR_UNTERM
-+ && terminated == ','))
-+ {
-+ if (lookfor != LOOKFOR_ENUM_OR_INIT &&
-+ (*skipwhite(l) == '[' || l[STRLEN(l) - 1] == '['))
-+ amount += ind_continuation;
-+ /*
-+ * if we're in the middle of a paren thing,
-+ * go back to the line that starts it so
-+ * we can get the right prevailing indent
-+ * if ( foo &&
-+ * bar )
-+ */
-+ /*
-+ * Position the cursor over the rightmost paren, so that
-+ * matching it will take us back to the start of the line.
-+ * Ignore a match before the start of the block.
-+ */
-+ (void)find_last_paren(l, '(', ')');
-+ trypos = find_match_paren(corr_ind_maxparen(&cur_curpos));
-+ if (trypos != NULL && (trypos->lnum < tryposBrace->lnum
-+ || (trypos->lnum == tryposBrace->lnum
-+ && trypos->col < tryposBrace->col)))
-+ trypos = NULL;
-+
-+ /*
-+ * If we are looking for ',', we also look for matching
-+ * braces.
-+ */
-+ if (trypos == NULL && terminated == ','
-+ && find_last_paren(l, '{', '}'))
-+ trypos = find_start_brace();
-+
-+ if (trypos != NULL)
-+ {
-+ /*
-+ * Check if we are on a case label now. This is
-+ * handled above.
-+ * case xx: if ( asdf &&
-+ * asdf)
-+ */
-+ curwin->w_cursor = *trypos;
-+ l = ml_get_curline();
-+ if (cin_iscase(l, FALSE) || cin_isscopedecl(l))
-+ {
-+ ++curwin->w_cursor.lnum;
-+ curwin->w_cursor.col = 0;
-+ continue;
-+ }
-+ }
-+
-+ /*
-+ * Skip over continuation lines to find the one to get the
-+ * indent from
-+ * char *usethis = "bla\
-+ * bla",
-+ * here;
-+ */
-+ if (terminated == ',')
-+ {
-+ while (curwin->w_cursor.lnum > 1)
-+ {
-+ l = ml_get(curwin->w_cursor.lnum - 1);
-+ if (*l == NUL || l[STRLEN(l) - 1] != '\\')
-+ break;
-+ --curwin->w_cursor.lnum;
-+ curwin->w_cursor.col = 0;
-+ }
-+ }
-+
-+ /*
-+ * Get indent and pointer to text for current line,
-+ * ignoring any jump label. XXX
-+ */
-+ if (curbuf->b_ind_js)
-+ cur_amount = get_indent();
-+ else
-+ cur_amount = skip_label(curwin->w_cursor.lnum, &l);
-+ /*
-+ * If this is just above the line we are indenting, and it
-+ * starts with a '{', line it up with this line.
-+ * while (not)
-+ * -> {
-+ * }
-+ */
-+ if (terminated != ',' && lookfor != LOOKFOR_TERM
-+ && theline[0] == '{')
-+ {
-+ amount = cur_amount;
-+ /*
-+ * Only add b_ind_open_extra when the current line
-+ * doesn't start with a '{', which must have a match
-+ * in the same line (scope is the same). Probably:
-+ * { 1, 2 },
-+ * -> { 3, 4 }
-+ */
-+ if (*skipwhite(l) != '{')
-+ amount += curbuf->b_ind_open_extra;
-+
-+ if (curbuf->b_ind_cpp_baseclass && !curbuf->b_ind_js)
-+ {
-+ /* have to look back, whether it is a cpp base
-+ * class declaration or initialization */
-+ lookfor = LOOKFOR_CPP_BASECLASS;
-+ continue;
-+ }
-+ break;
-+ }
-+
-+ /*
-+ * Check if we are after an "if", "while", etc.
-+ * Also allow " } else".
-+ */
-+ if (cin_is_cinword(l) || cin_iselse(skipwhite(l)))
-+ {
-+ /*
-+ * Found an unterminated line after an if (), line up
-+ * with the last one.
-+ * if (cond)
-+ * 100 +
-+ * -> here;
-+ */
-+ if (lookfor == LOOKFOR_UNTERM
-+ || lookfor == LOOKFOR_ENUM_OR_INIT)
-+ {
-+ if (cont_amount > 0)
-+ amount = cont_amount;
-+ else
-+ amount += ind_continuation;
-+ break;
-+ }
-+
-+ /*
-+ * If this is just above the line we are indenting, we
-+ * are finished.
-+ * while (not)
-+ * -> here;
-+ * Otherwise this indent can be used when the line
-+ * before this is terminated.
-+ * yyy;
-+ * if (stat)
-+ * while (not)
-+ * xxx;
-+ * -> here;
-+ */
-+ amount = cur_amount;
-+ if (theline[0] == '{')
-+ amount += curbuf->b_ind_open_extra;
-+ if (lookfor != LOOKFOR_TERM)
-+ {
-+ amount += curbuf->b_ind_level
-+ + curbuf->b_ind_no_brace;
-+ break;
-+ }
-+
-+ /*
-+ * Special trick: when expecting the while () after a
-+ * do, line up with the while()
-+ * do
-+ * x = 1;
-+ * -> here
-+ */
-+ l = skipwhite(ml_get_curline());
-+ if (cin_isdo(l))
-+ {
-+ if (whilelevel == 0)
-+ break;
-+ --whilelevel;
-+ }
-+
-+ /*
-+ * When searching for a terminated line, don't use the
-+ * one between the "if" and the matching "else".
-+ * Need to use the scope of this "else". XXX
-+ * If whilelevel != 0 continue looking for a "do {".
-+ */
-+ if (cin_iselse(l) && whilelevel == 0)
-+ {
-+ /* If we're looking at "} else", let's make sure we
-+ * find the opening brace of the enclosing scope,
-+ * not the one from "if () {". */
-+ if (*l == '}')
-+ curwin->w_cursor.col =
-+ (colnr_T)(l - ml_get_curline()) + 1;
-+
-+ if ((trypos = find_start_brace()) == NULL
-+ || find_match(LOOKFOR_IF, trypos->lnum)
-+ == FAIL)
-+ break;
-+ }
-+ }
-+
-+ /*
-+ * If we're below an unterminated line that is not an
-+ * "if" or something, we may line up with this line or
-+ * add something for a continuation line, depending on
-+ * the line before this one.
-+ */
-+ else
-+ {
-+ /*
-+ * Found two unterminated lines on a row, line up with
-+ * the last one.
-+ * c = 99 +
-+ * 100 +
-+ * -> here;
-+ */
-+ if (lookfor == LOOKFOR_UNTERM)
-+ {
-+ /* When line ends in a comma add extra indent */
-+ if (terminated == ',')
-+ amount += ind_continuation;
-+ break;
-+ }
-+
-+ if (lookfor == LOOKFOR_ENUM_OR_INIT)
-+ {
-+ /* Found two lines ending in ',', lineup with the
-+ * lowest one, but check for cpp base class
-+ * declaration/initialization, if it is an
-+ * opening brace or we are looking just for
-+ * enumerations/initializations. */
-+ if (terminated == ',')
-+ {
-+ if (curbuf->b_ind_cpp_baseclass == 0)
-+ break;
-+
-+ lookfor = LOOKFOR_CPP_BASECLASS;
-+ continue;
-+ }
-+
-+ /* Ignore unterminated lines in between, but
-+ * reduce indent. */
-+ if (amount > cur_amount)
-+ amount = cur_amount;
-+ }
-+ else
-+ {
-+ /*
-+ * Found first unterminated line on a row, may
-+ * line up with this line, remember its indent
-+ * 100 +
-+ * -> here;
-+ */
-+ l = ml_get_curline();
-+ amount = cur_amount;
-+
-+ n = (int)STRLEN(l);
-+ if (terminated == ',' && (*skipwhite(l) == ']'
-+ || (n >=2 && l[n - 2] == ']')))
-+ break;
-+
-+ /*
-+ * If previous line ends in ',', check whether we
-+ * are in an initialization or enum
-+ * struct xxx =
-+ * {
-+ * sizeof a,
-+ * 124 };
-+ * or a normal possible continuation line.
-+ * but only, of no other statement has been found
-+ * yet.
-+ */
-+ if (lookfor == LOOKFOR_INITIAL && terminated == ',')
-+ {
-+ if (curbuf->b_ind_js)
-+ {
-+ /* Search for a line ending in a comma
-+ * and line up with the line below it
-+ * (could be the current line).
-+ * some = [
-+ * 1, <- line up here
-+ * 2,
-+ * some = [
-+ * 3 + <- line up here
-+ * 4 *
-+ * 5,
-+ * 6,
-+ */
-+ if (cin_iscomment(skipwhite(l)))
-+ break;
-+ lookfor = LOOKFOR_COMMA;
-+ trypos = find_match_char('[',
-+ curbuf->b_ind_maxparen);
-+ if (trypos != NULL)
-+ {
-+ if (trypos->lnum
-+ == curwin->w_cursor.lnum - 1)
-+ {
-+ /* Current line is first inside
-+ * [], line up with it. */
-+ break;
-+ }
-+ ourscope = trypos->lnum;
-+ }
-+ }
-+ else
-+ {
-+ lookfor = LOOKFOR_ENUM_OR_INIT;
-+ cont_amount = cin_first_id_amount();
-+ }
-+ }
-+ else
-+ {
-+ if (lookfor == LOOKFOR_INITIAL
-+ && *l != NUL
-+ && l[STRLEN(l) - 1] == '\\')
-+ /* XXX */
-+ cont_amount = cin_get_equal_amount(
-+ curwin->w_cursor.lnum);
-+ if (lookfor != LOOKFOR_TERM
-+ && lookfor != LOOKFOR_JS_KEY
-+ && lookfor != LOOKFOR_COMMA
-+ && raw_string_start != curwin->w_cursor.lnum)
-+ lookfor = LOOKFOR_UNTERM;
-+ }
-+ }
-+ }
-+ }
-+
-+ /*
-+ * Check if we are after a while (cond);
-+ * If so: Ignore until the matching "do".
-+ */
-+ else if (cin_iswhileofdo_end(terminated)) /* XXX */
-+ {
-+ /*
-+ * Found an unterminated line after a while ();, line up
-+ * with the last one.
-+ * while (cond);
-+ * 100 + <- line up with this one
-+ * -> here;
-+ */
-+ if (lookfor == LOOKFOR_UNTERM
-+ || lookfor == LOOKFOR_ENUM_OR_INIT)
-+ {
-+ if (cont_amount > 0)
-+ amount = cont_amount;
-+ else
-+ amount += ind_continuation;
-+ break;
-+ }
-+
-+ if (whilelevel == 0)
-+ {
-+ lookfor = LOOKFOR_TERM;
-+ amount = get_indent(); /* XXX */
-+ if (theline[0] == '{')
-+ amount += curbuf->b_ind_open_extra;
-+ }
-+ ++whilelevel;
-+ }
-+
-+ /*
-+ * We are after a "normal" statement.
-+ * If we had another statement we can stop now and use the
-+ * indent of that other statement.
-+ * Otherwise the indent of the current statement may be used,
-+ * search backwards for the next "normal" statement.
-+ */
-+ else
-+ {
-+ /*
-+ * Skip single break line, if before a switch label. It
-+ * may be lined up with the case label.
-+ */
-+ if (lookfor == LOOKFOR_NOBREAK
-+ && cin_isbreak(skipwhite(ml_get_curline())))
-+ {
-+ lookfor = LOOKFOR_ANY;
-+ continue;
-+ }
-+
-+ /*
-+ * Handle "do {" line.
-+ */
-+ if (whilelevel > 0)
-+ {
-+ l = cin_skipcomment(ml_get_curline());
-+ if (cin_isdo(l))
-+ {
-+ amount = get_indent(); /* XXX */
-+ --whilelevel;
-+ continue;
-+ }
-+ }
-+
-+ /*
-+ * Found a terminated line above an unterminated line. Add
-+ * the amount for a continuation line.
-+ * x = 1;
-+ * y = foo +
-+ * -> here;
-+ * or
-+ * int x = 1;
-+ * int foo,
-+ * -> here;
-+ */
-+ if (lookfor == LOOKFOR_UNTERM
-+ || lookfor == LOOKFOR_ENUM_OR_INIT)
-+ {
-+ if (cont_amount > 0)
-+ amount = cont_amount;
-+ else
-+ amount += ind_continuation;
-+ break;
-+ }
-+
-+ /*
-+ * Found a terminated line above a terminated line or "if"
-+ * etc. line. Use the amount of the line below us.
-+ * x = 1; x = 1;
-+ * if (asdf) y = 2;
-+ * while (asdf) ->here;
-+ * here;
-+ * ->foo;
-+ */
-+ if (lookfor == LOOKFOR_TERM)
-+ {
-+ if (!lookfor_break && whilelevel == 0)
-+ break;
-+ }
-+
-+ /*
-+ * First line above the one we're indenting is terminated.
-+ * To know what needs to be done look further backward for
-+ * a terminated line.
-+ */
-+ else
-+ {
-+ /*
-+ * position the cursor over the rightmost paren, so
-+ * that matching it will take us back to the start of
-+ * the line. Helps for:
-+ * func(asdr,
-+ * asdfasdf);
-+ * here;
-+ */
-+ term_again:
-+ l = ml_get_curline();
-+ if (find_last_paren(l, '(', ')')
-+ && (trypos = find_match_paren(
-+ curbuf->b_ind_maxparen)) != NULL)
-+ {
-+ /*
-+ * Check if we are on a case label now. This is
-+ * handled above.
-+ * case xx: if ( asdf &&
-+ * asdf)
-+ */
-+ curwin->w_cursor = *trypos;
-+ l = ml_get_curline();
-+ if (cin_iscase(l, FALSE) || cin_isscopedecl(l))
-+ {
-+ ++curwin->w_cursor.lnum;
-+ curwin->w_cursor.col = 0;
-+ continue;
-+ }
-+ }
-+
-+ /* When aligning with the case statement, don't align
-+ * with a statement after it.
-+ * case 1: { <-- don't use this { position
-+ * stat;
-+ * }
-+ * case 2:
-+ * stat;
-+ * }
-+ */
-+ iscase = (curbuf->b_ind_keep_case_label
-+ && cin_iscase(l, FALSE));
-+
-+ /*
-+ * Get indent and pointer to text for current line,
-+ * ignoring any jump label.
-+ */
-+ amount = skip_label(curwin->w_cursor.lnum, &l);
-+
-+ if (theline[0] == '{')
-+ amount += curbuf->b_ind_open_extra;
-+ /* See remark above: "Only add b_ind_open_extra.." */
-+ l = skipwhite(l);
-+ if (*l == '{')
-+ amount -= curbuf->b_ind_open_extra;
-+ lookfor = iscase ? LOOKFOR_ANY : LOOKFOR_TERM;
-+
-+ /*
-+ * When a terminated line starts with "else" skip to
-+ * the matching "if":
-+ * else 3;
-+ * indent this;
-+ * Need to use the scope of this "else". XXX
-+ * If whilelevel != 0 continue looking for a "do {".
-+ */
-+ if (lookfor == LOOKFOR_TERM
-+ && *l != '}'
-+ && cin_iselse(l)
-+ && whilelevel == 0)
-+ {
-+ if ((trypos = find_start_brace()) == NULL
-+ || find_match(LOOKFOR_IF, trypos->lnum)
-+ == FAIL)
-+ break;
-+ continue;
-+ }
-+
-+ /*
-+ * If we're at the end of a block, skip to the start of
-+ * that block.
-+ */
-+ l = ml_get_curline();
-+ if (find_last_paren(l, '{', '}') /* XXX */
-+ && (trypos = find_start_brace()) != NULL)
-+ {
-+ curwin->w_cursor = *trypos;
-+ /* if not "else {" check for terminated again */
-+ /* but skip block for "} else {" */
-+ l = cin_skipcomment(ml_get_curline());
-+ if (*l == '}' || !cin_iselse(l))
-+ goto term_again;
-+ ++curwin->w_cursor.lnum;
-+ curwin->w_cursor.col = 0;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ /* add extra indent for a comment */
-+ if (cin_iscomment(theline))
-+ amount += curbuf->b_ind_comment;
-+
-+ /* subtract extra left-shift for jump labels */
-+ if (curbuf->b_ind_jump_label > 0 && original_line_islabel)
-+ amount -= curbuf->b_ind_jump_label;
-+
-+ goto theend;
-+ }
-+
-+ /*
-+ * ok -- we're not inside any sort of structure at all!
-+ *
-+ * This means we're at the top level, and everything should
-+ * basically just match where the previous line is, except
-+ * for the lines immediately following a function declaration,
-+ * which are K&R-style parameters and need to be indented.
-+ *
-+ * if our line starts with an open brace, forget about any
-+ * prevailing indent and make sure it looks like the start
-+ * of a function
-+ */
-+
-+ if (theline[0] == '{')
-+ {
-+ amount = curbuf->b_ind_first_open;
-+ goto theend;
-+ }
-+
-+ /*
-+ * If the NEXT line is a function declaration, the current
-+ * line needs to be indented as a function type spec.
-+ * Don't do this if the current line looks like a comment or if the
-+ * current line is terminated, ie. ends in ';', or if the current line
-+ * contains { or }: "void f() {\n if (1)"
-+ */
-+ if (cur_curpos.lnum < curbuf->b_ml.ml_line_count
-+ && !cin_nocode(theline)
-+ && vim_strchr(theline, '{') == NULL
-+ && vim_strchr(theline, '}') == NULL
-+ && !cin_ends_in(theline, (char_u *)":", NULL)
-+ && !cin_ends_in(theline, (char_u *)",", NULL)
-+ && cin_isfuncdecl(NULL, cur_curpos.lnum + 1,
-+ cur_curpos.lnum + 1)
-+ && !cin_isterminated(theline, FALSE, TRUE))
-+ {
-+ amount = curbuf->b_ind_func_type;
-+ goto theend;
-+ }
-+
-+ /* search backwards until we find something we recognize */
-+ amount = 0;
-+ curwin->w_cursor = cur_curpos;
-+ while (curwin->w_cursor.lnum > 1)
-+ {
-+ curwin->w_cursor.lnum--;
-+ curwin->w_cursor.col = 0;
-+
-+ l = ml_get_curline();
-+
-+ /*
-+ * If we're in a comment or raw string now, skip to the start
-+ * of it.
-+ */ /* XXX */
-+ if ((trypos = ind_find_start_CORS(NULL)) != NULL)
-+ {
-+ curwin->w_cursor.lnum = trypos->lnum + 1;
-+ curwin->w_cursor.col = 0;
-+ continue;
-+ }
-+
-+ /*
-+ * Are we at the start of a cpp base class declaration or
-+ * constructor initialization?
-+ */ /* XXX */
-+ n = FALSE;
-+ if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{')
-+ {
-+ n = cin_is_cpp_baseclass(&cache_cpp_baseclass);
-+ l = ml_get_curline();
-+ }
-+ if (n)
-+ {
-+ /* XXX */
-+ amount = get_baseclass_amount(cache_cpp_baseclass.lpos.col);
-+ break;
-+ }
-+
-+ /*
-+ * Skip preprocessor directives and blank lines.
-+ */
-+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount))
-+ continue;
-+
-+ if (cin_nocode(l))
-+ continue;
-+
-+ /*
-+ * If the previous line ends in ',', use one level of
-+ * indentation:
-+ * int foo,
-+ * bar;
-+ * do this before checking for '}' in case of eg.
-+ * enum foobar
-+ * {
-+ * ...
-+ * } foo,
-+ * bar;
-+ */
-+ n = 0;
-+ if (cin_ends_in(l, (char_u *)",", NULL)
-+ || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\'))
-+ {
-+ /* take us back to opening paren */
-+ if (find_last_paren(l, '(', ')')
-+ && (trypos = find_match_paren(
-+ curbuf->b_ind_maxparen)) != NULL)
-+ curwin->w_cursor = *trypos;
-+
-+ /* For a line ending in ',' that is a continuation line go
-+ * back to the first line with a backslash:
-+ * char *foo = "bla\
-+ * bla",
-+ * here;
-+ */
-+ while (n == 0 && curwin->w_cursor.lnum > 1)
-+ {
-+ l = ml_get(curwin->w_cursor.lnum - 1);
-+ if (*l == NUL || l[STRLEN(l) - 1] != '\\')
-+ break;
-+ --curwin->w_cursor.lnum;
-+ curwin->w_cursor.col = 0;
-+ }
-+
-+ amount = get_indent(); /* XXX */
-+
-+ if (amount == 0)
-+ amount = cin_first_id_amount();
-+ if (amount == 0)
-+ amount = ind_continuation;
-+ break;
-+ }
-+
-+ /*
-+ * If the line looks like a function declaration, and we're
-+ * not in a comment, put it the left margin.
-+ */
-+ if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0)) /* XXX */
-+ break;
-+ l = ml_get_curline();
-+
-+ /*
-+ * Finding the closing '}' of a previous function. Put
-+ * current line at the left margin. For when 'cino' has "fs".
-+ */
-+ if (*skipwhite(l) == '}')
-+ break;
-+
-+ /* (matching {)
-+ * If the previous line ends on '};' (maybe followed by
-+ * comments) align at column 0. For example:
-+ * char *string_array[] = { "foo",
-+ * / * x * / "b};ar" }; / * foobar * /
-+ */
-+ if (cin_ends_in(l, (char_u *)"};", NULL))
-+ break;
-+
-+ /*
-+ * If the previous line ends on '[' we are probably in an
-+ * array constant:
-+ * something = [
-+ * 234, <- extra indent
-+ */
-+ if (cin_ends_in(l, (char_u *)"[", NULL))
-+ {
-+ amount = get_indent() + ind_continuation;
-+ break;
-+ }
-+
-+ /*
-+ * Find a line only has a semicolon that belongs to a previous
-+ * line ending in '}', e.g. before an #endif. Don't increase
-+ * indent then.
-+ */
-+ if (*(look = skipwhite(l)) == ';' && cin_nocode(look + 1))
-+ {
-+ pos_T curpos_save = curwin->w_cursor;
-+
-+ while (curwin->w_cursor.lnum > 1)
-+ {
-+ look = ml_get(--curwin->w_cursor.lnum);
-+ if (!(cin_nocode(look) || cin_ispreproc_cont(
-+ &look, &curwin->w_cursor.lnum, &amount)))
-+ break;
-+ }
-+ if (curwin->w_cursor.lnum > 0
-+ && cin_ends_in(look, (char_u *)"}", NULL))
-+ break;
-+
-+ curwin->w_cursor = curpos_save;
-+ }
-+
-+ /*
-+ * If the PREVIOUS line is a function declaration, the current
-+ * line (and the ones that follow) needs to be indented as
-+ * parameters.
-+ */
-+ if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0))
-+ {
-+ amount = curbuf->b_ind_param;
-+ break;
-+ }
-+
-+ /*
-+ * If the previous line ends in ';' and the line before the
-+ * previous line ends in ',' or '\', ident to column zero:
-+ * int foo,
-+ * bar;
-+ * indent_to_0 here;
-+ */
-+ if (cin_ends_in(l, (char_u *)";", NULL))
-+ {
-+ l = ml_get(curwin->w_cursor.lnum - 1);
-+ if (cin_ends_in(l, (char_u *)",", NULL)
-+ || (*l != NUL && l[STRLEN(l) - 1] == '\\'))
-+ break;
-+ l = ml_get_curline();
-+ }
-+
-+ /*
-+ * Doesn't look like anything interesting -- so just
-+ * use the indent of this line.
-+ *
-+ * Position the cursor over the rightmost paren, so that
-+ * matching it will take us back to the start of the line.
-+ */
-+ find_last_paren(l, '(', ')');
-+
-+ if ((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
-+ curwin->w_cursor = *trypos;
-+ amount = get_indent(); /* XXX */
-+ break;
-+ }
-+
-+ /* add extra indent for a comment */
-+ if (cin_iscomment(theline))
-+ amount += curbuf->b_ind_comment;
-+
-+ /* add extra indent if the previous line ended in a backslash:
-+ * "asdfasdf\
-+ * here";
-+ * char *foo = "asdf\
-+ * here";
-+ */
-+ if (cur_curpos.lnum > 1)
-+ {
-+ l = ml_get(cur_curpos.lnum - 1);
-+ if (*l != NUL && l[STRLEN(l) - 1] == '\\')
-+ {
-+ cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1);
-+ if (cur_amount > 0)
-+ amount = cur_amount;
-+ else if (cur_amount == 0)
-+ amount += ind_continuation;
-+ }
-+ }
-+
-+ theend:
-+ if (amount < 0)
-+ amount = 0;
-+
-+ laterend:
-+ /* put the cursor back where it belongs */
-+ curwin->w_cursor = cur_curpos;
-+
-+ vim_free(linecopy);
-+
-+ return amount;
-+ }
-+
-+ static int
-+ find_match(int lookfor, linenr_T ourscope)
-+ {
-+ char_u *look;
-+ pos_T *theirscope;
-+ char_u *mightbeif;
-+ int elselevel;
-+ int whilelevel;
-+
-+ if (lookfor == LOOKFOR_IF)
-+ {
-+ elselevel = 1;
-+ whilelevel = 0;
-+ }
-+ else
-+ {
-+ elselevel = 0;
-+ whilelevel = 1;
-+ }
-+
-+ curwin->w_cursor.col = 0;
-+
-+ while (curwin->w_cursor.lnum > ourscope + 1)
-+ {
-+ curwin->w_cursor.lnum--;
-+ curwin->w_cursor.col = 0;
-+
-+ look = cin_skipcomment(ml_get_curline());
-+ if (cin_iselse(look)
-+ || cin_isif(look)
-+ || cin_isdo(look) /* XXX */
-+ || cin_iswhileofdo(look, curwin->w_cursor.lnum))
-+ {
-+ /*
-+ * if we've gone outside the braces entirely,
-+ * we must be out of scope...
-+ */
-+ theirscope = find_start_brace(); /* XXX */
-+ if (theirscope == NULL)
-+ break;
-+
-+ /*
-+ * and if the brace enclosing this is further
-+ * back than the one enclosing the else, we're
-+ * out of luck too.
-+ */
-+ if (theirscope->lnum < ourscope)
-+ break;
-+
-+ /*
-+ * and if they're enclosed in a *deeper* brace,
-+ * then we can ignore it because it's in a
-+ * different scope...
-+ */
-+ if (theirscope->lnum > ourscope)
-+ continue;
-+
-+ /*
-+ * if it was an "else" (that's not an "else if")
-+ * then we need to go back to another if, so
-+ * increment elselevel
-+ */
-+ look = cin_skipcomment(ml_get_curline());
-+ if (cin_iselse(look))
-+ {
-+ mightbeif = cin_skipcomment(look + 4);
-+ if (!cin_isif(mightbeif))
-+ ++elselevel;
-+ continue;
-+ }
-+
-+ /*
-+ * if it was a "while" then we need to go back to
-+ * another "do", so increment whilelevel. XXX
-+ */
-+ if (cin_iswhileofdo(look, curwin->w_cursor.lnum))
-+ {
-+ ++whilelevel;
-+ continue;
-+ }
-+
-+ /* If it's an "if" decrement elselevel */
-+ look = cin_skipcomment(ml_get_curline());
-+ if (cin_isif(look))
-+ {
-+ elselevel--;
-+ /*
-+ * When looking for an "if" ignore "while"s that
-+ * get in the way.
-+ */
-+ if (elselevel == 0 && lookfor == LOOKFOR_IF)
-+ whilelevel = 0;
-+ }
-+
-+ /* If it's a "do" decrement whilelevel */
-+ if (cin_isdo(look))
-+ whilelevel--;
-+
-+ /*
-+ * if we've used up all the elses, then
-+ * this must be the if that we want!
-+ * match the indent level of that if.
-+ */
-+ if (elselevel <= 0 && whilelevel <= 0)
-+ {
-+ return OK;
-+ }
-+ }
-+ }
-+ return FAIL;
-+ }
-+
-+ # if defined(FEAT_EVAL) || defined(PROTO)
-+ /*
-+ * Get indent level from 'indentexpr'.
-+ */
-+ int
-+ get_expr_indent(void)
-+ {
-+ int indent = -1;
-+ char_u *inde_copy;
-+ pos_T save_pos;
-+ colnr_T save_curswant;
-+ int save_set_curswant;
-+ int save_State;
-+ int use_sandbox = was_set_insecurely((char_u *)"indentexpr",
-+ OPT_LOCAL);
-+
-+ /* Save and restore cursor position and curswant, in case it was changed
-+ * via :normal commands */
-+ save_pos = curwin->w_cursor;
-+ save_curswant = curwin->w_curswant;
-+ save_set_curswant = curwin->w_set_curswant;
-+ set_vim_var_nr(VV_LNUM, curwin->w_cursor.lnum);
-+ if (use_sandbox)
-+ ++sandbox;
-+ ++textlock;
-+
-+ /* Need to make a copy, the 'indentexpr' option could be changed while
-+ * evaluating it. */
-+ inde_copy = vim_strsave(curbuf->b_p_inde);
-+ if (inde_copy != NULL)
-+ {
-+ indent = (int)eval_to_number(inde_copy);
-+ vim_free(inde_copy);
-+ }
-+
-+ if (use_sandbox)
-+ --sandbox;
-+ --textlock;
-+
-+ /* Restore the cursor position so that 'indentexpr' doesn't need to.
-+ * Pretend to be in Insert mode, allow cursor past end of line for "o"
-+ * command. */
-+ save_State = State;
-+ State = INSERT;
-+ curwin->w_cursor = save_pos;
-+ curwin->w_curswant = save_curswant;
-+ curwin->w_set_curswant = save_set_curswant;
-+ check_cursor();
-+ State = save_State;
-+
-+ /* If there is an error, just keep the current indent. */
-+ if (indent < 0)
-+ indent = get_indent();
-+
-+ return indent;
-+ }
-+ # endif
-+
-+ /*
-+ * return TRUE if 'cinkeys' contains the key "keytyped",
-+ * when == '*': Only if key is preceded with '*' (indent before insert)
-+ * when == '!': Only if key is preceded with '!' (don't insert)
-+ * when == ' ': Only if key is not preceded with '*'(indent afterwards)
-+ *
-+ * "keytyped" can have a few special values:
-+ * KEY_OPEN_FORW
-+ * KEY_OPEN_BACK
-+ * KEY_COMPLETE just finished completion.
-+ *
-+ * If line_is_empty is TRUE accept keys with '0' before them.
-+ */
-+ int
-+ in_cinkeys(
-+ int keytyped,
-+ int when,
-+ int line_is_empty)
-+ {
-+ char_u *look;
-+ int try_match;
-+ int try_match_word;
-+ char_u *p;
-+ char_u *line;
-+ int icase;
-+ int i;
-+
-+ if (keytyped == NUL)
-+ /* Can happen with CTRL-Y and CTRL-E on a short line. */
-+ return FALSE;
-+
-+ #ifdef FEAT_EVAL
-+ if (*curbuf->b_p_inde != NUL)
-+ look = curbuf->b_p_indk; /* 'indentexpr' set: use 'indentkeys' */
-+ else
-+ #endif
-+ look = curbuf->b_p_cink; /* 'indentexpr' empty: use 'cinkeys' */
-+ while (*look)
-+ {
-+ /*
-+ * Find out if we want to try a match with this key, depending on
-+ * 'when' and a '*' or '!' before the key.
-+ */
-+ switch (when)
-+ {
-+ case '*': try_match = (*look == '*'); break;
-+ case '!': try_match = (*look == '!'); break;
-+ default: try_match = (*look != '*'); break;
-+ }
-+ if (*look == '*' || *look == '!')
-+ ++look;
-+
-+ /*
-+ * If there is a '0', only accept a match if the line is empty.
-+ * But may still match when typing last char of a word.
-+ */
-+ if (*look == '0')
-+ {
-+ try_match_word = try_match;
-+ if (!line_is_empty)
-+ try_match = FALSE;
-+ ++look;
-+ }
-+ else
-+ try_match_word = FALSE;
-+
-+ /*
-+ * does it look like a control character?
-+ */
-+ if (*look == '^'
-+ #ifdef EBCDIC
-+ && (Ctrl_chr(look[1]) != 0)
-+ #else
-+ && look[1] >= '?' && look[1] <= '_'
-+ #endif
-+ )
-+ {
-+ if (try_match && keytyped == Ctrl_chr(look[1]))
-+ return TRUE;
-+ look += 2;
-+ }
-+ /*
-+ * 'o' means "o" command, open forward.
-+ * 'O' means "O" command, open backward.
-+ */
-+ else if (*look == 'o')
-+ {
-+ if (try_match && keytyped == KEY_OPEN_FORW)
-+ return TRUE;
-+ ++look;
-+ }
-+ else if (*look == 'O')
-+ {
-+ if (try_match && keytyped == KEY_OPEN_BACK)
-+ return TRUE;
-+ ++look;
-+ }
-+
-+ /*
-+ * 'e' means to check for "else" at start of line and just before the
-+ * cursor.
-+ */
-+ else if (*look == 'e')
-+ {
-+ if (try_match && keytyped == 'e' && curwin->w_cursor.col >= 4)
-+ {
-+ p = ml_get_curline();
-+ if (skipwhite(p) == p + curwin->w_cursor.col - 4 &&
-+ STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0)
-+ return TRUE;
-+ }
-+ ++look;
-+ }
-+
-+ /*
-+ * ':' only causes an indent if it is at the end of a label or case
-+ * statement, or when it was before typing the ':' (to fix
-+ * class::method for C++).
-+ */
-+ else if (*look == ':')
-+ {
-+ if (try_match && keytyped == ':')
-+ {
-+ p = ml_get_curline();
-+ if (cin_iscase(p, FALSE) || cin_isscopedecl(p) || cin_islabel())
-+ return TRUE;
-+ /* Need to get the line again after cin_islabel(). */
-+ p = ml_get_curline();
-+ if (curwin->w_cursor.col > 2
-+ && p[curwin->w_cursor.col - 1] == ':'
-+ && p[curwin->w_cursor.col - 2] == ':')
-+ {
-+ p[curwin->w_cursor.col - 1] = ' ';
-+ i = (cin_iscase(p, FALSE) || cin_isscopedecl(p)
-+ || cin_islabel());
-+ p = ml_get_curline();
-+ p[curwin->w_cursor.col - 1] = ':';
-+ if (i)
-+ return TRUE;
-+ }
-+ }
-+ ++look;
-+ }
-+
-+
-+ /*
-+ * Is it a key in <>, maybe?
-+ */
-+ else if (*look == '<')
-+ {
-+ if (try_match)
-+ {
-+ /*
-+ * make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>,
-+ * <:> and <!> so that people can re-indent on o, O, e, 0, <,
-+ * >, *, : and ! keys if they really really want to.
-+ */
-+ if (vim_strchr((char_u *)"<>!*oOe0:", look[1]) != NULL
-+ && keytyped == look[1])
-+ return TRUE;
-+
-+ if (keytyped == get_special_key_code(look + 1))
-+ return TRUE;
-+ }
-+ while (*look && *look != '>')
-+ look++;
-+ while (*look == '>')
-+ look++;
-+ }
-+
-+ /*
-+ * Is it a word: "=word"?
-+ */
-+ else if (*look == '=' && look[1] != ',' && look[1] != NUL)
-+ {
-+ ++look;
-+ if (*look == '~')
-+ {
-+ icase = TRUE;
-+ ++look;
-+ }
-+ else
-+ icase = FALSE;
-+ p = vim_strchr(look, ',');
-+ if (p == NULL)
-+ p = look + STRLEN(look);
-+ if ((try_match || try_match_word)
-+ && curwin->w_cursor.col >= (colnr_T)(p - look))
-+ {
-+ int match = FALSE;
-+
-+ #ifdef FEAT_INS_EXPAND
-+ if (keytyped == KEY_COMPLETE)
-+ {
-+ char_u *s;
-+
-+ /* Just completed a word, check if it starts with "look".
-+ * search back for the start of a word. */
-+ line = ml_get_curline();
-+ if (has_mbyte)
-+ {
-+ char_u *n;
-+
-+ for (s = line + curwin->w_cursor.col; s > line; s = n)
-+ {
-+ n = mb_prevptr(line, s);
-+ if (!vim_iswordp(n))
-+ break;
-+ }
-+ }
-+ else
-+ for (s = line + curwin->w_cursor.col; s > line; --s)
-+ if (!vim_iswordc(s[-1]))
-+ break;
-+ if (s + (p - look) <= line + curwin->w_cursor.col
-+ && (icase
-+ ? MB_STRNICMP(s, look, p - look)
-+ : STRNCMP(s, look, p - look)) == 0)
-+ match = TRUE;
-+ }
-+ else
-+ #endif
-+ /* TODO: multi-byte */
-+ if (keytyped == (int)p[-1] || (icase && keytyped < 256
-+ && TOLOWER_LOC(keytyped) == TOLOWER_LOC((int)p[-1])))
-+ {
-+ line = ml_get_cursor();
-+ if ((curwin->w_cursor.col == (colnr_T)(p - look)
-+ || !vim_iswordc(line[-(p - look) - 1]))
-+ && (icase
-+ ? MB_STRNICMP(line - (p - look), look, p - look)
-+ : STRNCMP(line - (p - look), look, p - look))
-+ == 0)
-+ match = TRUE;
-+ }
-+ if (match && try_match_word && !try_match)
-+ {
-+ /* "0=word": Check if there are only blanks before the
-+ * word. */
-+ if (getwhitecols_curline() !=
-+ (int)(curwin->w_cursor.col - (p - look)))
-+ match = FALSE;
-+ }
-+ if (match)
-+ return TRUE;
-+ }
-+ look = p;
-+ }
-+
-+ /*
-+ * ok, it's a boring generic character.
-+ */
-+ else
-+ {
-+ if (try_match && *look == keytyped)
-+ return TRUE;
-+ if (*look != NUL)
-+ ++look;
-+ }
-+
-+ /*
-+ * Skip over ", ".
-+ */
-+ look = skip_to_option_part(look);
-+ }
-+ return FALSE;
-+ }
-+ #endif /* FEAT_CINDENT */
-+
-+ #if defined(FEAT_LISP) || defined(PROTO)
-+
-+ static int
-+ lisp_match(char_u *p)
-+ {
-+ char_u buf[LSIZE];
-+ int len;
-+ char_u *word = *curbuf->b_p_lw != NUL ? curbuf->b_p_lw : p_lispwords;
-+
-+ while (*word != NUL)
-+ {
-+ (void)copy_option_part(&word, buf, LSIZE, ",");
-+ len = (int)STRLEN(buf);
-+ if (STRNCMP(buf, p, len) == 0 && p[len] == ' ')
-+ return TRUE;
-+ }
-+ return FALSE;
-+ }
-+
-+ /*
-+ * When 'p' is present in 'cpoptions, a Vi compatible method is used.
-+ * The incompatible newer method is quite a bit better at indenting
-+ * code in lisp-like languages than the traditional one; it's still
-+ * mostly heuristics however -- Dirk van Deun, dirk@rave.org
-+ *
-+ * TODO:
-+ * Findmatch() should be adapted for lisp, also to make showmatch
-+ * work correctly: now (v5.3) it seems all C/C++ oriented:
-+ * - it does not recognize the #\( and #\) notations as character literals
-+ * - it doesn't know about comments starting with a semicolon
-+ * - it incorrectly interprets '(' as a character literal
-+ * All this messes up get_lisp_indent in some rare cases.
-+ * Update from Sergey Khorev:
-+ * I tried to fix the first two issues.
-+ */
-+ int
-+ get_lisp_indent(void)
-+ {
-+ pos_T *pos, realpos, paren;
-+ int amount;
-+ char_u *that;
-+ colnr_T col;
-+ colnr_T firsttry;
-+ int parencount, quotecount;
-+ int vi_lisp;
-+
-+ /* Set vi_lisp to use the vi-compatible method */
-+ vi_lisp = (vim_strchr(p_cpo, CPO_LISP) != NULL);
-+
-+ realpos = curwin->w_cursor;
-+ curwin->w_cursor.col = 0;
-+
-+ if ((pos = findmatch(NULL, '(')) == NULL)
-+ pos = findmatch(NULL, '[');
-+ else
-+ {
-+ paren = *pos;
-+ pos = findmatch(NULL, '[');
-+ if (pos == NULL || LT_POSP(pos, &paren))
-+ pos = &paren;
-+ }
-+ if (pos != NULL)
-+ {
-+ /* Extra trick: Take the indent of the first previous non-white
-+ * line that is at the same () level. */
-+ amount = -1;
-+ parencount = 0;
-+
-+ while (--curwin->w_cursor.lnum >= pos->lnum)
-+ {
-+ if (linewhite(curwin->w_cursor.lnum))
-+ continue;
-+ for (that = ml_get_curline(); *that != NUL; ++that)
-+ {
-+ if (*that == ';')
-+ {
-+ while (*(that + 1) != NUL)
-+ ++that;
-+ continue;
-+ }
-+ if (*that == '\\')
-+ {
-+ if (*(that + 1) != NUL)
-+ ++that;
-+ continue;
-+ }
-+ if (*that == '"' && *(that + 1) != NUL)
-+ {
-+ while (*++that && *that != '"')
-+ {
-+ /* skipping escaped characters in the string */
-+ if (*that == '\\')
-+ {
-+ if (*++that == NUL)
-+ break;
-+ if (that[1] == NUL)
-+ {
-+ ++that;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ if (*that == '(' || *that == '[')
-+ ++parencount;
-+ else if (*that == ')' || *that == ']')
-+ --parencount;
-+ }
-+ if (parencount == 0)
-+ {
-+ amount = get_indent();
-+ break;
-+ }
-+ }
-+
-+ if (amount == -1)
-+ {
-+ curwin->w_cursor.lnum = pos->lnum;
-+ curwin->w_cursor.col = pos->col;
-+ col = pos->col;
-+
-+ that = ml_get_curline();
-+
-+ if (vi_lisp && get_indent() == 0)
-+ amount = 2;
-+ else
-+ {
-+ char_u *line = that;
-+
-+ amount = 0;
-+ while (*that && col)
-+ {
-+ amount += lbr_chartabsize_adv(line, &that, (colnr_T)amount);
-+ col--;
-+ }
-+
-+ /*
-+ * Some keywords require "body" indenting rules (the
-+ * non-standard-lisp ones are Scheme special forms):
-+ *
-+ * (let ((a 1)) instead (let ((a 1))
-+ * (...)) of (...))
-+ */
-+
-+ if (!vi_lisp && (*that == '(' || *that == '[')
-+ && lisp_match(that + 1))
-+ amount += 2;
-+ else
-+ {
-+ that++;
-+ amount++;
-+ firsttry = amount;
-+
-+ while (VIM_ISWHITE(*that))
-+ {
-+ amount += lbr_chartabsize(line, that, (colnr_T)amount);
-+ ++that;
-+ }
-+
-+ if (*that && *that != ';') /* not a comment line */
-+ {
-+ /* test *that != '(' to accommodate first let/do
-+ * argument if it is more than one line */
-+ if (!vi_lisp && *that != '(' && *that != '[')
-+ firsttry++;
-+
-+ parencount = 0;
-+ quotecount = 0;
-+
-+ if (vi_lisp
-+ || (*that != '"'
-+ && *that != '\''
-+ && *that != '#'
-+ && (*that < '0' || *that > '9')))
-+ {
-+ while (*that
-+ && (!VIM_ISWHITE(*that)
-+ || quotecount
-+ || parencount)
-+ && (!((*that == '(' || *that == '[')
-+ && !quotecount
-+ && !parencount
-+ && vi_lisp)))
-+ {
-+ if (*that == '"')
-+ quotecount = !quotecount;
-+ if ((*that == '(' || *that == '[')
-+ && !quotecount)
-+ ++parencount;
-+ if ((*that == ')' || *that == ']')
-+ && !quotecount)
-+ --parencount;
-+ if (*that == '\\' && *(that+1) != NUL)
-+ amount += lbr_chartabsize_adv(
-+ line, &that, (colnr_T)amount);
-+ amount += lbr_chartabsize_adv(
-+ line, &that, (colnr_T)amount);
-+ }
-+ }
-+ while (VIM_ISWHITE(*that))
-+ {
-+ amount += lbr_chartabsize(
-+ line, that, (colnr_T)amount);
-+ that++;
-+ }
-+ if (!*that || *that == ';')
-+ amount = firsttry;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ else
-+ amount = 0; /* no matching '(' or '[' found, use zero indent */
-+
-+ curwin->w_cursor = realpos;
-+
-+ return amount;
-+ }
-+ #endif /* FEAT_LISP */
-+
-+ #if defined(FEAT_CINDENT) || defined(PROTO)
-+ /*
-+ * Do C or expression indenting on the current line.
-+ */
-+ void
-+ do_c_expr_indent(void)
-+ {
-+ # ifdef FEAT_EVAL
-+ if (*curbuf->b_p_inde != NUL)
-+ fixthisline(get_expr_indent);
-+ else
-+ # endif
-+ fixthisline(get_c_indent);
-+ }
-+ #endif
-+
-+ #if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(PROTO)
-+ /*
-+ * Re-indent the current line, based on the current contents of it and the
-+ * surrounding lines. Fixing the cursor position seems really easy -- I'm very
-+ * confused what all the part that handles Control-T is doing that I'm not.
-+ * "get_the_indent" should be get_c_indent, get_expr_indent or get_lisp_indent.
-+ */
-+
-+ void
-+ fixthisline(int (*get_the_indent)(void))
-+ {
-+ int amount = get_the_indent();
-+
-+ if (amount >= 0)
-+ {
-+ change_indent(INDENT_SET, amount, FALSE, 0, TRUE);
-+ if (linewhite(curwin->w_cursor.lnum))
-+ did_ai = TRUE; /* delete the indent if the line stays empty */
-+ }
-+ }
-+
-+ void
-+ fix_indent(void)
-+ {
-+ if (p_paste)
-+ return;
-+ # ifdef FEAT_LISP
-+ if (curbuf->b_p_lisp && curbuf->b_p_ai)
-+ fixthisline(get_lisp_indent);
-+ # endif
-+ # if defined(FEAT_LISP) && defined(FEAT_CINDENT)
-+ else
-+ # endif
-+ # ifdef FEAT_CINDENT
-+ if (cindent_on())
-+ do_c_expr_indent();
-+ # endif
-+ }
-+
-+ #endif
-*** ../vim-8.1.0856/src/misc1.c 2019-01-26 17:28:22.228599112 +0100
---- src/misc1.c 2019-01-31 13:43:23.356467234 +0100
-***************
-*** 702,742 ****
- #endif
-
-
-- #if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT)
--
-- /*
-- * Return TRUE if the string "line" starts with a word from 'cinwords'.
-- */
-- static int
-- cin_is_cinword(char_u *line)
-- {
-- char_u *cinw;
-- char_u *cinw_buf;
-- int cinw_len;
-- int retval = FALSE;
-- int len;
--
-- cinw_len = (int)STRLEN(curbuf->b_p_cinw) + 1;
-- cinw_buf = alloc((unsigned)cinw_len);
-- if (cinw_buf != NULL)
-- {
-- line = skipwhite(line);
-- for (cinw = curbuf->b_p_cinw; *cinw; )
-- {
-- len = copy_option_part(&cinw, cinw_buf, cinw_len, ",");
-- if (STRNCMP(line, cinw_buf, len) == 0
-- && (!vim_iswordc(line[len]) || !vim_iswordc(line[len - 1])))
-- {
-- retval = TRUE;
-- break;
-- }
-- }
-- vim_free(cinw_buf);
-- }
-- return retval;
-- }
-- #endif
--
- /*
- * open_line: Add a new line below or above the current line.
- *
---- 702,707 ----
-***************
-*** 5404,9720 ****
- return new_fname;
- }
-
-- #if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL)
--
-- static char_u *skip_string(char_u *p);
-- static pos_T *find_start_rawstring(int ind_maxcomment);
--
-- /*
-- * Find the start of a comment, not knowing if we are in a comment right now.
-- * Search starts at w_cursor.lnum and goes backwards.
-- * Return NULL when not inside a comment.
-- */
-- static pos_T *
-- ind_find_start_comment(void) /* XXX */
-- {
-- return find_start_comment(curbuf->b_ind_maxcomment);
-- }
--
-- pos_T *
-- find_start_comment(int ind_maxcomment) /* XXX */
-- {
-- pos_T *pos;
-- char_u *line;
-- char_u *p;
-- int cur_maxcomment = ind_maxcomment;
--
-- for (;;)
-- {
-- pos = findmatchlimit(NULL, '*', FM_BACKWARD, cur_maxcomment);
-- if (pos == NULL)
-- break;
--
-- /*
-- * Check if the comment start we found is inside a string.
-- * If it is then restrict the search to below this line and try again.
-- */
-- line = ml_get(pos->lnum);
-- for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p)
-- p = skip_string(p);
-- if ((colnr_T)(p - line) <= pos->col)
-- break;
-- cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
-- if (cur_maxcomment <= 0)
-- {
-- pos = NULL;
-- break;
-- }
-- }
-- return pos;
-- }
--
-- /*
-- * Find the start of a comment or raw string, not knowing if we are in a
-- * comment or raw string right now.
-- * Search starts at w_cursor.lnum and goes backwards.
-- * If is_raw is given and returns start of raw_string, sets it to true.
-- * Return NULL when not inside a comment or raw string.
-- * "CORS" -> Comment Or Raw String
-- */
-- static pos_T *
-- ind_find_start_CORS(linenr_T *is_raw) /* XXX */
-- {
-- static pos_T comment_pos_copy;
-- pos_T *comment_pos;
-- pos_T *rs_pos;
--
-- comment_pos = find_start_comment(curbuf->b_ind_maxcomment);
-- if (comment_pos != NULL)
-- {
-- /* Need to make a copy of the static pos in findmatchlimit(),
-- * calling find_start_rawstring() may change it. */
-- comment_pos_copy = *comment_pos;
-- comment_pos = &comment_pos_copy;
-- }
-- rs_pos = find_start_rawstring(curbuf->b_ind_maxcomment);
--
-- /* If comment_pos is before rs_pos the raw string is inside the comment.
-- * If rs_pos is before comment_pos the comment is inside the raw string. */
-- if (comment_pos == NULL || (rs_pos != NULL
-- && LT_POS(*rs_pos, *comment_pos)))
-- {
-- if (is_raw != NULL && rs_pos != NULL)
-- *is_raw = rs_pos->lnum;
-- return rs_pos;
-- }
-- return comment_pos;
-- }
--
-- /*
-- * Find the start of a raw string, not knowing if we are in one right now.
-- * Search starts at w_cursor.lnum and goes backwards.
-- * Return NULL when not inside a raw string.
-- */
-- static pos_T *
-- find_start_rawstring(int ind_maxcomment) /* XXX */
-- {
-- pos_T *pos;
-- char_u *line;
-- char_u *p;
-- int cur_maxcomment = ind_maxcomment;
--
-- for (;;)
-- {
-- pos = findmatchlimit(NULL, 'R', FM_BACKWARD, cur_maxcomment);
-- if (pos == NULL)
-- break;
--
-- /*
-- * Check if the raw string start we found is inside a string.
-- * If it is then restrict the search to below this line and try again.
-- */
-- line = ml_get(pos->lnum);
-- for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p)
-- p = skip_string(p);
-- if ((colnr_T)(p - line) <= pos->col)
-- break;
-- cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
-- if (cur_maxcomment <= 0)
-- {
-- pos = NULL;
-- break;
-- }
-- }
-- return pos;
-- }
--
-- /*
-- * Skip to the end of a "string" and a 'c' character.
-- * If there is no string or character, return argument unmodified.
-- */
-- static char_u *
-- skip_string(char_u *p)
-- {
-- int i;
--
-- /*
-- * We loop, because strings may be concatenated: "date""time".
-- */
-- for ( ; ; ++p)
-- {
-- if (p[0] == '\'') /* 'c' or '\n' or '\000' */
-- {
-- if (!p[1]) /* ' at end of line */
-- break;
-- i = 2;
-- if (p[1] == '\\') /* '\n' or '\000' */
-- {
-- ++i;
-- while (vim_isdigit(p[i - 1])) /* '\000' */
-- ++i;
-- }
-- if (p[i] == '\'') /* check for trailing ' */
-- {
-- p += i;
-- continue;
-- }
-- }
-- else if (p[0] == '"') /* start of string */
-- {
-- for (++p; p[0]; ++p)
-- {
-- if (p[0] == '\\' && p[1] != NUL)
-- ++p;
-- else if (p[0] == '"') /* end of string */
-- break;
-- }
-- if (p[0] == '"')
-- continue; /* continue for another string */
-- }
-- else if (p[0] == 'R' && p[1] == '"')
-- {
-- /* Raw string: R"[delim](...)[delim]" */
-- char_u *delim = p + 2;
-- char_u *paren = vim_strchr(delim, '(');
--
-- if (paren != NULL)
-- {
-- size_t delim_len = paren - delim;
--
-- for (p += 3; *p; ++p)
-- if (p[0] == ')' && STRNCMP(p + 1, delim, delim_len) == 0
-- && p[delim_len + 1] == '"')
-- {
-- p += delim_len + 1;
-- break;
-- }
-- if (p[0] == '"')
-- continue; /* continue for another string */
-- }
-- }
-- break; /* no string found */
-- }
-- if (!*p)
-- --p; /* backup from NUL */
-- return p;
-- }
-- #endif /* FEAT_CINDENT || FEAT_SYN_HL */
--
-- #if defined(FEAT_CINDENT) || defined(PROTO)
--
-- /*
-- * Do C or expression indenting on the current line.
-- */
-- void
-- do_c_expr_indent(void)
-- {
-- # ifdef FEAT_EVAL
-- if (*curbuf->b_p_inde != NUL)
-- fixthisline(get_expr_indent);
-- else
-- # endif
-- fixthisline(get_c_indent);
-- }
--
-- /* Find result cache for cpp_baseclass */
-- typedef struct {
-- int found;
-- lpos_T lpos;
-- } cpp_baseclass_cache_T;
--
-- /*
-- * Functions for C-indenting.
-- * Most of this originally comes from Eric Fischer.
-- */
-- /*
-- * Below "XXX" means that this function may unlock the current line.
-- */
--
-- static int cin_isdefault(char_u *);
-- static int cin_ispreproc(char_u *);
-- static int cin_iscomment(char_u *);
-- static int cin_islinecomment(char_u *);
-- static int cin_isterminated(char_u *, int, int);
-- static int cin_iselse(char_u *);
-- static int cin_ends_in(char_u *, char_u *, char_u *);
-- static int cin_starts_with(char_u *s, char *word);
-- static pos_T *find_match_paren(int);
-- static pos_T *find_match_char(int c, int ind_maxparen);
-- static int find_last_paren(char_u *l, int start, int end);
-- static int find_match(int lookfor, linenr_T ourscope);
--
-- /*
-- * Skip over white space and C comments within the line.
-- * Also skip over Perl/shell comments if desired.
-- */
-- static char_u *
-- cin_skipcomment(char_u *s)
-- {
-- while (*s)
-- {
-- char_u *prev_s = s;
--
-- s = skipwhite(s);
--
-- /* Perl/shell # comment comment continues until eol. Require a space
-- * before # to avoid recognizing $#array. */
-- if (curbuf->b_ind_hash_comment != 0 && s != prev_s && *s == '#')
-- {
-- s += STRLEN(s);
-- break;
-- }
-- if (*s != '/')
-- break;
-- ++s;
-- if (*s == '/') /* slash-slash comment continues till eol */
-- {
-- s += STRLEN(s);
-- break;
-- }
-- if (*s != '*')
-- break;
-- for (++s; *s; ++s) /* skip slash-star comment */
-- if (s[0] == '*' && s[1] == '/')
-- {
-- s += 2;
-- break;
-- }
-- }
-- return s;
-- }
--
-- /*
-- * Return TRUE if there is no code at *s. White space and comments are
-- * not considered code.
-- */
-- static int
-- cin_nocode(char_u *s)
-- {
-- return *cin_skipcomment(s) == NUL;
-- }
--
-- /*
-- * Check previous lines for a "//" line comment, skipping over blank lines.
-- */
-- static pos_T *
-- find_line_comment(void) /* XXX */
-- {
-- static pos_T pos;
-- char_u *line;
-- char_u *p;
--
-- pos = curwin->w_cursor;
-- while (--pos.lnum > 0)
-- {
-- line = ml_get(pos.lnum);
-- p = skipwhite(line);
-- if (cin_islinecomment(p))
-- {
-- pos.col = (int)(p - line);
-- return &pos;
-- }
-- if (*p != NUL)
-- break;
-- }
-- return NULL;
-- }
--
-- /*
-- * Return TRUE if "text" starts with "key:".
-- */
-- static int
-- cin_has_js_key(char_u *text)
-- {
-- char_u *s = skipwhite(text);
-- int quote = -1;
--
-- if (*s == '\'' || *s == '"')
-- {
-- /* can be 'key': or "key": */
-- quote = *s;
-- ++s;
-- }
-- if (!vim_isIDc(*s)) /* need at least one ID character */
-- return FALSE;
--
-- while (vim_isIDc(*s))
-- ++s;
-- if (*s == quote)
-- ++s;
--
-- s = cin_skipcomment(s);
--
-- /* "::" is not a label, it's C++ */
-- return (*s == ':' && s[1] != ':');
-- }
--
-- /*
-- * Check if string matches "label:"; move to character after ':' if true.
-- * "*s" must point to the start of the label, if there is one.
-- */
-- static int
-- cin_islabel_skip(char_u **s)
-- {
-- if (!vim_isIDc(**s)) /* need at least one ID character */
-- return FALSE;
--
-- while (vim_isIDc(**s))
-- (*s)++;
--
-- *s = cin_skipcomment(*s);
--
-- /* "::" is not a label, it's C++ */
-- return (**s == ':' && *++*s != ':');
-- }
--
-- /*
-- * Recognize a label: "label:".
-- * Note: curwin->w_cursor must be where we are looking for the label.
-- */
-- int
-- cin_islabel(void) /* XXX */
-- {
-- char_u *s;
--
-- s = cin_skipcomment(ml_get_curline());
--
-- /*
-- * Exclude "default" from labels, since it should be indented
-- * like a switch label. Same for C++ scope declarations.
-- */
-- if (cin_isdefault(s))
-- return FALSE;
-- if (cin_isscopedecl(s))
-- return FALSE;
--
-- if (cin_islabel_skip(&s))
-- {
-- /*
-- * Only accept a label if the previous line is terminated or is a case
-- * label.
-- */
-- pos_T cursor_save;
-- pos_T *trypos;
-- char_u *line;
--
-- cursor_save = curwin->w_cursor;
-- while (curwin->w_cursor.lnum > 1)
-- {
-- --curwin->w_cursor.lnum;
--
-- /*
-- * If we're in a comment or raw string now, skip to the start of
-- * it.
-- */
-- curwin->w_cursor.col = 0;
-- if ((trypos = ind_find_start_CORS(NULL)) != NULL) /* XXX */
-- curwin->w_cursor = *trypos;
--
-- line = ml_get_curline();
-- if (cin_ispreproc(line)) /* ignore #defines, #if, etc. */
-- continue;
-- if (*(line = cin_skipcomment(line)) == NUL)
-- continue;
--
-- curwin->w_cursor = cursor_save;
-- if (cin_isterminated(line, TRUE, FALSE)
-- || cin_isscopedecl(line)
-- || cin_iscase(line, TRUE)
-- || (cin_islabel_skip(&line) && cin_nocode(line)))
-- return TRUE;
-- return FALSE;
-- }
-- curwin->w_cursor = cursor_save;
-- return TRUE; /* label at start of file??? */
-- }
-- return FALSE;
-- }
--
-- /*
-- * Recognize structure initialization and enumerations:
-- * "[typedef] [static|public|protected|private] enum"
-- * "[typedef] [static|public|protected|private] = {"
-- */
-- static int
-- cin_isinit(void)
-- {
-- char_u *s;
-- static char *skip[] = {"static", "public", "protected", "private"};
--
-- s = cin_skipcomment(ml_get_curline());
--
-- if (cin_starts_with(s, "typedef"))
-- s = cin_skipcomment(s + 7);
--
-- for (;;)
-- {
-- int i, l;
--
-- for (i = 0; i < (int)(sizeof(skip) / sizeof(char *)); ++i)
-- {
-- l = (int)strlen(skip[i]);
-- if (cin_starts_with(s, skip[i]))
-- {
-- s = cin_skipcomment(s + l);
-- l = 0;
-- break;
-- }
-- }
-- if (l != 0)
-- break;
-- }
--
-- if (cin_starts_with(s, "enum"))
-- return TRUE;
--
-- if (cin_ends_in(s, (char_u *)"=", (char_u *)"{"))
-- return TRUE;
--
-- return FALSE;
-- }
--
-- /*
-- * Recognize a switch label: "case .*:" or "default:".
-- */
-- int
-- cin_iscase(
-- char_u *s,
-- int strict) /* Allow relaxed check of case statement for JS */
-- {
-- s = cin_skipcomment(s);
-- if (cin_starts_with(s, "case"))
-- {
-- for (s += 4; *s; ++s)
-- {
-- s = cin_skipcomment(s);
-- if (*s == ':')
-- {
-- if (s[1] == ':') /* skip over "::" for C++ */
-- ++s;
-- else
-- return TRUE;
-- }
-- if (*s == '\'' && s[1] && s[2] == '\'')
-- s += 2; /* skip over ':' */
-- else if (*s == '/' && (s[1] == '*' || s[1] == '/'))
-- return FALSE; /* stop at comment */
-- else if (*s == '"')
-- {
-- /* JS etc. */
-- if (strict)
-- return FALSE; /* stop at string */
-- else
-- return TRUE;
-- }
-- }
-- return FALSE;
-- }
--
-- if (cin_isdefault(s))
-- return TRUE;
-- return FALSE;
-- }
--
-- /*
-- * Recognize a "default" switch label.
-- */
-- static int
-- cin_isdefault(char_u *s)
-- {
-- return (STRNCMP(s, "default", 7) == 0
-- && *(s = cin_skipcomment(s + 7)) == ':'
-- && s[1] != ':');
-- }
--
-- /*
-- * Recognize a "public/private/protected" scope declaration label.
-- */
-- int
-- cin_isscopedecl(char_u *s)
-- {
-- int i;
--
-- s = cin_skipcomment(s);
-- if (STRNCMP(s, "public", 6) == 0)
-- i = 6;
-- else if (STRNCMP(s, "protected", 9) == 0)
-- i = 9;
-- else if (STRNCMP(s, "private", 7) == 0)
-- i = 7;
-- else
-- return FALSE;
-- return (*(s = cin_skipcomment(s + i)) == ':' && s[1] != ':');
-- }
--
-- /* Maximum number of lines to search back for a "namespace" line. */
-- #define FIND_NAMESPACE_LIM 20
--
-- /*
-- * Recognize a "namespace" scope declaration.
-- */
-- static int
-- cin_is_cpp_namespace(char_u *s)
-- {
-- char_u *p;
-- int has_name = FALSE;
-- int has_name_start = FALSE;
--
-- s = cin_skipcomment(s);
-- if (STRNCMP(s, "namespace", 9) == 0 && (s[9] == NUL || !vim_iswordc(s[9])))
-- {
-- p = cin_skipcomment(skipwhite(s + 9));
-- while (*p != NUL)
-- {
-- if (VIM_ISWHITE(*p))
-- {
-- has_name = TRUE; /* found end of a name */
-- p = cin_skipcomment(skipwhite(p));
-- }
-- else if (*p == '{')
-- {
-- break;
-- }
-- else if (vim_iswordc(*p))
-- {
-- has_name_start = TRUE;
-- if (has_name)
-- return FALSE; /* word character after skipping past name */
-- ++p;
-- }
-- else if (p[0] == ':' && p[1] == ':' && vim_iswordc(p[2]))
-- {
-- if (!has_name_start || has_name)
-- return FALSE;
-- /* C++ 17 nested namespace */
-- p += 3;
-- }
-- else
-- {
-- return FALSE;
-- }
-- }
-- return TRUE;
-- }
-- return FALSE;
-- }
--
-- /*
-- * Recognize a `extern "C"` or `extern "C++"` linkage specifications.
-- */
-- static int
-- cin_is_cpp_extern_c(char_u *s)
-- {
-- char_u *p;
-- int has_string_literal = FALSE;
--
-- s = cin_skipcomment(s);
-- if (STRNCMP(s, "extern", 6) == 0 && (s[6] == NUL || !vim_iswordc(s[6])))
-- {
-- p = cin_skipcomment(skipwhite(s + 6));
-- while (*p != NUL)
-- {
-- if (VIM_ISWHITE(*p))
-- {
-- p = cin_skipcomment(skipwhite(p));
-- }
-- else if (*p == '{')
-- {
-- break;
-- }
-- else if (p[0] == '"' && p[1] == 'C' && p[2] == '"')
-- {
-- if (has_string_literal)
-- return FALSE;
-- has_string_literal = TRUE;
-- p += 3;
-- }
-- else if (p[0] == '"' && p[1] == 'C' && p[2] == '+' && p[3] == '+'
-- && p[4] == '"')
-- {
-- if (has_string_literal)
-- return FALSE;
-- has_string_literal = TRUE;
-- p += 5;
-- }
-- else
-- {
-- return FALSE;
-- }
-- }
-- return has_string_literal ? TRUE : FALSE;
-- }
-- return FALSE;
-- }
--
-- /*
-- * Return a pointer to the first non-empty non-comment character after a ':'.
-- * Return NULL if not found.
-- * case 234: a = b;
-- * ^
-- */
-- static char_u *
-- after_label(char_u *l)
-- {
-- for ( ; *l; ++l)
-- {
-- if (*l == ':')
-- {
-- if (l[1] == ':') /* skip over "::" for C++ */
-- ++l;
-- else if (!cin_iscase(l + 1, FALSE))
-- break;
-- }
-- else if (*l == '\'' && l[1] && l[2] == '\'')
-- l += 2; /* skip over 'x' */
-- }
-- if (*l == NUL)
-- return NULL;
-- l = cin_skipcomment(l + 1);
-- if (*l == NUL)
-- return NULL;
-- return l;
-- }
--
-- /*
-- * Get indent of line "lnum", skipping a label.
-- * Return 0 if there is nothing after the label.
-- */
-- static int
-- get_indent_nolabel (linenr_T lnum) /* XXX */
-- {
-- char_u *l;
-- pos_T fp;
-- colnr_T col;
-- char_u *p;
--
-- l = ml_get(lnum);
-- p = after_label(l);
-- if (p == NULL)
-- return 0;
--
-- fp.col = (colnr_T)(p - l);
-- fp.lnum = lnum;
-- getvcol(curwin, &fp, &col, NULL, NULL);
-- return (int)col;
-- }
--
-- /*
-- * Find indent for line "lnum", ignoring any case or jump label.
-- * Also return a pointer to the text (after the label) in "pp".
-- * label: if (asdf && asdfasdf)
-- * ^
-- */
-- static int
-- skip_label(linenr_T lnum, char_u **pp)
-- {
-- char_u *l;
-- int amount;
-- pos_T cursor_save;
--
-- cursor_save = curwin->w_cursor;
-- curwin->w_cursor.lnum = lnum;
-- l = ml_get_curline();
-- /* XXX */
-- if (cin_iscase(l, FALSE) || cin_isscopedecl(l) || cin_islabel())
-- {
-- amount = get_indent_nolabel(lnum);
-- l = after_label(ml_get_curline());
-- if (l == NULL) /* just in case */
-- l = ml_get_curline();
-- }
-- else
-- {
-- amount = get_indent();
-- l = ml_get_curline();
-- }
-- *pp = l;
--
-- curwin->w_cursor = cursor_save;
-- return amount;
-- }
--
-- /*
-- * Return the indent of the first variable name after a type in a declaration.
-- * int a, indent of "a"
-- * static struct foo b, indent of "b"
-- * enum bla c, indent of "c"
-- * Returns zero when it doesn't look like a declaration.
-- */
-- static int
-- cin_first_id_amount(void)
-- {
-- char_u *line, *p, *s;
-- int len;
-- pos_T fp;
-- colnr_T col;
--
-- line = ml_get_curline();
-- p = skipwhite(line);
-- len = (int)(skiptowhite(p) - p);
-- if (len == 6 && STRNCMP(p, "static", 6) == 0)
-- {
-- p = skipwhite(p + 6);
-- len = (int)(skiptowhite(p) - p);
-- }
-- if (len == 6 && STRNCMP(p, "struct", 6) == 0)
-- p = skipwhite(p + 6);
-- else if (len == 4 && STRNCMP(p, "enum", 4) == 0)
-- p = skipwhite(p + 4);
-- else if ((len == 8 && STRNCMP(p, "unsigned", 8) == 0)
-- || (len == 6 && STRNCMP(p, "signed", 6) == 0))
-- {
-- s = skipwhite(p + len);
-- if ((STRNCMP(s, "int", 3) == 0 && VIM_ISWHITE(s[3]))
-- || (STRNCMP(s, "long", 4) == 0 && VIM_ISWHITE(s[4]))
-- || (STRNCMP(s, "short", 5) == 0 && VIM_ISWHITE(s[5]))
-- || (STRNCMP(s, "char", 4) == 0 && VIM_ISWHITE(s[4])))
-- p = s;
-- }
-- for (len = 0; vim_isIDc(p[len]); ++len)
-- ;
-- if (len == 0 || !VIM_ISWHITE(p[len]) || cin_nocode(p))
-- return 0;
--
-- p = skipwhite(p + len);
-- fp.lnum = curwin->w_cursor.lnum;
-- fp.col = (colnr_T)(p - line);
-- getvcol(curwin, &fp, &col, NULL, NULL);
-- return (int)col;
-- }
--
-- /*
-- * Return the indent of the first non-blank after an equal sign.
-- * char *foo = "here";
-- * Return zero if no (useful) equal sign found.
-- * Return -1 if the line above "lnum" ends in a backslash.
-- * foo = "asdf\
-- * asdf\
-- * here";
-- */
-- static int
-- cin_get_equal_amount(linenr_T lnum)
-- {
-- char_u *line;
-- char_u *s;
-- colnr_T col;
-- pos_T fp;
--
-- if (lnum > 1)
-- {
-- line = ml_get(lnum - 1);
-- if (*line != NUL && line[STRLEN(line) - 1] == '\\')
-- return -1;
-- }
--
-- line = s = ml_get(lnum);
-- while (*s != NUL && vim_strchr((char_u *)"=;{}\"'", *s) == NULL)
-- {
-- if (cin_iscomment(s)) /* ignore comments */
-- s = cin_skipcomment(s);
-- else
-- ++s;
-- }
-- if (*s != '=')
-- return 0;
--
-- s = skipwhite(s + 1);
-- if (cin_nocode(s))
-- return 0;
--
-- if (*s == '"') /* nice alignment for continued strings */
-- ++s;
--
-- fp.lnum = lnum;
-- fp.col = (colnr_T)(s - line);
-- getvcol(curwin, &fp, &col, NULL, NULL);
-- return (int)col;
-- }
--
-- /*
-- * Recognize a preprocessor statement: Any line that starts with '#'.
-- */
-- static int
-- cin_ispreproc(char_u *s)
-- {
-- if (*skipwhite(s) == '#')
-- return TRUE;
-- return FALSE;
-- }
--
-- /*
-- * Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a
-- * continuation line of a preprocessor statement. Decrease "*lnump" to the
-- * start and return the line in "*pp".
-- * Put the amount of indent in "*amount".
-- */
-- static int
-- cin_ispreproc_cont(char_u **pp, linenr_T *lnump, int *amount)
-- {
-- char_u *line = *pp;
-- linenr_T lnum = *lnump;
-- int retval = FALSE;
-- int candidate_amount = *amount;
--
-- if (*line != NUL && line[STRLEN(line) - 1] == '\\')
-- candidate_amount = get_indent_lnum(lnum);
--
-- for (;;)
-- {
-- if (cin_ispreproc(line))
-- {
-- retval = TRUE;
-- *lnump = lnum;
-- break;
-- }
-- if (lnum == 1)
-- break;
-- line = ml_get(--lnum);
-- if (*line == NUL || line[STRLEN(line) - 1] != '\\')
-- break;
-- }
--
-- if (lnum != *lnump)
-- *pp = ml_get(*lnump);
-- if (retval)
-- *amount = candidate_amount;
-- return retval;
-- }
--
-- /*
-- * Recognize the start of a C or C++ comment.
-- */
-- static int
-- cin_iscomment(char_u *p)
-- {
-- return (p[0] == '/' && (p[1] == '*' || p[1] == '/'));
-- }
--
-- /*
-- * Recognize the start of a "//" comment.
-- */
-- static int
-- cin_islinecomment(char_u *p)
-- {
-- return (p[0] == '/' && p[1] == '/');
-- }
--
-- /*
-- * Recognize a line that starts with '{' or '}', or ends with ';', ',', '{' or
-- * '}'.
-- * Don't consider "} else" a terminated line.
-- * If a line begins with an "else", only consider it terminated if no unmatched
-- * opening braces follow (handle "else { foo();" correctly).
-- * Return the character terminating the line (ending char's have precedence if
-- * both apply in order to determine initializations).
-- */
-- static int
-- cin_isterminated(
-- char_u *s,
-- int incl_open, /* include '{' at the end as terminator */
-- int incl_comma) /* recognize a trailing comma */
-- {
-- char_u found_start = 0;
-- unsigned n_open = 0;
-- int is_else = FALSE;
--
-- s = cin_skipcomment(s);
--
-- if (*s == '{' || (*s == '}' && !cin_iselse(s)))
-- found_start = *s;
--
-- if (!found_start)
-- is_else = cin_iselse(s);
--
-- while (*s)
-- {
-- /* skip over comments, "" strings and 'c'haracters */
-- s = skip_string(cin_skipcomment(s));
-- if (*s == '}' && n_open > 0)
-- --n_open;
-- if ((!is_else || n_open == 0)
-- && (*s == ';' || *s == '}' || (incl_comma && *s == ','))
-- && cin_nocode(s + 1))
-- return *s;
-- else if (*s == '{')
-- {
-- if (incl_open && cin_nocode(s + 1))
-- return *s;
-- else
-- ++n_open;
-- }
--
-- if (*s)
-- s++;
-- }
-- return found_start;
-- }
--
-- /*
-- * Recognize the basic picture of a function declaration -- it needs to
-- * have an open paren somewhere and a close paren at the end of the line and
-- * no semicolons anywhere.
-- * When a line ends in a comma we continue looking in the next line.
-- * "sp" points to a string with the line. When looking at other lines it must
-- * be restored to the line. When it's NULL fetch lines here.
-- * "first_lnum" is where we start looking.
-- * "min_lnum" is the line before which we will not be looking.
-- */
-- static int
-- cin_isfuncdecl(
-- char_u **sp,
-- linenr_T first_lnum,
-- linenr_T min_lnum)
-- {
-- char_u *s;
-- linenr_T lnum = first_lnum;
-- linenr_T save_lnum = curwin->w_cursor.lnum;
-- int retval = FALSE;
-- pos_T *trypos;
-- int just_started = TRUE;
--
-- if (sp == NULL)
-- s = ml_get(lnum);
-- else
-- s = *sp;
--
-- curwin->w_cursor.lnum = lnum;
-- if (find_last_paren(s, '(', ')')
-- && (trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
-- {
-- lnum = trypos->lnum;
-- if (lnum < min_lnum)
-- {
-- curwin->w_cursor.lnum = save_lnum;
-- return FALSE;
-- }
--
-- s = ml_get(lnum);
-- }
-- curwin->w_cursor.lnum = save_lnum;
--
-- /* Ignore line starting with #. */
-- if (cin_ispreproc(s))
-- return FALSE;
--
-- while (*s && *s != '(' && *s != ';' && *s != '\'' && *s != '"')
-- {
-- if (cin_iscomment(s)) /* ignore comments */
-- s = cin_skipcomment(s);
-- else if (*s == ':')
-- {
-- if (*(s + 1) == ':')
-- s += 2;
-- else
-- /* To avoid a mistake in the following situation:
-- * A::A(int a, int b)
-- * : a(0) // <--not a function decl
-- * , b(0)
-- * {...
-- */
-- return FALSE;
-- }
-- else
-- ++s;
-- }
-- if (*s != '(')
-- return FALSE; /* ';', ' or " before any () or no '(' */
--
-- while (*s && *s != ';' && *s != '\'' && *s != '"')
-- {
-- if (*s == ')' && cin_nocode(s + 1))
-- {
-- /* ')' at the end: may have found a match
-- * Check for he previous line not to end in a backslash:
-- * #if defined(x) && \
-- * defined(y)
-- */
-- lnum = first_lnum - 1;
-- s = ml_get(lnum);
-- if (*s == NUL || s[STRLEN(s) - 1] != '\\')
-- retval = TRUE;
-- goto done;
-- }
-- if ((*s == ',' && cin_nocode(s + 1)) || s[1] == NUL || cin_nocode(s))
-- {
-- int comma = (*s == ',');
--
-- /* ',' at the end: continue looking in the next line.
-- * At the end: check for ',' in the next line, for this style:
-- * func(arg1
-- * , arg2) */
-- for (;;)
-- {
-- if (lnum >= curbuf->b_ml.ml_line_count)
-- break;
-- s = ml_get(++lnum);
-- if (!cin_ispreproc(s))
-- break;
-- }
-- if (lnum >= curbuf->b_ml.ml_line_count)
-- break;
-- /* Require a comma at end of the line or a comma or ')' at the
-- * start of next line. */
-- s = skipwhite(s);
-- if (!just_started && (!comma && *s != ',' && *s != ')'))
-- break;
-- just_started = FALSE;
-- }
-- else if (cin_iscomment(s)) /* ignore comments */
-- s = cin_skipcomment(s);
-- else
-- {
-- ++s;
-- just_started = FALSE;
-- }
-- }
--
-- done:
-- if (lnum != first_lnum && sp != NULL)
-- *sp = ml_get(first_lnum);
--
-- return retval;
-- }
--
-- static int
-- cin_isif(char_u *p)
-- {
-- return (STRNCMP(p, "if", 2) == 0 && !vim_isIDc(p[2]));
-- }
--
-- static int
-- cin_iselse(
-- char_u *p)
-- {
-- if (*p == '}') /* accept "} else" */
-- p = cin_skipcomment(p + 1);
-- return (STRNCMP(p, "else", 4) == 0 && !vim_isIDc(p[4]));
-- }
--
-- static int
-- cin_isdo(char_u *p)
-- {
-- return (STRNCMP(p, "do", 2) == 0 && !vim_isIDc(p[2]));
-- }
--
-- /*
-- * Check if this is a "while" that should have a matching "do".
-- * We only accept a "while (condition) ;", with only white space between the
-- * ')' and ';'. The condition may be spread over several lines.
-- */
-- static int
-- cin_iswhileofdo (char_u *p, linenr_T lnum) /* XXX */
-- {
-- pos_T cursor_save;
-- pos_T *trypos;
-- int retval = FALSE;
--
-- p = cin_skipcomment(p);
-- if (*p == '}') /* accept "} while (cond);" */
-- p = cin_skipcomment(p + 1);
-- if (cin_starts_with(p, "while"))
-- {
-- cursor_save = curwin->w_cursor;
-- curwin->w_cursor.lnum = lnum;
-- curwin->w_cursor.col = 0;
-- p = ml_get_curline();
-- while (*p && *p != 'w') /* skip any '}', until the 'w' of the "while" */
-- {
-- ++p;
-- ++curwin->w_cursor.col;
-- }
-- if ((trypos = findmatchlimit(NULL, 0, 0,
-- curbuf->b_ind_maxparen)) != NULL
-- && *cin_skipcomment(ml_get_pos(trypos) + 1) == ';')
-- retval = TRUE;
-- curwin->w_cursor = cursor_save;
-- }
-- return retval;
-- }
--
-- /*
-- * Check whether in "p" there is an "if", "for" or "while" before "*poffset".
-- * Return 0 if there is none.
-- * Otherwise return !0 and update "*poffset" to point to the place where the
-- * string was found.
-- */
-- static int
-- cin_is_if_for_while_before_offset(char_u *line, int *poffset)
-- {
-- int offset = *poffset;
--
-- if (offset-- < 2)
-- return 0;
-- while (offset > 2 && VIM_ISWHITE(line[offset]))
-- --offset;
--
-- offset -= 1;
-- if (!STRNCMP(line + offset, "if", 2))
-- goto probablyFound;
--
-- if (offset >= 1)
-- {
-- offset -= 1;
-- if (!STRNCMP(line + offset, "for", 3))
-- goto probablyFound;
--
-- if (offset >= 2)
-- {
-- offset -= 2;
-- if (!STRNCMP(line + offset, "while", 5))
-- goto probablyFound;
-- }
-- }
-- return 0;
--
-- probablyFound:
-- if (!offset || !vim_isIDc(line[offset - 1]))
-- {
-- *poffset = offset;
-- return 1;
-- }
-- return 0;
-- }
--
-- /*
-- * Return TRUE if we are at the end of a do-while.
-- * do
-- * nothing;
-- * while (foo
-- * && bar); <-- here
-- * Adjust the cursor to the line with "while".
-- */
-- static int
-- cin_iswhileofdo_end(int terminated)
-- {
-- char_u *line;
-- char_u *p;
-- char_u *s;
-- pos_T *trypos;
-- int i;
--
-- if (terminated != ';') /* there must be a ';' at the end */
-- return FALSE;
--
-- p = line = ml_get_curline();
-- while (*p != NUL)
-- {
-- p = cin_skipcomment(p);
-- if (*p == ')')
-- {
-- s = skipwhite(p + 1);
-- if (*s == ';' && cin_nocode(s + 1))
-- {
-- /* Found ");" at end of the line, now check there is "while"
-- * before the matching '('. XXX */
-- i = (int)(p - line);
-- curwin->w_cursor.col = i;
-- trypos = find_match_paren(curbuf->b_ind_maxparen);
-- if (trypos != NULL)
-- {
-- s = cin_skipcomment(ml_get(trypos->lnum));
-- if (*s == '}') /* accept "} while (cond);" */
-- s = cin_skipcomment(s + 1);
-- if (cin_starts_with(s, "while"))
-- {
-- curwin->w_cursor.lnum = trypos->lnum;
-- return TRUE;
-- }
-- }
--
-- /* Searching may have made "line" invalid, get it again. */
-- line = ml_get_curline();
-- p = line + i;
-- }
-- }
-- if (*p != NUL)
-- ++p;
-- }
-- return FALSE;
-- }
--
-- static int
-- cin_isbreak(char_u *p)
-- {
-- return (STRNCMP(p, "break", 5) == 0 && !vim_isIDc(p[5]));
-- }
--
-- /*
-- * Find the position of a C++ base-class declaration or
-- * constructor-initialization. eg:
-- *
-- * class MyClass :
-- * baseClass <-- here
-- * class MyClass : public baseClass,
-- * anotherBaseClass <-- here (should probably lineup ??)
-- * MyClass::MyClass(...) :
-- * baseClass(...) <-- here (constructor-initialization)
-- *
-- * This is a lot of guessing. Watch out for "cond ? func() : foo".
-- */
-- static int
-- cin_is_cpp_baseclass(
-- cpp_baseclass_cache_T *cached) /* input and output */
-- {
-- lpos_T *pos = &cached->lpos; /* find position */
-- char_u *s;
-- int class_or_struct, lookfor_ctor_init, cpp_base_class;
-- linenr_T lnum = curwin->w_cursor.lnum;
-- char_u *line = ml_get_curline();
--
-- if (pos->lnum <= lnum)
-- return cached->found; /* Use the cached result */
--
-- pos->col = 0;
--
-- s = skipwhite(line);
-- if (*s == '#') /* skip #define FOO x ? (x) : x */
-- return FALSE;
-- s = cin_skipcomment(s);
-- if (*s == NUL)
-- return FALSE;
--
-- cpp_base_class = lookfor_ctor_init = class_or_struct = FALSE;
--
-- /* Search for a line starting with '#', empty, ending in ';' or containing
-- * '{' or '}' and start below it. This handles the following situations:
-- * a = cond ?
-- * func() :
-- * asdf;
-- * func::foo()
-- * : something
-- * {}
-- * Foo::Foo (int one, int two)
-- * : something(4),
-- * somethingelse(3)
-- * {}
-- */
-- while (lnum > 1)
-- {
-- line = ml_get(lnum - 1);
-- s = skipwhite(line);
-- if (*s == '#' || *s == NUL)
-- break;
-- while (*s != NUL)
-- {
-- s = cin_skipcomment(s);
-- if (*s == '{' || *s == '}'
-- || (*s == ';' && cin_nocode(s + 1)))
-- break;
-- if (*s != NUL)
-- ++s;
-- }
-- if (*s != NUL)
-- break;
-- --lnum;
-- }
--
-- pos->lnum = lnum;
-- line = ml_get(lnum);
-- s = line;
-- for (;;)
-- {
-- if (*s == NUL)
-- {
-- if (lnum == curwin->w_cursor.lnum)
-- break;
-- /* Continue in the cursor line. */
-- line = ml_get(++lnum);
-- s = line;
-- }
-- if (s == line)
-- {
-- /* don't recognize "case (foo):" as a baseclass */
-- if (cin_iscase(s, FALSE))
-- break;
-- s = cin_skipcomment(line);
-- if (*s == NUL)
-- continue;
-- }
--
-- if (s[0] == '"' || (s[0] == 'R' && s[1] == '"'))
-- s = skip_string(s) + 1;
-- else if (s[0] == ':')
-- {
-- if (s[1] == ':')
-- {
-- /* skip double colon. It can't be a constructor
-- * initialization any more */
-- lookfor_ctor_init = FALSE;
-- s = cin_skipcomment(s + 2);
-- }
-- else if (lookfor_ctor_init || class_or_struct)
-- {
-- /* we have something found, that looks like the start of
-- * cpp-base-class-declaration or constructor-initialization */
-- cpp_base_class = TRUE;
-- lookfor_ctor_init = class_or_struct = FALSE;
-- pos->col = 0;
-- s = cin_skipcomment(s + 1);
-- }
-- else
-- s = cin_skipcomment(s + 1);
-- }
-- else if ((STRNCMP(s, "class", 5) == 0 && !vim_isIDc(s[5]))
-- || (STRNCMP(s, "struct", 6) == 0 && !vim_isIDc(s[6])))
-- {
-- class_or_struct = TRUE;
-- lookfor_ctor_init = FALSE;
--
-- if (*s == 'c')
-- s = cin_skipcomment(s + 5);
-- else
-- s = cin_skipcomment(s + 6);
-- }
-- else
-- {
-- if (s[0] == '{' || s[0] == '}' || s[0] == ';')
-- {
-- cpp_base_class = lookfor_ctor_init = class_or_struct = FALSE;
-- }
-- else if (s[0] == ')')
-- {
-- /* Constructor-initialization is assumed if we come across
-- * something like "):" */
-- class_or_struct = FALSE;
-- lookfor_ctor_init = TRUE;
-- }
-- else if (s[0] == '?')
-- {
-- /* Avoid seeing '() :' after '?' as constructor init. */
-- return FALSE;
-- }
-- else if (!vim_isIDc(s[0]))
-- {
-- /* if it is not an identifier, we are wrong */
-- class_or_struct = FALSE;
-- lookfor_ctor_init = FALSE;
-- }
-- else if (pos->col == 0)
-- {
-- /* it can't be a constructor-initialization any more */
-- lookfor_ctor_init = FALSE;
--
-- /* the first statement starts here: lineup with this one... */
-- if (cpp_base_class)
-- pos->col = (colnr_T)(s - line);
-- }
--
-- /* When the line ends in a comma don't align with it. */
-- if (lnum == curwin->w_cursor.lnum && *s == ',' && cin_nocode(s + 1))
-- pos->col = 0;
--
-- s = cin_skipcomment(s + 1);
-- }
-- }
--
-- cached->found = cpp_base_class;
-- if (cpp_base_class)
-- pos->lnum = lnum;
-- return cpp_base_class;
-- }
--
-- static int
-- get_baseclass_amount(int col)
-- {
-- int amount;
-- colnr_T vcol;
-- pos_T *trypos;
--
-- if (col == 0)
-- {
-- amount = get_indent();
-- if (find_last_paren(ml_get_curline(), '(', ')')
-- && (trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
-- amount = get_indent_lnum(trypos->lnum); /* XXX */
-- if (!cin_ends_in(ml_get_curline(), (char_u *)",", NULL))
-- amount += curbuf->b_ind_cpp_baseclass;
-- }
-- else
-- {
-- curwin->w_cursor.col = col;
-- getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
-- amount = (int)vcol;
-- }
-- if (amount < curbuf->b_ind_cpp_baseclass)
-- amount = curbuf->b_ind_cpp_baseclass;
-- return amount;
-- }
--
-- /*
-- * Return TRUE if string "s" ends with the string "find", possibly followed by
-- * white space and comments. Skip strings and comments.
-- * Ignore "ignore" after "find" if it's not NULL.
-- */
-- static int
-- cin_ends_in(char_u *s, char_u *find, char_u *ignore)
-- {
-- char_u *p = s;
-- char_u *r;
-- int len = (int)STRLEN(find);
--
-- while (*p != NUL)
-- {
-- p = cin_skipcomment(p);
-- if (STRNCMP(p, find, len) == 0)
-- {
-- r = skipwhite(p + len);
-- if (ignore != NULL && STRNCMP(r, ignore, STRLEN(ignore)) == 0)
-- r = skipwhite(r + STRLEN(ignore));
-- if (cin_nocode(r))
-- return TRUE;
-- }
-- if (*p != NUL)
-- ++p;
-- }
-- return FALSE;
-- }
--
-- /*
-- * Return TRUE when "s" starts with "word" and then a non-ID character.
-- */
-- static int
-- cin_starts_with(char_u *s, char *word)
-- {
-- int l = (int)STRLEN(word);
--
-- return (STRNCMP(s, word, l) == 0 && !vim_isIDc(s[l]));
-- }
--
-- /*
-- * Skip strings, chars and comments until at or past "trypos".
-- * Return the column found.
-- */
-- static int
-- cin_skip2pos(pos_T *trypos)
-- {
-- char_u *line;
-- char_u *p;
-- char_u *new_p;
--
-- p = line = ml_get(trypos->lnum);
-- while (*p && (colnr_T)(p - line) < trypos->col)
-- {
-- if (cin_iscomment(p))
-- p = cin_skipcomment(p);
-- else
-- {
-- new_p = skip_string(p);
-- if (new_p == p)
-- ++p;
-- else
-- p = new_p;
-- }
-- }
-- return (int)(p - line);
-- }
--
-- /*
-- * Find the '{' at the start of the block we are in.
-- * Return NULL if no match found.
-- * Ignore a '{' that is in a comment, makes indenting the next three lines
-- * work. */
-- /* foo() */
-- /* { */
-- /* } */
--
-- static pos_T *
-- find_start_brace(void) /* XXX */
-- {
-- pos_T cursor_save;
-- pos_T *trypos;
-- pos_T *pos;
-- static pos_T pos_copy;
--
-- cursor_save = curwin->w_cursor;
-- while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP, 0)) != NULL)
-- {
-- pos_copy = *trypos; /* copy pos_T, next findmatch will change it */
-- trypos = &pos_copy;
-- curwin->w_cursor = *trypos;
-- pos = NULL;
-- /* ignore the { if it's in a // or / * * / comment */
-- if ((colnr_T)cin_skip2pos(trypos) == trypos->col
-- && (pos = ind_find_start_CORS(NULL)) == NULL) /* XXX */
-- break;
-- if (pos != NULL)
-- curwin->w_cursor.lnum = pos->lnum;
-- }
-- curwin->w_cursor = cursor_save;
-- return trypos;
-- }
--
-- /*
-- * Find the matching '(', ignoring it if it is in a comment.
-- * Return NULL if no match found.
-- */
-- static pos_T *
-- find_match_paren(int ind_maxparen) /* XXX */
-- {
-- return find_match_char('(', ind_maxparen);
-- }
--
-- static pos_T *
-- find_match_char(int c, int ind_maxparen) /* XXX */
-- {
-- pos_T cursor_save;
-- pos_T *trypos;
-- static pos_T pos_copy;
-- int ind_maxp_wk;
--
-- cursor_save = curwin->w_cursor;
-- ind_maxp_wk = ind_maxparen;
-- retry:
-- if ((trypos = findmatchlimit(NULL, c, 0, ind_maxp_wk)) != NULL)
-- {
-- /* check if the ( is in a // comment */
-- if ((colnr_T)cin_skip2pos(trypos) > trypos->col)
-- {
-- ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum - trypos->lnum);
-- if (ind_maxp_wk > 0)
-- {
-- curwin->w_cursor = *trypos;
-- curwin->w_cursor.col = 0; /* XXX */
-- goto retry;
-- }
-- trypos = NULL;
-- }
-- else
-- {
-- pos_T *trypos_wk;
--
-- pos_copy = *trypos; /* copy trypos, findmatch will change it */
-- trypos = &pos_copy;
-- curwin->w_cursor = *trypos;
-- if ((trypos_wk = ind_find_start_CORS(NULL)) != NULL) /* XXX */
-- {
-- ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum
-- - trypos_wk->lnum);
-- if (ind_maxp_wk > 0)
-- {
-- curwin->w_cursor = *trypos_wk;
-- goto retry;
-- }
-- trypos = NULL;
-- }
-- }
-- }
-- curwin->w_cursor = cursor_save;
-- return trypos;
-- }
--
-- /*
-- * Find the matching '(', ignoring it if it is in a comment or before an
-- * unmatched {.
-- * Return NULL if no match found.
-- */
-- static pos_T *
-- find_match_paren_after_brace (int ind_maxparen) /* XXX */
-- {
-- pos_T *trypos = find_match_paren(ind_maxparen);
--
-- if (trypos != NULL)
-- {
-- pos_T *tryposBrace = find_start_brace();
--
-- /* If both an unmatched '(' and '{' is found. Ignore the '('
-- * position if the '{' is further down. */
-- if (tryposBrace != NULL
-- && (trypos->lnum != tryposBrace->lnum
-- ? trypos->lnum < tryposBrace->lnum
-- : trypos->col < tryposBrace->col))
-- trypos = NULL;
-- }
-- return trypos;
-- }
--
-- /*
-- * Return ind_maxparen corrected for the difference in line number between the
-- * cursor position and "startpos". This makes sure that searching for a
-- * matching paren above the cursor line doesn't find a match because of
-- * looking a few lines further.
-- */
-- static int
-- corr_ind_maxparen(pos_T *startpos)
-- {
-- long n = (long)startpos->lnum - (long)curwin->w_cursor.lnum;
--
-- if (n > 0 && n < curbuf->b_ind_maxparen / 2)
-- return curbuf->b_ind_maxparen - (int)n;
-- return curbuf->b_ind_maxparen;
-- }
--
-- /*
-- * Set w_cursor.col to the column number of the last unmatched ')' or '{' in
-- * line "l". "l" must point to the start of the line.
-- */
-- static int
-- find_last_paren(char_u *l, int start, int end)
-- {
-- int i;
-- int retval = FALSE;
-- int open_count = 0;
--
-- curwin->w_cursor.col = 0; /* default is start of line */
--
-- for (i = 0; l[i] != NUL; i++)
-- {
-- i = (int)(cin_skipcomment(l + i) - l); /* ignore parens in comments */
-- i = (int)(skip_string(l + i) - l); /* ignore parens in quotes */
-- if (l[i] == start)
-- ++open_count;
-- else if (l[i] == end)
-- {
-- if (open_count > 0)
-- --open_count;
-- else
-- {
-- curwin->w_cursor.col = i;
-- retval = TRUE;
-- }
-- }
-- }
-- return retval;
-- }
--
-- /*
-- * Parse 'cinoptions' and set the values in "curbuf".
-- * Must be called when 'cinoptions', 'shiftwidth' and/or 'tabstop' changes.
-- */
-- void
-- parse_cino(buf_T *buf)
-- {
-- char_u *p;
-- char_u *l;
-- char_u *digits;
-- int n;
-- int divider;
-- int fraction = 0;
-- int sw = (int)get_sw_value(buf);
--
-- /*
-- * Set the default values.
-- */
-- /* Spaces from a block's opening brace the prevailing indent for that
-- * block should be. */
-- buf->b_ind_level = sw;
--
-- /* Spaces from the edge of the line an open brace that's at the end of a
-- * line is imagined to be. */
-- buf->b_ind_open_imag = 0;
--
-- /* Spaces from the prevailing indent for a line that is not preceded by
-- * an opening brace. */
-- buf->b_ind_no_brace = 0;
--
-- /* Column where the first { of a function should be located }. */
-- buf->b_ind_first_open = 0;
--
-- /* Spaces from the prevailing indent a leftmost open brace should be
-- * located. */
-- buf->b_ind_open_extra = 0;
--
-- /* Spaces from the matching open brace (real location for one at the left
-- * edge; imaginary location from one that ends a line) the matching close
-- * brace should be located. */
-- buf->b_ind_close_extra = 0;
--
-- /* Spaces from the edge of the line an open brace sitting in the leftmost
-- * column is imagined to be. */
-- buf->b_ind_open_left_imag = 0;
--
-- /* Spaces jump labels should be shifted to the left if N is non-negative,
-- * otherwise the jump label will be put to column 1. */
-- buf->b_ind_jump_label = -1;
--
-- /* Spaces from the switch() indent a "case xx" label should be located. */
-- buf->b_ind_case = sw;
--
-- /* Spaces from the "case xx:" code after a switch() should be located. */
-- buf->b_ind_case_code = sw;
--
-- /* Lineup break at end of case in switch() with case label. */
-- buf->b_ind_case_break = 0;
--
-- /* Spaces from the class declaration indent a scope declaration label
-- * should be located. */
-- buf->b_ind_scopedecl = sw;
--
-- /* Spaces from the scope declaration label code should be located. */
-- buf->b_ind_scopedecl_code = sw;
--
-- /* Amount K&R-style parameters should be indented. */
-- buf->b_ind_param = sw;
--
-- /* Amount a function type spec should be indented. */
-- buf->b_ind_func_type = sw;
--
-- /* Amount a cpp base class declaration or constructor initialization
-- * should be indented. */
-- buf->b_ind_cpp_baseclass = sw;
--
-- /* additional spaces beyond the prevailing indent a continuation line
-- * should be located. */
-- buf->b_ind_continuation = sw;
--
-- /* Spaces from the indent of the line with an unclosed parentheses. */
-- buf->b_ind_unclosed = sw * 2;
--
-- /* Spaces from the indent of the line with an unclosed parentheses, which
-- * itself is also unclosed. */
-- buf->b_ind_unclosed2 = sw;
--
-- /* Suppress ignoring spaces from the indent of a line starting with an
-- * unclosed parentheses. */
-- buf->b_ind_unclosed_noignore = 0;
--
-- /* If the opening paren is the last nonwhite character on the line, and
-- * b_ind_unclosed_wrapped is nonzero, use this indent relative to the outer
-- * context (for very long lines). */
-- buf->b_ind_unclosed_wrapped = 0;
--
-- /* Suppress ignoring white space when lining up with the character after
-- * an unclosed parentheses. */
-- buf->b_ind_unclosed_whiteok = 0;
--
-- /* Indent a closing parentheses under the line start of the matching
-- * opening parentheses. */
-- buf->b_ind_matching_paren = 0;
--
-- /* Indent a closing parentheses under the previous line. */
-- buf->b_ind_paren_prev = 0;
--
-- /* Extra indent for comments. */
-- buf->b_ind_comment = 0;
--
-- /* Spaces from the comment opener when there is nothing after it. */
-- buf->b_ind_in_comment = 3;
--
-- /* Boolean: if non-zero, use b_ind_in_comment even if there is something
-- * after the comment opener. */
-- buf->b_ind_in_comment2 = 0;
--
-- /* Max lines to search for an open paren. */
-- buf->b_ind_maxparen = 20;
--
-- /* Max lines to search for an open comment. */
-- buf->b_ind_maxcomment = 70;
--
-- /* Handle braces for java code. */
-- buf->b_ind_java = 0;
--
-- /* Not to confuse JS object properties with labels. */
-- buf->b_ind_js = 0;
--
-- /* Handle blocked cases correctly. */
-- buf->b_ind_keep_case_label = 0;
--
-- /* Handle C++ namespace. */
-- buf->b_ind_cpp_namespace = 0;
--
-- /* Handle continuation lines containing conditions of if(), for() and
-- * while(). */
-- buf->b_ind_if_for_while = 0;
--
-- /* indentation for # comments */
-- buf->b_ind_hash_comment = 0;
--
-- /* Handle C++ extern "C" or "C++" */
-- buf->b_ind_cpp_extern_c = 0;
--
-- for (p = buf->b_p_cino; *p; )
-- {
-- l = p++;
-- if (*p == '-')
-- ++p;
-- digits = p; /* remember where the digits start */
-- n = getdigits(&p);
-- divider = 0;
-- if (*p == '.') /* ".5s" means a fraction */
-- {
-- fraction = atol((char *)++p);
-- while (VIM_ISDIGIT(*p))
-- {
-- ++p;
-- if (divider)
-- divider *= 10;
-- else
-- divider = 10;
-- }
-- }
-- if (*p == 's') /* "2s" means two times 'shiftwidth' */
-- {
-- if (p == digits)
-- n = sw; /* just "s" is one 'shiftwidth' */
-- else
-- {
-- n *= sw;
-- if (divider)
-- n += (sw * fraction + divider / 2) / divider;
-- }
-- ++p;
-- }
-- if (l[1] == '-')
-- n = -n;
--
-- /* When adding an entry here, also update the default 'cinoptions' in
-- * doc/indent.txt, and add explanation for it! */
-- switch (*l)
-- {
-- case '>': buf->b_ind_level = n; break;
-- case 'e': buf->b_ind_open_imag = n; break;
-- case 'n': buf->b_ind_no_brace = n; break;
-- case 'f': buf->b_ind_first_open = n; break;
-- case '{': buf->b_ind_open_extra = n; break;
-- case '}': buf->b_ind_close_extra = n; break;
-- case '^': buf->b_ind_open_left_imag = n; break;
-- case 'L': buf->b_ind_jump_label = n; break;
-- case ':': buf->b_ind_case = n; break;
-- case '=': buf->b_ind_case_code = n; break;
-- case 'b': buf->b_ind_case_break = n; break;
-- case 'p': buf->b_ind_param = n; break;
-- case 't': buf->b_ind_func_type = n; break;
-- case '/': buf->b_ind_comment = n; break;
-- case 'c': buf->b_ind_in_comment = n; break;
-- case 'C': buf->b_ind_in_comment2 = n; break;
-- case 'i': buf->b_ind_cpp_baseclass = n; break;
-- case '+': buf->b_ind_continuation = n; break;
-- case '(': buf->b_ind_unclosed = n; break;
-- case 'u': buf->b_ind_unclosed2 = n; break;
-- case 'U': buf->b_ind_unclosed_noignore = n; break;
-- case 'W': buf->b_ind_unclosed_wrapped = n; break;
-- case 'w': buf->b_ind_unclosed_whiteok = n; break;
-- case 'm': buf->b_ind_matching_paren = n; break;
-- case 'M': buf->b_ind_paren_prev = n; break;
-- case ')': buf->b_ind_maxparen = n; break;
-- case '*': buf->b_ind_maxcomment = n; break;
-- case 'g': buf->b_ind_scopedecl = n; break;
-- case 'h': buf->b_ind_scopedecl_code = n; break;
-- case 'j': buf->b_ind_java = n; break;
-- case 'J': buf->b_ind_js = n; break;
-- case 'l': buf->b_ind_keep_case_label = n; break;
-- case '#': buf->b_ind_hash_comment = n; break;
-- case 'N': buf->b_ind_cpp_namespace = n; break;
-- case 'k': buf->b_ind_if_for_while = n; break;
-- case 'E': buf->b_ind_cpp_extern_c = n; break;
-- }
-- if (*p == ',')
-- ++p;
-- }
-- }
--
-- /*
-- * Return the desired indent for C code.
-- * Return -1 if the indent should be left alone (inside a raw string).
-- */
-- int
-- get_c_indent(void)
-- {
-- pos_T cur_curpos;
-- int amount;
-- int scope_amount;
-- int cur_amount = MAXCOL;
-- colnr_T col;
-- char_u *theline;
-- char_u *linecopy;
-- pos_T *trypos;
-- pos_T *comment_pos;
-- pos_T *tryposBrace = NULL;
-- pos_T tryposCopy;
-- pos_T our_paren_pos;
-- char_u *start;
-- int start_brace;
-- #define BRACE_IN_COL0 1 /* '{' is in column 0 */
-- #define BRACE_AT_START 2 /* '{' is at start of line */
-- #define BRACE_AT_END 3 /* '{' is at end of line */
-- linenr_T ourscope;
-- char_u *l;
-- char_u *look;
-- char_u terminated;
-- int lookfor;
-- #define LOOKFOR_INITIAL 0
-- #define LOOKFOR_IF 1
-- #define LOOKFOR_DO 2
-- #define LOOKFOR_CASE 3
-- #define LOOKFOR_ANY 4
-- #define LOOKFOR_TERM 5
-- #define LOOKFOR_UNTERM 6
-- #define LOOKFOR_SCOPEDECL 7
-- #define LOOKFOR_NOBREAK 8
-- #define LOOKFOR_CPP_BASECLASS 9
-- #define LOOKFOR_ENUM_OR_INIT 10
-- #define LOOKFOR_JS_KEY 11
-- #define LOOKFOR_COMMA 12
--
-- int whilelevel;
-- linenr_T lnum;
-- int n;
-- int iscase;
-- int lookfor_break;
-- int lookfor_cpp_namespace = FALSE;
-- int cont_amount = 0; /* amount for continuation line */
-- int original_line_islabel;
-- int added_to_amount = 0;
-- int js_cur_has_key = 0;
-- linenr_T raw_string_start = 0;
-- cpp_baseclass_cache_T cache_cpp_baseclass = { FALSE, { MAXLNUM, 0 } };
--
-- /* make a copy, value is changed below */
-- int ind_continuation = curbuf->b_ind_continuation;
--
-- /* remember where the cursor was when we started */
-- cur_curpos = curwin->w_cursor;
--
-- /* if we are at line 1 zero indent is fine, right? */
-- if (cur_curpos.lnum == 1)
-- return 0;
--
-- /* Get a copy of the current contents of the line.
-- * This is required, because only the most recent line obtained with
-- * ml_get is valid! */
-- linecopy = vim_strsave(ml_get(cur_curpos.lnum));
-- if (linecopy == NULL)
-- return 0;
--
-- /*
-- * In insert mode and the cursor is on a ')' truncate the line at the
-- * cursor position. We don't want to line up with the matching '(' when
-- * inserting new stuff.
-- * For unknown reasons the cursor might be past the end of the line, thus
-- * check for that.
-- */
-- if ((State & INSERT)
-- && curwin->w_cursor.col < (colnr_T)STRLEN(linecopy)
-- && linecopy[curwin->w_cursor.col] == ')')
-- linecopy[curwin->w_cursor.col] = NUL;
--
-- theline = skipwhite(linecopy);
--
-- /* move the cursor to the start of the line */
--
-- curwin->w_cursor.col = 0;
--
-- original_line_islabel = cin_islabel(); /* XXX */
--
-- /*
-- * If we are inside a raw string don't change the indent.
-- * Ignore a raw string inside a comment.
-- */
-- comment_pos = ind_find_start_comment();
-- if (comment_pos != NULL)
-- {
-- /* findmatchlimit() static pos is overwritten, make a copy */
-- tryposCopy = *comment_pos;
-- comment_pos = &tryposCopy;
-- }
-- trypos = find_start_rawstring(curbuf->b_ind_maxcomment);
-- if (trypos != NULL && (comment_pos == NULL
-- || LT_POS(*trypos, *comment_pos)))
-- {
-- amount = -1;
-- goto laterend;
-- }
--
-- /*
-- * #defines and so on always go at the left when included in 'cinkeys'.
-- */
-- if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE)))
-- {
-- amount = curbuf->b_ind_hash_comment;
-- goto theend;
-- }
--
-- /*
-- * Is it a non-case label? Then that goes at the left margin too unless:
-- * - JS flag is set.
-- * - 'L' item has a positive value.
-- */
-- if (original_line_islabel && !curbuf->b_ind_js
-- && curbuf->b_ind_jump_label < 0)
-- {
-- amount = 0;
-- goto theend;
-- }
--
-- /*
-- * If we're inside a "//" comment and there is a "//" comment in a
-- * previous line, lineup with that one.
-- */
-- if (cin_islinecomment(theline)
-- && (trypos = find_line_comment()) != NULL) /* XXX */
-- {
-- /* find how indented the line beginning the comment is */
-- getvcol(curwin, trypos, &col, NULL, NULL);
-- amount = col;
-- goto theend;
-- }
--
-- /*
-- * If we're inside a comment and not looking at the start of the
-- * comment, try using the 'comments' option.
-- */
-- if (!cin_iscomment(theline) && comment_pos != NULL) /* XXX */
-- {
-- int lead_start_len = 2;
-- int lead_middle_len = 1;
-- char_u lead_start[COM_MAX_LEN]; /* start-comment string */
-- char_u lead_middle[COM_MAX_LEN]; /* middle-comment string */
-- char_u lead_end[COM_MAX_LEN]; /* end-comment string */
-- char_u *p;
-- int start_align = 0;
-- int start_off = 0;
-- int done = FALSE;
--
-- /* find how indented the line beginning the comment is */
-- getvcol(curwin, comment_pos, &col, NULL, NULL);
-- amount = col;
-- *lead_start = NUL;
-- *lead_middle = NUL;
--
-- p = curbuf->b_p_com;
-- while (*p != NUL)
-- {
-- int align = 0;
-- int off = 0;
-- int what = 0;
--
-- while (*p != NUL && *p != ':')
-- {
-- if (*p == COM_START || *p == COM_END || *p == COM_MIDDLE)
-- what = *p++;
-- else if (*p == COM_LEFT || *p == COM_RIGHT)
-- align = *p++;
-- else if (VIM_ISDIGIT(*p) || *p == '-')
-- off = getdigits(&p);
-- else
-- ++p;
-- }
--
-- if (*p == ':')
-- ++p;
-- (void)copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
-- if (what == COM_START)
-- {
-- STRCPY(lead_start, lead_end);
-- lead_start_len = (int)STRLEN(lead_start);
-- start_off = off;
-- start_align = align;
-- }
-- else if (what == COM_MIDDLE)
-- {
-- STRCPY(lead_middle, lead_end);
-- lead_middle_len = (int)STRLEN(lead_middle);
-- }
-- else if (what == COM_END)
-- {
-- /* If our line starts with the middle comment string, line it
-- * up with the comment opener per the 'comments' option. */
-- if (STRNCMP(theline, lead_middle, lead_middle_len) == 0
-- && STRNCMP(theline, lead_end, STRLEN(lead_end)) != 0)
-- {
-- done = TRUE;
-- if (curwin->w_cursor.lnum > 1)
-- {
-- /* If the start comment string matches in the previous
-- * line, use the indent of that line plus offset. If
-- * the middle comment string matches in the previous
-- * line, use the indent of that line. XXX */
-- look = skipwhite(ml_get(curwin->w_cursor.lnum - 1));
-- if (STRNCMP(look, lead_start, lead_start_len) == 0)
-- amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
-- else if (STRNCMP(look, lead_middle,
-- lead_middle_len) == 0)
-- {
-- amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
-- break;
-- }
-- /* If the start comment string doesn't match with the
-- * start of the comment, skip this entry. XXX */
-- else if (STRNCMP(ml_get(comment_pos->lnum) + comment_pos->col,
-- lead_start, lead_start_len) != 0)
-- continue;
-- }
-- if (start_off != 0)
-- amount += start_off;
-- else if (start_align == COM_RIGHT)
-- amount += vim_strsize(lead_start)
-- - vim_strsize(lead_middle);
-- break;
-- }
--
-- /* If our line starts with the end comment string, line it up
-- * with the middle comment */
-- if (STRNCMP(theline, lead_middle, lead_middle_len) != 0
-- && STRNCMP(theline, lead_end, STRLEN(lead_end)) == 0)
-- {
-- amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
-- /* XXX */
-- if (off != 0)
-- amount += off;
-- else if (align == COM_RIGHT)
-- amount += vim_strsize(lead_start)
-- - vim_strsize(lead_middle);
-- done = TRUE;
-- break;
-- }
-- }
-- }
--
-- /* If our line starts with an asterisk, line up with the
-- * asterisk in the comment opener; otherwise, line up
-- * with the first character of the comment text.
-- */
-- if (done)
-- ;
-- else if (theline[0] == '*')
-- amount += 1;
-- else
-- {
-- /*
-- * If we are more than one line away from the comment opener, take
-- * the indent of the previous non-empty line. If 'cino' has "CO"
-- * and we are just below the comment opener and there are any
-- * white characters after it line up with the text after it;
-- * otherwise, add the amount specified by "c" in 'cino'
-- */
-- amount = -1;
-- for (lnum = cur_curpos.lnum - 1; lnum > comment_pos->lnum; --lnum)
-- {
-- if (linewhite(lnum)) /* skip blank lines */
-- continue;
-- amount = get_indent_lnum(lnum); /* XXX */
-- break;
-- }
-- if (amount == -1) /* use the comment opener */
-- {
-- if (!curbuf->b_ind_in_comment2)
-- {
-- start = ml_get(comment_pos->lnum);
-- look = start + comment_pos->col + 2; /* skip / and * */
-- if (*look != NUL) /* if something after it */
-- comment_pos->col = (colnr_T)(skipwhite(look) - start);
-- }
-- getvcol(curwin, comment_pos, &col, NULL, NULL);
-- amount = col;
-- if (curbuf->b_ind_in_comment2 || *look == NUL)
-- amount += curbuf->b_ind_in_comment;
-- }
-- }
-- goto theend;
-- }
--
-- /*
-- * Are we looking at a ']' that has a match?
-- */
-- if (*skipwhite(theline) == ']'
-- && (trypos = find_match_char('[', curbuf->b_ind_maxparen)) != NULL)
-- {
-- /* align with the line containing the '['. */
-- amount = get_indent_lnum(trypos->lnum);
-- goto theend;
-- }
--
-- /*
-- * Are we inside parentheses or braces?
-- */ /* XXX */
-- if (((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL
-- && curbuf->b_ind_java == 0)
-- || (tryposBrace = find_start_brace()) != NULL
-- || trypos != NULL)
-- {
-- if (trypos != NULL && tryposBrace != NULL)
-- {
-- /* Both an unmatched '(' and '{' is found. Use the one which is
-- * closer to the current cursor position, set the other to NULL. */
-- if (trypos->lnum != tryposBrace->lnum
-- ? trypos->lnum < tryposBrace->lnum
-- : trypos->col < tryposBrace->col)
-- trypos = NULL;
-- else
-- tryposBrace = NULL;
-- }
--
-- if (trypos != NULL)
-- {
-- /*
-- * If the matching paren is more than one line away, use the indent of
-- * a previous non-empty line that matches the same paren.
-- */
-- if (theline[0] == ')' && curbuf->b_ind_paren_prev)
-- {
-- /* Line up with the start of the matching paren line. */
-- amount = get_indent_lnum(curwin->w_cursor.lnum - 1); /* XXX */
-- }
-- else
-- {
-- amount = -1;
-- our_paren_pos = *trypos;
-- for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum)
-- {
-- l = skipwhite(ml_get(lnum));
-- if (cin_nocode(l)) /* skip comment lines */
-- continue;
-- if (cin_ispreproc_cont(&l, &lnum, &amount))
-- continue; /* ignore #define, #if, etc. */
-- curwin->w_cursor.lnum = lnum;
--
-- /* Skip a comment or raw string. XXX */
-- if ((trypos = ind_find_start_CORS(NULL)) != NULL)
-- {
-- lnum = trypos->lnum + 1;
-- continue;
-- }
--
-- /* XXX */
-- if ((trypos = find_match_paren(
-- corr_ind_maxparen(&cur_curpos))) != NULL
-- && trypos->lnum == our_paren_pos.lnum
-- && trypos->col == our_paren_pos.col)
-- {
-- amount = get_indent_lnum(lnum); /* XXX */
--
-- if (theline[0] == ')')
-- {
-- if (our_paren_pos.lnum != lnum
-- && cur_amount > amount)
-- cur_amount = amount;
-- amount = -1;
-- }
-- break;
-- }
-- }
-- }
--
-- /*
-- * Line up with line where the matching paren is. XXX
-- * If the line starts with a '(' or the indent for unclosed
-- * parentheses is zero, line up with the unclosed parentheses.
-- */
-- if (amount == -1)
-- {
-- int ignore_paren_col = 0;
-- int is_if_for_while = 0;
--
-- if (curbuf->b_ind_if_for_while)
-- {
-- /* Look for the outermost opening parenthesis on this line
-- * and check whether it belongs to an "if", "for" or "while". */
--
-- pos_T cursor_save = curwin->w_cursor;
-- pos_T outermost;
-- char_u *line;
--
-- trypos = &our_paren_pos;
-- do {
-- outermost = *trypos;
-- curwin->w_cursor.lnum = outermost.lnum;
-- curwin->w_cursor.col = outermost.col;
--
-- trypos = find_match_paren(curbuf->b_ind_maxparen);
-- } while (trypos && trypos->lnum == outermost.lnum);
--
-- curwin->w_cursor = cursor_save;
--
-- line = ml_get(outermost.lnum);
--
-- is_if_for_while =
-- cin_is_if_for_while_before_offset(line, &outermost.col);
-- }
--
-- amount = skip_label(our_paren_pos.lnum, &look);
-- look = skipwhite(look);
-- if (*look == '(')
-- {
-- linenr_T save_lnum = curwin->w_cursor.lnum;
-- char_u *line;
-- int look_col;
--
-- /* Ignore a '(' in front of the line that has a match before
-- * our matching '('. */
-- curwin->w_cursor.lnum = our_paren_pos.lnum;
-- line = ml_get_curline();
-- look_col = (int)(look - line);
-- curwin->w_cursor.col = look_col + 1;
-- if ((trypos = findmatchlimit(NULL, ')', 0,
-- curbuf->b_ind_maxparen))
-- != NULL
-- && trypos->lnum == our_paren_pos.lnum
-- && trypos->col < our_paren_pos.col)
-- ignore_paren_col = trypos->col + 1;
--
-- curwin->w_cursor.lnum = save_lnum;
-- look = ml_get(our_paren_pos.lnum) + look_col;
-- }
-- if (theline[0] == ')' || (curbuf->b_ind_unclosed == 0
-- && is_if_for_while == 0)
-- || (!curbuf->b_ind_unclosed_noignore && *look == '('
-- && ignore_paren_col == 0))
-- {
-- /*
-- * If we're looking at a close paren, line up right there;
-- * otherwise, line up with the next (non-white) character.
-- * When b_ind_unclosed_wrapped is set and the matching paren is
-- * the last nonwhite character of the line, use either the
-- * indent of the current line or the indentation of the next
-- * outer paren and add b_ind_unclosed_wrapped (for very long
-- * lines).
-- */
-- if (theline[0] != ')')
-- {
-- cur_amount = MAXCOL;
-- l = ml_get(our_paren_pos.lnum);
-- if (curbuf->b_ind_unclosed_wrapped
-- && cin_ends_in(l, (char_u *)"(", NULL))
-- {
-- /* look for opening unmatched paren, indent one level
-- * for each additional level */
-- n = 1;
-- for (col = 0; col < our_paren_pos.col; ++col)
-- {
-- switch (l[col])
-- {
-- case '(':
-- case '{': ++n;
-- break;
--
-- case ')':
-- case '}': if (n > 1)
-- --n;
-- break;
-- }
-- }
--
-- our_paren_pos.col = 0;
-- amount += n * curbuf->b_ind_unclosed_wrapped;
-- }
-- else if (curbuf->b_ind_unclosed_whiteok)
-- our_paren_pos.col++;
-- else
-- {
-- col = our_paren_pos.col + 1;
-- while (VIM_ISWHITE(l[col]))
-- col++;
-- if (l[col] != NUL) /* In case of trailing space */
-- our_paren_pos.col = col;
-- else
-- our_paren_pos.col++;
-- }
-- }
--
-- /*
-- * Find how indented the paren is, or the character after it
-- * if we did the above "if".
-- */
-- if (our_paren_pos.col > 0)
-- {
-- getvcol(curwin, &our_paren_pos, &col, NULL, NULL);
-- if (cur_amount > (int)col)
-- cur_amount = col;
-- }
-- }
--
-- if (theline[0] == ')' && curbuf->b_ind_matching_paren)
-- {
-- /* Line up with the start of the matching paren line. */
-- }
-- else if ((curbuf->b_ind_unclosed == 0 && is_if_for_while == 0)
-- || (!curbuf->b_ind_unclosed_noignore
-- && *look == '(' && ignore_paren_col == 0))
-- {
-- if (cur_amount != MAXCOL)
-- amount = cur_amount;
-- }
-- else
-- {
-- /* Add b_ind_unclosed2 for each '(' before our matching one,
-- * but ignore (void) before the line (ignore_paren_col). */
-- col = our_paren_pos.col;
-- while ((int)our_paren_pos.col > ignore_paren_col)
-- {
-- --our_paren_pos.col;
-- switch (*ml_get_pos(&our_paren_pos))
-- {
-- case '(': amount += curbuf->b_ind_unclosed2;
-- col = our_paren_pos.col;
-- break;
-- case ')': amount -= curbuf->b_ind_unclosed2;
-- col = MAXCOL;
-- break;
-- }
-- }
--
-- /* Use b_ind_unclosed once, when the first '(' is not inside
-- * braces */
-- if (col == MAXCOL)
-- amount += curbuf->b_ind_unclosed;
-- else
-- {
-- curwin->w_cursor.lnum = our_paren_pos.lnum;
-- curwin->w_cursor.col = col;
-- if (find_match_paren_after_brace(curbuf->b_ind_maxparen)
-- != NULL)
-- amount += curbuf->b_ind_unclosed2;
-- else
-- {
-- if (is_if_for_while)
-- amount += curbuf->b_ind_if_for_while;
-- else
-- amount += curbuf->b_ind_unclosed;
-- }
-- }
-- /*
-- * For a line starting with ')' use the minimum of the two
-- * positions, to avoid giving it more indent than the previous
-- * lines:
-- * func_long_name( if (x
-- * arg && yy
-- * ) ^ not here ) ^ not here
-- */
-- if (cur_amount < amount)
-- amount = cur_amount;
-- }
-- }
--
-- /* add extra indent for a comment */
-- if (cin_iscomment(theline))
-- amount += curbuf->b_ind_comment;
-- }
-- else
-- {
-- /*
-- * We are inside braces, there is a { before this line at the position
-- * stored in tryposBrace.
-- * Make a copy of tryposBrace, it may point to pos_copy inside
-- * find_start_brace(), which may be changed somewhere.
-- */
-- tryposCopy = *tryposBrace;
-- tryposBrace = &tryposCopy;
-- trypos = tryposBrace;
-- ourscope = trypos->lnum;
-- start = ml_get(ourscope);
--
-- /*
-- * Now figure out how indented the line is in general.
-- * If the brace was at the start of the line, we use that;
-- * otherwise, check out the indentation of the line as
-- * a whole and then add the "imaginary indent" to that.
-- */
-- look = skipwhite(start);
-- if (*look == '{')
-- {
-- getvcol(curwin, trypos, &col, NULL, NULL);
-- amount = col;
-- if (*start == '{')
-- start_brace = BRACE_IN_COL0;
-- else
-- start_brace = BRACE_AT_START;
-- }
-- else
-- {
-- /* That opening brace might have been on a continuation
-- * line. if so, find the start of the line. */
-- curwin->w_cursor.lnum = ourscope;
--
-- /* Position the cursor over the rightmost paren, so that
-- * matching it will take us back to the start of the line. */
-- lnum = ourscope;
-- if (find_last_paren(start, '(', ')')
-- && (trypos = find_match_paren(curbuf->b_ind_maxparen))
-- != NULL)
-- lnum = trypos->lnum;
--
-- /* It could have been something like
-- * case 1: if (asdf &&
-- * ldfd) {
-- * }
-- */
-- if ((curbuf->b_ind_js || curbuf->b_ind_keep_case_label)
-- && cin_iscase(skipwhite(ml_get_curline()), FALSE))
-- amount = get_indent();
-- else if (curbuf->b_ind_js)
-- amount = get_indent_lnum(lnum);
-- else
-- amount = skip_label(lnum, &l);
--
-- start_brace = BRACE_AT_END;
-- }
--
-- /* For Javascript check if the line starts with "key:". */
-- if (curbuf->b_ind_js)
-- js_cur_has_key = cin_has_js_key(theline);
--
-- /*
-- * If we're looking at a closing brace, that's where
-- * we want to be. otherwise, add the amount of room
-- * that an indent is supposed to be.
-- */
-- if (theline[0] == '}')
-- {
-- /*
-- * they may want closing braces to line up with something
-- * other than the open brace. indulge them, if so.
-- */
-- amount += curbuf->b_ind_close_extra;
-- }
-- else
-- {
-- /*
-- * If we're looking at an "else", try to find an "if"
-- * to match it with.
-- * If we're looking at a "while", try to find a "do"
-- * to match it with.
-- */
-- lookfor = LOOKFOR_INITIAL;
-- if (cin_iselse(theline))
-- lookfor = LOOKFOR_IF;
-- else if (cin_iswhileofdo(theline, cur_curpos.lnum)) /* XXX */
-- lookfor = LOOKFOR_DO;
-- if (lookfor != LOOKFOR_INITIAL)
-- {
-- curwin->w_cursor.lnum = cur_curpos.lnum;
-- if (find_match(lookfor, ourscope) == OK)
-- {
-- amount = get_indent(); /* XXX */
-- goto theend;
-- }
-- }
--
-- /*
-- * We get here if we are not on an "while-of-do" or "else" (or
-- * failed to find a matching "if").
-- * Search backwards for something to line up with.
-- * First set amount for when we don't find anything.
-- */
--
-- /*
-- * if the '{' is _really_ at the left margin, use the imaginary
-- * location of a left-margin brace. Otherwise, correct the
-- * location for b_ind_open_extra.
-- */
--
-- if (start_brace == BRACE_IN_COL0) /* '{' is in column 0 */
-- {
-- amount = curbuf->b_ind_open_left_imag;
-- lookfor_cpp_namespace = TRUE;
-- }
-- else if (start_brace == BRACE_AT_START &&
-- lookfor_cpp_namespace) /* '{' is at start */
-- {
--
-- lookfor_cpp_namespace = TRUE;
-- }
-- else
-- {
-- if (start_brace == BRACE_AT_END) /* '{' is at end of line */
-- {
-- amount += curbuf->b_ind_open_imag;
--
-- l = skipwhite(ml_get_curline());
-- if (cin_is_cpp_namespace(l))
-- amount += curbuf->b_ind_cpp_namespace;
-- else if (cin_is_cpp_extern_c(l))
-- amount += curbuf->b_ind_cpp_extern_c;
-- }
-- else
-- {
-- /* Compensate for adding b_ind_open_extra later. */
-- amount -= curbuf->b_ind_open_extra;
-- if (amount < 0)
-- amount = 0;
-- }
-- }
--
-- lookfor_break = FALSE;
--
-- if (cin_iscase(theline, FALSE)) /* it's a switch() label */
-- {
-- lookfor = LOOKFOR_CASE; /* find a previous switch() label */
-- amount += curbuf->b_ind_case;
-- }
-- else if (cin_isscopedecl(theline)) /* private:, ... */
-- {
-- lookfor = LOOKFOR_SCOPEDECL; /* class decl is this block */
-- amount += curbuf->b_ind_scopedecl;
-- }
-- else
-- {
-- if (curbuf->b_ind_case_break && cin_isbreak(theline))
-- /* break; ... */
-- lookfor_break = TRUE;
--
-- lookfor = LOOKFOR_INITIAL;
-- /* b_ind_level from start of block */
-- amount += curbuf->b_ind_level;
-- }
-- scope_amount = amount;
-- whilelevel = 0;
--
-- /*
-- * Search backwards. If we find something we recognize, line up
-- * with that.
-- *
-- * If we're looking at an open brace, indent
-- * the usual amount relative to the conditional
-- * that opens the block.
-- */
-- curwin->w_cursor = cur_curpos;
-- for (;;)
-- {
-- curwin->w_cursor.lnum--;
-- curwin->w_cursor.col = 0;
--
-- /*
-- * If we went all the way back to the start of our scope, line
-- * up with it.
-- */
-- if (curwin->w_cursor.lnum <= ourscope)
-- {
-- /* We reached end of scope:
-- * If looking for a enum or structure initialization
-- * go further back:
-- * If it is an initializer (enum xxx or xxx =), then
-- * don't add ind_continuation, otherwise it is a variable
-- * declaration:
-- * int x,
-- * here; <-- add ind_continuation
-- */
-- if (lookfor == LOOKFOR_ENUM_OR_INIT)
-- {
-- if (curwin->w_cursor.lnum == 0
-- || curwin->w_cursor.lnum
-- < ourscope - curbuf->b_ind_maxparen)
-- {
-- /* nothing found (abuse curbuf->b_ind_maxparen as
-- * limit) assume terminated line (i.e. a variable
-- * initialization) */
-- if (cont_amount > 0)
-- amount = cont_amount;
-- else if (!curbuf->b_ind_js)
-- amount += ind_continuation;
-- break;
-- }
--
-- l = ml_get_curline();
--
-- /*
-- * If we're in a comment or raw string now, skip to
-- * the start of it.
-- */
-- trypos = ind_find_start_CORS(NULL);
-- if (trypos != NULL)
-- {
-- curwin->w_cursor.lnum = trypos->lnum + 1;
-- curwin->w_cursor.col = 0;
-- continue;
-- }
--
-- /*
-- * Skip preprocessor directives and blank lines.
-- */
-- if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum,
-- &amount))
-- continue;
--
-- if (cin_nocode(l))
-- continue;
--
-- terminated = cin_isterminated(l, FALSE, TRUE);
--
-- /*
-- * If we are at top level and the line looks like a
-- * function declaration, we are done
-- * (it's a variable declaration).
-- */
-- if (start_brace != BRACE_IN_COL0
-- || !cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0))
-- {
-- /* if the line is terminated with another ','
-- * it is a continued variable initialization.
-- * don't add extra indent.
-- * TODO: does not work, if a function
-- * declaration is split over multiple lines:
-- * cin_isfuncdecl returns FALSE then.
-- */
-- if (terminated == ',')
-- break;
--
-- /* if it es a enum declaration or an assignment,
-- * we are done.
-- */
-- if (terminated != ';' && cin_isinit())
-- break;
--
-- /* nothing useful found */
-- if (terminated == 0 || terminated == '{')
-- continue;
-- }
--
-- if (terminated != ';')
-- {
-- /* Skip parens and braces. Position the cursor
-- * over the rightmost paren, so that matching it
-- * will take us back to the start of the line.
-- */ /* XXX */
-- trypos = NULL;
-- if (find_last_paren(l, '(', ')'))
-- trypos = find_match_paren(
-- curbuf->b_ind_maxparen);
--
-- if (trypos == NULL && find_last_paren(l, '{', '}'))
-- trypos = find_start_brace();
--
-- if (trypos != NULL)
-- {
-- curwin->w_cursor.lnum = trypos->lnum + 1;
-- curwin->w_cursor.col = 0;
-- continue;
-- }
-- }
--
-- /* it's a variable declaration, add indentation
-- * like in
-- * int a,
-- * b;
-- */
-- if (cont_amount > 0)
-- amount = cont_amount;
-- else
-- amount += ind_continuation;
-- }
-- else if (lookfor == LOOKFOR_UNTERM)
-- {
-- if (cont_amount > 0)
-- amount = cont_amount;
-- else
-- amount += ind_continuation;
-- }
-- else
-- {
-- if (lookfor != LOOKFOR_TERM
-- && lookfor != LOOKFOR_CPP_BASECLASS
-- && lookfor != LOOKFOR_COMMA)
-- {
-- amount = scope_amount;
-- if (theline[0] == '{')
-- {
-- amount += curbuf->b_ind_open_extra;
-- added_to_amount = curbuf->b_ind_open_extra;
-- }
-- }
--
-- if (lookfor_cpp_namespace)
-- {
-- /*
-- * Looking for C++ namespace, need to look further
-- * back.
-- */
-- if (curwin->w_cursor.lnum == ourscope)
-- continue;
--
-- if (curwin->w_cursor.lnum == 0
-- || curwin->w_cursor.lnum
-- < ourscope - FIND_NAMESPACE_LIM)
-- break;
--
-- l = ml_get_curline();
--
-- /* If we're in a comment or raw string now, skip
-- * to the start of it. */
-- trypos = ind_find_start_CORS(NULL);
-- if (trypos != NULL)
-- {
-- curwin->w_cursor.lnum = trypos->lnum + 1;
-- curwin->w_cursor.col = 0;
-- continue;
-- }
--
-- /* Skip preprocessor directives and blank lines. */
-- if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum,
-- &amount))
-- continue;
--
-- /* Finally the actual check for "namespace". */
-- if (cin_is_cpp_namespace(l))
-- {
-- amount += curbuf->b_ind_cpp_namespace
-- - added_to_amount;
-- break;
-- }
-- else if (cin_is_cpp_extern_c(l))
-- {
-- amount += curbuf->b_ind_cpp_extern_c
-- - added_to_amount;
-- break;
-- }
--
-- if (cin_nocode(l))
-- continue;
-- }
-- }
-- break;
-- }
--
-- /*
-- * If we're in a comment or raw string now, skip to the start
-- * of it.
-- */ /* XXX */
-- if ((trypos = ind_find_start_CORS(&raw_string_start)) != NULL)
-- {
-- curwin->w_cursor.lnum = trypos->lnum + 1;
-- curwin->w_cursor.col = 0;
-- continue;
-- }
--
-- l = ml_get_curline();
--
-- /*
-- * If this is a switch() label, may line up relative to that.
-- * If this is a C++ scope declaration, do the same.
-- */
-- iscase = cin_iscase(l, FALSE);
-- if (iscase || cin_isscopedecl(l))
-- {
-- /* we are only looking for cpp base class
-- * declaration/initialization any longer */
-- if (lookfor == LOOKFOR_CPP_BASECLASS)
-- break;
--
-- /* When looking for a "do" we are not interested in
-- * labels. */
-- if (whilelevel > 0)
-- continue;
--
-- /*
-- * case xx:
-- * c = 99 + <- this indent plus continuation
-- *-> here;
-- */
-- if (lookfor == LOOKFOR_UNTERM
-- || lookfor == LOOKFOR_ENUM_OR_INIT)
-- {
-- if (cont_amount > 0)
-- amount = cont_amount;
-- else
-- amount += ind_continuation;
-- break;
-- }
--
-- /*
-- * case xx: <- line up with this case
-- * x = 333;
-- * case yy:
-- */
-- if ( (iscase && lookfor == LOOKFOR_CASE)
-- || (iscase && lookfor_break)
-- || (!iscase && lookfor == LOOKFOR_SCOPEDECL))
-- {
-- /*
-- * Check that this case label is not for another
-- * switch()
-- */ /* XXX */
-- if ((trypos = find_start_brace()) == NULL
-- || trypos->lnum == ourscope)
-- {
-- amount = get_indent(); /* XXX */
-- break;
-- }
-- continue;
-- }
--
-- n = get_indent_nolabel(curwin->w_cursor.lnum); /* XXX */
--
-- /*
-- * case xx: if (cond) <- line up with this if
-- * y = y + 1;
-- * -> s = 99;
-- *
-- * case xx:
-- * if (cond) <- line up with this line
-- * y = y + 1;
-- * -> s = 99;
-- */
-- if (lookfor == LOOKFOR_TERM)
-- {
-- if (n)
-- amount = n;
--
-- if (!lookfor_break)
-- break;
-- }
--
-- /*
-- * case xx: x = x + 1; <- line up with this x
-- * -> y = y + 1;
-- *
-- * case xx: if (cond) <- line up with this if
-- * -> y = y + 1;
-- */
-- if (n)
-- {
-- amount = n;
-- l = after_label(ml_get_curline());
-- if (l != NULL && cin_is_cinword(l))
-- {
-- if (theline[0] == '{')
-- amount += curbuf->b_ind_open_extra;
-- else
-- amount += curbuf->b_ind_level
-- + curbuf->b_ind_no_brace;
-- }
-- break;
-- }
--
-- /*
-- * Try to get the indent of a statement before the switch
-- * label. If nothing is found, line up relative to the
-- * switch label.
-- * break; <- may line up with this line
-- * case xx:
-- * -> y = 1;
-- */
-- scope_amount = get_indent() + (iscase /* XXX */
-- ? curbuf->b_ind_case_code
-- : curbuf->b_ind_scopedecl_code);
-- lookfor = curbuf->b_ind_case_break
-- ? LOOKFOR_NOBREAK : LOOKFOR_ANY;
-- continue;
-- }
--
-- /*
-- * Looking for a switch() label or C++ scope declaration,
-- * ignore other lines, skip {}-blocks.
-- */
-- if (lookfor == LOOKFOR_CASE || lookfor == LOOKFOR_SCOPEDECL)
-- {
-- if (find_last_paren(l, '{', '}')
-- && (trypos = find_start_brace()) != NULL)
-- {
-- curwin->w_cursor.lnum = trypos->lnum + 1;
-- curwin->w_cursor.col = 0;
-- }
-- continue;
-- }
--
-- /*
-- * Ignore jump labels with nothing after them.
-- */
-- if (!curbuf->b_ind_js && cin_islabel())
-- {
-- l = after_label(ml_get_curline());
-- if (l == NULL || cin_nocode(l))
-- continue;
-- }
--
-- /*
-- * Ignore #defines, #if, etc.
-- * Ignore comment and empty lines.
-- * (need to get the line again, cin_islabel() may have
-- * unlocked it)
-- */
-- l = ml_get_curline();
-- if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)
-- || cin_nocode(l))
-- continue;
--
-- /*
-- * Are we at the start of a cpp base class declaration or
-- * constructor initialization?
-- */ /* XXX */
-- n = FALSE;
-- if (lookfor != LOOKFOR_TERM && curbuf->b_ind_cpp_baseclass > 0)
-- {
-- n = cin_is_cpp_baseclass(&cache_cpp_baseclass);
-- l = ml_get_curline();
-- }
-- if (n)
-- {
-- if (lookfor == LOOKFOR_UNTERM)
-- {
-- if (cont_amount > 0)
-- amount = cont_amount;
-- else
-- amount += ind_continuation;
-- }
-- else if (theline[0] == '{')
-- {
-- /* Need to find start of the declaration. */
-- lookfor = LOOKFOR_UNTERM;
-- ind_continuation = 0;
-- continue;
-- }
-- else
-- /* XXX */
-- amount = get_baseclass_amount(
-- cache_cpp_baseclass.lpos.col);
-- break;
-- }
-- else if (lookfor == LOOKFOR_CPP_BASECLASS)
-- {
-- /* only look, whether there is a cpp base class
-- * declaration or initialization before the opening brace.
-- */
-- if (cin_isterminated(l, TRUE, FALSE))
-- break;
-- else
-- continue;
-- }
--
-- /*
-- * What happens next depends on the line being terminated.
-- * If terminated with a ',' only consider it terminating if
-- * there is another unterminated statement behind, eg:
-- * 123,
-- * sizeof
-- * here
-- * Otherwise check whether it is a enumeration or structure
-- * initialisation (not indented) or a variable declaration
-- * (indented).
-- */
-- terminated = cin_isterminated(l, FALSE, TRUE);
--
-- if (js_cur_has_key)
-- {
-- js_cur_has_key = 0; /* only check the first line */
-- if (curbuf->b_ind_js && terminated == ',')
-- {
-- /* For Javascript we might be inside an object:
-- * key: something, <- align with this
-- * key: something
-- * or:
-- * key: something + <- align with this
-- * something,
-- * key: something
-- */
-- lookfor = LOOKFOR_JS_KEY;
-- }
-- }
-- if (lookfor == LOOKFOR_JS_KEY && cin_has_js_key(l))
-- {
-- amount = get_indent();
-- break;
-- }
-- if (lookfor == LOOKFOR_COMMA)
-- {
-- if (tryposBrace != NULL && tryposBrace->lnum
-- >= curwin->w_cursor.lnum)
-- break;
-- if (terminated == ',')
-- /* line below current line is the one that starts a
-- * (possibly broken) line ending in a comma. */
-- break;
-- else
-- {
-- amount = get_indent();
-- if (curwin->w_cursor.lnum - 1 == ourscope)
-- /* line above is start of the scope, thus current
-- * line is the one that stars a (possibly broken)
-- * line ending in a comma. */
-- break;
-- }
-- }
--
-- if (terminated == 0 || (lookfor != LOOKFOR_UNTERM
-- && terminated == ','))
-- {
-- if (lookfor != LOOKFOR_ENUM_OR_INIT &&
-- (*skipwhite(l) == '[' || l[STRLEN(l) - 1] == '['))
-- amount += ind_continuation;
-- /*
-- * if we're in the middle of a paren thing,
-- * go back to the line that starts it so
-- * we can get the right prevailing indent
-- * if ( foo &&
-- * bar )
-- */
-- /*
-- * Position the cursor over the rightmost paren, so that
-- * matching it will take us back to the start of the line.
-- * Ignore a match before the start of the block.
-- */
-- (void)find_last_paren(l, '(', ')');
-- trypos = find_match_paren(corr_ind_maxparen(&cur_curpos));
-- if (trypos != NULL && (trypos->lnum < tryposBrace->lnum
-- || (trypos->lnum == tryposBrace->lnum
-- && trypos->col < tryposBrace->col)))
-- trypos = NULL;
--
-- /*
-- * If we are looking for ',', we also look for matching
-- * braces.
-- */
-- if (trypos == NULL && terminated == ','
-- && find_last_paren(l, '{', '}'))
-- trypos = find_start_brace();
--
-- if (trypos != NULL)
-- {
-- /*
-- * Check if we are on a case label now. This is
-- * handled above.
-- * case xx: if ( asdf &&
-- * asdf)
-- */
-- curwin->w_cursor = *trypos;
-- l = ml_get_curline();
-- if (cin_iscase(l, FALSE) || cin_isscopedecl(l))
-- {
-- ++curwin->w_cursor.lnum;
-- curwin->w_cursor.col = 0;
-- continue;
-- }
-- }
--
-- /*
-- * Skip over continuation lines to find the one to get the
-- * indent from
-- * char *usethis = "bla\
-- * bla",
-- * here;
-- */
-- if (terminated == ',')
-- {
-- while (curwin->w_cursor.lnum > 1)
-- {
-- l = ml_get(curwin->w_cursor.lnum - 1);
-- if (*l == NUL || l[STRLEN(l) - 1] != '\\')
-- break;
-- --curwin->w_cursor.lnum;
-- curwin->w_cursor.col = 0;
-- }
-- }
--
-- /*
-- * Get indent and pointer to text for current line,
-- * ignoring any jump label. XXX
-- */
-- if (curbuf->b_ind_js)
-- cur_amount = get_indent();
-- else
-- cur_amount = skip_label(curwin->w_cursor.lnum, &l);
-- /*
-- * If this is just above the line we are indenting, and it
-- * starts with a '{', line it up with this line.
-- * while (not)
-- * -> {
-- * }
-- */
-- if (terminated != ',' && lookfor != LOOKFOR_TERM
-- && theline[0] == '{')
-- {
-- amount = cur_amount;
-- /*
-- * Only add b_ind_open_extra when the current line
-- * doesn't start with a '{', which must have a match
-- * in the same line (scope is the same). Probably:
-- * { 1, 2 },
-- * -> { 3, 4 }
-- */
-- if (*skipwhite(l) != '{')
-- amount += curbuf->b_ind_open_extra;
--
-- if (curbuf->b_ind_cpp_baseclass && !curbuf->b_ind_js)
-- {
-- /* have to look back, whether it is a cpp base
-- * class declaration or initialization */
-- lookfor = LOOKFOR_CPP_BASECLASS;
-- continue;
-- }
-- break;
-- }
--
-- /*
-- * Check if we are after an "if", "while", etc.
-- * Also allow " } else".
-- */
-- if (cin_is_cinword(l) || cin_iselse(skipwhite(l)))
-- {
-- /*
-- * Found an unterminated line after an if (), line up
-- * with the last one.
-- * if (cond)
-- * 100 +
-- * -> here;
-- */
-- if (lookfor == LOOKFOR_UNTERM
-- || lookfor == LOOKFOR_ENUM_OR_INIT)
-- {
-- if (cont_amount > 0)
-- amount = cont_amount;
-- else
-- amount += ind_continuation;
-- break;
-- }
--
-- /*
-- * If this is just above the line we are indenting, we
-- * are finished.
-- * while (not)
-- * -> here;
-- * Otherwise this indent can be used when the line
-- * before this is terminated.
-- * yyy;
-- * if (stat)
-- * while (not)
-- * xxx;
-- * -> here;
-- */
-- amount = cur_amount;
-- if (theline[0] == '{')
-- amount += curbuf->b_ind_open_extra;
-- if (lookfor != LOOKFOR_TERM)
-- {
-- amount += curbuf->b_ind_level
-- + curbuf->b_ind_no_brace;
-- break;
-- }
--
-- /*
-- * Special trick: when expecting the while () after a
-- * do, line up with the while()
-- * do
-- * x = 1;
-- * -> here
-- */
-- l = skipwhite(ml_get_curline());
-- if (cin_isdo(l))
-- {
-- if (whilelevel == 0)
-- break;
-- --whilelevel;
-- }
--
-- /*
-- * When searching for a terminated line, don't use the
-- * one between the "if" and the matching "else".
-- * Need to use the scope of this "else". XXX
-- * If whilelevel != 0 continue looking for a "do {".
-- */
-- if (cin_iselse(l) && whilelevel == 0)
-- {
-- /* If we're looking at "} else", let's make sure we
-- * find the opening brace of the enclosing scope,
-- * not the one from "if () {". */
-- if (*l == '}')
-- curwin->w_cursor.col =
-- (colnr_T)(l - ml_get_curline()) + 1;
--
-- if ((trypos = find_start_brace()) == NULL
-- || find_match(LOOKFOR_IF, trypos->lnum)
-- == FAIL)
-- break;
-- }
-- }
--
-- /*
-- * If we're below an unterminated line that is not an
-- * "if" or something, we may line up with this line or
-- * add something for a continuation line, depending on
-- * the line before this one.
-- */
-- else
-- {
-- /*
-- * Found two unterminated lines on a row, line up with
-- * the last one.
-- * c = 99 +
-- * 100 +
-- * -> here;
-- */
-- if (lookfor == LOOKFOR_UNTERM)
-- {
-- /* When line ends in a comma add extra indent */
-- if (terminated == ',')
-- amount += ind_continuation;
-- break;
-- }
--
-- if (lookfor == LOOKFOR_ENUM_OR_INIT)
-- {
-- /* Found two lines ending in ',', lineup with the
-- * lowest one, but check for cpp base class
-- * declaration/initialization, if it is an
-- * opening brace or we are looking just for
-- * enumerations/initializations. */
-- if (terminated == ',')
-- {
-- if (curbuf->b_ind_cpp_baseclass == 0)
-- break;
--
-- lookfor = LOOKFOR_CPP_BASECLASS;
-- continue;
-- }
--
-- /* Ignore unterminated lines in between, but
-- * reduce indent. */
-- if (amount > cur_amount)
-- amount = cur_amount;
-- }
-- else
-- {
-- /*
-- * Found first unterminated line on a row, may
-- * line up with this line, remember its indent
-- * 100 +
-- * -> here;
-- */
-- l = ml_get_curline();
-- amount = cur_amount;
--
-- n = (int)STRLEN(l);
-- if (terminated == ',' && (*skipwhite(l) == ']'
-- || (n >=2 && l[n - 2] == ']')))
-- break;
--
-- /*
-- * If previous line ends in ',', check whether we
-- * are in an initialization or enum
-- * struct xxx =
-- * {
-- * sizeof a,
-- * 124 };
-- * or a normal possible continuation line.
-- * but only, of no other statement has been found
-- * yet.
-- */
-- if (lookfor == LOOKFOR_INITIAL && terminated == ',')
-- {
-- if (curbuf->b_ind_js)
-- {
-- /* Search for a line ending in a comma
-- * and line up with the line below it
-- * (could be the current line).
-- * some = [
-- * 1, <- line up here
-- * 2,
-- * some = [
-- * 3 + <- line up here
-- * 4 *
-- * 5,
-- * 6,
-- */
-- if (cin_iscomment(skipwhite(l)))
-- break;
-- lookfor = LOOKFOR_COMMA;
-- trypos = find_match_char('[',
-- curbuf->b_ind_maxparen);
-- if (trypos != NULL)
-- {
-- if (trypos->lnum
-- == curwin->w_cursor.lnum - 1)
-- {
-- /* Current line is first inside
-- * [], line up with it. */
-- break;
-- }
-- ourscope = trypos->lnum;
-- }
-- }
-- else
-- {
-- lookfor = LOOKFOR_ENUM_OR_INIT;
-- cont_amount = cin_first_id_amount();
-- }
-- }
-- else
-- {
-- if (lookfor == LOOKFOR_INITIAL
-- && *l != NUL
-- && l[STRLEN(l) - 1] == '\\')
-- /* XXX */
-- cont_amount = cin_get_equal_amount(
-- curwin->w_cursor.lnum);
-- if (lookfor != LOOKFOR_TERM
-- && lookfor != LOOKFOR_JS_KEY
-- && lookfor != LOOKFOR_COMMA
-- && raw_string_start != curwin->w_cursor.lnum)
-- lookfor = LOOKFOR_UNTERM;
-- }
-- }
-- }
-- }
--
-- /*
-- * Check if we are after a while (cond);
-- * If so: Ignore until the matching "do".
-- */
-- else if (cin_iswhileofdo_end(terminated)) /* XXX */
-- {
-- /*
-- * Found an unterminated line after a while ();, line up
-- * with the last one.
-- * while (cond);
-- * 100 + <- line up with this one
-- * -> here;
-- */
-- if (lookfor == LOOKFOR_UNTERM
-- || lookfor == LOOKFOR_ENUM_OR_INIT)
-- {
-- if (cont_amount > 0)
-- amount = cont_amount;
-- else
-- amount += ind_continuation;
-- break;
-- }
--
-- if (whilelevel == 0)
-- {
-- lookfor = LOOKFOR_TERM;
-- amount = get_indent(); /* XXX */
-- if (theline[0] == '{')
-- amount += curbuf->b_ind_open_extra;
-- }
-- ++whilelevel;
-- }
--
-- /*
-- * We are after a "normal" statement.
-- * If we had another statement we can stop now and use the
-- * indent of that other statement.
-- * Otherwise the indent of the current statement may be used,
-- * search backwards for the next "normal" statement.
-- */
-- else
-- {
-- /*
-- * Skip single break line, if before a switch label. It
-- * may be lined up with the case label.
-- */
-- if (lookfor == LOOKFOR_NOBREAK
-- && cin_isbreak(skipwhite(ml_get_curline())))
-- {
-- lookfor = LOOKFOR_ANY;
-- continue;
-- }
--
-- /*
-- * Handle "do {" line.
-- */
-- if (whilelevel > 0)
-- {
-- l = cin_skipcomment(ml_get_curline());
-- if (cin_isdo(l))
-- {
-- amount = get_indent(); /* XXX */
-- --whilelevel;
-- continue;
-- }
-- }
--
-- /*
-- * Found a terminated line above an unterminated line. Add
-- * the amount for a continuation line.
-- * x = 1;
-- * y = foo +
-- * -> here;
-- * or
-- * int x = 1;
-- * int foo,
-- * -> here;
-- */
-- if (lookfor == LOOKFOR_UNTERM
-- || lookfor == LOOKFOR_ENUM_OR_INIT)
-- {
-- if (cont_amount > 0)
-- amount = cont_amount;
-- else
-- amount += ind_continuation;
-- break;
-- }
--
-- /*
-- * Found a terminated line above a terminated line or "if"
-- * etc. line. Use the amount of the line below us.
-- * x = 1; x = 1;
-- * if (asdf) y = 2;
-- * while (asdf) ->here;
-- * here;
-- * ->foo;
-- */
-- if (lookfor == LOOKFOR_TERM)
-- {
-- if (!lookfor_break && whilelevel == 0)
-- break;
-- }
--
-- /*
-- * First line above the one we're indenting is terminated.
-- * To know what needs to be done look further backward for
-- * a terminated line.
-- */
-- else
-- {
-- /*
-- * position the cursor over the rightmost paren, so
-- * that matching it will take us back to the start of
-- * the line. Helps for:
-- * func(asdr,
-- * asdfasdf);
-- * here;
-- */
-- term_again:
-- l = ml_get_curline();
-- if (find_last_paren(l, '(', ')')
-- && (trypos = find_match_paren(
-- curbuf->b_ind_maxparen)) != NULL)
-- {
-- /*
-- * Check if we are on a case label now. This is
-- * handled above.
-- * case xx: if ( asdf &&
-- * asdf)
-- */
-- curwin->w_cursor = *trypos;
-- l = ml_get_curline();
-- if (cin_iscase(l, FALSE) || cin_isscopedecl(l))
-- {
-- ++curwin->w_cursor.lnum;
-- curwin->w_cursor.col = 0;
-- continue;
-- }
-- }
--
-- /* When aligning with the case statement, don't align
-- * with a statement after it.
-- * case 1: { <-- don't use this { position
-- * stat;
-- * }
-- * case 2:
-- * stat;
-- * }
-- */
-- iscase = (curbuf->b_ind_keep_case_label
-- && cin_iscase(l, FALSE));
--
-- /*
-- * Get indent and pointer to text for current line,
-- * ignoring any jump label.
-- */
-- amount = skip_label(curwin->w_cursor.lnum, &l);
--
-- if (theline[0] == '{')
-- amount += curbuf->b_ind_open_extra;
-- /* See remark above: "Only add b_ind_open_extra.." */
-- l = skipwhite(l);
-- if (*l == '{')
-- amount -= curbuf->b_ind_open_extra;
-- lookfor = iscase ? LOOKFOR_ANY : LOOKFOR_TERM;
--
-- /*
-- * When a terminated line starts with "else" skip to
-- * the matching "if":
-- * else 3;
-- * indent this;
-- * Need to use the scope of this "else". XXX
-- * If whilelevel != 0 continue looking for a "do {".
-- */
-- if (lookfor == LOOKFOR_TERM
-- && *l != '}'
-- && cin_iselse(l)
-- && whilelevel == 0)
-- {
-- if ((trypos = find_start_brace()) == NULL
-- || find_match(LOOKFOR_IF, trypos->lnum)
-- == FAIL)
-- break;
-- continue;
-- }
--
-- /*
-- * If we're at the end of a block, skip to the start of
-- * that block.
-- */
-- l = ml_get_curline();
-- if (find_last_paren(l, '{', '}') /* XXX */
-- && (trypos = find_start_brace()) != NULL)
-- {
-- curwin->w_cursor = *trypos;
-- /* if not "else {" check for terminated again */
-- /* but skip block for "} else {" */
-- l = cin_skipcomment(ml_get_curline());
-- if (*l == '}' || !cin_iselse(l))
-- goto term_again;
-- ++curwin->w_cursor.lnum;
-- curwin->w_cursor.col = 0;
-- }
-- }
-- }
-- }
-- }
-- }
--
-- /* add extra indent for a comment */
-- if (cin_iscomment(theline))
-- amount += curbuf->b_ind_comment;
--
-- /* subtract extra left-shift for jump labels */
-- if (curbuf->b_ind_jump_label > 0 && original_line_islabel)
-- amount -= curbuf->b_ind_jump_label;
--
-- goto theend;
-- }
--
-- /*
-- * ok -- we're not inside any sort of structure at all!
-- *
-- * This means we're at the top level, and everything should
-- * basically just match where the previous line is, except
-- * for the lines immediately following a function declaration,
-- * which are K&R-style parameters and need to be indented.
-- *
-- * if our line starts with an open brace, forget about any
-- * prevailing indent and make sure it looks like the start
-- * of a function
-- */
--
-- if (theline[0] == '{')
-- {
-- amount = curbuf->b_ind_first_open;
-- goto theend;
-- }
--
-- /*
-- * If the NEXT line is a function declaration, the current
-- * line needs to be indented as a function type spec.
-- * Don't do this if the current line looks like a comment or if the
-- * current line is terminated, ie. ends in ';', or if the current line
-- * contains { or }: "void f() {\n if (1)"
-- */
-- if (cur_curpos.lnum < curbuf->b_ml.ml_line_count
-- && !cin_nocode(theline)
-- && vim_strchr(theline, '{') == NULL
-- && vim_strchr(theline, '}') == NULL
-- && !cin_ends_in(theline, (char_u *)":", NULL)
-- && !cin_ends_in(theline, (char_u *)",", NULL)
-- && cin_isfuncdecl(NULL, cur_curpos.lnum + 1,
-- cur_curpos.lnum + 1)
-- && !cin_isterminated(theline, FALSE, TRUE))
-- {
-- amount = curbuf->b_ind_func_type;
-- goto theend;
-- }
--
-- /* search backwards until we find something we recognize */
-- amount = 0;
-- curwin->w_cursor = cur_curpos;
-- while (curwin->w_cursor.lnum > 1)
-- {
-- curwin->w_cursor.lnum--;
-- curwin->w_cursor.col = 0;
--
-- l = ml_get_curline();
--
-- /*
-- * If we're in a comment or raw string now, skip to the start
-- * of it.
-- */ /* XXX */
-- if ((trypos = ind_find_start_CORS(NULL)) != NULL)
-- {
-- curwin->w_cursor.lnum = trypos->lnum + 1;
-- curwin->w_cursor.col = 0;
-- continue;
-- }
--
-- /*
-- * Are we at the start of a cpp base class declaration or
-- * constructor initialization?
-- */ /* XXX */
-- n = FALSE;
-- if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{')
-- {
-- n = cin_is_cpp_baseclass(&cache_cpp_baseclass);
-- l = ml_get_curline();
-- }
-- if (n)
-- {
-- /* XXX */
-- amount = get_baseclass_amount(cache_cpp_baseclass.lpos.col);
-- break;
-- }
--
-- /*
-- * Skip preprocessor directives and blank lines.
-- */
-- if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount))
-- continue;
--
-- if (cin_nocode(l))
-- continue;
--
-- /*
-- * If the previous line ends in ',', use one level of
-- * indentation:
-- * int foo,
-- * bar;
-- * do this before checking for '}' in case of eg.
-- * enum foobar
-- * {
-- * ...
-- * } foo,
-- * bar;
-- */
-- n = 0;
-- if (cin_ends_in(l, (char_u *)",", NULL)
-- || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\'))
-- {
-- /* take us back to opening paren */
-- if (find_last_paren(l, '(', ')')
-- && (trypos = find_match_paren(
-- curbuf->b_ind_maxparen)) != NULL)
-- curwin->w_cursor = *trypos;
--
-- /* For a line ending in ',' that is a continuation line go
-- * back to the first line with a backslash:
-- * char *foo = "bla\
-- * bla",
-- * here;
-- */
-- while (n == 0 && curwin->w_cursor.lnum > 1)
-- {
-- l = ml_get(curwin->w_cursor.lnum - 1);
-- if (*l == NUL || l[STRLEN(l) - 1] != '\\')
-- break;
-- --curwin->w_cursor.lnum;
-- curwin->w_cursor.col = 0;
-- }
--
-- amount = get_indent(); /* XXX */
--
-- if (amount == 0)
-- amount = cin_first_id_amount();
-- if (amount == 0)
-- amount = ind_continuation;
-- break;
-- }
--
-- /*
-- * If the line looks like a function declaration, and we're
-- * not in a comment, put it the left margin.
-- */
-- if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0)) /* XXX */
-- break;
-- l = ml_get_curline();
--
-- /*
-- * Finding the closing '}' of a previous function. Put
-- * current line at the left margin. For when 'cino' has "fs".
-- */
-- if (*skipwhite(l) == '}')
-- break;
--
-- /* (matching {)
-- * If the previous line ends on '};' (maybe followed by
-- * comments) align at column 0. For example:
-- * char *string_array[] = { "foo",
-- * / * x * / "b};ar" }; / * foobar * /
-- */
-- if (cin_ends_in(l, (char_u *)"};", NULL))
-- break;
--
-- /*
-- * If the previous line ends on '[' we are probably in an
-- * array constant:
-- * something = [
-- * 234, <- extra indent
-- */
-- if (cin_ends_in(l, (char_u *)"[", NULL))
-- {
-- amount = get_indent() + ind_continuation;
-- break;
-- }
--
-- /*
-- * Find a line only has a semicolon that belongs to a previous
-- * line ending in '}', e.g. before an #endif. Don't increase
-- * indent then.
-- */
-- if (*(look = skipwhite(l)) == ';' && cin_nocode(look + 1))
-- {
-- pos_T curpos_save = curwin->w_cursor;
--
-- while (curwin->w_cursor.lnum > 1)
-- {
-- look = ml_get(--curwin->w_cursor.lnum);
-- if (!(cin_nocode(look) || cin_ispreproc_cont(
-- &look, &curwin->w_cursor.lnum, &amount)))
-- break;
-- }
-- if (curwin->w_cursor.lnum > 0
-- && cin_ends_in(look, (char_u *)"}", NULL))
-- break;
--
-- curwin->w_cursor = curpos_save;
-- }
--
-- /*
-- * If the PREVIOUS line is a function declaration, the current
-- * line (and the ones that follow) needs to be indented as
-- * parameters.
-- */
-- if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0))
-- {
-- amount = curbuf->b_ind_param;
-- break;
-- }
--
-- /*
-- * If the previous line ends in ';' and the line before the
-- * previous line ends in ',' or '\', ident to column zero:
-- * int foo,
-- * bar;
-- * indent_to_0 here;
-- */
-- if (cin_ends_in(l, (char_u *)";", NULL))
-- {
-- l = ml_get(curwin->w_cursor.lnum - 1);
-- if (cin_ends_in(l, (char_u *)",", NULL)
-- || (*l != NUL && l[STRLEN(l) - 1] == '\\'))
-- break;
-- l = ml_get_curline();
-- }
--
-- /*
-- * Doesn't look like anything interesting -- so just
-- * use the indent of this line.
-- *
-- * Position the cursor over the rightmost paren, so that
-- * matching it will take us back to the start of the line.
-- */
-- find_last_paren(l, '(', ')');
--
-- if ((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
-- curwin->w_cursor = *trypos;
-- amount = get_indent(); /* XXX */
-- break;
-- }
--
-- /* add extra indent for a comment */
-- if (cin_iscomment(theline))
-- amount += curbuf->b_ind_comment;
--
-- /* add extra indent if the previous line ended in a backslash:
-- * "asdfasdf\
-- * here";
-- * char *foo = "asdf\
-- * here";
-- */
-- if (cur_curpos.lnum > 1)
-- {
-- l = ml_get(cur_curpos.lnum - 1);
-- if (*l != NUL && l[STRLEN(l) - 1] == '\\')
-- {
-- cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1);
-- if (cur_amount > 0)
-- amount = cur_amount;
-- else if (cur_amount == 0)
-- amount += ind_continuation;
-- }
-- }
--
-- theend:
-- if (amount < 0)
-- amount = 0;
--
-- laterend:
-- /* put the cursor back where it belongs */
-- curwin->w_cursor = cur_curpos;
--
-- vim_free(linecopy);
--
-- return amount;
-- }
--
-- static int
-- find_match(int lookfor, linenr_T ourscope)
-- {
-- char_u *look;
-- pos_T *theirscope;
-- char_u *mightbeif;
-- int elselevel;
-- int whilelevel;
--
-- if (lookfor == LOOKFOR_IF)
-- {
-- elselevel = 1;
-- whilelevel = 0;
-- }
-- else
-- {
-- elselevel = 0;
-- whilelevel = 1;
-- }
--
-- curwin->w_cursor.col = 0;
--
-- while (curwin->w_cursor.lnum > ourscope + 1)
-- {
-- curwin->w_cursor.lnum--;
-- curwin->w_cursor.col = 0;
--
-- look = cin_skipcomment(ml_get_curline());
-- if (cin_iselse(look)
-- || cin_isif(look)
-- || cin_isdo(look) /* XXX */
-- || cin_iswhileofdo(look, curwin->w_cursor.lnum))
-- {
-- /*
-- * if we've gone outside the braces entirely,
-- * we must be out of scope...
-- */
-- theirscope = find_start_brace(); /* XXX */
-- if (theirscope == NULL)
-- break;
--
-- /*
-- * and if the brace enclosing this is further
-- * back than the one enclosing the else, we're
-- * out of luck too.
-- */
-- if (theirscope->lnum < ourscope)
-- break;
--
-- /*
-- * and if they're enclosed in a *deeper* brace,
-- * then we can ignore it because it's in a
-- * different scope...
-- */
-- if (theirscope->lnum > ourscope)
-- continue;
--
-- /*
-- * if it was an "else" (that's not an "else if")
-- * then we need to go back to another if, so
-- * increment elselevel
-- */
-- look = cin_skipcomment(ml_get_curline());
-- if (cin_iselse(look))
-- {
-- mightbeif = cin_skipcomment(look + 4);
-- if (!cin_isif(mightbeif))
-- ++elselevel;
-- continue;
-- }
--
-- /*
-- * if it was a "while" then we need to go back to
-- * another "do", so increment whilelevel. XXX
-- */
-- if (cin_iswhileofdo(look, curwin->w_cursor.lnum))
-- {
-- ++whilelevel;
-- continue;
-- }
--
-- /* If it's an "if" decrement elselevel */
-- look = cin_skipcomment(ml_get_curline());
-- if (cin_isif(look))
-- {
-- elselevel--;
-- /*
-- * When looking for an "if" ignore "while"s that
-- * get in the way.
-- */
-- if (elselevel == 0 && lookfor == LOOKFOR_IF)
-- whilelevel = 0;
-- }
--
-- /* If it's a "do" decrement whilelevel */
-- if (cin_isdo(look))
-- whilelevel--;
--
-- /*
-- * if we've used up all the elses, then
-- * this must be the if that we want!
-- * match the indent level of that if.
-- */
-- if (elselevel <= 0 && whilelevel <= 0)
-- {
-- return OK;
-- }
-- }
-- }
-- return FAIL;
-- }
--
-- # if defined(FEAT_EVAL) || defined(PROTO)
-- /*
-- * Get indent level from 'indentexpr'.
-- */
-- int
-- get_expr_indent(void)
-- {
-- int indent = -1;
-- char_u *inde_copy;
-- pos_T save_pos;
-- colnr_T save_curswant;
-- int save_set_curswant;
-- int save_State;
-- int use_sandbox = was_set_insecurely((char_u *)"indentexpr",
-- OPT_LOCAL);
--
-- /* Save and restore cursor position and curswant, in case it was changed
-- * via :normal commands */
-- save_pos = curwin->w_cursor;
-- save_curswant = curwin->w_curswant;
-- save_set_curswant = curwin->w_set_curswant;
-- set_vim_var_nr(VV_LNUM, curwin->w_cursor.lnum);
-- if (use_sandbox)
-- ++sandbox;
-- ++textlock;
--
-- /* Need to make a copy, the 'indentexpr' option could be changed while
-- * evaluating it. */
-- inde_copy = vim_strsave(curbuf->b_p_inde);
-- if (inde_copy != NULL)
-- {
-- indent = (int)eval_to_number(inde_copy);
-- vim_free(inde_copy);
-- }
--
-- if (use_sandbox)
-- --sandbox;
-- --textlock;
--
-- /* Restore the cursor position so that 'indentexpr' doesn't need to.
-- * Pretend to be in Insert mode, allow cursor past end of line for "o"
-- * command. */
-- save_State = State;
-- State = INSERT;
-- curwin->w_cursor = save_pos;
-- curwin->w_curswant = save_curswant;
-- curwin->w_set_curswant = save_set_curswant;
-- check_cursor();
-- State = save_State;
--
-- /* If there is an error, just keep the current indent. */
-- if (indent < 0)
-- indent = get_indent();
--
-- return indent;
-- }
-- # endif
--
-- #endif /* FEAT_CINDENT */
--
-- #if defined(FEAT_LISP) || defined(PROTO)
--
-- static int
-- lisp_match(char_u *p)
-- {
-- char_u buf[LSIZE];
-- int len;
-- char_u *word = *curbuf->b_p_lw != NUL ? curbuf->b_p_lw : p_lispwords;
--
-- while (*word != NUL)
-- {
-- (void)copy_option_part(&word, buf, LSIZE, ",");
-- len = (int)STRLEN(buf);
-- if (STRNCMP(buf, p, len) == 0 && p[len] == ' ')
-- return TRUE;
-- }
-- return FALSE;
-- }
--
-- /*
-- * When 'p' is present in 'cpoptions, a Vi compatible method is used.
-- * The incompatible newer method is quite a bit better at indenting
-- * code in lisp-like languages than the traditional one; it's still
-- * mostly heuristics however -- Dirk van Deun, dirk@rave.org
-- *
-- * TODO:
-- * Findmatch() should be adapted for lisp, also to make showmatch
-- * work correctly: now (v5.3) it seems all C/C++ oriented:
-- * - it does not recognize the #\( and #\) notations as character literals
-- * - it doesn't know about comments starting with a semicolon
-- * - it incorrectly interprets '(' as a character literal
-- * All this messes up get_lisp_indent in some rare cases.
-- * Update from Sergey Khorev:
-- * I tried to fix the first two issues.
-- */
-- int
-- get_lisp_indent(void)
-- {
-- pos_T *pos, realpos, paren;
-- int amount;
-- char_u *that;
-- colnr_T col;
-- colnr_T firsttry;
-- int parencount, quotecount;
-- int vi_lisp;
--
-- /* Set vi_lisp to use the vi-compatible method */
-- vi_lisp = (vim_strchr(p_cpo, CPO_LISP) != NULL);
--
-- realpos = curwin->w_cursor;
-- curwin->w_cursor.col = 0;
--
-- if ((pos = findmatch(NULL, '(')) == NULL)
-- pos = findmatch(NULL, '[');
-- else
-- {
-- paren = *pos;
-- pos = findmatch(NULL, '[');
-- if (pos == NULL || LT_POSP(pos, &paren))
-- pos = &paren;
-- }
-- if (pos != NULL)
-- {
-- /* Extra trick: Take the indent of the first previous non-white
-- * line that is at the same () level. */
-- amount = -1;
-- parencount = 0;
--
-- while (--curwin->w_cursor.lnum >= pos->lnum)
-- {
-- if (linewhite(curwin->w_cursor.lnum))
-- continue;
-- for (that = ml_get_curline(); *that != NUL; ++that)
-- {
-- if (*that == ';')
-- {
-- while (*(that + 1) != NUL)
-- ++that;
-- continue;
-- }
-- if (*that == '\\')
-- {
-- if (*(that + 1) != NUL)
-- ++that;
-- continue;
-- }
-- if (*that == '"' && *(that + 1) != NUL)
-- {
-- while (*++that && *that != '"')
-- {
-- /* skipping escaped characters in the string */
-- if (*that == '\\')
-- {
-- if (*++that == NUL)
-- break;
-- if (that[1] == NUL)
-- {
-- ++that;
-- break;
-- }
-- }
-- }
-- }
-- if (*that == '(' || *that == '[')
-- ++parencount;
-- else if (*that == ')' || *that == ']')
-- --parencount;
-- }
-- if (parencount == 0)
-- {
-- amount = get_indent();
-- break;
-- }
-- }
--
-- if (amount == -1)
-- {
-- curwin->w_cursor.lnum = pos->lnum;
-- curwin->w_cursor.col = pos->col;
-- col = pos->col;
--
-- that = ml_get_curline();
--
-- if (vi_lisp && get_indent() == 0)
-- amount = 2;
-- else
-- {
-- char_u *line = that;
--
-- amount = 0;
-- while (*that && col)
-- {
-- amount += lbr_chartabsize_adv(line, &that, (colnr_T)amount);
-- col--;
-- }
--
-- /*
-- * Some keywords require "body" indenting rules (the
-- * non-standard-lisp ones are Scheme special forms):
-- *
-- * (let ((a 1)) instead (let ((a 1))
-- * (...)) of (...))
-- */
--
-- if (!vi_lisp && (*that == '(' || *that == '[')
-- && lisp_match(that + 1))
-- amount += 2;
-- else
-- {
-- that++;
-- amount++;
-- firsttry = amount;
--
-- while (VIM_ISWHITE(*that))
-- {
-- amount += lbr_chartabsize(line, that, (colnr_T)amount);
-- ++that;
-- }
--
-- if (*that && *that != ';') /* not a comment line */
-- {
-- /* test *that != '(' to accommodate first let/do
-- * argument if it is more than one line */
-- if (!vi_lisp && *that != '(' && *that != '[')
-- firsttry++;
--
-- parencount = 0;
-- quotecount = 0;
--
-- if (vi_lisp
-- || (*that != '"'
-- && *that != '\''
-- && *that != '#'
-- && (*that < '0' || *that > '9')))
-- {
-- while (*that
-- && (!VIM_ISWHITE(*that)
-- || quotecount
-- || parencount)
-- && (!((*that == '(' || *that == '[')
-- && !quotecount
-- && !parencount
-- && vi_lisp)))
-- {
-- if (*that == '"')
-- quotecount = !quotecount;
-- if ((*that == '(' || *that == '[')
-- && !quotecount)
-- ++parencount;
-- if ((*that == ')' || *that == ']')
-- && !quotecount)
-- --parencount;
-- if (*that == '\\' && *(that+1) != NUL)
-- amount += lbr_chartabsize_adv(
-- line, &that, (colnr_T)amount);
-- amount += lbr_chartabsize_adv(
-- line, &that, (colnr_T)amount);
-- }
-- }
-- while (VIM_ISWHITE(*that))
-- {
-- amount += lbr_chartabsize(
-- line, that, (colnr_T)amount);
-- that++;
-- }
-- if (!*that || *that == ';')
-- amount = firsttry;
-- }
-- }
-- }
-- }
-- }
-- else
-- amount = 0; /* no matching '(' or '[' found, use zero indent */
--
-- curwin->w_cursor = realpos;
--
-- return amount;
-- }
-- #endif /* FEAT_LISP */
--
- void
- prepare_to_exit(void)
- {
---- 5369,5374 ----
-*** ../vim-8.1.0856/src/proto.h 2019-01-26 16:20:44.264683546 +0100
---- src/proto.h 2019-01-31 13:43:23.356467234 +0100
-***************
-*** 87,92 ****
---- 87,93 ----
- # endif
- # include "hardcopy.pro"
- # include "hashtab.pro"
-+ # include "indent.pro"
- # include "json.pro"
- # include "list.pro"
- # include "blob.pro"
-*** ../vim-8.1.0856/src/proto/edit.pro 2018-11-22 03:07:30.948596188 +0100
---- src/proto/edit.pro 2019-01-31 13:45:12.275722540 +0100
-***************
-*** 38,46 ****
- char_u *get_last_insert_save(void);
- void replace_push(int c);
- int replace_push_mb(char_u *p);
-- void fixthisline(int (*get_the_indent)(void));
-- void fix_indent(void);
-- int in_cinkeys(int keytyped, int when, int line_is_empty);
- int hkmap(int c);
- int bracketed_paste(paste_mode_T mode, int drop, garray_T *gap);
- void ins_scroll(void);
---- 38,43 ----
-*** ../vim-8.1.0856/src/proto/indent.pro 2019-01-31 13:47:08.570924989 +0100
---- src/proto/indent.pro 2019-01-31 13:45:17.403687423 +0100
-***************
-*** 0 ****
---- 1,16 ----
-+ /* indent.c */
-+ int cin_is_cinword(char_u *line);
-+ pos_T *find_start_comment(int ind_maxcomment);
-+ int cindent_on(void);
-+ int cin_islabel(void);
-+ int cin_iscase(char_u *s, int strict);
-+ int cin_isscopedecl(char_u *s);
-+ void parse_cino(buf_T *buf);
-+ int get_c_indent(void);
-+ int get_expr_indent(void);
-+ int in_cinkeys(int keytyped, int when, int line_is_empty);
-+ int get_lisp_indent(void);
-+ void do_c_expr_indent(void);
-+ void fixthisline(int (*get_the_indent)(void));
-+ void fix_indent(void);
-+ /* vim: set ft=c : */
-*** ../vim-8.1.0856/src/proto/misc1.pro 2019-01-02 00:02:07.607556145 +0100
---- src/proto/misc1.pro 2019-01-31 13:45:20.359667178 +0100
-***************
-*** 83,97 ****
- char_u *concat_str(char_u *str1, char_u *str2);
- void add_pathsep(char_u *p);
- char_u *FullName_save(char_u *fname, int force);
-- pos_T *find_start_comment(int ind_maxcomment);
-- void do_c_expr_indent(void);
-- int cin_islabel(void);
-- int cin_iscase(char_u *s, int strict);
-- int cin_isscopedecl(char_u *s);
-- void parse_cino(buf_T *buf);
-- int get_c_indent(void);
-- int get_expr_indent(void);
-- int get_lisp_indent(void);
- void prepare_to_exit(void);
- void preserve_exit(void);
- int vim_fexists(char_u *fname);
---- 83,88 ----
-*** ../vim-8.1.0856/src/version.c 2019-01-31 13:22:28.068543628 +0100
---- src/version.c 2019-01-31 13:45:27.287619720 +0100
-***************
-*** 785,786 ****
---- 785,788 ----
- { /* Add new patch number below this line */
-+ /**/
-+ 857,
- /**/
-
---
- [SIR LAUNCELOT runs back up the stairs, grabs a rope
- of the wall and swings out over the heads of the CROWD in a
- swashbuckling manner towards a large window. He stops just short
- of the window and is left swing pathetically back and forth.]
-LAUNCELOT: Excuse me ... could somebody give me a push ...
- "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
-
- /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
-/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
-\\\ an exciting new programming language -- http://www.Zimbu.org ///
- \\\ help me help AIDS victims -- http://ICCF-Holland.org ///