     [ hand-rel ] keep point>loc ;
 
 : click-loc ( editor model -- )
-    >r clicked-loc r> set-model ;
-
-: focus-editor ( editor -- ) t >>focused? relayout-1 ;
-
-: unfocus-editor ( editor -- ) f >>focused? relayout-1 ;
+    [ clicked-loc ] dip set-model ;
+
+: blink-caret ( editor -- )
+    [ not ] change-blink relayout-1 ;
+
+: start-blinking ( editor -- )
+    t >>blink
+    dup '[ _ blink-caret ] 750 milliseconds every >>blink-alarm drop ;
+
+: stop-blinking ( editor -- )
+    blink-alarm>> cancel-alarm ;
+
+: restart-blinking ( editor -- )
+    dup focused?>> [
+        [ stop-blinking ]
+        [ start-blinking ]
+        [ relayout-1 ]
+        tri
+    ] [ drop ] if ;
+
+: focus-editor ( editor -- )
+    dup start-blinking
+    t >>focused?
+    relayout-1 ;
+
+: unfocus-editor ( editor -- )
+    dup stop-blinking
+    f >>focused?
+    relayout-1 ;
 
 : (offset>x) ( font col# str -- x )
     swap head-slice string-width ;

    rot control-value <slice> ;

: with-editor-translation ( n quot -- )
    >r line-translation origin get v+ r> with-translation ;
    inline

: draw-lines ( -- )

M: editor gadget-text* editor-string % ;

: extend-selection ( editor -- )
    dup request-focus
    dup restart-blinking
    dup caret>> click-loc ;

: mouse-elt ( -- element )
    hand-click# get {
