mirror of
https://github.com/zyedidia/micro.git
synced 2024-11-04 01:12:52 +03:00
Merge pull request #2819 from JoeKar/fix/file-detection
Improve file detection with signature check capabilities
This commit is contained in:
commit
e424537ff8
@ -692,6 +692,16 @@ func (b *Buffer) UpdateRules() {
|
||||
if ft == "off" {
|
||||
return
|
||||
}
|
||||
|
||||
// syntaxFileBuffer is a helper structure
|
||||
// to store properties of one single syntax file
|
||||
type syntaxFileBuffer struct {
|
||||
header *highlight.Header
|
||||
fileName string
|
||||
syntaxDef *highlight.Def
|
||||
}
|
||||
|
||||
syntaxFiles := []syntaxFileBuffer{}
|
||||
syntaxFile := ""
|
||||
foundDef := false
|
||||
var header *highlight.Header
|
||||
@ -714,41 +724,79 @@ 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 == "") && header.MatchFileName(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})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search in the default syntax files
|
||||
for _, f := range config.ListRuntimeFiles(config.RTSyntaxHeader) {
|
||||
data, err := f.Data()
|
||||
if err != nil {
|
||||
screen.TermMessage("Error loading syntax header file " + f.Name() + ": " + err.Error())
|
||||
continue
|
||||
}
|
||||
if !foundDef {
|
||||
// search in the default syntax files
|
||||
for _, f := range config.ListRuntimeFiles(config.RTSyntaxHeader) {
|
||||
data, err := f.Data()
|
||||
if err != nil {
|
||||
screen.TermMessage("Error loading syntax header file " + f.Name() + ": " + err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
header, err = highlight.MakeHeader(data)
|
||||
if err != nil {
|
||||
screen.TermMessage("Error reading syntax header file", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
header, err = highlight.MakeHeader(data)
|
||||
if err != nil {
|
||||
screen.TermMessage("Error reading syntax header file", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
if ft == "unknown" || ft == "" {
|
||||
if highlight.MatchFiletype(header.FtDetect, b.Path, b.lines[0].data) {
|
||||
if ft == "unknown" || ft == "" {
|
||||
if header.MatchFileName(b.Path) {
|
||||
syntaxFiles = append(syntaxFiles, syntaxFileBuffer{header, f.Name(), nil})
|
||||
}
|
||||
} else if header.FileType == ft {
|
||||
syntaxFile = f.Name()
|
||||
break
|
||||
}
|
||||
} else if header.FileType == ft {
|
||||
syntaxFile = f.Name()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if syntaxFile == "" {
|
||||
length := len(syntaxFiles)
|
||||
if length > 0 {
|
||||
signatureMatch := false
|
||||
if length > 1 {
|
||||
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
|
||||
signatureMatch = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if length == 1 || !signatureMatch {
|
||||
syntaxFile = syntaxFiles[0].fileName
|
||||
b.SyntaxDef = syntaxFiles[0].syntaxDef
|
||||
header = syntaxFiles[0].header
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ func init() {
|
||||
var optionValidators = map[string]optionValidator{
|
||||
"autosave": validateNonNegativeValue,
|
||||
"clipboard": validateClipboard,
|
||||
"detectlimit": validateNonNegativeValue,
|
||||
"tabsize": validatePositiveValue,
|
||||
"scrollmargin": validateNonNegativeValue,
|
||||
"scrollspeed": validateNonNegativeValue,
|
||||
@ -282,6 +283,7 @@ var defaultCommonSettings = map[string]interface{}{
|
||||
"basename": false,
|
||||
"colorcolumn": float64(0),
|
||||
"cursorline": true,
|
||||
"detectlimit": float64(100),
|
||||
"diffgutter": false,
|
||||
"encoding": "utf-8",
|
||||
"eofnewline": true,
|
||||
|
@ -1,18 +0,0 @@
|
||||
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
|
||||
}
|
||||
|
||||
if ftdetect[1] != nil {
|
||||
return ftdetect[1].Match(firstLine)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
@ -33,27 +33,26 @@ func (g Group) String() string {
|
||||
// Then it has the rules which define how to highlight the file
|
||||
type Def struct {
|
||||
*Header
|
||||
|
||||
rules *rules
|
||||
}
|
||||
|
||||
type Header struct {
|
||||
FileType string
|
||||
FtDetect [2]*regexp.Regexp
|
||||
FileType string
|
||||
FileNameRegex *regexp.Regexp
|
||||
SignatureRegex *regexp.Regexp
|
||||
}
|
||||
|
||||
type HeaderYaml struct {
|
||||
FileType string `yaml:"filetype"`
|
||||
Detect struct {
|
||||
FNameRgx string `yaml:"filename"`
|
||||
HeaderRgx string `yaml:"header"`
|
||||
FNameRegexStr string `yaml:"filename"`
|
||||
SignatureRegexStr string `yaml:"signature"`
|
||||
} `yaml:"detect"`
|
||||
}
|
||||
|
||||
type File struct {
|
||||
FileType string
|
||||
|
||||
yamlSrc map[interface{}]interface{}
|
||||
yamlSrc map[interface{}]interface{}
|
||||
}
|
||||
|
||||
// A Pattern is one simple syntax rule
|
||||
@ -103,14 +102,14 @@ func MakeHeader(data []byte) (*Header, error) {
|
||||
header := new(Header)
|
||||
var err error
|
||||
header.FileType = string(lines[0])
|
||||
fnameRgx := string(lines[1])
|
||||
headerRgx := string(lines[2])
|
||||
fnameRegexStr := string(lines[1])
|
||||
signatureRegexStr := string(lines[2])
|
||||
|
||||
if fnameRgx != "" {
|
||||
header.FtDetect[0], err = regexp.Compile(fnameRgx)
|
||||
if fnameRegexStr != "" {
|
||||
header.FileNameRegex, err = regexp.Compile(fnameRegexStr)
|
||||
}
|
||||
if err == nil && headerRgx != "" {
|
||||
header.FtDetect[1], err = regexp.Compile(headerRgx)
|
||||
if err == nil && signatureRegexStr != "" {
|
||||
header.SignatureRegex, err = regexp.Compile(signatureRegexStr)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@ -132,11 +131,11 @@ func MakeHeaderYaml(data []byte) (*Header, error) {
|
||||
header := new(Header)
|
||||
header.FileType = hdrYaml.FileType
|
||||
|
||||
if hdrYaml.Detect.FNameRgx != "" {
|
||||
header.FtDetect[0], err = regexp.Compile(hdrYaml.Detect.FNameRgx)
|
||||
if hdrYaml.Detect.FNameRegexStr != "" {
|
||||
header.FileNameRegex, err = regexp.Compile(hdrYaml.Detect.FNameRegexStr)
|
||||
}
|
||||
if err == nil && hdrYaml.Detect.HeaderRgx != "" {
|
||||
header.FtDetect[1], err = regexp.Compile(hdrYaml.Detect.HeaderRgx)
|
||||
if err == nil && hdrYaml.Detect.SignatureRegexStr != "" {
|
||||
header.SignatureRegex, err = regexp.Compile(hdrYaml.Detect.SignatureRegexStr)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@ -146,6 +145,29 @@ func MakeHeaderYaml(data []byte) (*Header, error) {
|
||||
return header, nil
|
||||
}
|
||||
|
||||
// MatchFileName will check the given file name with the stored regex
|
||||
func (header *Header) MatchFileName(filename string) bool {
|
||||
if header.FileNameRegex != nil {
|
||||
return header.FileNameRegex.MatchString(filename)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// HasFileSignature checks the presence of a stored signature
|
||||
func (header *Header) HasFileSignature() bool {
|
||||
return header.SignatureRegex != nil
|
||||
}
|
||||
|
||||
// MatchFileSignature will check the given line with the stored regex
|
||||
func (header *Header) MatchFileSignature(line []byte) bool {
|
||||
if header.SignatureRegex != nil {
|
||||
return header.SignatureRegex.Match(line)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func ParseFile(input []byte) (f *File, err error) {
|
||||
// This is just so if we have an error, we can exit cleanly and return the parse error to the user
|
||||
defer func() {
|
||||
|
@ -268,13 +268,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
|
||||
|
@ -100,6 +100,13 @@ Here are the available options:
|
||||
|
||||
default value: `true`
|
||||
|
||||
* `detectlimit`: if this is not set to 0, it will limit the amount of first
|
||||
lines in a file that are matched to determine the filetype.
|
||||
A higher limit means better accuracy of guessing the filetype, but also
|
||||
taking more time.
|
||||
|
||||
default value: `100`
|
||||
|
||||
* `diffgutter`: display diff indicators before lines.
|
||||
|
||||
default value: `false`
|
||||
|
@ -5,7 +5,7 @@ filetype: powershell
|
||||
|
||||
detect:
|
||||
filename: "\\.ps(1|m1|d1)$"
|
||||
#header: ""
|
||||
#signature: ""
|
||||
|
||||
rules:
|
||||
# - comment.block: # Block Comment
|
||||
|
@ -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 all available lines of the file or to the value defined with the option `detectlimit` (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
|
||||
|
@ -2,7 +2,7 @@ filetype: awk
|
||||
|
||||
detect:
|
||||
filename: "\\.awk$"
|
||||
header: "^#!.*bin/(env +)?awk( |$)"
|
||||
signature: "^#!.*bin/(env +)?awk( |$)"
|
||||
|
||||
rules:
|
||||
- preproc: "\\$[A-Za-z0-9_!@#$*?\\-]+"
|
||||
|
@ -2,7 +2,7 @@ filetype: batch
|
||||
|
||||
detect:
|
||||
filename: "(\\.bat$|\\.cmd$)"
|
||||
# header: ""
|
||||
# signature: ""
|
||||
|
||||
rules:
|
||||
# Numbers
|
||||
|
@ -1,7 +1,8 @@
|
||||
filetype: c++
|
||||
|
||||
detect:
|
||||
filename: "(\\.c(c|pp|xx)$|\\.h(h|pp|xx)$|\\.ii?$|\\.(def)$)"
|
||||
filename: "(\\.c(c|pp|xx)$|\\.h(h|pp|xx)?$|\\.ii?$|\\.(def)$)"
|
||||
signature: "namespace|template|public|protected|private"
|
||||
|
||||
rules:
|
||||
- identifier: "\\b[A-Z_][0-9A-Z_]*\\b"
|
||||
|
@ -2,7 +2,7 @@ filetype: crontab
|
||||
|
||||
detect:
|
||||
filename: "crontab$"
|
||||
header: "^#.*?/etc/crontab"
|
||||
signature: "^#.*?/etc/crontab"
|
||||
|
||||
rules:
|
||||
# The time and date fields are:
|
||||
|
@ -1,7 +1,7 @@
|
||||
filetype: csharp-script
|
||||
detect:
|
||||
filename: "\\.csx$"
|
||||
header: "^#!.*/(env +)?dotnet-script( |$)"
|
||||
signature: "^#!.*/(env +)?dotnet-script( |$)"
|
||||
|
||||
rules:
|
||||
- include: "csharp"
|
||||
|
@ -2,7 +2,7 @@ filetype: fish
|
||||
|
||||
detect:
|
||||
filename: "\\.fish$"
|
||||
header: "^#!.*/(env +)?fish( |$)"
|
||||
signature: "^#!.*/(env +)?fish( |$)"
|
||||
|
||||
rules:
|
||||
# Numbers
|
||||
|
@ -5,7 +5,7 @@ filetype: godoc
|
||||
|
||||
detect:
|
||||
filename: "\\.godoc$"
|
||||
header: package.*import
|
||||
signature: package.*import
|
||||
|
||||
rules:
|
||||
- preproc: "^[^ ].*"
|
||||
|
@ -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
|
||||
|
@ -2,7 +2,7 @@ filetype: html4
|
||||
|
||||
detect:
|
||||
filename: "\\.htm[l]?4$"
|
||||
header: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN|http://www.w3.org/TR/html4/strict.dtd\">"
|
||||
signature: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN|http://www.w3.org/TR/html4/strict.dtd\">"
|
||||
|
||||
rules:
|
||||
- error: "<[^!].*?>"
|
||||
|
@ -2,7 +2,7 @@ filetype: html5
|
||||
|
||||
detect:
|
||||
filename: "\\.htm[l]?5$"
|
||||
header: "<!DOCTYPE html5>"
|
||||
signature: "<!DOCTYPE html5>"
|
||||
|
||||
rules:
|
||||
- error: "<[^!].*?>"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -2,7 +2,7 @@ filetype: julia
|
||||
|
||||
detect:
|
||||
filename: "\\.jl$"
|
||||
header: "^#!.*/(env +)?julia( |$)"
|
||||
signature: "^#!.*/(env +)?julia( |$)"
|
||||
|
||||
rules:
|
||||
|
||||
|
@ -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)\\>"
|
||||
|
@ -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 .*"
|
||||
|
@ -1,4 +1,5 @@
|
||||
//+build ignore
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
@ -16,15 +17,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
|
||||
FileType string
|
||||
FNameRgx string
|
||||
SignatureRgx string
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -58,7 +59,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 +70,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
|
||||
|
@ -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)\\>"
|
||||
|
@ -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:]]*\\{"
|
||||
|
@ -2,6 +2,7 @@ filetype: objective-c
|
||||
|
||||
detect:
|
||||
filename: "\\.(m|mm|h)$"
|
||||
signature: "(obj|objective)-c|#import|@(encode|end|interface|implementation|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"
|
||||
|
@ -2,7 +2,7 @@ filetype: patch
|
||||
|
||||
detect:
|
||||
filename: "\\.(patch|diff)$"
|
||||
header: "^diff"
|
||||
signature: "^diff"
|
||||
|
||||
rules:
|
||||
- brightgreen: "^\\+.*"
|
||||
|
@ -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"
|
||||
|
@ -2,7 +2,7 @@ filetype: python2
|
||||
|
||||
detect:
|
||||
filename: "\\.py2$"
|
||||
header: "^#!.*/(env +)?python2$"
|
||||
signature: "^#!.*/(env +)?python2$"
|
||||
|
||||
rules:
|
||||
|
||||
|
@ -2,7 +2,7 @@ filetype: python
|
||||
|
||||
detect:
|
||||
filename: "\\.py(3)?$"
|
||||
header: "^#!.*/(env +)?python(3)?$"
|
||||
signature: "^#!.*/(env +)?python(3)?$"
|
||||
|
||||
rules:
|
||||
# built-in objects
|
||||
|
@ -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:
|
||||
|
@ -2,7 +2,7 @@ filetype: sage
|
||||
|
||||
detect:
|
||||
filename: "\\.sage$"
|
||||
header: "^#!.*/(env +)?sage( |$)"
|
||||
signature: "^#!.*/(env +)?sage( |$)"
|
||||
|
||||
rules:
|
||||
|
||||
|
@ -2,7 +2,7 @@ filetype: sed
|
||||
|
||||
detect:
|
||||
filename: "\\.sed$"
|
||||
header: "^#!.*bin/(env +)?sed( |$)"
|
||||
signature: "^#!.*bin/(env +)?sed( |$)"
|
||||
|
||||
rules:
|
||||
- symbol.operator: "[|^$.*+]"
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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)="
|
||||
|
@ -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"
|
||||
|
@ -2,7 +2,7 @@ filetype: xml
|
||||
|
||||
detect:
|
||||
filename: "\\.(xml|sgml?|rng|svg|plist)$"
|
||||
header: "<\\?xml.*\\?>"
|
||||
signature: "<\\?xml.*\\?>"
|
||||
|
||||
rules:
|
||||
- preproc:
|
||||
|
@ -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) "
|
||||
|
@ -2,7 +2,7 @@ filetype: zsh
|
||||
|
||||
detect:
|
||||
filename: "(\\.zsh$|\\.?(zshenv|zprofile|zshrc|zlogin|zlogout)$)"
|
||||
header: "^#!.*/(env +)?zsh( |$)"
|
||||
signature: "^#!.*/(env +)?zsh( |$)"
|
||||
|
||||
rules:
|
||||
## Numbers
|
||||
|
Loading…
Reference in New Issue
Block a user