diff --git a/haskell/readme.md b/haskell/readme.md
--- a/haskell/readme.md
+++ b/haskell/readme.md
@@ -6,14 +6,14 @@
 $ ./test/Example
 ```
 
-See the [API documentation](https://hackage.haskell.org/package/isocline-1.0.0/docs/System-Console-Isocline.html) on hackage.
+See the [API documentation](https://hackage.haskell.org/package/isocline/docs/System-Console-Isocline.html) on hackage.
 
 ## Using with Stack
 
 You can build with isocline by adding 
 ```
 extra-deps:
-  - isocline-1.0.0  
+  - isocline-<version>    
 ```
 to your `stack.yaml` file, and 
 ```
diff --git a/include/isocline.h b/include/isocline.h
--- a/include/isocline.h
+++ b/include/isocline.h
@@ -45,7 +45,7 @@
 /// \{
 
 /// Isocline version: 102 = 1.0.2.
-#define IC_VERSION   (102)  
+#define IC_VERSION   (103)  
 
 
 /// Read input from the user using rich editing abilities.
diff --git a/isocline.cabal b/isocline.cabal
--- a/isocline.cabal
+++ b/isocline.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           isocline
-version:        1.0.2
+version:        1.0.3
 synopsis:       A portable alternative to GNU Readline
 description:    ![logo](https://raw.githubusercontent.com/daanx/isocline/main/doc/isocline-inline.svg) A Haskell wrapper around the [Isocline C library](https://github.com/daanx/isocline#readme) which can provide an alternative to GNU Readline. (The Isocline library is included whole and there are no runtime dependencies).
                 Please see the [readme](https://github.com/daanx/isocline/haskell#readme) on GitHub for more information.
diff --git a/src/completions.c b/src/completions.c
--- a/src/completions.c
+++ b/src/completions.c
@@ -94,12 +94,21 @@
   return cms->count;
 }
 
+static bool completions_contains(completions_t* cms, const char* replacement) {
+  for( ssize_t i = 0; i < cms->count; i++ ) {
+    const completion_t* c = cms->elems + i;
+    if (strcmp(replacement,c->replacement) == 0) { return true; }
+  }
+  return false;
+} 
 
 ic_private bool completions_add(completions_t* cms, const char* replacement, const char* display, const char* help, ssize_t delete_before, ssize_t delete_after) {
   if (cms->completer_max <= 0) return false;
   cms->completer_max--;
   //debug_msg("completion: add: %d,%d, %s\n", delete_before, delete_after, replacement);
-  completions_push(cms, replacement, display, help, delete_before, delete_after);
+  if (!completions_contains(cms,replacement)) {
+    completions_push(cms, replacement, display, help, delete_before, delete_after);
+  }
   return true;
 }
 
diff --git a/src/editline.c b/src/editline.c
--- a/src/editline.c
+++ b/src/editline.c
@@ -997,7 +997,12 @@
         break;
       case KEY_RIGHT:
       case KEY_CTRL_F:
-        edit_cursor_right(env,&eb);
+        if (eb.pos == sbuf_len(eb.input)) { 
+          edit_generate_completions( env, &eb, false );
+        }
+        else {
+          edit_cursor_right(env,&eb);
+        }
         break;
       case KEY_UP:
         edit_cursor_row_up(env,&eb);
@@ -1021,7 +1026,12 @@
       case KEY_CTRL_RIGHT:
       case WITH_SHIFT(KEY_RIGHT):      
       case WITH_ALT('f'):
-        edit_cursor_next_word(env,&eb);
+        if (eb.pos == sbuf_len(eb.input)) { 
+          edit_generate_completions( env, &eb, false );
+        }
+        else {
+          edit_cursor_next_word(env,&eb);
+        }
         break;      
       case KEY_CTRL_HOME:
       case WITH_SHIFT(KEY_HOME):      
