Linting customization in Anaconda Package Sublime - ide

I am using the Anaconda package for Sublime 3, and it works perfectly. My only problem is that linting highlights all kind of errors, warnings and PEP8 recommendations in the same color, white. I would like to change it so errors are red, warnings are yellow etc... But I can't figure out how to do that. I found this resource that basically tells me to add some XML code to my current theme to change the linting color, but I tried doing that, and it did nothing.
First of all I believe now themes are using json and not XML anymore, in filenames of the type ".sublime-color-scheme" or ".sublime-theme". Thus I found a custom theme that indeed had a ".tmtheme" file, and pasted the XML code given here, but linting was still completely white.
Then I tried translating this XML code into json, and pasting it into the ".sublime-color-scheme" file, but then again, linting was white. To be precise, I pasted it in the "rules" :[] entry, since that seemed to fit the format.
Anybody with more experience could tell me what I'm doing wrong, or point me to another way of changing linting color ? I am aware of package such as SublimeLinter, but I'd rather stick with the built-in linter of the Anaconda package since its working perfectly beside the coloring.

As you've noted, there are two different types of color schemes in Sublime Text:
The tmTheme format, which is an XML plist file. This format is still supported, but is considered to be a legacy file format at this point.
The sublime-color-scheme format, which is a JSON file. This format can do everything that the tmTheme format can do, and has extra capabilities that tmTheme files don't.
NOTE: Despite the name, tmTheme files are color schemes, not Themes. The format is unfortunately named, but in Sublime Text a Theme is an entirely different thing that styles the application look as a whole.
This distinction isn't particularly important here, but it can catch you unaware if you go searching for information because you sometimes end up finding information that doesn't seem to apply to anything.
It's hard to say exactly what you might have done wrong since you didn't include the content that you tried adding to the files. Generally I would expect that anything you added in there would either work or cause an error of some sort (either a popup or in the Sublime console), barring any configuration issues with the package itself.
As an added note, I don't use this package (or linters in general), so for test purposes the Anaconda settings I tested with are stock except for the following two settings:
// The default is "basic", but that seemed too generic for testing
"anaconda_gutter_theme": "bright",
// I don't use linters, but I happened to have pylint already installed
// so this was the path of least resistance.
"use_pylint": true,
How you would go about adding the extra rules to your color scheme depends first on where your color scheme lives. In particular, if you have created your own custom color scheme that's stored in your User package, the steps are different than if you're using a color scheme that's being provided by someone else (Sublime Text or some package that you installed).
Since most people tend to use pre-existing color schemes that they obtained from somewhere else, we'll cover that first.
The color rules that are given on the page you linked are in the tmTheme XML format, and look like this:
<!-- Anaconda -->
<dict>
<key>name</key>
<string>anaconda Error Outline</string>
<key>scope</key>
<string>anaconda.outline.illegal</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#FF4A52</string>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>anaconda Error Underline</string>
<key>scope</key>
<string>anaconda.underline.illegal</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#FF0000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>anaconda Warning Outline</string>
<key>scope</key>
<string>anaconda.outline.warning</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#DF9400</string>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>anaconda Warning Underline</string>
<key>scope</key>
<string>anaconda.underline.warning</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#FF0000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>anaconda Violation Outline</string>
<key>scope</key>
<string>anaconda.outline.violation</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#ffffff33</string>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>anaconda Violation Underline</string>
<key>scope</key>
<string>anaconda.underline.violation</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#FF0000</string>
</dict>
</dict>
To add these rules, we need to first convert them into the sublime-color-scheme JSON format, even if your color scheme is a tmTheme color scheme. The method that you use to adjust a color scheme is to create a file in your User package with the additional content, and that file is always in the sublime-color-scheme format.
The conversion of these rules to the new JSON format of a sublime-color-scheme looks like this:
{
"name": "anaconda Error Outline",
"scope": "anaconda.outline.illegal",
"foreground": "#FFFFFF",
"background": "#FF4A52"
},
{
"name": "anaconda Error Underline",
"scope": "anaconda.underline.illegal",
"background": "#FF0000"
},
{
"name": "anaconda Warning Outline",
"scope": "anaconda.outline.warning",
"foreground": "#FFFFFF",
"background": "#DF9400"
},
{
"name": "anaconda Warning Underline",
"scope": "anaconda.underline.warning",
"background": "#FF0000"
},
{
"name": "anaconda Violation Outline",
"scope": "anaconda.outline.violation",
"foreground": "#FFFFFF",
"background": "#ffffff33"
},
{
"name": "anaconda Violation Underline",
"scope": "anaconda.underline.violation",
"background": "#FF0000"
},
Depending on your actual color scheme, the colors in here may or may not be appropriate, so you'll have to play with them to get them looking as you want. This would also require knowing what classifies as illegal versus warning versus violation as well as how you've set up Anaconda's linting style. Your rules might need foreground, background or both depending on how you've set things up.
With this content in hand, we're ready to begin. In order to make the adjustment, you need to know what the name of your color scheme is. You can get this by using Preferences > Settings and looking at the color_scheme setting (if you're using syntax specific settings, then open a file of that type and use Preferences > Settings - syntax specific and get the color scheme from there).
The part that we're interested in here is the name of the file; we don't care what package it might say it lives in, only the name of the file itself. We also don't care what extension the file has because we're going to assume that the extension is sublime-color-scheme anyway.
For example, with the setting set as the following, the name of the color scheme is Cobalt and that's all we care about.
"color_scheme": "Packages/Color Scheme - Legacy/Cobalt.tmTheme",
With this color scheme, the configuration above and some sample code, the results I see in the buffer are this:
In order to put the new rules in place, we need to create a sublime-color-scheme file in the User package named for our color scheme. So in this case that would be Cobalt.sublime-color-scheme. If you're unsure of where your User package lives, you can use Preferences > Browse Packages to find it.
The content of the file that you create should look like this (paste the content from above as appropriate; for brevity I'm not including it again here):
{
"rules": [
// Paste the JSON rules above here
]
}
As soon as you save the file, it will take effect. The result of that is this:
Presuming that you're using a color scheme that you created yourself that's in your User package, this won't work and you would instead need to add the rules directly to your color scheme file in your User package. This would also be the case if you have a "patch" file like this already in your User package (if you were adding extra color rules for somethign else, for example).
If your custom color scheme is in sublime-color-scheme format, then you can just add these rules into the rules section of your color scheme just like above to have them take effect.
If your color scheme is in tmTheme format, then instead you'd need to copy the XML version of the settings into your color scheme. Here how you'd do that is not entirely as straight forward as with the sublime-color-scheme formatted file due to the XML nature of the file.
In this case you'd instead need to note that each rule is a <dict></dict> tag with specific keys, then examine the color scheme to see where it has similar color rules and inject yours into the correct location.
Generally speaking if you get it wrong the color scheme will be ignored (everything will turn black and white) and you'll get an error dialog to tell you that something has gone wrong.
More information on how color schemes work, how to apply colors, etc can be found in this video series on color schemes in Sublime Text (with the disclaimer that I'm the author of the videos in question).

Related

File icons getting changed to App icon in macOS Catalina

I have a Mac app that opens office files(.doc, .xls, etc.) and I need to show custom icon for these supported files.
I used to achieve by adding the supported UTI types in CFBundleDocumentTypes and assign my custom icns icon. Also set my app as the default app which opens these file types.
Now this approach worked flawlessly until macOS Catalina beta, even with Microsoft apps being present along with my app. In macOS Catalina beta onwards, I am seeing my app icon in place of all the file icons.
I tried clearing icon cache and even relaunching Finder, but to no avail.
Later on I even tried by adding the UTI types under UTExportedTypeDeclarations and UTImportedTypeDeclarations.
Is this a bug with Catalina Beta? Or anything I can do to get this working.
My plist has UTExportedTypeDeclarations looking like this. UTImportedTypeDeclarations and CFBundleDocumentTypes have similar values.
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>org.openxmlformats.spreadsheetml.sheet</string>
<string>org.openxmlformats.openxml</string>
<string>public.composite-content</string>
</array>
<key>UTTypeDescription</key>
<string>Excel Open XML spreadsheet</string>
<key>UTTypeIconFile</key>
<string>custom.icns</string>
<key>UTTypeIdentifier</key>
<string>com.microsoft.excel.openxmlformats.spreadsheetml.sheet</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>com.apple.ostype</key>
<string>XLSX</string>
<key>public.filename-extension</key>
<array>
<string>xlsx</string>
</array>
</dict>
</dict>
</array>
It looks like macOS 10.15 changed the way how the corresponding icon for a type is resolved.
I found a way how to get proper document icons for my app on Catalina:
Previously I only had an icon defined for the CFBundleTypeIconFile key in my CFBundleDocumentTypes dictionaries. But since Catalina, the system uses the LSItemContentTypes array to find an exported UTI and then uses the icon of that UTI (defined via the UTTypeIconFile).
If the LSItemContentTypes array contains types that are not known to the system yet (= newly introduced custom types), those types must also be exported by defining dictionaries in UTExportedTypeDeclarations.
This works for my case because I use a custom file format with its own UTI.
For the case you are describing, where existing UTIs are used, I am not sure if it is still possible to override the icons of UTIs that you don't "own".
I think the correct way to define custom icons for 3rd party types would be to define dictionaries in the imported types array (UTImportedTypeDeclarations). In that case the system should choose your custom icon as long as no other app declares ownership of an UTI by exporting it. I suppose that the icon of the app that is set as Default application for a type wins in the case where 2 or more apps claim ownership for it (Haven't tried that).
Another issue I ran into was, that the icon file assigned to UTTypeIconFile can't come from an Asset Catalog (this worked for CFBundleTypeIconFile). It needs to refer to an .icns file in the Resource folder in your bundle.
Existing .iconset folders from the Asset Catalog can be converted to icns with the following command:
iconutil --convert icns iconname.iconset
I am not sure if this intended behavior or if this is just a bug in the Asset Catalog compiler build phase of Xcode 11. I filed a bug via Feedback Assistant.
I also have this issue. Tried empty project and reproduced it with bundled macOS applications, so it's mostly safe to assume this is a bug in macOS Catalina.
As trojanfoe suggested in a comment the only thing to do right now is reporting it to Apple via the Feedback Assistant.
Thomas Zoechling refers to another issue that may affect earlier macOS versions too, but does not solve the main issue here.

application:handleOpenUrl: is appending the wrong extension to the file

When I attempt to export a file to my app, from within Mail, it is sending the file to export with the wrong extension.
Here's an example:
I e-mail an attachment to myself
Open the attachment in Mail
Export the file and open with my app
The url passed to application:handleOpenUrl: is wrong
The name of the file I am attempting to export is named 'NSIS.nsi' (without quotes). Mail (iOS?) renames the file to 'NSIS.4th' when it passes it back to my app via application:handleOpenUrl. One thing I did notice is that the first extension (item) within the Exported Type UTIs > Item 0 > Conforms to UTIs > Equivalent Types > public.filename-extension is '4th' (again, without quotes).
Another thing to note is that I do have the 'nsi' extension in the same public.filename-extension array.
And yet another thing to note is that this appears to happen only with the 'nsi' extension. I haven't tested all of the extensions my app supports (there's 92 of them. I got tired after about the 40th one). But this extension in particular is having issues.
By the way here is the code sample... it really is this simple. The NSURL passed contains the wrong extension. This will log the url passed -- which is the wrong one. So, I can say for certain that there is nothing in my app that is doing something with the NSURL before it gets passed to application:handleOpenUrl:.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
NSLog(#"url: %#", url);
...
}
I also don't know if this helps, but in the Mail app it does show my app's icon next to the NSIS.nsi file. And yes, the file's name displays as 'NSIS.nsi' within Mail.
Update 2
I was able to confirm that changing the first extension to '5th' (for kicks) and then imported the 'NSIS.nsi' file it indeed changed the file extension to 'NSIS.5th'. I think what's happening is I'm defining the UTIs that my app supports incorrectly. All I want to do is say, "Hey, iOS, I support all of these file extensions. Don't change the name. Just give me the file and let me do what I need to do with it." In reality I just want my app to support all types of text files (text, utf8, utf16, etc). That's the end result.
The problem is, when I tell iOS that I support plain.text, utf8 and utf16 it still won't display my app in the list of apps that can open a file unless I specifically set the extension in the public.filename-extension array. I wish there was just an all encompassing "I support all text files" configuration value in the plist.
One other thing I noticed is that the issue does affect other file extensions. For example, I have a file that I am exporting from Mail to my app called 'Ada.adb'. iOS is returning the file as 'Ada.ada' (notice the 'a' at the end instead of a 'b'). This makes sense... I don't even have 'ada' in my list of file extensions within the public.filename-extension array or anywhere in my app for that matter.
Update 3
I figured out how to support all types of public.text files.
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFiles</key>
<array>
<string>icon_buffer_ipad_small.png</string>
<string>icon_buffer_iphone_small.png</string>
</array>
<key>LSItemContentTypes</key>
<array>
<string>public.text</string>
</array>
<key>NSExportableTypes</key>
<array>
<string>public.text</string>
</array>
<key>CFBundleTypeName</key>
<string>Source File</string>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
</array>
Essentially you need to include the NSExportableTypes in addition to the LSItemContentTypes. I'll add an update when I figure out how to make other "public.text" file types such as 4th, md, and the huge list of other file types that are public.text, associated to your app. Hopefully this won't be necessary. Regardless, I'll update with my findings.
Update 4
You guys aren't going to believe this. This issue affects every app I have tested this with. Essentially, when I attempt to export the 'Ada.adb' file it exports the file as 'Ada.ada' to every application. Wow! I'm going to figure out how to file this bug with Apple. Unless, of course, this is expected behavior!
Small update: I filed the bug to Apple. Bug ID# 12802236
I do not recall this occurred in iOS 5. I believe this is a regression introduced in iOS 6.
If the file name doesn't change, how about change its extension manually after - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url receive the url? Of course, you have to know what the right extension is.

Creating a QuickLook plug-in for text files in Xcode 4.1

Background
I'm learning Objective-C and Cocoa, and I thought creating simple programs to answer my needs would be a nice thing. I already have a solid .NET C# background, some Python knowledge, and a little of C.
One of my "simple first app" I tried to do is a simple QuickLook plug-in for Arduino's sketch files. I thought it would be a simple task to accomplish since these files are plain text C-like scripts, the only "different" thing is they have a .pde extension.
I uploaded the project on GitHub at ArduinoQuickLook as a reference (the first commit contains a vanilla Xcode 4.1 QuickLook plugin-project).
What I found
Looking around the net I found these resources:
QLStephen
QLColorCode
Introduction to Quick Look Programming Guide
What are my problems
Both of them use GeneratePreviewForURL.m and GenerateThumbnailForURL.m files, but when I created the project in Xcode 4.1 it created GeneratePreviewForURL.c and GenerateThumbnailForURL.c (note .c instead of .m).
Both QLStephen and QLColorCode use #import <Foundation/Foundation.h> in their GeneratePreviewForURL.m and GenerateThumbnailForURL.m files, but if I try to #import it it yields to many errors. (Maybe because my files are .c instead of .m?)
It's not clear to me how I declare which files my plug-in will handle, I understood I need to change ArduinoQuickLook/ArduinoQuickLook-Info.plist (row 14) but what I have to write there? Something like cc.arduino.pde?
This tutorial on creating a Quicklook plugin explains things nicely, but to summarise:
Point 1 and 2 are related - for some strange reason the Quicklook plugin template only contains .c files - as such, importing the Obj-C Foundation.h header causes errors.
You should just be able to rename the files from .c to .m and it will work as expected.
It's not clear to me how I declare which files my plug-in will handle
You need to do two things - one is say which UTI (Uniform Type Identifier) your plugin handles (e.g cc.arduino.pde), by changing the line you mention:
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>QLGenerator</string>
<key>LSItemContentTypes</key>
<array>
<string>cc.arduino.pde</string>
</array>
</dict>
</array>
...but you also have to describe that UTI (mostly so it can map the file-extension to that UTI)
There are two slightly different ways to declare UTI's, [as "Declaring New Uniform Type Identifiers"] describes:
Your UTI declarations must be either imported or exported:
An exported UTI declaration means that the type is available for use by all other parties. For example, an application that uses a proprietary document format should declare it as an exported UTI.
An imported UTI declaration is used to declare a type that the bundle does not own, but would like to see available on the system. For example, say a video-editing program creates files using a proprietary format whose UTI is declared in its application bundle. If you are writing an application or plugin that can read such files, you must make sure that the system knows about the proprietary UTI, even if the actual video-editing application is not available. To do so, your application should redeclare the UTI in its own bundle but mark it as an imported declaration.
For a Quicklook plugin, you probably want an "imported" UTI declaration, in which you would add something like this to your Info.plist:
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>cc.arduino.pde</string>
<key>UTTypeReferenceURL</key>
<string>http://www.example.com</string>
<key>UTTypeDescription</key>
<string>Arduino PDE file</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.c-source</string>
<string>public.text</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>pde</string>
</array>
</dict>
</dict>
</array>
Here is the source for a project that provides QuickLook for Processing and Arduino .pde files: https://github.com/kroko/ProcessingQL I know this question is a year old, but this project might be helpful for anyone else attempting this.

How do I launch a non-document-based Cocoa application by dropping files on it?

The only way I've been able to get this working is with a document-based application (which this app isn't). In my non-document-based application I've defined the supported Document Types (from the Properties tab of the Target info window) and my AppDelegate implements application:openFile: and application:openFiles:. That enables dropping files on the application's Dock icon when it has already been launched but not its icon in the Finder (launched or otherwise). What am I missing?
Updated
As requested, my Document Types array:
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>nsf</string>
<string>nsfe</string>
</array>
<key>CFBundleTypeName</key>
<string>NSF Soundtrack</string>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>LSTypeIsPackage</key>
<false/>
<key>NSPersistentStoreTypeKey</key>
<string>InMemory</string>
</dict>
</array>
Two parts of this make me suspicious:
<key>CFBundleTypeRole</key>
<string>None</string>
Don't you mean this to be Viewer at least?
<key>NSPersistentStoreTypeKey</key>
<string>InMemory</string>
What are you trying to do here? Why would your on-disk file be specified as an in-memory Core Data persistent store? If you want to just hoist the whole thing into memory when you load it, that's called Binary or XML, not InMemory.
I also recommend that you define UTIs for your document types, not just extensions.
You should also double-check what Launch Services thinks is going on by using lsregister. Sometimes the problem is that you have multiple versions of your app lying around and Launch Services hasn't found the one you think it should have. You can look the Launch Services database like this:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump
This should work on 10.5 and 10.6. 10.4 has lsregister in a different place. I usually use locate to find it rather than trying to memorize it.
In your Target settings, go to the Properties tab and add to the Document Types table.

Registering an icon for my application's document type

I'm trying to register an icon for my app's document type. After reading Declaring New Uniform Type Identifiers and looking at /Developer/Examples/Sketch I came up with something like this in my Info.plist:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.mycompany.myextension</string>
</array>
<key>NSDocumentClass</key>
<string>NSString</string>
</dict>
</array>
...
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeDescription</key>
<string>Blah blah blah</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeIconFile</key>
<string>My-file-icon.icns</string>
<key>UTTypeIdentifier</key>
<string>com.mycompany.myextension</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>myextension</string>
</array>
</dict>
</dict>
</array>
Now, everything is fine and dandy, i.e. my program is opened when I click on a file with my extension, etc. However, the document icon is not registered with the OS, i.e. I see an ugly blank icon instead of my beautiful My-file-icon.icns. I suspect that I'm missing something in the plist above, any ideas?
Try putting the icon name in the CFBundleTypeIconFile key in the CFBundleDocumentTypes array, not in the UTExportedTypeDeclarations array.
And of course make sure that "My-file-icon.icns" is in your target's Copy Bundle Resources build phase and is being copied into Contents/Resources in your app's bundle.
I've been trying to do this in Xcode 11 and it's been a challenge. There are lots of answers here on SO to questions like this but I couldn't find one that had everything I needed to get this working. I'll try to do that here.
Technical Q&A QA1587 Although this is a bit old I think it has everything required but it's a bit vague in some spots like when it says Provide an icon for the document.
I thought I could make it work with an icon in Assets.xcassets but it didn't work for me until I provided an icns file. I took the 1024x1024 png app icon and converted it to an icns here at cloudconvert. Then I added that icns to my project. I don't think it matters where you put it. I put it just below the top level. It's circled in the image below.
Follow the arrows in the image and you end up at the Info tab. I tapped the Add button to create a Document Type and filled it in as shown. When you tap the Add button in the icon section it will ask you for an icns file. Once I had mine in the project it appeared in the window and I could select it.
Same for Configured UTIs.
That was it. In Files, Messages, or Mail the icon appears.
Your UTI declaration in the Info.plist appears to be correct, however I noticed an other issue. If you application is a document-based application you need to replace the NSString in following entry with your NSDocument subclass:
<key>NSDocumentClass</key>
<string>NSString</string>
For example it's "SKTDocument" in Sketch:
<key>NSDocumentClass</key>
<string>SKTDocument</string>
Edit:
Please also make sure to use your own reverse domain name for your exported UTIs. This ensures that UTIs are unique. For example its com.mindnode.MindNode.MindNodeDocument in my case.
I also had a similar problem, turns out I needed to rebuild the launch services database as per what i have documented here....
https://stackoverflow.com/a/12466968/1571635