# CFML Package for Sublime Text This package provides CFML (ColdFusion Markup Language) support in Sublime Text. It includes syntax highlighting, function and tag completions, and inline documentation. It also includes a number of other features, so please see below for the full list. You can install this package via [Package Control](https://packagecontrol.io/). The package name is [CFML](https://packagecontrol.io/packages/CFML). Sublime Text should be restarted after installation. Manual installation is also possible. See the [Installation](#installation) section below for more information about these options. ### Acknowledgements The following packages were used in the development of this package: - - The CFScript syntax is based on work done by Thomas Smith ([@Thom1729](https://github.com/Thom1729)) on the official JavaScript syntax: - Special thanks to [@foundeo](https://github.com/foundeo) and [cfdocs.org](https://cfdocs.org), from which this package gets its function and tag data. Also, thanks to [@mjhagen](https://github.com/mjhagen) who helped me get this package off the ground. ### Table of Contents - [Installation](#installation) - [Settings](#settings) - [Completions](#completions) - [Inline Documentation](#inline-documentation) - [Default Key Bindings](#default-key-bindings) - [CFC Indexing and Dot Paths](#cfc-indexing-and-dot-paths) - [Custom Tags](#custom-tags) - [Code Formatting](#code-formatting) - [Custom Coloring for CFML Tags](#custom-coloring-for-cfml-tags) - [Controller/View Toggle](#controllerview-toggle) - [CommandBox](#commandbox) - [TestBox](#testbox) - [Framework One](#framework-one) ### Installation #### Via Package Control First ensure Package Control is installed. More recent versions of Sublime Text include a menu option and command palette entry for installing Package Control. You can also follow the instructions at to install it. Open the command palette (CTRL+SHIFT+P on Windows, CMD+SHIFT+P on a Mac) and select `Package Control: Install Package`. Wait for the list to open and find the `CFML` entry (subtitled with this GitHub repo `github.com/jcberquist/sublimetext-cfml`), then select it to install. Restart Sublime Text. Package Control will keep the CFML package up to date automatically for you. #### Manual Installation First locate your Sublime Text packages directory. This can be easily done by opening the command palette in Sublime Text (CTRL+SHIFT+P on Windows, CMD+SHIFT+P on a Mac), and running `Preferences: Browse Packages`. On Windows it will typically be something like this: C:\Users\Username\AppData\Roaming\Sublime Text\Packages\ On a Mac it will be something like this /Users/Username/Library/Application Support/Sublime Text/Packages/ *Via Git* Open Terminal or Command Prompt and `cd` into your packages directory, then run: git clone https://github.com/jcberquist/sublimetext-cfml.git ./CFML Restart Sublime Text. As changes are made to this repository and the package is updated, simply run the following command inside the folder where you installed the package in order to get your copy of the package up to date: git pull origin master *Via ZIP Download* Use the `Download ZIP` option to download a zip of the repository to your computer. (The master branch zip file is located at ) Unzip this, and copy the contents of the resulting repository folder into a subdirectory named `CFML` in your Sublime Text packages directory. Restart Sublime Text. As changes are made to this repository and the package is updated you will need to repeat this process (replacing the old contents in the `CFML` subdirectory) in order to get your copy of the package up to date. ### Settings There are several settings files that you should be aware of, as they control much of the functionality of the package. There are two ways to access each file, the first being through the menus, and the second being via the command palette, which you open with CTRL+SHIFT+P on Windows (CMD+SHIFT+P on a Mac). #### Package Settings You can access package settings from the menu under `Package Settings -> CFML -> Settings` or via the command palette: `CFML: Settings`. To override any of these settings, use the user package settings file. (The default settings and user settings open side by side.) #### Project Settings Some settings are also (or only) able to be set on a per project basis. These settings control the behavior of the package for a given project. You can access and edit project files from the menu under `Project -> Edit Project` or via the command palette: `Project: Edit Project`. (These will only be accessible after you have saved a project: `Project -> Save Project As` or `Project: Save As`.) #### Bindings The keyboard and mouse binding files are available in the menu under `Package Settings -> CFML -> Key Bindings` and `Package Settings -> CFML -> Mouse Bindings`. Or via the command palette at `CFML: Key Bindings` and `CFML: Mouse Bindings`. The default and user files open side by side. ### Completions Completions are included for tags and tag attributes, as well as for built-in functions and member functions. Completions are also available for `Application.cfc` settings and methods. There are three completions styles for built-in functions. This is controlled by a package setting, `cfml_bif_completions`, which can be set to one of three options: `basic`, `required`, or `full`. Setting this to `basic` will cause only the function name to be completed, with no function parameters inserted. `required`, which is the default setting, includes required parameters in the completion, but only their names, and no types. Setting this to `full` results in all parameters being included in the completion, as well as the parameters types. When entering a function call parameter for a built-in function, a pop-up window with documentation from [cfdocs.org](http://cfdocs.org) for that parameter is shown. This can be disabled by setting `cfml_completion_docs` to `false` in your user package settings. ### Inline Documentation F1 is mapped to an inline documentation command that provides an inline documentation pop-up based on the cursor position. The documentation command can also be run on mouse hover. This is enabled by default, but can be disabled by setting the package setting `cfml_hover_docs` to `false` in your user package settings. *You can always override the default key binding in your user key bindings file.* If the documentation command is run when the cursor is within a built-in function or tag it will load the [cfdocs.org](http://cfdocs.org) documentation for that function or tag. Thus, having the cursor anywhere within `dateFormat(myDate, "yyyy-mm-dd")` and pressing F1 (by default) will trigger a pop-up displaying the documentation for `dateFormat`. Similarly, having the cursor anywhere within `` and pressing F1 will trigger the display of the documentation for `cfinclude`. Inline documentation is also available for `Application.cfc` settings and methods. *If you have a copy of the cfdocs.org GitHub repository on your file system, there is a package setting, `"cfdocs_path"`, which can be set to the data directory of that repository (e.g. `"cfdocs_path": "C:/github/cfdocs/data/en/"`). If this is set, the cfdocs.org documentation will be loaded from the file system instead of being fetched via HTTP request. (See below for more information on package settings.)* ### Default Key Bindings In tag attributes, script strings, and between `cfoutput` tags, pressing `#` when text is selected will wrap the currently selected text `#selected#`. CTRL+ALT+D will output a `` tag or `writeDump()/dump()` function in CFML script, wrapping any currently selected text. CTRL+SHIFT+O will output a `` tag or `writeOutput()` function in CFML script, wrapping any currently selected text. CTRL+ALT+A will output a `` tag or `abort;` in CFML script. If Sublime Text's `auto_close_tags` setting is `true`, when a closing tag's `/` has been pressed, the closing tag will be completed. There are two package settings that control which CFML and HTML tags should not be closed: `cfml_non_closing_tags` and `html_non_closing_tags`. If the package setting `cfml_auto_insert_closing_tag` is set to `true` (by default it is `false`), when `>` is pressed in a tag, the corresponding closing tag will be automatically inserted after the cursor position. The package setting `cfml_non_closing_tags` controls which CFML tags will not get a closing tag auto inserted. The package setting `cfml_between_tag_pair` controls the behavior of the editor when ENTER is pressed while the cursor is between a CFML tag pair (e.g. `|`). By default only a single new line is inserted. This can be changed to have an extra new line auto inserted between the tag pair (with an optional indent), and the cursor placed there. See the default package settings file for more information. ### CFC Indexing and Dot Paths There are two settings that are set on a per project basis in a project file, `cfc_folders` and `mappings`. Here is an example (a real project file will have other settings in it as well): ```json { "mappings": [ {"mapping": "/framework", "path": "C:/myprojects/projectname/framework"}, {"mapping": "/model", "path": "C:/myprojects/projectname/app/model"} ], "cfc_folders": [ { "path": "C:/myprojects/projectname/app/model", "variable_names": ["{cfc}", "{cfc}{cfc_folder_singularized}"], "accessors": false } ] } ``` *__Note__: the paths specified above can either be absolute paths, or relative paths. If they are relative paths, they will be resolved relative to the location of the `.sublime-project` file.* The specified mappings are used to resolve file paths to dot paths when right clicking on a CFC file in the sidebar and selecting `Copy CFC Dotted Path`. If more than one mapping matches, you will be given a choice, and if none match, it will fall back to using the base folder of the project as a dot path root. The mappings are also used to resolve dot paths specified in the `extends` attribute in a component, the `createObject` function, and when using the `new` operator to instantiate a component (e.g. `new dot.path.to.component()`). If the F1 command is used when the cursor is in any of these, you will get a pop-up with the file path for the component (plus more information about the component if it is one that has been indexed). You can click on the file path to jump to the component file. You can also CTRL+ALT+Left Click (CMD+ALT+Left Click on a Mac) on any of these to jump straight to the component file without going through the pop-up. In addition, these same commands will work in any quoted string that is used as a function call argument if it contains a dot path that can be resolved. *You can see the structure of this mouse binding in the `Mouse Bindings - Default` file. Use the `Mouse Bindings - User` file to create your own.* *__Important__: mouse bindings are global throughout Sublime Text, so use caution to ensure you don't override a default Sublime Text mouse binding (such as CTRL+Left Click which adds a new cursor at the position clicked).* The `cfc_folders` array contains objects with one required key: `path`. Folders specified here are recursively searched for CFC files and those files are indexed. The `variable_names` setting is an array of strings, where each string specifies a variable name to associate each indexed CFC with. The names are determined via substitution as follows: | Key | Substitution | |:--------------------------|:------------------------------------------------------------| | {cfc} | CFC name | | {entityname} | entity name of CFC if it has one, otherwise CFC name | | {cfc_folder} | name of folder containing the CFC | | {cfc_folder_singularized} | name of folder containing the CFC with trailing 's' removed | Any other text in the string will be left in place - this allows for specifying a prefix or suffix to use in the variable names. Then, if that variable name is typed in your code and followed with a ., method completions from the corresponding CFC will be offered. A variable name can contain periods in it (e.g. `application.services.{cfc}`). You can also use the F1 documentation command on these variable names as well as their methods calls to view documentation regarding the CFC and its methods. (Note: the F1 command also works on property names, if they match a cfc variable name, to work with DI frameworks like DI/1 that inject beans into properties of the same name.) In addition, you can use CTRL+ALT+Left Click to jump to the CFC or to the specific method in the CFC. By default, implicit accessors are included in the completions. The `accessors` key, if present and set to `false`, will remove implicit property accessors from the completions offered (explicit accessors will always be included). These two settings work together, such that when a base CFC as well as another CFC that extends it are both indexed, and a mapping is specified such that the dot path in the `extends` can be resolved, the documentation and completions for the child CFC will include properties and methods from the base CFC. In addition, the dot paths of all indexed CFCs will be offered as completions in the `extends` attribute, the `createObject` function (where the type is `component`), as well as when using `new` to instantiate a CFC. Further, when an instantiated component has been assigned to a variable (e.g. `myVar = new path.to.mycfc()`), and that component has been indexed and a mapping specified for it, then method completions for that component will be offered when a . is typed after that variable name. The F1 documentation command and the CTRL+ALT+Left Click jump to CFC command will also work on that variable name. (This behavior can be disabled by setting `instantiated_component_completions` to `false` in your user package settings.) *__Note__: completions from indexed components are available in three styles matching the completion styles for built-in functions. This is controlled by the `cfml_cfc_completions` package setting. Also, when entering parameters for indexed component method calls, a pop-up window with information regarding that parameter is shown. Completion names are available in two styles, controlled by the `cfc_completion_names` package setting. (The two options for it are `basic` and `full`; if this setting is changed, you will need to run the `CFML: Index Active Project` command via the command palette for the change to take effect for indexed components.) The reason for these options is that completion names in the `full` style, which are of the form `method():returntype`, block Sublime Text from including local buffer completions in the completion list. The `basic` style, which only includes the method names is therefore the default. If you do want to use the `full` completion style a plugin such as [All Autocomplete](https://packagecontrol.io/packages/All%20Autocomplete) can be used as a workaround to get local buffer completions back into the completion list.* **Inject Property Command** SHIFT+ALT+D is bound to command that will insert a property into a component. If it is run while the cursor is on one of the above mentioned component variable names or method calls, it will insert a property with its name set to the component variable name. Otherwise, it will present a list of all component variable names indexed in the given project, allowing one to be selected from the list and inserted. The default property templates used by the insert command can be found in the default package settings under the `di_property` key. These can be overridden in the user package settings, or on a per project basis by adding the same settings to a project settings file. By default, after a new property has been inserted all properties in the component will be sorted by name; this can be turned off by setting the `sort_properties` key in the `di_property` object to `false`. ### Custom Tags Support is offered on a per project basis for custom tags. This can be set up to function as used with a `` tag and a custom tag prefix, or with the generic `` format. Here is an example project file (other settings have been removed): ```json { "custom_tag_folders": [ { "path": "C:/myprojects/projectname/customtags/page", "prefix": "page" } ] } ``` *__Note__: the path specified above can either be an absolute path, or a relative path. If it is a relative path, it will be resolved relative to the location of `.sublime-project` file.* Once this is done, `page` will be offered as a custom tag prefix completion, and then after entering `F1 documentation command to get some minimal documentation about that custom tag, and CTRL+ALT+Left Click can be used to jump to the custom tag file. The indexer will search for `thistag.executionmode is/eq/== "end"/'end'` (case insensitive) or `` (case insensitive) in custom tag files in order to determine whether or not to auto close the custom tag. ### Code Formatting This package includes a CFScript code formatter. You can view the default settings for this command via the menu: `Package Settings -> CFML -> Format Settings`, or from the command palette via `CFML: Format CFScript - Settings`. Please view these settings to see the various formatting options available. These settings can be overridden in your user format settings file. There is a key binding included that runs the formatting command: SHIFT+ALT+F. By default this will format only the current method when in a component - though if any text is selected it formats that text, and in `.cfm` files it formats all CFScript in the file. To format an entire component the `CFML: Format CFScript` command palette command can be used, or you can override the default key binding with a custom one in your user key bindings - pass in the argument `"current_method": false` to bind this to full component formatting. (You can look in the `inputmaps` folder at the `.sublime-keymap` files to see the default key bindings - there is a commented out "args" object for this binding, so that you can simply copy the binding to your user key bindings and then uncomment the "args" object.) *PLEASE NOTE:* The reason formatting is limited by default to the current method in components is that the formatting is CPU intensive and is currently run on the main thread, meaning Sublime Text will "freeze" while formatting is ongoing. On small blocks of code, this should be very quick, but on a large file it can take some time. ### Custom Coloring for CFML Tags Unless you are using a specialized color scheme, CFML and HTML tags will receive the same coloring. In the latest builds of Sublime Text a new color scheme format `.sublime-color-scheme` has been introduced, along with the very easy customization of your active color scheme: . This package includes a command that will add such a customization in your `Packages/User/` directory for your active color scheme that applies custom colors for CFML tags. Press CTRL+SHIFT+P to bring up the command palette (CMD+SHIFT+P on a Mac) and run `CFML: Toggle Color Scheme Styles`. You can edit the styles that will be injected via the user settings for this package. ### Controller/View Toggle CFML MVC frameworks typically have the convention that a `controllers` and a `views` folder are contained in the same parent directory, and that controller names and methods correspond to view folder and file names. CTRL+F1 (CMD+F1 on a Mac) is mapped to a toggle command that will jump the editor back and forth between a view file and the controller method that corresponds to it. The settings which determine which folder names are regarded as controller and view folders are contained in the package settings file. By default, `controllers` and `handlers` are treated as controller folders, and `views` as the views folder. Alternate folder names can be specified in the user package settings file. ### CommandBox CommandBox () has been added as the default CFML build system. This simply means that running the build command (F7 on Windows) on a CFML file will run `box ${filename}` as a shell command in the directory of the file and output the result in a pane within Sublime Text (it can also be selected from the build system menu available via CTRL+SHIFT+B). For this to work, CommandBox needs to be installed, and the CommandBox `box` binary needs to be available system wide, so that `box` can be run in any directory (see ). ### TestBox TestBox () completions and inline documentation are available for `BaseSpec` components. They are enabled by default, but can be disabled globally by adding `"testbox_enabled": false` to your CFML user package settings, or on a per project basis by adding the same setting to a project settings file. The completions and documentation are offered in any CFC that is contained under a folder named `tests` (alternate folders can be specified in the settings), as well as in any CFC that extends `testbox.system.BaseSpec`. There are three build system variants for running TestBox tests from within Sublime Text. The first is for running all of a project's tests, which can be used no matter what project files are open, so long as the active file is a CFML one. The next variant is for running all of the tests in the directory of the currently active file, while the last variant runs the tests in the currently active test CFC only. CTRL+SHIFT+B calls up the build system menu, from which these options can be selected. Once one of the variants has been run, CTRL+B can used to run the last selected option again, without having to go through the menu. This system is configured via a `testbox` object in your project settings, with one required key: `runner`. (Note that this mimics the structure of a `box.json` file used with CommandBox.) `testbox.runner` can either be a URL to a TestBox runner, or an array of URL objects (see ). If an array is used, then you will be asked to select a particular runner when executing your tests. Before calling the runner URL provided, `reporter=json` will be added to it, as that is the format this package expects back. Aside from that, when running the "full" project variant of the build system, the URL will be called as is. If the variant for running the tests in a given directory is used, `directory=dot.path.to.directory` will be added to the URL. Additionally, if running the tests in a particular CFC, `testBundles=dot.path.to.directory.cfc` will be added to the URL. If `directory` or `testBundles` is already set in the query string of the URL, it will be overwritten. When running these variants, the setting `testbox.tests_root` is used, which specifies the root directory path that is used to determine the dot delimited path to the particular test directory. If you do not specify this, it will default to the directory location of your project file. If these settings are not found in your project file, the root folder(s) of your project will be searched for a `box.json` file. If found, and if that file contains a `testbox` object, then its settings will be used. Results are displayed in a results pane. There is a setting that controls the verbosity of the output: `testbox.reporter`, which has two options: "text" and "compacttext" ("compacttext" being the default). If there are errors or failures you can step backwards and forwards through the file stack traces via F4 and SHIFT+F4. As each file is selected, Sublime Text opens that file and jumps to the line indicated. You can also double click on any file, and Sublime Text will open it for you. Since the path to your files might look different to Sublime Text and the CFML application server (for example, if the server is running on a virtual machine), there is one more setting that maps the path as it appears to the server to the path as it appears to Sublime Text. Use `testbox.results.server_root` and `testbox.results.sublime_root` to specify the respective root paths to your project, so that Sublime Text can accurately open the files in stack traces. All of the settings for TestBox can be seen in the default package settings. ### Framework One Framework One () function completions and `variables.framework` setting completions are available. They are disabled by default, but can be enabled globally by adding `"fw1_enabled": true` to your CFML user package settings, or on a per project basis by adding the same setting to a project settings file. (Project based settings will override global settings. The default package settings for Framework One can be viewed in the CFML default package settings file.) The completions are offered in `Application.cfc` as well as in Framework One controller, view and layout files. (The folder names can be specified in the settings.) In controllers, Framework One method completions are offered after typing `framework.` and `fw.`.