mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-31 07:07:09 +09:00
Compare commits
82 Commits
v2.0.1
...
v2-modules
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eff89a98a7 | ||
|
|
221d8f462a | ||
|
|
7a23878250 | ||
|
|
5d3e4fc3d9 | ||
|
|
f52fbfa1f0 | ||
|
|
d60626c64b | ||
|
|
aaac0b1e6f | ||
|
|
0f984131fb | ||
|
|
eb7189dcdb | ||
|
|
74523d28c5 | ||
|
|
f894f0a26e | ||
|
|
a067ce1f41 | ||
|
|
f59468642d | ||
|
|
85e85b7ccc | ||
|
|
8f5888e7bf | ||
|
|
f0da73bae2 | ||
|
|
d92deacf99 | ||
|
|
ffd7b5c770 | ||
|
|
bd8c0d25c8 | ||
|
|
052a36b896 | ||
|
|
a76bf02f5f | ||
|
|
92f4cb7ef7 | ||
|
|
1cf9537340 | ||
|
|
60c8c81da3 | ||
|
|
c76a973877 | ||
|
|
6def99ce24 | ||
|
|
26930ca81f | ||
|
|
cd379cd838 | ||
|
|
ee157f6503 | ||
|
|
48ca19873f | ||
|
|
fee5528309 | ||
|
|
671a188802 | ||
|
|
18d540583b | ||
|
|
943ea15fa3 | ||
|
|
2ef57977d7 | ||
|
|
527750b68d | ||
|
|
629efe5eb7 | ||
|
|
a19cd2e6d0 | ||
|
|
9e8d76f2fa | ||
|
|
8a9a14562f | ||
|
|
a6f5dee45c | ||
|
|
b12886b066 | ||
|
|
56f5b475eb | ||
|
|
c51f84955e | ||
|
|
e4bf1e9984 | ||
|
|
917e2922a1 | ||
|
|
59e8f3aa3e | ||
|
|
53bda0cfa7 | ||
|
|
f059541e0d | ||
|
|
d78fe81e21 | ||
|
|
25b9342fbe | ||
|
|
70bcf9f618 | ||
|
|
8848388411 | ||
|
|
dff8b33e9c | ||
|
|
8a2048e7f6 | ||
|
|
0174d7dba4 | ||
|
|
e1827480c9 | ||
|
|
d8584d1ddb | ||
|
|
f0cdc3cabb | ||
|
|
2ef4f83358 | ||
|
|
a9120ce270 | ||
|
|
190d9d0609 | ||
|
|
cf3fdb344a | ||
|
|
b91242124c | ||
|
|
5ffc19f159 | ||
|
|
cc994b6241 | ||
|
|
087e7207f7 | ||
|
|
db32b84cd1 | ||
|
|
00006aa2b4 | ||
|
|
600d8558b2 | ||
|
|
4874823240 | ||
|
|
6a0e4b5564 | ||
|
|
b2d7c8c5d4 | ||
|
|
38f88ade60 | ||
|
|
8348cc8ec2 | ||
|
|
743d42e417 | ||
|
|
faa207907c | ||
|
|
9d1c489574 | ||
|
|
30ed25859a | ||
|
|
d2288c5f66 | ||
|
|
a07ee26b05 | ||
|
|
a7ce85d6f6 |
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
|
||||
|
||||
24
Makefile
24
Makefile
@@ -8,14 +8,19 @@ 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
|
||||
|
||||
# Builds micro after building the runtime and checking dependencies
|
||||
build-all: runtime build
|
||||
@@ -35,6 +40,9 @@ install-all: runtime install
|
||||
install-quick:
|
||||
go install -ldflags "-s -w $(GOVARS) $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro
|
||||
|
||||
fetch-tags:
|
||||
git fetch --tags
|
||||
|
||||
# Builds the runtime
|
||||
runtime:
|
||||
git submodule update --init
|
||||
@@ -44,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
|
||||
|
||||
15
README.md
15
README.md
@@ -91,7 +91,7 @@ Running `micro -version` will give you the version information.
|
||||
|
||||
There is a script which can install micro for you by downloading the latest prebuilt binary. You can find it at <https://getmic.ro>.
|
||||
|
||||
Then you can easily install micro:
|
||||
You can easily install micro by running
|
||||
|
||||
```bash
|
||||
curl https://getmic.ro | bash
|
||||
@@ -128,6 +128,8 @@ for other operating systems:
|
||||
* `scoop install micro`
|
||||
* OpenBSD: Available in the ports tree and also available as a binary package
|
||||
* `pkd_add -v micro`
|
||||
* Arch Linux, CRUX, Termux for Android
|
||||
* See details in the [wiki page](https://github.com/zyedidia/micro/wiki/Installing-Micro)
|
||||
|
||||
### Building from source
|
||||
|
||||
@@ -170,15 +172,12 @@ If you still insist on using the default Mac terminal, be sure to set `Use Optio
|
||||
|
||||
### Linux clipboard support
|
||||
|
||||
On Linux, clipboard support requires the `xclip` or `xsel` commands to be installed.
|
||||
On Linux, clipboard support requires:
|
||||
|
||||
For Ubuntu:
|
||||
- On X11, the `xclip` or `xsel` commands (for Ubuntu: `sudo apt install xclip`)
|
||||
- On Wayland, the `wl-clipboard` command
|
||||
|
||||
```sh
|
||||
sudo apt-get install xclip
|
||||
```
|
||||
|
||||
If you don't have `xclip` or `xsel`, micro will use an internal clipboard for copy and paste, but it won't work with external applications.
|
||||
If you don't have these commands, micro will use an internal clipboard for copy and paste, but it won't work with external applications.
|
||||
|
||||
### Colors and syntax highlighting
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
)
|
||||
|
||||
func shouldContinue() bool {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
// NullWriter simply sends writes into the void
|
||||
|
||||
@@ -6,14 +6,14 @@ import (
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
luar "layeh.com/gopher-luar"
|
||||
|
||||
"github.com/zyedidia/micro/internal/action"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/display"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/shell"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/action"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/display"
|
||||
ulua "github.com/zyedidia/micro/v2/internal/lua"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sort"
|
||||
"time"
|
||||
@@ -12,12 +13,12 @@ import (
|
||||
"github.com/go-errors/errors"
|
||||
isatty "github.com/mattn/go-isatty"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
"github.com/zyedidia/micro/internal/action"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/shell"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/action"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
@@ -44,6 +45,7 @@ func InitFlags() {
|
||||
fmt.Println("-config-dir dir")
|
||||
fmt.Println(" \tSpecify a custom location for the configuration directory")
|
||||
fmt.Println("[FILE]:LINE:COL")
|
||||
fmt.Println("+LINE:COL")
|
||||
fmt.Println(" \tSpecify a line and column to start the cursor at when opening a buffer")
|
||||
fmt.Println("-options")
|
||||
fmt.Println(" \tShow all option help")
|
||||
@@ -147,11 +149,32 @@ func LoadInput() []*buffer.Buffer {
|
||||
args := flag.Args()
|
||||
buffers := make([]*buffer.Buffer, 0, len(args))
|
||||
|
||||
if len(args) > 0 {
|
||||
btype := buffer.BTDefault
|
||||
if !isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
btype = buffer.BTStdout
|
||||
}
|
||||
|
||||
files := make([]string, 0, len(args))
|
||||
flagStartPos := ""
|
||||
flagr := regexp.MustCompile(`^\+\d+(:\d+)?$`)
|
||||
for _, a := range args {
|
||||
if flagr.MatchString(a) {
|
||||
flagStartPos = a[1:]
|
||||
} else {
|
||||
if flagStartPos != "" {
|
||||
files = append(files, a+":"+flagStartPos)
|
||||
flagStartPos = ""
|
||||
} else {
|
||||
files = append(files, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(files) > 0 {
|
||||
// Option 1
|
||||
// We go through each file and load it
|
||||
for i := 0; i < len(args); i++ {
|
||||
buf, err := buffer.NewBufferFromFile(args[i], buffer.BTDefault)
|
||||
for i := 0; i < len(files); i++ {
|
||||
buf, err := buffer.NewBufferFromFile(files[i], btype)
|
||||
if err != nil {
|
||||
screen.TermMessage(err)
|
||||
continue
|
||||
@@ -168,17 +191,22 @@ func LoadInput() []*buffer.Buffer {
|
||||
screen.TermMessage("Error reading from stdin: ", err)
|
||||
input = []byte{}
|
||||
}
|
||||
buffers = append(buffers, buffer.NewBufferFromString(string(input), filename, buffer.BTDefault))
|
||||
buffers = append(buffers, buffer.NewBufferFromString(string(input), filename, btype))
|
||||
} else {
|
||||
// Option 3, just open an empty buffer
|
||||
buffers = append(buffers, buffer.NewBufferFromString(string(input), filename, buffer.BTDefault))
|
||||
buffers = append(buffers, buffer.NewBufferFromString(string(input), filename, btype))
|
||||
}
|
||||
|
||||
return buffers
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer os.Exit(0)
|
||||
defer func() {
|
||||
if util.Stdout.Len() > 0 {
|
||||
fmt.Fprint(os.Stdout, util.Stdout.String())
|
||||
}
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
// runtime.SetCPUProfileRate(400)
|
||||
// f, _ := os.Create("micro.prof")
|
||||
|
||||
6
go.mod
6
go.mod
@@ -1,4 +1,4 @@
|
||||
module github.com/zyedidia/micro
|
||||
module github.com/zyedidia/micro/v2
|
||||
|
||||
require (
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
@@ -8,10 +8,11 @@ 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
|
||||
github.com/zyedidia/clipboard v0.0.0-20190823154308-241f98e9b197
|
||||
github.com/zyedidia/clipboard v0.0.0-20200421031010-7c45b8673834
|
||||
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3
|
||||
github.com/zyedidia/highlight v0.0.0-20170330143449-201131ce5cf5
|
||||
github.com/zyedidia/json5 v0.0.0-20200102012142-2da050b1a98d
|
||||
@@ -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
|
||||
)
|
||||
|
||||
8
go.sum
8
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=
|
||||
@@ -40,6 +42,8 @@ github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb h1:ZkM6LRnq40pR1Ox
|
||||
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||
github.com/zyedidia/clipboard v0.0.0-20190823154308-241f98e9b197 h1:gYTNnAW6azuB3BbA6QYWO/H4F2ABSOjjw3Z03tlXd2c=
|
||||
github.com/zyedidia/clipboard v0.0.0-20190823154308-241f98e9b197/go.mod h1:WDk3p8GiZV9+xFWlSo8qreeoLhW6Ik692rqXk+cNeRY=
|
||||
github.com/zyedidia/clipboard v0.0.0-20200421031010-7c45b8673834 h1:0nOfq3JwYRiY3+nwfWVQYEaXDmGCQgj3RKoqTifLzP4=
|
||||
github.com/zyedidia/clipboard v0.0.0-20200421031010-7c45b8673834/go.mod h1:zykFnZUXX0ErxqvYLUFEq7QDJKId8rmh2FgD0/Y8cjA=
|
||||
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3 h1:oMHjjTLfGXVuyOQBYj5/td9WC0mw4g1xDBPovIqmHew=
|
||||
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3/go.mod h1:YKbIYP//Eln8eDgAJGI3IDvR3s4Tv9Z9TGIOumiyQ5c=
|
||||
github.com/zyedidia/highlight v0.0.0-20170330143449-201131ce5cf5 h1:Zs6mpwXvlqpF9zHl5XaN0p5V4J9XvP+WBuiuXyIgqvc=
|
||||
@@ -50,8 +54,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 +69,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=
|
||||
|
||||
@@ -9,11 +9,11 @@ import (
|
||||
|
||||
shellquote "github.com/kballard/go-shellquote"
|
||||
"github.com/zyedidia/clipboard"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/shell"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
@@ -283,7 +283,7 @@ func (h *BufPane) SelectWordLeft() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// StartOfLine moves the cursor to the start of the text of the line
|
||||
// StartOfText moves the cursor to the start of the text of the line
|
||||
func (h *BufPane) StartOfText() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.StartOfText()
|
||||
@@ -291,6 +291,19 @@ func (h *BufPane) StartOfText() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// StartOfTextToggle toggles the cursor between the start of the text of the line
|
||||
// and the start of the line
|
||||
func (h *BufPane) StartOfTextToggle() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
if h.Cursor.IsStartOfText() {
|
||||
h.Cursor.Start()
|
||||
} else {
|
||||
h.Cursor.StartOfText()
|
||||
}
|
||||
h.Relocate()
|
||||
return true
|
||||
}
|
||||
|
||||
// StartOfLine moves the cursor to the start of the line
|
||||
func (h *BufPane) StartOfLine() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
@@ -325,6 +338,22 @@ func (h *BufPane) SelectToStartOfText() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectToStartOfTextToggle toggles the selection between the start of the text
|
||||
// on the current line and the start of the line
|
||||
func (h *BufPane) SelectToStartOfTextToggle() bool {
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = h.Cursor.Loc
|
||||
}
|
||||
if h.Cursor.IsStartOfText() {
|
||||
h.Cursor.Start()
|
||||
} else {
|
||||
h.Cursor.StartOfText()
|
||||
}
|
||||
h.Cursor.SelectTo(h.Cursor.Loc)
|
||||
h.Relocate()
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectToStartOfLine selects to the start of the current line
|
||||
func (h *BufPane) SelectToStartOfLine() bool {
|
||||
if !h.Cursor.HasSelection() {
|
||||
@@ -396,6 +425,7 @@ func (h *BufPane) CursorStart() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.X = 0
|
||||
h.Cursor.Y = 0
|
||||
h.Cursor.StoreVisualX()
|
||||
h.Relocate()
|
||||
return true
|
||||
}
|
||||
@@ -773,7 +803,7 @@ func (h *BufPane) saveBufToFile(filename string, action string, callback func())
|
||||
// Find opens a prompt and searches forward for the input
|
||||
func (h *BufPane) Find() bool {
|
||||
h.searchOrig = h.Cursor.Loc
|
||||
InfoBar.Prompt("Find: ", "", "Find", func(resp string) {
|
||||
InfoBar.Prompt("Find (regex): ", "", "Find", func(resp string) {
|
||||
// Event callback
|
||||
match, found, _ := h.Buf.FindNext(resp, h.Buf.Start(), h.Buf.End(), h.searchOrig, true, true)
|
||||
if found {
|
||||
@@ -899,6 +929,25 @@ func (h *BufPane) Copy() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Copy the current line to the clipboard
|
||||
func (h *BufPane) CopyLine() bool {
|
||||
if h.Cursor.HasSelection() {
|
||||
return false
|
||||
} else {
|
||||
h.Cursor.SelectLine()
|
||||
h.Cursor.CopySelection("clipboard")
|
||||
h.freshClip = true
|
||||
if clipboard.Unsupported {
|
||||
InfoBar.Message("Copied line (install xclip for external clipboard)")
|
||||
} else {
|
||||
InfoBar.Message("Copied line")
|
||||
}
|
||||
}
|
||||
h.Cursor.Deselect(true)
|
||||
h.Relocate()
|
||||
return true
|
||||
}
|
||||
|
||||
// CutLine cuts the current line to the clipboard
|
||||
func (h *BufPane) CutLine() bool {
|
||||
h.Cursor.SelectLine()
|
||||
@@ -1119,6 +1168,16 @@ func (h *BufPane) OpenFile() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// OpenFile opens a new file in the buffer
|
||||
func (h *BufPane) JumpLine() bool {
|
||||
InfoBar.Prompt("> ", "goto ", "Command", nil, func(resp string, canceled bool) {
|
||||
if !canceled {
|
||||
h.HandleCommand(resp)
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
// Start moves the viewport to the start of the buffer
|
||||
func (h *BufPane) Start() bool {
|
||||
v := h.GetView()
|
||||
@@ -1406,8 +1465,9 @@ func (h *BufPane) AddTab() bool {
|
||||
|
||||
// PreviousTab switches to the previous tab in the tab list
|
||||
func (h *BufPane) PreviousTab() bool {
|
||||
a := Tabs.Active()
|
||||
Tabs.SetActive(util.Clamp(a-1, 0, len(Tabs.List)-1))
|
||||
tabsLen := len(Tabs.List)
|
||||
a := Tabs.Active() + tabsLen
|
||||
Tabs.SetActive((a - 1) % tabsLen)
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -1415,7 +1475,8 @@ func (h *BufPane) PreviousTab() bool {
|
||||
// NextTab switches to the next tab in the tab list
|
||||
func (h *BufPane) NextTab() bool {
|
||||
a := Tabs.Active()
|
||||
Tabs.SetActive(util.Clamp(a+1, 0, len(Tabs.List)-1))
|
||||
Tabs.SetActive((a + 1) % len(Tabs.List))
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1567,7 +1628,7 @@ func (h *BufPane) SpawnMultiCursorUp() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SpawnMultiCursorUp creates additional cursor, at the same X (if possible), one Y more.
|
||||
// SpawnMultiCursorDown creates additional cursor, at the same X (if possible), one Y more.
|
||||
func (h *BufPane) SpawnMultiCursorDown() bool {
|
||||
if h.Cursor.Y+1 == h.Buf.LinesNum() {
|
||||
return false
|
||||
|
||||
@@ -5,7 +5,7 @@ package action
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
)
|
||||
|
||||
// Suspend sends micro to the background. This is the same as pressing CtrlZ in most unix programs.
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"unicode"
|
||||
|
||||
"github.com/zyedidia/json5"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
luar "layeh.com/gopher-luar"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/display"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/display"
|
||||
ulua "github.com/zyedidia/micro/v2/internal/lua"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
@@ -103,7 +103,7 @@ func BufMapKey(k Event, action string) {
|
||||
afn = f
|
||||
names = append(names, a)
|
||||
} else {
|
||||
screen.TermMessage("Error:", a, "does not exist")
|
||||
screen.TermMessage("Error in bindings: action", a, "does not exist")
|
||||
continue
|
||||
}
|
||||
actionfns = append(actionfns, afn)
|
||||
@@ -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
|
||||
@@ -339,10 +343,11 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
|
||||
// release the mouse
|
||||
|
||||
// if !h.doubleClick && !h.tripleClick {
|
||||
// h.Cursor.Loc = mouseLoc
|
||||
// h.Cursor.SetSelectionEnd(h.Cursor.Loc)
|
||||
// h.Cursor.CopySelection("primary")
|
||||
// }
|
||||
if h.Cursor.HasSelection() {
|
||||
h.Cursor.CopySelection("primary")
|
||||
}
|
||||
h.mouseReleased = true
|
||||
}
|
||||
}
|
||||
@@ -458,6 +463,7 @@ func (h *BufPane) DoRuneInsert(r rune) {
|
||||
if recording_macro {
|
||||
curmacro = append(curmacro, r)
|
||||
}
|
||||
h.Relocate()
|
||||
h.PluginCBRune("onRune", r)
|
||||
}
|
||||
}
|
||||
@@ -511,106 +517,110 @@ func (h *BufPane) SetActive(b bool) {
|
||||
|
||||
// BufKeyActions contains the list of all possible key actions the bufhandler could execute
|
||||
var BufKeyActions = map[string]BufKeyAction{
|
||||
"CursorUp": (*BufPane).CursorUp,
|
||||
"CursorDown": (*BufPane).CursorDown,
|
||||
"CursorPageUp": (*BufPane).CursorPageUp,
|
||||
"CursorPageDown": (*BufPane).CursorPageDown,
|
||||
"CursorLeft": (*BufPane).CursorLeft,
|
||||
"CursorRight": (*BufPane).CursorRight,
|
||||
"CursorStart": (*BufPane).CursorStart,
|
||||
"CursorEnd": (*BufPane).CursorEnd,
|
||||
"SelectToStart": (*BufPane).SelectToStart,
|
||||
"SelectToEnd": (*BufPane).SelectToEnd,
|
||||
"SelectUp": (*BufPane).SelectUp,
|
||||
"SelectDown": (*BufPane).SelectDown,
|
||||
"SelectLeft": (*BufPane).SelectLeft,
|
||||
"SelectRight": (*BufPane).SelectRight,
|
||||
"WordRight": (*BufPane).WordRight,
|
||||
"WordLeft": (*BufPane).WordLeft,
|
||||
"SelectWordRight": (*BufPane).SelectWordRight,
|
||||
"SelectWordLeft": (*BufPane).SelectWordLeft,
|
||||
"DeleteWordRight": (*BufPane).DeleteWordRight,
|
||||
"DeleteWordLeft": (*BufPane).DeleteWordLeft,
|
||||
"SelectLine": (*BufPane).SelectLine,
|
||||
"SelectToStartOfLine": (*BufPane).SelectToStartOfLine,
|
||||
"SelectToStartOfText": (*BufPane).SelectToStartOfText,
|
||||
"SelectToEndOfLine": (*BufPane).SelectToEndOfLine,
|
||||
"ParagraphPrevious": (*BufPane).ParagraphPrevious,
|
||||
"ParagraphNext": (*BufPane).ParagraphNext,
|
||||
"InsertNewline": (*BufPane).InsertNewline,
|
||||
"Backspace": (*BufPane).Backspace,
|
||||
"Delete": (*BufPane).Delete,
|
||||
"InsertTab": (*BufPane).InsertTab,
|
||||
"Save": (*BufPane).Save,
|
||||
"SaveAll": (*BufPane).SaveAll,
|
||||
"SaveAs": (*BufPane).SaveAs,
|
||||
"Find": (*BufPane).Find,
|
||||
"FindNext": (*BufPane).FindNext,
|
||||
"FindPrevious": (*BufPane).FindPrevious,
|
||||
"Center": (*BufPane).Center,
|
||||
"Undo": (*BufPane).Undo,
|
||||
"Redo": (*BufPane).Redo,
|
||||
"Copy": (*BufPane).Copy,
|
||||
"Cut": (*BufPane).Cut,
|
||||
"CutLine": (*BufPane).CutLine,
|
||||
"DuplicateLine": (*BufPane).DuplicateLine,
|
||||
"DeleteLine": (*BufPane).DeleteLine,
|
||||
"MoveLinesUp": (*BufPane).MoveLinesUp,
|
||||
"MoveLinesDown": (*BufPane).MoveLinesDown,
|
||||
"IndentSelection": (*BufPane).IndentSelection,
|
||||
"OutdentSelection": (*BufPane).OutdentSelection,
|
||||
"Autocomplete": (*BufPane).Autocomplete,
|
||||
"CycleAutocompleteBack": (*BufPane).CycleAutocompleteBack,
|
||||
"OutdentLine": (*BufPane).OutdentLine,
|
||||
"IndentLine": (*BufPane).IndentLine,
|
||||
"Paste": (*BufPane).Paste,
|
||||
"PastePrimary": (*BufPane).PastePrimary,
|
||||
"SelectAll": (*BufPane).SelectAll,
|
||||
"OpenFile": (*BufPane).OpenFile,
|
||||
"Start": (*BufPane).Start,
|
||||
"End": (*BufPane).End,
|
||||
"PageUp": (*BufPane).PageUp,
|
||||
"PageDown": (*BufPane).PageDown,
|
||||
"SelectPageUp": (*BufPane).SelectPageUp,
|
||||
"SelectPageDown": (*BufPane).SelectPageDown,
|
||||
"HalfPageUp": (*BufPane).HalfPageUp,
|
||||
"HalfPageDown": (*BufPane).HalfPageDown,
|
||||
"StartOfText": (*BufPane).StartOfText,
|
||||
"StartOfLine": (*BufPane).StartOfLine,
|
||||
"EndOfLine": (*BufPane).EndOfLine,
|
||||
"ToggleHelp": (*BufPane).ToggleHelp,
|
||||
"ToggleKeyMenu": (*BufPane).ToggleKeyMenu,
|
||||
"ToggleDiffGutter": (*BufPane).ToggleDiffGutter,
|
||||
"ToggleRuler": (*BufPane).ToggleRuler,
|
||||
"ClearStatus": (*BufPane).ClearStatus,
|
||||
"ShellMode": (*BufPane).ShellMode,
|
||||
"CommandMode": (*BufPane).CommandMode,
|
||||
"ToggleOverwriteMode": (*BufPane).ToggleOverwriteMode,
|
||||
"Escape": (*BufPane).Escape,
|
||||
"Quit": (*BufPane).Quit,
|
||||
"QuitAll": (*BufPane).QuitAll,
|
||||
"AddTab": (*BufPane).AddTab,
|
||||
"PreviousTab": (*BufPane).PreviousTab,
|
||||
"NextTab": (*BufPane).NextTab,
|
||||
"NextSplit": (*BufPane).NextSplit,
|
||||
"PreviousSplit": (*BufPane).PreviousSplit,
|
||||
"Unsplit": (*BufPane).Unsplit,
|
||||
"VSplit": (*BufPane).VSplitAction,
|
||||
"HSplit": (*BufPane).HSplitAction,
|
||||
"ToggleMacro": (*BufPane).ToggleMacro,
|
||||
"PlayMacro": (*BufPane).PlayMacro,
|
||||
"Suspend": (*BufPane).Suspend,
|
||||
"ScrollUp": (*BufPane).ScrollUpAction,
|
||||
"ScrollDown": (*BufPane).ScrollDownAction,
|
||||
"SpawnMultiCursor": (*BufPane).SpawnMultiCursor,
|
||||
"SpawnMultiCursorUp": (*BufPane).SpawnMultiCursorUp,
|
||||
"SpawnMultiCursorDown": (*BufPane).SpawnMultiCursorDown,
|
||||
"SpawnMultiCursorSelect": (*BufPane).SpawnMultiCursorSelect,
|
||||
"RemoveMultiCursor": (*BufPane).RemoveMultiCursor,
|
||||
"RemoveAllMultiCursors": (*BufPane).RemoveAllMultiCursors,
|
||||
"SkipMultiCursor": (*BufPane).SkipMultiCursor,
|
||||
"JumpToMatchingBrace": (*BufPane).JumpToMatchingBrace,
|
||||
"None": (*BufPane).None,
|
||||
"CursorUp": (*BufPane).CursorUp,
|
||||
"CursorDown": (*BufPane).CursorDown,
|
||||
"CursorPageUp": (*BufPane).CursorPageUp,
|
||||
"CursorPageDown": (*BufPane).CursorPageDown,
|
||||
"CursorLeft": (*BufPane).CursorLeft,
|
||||
"CursorRight": (*BufPane).CursorRight,
|
||||
"CursorStart": (*BufPane).CursorStart,
|
||||
"CursorEnd": (*BufPane).CursorEnd,
|
||||
"SelectToStart": (*BufPane).SelectToStart,
|
||||
"SelectToEnd": (*BufPane).SelectToEnd,
|
||||
"SelectUp": (*BufPane).SelectUp,
|
||||
"SelectDown": (*BufPane).SelectDown,
|
||||
"SelectLeft": (*BufPane).SelectLeft,
|
||||
"SelectRight": (*BufPane).SelectRight,
|
||||
"WordRight": (*BufPane).WordRight,
|
||||
"WordLeft": (*BufPane).WordLeft,
|
||||
"SelectWordRight": (*BufPane).SelectWordRight,
|
||||
"SelectWordLeft": (*BufPane).SelectWordLeft,
|
||||
"DeleteWordRight": (*BufPane).DeleteWordRight,
|
||||
"DeleteWordLeft": (*BufPane).DeleteWordLeft,
|
||||
"SelectLine": (*BufPane).SelectLine,
|
||||
"SelectToStartOfLine": (*BufPane).SelectToStartOfLine,
|
||||
"SelectToStartOfText": (*BufPane).SelectToStartOfText,
|
||||
"SelectToStartOfTextToggle": (*BufPane).SelectToStartOfTextToggle,
|
||||
"SelectToEndOfLine": (*BufPane).SelectToEndOfLine,
|
||||
"ParagraphPrevious": (*BufPane).ParagraphPrevious,
|
||||
"ParagraphNext": (*BufPane).ParagraphNext,
|
||||
"InsertNewline": (*BufPane).InsertNewline,
|
||||
"Backspace": (*BufPane).Backspace,
|
||||
"Delete": (*BufPane).Delete,
|
||||
"InsertTab": (*BufPane).InsertTab,
|
||||
"Save": (*BufPane).Save,
|
||||
"SaveAll": (*BufPane).SaveAll,
|
||||
"SaveAs": (*BufPane).SaveAs,
|
||||
"Find": (*BufPane).Find,
|
||||
"FindNext": (*BufPane).FindNext,
|
||||
"FindPrevious": (*BufPane).FindPrevious,
|
||||
"Center": (*BufPane).Center,
|
||||
"Undo": (*BufPane).Undo,
|
||||
"Redo": (*BufPane).Redo,
|
||||
"Copy": (*BufPane).Copy,
|
||||
"CopyLine": (*BufPane).CopyLine,
|
||||
"Cut": (*BufPane).Cut,
|
||||
"CutLine": (*BufPane).CutLine,
|
||||
"DuplicateLine": (*BufPane).DuplicateLine,
|
||||
"DeleteLine": (*BufPane).DeleteLine,
|
||||
"MoveLinesUp": (*BufPane).MoveLinesUp,
|
||||
"MoveLinesDown": (*BufPane).MoveLinesDown,
|
||||
"IndentSelection": (*BufPane).IndentSelection,
|
||||
"OutdentSelection": (*BufPane).OutdentSelection,
|
||||
"Autocomplete": (*BufPane).Autocomplete,
|
||||
"CycleAutocompleteBack": (*BufPane).CycleAutocompleteBack,
|
||||
"OutdentLine": (*BufPane).OutdentLine,
|
||||
"IndentLine": (*BufPane).IndentLine,
|
||||
"Paste": (*BufPane).Paste,
|
||||
"PastePrimary": (*BufPane).PastePrimary,
|
||||
"SelectAll": (*BufPane).SelectAll,
|
||||
"OpenFile": (*BufPane).OpenFile,
|
||||
"Start": (*BufPane).Start,
|
||||
"End": (*BufPane).End,
|
||||
"PageUp": (*BufPane).PageUp,
|
||||
"PageDown": (*BufPane).PageDown,
|
||||
"SelectPageUp": (*BufPane).SelectPageUp,
|
||||
"SelectPageDown": (*BufPane).SelectPageDown,
|
||||
"HalfPageUp": (*BufPane).HalfPageUp,
|
||||
"HalfPageDown": (*BufPane).HalfPageDown,
|
||||
"StartOfText": (*BufPane).StartOfText,
|
||||
"StartOfTextToggle": (*BufPane).StartOfTextToggle,
|
||||
"StartOfLine": (*BufPane).StartOfLine,
|
||||
"EndOfLine": (*BufPane).EndOfLine,
|
||||
"ToggleHelp": (*BufPane).ToggleHelp,
|
||||
"ToggleKeyMenu": (*BufPane).ToggleKeyMenu,
|
||||
"ToggleDiffGutter": (*BufPane).ToggleDiffGutter,
|
||||
"ToggleRuler": (*BufPane).ToggleRuler,
|
||||
"ClearStatus": (*BufPane).ClearStatus,
|
||||
"ShellMode": (*BufPane).ShellMode,
|
||||
"CommandMode": (*BufPane).CommandMode,
|
||||
"ToggleOverwriteMode": (*BufPane).ToggleOverwriteMode,
|
||||
"Escape": (*BufPane).Escape,
|
||||
"Quit": (*BufPane).Quit,
|
||||
"QuitAll": (*BufPane).QuitAll,
|
||||
"AddTab": (*BufPane).AddTab,
|
||||
"PreviousTab": (*BufPane).PreviousTab,
|
||||
"NextTab": (*BufPane).NextTab,
|
||||
"NextSplit": (*BufPane).NextSplit,
|
||||
"PreviousSplit": (*BufPane).PreviousSplit,
|
||||
"Unsplit": (*BufPane).Unsplit,
|
||||
"VSplit": (*BufPane).VSplitAction,
|
||||
"HSplit": (*BufPane).HSplitAction,
|
||||
"ToggleMacro": (*BufPane).ToggleMacro,
|
||||
"PlayMacro": (*BufPane).PlayMacro,
|
||||
"Suspend": (*BufPane).Suspend,
|
||||
"ScrollUp": (*BufPane).ScrollUpAction,
|
||||
"ScrollDown": (*BufPane).ScrollDownAction,
|
||||
"SpawnMultiCursor": (*BufPane).SpawnMultiCursor,
|
||||
"SpawnMultiCursorUp": (*BufPane).SpawnMultiCursorUp,
|
||||
"SpawnMultiCursorDown": (*BufPane).SpawnMultiCursorDown,
|
||||
"SpawnMultiCursorSelect": (*BufPane).SpawnMultiCursorSelect,
|
||||
"RemoveMultiCursor": (*BufPane).RemoveMultiCursor,
|
||||
"RemoveAllMultiCursors": (*BufPane).RemoveAllMultiCursors,
|
||||
"SkipMultiCursor": (*BufPane).SkipMultiCursor,
|
||||
"JumpToMatchingBrace": (*BufPane).JumpToMatchingBrace,
|
||||
"JumpLine": (*BufPane).JumpLine,
|
||||
"None": (*BufPane).None,
|
||||
|
||||
// This was changed to InsertNewline but I don't want to break backwards compatibility
|
||||
"InsertEnter": (*BufPane).InsertNewline,
|
||||
@@ -627,54 +637,57 @@ var BufMouseActions = map[string]BufMouseAction{
|
||||
// Generally actions that modify global editor state like quitting or
|
||||
// saving should not be included in this list
|
||||
var MultiActions = map[string]bool{
|
||||
"CursorUp": true,
|
||||
"CursorDown": true,
|
||||
"CursorPageUp": true,
|
||||
"CursorPageDown": true,
|
||||
"CursorLeft": true,
|
||||
"CursorRight": true,
|
||||
"CursorStart": true,
|
||||
"CursorEnd": true,
|
||||
"SelectToStart": true,
|
||||
"SelectToEnd": true,
|
||||
"SelectUp": true,
|
||||
"SelectDown": true,
|
||||
"SelectLeft": true,
|
||||
"SelectRight": true,
|
||||
"WordRight": true,
|
||||
"WordLeft": true,
|
||||
"SelectWordRight": true,
|
||||
"SelectWordLeft": true,
|
||||
"DeleteWordRight": true,
|
||||
"DeleteWordLeft": true,
|
||||
"SelectLine": true,
|
||||
"SelectToStartOfLine": true,
|
||||
"SelectToStartOfText": true,
|
||||
"SelectToEndOfLine": true,
|
||||
"ParagraphPrevious": true,
|
||||
"ParagraphNext": true,
|
||||
"InsertNewline": true,
|
||||
"Backspace": true,
|
||||
"Delete": true,
|
||||
"InsertTab": true,
|
||||
"FindNext": true,
|
||||
"FindPrevious": true,
|
||||
"Cut": true,
|
||||
"CutLine": true,
|
||||
"DuplicateLine": true,
|
||||
"DeleteLine": true,
|
||||
"MoveLinesUp": true,
|
||||
"MoveLinesDown": true,
|
||||
"IndentSelection": true,
|
||||
"OutdentSelection": true,
|
||||
"OutdentLine": true,
|
||||
"IndentLine": true,
|
||||
"Paste": true,
|
||||
"PastePrimary": true,
|
||||
"SelectPageUp": true,
|
||||
"SelectPageDown": true,
|
||||
"StartOfLine": true,
|
||||
"StartOfText": true,
|
||||
"EndOfLine": true,
|
||||
"JumpToMatchingBrace": true,
|
||||
"CursorUp": true,
|
||||
"CursorDown": true,
|
||||
"CursorPageUp": true,
|
||||
"CursorPageDown": true,
|
||||
"CursorLeft": true,
|
||||
"CursorRight": true,
|
||||
"CursorStart": true,
|
||||
"CursorEnd": true,
|
||||
"SelectToStart": true,
|
||||
"SelectToEnd": true,
|
||||
"SelectUp": true,
|
||||
"SelectDown": true,
|
||||
"SelectLeft": true,
|
||||
"SelectRight": true,
|
||||
"WordRight": true,
|
||||
"WordLeft": true,
|
||||
"SelectWordRight": true,
|
||||
"SelectWordLeft": true,
|
||||
"DeleteWordRight": true,
|
||||
"DeleteWordLeft": true,
|
||||
"SelectLine": true,
|
||||
"SelectToStartOfLine": true,
|
||||
"SelectToStartOfText": true,
|
||||
"SelectToStartOfTextToggle": true,
|
||||
"SelectToEndOfLine": true,
|
||||
"ParagraphPrevious": true,
|
||||
"ParagraphNext": true,
|
||||
"InsertNewline": true,
|
||||
"Backspace": true,
|
||||
"Delete": true,
|
||||
"InsertTab": true,
|
||||
"FindNext": true,
|
||||
"FindPrevious": true,
|
||||
"CopyLine": true,
|
||||
"Cut": true,
|
||||
"CutLine": true,
|
||||
"DuplicateLine": true,
|
||||
"DeleteLine": true,
|
||||
"MoveLinesUp": true,
|
||||
"MoveLinesDown": true,
|
||||
"IndentSelection": true,
|
||||
"OutdentSelection": true,
|
||||
"OutdentLine": true,
|
||||
"IndentLine": true,
|
||||
"Paste": true,
|
||||
"PastePrimary": true,
|
||||
"SelectPageUp": true,
|
||||
"SelectPageDown": true,
|
||||
"StartOfLine": true,
|
||||
"StartOfText": true,
|
||||
"StartOfTextToggle": true,
|
||||
"EndOfLine": true,
|
||||
"JumpToMatchingBrace": true,
|
||||
}
|
||||
|
||||
@@ -13,11 +13,11 @@ import (
|
||||
"unicode/utf8"
|
||||
|
||||
shellquote "github.com/kballard/go-shellquote"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/shell"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
// A Command contains information about how to execute a command
|
||||
@@ -732,23 +732,23 @@ func (h *BufPane) ReplaceCmd(args []string) {
|
||||
|
||||
nreplaced := 0
|
||||
start := h.Buf.Start()
|
||||
// end := h.Buf.End()
|
||||
// if h.Cursor.HasSelection() {
|
||||
// start = h.Cursor.CurSelection[0]
|
||||
// end = h.Cursor.CurSelection[1]
|
||||
// }
|
||||
end := h.Buf.End()
|
||||
selection := h.Cursor.HasSelection()
|
||||
if selection {
|
||||
start = h.Cursor.CurSelection[0]
|
||||
end = h.Cursor.CurSelection[1]
|
||||
}
|
||||
if all {
|
||||
nreplaced = h.Buf.ReplaceRegex(start, h.Buf.End(), regex, replace)
|
||||
nreplaced, _ = h.Buf.ReplaceRegex(start, end, regex, replace)
|
||||
} else {
|
||||
inRange := func(l buffer.Loc) bool {
|
||||
return l.GreaterEqual(start) && l.LessEqual(h.Buf.End())
|
||||
return l.GreaterEqual(start) && l.LessEqual(end)
|
||||
}
|
||||
|
||||
searchLoc := start
|
||||
searching := true
|
||||
var doReplacement func()
|
||||
doReplacement = func() {
|
||||
locs, found, err := h.Buf.FindNext(search, start, h.Buf.End(), searchLoc, true, !noRegex)
|
||||
locs, found, err := h.Buf.FindNext(search, start, end, searchLoc, true, !noRegex)
|
||||
if err != nil {
|
||||
InfoBar.Error(err)
|
||||
return
|
||||
@@ -761,13 +761,17 @@ func (h *BufPane) ReplaceCmd(args []string) {
|
||||
|
||||
h.Cursor.SetSelectionStart(locs[0])
|
||||
h.Cursor.SetSelectionEnd(locs[1])
|
||||
h.Cursor.GotoLoc(locs[0])
|
||||
|
||||
h.Relocate()
|
||||
|
||||
InfoBar.YNPrompt("Perform replacement (y,n,esc)", func(yes, canceled bool) {
|
||||
if !canceled && yes {
|
||||
h.Buf.Replace(locs[0], locs[1], replaceStr)
|
||||
_, nrunes := h.Buf.ReplaceRegex(locs[0], locs[1], regex, replace)
|
||||
|
||||
searchLoc = locs[0]
|
||||
searchLoc.X += utf8.RuneCount(replace)
|
||||
searchLoc.X += nrunes + locs[0].Diff(locs[1], h.Buf)
|
||||
end.Move(nrunes, h.Buf)
|
||||
h.Cursor.Loc = searchLoc
|
||||
nreplaced++
|
||||
} else if !canceled && !yes {
|
||||
@@ -778,23 +782,29 @@ func (h *BufPane) ReplaceCmd(args []string) {
|
||||
h.Buf.RelocateCursors()
|
||||
return
|
||||
}
|
||||
if searching {
|
||||
doReplacement()
|
||||
}
|
||||
doReplacement()
|
||||
})
|
||||
}
|
||||
doReplacement()
|
||||
}
|
||||
|
||||
h.Buf.RelocateCursors()
|
||||
h.Relocate()
|
||||
|
||||
var s string
|
||||
if nreplaced > 1 {
|
||||
InfoBar.Message("Replaced ", nreplaced, " occurrences of ", search)
|
||||
s = fmt.Sprintf("Replaced %d occurrences of %s", nreplaced, search)
|
||||
} else if nreplaced == 1 {
|
||||
InfoBar.Message("Replaced ", nreplaced, " occurrence of ", search)
|
||||
s = fmt.Sprintf("Replaced 1 occurrence of %s", search)
|
||||
} else {
|
||||
InfoBar.Message("Nothing matched ", search)
|
||||
s = fmt.Sprintf("Nothing matched %s", search)
|
||||
}
|
||||
|
||||
if selection {
|
||||
s += " in selection"
|
||||
}
|
||||
|
||||
InfoBar.Message(s)
|
||||
}
|
||||
|
||||
// ReplaceAllCmd replaces search term all at once
|
||||
@@ -823,7 +833,11 @@ func (h *BufPane) TermCmd(args []string) {
|
||||
|
||||
term := func(i int, newtab bool) {
|
||||
t := new(shell.Terminal)
|
||||
t.Start(args, false, true, nil, nil)
|
||||
err := t.Start(args, false, true, nil, nil)
|
||||
if err != nil {
|
||||
InfoBar.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
id := h.ID()
|
||||
if newtab {
|
||||
|
||||
@@ -17,10 +17,10 @@ func DefaultBindings() map[string]string {
|
||||
"AltDown": "MoveLinesDown",
|
||||
"AltShiftRight": "SelectWordRight",
|
||||
"AltShiftLeft": "SelectWordLeft",
|
||||
"CtrlLeft": "StartOfText",
|
||||
"CtrlLeft": "StartOfTextToggle",
|
||||
"CtrlRight": "EndOfLine",
|
||||
"CtrlShiftLeft": "SelectToStartOfText",
|
||||
"ShiftHome": "SelectToStartOfText",
|
||||
"CtrlShiftLeft": "SelectToStartOfTextToggle",
|
||||
"ShiftHome": "SelectToStartOfTextToggle",
|
||||
"CtrlShiftRight": "SelectToEndOfLine",
|
||||
"ShiftEnd": "SelectToEndOfLine",
|
||||
"CtrlUp": "CursorStart",
|
||||
@@ -43,7 +43,7 @@ func DefaultBindings() map[string]string {
|
||||
"CtrlP": "FindPrevious",
|
||||
"CtrlZ": "Undo",
|
||||
"CtrlY": "Redo",
|
||||
"CtrlC": "Copy",
|
||||
"CtrlC": "CopyLine|Copy",
|
||||
"CtrlX": "Cut",
|
||||
"CtrlK": "CutLine",
|
||||
"CtrlD": "DuplicateLine",
|
||||
@@ -52,7 +52,7 @@ func DefaultBindings() map[string]string {
|
||||
"CtrlT": "AddTab",
|
||||
"Alt,": "PreviousTab",
|
||||
"Alt.": "NextTab",
|
||||
"Home": "StartOfText",
|
||||
"Home": "StartOfTextToggle",
|
||||
"End": "EndOfLine",
|
||||
"CtrlHome": "CursorStart",
|
||||
"CtrlEnd": "CursorEnd",
|
||||
|
||||
@@ -19,10 +19,10 @@ func DefaultBindings() map[string]string {
|
||||
"AltDown": "MoveLinesDown",
|
||||
"CtrlShiftRight": "SelectWordRight",
|
||||
"CtrlShiftLeft": "SelectWordLeft",
|
||||
"AltLeft": "StartOfText",
|
||||
"AltLeft": "StartOfTextToggle",
|
||||
"AltRight": "EndOfLine",
|
||||
"AltShiftLeft": "SelectToStartOfText",
|
||||
"ShiftHome": "SelectToStartOfText",
|
||||
"AltShiftLeft": "SelectToStartOfTextToggle",
|
||||
"ShiftHome": "SelectToStartOfTextToggle",
|
||||
"AltShiftRight": "SelectToEndOfLine",
|
||||
"ShiftEnd": "SelectToEndOfLine",
|
||||
"CtrlUp": "CursorStart",
|
||||
@@ -45,7 +45,7 @@ func DefaultBindings() map[string]string {
|
||||
"CtrlP": "FindPrevious",
|
||||
"CtrlZ": "Undo",
|
||||
"CtrlY": "Redo",
|
||||
"CtrlC": "Copy",
|
||||
"CtrlC": "CopyLine|Copy",
|
||||
"CtrlX": "Cut",
|
||||
"CtrlK": "CutLine",
|
||||
"CtrlD": "DuplicateLine",
|
||||
@@ -54,7 +54,7 @@ func DefaultBindings() map[string]string {
|
||||
"CtrlT": "AddTab",
|
||||
"Alt,": "PreviousTab",
|
||||
"Alt.": "NextTab",
|
||||
"Home": "StartOfText",
|
||||
"Home": "StartOfTextToggle",
|
||||
"End": "EndOfLine",
|
||||
"CtrlHome": "CursorStart",
|
||||
"CtrlEnd": "CursorEnd",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package action
|
||||
|
||||
import "github.com/zyedidia/micro/internal/buffer"
|
||||
import "github.com/zyedidia/micro/v2/internal/buffer"
|
||||
|
||||
var InfoBar *InfoPane
|
||||
var LogBufPane *BufPane
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
// This file is meant (for now) for autocompletion in command mode, not
|
||||
|
||||
@@ -4,9 +4,10 @@ import (
|
||||
"bytes"
|
||||
"strings"
|
||||
|
||||
"github.com/zyedidia/micro/internal/display"
|
||||
"github.com/zyedidia/micro/internal/info"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/display"
|
||||
"github.com/zyedidia/micro/v2/internal/info"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
@@ -68,7 +69,7 @@ func (h *InfoPane) HandleEvent(event tcell.Event) {
|
||||
h.EventCallback(resp)
|
||||
}
|
||||
}
|
||||
case *tcell.EventMouse:
|
||||
default:
|
||||
h.BufPane.HandleEvent(event)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package action
|
||||
|
||||
import (
|
||||
"github.com/zyedidia/micro/internal/display"
|
||||
"github.com/zyedidia/micro/v2/internal/display"
|
||||
)
|
||||
|
||||
type Pane interface {
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/display"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/display"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package action
|
||||
|
||||
import (
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/display"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/views"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/display"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/views"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
@@ -166,6 +166,8 @@ type Tab struct {
|
||||
active int
|
||||
|
||||
resizing *views.Node // node currently being resized
|
||||
// captures whether the mouse is released
|
||||
release bool
|
||||
}
|
||||
|
||||
// NewTabFromBuffer creates a new tab from the given buffer
|
||||
@@ -203,6 +205,8 @@ func (t *Tab) HandleEvent(event tcell.Event) {
|
||||
mx, my := e.Position()
|
||||
switch e.Buttons() {
|
||||
case tcell.Button1:
|
||||
wasReleased := t.release
|
||||
t.release = false
|
||||
if t.resizing != nil {
|
||||
var size int
|
||||
if t.resizing.Kind == views.STVert {
|
||||
@@ -215,22 +219,25 @@ func (t *Tab) HandleEvent(event tcell.Event) {
|
||||
return
|
||||
}
|
||||
|
||||
resizeID := t.GetMouseSplitID(buffer.Loc{mx, my})
|
||||
if resizeID != 0 {
|
||||
t.resizing = t.GetNode(uint64(resizeID))
|
||||
return
|
||||
}
|
||||
if wasReleased {
|
||||
resizeID := t.GetMouseSplitID(buffer.Loc{mx, my})
|
||||
if resizeID != 0 {
|
||||
t.resizing = t.GetNode(uint64(resizeID))
|
||||
return
|
||||
}
|
||||
|
||||
for i, p := range t.Panes {
|
||||
v := p.GetView()
|
||||
inpane := mx >= v.X && mx < v.X+v.Width && my >= v.Y && my < v.Y+v.Height
|
||||
if inpane {
|
||||
t.SetActive(i)
|
||||
break
|
||||
for i, p := range t.Panes {
|
||||
v := p.GetView()
|
||||
inpane := mx >= v.X && mx < v.X+v.Width && my >= v.Y && my < v.Y+v.Height
|
||||
if inpane {
|
||||
t.SetActive(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
case tcell.ButtonNone:
|
||||
t.resizing = nil
|
||||
t.release = true
|
||||
default:
|
||||
for _, p := range t.Panes {
|
||||
v := p.GetView()
|
||||
|
||||
@@ -4,7 +4,7 @@ package action
|
||||
|
||||
import (
|
||||
shellquote "github.com/kballard/go-shellquote"
|
||||
"github.com/zyedidia/micro/internal/shell"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
)
|
||||
|
||||
// TermEmuSupported is a constant that marks if the terminal emulator is supported
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"runtime"
|
||||
|
||||
"github.com/zyedidia/clipboard"
|
||||
"github.com/zyedidia/micro/internal/display"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/shell"
|
||||
"github.com/zyedidia/micro/v2/internal/display"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
"github.com/zyedidia/tcell"
|
||||
"github.com/zyedidia/terminal"
|
||||
)
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
// A Completer is a function that takes a buffer and returns info
|
||||
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"golang.org/x/text/encoding"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@ import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -19,11 +20,11 @@ import (
|
||||
luar "layeh.com/gopher-luar"
|
||||
|
||||
dmp "github.com/sergi/go-diff/diffmatchpatch"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/pkg/highlight"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
ulua "github.com/zyedidia/micro/v2/internal/lua"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"github.com/zyedidia/micro/v2/pkg/highlight"
|
||||
"golang.org/x/text/encoding/htmlindex"
|
||||
"golang.org/x/text/encoding/unicode"
|
||||
"golang.org/x/text/transform"
|
||||
@@ -60,6 +61,9 @@ var (
|
||||
BTRaw = BufType{4, false, true, false}
|
||||
// BTInfo is a buffer for inputting information
|
||||
BTInfo = BufType{5, false, true, false}
|
||||
// BTStdout is a buffer that only writes to stdout
|
||||
// when closed
|
||||
BTStdout = BufType{6, false, true, true}
|
||||
|
||||
// ErrFileTooLarge is returned when the file is too large to hash
|
||||
// (fastdirty is automatically enabled)
|
||||
@@ -75,6 +79,34 @@ 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
|
||||
|
||||
toStdout bool
|
||||
|
||||
// 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 +116,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 +133,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 +190,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 +244,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 +255,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 +301,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 +322,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 +331,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
|
||||
@@ -341,18 +361,26 @@ func (b *Buffer) Fini() {
|
||||
b.Serialize()
|
||||
}
|
||||
b.RemoveBackup()
|
||||
|
||||
if b.Type == BTStdout {
|
||||
fmt.Fprint(util.Stdout, string(b.Bytes()))
|
||||
}
|
||||
}
|
||||
|
||||
// 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 +410,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)
|
||||
@@ -530,7 +548,37 @@ func (b *Buffer) UpdateRules() {
|
||||
return
|
||||
}
|
||||
syntaxFile := ""
|
||||
foundDef := false
|
||||
var header *highlight.Header
|
||||
// search for the syntax file in the user's custom syntax files
|
||||
for _, f := range config.ListRealRuntimeFiles(config.RTSyntax) {
|
||||
data, err := f.Data()
|
||||
if err != nil {
|
||||
screen.TermMessage("Error loading syntax file " + f.Name() + ": " + err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
header, err = highlight.MakeHeaderYaml(data)
|
||||
file, err := highlight.ParseFile(data)
|
||||
if err != nil {
|
||||
screen.TermMessage("Error parsing syntax file " + f.Name() + ": " + err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
if ((ft == "unknown" || ft == "") && highlight.MatchFiletype(header.FtDetect, b.Path, b.lines[0].data)) || 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
|
||||
}
|
||||
}
|
||||
|
||||
// search in the default syntax files
|
||||
for _, f := range config.ListRuntimeFiles(config.RTSyntaxHeader) {
|
||||
data, err := f.Data()
|
||||
if err != nil {
|
||||
@@ -555,34 +603,8 @@ 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())
|
||||
continue
|
||||
}
|
||||
|
||||
header, err = highlight.MakeHeaderYaml(data)
|
||||
file, err := highlight.ParseFile(data)
|
||||
if err != nil {
|
||||
screen.TermMessage("Error parsing syntax file " + f.Name() + ": " + err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
if ((ft == "unknown" || ft == "") && highlight.MatchFiletype(header.FtDetect, b.Path, b.lines[0].data)) || 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
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if syntaxFile != "" && !foundDef {
|
||||
// we found a syntax file using a syntax header file
|
||||
for _, f := range config.ListRuntimeFiles(config.RTSyntax) {
|
||||
if f.Name() == syntaxFile {
|
||||
data, err := f.Data()
|
||||
@@ -776,7 +798,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 +943,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
113
internal/buffer/buffer_test.go
Normal file
113
internal/buffer/buffer_test.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package buffer
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
testifyAssert "github.com/stretchr/testify/assert"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
|
||||
ulua "github.com/zyedidia/micro/v2/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()
|
||||
b.Insert(cursor.Loc, strings.Join(op.text, "\n"))
|
||||
}
|
||||
|
||||
checkText(after)
|
||||
|
||||
// must have exactly two events per operation (delete and insert)
|
||||
for range operations {
|
||||
b.UndoOneEvent()
|
||||
b.UndoOneEvent()
|
||||
}
|
||||
|
||||
checkText(before)
|
||||
|
||||
for i, op := range operations {
|
||||
cursor := cursors[i]
|
||||
if op.start == op.end {
|
||||
assert.Equal(op.start, cursor.Loc)
|
||||
} else {
|
||||
assert.Equal(op.start, cursor.CurSelection[0])
|
||||
assert.Equal(op.end, cursor.CurSelection[1])
|
||||
}
|
||||
}
|
||||
|
||||
for range operations {
|
||||
b.RedoOneEvent()
|
||||
b.RedoOneEvent()
|
||||
}
|
||||
|
||||
checkText(after)
|
||||
|
||||
b.Close()
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/zyedidia/clipboard"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
// InBounds returns whether the given location is a valid character position in the given buffer
|
||||
@@ -109,6 +109,19 @@ func (c *Cursor) StartOfText() {
|
||||
}
|
||||
}
|
||||
|
||||
// IsStartOfText returns whether the cursor is at the first
|
||||
// non-whitespace rune of the line it is on
|
||||
func (c *Cursor) IsStartOfText() bool {
|
||||
x := 0
|
||||
for util.IsWhitespace(c.RuneUnder(x)) {
|
||||
if x == utf8.RuneCount(c.buf.LineBytes(c.Y)) {
|
||||
break
|
||||
}
|
||||
x++
|
||||
}
|
||||
return c.X == x
|
||||
}
|
||||
|
||||
// End moves the cursor to the end of the line it is on
|
||||
func (c *Cursor) End() {
|
||||
c.X = utf8.RuneCount(c.buf.LineBytes(c.Y))
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"unicode/utf8"
|
||||
|
||||
dmp "github.com/sergi/go-diff/diffmatchpatch"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
ulua "github.com/zyedidia/micro/v2/internal/lua"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
luar "layeh.com/gopher-luar"
|
||||
)
|
||||
|
||||
@@ -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
|
||||
@@ -264,10 +281,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
|
||||
@@ -313,9 +329,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 +337,8 @@ func (eh *EventHandler) RedoOneEvent() {
|
||||
teCursor.Num = -1
|
||||
}
|
||||
|
||||
// Modifies the text event
|
||||
eh.UndoTextEvent(t)
|
||||
|
||||
eh.UndoStack.Push(t)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@ package buffer
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/zyedidia/micro/pkg/highlight"
|
||||
"github.com/zyedidia/micro/v2/pkg/highlight"
|
||||
)
|
||||
|
||||
// Finds the byte index of the nth rune in a byte slice
|
||||
@@ -152,17 +153,19 @@ func NewLineArray(size uint64, endings FileFormat, reader io.Reader) *LineArray
|
||||
// Bytes returns the string that should be written to disk when
|
||||
// the line array is saved
|
||||
func (la *LineArray) Bytes() []byte {
|
||||
str := make([]byte, 0, la.initsize+1000) // initsize should provide a good estimate
|
||||
b := new(bytes.Buffer)
|
||||
// initsize should provide a good estimate
|
||||
b.Grow(int(la.initsize + 4096))
|
||||
for i, l := range la.lines {
|
||||
str = append(str, l.data...)
|
||||
b.Write(l.data)
|
||||
if i != len(la.lines)-1 {
|
||||
if la.Endings == FFDos {
|
||||
str = append(str, '\r')
|
||||
b.WriteByte('\r')
|
||||
}
|
||||
str = append(str, '\n')
|
||||
b.WriteByte('\n')
|
||||
}
|
||||
}
|
||||
return str
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
// newlineBelow adds a newline below the given line number
|
||||
|
||||
@@ -3,7 +3,7 @@ package buffer
|
||||
import (
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
// Loc stores a location
|
||||
@@ -102,7 +102,7 @@ func (l Loc) left(buf *LineArray) Loc {
|
||||
return res
|
||||
}
|
||||
|
||||
// Move moves the cursor n characters to the left or right
|
||||
// MoveLA moves the cursor n characters to the left or right
|
||||
// It moves the cursor left if n is negative
|
||||
func (l Loc) MoveLA(n int, buf *LineArray) Loc {
|
||||
if n > 0 {
|
||||
@@ -117,9 +117,12 @@ func (l Loc) MoveLA(n int, buf *LineArray) Loc {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l Loc) Diff(a, b Loc, buf *Buffer) int {
|
||||
return DiffLA(a, b, buf.LineArray)
|
||||
// Diff returns the difference between two locs
|
||||
func (l Loc) Diff(b Loc, buf *Buffer) int {
|
||||
return DiffLA(l, b, buf.LineArray)
|
||||
}
|
||||
|
||||
// Move moves a loc n characters
|
||||
func (l Loc) Move(n int, buf *Buffer) Loc {
|
||||
return l.MoveLA(n, buf.LineArray)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package buffer
|
||||
|
||||
import (
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"golang.org/x/text/encoding"
|
||||
"golang.org/x/text/encoding/htmlindex"
|
||||
"golang.org/x/text/transform"
|
||||
@@ -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'})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"regexp"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
func (b *Buffer) findDown(r *regexp.Regexp, start, end Loc) ([2]Loc, bool) {
|
||||
@@ -120,24 +120,27 @@ func (b *Buffer) FindNext(s string, start, end, from Loc, down bool, useRegex bo
|
||||
if down {
|
||||
l, found = b.findDown(r, from, end)
|
||||
if !found {
|
||||
l, found = b.findDown(r, start, from)
|
||||
l, found = b.findDown(r, start, end)
|
||||
}
|
||||
} else {
|
||||
l, found = b.findUp(r, from, start)
|
||||
if !found {
|
||||
l, found = b.findUp(r, end, from)
|
||||
l, found = b.findUp(r, end, start)
|
||||
}
|
||||
}
|
||||
return l, found, nil
|
||||
}
|
||||
|
||||
// ReplaceRegex replaces all occurrences of 'search' with 'replace' in the given area
|
||||
// and returns the number of replacements made
|
||||
func (b *Buffer) ReplaceRegex(start, end Loc, search *regexp.Regexp, replace []byte) int {
|
||||
// and returns the number of replacements made and the number of runes
|
||||
// added or removed
|
||||
func (b *Buffer) ReplaceRegex(start, end Loc, search *regexp.Regexp, replace []byte) (int, int) {
|
||||
if start.GreaterThan(end) {
|
||||
start, end = end, start
|
||||
}
|
||||
|
||||
netrunes := 0
|
||||
|
||||
found := 0
|
||||
var deltas []Delta
|
||||
for i := start.Y; i <= end.Y; i++ {
|
||||
@@ -155,8 +158,13 @@ func (b *Buffer) ReplaceRegex(start, end Loc, search *regexp.Regexp, replace []b
|
||||
l = util.SliceStart(l, end.X)
|
||||
}
|
||||
newText := search.ReplaceAllFunc(l, func(in []byte) []byte {
|
||||
result := []byte{}
|
||||
for _, submatches := range search.FindAllSubmatchIndex(in, -1) {
|
||||
result = search.Expand(result, replace, in, submatches)
|
||||
}
|
||||
found++
|
||||
return replace
|
||||
netrunes += utf8.RuneCount(in) - utf8.RuneCount(result)
|
||||
return result
|
||||
})
|
||||
|
||||
from := Loc{charpos, i}
|
||||
@@ -166,5 +174,5 @@ func (b *Buffer) ReplaceRegex(start, end Loc, search *regexp.Regexp, replace []b
|
||||
}
|
||||
b.MultipleReplace(deltas)
|
||||
|
||||
return found
|
||||
return found, netrunes
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
"golang.org/x/text/encoding"
|
||||
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
// The SerializedBuffer holds the types that get serialized when a buffer is saved
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package buffer
|
||||
|
||||
import (
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
)
|
||||
|
||||
func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"log"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
ulua "github.com/zyedidia/micro/v2/internal/lua"
|
||||
)
|
||||
|
||||
// ErrNoSuchFunction is returned when Call is executed on a function that does not exist
|
||||
|
||||
@@ -16,8 +16,8 @@ import (
|
||||
"github.com/blang/semver"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
"github.com/zyedidia/json5"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
ulua "github.com/zyedidia/micro/v2/internal/lua"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/zyedidia/glob"
|
||||
"github.com/zyedidia/json5"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"golang.org/x/text/encoding/htmlindex"
|
||||
)
|
||||
|
||||
@@ -184,15 +184,15 @@ func GetGlobalOption(name string) interface{} {
|
||||
|
||||
var defaultCommonSettings = map[string]interface{}{
|
||||
"autoindent": true,
|
||||
"autosu": true,
|
||||
"autosu": false,
|
||||
"backup": true,
|
||||
"basename": false,
|
||||
"colorcolumn": float64(0),
|
||||
"cursorline": true,
|
||||
"diffgutter": false,
|
||||
"encoding": "utf-8",
|
||||
"eofnewline": false,
|
||||
"fastdirty": true,
|
||||
"eofnewline": true,
|
||||
"fastdirty": false,
|
||||
"fileformat": "unix",
|
||||
"filetype": "unknown",
|
||||
"ignorecase": false,
|
||||
@@ -256,6 +256,7 @@ var DefaultGlobalOnlySettings = map[string]interface{}{
|
||||
"sucmd": "sudo",
|
||||
"pluginchannels": []string{"https://raw.githubusercontent.com/micro-editor/plugin-channel/master/channel.json"},
|
||||
"pluginrepos": []string{},
|
||||
"xterm": false,
|
||||
}
|
||||
|
||||
// a list of settings that should never be globally modified
|
||||
|
||||
@@ -5,10 +5,10 @@ import (
|
||||
"unicode/utf8"
|
||||
|
||||
runewidth "github.com/mattn/go-runewidth"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
@@ -136,9 +136,6 @@ func (w *BufWindow) Relocate() bool {
|
||||
if w.drawStatus {
|
||||
h--
|
||||
}
|
||||
if b.LinesNum() <= h {
|
||||
height = w.Height
|
||||
}
|
||||
ret := false
|
||||
activeC := w.Buf.GetActiveCursor()
|
||||
cy := activeC.Y
|
||||
@@ -275,14 +272,7 @@ func (w *BufWindow) LocFromVisual(svloc buffer.Loc) buffer.Loc {
|
||||
if vloc.Y >= bufHeight {
|
||||
break
|
||||
}
|
||||
vloc.X = 0
|
||||
if b.Settings["diffgutter"].(bool) {
|
||||
vloc.X++
|
||||
}
|
||||
// This will draw an empty line number because the current line is wrapped
|
||||
if b.Settings["ruler"].(bool) {
|
||||
vloc.X += maxLineNumLength + 1
|
||||
}
|
||||
vloc.X = w.gutterOffset
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -407,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
|
||||
@@ -436,6 +412,7 @@ func (w *BufWindow) displayBuffer() {
|
||||
}
|
||||
})
|
||||
}
|
||||
b.ModifiedThisFrame = false
|
||||
}
|
||||
|
||||
var matchingBraces []buffer.Loc
|
||||
@@ -579,7 +556,7 @@ func (w *BufWindow) displayBuffer() {
|
||||
}
|
||||
|
||||
if s, ok := config.Colorscheme["color-column"]; ok {
|
||||
if colorcolumn != 0 && vloc.X-w.gutterOffset == colorcolumn {
|
||||
if colorcolumn != 0 && vloc.X-w.gutterOffset+w.StartCol == colorcolumn {
|
||||
fg, _, _ := s.Decompose()
|
||||
style = style.Background(fg)
|
||||
}
|
||||
@@ -645,9 +622,13 @@ func (w *BufWindow) displayBuffer() {
|
||||
break
|
||||
}
|
||||
vloc.X = 0
|
||||
if hasMessage {
|
||||
w.drawGutter(&vloc, &bloc)
|
||||
}
|
||||
if b.Settings["diffgutter"].(bool) {
|
||||
w.drawDiffGutter(lineNumStyle, true, &vloc, &bloc)
|
||||
}
|
||||
|
||||
// This will draw an empty line number because the current line is wrapped
|
||||
if b.Settings["ruler"].(bool) {
|
||||
w.drawLineNum(lineNumStyle, true, maxLineNumLength, &vloc, &bloc)
|
||||
@@ -669,7 +650,7 @@ func (w *BufWindow) displayBuffer() {
|
||||
for i := vloc.X; i < bufWidth; i++ {
|
||||
curStyle := style
|
||||
if s, ok := config.Colorscheme["color-column"]; ok {
|
||||
if colorcolumn != 0 && i-w.gutterOffset == colorcolumn {
|
||||
if colorcolumn != 0 && i-w.gutterOffset+w.StartCol == colorcolumn {
|
||||
fg, _, _ := s.Decompose()
|
||||
curStyle = style.Background(fg)
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"unicode/utf8"
|
||||
|
||||
runewidth "github.com/mattn/go-runewidth"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/info"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/info"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
@@ -209,13 +209,13 @@ func (i *InfoWindow) scrollToSuggestion() {
|
||||
}
|
||||
|
||||
func (i *InfoWindow) Display() {
|
||||
i.Clear()
|
||||
x := 0
|
||||
if config.GetGlobalOption("keymenu").(bool) {
|
||||
i.displayKeyMenu()
|
||||
}
|
||||
|
||||
if i.HasPrompt || config.GlobalSettings["infobar"].(bool) {
|
||||
i.Clear()
|
||||
x := 0
|
||||
if config.GetGlobalOption("keymenu").(bool) {
|
||||
i.displayKeyMenu()
|
||||
}
|
||||
|
||||
if !i.HasPrompt && !i.HasMessage && !i.HasError {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package display
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -13,11 +12,11 @@ import (
|
||||
|
||||
runewidth "github.com/mattn/go-runewidth"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
ulua "github.com/zyedidia/micro/v2/internal/lua"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
// StatusLine represents the information line at the bottom
|
||||
@@ -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 {
|
||||
|
||||
@@ -4,10 +4,10 @@ import (
|
||||
"unicode/utf8"
|
||||
|
||||
runewidth "github.com/mattn/go-runewidth"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
type TabWindow struct {
|
||||
@@ -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++
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ package display
|
||||
import (
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/shell"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
"github.com/zyedidia/tcell"
|
||||
"github.com/zyedidia/terminal"
|
||||
)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package display
|
||||
|
||||
import (
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/views"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/views"
|
||||
)
|
||||
|
||||
type UIWindow struct {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package display
|
||||
|
||||
import (
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
)
|
||||
|
||||
type View struct {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
)
|
||||
|
||||
// LoadHistory attempts to load user history from configDir/buffers/history
|
||||
|
||||
@@ -3,7 +3,7 @@ package info
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
)
|
||||
|
||||
// The InfoBuf displays messages and other info at the bottom of the screen.
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
@@ -136,6 +136,12 @@ func Init() {
|
||||
os.Setenv("TCELL_TRUECOLOR", "disable")
|
||||
}
|
||||
|
||||
var oldTerm string
|
||||
if config.GetGlobalOption("xterm").(bool) {
|
||||
oldTerm = os.Getenv("TERM")
|
||||
os.Setenv("TERM", "xterm-256color")
|
||||
}
|
||||
|
||||
// Initilize tcell
|
||||
var err error
|
||||
Screen, err = tcell.NewScreen()
|
||||
@@ -149,6 +155,11 @@ func Init() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// restore TERM
|
||||
if config.GetGlobalOption("xterm").(bool) {
|
||||
os.Setenv("TERM", oldTerm)
|
||||
}
|
||||
|
||||
if config.GetGlobalOption("mouse").(bool) {
|
||||
Screen.EnableMouse()
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
shellquote "github.com/kballard/go-shellquote"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
)
|
||||
|
||||
// ExecCommand executes a command using exec
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/terminal"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -30,10 +31,13 @@ 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
|
||||
|
||||
// Stdout is a buffer that is written to stdout when micro closes
|
||||
Stdout *bytes.Buffer
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -46,6 +50,7 @@ func init() {
|
||||
if runtime.GOOS == "windows" {
|
||||
FakeCursor = true
|
||||
}
|
||||
Stdout = new(bytes.Buffer)
|
||||
}
|
||||
|
||||
// SliceEnd returns a byte slice where the index is a rune index
|
||||
|
||||
34
runtime/colorschemes/dukedark-tc.micro
Normal file
34
runtime/colorschemes/dukedark-tc.micro
Normal file
@@ -0,0 +1,34 @@
|
||||
color-link color-column "#001e28"
|
||||
color-link comment "#608b4e,#001e28"
|
||||
color-link constant.bool "#fd971f,#001e28"
|
||||
color-link constant "#fd971f,#001e28"
|
||||
color-link constant.string "#a0f000,#001e28"
|
||||
color-link constant.string.char "#a0f000,#001e28"
|
||||
color-link constant.string.url "#a0f000,#001e28"
|
||||
color-link current-line-number "bold #fd971f,#001e28"
|
||||
color-link cursor-line "#001923"
|
||||
color-link default "#ffffff,#001e28"
|
||||
color-link diff-added "#00c8a0,#001e28"
|
||||
color-link diff-modified "#fd971f,#001e28"
|
||||
color-link diff-deleted "#cb4b16,#001e28"
|
||||
color-link divider "#001e28,#d0d0d0"
|
||||
color-link error "#cb4b16,#001e28"
|
||||
color-link gutter-error "#cb4b16,#001e28"
|
||||
color-link gutter-warning "#fce94f,#001e28"
|
||||
color-link identifier "#00c8a0,#001e28"
|
||||
color-link identifier.class "#00c8a0,#001e28"
|
||||
color-link indent-char "#a0a0a0,#001e28"
|
||||
color-link line-number "#a0a0a0,#001923"
|
||||
color-link preproc "bold #5aaae6,#001e28"
|
||||
color-link special "#a6e22e,#001e28"
|
||||
color-link statement "bold #5aaae6,#001e28"
|
||||
color-link statusline "#ffffff,#0078c8"
|
||||
color-link symbol "#00c8a0,#001e28"
|
||||
color-link symbol.brackets "#ffffff,#001e28"
|
||||
color-link symbol.tag "bold #5aaae6,#001e28"
|
||||
color-link tabbar "#001e28,#ffffff"
|
||||
color-link todo "#fce94f,#001e28"
|
||||
color-link type "bold #3cc83c,#001e28"
|
||||
color-link type.keyword "bold #5aaae6,#001e28"
|
||||
color-link type.extended "#ffffff,#001e28"
|
||||
color-link underlined "#608b4e,#001e28"
|
||||
34
runtime/colorschemes/dukelight-tc.micro
Normal file
34
runtime/colorschemes/dukelight-tc.micro
Normal file
@@ -0,0 +1,34 @@
|
||||
color-link color-column "#f0f0f0"
|
||||
color-link comment "#3f7f5f,#f0f0f0"
|
||||
color-link constant.bool "#641e00,#f0f0f0"
|
||||
color-link constant "#641e00,#f0f0f0"
|
||||
color-link constant.string "#0000ff,#f0f0f0"
|
||||
color-link constant.string.char "#0000ff,#f0f0f0"
|
||||
color-link constant.string.url "#0000ff,#f0f0f0"
|
||||
color-link current-line-number "bold #004080,#f0f0f0"
|
||||
color-link cursor-line "#e6e6e6"
|
||||
color-link default "#000000,#f0f0f0"
|
||||
color-link diff-added "#008040,#f0f0f0"
|
||||
color-link diff-modified "#641e00,#f0f0f0"
|
||||
color-link diff-deleted "#500000,#f0f0f0"
|
||||
color-link divider "#f0f0f0,#004080"
|
||||
color-link error "#500000,#f0f0f0"
|
||||
color-link gutter-error "#500000,#f0f0f0"
|
||||
color-link gutter-warning "#dcc800,#f0f0f0"
|
||||
color-link identifier "bold #0078a0,#f0f0f0"
|
||||
color-link identifier.class "bold #0078a0,#f0f0f0"
|
||||
color-link indent-char "#404040,#f0f0f0"
|
||||
color-link line-number "#404040,#e6e6e6"
|
||||
color-link preproc "bold #780050,#f0f0f0"
|
||||
color-link special "bold #0078a0,#f0f0f0"
|
||||
color-link statement "bold #780050,#f0f0f0"
|
||||
color-link statusline "#ffffff,#0078c8"
|
||||
color-link symbol "bold #0078a0,#f0f0f0"
|
||||
color-link symbol.brackets "#000000,#f0f0f0"
|
||||
color-link symbol.tag "bold #780050,#f0f0f0"
|
||||
color-link tabbar "#f0f0f0,#004080"
|
||||
color-link todo "#dcc800,#f0f0f0"
|
||||
color-link type "bold #004080,#f0f0f0"
|
||||
color-link type.keyword "bold #780050,#f0f0f0"
|
||||
color-link type.extended "#000000,#f0f0f0"
|
||||
color-link underlined "#3f7f5f,#f0f0f0"
|
||||
34
runtime/colorschemes/dukeubuntu-tc.micro
Normal file
34
runtime/colorschemes/dukeubuntu-tc.micro
Normal file
@@ -0,0 +1,34 @@
|
||||
color-link color-column "#2d0023"
|
||||
color-link comment "#886484,#2d0023"
|
||||
color-link constant.bool "#fd971f,#2d0023"
|
||||
color-link constant "#fd971f,#2d0023"
|
||||
color-link constant.string "#a0f000,#2d0023"
|
||||
color-link constant.string.char "#a0f000,#2d0023"
|
||||
color-link constant.string.url "#a0f000,#2d0023"
|
||||
color-link current-line-number "bold #fd971f,#2d0023"
|
||||
color-link cursor-line "#230019"
|
||||
color-link default "#ffffff,#2d0023"
|
||||
color-link diff-added "#00c8a0,#2d0023"
|
||||
color-link diff-modified "#fd971f,#2d0023"
|
||||
color-link diff-deleted "#cb4b16,#2d0023"
|
||||
color-link divider "#2d0023,#d0d0d0"
|
||||
color-link error "#cb4b16,#2d0023"
|
||||
color-link gutter-error "#cb4b16,#2d0023"
|
||||
color-link gutter-warning "#fce94f,#2d0023"
|
||||
color-link identifier "#00c8a0,#2d0023"
|
||||
color-link identifier.class "#00c8a0,#2d0023"
|
||||
color-link indent-char "#a0a0a0,#2d0023"
|
||||
color-link line-number "#a0a0a0,#230019"
|
||||
color-link preproc "bold #5aaae6,#2d0023"
|
||||
color-link special "#a6e22e,#2d0023"
|
||||
color-link statement "bold #5aaae6,#2d0023"
|
||||
color-link statusline "#ffffff,#0078c8"
|
||||
color-link symbol "#00c8a0,#2d0023"
|
||||
color-link symbol.brackets "#ffffff,#2d0023"
|
||||
color-link symbol.tag "bold #5aaae6,#2d0023"
|
||||
color-link tabbar "#2d0023,#ffffff"
|
||||
color-link todo "#fce94f,#2d0023"
|
||||
color-link type "bold #3cc83c,#2d0023"
|
||||
color-link type.keyword "bold #5aaae6,#2d0023"
|
||||
color-link type.extended "#ffffff,#2d0023"
|
||||
color-link underlined "#886484,#2d0023"
|
||||
@@ -20,6 +20,8 @@ set colorscheme twilight
|
||||
Micro comes with a number of colorschemes by default. The colorschemes that you
|
||||
can display will depend on what kind of color support your terminal has.
|
||||
|
||||
Omit color-link default "[fg color],[bg color]" will make the background color match the terminal's, and transparency if set.
|
||||
|
||||
Modern terminals tend to have a palette of 16 user-configurable colors (these
|
||||
colors can often be configured in the terminal preferences), and additional
|
||||
color support comes in three flavors.
|
||||
|
||||
@@ -23,7 +23,7 @@ can change it!
|
||||
| Shift+arrows | Move and select text |
|
||||
| Alt(Ctrl on Mac)+LeftArrow | Move to the beginning of the current line |
|
||||
| Alt(Ctrl on Mac)+RightArrow | Move to the end of the current line |
|
||||
| Home | Move to the beginning of the current line |
|
||||
| Home | Move to the beginning of text on the current line |
|
||||
| End | Move to the end of the current line |
|
||||
| Ctrl(Alt on Mac)+LeftArrow | Move cursor one word left |
|
||||
| Ctrl(Alt on Mac)+RightArrow | Move cursor one word right |
|
||||
|
||||
@@ -162,6 +162,8 @@ SelectUp
|
||||
SelectDown
|
||||
SelectLeft
|
||||
SelectRight
|
||||
SelectToStartOfText
|
||||
SelectToStartOfTextToggle
|
||||
WordRight
|
||||
WordLeft
|
||||
SelectWordRight
|
||||
@@ -188,6 +190,7 @@ FindPrevious
|
||||
Undo
|
||||
Redo
|
||||
Copy
|
||||
CopyLine
|
||||
Cut
|
||||
CutLine
|
||||
DuplicateLine
|
||||
@@ -209,6 +212,8 @@ HalfPageUp
|
||||
HalfPageDown
|
||||
StartOfLine
|
||||
EndOfLine
|
||||
StartOfText
|
||||
StartOfTextToggle
|
||||
ParagraphPrevious
|
||||
ParagraphNext
|
||||
ToggleHelp
|
||||
@@ -245,6 +250,9 @@ JumpToMatchingBrace
|
||||
Autocomplete
|
||||
```
|
||||
|
||||
The `StartOfTextToggle` and `SelectToStartOfTextToggle` actions toggle between
|
||||
jumping to the start of the text (first) and start of the line.
|
||||
|
||||
You can also bind some mouse actions (these must be bound to mouse buttons)
|
||||
|
||||
```
|
||||
@@ -410,21 +418,21 @@ conventions for text editing defaults.
|
||||
"ShiftDown": "SelectDown",
|
||||
"ShiftLeft": "SelectLeft",
|
||||
"ShiftRight": "SelectRight",
|
||||
"AltLeft": "WordLeft",
|
||||
"AltRight": "WordRight",
|
||||
"AltLeft": "WordLeft", (Mac)
|
||||
"AltRight": "WordRight", (Mac)
|
||||
"AltUp": "MoveLinesUp",
|
||||
"AltDown": "MoveLinesDown",
|
||||
"CtrlShiftRight": "SelectWordRight",
|
||||
"CtrlShiftLeft": "SelectWordLeft",
|
||||
"AltLeft": "StartOfLine",
|
||||
"AltLeft": "StartOfTextToggle",
|
||||
"AltRight": "EndOfLine",
|
||||
"AltShiftRight": "SelectWordRight", (Mac)
|
||||
"AltShiftLeft": "SelectWordLeft", (Mac)
|
||||
"CtrlLeft": "StartOfText", (Mac)
|
||||
"CtrlRight": "EndOfLine", (Mac)
|
||||
"AltShiftLeft": "SelectToStartOfLine",
|
||||
"CtrlShiftLeft": "SelectToStartOfText", (Mac)
|
||||
"ShiftHome": "SelectToStartOfLine",
|
||||
"AltShiftLeft": "SelectToStartOfTextToggle",
|
||||
"CtrlShiftLeft": "SelectToStartOfTextToggle", (Mac)
|
||||
"ShiftHome": "SelectToStartOfTextToggle",
|
||||
"AltShiftRight": "SelectToEndOfLine",
|
||||
"CtrlShiftRight": "SelectToEndOfLine", (Mac)
|
||||
"ShiftEnd": "SelectToEndOfLine",
|
||||
@@ -448,7 +456,7 @@ conventions for text editing defaults.
|
||||
"CtrlP": "FindPrevious",
|
||||
"CtrlZ": "Undo",
|
||||
"CtrlY": "Redo",
|
||||
"CtrlC": "Copy",
|
||||
"CtrlC": "CopyLine|Copy",
|
||||
"CtrlX": "Cut",
|
||||
"CtrlK": "CutLine",
|
||||
"CtrlD": "DuplicateLine",
|
||||
@@ -457,7 +465,7 @@ conventions for text editing defaults.
|
||||
"CtrlT": "AddTab",
|
||||
"Alt,": "PreviousTab",
|
||||
"Alt.": "NextTab",
|
||||
"Home": "StartOfLine",
|
||||
"Home": "StartOfText",
|
||||
"End": "EndOfLine",
|
||||
"CtrlHome": "CursorStart",
|
||||
"CtrlEnd": "CursorEnd",
|
||||
|
||||
@@ -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
|
||||
@@ -95,10 +96,10 @@ Here are the available options:
|
||||
This is fast, but can be inaccurate. If `fastdirty` is off, then micro will
|
||||
hash the current buffer against a hash of the original file (created when
|
||||
the buffer was loaded). This is more accurate but obviously more resource
|
||||
intensive. This option is only for people who really care about having
|
||||
accurate modified status.
|
||||
intensive. This option will be automatically disabled if the file size
|
||||
exceeds 50KB.
|
||||
|
||||
default value: `true`
|
||||
default value: `false`
|
||||
|
||||
* `fileformat`: this determines what kind of line endings micro will use for
|
||||
the file. UNIX line endings are just `\n` (linefeed) whereas dos line
|
||||
@@ -296,11 +297,33 @@ Here are the available options:
|
||||
|
||||
default value: `true`
|
||||
|
||||
* `xterm`: micro will assume that the terminal it is running in conforms to
|
||||
`xterm-256color` regardless of what the `$TERM` variable actually contains.
|
||||
Enabling this option may cause unwanted effects if your terminal in fact
|
||||
does not conform to the `xterm-256color` standard.
|
||||
|
||||
Default value: `false`
|
||||
|
||||
---
|
||||
|
||||
Plugin options: all plugins come with a special option to enable or disable
|
||||
them. The option is a boolean with the same name as the plugin itself.
|
||||
|
||||
By default, the following plugins are provided, each with an option to enable
|
||||
or disable them:
|
||||
|
||||
* `autoclose`: automatically closes brackets, quotes, etc...
|
||||
* `comment`: provides automatic commenting for a number of languages
|
||||
* `ftoptions`: alters some default options depending on the filetype
|
||||
* `linter`: provides extensible linting for many languages
|
||||
* `literate`: provides advanced syntax highlighting for the Literate
|
||||
programming tool.
|
||||
* `status`: provides some extensions to the status line (integration with
|
||||
Git and more).
|
||||
* `diff`: integrates the `diffgutter` option with Git. If you are in a Git
|
||||
directory, the diff gutter will show changes with respect to the most
|
||||
recent Git commit rather than the diff since opening the file.
|
||||
|
||||
Any option you set in the editor will be saved to the file
|
||||
~/.config/micro/settings.json so, in effect, your configuration file will be
|
||||
created for you. If you'd like to take your configuration with you to another
|
||||
|
||||
@@ -391,6 +391,9 @@ There are 6 default plugins that come pre-installed with micro. These are
|
||||
programming tool.
|
||||
* `status`: provides some extensions to the status line (integration with
|
||||
Git and more).
|
||||
* `diff`: integrates the `diffgutter` option with Git. If you are in a Git
|
||||
directory, the diff gutter will show changes with respect to the most
|
||||
recent Git commit rather than the diff since opening the file.
|
||||
|
||||
See `> help linter`, `> help comment`, and `> help status` for additional
|
||||
documentation specific to those plugins.
|
||||
|
||||
@@ -23,6 +23,7 @@ ft["javascript"] = "// %s"
|
||||
ft["ruby"] = "# %s"
|
||||
ft["d"] = "// %s"
|
||||
ft["swift"] = "// %s"
|
||||
ft["elm"] = "-- %s"
|
||||
|
||||
function onBufferOpen(buf)
|
||||
if buf.Settings["commenttype"] == nil then
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -64,10 +66,11 @@ function init()
|
||||
end
|
||||
|
||||
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("g++", "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("hlint", "haskell", "hlint", {"%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")
|
||||
makeLinter("literate", "literate", "lit", {"-c", "%f"}, "%f:%l:%m", {}, false, true)
|
||||
@@ -102,7 +105,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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
filetype: c++
|
||||
|
||||
detect:
|
||||
filename: "\\.c(c|pp|xx)$|\\.h(h|pp|xx)$|\\.ii?$|\\.(def)$"
|
||||
filename: "\\.c(c|pp|xx)$|\\.h(h|pp|xx)$|\\.inl$|\\.ii?$|\\.(def)$"
|
||||
|
||||
rules:
|
||||
- identifier: "\\b[A-Z_][0-9A-Z_]+\\b"
|
||||
|
||||
@@ -12,6 +12,9 @@ rules:
|
||||
- statement: "\\b(debugger|switch|while|do|class|extends|super)\\b"
|
||||
- statement: "\\b(undefined|then|unless|until|loop|of|by|when)\\b"
|
||||
- constant.bool: "\\b(true|false|yes|no|on|off)\\b"
|
||||
- constant.number: "\\b[-+]?([1-9][0-9]*|0[0-7]*|0x[0-9a-fA-F]+)([uU][lL]?|[lL][uU]?)?\\b"
|
||||
- constant.number: "\\b[-+]?([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+)([EePp][+-]?[0-9]+)?[fFlL]?"
|
||||
- constant.number: "\\b[-+]?([0-9]+[EePp][+-]?[0-9]+)[fFlL]?"
|
||||
- identifier: "@[A-Za-z0-9_]*"
|
||||
|
||||
- constant.string:
|
||||
@@ -20,10 +23,23 @@ rules:
|
||||
skip: "\\\\."
|
||||
rules:
|
||||
- constant.specialChar: "\\\\."
|
||||
|
||||
- constant.string:
|
||||
start: "'"
|
||||
end: "'"
|
||||
skip: "\\\\."
|
||||
rules:
|
||||
- constant.specialChar: "\\\\."
|
||||
|
||||
|
||||
- comment:
|
||||
start: "#"
|
||||
end: "$"
|
||||
rules:
|
||||
- todo: "(TODO|XXX|FIXME):?"
|
||||
- comment:
|
||||
start: "###"
|
||||
end: "###"
|
||||
rules:
|
||||
- todo: "(TODO|XXX|FIXME)"
|
||||
|
||||
|
||||
8
runtime/syntax/csx.yaml
Normal file
8
runtime/syntax/csx.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
filetype: csharp-script
|
||||
detect:
|
||||
filename: "\\.csx$"
|
||||
header: "^#!.*/(env +)?dotnet-script( |$)"
|
||||
|
||||
rules:
|
||||
- include: "csharp"
|
||||
- preproc: "\\B(\\#!|\\#[r|load|]+\\b)"
|
||||
@@ -26,7 +26,7 @@ rules:
|
||||
|
||||
# Diffs (i.e. git commit --verbose)
|
||||
- default:
|
||||
start: "^diff"
|
||||
start: "^diff --git"
|
||||
# Diff output puts a space before file contents on each line so this
|
||||
# should never match valid diff output and extend highlighting to the
|
||||
# end of the file
|
||||
|
||||
@@ -8,13 +8,14 @@ rules:
|
||||
|
||||
# built-in objects
|
||||
- constant.bool: "\\b(true|false)\\b"
|
||||
- constant: "\\b(nothing|missing)\\b"
|
||||
# built-in attributes
|
||||
- constant: "__[A-Za-z0-9_]+__"
|
||||
# definitions
|
||||
- identifier: "[A-Za-z_][A-Za-z0-9_]*[[:space:]]*[(]"
|
||||
# keywords
|
||||
- statement: "\\b(baremodule|begin|break|catch|const|continue|do|else|elseif|end|export|finally|for|function|global|if|import|let|local|macro|module|quote|return|struct|try|using|while)\\b"
|
||||
- statement: "\\b(abstract type|primitive type|mutable struct\\b)"
|
||||
- statement: "\\b(abstract\\s+type|primitive\\s+type|mutable\\s+struct)\\b"
|
||||
# decorators
|
||||
- identifier.macro: "@[A-Za-z0-9_]+"
|
||||
# operators
|
||||
@@ -22,7 +23,7 @@ rules:
|
||||
# parentheses
|
||||
- symbol.brackets: "([(){}]|\\[|\\])"
|
||||
# numbers
|
||||
- constant.number: "\\b([0-9]+(_[0-9]+)*|0x[0-9a-fA-F]+(_[0-9a-fA-F]+)*|0b[01]+(_[01]+)*|0o[0-7]+(_[0-7]+)*)\\b"
|
||||
- constant.number: "\\b([0-9]+(_[0-9]+)*|0x[0-9a-fA-F]+(_[0-9a-fA-F]+)*|0b[01]+(_[01]+)*|0o[0-7]+(_[0-7]+)*|Inf(16|32|64)?|NaN(16|32|64)?)\\b"
|
||||
|
||||
- constant.string: "\"(\\\\.|[^\"])*\"|'(\\\\.|[^']){1}'"
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
filetype: python
|
||||
filetype: python2
|
||||
|
||||
detect:
|
||||
filename: "\\.py$"
|
||||
header: "^#!.*/(env +)?python( |$)"
|
||||
filename: "\\.py2$"
|
||||
header: "^#!.*/(env +)?python2$"
|
||||
|
||||
rules:
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
filename: python3
|
||||
filetype: python
|
||||
|
||||
detect:
|
||||
filename: "\\.py3$"
|
||||
header: "^#!.*/(env +)?python3$"
|
||||
filename: "\\.py(3)?$"
|
||||
header: "^#!.*/(env +)?python(3)?$"
|
||||
|
||||
rules:
|
||||
# built-in objects
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
filetype: ruby
|
||||
|
||||
detect:
|
||||
filename: "\\.(rb|rake|gemspec)$|^(Gemfile|config.ru|Rakefile|Capfile|Vagrantfile|Guardfile)$"
|
||||
filename: "\\.(rb|rake|gemspec)$|^(Gemfile|config.ru|Rakefile|Capfile|Vagrantfile|Guardfile|Appfile|Fastfile|Pluginfile|Podfile)$"
|
||||
header: "^#!.*/(env +)?ruby( |$)"
|
||||
|
||||
rules:
|
||||
|
||||
60
runtime/syntax/sage.yaml
Normal file
60
runtime/syntax/sage.yaml
Normal file
@@ -0,0 +1,60 @@
|
||||
filetype: sage
|
||||
|
||||
detect:
|
||||
filename: "\\.sage$"
|
||||
header: "^#!.*/(env +)?sage( |$)"
|
||||
|
||||
rules:
|
||||
|
||||
# built-in objects
|
||||
- constant: "\\b(None|self|True|False)\\b"
|
||||
# built-in attributes
|
||||
- constant: "\\b(__bases__|__builtin__|__class__|__debug__|__dict__|__doc__|__file__|__members__|__methods__|__name__|__self__)\\b"
|
||||
# built-in functions
|
||||
- identifier: "\\b(abs|apply|callable|chr|cmp|compile|delattr|dir|divmod|eval|exec|execfile|filter|format|getattr|globals|hasattr|hash|help|hex|id|input|intern|isinstance|issubclass|len|locals|max|min|next|oct|open|ord|pow|range|raw_input|reduce|reload|repr|round|setattr|unichr|vars|zip|__import__)\\b"
|
||||
# special method names
|
||||
- identifier: "\\b(__abs__|__add__|__and__|__call__|__cmp__|__coerce__|__complex__|__concat__|__contains__|__del__|__delattr__|__delitem__|__dict__|__delslice__|__div__|__divmod__|__float__|__getattr__|__getitem__|__getslice__|__hash__|__hex__|__init__|__int__|__inv__|__invert__|__len__|__long__|__lshift__|__mod__|__mul__|__neg__|__nonzero__|__oct__|__or__|__pos__|__pow__|__radd__|__rand__|__rcmp__|__rdiv__|__rdivmod__|__repeat__|__repr__|__rlshift__|__rmod__|__rmul__|__ror__|__rpow__|__rrshift__|__rshift__|__rsub__|__rxor__|__setattr__|__setitem__|__setslice__|__str__|__sub__|__xor__)\\b"
|
||||
# types
|
||||
- type: "\\b(basestring|bool|buffer|bytearray|bytes|classmethod|complex|dict|enumerate|file|float|frozenset|int|list|long|map|memoryview|object|property|reversed|set|slice|staticmethod|str|super|tuple|type|unicode|xrange)\\b"
|
||||
# definitions
|
||||
- identifier: "def [a-zA-Z_0-9]+"
|
||||
# keywords
|
||||
- statement: "\\b(and|as|assert|break|class|continue|def|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield)\\b"
|
||||
# decorators
|
||||
- brightgreen: "@.*[(]"
|
||||
# operators
|
||||
- statement: "([.:;,+*|=!\\%@]|<|>|/|-|&)"
|
||||
# parentheses
|
||||
- statement: "([(){}]|\\[|\\])"
|
||||
# numbers
|
||||
- constant.number: "\\b[0-9]+\\b"
|
||||
|
||||
- comment:
|
||||
start: "\"\"\""
|
||||
end: "\"\"\""
|
||||
rules: []
|
||||
|
||||
- comment:
|
||||
start: "'''"
|
||||
end: "'''"
|
||||
rules: []
|
||||
|
||||
- constant.string:
|
||||
start: "\""
|
||||
end: "\""
|
||||
skip: "\\\\."
|
||||
rules:
|
||||
- constant.specialChar: "\\\\."
|
||||
|
||||
- constant.string:
|
||||
start: "'"
|
||||
end: "'"
|
||||
skip: "\\\\."
|
||||
rules:
|
||||
- constant.specialChar: "\\\\."
|
||||
|
||||
- comment:
|
||||
start: "#"
|
||||
end: "$"
|
||||
rules: []
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
filetype: v
|
||||
|
||||
detect:
|
||||
filename: "\\.v$"
|
||||
|
||||
rules:
|
||||
# Conditionals and control flow
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
filetype: verilog
|
||||
|
||||
detect:
|
||||
filename: "\\.(vh|sv|svh)$"
|
||||
filename: "\\.(v|vh|sv|svh)$"
|
||||
|
||||
rules:
|
||||
- preproc: "\\b(module|package|program|endmodule|endpackage|endprogram)\\b"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name: micro
|
||||
version: git
|
||||
summary: A modern and intuitive terminal-based text editor
|
||||
description: |
|
||||
Micro is a terminal-based text editor that aims to be easy to use and
|
||||
intuitive, while also taking advantage of the full capabilities of modern
|
||||
terminals.
|
||||
confinement: classic
|
||||
adopt-info: micro
|
||||
|
||||
apps:
|
||||
micro:
|
||||
@@ -19,7 +19,13 @@ parts:
|
||||
build-packages: [make]
|
||||
build-snaps: [go]
|
||||
build-attributes: [no-patchelf]
|
||||
override-pull: |
|
||||
snapcraftctl pull
|
||||
version="$(go run $SNAPCRAFT_PART_SRC/tools/build-version.go)"
|
||||
[ -n "$(echo $version | grep "dev")" ] && grade=devel || grade=stable
|
||||
snapcraftctl set-version "$version"
|
||||
snapcraftctl set-grade "$grade"
|
||||
override-build: |
|
||||
make build
|
||||
make build-tags
|
||||
mkdir $SNAPCRAFT_PART_INSTALL/bin
|
||||
mv ./micro $SNAPCRAFT_PART_INSTALL/bin/
|
||||
|
||||
@@ -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:
|
||||
|
||||
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