Beyond debugging and auto-building, I’ve never used an IDE. I’ve been a stalwart–nay, evangalistic–TextPad user for much of that time. Unfortunately, the developers of TextPad are notoriously non-communicative, and the current version has basically been the same for about ten years. For me, the only major improvement during all this time, has been changing its regex engine to a POSIX-y like thing to a truly Perl-compatible Boost (ignoring its look-behind issues).

Updates: 2/9/2015: Added sftp-project-file tip to first-tips

1/8/2015: Added command for displaying current file in sidebar directory tree to first-tips.

10/3/2014: Added SmartCursor plugin to TextPad section

What TextPad does well, it does really well:

Cheap license

Rarely crashes

Syntax highlighting

Large file handling

Regex (including their excellent WildEdit product)

Workspaces

Block-selection mode

And especially: Fast key-driven navigation around and within open files

It’s also missing basic features found in lots of other editors:

It’s Clip Library is a poor replacement for true auto-completion.

No workspace-specific configuration, and no way to associate macros or clips to specific syntaxes.

No code folding (another post)

No live bracket or tag highlighting (although you can match a single bracket by hitting a key-command), and no bracket completion (typing an open paren, quote, curly-brace, etc., automatically prints the close character after the cursor).

Although you can call an external application via the Tools menu, it can’t be properly "extended", such as with plugins or extensions.

No inline spell checking

No UNICODE support

But most of all:

Macros that are uneditable (so recording them is stressful), and whose key-commands are completely obliterated–all of them–when you rename or delete any single macro file, either directly in Windows Explorer (which you "shouldn’t" do), or even in TextPad’s built-in macro editor. Worst of all, you’re only allowed to have sixty-four of them.

When macros work, they are super-fast and invaluable. They don’t need to be “upgraded” with if-logic or loops or anything else–they just need to be editable. The point is not to have perfect, uber-functional macros–the point is to make it easier to automate TextPad–but all these issues discourage macro development. While I can already automate most of TextPad, it can only be fast when the critical pieces are recorded as TextPad macros.

Things TextPad users will love in Sublime Text 3

In addition to the above basic features, Sublime has

Multi-cursors

When I first heard about Sublime’s multi-cursors, I assumed it was a gimmick, cumbersome, and sure to slow things down. But it’s not, it’s not, and it doesn’t. It’s a blazing-fast miracle. A short demonstration:

Here’s a more thorough look.

More robust project management

TextPad has workspaces, which remember the currently-open files, including cursor positions and bookmarks. Sublime also has workspaces, but they each exist in a "project". A project is a saved set of folders which can contain zero or more workspaces. A project can also have its own settings overrides, and can automatically hide files and folders based on wildcards. Watch a video demo.

Although a project behaves just like a workspace, it’s much more than that, and you should almost always create a project and then a workspace, before proceeding. Creating a new project should not happen very often.

Sublime indexes all the files in a project’s folders, so they can be used by the amazing

Go to anything dialog

The go-to-anything dialog only knows about the files existing in a project. That’s important.

There’s also a corresponding go-to-project dialog (a dialog is called an "overlay" in Sublime).

The command palette

Nearly complete and trivial access to hundreds of commands with a few key presses. You don’t need to remember anything.

The minimap

Instead of a vertical scrollbar, you get this:

Things TextPad users will miss

Learning the advanced concepts in Sublime is not easy. All configuration is done by manually editing JSON files and, although there is a lot of documentation (official and unofficial), it’s not enough–particularly if you want to develop plugins.

Sublime’s macros don’t record anything in the find or replace dialogs. (I haven’t used it, but the RegReplace plugin is supposed to fill this gap).

In TextPad, selecting a word, and then pressing find-next or find-prev sets that word as the current search term. Even if the selection is undone, the search-term remains. In Sublime, there are multiple kinds of "find-next/prev" commands, and they sort of work together, and they sort of don’t, and it’s confusing.

