Finding the path of a resource in Atom Package


#1

Hello! I’ve been learning how to make packages for Atom over the past two days, and I made a small package that inserts user defined “Dummy Text” into the current selection. The way it currently works is by populating a “Select View List” with the contents of a CSON file.

However, I’ve run into a problem when it comes to referencing this file in the package. Here’s a snippet of the code below:

activate: (state) ->
   result = CSON.readFileSync("Path/To/Datafile)
   @placeholderTextView = new PlaceholderTextView(result)

This is taking an array of objects defined in CSON and parsing it with Atom’s Season module. Now I’m not sure if any of this is best practice or a smart way of doing this, but that’s not actually my question.

The problem with this is that I can’t directly reference the file like “’…/data/data.cson’”. Any string passed to readFileSync() is appended to the path where Atom was launched. So the link, if I launched it from the desktop icon, would read “C:/Users/Me/data/data.cson” instead of working off the package directory.

So in the end, the only way I can get it to work is by using atom.project.getPath(), but in THAT case it will only work when the project open in Atom is the package itself.

Now I think I understand why it works like that, since presumably the code isn’t actually running from the package directory, but it leaves me with the problem of being unable to reference or manipulate a datafile that is crucial for my package to work.


###So I guess my question is
How would I reference a resource like this in my package, and if this is the wrong way to go about this, what better alternative do I have for storing and manipulating a set of data (In this case, an array of objects that contain a name and text)?


Should I use those serialization methods? I feel like there should be a straightforward, “Best-practice” way of doing this that I’m missing, because in most cases reading from something like JSON is no big deal.

But regardless, what do I do if I want to use a resource that isn’t coffee or javascript inside an Atom package?

Thanks in advance, I hope somebody understands what I’m getting at. Still new to Atom,Coffeescript, and these kinds of packages, so if I’m way off course please help me out!


#2

I believe atom.packages.getPackageDirPaths() is for what you’re looking:


#3

Well damn, that’s it!

I saw that method before but figured it was used for something else. But as it turns out, “atom.packages.getPackageDirPaths()[0]” gets the true link to the atom package directory. Thanks for the quick answer!


#4

Alternatively, you can use __dirname, which gives you the directory of the file you call it in.

For example, suppose you have the following structure:

C:\Users\MyUser\.atom\packages\my-package
├───lib
│   └───my-package.coffee
├───data
│   └───data.cson
└───package.json

If you call it in my-package.coffee you’ll get C:\Users\MyUser\.atom\packages\my-package\lib, so obtaining your data file is now easy:

path = require 'path'
path.join __dirname, "..", "data", "data.cson"

#5

You can also retrieve a package using atom.packages.getLoadedPackage or atom.packages.getActivePackage. The returned package will have a path property with the path to the package directory.

So with your example, it’ll give:

activate: (state) ->
   path = require 'path' 
   packagePath = atom.packages.getActivePath('my-package').path
   result = CSON.readFileSync(path.join(packagePath, 'path', 'to', 'datafile'))
   @placeholderTextView = new PlaceholderTextView(result)