int operyank(int f, int n) { MARK savedot; REGION region; int s; savedot = DOT; opcmd = OPDEL; wantregion = ®ion; s = vile_op(f, n, yankregion, "Yank"); wantregion = 0; /* * If the associated motion was to the left, or up, we want to set DOT to * the beginning of the region, to match vi's behavior. Otherwise leave * DOT where it is. */ if (s == TRUE && b_val(curbp, MDYANKMOTION)) { if (line_no(curbp, post_op_dot.l) != 0 && line_no(curbp, post_op_dot.l) < line_no(curbp, savedot.l)) { savedot = post_op_dot; } else if (!samepoint(region.r_orig, region.r_end)) { if (sameline(region.r_orig, savedot) && sameline(region.r_end, savedot) && region.r_orig.o < savedot.o) { savedot = region.r_orig; } } } DOT = savedot; return s; }
static int show_mark(int count, BUFFER *bp, MARK mark, int name) { static int tab = 8; /* no b_val(bp,VAL_TAB) -- set_rdonly uses 8 */ static int stop; if (!samepoint(mark, nullmark)) { if (!count) { bprintf("\nMark Line Column"); if (stop == 0) { stop = ((DOT.o + tab - 1) / tab) * tab; } bpadc(' ', stop - DOT.o); bprintf("Text"); bprintf("\n---- -------- ------"); bpadc(' ', stop - DOT.o); bprintf("----"); } bprintf("\n%c %8d %8d", name, line_no(bp, mark.l), mk_to_vcol(curwp, mark, FALSE, 0, 0) + 1); if (llength(mark.l) > 0) { bpadc(' ', stop - DOT.o); bputsn(lvalue(mark.l), llength(mark.l)); } return 1; } return 0; }
/* * Go to the beginning of the current sentence. If we skip into an empty line * (from a non-empty line), return at that point -- that's what vi does. */ int gotobosent(int f, int n) { MARK savepos; int looped = 0; int extra; int empty = is_empty_line(DOT); regexp *exp; int s = TRUE; savepos = DOT; exp = b_val_rexp(curbp, VAL_SENTENCES)->reg; while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot()))) { s = backchar(TRUE, 1); if (is_empty_line(DOT) && !empty) return TRUE; } top: extra = 0; if (findpat(f, n, exp, REVERSE) != TRUE) { return gotobob(f, n); } s = forwchar(TRUE, RegexpLen(exp)); while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot()))) { s = forwchar(TRUE, 1); extra++; } if (n == 1 && samepoint(savepos, DOT)) { /* try again */ if (looped > 10) return FALSE; s = backchar(TRUE, RegexpLen(exp) + extra + looped); while (s && is_at_end_of_line(DOT)) { if (!empty && is_empty_line(DOT)) return TRUE; s = backchar(TRUE, 1); } looped++; goto top; } return TRUE; }
/* extra args -- marking if called from globals, and should mark lines, and fromscreen, if the searchpattern is on the screen, so we don't need to ask for it. */ int fsearch(int f, int n, int marking, int fromscreen) { int status = TRUE; int wrapok; MARK curpos; int didmark = FALSE; int didwrap; assert(curwp != 0); if (f && n < 0) return rsearch(f, -n, FALSE, FALSE); if (n == 0) n = 1; wrapok = marking || window_b_val(curwp, MDWRAPSCAN); last_srch_direc = FORWARD; /* ask the user for a regular expression to search for. if * "marking", then we were called to do line marking for the * global command. */ if (!marking) { status = readpattern("Search: ", &searchpat, &gregexp, lastkey, fromscreen); if (status != TRUE) return status; } ignorecase = window_b_val(curwp, MDIGNCASE); if (curwp == 0) return FALSE; curpos = DOT; scanboundry(wrapok, curpos, FORWARD); didwrap = FALSE; while (marking || n--) { movenext(&(DOT), FORWARD); status = scanner(gregexp, FORWARD, wrapok, &didwrap); if (status == ABORT) { mlwarn("[Aborted]"); DOT = curpos; return status; } /* if found, mark the line */ if (status && marking) { /* if we were on a match when we started, then scanner returns TRUE, even though it's on a boundary. quit if we find ourselves marking a line twice */ if (lismarked(DOT.l)) break; lsetmarked(DOT.l); /* and, so the next movenext gets to next line */ DOT.o = llength(DOT.l); didmark = TRUE; } if (!marking && didwrap) { mlwrite("[Search wrapped past end of buffer]"); didwrap = FALSE; } if (status != TRUE) break; } if (!marking && !status) movenext(&(DOT), REVERSE); if (marking) { /* restore dot and offset */ DOT = curpos; } else if (status) { savematch(DOT, gregexp->mlen); if (samepoint(DOT, curpos)) { mlwrite(onlyonemsg); } } /* Complain if not there. */ if ((marking && didmark == FALSE) || (!marking && status == FALSE)) { not_found_msg(wrapok, FORWARD); return FALSE; } attrib_matches(); return TRUE; }
/* * backhunt -- repeat previous forward search */ int backhunt(int f, int n) { int status = TRUE; int wrapok; MARK curpos; int didwrap; assert(curwp != 0); wrapok = window_b_val(curwp, MDWRAPSCAN); if (f && n < 0) /* search forwards */ return (forwhunt(f, -n)); if (n == 0) n = 1; /* Make sure a pattern exists */ if (tb_length(searchpat) == 0) { mlforce("[No pattern set]"); return FALSE; } ignorecase = window_b_val(curwp, MDIGNCASE); if (curwp == 0) return FALSE; /* find n'th occurrence of pattern */ curpos = DOT; scanboundry(wrapok, DOT, REVERSE); didwrap = FALSE; while (n--) { movenext(&(DOT), REVERSE); status = scanner(gregexp, REVERSE, wrapok, &didwrap); if (didwrap) { mlwrite("[Search wrapped past start of buffer]"); didwrap = FALSE; } if (status != TRUE) break; } if (status == TRUE) { savematch(DOT, gregexp->mlen); if (samepoint(DOT, curpos)) { mlwrite(onlyonemsg); } } else if (status == FALSE) { movenext(&(DOT), FORWARD); not_found_msg(wrapok, REVERSE); } else if (status == ABORT) { mlwarn("[Aborted]"); DOT = curpos; return status; } attrib_matches(); return status; }
/* ARGSUSED */ static int rsearch(int f, int n, int dummy GCC_UNUSED, int fromscreen) { int status; int wrapok; MARK curpos; int didwrap; assert(curwp != 0); if (f && n < 0) /* reverse direction */ return fsearch(f, -n, FALSE, fromscreen); if (n == 0) n = 1; wrapok = window_b_val(curwp, MDWRAPSCAN); last_srch_direc = REVERSE; /* ask the user for the regular expression to search for, and * find n'th occurrence. */ status = readpattern("Reverse search: ", &searchpat, &gregexp, EOS, fromscreen); if (status != TRUE) return status; ignorecase = window_b_val(curwp, MDIGNCASE); if (curwp == 0) return FALSE; curpos = DOT; scanboundry(wrapok, DOT, REVERSE); didwrap = FALSE; while (n--) { movenext(&(DOT), REVERSE); status = scanner(gregexp, REVERSE, wrapok, &didwrap); if (didwrap) { mlwrite( "[Search wrapped past start of buffer]"); didwrap = FALSE; } if (status != TRUE) break; } if (status == TRUE) { savematch(DOT, gregexp->mlen); if (samepoint(DOT, curpos)) { mlwrite(onlyonemsg); } } else if (status == FALSE) { movenext(&(DOT), FORWARD); not_found_msg(wrapok, REVERSE); } else if (status == ABORT) { mlwarn("[Aborted]"); DOT = curpos; return status; } attrib_matches(); return status; }
/* Extend the current selection to dot */ int sel_extend(int wiping, int include_dot) { BUFFER *bp = curbp; REGIONSHAPE save_shape = regionshape; REGION a, b; MARK saved_dot; MARK working_dot; saved_dot = DOT; if (valid_buffer(startbufp)) { detach_attrib(selbufp, &selregion); selbufp = startbufp; selregion = startregion; attach_attrib(selbufp, &selregion); detach_attrib(startbufp, &startregion); startbufp = NULL; } if (curwp->w_bufp != selbufp) return FALSE; /* handles NULL case also */ fix_dot(); regionshape = selregion.ar_shape; if (wiping && whichend == END_FIXED) MK = selregion.ar_region.r_end; else MK = selregion.ar_region.r_orig; /* FIXME: Make sure DOT and MK are in the same buffer */ /* * If we're extending in the positive direction, we want to include DOT * in the selection. To include DOT, we must advance it one char since * a region runs from r_orig up to but not including r_end. */ working_dot = DOT; if (include_dot && (selregion.ar_shape == rgn_EXACT) && dot_vs_mark() >= 0) { if (samepoint(MK, orig_region)) { DOT.o += BytesAt(DOT.l, DOT.o); } else if (samepoint(MK, plus_region)) { DOT.o += BytesAt(DOT.l, DOT.o); MK = orig_region; } } if (getregion(bp, &a) == FALSE) { return FALSE; } DOT = working_dot; /* * Build a second region in the "opposite" direction. */ if (wiping && whichend == ORIG_FIXED) MK = selregion.ar_region.r_orig; else MK = selregion.ar_region.r_end; if (include_dot) { if (selregion.ar_shape == rgn_EXACT) { if (dot_vs_mark() <= 0) { if (samepoint(MK, orig_region)) MK.o += BytesAt(MK.l, MK.o); } } else if (selregion.ar_shape == rgn_RECTANGLE) { if (samepoint(MK, DOT)) { /* avoid making empty-region */ MK = orig_region; DOT = plus_region; } } } if (getregion(bp, &b) == FALSE) { return FALSE; } /* * The two regions, 'a' and 'b' are _usually_ identical, except for the * special case where we've extended one to the right to include the * right endpoint of the region. * * For rgn_EXACT selections, setting 'whichend' to ORIG_FIXED means that * we're selecting from the anchor point right/down. Conversely, * setting it to END_FIXED means that we selecting left/up. * * Rectangles are specified by making MK the opposite corner from DOT. * If DOT is below MK, we'll say that the selection region is * ORIG_FIXED so that the next call on this function will build the * regions a/b consistently. * * If the regions a/b are empty, we've made a mistake; this will cause * the selection to be dropped in xvile. */ if (a.r_size > b.r_size) { whichend = ORIG_FIXED; selregion.ar_region = a; } else { if (selregion.ar_shape == rgn_RECTANGLE) { if (dot_vs_mark() < 0) whichend = END_FIXED; else whichend = ORIG_FIXED; } else { /* exact or full-line */ whichend = END_FIXED; } selregion.ar_region = b; } selregion.ar_vattr = VASEL | VOWN_SELECT; mark_buffers_windows(selbufp); show_selection_position(FALSE); regionshape = save_shape; DOT = saved_dot; OWN_SELECTION(); return TRUE; }
int MeshEdgeElementTable::calcLineIntersections(int elem_index, short elem_dir, Point3& lstart, Point3& ldir, Point3* isec_points) { meshElementCode elem_code = getElementCode(elem_index); if (elem_code < MEC_202 || elem_code >= 303) return 0; const int* nodeIds = getNodeIds(elem_index, elem_dir); Point3& p0 = meshNodes[nodeIds[0]]; Point3& p1 = meshNodes[nodeIds[1]]; Point3& normal = normals[elem_index]; if (elem_dir == -1) scalarmult(-1, normal, normal); // Check end-point cases if ( samepoint(p0, lstart) ){ copy3(p0, *isec_points); return 1; } if ( samepoint(p1, lstart) ){ copy3(p1, *isec_points); return 1; } Point3 edge_dir, l_delta0, tmp; // Edge direction vector (normalized) edge_dir[0] = normal[1]; edge_dir[1] = -1 * normal[0]; edge_dir[2] = 0.0; // Edge length diff3(p1, p0, tmp); double edge_len = dot3(edge_dir, tmp); // Vector l_delta0 = lstart - p0 diff3(lstart, p0, l_delta0); // Check that intersection is "within" the edge // project the intersection point to the edge double t = dot3(edge_dir, l_delta0); if ( isLess(t, 0.0) || isGreater(t, edge_len) ) return 0; // Check that intersection distance from the edge is ok // project intersection point to the edge normal double d = dot3(normal, l_delta0); if (d < 0) d *= -1; if ( isGreater(d, MeshEdgeElementTable::pickingTolerance) ) return 0; // Intersection point is: p0 + t * (p1 - p0) scalarmult(t, edge_dir, tmp); add3(p0, tmp, *isec_points); return 1; }