📄 ttyselect.c
字号:
/* * Make a selection be empty */static voidttysel_empty(ttysel) register struct ttyselection *ttysel;{ ttysel->sel_null = TRUE; ttysel->sel_level = SEL_CHAR; ttysel->sel_begin = tse_null_extent; ttysel->sel_end = tse_null_extent;}/* * Is the specified position within the current selection? */static intttysel_insel(ttysel, tsp) struct ttyselection *ttysel; register struct textselpos *tsp;{ register struct textselpos *tb = &ttysel->sel_begin; register struct textselpos *te = &ttysel->sel_end; if (tsp->tsp_row < tb->tsp_row || tsp->tsp_row > te->tsp_row) return (0); if (tb->tsp_row == te->tsp_row) return (tsp->tsp_col >= tb->tsp_col && tsp->tsp_col <= te->tsp_col); if (tsp->tsp_row == tb->tsp_row) return (tsp->tsp_col >= tb->tsp_col); if (tsp->tsp_row == te->tsp_row) return (tsp->tsp_col <= te->tsp_col); return (1);}static intttysel_eq(t1, t2) register struct textselpos *t1, *t2;{ return (t1->tsp_row == t2->tsp_row && t1->tsp_col == t2->tsp_col);}static voidtvsub(tdiff, t1, t0) register struct timeval *tdiff, *t1, *t0;{ tdiff->tv_sec = t1->tv_sec - t0->tv_sec; tdiff->tv_usec = t1->tv_usec - t0->tv_usec; if (tdiff->tv_usec < 0) tdiff->tv_sec--, tdiff->tv_usec += 1000000;}static voidttyenumerateselection(ttysel, proc, data) struct ttyselection *ttysel; register void (*proc) (); register char *data;{ struct textselpos *xbegin, *xend; register struct textselpos *begin, *end; register int row; if (!ttysel->sel_made || ttysel->sel_null) return; /* * Sort extents */ ttysortextents(ttysel, &xbegin, &xend); begin = xbegin; end = xend; /* * Process a line at a time */ for (row = begin->tsp_row; row <= end->tsp_row; row++) { if (row == begin->tsp_row && row == end->tsp_row) { /* * Partial line hilite in middle */ proc(begin->tsp_col, end->tsp_col, row, data); } else if (row == begin->tsp_row) { /* * Partial line hilite from beginning */ proc(begin->tsp_col, length(image[row]), row, data); } else if (row == end->tsp_row) { /* * Partial line hilite not to end */ proc(0, end->tsp_col, row, data); } else { /* * Full line hilite */ proc(0, length(image[row]), row, data); } }}static voidttyhiliteline(start, finish, row, offsets) int start, finish, row; struct pr_size *offsets;{ struct rect r; rect_construct(&r, col_to_x(start), row_to_y(row) + offsets->x, col_to_x(finish + 1) - col_to_x(start), offsets->y); if (r.r_width == 0) return; (void)pselectionhilite(&r);}static voidttysel_resolve(tb, te, level, event) register struct textselpos *tb, *te; int level; struct inputevent *event;{ register unsigned char *line; tb->tsp_row = y_to_row(event->ie_locy); if (tb->tsp_row >= bottom) tb->tsp_row = max(0, bottom - 1); line = image[tb->tsp_row]; tb->tsp_col = x_to_col(event->ie_locx); if (tb->tsp_col > length(line)) tb->tsp_col = length(line); *te = *tb; switch (level) { case SEL_CHAR: break; case SEL_WORD:{ register int col, chr; for (col = te->tsp_col; col < length(line); col++) { chr = line[col]; if (!isalnum(chr) && chr != '_') break; } te->tsp_col = max(col - 1, tb->tsp_col); for (col = tb->tsp_col; col >= 0; col--) { chr = line[col]; if (!isalnum(chr) && chr != '_') break; } tb->tsp_col = min(col + 1, te->tsp_col); break; } case SEL_LINE: tb->tsp_col = 0; te->tsp_col = length(line) - 1; break; case SEL_PARA:{ register int row; for (row = tb->tsp_row; row >= top; row--) if (length(image[row]) == 0) break; tb->tsp_row = min(tb->tsp_row, row + 1); tb->tsp_col = 0; for (row = te->tsp_row; row < bottom; row++) if (length(image[row]) == 0) break; te->tsp_row = max(te->tsp_row, row - 1); te->tsp_col = length(image[te->tsp_row]); break; } }}static voidttysortextents(ttysel, begin, end) register struct ttyselection *ttysel; struct textselpos **begin, **end;{ if (ttysel->sel_begin.tsp_row == ttysel->sel_end.tsp_row) { if (ttysel->sel_begin.tsp_col > ttysel->sel_end.tsp_col) { *begin = &ttysel->sel_end; *end = &ttysel->sel_begin; } else { *begin = &ttysel->sel_begin; *end = &ttysel->sel_end; } } else if (ttysel->sel_begin.tsp_row > ttysel->sel_end.tsp_row) { *begin = &ttysel->sel_end; *end = &ttysel->sel_begin; } else { *begin = &ttysel->sel_begin; *end = &ttysel->sel_end; }}static voidttycountchars(start, finish, row, count) register int start, finish, row, *count;{ *count += finish + 1 - start; if (length(image[row]) == finish && finish == right) { *count -= 1; /* no CR on wrapped lines */ }}/* ARGSUSED */static voidttysel_write(sel, file) struct selection *sel; FILE *file;{ ttyenumerateselection(ttysel_ttysel, ttyputline, (char *)(file));}#ifdef lint#undef putc#define putc(_char, _file) \ _file = (FILE *)(_file ? _file : 0)#endif lintstatic voidttyputline(start, finish, row, file) int start; register int finish; register int row; register FILE *file;{ register int col; finish++; for (col = start; col < finish; col++) { if (length(image[row]) == col) { /* * For full width lines, don't put in CR so can grab command lines * that wrap. */ if (col != right) { putc('\n', file); } } else { putc(*(image[row] + col), file); } }}static voidttysel_read(sel, file) struct selection *sel; register FILE *file;{ register int buf; char c; if (sel->sel_type != SELTYPE_CHAR || sel->sel_itembytes != 1) return; while ((buf = getc(file)) != EOF) { c = buf; /* goddamn possibly-signed characters! */ (void) ttysw_input((caddr_t)ttysel_ttysw, &c, 1); } (void)ttysw_reset_conditions(ttysel_ttysw);}/* * Do_function: respond to notification that a function key went up */static voidttysel_function(ttysw, buffer) register struct ttysubwindow *ttysw; register Seln_function_buffer *buffer;{ Seln_response response; Seln_holder *holder; response = seln_figure_response(buffer, &holder); switch (response) { case SELN_IGNORE: return; case SELN_DELETE: case SELN_FIND: break; case SELN_REQUEST: if (ttysw->ttysw_seln_client == (char *) NULL) { ttygetselection(ttysw); } else { (void)ttysel_get_selection(ttysw, holder); } if (holder->rank == SELN_SECONDARY) { ttysel_end_request(ttysw, holder, SELN_SECONDARY); } break; case SELN_SHELVE: { FILE *held_file; struct ttyselection *ttysel; ttysel = ttysel_from_rank(ttysw, SELN_PRIMARY); if (!ttysel->sel_made) { return; } if ((held_file = fopen(ttysel_filename, "w")) == (FILE *) NULL) { return; } (void) fchmod (fileno(held_file), 00666); /* Allowing world to read and write */ ttyenumerateselection(ttysel, ttyputline, (char *)(held_file)); (void)fclose(held_file); (void)seln_hold_file(SELN_SHELF, ttysel_filename); break; } default: (void) fprintf(stderr, "ttysw didn't recognize function to perform on selection\n"); break; } ttysel_resynch(ttysw, buffer); if (buffer->addressee_rank == SELN_SECONDARY) { (void)ttysel_cancel(ttysw, buffer->addressee_rank); }}ttysel_get_selection(ttysw, holder) Ttysw *ttysw; Seln_holder *holder;{ struct ttysel_context context; context.continued = FALSE; context.ttysw = ttysw; (void) seln_query(holder, ttysel_copy_in, (char *)(LINT_CAST(&context)), SELN_REQ_BYTESIZE, 0, SELN_REQ_CONTENTS_ASCII, 0, 0);}/* * Do the action for "Put, then Get" menu item. */voidttysw_do_put_get(ttysw) register Ttysw *ttysw;{ Seln_holder holder; Seln_function_buffer buffer; /* * if there is a nonzero length primary selection, * do put_then_get: * copy the primary selection to the tty cursor, * then fake Put down, up. * NOTE: can't Put, then Get from shelf because of **race** * else * do get_only: * copy the shelf to the tty cursor. */ if (ttysw_is_seln_nonzero(ttysw, SELN_PRIMARY)) { holder = seln_inquire(SELN_PRIMARY); (void)ttysel_get_selection(ttysw, &holder); (void)seln_inform(ttysw->ttysw_seln_client, SELN_FN_PUT, TRUE); buffer = seln_inform(ttysw->ttysw_seln_client, SELN_FN_PUT, FALSE); if (buffer.function != SELN_FN_ERROR && ttysw->ttysw_seln_client != NULL) { ttysel_function(ttysw, &buffer); } } else if (ttysw_is_seln_nonzero(ttysw, SELN_SHELF)) { holder = seln_inquire(SELN_SHELF); (void)ttysel_get_selection(ttysw, &holder); }}/* * Reply: respond to a request sent from another process */static Seln_resultttysel_reply(request, context, buffer_length) Seln_attribute request; register Seln_replier_data *context; int buffer_length;{ unsigned count; struct ttysubwindow *ttysw; struct ttyselection *ttysel; ttysw = (struct ttysubwindow *)LINT_CAST(context->client_data); ttysel = ttysel_from_rank(ttysw, context->rank); if (!ttysel->sel_made) { return SELN_DIDNT_HAVE; } switch (request) { case SELN_REQ_BYTESIZE: if (buffer_length < sizeof (char **)) { return SELN_FAILED; } count = 0; if (!ttysel->sel_null) { ttyenumerateselection(ttysel, ttycountchars, (char *)(&count)); } *context->response_pointer++ = (char *) count; return SELN_SUCCESS; case SELN_REQ_CONTENTS_ASCII: if (ttysel->sel_null) { *context->response_pointer++ = (char *) 0; return SELN_SUCCESS; } return ttysel_copy_out(ttysel, context, buffer_length); case SELN_REQ_YIELD: if (buffer_length < sizeof (char **)) { return SELN_FAILED; } if (!ttysel->sel_made) { *context->response_pointer++ = (char *) SELN_DIDNT_HAVE; } else { (void)ttysel_cancel(ttysw, context->rank); *context->response_pointer++ = (char *) SELN_SUCCESS; } return SELN_SUCCESS; default: return SELN_UNRECOGNIZED; }}/* * Send_deselect: tell another process to deselect */static voidttysel_end_request(ttysw, addressee, rank) struct ttysubwindow *ttysw; Seln_holder *addressee; Seln_rank rank;{ Seln_request buffer; if (seln_holder_same_client(addressee, (char *)ttysw)) { (void)ttysel_cancel(ttysw, rank); return; } seln_init_request(&buffer, addressee, SELN_REQ_COMMIT_PENDING_DELETE, SELN_REQ_YIELD, 0, 0); (void) seln_request(addressee, &buffer);}static Seln_resultttysel_copy_out(ttysel, context, max_length) register struct ttyselection *ttysel; register Seln_replier_data *context; register int max_length;{ register int curr_col, curr_row, index, row_len; register unsigned char *dest, *src; int start_col, end_col, last_row; if (context->context != (char *) NULL) { ttysel = (struct ttyselection *) LINT_CAST(context->context); } start_col = ttysel->sel_begin.tsp_col; end_col = ttysel->sel_end.tsp_col; last_row = ttysel->sel_end.tsp_row; dest = (unsigned char *) context->response_pointer; curr_col = start_col; curr_row = ttysel->sel_begin.tsp_row; while (curr_row < last_row) { row_len = min(length(image[curr_row]) - curr_col, max_length); index = row_len; src = image[curr_row] + curr_col; while (index--) { *dest++ = *src++; } if ((max_length -= row_len) <= 0) { goto continue_reply; } if (row_len + curr_col != right) { *dest++ = '\n'; max_length--; } curr_col = 0; curr_row += 1; } row_len = min(end_col + 1 - curr_col, max_length); index = row_len; src = image[curr_row] + curr_col; while (index--) { *dest++ = *src++; } if ((max_length -= row_len) <= 0) { goto continue_reply; } if (end_col == length(image[curr_row]) && end_col < right) { dest[-1] = '\n'; *dest = '\0'; max_length--; } /* round up to word boundary */ while ((unsigned) dest % 4 != 0) { *dest++ = '\0'; } context->response_pointer = (char **) LINT_CAST(dest); *context->response_pointer++ = 0; if (context->context != (char *) NULL) { free(context->context); } return SELN_SUCCESS;continue_reply: { register struct ttyselection *ttysel2; if (context->context == (char *) NULL) { ttysel2 = (struct ttyselection *) LINT_CAST(malloc(sizeof(struct ttyselection))); if (ttysel2 == (struct ttyselection *) NULL) { (void) fprintf(stderr, "malloc failed for selection copy-out"); return SELN_FAILED; } *ttysel2 = *ttysel; } else { ttysel2 = (struct ttyselection *) LINT_CAST(context->context); } ttysel2->sel_begin.tsp_row = curr_row; ttysel2->sel_begin.tsp_col = curr_col + row_len; ttysel2->sel_end.tsp_row = last_row; ttysel2->sel_end.tsp_col = end_col; context->context = (char *) ttysel2; context->response_pointer = (char **) LINT_CAST(dest); return SELN_CONTINUED; }}static Seln_resultttysel_copy_in(buffer) register Seln_request *buffer;{ register Seln_attribute *response_ptr; register struct ttysel_context *context; struct ttysubwindow *ttysw; register int current_size; if (buffer == (Seln_request *) NULL) { return SELN_UNRECOGNIZED; } context = (struct ttysel_context *) LINT_CAST(buffer->requester.context); ttysw = context->ttysw; response_ptr = (Seln_attribute *) LINT_CAST(buffer->data); if (!context->continued) { if (*response_ptr++ != SELN_REQ_BYTESIZE) { return SELN_FAILED; } context->bytes_left = (int) *response_ptr++; current_size = min(context->bytes_left, buffer->buf_size - 3 * sizeof (Seln_attribute)); if (*response_ptr++ != SELN_REQ_CONTENTS_ASCII) { return SELN_FAILED; } } else { current_size = min(context->bytes_left, buffer->buf_size); } (void) ttysw_input((caddr_t)ttysw, (char *) response_ptr, current_size); (void)ttysw_reset_conditions(ttysw); if (buffer->status == SELN_CONTINUED) { context->continued = TRUE; context->bytes_left -= current_size; } return SELN_SUCCESS;}staticttysel_resynch(ttysw, buffer) register struct ttysubwindow *ttysw; register Seln_function_buffer *buffer;{ if (ttysw->ttysw_caret.sel_made && !seln_holder_same_client(&buffer->caret, (char *)ttysw)) { ttysel_deselect(&ttysw->ttysw_caret, SELN_CARET); ttysw->ttysw_caret.sel_made = FALSE; } if (ttysw->ttysw_primary.sel_made && !seln_holder_same_client(&buffer->primary, (char *)ttysw)) { ttysel_deselect(&ttysw->ttysw_primary, SELN_PRIMARY); ttysw->ttysw_primary.sel_made = FALSE; } if (ttysw->ttysw_secondary.sel_made && !seln_holder_same_client(&buffer->secondary, (char *)ttysw)) { ttysel_deselect(&ttysw->ttysw_secondary, SELN_SECONDARY); ttysw->ttysw_secondary.sel_made = FALSE; } if (ttysw->ttysw_shelf.sel_made && !seln_holder_same_client(&buffer->shelf, (char *)ttysw)) { ttysel_deselect(&ttysw->ttysw_shelf, SELN_SHELF); ttysw->ttysw_shelf.sel_made = FALSE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -