                 # since we just canceled the change.
                 @remove_cell_flags_from_changeObj(changeObj, ACTION_FLAGS)
                 @_apply_changeObj(changeObj)
-                @sync()
-                @process_sage_updates()
+                @sync () =>
+                    @process_sage_updates()
 
     init_worksheet_buttons: () =>
         buttons = @element.find(".salvus-editor-codemirror-worksheet-buttons")

            @opts.string = diffsync.dmp.patch_apply(p, @string())[0]
        else
            cm = @opts.cm
            s = @string()
            x = diffsync.dmp.patch_apply(p, s)
            new_value = x[0]

            next_pos = (val, pos) ->
                # This functions answers the question:
                # If you were to insert the string val at the CodeMirror position pos
                # in a codemirror document, at what position (in codemirror) would
                # the inserted string end at?
                number_of_newlines = (val.match(/\n/g)||[]).length
                if number_of_newlines == 0
                    return {line:pos.line, ch:pos.ch+val.length}
                else
                    return {line:pos.line+number_of_newlines, ch:(val.length - val.lastIndexOf('\n')-1)}

            pos = {line:0, ch:0}  # start at the beginning
            diff = diffsync.dmp.diff_main(s, new_value)
            for chunk in diff
                #console.log(chunk)
                op  = chunk[0]  # 0 = stay same; -1 = delete; +1 = add
                val = chunk[1] # the actual text to leave same, delete, or add
                pos1 = next_pos(val, pos)
                switch op
                    when 0 # stay the same
                        # Move our pos pointer to the next position
                        pos = pos1
                        #console.log("skipping to ", pos1)
                    when -1 # delete
                        # Delete until where val ends; don't change pos pointer.
                        cm.replaceRange("", pos, pos1)
                        #console.log("deleting from ", pos, " to ", pos1)
                    when +1 # insert
                        # Insert the new text right here.
                        cm.replaceRange(val, pos)
                        #console.log("inserted new text at ", pos)
                        # Move our pointer to just beyond the text we just inserted.
                        pos = pos1


codemirror_diffsync_client = (cm_session, content) ->

            cursor_interval : 1000
            sync_interval   : 750   # never send sync messages up stream more often than this

        @connect    = misc.retry_until_success_wrapper(f:@_connect)#, logname:'connect')
        @sync       = misc.retry_until_success_wrapper(f:@_sync, min_interval:@opts.sync_interval)#, logname:'sync')
        @save       = misc.retry_until_success_wrapper(f:@_save)#, logname:'save')

        @filename    = @editor.filename
        @editor.save = @save
