- Create a new file named
kilo.c. - Write a
main()function that takes no arguments and returns0. - Create a
Makefilethat compileskilo.ctokilowhen you typemake.- Use
$(CC)for the compiler. - Turn on warnings using the
-Wall -Wextra -pedanticoptions. - Turn on C99 mode using the
-std=c99option.
- Use
- In
main(), Declare acharvariable namedc. - Include
<unistd.h>. - Read a single byte from standard input into
crepeatedly usingread(), untilread()returns an error or reaches the end of file. - Stop the
read()loop as soon asccontains the character'q'. - Create an
enableRawMode()function abovemain()that takes no arguments and doesn't return anything. - Call
enableRawMode()at the top ofmain(). - Include
<termios.h>. - In
enableRawMode(), declare astruct termiosvariable namedraw. - Call
tcgetattr()to load terminal attributes intoraw. - Turn off the
ECHObit in thec_lflagfield ofraw. - Call
tcsetattr()to apply the attributes inrawback to the terminal. (UseTCSAFLUSHfor the second argument.) - Declare a global
struct termiosvariable namedorig_termios, aboveenableRawMode(). - Change the
tcgetattr()call to load theorig_termiosvariable instead ofraw. - Move the declaration of
rawafter thetcgetattr()call, and initialize it to the value oforig_termios. - Create a
disableRawMode()function aboveenableRawMode()that takes no arguments and doesn't return anything. - In
disableRawMode(), calltcsetattr()to set the terminal attributes to the original ones saved inorig_termios. - Include
<stdlib.h>. - In
enableRawMode(), aftertcgetattr(), useatexit()to registerdisableRawMode()to be called when the program exits. - Turn off the
ICANONbit in thec_lflagfield ofraw. - Include
<ctype.h>. - Include
<stdio.h>. - In the
read()loop inmain(), useisprint()to check ifcis printable. If it is, useprintf()to print it out as both an ASCII code in decimal, and as a character. If it's not, then just print out its ASCII code. - Turn off the
ISIGbit in thec_lflagfield ofraw. - Turn off the
IXONbit in thec_iflagfield ofraw. - Turn off the
ICRNLbit in thec_iflagfield ofraw. - Turn off the
OPOSTbit in thec_oflagfield ofraw. - If your
printf()statements print\nat the end, change them to print\r\ninstead. - Turn off the
IEXTENbit in thec_lflagfield ofraw. - Turn off the
BRKINT,INPCK, andISTRIPbits in thec_iflagfield ofraw. - Set the
CS8bitmask in thec_cflagfield ofraw. - Set
raw.c_cc[VMIN]to0. - Set
raw.c_cc[VTIME]to1. - In
main(), ignore the return value ofread(). - At the beginning of the loop in
main(), setcto the nul character before theread()call. - Create a
die()function abovedisableRawMode()that takes a string namedsand doesn't return anything. - In
die(), callperror()and passsto it. - At the end of
die(), callexit()with a non-zero exit status. - For each of the 3 calls to
tcgetattr()ortcsetattr(), check if the return value is-1, and if so, calldie()passing it the name of the function that failed (either"tcgetattr"or"tcsetattr"). - Check if the
read()call returns-1, and if so, calldie()passing it the name of theread()function. - We'll split up the file into sections so we can talk about it easier. A
section begins with a comment that looks like
/*** name of section ***/on its own line. At the top of the file, add an/*** includes ***/section. - Above the
orig_termiosdeclaration, add a/*** data ***/section. - Above the
die()function, add a/*** terminal ***/section. - Above the
main()function, add an/*** init ***/section. - Above the
/*** data ***/section, add an/*** defines ***/section. - In the
/*** defines ***/section, define a macro namedCTRL_KEYthat takes one argument, and sets all the bits in the given value to0except for the lowest 5 bits. - Instead of breaking out of the
main()loop whencis equal to'q', break out of the loop whencis equal toCTRL_KEY('q'). - Create an
editorReadKey()function belowenableRawMode()that takes no arguments and returns achar. - Move the
cvariable and theread()call frommain()into the neweditorReadKey()function. - Have
editorReadKey()keep callingread()untilread()returns1, thenreturnthe character that it read. - Above the
/*** init ***/section, add an/*** input ***/section. - In the
/*** input ***/section, create aneditorProcessKeypress()function that takes no arguments and doesn't return anything. - In
editorProcessKeypress(), calleditorReadKey()and store the result in acharnamedc. - Use a
switchstatement to callexit()with a0exit status whencis equal toCTRL_KEY('q'). - In
main(), replace the loop with an infinite loop that just callseditorProcessKeypress()repeatedly. - Above the
/*** input ***/section, add an/*** output ***/section. - In the
/*** output ***/section, create aneditorRefreshScreen()function that takes no arguments and doesn't return anything. - In
editorRefreshScreen(), usewrite()to write the escape sequence"\x1b[2J"to standard output. - At the top of the
main()loop, calleditorRefreshScreen(). - At the end of
editorRefreshScreen(), usewrite()to write the escape sequence"\x1b[H"to standard output. - Copy and paste those two
write()calls to the top of thedie()function. - Copy and paste those same two
write()calls to the top of theCTRL_KEY('q')case of theswitchstatement ineditorProcessKeypress(). - Above
editorRefreshScreen(), create aneditorDrawRows()function that takes no arguments and doesn't return anything. - In
editorDrawRows(), declare anintnamedyand have it loop through the values0to23inclusive. - For each value of
y, usewrite()to write the string"~\r\n"to standard output. - At the end of
editorRefreshScreen(), calleditorDrawRows(). - At the end of
editorRefreshScreen(), usewrite()to write the escape sequence"\x1b[H"to standard output. - At the top of the
/*** data ***/section, define astructtype namededitorConfig, and move theorig_termiosvariable into it. - Below the
editorConfigstruct, declare a globalstruct editorConfigvariable namedE. - In
disableRawMode()andenableRawMode(), replace the 3 occurrences oforig_termioswithE.orig_termios. - Below
editorReadKey(), create agetWindowSize()function that takes twointpointers namedrowsandcolsas arguments, and returns anint. - Include
<sys/ioctl.h>. - In
getWindowSize(), declare astruct winsizevariable namedws. - Call
ioctl()with theTIOCGWINSZrequest to load thewsvariable with the window dimensions. - If
ioctl()returns-1, or if thews_colfield ofwsis0, then return-1to indicate an error occurred. Otherwise, set therowsandcolsreferences to thews_rowandws_colfields ofws, and return0to indicate success. - At the top of the
editorConfigstruct, add twointfields namedscreenrowsandscreencols. - Above
main(), create aninitEditor()function that takes no arguments and doesn't return anything. - In
initEditor(), callgetWindowSize(), passing thescreenrowsandscreencolsfields ofEby reference. If it returns-1, then calldie()with the name of thegetWindowSize()function. - In
main(), callinitEditor()after theenableRawMode()call. - In
editorDrawRows(), useE.screenrowsas the (exclusive) upper bound fory, instead of the (inclusive)23we hardcoded earlier.
Created
March 24, 2017 22:46
-
-
Save paigeruten/88d4d5ed534edd66edcbc529a62e087a to your computer and use it in GitHub Desktop.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment