diff --git a/st.c b/st.c
index a6fb766..e1088d4 100644
--- a/st.c
+++ b/st.c
@@ -218,7 +218,7 @@ static void selrequest(XEvent *);
 
 static void selinit(void);
 static inline int selected(int, int);
-static void selcopy(void);
+static void selcopy(int);
 static void selpaste(void);
 
 static int utf8decode(char *, long *);
@@ -252,6 +252,8 @@ static Selection sel;
 static char **opt_cmd  = NULL;
 static char *opt_title = NULL;
 static char *opt_class = NULL;
+static int rlstime = -1;
+static int clikcnt = 0;
 
 int
 utf8decode(char *s, long *u) {
@@ -408,27 +410,68 @@ bpress(XEvent *e) {
 }
 
 void
-selcopy(void) {
+selcopy(int mode) {
 	char *str, *ptr;
-	int x, y, sz, sl, ls = 0;
-
-	if(sel.bx == -1)
-		str = NULL;
-	else {
-		sz = (term.col+1) * (sel.e.y-sel.b.y+1) * UTF_SIZ;
-		ptr = str = malloc(sz);
-		for(y = 0; y < term.row; y++) {
-			for(x = 0; x < term.col; x++)
-				if(term.line[y][x].state & GLYPH_SET && (ls = selected(x, y))) {
-					sl = utf8size(term.line[y][x].c);
-					memcpy(ptr, term.line[y][x].c, sl);
-					ptr += sl;
-				}
-			if(ls && y < sel.e.y)
-				*ptr++ = '\n';
-		}
-		*ptr = 0;
-	}
+	int x, y, sz;
+
+        switch(mode) {
+        case 0:
+	        if(sel.bx == -1)
+	        	str = NULL;
+	        else {
+	        	sz = (term.col+1) * (sel.e.y-sel.b.y+1) * UTF_SIZ;
+	        	ptr = str = malloc(sz);
+	        	for(y = 0; y < term.row; y++) {
+	        		for(x = 0; x < term.col; x++)
+	        			if(term.line[y][x].state & GLYPH_SET && selected(x, y)) {
+	        				memcpy(ptr, term.line[y][x].c, utf8size(term.line[y][x].c));
+	        				ptr += utf8size(term.line[y][x].c);
+	        			}
+	        		if(selected(x, y) && y < sel.e.y)
+	        			*ptr++ = '\n';
+	        	}
+	        	*ptr = 0;
+	        }
+                break;
+        case 1:
+                sel.bx = sel.ex;
+                for (; term.line[sel.ey][sel.bx].state && sel.bx >= 0; sel.bx--) {
+                        if (utf8size(term.line[sel.ey][sel.bx].c) == 1 &&
+                            isspace(term.line[sel.ey][sel.bx].c[0]))
+                                break;
+                }
+                for (; term.line[sel.ey][sel.ex].state && sel.ex <= term.col; sel.ex++) {
+                        if (utf8size(term.line[sel.ey][sel.ex].c) == 1 &&
+                            isspace(term.line[sel.ey][sel.ex].c[0]))
+                                break;
+                }
+                if (++sel.bx > --sel.ex) {
+                    sel.bx = sel.ex = -1;
+                    str = NULL;
+                }
+                ptr = str = (char *)malloc((sel.ex - sel.bx) * UTF_SIZ + 1);
+                for (x = sel.bx; x <= sel.ex; x++) {
+                        memcpy (ptr, term.line[sel.ey][x].c, utf8size(term.line[sel.ey][x].c));
+                        ptr += utf8size(term.line[sel.ey][x].c);
+                }
+                *ptr = 0;
+                break;
+        case 2:
+                sel.bx = 0;
+                sel.ex = term.col;
+
+                ptr = str = (char *)malloc((term.col) * UTF_SIZ + 1);
+                for (x = sel.bx; x <= sel.ex; x++) {
+                        memcpy(ptr, term.line[sel.ey][x].c, utf8size(term.line[sel.ey][x].c));
+                        ptr += utf8size(term.line[sel.ey][x].c);
+                }
+                *ptr = 0;
+                break;
+        default:
+                sel.bx = -1;
+                str = NULL;
+                break;
+        }
 	xsetsel(str);
 }
 
@@ -521,11 +564,18 @@ brelease(XEvent *e) {
 		sel.bx = -1;
 		if(b==2)
 			selpaste();
-	} else {
+                else if(b==1) {
+                        if (e->xbutton.time - rlstime <= 200)
+                                selcopy(++clikcnt);
+                        else
+                                clikcnt = 0;
+                }
+        } else {
 		if(b==1)
-			selcopy();
+			selcopy(0);
 	}
-	draw(1);
+        rlstime = e->xbutton.time; 
+        draw(1);
 }
 
 void
