Jan 17 2012

IO-style cloning in Javascript

Category: Uncategorizedzvolkov @ 5:31 pm

In true prototype languages like IO, there is no inheritance vs. instantiation of classes, there is differential inheritance aka cloning. New objects are derived from existing objects. The old object serves as a prototype of the new one.

In Javascript there is no proper cloning — instead, a prototype to be assigned to a freshly created object depends on the prototype property of the constructor function. All the elements are there but they are insanely incoherent.

To take Crockford’s Object.create pattern one micro-step closer to IO, here’s how IO-style cloning can be implemented in Javascript:

var yobject = {
  derive : function () {
    var F = function() {};
    F.prototype = this;
    return new F();
  }
};

Now the objects (or, rather, “yobjects”) can be easily cloned like this:

var car = yobject.derive();
car.wheels = 4;
var ferrari = car.derive();
ferrari.color = red;
console.log(ferrari.wheels); //prints 4

You can even implement singleton pattern, IO-style:

var elvisCadillac = car.derive();
elvisCadillac.color = 'pink';
elvisCadillac.clone = function () {return this;};

var fake = elvisCadillac.derive();
console.log(fake === elvisCadillac ); //prints true

I thereby name you The Yobject Pattern!


Jan 15 2012

Teaching Assembly, Part 2

Category: Uncategorizedzvolkov @ 12:36 pm

Just to dump my thoughts on the subject, and clean the brain buffer for new ideas, I’m writing this post summarizing what I taught my son since the last post:

  • Learned the notion of video memory. Drew a stickman by setting bits in video memory. Made the stickman “move” by erasing and redrawing it with an offset.
  • Made a “font” consisting of binary representation of pixels required to draw letter “A”. Learned to “print” strings consisting of A’s. Discussed what it would take to print arbitrary strings this way.
  • Learned the notion of ASCII code as a way to represent characters in memory.
  • Called CP/M system function to print a $-terminated string.

Now, in our first phase, all programming was done in CP/M’s debugger “SID”, running on an 8080 emulator. The idea was to start with simple non-segmented addressing, understand limitations of 8-bit arithmetic, and overall get used to a highly restricted environment the assembler programmer works in. At some point I realized it wasn’t our primary goal to learn CP/M and decided to upgrade to 8086.

Here’s what we learned on 8086:

  • Learned that DOS command DEBUG — DOS equivalent of CP/M’s SID — still works on Windows XP (and even on 32-bit Windows 7 or so I was told!). Played with DEBUG to learn its slightly different commands and output format. Turns out there’s an improved clone of DEBUG called GRDB.
  • 8086 registers. All 16 bit. Many accumulators. Extra registers.
  • 8086 versatile MOV commands and the [xyz] notation. No need to remember 8080′s LXI/LDAX bullshit.
  • 8086 built-in multiplication and division
  • File system basics. Directories and files. Path. Commands CD and DIR. The process of loading executable file into memory and starting it.
  • 8086 has lots of RAM. Segment addressing. Why segments “overlap” (or, rather, can start anywhere on 16 byte boundary). Tiny model vs. small model.
  • DOS equivalent of CP/M’s print functions (Interrupt 21h, same function #9). Same $-terminated strings.
  • Rewrote a couple of previously written programs (e.g. reversing an array) from 8080 assembler into 8086.
  • Learned to save a program from DEBUG into a .COM file.
  • The notion of source code vs. executable. Compilation. Wrote a “hello world” in .asm file and compiled it to .COM using MASM.
  • A DOS Int 21 function to input a character.
  • Wrote a console game (!) that guesses a number from 1 to 1000 by progressively cutting the range in half.
  • Representation of negative numbers. Two’s complement format.

This was a time when I almost decided that we were done and it was time to move on to C. I even showed Matthew hello world in C and he liked how you don’t need to juggle registers and how printf magically formats strings and numbers. But then I realized: first, I was rushing a bit and perhaps we need to stay on assembler until he gets comfortable writing programs w/o my help. Most importantly, I realized C was not exactly meant for “fun” programming — it is perfect for processing files but less perfect for drawing on screen, or for making sounds, or for developing micro-games, not without using third-party libraries anyway. I really believe I should avoid the libraries as they will certainly overwhelm Matthew (“look these people have already written EVERYTHING there was to be written!”).

And so I this morning I decided to linger on assembler a bit longer. Here’s what we learned in the last few days:

  • The notion of global constants (the strings we print) vs. global variables. Rewrote the game to take advantage of global variables as opposed to holding stuff in registers all the time.
  • The notion of local variables on stack.
  • Intel 80386. 32-bit registers.
  • Modern debuggers: IDA Pro and OllyDbg.
  • FASM (Flat assembler) as a simpler, more modern alternative to MASM. FASMW IDE.
  • The boot process. BIOS vs. OS.
  • Interrupts. Actual (hardware interrupts) vs. interrupts as system API.
  • DOS interrupts and BIOS interrupts vs. directly working with hardware.
  • Keyboard scan codes. Difference between scan- ASCII- codes.

Now I’m thinking we should develop a console game that would involve moving an object on screen with cursor keys. Perhaps such a game as Snake or Sokoban or Arcanoid would work well. Any ideas?


Dec 20 2011

Teaching assembly

Category: Uncategorizedzvolkov @ 8:49 pm

When my son was about 8 or 9 I introduced him to non-decimal base numbers — we were playing aliens with 2 or 3 or 8 or 16 total fingers.  Now he is 12. We’ve been studying 8080 asm for about two weeks now, every evening. To my surprise, it’s going extremely well.

Why did I choose assembly language?

Both ”enterprise” languages (Java or C#) and “open” languages (Ruby, Javascript etc.) are overcomplicated. Most of modern languages are multiparadigm ones. This means, if you start with a “real” language, on his first day he’d bump into elements of OOP, functions, closures and God knows what else. Then there are libraries. Then there are IDEs. Believe me, you don’t want your kid to get overwhelmed on his first day.

Most modern languages — except pure functional ones like Haskell and the like — have their syntaxis highly influenced by C. Why not learn C then? IMHO, that’s a great idea. It does not have OOP, and is overall pretty simple. However, when learning C you will inevitably bump into things that are IMPOSSIBLE TO EXPLAIN without talking about RAM, stack, and registers. Unless of course you want to wave your arms and say that it’s all computer magic.

In light of the above, learning ASM as the first language makes a lot of sense. ASM is not hard at all. I would even say it’s simpler than any high-level programming language because of its narrow scope and small number of moving parts. You really only have a handful of registers, a few arithmetical commands, plus 1-2 instructions for moving stuff in/out of RAM. THAT’S ALL. With about a dozen instructions you can start writing meaningful algorithms. In a few weeks he can learn conditional logic, loops, and even arrays.

Now, what you DON’T want to teach your child is the memory conventions, segments, and the process of compiling and linking an asm source file. Leave that for until after he knows C. That’s why for our programming environment I chose SID — this is a ”debugger-monitor” running on a legacy OS called CP/M (running on an in-browser 8080 emulator: http://www.tramm.li/i8080). All you get is a blank screen, with few simple commands (L100 to see a disasemmbly of instructions at address 100, A100 to start entering new instructions line by line, G100 to run the program etc.). I can’t tell you how much it helps the focus to narrow the scope to a blank screen with one command line.

Here’s what we have covered so far:

  • Hex / Binary / Decimal conversion and arithmetic.
  • Basics of von-Neumann architecture: CPU, registers, RAM
  • Basic assembly mnemonics (Intel-style) – MOV, ADD, SUB
  • CP/M debugger-monitor (DDT/SID) workflow and basic commands: A, L, T, X
  • i8080-specific mnemonics – MVI, ADI. Entering and running a simple program.
  • The notion of loop. The FLAGS register. The Zero flag. New command JNZ. Implementing multiplication of two numbers via addition.
  • More 8080 mnemonics – LXI, PCHL. Implementing a subprogram via jumps (don’t know what stack is yet)
  • More debugger commands: S, H. More 8080 mnemonics: INR. Reading from RAM.
  • Implementing a program that sums elements of an array given a pointer to its head and a number of elements.
  • The notion of carryover. The Carry flag. Implementing a two-byte addition by counting the carryovers. Enhanced the Sum Of Array program accordingly.
  • More 8080 mnemonics: INX. Array of structures. Writing to RAM. Using flowcharts to visualize complex programs.
  • Implemented a program that takes an array of triples, then for each element multiples first two bytes and stores the result into the third byte.
  • Comparing numbers with CMP. A program to find maximum value in array.
  • A program to reverse an array in-place.

Next, I’m planning to introduce a concept of stack, and then, after a bunch of exercises we will move on to C. I’m excited.

As Joel Spolsky once said:

Trying to be a programmer without understanding how a CPU works is like trying to practice medicine without learning anatomy. Sure, you can have limited success curing patients with medical advice gleaned from Google, but on the whole you’re going to be a pretty bad doctor.

 


Nov 09 2011

MIT Course in Operating Systems

Category: Uncategorizedzvolkov @ 2:39 pm

One of the most exciting areas of Software Engineering is operating systems design. That and design of compilers are the two topics I have always dreamed of studying more closely. While my friend Max Trushin is digging deeply into the second topic, I find myself getting sucked in the first one. Indeed, lately I’ve spent significant time installing and tweaking my two Arch Linux installations. What I found recently though, takes my Linux hobby to an entirely new level. I’m talking about the Massachusetts Institute of Technology’s course in Operating System Engineering.

It’s a 6-month-long course that covers all you need to know about OS design, starting from basics, all the way through multitasking and micro-kernels.

Here’s what they provide for free:

A list of literature, with some of the books actually available for free download:

Lecture notes (from 2006, and from 2011 – click on lecture topic) summarizing the essence of 23 lectures on  topics ranging from boot process management to shell design.

A working Unix clone, complete with source code and commentaries:

More information available on MIT current 6.828 course page and on MIT open courseware page for 6.828.

Not sure about you but I’m seriously considering reading through the lectures, if not doing the actual labs!


Oct 23 2011

Buying a monitor

Category: Uncategorizedzvolkov @ 10:13 pm

Continuing my “spending money” series, today I’ll explain what I was looking for in a monitor.
Before buying a monitor, I’ve spent a great deal of time researching monitor technologies and stuff.
If you a programmer, here are the main things you want in a monitor:

Stand

This is big. I can’t tell you how many monitors come with a stand that can tilt but can’t go up and down. If you spend many hours in front of your monitor, you really want your screen to be at your eye level. Get yourself a height-adjustable monitor, your back and neck will thank you.

TFT panel

100% of laptop screen and perhaps 90% of desktop monitors on the market use so-called TN panels. While TN panels are cheaper and they do redraw faster (good for games) they have one annoying feature: the screen brightness / contrast changes depending on the angle you’re looking at. Some TN panels are so bad that only the middle of the screen looks good, while top and bottom are darker.

This problem is fixed in IPS panels, which also provide better colors as well. They are more expensive though, but if you spend most of your waking time in front of a monitor, you don’t want to economize on it. Your eye doctor bill will cost much more, believe me.

Now, there are many sub-types of IPS panels (e-IPS, h-IPS, s-IPS) but these are just marketing names, don’t pay attention to them. What’s actually important are the actual characteristics of the panel, and with a bit of effort you can look them up. Go to TFT Central Panel Search Database and enter model code of the monitor you are considering e.g. “U2410″. This will give you code of actual TFT panel e.g. “LM240WU4-SLB1″. Then go to TFT Central Monitor Panel Part Database and find the panel specifications. Make sure your panel number matches exactly. Even a one-letter difference can be a completely different panel with totally different characteristics.

  1. Make sure your panel is actually an IPS. If you can’t afford one, get an MVA or PVA panel, but never buy a TN.
  2. Make sure your panel is not a 6-bit one. If it just says 16.7M colors without mentioning bits, it should be safe to assume it’s an 8-bit panel. Obviously, 6-bit panels can show 8 times less colors than 8-bit ones (6 bits x RGB vs. 8 bits x RGB). This is especially noticeable on shades of gray which set Red, Green and Blue to the same value. While 8-bit panels will give 256 shades of gray, 6-bit ones will give only 64! To hide this limitation manufacturers employ  a trick called ”FRC” (Frame Rate Control) — basically blinking the pixel between two colors to simulate the color in between. Needless to say, this increases eye strain.
  3. Make sure your panel is not a 10-bit one. Both true 10-bit panels, as well as 8-bit panels emulating 10 bit through FRC are bad for programmers. True 10 bits produce over-saturated colors — good for movies and games but not for coding. 8-bit FRC are not as bad for eye strain as 6-bit FRC ones, but you should avoid them as well.

Resolution and size

These days, the standard resolution is 1920×1080 (aka Full HD). Now, depending on the physical size, these pixels will either be spread over 27 inches or crammed in 17 inches.

Bigger screen with smaller resolution (=bigger pixel size) is generally better for your eyes. What you want to avoid is big screen size and lots of pixels — too much screen space means you will not be able to see it all and will have to move your eyes and even your head a lot more! This can not only reduce your productivity, but even cause a headache.

Based on the above, the monitor bigger than 24 inches is probably too big for a developer. Resolution-wise, anything smaller than 1400×1050 is way too small for anyone but hardcore vim fans, while anything more than 2000 pixels wide will result in tiny pixels (= small fonts).

Widescreen ratio

While 16:9 widescreens are good for movies, they are not so good for programming. Remember, your are looking at code, which is rarely longer than a hundred chars, but usually much longer than 100 lines. You want to see as many lines of code as possible without scrolling. More lines of code reduces pressure on your short- term memory. Your brain will thank you.

As you understand, this means that (given the same resolution and pixel size) 16:10 monitors are better than 16:9, while 4:3 are the best, for us, code monkeys.

Number of monitors

Two smallish monitors is better than one huge monster. Here’s why. Because most programmers tend to run their IDEs and editors full-screen, multiple monitors give you natural boundaries for your maximized windows. While you can simulate those boundaries with software-based virtual desktops, nothing beats simplicity of multiple monitors.

Putting it all together

Based on the above the ultimate development workstation should have two or three 1600×1200 monitors (or 1400×1050). The biggest 1600×1200 screens in existence are 21.3″ — anything bigger will be 16:10. Don’t get me wrong, 21.3″ at 1600×1200 is a great size, with nice chunky pixels. There are two problems with this idea though. One, you can’t watch native BD-movies, and two, it is almost impossible to find 1600×1200 monitors with 8-bit IPS panels, and if you find them they tend to be very expensive $1000+ professional screens.

Dismissed choices

  • Dell U2410m — is an 8-bit FCR IPS, too expensive at $500.
  • Dell u2412m, is a 6-bit FCR IPS, plus Dell.com charges sales tax which amounts to extra $20.
  • Dell U2312m is an affordable IPS screen, but it is a 6-bit FCR and too wide at 1900×1080.
  • NEC 2190UXp is fantastic 1600×1200 21.3″ PVA, way too expensive at $850!
  • NEC 2090UXi is a great 1600×1200 20″ 8-bit IPS, again too expensive at $700
  • LG IPS231P is a cheap 6-bit FCR IPS, again too wide at 1920×1080
  • LG L2000CP-BF is a bit small at 20″ 1600×1200, but is a real 8-bit IPS. The question is, do you want to pay $400 for that?

Most others were either countless cheap TN panels or way too expensive professional IPSes like Eizo and NEC.

And the winner is

If I had limitless supply of money, I would get two NEC 2190UXp for the total of mind-boggling $1700!. But since my family still has to eat, I had to settle on something cheaper. I have browsed through endless lists of reviews and specifications before choosing Hewlett Packard’s good old HP ZR24w. Being a 24 inch 1920×1200 monitor (16:10) it is almost too big, but it does have an 8-bit IPS matrix, and a nice pixel size, and a good height-adjustable base. At the moment of this writing BHPhotoVideo has the best price: $340 with free shipping and no tax. Beware of an “improved” version of same monitor, HP ZR2440w.  Even though it costs more, it has a much inferior 6-bit panel…

UPDATE: Don’t buy HP ZR24w, it’s a piece of crap! Its backlight fixture makes buzzing noise and its viewing angle is horrible for an IPS panel. Next to my 24″ iMac circa 2008 (same size, same resolution) the HP looks colorless and milky. I should have bought NEC instead.


Oct 22 2011

Bye-bye Godaddy!

Category: Uncategorizedzvolkov @ 9:48 pm

Today I’m totally happy. Earlier this year I have migrated this blog from BlogEngine.NET onto WordPress.
Today I have finished moving all my web sites off Godaddy and onto Linode VPS.
Here’s the stack I run now:

  • openSUSE Linux 11.4. Liking it more than Ubuntu so far. Compare names: “apt-get” vs. “zypper”. The standard greeting says “Have a lot of fun!”.
  • nginx. Superfast, simple, powerful web-server optimized for static content (but not only). Helped me configure redirects from zvolkov.com/blog to zvolkov.com/clog and from zvolkov.com/poignant_ru to www.poignant.ru.
  • MySQL. Moving two WordPress databases I had on Godaddy over was a piece of cake.
  • PHP with PHP-FPM and APC. The latter is an opcode cache for PHP.
  • WordPress. I was concerned about moving existing WordPress installation from Windows to Linux by copying files, but surprisingly, this was painless.
  • WP Super Cache. This plugin creates static gzip files for each WordPress post, which then can be served by ngnix w/o the overhead of PHP and SQL processing.

By far the most interesting and demanding part of the move was tweaking nginx.


Oct 21 2011

Permanent redirect static pages from Godaddy Windows IIS using httpRedirect in Web.Config

Category: Uncategorizedzvolkov @ 9:21 am

Today I moved my Russian translation of W(p)GtR from Godaddy to my shiny new Linode VPS.
What I needed though, is to redirect people visiting the old site, to the new site.
My old site was running on Windows / IIS / ASP.NET so I could not use Godaddy’s Redirect URL feature in Control Panel which only works on Linux accounts.
To redirect those visitors hitting the folder (i.e. zvolkov.com/poignant_ru), I added default.asp with following content:

<%@ Language=VBScript %>
<%
Response.Status="301 Moved Permanently"
Response.AddHeader "Location","http://www.poignant.ru"
%>

This was easy. The trick was to redirect visitors to individual static .html pages — and here’s how I solved it.
Basically, you need to add a web.config to your folder with httpRedirect tag in it, like this:

<configuration>
<system.webServer>
  <httpRedirect enabled="true" exactDestination="true" httpResponseStatus="Permanent">
     <add wildcard="*ch1.html" destination="http://www.poignant.ru/ch1.html" />
     <add wildcard="*ch2.html" destination="http://www.poignant.ru/ch2.html" />
     <add wildcard="*ch3.html" destination="http://www.poignant.ru/ch3.html" />
     <add wildcard="*ch4.html" destination="http://www.poignant.ru/ch4.html" />
     <add wildcard="*index.html" destination="http://www.poignant.ru/index.html" />
     <add wildcard="*copyright.html" destination="http://www.poignant.ru/copyright.html" />
     <add wildcard="*help.html" destination="http://www.poignant.ru/help.html" />
     <add wildcard="*WpGtR_rus.pdf" destination="http://www.poignant.ru/WpGtR_rus.pdf" />
  </httpRedirect>
</system.webServer>
</configuration>

Works like a charm! You will notice that the site is significantly faster now.
This is because it is served by nginx, a relatively new super-speed web server.
Next week I will be moving my blogs as well.


Oct 20 2011

Building my PC, part 3

Category: Uncategorizedzvolkov @ 9:23 am

Ok, I must admit, I’m just enjoying spending money. Then again, what kind of computer is complete until you spend a fortune? Here’s what I bought since the last post:

DVD — $70

The tough part about choosing a DVD-reader-writer is to find one that would match the front panel. I have settled on this LG WH12LS30. It’s a multiformat Blu-Ray / DVD / CD reader and writer. Perhaps more importantly, it’s front panel more-or-less matches my Corsair 650D’s black brushed aluminium front.

HDD — $65

Considering that I have an SSD as my primary drive, the main factor in the purchase of an HDD for me was noise. I hate those bird chirping sounds most hard-drives emit, but more than the chirping, over years I came to hate the hiss of a rotating spindle. That’s why I decided to go with this 1 Tb Western Digital Caviar Green WD10EARX. According to these tests by silentpcreview.com, its 2Tb brother is the quietest of all 3.5″ hard drives on the market today. Now, these tests were done before the 1Tb version was available. Given that the 2Tb version has 3 actual disks inside, the 1Tb is likely to have only 2 disks. This guess is supported by the WD spec sheet, which says that WD10EARX is 40 grams lighter than WD20EARX, requires 0.10VDC less power, and emits 1dbA less noise. From first hand experience I must say this is the quietest hard drive I have ever seen in my life.

Total cost - $1376 (plus shipping)

That’s it for today. The next up is the Monitor.


Oct 05 2011

Building my PC part 2

Category: Uncategorizedzvolkov @ 5:43 pm

This is fun. Researching, assembling, testing my own baby computer.

Dimensions

Make sure your components will actually physically fit together.

First, make sure your case is big enough for your Power Supply and your motherboard. You can get dimensions of both before you by them.

If you have a non-standard CPU cooler, like I do, make sure it will fit in the case height-wise. Make sure the memory will fit with the cooler installed.

If you’re planing on a big-ass video-card, make sure it will fit length-wise into the case. Make sure it won’t obstruct other slots on the motherboard that you are going to use.

If you’re buying *high* memory DIMMs (the new style, with heat radiators), make sure they won’t bump into your video card or your CPU cooler.

Luckily, I had very little issues with the above. I ordered a huge case, so my CPU cooler (barely) fit. But I had to install it facing the backpanel, to resolve the conflict with my DIMMs.

Noise

Standard fans that come with case — any case, even a $175 one — are crappy. Meaning, they produce lots of noise.

First, if your case has 3 or more fans — you may not even need them all. Two good fans should be plenty enough.

Next, I’m replacing the exhaust fan (the one on the backpanel) with this $17 Scythe. Since it is 4 pin (Pulse Width Modulation), I can plug it into MB and have the BIOS slow it down when cold. It also comes with a tiny knob of its own which I can rotate to adjust the lowest speed.

My Scythe will only produce 7 decibels of noise on its lowest setting. This is very good, but remember, multiple fans add up. If you have a fan on the top of the case (I do), see if you can replace that one too. I’m getting a 200mm Coolermaster for $16.  It may look obnoxious with those red LEDs, but it will push the air at 110 Cubic Feet per Minute while making only 19 decibels of noise. If worse comes to worse, I think I can cut those leds off.

Again, measure twice, cut once. The fans come in  different diameters (120mm, 140mm, 200mm are most common), but most importantly they have different distances between their mounting holes, and different depths (=thickness) too.

Hard Drive

After long hesitations I decided to buy an 128GB Crucial m4 SSD for $200. Why SSD? Because it’s been more than 3 years since they became common and I must check whether those super-speed myths are true. Why Crucial m4? Because Crucial is an old-school memory company that cares about quality, unlike OCZ who make super-fast SSDs that crash. That simple.

Total Cost

This brings my total cost from $1008 to $1241 (plus shipping, so probably more like $1300). The only thing I’m missing is a video card. Another $200. So the total cost is going to be $1500. Not bad for a rig made off of top of the [mainstream] line components.

This is it for now, and since I personally know one person who reads my blog, I can tell you: you should totally do it, Igor!


Sep 26 2011

Unix text editors: the layered approach

Category: Uncategorizedzvolkov @ 9:49 pm

When it comes to learning things, I’m a big fan of layered approach. By this I mean a methodology of study that emphasizes the history of evolution of whatever it is we are learning. Recently I’ve been applying it to Unix text editors. This post is a document of my research into this topic.

As you may or may not know, in Unix operating systems there is a line of text editors that lead to creation of famous vim. The full line looks as follows:

  • ed — “the standard text EDitor” written by Ken Thompson for the first Unix back in 1971
  • em — “the ed for Mortals” — a mod of ed featuring one-line visual editing, developed by George Coulouris in 1976
  • ex — an “eXtended” version of em written by Bill Joy at Berkley University in 1977, featuring the full-screen visual editing mode
  • vi — a hard link to ex 2.0 that starts the editor with the visual mode turned ON by default
  • vim — a “vi iMitation” developed in 1988-91 for Amiga computers. Supports syntax highlighting, various plugins, mouse, unlimited undo, word-completion etc.

You can find more vi history in wikipedia.

What I want to look at today is the great-great-grandfather of vim: the venerable ed. Using ed is like writing with ink using a goose pen. Its Zen character hides itself under the surface of false simplicity. It requires concentration and focus. It teaches you the origins of the commands you will see in vim. Try using ed for a day to edit all your text files.

If you’re running Mac or any flavor of Unix, you already have it. If you are on Windows, you can get it from here.

Open it on command line like this: “ed 1.txt”.

At first you can be shocked: No only you don’t see scrollbars, there is no fucking text visible anywhere on screen! That’s because ed is a command-centric editor. You issue commands to move in the files and to edit text, one line at a time. Here, to make your experience less shocking I’ve organized ed commands into 8 layers, each building up on the previous. Once you have tried them all, you will not only understand vim better, but also get the taste of what computers felt like back in 1972.

Layer 1. Moving around

  • h — help explain why ed said “?”
  • q — quit
  • + — go to next line
  • - — go to prev line
  • +10 — go 10 lines forward
  • -10 — go 10 lines backward
  • 123 — go to line 123
  • $ — go to last line
  • [Enter] — move through text printing one line at a time
  • z — move through text printing one screen at a time

Layer 2. Editing text

  • a — append text after current line
  • . — exit the text mode and go back to command mode
  • p — print the current line
  • d — delete current line
  • c — change the text of the current line
  • i — insert text before current line
  • Q — quit even if there are unsaved changes
  • w — write the file back to disk

Layer 3. Search and replace

  • ?abc —  go to the previous line containing “abc”
  • /abc — same as ? but searches down, and wraps over to the top of the file
  • s/abc/xyz — if current line contains “abc”, substitutes it for “xyz”
  • s — substitutes the next match on the same line
  • s/abc/xyz/3 — substitutes third match on the current line, instead of the first one
  • s/abc/xyz/g — substitutes all matches on the current line

 Layer 4. Line addressing

  • 123a — append text after line 123
  • 123i — insert text before line 123
  • 10,20d — delete lines from 10th to 20th
  • 10,20c — delete lines from 10th to 20th and enter the text that will go in their place
  • 10,20p — print lines from 10th to 20th
  • 10,20n — print lines from 10th to 20th with their line numbers
  • %p — print all lines
  • 10,20s/abc/xyz/g — substitute all occurrences of “abc” with “xyz” in lines 10 through 20
  • %s/abc/xyz/g — substitute all occurrences of “abc” with “xyz” in the entire file

Layer 5. Regular expressions

The substitute command “s/abc/xyz” supports regular expressions in its “abc” part:

  • . means any character. To search for dot, use \.
  • .* means any sequence of any characters
  • ^ means beginning of line
  • $ means end of line

Also, it supports special characters in the “xyz” part:

  • & means the actual substring matched by the “abc”
  • \[Enter] means a new line

Layer 6. Advanced editing

  • j — join the next line to the end of the current line
  • m123 — move current line in front of line 123
  • t123 — copy current line in front of line 123

(the above commands also work with multiple lines)

  • u — undo the last command. doing the  “u” again redoes the undone command.
  • 123kx — mark line 123 with label “x”
  • ‘x= — print line number of line marked with label “x”
  • ‘x — go to line marked with label “x”

Layer 7. Interaction with external world

  • !dir — execute shell command “dir” without exiting to shell
  • r !dir — execute shell command “dir” and append its output to the end of the current text
  • 10,20w 2.txt — write lines 10 through 20 to file 2.txt
  • 10,20w !cmd — send lines 10 through 20 to standard input of shell command cmd
  • f 2.txt — changes current file name to 2.txt

 Layer 8. Interactive search

  • G/abc — for each line matching “abc”, makes it current and allows user to enter a command


Next Page »