I am trying to create an NSTextView that behaves somewhat like a series of typewriter pages — each page has a fixed number of rows and columns available.
The underlying representation ideally match the display, which in turn matches the file format. Pages end with a form-feed character '\f'. For example, two 4×4 pages would look like this when saved (spaces between characters for readability):
T H I S \n
P A G E \n
I S \n
F U L L \n
\f
N O T \n
T H I S \n
O N E \n
\n
\f
A few things to notice:
- Newlines and form-feeds don’t count in the row/column total
- Lines shorter than the column count are not padded with trailing whitespace (though they could be if the editor worked in overwrite mode)
- Pages shorter than the row count are padded with newlines
I tried a few approaches, like converting the text to a NSArray of lines and splitting long lines on every textDidChange notification, then setting the text to the concatenated lines, but it is really inefficient, and loses cursor position if typing happens anywhere except the end of the document.
In the end, I think I’d like this to behave as a large page populated with whitespace, and typing only happens in overwrite mode, but wraps at the end of lines. I’m not sure where to begin with that approach. Any suggestions?
I have found an acceptable, if not perfect, solution for wrapping by subclassing
NSTextStorage.It behaves entirely as expected when adding text to the end of the document, whether pasting or typing. It also behaves when deleting or replacing text. The only place it is a little strange is when inserting text into the middle of already-full lines. That will cause a wrap just before the inserted text. It works fine, but it means that continuing to type at that position will create a number of short lines.
For example, the text below wraps at 20 columns. Original text is
x, and inserted text iso. The inserted text begins on the second line, at the 8th character.Code below: