void screen_move_up(struct te_buffer *buf) { if (buf == NULL) return; int i = 0; int old_x = buf->x; /* move until the first character of the line */ while(prev_char(buf) != '\n') { if(move_left(buf) == ERR) break; } move_left(buf); /* then, move to the beginning of the previous line */ while(prev_char(buf) != '\n') { if(move_left(buf) == ERR) break; } screen_prev_line(buf); buf->x = 0; /* mimic emacs' behaviour of moving the user to the exact offset we were on */ while(buf->x < old_x && next_char(buf) != '\n' && curr_char(buf) != '\n') { if (screen_move_right(buf) == ERR) break; } move(buf->y, buf->x); return; }
int screen_move_right(struct te_buffer *buf) { if (buf == NULL) return ERR; if (move_right(buf) == ERR) /* last char of the document */ return ERR; if (prev_char(buf) == '\n') { screen_next_line(buf); } else { /* tab is the only character larger than 1 */ if (prev_char(buf) == '\t') { buf->x += TAB_LEN; } else { buf->x++; } if(buf->x == COLS - 1) { bstring s = current_line_as_bstring(buf->contents, buf->point); int off = screen_numchar_to_offset(s, COLS - 1); bstring s2 = bmidstr(s, off, blength(s) - off); draw_line(s2, buf->y); bdestroy(s); bdestroy(s2); wmove(buffer_win, buf->y, 0); refresh(); } } move(buf->y, buf->x); return OK; }
void screen_move_down(struct te_buffer *buf) { if (buf == NULL) return; if (buf->point == blength(buf->contents)) return; int i = 0; int old_x = buf->x; do { /* move until the first char of the next line */ if (move_right(buf) == ERR) break; } while (prev_char(buf) != '\n'); screen_next_line(buf); /* mimic emacs' behaviour of moving the user to the exact offset we were on */ while (buf->x < old_x && curr_char(buf) != '\n') { if(screen_move_right(buf) == ERR) return; } move(buf->y, buf->x); return; }
void next () { //Skip whitespace while (curch == ' ' || curch == '\r' || curch == '\n' || curch == '\t') next_char(); //Treat preprocessor lines as line comments if ( curch == '#' || (curch == '/' && (next_char() == '/' || prev_char('/')))) { while (curch != '\n' && !feof(input)) next_char(); //Restart the function (to skip subsequent whitespace, comments and pp) next(); return; } buflength = 0; token = token_other; //Identifier, keyword or integer literal if (isalpha(curch) || isdigit(curch)) { token = isalpha(curch) ? token_ident : token_int; while (token == token_ident ? (isalnum(curch) || curch == '_') && !feof(input) : isdigit(curch) && !feof(input)) eat_char(); //String or character literal } else if (curch == '\'' || curch == '"') { token = curch == '"' ? token_str : token_char; //Can't retrieve this from the buffer - mini-c only has int reads char delimiter = curch; eat_char(); while (curch != delimiter && !feof(input)) { if (curch == '\\') eat_char(); eat_char(); } eat_char(); //Two char operators } else if ( curch == '+' || curch == '-' || curch == '|' || curch == '&' || curch == '=' || curch == '!' || curch == '>' || curch == '<') { eat_char(); if ((curch == buffer[0] && curch != '!') || curch == '=') eat_char(); } else eat_char(); (buffer + buflength++)[0] = 0; }
static char *prev_word(char *p, char *start) { while (p > start && !myisalnum(prev_char(p, start))) p = prev_char(p, start); while (p > start && myisalnum(prev_char(p, start))) p = prev_char(p, start); return p; }
static int ui_input_key(struct input *input) { switch (ui.key) { case KEY_LEFT: if (ui.mod == GLFW_MOD_CONTROL + GLFW_MOD_SHIFT) { input->q = prev_word(input->q, input->text); } else if (ui.mod == GLFW_MOD_CONTROL) { if (input->p != input->q) input->p = input->q = input->p < input->q ? input->p : input->q; else input->p = input->q = prev_word(input->q, input->text); } else if (ui.mod == GLFW_MOD_SHIFT) { if (input->q > input->text) input->q = prev_char(input->q, input->text); } else if (ui.mod == 0) { if (input->p != input->q) input->p = input->q = input->p < input->q ? input->p : input->q; else if (input->q > input->text) input->p = input->q = prev_char(input->q, input->text); } break; case KEY_RIGHT: if (ui.mod == GLFW_MOD_CONTROL + GLFW_MOD_SHIFT) { input->q = next_word(input->q, input->end); } else if (ui.mod == GLFW_MOD_CONTROL) { if (input->p != input->q) input->p = input->q = input->p > input->q ? input->p : input->q; else input->p = input->q = next_word(input->q, input->end); } else if (ui.mod == GLFW_MOD_SHIFT) { if (input->q < input->end) input->q = next_char(input->q); } else if (ui.mod == 0) { if (input->p != input->q) input->p = input->q = input->p > input->q ? input->p : input->q; else if (input->q < input->end) input->p = input->q = next_char(input->q); } break; case KEY_UP: case KEY_HOME: if (ui.mod == GLFW_MOD_CONTROL + GLFW_MOD_SHIFT) { input->q = input->text; } else if (ui.mod == GLFW_MOD_CONTROL) { input->p = input->q = input->text; } else if (ui.mod == GLFW_MOD_SHIFT) { input->q = input->text; } else if (ui.mod == 0) { input->p = input->q = input->text; } break; case KEY_DOWN: case KEY_END: if (ui.mod == GLFW_MOD_CONTROL + GLFW_MOD_SHIFT) { input->q = input->end; } else if (ui.mod == GLFW_MOD_CONTROL) { input->p = input->q = input->end; } else if (ui.mod == GLFW_MOD_SHIFT) { input->q = input->end; } else if (ui.mod == 0) { input->p = input->q = input->end; } break; case KEY_DELETE: if (input->p != input->q) ui_input_delete_selection(input); else if (input->p < input->end) { char *np = next_char(input->p); memmove(input->p, np, input->end - np); input->end -= np - input->p; *input->end = 0; input->q = input->p; } break; case KEY_ESCAPE: return -1; case KEY_ENTER: return 1; case KEY_BACKSPACE: if (input->p != input->q) ui_input_delete_selection(input); else if (input->p > input->text) { char *pp = prev_char(input->p, input->text); memmove(pp, input->p, input->end - input->p); input->end -= input->p - pp; *input->end = 0; input->q = input->p = pp; } break; case KEY_CTL_A: input->p = input->q = input->text; break; case KEY_CTL_E: input->p = input->q = input->end; break; case KEY_CTL_W: if (input->p != input->q) ui_input_delete_selection(input); else { input->p = prev_word(input->p, input->text); ui_input_delete_selection(input); } break; case KEY_CTL_U: input->p = input->q = input->end = input->text; break; case KEY_CTL_C: case KEY_CTL_X: if (input->p != input->q) { char buf[sizeof input->text]; char *p = input->p < input->q ? input->p : input->q; char *q = input->p > input->q ? input->p : input->q; memmove(buf, p, q - p); buf[q-p] = 0; glfwSetClipboardString(window, buf); if (ui.key == KEY_CTL_X) ui_input_delete_selection(input); } break; case KEY_CTL_V: { const char *buf = glfwGetClipboardString(window); if (buf) ui_input_paste(input, buf, (int)strlen(buf)); } break; default: if (ui.key >= 32) { int cat = ucdn_get_general_category(ui.key); if (ui.key == ' ' || (cat >= UCDN_GENERAL_CATEGORY_LL && cat < UCDN_GENERAL_CATEGORY_ZL)) { char buf[8]; int n = fz_runetochar(buf, ui.key); ui_input_paste(input, buf, n); } } break; } return 0; }