/* Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic Xource is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation. And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version. It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3. */ #include #include #include static int cursor = 0; static int cursor_x = 0; static int cursor_y = 0; static void render_status_bar (int colour) { char status_bar [] = " Xource : C = Xolatile's text editor"; int offset; curses_render_string (status_bar, colour, EFFECT_REVERSE, 0, 0); for (offset = string_length (status_bar); offset != curses_screen_width; ++offset) { curses_render_string (" ", colour, EFFECT_REVERSE, offset, 0); } for (offset = 1; offset != curses_screen_height; ++offset) { curses_render_string (string_realign (number_to_string (offset), 4, ' '), colour, EFFECT_REVERSE, 0, offset); } } static void render_source_code (void) { int offset, select, length; cursor_x = curses_realign_x = 5; cursor_y = curses_realign_y = 1; for (offset = 0; file_list_data [file_list_active] [offset] != '\0'; offset += length) { if (cursor_y > curses_screen_height - 2) { break; } select = syntax_select (& file_list_data [file_list_active] [offset], & length); if (select >= syntax_count) { curses_render_string_point (& file_list_data [file_list_active] [offset], length, COLOUR_WHITE, EFFECT_NORMAL, & cursor_x, & cursor_y); } else { curses_render_string_point (& file_list_data [file_list_active] [offset], length, syntax_colour [select], syntax_effect [select], & cursor_x, & cursor_y); } } if (cursor_y < curses_screen_height) { for (offset = ++cursor_y; offset != curses_screen_height; ++offset) { curses_render_string (" ~", COLOUR_WHITE, EFFECT_REVERSE, 0, offset); } } } static void append_character (char character) { int offset = 0; ++file_list_size [file_list_active]; file_list_data [file_list_active] = reallocate (file_list_data [file_list_active], file_list_size [file_list_active]); for (offset = file_list_size [file_list_active] - 1; offset != cursor; --offset) { file_list_data [file_list_active] [offset] = file_list_data [file_list_active] [offset - 1]; } file_list_data [file_list_active] [cursor] = character; ++cursor; } static void remove_character (void) { int offset = 0; if (cursor == 0) { return; } --file_list_size [file_list_active]; for (offset = cursor - 1; offset != file_list_size [file_list_active] - 1; ++offset) { file_list_data [file_list_active] [offset] = file_list_data [file_list_active] [offset + 1]; } --cursor; } static void cursor_limits (void) { if (cursor <= -1) { cursor = 0; } if (cursor >= file_list_size [file_list_active]) { cursor = file_list_size [file_list_active] - 1; } } int main (int argc, char * * argv) { char * separators = ".,:;<=>+-*/%!&~^?|()[]{}'\" \t\r\n"; char * keywords [] = { "register", "volatile", "auto", "const", "static", "extern", "if", "else", "do", "while", "for", "continue", "switch", "case", "default", "break", "enum", "union", "struct", "typedef", "goto", "void", "return", "sizeof", "char", "short", "int", "long", "signed", "unsigned", "float", "double" }; if (argc == 2) { file_list_import (argv [1]); } else { out ("ARGUMENTS\n", 10); return (-1); } syntax_define_separators (separators); syntax_define_range ("/*", "*/", '\0', COLOUR_GREY, EFFECT_BOLD); syntax_define_range ("//", "\n", '\0', COLOUR_GREY, EFFECT_BOLD); syntax_define_range ("#", "\n", '\\', COLOUR_PINK, EFFECT_NORMAL); syntax_define_range ("'", "'", '\\', COLOUR_PINK, EFFECT_BOLD); syntax_define_operators (".,:;<=>+*-/%!&~^?|()[]{}", COLOUR_YELLOW, EFFECT_NORMAL); syntax_define_words (keywords, sizeof (keywords) / sizeof (keywords [0]), COLOUR_YELLOW, EFFECT_BOLD); syntax_define_default (1, COLOUR_RED, EFFECT_NORMAL, COLOUR_CYAN, EFFECT_BOLD); curses_configure (); curses_bind (SIGNAL_Q, curses_exit); curses_bind (SIGNAL_W | SIGNAL_SHIFT, curses_exit); do { curses_render_background (' ', COLOUR_WHITE, EFFECT_NORMAL); render_status_bar (COLOUR_WHITE); render_source_code (); cursor_x = 8; cursor_y = 4; curses_render_cursor (cursor_x, cursor_y); curses_synchronize (); if (curses_signal == ('Q' & 0X1F)) { curses_active = 0; } else if (curses_signal == '\r') { append_character ('\n'); } else if (curses_signal == ('S' & 0X1F)) { file_list_export (file_list_name [file_list_active]); } else if (curses_signal == (char) 127) { remove_character (); } else if (curses_signal == '\033') { in (& curses_signal, 1); if (curses_signal == '[') { in (& curses_signal, 1); if (curses_signal == 'A') { do { --cursor; } while ( (cursor >= 0) && (file_list_data [file_list_active] [cursor] != '\n') && (file_list_data [file_list_active] [cursor] != '\0') ); --cursor; } else if (curses_signal == 'B') { do { ++cursor; } while ( (cursor <= file_list_size [file_list_active] - 1) && (file_list_data [file_list_active] [cursor] != '\n') && (file_list_data [file_list_active] [cursor] != '\0') ); ++cursor; } else if (curses_signal == 'C') { ++cursor; } else if (curses_signal == 'D') { --cursor; } cursor_limits (); } } else if ((curses_signal >= ' ') && (curses_signal <= '~')) { append_character (curses_signal); cursor_limits (); } else { continue; } } while (curses_active != 0); file_list_delete (); syntax_delete (); return (EXIT_SUCCESS); }