Compare commits

..

43 Commits

Author SHA1 Message Date
Zachary Yedidia
3d845eefe3 Increase totalwidth as well for correct tab alignment 2023-02-13 14:28:07 -08:00
Zachary Yedidia
d8576d0fe6 Display a tilde before every uppercase letter 2023-02-13 14:24:49 -08:00
Sertonix
7ee77d56a6 Delete .gitmodules (#2743) 2023-02-06 17:00:09 -08:00
Rein F
eb6daab169 Make the commenttype option useful (#2735) 2023-02-05 18:30:12 -08:00
Sertonix
b0cd92b70f add restrict to C syntax (#2728) 2023-02-04 14:33:25 -08:00
Sertonix
a929437490 fix unsigned int not highlighted (#2725) 2023-02-01 10:27:33 -08:00
Zachary Yedidia
cb66d22b94 Update readme build badge for github actions 2023-01-30 17:42:34 -08:00
Zachary Yedidia
d1af21f626 Convert ci to github actions 2023-01-30 17:34:37 -08:00
Alan Hamlett
0500cc234d util.HttpRequest helper to make requests with headers (#2678) 2023-01-30 01:29:06 -08:00
Zachary Yedidia
f7677549ea Fix build
Fixes #2716
2023-01-29 19:23:21 -08:00
Preston Thorpe
d5caf84788 Prompt on save/ existing file (#2714)
* Update for fixing bug issue

Adds YNprompt when user tries save new file as existing file name in current directory.

https://github.com/zyedidia/micro/issues/2709

* Update actions.go

error handled. gonna have to be tested on permission errors, etc
2023-01-29 18:11:34 -08:00
Dmitry Maluka
e31f5ed26e Add -profile flag for CPU profiling (#2715)
There is already a commented-out code in main() for enabling CPU
profiling of micro, which is often useful. Adjust it to allow enabling
it just by providing -profile flag on the command line, without
modifying and recompiling the code.
2023-01-29 18:10:57 -08:00
Zachary Yedidia
3ef0267f0a Reload settings when filetype is changed
Fixes #2712
2023-01-26 18:21:35 -08:00
Zachary Yedidia
d5ff785559 Add fakecursor option
When 'fakecursor' is enabled micro will use a "fake" block to display
the cursor instead of the terminal's cursor.

Closes #2698
Closes #2703
2023-01-26 18:02:54 -08:00
Zachary Yedidia
e222ed73b8 Rename multimode to multiopen
Ref #2689
2023-01-24 17:06:52 -08:00
Andrew Geng
432fc7ed58 Add -multimode to open multiple files into split. (#2689)
Adds config option `multimode`, which takes values `tab`, `vsplit`,
or `hsplit` (corresponding to the file-opening commands). I mean to
use it with a command line like

    micro -multimode vsplit foo.h foo.c

to open files in a side-by-side split, but if one really wanted to
one could set it in the config file to change the default behavior of
opening multiple files in tabs.
2023-01-23 11:13:42 -08:00
Zachary Yedidia
43b512fd77 Include mac arm binary in release scripts 2023-01-12 19:19:20 -08:00
Zachary Yedidia
980112c071 Add darwin arm64 prebuilt binary
Fixes #2456
2023-01-12 19:16:07 -08:00
Alan Christian
b0e7efe6a5 description different from JSON real default (#2680)
* description different from JSON real default

* fix wrong line
2023-01-12 12:40:04 -08:00
Steven Xu
64638845e9 fix: allow binding the minus key, fixes #2471 (#2617) 2023-01-11 21:56:54 -08:00
oplexius
97f362b465 Doc changes (#2646)
Try to make things a little more concise to start with, remove a couple of repetitions.

This seems like a good editor for people starting out, and I like it as a good alternative to nano for explaining to beginners how to edit config files. If you appreciate the suggestions, I can go over the rest of the documentation, in the hope of making things even easier to get going with.

If the line breaks are off, I can redo this in a text editor, rather than on the web on github. I've limited the changes, but I could make a few more changes to style...

Btw, the tutorial is just about settings. I'm guessing this is just because things aren't finished, but I'm asking just in case this is an error and there may exist a tutorial somewhere.
2023-01-11 21:56:23 -08:00
Dmitry Maluka
f1801f1958 Comment plugin: improve commenting multi-line selection (#2668)
When commenting a block of multiple lines, the comment symbol is added
right before the first non-whitespace character in each line, e.g.:

void somefunc(int a)
{
    // if (a) {
        // a += 2;
        // printf("a = %d\n", a);
    // } else {
        // printf("none");
    // }
}

which isn't quite nice.

Change it to add the comment at the same position on each line, which is
the position of the leftmost non-whitespace in the entire block, e.g.:

void somefunc(int a)
{
    // if (a) {
    //     a += 2;
    //     printf("a = %d\n", a);
    // } else {
    //     printf("none");
    // }
}

Ref #2282
2023-01-11 21:54:59 -08:00
Zachary Yedidia
443ede470d Fix perl syntax file
Fixes #2656
2022-12-09 01:19:19 -08:00
Mark Shachkov
c4d4d5fb7d Add CUDA syntax support (#2652)
Reusing cpp syntax with minor additions.
2022-12-03 22:17:35 -08:00
Dmitry Maluka
28e0e20651 Improve buffer view relocation after jumping to a far-away location (#2628)
* Improve buffer view relocation after jumping to a far-away location

When the cursor is moved to a location which is far away from the
current location (e.g. after a search or a goto line), the buffer view
is always relocated in such a way that the cursor is at the bottom or
at the top (minus scrollmargin), i.e. as if we just scrolled to this
location. It's not like in other editors, and IMHO it's annoying. When
we jump to a new location far away, we usually want to see more of its
context, so the cursor should be placed closer to the center of the
view, not near its edges.

This change implements the behavior similar to other editors:

- If the distance between the new and the old location is less than one
  frame (i.e. the view either doesn't change or just slightly "shifts")
  then the current behavior remains unchanged.

- Otherwise the current line is placed at 25% of the window height.

* Postpone calling onBufPaneOpen until the initial resize

It is currently not possible to find out the geometry of a newly created
bufpane in onBufPaneOpen lua callback: bp:GetView() returns {0,0,0,0}
instead of the actual window. The reason is that the bufpane view is not
properly initialized yet when the bufpane is created and the callback is
triggered. It is initialized a bit later, at the initial resize.

So postpone calling onBufPaneOpen until after the initial resize.

* Improve buffer view relocation when opening a file at a far-away location

When a file is opened with the initial cursor location at a given line
which is far away from the beginning of the file, the buffer view is
relocated so that the cursor is at the bottom (minus scrollmargin)
as if we just scrolled to this line, which is annoying since we'd rather
like to see more of the context of this initial location.

So implement the behavior similar to the earlier commit (which addresses
a similar issue about jumping far away after a search or goto):

- If the initial cursor location is less than one frame away from the
  beginning of the buffer, keep the existing behavior i.e. just display
  the beginning of the buffer.

- Otherwise place the cursor location at 25% of the window height.
2022-12-02 19:38:09 -08:00
Jakob Nybo Nissen
9a10cac598 Improve Julia syntax highlighting (#2643)
Specifically, do not allow multiline single-quote strings, which are not a
thing in Julia. The existing rule broke when adjoints were used, such as
`b = a'`.
The syntax rules have been copied from Rust, which also uses single ticks for
character literals, and also uses the ' symbol for things unrelated to chars.
2022-12-02 17:49:50 -08:00
Aaron Clark
0a080ba03c Syntax: added support for Smalltalk (#2626) 2022-12-02 17:49:25 -08:00
Dmitry Maluka
3f0cd019d7 Fix incorrect LastVisualX after changing bufWidth w/o resize (#2629)
* Fix incorrect LastVisualX after changing bufWidth w/o resize

When we resize a buffer pane with softwrap enabled, we update the
cursors LastVisualX values to ensure that moving cursor up or down
within a wrapped line will move the cursor to the correct location.
The problem is that we need to do it also in cases when the visual
buffer width within the buffer window is changing without resizing
the window itself, e.g. when toggling the ruler on/off.

So update LastVisualX whenever the buffer width changes, not neccesarily
as a result of resizing the buffer window.

* Update LastVisualX and relocate when toggling wordwrap on/off

Visual location of a cursor may change not only when softwrap is toggled
on or off but also when wordwrap is toggled on or off without changing
the softwrap setting. So need to update cursor LastVisualX values and
relocate the view if needed, just like when softwrap is toggled, to make
sure that moving the cursor up and down will work correctly and that the
cursor will not be left out of the view.
2022-12-02 17:49:06 -08:00
zehkira
5d3dbde698 Fix "no" when replacing with empty string (#2641)
* advance to end of found string when not replacing

* simplify search location change
2022-12-02 17:48:50 -08:00
Zachary Yedidia
87ad67ada7 Update readme 2022-11-25 16:48:06 -08:00
Zachary Yedidia
fba5e2bf36 Bump clipper 2022-11-05 18:30:52 -07:00
Zachary Yedidia
2e9dabd434 Fix save with sudo for large file sizes
Fixes #2200
2022-11-02 16:00:12 -07:00
d!key
c8c7ad57bd Added openSUSE installation command (#2587) 2022-10-12 19:06:01 -07:00
Zachary Yedidia
986faa783b Add better explanation about find 2022-10-12 19:05:42 -07:00
Zachary Yedidia
f86f56a628 Bump tcell 2022-10-07 11:20:31 -07:00
Zachary Yedidia
957650c3ee Document FindLiteral default binding 2022-10-04 16:30:06 -07:00
Dmitry Maluka
8ff7ec50ef Fix relocate at the end of buffer when scrollmargin is 0 (#2578)
* Add LessEqual and GreaterEqual for SLoc

* Fix relocate at the end of buffer when scrollmargin is 0

Fix the following issue: when scrollmargin is set to 0 and we move the
cursor to the end of buffer (e.g. via Ctrl-End), the buffer view doesn't
move.

The cause is that the condition c.LessThan(w.Scroll(bEnd, -scrollmargin+1))
doesn't hold, since Scroll() takes care not to return a location beyond
the end of buffer, so in this case Scroll() just returns bEnd.
2022-10-01 13:03:40 -07:00
Valiant-Wolf
48645907ec Revert adding 'git-rebase-todo' to the main git syntax highlighting file (#2564) 2022-09-16 11:27:38 -07:00
Tomo
3cbbba534c Add justfile syntax (#2523)
Just is 'just a command runner'. It has syntax inspired by make,
 so `makefile.yaml` was used as a template.
2022-08-21 23:53:04 -07:00
Mishanya
3dcd01f8b8 Add template literal string highlighting to typescript (#2525) 2022-08-21 23:52:47 -07:00
trolzen
e7bdcb093b Restore installation instructions for Debian and Ubuntu. (#2530) 2022-08-20 19:08:57 -07:00
Zachary Yedidia
810133d5a8 Use shell job for terminal callback
Fixes #2529
2022-08-19 15:46:01 -07:00
Zachary Yedidia
3d6b0c6dd6 Ensure screen cannot draw during a term prompt
Fixes #2528
2022-08-16 22:07:41 -07:00
39 changed files with 555 additions and 115 deletions

22
.github/workflows/test.yaml vendored Normal file
View File

@@ -0,0 +1,22 @@
on: [push, pull_request]
name: Build and Test
jobs:
test:
strategy:
matrix:
go-version: [1.19.x]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- uses: actions/checkout@v3
- name: Build
run: |
make build
- name: Test
run: |
make test

0
.gitmodules vendored
View File

View File

@@ -1,11 +0,0 @@
language: go
go:
- "1.13.x"
os:
- linux
- osx
- windows
script:
- go build ./cmd/micro
- go test ./internal/...
- go test ./cmd/...

View File

@@ -1,6 +1,6 @@
<img alt="micro logo" src="./assets/micro-logo-drop.svg" width="500px"/>
[![Build Status](https://travis-ci.org/zyedidia/micro.svg?branch=master)](https://travis-ci.org/zyedidia/micro)
![Test Workflow](https://github.com/zyedidia/micro/actions/workflows/test.yaml/badge.svg)
[![Go Report Card](https://goreportcard.com/badge/github.com/zyedidia/micro)](https://goreportcard.com/report/github.com/zyedidia/micro)
[![Release](https://img.shields.io/github/release/zyedidia/micro.svg?label=Release)](https://github.com/zyedidia/micro/releases)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/zyedidia/micro/blob/master/LICENSE)
@@ -139,8 +139,10 @@ for other operating systems. These packages are not guaranteed to be up-to-date.
* Linux: Available in distro-specific package managers.
* `dnf install micro` (Fedora).
* `apt install micro` (Ubuntu and Debian).
* `pacman -S micro` (Arch Linux).
* `emerge app-editors/micro` (Gentoo).
* `zypper install micro-editor` (SUSE)
* `eopkg install micro` (Solus).
* `pacstall -I micro` (Pacstall).
* See [wiki](https://github.com/zyedidia/micro/wiki/Installing-Micro) for details about CRUX, Termux.
@@ -201,6 +203,18 @@ If you are using macOS, you should consider using [iTerm2](http://iterm2.com/) i
If you still insist on using the default Mac terminal, be sure to set `Use Option key as Meta key` under
`Preferences->Profiles->Keyboard` to use <kbd>option</kbd> as <kbd>alt</kbd>.
### WSL and Windows Console
If you use micro within WSL, it is highly recommended that you use the [Windows
Terminal](https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701?hl=en-us&gl=us)
instead of the default Windows Console.
If you must use Windows Console for some reason, note that there is a bug in
Windows Console WSL that causes a font change whenever micro tries to access
the external clipboard via powershell. To fix this, use an internal clipboard
with `set clipboard internal` (though your system clipboard will no longer be
available in micro).
### Colors and syntax highlighting
If you open micro and it doesn't seem like syntax highlighting is working, this is probably because

View File

@@ -150,6 +150,7 @@ func luaImportMicroUtil() *lua.LTable {
ulua.L.SetField(pkg, "Unzip", luar.New(ulua.L, util.Unzip))
ulua.L.SetField(pkg, "Version", luar.New(ulua.L, util.Version))
ulua.L.SetField(pkg, "SemVersion", luar.New(ulua.L, util.SemVersion))
ulua.L.SetField(pkg, "HttpRequest", luar.New(ulua.L, util.HttpRequest))
ulua.L.SetField(pkg, "CharacterCountInString", luar.New(ulua.L, util.CharacterCountInString))
ulua.L.SetField(pkg, "RuneStr", luar.New(ulua.L, func(r rune) string {
return string(r)

View File

@@ -9,6 +9,7 @@ import (
"os/signal"
"regexp"
"runtime"
"runtime/pprof"
"sort"
"strconv"
"syscall"
@@ -37,6 +38,7 @@ var (
flagConfigDir = flag.String("config-dir", "", "Specify a custom location for the configuration directory")
flagOptions = flag.Bool("options", false, "Show all option help")
flagDebug = flag.Bool("debug", false, "Enable debug mode (prints debug info to ./log.txt)")
flagProfile = flag.Bool("profile", false, "Enable CPU profiling (writes profile info to ./micro.prof)")
flagPlugin = flag.String("plugin", "", "Plugin command")
flagClean = flag.Bool("clean", false, "Clean configuration directory")
optionFlags map[string]*string
@@ -59,6 +61,9 @@ func InitFlags() {
fmt.Println(" \tShow all option help")
fmt.Println("-debug")
fmt.Println(" \tEnable debug mode (enables logging to ./log.txt)")
fmt.Println("-profile")
fmt.Println(" \tEnable CPU profiling (writes profile info to ./micro.prof")
fmt.Println(" \tso it can be analyzed later with \"go tool pprof micro.prof\")")
fmt.Println("-version")
fmt.Println(" \tShow the version number and information")
@@ -228,15 +233,21 @@ func main() {
os.Exit(0)
}()
// runtime.SetCPUProfileRate(400)
// f, _ := os.Create("micro.prof")
// pprof.StartCPUProfile(f)
// defer pprof.StopCPUProfile()
var err error
InitFlags()
if *flagProfile {
f, err := os.Create("micro.prof")
if err != nil {
log.Fatal("error creating CPU profile: ", err)
}
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("error starting CPU profile: ", err)
}
defer pprof.StopCPUProfile()
}
InitLog()
err = config.InitConfigDir(*flagConfigDir)

4
go.mod
View File

@@ -11,11 +11,11 @@ require (
github.com/sergi/go-diff v1.1.0
github.com/stretchr/testify v1.4.0
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb
github.com/zyedidia/clipper v0.1.0
github.com/zyedidia/clipper v0.1.1
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3
github.com/zyedidia/json5 v0.0.0-20200102012142-2da050b1a98d
github.com/zyedidia/pty v1.1.20 // indirect
github.com/zyedidia/tcell/v2 v2.0.9
github.com/zyedidia/tcell/v2 v2.0.10-0.20221007181625-f562052bccb8 // indirect
github.com/zyedidia/terminal v0.0.0-20180726154117-533c623e2415
golang.org/x/text v0.3.2
gopkg.in/yaml.v2 v2.2.8

4
go.sum
View File

@@ -43,6 +43,8 @@ github.com/zyedidia/clipper v0.0.0-20220613212750-517cd4a6c524 h1:sWYUMHs1EAlsPE
github.com/zyedidia/clipper v0.0.0-20220613212750-517cd4a6c524/go.mod h1:7YApPNiiTZTXdKKZG92G50qj6mnWEX975Sdu65J7YpQ=
github.com/zyedidia/clipper v0.1.0 h1:e16nhM1RgL3HYcugcHRUpMya1K830TS5uo6LlPJHySg=
github.com/zyedidia/clipper v0.1.0/go.mod h1:7YApPNiiTZTXdKKZG92G50qj6mnWEX975Sdu65J7YpQ=
github.com/zyedidia/clipper v0.1.1 h1:HBgguFNDq/QmSQKBnhy4sMKzILINr139VEgAhftOUTw=
github.com/zyedidia/clipper v0.1.1/go.mod h1:7YApPNiiTZTXdKKZG92G50qj6mnWEX975Sdu65J7YpQ=
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3 h1:oMHjjTLfGXVuyOQBYj5/td9WC0mw4g1xDBPovIqmHew=
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3/go.mod h1:YKbIYP//Eln8eDgAJGI3IDvR3s4Tv9Z9TGIOumiyQ5c=
github.com/zyedidia/go-runewidth v0.0.12 h1:aHWj8qL3aH7caRzoPBJXe1pEaZBXHpKtfTuiBo5p74Q=
@@ -61,6 +63,8 @@ github.com/zyedidia/pty v1.1.20 h1:mkZ5/UiEjZVMFzoXp8oyJAlbn3b380m5lvFrbx/NL/g=
github.com/zyedidia/pty v1.1.20/go.mod h1:HWbpfrLoVM9FmU+/9NV+PzVQV8jSxgnQLk8fvx0q/i8=
github.com/zyedidia/tcell/v2 v2.0.9 h1:FxXRkE62N0GPHES7EMLtp2rteYqC9r1kVid8vJN1kOE=
github.com/zyedidia/tcell/v2 v2.0.9/go.mod h1:i4NNlquIQXFeNecrOgxDQQJdu+7LmTi3g62asvmwUws=
github.com/zyedidia/tcell/v2 v2.0.10-0.20221007181625-f562052bccb8 h1:53ULv4mmLyQDnqbjVxanckP57WSreWHwTmlLJrJEutY=
github.com/zyedidia/tcell/v2 v2.0.10-0.20221007181625-f562052bccb8/go.mod h1:i4NNlquIQXFeNecrOgxDQQJdu+7LmTi3g62asvmwUws=
github.com/zyedidia/terminal v0.0.0-20180726154117-533c623e2415 h1:752dTQ5OatJ9M5ULK2+9lor+nzyZz+LYDo3WGngg3Rc=
github.com/zyedidia/terminal v0.0.0-20180726154117-533c623e2415/go.mod h1:8leT8G0Cm8NoJHdrrKHyR9MirWoF4YW7pZh06B6H+1E=
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

View File

@@ -4,12 +4,12 @@ import (
"errors"
"fmt"
"io/fs"
"os"
"regexp"
"runtime"
"strings"
"time"
shellquote "github.com/kballard/go-shellquote"
"github.com/zyedidia/micro/v2/internal/buffer"
"github.com/zyedidia/micro/v2/internal/clipboard"
@@ -791,10 +791,27 @@ func (h *BufPane) SaveAsCB(action string, callback func()) bool {
return
}
filename := strings.Join(args, " ")
noPrompt := h.saveBufToFile(filename, action, callback)
if noPrompt {
h.completeAction(action)
fileinfo, err := os.Stat(filename)
if err != nil {
if os.IsNotExist(err) {
noPrompt := h.saveBufToFile(filename, action, callback)
if noPrompt {
h.completeAction(action)
return
}
}
}
InfoBar.YNPrompt(
fmt.Sprintf("the file %s already exists in the directory, would you like to overwrite? Y/n", fileinfo.Name()),
func(yes, canceled bool) {
if yes && !canceled {
noPrompt := h.saveBufToFile(filename, action, callback)
if noPrompt {
h.completeAction(action)
}
}
},
)
}
})
return false
@@ -879,11 +896,10 @@ func (h *BufPane) Search(str string, useRegex bool, searchDown bool) error {
h.Cursor.SetSelectionEnd(match[1])
h.Cursor.OrigSelection[0] = h.Cursor.CurSelection[0]
h.Cursor.OrigSelection[1] = h.Cursor.CurSelection[1]
h.Cursor.GotoLoc(h.Cursor.CurSelection[1])
h.GotoLoc(h.Cursor.CurSelection[1])
h.Buf.LastSearch = str
h.Buf.LastSearchRegex = useRegex
h.Buf.HighlightSearch = h.Buf.Settings["hlsearch"].(bool)
h.Relocate()
} else {
h.Cursor.ResetSelection()
}
@@ -905,12 +921,11 @@ func (h *BufPane) find(useRegex bool) bool {
h.Cursor.SetSelectionEnd(match[1])
h.Cursor.OrigSelection[0] = h.Cursor.CurSelection[0]
h.Cursor.OrigSelection[1] = h.Cursor.CurSelection[1]
h.Cursor.GotoLoc(match[1])
h.GotoLoc(match[1])
} else {
h.Cursor.GotoLoc(h.searchOrig)
h.GotoLoc(h.searchOrig)
h.Cursor.ResetSelection()
}
h.Relocate()
}
}
findCallback := func(resp string, canceled bool) {
@@ -925,7 +940,7 @@ func (h *BufPane) find(useRegex bool) bool {
h.Cursor.SetSelectionEnd(match[1])
h.Cursor.OrigSelection[0] = h.Cursor.CurSelection[0]
h.Cursor.OrigSelection[1] = h.Cursor.CurSelection[1]
h.Cursor.GotoLoc(h.Cursor.CurSelection[1])
h.GotoLoc(h.Cursor.CurSelection[1])
h.Buf.LastSearch = resp
h.Buf.LastSearchRegex = useRegex
h.Buf.HighlightSearch = h.Buf.Settings["hlsearch"].(bool)
@@ -936,7 +951,6 @@ func (h *BufPane) find(useRegex bool) bool {
} else {
h.Cursor.ResetSelection()
}
h.Relocate()
}
pattern := string(h.Cursor.GetSelection())
if eventCallback != nil && pattern != "" {
@@ -980,11 +994,10 @@ func (h *BufPane) FindNext() bool {
h.Cursor.SetSelectionEnd(match[1])
h.Cursor.OrigSelection[0] = h.Cursor.CurSelection[0]
h.Cursor.OrigSelection[1] = h.Cursor.CurSelection[1]
h.Cursor.Loc = h.Cursor.CurSelection[1]
h.GotoLoc(h.Cursor.CurSelection[1])
} else {
h.Cursor.ResetSelection()
}
h.Relocate()
return true
}
@@ -1007,11 +1020,10 @@ func (h *BufPane) FindPrevious() bool {
h.Cursor.SetSelectionEnd(match[1])
h.Cursor.OrigSelection[0] = h.Cursor.CurSelection[0]
h.Cursor.OrigSelection[1] = h.Cursor.CurSelection[1]
h.Cursor.Loc = h.Cursor.CurSelection[1]
h.GotoLoc(h.Cursor.CurSelection[1])
} else {
h.Cursor.ResetSelection()
}
h.Relocate()
return true
}

View File

@@ -139,7 +139,7 @@ func findSingleEvent(k string) (b Event, ok bool) {
modSearch:
for {
switch {
case strings.HasPrefix(k, "-"):
case strings.HasPrefix(k, "-") && k != "-":
// We optionally support dashes between modifiers
k = k[1:]
case strings.HasPrefix(k, "Ctrl") && k != "CtrlH":

View File

@@ -13,6 +13,7 @@ import (
"github.com/zyedidia/micro/v2/internal/display"
ulua "github.com/zyedidia/micro/v2/internal/lua"
"github.com/zyedidia/micro/v2/internal/screen"
"github.com/zyedidia/micro/v2/internal/util"
"github.com/zyedidia/tcell/v2"
)
@@ -235,10 +236,14 @@ type BufPane struct {
// remember original location of a search in case the search is canceled
searchOrig buffer.Loc
// The pane may not yet be fully initialized after its creation
// since we may not know the window geometry yet. In such case we finish
// its initialization a bit later, after the initial resize.
initialized bool
}
// NewBufPane creates a new buffer pane with the given window.
func NewBufPane(buf *buffer.Buffer, win display.BWindow, tab *Tab) *BufPane {
func newBufPane(buf *buffer.Buffer, win display.BWindow, tab *Tab) *BufPane {
h := new(BufPane)
h.Buf = buf
h.BWindow = win
@@ -247,8 +252,13 @@ func NewBufPane(buf *buffer.Buffer, win display.BWindow, tab *Tab) *BufPane {
h.Cursor = h.Buf.GetActiveCursor()
h.mouseReleased = true
config.RunPluginFn("onBufPaneOpen", luar.New(ulua.L, h))
return h
}
// NewBufPane creates a new buffer pane with the given window.
func NewBufPane(buf *buffer.Buffer, win display.BWindow, tab *Tab) *BufPane {
h := newBufPane(buf, win, tab)
h.finishInitialize()
return h
}
@@ -256,7 +266,25 @@ func NewBufPane(buf *buffer.Buffer, win display.BWindow, tab *Tab) *BufPane {
// creates a buf window.
func NewBufPaneFromBuf(buf *buffer.Buffer, tab *Tab) *BufPane {
w := display.NewBufWindow(0, 0, 0, 0, buf)
return NewBufPane(buf, w, tab)
h := newBufPane(buf, w, tab)
// Postpone finishing initializing the pane until we know the actual geometry
// of the buf window.
return h
}
// TODO: make sure splitID and tab are set before finishInitialize is called
func (h *BufPane) finishInitialize() {
h.initialRelocate()
h.initialized = true
config.RunPluginFn("onBufPaneOpen", luar.New(ulua.L, h))
}
// Resize resizes the pane
func (h *BufPane) Resize(width, height int) {
h.BWindow.Resize(width, height)
if !h.initialized {
h.finishInitialize()
}
}
// SetTab sets this pane's tab.
@@ -301,7 +329,7 @@ func (h *BufPane) OpenBuffer(b *buffer.Buffer) {
h.BWindow.SetBuffer(b)
h.Cursor = b.GetActiveCursor()
h.Resize(h.GetView().Width, h.GetView().Height)
h.Relocate()
h.initialRelocate()
// Set mouseReleased to true because we assume the mouse is not being
// pressed when the editor is opened
h.mouseReleased = true
@@ -311,6 +339,43 @@ func (h *BufPane) OpenBuffer(b *buffer.Buffer) {
h.lastClickTime = time.Time{}
}
// GotoLoc moves the cursor to a new location and adjusts the view accordingly.
// Use GotoLoc when the new location may be far away from the current location.
func (h *BufPane) GotoLoc(loc buffer.Loc) {
sloc := h.SLocFromLoc(loc)
d := h.Diff(h.SLocFromLoc(h.Cursor.Loc), sloc)
h.Cursor.GotoLoc(loc)
// If the new location is far away from the previous one,
// ensure the cursor is at 25% of the window height
height := h.BufView().Height
if util.Abs(d) >= height {
v := h.GetView()
v.StartLine = h.Scroll(sloc, -height/4)
h.ScrollAdjust()
v.StartCol = 0
}
h.Relocate()
}
func (h *BufPane) initialRelocate() {
sloc := h.SLocFromLoc(h.Cursor.Loc)
height := h.BufView().Height
// If the initial cursor location is far away from the beginning
// of the buffer, ensure the cursor is at 25% of the window height
v := h.GetView()
if h.Diff(display.SLoc{0, 0}, sloc) < height {
v.StartLine = display.SLoc{0, 0}
} else {
v.StartLine = h.Scroll(sloc, -height/4)
h.ScrollAdjust()
}
v.StartCol = 0
h.Relocate()
}
// ID returns this pane's split id.
func (h *BufPane) ID() uint64 {
return h.splitID

View File

@@ -722,7 +722,7 @@ func (h *BufPane) GotoCmd(args []string) {
}
line = util.Clamp(line-1, 0, h.Buf.LinesNum()-1)
col = util.Clamp(col-1, 0, util.CharacterCount(h.Buf.LineBytes(line)))
h.Cursor.GotoLoc(buffer.Loc{col, line})
h.GotoLoc(buffer.Loc{col, line})
} else {
line, err := strconv.Atoi(args[0])
if err != nil {
@@ -733,9 +733,8 @@ func (h *BufPane) GotoCmd(args []string) {
line = h.Buf.LinesNum() + 1 + line
}
line = util.Clamp(line-1, 0, h.Buf.LinesNum()-1)
h.Cursor.GotoLoc(buffer.Loc{0, line})
h.GotoLoc(buffer.Loc{0, line})
}
h.Relocate()
}
}
@@ -834,13 +833,11 @@ func (h *BufPane) ReplaceCmd(args []string) {
h.Cursor.SetSelectionStart(locs[0])
h.Cursor.SetSelectionEnd(locs[1])
h.Cursor.GotoLoc(locs[0])
h.GotoLoc(locs[0])
h.Buf.LastSearch = search
h.Buf.LastSearchRegex = true
h.Buf.HighlightSearch = h.Buf.Settings["hlsearch"].(bool)
h.Relocate()
InfoBar.YNPrompt("Perform replacement (y,n,esc)", func(yes, canceled bool) {
if !canceled && yes {
_, nrunes := h.Buf.ReplaceRegex(locs[0], locs[1], regex, replace)
@@ -853,8 +850,7 @@ func (h *BufPane) ReplaceCmd(args []string) {
h.Cursor.Loc = searchLoc
nreplaced++
} else if !canceled && !yes {
searchLoc = locs[0]
searchLoc.X += util.CharacterCount(replace)
searchLoc = locs[1]
} else if canceled {
h.Cursor.ResetSelection()
h.Buf.RelocateCursors()

View File

@@ -148,7 +148,19 @@ func (t *TabList) Display() {
var Tabs *TabList
func InitTabs(bufs []*buffer.Buffer) {
Tabs = NewTabList(bufs)
multiopen := config.GetGlobalOption("multiopen").(string)
if multiopen == "tab" {
Tabs = NewTabList(bufs)
} else {
Tabs = NewTabList(bufs[:1])
for _, b := range bufs[1:] {
if multiopen == "vsplit" {
MainTab().CurPane().VSplitBuf(b)
} else { // default hsplit
MainTab().CurPane().HSplitBuf(b)
}
}
}
}
func MainTab() *Tab {

View File

@@ -29,9 +29,11 @@ const LargeFileThreshold = 50000
// closed afterwards.
func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error, withSudo bool) (err error) {
var writeCloser io.WriteCloser
var screenb bool
var cmd *exec.Cmd
if withSudo {
cmd := exec.Command(config.GlobalSettings["sucmd"].(string), "dd", "bs=4k", "of="+name)
cmd = exec.Command(config.GlobalSettings["sucmd"].(string), "dd", "bs=4k", "of="+name)
if writeCloser, err = cmd.StdinPipe(); err != nil {
return
@@ -44,13 +46,13 @@ func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error,
cmd.Process.Kill()
}()
defer func() {
screenb := screen.TempFini()
if e := cmd.Run(); e != nil && err == nil {
err = e
}
screen.TempStart(screenb)
}()
screenb = screen.TempFini()
// need to start the process now, otherwise when we flush the file
// contents to its stdin it might hang because the kernel's pipe size
// is too small to handle the full file contents all at once
if e := cmd.Start(); e != nil && err == nil {
return err
}
} else if writeCloser, err = os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644); err != nil {
return
}
@@ -63,6 +65,15 @@ func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error,
err = e
}
if withSudo {
// wait for dd to finish and restart the screen if we used sudo
err := cmd.Wait()
if err != nil {
return err
}
screen.TempStart(screenb)
}
return
}

View File

@@ -20,6 +20,16 @@ func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error {
} else if option == "statusline" {
screen.Redraw()
} else if option == "filetype" {
config.InitRuntimeFiles()
err := config.ReadSettings()
if err != nil {
screen.TermMessage(err)
}
err = config.InitGlobalSettings()
if err != nil {
screen.TermMessage(err)
}
config.InitLocalSettings(b.Settings, b.Path)
b.UpdateRules()
} else if option == "fileformat" {
switch b.Settings["fileformat"].(string) {

View File

@@ -51,6 +51,7 @@ var optionValidators = map[string]optionValidator{
"colorcolumn": validateNonNegativeValue,
"fileformat": validateLineEnding,
"encoding": validateEncoding,
"multiopen": validateMultiOpen,
}
func ReadSettings() error {
@@ -330,9 +331,11 @@ var DefaultGlobalOnlySettings = map[string]interface{}{
"colorscheme": "default",
"divchars": "|-",
"divreverse": true,
"fakecursor": false,
"infobar": true,
"keymenu": false,
"mouse": true,
"multiopen": "tab",
"parsecursor": false,
"paste": false,
"pluginchannels": []string{"https://raw.githubusercontent.com/micro-editor/plugin-channel/master/channel.json"},
@@ -491,3 +494,19 @@ func validateEncoding(option string, value interface{}) error {
_, err := htmlindex.Get(value.(string))
return err
}
func validateMultiOpen(option string, value interface{}) error {
val, ok := value.(string)
if !ok {
return errors.New("Expected string type for multiopen")
}
switch val {
case "tab", "hsplit", "vsplit":
default:
return errors.New(option + " must be 'tab', 'hsplit', or 'vsplit'")
}
return nil
}

View File

@@ -2,6 +2,7 @@ package display
import (
"strconv"
"unicode"
runewidth "github.com/mattn/go-runewidth"
"github.com/zyedidia/micro/v2/internal/buffer"
@@ -53,8 +54,10 @@ func (w *BufWindow) SetBuffer(b *buffer.Buffer) {
} else {
w.StartLine.Row = 0
}
w.Relocate()
}
if option == "softwrap" || option == "wordwrap" {
w.Relocate()
for _, c := range w.Buf.GetCursors() {
c.LastVisualX = c.GetVisualX()
}
@@ -81,12 +84,6 @@ func (w *BufWindow) Resize(width, height int) {
w.updateDisplayInfo()
w.Relocate()
if w.Buf.Settings["softwrap"].(bool) {
for _, c := range w.Buf.GetCursors() {
c.LastVisualX = c.GetVisualX()
}
}
}
// SetActive marks the window as active.
@@ -150,10 +147,18 @@ func (w *BufWindow) updateDisplayInfo() {
w.gutterOffset += w.maxLineNumLength + 1
}
prevBufWidth := w.bufWidth
w.bufWidth = w.Width - w.gutterOffset
if w.Buf.Settings["scrollbar"].(bool) && w.Buf.LinesNum() > w.Height {
w.bufWidth--
}
if w.bufWidth != prevBufWidth && w.Buf.Settings["softwrap"].(bool) {
for _, c := range w.Buf.GetCursors() {
c.LastVisualX = c.GetVisualX()
}
}
}
func (w *BufWindow) getStartInfo(n, lineN int) ([]byte, int, int, *tcell.Style) {
@@ -219,7 +224,7 @@ func (w *BufWindow) Relocate() bool {
w.StartLine = c
ret = true
}
if c.GreaterThan(w.Scroll(w.StartLine, height-1-scrollmargin)) && c.LessThan(w.Scroll(bEnd, -scrollmargin+1)) {
if c.GreaterThan(w.Scroll(w.StartLine, height-1-scrollmargin)) && c.LessEqual(w.Scroll(bEnd, -scrollmargin)) {
w.StartLine = w.Scroll(c, -height+1+scrollmargin)
ret = true
} else if c.GreaterThan(w.Scroll(bEnd, -scrollmargin)) && c.GreaterThan(w.Scroll(w.StartLine, height-1)) {
@@ -620,6 +625,11 @@ func (w *BufWindow) displayBuffer() {
width = util.Min(ts, maxWidth-vloc.X)
totalwidth += ts
default:
if unicode.IsUpper(r) {
width = 2
totalwidth += 2
break
}
width = runewidth.RuneWidth(r)
totalwidth += width
}
@@ -654,6 +664,13 @@ func (w *BufWindow) displayBuffer() {
}
for _, r := range word {
if unicode.IsUpper(r.r) {
draw('~', nil, r.style, true, true)
draw(r.r, r.combc, r.style, true, false)
bloc.X++
continue
}
draw(r.r, r.combc, r.style, true, true)
// Draw any extra characters either spaces for tabs or @ for incomplete wide runes

View File

@@ -30,6 +30,28 @@ func (s SLoc) GreaterThan(b SLoc) bool {
return s.Line == b.Line && s.Row > b.Row
}
// LessEqual returns true if s is less than or equal to b
func (s SLoc) LessEqual(b SLoc) bool {
if s.Line < b.Line {
return true
}
if s.Line == b.Line && s.Row < b.Row {
return true
}
return s == b
}
// GreaterEqual returns true if s is bigger than or equal to b
func (s SLoc) GreaterEqual(b SLoc) bool {
if s.Line > b.Line {
return true
}
if s.Line == b.Line && s.Row > b.Row {
return true
}
return s == b
}
// VLoc represents a location in the buffer as a visual location in the
// linewrapped buffer.
type VLoc struct {

View File

@@ -79,6 +79,10 @@ func ShowFakeCursor(x, y int) {
lastCursor.style = style
}
func UseFake() bool {
return util.FakeCursor || config.GetGlobalOption("fakecursor").(bool)
}
// ShowFakeCursorMulti is the same as ShowFakeCursor except it does not
// reset previous locations of the cursor
// Fake cursors are also necessary to display multiple cursors
@@ -91,7 +95,7 @@ func ShowFakeCursorMulti(x, y int) {
// if enabled or using the terminal cursor otherwise
// By default only the windows console will use a fake cursor
func ShowCursor(x, y int) {
if util.FakeCursor {
if UseFake() {
ShowFakeCursor(x, y)
} else {
Screen.ShowCursor(x, y)
@@ -106,7 +110,7 @@ func SetContent(x, y int, mainc rune, combc []rune, style tcell.Style) {
}
Screen.SetContent(x, y, mainc, combc, style)
if util.FakeCursor && lastCursor.x == x && lastCursor.y == y {
if UseFake() && lastCursor.x == x && lastCursor.y == y {
lastCursor.r = mainc
lastCursor.style = style
lastCursor.combc = combc

View File

@@ -128,7 +128,13 @@ func (t *Terminal) Close() {
// call the lua function that the user has given as a callback
if t.getOutput {
if t.callback != nil {
t.callback(t.output.String())
Jobs <- JobFunction{
Function: func(out string, args []interface{}) {
t.callback(out)
},
Output: t.output.String(),
Args: nil,
}
}
}
}

View File

@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"io"
"net/http"
"os"
"os/user"
"path/filepath"
@@ -493,3 +494,16 @@ func Unzip(src, dest string) error {
return nil
}
// HttpRequest returns a new http.Client for making custom requests (for lua plugins)
func HttpRequest(method string, url string, headers []string) (resp *http.Response, err error) {
client := http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
return nil, err
}
for i := 0; i < len(headers); i += 2 {
req.Header.Add(headers[i], headers[i+1])
}
return client.Do(req)
}

View File

@@ -52,6 +52,10 @@ can change it!
| Ctrl-n | Find next instance of current search |
| Ctrl-p | Find previous instance of current search |
Note: Ctrl-n and Ctrl-p should be used from the main buffer, not from inside
the search prompt. After Ctrl-f, press enter to complete the search and then
you can use Ctrl-n and Ctrl-p to cycle through matches.
### File Operations
| Key | Description of function |

View File

@@ -1,26 +1,25 @@
# Micro help text
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.
Micro is an easy to use, intuitive, text editor that takes advantage of the
full capabilities of modern terminals.
To open the command bar, press Ctrl-e. This enables a `>` prompt for typing
commands. From now on when the documentation says to run a command such as `>
help`, this means press Ctrl-e and type `help` (and press enter to execute the
command).
Micro can be controlled by commands entered on the command bar, or with
keybindings. To open the command bar, press Ctrl-e: the `>` prompt will
display. From now on, when the documentation shows a command to run (such as
`> help`), press Ctrl-e and type the command followed by enter.
For a list of the default keybindings run `> help defaultkeys`.
For more information on keybindings see `> help keybindings`.
For a list of the default keybindings, run `> help defaultkeys`.
For more information on keybindings, see `> help keybindings`.
To toggle a short list of important keybindings, press Alt-g.
## Quick-start
Press Ctrl-q to quit, and Ctrl-s to save. Press Ctrl-e to start typing commands
and you can see which commands are available by pressing tab, or by viewing the
help topic `> help commands`.
To quit, press Ctrl-q. Save by pressing Ctrl-s. Press Ctrl-e, as previously
mentioned, to start typing commands. To see which commands are available, at the
prompt, press tab, or view the help topic with `> help commands`.
Move the cursor around with the mouse or the arrow keys. Run
`> help defaultkeys` to get a quick, easy overview of the default hotkeys and
what they do. For more info on rebinding keys, see type `> help keybindings`.
Move the cursor around with the mouse or with the arrow keys. Enter text simply
by pressing character keys.
If the colorscheme doesn't look good, you can change it with
`> set colorscheme ...`. You can press tab to see the available colorschemes,
@@ -32,19 +31,20 @@ Press Ctrl-w to move between splits, and type `> vsplit filename` or
## Accessing more help
Micro has a built-in help system which can be accessed with the `help` command.
Micro has a built-in help system which can be accessed with the `> help` command.
To use it, press Ctrl-e to access command mode and type in `help` followed by a
topic. Typing `help` followed by nothing will open this page.
To view help for the various available topics, press Ctrl-e to access command
mode and type in `> help` followed by a topic. Typing just `> help` will open
this page.
Here are the possible help topics that you can read:
Here are the available help topics:
* 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
* defaultkeys: Gives a more straight-forward list of the hotkey commands and
what they do.
what they do
* commands: Gives a list of all the commands and what they do
* options: Gives a list of all the options you can customize
* plugins: Explains how micro's plugin system works and how to create your own

View File

@@ -470,6 +470,7 @@ conventions for text editing defaults.
"Ctrl-o": "OpenFile",
"Ctrl-s": "Save",
"Ctrl-f": "Find",
"Alt-F": "FindLiteral",
"Ctrl-n": "FindNext",
"Ctrl-p": "FindPrevious",
"Ctrl-z": "Undo",

View File

@@ -223,6 +223,15 @@ Here are the available options:
default value: `true`
* `multiopen`: specifies how to layout multiple files opened at startup.
Most useful as a command-line option, like `-multiopen vsplit`. Possible
values correspond to commands (see `> help commands`) that open files:
* `tab`: open each file in a separate tab.
* `vsplit`: open files side-by-side.
* `hsplit`: open files stacked top to bottom.
default value: `tab`
* `paste`: treat characters sent from the terminal in a single chunk as a paste
event rather than a series of manual key presses. If you are pasting using
the terminal keybinding (not Ctrl-v, which is micro's default paste
@@ -462,7 +471,7 @@ so that you can see what the formatting should look like.
"filetype": "unknown",
"incsearch": true,
"ftoptions": true,
"ignorecase": false,
"ignorecase": true,
"indentchar": " ",
"infobar": true,
"initlua": true,

View File

@@ -287,6 +287,7 @@ The packages and functions are listed below (in Go type signatures):
- `String(b []byte) string`: converts a byte array to a string.
- `RuneStr(r rune) string`: converts a rune to a string.
- `Unzip(src, dest string) error`: unzips a file to given folder.
- `HttpRequest(method string, url string, headers []string) (http.Response, error)`: makes a http request.
This may seem like a small list of available functions but some of the objects
returned by the functions have many methods. The Lua plugin may access any

View File

@@ -60,23 +60,30 @@ ft["zig"] = "// %s"
ft["zscript"] = "// %s"
ft["zsh"] = "# %s"
local last_ft
function updateCommentType(buf)
if ft[buf.Settings["filetype"]] ~= nil and ft[buf.Settings["filetype"]] ~= nil then
buf.Settings["commenttype"] = ft[buf.Settings["filetype"]]
elseif buf.Settings["commenttype"] == nil then
buf.Settings["commenttype"] = "# %s"
if buf.Settings["commenttype"] == nil or last_ft ~= buf.Settings["filetype"] then
if ft[buf.Settings["filetype"]] ~= nil then
buf.Settings["commenttype"] = ft[buf.Settings["filetype"]]
else
buf.Settings["commenttype"] = "# %s"
end
last_ft = buf.Settings["filetype"]
end
end
function isCommented(bp, lineN, commentRegex)
local line = bp.Buf:Line(lineN)
if string.match(line, commentRegex) then
local regex = commentRegex:gsub("%s+", "%s*")
if string.match(line, regex) then
return true
end
return false
end
function commentLine(bp, lineN)
function commentLine(bp, lineN, indentLen)
updateCommentType(bp.Buf)
local line = bp.Buf:Line(lineN)
@@ -84,8 +91,11 @@ function commentLine(bp, lineN)
local sel = -bp.Cursor.CurSelection
local curpos = -bp.Cursor.Loc
local index = string.find(commentType, "%%s") - 1
local commentedLine = commentType:gsub("%%s", trim(line))
bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. commentedLine)
local indent = string.sub(line, 1, indentLen)
local trimmedLine = string.sub(line, indentLen + 1)
trimmedLine = trimmedLine:gsub("%%", "%%%%")
local commentedLine = commentType:gsub("%%s", trimmedLine)
bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), indent .. commentedLine)
if bp.Cursor:HasSelection() then
bp.Cursor.CurSelection[1].Y = sel[1].Y
bp.Cursor.CurSelection[2].Y = sel[2].Y
@@ -107,6 +117,9 @@ function uncommentLine(bp, lineN, commentRegex)
local sel = -bp.Cursor.CurSelection
local curpos = -bp.Cursor.Loc
local index = string.find(commentType, "%%s") - 1
if not string.match(line, commentRegex) then
commentRegex = commentRegex:gsub("%s+", "%s*")
end
if string.match(line, commentRegex) then
uncommentedLine = string.match(line, commentRegex)
bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. uncommentedLine)
@@ -128,7 +141,7 @@ function toggleCommentLine(bp, lineN, commentRegex)
if isCommented(bp, lineN, commentRegex) then
uncommentLine(bp, lineN, commentRegex)
else
commentLine(bp, lineN)
commentLine(bp, lineN, #util.GetLeadingWhitespace(bp.Buf:Line(lineN)))
end
end
@@ -141,11 +154,22 @@ function toggleCommentSelection(bp, startLine, endLine, commentRegex)
end
end
-- NOTE: we assume that the indentation is either tabs only or spaces only
local indentMin = -1
if not allComments then
for line = startLine, endLine do
local indentLen = #util.GetLeadingWhitespace(bp.Buf:Line(line))
if indentMin == -1 or indentLen < indentMin then
indentMin = indentLen
end
end
end
for line = startLine, endLine do
if allComments then
uncommentLine(bp, line, commentRegex)
else
commentLine(bp, line)
commentLine(bp, line, indentMin)
end
end
end
@@ -154,7 +178,7 @@ function comment(bp, args)
updateCommentType(bp.Buf)
local commentType = bp.Buf.Settings["commenttype"]
local commentRegex = "^%s*" .. commentType:gsub("%%","%%%%"):gsub("%$","%$"):gsub("%)","%)"):gsub("%(","%("):gsub("%?","%?"):gsub("%*", "%*"):gsub("%-", "%-"):gsub("%.", "%."):gsub("%+", "%+"):gsub("%]", "%]"):gsub("%[", "%["):gsub("%%%%s", "(.*)"):gsub("%s+", "%s*")
local commentRegex = "^%s*" .. commentType:gsub("%%","%%%%"):gsub("%$","%$"):gsub("%)","%)"):gsub("%(","%("):gsub("%?","%?"):gsub("%*", "%*"):gsub("%-", "%-"):gsub("%.", "%."):gsub("%+", "%+"):gsub("%]", "%]"):gsub("%[", "%["):gsub("%%%%s", "(.*)")
if bp.Cursor:HasSelection() then
if bp.Cursor.CurSelection[1]:GreaterThan(-bp.Cursor.CurSelection[2]) then
@@ -175,11 +199,6 @@ function comment(bp, args)
end
end
function trim(s)
local trimmed = s:gsub("^%s*(.-)%s*$", "%1"):gsub("%%","%%%%")
return trimmed
end
function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start
end

View File

@@ -9,7 +9,7 @@ rules:
- type: "\\b((s?size)|((u_?)?int(8|16|32|64|ptr)))_t\\b"
- type: "\\b[a-z_][0-9a-z_]+(_t|_T)\\b"
- type.extended: "\\b(bool)\\b"
- statement: "\\b(volatile|register)\\b"
- statement: "\\b(volatile|register|restrict)\\b"
- statement: "\\b(for|if|while|do|else|case|default|switch)\\b"
- statement: "\\b(goto|continue|break|return)\\b"
- preproc: "^[[:space:]]*#[[:space:]]*(define|pragma|include|(un|ifn?)def|endif|el(if|se)|if|warning|error)"
@@ -20,7 +20,7 @@ rules:
- symbol.operator: "([.:;,+*|=!\\%]|<|>|/|-|&)"
- symbol.brackets: "[(){}]|\\[|\\]"
# Integer Constants
- constant.number: "(\\b([1-9][0-9]*|0[0-7]*|0[Xx][0-9A-Fa-f]+|0[Bb][01]+)([Uu]?[Ll][Ll]?|[Ll][Ll]?[Uu]?)?\\b)"
- constant.number: "(\\b([1-9][0-9]*|0[0-7]*|0[Xx][0-9A-Fa-f]+|0[Bb][01]+)([Uu][Ll]?[Ll]?|[Ll][Ll]?[Uu]?)?\\b)"
# Decimal Floating Constants
- constant.number: "(\\b(([0-9]*[.][0-9]+|[0-9]+[.][0-9]*)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)[FfLl]?\\b)"
# Hexadecimal Floating Constants

68
runtime/syntax/cuda.yaml Normal file
View File

@@ -0,0 +1,68 @@
filetype: cuda
detect:
filename: "(\\.cu[h]?$)"
rules:
- identifier: "\\b[A-Z_][0-9A-Z_]*\\b"
- type: "\\b(float|double|bool|char|int|short|long|enum|void|struct|union|typedef|(un)?signed|inline)\\b"
- type: "\\b(((s?size)|((u_?)?int(8|16|32|64|ptr))|char(8|16|32))_t|wchar_t)\\b"
- type: "\\b[a-z_][0-9a-z_]+(_t|_T)\\b"
- type: "\\b(final|override)\\b"
- type.keyword: "\\b(auto|volatile|const(expr|eval|init)?|mutable|register|thread_local|static|extern|decltype|explicit|virtual)\\b"
- statement: "\\b(class|namespace|template|typename|this|friend|using|public|protected|private|noexcept)\\b"
- statement: "\\b(concept|requires)\\b"
- statement: "\\b(import|export|module)\\b"
- statement: "\\b(for|if|while|do|else|case|default|switch)\\b"
- statement: "\\b(try|throw|catch|operator|new|delete|static_assert)\\b"
- statement: "\\b(goto|continue|break|return)\\b"
- preproc: "^[[:space:]]*#[[:space:]]*(define|pragma|include|(un|ifn?)def|endif|el(if|se)|if|warning|error)|_Pragma"
# Conditionally-supported/extension keywords
- statement: "\\b(asm|fortran)\\b"
# GCC builtins
- statement: "(__attribute__[[:space:]]*\\(\\([^)]*\\)\\)|__(aligned|asm|builtin|hidden|inline|packed|restrict|section|typeof|weak)__)"
# CUDA specific keywords
- statement: "__(global|device|host|shared)__"
# Operator Color
- symbol.operator: "[-+*/%=<>.:;,~&|^!?]|\\b(sizeof|alignof|typeid|(and|or|xor|not)(_eq)?|bitor|compl|bitand|(const|dynamic|reinterpret|static)_cast)\\b"
# Parenthetical Color
- symbol.brackets: "[(){}]|\\[|\\]"
# Integer Literals
- constant.number: "(\\b([1-9][0-9']*|0[0-7']*|0[Xx][0-9a-fA-F']+|0[Bb][01]+)([Uu]?[Ll][Ll]?|[Ll][Ll]?[Uu]?)?\\b)"
# Decimal Floating-point Literals
- constant.number: "(\\b(([0-9']*[.][0-9']+|[0-9']+[.][0-9']*)([Ee][+-]?[0-9']+)?|[0-9']+[Ee][+-]?[0-9']+)[FfLl]?\\b)"
# Hexadecimal Floating-point Literals
- constant.number: "(\\b0[Xx]([0-9a-zA-Z']*[.][0-9a-zA-Z']+|[0-9a-zA-Z']+[.][0-9a-zA-Z']*)[Pp][+-]?[0-9']+[FfLl]?\\b)"
- constant.bool: "(\\b(true|false|NULL|nullptr)\\b)"
- constant.string:
start: "\""
end: "\""
skip: "\\\\."
rules:
- constant.specialChar: "\\\\([\"'abfnrtv\\\\]|[0-3]?[0-7]{1,2}|x[0-9A-Fa-f]{1,2}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})"
- constant.string:
start: "'"
end: "'"
skip: "\\\\."
rules:
- error: "..+"
- constant.specialChar: "\\\\([\"'abfnrtv\\\\]|[0-3]?[0-7]{1,2}|x[0-9A-Fa-f]{1,2}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})"
- comment:
start: "//"
end: "$"
rules:
- todo: "(TODO|XXX|FIXME):?"
- comment:
start: "/\\*"
end: "\\*/"
rules:
- todo: "(TODO|XXX|FIXME):?"

View File

@@ -1,7 +1,7 @@
filetype: git-commit
detect:
filename: "^(.*[\\/])?(COMMIT_EDITMSG|TAG_EDITMSG|MERGE_MSG|git-rebase-todo)$"
filename: "^(.*[\\/])?(COMMIT_EDITMSG|TAG_EDITMSG|MERGE_MSG)$"
rules:
# File changes

View File

@@ -39,13 +39,12 @@ rules:
rules:
- constant.specialChar: "\\\\([\"'abfnrtv\\\\]|[0-3]?[0-7]{1,2}|x[0-9A-Fa-f]{1,2}|u[0-9A-Fa-f]{1,4}|U[0-9A-Fa-f]{1,8})"
# Lifted from Rust's syntax highlighting
- constant.string: "'(\\\\.|.)'"
- constant.string:
start: "'"
start: "'\""
end: "'"
skip: "\\\\."
rules:
- error: "..+"
- constant.specialChar: "\\\\([\"'abfnrtv\\\\]|[0-3]?[0-7]{1,2}|x[0-9A-Fa-f]{1,2}|u[0-9A-Fa-f]{1,4}|U[0-9A-Fa-f]{1,8})"
rules: []
- comment:
start: "#="

View File

@@ -0,0 +1,40 @@
# For more information, see https://github.com/casey/just
filetype: 'justfile'
detect:
filename: '(^\\.?[Jj]ustfile|\\.just)$'
header: "^#!.*/(env +)?[bg]?just --justfile"
rules:
- preproc: "\\<(ifeq|ifdef|ifneq|ifndef|else|endif)\\>"
- statement: "^(export|include|override)\\>"
- symbol.operator: "^[^:= ]+:"
- symbol.operator: "([=,%]|\\+=|\\?=|:=|&&|\\|\\|)"
- statement: "\\$\\((abspath|addprefix|addsuffix|and|basename|call|dir)[[:space:]]"
- statement: "\\$\\((error|eval|filter|filter-out|findstring|firstword)[[:space:]]"
- statement: "\\$\\((flavor|foreach|if|info|join|lastword|notdir|or)[[:space:]]"
- statement: "\\$\\((origin|patsubst|realpath|shell|sort|strip|suffix)[[:space:]]"
- statement: "\\$\\((value|warning|wildcard|word|wordlist|words)[[:space:]]"
# default functions - probably shouldn't be overwritten by assignment
- statement: "\\b(arch|os|os_family|env_var|invocation_directory|justfile|justfile_directory|just_executable|lowercase|quote|replace|trim|trim_end|trim_end|trim_end_match|trim_end_matches|trim_start|trim_start_match|trim_start_matches|uppercase)\\b"
- identifier: "^.+:"
- identifier: "[()$]"
- constant.string:
start: "\""
end: "\""
skip: "\\\\."
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "'"
skip: "\\\\."
rules:
- constant.specialChar: "\\\\."
- identifier: "\\$+(\\{[^} ]+\\}|\\([^) ]+\\))"
- identifier: "\\$[@^<*?%|+]|\\$\\([@^<*?%+-][DF]\\)"
- identifier: "\\$\\$|\\\\.?"
- comment:
start: "#"
end: "$"
rules: []

View File

@@ -1,7 +1,7 @@
filetype: perl
detect:
filename: "\\.pp[lmp]$"
filename: "\\.p[lmp]$"
header: "^#!.*/(env +)?perl( |$)"
rules:

View File

@@ -0,0 +1,55 @@
filetype: smalltalk
detect:
filename: "\\.(st|sources|changes)$"
rules:
- statement: "\\b(self|nil|true|false|ifTrue|ifFalse|whileTrue|whileFalse)\\b"
- constant: "(\\$|@|@@)?\\b[A-Z]+[0-9A-Z_a-z]*"
- constant.number: "(?i)\\b0x[0-9a-fA-F][0-9a-f_]*\\b"
- constant.number: "(?i)\\b0b[01][01_]*\\b"
- constant.number: "(?i)\\b[0-9][0-9_]*(['.'][0-9_]+)?(e[\\-]?[0-9_]+)?\\b"
# Ruby "Symbols"
- constant: "(i?)([ ]|^):[0-9A-Z_]+\\b"
- constant: "\\b(__FILE__|__LINE__)\\b"
- constant: "/([^/]|(\\\\/))*/[iomx]*|%r\\{([^}]|(\\\\}))*\\}[iomx]*"
- constant.string:
start: "'"
end: "'"
skip: "\\\\."
rules: []
- constant.string:
start: "\""
end: "\""
skip: "\\\\."
rules:
- symbol.brackets:
start: "#\\{"
end: "\\}"
rules:
- default: ".*"
- constant.string.exec:
start: "`"
end: "`"
skip: "\\\\."
rules:
- symbol.brackets:
start: "#\\{"
end: "\\}"
rules:
- default: ".*"
- constant.string: "%[QW]?\\{[^}]*\\}|%[QW]?\\([^)]*\\)|%[QW]?<[^>]*>|%[QW]?\\[[^]]*\\]|%[QW]?\\$[^$]*\\$|%[QW]?\\^[^^]*\\^|%[QW]?![^!]*!"
- constant.string: "%[qw]\\{[^}]*\\}|%[qw]\\([^)]*\\)|%[qw]<[^>]*>|%[qw]\\[[^]]*\\]|%[qw]\\$[^$]*\\$|%[qw]\\^[^^]*\\^|%[qw]![^!]*!"
- constant.string.exec: "%[x]\\{[^}]*\\}|%[x]\\([^)]*\\)|%[x]<[^>]*>|%[x]\\[[^]]*\\]|%[x]\\$[^$]*\\$|%[x]\\^[^^]*\\^|%[x]![^!]*!"
- symbol.operator: "[-+/*=<>!~%&|^]|\\b:"
- symbol.brackets: "([(){}]|\\[|\\])"
- constant.macro:
start: "<<-?'?EOT'?"
end: "^EOT"
rules: []
- preproc.shebang: "^#!.+?( |$)"

View File

@@ -41,4 +41,9 @@ rules:
skip: "\\\\."
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "`"
end: "`"
rules:
- constant.specialChar: "\\\\."
- identifier: "\\x24\\{.*?\\}"

View File

@@ -22,6 +22,13 @@ mv micro micro-$1
tar -czf micro-$1-osx.tar.gz micro-$1
mv micro-$1-osx.tar.gz binaries
# Mac ARM64
echo "MacOS ARM64"
GOOS=darwin GOARCH=arm64 make build
mv micro micro-$1
tar -czf micro-$1-macos-arm64.tar.gz micro-$1
mv micro-$1-macos-arm64.tar.gz binaries
# Linux
echo "Linux 64"
GOOS=linux GOARCH=amd64 make build

View File

@@ -17,6 +17,7 @@ hub release edit nightly \
--draft=false \
--message "$MESSAGE (please DISREGARD the creation date of this Github release). Assets uploaded on $(date) for commit $commitID." \
--attach "binaries/micro-$1-osx.tar.gz" \
--attach "binaries/micro-$1-macos-arm64.tar.gz" \
--attach "binaries/micro-$1-linux64.tar.gz" \
--attach "binaries/micro-$1-linux64-static.tar.gz" \
--attach "binaries/micro-$1-amd64.deb" \

View File

@@ -21,6 +21,7 @@ hub release create $tag \
--prerelease \
--message "$1${NL}${NL}$2" \
--attach "binaries/micro-$1-osx.tar.gz" \
--attach "binaries/micro-$1-macos-arm64.tar.gz" \
--attach "binaries/micro-$1-linux64.tar.gz" \
--attach "binaries/micro-$1-linux64-static.tar.gz" \
--attach "binaries/micro-$1-amd64.deb" \

View File

@@ -20,6 +20,7 @@ echo "Creating new release"
hub release create $tag \
--message "$1${NL}${NL}$2" \
--attach "binaries/micro-$1-osx.tar.gz" \
--attach "binaries/micro-$1-macos-arm64.tar.gz" \
--attach "binaries/micro-$1-linux64.tar.gz" \
--attach "binaries/micro-$1-linux64-static.tar.gz" \
--attach "binaries/micro-$1-amd64.deb" \