Subversion Repositories Kolibri OS

Rev

Rev 7413 | Rev 7419 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7413 Rev 7414
Line 27... Line 27...
27
#define _BSD_SOURCE
27
#define _BSD_SOURCE
28
#define _GNU_SOURCE
28
#define _GNU_SOURCE
Line 29... Line 29...
29
 
29
 
30
#include 
30
#include 
31
#include 
31
#include 
32
#include 
32
///#include 
33
#include 
33
///#include 
34
#include 
34
#include 
35
#include 
35
#include 
36
#include 
36
#include 
37
#include 
37
#include 
38
#include 
38
///#include 
39
#include 
39
///#include 
40
#include 
40
///#include 
41
#include 
41
#include 
42
#include 
-
 
-
 
42
///#include 
43
 
43
#include 
Line 44... Line 44...
44
/*** Define section ***/
44
/*** Define section ***/
45
 
45
 
46
// This mimics the Ctrl + whatever behavior, setting the
46
// This mimics the Ctrl + whatever behavior, setting the
-
 
47
// 3 upper bits of the character pressed to 0.
-
 
48
///#define CTRL_KEY(k) ((k) & 0x1f)
47
// 3 upper bits of the character pressed to 0.
49
// Siemargl - set top 4 bits
48
#define CTRL_KEY(k) ((k) & 0x1f)
50
#define CTRL_KEY(k) ((k) | 0xf000)
49
// Empty buffer
51
// Empty buffer
50
#define ABUF_INIT {NULL, 0}
52
#define ABUF_INIT {NULL, 0}
51
// Version code
53
// Version code
Line 58... Line 60...
58
#define HL_HIGHLIGHT_NUMBERS (1 << 0)
60
#define HL_HIGHLIGHT_NUMBERS (1 << 0)
59
#define HL_HIGHLIGHT_STRINGS (1 << 1)
61
#define HL_HIGHLIGHT_STRINGS (1 << 1)
Line 60... Line 62...
60
 
62
 
Line -... Line 63...
-
 
63
/*** Data section ***/
-
 
64
 
-
 
65
// Kolibri defaults
-
 
66
int con_def_wnd_width   =    80;
-
 
67
int	con_def_wnd_height  =    25;
61
/*** Data section ***/
68
 
62
 
69
 
63
typedef struct editor_row {
70
typedef struct editor_row {
64
    int idx; // Row own index within the file.
71
    int idx; // Row own index within the file.
65
    int size; // Size of the content (excluding NULL term)
72
    int size; // Size of the content (excluding NULL term)
Line 107... Line 114...
107
    char* file_name;
114
    char* file_name;
108
    char status_msg[80];
115
    char status_msg[80];
109
    time_t status_msg_time;
116
    time_t status_msg_time;
110
    char* copied_char_buffer;
117
    char* copied_char_buffer;
111
    struct editor_syntax* syntax;
118
    struct editor_syntax* syntax;
112
    struct termios orig_termios;
119
///    struct termios orig_termios;
113
} ec;
120
} ec;
Line 114... Line 121...
114
 
121
 
115
// Having a dynamic buffer will allow us to write only one
122
// Having a dynamic buffer will allow us to write only one
116
// time once the screen is refreshing, instead of doing
123
// time once the screen is refreshing, instead of doing
Line 119... Line 126...
119
    char* buf;
126
    char* buf;
120
    int len;
127
    int len;
121
};
128
};
Line 122... Line 129...
122
 
129
 
123
enum editor_key {
130
enum editor_key {
-
 
131
///    BACKSPACE = 0x7f, // 127
124
    BACKSPACE = 0x7f, // 127
132
    BACKSPACE = 0x3e7, // fixed russian letter
125
    ARROW_LEFT = 0x3e8, // 1000, large value out of the range of a char.
133
    ARROW_LEFT = 0x3e8, // 1000, large value out of the range of a char.
126
    ARROW_RIGHT,
134
    ARROW_RIGHT,
127
    ARROW_UP,
135
    ARROW_UP,
128
    ARROW_DOWN,
136
    ARROW_DOWN,
Line 393... Line 401...
393
    printf("\r\n");
401
    printf("\r\n");
394
    exit(1);
402
    exit(1);
395
}
403
}
Line 396... Line 404...
396
 
