Posts RSS Comments RSS 32 Posts and 1,017 Comments till now

TextMate Tip – Find and Replace

Today I’ll give a tour of TextMate’s features related to finding (and replacing) text.

Find Dialog

Here’s the Find Dialog, accessible through Edit → Find → Find… or ⌘F. A few notes:

  • You can press the button with the arrow next to the Replace field to change to multi-line input (Note that you still need to hold Option to insert a tab or newline into the text fields – i.e. press ⌥↩ to insert a newline).
  • The sigma (Σ) button next to the Find field will display how many matches there are in the current document – handy before doing a big Replace All.
  • The 3 checkboxes can be toggled with the keyboard by using ⌥⌘ and the first letter of the option title (e.g. ⌥⌘R toggles regular expression mode)
  • Holding either Shift or Option will toggle the Replace All button to In Selection Mode

However, I rarely use the Find dialog (mainly just for regular expression searches) because TextMate offers key equivalents for common operations. You can view the list in the Edit → Find menu, but here’s a brief rundown:

  • Press ⌘E to use the current selection for the text to search for
  • Press ⇧⌘E to use the current selection to replace with (or use an empty selection)
  • Press ⌘G to go to the next occurrence of the find string (or ⇧⌘G for the previous occurrence)
  • Press ⌥⌘F to replace the current selection and move to the next occurrence – this is useful when you want to review what you are replacing, you can use ⌥⌘F to do a replace or ⌘G to skip to the next one
  • After using ⌘E and ⇧⌘E to set both a find and replace string then you can use ⌃⌘F to replace all instances or ⌃⇧⌘F to replace all in the selection.

These are really handy and will save you a lot of time if you can get used to them – I would recommend learning ⌘E and ⌘G at least, since they are the most common.

Note: If you find that you’re able to move the caret beyond line endings then you’ve accidentally pressed ⌥⌘EEdit → Mode → Freehanded Editing. Press it again (or use the menu item) to disable it.

For quick one-off searches you can use the incremental search feature instead, activated with ⌃S. The selection will move as you type in a query – you can move to the next occurrence by pressing ⌃S again (or the previous occurrence with ⌃⇧S).

TextMate also offers Find in Project functionality (⇧⌘F) on the same menu, which can do a global search in your project’s files. You can also perform a mass replace: first enter your query and run the find, then once you are happy with the results you can enter your replace string and use “Replace All” (or you can select individual occurrences and use “Replace Selected” – selecting a filename will replace all the occurrences inside that file).

However I rarely, if ever use the project find as it can be quite slow, and is blocking. Generally I use grep, but the Grep in Project command from over on the The Pug Automatic is nice when I want a quick search.

9 Responses to “TextMate Tip – Find and Replace”

  1. on 14 Nov 2007 at 7:04 amJon Henshaw

    If you get a chance, you should check out the Snipplr TextMate bundle – it seems like the perfect fodder for an entry on your blog.

  2. on 10 Dec 2007 at 11:28 amRuby, Rails, TextMate « exceptionz

    [...] Tips and Tricks – Find and Replace [...]

  3. on 04 Jan 2008 at 4:32 amRuby, Rails, TextMate

    [...] Tips and Tricks – Find and Replace [...]

  4. on 17 Dec 2008 at 9:01 pmJosh

    Do you know of a find and replace, where you can replace a certain tag, and anything within that tag, with something else? I have a XML document and i need to delete some extraneous tags but don;t want to go through line by line and do it.

    Any suggestions??

  5. on 17 Dec 2008 at 9:03 pmCiarán

    Hi Josh, I suggest you ask in the IRC channel (##textmate on freenode), or post a more detailed description of your problem to the mailing list.

  6. on 28 Jan 2009 at 4:29 pmcosmetic dentist

    Hi how do we do aglobal find an replace acorss 1000 files ive tried it and it works for open fiels but is there any way of doing this accross an entire website?

  7. on 05 Mar 2009 at 10:17 pmjulian

    Josh, if you want to replace tags you can use a regular expression

    In the find box type <mytag>.+</mytag> In the replace box type whatever you want to replace it with .. for example <mynewtag>hello</mynewtag> check the “Regular Expression” checkbox

    The . means any character, and the + means 1 or more of them – so .+ means any string with at least one character. If you want to match zero or more, use * instead of +

    You can also use part of the matched search in the replacement. You do this by placing () around each part of the search you want to use, and referring to them in the replacement with $1, $2 etc. For example, suppose you have months and years in date tags january 1992 march 2003 etc., but instead you want: is the month is the year

    You can do it like this: In the search field: ([A-Z,a-z]+) ([1-2][0-9][0-9][0-9]) In the replace field: \nis the month\nis the year\n

    As mentioned, the brackets store the matches in variables: $1 and $2 based on the order of the bracket groups. [A-Z,a-z]+ means 1 or more upper or lower case characters [1-2][0-9][0-9][0-9] means 4 digits, the first must be 1 or 2 \n prints a new line

    hope it helps

  8. on 05 Mar 2009 at 10:21 pmjulian

    sorry – the tags have been mangled in the above comment – not quite sure how to fix it as there is no preview option.

  9. on 18 Aug 2009 at 6:10 pmAnnie Niemoose

    What’s the easiest way to do a find and iterative replace in TextMate? I find I often have the problem where I’d like to find every result matching an expression and replace them from a list of values in my clipboard or in another file. Let’s say you have a hundred expressions in the form of:

    INSERT INTO pricechange (id, productid, newprice, startdate) VALUES (1, 12345, ’34.99′, sysdate + 15); INSERT INTO pricechange (id, productid, newprice, startdate) VALUES (2, 23238, ’37.99′, sysdate + 20); …

    and you have a list of a hundred product IDs that you’d like swap into those statements. It’d be neat if there was a simple way to do a find/replace on (\(\d+, )\d+, to replace with $1$productid, where each time it used the next product ID instead of $productid.

Fork me on GitHub