Sublime Forum

[SOLVED] Issue getting absolute path from "sublime.find_resources"

#1

I’m working on a plugin that will dynamically add completions from any json file with a .custom-completions extension.
( implementation will be similar to the *_completions.py plugins )

The issue I’m running into is that I need to get the absolute path of the custom-completions files.

I’m attempting to use sublime.find_resources to find all custom-completions.  Once they’re found, I need to convert them from relative to absolute paths so that I can run them through the json module.
 



 
Here is the code I have so far:

import sublime
from os import path

customCompletion_Files = sublime.find_resources ( "*.custom-completions" )

file = path.abspath ( customCompletion_Files[0] )

print ( file )

 

The actual file I’m testing is:

Relative ( returned by "sublime.find_resources" ):
Packages\CustomCompletions\Completion Files\CSS.custom-completions

Absolute:
C:\Users\Fico\AppData\Roaming\Sublime Text 3\Packages\CustomCompletions\Completion Files\CSS.custom-completions

 

Currently, print is returning the relative path appended to some arbitrary directory:

C:\_GIT\ST_SlideNav\Packages\CustomCompletions\Completion Files\CSS.custom-completions

 

If I reload SublimeText, the issue is persistent but the arbitrary directory will change.

Any ideas?

0 Likes

#2

I found a workaround; but if anyone knows a solution to the original issue, please post it!   Might come in handy one day :slightly_smiling:

I was able to use sublime.load_resource since yaml.load accepts strings.

import sublime
import yaml

customCompletion_Files = sublime.find_resources ( "*.custom-completions" )
file = customCompletion_Files[0]

jsonString = sublime.load_resource ( file )
jsonValues = yaml.load( jsonString )

string = jsonValues[ "test" ]
print ( string )
0 Likes

#3

if you are trying to convert a json string to its parsed object equivalent, you can use the sublime.decode_value method. This is what I did in my parse keybindings code that I posted to SO earlier in the week.

1 Like

#4

Nice, I like that method better. :grin:

 
With my method above I ended up having to implement this to remove comments or else yaml.load would throw a fit about it:

rx_jsonComments = "[\\t\\ ]*\/\/[A-Za-z0-9\\\\\\{\\}\\[\\]\\(\\)\\*\\|\\^\\-\\$\\.\\+\\?\\/\\:\\!\\&\\`\\,\\@\\=\\#\\%\\;\\~\\_\\<\\>\ ]*\r"
jsonString = re.sub( rx_jsonComments, "", jsonString )

 
I can ditch yaml now too.
The only reason I was even using it was because json doesn’t work with trailing commas.

sublime.decode_value works better since ST natively has awesome handling of comments & trailing commas, so it solves both issues without the need for an external module :+1:

0 Likes

#5

Well, since ST3 there is this mutated and JSON-based thing that seems to be undocumented but is similar to JSON and supports JavaScript-like comments as well as trailing commas.

It’s user-friendly since it’s forgiving but most parsers hate it, since it violates the JSON standard, which is very simple by the way. Fortunately you can manually patch the forgivingness with more or less simple regular expressions, as you already mentioned, although your expression looks way more complicated than it needs to.
Either way, the proper way is to use sublime.load_resource, just like @kingkeith said.

PS: Python ships a json module in its stdlib with a parser and serializer.

1 Like

#6

Is there a built-in way to parse a YAML file since ST does it? (i.e., not using an import yaml)

0 Likes

#7

Nothing exposed in the API, no.

ST’s YAML parser is also (at least) not YAML 1.2 compliant since it doesn’t support anchors and the merge type key (see here).

1 Like

#8

 
That’s what I used initially, but it was not as forgiving as sublime.decode_value in regards to trailing characters & comments.

I guess I’m spoiled by ST’s JSON variant, but I feel like that’s how it should be anyway.

Why should I have to do extra work & maintenance when teh codez should just know what I meant?! :stuck_out_tongue:

 

 
True, I probably should have used a negated character set for valid comment characters instead of an explicitly defined character set.

I was being lazy during testing & used some preset values from my personal RegEx reference.

0 Likes