diff --git a/LICENSE b/LICENSE index 59d68ac7..2d0bc9ca 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2016, Salvatore Sanfilippo +Copyright + (c) 2016, Salvatore Sanfilippo + (c) 2025, BloodRose.org All rights reserved. diff --git a/README.md b/README.md index 47d612fe..deb559d5 100644 --- a/README.md +++ b/README.md @@ -24,3 +24,12 @@ style CLI. Kilo was written by Salvatore Sanfilippo aka antirez and is released under the BSD 2 clause license. + +# TODO + +* Testing and stability to reach "usable" level. +* Improve internals to be more understandable. + +### Maybe + +* Send alternate screen sequences if TERM=xterm: "\033[?1049h" and "\033[?1049l" \ No newline at end of file diff --git a/TODO b/TODO deleted file mode 100644 index 95ae28b9..00000000 --- a/TODO +++ /dev/null @@ -1,10 +0,0 @@ -IMPORTANT -=== - -* Testing and stability to reach "usable" level. - -MAYBE -=== - -* Send alternate screen sequences if TERM=xterm: "\033[?1049h" and "\033[?1049l" -* Improve internals to be more understandable. diff --git a/kilo.c b/kilo.c index 0d8aef4e..6d01d988 100644 --- a/kilo.c +++ b/kilo.c @@ -4,7 +4,9 @@ * * ----------------------------------------------------------------------- * - * Copyright (C) 2016 Salvatore Sanfilippo + * Copyright + * (c) 2016, Salvatore Sanfilippo + * (c) 2025, BloodRose.org * * All rights reserved. * @@ -32,7 +34,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define KILO_VERSION "0.0.1" +#define KILO_VERSION "0.0.2" #ifdef __linux__ #define _POSIX_C_SOURCE 200809L @@ -89,9 +91,10 @@ typedef struct erow { check. */ } erow; +/* -- Is not referenced anywhere else typedef struct hlcolor { int r,g,b; -} hlcolor; +} hlcolor; */ struct editorConfig { int cx,cy; /* Cursor x and y position in characters */ @@ -152,50 +155,16 @@ void editorSetStatusMessage(const char *fmt, ...); * a trailing '|' character is added at the end, they are highlighted in * a different color, so that you can have two different sets of keywords. * - * Finally add a stanza in the HLDB global variable with two two arrays - * of strings, and a set of flags in order to enable highlighting of - * comments and numbers. + * Finally add the new syntax to the list of syntaxs in the HLBD struct + * found in `./languages/languages.c`, and a set of flags in order + * to enable highlighting of comments and numbers. * * The characters for single and multi line comments must be exactly two * and must be provided as well (see the C language example). * * There is no support to highlight patterns currently. */ -/* C / C++ */ -char *C_HL_extensions[] = {".c",".h",".cpp",".hpp",".cc",NULL}; -char *C_HL_keywords[] = { - /* C Keywords */ - "auto","break","case","continue","default","do","else","enum", - "extern","for","goto","if","register","return","sizeof","static", - "struct","switch","typedef","union","volatile","while","NULL", - - /* C++ Keywords */ - "alignas","alignof","and","and_eq","asm","bitand","bitor","class", - "compl","constexpr","const_cast","deltype","delete","dynamic_cast", - "explicit","export","false","friend","inline","mutable","namespace", - "new","noexcept","not","not_eq","nullptr","operator","or","or_eq", - "private","protected","public","reinterpret_cast","static_assert", - "static_cast","template","this","thread_local","throw","true","try", - "typeid","typename","virtual","xor","xor_eq", - - /* C types */ - "int|","long|","double|","float|","char|","unsigned|","signed|", - "void|","short|","auto|","const|","bool|",NULL -}; - -/* Here we define an array of syntax highlights by extensions, keywords, - * comments delimiters and flags. */ -struct editorSyntax HLDB[] = { - { - /* C / C++ */ - C_HL_extensions, - C_HL_keywords, - "//","/*","*/", - HL_HIGHLIGHT_STRINGS | HL_HIGHLIGHT_NUMBERS - } -}; - -#define HLDB_ENTRIES (sizeof(HLDB)/sizeof(HLDB[0])) +#include "languages/languages.c" /* ======================= Low level terminal handling ====================== */ @@ -1207,6 +1176,8 @@ void editorProcessKeypress(int fd) { quit_times--; return; } + // \r \n so that we don't exit into the middle of a line or whatever + printf("\r\n"); exit(0); break; case CTRL_S: /* Ctrl-s */ @@ -1305,4 +1276,4 @@ int main(int argc, char **argv) { editorProcessKeypress(STDIN_FILENO); } return 0; -} +} \ No newline at end of file diff --git a/languages/asm.h b/languages/asm.h new file mode 100644 index 00000000..a3a2fb36 --- /dev/null +++ b/languages/asm.h @@ -0,0 +1,108 @@ +char *ASM_HL_extensions[]; +char *ASM_HL_keywords[]; + +const struct editorSyntax syntax_asm = { + ASM_HL_extensions, + ASM_HL_keywords, + "; ","/*","*/", + HL_HIGHLIGHT_STRINGS | HL_HIGHLIGHT_NUMBERS +}; + +char *ASM_HL_extensions[] = { ".asm",".s", NULL }; +char *ASM_HL_keywords[] = { + + /* Nasm registers & argument indexes */ + "%0", "%1", "%2", "%3", "%4", "%5", "%6", "%7", "%8", + "al", "ah", "ax", "eax", "rax", + "bl", "bh", "bx", "ebx", "rbx", + "cl", "ch", "cx", "ecx", "rcx", + "dl", "dh", "dx", "edx", "rdx", + "si", "esi", "rsi", + "di", "edi", "rdi", + "bp", "ebp", "rbp", + "sp", "esp", "rsp", + "r8b", "r8w", "r8d", "r8", + "r9b", "r9w", "r9d", "r9", + "r10b", "r10w", "r10d", "r10", + "r11b", "r11w", "r11d", "r11", + "r12b", "r12w", "r12d", "r12", + "r13b", "r13w", "r13d", "r13", + "r14b", "r14w", "r14d", "r14", + "r15b", "r15w", "r15d", "r15", + "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", + "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", + "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", + "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", + "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", + "cr0", "cr2", "cr3", "cr4", "cr8", + "dr0", "dr1", "dr2", "dr3", "dr6", "dr7", + "tr3", "tr4", "tr5", "tr6", "tr7", + "es", "cs", "ss", "ds", "fs", "gs", + "rip", "eip", "ip", + "flags", "eflags", "rflags", + + /* Nasm preprocessor */ + "%include", + "%define", "%undef", "%line", "%idefine", "%xdefine", "%ixdefine", + "%macro", "%endmacro", "%unmacro", "%assign", + "%if", "%ifdef", "%ifndef", "%ifnidn", "%ifdefalias", "%ifmacro", "%elif", "%else", "%endif", + "%defstr", "%deftok", "%defalias", "%eval", "%ord", "%%", "%rotate", + "%rep", "%endrep", "%clear", + "extern", + + /* Nasm pseudo-instructions, append | */ + "db|", "dw|", "dd|", "dq|", "dt|", "do|", "dy|", "dz|", + "resb|", "resw|", "resd|", "resq|", "rest|", "reso|", "resy|", "resz|", + "incbin|", "equ|", "times|", + "$|", "$$|", + + + /* Nasm true instructions */ + "aaa|", "aad|", "aam|", "aas|", + "adc|", "add|", "and|", + "arpl|", + "bound|", "bsf|", "bsr|", "bswap|", "bt|", "btc|", "btr|", "bts|", + "call|", "cbw|", "cdq|", "clc|", "cld|", "cli|", "clts|", "cmc|", "cmp|", "cmpsb|", "cmpsw|", "cmpxchg|", + "cpuid|", "cwd|", "cwde|", + "daa|", "das|", + "dec|", "div|", + "emms|", "enter|", "esc|", + "f2xm1|", "fabs|", "fadd|", "faddp|", "fbld|", "fbstp|", "fchs|", "fclex|", "fcom|", "fcomp|", "fcompp|", "fcos|", "fdecstp|", "fdiv|", "fdivp|", "fdivr|", "fdivrp|", "ffree|", "fiadd|", "ficom|", "ficomp|", "fidiv|", "fidivr|", "fild|", "fimul|", "fincstp|", "finit|", "fist|", "fistp|", "fisttp|", "fisub|", "fisubr|", "fld|", "fld1|", "fldcw|", "fldenv|", "fldl2e|", "fldl2t|", "fldlg2|", "fldln2|", "fldpi|", "fldz|", "fmul|", "fmulp|", "fnclex|", "fndisi|", "fninit|", "fnop|", "fnsave|", "fnstcw|", "fnstenv|", "fnstsw|", "fpatan|", "fprem|", "fprem1|", "fptan|", "frndint|", "frstor|", "fsave|", "fscale|", "fsetpm|", "fsin|", "fsincos|", "fsqrt|", "fst|", "fstcw|", "fstenv|", "fstp|", "fstsw|", "fsub|", "fsubp|", "fsubr|", "fsubrp|", "ftst|", "fucom|", "fucomp|", "fucompp|", "fxam|", "fxch|", "fxtract|", "fyl2x|", "fyl2xp1|", + "hlt|", "idiv|", "imul|", "in|", "inc|", "insb|", "insw|", "int|", "into|", "invd|", "invlpg|", "iret|", "iretd|", "ja|", "jae|", "jb|", "jbe|", "jc|", "jcxz|", "je|", "jecxz|", "jg|", "jge|", "jl|", "jle|", "jmp|", "jna|", "jnae|", "jnb|", "jnbe|", "jnc|", "jne|", "jng|", "jnge|", "jnl|", "jnle|", "jno|", "jnp|", "jns|", "jnz|", "jo|", "jp|", "jpe|", "jpo|", "js|", "jz|", + "lahf|", "lar|", "lds|", "lea|", "leave|", "les|", "lfence|", "lgdt|", "lidt|", "lldt|", "lmsw|", "lock|", "lodsb|", "lodsw|", "loop|", "loope|", "loopne|", "lsl|", "ltr|", + "mov|", "movsb|", "movsw|", "movsx|", "movzx|", "mul|", + "neg|", "nop|", + "not|", "or|", + "out|", "outsb|", "outsw|", + "pop|", "popa|", "popa|", "popf|", "push|", "pusha|", "pushf|", + "rcl|", "rcr|", "rdmsr|", "rdtsc|", "rdtscp|", "rep|", "repe|", "repne|", "repnz|", "repz|", "ret|", "rol|", "ror|", "rsqrtps|", "rsm|", "sahf|", "sal|", "sar|", "sbb|", "scasb|", "scasw|", "setcc|", "sgdt|", "shl|", "shld|", "shr|", "shrd|", "sidt|", "sldt|", "smsw|", "stc|", "std|", "sti|", "stosb|", "stosw|", "str|", "sub|", "syscall|", "sysenter|", "sysexit|", "sysret|", "test|", "ud2|", "verw|", "wait|", "wbinvd|", "xadd|", "xrelease|", "xacquire|", "xchg|", "xlat|", "xor|", + + /* Nasm simd instructions */ + "addpd|", "addps|", "addsd|", "addss|", + "andnpd|", "andnps|", "andpd|", "andps|", + "blendpd|", "blendps|", "blendvpd|", "blendvps|", + "castpd128|", "castpd256|", "castps128|", "castps256|", + "clflush|", "cmppd|", "cmpps|", "cmpsd|", "cmpss|", "cmpxchg16b|", + "cvtdq2pd|", "cvtdq2ps|", "cvtpd2dq|", "cvtpd2ps|", "cvtps2dq|", "cvtps2pd|", "cvtsd2si|", "cvtsd2ss|", "cvtsi2sd|", "cvtsi2ss|", "cvtss2sd|", "cvtss2si|", "cvttpd2dq|", "cvttpd2pi|", "cvttps2dq|", "cvttps2pi|", "cvttsd2si|", "cvttss2si|", + "divpd|", "divps|", "divsd|", "divss|", + "dppd|", "dpps|", + "emms|", "extractps|", "extrq|", + "insertps|", "insertq|", + "maskmovdqu|", "maskmovq|", + "maxpd|", "maxps|", "maxsd|", "maxss|", "minpd|", "minps|", "minsd|", "minss|", + "monitor|", "movapd|", "movaps|", "movd|", "movddup|", "movdq2q|", "movdqa|", "movdqu|", "movhlps|", "movhpd|", "movhps|", "movlhps|", "movlpd|", "movlps|", "movmskpd|", "movmskps|", "movntdq|", "movntdqa|", "movntpd|", "movntps|", "movq|", "movq2dq|", "movsd|", "movshdup|", "movsldup|", "movss|", "movupd|", "movups|", + "mulpd|", "mulps|", "mulsd|", "mulss|", + "orpd|", "orps|", + "pabsb|", "pabsd|", "pabsw|", "packssdw|", "packsswb|", "packusdw|", "packuswb|", "paddb|", "paddd|", "paddq|", "paddsb|", "paddsw|", "paddusb|", "paddusw|", "paddw|", "palignr|", "pand|", "pandn|", "pavgw|", "pavgb|", "pavgusb|", "pcmpeqb|", "pcmpeqd|", "pcmpeqw|", "pcmpeistri|", "pcmpeistrm|", "pcmpgtb|", "pcmpgtd|", "pcmpgtw|", "pcmpistri|", "pcmpistrm|", "pinsrb|", "pinsrd|", "pinsrq|", "pinsrw|", "pmaddwd|", "pmaxsb|", "pmaxsd|", "pmaxsw|", "pmaxub|", "pmaxud|", "pmaxuw|", "pminsb|", "pminsd|", "pminsw|", "pminub|", "pminud|", "pminuw|", "pmovmskb|", "pmovsxbd|", "pmovsxwq|", "pmovsxbq|", "pmovsxwq|", "pmovsxwd|", "pmovsxdq|", "pmovzxbd|", "pmovzxbq|", "pmovzxwq|", "pmovzxwd|", "pmovzxdq|", "pmuldq|", "pmulhrsw|", "pmulhuw|", "pmulhw|", "pmulld|", "pmullw|", "pmuludq|", "popad|", "popfd|", "por|", "psadbw|", "pshufb|", "pshufd|", "pshufhw|", "pshuflw|", "pshufw|", "psignb|", "psignd|", "psignw|", "pslld|", "pslldq|", "psllq|", "psllw|", "psrad|", "psraw|", "psrld|", "psrldq|", "psrlq|", "psrlw|", "psubb|", "psubd|", "psubq|", "psubsb|", "psubsw|", "psubusb|", "psubusw|", "psubw|", "punpckhbw|", "punpckhdq|", "punpckhqdq|", "punpckhwd|", "punpcklbw|", "punpckldq|", "punpcklqdq|", "punpcklwd|", "pxor|", + "rcpps|", "rcpss|", "rmpps|", "roundsd|", "roundss|", + "rsqrtps|", "rsqrtss|", + "sqrtpd|", "sqrtps|", "sqrtsd|", "sqrtss|", + "subpd|", "subps|", "subsd|", "subss|", + "testpd|", "testps|", + "unpckhpd|", "unpckhps|", "unpcklpd|", "unpcklps|", + "xorpd|", "xorps|", + + NULL + +}; \ No newline at end of file diff --git a/languages/c.h b/languages/c.h new file mode 100644 index 00000000..fb641b47 --- /dev/null +++ b/languages/c.h @@ -0,0 +1,24 @@ +char *C_HL_extensions[]; +char *C_HL_keywords[]; +const struct editorSyntax syntax_c = { + C_HL_extensions, + C_HL_keywords, + "//","/*","*/", + HL_HIGHLIGHT_STRINGS | HL_HIGHLIGHT_NUMBERS +}; + +char *C_HL_extensions[] = {".c",".h",NULL}; +char *C_HL_keywords[] = { + /* Preprocessor Keywords */ + "#define", "#include", "#pragma", "#undef", + "#if", "#ifdef", "#ifndef", "#else", "#elif", "#endif", "#error", + + /* C Keywords */ + "auto","break","case","continue","default","do","else","enum", + "extern","for","goto","if","register","return","sizeof","static", + "struct","switch","typedef","union","volatile","while","NULL", + + /* C types */ + "int|","long|","double|","float|","char|","unsigned|","signed|", + "void|","short|","auto|","const|","bool|",NULL +}; \ No newline at end of file diff --git a/languages/cpp.h b/languages/cpp.h new file mode 100644 index 00000000..c5ef47ac --- /dev/null +++ b/languages/cpp.h @@ -0,0 +1,34 @@ + +char *CPP_HL_extensions[]; +char *CPP_HL_keywords[]; +const struct editorSyntax syntax_cpp = { + CPP_HL_extensions, + CPP_HL_keywords, + "//","/*","*/", + HL_HIGHLIGHT_STRINGS | HL_HIGHLIGHT_NUMBERS +}; + +char *CPP_HL_extensions[] = {".cpp",".hpp",".cc",NULL}; +char *CPP_HL_keywords[] = { + /* Preprocessor Keywords */ + "#define", "#include", "#pragma", "#undef", + "#if", "#ifdef", "#ifndef", "#else", "#elif", "#endif", "#error", + + /* C Keywords */ + "auto","break","case","continue","default","do","else","enum", + "extern","for","goto","if","register","return","sizeof","static", + "struct","switch","typedef","union","volatile","while","NULL", + + /* C++ Keywords */ + "alignas","alignof","and","and_eq","asm","bitand","bitor","class", + "compl","constexpr","const_cast","deltype","delete","dynamic_cast", + "explicit","export","false","friend","inline","mutable","namespace", + "new","noexcept","not","not_eq","nullptr","operator","or","or_eq", + "private","protected","public","reinterpret_cast","static_assert", + "static_cast","template","this","thread_local","throw","true","try", + "typeid","typename","virtual","xor","xor_eq", + + /* C types */ + "int|","long|","double|","float|","char|","unsigned|","signed|", + "void|","short|","auto|","const|","bool|",NULL +}; \ No newline at end of file diff --git a/languages/languages.c b/languages/languages.c new file mode 100644 index 00000000..279c1786 --- /dev/null +++ b/languages/languages.c @@ -0,0 +1,23 @@ +/* +* Separating out the syntaxes like this should make it much easier to add more later, +* and makes this portion of the code much easier to read, taking almost a hundred +* lines of code out of the main program logic, bringing it a little closer to the +* goal of being "less than 1000 SLOC" +*/ + +#include "asm.h" +#include "c.h" +#include "cpp.h" +#include "rust.h" +#include "python.h" + +struct editorSyntax HLDB[] = { + + syntax_asm, + syntax_c, + syntax_cpp, + syntax_rust, + syntax_python + +}; +#define HLDB_ENTRIES (sizeof(HLDB)/sizeof(HLDB[0])) \ No newline at end of file diff --git a/languages/python.h b/languages/python.h new file mode 100644 index 00000000..4a05d0d6 --- /dev/null +++ b/languages/python.h @@ -0,0 +1,47 @@ + +char *PYTHON_HL_extensions[]; +char *PYTHON_HL_keywords[]; +const struct editorSyntax syntax_python = { + PYTHON_HL_extensions, + PYTHON_HL_keywords, + "# ","''","''", + HL_HIGHLIGHT_STRINGS | HL_HIGHLIGHT_NUMBERS +}; + +char *PYTHON_HL_extensions[] = {".py",".pyx",".pyc", NULL}; +char *PYTHON_HL_keywords[] = { + + /* Keywords */ + + "False", "None", "True", "and", "as", "assert", "async", "await", "break", + "class", "continue", "def", "del", "elif", "else", "except", "finally", "for", "from", "global", "if", + "import", "in", "is", "lambda", "nonlocal", "not", "or", "pass", "raise", "return", "try", "while", "with", "yield", + + /* Class dunder methods and names */ + "self|", + "__init__", "__new__", "__del__", "__enter__", "__exit__", "__copy__", "__deepcopy__", + "__repr__", "__str__", "__bytes__", "__format__", + "__getattr__", "__getattribute__", "__setattr__", "__delattr__", "__dir__", + "__get__", "__set__", "__delete__", + "__len__", "__getitem__", "__setitem__", "__delitem__", "__iter__", "__next__", + "__contains__", "__reversed__", "__missing__", + "__call__", "__await__", "__aiter__", "__anext__", "__aenter__", "__aexit__", + "__neg__", "__pos__", "__abs__", "__invert__", + "__add__", "__sub__", "__mul__", "__matmul__", "__truediv__", "__floordiv__", + "__mod__", "__divmod__", "__pow__", "__lshift__", "__rshift__", + "__and__", "__xor__", "__or__", + "__radd__", "__rsub__", "__rmul__", "__rmatmul__", "__rtruediv__", "__rfloordiv__", + "__rmod__", "__rdivmod__", "__rpow__", "__rlshift__", "__rrshift__", + "__rand__", "__rxor__", "__ror__", + "__iadd__", "__isub__", "__imul__", "__imatmul__", "__itruediv__", "__ifloordiv__", + "__imod__", "__ipow__", "__ilshift__", "__irshift__", "__iand__", "__ixor__", "__ior__", + "__eq__", "__ne__", "__lt__", "__le__", "__gt__", "__ge__", "__hash__", + "__int__", "__float__", "__complex__", "__index__", "__bool__" + + /* Types */ + "object|", "bool|", "int|", "float|", "complex|", "str|", + "bytes|", "bytearray|", "list|", "tuple|", "set|", "frozenset|", "dict|", "range|", + + NULL + +}; \ No newline at end of file diff --git a/languages/rust.h b/languages/rust.h new file mode 100644 index 00000000..284f87d5 --- /dev/null +++ b/languages/rust.h @@ -0,0 +1,34 @@ +char *RUST_HL_extensions[]; +char *RUST_HL_keywords[]; + +const struct editorSyntax syntax_rust = { + RUST_HL_extensions, + RUST_HL_keywords, + "//", "/*", "*/", + HL_HIGHLIGHT_STRINGS | HL_HIGHLIGHT_NUMBERS +}; + +char *RUST_HL_extensions[] = { + ".rs", + NULL +}; + +char *RUST_HL_keywords[] = { + + /* Keywords */ + "as", "break", "const", "continue", "crate", "else", + "enum", "extern", "false", "fn", "for", "if", "impl", + "in", "let", "loop", "match", "mod", "move", "mut", + "pub", "ref", "return", "self", "Self", "static", + "struct", "super", "trait", "true", "type", "unsafe", + "use", "where", "while", "async", "await", "dyn", + + /* Types */ + "i8|", "i16|", "i32|", "i64|", "i128|", "isize|", + "u8|", "u16|", "u32|", "u64|", "u128|", "usize|", + "f32|", "f64|", + "bool|", "char|", "str|", + "Option|", "Result|", "String|", "Vec|", + + NULL +}; \ No newline at end of file