                 # 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")

        @project_id = @opts.project_id
        @filename   = @opts.filename

        @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')

        @connect (err) =>
            opts.cb(err, @)

            @opts.string = diffsync.dmp.patch_apply(p, @string())[0]
        else
            cm = @opts.cm
            cm.setOption('readOnly', true)
            try
                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
            catch e
                console.log("BUG in patch_in_place")
            cm.setOption('readOnly', false)



codemirror_diffsync_client = (cm_session, content) ->
