Archive

Posts Tagged ‘textmate’

Your update is not more important than my work

March 5, 2015 Leave a comment

I love TextMate, but I just saw the most user-hostile, infuriating thing. I’m doing work when all of a sudden I get the pop-up:

 

TextMate forced update

TextMate forced update

It closed my document (thankfully giving me a chance to save), and now the program refuses to launch until updated.

sigh

Advertisements

TextMate Grammar Editing Tip – “Edit in TextMate”

April 12, 2011 Leave a comment

I wrote previously about creating language grammars in TextMate and I’ve been doing a bit more of this lately. One thing that makes this process a lot less painful is following the advice from the official Textmate book and installing the “Edit in TextMate” bundle.  Do this by going to Bundles->TextMate->Install “Edit in TextMate”, and follow the instructions.  After rebooting TextMate, you can press ⌃⌘E while within the Edit Grammar file to open a live copy of the document in a syntax highlighted textmate window.  Every time you hit Save, the changes are pushed back to the unstyled document pane.  This drastically speeds up development, as you no longer have to copy and paste text between the windows, but instead can hit save any time you want to try your changes out.

Live updating, syntax highlighted language grammar

Live updating, syntax highlighted language grammar

Pandoc – an essential tool for Markdown users

March 23, 2011 6 comments

Pandoc is a great tool to convert between various text based formats. For instance, with a single input Markdown file, I can generate an HTML page of that document, a LaTeX document, and a beautifully typeset PDF.

I had troubles installing it on Mac OSX via MacPorts; a simpler solution for me was to download and install the Haskell package and then use the commands:

cabal update
cabal install pandoc

This assumes, of course, that the cabal program that the Haskell package installs is accessible from your path.

The next step for me was to install the excellent Pandoc TextMate bundle. This gives you the standard things like syntax highlighting of your document, as well as a variety of useful snippets. For instance, when I am in Pandoc mode and press ⌃ ⌥ ⌘ P, I get the following popup from which I can easily choose options via mouse or keyboard:

Easy way to preview your document in various output formats

Easy way to preview your document in various output formats

Before you can start using the Pandoc TextMate bundle, you must ensure that the Pandoc executable is on the PATH exposed to TextMate, which is different than your global system path. In other words, just because you can execute pandoc in a shell and have it work, this doesn’t mean it will work in TextMate. For instance, on my computer, Pandoc is located in:

$ which pandoc
/Users/ndunn/Library/Haskell/bin/pandoc

Go to TextMate -> Preferences -> Advanced -> PATH and append :/Users/ndunn/Library/Haskell/bin to the end of the PATH variable.

Appending the Pandoc path to the PATH variable

Appending the Pandoc path to the PATH variable

Pandoc makes a few extensions to the Markdown syntax, which I really like. For instance, you can designate a section of text to be interpreted literally by surrounding it with three ~ characters. Furthermore, you can specify what language the source code is in, and the Pandoc converter will syntax highlight it in the final document (assuming the correct extensions have been installed).

I like this setup because it allows you to specify the language of the block of text, which means that you can force TextMate to interpret it the same way. As I’ve blogged about previously, one can add source code syntax highlighting embedded in HTML documents. I added the following lines to my HTML language grammar in order to have a few different languages recognized and interpreted as source code within these delimited blocks.

Here is the relevant section:

    {   name = 'source.java';
            comment = 'Use Java grammar';
            begin = '~~~\s*{.java}';
            end = '~~~';
            patterns = ( { include = 'source.java'; } );
        },
        {   name = 'text.xml';
            comment = 'Use XML grammar';
            begin = '~~~\s*{.xml}';
            end = '~~~';
            patterns = ( { include = 'text.xml'; } );
        },
        {   name = 'source.shell';
            comment = 'Use Shell grammar';
            begin = '~~~\s*{.shell}';
            end = '~~~';
            patterns = ( { include = 'source.shell'; } );
        },
        {   name = 'source';
            begin = '~~~';
            end = '~~~';
            patterns = ( { include = 'source'; } );
        },

(One tricky bit to get used to is that you need to have at least one blank space between surrounding text and a ~~~ delimited block, or else the ~ characters are interpreted as strikeouts through the text.)

Here is a screenshot of this working in TextMate:

Syntax highlighting of sourcecode within the Pandoc document

Syntax highlighting of sourcecode within the Pandoc document

Finally, just to get really meta on you here’s a screenshot of the text of this document

Text version of the document

Text version of the document

followed by a screenshot of the HTML that Pandoc produces: HTML version of the document

followed by a screenshot of the PDF that LaTeX formatted via Pandoc: PDF version of the document

I hope this has piqued your interest in Pandoc. I love the beautiful output of LaTeX but hate working with its syntax. With Pandoc I’m free to compose in Markdown, a language with a very lightweight syntax, and then convert into TeX when and if I want to.

TextMate – Introduction to Language Grammars: How to add source code syntax highlighting embedded in HTML

February 8, 2011 7 comments

I’ve blogged about TextMate a few times in the past, and with good reason – it’s an extremely versatile, light weight, powerful text editor for the Mac. One great feature of TextMate is its extreme customizability. Today I’m going to show how to modify one of the TextMate language files in order to add support for Java code within HTML text.

Why is this useful? My workflow for producing blog posts is often to write the post in TextMate using the Markdown markup language, which I then convert to HTML. WordPress has the ability to syntax highlight and provide a nice monospaced version of sourcecode within a post if it’s delimited by <code></code> tags. While the sourcecode comes out fine in the final post, it would be nice to have the syntax highlighting show up from within the Markdown view (i.e. while I am composing a blog post). Let’s get started by looking at how language grammars work in TextMate.

Introduction to Language Grammar Editing

The language support in TextMate is extremely powerful, but it’s a little complicated to get started. In essence, a language defines a series of rules mapping patterns to scopes. For instance, the Java language grammar defines a scope for comments, a scope for control characters, and so on and so forth. The scope is extremely important for many reasons. A few of them are

  • The scope determines whether text is spellchecked or not (a top level scope of source is not spell checked; one that is text will be)
  • It provides syntax highlighting, as certain scopes are associated with certain colors.
  • Snippets can be targeted to only run when within a certain scope. (See this article on Scope selectors for more.) For instance, all the Java snippets are defined as only being active in the source.java scope.

An example of a Java snippet that's only accessible when the cursor is within something identified as source.java

As an aside, you might wonder why the scope is called source.java as opposed to java.scope. The reason is that some scope selectors can target the more general case (scope), whereas those concerned with java can target the more specific scope (java.scope).

Since someone has already done the hard work of creating a language definition for Java and for creating all of the snippets that support it, we want to leverage this body of work. All we need to do is ensure that text between the java tags is considered to be part of the source.java scope, and everything will just work.

First, let us look at a sample grammar file. Open up the HTML language definition file by going to Bundles -> Bundle Editor -> Edit Languages, or via the shortcut ⌃ ⌥ ⌘L, and choose the HTML option. You’ll be presented with a rather inscrutable, unstyled document to the right. The first thing you should do, and which I found out the hard way, is copy all that text and paste it into a new document.

Edit Languages

Edit HTML language

When you paste the text into the document, the text is unstyled and interpreted as plain text. In order to force TextMate to interpret this as a language grammar, you must click the item in the lower middle that says “Plain Text” and choose “Language Grammar” from the dropdown box. The document should look a lot nicer after this step:

Plain Text
After changing to Language Grammar

Take a look through the grammar, but don’t get bogged down in the details. The important thing to look at is the list of patterns defined. Here’s just a small section:

    patterns = (
        {   name = 'meta.tag.any.html';
            begin = '(]*>)';
            end = '(>()';
            beginCaptures = {
                1 = { name = 'punctuation.definition.tag.html'; };
                2 = { name = 'entity.name.tag.html'; };
            };
            endCaptures = {
                1 = { name = 'punctuation.definition.tag.html'; };
                2 = { name = 'meta.scope.between-tag-pair.html'; };
                3 = { name = 'entity.name.tag.html'; };
                4 = { name = 'punctuation.definition.tag.html'; };
            };
            patterns = ( { include = '#tag-stuff'; } );
        }

This is the first pattern that will attempt to match. You don’t need to understand all of it, but you should understand that the parentheses in the regular expressions denote capturing groups, which are then referenced in the beginCaptures and endCaptures tags. These assign scopes to the various captured groups. Note too that we can recursively include patterns (via the include = '#tag-stuff' line) which assign scope to various parts of the matched text. This allows us to define a pattern one time and reference it in multiple places, which cuts down on code duplications.

If you look through the HTML grammar, you’ll notice that some embedded code is automatically detected and set to have the matching text use the corresponding language:

ruby = {
    patterns = (
        {   name = 'comment.block.erb';
            begin = '';
            captures = { 0 = { name = 'punctuation.definition.comment.erb'; }; };
        },

Here, any times the <%# %> tag pair is seen, the entire block is captured and assigned to the scope punctuation.definition.comment.erb, which has the effect of distinguishing it from surrounding text. You can see this in action in the following screenshot:

comment.block.erb scope

In addition to the fact that the ERB snippet is syntax highlighted, take note of the popup in the screenshot showing “text.html.basic” and “comment.block.erb”. At any point in any TextMate file, you can hit ⌃ ⇧P (Control Shift P) to get the current scope of the cursor. This is extremely useful for debugging why certain elements are not being selected or assigned the scope you think they are.

Adding Java support

While using a TextMate window to edit the grammar is extremely nice, unfortunately you cannot test your changes interactively here. You must copy and paste the contents back to the original grammar window, overwriting the contents, and then press Test. This will reload the grammar and you will see the change reflected in any window using that grammar currently.

With that in mind, let’s add the support for embedding Java within our Markdown blog posts.

The basic pattern is pretty simple:

    {   name = 'source.java';
        comment = 'Use Java grammar';
        begin = '\
';
        end = '\[/sourcecode\]';
        patterns = ( { include = 'source.java'; } );
    }</pre>
</div>
I look for the literal string <code></code> to start the pattern, and then the literal string <code>

to end it. I have to escape the brackets due to the fact that they have a special meaning within regular expressions ([aeiou] matches any vowel, while \[aeiou\] matches the literal string [aeiou]).

By adding this line to the top of the patterns, it is run before any of the others. (Remember, we have to actually add it to the HTML grammar within the Bundle Editor, not just the TextMate window with the grammar inside of it). Once the line is added and you press Test, the Java highlighting beings to work.

Here’s what a snippet of Java embedded in a Markdown blog post looked like without this change:

without language support

And after:

with the language support

Conclusion

Language support in TextMate is a very complex task, and one that cannot be adequately covered in a single post. I’ve shown here how to add a small snippet to the HTML grammar to allow syntax highlighting of sourcecode delimited by special blocks. This technique could be expanded to support any number of other programming languages.

The ability to customize TextMate through editing snippets and language grammars makes it extremely powerful. I hope this has only whetted your appetite to learn more. If it has, please see the macromates site which has more information about this.

Two shortcuts for NetBeans navigation

December 10, 2010 Leave a comment

NetBeans is my Java IDE of choice, and I have written about it a few times in the past.  There are a slew of features to make you more productive and today I will highlight two shortcuts that are essential to efficient navigation.  I will show you how to jump quickly to any file in any open project, and how to search for a string in any file.

Jump to any file in any open project
⌃⇧ O

Ctrl Shift O = Go to File
By typing this shortcut at any time, you launch the Go to File dialog.  This dialog allows you type pieces of any file name, and you will see results returned in near real time.  This is excellent for when you know the approximate name of the file you’re looking for (you can insert a ‘*’ character as a wildcard, so if you know the word ‘foo’ appears somewhere in the word, you would search for *foo.

Search results are returned instantly

This dialog is a great example of incremental search, a UI technique I blogged about previously.  The incremental search is beneficial because it gives you instant feedback on your search query, allowing you to modify it as necessary to find what you’re looking for.
Those of you who use TextMate might recognize this feature; in TextMate this dialog is accessible via ⌘T (Command T).
The difference is that TextMate’s search is faster, and it is more forgiving (you can search for just a few letters in the file you’re searching for and still find it; you don’t need to know the precise name).
In general it’s much faster to search for files than to navigate through the file hierarchies manually.

Search for string

The second shortcut is to search for text in all the open projects (or narrowing it down to a select few files if you prefer).  This command is easily accessible when right clicking on a project node, but it’s accessible any time via keyboard shortcut as well

⇧ ⌘ F – Find in projects
Shift Command F

This one’s pretty self explanatory, but it took me awhile to stumble onto the shortcut, and it’s a pretty helpful one to know.

I hope these two shortcuts make your time in NetBeans a little easier.

How to make git use TextMate as the default commit editor

July 21, 2010 2 comments
git config --global core.editor "mate -w"

Now when you do a git commit without specifying a commit message, TextMate will pop-up and allow you to enter a commit message in it. When you save the file and close the window, the commit will go through as normal. (If you have another text editor you prefer instead, just change the “mate -w” line to the preferred one)

For those curious what the -w argument is about, it tells the shell to wait for the mate process to terminate (the file to be saved and closed). Read this for more information about how to associate TextMate with various other shell scripts and programs.

Categories: textmate, Uncategorized, unix Tags: , ,

TextMate usability flaws

May 24, 2010 20 comments

I’ve posted previously about TextMate, a great text editor for Mac OSX.  While it is one of the best text editors I’ve used due to its simplicity, elegance, and power, there are a few UI features that drive me up the wall, and make it fall short of being perfect.

Tab key behavior

Here I have a bunch of text selected.  What will happen when I hit tab?


If you answered, delete your selection and insert a literal tab, you win the prize.  What happens in Microsoft Word, NetBeans Platform, and any number of other IDEs and text editors?  The text is indented.  This is clearly the better alternative in my mind because it is non-destructive, and you can get the destructive tab with a simple addition of any delete/backspace key before hitting tab.

Furthermore, it’s inconsistent – if I had selected that text and hit quote, I’d have the text surrounded by quotes, not a single quote replacing all my test.  I would argue that it does more harm than good to

To indent the region, you have to do ⌘-]; to unindent you do ⌘-[.  I’m sure there’s a way to remap tab and shift tab to indent the region, but it’s not immediately clear to me how to do that.  If you know how, please comment so people can see.  Every time I switch between Netbeans and TextMate I invariably delete a whole region of text I meant to indent by forgetting to context switch and use ⌘-].  Fortunately TextMate has extremely good undo support, so it’s not the end of the world, but it’s that little bit of friction that slows down work and adds up to frustration over multiple instances.

EDIT: The following sneaks up on me all the time and also is very irksome.  Here’s a rather typical situation:

Before backwards indenting

Here I want to move the block of text backward; I resist the urge to hit shift tab, and instead press ⌘-[.  What happens?  Not what you’d think.

After hitting un-indent

I really cannot think of a valid reason for this behavior; I have the first line selected, but it does not respond to the indentation command.  Very frustrating.

Syntax highlighting with unsaved files

If you are working on an unsaved file, there is no way to tell TextMate to treat it as a file of a certain programming language, and thus which syntax highlighting rules apply.

Why is this irksome?  When I’m writing a blog post, for instance, I have a lot of snippets I compose in TextMate.  In order to get the syntax highlighting to work correctly, I need to save each individual file.

Now, I’m not suggesting TextMate is magical and can read my mind as to what ruleset to apply to an unsaved file.  What I’m suggesting is the addition of a menu that allows you to apply the syntax rules of a given language to the current file, regardless of whether it’s saved or not.  Notepad++, a Windows text editor, has precisely this feature.

EDIT: Thanks to the comment by Marshall, I realize that this complaint is way off base – I didn’t realize where the menu was but it’s there.  Right where it says “Plain text” in the above screen shot, click that and you get a full list of languages to treat the file as.

Tab support

Tab support is abysmal.  There is no support for closing tabs with the middle mouse button, a convention followed by most major web browsers, as well as NetBeans and Eclipse.  Instead, you are forced to click a small close icon on each tab.  Fitts’s Law states that the smaller a button is, the longer it will take a user to navigate to; this is part of the reason that Apple has adopted menu bars at the top of the screen rather than floating with each window.  Doing so gives the menu effectively infinite height, as the user can slam the mouse up and not go past it.  Long story short, having the only means of closing tabs be a tiny button is bad UI design.

I could forgive the lack of middle button close IF the tabs supported sensible context menus to close other tabs.  Compare for instance the options of some other products that support tabs:

Firefox’s popup menu on tab

When you right click a tab in TextMate, no context menu appears – there is absolutely no menu option I can find to close all tabs.  Any system providing tabs should allow the user to make a blank slate for himself and focus on one (or zero) files at a time.  As it stands, you must click each tiny x button individually on all the tabs.

Finally, you cannot undock tabs.  Again, maybe I’ve just been spoiled by other products like Adium, Firefox, and NetBeans, but I consider it a very important feature to be able to undock tabs to show two windows side by side.  While tabs are certainly more space efficient than tiling windows side by side, sometimes you really need to compare two files side by side.  TextMate makes it very difficult to do that, especially when you have opened a project rather than individual files.

Here is the workflow in FireFox:


Before drag is initiated on the tab

While tab is being dragged; note that a translucent version of the page follows the cursor to indicate what is happening

After the drop is completed, the tab is split off from the original window and becomes a separate frame.

Conclusion

TextMate is an excellent text editor but not without some usability flaws.  I’ve detailed some features that irritate me about TextMate, due to their violation of the principle of least astonishment; I’ve used enough other similar systems to expect certain functionality, and this expectation is violated in a few ways.  These ways include the fact that hitting tab while text is selected replaces the contents with a literal tab rather than indenting the region, lack of a feature to syntax highlight unsaved files, an inability to close multiple tabs at once, and finally an inability to drag tabs out of the frame to become separate frames, so as to be able to compare documents side by side.  Software designers take note – if you are going to have tabs, you must build in these features or your users will feel seriously limited.

Categories: UI Tags: , ,