#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <stdio.h>
#include <string>
#include <map>
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define H 30
#define W 100
#define helps "\
<Ctrl+Enter> : command\n\
<h,H,?> : help\n\
<s,S> : save\n\
<q,Q> : quit and save\n\
<!> : quit\n\
<o,O> : compile\n\
<t,T,^> : top\n\
<l,L,y,Y,@> num : y = num\n\
<x,X> num : x = num\n\
<k,K> str : str = keyword\n\
<p,P> str num : str = color (num)\n\
<w,W,$> + Enter+ str : system (str)\n\
<c,C,=> : copy\n\
<v,V,~> : paste\n\
< < > str : find(str)\n\
< > > str : find(str)\n\
<-> num : erase(num)\n\
<{> num,begin,step : {begin,begin+step,begin+step*2,...}\n\
<\"> num,begin,step : \"begin,begin+step,begin+step*2,...\"\n\
<|> num,begin,step,+ :\n\
<|> num,begin,step,- :\n\
"
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
#define color(tc) SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), tc)
#define gotoxy(xx, yy) \
do{ \
COORD position = {xx, yy}; \
SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), position); \
}while(false)
typedef signed char int8;
typedef signed short int16;
typedef signed long int32;
typedef signed long long int64;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;
typedef unsigned long long uint64;
typedef unsigned char byte_t;
typedef unsigned short word_t;
typedef unsigned long iterator;
typedef void* pointer_t;
template <typename type> class vector {
public:
type* p;
size_t Len;
size_t Size;
vector () {
p = NULL;
Len = 0;
Size = 0;
}
~vector () {
delete[] p;
}
size_t size () {
return Size;
}
size_t len () {
return Len;
}
void exp () {
Len = (Len << 1) + 1;
if (p == NULL) {
p = new type [ Len ];
} else {
type *tp = new type [ Len ];
for (size_t it = 0; it < Size; it++)
tp[ it ] = p[ it ];
delete[] p;
p = tp;
}
return;
}
void exp (size_t ts) {
while (ts >= Len)
exp ();
return;
}
type& operator [] (size_t it) {
if (it >= Len)
exp (it);
return p[ it ];
}
type at (size_t it) {
if (it >= Len)
exp (it);
return p[ it ];
}
void push_back (type& x) {
if (Size == Len)
exp ();
p[ Size++ ] = x;
return;
}
void push_back (type&& x) {
if (Size == Len)
exp ();
p[ Size++ ] = x;
return;
}
void push_back (vector <type>& vc) {
for (size_t i = 0; i < vc.size(); i++)
push_back (vc[i]);
return;
}
void pop_back () {
if (Size > 0)
Size--;
return;
}
void pop_back (size_t ts) {
if (Size >= ts)
Size -= ts;
else
Size = 0;
return;
}
void insert (size_t it, type& x) {
if (Size == Len) exp ();
for (size_t it_t = Size; it_t > it; it_t--)
p[ it_t ] = p[it_t - 1];
p[ it ] = x;
Size++;
return;
}
void insert (size_t it, type&& x) {
if (Size == Len)
exp ();
for (size_t it_t = Size; it_t > it; it_t--)
p[ it_t ] = p[it_t - 1];
p[ it ] = x;
Size++;
return;
}
void erase (size_t it) {
Size--;
for (size_t it_t = it; it_t < Size; it_t++)
p[ it_t ] = p[it_t + 1];
return;
}
void reverse () {
for (size_t it = 0; it < (Size >> 1); it++) {
type tt = p[ it ];
p[ it ] = p[Size - it - 1];
p[Size - it - 1] = tt;
}
return;
}
void operator ++ () {
if (Size == Len)
exp ();
Size++;
return;
}
void operator ++ (int) {
if (Size == Len)
exp ();
Size++;
return;
}
void operator += (type& x) {
if (Size == Len)
exp ();
p[ Size++ ] = x;
return;
}
void operator += (type&& x) {
if (Size == Len)
exp ();
p[ Size++ ] = x;
return;
}
void operator += (vector <type>& vc) {
for (size_t i = 0; i < vc.size(); i++)
push_back (vc[i]);
return;
}
void operator -- () {
if (Size > 0)
Size--;
return;
}
void operator -- (int) {
if (Size > 0)
Size--;
return;
}
void operator -= (size_t ts) {
if (Size >= ts)
Size -= ts;
else Size = 0;
return;
}
void operator = (vector <type>& vc) {
for (size_t i = 0; i < vc.size(); i++)
push_back (vc[i]);
return;
}
};
template <typename type> struct node {
type v;
node <type>* pre;
node <type>* next;
node () {
pre = next = NULL;
}
};
template <typename type> class list {
public:
node <type>* head;
node <type>* tail;
list () {
head = new node <type>;
tail = new node <type>;
head -> next = tail;
tail -> pre = head;
}
~list () {
node <type>* fn = head;
node <type>* sn = head;
while (fn !=NULL) {
sn = sn -> next;
delete fn;
fn = sn;
}
}
node <type>* begin () {
return head;
}
node <type>* end () {
return tail;
}
void push_back (type& x) {
node <type>* tn = new node <type>;
tn -> v = x;
tn -> pre = tail -> pre;
tn -> next = tail;
tail -> pre -> next = tn;
tail -> pre = tn;
return;
}
void push_back (type&& x) {
node <type>* tn = new node <type>;
tn -> v = x;
tn -> pre = tail -> pre;
tn -> next = tail;
tail -> pre -> next = tn;
tail -> pre = tn;
return;
}
void push_back (list <type>& tl) {
node <type>* tn = tl.begin();
tn = tn -> next;
while (tn != tl.end()) {
push_back(tn -> v);
tn = tn -> next;
}
return;
}
void pop_back () {
node <type>* tn = tail -> pre;
if (tn != head) {
tail -> pre = tn -> pre;
tn -> pre -> next = tail;
delete tn;
}
return;
}
void insert (node <type>* in, type& x) {
node <type>* tn = new node <type>;
tn -> v = x;
tn -> pre = in;
tn -> next = in -> next;
in -> next -> pre = tn;
in -> next = tn;
return;
}
void insert (node <type>* in, type&& x) {
node <type>* tn = new node <type>;
tn -> v = x;
tn -> pre = in;
tn -> next = in -> next;
in -> next -> pre = tn;
in -> next = tn;
return;
}
void erase (node <type>* en) {
node <type>* tn = en -> next;
if (tn != tail) {
en -> next = tn -> next;
tn -> next -> pre = en;
delete tn;
}
return;
}
void operator += (type& x) {
node <type>* tn = new node <type>;
tn -> v = x;
tn -> pre = tail -> pre;
tn -> next = tail;
tail -> pre -> next = tn;
tail -> pre = tn;
return;
}
void operator += (type&& x) {
node <type>* tn = new node <type>;
tn -> v = x;
tn -> pre = tail -> pre;
tn -> next = tail;
tail -> pre -> next = tn;
tail -> pre = tn;
return;
}
void operator += (list <type>& tl) {
node <type>* tn = tl.begin();
tn = tn -> next;
while (tn != tl.end()) {
push_back(tn -> v);
tn = tn -> next;
}
return;
}
void operator -- () {
node <type>* tn = tail -> pre;
if (tn != head) {
tail -> pre = tn -> pre;
tn -> pre -> next = tail;
delete tn;
}
return;
}
void operator = (list <type>& tl) {
node <type>* tn = tl.begin();
tn = tn -> next;
while (tn != tl.end()) {
push_back(tn -> v);
tn = tn -> next;
}
return;
}
};
list <vector <char> > doc;
node <vector <char> >* ty;
iterator tx;
node <vector <char> >* py;
iterator px;
short cnt;
size_t lines;
char name[64];
char path[64];
bool isat[256];
std::map <std::string, byte_t> keyword;
void whelp () {
FILE* fp = fopen ("FCDOC\\help.txt", "w");
fprintf (fp, helps);
fclose (fp);
return;
}
void rpath () {
FILE* fp = fopen ("FCDOC\\path.txt", "r");
if (fp == NULL) {
printf ("Input path:");
gets (path);
FILE* sf = fopen ("path.txt", "w");
fprintf (sf, "%s", path);
fclose (sf);
} else {
fscanf (fp, "%s", path);
}
fclose (fp);
}
void init (int argc, char** argv) {
printf ("init...\n");
system ("title FastCode 1.6.0");
system ("mode con lines=32 cols=132");
if (argc != 1) {
int ch;
vector <char> tv;
FILE* fp = fopen (argv[1], "r");
printf ("Loadind...\n");
iterator nt = strlen (argv[1]) - 1;
for (; nt > 0; nt--) {
if (argv[1][nt] == '\\')
break;
}
for (iterator it = 0; argv[1][nt] != '\0'; it++)
name[it] = argv[1][++nt];
ch = fgetc (fp);
while (ch != EOF) {
if (ch == 10) {
node <vector <char> >* tn = new node <vector <char> >;
for (iterator it = 0; it < tv.size(); it++)
tn -> v.push_back (tv[it]);
tn -> pre = doc.tail -> pre;
tn -> next = doc.tail;
doc.tail -> pre -> next = tn;
doc.tail -> pre = tn;
while (tv.size () != 0)
tv.pop_back ();
} else if (ch == 9) {
tv += ' ';
tv += ' ';
tv += ' ';
tv += ' ';
} else {
tv += ch;
}
printf ("%c", ch);
ch = fgetc(fp);
}
if (tv.size () != 0) {
node <vector <char> >* tn = new node <vector <char> >;
for (iterator it = 0; it < tv.size(); it++)
tn -> v.push_back (tv[it]);
tn -> pre = doc.tail -> pre;
tn -> next = doc.tail;
doc.tail -> pre -> next = tn;
doc.tail -> pre = tn;
}
fclose(fp);
} else {
printf ("Input name:");
vector <char> tv;
doc += tv;
gets (name);
}
char ts[64];
sprintf (ts, "title %s", name);
system (ts);
ty = doc.begin () -> next;
tx = 0;
py = doc.begin () -> next;
px = 0;
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cursor_info);
isat['~'] = true;
isat['!'] = true;
isat['%'] = true;
isat['^'] = true;
isat['&'] = true;
isat['*'] = true;
isat['('] = true;
isat[')'] = true;
isat['-'] = true;
isat['+'] = true;
isat['='] = true;
isat['{'] = true;
isat['}'] = true;
isat['['] = true;
isat[']'] = true;
isat['|'] = true;
isat[':'] = true;
isat[';'] = true;
isat['<'] = true;
isat['>'] = true;
isat[','] = true;
isat['.'] = true;
isat['?'] = true;
isat['/'] = true;
keyword["alignas"] = 11;
keyword["alignof"] = 11;
keyword["and"] = 11;
keyword["and_eq"] = 11;
keyword["asm"] = 11;
keyword["auto"] = 11;
keyword["bitand"] = 11;
keyword["bitor"] = 11;
keyword["bool"] = 11;
keyword["break"] = 11;
keyword["case"] = 11;
keyword["catch"] = 11;
keyword["char"] = 11;
keyword["char16_t"] = 11;
keyword["char32_t"] = 11;
keyword["class"] = 11;
keyword["compl"] = 11;
keyword["const"] = 11;
keyword["constexpr"] = 11;
keyword["const_cast"] = 11;
keyword["continue"] = 11;
keyword["decltype"] = 11;
keyword["default"] = 11;
keyword["delete"] = 11;
keyword["do"] = 11;
keyword["double"] = 11;
keyword["dynamic_cast"] = 11;
keyword["else"] = 11;
keyword["enum"] = 11;
keyword["explicit"] = 11;
keyword["export"] = 11;
keyword["extern"] = 11;
keyword["false"] = 11;
keyword["float"] = 11;
keyword["for"] = 11;
keyword["friend"] = 11;
keyword["goto"] = 11;
keyword["if"] = 11;
keyword["inline"] = 11;
keyword["int"] = 11;
keyword["long"] = 11;
keyword["mutable"] = 11;
keyword["namespace"] = 11;
keyword["new"] = 11;
keyword["noexcept"] = 11;
keyword["not"] = 11;
keyword["not_eq"] = 11;
keyword["nullptr"] = 11;
keyword["operator"] = 11;
keyword["or"] = 11;
keyword["or_eq"] = 11;
keyword["private"] = 11;
keyword["protected"] = 11;
keyword["public"] = 11;
keyword["register"] = 11;
keyword["reinterpret_cast"] = 11;
keyword["return"] = 11;
keyword["short"] = 11;
keyword["signed"] = 11;
keyword["sizeof"] = 11;
keyword["static"] = 11;
keyword["static_assert"] = 11;
keyword["static_cast"] = 11;
keyword["struct"] = 11;
keyword["switch"] = 11;
keyword["template"] = 11;
keyword["this"] = 11;
keyword["thread_local"] = 11;
keyword["throw"] = 11;
keyword["true"] = 11;
keyword["try"] = 11;
keyword["typedef"] = 11;
keyword["typeid"] = 11;
keyword["typeof"] = 11;
keyword["typename"] = 11;
keyword["union"] = 11;
keyword["unsigned"] = 11;
keyword["using"] = 11;
keyword["virtual"] = 11;
keyword["void"] = 11;
keyword["volatile"] = 11;
keyword["wchar_t"] = 11;
keyword["while"] = 11;
keyword["xor"] = 11;
keyword["xor_eq"] = 11;
system ("cls");
return;
}
void save () {
FILE* fp = fopen(name, "w");
node <vector <char> >* sp = doc.begin () -> next;
while (sp != doc.end ()) {
for (iterator it = 0; it < sp -> v.size(); it++)
fputc (sp -> v[it], fp);
fputc ('\n', fp);
sp = sp -> next;
}
fclose(fp);
return;
}
void doccopy (const char* from, const char* to) {
FILE* fp = fopen (from, "r");
if (fp == NULL) {
printf ("Fail!\n");
return;
}
FILE* tp = fopen (to, "w");
char ch;
ch = fgetc (fp);
while (ch != EOF) {
fputc (ch, tp);
ch = fgetc (fp);
}
fclose (fp);
fclose (tp);
printf ("OKK!\n");
return;
}
void output () {
gotoxy (0, 0);
node <vector <char> >* pt = py;
char prts[W];
for (iterator yy = 0; yy < H - 1 && pt != doc.end (); yy++) {
iterator xx;
bool isinc = false;
bool isstr = false;
bool isch = false;
bool isnum = false;
std::string ks;
color(112);
printf ("%4d ", (int)(lines + yy));
for (xx = 0; xx < W - 7 && xx + px < pt -> v.size (); xx++) {
char putch = pt -> v.at(xx + px);
if ((!isinc) && (!isstr) && (!isch)) {
if ((putch >= 'A' && putch <= 'Z') || (putch >= 'a' && putch <= 'z') || (putch >= '0' && putch <= '9') || putch == '_')
ks += putch;
else {
if (keyword[ks] != 0) {
memset (prts, '\b', sizeof(prts));
prts[ks.size ()] = '\0';
printf (prts);
for (iterator it = 0; it < ks.size(); it++) {
if (pt == ty && xx + px - ks.size() + it == tx)
color (240);
else
color(keyword[ks]);
printf ("%c", ks[it]);
}
}
ks = "";
}
} else ks = "";
if (putch == ' ' || isat[(int)putch] == true || xx + px == 0)
isnum = true;
else if(putch < '0' || putch > '9')
isnum = false;
if ((!isstr) && (!isch) && (isinc || putch == '#')) {
color (10);
isinc = true;
} else if ((!isinc) && (!isch) && (isstr || putch == '\"')) {
color (11);
if (pt -> v[xx + px] == '\"')
isstr = !isstr;
} else if ((!isinc) && (!isstr) && (isch || putch == '\'')) {
color (14);
if (pt -> v[xx + px] == '\'')
isch = !isch;
} else if ((!isinc) && (!isstr) && (!isch) && (isnum) && (putch >= '0' && putch <= '9'))
color (11);
else if (isat[(int)putch] == true)
color(9);
else
color (15);
if (pt == ty && xx + px == tx)
color (240);
printf ("%c", putch);
}
if (pt == ty && tx == pt -> v.size ())
color (240);
else
color (15);
printf (" ");
color (15);
memset(prts, ' ', sizeof (prts));
prts[W - 7 - xx] = '\0';
printf ("%s\n", prts);
pt = pt -> next;
}
printf ("%126c", ' ');
return;
}
void input () {
int ch;
bool lock = true;
output ();
while (true) {
if (kbhit () != 0) {
while (kbhit () != 0) {
ch = getch ();
if (ch == 8) {
if (tx == 0) {
if (ty -> pre != doc.begin ()) {
ty = ty -> pre;
tx = ty -> v.size();
for (iterator it = 0; it < ty -> next -> v.size (); it++)
ty -> v += ty -> next -> v[it];
doc.erase (ty);
cnt--;
}
} else {
ty -> v.erase (tx - 1);
tx--;
}
} else if (ch == 9) {
iterator it = 4;
while (it--) {
ty -> v.insert (tx, ' ');
tx++;
}
} else if (ch == 10) {
char prt[128];
memset(prt, '\b', sizeof(prt));
prt[127] = '\0';
printf("%s:", prt);
ch = getchar ();
switch (ch) {
case 'h':
case 'H':
case '?': {
printf (helps);
system ("pause");
break;
}
case 's':
case 'S': {
save ();
break;
}
case 'q':
case 'Q': {
save ();
return;
}
case '!': {
return;
}
case 'o':
case 'O': {
save ();
char calls[W];
sprintf (calls, "%s -o3 %s", path, name);
printf("%s\n", calls);
system (calls);
system ("start 3.exe");
system ("pause");
break;
}
case 't':
case 'T':
case '^': {
tx = 0;
cnt = 0;
lines = 0;
ty = doc.begin () -> next;
py = doc.begin () -> next;
break;
}
case 'l':
case 'L':
case 'y':
case 'Y':
case '@': {
unsigned int linenum;
scanf ("%d", &linenum);
tx = 0;
cnt = 0;
lines = 0;
ty = doc.begin () -> next;
py = doc.begin () -> next;
for (iterator it = 0; it < linenum; it++) {
if (ty -> next != doc.end ()) {
ty = ty -> next;
py = py -> next;
lines++;
}
}
break;
}
case 'x':
case 'X': {
unsigned int colnum;
scanf ("%d", &colnum);
tx = colnum;
if (tx < 0) {
tx = 0;
}
if (tx > ty -> v.size()) {
tx = ty -> v.size();
}
break;
}
case '<': {
int len;
bool okk;
char word[W];
getchar ();
gets (word);
len = strlen(word);
while (ty -> pre != doc.begin()) {
tx = 0;
ty = ty -> pre;
cnt--;
for (; (signed int)tx < (signed int)ty -> v.size() - len; tx++) {
okk = true;
for (iterator it = 0; it < len; it++) {
if (word[it] != ty -> v[tx + it]) {
okk = false;
break;
}
}
if (okk) {
goto FL_END;
}
}
}
break;
FL_END:
break;
}
case '>': {
int len;
bool okk;
char word[W];
getchar ();
gets (word);
len = strlen(word);
while (ty -> next != doc.end()) {
tx = 0;
ty = ty -> next;
cnt++;
for (; (signed int)tx < (signed int)ty -> v.size() - len; tx++) {
okk = true;
for (iterator it = 0; it < len; it++) {
if (word[it] != ty -> v[tx + it]) {
okk = false;
break;
}
}
if (okk) {
goto FR_END;
}
}
}
break;
FR_END:
break;
}
case '-': {
int num;
scanf ("%d", &num);
for (iterator it = 0; it < num; it++) {
if (tx > 0) {
tx--;
ty -> v.erase (tx);
}
}
break;
}
case '{': {
int num;
int step;
int begin;
char word[W];
scanf ("%d,%d,%d", &num, &begin, &step);
for (iterator it = 0; it < num; it++) {
sprintf (word, "%d", it * step + begin);
for (iterator i = 0; word[i] != '\0'; i++) {
ty -> v.insert (tx, word[i]);
tx++;
}
ty -> v.insert (tx, ',');
tx++;
ty -> v.insert (tx, ' ');
tx++;
}
break;
}
case '\"': {
int num;
int step;
char begin;
scanf ("%d,%c,%d", &num, &begin, &step);
for (iterator it = 0; it < num; it++) {
ty -> v.insert (tx, (char)(it * step) + begin);
tx++;
}
break;
}
case '|': {
int num;
int deln;
int step;
int begin;
char ch;
char str[W];
node <vector <char> >* tn = ty;
scanf ("%d,%d,%d,%c", &num, &begin, &step, &ch);
if (ch == '-') {
scanf ("%d", &deln);
tx -= deln;
while (tx < 0) {
tx++;
deln--;
}
} else if (ch == '+') {
getchar ();
gets (str);
}
for (iterator it = 0; it < num; it++) {
if (ch == '-') {
for (iterator it = 0; it < deln; it++)
tn -> v.erase (tx);
} else if (ch == '+') {
for (iterator l = 0; str[l] != '\0'; l++)
tn -> v.insert (l + tx, str[l]);
}
for (iterator l = 0; l < step; l++) {
if (tn -> next != doc.end())
tn = tn -> next;
else
goto LF_END;
}
}
break;
LF_END:
break;
}
case '/': {
ty -> v.insert (0, '#');
ty -> v.insert (0, '/');
ty -> v.insert (0, '/');
tx = 0;
break;
}
case 'k':
case 'K': {
char word[W];
scanf ("%s", word);
keyword[word] = 11;
break;
}
case 'p':
case 'P': {
unsigned int tcolor;
char word[W];
scanf ("%s", word);
scanf ("%d", &tcolor);
keyword[word] = (byte_t)tcolor;
break;
}
case 'w':
case 'W':
case '$': {
char calls[W];
getchar ();
gets (calls);
system (calls);
system ("pause");
break;
}
case 'c':
case 'C':
case '=': {
std::string TempBin;
HGLOBAL hMemBin = NULL;
PCHAR LockBin = NULL;
node <vector <char> >* tn = doc.begin () -> next;
OpenClipboard(NULL);
EmptyClipboard();
while (tn != doc.end ()) {
for (iterator it = 0; it < tn -> v.size (); it++)
TempBin += tn -> v[it];
TempBin += '\n';
tn = tn -> next;
}
hMemBin = GlobalAlloc(GMEM_MOVEABLE, TempBin.size() + 1);
LockBin = (PCHAR)GlobalLock(hMemBin);
RtlMoveMemory(LockBin, TempBin.c_str(), TempBin.size() + 1);
GlobalUnlock(hMemBin);
LockBin = NULL;
SetClipboardData(CF_TEXT, hMemBin);
CloseClipboard();
break;
}
case 'v':
case 'V':
case '~': {
lock = !lock;
break;
}
case 'm':
case 'M':
case '%': {
char from[64];
char to[64];
getchar ();
gets (from);
gets (to);
doccopy (from, to);
system ("pause");
break;
}
default:
break;
}
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cursor_info);
system ("cls");
} else if (ch == 13) {
node <vector <char> >* tn = new node <vector <char> >;
for (iterator it = tx; it < ty -> v.size (); it++) tn -> v += ty -> v[it];
ty -> v -= (ty -> v.size() - tx);
tn -> pre = ty;
tn -> next = ty -> next;
ty -> next -> pre = tn;
ty -> next = tn;
ty = ty -> next;
tx = 0;
cnt++;
} else if (lock && ch == '(') {
ty -> v.insert (tx, (char)ch);
tx++;
ty -> v.insert (tx, ')');
} else if (lock && ch == '[') {
ty -> v.insert (tx, (char)ch);
tx++;
ty -> v.insert (tx, ']');
} else if (lock && ch == '{') {
ty -> v.insert (tx, (char)ch);
tx++;
ty -> v.insert (tx, '}');
} else if (lock && ch == '\"') {
ty -> v.insert (tx, (char)ch);
tx++;
ty -> v.insert (tx, '\"');
} else if (lock && ch == '\'') {
ty -> v.insert (tx, (char)ch);
tx++;
ty -> v.insert (tx, '\'');
} else if (ch == 224) {
ch = getch ();
switch (ch) {
case UP: {
if (ty -> pre != doc.begin ()) {
ty = ty -> pre;
tx = min (tx, ty -> v.size ());
cnt--;
}
break;
}
case DOWN: {
if (ty -> next != doc.end ()) {
ty = ty -> next;
tx = min (tx, ty -> v.size ());
cnt++;
}
break;
}
case LEFT: {
if (tx > 0) {
tx--;
}
break;
}
case RIGHT: {
if (tx < ty -> v.size ()) {
tx++;
}
break;
}
}
} else {
ty -> v.insert (tx, (char)ch);
tx++;
}
while (cnt > H - 2) {
lines++;
cnt--;
py = py -> next;
}
while (cnt < 0) {
lines--;
cnt++;
py = py -> pre;
}
}
if (lock) {
output ();
}
}
}
return;
}
int main (int argc, char** argv) {
whelp ();
rpath ();
init (argc, argv);
input ();
return 0;
}