Chapter 9. Customizing skEdit

The easiest way to customize skEdit is via the built-in preference panes. This section covers other ways to customize skEdit

9.1. Bundles

skEdit encapsulates all of the settings for a language into an OS X bundle, which is essentially a directory containing certain files in certain places. The general directory structure of a bundle is as follows. Click on a file name for more information.

skEdit looks for bundles first in ~/Library/Application Support/skHTML/Bundles, then inside of skEdit.app. For best performance, the plist files should be in binary format. You can convert an XML or textual plist to binary using the plutil command-line application:

plutil -convert binary1 /path/to/file.plist

9.1.1. Code Navigator

Code navigator definitions are property list files that live as a codenav.plist file inside of an skEdit bundle. They will be applied to sections of text handled by the bundle. The format is an array of dictionaries with the following keys:

bold

Boolean. If true, the title in the menu will be bold.

display

String. The title that will be displayed in the menu. Can contain regular expression backreferences. If blank, skEdit will use a separator item.

icon

String. The name, including extension, of an image to display in the menu.

italic

Boolean. If true, the title in the menu will be italic.

pattern

String. The regular expression to match.

skEdit will look for the icon first in the .skbundle, then in skEdit itself. You can place icons anywhere in the bundle, but I would suggest a Resources directory. skEdit provides some generic icons: class.gif, function.gif, interface.gif, method.gif, todo.gif.

9.1.2. Code Completion

The code completion definitions is a .plist file that lives inside an skEdit bundle as completion.plist. It defines the default completion for text handles by that bundle. It can be augmented by entries generated by the code indexer. skEdit has several types of code completion, which are detailed below.

9.1.2.1. Keyword-Based Code Completion

This is the most generic type, and is appropriate for languages like PHP or JavaScript. It's definition is a dictionary with the following keys:

format-type

String. Must be "keyword".

keys

Dictionary. A dictionary of the code completion keywords. The keys of the dictionary are the keywords, while the values are what the keyword should complete to. For example:

<key>some_function</key>
<string>int some_function(int arg1, float arg2)</string>
<key>another_function</key>
<string> another_function()</string>

Everything up to the first space in the value is considered the type. It will be displayed in the UI, but will not be inserted. This is mainly intended for languages that have return types for functions, methods, etc., but can also be used for other things. If there is no type, the value should be prefixed with a space, as seen in the second entry above.

9.1.2.2. Tag-Based Code Completion

This type is specific to element-based languages, like HTML or XML. It's definition is a dictionary with the following keys:

format-type

String. Must be "tag".

elements

Dictionary. A dictionary where the keys are the names of elements, and the values are dictionaries where the keys are attributes, and the values are the values for that attribute. For example:

<key>a</key>
<dict>
  <key>accesskey</key>
  <string></string>
  <key>class</key>
  <string>#text.css.class</string>
  <key>dir</key>
  <array>
    <string>ltr</string>
    <string>rtl</string>
  </array>
</dict>

As can be seen above, the values for an attribute can either be a string, or an array of strings. In addition, the values can be populated from code indexer entries. For example, the class attribute above will be populated with "class" entries from files indexed by the text.css bundle.

9.1.2.3. Special Code Completion

skEdit's code completion can be extended to new types. For example, the CSS code completion is completely custom, with its own definition and own implementation inside of skEdit. This eventually will be opened up with a plugin architecture, but for now remains closed for third parties. If you have something you'd really like to do that needs special behavior, please let me know.

9.1.3. Code Indexing

Indexer definitions are .plist files that live inside skEdit bundles as indexer.plist files. They are run on all files that match to the bundle when skEdit is indexing. The definition is a dictionary with the following keys:

comments

Array. An array of strings. Each string is a regular expression representing language comments. As the first step of indexing, all comments will be removed from the code.

external-files

Array. An array of strings. Each string is a regular expression. The first backreference or the regex should be a path to a file. These paths will be saved in the database as files the current file references. For example, the HTML indexer has expressions to find <link> elements that reference CSS files.

includes

Array. An array of dictionaries. Allows one indexer to reference other indexers so that difference sections of a file can be indexed appropriately. For example, the HTML indexer has includes for CSS, JavaScript?, and PHP. The dictionaries have the following keys:

begin

String. A regular expression defining the beginning of the section to index.

end

String. A regular expression defining the end of the section to index.

begin

String. The parser ID of the indexer to use for the section.

keys

Array. An array of dictionaries. Each dictionary represents an item that can be found in the code and saved into the database for code completion or other things to lookup. The dictionaries have the following keys:

