feat(processor): add chroma dep, lexer resolution and drop rules
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
module github.com/carlosarraes/shush
|
||||
|
||||
go 1.24.4
|
||||
go 1.25
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.5.0
|
||||
github.com/alecthomas/chroma/v2 v2.27.0
|
||||
github.com/alecthomas/kong v1.12.0
|
||||
github.com/fatih/color v1.18.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/dlclark/regexp2/v2 v2.2.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
|
||||
@@ -2,10 +2,14 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/chroma/v2 v2.27.0 h1:FodwmyOBgJULFYmDqibcp9pvfDLWdtPRh9v/r5BXYZs=
|
||||
github.com/alecthomas/chroma/v2 v2.27.0/go.mod h1:NjJ3ciIgrqBNeIkWZ4e46nseoLDslxU1LmfCoL+wcY8=
|
||||
github.com/alecthomas/kong v1.12.0 h1:oKd/0fHSdajj5PfGDd3ScvEvpVJf9mT2mb5r9xYadYM=
|
||||
github.com/alecthomas/kong v1.12.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
|
||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
|
||||
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/dlclark/regexp2/v2 v2.2.1 h1:mf4KkFUj0gJuarK8P+LgiS+Lit7m9N1yAwEfPbee7R0=
|
||||
github.com/dlclark/regexp2/v2 v2.2.1/go.mod h1:avUrQvPaLz2DrFNHJF0taWAFFX2C1GMSSoeiqFjcBmU=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/chroma/v2"
|
||||
"github.com/alecthomas/chroma/v2/lexers"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
Inline bool
|
||||
Block bool
|
||||
PreserveLines bool
|
||||
InRange func(line int) bool
|
||||
}
|
||||
|
||||
type LineChange struct {
|
||||
Num int
|
||||
Original string
|
||||
Result string
|
||||
Action string
|
||||
}
|
||||
|
||||
func resolveLexer(filename string) chroma.Lexer {
|
||||
ext := strings.TrimPrefix(strings.ToLower(filepath.Ext(filename)), ".")
|
||||
var l chroma.Lexer
|
||||
if ext == "less" {
|
||||
l = lexers.Get("SCSS")
|
||||
} else {
|
||||
l = lexers.Match("f." + ext)
|
||||
}
|
||||
if l == nil {
|
||||
return nil
|
||||
}
|
||||
return chroma.Coalesce(l)
|
||||
}
|
||||
|
||||
func shouldDrop(tt chroma.TokenType, opts Options) bool {
|
||||
if tt == chroma.CommentPreproc || tt == chroma.CommentPreprocFile {
|
||||
return false
|
||||
}
|
||||
if opts.Inline {
|
||||
return tt == chroma.CommentSingle || tt == chroma.CommentHashbang || tt == chroma.CommentSpecial
|
||||
}
|
||||
if opts.Block {
|
||||
return tt == chroma.CommentMultiline
|
||||
}
|
||||
return tt.Category() == chroma.Comment
|
||||
}
|
||||
|
||||
func isCommentType(tt chroma.TokenType) bool {
|
||||
return tt.Category() == chroma.Comment && tt != chroma.CommentPreproc && tt != chroma.CommentPreprocFile
|
||||
}
|
||||
|
||||
func leadingWhitespace(s string) string {
|
||||
for i, r := range s {
|
||||
if r != ' ' && r != '\t' {
|
||||
return s[:i]
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/alecthomas/chroma/v2"
|
||||
)
|
||||
|
||||
func TestResolveLexer(t *testing.T) {
|
||||
cases := []struct {
|
||||
file string
|
||||
want string
|
||||
}{
|
||||
{"a.c", "C"},
|
||||
{"a.go", "Go"},
|
||||
{"a.js", "JavaScript"},
|
||||
{"a.rs", "Rust"},
|
||||
{"a.html", "HTML"},
|
||||
{"a.less", "SCSS"},
|
||||
{"a.conf", ""},
|
||||
}
|
||||
for _, c := range cases {
|
||||
l := resolveLexer(c.file)
|
||||
got := ""
|
||||
if l != nil {
|
||||
got = l.Config().Name
|
||||
}
|
||||
if got != c.want {
|
||||
t.Errorf("resolveLexer(%q) = %q, want %q", c.file, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldDrop(t *testing.T) {
|
||||
def := Options{}
|
||||
inline := Options{Inline: true}
|
||||
block := Options{Block: true}
|
||||
cases := []struct {
|
||||
tt chroma.TokenType
|
||||
opts Options
|
||||
want bool
|
||||
}{
|
||||
{chroma.CommentSingle, def, true},
|
||||
{chroma.CommentMultiline, def, true},
|
||||
{chroma.CommentPreproc, def, false},
|
||||
{chroma.CommentPreprocFile, def, false},
|
||||
{chroma.CommentSingle, inline, true},
|
||||
{chroma.CommentMultiline, inline, false},
|
||||
{chroma.CommentSingle, block, false},
|
||||
{chroma.CommentMultiline, block, true},
|
||||
{chroma.KeywordType, def, false},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if got := shouldDrop(c.tt, c.opts); got != c.want {
|
||||
t.Errorf("shouldDrop(%v, %+v) = %v, want %v", c.tt, c.opts, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user