Lines Matching refs:gl

291 static int gl_call_fd_handler(GetLine *gl, GlFdHandler *gfh, int fd,
294 static int gl_call_timeout_handler(GetLine *gl);
648 static int gl_check_caught_signal(GetLine *gl);
654 static void gl_suspend_process(int signo, GetLine *gl, int ngl);
677 static void gl_query_size(GetLine *gl, int *ncolumn, int *nline);
683 static int gl_override_signal_handlers(GetLine *gl);
689 static int gl_restore_signal_handlers(GetLine *gl);
695 static int gl_mask_signals(GetLine *gl, sigset_t *oldset);
701 static int gl_unmask_signals(GetLine *gl, sigset_t *oldset);
706 static int gl_catch_signals(GetLine *gl);
717 static int gl_raw_terminal_mode(GetLine *gl);
722 static int gl_restore_terminal_attributes(GetLine *gl);
727 static int gl_nonblocking_io(GetLine *gl, int fd);
732 static int gl_blocking_io(GetLine *gl, int fd);
737 static int gl_get_input_line(GetLine *gl, const char *prompt,
743 static int gl_get_query_char(GetLine *gl, const char *prompt, int defchar);
748 static int gl_read_stream_line(GetLine *gl);
753 static int gl_read_stream_char(GetLine *gl);
758 static int gl_present_line(GetLine *gl, const char *prompt,
764 static void gl_reset_input_line(GetLine *gl);
770 static int gl_interpret_char(GetLine *gl, char c);
775 static int gl_bind_control_char(GetLine *gl, KtBinder binder,
781 static int gl_bind_terminal_keys(GetLine *gl);
786 static int gl_control_strings(GetLine *gl, const char *term);
793 static const char *gl_tigetstr(GetLine *gl, const char *name);
795 static const char *gl_tgetstr(GetLine *gl, const char *name, char **bufptr);
801 static int gl_print_raw_string(GetLine *gl, int buffered,
809 static int gl_print_info(GetLine *gl, ...);
815 static int gl_start_newline(GetLine *gl, int buffered);
820 static int gl_print_control_sequence(GetLine *gl, int nline,
828 static int gl_print_char(GetLine *gl, char c, char pad);
829 static int gl_print_string(GetLine *gl, const char *string, char pad);
835 static int gl_delete_chars(GetLine *gl, int nc, int cut);
841 static int gl_add_char_to_line(GetLine *gl, char c);
847 static int gl_add_string_to_line(GetLine *gl, const char *s);
852 static int gl_buffer_char(GetLine *gl, char c, int bufpos);
857 static int gl_buffer_string(GetLine *gl, const char *s, int n, int bufpos);
862 static int gl_make_gap_in_buffer(GetLine *gl, int start, int n);
868 static void gl_remove_from_buffer(GetLine *gl, int start, int n);
873 static int gl_truncate_buffer(GetLine *gl, int n);
879 static int gl_truncate_display(GetLine *gl);
885 static void gl_update_buffer(GetLine *gl);
890 static int gl_read_terminal(GetLine *gl, int keep, char *c);
895 static void gl_discard_chars(GetLine *gl, int nused);
900 static int gl_terminal_move_cursor(GetLine *gl, int n);
905 static int gl_set_term_curpos(GetLine *gl, int term_curpos);
911 static int gl_place_cursor(GetLine *gl, int buff_curpos);
922 static int gl_displayed_tab_width(GetLine *gl, int term_curpos);
928 static int gl_displayed_char_width(GetLine *gl, char c, int term_curpos);
934 static int gl_displayed_string_width(GetLine *gl, const char *string, int nc,
945 static int _gl_read_config_file(GetLine *gl, const char *filename, KtBinder who);
950 static int _gl_read_config_string(GetLine *gl, const char *buffer, KtBinder who);
965 static int _gl_parse_config_line(GetLine *gl, void *stream, GlcGetcFn *getc_fn,
967 static int gl_report_config_error(GetLine *gl, const char *origin, int lineno,
974 static int _gl_bind_arrow_keys(GetLine *gl);
980 static int _gl_rebind_arrow_key(GetLine *gl, const char *name,
991 static void gl_revert_input(GetLine *gl);
996 static int gl_flush_output(GetLine *gl);
1021 static GlReadStatus gl_read_input(GetLine *gl, char *c);
1025 static int gl_event_handler(GetLine *gl, int fd);
1026 static int gl_read_unmasked(GetLine *gl, int fd, char *c);
1037 static int gl_change_editor(GetLine *gl, GlEditor editor);
1044 static int gl_find_char(GetLine *gl, int count, int forward, int onto, char c);
1049 static int gl_nth_word_end_forward(GetLine *gl, int n);
1054 static int gl_nth_word_start_forward(GetLine *gl, int n);
1059 static int gl_nth_word_start_backward(GetLine *gl, int n);
1066 static void gl_save_for_undo(GetLine *gl);
1071 static void gl_vi_command_mode(GetLine *gl);
1078 static int gl_delete_find(GetLine *gl, int count, char c, int forward,
1085 static int gl_copy_find(GetLine *gl, int count, char c, int forward, int onto);
1092 static int gl_index_of_matching_paren(GetLine *gl);
1116 static int gl_display_prompt(GetLine *gl);
1121 static int gl_displayed_prompt_width(GetLine *gl);
1126 static int gl_line_ended(GetLine *gl, int newline_char);
1132 static void gl_queue_redisplay(GetLine *gl);
1138 static int gl_erase_line(GetLine *gl);
1143 static void gl_line_erased(GetLine *gl);
1148 void _gl_abandon_line(GetLine *gl);
1158 static char *_gl_get_line(GetLine *gl, const char *prompt,
1160 static int _gl_query_char(GetLine *gl, const char *prompt, char defchar);
1161 static int _gl_read_char(GetLine *gl);
1162 static int _gl_update_size(GetLine *gl);
1167 static int gl_handle_tty_resize(GetLine *gl, int ncolumn, int nline);
1169 static int _gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp,
1171 static int _gl_configure_getline(GetLine *gl, const char *app_string,
1173 static int _gl_save_history(GetLine *gl, const char *filename,
1175 static int _gl_load_history(GetLine *gl, const char *filename,
1177 static int _gl_watch_fd(GetLine *gl, int fd, GlFdEvent event,
1179 static void _gl_terminal_size(GetLine *gl, int def_ncolumn, int def_nline,
1181 static void _gl_replace_prompt(GetLine *gl, const char *prompt);
1182 static int _gl_trap_signal(GetLine *gl, int signo, unsigned flags,
1184 static int _gl_raw_io(GetLine *gl, int redisplay);
1185 static int _gl_normal_io(GetLine *gl);
1186 static int _gl_completion_action(GetLine *gl, void *data, CplMatchFn *match_fn,
1189 static int _gl_register_action(GetLine *gl, void *data, GlActionFn *fn,
1191 static int _gl_io_mode(GetLine *gl, GlIOMode mode);
1192 static int _gl_set_term_size(GetLine *gl, int ncolumn, int nline);
1193 static int _gl_append_history(GetLine *gl, const char *line);
1199 static void gl_clear_status(GetLine *gl);
1205 static void gl_record_status(GetLine *gl, GlReturnStatus rtn_status,
1725 GetLine *gl; /* The object to be returned */ in new_GetLine() local
1737 gl = (GetLine *) malloc(sizeof(GetLine)); in new_GetLine()
1738 if(!gl) { in new_GetLine()
1747 gl->err = NULL; in new_GetLine()
1748 gl->glh = NULL; in new_GetLine()
1749 gl->cpl = NULL; in new_GetLine()
1751 gl->cplfn.fn = cpl_file_completions; in new_GetLine()
1753 gl->cplfn.fn = gl_no_completions; in new_GetLine()
1755 gl->cplfn.data = NULL; in new_GetLine()
1757 gl->ef = NULL; in new_GetLine()
1759 gl->capmem = NULL; in new_GetLine()
1760 gl->cq = NULL; in new_GetLine()
1761 gl->input_fd = -1; in new_GetLine()
1762 gl->output_fd = -1; in new_GetLine()
1763 gl->input_fp = NULL; in new_GetLine()
1764 gl->output_fp = NULL; in new_GetLine()
1765 gl->file_fp = NULL; in new_GetLine()
1766 gl->term = NULL; in new_GetLine()
1767 gl->is_term = 0; in new_GetLine()
1768 gl->flush_fn = gl_flush_terminal; in new_GetLine()
1769 gl->io_mode = GL_NORMAL_MODE; in new_GetLine()
1770 gl->raw_mode = 0; in new_GetLine()
1771 gl->pending_io = GLP_WRITE; /* We will start by writing the prompt */ in new_GetLine()
1772 gl_clear_status(gl); in new_GetLine()
1773 gl->linelen = linelen; in new_GetLine()
1774 gl->line = NULL; in new_GetLine()
1775 gl->cutbuf = NULL; in new_GetLine()
1776 gl->prompt = NULL; in new_GetLine()
1777 gl->prompt_len = 0; in new_GetLine()
1778 gl->prompt_changed = 0; in new_GetLine()
1779 gl->prompt_style = GL_LITERAL_PROMPT; in new_GetLine()
1780 gl->cpl_mem = NULL; in new_GetLine()
1781 gl->ext_act_mem = NULL; in new_GetLine()
1782 gl->sig_mem = NULL; in new_GetLine()
1783 gl->sigs = NULL; in new_GetLine()
1784 gl->signals_masked = 0; in new_GetLine()
1785 gl->signals_overriden = 0; in new_GetLine()
1786 sigemptyset(&gl->all_signal_set); in new_GetLine()
1787 sigemptyset(&gl->old_signal_set); in new_GetLine()
1788 sigemptyset(&gl->use_signal_set); in new_GetLine()
1789 gl->bindings = NULL; in new_GetLine()
1790 gl->ntotal = 0; in new_GetLine()
1791 gl->buff_curpos = 0; in new_GetLine()
1792 gl->term_curpos = 0; in new_GetLine()
1793 gl->term_len = 0; in new_GetLine()
1794 gl->buff_mark = 0; in new_GetLine()
1795 gl->insert_curpos = 0; in new_GetLine()
1796 gl->insert = 1; in new_GetLine()
1797 gl->number = -1; in new_GetLine()
1798 gl->endline = 1; in new_GetLine()
1799 gl->displayed = 0; in new_GetLine()
1800 gl->redisplay = 0; in new_GetLine()
1801 gl->postpone = 0; in new_GetLine()
1802 gl->keybuf[0]='\0'; in new_GetLine()
1803 gl->nbuf = 0; in new_GetLine()
1804 gl->nread = 0; in new_GetLine()
1805 gl->current_action.fn = 0; in new_GetLine()
1806 gl->current_action.data = NULL; in new_GetLine()
1807 gl->current_count = 0; in new_GetLine()
1808 gl->preload_id = 0; in new_GetLine()
1809 gl->preload_history = 0; in new_GetLine()
1810 gl->keyseq_count = 0; in new_GetLine()
1811 gl->last_search = -1; in new_GetLine()
1812 gl->editor = GL_EMACS_MODE; in new_GetLine()
1813 gl->silence_bell = 0; in new_GetLine()
1814 gl->automatic_history = 1; in new_GetLine()
1815 gl->vi.undo.line = NULL; in new_GetLine()
1816 gl->vi.undo.buff_curpos = 0; in new_GetLine()
1817 gl->vi.undo.ntotal = 0; in new_GetLine()
1818 gl->vi.undo.saved = 0; in new_GetLine()
1819 gl->vi.repeat.action.fn = 0; in new_GetLine()
1820 gl->vi.repeat.action.data = 0; in new_GetLine()
1821 gl->vi.repeat.count = 0; in new_GetLine()
1822 gl->vi.repeat.input_curpos = 0; in new_GetLine()
1823 gl->vi.repeat.command_curpos = 0; in new_GetLine()
1824 gl->vi.repeat.input_char = '\0'; in new_GetLine()
1825 gl->vi.repeat.saved = 0; in new_GetLine()
1826 gl->vi.repeat.active = 0; in new_GetLine()
1827 gl->vi.command = 0; in new_GetLine()
1828 gl->vi.find_forward = 0; in new_GetLine()
1829 gl->vi.find_onto = 0; in new_GetLine()
1830 gl->vi.find_char = '\0'; in new_GetLine()
1831 gl->left = NULL; in new_GetLine()
1832 gl->right = NULL; in new_GetLine()
1833 gl->up = NULL; in new_GetLine()
1834 gl->down = NULL; in new_GetLine()
1835 gl->home = NULL; in new_GetLine()
1836 gl->bol = 0; in new_GetLine()
1837 gl->clear_eol = NULL; in new_GetLine()
1838 gl->clear_eod = NULL; in new_GetLine()
1839 gl->u_arrow = NULL; in new_GetLine()
1840 gl->d_arrow = NULL; in new_GetLine()
1841 gl->l_arrow = NULL; in new_GetLine()
1842 gl->r_arrow = NULL; in new_GetLine()
1843 gl->sound_bell = NULL; in new_GetLine()
1844 gl->bold = NULL; in new_GetLine()
1845 gl->underline = NULL; in new_GetLine()
1846 gl->standout = NULL; in new_GetLine()
1847 gl->dim = NULL; in new_GetLine()
1848 gl->reverse = NULL; in new_GetLine()
1849 gl->blink = NULL; in new_GetLine()
1850 gl->text_attr_off = NULL; in new_GetLine()
1851 gl->nline = 0; in new_GetLine()
1852 gl->ncolumn = 0; in new_GetLine()
1854 gl->left_n = NULL; in new_GetLine()
1855 gl->right_n = NULL; in new_GetLine()
1857 gl->tgetent_buf = NULL; in new_GetLine()
1858 gl->tgetstr_buf = NULL; in new_GetLine()
1860 gl->app_file = NULL; in new_GetLine()
1861 gl->user_file = NULL; in new_GetLine()
1862 gl->configured = 0; in new_GetLine()
1863 gl->echo = 1; in new_GetLine()
1864 gl->last_signal = -1; in new_GetLine()
1866 gl->fd_node_mem = NULL; in new_GetLine()
1867 gl->fd_nodes = NULL; in new_GetLine()
1868 FD_ZERO(&gl->rfds); in new_GetLine()
1869 FD_ZERO(&gl->wfds); in new_GetLine()
1870 FD_ZERO(&gl->ufds); in new_GetLine()
1871 gl->max_fd = 0; in new_GetLine()
1872 gl->timer.dt.tv_sec = 0; in new_GetLine()
1873 gl->timer.dt.tv_usec = 0; in new_GetLine()
1874 gl->timer.fn = 0; in new_GetLine()
1875 gl->timer.data = NULL; in new_GetLine()
1880 gl->err = _new_ErrMsg(); in new_GetLine()
1881 if(!gl->err) in new_GetLine()
1882 return del_GetLine(gl); in new_GetLine()
1886 gl->glh = _new_GlHistory(histlen); in new_GetLine()
1887 if(!gl->glh) in new_GetLine()
1888 return del_GetLine(gl); in new_GetLine()
1892 gl->cpl = new_WordCompletion(); in new_GetLine()
1893 if(!gl->cpl) in new_GetLine()
1894 return del_GetLine(gl); in new_GetLine()
1899 gl->ef = new_ExpandFile(); in new_GetLine()
1900 if(!gl->ef) in new_GetLine()
1901 return del_GetLine(gl); in new_GetLine()
1907 gl->capmem = _new_StringGroup(CAPMEM_SEGMENT_SIZE); in new_GetLine()
1908 if(!gl->capmem) in new_GetLine()
1909 return del_GetLine(gl); in new_GetLine()
1913 gl->cq = _new_GlCharQueue(); in new_GetLine()
1914 if(!gl->cq) in new_GetLine()
1915 return del_GetLine(gl); in new_GetLine()
1920 gl->line = (char *) malloc(linelen + 2); in new_GetLine()
1921 if(!gl->line) { in new_GetLine()
1923 return del_GetLine(gl); in new_GetLine()
1928 gl_truncate_buffer(gl, 0); in new_GetLine()
1932 gl->cutbuf = (char *) malloc(linelen + 2); in new_GetLine()
1933 if(!gl->cutbuf) { in new_GetLine()
1935 return del_GetLine(gl); in new_GetLine()
1937 gl->cutbuf[0] = '\0'; in new_GetLine()
1941 _gl_replace_prompt(gl, NULL); in new_GetLine()
1942 if(!gl->prompt) { in new_GetLine()
1944 return del_GetLine(gl); in new_GetLine()
1949 gl->vi.undo.line = (char *) malloc(linelen + 2); in new_GetLine()
1950 if(!gl->vi.undo.line) { in new_GetLine()
1952 return del_GetLine(gl); in new_GetLine()
1954 gl->vi.undo.line[0] = '\0'; in new_GetLine()
1959 gl->cpl_mem = _new_FreeList(sizeof(GlCplCallback), GL_CPL_FREELIST_BLOCKING); in new_GetLine()
1960 if(!gl->cpl_mem) in new_GetLine()
1961 return del_GetLine(gl); in new_GetLine()
1966 gl->ext_act_mem = _new_FreeList(sizeof(GlExternalAction), in new_GetLine()
1968 if(!gl->ext_act_mem) in new_GetLine()
1969 return del_GetLine(gl); in new_GetLine()
1974 gl->sig_mem = _new_FreeList(sizeof(GlSignalNode), GLS_FREELIST_BLOCKING); in new_GetLine()
1975 if(!gl->sig_mem) in new_GetLine()
1976 return del_GetLine(gl); in new_GetLine()
1983 if(_gl_trap_signal(gl, sig->signo, sig->flags, sig->after, in new_GetLine()
1985 return del_GetLine(gl); in new_GetLine()
1990 gl->bindings = _new_KeyTab(); in new_GetLine()
1991 if(!gl->bindings) in new_GetLine()
1992 return del_GetLine(gl); in new_GetLine()
1997 if(_kt_set_action(gl->bindings, gl_actions[i].name, gl_actions[i].fn, NULL)) in new_GetLine()
1998 return del_GetLine(gl); in new_GetLine()
2003 if(gl_change_editor(gl, gl->editor)) in new_GetLine()
2004 return del_GetLine(gl); in new_GetLine()
2009 gl->tgetent_buf = (char *) malloc(TERMCAP_BUF_SIZE); in new_GetLine()
2010 gl->tgetstr_buf = (char *) malloc(TERMCAP_BUF_SIZE); in new_GetLine()
2011 if(!gl->tgetent_buf || !gl->tgetstr_buf) { in new_GetLine()
2013 return del_GetLine(gl); in new_GetLine()
2019 if(_gl_change_terminal(gl, stdin, stdout, getenv("TERM"))) in new_GetLine()
2020 return del_GetLine(gl); in new_GetLine()
2025 gl->fd_node_mem = _new_FreeList(sizeof(GlFdNode), GLFD_FREELIST_BLOCKING); in new_GetLine()
2026 if(!gl->fd_node_mem) in new_GetLine()
2027 return del_GetLine(gl); in new_GetLine()
2032 return gl; in new_GetLine()
2043 GetLine *del_GetLine(GetLine *gl) in del_GetLine() argument
2045 if(gl) { in del_GetLine()
2049 _gl_normal_io(gl); in del_GetLine()
2053 gl->err = _del_ErrMsg(gl->err); in del_GetLine()
2054 gl->glh = _del_GlHistory(gl->glh); in del_GetLine()
2055 gl->cpl = del_WordCompletion(gl->cpl); in del_GetLine()
2057 gl->ef = del_ExpandFile(gl->ef); in del_GetLine()
2059 gl->capmem = _del_StringGroup(gl->capmem); in del_GetLine()
2060 gl->cq = _del_GlCharQueue(gl->cq); in del_GetLine()
2061 if(gl->file_fp) in del_GetLine()
2062 fclose(gl->file_fp); in del_GetLine()
2063 if(gl->term) in del_GetLine()
2064 free(gl->term); in del_GetLine()
2065 if(gl->line) in del_GetLine()
2066 free(gl->line); in del_GetLine()
2067 if(gl->cutbuf) in del_GetLine()
2068 free(gl->cutbuf); in del_GetLine()
2069 if(gl->prompt) in del_GetLine()
2070 free(gl->prompt); in del_GetLine()
2071 gl->cpl_mem = _del_FreeList(gl->cpl_mem, 1); in del_GetLine()
2072 gl->ext_act_mem = _del_FreeList(gl->ext_act_mem, 1); in del_GetLine()
2073 gl->sig_mem = _del_FreeList(gl->sig_mem, 1); in del_GetLine()
2074 gl->sigs = NULL; /* Already freed by freeing sig_mem */ in del_GetLine()
2075 gl->bindings = _del_KeyTab(gl->bindings); in del_GetLine()
2076 if(gl->vi.undo.line) in del_GetLine()
2077 free(gl->vi.undo.line); in del_GetLine()
2079 if(gl->tgetent_buf) in del_GetLine()
2080 free(gl->tgetent_buf); in del_GetLine()
2081 if(gl->tgetstr_buf) in del_GetLine()
2082 free(gl->tgetstr_buf); in del_GetLine()
2084 if(gl->app_file) in del_GetLine()
2085 free(gl->app_file); in del_GetLine()
2086 if(gl->user_file) in del_GetLine()
2087 free(gl->user_file); in del_GetLine()
2089 gl->fd_node_mem = _del_FreeList(gl->fd_node_mem, 1); in del_GetLine()
2090 gl->fd_nodes = NULL; /* Already freed by freeing gl->fd_node_mem */ in del_GetLine()
2095 free(gl); in del_GetLine()
2113 static int gl_bind_control_char(GetLine *gl, KtBinder binder, char c, in gl_bind_control_char() argument
2136 if(_kt_set_keybinding(gl->bindings, binder, keyseq, action)) { in gl_bind_control_char()
2137 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG); in gl_bind_control_char()
2165 char *gl_get_line(GetLine *gl, const char *prompt, in gl_get_line() argument
2172 if(!gl) { in gl_get_line()
2179 if(gl_mask_signals(gl, &gl->old_signal_set)) in gl_get_line()
2184 retval = _gl_get_line(gl, prompt, start_line, start_pos); in gl_get_line()
2189 gl_unmask_signals(gl, &gl->old_signal_set); in gl_get_line()
2197 static char *_gl_get_line(GetLine *gl, const char *prompt, in _gl_get_line() argument
2205 gl_clear_status(gl); in _gl_get_line()
2210 if(!gl->configured) { in _gl_get_line()
2211 (void) _gl_configure_getline(gl, NULL, NULL, TECLA_CONFIG_FILE); in _gl_get_line()
2212 gl->configured = 1; in _gl_get_line()
2224 waserr = gl_override_signal_handlers(gl); in _gl_get_line()
2229 waserr = waserr || _gl_raw_io(gl, 1); in _gl_get_line()
2239 if(gl->file_fp || !gl->is_term) { in _gl_get_line()
2240 if(gl_read_stream_line(gl)==0) { in _gl_get_line()
2242 } else if(gl->file_fp) { in _gl_get_line()
2243 gl_revert_input(gl); in _gl_get_line()
2244 gl_record_status(gl, GLR_NEWLINE, 0); in _gl_get_line()
2255 if(!gl->file_fp && gl->is_term) { in _gl_get_line()
2256 if(gl_get_input_line(gl, prompt, start_line, start_pos)) in _gl_get_line()
2270 if(waserr && gl->rtn_status == GLR_NEWLINE) in _gl_get_line()
2271 gl_record_status(gl, GLR_ERROR, errno); in _gl_get_line()
2275 if(gl->io_mode != GL_SERVER_MODE) in _gl_get_line()
2276 _gl_normal_io(gl); in _gl_get_line()
2280 gl_restore_signal_handlers(gl); in _gl_get_line()
2289 errno = gl->rtn_errno; in _gl_get_line()
2293 switch(gl->rtn_status) { in _gl_get_line()
2295 return gl->line; in _gl_get_line()
2300 if(gl->io_mode != GL_SERVER_MODE) in _gl_get_line()
2301 _gl_abandon_line(gl); in _gl_get_line()
2306 _gl_abandon_line(gl); in _gl_get_line()
2326 int gl_query_char(GetLine *gl, const char *prompt, char defchar) in gl_query_char() argument
2332 if(!gl) { in gl_query_char()
2339 if(gl_mask_signals(gl, &gl->old_signal_set)) in gl_query_char()
2344 retval = _gl_query_char(gl, prompt, defchar); in gl_query_char()
2349 gl_unmask_signals(gl, &gl->old_signal_set); in gl_query_char()
2356 static int _gl_query_char(GetLine *gl, const char *prompt, char defchar) in _gl_query_char() argument
2364 gl_clear_status(gl); in _gl_query_char()
2369 if(!gl->configured) { in _gl_query_char()
2370 (void) _gl_configure_getline(gl, NULL, NULL, TECLA_CONFIG_FILE); in _gl_query_char()
2371 gl->configured = 1; in _gl_query_char()
2383 waserr = gl_override_signal_handlers(gl); in _gl_query_char()
2389 waserr = waserr || _gl_raw_io(gl, 0); in _gl_query_char()
2399 if(gl->file_fp || !gl->is_term) { in _gl_query_char()
2400 c = gl_read_stream_char(gl); in _gl_query_char()
2404 } else if(gl->file_fp) { /* End of temporary input file? */ in _gl_query_char()
2405 gl_revert_input(gl); in _gl_query_char()
2406 gl_record_status(gl, GLR_NEWLINE, 0); in _gl_query_char()
2417 if(!gl->file_fp && gl->is_term) { in _gl_query_char()
2418 c = gl_get_query_char(gl, prompt, defchar); in _gl_query_char()
2433 if(waserr && gl->rtn_status == GLR_NEWLINE) in _gl_query_char()
2434 gl_record_status(gl, GLR_ERROR, errno); in _gl_query_char()
2438 if(gl->io_mode != GL_SERVER_MODE) in _gl_query_char()
2439 _gl_normal_io(gl); in _gl_query_char()
2443 gl_restore_signal_handlers(gl); in _gl_query_char()
2452 errno = gl->rtn_errno; in _gl_query_char()
2457 if(gl->rtn_status != GLR_NEWLINE) in _gl_query_char()
2464 _gl_abandon_line(gl); in _gl_query_char()
2481 static int gl_override_signal_handlers(GetLine *gl) in gl_override_signal_handlers() argument
2489 memcpy(&act.sa_mask, &gl->all_signal_set, sizeof(sigset_t)); in gl_override_signal_handlers()
2495 sigemptyset(&gl->use_signal_set); in gl_override_signal_handlers()
2496 for(sig=gl->sigs; sig; sig=sig->next) { in gl_override_signal_handlers()
2502 !sigismember(&gl->old_signal_set, sig->signo)) { in gl_override_signal_handlers()
2503 if(sigaddset(&gl->use_signal_set, sig->signo) == -1) { in gl_override_signal_handlers()
2504 _err_record_msg(gl->err, "sigaddset error", END_ERR_MSG); in gl_override_signal_handlers()
2512 for(sig=gl->sigs; sig; sig=sig->next) { in gl_override_signal_handlers()
2513 if(sigismember(&gl->use_signal_set, sig->signo)) { in gl_override_signal_handlers()
2516 _err_record_msg(gl->err, "sigaction error", END_ERR_MSG); in gl_override_signal_handlers()
2526 gl->signals_overriden = 1; in gl_override_signal_handlers()
2532 if(_gl_update_size(gl)) in gl_override_signal_handlers()
2546 static int gl_restore_signal_handlers(GetLine *gl) in gl_restore_signal_handlers() argument
2553 for(sig=gl->sigs; sig; sig=sig->next) { in gl_restore_signal_handlers()
2554 if(sigismember(&gl->use_signal_set, sig->signo) && in gl_restore_signal_handlers()
2556 _err_record_msg(gl->err, "sigaction error", END_ERR_MSG); in gl_restore_signal_handlers()
2564 gl->signals_overriden = 0; in gl_restore_signal_handlers()
2588 static int gl_raw_terminal_mode(GetLine *gl) in gl_raw_terminal_mode() argument
2594 if(gl->raw_mode) in gl_raw_terminal_mode()
2599 if(tcgetattr(gl->input_fd, &gl->oldattr)) { in gl_raw_terminal_mode()
2600 _err_record_msg(gl->err, "tcgetattr error", END_ERR_MSG); in gl_raw_terminal_mode()
2607 if(gl->editor == GL_NO_EDITOR) in gl_raw_terminal_mode()
2612 newattr = gl->oldattr; in gl_raw_terminal_mode()
2634 newattr.c_cc[VMIN] = gl->io_mode==GL_SERVER_MODE ? 0:1; in gl_raw_terminal_mode()
2639 while(tcsetattr(gl->input_fd, TCSADRAIN, &newattr)) { in gl_raw_terminal_mode()
2641 _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG); in gl_raw_terminal_mode()
2648 gl->raw_mode = 1; in gl_raw_terminal_mode()
2661 static int gl_restore_terminal_attributes(GetLine *gl) in gl_restore_terminal_attributes() argument
2667 if(!gl->raw_mode) in gl_restore_terminal_attributes()
2673 if(gl_flush_output(gl)) in gl_restore_terminal_attributes()
2679 while(tcsetattr(gl->input_fd, TCSADRAIN, &gl->oldattr)) { in gl_restore_terminal_attributes()
2681 _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG); in gl_restore_terminal_attributes()
2689 gl->raw_mode = 0; in gl_restore_terminal_attributes()
2700 static int gl_nonblocking_io(GetLine *gl, int fd) in gl_nonblocking_io() argument
2722 _err_record_msg(gl->err, "fcntl error", END_ERR_MSG); in gl_nonblocking_io()
2736 static int gl_blocking_io(GetLine *gl, int fd) in gl_blocking_io() argument
2752 _err_record_msg(gl->err, "fcntl error", END_ERR_MSG); in gl_blocking_io()
2778 static int gl_get_input_line(GetLine *gl, const char *prompt, in gl_get_input_line() argument
2785 if(_glq_char_count(gl->cq) > 0 && gl_flush_output(gl)) in gl_get_input_line()
2790 if(gl->endline) { in gl_get_input_line()
2794 if(gl_erase_line(gl)) in gl_get_input_line()
2799 if(gl_present_line(gl, prompt, start_line, start_pos)) in gl_get_input_line()
2805 while(gl_read_terminal(gl, 1, &c) == 0) { in gl_get_input_line()
2809 gl->keyseq_count++; in gl_get_input_line()
2815 if(gl_interpret_char(gl, c)) in gl_get_input_line()
2821 if(gl->file_fp) in gl_get_input_line()
2826 if(gl->endline) in gl_get_input_line()
2827 return gl_line_ended(gl, c); in gl_get_input_line()
2834 if(gl->endline) in gl_get_input_line()
2835 return gl_line_ended(gl, '\n'); in gl_get_input_line()
2842 if(gl->rtn_status == GLR_BLOCKED && gl->pending_io == GLP_READ) in gl_get_input_line()
2843 gl->nread = 0; in gl_get_input_line()
2862 static int gl_get_query_char(GetLine *gl, const char *prompt, int defchar) in gl_get_query_char() argument
2869 if(_glq_char_count(gl->cq) > 0 && gl_flush_output(gl)) in gl_get_query_char()
2874 if(gl_erase_line(gl)) in gl_get_query_char()
2879 if(gl_present_line(gl, prompt, NULL, 0)) in gl_get_query_char()
2884 if(gl_read_terminal(gl, 1, &c) == 0) { in gl_get_query_char()
2888 gl->keyseq_count++; in gl_get_query_char()
2892 gl_discard_chars(gl, gl->nread); in gl_get_query_char()
2907 if(gl_end_of_line(gl, 1, NULL)==0) in gl_get_query_char()
2908 gl_print_char(gl, c, ' '); in gl_get_query_char()
2914 gl_record_status(gl, GLR_NEWLINE, 0); in gl_get_query_char()
2919 } else if(gl->endline) { in gl_get_query_char()
2921 gl_record_status(gl, GLR_NEWLINE, 0); in gl_get_query_char()
2928 if(gl_start_newline(gl, 1)) in gl_get_query_char()
2933 (void) gl_flush_output(gl); in gl_get_query_char()
2951 static int gl_add_char_to_line(GetLine *gl, char c) in gl_add_char_to_line() argument
2956 int buff_curpos = gl->buff_curpos; in gl_add_char_to_line()
2957 int term_curpos = gl->term_curpos; in gl_add_char_to_line()
2961 int width = gl_displayed_char_width(gl, c, term_curpos); in gl_add_char_to_line()
2968 if((gl->insert || buff_curpos >= gl->ntotal) && gl->ntotal >= gl->linelen) in gl_add_char_to_line()
2973 if(gl->insert || buff_curpos >= gl->ntotal) { in gl_add_char_to_line()
2977 if(buff_curpos < gl->ntotal) in gl_add_char_to_line()
2978 gl_make_gap_in_buffer(gl, buff_curpos, 1); in gl_add_char_to_line()
2982 gl_buffer_char(gl, c, buff_curpos); in gl_add_char_to_line()
2983 gl->buff_curpos++; in gl_add_char_to_line()
2988 if(gl_print_string(gl, gl->line + buff_curpos, '\0') || in gl_add_char_to_line()
2989 gl_set_term_curpos(gl, term_curpos + width)) in gl_add_char_to_line()
2998 int old_width = gl_displayed_char_width(gl, gl->line[buff_curpos], in gl_add_char_to_line()
3003 gl_buffer_char(gl, c, buff_curpos); in gl_add_char_to_line()
3011 if(gl_print_string(gl, gl->line + buff_curpos, '\0')) in gl_add_char_to_line()
3016 if(gl_truncate_display(gl)) in gl_add_char_to_line()
3021 if(gl_set_term_curpos(gl, term_curpos + width)) in gl_add_char_to_line()
3023 gl->buff_curpos++; in gl_add_char_to_line()
3033 if(gl_print_string(gl, gl->line + buff_curpos, '\0') || in gl_add_char_to_line()
3034 gl_set_term_curpos(gl, term_curpos + width)) in gl_add_char_to_line()
3036 gl->buff_curpos++; in gl_add_char_to_line()
3045 gl_buffer_char(gl, c, buff_curpos); in gl_add_char_to_line()
3046 gl->buff_curpos++; in gl_add_char_to_line()
3050 if(gl_print_char(gl, c, gl->line[gl->buff_curpos])) in gl_add_char_to_line()
3068 static int gl_add_string_to_line(GetLine *gl, const char *s) in gl_add_string_to_line() argument
3077 buff_curpos = gl->buff_curpos; in gl_add_string_to_line()
3078 term_curpos = gl->term_curpos; in gl_add_string_to_line()
3083 term_slen = gl_displayed_string_width(gl, s, buff_slen, term_curpos); in gl_add_string_to_line()
3089 if(gl->ntotal + buff_slen > gl->linelen) in gl_add_string_to_line()
3095 if(gl->ntotal > gl->buff_curpos) in gl_add_string_to_line()
3096 gl_make_gap_in_buffer(gl, gl->buff_curpos, buff_slen); in gl_add_string_to_line()
3100 gl_buffer_string(gl, s, buff_slen, gl->buff_curpos); in gl_add_string_to_line()
3101 gl->buff_curpos += buff_slen; in gl_add_string_to_line()
3106 if(gl_print_string(gl, gl->line + buff_curpos, '\0') || in gl_add_string_to_line()
3107 gl_set_term_curpos(gl, term_curpos + term_slen)) in gl_add_string_to_line()
3132 static int gl_read_terminal(GetLine *gl, int keep, char *c) in gl_read_terminal() argument
3138 if(gl_flush_output(gl)) in gl_read_terminal()
3143 gl->pending_io = GLP_READ; in gl_read_terminal()
3148 if(gl->nread < gl->nbuf) { in gl_read_terminal()
3149 *c = gl->keybuf[gl->nread]; in gl_read_terminal()
3154 gl->nread++; in gl_read_terminal()
3159 memmove(gl->keybuf + gl->nread, gl->keybuf + gl->nread + 1, in gl_read_terminal()
3160 gl->nbuf - gl->nread - 1); in gl_read_terminal()
3170 if(gl->nbuf + 1 > GL_KEY_MAX) { in gl_read_terminal()
3171 gl_print_info(gl, "gl_read_terminal: Buffer overflow avoided.", in gl_read_terminal()
3179 switch(gl_read_input(gl, c)) { in gl_read_terminal()
3183 gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO); in gl_read_terminal()
3194 gl->keybuf[gl->nbuf] = *c; in gl_read_terminal()
3195 gl->nread = ++gl->nbuf; in gl_read_terminal()
3209 static GlReadStatus gl_read_input(GetLine *gl, char *c) in gl_read_input() argument
3219 volatile int fd = gl->file_fp ? fileno(gl->file_fp) : gl->input_fd; in gl_read_input()
3223 if(gl->endline) in gl_read_input()
3232 switch(gl->io_mode) { in gl_read_input()
3238 if(gl_event_handler(gl, fd)) in gl_read_input()
3240 return gl_read_unmasked(gl, fd, c); /* Read one character */ in gl_read_input()
3257 gl_blocking_io(gl, fd); /* switch to blocking I/O */ in gl_read_input()
3258 status = gl_read_unmasked(gl, fd, c); /* Try reading */ in gl_read_input()
3260 if(gl_event_handler(gl, fd)) /* Wait for input */ in gl_read_input()
3263 status = gl_read_unmasked(gl, fd, c); /* Try reading again */ in gl_read_input()
3265 gl_nonblocking_io(gl, fd); /* Restore non-blocking I/O */ in gl_read_input()
3280 if(gl->io_mode == GL_SERVER_MODE) in gl_read_input()
3281 gl_nonblocking_io(gl, fd); in gl_read_input()
3285 if(gl_check_caught_signal(gl)) in gl_read_input()
3302 static int gl_read_unmasked(GetLine *gl, int fd, char *c) in gl_read_unmasked() argument
3308 gl_catch_signals(gl); in gl_read_unmasked()
3320 gl_mask_signals(gl, NULL); in gl_read_unmasked()
3344 static void gl_discard_chars(GetLine *gl, int nused) in gl_discard_chars() argument
3346 int nkeep = gl->nbuf - nused; in gl_discard_chars()
3348 memmove(gl->keybuf, gl->keybuf + nused, nkeep); in gl_discard_chars()
3349 gl->nbuf = nkeep; in gl_discard_chars()
3350 gl->nread = 0; in gl_discard_chars()
3352 gl->nbuf = gl->nread = 0; in gl_discard_chars()
3366 static int gl_check_caught_signal(GetLine *gl) in gl_check_caught_signal() argument
3389 gl->last_signal = signo; in gl_check_caught_signal()
3402 if(gl->io_mode==GL_SERVER_MODE) { in gl_check_caught_signal()
3403 gl_record_status(gl, GLR_SIGNAL, EINTR); in gl_check_caught_signal()
3410 for(sig=gl->sigs; sig && sig->signo != signo; sig=sig->next) in gl_check_caught_signal()
3422 if(signo == SIGWINCH && _gl_update_size(gl)) in gl_check_caught_signal()
3429 if(gl_start_newline(gl, 0)) in gl_check_caught_signal()
3437 gl_restore_terminal_attributes(gl); in gl_check_caught_signal()
3444 gl_restore_signal_handlers(gl); in gl_check_caught_signal()
3445 gl_unmask_signals(gl, &gl->old_signal_set); in gl_check_caught_signal()
3459 gl_mask_signals(gl, NULL); in gl_check_caught_signal()
3460 gl_override_signal_handlers(gl); in gl_check_caught_signal()
3469 gl_raw_terminal_mode(gl); in gl_check_caught_signal()
3474 gl_queue_redisplay(gl); in gl_check_caught_signal()
3480 gl_newline(gl, 1, NULL); in gl_check_caught_signal()
3481 return gl_flush_output(gl); in gl_check_caught_signal()
3484 gl_record_status(gl, GLR_SIGNAL, sig->errno_value); in gl_check_caught_signal()
3488 return gl_flush_output(gl); in gl_check_caught_signal()
3504 static int gl_control_strings(GetLine *gl, const char *term) in gl_control_strings() argument
3510 gl->left = NULL; in gl_control_strings()
3511 gl->right = NULL; in gl_control_strings()
3512 gl->up = NULL; in gl_control_strings()
3513 gl->down = NULL; in gl_control_strings()
3514 gl->home = NULL; in gl_control_strings()
3515 gl->bol = 0; in gl_control_strings()
3516 gl->clear_eol = NULL; in gl_control_strings()
3517 gl->clear_eod = NULL; in gl_control_strings()
3518 gl->u_arrow = NULL; in gl_control_strings()
3519 gl->d_arrow = NULL; in gl_control_strings()
3520 gl->l_arrow = NULL; in gl_control_strings()
3521 gl->r_arrow = NULL; in gl_control_strings()
3522 gl->sound_bell = NULL; in gl_control_strings()
3523 gl->bold = NULL; in gl_control_strings()
3524 gl->underline = NULL; in gl_control_strings()
3525 gl->standout = NULL; in gl_control_strings()
3526 gl->dim = NULL; in gl_control_strings()
3527 gl->reverse = NULL; in gl_control_strings()
3528 gl->blink = NULL; in gl_control_strings()
3529 gl->text_attr_off = NULL; in gl_control_strings()
3530 gl->nline = 0; in gl_control_strings()
3531 gl->ncolumn = 0; in gl_control_strings()
3533 gl->left_n = NULL; in gl_control_strings()
3534 gl->right_n = NULL; in gl_control_strings()
3543 if(!term || setupterm((char *)term, gl->input_fd, &errret) == ERR) { in gl_control_strings()
3546 _clr_StringGroup(gl->capmem); in gl_control_strings()
3547 gl->left = gl_tigetstr(gl, "cub1"); in gl_control_strings()
3548 gl->right = gl_tigetstr(gl, "cuf1"); in gl_control_strings()
3549 gl->up = gl_tigetstr(gl, "cuu1"); in gl_control_strings()
3550 gl->down = gl_tigetstr(gl, "cud1"); in gl_control_strings()
3551 gl->home = gl_tigetstr(gl, "home"); in gl_control_strings()
3552 gl->clear_eol = gl_tigetstr(gl, "el"); in gl_control_strings()
3553 gl->clear_eod = gl_tigetstr(gl, "ed"); in gl_control_strings()
3554 gl->u_arrow = gl_tigetstr(gl, "kcuu1"); in gl_control_strings()
3555 gl->d_arrow = gl_tigetstr(gl, "kcud1"); in gl_control_strings()
3556 gl->l_arrow = gl_tigetstr(gl, "kcub1"); in gl_control_strings()
3557 gl->r_arrow = gl_tigetstr(gl, "kcuf1"); in gl_control_strings()
3558 gl->left_n = gl_tigetstr(gl, "cub"); in gl_control_strings()
3559 gl->right_n = gl_tigetstr(gl, "cuf"); in gl_control_strings()
3560 gl->sound_bell = gl_tigetstr(gl, "bel"); in gl_control_strings()
3561 gl->bold = gl_tigetstr(gl, "bold"); in gl_control_strings()
3562 gl->underline = gl_tigetstr(gl, "smul"); in gl_control_strings()
3563 gl->standout = gl_tigetstr(gl, "smso"); in gl_control_strings()
3564 gl->dim = gl_tigetstr(gl, "dim"); in gl_control_strings()
3565 gl->reverse = gl_tigetstr(gl, "rev"); in gl_control_strings()
3566 gl->blink = gl_tigetstr(gl, "blink"); in gl_control_strings()
3567 gl->text_attr_off = gl_tigetstr(gl, "sgr0"); in gl_control_strings()
3571 if(!term || tgetent(gl->tgetent_buf, (char *)term) < 0) { in gl_control_strings()
3574 char *tgetstr_buf_ptr = gl->tgetstr_buf; in gl_control_strings()
3575 _clr_StringGroup(gl->capmem); in gl_control_strings()
3576 gl->left = gl_tgetstr(gl, "le", &tgetstr_buf_ptr); in gl_control_strings()
3577 gl->right = gl_tgetstr(gl, "nd", &tgetstr_buf_ptr); in gl_control_strings()
3578 gl->up = gl_tgetstr(gl, "up", &tgetstr_buf_ptr); in gl_control_strings()
3579 gl->down = gl_tgetstr(gl, "do", &tgetstr_buf_ptr); in gl_control_strings()
3580 gl->home = gl_tgetstr(gl, "ho", &tgetstr_buf_ptr); in gl_control_strings()
3581 gl->clear_eol = gl_tgetstr(gl, "ce", &tgetstr_buf_ptr); in gl_control_strings()
3582 gl->clear_eod = gl_tgetstr(gl, "cd", &tgetstr_buf_ptr); in gl_control_strings()
3583 gl->u_arrow = gl_tgetstr(gl, "ku", &tgetstr_buf_ptr); in gl_control_strings()
3584 gl->d_arrow = gl_tgetstr(gl, "kd", &tgetstr_buf_ptr); in gl_control_strings()
3585 gl->l_arrow = gl_tgetstr(gl, "kl", &tgetstr_buf_ptr); in gl_control_strings()
3586 gl->r_arrow = gl_tgetstr(gl, "kr", &tgetstr_buf_ptr); in gl_control_strings()
3587 gl->sound_bell = gl_tgetstr(gl, "bl", &tgetstr_buf_ptr); in gl_control_strings()
3588 gl->bold = gl_tgetstr(gl, "md", &tgetstr_buf_ptr); in gl_control_strings()
3589 gl->underline = gl_tgetstr(gl, "us", &tgetstr_buf_ptr); in gl_control_strings()
3590 gl->standout = gl_tgetstr(gl, "so", &tgetstr_buf_ptr); in gl_control_strings()
3591 gl->dim = gl_tgetstr(gl, "mh", &tgetstr_buf_ptr); in gl_control_strings()
3592 gl->reverse = gl_tgetstr(gl, "mr", &tgetstr_buf_ptr); in gl_control_strings()
3593 gl->blink = gl_tgetstr(gl, "mb", &tgetstr_buf_ptr); in gl_control_strings()
3594 gl->text_attr_off = gl_tgetstr(gl, "me", &tgetstr_buf_ptr); in gl_control_strings()
3601 gl_print_info(gl, "Bad terminal type: \"", term ? term : "(null)", in gl_control_strings()
3607 if(!gl->left) in gl_control_strings()
3608 gl->left = "\b"; /* ^H */ in gl_control_strings()
3609 if(!gl->right) in gl_control_strings()
3610 gl->right = GL_ESC_STR "[C"; in gl_control_strings()
3611 if(!gl->up) in gl_control_strings()
3612 gl->up = GL_ESC_STR "[A"; in gl_control_strings()
3613 if(!gl->down) in gl_control_strings()
3614 gl->down = "\n"; in gl_control_strings()
3615 if(!gl->home) in gl_control_strings()
3616 gl->home = GL_ESC_STR "[H"; in gl_control_strings()
3617 if(!gl->bol) in gl_control_strings()
3618 gl->bol = "\r"; in gl_control_strings()
3619 if(!gl->clear_eol) in gl_control_strings()
3620 gl->clear_eol = GL_ESC_STR "[K"; in gl_control_strings()
3621 if(!gl->clear_eod) in gl_control_strings()
3622 gl->clear_eod = GL_ESC_STR "[J"; in gl_control_strings()
3623 if(!gl->u_arrow) in gl_control_strings()
3624 gl->u_arrow = GL_ESC_STR "[A"; in gl_control_strings()
3625 if(!gl->d_arrow) in gl_control_strings()
3626 gl->d_arrow = GL_ESC_STR "[B"; in gl_control_strings()
3627 if(!gl->l_arrow) in gl_control_strings()
3628 gl->l_arrow = GL_ESC_STR "[D"; in gl_control_strings()
3629 if(!gl->r_arrow) in gl_control_strings()
3630 gl->r_arrow = GL_ESC_STR "[C"; in gl_control_strings()
3631 if(!gl->sound_bell) in gl_control_strings()
3632 gl->sound_bell = "\a"; in gl_control_strings()
3633 if(!gl->bold) in gl_control_strings()
3634 gl->bold = GL_ESC_STR "[1m"; in gl_control_strings()
3635 if(!gl->underline) in gl_control_strings()
3636 gl->underline = GL_ESC_STR "[4m"; in gl_control_strings()
3637 if(!gl->standout) in gl_control_strings()
3638 gl->standout = GL_ESC_STR "[1;7m"; in gl_control_strings()
3639 if(!gl->dim) in gl_control_strings()
3640 gl->dim = ""; /* Not available */ in gl_control_strings()
3641 if(!gl->reverse) in gl_control_strings()
3642 gl->reverse = GL_ESC_STR "[7m"; in gl_control_strings()
3643 if(!gl->blink) in gl_control_strings()
3644 gl->blink = GL_ESC_STR "[5m"; in gl_control_strings()
3645 if(!gl->text_attr_off) in gl_control_strings()
3646 gl->text_attr_off = GL_ESC_STR "[m"; in gl_control_strings()
3650 (void) _gl_terminal_size(gl, GL_DEF_NCOLUMN, GL_DEF_NLINE, NULL); in gl_control_strings()
3667 static const char *gl_tigetstr(GetLine *gl, const char *name) in gl_tigetstr() argument
3672 return _sg_store_string(gl->capmem, value, 0); in gl_tigetstr()
3697 static const char *gl_tgetstr(GetLine *gl, const char *name, char **bufptr) in gl_tgetstr() argument
3702 return _sg_store_string(gl->capmem, value, 0); in gl_tgetstr()
3739 tcflow(gl->output_fd, TCOOFF); in KT_KEY_FN()
3748 tcflow(gl->output_fd, TCOON); in KT_KEY_FN()
3763 if(gl_read_terminal(gl, 1, &c)) in KT_KEY_FN()
3769 gl_add_char_to_line(gl, c); in KT_KEY_FN()
3785 static int gl_displayed_tab_width(GetLine *gl, int term_curpos) in gl_displayed_tab_width() argument
3787 return TAB_WIDTH - ((term_curpos % gl->ncolumn) % TAB_WIDTH); in gl_displayed_tab_width()
3806 static int gl_displayed_char_width(GetLine *gl, char c, int term_curpos) in gl_displayed_char_width() argument
3809 return gl_displayed_tab_width(gl, term_curpos); in gl_displayed_char_width()
3833 static int gl_displayed_string_width(GetLine *gl, const char *string, int nc, in gl_displayed_string_width() argument
3847 slen += gl_displayed_char_width(gl, string[i], term_curpos + slen); in gl_displayed_string_width()
3872 static int gl_print_raw_string(GetLine *gl, int buffered, in gl_print_raw_string() argument
3875 GlWriteFn *write_fn = buffered ? gl_write_fn : gl->flush_fn; in gl_print_raw_string()
3879 if(gl->echo) { in gl_print_raw_string()
3885 if(gl_flush_output(gl)) in gl_print_raw_string()
3896 if(write_fn(gl, string + ndone, n-ndone) != n) in gl_print_raw_string()
3916 static int gl_print_control_sequence(GetLine *gl, int nline, const char *string) in gl_print_control_sequence() argument
3922 if(gl->echo) { in gl_print_control_sequence()
3924 tputs_gl = gl; in gl_print_control_sequence()
3929 waserr = gl_print_raw_string(gl, 1, string, -1); in gl_print_control_sequence()
3961 static int gl_terminal_move_cursor(GetLine *gl, int n) in gl_terminal_move_cursor() argument
3972 if(!gl->displayed) in gl_terminal_move_cursor()
3977 if(gl->term_curpos + n < 0) in gl_terminal_move_cursor()
3978 n = gl->term_curpos; in gl_terminal_move_cursor()
3982 cur_row = gl->term_curpos / gl->ncolumn; in gl_terminal_move_cursor()
3983 cur_col = gl->term_curpos % gl->ncolumn; in gl_terminal_move_cursor()
3984 new_row = (gl->term_curpos + n) / gl->ncolumn; in gl_terminal_move_cursor()
3985 new_col = (gl->term_curpos + n) % gl->ncolumn; in gl_terminal_move_cursor()
3990 if(gl_print_control_sequence(gl, 1, gl->down)) in gl_terminal_move_cursor()
3997 if(gl_print_control_sequence(gl, 1, gl->up)) in gl_terminal_move_cursor()
4009 if(gl->right_n != NULL && new_col - cur_col > 1) { in gl_terminal_move_cursor()
4010 if(gl_print_control_sequence(gl, 1, tparm((char *)gl->right_n, in gl_terminal_move_cursor()
4017 if(gl_print_control_sequence(gl, 1, gl->right)) in gl_terminal_move_cursor()
4030 if(gl->left_n != NULL && cur_col - new_col > 3) { in gl_terminal_move_cursor()
4031 if(gl_print_control_sequence(gl, 1, tparm((char *)gl->left_n, in gl_terminal_move_cursor()
4038 if(gl_print_control_sequence(gl, 1, gl->left)) in gl_terminal_move_cursor()
4046 gl->term_curpos += n; in gl_terminal_move_cursor()
4072 static int gl_print_char(GetLine *gl, char c, char pad) in gl_print_char() argument
4085 nchar = gl_displayed_tab_width(gl, gl->term_curpos); in gl_print_char()
4109 if(gl_print_raw_string(gl, 1, string, -1)) in gl_print_char()
4115 gl->term_curpos += nchar; in gl_print_char()
4120 if(gl->term_curpos > gl->term_len) in gl_print_char()
4121 gl->term_len = gl->term_curpos; in gl_print_char()
4128 if(gl->term_curpos % gl->ncolumn == 0) { in gl_print_char()
4129 int term_curpos = gl->term_curpos; in gl_print_char()
4130 if(gl_print_char(gl, pad ? pad : ' ', ' ') || in gl_print_char()
4131 gl_set_term_curpos(gl, term_curpos)) in gl_print_char()
4159 static int gl_print_string(GetLine *gl, const char *string, char pad) in gl_print_string() argument
4164 if(gl_print_char(gl, *cptr, nextc ? nextc : pad)) in gl_print_string()
4180 static int gl_set_term_curpos(GetLine *gl, int term_curpos) in gl_set_term_curpos() argument
4182 return gl_terminal_move_cursor(gl, term_curpos - gl->term_curpos); in gl_set_term_curpos()
4191 return gl_place_cursor(gl, gl->buff_curpos - count); in KT_KEY_FN()
4200 return gl_place_cursor(gl, gl->buff_curpos + count); in KT_KEY_FN()
4209 gl->insert = !gl->insert; in KT_KEY_FN()
4219 return gl_place_cursor(gl, 0); in KT_KEY_FN()
4228 return gl_place_cursor(gl, gl->ntotal); in KT_KEY_FN()
4241 gl_save_for_undo(gl); in KT_KEY_FN()
4245 strlcpy(gl->cutbuf, gl->line, gl->linelen); in KT_KEY_FN()
4249 gl_truncate_buffer(gl, 0); in KT_KEY_FN()
4253 if(gl_place_cursor(gl, 0)) in KT_KEY_FN()
4258 if(gl_truncate_display(gl)) in KT_KEY_FN()
4273 gl_save_for_undo(gl); in KT_KEY_FN()
4277 strlcpy(gl->cutbuf, gl->line + gl->buff_curpos, gl->linelen); in KT_KEY_FN()
4281 gl_truncate_buffer(gl, gl->buff_curpos); in KT_KEY_FN()
4285 if(gl_truncate_display(gl)) in KT_KEY_FN()
4291 return gl_place_cursor(gl, gl->buff_curpos); in KT_KEY_FN()
4303 int nc = gl->buff_curpos - gl->insert_curpos; in KT_KEY_FN()
4311 return gl_place_cursor(gl, gl->insert_curpos) || in KT_KEY_FN()
4312 gl_delete_chars(gl, nc, gl->editor == GL_EMACS_MODE || gl->vi.command); in KT_KEY_FN()
4320 return gl_place_cursor(gl, gl_nth_word_end_forward(gl, count) + in KT_KEY_FN()
4321 (gl->editor==GL_EMACS_MODE)); in KT_KEY_FN()
4330 return gl_place_cursor(gl, gl_nth_word_start_forward(gl, count)); in KT_KEY_FN()
4338 return gl_place_cursor(gl, gl_nth_word_start_backward(gl, count)); in KT_KEY_FN()
4352 static int gl_delete_chars(GetLine *gl, int nc, int cut) in gl_delete_chars() argument
4358 gl_save_for_undo(gl); in gl_delete_chars()
4363 if(gl->buff_curpos + nc > gl->ntotal) in gl_delete_chars()
4364 nc = gl->ntotal - gl->buff_curpos; in gl_delete_chars()
4369 memcpy(gl->cutbuf, gl->line + gl->buff_curpos, nc); in gl_delete_chars()
4370 gl->cutbuf[nc] = '\0'; in gl_delete_chars()
4381 if(gl->editor == GL_VI_MODE && !gl->vi.command && !gl->insert) { in gl_delete_chars()
4386 int nrestore = gl->buff_curpos + nc <= gl->vi.undo.ntotal ? in gl_delete_chars()
4387 nc : gl->vi.undo.ntotal - gl->buff_curpos; in gl_delete_chars()
4392 gl_buffer_string(gl, gl->vi.undo.line + gl->buff_curpos, nrestore, in gl_delete_chars()
4393 gl->buff_curpos); in gl_delete_chars()
4403 gl_truncate_buffer(gl, (gl->vi.undo.ntotal > gl->buff_curpos) ? in gl_delete_chars()
4404 gl->vi.undo.ntotal : gl->buff_curpos); in gl_delete_chars()
4410 gl_remove_from_buffer(gl, gl->buff_curpos, nc); in gl_delete_chars()
4415 if(gl_print_string(gl, gl->line + gl->buff_curpos, '\0')) in gl_delete_chars()
4420 if(gl_truncate_display(gl)) in gl_delete_chars()
4425 return gl_place_cursor(gl, gl->buff_curpos); in gl_delete_chars()
4437 return gl_delete_chars(gl, count, gl->vi.command); in KT_KEY_FN()
4450 if(count > gl->buff_curpos - gl->insert_curpos) in KT_KEY_FN()
4451 count = gl->buff_curpos - gl->insert_curpos; in KT_KEY_FN()
4456 gl_save_for_undo(gl); in KT_KEY_FN()
4457 return gl_cursor_left(gl, count, NULL) || in KT_KEY_FN()
4458 gl_delete_chars(gl, count, gl->vi.command); in KT_KEY_FN()
4466 if (--count >= gl->buff_curpos) in KT_KEY_FN()
4467 return gl_forward_delete_char(gl, count - gl->buff_curpos, NULL); in KT_KEY_FN()
4469 return gl_backward_delete_char(gl, gl->buff_curpos - count, NULL); in KT_KEY_FN()
4478 int curpos = gl_index_of_matching_paren(gl); in KT_KEY_FN()
4480 gl_save_for_undo(gl); in KT_KEY_FN()
4481 if(curpos >= gl->buff_curpos) in KT_KEY_FN()
4482 return gl_forward_delete_char(gl, curpos - gl->buff_curpos + 1, NULL); in KT_KEY_FN()
4484 return gl_backward_delete_char(gl, ++gl->buff_curpos - curpos + 1, NULL); in KT_KEY_FN()
4499 gl_save_for_undo(gl); in KT_KEY_FN()
4504 if(gl->editor == GL_EMACS_MODE) { in KT_KEY_FN()
4505 return gl_delete_chars(gl, in KT_KEY_FN()
4506 gl_nth_word_end_forward(gl,count) - gl->buff_curpos + 1, 1); in KT_KEY_FN()
4508 return gl_delete_chars(gl, in KT_KEY_FN()
4509 gl_nth_word_start_forward(gl,count) - gl->buff_curpos, in KT_KEY_FN()
4510 gl->vi.command); in KT_KEY_FN()
4523 int buff_curpos = gl->buff_curpos; in KT_KEY_FN()
4528 gl_save_for_undo(gl); in KT_KEY_FN()
4532 if(gl_backward_word(gl, count, NULL)) in KT_KEY_FN()
4537 return gl_delete_chars(gl, buff_curpos - gl->buff_curpos, in KT_KEY_FN()
4538 gl->editor == GL_EMACS_MODE || gl->vi.command); in KT_KEY_FN()
4563 static int gl_delete_find(GetLine *gl, int count, char c, int forward, in gl_delete_find() argument
4569 int pos = gl_find_char(gl, count, forward, onto, c); in gl_delete_find()
4576 gl_save_for_undo(gl); in gl_delete_find()
4582 gl->vi.command = 0; in gl_delete_find()
4587 if(gl_delete_chars(gl, pos - gl->buff_curpos + 1, 1)) in gl_delete_find()
4590 int buff_curpos = gl->buff_curpos; in gl_delete_find()
4591 if(gl_place_cursor(gl, pos) || in gl_delete_find()
4592 gl_delete_chars(gl, buff_curpos - gl->buff_curpos, 1)) in gl_delete_find()
4598 if(change && gl_vi_insert(gl, 0, NULL)) in gl_delete_find()
4609 return gl_delete_find(gl, count, '\0', 1, 1, 0); in KT_KEY_FN()
4618 return gl_delete_find(gl, count, '\0', 0, 1, 0); in KT_KEY_FN()
4627 return gl_delete_find(gl, count, '\0', 1, 0, 0); in KT_KEY_FN()
4636 return gl_delete_find(gl, count, '\0', 0, 0, 0); in KT_KEY_FN()
4645 return gl_delete_find(gl, count, gl->vi.find_char, gl->vi.find_forward, in KT_KEY_FN()
4646 gl->vi.find_onto, 0); in KT_KEY_FN()
4655 return gl_delete_find(gl, count, gl->vi.find_char, in KT_KEY_FN()
4656 !gl->vi.find_forward, gl->vi.find_onto, 0); in KT_KEY_FN()
4668 int last = gl_nth_word_end_forward(gl, count); in KT_KEY_FN()
4673 gl_save_for_undo(gl); in KT_KEY_FN()
4677 while(gl->buff_curpos <= last) { in KT_KEY_FN()
4678 char *cptr = gl->line + gl->buff_curpos; in KT_KEY_FN()
4683 gl_buffer_char(gl, toupper((int) *cptr), gl->buff_curpos); in KT_KEY_FN()
4684 gl->buff_curpos++; in KT_KEY_FN()
4689 if(gl_print_char(gl, *cptr, cptr[1])) in KT_KEY_FN()
4692 return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ in KT_KEY_FN()
4704 int last = gl_nth_word_end_forward(gl, count); in KT_KEY_FN()
4709 gl_save_for_undo(gl); in KT_KEY_FN()
4713 while(gl->buff_curpos <= last) { in KT_KEY_FN()
4714 char *cptr = gl->line + gl->buff_curpos; in KT_KEY_FN()
4719 gl_buffer_char(gl, tolower((int) *cptr), gl->buff_curpos); in KT_KEY_FN()
4720 gl->buff_curpos++; in KT_KEY_FN()
4725 if(gl_print_char(gl, *cptr, cptr[1])) in KT_KEY_FN()
4728 return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ in KT_KEY_FN()
4744 int insert = gl->insert; in KT_KEY_FN()
4749 gl_save_for_undo(gl); in KT_KEY_FN()
4753 gl->insert = 0; in KT_KEY_FN()
4757 for(i=0; i<count && gl->buff_curpos < gl->ntotal; i++) { in KT_KEY_FN()
4758 int pos = gl->buff_curpos; in KT_KEY_FN()
4762 for(cptr = gl->line + pos ; pos<gl->ntotal && !gl_is_word_char((int) *cptr); in KT_KEY_FN()
4768 if(gl_place_cursor(gl, pos)) in KT_KEY_FN()
4774 for(first=1; gl->buff_curpos<gl->ntotal && gl_is_word_char((int) *cptr); in KT_KEY_FN()
4775 gl->buff_curpos++, cptr++) { in KT_KEY_FN()
4781 gl_buffer_char(gl, toupper((int) *cptr), cptr - gl->line); in KT_KEY_FN()
4784 gl_buffer_char(gl, tolower((int) *cptr), cptr - gl->line); in KT_KEY_FN()
4791 if(gl_print_char(gl, *cptr, cptr[1])) in KT_KEY_FN()
4798 gl->insert = insert; in KT_KEY_FN()
4799 return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ in KT_KEY_FN()
4810 int buff_curpos = gl->buff_curpos; in KT_KEY_FN()
4814 if(gl->endline) in KT_KEY_FN()
4819 if(gl_erase_line(gl)) in KT_KEY_FN()
4824 if(gl_display_prompt(gl)) in KT_KEY_FN()
4829 if(gl_print_string(gl, gl->line, '\0')) in KT_KEY_FN()
4834 if(gl_place_cursor(gl, buff_curpos)) in KT_KEY_FN()
4839 gl->redisplay = 0; in KT_KEY_FN()
4843 return gl_flush_output(gl); in KT_KEY_FN()
4855 if(gl_print_control_sequence(gl, gl->nline, gl->home) || in KT_KEY_FN()
4856 gl_print_control_sequence(gl, gl->nline, gl->clear_eod)) in KT_KEY_FN()
4861 gl_line_erased(gl); in KT_KEY_FN()
4865 gl_queue_redisplay(gl); in KT_KEY_FN()
4881 if(gl->buff_curpos < 1 || gl->buff_curpos >= gl->ntotal) in KT_KEY_FN()
4887 gl_save_for_undo(gl); in KT_KEY_FN()
4891 from[0] = gl->line[gl->buff_curpos - 1]; in KT_KEY_FN()
4892 from[1] = gl->line[gl->buff_curpos]; in KT_KEY_FN()
4894 swap[0] = gl->line[gl->buff_curpos]; in KT_KEY_FN()
4895 swap[1] = gl->line[gl->buff_curpos - 1]; in KT_KEY_FN()
4900 if(gl_place_cursor(gl, gl->buff_curpos-1)) in KT_KEY_FN()
4905 gl_buffer_char(gl, swap[0], gl->buff_curpos); in KT_KEY_FN()
4906 gl_buffer_char(gl, swap[1], gl->buff_curpos+1); in KT_KEY_FN()
4912 if(gl_displayed_string_width(gl, from, -1, gl->term_curpos) == in KT_KEY_FN()
4913 gl_displayed_string_width(gl, swap, -1, gl->term_curpos)) { in KT_KEY_FN()
4914 int insert = gl->insert; in KT_KEY_FN()
4915 gl->insert = 0; in KT_KEY_FN()
4916 if(gl_print_char(gl, swap[0], swap[1]) || in KT_KEY_FN()
4917 gl_print_char(gl, swap[1], gl->line[gl->buff_curpos+2])) in KT_KEY_FN()
4919 gl->insert = insert; in KT_KEY_FN()
4925 if(gl_print_string(gl, gl->line + gl->buff_curpos, '\0') || in KT_KEY_FN()
4926 gl_truncate_display(gl)) in KT_KEY_FN()
4932 return gl_place_cursor(gl, gl->buff_curpos + 2); in KT_KEY_FN()
4941 gl->buff_mark = gl->buff_curpos; in KT_KEY_FN()
4955 int old_mark = gl->buff_mark <= gl->ntotal ? gl->buff_mark : gl->ntotal; in KT_KEY_FN()
4959 gl->buff_mark = gl->buff_curpos; in KT_KEY_FN()
4963 return gl_place_cursor(gl, old_mark); in KT_KEY_FN()
4976 gl_save_for_undo(gl); in KT_KEY_FN()
4980 if(gl->buff_mark > gl->ntotal) in KT_KEY_FN()
4981 gl->buff_mark = gl->ntotal; in KT_KEY_FN()
4986 if(gl->buff_mark == gl->buff_curpos) { in KT_KEY_FN()
4987 gl->cutbuf[0] = '\0'; in KT_KEY_FN()
4993 if(gl->buff_mark < gl->buff_curpos && gl_exchange_point_and_mark(gl,1,NULL)) in KT_KEY_FN()
4998 if(gl_delete_chars(gl, gl->buff_mark - gl->buff_curpos, 1)) in KT_KEY_FN()
5003 gl->buff_mark = gl->buff_curpos; in KT_KEY_FN()
5018 mark = gl->buff_mark > gl->ntotal ? gl->ntotal : gl->buff_mark; in KT_KEY_FN()
5023 if(mark == gl->buff_curpos) { in KT_KEY_FN()
5024 gl->cutbuf[0] = '\0'; in KT_KEY_FN()
5030 if(mark < gl->buff_curpos) { in KT_KEY_FN()
5032 cb = gl->buff_curpos - 1; in KT_KEY_FN()
5034 ca = gl->buff_curpos; in KT_KEY_FN()
5040 memcpy(gl->cutbuf, gl->line + ca, cb + 1 - ca); in KT_KEY_FN()
5041 gl->cutbuf[cb + 1 - ca] = '\0'; in KT_KEY_FN()
5055 gl->buff_mark = gl->buff_curpos; in KT_KEY_FN()
5059 if(gl->cutbuf[0] == '\0') in KT_KEY_FN()
5060 return gl_ring_bell(gl, 1, NULL); in KT_KEY_FN()
5065 gl_save_for_undo(gl); in KT_KEY_FN()
5070 if(gl_add_string_to_line(gl, gl->cutbuf)) in KT_KEY_FN()
5077 if(gl->editor == GL_VI_MODE && gl_cursor_left(gl, 1, NULL)) in KT_KEY_FN()
5088 int was_command = gl->vi.command; in KT_KEY_FN()
5093 if(gl->cutbuf[0] == '\0') in KT_KEY_FN()
5094 return gl_ring_bell(gl, 1, NULL); in KT_KEY_FN()
5098 gl->buff_mark = gl->buff_curpos + 1; in KT_KEY_FN()
5103 gl_save_for_undo(gl); in KT_KEY_FN()
5107 if(gl_vi_append(gl, 0, NULL)) in KT_KEY_FN()
5113 if(gl_add_string_to_line(gl, gl->cutbuf)) in KT_KEY_FN()
5120 gl_vi_command_mode(gl); in KT_KEY_FN()
5135 static void gl_query_size(GetLine *gl, int *ncolumn, int *nline) in gl_query_size() argument
5142 if(ioctl(gl->output_fd, TIOCGWINSZ, &size) == 0 && in gl_query_size()
5152 *ncolumn = gl->ncolumn; in gl_query_size()
5153 *nline = gl->nline; in gl_query_size()
5167 static int _gl_update_size(GetLine *gl) in _gl_update_size() argument
5173 gl_query_size(gl, &ncolumn, &nline); in _gl_update_size()
5177 return gl_handle_tty_resize(gl, ncolumn, nline); in _gl_update_size()
5192 static int gl_handle_tty_resize(GetLine *gl, int ncolumn, int nline) in gl_handle_tty_resize() argument
5197 if(!gl->is_term) { in gl_handle_tty_resize()
5198 gl->nline = nline; in gl_handle_tty_resize()
5199 gl->ncolumn = ncolumn; in gl_handle_tty_resize()
5203 } else if(ncolumn != gl->ncolumn || nline != gl->nline) { in gl_handle_tty_resize()
5207 if(gl_erase_line(gl)) in gl_handle_tty_resize()
5212 gl->nline = nline; in gl_handle_tty_resize()
5213 gl->ncolumn = ncolumn; in gl_handle_tty_resize()
5218 gl_queue_redisplay(gl); in gl_handle_tty_resize()
5233 gl_vi_command_mode(gl); in KT_KEY_FN()
5237 gl->preload_id = 0; in KT_KEY_FN()
5241 gl->last_search = gl->keyseq_count; in KT_KEY_FN()
5245 if(_glh_search_prefix(gl->glh, gl->line, 0)) { in KT_KEY_FN()
5246 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG); in KT_KEY_FN()
5254 if(_glh_find_backwards(gl->glh, gl->line, gl->linelen+1) == NULL) in KT_KEY_FN()
5256 while(--count && _glh_find_backwards(gl->glh, gl->line, gl->linelen+1)) in KT_KEY_FN()
5261 gl_update_buffer(gl); in KT_KEY_FN()
5265 gl->buff_curpos = gl->ntotal; in KT_KEY_FN()
5269 gl_queue_redisplay(gl); in KT_KEY_FN()
5283 gl_vi_command_mode(gl); in KT_KEY_FN()
5287 gl->last_search = gl->keyseq_count; in KT_KEY_FN()
5292 if(_glh_line_id(gl->glh, 0) == 0 && gl->preload_id) { in KT_KEY_FN()
5293 _glh_recall_line(gl->glh, gl->preload_id, gl->line, gl->linelen+1); in KT_KEY_FN()
5294 gl->preload_id = 0; in KT_KEY_FN()
5299 if(_glh_search_prefix(gl->glh, gl->line, 0)) { in KT_KEY_FN()
5300 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG); in KT_KEY_FN()
5308 if(_glh_find_forwards(gl->glh, gl->line, gl->linelen+1) == NULL) in KT_KEY_FN()
5310 while(--count && _glh_find_forwards(gl->glh, gl->line, gl->linelen+1)) in KT_KEY_FN()
5316 gl_update_buffer(gl); in KT_KEY_FN()
5320 gl->buff_curpos = gl->ntotal; in KT_KEY_FN()
5324 gl_queue_redisplay(gl); in KT_KEY_FN()
5340 gl_vi_command_mode(gl); in KT_KEY_FN()
5344 gl->preload_id = 0; in KT_KEY_FN()
5348 gl->last_search = gl->keyseq_count; in KT_KEY_FN()
5356 if(count >= 0 && !_glh_search_active(gl->glh) && in KT_KEY_FN()
5357 _glh_search_prefix(gl->glh, gl->line, gl->buff_curpos + in KT_KEY_FN()
5358 (gl->editor==GL_VI_MODE && gl->ntotal>0))) { in KT_KEY_FN()
5359 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG); in KT_KEY_FN()
5366 if(_glh_find_backwards(gl->glh, gl->line, gl->linelen+1) == NULL) in KT_KEY_FN()
5371 gl_update_buffer(gl); in KT_KEY_FN()
5375 gl->buff_curpos = gl->ntotal; in KT_KEY_FN()
5379 gl_queue_redisplay(gl); in KT_KEY_FN()
5390 return gl_history_search_backward(gl, -1, NULL); in KT_KEY_FN()
5406 gl_vi_command_mode(gl); in KT_KEY_FN()
5410 gl->last_search = gl->keyseq_count; in KT_KEY_FN()
5418 if(count >= 0 && !_glh_search_active(gl->glh) && in KT_KEY_FN()
5419 _glh_search_prefix(gl->glh, gl->line, gl->buff_curpos + in KT_KEY_FN()
5420 (gl->editor==GL_VI_MODE && gl->ntotal>0))) { in KT_KEY_FN()
5421 _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG); in KT_KEY_FN()
5427 if(_glh_find_forwards(gl->glh, gl->line, gl->linelen+1) == NULL) in KT_KEY_FN()
5432 gl_update_buffer(gl); in KT_KEY_FN()
5436 gl->buff_curpos = gl->ntotal; in KT_KEY_FN()
5440 gl_queue_redisplay(gl); in KT_KEY_FN()
5451 return gl_history_search_forward(gl, -1, NULL); in KT_KEY_FN()
5484 GlCplCallback *cb = data ? (GlCplCallback *) data : &gl->cplfn; in KT_KEY_FN()
5490 if(gl->vi.command && gl_vi_append(gl, 0, NULL)) in KT_KEY_FN()
5495 buff_pos = gl->buff_curpos; in KT_KEY_FN()
5499 matches = cpl_complete_word(gl->cpl, gl->line, gl->buff_curpos, cb->data, in KT_KEY_FN()
5505 waserr = gl_print_info(gl, cpl_last_error(gl->cpl), GL_END_INFO); in KT_KEY_FN()
5513 if(matches->nmatch > 1 && gl->echo) { in KT_KEY_FN()
5514 if(_gl_normal_io(gl) || in KT_KEY_FN()
5515 _cpl_output_completions(matches, gl_write_fn, gl, gl->ncolumn)) in KT_KEY_FN()
5531 if(gl_newline(gl, 1, NULL)) in KT_KEY_FN()
5545 if(gl->ntotal + nextra < gl->linelen) { in KT_KEY_FN()
5549 gl_make_gap_in_buffer(gl, gl->buff_curpos, nextra); in KT_KEY_FN()
5553 gl_buffer_string(gl, matches->suffix, suffix_len, gl->buff_curpos); in KT_KEY_FN()
5557 gl_buffer_string(gl, matches->cont_suffix, cont_len, in KT_KEY_FN()
5558 gl->buff_curpos + suffix_len); in KT_KEY_FN()
5562 gl->buff_curpos += nextra; in KT_KEY_FN()
5568 if(gl->displayed) { in KT_KEY_FN()
5569 if(gl_truncate_display(gl) || in KT_KEY_FN()
5570 gl_print_string(gl, gl->line + buff_pos, '\0') || in KT_KEY_FN()
5571 gl_place_cursor(gl, gl->buff_curpos)) in KT_KEY_FN()
5575 (void) gl_print_info(gl, in KT_KEY_FN()
5587 if(_gl_raw_io(gl, 1)) in KT_KEY_FN()
5613 if(gl->vi.command && gl_vi_append(gl, 0, NULL)) in KT_KEY_FN()
5618 start_path = _pu_start_of_path(gl->line, gl->buff_curpos); in KT_KEY_FN()
5624 pathlen = gl->buff_curpos - (start_path - gl->line); in KT_KEY_FN()
5628 result = ef_expand_file(gl->ef, start_path, pathlen); in KT_KEY_FN()
5633 return gl_print_info(gl, ef_last_error(gl->ef), GL_END_INFO); in KT_KEY_FN()
5638 return gl_print_info(gl, "No files match.", GL_END_INFO); in KT_KEY_FN()
5643 gl_save_for_undo(gl); in KT_KEY_FN()
5670 if(gl->ntotal + nextra >= gl->linelen) { in KT_KEY_FN()
5671 return gl_print_info(gl, "Insufficient room in line for file expansion.", in KT_KEY_FN()
5679 gl_make_gap_in_buffer(gl, gl->buff_curpos, nextra); in KT_KEY_FN()
5681 gl->buff_curpos += nextra; in KT_KEY_FN()
5682 gl_remove_from_buffer(gl, gl->buff_curpos, -nextra); in KT_KEY_FN()
5688 for(i=0,j=start_path - gl->line; i<result->nfile; i++) { in KT_KEY_FN()
5694 gl_buffer_char(gl, '\\', j++); in KT_KEY_FN()
5696 gl_buffer_char(gl, c, j++); in KT_KEY_FN()
5698 gl_buffer_char(gl, ' ', j++); in KT_KEY_FN()
5705 if(gl_place_cursor(gl, start_path - gl->line) || in KT_KEY_FN()
5706 gl_truncate_display(gl) || in KT_KEY_FN()
5707 gl_print_string(gl, start_path, start_path[length])) in KT_KEY_FN()
5712 return gl_place_cursor(gl, (start_path - gl->line) + length); in KT_KEY_FN()
5731 start_path = _pu_start_of_path(gl->line, gl->buff_curpos); in KT_KEY_FN()
5737 pathlen = gl->buff_curpos - (start_path - gl->line); in KT_KEY_FN()
5741 result = ef_expand_file(gl->ef, start_path, pathlen); in KT_KEY_FN()
5746 return gl_print_info(gl, ef_last_error(gl->ef), GL_END_INFO); in KT_KEY_FN()
5751 return gl_print_info(gl, "No files match.", GL_END_INFO); in KT_KEY_FN()
5755 } else if(gl->echo) { in KT_KEY_FN()
5756 if(gl_start_newline(gl, 1) || in KT_KEY_FN()
5757 _ef_output_expansions(result, gl_write_fn, gl, gl->ncolumn)) in KT_KEY_FN()
5759 gl_queue_redisplay(gl); in KT_KEY_FN()
5796 int gl_customize_completion(GetLine *gl, void *data, CplMatchFn *match_fn) in gl_customize_completion() argument
5802 if(!gl || !match_fn) { in gl_customize_completion()
5803 if(gl) in gl_customize_completion()
5804 _err_record_msg(gl->err, "NULL argument", END_ERR_MSG); in gl_customize_completion()
5811 gl_mask_signals(gl, &oldset); in gl_customize_completion()
5815 gl->cplfn.fn = match_fn; in gl_customize_completion()
5816 gl->cplfn.data = data; in gl_customize_completion()
5820 gl_unmask_signals(gl, &oldset); in gl_customize_completion()
5840 int gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp, in gl_change_terminal() argument
5848 if(!gl) { in gl_change_terminal()
5855 if(gl_mask_signals(gl, &oldset)) in gl_change_terminal()
5860 status = _gl_change_terminal(gl, input_fp, output_fp, term); in gl_change_terminal()
5864 gl_unmask_signals(gl, &oldset); in gl_change_terminal()
5873 static int _gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp, in _gl_change_terminal() argument
5882 gl_print_info(gl, "Can't change terminal. Bad input/output stream(s).", in _gl_change_terminal()
5890 if(gl->input_fd >= 0) { in _gl_change_terminal()
5894 if(_gl_normal_io(gl)) in _gl_change_terminal()
5900 FD_CLR(gl->input_fd, &gl->rfds); in _gl_change_terminal()
5906 gl->input_fp = input_fp; in _gl_change_terminal()
5907 gl->input_fd = fileno(input_fp); in _gl_change_terminal()
5908 gl->output_fp = output_fp; in _gl_change_terminal()
5909 gl->output_fd = fileno(output_fp); in _gl_change_terminal()
5915 if(gl->input_fd > gl->max_fd) in _gl_change_terminal()
5916 gl->max_fd = gl->input_fd; in _gl_change_terminal()
5922 gl->is_term = 0; in _gl_change_terminal()
5928 is_term = isatty(gl->input_fd) && isatty(gl->output_fd); in _gl_change_terminal()
5938 if(term != gl->term) { in _gl_change_terminal()
5942 if(gl->term) { in _gl_change_terminal()
5943 free(gl->term); in _gl_change_terminal()
5944 gl->term = NULL; in _gl_change_terminal()
5952 gl->term = (char *) malloc(termsz); in _gl_change_terminal()
5953 if(gl->term) in _gl_change_terminal()
5954 strlcpy(gl->term, term, termsz); in _gl_change_terminal()
5961 _kt_clear_bindings(gl->bindings, KTB_TERM); in _gl_change_terminal()
5969 if(tcgetattr(gl->input_fd, &gl->oldattr)) { in _gl_change_terminal()
5970 _err_record_msg(gl->err, "tcgetattr error", END_ERR_MSG); in _gl_change_terminal()
5977 gl->is_term = 1; in _gl_change_terminal()
5981 if(gl_control_strings(gl, term)) { in _gl_change_terminal()
5982 gl->is_term = 0; in _gl_change_terminal()
5988 if(gl_bind_terminal_keys(gl)) in _gl_change_terminal()
5994 gl->io_mode = GL_NORMAL_MODE; in _gl_change_terminal()
5998 if(_gl_io_mode(gl, gl->io_mode)) in _gl_change_terminal()
6013 static int gl_bind_terminal_keys(GetLine *gl) in gl_bind_terminal_keys() argument
6018 if(gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VINTR], in gl_bind_terminal_keys()
6020 gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VQUIT], "abort") || in gl_bind_terminal_keys()
6021 gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VSUSP], "suspend")) in gl_bind_terminal_keys()
6027 if(gl->editor == GL_VI_MODE) { in gl_bind_terminal_keys()
6028 if(gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VINTR]), in gl_bind_terminal_keys()
6030 gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VQUIT]), in gl_bind_terminal_keys()
6032 gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VSUSP]), in gl_bind_terminal_keys()
6040 if(gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VLNEXT], in gl_bind_terminal_keys()
6044 if(_kt_set_keybinding(gl->bindings, KTB_TERM, "^V", "literal-next")) { in gl_bind_terminal_keys()
6045 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG); in gl_bind_terminal_keys()
6053 if(_gl_bind_arrow_keys(gl)) in gl_bind_terminal_keys()
6070 if(gl->ntotal < 1) { in KT_KEY_FN()
6071 gl_record_status(gl, GLR_EOF, 0); in KT_KEY_FN()
6076 } else if(gl->buff_curpos >= gl->ntotal) { in KT_KEY_FN()
6077 return gl_list_completions(gl, 1, NULL); in KT_KEY_FN()
6086 gl_save_for_undo(gl); in KT_KEY_FN()
6090 return gl_forward_delete_char(gl, count, NULL); in KT_KEY_FN()
6105 if(gl->ntotal < 1) { in KT_KEY_FN()
6106 gl_record_status(gl, GLR_EOF, 0); in KT_KEY_FN()
6112 return gl_list_completions(gl, 1, NULL); in KT_KEY_FN()
6128 GlCplCallback *cb = data ? (GlCplCallback *) data : &gl->cplfn; in KT_KEY_FN()
6132 CplMatches *matches = cpl_complete_word(gl->cpl, gl->line, gl->buff_curpos, in KT_KEY_FN()
6138 waserr = gl_print_info(gl, cpl_last_error(gl->cpl), GL_END_INFO); in KT_KEY_FN()
6142 } else if(matches->nmatch > 0 && gl->echo) { in KT_KEY_FN()
6143 if(_gl_normal_io(gl) || in KT_KEY_FN()
6144 _cpl_output_completions(matches, gl_write_fn, gl, gl->ncolumn)) in KT_KEY_FN()
6152 if(_gl_raw_io(gl, 1)) in KT_KEY_FN()
6168 static int _gl_bind_arrow_keys(GetLine *gl) in _gl_bind_arrow_keys() argument
6173 if(_gl_rebind_arrow_key(gl, "up", gl->u_arrow, "^[[A", "^[OA") || in _gl_bind_arrow_keys()
6174 _gl_rebind_arrow_key(gl, "down", gl->d_arrow, "^[[B", "^[OB") || in _gl_bind_arrow_keys()
6175 _gl_rebind_arrow_key(gl, "left", gl->l_arrow, "^[[D", "^[OD") || in _gl_bind_arrow_keys()
6176 _gl_rebind_arrow_key(gl, "right", gl->r_arrow, "^[[C", "^[OC")) in _gl_bind_arrow_keys()
6201 static int _gl_rebind_arrow_key(GetLine *gl, const char *name, in _gl_rebind_arrow_key() argument
6211 if(_kt_lookup_keybinding(gl->bindings, name, strlen(name), &keysym, &nsym) in _gl_rebind_arrow_key()
6223 _kt_set_keyfn(gl->bindings, KTB_TERM, term_seq, fn, data)) || in _gl_rebind_arrow_key()
6225 _kt_set_keyfn(gl->bindings, KTB_NORM, def_seq1, fn, data)) || in _gl_rebind_arrow_key()
6227 _kt_set_keyfn(gl->bindings, KTB_NORM, def_seq2, fn, data))) { in _gl_rebind_arrow_key()
6228 _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG); in _gl_rebind_arrow_key()
6250 static int _gl_read_config_file(GetLine *gl, const char *filename, KtBinder who) in _gl_read_config_file() argument
6257 _err_record_msg(gl->err, in _gl_read_config_file()
6270 if(!gl || !filename) { in _gl_read_config_file()
6271 if(gl) in _gl_read_config_file()
6272 _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG); in _gl_read_config_file()
6279 expansion = ef_expand_file(gl->ef, filename, -1); in _gl_read_config_file()
6281 gl_print_info(gl, "Unable to expand ", filename, " (", in _gl_read_config_file()
6282 ef_last_error(gl->ef), ").", GL_END_INFO); in _gl_read_config_file()
6298 waserr = _gl_parse_config_line(gl, fp, glc_file_getc, filename, who, in _gl_read_config_file()
6303 if(_gl_bind_arrow_keys(gl)) in _gl_read_config_file()
6318 static int _gl_read_config_string(GetLine *gl, const char *buffer, KtBinder who) in _gl_read_config_string() argument
6326 if(!gl || !buffer) { in _gl_read_config_string()
6327 if(gl) in _gl_read_config_string()
6328 _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG); in _gl_read_config_string()
6340 waserr = _gl_parse_config_line(gl, &bptr, glc_buff_getc, "", who, &lineno); in _gl_read_config_string()
6344 if(_gl_bind_arrow_keys(gl)) in _gl_read_config_string()
6369 static int _gl_parse_config_line(GetLine *gl, void *stream, GlcGetcFn *getc_fn, in _gl_parse_config_line() argument
6428 gl_report_config_error(gl, origin, *lineno, "Too many arguments."); in _gl_parse_config_line()
6470 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, &current_fn, &current_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, &current_fn, &current_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;