Subversion Repositories Kolibri OS

Rev

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

Rev 7414 Rev 7419
Line 12... Line 12...
12
*   GNU General Public License for more details.
12
*   GNU General Public License for more details.
13
*
13
*
14
*   You should have received a copy of the GNU General Public License
14
*   You should have received a copy of the GNU General Public License
15
*   along with this program.  If not, see .
15
*   along with this program.  If not, see .
16
*/
16
*/
-
 
17
/* Kolibri port by Siemargl 2018 
-
 
18
 * my fixes mostly commented with triple comment ///
-
 
19
 * */
Line 17... Line 20...
17
 
20
 
Line 18... Line 21...
18
/*** Include section ***/
21
/*** Include section ***/
19
 
22
 
Line 39... Line 42...
39
///#include 
42
///#include 
40
///#include 
43
///#include 
41
#include 
44
#include 
42
///#include 
45
///#include 
43
#include 
46
#include 
-
 
47
 
-
 
48
 
-
 
49
 
44
/*** Define section ***/
50
/*** Define section ***/
Line 45... Line 51...
45
 
51
 
46
// This mimics the Ctrl + whatever behavior, setting the
52
// This mimics the Ctrl + whatever behavior, setting the
47
// 3 upper bits of the character pressed to 0.
53
// 3 upper bits of the character pressed to 0.
Line 63... Line 69...
63
/*** Data section ***/
69
/*** Data section ***/
Line 64... Line 70...
64
 
70
 
65
// Kolibri defaults
71
// Kolibri defaults
66
int con_def_wnd_width   =    80;
72
int con_def_wnd_width   =    80;
-
 
73
int	con_def_wnd_height  =    25;
67
int	con_def_wnd_height  =    25;
74
/// winFile support
Line 68... Line 75...
68
 
75
int	fileIsOd0a; 
69
 
76
 
70
typedef struct editor_row {
77
typedef struct editor_row {
71
    int idx; // Row own index within the file.
78
    int idx; // Row own index within the file.
Line 397... Line 404...
397
    editorClearScreen();
404
    editorClearScreen();
398
    // perror looks for global errno variable and then prints
405
    // perror looks for global errno variable and then prints
399
    // a descriptive error mesage for it.
406
    // a descriptive error mesage for it.
400
    perror(s);
407
    perror(s);
401
    printf("\r\n");
408
    printf("\r\n");
-
 
409
    con_exit(0); /// KOS console
402
    exit(1);
410
    exit(1);
403
}
411
}
Line 404... Line 412...
404
 
412
 
405
void disableRawMode() {
413
void disableRawMode() {
Line 447... Line 455...
447
///    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1)
455
///    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1)
448
///        die("Failed to set raw mode");
456
///        die("Failed to set raw mode");
449
}
457
}
Line 450... Line -...
450
 
-
 
451
 
-
 
452
/*
-
 
453
int editorReadKey() {
-
 
454
    int nread;
-
 
455
    char c;
-
 
456
    while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
-
 
457
        // Ignoring EAGAIN to make it work on Cygwin.
-
 
458
        if (nread == -1 && errno != EAGAIN)
-
 
459
            die("Error reading input");
-
 
460
    }
-
 
461
 
-
 
462
    // Check escape sequences, if first byte
-
 
463
    // is an escape character then...
-
 
464
    if (c == '\x1b') {
-
 
465
        char seq[3];
-
 
466
 
-
 
467
        if (read(STDIN_FILENO, &seq[0], 1) != 1 ||
-
 
Line 468... Line -...
468
            read(STDIN_FILENO, &seq[1], 1) != 1)
-
 
469
            return '\x1b';
-
 
470
 
-
 
471
        if (seq[0] == '[') {
-
 
472
            if (seq[1] >= '0' && seq[1] <= '9') {
-
 
473
                if (read(STDIN_FILENO, &seq[2], 1) != 1)
-
 
474
                    return '\x1b';
-
 
475
                if (seq[2] == '~') {
-
 
476
                    switch (seq[1]) {
-
 
477
                        // Home and End keys may be sent in many ways depending on the OS
-
 
478
                        // \x1b[1~, \x1b[7~, \x1b[4~, \x1b[8~
-
 
479
                        case '1':
-
 
480
                        case '7':
-
 
481
                            return HOME_KEY;
-
 
482
                        case '4':
-
 
483
                        case '8':
-
 
484
                            return END_KEY;
-
 
485
                        // Del key is sent as \x1b[3~
-
 
486
                        case '3':
-
 
487
                            return DEL_KEY;
-
 
488
                        // Page Up and Page Down send '\x1b', '[', '5' or '6' and '~'.
-
 
489
                        case '5': return PAGE_UP;
-
 
490
                        case '6': return PAGE_DOWN;
-
 
491
                    }
-
 
492
                }
-
 
493
            } else {
-
 
494
                switch (seq[1]) {
-
 
495
                    // Arrow keys send multiple bytes starting with '\x1b', '[''
-
 
496
                    // and followed by an 'A', 'B', 'C' or 'D' depending on which
-
 
497
                    // arrow is pressed.
-
 
498
                    case 'A': return ARROW_UP;
-
 
499
                    case 'B': return ARROW_DOWN;
-
 
500
                    case 'C': return ARROW_RIGHT;
-
 
501
                    case 'D': return ARROW_LEFT;
-
 
502
                    // Home key can also be sent as \x1b[H
-
 
503
                    case 'H': return HOME_KEY;
-
 
504
                    // End key can also be sent as \x1b[F
-
 
505
                    case 'F': return END_KEY;
-
 
506
                }
-
 
507
            }
-
 
508
        } else if (seq[0] == 'O') {
-
 
509
            switch (seq[1]) {
-
 
510
                // Yes, Home key can ALSO be sent as \x1bOH
-
 
511
                case 'H': return HOME_KEY;
-
 
512
                // And... End key as \x1bOF
-
 
513
                case 'F': return END_KEY;
-
 
514
            }
-
 
515
        }
-
 
516
        return '\x1b';
-
 
517
    } else {
-
 
518
        return c;
-
 
519
    }
458
 
520
}
459
 
521
*/
-
 
522
/// by Siemargl rewritten, still Ctrl+ combination works only in english locale, so need analyze scancode
460
 
523
int editorReadKey() {
461
/// by Siemargl rewritten, still Ctrl+ combination works only in english locale, so need analyze scancode
524
    int nread;
462
int editorReadKey() {
Line 525... Line 463...
525
    int key = con_getch2();
463
    int key = con_getch2();
526
    if (key == 0)
464
    if (key == 0)
527
		die("Window closed by X-button");
465
		die("Window closed by moused X-button");
528
 
466
 
Line 549... Line 487...
549
				
487
				
550
			case 12: // Ctrl+L
488
			case 12: // Ctrl+L
Line 551... Line 489...
551
				return CTRL_KEY('l');
489
				return CTRL_KEY('l');
-
 
490
 
552
 
491
			case 17: // Ctrl+Q
Line 553... Line 492...
553
			case 17: // Ctrl+Q
492
			case 26: // Ctrl+Z
554
				return CTRL_KEY('q');
493
				return CTRL_KEY('q');
Line 1152... Line 1091...
1152
    int j;
1091
    int j;
1153
    // Adding up the lengths of each row of text, adding 1
1092
    // Adding up the lengths of each row of text, adding 1
1154
    // to each one for the newline character we'll add to
1093
    // to each one for the newline character we'll add to
1155
    // the end of each line.
1094
    // the end of each line.
1156
    for (j = 0; j < ec.num_rows; j++) {
1095
    for (j = 0; j < ec.num_rows; j++) {
1157
        total_len += ec.row[j].size + 1;
1096
        total_len += ec.row[j].size + 1 
-
 
1097
							+ (fileIsOd0a ? 1:0); /// winFile suppor
1158
    }
1098
    }
1159
    *buf_len = total_len;
1099
    *buf_len = total_len;
Line 1160... Line 1100...
1160
 
1100
 
1161
    char* buf = malloc(total_len);
1101
    char* buf = malloc(total_len);
Line 1164... Line 1104...
1164
    // buffer, appending a newline character after each
1104
    // buffer, appending a newline character after each
1165
    // row.
1105
    // row.
1166
    for (j = 0; j < ec.num_rows; j++) {
1106
    for (j = 0; j < ec.num_rows; j++) {
1167
        memcpy(p, ec.row[j].chars, ec.row[j].size);
1107
        memcpy(p, ec.row[j].chars, ec.row[j].size);
1168
        p += ec.row[j].size;
1108
        p += ec.row[j].size;
-
 
1109
        /// winFile support
-
 
1110
        if (fileIsOd0a) *p++ = '\r';
1169
        *p = '\n';
1111
        *p = '\n';
1170
        p++;
1112
        p++;
1171
    }
1113
    }
Line 1172... Line 1114...
1172
 
1114
 
Line 1188... Line 1130...
1188
    char* line = NULL;
1130
    char* line = NULL;
1189
    // Unsigned int of at least 16 bit.
1131
    // Unsigned int of at least 16 bit.
1190
    size_t line_cap = 0;
1132
    size_t line_cap = 0;
1191
    // Bigger than int
1133
    // Bigger than int
1192
    int line_len;  ///was ssize_t
1134
    int line_len;  ///was ssize_t
-
 
1135
    fileIsOd0a = 0; /// winFile support
-
 
1136
 
1193
    while ((line_len = getline(&line, &line_cap, file)) != -1) {
1137
    while ((line_len = getline(&line, &line_cap, file)) != -1) {
1194
        // We already know each row represents one line of text, there's no need
1138
        // We already know each row represents one line of text, there's no need
1195
        // to keep carriage return and newline characters.
1139
        // to keep carriage return and newline characters.
1196
        if (line_len > 0 && (line[line_len - 1] == '\n' || line[line_len - 1] == '\r'))
1140
        if (line_len > 0 && (line[line_len - 1] == '\n' || line[line_len - 1] == '\r'))
1197
            line_len--;
1141
            line_len--;
-
 
1142
/// Siemargl fix 0d0a windows file, save format flag
-
 
1143
         if (line_len > 0 && line[line_len - 1] == '\r')
-
 
1144
         {
-
 
1145
            line_len--;
-
 
1146
            fileIsOd0a = 1;
-
 
1147
		 }
1198
        editorInsertRow(ec.num_rows, line, line_len);
1148
       editorInsertRow(ec.num_rows, line, line_len);
1199
    }
1149
    }
1200
    free(line);
1150
    free(line);
1201
    fclose(file);
1151
    fclose(file);
1202
    ec.dirty = 0;
1152
    ec.dirty = 0;
Line 1212... Line 1162...
1212
        editorSelectSyntaxHighlight();
1162
        editorSelectSyntaxHighlight();
1213
    }
1163
    }
