Atom: How to complete an Autocomplete Provider

This is the second part of Atom: How to create an Autocomplete Provider

In the previous post we tried to create an Autocomplete Provider for FactoryGirl but we haven’t finished yet, so, let’s go on.

The first problem we want to solve is the filterSuggestions: true that completely removes the suggestions we provide from the autocomplete drop down. In the end it turned out easier than expected, we can just remove the colon : from the text of our suggestions. I have not delve into this but it seems that the colon : is a ignored character by the Autocomplete+ engine (for now we are fine with the text without the : prefix).

  buildCompletion: (factory) ->
-  text: ":#{factory}"
+  text: "#{factory}"
   rightLabel: 'FactoryGirl'

Now we can safely add filterSuggestions to our provider settings and our suggestions will be filtered automatically by the fuzzy finder logic:

module.exports =
   selector: '.source.ruby'
   disableForSelector: 'source.ruby .comment'
+  filterSuggestions: true

The second problem we have to solve is when we open a project that doesn’t have the /spec/factories dir; an ugly red message appears on the right top and informs that the directory is not found.
I searched on google and came across some Stack Overflow questions, in the end the best solution I’ve found is to add a try/catch block. I don’t completely like it but for now it works.

scanFactories: () ->
+    try
       results = []
       factoryPattern = /factory :(w+)/g
       for factory_file in fs.readdirSync("#{@rootDirectory()}#{@factoryDirectory()}")
         data = fs.readFileSync "#{@rootDirectory()}#{@factoryDirectory()}/#{factory_file}", 'utf8'
         while (matches = factoryPattern.exec(data)) != null
            results.push matches[1]
+    catch e

Now we have an autocomplete provider that doesn’t annoy us when we open a project without the /spec/factories. One last change we can do is to limit the suggestions only in the RSpecs files, to do this we simply add .rspec to our selector: property.

module.exports =
+  selector: '.source.ruby.rspec'
   disableForSelector: 'source.ruby .comment'
   filterSuggestions: true

Loading suggestions

There is still a problem, our code loads the suggestions only at the first loading of Atom and if a new factory is added it will not be displayed until we close and reopen the project, not much practical.
To solve this we have to reload our suggestions when a factory definition file is saved, in order to do this we can bind to the save event and reload our suggestions if the file is a factory file:

bindEvents: ->
  atom.workspace.observeTextEditors (editor) =>
    editor.onDidSave (event) =>
      if event.path.includes @factoryDirectory()

With atom.workspace.observeTextEditors we are watching on all editor windows, also if a new one is opened after the start of Atom. For now, we can keep it simple and check if the file saved is under the /spec/factories dir, then, reload the suggestions.

Our autocomplete provider is finally completed! And it is ready to be released to the world! You can found it here

That’s all for now, see you next time!

Leave a Reply