我想创建自己的操作系统。在这个操作系统中,我有一个用于修改文件数据的编辑模式(目前仅在RAM中)。现在,我想为 C 代码添加语法突出显示。以下是我尝试创建 C 关键字突出显示的方法:
#include "editor.h"
#include "uart.h"
#include "strings.h"
int has_c_extension(const char *filename);
// Масив з ключовими словами мови C/C++
const char *c_keywords[] = {
"auto", "break", "case", "char", "const", "continue",
"default", "do", "double", "else", "enum", "extern",
"float", "for", "goto", "if", "int", "long",
"register", "return", "short", "signed", "sizeof", "static",
"struct", "switch", "typedef", "union", "unsigned", "void",
"volatile", "while", "include", "define", "NULL"
// Додайте інші ключові слова за потреби
};
#define NUM_KEYWORDS (sizeof(c_keywords) / sizeof(c_keywords[0]))
// Додаємо прототипи функцій, щоб компілятор знав про них перед використанням
void display_with_syntax_highlighting(const char *content);
void re_render_current_line(const char *content, int length);
int is_letter_or_digit(char c);
int is_keyword(const char *word);
// Функція редагування файлу
void edit_file(File *file){
char c;
int index = 0;
int is_c_file = 0; // Змінна для перевірки, чи файл є C/C++ файлом
uart_puts("\r\nEntering edit mode. Press Ctrl + Q to save and exit.\r\n");
// Перевіряємо, чи файл має розширення .c або .cpp
if (has_c_extension(file->name)) {
is_c_file = 1;
}
// Якщо файл має вміст, відображаємо його з або без підсвічування
if (file->content[0] != '\0'){
index = my_strlen(file->content);
if (is_c_file) {
display_with_syntax_highlighting(file->content);
} else {
uart_puts(file->content);
}
}
while(1){
c = uart_getc();
if(c == 17){ // Ctrl + Q для виходу
file->content[index] = '\0';
uart_puts("\r\nFile saved and exited edit mode.\r\n");
break;
} else if (c == '\b' || c == 127){ // Обробка Backspace
if(index > 0){
index--;
file->content[index] = '\0'; // Видаляємо символ з вмісту
if (is_c_file) {
re_render_current_line(file->content, index);
} else {
uart_puts("\b \b");
}
}
} else if (c == '\r'){ // Обробка Enter
if(index < MAX_FILE_SIZE -1){
file->content[index++] = '\n';
uart_putc('\r');
uart_putc('\n');
}
} else {
if(index < MAX_FILE_SIZE -1){
file->content[index++] = c; // Додаємо символ до вмісту файлу
if (is_c_file) {
re_render_current_line(file->content, index);
} else {
uart_putc(c);
}
}
}
}
}
int has_c_extension(const char *filename) {
int len = my_strlen(filename);
if (len >= 2 && my_strcmp(filename + len - 2, ".c") == 0) {
return 1;
}
if (len >= 4 && my_strcmp(filename + len - 4, ".cpp") == 0) {
return 1;
}
return 0;
}
char c;
int index = 0;
uart_puts("\r\nEntering edit mode. Press Ctrl + Q to save and exit.\r\n");
// Якщо файл має вміст, відображаємо його з підсвічуванням
if (file->content[0] != '\0'){
index = my_strlen(file->content);
display_with_syntax_highlighting(file->content); // Використовуємо функцію підсвічування
}
while(1){
c = uart_getc();
if(c == 17){ // Ctrl + Q для виходу
file->content[index] = '\0';
uart_puts("\r\nFile saved and exited edit mode.\r\n");
break;
} else if (c == '\b' || c == 127){ // Обробка Backspace
if(index > 0){
index--;
file->content[index] = '\0';
re_render_current_line(file->content, index); // Перерисовуємо поточний рядок
}
} else if (c == '\r'){ // Обробка Enter
if(index < MAX_FILE_SIZE -1){
file->content[index++] = '\n';
uart_putc('\r');
uart_putc('\n');
}
} else {
if(index < MAX_FILE_SIZE -1){
file->content[index++] = c; // Додаємо символ до вмісту файлу
re_render_current_line(file->content, index); // Перерисовуємо поточний рядок
}
}
}
}
// Функція відображення тексту з підсвічуванням синтаксису
void display_with_syntax_highlighting(const char *content){
const char *ptr = content;
char word[100];
int w_index = 0;
while(*ptr){
if(is_letter_or_digit(*ptr)){
word[w_index++] = *ptr;
} else {
if(w_index > 0){
word[w_index] = '\0';
if(is_keyword(word)){
uart_puts(ANSI_COLOR_BLUE);
uart_puts(word);
uart_puts(ANSI_COLOR_RESET);
} else {
uart_puts(word);
}
w_index = 0;
}
uart_putc(*ptr);
}
ptr++;
}
if(w_index > 0){
word[w_index] = '\0';
if(is_keyword(word)){
uart_puts(ANSI_COLOR_BLUE);
uart_puts(word);
uart_puts(ANSI_COLOR_RESET);
} else {
uart_puts(word);
}
}
}
void re_render_current_line(const char *content, int length){
uart_putc('\r');
int start = length - 1;
while(start >= 0 && content[start] != '\n'){
start--;
}
start++;
char line[256];
int line_index = 0;
for(int i = start; i < length; i++){
line[line_index++] = content[i];
}
line[line_index] = '\0';
uart_puts("\033[K");
display_with_syntax_highlighting(line);
}
int is_letter_or_digit(char c){
return (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
(c == '_');
}
int is_keyword(const char *word){
for(int i = 0; i < NUM_KEYWORDS; i++){
if(my_strcmp(word, c_keywords[i]) == 0){
return 1;
}
}
return 0;
}
我不知道为什么代码没有突出显示,但是我在主文件中添加了测试代码来为一些测试着色:
void test_ansi_colors() {
uart_puts("\033[31mЦей текст повинен бути червоним\033[0m\r\n");
uart_puts("\033[32mЦей текст повинен бути зеленим\033[0m\r\n");
uart_puts("\033[34mЦей текст повинен бути синім\033[0m\r\n");
}
它是彩色的:
你说你写你的个人操作系统。伟大的意图!
“代码中没有着色 C 代码的问题在哪里”,- 代码中的问题。你必须有终端模拟器和外壳。你必须自己编码或从 sombady 获取。
同时,检查 dokumantutaon 以了解您的操作系统、术语和 shell。您将在文本中看到这一点,为您的操作系统、shell、术语显示文本的方法是什么。
为了帮助人们获得 CEE 和帮助,请指定您现在使用的操作系统、术语和 shell。我的意思不是 uo os,而是 yu type 的操作系统。您可以更新问题的标签来反映和缩小问题范围。
我会更新答案,但我们知道具体细节。