Line 1214... Line 1164...
1214
 
1164
 
1215
    int len;
1165
    int len;
1216
    char* buf = editorRowsToString(&len);
-
 
1217
///
1166
    char* buf = editorRowsToString(&len);
1218
/*
-
 
1219
    // We want to create if it doesn't already exist (O_CREAT flag), giving
-
 
1220
    // 0644 permissions (the standard ones). O_RDWR stands for reading and
-
 
1221
    // writing.
-
 
1222
    int fd = open(ec.file_name, O_RDWR | O_CREAT, 0644);
-
 
1223
    if (fd != -1) {
-
 
1224
        // ftruncate sets the file's size to the specified length.
-
 
1225
        if (ftruncate(fd, len) != -1) {
-
 
1226
            // Writing the file.
1167
 
1227
            if (write(fd, buf, len) == len) {
-
 
1228
                close(fd);
-
 
1229
                free(buf);
-
 
1230
                ec.dirty = 0;
-
 
1231
                editorSetStatusMessage("%d bytes written to disk", len);
-
 
1232
                return;
-
 
1233
            }
-
 
1234
        }
-
 
1235
        close(fd);
-
 
1236
    }
-
 
1237
*/
1168
/// siemargl rewrite using standard FILE stream
-
 
1169
	FILE *fd = fopen(ec.file_name,"w+b");
1238
	FILE *fd = fopen(ec.file_name,"w+b");
1170
	int rc = -1;