404
 
397
void disableRawMode() {
405
void disableRawMode() {
398
    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &ec.orig_termios) == -1)
406
///    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &ec.orig_termios) == -1)
399
        die("Failed to disable raw mode");
407
///        die("Failed to disable raw mode");
Line 400... Line 408...
400
}
408
}
401
 
409
 
402
void enableRawMode() {
410
void enableRawMode() {
403
    // Save original terminal state into orig_termios.
411
    // Save original terminal state into orig_termios.
404
    if (tcgetattr(STDIN_FILENO, &ec.orig_termios) == -1)
412
///    if (tcgetattr(STDIN_FILENO, &ec.orig_termios) == -1)
405
        die("Failed to get current terminal state");
413
///        die("Failed to get current terminal state");
-
 
414
    // At exit, restore the original state.
406
    // At exit, restore the original state.
415
///    atexit(disableRawMode);
407
    atexit(disableRawMode);
416
///
408
 
417
/*
409
    // Modify the original state to enter in raw mode.
418
    // Modify the original state to enter in raw mode.
410
    struct termios raw = ec.orig_termios;
419
    struct termios raw = ec.orig_termios;
411
    // This disables Ctrl-M, Ctrl-S and Ctrl-Q commands.
420
    // This disables Ctrl-M, Ctrl-S and Ctrl-Q commands.
Line 430... Line 439...
430
    // input to be read.
439
    // input to be read.
431
    raw.c_cc[VMIN] = 0;
440
    raw.c_cc[VMIN] = 0;
432
    // Forcing read() function to return every 1/10 of a
441
    // Forcing read() function to return every 1/10 of a
433
    // second if there is nothing to read.
442
    // second if there is nothing to read.
434
    raw.c_cc[VTIME] = 1;
443
    raw.c_cc[VTIME] = 1;
435
 
444
*/
436
    consoleBufferOpen();
445
    consoleBufferOpen();
Line 437... Line 446...
437
 
446
 
438
    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1)
447
///    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1)
439
        die("Failed to set raw mode");
448
///        die("Failed to set raw mode");
Line -... Line 449...
-
 
449
}
-
 
450
 
440
}
451
 
441
 
452
/*
442
int editorReadKey() {
453
int editorReadKey() {
443
    int nread;
454
    int nread;
444
    char c;
455
    char c;
Line 505... Line 516...
505
        return '\x1b';
516
        return '\x1b';
506
    } else {
517
    } else {
507
        return c;
518
        return c;
508
    }
519
    }
509
}
520
}
-
 
521
*/
-
 
522
/// by Siemargl rewritten, still Ctrl+ combination works only in english locale, so need analyze scancode
-
 
