Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From \$16.50/m

# Customizing FoldingText

Difficulty:IntermediateLength:LongLanguages:

The Mac has many applications that are minimalistic: programs that present the minimum number of possible options whilst still retaining functionality. There are many minimalist text editors. FoldingText stands out as different.

In this tutorial, I’ll introduce you to the FoldingText editor and show you how to extend it with:

• Snippets
• Keyboard Shortcuts
• Commands
• Scripts
• Extensions
• Themes

## Overview

Not only is FoldingText minimalistic in design, but also in file format: it only uses plain text files. All formatting is done with Markdown with a twist: You can mark any area as having special formatting and functionality by adding an extension to the end of a header line.

When you launch FoldingText, you are presented with a plain window. This clean, minimal graphics interface helps to focus on the writing and not on the program.

As you type Markdown formatting commands, the text is highlighted and extra things—such as addresses in a link—are hidden. In the above example, you can see the Markdown for an anchor while the cursor is still on it.

When moving to a new line, or adding another character, FoldingText hides the address details so that you only see the title.

Now edit the Markdown text to be a header and click on the # symbol beside Introduction. This quickly folds the text in that section up to the next header. The folded text symbol is shown in the upper left corner. Also, it adds a  (an ellipsis) to the end of the folded section. Clicking either the triangular symbol at the top left corner or the at the end of the folded section will unfold that text.

The real innovation found in FoldingText is the extensions. FoldingText comes with two extensions pre-built in: todo, and timer

The todo extension gives you a multi-level todo list with checkboxes.

The timer extension gives you timers to alert you. The timers work as countdown timers. If you make a list with times on the lines, it will countdown the topmost time, message you, and start on the next time. You can create as many extension areas in one document as you need.

As you can see in the todo list example, you can tag any line in FoldingText. The tag syntax is @ and some text. FoldingText uses some tags for special formatting (ie: the cross-out on the @done tag).

FoldingText has a command palette, similar to that made popular with Sublime Text. When you press Command-Quote, a list of all available commands will appear. It does not have that many commands built in so I’ll show you how to add some.

## Plug-in Manager

From the FoldingText Main Menu, select Plug-In Manager.

The lefhand panel shows a list of each and every plug-in installed. Clicking on one shows its description on the right side panel. All of these extensions are downloadable from FoldingText’s website by clicking the Find Plug-Ins button.

To create a plug-in, go to the plug-in directory by selecting the Open Plug-Ins Folder button at the lower right.

This opens Finder in the directory that contains all of the plug-ins. Create a directory called MySnippets.ftplugin. In that directory, create the files main.js and package.json. These are the minimum files needed for a plug-in.

FoldingText extensions are coded with JavaScript. The package.json file gives FoldingText information to display in the Plug-In Manager.

In the package.json file, place the following:

This tells FoldingText about the plug-in’s name, version, description, homepage of the author, and what versions of FoldingText or TaskPaper to use. Only FoldingText 2.0.0 or TaskPaper 3.0.0 and greater support plug-ins.

## Snippets

To add snippets to FoldingText, add the following lines to the main.js file:

All extensions files begin with the define() function. That function takes a function that when called will accept three objects: require, exports, and module. The require object allows you to acquire any library like the Extensions library to add things to FoldingText.

To create snippets, use the addSnippet function of Extensions. It expects a json key—value array. The key will be the expansion text and the value evaluates to text to replace the key. The expansion side can be text or a function.

I defined two snippets here: ;tut and ;code. When you type either text followed with a tab, the text will get expanded accordingly. The ;tut snippet gives me a bare minimum tutorial layout. The ;code snippet gives me a fold-able code block so that I can tuck away the code before getting a word count of my tutorial.

## Keyboard Shortcuts

To add keyboard shortcuts, you use a hook into starting the editor engine. Just after the code for snippets, add this code:

The Extensions.addInit() function adds the function to the initialization process for the editor. The editor object will be passed to the function. Using the editor.addKeyMap() function, a keyboard shortcut is easily added to the editor.

This function expects a json key—value list with the key being the keyboard shortcut and the value is the name of the function to execute. Since I use code blocks often, I made a shortcut for it.

## Commands

If you are good at JavaScript programming, creating your own commands are easy. Any command made will be available in the command palette. I work with many todo lists and often moving items back and forth. You can automate that with the following code:

The Extensions.addCommand() function is used to create new command. In this code example, the commands are: moveTDNext, and moveTDPrevious. moveTDNext moves the current todo item the cursor is on to the next todo list. moveTDPrevious does exactly the opposite.

The Extensions.addCommand() takes a json list with three elements: name, description, and performCommand. The name item is a string giving a name to the command with no spaces. The description is a string describing what the command does. This description will be shown in the command palette. The performCommand is a function that will accept an editor instance and return nothing.

