                     if complete.status != 'ok'
                         complete = {error:'completion failed'}
                     delete complete.status
-                complete.args = {code: code, pos:cursor_pos, id:id}
+                complete.base = code
+                complete.code = code
+                complete.pos  = cursor_pos
+                complete.id   = id
                 # Set the result so the UI can then react to the change.
-                if complete?.matches?.length == 0
+                if (complete.matches?.length ? 0) == 0
                     # do nothing -- no completions at all
                     return
                 if offset?

            return
        c                     = String.fromCharCode(keyCode)
        complete              = complete.toJS()  # code is ugly without just doing this - doesn't matter for speed
        code                  = complete.args.code
        pos                   = complete.args.pos
        complete.args.code    = code.slice(0, pos) + c + code.slice(pos)
        complete.cursor_end  += 1
        complete.args.pos    += 1
        target                = complete.args.code.slice(complete.cursor_start, complete.cursor_end)
        complete.matches      = (x for x in complete.matches when misc.startswith(x, target))
        if complete.matches.length == 0
            @clear_complete()
            @set_mode('edit')
        else
            @set_cell_input(complete.args.id, complete.args.code)
            @setState(complete : immutable.fromJS(complete))
        return


{IPynbImporter} = require('./import-from-ipynb')

DEFAULT_KERNEL = 'python2'

syncstring    = require('smc-util/syncstring')

###
The actions -- what you can do with a jupyter notebook, and also the
