aboutsummaryrefslogtreecommitdiff
path: root/src/edit.c
diff options
context:
space:
mode:
authorEliseo Martínez <eliseomarmol@gmail.com>2014-05-12 02:25:17 +0200
committerEliseo Martínez <eliseomarmol@gmail.com>2014-05-15 20:46:01 +0200
commitda51dc9cf202772f60bd2da975dbef257bd9237c (patch)
tree5c16b93238a153f55634e9323077f30c8133970c /src/edit.c
parentffe61e5ba1721340ca51d56bae3ddaca415fb5bc (diff)
downloadrneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.tar.gz
rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.tar.bz2
rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.zip
Introduce nvim namespace: Move files.
Move files from src/ to src/nvim/. - src/nvim/ becomes the new root dir for nvim executable sources. - src/libnvim/ is planned to become root dir of the neovim library.
Diffstat (limited to 'src/edit.c')
-rw-r--r--src/edit.c8444
1 files changed, 0 insertions, 8444 deletions
diff --git a/src/edit.c b/src/edit.c
deleted file mode 100644
index 146a8bba70..0000000000
--- a/src/edit.c
+++ /dev/null
@@ -1,8444 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * edit.c: functions for Insert mode
- */
-
-#include <string.h>
-
-#include "vim.h"
-#include "edit.h"
-#include "buffer.h"
-#include "charset.h"
-#include "digraph.h"
-#include "eval.h"
-#include "ex_docmd.h"
-#include "ex_getln.h"
-#include "farsi.h"
-#include "fileio.h"
-#include "fold.h"
-#include "getchar.h"
-#include "indent.h"
-#include "indent_c.h"
-#include "main.h"
-#include "mbyte.h"
-#include "memline.h"
-#include "memory.h"
-#include "message.h"
-#include "misc1.h"
-#include "misc2.h"
-#include "keymap.h"
-#include "move.h"
-#include "normal.h"
-#include "ops.h"
-#include "option.h"
-#include "path.h"
-#include "popupmnu.h"
-#include "quickfix.h"
-#include "regexp.h"
-#include "screen.h"
-#include "search.h"
-#include "spell.h"
-#include "syntax.h"
-#include "tag.h"
-#include "term.h"
-#include "ui.h"
-#include "undo.h"
-#include "window.h"
-#include "os/event.h"
-
-/*
- * definitions used for CTRL-X submode
- */
-#define CTRL_X_WANT_IDENT 0x100
-
-#define CTRL_X_NOT_DEFINED_YET 1
-#define CTRL_X_SCROLL 2
-#define CTRL_X_WHOLE_LINE 3
-#define CTRL_X_FILES 4
-#define CTRL_X_TAGS (5 + CTRL_X_WANT_IDENT)
-#define CTRL_X_PATH_PATTERNS (6 + CTRL_X_WANT_IDENT)
-#define CTRL_X_PATH_DEFINES (7 + CTRL_X_WANT_IDENT)
-#define CTRL_X_FINISHED 8
-#define CTRL_X_DICTIONARY (9 + CTRL_X_WANT_IDENT)
-#define CTRL_X_THESAURUS (10 + CTRL_X_WANT_IDENT)
-#define CTRL_X_CMDLINE 11
-#define CTRL_X_FUNCTION 12
-#define CTRL_X_OMNI 13
-#define CTRL_X_SPELL 14
-#define CTRL_X_LOCAL_MSG 15 /* only used in "ctrl_x_msgs" */
-
-#define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT]
-
-static char *ctrl_x_msgs[] =
-{
- N_(" Keyword completion (^N^P)"), /* ctrl_x_mode == 0, ^P/^N compl. */
- N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"),
- NULL,
- N_(" Whole line completion (^L^N^P)"),
- N_(" File name completion (^F^N^P)"),
- N_(" Tag completion (^]^N^P)"),
- N_(" Path pattern completion (^N^P)"),
- N_(" Definition completion (^D^N^P)"),
- NULL,
- N_(" Dictionary completion (^K^N^P)"),
- N_(" Thesaurus completion (^T^N^P)"),
- N_(" Command-line completion (^V^N^P)"),
- N_(" User defined completion (^U^N^P)"),
- N_(" Omni completion (^O^N^P)"),
- N_(" Spelling suggestion (s^N^P)"),
- N_(" Keyword Local completion (^N^P)"),
-};
-
-static char e_hitend[] = N_("Hit end of paragraph");
-static char e_complwin[] = N_("E839: Completion function changed window");
-static char e_compldel[] = N_("E840: Completion function deleted text");
-
-/*
- * Structure used to store one match for insert completion.
- */
-typedef struct compl_S compl_T;
-struct compl_S {
- compl_T *cp_next;
- compl_T *cp_prev;
- char_u *cp_str; /* matched text */
- char cp_icase; /* TRUE or FALSE: ignore case */
- char_u *(cp_text[CPT_COUNT]); /* text for the menu */
- char_u *cp_fname; /* file containing the match, allocated when
- * cp_flags has FREE_FNAME */
- int cp_flags; /* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */
- int cp_number; /* sequence number */
-};
-
-#define ORIGINAL_TEXT (1) /* the original text when the expansion begun */
-#define FREE_FNAME (2)
-
-/*
- * All the current matches are stored in a list.
- * "compl_first_match" points to the start of the list.
- * "compl_curr_match" points to the currently selected entry.
- * "compl_shown_match" is different from compl_curr_match during
- * ins_compl_get_exp().
- */
-static compl_T *compl_first_match = NULL;
-static compl_T *compl_curr_match = NULL;
-static compl_T *compl_shown_match = NULL;
-
-/* After using a cursor key <Enter> selects a match in the popup menu,
- * otherwise it inserts a line break. */
-static int compl_enter_selects = FALSE;
-
-/* When "compl_leader" is not NULL only matches that start with this string
- * are used. */
-static char_u *compl_leader = NULL;
-
-static int compl_get_longest = FALSE; /* put longest common string
- in compl_leader */
-
-static int compl_used_match; /* Selected one of the matches. When
- FALSE the match was edited or using
- the longest common string. */
-
-static int compl_was_interrupted = FALSE; /* didn't finish finding
- completions. */
-
-static int compl_restarting = FALSE; /* don't insert match */
-
-/* When the first completion is done "compl_started" is set. When it's
- * FALSE the word to be completed must be located. */
-static int compl_started = FALSE;
-
-/* Set when doing something for completion that may call edit() recursively,
- * which is not allowed. */
-static int compl_busy = FALSE;
-
-static int compl_matches = 0;
-static char_u *compl_pattern = NULL;
-static int compl_direction = FORWARD;
-static int compl_shows_dir = FORWARD;
-static int compl_pending = 0; /* > 1 for postponed CTRL-N */
-static pos_T compl_startpos;
-static colnr_T compl_col = 0; /* column where the text starts
- * that is being completed */
-static char_u *compl_orig_text = NULL; /* text as it was before
- * completion started */
-static int compl_cont_mode = 0;
-static expand_T compl_xp;
-
-static int compl_opt_refresh_always = FALSE;
-
-static void ins_ctrl_x(void);
-static int has_compl_option(int dict_opt);
-static int ins_compl_accept_char(int c);
-static int ins_compl_add(char_u *str, int len, int icase, char_u *fname,
- char_u **cptext, int cdir, int flags,
- int adup);
-static int ins_compl_equal(compl_T *match, char_u *str, int len);
-static void ins_compl_longest_match(compl_T *match);
-static void ins_compl_add_matches(int num_matches, char_u **matches,
- int icase);
-static int ins_compl_make_cyclic(void);
-static void ins_compl_upd_pum(void);
-static void ins_compl_del_pum(void);
-static int pum_wanted(void);
-static int pum_enough_matches(void);
-static void ins_compl_dictionaries(char_u *dict, char_u *pat, int flags,
- int thesaurus);
-static void ins_compl_files(int count, char_u **files, int thesaurus,
- int flags, regmatch_T *regmatch, char_u *
- buf,
- int *dir);
-static char_u *find_line_end(char_u *ptr);
-static void ins_compl_free(void);
-static void ins_compl_clear(void);
-static int ins_compl_bs(void);
-static int ins_compl_need_restart(void);
-static void ins_compl_new_leader(void);
-static void ins_compl_addleader(int c);
-static int ins_compl_len(void);
-static void ins_compl_restart(void);
-static void ins_compl_set_original_text(char_u *str);
-static void ins_compl_addfrommatch(void);
-static int ins_compl_prep(int c);
-static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg);
-static buf_T *ins_compl_next_buf(buf_T *buf, int flag);
-static void ins_compl_add_list(list_T *list);
-static void ins_compl_add_dict(dict_T *dict);
-static int ins_compl_get_exp(pos_T *ini);
-static void ins_compl_delete(void);
-static void ins_compl_insert(void);
-static int ins_compl_next(int allow_get_expansion, int count,
- int insert_match);
-static int ins_compl_key2dir(int c);
-static int ins_compl_pum_key(int c);
-static int ins_compl_key2count(int c);
-static int ins_compl_use_match(int c);
-static int ins_complete(int c);
-static unsigned quote_meta(char_u *dest, char_u *str, int len);
-
-#define BACKSPACE_CHAR 1
-#define BACKSPACE_WORD 2
-#define BACKSPACE_WORD_NOT_SPACE 3
-#define BACKSPACE_LINE 4
-
-static void ins_redraw(int ready);
-static void ins_ctrl_v(void);
-static void undisplay_dollar(void);
-static void insert_special(int, int, int);
-static void internal_format(int textwidth, int second_indent, int flags,
- int format_only,
- int c);
-static void check_auto_format(int);
-static void redo_literal(int c);
-static void start_arrow(pos_T *end_insert_pos);
-static void check_spell_redraw(void);
-static void spell_back_to_badword(void);
-static int spell_bad_len = 0; /* length of located bad word */
-static void stop_insert(pos_T *end_insert_pos, int esc, int nomove);
-static int echeck_abbr(int);
-static int replace_pop(void);
-static void replace_join(int off);
-static void replace_pop_ins(void);
-static void mb_replace_pop_ins(int cc);
-static void replace_flush(void);
-static void replace_do_bs(int limit_col);
-static int del_char_after_col(int limit_col);
-static int cindent_on(void);
-static void ins_reg(void);
-static void ins_ctrl_g(void);
-static void ins_ctrl_hat(void);
-static int ins_esc(long *count, int cmdchar, int nomove);
-static void ins_ctrl_(void);
-static int ins_start_select(int c);
-static void ins_insert(int replaceState);
-static void ins_ctrl_o(void);
-static void ins_shift(int c, int lastc);
-static void ins_del(void);
-static int ins_bs(int c, int mode, int *inserted_space_p);
-static void ins_mouse(int c);
-static void ins_mousescroll(int dir);
-static void ins_left(void);
-static void ins_home(int c);
-static void ins_end(int c);
-static void ins_s_left(void);
-static void ins_right(void);
-static void ins_s_right(void);
-static void ins_up(int startcol);
-static void ins_pageup(void);
-static void ins_down(int startcol);
-static void ins_pagedown(void);
-static int ins_tab(void);
-static int ins_eol(int c);
-static int ins_digraph(void);
-static int ins_ctrl_ey(int tc);
-static void ins_try_si(int c);
-static colnr_T get_nolist_virtcol(void);
-static char_u *do_insert_char_pre(int c);
-
-static colnr_T Insstart_textlen; /* length of line when insert started */
-static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */
-static bool update_Insstart_orig = true; /* set Insstart_orig to Insstart */
-
-static char_u *last_insert = NULL; /* the text of the previous insert,
- K_SPECIAL and CSI are escaped */
-static int last_insert_skip; /* nr of chars in front of previous insert */
-static int new_insert_skip; /* nr of chars in front of current insert */
-static int did_restart_edit; /* "restart_edit" when calling edit() */
-
-static int can_cindent; /* may do cindenting on this line */
-
-static int old_indent = 0; /* for ^^D command in insert mode */
-
-static int revins_on; /* reverse insert mode on */
-static int revins_chars; /* how much to skip after edit */
-static int revins_legal; /* was the last char 'legal'? */
-static int revins_scol; /* start column of revins session */
-
-static int ins_need_undo; /* call u_save() before inserting a
- char. Set when edit() is called.
- after that arrow_used is used. */
-
-static int did_add_space = FALSE; /* auto_format() added an extra space
- under the cursor */
-
-/*
- * edit(): Start inserting text.
- *
- * "cmdchar" can be:
- * 'i' normal insert command
- * 'a' normal append command
- * 'R' replace command
- * 'r' "r<CR>" command: insert one <CR>. Note: count can be > 1, for redo,
- * but still only one <CR> is inserted. The <Esc> is not used for redo.
- * 'g' "gI" command.
- * 'V' "gR" command for Virtual Replace mode.
- * 'v' "gr" command for single character Virtual Replace mode.
- *
- * This function is not called recursively. For CTRL-O commands, it returns
- * and lets the caller handle the Normal-mode command.
- *
- * Return TRUE if a CTRL-O command caused the return (insert mode pending).
- */
-int
-edit (
- int cmdchar,
- int startln, /* if set, insert at start of line */
- long count
-)
-{
- int c = 0;
- char_u *ptr;
- int lastc;
- int mincol;
- static linenr_T o_lnum = 0;
- int i;
- int did_backspace = TRUE; /* previous char was backspace */
- int line_is_white = FALSE; /* line is empty before insert */
- linenr_T old_topline = 0; /* topline before insertion */
- int old_topfill = -1;
- int inserted_space = FALSE; /* just inserted a space */
- int replaceState = REPLACE;
- int nomove = FALSE; /* don't move cursor on return */
-
- /* Remember whether editing was restarted after CTRL-O. */
- did_restart_edit = restart_edit;
-
- /* sleep before redrawing, needed for "CTRL-O :" that results in an
- * error message */
- check_for_delay(TRUE);
-
- // set Insstart_orig to Insstart
- update_Insstart_orig = true;
-
-#ifdef HAVE_SANDBOX
- /* Don't allow inserting in the sandbox. */
- if (sandbox != 0) {
- EMSG(_(e_sandbox));
- return FALSE;
- }
-#endif
- /* Don't allow changes in the buffer while editing the cmdline. The
- * caller of getcmdline() may get confused. */
- if (textlock != 0) {
- EMSG(_(e_secure));
- return FALSE;
- }
-
- /* Don't allow recursive insert mode when busy with completion. */
- if (compl_started || compl_busy || pum_visible()) {
- EMSG(_(e_secure));
- return FALSE;
- }
- ins_compl_clear(); /* clear stuff for CTRL-X mode */
-
- /*
- * Trigger InsertEnter autocommands. Do not do this for "r<CR>" or "grx".
- */
- if (cmdchar != 'r' && cmdchar != 'v') {
- pos_T save_cursor = curwin->w_cursor;
-
- if (cmdchar == 'R')
- ptr = (char_u *)"r";
- else if (cmdchar == 'V')
- ptr = (char_u *)"v";
- else
- ptr = (char_u *)"i";
- set_vim_var_string(VV_INSERTMODE, ptr, 1);
- set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */
- apply_autocmds(EVENT_INSERTENTER, NULL, NULL, FALSE, curbuf);
-
- /* Make sure the cursor didn't move. Do call check_cursor_col() in
- * case the text was modified. Since Insert mode was not started yet
- * a call to check_cursor_col() may move the cursor, especially with
- * the "A" command, thus set State to avoid that. Also check that the
- * line number is still valid (lines may have been deleted).
- * Do not restore if v:char was set to a non-empty string. */
- if (!equalpos(curwin->w_cursor, save_cursor)
- && *get_vim_var_str(VV_CHAR) == NUL
- && save_cursor.lnum <= curbuf->b_ml.ml_line_count) {
- int save_state = State;
-
- curwin->w_cursor = save_cursor;
- State = INSERT;
- check_cursor_col();
- State = save_state;
- }
- }
-
- /* Check if the cursor line needs redrawing before changing State. If
- * 'concealcursor' is "n" it needs to be redrawn without concealing. */
- conceal_check_cursur_line();
-
- /*
- * When doing a paste with the middle mouse button, Insstart is set to
- * where the paste started.
- */
- if (where_paste_started.lnum != 0)
- Insstart = where_paste_started;
- else {
- Insstart = curwin->w_cursor;
- if (startln)
- Insstart.col = 0;
- }
- Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
- Insstart_blank_vcol = MAXCOL;
- if (!did_ai)
- ai_col = 0;
-
- if (cmdchar != NUL && restart_edit == 0) {
- ResetRedobuff();
- AppendNumberToRedobuff(count);
- if (cmdchar == 'V' || cmdchar == 'v') {
- /* "gR" or "gr" command */
- AppendCharToRedobuff('g');
- AppendCharToRedobuff((cmdchar == 'v') ? 'r' : 'R');
- } else {
- AppendCharToRedobuff(cmdchar);
- if (cmdchar == 'g') /* "gI" command */
- AppendCharToRedobuff('I');
- else if (cmdchar == 'r') /* "r<CR>" command */
- count = 1; /* insert only one <CR> */
- }
- }
-
- if (cmdchar == 'R') {
- if (p_fkmap && p_ri) {
- beep_flush();
- EMSG(farsi_text_3); /* encoded in Farsi */
- State = INSERT;
- } else
- State = REPLACE;
- } else if (cmdchar == 'V' || cmdchar == 'v') {
- State = VREPLACE;
- replaceState = VREPLACE;
- orig_line_count = curbuf->b_ml.ml_line_count;
- vr_lines_changed = 1;
- } else
- State = INSERT;
-
- stop_insert_mode = FALSE;
-
- /*
- * Need to recompute the cursor position, it might move when the cursor is
- * on a TAB or special character.
- */
- curs_columns(TRUE);
-
- /*
- * Enable langmap or IME, indicated by 'iminsert'.
- * Note that IME may enabled/disabled without us noticing here, thus the
- * 'iminsert' value may not reflect what is actually used. It is updated
- * when hitting <Esc>.
- */
- if (curbuf->b_p_iminsert == B_IMODE_LMAP)
- State |= LANGMAP;
-#ifdef USE_IM_CONTROL
- im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
-#endif
-
- setmouse();
- clear_showcmd();
- /* there is no reverse replace mode */
- revins_on = (State == INSERT && p_ri);
- if (revins_on)
- undisplay_dollar();
- revins_chars = 0;
- revins_legal = 0;
- revins_scol = -1;
-
- /*
- * Handle restarting Insert mode.
- * Don't do this for "CTRL-O ." (repeat an insert): we get here with
- * restart_edit non-zero, and something in the stuff buffer.
- */
- if (restart_edit != 0 && stuff_empty()) {
- /*
- * After a paste we consider text typed to be part of the insert for
- * the pasted text. You can backspace over the pasted text too.
- */
- if (where_paste_started.lnum)
- arrow_used = FALSE;
- else
- arrow_used = TRUE;
- restart_edit = 0;
-
- /*
- * If the cursor was after the end-of-line before the CTRL-O and it is
- * now at the end-of-line, put it after the end-of-line (this is not
- * correct in very rare cases).
- * Also do this if curswant is greater than the current virtual
- * column. Eg after "^O$" or "^O80|".
- */
- validate_virtcol();
- update_curswant();
- if (((ins_at_eol && curwin->w_cursor.lnum == o_lnum)
- || curwin->w_curswant > curwin->w_virtcol)
- && *(ptr = ml_get_curline() + curwin->w_cursor.col) != NUL) {
- if (ptr[1] == NUL)
- ++curwin->w_cursor.col;
- else if (has_mbyte) {
- i = (*mb_ptr2len)(ptr);
- if (ptr[i] == NUL)
- curwin->w_cursor.col += i;
- }
- }
- ins_at_eol = FALSE;
- } else
- arrow_used = FALSE;
-
- /* we are in insert mode now, don't need to start it anymore */
- need_start_insertmode = FALSE;
-
- /* Need to save the line for undo before inserting the first char. */
- ins_need_undo = TRUE;
-
- where_paste_started.lnum = 0;
- can_cindent = TRUE;
- /* The cursor line is not in a closed fold, unless 'insertmode' is set or
- * restarting. */
- if (!p_im && did_restart_edit == 0)
- foldOpenCursor();
-
- /*
- * If 'showmode' is set, show the current (insert/replace/..) mode.
- * A warning message for changing a readonly file is given here, before
- * actually changing anything. It's put after the mode, if any.
- */
- i = 0;
- if (p_smd && msg_silent == 0)
- i = showmode();
-
- if (!p_im && did_restart_edit == 0)
- change_warning(i == 0 ? 0 : i + 1);
-
- ui_cursor_shape(); /* may show different cursor shape */
- do_digraph(-1); /* clear digraphs */
-
- /*
- * Get the current length of the redo buffer, those characters have to be
- * skipped if we want to get to the inserted characters.
- */
- ptr = get_inserted();
- if (ptr == NULL)
- new_insert_skip = 0;
- else {
- new_insert_skip = (int)STRLEN(ptr);
- free(ptr);
- }
-
- old_indent = 0;
-
- /*
- * Main loop in Insert mode: repeat until Insert mode is left.
- */
- for (;; ) {
- if (!revins_legal)
- revins_scol = -1; /* reset on illegal motions */
- else
- revins_legal = 0;
- if (arrow_used) /* don't repeat insert when arrow key used */
- count = 0;
-
- if (update_Insstart_orig) {
- Insstart_orig = Insstart;
- }
-
- if (stop_insert_mode) {
- /* ":stopinsert" used or 'insertmode' reset */
- count = 0;
- goto doESCkey;
- }
-
- /* set curwin->w_curswant for next K_DOWN or K_UP */
- if (!arrow_used)
- curwin->w_set_curswant = TRUE;
-
- /* If there is no typeahead may check for timestamps (e.g., for when a
- * menu invoked a shell command). */
- if (stuff_empty()) {
- did_check_timestamps = FALSE;
- if (need_check_timestamps)
- check_timestamps(FALSE);
- }
-
- /*
- * When emsg() was called msg_scroll will have been set.
- */
- msg_scroll = FALSE;
-
-
- /* Open fold at the cursor line, according to 'foldopen'. */
- if (fdo_flags & FDO_INSERT)
- foldOpenCursor();
- /* Close folds where the cursor isn't, according to 'foldclose' */
- if (!char_avail())
- foldCheckClose();
-
- /*
- * If we inserted a character at the last position of the last line in
- * the window, scroll the window one line up. This avoids an extra
- * redraw.
- * This is detected when the cursor column is smaller after inserting
- * something.
- * Don't do this when the topline changed already, it has
- * already been adjusted (by insertchar() calling open_line())).
- */
- if (curbuf->b_mod_set
- && curwin->w_p_wrap
- && !did_backspace
- && curwin->w_topline == old_topline
- && curwin->w_topfill == old_topfill
- ) {
- mincol = curwin->w_wcol;
- validate_cursor_col();
-
- if ((int)curwin->w_wcol < mincol - curbuf->b_p_ts
- && curwin->w_wrow == W_WINROW(curwin)
- + curwin->w_height - 1 - p_so
- && (curwin->w_cursor.lnum != curwin->w_topline
- || curwin->w_topfill > 0
- )) {
- if (curwin->w_topfill > 0)
- --curwin->w_topfill;
- else if (hasFolding(curwin->w_topline, NULL, &old_topline))
- set_topline(curwin, old_topline + 1);
- else
- set_topline(curwin, curwin->w_topline + 1);
- }
- }
-
- /* May need to adjust w_topline to show the cursor. */
- update_topline();
-
- did_backspace = FALSE;
-
- validate_cursor(); /* may set must_redraw */
-
- /*
- * Redraw the display when no characters are waiting.
- * Also shows mode, ruler and positions cursor.
- */
- ins_redraw(TRUE);
-
- if (curwin->w_p_scb)
- do_check_scrollbind(TRUE);
-
- if (curwin->w_p_crb)
- do_check_cursorbind();
- update_curswant();
- old_topline = curwin->w_topline;
- old_topfill = curwin->w_topfill;
-
-#ifdef USE_ON_FLY_SCROLL
- dont_scroll = FALSE; /* allow scrolling here */
-#endif
-
- /*
- * Get a character for Insert mode. Ignore K_IGNORE.
- */
- lastc = c; /* remember previous char for CTRL-D */
- do {
- c = safe_vgetc();
- } while (c == K_IGNORE);
-
- /* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
- did_cursorhold = TRUE;
-
- if (p_hkmap && KeyTyped)
- c = hkmap(c); /* Hebrew mode mapping */
- if (p_fkmap && KeyTyped)
- c = fkmap(c); /* Farsi mode mapping */
-
- /*
- * Special handling of keys while the popup menu is visible or wanted
- * and the cursor is still in the completed word. Only when there is
- * a match, skip this when no matches were found.
- */
- if (compl_started
- && pum_wanted()
- && curwin->w_cursor.col >= compl_col
- && (compl_shown_match == NULL
- || compl_shown_match != compl_shown_match->cp_next)) {
- /* BS: Delete one character from "compl_leader". */
- if ((c == K_BS || c == Ctrl_H)
- && curwin->w_cursor.col > compl_col
- && (c = ins_compl_bs()) == NUL)
- continue;
-
- /* When no match was selected or it was edited. */
- if (!compl_used_match) {
- /* CTRL-L: Add one character from the current match to
- * "compl_leader". Except when at the original match and
- * there is nothing to add, CTRL-L works like CTRL-P then. */
- if (c == Ctrl_L
- && (ctrl_x_mode != CTRL_X_WHOLE_LINE
- || (int)STRLEN(compl_shown_match->cp_str)
- > curwin->w_cursor.col - compl_col)) {
- ins_compl_addfrommatch();
- continue;
- }
-
- /* A non-white character that fits in with the current
- * completion: Add to "compl_leader". */
- if (ins_compl_accept_char(c)) {
- /* Trigger InsertCharPre. */
- char_u *str = do_insert_char_pre(c);
- char_u *p;
-
- if (str != NULL) {
- for (p = str; *p != NUL; mb_ptr_adv(p))
- ins_compl_addleader(PTR2CHAR(p));
- free(str);
- } else
- ins_compl_addleader(c);
- continue;
- }
-
- /* Pressing CTRL-Y selects the current match. When
- * compl_enter_selects is set the Enter key does the same. */
- if (c == Ctrl_Y || (compl_enter_selects
- && (c == CAR || c == K_KENTER || c == NL))) {
- ins_compl_delete();
- ins_compl_insert();
- }
- }
- }
-
- /* Prepare for or stop CTRL-X mode. This doesn't do completion, but
- * it does fix up the text when finishing completion. */
- compl_get_longest = FALSE;
- if (ins_compl_prep(c))
- continue;
-
- /* CTRL-\ CTRL-N goes to Normal mode,
- * CTRL-\ CTRL-G goes to mode selected with 'insertmode',
- * CTRL-\ CTRL-O is like CTRL-O but without moving the cursor. */
- if (c == Ctrl_BSL) {
- /* may need to redraw when no more chars available now */
- ins_redraw(FALSE);
- ++no_mapping;
- ++allow_keys;
- c = plain_vgetc();
- --no_mapping;
- --allow_keys;
- if (c != Ctrl_N && c != Ctrl_G && c != Ctrl_O) {
- /* it's something else */
- vungetc(c);
- c = Ctrl_BSL;
- } else if (c == Ctrl_G && p_im)
- continue;
- else {
- if (c == Ctrl_O) {
- ins_ctrl_o();
- ins_at_eol = FALSE; /* cursor keeps its column */
- nomove = TRUE;
- }
- count = 0;
- goto doESCkey;
- }
- }
-
- c = do_digraph(c);
-
- if ((c == Ctrl_V || c == Ctrl_Q) && ctrl_x_mode == CTRL_X_CMDLINE)
- goto docomplete;
- if (c == Ctrl_V || c == Ctrl_Q) {
- ins_ctrl_v();
- c = Ctrl_V; /* pretend CTRL-V is last typed character */
- continue;
- }
-
- if (cindent_on()
- && ctrl_x_mode == 0
- ) {
- /* A key name preceded by a bang means this key is not to be
- * inserted. Skip ahead to the re-indenting below.
- * A key name preceded by a star means that indenting has to be
- * done before inserting the key. */
- line_is_white = inindent(0);
- if (in_cinkeys(c, '!', line_is_white))
- goto force_cindent;
- if (can_cindent && in_cinkeys(c, '*', line_is_white)
- && stop_arrow() == OK)
- do_c_expr_indent();
- }
-
- if (curwin->w_p_rl)
- switch (c) {
- case K_LEFT: c = K_RIGHT; break;
- case K_S_LEFT: c = K_S_RIGHT; break;
- case K_C_LEFT: c = K_C_RIGHT; break;
- case K_RIGHT: c = K_LEFT; break;
- case K_S_RIGHT: c = K_S_LEFT; break;
- case K_C_RIGHT: c = K_C_LEFT; break;
- }
-
- /*
- * If 'keymodel' contains "startsel", may start selection. If it
- * does, a CTRL-O and c will be stuffed, we need to get these
- * characters.
- */
- if (ins_start_select(c))
- continue;
-
- /*
- * The big switch to handle a character in insert mode.
- */
- switch (c) {
- case ESC: /* End input mode */
- if (echeck_abbr(ESC + ABBR_OFF))
- break;
- /*FALLTHROUGH*/
-
- case Ctrl_C: /* End input mode */
- if (c == Ctrl_C && cmdwin_type != 0) {
- /* Close the cmdline window. */
- cmdwin_result = K_IGNORE;
- got_int = FALSE; /* don't stop executing autocommands et al. */
- nomove = TRUE;
- goto doESCkey;
- }
-
-#ifdef UNIX
-do_intr:
-#endif
- /* when 'insertmode' set, and not halfway a mapping, don't leave
- * Insert mode */
- if (goto_im()) {
- if (got_int) {
- (void)vgetc(); /* flush all buffers */
- got_int = FALSE;
- } else
- vim_beep();
- break;
- }
-doESCkey:
- /*
- * This is the ONLY return from edit()!
- */
- /* Always update o_lnum, so that a "CTRL-O ." that adds a line
- * still puts the cursor back after the inserted text. */
- if (ins_at_eol && gchar_cursor() == NUL)
- o_lnum = curwin->w_cursor.lnum;
-
- if (ins_esc(&count, cmdchar, nomove)) {
- if (cmdchar != 'r' && cmdchar != 'v')
- apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL,
- FALSE, curbuf);
- did_cursorhold = FALSE;
- return c == Ctrl_O;
- }
- continue;
-
- case Ctrl_Z: /* suspend when 'insertmode' set */
- if (!p_im)
- goto normalchar; /* insert CTRL-Z as normal char */
- stuffReadbuff((char_u *)":st\r");
- c = Ctrl_O;
- /*FALLTHROUGH*/
-
- case Ctrl_O: /* execute one command */
- if (ctrl_x_mode == CTRL_X_OMNI)
- goto docomplete;
- if (echeck_abbr(Ctrl_O + ABBR_OFF))
- break;
- ins_ctrl_o();
-
- /* don't move the cursor left when 'virtualedit' has "onemore". */
- if (ve_flags & VE_ONEMORE) {
- ins_at_eol = FALSE;
- nomove = TRUE;
- }
- count = 0;
- goto doESCkey;
-
- case K_INS: /* toggle insert/replace mode */
- case K_KINS:
- ins_insert(replaceState);
- break;
-
- case K_SELECT: /* end of Select mode mapping - ignore */
- break;
-
-
- case K_HELP: /* Help key works like <ESC> <Help> */
- case K_F1:
- case K_XF1:
- stuffcharReadbuff(K_HELP);
- if (p_im)
- need_start_insertmode = TRUE;
- goto doESCkey;
-
-
- case K_ZERO: /* Insert the previously inserted text. */
- case NUL:
- case Ctrl_A:
- /* For ^@ the trailing ESC will end the insert, unless there is an
- * error. */
- if (stuff_inserted(NUL, 1L, (c == Ctrl_A)) == FAIL
- && c != Ctrl_A && !p_im)
- goto doESCkey; /* quit insert mode */
- inserted_space = FALSE;
- break;
-
- case Ctrl_R: /* insert the contents of a register */
- ins_reg();
- auto_format(FALSE, TRUE);
- inserted_space = FALSE;
- break;
-
- case Ctrl_G: /* commands starting with CTRL-G */
- ins_ctrl_g();
- break;
-
- case Ctrl_HAT: /* switch input mode and/or langmap */
- ins_ctrl_hat();
- break;
-
- case Ctrl__: /* switch between languages */
- if (!p_ari)
- goto normalchar;
- ins_ctrl_();
- break;
-
- case Ctrl_D: /* Make indent one shiftwidth smaller. */
- if (ctrl_x_mode == CTRL_X_PATH_DEFINES)
- goto docomplete;
- /* FALLTHROUGH */
-
- case Ctrl_T: /* Make indent one shiftwidth greater. */
- if (c == Ctrl_T && ctrl_x_mode == CTRL_X_THESAURUS) {
- if (has_compl_option(FALSE))
- goto docomplete;
- break;
- }
- ins_shift(c, lastc);
- auto_format(FALSE, TRUE);
- inserted_space = FALSE;
- break;
-
- case K_DEL: /* delete character under the cursor */
- case K_KDEL:
- ins_del();
- auto_format(FALSE, TRUE);
- break;
-
- case K_BS: /* delete character before the cursor */
- case Ctrl_H:
- did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space);
- auto_format(FALSE, TRUE);
- break;
-
- case Ctrl_W: /* delete word before the cursor */
- did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space);
- auto_format(FALSE, TRUE);
- break;
-
- case Ctrl_U: /* delete all inserted text in current line */
- /* CTRL-X CTRL-U completes with 'completefunc'. */
- if (ctrl_x_mode == CTRL_X_FUNCTION)
- goto docomplete;
- did_backspace = ins_bs(c, BACKSPACE_LINE, &inserted_space);
- auto_format(FALSE, TRUE);
- inserted_space = FALSE;
- break;
-
- case K_LEFTMOUSE: /* mouse keys */
- case K_LEFTMOUSE_NM:
- case K_LEFTDRAG:
- case K_LEFTRELEASE:
- case K_LEFTRELEASE_NM:
- case K_MIDDLEMOUSE:
- case K_MIDDLEDRAG:
- case K_MIDDLERELEASE:
- case K_RIGHTMOUSE:
- case K_RIGHTDRAG:
- case K_RIGHTRELEASE:
- case K_X1MOUSE:
- case K_X1DRAG:
- case K_X1RELEASE:
- case K_X2MOUSE:
- case K_X2DRAG:
- case K_X2RELEASE:
- ins_mouse(c);
- break;
-
- case K_MOUSEDOWN: /* Default action for scroll wheel up: scroll up */
- ins_mousescroll(MSCR_DOWN);
- break;
-
- case K_MOUSEUP: /* Default action for scroll wheel down: scroll down */
- ins_mousescroll(MSCR_UP);
- break;
-
- case K_MOUSELEFT: /* Scroll wheel left */
- ins_mousescroll(MSCR_LEFT);
- break;
-
- case K_MOUSERIGHT: /* Scroll wheel right */
- ins_mousescroll(MSCR_RIGHT);
- break;
-
- case K_IGNORE: /* Something mapped to nothing */
- break;
-
- case K_CURSORHOLD: /* Didn't type something for a while. */