523
int editorReadKey() {
-
 
524
    int nread;
-
 
525
    int key = con_getch2();
-
 
526
    if (key == 0)
-
 
527
		die("Window closed by X-button");
-
 
528
 
-
 
529
	if (0 != (key & 0xff)) {
-
 
530
		key &= 0xff;
-
 
531
		switch (key) {
-
 
532
			case 27: // ESC
-
 
533
				return '\x1b';
-
 
534
 
-
 
535
			case 13: // ENTER
-
 
536
				return '\r';
-
 
537
 
-
 
538
			case 8: // BACKSPACE
-
 
539
				return BACKSPACE;
-
 
540
 
-
 
541
			case 9: // TAB
-
 
542
				return	key;
-
 
543
				
-
 
544
			case 22: // Ctrl+V
-
 
545
				return CTRL_KEY('v');
-
 
546
				
-
 
547
			case 3: // Ctrl+C
-
 
548
				return CTRL_KEY('c');
-
 
549
				
-
 
550
			case 12: // Ctrl+L
-
 
551
				return CTRL_KEY('l');
-
 
552
 
-
 
553
			case 17: // Ctrl+Q
-
 
554
				return CTRL_KEY('q');
-
 
555
 
-
 
556
			case 19: // Ctrl+S
-
 
557
				return CTRL_KEY('s');
-
 
558
 
-
 
559
			case 5: // Ctrl+E
-
 
560
				return CTRL_KEY('e');
-
 
561
 
-
 
562
			case 4: // Ctrl+D
-
 
563
				return CTRL_KEY('d');
-
 
564
 
-
 
565
			case 6: // Ctrl+F
-
 
566
				return CTRL_KEY('f');
-
 
567
 
-
 
568
			case 8: // Ctrl+H
-
 
569
				return CTRL_KEY('h');
-
 
570
 
-
 
571
			case 24: // Ctrl+X
-
 
572
				return CTRL_KEY('x');
-
 
573
				
-
 
574
			default:
-
 
575
				return	key;
-
 
576
 
-
 
577
		}
-
 
578
	} else {
-
 
579
		key = (key >> 8) & 0xff;
-
 
580
		switch (key) {
-
 
581
			case 83: // Del
-
 
582
				return DEL_KEY;
-
 
583
 
-
 
584
			case 75: // Left
-
 
585
				return ARROW_LEFT;
-
 
586
				
-
 
587
			case 77: // Right
-
 
588
				return ARROW_RIGHT;
-
 
589
 
-
 
590
			case 72: // Up
-
 
591
				return ARROW_UP;
-
 
592
 
-
 
593
			case 80: // Down
-
 
594
				return ARROW_DOWN;
-
 
595
 
-
 
596
			case 81: // PgDn
-
 
597
				return PAGE_DOWN;
-
 
598
				
-
 
599
			case 73: // PgUp
-
 
600
				return PAGE_UP;
-
 
601
				
-
 
602
			case 71: // Home
-
 
603
				return HOME_KEY;
-
 
604
				
-
 
605
			case 79: // End
-
 
606
				return END_KEY;
-
 
607
				
-
 
608
			default:
-
 
609
				return	0;
-
 
610
		}
-
 
611
	}
-
 
612
	return	0;
-
 
613
}
-
 
614
 
-
 
615
 
-
 
616
 
-
 
617
 
Line 510... Line 618...
510
 
618
 
511
int getWindowSize(int* screen_rows, int* screen_cols) {
619
int getWindowSize(int* screen_rows, int* screen_cols) {
Line 512... Line 620...
512
    struct winsize ws;
620
///    struct winsize ws;
513
 
621
 
-
 
622
    // Getting window size thanks to ioctl into the given
514
    // Getting window size thanks to ioctl into the given
623
    // winsize struct.
515
    // winsize struct.
624
    /*
516
    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) {
625
    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) {
517
        return -1;
626
        return -1;
518
    } else {
627
    } else {
519
        *screen_cols = ws.ws_col;
628
        *screen_cols = ws.ws_col;
520
        *screen_rows = ws.ws_row;
629
        *screen_rows = ws.ws_row;
-
 
630
        return 0;
-
 
631
    }
-
 
632
    */
521
        return 0;
633
    *screen_cols = con_def_wnd_width;
Line 522... Line 634...
522
    }
634
    *screen_rows = con_def_wnd_height;
523
}
635
}
524
 
636
 
Line 545... Line 657...
545
}
657
}
Line 546... Line 658...
546
 
658
 
