📄 textedit.cc
字号:
{ return CURSOR_NORMAL;}ht_syntax_lexer *ht_text_viewer::get_lexer(){ return lexer;}/* * 0xffffffff --> ignore this line */uint ht_text_viewer::get_line_indent(uint line){ char s[1024]; uint i, r, j; textfile->getline(line, 0, s, 1024, &i, NULL); if (i==0) return 0xffffffff; j = r = 0; while (i && (s[j]==' ' || s[j]=='\t')) { r += char_vsize(s[j], r); j++; i--; } if (i==0) return 0xffffffff; return r;}uint ht_text_viewer::get_line_length(uint line){ return textfile->getlinelength(line);}uint ht_text_viewer::get_line_vlength(uint line){ char l[1024]; char *linep=l; uint vl=0; uint linelen; if (!textfile->getline(line, 0, l, sizeof l, &linelen, NULL)) return 0; while (linelen--) vl+=char_vsize(*(linep++), vl); return vl;}int ht_text_viewer::get_pindicator_str(char *buf, int max_len){ ht_syntax_lexer *l = get_lexer(); const char *ln = l ? l->getname() : NULL; if (ln) { return ht_snprintf(buf, max_len, " %d:%d (%s) ", top_line+cursory+1, xofs+cursorx+1, ln); } else { return ht_snprintf(buf, max_len, " %d:%d ", top_line+cursory+1, xofs+cursorx+1); }}bool ht_text_viewer::get_vscrollbar_pos(int *pstart, int *psize){ return (scrollbar_pos(top_line, size.h, textfile->linecount(), pstart, psize));}void ht_text_viewer::get_selection(text_viewer_pos *start, text_viewer_pos *end){ *start = sel_start; *end = sel_end;}ht_textfile *ht_text_viewer::get_textfile(){ return textfile;}bool ht_text_viewer::get_hscrollbar_pos(int *pstart, int *psize){ return false;}bool ht_text_viewer::goto_line(uint line){ if (line >= textfile->linecount()) { return false; } if ((line >= top_line) && (line - top_line < (uint)size.h)) { cursory = line - top_line; } else { cursory = 0; if (line > top_line) { top_line = line; cursor_down(cursor_up(size.h)); } else { top_line = line; cursor_up(cursor_down(size.h)); } } return true;}void ht_text_viewer::handlemsg(htmsg *msg){ switch (msg->msg) { case msg_keypressed: { int k=msg->data1.integer; bool sel; switch (k) { case K_Meta_S: selectcursor=!selectcursor; clearmsg(msg); return; case K_Control_Shift_Right: case K_Control_Right: { sel=(k==K_Control_Shift_Right) != selectcursor; char line[1024]; uint linelen; uint i=0; uint px=physical_cursorx(); bool phase = true; while (1) { if (!textfile->getline(top_line+cursory+i, 0, line, sizeof line, &linelen, NULL)) return; if (!linelen) { phase = false; } else while (px < linelen) { if (phase ^ ((line[px]>='0' && line[px]<='9') || (line[px]>='A' && line[px]<='Z') || (line[px]>='a' && line[px]<='z') || line[px]=='_')) { phase = !phase; if (phase) { if (sel) select_start(); goto_line(top_line+cursory+i); cursor_pput(px); if (sel) select_end(); dirtyview(); clearmsg(msg); return; } } px++; } phase = false; px = 0; i++; } } case K_Control_Shift_Left: case K_Control_Left: { sel=(k==K_Control_Shift_Left) != selectcursor; char line[1024]; uint linelen; int i=top_line+cursory; uint px=physical_cursorx(); bool phase = true; while (i >= 0) { if (!textfile->getline(i, 0, line, sizeof line, &linelen, NULL)) return; if (px > linelen) px = linelen; while (px > 0) { if (phase ^ !((line[px-1]>='0' && line[px-1]<='9') || (line[px-1]>='A' && line[px-1]<='Z') || (line[px-1]>='a' && line[px-1]<='z') || line[px-1]=='_')) { phase = !phase; if (phase) goto bloed3; } px--; } if (!px && !phase) goto bloed3; px = (uint)-1; i--; } return; bloed3: if (sel) select_start(); goto_line(i); cursor_pput(px); if (sel) select_end(); dirtyview(); clearmsg(msg); return; } case K_Control_J: sendmsg(cmd_text_viewer_goto); clearmsg(msg); return; case K_Up: case K_Shift_Up: sel=(k==K_Shift_Up) != selectcursor; if (sel) select_start(); cursor_up(1); if (sel) select_end(); dirtyview(); clearmsg(msg); return; case K_Down: case K_Shift_Down: sel=(k==K_Shift_Down) != selectcursor; if (sel) select_start(); cursor_down(1); if (sel) select_end(); dirtyview(); clearmsg(msg); return; case K_Left: case K_Shift_Left: sel=(k==K_Shift_Left) != selectcursor; if (sel) select_start(); cursor_left(1); if (sel) select_end(); dirtyview(); clearmsg(msg); return; case K_Right: case K_Shift_Right: sel=(k==K_Shift_Right) != selectcursor; if (sel) select_start(); cursor_right(1); if (sel) select_end(); dirtyview(); clearmsg(msg); return; case K_PageUp: case K_Shift_PageUp: sel=(k==K_Shift_PageUp) != selectcursor; if (sel) select_start(); scroll_up(size.h-1); if (sel) select_end(); dirtyview(); clearmsg(msg); return; case K_PageDown: case K_Shift_PageDown: sel=(k==K_Shift_PageDown) != selectcursor; if (sel) select_start(); scroll_down(size.h-1); if (sel) select_end(); dirtyview(); clearmsg(msg); return; case K_Home: case K_Shift_Home: sel=(k==K_Shift_Home) != selectcursor; if (sel) select_start(); cursor_home(); if (sel) select_end(); dirtyview(); clearmsg(msg); return; case K_End: case K_Shift_End: sel=(k==K_Shift_End) != selectcursor; if (sel) select_start(); cursor_end(); if (sel) select_end(); dirtyview(); clearmsg(msg); return; case K_Control_PageUp: sel=selectcursor; if (sel) select_start(); top_line=0; cursorx=0; cursory=0; if (sel) select_end(); dirtyview(); clearmsg(msg); return; case K_Control_PageDown: sel=selectcursor; if (sel) select_start(); top_line=textfile->linecount()-1; cursory=0; cursor_pput(0); scroll_down(size.h-1); scroll_up(size.h-1); cursor_down(size.h-1); if (sel) select_end(); dirtyview(); clearmsg(msg); return; case K_Meta_C: case K_Control_Insert: sendmsg(cmd_edit_copy); clearmsg(msg); return; case K_Control_L: case K_Shift_F7: if (!continue_search()) infobox("no further matches"); dirtyview(); clearmsg(msg); return; } break; } case cmd_edit_copy: { clipboard_copy_cmd(); clearmsg(msg); return; } case cmd_text_viewer_goto: { char line[1024]; line[0]=0; if (inputbox("goto", "line", line, 1024)) { eval_scalar r; if (eval(&r, line, NULL, NULL, NULL)) { eval_int i; scalar_context_int(&r, &i); if (!i.value || !goto_line(i.value - 1)) { errorbox("no such line: %qd!", i.value); } } } return; } case cmd_text_viewer_change_highlight: { popup_change_highlight(); dirtyview(); clearmsg(msg); return; } case msg_get_pindicator: { msg->data1.integer = get_pindicator_str((char*)msg->data2.ptr, msg->data1.integer); clearmsg(msg); return; } case msg_get_scrollinfo: { switch (msg->data1.integer) { case gsi_hscrollbar: { gsi_scrollbar_t *p=(gsi_scrollbar_t*)msg->data2.ptr; if (!get_hscrollbar_pos(&p->pstart, &p->psize)) { p->pstart = 0; p->psize = 100; } clearmsg(msg); return; } case gsi_vscrollbar: { gsi_scrollbar_t *p=(gsi_scrollbar_t*)msg->data2.ptr; if (!get_vscrollbar_pos(&p->pstart, &p->psize)) { p->pstart = 0; p->psize = 100; } clearmsg(msg); return; } } break; } case msg_funcexec: if (func(msg->data1.integer, 1)) { clearmsg(msg); return; } break; case msg_funcquery: { const char *s=func(msg->data1.integer, 0); if (s) { msg->msg=msg_retval; msg->data1.cstr=s; } break; } } ht_view::handlemsg(msg);}void ht_text_viewer::make_pos_physical(text_viewer_pos *p){ uint l=textfile->getlinelength(p->line); if (p->pofs > l) p->pofs=l;}void ht_text_viewer::normalize_selection(){ if (text_viewer_pos_compare(&sel_end, &sel_start) <= 0) { sel_start.line = 0; sel_start.pofs = 0; sel_end.line = 0; sel_end.pofs = 0; }}uint ht_text_viewer::physical_cursorx(){ int vx=0, px=0, v=cursorx+xofs; char line[1024]; char *linep=line; uint linelen; if (!textfile->getline(top_line+cursory, 0, line, sizeof line, &linelen, NULL)) return 0; while (linelen--) { int k=char_vsize(*(linep++), vx); vx+=k; v-=k; if (v<0) break; px++; } if (v>0) px+=v; return px;}void ht_text_viewer::popup_change_highlight(){ Bounds b, c; app->getbounds(&b); b.x = (b.w - 40) / 2, b.y = (b.h - 8) / 2; b.w = 40; b.h = 8; ht_dialog *d = new ht_dialog(); d->init(&b, "change highlighting mode", FS_KILLER | FS_TITLE | FS_MOVE | FS_RESIZE); b.x = 0; b.y = 0; /* mode (input) */ c = b; c.x = 0; c.y = 1; c.w = b.w-2-c.x; c.h = b.h-2-c.y; ht_itext_listbox *mode_input = new ht_itext_listbox(); mode_input->init(&c); mode_input->insert_str(-1, "no highlighting"); uint lc = lexers->count(); int selected = -1; for (uint i=0; i < lc; i++) { ht_syntax_lexer *l = (ht_syntax_lexer*)(*lexers)[i]; mode_input->insert_str(i, l->getname()); if (lexer && (strcmp(lexer->getname(), l->getname()) == 0)) { selected = i+1; } } mode_input->update(); if (selected >= 0) mode_input->gotoItemByPosition(selected); d->insert(mode_input); /* mode (text) */ c = b; c.x = 0; c.y = 0; c.w = 30; c.h = 1; ht_label *mode_text = new ht_label(); mode_text->init(&c, "choose ~highlighting mode", mode_input); d->insert(mode_text); if (d->run(false)) { ht_listbox_data type; ViewDataBuf vdb(mode_input, &type, sizeof type); ht_syntax_lexer *l = (ht_syntax_lexer*)(*lexers)[ mode_input->getID(type.data->cursor_ptr)]; set_lexer(l, false); } d->done(); delete d;}bool ht_text_viewer::pos_to_offset(text_viewer_pos *pos, FileOfs *ofs){ return textfile->convert_line2ofs(pos->line, pos->pofs, ofs);}int ht_text_viewer::ppos_str(char *buf, uint bufsize, text_viewer_pos *ppos){ return ht_snprintf(buf, bufsize, "some pos");}void ht_text_viewer::render_meta(uint x, uint y, text_viewer_pos *pos, vcp color){ text_viewer_pos p = *pos; render_str_color(&color, &p); if (pos->line == textfile->linecount()-1) { if (show_EOF && EOF_string) buf->print(x, y, color, EOF_string); } else { if (show_EOL && EOL_string) buf->print(x, y, color, EOL_string); }}void ht_text_viewer::render_str(int x, int y, vcp color, text_viewer_pos *pos, uint len, char *str, bool multi){ if ((pos->line == sel_start.line || pos->line == sel_end.line) && text_viewer_pos_compare(&sel_start, &sel_end) != 0) { text_viewer_pos p=*pos; vcp c; while (len--) { c = color; render_str_color(&c, &p); buf_lprint0(x++, y, c, 1, str); str++; if (multi) p.pofs++; } } else { render_str_color(&color, pos); buf_lprint0(x, y, color, len, str); }}int ht_text_viewer::buf_lprint0(int x, int y, int c, int l, char *text){ while (l--) { char s = *text; if (!s) s = ' '; buf->printChar(x++, y, c, s); text++; } return l;}void ht_text_viewer::render_str_color(vcp *color, text_viewer_pos *pos){ if (text_viewer_pos_compare(pos, &sel_start) >= 0 && text_viewer_pos_compare(pos, &sel_end) < 0) { vcp selcolor = getcolor(palidx_generic_input_selected); *color = VCP(*color, selcolor); }}void ht_text_viewer::resize(int rw, int rh){ ht_view::resize(rw, rh); if ((int)cursorx > size.w-1) { xofs += (int)cursorx-(size.w-1); cursorx = size.w-1; } if ((int)cursory > size.h-1) { top_line += (int)cursory-(size.h-1); cursory = size.h-1; }}uint ht_text_viewer::scroll_up(uint n){ if (top_line > n) top_line -= n; else { int q = top_line; top_line = 0; cursory = 0; return q; } return n;}uint ht_text_viewer::scroll_down(uint n){ uint lc=textfile->linecount(); if (top_line+n+size.h <= lc) { top_line += n; } else { if (lc-top_line >= (uint)size.h) { int q = top_line; top_line = lc-size.h; cursory = size.h-1; return top_line-q; } cursory = lc-top_line-1; return 0; } return n;}uint ht_text_viewer::scroll_left(uint n){ if (xofs > n) xofs -= n; else xofs = 0; return n;}uint ht_text_viewer::scroll_right(uint n){ xofs += n; return n;}ht_search_result *ht_text_viewer::search(ht_search_request *request, text_search_pos *s, text_search_pos *e){ if (request != last_search_request) { delete last_search_request; last_search_request = request->clone(); } last_search_end_ofs = e->offset; switch (request->search_class) { case SC_PHYSICAL: { FileOfs start = s->offset, end = e->offset; return linear_bin_search(request, start, end, textfile, 0, 0xffffffff); } } return NULL;}void ht_text_viewer::select_add(text_viewer_pos *s, text_viewer_pos *e){ text_viewer_pos start=*s, end=*e; make_pos_physical(&start); make_pos_physical(&end); bool downward = true; if (text_viewer_pos_compare(&start, &end)>0) { text_viewer_pos temp=start; downward = false; start=end; end=temp; } if ((text_viewer_pos_compare(&end, &sel_end)==0) && !downward) { sel_end=start; } else if ((text_viewer_pos_compare(&start, &sel_end)==0) && downward) { sel_end=end; } else if ((text_viewer_pos_compare(&end, &sel_start)==0) && !downward) { sel_start=start; } else if ((text_viewer_pos_compare(&start, &sel_start)==0) && downward){ sel_start=end; } else { sel_start=start; sel_end=end; } if (text_viewer_pos_compare(&sel_start, &sel_end)>0) { text_viewer_pos temp=sel_start; sel_start=sel_end; sel_end=temp; } normalize_selection();}void ht_text_viewer::select_clear(){ sel_start.line = 0; sel_start.pofs = 0; sel_end.line = 0; sel_end.pofs = 0;}void ht_text_viewer::select_set(text_viewer_pos *s, text_viewer_pos *e){ sel_start = *s; sel_end = *e; normalize_selection();}void ht_text_viewer::select_start(){ selectmode = true; selectstart.line = top_line+cursory; selectstart.pofs = physical_cursorx();}void ht_text_viewer::select_end(){ text_viewer_pos p; selectmode = false; p.line = top_line+cursory; p.pofs = physical_cursorx(); select_add(&selectstart, &p);}void ht_text_viewer::set_lexer(ht_syntax_lexer *l, bool own_l){ if (own_lexer) { lexer->done();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -