Compare commits

..

152 Commits

Author SHA1 Message Date
Zachary Yedidia
d03a5fc998 Fix tcell import 2016-09-06 11:29:51 -04:00
Zachary Yedidia
ef4a385380 Fix variable name bug 2016-09-06 11:29:51 -04:00
Zachary Yedidia
a1fcbde863 Make database from terminfo if terminal entry is not found 2016-09-06 11:29:51 -04:00
Zachary Yedidia
c0282c4a3c Add issue template 2016-09-06 11:24:55 -04:00
Zachary Yedidia
0a6e1de404 Merge branch 'boombuler-params' 2016-09-06 10:59:46 -04:00
Zachary Yedidia
131524e670 Merge branch 'params' of https://github.com/boombuler/micro into boombuler-params 2016-09-06 10:59:30 -04:00
Zachary Yedidia
539495d2f7 Add support for macros
Closes #270

CtrlU to toggle recording and CtrlJ to playback.
You can also rebind using the "ToggleMacro" and "PlayMacro"
actions.

Note that recursive macros are not yet supported.
2016-09-06 10:44:15 -04:00
Zachary Yedidia
966dac97f8 Make unsaved changes prompt more clear
Fixes #301
2016-09-06 10:06:36 -04:00
Zachary Yedidia
bf6e596808 Merge pull request #323 from zonuexe/php-keywords
Add PHP Keywords
2016-09-06 07:24:22 -04:00
USAMI Kenta
efa24f5a8d Add PHP Keywords
- trait (PHP 5.5)
- iterable (PHP 7.1)
- void (PHP 7.1)

see https://github.com/ejmr/php-mode/pull/317
2016-09-06 18:25:08 +09:00
Zachary Yedidia
432146b068 Merge pull request #318 from elopio/update_runtime
Update runtime
2016-09-05 16:12:26 -04:00
Leo Arias
02b6eaaff0 Update runtime
closes #317
2016-09-05 18:31:36 +00:00
Zachary Yedidia
dc532e337b Merge pull request #315 from boombuler/pascal
added pascal syntax
2016-09-05 12:10:56 -04:00
boombuler
a952e249b4 added pascal syntax 2016-09-05 17:53:49 +02:00
Zachary Yedidia
94465ef1ae Merge 2016-09-05 11:38:16 -04:00
Zachary Yedidia
0a534767f0 Merge branch 'primary-clipboard' 2016-09-05 11:37:49 -04:00
Zachary Yedidia
7937f7038b Merge pull request #314 from mame98/master
Added some SCSS keywords for the css/scss highlighting
2016-09-05 10:50:00 -04:00
Marius Messerschmidt
d6a01ad29f Added some SCSS keywords for the css/scss highlighting
Signed-off-by: Marius Messerschmidt <marius.messerschmidt@googlemail.com>
2016-09-05 16:41:32 +02:00
Zachary Yedidia
b1cb583e8c Update runtime 2016-09-05 10:30:08 -04:00
Zachary Yedidia
ea4d822923 Merge pull request #283 from boombuler/autocompleteplugin
Autocomplete for plugins
2016-09-05 10:29:51 -04:00
Zachary Yedidia
583177feff Update readme 2016-09-05 10:29:15 -04:00
Zachary Yedidia
3bec1b8c1b Merge pull request #313 from adrianvoica/master
Updates to TypeScript dictionary.
2016-09-05 10:28:36 -04:00
Adrian Voica
b992669f5b Updates to TypeScript dictionary. 2016-09-05 17:18:41 +03:00
Zachary Yedidia
086aa61e5a Merge pull request #311 from adrianvoica/master
Added TypeScript syntax highlighting file.
2016-09-05 10:09:23 -04:00
Adrian Voica
c310053777 Added TypeScript syntax highlighting file. 2016-09-05 17:01:37 +03:00
Zachary Yedidia
2041e12eba Fix some issues with mouse selection copying 2016-09-05 08:36:30 -04:00
Zachary Yedidia
5d00522d4e Deselect for CursorStart
Fixes #308
2016-09-05 08:25:49 -04:00
Zachary Yedidia
c71e816e37 Fix recursive function 2016-09-04 21:28:40 -04:00
Zachary Yedidia
6721ec8e7d Copy to primary clipboard for any change in selection 2016-09-04 21:19:14 -04:00
Zachary Yedidia
93eadfb9dc Merge 2016-09-04 18:27:16 -04:00
Zachary Yedidia
cf3ce29a08 Fix YesNoPrompt bug 2016-09-04 18:27:11 -04:00
Zachary Yedidia
cd1117c08c Merge pull request #304 from techtonik/windate
Windows-compatible Makefile
2016-09-04 15:17:27 -04:00
anatoly techtonik
f247823936 Get build date on Windows without Python 2016-09-04 22:07:07 +03:00
Zachary Yedidia
a8feef3c12 Minor cleanup
See #300
2016-09-04 12:57:09 -04:00
Zachary Yedidia
de9707f088 Merge 2016-09-04 12:51:00 -04:00
Zachary Yedidia
9ff396c69f Don't allow setting invalid colorschemes
Fixes #303
2016-09-04 12:50:13 -04:00
anatoly techtonik
4b350d02e0 Let Go choose binary name and extension
This creates micro.exe on Windows
2016-09-04 19:38:50 +03:00
anatoly techtonik
ae3696e82d Use Python to get date in cross-platform way
I was able to build micro with Mozilla's pymake on Windows
2016-09-04 19:31:16 +03:00
Zachary Yedidia
b3f6731db5 Update runtime 2016-09-04 11:36:25 -04:00
Zachary Yedidia
2b9ef4d406 Merge 2016-09-04 11:20:18 -04:00
Zachary Yedidia
54a34001e3 Fix cursor problem in LetterPrompt
Fixes #300
2016-09-04 11:19:53 -04:00
Zachary Yedidia
aad7cc7572 Merge pull request #299 from skovsgaard/add-lfe
Add an LFE syntax file
2016-09-04 11:02:41 -04:00
Zachary Yedidia
def5e29b91 Merge pull request #302 from tanuck/align-tabs-with-spaces
Correct the number of spaces in a tab
2016-09-04 10:58:12 -04:00
James Tancock
187ea0da1c Correct the number of spaces to add when a tab is inserted at an offset cursor.
Fixes #268
2016-09-04 15:50:39 +01:00
Zachary Yedidia
5b7fa01825 Add newline to end of settings.json
Fixes #296
2016-09-04 10:10:57 -04:00
Zachary Yedidia
c38044106c Merge pull request #298 from boombuler/bug269
exit conditional replace if no match is left
2016-09-04 09:44:05 -04:00
skovsgaard
399e3a5ee1 Add an LFE syntax file 2016-09-04 11:11:30 +02:00
boombuler
fce5b81c22 exit conditional replace if no match is left 2016-09-04 09:29:26 +02:00
Zachary Yedidia
a4ac9f2b7b Merge pull request #286 from boombuler/bug269
fixes conditional replace
2016-09-03 13:45:43 -04:00
Zachary Yedidia
abedeebc0a Merge pull request #282 from boombuler/windows
File autocomplete should now work on windows
2016-09-03 13:45:19 -04:00
Zachary Yedidia
b905400892 Add default bindings for CtrlHome and CtrlEnd
Fixes #280
2016-09-03 13:37:16 -04:00
Zachary Yedidia
c4d6f5e584 Fix various infobar bugs
Fixes #294
Fixes #295
2016-09-03 13:28:48 -04:00
Zachary Yedidia
b5232dd24d Merge 2016-09-03 13:00:23 -04:00
Zachary Yedidia
89886f10c7 Update conf.micro syntax file
Fixes #290
2016-09-03 13:00:05 -04:00
Zachary Yedidia
c679500d06 Merge pull request #292 from devoncarew/fix_typo
fix a typo
2016-09-03 12:53:47 -04:00
Zachary Yedidia
76f80bf694 Merge pull request #293 from devoncarew/add_dart
add dart syntax highlighting
2016-09-03 12:53:39 -04:00
Devon Carew
a7b72f0e0e add dart syntax highlighting 2016-09-03 09:16:52 -07:00
Devon Carew
00eb6725e6 fix a typo 2016-09-03 09:16:08 -07:00
Zachary Yedidia
af22e0a567 Allow overwriting options with flags
Fixes #258