completion

Integer. A regular expression backreference index. The value of this backreference will be inserted for the code completion.

key

Integer. A regular expression backreference index. The value of this backreference will be used when doing code completion lookup.

pattern

String. The regular expression pattern that will be matched in the file.

type

String. A type identifier for the match. Will be shown in the UI and can be used by skEdit when doing lookups.

pathResolution

String. The name of a class loaded by skEdit at run-time. Used for custom path resolution. For example, skEdit includes special path resolvers for Ruby and Perl. This feature is currently not available to third parties. If you'd like to do something special here, please let me know.

remove

Array. An array of strings. Each string is a regular expression that will be removed from the text before finding the keys. This is typically used to remove quoted strings.

9.1.4. Bundle Info

The Info.plist files lives inside of an skEdit bundle and provides metadata about the bundle:

CFBundleIdentifier

String. Should be a unique identifier for the bundle. I suggest reverse domain notation (e.g. org.skti.skEdit.bundles.html)

CFBundleName

String. Should be a unique identifier for the bundle. I suggest reverse domain notation (e.g. org.skti.skEdit.bundles.html)

CFBundleVersion

String. The bundle version. Should be 1.0 at the moment.

file-categories

Array. An array of file categories titles for which the bundle applies.

file-types

Array. An array of file type strings. Serves as a fallback - if no file categories are matched, the bundle will apply to these file types.

9.1.5. Syntax

The syntax highlighting definitions live in skEdit bundles as syntax.plist. They define how skEdit highlights files and also define the regular expression patterns used for code folding. There are two types of definitions: one for keyword-based languages and one for element-based languages.

9.1.5.1. Keyword-Based Definition

This type is appropriate for languages like PHP or JavaScript?. The definition is a dictionary with the following keys:

closers

Array. An array of strings that would end a section of code. For example, CSS has </style>

comments

Array. An array of dictionaries that represent comments. The dictionaries have the following keys:

begin

String. A string that represents the beginning of a comment. For example, <!--.

end

String. A string that represents the end of a comment. If omitted, the comment will be restricted to one line.

id

String. The theme identifier that will be applied to the comment.

folding

Dictionary. Defines the code folding patterns with the following keys:

close

String. A regular expression pattern. Any line matching this pattern will be considered the end of a code folding block.

open

String. A regular expression pattern. Any line matching this pattern will be considered the beginning of a code folding block.

format-id

String. An identifier used by other bundles to reference this one. For example, CSS is text.css.

format-type

String. Must be "keyword".

keyword-characters

String. A string of all characters that will be considered part of keywords while highlighting.

keywords

Dictionary. A dictionary defining all of the plain-text keywords. The keys are style identifiers, while the values are arrays of strings that represent keywords for that style identifier. For example:

<key>keyword.properties.css</key>
<array>
  <string>border</string>
</array>
openers

Array. Like closers, but represent the beginning of a section of code.

quotes

Dictionary. Defines how quotes are handled with the following keys:

double

String. If defined, double-quoted strings will have the this style identifier applied.

single

String. If defined, single-quoted strings will have the this style identifier applied.

regex-keywords

Array. An array of dictionaries representing regular expression keywords. The dictionary keys are as follows:

id

String. The style identifier that will be applied to matches.

keyword

String. The regular expression pattern used for matching.

9.1.5.2. Element-Based Definition

Appropriate for languages like HTML or XML. It's definition is a dictionary with the following keys:

embedded

Dictionary. A dictionary allowing other bundles to handle certain sections of code. For example, HTML has entries for ASP, PHP, CSS, and JavaScript?. This is easier to demonstrate with some examples:

<key>%</key>
<string>text.asp</string>
<key>?php</string>
<dict>
  <key>end</key>
  <string>?></string>
  <key>id</key>
  <string>text.php</string>
</dict>

In the first entry, everything between <% and %> will be handle by the text.asp parser. Because the opening and closing tags are the same, it can have a simpler definition. In the second example, everything between <?php and ?> will be handled by the text.php parser. Because the opening and closing tags don't match, it has a more complicated definition.

folding

Dictionary. The same as in the keyword-based definition.

format-id

String. The same as in the keyword-based definition.

format-type

String. Must be "tag".

style

Dictionary. A dictionary defining which theme identifiers to apply to which pieces of the element:

attributes

String. The style identifier to apply to attributes. Currently not used.

comments

String. The style identifier to apply to comments.

quotes

String. The style identifier to apply to quotes.

tags

String. The style identifier to apply to tags.