Index: uspace/app/bdsh/compl.c
===================================================================
--- uspace/app/bdsh/compl.c	(revision 5992e0e41989c99660bb58b7c18ba9d5489d4f87)
+++ uspace/app/bdsh/compl.c	(revision e14a1031cc92bf3c52f3afbe8c19cb40e7e3d8ea)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2011 Jiri Svoboda
+ * Copyright (c) 2011 Martin Sucha
  * All rights reserved.
  *
@@ -37,4 +38,5 @@
 #include "compl.h"
 #include "exec.h"
+#include "tok.h"
 
 static int compl_init(wchar_t *text, size_t pos, size_t *cstart, void **state);
@@ -88,5 +90,4 @@
 {
 	compl_t *cs = NULL;
-	size_t p;
 	size_t pref_size;
 	char *stext = NULL;
@@ -96,4 +97,8 @@
 	static const char *dirlist_arg[] = { ".", NULL };
 	int retval;
+	tokenizer_t tok;
+	token_t tokens[WORD_MAX];
+	unsigned int current_token;
+	size_t tokens_length;
 
 	cs = calloc(1, sizeof(compl_t));
@@ -103,21 +108,44 @@
 	}
 
-	/*
-	 * Copy token pointed to by caret from start up to the caret.
-	 * XXX Ideally we would use the standard tokenizer.
-	 */
-	p = pos;
-	while (p > 0 && text[p - 1] != (wchar_t) ' ')
-		--p;
-	*cstart = p;
-
 	/* Convert text buffer to string */
-	stext = wstr_to_astr(text + *cstart);
+	stext = wstr_to_astr(text);
 	if (stext == NULL) {
 		retval = ENOMEM;
 		goto error;
 	}
-
-	/* Extract the prefix being completed */
+	
+	/* Tokenize the input string */
+	retval = tok_init(&tok, stext, tokens, WORD_MAX);
+	if (retval != EOK) {
+		goto error;
+	}
+	
+	retval = tok_tokenize(&tok, &tokens_length);
+	if (retval != EOK) {
+		goto error;
+	}
+	
+	/* Find the current token */
+	for (current_token = 0; current_token < tokens_length; current_token++) {
+		token_t *t = &tokens[current_token];
+		size_t end = t->char_start + t->char_length;
+		/* Check if the caret lies inside the token or immediately
+		 * after it
+		 */
+		if (t->char_start <= pos && pos <= end) {
+			break;
+		}
+	}
+	
+	if (tokens[current_token].type != TOKTYPE_SPACE) {
+		*cstart = tokens[current_token].char_start;
+	}
+	else {
+		*cstart = pos;
+	}
+	
+	/* Extract the prefix being completed
+	 * XXX: handle strings, etc.
+	 */
 	pref_size = str_lsize(stext, pos - *cstart);
 	prefix = malloc(pref_size + 1);
@@ -127,5 +155,6 @@
 	}
 
-	str_ncpy(prefix, pref_size + 1, stext, pref_size);
+	str_ncpy(prefix, pref_size + 1, stext +
+	    tokens[current_token].byte_start, pref_size);
 
 	/*
@@ -133,10 +162,11 @@
 	 * We look at the previous token. If there is none or it is a pipe
 	 * ('|'), it is a command, otherwise it is an argument.
-	 * XXX Again we should use the standard tokenizer/parser.
 	 */
 
 	/* Skip any whitespace before current token */
-	while (p > 0 && text[p - 1] == (wchar_t) ' ')
-		--p;
+	int prev_token = current_token - 1;
+	if (prev_token != -1 && tokens[prev_token].type == TOKTYPE_SPACE) {
+		prev_token--;
+	}
 
 	/*
@@ -144,5 +174,5 @@
 	 * follows a pipe token.
 	 */
-	if (p == 0 || text[p - 1] == '|')
+	if (prev_token == -1 || tokens[prev_token].type == TOKTYPE_SPACE)
 		cs->is_command = true;
 	else
@@ -189,4 +219,6 @@
 
 	cs->prefix_len = str_length(cs->prefix);
+	
+	tok_fini(&tok);
 
 	*state = cs;
@@ -195,4 +227,6 @@
 error:
 	/* Error cleanup */
+	
+	tok_fini(&tok);
 
 	if (cs != NULL && cs->path_list != NULL) {
