void set_cursor_rowcol(Text *text, int row, int col) { int r, c; int i; int diff; get_cursor_rowcol(text, &r, &c); diff = abs(r - row); for (i = 0; i < diff; ++i) r > row ? move_up(text) : move_down(text); move_cursor_bol(text); get_cursor_rowcol(text, &r, &c); diff = abs(c - col); for (i = 0; i < diff; ++i) { if (text->buf[text->text_start] != '\n') { if (text->buf[text->text_start] == '\t') diff -= 7; c > col ? move_left(text) : move_right(text); } } }
int get_rowcoloffset_of_chars(Text *text, char *ch, int *row, int *col, int *offset, int forwards) { int r, c; int i, j, mo,bytes, matched, length; r = 0, c = 0; get_cursor_rowcol(text, &r, &c); *offset = 0; length = strlen(ch); if (forwards) { for (i = text->text_start; i + length < text->size; ++i) { matched = 1; for (j = 0; j < length; ++j) { if (text->buf[i + j] != ch[j]) { matched = 0; break; } } if (matched) { goto done; } if (text->buf[i] == '\n') { ++r; c = 0; } else if (text->buf[i] == '\t') { c += 8; } else { bytes = more_bytes_utf8[(unsigned int)(unsigned char)text->buf[i]]; i += bytes; ++c; } ++(*offset); } } else { for (i = ((int)text->gap_start)-1; i >= 0; --i) { matched = 1; mo = 0; for (j = 0; j < length; ++j) { if (i + j == text->gap_start) mo = GAPSIZE(text); if (text->buf[i + j + mo] != ch[j]) { matched = 0; break; } } if (matched) { c = -1; for (; i >= 0; --i) { if (text->buf[i] == '\n') { break; } else if (text->buf[i] == '\t') { c += 8; } else { bytes = more_bytes_utf8[(unsigned int)(unsigned char)text->buf[i]]; i -= bytes; ++c; } } goto done; } if (text->buf[i] == '\n') { --r; } else { bytes = more_bytes_utf8[(unsigned int)(unsigned char)text->buf[i]]; i -= bytes; } ++(*offset); } } return -1; done: *row = r; *col = c; return 0; }
int main(int argc, char *argv[]) { struct arguments arguments; signal(SIGINT, finish); arguments.verbose = 0; arguments.nopy = 0; arguments.files = NULL; arguments.num_files = 0; argp_parse(&argp, argc, argv, 0, 0, &arguments); vx_py_init_python(arguments.num_files, argc, argv); init_curses(); getmaxyx(stdscr, row, col); vx_py_load_start(); clear(); refresh(); get_cursor_rowcol(focused_window->buffer->text, &screen_rows, &screen_cols); vx_py_update_vars(); vx_py_pump(); wmove(focused_window->curses_window, 0, 0); refresh_window(focused_window); clock_t last_tick = clock(); float update_every = .25; while (lets_edit) { if (lets_suspend) { endwin(); raise(SIGSTOP); lets_suspend = 0; refresh(); clear(); nonl(); raw(); noecho(); getmaxyx(stdscr, row, col); vx_py_update_vars(); vx_py_register_resize(); continue; } float delay = update_every - ((float)(clock() - last_tick))/CLOCKS_PER_SEC; timeout(delay*1000); int c = getch(); size_t bytes; int utf8q = 1; /* Handle resize */ if (c == KEY_RESIZE) { endwin(); refresh(); clear(); getmaxyx(stdscr, row, col); vx_py_update_vars(); vx_py_register_resize(); continue; } /* Handle escape and alt */ if (c != ERR) { if (c == '\033') { nodelay(stdscr, 1); c = getch(); if (c == ERR) { // got an escape c = '\033'; } else { // got an alt+key c |= 0x80; utf8q = 0; } nodelay(stdscr, 0); } /* handle utf8 */ bytes = more_bytes_utf8[c]; if (utf8q && bytes > 0) { int i; char *c_utf8 = calloc(1, bytes + 2); c_utf8[0] = c; nodelay(stdscr, 1); for (i = 0; i < bytes; ++i) { c = getch(); c_utf8[i+1] = c; } vx_py_handle_key_utf8(c_utf8); nodelay(stdscr, 0); free(c_utf8); } else { vx_py_handle_key(c); } } get_cursor_rowcol(focused_window->buffer->text, &screen_rows, &screen_cols); while (screen_rows+1 < focused_window->line && focused_window->line > 1) --focused_window->line; while (screen_rows+1 > focused_window->line + focused_window->lines - 1) ++focused_window->line; while (screen_cols < focused_window->column && focused_window->column > 1) --focused_window->column; while (screen_cols > focused_window->column + focused_window->columns - 4) ++focused_window->column; vx_py_update_vars(); vx_py_pump(); wmove(focused_window->curses_window, screen_rows - (focused_window->line - 1), screen_cols - (focused_window->column - 1)); refresh_window(focused_window); last_tick = clock(); } vx_py_deinit_python(); finish(0); }