- return ((sel.b.y < y && y < sel.e.y)
- || (y == sel.e.y && x <= sel.e.x))
- || (y == sel.b.y && x >= sel.b.x
- && (x <= sel.e.x || sel.b.y != sel.e.y));
+ return ((sel.nb.y < y && y < sel.ne.y)
+ || (y == sel.ne.y && x <= sel.ne.x))
+ || (y == sel.nb.y && x >= sel.nb.x
+ && (x <= sel.ne.x || sel.nb.y != sel.ne.y));
+}
+
+void
+selsnap(int mode, int *x, int *y, int direction) {
+ int i;
+
+ switch(mode) {
+ case SNAP_WORD:
+ /*
+ * Snap around if the word wraps around at the end or
+ * beginning of a line.
+ */
+ for(;;) {
+ if(direction < 0 && *x <= 0) {
+ if(*y > 0 && term.line[*y - 1][term.col-1].mode
+ & ATTR_WRAP) {
+ *y -= 1;
+ *x = term.col-1;
+ } else {
+ break;
+ }
+ }
+ if(direction > 0 && *x >= term.col-1) {
+ if(*y < term.row-1 && term.line[*y][*x].mode
+ & ATTR_WRAP) {
+ *y += 1;
+ *x = 0;
+ } else {
+ break;
+ }
+ }
+
+ if(term.line[*y][*x+direction].mode & ATTR_WDUMMY) {
+ *x += direction;
+ continue;
+ }
+
+ if(strchr(worddelimiters,
+ term.line[*y][*x+direction].c[0])) {
+ break;
+ }
+
+ *x += direction;
+ }
+ break;
+ case SNAP_LINE:
+ /*
+ * Snap around if the the previous line or the current one
+ * has set ATTR_WRAP at its end. Then the whole next or
+ * previous line will be selected.
+ */
+ *x = (direction < 0) ? 0 : term.col - 1;
+ if(direction < 0 && *y > 0) {
+ for(; *y > 0; *y += direction) {
+ if(!(term.line[*y-1][term.col-1].mode
+ & ATTR_WRAP)) {
+ break;
+ }
+ }
+ } else if(direction > 0 && *y < term.row-1) {
+ for(; *y < term.row; *y += direction) {
+ if(!(term.line[*y][term.col-1].mode
+ & ATTR_WRAP)) {
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ /*
+ * Select the whole line when the end of line is reached.
+ */
+ if(direction > 0) {
+ i = term.col;
+ while(--i > 0 && term.line[*y][i].c[0] == ' ')
+ /* nothing */;
+ if(i > 0 && i < *x)
+ *x = term.col - 1;
+ }
+ break;
+ }