Command palette is not focused when starting from script


#1

When the command palette or grammar-selector dropdowns are started from a script, they don’t get keyboard focus and anything typed will go into the document behind the dropdown.

I’m trying to write an ex-mode command to open the grammar-selector dropdown list, which you do in vim with :setf.

In init.coffee:

atom.packages.onDidActivatePackage (pack) ->
    if pack.name == 'ex-mode'
        Ex.registerCommand 'setf', ->
            atom.commands.dispatch(atom.views.getView(atom.workspace), 'grammar-selector:show')

What’s the right way to bring up the grammar selector or command palette from a script? Am I dispatching the command to the right place? The documentation for dispatch is not very helpful.


#2

atom.commands.dispatch is mainly intended for testing. I would double-check to see if the keybinding for the grammar-selector:show command is bound to the workspace or to some other element. Perhaps there is an implicit assumption on where the command will be called.


#3

It’s bound to atom-text-editor. (link)

Modifying my code to dispatch to document.querySelector('atom-text-editor') gives the same result.

The ex-mode input window closes itself at the same time it runs the command. I suspect that breaks the focus somehow.

(If dispatch is for testing, what’s the recommended way to do something like opening the command palette?)


#4

Wrapping the dispatch in a setTimeout resolves the issue, so it probably is an issue with ex-mode closing its UI at the same time it’s doing the dispatch.

Thanks for the help!


#5

I’m facing the same problem with the command advanced-new-file:toggle (Provided by advanced-new-file package.

atom.packages.onDidActivatePackage (pack) ->
  if pack.name == 'ex-mode'
    Ex = pack.mainModule.provideEx()
    Ex.registerCommand 'n', ->
      atom.commands.dispatch(atom.views.getView(atom.workspace),'advanced-new-file:toggle')

I’m not familiar with coffescript, so how to use setTimeout here?

setTimeout atom.commands.dispatch, 1000, atom.views.getView(atom.workspace),'advanced-new-file:toggle'

UPDATE

Ok, I’ve managed to make it work declaring the dispatch in a function apart.

advancedNewFile = () ->
  atomWorkspace = atom.views.getView(atom.workspace)
  atom.commands.dispatch(atomWorkspace,'advanced-new-file:toggle')
atom.packages.onDidActivatePackage (pack) ->
  if pack.name == 'ex-mode'
    Ex = pack.mainModule.provideEx()
    Ex.registerCommand 'n', ->
      setTimeout advancedNewFile, 10

#6

You would do

Ex.registerCommand 'n', ->
  setTimeout ->
    atom.commands.dispatch(...)
  , 1000

However, you probably only want to defer execution of the dispatch until the next frame in the event loop. For that you can use

Ex.registerCommand 'n', ->
  process.nextTick ->
    atom.commands.dispatch(...)

#7

Thanks but none of your methods work.

The 1st one gives me an error (The , in the last statement) and the 2nd one shows me nothing.
By the way, isn’t setTimeout -> the syntax for declaring a function in coffescript? In my case, I want to use the javascript default method setTimeout.

Anyway, I’ve managed to make it work (Check my last message and please tell me if something wrong).


EDIT:

Ok I corrected the indentation in my init.coffee and your first method works now as expected :smiley: (The identation was completely messed up).


#8

The CoffeeScript syntax for declaring a function is just ->.

someFunction = ->
  do stuff
setTimeout ->, 0

would translate to the following javascript:

setTimeout(function() {}, 0);

#9

I got it, thanks.