1239
	if (fd) {
1171
	if (fd) {
1240
		if (fwrite(buf, 1, len, fd) == len) {
1172
		if ((rc = fwrite(buf, 1, len, fd)) == len) {
1241
			fclose(fd);
1173
			fclose(fd);
1242
			free(buf);
1174
			free(buf);
1243
			ec.dirty = 0;
1175
			ec.dirty = 0;
1244
			editorSetStatusMessage("%d bytes written to disk", len);
1176
			editorSetStatusMessage("%d bytes written to disk", len);
Line 1420... Line 1352...
1420
    abufAppend(ab, "\r\n", 2);
1352
    abufAppend(ab, "\r\n", 2);
1421
}
1353
}
Line 1422... Line 1354...
1422
 
1354
 
1423
void editorDrawMessageBar(struct a_buf *ab) {
1355
void editorDrawMessageBar(struct a_buf *ab) {
1424
    // Clearing the message bar.
1356
    // Clearing the message bar.
1425
    abufAppend(ab, "\x1b[K", 3);
1357
///    abufAppend(ab, "\x1b[K", 3);	/// not work in Kolibri
1426
    int msg_len = strlen(ec.status_msg);
1358
    int msg_len = strlen(ec.status_msg);
1427
    if (msg_len > ec.screen_cols)
1359
    if (msg_len > ec.screen_cols)
1428
        msg_len = ec.screen_cols;
1360
        msg_len = ec.screen_cols;
1429
    // We only show the message if its less than 5 secons old, but
1361
    // We only show the message if its less than 5 secons old, but
Line 1507... Line 1439...
1507
                        int c_len = snprintf(buf, sizeof(buf), "\x1b[%dm", current_color);
1439
                        int c_len = snprintf(buf, sizeof(buf), "\x1b[%dm", current_color);
1508
                        abufAppend(ab, buf, c_len);
1440
                        abufAppend(ab, buf, c_len);
1509
                    }
1441
                    }
1510
                } else if (highlight[j] == HL_NORMAL) {
1442
                } else if (highlight[j] == HL_NORMAL) {
1511
                    if (current_color != -1) {
1443
                    if (current_color != -1) {
1512
                        abufAppend(ab, "\x1b[39m", 5);
1444
                        abufAppend(ab, "\x1b[m", 3);  /// was [39, 5
1513
                        current_color = -1;
1445
                        current_color = -1;
1514
                    }
1446
                    }
1515
                    abufAppend(ab, &c[j], 1);
1447
                    abufAppend(ab, &c[j], 1);
1516
                } else {
1448
                } else {
1517
                    int color = editorSyntaxToColor(highlight[j]);
1449
                    int color = editorSyntaxToColor(highlight[j]);
Line 1525... Line 1457...
1525
                    }
1457
                    }
Line 1526... Line 1458...
1526
 
1458
 
1527
                    abufAppend(ab, &c[j], 1);
1459
                    abufAppend(ab, &c[j], 1);
1528
                }
1460
                }
1529
            }
1461
            }
1530
            abufAppend(ab, "\x1b[39m", 5);
1462
            abufAppend(ab, "\x1b[m", 3);  /// was [39, 5
Line 1531... Line 1463...
1531
        }
1463
        }
1532
 
1464
 
1533
        // Redrawing each line instead of the whole screen.
1465
        // Redrawing each line instead of the whole screen.
1534
        abufAppend(ab, "\x1b[K", 3);
1466
///        abufAppend(ab, "\x1b[K", 3);  /// not work in Kolibri
1535
        // Addind a new line
1467
        // Addind a new line
1536
        abufAppend(ab, "\r\n", 2);
1468
        abufAppend(ab, "\r\n", 2);
Line 1543... Line 1475...
1543
    struct a_buf ab = ABUF_INIT;
1475
    struct a_buf ab = ABUF_INIT;
Line 1544... Line 1476...
1544
 
1476
 
1545
    // Hiding the cursor while the screen is refreshing.
1477
    // Hiding the cursor while the screen is refreshing.
1546
    // See http://vt100.net/docs/vt100-ug/chapter3.html#S3.3.4
1478
    // See http://vt100.net/docs/vt100-ug/chapter3.html#S3.3.4
1547
    // for more info.
1479
    // for more info.
1548
    abufAppend(&ab, "\x1b[?25l", 6);
1480
///    abufAppend(&ab, "\x1b[?25l", 6);
Line -... Line 1481...
-
 
1481
    abufAppend(&ab, "\x1b[H", 3);
-
 
1482
 
-
 
1483
/// full clear because "\x1b[K" not work in Kolibri
1549
    abufAppend(&ab, "\x1b[H", 3);
1484
    abufAppend(&ab, "\x1b[2J", 4);
1550
 
1485
 
1551
    editorDrawRows(&ab);
1486
    editorDrawRows(&ab);
Line 1552... Line 1487...
1552
    editorDrawStatusBar(&ab);
1487
    editorDrawStatusBar(&ab);
1553
    editorDrawMessageBar(&ab);
1488
    editorDrawMessageBar(&ab);
1554
 
1489
 
-
 
1490
    // Moving the cursor where it should be.
-
 
1491
    char buf[32];
1555
    // Moving the cursor where it should be.
1492
///    snprintf(buf, sizeof(buf), "\x1b[%d;%dH", (ec.cursor_y - ec.row_offset) + 1, (ec.render_x - ec.col_offset) + 1);
Line 1556... Line 1493...
1556
    char buf[32];
