Text Editor Edit on Github
Learning Objectives
The learning objectives for Text Editor are:
- Writing a C program
- File I/O
- String Manipulation
- Leveraging a Datastructure
- Writing an Event Driven Program
Suggested Readings
We suggest you read the following from the
wikibook
before starting Text Editor:
- C Programming, Part 1: Introduction
- C Programming, Part 2: Text Input And Output
- C Programming, Part 3: Common Gotchas
- Memory, Part 1: Heap Memory Introduction
Backstory
You have just finished implementing a Document library, and now your mentor
wants you to implement a text editor using it. Since you’ve already turned your
Document over to the QA team, who have run a
brutal comprehensive set of tests
(and fixed any bugs they found), your mentor has decided to provide you with a
compiled version of the post-QA Document and Vector (as an “archive file”)
for use in your text editor.
Overview
Your editor can be run like any other editor with:
$ ./editor <filename> [window_size=20]
The filename provided will be loaded into the Document for manipulation using
Document_create_from_file(). Then, editor_main.c reads any keyboard stroke
into the text user interface (TUI) and the appropriate function in
editor.c is called. You will need to fill in the functions in editor.c.
You can optionally provide a window size (default = 20 lines) for the TUI (so long as it’s greater than or equal to 20).
Important: Lines will be 1-indexed for this assignment! Character indices are still 0-indexed.
Important: Send all your debug printing to stderr instead of stdout.
Please keep the following in mind when implementing your text editor:
- Lines are 1-indexed (are they 1-indexed in the document? Be careful!)
- There is no limit on the number of lines
- There is no limit on the number of characters per line
- Some lines may be empty (you should treat these as “”)
- Only when the user gives the save command will the contents of the file on disk be modified.
- All your editor operations should use the
Documentlibrary to modify the document. Don’t write directly to the file!
Valid documents and inputs?
For opening documents, assume that the document will always be a document created from this text editor. That means it will always have valid characters.
Remember! An empty or non-existent file can be a valid document!
Format library
We have provided a format library that handles all printing to stdout or stderr. This is to ensure that you do not lose points for not matching the format that the autograder expects.
Please take a look at format.c and format.h. These files include all the
error messages and printouts that you need. (There’s not a whole lot for this mp)
Features
Make sure your editor can perform the following basic tasks:
- Display the contents of a file.
- Insert text to a file at a specified line number and character index.
- Delete
ncharacters of text from a file at a specified line number and character index. - Delete a line of text from a file
- Find the next occurrence of text in a file and return the location of the match.
- Merge and split lines
- Save the file to disk.
- Quit the editor
Text User Interface (TUI)
Because you want to really impress your mentor, you’ve gone ahead and decided to use a text user interface (or TUI for short). Don’t worry though, we’ve already done this part for you. All you have to do is make sure that the callbacks for the TUI (defined in editor.c) work perfectly.
The TUI supports the following interaction:
- Inserting text (just type in those characters)
- Splitting a line (Press
enterwhile in the middle of a line) - Merging a line (Press
deleteat the end of a line orbackspaceat the starting of one) - Deleting text (
deleteorbackspace) - Deleting a line (
ctrl+w) - Finding text in the file (
ctrl+fto search, read below to see how search should work) - Saving the file (
ctrl+x) - Exiting (
ctrl+a)
note: You may be wondering why we use ctrl+x instead of ctrl+s to save. By default, ctrl+s locks the terminal and ctrl+q unlocks it.
Important: The TUI isn’t capable of using all of your editor’s features! For example, the TUI does not support deleting multiple characters at once. You still need to implement everything. We WILL be testing for ALL features.
Important: The TUI isn’t compatible with MacOS’s Terminal.App. Try downloading iterm2 instead! Alternatively, use the EWS machines to try the TUI. You can still test your editor by defining test cases in editor_test.c.
Location
In order to keep track of the cursor position, we have provided a struct typedef’ed to location defined in editor.h as:
typedef struct {
size_t line_no;
size_t idx;
} location;
Some functions which you will have to implement will take in a location argument to know where to edit the file.
Display contents
Your text editor should be able to print out the contents of the file that is loaded.
Suppose we had a file things_on_my_table.txt which contained the following:
mug
salt
T.V. remote
Now calling handle_display_command() with start_line and max_lines as 1
would print out the following if things_on_my_table.txt was loaded as a document.
1 mug
However, calling handle_display_command() with start_line as 1 and max_lines as 5 would print out
1 mug
2 salt
3 T.V. remote
Since there were less than 5 lines of text.
Again, make sure to use format.{c,h} to print these lines out.
Errors
If the user asks you to print a document which is empty,
call print_document_empty_error()in format.{c,h} to tell the user
that they can’t do that. You can assume that all of your functions which depend on cursor locations are always given valid locations.
Inserting text
Now using the same things_on_my_table.txt file
If a user were to call handle_insert_command() with
line = "peanuts " and loc.line_no = 1 and loc.idx = 1
The result of the file would be
1 mpeanuts ug
2 salt
3 T.V. remote
Note: If the line a user is inserting to is currently empty, that’s fine!
Note: If your editor is asked to insert to a line that does not exist
yet, then it should fill in the gap with empty lines. (How can you use
Document to make this easy?). You must handle inserts at the end
of a line (so that appending text is possible), but you do not need
to handle inserts past the end of line.
Deleting text
There are two types of deletes. Deleting characters and deleting lines.
Deleting Characters
This function is to be implemented in handle_delete_command. The current location of the cursor is defined by the location argument loc. The function will delete num_chars characters at the specified line number from the specified character index till the end of the line.
Deleting Lines
This function is to be implemented in handle_delete_line. This function takes in a size_t argument called line_no to specify the line number which should be deleted.
Finding text
Your text editor should be able to find the next occurrence of a string from the current cursor location. You will implement this in the function handle_search_command. The current location of the cursor is defined by the location argument loc. This function will return a location to inform the TUI of the location of the results.
Suppose we had the following file (already loaded into the editor):
1 According to all known laws of aviation,
2 there is no [w]ay that a bee should be
3 bees beEs Bees bees
Assume that [] represents the position of your cursor
If your user searches for the string “bee” then your cursor should move to the next instance of the string bee including and after the current character as shown below:
1 According to all known laws of aviation,
2 there is no way that a [b]ee should be
3 bees beEs Bees bees
note: the tui automatically increments the character index by one so that the search function doesn’t match the same result twice. If you’re writing your own test cases and want it to act the same way as the tui, you should handle this increment on your own. Your function in editor.c should NOT account for this.
Searching for bee again:
1 According to all known laws of aviation,
2 there is no way that a bee should be
3 [b]ees beEs Bees bees
Note that the string only has to contain the search string. It’s okay if there are characters before or after the found position.
Additionally, the search IS case-sensitive, so searching for bee again:
1 According to all known laws of aviation,
2 there is no way that a bee should be
3 bees beEs Bees [b]ees
will skip the two instances of bee with capital letters.
Finally, the search wraps around the file. So if we search for bee one more time:
1 According to all known laws of aviation,
2 there is no way that a [b]ee should be
3 bees beEs Bees bees
We’re back to the first instance of bee.
If the search string is empty or not present in the file, return a location with line_no set to 0.
The search string does not have to be a word by itself! For example if I was to search for the string ana in the following file:
1 B[a]nana
will have the above result. Searching for ana again:
1 Ban[a]na
Will just find the second instance of ana.
hint: man strstr
Merging Lines
When a user enters a backspace at the beginning of a line or delete at the end of a line, then the previous line and the current line should merge (if you used backspace, vice versa for delete).
You must implement the function handle_merge_line. This function has a location as an argument and requires you to merge the line located at line_no with the line located at line_no + 1. (We will ALWAYS call this function with a valid line number such that line_no and line_no + 1 both exist)
An example using the same lines as in the first example:
1 mpeanutsug
2 [s]alt
3 T.V. remote
Pressing backspace from the position specified by [] will merge the line:
1 mpeanutsug[s]alt
2 T.V. remote
Splitting Lines
When a user enters an enter key anywhere in a line, then the line should split.
You must implement the function handle_split_line. This function has a location as an argument and requires you to split the line located at loc.line_no at the character index loc.idx.
An example:
1 mpeanutsug[s]alt
2 T.V. remote
Pressing enter from the position specified by [] will split the line:
1 mpeanutsug
2 [s]alt
3 T.V. remote
Saving text
This should simply write the text to the file.
Implement this in the function handle_save_command
(Optional) Extending the TUI’s functionality
This part will NOT be graded.
Take a look at exts/Instructions.md for more information on how to make your own extension.
For example, you could implement a copy/paste function for lines or words.
Share your extensions on Piazza if you come up with a cool feature!
Testing
We have provided a file editor_test.c where you can programmatically test
your editor. This compiles to editor_test and editor_test-debug. We STRONGLY recommend testing by adding test cases to editor_test.c and running editor_test instead of testing using editor as the tui may overwrite any print statements you wanted to see.
Submission Instructions
Please read details on Academic Integrity fully. These are shared by all assignments in CS 241.
We will be using Subversion as our hand-in system this semester. Our grading system will checkout your most recent (pre-deadline) commit for grading. Therefore, to hand in your code, all you have to do is commit it to your Subversion repository.
To check out the provided code for
text_editor
from the class repository, go to your cs241 directory (the one you checked out for "know your tools") and run:
svn up
If you run ls you will now see a
text_editor folder, where you can find this assignment!
To commit your changes (send them to us) type:
svn ci -m "text_editor submission"
Your repository directory can be viewed from a web browser from the following URL: https://subversion.ews.illinois.edu/svn/sp17-cs241/NETID/text_editor where NETID is your University NetID. It is important to check that the files you expect to be graded are present and up to date in your SVN copy.
Assignment Feedback
We strive to provide the best assignments that we can for this course and would like your feedback on them!
This is the form we will use to evaluate assignments. We appreciate the time you take to give us your honest feedback and we promise to keep iterating on these assignments to make your experience in 241 the best it can be.
https://goo.gl/forms/z06gBY7MocFDrE3S2
