Adobe
Products

Top destinations

  • Adobe Creative Cloud
  • Creative Suite
  • Adobe Marketing Cloud
  • Acrobat
  • Photoshop
  • SiteCatalyst
  • Students
  • Elements family

Adobe Creative Cloud

  • What is Adobe Creative Cloud?
  • Design
  • Web
  • Photography
  • Video
  • Students
  • Teams
  • Enterprise
  • Educational institutions

Design and photography

  • Photoshop
  • Illustrator
  • InDesign
  • Adobe Muse
  • Lightroom

Video

  • Adobe Premiere
  • After Effects

Web development and HTML5

  • Edge Tools & Services [opens in a new window]
  • Dreamweaver
  • Gaming [opens in a new window]

Adobe Marketing Cloud

  • What is Adobe Marketing Cloud?
  • Digital analytics
  • Social marketing
  • Web experience management
  • Testing and targeting
  • Media optimization

Analytics

  • SiteCatalyst
  • Adobe Discover
  • Insight

Social

  • Adobe Social

Experience Manager

  • CQ
  • Scene7

Target

  • Test&Target
  • Recommendations
  • Search&Promote

Media Optimizer

  • AdLens
  • AudienceManager
  • AudienceResearch

Document services

  • Acrobat
  • EchoSign [opens in a new window]
  • FormsCentral [opens in a new window]
  • SendNow [opens in a new window]
  • Acrobat.com [opens in a new window]

Publishing

  • Digital Publishing Suite

  • See all products
Business solutions

By business need

  • Digital analytics
  • Digital publishing
  • Document management
  • Media optimization
  • Social marketing
  • Testing and targeting
  • Video editing and serving
  • Web development [opens in a new window]
  • Web experience management
  • See all business needs

By industry

  • Broadcast
  • Education
  • Financial services
  • Government
  • Publishing
  • Retail
  • See all industries
Support & Learning

I need help

  • Products
  • Adobe Creative Cloud
  • Adobe Marketing Cloud
  • Forums [opens in a new window]

I want to learn

  • Training and tutorials
  • Certification [opens in a new window]
  • Adobe Developer Connection
  • Adobe Design Center
  • Adobe TV [opens in a new window]
  • Adobe Marketing Center
  • Adobe Labs [opens in a new window]
Download
  • Product trials
  • Adobe Flash Player
  • Adobe Reader
  • Adobe AIR
  • See all downloads
Company
  • Careers at Adobe
  • Investor Relations
  • Newsroom
  • Privacy
  • Corporate Social Responsibility
  • Customer Showcase
  • Contact us
  • More company info
Buy
  • For personal and professional use
  • For students, educators, and staff
  • For small and medium businesses
  • Volume Licensing
  • Special offers
  • Adobe Marketing Cloud sales [opens in a new window]
Search
 
Info Sign in
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Welcome,
My Adobe
My orders
My information
My preferences
My products and services
Sign out
My cart
Privacy My Adobe
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out Privacy My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Promotions
Estimated shipping
Tax
Calculated at checkout
Total
Review and Checkout
Adobe Developer Connection /

Building your first Brackets extension

by David Deraedt

David Deraedt
  • www.dehats.com

Content

  • Extensions location
  • Setting up Brackets for development
  • Working from a Brackets repository clone
  • Using an extension template
  • Introduction to the Brackets extension API
  • Editing the current document
  • Where to go from here

Created

26 November 2012

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
best practiceCSSextensibilityHTML5JavaScript
Was this helpful?
Yes   No

By clicking Submit, you accept the Adobe Terms of Use.

 
Thanks for your feedback.

Requirements

Prerequisite knowledge

Readers should know about Brackets or Edge Code and have a good knowledge of JavaScript.

 

Required Adobe products

  • Brackets (An open source code editor for the web, written in JavaScript, HTML and CSS.)

User level

Intermediate

Brackets, the new open source code editor for the web, takes extensibility very seriously. In fact, some of its core features are implemented as extensions, such as Quick Open, Quick Edit, and HTML Code Hinting.

Brackets has a highly modular architecture that enforces separation of concerns by keeping the Brackets main code as focused as possible, while it is still deeply customizable—an absolute requirement to fit modern web developers’ needs.

You may notice, however, that while Brackets comes with some default extensions, out-of-box it still might seem a bit limited. For that reason, the first thing new users can do is to install extra extensions, as described in my blog post: Brackets/Edge Code extensions you should install right now. By doing so, you will have access to extensions, such as string manipulation or code snippets.

That said, as a user, you'll probably quickly find yourself thinking "if only Brackets could X... how hard can it be?" Well, since Brackets is built using web standards, as described in the article, Brackets: The Open Source Code Editor for the Web, by Adam Lehman, customizing it by yourself is far easier than you might imagine. It's also a very rewarding experience—one you can quickly get hooked on.

In this article, we'll take a look at how Brackets extensions work, how you can build one using a template or starting from scratch, and how to best set up your development environment.

Note: While Edge Code is a Brackets distribution that you can use to potentially build extensions too, it does not come with a Debug menu, making it less convenient than Brackets for the job of writing extensions. You can, however, use any extension you create with Brackets within Edge Code. This article was written using Brackets Sprint 16.

Extensions location

Technically speaking, an extension is nothing more than a folder containing a JavaScript file named main.js, which is executed by Brackets at startup.

Figure 1. Setting up the location of extensions
Figure 1. Setting up the location of extensions

When it finished loading and executing the rest of its code, the application will look for those extensions in the following folders:

  • The default extensions folder (src/extensions/default). This folder contains default extensions that the Brackets team has chosen. Users should not put anything in this folder.
  • The user extensions folder (/Users/<user>/Library/Application Support/Brackets/extensions/user on OSX or C:\Users\<user>\AppData\Roaming\Brackets\extensions\user on Windows 7). Brackets users put downloaded third-party extensions from Github within this folder. For convenience, Brackets automatically opens this folder when you select Help > Show Extensions Folder.
  • The extension development folder (src/extensions/dev). As an extension developer, you place your own extensions within this folder. This is a more convenient place for them than the user extension folder, which ties into the user system.

Note that Brackets provides a place for disabled extensions, at src/extensions/disabled, which makes it easy to temporarily disable extensions without having to delete them altogether.

Setting up Brackets for development

To debug an extension within Brackets, use the following steps.

  1.  Within Brackets, select Debug > Show Developer Tools to open the Chrome developer tools. Note that, in the current version (sprint 16), Brackets opens the Chrome developer tools in a Chrome browser window (or opens Chrome if it was closed). On Macintosh, if you use Spaces, ensure that you have a Chrome window open alongside Brackets.
Figure 2. Debugging an extension
Figure 2. Debugging an extension
  1. I strongly recommend that you disable the cache in the developer tools tab opened from Brackets, otherwise you won’t be able to test your changes, even after reloading the application. You can do that from the developer tools option panel.
Figure 3. Disabling cache to test your changes
Figure 3. Disabling cache to test your changes
  1. You'll quickly realize, however, that writing code and testing the result within the same editor window is just not the way to go. This is exactly why it is preferable that you open a New Brackets Window under the Debug menu, but selecting Debug > New Brackets Window (Figure 4).
Figure 4. Opening a New Brackets Window under the Debug menu to truly test your code.
Figure 4. Opening a New Brackets Window under the Debug menu to truly test your code.

I also strongly recommend testing from this second window. To do so correctly, you must set up the developer tools from this window, as explained in step 1. My typical setup looks like the following:

Figure 5. My typical debugging and development setup.
Figure 5. My typical debugging and development setup.

Working from a Brackets repository clone

Another good practice is to develop your code from a separate copy of the Brackets source. The advantage is that you can work with the latest version of the application code, ensuring your extension is up-to-date. You also avoid having to edit the original application source, which could have some undesirable effects. A simple way to work from a Brackets repository clone would be to just fork or clone the Brackets repository from GitHub as described in the following steps.

  1. Go to the Brackets repository from GitHub.
  2. If you have the GitHub client for Mac or GitHub client for Windows, simply click the “Clone in Mac” or “Clone in Windows” button (depending on your platform) from this repo homepage, and choose and a local destination on your disk.
Figure 6. Cloning the Brackets repository for Mac
Figure 6. Cloning the Brackets repository for Mac
  1. Specify that Brackets should run this code instead of the default application contents by pressing shift while you launch the app.

To better understand what I mean by this, it is important to understand that the Brackets application is actually made up of two parts:

  • On the one hand, you have the Brackets shell built with the Chromium Embedded Framework, which executes local web content within a native desktop application shell.
  • On the other hand, you have local web content such as HTML, CSS, and JavaScript files, which are the Brackets editor source code.

By default, the Brackets shell executes the web files stored within the application content folder, which was created when the application was installed. It is not recommended that you  edit code directly from this folder, however. As a result, the native application has the capacity of running from within a different source folder by pressing and holding the Shift key while launching the app. Alternatively, you can use the setup_for_hacking script included under the tools folder of the application source code. You can get this script in from the article, How to Hack on Brackets, on GitHub.

Using an extension template

While you can of course write an extension from scratch, it's preferable to start with a template. Several options are available for you to choose.
A typical way to begin with extension development is to copy and paste an existing extension relatively close to what you want to achieve. This is a valid way to get started, but keep in mind that not all extensions are up to date, and that not all necessarily showcase the latest best practices. Also, some extensions can be really hard to read, especially if you're new to extension development.

Alternatively, you can use the Brackets Extension Toolkit, which provides you with a dedicated template, which you can just drag and drop to the src/extensions/dev folder. The toolkit also comes with  heavily commented code to guide you through your first development experience of extensions, and the toolkit also provides related helper tools.

Whatever option you choose, once you're relatively comfortable, I recommend storing your own custom template in the src/extensions/disabled folder to access it quickly later. Simply copy it to the user extensions folder.

Introduction to the Brackets extension API

If you look at an existing extension for the first time, chances are that you'll feel a bit lost. Brackets extensions are JavaScript modules as specified by RequireJS' Simplified CommonJS Wrapper. Understanding JavaScript modules is outside the scope of this tutorial, however, for more information, see Modern Modular JavaScript Design Patterns, by Addy Osmani. For demonstration purposes, let's assume that in its simplest form, an extension would look like the following:

define(function (require, exports, module) { 'use strict'; // Extension code goes here console.log("Extension initialized"); });

All the code within the body of the anonymous function inside the define call executes at application startup.
Of course, most of the time, what you want to build is an extension that makes it possible to execute some code when another part of the application invokes the extension. For example, when a user selects a menu item, this causes your application to execute an action.

You can code this kind of mechanism through commands. You register a command ID with a function so that when the app invokes the ID, a function executes. This is the job of the CommandManager. As with pretty much everything in Brackets, the CommandManager itself is a module. To access other modules from an extension, simply call the dedicated brackets.getModule() method, passing to the method the path to the module relative to the src folder. Notice how the code below does not specify the JS file extension.

var CommandManager = brackets.getModule("command/CommandManager");

To specify to the CommandManager which function to execute, and when, specify the register(name, command_id, function) method. The parameters within this method are as follows:

  • The name parameter is a readable user-friendly name, which is also used as a menu label in the user interface.
  • The command_id parameter is a string to uniquely identify this command. Format it as follows: [author].[my_extension].[menu_name].[my_command_name].
  • The last parameter, function, is the function the method calls when a user selects a menu item in the UI. When a user selects a menu item in the UI, the app automatically calls execute(command_id) method with the corresponding ID, as shown in the following code example.
var COMMAND_ID = "dderaedt.tutorialExt.logHelloWorld.logHelloWorld"; var COMMAND_NAME = "Log Hello World"; function sayHello() { console.log("Hello World"); } CommandManager.register(COMMAND_NAME, COMMAND_ID, sayHello);

At this stage, the extension is functional but will never be called since something must invoke the command ID. To do so, we add a menu item through the Menus module to invoke  the corresponding command ID, resulting in the execution of the function. To do so, we'll first access the Menus module, as follows:

var Menus = brackets.getModule("command/Menus");

Then, we'll get a handle to the menu we want to add our item to (the File menu, in this example).

var fileMenu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);

Finally, we simply add an item corresponding to the command that we wish to trigger, as follows:

fileMenu.addMenuItem(COMMAND_ID);

The resulting code for this Hello World extension is as follows:

define(function (require, exports, module) { 'use strict'; var CommandManager = brackets.getModule("command/CommandManager"); var Menus = brackets.getModule("command/Menus"); var COMMAND_ID = "dderaedt.tutorialExt.LogHelloWorld"; var COMMAND_NAME = "Log Hello World"; function sayHello() { console.log("Hello World"); } CommandManager.register(COMMAND_NAME, COMMAND_ID, sayHello); var fileMenu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU); fileMenu.addMenuItem(COMMAND_ID); });

Editing the current document

Now, to do something slightly more useful, let's pretend we want our extension to generate some code inside the current document.

In Brackets, files opened in the tool are represented as instances of the Document class. To get a reference to the current document (in other words, the file the user currently has open and editing), we need to use the DocumentManager module. First, we must get a reference to this module, which is inside the document folder.

var DocumentManager = brackets.getModule("document/DocumentManager");

Now, starting from the code in the previous section, rename the sayHello() function to addSomeText().

The first thing we'll need to do inside this function is get a reference to the current document.

var currentDoc = DocumentManager.getCurrentDocument();

Now you can use the Document API, which can help you work with the text content. Here are some of the available methods:

  • getText() returns the whole text content
  • setText() set the whole text content
  • getRange(start, end) returns part of the text content
  • replaceRange(text, start, end) replaces text in a given position

Note that the position in the text (such as the start and end parameters above) are expressed through a position object, which contains two properties: line, the line number, and ch (the character number).

In the following scenario, pretend that we want to generate a one-line comment at the location of the current cursor position. Since the Editor object manages code editing, you must get access to the current editor instance as returned by the EditorManager.getCurrentFullEditor() method. So after you make sure to import the corresponding module, as follows:

var EditorManager = brackets.getModule("editor/EditorManager");

You can access the editor for the current document, as follows:

var editor = EditorManager.getCurrentFullEditor();

Finally, you can then use the editor to do all sorts of operations related to text selection, such as:

  • getSelectedText()
  • setSelection(start, end)
  • selectWordAt(position)
  • getCursorPos()

Now that you have access to all you need, you can rewrite the addSomeText() function, as follows:

function addSomeText() { var currentDoc = DocumentManager.getCurrentDocument(); var editor = EditorManager.getCurrentFullEditor(); var pos = editor.getCursorPos(); currentDoc.replaceRange("//Black magic. Do not modify EVER", pos); }

Where to go from here

Of course, such simple examples will only get you so far. You'll quickly need to learn more about the APIs exposed by other modules. The following are some useful resources to learn more about it:

  • Brackets' source code itself is, of course, the ultimate and only 100% reliable source of information. If you installed the Brackets extension toolkit, simply select Help > Open Brackets src. Start by taking a look at Document, Editor, EditorManager, FileUtils and of course all the default extensions.
  • The Brackets wiki is full of useful information. In particular, the How to write extensions page covers the basics you should know about. The Brackets extension toolkit includes a shortcut to this wiki under the Help menu.
  • If you intend to make an extension that edits the code for the current document, it's a good idea to get familiar with CodeMirror, the project responsible for the underlying code editing logic.
  • To understand how Brackets works at a higher level, learn more about the Brackets general architecture in the article, An overview of Brackets code architecture.
  • Finally, if you plan to include some UI in your extension, be sure to check the Extension UI Guidelines draft on the Brackets wiki.

Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License+Adobe Commercial Rights

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

 

Products

  • Adobe Creative Cloud
  • Creative Suite
  • Adobe Marketing Cloud
  • Acrobat
  • Photoshop
  • Digital Publishing Suite
  • Elements family
  • SiteCatalyst
  • For education

Download

  • Product trials
  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR

Support & Learning

  • Product help
  • Forums

Buy

  • For personal and professional use
  • For students, educators, and staff
  • For small and medium businesses
  • Volume Licensing
  • Special offers

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2013 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy | Cookies

Ad Choices

Reviewed by TRUSTe: site privacy statement