1493
/// a bit different in Kolibri
1557
    snprintf(buf, sizeof(buf), "\x1b[%d;%dH", (ec.cursor_y - ec.row_offset) + 1, (ec.render_x - ec.col_offset) + 1);
1494
    snprintf(buf, sizeof(buf), "\x1b[%d;%dH", (ec.render_x - ec.col_offset), (ec.cursor_y - ec.row_offset));
Line 1558... Line 1495...
1558
    abufAppend(&ab, buf, strlen(buf));
1495
       abufAppend(&ab, buf, strlen(buf));
1559
 
1496
 
1560
    // Showing again the cursor.
1497
    // Showing again the cursor.
1561
    abufAppend(&ab, "\x1b[?25h", 6);
1498
///    abufAppend(&ab, "\x1b[?25h", 6);
Line 1675... Line 1612...
1675
        case '\r': // Enter key
1612
        case '\r': // Enter key
1676
            editorInsertNewline();
1613
            editorInsertNewline();
1677
            break;
1614
            break;
1678
        case CTRL_KEY('q'):
1615
        case CTRL_KEY('q'):
1679
            if (ec.dirty && quit_times > 0) {
1616
            if (ec.dirty && quit_times > 0) {
1680
                editorSetStatusMessage("Warning! File has unsaved changes. Press Ctrl-Q %d more time%s to quit", quit_times, quit_times > 1 ? "s" : "");
1617
                editorSetStatusMessage("Warning! File has unsaved changes. Press Ctrl-Q or ^Z %d more time%s to quit", quit_times, quit_times > 1 ? "s" : "");
1681
                quit_times--;
1618
                quit_times--;
1682
                return;
1619
                return;
1683
            }
1620
            }
1684
            editorClearScreen();
1621
            editorClearScreen();
1685
            consoleBufferClose();
1622
            consoleBufferClose();
-
 
1623
            con_exit(1); /// KOS console
1686
            exit(0);
1624
            exit(0);
1687
            break;
1625
            break;
1688
        case CTRL_KEY('s'):
1626
        case CTRL_KEY('s'):
1689
            editorSave();
1627
            editorSave();
1690
            break;
1628
            break;
Line 1786... Line 1724...
1786
 
1724
 
1787
void printHelp() {
1725
void printHelp() {
1788
    printf("Usage: tte [OPTIONS] [FILE]\n\n");
1726
    printf("Usage: tte [OPTIONS] [FILE]\n\n");
1789
    printf("\nKEYBINDINGS\n-----------\n\n");
1727
    printf("\nKEYBINDINGS\n-----------\n\n");
1790
    printf("Keybinding\t\tAction\n\n");
1728
    printf("Keybinding\t\tAction\n\n");
1791
    printf("Ctrl-Q    \t\tExit\n");
1729
    printf("Ctrl-Q,^Z \t\tExit\n");
1792
    printf("Ctrl-S    \t\tSave\n");
1730
    printf("Ctrl-S    \t\tSave\n");
1793
    printf("Ctrl-F    \t\tSearch. Esc, enter and arrows to interact once searching\n");
1731
    printf("Ctrl-F    \t\tSearch. Esc, enter and arrows to interact once searching\n");
1794
    printf("Ctrl-E    \t\tFlip line upwards\n");
1732
    printf("Ctrl-E    \t\tFlip line upwards\n");
1795
    printf("Ctrl-D    \t\tFlip line downwards\n");
1733
    printf("Ctrl-D    \t\tFlip line downwards\n");
Line 1833... Line 1771...
1833
        editorOpen(argv[1]);
1771
        editorOpen(argv[1]);
1834
    else if (arg_response == -1)
1772
    else if (arg_response == -1)
1835
        return 0;
1773
        return 0;
1836
    enableRawMode();
1774
    enableRawMode();
Line 1837... Line 1775...
1837
 
1775
 
Line 1838... Line 1776...
1838
    editorSetStatusMessage(" Ctrl-Q to quit | Ctrl-S to save | (tte -h | --help for more info)");
1776
    editorSetStatusMessage(" Ctrl-Q, ^Z to quit | Ctrl-S to save | (tte -h | --help for more info)");
1839
 
1777
 
1840
    while (1) {
1778
    while (1) {
1841
        editorRefreshScreen();
1779
        editorRefreshScreen();
Line 1842... Line 1780...
1842
        editorProcessKeypress();
1780
        editorProcessKeypress();
1843
    }
1781
    }
1844
 
1782