In these functions, I use the editor API to move to the header of the current todo list, move to the next or previous list, and append the item to that list. The API is too large to describe for this tutorial. All of the API Documents are accessible from the Help > Software Development Kit menu.

The Documentation link will open the HTML documentation in the default web browser. The Run Editor link will start FoldingText instance with the code debugger enabled. The Run Specs link will run all specifications on FoldingText and each of it’s extensions.

## Scripts

In FoldingText terminology, a script is using AppleScript to inject a JavaScript function into FoldingText to perform an action. FoldingText adds two keywords in it’s AppleScript dictionary: evaluate and debug. Both evaluate and debug take a JavaScript and parameters for input, but evaluate runs it and returns the result while debug launches the script into the debuger window.

A good example would be getting a list of tags from the top most window. Open the AppleScript Editor with this code:

This tells the first FoldingText document to evaluate a JavaScript function that accepts an editor instance. The function gets the tags from FoldingText editor object and returns them sorted.

When this script is executed, the result is the tags in the current document. Here the current document has the tags done and next. I use this script along with others in an Alfred workflow. You can get the workflow from the download for this article.

## Extensions

An extension for FoldingText adds new functionality to the editor. A math block that allows some calculations to be made would be really nice to have.

Create a new extension called imath.ftplugin. In the package.json file, add the following:

This gives all the information needed to describe the extension.

For doing the actual math, the Math.js framework is great. Download that library and place it in the directory with the main.js file.

In the main.js file, add this code:

This extension starts just like the snippets extension. After getting a reference to the Extensions library, require is used to load the math.js library from the extensions folder. To load local libraries, require uses a relative path to the full name of the library file.

Next, Extensions.addMode() function is used to add a new mode with the name imath. This function accepts a json list with the key name set to the name of the new extension: imath. This allows a block of text to be defined as containing math for the imath extension to evaluate.

Some helper functions are needed. Add this code after the Extensions.addMode() function:

The function inMathArea() takes a node and determines if that node is in a math text area by calling node.modeContext(). Since processing blank lines results in nothing, it also checks for that condition.

The Calculate() function will call the Math.js library to evaluate the string given. If the library throws an exception, it returns a question mark. The string to evaluate will be the whole line except for the last two characters.

The last thing to do is to hook into the routine that is called whenever the user changes the text. Add these lines of code after the Calculate() function:?

The Extensions.addTreeChanged() function is used to hook in to the text change routines. FoldingText keeps a tree structure of every line of text in the document. When the tree structure is changed, every function registered will be called with the editor instance and a structure of deltas.

The function loops through every update delta and addition to determine if it is in the imath area using the inMathArea() function. If it is and the last two characters in the line are =>, then the ProcessMathNode() function is called. The ProcessMathNode() function calls a couple of helper functions to climb back up the document to get any relevant imath sections.

If a section is hidden, then it is ignored. That way different scenarios can be used and evaluated. Once all relevant imath sections are processed, the whole is given to Calculate() to evaluate the results. The results are added to the end of the line with proper spacing and sent back into the tree. The math extension will only calculate right after the user types in a =>.

Once you save the file, you will have to reload FoldingText. Try out the lines above and see the results. Just remember: to re-evaluate an expression you have to delete the previous results. The new result will be calculated and returned to the document.

## Themes

FoldingText makes use of Less.js to style it’s user interface. FoldingText is really a web browser without all the web browser user interface.

There are two ways to change how FoldingText looks: add Less.js statements to the user.less file that is one directory up from the Plug-Ins directory, or add it to a style.less file in any plugin folder.

For example, open Finder in the Plug-Ins folder and go up one directory. There, open the user.less file. You will see:

This is some of the defaults that you can change. I prefer larger text, so remove the comments indicator for the @fontSize variable and set it to 12pt. When you save and reload FoldingText, all text will be based at 12pt size.

If there is something you want to change that is not listed in the file, open the Debugger to browser the DOM. Find what you want, get it’s ID, and change it in the Less.js file.

## Running the Editor’s Debugger

While making all these extensions, you will need to debug your code or browse the DOM to find what you need to change. FoldingText makes that real easy.

When you select the Run Editor link on the Software Development Kit, you get the FoldingText Editor with controls for debugging. Selecting the Inspector in the tool bar shows the standard Safari developer tools. This gives you all the tools you will need to debug anything in FoldingText. You can check Apple Safari’s Developer Guide for information about using the developer tools.

## Conclusion

In this tutorial I have shown you how to create snippets, keyboard shortcuts, commands, scripts, extensions, and themes for FoldingText. Since it is all based on Web browser technology, the learning curve is easy. With all the wealth of JavaScript libraries available, there is almost no limit to what you can do with FoldingText.