547
void consoleBufferOpen() {
659
void consoleBufferOpen() {
548
    // Switch to another terminal buffer in order to be able to restore state at exit
660
    // Switch to another terminal buffer in order to be able to restore state at exit
549
    // by calling consoleBufferClose().
661
    // by calling consoleBufferClose().
550
    if (write(STDOUT_FILENO, "\x1b[?47h", 6) == -1)
662
///    if (write(STDOUT_FILENO, "\x1b[?47h", 6) == -1)
551
        die("Error changing terminal buffer");
663
///        die("Error changing terminal buffer");
Line 552... Line 664...
552
}
664
}
553
 
665
 
554
void consoleBufferClose() {
666
void consoleBufferClose() {
555
    // Restore console to the state tte opened.
667
    // Restore console to the state tte opened.
556
    if (write(STDOUT_FILENO, "\x1b[?9l", 5) == -1 ||
668
///    if (write(STDOUT_FILENO, "\x1b[?9l", 5) == -1 ||
Line 557... Line 669...
557
        write(STDOUT_FILENO, "\x1b[?47l", 6) == -1)
669
///        write(STDOUT_FILENO, "\x1b[?47l", 6) == -1)
558
        die("Error restoring buffer state");
670
///        die("Error restoring buffer state");
559
 
671
 
560
    /*struct a_buf ab = {.buf = NULL, .len = 0};
672
    /*struct a_buf ab = {.buf = NULL, .len = 0};
Line 1059... Line 1171...
1059
    }
1171
    }
Line 1060... Line 1172...
1060
 
1172
 
1061
    return buf;
1173
    return buf;
Line -... Line 1174...
-
 
1174
}
-
 
1175
 
1062
}
1176
extern int getline(char **buf, size_t *bufsiz, FILE *fp);
1063
 
1177
 
1064
void editorOpen(char* file_name) {
1178
void editorOpen(char* file_name) {
Line 1065... Line 1179...
1065
    free(ec.file_name);
1179
    free(ec.file_name);
Line 1073... Line 1187...
1073
 
1187
 
1074
    char* line = NULL;
1188
    char* line = NULL;
1075
    // Unsigned int of at least 16 bit.
1189
    // Unsigned int of at least 16 bit.
1076
    size_t line_cap = 0;
1190
    size_t line_cap = 0;
1077
    // Bigger than int
1191
    // Bigger than int
1078
    ssize_t line_len;
1192
    int line_len;  ///was ssize_t
1079
    while ((line_len = getline(&line, &line_cap, file)) != -1) {
1193
    while ((line_len = getline(&line, &line_cap, file)) != -1) {
1080
        // We already know each row represents one line of text, there's no need
1194
        // We already know each row represents one line of text, there's no need
1081
        // to keep carriage return and newline characters.
1195
        // to keep carriage return and newline characters.
1082
        if (line_len > 0 && (line[line_len - 1] == '\n' || line[line_len - 1] == '\r'))
1196
        if (line_len > 0 && (line[line_len - 1] == '\n' || line[line_len - 1] == '\r'))
Line 1098... Line 1212...
1098
        editorSelectSyntaxHighlight();
1212
        editorSelectSyntaxHighlight();
1099
    }
1213
    }
Line 1100... Line 1214...
1100
 
1214
 
1101
    int len;
1215
    int len;
-
 
1216
    char* buf = editorRowsToString(&len);
1102
    char* buf = editorRowsToString(&len);
1217
///
1103
 
1218
/*
1104
    // We want to create if it doesn't already exist (O_CREAT flag), giving
1219
    // We want to create if it doesn't already exist (O_CREAT flag), giving
1105
    // 0644 permissions (the standard ones). O_RDWR stands for reading and
1220
    // 0644 permissions (the standard ones). O_RDWR stands for reading and
1106
    // writing.
1221
    // writing.
1107
    int fd = open(ec.file_name, O_RDWR | O_CREAT, 0644);
1222
    int fd = open(ec.file_name, O_RDWR | O_CREAT, 0644);
Line 1117... Line 1232...
1117
                return;
1232
                return;
1118
            }
1233
            }
1119
        }
1234
        }
1120
        close(fd);
1235
        close(fd);
1121
    }
1236
    }
-
 
1237
*/
-
 
1238
	FILE *fd = fopen(ec.file_name,"w+b");
-
 
1239
	if (fd) {
-
 
1240
		if (fwrite(buf, 1, len, fd) == len) {
-
 
1241
			fclose(fd);
-
 
1242
			free(buf);
-
 
1243
			ec.dirty = 0;
-
 
1244
			editorSetStatusMessage("%d bytes written to disk", len);
-
 
1245
			return;
-
 
1246
		}
-
 
1247
        fclose(fd);
-
 
1248
	}
Line 1122... Line 1249...
1122
 
1249
 
1123
    free(buf);
1250
    free(buf);
1124
    editorSetStatusMessage("Cant's save file. Error occurred: %s", strerror(errno));
1251
    editorSetStatusMessage("Cant's save file. Error occurred: %s", strerror(errno));
Line 1432... Line 1559...
1432
 
1559
 
1433
    // Showing again the cursor.
1560
    // Showing again the cursor.
Line 1434... Line 1561...
1434
    abufAppend(&ab, "\x1b[?25h", 6);
1561
    abufAppend(&ab, "\x1b[?25h", 6);
1435
 
1562
 
-
 
1563
    // Writing all content at once
1436
    // Writing all content at once
1564
///    write(STDOUT_FILENO, ab.buf, ab.len);
1437
    write(STDOUT_FILENO, ab.buf, ab.len);
1565
	con_write_string(ab.buf, ab.len);
Line 1438... Line 1566...
1438
    abufFree(&ab);
1566
    abufFree(&ab);
1439
}
1567
}
1440
 
