From f1bcee83d6c21a92e9d1bd1530c575149a85635a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6ran=20Karl?= <3951388+JoeKar@users.noreply.github.com> Date: Thu, 4 May 2023 23:48:42 +0200 Subject: [PATCH] Improve file detection with signature check capabilities This allows more complex detection upon regex rules for a certain amount of lines. --- internal/buffer/buffer.go | 65 ++++++++++++++++++++++++++---- pkg/highlight/ftdetect.go | 36 ++++++++++++----- pkg/highlight/parser.go | 12 +++--- runtime/help/colors.md | 6 +-- runtime/syntax/PowerShell.yaml | 2 +- runtime/syntax/README.md | 2 +- runtime/syntax/awk.yaml | 2 +- runtime/syntax/bat.yaml | 2 +- runtime/syntax/crontab.yaml | 2 +- runtime/syntax/csx.yaml | 2 +- runtime/syntax/fish.yaml | 2 +- runtime/syntax/godoc.yaml | 2 +- runtime/syntax/groovy.yaml | 2 +- runtime/syntax/html4.yaml | 2 +- runtime/syntax/html5.yaml | 2 +- runtime/syntax/javascript.yaml | 2 +- runtime/syntax/json.yaml | 2 +- runtime/syntax/julia.yaml | 2 +- runtime/syntax/justfile.yaml | 2 +- runtime/syntax/mail.yaml | 2 +- runtime/syntax/make_headers.go | 10 ++--- runtime/syntax/makefile.yaml | 2 +- runtime/syntax/nginx.yaml | 2 +- runtime/syntax/objc.yaml | 1 + runtime/syntax/patch.yaml | 2 +- runtime/syntax/perl.yaml | 2 +- runtime/syntax/python2.yaml | 2 +- runtime/syntax/python3.yaml | 2 +- runtime/syntax/ruby.yaml | 2 +- runtime/syntax/sage.yaml | 2 +- runtime/syntax/sed.yaml | 2 +- runtime/syntax/sh.yaml | 2 +- runtime/syntax/syntax_converter.go | 2 +- runtime/syntax/systemd.yaml | 2 +- runtime/syntax/tcl.yaml | 2 +- runtime/syntax/xml.yaml | 2 +- runtime/syntax/yaml.yaml | 2 +- runtime/syntax/zsh.yaml | 2 +- 38 files changed, 131 insertions(+), 63 deletions(-) diff --git a/internal/buffer/buffer.go b/internal/buffer/buffer.go index 6365cec022..bae8acd7e4 100644 --- a/internal/buffer/buffer.go +++ b/internal/buffer/buffer.go @@ -126,6 +126,13 @@ type SharedBuffer struct { origHash [md5.Size]byte } +// SyntaxFileBuffer is a helper structure to store properties of one single syntax file +type SyntaxFileBuffer struct { + Header *highlight.Header + FileName string + SyntaxDef *highlight.Def +} + func (b *SharedBuffer) insert(pos Loc, value []byte) { b.isModified = true b.HasSuggestions = false @@ -685,6 +692,8 @@ func (b *Buffer) UpdateRules() { if ft == "off" { return } + + syntaxFiles := []SyntaxFileBuffer{} syntaxFile := "" foundDef := false var header *highlight.Header @@ -706,16 +715,21 @@ func (b *Buffer) UpdateRules() { continue } - if ((ft == "unknown" || ft == "") && highlight.MatchFiletype(header.FtDetect, b.Path, b.lines[0].data)) || header.FileType == ft { + if ((ft == "unknown" || ft == "") && highlight.MatchFileName(header, b.Path)) || header.FileType == ft { syndef, err := highlight.ParseDef(file, header) if err != nil { screen.TermMessage("Error parsing syntax file " + f.Name() + ": " + err.Error()) continue } - b.SyntaxDef = syndef - syntaxFile = f.Name() foundDef = true - break + + if header.FileType == ft { + b.SyntaxDef = syndef + syntaxFile = f.Name() + break + } else { + syntaxFiles = append(syntaxFiles, SyntaxFileBuffer{header, f.Name(), syndef}) + } } } @@ -734,9 +748,8 @@ func (b *Buffer) UpdateRules() { } if ft == "unknown" || ft == "" { - if highlight.MatchFiletype(header.FtDetect, b.Path, b.lines[0].data) { - syntaxFile = f.Name() - break + if highlight.MatchFileName(header, b.Path) { + syntaxFiles = append(syntaxFiles, SyntaxFileBuffer{header, f.Name(), nil}) } } else if header.FileType == ft { syntaxFile = f.Name() @@ -744,6 +757,44 @@ func (b *Buffer) UpdateRules() { } } + if syntaxFile == "" { + length := len(syntaxFiles) + if length > 0 { + signatureMatch := false + if length > 1 { + detectlimit := util.IntOpt(b.Settings["detectlimit"]) + lineCount := len(b.lines) + limit := 0 + if detectlimit > 0 { + if lineCount < detectlimit { + limit = lineCount + } else { + limit = detectlimit + } + } else { + limit = lineCount + } + for i := 0; i < length && !signatureMatch; i++ { + if highlight.HasFileSignature(syntaxFiles[i].Header) { + for j := 0; j < limit && !signatureMatch; j++ { + if highlight.MatchFileSignature(syntaxFiles[i].Header, b.lines[j].data) { + syntaxFile = syntaxFiles[i].FileName + b.SyntaxDef = syntaxFiles[i].SyntaxDef + header = syntaxFiles[i].Header + signatureMatch = true + } + } + } + } + } + if length == 1 || !signatureMatch { + syntaxFile = syntaxFiles[0].FileName + b.SyntaxDef = syntaxFiles[0].SyntaxDef + header = syntaxFiles[0].Header + } + } + } + if syntaxFile != "" && !foundDef { // we found a syntax file using a syntax header file for _, f := range config.ListRuntimeFiles(config.RTSyntax) { diff --git a/pkg/highlight/ftdetect.go b/pkg/highlight/ftdetect.go index 580ade8fc4..5cc2bd327b 100644 --- a/pkg/highlight/ftdetect.go +++ b/pkg/highlight/ftdetect.go @@ -1,17 +1,33 @@ package highlight -import "regexp" - -// MatchFiletype will use the list of syntax definitions provided and the filename and first line of the file -// to determine the filetype of the file -// It will return the corresponding syntax definition for the filetype -func MatchFiletype(ftdetect [2]*regexp.Regexp, filename string, firstLine []byte) bool { - if ftdetect[0] != nil && ftdetect[0].MatchString(filename) { - return true +// MatchFileName will use the list of syntax definitions provided and the filename to +// determine the filetype of the file +func MatchFileName(header *Header, filename string) bool { + if header != nil { + // index 0 refers to the filename respective filetype rule + if header.FtDetect[0] != nil { + return header.FtDetect[0].MatchString(filename) + } } - if ftdetect[1] != nil { - return ftdetect[1].Match(firstLine) + return false +} + +// HasFileSignature will use the list of syntax definitions provided +// to determine if a signature is present +func HasFileSignature(header *Header) bool { + // index 1 refers to the signature rule + return header != nil && header.FtDetect[1] != nil +} + +// MatchFileSignature will use the list of syntax definitions provided and a line of the file +// to determine a match of the signature +func MatchFileSignature(header *Header, line []byte) bool { + if header != nil { + // index 1 refers to the signature rule + if header.FtDetect[1] != nil { + return header.FtDetect[1].Match(line) + } } return false diff --git a/pkg/highlight/parser.go b/pkg/highlight/parser.go index b41c83c5fc..f88574f05f 100644 --- a/pkg/highlight/parser.go +++ b/pkg/highlight/parser.go @@ -46,7 +46,7 @@ type HeaderYaml struct { FileType string `yaml:"filetype"` Detect struct { FNameRgx string `yaml:"filename"` - HeaderRgx string `yaml:"header"` + SignatureRgx string `yaml:"signature"` } `yaml:"detect"` } @@ -104,13 +104,13 @@ func MakeHeader(data []byte) (*Header, error) { var err error header.FileType = string(lines[0]) fnameRgx := string(lines[1]) - headerRgx := string(lines[2]) + signatureRgx := string(lines[2]) if fnameRgx != "" { header.FtDetect[0], err = regexp.Compile(fnameRgx) } - if headerRgx != "" { - header.FtDetect[1], err = regexp.Compile(headerRgx) + if signatureRgx != "" { + header.FtDetect[1], err = regexp.Compile(signatureRgx) } if err != nil { @@ -135,8 +135,8 @@ func MakeHeaderYaml(data []byte) (*Header, error) { if hdrYaml.Detect.FNameRgx != "" { header.FtDetect[0], err = regexp.Compile(hdrYaml.Detect.FNameRgx) } - if hdrYaml.Detect.HeaderRgx != "" { - header.FtDetect[1], err = regexp.Compile(hdrYaml.Detect.HeaderRgx) + if hdrYaml.Detect.SignatureRgx != "" { + header.FtDetect[1], err = regexp.Compile(hdrYaml.Detect.SignatureRgx) } if err != nil { diff --git a/runtime/help/colors.md b/runtime/help/colors.md index ac8b4be370..4a3ee7e0cb 100644 --- a/runtime/help/colors.md +++ b/runtime/help/colors.md @@ -267,13 +267,13 @@ detect: ``` Micro will match this regex against a given filename to detect the filetype. -You may also provide an optional `header` regex that will check the first line -of the file. For example: +You may also provide an optional `signature` regex that will check a certain +amount of lines of a file to find specific marks. For example: ``` detect: filename: "\\.ya?ml$" - header: "%YAML" + signature: "%YAML" ``` ### Syntax rules diff --git a/runtime/syntax/PowerShell.yaml b/runtime/syntax/PowerShell.yaml index 7a45e426e3..daaa2b2107 100644 --- a/runtime/syntax/PowerShell.yaml +++ b/runtime/syntax/PowerShell.yaml @@ -5,7 +5,7 @@ filetype: powershell detect: filename: "\\.ps(1|m1|d1)$" - #header: "" + #signature: "" rules: # - comment.block: # Block Comment diff --git a/runtime/syntax/README.md b/runtime/syntax/README.md index 7d1a9de4c1..e97a4f77ed 100644 --- a/runtime/syntax/README.md +++ b/runtime/syntax/README.md @@ -2,7 +2,7 @@ Here are micro's syntax files. -Each yaml file specifies how to detect the filetype based on file extension or headers (first line of the file). +Each yaml file specifies how to detect the filetype based on file extension or given signature. The signature can be matched to a maximum of 100 lines (to limit parse times) for a best "guess". Then there are patterns and regions linked to highlight groups which tell micro how to highlight that filetype. Making your own syntax files is very simple. I recommend you check the file after you are finished with the diff --git a/runtime/syntax/awk.yaml b/runtime/syntax/awk.yaml index ff3f6988e7..93ddf9ae98 100644 --- a/runtime/syntax/awk.yaml +++ b/runtime/syntax/awk.yaml @@ -2,7 +2,7 @@ filetype: awk detect: filename: "\\.awk$" - header: "^#!.*bin/(env +)?awk( |$)" + signature: "^#!.*bin/(env +)?awk( |$)" rules: - preproc: "\\$[A-Za-z0-9_!@#$*?\\-]+" diff --git a/runtime/syntax/bat.yaml b/runtime/syntax/bat.yaml index e6077a57ea..7af1f65c22 100644 --- a/runtime/syntax/bat.yaml +++ b/runtime/syntax/bat.yaml @@ -2,7 +2,7 @@ filetype: batch detect: filename: "(\\.bat$)" - # header: "" + # signature: "" rules: # Numbers diff --git a/runtime/syntax/crontab.yaml b/runtime/syntax/crontab.yaml index cebc7cad6a..aec2e78ffc 100644 --- a/runtime/syntax/crontab.yaml +++ b/runtime/syntax/crontab.yaml @@ -2,7 +2,7 @@ filetype: crontab detect: filename: "crontab$" - header: "^#.*?/etc/crontab" + signature: "^#.*?/etc/crontab" rules: # The time and date fields are: diff --git a/runtime/syntax/csx.yaml b/runtime/syntax/csx.yaml index a3a13a6c59..3710af178c 100644 --- a/runtime/syntax/csx.yaml +++ b/runtime/syntax/csx.yaml @@ -1,7 +1,7 @@ filetype: csharp-script detect: filename: "\\.csx$" - header: "^#!.*/(env +)?dotnet-script( |$)" + signature: "^#!.*/(env +)?dotnet-script( |$)" rules: - include: "csharp" diff --git a/runtime/syntax/fish.yaml b/runtime/syntax/fish.yaml index 88798a04aa..e507809702 100644 --- a/runtime/syntax/fish.yaml +++ b/runtime/syntax/fish.yaml @@ -2,7 +2,7 @@ filetype: fish detect: filename: "\\.fish$" - header: "^#!.*/(env +)?fish( |$)" + signature: "^#!.*/(env +)?fish( |$)" rules: # Numbers diff --git a/runtime/syntax/godoc.yaml b/runtime/syntax/godoc.yaml index b77262965c..4aa1bc4574 100644 --- a/runtime/syntax/godoc.yaml +++ b/runtime/syntax/godoc.yaml @@ -5,7 +5,7 @@ filetype: godoc detect: filename: "\\.godoc$" - header: package.*import + signature: package.*import rules: - preproc: "^[^ ].*" diff --git a/runtime/syntax/groovy.yaml b/runtime/syntax/groovy.yaml index 3aa0e28343..a19cdcd386 100644 --- a/runtime/syntax/groovy.yaml +++ b/runtime/syntax/groovy.yaml @@ -2,7 +2,7 @@ filetype: groovy detect: filename: "(\\.(groovy|gy|gvy|gsh|gradle)$|^[Jj]enkinsfile$)" - header: "^#!.*/(env +)?groovy *$" + signature: "^#!.*/(env +)?groovy *$" rules: # And the style guide for constants is CONSTANT_CASE diff --git a/runtime/syntax/html4.yaml b/runtime/syntax/html4.yaml index c132d61e98..a7cfae3f0c 100644 --- a/runtime/syntax/html4.yaml +++ b/runtime/syntax/html4.yaml @@ -2,7 +2,7 @@ filetype: html4 detect: filename: "\\.htm[l]?4$" - header: "" + signature: "" rules: - error: "<[^!].*?>" diff --git a/runtime/syntax/html5.yaml b/runtime/syntax/html5.yaml index 411d538581..97bffde273 100644 --- a/runtime/syntax/html5.yaml +++ b/runtime/syntax/html5.yaml @@ -2,7 +2,7 @@ filetype: html5 detect: filename: "\\.htm[l]?5$" - header: "" + signature: "" rules: - error: "<[^!].*?>" diff --git a/runtime/syntax/javascript.yaml b/runtime/syntax/javascript.yaml index b2bfe4873f..0b42caa69e 100644 --- a/runtime/syntax/javascript.yaml +++ b/runtime/syntax/javascript.yaml @@ -2,7 +2,7 @@ filetype: javascript detect: filename: "(\\.js$|\\.es[5678]?$|\\.mjs$)" - header: "^#!.*/(env +)?node( |$)" + signature: "^#!.*/(env +)?node( |$)" rules: - constant.number: "\\b[-+]?([1-9][0-9]*|0[0-7]*|0x[0-9a-fA-F]+)([uU][lL]?|[lL][uU]?)?\\b" diff --git a/runtime/syntax/json.yaml b/runtime/syntax/json.yaml index c590bd388d..35b483e9f2 100644 --- a/runtime/syntax/json.yaml +++ b/runtime/syntax/json.yaml @@ -2,7 +2,7 @@ filetype: json detect: filename: "\\.json$" - header: "^\\{$" + signature: "^\\{$" rules: - constant.number: "\\b[-+]?([1-9][0-9]*|0[0-7]*|0x[0-9a-fA-F]+)([uU][lL]?|[lL][uU]?)?\\b" diff --git a/runtime/syntax/julia.yaml b/runtime/syntax/julia.yaml index c96ef0f34f..8a46e5cf29 100644 --- a/runtime/syntax/julia.yaml +++ b/runtime/syntax/julia.yaml @@ -2,7 +2,7 @@ filetype: julia detect: filename: "\\.jl$" - header: "^#!.*/(env +)?julia( |$)" + signature: "^#!.*/(env +)?julia( |$)" rules: diff --git a/runtime/syntax/justfile.yaml b/runtime/syntax/justfile.yaml index 926edb21e2..2a856edb8e 100644 --- a/runtime/syntax/justfile.yaml +++ b/runtime/syntax/justfile.yaml @@ -3,7 +3,7 @@ filetype: 'justfile' detect: filename: "(^\\.?[Jj]ustfile|\\.just)$" - header: "^#!.*/(env +)?[bg]?just --justfile" + signature: "^#!.*/(env +)?[bg]?just --justfile" rules: - preproc: "\\<(ifeq|ifdef|ifneq|ifndef|else|endif)\\>" diff --git a/runtime/syntax/mail.yaml b/runtime/syntax/mail.yaml index 57aa034415..a400b28b72 100644 --- a/runtime/syntax/mail.yaml +++ b/runtime/syntax/mail.yaml @@ -2,7 +2,7 @@ filetype: mail detect: filename: "(.*/mutt-.*|\\.eml)$" - header: "^From .* \\d+:\\d+:\\d+ \\d+" + signature: "^From .* \\d+:\\d+:\\d+ \\d+" rules: - type: "^From .*" diff --git a/runtime/syntax/make_headers.go b/runtime/syntax/make_headers.go index e04d806272..31bed51164 100644 --- a/runtime/syntax/make_headers.go +++ b/runtime/syntax/make_headers.go @@ -16,15 +16,15 @@ import ( type HeaderYaml struct { FileType string `yaml:"filetype"` Detect struct { - FNameRgx string `yaml:"filename"` - HeaderRgx string `yaml:"header"` + FNameRgx string `yaml:"filename"` + SignatureRgx string `yaml:"signature"` } `yaml:"detect"` } type Header struct { FileType string FNameRgx string - HeaderRgx string + SignatureRgx string } func main() { @@ -58,7 +58,7 @@ func encode(name string, c HeaderYaml) { f, _ := os.Create(name + ".hdr") f.WriteString(c.FileType + "\n") f.WriteString(c.Detect.FNameRgx + "\n") - f.WriteString(c.Detect.HeaderRgx + "\n") + f.WriteString(c.Detect.SignatureRgx + "\n") f.Close() } @@ -69,7 +69,7 @@ func decode(name string) Header { var hdr Header hdr.FileType = string(strs[0]) hdr.FNameRgx = string(strs[1]) - hdr.HeaderRgx = string(strs[2]) + hdr.SignatureRgx = string(strs[2]) fmt.Printf("took %v\n", time.Since(start)) return hdr diff --git a/runtime/syntax/makefile.yaml b/runtime/syntax/makefile.yaml index 7e90cdeb76..670935fa7e 100644 --- a/runtime/syntax/makefile.yaml +++ b/runtime/syntax/makefile.yaml @@ -2,7 +2,7 @@ filetype: makefile detect: filename: "([Mm]akefile|\\.ma?k)$" - header: "^#!.*/(env +)?[bg]?make( |$)" + signature: "^#!.*/(env +)?[bg]?make( |$)" rules: - preproc: "\\<(ifeq|ifdef|ifneq|ifndef|else|endif)\\>" diff --git a/runtime/syntax/nginx.yaml b/runtime/syntax/nginx.yaml index c2223b5a31..c35e213ef2 100644 --- a/runtime/syntax/nginx.yaml +++ b/runtime/syntax/nginx.yaml @@ -2,7 +2,7 @@ filetype: nginx detect: filename: "nginx.*\\.conf$|\\.nginx$" - header: "^(server|upstream)[a-z ]*\\{$" + signature: "^(server|upstream)[a-z ]*\\{$" rules: - preproc: "\\b(events|server|http|location|upstream)[[:space:]]*\\{" diff --git a/runtime/syntax/objc.yaml b/runtime/syntax/objc.yaml index 223d6929f8..950a2acbb9 100644 --- a/runtime/syntax/objc.yaml +++ b/runtime/syntax/objc.yaml @@ -2,6 +2,7 @@ filetype: objective-c detect: filename: "\\.(m|mm|h)$" + signature: "(obj|objective)-c|#import|@(encode|end|interface|implementation|class|selector|protocol|synchronized|try|catch|finally|property|optional|required|import|autoreleasepool)" rules: - type: "\\b(float|double|CGFloat|id|bool|BOOL|Boolean|char|int|short|long|sizeof|enum|void|static|const|struct|union|typedef|extern|(un)?signed|inline|Class|SEL|IMP|NS(U)?Integer)\\b" diff --git a/runtime/syntax/patch.yaml b/runtime/syntax/patch.yaml index 996bdc38f5..6275d42381 100644 --- a/runtime/syntax/patch.yaml +++ b/runtime/syntax/patch.yaml @@ -2,7 +2,7 @@ filetype: patch detect: filename: "\\.(patch|diff)$" - header: "^diff" + signature: "^diff" rules: - brightgreen: "^\\+.*" diff --git a/runtime/syntax/perl.yaml b/runtime/syntax/perl.yaml index 984cc24a21..5a8ad3cd3e 100644 --- a/runtime/syntax/perl.yaml +++ b/runtime/syntax/perl.yaml @@ -2,7 +2,7 @@ filetype: perl detect: filename: "\\.p[lmp]$" - header: "^#!.*/(env +)?perl( |$)" + signature: "^#!.*/(env +)?perl( |$)" rules: - type: "\\b(accept|alarm|atan2|bin(d|mode)|c(aller|homp|h(dir|mod|op|own|root)|lose(dir)?|onnect|os|rypt)|d(bm(close|open)|efined|elete|ie|o|ump)|e(ach|of|val|x(ec|ists|it|p))|f(cntl|ileno|lock|ork))\\b|\\b(get(c|login|peername|pgrp|ppid|priority|pwnam|(host|net|proto|serv)byname|pwuid|grgid|(host|net)byaddr|protobynumber|servbyport)|([gs]et|end)(pw|gr|host|net|proto|serv)ent|getsock(name|opt)|gmtime|goto|grep|hex|index|int|ioctl|join)\\b|\\b(keys|kill|last|length|link|listen|local(time)?|log|lstat|m|mkdir|msg(ctl|get|snd|rcv)|next|oct|open(dir)?|ord|pack|pipe|pop|printf?|push|q|qq|qx|rand|re(ad(dir|link)?|cv|say|do|name|quire|set|turn|verse|winddir)|rindex|rmdir|s|scalar|seek(dir)?)\\b|\\b(se(lect|mctl|mget|mop|nd|tpgrp|tpriority|tsockopt)|shift|shm(ctl|get|read|write)|shutdown|sin|sleep|socket(pair)?|sort|spli(ce|t)|sprintf|sqrt|srand|stat|study|substr|symlink|sys(call|read|tem|write)|tell(dir)?|time|tr(y)?|truncate|umask)\\b|\\b(un(def|link|pack|shift)|utime|values|vec|wait(pid)?|wantarray|warn|write)\\b" diff --git a/runtime/syntax/python2.yaml b/runtime/syntax/python2.yaml index d668809467..1e9c1e9187 100644 --- a/runtime/syntax/python2.yaml +++ b/runtime/syntax/python2.yaml @@ -2,7 +2,7 @@ filetype: python2 detect: filename: "\\.py2$" - header: "^#!.*/(env +)?python2$" + signature: "^#!.*/(env +)?python2$" rules: diff --git a/runtime/syntax/python3.yaml b/runtime/syntax/python3.yaml index f84d536e49..cf5bef24b9 100644 --- a/runtime/syntax/python3.yaml +++ b/runtime/syntax/python3.yaml @@ -2,7 +2,7 @@ filetype: python detect: filename: "\\.py(3)?$" - header: "^#!.*/(env +)?python(3)?$" + signature: "^#!.*/(env +)?python(3)?$" rules: # built-in objects diff --git a/runtime/syntax/ruby.yaml b/runtime/syntax/ruby.yaml index f04593ce03..4a432d3bac 100644 --- a/runtime/syntax/ruby.yaml +++ b/runtime/syntax/ruby.yaml @@ -2,7 +2,7 @@ filetype: ruby detect: filename: "\\.(rb|rake|gemspec)$|^(.*[\\/])?(Gemfile|config.ru|Rakefile|Capfile|Vagrantfile|Guardfile|Appfile|Fastfile|Pluginfile|Podfile|\\.?[Bb]rewfile)$" - header: "^#!.*/(env +)?ruby( |$)" + signature: "^#!.*/(env +)?ruby( |$)" rules: - comment.bright: diff --git a/runtime/syntax/sage.yaml b/runtime/syntax/sage.yaml index e24fbeb603..8d2cb07a7d 100644 --- a/runtime/syntax/sage.yaml +++ b/runtime/syntax/sage.yaml @@ -2,7 +2,7 @@ filetype: sage detect: filename: "\\.sage$" - header: "^#!.*/(env +)?sage( |$)" + signature: "^#!.*/(env +)?sage( |$)" rules: diff --git a/runtime/syntax/sed.yaml b/runtime/syntax/sed.yaml index dc5f7adc95..1b297c448b 100644 --- a/runtime/syntax/sed.yaml +++ b/runtime/syntax/sed.yaml @@ -2,7 +2,7 @@ filetype: sed detect: filename: "\\.sed$" - header: "^#!.*bin/(env +)?sed( |$)" + signature: "^#!.*bin/(env +)?sed( |$)" rules: - symbol.operator: "[|^$.*+]" diff --git a/runtime/syntax/sh.yaml b/runtime/syntax/sh.yaml index 49eb4e3fb4..c5c316eaaf 100644 --- a/runtime/syntax/sh.yaml +++ b/runtime/syntax/sh.yaml @@ -24,7 +24,7 @@ filetype: shell # * bash-fc. (followed by a random string) detect: filename: "(\\.(sh|bash|ash|ebuild)$|(\\.bash(rc|_aliases|_functions|_profile)|\\.?profile|Pkgfile|pkgmk\\.conf|rc\\.conf|PKGBUILD|APKBUILD)$|bash-fc\\.)" - header: "^#!.*/(env +)?(ba)?(a)?(mk)?sh( |$)" + signature: "^#!.*/(env +)?(ba)?(a)?(mk)?sh( |$)" rules: # Numbers diff --git a/runtime/syntax/syntax_converter.go b/runtime/syntax/syntax_converter.go index d2954e3aa7..f8af15dc6c 100644 --- a/runtime/syntax/syntax_converter.go +++ b/runtime/syntax/syntax_converter.go @@ -137,7 +137,7 @@ func generateFile(filetype, syntax, header string, rules []interface{}) string { output += fmt.Sprintf("detect: \n filename: \"%s\"\n", strings.Replace(strings.Replace(syntax, "\\", "\\\\", -1), "\"", "\\\"", -1)) if header != "" { - output += fmt.Sprintf(" header: \"%s\"\n", strings.Replace(strings.Replace(header, "\\", "\\\\", -1), "\"", "\\\"", -1)) + output += fmt.Sprintf(" signature: \"%s\"\n", strings.Replace(strings.Replace(header, "\\", "\\\\", -1), "\"", "\\\"", -1)) } output += "\nrules:\n" diff --git a/runtime/syntax/systemd.yaml b/runtime/syntax/systemd.yaml index a8650be4b2..9b66877624 100644 --- a/runtime/syntax/systemd.yaml +++ b/runtime/syntax/systemd.yaml @@ -2,7 +2,7 @@ filetype: systemd detect: filename: "\\.(service|socket|timer)$" - header: "^\\[Unit\\]$" + signature: "^\\[Unit\\]$" rules: - statement: "^(Accept|After|Alias|AllowIsolate|Also|ANSI_COLOR|_AUDIT_LOGINUID|_AUDIT_SESSION|Backlog|Before|BindIPv6Only|BindsTo|BindToDevice|BlockIOReadBandwidth|BlockIOWeight|BlockIOWriteBandwidth|_BOOT_ID|Broadcast|BUG_REPORT_URL|BusName|Capabilities|CapabilityBoundingSet|CHASSIS|cipher|class|_CMDLINE|CODE_FILE|CODE_FUNC|CODE_LINE|_COMM|Compress|ConditionACPower|ConditionCapability|ConditionDirectoryNotEmpty|ConditionFileIsExecutable|ConditionFileNotEmpty|ConditionHost|ConditionKernelCommandLine|ConditionNull|ConditionPathExists|ConditionPathExistsGlob|ConditionPathIsDirectory|ConditionPathIsMountPoint|ConditionPathIsReadWrite|ConditionPathIsSymbolicLink|ConditionSecurity|ConditionVirtualization|Conflicts|ControlGroup|ControlGroupAttribute|ControlGroupModify|ControlGroupPersistent|controllers|Controllers|CPE_NAME|CPUAffinity|CPUSchedulingPolicy|CPUSchedulingPriority|CPUSchedulingResetOnFork|CPUShares|CrashChVT|CrashShell|__CURSOR|debug|DefaultControllers|DefaultDependencies|DefaultLimitAS|DefaultLimitCORE|DefaultLimitCPU|DefaultLimitDATA|DefaultLimitFSIZE|DefaultLimitLOCKS|DefaultLimitMEMLOCK|DefaultLimitMSGQUEUE|DefaultLimitNICE|DefaultLimitNOFILE|DefaultLimitNPROC|DefaultLimitRSS|DefaultLimitRTPRIO|DefaultLimitRTTIME|DefaultLimitSIGPENDING|DefaultLimitSTACK|DefaultStandardError|DefaultStandardOutput|Description|DeviceAllow|DeviceDeny|DirectoryMode|DirectoryNotEmpty|Documentation|DumpCore|entropy|Environment|EnvironmentFile|ERRNO|event_timeout|_EXE|ExecReload|ExecStart|ExecStartPost|ExecStartPre|ExecStop|ExecStopPost|ExecStopPre|filter|FONT|FONT_MAP|FONT_UNIMAP|ForwardToConsole|ForwardToKMsg|ForwardToSyslog|FreeBind|freq|FsckPassNo|fstab|_GID|Group|GuessMainPID|HandleHibernateKey|HandleLidSwitch|HandlePowerKey|HandleSuspendKey|hash|HibernateKeyIgnoreInhibited|HOME_URL|_HOSTNAME|ICON_NAME|ID|IdleAction|IdleActionSec|ID_LIKE|ID_MODEL|ID_MODEL_FROM_DATABASE|IgnoreOnIsolate|IgnoreOnSnapshot|IgnoreSIGPIPE|InaccessibleDirectories|InhibitDelayMaxSec|init|IOSchedulingClass|IOSchedulingPriority|IPTOS|IPTTL|JobTimeoutSec|JoinControllers|KeepAlive|KEYMAP|KEYMAP_TOGGLE|KillExcludeUsers|KillMode|KillOnlyUsers|KillSignal|KillUserProcesses|LidSwitchIgnoreInhibited|LimitAS|LimitCORE|LimitCPU|LimitDATA|LimitFSIZE|LimitLOCKS|LimitMEMLOCK|LimitMSGQUEUE|LimitNICE|LimitNOFILE|LimitNPROC|LimitRSS|LimitRTPRIO|LimitRTTIME|LimitSIGPENDING|LimitSTACK|link_priority|valueListenDatagram|ListenFIFO|ListenMessageQueue|ListenNetlink|ListenSequentialPacket|ListenSpecial|ListenStream|LogColor|LogLevel|LogLocation|LogTarget|luks|_MACHINE_ID|MakeDirectory|Mark|MaxConnections|MaxFileSec|MaxLevelConsole|MaxLevelKMsg|MaxLevelStore|MaxLevelSyslog|MaxRetentionSec|MemoryLimit|MemorySoftLimit|MESSAGE|MESSAGE_ID|MessageQueueMaxMessages|MessageQueueMessageSize|__MONOTONIC_TIMESTAMP|MountFlags|NAME|NAutoVTs|Nice|NonBlocking|NoNewPrivileges|NotifyAccess|OnActiveSec|OnBootSec|OnCalendar|OnFailure|OnFailureIsolate|OnStartupSec|OnUnitActiveSec|OnUnitInactiveSec|OOMScoreAdjust|Options|output|PAMName|PartOf|PassCredentials|PassSecurity|PathChanged|PathExists|PathExistsGlob|PathModified|PermissionsStartOnly|_PID|PIDFile|PipeSize|PowerKeyIgnoreInhibited|PRETTY_HOSTNAME|PRETTY_NAME|Priority|PRIORITY|PrivateNetwork|PrivateTmp|PropagatesReloadTo|pss|RateLimitBurst|RateLimitInterval|ReadOnlyDirectories|ReadWriteDirectories|__REALTIME_TIMESTAMP|ReceiveBuffer|RefuseManualStart|RefuseManualStop|rel|ReloadPropagatedFrom|RemainAfterExit|RequiredBy|Requires|RequiresMountsFor|RequiresOverridable|Requisite|RequisiteOverridable|ReserveVT|ResetControllers|Restart|RestartPreventExitStatus|RestartSec|RootDirectory|RootDirectoryStartOnly|RuntimeKeepFree|RuntimeMaxFileSize|RuntimeMaxUse|RuntimeWatchdogSec|samples|scale_x|scale_y|Seal|SecureBits|_SELINUX_CONTEXT|SendBuffer|SendSIGKILL|Service|ShowStatus|ShutdownWatchdogSec|size|SmackLabel|SmackLabelIPIn|SmackLabelIPOut|SocketMode|Sockets|SourcePath|_SOURCE_REALTIME_TIMESTAMP|SplitMode|StandardError|StandardInput|StandardOutput|StartLimitAction|StartLimitBurst|StartLimitInterval|static_node|StopWhenUnneeded|Storage|string_escape|none|replaceSuccessExitStatus|SupplementaryGroups|SUPPORT_URL|SuspendKeyIgnoreInhibited|SyslogFacility|SYSLOG_FACILITY|SyslogIdentifier|SYSLOG_IDENTIFIER|SyslogLevel|SyslogLevelPrefix|SYSLOG_PID|SystemCallFilter|SYSTEMD_ALIAS|_SYSTEMD_CGROUP|_SYSTEMD_OWNER_UID|SYSTEMD_READY|_SYSTEMD_SESSION|_SYSTEMD_UNIT|_SYSTEMD_USER_UNIT|SYSTEMD_WANTS|SystemKeepFree|SystemMaxFileSize|SystemMaxUse|SysVStartPriority|TCPCongestion|TCPWrapName|timeout|TimeoutSec|TimeoutStartSec|TimeoutStopSec|TimerSlackNSec|Transparent|_TRANSPORT|tries|TTYPath|TTYReset|TTYVHangup|TTYVTDisallocate|Type|_UID|UMask|Unit|User|UtmpIdentifier|VERSION|VERSION_ID|WantedBy|Wants|WatchdogSec|What|Where|WorkingDirectory)=" diff --git a/runtime/syntax/tcl.yaml b/runtime/syntax/tcl.yaml index b87a7d7906..1b4ae7e5c9 100644 --- a/runtime/syntax/tcl.yaml +++ b/runtime/syntax/tcl.yaml @@ -2,7 +2,7 @@ filetype: tcl detect: filename: "\\.tcl$" - header: "^#!.*/(env +)?tclsh( |$)" + signature: "^#!.*/(env +)?tclsh( |$)" rules: - statement: "\\b(after|append|array|auto_execok|auto_import|auto_load|auto_load_index|auto_qualify|binary|break|case|catch|cd|clock|close|concat|continue|else|elseif|encoding|eof|error|eval|exec|exit|expr|fblocked|fconfigure|fcopy|file|fileevent|flush|for|foreach|format|gets|glob|global|history|if|incr|info|interp|join|lappend|lindex|linsert|list|llength|load|lrange|lreplace|lsearch|lset|lsort|namespace|open|package|pid|puts|pwd|read|regexp|regsub|rename|return|scan|seek|set|socket|source|split|string|subst|switch|tclLog|tell|time|trace|unknown|unset|update|uplevel|upvar|variable|vwait|while)\\b" diff --git a/runtime/syntax/xml.yaml b/runtime/syntax/xml.yaml index df4cde8118..0e9b901e85 100644 --- a/runtime/syntax/xml.yaml +++ b/runtime/syntax/xml.yaml @@ -2,7 +2,7 @@ filetype: xml detect: filename: "\\.(xml|sgml?|rng|svg|plist)$" - header: "<\\?xml.*\\?>" + signature: "<\\?xml.*\\?>" rules: - preproc: diff --git a/runtime/syntax/yaml.yaml b/runtime/syntax/yaml.yaml index 54d4a64725..c21286e4f6 100644 --- a/runtime/syntax/yaml.yaml +++ b/runtime/syntax/yaml.yaml @@ -2,7 +2,7 @@ filetype: yaml detect: filename: "\\.ya?ml$" - header: "%YAML" + signature: "%YAML" rules: - type: "(^| )!!(binary|bool|float|int|map|null|omap|seq|set|str) " diff --git a/runtime/syntax/zsh.yaml b/runtime/syntax/zsh.yaml index a283213104..3b7e059396 100644 --- a/runtime/syntax/zsh.yaml +++ b/runtime/syntax/zsh.yaml @@ -2,7 +2,7 @@ filetype: zsh detect: filename: "(\\.zsh$|\\.?(zshenv|zprofile|zshrc|zlogin|zlogout)$)" - header: "^#!.*/(env +)?zsh( |$)" + signature: "^#!.*/(env +)?zsh( |$)" rules: ## Numbers