Mercurial > vim
comparison src/edit.c @ 18265:fe5afdc03bd2 v8.1.2127
patch 8.1.2127: the indent.c file is a bit big
Commit: https://github.com/vim/vim/commit/14c01f83487d5c53192297a710eda2b8a4ab17c9
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Oct 9 22:53:08 2019 +0200
patch 8.1.2127: the indent.c file is a bit big
Problem: The indent.c file is a bit big.
Solution: Move C-indent code a a new cindent.c file. Move other
indent-related code to indent.c. (Yegappan Lakshmanan,
closes #5031)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 09 Oct 2019 23:00:04 +0200 |
parents | e0ec4cd7a865 |
children | 9f51d0cef8da |
comparison
equal
deleted
inserted
replaced
18264:5202d9b99bee | 18265:fe5afdc03bd2 |
---|---|
35 #ifdef FEAT_SPELL | 35 #ifdef FEAT_SPELL |
36 static void check_spell_redraw(void); | 36 static void check_spell_redraw(void); |
37 #endif | 37 #endif |
38 static void stop_insert(pos_T *end_insert_pos, int esc, int nomove); | 38 static void stop_insert(pos_T *end_insert_pos, int esc, int nomove); |
39 static int echeck_abbr(int); | 39 static int echeck_abbr(int); |
40 static void replace_join(int off); | |
41 static void mb_replace_pop_ins(int cc); | 40 static void mb_replace_pop_ins(int cc); |
42 static void replace_flush(void); | 41 static void replace_flush(void); |
43 static void replace_do_bs(int limit_col); | 42 static void replace_do_bs(int limit_col); |
44 static int del_char_after_col(int limit_col); | 43 static int del_char_after_col(int limit_col); |
45 static void ins_reg(void); | 44 static void ins_reg(void); |
74 static int ins_tab(void); | 73 static int ins_tab(void); |
75 #ifdef FEAT_DIGRAPHS | 74 #ifdef FEAT_DIGRAPHS |
76 static int ins_digraph(void); | 75 static int ins_digraph(void); |
77 #endif | 76 #endif |
78 static int ins_ctrl_ey(int tc); | 77 static int ins_ctrl_ey(int tc); |
79 #ifdef FEAT_SMARTINDENT | |
80 static void ins_try_si(int c); | |
81 #endif | |
82 #if defined(FEAT_EVAL) | 78 #if defined(FEAT_EVAL) |
83 static char_u *do_insert_char_pre(int c); | 79 static char_u *do_insert_char_pre(int c); |
84 #endif | 80 #endif |
85 | 81 |
86 static colnr_T Insstart_textlen; /* length of line when insert started */ | 82 static colnr_T Insstart_textlen; /* length of line when insert started */ |
94 static int did_restart_edit; /* "restart_edit" when calling edit() */ | 90 static int did_restart_edit; /* "restart_edit" when calling edit() */ |
95 | 91 |
96 #ifdef FEAT_CINDENT | 92 #ifdef FEAT_CINDENT |
97 static int can_cindent; /* may do cindenting on this line */ | 93 static int can_cindent; /* may do cindenting on this line */ |
98 #endif | 94 #endif |
99 | |
100 static int old_indent = 0; /* for ^^D command in insert mode */ | |
101 | 95 |
102 #ifdef FEAT_RIGHTLEFT | 96 #ifdef FEAT_RIGHTLEFT |
103 static int revins_on; /* reverse insert mode on */ | 97 static int revins_on; /* reverse insert mode on */ |
104 static int revins_chars; /* how much to skip after edit */ | 98 static int revins_chars; /* how much to skip after edit */ |
105 static int revins_legal; /* was the last char 'legal'? */ | 99 static int revins_legal; /* was the last char 'legal'? */ |
1757 { | 1751 { |
1758 if (dollar_vcol >= 0) | 1752 if (dollar_vcol >= 0) |
1759 { | 1753 { |
1760 dollar_vcol = -1; | 1754 dollar_vcol = -1; |
1761 redrawWinline(curwin, curwin->w_cursor.lnum); | 1755 redrawWinline(curwin, curwin->w_cursor.lnum); |
1762 } | |
1763 } | |
1764 | |
1765 /* | |
1766 * Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D). | |
1767 * Keep the cursor on the same character. | |
1768 * type == INDENT_INC increase indent (for CTRL-T or <Tab>) | |
1769 * type == INDENT_DEC decrease indent (for CTRL-D) | |
1770 * type == INDENT_SET set indent to "amount" | |
1771 * if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec). | |
1772 */ | |
1773 void | |
1774 change_indent( | |
1775 int type, | |
1776 int amount, | |
1777 int round, | |
1778 int replaced, /* replaced character, put on replace stack */ | |
1779 int call_changed_bytes) /* call changed_bytes() */ | |
1780 { | |
1781 int vcol; | |
1782 int last_vcol; | |
1783 int insstart_less; /* reduction for Insstart.col */ | |
1784 int new_cursor_col; | |
1785 int i; | |
1786 char_u *ptr; | |
1787 int save_p_list; | |
1788 int start_col; | |
1789 colnr_T vc; | |
1790 colnr_T orig_col = 0; /* init for GCC */ | |
1791 char_u *new_line, *orig_line = NULL; /* init for GCC */ | |
1792 | |
1793 /* VREPLACE mode needs to know what the line was like before changing */ | |
1794 if (State & VREPLACE_FLAG) | |
1795 { | |
1796 orig_line = vim_strsave(ml_get_curline()); /* Deal with NULL below */ | |
1797 orig_col = curwin->w_cursor.col; | |
1798 } | |
1799 | |
1800 /* for the following tricks we don't want list mode */ | |
1801 save_p_list = curwin->w_p_list; | |
1802 curwin->w_p_list = FALSE; | |
1803 vc = getvcol_nolist(&curwin->w_cursor); | |
1804 vcol = vc; | |
1805 | |
1806 /* | |
1807 * For Replace mode we need to fix the replace stack later, which is only | |
1808 * possible when the cursor is in the indent. Remember the number of | |
1809 * characters before the cursor if it's possible. | |
1810 */ | |
1811 start_col = curwin->w_cursor.col; | |
1812 | |
1813 /* determine offset from first non-blank */ | |
1814 new_cursor_col = curwin->w_cursor.col; | |
1815 beginline(BL_WHITE); | |
1816 new_cursor_col -= curwin->w_cursor.col; | |
1817 | |
1818 insstart_less = curwin->w_cursor.col; | |
1819 | |
1820 /* | |
1821 * If the cursor is in the indent, compute how many screen columns the | |
1822 * cursor is to the left of the first non-blank. | |
1823 */ | |
1824 if (new_cursor_col < 0) | |
1825 vcol = get_indent() - vcol; | |
1826 | |
1827 if (new_cursor_col > 0) /* can't fix replace stack */ | |
1828 start_col = -1; | |
1829 | |
1830 /* | |
1831 * Set the new indent. The cursor will be put on the first non-blank. | |
1832 */ | |
1833 if (type == INDENT_SET) | |
1834 (void)set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0); | |
1835 else | |
1836 { | |
1837 int save_State = State; | |
1838 | |
1839 /* Avoid being called recursively. */ | |
1840 if (State & VREPLACE_FLAG) | |
1841 State = INSERT; | |
1842 shift_line(type == INDENT_DEC, round, 1, call_changed_bytes); | |
1843 State = save_State; | |
1844 } | |
1845 insstart_less -= curwin->w_cursor.col; | |
1846 | |
1847 /* | |
1848 * Try to put cursor on same character. | |
1849 * If the cursor is at or after the first non-blank in the line, | |
1850 * compute the cursor column relative to the column of the first | |
1851 * non-blank character. | |
1852 * If we are not in insert mode, leave the cursor on the first non-blank. | |
1853 * If the cursor is before the first non-blank, position it relative | |
1854 * to the first non-blank, counted in screen columns. | |
1855 */ | |
1856 if (new_cursor_col >= 0) | |
1857 { | |
1858 /* | |
1859 * When changing the indent while the cursor is touching it, reset | |
1860 * Insstart_col to 0. | |
1861 */ | |
1862 if (new_cursor_col == 0) | |
1863 insstart_less = MAXCOL; | |
1864 new_cursor_col += curwin->w_cursor.col; | |
1865 } | |
1866 else if (!(State & INSERT)) | |
1867 new_cursor_col = curwin->w_cursor.col; | |
1868 else | |
1869 { | |
1870 /* | |
1871 * Compute the screen column where the cursor should be. | |
1872 */ | |
1873 vcol = get_indent() - vcol; | |
1874 curwin->w_virtcol = (colnr_T)((vcol < 0) ? 0 : vcol); | |
1875 | |
1876 /* | |
1877 * Advance the cursor until we reach the right screen column. | |
1878 */ | |
1879 vcol = last_vcol = 0; | |
1880 new_cursor_col = -1; | |
1881 ptr = ml_get_curline(); | |
1882 while (vcol <= (int)curwin->w_virtcol) | |
1883 { | |
1884 last_vcol = vcol; | |
1885 if (has_mbyte && new_cursor_col >= 0) | |
1886 new_cursor_col += (*mb_ptr2len)(ptr + new_cursor_col); | |
1887 else | |
1888 ++new_cursor_col; | |
1889 vcol += lbr_chartabsize(ptr, ptr + new_cursor_col, (colnr_T)vcol); | |
1890 } | |
1891 vcol = last_vcol; | |
1892 | |
1893 /* | |
1894 * May need to insert spaces to be able to position the cursor on | |
1895 * the right screen column. | |
1896 */ | |
1897 if (vcol != (int)curwin->w_virtcol) | |
1898 { | |
1899 curwin->w_cursor.col = (colnr_T)new_cursor_col; | |
1900 i = (int)curwin->w_virtcol - vcol; | |
1901 ptr = alloc(i + 1); | |
1902 if (ptr != NULL) | |
1903 { | |
1904 new_cursor_col += i; | |
1905 ptr[i] = NUL; | |
1906 while (--i >= 0) | |
1907 ptr[i] = ' '; | |
1908 ins_str(ptr); | |
1909 vim_free(ptr); | |
1910 } | |
1911 } | |
1912 | |
1913 /* | |
1914 * When changing the indent while the cursor is in it, reset | |
1915 * Insstart_col to 0. | |
1916 */ | |
1917 insstart_less = MAXCOL; | |
1918 } | |
1919 | |
1920 curwin->w_p_list = save_p_list; | |
1921 | |
1922 if (new_cursor_col <= 0) | |
1923 curwin->w_cursor.col = 0; | |
1924 else | |
1925 curwin->w_cursor.col = (colnr_T)new_cursor_col; | |
1926 curwin->w_set_curswant = TRUE; | |
1927 changed_cline_bef_curs(); | |
1928 | |
1929 /* | |
1930 * May have to adjust the start of the insert. | |
1931 */ | |
1932 if (State & INSERT) | |
1933 { | |
1934 if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0) | |
1935 { | |
1936 if ((int)Insstart.col <= insstart_less) | |
1937 Insstart.col = 0; | |
1938 else | |
1939 Insstart.col -= insstart_less; | |
1940 } | |
1941 if ((int)ai_col <= insstart_less) | |
1942 ai_col = 0; | |
1943 else | |
1944 ai_col -= insstart_less; | |
1945 } | |
1946 | |
1947 /* | |
1948 * For REPLACE mode, may have to fix the replace stack, if it's possible. | |
1949 * If the number of characters before the cursor decreased, need to pop a | |
1950 * few characters from the replace stack. | |
1951 * If the number of characters before the cursor increased, need to push a | |
1952 * few NULs onto the replace stack. | |
1953 */ | |
1954 if (REPLACE_NORMAL(State) && start_col >= 0) | |
1955 { | |
1956 while (start_col > (int)curwin->w_cursor.col) | |
1957 { | |
1958 replace_join(0); /* remove a NUL from the replace stack */ | |
1959 --start_col; | |
1960 } | |
1961 while (start_col < (int)curwin->w_cursor.col || replaced) | |
1962 { | |
1963 replace_push(NUL); | |
1964 if (replaced) | |
1965 { | |
1966 replace_push(replaced); | |
1967 replaced = NUL; | |
1968 } | |
1969 ++start_col; | |
1970 } | |
1971 } | |
1972 | |
1973 /* | |
1974 * For VREPLACE mode, we also have to fix the replace stack. In this case | |
1975 * it is always possible because we backspace over the whole line and then | |
1976 * put it back again the way we wanted it. | |
1977 */ | |
1978 if (State & VREPLACE_FLAG) | |
1979 { | |
1980 /* If orig_line didn't allocate, just return. At least we did the job, | |
1981 * even if you can't backspace. */ | |
1982 if (orig_line == NULL) | |
1983 return; | |
1984 | |
1985 /* Save new line */ | |
1986 new_line = vim_strsave(ml_get_curline()); | |
1987 if (new_line == NULL) | |
1988 return; | |
1989 | |
1990 /* We only put back the new line up to the cursor */ | |
1991 new_line[curwin->w_cursor.col] = NUL; | |
1992 | |
1993 /* Put back original line */ | |
1994 ml_replace(curwin->w_cursor.lnum, orig_line, FALSE); | |
1995 curwin->w_cursor.col = orig_col; | |
1996 | |
1997 /* Backspace from cursor to start of line */ | |
1998 backspace_until_column(0); | |
1999 | |
2000 /* Insert new stuff into line again */ | |
2001 ins_bytes(new_line); | |
2002 | |
2003 vim_free(new_line); | |
2004 } | 1756 } |
2005 } | 1757 } |
2006 | 1758 |
2007 /* | 1759 /* |
2008 * Truncate the space at the end of a line. This is to be used only in an | 1760 * Truncate the space at the end of a line. This is to be used only in an |
3838 | 3590 |
3839 /* | 3591 /* |
3840 * Join the top two items on the replace stack. This removes to "off"'th NUL | 3592 * Join the top two items on the replace stack. This removes to "off"'th NUL |
3841 * encountered. | 3593 * encountered. |
3842 */ | 3594 */ |
3843 static void | 3595 void |
3844 replace_join( | 3596 replace_join( |
3845 int off) /* offset for which NUL to remove */ | 3597 int off) /* offset for which NUL to remove */ |
3846 { | 3598 { |
3847 int i; | 3599 int i; |
3848 | 3600 |
6068 } | 5820 } |
6069 } | 5821 } |
6070 return c; | 5822 return c; |
6071 } | 5823 } |
6072 | 5824 |
6073 #ifdef FEAT_SMARTINDENT | |
6074 /* | |
6075 * Try to do some very smart auto-indenting. | |
6076 * Used when inserting a "normal" character. | |
6077 */ | |
6078 static void | |
6079 ins_try_si(int c) | |
6080 { | |
6081 pos_T *pos, old_pos; | |
6082 char_u *ptr; | |
6083 int i; | |
6084 int temp; | |
6085 | |
6086 /* | |
6087 * do some very smart indenting when entering '{' or '}' | |
6088 */ | |
6089 if (((did_si || can_si_back) && c == '{') || (can_si && c == '}')) | |
6090 { | |
6091 /* | |
6092 * for '}' set indent equal to indent of line containing matching '{' | |
6093 */ | |
6094 if (c == '}' && (pos = findmatch(NULL, '{')) != NULL) | |
6095 { | |
6096 old_pos = curwin->w_cursor; | |
6097 /* | |
6098 * If the matching '{' has a ')' immediately before it (ignoring | |
6099 * white-space), then line up with the start of the line | |
6100 * containing the matching '(' if there is one. This handles the | |
6101 * case where an "if (..\n..) {" statement continues over multiple | |
6102 * lines -- webb | |
6103 */ | |
6104 ptr = ml_get(pos->lnum); | |
6105 i = pos->col; | |
6106 if (i > 0) /* skip blanks before '{' */ | |
6107 while (--i > 0 && VIM_ISWHITE(ptr[i])) | |
6108 ; | |
6109 curwin->w_cursor.lnum = pos->lnum; | |
6110 curwin->w_cursor.col = i; | |
6111 if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL) | |
6112 curwin->w_cursor = *pos; | |
6113 i = get_indent(); | |
6114 curwin->w_cursor = old_pos; | |
6115 if (State & VREPLACE_FLAG) | |
6116 change_indent(INDENT_SET, i, FALSE, NUL, TRUE); | |
6117 else | |
6118 (void)set_indent(i, SIN_CHANGED); | |
6119 } | |
6120 else if (curwin->w_cursor.col > 0) | |
6121 { | |
6122 /* | |
6123 * when inserting '{' after "O" reduce indent, but not | |
6124 * more than indent of previous line | |
6125 */ | |
6126 temp = TRUE; | |
6127 if (c == '{' && can_si_back && curwin->w_cursor.lnum > 1) | |
6128 { | |
6129 old_pos = curwin->w_cursor; | |
6130 i = get_indent(); | |
6131 while (curwin->w_cursor.lnum > 1) | |
6132 { | |
6133 ptr = skipwhite(ml_get(--(curwin->w_cursor.lnum))); | |
6134 | |
6135 /* ignore empty lines and lines starting with '#'. */ | |
6136 if (*ptr != '#' && *ptr != NUL) | |
6137 break; | |
6138 } | |
6139 if (get_indent() >= i) | |
6140 temp = FALSE; | |
6141 curwin->w_cursor = old_pos; | |
6142 } | |
6143 if (temp) | |
6144 shift_line(TRUE, FALSE, 1, TRUE); | |
6145 } | |
6146 } | |
6147 | |
6148 /* | |
6149 * set indent of '#' always to 0 | |
6150 */ | |
6151 if (curwin->w_cursor.col > 0 && can_si && c == '#') | |
6152 { | |
6153 /* remember current indent for next line */ | |
6154 old_indent = get_indent(); | |
6155 (void)set_indent(0, SIN_CHANGED); | |
6156 } | |
6157 | |
6158 /* Adjust ai_col, the char at this position can be deleted. */ | |
6159 if (ai_col > curwin->w_cursor.col) | |
6160 ai_col = curwin->w_cursor.col; | |
6161 } | |
6162 #endif | |
6163 | |
6164 /* | 5825 /* |
6165 * Get the value that w_virtcol would have when 'list' is off. | 5826 * Get the value that w_virtcol would have when 'list' is off. |
6166 * Unless 'cpo' contains the 'L' flag. | 5827 * Unless 'cpo' contains the 'L' flag. |
6167 */ | 5828 */ |
6168 colnr_T | 5829 colnr_T |