diff --git a/editor/document/row.go b/editor/document/row.go index d5af1d8..097b318 100644 --- a/editor/document/row.go +++ b/editor/document/row.go @@ -133,14 +133,28 @@ func (r *Row) updateSyntax() { keywords1 := s.Keywords1 keywords2 := s.Keywords2 + // Scan for comments var scsIndex int = -1 + var mcsIndex int = -1 + var mceIndex int = -1 scs := s.LineCommentStart + mcs := s.MultilineCommentStart + mce := s.MultilineCommentEnd + hasMcs := len(mcs) > 0 + hasMce := len(mce) > 0 if len(scs) > 0 { scsIndex = strings.Index(renderStr, scs) } + if hasMcs { + mcsIndex = strings.Index(renderStr, mcs) + } + if hasMce { + mceIndex = strings.Index(renderStr, mce) + } prevSep := true inString := '0' + inComment := false for i < r.RenderSize() { ch := r.render[i] prevHl := highlight.Normal @@ -151,13 +165,43 @@ func (r *Row) updateSyntax() { ip1 := i + 1 // Single line comments - if inString == '0' && scsIndex == i { + if inString == '0' && !inComment && scsIndex == i { for j := scsIndex; j < renderLen; j++ { r.Hl[j] = highlight.Comment } break } + // Multiline comments + if hasMcs && hasMce && inString == '0' { + if inComment { + r.Hl[i] = highlight.MLComment + // We found the end of the multiline comment + if mceIndex == i { + for j := i; j < (i + len(mce)); j++ { + r.Hl[j] = highlight.MLComment + } + i += len(mce) + inComment = false + prevSep = true + continue + } + + i++ + continue + } + + // Found the start of the multiline comment + if mcsIndex == i { + for j := i; j < (i + len(mce)); j++ { + r.Hl[j] = highlight.MLComment + } + i += len(mcs) + inComment = true + continue + } + } + // String literals if s.Flags&highlight.DoStrings == highlight.DoStrings { // At the start of a string literal diff --git a/editor/highlight/highlight.go b/editor/highlight/highlight.go index 83ed119..806f667 100644 --- a/editor/highlight/highlight.go +++ b/editor/highlight/highlight.go @@ -11,6 +11,7 @@ import ( const ( Normal = iota Comment + MLComment Keyword1 Keyword2 String @@ -28,13 +29,14 @@ const ( // ------------------------------------------------------------------ var syntaxColorMap = map[int]string{ - Comment: terminal.FGCyan, - Keyword1: terminal.FGYellow, - Keyword2: terminal.FGGreen, - String: terminal.FGBrightMagenta, - Number: terminal.FGRed, - Match: terminal.FGBlue, - Normal: terminal.DefaultFGColor, + Comment: terminal.FGCyan, + MLComment: terminal.FGBrightCyan, + Keyword1: terminal.FGYellow, + Keyword2: terminal.FGGreen, + String: terminal.FGBrightMagenta, + Number: terminal.FGRed, + Match: terminal.FGBlue, + Normal: terminal.DefaultFGColor, } // SyntaxToColor Take a highlighting type and map it to @@ -53,12 +55,14 @@ func SyntaxToColor(hl int) string { // ------------------------------------------------------------------ type Syntax struct { - FileType string - FileMatch []string - LineCommentStart string - Keywords1 []string - Keywords2 []string - Flags int + FileType string + FileMatch []string + LineCommentStart string + MultilineCommentStart string + MultilineCommentEnd string + Keywords1 []string + Keywords2 []string + Flags int } // HLDB - The "database" of syntax types @@ -66,20 +70,44 @@ var HLDB = []*Syntax{{ "c", []string{".c", ".h", ".cpp"}, "//", - []string{"switch", "if", "while", "for", "break", "continue", "return", "else", "struct", "union", "typedef", "static", "enum", "class", "case"}, - []string{"int", "long", "double", "float", "char", "unsigned", "signed", "void"}, + "/*", + "*/", + []string{ + "switch", "if", "while", "for", "break", "continue", "return", + "else", "struct", "union", "typedef", "static", "enum", + "class", "case", + }, + []string{"int", + "long", "double", "float", "char", "unsigned", "signed", "void", + "#define", "#endif", "#error", "#if", "#ifdef", "#ifndef", "#include", + "#undef", + }, DoNumbers | DoStrings, }, { "go", []string{".go", "go.mod"}, "//", - []string{"break", "case", "chan", "const", "continue", "default", "defer", "else", "fallthrough", "for", "func", "go", "goto", "if", "import", "interface", "map", "package", "range", "return", "select", "struct", "switch", "type", "var", "iota"}, - []string{"bool", "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64", "float32", "float64", "complex64", "complex128", "byte", "rune", "uint", "int", "uintptr", "string", "struct", "type", "map"}, + "/*", + "*/", + []string{ + "break", "case", "chan", "const", "continue", "default", "defer", + "else", "fallthrough", "for", "func", "go", "goto", "if", + "import", "interface", "map", "package", "range", "return", "select", + "struct", "switch", "type", "var", "iota", + }, + []string{ + "bool", "uint8", "uint16", "uint32", "uint64", "int8", "int16", + "int32", "int64", "float32", "float64", "complex64", "complex128", + "byte", "rune", "uint", "int", "uintptr", "string", + "struct", "type", "map", + }, DoNumbers | DoStrings, }, { "makefile", []string{"Makefile", "makefile", "justfile"}, "#", + "", + "", []string{}, []string{}, 0,