1568
 
1441
void editorClearScreen() {
1569
void editorClearScreen() {
1442
    // Writing 4 bytes out to the terminal:
1570
    // Writing 4 bytes out to the terminal:
1443
    // - (1 byte) \x1b : escape character
1571
    // - (1 byte) \x1b : escape character
1444
    // - (3 bytes) [2J : Clears the entire screen, see
1572
    // - (3 bytes) [2J : Clears the entire screen, see
-
 
1573
    // http://vt100.net/docs/vt100-ug/chapter3.html#ED
-
 
1574
    // for more info.
1445
    // http://vt100.net/docs/vt100-ug/chapter3.html#ED
1575
///    write(STDOUT_FILENO, "\x1b[2J", 4);
1446
    // for more info.
1576
	con_write_string("\x1b[2J", 4);
1447
    write(STDOUT_FILENO, "\x1b[2J", 4);
1577
 
1448
    // Writing 3 bytes to reposition the cursor back at
1578
    // Writing 3 bytes to reposition the cursor back at
1449
    // the top-left corner, see
1579
    // the top-left corner, see
-
 
1580
    // http://vt100.net/docs/vt100-ug/chapter3.html#CUP
1450
    // http://vt100.net/docs/vt100-ug/chapter3.html#CUP
1581
    // for more info.
Line 1451... Line 1582...
1451
    // for more info.
1582
///    write(STDOUT_FILENO, "\x1b[H", 3);
Line 1452... Line 1583...
1452
    write(STDOUT_FILENO, "\x1b[H", 3);
1583
	con_write_string("\x1b[H", 3);
Line 1574... Line 1705...
1574
            editorCopy(0);
1705
            editorCopy(0);
1575
            break;
1706
            break;
1576
        case CTRL_KEY('v'):
1707
        case CTRL_KEY('v'):
1577
            editorPaste();
1708
            editorPaste();
1578
            break;
1709
            break;
1579
        case CTRL_KEY('p'):
1710
///        case CTRL_KEY('p'):
1580
            consoleBufferClose();
1711
///            consoleBufferClose();
1581
            kill(0, SIGTSTP);
1712
///            kill(0, SIGTSTP);
1582
        case ARROW_UP:
1713
        case ARROW_UP:
1583
        case ARROW_DOWN:
1714
        case ARROW_DOWN:
1584
        case ARROW_LEFT:
1715
        case ARROW_LEFT:
1585
        case ARROW_RIGHT:
1716
        case ARROW_RIGHT:
1586
            editorMoveCursor(c);
1717
            editorMoveCursor(c);
Line 1644... Line 1775...
1644
    ec.syntax = NULL;
1775
    ec.syntax = NULL;
Line 1645... Line 1776...
1645
 
1776
 
1646
    editorUpdateWindowSize();
1777
    editorUpdateWindowSize();
1647
    // The SIGWINCH signal is sent to a process when its controlling
1778
    // The SIGWINCH signal is sent to a process when its controlling
1648
    // terminal changes its size (a window change).
1779
    // terminal changes its size (a window change).
1649
    signal(SIGWINCH, editorHandleSigwinch);
1780
///    signal(SIGWINCH, editorHandleSigwinch);
1650
    // The SIGCONT signal instructs the operating system to continue
1781
    // The SIGCONT signal instructs the operating system to continue
1651
    // (restart) a process previously paused by the SIGSTOP or SIGTSTP
1782
    // (restart) a process previously paused by the SIGSTOP or SIGTSTP
1652
    // signal.
1783
    // signal.
1653
    signal(SIGCONT, editorHandleSigcont);
1784
///    signal(SIGCONT, editorHandleSigcont);
Line 1654... Line 1785...
1654
}
1785
}
1655
 
1786
 
1656
void printHelp() {
1787
void printHelp() {
Line 1663... Line 1794...
1663
    printf("Ctrl-E    \t\tFlip line upwards\n");
1794
    printf("Ctrl-E    \t\tFlip line upwards\n");
1664
    printf("Ctrl-D    \t\tFlip line downwards\n");
1795
    printf("Ctrl-D    \t\tFlip line downwards\n");
1665
    printf("Ctrl-C    \t\tCopy line\n");
1796
    printf("Ctrl-C    \t\tCopy line\n");
1666
    printf("Ctrl-X    \t\tCut line\n");
1797
    printf("Ctrl-X    \t\tCut line\n");
1667
    printf("Ctrl-V    \t\tPaste line\n");
1798
    printf("Ctrl-V    \t\tPaste line\n");
1668
    printf("Ctrl-P    \t\tPause tte (type \"fg\" to resume)\n");
1799
 ///   printf("Ctrl-P    \t\tPause tte (type \"fg\" to resume)\n");
Line 1669... Line 1800...
1669
 
1800
 
1670
    printf("\n\nOPTIONS\n-------\n\n");
1801
    printf("\n\nOPTIONS\n-------\n\n");
1671
    printf("Option        \t\tAction\n\n");
1802
    printf("Option        \t\tAction\n\n");
1672
    printf("-h | --help   \t\tPrints the help\n");
1803
    printf("-h | --help   \t\tPrints the help\n");
Line 1692... Line 1823...
1692
 
1823
 
1693
    return 1;
1824
    return 1;
Line 1694... Line 1825...
1694
}
1825
}
-
 
1826
 
-
 
1827
int main(int argc, char* argv[]) {
1695
 
1828
	if (con_init_console_dll()) return 1; // init fail
1696
int main(int argc, char* argv[]) {
1829
 
1697
    initEditor();
1830
    initEditor();
1698
    int arg_response = handleArgs(argc, argv);
1831
    int arg_response = handleArgs(argc, argv);
1699
    if (arg_response == 1)
1832
    if (arg_response == 1)
Line 1707... Line 1840...
1707
    while (1) {
1840
    while (1) {
1708
        editorRefreshScreen();
1841
        editorRefreshScreen();
1709
        editorProcessKeypress();
1842
        editorProcessKeypress();
1710
    }
1843
    }
Line -... Line 1844...
-
 
1844
 
1711
 
1845
	con_exit(0);
1712
    return 0;
1846
    return 0;