# String manipulation

The challenge is to manipulate strings using basic Vim-like commands

Input:

• A string of text to be transformed. The input alphabet is [a-z].
• A string of legal commands

Output:

• The transformed string

There are a few ideas you should understand:

The cursor is represented as a location between 2 characters. | will be used to represent the cursor(s) in this explanation.

• |foobar - The cursor at beginning of string
• foo|bar - Cursor in the middle of the string
• foobar| - Cursor at the end of the string

A selection is a a group of characters between 2 cursors.

• |foobar| - The selection is foobar
• |foo|bar - The selection is foo
• foo|bar| - the selection is bar
• |foobar - The selection is the empy string (both cursors at same location)

A selection is formed from the previous cursor position and the result of the current command.

Using the command > on |foo would make the selection |f|oo.

Commands can be described as functions. C<selection> is a command that has a selection parameter. The next command provides the selection.

• D> deletes the character to the right of the cursor. f|oo -> f|o
• DNa deletes from the cursor to the next a character f|oobar -> f|ar
• Etc.

As you can see, commands "associate to the right"

• DNa is parsed as (D(Na))
• DDNa is parsed as (D(D(Na)))
• Etc.

The insert mode command I extends until the next command.

• DIbar> is parsed as (D(Ibar))(>).

These are the commands:

• > - Move cursor right. > on foo|bar -> foob|ar
• < - Move cursor left. < on foo|bar -> fo|obar
• B - Move cursor to the beginning of the string
• E - Move cursor to the end of the string
• N<char> - Move cursor to place before next <char>. Na on |foobar -> foob|ar
• P<char> - Move cursor to place after previous <char>. Po on foobar| -> foo|bar
• I<string> - Enter/exit insert mode. Characters in <string> are inserted at the current cursor position. <string> extends until the next command. The cursor is moved to end of insertion <string>. Iquz on foo|bar -> fooquz|bar
• D<selection> - delete characters in <selection>. f|ooba|r -> f|r. The output selection from this command is the empty string.

Notes:

• The cursor cannot move out of bounds. B<<< is the same as B. Nx is the same as E if no x can be found.
• The cursor location always starts at the beginning of the string
• The cursor should not be outputted
• Commands are always uppercase, characters are lowercase.

Restrictions:

• No text editor scripts like Vimscript

Winning criteria:

• It's code golf. Lowest character count wins.

Examples:

Input:

• foobar
• >>><<>If

Output:

• fofobar

Input:

• foobar
• >>>DNEDPf

Output:

• f

Input:

• foobar
• >>>DDDDIbazD<Iquz>DPfDII

Output:

• far
• "<string> extends until the next command." But how do we know that it's a command rather than part of the string? Jan 21, 2012 at 21:59
• @PeterTaylor Commands are uppercase, characters are lower. Jan 21, 2012 at 22:04
• I'm starting to think that this question might be a bit too complicated for a code-golf tag. Jan 23, 2012 at 15:47
• The first example is like teaching a 4th grader how to multiply; the second example is like trying to teach that 4th grader algebra, and the third example is like trying to teach that 4th grader calculus. Jan 24, 2012 at 15:14

z l b n i=p where
p(a:c@ ~(q:u))|Just x<-alookupzip"<>BEDNP"[l#c,m l#c,b#c,m b#c,z(d$k id)(\k _->k"")h(k f)c,m(n q)#u,n q#u]=x p('I':q:c)|q>''=i q c;p(_:c)=f c;p""=(++).r d f k(q:x)=k x.f q;d f k""=k"";k&x=k"".(r x++);h q=(.snd.s q);n q k=(\(a,b)->k b.(r a++)).s q x%c=f c""x;f=z(d(:))(&)n$ \q c->f('I':c).(q:);m f=flip.f.flip;k=const;r=reverse;(#)=(.f);s=span.(/=)


This defines a function % which returns the result of applying the string of commands to the original string.

Example usage:

> "foobar" % ">>>DNEDPf"
"f"
> "foobar" % ">>>DDDDIbazD<Iquz>DPfDII"
"far"
`