TextPad optionally resets the undo buffer at save, so you can no longer undo or redo. Sublime allows you to undo "through" saves, without any indication of the point at which the save occurred . So you save, then press redo and undo a bunch of times, and there’s no way to know where you started. In fact, saving, then immediately pressing undo, then redo, just once, marks the document as unsaved. You lose track of things, and there is no way to stop this behavior.

. So you save, then press redo and undo a bunch of times, and there’s no way to know where you started. In fact, saving, then immediately pressing undo, then redo, just once, marks the document as unsaved. You lose track of things, and there is no way to stop this behavior. TextPad has separate commands for go-to-line-start and go-to-first-non-whitespace-character-in-the-line (“soft” line start). Sublime has a single command that toggles between “hard” and “soft”. Two-thirds of the time I want to go to hard-start, and I wish the commands were separate.

If the cursor happens to not be next to a bracket, TextPad’s match-bracket command finds the next open bracket. In the same situation, Sublime does nothing.

TextPad is much smarter with cursor placement

Update: 10/3/2014 The "first" behavior is emulated properly by the SmartCursor plugin. The second behavior is not (I’d say add your comment to this GitHub feature request, but the author’s abandoned it, so it looks like you’ll have to fork it instead). This plugin was actually created in reaction to former TextPad users. Unfortunately, it’s not in Package Control, but manual installation works: Download the zip from GitHub (on the bottom-right of this page).

Extract the files onto a temporary folder.

Go into the folder containing the files.

Select those files and create a new zip-file called SmartCursor.sublime-package , and save it into the Packages folder.

, and save it into the folder. Add these key-bindings to your user-bindings file ( Preferences > Key Bindings - User ). I only use (only added) the plain up and down version, not the alt+ version.

This seemingly small and subtle thing is actually what I miss most most. TextPad is much smarter about where to place the cursor when pressing the up and down keys.

First, place your cursor here, either with the keyboard or mouse:

Type “Hello”:

And then press the down arrow. Sublime takes you here:

TextPad takes you here:

This makes it much much easier to do common things on contiguous lines, such as populate lists with unique values. It remembers where you originally placed the cursor, or where you started typing (after navigating around with arrows).

The second part of this is that, when clicking outside of the right margin, the remembered position is where you click the mouse, not where the cursor is actually placed. So the cursor goes to the end of the line, as you expect

But when you press down, Sublime goes here

And TextPad goes here

Which makes it much easier to edit contiguous ends-of-lines with unique information.

(In both situations, in TextPad, clicking the right or left arrow resets the position. Vote for this to be implemented into Sublime.)

Some first tips for new Sublime Text 3 Users

Install Will Bond’s Package Control and browse the available packages.

Create an account on Tuts Plus and watch Jeffrey Way’s Sublime tutorial.

De-clutter the syntax menu, on the bottom-right of the status bar, by disabling unused or won’t-be-used-for-a-while syntaxes. Do this in the command palette with "Package Control: Disable Package"

Snippets and autocompletes are pretty much equal. A snippet can have multi-line text without special characters such as '

' , '\t' , and '\"' , but can only have one item per file. An autocomplete file can have multiple snippets, one per line, but must have those special characters.

, , and , but can only have one item per file. An autocomplete file can have multiple snippets, one per line, but must have those special characters. Follow this tip for highlighting the active tab.

When selecting multiple paragraphs, and then setting a bookmark, only the first paragraph is marked. To mark all of them, first split the lines with ctrl+shift+L (as demonstrated in the multi-cursor video). To select all bookmarks, hit alt+f2 (“select_all_bookmarks”), and then ctrl+L .

(as demonstrated in the multi-cursor video). To select all bookmarks, hit (“select_all_bookmarks”), and then . Sublime’s "build" system does nothing more than call an external application (one per tool). It’s assumed you’ll be using it to build something, but it could just as easily execute an unrelated script or application.

Add this command to your user key-bindings file (Preferences > Key Bindings – User), to display the current file in the sidebar tree:

{ "keys": ["ctrl+alt+b"], "command": "reveal_in_side_bar"}, (I have ctrl+b for toggling the sidebar.)

If you work on a remote drive that is mapped with SFTP, do not put the sublime-project on the remote drive (because loading that project is now doubly slow: first to opening the project file, second to opening the files in the project). Instead, put the project file on a local drive. If the project files need to be checked into a git repository–which is on the sftp drive–then make a Windows shortcut from local directory (in which the project file exists) to the remote directory (name it project_name.sublime-project_q_drive.lnk , so it’s always right next to it). Any changes you make, copy it to the sftp drive by dragging it to that link.

Scopes

Wherever you see "scope" in a configuration file, such as in snippet and autocomplete files, it defines which syntaxes should be affected. To affect all files, use

"scope": "source, text",

For only Java code:

"scope": "source.java",

For Java and JavaScript:

"scope": "source.java, source.javascript",

In all of my autocomplete files, I have this:

//"scope": "text, source", "scope": "text.plain", //The below autocompletes should only work in plain-text files (*.txt)

So I can move the comment slashes up or down to test the autocompletes in the autocomplete file itself, or set it back to "live mode".

Here’s a hack I came up with for sub-scopes, when, for instance, you want Django autocompletes to not display when you’re working on non-Django Python code.

Customizing individual configuration settings

Review the default configuration file ( Preferences > Settings - Default ), which is well documented. To change any of these values, you must do so in your user config file ( Preferences > Settings - User ). Do not edit the default settings file, and do not move or rename your user-settings file. For example, to change this to true

// Show folders in the side bar in bold "bold_folder_labels": false,

Duplicate it to your user-config file, and then change false to true . (Make sure each value in this file is separated by a comma, and that the last value does not end with a comma). Save the file, and the setting immediately changes. (See the bottom for my full configuration file.)

To set your own key-commands, follow the same process with Preferences > Key Bindings . Your user-bindings file must also not be moved or renamed.

Packages

A *.sublime-package file is just a zip file. You can change it to *.zip if you like (but Sublime won’t recognize it, so don’t), or directly expand it with something like 7-Zip.

Critical packages

FindKeyConflicts: To determine why your key commands are not working as you expect. I enable this package only when needed.

RegReplace for scripting a sequence of replacements.

The amazing Emmet, for easy creation of html and css. I wrote about this in a previous post.

PackageResourceViewer to quickly view another package’s various resource files, such as its settings or key bindings.

Alignment, so this can become this:

Other favorite packages

DPaste Sublime to create a new dpaste entry from the selection. It’s fast, and the url is placed in the clipboard. (If you’re on Windows, there’s also the non-Sublime EasyImgur)

SublimeLinter and all its language-specific sub-packages (such as for Python, Java, and JavaScript–at least one of which is required), to warn you about errors while you type. If you’re developing Sublime Plugins, you’ll need to do something before it’ll recognize Sublime’s packages. Check out my answer in this Stack Overflow question

AdvancedNewFile, an innovative alternative for creating-and-then-saving a new document. (It works especially well when you have some base directories set up as auto-completes in an external, non-Sublime auto-completion/scripting tool, such as PhraseExpress or Macro Scheduler.)

My configuration file

Scroll down for my favorite syntax file.

{ /* DO NOT WASTE YOUR TIME DOCUMENTING OR ORGANIZING THIS FILE. It's overwritten when one of the automatically-updated values (in the bottom section) are changed, and all comments are obliterated. Up-vote this request (maybe even leave a comment!) to get it fixed: http://sublimetext.userecho.com/topic/205068-keeps-comments-and-layout-in-user-preferences-file/ --- This file: C:\Users\jeffy\AppData\Roaming\Sublime Text 3\Packages\User\Preferences.sublime-settings (which is opened with Preferences > Settings - User) All settings in this file override those in C:\Users\jeffy\AppData\Roaming\Sublime Text 3\Packages\Default\Preferences.sublime-settings (which is opened with Preferences > Settings - Default) --- Aside from the bottom section, all values remain unchanged, unless you manually change them by directly editing this file. --- (Single-line comments are duplicated from the default settings file. Multi-line comments are written by me.) */ // If true, the copy and cut commands will operate on the current line // when the selection is empty, rather than doing nothing. "copy_with_empty_selection": false, // Always visualise the viewport on the minimap, as opposed to only // showing it on mouse over "always_show_minimap_viewport": true, // Save via writing to an alternate file, and then renaming it over the // original file. /* REQUIRED to prevent failure when saving documents onto a remote machine, mounted as a lettered Windows drive, via SFTP Net Drive. Unfortunately, it's *only* required for the remote drive. Vote to make this setting filtered by drive: http://sublimetext.userecho.com/topic/516558-/ */ "atomic_save": false, // The delay, in ms, before the auto complete window is shown after typing "auto_complete_delay": 100, // Controls what scopes auto complete will be triggered in "auto_complete_selector": "text, source", // Show folders in the side bar in bold "bold_folder_labels": true, // Hides the fold buttons unless the mouse is over the gutter "fade_fold_buttons": true, // These settings control the size of the caret "caret_extra_bottom": 5, "caret_extra_top": 4, "caret_extra_width": 0, // Valid values are "smooth", "phase", "blink" and "solid". "caret_style": "phase", // Determines what character(s) are used to terminate each line in new files. // Valid values are 'system' (whatever the OS uses), 'windows' (CRLF) and // 'unix' (LF only). "default_line_ending": "unix", // Set to true to draw a border around the visible rectangle on the minimap. // The color of the border will be determined by the "minimapBorder" key in // the color scheme "draw_minimap_border": true, // Spacing between the gutter and the text "margin": 0, // Set to false to not highlight angle brackets. This only takes effect if // match_brackets is true "match_brackets_angle": true, // Columns in which to display vertical rulers "rulers": [ 25, 50, 75, 100, 125, 150, 175, 200 ], // Set to false to disable scrolling past the end of the buffer. // On OS X, this value is overridden in the platform specific settings, so // you'll need to place this line in your user settings to override it. "scroll_past_end": false, // Set to true to turn spell checking on by default "spell_check": true, // The DEFAULT number of spaces a tab is considered equal to "tab_size": 3, // Set to true to removing trailing white space on save "trim_trailing_white_space_on_save": true, // Disables horizontal scrolling BY DEFAULT, if enabled. // May be set to true, false, or "auto", where it will be disabled for // source code, and otherwise enabled. "word_wrap": "true", // Makes tabs with modified files more visible "highlight_modified_tabs": true, /* ---Manual-change-only values above--- ---Manual- and auto-changed values below--- The above settings only change if you manually edit them. The below settings can be manually edited. they are als automatically updated when you do certain things elsewhere in Sublime. For example, if you click ctrl+[plus-sign] to increase the font size, this file is overwritten--AND ALL YOUR ORGANIZATION AND COMMENTS IN THIS FILE GO POOF. */ // Sets the colors used within the text area "color_scheme": "Packages/User/Mud_20140928 (SL) (SL).tmTheme", // Note that the font_face and font_size are overridden in the platform // specific settings file, for example, "Preferences (Linux).sublime-settings". // Because of this, setting them here will have no effect: you must set them // in your User File Preferences. "font_size": 10, // List any packages to ignore here. When removing entries from this list, // a restart may be required if the package contains plugins. /* I've disabled all syntaxes I never use, or am not currently using. It's also a good diagnostic technique to disable packages one-by-one, to see if a specific package is the cause of your problem. Packages can be disabled one-by-one via Command Palatte > Package Control: Disable Package or by manually entering their name (I think it's the name of its *.sublime-package file). */ "ignored_packages": [ "Lisp", "Javatar", "YAML", "R", "Makefile", "LaTeX", "Graphviz", "OCaml", "FileDiffs", "RegReplace", "BracketHighlighter", "Objective-C", "Go", "LESS-build", "LiveReload", "ActionScript", "Scala", "ASP", "Lua", "Haskell", "Default", "PHP", "Color Highlighter", "Google Search", "CSS", "Pascal", "D", "Ruby", "Matlab", "Python PEP8 Autoformat", "SublimeLinter-html-tidy", "Groovy", "Postgres PL pgSQL", "AppleScript", "LinkOpener", "GotoDocumentation", "C++", "C#", "Alignment", "Markdown Preview", "AAAPackageDev", "SublimeLinter-javac", "SublimeLinter-csslint", "Erlang", "Vintage", "Textile", "Rails", "TCL", "W3CValidators", "Clojure" ] }

My favorite theme

This is Mud by Dayle Rees, which I’ve tweaked with the online theme editor. Save it as MyMud.tmTheme in your User folder, and then select it in Preferences > Color Scheme > User .

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>gutterSettings</key> <dict> <key>background</key> <string>#49483E</string> <key>divider</key> <string>#75715E</string> <key>foreground</key> <string>#75715E</string> </dict> <key>name</key> <string>Monokai</string> <key>semanticClass</key> <string>theme.dark.monokai</string> <key>settings</key> <array> <dict> <key>settings</key> <dict> <key>background</key> <string>#272822</string> <key>caret</key> <string>#F8F8F0</string> <key>foreground</key> <string>#F8F8F2</string> <key>invisibles</key> <string>#49483E</string> <key>lineHighlight</key> <string>#405939</string> <key>selection</key> <string>#711c60</string> </dict> </dict> <dict> <key>name</key> <string>Comment</string> <key>scope</key> <string>comment</string> <key>settings</key> <dict> <key>foreground</key> <string>#819876</string> </dict> </dict> <dict> <key>name</key> <string>String</string> <key>scope</key> <string>string</string> <key>settings</key> <dict> <key>foreground</key> <string>#E6DB74</string> <key>fontStyle</key> <string> italic</string> </dict> </dict> <dict> <key>name</key> <string>Number</string> <key>scope</key> <string>constant.numeric</string> <key>settings</key> <dict> <key>foreground</key> <string>#e6bea2</string> <key>background</key> <string>#000000</string> </dict> </dict> <dict> <key>name</key> <string>Built-in constant</string> <key>scope</key> <string>constant.language</string> <key>settings</key> <dict> <key>foreground</key> <string>#b993ff</string> </dict> </dict> <dict> <key>name</key> <string>User-defined constant</string> <key>scope</key> <string>constant.character, constant.other</string> <key>settings</key> <dict> <key>foreground</key> <string>#ae81fe</string> </dict> </dict> <dict> <key>name</key> <string>Variable</string> <key>scope</key> <string>variable</string> <key>settings</key> <dict> <key>fontStyle</key> <string> bold</string> </dict> </dict> <dict> <key>name</key> <string>Keyword</string> <key>scope</key> <string>keyword</string> <key>settings</key> <dict> <key>foreground</key> <string>#f92672</string> <key>background</key> <string>#000000</string> </dict> </dict> <dict> <key>name</key> <string>Storage</string> <key>scope</key> <string>storage</string> <key>settings</key> <dict> <key>fontStyle</key> <string /> <key>foreground</key> <string>#F92672</string> </dict> </dict> <dict> <key>name</key> <string>Storage type</string> <key>scope</key> <string>storage.type</string> <key>settings</key> <dict> <key>fontStyle</key> <string>italic</string> <key>foreground</key> <string>#66D9EF</string> </dict> </dict> <dict> <key>name</key> <string>Class name</string> <key>scope</key> <string>entity.name.class</string> <key>settings</key> <dict> <key>fontStyle</key> <string>underline</string> <key>foreground</key> <string>#A6E22E</string> </dict> </dict> <dict> <key>name</key> <string>Inherited class</string> <key>scope</key> <string>entity.other.inherited-class</string> <key>settings</key> <dict> <key>fontStyle</key> <string>italic underline</string> <key>foreground</key> <string>#A6E22E</string> </dict> </dict> <dict> <key>name</key> <string>Function name</string> <key>scope</key> <string>entity.name.function</string> <key>settings</key> <dict> <key>fontStyle</key> <string /> <key>foreground</key> <string>#A6E22E</string> </dict> </dict> <dict> <key>name</key> <string>Function argument</string> <key>scope</key> <string>variable.parameter</string> <key>settings</key> <dict> <key>fontStyle</key> <string>italic</string> <key>foreground</key> <string>#FD971F</string> </dict> </dict> <dict> <key>name</key> <string>Tag name</string> <key>scope</key> <string>entity.name.tag</string> <key>settings</key> <dict> <key>fontStyle</key> <string /> <key>foreground</key> <string>#F92672</string> </dict> </dict> <dict> <key>name</key> <string>Tag attribute</string> <key>scope</key> <string>entity.other.attribute-name</string> <key>settings</key> <dict> <key>fontStyle</key> <string /> <key>foreground</key> <string>#A6E22E</string> </dict> </dict> <dict> <key>name</key> <string>Library function</string> <key>scope</key> <string>support.function</string> <key>settings</key> <dict> <key>fontStyle</key> <string /> <key>foreground</key> <string>#66D9EF</string> </dict> </dict> <dict> <key>name</key> <string>Library constant</string> <key>scope</key> <string>support.constant</string> <key>settings</key> <dict> <key>fontStyle</key> <string /> <key>foreground</key> <string>#66D9EF</string> </dict> </dict> <dict> <key>name</key> <string>Library class/type</string> <key>scope</key> <string>support.type, support.class</string> <key>settings</key> <dict> <key>fontStyle</key> <string>italic</string> <key>foreground</key> <string>#66D9EF</string> </dict> </dict> <dict> <key>name</key> <string>Library variable</string> <key>scope</key> <string>support.other.variable</string> <key>settings</key> <dict> <key>fontStyle</key> <string /> </dict> </dict> <dict> <key>name</key> <string>Invalid</string> <key>scope</key> <string>invalid</string> <key>settings</key> <dict> <key>background</key> <string>#F92672</string> <key>fontStyle</key> <string /> <key>foreground</key> <string>#F8F8F0</string> </dict> </dict> <dict> <key>name</key> <string>Invalid deprecated</string> <key>scope</key> <string>invalid.deprecated</string> <key>settings</key> <dict> <key>background</key> <string>#AE81FF</string> <key>foreground</key> <string>#F8F8F0</string> </dict> </dict> <dict> <key>name</key> <string>SublimeLinter Warning</string> <key>scope</key> <string>sublimelinter.mark.warning</string> <key>settings</key> <dict> <key>foreground</key> <string>#DDB700</string> </dict> </dict><dict> <key>name</key> <string>SublimeLinter Gutter Mark</string> <key>scope</key> <string>sublimelinter.gutter-mark</string> <key>settings</key> <dict> <key>foreground</key> <string>#FFFFFF</string> </dict> </dict><dict> <key>name</key> <string>SublimeLinter Error</string> <key>scope</key> <string>sublimelinter.mark.error</string> <key>settings</key> <dict> <key>foreground</key> <string>#D02000</string> </dict> </dict></array> <key>uuid</key> <string>D8D5E82E-3D5B-46B5-B38E-8C841C21347D</string> <key>colorSpaceName</key> <string>sRGB</string> </dict> </plist>

[Posts: TextPad Reddit, Sublime]