📄 textarea.c
字号:
unlink(filename); return value;}voidtextarea_edit(int op, struct terminal *term_, struct form_state *fs_, struct document_view *doc_view_, struct link *link_){ static int fc_maxlength; static struct form_state *fs; static struct terminal *term; static struct document_view *doc_view; static struct link *link; static unsigned char *fn; assert (op == 0 || op == 1); if_assert_failed return; assert (op == 1 || term_); if_assert_failed return; if (op == 0 && get_cmd_opt_bool("anonymous")) { info_box(term_, 0, N_("Error"), ALIGN_CENTER, N_("You cannot launch an external" " editor in the anonymous mode.")); return; } if (op == 0 && !term_->master) { info_box(term_, 0, N_("Error"), ALIGN_CENTER, N_("You can do this only on the master terminal")); return; } if (op == 0 && !textarea_editor) { unsigned char *ed = getenv("EDITOR"); unsigned char *ex; fn = save_textarea_file(fs_->value); if (!fn) return; if (!ed || !*ed) ed = "vi"; ex = straconcat(ed, " ", fn, NULL); if (!ex) { unlink(fn); goto free_and_return; } if (fs_) fs = fs_; if (doc_view_) doc_view = doc_view_; if (link_) { link = link_; fc_maxlength = get_link_form_control(link_)->maxlength; } if (term_) term = term_; exec_on_terminal(term, ex, "", 1); mem_free(ex); textarea_editor = 1; } else if (op == 1 && fs) { unsigned char *value = load_textarea_file(fn, fc_maxlength); if (value) { mem_free(fs->value); fs->value = value; fs->state = strlen(value); if (doc_view && link) draw_form_entry(term, doc_view, link); } textarea_editor = 0; goto free_and_return; } return;free_and_return: mem_free_set(&fn, NULL); fs = NULL;}/* menu_func */voidmenu_textarea_edit(struct terminal *term, void *xxx, void *ses_){ struct session *ses = ses_; struct document_view *doc_view; struct link *link; struct form_state *fs; struct form_control *fc; assert(term && ses); if_assert_failed return; doc_view = current_frame(ses); assert(doc_view && doc_view->vs && doc_view->document); if_assert_failed return; link = get_current_link(doc_view); if (!link) return; fc = get_link_form_control(link); if (form_field_is_readonly(fc)) return; fs = find_form_state(doc_view, fc); if (!fs) return; textarea_edit(0, term, fs, doc_view, link);}/* TODO: Unify the textarea field_op handlers to one trampoline function. */enum frame_event_statustextarea_op_home(struct form_state *fs, struct form_control *fc){ struct line_info *line; int current, state; assert(fs && fs->value && fc); if_assert_failed return FRAME_EVENT_OK; state = fs->state; line = format_text(fs->value, fc->cols, fc->wrap, 0); if (!line) return FRAME_EVENT_OK; current = get_textarea_line_number(line, fs->state); if (current != -1) fs->state = line[current].start; mem_free(line); return fs->state == state ? FRAME_EVENT_OK : FRAME_EVENT_REFRESH;}enum frame_event_statustextarea_op_up(struct form_state *fs, struct form_control *fc){ struct line_info *line; int current, state; assert(fs && fs->value && fc); if_assert_failed return FRAME_EVENT_OK; line = format_text(fs->value, fc->cols, fc->wrap, 0); if (!line) return FRAME_EVENT_OK; current = get_textarea_line_number(line, fs->state); if (current == -1) { mem_free(line); return FRAME_EVENT_OK; } if (!current) { mem_free(line); return FRAME_EVENT_IGNORED; } state = fs->state; fs->state -= line[current].start - line[current-1].start; int_upper_bound(&fs->state, line[current-1].end); mem_free(line); return fs->state == state ? FRAME_EVENT_OK : FRAME_EVENT_REFRESH;}enum frame_event_statustextarea_op_down(struct form_state *fs, struct form_control *fc){ struct line_info *line; int current, state; assert(fs && fs->value && fc); if_assert_failed return FRAME_EVENT_OK; line = format_text(fs->value, fc->cols, fc->wrap, 0); if (!line) return FRAME_EVENT_OK; current = get_textarea_line_number(line, fs->state); if (current == -1) { mem_free(line); return FRAME_EVENT_OK; } if (line[current+1].start == -1) { mem_free(line); return FRAME_EVENT_IGNORED; } state = fs->state; fs->state += line[current+1].start - line[current].start; int_upper_bound(&fs->state, line[current+1].end); mem_free(line); return fs->state == state ? FRAME_EVENT_OK : FRAME_EVENT_REFRESH;}enum frame_event_statustextarea_op_end(struct form_state *fs, struct form_control *fc){ struct line_info *line; int current, state; assert(fs && fs->value && fc); if_assert_failed return FRAME_EVENT_OK; state = fs->state; line = format_text(fs->value, fc->cols, fc->wrap, 0); if (!line) return FRAME_EVENT_OK; current = get_textarea_line_number(line, fs->state); if (current == -1) { fs->state = strlen(fs->value); } else { int wrap = line[current + 1].start == line[current].end; /* Don't jump to next line when wrapping. */ fs->state = int_max(0, line[current].end - wrap); } mem_free(line); return fs->state == state ? FRAME_EVENT_OK : FRAME_EVENT_REFRESH;}/* Set the form state so the cursor is on the first line of the buffer. * Preserve the column if possible. */enum frame_event_statustextarea_op_bob(struct form_state *fs, struct form_control *fc){ struct line_info *line; int current, state; assert(fs && fs->value && fc); if_assert_failed return FRAME_EVENT_OK; state = fs->state; line = format_text(fs->value, fc->cols, fc->wrap, 0); if (!line) return FRAME_EVENT_OK; current = get_textarea_line_number(line, fs->state); if (current != -1) { fs->state -= line[current].start; int_upper_bound(&fs->state, line[0].end); } mem_free(line); return fs->state == state ? FRAME_EVENT_OK : FRAME_EVENT_REFRESH;}/* Set the form state so the cursor is on the last line of the buffer. Preserve * the column if possible. This is done by getting current and last line and * then shifting the state by the delta of both lines start position bounding * the whole thing to the end of the last line. */enum frame_event_statustextarea_op_eob(struct form_state *fs, struct form_control *fc){ struct line_info *line; int current, state; assert(fs && fs->value && fc); if_assert_failed return FRAME_EVENT_OK; state = fs->state; line = format_text(fs->value, fc->cols, fc->wrap, 0); if (!line) return FRAME_EVENT_OK; current = get_textarea_line_number(line, fs->state); if (current == -1) { fs->state = strlen(fs->value); } else { int last = get_textarea_line_number(line, strlen(fs->value)); assertm(last != -1, "line info corrupt"); fs->state += line[last].start - line[current].start; int_upper_bound(&fs->state, line[last].end); } mem_free(line); return fs->state == state ? FRAME_EVENT_OK : FRAME_EVENT_REFRESH;}enum frame_event_statustextarea_op_enter(struct form_state *fs, struct form_control *fc){ assert(fs && fs->value && fc); if_assert_failed return FRAME_EVENT_OK; if (form_field_is_readonly(fc) || strlen(fs->value) >= fc->maxlength || !insert_in_string(&fs->value, fs->state, "\n", 1)) return FRAME_EVENT_OK; fs->state++; return FRAME_EVENT_REFRESH;}voidset_textarea(struct document_view *doc_view, int direction){ struct form_control *fc; struct form_state *fs; struct link *link; assert(doc_view && doc_view->vs && doc_view->document); assert(direction == 1 || direction == -1); if_assert_failed return; link = get_current_link(doc_view); if (!link || link->type != LINK_AREA) return; fc = get_link_form_control(link); assertm(fc, "link has no form control"); if_assert_failed return; if (fc->mode == FORM_MODE_DISABLED) return; fs = find_form_state(doc_view, fc); if (!fs || !fs->value) return; /* Depending on which way we entered the textarea move cursor so that * it is available at end or start. */ if (direction == 1) textarea_op_eob(fs, fc); else textarea_op_bob(fs, fc);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -