- Know functionality & memorize hotkeys–dig through the Sublime docs or menus to see what’s possible
- Isolate significant code snippets–copy/paste into separate documents to prevent interference with other code
- Leverage ‘Quick Find All’ hotkey–A faster way to find all
- Leverage multiple cursors–Type it once in multiple places at the same time
- Convert case automatically–Use hotkeys
- Leverage column selection
- Leverage multi-selection
- Leverage ‘Quick Add Next’ hotkey
- Sort lines alphabetically–Case sensitivity optional
- Leverage find and replace with regex (sparingly)
Column Selection or Multi-Selection combined with Ctrl+Click and Copy/Paste is king.
More recently, I’ve realized the benefits and efficiency of a powerful text/code editor. For my purposes, I want to focus on how to code efficiently with some Sublime Text tricks. It’s taken me some extra time to figure out how to leverage Sublime as a code editor, but it has paid off tremendously. I want to share some tricks that have made code editing fun, fast and easy.
As I was coding at work the other day, creating JS models for some new tables in the database, I found myself in a predicament. I had this database table with roughly 55 columns of attributes, a massive table relevant to our other tables. And I knew immediately that I was going to have to code all 55 columns into a JS model. I started to sigh, but then I got really excited because I knew I could find some incredible ways to do this really fast using Sublime.
Trick #1 – Know functionality & memorize hotkeys
Hotkeys are a fundamental of fast computing. I probably don’t have to mention this but I will anyway because I know how lazy some of us are, myself in included. Some times when you pick up a new program it can feel like a lot of work to learn all the new hot keys, especially when they’re different from another program or, in this case, when you’re talking about a really powerful text editor with lots of tricks up its sleeves. Put in the time sooner than later. It will pay off. Peruse (peruse |pəˈro͞oz|, verb – to read through with thoroughness or care) the menus and digest all the possibilities. Memorize the hotkeys of the actions you know you’ll use, then just remember the other actions so you can think to use them later. Memorize the latter hotkeys once you find yourself leveraging their respective actions regularly.
Trick #2 – Isolate significant code snippets–copy/paste into separate documents
Back to my story. I was at work and I needed to code this new model. First, I dug into our backend and found that the table had already been replicated into a C# model. Score! No tedious typing necessary. Below is some pseudo code similar to the code just mentioned. I’ve inserted it here so you can use it to try some of the Sublime functionality I’ll be discussing.
public int LoremIpsum public boolean Dolor public int Sit public int Amet public string Consectetur public string Adipisicing public string elitElit public int Quidem public boolean CulpaNobis public int Exercitationem public string Repellendus public int Aliquam public string Perspiciatis public int Placeat public string Ad public int Laborum public int Deserunt public DateTime Soluta public DateTime Cumque public int Doloremque public int Ipsa public string Cupiditate public boolean Provident public int Incidunt public int In public string Quasi public string Repudiandae public int Quidem public int Ab public boolean Iusto public int Commodi public string Natus public DateTime Minima public int Atque public int Molestiae public string HicTemporibus public string UllamLabore public string Facere public boolean Obcaecati public int Sed public int Excepturi public int Distinctio public boolean Similique public int AdipisciVeritatis public int QuoSequi public DateTime Velit public int A public int Est public int Necessitatibus public string UtLiberoInventore public string IpsaDicta public int VoluptatumSimiliqueMagni public boolean ImpeditDelectusFacilisNatus public DateTime Labore public string Corrupti
I copied all the properties from that model into an empty Sublime document. I recommend you copy and paste significant code change snippets into separate documents because it allows you to leverage the power of commands like find/replace without interfering with existing code. (Obviously, for simple things, this is too much work.) This is another reason why I always have Sublime open on the side. If I’m using an IDE like Visual Studio, Eclipse or Xcode, it’s a pain to create a new document because you usually have to go through the process of adding it to your project (wait for the modal to load, select a doc type, give it a name, hit next, then finish, etc.). That’s a such a hassle. Sublime is light weight and fast so I can open a new document in a second and paste in the code I’m working with. Easy as Ctrl+C >> Alt+Tab to Sublime >> Ctrl+N >> Ctrl+V >> Make modifications >> Ctrl+A >> Ctrl+C >> Alt+Tab to IDE >> Ctrl+V. And if you use Alt+Tab, the selection you made in the IDE remains when you switch to Sublime, so when you return, all you have to do is press Ctrl+V to replace the existing selection.
Trick #3 – Leverage ‘Quick Find All’ hotkey
Trick #4 – Leverage multiple cursors
Next, I stripped off the unnecessary C# keywords (i.e. ‘public’ and types like ‘int’, ‘string’, etc.) using find and replace…with a twist. Instead of using Ctrl+F, I double-clicked the word ‘public’ with the mouse (this highlights all matches) and keyed Alt+F3 (Cmd+Ctrl+G in Mac), the shortcut to Quick Find All. Alternatively, you may want the options of the Find toolbar (case sensitive or whole word), in which case you can click the word >> Ctrl+F >> Alt+Enter to Find All. With all the same words selected, I pressed Delete/Backspace.
One of the most powerful features of Sublime (or other text editors) is multiple cursors. You’ll notice when you do a Quick Find All you’re not just highlighting all occurrences, but actually selecting all occurrences. You have individual cursors for all your selections.
Next I wanted to clear out the value types, so I just pressed Ctrl+Delete (Fn+Alt+Delete) to delete the entire next word followed by Delete once more to delete the final space. I successfully narrowed down my properties with a few quick key strokes, which took literally a few seconds. If this seems slow to you now, with practice it will become second nature. You start my recognizing when you can/cannot leverage the tools available and then when you should/shouldn’t. You shouldn’t leverage these tools when it will take you longer to use them than just sticking to the basics, even after it becomes natural and fast.
This is what my code looks like after a few key strokes and seconds later (remember these are just the pseudo names of my model’s properties):
LoremIpsum Dolor Sit Amet Consectetur ... IpsaDicta VoluptatumSimiliqueMagni ImpeditDelectusFacilisNatus Labore Corrupti
Trick #5 – Convert case automatically
Trick #6 – Leverage column selection
You’ll notice all my properties are PascalCase according to C# convention. But in JS we use camelCase, so I needed to convert case on these properties. I could have simply keyed Ctrl+A to Select All >> Ctrl+K >> Ctrl+L to Convert Lowercase. However, there are some property names listed here that consist of more than one word and I didn’t want to lose their case. So instead I used column selection by middle clicking on my mouse (alternatively Shift+RightMouseButton for Windows and Alt+LeftMouseButton for Mac) in between the first and second letters of the first line and dragging all the way to the last line and to the left so that we highlight only the first letter of every line and then release the button. Now press Ctrl+K >> Ctrl+L to Convert Lowercase. That does it.
Next there were a number of things I needed to do to construct my model. I’d like to touch on one of those things that I think illustrates another powerful case for column selection. As part of our web app we are using Knockout.js and we use the KO observables in our models. In one portion of the model, I needed to assign the value of each property to a KO observable. Before I started using Sublime, I probably would have just copy/pasted the ‘ = ko.observable();’ onto each…and every…line. But with column selection I can simply middle click on the first line way out to the right of all the properties and just drag down to the last line and release. This effectively places a cursor at the end of every line. Now I simply type (or paste) ‘ = ko.observable();’. Then let’s say I hadn’t declared these variables yet so with all my existing cursors, I press Home >> type ‘var ‘. Except that looks kinda ugly and redundant so let’s undo that so we only have one variable declaration:
Ctrl+Z to delete ‘var ‘ >> End >> Backspace ‘;’ >> Type ‘,’ >> Esc >> Click end of last line >> Backspace ‘,’ >> Type ‘;’ >> Click beginning of first line >> Type ‘var ‘.
My code now looked something like this:
var loremIpsum = ko.observable(), dolor = ko.observable(), sit = ko.observable(), amet = ko.observable(), consectetur = ko.observable(), ... ipsaDicta = ko.observable(), voluptatumSimiliqueMagni = ko.observable(), impeditDelectusFacilisNatus = ko.observable(), labore = ko.observable(), corrupti = ko.observable();
Trick #7 – Leverage discrete mutli-selection
Trick #8 – Leverage ‘Quick Add Next’ hotkey
As I continued down my path, I noticed there were a few assignments that needed changing. Some of them needed default values and some were actually supposed to be observable arrays. Once again, before Sublime I probably would have just typed out the changes on the respective lines. However, instead I leveraged multi-selection like so:
DoubleClick ‘observable’ in the first line >> Ctrl+D 5x to Quick Add Next >> Ctrl+DoubleClick ‘observable’ every other line 5x >> Press RightArrow to go to the end of the selection >> Type ‘Array’ to change them all at once to ‘observableArray’. Then press Esc >> Ctrl+Click inside at least 5 sets of parenthesis >> Type ‘false’ to set the default observable value. My code now looked something like this:
var loremIpsum = ko.observableArray(), dolor = ko.observableArray(), sit = ko.observableArray(), amet = ko.observableArray(), consectetur = ko.observableArray(), adipisicing = ko.observableArray(), elitElit = ko.observable(), quidem = ko.observableArray(), culpaNobis = ko.observable(), exercitationem = ko.observableArray(), repellendus = ko.observable(), aliquam = ko.observableArray(), perspiciatis = ko.observable(), placeat = ko.observableArray(), ad = ko.observable(), laborum = ko.observableArray(), deserunt = ko.observable(), soluta = ko.observable(), cumque = ko.observable(), doloremque = ko.observable(false), ipsa = ko.observable(), cupiditate = ko.observable(), provident = ko.observable(), incidunt = ko.observable(), in = ko.observable(), quasi = ko.observable(), repudiandae = ko.observable(false), quidem = ko.observable(), ab = ko.observable(), iusto = ko.observable(), commodi = ko.observable(), natus = ko.observable(), minima = ko.observable(false), atque = ko.observable(), molestiae = ko.observable(), hicTemporibus = ko.observable(), ullamLabore = ko.observable(), facere = ko.observable(), obcaecati = ko.observable(), sed = ko.observable(), excepturi = ko.observable(false), distinctio = ko.observable(), similique = ko.observable(), adipisciVeritatis = ko.observable(), quoSequi = ko.observable(), velit = ko.observable(), a = ko.observable(), est = ko.observable(), necessitatibus = ko.observable(false), utLiberoInventore = ko.observable(), ipsaDicta = ko.observable(), voluptatumSimiliqueMagni = ko.observable(), impeditDelectusFacilisNatus = ko.observable(), labore = ko.observable(), corrupti = ko.observable();
Obviously, based on the types in my original C# model, the model I’ve created won’t work too well (I didn’t actually need arrays). So before I move on, I’d like to show you something I did have to do that may be more applicable. I had to set the default values for my properties based on their respective types (number, boolean, date, etc.). I went back to the original C# properties which I left isolated in a separate document and leveraged column selection to grab the types. This is what I started with:
var loremIpsum = , dolor = , sit = , amet = , consectetur = , adipisicing = , elitElit = , quidem = , culpaNobis = , exercitationem = , ...
I used column selection to place a cursor on the end of every line >> Ctrl+LeftArrow (2x) >> Ctrl+Shift+RightArrow to select the types on every line >> Ctrl+C >> Ctrl+Tab to previous file with JS properties >> Column select end of every line >> Ctrl+V. This is how it looked when I was done.
var loremIpsum = int, dolor = boolean, sit = int, amet = int, consectetur = string, adipisicing = string, elitElit = string, quidem = int, culpaNobis = boolean, exercitationem = int, ...
I next used Quick Find All on each type to replace each type with the desired default value. DoubleClick ‘int’ >> Alt+F3 or Cmd+Ctrl+G >> Type ‘0’ >> Repeat with different type. When all was said and done this was the product:
var loremIpsum = 0, dolor = false, sit = 0, amet = 0, consectetur = '', adipisicing = '', elitElit = '', quidem = 0, culpaNobis = false, exercitationem = 0, ...
Trick #9 – Sort lines alphabetically
It’s nice to have all your model’s properties (or CSS attributes) alphabetized. Simply select all the relative lines and choose F9 to Sort Lines or Ctrl+F9 to Sort Lines (Case Sensitive). Don’t forget to readjust any line beginnings or endings after sorting (i.e. commas, semicolons, var declarations, etc.).
var a = 0, ab = 0, ad = '', adipisciVeritatis = 0, adipisicing = '', aliquam = 0, amet = 0, atque = 0, commodi = 0, consectetur = '', corrupti = '', culpaNobis = false, cumque = new Date(), cupiditate = '', deserunt = 0, distinctio = 0, dolor = false, doloremque = 0, elitElit = '', est = 0, excepturi = 0, exercitationem = 0, facere = '', hicTemporibus = '', impeditDelectusFacilisNatus = false, in = 0, incidunt = 0, ipsa = 0, ipsaDicta = '', iusto = false, labore = new Date(), laborum = 0, loremIpsum = 0, minima = new Date(), molestiae = 0, natus = '', necessitatibus = 0, obcaecati = false, perspiciatis = '', placeat = 0, provident = false, quasi = '', quidem = 0, quidem = 0, quoSequi = 0, repellendus = '', repudiandae = '', sed = 0, similique = false, sit = 0, soluta = new Date(), ullamLabore = '', utLiberoInventore = '', velit = new Date(), voluptatumSimiliqueMagni = 0;
Trick #10 – Leverage find/replace with regex (sparingly)
As a final example, I’d like to show you how I used regex, specifically regex groups, to solve a text editing predicament in one fell swoop. However, I’ve found that regex can be overused, therefore I caution to use it sparingly. Even for the example at hand, I didn’t need to use regex (I could have used a combination of column selection and copy/paste), but I quickly saw an opportunity that wouldn’t take very much extra time. However, in the past, mostly school projects, I have wasted plenty of time trying use regex for simple problems. Don’t fall into the trap of over-engineering.
Let’s say I had a code snippet that looked something like this where I was chaining a bunch of properties together to change some values:
var thing = thing.loremIpsum(item.) .dolor(item.) .sit(item.) .amet(item.) ... .voluptatumSimiliqueMagni(item.) .impeditDelectusFacilisNatus(item.) .labore(item.) .corrupti(item.);
I want to copy the name after the first period on each line and paste it after the second period. First, I would isolate the significant code snippet into a separate Sublime Text document–everything starting after ‘var thing = thing’ at the first ‘.loremIpsum(item.)’ to the last ‘.corrupti(item.)’. Then I would press Ctrl+H or Cmd+Alt+F to bring up the Find/Replace toolbar (from the menu Find >> Replace…). Enable both ‘Regular Expression’ and ‘Wrap’ options, type in the text below in the appropriate boxes and click Replace All.
Find What: \.(\w+)\(item.\) Replace With: \.$1\(item.$1\)
My final product would be this:
var thing = thing.loremIpsum(item.loremIpsum) .dolor(item.dolor) .sit(item.sit) .amet(item.amet) ... .voluptatumSimiliqueMagni(item.voluptatumSimiliqueMagni) .impeditDelectusFacilisNatus(item.impeditDelectusFacilisNatus) .labore(item.labore) .corrupti(item.corrupti);
As a second example, let’s say I was not chaining and did not have just ‘thing’ and ‘item’ but wanted to swap some properties around–I needed to convert something bizarre like this:
.loremIpsum(est.) .dolor(necessitatibus.) .sit(utLiberoInventore.) .amet(ipsaDicta.) ... .voluptatumSimiliqueMagni(exercitationem.) .impeditDelectusFacilisNatus(repellendus.) .labore(perspiciatis.) .corrupti(placeat.)
est.loremIpsum(loremIpsum.est) necessitatibus.dolor(dolor.necessitatibus) utLiberoInventore.sit(sit.utLiberoInventore) ipsaDicta.amet(amet.ipsaDicta) ... exercitationem.voluptatumSimiliqueMagni(voluptatumSimiliqueMagni.exercitationem) repellendus.impeditDelectusFacilisNatus(impeditDelectusFacilisNatus.repellendus) perspiciatis.labore(labore.perspiciatis) placeat.corrupti(corrupti.placeat)
The regex would be something like:
Find What: \.(\w+)\((\w+)\.\) Replace With: $2.$1($1.$2)
There are lots of other cool possibilities with a powerful text editor like Sublime Text. Something I didn’t address here that I may in a future post is leveraging the sublime package manager to install plugins. Also, customizing your hotkeys and adding new ones. If you frequently use similar tricks, share them in the comments.
Column Selection or Multi-Selection combined with Ctrl+Click and Copy/Paste is probably one of the most powerful tricks you can use. Most code is not random enough to overcome these trios. You often have variable property name lengths, but Ctrl+LeftArrow or Ctrl+RightArrow overcomes that by skipping over phrase chunks. This only starts to break down when you have dashes (-) in your names like ‘some-css-class’. That’s usually not a problem for most languages though since convention calls for PascalCase or camelCase combined with underscore (_) for some variable names (e.g. SOME_STATIC_VAR), but underscores are considered part of the phrase.
Ideally I would have had a tool or script that simply looked at my database table and would have pumped out the model for me. Alas, that would have taken more time to script out or investigate. The methods I used here have significantly reduced the time it takes me to code lengthy, repetitive, pattern-prone snippets.