mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-31 15:17:15 +09:00
Compare commits
19 Commits
hub-autore
...
buffer-uni
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59e8f3aa3e | ||
|
|
53bda0cfa7 | ||
|
|
f059541e0d | ||
|
|
d78fe81e21 | ||
|
|
25b9342fbe | ||
|
|
70bcf9f618 | ||
|
|
8848388411 | ||
|
|
dff8b33e9c | ||
|
|
8a2048e7f6 | ||
|
|
0174d7dba4 | ||
|
|
e1827480c9 | ||
|
|
d8584d1ddb | ||
|
|
f0cdc3cabb | ||
|
|
2ef4f83358 | ||
|
|
a9120ce270 | ||
|
|
190d9d0609 | ||
|
|
cf3fdb344a | ||
|
|
b91242124c | ||
|
|
5ffc19f159 |
2
.github/ISSUE_TEMPLATE
vendored
2
.github/ISSUE_TEMPLATE
vendored
@@ -2,7 +2,7 @@
|
||||
|
||||
## Specifications
|
||||
|
||||
You can use `micro -version` to get the commit hash.
|
||||
<!-- You can use `micro -version` to get the commit hash. -->
|
||||
|
||||
Commit hash:
|
||||
OS:
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,4 +15,5 @@ tools/build-version
|
||||
tools/build-date
|
||||
tools/info-plist
|
||||
tools/bindata
|
||||
tools/vscode-tests/
|
||||
*.hdr
|
||||
|
||||
18
Makefile
18
Makefile
@@ -8,14 +8,16 @@ DATE = $(shell GOOS=$(shell go env GOHOSTOS) GOARCH=$(shell go env GOHOSTARCH) \
|
||||
ADDITIONAL_GO_LINKER_FLAGS = $(shell GOOS=$(shell go env GOHOSTOS) \
|
||||
GOARCH=$(shell go env GOHOSTARCH))
|
||||
GOBIN ?= $(shell go env GOPATH)/bin
|
||||
GOVARS = -X github.com/zyedidia/micro/internal/util.Version=$(VERSION) -X github.com/zyedidia/micro/internal/util.CommitHash=$(HASH) -X 'github.com/zyedidia/micro/internal/util.CompileDate=$(DATE)' -X github.com/zyedidia/micro/internal/util.Debug=OFF
|
||||
GOVARS = -X github.com/zyedidia/micro/internal/util.Version=$(VERSION) -X github.com/zyedidia/micro/internal/util.CommitHash=$(HASH) -X 'github.com/zyedidia/micro/internal/util.CompileDate=$(DATE)'
|
||||
DEBUGVAR = -X github.com/zyedidia/micro/internal/util.Debug=ON
|
||||
VSCODE_TESTS_BASE_URL = 'https://raw.githubusercontent.com/microsoft/vscode/e6a45f4242ebddb7aa9a229f85555e8a3bd987e2/src/vs/editor/test/common/model/'
|
||||
|
||||
# Builds micro after checking dependencies but without updating the runtime
|
||||
build:
|
||||
go build -ldflags "-s -w $(GOVARS) $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro
|
||||
|
||||
build-dbg:
|
||||
go build -ldflags "-s -w $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro
|
||||
go build -ldflags "-s -w $(ADDITIONAL_GO_LINKER_FLAGS) $(DEBUGVAR)" ./cmd/micro
|
||||
|
||||
build-tags: fetch-tags
|
||||
go build -ldflags "-s -w $(GOVARS) $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro
|
||||
@@ -50,8 +52,20 @@ runtime:
|
||||
mv runtime.go internal/config
|
||||
gofmt -w internal/config/runtime.go
|
||||
|
||||
testgen:
|
||||
mkdir -p tools/vscode-tests
|
||||
cd tools/vscode-tests && \
|
||||
curl --remote-name-all $(VSCODE_TESTS_BASE_URL){editableTextModelAuto,editableTextModel,model.line}.test.ts
|
||||
tsc tools/vscode-tests/*.ts > /dev/null; true
|
||||
go run tools/testgen.go tools/vscode-tests/*.js > buffer_generated_test.go
|
||||
mv buffer_generated_test.go internal/buffer
|
||||
gofmt -w internal/buffer/buffer_generated_test.go
|
||||
|
||||
test:
|
||||
go test ./internal/...
|
||||
|
||||
bench:
|
||||
go test -bench=. ./internal/...
|
||||
|
||||
clean:
|
||||
rm -f micro
|
||||
|
||||
2
go.mod
2
go.mod
@@ -8,6 +8,7 @@ require (
|
||||
github.com/mattn/go-isatty v0.0.11
|
||||
github.com/mattn/go-runewidth v0.0.7
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff
|
||||
github.com/sergi/go-diff v1.1.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb
|
||||
@@ -19,6 +20,7 @@ require (
|
||||
github.com/zyedidia/tcell v1.4.4
|
||||
github.com/zyedidia/terminal v0.0.0-20180726154117-533c623e2415
|
||||
golang.org/x/text v0.3.2
|
||||
gopkg.in/sourcemap.v1 v1.0.5 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.7
|
||||
layeh.com/gopher-luar v1.0.7
|
||||
)
|
||||
|
||||
6
go.sum
6
go.sum
@@ -29,6 +29,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff h1:+6NUiITWwE5q1KO6SAfUX918c+Tab0+tGAM/mtdlUyA=
|
||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
@@ -50,8 +52,6 @@ github.com/zyedidia/poller v1.0.1 h1:Tt9S3AxAjXwWGNiC2TUdRJkQDZSzCBNVQ4xXiQ7440s
|
||||
github.com/zyedidia/poller v1.0.1/go.mod h1:vZXJOHGDcuK08GXhF6IAY0ZFd2WcgOR5DOTp84Uk5eE=
|
||||
github.com/zyedidia/pty v2.0.0+incompatible h1:Ou5vXL6tvjst+RV8sUFISbuKDnUJPhnpygApMFGweqw=
|
||||
github.com/zyedidia/pty v2.0.0+incompatible/go.mod h1:4y9l9yJZNxRa7GB/fB+mmDmGkG3CqmzLf4vUxGGotEA=
|
||||
github.com/zyedidia/tcell v1.4.3 h1:s0nmxj22Jj+vyt4nVmnB6kbnwRxEay1zfS0j8IsbtfI=
|
||||
github.com/zyedidia/tcell v1.4.3/go.mod h1:HhlbMSCcGX15rFDB+Q1Lk3pKEOocsCUAQC3zhZ9sadA=
|
||||
github.com/zyedidia/tcell v1.4.4 h1:o34LXujNuSueuyTy+5eoQW+rQr8g0UbY8k1NczZyskQ=
|
||||
github.com/zyedidia/tcell v1.4.4/go.mod h1:HhlbMSCcGX15rFDB+Q1Lk3pKEOocsCUAQC3zhZ9sadA=
|
||||
github.com/zyedidia/terminal v0.0.0-20180726154117-533c623e2415 h1:752dTQ5OatJ9M5ULK2+9lor+nzyZz+LYDo3WGngg3Rc=
|
||||
@@ -67,6 +67,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
|
||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
||||
|
||||
@@ -270,7 +270,11 @@ func (h *BufPane) SetID(i uint64) {
|
||||
}
|
||||
|
||||
func (h *BufPane) Name() string {
|
||||
return h.Buf.GetName()
|
||||
n := h.Buf.GetName()
|
||||
if h.Buf.Modified() {
|
||||
n += " +"
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// HandleEvent executes the tcell event properly
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"strings"
|
||||
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/display"
|
||||
"github.com/zyedidia/micro/internal/info"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
@@ -186,14 +187,17 @@ func (h *InfoPane) Autocomplete() {
|
||||
args := bytes.Split(l, []byte{' '})
|
||||
cmd := string(args[0])
|
||||
|
||||
if len(args) == 1 {
|
||||
b.Autocomplete(CommandComplete)
|
||||
} else {
|
||||
if action, ok := commands[cmd]; ok {
|
||||
if h.PromptType == "Command" {
|
||||
if len(args) == 1 {
|
||||
b.Autocomplete(CommandComplete)
|
||||
} else if action, ok := commands[cmd]; ok {
|
||||
if action.completer != nil {
|
||||
b.Autocomplete(action.completer)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// by default use filename autocompletion
|
||||
b.Autocomplete(buffer.FileComplete)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -75,6 +75,32 @@ type SharedBuffer struct {
|
||||
// Type of the buffer (e.g. help, raw, scratch etc..)
|
||||
Type BufType
|
||||
|
||||
// Path to the file on disk
|
||||
Path string
|
||||
// Absolute path to the file on disk
|
||||
AbsPath string
|
||||
// Name of the buffer on the status line
|
||||
name string
|
||||
|
||||
// Settings customized by the user
|
||||
Settings map[string]interface{}
|
||||
|
||||
Suggestions []string
|
||||
Completions []string
|
||||
CurSuggestion int
|
||||
|
||||
Messages []*Message
|
||||
|
||||
updateDiffTimer *time.Timer
|
||||
diffBase []byte
|
||||
diffBaseLineCount int
|
||||
diffLock sync.RWMutex
|
||||
diff map[int]DiffStatus
|
||||
|
||||
// counts the number of edits
|
||||
// resets every backupTime edits
|
||||
lastbackup time.Time
|
||||
|
||||
// ReloadDisabled allows the user to disable reloads if they
|
||||
// are viewing a file that is constantly changing
|
||||
ReloadDisabled bool
|
||||
@@ -84,8 +110,13 @@ type SharedBuffer struct {
|
||||
// it changes based on how the buffer has changed
|
||||
HasSuggestions bool
|
||||
|
||||
// Modifications is the list of modified regions for syntax highlighting
|
||||
Modifications []Loc
|
||||
// The Highlighter struct actually performs the highlighting
|
||||
Highlighter *highlight.Highlighter
|
||||
// SyntaxDef represents the syntax highlighting definition being used
|
||||
// This stores the highlighting rules and filetype detection info
|
||||
SyntaxDef *highlight.Def
|
||||
|
||||
ModifiedThisFrame bool
|
||||
|
||||
// Hash of the original buffer -- empty if fastdirty is on
|
||||
origHash [md5.Size]byte
|
||||
@@ -96,17 +127,35 @@ func (b *SharedBuffer) insert(pos Loc, value []byte) {
|
||||
b.HasSuggestions = false
|
||||
b.LineArray.insert(pos, value)
|
||||
|
||||
// b.Modifications is cleared every screen redraw so it's
|
||||
// ok to append duplicates
|
||||
b.Modifications = append(b.Modifications, Loc{pos.Y, pos.Y + bytes.Count(value, []byte{'\n'})})
|
||||
inslines := bytes.Count(value, []byte{'\n'})
|
||||
b.MarkModified(pos.Y, pos.Y+inslines)
|
||||
}
|
||||
func (b *SharedBuffer) remove(start, end Loc) []byte {
|
||||
b.isModified = true
|
||||
b.HasSuggestions = false
|
||||
b.Modifications = append(b.Modifications, Loc{start.Y, start.Y})
|
||||
defer b.MarkModified(start.Y, end.Y)
|
||||
return b.LineArray.remove(start, end)
|
||||
}
|
||||
|
||||
// MarkModified marks the buffer as modified for this frame
|
||||
// and performs rehighlighting if syntax highlighting is enabled
|
||||
func (b *SharedBuffer) MarkModified(start, end int) {
|
||||
b.ModifiedThisFrame = true
|
||||
|
||||
if !b.Settings["syntax"].(bool) || b.SyntaxDef == nil {
|
||||
return
|
||||
}
|
||||
|
||||
start = util.Clamp(start, 0, len(b.lines))
|
||||
end = util.Clamp(end, 0, len(b.lines))
|
||||
|
||||
l := -1
|
||||
for i := start; i <= end; i++ {
|
||||
l = util.Max(b.Highlighter.ReHighlightStates(b, i), l)
|
||||
}
|
||||
b.Highlighter.HighlightMatches(b, start, l+1)
|
||||
}
|
||||
|
||||
// DisableReload disables future reloads of this sharedbuffer
|
||||
func (b *SharedBuffer) DisableReload() {
|
||||
b.ReloadDisabled = true
|
||||
@@ -135,39 +184,6 @@ type Buffer struct {
|
||||
cursors []*Cursor
|
||||
curCursor int
|
||||
StartCursor Loc
|
||||
|
||||
// Path to the file on disk
|
||||
Path string
|
||||
// Absolute path to the file on disk
|
||||
AbsPath string
|
||||
// Name of the buffer on the status line
|
||||
name string
|
||||
|
||||
// SyntaxDef represents the syntax highlighting definition being used
|
||||
// This stores the highlighting rules and filetype detection info
|
||||
SyntaxDef *highlight.Def
|
||||
// The Highlighter struct actually performs the highlighting
|
||||
Highlighter *highlight.Highlighter
|
||||
HighlightLock sync.Mutex
|
||||
|
||||
// Settings customized by the user
|
||||
Settings map[string]interface{}
|
||||
|
||||
Suggestions []string
|
||||
Completions []string
|
||||
CurSuggestion int
|
||||
|
||||
Messages []*Message
|
||||
|
||||
updateDiffTimer *time.Timer
|
||||
diffBase []byte
|
||||
diffBaseLineCount int
|
||||
diffLock sync.RWMutex
|
||||
diff map[int]DiffStatus
|
||||
|
||||
// counts the number of edits
|
||||
// resets every backupTime edits
|
||||
lastbackup time.Time
|
||||
}
|
||||
|
||||
// NewBufferFromFile opens a new buffer using the given path
|
||||
@@ -222,23 +238,6 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT
|
||||
|
||||
b := new(Buffer)
|
||||
|
||||
b.Settings = config.DefaultCommonSettings()
|
||||
for k, v := range config.GlobalSettings {
|
||||
if _, ok := config.DefaultGlobalOnlySettings[k]; !ok {
|
||||
// make sure setting is not global-only
|
||||
b.Settings[k] = v
|
||||
}
|
||||
}
|
||||
config.InitLocalSettings(b.Settings, path)
|
||||
|
||||
enc, err := htmlindex.Get(b.Settings["encoding"].(string))
|
||||
if err != nil {
|
||||
enc = unicode.UTF8
|
||||
b.Settings["encoding"] = "utf-8"
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(transform.NewReader(r, enc.NewDecoder()))
|
||||
|
||||
found := false
|
||||
if len(path) > 0 {
|
||||
for _, buf := range OpenBuffers {
|
||||
@@ -250,28 +249,44 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT
|
||||
}
|
||||
}
|
||||
|
||||
b.Path = path
|
||||
b.AbsPath = absPath
|
||||
|
||||
if !found {
|
||||
b.SharedBuffer = new(SharedBuffer)
|
||||
b.Type = btype
|
||||
|
||||
b.AbsPath = absPath
|
||||
b.Path = path
|
||||
|
||||
b.Settings = config.DefaultCommonSettings()
|
||||
for k, v := range config.GlobalSettings {
|
||||
if _, ok := config.DefaultGlobalOnlySettings[k]; !ok {
|
||||
// make sure setting is not global-only
|
||||
b.Settings[k] = v
|
||||
}
|
||||
}
|
||||
config.InitLocalSettings(b.Settings, path)
|
||||
|
||||
enc, err := htmlindex.Get(b.Settings["encoding"].(string))
|
||||
if err != nil {
|
||||
enc = unicode.UTF8
|
||||
b.Settings["encoding"] = "utf-8"
|
||||
}
|
||||
|
||||
hasBackup := b.ApplyBackup(size)
|
||||
|
||||
if !hasBackup {
|
||||
reader := bufio.NewReader(transform.NewReader(r, enc.NewDecoder()))
|
||||
b.LineArray = NewLineArray(uint64(size), FFAuto, reader)
|
||||
}
|
||||
b.EventHandler = NewEventHandler(b.SharedBuffer, b.cursors)
|
||||
|
||||
// The last time this file was modified
|
||||
b.UpdateModTime()
|
||||
}
|
||||
|
||||
if b.Settings["readonly"].(bool) && b.Type == BTDefault {
|
||||
b.Type.Readonly = true
|
||||
}
|
||||
|
||||
// The last time this file was modified
|
||||
b.UpdateModTime()
|
||||
|
||||
switch b.Endings {
|
||||
case FFUnix:
|
||||
b.Settings["fileformat"] = "unix"
|
||||
@@ -280,6 +295,7 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT
|
||||
}
|
||||
|
||||
b.UpdateRules()
|
||||
// init local settings again now that we know the filetype
|
||||
config.InitLocalSettings(b.Settings, b.Path)
|
||||
|
||||
if _, err := os.Stat(filepath.Join(config.ConfigDir, "buffers")); os.IsNotExist(err) {
|
||||
@@ -300,7 +316,7 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT
|
||||
b.AddCursor(NewCursor(b, b.StartCursor))
|
||||
b.GetActiveCursor().Relocate()
|
||||
|
||||
if !b.Settings["fastdirty"].(bool) {
|
||||
if !b.Settings["fastdirty"].(bool) && !found {
|
||||
if size > LargeFileThreshold {
|
||||
// If the file is larger than LargeFileThreshold fastdirty needs to be on
|
||||
b.Settings["fastdirty"] = true
|
||||
@@ -309,13 +325,11 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT
|
||||
}
|
||||
}
|
||||
|
||||
err = config.RunPluginFn("onBufferOpen", luar.New(ulua.L, b))
|
||||
err := config.RunPluginFn("onBufferOpen", luar.New(ulua.L, b))
|
||||
if err != nil {
|
||||
screen.TermMessage(err)
|
||||
}
|
||||
|
||||
b.Modifications = make([]Loc, 0, 10)
|
||||
|
||||
OpenBuffers = append(OpenBuffers, b)
|
||||
|
||||
return b
|
||||
@@ -346,13 +360,17 @@ func (b *Buffer) Fini() {
|
||||
// GetName returns the name that should be displayed in the statusline
|
||||
// for this buffer
|
||||
func (b *Buffer) GetName() string {
|
||||
if b.name == "" {
|
||||
name := b.name
|
||||
if name == "" {
|
||||
if b.Path == "" {
|
||||
return "No name"
|
||||
}
|
||||
return b.Path
|
||||
name = b.Path
|
||||
}
|
||||
return b.name
|
||||
if b.Settings["basename"].(bool) {
|
||||
return path.Base(name)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
//SetName changes the name for this buffer
|
||||
@@ -382,16 +400,6 @@ func (b *Buffer) Remove(start, end Loc) {
|
||||
}
|
||||
}
|
||||
|
||||
// ClearModifications clears the list of modified lines in this buffer
|
||||
// The list of modified lines is used for syntax highlighting so that
|
||||
// we can selectively highlight only the necessary lines
|
||||
// This function should be called every time this buffer is drawn to
|
||||
// the screen
|
||||
func (b *Buffer) ClearModifications() {
|
||||
// clear slice without resetting the cap
|
||||
b.Modifications = b.Modifications[:0]
|
||||
}
|
||||
|
||||
// FileType returns the buffer's filetype
|
||||
func (b *Buffer) FileType() string {
|
||||
return b.Settings["filetype"].(string)
|
||||
@@ -558,7 +566,6 @@ func (b *Buffer) UpdateRules() {
|
||||
if syntaxFile == "" {
|
||||
// search for the syntax file in the user's custom syntax files
|
||||
for _, f := range config.ListRealRuntimeFiles(config.RTSyntax) {
|
||||
log.Println("real runtime file", f.Name())
|
||||
data, err := f.Data()
|
||||
if err != nil {
|
||||
screen.TermMessage("Error loading syntax file " + f.Name() + ": " + err.Error())
|
||||
@@ -776,7 +783,6 @@ func (b *Buffer) ClearCursors() {
|
||||
b.UpdateCursors()
|
||||
b.curCursor = 0
|
||||
b.GetActiveCursor().ResetSelection()
|
||||
log.Println("Cleared cursors:", len(b.cursors))
|
||||
}
|
||||
|
||||
// MoveLinesUp moves the range of lines up one row
|
||||
@@ -922,7 +928,7 @@ func (b *Buffer) Retab() {
|
||||
|
||||
l = bytes.TrimLeft(l, " \t")
|
||||
b.lines[i].data = append(ws, l...)
|
||||
b.Modifications = append(b.Modifications, Loc{i, i})
|
||||
b.MarkModified(i, i)
|
||||
dirty = true
|
||||
}
|
||||
|
||||
|
||||
1889
internal/buffer/buffer_generated_test.go
Normal file
1889
internal/buffer/buffer_generated_test.go
Normal file
File diff suppressed because it is too large
Load Diff
111
internal/buffer/buffer_test.go
Normal file
111
internal/buffer/buffer_test.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package buffer
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
testifyAssert "github.com/stretchr/testify/assert"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
)
|
||||
|
||||
type operation struct {
|
||||
start Loc
|
||||
end Loc
|
||||
text []string
|
||||
}
|
||||
|
||||
type asserter interface {
|
||||
Equal(interface{}, interface{}, ...interface{}) bool
|
||||
NotEqual(interface{}, interface{}, ...interface{}) bool
|
||||
}
|
||||
|
||||
type noOpAsserter struct {
|
||||
}
|
||||
|
||||
func (a *noOpAsserter) Equal(interface{}, interface{}, ...interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *noOpAsserter) NotEqual(interface{}, interface{}, ...interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
ulua.L = lua.NewState()
|
||||
}
|
||||
|
||||
func check(t *testing.T, before []string, operations []operation, after []string) {
|
||||
var assert asserter
|
||||
if t == nil {
|
||||
// Benchmark mode; don't perform assertions
|
||||
assert = &noOpAsserter{}
|
||||
} else {
|
||||
assert = testifyAssert.New(t)
|
||||
}
|
||||
|
||||
b := NewBufferFromString(strings.Join(before, "\n"), "", BTDefault)
|
||||
|
||||
assert.NotEqual("", b.GetName())
|
||||
assert.Equal(false, b.ExternallyModified())
|
||||
assert.Equal(false, b.Modified())
|
||||
assert.Equal(1, b.NumCursors())
|
||||
|
||||
checkText := func(lines []string) {
|
||||
assert.Equal([]byte(strings.Join(lines, "\n")), b.Bytes())
|
||||
assert.Equal(len(lines), b.LinesNum())
|
||||
for i, s := range lines {
|
||||
assert.Equal(s, b.Line(i))
|
||||
assert.Equal([]byte(s), b.LineBytes(i))
|
||||
}
|
||||
}
|
||||
|
||||
checkText(before)
|
||||
|
||||
var cursors []*Cursor
|
||||
|
||||
for _, op := range operations {
|
||||
cursor := NewCursor(b, op.start)
|
||||
cursor.SetSelectionStart(op.start)
|
||||
cursor.SetSelectionEnd(op.end)
|
||||
b.AddCursor(cursor)
|
||||
cursors = append(cursors, cursor)
|
||||
}
|
||||
|
||||
assert.Equal(1+len(operations), b.NumCursors())
|
||||
|
||||
for i, op := range operations {
|
||||
cursor := cursors[i]
|
||||
b.SetCurCursor(cursor.Num)
|
||||
cursor.DeleteSelection()
|
||||
cursor.ResetSelection()
|
||||
b.Insert(cursor.Loc, strings.Join(op.text, "\n"))
|
||||
}
|
||||
|
||||
checkText(after)
|
||||
|
||||
for b.UndoStack.Peek() != nil {
|
||||
b.UndoOneEvent()
|
||||
}
|
||||
|
||||
checkText(before)
|
||||
|
||||
for i, op := range operations {
|
||||
cursor := cursors[i]
|
||||
if !cursor.HasSelection() {
|
||||
assert.Equal(op.start, cursor.Loc)
|
||||
} else {
|
||||
assert.Equal(op.start, cursor.CurSelection[0])
|
||||
assert.Equal(op.end, cursor.CurSelection[1])
|
||||
}
|
||||
}
|
||||
|
||||
for b.RedoStack.Peek() != nil {
|
||||
b.RedoOneEvent()
|
||||
}
|
||||
|
||||
checkText(after)
|
||||
|
||||
b.Close()
|
||||
}
|
||||
@@ -41,6 +41,73 @@ type Delta struct {
|
||||
End Loc
|
||||
}
|
||||
|
||||
// DoTextEvent runs a text event
|
||||
func (eh *EventHandler) DoTextEvent(t *TextEvent, useUndo bool) {
|
||||
oldl := eh.buf.LinesNum()
|
||||
|
||||
if useUndo {
|
||||
eh.Execute(t)
|
||||
} else {
|
||||
ExecuteTextEvent(t, eh.buf)
|
||||
}
|
||||
|
||||
if len(t.Deltas) != 1 {
|
||||
return
|
||||
}
|
||||
|
||||
text := t.Deltas[0].Text
|
||||
start := t.Deltas[0].Start
|
||||
lastnl := -1
|
||||
var endX int
|
||||
var textX int
|
||||
if t.EventType == TextEventInsert {
|
||||
linecount := eh.buf.LinesNum() - oldl
|
||||
textcount := utf8.RuneCount(text)
|
||||
lastnl = bytes.LastIndex(text, []byte{'\n'})
|
||||
if lastnl >= 0 {
|
||||
endX = utf8.RuneCount(text[lastnl+1:])
|
||||
textX = endX
|
||||
} else {
|
||||
endX = start.X + textcount
|
||||
textX = textcount
|
||||
}
|
||||
t.Deltas[0].End = clamp(Loc{endX, start.Y + linecount}, eh.buf.LineArray)
|
||||
}
|
||||
end := t.Deltas[0].End
|
||||
|
||||
for _, c := range eh.cursors {
|
||||
move := func(loc Loc) Loc {
|
||||
if t.EventType == TextEventInsert {
|
||||
if start.Y != loc.Y && loc.GreaterThan(start) {
|
||||
loc.Y += end.Y - start.Y
|
||||
} else if loc.Y == start.Y && loc.GreaterEqual(start) {
|
||||
loc.Y += end.Y - start.Y
|
||||
if lastnl >= 0 {
|
||||
loc.X += textX - start.X
|
||||
} else {
|
||||
loc.X += textX
|
||||
}
|
||||
}
|
||||
return loc
|
||||
} else {
|
||||
if loc.Y != end.Y && loc.GreaterThan(end) {
|
||||
loc.Y -= end.Y - start.Y
|
||||
} else if loc.Y == end.Y && loc.GreaterEqual(end) {
|
||||
loc = loc.MoveLA(-DiffLA(start, end, eh.buf.LineArray), eh.buf.LineArray)
|
||||
}
|
||||
return loc
|
||||
}
|
||||
}
|
||||
c.Loc = move(c.Loc)
|
||||
c.CurSelection[0] = move(c.CurSelection[0])
|
||||
c.CurSelection[1] = move(c.CurSelection[1])
|
||||
c.OrigSelection[0] = move(c.OrigSelection[0])
|
||||
c.OrigSelection[1] = move(c.OrigSelection[1])
|
||||
c.Relocate()
|
||||
c.LastVisualX = c.GetVisualX()
|
||||
}
|
||||
}
|
||||
|
||||
// ExecuteTextEvent runs a text event
|
||||
func ExecuteTextEvent(t *TextEvent, buf *SharedBuffer) {
|
||||
if t.EventType == TextEventInsert {
|
||||
@@ -65,9 +132,9 @@ func ExecuteTextEvent(t *TextEvent, buf *SharedBuffer) {
|
||||
}
|
||||
|
||||
// UndoTextEvent undoes a text event
|
||||
func UndoTextEvent(t *TextEvent, buf *SharedBuffer) {
|
||||
func (eh *EventHandler) UndoTextEvent(t *TextEvent) {
|
||||
t.EventType = -t.EventType
|
||||
ExecuteTextEvent(t, buf)
|
||||
eh.DoTextEvent(t, false)
|
||||
}
|
||||
|
||||
// EventHandler executes text manipulations and allows undoing and redoing
|
||||
@@ -117,6 +184,9 @@ func (eh *EventHandler) Insert(start Loc, textStr string) {
|
||||
|
||||
// InsertBytes creates an insert text event and executes it
|
||||
func (eh *EventHandler) InsertBytes(start Loc, text []byte) {
|
||||
if len(text) == 0 {
|
||||
return
|
||||
}
|
||||
start = clamp(start, eh.buf.LineArray)
|
||||
e := &TextEvent{
|
||||
C: *eh.cursors[eh.active],
|
||||
@@ -124,50 +194,14 @@ func (eh *EventHandler) InsertBytes(start Loc, text []byte) {
|
||||
Deltas: []Delta{{text, start, Loc{0, 0}}},
|
||||
Time: time.Now(),
|
||||
}
|
||||
oldl := eh.buf.LinesNum()
|
||||
eh.Execute(e)
|
||||
linecount := eh.buf.LinesNum() - oldl
|
||||
textcount := utf8.RuneCount(text)
|
||||
lastnl := bytes.LastIndex(text, []byte{'\n'})
|
||||
var endX int
|
||||
var textX int
|
||||
if lastnl >= 0 {
|
||||
endX = utf8.RuneCount(text[lastnl+1:])
|
||||
textX = endX
|
||||
} else {
|
||||
endX = start.X + textcount
|
||||
textX = textcount
|
||||
}
|
||||
|
||||
e.Deltas[0].End = clamp(Loc{endX, start.Y + linecount}, eh.buf.LineArray)
|
||||
end := e.Deltas[0].End
|
||||
|
||||
for _, c := range eh.cursors {
|
||||
move := func(loc Loc) Loc {
|
||||
if start.Y != end.Y && loc.GreaterThan(start) {
|
||||
loc.Y += end.Y - start.Y
|
||||
} else if loc.Y == start.Y && loc.GreaterEqual(start) {
|
||||
loc.Y += end.Y - start.Y
|
||||
if lastnl >= 0 {
|
||||
loc.X = textX
|
||||
} else {
|
||||
loc.X += textX
|
||||
}
|
||||
}
|
||||
return loc
|
||||
}
|
||||
c.Loc = move(c.Loc)
|
||||
c.Relocate()
|
||||
c.CurSelection[0] = move(c.CurSelection[0])
|
||||
c.CurSelection[1] = move(c.CurSelection[1])
|
||||
c.OrigSelection[0] = move(c.OrigSelection[0])
|
||||
c.OrigSelection[1] = move(c.OrigSelection[1])
|
||||
c.LastVisualX = c.GetVisualX()
|
||||
}
|
||||
eh.DoTextEvent(e, true)
|
||||
}
|
||||
|
||||
// Remove creates a remove text event and executes it
|
||||
func (eh *EventHandler) Remove(start, end Loc) {
|
||||
if start == end {
|
||||
return
|
||||
}
|
||||
start = clamp(start, eh.buf.LineArray)
|
||||
end = clamp(end, eh.buf.LineArray)
|
||||
e := &TextEvent{
|
||||
@@ -176,24 +210,7 @@ func (eh *EventHandler) Remove(start, end Loc) {
|
||||
Deltas: []Delta{{[]byte{}, start, end}},
|
||||
Time: time.Now(),
|
||||
}
|
||||
eh.Execute(e)
|
||||
|
||||
for _, c := range eh.cursors {
|
||||
move := func(loc Loc) Loc {
|
||||
if start.Y != end.Y && loc.GreaterThan(end) {
|
||||
loc.Y -= end.Y - start.Y
|
||||
} else if loc.Y == end.Y && loc.GreaterEqual(end) {
|
||||
loc = loc.MoveLA(-DiffLA(start, end, eh.buf.LineArray), eh.buf.LineArray)
|
||||
}
|
||||
return loc
|
||||
}
|
||||
c.Loc = move(c.Loc)
|
||||
c.CurSelection[0] = move(c.CurSelection[0])
|
||||
c.CurSelection[1] = move(c.CurSelection[1])
|
||||
c.OrigSelection[0] = move(c.OrigSelection[0])
|
||||
c.OrigSelection[1] = move(c.OrigSelection[1])
|
||||
c.LastVisualX = c.GetVisualX()
|
||||
}
|
||||
eh.DoTextEvent(e, true)
|
||||
}
|
||||
|
||||
// MultipleReplace creates an multiple insertions executes them
|
||||
@@ -253,6 +270,7 @@ func (eh *EventHandler) Undo() {
|
||||
}
|
||||
|
||||
eh.UndoOneEvent()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,10 +282,9 @@ func (eh *EventHandler) UndoOneEvent() {
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Undo it
|
||||
// Modifies the text event
|
||||
UndoTextEvent(t, eh.buf)
|
||||
eh.UndoTextEvent(t)
|
||||
|
||||
// Set the cursor in the right place
|
||||
teCursor := t.C
|
||||
@@ -303,6 +320,7 @@ func (eh *EventHandler) Redo() {
|
||||
}
|
||||
|
||||
eh.RedoOneEvent()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,9 +331,6 @@ func (eh *EventHandler) RedoOneEvent() {
|
||||
return
|
||||
}
|
||||
|
||||
// Modifies the text event
|
||||
UndoTextEvent(t, eh.buf)
|
||||
|
||||
teCursor := t.C
|
||||
if teCursor.Num >= 0 && teCursor.Num < len(eh.cursors) {
|
||||
t.C = *eh.cursors[teCursor.Num]
|
||||
@@ -324,5 +339,8 @@ func (eh *EventHandler) RedoOneEvent() {
|
||||
teCursor.Num = -1
|
||||
}
|
||||
|
||||
// Modifies the text event
|
||||
eh.UndoTextEvent(t)
|
||||
|
||||
eh.UndoStack.Push(t)
|
||||
}
|
||||
|
||||
@@ -111,8 +111,8 @@ func (b *Buffer) saveToFile(filename string, withSudo bool) error {
|
||||
|
||||
if b.Settings["eofnewline"].(bool) {
|
||||
end := b.End()
|
||||
if b.RuneAt(Loc{end.X - 1, end.Y}) != '\n' {
|
||||
b.Insert(end, "\n")
|
||||
if b.RuneAt(Loc{end.X, end.Y}) != '\n' {
|
||||
b.insert(end, []byte{'\n'})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -191,7 +191,7 @@ var defaultCommonSettings = map[string]interface{}{
|
||||
"cursorline": true,
|
||||
"diffgutter": false,
|
||||
"encoding": "utf-8",
|
||||
"eofnewline": false,
|
||||
"eofnewline": true,
|
||||
"fastdirty": false,
|
||||
"fileformat": "unix",
|
||||
"filetype": "unknown",
|
||||
|
||||
@@ -397,21 +397,7 @@ func (w *BufWindow) displayBuffer() {
|
||||
bufWidth--
|
||||
}
|
||||
|
||||
if len(b.Modifications) > 0 {
|
||||
if b.Settings["syntax"].(bool) && b.SyntaxDef != nil {
|
||||
for _, r := range b.Modifications {
|
||||
rx := util.Clamp(r.X, 0, b.LinesNum())
|
||||
ry := util.Clamp(r.Y, 0, b.LinesNum())
|
||||
final := -1
|
||||
for i := rx; i <= ry; i++ {
|
||||
final = util.Max(b.Highlighter.ReHighlightStates(b, i), final)
|
||||
}
|
||||
b.Highlighter.HighlightMatches(b, rx, final+1)
|
||||
}
|
||||
}
|
||||
|
||||
b.ClearModifications()
|
||||
|
||||
if b.ModifiedThisFrame {
|
||||
if b.Settings["diffgutter"].(bool) {
|
||||
b.UpdateDiff(func(synchronous bool) {
|
||||
// If the diff was updated asynchronously, the outer call to
|
||||
@@ -426,6 +412,7 @@ func (w *BufWindow) displayBuffer() {
|
||||
}
|
||||
})
|
||||
}
|
||||
b.ModifiedThisFrame = false
|
||||
}
|
||||
|
||||
var matchingBraces []buffer.Loc
|
||||
|
||||
@@ -3,7 +3,6 @@ package display
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -32,9 +31,6 @@ type StatusLine struct {
|
||||
|
||||
var statusInfo = map[string]func(*buffer.Buffer) string{
|
||||
"filename": func(b *buffer.Buffer) string {
|
||||
if b.Settings["basename"].(bool) {
|
||||
return path.Base(b.GetName())
|
||||
}
|
||||
return b.GetName()
|
||||
},
|
||||
"line": func(b *buffer.Buffer) string {
|
||||
|
||||
@@ -96,6 +96,11 @@ func (w *TabWindow) Display() {
|
||||
x := -w.hscroll
|
||||
done := false
|
||||
|
||||
tabBarStyle := config.DefStyle.Reverse(true)
|
||||
if style, ok := config.Colorscheme["tabbar"]; ok {
|
||||
tabBarStyle = style
|
||||
}
|
||||
|
||||
draw := func(r rune, n int) {
|
||||
for i := 0; i < n; i++ {
|
||||
rw := runewidth.RuneWidth(r)
|
||||
@@ -105,13 +110,13 @@ func (w *TabWindow) Display() {
|
||||
c = ' '
|
||||
}
|
||||
if x == w.Width-1 && !done {
|
||||
screen.SetContent(w.Width-1, w.Y, '>', nil, config.DefStyle.Reverse(true))
|
||||
screen.SetContent(w.Width-1, w.Y, '>', nil, tabBarStyle)
|
||||
x++
|
||||
break
|
||||
} else if x == 0 && w.hscroll > 0 {
|
||||
screen.SetContent(0, w.Y, '<', nil, config.DefStyle.Reverse(true))
|
||||
screen.SetContent(0, w.Y, '<', nil, tabBarStyle)
|
||||
} else if x >= 0 && x < w.Width {
|
||||
screen.SetContent(x, w.Y, c, nil, config.DefStyle.Reverse(true))
|
||||
screen.SetContent(x, w.Y, c, nil, tabBarStyle)
|
||||
}
|
||||
x++
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ var (
|
||||
// CompileDate is the date this binary was compiled on
|
||||
CompileDate = "Unknown"
|
||||
// Debug logging
|
||||
Debug = "ON"
|
||||
Debug = "OFF"
|
||||
// FakeCursor is used to disable the terminal cursor and have micro
|
||||
// draw its own (enabled for windows consoles where the cursor is slow)
|
||||
FakeCursor = false
|
||||
|
||||
@@ -44,8 +44,8 @@ Here are the available options:
|
||||
|
||||
default value: `true`
|
||||
|
||||
* `basename`: in the infobar, show only the basename of the file being edited
|
||||
rather than the full path.
|
||||
* `basename`: in the infobar and tabbar, show only the basename of the file
|
||||
being edited rather than the full path.
|
||||
|
||||
default value: `false`
|
||||
|
||||
@@ -85,9 +85,10 @@ Here are the available options:
|
||||
|
||||
default value: `utf-8`
|
||||
|
||||
* `eofnewline`: micro will automatically add a newline to the file.
|
||||
* `eofnewline`: micro will automatically add a newline to the end of the
|
||||
file if one does not exist.
|
||||
|
||||
default value: `false`
|
||||
default value: `true`
|
||||
|
||||
* `fastdirty`: this determines what kind of algorithm micro uses to determine
|
||||
if a buffer is modified or not. When `fastdirty` is on, micro just uses a
|
||||
|
||||
@@ -6,6 +6,8 @@ local filepath = import("path/filepath")
|
||||
local shell = import("micro/shell")
|
||||
local buffer = import("micro/buffer")
|
||||
local config = import("micro/config")
|
||||
local util = import("micro/util")
|
||||
local os = import("os")
|
||||
|
||||
local linters = {}
|
||||
|
||||
@@ -66,7 +68,7 @@ function init()
|
||||
makeLinter("gcc", "c", "gcc", {"-fsyntax-only", "-Wall", "-Wextra", "%f"}, "%f:%l:%c:.+: %m")
|
||||
makeLinter("gcc", "c++", "gcc", {"-fsyntax-only","-std=c++14", "-Wall", "-Wextra", "%f"}, "%f:%l:%c:.+: %m")
|
||||
makeLinter("dmd", "d", "dmd", {"-color=off", "-o-", "-w", "-wi", "-c", "%f"}, "%f%(%l%):.+: %m")
|
||||
makeLinter("gobuild", "go", "go", {"build", "-o", devnull}, "%f:%l:%c:? %m")
|
||||
makeLinter("gobuild", "go", "go", {"build", "-o", devnull, "%d"}, "%f:%l:%c:? %m")
|
||||
-- makeLinter("golint", "go", "golint", {"%f"}, "%f:%l:%c: %m")
|
||||
makeLinter("javac", "java", "javac", {"-d", "%d", "%f"}, "%f:%l: error: %m")
|
||||
makeLinter("jshint", "javascript", "jshint", {"%f"}, "%f: line %l,.+, %m")
|
||||
@@ -102,7 +104,7 @@ end
|
||||
function runLinter(buf)
|
||||
local ft = buf:FileType()
|
||||
local file = buf.Path
|
||||
local dir = filepath.Dir(file)
|
||||
local dir = "." .. util.RuneStr(os.PathSeparator) .. filepath.Dir(file)
|
||||
|
||||
for k, v in pairs(linters) do
|
||||
local ftmatch = ft == v.filetype
|
||||
|
||||
@@ -53,7 +53,7 @@ func main() {
|
||||
}
|
||||
|
||||
// If we don't have any tag assume "dev"
|
||||
if tag == "" {
|
||||
if tag == "" || strings.HasPrefix(tag, "nightly") {
|
||||
tag = "dev"
|
||||
}
|
||||
// Get the most likely next version:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This script creates the nightly release on Github for micro
|
||||
# Must be run from inside the micro git repository
|
||||
# You must have the correct Github access token to run this script
|
||||
|
||||
commitID=$(git rev-parse HEAD)
|
||||
info=$(github-release info -u zyedidia -r micro -t nightly)
|
||||
@@ -10,32 +10,152 @@ if [[ $info = *$commitID* ]]; then
|
||||
fi
|
||||
|
||||
echo "Deleting old release"
|
||||
hub release delete nightly
|
||||
github-release delete \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly
|
||||
|
||||
echo "Moving tag"
|
||||
hub push origin :refs/tags/nightly
|
||||
git tag -f nightly $commitID
|
||||
hub push --tags
|
||||
git tag --force nightly $commitID
|
||||
git push --force --tags
|
||||
|
||||
echo "Creating new release"
|
||||
github-release release \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "Nightly build" \
|
||||
--description "Autogenerated nightly build of micro. If you don't see anything here that probably means it's building right now!" \
|
||||
--pre-release
|
||||
|
||||
echo "Cross compiling binaries"
|
||||
./cross-compile.sh $1
|
||||
mv ../binaries .
|
||||
|
||||
echo "Creating new release"
|
||||
hub release create nightly \
|
||||
--prerelease \
|
||||
--message $'Nightly build\n\nAutogenerated nightly build of micro.' \
|
||||
--attach "binaries/micro-$1-osx.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux64.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux64-static.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux32.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux-arm.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux-arm64.tar.gz" \
|
||||
--attach "binaries/micro-$1-freebsd64.tar.gz" \
|
||||
--attach "binaries/micro-$1-freebsd32.tar.gz" \
|
||||
--attach "binaries/micro-$1-openbsd64.tar.gz" \
|
||||
--attach "binaries/micro-$1-openbsd32.tar.gz" \
|
||||
--attach "binaries/micro-$1-netbsd64.tar.gz" \
|
||||
--attach "binaries/micro-$1-netbsd32.tar.gz" \
|
||||
--attach "binaries/micro-$1-win64.zip" \
|
||||
--attach "binaries/micro-$1-win32.zip"
|
||||
echo "Uploading OSX binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-osx.tar.gz" \
|
||||
--file binaries/micro-$1-osx.tar.gz
|
||||
|
||||
echo "Uploading Linux 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-linux64.tar.gz" \
|
||||
--file binaries/micro-$1-linux64.tar.gz
|
||||
|
||||
echo "Uploading Linux 64 static binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-linux64-static.tar.gz" \
|
||||
--file binaries/micro-$1-linux64-static.tar.gz
|
||||
|
||||
echo "Uploading Linux 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-linux32.tar.gz" \
|
||||
--file binaries/micro-$1-linux32.tar.gz
|
||||
|
||||
echo "Uploading Linux Arm 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-linux-arm.tar.gz" \
|
||||
--file binaries/micro-$1-linux-arm.tar.gz
|
||||
|
||||
echo "Uploading Linux Arm 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-linux-arm64.tar.gz" \
|
||||
--file binaries/micro-$1-linux-arm64.tar.gz
|
||||
|
||||
echo "Uploading FreeBSD 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-freebsd64.tar.gz" \
|
||||
--file binaries/micro-$1-freebsd64.tar.gz
|
||||
|
||||
echo "Uploading FreeBSD 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-freebsd32.tar.gz" \
|
||||
--file binaries/micro-$1-freebsd32.tar.gz
|
||||
|
||||
echo "Uploading OpenBSD 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-openbsd64.tar.gz" \
|
||||
--file binaries/micro-$1-openbsd64.tar.gz
|
||||
|
||||
echo "Uploading OpenBSD 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-openbsd32.tar.gz" \
|
||||
--file binaries/micro-$1-openbsd32.tar.gz
|
||||
|
||||
echo "Uploading NetBSD 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-netbsd64.tar.gz" \
|
||||
--file binaries/micro-$1-netbsd64.tar.gz
|
||||
|
||||
echo "Uploading NetBSD 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-netbsd32.tar.gz" \
|
||||
--file binaries/micro-$1-netbsd32.tar.gz
|
||||
|
||||
echo "Uploading Windows 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-win64.zip" \
|
||||
--file binaries/micro-$1-win64.zip
|
||||
|
||||
echo "Uploading Windows 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag nightly \
|
||||
--name "micro-$1-win32.zip" \
|
||||
--file binaries/micro-$1-win32.zip
|
||||
|
||||
# echo "Uploading vendored tarball"
|
||||
# github-release upload \
|
||||
# --user zyedidia \
|
||||
# --repo micro \
|
||||
# --tag nightly \
|
||||
# --name "micro-$1-src.tar.gz" \
|
||||
# --file binaries/micro-$1-src.tar.gz
|
||||
#
|
||||
# echo "Uploading vendored zip"
|
||||
# github-release upload \
|
||||
# --user zyedidia \
|
||||
# --repo micro \
|
||||
# --tag nightly \
|
||||
# --name "micro-$1-src.zip" \
|
||||
# --file binaries/micro-$1-src.zip
|
||||
|
||||
@@ -8,29 +8,145 @@ tag="v$1"
|
||||
|
||||
echo "Creating tag"
|
||||
git tag $tag $commitID
|
||||
hub push --tags
|
||||
git push --tags
|
||||
|
||||
echo "Creating new release"
|
||||
github-release release \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "$1" \
|
||||
--description "$2" \
|
||||
--pre-release
|
||||
|
||||
echo "Cross compiling binaries"
|
||||
./cross-compile.sh $1
|
||||
mv ../binaries .
|
||||
|
||||
NL=$'\n'
|
||||
echo "Uploading OSX binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-osx.tar.gz" \
|
||||
--file binaries/micro-$1-osx.tar.gz
|
||||
|
||||
echo "Creating new release"
|
||||
hub release create $tag \
|
||||
--prerelease \
|
||||
--message "$1${NL}${NL}$2" \
|
||||
--attach "binaries/micro-$1-osx.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux64.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux64-static.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux32.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux-arm.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux-arm64.tar.gz" \
|
||||
--attach "binaries/micro-$1-freebsd64.tar.gz" \
|
||||
--attach "binaries/micro-$1-freebsd32.tar.gz" \
|
||||
--attach "binaries/micro-$1-openbsd64.tar.gz" \
|
||||
--attach "binaries/micro-$1-openbsd32.tar.gz" \
|
||||
--attach "binaries/micro-$1-netbsd64.tar.gz" \
|
||||
--attach "binaries/micro-$1-netbsd32.tar.gz" \
|
||||
--attach "binaries/micro-$1-win64.zip" \
|
||||
--attach "binaries/micro-$1-win32.zip"
|
||||
echo "Uploading Linux 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-linux64.tar.gz" \
|
||||
--file binaries/micro-$1-linux64.tar.gz
|
||||
|
||||
echo "Uploading Linux 64 static binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-linux64-static.tar.gz" \
|
||||
--file binaries/micro-$1-linux64-static.tar.gz
|
||||
|
||||
echo "Uploading Linux 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-linux32.tar.gz" \
|
||||
--file binaries/micro-$1-linux32.tar.gz
|
||||
|
||||
echo "Uploading Linux Arm 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-linux-arm.tar.gz" \
|
||||
--file binaries/micro-$1-linux-arm.tar.gz
|
||||
|
||||
echo "Uploading Linux Arm 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-linux-arm64.tar.gz" \
|
||||
--file binaries/micro-$1-linux-arm64.tar.gz
|
||||
|
||||
echo "Uploading FreeBSD 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-freebsd64.tar.gz" \
|
||||
--file binaries/micro-$1-freebsd64.tar.gz
|
||||
|
||||
echo "Uploading FreeBSD 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-freebsd32.tar.gz" \
|
||||
--file binaries/micro-$1-freebsd32.tar.gz
|
||||
|
||||
echo "Uploading OpenBSD 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-openbsd64.tar.gz" \
|
||||
--file binaries/micro-$1-openbsd64.tar.gz
|
||||
|
||||
echo "Uploading OpenBSD 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-openbsd32.tar.gz" \
|
||||
--file binaries/micro-$1-openbsd32.tar.gz
|
||||
|
||||
echo "Uploading NetBSD 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-netbsd64.tar.gz" \
|
||||
--file binaries/micro-$1-netbsd64.tar.gz
|
||||
|
||||
echo "Uploading NetBSD 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-netbsd32.tar.gz" \
|
||||
--file binaries/micro-$1-netbsd32.tar.gz
|
||||
|
||||
echo "Uploading Windows 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-win64.zip" \
|
||||
--file binaries/micro-$1-win64.zip
|
||||
|
||||
echo "Uploading Windows 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-win32.zip" \
|
||||
--file binaries/micro-$1-win32.zip
|
||||
|
||||
# echo "Uploading vendored tarball"
|
||||
# github-release upload \
|
||||
# --user zyedidia \
|
||||
# --repo micro \
|
||||
# --tag $tag \
|
||||
# --name "micro-$1-src.tar.gz" \
|
||||
# --file binaries/micro-$1-src.tar.gz
|
||||
#
|
||||
# echo "Uploading vendored zip"
|
||||
# github-release upload \
|
||||
# --user zyedidia \
|
||||
# --repo micro \
|
||||
# --tag $tag \
|
||||
# --name "micro-$1-src.zip" \
|
||||
# --file binaries/micro-$1-src.zip
|
||||
|
||||
154
tools/release.sh
154
tools/release.sh
@@ -8,28 +8,144 @@ tag="v$1"
|
||||
|
||||
echo "Creating tag"
|
||||
git tag $tag $commitID
|
||||
hub push --tags
|
||||
git push --tags
|
||||
|
||||
NL=$'\n'
|
||||
echo "Creating new release"
|
||||
github-release release \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "$1" \
|
||||
--description "$2" \
|
||||
|
||||
echo "Cross compiling binaries"
|
||||
./cross-compile.sh $1
|
||||
mv ../binaries .
|
||||
|
||||
echo "Creating new release"
|
||||
hub release create $tag \
|
||||
--message "$1${NL}${NL}$2" \
|
||||
--attach "binaries/micro-$1-osx.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux64.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux64-static.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux32.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux-arm.tar.gz" \
|
||||
--attach "binaries/micro-$1-linux-arm64.tar.gz" \
|
||||
--attach "binaries/micro-$1-freebsd64.tar.gz" \
|
||||
--attach "binaries/micro-$1-freebsd32.tar.gz" \
|
||||
--attach "binaries/micro-$1-openbsd64.tar.gz" \
|
||||
--attach "binaries/micro-$1-openbsd32.tar.gz" \
|
||||
--attach "binaries/micro-$1-netbsd64.tar.gz" \
|
||||
--attach "binaries/micro-$1-netbsd32.tar.gz" \
|
||||
--attach "binaries/micro-$1-win64.zip" \
|
||||
--attach "binaries/micro-$1-win32.zip"
|
||||
echo "Uploading OSX binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-osx.tar.gz" \
|
||||
--file binaries/micro-$1-osx.tar.gz
|
||||
|
||||
echo "Uploading Linux 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-linux64.tar.gz" \
|
||||
--file binaries/micro-$1-linux64.tar.gz
|
||||
|
||||
echo "Uploading Linux 64 static binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-linux64-static.tar.gz" \
|
||||
--file binaries/micro-$1-linux64-static.tar.gz
|
||||
|
||||
echo "Uploading Linux 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-linux32.tar.gz" \
|
||||
--file binaries/micro-$1-linux32.tar.gz
|
||||
|
||||
echo "Uploading Linux Arm 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-linux-arm.tar.gz" \
|
||||
--file binaries/micro-$1-linux-arm.tar.gz
|
||||
|
||||
echo "Uploading Linux Arm 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-linux-arm64.tar.gz" \
|
||||
--file binaries/micro-$1-linux-arm64.tar.gz
|
||||
|
||||
echo "Uploading FreeBSD 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-freebsd64.tar.gz" \
|
||||
--file binaries/micro-$1-freebsd64.tar.gz
|
||||
|
||||
echo "Uploading FreeBSD 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-freebsd32.tar.gz" \
|
||||
--file binaries/micro-$1-freebsd32.tar.gz
|
||||
|
||||
echo "Uploading OpenBSD 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-openbsd64.tar.gz" \
|
||||
--file binaries/micro-$1-openbsd64.tar.gz
|
||||
|
||||
echo "Uploading OpenBSD 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-openbsd32.tar.gz" \
|
||||
--file binaries/micro-$1-openbsd32.tar.gz
|
||||
|
||||
echo "Uploading NetBSD 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-netbsd64.tar.gz" \
|
||||
--file binaries/micro-$1-netbsd64.tar.gz
|
||||
|
||||
echo "Uploading NetBSD 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-netbsd32.tar.gz" \
|
||||
--file binaries/micro-$1-netbsd32.tar.gz
|
||||
|
||||
echo "Uploading Windows 64 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-win64.zip" \
|
||||
--file binaries/micro-$1-win64.zip
|
||||
|
||||
echo "Uploading Windows 32 binary"
|
||||
github-release upload \
|
||||
--user zyedidia \
|
||||
--repo micro \
|
||||
--tag $tag \
|
||||
--name "micro-$1-win32.zip" \
|
||||
--file binaries/micro-$1-win32.zip
|
||||
|
||||
# echo "Uploading vendored tarball"
|
||||
# github-release upload \
|
||||
# --user zyedidia \
|
||||
# --repo micro \
|
||||
# --tag $tag \
|
||||
# --name "micro-$1-src.tar.gz" \
|
||||
# --file binaries/micro-$1-src.tar.gz
|
||||
#
|
||||
# echo "Uploading vendored zip"
|
||||
# github-release upload \
|
||||
# --user zyedidia \
|
||||
# --repo micro \
|
||||
# --tag $tag \
|
||||
# --name "micro-$1-src.zip" \
|
||||
# --file binaries/micro-$1-src.zip
|
||||
|
||||
267
tools/testgen.go
Normal file
267
tools/testgen.go
Normal file
@@ -0,0 +1,267 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
"github.com/robertkrimen/otto/parser"
|
||||
)
|
||||
|
||||
type walker struct {
|
||||
nodes []ast.Node
|
||||
}
|
||||
|
||||
func (w *walker) Enter(node ast.Node) ast.Visitor {
|
||||
w.nodes = append(w.nodes, node)
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *walker) Exit(node ast.Node) {
|
||||
}
|
||||
|
||||
func getAllNodes(node ast.Node) []ast.Node {
|
||||
w := &walker{}
|
||||
ast.Walk(w, node)
|
||||
return w.nodes
|
||||
}
|
||||
|
||||
func getCalls(node ast.Node, name string) []*ast.CallExpression {
|
||||
nodes := []*ast.CallExpression{}
|
||||
for _, n := range getAllNodes(node) {
|
||||
if ce, ok := n.(*ast.CallExpression); ok {
|
||||
var calleeName string
|
||||
switch callee := ce.Callee.(type) {
|
||||
case *ast.Identifier:
|
||||
calleeName = callee.Name
|
||||
case *ast.DotExpression:
|
||||
calleeName = callee.Identifier.Name
|
||||
default:
|
||||
continue
|
||||
}
|
||||
if calleeName == name {
|
||||
nodes = append(nodes, ce)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
func getPropertyValue(node ast.Node, key string) ast.Expression {
|
||||
for _, p := range node.(*ast.ObjectLiteral).Value {
|
||||
if p.Key == key {
|
||||
return p.Value
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type operation struct {
|
||||
startLine int
|
||||
startColumn int
|
||||
endLine int
|
||||
endColumn int
|
||||
text []string
|
||||
}
|
||||
|
||||
type check struct {
|
||||
before []string
|
||||
operations []operation
|
||||
after []string
|
||||
}
|
||||
|
||||
type test struct {
|
||||
description string
|
||||
checks []check
|
||||
}
|
||||
|
||||
func stringSliceToGoSource(slice []string) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("[]string{\n")
|
||||
for _, s := range slice {
|
||||
b.WriteString(fmt.Sprintf("%#v,\n", s))
|
||||
}
|
||||
b.WriteString("}")
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func testToGoTest(test test, name string) string {
|
||||
var b strings.Builder
|
||||
|
||||
b.WriteString("func Test")
|
||||
b.WriteString(name)
|
||||
b.WriteString("(t *testing.T) {\n")
|
||||
|
||||
for _, c := range test.checks {
|
||||
b.WriteString("check(\n")
|
||||
b.WriteString("t,\n")
|
||||
b.WriteString(fmt.Sprintf("%v,\n", stringSliceToGoSource(c.before)))
|
||||
b.WriteString("[]operation{\n")
|
||||
for _, op := range c.operations {
|
||||
b.WriteString("operation{\n")
|
||||
b.WriteString(fmt.Sprintf("start: Loc{%v, %v},\n", op.startColumn, op.startLine))
|
||||
b.WriteString(fmt.Sprintf("end: Loc{%v, %v},\n", op.endColumn, op.endLine))
|
||||
b.WriteString(fmt.Sprintf("text: %v,\n", stringSliceToGoSource(op.text)))
|
||||
b.WriteString("},\n")
|
||||
}
|
||||
b.WriteString("},\n")
|
||||
b.WriteString(fmt.Sprintf("%v,\n", stringSliceToGoSource(c.after)))
|
||||
b.WriteString(")\n")
|
||||
}
|
||||
|
||||
b.WriteString("}\n")
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func nodeToStringSlice(node ast.Node) []string {
|
||||
var result []string
|
||||
for _, s := range node.(*ast.ArrayLiteral).Value {
|
||||
result = append(result, s.(*ast.StringLiteral).Value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func nodeToStringSlice2(node ast.Node) []string {
|
||||
var result []string
|
||||
for _, o := range node.(*ast.ArrayLiteral).Value {
|
||||
result = append(result, getPropertyValue(o, "text").(*ast.StringLiteral).Value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func nodeToInt(node ast.Node) int {
|
||||
return int(node.(*ast.NumberLiteral).Value.(int64))
|
||||
}
|
||||
|
||||
func getChecks(node ast.Node) []check {
|
||||
checks := []check{}
|
||||
|
||||
for _, ce := range getCalls(node, "testApplyEdits") {
|
||||
if len(ce.ArgumentList) != 3 {
|
||||
// Wrong function
|
||||
continue
|
||||
}
|
||||
|
||||
before := nodeToStringSlice2(ce.ArgumentList[0])
|
||||
after := nodeToStringSlice2(ce.ArgumentList[2])
|
||||
|
||||
var operations []operation
|
||||
for _, op := range ce.ArgumentList[1].(*ast.ArrayLiteral).Value {
|
||||
args := getPropertyValue(op, "range").(*ast.NewExpression).ArgumentList
|
||||
operations = append(operations, operation{
|
||||
startLine: nodeToInt(args[0]) - 1,
|
||||
startColumn: nodeToInt(args[1]) - 1,
|
||||
endLine: nodeToInt(args[2]) - 1,
|
||||
endColumn: nodeToInt(args[3]) - 1,
|
||||
text: []string{getPropertyValue(op, "text").(*ast.StringLiteral).Value},
|
||||
})
|
||||
}
|
||||
|
||||
checks = append(checks, check{before, operations, after})
|
||||
}
|
||||
|
||||
for _, ce := range getCalls(node, "testApplyEditsWithSyncedModels") {
|
||||
if len(ce.ArgumentList) > 3 && ce.ArgumentList[3].(*ast.BooleanLiteral).Value {
|
||||
// inputEditsAreInvalid == true
|
||||
continue
|
||||
}
|
||||
|
||||
before := nodeToStringSlice(ce.ArgumentList[0])
|
||||
after := nodeToStringSlice(ce.ArgumentList[2])
|
||||
|
||||
var operations []operation
|
||||
for _, op := range getCalls(ce.ArgumentList[1], "editOp") {
|
||||
operations = append(operations, operation{
|
||||
startLine: nodeToInt(op.ArgumentList[0]) - 1,
|
||||
startColumn: nodeToInt(op.ArgumentList[1]) - 1,
|
||||
endLine: nodeToInt(op.ArgumentList[2]) - 1,
|
||||
endColumn: nodeToInt(op.ArgumentList[3]) - 1,
|
||||
text: nodeToStringSlice(op.ArgumentList[4]),
|
||||
})
|
||||
}
|
||||
|
||||
checks = append(checks, check{before, operations, after})
|
||||
}
|
||||
|
||||
return checks
|
||||
}
|
||||
|
||||
func getTests(node ast.Node) []test {
|
||||
tests := []test{}
|
||||
for _, ce := range getCalls(node, "test") {
|
||||
description := ce.ArgumentList[0].(*ast.StringLiteral).Value
|
||||
body := ce.ArgumentList[1].(*ast.FunctionLiteral).Body
|
||||
checks := getChecks(body)
|
||||
if len(checks) > 0 {
|
||||
tests = append(tests, test{description, checks})
|
||||
}
|
||||
}
|
||||
return tests
|
||||
}
|
||||
|
||||
func main() {
|
||||
var tests []test
|
||||
|
||||
for _, filename := range os.Args[1:] {
|
||||
source, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
program, err := parser.ParseFile(nil, "", source, parser.IgnoreRegExpErrors)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
tests = append(tests, getTests(program)...)
|
||||
}
|
||||
|
||||
if len(tests) == 0 {
|
||||
log.Fatalln("no tests found!")
|
||||
}
|
||||
|
||||
fmt.Println("// This file is generated from VSCode model tests by the testgen tool.")
|
||||
fmt.Println("// DO NOT EDIT THIS FILE BY HAND; your changes will be overwritten!\n")
|
||||
fmt.Println("package buffer")
|
||||
fmt.Println(`import "testing"`)
|
||||
|
||||
re := regexp.MustCompile(`[^\w]`)
|
||||
usedNames := map[string]bool{}
|
||||
|
||||
var b strings.Builder
|
||||
|
||||
for _, test := range tests {
|
||||
name := strings.Title(strings.ToLower(test.description))
|
||||
name = re.ReplaceAllLiteralString(name, "")
|
||||
if name == "" {
|
||||
name = "Unnamed"
|
||||
}
|
||||
if usedNames[name] {
|
||||
for i := 2; ; i++ {
|
||||
newName := fmt.Sprintf("%v_%v", name, i)
|
||||
if !usedNames[newName] {
|
||||
name = newName
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
usedNames[name] = true
|
||||
|
||||
fmt.Println(testToGoTest(test, name))
|
||||
|
||||
b.WriteString("Test")
|
||||
b.WriteString(name)
|
||||
b.WriteString("(nil)\n")
|
||||
}
|
||||
|
||||
fmt.Println("func BenchmarkBuffer(b *testing.B) {")
|
||||
fmt.Println("for i := 0; i < b.N; i++ {")
|
||||
fmt.Print(b.String())
|
||||
fmt.Println("}")
|
||||
fmt.Println("}")
|
||||
}
|
||||
Reference in New Issue
Block a user