diff --git a/internal/buffer/buffer.go b/internal/buffer/buffer.go index 8720aa47..ecdc90e1 100644 --- a/internal/buffer/buffer.go +++ b/internal/buffer/buffer.go @@ -693,15 +693,16 @@ func (b *Buffer) UpdateRules() { return } - // syntaxFileBuffer is a helper structure + // syntaxFileInfo is an internal helper structure // to store properties of one single syntax file - type syntaxFileBuffer struct { + type syntaxFileInfo struct { header *highlight.Header fileName string syntaxDef *highlight.Def } - syntaxFiles := []syntaxFileBuffer{} + fnameMatches := []syntaxFileInfo{} + headerMatches := []syntaxFileInfo{} syntaxFile := "" foundDef := false var header *highlight.Header @@ -718,26 +719,46 @@ func (b *Buffer) UpdateRules() { screen.TermMessage("Error parsing header for syntax file " + f.Name() + ": " + err.Error()) continue } - file, err := highlight.ParseFile(data) - if err != nil { - screen.TermMessage("Error parsing syntax file " + f.Name() + ": " + err.Error()) - continue + + matchedFileType := false + matchedFileName := false + matchedFileHeader := false + + if ft == "unknown" || ft == "" { + if header.MatchFileName(b.Path) { + matchedFileName = true + } + if len(fnameMatches) == 0 && header.MatchFileHeader(b.lines[0].data) { + matchedFileHeader = true + } + } else if header.FileType == ft { + matchedFileType = true } - if ((ft == "unknown" || ft == "") && header.MatchFileName(b.Path)) || header.FileType == ft { + if matchedFileType || matchedFileName || matchedFileHeader { + file, err := highlight.ParseFile(data) + if err != nil { + screen.TermMessage("Error parsing syntax file " + f.Name() + ": " + err.Error()) + continue + } + syndef, err := highlight.ParseDef(file, header) if err != nil { screen.TermMessage("Error parsing syntax file " + f.Name() + ": " + err.Error()) continue } - foundDef = true - if header.FileType == ft { + if matchedFileType { b.SyntaxDef = syndef syntaxFile = f.Name() + foundDef = true break - } else { - syntaxFiles = append(syntaxFiles, syntaxFileBuffer{header, f.Name(), syndef}) + } + + if matchedFileName { + fnameMatches = append(fnameMatches, syntaxFileInfo{header, f.Name(), syndef}) + } else if matchedFileHeader { + headerMatches = append(headerMatches, syntaxFileInfo{header, f.Name(), syndef}) } } } @@ -759,7 +780,10 @@ func (b *Buffer) UpdateRules() { if ft == "unknown" || ft == "" { if header.MatchFileName(b.Path) { - syntaxFiles = append(syntaxFiles, syntaxFileBuffer{header, f.Name(), nil}) + fnameMatches = append(fnameMatches, syntaxFileInfo{header, f.Name(), nil}) + } + if len(fnameMatches) == 0 && header.MatchFileHeader(b.lines[0].data) { + headerMatches = append(headerMatches, syntaxFileInfo{header, f.Name(), nil}) } } else if header.FileType == ft { syntaxFile = f.Name() @@ -769,33 +793,49 @@ func (b *Buffer) UpdateRules() { } if syntaxFile == "" { - length := len(syntaxFiles) + matches := fnameMatches + if len(matches) == 0 { + matches = headerMatches + } + + length := len(matches) if length > 0 { signatureMatch := false if length > 1 { + // multiple matching syntax files found, try to resolve the ambiguity + // using signatures detectlimit := util.IntOpt(b.Settings["detectlimit"]) lineCount := len(b.lines) limit := lineCount if detectlimit > 0 && lineCount > detectlimit { limit = detectlimit } - for i := 0; i < length && !signatureMatch; i++ { - if syntaxFiles[i].header.HasFileSignature() { - for j := 0; j < limit && !signatureMatch; j++ { - if syntaxFiles[i].header.MatchFileSignature(b.lines[j].data) { - syntaxFile = syntaxFiles[i].fileName - b.SyntaxDef = syntaxFiles[i].syntaxDef - header = syntaxFiles[i].header + + matchLoop: + for _, m := range matches { + if m.header.HasFileSignature() { + for i := 0; i < limit; i++ { + if m.header.MatchFileSignature(b.lines[i].data) { + syntaxFile = m.fileName + if m.syntaxDef != nil { + b.SyntaxDef = m.syntaxDef + foundDef = true + } + header = m.header signatureMatch = true + break matchLoop } } } } } if length == 1 || !signatureMatch { - syntaxFile = syntaxFiles[0].fileName - b.SyntaxDef = syntaxFiles[0].syntaxDef - header = syntaxFiles[0].header + syntaxFile = matches[0].fileName + if matches[0].syntaxDef != nil { + b.SyntaxDef = matches[0].syntaxDef + foundDef = true + } + header = matches[0].header } } } diff --git a/pkg/highlight/parser.go b/pkg/highlight/parser.go index 92e290fe..c7f57b69 100644 --- a/pkg/highlight/parser.go +++ b/pkg/highlight/parser.go @@ -39,6 +39,7 @@ type Def struct { type Header struct { FileType string FileNameRegex *regexp.Regexp + HeaderRegex *regexp.Regexp SignatureRegex *regexp.Regexp } @@ -46,6 +47,7 @@ type HeaderYaml struct { FileType string `yaml:"filetype"` Detect struct { FNameRegexStr string `yaml:"filename"` + HeaderRegexStr string `yaml:"header"` SignatureRegexStr string `yaml:"signature"` } `yaml:"detect"` } @@ -96,18 +98,22 @@ func init() { // A yaml file might take ~400us to parse while a header file only takes ~20us func MakeHeader(data []byte) (*Header, error) { lines := bytes.Split(data, []byte{'\n'}) - if len(lines) < 3 { + if len(lines) < 4 { return nil, errors.New("Header file has incorrect format") } header := new(Header) var err error header.FileType = string(lines[0]) fnameRegexStr := string(lines[1]) - signatureRegexStr := string(lines[2]) + headerRegexStr := string(lines[2]) + signatureRegexStr := string(lines[3]) if fnameRegexStr != "" { header.FileNameRegex, err = regexp.Compile(fnameRegexStr) } + if err == nil && headerRegexStr != "" { + header.HeaderRegex, err = regexp.Compile(headerRegexStr) + } if err == nil && signatureRegexStr != "" { header.SignatureRegex, err = regexp.Compile(signatureRegexStr) } @@ -134,6 +140,9 @@ func MakeHeaderYaml(data []byte) (*Header, error) { if hdrYaml.Detect.FNameRegexStr != "" { header.FileNameRegex, err = regexp.Compile(hdrYaml.Detect.FNameRegexStr) } + if err == nil && hdrYaml.Detect.HeaderRegexStr != "" { + header.HeaderRegex, err = regexp.Compile(hdrYaml.Detect.HeaderRegexStr) + } if err == nil && hdrYaml.Detect.SignatureRegexStr != "" { header.SignatureRegex, err = regexp.Compile(hdrYaml.Detect.SignatureRegexStr) } @@ -154,6 +163,14 @@ func (header *Header) MatchFileName(filename string) bool { return false } +func (header *Header) MatchFileHeader(firstLine []byte) bool { + if header.HeaderRegex != nil { + return header.HeaderRegex.Match(firstLine) + } + + return false +} + // HasFileSignature checks the presence of a stored signature func (header *Header) HasFileSignature() bool { return header.SignatureRegex != nil diff --git a/runtime/help/colors.md b/runtime/help/colors.md index 80a877d7..4e7d874f 100644 --- a/runtime/help/colors.md +++ b/runtime/help/colors.md @@ -271,13 +271,40 @@ detect: ``` Micro will match this regex against a given filename to detect the filetype. -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: + +In addition to the `filename` regex (or even instead of it) you can provide +a `header` regex that will check the first line of the line. For example: ``` detect: filename: "\\.ya?ml$" - signature: "%YAML" + header: "%YAML" +``` + +This is useful in cases when the given file name is not sufficient to determine +the filetype, e.g. with the above example, if a YAML file has no `.yaml` +extension but may contain a `%YAML` directive in its first line. + +`filename` takes precedence over `header`, i.e. if there is a syntax file that +matches the file with a filetype by the `filename` and another syntax file that +matches the same file with another filetype by the `header`, the first filetype +will be used. + +Finally, in addition to `filename` and/or `header` (but not instead of them) +you may also provide an optional `signature` regex which is useful for resolving +ambiguities when there are multiple syntax files matching the same file with +different filetypes. If a `signature` regex is given, micro will match a certain +amount of first lines in the file (this amount is determined by the `detectlimit` +option) against this regex, and if any of the lines match, this syntax file's +filetype will be preferred over other matching filetypes. + +For example, to distinguish C++ header files from C and Objective-C header files +that have the same `.h` extension: + +``` +detect: + filename: "\\.c(c|pp|xx)$|\\.h(h|pp|xx)?$" + signature: "namespace|template|public|protected|private" ``` ### Syntax rules diff --git a/runtime/syntax/PowerShell.yaml b/runtime/syntax/PowerShell.yaml index daaa2b21..a778199d 100644 --- a/runtime/syntax/PowerShell.yaml +++ b/runtime/syntax/PowerShell.yaml @@ -5,7 +5,6 @@ filetype: powershell detect: filename: "\\.ps(1|m1|d1)$" - #signature: "" rules: # - comment.block: # Block Comment diff --git a/runtime/syntax/README.md b/runtime/syntax/README.md index 4fa58647..3e2c5631 100644 --- a/runtime/syntax/README.md +++ b/runtime/syntax/README.md @@ -2,7 +2,8 @@ Here are micro's syntax files. -Each yaml file specifies how to detect the filetype based on file extension or given signature. The signature can be matched to all available lines of the file or to the value defined with the option `detectlimit` (to limit parse times) for a best "guess". +Each yaml file specifies how to detect the filetype based on file extension or header (first line of the line). +In addition, a signature can be provided to help resolving ambiguities when multiple matching filetypes are detected. 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 93ddf9ae..ff3f6988 100644 --- a/runtime/syntax/awk.yaml +++ b/runtime/syntax/awk.yaml @@ -2,7 +2,7 @@ filetype: awk detect: filename: "\\.awk$" - signature: "^#!.*bin/(env +)?awk( |$)" + header: "^#!.*bin/(env +)?awk( |$)" rules: - preproc: "\\$[A-Za-z0-9_!@#$*?\\-]+" diff --git a/runtime/syntax/bat.yaml b/runtime/syntax/bat.yaml index 741f7437..a719a6d4 100644 --- a/runtime/syntax/bat.yaml +++ b/runtime/syntax/bat.yaml @@ -2,7 +2,6 @@ filetype: batch detect: filename: "(\\.bat$|\\.cmd$)" - # signature: "" rules: # Numbers diff --git a/runtime/syntax/crontab.yaml b/runtime/syntax/crontab.yaml index a5ee3746..86566512 100644 --- a/runtime/syntax/crontab.yaml +++ b/runtime/syntax/crontab.yaml @@ -2,7 +2,7 @@ filetype: crontab detect: filename: "crontab$" - signature: "^#.*?/etc/crontab" + header: "^#.*?/etc/crontab" rules: # The time and date fields are: diff --git a/runtime/syntax/csx.yaml b/runtime/syntax/csx.yaml index 61c5d6ea..5ba6ea11 100644 --- a/runtime/syntax/csx.yaml +++ b/runtime/syntax/csx.yaml @@ -1,7 +1,7 @@ filetype: csharp-script detect: filename: "\\.csx$" - signature: "^#!.*/(env +)?dotnet-script( |$)" + header: "^#!.*/(env +)?dotnet-script( |$)" rules: - include: "csharp" diff --git a/runtime/syntax/fish.yaml b/runtime/syntax/fish.yaml index e5078097..88798a04 100644 --- a/runtime/syntax/fish.yaml +++ b/runtime/syntax/fish.yaml @@ -2,7 +2,7 @@ filetype: fish detect: filename: "\\.fish$" - signature: "^#!.*/(env +)?fish( |$)" + header: "^#!.*/(env +)?fish( |$)" rules: # Numbers diff --git a/runtime/syntax/godoc.yaml b/runtime/syntax/godoc.yaml index 3d926b68..383f3097 100644 --- a/runtime/syntax/godoc.yaml +++ b/runtime/syntax/godoc.yaml @@ -5,7 +5,7 @@ filetype: godoc detect: filename: "\\.godoc$" - signature: package.*import + header: package.*import rules: - preproc: "^[^ ].*" diff --git a/runtime/syntax/groovy.yaml b/runtime/syntax/groovy.yaml index a19cdcd3..3aa0e283 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$)" - signature: "^#!.*/(env +)?groovy *$" + header: "^#!.*/(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 a7cfae3f..c132d61e 100644 --- a/runtime/syntax/html4.yaml +++ b/runtime/syntax/html4.yaml @@ -2,7 +2,7 @@ filetype: html4 detect: filename: "\\.htm[l]?4$" - signature: "" + header: "" rules: - error: "<[^!].*?>" diff --git a/runtime/syntax/html5.yaml b/runtime/syntax/html5.yaml index 97bffde2..411d5385 100644 --- a/runtime/syntax/html5.yaml +++ b/runtime/syntax/html5.yaml @@ -2,7 +2,7 @@ filetype: html5 detect: filename: "\\.htm[l]?5$" - signature: "" + header: "" rules: - error: "<[^!].*?>" diff --git a/runtime/syntax/javascript.yaml b/runtime/syntax/javascript.yaml index 0b42caa6..b2bfe487 100644 --- a/runtime/syntax/javascript.yaml +++ b/runtime/syntax/javascript.yaml @@ -2,7 +2,7 @@ filetype: javascript detect: filename: "(\\.js$|\\.es[5678]?$|\\.mjs$)" - signature: "^#!.*/(env +)?node( |$)" + header: "^#!.*/(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 35705b1d..6d840833 100644 --- a/runtime/syntax/json.yaml +++ b/runtime/syntax/json.yaml @@ -2,7 +2,7 @@ filetype: json detect: filename: "\\.json$" - signature: "^\\{$" + header: "^\\{$" 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 8a46e5cf..c96ef0f3 100644 --- a/runtime/syntax/julia.yaml +++ b/runtime/syntax/julia.yaml @@ -2,7 +2,7 @@ filetype: julia detect: filename: "\\.jl$" - signature: "^#!.*/(env +)?julia( |$)" + header: "^#!.*/(env +)?julia( |$)" rules: diff --git a/runtime/syntax/justfile.yaml b/runtime/syntax/justfile.yaml index 2a856edb..926edb21 100644 --- a/runtime/syntax/justfile.yaml +++ b/runtime/syntax/justfile.yaml @@ -3,7 +3,7 @@ filetype: 'justfile' detect: filename: "(^\\.?[Jj]ustfile|\\.just)$" - signature: "^#!.*/(env +)?[bg]?just --justfile" + header: "^#!.*/(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 4cf588ce..6ffe8733 100644 --- a/runtime/syntax/mail.yaml +++ b/runtime/syntax/mail.yaml @@ -2,7 +2,7 @@ filetype: mail detect: filename: "(.*/mutt-.*|\\.eml)$" - signature: "^From .* \\d+:\\d+:\\d+ \\d+" + header: "^From .* \\d+:\\d+:\\d+ \\d+" rules: - type: "^From .*" diff --git a/runtime/syntax/make_headers.go b/runtime/syntax/make_headers.go index c80c680e..c00c27da 100644 --- a/runtime/syntax/make_headers.go +++ b/runtime/syntax/make_headers.go @@ -18,6 +18,7 @@ type HeaderYaml struct { FileType string `yaml:"filetype"` Detect struct { FNameRgx string `yaml:"filename"` + HeaderRgx string `yaml:"header"` SignatureRgx string `yaml:"signature"` } `yaml:"detect"` } @@ -25,6 +26,7 @@ type HeaderYaml struct { type Header struct { FileType string FNameRgx string + HeaderRgx string SignatureRgx string } @@ -59,6 +61,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() } @@ -70,7 +73,8 @@ func decode(name string) Header { var hdr Header hdr.FileType = string(strs[0]) hdr.FNameRgx = string(strs[1]) - hdr.SignatureRgx = string(strs[2]) + hdr.HeaderRgx = string(strs[2]) + hdr.SignatureRgx = string(strs[3]) fmt.Printf("took %v\n", time.Since(start)) return hdr diff --git a/runtime/syntax/makefile.yaml b/runtime/syntax/makefile.yaml index 670935fa..7e90cdeb 100644 --- a/runtime/syntax/makefile.yaml +++ b/runtime/syntax/makefile.yaml @@ -2,7 +2,7 @@ filetype: makefile detect: filename: "([Mm]akefile|\\.ma?k)$" - signature: "^#!.*/(env +)?[bg]?make( |$)" + header: "^#!.*/(env +)?[bg]?make( |$)" rules: - preproc: "\\<(ifeq|ifdef|ifneq|ifndef|else|endif)\\>" diff --git a/runtime/syntax/nginx.yaml b/runtime/syntax/nginx.yaml index 4a103ca3..02ea6eb0 100644 --- a/runtime/syntax/nginx.yaml +++ b/runtime/syntax/nginx.yaml @@ -2,7 +2,7 @@ filetype: nginx detect: filename: "nginx.*\\.conf$|\\.nginx$" - signature: "^(server|upstream)[a-z ]*\\{$" + header: "^(server|upstream)[a-z ]*\\{$" rules: - preproc: "\\b(events|server|http|location|upstream)[[:space:]]*\\{" diff --git a/runtime/syntax/patch.yaml b/runtime/syntax/patch.yaml index 6275d423..996bdc38 100644 --- a/runtime/syntax/patch.yaml +++ b/runtime/syntax/patch.yaml @@ -2,7 +2,7 @@ filetype: patch detect: filename: "\\.(patch|diff)$" - signature: "^diff" + header: "^diff" rules: - brightgreen: "^\\+.*" diff --git a/runtime/syntax/perl.yaml b/runtime/syntax/perl.yaml index d43c264f..2b01b894 100644 --- a/runtime/syntax/perl.yaml +++ b/runtime/syntax/perl.yaml @@ -2,7 +2,7 @@ filetype: perl detect: filename: "\\.p[lmp]$" - signature: "^#!.*/(env +)?perl( |$)" + header: "^#!.*/(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 42f7ffb4..3a993b05 100644 --- a/runtime/syntax/python2.yaml +++ b/runtime/syntax/python2.yaml @@ -2,7 +2,7 @@ filetype: python2 detect: filename: "\\.py2$" - signature: "^#!.*/(env +)?python2$" + header: "^#!.*/(env +)?python2$" rules: diff --git a/runtime/syntax/python3.yaml b/runtime/syntax/python3.yaml index 7e18df6e..5a060bff 100644 --- a/runtime/syntax/python3.yaml +++ b/runtime/syntax/python3.yaml @@ -2,7 +2,7 @@ filetype: python detect: filename: "\\.py(3)?$" - signature: "^#!.*/(env +)?python(3)?$" + header: "^#!.*/(env +)?python(3)?$" rules: # built-in objects diff --git a/runtime/syntax/ruby.yaml b/runtime/syntax/ruby.yaml index c84ada44..03dac2e5 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)$" - signature: "^#!.*/(env +)?ruby( |$)" + header: "^#!.*/(env +)?ruby( |$)" rules: - comment.bright: diff --git a/runtime/syntax/sage.yaml b/runtime/syntax/sage.yaml index 8d2cb07a..e24fbeb6 100644 --- a/runtime/syntax/sage.yaml +++ b/runtime/syntax/sage.yaml @@ -2,7 +2,7 @@ filetype: sage detect: filename: "\\.sage$" - signature: "^#!.*/(env +)?sage( |$)" + header: "^#!.*/(env +)?sage( |$)" rules: diff --git a/runtime/syntax/sed.yaml b/runtime/syntax/sed.yaml index a3bf1595..ed33bae5 100644 --- a/runtime/syntax/sed.yaml +++ b/runtime/syntax/sed.yaml @@ -2,7 +2,7 @@ filetype: sed detect: filename: "\\.sed$" - signature: "^#!.*bin/(env +)?sed( |$)" + header: "^#!.*bin/(env +)?sed( |$)" rules: - symbol.operator: "[|^$.*+]" diff --git a/runtime/syntax/sh.yaml b/runtime/syntax/sh.yaml index 3a0d9d45..3ace3268 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\\.)" - signature: "^#!.*/(env +)?(ba)?(a)?(mk)?sh( |$)" + header: "^#!.*/(env +)?(ba)?(a)?(mk)?sh( |$)" rules: # Numbers diff --git a/runtime/syntax/systemd.yaml b/runtime/syntax/systemd.yaml index 9b668776..a8650be4 100644 --- a/runtime/syntax/systemd.yaml +++ b/runtime/syntax/systemd.yaml @@ -2,7 +2,7 @@ filetype: systemd detect: filename: "\\.(service|socket|timer)$" - signature: "^\\[Unit\\]$" + header: "^\\[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 1b4ae7e5..b87a7d79 100644 --- a/runtime/syntax/tcl.yaml +++ b/runtime/syntax/tcl.yaml @@ -2,7 +2,7 @@ filetype: tcl detect: filename: "\\.tcl$" - signature: "^#!.*/(env +)?tclsh( |$)" + header: "^#!.*/(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 0e9b901e..df4cde81 100644 --- a/runtime/syntax/xml.yaml +++ b/runtime/syntax/xml.yaml @@ -2,7 +2,7 @@ filetype: xml detect: filename: "\\.(xml|sgml?|rng|svg|plist)$" - signature: "<\\?xml.*\\?>" + header: "<\\?xml.*\\?>" rules: - preproc: diff --git a/runtime/syntax/yaml.yaml b/runtime/syntax/yaml.yaml index c21286e4..54d4a647 100644 --- a/runtime/syntax/yaml.yaml +++ b/runtime/syntax/yaml.yaml @@ -2,7 +2,7 @@ filetype: yaml detect: filename: "\\.ya?ml$" - signature: "%YAML" + header: "%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 3b7e0593..a2832131 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)$)" - signature: "^#!.*/(env +)?zsh( |$)" + header: "^#!.*/(env +)?zsh( |$)" rules: ## Numbers