272 lines
7.4 KiB
C
272 lines
7.4 KiB
C
#include <ncurses.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "editor.h"
|
|
#include "log.h"
|
|
|
|
void help() {
|
|
printf("Usage:\n");
|
|
printf(" cmd open <file/path> // opens the specified file\n");
|
|
printf(" cmd rm <file/path> // deletes the specified file\n");
|
|
printf(" cmd new <file/path> // creates a new empty file at the specified path\n");
|
|
printf(" cmd mv <old/path> <new/path> // moves the specified file to the new path\n");
|
|
printf(" cmd cp <old/path> <new/path> // copies the specified file to the new path\n");
|
|
printf(" cmd lenl <file/path> // returns the length of the specified file in lines\n");
|
|
printf(" cmd lenc <file/path> // returns the length of the specified file in chars\n");
|
|
printf(" cmd log // prints a list of all changes made to the file\n");
|
|
}
|
|
|
|
int open_editor(char* filename) {
|
|
initscr();
|
|
raw();
|
|
noecho();
|
|
keypad(stdscr, true);
|
|
int max_y, max_x;
|
|
getmaxyx(stdscr, max_y, max_x);
|
|
|
|
start_color();
|
|
use_default_colors();
|
|
|
|
init_pair(1, COLOR_CYAN, -1);
|
|
init_pair(2, COLOR_MAGENTA, -1);
|
|
|
|
move(0, 5);
|
|
|
|
Editor editor;
|
|
if (strcmp(filename, "") == 0) {
|
|
editor = new_editor(str_from_chars(filename));
|
|
} else {
|
|
editor = editor_from(str_from_file(fopen(filename, "r")), str_from_chars(filename));
|
|
}
|
|
while (true) {
|
|
refresh();
|
|
int c = getch();
|
|
if (editor.editmode == true) {
|
|
switch (c) {
|
|
case 27:
|
|
switch_mode(&editor);
|
|
break;
|
|
case KEY_BACKSPACE:
|
|
move_cursor(&editor, -1, 0);
|
|
delchar(&editor);
|
|
break;
|
|
case KEY_DC:
|
|
delchar(&editor);
|
|
break;
|
|
case '\n':
|
|
pressed_enter(&editor);
|
|
break;
|
|
case KEY_UP:
|
|
move_cursor(&editor, 0, -1);
|
|
break;
|
|
case KEY_DOWN:
|
|
move_cursor(&editor, 0, 1);
|
|
break;
|
|
case KEY_LEFT:
|
|
move_cursor(&editor, -1, 0);
|
|
break;
|
|
case KEY_RIGHT:
|
|
move_cursor(&editor, 1, 0);
|
|
break;
|
|
default:
|
|
addchar(&editor, c);
|
|
break;
|
|
}
|
|
} else {
|
|
switch (c) {
|
|
case 'q':
|
|
endwin();
|
|
shutdown_editor(&editor);
|
|
|
|
return 0;
|
|
case 'i':
|
|
switch_mode(&editor);
|
|
break;
|
|
case 'w':
|
|
editor.unsaved_changes = false;
|
|
save_file(&editor);
|
|
// TODO: write function to save the data to a file
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Copies a file from source to destination
|
|
int copy_file(const char* source, const char* dest) {
|
|
FILE* src = fopen(source, "rb");
|
|
if (src == NULL) {
|
|
fprintf(stderr, "Error: Could not open source file %s\n", source);
|
|
return -1;
|
|
}
|
|
|
|
FILE* dst = fopen(dest, "wb");
|
|
if (dst == NULL) {
|
|
fclose(src);
|
|
fprintf(stderr, "Error: Could not create destination file %s\n", dest);
|
|
return -1;
|
|
}
|
|
|
|
char buffer[8192];
|
|
size_t bytes;
|
|
while ((bytes = fread(buffer, 1, sizeof(buffer), src)) > 0) {
|
|
if (fwrite(buffer, 1, bytes, dst) != bytes) {
|
|
fclose(src);
|
|
fclose(dst);
|
|
fprintf(stderr, "Error: Write failed to %s\n", dest);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
fclose(src);
|
|
fclose(dst);
|
|
return 0;
|
|
}
|
|
|
|
// Counts the number of characters in a file
|
|
int count_chars(const char* filename) {
|
|
FILE* file = fopen(filename, "r");
|
|
if (file == NULL) {
|
|
fprintf(stderr, "Error: Could not open file %s\n", filename);
|
|
return -1;
|
|
}
|
|
|
|
int count = 0;
|
|
int ch;
|
|
while ((ch = fgetc(file)) != EOF) {
|
|
count++;
|
|
}
|
|
|
|
fclose(file);
|
|
return count;
|
|
}
|
|
|
|
// Counts the number of lines in a file
|
|
int count_lines(const char* filename) {
|
|
FILE* file = fopen(filename, "r");
|
|
if (file == NULL) {
|
|
fprintf(stderr, "Error: Could not open file %s\n", filename);
|
|
return -1;
|
|
}
|
|
|
|
int count = 0;
|
|
int ch;
|
|
int last_char = '\n'; // Handle empty files as 0 lines
|
|
|
|
while ((ch = fgetc(file)) != EOF) {
|
|
if (ch == '\n') {
|
|
count++;
|
|
}
|
|
last_char = ch;
|
|
}
|
|
|
|
// Count last line if it doesn't end with newline
|
|
if (last_char != '\n' && last_char != EOF) {
|
|
count++;
|
|
}
|
|
|
|
fclose(file);
|
|
return count;
|
|
}
|
|
|
|
// Command types
|
|
typedef enum {
|
|
CMD_OPEN,
|
|
CMD_RM,
|
|
CMD_NEW,
|
|
CMD_MV,
|
|
CMD_CP,
|
|
CMD_LENL,
|
|
CMD_LENC,
|
|
CMD_LOG,
|
|
CMD_UNKNOWN
|
|
} CommandType;
|
|
|
|
// Convert string to command type
|
|
CommandType str_to_cmd(const char* cmd) {
|
|
if (strcmp(cmd, "open") == 0) return CMD_OPEN;
|
|
if (strcmp(cmd, "rm") == 0) return CMD_RM;
|
|
if (strcmp(cmd, "new") == 0) return CMD_NEW;
|
|
if (strcmp(cmd, "mv") == 0) return CMD_MV;
|
|
if (strcmp(cmd, "cp") == 0) return CMD_CP;
|
|
if (strcmp(cmd, "lenl") == 0) return CMD_LENL;
|
|
if (strcmp(cmd, "lenc") == 0) return CMD_LENC;
|
|
if (strcmp(cmd, "log") == 0) return CMD_LOG;
|
|
return CMD_UNKNOWN;
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
char log_fmt_string[128];
|
|
|
|
if (argc < 2) {
|
|
help();
|
|
return 1;
|
|
}
|
|
|
|
CommandType cmd = str_to_cmd(argv[1]);
|
|
|
|
if (argc == 3) {
|
|
switch (cmd) {
|
|
case CMD_OPEN:
|
|
sprintf(log_fmt_string, "Opened File [%s]", argv[2]);
|
|
open_editor(argv[2]);
|
|
break;
|
|
case CMD_RM:
|
|
remove(argv[2]);
|
|
sprintf(log_fmt_string, "Deleted File [%s]", argv[2]);
|
|
break;
|
|
case CMD_NEW:
|
|
sprintf(log_fmt_string, "Created File [%s]", argv[2]);
|
|
open_editor(argv[2]);
|
|
break;
|
|
case CMD_LENC:
|
|
printf("%d\n", count_chars(argv[2]));
|
|
break;
|
|
case CMD_LENL:
|
|
printf("%d\n", count_lines(argv[2]));
|
|
break;
|
|
default:
|
|
help();
|
|
}
|
|
}
|
|
|
|
else if (argc == 4) {
|
|
switch (cmd) {
|
|
case CMD_MV:
|
|
if (rename(argv[2], argv[3]) != 0) {
|
|
fprintf(stderr, "Error: Failed to move file %s to %s\n", argv[2], argv[3]);
|
|
} else {
|
|
sprintf(log_fmt_string, "Moved file [%s] To [%s]", argv[2], argv[3]);
|
|
}
|
|
break;
|
|
case CMD_CP:
|
|
if (copy_file(argv[2], argv[3]) != 0) {
|
|
fprintf(stderr, "Error: Failed to copy file %s to %s\n", argv[2], argv[3]);
|
|
sprintf(log_fmt_string, "Failed to copy file [%s] To [%s]", argv[2], argv[3]);
|
|
} else {
|
|
sprintf(log_fmt_string, "Copied file [%s] To [%s]", argv[2], argv[3]);
|
|
}
|
|
break;
|
|
default:
|
|
help();
|
|
}
|
|
}
|
|
|
|
else {
|
|
printf("invalid options\n");
|
|
help();
|
|
}
|
|
|
|
// log output of command
|
|
if (log_fmt_string[0] != '\0') {
|
|
String_t str = str_from_chars(log_fmt_string);
|
|
write_log(&str);
|
|
str_dealloc(&str);
|
|
}
|
|
|
|
return 0;
|
|
}
|