This source file includes following definitions.
- ReadFile
- PrintStatusLine
- RedrawScreen
- main
#include "lib.h"
#include "syscalls.h"
#define ctrl(x) x - 0x40
#define ESC 27
#define CLRBUFF for (count = 0; count < 80; count++) currentLineBuffer[count] = 0
#define Overwrite 0
#define Insert 1
#define WINDOWSIZE 20
struct line
{
struct line *next;
struct line *prev;
int lineno;
unsigned char *line;
};
struct line *lines;
struct line *windowStart;
int line;
int column;
char mode;
int count;
void ReadFile(FD file)
{
struct line *firstline = lines;
struct line *currline;
struct FileInfo info;
fstat(file, &info);
int filesize = info.Length;
unsigned char *buffer = malloc(filesize);
read(file, buffer, filesize);
lines = malloc(sizeof(struct line));
lines->next = 0;
lines->prev = 0;
lines->lineno = 0;
currline = lines;
int i;
while (filesize)
{
while (buffer[i] != 0x0a && i < filesize)
i++;
buffer[i] = 0;
currline->line = malloc(i + 1);
strcpy(currline->line, buffer);
buffer = buffer + i + 1;
filesize -= i + 1;
if (filesize)
{
i = 0;
currline->next = malloc(sizeof(struct line));
currline->next->prev = currline;
currline = currline->next;
}
}
}
void PrintStatusLine()
{
if (mode == Insert)
{
printf(
"%c[24;1H%c[?5h^Q Quit ^I Insert toggle Insert on ",
ESC, ESC);
printf("%c[%d;%dH%c[?5l", ESC, line, column, ESC);
}
else
{
printf(
"%c[24;1H%c[?5h^Q Quit ^I Insert toggle Insert off ",
ESC, ESC);
printf("%c[%d;%dH%c[?5l", ESC, line, column, ESC);
}
}
void RedrawScreen()
{
struct line *tempcurrline = lines;
printf("%c[2J", ESC);
tempcurrline = windowStart;
if (!windowStart) return;
for (count = 0; count <= WINDOWSIZE; count++)
{
if (tempcurrline->line)
printf("%s\n", tempcurrline->line);
if (!tempcurrline->next)
break;
tempcurrline = tempcurrline->next;
}
PrintStatusLine();
}
int main(int argc, char **argv)
{
lines = 0;
FD file;
line = 0;
column = 0;
struct line *currline;
char currentLineBuffer[80];
int count;
mode = Insert;
printf("%c[2J", ESC);
if (argc == 2)
{
file = open(argv[1]);
if (file != -1)
{
ReadFile(file);
windowStart = lines;
RedrawScreen();
}
else
{
lines = malloc(sizeof(struct line));
lines->next = 0;
lines->prev = 0;
lines->lineno = 0;
lines->line = malloc(80);
}
currline = lines;
}
int done = 0;
PrintStatusLine();
CLRBUFF;
char c;
if (currline->line)
strcpy(currentLineBuffer, currline->line);
while (!done)
{
c = getchar();
switch (c)
{
case ctrl('Q'):
done = 1;
break;
case ctrl('I'):
if (mode == Insert)
mode = Overwrite;
else
mode = Insert;
PrintStatusLine();
break;
case ctrl('M'):
;
int linelength = strlen(currentLineBuffer);
currentLineBuffer[column] = 0;
free(currline->line);
currline->line = malloc(strlen(currentLineBuffer) + 1);
currentLineBuffer[column] = 0;
strcpy(currline->line, currentLineBuffer);
struct line *temp = malloc(sizeof(struct line));
temp->next = currline->next;
currline->next = temp;
if (temp->next)
temp->next->prev = temp;
temp->prev = currline;
if (column < linelength)
{
temp->line = malloc(strlen(currentLineBuffer + column) + 1);
strcpy(temp->line, currentLineBuffer + column + 1);
}
else
{
temp->line = malloc(1);
temp->line[0] = 0;
}
CLRBUFF;
strcpy(currentLineBuffer, temp->line);
column = 0;
line++;
currline = currline->next;
RedrawScreen(windowStart);
break;
case ctrl('U'):
if (currline->prev)
{
line--;
free(currline->line);
currline->line = malloc(strlen(currentLineBuffer) + 1);
strcpy(currline->line, currentLineBuffer);
currline = currline->prev;
CLRBUFF;
if (currline->line)
strcpy(currentLineBuffer, currline->line);
if (column > strlen(currentLineBuffer))
column = strlen(currentLineBuffer);
printf("%c[%d;%dH", ESC, line, column);
if (line < 0)
{
windowStart = windowStart->prev;
line++;
RedrawScreen();
}
}
break;
case ctrl('D'):
if (currline->next)
{
line++;
free(currline->line);
currline->line = malloc(strlen(currentLineBuffer) + 1);
strcpy(currline->line, currentLineBuffer);
currline = currline->next;
CLRBUFF;
if (currline->line)
strcpy(currentLineBuffer, currline->line);
if (column > strlen(currentLineBuffer))
column = strlen(currentLineBuffer);
printf("%c[%d;%dH", ESC, line, column);
if (line > WINDOWSIZE)
{
windowStart = windowStart->next;
line--;
RedrawScreen();
}
}
break;
case ctrl('L'):
if (column)
{
printf("%c[1D", ESC);
column--;
}
break;
case ctrl('R'):
if (column < 80 && column < strlen(currentLineBuffer))
{
column++;
printf("%c[1C", ESC);
}
break;
case 8:
if (column)
{
int i;
for (i = column; i < 80; i++)
currentLineBuffer[i - 1] = currentLineBuffer[i];
column--;
printf("%c[1D", ESC);
printf("%s", currentLineBuffer + column);
printf("%c[%d;%dH", ESC, line, column);
}
break;
default:
if (mode == Insert)
{
int i;
for (i = 80; i > column; i--)
currentLineBuffer[i] = currentLineBuffer[i - 1];
}
currentLineBuffer[column] = c;
printf("%s", currentLineBuffer + column);
if (column < 80)
column++;
printf("%c[%d;%dH", ESC, line, column);
break;
}
}
free(currline->line);
currline->line = malloc(strlen(currentLineBuffer) + 1);
strcpy(currline->line, currentLineBuffer);
printf("%c[2J", ESC);
if (file != -1)
{
close(file);
unlink(argv[1]);
}
file = creat(argv[1]);
currline = lines;
if (file)
{
while (currline)
{
if (currline->line)
{
write(file, currline->line, strlen(currline->line));
write(file, "\n", 1);
}
currline = currline->next;
}
close(file);
}
free(lines->line);
free(lines);
exit();
return 0;
}