diff --git a/README.md b/README.md index 56530c3..3e9fb89 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ var defs []*highlight.Def ... def := highlight.DetectFiletype(defs, filename, firstLine) -fmt.Println("Filetype is", def.ft) +fmt.Println("Filetype is", def.FileType) ``` For a full example, see the [`syncat`](./examples) example which acts like cat but will syntax highlight the output (if highlight recognizes the filetype). diff --git a/examples/syncat.go b/examples/syncat.go index 42467cb..8bc42ab 100644 --- a/examples/syncat.go +++ b/examples/syncat.go @@ -39,7 +39,7 @@ func main() { h := highlight.NewHighlighter(def) - matches := h.Highlight(string(fileSrc)) + matches := h.HighlightString(string(fileSrc)) lines := strings.Split(string(fileSrc), "\n") for lineN, l := range lines { diff --git a/ftdetect.go b/ftdetect.go index ad8f879..a0ac389 100644 --- a/ftdetect.go +++ b/ftdetect.go @@ -12,5 +12,8 @@ func DetectFiletype(defs []*Def, filename string, firstLine []byte) *Def { } } - return nil + emptyDef := new(Def) + emptyDef.FileType = "Unknown" + emptyDef.rules = new(Rules) + return emptyDef } diff --git a/highlighter.go b/highlighter.go index 5410070..b930d37 100644 --- a/highlighter.go +++ b/highlighter.go @@ -21,7 +21,7 @@ func combineLineMatch(src, dst LineMatch) LineMatch { type State *Region type LineStates interface { - Lines() [][]byte + LineData() [][]byte State(lineN int) State SetState(lineN int, s State) } @@ -173,7 +173,7 @@ func (h *Highlighter) highlightEmptyRegion(start int, canMatchEnd bool, lineNum return highlights } -func (h *Highlighter) Highlight(input string) []LineMatch { +func (h *Highlighter) HighlightString(input string) []LineMatch { lines := strings.Split(input, "\n") var lineMatches []LineMatch @@ -190,10 +190,35 @@ func (h *Highlighter) Highlight(input string) []LineMatch { return lineMatches } -func (h *Highlighter) ReHighlight(input LineStates, startline int) []LineMatch { - lines := input.Lines() +func (h *Highlighter) Highlight(input LineStates, startline int) []LineMatch { + lines := input.LineData() var lineMatches []LineMatch + for i := startline; i < len(lines); i++ { + line := []byte(lines[i]) + + if i == 0 || h.lastRegion == nil { + lineMatches = append(lineMatches, h.highlightEmptyRegion(0, true, i, line)) + } else { + lineMatches = append(lineMatches, h.highlightRegion(0, true, i, line, h.lastRegion)) + } + + curState := h.lastRegion + + input.SetState(i, curState) + } + + return lineMatches +} + +func (h *Highlighter) ReHighlight(input LineStates, startline int) []LineMatch { + lines := input.LineData() + var lineMatches []LineMatch + + h.lastRegion = nil + if startline > 0 { + h.lastRegion = input.State(startline - 1) + } for i := startline; i < len(lines); i++ { line := []byte(lines[i]) diff --git a/parser.go b/parser.go index d27207a..caa22ba 100644 --- a/parser.go +++ b/parser.go @@ -12,7 +12,7 @@ import ( // on filename or header (the first line of the file) // Then it has the rules which define how to highlight the file type Def struct { - ft string + FileType string ftdetect []*regexp.Regexp rules *Rules } @@ -68,7 +68,7 @@ func ParseDef(input []byte) (s *Def, err error) { if k == "filetype" { filetype := v.(string) - s.ft = filetype + s.FileType = filetype } else if k == "detect" { ftdetect := v.(map[interface{}]interface{}) if len(ftdetect) >= 1 {