comparison src/getchar.c @ 18094:a1396a35444c v8.1.2042

patch 8.1.2042: the evalfunc.c file is too big Commit: https://github.com/vim/vim/commit/9c658c9eacbd97e2c071f652a0155f71db94c0f3 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Sep 15 21:00:54 2019 +0200 patch 8.1.2042: the evalfunc.c file is too big Problem: The evalfunc.c file is too big. Solution: Move getchar() and parse_queued_messages() to getchar.c.
author Bram Moolenaar <Bram@vim.org>
date Sun, 15 Sep 2019 21:15:03 +0200
parents 59f8948b7590
children 0d9ec3a2821f
comparison
equal deleted inserted replaced
18093:18c77f2ec0d9 18094:a1396a35444c
1898 ++no_mapping; 1898 ++no_mapping;
1899 retval = vpeekc(); 1899 retval = vpeekc();
1900 --no_mapping; 1900 --no_mapping;
1901 return (retval != NUL); 1901 return (retval != NUL);
1902 } 1902 }
1903
1904 #if defined(FEAT_EVAL) || defined(PROTO)
1905 /*
1906 * "getchar()" function
1907 */
1908 void
1909 f_getchar(typval_T *argvars, typval_T *rettv)
1910 {
1911 varnumber_T n;
1912 int error = FALSE;
1913
1914 #ifdef MESSAGE_QUEUE
1915 // vpeekc() used to check for messages, but that caused problems, invoking
1916 // a callback where it was not expected. Some plugins use getchar(1) in a
1917 // loop to await a message, therefore make sure we check for messages here.
1918 parse_queued_messages();
1919 #endif
1920
1921 /* Position the cursor. Needed after a message that ends in a space. */
1922 windgoto(msg_row, msg_col);
1923
1924 ++no_mapping;
1925 ++allow_keys;
1926 for (;;)
1927 {
1928 if (argvars[0].v_type == VAR_UNKNOWN)
1929 /* getchar(): blocking wait. */
1930 n = plain_vgetc();
1931 else if (tv_get_number_chk(&argvars[0], &error) == 1)
1932 /* getchar(1): only check if char avail */
1933 n = vpeekc_any();
1934 else if (error || vpeekc_any() == NUL)
1935 /* illegal argument or getchar(0) and no char avail: return zero */
1936 n = 0;
1937 else
1938 /* getchar(0) and char avail: return char */
1939 n = plain_vgetc();
1940
1941 if (n == K_IGNORE)
1942 continue;
1943 break;
1944 }
1945 --no_mapping;
1946 --allow_keys;
1947
1948 set_vim_var_nr(VV_MOUSE_WIN, 0);
1949 set_vim_var_nr(VV_MOUSE_WINID, 0);
1950 set_vim_var_nr(VV_MOUSE_LNUM, 0);
1951 set_vim_var_nr(VV_MOUSE_COL, 0);
1952
1953 rettv->vval.v_number = n;
1954 if (IS_SPECIAL(n) || mod_mask != 0)
1955 {
1956 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */
1957 int i = 0;
1958
1959 /* Turn a special key into three bytes, plus modifier. */
1960 if (mod_mask != 0)
1961 {
1962 temp[i++] = K_SPECIAL;
1963 temp[i++] = KS_MODIFIER;
1964 temp[i++] = mod_mask;
1965 }
1966 if (IS_SPECIAL(n))
1967 {
1968 temp[i++] = K_SPECIAL;
1969 temp[i++] = K_SECOND(n);
1970 temp[i++] = K_THIRD(n);
1971 }
1972 else if (has_mbyte)
1973 i += (*mb_char2bytes)(n, temp + i);
1974 else
1975 temp[i++] = n;
1976 temp[i++] = NUL;
1977 rettv->v_type = VAR_STRING;
1978 rettv->vval.v_string = vim_strsave(temp);
1979
1980 #ifdef FEAT_MOUSE
1981 if (is_mouse_key(n))
1982 {
1983 int row = mouse_row;
1984 int col = mouse_col;
1985 win_T *win;
1986 linenr_T lnum;
1987 win_T *wp;
1988 int winnr = 1;
1989
1990 if (row >= 0 && col >= 0)
1991 {
1992 /* Find the window at the mouse coordinates and compute the
1993 * text position. */
1994 win = mouse_find_win(&row, &col, FIND_POPUP);
1995 if (win == NULL)
1996 return;
1997 (void)mouse_comp_pos(win, &row, &col, &lnum, NULL);
1998 # ifdef FEAT_TEXT_PROP
1999 if (WIN_IS_POPUP(win))
2000 winnr = 0;
2001 else
2002 # endif
2003 for (wp = firstwin; wp != win && wp != NULL;
2004 wp = wp->w_next)
2005 ++winnr;
2006 set_vim_var_nr(VV_MOUSE_WIN, winnr);
2007 set_vim_var_nr(VV_MOUSE_WINID, win->w_id);
2008 set_vim_var_nr(VV_MOUSE_LNUM, lnum);
2009 set_vim_var_nr(VV_MOUSE_COL, col + 1);
2010 }
2011 }
2012 #endif
2013 }
2014 }
2015
2016 /*
2017 * "getcharmod()" function
2018 */
2019 void
2020 f_getcharmod(typval_T *argvars UNUSED, typval_T *rettv)
2021 {
2022 rettv->vval.v_number = mod_mask;
2023 }
2024 #endif // FEAT_EVAL
2025
2026 #if defined(MESSAGE_QUEUE) || defined(PROTO)
2027 # define MAX_REPEAT_PARSE 8
2028
2029 /*
2030 * Process messages that have been queued for netbeans or clientserver.
2031 * Also check if any jobs have ended.
2032 * These functions can call arbitrary vimscript and should only be called when
2033 * it is safe to do so.
2034 */
2035 void
2036 parse_queued_messages(void)
2037 {
2038 int old_curwin_id = curwin->w_id;
2039 int old_curbuf_fnum = curbuf->b_fnum;
2040 int i;
2041 int save_may_garbage_collect = may_garbage_collect;
2042
2043 // Do not handle messages while redrawing, because it may cause buffers to
2044 // change or be wiped while they are being redrawn.
2045 if (updating_screen)
2046 return;
2047
2048 // may_garbage_collect is set in main_loop() to do garbage collection when
2049 // blocking to wait on a character. We don't want that while parsing
2050 // messages, a callback may invoke vgetc() while lists and dicts are in use
2051 // in the call stack.
2052 may_garbage_collect = FALSE;
2053
2054 // Loop when a job ended, but don't keep looping forever.
2055 for (i = 0; i < MAX_REPEAT_PARSE; ++i)
2056 {
2057 // For Win32 mch_breakcheck() does not check for input, do it here.
2058 # if defined(MSWIN) && defined(FEAT_JOB_CHANNEL)
2059 channel_handle_events(FALSE);
2060 # endif
2061
2062 # ifdef FEAT_NETBEANS_INTG
2063 // Process the queued netbeans messages.
2064 netbeans_parse_messages();
2065 # endif
2066 # ifdef FEAT_JOB_CHANNEL
2067 // Write any buffer lines still to be written.
2068 channel_write_any_lines();
2069
2070 // Process the messages queued on channels.
2071 channel_parse_messages();
2072 # endif
2073 # if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
2074 // Process the queued clientserver messages.
2075 server_parse_messages();
2076 # endif
2077 # ifdef FEAT_JOB_CHANNEL
2078 // Check if any jobs have ended. If so, repeat the above to handle
2079 // changes, e.g. stdin may have been closed.
2080 if (job_check_ended())
2081 continue;
2082 # endif
2083 # ifdef FEAT_TERMINAL
2084 free_unused_terminals();
2085 # endif
2086 # ifdef FEAT_SOUND_CANBERRA
2087 if (has_sound_callback_in_queue())
2088 invoke_sound_callback();
2089 # endif
2090 break;
2091 }
2092
2093 may_garbage_collect = save_may_garbage_collect;
2094
2095 // If the current window or buffer changed we need to bail out of the
2096 // waiting loop. E.g. when a job exit callback closes the terminal window.
2097 if (curwin->w_id != old_curwin_id || curbuf->b_fnum != old_curbuf_fnum)
2098 ins_char_typebuf(K_IGNORE);
2099 }
2100 #endif
2101
1903 2102
1904 typedef enum { 2103 typedef enum {
1905 map_result_fail, // failed, break loop 2104 map_result_fail, // failed, break loop
1906 map_result_get, // get a character from typeahead 2105 map_result_get, // get a character from typeahead
1907 map_result_retry, // try to map again 2106 map_result_retry, // try to map again
3014 #ifdef FEAT_EVAL 3213 #ifdef FEAT_EVAL
3015 && !ignore_script 3214 && !ignore_script
3016 #endif 3215 #endif
3017 ) 3216 )
3018 { 3217 {
3019
3020 #ifdef MESSAGE_QUEUE 3218 #ifdef MESSAGE_QUEUE
3021 parse_queued_messages(); 3219 parse_queued_messages();
3022 #endif 3220 #endif
3023 3221
3024 if (got_int || (script_char = getc(scriptin[curscript])) < 0) 3222 if (got_int || (script_char = getc(scriptin[curscript])) < 0)