/* SMARTEDIT - A general purpose editor for text files. Copyright (C) 1999 Prashant TR B-42, Kudremukh Colony, II Block, Koramangala, Bangalore - 560034. This program is freeware. You are free to modify and/or redistribute them under the terms of the GNU General Public License version 2.0 or later. Read the file COPYING for the license. The file COPYING.TR contains details about the distribution of this software. */ /* ID for this file. */ #define _STRUCT_C_ #include "editor.h" extern WINDOW *win; TEXT *newnode() { TEXT *node = (TEXT *)malloc(sizeof(TEXT)); if (node == NULL) { /* Give error message. */ printf("Out of memory.\n"); exit(0x7f); return (NULL); } else { /* Initialize the node. */ memset(node -> text, 32, 256); node -> text[255] = 0; return (node); } } void insert_char(int key) { if (!win -> insert) { if (win -> logicalcol < 255) win -> currline -> text[ win -> logicalcol++ - 1] = key; } else { if (win -> logicalcol < 255) { /* Shift contents. */ memmove(&win -> currline -> text[ win -> logicalcol], &win -> currline -> text[ win -> logicalcol - 1], (256 - win -> logicalcol)); win -> currline -> text[ win -> logicalcol++ - 1] = key; /* Cut off at 255 characters. */ win -> currline -> text[255] = 0; } } win -> physicalcol++; if (win -> physicalcol == win -> x2) { win -> physicalcol--; win -> logicalcolstart++; redrawwindow(); } else redrawline(); } void delete_char() { unsigned short pos = 254; TEXT *ptr; ptr = win -> currline; while ((pos != 0xffff) && (ptr -> text[pos] == 32)) pos--; pos++; /* See if line is empty. */ if (pos <= win -> logicalcol - 1) { append_line_for_delete(); redrawwindow(); } else { memccpy(&win -> currline -> text[win -> logicalcol - 1], &win -> currline -> text[win -> logicalcol], 0, 255); win -> currline -> text[strlen(win -> currline -> text)] = 32; /* The length could be 255. */ win -> currline -> text[255] = 0; redrawline(); } } void backspace_char() { unsigned short phycol = win -> physicalcol; if (!win -> logicalcol) return; memccpy(&win -> currline -> text[win -> logicalcol - 2], &win -> currline -> text[win -> logicalcol - 1], 0, 255); win -> currline -> text[strlen(win -> currline -> text)] = 32; /* The length could be 255. */ win -> currline -> text[255] = 0; win -> logicalcol--; if (win -> physicalcol == win -> x1 + 1) { if (win -> logicalcolstart > 10) { win -> logicalcolstart -= 10; win -> physicalcol += 9; redrawwindow(); } else { win -> physicalcol = win -> x1 + win -> logicalcolstart - 1; win -> logicalcolstart = 1; if (phycol == win -> x1 + 1) redrawwindow(); else redrawline(); } } else { win -> physicalcol--; redrawline(); } } void append_line() { unsigned short pos1 = 254, pos2 = 254, num; TEXT *ptr1, *ptr2; if (win -> currline == win -> topline) return; ptr1 = win -> currline -> prev; while ((pos1 != 0xffff) && (ptr1 -> text[pos1] == 32)) pos1--; pos1++; ptr2 = win -> currline; while ((pos2 != 0xffff) && (ptr2 -> text[pos2] == 32)) pos2--; pos2++; /* Can't concatenate those two lines. */ if (pos1 + pos2 >= 255) return; memcpy(&ptr1 -> text[pos1], ptr2 -> text, pos2); ptr1 -> text[strlen(ptr1 -> text)] = 32; /* In case the 255 limit was cut. */ ptr1 -> text[255] = 0; /* Remove the old line. */ win -> currline -> prev -> next = ptr2 -> next; win -> currline -> next -> prev = ptr1; free(win -> currline); win -> currline = ptr1; /* Change line count. */ win -> total_lines--; /* Setup screen conditions. */ win -> logicalrow--; win -> physicalrow--; win -> logicalcol = pos1 + 1; num = pos1 % (win -> x2 - win -> x1 - 1); win -> physicalcol = win -> x1 + num + 1; win -> logicalcolstart = ((win -> logicalcol - 1) / (win -> x2 - win -> x1 - 1)) * (win -> x2 - win -> x1 - 1) + 1; if (win -> physicalrow < win -> y1 + 1) { /* Retain physicalrow. */ win -> physicalrow++; win -> scrline = win -> scrline -> prev; } redrawwindow(); } void append_line_for_delete() { unsigned short pos1 = 254, pos2 = 254; TEXT *ptr1, *ptr2; if (win -> currline -> next == NULL) return; ptr1 = win -> currline; while ((pos1 != 0xffff) && (ptr1 -> text[pos1] == 32)) pos1--; pos1++; ptr2 = win -> currline -> next; while ((pos2 != 0xffff) && (ptr2 -> text[pos2] == 32)) pos2--; pos2++; /* Can't concatenate those two lines. */ if (win -> logicalcol + pos2 - 1 >= 255) return; memcpy(&ptr1 -> text[win -> logicalcol - 1], ptr2 -> text, pos2); /* Remove the old line. */ win -> currline -> next = ptr2 -> next; ptr2 -> next -> prev = win -> currline; free(ptr2); /* Change line count. */ win -> total_lines--; /* Setup screen conditions. */ redrawwindow(); } void insert_line() { TEXT *node; node = newnode(); /* Setup links. */ node -> next = win -> currline -> next; node -> next -> prev = node; node -> prev = win -> currline; win -> currline -> next = node; win -> currline = win -> currline -> next; memccpy(node -> text, &node -> prev -> text[win -> logicalcol - 1], 0, 255); node -> text[strlen(node -> text)] = 32; memset(&node -> prev -> text[win -> logicalcol - 1], 32, 256 - win -> logicalcol); win -> logicalcol = 1; win -> logicalcolstart = 1; win -> physicalcol = win -> x1 + 1; win -> logicalrow++; win -> physicalrow++; /* See if we went past the window. */ if (win -> physicalrow > win -> y2 - 1) { /* Retain physical row. */ win -> physicalrow--; win -> scrline = win -> scrline -> next; } /* Change line count. */ win -> total_lines++; redrawwindow(); } void delete_line() { TEXT *node; /* Setup links. */ /* See if 1st line. */ if (win -> currline == win -> topline) { if (win -> currline -> next != NULL) { win -> topline = win -> topline -> next; free(win -> currline); win -> currline = win -> topline; /* scrline must be at the top. */ win -> scrline = win -> topline; win -> logicalcol = 1; win -> logicalcolstart = 1; win -> physicalcol = win -> x1 + 1; redrawwindow(); /* Change line count. */ win -> total_lines--; } else { memset(win -> currline -> text, 32, 256); win -> currline -> text[255] = 0; win -> physicalcol = win -> x1 + 1; win -> logicalcol = 1; win -> logicalcolstart = 1; redrawline(); } } else { /* If this is that last line. */ if (win -> currline -> next == NULL) { memset(win -> currline -> text, 32, 256); win -> currline -> text[255] = 0; win -> physicalcol = win -> x1 + 1; win -> logicalcol = 1; win -> logicalcolstart = 1; redrawline(); } /* Line somewhere in the middle. */ else { node = win -> currline; if (win -> scrline == win -> currline) win -> scrline = node -> next; win -> currline -> prev -> next = node -> next; win -> currline -> next -> prev = node -> prev; win -> currline = node -> next; free(node); win -> logicalcol = 1; win -> logicalcolstart = 1; win -> physicalcol = win -> x1 + 1; redrawwindow(); /* Change line count. */ win -> total_lines--; } } }