Also related to #233, this commit also changes how +LINE,COL works. Now it is
micro -startpos LINE,COL file.
2016-09-03 11:26:01 -04:00
boombuler
98b6f63b70 fixes conditional replace
before this, conditional replace always replaces the first found
occurence of the match not the currenly selected.
Might also fix #269
2016-09-03 12:34:57 +02:00
boombuler
403a99d2ea removed obsolete replace command preparations 2016-09-03 12:13:25 +02:00
boombuler
b2735d7b5b use build-in functions to quote / unquote 2016-09-03 12:02:49 +02:00
boombuler
699ad316e5 removed old code 2016-09-03 08:18:47 +02:00
boombuler
8617ae5c1f keep trailing space at commandline 2016-09-03 08:16:18 +02:00
boombuler
c5ac5be764 updated plugin help 2016-09-02 19:50:19 +02:00
boombuler
881f57b047 allow plugins to register autocomplete functions 2016-09-02 19:42:33 +02:00
Zachary Yedidia
1c2b815d95 Merge 2016-09-02 11:12:36 -04:00
Zachary Yedidia
b45fcf5bd7 Use json5 for config files 2016-09-02 11:12:16 -04:00
Zachary Yedidia
45ec01d197 Merge pull request #281 from onodera-punpun/patch-1
sh.micro: Add some linux config files that use sh.
2016-09-02 10:53:55 -04:00
Camille
0df7e59ca4 sh.micro: Add some linux config files that use sh. 2016-09-02 16:49:19 +02:00
Zachary Yedidia
89c34ed8b3 Copy to primary clipboard on mouse selection 2016-09-02 10:44:32 -04:00
Zachary Yedidia
d9b8a04841 Add support for primary clipboard 2016-09-02 09:40:08 -04:00
Florian Sundermann
ccfe08bc60 allow command parameters to be quoted
this way FileCompletions could contain space runes without
breaking the parameter.
2016-09-02 13:44:22 +02:00
Florian Sundermann
2e3ee22aca File autocomplete should now work on windows 2016-09-02 08:49:54 +02:00
Zachary Yedidia
226cf399ba Merge pull request #271 from teryanik/master
Improvement highlight php syntax
2016-09-01 20:23:53 -04:00
Zachary Yedidia
0f6260601f Merge pull request #272 from thecotne/master
improve json.micro
2016-09-01 20:23:38 -04:00
cotne nazarashvili
d2254df062 improve json.micro 2016-09-02 03:59:36 +04:00
teryanik
3e83d29fb4 improvement highlight php syntax 2016-09-01 22:24:31 +03:00
Zachary Yedidia
a432bc7e7b Fix typo in readme 2016-09-01 12:09:49 -04:00
Zachary Yedidia
486279e1d1 Update readme 2016-09-01 12:08:46 -04:00
Zachary Yedidia
3967981b38 Fix help links in readme 2016-08-31 20:05:35 -04:00
Zachary Yedidia
597c549b5b Update readme 2016-08-31 20:04:24 -04:00
Zachary Yedidia
fc2d9bb461 Merge pull request #233 from schollz/master
Flag to start at specified line/column number (#224)
2016-08-31 16:39:30 -04:00
Zachary Yedidia
832cc366af Merge 2016-08-31 14:22:19 -04:00
Zachary Yedidia
5458605618 Add "bubblegum" light colorscheme
Closes #255
2016-08-31 14:21:46 -04:00
Zachary Yedidia
104af2ef7a Merge pull request #263 from dtakahas/fix-help-typos
Fix a couple typos in help files
2016-08-31 14:08:38 -04:00
Dave Takahashi
64ff933451 Fix a couple typos in help files 2016-08-31 11:01:30 -07:00
Zachary Yedidia
031ed64305 Add colorscheme support for gentoo-ebuild
See #229
2016-08-31 12:12:23 -04:00
Zachary Yedidia
1be332a0f9 Merge 2016-08-31 12:00:28 -04:00
Zachary Yedidia
b9d4dbd5e0 Add colorscheme support for yaml
See #229
2016-08-31 11:59:43 -04:00
Zachary Yedidia
2e264b342a Fix prompts not displaying because of infobar 2016-08-31 11:52:59 -04:00
Zachary Yedidia
4972db4bf6 Merge 2016-08-31 11:16:58 -04:00
Zachary Yedidia
b70db77c29 Add infobar option to disable the message line
Fixes #257
2016-08-31 11:16:22 -04:00
Zachary Yedidia
f8612d1572 Merge pull request #259 from handicraftsman/master
ASM & Micro fix
2016-08-31 10:53:14 -04:00
Nickolay
f9d0c563e4 Fixed Micro & ASM syntax files 2016-08-31 17:50:09 +03:00
Zachary Yedidia
3105205ab8 Use text from the paste event, not the clipboard
Closes #93
2016-08-31 10:47:31 -04:00
Nickolay
ec29d592da Merge pull request #1 from zyedidia/master
Sync repos for updating ASM syntax
2016-08-31 17:41:53 +03:00
Zack Scholl
62ac9f79f2 Switched to +LINE,COL
Previously the flag was parsed for `-cursor LINE,COL`

However, emacs and nano both us `+LINE,COL` and this also makes
it easier to ignore the `+` as a filename.
2016-08-31 10:10:54 -04:00
Zachary Yedidia
a6d695f471 Merge 2016-08-31 08:51:44 -04:00
Zachary Yedidia
59d2fa81dd Unselect for cursor movement actions
Fixes #250
2016-08-31 08:51:24 -04:00
Zachary Yedidia
4003586456 Merge pull request #253 from xDShot/patch-1
Update ini.micro
2016-08-31 08:36:54 -04:00
Zachary Yedidia
be44dc3ff5 Merge pull request #256 from handicraftsman/master
Added .micro syntax theme
2016-08-31 08:36:31 -04:00
Nickolay
c59b1ea387 Added .micro syntax theme 2016-08-31 15:19:45 +03:00
xDShot
00089a7c01 Update ini.micro 2016-08-31 12:06:46 +03:00
Zachary Yedidia
c661c65c8c Update help to give quick instructions on quitting and saving 2016-08-30 21:29:41 -04:00
Zachary Yedidia
13da5ced15 Fix problem with linter.onSave calling view.Save
Fixes #246
2016-08-30 19:38:45 -04:00
Zachary Yedidia
b970b393f2 Add caddyfile to runtime 2016-08-30 19:32:26 -04:00
Zachary Yedidia
30323116a5 Merge pull request #247 from mholt/patch-1
Add Caddyfile syntax
2016-08-30 19:30:46 -04:00
Matt Holt
2fc274da7d Add Caddyfile syntax 2016-08-30 17:22:55 -06:00
Zachary Yedidia
b19b36d113 Update syntax file readme
Fixes #245
2016-08-30 18:08:26 -04:00
Zachary Yedidia
b6f5db3692 Add QuitAll action to close all splits and tabs at once
See #239
2016-08-30 17:38:46 -04:00
Zachary Yedidia
8bdaacaa5e Switch splits on mouse *click* not drag
Fixes #240
2016-08-30 17:29:49 -04:00
Zachary Yedidia
c9ead25b1e Merge 2016-08-30 17:26:05 -04:00
Zachary Yedidia
ddff950fcd Check for filetype after saving an untitled buffer
Fixes #242
2016-08-30 17:25:30 -04:00
Zachary Yedidia
ed6be89d5c Merge pull request #241 from handicraftsman/master
ASM Support
2016-08-30 17:21:14 -04:00
Nickolay
6e63472930 Whooops! 2016-08-31 00:08:37 +03:00
Nickolay
94397a90bd Fully finished ASM syntax highlightig 2016-08-31 00:03:22 +03:00
Nickolay
216bfaca7e Added SIMD, Crypto and undocumented instructions 2016-08-30 23:02:03 +03:00
Nickolay
9854fc712f Added x87 instructions 2016-08-30 22:13:46 +03:00
Nickolay
99635d9491 Added x86 cpu support for assembly. 2016-08-30 21:51:30 +03:00
Zachary Yedidia
96209cbeb0 Merge pull request #235 from toxinu/patch-1
Add missing comma
2016-08-30 11:58:02 -04:00
Geoffrey Lehée
db520fe9e7 Add missing comma 2016-08-30 17:56:40 +02:00
Zachary Yedidia
93361fe72d Fix issue with settings.json 2016-08-30 11:32:23 -04:00
Zack Scholl
4499228cdb Added flag to introduce cursor starting positions 2016-08-30 11:28:28 -04:00
Zachary Yedidia
d79e68bbf9 Update readme about colorschemes 2016-08-30 11:24:02 -04:00
Zachary Yedidia
ec9eab8a3e Auto update settings.json if it contains 'null' 2016-08-30 11:19:51 -04:00
Zachary Yedidia
628cdd34aa Merge 2016-08-30 10:16:35 -04:00
Zachary Yedidia
20d6dffce9 Remove cmder from list of windows terminals
See #223
2016-08-30 10:15:57 -04:00
Zachary Yedidia
afa58a984a Merge pull request #220 from wayneashleyberry/patch-1
Update options.md
2016-08-30 09:47:22 -04:00
Zachary Yedidia
209cdccdc5 Merge pull request #225 from jfchevrette/patch-1
Fix typo in tutorial.md
2016-08-30 09:47:09 -04:00
Zachary Yedidia
2761f57565 Merge pull request #221 from ilmanzo/patch-1
Update tutorial.md
2016-08-30 09:47:00 -04:00
Zachary Yedidia
791a397d55 Fix problem with first-time creation of the settings file
Fixes #219
2016-08-30 09:45:05 -04:00
Jean-Francois Chevrette
3e428ff505 Fix typo in tutorial.md
small typo
2016-08-30 09:38:49 -04:00
Andrea Manzini
ddc237872c Update tutorial.md
small typo
2016-08-30 10:07:28 +02:00
Wayne Ashley Berry
ee5ac6a582 Update options.md
Fixes json syntax and adds syntax highlighting.
2016-08-30 09:35:21 +02:00
Zachary Yedidia
5df28c76e8 Add tutorial.md to help files
Fixes #218
2016-08-29 21:26:53 -04:00
Zachary Yedidia
19c7860f14 Update readme 2016-08-29 10:21:34 -04:00
Zachary Yedidia
f6c7c488f5 Separate release.sh and pre-release.sh 2016-08-29 10:19:24 -04:00
Zachary Yedidia
bc6c9772cd Update readme 2016-08-29 10:17:15 -04:00
Zachary Yedidia
fccec47ae5 Have CanClose use single letters for responses
Closes #184
2016-08-29 10:10:16 -04:00
Zachary Yedidia
eda08a994a Make cursorline on by default 2016-08-29 09:20:48 -04:00
Zachary Yedidia
f8071af717 Fix bug with view.Center
Fixes #215
2016-08-29 09:16:24 -04:00
Zachary Yedidia
6ce8fe3ce1 Open an empty buffer if user opened a directory
Fixes #216
2016-08-29 09:01:54 -04:00
Zachary Yedidia
00e385b871 Add show command to show the value of an option 2016-08-28 21:48:03 -04:00
Zachary Yedidia
da98a2e9ec Fix broken readme link 2016-08-28 16:29:01 -04:00
Zachary Yedidia
59b7555f01 Fix various small details and update readme 2016-08-28 16:28:28 -04:00
Zachary Yedidia
8cef0abf6a Fix import error in tests 2016-08-28 13:45:38 -04:00
Zachary Yedidia
56224c9184 Minor update to zenburn line number colors 2016-08-28 13:13:01 -04:00
Zachary Yedidia
40523871fa Update runtime 2016-08-28 13:09:37 -04:00
Zachary Yedidia
90e0a2ec1a Rename 'default' colorscheme to 'simple'
This commit also adds an additional name for zenburn as 'default'
so you can refer to zenburn as 'default' or as 'zenburn'
2016-08-28 13:07:47 -04:00
Zachary Yedidia
aa9dbdde3e Improve tab completion in command mode
Pressing tab when all suggestions start with the same substring
will insert that substring (this is how bash autocompletion works).
2016-08-28 13:05:07 -04:00
Zachary Yedidia
da7bc997ff Update docs and makefile 2016-08-27 22:00:56 -04:00
56 changed files with 2391 additions and 492 deletions

9
.github/ISSUE_TEMPLATE vendored Normal file
View File

@@ -0,0 +1,9 @@
## Description of the problem or steps to reproduce
## Specifications
You can use `micro -version` to get the commit hash.
Commit hash:
OS:
Terminal:

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
./micro
!cmd/micro
binaries/
tmp.sh
test/

View File

@@ -2,19 +2,39 @@
VERSION = $(shell git describe --tags --abbrev=0)
HASH = $(shell git rev-parse --short HEAD)
DATE = $(shell go run tools/build-date.go)
build: tcell
go build -ldflags "-X main.Version=$(VERSION) -X main.CommitHash=$(HASH) -X 'main.CompileDate=$(shell date -u '+%B %d, %Y')'" -o micro ./cmd/micro
# Builds micro after checking dependencies but without updating the runtime
build: deps tcell
go build -ldflags "-X main.Version=$(VERSION) -X main.CommitHash=$(HASH) -X 'main.CompileDate=$(DATE)'" ./cmd/micro
# Builds micro after building the runtime and checking dependencies
build-all: runtime build
# Builds micro without checking for dependencies
build-quick:
go build -ldflags "-X main.Version=$(VERSION) -X main.CommitHash=$(HASH) -X 'main.CompileDate=$(DATE)'" ./cmd/micro
# Same as 'build' but installs to $GOPATH/bin afterward
install: build
mv micro $(GOPATH)/bin
# Same as 'build-all' but installs to $GOPATH/bin afterward
install-all: runtime install
# Same as 'build-quick' but installs to $GOPATH/bin afterward
install-quick: build-quick
mv micro $(GOPATH)/bin
# Updates tcell
tcell:
git -C $(GOPATH)/src/github.com/zyedidia/tcell pull
# Checks for dependencies
deps:
go get -d ./cmd/micro
# Builds the runtime
runtime:
go get -u github.com/jteeuwen/go-bindata/...
$(GOPATH)/bin/go-bindata -nometadata -o runtime.go runtime/...

View File

@@ -1,19 +1,22 @@
# ![Micro](./assets/logo.png)
[![Build Status](https://travis-ci.org/zyedidia/micro.svg?branch=master)](https://travis-ci.org/zyedidia/micro)
![Go Report Card](https://goreportcard.com/badge/github.com/zyedidia/micro)
[![Go Report Card](https://goreportcard.com/badge/github.com/zyedidia/micro)](https://goreportcard.com/report/github.com/zyedidia/micro)
[![Join the chat at https://gitter.im/zyedidia/micro](https://badges.gitter.im/zyedidia/micro.svg)](https://gitter.im/zyedidia/micro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/zyedidia/micro/blob/master/LICENSE)
> Micro is still a work in progress
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. It comes as one single, batteries-included, static binary with no dependencies, and you can download and use it right now.
As the name indicates, micro aims to be somewhat of a successor to the nano editor by being easy to install and use in a pinch, but micro also aims to be
enjoyable to use full time, whether you work in the terminal because you prefer it (like me), or because you need to (over ssh).
Here is a picture of micro editing its source code.
![Screenshot](./assets/micro-solarized.png)
To see more screenshots of micro, showcasing all of the default colorschemes, see [here](http://zbyedidia.webfactional.com/micro/screenshots.html).
# Features
* Easy to use and to install
@@ -22,11 +25,13 @@ Here is a picture of micro editing its source code.
* Keybindings can be rebound to your liking
* Sane defaults
* You shouldn't have to configure much out of the box (and it is extremely easy to configure)
* Splits and tabs
* Extremely good mouse support
* This means mouse dragging to create a selection, double click to select by word, and triple click to select by line
* Cross platform (It should work on all the platforms Go runs on)
* Note that while Windows is supported, there are still some bugs that need to be worked out
* Plugin system (plugins are written in Lua)
* Persistent undo
* Automatic linting and error notifications
* Syntax highlighting (for over [75 languages](runtime/syntax)!)
* Colorscheme support
@@ -35,24 +40,22 @@ Here is a picture of micro editing its source code.
* Copy and paste with the system clipboard
* Small and simple
* Easily configurable
* Macros
* Common editor things such as undo/redo, line numbers, unicode support...
Although not yet implemented, I hope to add more features such as autocompletion ([#174](https://github.com/zyedidia/micro/issues/174)), and multiple cursors ([#5](https://github.com/zyedidia/micro/issues/5)) in the future.
# Installation
To install micro, you can download a prebuilt binary, or you can build it from source.
To install micro, you can download a [prebuilt binary](https://github.com/zyedidia/micro/releases), or you can build it from source.
You can also install micro with a few package managers (on OSX, Arch Linux, and CRUX).
See this [wiki page](https://github.com/zyedidia/micro/wiki/Installing-Micro) for details.
Please note that micro uses the amazing [tcell library](https://github.com/gdamore/tcell), but this
means that micro is restricted to the platforms tcell supports. As a result, micro does not support
Plan9, NaCl, and Cygwin (although this may change in the future).
If you want more information about ways to install micro, see this [wiki page](https://github.com/zyedidia/micro/wiki/Installing-Micro)
### Prebuilt binaries
All you need to install micro is one file, the binary itself. It's as simple as that!
You can download the correct binary for your operating system from the list in the [nightly build release](https://github.com/zyedidia/micro/releases).
Download the binary from the [releases](https://github.com/zyedidia/micro/releases) page.
On that page you'll see the nightly release, which contains binaries for micro which are built every night,
and you'll see all the stable releases with the corresponding binaries.
@@ -63,13 +66,13 @@ If you'd like to see more information after installing micro, run `micro -versio
If your operating system does not have binary, but does run Go, you can build from source.
Make sure that you have Go version 1.5 or greater (Go 1.4 will work for the systems like support CGO then).
Make sure that you have Go version 1.5 or greater (Go 1.4 will work if your version supports CGO).
```sh
go get -u github.com/zyedidia/micro/...
```
### Clipboard support
### Linux clipboard support
On Linux, clipboard support requires 'xclip' or 'xsel' command to be installed.
@@ -81,6 +84,26 @@ 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.
### Colors and syntax highlighting
If you open micro and it doesn't seem like syntax highlighting is working, this is probably because
you are using a terminal which does not support 256 color. Try changing the colorscheme to `simple`
by running `> set colorscheme simple`.
If you are using the default ubuntu terminal, to enable 256 make sure your `TERM` variable is set
to `xterm-256color`.
Many of the Windows terminals don't support more than 16 colors, which means
that micro's default colorscheme won't look very good. You can either set
the colorscheme to `simple`, or download a better terminal emulator, like
mintty.
### Plan9, NaCl, Cygwin
Please note that micro uses the amazing [tcell library](https://github.com/gdamore/tcell), but this
means that micro is restricted to the platforms tcell supports. As a result, micro does not support
Plan9, NaCl, and Cygwin (although this may change in the future).
# Usage
Once you have built the editor, simply start it by running `micro path/to/file.txt` or simply `micro` to open an empty buffer.
@@ -100,10 +123,22 @@ click to enable line selection.
# Documentation and Help
Micro has a built-in help system which you can access by pressing `CtrlE` and typing `help`. Additionally, you can
view the help files online [here](https://github.com/zyedidia/micro/tree/master/runtime/help).
view the help files here:
* [main help](https://github.com/zyedidia/micro/tree/master/runtime/help/help.md)
* [keybindings](https://github.com/zyedidia/micro/tree/master/runtime/help/keybindings.md)
* [commands](https://github.com/zyedidia/micro/tree/master/runtime/help/commands.md)
* [colors](https://github.com/zyedidia/micro/tree/master/runtime/help/colors.md)
* [options](https://github.com/zyedidia/micro/tree/master/runtime/help/options.md)
* [plugins](https://github.com/zyedidia/micro/tree/master/runtime/help/plugins.md)
I also recommend reading the [tutorial](https://github.com/zyedidia/micro/tree/master/runtime/help/tutorial.md) for
a brief introduction to the more powerful configuration features micro offers.
# Contributing
If you find any bugs, please report them! I am also happy to accept pull requests from anyone.
You can use the Github issue tracker to report bugs, ask questions, or suggest new features.
For a more informal setting to discuss the editor, you can join the [Gitter chat](https://gitter.im/zyedidia/micro).

View File

@@ -44,6 +44,15 @@ func PostActionCall(funcName string, view *View) bool {
return relocate
}
func (v *View) deselect(index int) bool {
if v.Cursor.HasSelection() {
v.Cursor.Loc = v.Cursor.CurSelection[index]
v.Cursor.ResetSelection()
return true
}
return false
}
// Center centers the view on the cursor
func (v *View) Center(usePlugin bool) bool {
if usePlugin && !PreActionCall("Center", v) {
@@ -51,10 +60,11 @@ func (v *View) Center(usePlugin bool) bool {
}
v.Topline = v.Cursor.Y - v.height/2
if v.Topline+v.height > v.Buf.NumLines {
v.Topline = v.Buf.NumLines - v.height
}
if v.Topline < 0 {
v.Topline = 0
} else if v.Topline+v.height > v.Buf.NumLines {
v.Topline = v.Buf.NumLines - v.height
}
if usePlugin {
@@ -69,10 +79,7 @@ func (v *View) CursorUp(usePlugin bool) bool {
return false
}
if v.Cursor.HasSelection() {
v.Cursor.Loc = v.Cursor.CurSelection[0]
v.Cursor.ResetSelection()
}
v.deselect(0)
v.Cursor.Up()
if usePlugin {
@@ -87,10 +94,7 @@ func (v *View) CursorDown(usePlugin bool) bool {
return false
}
if v.Cursor.HasSelection() {
v.Cursor.Loc = v.Cursor.CurSelection[1]
v.Cursor.ResetSelection()
}
v.deselect(1)
v.Cursor.Down()
if usePlugin {
@@ -289,6 +293,8 @@ func (v *View) StartOfLine(usePlugin bool) bool {
return false
}
v.deselect(0)
v.Cursor.Start()
if usePlugin {
@@ -303,6 +309,8 @@ func (v *View) EndOfLine(usePlugin bool) bool {
return false
}
v.deselect(0)
v.Cursor.End()
if usePlugin {
@@ -353,6 +361,8 @@ func (v *View) CursorStart(usePlugin bool) bool {
return false
}
v.deselect(0)
v.Cursor.X = 0
v.Cursor.Y = 0
@@ -368,6 +378,8 @@ func (v *View) CursorEnd(usePlugin bool) bool {
return false
}
v.deselect(0)
v.Cursor.Loc = v.Buf.End()
if usePlugin {
@@ -586,21 +598,21 @@ func (v *View) IndentSelection(usePlugin bool) bool {
v.Buf.Insert(Loc{0, i}, Spaces(tabsize))
if i == start {
if v.Cursor.CurSelection[0].X > 0 {
v.Cursor.CurSelection[0] = v.Cursor.CurSelection[0].Move(tabsize, v.Buf)
v.Cursor.SetSelectionStart(v.Cursor.CurSelection[0].Move(tabsize, v.Buf))
}
}
if i == end {
v.Cursor.CurSelection[1] = Loc{endX + tabsize + 1, end}
v.Cursor.SetSelectionEnd(Loc{endX + tabsize + 1, end})
}
} else {
v.Buf.Insert(Loc{0, i}, "\t")
if i == start {
if v.Cursor.CurSelection[0].X > 0 {
v.Cursor.CurSelection[0] = v.Cursor.CurSelection[0].Move(1, v.Buf)
v.Cursor.SetSelectionStart(v.Cursor.CurSelection[0].Move(1, v.Buf))
}
}
if i == end {
v.Cursor.CurSelection[1] = Loc{endX + 2, end}
v.Cursor.SetSelectionEnd(Loc{endX + 2, end})
}
}
}
@@ -635,22 +647,22 @@ func (v *View) OutdentSelection(usePlugin bool) bool {
v.Buf.Remove(Loc{0, i}, Loc{1, i})
if i == start {
if v.Cursor.CurSelection[0].X > 0 {
v.Cursor.CurSelection[0] = v.Cursor.CurSelection[0].Move(-1, v.Buf)
v.Cursor.SetSelectionStart(v.Cursor.CurSelection[0].Move(-1, v.Buf))
}
}
if i == end {
v.Cursor.CurSelection[1] = Loc{endX - j, end}
v.Cursor.SetSelectionEnd(Loc{endX - j, end})
}
}
} else {
v.Buf.Remove(Loc{0, i}, Loc{1, i})
if i == start {
if v.Cursor.CurSelection[0].X > 0 {
v.Cursor.CurSelection[0] = v.Cursor.CurSelection[0].Move(-1, v.Buf)
v.Cursor.SetSelectionStart(v.Cursor.CurSelection[0].Move(-1, v.Buf))
}
}
if i == end {
v.Cursor.CurSelection[1] = Loc{endX, end}
v.Cursor.SetSelectionEnd(Loc{endX, end})
}
}
}
@@ -677,6 +689,9 @@ func (v *View) InsertTab(usePlugin bool) bool {
// Insert a tab
if v.Buf.Settings["tabstospaces"].(bool) {
tabSize := int(v.Buf.Settings["tabsize"].(float64))
if remainder := v.Cursor.Loc.X % tabSize; remainder != 0 {
tabSize = tabSize - remainder
}
v.Buf.Insert(v.Cursor.Loc, Spaces(tabSize))
for i := 0; i < tabSize; i++ {
v.Cursor.Right()
@@ -706,6 +721,8 @@ func (v *View) Save(usePlugin bool) bool {
if v.Buf.Path == "" {
filename, canceled := messenger.Prompt("Filename: ", "Save", NoCompletion)
if !canceled {
// the filename might or might not be quoted, so unquote first then join the strings.
filename = strings.Join(SplitCommandArgs(filename), " ")
v.Buf.Path = filename
v.Buf.Name = filename
} else {
@@ -835,7 +852,7 @@ func (v *View) Copy(usePlugin bool) bool {
}
if v.Cursor.HasSelection() {
clipboard.WriteAll(v.Cursor.GetSelection())
clipboard.WriteAll(v.Cursor.GetSelection(), "clipboard")
v.freshClip = true
messenger.Message("Copied selection")
}
@@ -858,10 +875,10 @@ func (v *View) CutLine(usePlugin bool) bool {
}
if v.freshClip == true {
if v.Cursor.HasSelection() {
if clip, err := clipboard.ReadAll(); err != nil {
if clip, err := clipboard.ReadAll("clipboard"); err != nil {
messenger.Error(err)
} else {
clipboard.WriteAll(clip + v.Cursor.GetSelection())
clipboard.WriteAll(clip+v.Cursor.GetSelection(), "clipboard")
}
}
} else if time.Since(v.lastCutTime)/time.Second > 10*time.Second || v.freshClip == false {
@@ -886,7 +903,7 @@ func (v *View) Cut(usePlugin bool) bool {
}
if v.Cursor.HasSelection() {
clipboard.WriteAll(v.Cursor.GetSelection())
clipboard.WriteAll(v.Cursor.GetSelection(), "clipboard")
v.Cursor.DeleteSelection()
v.Cursor.ResetSelection()
v.freshClip = true
@@ -945,18 +962,23 @@ func (v *View) Paste(usePlugin bool) bool {
return false
}
leadingWS := GetLeadingWhitespace(v.Buf.Line(v.Cursor.Y))
clip, _ := clipboard.ReadAll("clipboard")
v.paste(clip)
if v.Cursor.HasSelection() {
v.Cursor.DeleteSelection()
v.Cursor.ResetSelection()
if usePlugin {
return PostActionCall("Paste", v)
}
clip, _ := clipboard.ReadAll()
clip = strings.Replace(clip, "\n", "\n"+leadingWS, -1)
v.Buf.Insert(v.Cursor.Loc, clip)
v.Cursor.Loc = v.Cursor.Loc.Move(Count(clip), v.Buf)
v.freshClip = false
messenger.Message("Pasted clipboard")
return true
}
// PastePrimary pastes from the primary clipboard (only use on linux)
func (v *View) PastePrimary(usePlugin bool) bool {
if usePlugin && !PreActionCall("Paste", v) {
return false
}
clip, _ := clipboard.ReadAll("primary")
v.paste(clip)
if usePlugin {
return PostActionCall("Paste", v)
@@ -970,8 +992,8 @@ func (v *View) SelectAll(usePlugin bool) bool {
return false
}
v.Cursor.CurSelection[0] = v.Buf.Start()
v.Cursor.CurSelection[1] = v.Buf.End()
v.Cursor.SetSelectionStart(v.Buf.Start())
v.Cursor.SetSelectionEnd(v.Buf.End())
// Put the cursor at the beginning
v.Cursor.X = 0
v.Cursor.Y = 0
@@ -988,11 +1010,14 @@ func (v *View) OpenFile(usePlugin bool) bool {
return false
}
if v.CanClose("Continue? (yes, no, save) ") {
if v.CanClose() {
filename, canceled := messenger.Prompt("File to open: ", "Open", FileCompletion)
if canceled {
return false
}
// the filename might or might not be quoted, so unquote first then join the strings.
filename = strings.Join(SplitCommandArgs(filename), " ")
home, _ := homedir.Dir()
filename = strings.Replace(filename, "~", home, 1)
file, err := ioutil.ReadFile(filename)
@@ -1088,6 +1113,8 @@ func (v *View) CursorPageUp(usePlugin bool) bool {
return false
}
v.deselect(0)
if v.Cursor.HasSelection() {
v.Cursor.Loc = v.Cursor.CurSelection[0]
v.Cursor.ResetSelection()
@@ -1106,6 +1133,8 @@ func (v *View) CursorPageDown(usePlugin bool) bool {
return false
}
v.deselect(0)
if v.Cursor.HasSelection() {
v.Cursor.Loc = v.Cursor.CurSelection[1]
v.Cursor.ResetSelection()
@@ -1284,7 +1313,7 @@ func (v *View) Quit(usePlugin bool) bool {
}
// Make sure not to quit if there are unsaved changes
if v.CanClose("Quit anyway? (yes, no, save) ") {
if v.CanClose() {
v.CloseBuffer()
if len(tabs[curTab].views) > 1 {
v.splitNode.Delete()
@@ -1321,6 +1350,39 @@ func (v *View) Quit(usePlugin bool) bool {
return false
}
// QuitAll quits the whole editor; all splits and tabs
func (v *View) QuitAll(usePlugin bool) bool {
if usePlugin && !PreActionCall("QuitAll", v) {
return false
}
closeAll := true
for _, tab := range tabs {
for _, v := range tab.views {
if !v.CanClose() {
closeAll = false
}
}
}
if closeAll {
for _, tab := range tabs {
for _, v := range tab.views {
v.CloseBuffer()
}
}
if usePlugin {
PostActionCall("QuitAll", v)
}
screen.Fini()
os.Exit(0)
}
return false
}
// AddTab adds a new tab with an empty buffer
func (v *View) AddTab(usePlugin bool) bool {
if usePlugin && !PreActionCall("AddTab", v) {
@@ -1419,6 +1481,62 @@ func (v *View) PreviousSplit(usePlugin bool) bool {
return false
}
var curMacro []interface{}
var recordingMacro bool
func (v *View) ToggleMacro(usePlugin bool) bool {
if usePlugin && !PreActionCall("ToggleMacro", v) {
return false
}
recordingMacro = !recordingMacro
if recordingMacro {
curMacro = []interface{}{}
messenger.Message("Recording")
} else {
messenger.Message("Stopped recording")
}
if usePlugin {
return PostActionCall("ToggleMacro", v)
}
return true
}
func (v *View) PlayMacro(usePlugin bool) bool {
if usePlugin && !PreActionCall("PlayMacro", v) {
return false
}
for _, action := range curMacro {
switch t := action.(type) {
case rune:
// Insert a character
if v.Cursor.HasSelection() {
v.Cursor.DeleteSelection()
v.Cursor.ResetSelection()
}
v.Buf.Insert(v.Cursor.Loc, string(t))
v.Cursor.Right()
for _, pl := range loadedPlugins {
_, err := Call(pl+".onRune", string(t), v)
if err != nil && !strings.HasPrefix(err.Error(), "function does not exist") {
TermMessage(err)
}
}
case func(*View, bool) bool:
t(v, true)
}
}
if usePlugin {
return PostActionCall("PlayMacro", v)
}
return true
}
// None is no action
func None() bool {
return false

View File

@@ -8,19 +8,22 @@ import (
"github.com/mitchellh/go-homedir"
)
var pluginCompletions []func(string) []string
// This file is meant (for now) for autocompletion in command mode, not
// while coding. This helps micro autocomplete commands and then filenames
// for example with `vsplit filename`.
// FileComplete autocompletes filenames
func FileComplete(input string) (string, []string) {
dirs := strings.Split(input, "/")
var sep string = string(os.PathSeparator)
dirs := strings.Split(input, sep)
var files []os.FileInfo
var err error
if len(dirs) > 1 {
home, _ := homedir.Dir()
directories := strings.Join(dirs[:len(dirs)-1], "/")
directories := strings.Join(dirs[:len(dirs)-1], sep)
if strings.HasPrefix(directories, "~") {
directories = strings.Replace(directories, "~", home, 1)
}
@@ -35,7 +38,7 @@ func FileComplete(input string) (string, []string) {
for _, f := range files {
name := f.Name()
if f.IsDir() {
name += "/"
name += sep
}
if strings.HasPrefix(name, dirs[len(dirs)-1]) {
suggestions = append(suggestions, name)
@@ -45,10 +48,14 @@ func FileComplete(input string) (string, []string) {
var chosen string
if len(suggestions) == 1 {
if len(dirs) > 1 {
chosen = strings.Join(dirs[:len(dirs)-1], "/") + "/" + suggestions[0]
chosen = strings.Join(dirs[:len(dirs)-1], sep) + sep + suggestions[0]
} else {
chosen = suggestions[0]
}
} else {
if len(dirs) > 1 {
chosen = strings.Join(dirs[:len(dirs)-1], sep) + sep
}
}
return chosen, suggestions
@@ -88,6 +95,15 @@ func HelpComplete(input string) (string, []string) {
return chosen, suggestions
}
func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
// OptionComplete autocompletes options
func OptionComplete(input string) (string, []string) {
var suggestions []string
@@ -98,7 +114,7 @@ func OptionComplete(input string) (string, []string) {
}
}
for option := range localSettings {
if strings.HasPrefix(option, input) {
if strings.HasPrefix(option, input) && !contains(suggestions, option) {
suggestions = append(suggestions, option)
}
}
@@ -109,3 +125,24 @@ func OptionComplete(input string) (string, []string) {
}
return chosen, suggestions
}
// MakeCompletion registeres a function from a plugin for autocomplete commands
func MakeCompletion(function string) Completion {
pluginCompletions = append(pluginCompletions, LuaFunctionComplete(function))
return Completion(-len(pluginCompletions))
}
// PluginComplete autocompletes from plugin function
func PluginComplete(complete Completion, input string) (chosen string, suggestions []string) {
idx := int(-complete) - 1
if len(pluginCompletions) <= idx {
return "", nil
}
suggestions = pluginCompletions[idx](input)
if len(suggestions) == 1 {
chosen = suggestions[0]
}
return
}

View File

@@ -1,11 +1,11 @@
package main
import (
"encoding/json"
"io/ioutil"
"os"
"strings"
"github.com/yosuke-furukawa/json5/encoding/json5"
"github.com/zyedidia/tcell"
)
@@ -55,6 +55,7 @@ var bindingActions = map[string]func(*View, bool) bool{
"IndentSelection": (*View).IndentSelection,
"OutdentSelection": (*View).OutdentSelection,
"Paste": (*View).Paste,
"PastePrimary": (*View).PastePrimary,
"SelectAll": (*View).SelectAll,
"OpenFile": (*View).OpenFile,
"Start": (*View).Start,
@@ -72,11 +73,14 @@ var bindingActions = map[string]func(*View, bool) bool{
"ShellMode": (*View).ShellMode,
"CommandMode": (*View).CommandMode,
"Quit": (*View).Quit,
"QuitAll": (*View).QuitAll,
"AddTab": (*View).AddTab,
"PreviousTab": (*View).PreviousTab,
"NextTab": (*View).NextTab,
"NextSplit": (*View).NextSplit,
"PreviousSplit": (*View).PreviousSplit,
"ToggleMacro": (*View).ToggleMacro,
"PlayMacro": (*View).PlayMacro,
// This was changed to InsertNewline but I don't want to break backwards compatibility
"InsertEnter": (*View).InsertNewline,
@@ -235,7 +239,7 @@ func InitBindings() {
return
}
err = json.Unmarshal(input, &parsed)
err = json5.Unmarshal(input, &parsed)
if err != nil {
TermMessage("Error reading bindings.json:", err.Error())
}
@@ -393,6 +397,8 @@ func DefaultBindings() map[string]string {
"CtrlBackslash": "NextTab",
"Home": "StartOfLine",
"End": "EndOfLine",
"CtrlHome": "CursorStart",
"CtrlEnd": "CursorEnd",
"PageUp": "CursorPageUp",
"PageDown": "CursorPageDown",
"CtrlG": "ToggleHelp",
@@ -404,6 +410,8 @@ func DefaultBindings() map[string]string {
"CtrlQ": "Quit",
"CtrlE": "CommandMode",
"CtrlW": "NextSplit",
"CtrlU": "ToggleMacro",
"CtrlJ": "PlayMacro",
// Emacs-style keybindings
"Alt-f": "WordRight",

View File

@@ -8,6 +8,8 @@ import (
"os/exec"
"os/signal"
"path/filepath"
"strconv"
"strings"
"time"
"unicode/utf8"
)
@@ -85,10 +87,36 @@ func NewBuffer(txt []byte, path string) *Buffer {
}
// Put the cursor at the first spot
cursorStartX := 0
cursorStartY := 0
// If -startpos LINE,COL was passed, use start position LINE,COL
if len(*flagStartPos) > 0 {
positions := strings.Split(*flagStartPos, ",")
if len(positions) == 2 {
lineNum, errPos1 := strconv.Atoi(positions[0])
colNum, errPos2 := strconv.Atoi(positions[1])
if errPos1 == nil && errPos2 == nil {
cursorStartX = colNum
cursorStartY = lineNum - 1
// Check to avoid line overflow
if cursorStartY > b.NumLines {
cursorStartY = b.NumLines - 1
} else if cursorStartY < 0 {
cursorStartY = 0
}
// Check to avoid column overflow
if cursorStartX > len(b.Line(cursorStartY)) {
cursorStartX = len(b.Line(cursorStartY))
} else if cursorStartX < 0 {
cursorStartX = 0
}
}
}
}
b.Cursor = Cursor{
Loc: Loc{
X: 0,
Y: 0,
X: cursorStartX,
Y: cursorStartY,
},
buf: b,
}
@@ -219,6 +247,7 @@ func (b *Buffer) Serialize() error {
// SaveAs saves the buffer to a specified path (filename), creating the file if it does not exist
func (b *Buffer) SaveAs(filename string) error {
b.FindFileType()
b.UpdateRules()
b.Name = filename
b.Path = filename
@@ -235,6 +264,7 @@ func (b *Buffer) SaveAs(filename string) error {
// SaveAsWithSudo is the same as SaveAs except it uses a neat trick
// with tee to use sudo so the user doesn't have to reopen micro with sudo
func (b *Buffer) SaveAsWithSudo(filename string) error {
b.FindFileType()
b.UpdateRules()
b.Name = filename
b.Path = filename

View File

@@ -2,11 +2,12 @@ package main
import (
"fmt"
"github.com/zyedidia/tcell"
"io/ioutil"
"regexp"
"strconv"
"strings"
"github.com/zyedidia/tcell"
)
// Colorscheme is a map from string to style -- it represents a colorscheme
@@ -15,7 +16,25 @@ type Colorscheme map[string]tcell.Style
// The current colorscheme
var colorscheme Colorscheme
var preInstalledColors = []string{"default", "solarized", "solarized-tc", "atom-dark-tc", "monokai", "gruvbox", "zenburn"}
var preInstalledColors = []string{"default", "simple", "solarized", "solarized-tc", "atom-dark-tc", "monokai", "gruvbox", "zenburn", "bubblegum"}
// ColorschemeExists checks if a given colorscheme exists
func ColorschemeExists(colorschemeName string) bool {
files, _ := ioutil.ReadDir(configDir)
for _, f := range files {
if f.Name() == colorschemeName+".micro" {
return true
}
}
for _, name := range preInstalledColors {
if name == colorschemeName {
return true
}
}
return false
}
// InitColorscheme picks and initializes the colorscheme when micro starts
func InitColorscheme() {
@@ -30,6 +49,7 @@ func LoadDefaultColorscheme() {
// LoadColorscheme loads the given colorscheme from a directory
func LoadColorscheme(colorschemeName, dir string) {
files, _ := ioutil.ReadDir(dir)
found := false
for _, f := range files {
if f.Name() == colorschemeName+".micro" {
text, err := ioutil.ReadFile(dir + "/" + f.Name())
@@ -38,6 +58,7 @@ func LoadColorscheme(colorschemeName, dir string) {
continue
}
colorscheme = ParseColorscheme(string(text))
found = true
}
}
@@ -49,8 +70,13 @@ func LoadColorscheme(colorschemeName, dir string) {
continue
}
colorscheme = ParseColorscheme(string(data))
found = true
}
}
if !found {
TermMessage(colorschemeName, "is not a valid colorscheme")
}
}
// ParseColorscheme parses the text definition for a colorscheme and returns the corresponding object

View File

@@ -27,6 +27,7 @@ var commands map[string]Command
var commandActions = map[string]func([]string){
"Set": Set,
"SetLocal": SetLocal,
"Show": Show,
"Run": Run,
"Bind": Bind,
"Quit": Quit,
@@ -68,17 +69,18 @@ func MakeCommand(name, function string, completions ...Completion) {
// DefaultCommands returns a map containing micro's default commands
func DefaultCommands() map[string]StrCommand {
return map[string]StrCommand{
"set": StrCommand{"Set", []Completion{OptionCompletion, NoCompletion}},
"setlocal": StrCommand{"SetLocal", []Completion{OptionCompletion, NoCompletion}},
"bind": StrCommand{"Bind", []Completion{NoCompletion}},
"run": StrCommand{"Run", []Completion{NoCompletion}},
"quit": StrCommand{"Quit", []Completion{NoCompletion}},
"save": StrCommand{"Save", []Completion{NoCompletion}},
"replace": StrCommand{"Replace", []Completion{NoCompletion}},
"vsplit": StrCommand{"VSplit", []Completion{FileCompletion, NoCompletion}},
"hsplit": StrCommand{"HSplit", []Completion{FileCompletion, NoCompletion}},
"tab": StrCommand{"Tab", []Completion{FileCompletion, NoCompletion}},
"help": StrCommand{"Help", []Completion{HelpCompletion, NoCompletion}},
"set": {"Set", []Completion{OptionCompletion, NoCompletion}},
"setlocal": {"SetLocal", []Completion{OptionCompletion, NoCompletion}},
"show": {"Show", []Completion{OptionCompletion, NoCompletion}},
"bind": {"Bind", []Completion{NoCompletion}},
"run": {"Run", []Completion{NoCompletion}},
"quit": {"Quit", []Completion{NoCompletion}},
"save": {"Save", []Completion{NoCompletion}},
"replace": {"Replace", []Completion{NoCompletion}},
"vsplit": {"VSplit", []Completion{FileCompletion, NoCompletion}},
"hsplit": {"HSplit", []Completion{FileCompletion, NoCompletion}},
"tab": {"Tab", []Completion{FileCompletion, NoCompletion}},
"help": {"Help", []Completion{HelpCompletion, NoCompletion}},
}
}
@@ -168,6 +170,7 @@ func NewTab(args []string) {
// Set sets an option
func Set(args []string) {
if len(args) < 2 {
messenger.Error("Not enough arguments")
return
}
@@ -177,8 +180,10 @@ func Set(args []string) {
SetOptionAndSettings(option, value)
}
// SetLocal sets an option local to the buffer
func SetLocal(args []string) {
if len(args) < 2 {
messenger.Error("Not enough arguments")
return
}
@@ -191,10 +196,27 @@ func SetLocal(args []string) {
}
}
// Show shows the value of the given option
func Show(args []string) {
if len(args) < 1 {
messenger.Error("Please provide an option to show")
return
}
option := GetOption(args[0])
if option == nil {
messenger.Error(args[0], " is not a valid option")
return
}
messenger.Message(option)
}
// Bind creates a new keybinding
func Bind(args []string) {
if len(args) != 2 {
messenger.Error("Incorrect number of arguments")
if len(args) < 2 {
messenger.Error("Not enough arguments")
return
}
BindKey(args[0], args[1])
@@ -203,7 +225,7 @@ func Bind(args []string) {
// Run runs a shell command in the background
func Run(args []string) {
// Run a shell command in the background (openTerm is false)
HandleShellCommand(strings.Join(args, " "), false)
HandleShellCommand(JoinCommandArgs(args...), false)
}
// Quit closes the main view
@@ -220,40 +242,20 @@ func Save(args []string) {
// Replace runs search and replace
func Replace(args []string) {
// This is a regex to parse the replace expression
// We allow no quotes if there are no spaces, but if you want to search
// for or replace an expression with spaces, you can add double quotes
r := regexp.MustCompile(`"[^"\\]*(?:\\.[^"\\]*)*"|[^\s]*`)
replaceCmd := r.FindAllString(strings.Join(args, " "), -1)
if len(replaceCmd) < 2 {
if len(args) < 2 {
// We need to find both a search and replace expression
messenger.Error("Invalid replace statement: " + strings.Join(args, " "))
return
}
var flags string
if len(replaceCmd) == 3 {
if len(args) == 3 {
// The user included some flags
flags = replaceCmd[2]
flags = args[2]
}
search := string(replaceCmd[0])
replace := string(replaceCmd[1])
// If the search and replace expressions have quotes, we need to remove those
if strings.HasPrefix(search, `"`) && strings.HasSuffix(search, `"`) {
search = search[1 : len(search)-1]
}
if strings.HasPrefix(replace, `"`) && strings.HasSuffix(replace, `"`) {
replace = replace[1 : len(replace)-1]
}
// We replace all escaped double quotes to real double quotes
search = strings.Replace(search, `\"`, `"`, -1)
replace = strings.Replace(replace, `\"`, `"`, -1)
// Replace some things so users can actually insert newlines and tabs in replacements
replace = strings.Replace(replace, "\\n", "\n", -1)
replace = strings.Replace(replace, "\\t", "\t", -1)
search := string(args[0])
replace := string(args[1])
regex, err := regexp.Compile(search)
if err != nil {
@@ -265,15 +267,13 @@ func Replace(args []string) {
view := CurView()
found := 0
for {
match := regex.FindStringIndex(view.Buf.String())
if match == nil {
break
}
found++
if strings.Contains(flags, "c") {
if strings.Contains(flags, "c") {
for {
// The 'check' flag was used
Search(search, view, true)
if !view.Cursor.HasSelection() {
break
}
view.Relocate()
if view.Buf.Settings["syntax"].(bool) {
view.matches = Match(view)
@@ -286,13 +286,14 @@ func Replace(args []string) {
view.Cursor.ResetSelection()
}
messenger.Reset()
return
break
}
if choice {
view.Cursor.DeleteSelection()
view.Buf.Insert(FromCharPos(match[0], view.Buf), replace)
view.Buf.Insert(view.Cursor.Loc, replace)
view.Cursor.ResetSelection()
messenger.Reset()
found++
} else {
if view.Cursor.HasSelection() {
searchStart = ToCharPos(view.Cursor.CurSelection[1], view.Buf)
@@ -301,16 +302,23 @@ func Replace(args []string) {
}
continue
}
} else {
}
} else {
for {
match := regex.FindStringIndex(view.Buf.String())
if match == nil {
break
}
found++
view.Buf.Replace(FromCharPos(match[0], view.Buf), FromCharPos(match[1], view.Buf), replace)
}
}
view.Cursor.Relocate()
if found > 1 {
messenger.Message("Replaced ", found, " occurences of ", search)
messenger.Message("Replaced ", found, " occurrences of ", search)
} else if found == 1 {
messenger.Message("Replaced ", found, " occurence of ", search)
messenger.Message("Replaced ", found, " occurrence of ", search)
} else {
messenger.Message("Nothing matched ", search)
}
@@ -318,8 +326,8 @@ func Replace(args []string) {
// RunShellCommand executes a shell command and returns the output/error
func RunShellCommand(input string) (string, error) {
inputCmd := strings.Split(input, " ")[0]
args := strings.Split(input, " ")[1:]
inputCmd := SplitCommandArgs(input)[0]
args := SplitCommandArgs(input)[1:]
cmd := exec.Command(inputCmd, args...)
outputBytes := &bytes.Buffer{}
@@ -335,7 +343,7 @@ func RunShellCommand(input string) (string, error) {
// The openTerm argument specifies whether a terminal should be opened (for viewing output
// or interacting with stdin)
func HandleShellCommand(input string, openTerm bool) {
inputCmd := strings.Split(input, " ")[0]
inputCmd := SplitCommandArgs(input)[0]
if !openTerm {
// Simply run the command in the background and notify the user when it's done
messenger.Message("Running...")
@@ -360,7 +368,7 @@ func HandleShellCommand(input string, openTerm bool) {
screen.Fini()
screen = nil
args := strings.Split(input, " ")[1:]
args := SplitCommandArgs(input)[1:]
// Set up everything for the command
cmd := exec.Command(inputCmd, args...)
@@ -392,12 +400,12 @@ func HandleShellCommand(input string, openTerm bool) {
// HandleCommand handles input from the user
func HandleCommand(input string) {
inputCmd := strings.Split(input, " ")[0]
args := strings.Split(input, " ")[1:]
args := SplitCommandArgs(input)
inputCmd := args[0]
if _, ok := commands[inputCmd]; !ok {
messenger.Error("Unkown command ", inputCmd)
messenger.Error("Unknown command ", inputCmd)
} else {
commands[inputCmd].action(args)
commands[inputCmd].action(args[1:])
}
}

View File

@@ -1,5 +1,7 @@
package main
import "github.com/zyedidia/clipboard"
// The Cursor struct stores the location of the cursor in the view
// The complicated part about the cursor is storing its location.
// The cursor must be displayed at an x, y location, but since the buffer
@@ -33,6 +35,24 @@ func (c *Cursor) ResetSelection() {
c.CurSelection[1] = c.buf.Start()
}
// SetSelectionStart sets the start of the selection
func (c *Cursor) SetSelectionStart(pos Loc) {
c.CurSelection[0] = pos
// Copy to primary clipboard for linux
if c.HasSelection() {
clipboard.WriteAll(c.GetSelection(), "primary")
}
}
// SetSelectionEnd sets the end of the selection
func (c *Cursor) SetSelectionEnd(pos Loc) {
c.CurSelection[1] = pos
// Copy to primary clipboard for linux
if c.HasSelection() {
clipboard.WriteAll(c.GetSelection(), "primary")
}
}
// HasSelection returns whether or not the user has selected anything
func (c *Cursor) HasSelection() bool {
return c.CurSelection[0] != c.CurSelection[1]
@@ -43,7 +63,7 @@ func (c *Cursor) DeleteSelection() {
if c.CurSelection[0].GreaterThan(c.CurSelection[1]) {
c.buf.Remove(c.CurSelection[1], c.CurSelection[0])
c.Loc = c.CurSelection[1]
} else if c.GetSelection() == "" {
} else if !c.HasSelection() {
return
} else {
c.buf.Remove(c.CurSelection[0], c.CurSelection[1])
@@ -62,12 +82,12 @@ func (c *Cursor) GetSelection() string {
// SelectLine selects the current line
func (c *Cursor) SelectLine() {
c.Start()
c.CurSelection[0] = c.Loc
c.SetSelectionStart(c.Loc)
c.End()
if c.buf.NumLines-1 > c.Y {
c.CurSelection[1] = c.Loc.Move(1, c.buf)
c.SetSelectionEnd(c.Loc.Move(1, c.buf))
} else {
c.CurSelection[1] = c.Loc
c.SetSelectionEnd(c.Loc)
}
c.OrigSelection = c.CurSelection
@@ -77,13 +97,13 @@ func (c *Cursor) SelectLine() {
func (c *Cursor) AddLineToSelection() {
if c.Loc.LessThan(c.OrigSelection[0]) {
c.Start()
c.CurSelection[0] = c.Loc
c.CurSelection[1] = c.OrigSelection[1]
c.SetSelectionStart(c.Loc)
c.SetSelectionEnd(c.OrigSelection[1])
}
if c.Loc.GreaterThan(c.OrigSelection[1]) {
c.End()
c.CurSelection[1] = c.Loc.Move(1, c.buf)
c.CurSelection[0] = c.OrigSelection[0]
c.SetSelectionEnd(c.Loc.Move(1, c.buf))
c.SetSelectionStart(c.OrigSelection[0])
}
if c.Loc.LessThan(c.OrigSelection[1]) && c.Loc.GreaterThan(c.OrigSelection[0]) {
@@ -98,8 +118,8 @@ func (c *Cursor) SelectWord() {
}
if !IsWordChar(string(c.RuneUnder(c.X))) {
c.CurSelection[0] = c.Loc
c.CurSelection[1] = c.Loc.Move(1, c.buf)
c.SetSelectionStart(c.Loc)
c.SetSelectionEnd(c.Loc.Move(1, c.buf))
c.OrigSelection = c.CurSelection
return
}
@@ -110,14 +130,14 @@ func (c *Cursor) SelectWord() {
backward--
}
c.CurSelection[0] = Loc{backward, c.Y}
c.SetSelectionStart(Loc{backward, c.Y})
c.OrigSelection[0] = c.CurSelection[0]
for forward < Count(c.buf.Line(c.Y))-1 && IsWordChar(string(c.RuneUnder(forward+1))) {
forward++
}
c.CurSelection[1] = Loc{forward, c.Y}.Move(1, c.buf)
c.SetSelectionEnd(Loc{forward, c.Y}.Move(1, c.buf))
c.OrigSelection[1] = c.CurSelection[1]
c.Loc = c.CurSelection[1]
}
@@ -136,8 +156,8 @@ func (c *Cursor) AddWordToSelection() {
backward--
}
c.CurSelection[0] = Loc{backward, c.Y}
c.CurSelection[1] = c.OrigSelection[1]
c.SetSelectionStart(Loc{backward, c.Y})
c.SetSelectionEnd(c.OrigSelection[1])
}
if c.Loc.GreaterThan(c.OrigSelection[1]) {
@@ -147,8 +167,8 @@ func (c *Cursor) AddWordToSelection() {
forward++
}
c.CurSelection[1] = Loc{forward, c.Y}.Move(1, c.buf)
c.CurSelection[0] = c.OrigSelection[0]
c.SetSelectionEnd(Loc{forward, c.Y}.Move(1, c.buf))
c.SetSelectionStart(c.OrigSelection[0])
}
c.Loc = c.CurSelection[1]
@@ -157,11 +177,11 @@ func (c *Cursor) AddWordToSelection() {
// SelectTo selects from the current cursor location to the given location
func (c *Cursor) SelectTo(loc Loc) {
if loc.GreaterThan(c.OrigSelection[0]) {
c.CurSelection[0] = c.OrigSelection[0]
c.CurSelection[1] = loc
c.SetSelectionStart(c.OrigSelection[0])
c.SetSelectionEnd(loc)
} else {
c.CurSelection[0] = loc
c.CurSelection[1] = c.OrigSelection[0]
c.SetSelectionStart(loc)
c.SetSelectionEnd(c.OrigSelection[0])
}
}

View File

@@ -9,6 +9,7 @@ var helpFiles = []string{
"colors",
"options",
"commands",
"tutorial",
}
// LoadHelp loads the help text from inside the binary

View File

@@ -38,6 +38,7 @@ var preInstalledSynFiles = []string{
"asm",
"awk",
"c",
"caddyfile",
"cmake",
"coffeescript",
"colortest",
@@ -47,6 +48,7 @@ var preInstalledSynFiles = []string{
"css",
"cython",
"d",
"dart",
"dot",
"erb",
"fish",
@@ -79,9 +81,11 @@ var preInstalledSynFiles = []string{
"man",
"markdown",
"mpdconf",
"micro",
"nanorc",
"nginx",
"ocaml",
"pascal",
"patch",
"peg",
"perl",
@@ -482,7 +486,6 @@ func Match(v *View) SyntaxMatches {
for _, value := range indicies {
start := runePos(value[0], line)
end := runePos(value[1], line)
// messenger.Message(start, " ", end)
for i := start; i < end; i++ {
matches[lineN][i] = rule.style
}

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"os"
"strconv"
"strings"
"github.com/zyedidia/clipboard"
"github.com/zyedidia/tcell"
@@ -98,6 +97,7 @@ func (m *Messenger) Error(msg ...interface{}) {
// YesNoPrompt asks the user a yes or no question (waits for y or n) and returns the result
func (m *Messenger) YesNoPrompt(prompt string) (bool, bool) {
m.hasPrompt = true
m.Message(prompt)
_, h := screen.Size()
@@ -113,17 +113,55 @@ func (m *Messenger) YesNoPrompt(prompt string) (bool, bool) {
switch e.Key() {
case tcell.KeyRune:
if e.Rune() == 'y' {
m.hasPrompt = false
return true, false
} else if e.Rune() == 'n' {
m.hasPrompt = false
return false, false
}
case tcell.KeyCtrlC, tcell.KeyCtrlQ, tcell.KeyEscape:
m.hasPrompt = false
return false, true
}
}
}
}
// LetterPrompt gives the user a prompt and waits for a one letter response
func (m *Messenger) LetterPrompt(prompt string, responses ...rune) (rune, bool) {
m.hasPrompt = true
m.Message(prompt)
_, h := screen.Size()
for {
m.Clear()
m.Display()
screen.ShowCursor(Count(m.message), h-1)
screen.Show()
event := <-events
switch e := event.(type) {
case *tcell.EventKey:
switch e.Key() {
case tcell.KeyRune:
for _, r := range responses {
if e.Rune() == r {
m.Clear()
m.Reset()
m.hasPrompt = false
return r, false
}
}
case tcell.KeyCtrlC, tcell.KeyCtrlQ, tcell.KeyEscape:
m.Clear()
m.Reset()
m.hasPrompt = false
return ' ', true
}
}
}
}
type Completion int
const (
@@ -167,7 +205,7 @@ func (m *Messenger) Prompt(prompt, historyType string, completionTypes ...Comple
response, canceled = m.response, false
m.history[historyType][len(m.history[historyType])-1] = response
case tcell.KeyTab:
args := strings.Split(m.response, " ")
args := SplitCommandArgs(m.response)
currentArgNum := len(args) - 1
currentArg := args[currentArgNum]
var completionType Completion
@@ -193,13 +231,16 @@ func (m *Messenger) Prompt(prompt, historyType string, completionTypes ...Comple
chosen, suggestions = HelpComplete(currentArg)
} else if completionType == OptionCompletion {
chosen, suggestions = OptionComplete(currentArg)
} else if completionType < NoCompletion {
chosen, suggestions = PluginComplete(completionType, currentArg)
}
if len(suggestions) > 1 {
chosen = chosen + CommonSubstring(suggestions...)
}
if chosen != "" {
if len(args) > 1 {
chosen = " " + chosen
}
m.response = strings.Join(args[:len(args)-1], " ") + chosen
m.response = JoinCommandArgs(append(args[:len(args)-1], chosen)...)
m.cursorx = Count(m.response)
}
}
@@ -207,18 +248,19 @@ func (m *Messenger) Prompt(prompt, historyType string, completionTypes ...Comple
m.HandleEvent(event, m.history[historyType])
messenger.Clear()
m.Clear()
for _, v := range tabs[curTab].views {
v.Display()
}
DisplayTabs()
messenger.Display()
m.Display()
if len(suggestions) > 1 {
m.DisplaySuggestions(suggestions)
}
screen.Show()
}
m.Clear()
m.Reset()
return response, canceled
}
@@ -254,7 +296,7 @@ func (m *Messenger) HandleEvent(event tcell.Event, history []string) {
m.cursorx--
}
case tcell.KeyCtrlV:
clip, _ := clipboard.ReadAll()
clip, _ := clipboard.ReadAll("clipboard")
m.response = Insert(m.response, m.cursorx, clip)
m.cursorx += Count(clip)
case tcell.KeyRune:
@@ -314,11 +356,14 @@ func (m *Messenger) DisplaySuggestions(suggestions []string) {
func (m *Messenger) Display() {
_, h := screen.Size()
if m.hasMessage {
runes := []rune(m.message + m.response)
for x := 0; x < len(runes); x++ {
screen.SetContent(x, h-1, runes[x], nil, m.style)
if m.hasPrompt || globalSettings["infobar"].(bool) {
runes := []rune(m.message + m.response)
for x := 0; x < len(runes); x++ {
screen.SetContent(x, h-1, runes[x], nil, m.style)
}
}
}
if m.hasPrompt {
screen.ShowCursor(Count(m.message)+m.cursorx, h-1)
screen.Show()

View File

@@ -42,7 +42,7 @@ var (
configDir string
// Version is the version number or commit hash
// This should be set by the linker when compiling
// These variables should be set by the linker when compiling
Version = "Unknown"
CommitHash = "Unknown"
CompileDate = "Unknown"
@@ -64,11 +64,11 @@ var (
)
// LoadInput determines which files should be loaded into buffers
// based on the input stored in os.Args
// based on the input stored in flag.Args()
func LoadInput() []*Buffer {
// There are a number of ways micro should start given its input
// 1. If it is given a files in os.Args, it should open those
// 1. If it is given a files in flag.Args(), it should open those
// 2. If there is no input file and the input is not a terminal, that means
// something is being piped in and the stdin should be opened in an
@@ -82,18 +82,20 @@ func LoadInput() []*Buffer {
var err error
var buffers []*Buffer
if len(os.Args) > 1 {
if len(flag.Args()) > 0 {
// Option 1
// We go through each file and load it
for i := 1; i < len(os.Args); i++ {
filename = os.Args[i]
for i := 0; i < len(flag.Args()); i++ {
filename = flag.Args()[i]
// Check that the file exists
if _, e := os.Stat(filename); e == nil {
// If it exists we load it into a buffer
input, err = ioutil.ReadFile(filename)
if err != nil {
TermMessage(err)
continue
input = []byte{}
filename = ""
}
}
// If the file didn't exist, input will be empty, and we'll open an empty buffer
@@ -104,6 +106,10 @@ func LoadInput() []*Buffer {
// The input is not a terminal, so something is being piped in
// and we should read from stdin
input, err = ioutil.ReadAll(os.Stdin)
if err != nil {
TermMessage("Error reading from stdin: ", err)
input = []byte{}
}
buffers = append(buffers, NewBuffer(input, filename))
} else {
// Option 3, just open an empty buffer
@@ -157,9 +163,29 @@ func InitScreen() {
os.Setenv("TERM", "xterm-truecolor")
}
os.Setenv("TCELLDB", configDir+"/.tcelldb")
// Initilize tcell
var err error
screen, err = tcell.NewScreen()
if err != nil && err.Error() == "terminal entry not found" {
var termDB []byte
termDB, err = MkInfo()
if err != nil {
fmt.Println("Terminal entry not found")
fmt.Println("Error when trying to read terminfo: ", err)
os.Exit(1)
}
if _, e := os.Stat(configDir); e == nil {
ioutil.WriteFile(configDir+"/.tcelldb", termDB, 0644)
}
screen, err = tcell.NewScreen()
}
if err != nil {
fmt.Println(err)
os.Exit(1)
@@ -190,10 +216,24 @@ func RedrawAll() {
}
// Passing -version as a flag will have micro print out the version number
var flagVersion = flag.Bool("version", false, "Show the version number")
var flagVersion = flag.Bool("version", false, "Show the version number and information")
var flagStartPos = flag.String("startpos", "", "LINE,COL to start the cursor at when opening a buffer.")
func main() {
flag.Usage = func() {
fmt.Println("Usage: micro [OPTIONS] [FILE]...")
fmt.Println("Micro's options can be set via command line arguments for quick adjustments. For real configuration, please use the bindings.json file (see 'help options').\n")
flag.PrintDefaults()
}
optionFlags := make(map[string]*string)
for k, v := range DefaultGlobalSettings() {
optionFlags[k] = flag.String(k, "", fmt.Sprintf("The %s option. Default value: '%v'", k, v))
}
flag.Parse()
if *flagVersion {
// If -version was passed
fmt.Println("Version:", Version)
@@ -215,6 +255,7 @@ func main() {
// Load the user's settings
InitGlobalSettings()
InitCommands()
InitBindings()
@@ -262,6 +303,12 @@ func main() {
}
}
for k, v := range optionFlags {
if *v != "" {
SetOption(k, *v)
}
}
// Load all the plugin stuff
// We give plugins access to a bunch of variables here which could be useful to them
L.SetGlobal("OS", luar.New(L, runtime.GOOS))
@@ -279,6 +326,7 @@ func main() {
L.SetGlobal("HandleCommand", luar.New(L, HandleCommand))
L.SetGlobal("HandleShellCommand", luar.New(L, HandleShellCommand))
L.SetGlobal("GetLeadingWhitespace", luar.New(L, GetLeadingWhitespace))
L.SetGlobal("MakeCompletion", luar.New(L, MakeCompletion))
// Used for asynchronous jobs
L.SetGlobal("JobStart", luar.New(L, JobStart))
@@ -333,20 +381,22 @@ func main() {
// If the user left clicked we check a couple things
_, h := screen.Size()
x, y := e.Position()
if y == h-1 && messenger.message != "" {
if y == h-1 && messenger.message != "" && globalSettings["infobar"].(bool) {
// If the user clicked in the bottom bar, and there is a message down there
// we copy it to the clipboard.
// Often error messages are displayed down there so it can be useful to easily
// copy the message
clipboard.WriteAll(messenger.message)
clipboard.WriteAll(messenger.message, "primary")
continue
}
// We loop through each view in the current tab and make sure the current view
// it the one being clicked in
for _, v := range tabs[curTab].views {
if x >= v.x && x < v.x+v.width && y >= v.y && y < v.y+v.height {
tabs[curTab].curView = v.Num
if CurView().mouseReleased {
// We loop through each view in the current tab and make sure the current view
// is the one being clicked in
for _, v := range tabs[curTab].views {
if x >= v.x && x < v.x+v.width && y >= v.y && y < v.y+v.height {
tabs[curTab].curView = v.Num
}
}
}
}

669
cmd/micro/mkinfo.go Normal file
View File

@@ -0,0 +1,669 @@
// Copyright 2016 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This command is used to generate suitable configuration files in either
// go syntax or in JSON. It defaults to JSON output on stdout. If no
// term values are specified on the command line, then $TERM is used.
//
// Usage is like this:
//
// mkinfo [-go file.go] [-json file.json] [-quiet] [-nofatal] [<term>...]
//
// -go specifiles Go output into the named file. Use - for stdout.
// -json specifies JSON output in the named file. Use - for stdout
// -nofatal indicates that errors loading definitions should not be fatal
//
package main
import (
"encoding/json"
"errors"
"fmt"
"io"
"os"
"regexp"
"runtime"
"sort"
"strings"
"time"
"github.com/zyedidia/tcell"
)
// #include <curses.h>
// #include <term.h>
// #cgo LDFLAGS: -lcurses
//
// void noenv() {
// use_env(FALSE);
// }
//
// char *tigetstr_good(char *name) {
// char *r;
// r = tigetstr(name);
// if (r == (char *)-1) {
// r = NULL;
// }
// return (r);
// }
import "C"
func tigetnum(s string) int {
n := C.tigetnum(C.CString(s))
return int(n)
}
func tigetflag(s string) bool {
n := C.tigetflag(C.CString(s))
return n != 0
}
func tigetstr(s string) string {
// NB: If the string is invalid, we'll get back -1, which causes
// no end of grief. So make sure your capability strings are correct!
cs := C.tigetstr_good(C.CString(s))
if cs == nil {
return ""
}
return C.GoString(cs)
}
// This program is used to collect data from the system's terminfo library,
// and write it into Go source code. That is, we maintain our terminfo
// capabilities encoded in the program. It should never need to be run by
// an end user, but developers can use this to add codes for additional
// terminal types.
//
// If a terminal name ending with -truecolor is given, and we cannot find
// one, we will try to fabricte one from either the -256color (if present)
// or the unadorned base name, adding the XTerm specific 24-bit color
// escapes. We believe that all 24-bit capable terminals use the same
// escape sequences, and terminfo has yet to evolve to support this.
func getinfo(name string) (*tcell.Terminfo, error) {
addTrueColor := false
rsn := C.int(0)
C.noenv()
rv, _ := C.setupterm(C.CString(name), 1, &rsn)
if rv == C.ERR {
if strings.HasSuffix(name, "-truecolor") {
base := name[:len(name)-len("-truecolor")]
// Probably -256color is closest to what we want
rv, _ = C.setupterm(C.CString(base+"-256color"), 1,
&rsn)
// Otherwise try the base
if rv == C.ERR {
rv, _ = C.setupterm(C.CString(base), 1, &rsn)
}
if rv != C.ERR {
addTrueColor = true
}
}
}
if rv == C.ERR {
switch rsn {
case 1:
return nil, errors.New("hardcopy terminal")
case 0:
return nil, errors.New("terminal definition not found")
case -1:
return nil, errors.New("terminfo database missing")
default:
return nil, errors.New("setupterm failed (other)")
}
}
t := &tcell.Terminfo{}
t.Name = name
t.Colors = tigetnum("colors")
t.Columns = tigetnum("cols")
t.Lines = tigetnum("lines")
t.Bell = tigetstr("bel")
t.Clear = tigetstr("clear")
t.EnterCA = tigetstr("smcup")
t.ExitCA = tigetstr("rmcup")
t.ShowCursor = tigetstr("cnorm")
t.HideCursor = tigetstr("civis")
t.AttrOff = tigetstr("sgr0")
t.Underline = tigetstr("smul")
t.Bold = tigetstr("bold")
t.Blink = tigetstr("blink")
t.Dim = tigetstr("dim")
t.Reverse = tigetstr("rev")
t.EnterKeypad = tigetstr("smkx")
t.ExitKeypad = tigetstr("rmkx")
t.SetFg = tigetstr("setaf")
t.SetBg = tigetstr("setab")
t.SetCursor = tigetstr("cup")
t.CursorBack1 = tigetstr("cub1")
t.CursorUp1 = tigetstr("cuu1")
t.KeyF1 = tigetstr("kf1")
t.KeyF2 = tigetstr("kf2")
t.KeyF3 = tigetstr("kf3")
t.KeyF4 = tigetstr("kf4")
t.KeyF5 = tigetstr("kf5")
t.KeyF6 = tigetstr("kf6")
t.KeyF7 = tigetstr("kf7")
t.KeyF8 = tigetstr("kf8")
t.KeyF9 = tigetstr("kf9")
t.KeyF10 = tigetstr("kf10")
t.KeyF11 = tigetstr("kf11")
t.KeyF12 = tigetstr("kf12")
t.KeyF13 = tigetstr("kf13")
t.KeyF14 = tigetstr("kf14")
t.KeyF15 = tigetstr("kf15")
t.KeyF16 = tigetstr("kf16")
t.KeyF17 = tigetstr("kf17")
t.KeyF18 = tigetstr("kf18")
t.KeyF19 = tigetstr("kf19")
t.KeyF20 = tigetstr("kf20")
t.KeyF21 = tigetstr("kf21")
t.KeyF22 = tigetstr("kf22")
t.KeyF23 = tigetstr("kf23")
t.KeyF24 = tigetstr("kf24")
t.KeyF25 = tigetstr("kf25")
t.KeyF26 = tigetstr("kf26")
t.KeyF27 = tigetstr("kf27")
t.KeyF28 = tigetstr("kf28")
t.KeyF29 = tigetstr("kf29")
t.KeyF30 = tigetstr("kf30")
t.KeyF31 = tigetstr("kf31")
t.KeyF32 = tigetstr("kf32")
t.KeyF33 = tigetstr("kf33")
t.KeyF34 = tigetstr("kf34")
t.KeyF35 = tigetstr("kf35")
t.KeyF36 = tigetstr("kf36")
t.KeyF37 = tigetstr("kf37")
t.KeyF38 = tigetstr("kf38")
t.KeyF39 = tigetstr("kf39")
t.KeyF40 = tigetstr("kf40")
t.KeyF41 = tigetstr("kf41")
t.KeyF42 = tigetstr("kf42")
t.KeyF43 = tigetstr("kf43")
t.KeyF44 = tigetstr("kf44")
t.KeyF45 = tigetstr("kf45")
t.KeyF46 = tigetstr("kf46")
t.KeyF47 = tigetstr("kf47")
t.KeyF48 = tigetstr("kf48")
t.KeyF49 = tigetstr("kf49")
t.KeyF50 = tigetstr("kf50")
t.KeyF51 = tigetstr("kf51")
t.KeyF52 = tigetstr("kf52")
t.KeyF53 = tigetstr("kf53")
t.KeyF54 = tigetstr("kf54")
t.KeyF55 = tigetstr("kf55")
t.KeyF56 = tigetstr("kf56")
t.KeyF57 = tigetstr("kf57")
t.KeyF58 = tigetstr("kf58")
t.KeyF59 = tigetstr("kf59")
t.KeyF60 = tigetstr("kf60")
t.KeyF61 = tigetstr("kf61")
t.KeyF62 = tigetstr("kf62")
t.KeyF63 = tigetstr("kf63")
t.KeyF64 = tigetstr("kf64")
t.KeyInsert = tigetstr("kich1")
t.KeyDelete = tigetstr("kdch1")
t.KeyBackspace = tigetstr("kbs")
t.KeyHome = tigetstr("khome")
t.KeyEnd = tigetstr("kend")
t.KeyUp = tigetstr("kcuu1")
t.KeyDown = tigetstr("kcud1")
t.KeyRight = tigetstr("kcuf1")
t.KeyLeft = tigetstr("kcub1")
t.KeyPgDn = tigetstr("knp")
t.KeyPgUp = tigetstr("kpp")
t.KeyBacktab = tigetstr("kcbt")
t.KeyExit = tigetstr("kext")
t.KeyCancel = tigetstr("kcan")
t.KeyPrint = tigetstr("kprt")
t.KeyHelp = tigetstr("khlp")
t.KeyClear = tigetstr("kclr")
t.AltChars = tigetstr("acsc")
t.EnterAcs = tigetstr("smacs")
t.ExitAcs = tigetstr("rmacs")
t.EnableAcs = tigetstr("enacs")
t.Mouse = tigetstr("kmous")
t.KeyShfRight = tigetstr("kRIT")
t.KeyShfLeft = tigetstr("kLFT")
t.KeyShfHome = tigetstr("kHOM")
t.KeyShfEnd = tigetstr("kEND")
// Terminfo lacks descriptions for a bunch of modified keys,
// but modern XTerm and emulators often have them. Let's add them,
// if the shifted right and left arrows are defined.
if t.KeyShfRight == "\x1b[1;2C" && t.KeyShfLeft == "\x1b[1;2D" {
t.KeyShfUp = "\x1b[1;2A"
t.KeyShfDown = "\x1b[1;2B"
t.KeyMetaUp = "\x1b[1;9A"
t.KeyMetaDown = "\x1b[1;9B"
t.KeyMetaRight = "\x1b[1;9C"
t.KeyMetaLeft = "\x1b[1;9D"
t.KeyAltUp = "\x1b[1;3A"
t.KeyAltDown = "\x1b[1;3B"
t.KeyAltRight = "\x1b[1;3C"
t.KeyAltLeft = "\x1b[1;3D"
t.KeyCtrlUp = "\x1b[1;5A"
t.KeyCtrlDown = "\x1b[1;5B"
t.KeyCtrlRight = "\x1b[1;5C"
t.KeyCtrlLeft = "\x1b[1;5D"
t.KeyAltShfUp = "\x1b[1;4A"
t.KeyAltShfDown = "\x1b[1;4B"
t.KeyAltShfRight = "\x1b[1;4C"
t.KeyAltShfLeft = "\x1b[1;4D"
t.KeyMetaShfUp = "\x1b[1;10A"
t.KeyMetaShfDown = "\x1b[1;10B"
t.KeyMetaShfRight = "\x1b[1;10C"
t.KeyMetaShfLeft = "\x1b[1;10D"
t.KeyCtrlShfUp = "\x1b[1;6A"
t.KeyCtrlShfDown = "\x1b[1;6B"
t.KeyCtrlShfRight = "\x1b[1;6C"
t.KeyCtrlShfLeft = "\x1b[1;6D"
}
// And also for Home and End
if t.KeyShfHome == "\x1b[1;2H" && t.KeyShfEnd == "\x1b[1;2F" {
t.KeyCtrlHome = "\x1b[1;5H"
t.KeyCtrlEnd = "\x1b[1;5F"
t.KeyAltHome = "\x1b[1;9H"
t.KeyAltEnd = "\x1b[1;9F"
t.KeyCtrlShfHome = "\x1b[1;6H"
t.KeyCtrlShfEnd = "\x1b[1;6F"
t.KeyAltShfHome = "\x1b[1;4H"
t.KeyAltShfEnd = "\x1b[1;4F"
t.KeyMetaShfHome = "\x1b[1;10H"
t.KeyMetaShfEnd = "\x1b[1;10F"
}
// And the same thing for rxvt and workalikes (Eterm, aterm, etc.)
// It seems that urxvt at least send ESC as ALT prefix for these,
// although some places seem to indicate a separate ALT key sesquence.
if t.KeyShfRight == "\x1b[c" && t.KeyShfLeft == "\x1b[d" {
t.KeyShfUp = "\x1b[a"
t.KeyShfDown = "\x1b[b"
t.KeyCtrlUp = "\x1b[Oa"
t.KeyCtrlDown = "\x1b[Ob"
t.KeyCtrlRight = "\x1b[Oc"
t.KeyCtrlLeft = "\x1b[Od"
}
if t.KeyShfHome == "\x1b[7$" && t.KeyShfEnd == "\x1b[8$" {
t.KeyCtrlHome = "\x1b[7^"
t.KeyCtrlEnd = "\x1b[8^"
}
// If the kmous entry is present, then we need to record the
// the codes to enter and exit mouse mode. Sadly, this is not
// part of the terminfo databases anywhere that I've found, but
// is an extension. The escape codes are documented in the XTerm
// manual, and all terminals that have kmous are expected to
// use these same codes, unless explicitly configured otherwise
// vi XM. Note that in any event, we only known how to parse either
// x11 or SGR mouse events -- if your terminal doesn't support one
// of these two forms, you maybe out of luck.
t.MouseMode = tigetstr("XM")
if t.Mouse != "" && t.MouseMode == "" {
// we anticipate that all xterm mouse tracking compatible
// terminals understand mouse tracking (1000), but we hope
// that those that don't understand any-event tracking (1003)
// will at least ignore it. Likewise we hope that terminals
// that don't understand SGR reporting (1006) just ignore it.
t.MouseMode = "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;" +
"\x1b[?1000%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c"
}
// We only support colors in ANSI 8 or 256 color mode.
if t.Colors < 8 || t.SetFg == "" {
t.Colors = 0
}
if t.SetCursor == "" {
return nil, errors.New("terminal not cursor addressable")
}
// For padding, we lookup the pad char. If that isn't present,
// and npc is *not* set, then we assume a null byte.
t.PadChar = tigetstr("pad")
if t.PadChar == "" {
if !tigetflag("npc") {
t.PadChar = "\u0000"
}
}
// For some terminals we fabricate a -truecolor entry, that may
// not exist in terminfo.
if addTrueColor {
t.SetFgRGB = "\x1b[38;2;%p1%d;%p2%d;%p3%dm"
t.SetBgRGB = "\x1b[48;2;%p1%d;%p2%d;%p3%dm"
t.SetFgBgRGB = "\x1b[38;2;%p1%d;%p2%d;%p3%d;" +
"48;2;%p4%d;%p5%d;%p6%dm"
}
// For terminals that use "standard" SGR sequences, lets combine the
// foreground and background together.
if strings.HasPrefix(t.SetFg, "\x1b[") &&
strings.HasPrefix(t.SetBg, "\x1b[") &&
strings.HasSuffix(t.SetFg, "m") &&
strings.HasSuffix(t.SetBg, "m") {
fg := t.SetFg[:len(t.SetFg)-1]
r := regexp.MustCompile("%p1")
bg := r.ReplaceAllString(t.SetBg[2:], "%p2")
t.SetFgBg = fg + ";" + bg
}
return t, nil
}
func dotGoAddInt(w io.Writer, n string, i int) {
if i == 0 {
// initialized to 0, ignore
return
}
fmt.Fprintf(w, " %-13s %d,\n", n+":", i)
}
func dotGoAddStr(w io.Writer, n string, s string) {
if s == "" {
return
}
fmt.Fprintf(w, " %-13s %q,\n", n+":", s)
}
func dotGoAddArr(w io.Writer, n string, a []string) {
if len(a) == 0 {
return
}
fmt.Fprintf(w, " %-13s []string{", n+":")
did := false
for _, b := range a {
if did {
fmt.Fprint(w, ", ")
}
did = true
fmt.Fprintf(w, "%q", b)
}
fmt.Fprintln(w, "},")
}
func dotGoHeader(w io.Writer) {
fmt.Fprintf(w, "// Generated by %s (%s/%s) on %s.\n",
os.Args[0],
runtime.GOOS, runtime.GOARCH,
time.Now().Format(time.UnixDate))
fmt.Fprintln(w, "// DO NOT HAND-EDIT")
fmt.Fprintln(w, "")
fmt.Fprintln(w, "package tcell")
fmt.Fprintln(w, "")
fmt.Fprintln(w, "func init() {")
}
func dotGoTrailer(w io.Writer) {
fmt.Fprintln(w, "}")
}
func dotGoInfo(w io.Writer, t *tcell.Terminfo) {
fmt.Fprintln(w, " AddTerminfo(&Terminfo{")
dotGoAddStr(w, "Name", t.Name)
dotGoAddArr(w, "Aliases", t.Aliases)
dotGoAddInt(w, "Columns", t.Columns)
dotGoAddInt(w, "Lines", t.Lines)
dotGoAddInt(w, "Colors", t.Colors)
dotGoAddStr(w, "Bell", t.Bell)
dotGoAddStr(w, "Clear", t.Clear)
dotGoAddStr(w, "EnterCA", t.EnterCA)
dotGoAddStr(w, "ExitCA", t.ExitCA)
dotGoAddStr(w, "ShowCursor", t.ShowCursor)
dotGoAddStr(w, "HideCursor", t.HideCursor)
dotGoAddStr(w, "AttrOff", t.AttrOff)
dotGoAddStr(w, "Underline", t.Underline)
dotGoAddStr(w, "Bold", t.Bold)
dotGoAddStr(w, "Dim", t.Dim)
dotGoAddStr(w, "Blink", t.Blink)
dotGoAddStr(w, "Reverse", t.Reverse)
dotGoAddStr(w, "EnterKeypad", t.EnterKeypad)
dotGoAddStr(w, "ExitKeypad", t.ExitKeypad)
dotGoAddStr(w, "SetFg", t.SetFg)
dotGoAddStr(w, "SetBg", t.SetBg)
dotGoAddStr(w, "SetFgBg", t.SetFgBg)
dotGoAddStr(w, "PadChar", t.PadChar)
dotGoAddStr(w, "AltChars", t.AltChars)
dotGoAddStr(w, "EnterAcs", t.EnterAcs)
dotGoAddStr(w, "ExitAcs", t.ExitAcs)
dotGoAddStr(w, "EnableAcs", t.EnableAcs)
dotGoAddStr(w, "SetFgRGB", t.SetFgRGB)
dotGoAddStr(w, "SetBgRGB", t.SetBgRGB)
dotGoAddStr(w, "SetFgBgRGB", t.SetFgBgRGB)
dotGoAddStr(w, "Mouse", t.Mouse)
dotGoAddStr(w, "MouseMode", t.MouseMode)
dotGoAddStr(w, "SetCursor", t.SetCursor)
dotGoAddStr(w, "CursorBack1", t.CursorBack1)
dotGoAddStr(w, "CursorUp1", t.CursorUp1)
dotGoAddStr(w, "KeyUp", t.KeyUp)
dotGoAddStr(w, "KeyDown", t.KeyDown)
dotGoAddStr(w, "KeyRight", t.KeyRight)
dotGoAddStr(w, "KeyLeft", t.KeyLeft)
dotGoAddStr(w, "KeyInsert", t.KeyInsert)
dotGoAddStr(w, "KeyDelete", t.KeyDelete)
dotGoAddStr(w, "KeyBackspace", t.KeyBackspace)
dotGoAddStr(w, "KeyHome", t.KeyHome)
dotGoAddStr(w, "KeyEnd", t.KeyEnd)
dotGoAddStr(w, "KeyPgUp", t.KeyPgUp)
dotGoAddStr(w, "KeyPgDn", t.KeyPgDn)
dotGoAddStr(w, "KeyF1", t.KeyF1)
dotGoAddStr(w, "KeyF2", t.KeyF2)
dotGoAddStr(w, "KeyF3", t.KeyF3)
dotGoAddStr(w, "KeyF4", t.KeyF4)
dotGoAddStr(w, "KeyF5", t.KeyF5)
dotGoAddStr(w, "KeyF6", t.KeyF6)
dotGoAddStr(w, "KeyF7", t.KeyF7)
dotGoAddStr(w, "KeyF8", t.KeyF8)
dotGoAddStr(w, "KeyF9", t.KeyF9)
dotGoAddStr(w, "KeyF10", t.KeyF10)
dotGoAddStr(w, "KeyF11", t.KeyF11)
dotGoAddStr(w, "KeyF12", t.KeyF12)
dotGoAddStr(w, "KeyF13", t.KeyF13)
dotGoAddStr(w, "KeyF14", t.KeyF14)
dotGoAddStr(w, "KeyF15", t.KeyF15)
dotGoAddStr(w, "KeyF16", t.KeyF16)
dotGoAddStr(w, "KeyF17", t.KeyF17)
dotGoAddStr(w, "KeyF18", t.KeyF18)
dotGoAddStr(w, "KeyF19", t.KeyF19)
dotGoAddStr(w, "KeyF20", t.KeyF20)
dotGoAddStr(w, "KeyF21", t.KeyF21)
dotGoAddStr(w, "KeyF22", t.KeyF22)
dotGoAddStr(w, "KeyF23", t.KeyF23)
dotGoAddStr(w, "KeyF24", t.KeyF24)
dotGoAddStr(w, "KeyF25", t.KeyF25)
dotGoAddStr(w, "KeyF26", t.KeyF26)
dotGoAddStr(w, "KeyF27", t.KeyF27)
dotGoAddStr(w, "KeyF28", t.KeyF28)
dotGoAddStr(w, "KeyF29", t.KeyF29)
dotGoAddStr(w, "KeyF30", t.KeyF30)
dotGoAddStr(w, "KeyF31", t.KeyF31)
dotGoAddStr(w, "KeyF32", t.KeyF32)
dotGoAddStr(w, "KeyF33", t.KeyF33)
dotGoAddStr(w, "KeyF34", t.KeyF34)
dotGoAddStr(w, "KeyF35", t.KeyF35)
dotGoAddStr(w, "KeyF36", t.KeyF36)
dotGoAddStr(w, "KeyF37", t.KeyF37)
dotGoAddStr(w, "KeyF38", t.KeyF38)
dotGoAddStr(w, "KeyF39", t.KeyF39)
dotGoAddStr(w, "KeyF40", t.KeyF40)
dotGoAddStr(w, "KeyF41", t.KeyF41)
dotGoAddStr(w, "KeyF42", t.KeyF42)
dotGoAddStr(w, "KeyF43", t.KeyF43)
dotGoAddStr(w, "KeyF44", t.KeyF44)
dotGoAddStr(w, "KeyF45", t.KeyF45)
dotGoAddStr(w, "KeyF46", t.KeyF46)
dotGoAddStr(w, "KeyF47", t.KeyF47)
dotGoAddStr(w, "KeyF48", t.KeyF48)
dotGoAddStr(w, "KeyF49", t.KeyF49)
dotGoAddStr(w, "KeyF50", t.KeyF50)
dotGoAddStr(w, "KeyF51", t.KeyF51)
dotGoAddStr(w, "KeyF52", t.KeyF52)
dotGoAddStr(w, "KeyF53", t.KeyF53)
dotGoAddStr(w, "KeyF54", t.KeyF54)
dotGoAddStr(w, "KeyF55", t.KeyF55)
dotGoAddStr(w, "KeyF56", t.KeyF56)
dotGoAddStr(w, "KeyF57", t.KeyF57)
dotGoAddStr(w, "KeyF58", t.KeyF58)
dotGoAddStr(w, "KeyF59", t.KeyF59)
dotGoAddStr(w, "KeyF60", t.KeyF60)
dotGoAddStr(w, "KeyF61", t.KeyF61)
dotGoAddStr(w, "KeyF62", t.KeyF62)
dotGoAddStr(w, "KeyF63", t.KeyF63)
dotGoAddStr(w, "KeyF64", t.KeyF64)
dotGoAddStr(w, "KeyCancel", t.KeyCancel)
dotGoAddStr(w, "KeyPrint", t.KeyPrint)
dotGoAddStr(w, "KeyExit", t.KeyExit)
dotGoAddStr(w, "KeyHelp", t.KeyHelp)
dotGoAddStr(w, "KeyClear", t.KeyClear)
dotGoAddStr(w, "KeyBacktab", t.KeyBacktab)
dotGoAddStr(w, "KeyShfLeft", t.KeyShfLeft)
dotGoAddStr(w, "KeyShfRight", t.KeyShfRight)
dotGoAddStr(w, "KeyShfUp", t.KeyShfUp)
dotGoAddStr(w, "KeyShfDown", t.KeyShfDown)
dotGoAddStr(w, "KeyCtrlLeft", t.KeyCtrlLeft)
dotGoAddStr(w, "KeyCtrlRight", t.KeyCtrlRight)
dotGoAddStr(w, "KeyCtrlUp", t.KeyCtrlUp)
dotGoAddStr(w, "KeyCtrlDown", t.KeyCtrlDown)
dotGoAddStr(w, "KeyMetaLeft", t.KeyMetaLeft)
dotGoAddStr(w, "KeyMetaRight", t.KeyMetaRight)
dotGoAddStr(w, "KeyMetaUp", t.KeyMetaUp)
dotGoAddStr(w, "KeyMetaDown", t.KeyMetaDown)
dotGoAddStr(w, "KeyAltLeft", t.KeyAltLeft)
dotGoAddStr(w, "KeyAltRight", t.KeyAltRight)
dotGoAddStr(w, "KeyAltUp", t.KeyAltUp)
dotGoAddStr(w, "KeyAltDown", t.KeyAltDown)
dotGoAddStr(w, "KeyAltShfLeft", t.KeyAltShfLeft)
dotGoAddStr(w, "KeyAltShfRight", t.KeyAltShfRight)
dotGoAddStr(w, "KeyAltShfUp", t.KeyAltShfUp)
dotGoAddStr(w, "KeyAltShfDown", t.KeyAltShfDown)
dotGoAddStr(w, "KeyMetaShfLeft", t.KeyMetaShfLeft)
dotGoAddStr(w, "KeyMetaShfRight", t.KeyMetaShfRight)
dotGoAddStr(w, "KeyMetaShfUp", t.KeyMetaShfUp)
dotGoAddStr(w, "KeyMetaShfDown", t.KeyMetaShfDown)
dotGoAddStr(w, "KeyCtrlShfLeft", t.KeyCtrlShfLeft)
dotGoAddStr(w, "KeyCtrlShfRight", t.KeyCtrlShfRight)
dotGoAddStr(w, "KeyCtrlShfUp", t.KeyCtrlShfUp)
dotGoAddStr(w, "KeyCtrlShfDown", t.KeyCtrlShfDown)
dotGoAddStr(w, "KeyShfHome", t.KeyShfHome)
dotGoAddStr(w, "KeyShfEnd", t.KeyShfEnd)
dotGoAddStr(w, "KeyCtrlHome", t.KeyCtrlHome)
dotGoAddStr(w, "KeyCtrlEnd", t.KeyCtrlEnd)
dotGoAddStr(w, "KeyMetaHome", t.KeyMetaHome)
dotGoAddStr(w, "KeyMetaEnd", t.KeyMetaEnd)
dotGoAddStr(w, "KeyAltHome", t.KeyAltHome)
dotGoAddStr(w, "KeyAltEnd", t.KeyAltEnd)
dotGoAddStr(w, "KeyCtrlShfHome", t.KeyCtrlShfHome)
dotGoAddStr(w, "KeyCtrlShfEnd", t.KeyCtrlShfEnd)
dotGoAddStr(w, "KeyMetaShfHome", t.KeyMetaShfHome)
dotGoAddStr(w, "KeyMetaShfEnd", t.KeyMetaShfEnd)
dotGoAddStr(w, "KeyAltShfHome", t.KeyAltShfHome)
dotGoAddStr(w, "KeyAltShfEnd", t.KeyAltShfEnd)
fmt.Fprintln(w, " })")
}
func MkInfo() ([]byte, error) {
jsonfile := ""
gofile := ""
nofatal := true
quiet := true
var e error
js := []byte{}
args := []string{os.Getenv("TERM")}
tdata := make(map[string]*tcell.Terminfo)
adata := make(map[string]string)
for _, term := range args {
if arr := strings.SplitN(term, "=", 2); len(arr) == 2 {
adata[arr[0]] = arr[1]
} else if t, e := getinfo(term); e != nil {
if !quiet {
fmt.Fprintf(os.Stderr,
"Failed loading %s: %v\n", term, e)
}
if !nofatal {
os.Exit(1)
}
} else {
tdata[t.Name] = t
}
}
for alias, canon := range adata {
if t, ok := tdata[canon]; ok {
t.Aliases = append(t.Aliases, alias)
// sort aliases to avoid extra diffs
sort.Strings(t.Aliases)
} else {
if !quiet {
fmt.Fprintf(os.Stderr,
"Alias %s missing canonical %s\n",
alias, canon)
}
if !nofatal {
os.Exit(1)
}
}
}
if gofile != "" {
w := os.Stdout
if gofile != "-" {
if w, e = os.Create(gofile); e != nil {
return []byte{}, fmt.Errorf("Failed: %v", e)
}
}
dotGoHeader(w)
for _, term := range args {
if t := tdata[term]; t != nil {
dotGoInfo(w, t)
}
}
dotGoTrailer(w)
if w != os.Stdout {
w.Close()
}
} else if jsonfile != "" {
w := os.Stdout
if jsonfile != "-" {
if w, e = os.Create(jsonfile); e != nil {
fmt.Fprintf(os.Stderr, "Failed: %v", e)
}
}
for _, term := range args {
if t := tdata[term]; t != nil {
js, e = json.Marshal(t)
fmt.Fprintln(w, string(js))
}
// arguably if there is more than one term, this
// should be a javascript array, but that's not how
// we load it. We marshal objects one at a time from
// the file.
}
if e != nil {
return []byte{}, fmt.Errorf("Failed: %v", e)
}
} else {
for _, term := range args {
if t := tdata[term]; t != nil {
js, e := json.Marshal(tdata[term])
if e != nil {
return []byte{}, fmt.Errorf("Failed ", e)
}
return js, nil
}
}
}
return []byte{}, nil
}

View File

@@ -85,6 +85,30 @@ func LuaFunctionCommand(function string) func([]string) {
}
}
// LuaFunctionComplete returns a function which can be used for autocomplete in plugins
func LuaFunctionComplete(function string) func(string) []string {
return func(input string) (result []string) {
res, err := Call(function, input)
if err != nil {
TermMessage(err)
}
if tbl, ok := res.(*lua.LTable); !ok {
TermMessage(function, "should return a table of strings")
} else {
for i := 1; i <= tbl.Len(); i++ {
val := tbl.RawGetInt(i)
if v, ok := val.(lua.LString); !ok {
TermMessage(function, "should return a table of strings")
} else {
result = append(result, string(v))
}
}
}
return result
}
}
func LuaFunctionJob(function string) func(string, ...string) {
return func(output string, args ...string) {
_, err := Call(function, unpack(append([]string{output}, args...))...)

File diff suppressed because one or more lines are too long

View File

@@ -125,8 +125,8 @@ func Search(searchStr string, v *View, down bool) {
return
}
v.Cursor.CurSelection[0] = FromCharPos(charPos+runePos(match[0], str), v.Buf)
v.Cursor.CurSelection[1] = FromCharPos(charPos+runePos(match[1], str), v.Buf)
v.Cursor.SetSelectionStart(FromCharPos(charPos+runePos(match[0], str), v.Buf))
v.Cursor.SetSelectionEnd(FromCharPos(charPos+runePos(match[1], str), v.Buf))
v.Cursor.Loc = v.Cursor.CurSelection[1]
if v.Relocate() {
v.matches = Match(v)

View File

@@ -1,7 +1,6 @@
package main
import (
"encoding/json"
"errors"
"io/ioutil"
"os"
@@ -9,6 +8,7 @@ import (
"strconv"
"strings"
"github.com/yosuke-furukawa/json5/encoding/json5"
"github.com/zyedidia/glob"
)
@@ -21,16 +21,21 @@ func InitGlobalSettings() {
var parsed map[string]interface{}
filename := configDir + "/settings.json"
writeSettings := false
if _, e := os.Stat(filename); e == nil {
input, err := ioutil.ReadFile(filename)
if err != nil {
TermMessage("Error reading settings.json file: " + err.Error())
return
}
if !strings.HasPrefix(string(input), "null") {
if err != nil {
TermMessage("Error reading settings.json file: " + err.Error())
return
}
err = json.Unmarshal(input, &parsed)
if err != nil {
TermMessage("Error reading settings.json:", err.Error())
err = json5.Unmarshal(input, &parsed)
if err != nil {
TermMessage("Error reading settings.json:", err.Error())
}
} else {
writeSettings = true
}
}
@@ -44,7 +49,7 @@ func InitGlobalSettings() {
}
}
if _, err := os.Stat(filename); os.IsNotExist(err) {
if _, err := os.Stat(filename); os.IsNotExist(err) || writeSettings {
err := WriteSettings(filename)
if err != nil {
TermMessage("Error writing settings.json file: " + err.Error())
@@ -65,7 +70,7 @@ func InitLocalSettings(buf *Buffer) {
return
}
err = json.Unmarshal(input, &parsed)
err = json5.Unmarshal(input, &parsed)
if err != nil {
TermMessage("Error reading settings.json:", err.Error())
}
@@ -92,31 +97,36 @@ func InitLocalSettings(buf *Buffer) {
func WriteSettings(filename string) error {
var err error
if _, e := os.Stat(configDir); e == nil {
var parsed map[string]interface{}
parsed := make(map[string]interface{})
filename := configDir + "/settings.json"
for k, v := range globalSettings {
parsed[k] = v
}
if _, e := os.Stat(filename); e == nil {
input, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
if string(input) != "null" {
if err != nil {
return err
}
err = json.Unmarshal(input, &parsed)
if err != nil {
TermMessage("Error reading settings.json:", err.Error())
}
}
err = json5.Unmarshal(input, &parsed)
if err != nil {
TermMessage("Error reading settings.json:", err.Error())
}
for k, v := range parsed {
if !strings.HasPrefix(reflect.TypeOf(v).String(), "map") {
if _, ok := globalSettings[k]; ok {
parsed[k] = globalSettings[k]
for k, v := range parsed {
if !strings.HasPrefix(reflect.TypeOf(v).String(), "map") {
if _, ok := globalSettings[k]; ok {
parsed[k] = globalSettings[k]
}
}
}
}
}
txt, _ := json.MarshalIndent(parsed, "", " ")
err = ioutil.WriteFile(filename, txt, 0644)
txt, _ := json5.MarshalIndent(parsed, "", " ")
err = ioutil.WriteFile(filename, append(txt, '\n'), 0644)
}
return err
}
@@ -156,9 +166,10 @@ func DefaultGlobalSettings() map[string]interface{} {
return map[string]interface{}{
"autoindent": true,
"colorscheme": "zenburn",
"cursorline": false,
"cursorline": true,
"ignorecase": false,
"indentchar": " ",
"infobar": true,
"ruler": true,
"savecursor": false,
"saveundo": false,
@@ -176,7 +187,7 @@ func DefaultGlobalSettings() map[string]interface{} {
func DefaultLocalSettings() map[string]interface{} {
return map[string]interface{}{
"autoindent": true,
"cursorline": false,
"cursorline": true,
"filetype": "Unknown",
"ignorecase": false,
"indentchar": " ",
@@ -197,6 +208,12 @@ func DefaultLocalSettings() map[string]interface{} {
// is local only it will set the local version
// Use setlocal to force an option to be set locally
func SetOption(option, value string) error {
if option == "colorscheme" {
if !ColorschemeExists(value) {
return errors.New(value + " is not a valid colorscheme")
}
}
if _, ok := globalSettings[option]; !ok {
if _, ok := CurView().Buf.Settings[option]; !ok {
return errors.New("Invalid option")
@@ -234,6 +251,12 @@ func SetOption(option, value string) error {
}
}
if option == "infobar" {
for _, tab := range tabs {
tab.Resize()
}
}
if _, ok := CurView().Buf.Settings[option]; ok {
for _, tab := range tabs {
for _, view := range tab.views {

View File

@@ -146,9 +146,7 @@ func (s *SplitTree) ResizeSplits() {
n.view.y = s.y + n.view.height*i
n.view.x = s.x
}
// n.view.ToggleStatusLine()
_, screenH := screen.Size()
if n.view.Buf.Settings["statusline"].(bool) || (n.view.y+n.view.height) != screenH-1 {
if n.view.Buf.Settings["statusline"].(bool) {
n.view.height--
}

View File

@@ -31,7 +31,12 @@ func NewTabFromView(v *View) *Tab {
w, h := screen.Size()
t.tree.width = w
t.tree.height = h - 1
t.tree.height = h
if globalSettings["infobar"].(bool) {
t.tree.height--
}
return t
}
@@ -49,7 +54,12 @@ func (t *Tab) Cleanup() {
func (t *Tab) Resize() {
w, h := screen.Size()
t.tree.width = w
t.tree.height = h - 1
t.tree.height = h
if globalSettings["infobar"].(bool) {
t.tree.height--
}
t.tree.ResizeSplits()
}
@@ -61,7 +71,7 @@ func CurView() *View {
// TabbarString returns the string that should be displayed in the tabbar
// It also returns a map containing which indicies correspond to which tab number
// This is useful when we know that the mouse click has occured at an x location
// This is useful when we know that the mouse click has occurred at an x location
// but need to know which tab that corresponds to to accurately change the tab
func TabbarString() (string, map[int]int) {
str := ""

View File

@@ -1,8 +1,11 @@
package main
import (
"bytes"
"os"
"path/filepath"
"reflect"
"runtime"
"strconv"
"strings"
"time"
@@ -20,8 +23,8 @@ func Count(s string) int {
return utf8.RuneCountInString(s)
}
// NumOccurences counts the number of occurences of a byte in a string
func NumOccurences(s string, c byte) int {
// NumOccurrences counts the number of occurences of a byte in a string
func NumOccurrences(s string, c byte) int {
var n int
for i := 0; i < len(s); i++ {
if s[i] == c {
@@ -154,7 +157,7 @@ func GetModTime(path string) (time.Time, bool) {
// StringWidth returns the width of a string where tabs count as `tabsize` width
func StringWidth(str string, tabsize int) int {
sw := runewidth.StringWidth(str)
sw += NumOccurences(str, '\t') * (tabsize - 1)
sw += NumOccurrences(str, '\t') * (tabsize - 1)
return sw
}
@@ -182,6 +185,34 @@ func runePos(p int, str string) int {
return utf8.RuneCountInString(str[:p])
}
func lcs(a, b string) string {
arunes := []rune(a)
brunes := []rune(b)
lcs := ""
for i, r := range arunes {
if i >= len(brunes) {
break
}
if r == brunes[i] {
lcs += string(r)
} else {
break
}
}
return lcs
}
func CommonSubstring(arr ...string) string {
commonStr := arr[0]
for _, str := range arr[1:] {
commonStr = lcs(commonStr, str)
}
return commonStr
}
// Abs is a simple absolute value function for ints
func Abs(n int) int {
if n < 0 {
@@ -189,3 +220,77 @@ func Abs(n int) int {
}
return n
}
// FuncName returns the name of a given function object
func FuncName(i interface{}) string {
return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
}
// SplitCommandArgs seperates multiple command arguments which may be quoted.
// The returned slice contains at least one string
func SplitCommandArgs(input string) []string {
var result []string
curArg := new(bytes.Buffer)
inQuote := false
escape := false
appendResult := func() {
str := curArg.String()
inQuote = false
escape = false
if strings.HasPrefix(str, `"`) && strings.HasSuffix(str, `"`) {
if unquoted, err := strconv.Unquote(str); err == nil {
str = unquoted
}
}
result = append(result, str)
curArg.Reset()
}
for _, r := range input {
if r == ' ' && !inQuote {
appendResult()
} else {
curArg.WriteRune(r)
if r == '"' && !inQuote {
inQuote = true
} else {
if inQuote && !escape {
if r == '"' {
inQuote = false
}
if r == '\\' {
escape = true
continue
}
}
}
}
escape = false
}
appendResult()
return result
}
// JoinCommandArgs joins multiple command arguments and quote the strings if needed.
func JoinCommandArgs(args ...string) string {
buf := new(bytes.Buffer)
first := true
for _, arg := range args {
if first {
first = false
} else {
buf.WriteRune(' ')
}
quoted := strconv.Quote(arg)
if quoted[1:len(quoted)-1] != arg || strings.ContainsRune(arg, ' ') {
buf.WriteString(quoted)
} else {
buf.WriteString(arg)
}
}
return buf.String()
}

View File

@@ -1,6 +1,9 @@
package main
import "testing"
import (
"reflect"
"testing"
)
func TestNumOccurences(t *testing.T) {
var tests = []struct {
@@ -13,7 +16,7 @@ func TestNumOccurences(t *testing.T) {
{"∆ƒ\tø ® \t\t", '\t', 3},
}
for _, test := range tests {
if got := NumOccurences(test.inputStr, test.inputChar); got != test.want {
if got := NumOccurrences(test.inputStr, test.inputChar); got != test.want {
t.Errorf("NumOccurences(%s, %c) = %d", test.inputStr, test.inputChar, got)
}
}
@@ -63,3 +66,48 @@ func TestIsWordChar(t *testing.T) {
t.Errorf("IsWordChar(\n)) = true")
}
}
func TestJoinAndSplitCommandArgs(t *testing.T) {
tests := []struct {
Query []string
Wanted string
}{
{[]string{`test case`}, `"test case"`},
{[]string{`quote "test"`}, `"quote \"test\""`},
{[]string{`slash\\\ test`}, `"slash\\\\\\ test"`},
{[]string{`path 1`, `path\" 2`}, `"path 1" "path\\\" 2"`},
{[]string{`foo`}, `foo`},
{[]string{`foo\"bar`}, `"foo\\\"bar"`},
{[]string{``}, ``},
{[]string{`"`}, `"\""`},
{[]string{`a`, ``}, `a `},
{[]string{``, ``, ``, ``}, ` `},
{[]string{"\n"}, `"\n"`},
{[]string{"foo\tbar"}, `"foo\tbar"`},
}
for i, test := range tests {
if result := JoinCommandArgs(test.Query...); test.Wanted != result {
t.Errorf("JoinCommandArgs failed at Test %d\nGot: %q", i, result)
}
if result := SplitCommandArgs(test.Wanted); !reflect.DeepEqual(test.Query, result) {
t.Errorf("SplitCommandArgs failed at Test %d\nGot: `%q`", i, result)
}
}
splitTests := []struct {
Query string
Wanted []string
}{
{`"hallo""Welt"`, []string{`"hallo""Welt"`}},
{`\"`, []string{`\"`}},
{`"\"`, []string{`"\"`}},
}
for i, test := range splitTests {
if result := SplitCommandArgs(test.Query); !reflect.DeepEqual(test.Wanted, result) {
t.Errorf("SplitCommandArgs failed at Split-Test %d\nGot: `%q`", i, result)
}
}
}

View File

@@ -84,7 +84,7 @@ type View struct {
// NewView returns a new fullscreen view
func NewView(buf *Buffer) *View {
screenW, screenH := screen.Size()
return NewViewWidthHeight(buf, screenW, screenH-1)
return NewViewWidthHeight(buf, screenW, screenH)
}
// NewViewWidthHeight returns a new view with the specified width and height
@@ -145,6 +145,20 @@ func (v *View) ToggleTabbar() {
}
}
func (v *View) paste(clip string) {
leadingWS := GetLeadingWhitespace(v.Buf.Line(v.Cursor.Y))
if v.Cursor.HasSelection() {
v.Cursor.DeleteSelection()
v.Cursor.ResetSelection()
}
clip = strings.Replace(clip, "\n", "\n"+leadingWS, -1)
v.Buf.Insert(v.Cursor.Loc, clip)
v.Cursor.Loc = v.Cursor.Loc.Move(Count(clip), v.Buf)
v.freshClip = false
messenger.Message("Pasted clipboard")
}
// ScrollUp scrolls the view up n lines (if possible)
func (v *View) ScrollUp(n int) {
// Try to scroll by n but if it would overflow, scroll by 1
@@ -169,15 +183,15 @@ func (v *View) ScrollDown(n int) {
// If there are unsaved changes, the user will be asked if the view can be closed
// causing them to lose the unsaved changes
// The message is what to print after saying "You have unsaved changes. "
func (v *View) CanClose(msg string) bool {
func (v *View) CanClose() bool {
if v.Buf.IsModified {
quit, canceled := messenger.Prompt("You have unsaved changes. "+msg, "Unsaved", NoCompletion)
char, canceled := messenger.LetterPrompt("Save changes to "+v.Buf.Name+" before closing? (y,n,esc) ", 'y', 'n')
if !canceled {
if strings.ToLower(quit) == "yes" || strings.ToLower(quit) == "y" {
return true
} else if strings.ToLower(quit) == "save" || strings.ToLower(quit) == "s" {
if char == 'y' {
v.Save(true)
return true
} else if char == 'n' {
return true
}
}
} else {
@@ -217,7 +231,7 @@ func (v *View) CloseBuffer() {
// ReOpen reloads the current buffer
func (v *View) ReOpen() {
if v.CanClose("Continue? (yes, no, save) ") {
if v.CanClose() {
screen.Clear()
v.Buf.ReOpen()
v.Relocate()
@@ -326,6 +340,10 @@ func (v *View) HandleEvent(event tcell.Event) {
TermMessage(err)
}
}
if recordingMacro {
curMacro = append(curMacro, e.Rune())
}
} else {
for key, actions := range bindings {
if e.Key() == key.keyCode {
@@ -338,13 +356,36 @@ func (v *View) HandleEvent(event tcell.Event) {
relocate = false
for _, action := range actions {
relocate = action(v, true) || relocate
funcName := FuncName(action)
if funcName != "main.(*View).ToggleMacro" && funcName != "main.(*View).PlayMacro" {
if recordingMacro {
curMacro = append(curMacro, action)
}
}
}
}
}
}
}
case *tcell.EventPaste:
relocate = v.Paste(true)
if !PreActionCall("Paste", v) {
break
}
leadingWS := GetLeadingWhitespace(v.Buf.Line(v.Cursor.Y))
if v.Cursor.HasSelection() {
v.Cursor.DeleteSelection()
v.Cursor.ResetSelection()
}
clip := e.Text()
clip = strings.Replace(clip, "\n", "\n"+leadingWS, -1)
v.Buf.Insert(v.Cursor.Loc, clip)
v.Cursor.Loc = v.Cursor.Loc.Move(Count(clip), v.Buf)
v.freshClip = false
messenger.Message("Pasted clipboard")
PostActionCall("Paste", v)
case *tcell.EventMouse:
x, y := e.Position()
x -= v.lineNumOffset - v.leftCol + v.x
@@ -394,9 +435,13 @@ func (v *View) HandleEvent(event tcell.Event) {
} else if v.doubleClick {
v.Cursor.AddWordToSelection()
} else {
v.Cursor.CurSelection[1] = v.Cursor.Loc
v.Cursor.SetSelectionEnd(v.Cursor.Loc)
}
}
case tcell.Button2:
// Middle mouse button was clicked,
// We should paste primary
v.PastePrimary(true)
case tcell.ButtonNone:
// Mouse event with no click
if !v.mouseReleased {
@@ -410,7 +455,7 @@ func (v *View) HandleEvent(event tcell.Event) {
if !v.doubleClick && !v.tripleClick {
v.MoveToMouseClick(x, y)
v.Cursor.CurSelection[1] = v.Cursor.Loc
v.Cursor.SetSelectionEnd(v.Cursor.Loc)
}
v.mouseReleased = true
}
@@ -600,7 +645,7 @@ func (v *View) DisplayView() {
lineNumStyle = style
}
if style, ok := colorscheme["current-line-number"]; ok {
if curLineN == v.Cursor.Y {
if curLineN == v.Cursor.Y && tabs[curTab].curView == v.Num && !v.Cursor.HasSelection() {
lineNumStyle = style
}
}

View File

@@ -0,0 +1,19 @@
color-link default "241,231"
color-link comment "246,231"
color-link constant "130,231"
color-link constant.string "136,231"
color-link constant.number "131,231"
color-link identifier "133,231"
color-link statement "32,231"
color-link preproc "28,231"
color-link type "61,231"
color-link special "167,231"
color-link error "231, 160"
color-link underlined "underline 241,231"
color-link todo "246,231"
color-link statusline "241,254"
color-link gutter-error "197,231"
color-link gutter-warning "134,231"
color-link line-number "246,254"
color-link cursor-line "254"

View File

@@ -1,16 +1,20 @@
color-link comment "blue"
color-link constant "red"
color-link identifier "cyan"
color-link statement "yellow"
color-link preproc "magenta"
color-link type "green"
color-link special "magenta"
color-link ignore "default"
color-link error ",brightred"
color-link todo ",brightyellow"
color-link indent-char "black"
color-link line-number "yellow"
color-link current-line-number "red"
color-link gutter-error ",red"
color-link gutter-warning "red"
color-link cursor-line "white"
color-link default "188,237"
color-link comment "108,237"
color-link constant.string "174,237"
color-link constant.number "116,237"
color-link constant "181,237"
color-link identifier "223,237"
color-link statement "223,237"
color-link preproc "223,237"
color-link type "187,237"
color-link special "181,237"
color-link underlined "188,237"
color-link error "115,236"
color-link todo "bold 254,237"
color-link statusline "186,236"
color-link indent-char "238,237"
color-link line-number "188,238"
color-link gutter-error "237,174"
color-link gutter-warning "174,237"
color-link cursor-line "238"
color-link current-line-number "188,237"

View File

@@ -0,0 +1,16 @@
color-link comment "blue"
color-link constant "red"
color-link identifier "cyan"
color-link statement "yellow"
color-link preproc "magenta"
color-link type "green"
color-link special "magenta"
color-link ignore "default"
color-link error ",brightred"
color-link todo ",brightyellow"
color-link indent-char "black"
color-link line-number "yellow"
color-link current-line-number "red"
color-link gutter-error ",red"
color-link gutter-warning "red"
color-link cursor-line "white"

View File

@@ -13,7 +13,7 @@ color-link error "115,236"
color-link todo "bold 254,237"
color-link statusline "186,236"
color-link indent-char "238,237"
color-link line-number "188,238"
color-link line-number "248,238"
color-link gutter-error "237,174"
color-link gutter-warning "174,237"
color-link cursor-line "238"

View File

@@ -9,9 +9,13 @@ This help page aims to cover two aspects of micro's syntax highlighting engine:
Micro comes with a number of colorschemes by default. Here is the list:
* default: this is the simplest colorscheme. It uses 16 colors which are
* simple: this is the simplest colorscheme. It uses 16 colors which are
set by your terminal
* zenburn: this is micro's default colorscheme because it looks very good
and works in 256 color terminals.
this colorscheme also has the name 'default'
* solarized: this is the solarized colorscheme.
You should have the solarized color palette in your terminal to use it.
@@ -19,8 +23,8 @@ Micro comes with a number of colorschemes by default. Here is the list:
make sure your terminal supports true color before using it and that the
MICRO_TRUECOLOR environment variable is set to 1 before starting micro.
* monokai: this is the monokai colorscheme and is micro's default colorscheme
(as well as sublime text's). It requires true color to
* monokai: this is the monokai colorscheme, you may recognize it as
sublime text's default colorscheme. It requires true color to
look perfect, but the 256 color approximation looks very good as well.
* atom-dark-tc: this colorscheme is based off of Atom's "dark" colorscheme.

View File

@@ -21,6 +21,8 @@ Here are the possible commands that you can use.
* `setlocal option value`: sets the option to value locally (only in the current
buffer).
* `show option`: shows the current value of the given option.
* `run sh-command`: runs the given shell command in the background. The
command's output will be displayed in one line when it finishes running.

View File

@@ -3,6 +3,12 @@
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.
*Press CtrlQ to quit, and CtrlS to save.*
If you want to see all the keybindings press CtrlE and type `help keybindings`.
See the next section for more information about documentation and help.
### Accessing more help
Micro has a built-in help system much like Vim's (although less extensive).
@@ -12,6 +18,7 @@ Typing help followed by nothing will open this page.
Here are the possible help topics that you can read:
* tutorial: A brief tutorial which gives an overview of all the other help topics
* keybindings: Gives a full list of the default keybindings as well as how to rebind them
* commands: Gives a list of all the commands and what they do
* options: Gives a list of all the options you can customize
@@ -21,15 +28,6 @@ Here are the possible help topics that you can read:
For example to open the help page on plugins you would press CtrlE and type `help plugins`.
### Usage
Once you have built the editor, simply start it by running
`micro path/to/file.txt` or simply `micro` to open an empty buffer.
Micro also supports creating buffers from stdin:
```
$ ifconfig | micro
```
You can move the cursor around with the arrow keys and mouse.
I recommend looking at the `tutorial` help file because it is short for each section and
gives concrete examples of how to use the various configuration options in micro. However,
it does not give the in-depth documentation that the other topics provide.

View File

@@ -45,11 +45,13 @@ you can rebind them to your liking.
"CtrlD": "DuplicateLine",
"CtrlV": "Paste",
"CtrlA": "SelectAll",
"CtrlT": "AddTab"
"CtrlT": "AddTab",
"CtrlRightSq": "PreviousTab",
"CtrlBackslash": "NextTab",
"Home": "Start",
"End": "End",
"CtrlHome": "CursorStart",
"CtrlEnd": "CursorEnd",
"PageUp": "CursorPageUp",
"PageDown": "CursorPageDown",
"CtrlG": "ToggleHelp",
@@ -61,6 +63,8 @@ you can rebind them to your liking.
"CtrlQ": "Quit",
"CtrlE": "CommandMode",
"CtrlW": "NextSplit",
"CtrlU": "ToggleMacro",
"CtrlJ": "PlayMacro",
// Emacs-style keybindings
"Alt-f": "WordRight",
@@ -136,6 +140,7 @@ InsertNewline
InsertSpace
Backspace
Delete
Center
InsertTab
Save
Find
@@ -168,11 +173,14 @@ ClearStatus
ShellMode
CommandMode
Quit
QuitAll
AddTab
PreviousTab
NextTab
NextSplit
PreviousSplit
ToggleMacro
PlayMacro
```
Here is the list of all possible keys you can bind:

View File

@@ -20,21 +20,8 @@ Here are the options that you can set:
~/.config/micro/colorschemes/ directory. Micro comes by default with three
colorschemes:
* default: this is the default colorscheme.
* solarized: this is the solarized colorscheme (used in the screenshot).
You should have the solarized color palette in your terminal to use it.
* solarized-tc: this is the solarized colorscheme for true color, just
make sure your terminal supports true color before using it and that the
MICRO_TRUECOLOR environment variable is set to 1 before starting micro.
* monokai-tc: this is the monokai colorscheme. It requires true color to
look perfect, but the 256 color approximation looks good as well.
* atom-dark-tc: this colorscheme is based off of Atom's "dark" colorscheme.
It requires true color to look good.
You can read more about micro's colorschemes in the `colors` help topic
(`help colors`).
* `tabsize`: sets the tab size to `option`
@@ -44,6 +31,11 @@ Here are the options that you can set:
default value: ` `
* `infobar`: enables the line at the bottom of the editor where messages are printed.
This option is `global only`.
default value: `on`
* `filetype`: sets the filetype for the current buffer. This setting is `local only`
default value: this will be automatically set depending on the file you have open
@@ -68,7 +60,7 @@ Here are the options that you can set:
* `cursorline`: highlight the line that the cursor is on in a different color
(the color is defined by the colorscheme you are using)
default value: `off`
default value: `on`
* `ruler`: display line numbers
@@ -136,16 +128,16 @@ In the `settings.json` file you can also put set options locally by specifying a
Here is an example which has `tabstospaces` on for all files except Go files, and
`tabsize` 4 for all files except Ruby files:
```
```json
{
"*.go": {
"tabstospaces": false
},
"*.rb": {
"tabsize": 2
}
},
"tabstospaces": true,
"tabsize": 4,
"tabsize": 4
}
```

View File

@@ -37,7 +37,7 @@ for example turning off `tabstospaces` only for Go files when they are opened.
---
There are a number of functions and variables that are available to you in
oder to access the inner workings of micro. Here is a list (the type signatures
order to access the inner workings of micro. Here is a list (the type signatures
for functions are given using Go's type system):
* `OS`: variable which gives the OS micro is currently running on (this is the same
@@ -66,6 +66,9 @@ as Go's GOOS variable, so `darwin`, `windows`, `linux`, `freebsd`...)
creates a command with `name` which will call `function` when executed.
Use 0 for completions to get NoCompletion.
* `MakeCompletion(function string)`:
creates a `Completion` to use with `MakeCommand`.
* `CurView()`: returns the current view
* `HandleCommand(cmd string)`: runs the given command
@@ -104,6 +107,36 @@ The possible methods which you can call using the `messenger` variable are:
If you want a standard prompt, just use `messenger.Prompt(prompt, "", 0)`
# Autocomplete command arguments
See this example to learn how to use `MakeCompletion` and `MakeCommand`
```lua
local function StartsWith(String,Start)
String = String:upper()
Start = Start:upper()
return string.sub(String,1,string.len(Start))==Start
end
function complete(input)
local allCompletions = {"Hello", "World", "Foo", "Bar"}
local result = {}
for i,v in pairs(allCompletions) do
if StartsWith(v, input) then
table.insert(result, v)
end
end
return result
end
function foo(arg)
messenger:Message(arg)
end
MakeCommand("foo", "example.foo", MakeCompletion("example.complete"))
```
# Default plugins
For examples of plugins, see the default plugins `linter`, `go`, and `autoclose`.

View File

@@ -1,7 +1,7 @@
# Tutorial
This is a brief intro to micro's configuration system that will will give some
simple examples showing how to configure settings, rebind keys,
This is a brief intro to micro's configuration system that will give some
simple examples showing how to configure settings, rebind keys,
and use `init.lua` to configure micro to your liking.
Hopefully you'll find this useful.
@@ -68,13 +68,13 @@ what actions are available, see the `keybindings` help topic (`> help keybinding
If you need more power than the json files provide, you can use the `init.lua`
file. Create it in `~/.config/micro`. This file is a lua file that is run
when micro starts and is essential a one-file plugin.
when micro starts and is essentially a one-file plugin.
I'll show you how to use the `init.lua` file by giving an example of how to
create a binding to `CtrlR` which will execute `go run` on the current file,
given that the current file is a Go file.
You can do that by puttint the following in `init.lua`:
You can do that by putting the following in `init.lua`:
```lua
function gorun()

View File

@@ -2,10 +2,14 @@ if GetOption("linter") == nil then
AddOption("linter", true)
end
MakeCommand("lint", "linter.runLinter", 0)
MakeCommand("lint", "linter.lintCommand", 0)
function lintCommand()
CurView():Save(false)
runLinter()
end
function runLinter()
CurView():Save(false)
local ft = CurView().Buf:FileType()
local file = CurView().Buf.Path
local devnull = "/dev/null"

View File

@@ -8,8 +8,6 @@ Micro syntax files are almost identical to Nano's, except for some key differenc
* Micro does not use `icolor`. Instead, for a case insensitive match, use the case insensitive flag (`i`) in the regular expression
* For example, `icolor green ".*"` would become `color green (i) ".*"`
* Micro does not support `start="..." end="..."`. Instead use the `s` flag to match newlines and put `.*?` in the middle
* For example `color green start="hello" end="world"` would become `color green (s) "hello.*?world"`
# Using with colorschemes
@@ -29,6 +27,7 @@ Here is a list of the files that have been converted to properly use colorscheme
* rust
* java
* javascript
* pascal
* python
* ruby
* sh

View File

@@ -1,17 +1,93 @@
## Here is an example for assembler.
##
## Made by Nickolay Ilyushin <nickolay02@inbox.ru>. Next line is from previous (first) version (no need for modifications :P)
syntax "asm" "\.(S|s|asm)$"
color red "\<[A-Z_]{2,}\>"
color brightgreen "\.(data|subsection|text)"
color green "\.(align|file|globl|global|hidden|section|size|type|weak)"
color brightyellow "\.(ascii|asciz|byte|double|float|hword|int|long|short|single|struct|word)"
brightred (i) "^[[:space:]]*[.0-9A-Z_]*:"
color brightcyan "^[[:space:]]*#[[:space:]]*(define|undef|include|ifn?def|endif|elif|else|if|warning|error)"
## Highlight strings (note: VERY resource intensive)
color brightyellow "<[^= ]*>" ""(\\.|[^"])*""
color brightyellow start=""(\\.|[^"])*\\[[:space:]]*$" end="^(\\.|[^"])*""
## Highlight comments
color brightblue "//.*"
color brightblue start="/\*" end="\*/"
## Highlight trailing whitespace
color ,green "[[:space:]]+$"
# This file is made for NASM assembly
## Instructions
# x86
color statement "\b(?i)(mov|aaa|aad|aam|aas|adc|add|and|call|cbw|clc|cld|cli|cmc|cmp|cmpsb|cmpsw|cwd|daa|das|dec|div|esc|hlt|idiv|imul|in|inc|int|into|iret|ja|jae|jb|jbe|jc|je|jg|jge|jl|jle|jna|jnae|jnb|jnbe|jnc|jne|jng|jnge|jnl|jnle|jno|jnp|jns|jnz|jo|jp|jpe|jpo|js|jz|jcxz|jmp|lahf|lds|lea|les|lock|lodsb|lodsw|loop|loope|loopne|loopnz|loopz|movsb|movsw|mul|neg|nop|or|pop|popf|push|pushf|rcl|rcr|rep|repe|repne|repnz|repz|ret|retn|retf|rol|ror|sahf|sal|sar|sbb|scasb|scasw|shl|shr|stc|std|sti|stosb|stosw|sub|test|wait|xchg|xlat|xor)(?-i)\b"
color statement "\b(?i)(bound|enter|ins|leave|outs|popa|pusha)(?-i)\b"
color statement "\b(?i)(arpl|clts|lar|lgdt|lidt|lldt|lmsw|loadall|lsl|ltr|sgdt|sidt|sldt|smsw|str|verr|verw)(?-i)\b"
color statement "\b(?i)(bsf|bsr|bt|btc|btr|bts|cdq|cmpsd|cwde|insd|iret|iretd|iretf|jecxz|lfs|lgs|lss|lodsd|loopw|loopew|loopnew|loopnzw|loopzw|loopd|looped|loopned|loopnzd|loopzd|cr|tr|dr|movsd|movsx|movzx|outsd|popad|popfd|pushad|pushfd|scasd|seta|setae|setb|setbe|setc|sete|setg|setge|setl|setle|setna|setnae|setnb|setnbe|setnc|setne|setng|setnge|setnl|setnle|setno|setnp|setns|setnz|seto|setp|setpe|setpo|sets|setz|shdl|shrd|stosd)(?-i)\b"
color statement "\b(?i)(bswap|cmpxcgh|invd|invlpg|wbinvd|xadd)(?-i)\b"
color statement "\b(?i)(cpuid|cmpxchg8b|rdmsr|rdtsc|wrmsr|rsm)(?-i)\b"
color statement "\b(?i)(rdpmc)(?-i)\b"
color statement "\b(?i)(syscall|sysret)(?-i)\b"
color statement "\b(?i)(cmova|cmovae|cmovb|cmovbe|cmovc|cmove|cmovg|cmovge|cmovl|cmovle|cmovna|cmovnae|cmovnb|cmovnbe|cmovnc|cmovne|cmovng|cmovnge|cmovnle|cmovno|cmovpn|cmovns|cmovnz|cmovo|cmovp|cmovpe|cmovpo|cmovs|cmovz|sysenter|sysexit|ud2)(?-i)\b"
color statement "\b(?i)(maskmovq|movntps|movntq|prefetch0|prefetch1|prefetch2|prefetchnta|sfence)(?-i)\b"
color statement "\b(?i)(clflush|lfence|maskmovdqu|mfence|movntdq|movnti|movntpd|pause)(?-i)\b"
color statement "\b(?i)(monitor|mwait)(?-i)\b"
color statement "\b(?i)(cdqe|cqo|cmpsq|cmpxchg16b|iretq|jrcxz|lodsq|movsdx|popfq|pushfq|rdtscp|scasq|stosq|swapgs)(?-i)\b"
color statement "\b(?i)(clgi|invlpga|skinit|stgi|vmload|vmmcall|vmrun|vmsave)(?-i)\b"
color statement "\b(?i)(vmptrdl|vmptrst|vmclear|vmread|vmwrite|vmcall|vmlaunch|vmresume|vmxoff|vmxon)(?-i)\b"
color statement "\b(?i)(lzcnt|popcnt)(?-i)\b"
color statement "\b(?i)(bextr|blcfill|blci|blcic|blcmask|blcs|blsfill|blsic|t1mskc|tzmsk)(?-i)\b"
# x87
color statement "\b(?i)(f2xm1|fabs|fadd|faddp|fbld|fbstp|fchs|fclex|fcom|fcomp|fcompp|fdecstp|fdisi|fdiv|fvidp|fdivr|fdivrp|feni|ffree|fiadd|ficom|ficomp|fidiv|fidivr|fild|fimul|fincstp|finit|fist|fistp|fisub|fisubr|fld|fld1|fldcw|fldenv|fldenvw|fldl2e|fldl2t|fldlg2|fldln2|fldpi|fldz|fmul|fmulp|fnclex|fndisi|fneni|fninit|fnop|fnsave|fnsavenew|fnstcw|fnstenv|fnstenvw|fnstsw|fpatan|fprem|fptan|frndint|frstor|frstorw|fsave|fsavew|fscale|fsqrt|fst|fstcw|fstenv|fstenvw|fstp|fstpsw|fsub|fsubp|fsubr|fsubrp|ftst|fwait|fxam|fxch|fxtract|fyl2x|fyl2xp1)(?-i)\b"
color statement "\b(?i)(fsetpm)(?-i)\b"
color statement "\b(?i)(fcos|fldenvd|fsaved|fstenvd|fprem1|frstord|fsin|fsincos|fstenvd|fucom|fucomp|fucompp)(?-i)\b"
color statement "\b(?i)(fcmovb|fcmovbe|fcmove|fcmove|fcmovnb|fcmovnbe|fcmovne|fcmovnu|fcmovu)(?-i)\b"
color statement "\b(?i)(fcomi|fcomip|fucomi|fucomip)(?-i)\b"
color statement "\b(?i)(fxrstor|fxsave)(?-i)\b"
color statement "\b(?i)(fisttp)(?-i)\b"
color statement "\b(?i)(ffreep)(?-i)\b"
# SIMD
color statement "\b(?i)(emms|movd|movq|packssdw|packsswb|packuswb|paddb|paddw|paddd|paddsb|paddsw|paddusb|paddusw|pand|pandn|por|pxor|pcmpeqb|pcmpeqw|pcmpeqd|pcmpgtb|pcmpgtw|pcmpgtd|pmaddwd|pmulhw|pmullw|psllw|pslld|psllq|psrad|psraw|psrlw|psrld|psrlq|psubb|psubw|psubd|psubsb|psubsw|psubusb|punpckhbw|punpckhwd|punpckhdq|punkcklbw|punpckldq|punpcklwd)(?-i)\b"
color statement "\b(?i)(paveb|paddsiw|pmagw|pdistib|psubsiw|pmwzb|pmulhrw|pmvnzb|pmvlzb|pmvgezb|pmulhriw|pmachriw)(?-i)\b"
color statement "\b(?i)(femms|pavgusb|pf2id|pfacc|pfadd|pfcmpeq|pfcmpge|pfcmpgt|pfmax|pfmin|pfmul|pfrcp|pfrcpit1|pfrcpit2|pfrsqit1|pfrsqrt|pfsub|pfsubr|pi2fd|pmulhrw|prefetch|prefetchw)(?-i)\b"
color statement "\b(?i)(pf2iw|pfnacc|pfpnacc|pi2fw|pswapd)(?-i)\b"
color statement "\b(?i)(pfrsqrtv|pfrcpv)(?-i)\b"
color statement "\b(?i)(addps|addss|cmpps|cmpss|comiss|cvtpi2ps|cvtps2pi|cvtsi2ss|cvtss2si|cvttps2pi|cvttss2si|divps|divss|ldmxcsr|maxps|maxss|minps|minss|movaps|movhlps|movhps|movlhps|movlps|movmskps|movntps|movss|movups|mulps|mulss|rcpps|rcpss|rsqrtps|rsqrtss|shufps|sqrtps|sqrtss|stmxcsr|subps|subss|ucomiss|unpckhps|unpcklps)(?-i)\b"
color statement "\b(?i)(andnps|andps|orps|pavgb|pavgw|pextrw|pinsrw|pmaxsw|pmaxub|pminsw|pminub|pmovmskb|pmulhuw|psadbw|pshufw|xorps)(?-i)\b"
color statement "\b(?i)(movups|movss|movlps|movhlps|movlps|unpcklps|unpckhps|movhps|movlhps|prefetchnta|prefetch0|prefetch1|prefetch2|nop|movaps|cvtpi2ps|cvtsi2ss|cvtps2pi|cvttss2si|cvtps2pi|cvtss2si|ucomiss|comiss|sqrtps|sqrtss|rsqrtps|rsqrtss|rcpps|andps|orps|xorps|addps|addss|mulps|mulss|subps|subss|minps|minss|divps|divss|maxps|maxss|pshufw|ldmxcsr|stmxcsr|sfence|cmpps|cmpss|pinsrw|pextrw|shufps|pmovmskb|pminub|pmaxub|pavgb|pavgw|pmulhuw|movntq|pminsw|pmaxsw|psadbw|maskmovq)(?-i)\b"
color statement "\b(?i)(addpd|addsd|addnpd|cmppd|cmpsd)(?-i)\b"
color statement "\b(?i)(addpd|addsd|andnpd|andpd|cmppd|cmpsd|comisd|cvtdq2pd|cvtdq2ps|cvtpd2dq|cvtpd2pi|cvtpd2ps|cvtpi2pd|cvtps2dq|cvtps2pd|cvtsd2si|cvtsd2ss|cvtsi2sd|cvtss2sd|cvttpd2dq|cvttpd2pi|cvttps2dq|cvttsd2si|divpd|divsd|maxpd|maxsd|minpd|minsd|movapd|movhpd|movlpd|movmskpd|movsd|movupd|mulpd|mulsd|orpd|shufpd|sqrtpd|sqrtsd|subpd|subsd|ucomisd|unpckhpd|unpcklpd|xorpd)(?-i)\b"
color statement "\b(?i)(movdq2q|movdqa|movdqu|movq2dq|paddq|psubq|pmuludq|pshufhw|pshuflw|pshufd|pslldq|psrldq|punpckhqdq|punpcklqdq)(?-i)\b"
color statement "\b(?i)(addsubpd|addsubps|haddpd|haddps|hsubpd|hsubps|movddup|movshdup|movsldu)(?-i)\b"
color statement "\b(?i)(lddqu)(?-i)\b"
color statement "\b(?i)(psignw|psignd|psignb|pshufb|pmulhrsw|pmaddubsw|phsubw|phsubsw|phsubd|phaddw|phaddsw|phaddd|palignr|pabsw|pabsd|pabsb)(?-i)\b"
color statement "\b(?i)(dpps|dppd|blendps|blendpd|blendvps|blendvpd|roundps|roundss|roundpd|roundsd|insertps|extractps)(?-i)\b"
color statement "\b(?i)(mpsadbw|phminposuw|pmulld|pmuldq|pblendvb|pblendw|pminsb|pmaxsb|pminuw|pmaxuw|pminud|pmaxud|pminsd|pmaxsd|pinsrb|pinsrd/pinsrq|pextrb|pextrw|pextrd/pextrq|pmovsxbw|pmovzxbw|pmovsxbd|pmovzxbd|pmovsxbq|pmovzxbq|pmovsxwd|pmovzxwd|pmovsxwq|pmovzxwq|pmovsxdq|pmovzxdq|ptest|pcmpeqq|packusdw|movntdqa)(?-i)\b"
color statement "\b(?i)(extrq|insertq|movntsd|movntss)(?-i)\b"
color statement "\b(?i)(crc32|pcmpestri|pcmpestrm|pcmpistri|pcmpistrm|pcmpgtq)(?-i)\b"
color statement "\b(?i)(vfmaddpd|vfmaddps|vfmaddsd|vfmaddss|vfmaddsubpd|vfmaddsubps|vfmsubaddpd|vfmsubaddps|vfmsubpd|vfmsubps|vfmsubsd|vfmsubss|vfnmaddpd|vfnmaddps|vfnmaddsd|vfnmaddss|vfnmsubps|vfnmsubsd|vfnmsubss)(?-i)\b"
# Crypto
color statement "\b(?i)(aesenc|aesenclast|aesdec|aesdeclast|aeskeygenassist|aesimc)(?-i)\b"
color statement "\b(?i)(sha1rnds4|sha1nexte|sha1msg1|sha1msg2|sha256rnds2|sha256msg1|sha256msg2)(?-i)\b"
# Undocumented
color statement "\b(?i)(aam|aad|salc|icebp|loadall|loadalld|ud1)(?-i)\b"
## Registers
color identifier "\b(?i)(al|ah|bl|bh|cl|ch|dl|dh|bpl|sil|r8b|r9b|r10b|r11b|dil|spl|r12b|r13b|r14b|r15)(?-i)\b"
color identifier "\b(?i)(cw|sw|tw|fp_ds|fp_opc|fp_ip|fp_dp|fp_cs|cs|ss|ds|es|fs|gs|gdtr|idtr|tr|ldtr|ax|bx|cx|dx|bp|si|r8w|r9w|r10w|r11w|di|sp|r12w|r13w|r14w|r15w|ip)(?-i)\b"
color identifier "\b(?i)(fp_dp|fp_ip|eax|ebx|ecx|edx|ebp|esi|r8d|r9d|r10d|r11d|edi|esp|r12d|r13d|r14d|r15d|eip|eflags|mxcsr)(?-i)\b"
color identifier "\b(?i)(mm0|mm1|mm2|mm3|mm4|mm5|mm6|mm7|rax|rbx|rcx|rdx|rbp|rsi|r8|r9|r10|r11|rdi|rsp|r12|r13|r14|r15|rip|rflags|cr0|cr1|cr2|cr3|cr4|cr5|cr6|cr7|cr8|cr9|cr10|cr11|cr12|cr13|cr14|cr15|msw|dr0|dr1|dr2|dr3|r4|dr5|dr6|dr7|dr8|dr9|dr10|dr11|dr12|dr13|dr14|dr15)(?-i)\b"
color identifier "\b(?i)(st0|st1|st2|st3|st4|st5|st6|st7)(?-i)\b"
color identifier "\b(?i)(xmm0|xmm1|xmm2|xmm3|xmm4|xmm5|xmm6|xmm7|xmm8|xmm9|xmm10|xmm11|xmm12|xmm13|xmm14|xmm15)(?-i)\b"
color identifier "\b(?i)(ymm0|ymm1|ymm2|ymm3|ymm4|ymm5|ymm6|ymm7|ymm8|ymm9|ymm10|ymm11|ymm12|ymm13|ymm14|ymm15)(?-i)\b"
color identifier "\b(?i)(zmm0|zmm1|zmm2|zmm3|zmm4|zmm5|zmm6|zmm7|zmm8|zmm9|zmm10|zmm11|zmm12|zmm13|zmm14|zmm15|zmm16|zmm17|zmm18|zmm19|zmm20|zmm21|zmm22|zmm23|zmm24|zmm25|zmm26|zmm27|zmm28|zmm29|zmm30|zmm31)(?-i)\b"
## Constants
# Number - it works
color constant.number "\b(|h|A|0x)+[0-9]+(|h|A)+\b"
color constant.number "\b0x[0-9 a-f A-F]+\b"
## Preprocessor (NASM)
color preproc "%+(\+|\?|\?\?|)[a-z A-Z 0-9]+"
color preproc "%\[[. a-z A-Z 0-9]*\]"
## Other
color statement "\b(?i)(extern|global|section|segment|_start|\.text|\.data|\.bss)(?-i)\b"
color statement "\b(?i)(db|dw|dd|dq|dt|ddq|do)(?-i)\b"
color identifier "[a-z A-Z 0-9 _]+:"
# String
color constant.string ""(\\.|[^"])*""
color constant.string "'(\\.|[^'])*'"
## Comments
color comment ";.*"

View File

@@ -0,0 +1,13 @@
syntax "caddyfile" "Caddyfile"
color identifier "^\s*\S+(\s|$)"
color type "^([\w.:/-]+,? ?)+[,{]$"
color constant.specialChar "\s{$"
color constant.specialChar "^\s*}$"
color constant.string start="\"" end="\""
color preproc "\{(\w+|\$\w+|%\w+%)\}"
color comment "#.*"
# extra and trailing spaces
color ,red "([[:space:]]{2,}|\t){$"
color ,red "[[:space:]]+$"

View File

@@ -3,8 +3,8 @@
syntax "conf" "\.c[o]?nf$"
## Possible errors and parameters
## Strings
white (i) ""(\\.|[^"])*""
color constant.string (i) ""(\\.|[^"])*""
## Comments
brightblue (i) "^[[:space:]]*#.*$"
cyan (i) "^[[:space:]]*##.*$"
color comment (i) "^[[:space:]]*#.*$"
color comment (i) "^[[:space:]]*##.*$"

View File

@@ -11,6 +11,12 @@ color special "!important"
color identifier ":active|:focus|:hover|:link|:visited|:link|:after|:before|$"
color special "(\{|\}|\(|\)|\;|:|\]|~|<|>|,)"
# SCSS Varaibles
color identifier (i) "\$\{?[0-9A-Z_!@#$*?-]+\}?"
# SCSS Commands
color statement "@import|@mixin|@extend"
# Strings
color constant ""(\\.|[^"])*""
color constant "'(\\.|[^'])*'"

19
runtime/syntax/dart.micro Normal file
View File

@@ -0,0 +1,19 @@
syntax "dart" "\.dart$"
color constant.number "\b[-+]?([1-9][0-9]*|0[0-7]*|0x[0-9a-fA-F]+)([uU][lL]?|[lL][uU]?)?\b"
color constant.number "\b[-+]?([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([EePp][+-]?[0-9]+)?[fFlL]?"
color constant.number "\b[-+]?([0-9]+[EePp][+-]?[0-9]+)[fFlL]?"
color identifier "[A-Za-z_][A-Za-z0-9_]*[[:space:]]*[(]"
color statement "\b(break|case|catch|continue|default|else|finally)\b"
color statement "\b(for|function|get|if|in|as|is|new|return|set|switch|final|await|async|sync)\b"
color statement "\b(switch|this|throw|try|var|void|while|with|import|library|part|const|export)\b"
color constant "\b(true|false|null)\b"
color type "\b(List|String)\b"
color type "\b(int|num|double|bool)\b"
color statement "[-+/*=<>!~%?:&|]"
color constant "/[^*]([^/]|(\\/))*[^\\]/[gim]*"
color constant "\\[0-7][0-7]?[0-7]?|\\x[0-9a-fA-F]+|\\[bfnrt'"\?\\]"
color comment "(^|[[:space:]])//.*"
color comment "/\*.+\*/"
color todo "TODO:?"
color constant.string ""(\\.|[^"])*"|'(\\.|[^'])*'"

View File

@@ -2,29 +2,27 @@
##
syntax "ebuild" "\.e(build|class)$"
## All the standard portage functions
color brightgreen "^src_(unpack|compile|install|test)" "^pkg_(config|nofetch|setup|(pre|post)(inst|rm))"
color identifier "^src_(unpack|compile|install|test)" "^pkg_(config|nofetch|setup|(pre|post)(inst|rm))"
## Highlight bash related syntax
color green "\<(case|do|done|elif|else|esac|exit|fi|for|function|if|in|local|read|return|select|shift|then|time|until|while|continue|break)\>"
color green "(\{|\}|\(|\)|\;|\]|\[|`|\\|\$|<|>|!|=|&|\|)"
color green "-(e|d|f|r|g|u|w|x|L)\>"
color green "-(eq|ne|gt|lt|ge|le|s|n|z)\>"
color statement "\b(case|do|done|elif|else|esac|exit|fi|for|function|if|in|local|read|return|select|shift|then|time|until|while|continue|break)\b"
color statement "(\{|\}|\(|\)|\;|\]|\[|`|\\|\$|<|>|!|=|&|\|)"
color statement "-(e|d|f|r|g|u|w|x|L)\b"
color statement "-(eq|ne|gt|lt|ge|le|s|n|z)\b"
## Highlight variables ... official portage ones in red, all others in bright red
color brightred "\$\{?[a-zA-Z_0-9]+\}?"
color red "\<(ARCH|HOMEPAGE|DESCRIPTION|IUSE|SRC_URI|LICENSE|SLOT|KEYWORDS|FILESDIR|WORKDIR|(P|R)?DEPEND|PROVIDE|DISTDIR|RESTRICT|USERLAND)\>"
color red "\<(S|D|T|PV|PF|P|PN|A)\>" "\<C(XX)?FLAGS\>" "\<LDFLAGS\>" "\<C(HOST|TARGET|BUILD)\>"
color preproc "\$\{?[a-zA-Z_0-9]+\}?"
color special "\b(ARCH|HOMEPAGE|DESCRIPTION|IUSE|SRC_URI|LICENSE|SLOT|KEYWORDS|FILESDIR|WORKDIR|(P|R)?DEPEND|PROVIDE|DISTDIR|RESTRICT|USERLAND)\b"
color special "\b(S|D|T|PV|PF|P|PN|A)\b" "\bC(XX)?FLAGS\b" "\bLDFLAGS\b" "\bC(HOST|TARGET|BUILD)\b"
## Highlight portage commands
color magenta "\<use(_(with|enable))?\> [!a-zA-Z0-9_+ -]*" "inherit.*"
color brightblue "\<e(begin|end|conf|install|make|warn|infon?|error|log|patch|new(group|user))\>"
color brightblue "\<die\>" "\<use(_(with|enable))?\>" "\<inherit\>" "\<has\>" "\<(has|best)_version\>" "\<unpack\>"
color brightblue "\<(do|new)(ins|s?bin|doc|lib(\.so|\.a)|man|info|exe|initd|confd|envd|pam|menu|icon)\>"
color brightblue "\<do(python|sed|dir|hard|sym|html|jar|mo)\>" "\<keepdir\>"
color brightblue "prepall(docs|info|man|strip)" "prep(info|lib|lib\.(so|a)|man|strip)"
color brightblue "\<(doc|ins|exe)into\>" "\<f(owners|perms)\>" "\<(exe|ins|dir)opts\>"
color identifier "\buse(_(with|enable))?\b [!a-zA-Z0-9_+ -]*" "inherit.*"
color statement "\be(begin|end|conf|install|make|warn|infon?|error|log|patch|new(group|user))\b"
color statement "\bdie\b" "\buse(_(with|enable))?\b" "\binherit\b" "\bhas\b" "\b(has|best)_version\b" "\bunpack\b"
color statement "\b(do|new)(ins|s?bin|doc|lib(\.so|\.a)|man|info|exe|initd|confd|envd|pam|menu|icon)\b"
color statement "\bdo(python|sed|dir|hard|sym|html|jar|mo)\b" "\bkeepdir\b"
color statement "prepall(docs|info|man|strip)" "prep(info|lib|lib\.(so|a)|man|strip)"
color statement "\b(doc|ins|exe)into\b" "\bf(owners|perms)\b" "\b(exe|ins|dir)opts\b"
## Highlight common commands used in ebuilds
color blue "\<make\>" "\<(cat|cd|chmod|chown|cp|echo|env|export|grep|let|ln|mkdir|mv|rm|sed|set|tar|touch|unset)\>"
color type "\bmake\b" "\b(cat|cd|chmod|chown|cp|echo|env|export|grep|let|ln|mkdir|mv|rm|sed|set|tar|touch|unset)\b"
## Highlight comments (doesnt work that well)
color yellow "#.*$"
color comment "#.*$"
## Highlight strings (doesnt work that well)
color brightyellow ""(\\.|[^\"])*"" "'(\\.|[^'])*'"
## Trailing space is bad!
color ,green "[[:space:]]+$"
color constant.string ""(\\.|[^\"])*"" "'(\\.|[^'])*'"

View File

@@ -1,11 +1,9 @@
syntax "ini" "\.(ini|desktop|lfl|override)$" "(mimeapps\.list|pinforc|setup\.cfg)$" "weechat/.+\.conf$"
header "^\[[A-Za-z]+\]$"
color brightcyan "\<(true|false)\>"
color cyan "^[[:space:]]*[^=]*="
color brightmagenta "^[[:space:]]*\[.*\]$"
color red "[=;]"
color yellow ""(\\.|[^"])*"|'(\\.|[^'])*'"
color brightblack "(^|[[:space:]])#([^{].*)?$"
color ,green "[[:space:]]+$"
color ,red " + +| + +"
color constant "\b(true|false)\b"
color identifier "^[[:space:]]*[^=]*="
color special "^[[:space:]]*\[.*\]$"
color statement "[=;]"
color comment "(^|[[:space:]])#([^{].*)?$"
color constant.string ""(\\.|[^"])*"|'(\\.|[^'])*'"

View File

@@ -1,11 +1,13 @@
syntax "json" "\.json$"
header "^\{$"
color blue "\<[-]?[1-9][0-9]*([Ee][+-]?[0-9]+)?\>" "\<[-]?[0](\.[0-9]+)?\>"
color cyan "\<null\>"
color brightcyan "\<(true|false)\>"
color yellow ""(\\.|[^"])*"|'(\\.|[^'])*'"
color brightyellow "\"(\\"|[^"])*\"[[:space:]]*:" "'(\'|[^'])*'[[:space:]]*:"
color magenta "\\u[0-9a-fA-F]{4}|\\[bfnrt'"/\\]"
color constant.number "\b[-+]?([1-9][0-9]*|0[0-7]*|0x[0-9a-fA-F]+)([uU][lL]?|[lL][uU]?)?\b"
color constant.number "\b[-+]?([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([EePp][+-]?[0-9]+)?[fFlL]?"
color constant.number "\b[-+]?([0-9]+[EePp][+-]?[0-9]+)[fFlL]?"
color constant "\b(null)\b"
color constant "\b(true|false)\b"
color constant.string ""(\\.|[^"])*"|'(\\.|[^'])*'"
color statement "\"(\\"|[^"])*\"[[:space:]]*:" "'(\'|[^'])*'[[:space:]]*:"
color constant "\\u[0-9a-fA-F]{4}|\\[bfnrt'"/\\]"
color ,green "[[:space:]]+$"
color ,red " + +| + +"

21
runtime/syntax/lfe.micro Normal file
View File

@@ -0,0 +1,21 @@
syntax "lfe" "lfe$" "\.lfe$"
# Parens are everywhere!
color statement "\("
color statement "\)"
# Good overrides for LFE in particular
color type "defun|define-syntax|define|defmacro|defmodule|export"
# Dirty base cases stolen from the generic lisp syntax
color constant "\ [A-Za-z][A-Za-z0-9_-]+\ "
color statement "\(([-+*/<>]|<=|>=)|'"
color constant.number "\<[0-9]+\>"
color constant.string "\"(\\.|[^"])*\""
color special "['|`][A-Za-z][A-Za-z0-9_-]+"
color constant.string "\\.?"
color comment "(^|[[:space:]]);.*"
# Some warning colors because our indents are wrong.
color ,green "[[:space:]]+$"
color ,red " + +| + +"

View File

@@ -0,0 +1,10 @@
# Micro syntax by <nickolay02@inbox.ru>
syntax "micro" "\.(micro)$"
color statement "\b(syntax|color|color-link)\b"
color statement "\b(start=|end=)\b"
color identifier "\b(default|comment|identifier|constant|constant|string|constant|number|statement|preproc|type|special|underlined|error|todo|statusline|indent-char|line=number|gutter-error|gutter-warning|cursor-line)\b"
color constant.number "\b(|h|A|0x)+[0-9]+(|h|A)+\b"
color constant.number "\b0x[0-9 a-f A-F]+\b"
color constant.string ""(\\.|[^"])*""
color comment "#.*"

View File

@@ -0,0 +1,24 @@
syntax "pascal" "\.pas$"
# color identifier "\b[\pL_][\pL_\pN]*\b"
color comment "//.*"
color comment start="\(\*" end="\*\)"
color comment start="({)(?:[^$])" end="}"
color special start="asm" end="end"
color type "\b(?i:(string|ansistring|widestring|shortstring|char|ansichar|widechar|boolean|byte|shortint|word|smallint|longword|cardinal|longint|integer|int64|single|currency|double|extended))\b"
color statement "\b(?i:(and|asm|array|begin|break|case|const|constructor|continue|destructor|div|do|downto|else|end|file|for|function|goto|if|implementation|in|inline|interface|label|mod|not|object|of|on|operator|or|packed|procedure|program|record|repeat|resourcestring|set|shl|shr|then|to|type|unit|until|uses|var|while|with|xor))\b"
color statement "\b(?i:(as|class|dispose|except|exit|exports|finalization|finally|inherited|initialization|is|library|new|on|out|property|raise|self|threadvar|try))\b"
color statement "\b(?i:(absolute|abstract|alias|assembler|cdecl|cppdecl|default|export|external|forward|generic|index|local|name|nostackframe|oldfpccall|override|pascal|private|protected|public|published|read|register|reintroduce|safecall|softfloat|specialize|stdcall|virtual|write))\b"
color constant "\b(?i:(false|true|nil))\b"
color constant "\$[0-9A-Fa-f]+" "\b[+-]?[0-9]+([.]?[0-9]+)?(?i:e[+-]?[0-9]+)?"
color constant.string "'(?:[^']+|'')*'"
color preproc start="{\$" end="}"

View File

@@ -1,40 +1,30 @@
## PHP Syntax Highlighting
syntax "php" "\.php[2345s~]?$"
color white start="<\?(php|=)?" end="\?>"
# Functions
color brightblue "([a-zA-Z0-9_-]*)\("
# Constructs
color brightblue "(class|extends|goto) ([a-zA-Z0-9_]*)"
color green "[^a-z0-9_-]{1}(var|class|function|echo|case|break|default|exit|switch|if|else|elseif|endif|foreach|endforeach|@|while|public|private|protected|return|true|false|null|TRUE|FALSE|NULL|const|static|extends|as|array|require|include|require_once|include_once|define|do|continue|declare|goto|print|in|namespace|use)[^a-z0-9_-]{1}"
color brightblue "[a-zA-Z0-9]+:"
# Variables
color white "\$[a-zA-Z_0-9$]*|[=!<>]"
color white "\->[a-zA-Z_0-9$]*|[=!<>]"
# Special Characters
color yellow "[.,{}();]"
color yellow "\["
color yellow "\]"
color yellow "[=][^>]"
# Numbers
color magenta "[+-]*([0-9]\.)*[0-9]+([eE][+-]?([0-9]\.)*[0-9])*"
color magenta "0x[0-9a-zA-Z]*"
# Special Variables
color brightblue "(\$this|parent::|self::|\$this->)"
# Bitwise Operations
color magenta "(\;|\||\^){1}"
# And/Or/SRO/etc
color green "(\;\;|\|\||::|=>|->)"
# Online Comments
color brightyellow "(#.*|//.*)$"
# STRINGS!
color red "('[^']*')|(\"[^\"]*\")"
# Inline Variables
color white "\{\$[^}]*\}"
# PHP Tags
color red "(<\?(php)?|\?>)"
# General HTML
color red start="\?>" end="<\?(php|=)?"
# trailing whitespace
color ,green "[^[:space:]]{1}[[:space:]]+$"
# multi-line comments
color brightyellow start="/\*" end="\*/"
color default start="<\?(php|=)?" end="\?>"
color special "([a-zA-Z0-9_-]+)\("
color identifier "(var|class|goto|extends|function|echo|case|break|default|exit|switch|foreach|endforeach|while|const|static|extends|as|require|include|require_once|include_once|define|do|continue|declare|goto|print|in|trait|interface|[E|e]xception|array|int|string|bool|iterable|void)[\s|\)]"
color identifier "[a-zA-Z\\]+::"
color identifier "new\s([a-zA-Z0-9\\]+)"
color identifier "([A-Z][a-zA-Z0-9_]+)\s"
color identifier "([A-Z0-9_]+)[;|\s|\)|,]"
color statement "(implements|abstract|global|public|instanceof|private|protected|static|if|else|elseif|endif|namespace|use|as|new|throw|catch|try|return)[\s|;]"
color constant "(true|false|null|TRUE|FALSE|NULL)"
color constant "[\s|=|>|\s|\(|/|+|-|\*|\[](\d+)"
color identifier "(\$this|parent|self|\$this->)"
color statement "(=>|===|!==|==|!=|&&|\|\||::|=|->|\!)"
color default "(\$[a-zA-Z0-9\-_]+)"
color default "[\(|\)|/|+|-|\*|\[|,|;]"
color constant.string "('.*?'|\".*?\")"
color comment start="/\*" end="\*/"
color comment "(#.*|//.*)$"

View File

@@ -1,4 +1,4 @@
syntax "shell" "\.sh$" "\.bash" "\.bashrc" "bashrc" "\.bash_aliases" "bash_aliases" "\.bash_functions" "bash_functions" "\.bash_profile" "bash_profile" "Pkgfile" "PKGBUILD" ".ebuild\$" "APKBUILD"
syntax "shell" "\.sh$" "\.bash" "\.bashrc" "bashrc" "\.bash_aliases" "bash_aliases" "\.bash_functions" "bash_functions" "\.bash_profile" "bash_profile" "Pkgfile" "pkgmk.conf" "profile" "rc.conf" "PKGBUILD" ".ebuild\$" "APKBUILD"
header "^#!.*/(env +)?(ba)?sh( |$)"
# Numbers

View File

@@ -0,0 +1,20 @@
syntax "typescript" "\.ts$"
color constant.number "\b[-+]?([1-9][0-9]*|0[0-7]*|0x[0-9a-fA-F]+)([uU][lL]?|[lL][uU]?)?\b"
color constant.number "\b[-+]?([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([EePp][+-]?[0-9]+)?[fFlL]?"
color constant.number "\b[-+]?([0-9]+[EePp][+-]?[0-9]+)[fFlL]?"
color identifier "[A-Za-z_][A-Za-z0-9_]*[[:space:]]*[(]"
color statement "\b(break|case|catch|continue|default|delete|do|else|finally)\b"
color statement "\b(declare|interface|import|export|from|for|function|get|if|in|instanceof|new|return|set|switch)\b"
color statement "\b(switch|this|throw|try|typeof|var|void|while|with|async|await)\b"
color constant "\b(null|undefined|NaN)\b"
color constant "\b(true|false)\b"
color type "\b(Array|Boolean|Date|Enumerator|Error|Function|Math|string|number|boolean|any)\b"
color type "\b(Number|Object|RegExp|String)\b"
color statement "[-+/*=<>!~%?:&|]"
color constant "/[^*]([^/]|(\\/))*[^\\]/[gim]*"
color constant "\\[0-7][0-7]?[0-7]?|\\x[0-9a-fA-F]+|\\[bfnrt'"\?\\]"
color comment "(^|[[:space:]])//.*"
color comment "/\*.+\*/"
color todo "TODO:?"
color constant.string ""(\\.|[^"])*"|'(\\.|[^'])*'"

View File

@@ -1,13 +1,11 @@
syntax "yaml" "\.ya?ml$"
header "^---" "%YAML"
color green "(^| )!!(binary|bool|float|int|map|null|omap|seq|set|str) "
color brightcyan "\<(YES|yes|Y|y|ON|on|NO|no|N|n|OFF|off)\>"
color brightcyan "\<(true|false)\>"
color red ":[[:space:]]" "\[" "\]" ":[[:space:]]+[|>]" "^[[:space:]]*- "
color brightyellow "[[:space:]][\*&][A-Za-z0-9]+"
color yellow ""(\\.|[^"])*"|'(\\.|[^'])*'"
color brightblack "(^|[[:space:]])#([^{].*)?$"
color brightmagenta "^---" "^\.\.\." "^%YAML" "^%TAG"
color ,green "[[:space:]]+$"
color ,red " + +| + +"
color type "(^| )!!(binary|bool|float|int|map|null|omap|seq|set|str) "
color constant "\b(YES|yes|Y|y|ON|on|NO|no|N|n|OFF|off)\b"
color constant "\b(true|false)\b"
color statement ":[[:space:]]" "\[" "\]" ":[[:space:]]+[|>]" "^[[:space:]]*- "
color identifier "[[:space:]][\*&][A-Za-z0-9]+"
color constant.string ""(\\.|[^"])*"|'(\\.|[^'])*'"
color comment "(^|[[:space:]])#([^{].*)?$"
color special "^---" "^\.\.\." "^%YAML" "^%TAG"

10
tools/build-date.go Normal file
View File

@@ -0,0 +1,10 @@
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now().Local().Format("January 02, 2006"))
}

117
tools/pre-release.sh Executable file
View File

@@ -0,0 +1,117 @@
# This script creates releases on Github for micro
# It assumes that the binaries are in the current directory
# You must have the correct Github access token to run this script
# $1 is the title, $2 is the description
commitID=$(git rev-parse HEAD)
tag="v$1"
echo "Creating tag"
git tag $tag $commitID
git push --tags
echo "Creating new release"
github-release release \
--user zyedidia \
--repo micro \
--tag $tag \
--name "$1" \
--description "$2" \
--pre-release
echo "Uploading OSX binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-osx.tar.gz" \
--file binaries/micro-$1-osx.tar.gz
echo "Uploading Linux 64 binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-linux64.tar.gz" \
--file binaries/micro-$1-linux64.tar.gz
echo "Uploading Linux 32 binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-linux32.tar.gz" \
--file binaries/micro-$1-linux32.tar.gz
echo "Uploading Linux Arm binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-linux-arm.tar.gz" \
--file binaries/micro-$1-linux-arm.tar.gz
echo "Uploading FreeBSD 64 binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-freebsd64.tar.gz" \
--file binaries/micro-$1-freebsd64.tar.gz
echo "Uploading FreeBSD 32 binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-freebsd32.tar.gz" \
--file binaries/micro-$1-freebsd32.tar.gz
echo "Uploading OpenBSD 64 binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-openbsd64.tar.gz" \
--file binaries/micro-$1-openbsd64.tar.gz
echo "Uploading OpenBSD 32 binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-openbsd32.tar.gz" \
--file binaries/micro-$1-openbsd32.tar.gz
echo "Uploading NetBSD 64 binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-netbsd64.tar.gz" \
--file binaries/micro-$1-netbsd64.tar.gz
echo "Uploading NetBSD 32 binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-netbsd32.tar.gz" \
--file binaries/micro-$1-netbsd32.tar.gz
echo "Uploading Windows 64 binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-win64.zip" \
--file binaries/micro-$1-win64.zip
echo "Uploading Windows 32 binary"
github-release upload \
--user zyedidia \
--repo micro \
--tag $tag \
--name "micro-$1-win32.zip" \
--file binaries/micro-$1-win32.zip

View File

@@ -18,7 +18,6 @@ github-release release \
--tag $tag \
--name "$1" \
--description "$2" \
--pre-release
echo "Uploading OSX binary"
github-release upload \
@@ -115,3 +114,4 @@ github-release upload \
--tag $tag \
--name "micro-$1-win32.zip" \
--file binaries/micro-$1-win32.zip