CS 1410-20 Homework 2
Due: Friday, September 10th, 2010 9:40am
This assignment builds on the text editor of HW 1.
You’ll want to copy over your implementation of insert-at,
or use this one:
;; insert-at : string num string -> string
;; Inserts new into orig at position n
(define (insert-at orig n new)
(string-append (substring orig 0 n)
new
(substring orig n)))
Part 1 – Caret Position
A more realistic text editor lets the user position the caret for
inserting text that is typed (instead of always inserting into the
middle). In that case, the state of the text editor consists of two
parts: the content string and the position of the insertion caret.
;; An editor1 is
;; (make-editor1 string num)
;; where the num is always between 0 and
;; the length of the string
(define-struct editor1 (content caret))
|
(make-editor1 "hello" 3) |
Implement the function insert1, which takes a editor1
and a string and returns an editor1 with the given string
inserted at the current caret place. The caret place should
be advanced as many characters as the inserted string.
For example, (insert1 (make-editor1 "hello" 3) "q") should produce
(make-editor1 "helqlo" 4).
| (make-editor1 "hello" 3) |
| → "q" → | | (make-editor1 "helqlo" 4) |
|
Part 2 – Optional: Editor Image
This part is optional.
Write an editor1-image function that takes an editor1
and produces an image that shows the editor text with a vertical
line at the caret place (which is between characters in the content).
This function is similar to editor-image from HW 1,
except that the caret is not always in the middle of the content.
You can now add (require 2htdp/universe) at the beginning of
your program and then add
;; main : editor1 -> editor1
(define (main starting-editor1)
(big-bang starting-editor1
(on-key insert)
(to-draw editor1-image)))
In the interactions window (that is, not in the main program that
you hand in, please), you can run (main (make-editor1 "" 0)) to start your text
editor. At this point, however, typing plain characters will insert them at the
end.
Part 3 – Caret Movement
With your current text editor, if you hit the left-arrow key, then
the text “left” is inserted into your editor. That’s because the
function provided with on-key in big-bang receives the
string "left" when you hit the left-arrow key. In general, keys
that correspond to text that should be inserted are represented as
single-character strings, while most other special keys are
represented by multi-character strings (such as "left" for the
left-arrow key or "f2" for the F2 key).
Define a function insert-or-move1 that takes an editor1
and a string. It should behave like insert1 if the string contains a
single character. If the string is "left", it should decrease the
editor’s caret place by one but go no lower than 0. If the string
is "right", it should increase the
editor’s caret place by one, but go no higher than
the length of the content string. All other multi-character strings
should have no effect on the content of the editor.
For example, (insert-or-move1 (make-editor1 "hello" 3) "q")
should produce (make-editor1 "helqlo" 4), while
(insert-or-move1 (make-editor1 "hello" 3) "left") hould produce
(make-editor1 "hello" 2).
| (make-editor1 "hello" 3) |
| → "left" → | | (make-editor1 "hello" 2) |
|
To avoid going lower than 0, you may find it useful to use
the max function with 0 and anther expression. To avoid
going higher than the length of the content string, you may find it
useful to use the min function.
You can change the main function to use insert-or-move1
instead of insert1, and now you can move the caret in the text
editor.
Part 4 – The Backspace/Delete Key
The delete key is unusual, in that is is represented by a
single-character string where the character cannot be written in the
usual way. This special string is written as "\b". The backslash
and “b” together create a single character within the string.
Define a function change-or-move1 that is like
insert-or-move1, except that if the string is "\b",
then the character just before the caret in the editor is removed,
and the caret place is decreased by one.
If the caret is at place 0, no content is removed from the editor.
For example, (change-or-move1 (make-editor1 "hello" 3) "\b")
should produce (make-editor1 "helo" 2).
| (make-editor1 "hello" 3) |
| → "\b" → | | (make-editor1 "helo" 2) |
|
You should reuse insert-or-move1, rather than copying its
implementation into change-or-move1. Also, you may find it useful
to implement a helper function remove-chars, which could take
a string, a starting position within the string, and a number of
characters to remove from the string.
Part 5 – Caret or Selection Range
A yet-more realistic text editor allows the caret to be expanded
into a selection range. Typically, the selection can be extended by
holding down the shift key in combination with the left- or
right-arrow key. To keep things simple, we will use the up-arrow key
instead of shift-left-arrow, and we’ll use the down-arrow key instead of
shift-right-arrow.
To represent an editor with a caret that is expanded to a
selection, we use the following data definitions:
;; An editor2 is
;; (make-editor2 string num num)
;; where the first num is always between 0 and
;; the one less length of the string, and the second
;; num is greater than the first and less or equal
;; to the length of the string
(define-struct editor2 (content left right))
;; An editor is either
;; - an editor1
;; - an editor2
Using these data defintions, (make-editor1 "nihao" 5)
represents a caret at position 5 in the editor (i.e., after the “o”
in “nihao”), while (make-editor2 "nihao" 2 4) represents a
selection that covers the third and fourth characters in the
editor (i.e., the “ha” part of “nihao”).
|
(make-editor2 "nihao" 2 4) |
Implement the function move-left, which takes an
editor and returns a editor after the left-arrow key is
pressed. Specifically:
Of course, you should implement move-left by
implementing move-left1 and move-left2,
since editor is defined in terms of editor1 and editor.
For now, do not try to reuse change-or-move1 or insert-or-move1.
For example, (move-left (make-editor1 "hello" 2)) should produce
(make-editor1 "hello" 1), while (move-left (make-editor2 "hello" 2
4)) should produce (make-editor1 "hello" 2).
Part 6 – Moving Carets and Selections
Implement the function handle-key, which takes an
editor and a key string and returns an editor after the key
is handled according to the following rules:
This function is complicated, but you should be able to break it
down into smaller problems. Of course, you will need to implement
handle-key by implementing handle-key1 and
handle-key2. For handle-key1, you should reuse
change-or-move1, which works for any key except "up" or
"down".
Some examples:
(check-expect (handle-key (make-editor1 "hello" 5) "left")
(make-editor1 "hello" 4))
(check-expect (handle-key (make-editor1 "hello" 5) "right")
(make-editor1 "hello" 5))
(check-expect (handle-key (make-editor1 "hello" 5) "up")
(make-editor2 "hello" 4 5))
(check-expect (handle-key (make-editor1 "hello" 5) "down")
(make-editor1 "hello" 5))
(check-expect (handle-key (make-editor2 "hello" 3 5) "right")
(make-editor1 "hello" 5))
(check-expect (handle-key (make-editor2 "hello" 3 5) "down")
(make-editor2 "hello" 3 5))
(check-expect (handle-key (make-editor2 "hello" 3 4) "f2")
(make-editor2 "hello" 3 4))
(check-expect (handle-key (make-editor1 "hello" 3) "q")
(make-editor1 "helqlo" 4))
(check-expect (handle-key (make-editor2 "hello" 1 3) "\b")
(make-editor1 "hlo" 1))
Part 7 – Optional: General Editor Image
This part is optional.
Write an editor2-image function that takes an editor2
and produces an image that shows the editor text with the selected
range as white-on-black. Recall that you learned how to put an image
on a color background in HW 0.
Write editor-image, which uses editor1-image and
editor2-image to create an image for any editor.
Finally, change main to
;; main : editor -> editor
(define (main starting-editor)
(big-bang starting-editor
(on-key handle-key)
(to-draw editor-image)))
and you can run your fairly realistic single-line text editor with
(main (make-editor1 "" 0)).
Last update: Wednesday, October 20th, 2010mflatt@cs.utah.edu |