     [ 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 ;

    editor-mark* before? ;

: drag-selection-caret ( loc editor element -- loc )
    >r [ drag-direction? ] 2keep
    model>>
    r> prev/next-elt ? ;

: drag-selection-mark ( loc editor element -- loc )
    >r [ drag-direction? not ] 2keep
    nip dup editor-mark* swap model>>
    r> prev/next-elt ? ;

: drag-caret&mark ( editor -- caret mark )
    dup clicked-loc swap mouse-elt

    caret>> set-model ;

: change-caret ( editor quot -- )
    [ [ [ editor-caret* ] [ model>> ] bi ] dip call ] [ drop ] 2bi
    set-caret ; inline

: mark>caret ( editor -- )
    [ editor-caret* ] [ mark>> ] bi set-model ;

: change-caret&mark ( editor quot -- )
    [ change-caret ] [ drop mark>caret ] 2bi ; inline

: editor-line ( n editor -- str ) control-value nth ;

