Lines Matching refs:gl
292 static int gl_call_fd_handler(GetLine *gl, GlFdHandler *gfh, int fd,
295 static int gl_call_timeout_handler(GetLine *gl);
649 static int gl_check_caught_signal(GetLine *gl);
655 static void gl_suspend_process(int signo, GetLine *gl, int ngl);
678 static void gl_query_size(GetLine *gl, int *ncolumn, int *nline);
684 static int gl_override_signal_handlers(GetLine *gl);
690 static int gl_restore_signal_handlers(GetLine *gl);
696 static int gl_mask_signals(GetLine *gl, sigset_t *oldset);
702 static int gl_unmask_signals(GetLine *gl, sigset_t *oldset);
707 static int gl_catch_signals(GetLine *gl);
718 static int gl_raw_terminal_mode(GetLine *gl);
723 static int gl_restore_terminal_attributes(GetLine *gl);
728 static int gl_nonblocking_io(GetLine *gl, int fd);
733 static int gl_blocking_io(GetLine *gl, int fd);
738 static int gl_get_input_line(GetLine *gl, const char *prompt,
744 static int gl_get_query_char(GetLine *gl, const char *prompt, int defchar);
749 static int gl_read_stream_line(GetLine *gl);
754 static int gl_read_stream_char(GetLine *gl);
759 static int gl_present_line(GetLine *gl, const char *prompt,
765 static void gl_reset_input_line(GetLine *gl);
771 static int gl_interpret_char(GetLine *gl, char c);
776 static int gl_bind_control_char(GetLine *gl, KtBinder binder,
782 static int gl_bind_terminal_keys(GetLine *gl);
787 static int gl_control_strings(GetLine *gl, const char *term);
794 static const char *gl_tigetstr(GetLine *gl, const char *name);
796 static const char *gl_tgetstr(GetLine *gl, const char *name, char **bufptr);
802 static int gl_print_raw_string(GetLine *gl, int buffered,
810 static int gl_print_info(GetLine *gl, ...);
816 static int gl_start_newline(GetLine *gl, int buffered);
821 static int gl_print_control_sequence(GetLine *gl, int nline,
829 static int gl_print_char(GetLine *gl, char c, char pad);
830 static int gl_print_string(GetLine *gl, const char *string, char pad);
836 static int gl_delete_chars(GetLine *gl, int nc, int cut);
842 static int gl_add_char_to_line(GetLine *gl, char c);
848 static int gl_add_string_to_line(GetLine *gl, const char *s);
853 static int gl_buffer_char(GetLine *gl, char c, int bufpos);
858 static int gl_buffer_string(GetLine *gl, const char *s, int n, int bufpos);
863 static int gl_make_gap_in_buffer(GetLine *gl, int start, int n);
869 static void gl_remove_from_buffer(GetLine *gl, int start, int n);
874 static int gl_truncate_buffer(GetLine *gl, int n);
880 static int gl_truncate_display(GetLine *gl);
886 static void gl_update_buffer(GetLine *gl);
891 static int gl_read_terminal(GetLine *gl, int keep, char *c);
896 static void gl_discard_chars(GetLine *gl, int nused);
901 static int gl_terminal_move_cursor(GetLine *gl, int n);
906 static int gl_set_term_curpos(GetLine *gl, int term_curpos);
912 static int gl_place_cursor(GetLine *gl, int buff_curpos);
923 static int gl_displayed_tab_width(GetLine *gl, int term_curpos);
929 static int gl_displayed_char_width(GetLine *gl, char c, int term_curpos);
935 static int gl_displayed_string_width(GetLine *gl, const char *string, int nc,
946 static int _gl_read_config_file(GetLine *gl, const char *filename, KtBinder who);
951 static int _gl_read_config_string(GetLine *gl, const char *buffer, KtBinder who);
966 static int _gl_parse_config_line(GetLine *gl, void *stream, GlcGetcFn *getc_fn,
968 static int gl_report_config_error(GetLine *gl, const char *origin, int lineno,
975 static int _gl_bind_arrow_keys(GetLine *gl);
981 static int _gl_rebind_arrow_key(GetLine *gl, const char *name,
992 static void gl_revert_input(GetLine *gl);
997 static int gl_flush_output(GetLine *gl);
1022 static GlReadStatus gl_read_input(GetLine *gl, char *c);
1026 static int gl_event_handler(GetLine *gl, int fd);
1027 static int gl_read_unmasked(GetLine *gl, int fd, char *c);
1038 static int gl_change_editor(GetLine *gl, GlEditor editor);
1045 static int gl_find_char(GetLine *gl, int count, int forward, int onto, char c);
1050 static int gl_nth_word_end_forward(GetLine *gl, int n);
1055 static int gl_nth_word_start_forward(GetLine *gl, int n);
1060 static int gl_nth_word_start_backward(GetLine *gl, int n);
1067 static void gl_save_for_undo(GetLine *gl);
1072 static void gl_vi_command_mode(GetLine *gl);
1079 static int gl_delete_find(GetLine *gl, int count, char c, int forward,
1086 static int gl_copy_find(GetLine *gl, int count, char c, int forward, int onto);
1093 static int gl_index_of_matching_paren(GetLine *gl);
1117 static int gl_display_prompt(GetLine *gl);
1122 static int gl_displayed_prompt_width(GetLine *gl);
1127 static int gl_line_ended(GetLine *gl, int newline_char);
1133 static void gl_queue_redisplay(GetLine *gl);
1139 static int gl_erase_line(GetLine *gl);
1144 static void gl_line_erased(GetLine *gl);
1149 void _gl_abandon_line(GetLine *gl);
1159 static char *_gl_get_line(GetLine *gl, const char *prompt,
1161 static int _gl_query_char(GetLine *gl, const char *prompt, char defchar);
1162 static int _gl_read_char(GetLine *gl);
1163 static int _gl_update_size(GetLine *gl);
1168 static int gl_handle_tty_resize(GetLine *gl, int ncolumn, int nline);
1170 static int _gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp,
1172 static int _gl_configure_getline(GetLine *gl, const char *app_string,
1174 static int _gl_save_history(GetLine *gl, const char *filename,
1176 static int _gl_load_history(GetLine *gl, const char *filename,
1178 static int _gl_watch_fd(GetLine *gl, int fd, GlFdEvent event,
1180 static void _gl_terminal_size(GetLine *gl, int def_ncolumn, int def_nline,
1182 static void _gl_replace_prompt(GetLine *gl, const char *prompt);
1183 static int _gl_trap_signal(GetLine *gl, int signo, unsigned flags,
1185 static int _gl_raw_io(GetLine *gl, int redisplay);
1186 static int _gl_normal_io(GetLine *gl);
1187 static int _gl_completion_action(GetLine *gl, void *data, CplMatchFn *match_fn,
1190 static int _gl_register_action(GetLine *gl, void *data, GlActionFn *fn,
1192 static int _gl_io_mode(GetLine *gl, GlIOMode mode);
1193 static int _gl_set_term_size(GetLine *gl, int ncolumn, int nline);
1194 static int _gl_append_history(GetLine *gl, const char *line);
1200 static void gl_clear_status(GetLine *gl);
1206 static void gl_record_status(GetLine *gl, GlReturnStatus rtn_status,
1726 GetLine *gl; /* The object to be returned */ in new_GetLine() local
1738 gl = (GetLine *) malloc(sizeof(GetLine)); in new_GetLine()
1739 if(!gl) { in new_GetLine()
1748 gl->err = NULL; in new_GetLine()
1749 gl->glh = NULL; in new_GetLine()
1750 gl->cpl = NULL; in new_GetLine()
1752 gl->cplfn.fn = cpl_file_completions; in new_GetLine()
1754 gl->cplfn.fn = gl_no_completions; in new_GetLine()
1756 gl->cplfn.data = NULL; in new_GetLine()
1758 gl->ef = NULL; in new_GetLine()
1760 gl->capmem = NULL; in new_GetLine()
1761 gl->cq = NULL; in new_GetLine()
1762 gl->input_fd = -1; in new_GetLine()
1763 gl->output_fd = -1; in new_GetLine()
1764 gl->input_fp = NULL; in new_GetLine()
1765 gl->output_fp = NULL; in new_GetLine()
1766 gl->file_fp = NULL; in new_GetLine()
1767 gl->term = NULL; in new_GetLine()
1768 gl->is_term = 0; in new_GetLine()
1769 gl->flush_fn = gl_flush_terminal; in new_GetLine()
1770 gl->io_mode = GL_NORMAL_MODE; in new_GetLine()
1771 gl->raw_mode = 0; in new_GetLine()
1772 gl->pending_io = GLP_WRITE; /* We will start by writing the prompt */ in new_GetLine()
1773 gl_clear_status(gl); in new_GetLine()
1774 gl->linelen = linelen; in new_GetLine()
1775 gl->line = NULL; in new_GetLine()
1776 gl->cutbuf = NULL; in new_GetLine()
1777 gl->prompt = NULL; in new_GetLine()
1778 gl->prompt_len = 0; in new_GetLine()
1779 gl->prompt_changed = 0; in new_GetLine()
1780 gl->prompt_style = GL_LITERAL_PROMPT; in new_GetLine()
1781 gl->cpl_mem = NULL; in new_GetLine()
1782 gl->ext_act_mem = NULL; in new_GetLine()
1783 gl->sig_mem = NULL; in new_GetLine()
1784 gl->sigs = NULL; in new_GetLine()
1785 gl->signals_masked = 0; in new_GetLine()
1786 gl->signals_overriden = 0; in new_GetLine()
1787 sigemptyset(&gl->all_signal_set); in new_GetLine()
1788 sigemptyset(&gl->old_signal_set); in new_GetLine()
1789 sigemptyset(&gl->use_signal_set); in new_GetLine()
1790 gl->bindings = NULL; in new_GetLine()
1791 gl->ntotal = 0; in new_GetLine()
1792 gl->buff_curpos = 0; in new_GetLine()
1793 gl->term_curpos = 0; in new_GetLine()
1794 gl->term_len = 0; in new_GetLine()
1795 gl->buff_mark = 0; in new_GetLine()
1796 gl->insert_curpos = 0; in new_GetLine()
1797 gl->insert = 1; in new_GetLine()
1798 gl->number = -1; in new_GetLine()
1799 gl->endline = 1; in new_GetLine()
1800 gl->displayed = 0; in new_GetLine()
1801 gl->redisplay = 0; in new_GetLine()
1802 gl->postpone = 0; in new_GetLine()
1803 gl->keybuf[0]='\0'; in new_GetLine()
1804 gl->nbuf = 0; in new_GetLine()
1805 gl->nread = 0; in new_GetLine()
1806 gl->current_action.fn = 0; in new_GetLine()
1807 gl->current_action.data = NULL; in new_GetLine()
1808 gl->current_count = 0; in new_GetLine()
1809 gl->preload_id = 0; in new_GetLine()
1810 gl->preload_history = 0; in new_GetLine()
1811 gl->keyseq_count = 0; in new_GetLine()
1812 gl->last_search = -1; in new_GetLine()
1813 gl->editor = GL_EMACS_MODE; in new_GetLine()
1814 gl->silence_bell = 0; in new_GetLine()
1815 gl->automatic_history = 1; in new_GetLine()
1816 gl->vi.undo.line = NULL; in new_GetLine()
1817 gl->vi.undo.buff_curpos = 0; in new_GetLine()
1818 gl->vi.undo.ntotal = 0; in new_GetLine()
1819 gl->vi.undo.saved = 0; in new_GetLine()
1820 gl->vi.repeat.action.fn = 0; in new_GetLine()
1821 gl->vi.repeat.action.data = 0; in new_GetLine()
1822 gl->vi.repeat.count = 0; in new_GetLine()
1823 gl->vi.repeat.input_curpos = 0; in new_GetLine()
1824 gl->vi.repeat.command_curpos = 0; in new_GetLine()
1825 gl->vi.repeat.input_char = '\0'; in new_GetLine()
1826 gl->vi.repeat.saved = 0; in new_GetLine()
1827 gl->vi.repeat.active = 0; in new_GetLine()
1828 gl->vi.command = 0; in new_GetLine()
1829 gl->vi.find_forward = 0; in new_GetLine()
1830 gl->vi.find_onto = 0; in new_GetLine()
1831 gl->vi.find_char = '\0'; in new_GetLine()
1832 gl->left = NULL; in new_GetLine()
1833 gl->right = NULL; in new_GetLine()
1834 gl->up = NULL; in new_GetLine()
1835 gl->down = NULL; in new_GetLine()
1836 gl->home = NULL; in new_GetLine()
1837 gl->bol = 0; in new_GetLine()
1838 gl->clear_eol = NULL; in new_GetLine()
1839 gl->clear_eod = NULL; in new_GetLine()
1840 gl->u_arrow = NULL; in new_GetLine()
1841 gl->d_arrow = NULL; in new_GetLine()
1842 gl->l_arrow = NULL; in new_GetLine()
1843 gl->r_arrow = NULL; in new_GetLine()
1844 gl->sound_bell = NULL; in new_GetLine()
1845 gl->bold = NULL; in new_GetLine()
1846 gl->underline = NULL; in new_GetLine()
1847 gl->standout = NULL; in new_GetLine()
1848 gl->dim = NULL; in new_GetLine()
1849 gl->reverse = NULL; in new_GetLine()
1850 gl->blink = NULL; in new_GetLine()
1851 gl->text_attr_off = NULL; in new_GetLine()
1852 gl->nline = 0; in new_GetLine()
1853 gl->ncolumn = 0; in new_GetLine()
1855 gl->left_n = NULL; in new_GetLine()
1856 gl->right_n = NULL; in new_GetLine()
1858 gl->tgetent_buf = NULL; in new_GetLine()
1859 gl->tgetstr_buf = NULL; in new_GetLine()
1861 gl->app_file = NULL; in new_GetLine()
1862 gl->user_file = NULL; in new_GetLine()
1863 gl->configured = 0; in new_GetLine()
1864 gl->echo = 1; in new_GetLine()
1865 gl->last_signal = -1; in new_GetLine()
1867 gl->fd_node_mem = NULL; in new_GetLine()
1868 gl->fd_nodes = NULL; in new_GetLine()
1869 FD_ZERO(&gl->rfds); in new_GetLine()
1870 FD_ZERO(&gl->wfds); in new_GetLine()
1871 FD_ZERO(&gl->ufds); in new_GetLine()
1872 gl->max_fd = 0; in new_GetLine()
1873 gl->timer.dt.tv_sec = 0; in new_GetLine()
1874 gl->timer.dt.tv_usec = 0; in new_GetLine()
1875 gl->timer.fn = 0; in new_GetLine()
1876 gl->timer.data = NULL; in new_GetLine()
1881 gl->err = _new_ErrMsg(); in new_GetLine()
1882 if(!gl->err) in new_GetLine()
1883 return del_GetLine(gl); in new_GetLine()
1887 gl->glh = _new_GlHistory(histlen); in new_GetLine()
1888 if(!gl->glh) in new_GetLine()
1889 return del_GetLine(gl); in new_GetLine()
1893 gl->cpl = new_WordCompletion(); in new_GetLine()
1894 if(!gl->cpl) in new_GetLine()
1895 return del_GetLine(gl); in new_GetLine()
1900 gl->ef = new_ExpandFile(); in new_GetLine()
1901 if(!gl->ef) in new_GetLine()
1902 return del_GetLine(gl); in new_GetLine()
1908 gl->capmem = _new_StringGroup(CAPMEM_SEGMENT_SIZE); in new_GetLine()
1909 if(!gl->capmem) in new_GetLine()
1910 return del_GetLine(gl); in new_GetLine()
1914 gl->cq = _new_GlCharQueue(); in new_GetLine()
1915 if(!gl->cq) in new_GetLine()
1916 return del_GetLine(gl); in new_GetLine()
1921 gl->line = (char *) malloc(linelen + 2); in new_GetLine()
1922 if(!gl->line) { in new_GetLine()
1924 return del_GetLine(gl); in new_GetLine()
1929 gl_truncate_buffer(gl, 0); in new_GetLine()
1933 gl->cutbuf = (char *) malloc(linelen + 2); in new_GetLine()
1934 if(!gl->cutbuf) { in new_GetLine()
1936 return del_GetLine(gl); in new_GetLine()
1938 gl->cutbuf[0] = '\0'; in new_GetLine()
1942 _gl_replace_prompt(gl, NULL); in new_GetLine()
1943 if(!gl->prompt) { in new_GetLine()
1945 return del_GetLine(gl); in new_GetLine()
1950 gl->vi.undo.line = (char *) malloc(linelen + 2); in new_GetLine()
1951 if(!gl->vi.undo.line) { in new_GetLine()
1953 return del_GetLine(gl); in new_GetLine()
1955 gl->vi.undo.line[0] = '\0'; in new_GetLine()
1960 gl->cpl_mem = _new_FreeList(sizeof(GlCplCallback), GL_CPL_FREELIST_BLOCKING); in new_GetLine()
1961 if(!gl->cpl_mem) in new_GetLine()
1962 return del_GetLine(gl); in new_GetLine()
1967 gl->ext_act_mem = _new_FreeList(sizeof(GlExternalAction), in new_GetLine()
1969 if(!gl->ext_act_mem) in new_GetLine()
1970 return del_GetLine(gl); in new_GetLine()
1975 gl->sig_mem = _new_FreeList(sizeof(GlSignalNode), GLS_FREELIST_BLOCKING); in new_GetLine()
1976 if(!gl->sig_mem) in new_GetLine()
1977 return del_GetLine(gl); in new_GetLine()
1984 if(_gl_trap_signal(gl, sig->signo, sig->flags, sig->after, in new_GetLine()
1986 return del_GetLine(gl); in new_GetLine()
1991 gl->bindings = _new_KeyTab(); in new_GetLine()
1992 if(!gl->bindings) in new_GetLine()
1993 return del_GetLine(gl); in new_GetLine()
1998 if(_kt_set_action(gl->bindings, gl_actions[i].name, gl_actions[i].fn, NULL)) in new_GetLine()
1999 return del_GetLine(gl); in new_GetLine()
2004 if(gl_change_editor(gl, gl->editor)) in new_GetLine()
2005 return del_GetLine(gl); in new_GetLine()
2010 gl->tgetent_buf = (char *) malloc(TERMCAP_BUF_SIZE); in new_GetLine()
2011 gl->tgetstr_buf = (char *) malloc(TERMCAP_BUF_SIZE); in new_GetLine()
2012 if(!gl->tgetent_buf || !gl->tgetstr_buf) { in new_GetLine()
2014 return del_GetLine(gl); in new_GetLine()
2020 if(_gl_change_terminal(gl, stdin, stdout, getenv("TERM"))) in new_GetLine()
2021 return del_GetLine(gl); in new_GetLine()
2026 gl->fd_node_mem = _new_FreeList(sizeof(GlFdNode), GLFD_FREELIST_BLOCKING); in new_GetLine()
2027 if(!gl->fd_node_mem) in new_GetLine()
2028 return del_GetLine(gl); in new_GetLine()
2033 return gl; in new_GetLine()
2044 GetLine *del_GetLine(GetLine *gl) in del_GetLine() argument
2046 if(gl) { in del_GetLine()
2050 _gl_normal_io(gl); in del_GetLine()
2054 gl->err = _del_ErrMsg(gl->err); in del_GetLine()
2055 gl->glh = _del_GlHistory(gl->glh); in del_GetLine()
2056 gl->cpl = del_WordCompletion(gl->cpl); in del_GetLine()
2058 gl->ef = del_ExpandFile(gl->ef); in del_GetLine()
2060 gl->capmem = _del_StringGroup(gl->capmem); in del_GetLine()
2061 gl->cq = _del_GlCharQueue(gl->cq); in del_GetLine()
2062 if(gl->file_fp) in del_GetLine()
2063 fclose(gl->file_fp); in del_GetLine()
2064 if(gl->term) in del_GetLine()
2065 free(gl->term); in del_GetLine()
2066 if(gl->line) in del_GetLine()
2067 free(gl->line); in del_GetLine()
2068 if(gl->cutbuf) in del_GetLine()
2069 free(gl->cutbuf); in del_GetLine()
2070 if(gl->prompt) in del_GetLine()
2071 free(gl->prompt); in del_GetLine()
2072 gl->cpl_mem = _del_FreeList(gl->cpl_mem, 1); in del_GetLine()
2073 gl->ext_act_mem = _del_FreeList(gl->ext_act_mem, 1); in del_GetLine()
2074 gl->sig_mem = _del_FreeList(gl->sig_mem, 1); in del_GetLine()
2075 gl->sigs = NULL; /* Already freed by freeing sig_mem */ in del_GetLine()
2076 gl->bindings = _del_KeyTab(gl->bindings); in del_GetLine()
2077 if(gl->vi.undo.line) in del_GetLine()
2078 free(gl->vi.undo.line); in del_GetLine()
2080 if(gl->tgetent_buf) in del_GetLine()
2081 free(gl->tgetent_buf); in del_GetLine()
2082 if(gl->tgetstr_buf) in del_GetLine()
2083 free(gl->tgetstr_buf); in del_GetLine()
2085 if(gl->app_file) in del_GetLine()
2086 free(gl->app_file); in del_GetLine()
2087 if(gl->user_file) in del_GetLine()
2088 free(gl->user_file); in del_GetLine()
2090 gl->fd_node_mem = _del_FreeList(gl->fd_node_mem, 1); in del_GetLine()
2091 gl->fd_nodes = NULL; /* Already freed by freeing gl->fd_node_mem */ in del_GetLine()
2096 free(gl); in del_GetLine()
2114 static int gl_bind_control_char(GetLine *gl, KtBinder binder, char c, in gl_bind_control_char() argument
2137 if(_kt_set_keybinding(gl->bindings, binder, keyseq, action)) { in gl_bind_control_char()
2138 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG); in gl_bind_control_char()
2166 char *gl_get_line(GetLine *gl, const char *prompt, in gl_get_line() argument
2173 if(!gl) { in gl_get_line()
2180 if(gl_mask_signals(gl, &gl->old_signal_set)) in gl_get_line()
2185 retval = _gl_get_line(gl, prompt, start_line, start_pos); in gl_get_line()
2190 gl_unmask_signals(gl, &gl->old_signal_set); in gl_get_line()
2198 static char *_gl_get_line(GetLine *gl, const char *prompt, in _gl_get_line() argument
2206 gl_clear_status(gl); in _gl_get_line()
2211 if(!gl->configured) { in _gl_get_line()
2212 (void) _gl_configure_getline(gl, NULL, NULL, TECLA_CONFIG_FILE); in _gl_get_line()
2213 gl->configured = 1; in _gl_get_line()
2225 waserr = gl_override_signal_handlers(gl); in _gl_get_line()
2230 waserr = waserr || _gl_raw_io(gl, 1); in _gl_get_line()
2240 if(gl->file_fp || !gl->is_term) { in _gl_get_line()
2241 if(gl_read_stream_line(gl)==0) { in _gl_get_line()
2243 } else if(gl->file_fp) { in _gl_get_line()
2244 gl_revert_input(gl); in _gl_get_line()
2245 gl_record_status(gl, GLR_NEWLINE, 0); in _gl_get_line()
2256 if(!gl->file_fp && gl->is_term) { in _gl_get_line()
2257 if(gl_get_input_line(gl, prompt, start_line, start_pos)) in _gl_get_line()
2271 if(waserr && gl->rtn_status == GLR_NEWLINE) in _gl_get_line()
2272 gl_record_status(gl, GLR_ERROR, errno); in _gl_get_line()
2276 if(gl->io_mode != GL_SERVER_MODE) in _gl_get_line()
2277 _gl_normal_io(gl); in _gl_get_line()
2281 gl_restore_signal_handlers(gl); in _gl_get_line()
2290 errno = gl->rtn_errno; in _gl_get_line()
2294 switch(gl->rtn_status) { in _gl_get_line()
2296 return gl->line; in _gl_get_line()
2301 if(gl->io_mode != GL_SERVER_MODE) in _gl_get_line()
2302 _gl_abandon_line(gl); in _gl_get_line()
2307 _gl_abandon_line(gl); in _gl_get_line()
2327 int gl_query_char(GetLine *gl, const char *prompt, char defchar) in gl_query_char() argument
2333 if(!gl) { in gl_query_char()
2340 if(gl_mask_signals(gl, &gl->old_signal_set)) in gl_query_char()
2345 retval = _gl_query_char(gl, prompt, defchar); in gl_query_char()
2350 gl_unmask_signals(gl, &gl->old_signal_set); in gl_query_char()
2357 static int _gl_query_char(GetLine *gl, const char *prompt, char defchar) in _gl_query_char() argument
2365 gl_clear_status(gl); in _gl_query_char()
2370 if(!gl->configured) { in _gl_query_char()
2371 (void) _gl_configure_getline(gl, NULL, NULL, TECLA_CONFIG_FILE); in _gl_query_char()
2372 gl->configured = 1; in _gl_query_char()
2384 waserr = gl_override_signal_handlers(gl); in _gl_query_char()
2390 waserr = waserr || _gl_raw_io(gl, 0); in _gl_query_char()
2400 if(gl->file_fp || !gl->is_term) { in _gl_query_char()
2401 c = gl_read_stream_char(gl); in _gl_query_char()
2405 } else if(gl->file_fp) { /* End of temporary input file? */ in _gl_query_char()
2406 gl_revert_input(gl); in _gl_query_char()
2407 gl_record_status(gl, GLR_NEWLINE, 0); in _gl_query_char()
2418 if(!gl->file_fp && gl->is_term) { in _gl_query_char()
2419 c = gl_get_query_char(gl, prompt, defchar); in _gl_query_char()
2434 if(waserr && gl->rtn_status == GLR_NEWLINE) in _gl_query_char()
2435 gl_record_status(gl, GLR_ERROR, errno); in _gl_query_char()
2439 if(gl->io_mode != GL_SERVER_MODE) in _gl_query_char()
2440 _gl_normal_io(gl); in _gl_query_char()
2444 gl_restore_signal_handlers(gl); in _gl_query_char()
2453 errno = gl->rtn_errno; in _gl_query_char()
2458 if(gl->rtn_status != GLR_NEWLINE) in _gl_query_char()
2465 _gl_abandon_line(gl); in _gl_query_char()
2482 static int gl_override_signal_handlers(GetLine *gl) in gl_override_signal_handlers() argument
2490 memcpy(&act.sa_mask, &gl->all_signal_set, sizeof(sigset_t)); in gl_override_signal_handlers()
2496 sigemptyset(&gl->use_signal_set); in gl_override_signal_handlers()
2497 for(sig=gl->sigs; sig; sig=sig->next) { in gl_override_signal_handlers()
2503 !sigismember(&gl->old_signal_set, sig->signo)) { in gl_override_signal_handlers()
2504 if(sigaddset(&gl->use_signal_set, sig->signo) == -1) { in gl_override_signal_handlers()
2505 _err_record_msg(gl->err, "sigaddset error", END_ERR_MSG); in gl_override_signal_handlers()
2513 for(sig=gl->sigs; sig; sig=sig->next) { in gl_override_signal_handlers()
2514 if(sigismember(&gl->use_signal_set, sig->signo)) { in gl_override_signal_handlers()
2517 _err_record_msg(gl->err, "sigaction error", END_ERR_MSG); in gl_override_signal_handlers()
2527 gl->signals_overriden = 1; in gl_override_signal_handlers()
2533 if(_gl_update_size(gl)) in gl_override_signal_handlers()
2547 static int gl_restore_signal_handlers(GetLine *gl) in gl_restore_signal_handlers() argument
2554 for(sig=gl->sigs; sig; sig=sig->next) { in gl_restore_signal_handlers()
2555 if(sigismember(&gl->use_signal_set, sig->signo) && in gl_restore_signal_handlers()
2557 _err_record_msg(gl->err, "sigaction error", END_ERR_MSG); in gl_restore_signal_handlers()
2565 gl->signals_overriden = 0; in gl_restore_signal_handlers()
2589 static int gl_raw_terminal_mode(GetLine *gl) in gl_raw_terminal_mode() argument
2595 if(gl->raw_mode) in gl_raw_terminal_mode()
2600 if(tcgetattr(gl->input_fd, &gl->oldattr)) { in gl_raw_terminal_mode()
2601 _err_record_msg(gl->err, "tcgetattr error", END_ERR_MSG); in gl_raw_terminal_mode()
2608 if(gl->editor == GL_NO_EDITOR) in gl_raw_terminal_mode()
2613 newattr = gl->oldattr; in gl_raw_terminal_mode()
2635 newattr.c_cc[VMIN] = gl->io_mode==GL_SERVER_MODE ? 0:1; in gl_raw_terminal_mode()
2640 while(tcsetattr(gl->input_fd, TCSADRAIN, &newattr)) { in gl_raw_terminal_mode()
2642 _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG); in gl_raw_terminal_mode()
2649 gl->raw_mode = 1; in gl_raw_terminal_mode()
2662 static int gl_restore_terminal_attributes(GetLine *gl) in gl_restore_terminal_attributes() argument
2668 if(!gl->raw_mode) in gl_restore_terminal_attributes()
2674 if(gl_flush_output(gl)) in gl_restore_terminal_attributes()
2680 while(tcsetattr(gl->input_fd, TCSADRAIN, &gl->oldattr)) { in gl_restore_terminal_attributes()
2682 _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG); in gl_restore_terminal_attributes()
2690 gl->raw_mode = 0; in gl_restore_terminal_attributes()
2701 static int gl_nonblocking_io(GetLine *gl, int fd) in gl_nonblocking_io() argument
2723 _err_record_msg(gl->err, "fcntl error", END_ERR_MSG); in gl_nonblocking_io()
2737 static int gl_blocking_io(GetLine *gl, int fd) in gl_blocking_io() argument
2753 _err_record_msg(gl->err, "fcntl error", END_ERR_MSG); in gl_blocking_io()
2779 static int gl_get_input_line(GetLine *gl, const char *prompt, in gl_get_input_line() argument
2786 if(_glq_char_count(gl->cq) > 0 && gl_flush_output(gl)) in gl_get_input_line()
2791 if(gl->endline) { in gl_get_input_line()
2795 if(gl_erase_line(gl)) in gl_get_input_line()
2800 if(gl_present_line(gl, prompt, start_line, start_pos)) in gl_get_input_line()
2806 while(gl_read_terminal(gl, 1, &c) == 0) { in gl_get_input_line()
2810 gl->keyseq_count++; in gl_get_input_line()
2816 if(gl_interpret_char(gl, c)) in gl_get_input_line()
2822 if(gl->file_fp) in gl_get_input_line()
2827 if(gl->endline) in gl_get_input_line()
2828 return gl_line_ended(gl, c); in gl_get_input_line()
2835 if(gl->endline) in gl_get_input_line()
2836 return gl_line_ended(gl, '\n'); in gl_get_input_line()
2843 if(gl->rtn_status == GLR_BLOCKED && gl->pending_io == GLP_READ) in gl_get_input_line()
2844 gl->nread = 0; in gl_get_input_line()
2863 static int gl_get_query_char(GetLine *gl, const char *prompt, int defchar) in gl_get_query_char() argument
2870 if(_glq_char_count(gl->cq) > 0 && gl_flush_output(gl)) in gl_get_query_char()
2875 if(gl_erase_line(gl)) in gl_get_query_char()
2880 if(gl_present_line(gl, prompt, NULL, 0)) in gl_get_query_char()
2885 if(gl_read_terminal(gl, 1, &c) == 0) { in gl_get_query_char()
2889 gl->keyseq_count++; in gl_get_query_char()
2893 gl_discard_chars(gl, gl->nread); in gl_get_query_char()
2908 if(gl_end_of_line(gl, 1, NULL)==0) in gl_get_query_char()
2909 gl_print_char(gl, c, ' '); in gl_get_query_char()
2915 gl_record_status(gl, GLR_NEWLINE, 0); in gl_get_query_char()
2920 } else if(gl->endline) { in gl_get_query_char()
2922 gl_record_status(gl, GLR_NEWLINE, 0); in gl_get_query_char()
2929 if(gl_start_newline(gl, 1)) in gl_get_query_char()
2934 (void) gl_flush_output(gl); in gl_get_query_char()
2952 static int gl_add_char_to_line(GetLine *gl, char c) in gl_add_char_to_line() argument
2957 int buff_curpos = gl->buff_curpos; in gl_add_char_to_line()
2958 int term_curpos = gl->term_curpos; in gl_add_char_to_line()
2962 int width = gl_displayed_char_width(gl, c, term_curpos); in gl_add_char_to_line()
2969 if((gl->insert || buff_curpos >= gl->ntotal) && gl->ntotal >= gl->linelen) in gl_add_char_to_line()
2974 if(gl->insert || buff_curpos >= gl->ntotal) { in gl_add_char_to_line()
2978 if(buff_curpos < gl->ntotal) in gl_add_char_to_line()
2979 gl_make_gap_in_buffer(gl, buff_curpos, 1); in gl_add_char_to_line()
2983 gl_buffer_char(gl, c, buff_curpos); in gl_add_char_to_line()
2984 gl->buff_curpos++; in gl_add_char_to_line()
2989 if(gl_print_string(gl, gl->line + buff_curpos, '\0') || in gl_add_char_to_line()
2990 gl_set_term_curpos(gl, term_curpos + width)) in gl_add_char_to_line()
2999 int old_width = gl_displayed_char_width(gl, gl->line[buff_curpos], in gl_add_char_to_line()
3004 gl_buffer_char(gl, c, buff_curpos); in gl_add_char_to_line()
3012 if(gl_print_string(gl, gl->line + buff_curpos, '\0')) in gl_add_char_to_line()
3017 if(gl_truncate_display(gl)) in gl_add_char_to_line()
3022 if(gl_set_term_curpos(gl, term_curpos + width)) in gl_add_char_to_line()
3024 gl->buff_curpos++; in gl_add_char_to_line()
3034 if(gl_print_string(gl, gl->line + buff_curpos, '\0') || in gl_add_char_to_line()
3035 gl_set_term_curpos(gl, term_curpos + width)) in gl_add_char_to_line()
3037 gl->buff_curpos++; in gl_add_char_to_line()
3046 gl_buffer_char(gl, c, buff_curpos); in gl_add_char_to_line()
3047 gl->buff_curpos++; in gl_add_char_to_line()
3051 if(gl_print_char(gl, c, gl->line[gl->buff_curpos])) in gl_add_char_to_line()
3069 static int gl_add_string_to_line(GetLine *gl, const char *s) in gl_add_string_to_line() argument
3078 buff_curpos = gl->buff_curpos; in gl_add_string_to_line()
3079 term_curpos = gl->term_curpos; in gl_add_string_to_line()
3084 term_slen = gl_displayed_string_width(gl, s, buff_slen, term_curpos); in gl_add_string_to_line()
3090 if(gl->ntotal + buff_slen > gl->linelen) in gl_add_string_to_line()
3096 if(gl->ntotal > gl->buff_curpos) in gl_add_string_to_line()
3097 gl_make_gap_in_buffer(gl, gl->buff_curpos, buff_slen); in gl_add_string_to_line()
3101 gl_buffer_string(gl, s, buff_slen, gl->buff_curpos); in gl_add_string_to_line()
3102 gl->buff_curpos += buff_slen; in gl_add_string_to_line()
3107 if(gl_print_string(gl, gl->line + buff_curpos, '\0') || in gl_add_string_to_line()
3108 gl_set_term_curpos(gl, term_curpos + term_slen)) in gl_add_string_to_line()
3133 static int gl_read_terminal(GetLine *gl, int keep, char *c) in gl_read_terminal() argument
3139 if(gl_flush_output(gl)) in gl_read_terminal()
3144 gl->pending_io = GLP_READ; in gl_read_terminal()
3149 if(gl->nread < gl->nbuf) { in gl_read_terminal()
3150 *c = gl->keybuf[gl->nread]; in gl_read_terminal()
3155 gl->nread++; in gl_read_terminal()
3160 memmove(gl->keybuf + gl->nread, gl->keybuf + gl->nread + 1, in gl_read_terminal()
3161 gl->nbuf - gl->nread - 1); in gl_read_terminal()
3171 if(gl->nbuf + 1 > GL_KEY_MAX) { in gl_read_terminal()
3172 gl_print_info(gl, "gl_read_terminal: Buffer overflow avoided.", in gl_read_terminal()
3180 switch(gl_read_input(gl, c)) { in gl_read_terminal()
3184 gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO); in gl_read_terminal()
3195 gl->keybuf[gl->nbuf] = *c; in gl_read_terminal()
3196 gl->nread = ++gl->nbuf; in gl_read_terminal()
3210 static GlReadStatus gl_read_input(GetLine *gl, char *c) in gl_read_input() argument
3220 volatile int fd = gl->file_fp ? fileno(gl->file_fp) : gl->input_fd; in gl_read_input()
3224 if(gl->endline) in gl_read_input()
3233 switch(gl->io_mode) { in gl_read_input()
3239 if(gl_event_handler(gl, fd)) in gl_read_input()
3241 return gl_read_unmasked(gl, fd, c); /* Read one character */ in gl_read_input()
3258 gl_blocking_io(gl, fd); /* switch to blocking I/O */ in gl_read_input()
3259 status = gl_read_unmasked(gl, fd, c); /* Try reading */ in gl_read_input()
3261 if(gl_event_handler(gl, fd)) /* Wait for input */ in gl_read_input()
3264 status = gl_read_unmasked(gl, fd, c); /* Try reading again */ in gl_read_input()
3266 gl_nonblocking_io(gl, fd); /* Restore non-blocking I/O */ in gl_read_input()
3281 if(gl->io_mode == GL_SERVER_MODE) in gl_read_input()
3282 gl_nonblocking_io(gl, fd); in gl_read_input()
3286 if(gl_check_caught_signal(gl)) in gl_read_input()
3303 static int gl_read_unmasked(GetLine *gl, int fd, char *c) in gl_read_unmasked() argument
3309 gl_catch_signals(gl); in gl_read_unmasked()
3321 gl_mask_signals(gl, NULL); in gl_read_unmasked()
3345 static void gl_discard_chars(GetLine *gl, int nused) in gl_discard_chars() argument
3347 int nkeep = gl->nbuf - nused; in gl_discard_chars()
3349 memmove(gl->keybuf, gl->keybuf + nused, nkeep); in gl_discard_chars()
3350 gl->nbuf = nkeep; in gl_discard_chars()
3351 gl->nread = 0; in gl_discard_chars()
3353 gl->nbuf = gl->nread = 0; in gl_discard_chars()
3367 static int gl_check_caught_signal(GetLine *gl) in gl_check_caught_signal() argument
3390 gl->last_signal = signo; in gl_check_caught_signal()
3403 if(gl->io_mode==GL_SERVER_MODE) { in gl_check_caught_signal()
3404 gl_record_status(gl, GLR_SIGNAL, EINTR); in gl_check_caught_signal()
3411 for(sig=gl->sigs; sig && sig->signo != signo; sig=sig->next) in gl_check_caught_signal()
3423 if(signo == SIGWINCH && _gl_update_size(gl)) in gl_check_caught_signal()
3430 if(gl_start_newline(gl, 0)) in gl_check_caught_signal()
3438 gl_restore_terminal_attributes(gl); in gl_check_caught_signal()
3445 gl_restore_signal_handlers(gl); in gl_check_caught_signal()
3446 gl_unmask_signals(gl, &gl->old_signal_set); in gl_check_caught_signal()
3460 gl_mask_signals(gl, NULL); in gl_check_caught_signal()
3461 gl_override_signal_handlers(gl); in gl_check_caught_signal()
3470 gl_raw_terminal_mode(gl); in gl_check_caught_signal()
3475 gl_queue_redisplay(gl); in gl_check_caught_signal()
3481 gl_newline(gl, 1, NULL); in gl_check_caught_signal()
3482 return gl_flush_output(gl); in gl_check_caught_signal()
3485 gl_record_status(gl, GLR_SIGNAL, sig->errno_value); in gl_check_caught_signal()
3489 return gl_flush_output(gl); in gl_check_caught_signal()
3505 static int gl_control_strings(GetLine *gl, const char *term) in gl_control_strings() argument
3511 gl->left = NULL; in gl_control_strings()
3512 gl->right = NULL; in gl_control_strings()
3513 gl->up = NULL; in gl_control_strings()
3514 gl->down = NULL; in gl_control_strings()
3515 gl->home = NULL; in gl_control_strings()
3516 gl->bol = 0; in gl_control_strings()
3517 gl->clear_eol = NULL; in gl_control_strings()
3518 gl->clear_eod = NULL; in gl_control_strings()
3519 gl->u_arrow = NULL; in gl_control_strings()
3520 gl->d_arrow = NULL; in gl_control_strings()
3521 gl->l_arrow = NULL; in gl_control_strings()
3522 gl->r_arrow = NULL; in gl_control_strings()
3523 gl->sound_bell = NULL; in gl_control_strings()
3524 gl->bold = NULL; in gl_control_strings()
3525 gl->underline = NULL; in gl_control_strings()
3526 gl->standout = NULL; in gl_control_strings()
3527 gl->dim = NULL; in gl_control_strings()
3528 gl->reverse = NULL; in gl_control_strings()
3529 gl->blink = NULL; in gl_control_strings()
3530 gl->text_attr_off = NULL; in gl_control_strings()
3531 gl->nline = 0; in gl_control_strings()
3532 gl->ncolumn = 0; in gl_control_strings()
3534 gl->left_n = NULL; in gl_control_strings()
3535 gl->right_n = NULL; in gl_control_strings()
3544 if(!term || setupterm((char *)term, gl->input_fd, &errret) == ERR) { in gl_control_strings()
3547 _clr_StringGroup(gl->capmem); in gl_control_strings()
3548 gl->left = gl_tigetstr(gl, "cub1"); in gl_control_strings()
3549 gl->right = gl_tigetstr(gl, "cuf1"); in gl_control_strings()
3550 gl->up = gl_tigetstr(gl, "cuu1"); in gl_control_strings()
3551 gl->down = gl_tigetstr(gl, "cud1"); in gl_control_strings()
3552 gl->home = gl_tigetstr(gl, "home"); in gl_control_strings()
3553 gl->clear_eol = gl_tigetstr(gl, "el"); in gl_control_strings()
3554 gl->clear_eod = gl_tigetstr(gl, "ed"); in gl_control_strings()
3555 gl->u_arrow = gl_tigetstr(gl, "kcuu1"); in gl_control_strings()
3556 gl->d_arrow = gl_tigetstr(gl, "kcud1"); in gl_control_strings()
3557 gl->l_arrow = gl_tigetstr(gl, "kcub1"); in gl_control_strings()
3558 gl->r_arrow = gl_tigetstr(gl, "kcuf1"); in gl_control_strings()
3559 gl->left_n = gl_tigetstr(gl, "cub"); in gl_control_strings()
3560 gl->right_n = gl_tigetstr(gl, "cuf"); in gl_control_strings()
3561 gl->sound_bell = gl_tigetstr(gl, "bel"); in gl_control_strings()
3562 gl->bold = gl_tigetstr(gl, "bold"); in gl_control_strings()
3563 gl->underline = gl_tigetstr(gl, "smul"); in gl_control_strings()
3564 gl->standout = gl_tigetstr(gl, "smso"); in gl_control_strings()
3565 gl->dim = gl_tigetstr(gl, "dim"); in gl_control_strings()
3566 gl->reverse = gl_tigetstr(gl, "rev"); in gl_control_strings()
3567 gl->blink = gl_tigetstr(gl, "blink"); in gl_control_strings()
3568 gl->text_attr_off = gl_tigetstr(gl, "sgr0"); in gl_control_strings()
3572 if(!term || tgetent(gl->tgetent_buf, (char *)term) < 0) { in gl_control_strings()
3575 char *tgetstr_buf_ptr = gl->tgetstr_buf; in gl_control_strings()
3576 _clr_StringGroup(gl->capmem); in gl_control_strings()
3577 gl->left = gl_tgetstr(gl, "le", &tgetstr_buf_ptr); in gl_control_strings()
3578 gl->right = gl_tgetstr(gl, "nd", &tgetstr_buf_ptr); in gl_control_strings()
3579 gl->up = gl_tgetstr(gl, "up", &tgetstr_buf_ptr); in gl_control_strings()
3580 gl->down = gl_tgetstr(gl, "do", &tgetstr_buf_ptr); in gl_control_strings()
3581 gl->home = gl_tgetstr(gl, "ho", &tgetstr_buf_ptr); in gl_control_strings()
3582 gl->clear_eol = gl_tgetstr(gl, "ce", &tgetstr_buf_ptr); in gl_control_strings()
3583 gl->clear_eod = gl_tgetstr(gl, "cd", &tgetstr_buf_ptr); in gl_control_strings()
3584 gl->u_arrow = gl_tgetstr(gl, "ku", &tgetstr_buf_ptr); in gl_control_strings()
3585 gl->d_arrow = gl_tgetstr(gl, "kd", &tgetstr_buf_ptr); in gl_control_strings()
3586 gl->l_arrow = gl_tgetstr(gl, "kl", &tgetstr_buf_ptr); in gl_control_strings()
3587 gl->r_arrow = gl_tgetstr(gl, "kr", &tgetstr_buf_ptr); in gl_control_strings()
3588 gl->sound_bell = gl_tgetstr(gl, "bl", &tgetstr_buf_ptr); in gl_control_strings()
3589 gl->bold = gl_tgetstr(gl, "md", &tgetstr_buf_ptr); in gl_control_strings()
3590 gl->underline = gl_tgetstr(gl, "us", &tgetstr_buf_ptr); in gl_control_strings()
3591 gl->standout = gl_tgetstr(gl, "so", &tgetstr_buf_ptr); in gl_control_strings()
3592 gl->dim = gl_tgetstr(gl, "mh", &tgetstr_buf_ptr); in gl_control_strings()
3593 gl->reverse = gl_tgetstr(gl, "mr", &tgetstr_buf_ptr); in gl_control_strings()
3594 gl->blink = gl_tgetstr(gl, "mb", &tgetstr_buf_ptr); in gl_control_strings()
3595 gl->text_attr_off = gl_tgetstr(gl, "me", &tgetstr_buf_ptr); in gl_control_strings()
3602 gl_print_info(gl, "Bad terminal type: \"", term ? term : "(null)", in gl_control_strings()
3608 if(!gl->left) in gl_control_strings()
3609 gl->left = "\b"; /* ^H */ in gl_control_strings()
3610 if(!gl->right) in gl_control_strings()
3611 gl->right = GL_ESC_STR "[C"; in gl_control_strings()
3612 if(!gl->up) in gl_control_strings()
3613 gl->up = GL_ESC_STR "[A"; in gl_control_strings()
3614 if(!gl->down) in gl_control_strings()
3615 gl->down = "\n"; in gl_control_strings()
3616 if(!gl->home) in gl_control_strings()
3617 gl->home = GL_ESC_STR "[H"; in gl_control_strings()
3618 if(!gl->bol) in gl_control_strings()
3619 gl->bol = "\r"; in gl_control_strings()
3620 if(!gl->clear_eol) in gl_control_strings()
3621 gl->clear_eol = GL_ESC_STR "[K"; in gl_control_strings()
3622 if(!gl->clear_eod) in gl_control_strings()
3623 gl->clear_eod = GL_ESC_STR "[J"; in gl_control_strings()
3624 if(!gl->u_arrow) in gl_control_strings()
3625 gl->u_arrow = GL_ESC_STR "[A"; in gl_control_strings()
3626 if(!gl->d_arrow) in gl_control_strings()
3627 gl->d_arrow = GL_ESC_STR "[B"; in gl_control_strings()
3628 if(!gl->l_arrow) in gl_control_strings()
3629 gl->l_arrow = GL_ESC_STR "[D"; in gl_control_strings()
3630 if(!gl->r_arrow) in gl_control_strings()
3631 gl->r_arrow = GL_ESC_STR "[C"; in gl_control_strings()
3632 if(!gl->sound_bell) in gl_control_strings()
3633 gl->sound_bell = "\a"; in gl_control_strings()
3634 if(!gl->bold) in gl_control_strings()
3635 gl->bold = GL_ESC_STR "[1m"; in gl_control_strings()
3636 if(!gl->underline) in gl_control_strings()
3637 gl->underline = GL_ESC_STR "[4m"; in gl_control_strings()
3638 if(!gl->standout) in gl_control_strings()
3639 gl->standout = GL_ESC_STR "[1;7m"; in gl_control_strings()
3640 if(!gl->dim) in gl_control_strings()
3641 gl->dim = ""; /* Not available */ in gl_control_strings()
3642 if(!gl->reverse) in gl_control_strings()
3643 gl->reverse = GL_ESC_STR "[7m"; in gl_control_strings()
3644 if(!gl->blink) in gl_control_strings()
3645 gl->blink = GL_ESC_STR "[5m"; in gl_control_strings()
3646 if(!gl->text_attr_off) in gl_control_strings()
3647 gl->text_attr_off = GL_ESC_STR "[m"; in gl_control_strings()
3651 (void) _gl_terminal_size(gl, GL_DEF_NCOLUMN, GL_DEF_NLINE, NULL); in gl_control_strings()
3668 static const char *gl_tigetstr(GetLine *gl, const char *name) in gl_tigetstr() argument
3673 return _sg_store_string(gl->capmem, value, 0); in gl_tigetstr()
3698 static const char *gl_tgetstr(GetLine *gl, const char *name, char **bufptr) in gl_tgetstr() argument
3703 return _sg_store_string(gl->capmem, value, 0); in gl_tgetstr()
3740 tcflow(gl->output_fd, TCOOFF); in KT_KEY_FN()
3749 tcflow(gl->output_fd, TCOON); in KT_KEY_FN()
3764 if(gl_read_terminal(gl, 1, &c)) in KT_KEY_FN()
3770 gl_add_char_to_line(gl, c); in KT_KEY_FN()
3786 static int gl_displayed_tab_width(GetLine *gl, int term_curpos) in gl_displayed_tab_width() argument
3788 return TAB_WIDTH - ((term_curpos % gl->ncolumn) % TAB_WIDTH); in gl_displayed_tab_width()
3807 static int gl_displayed_char_width(GetLine *gl, char c, int term_curpos) in gl_displayed_char_width() argument
3810 return gl_displayed_tab_width(gl, term_curpos); in gl_displayed_char_width()
3834 static int gl_displayed_string_width(GetLine *gl, const char *string, int nc, in gl_displayed_string_width() argument
3848 slen += gl_displayed_char_width(gl, string[i], term_curpos + slen); in gl_displayed_string_width()
3873 static int gl_print_raw_string(GetLine *gl, int buffered, in gl_print_raw_string() argument
3876 GlWriteFn *write_fn = buffered ? gl_write_fn : gl->flush_fn; in gl_print_raw_string()
3880 if(gl->echo) { in gl_print_raw_string()
3886 if(gl_flush_output(gl)) in gl_print_raw_string()
3897 if(write_fn(gl, string + ndone, n-ndone) != n) in gl_print_raw_string()
3917 static int gl_print_control_sequence(GetLine *gl, int nline, const char *string) in gl_print_control_sequence() argument
3923 if(gl->echo) { in gl_print_control_sequence()
3925 tputs_gl = gl; in gl_print_control_sequence()
3930 waserr = gl_print_raw_string(gl, 1, string, -1); in gl_print_control_sequence()
3962 static int gl_terminal_move_cursor(GetLine *gl, int n) in gl_terminal_move_cursor() argument
3973 if(!gl->displayed) in gl_terminal_move_cursor()
3978 if(gl->term_curpos + n < 0) in gl_terminal_move_cursor()
3979 n = gl->term_curpos; in gl_terminal_move_cursor()
3983 cur_row = gl->term_curpos / gl->ncolumn; in gl_terminal_move_cursor()
3984 cur_col = gl->term_curpos % gl->ncolumn; in gl_terminal_move_cursor()
3985 new_row = (gl->term_curpos + n) / gl->ncolumn; in gl_terminal_move_cursor()
3986 new_col = (gl->term_curpos + n) % gl->ncolumn; in gl_terminal_move_cursor()
3991 if(gl_print_control_sequence(gl, 1, gl->down)) in gl_terminal_move_cursor()
3998 if(gl_print_control_sequence(gl, 1, gl->up)) in gl_terminal_move_cursor()
4010 if(gl->right_n != NULL && new_col - cur_col > 1) { in gl_terminal_move_cursor()
4011 if(gl_print_control_sequence(gl, 1, tparm((char *)gl->right_n, in gl_terminal_move_cursor()
4018 if(gl_print_control_sequence(gl, 1, gl->right)) in gl_terminal_move_cursor()
4031 if(gl->left_n != NULL && cur_col - new_col > 3) { in gl_terminal_move_cursor()
4032 if(gl_print_control_sequence(gl, 1, tparm((char *)gl->left_n, in gl_terminal_move_cursor()
4039 if(gl_print_control_sequence(gl, 1, gl->left)) in gl_terminal_move_cursor()
4047 gl->term_curpos += n; in gl_terminal_move_cursor()
4073 static int gl_print_char(GetLine *gl, char c, char pad) in gl_print_char() argument
4086 nchar = gl_displayed_tab_width(gl, gl->term_curpos); in gl_print_char()
4110 if(gl_print_raw_string(gl, 1, string, -1)) in gl_print_char()
4116 gl->term_curpos += nchar; in gl_print_char()
4121 if(gl->term_curpos > gl->term_len) in gl_print_char()
4122 gl->term_len = gl->term_curpos; in gl_print_char()
4129 if(gl->term_curpos % gl->ncolumn == 0) { in gl_print_char()
4130 int term_curpos = gl->term_curpos; in gl_print_char()
4131 if(gl_print_char(gl, pad ? pad : ' ', ' ') || in gl_print_char()
4132 gl_set_term_curpos(gl, term_curpos)) in gl_print_char()
4160 static int gl_print_string(GetLine *gl, const char *string, char pad) in gl_print_string() argument
4165 if(gl_print_char(gl, *cptr, nextc ? nextc : pad)) in gl_print_string()
4181 static int gl_set_term_curpos(GetLine *gl, int term_curpos) in gl_set_term_curpos() argument
4183 return gl_terminal_move_cursor(gl, term_curpos - gl->term_curpos); in gl_set_term_curpos()
4192 return gl_place_cursor(gl, gl->buff_curpos - count); in KT_KEY_FN()
4201 return gl_place_cursor(gl, gl->buff_curpos + count); in KT_KEY_FN()
4210 gl->insert = !gl->insert; in KT_KEY_FN()
4220 return gl_place_cursor(gl, 0); in KT_KEY_FN()
4229 return gl_place_cursor(gl, gl->ntotal); in KT_KEY_FN()
4242 gl_save_for_undo(gl); in KT_KEY_FN()
4246 strlcpy(gl->cutbuf, gl->line, gl->linelen); in KT_KEY_FN()
4250 gl_truncate_buffer(gl, 0); in KT_KEY_FN()
4254 if(gl_place_cursor(gl, 0)) in KT_KEY_FN()
4259 if(gl_truncate_display(gl)) in KT_KEY_FN()
4274 gl_save_for_undo(gl); in KT_KEY_FN()
4278 strlcpy(gl->cutbuf, gl->line + gl->buff_curpos, gl->linelen); in KT_KEY_FN()
4282 gl_truncate_buffer(gl, gl->buff_curpos); in KT_KEY_FN()
4286 if(gl_truncate_display(gl)) in KT_KEY_FN()
4292 return gl_place_cursor(gl, gl->buff_curpos); in KT_KEY_FN()
4304 int nc = gl->buff_curpos - gl->insert_curpos; in KT_KEY_FN()
4312 return gl_place_cursor(gl, gl->insert_curpos) || in KT_KEY_FN()
4313 gl_delete_chars(gl, nc, gl->editor == GL_EMACS_MODE || gl->vi.command); in KT_KEY_FN()
4321 return gl_place_cursor(gl, gl_nth_word_end_forward(gl, count) + in KT_KEY_FN()
4322 (gl->editor==GL_EMACS_MODE)); in KT_KEY_FN()
4331 return gl_place_cursor(gl, gl_nth_word_start_forward(gl, count)); in KT_KEY_FN()
4339 return gl_place_cursor(gl, gl_nth_word_start_backward(gl, count)); in KT_KEY_FN()
4353 static int gl_delete_chars(GetLine *gl, int nc, int cut) in gl_delete_chars() argument
4359 gl_save_for_undo(gl); in gl_delete_chars()
4364 if(gl->buff_curpos + nc > gl->ntotal) in gl_delete_chars()
4365 nc = gl->ntotal - gl->buff_curpos; in gl_delete_chars()
4370 memcpy(gl->cutbuf, gl->line + gl->buff_curpos, nc); in gl_delete_chars()
4371 gl->cutbuf[nc] = '\0'; in gl_delete_chars()
4382 if(gl->editor == GL_VI_MODE && !gl->vi.command && !gl->insert) { in gl_delete_chars()
4387 int nrestore = gl->buff_curpos + nc <= gl->vi.undo.ntotal ? in gl_delete_chars()
4388 nc : gl->vi.undo.ntotal - gl->buff_curpos; in gl_delete_chars()
4393 gl_buffer_string(gl, gl->vi.undo.line + gl->buff_curpos, nrestore, in gl_delete_chars()
4394 gl->buff_curpos); in gl_delete_chars()
4404 gl_truncate_buffer(gl, (gl->vi.undo.ntotal > gl->buff_curpos) ? in gl_delete_chars()
4405 gl->vi.undo.ntotal : gl->buff_curpos); in gl_delete_chars()
4411 gl_remove_from_buffer(gl, gl->buff_curpos, nc); in gl_delete_chars()
4416 if(gl_print_string(gl, gl->line + gl->buff_curpos, '\0')) in gl_delete_chars()
4421 if(gl_truncate_display(gl)) in gl_delete_chars()
4426 return gl_place_cursor(gl, gl->buff_curpos); in gl_delete_chars()
4438 return gl_delete_chars(gl, count, gl->vi.command); in KT_KEY_FN()
4451 if(count > gl->buff_curpos - gl->insert_curpos) in KT_KEY_FN()
4452 count = gl->buff_curpos - gl->insert_curpos; in KT_KEY_FN()
4457 gl_save_for_undo(gl); in KT_KEY_FN()
4458 return gl_cursor_left(gl, count, NULL) || in KT_KEY_FN()
4459 gl_delete_chars(gl, count, gl->vi.command); in KT_KEY_FN()
4467 if (--count >= gl->buff_curpos) in KT_KEY_FN()
4468 return gl_forward_delete_char(gl, count - gl->buff_curpos, NULL); in KT_KEY_FN()
4470 return gl_backward_delete_char(gl, gl->buff_curpos - count, NULL); in KT_KEY_FN()
4479 int curpos = gl_index_of_matching_paren(gl); in KT_KEY_FN()
4481 gl_save_for_undo(gl); in KT_KEY_FN()
4482 if(curpos >= gl->buff_curpos) in KT_KEY_FN()
4483 return gl_forward_delete_char(gl, curpos - gl->buff_curpos + 1, NULL); in KT_KEY_FN()
4485 return gl_backward_delete_char(gl, ++gl->buff_curpos - curpos + 1, NULL); in KT_KEY_FN()
4500 gl_save_for_undo(gl); in KT_KEY_FN()
4505 if(gl->editor == GL_EMACS_MODE) { in KT_KEY_FN()
4506 return gl_delete_chars(gl, in KT_KEY_FN()
4507 gl_nth_word_end_forward(gl,count) - gl->buff_curpos + 1, 1); in KT_KEY_FN()
4509 return gl_delete_chars(gl, in KT_KEY_FN()
4510 gl_nth_word_start_forward(gl,count) - gl->buff_curpos, in KT_KEY_FN()
4511 gl->vi.command); in KT_KEY_FN()
4524 int buff_curpos = gl->buff_curpos; in KT_KEY_FN()
4529 gl_save_for_undo(gl); in KT_KEY_FN()
4533 if(gl_backward_word(gl, count, NULL)) in KT_KEY_FN()
4538 return gl_delete_chars(gl, buff_curpos - gl->buff_curpos, in KT_KEY_FN()
4539 gl->editor == GL_EMACS_MODE || gl->vi.command); in KT_KEY_FN()
4564 static int gl_delete_find(GetLine *gl, int count, char c, int forward, in gl_delete_find() argument
4570 int pos = gl_find_char(gl, count, forward, onto, c); in gl_delete_find()
4577 gl_save_for_undo(gl); in gl_delete_find()
4583 gl->vi.command = 0; in gl_delete_find()
4588 if(gl_delete_chars(gl, pos - gl->buff_curpos + 1, 1)) in gl_delete_find()
4591 int buff_curpos = gl->buff_curpos; in gl_delete_find()
4592 if(gl_place_cursor(gl, pos) || in gl_delete_find()
4593 gl_delete_chars(gl, buff_curpos - gl->buff_curpos, 1)) in gl_delete_find()
4599 if(change && gl_vi_insert(gl, 0, NULL)) in gl_delete_find()
4610 return gl_delete_find(gl, count, '\0', 1, 1, 0); in KT_KEY_FN()
4619 return gl_delete_find(gl, count, '\0', 0, 1, 0); in KT_KEY_FN()
4628 return gl_delete_find(gl, count, '\0', 1, 0, 0); in KT_KEY_FN()
4637 return gl_delete_find(gl, count, '\0', 0, 0, 0); in KT_KEY_FN()
4646 return gl_delete_find(gl, count, gl->vi.find_char, gl->vi.find_forward, in KT_KEY_FN()
4647 gl->vi.find_onto, 0); in KT_KEY_FN()
4656 return gl_delete_find(gl, count, gl->vi.find_char, in KT_KEY_FN()
4657 !gl->vi.find_forward, gl->vi.find_onto, 0); in KT_KEY_FN()
4669 int last = gl_nth_word_end_forward(gl, count); in KT_KEY_FN()
4674 gl_save_for_undo(gl); in KT_KEY_FN()
4678 while(gl->buff_curpos <= last) { in KT_KEY_FN()
4679 char *cptr = gl->line + gl->buff_curpos; in KT_KEY_FN()
4684 gl_buffer_char(gl, toupper((int) *cptr), gl->buff_curpos); in KT_KEY_FN()
4685 gl->buff_curpos++; in KT_KEY_FN()
4690 if(gl_print_char(gl, *cptr, cptr[1])) in KT_KEY_FN()
4693 return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ in KT_KEY_FN()
4705 int last = gl_nth_word_end_forward(gl, count); in KT_KEY_FN()
4710 gl_save_for_undo(gl); in KT_KEY_FN()
4714 while(gl->buff_curpos <= last) { in KT_KEY_FN()
4715 char *cptr = gl->line + gl->buff_curpos; in KT_KEY_FN()
4720 gl_buffer_char(gl, tolower((int) *cptr), gl->buff_curpos); in KT_KEY_FN()
4721 gl->buff_curpos++; in KT_KEY_FN()
4726 if(gl_print_char(gl, *cptr, cptr[1])) in KT_KEY_FN()
4729 return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ in KT_KEY_FN()
4745 int insert = gl->insert; in KT_KEY_FN()
4750 gl_save_for_undo(gl); in KT_KEY_FN()
4754 gl->insert = 0; in KT_KEY_FN()
4758 for(i=0; i<count && gl->buff_curpos < gl->ntotal; i++) { in KT_KEY_FN()
4759 int pos = gl->buff_curpos; in KT_KEY_FN()
4763 for(cptr = gl->line + pos ; pos<gl->ntotal && !gl_is_word_char((int) *cptr); in KT_KEY_FN()
4769 if(gl_place_cursor(gl, pos)) in KT_KEY_FN()
4775 for(first=1; gl->buff_curpos<gl->ntotal && gl_is_word_char((int) *cptr); in KT_KEY_FN()
4776 gl->buff_curpos++, cptr++) { in KT_KEY_FN()
4782 gl_buffer_char(gl, toupper((int) *cptr), cptr - gl->line); in KT_KEY_FN()
4785 gl_buffer_char(gl, tolower((int) *cptr), cptr - gl->line); in KT_KEY_FN()
4792 if(gl_print_char(gl, *cptr, cptr[1])) in KT_KEY_FN()
4799 gl->insert = insert; in KT_KEY_FN()
4800 return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ in KT_KEY_FN()
4811 int buff_curpos = gl->buff_curpos; in KT_KEY_FN()
4815 if(gl->endline) in KT_KEY_FN()
4820 if(gl_erase_line(gl)) in KT_KEY_FN()
4825 if(gl_display_prompt(gl)) in KT_KEY_FN()
4830 if(gl_print_string(gl, gl->line, '\0')) in KT_KEY_FN()
4835 if(gl_place_cursor(gl, buff_curpos)) in KT_KEY_FN()
4840 gl->redisplay = 0; in KT_KEY_FN()
4844 return gl_flush_output(gl); in KT_KEY_FN()
4856 if(gl_print_control_sequence(gl, gl->nline, gl->home) || in KT_KEY_FN()
4857 gl_print_control_sequence(gl, gl->nline, gl->clear_eod)) in KT_KEY_FN()
4862 gl_line_erased(gl); in KT_KEY_FN()
4866 gl_queue_redisplay(gl); in KT_KEY_FN()
4882 if(gl->buff_curpos < 1 || gl->buff_curpos >= gl->ntotal) in KT_KEY_FN()
4888 gl_save_for_undo(gl); in KT_KEY_FN()
4892 from[0] = gl->line[gl->buff_curpos - 1]; in KT_KEY_FN()
4893 from[1] = gl->line[gl->buff_curpos]; in KT_KEY_FN()
4895 swap[0] = gl->line[gl->buff_curpos]; in KT_KEY_FN()
4896 swap[1] = gl->line[gl->buff_curpos - 1]; in KT_KEY_FN()
4901 if(gl_place_cursor(gl, gl->buff_curpos-1)) in KT_KEY_FN()
4906 gl_buffer_char(gl, swap[0], gl->buff_curpos); in KT_KEY_FN()
4907 gl_buffer_char(gl, swap[1], gl->buff_curpos+1); in KT_KEY_FN()
4913 if(gl_displayed_string_width(gl, from, -1, gl->term_curpos) == in KT_KEY_FN()
4914 gl_displayed_string_width(gl, swap, -1, gl->term_curpos)) { in KT_KEY_FN()
4915 int insert = gl->insert; in KT_KEY_FN()
4916 gl->insert = 0; in KT_KEY_FN()
4917 if(gl_print_char(gl, swap[0], swap[1]) || in KT_KEY_FN()
4918 gl_print_char(gl, swap[1], gl->line[gl->buff_curpos+2])) in KT_KEY_FN()
4920 gl->insert = insert; in KT_KEY_FN()
4926 if(gl_print_string(gl, gl->line + gl->buff_curpos, '\0') || in KT_KEY_FN()
4927 gl_truncate_display(gl)) in KT_KEY_FN()
4933 return gl_place_cursor(gl, gl->buff_curpos + 2); in KT_KEY_FN()
4942 gl->buff_mark = gl->buff_curpos; in KT_KEY_FN()
4956 int old_mark = gl->buff_mark <= gl->ntotal ? gl->buff_mark : gl->ntotal; in KT_KEY_FN()
4960 gl->buff_mark = gl->buff_curpos; in KT_KEY_FN()
4964 return gl_place_cursor(gl, old_mark); in KT_KEY_FN()
4977 gl_save_for_undo(gl); in KT_KEY_FN()
4981 if(gl->buff_mark > gl->ntotal) in KT_KEY_FN()
4982 gl->buff_mark = gl->ntotal; in KT_KEY_FN()
4987 if(gl->buff_mark == gl->buff_curpos) { in KT_KEY_FN()
4988 gl->cutbuf[0] = '\0'; in KT_KEY_FN()
4994 if(gl->buff_mark < gl->buff_curpos && gl_exchange_point_and_mark(gl,1,NULL)) in KT_KEY_FN()
4999 if(gl_delete_chars(gl, gl->buff_mark - gl->buff_curpos, 1)) in KT_KEY_FN()
5004 gl->buff_mark = gl->buff_curpos; in KT_KEY_FN()
5019 mark = gl->buff_mark > gl->ntotal ? gl->ntotal : gl->buff_mark; in KT_KEY_FN()
5024 if(mark == gl->buff_curpos) { in KT_KEY_FN()
5025 gl->cutbuf[0] = '\0'; in KT_KEY_FN()
5031 if(mark < gl->buff_curpos) { in KT_KEY_FN()
5033 cb = gl->buff_curpos - 1; in KT_KEY_FN()
5035 ca = gl->buff_curpos; in KT_KEY_FN()
5041 memcpy(gl->cutbuf, gl->line + ca, cb + 1 - ca); in KT_KEY_FN()
5042 gl->cutbuf[cb + 1 - ca] = '\0'; in KT_KEY_FN()
5056 gl->buff_mark = gl->buff_curpos; in KT_KEY_FN()
5060 if(gl->cutbuf[0] == '\0') in KT_KEY_FN()
5061 return gl_ring_bell(gl, 1, NULL); in KT_KEY_FN()
5066 gl_save_for_undo(gl); in KT_KEY_FN()
5071 if(gl_add_string_to_line(gl, gl->cutbuf)) in KT_KEY_FN()
5078 if(gl->editor == GL_VI_MODE && gl_cursor_left(gl, 1, NULL)) in KT_KEY_FN()
5089 int was_command = gl->vi.command; in KT_KEY_FN()
5094 if(gl->cutbuf[0] == '\0') in KT_KEY_FN()
5095 return gl_ring_bell(gl, 1, NULL); in KT_KEY_FN()
5099 gl->buff_mark = gl->buff_curpos + 1; in KT_KEY_FN()
5104 gl_save_for_undo(gl); in KT_KEY_FN()
5108 if(gl_vi_append(gl, 0, NULL)) in KT_KEY_FN()
5114 if(gl_add_string_to_line(gl, gl->cutbuf)) in KT_KEY_FN()
5121 gl_vi_command_mode(gl); in KT_KEY_FN()
5136 static void gl_query_size(GetLine *gl, int *ncolumn, int *nline) in gl_query_size() argument
5143 if(ioctl(gl->output_fd, TIOCGWINSZ, &size) == 0 && in gl_query_size()
5153 *ncolumn = gl->ncolumn; in gl_query_size()
5154 *nline = gl->nline; in gl_query_size()
5168 static int _gl_update_size(GetLine *gl) in _gl_update_size() argument
5174 gl_query_size(gl, &ncolumn, &nline); in _gl_update_size()
5178 return gl_handle_tty_resize(gl, ncolumn, nline); in _gl_update_size()
5193 static int gl_handle_tty_resize(GetLine *gl, int ncolumn, int nline) in gl_handle_tty_resize() argument
5198 if(!gl->is_term) { in gl_handle_tty_resize()
5199 gl->nline = nline; in gl_handle_tty_resize()
5200 gl->ncolumn = ncolumn; in gl_handle_tty_resize()
5204 } else if(ncolumn != gl->ncolumn || nline != gl->nline) { in gl_handle_tty_resize()
5208 if(gl_erase_line(gl)) in gl_handle_tty_resize()
5213 gl->nline = nline; in gl_handle_tty_resize()
5214 gl->ncolumn = ncolumn; in gl_handle_tty_resize()
5219 gl_queue_redisplay(gl); in gl_handle_tty_resize()
5234 gl_vi_command_mode(gl); in KT_KEY_FN()
5238 gl->preload_id = 0; in KT_KEY_FN()
5242 gl->last_search = gl->keyseq_count; in KT_KEY_FN()
5246 if(_glh_search_prefix(gl->glh, gl->line, 0)) { in KT_KEY_FN()
5247 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG); in KT_KEY_FN()
5255 if(_glh_find_backwards(gl->glh, gl->line, gl->linelen+1) == NULL) in KT_KEY_FN()
5257 while(--count && _glh_find_backwards(gl->glh, gl->line, gl->linelen+1)) in KT_KEY_FN()
5262 gl_update_buffer(gl); in KT_KEY_FN()
5266 gl->buff_curpos = gl->ntotal; in KT_KEY_FN()
5270 gl_queue_redisplay(gl); in KT_KEY_FN()
5284 gl_vi_command_mode(gl); in KT_KEY_FN()
5288 gl->last_search = gl->keyseq_count; in KT_KEY_FN()
5293 if(_glh_line_id(gl->glh, 0) == 0 && gl->preload_id) { in KT_KEY_FN()
5294 _glh_recall_line(gl->glh, gl->preload_id, gl->line, gl->linelen+1); in KT_KEY_FN()
5295 gl->preload_id = 0; in KT_KEY_FN()
5300 if(_glh_search_prefix(gl->glh, gl->line, 0)) { in KT_KEY_FN()
5301 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG); in KT_KEY_FN()
5309 if(_glh_find_forwards(gl->glh, gl->line, gl->linelen+1) == NULL) in KT_KEY_FN()
5311 while(--count && _glh_find_forwards(gl->glh, gl->line, gl->linelen+1)) in KT_KEY_FN()
5317 gl_update_buffer(gl); in KT_KEY_FN()
5321 gl->buff_curpos = gl->ntotal; in KT_KEY_FN()
5325 gl_queue_redisplay(gl); in KT_KEY_FN()
5341 gl_vi_command_mode(gl); in KT_KEY_FN()
5345 gl->preload_id = 0; in KT_KEY_FN()
5349 gl->last_search = gl->keyseq_count; in KT_KEY_FN()
5357 if(count >= 0 && !_glh_search_active(gl->glh) && in KT_KEY_FN()
5358 _glh_search_prefix(gl->glh, gl->line, gl->buff_curpos + in KT_KEY_FN()
5359 (gl->editor==GL_VI_MODE && gl->ntotal>0))) { in KT_KEY_FN()
5360 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG); in KT_KEY_FN()
5367 if(_glh_find_backwards(gl->glh, gl->line, gl->linelen+1) == NULL) in KT_KEY_FN()
5372 gl_update_buffer(gl); in KT_KEY_FN()
5376 gl->buff_curpos = gl->ntotal; in KT_KEY_FN()
5380 gl_queue_redisplay(gl); in KT_KEY_FN()
5391 return gl_history_search_backward(gl, -1, NULL); in KT_KEY_FN()
5407 gl_vi_command_mode(gl); in KT_KEY_FN()
5411 gl->last_search = gl->keyseq_count; in KT_KEY_FN()
5419 if(count >= 0 && !_glh_search_active(gl->glh) && in KT_KEY_FN()
5420 _glh_search_prefix(gl->glh, gl->line, gl->buff_curpos + in KT_KEY_FN()
5421 (gl->editor==GL_VI_MODE && gl->ntotal>0))) { in KT_KEY_FN()
5422 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG); in KT_KEY_FN()
5428 if(_glh_find_forwards(gl->glh, gl->line, gl->linelen+1) == NULL) in KT_KEY_FN()
5433 gl_update_buffer(gl); in KT_KEY_FN()
5437 gl->buff_curpos = gl->ntotal; in KT_KEY_FN()
5441 gl_queue_redisplay(gl); in KT_KEY_FN()
5452 return gl_history_search_forward(gl, -1, NULL); in KT_KEY_FN()
5485 GlCplCallback *cb = data ? (GlCplCallback *) data : &gl->cplfn; in KT_KEY_FN()
5491 if(gl->vi.command && gl_vi_append(gl, 0, NULL)) in KT_KEY_FN()
5496 buff_pos = gl->buff_curpos; in KT_KEY_FN()
5500 matches = cpl_complete_word(gl->cpl, gl->line, gl->buff_curpos, cb->data, in KT_KEY_FN()
5506 waserr = gl_print_info(gl, cpl_last_error(gl->cpl), GL_END_INFO); in KT_KEY_FN()
5514 if(matches->nmatch > 1 && gl->echo) { in KT_KEY_FN()
5515 if(_gl_normal_io(gl) || in KT_KEY_FN()
5516 _cpl_output_completions(matches, gl_write_fn, gl, gl->ncolumn)) in KT_KEY_FN()
5532 if(gl_newline(gl, 1, NULL)) in KT_KEY_FN()
5546 if(gl->ntotal + nextra < gl->linelen) { in KT_KEY_FN()
5550 gl_make_gap_in_buffer(gl, gl->buff_curpos, nextra); in KT_KEY_FN()
5554 gl_buffer_string(gl, matches->suffix, suffix_len, gl->buff_curpos); in KT_KEY_FN()
5558 gl_buffer_string(gl, matches->cont_suffix, cont_len, in KT_KEY_FN()
5559 gl->buff_curpos + suffix_len); in KT_KEY_FN()
5563 gl->buff_curpos += nextra; in KT_KEY_FN()
5569 if(gl->displayed) { in KT_KEY_FN()
5570 if(gl_truncate_display(gl) || in KT_KEY_FN()
5571 gl_print_string(gl, gl->line + buff_pos, '\0') || in KT_KEY_FN()
5572 gl_place_cursor(gl, gl->buff_curpos)) in KT_KEY_FN()
5576 (void) gl_print_info(gl, in KT_KEY_FN()
5588 if(_gl_raw_io(gl, 1)) in KT_KEY_FN()
5614 if(gl->vi.command && gl_vi_append(gl, 0, NULL)) in KT_KEY_FN()
5619 start_path = _pu_start_of_path(gl->line, gl->buff_curpos); in KT_KEY_FN()
5625 pathlen = gl->buff_curpos - (start_path - gl->line); in KT_KEY_FN()
5629 result = ef_expand_file(gl->ef, start_path, pathlen); in KT_KEY_FN()
5634 return gl_print_info(gl, ef_last_error(gl->ef), GL_END_INFO); in KT_KEY_FN()
5639 return gl_print_info(gl, "No files match.", GL_END_INFO); in KT_KEY_FN()
5644 gl_save_for_undo(gl); in KT_KEY_FN()
5671 if(gl->ntotal + nextra >= gl->linelen) { in KT_KEY_FN()
5672 return gl_print_info(gl, "Insufficient room in line for file expansion.", in KT_KEY_FN()
5680 gl_make_gap_in_buffer(gl, gl->buff_curpos, nextra); in KT_KEY_FN()
5682 gl->buff_curpos += nextra; in KT_KEY_FN()
5683 gl_remove_from_buffer(gl, gl->buff_curpos, -nextra); in KT_KEY_FN()
5689 for(i=0,j=start_path - gl->line; i<result->nfile; i++) { in KT_KEY_FN()
5695 gl_buffer_char(gl, '\\', j++); in KT_KEY_FN()
5697 gl_buffer_char(gl, c, j++); in KT_KEY_FN()
5699 gl_buffer_char(gl, ' ', j++); in KT_KEY_FN()
5706 if(gl_place_cursor(gl, start_path - gl->line) || in KT_KEY_FN()
5707 gl_truncate_display(gl) || in KT_KEY_FN()
5708 gl_print_string(gl, start_path, start_path[length])) in KT_KEY_FN()
5713 return gl_place_cursor(gl, (start_path - gl->line) + length); in KT_KEY_FN()
5732 start_path = _pu_start_of_path(gl->line, gl->buff_curpos); in KT_KEY_FN()
5738 pathlen = gl->buff_curpos - (start_path - gl->line); in KT_KEY_FN()
5742 result = ef_expand_file(gl->ef, start_path, pathlen); in KT_KEY_FN()
5747 return gl_print_info(gl, ef_last_error(gl->ef), GL_END_INFO); in KT_KEY_FN()
5752 return gl_print_info(gl, "No files match.", GL_END_INFO); in KT_KEY_FN()
5756 } else if(gl->echo) { in KT_KEY_FN()
5757 if(gl_start_newline(gl, 1) || in KT_KEY_FN()
5758 _ef_output_expansions(result, gl_write_fn, gl, gl->ncolumn)) in KT_KEY_FN()
5760 gl_queue_redisplay(gl); in KT_KEY_FN()
5797 int gl_customize_completion(GetLine *gl, void *data, CplMatchFn *match_fn) in gl_customize_completion() argument
5803 if(!gl || !match_fn) { in gl_customize_completion()
5804 if(gl) in gl_customize_completion()
5805 _err_record_msg(gl->err, "NULL argument", END_ERR_MSG); in gl_customize_completion()
5812 gl_mask_signals(gl, &oldset); in gl_customize_completion()
5816 gl->cplfn.fn = match_fn; in gl_customize_completion()
5817 gl->cplfn.data = data; in gl_customize_completion()
5821 gl_unmask_signals(gl, &oldset); in gl_customize_completion()
5841 int gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp, in gl_change_terminal() argument
5849 if(!gl) { in gl_change_terminal()
5856 if(gl_mask_signals(gl, &oldset)) in gl_change_terminal()
5861 status = _gl_change_terminal(gl, input_fp, output_fp, term); in gl_change_terminal()
5865 gl_unmask_signals(gl, &oldset); in gl_change_terminal()
5874 static int _gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp, in _gl_change_terminal() argument
5883 gl_print_info(gl, "Can't change terminal. Bad input/output stream(s).", in _gl_change_terminal()
5891 if(gl->input_fd >= 0) { in _gl_change_terminal()
5895 if(_gl_normal_io(gl)) in _gl_change_terminal()
5901 FD_CLR(gl->input_fd, &gl->rfds); in _gl_change_terminal()
5907 gl->input_fp = input_fp; in _gl_change_terminal()
5908 gl->input_fd = fileno(input_fp); in _gl_change_terminal()
5909 gl->output_fp = output_fp; in _gl_change_terminal()
5910 gl->output_fd = fileno(output_fp); in _gl_change_terminal()
5916 if(gl->input_fd > gl->max_fd) in _gl_change_terminal()
5917 gl->max_fd = gl->input_fd; in _gl_change_terminal()
5923 gl->is_term = 0; in _gl_change_terminal()
5929 is_term = isatty(gl->input_fd) && isatty(gl->output_fd); in _gl_change_terminal()
5939 if(term != gl->term) { in _gl_change_terminal()
5943 if(gl->term) { in _gl_change_terminal()
5944 free(gl->term); in _gl_change_terminal()
5945 gl->term = NULL; in _gl_change_terminal()
5953 gl->term = (char *) malloc(termsz); in _gl_change_terminal()
5954 if(gl->term) in _gl_change_terminal()
5955 strlcpy(gl->term, term, termsz); in _gl_change_terminal()
5962 _kt_clear_bindings(gl->bindings, KTB_TERM); in _gl_change_terminal()
5970 if(tcgetattr(gl->input_fd, &gl->oldattr)) { in _gl_change_terminal()
5971 _err_record_msg(gl->err, "tcgetattr error", END_ERR_MSG); in _gl_change_terminal()
5978 gl->is_term = 1; in _gl_change_terminal()
5982 if(gl_control_strings(gl, term)) { in _gl_change_terminal()
5983 gl->is_term = 0; in _gl_change_terminal()
5989 if(gl_bind_terminal_keys(gl)) in _gl_change_terminal()
5995 gl->io_mode = GL_NORMAL_MODE; in _gl_change_terminal()
5999 if(_gl_io_mode(gl, gl->io_mode)) in _gl_change_terminal()
6014 static int gl_bind_terminal_keys(GetLine *gl) in gl_bind_terminal_keys() argument
6019 if(gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VINTR], in gl_bind_terminal_keys()
6021 gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VQUIT], "abort") || in gl_bind_terminal_keys()
6022 gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VSUSP], "suspend")) in gl_bind_terminal_keys()
6028 if(gl->editor == GL_VI_MODE) { in gl_bind_terminal_keys()
6029 if(gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VINTR]), in gl_bind_terminal_keys()
6031 gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VQUIT]), in gl_bind_terminal_keys()
6033 gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VSUSP]), in gl_bind_terminal_keys()
6041 if(gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VLNEXT], in gl_bind_terminal_keys()
6045 if(_kt_set_keybinding(gl->bindings, KTB_TERM, "^V", "literal-next")) { in gl_bind_terminal_keys()
6046 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG); in gl_bind_terminal_keys()
6054 if(_gl_bind_arrow_keys(gl)) in gl_bind_terminal_keys()
6071 if(gl->ntotal < 1) { in KT_KEY_FN()
6072 gl_record_status(gl, GLR_EOF, 0); in KT_KEY_FN()
6077 } else if(gl->buff_curpos >= gl->ntotal) { in KT_KEY_FN()
6078 return gl_list_completions(gl, 1, NULL); in KT_KEY_FN()
6087 gl_save_for_undo(gl); in KT_KEY_FN()
6091 return gl_forward_delete_char(gl, count, NULL); in KT_KEY_FN()
6106 if(gl->ntotal < 1) { in KT_KEY_FN()
6107 gl_record_status(gl, GLR_EOF, 0); in KT_KEY_FN()
6113 return gl_list_completions(gl, 1, NULL); in KT_KEY_FN()
6129 GlCplCallback *cb = data ? (GlCplCallback *) data : &gl->cplfn; in KT_KEY_FN()
6133 CplMatches *matches = cpl_complete_word(gl->cpl, gl->line, gl->buff_curpos, in KT_KEY_FN()
6139 waserr = gl_print_info(gl, cpl_last_error(gl->cpl), GL_END_INFO); in KT_KEY_FN()
6143 } else if(matches->nmatch > 0 && gl->echo) { in KT_KEY_FN()
6144 if(_gl_normal_io(gl) || in KT_KEY_FN()
6145 _cpl_output_completions(matches, gl_write_fn, gl, gl->ncolumn)) in KT_KEY_FN()
6153 if(_gl_raw_io(gl, 1)) in KT_KEY_FN()
6169 static int _gl_bind_arrow_keys(GetLine *gl) in _gl_bind_arrow_keys() argument
6174 if(_gl_rebind_arrow_key(gl, "up", gl->u_arrow, "^[[A", "^[OA") || in _gl_bind_arrow_keys()
6175 _gl_rebind_arrow_key(gl, "down", gl->d_arrow, "^[[B", "^[OB") || in _gl_bind_arrow_keys()
6176 _gl_rebind_arrow_key(gl, "left", gl->l_arrow, "^[[D", "^[OD") || in _gl_bind_arrow_keys()
6177 _gl_rebind_arrow_key(gl, "right", gl->r_arrow, "^[[C", "^[OC")) in _gl_bind_arrow_keys()
6202 static int _gl_rebind_arrow_key(GetLine *gl, const char *name, in _gl_rebind_arrow_key() argument
6212 if(_kt_lookup_keybinding(gl->bindings, name, strlen(name), &keysym, &nsym) in _gl_rebind_arrow_key()
6224 _kt_set_keyfn(gl->bindings, KTB_TERM, term_seq, fn, data)) || in _gl_rebind_arrow_key()
6226 _kt_set_keyfn(gl->bindings, KTB_NORM, def_seq1, fn, data)) || in _gl_rebind_arrow_key()
6228 _kt_set_keyfn(gl->bindings, KTB_NORM, def_seq2, fn, data))) { in _gl_rebind_arrow_key()
6229 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG); in _gl_rebind_arrow_key()
6251 static int _gl_read_config_file(GetLine *gl, const char *filename, KtBinder who) in _gl_read_config_file() argument
6258 _err_record_msg(gl->err, in _gl_read_config_file()
6271 if(!gl || !filename) { in _gl_read_config_file()
6272 if(gl) in _gl_read_config_file()
6273 _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG); in _gl_read_config_file()
6280 expansion = ef_expand_file(gl->ef, filename, -1); in _gl_read_config_file()
6282 gl_print_info(gl, "Unable to expand ", filename, " (", in _gl_read_config_file()
6283 ef_last_error(gl->ef), ").", GL_END_INFO); in _gl_read_config_file()
6299 waserr = _gl_parse_config_line(gl, fp, glc_file_getc, filename, who, in _gl_read_config_file()
6304 if(_gl_bind_arrow_keys(gl)) in _gl_read_config_file()
6319 static int _gl_read_config_string(GetLine *gl, const char *buffer, KtBinder who) in _gl_read_config_string() argument
6327 if(!gl || !buffer) { in _gl_read_config_string()
6328 if(gl) in _gl_read_config_string()
6329 _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG); in _gl_read_config_string()
6341 waserr = _gl_parse_config_line(gl, &bptr, glc_buff_getc, "", who, &lineno); in _gl_read_config_string()
6345 if(_gl_bind_arrow_keys(gl)) in _gl_read_config_string()
6370 static int _gl_parse_config_line(GetLine *gl, void *stream, GlcGetcFn *getc_fn, in _gl_parse_config_line() argument
6429 gl_report_config_error(gl, origin, *lineno, "Too many arguments."); in _gl_parse_config_line()
6471 gl_report_config_error(gl, origin, *lineno, "Line too long."); in _gl_parse_config_line()
6488 if(_kt_set_keybinding(gl->bindings, who, keyseq, action)) { in _gl_parse_config_line()
6489 gl_report_config_error(gl, origin, *lineno, in _gl_parse_config_line()
6490 _kt_last_error(gl->bindings)); in _gl_parse_config_line()
6494 gl_report_config_error(gl, origin, *lineno, "Wrong number of arguments."); in _gl_parse_config_line()
6498 gl_change_editor(gl, GL_EMACS_MODE); in _gl_parse_config_line()
6500 gl_change_editor(gl, GL_VI_MODE); in _gl_parse_config_line()
6502 gl_change_editor(gl, GL_NO_EDITOR); in _gl_parse_config_line()
6504 gl_report_config_error(gl, origin, *lineno, in _gl_parse_config_line()
6508 gl->silence_bell = 1; in _gl_parse_config_line()
6510 gl_report_config_error(gl, origin, *lineno, "Unknown command name."); in _gl_parse_config_line()
6536 static int gl_report_config_error(GetLine *gl, const char *origin, int lineno, in gl_report_config_error() argument
6547 return gl_print_info(gl, origin, ":", lnum, ": ", errmsg, GL_END_INFO); in gl_report_config_error()
6585 start_path = _pu_start_of_path(gl->line, gl->buff_curpos); in KT_KEY_FN()
6591 pathlen = gl->buff_curpos - (start_path - gl->line); in KT_KEY_FN()
6595 result = ef_expand_file(gl->ef, start_path, pathlen); in KT_KEY_FN()
6600 return gl_print_info(gl, ef_last_error(gl->ef), GL_END_INFO); in KT_KEY_FN()
6605 return gl_print_info(gl, "No files match.", GL_END_INFO); in KT_KEY_FN()
6610 return gl_print_info(gl, "More than one file matches.", GL_END_INFO); in KT_KEY_FN()
6618 return gl_print_info(gl, "Not a normal file.", GL_END_INFO); in KT_KEY_FN()
6623 gl->file_fp = fopen(result->files[0], "r"); in KT_KEY_FN()
6624 if(!gl->file_fp) { in KT_KEY_FN()
6625 return gl_print_info(gl, "Unable to open: ", result->files[0], in KT_KEY_FN()
6633 if(fileno(gl->file_fp) > gl->max_fd) in KT_KEY_FN()
6634 gl->max_fd = fileno(gl->file_fp); in KT_KEY_FN()
6639 if(gl->raw_mode && gl->io_mode==GL_SERVER_MODE && in KT_KEY_FN()
6640 gl_nonblocking_io(gl, fileno(gl->file_fp))) { in KT_KEY_FN()
6641 gl_revert_input(gl); in KT_KEY_FN()
6642 return gl_print_info(gl, "Can't read file %s with non-blocking I/O", in KT_KEY_FN()
6648 if(gl_print_info(gl, "<Taking input from ", result->files[0], ">", in KT_KEY_FN()
6662 static void gl_revert_input(GetLine *gl) in gl_revert_input() argument
6664 if(gl->file_fp) in gl_revert_input()
6665 fclose(gl->file_fp); in gl_revert_input()
6666 gl->file_fp = NULL; in gl_revert_input()
6667 gl->endline = 1; in gl_revert_input()
6680 gl_vi_command_mode(gl); in KT_KEY_FN()
6684 gl->preload_id = 0; in KT_KEY_FN()
6688 gl->last_search = gl->keyseq_count; in KT_KEY_FN()
6692 if(_glh_oldest_line(gl->glh, gl->line, gl->linelen+1) == NULL) in KT_KEY_FN()
6697 gl_update_buffer(gl); in KT_KEY_FN()
6701 gl->buff_curpos = gl->ntotal; in KT_KEY_FN()
6705 gl_queue_redisplay(gl); in KT_KEY_FN()
6720 gl_vi_command_mode(gl); in KT_KEY_FN()
6724 gl->preload_id = 0; in KT_KEY_FN()
6728 gl->last_search = gl->keyseq_count; in KT_KEY_FN()
6732 if(_glh_current_line(gl->glh, gl->line, gl->linelen+1) == NULL) in KT_KEY_FN()
6737 gl_update_buffer(gl); in KT_KEY_FN()
6741 gl->buff_curpos = gl->ntotal; in KT_KEY_FN()
6745 gl_queue_redisplay(gl); in KT_KEY_FN()
6764 if(gl->vi.command && gl->number < 0 && count == '0') in KT_KEY_FN()
6765 return gl_beginning_of_line(gl, count, NULL); in KT_KEY_FN()
6769 if(gl->number < 0 || !is_digit) in KT_KEY_FN()
6770 gl->number = 0; in KT_KEY_FN()
6784 gl->number = gl->number * 10 + n; in KT_KEY_FN()
6799 gl->endline = 1; in KT_KEY_FN()
6804 id = _glh_line_id(gl->glh, 1); in KT_KEY_FN()
6806 gl->preload_id = id; in KT_KEY_FN()
6818 gl->endline = 1; in KT_KEY_FN()
6819 gl->preload_id = _glh_line_id(gl->glh, 1); in KT_KEY_FN()
6820 gl->preload_history = 1; in KT_KEY_FN()
6835 static int gl_flush_output(GetLine *gl) in gl_flush_output() argument
6840 gl->pending_io = GLP_WRITE; in gl_flush_output()
6845 switch(_glq_flush_queue(gl->cq, gl->flush_fn, gl)) { in gl_flush_output()
6847 return gl->redisplay && !gl->postpone && gl_redisplay(gl, 1, NULL); in gl_flush_output()
6850 gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO); in gl_flush_output()
6854 gl_record_status(gl, errno==EINTR ? GLR_SIGNAL : GLR_ERROR, errno); in gl_flush_output()
6870 GetLine *gl = (GetLine *) data; in GL_WRITE_FN() local
6875 int nnew = write(gl->output_fd, s, n-ndone); in GL_WRITE_FN()
6929 static int gl_change_editor(GetLine *gl, GlEditor editor) in gl_change_editor() argument
6936 _kt_clear_bindings(gl->bindings, KTB_NORM); in gl_change_editor()
6937 _kt_clear_bindings(gl->bindings, KTB_TERM); in gl_change_editor()
6938 (void) _kt_add_bindings(gl->bindings, KTB_NORM, gl_emacs_bindings, in gl_change_editor()
6942 _kt_clear_bindings(gl->bindings, KTB_NORM); in gl_change_editor()
6943 _kt_clear_bindings(gl->bindings, KTB_TERM); in gl_change_editor()
6944 (void) _kt_add_bindings(gl->bindings, KTB_NORM, gl_vi_bindings, in gl_change_editor()
6950 _err_record_msg(gl->err, "Unknown editor", END_ERR_MSG); in gl_change_editor()
6957 gl->editor = editor; in gl_change_editor()
6958 gl->vi.command = 0; /* Start in input mode */ in gl_change_editor()
6959 gl->insert_curpos = 0; in gl_change_editor()
6963 if(gl->editor != GL_NO_EDITOR && gl->input_fp) in gl_change_editor()
6964 (void) gl_bind_terminal_keys(gl); in gl_change_editor()
6973 return gl_change_editor(gl, GL_EMACS_MODE); in KT_KEY_FN()
6981 return gl_change_editor(gl, GL_VI_MODE); in KT_KEY_FN()
6993 gl_save_for_undo(gl); in KT_KEY_FN()
6997 gl->insert = 1; in KT_KEY_FN()
6998 gl->vi.command = 0; in KT_KEY_FN()
6999 gl->insert_curpos = gl->buff_curpos; in KT_KEY_FN()
7012 gl_save_for_undo(gl); in KT_KEY_FN()
7016 gl->insert = 0; in KT_KEY_FN()
7017 gl->vi.command = 0; in KT_KEY_FN()
7018 gl->insert_curpos = gl->buff_curpos; in KT_KEY_FN()
7032 int insert = gl->insert; in KT_KEY_FN()
7037 gl_save_for_undo(gl); in KT_KEY_FN()
7041 gl->insert = 0; in KT_KEY_FN()
7045 for(i=0; i<count && gl->buff_curpos < gl->ntotal; i++) { in KT_KEY_FN()
7046 char *cptr = gl->line + gl->buff_curpos++; in KT_KEY_FN()
7051 gl_buffer_char(gl, toupper((int) *cptr), cptr - gl->line); in KT_KEY_FN()
7053 gl_buffer_char(gl, tolower((int) *cptr), cptr - gl->line); in KT_KEY_FN()
7058 if(gl_print_char(gl, *cptr, cptr[1])) in KT_KEY_FN()
7064 gl->insert = insert; in KT_KEY_FN()
7065 return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ in KT_KEY_FN()
7074 gl_save_for_undo(gl); in KT_KEY_FN()
7075 return gl_beginning_of_line(gl, 0, NULL) || in KT_KEY_FN()
7076 gl_vi_insert(gl, 0, NULL); in KT_KEY_FN()
7087 gl_save_for_undo(gl); in KT_KEY_FN()
7088 gl->vi.command = 0; /* Allow cursor at EOL */ in KT_KEY_FN()
7089 return gl_end_of_line(gl, 0, NULL) || in KT_KEY_FN()
7090 gl_vi_insert(gl, 0, NULL); in KT_KEY_FN()
7100 gl_save_for_undo(gl); in KT_KEY_FN()
7101 gl->vi.command = 0; /* Allow cursor at EOL */ in KT_KEY_FN()
7102 return gl_cursor_right(gl, 1, NULL) || in KT_KEY_FN()
7103 gl_vi_insert(gl, 0, NULL); in KT_KEY_FN()
7112 return gl_place_cursor(gl, count - 1); in KT_KEY_FN()
7126 int insert = gl->insert; in KT_KEY_FN()
7130 if(gl->vi.repeat.active) { in KT_KEY_FN()
7131 c = gl->vi.repeat.input_char; in KT_KEY_FN()
7133 if(gl_read_terminal(gl, 1, &c)) in KT_KEY_FN()
7135 gl->vi.repeat.input_char = c; in KT_KEY_FN()
7140 if(gl->ntotal - gl->buff_curpos >= count) { in KT_KEY_FN()
7145 gl_save_for_undo(gl); in KT_KEY_FN()
7149 gl->insert = 0; in KT_KEY_FN()
7155 gl_add_char_to_line(gl, c); in KT_KEY_FN()
7159 gl->insert = insert; in KT_KEY_FN()
7161 return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ in KT_KEY_FN()
7170 gl_save_for_undo(gl); in KT_KEY_FN()
7171 gl->vi.command = 0; /* Allow cursor at EOL */ in KT_KEY_FN()
7172 return gl_kill_line(gl, count, NULL) || gl_vi_insert(gl, 0, NULL); in KT_KEY_FN()
7181 return gl_backward_kill_line(gl,count,NULL) || gl_vi_insert(gl,0,NULL); in KT_KEY_FN()
7190 return gl_delete_line(gl,count,NULL) || gl_vi_insert(gl,0,NULL); in KT_KEY_FN()
7202 if(gl->buff_curpos + count >= gl->ntotal) in KT_KEY_FN()
7203 count = gl->ntotal - gl->buff_curpos; in KT_KEY_FN()
7209 memcpy(gl->cutbuf, gl->line + gl->buff_curpos, count); in KT_KEY_FN()
7210 gl->cutbuf[count] = '\0'; in KT_KEY_FN()
7224 if(count > gl->buff_curpos) in KT_KEY_FN()
7225 count = gl->buff_curpos; in KT_KEY_FN()
7228 gl_place_cursor(gl, gl->buff_curpos - count); in KT_KEY_FN()
7232 memcpy(gl->cutbuf, gl->line + gl->buff_curpos, count); in KT_KEY_FN()
7233 gl->cutbuf[count] = '\0'; in KT_KEY_FN()
7243 if (--count >= gl->buff_curpos) in KT_KEY_FN()
7244 return gl_forward_copy_char(gl, count - gl->buff_curpos, NULL); in KT_KEY_FN()
7246 return gl_backward_copy_char(gl, gl->buff_curpos - count, NULL); in KT_KEY_FN()
7255 int curpos = gl_index_of_matching_paren(gl); in KT_KEY_FN()
7257 gl_save_for_undo(gl); in KT_KEY_FN()
7258 if(curpos >= gl->buff_curpos) in KT_KEY_FN()
7259 return gl_forward_copy_char(gl, curpos - gl->buff_curpos + 1, NULL); in KT_KEY_FN()
7261 return gl_backward_copy_char(gl, ++gl->buff_curpos - curpos + 1, NULL); in KT_KEY_FN()
7275 memcpy(gl->cutbuf, gl->line + gl->buff_curpos, gl->ntotal - gl->buff_curpos); in KT_KEY_FN()
7276 gl->cutbuf[gl->ntotal - gl->buff_curpos] = '\0'; in KT_KEY_FN()
7289 memcpy(gl->cutbuf, gl->line, gl->buff_curpos); in KT_KEY_FN()
7290 gl->cutbuf[gl->buff_curpos] = '\0'; in KT_KEY_FN()
7291 gl_place_cursor(gl, 0); in KT_KEY_FN()
7303 memcpy(gl->cutbuf, gl->line, gl->ntotal); in KT_KEY_FN()
7304 gl->cutbuf[gl->ntotal] = '\0'; in KT_KEY_FN()
7313 int pos = gl_find_char(gl, count, 1, 1, '\0'); in KT_KEY_FN()
7314 return pos >= 0 && gl_place_cursor(gl, pos); in KT_KEY_FN()
7322 int pos = gl_find_char(gl, count, 0, 1, '\0'); in KT_KEY_FN()
7323 return pos >= 0 && gl_place_cursor(gl, pos); in KT_KEY_FN()
7332 int pos = gl_find_char(gl, count, 1, 0, '\0'); in KT_KEY_FN()
7333 return pos >= 0 && gl_place_cursor(gl, pos); in KT_KEY_FN()
7342 int pos = gl_find_char(gl, count, 0, 0, '\0'); in KT_KEY_FN()
7343 return pos >= 0 && gl_place_cursor(gl, pos); in KT_KEY_FN()
7365 static int gl_find_char(GetLine *gl, int count, int forward, int onto, char c) in gl_find_char() argument
7377 if(gl->vi.repeat.active) { in gl_find_char()
7378 c = gl->vi.find_char; in gl_find_char()
7380 if(gl_read_terminal(gl, 1, &c)) in gl_find_char()
7385 gl->vi.find_forward = forward; in gl_find_char()
7386 gl->vi.find_onto = onto; in gl_find_char()
7387 gl->vi.find_char = c; in gl_find_char()
7398 for(i=0, pos=gl->buff_curpos; i<count && pos < gl->ntotal; i++) { in gl_find_char()
7407 for( ; pos<gl->ntotal && c!=gl->line[pos]; pos++) in gl_find_char()
7415 if(!onto && pos<gl->ntotal) in gl_find_char()
7422 for(i=0, pos=gl->buff_curpos; i<count && pos >= gl->insert_curpos; i++) { in gl_find_char()
7431 for( ; pos>=gl->insert_curpos && c!=gl->line[pos]; pos--) in gl_find_char()
7439 if(!onto && pos>=gl->insert_curpos) in gl_find_char()
7446 if(pos >= gl->insert_curpos && pos < gl->ntotal) { in gl_find_char()
7449 (void) gl_ring_bell(gl, 1, NULL); in gl_find_char()
7460 int pos = gl->vi.find_char ? in KT_KEY_FN()
7461 gl_find_char(gl, count, gl->vi.find_forward, gl->vi.find_onto, in KT_KEY_FN()
7462 gl->vi.find_char) : -1; in KT_KEY_FN()
7463 return pos >= 0 && gl_place_cursor(gl, pos); in KT_KEY_FN()
7472 int pos = gl->vi.find_char ? in KT_KEY_FN()
7473 gl_find_char(gl, count, !gl->vi.find_forward, gl->vi.find_onto, in KT_KEY_FN()
7474 gl->vi.find_char) : -1; in KT_KEY_FN()
7475 return pos >= 0 && gl_place_cursor(gl, pos); in KT_KEY_FN()
7489 static int gl_nth_word_end_forward(GetLine *gl, int n) in gl_nth_word_end_forward() argument
7498 bufpos = gl->buff_curpos + 1; in gl_nth_word_end_forward()
7504 if(bufpos >= gl->ntotal) in gl_nth_word_end_forward()
7505 return gl->ntotal - 1; in gl_nth_word_end_forward()
7509 for(i=0; i<n && bufpos<gl->ntotal; i++) { in gl_nth_word_end_forward()
7513 for( ; bufpos<gl->ntotal && !gl_is_word_char((int)gl->line[bufpos]); in gl_nth_word_end_forward()
7519 for( ; bufpos<gl->ntotal && gl_is_word_char((int)gl->line[bufpos]); in gl_nth_word_end_forward()
7540 static int gl_nth_word_start_forward(GetLine *gl, int n) in gl_nth_word_start_forward() argument
7547 bufpos = gl->buff_curpos; in gl_nth_word_start_forward()
7551 for(i=0; i<n && bufpos<gl->ntotal; i++) { in gl_nth_word_start_forward()
7555 for( ; bufpos<gl->ntotal && gl_is_word_char((int)gl->line[bufpos]); in gl_nth_word_start_forward()
7561 for( ; bufpos<gl->ntotal && !gl_is_word_char((int)gl->line[bufpos]); in gl_nth_word_start_forward()
7579 static int gl_nth_word_start_backward(GetLine *gl, int n) in gl_nth_word_start_backward() argument
7586 bufpos = gl->buff_curpos; in gl_nth_word_start_backward()
7591 for(i=0; i<n && bufpos > gl->insert_curpos; i++) { in gl_nth_word_start_backward()
7597 while(--bufpos >= gl->insert_curpos && in gl_nth_word_start_backward()
7598 !gl_is_word_char((int)gl->line[bufpos])) in gl_nth_word_start_backward()
7603 while(--bufpos >= gl->insert_curpos && in gl_nth_word_start_backward()
7604 gl_is_word_char((int)gl->line[bufpos])) in gl_nth_word_start_backward()
7611 return bufpos >= gl->insert_curpos ? bufpos : gl->insert_curpos; in gl_nth_word_start_backward()
7624 int next = gl->editor == GL_EMACS_MODE ? in KT_KEY_FN()
7625 gl_nth_word_end_forward(gl, count) : in KT_KEY_FN()
7626 gl_nth_word_start_forward(gl, count); in KT_KEY_FN()
7630 int n = next - gl->buff_curpos; in KT_KEY_FN()
7634 memcpy(gl->cutbuf, gl->line + gl->buff_curpos, n); in KT_KEY_FN()
7635 gl->cutbuf[n] = '\0'; in KT_KEY_FN()
7648 int next = gl_nth_word_start_backward(gl, count); in KT_KEY_FN()
7652 int n = gl->buff_curpos - next; in KT_KEY_FN()
7653 gl_place_cursor(gl, next); in KT_KEY_FN()
7657 memcpy(gl->cutbuf, gl->line + next, n); in KT_KEY_FN()
7658 gl->cutbuf[n] = '\0'; in KT_KEY_FN()
7681 static int gl_copy_find(GetLine *gl, int count, char c, int forward, int onto) in gl_copy_find() argument
7687 int pos = gl_find_char(gl, count, forward, onto, c); in gl_copy_find()
7694 n = pos + 1 - gl->buff_curpos; in gl_copy_find()
7695 memcpy(gl->cutbuf, gl->line + gl->buff_curpos, n); in gl_copy_find()
7697 n = gl->buff_curpos - pos; in gl_copy_find()
7698 memcpy(gl->cutbuf, gl->line + pos, n); in gl_copy_find()
7699 if(gl->editor == GL_VI_MODE) in gl_copy_find()
7700 gl_place_cursor(gl, pos); in gl_copy_find()
7705 gl->cutbuf[n] = '\0'; in gl_copy_find()
7715 return gl_copy_find(gl, count, '\0', 1, 1); in KT_KEY_FN()
7724 return gl_copy_find(gl, count, '\0', 0, 1); in KT_KEY_FN()
7733 return gl_copy_find(gl, count, '\0', 1, 0); in KT_KEY_FN()
7742 return gl_copy_find(gl, count, '\0', 0, 0); in KT_KEY_FN()
7751 return gl_copy_find(gl, count, gl->vi.find_char, gl->vi.find_forward, in KT_KEY_FN()
7752 gl->vi.find_onto); in KT_KEY_FN()
7761 return gl_copy_find(gl, count, gl->vi.find_char, !gl->vi.find_forward, in KT_KEY_FN()
7762 gl->vi.find_onto); in KT_KEY_FN()
7776 static int gl_place_cursor(GetLine *gl, int buff_curpos) in gl_place_cursor() argument
7782 if(buff_curpos >= gl->ntotal) in gl_place_cursor()
7783 buff_curpos = gl->vi.command ? gl->ntotal-1 : gl->ntotal; in gl_place_cursor()
7789 gl->buff_curpos = buff_curpos; in gl_place_cursor()
7793 return gl_set_term_curpos(gl, gl->prompt_len + in gl_place_cursor()
7794 gl_displayed_string_width(gl, gl->line, buff_curpos, gl->prompt_len)); in gl_place_cursor()
7808 static void gl_save_for_undo(GetLine *gl) in gl_save_for_undo() argument
7810 if(gl->vi.command && !gl->vi.undo.saved) { in gl_save_for_undo()
7811 strlcpy(gl->vi.undo.line, gl->line, gl->linelen); in gl_save_for_undo()
7812 gl->vi.undo.buff_curpos = gl->buff_curpos; in gl_save_for_undo()
7813 gl->vi.undo.ntotal = gl->ntotal; in gl_save_for_undo()
7814 gl->vi.undo.saved = 1; in gl_save_for_undo()
7816 if(gl->vi.command && !gl->vi.repeat.saved && in gl_save_for_undo()
7817 gl->current_action.fn != gl_vi_repeat_change) { in gl_save_for_undo()
7818 gl->vi.repeat.action = gl->current_action; in gl_save_for_undo()
7819 gl->vi.repeat.count = gl->current_count; in gl_save_for_undo()
7820 gl->vi.repeat.saved = 1; in gl_save_for_undo()
7835 char *undo_ptr = gl->vi.undo.line; in KT_KEY_FN()
7836 char *line_ptr = gl->line; in KT_KEY_FN()
7849 if(gl->ntotal > gl->vi.undo.ntotal) { in KT_KEY_FN()
7850 strlcpy(undo_ptr, line_ptr, gl->linelen); in KT_KEY_FN()
7853 strlcpy(line_ptr, undo_ptr, gl->linelen); in KT_KEY_FN()
7859 gl->vi.undo.ntotal = gl->ntotal; in KT_KEY_FN()
7863 gl_update_buffer(gl); in KT_KEY_FN()
7868 if(gl->buff_curpos < gl->vi.undo.buff_curpos) in KT_KEY_FN()
7869 gl->vi.undo.buff_curpos = gl->buff_curpos; in KT_KEY_FN()
7871 gl->buff_curpos = gl->vi.undo.buff_curpos; in KT_KEY_FN()
7876 gl->vi.repeat.action.fn = gl_vi_undo; in KT_KEY_FN()
7877 gl->vi.repeat.action.data = NULL; in KT_KEY_FN()
7878 gl->vi.repeat.count = 1; in KT_KEY_FN()
7882 gl_queue_redisplay(gl); in KT_KEY_FN()
7891 gl_save_for_undo(gl); in KT_KEY_FN()
7892 gl->vi.command = 0; /* Allow cursor at EOL */ in KT_KEY_FN()
7893 return gl_forward_delete_word(gl, count, NULL) || gl_vi_insert(gl, 0, NULL); in KT_KEY_FN()
7901 return gl_backward_delete_word(gl, count, NULL) || gl_vi_insert(gl, 0, NULL); in KT_KEY_FN()
7909 return gl_delete_find(gl, count, '\0', 1, 1, 1); in KT_KEY_FN()
7917 return gl_delete_find(gl, count, '\0', 0, 1, 1); in KT_KEY_FN()
7925 return gl_delete_find(gl, count, '\0', 1, 0, 1); in KT_KEY_FN()
7933 return gl_delete_find(gl, count, '\0', 0, 0, 1); in KT_KEY_FN()
7942 return gl_delete_find(gl, count, gl->vi.find_char, gl->vi.find_forward, in KT_KEY_FN()
7943 gl->vi.find_onto, 1); in KT_KEY_FN()
7952 return gl_delete_find(gl, count, gl->vi.find_char, !gl->vi.find_forward, in KT_KEY_FN()
7953 gl->vi.find_onto, 1); in KT_KEY_FN()
7961 gl_save_for_undo(gl); in KT_KEY_FN()
7962 gl->vi.command = 0; /* Allow cursor at EOL */ in KT_KEY_FN()
7963 return gl_delete_chars(gl, count, 1) || gl_vi_insert(gl, 0, NULL); in KT_KEY_FN()
7971 return gl_backward_delete_char(gl, count, NULL) || gl_vi_insert(gl, 0, NULL); in KT_KEY_FN()
7979 if (--count >= gl->buff_curpos) in KT_KEY_FN()
7980 return gl_vi_forward_change_char(gl, count - gl->buff_curpos, NULL); in KT_KEY_FN()
7982 return gl_vi_backward_change_char(gl, gl->buff_curpos - count, NULL); in KT_KEY_FN()
7991 int curpos = gl_index_of_matching_paren(gl); in KT_KEY_FN()
7993 gl_save_for_undo(gl); in KT_KEY_FN()
7994 if(curpos >= gl->buff_curpos) in KT_KEY_FN()
7995 return gl_vi_forward_change_char(gl, curpos - gl->buff_curpos + 1, NULL); in KT_KEY_FN()
7997 return gl_vi_backward_change_char(gl, ++gl->buff_curpos - curpos + 1, in KT_KEY_FN()
8009 static void gl_vi_command_mode(GetLine *gl) in gl_vi_command_mode() argument
8011 if(gl->editor == GL_VI_MODE && !gl->vi.command) { in gl_vi_command_mode()
8012 gl->insert = 1; in gl_vi_command_mode()
8013 gl->vi.command = 1; in gl_vi_command_mode()
8014 gl->vi.repeat.input_curpos = gl->insert_curpos; in gl_vi_command_mode()
8015 gl->vi.repeat.command_curpos = gl->buff_curpos; in gl_vi_command_mode()
8016 gl->insert_curpos = 0; /* unrestrict left motion boundary */ in gl_vi_command_mode()
8017 gl_cursor_left(gl, 1, NULL); /* Vi moves 1 left on entering command mode */ in gl_vi_command_mode()
8026 return gl->silence_bell ? 0 : in KT_KEY_FN()
8027 gl_print_control_sequence(gl, 1, gl->sound_bell); in KT_KEY_FN()
8041 if(!gl->vi.repeat.action.fn) in KT_KEY_FN()
8042 return gl_ring_bell(gl, 1, NULL); in KT_KEY_FN()
8047 gl->vi.repeat.active = 1; in KT_KEY_FN()
8051 status = gl->vi.repeat.action.fn(gl, gl->vi.repeat.count, in KT_KEY_FN()
8052 gl->vi.repeat.action.data); in KT_KEY_FN()
8056 gl->vi.repeat.active = 0; in KT_KEY_FN()
8062 if(status==0 && !gl->vi.command) { in KT_KEY_FN()
8066 gl_save_for_undo(gl); in KT_KEY_FN()
8070 if(gl->vi.repeat.input_curpos >= 0 && in KT_KEY_FN()
8071 gl->vi.repeat.input_curpos <= gl->vi.repeat.command_curpos && in KT_KEY_FN()
8072 gl->vi.repeat.command_curpos <= gl->vi.undo.ntotal) { in KT_KEY_FN()
8079 for(i=gl->vi.repeat.input_curpos; i<gl->vi.repeat.command_curpos; i++) { in KT_KEY_FN()
8080 if(gl_add_char_to_line(gl, gl->vi.undo.line[i])) in KT_KEY_FN()
8087 gl_vi_command_mode(gl); in KT_KEY_FN()
8105 static int gl_index_of_matching_paren(GetLine *gl) in gl_index_of_matching_paren() argument
8117 char c = gl->line[gl->buff_curpos]; in gl_index_of_matching_paren()
8125 for(i=gl->buff_curpos+1; i<gl->ntotal; i++) { in gl_index_of_matching_paren()
8126 if(gl->line[i] == c) in gl_index_of_matching_paren()
8128 else if(gl->line[i] == match && --matches_needed==0) in gl_index_of_matching_paren()
8138 for(i=gl->buff_curpos-1; i>=0; i--) { in gl_index_of_matching_paren()
8139 if(gl->line[i] == c) in gl_index_of_matching_paren()
8141 else if(gl->line[i] == match && --matches_needed==0) in gl_index_of_matching_paren()
8149 for(i=gl->buff_curpos+1; i<gl->ntotal; i++) in gl_index_of_matching_paren()
8150 if(strchr(c_paren, gl->line[i]) != NULL) in gl_index_of_matching_paren()
8156 (void) gl_ring_bell(gl, 1, NULL); in gl_index_of_matching_paren()
8166 int curpos = gl_index_of_matching_paren(gl); in KT_KEY_FN()
8168 return gl_place_cursor(gl, curpos); in KT_KEY_FN()
8183 static int gl_interpret_char(GetLine *gl, char first_char) in gl_interpret_char() argument
8198 if(gl->editor == GL_NO_EDITOR) { in gl_interpret_char()
8199 gl_discard_chars(gl, 1); in gl_interpret_char()
8200 if(gl->ntotal >= gl->linelen) in gl_interpret_char()
8203 return gl_newline(gl, 1, NULL); in gl_interpret_char()
8204 gl_buffer_char(gl, c, gl->ntotal); in gl_interpret_char()
8211 if(gl->number >= 0 && isdigit((int)(unsigned char) c)) { in gl_interpret_char()
8212 gl_discard_chars(gl, 1); in gl_interpret_char()
8213 return gl_digit_argument(gl, c, NULL); in gl_interpret_char()
8218 } else if(gl->vi.command && c != GL_ESC_CHAR) { in gl_interpret_char()
8254 if(keyseq[0] == GL_ESC_CHAR && !gl->vi.command) in gl_interpret_char()
8255 gl_vi_command_mode(gl); in gl_interpret_char()
8259 switch(_kt_lookup_keybinding(gl->bindings, keyseq, nkey, &keysym, &nsym)) { in gl_interpret_char()
8272 count = gl->number >= 0 ? gl->number : 1; in gl_interpret_char()
8277 gl->current_action = *action; in gl_interpret_char()
8278 gl->current_count = count; in gl_interpret_char()
8282 gl->vi.undo.saved = 0; in gl_interpret_char()
8283 gl->vi.repeat.saved = 0; in gl_interpret_char()
8290 ret = action->fn(gl, count, action->data); in gl_interpret_char()
8298 if(gl->rtn_status == GLR_BLOCKED && gl->pending_io==GLP_READ) in gl_interpret_char()
8303 gl_discard_chars(gl, gl->nread); in gl_interpret_char()
8308 if(gl->last_search != gl->keyseq_count) in gl_interpret_char()
8309 _glh_cancel_search(gl->glh); in gl_interpret_char()
8314 gl->number = -1; in gl_interpret_char()
8318 if(gl_read_terminal(gl, 1, &c)) in gl_interpret_char()
8328 gl_ring_bell(gl, 1, NULL); in gl_interpret_char()
8335 count = gl->number >= 0 ? gl->number : 1; in gl_interpret_char()
8337 gl_add_char_to_line(gl, first_char); in gl_interpret_char()
8338 gl->number = -1; in gl_interpret_char()
8340 gl_discard_chars(gl, 1); in gl_interpret_char()
8341 _glh_cancel_search(gl->glh); in gl_interpret_char()
8345 gl_ring_bell(gl, 1, NULL); in gl_interpret_char()
8346 gl_discard_chars(gl, gl->nread); in gl_interpret_char()
8347 _glh_cancel_search(gl->glh); in gl_interpret_char()
8359 gl_ring_bell(gl, 1, NULL); in gl_interpret_char()
8360 gl_discard_chars(gl, 1); in gl_interpret_char()
8393 int gl_configure_getline(GetLine *gl, const char *app_string, in gl_configure_getline() argument
8401 if(!gl) { in gl_configure_getline()
8408 if(gl_mask_signals(gl, &oldset)) in gl_configure_getline()
8413 status = _gl_configure_getline(gl, app_string, app_file, user_file); in gl_configure_getline()
8417 gl_unmask_signals(gl, &oldset); in gl_configure_getline()
8426 static int _gl_configure_getline(GetLine *gl, const char *app_string, in _gl_configure_getline() argument
8432 gl->configured = 1; in _gl_configure_getline()
8437 (void) _gl_read_config_string(gl, app_string, KTB_NORM); in _gl_configure_getline()
8442 (void) _gl_read_config_file(gl, app_file, KTB_NORM); in _gl_configure_getline()
8447 (void) _gl_read_config_file(gl, user_file, KTB_USER); in _gl_configure_getline()
8452 if(gl_record_string(&gl->app_file, app_file) || in _gl_configure_getline()
8453 gl_record_string(&gl->user_file, user_file)) { in _gl_configure_getline()
8455 _err_record_msg(gl->err, in _gl_configure_getline()
8515 return _gl_configure_getline(gl, NULL, gl->app_file, gl->user_file); in KT_KEY_FN()
8537 int gl_save_history(GetLine *gl, const char *filename, const char *comment, in gl_save_history() argument
8545 if(!gl || !filename || !comment) { in gl_save_history()
8546 if(gl) in gl_save_history()
8547 _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG); in gl_save_history()
8554 if(gl_mask_signals(gl, &oldset)) in gl_save_history()
8559 status = _gl_save_history(gl, filename, comment, max_lines); in gl_save_history()
8563 gl_unmask_signals(gl, &oldset); in gl_save_history()
8572 static int _gl_save_history(GetLine *gl, const char *filename, in _gl_save_history() argument
8580 _err_record_msg(gl->err, "Can't save history without filesystem access", in _gl_save_history()
8589 expansion = ef_expand_file(gl->ef, filename, -1); in _gl_save_history()
8591 gl_print_info(gl, "Unable to expand ", filename, " (", in _gl_save_history()
8592 ef_last_error(gl->ef), ").", GL_END_INFO); in _gl_save_history()
8598 if(_glh_save_history(gl->glh, expansion->files[0], comment, max_lines)) { in _gl_save_history()
8599 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG); in _gl_save_history()
8619 int gl_load_history(GetLine *gl, const char *filename, const char *comment) in gl_load_history() argument
8626 if(!gl || !filename || !comment) { in gl_load_history()
8627 if(gl) in gl_load_history()
8628 _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG); in gl_load_history()
8635 if(gl_mask_signals(gl, &oldset)) in gl_load_history()
8640 status = _gl_load_history(gl, filename, comment); in gl_load_history()
8644 gl_unmask_signals(gl, &oldset); in gl_load_history()
8653 static int _gl_load_history(GetLine *gl, const char *filename, in _gl_load_history() argument
8661 _err_record_msg(gl->err, "Can't load history without filesystem access", in _gl_load_history()
8670 expansion = ef_expand_file(gl->ef, filename, -1); in _gl_load_history()
8672 gl_print_info(gl, "Unable to expand ", filename, " (", in _gl_load_history()
8673 ef_last_error(gl->ef), ").", GL_END_INFO); in _gl_load_history()
8679 if(_glh_load_history(gl->glh, expansion->files[0], comment, in _gl_load_history()
8680 gl->cutbuf, gl->linelen+1)) { in _gl_load_history()
8681 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG); in _gl_load_history()
8682 gl->cutbuf[0] = '\0'; in _gl_load_history()
8685 gl->cutbuf[0] = '\0'; in _gl_load_history()
8712 int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event, in gl_watch_fd() argument
8720 if(!gl) { in gl_watch_fd()
8725 _err_record_msg(gl->err, "Error: fd < 0", END_ERR_MSG); in gl_watch_fd()
8732 if(gl_mask_signals(gl, &oldset)) in gl_watch_fd()
8737 status = _gl_watch_fd(gl, fd, event, callback, data); in gl_watch_fd()
8741 gl_unmask_signals(gl, &oldset); in gl_watch_fd()
8750 static int _gl_watch_fd(GetLine *gl, int fd, GlFdEvent event, in _gl_watch_fd() argument
8762 for(prev=NULL,node=gl->fd_nodes; node && node->fd != fd;
8777 node = (GlFdNode *) _new_FreeListNode(gl->fd_node_mem);
8780 _err_record_msg(gl->err, "Insufficient memory", END_ERR_MSG);
8786 node->next = gl->fd_nodes;
8787 gl->fd_nodes = node;
8804 FD_SET(fd, &gl->rfds);
8806 FD_CLR(fd, &gl->rfds);
8812 FD_SET(fd, &gl->wfds);
8814 FD_CLR(fd, &gl->wfds);
8820 FD_SET(fd, &gl->ufds);
8822 FD_CLR(fd, &gl->ufds);
8828 if(fd > gl->max_fd)
8829 gl->max_fd = fd;
8839 gl->fd_nodes = node->next;
8840 node = (GlFdNode *) _del_FreeListNode(gl->fd_node_mem, node);
8885 int gl_inactivity_timeout(GetLine *gl, GlTimeoutFn *timeout_fn, void *data, in gl_inactivity_timeout() argument
8895 if(!gl) {
8902 if(gl_mask_signals(gl, &oldset))
8908 gl->timer.dt.tv_sec = sec;
8909 gl->timer.dt.tv_usec = nsec / 1000;
8910 gl->timer.fn = timeout_fn;
8911 gl->timer.data = data;
8913 gl->timer.fn = 0;
8914 gl->timer.data = NULL;
8919 gl_unmask_signals(gl, &oldset);
8937 static int gl_event_handler(GetLine *gl, int fd) in gl_event_handler() argument
8954 while(gl->fd_nodes || gl->timer.fn) { in gl_event_handler()
8959 fd_set rfds = gl->rfds; in gl_event_handler()
8960 fd_set wfds = gl->wfds; in gl_event_handler()
8961 fd_set ufds = gl->ufds; in gl_event_handler()
8965 struct timeval dt = gl->timer.fn ? gl->timer.dt : zero; in gl_event_handler()
8975 gl_catch_signals(gl); in gl_event_handler()
8979 nready = select(gl->max_fd+1, &rfds, &wfds, &ufds, in gl_event_handler()
8980 (gl->timer.fn || gl->io_mode==GL_SERVER_MODE) ? &dt : NULL); in gl_event_handler()
8988 gl_mask_signals(gl, NULL); in gl_event_handler()
9000 if(gl_call_timeout_handler(gl)) { in gl_event_handler()
9002 } else if(gl->io_mode == GL_SERVER_MODE) { in gl_event_handler()
9003 gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO); in gl_event_handler()
9011 gl_record_status(gl, GLR_ERROR, errno); in gl_event_handler()
9028 for(node=gl->fd_nodes; node; node=node->next) { in gl_event_handler()
9033 if(gl_call_fd_handler(gl, &node->ur, node->fd, GLFD_URGENT)) in gl_event_handler()
9040 if(gl_call_fd_handler(gl, &node->rd, node->fd, GLFD_READ)) in gl_event_handler()
9047 if(gl_call_fd_handler(gl, &node->wr, node->fd, GLFD_WRITE)) in gl_event_handler()
9057 if(gl_flush_output(gl)) in gl_event_handler()
9078 static int gl_call_fd_handler(GetLine *gl, GlFdHandler *gfh, int fd,
9088 if(tcgetattr(gl->input_fd, &attr)) {
9089 _err_record_msg(gl->err, "tcgetattr error", END_ERR_MSG);
9093 while(tcsetattr(gl->input_fd, TCSADRAIN, &attr)) {
9095 _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG);
9102 switch(gfh->fn(gl, gfh->data, fd, event)) {
9105 gl_record_status(gl, GLR_FDABORT, 0);
9109 gl_queue_redisplay(gl);
9118 while(tcsetattr(gl->input_fd, TCSADRAIN, &attr)) {
9120 _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG);
9137 static int gl_call_timeout_handler(GetLine *gl)
9144 if(!gl->timer.fn)
9151 if(tcgetattr(gl->input_fd, &attr)) {
9152 _err_record_msg(gl->err, "tcgetattr error", END_ERR_MSG);
9156 while(tcsetattr(gl->input_fd, TCSADRAIN, &attr)) {
9158 _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG);
9165 switch(gl->timer.fn(gl, gl->timer.data)) {
9168 gl_record_status(gl, GLR_TIMEOUT, 0);
9172 gl_queue_redisplay(gl);
9181 while(tcsetattr(gl->input_fd, TCSADRAIN, &attr)) {
9183 _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG);
9207 int gl_group_history(GetLine *gl, unsigned id)
9214 if(!gl) {
9221 if(gl_mask_signals(gl, &oldset))
9226 if(_glh_get_group(gl->glh) == id) {
9231 } else if(_glh_set_group(gl->glh, id)) {
9232 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
9239 gl->preload_history = 0;
9240 gl->last_search = -1;
9246 gl_unmask_signals(gl, &oldset);
9279 int gl_show_history(GetLine *gl, FILE *fp, const char *fmt, int all_groups,
9287 if(!gl || !fp || !fmt) {
9288 if(gl)
9289 _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG);
9296 if(gl_mask_signals(gl, &oldset))
9301 status = _glh_show_history(gl->glh, _io_write_stdio, fp, fmt, all_groups,
9304 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
9308 gl_unmask_signals(gl, &oldset);
9324 GlTerminalSize gl_terminal_size(GetLine *gl, int def_ncolumn, int def_nline)
9332 gl_mask_signals(gl, &oldset);
9336 _gl_terminal_size(gl, def_ncolumn, def_nline, &size);
9340 gl_unmask_signals(gl, &oldset);
9349 static void _gl_terminal_size(GetLine *gl, int def_ncolumn, int def_nline,
9358 gl->nline = 0;
9359 gl->ncolumn = 0;
9363 if(gl->is_term) {
9367 (void) _gl_update_size(gl);
9379 if(gl->nline < 1) {
9381 gl->nline = n;
9384 gl->nline = tigetnum((char *)"lines");
9387 gl->nline = tgetnum("li");
9396 if(gl->ncolumn < 1) {
9398 gl->ncolumn = n;
9401 gl->ncolumn = tigetnum((char *)"cols");
9404 gl->ncolumn = tgetnum("co");
9412 if(gl->nline <= 0)
9413 gl->nline = def_nline;
9414 if(gl->ncolumn <= 0)
9415 gl->ncolumn = def_ncolumn;
9420 size->nline = gl->nline;
9421 size->ncolumn = gl->ncolumn;
9439 int gl_resize_history(GetLine *gl, size_t bufsize)
9446 if(!gl)
9451 if(gl_mask_signals(gl, &oldset))
9456 status = _glh_resize_history(gl->glh, bufsize);
9458 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
9462 gl_unmask_signals(gl, &oldset);
9476 void gl_limit_history(GetLine *gl, int max_lines)
9478 if(gl) {
9483 gl_mask_signals(gl, &oldset);
9487 _glh_limit_history(gl->glh, max_lines);
9491 gl_unmask_signals(gl, &oldset);
9505 void gl_clear_history(GetLine *gl, int all_groups)
9507 if(gl) {
9512 gl_mask_signals(gl, &oldset);
9516 _glh_clear_history(gl->glh, all_groups);
9520 gl_unmask_signals(gl, &oldset);
9532 void gl_toggle_history(GetLine *gl, int enable)
9534 if(gl) {
9539 gl_mask_signals(gl, &oldset);
9543 _glh_toggle_history(gl->glh, enable);
9547 gl_unmask_signals(gl, &oldset);
9578 int gl_lookup_history(GetLine *gl, unsigned long id, GlHistoryLine *line)
9585 if(!gl)
9590 if(gl_mask_signals(gl, &oldset))
9595 status = _glh_lookup_history(gl->glh, (GlhLineID) id, &line->line,
9598 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
9602 gl_unmask_signals(gl, &oldset);
9616 void gl_state_of_history(GetLine *gl, GlHistoryState *state)
9618 if(gl && state) {
9623 gl_mask_signals(gl, &oldset);
9627 _glh_state_of_history(gl->glh, &state->enabled, &state->group,
9632 gl_unmask_signals(gl, &oldset);
9645 void gl_range_of_history(GetLine *gl, GlHistoryRange *range)
9647 if(gl && range) {
9652 gl_mask_signals(gl, &oldset);
9656 _glh_range_of_history(gl->glh, &range->oldest, &range->newest,
9661 gl_unmask_signals(gl, &oldset);
9675 void gl_size_of_history(GetLine *gl, GlHistorySize *size)
9677 if(gl && size) {
9682 gl_mask_signals(gl, &oldset);
9686 _glh_size_of_history(gl->glh, &size->size, &size->used);
9690 gl_unmask_signals(gl, &oldset);
9703 if(gl_start_newline(gl, 1))
9708 _glh_show_history(gl->glh, gl_write_fn, gl, "%N %T %H\r\n", 0,
9713 gl_queue_redisplay(gl);
9733 int gl_echo_mode(GetLine *gl, int enable)
9735 if(gl) {
9741 gl_mask_signals(gl, &oldset);
9745 was_echoing = gl->echo;
9747 gl->echo = enable;
9751 gl_unmask_signals(gl, &oldset);
9769 static int gl_display_prompt(GetLine *gl)
9777 int kept_echo = gl->echo;
9778 gl->echo = 1;
9783 if(gl_print_control_sequence(gl, 1, gl->bol))
9788 gl->displayed = 1;
9792 switch(gl->prompt_style) {
9794 if(gl_print_string(gl, gl->prompt, '\0'))
9798 for(pptr=gl->prompt; *pptr; pptr++) {
9866 if(gl_print_control_sequence(gl, 1, gl->text_attr_off))
9875 gl_print_control_sequence(gl, 1, gl->bold))
9878 gl_print_control_sequence(gl, 1, gl->underline))
9881 gl_print_control_sequence(gl, 1, gl->standout))
9884 gl_print_control_sequence(gl, 1, gl->dim))
9887 gl_print_control_sequence(gl, 1, gl->reverse))
9890 gl_print_control_sequence(gl, 1, gl->blink))
9897 if(gl_print_char(gl, *pptr, pptr[1]))
9904 if(gl_print_control_sequence(gl, 1, gl->text_attr_off))
9911 gl->echo = kept_echo;
9915 gl->prompt_changed = 0;
9928 void gl_replace_prompt(GetLine *gl, const char *prompt)
9930 if(gl) {
9935 gl_mask_signals(gl, &oldset);
9939 _gl_replace_prompt(gl, prompt);
9943 gl_unmask_signals(gl, &oldset);
9952 static void _gl_replace_prompt(GetLine *gl, const char *prompt)
9964 if(gl->prompt != prompt) {
9973 if(!gl->prompt || slen > strlen(gl->prompt)) {
9974 char *new_prompt = gl->prompt ? realloc(gl->prompt, size) : malloc(size);
9977 gl->prompt = new_prompt;
9982 strlcpy(gl->prompt, prompt, size);
9987 gl->prompt_len = gl_displayed_prompt_width(gl);
9988 gl->prompt_changed = 1;
9989 gl_queue_redisplay(gl);
10002 static int gl_displayed_prompt_width(GetLine *gl)
10009 switch(gl->prompt_style) {
10011 return gl_displayed_string_width(gl, gl->prompt, -1, 0);
10018 for(pptr=gl->prompt; *pptr; pptr++) {
10038 slen += gl_displayed_char_width(gl, *pptr, slen);
10054 void gl_prompt_style(GetLine *gl, GlPromptStyle style)
10056 if(gl) {
10061 gl_mask_signals(gl, &oldset);
10065 if(style != gl->prompt_style) {
10066 gl->prompt_style = style;
10067 gl->prompt_len = gl_displayed_prompt_width(gl);
10068 gl->prompt_changed = 1;
10069 gl_queue_redisplay(gl);
10074 gl_unmask_signals(gl, &oldset);
10095 int gl_trap_signal(GetLine *gl, int signo, unsigned flags,
10103 if(!gl) {
10110 if(gl_mask_signals(gl, &oldset))
10115 status = _gl_trap_signal(gl, signo, flags, after, errno_value);
10119 gl_unmask_signals(gl, &oldset);
10128 static int _gl_trap_signal(GetLine *gl, int signo, unsigned flags,
10149 for(sig=gl->sigs; sig && sig->signo != signo; sig = sig->next)
10156 sig = (GlSignalNode *) _new_FreeListNode(gl->sig_mem);
10162 sig->next = gl->sigs;
10163 gl->sigs = sig;
10173 _err_record_msg(gl->err, "sigaddset error", END_ERR_MSG);
10174 sig = (GlSignalNode *) _del_FreeListNode(gl->sig_mem, sig);
10180 sigaddset(&gl->all_signal_set, signo);
10201 int gl_ignore_signal(GetLine *gl, int signo)
10210 if(!gl) {
10217 if(gl_mask_signals(gl, &oldset))
10223 for(prev=NULL,sig=gl->sigs; sig && sig->signo != signo;
10233 gl->sigs = sig->next;
10237 sig = (GlSignalNode *) _del_FreeListNode(gl->sig_mem, sig);
10241 sigdelset(&gl->all_signal_set, signo);
10246 gl_unmask_signals(gl, &oldset);
10264 static int gl_line_ended(GetLine *gl, int newline_char)
10271 if(gl_end_of_line(gl, 1, NULL) || gl_add_char_to_line(gl, newline_char))
10278 gl_buffer_char(gl, newline_char, gl->ntotal);
10284 if(gl->echo && gl->automatic_history && newline_char=='\n')
10285 (void) _gl_append_history(gl, gl->line);
10290 if(gl->editor != GL_NO_EDITOR && gl_start_newline(gl, 1))
10295 gl_record_status(gl, GLR_NEWLINE, 0);
10299 (void) gl_flush_output(gl);
10306 gl->pending_io = GLP_WRITE;
10323 int gl_last_signal(GetLine *gl)
10326 if(gl) {
10331 gl_mask_signals(gl, &oldset);
10335 signo = gl->last_signal;
10339 gl_unmask_signals(gl, &oldset);
10363 static int gl_present_line(GetLine *gl, const char *prompt,
10369 gl_reset_input_line(gl);
10374 _gl_replace_prompt(gl, prompt);
10378 if(_glh_cancel_search(gl->glh)) {
10379 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
10386 if(gl->preload_history) {
10387 gl->preload_history = 0;
10388 if(gl->preload_id) {
10389 if(_glh_recall_line(gl->glh, gl->preload_id, gl->line, gl->linelen+1)) {
10390 gl_update_buffer(gl); /* Compute gl->ntotal etc.. */
10391 gl->buff_curpos = gl->ntotal;
10393 gl_truncate_buffer(gl, 0);
10395 gl->preload_id = 0;
10410 if(start_len > gl->linelen)
10411 start_len = gl->linelen;
10415 if(start_line != gl->line)
10416 gl_buffer_string(gl, start_line, start_len, 0);
10420 for(cptr=gl->line + gl->ntotal - 1; cptr >= gl->line &&
10421 (*cptr=='\n' || *cptr=='\r'); cptr--,gl->ntotal--)
10423 gl_truncate_buffer(gl, gl->ntotal < 0 ? 0 : gl->ntotal);
10427 if(start_pos < 0 || start_pos > gl->ntotal) {
10428 if(gl_place_cursor(gl, gl->ntotal))
10431 if(gl_place_cursor(gl, start_pos))
10438 gl_truncate_buffer(gl, 0);
10443 gl_queue_redisplay(gl);
10447 return gl_flush_output(gl);
10456 static void gl_reset_input_line(GetLine *gl)
10458 gl->ntotal = 0;
10459 gl->line[0] = '\0';
10460 gl->buff_curpos = 0;
10461 gl->term_curpos = 0;
10462 gl->term_len = 0;
10463 gl->insert_curpos = 0;
10464 gl->number = -1;
10465 gl->displayed = 0;
10466 gl->endline = 0;
10467 gl->redisplay = 0;
10468 gl->postpone = 0;
10469 gl->nbuf = 0;
10470 gl->nread = 0;
10471 gl->vi.command = 0;
10472 gl->vi.undo.line[0] = '\0';
10473 gl->vi.undo.ntotal = 0;
10474 gl->vi.undo.buff_curpos = 0;
10475 gl->vi.repeat.action.fn = 0;
10476 gl->vi.repeat.action.data = 0;
10477 gl->last_signal = -1;
10492 static int gl_print_info(GetLine *gl, ...)
10500 if(gl->echo) {
10504 if(gl_start_newline(gl, 1))
10509 va_start(ap, gl);
10511 waserr = gl_print_raw_string(gl, 1, s, -1);
10516 waserr = waserr || gl_print_raw_string(gl, 1, "\n\r", -1);
10520 gl_queue_redisplay(gl);
10541 static int gl_start_newline(GetLine *gl, int buffered)
10552 if(gl->displayed) { /* Is an input line currently displayed? */
10557 int curs_line = gl->term_curpos / gl->ncolumn;
10558 int last_line = gl->term_len / gl->ncolumn;
10564 waserr = waserr || gl_print_raw_string(gl, buffered, "\n", 1);
10565 waserr = waserr || gl_print_raw_string(gl, buffered, "\r", 1);
10569 gl_line_erased(gl);
10590 GetLine *gl = (GetLine *) data; local
10591 int ndone = _glq_append_chars(gl->cq, s, n, gl->flush_fn, gl);
10593 _err_record_msg(gl->err, _glq_last_error(gl->cq), END_ERR_MSG);
10606 GlReturnStatus gl_return_status(GetLine *gl)
10609 if(gl) {
10614 gl_mask_signals(gl, &oldset);
10618 rtn_status = gl->rtn_status;
10622 gl_unmask_signals(gl, &oldset);
10638 GlPendingIO gl_pending_io(GetLine *gl)
10641 if(gl) {
10646 gl_mask_signals(gl, &oldset);
10650 pending_io = gl->pending_io;
10654 gl_unmask_signals(gl, &oldset);
10679 int gl_raw_io(GetLine *gl)
10686 if(!gl) {
10693 if(gl_mask_signals(gl, &oldset))
10698 if(gl->io_mode != GL_SERVER_MODE) {
10699 _err_record_msg(gl->err, "Can't switch to raw I/O unless in server mode",
10707 status = _gl_raw_io(gl, 1);
10712 gl_unmask_signals(gl, &oldset);
10723 static int _gl_raw_io(GetLine *gl, int redisplay)
10728 if(gl->raw_mode)
10733 if(gl->is_term && gl_raw_terminal_mode(gl))
10738 if(gl->io_mode==GL_SERVER_MODE &&
10739 (gl_nonblocking_io(gl, gl->input_fd) ||
10740 gl_nonblocking_io(gl, gl->output_fd) ||
10741 (gl->file_fp && gl_nonblocking_io(gl, fileno(gl->file_fp))))) {
10742 if(gl->is_term)
10743 gl_restore_terminal_attributes(gl);
10751 gl->postpone = 0;
10752 gl_queue_redisplay(gl);
10771 int gl_normal_io(GetLine *gl)
10778 if(!gl) {
10785 if(gl_mask_signals(gl, &oldset))
10790 status = _gl_normal_io(gl);
10794 gl_unmask_signals(gl, &oldset);
10803 static int _gl_normal_io(GetLine *gl)
10808 if(!gl->raw_mode)
10814 gl->postpone = 1;
10822 if(gl->io_mode==GL_SERVER_MODE &&
10823 (gl_blocking_io(gl, gl->input_fd) ||
10824 gl_blocking_io(gl, gl->output_fd) ||
10825 (gl->file_fp && gl_blocking_io(gl, fileno(gl->file_fp)))))
10832 if(gl->is_term && gl_start_newline(gl, 0))
10837 if(gl->is_term && gl_restore_terminal_attributes(gl)) {
10842 if(gl->io_mode==GL_SERVER_MODE) {
10843 gl_nonblocking_io(gl, gl->input_fd);
10844 gl_nonblocking_io(gl, gl->output_fd);
10845 if(gl->file_fp)
10846 gl_nonblocking_io(gl, fileno(gl->file_fp));
10883 int gl_completion_action(GetLine *gl, void *data, CplMatchFn *match_fn,
10891 if(!gl || !name || !match_fn) {
10898 if(gl_mask_signals(gl, &oldset))
10903 status = _gl_completion_action(gl, data, match_fn, list_only, name, keyseq);
10907 gl_unmask_signals(gl, &oldset);
10916 static int _gl_completion_action(GetLine *gl, void *data, CplMatchFn *match_fn,
10929 if(_kt_lookup_action(gl->bindings, name, ¤t_fn, ¤t_data) == 0) {
10940 _err_record_msg(gl->err,
10952 GlCplCallback *cb = (GlCplCallback *) _new_FreeListNode(gl->cpl_mem);
10955 _err_record_msg(gl->err, "Insufficient memory to add completion action",
10967 if(_kt_set_action(gl->bindings, name, action_fn, cb)) {
10968 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
10969 _del_FreeListNode(gl->cpl_mem, (void *) cb);
10976 if(keyseq && _kt_set_keybinding(gl->bindings, KTB_NORM, keyseq, name)) {
10977 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
11009 int gl_register_action(GetLine *gl, void *data, GlActionFn *fn,
11017 if(!gl || !name || !fn) {
11024 if(gl_mask_signals(gl, &oldset))
11029 status = _gl_register_action(gl, data, fn, name, keyseq);
11033 gl_unmask_signals(gl, &oldset);
11042 static int _gl_register_action(GetLine *gl, void *data, GlActionFn *fn,
11055 if(_kt_lookup_action(gl->bindings, name, ¤t_fn, ¤t_data) == 0) {
11066 _err_record_msg(gl->err,
11079 (GlExternalAction *) _new_FreeListNode(gl->ext_act_mem);
11082 _err_record_msg(gl->err, "Insufficient memory to add completion action",
11094 if(_kt_set_action(gl->bindings, name, action_fn, a)) {
11095 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
11096 _del_FreeListNode(gl->cpl_mem, (void *) a);
11103 if(keyseq && _kt_set_keybinding(gl->bindings, KTB_NORM, keyseq, name)) {
11104 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
11124 status = a->fn(gl, a->data, count, gl->buff_curpos, gl->line);
11129 if(_gl_raw_io(gl, 1))
11137 gl_record_status(gl, GLR_ERROR, errno);
11141 return gl_newline(gl, 1, NULL);
11303 int gl_display_text(GetLine *gl, int indentation, const char *prefix,
11312 if(!gl || !string) {
11319 if(gl_mask_signals(gl, &oldset))
11324 status = _io_display_text(_io_write_stdio, gl->output_fp, indentation,
11326 gl->ncolumn > 0 ? gl->ncolumn : def_width,
11331 gl_unmask_signals(gl, &oldset);
11348 static int gl_mask_signals(GetLine *gl, sigset_t *oldset)
11354 if(sigprocmask(SIG_BLOCK, &gl->all_signal_set, oldset) >= 0) {
11355 gl->signals_masked = 1;
11365 gl->signals_masked = 0;
11381 static int gl_unmask_signals(GetLine *gl, sigset_t *oldset)
11383 gl->signals_masked = 0;
11396 static int gl_catch_signals(GetLine *gl)
11398 return sigprocmask(SIG_UNBLOCK, &gl->use_signal_set, NULL) < 0;
11411 int gl_io_mode(GetLine *gl, GlIOMode mode)
11418 if(!gl) {
11431 _err_record_msg(gl->err, "Unknown gl_get_line() I/O mode requested.",
11438 if(gl_mask_signals(gl, &oldset))
11443 status = _gl_io_mode(gl, mode);
11447 gl_unmask_signals(gl, &oldset);
11456 static int _gl_io_mode(GetLine *gl, GlIOMode mode)
11461 if(mode == gl->io_mode)
11466 _gl_normal_io(gl);
11470 gl->io_mode = mode;
11475 if(_gl_raw_io(gl, 1))
11505 const char *gl_error_message(GetLine *gl, char *buff, size_t n)
11507 if(!gl) {
11520 gl_mask_signals(gl, &oldset);
11525 strncpy(buff, _err_get_msg(gl->err), n);
11531 gl_unmask_signals(gl, &oldset);
11533 return _err_get_msg(gl->err);
11555 int gl_list_signals(GetLine *gl, sigset_t *set)
11560 if(!gl || !set) {
11561 if(gl)
11562 _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG);
11569 memcpy(set, &gl->all_signal_set, sizeof(*set));
11590 void gl_catch_blocked(GetLine *gl)
11597 if(!gl) {
11604 gl_mask_signals(gl, &oldset);
11608 for(sig=gl->sigs; sig; sig=sig->next)
11614 gl_unmask_signals(gl, &oldset);
11648 void gl_handle_signal(int signo, GetLine *gl, int ngl)
11657 if(ngl < 1 || !gl)
11677 gl_suspend_process(signo, gl, ngl);
11689 gl[i].pending_io = GLP_WRITE;
11721 static void gl_suspend_process(int signo, GetLine *gl, int ngl)
11743 GetLine *obj = gl + i;
11780 GetLine *obj = gl + i;
11832 void gl_abandon_line(GetLine *gl)
11838 if(!gl) {
11845 gl_mask_signals(gl, &oldset);
11849 _gl_abandon_line(gl);
11854 gl_unmask_signals(gl, &oldset);
11863 void _gl_abandon_line(GetLine *gl)
11865 gl->endline = 1;
11866 gl->pending_io = GLP_WRITE;
11898 int gl_set_term_size(GetLine *gl, int ncolumn, int nline)
11906 gl_mask_signals(gl, &oldset);
11910 status = _gl_set_term_size(gl, ncolumn, nline);
11914 gl_unmask_signals(gl, &oldset);
11923 static int _gl_set_term_size(GetLine *gl, int ncolumn, int nline)
11928 if(!gl) {
11936 _err_record_msg(gl->err, "Invalid terminal size", END_ERR_MSG);
11945 if(gl->is_term) {
11951 if(ioctl(gl->output_fd, TIOCSWINSZ, &size) == -1) {
11952 _err_record_msg(gl->err, "Can't change terminal size", END_ERR_MSG);
11962 return gl_handle_tty_resize(gl, ncolumn, nline);
11977 static int gl_buffer_char(GetLine *gl, char c, int bufpos)
11982 if(bufpos >= gl->linelen)
11987 gl->line[bufpos] = c;
11993 if(bufpos >= gl->ntotal) {
11994 gl->ntotal = bufpos+1;
11995 gl->line[gl->ntotal] = '\0';
12015 static int gl_buffer_string(GetLine *gl, const char *s, int n, int bufpos)
12022 nnew = bufpos + n <= gl->linelen ? n : (gl->linelen - bufpos);
12027 gl_buffer_char(gl, s[i], bufpos + i);
12047 static int gl_make_gap_in_buffer(GetLine *gl, int start, int n)
12052 if(gl->ntotal + n > gl->linelen)
12058 memmove(gl->line + start + n, gl->line + start, gl->ntotal - start + 1);
12062 gl->ntotal += n;
12076 static void gl_remove_from_buffer(GetLine *gl, int start, int n)
12078 memmove(gl->line + start, gl->line + start + n, gl->ntotal - start - n + 1);
12082 gl->ntotal -= n;
12096 static int gl_truncate_buffer(GetLine *gl, int n)
12098 if(n > gl->linelen)
12100 gl->line[n] = '\0';
12101 gl->ntotal = n;
12113 static void gl_update_buffer(GetLine *gl)
12119 for(len=0; len <= gl->linelen && gl->line[len]; len++)
12124 gl->line[len] = '\0';
12128 gl->ntotal = len;
12133 if(gl->buff_curpos > gl->ntotal)
12134 gl->buff_curpos = gl->ntotal;
12138 gl_queue_redisplay(gl);
12155 static int gl_erase_line(GetLine *gl)
12160 if(gl->displayed) {
12165 int cursor_line = gl->term_curpos / gl->ncolumn;
12170 if(gl_print_control_sequence(gl, 1, gl->up))
12173 if(gl_print_control_sequence(gl, 1, gl->bol))
12178 if(gl_print_control_sequence(gl, gl->nline, gl->clear_eod))
12183 gl_line_erased(gl);
12195 static void gl_queue_redisplay(GetLine *gl)
12197 gl->redisplay = 1;
12198 gl->pending_io = GLP_WRITE;
12212 static int gl_truncate_display(GetLine *gl)
12217 int term_curpos = gl->term_curpos;
12221 if(gl_print_control_sequence(gl, 1, gl->clear_eol))
12233 if(gl->term_len / gl->ncolumn > gl->term_curpos / gl->ncolumn) {
12234 if(gl_print_control_sequence(gl, 1, gl->down) ||
12235 gl_print_control_sequence(gl, 1, gl->bol) ||
12236 gl_print_control_sequence(gl, gl->nline, gl->clear_eod))
12241 gl->term_curpos = gl->ncolumn * (term_curpos / gl->ncolumn + 1);
12245 gl_set_term_curpos(gl, term_curpos);
12250 gl->term_len = gl->term_curpos;
12287 static int gl_read_stream_line(GetLine *gl)
12293 gl->pending_io = GLP_READ;
12297 if(gl->endline)
12298 gl_reset_input_line(gl);
12302 while(gl->ntotal < gl->linelen && c != '\n') {
12306 switch(gl_read_input(gl, &c)) {
12316 if(gl->ntotal > 0) {
12319 gl_record_status(gl, GLR_EOF, 0);
12324 gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO);
12334 if(gl_buffer_char(gl, c, gl->ntotal))
12340 gl->endline = (c == '\n');
12352 static int gl_read_stream_char(GetLine *gl)
12359 _gl_abandon_line(gl);
12363 gl->pending_io = GLP_READ;
12367 switch(gl_read_input(gl, &c)) {
12372 gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO);
12376 gl_record_status(gl, GLR_EOF, 0);
12400 int gl_bind_keyseq(GetLine *gl, GlKeyOrigin origin, const char *keyseq,
12407 if(!gl || !keyseq) {
12409 if(gl)
12410 _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG);
12427 if(keyseq && _kt_set_keybinding(gl->bindings, binder, keyseq, action)) {
12428 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
12446 int gl_erase_terminal(GetLine *gl)
12454 gl_mask_signals(gl, &oldset);
12458 status = gl_clear_screen(gl, 1, NULL);
12464 (void) gl_flush_output(gl);
12468 gl_unmask_signals(gl, &oldset);
12479 static void gl_line_erased(GetLine *gl)
12481 gl->displayed = 0;
12482 gl->term_curpos = 0;
12483 gl->term_len = 0;
12496 int gl_append_history(GetLine *gl, const char *line)
12504 if(!gl || !line) {
12511 if(gl_mask_signals(gl, &oldset))
12516 status = _gl_append_history(gl, line);
12520 gl_unmask_signals(gl, &oldset);
12529 static int _gl_append_history(GetLine *gl, const char *line)
12531 int status =_glh_add_history(gl->glh, line, 0);
12533 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
12554 int gl_automatic_history(GetLine *gl, int enable)
12561 if(!gl) {
12568 if(gl_mask_signals(gl, &oldset))
12573 gl->automatic_history = enable;
12577 gl_unmask_signals(gl, &oldset);
12593 int gl_read_char(GetLine *gl)
12601 int was_masked = gl->signals_masked;
12605 if(!gl) {
12612 if(!was_masked && gl_mask_signals(gl, &gl->old_signal_set))
12617 retval = _gl_read_char(gl);
12623 gl_unmask_signals(gl, &gl->old_signal_set);
12630 static int _gl_read_char(GetLine *gl)
12642 int was_overriden = gl->signals_overriden;
12643 int was_raw = gl->raw_mode;
12648 GlPendingIO old_pending_io = gl->pending_io;
12653 gl_clear_status(gl);
12658 if(!gl->configured) {
12659 (void) _gl_configure_getline(gl, NULL, NULL, TECLA_CONFIG_FILE);
12660 gl->configured = 1;
12673 waserr = gl_override_signal_handlers(gl);
12680 waserr = waserr || _gl_raw_io(gl, 0);
12690 if(gl->file_fp || !gl->is_term) {
12691 retval = gl_read_stream_char(gl);
12694 } else if(gl->file_fp) { /* End of temporary input file? */
12695 gl_revert_input(gl);
12696 gl_record_status(gl, GLR_NEWLINE, 0);
12707 if(!gl->file_fp && gl->is_term) {
12712 if(_glq_char_count(gl->cq) > 0 && gl_flush_output(gl)) {
12718 } else if(gl_read_terminal(gl, 0, &c) == 0) {
12726 gl->keyseq_count++;
12730 gl_discard_chars(gl, 1);
12746 if(waserr && gl->rtn_status == GLR_NEWLINE)
12747 gl_record_status(gl, GLR_ERROR, errno);
12751 if(!was_raw && gl->io_mode != GL_SERVER_MODE)
12752 _gl_normal_io(gl);
12757 gl_restore_signal_handlers(gl);
12766 errno = gl->rtn_errno;
12771 if(gl->rtn_status != GLR_NEWLINE)
12777 gl->pending_io = old_pending_io;
12793 static void gl_clear_status(GetLine *gl)
12795 gl_record_status(gl, GLR_NEWLINE, 0);
12812 static void gl_record_status(GetLine *gl, GlReturnStatus rtn_status,
12820 if(rtn_status == GLR_NEWLINE || gl->rtn_status == GLR_NEWLINE) {
12821 gl->rtn_status = rtn_status;
12822 gl->rtn_errno = rtn_errno;