Compare commits

...

172 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
cat-master21
225927b9a2 add: add Pacstall to README.md (#2367) 2022-07-24 14:14:52 -07:00
Daniel Lee Harple
88e76b367c plugins: load directories that are symlinks (#2214)
Fix issue where symlinked plugin directories were ignored. For example

    $ file ~/.config/micro/plug/example
    example: symbolic link to <target directory>

This allows plugins to be managed in a user's "dotfiles" repository, and
be symlinked into micro's plugin directory.
2022-07-24 14:13:46 -07:00
silvershade1337
208a778387 Add new python 3.10 keywords (#2243)
Keywords from the new python 3.10.0 feature "Structural Pattern Matching" - match and case
2022-07-24 14:11:48 -07:00
Martin Kühl
738f131269 Fix gruvbox-tc colorscheme (#2240)
The underline style is missing a color and accidentally using the
background color for its foreground.  This makes links essentially
invisible.  It's also missing the todo style.

This change adds the missing style and color.  Following the gruvbox
colorscheme it uses the gruvbox shade of blue for links, and makes
todos bold.
2022-07-24 14:11:16 -07:00
Matthias Thym
639d8a0b08 Add Terraform syntax support (#2279) 2022-07-24 14:10:29 -07:00
Lincoln Júnior
ce2d186543 Fix cursor position change after CopyLine command (#2353) 2022-07-24 14:09:14 -07:00
Max Grinberg
091fa9091d Added installation instruction for Gentoo distro (#2209)
Co-authored-by: Max Grinberg <codeswhite@protonmail.com>
2022-07-24 14:07:57 -07:00
worldmaker
7efec130dc Fix weird behavior of JumpToMatchingBrace in some ill cases (#1966)
It should not return false immediately when no matching brace is found. This makes the jump fails in certain case: `[  )I]` =/=> `[I  )]`.
When there is no brace near the cursor, the last statement is also executed. This may cause problems when chaining commands.
2022-07-24 14:06:59 -07:00
Mario
cf98b7f824 Update README.md (#2109)
Change over 10 years deprecated ifconfig
2022-07-24 14:04:59 -07:00
Zachary Yedidia
dde4001170 Merge branch 'john-batch-master' 2022-07-24 14:04:00 -07:00
john-batch
c226779aca Case-insensitive highlighting of hexadecimal constants 2022-07-24 14:03:53 -07:00
Max Grinberg
02ef99a3a6 Linux clipboard notes reformatted and reordered (#2210)
Co-authored-by: Max Grinberg <codeswhite@protonmail.com>
2022-07-24 14:00:41 -07:00
Zachary Yedidia
bd9bd3a215 Merge branch 'mardukbp-patch-1' 2022-07-24 13:59:18 -07:00
Zachary Yedidia
ce98970c06 Merge branch 'patch-1' of https://github.com/mardukbp/micro into mardukbp-patch-1 2022-07-24 13:59:12 -07:00
Sizhe Zhao
7cc74491d0 runtime/help/defaultkeys.md: Fix table (#2376) 2022-07-24 13:56:30 -07:00
Waldir Pimenta
63cb6ce9fd help/options.md: reword hlsearch help text (#2502)
Also adjust text wrapping in some lines that had become too long with recent edits.
2022-07-24 13:56:11 -07:00
Abirdcfly
ee6688eb74 delete minor unreachable code caused by log.Fatal (#2507)
Signed-off-by: Abirdcfly <fp544037857@gmail.com>
2022-07-24 13:56:02 -07:00
Zachary Yedidia
ad70480de7 Only run info plist on darwin 2022-07-21 17:54:01 -07:00
Zachary Yedidia
490ee93796 Fix info-plist script 2022-07-21 17:46:23 -07:00
Zachary Yedidia
ba11d98fef Merge 2022-07-20 10:16:46 -07:00
Zachary Yedidia
d629008688 Add livemd to markdown extensions 2022-07-20 10:16:42 -07:00
Naftoli Gugenheim
6aa3ea70dc scala.yaml: add support for .sc extension (#2452)
It's used for Ammonite scripts and Scala worksheets
2022-07-17 12:19:07 -07:00
Mikko
3d4012850a fix javascript syntax recognizing parts of words as keywords (#2462) 2022-07-17 12:18:56 -07:00
Aaron Clark
5e035efbcb added support for HolyC (#2473) 2022-07-17 12:18:39 -07:00
yeti
515ec57b77 improve fortran syntax highlighting (#2479)
* support integer highlighting

* add missing keywords and move some to where they fit better

* add missing operators

* fix previous commit

* add and

* add import
2022-07-17 12:18:30 -07:00
Ben Hammond
585dcc7d19 Adds options for tab bar and tab color reversing (#2480)
* Adds options for tab bar and tab color reversing

* Fixes small bug with tabreverse, options now work fully as expected
2022-07-17 12:18:11 -07:00
raidenXR
fc21fc9816 Gnuplot Syntax highlighting (#2483)
* gnuplot syntax support

* Update gnuplot.yaml

* Add files via upload

* Update gnuplot.yaml
2022-07-17 12:17:11 -07:00
Matthias Thym
77c784def4 Add nushell syntax highlighting (#2486) 2022-07-17 12:16:57 -07:00
Peder Bergebakken Sundt
80bfaf1c54 runtime/syntax/nix: Add support for block comments (#2488) 2022-07-17 12:16:47 -07:00
Waldir Pimenta
d89db64829 syntax/git-rebase-todo.yaml: support more commands (#2495)
For reference, see the list of supported commands in the help text of git's interactive rebase:
https://github.com/git/git/blob/v2.37.1/rebase-interactive.c#L43-L59
2022-07-17 12:16:35 -07:00
Vilém Zouhar
191438b481 add new logo with white shadow, change readme title logo (#2497) 2022-07-17 12:16:27 -07:00
USAMI Kenta
37ed9dfe1e PHP: Add enum and keyword, and modify types (#2204)
* Add enum keyword to PHP (8.1) syntax

* Specify only keywords that are valid as type declarations as PHP types

boolean, integer and resource are not valid type name.

* Add match keyword to PHP (8.2) syntax
2022-07-17 12:16:17 -07:00
Zachary Yedidia
0ac7193c4d Fix cross compilation from macOS 2022-07-15 11:40:32 -07:00
Zachary Yedidia
9ce469f372 Update zyedidia/pty for openbsd support
Fixes #2335
2022-06-24 23:31:13 -07:00
Zachary Yedidia
03ae049c0f Use zyedidia/clipper for external clipboard
Micro will now also search for a program called micro-clip for handling
the clipboard. This allows the user to make a program called micro-clip
that micro will call out to for performing copy/paste. For copy it will
be called with `micro-clip -i <reg>` and the text will be provided on
stdin. For paste it will be called with `micro-clip -o <reg>` and micro
expects the text to be provided on stdout.
2022-06-14 08:40:57 -04:00
Zachary Yedidia
4194c502ae Update clipboard for WSL support 2022-06-12 15:39:33 +01:00
Zachary Yedidia
f32da00667 Add discussions note to readme 2022-06-10 11:19:05 +01:00
Zachary Yedidia
a285e814c1 Update tcell for OSC 52 fix
Ref #2444
2022-06-08 23:47:56 +01:00
Ethan Kinnear
6948cc88ef Register Brewfiles as Ruby files (#2432)
A `Brewfile` (sometimes named `.Brewfile`) is a bundler for Homebrew packages.
Brewfiles are written in Ruby and are functionally similar to Gemfiles.

`homebrew-bundle` on GitHub: <https://github.com/Homebrew/homebrew-bundle>.
`brew bundle` Manpage: <https://docs.brew.sh/Manpage#bundle-subcommand>.
2022-06-08 00:07:59 +01:00
Ruzie
25a19e2f21 fix: add "unknown" type (#2445) 2022-06-08 00:07:38 +01:00
Mikko
c57c5c04e5 Julia syntax improvements (#2415)
* fix D syntax highlighting for integer literals with underscores

* improve julia syntax highlighting for strings, chars and operators
2022-05-15 13:00:59 -07:00
Lars Müller
656e0a8a7b Lua syntax highlighting: Various fixes (#2426) 2022-05-15 13:00:44 -07:00
Lars Müller
176d1aa17a Fix syntax highlighting of single-quoted strings (#2425) 2022-05-15 13:00:29 -07:00
Lars Müller
db3afc1c0d Fix Lua number syntax highlighting (#2409)
* Fix Lua number syntax highlighting

* Number RegEx: Fix hex exponent

The hex exponent doesn't support hex digits, only decimals.
2022-04-28 15:28:28 -07:00
esdnm
dd69599f37 Update README.md (#2400) 2022-04-10 16:36:19 -07:00
Zachary Yedidia
2f4675eb93 Merge 2022-02-26 18:33:35 -08:00
Zachary Yedidia
56c825c44c Update minimum required Go version to 1.16
Fixes #2361
2022-02-26 18:33:12 -08:00
0x5c
987e409071 Added lines and percentage statusbar directives (#2055)
- "lines" for the number of lines in the buffer
- "percentage" for the percentage of the file at the current line

Fixes zyedidia#2049
2022-02-22 01:31:32 -08:00
Philippe Eberli
fe59e18e69 Error in documentation of +LINE:COL (#2205)
Its +LINE:COL not +LINE,COL
2022-02-14 13:32:46 -08:00
ftphikari
d3b9b37b07 runtime/syntax: add rudimentary Odin support (#2296)
Odin is a general-purpose programming language with distinct typing,
built for high performance, modern systems, and built-in data-oriented
data types. The Odin Programming Language, the C alternative for
the joy of programming. The Data-Oriented Language for Sane Software
Development.

https://odin-lang.org/
https://odin-lang.org/docs/overview/
https://github.com/odin-lang/Odin
2022-02-11 14:15:34 -08:00
Evan Shimoniak
9ca89ad300 Made apparent the functionality of the ftoptions plugin (#2321)
* Clarified meaning of indentchar setting

The description "sets the indentation character" combined with the default value of a space led me to believe that this was a way to set a preference for tabs/spaces and choose a number of spaces per indentation all at once. I've updated the description to try to make its true function clearer.

* Added note on rmtrailingws

This behavior was unexpected for me, so it's probably good to let other users know which option has precedence.

* Added details to help command

Initially I kept trying to use `help <command-name>` rather than `help commands`

* Added warning about ftoptions and tabstospaces

The current description for ftoptions states that it "alters some default options depending on the filetype", which hints at this behavior, but does not explicitly state it.

* Clarified specific functionality of ftoptions
2022-02-11 14:15:26 -08:00
Andrey Bienkowski
031d953ed5 Help: mention (un)indent in defaultkeys (#2358) 2022-02-11 14:13:35 -08:00
Shura
9ece5c8a3f Perl syntax improvement (#2359)
* Perl syntax improvement

Fixed \" inside strings
Fixed comment coloring
Improved integer, float, strings variable coloring
Added regex coloring

* Update perl.yaml
2022-02-11 14:13:27 -08:00
Andrew
f20179519f Detect more file types for git syntax highlighting (#2330)
* Update git-commit.yaml

This will enable syntax highlighting for merge commit messages

* Update git-commit.yaml
2022-01-08 19:51:15 -08:00
dependabot[bot]
80d0654847 Bump gopkg.in/yaml.v2 from 2.2.7 to 2.2.8 (#2329)
Bumps [gopkg.in/yaml.v2](https://github.com/go-yaml/yaml) from 2.2.7 to 2.2.8.
- [Release notes](https://github.com/go-yaml/yaml/releases)
- [Commits](https://github.com/go-yaml/yaml/compare/v2.2.7...v2.2.8)

---
updated-dependencies:
- dependency-name: gopkg.in/yaml.v2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-06 18:14:50 -08:00
Zachary Yedidia
a40d171d9c Merge 2022-01-06 18:11:15 -08:00
Zachary Yedidia
1cf8cbe546 Update luar import path
Fixes #2306
2022-01-06 18:11:02 -08:00
Zachary Yedidia
409ac54605 Add unofficial discord to readme 2022-01-01 00:33:05 -05:00
Juan Francisco Cantero Hurtado
3a1ec088e2 Raku syntax: fix comments (#2318)
Code:
 # sub xyz(Str is encoded("utf8")) returns int32 is native("asdf") { * }
2021-12-31 18:51:53 -05:00
Juan Francisco Cantero Hurtado
a2d83132ca Raku syntax: Fix strings and comments (#2311)
* Raku syntax: Fix strings and comments

Problematic code:
my @array1 = [
   "'", "a", "b"
];
my @array2 = [
   '"', 'a', 'b'
];
my @array3 = [
   "#", "a", "b"
];

I deleted "default" because it was breaking comments with urls after
of my changes.

Some parts were taken from:
https://github.com/hankache/raku.nanorc/blob/master/raku.nanorc

* Raku syntax: fix strings

Code:
sub xyz(Str is encoded('utf8')) returns int32 is native('asdf') { * }
sub xyz(Str is encoded("utf8")) returns int32 is native("asdf") { * }

From python3.yaml
2021-12-31 17:42:21 -05:00
Reilly Wood
580c32bcef Fix repo.json info in plugin docs (#2313) 2021-12-31 02:06:53 -05:00
Owen Valentine
cc0af275c1 Adjust default keybinding text (#2293)
Fixes #2287
2021-12-24 22:32:15 -05:00
Juan Francisco Cantero Hurtado
fd20fc8837 Fix the syntax for Raku variables. (#2309)
The current version has problems with the last argument and the
brackets in this code:

sub myfunction(Int $x1, Int $x2){

}

Taken from:
https://github.com/hankache/raku.nanorc/blob/master/raku.nanorc
2021-12-21 23:47:31 -05:00
Jake Leahy
c442d7030d Fix edge case when comment is at start of line (#2237) 2021-12-05 17:45:10 -08:00
antonl05
6998cb5602 add more types for nim (#2284) 2021-11-22 22:41:04 -08:00
Zachary Yedidia
d2dca2b6c3 Fix 2021-11-22 18:46:36 -08:00
Zachary Yedidia
0e63224dea Use abspath for local glob settings
Ref #2276
2021-11-22 18:45:19 -08:00
Hugo Hromic
0bbc3e7e3d Add support for alternatives system in Debian package (#1935)
* Allows for micro to be selectable in the `editor` group
* Use same priority as in the nano package

Ref: https://wiki.debian.org/DebianAlternatives
2021-11-17 15:51:40 -08:00
Matthias Thym
dd8e341de2 Fix linter help formatting (#2280) 2021-11-17 12:59:16 -08:00
abaldota
d023aef6b5 Python syntax: multiline string should be constant.string, not comment (#2268)
* Python syntax: multiline string should be comment.string, not comment 

''' delimits multiline strings, not comments

* Python syntax: multiline string should be comment.string, not comment 

''' delimits multiline strings, not comments

* Update python3.yaml for python3.10 keywords
2021-11-14 21:54:56 -08:00
Herby Gillot
26c24c25c0 README: add MacPorts install info (#2265) 2021-11-06 20:18:24 -07:00
Evan Shimoniak
58e3cc1be0 Clarified some documentation (#2259)
* Clarified meaning of indentchar setting

The description "sets the indentation character" combined with the default value of a space led me to believe that this was a way to set a preference for tabs/spaces and choose a number of spaces per indentation all at once. I've updated the description to try to make its true function clearer.

* Added note on rmtrailingws

This behavior was unexpected for me, so it's probably good to let other users know which option has precedence.

* Added details to help command

Initially I kept trying to use `help <command-name>` rather than `help commands`
2021-11-02 13:26:14 -07:00
Zachary Yedidia
7df91eb038 Fix makefile for cross compilation 2021-10-29 04:47:23 +00:00
Dmitry Maluka
728d87ceba Fix regression: non-working direct colors in syntax files (#2252)
After 9ad4437, directly specifying color names (instead of syntax groups)
in syntax files no longer works. In particular *.patch and *.diff files
are not highlighted, since in patch.yaml direct colors names are used.

Restore the previous behavior of GetColor (fallback to direct colors if
no syntax group found) to fix this regression, but also make some changes
in StringToStyle and StringToColor to still fix the issue which was fixed
by 9ad4437. In other words, ensure that there is no confusion between
direct colors ("red", "green" etc) and syntax groups omitted in the
colorscheme file.
2021-10-27 15:12:55 -07:00
Zachary Yedidia
a6796fcbd9 Update makefile generation rules
Ref #2229
2021-09-29 16:30:20 -07:00
Dmitry Maluka
ffbb257434 Support for highlighting all search matches (hlsearch) (#1762)
* Support for highlighting all search matches (hlsearch)

hlsearch is implemented efficiently using the buffer's line array,
somewhat similarly to the syntax highlighting.
Unlike the syntax highlighter which highlights the entire file,
hlsearch searches for matches for the displayed lines only.
Matches are searched when the given line is displayed first time
or after it was modified. Otherwise the previously found matches
are used.

* Add UnhighlightSearch action

and add it to the list of actions triggered by Esc key by default.

* Add comment explaining the purpose of search map

* Add hlsearch colors to colorschemes

Mostly just copied from the corresponding original (mostly vim) colorschemes.

* Highlight matches during/after replace as well

As a side effect it also changes the last search value, i.e. affects FindNext
and FindPrevious, but it's probably fine. In vim it works the same way.

* Improve hlsearch option description
2021-09-28 13:39:03 -07:00
Dmitry Maluka
9ad4437a98 Fix some issues with default colors in colorschemes (#2225)
* Fix default colors for unconfigured syntax groups

When GetColor is called for a syntax group not specified in the
colorscheme, it should fallback not to the terminal's default colors
(tcell.DefaultColor) but to the colorscheme's defaults (DefStyle)
which may be different from tcell.DefaultColor.

For example, if we are using micro's default colorscheme in a terminal
which uses a black-on-white theme, then dots and commas in Go files
("symbol" syntax group in go.yaml) are displayed black on a dark
background, i.e. barely visible.

* Avoid using terminal's default colors directly

If a syntax group color is set to "default" (which we have for some
syntax groups in some colorschemes), it defaults to the terminal's
default colors (tcell.DefaultColor), which is fine for 16-color
colorschemes but not quite fine for truecolor and 256-color
colorschemes which should not depend on the terminal colors.
It should default to the colorscheme's default (DefStyle) instead.

For example, if we are using micro's default colorscheme in a terminal
which uses a black-on-white theme, then "bool" type in C files
("type.extended" syntax group in c.yaml) is displayed black on a dark
background, i.e. barely visible.
2021-09-28 13:30:29 -07:00
Dmitry Maluka
a21a720941 Make 'make' do the same as 'make build' (#2217)
Fix a slight regression after ec3292: when 'make' is run without specifying
a target, it counter-intuitively runs fetch-tags instead of building micro.
2021-09-24 14:40:26 -07:00
Ryan Westlund
c2d7b62e8f Fix #2190: Document goto command in commands.md (#2218) 2021-09-24 14:40:11 -07:00
Ryan Westlund
9270f17378 Fix #1943: 'Duplicated line' message being wrong (#2219) 2021-09-24 14:39:58 -07:00
TogoorooDev
395bfc2307 Syntax Highlighting Support for FreeBSD Kernel Configuration Files (#2220)
* added FreeBSD kernel configuration file format

* updated format, notably to highlight the word 'include'
2021-09-24 14:39:46 -07:00
Ali Kefia
a417ec4dcb normalize path - force slash separator to access embed FS (#2197) 2021-08-25 16:26:54 -04:00
Ali Kefia
ec3292e8c4 Build : using go:generate and go:embed (#2195)
* using go:generate and go:embed

* fix import
2021-08-24 22:02:29 -04:00
Zachary Yedidia
fe3186ba9d Ignore tool files 2021-08-21 18:07:43 -04:00
Zachary Yedidia
3a97ce820c More style improvements 2021-08-21 18:04:08 -04:00
Zachary Yedidia
c44ccb8cc7 Merge 2021-08-21 17:58:35 -04:00
Zachary Yedidia
0914f158c2 Improve comments 2021-08-21 17:58:30 -04:00
Andrew Clarke
dcf94816fb remove carriage return from -clean prompt and fix broken logic (#2186) 2021-08-21 00:30:16 -04:00
Zachary Yedidia
bb609467dd Update comment filetype when commenting 2021-08-20 14:42:38 -04:00
Zachary Yedidia
a4c3f7dad9 Merge branch 'master' of https://github.com/zyedidia/micro 2021-08-20 13:56:22 -04:00
Zachary Yedidia
dceddcfd83 Fix save with sudo auto-detection and sudo/doas message 2021-08-20 13:55:59 -04:00
Zachary Yedidia
0c2e139672 Fix formatting 2021-08-18 16:55:51 -04:00
Zachary Yedidia
fb1e7eabab Update install instructions 2021-08-18 16:55:22 -04:00
Zachary Yedidia
272f3adcc4 Add eget to install instructions 2021-08-18 16:13:17 -04:00
Dmitry Maluka
87ad6fc0bb plugins.md: update link to the internal documentation (#2191)
godoc.org now redirects to pkg.go.dev and it's not obvious how to locate
the internal packages documentation at https://pkg.go.dev/github.com/zyedidia/micro
2021-08-18 15:35:49 -04:00
Zachary Yedidia
2eeeb0f2e4 Update runtime 2021-08-18 01:09:53 -04:00
Zachary Yedidia
aa541d6d6f Merge 2021-08-18 01:08:58 -04:00
Zachary Yedidia
403a9eb11d Add rust clippy linter and go vet linter 2021-08-18 01:08:54 -04:00
john-batch
77f93bfd93 Make yes/no prompts case-insensitive (#2182) 2021-08-13 23:56:26 -04:00
Zachary Yedidia
b97638566e Merge branch 'pyfisch-patch-3' 2021-08-06 20:45:12 -04:00
Zachary Yedidia
7a1ba01621 Merge branch 'patch-3' of https://github.com/pyfisch/micro into pyfisch-patch-3 2021-08-06 20:44:57 -04:00
riley
2b8cd6b758 Highlight racket files as lisp (#1931)
Add syntax highlighting for [racket](racket-lang.org), a (variant of scheme which is a) variant of lisp which uses the .rkt extension.
2021-08-06 20:38:22 -04:00
AAAA
cbe339da07 Update v.yaml (#1925)
Improvements:
 - Use proper scope names for better colorization
 - Better regex to detect binary, octal, decimal and hexadecimal numbers
 - Extend some definitions based on the Vlang docs

Co-authored-by: AAAA <dev@onerbs.com>
2021-08-06 20:37:42 -04:00
Zachary Yedidia
e290ce2de5 Fixes for syntax and docs
Fixes #2163
Ref #2173
2021-08-03 00:07:14 -04:00
Andrey Nering
c7fd4ba5f1 Document that "bubblegum" is a light theme (#2153) 2021-08-02 21:13:05 -04:00
Zachary Yedidia
0efc919f24 Merge 2021-08-02 21:06:28 -04:00
Zachary Yedidia
c315a91fc6 Allow aborting while opening a file with backup
Also fixes an issue where the abort prompt consumes interrupt signals.

Fixes #2151
2021-08-02 21:05:22 -04:00
pyfisch
6e1fe5b301 More precise filename detection for shell scripts
Make the regular expression much more precise:

* match literal dots instead of any char (match rc.conf but not rcXconf)
* match special filenames exactly (match PKGBUILD but not myPKGBUILD.something)

Run build-all to update internal/config/runtime.go

closes #2163
2021-07-21 22:09:46 +02:00
pyfisch
84a490f14c Update rust syntax: don't highlight lifetimes (#2164)
Work-around rust lifetimes and character literals both using single quotes.
2021-07-21 15:02:28 -04:00
pyfisch
42a9302636 Update rust syntax: char literal (#2162)
Highlight character literals started with a single quote (').
Importantly this ensures correct highlighting for the character literal '"'.
Limitation: rust char literals contain exactly one character, however this isn't checked by the highlighter.

Closes #2160
2021-07-21 12:37:41 -04:00
Ali Kefia
ae0c28a03d Fix name collision on linter name (swiftc) (#2158) 2021-07-18 18:30:52 -04:00
Ali Kefia
1a5518ebbb Shellcheck as a new shell linter + runtime.go out of git control (#2157)
* shellcheck as a new shell linter + runtime.go out of git control

* keep runtime.go and keep both shfmt and shellcheck since we can remove from custom conf
2021-07-16 15:01:50 -04:00
Rylee
160a81c572 Add alcritty and foot to the list of OSC 52 supporting terminals (#2154) 2021-07-13 23:37:48 -04:00
Ali Kefia
4a2a72983f Search the last match on line when search back (#2156) 2021-07-13 23:37:22 -04:00
Zachary Yedidia
33e064b3b9 Add default binding for FindLiteral 2021-07-04 20:00:49 -04:00
Zachary Yedidia
005442a4d0 Merge 2021-06-17 17:11:35 -04:00
Zachary Yedidia
6c666190e2 Update zyedidia/pty from upstream
Fixes #2138
2021-06-17 17:10:59 -04:00
vandervoortj
9ceb69921a Add nix language syntax (#2024)
* Create nix.yaml

Add nix language syntax

* Add nix-linter
2021-06-15 17:56:31 -04:00
Kethan
4b0db74770 Fix typo in tutorial.md (#2130) 2021-06-12 23:52:08 -04:00
Dmitry Maluka
3bfd367d87 find: select prefilled text (#2127)
The new feature of prefilling the search bar with the selected text (added
in 3d0b5db) has an annoying side effect: if we do have some text selected
but we want to search for some other pattern, not the selected text,
then we have to manually delete the prefilled text before we can start
entering our wanted search pattern.

A simple solution is to select the prefilled text, so that we can replace it
with our pattern right away just by typing, without any additional keystrokes.
2021-06-09 17:04:11 -04:00
Balló György
6d5beb50ba Add desktop-id to Appstream Metainfo (#2122)
It's needed for tools like appstream-generator to detect the associated desktop file.
2021-06-06 17:53:33 -04:00
Ali Kefia
3d0b5db2e4 find: prefill with selection (#2115)
* find: prefill with selection

* keep search func - could be used in plugins
2021-06-02 16:04:31 -04:00
Jeff Zhao
ee9c78dc86 Improve linter performance (#2083)
Only compute args if we are actually going to use it
2021-06-01 19:34:10 -04:00
Rosetta H&S
b66ec2bf7a Add highlighting for user-defined types (#2107)
* Added highlighting for user-defined types

Provides automatic highlighting of user-defined types ending with either "_t" or "_T", as is seen in editors such as Nano, or within GitHub itself.

* Update cpp.yaml
2021-06-01 19:33:40 -04:00
Héctor M. Monacci
2dc2cabe0e Dont take # as comment when preceded by backslash (#2112)
When escaped with a backslash (e.g., inside a regex) the numeral char, ```#```, shouldn't be interpreted as a beginning of comment.
2021-06-01 19:33:06 -04:00
Zachary Yedidia
56c7744e23 Fix erlang comment syntax 2021-05-31 20:26:32 -04:00
Zachary Yedidia
9bc32d4be9 Update tcell
Fixes #2108
2021-05-24 01:43:11 -04:00
Zachary Yedidia
0b0c99f1f5 Warn for readonly instead of setting option
Fixes #2106
2021-05-19 14:58:00 -04:00
Marduk Bolaños
3d683b27f7 .sbt files also contain Scala code
The Scala Build Tool sbt uses Scala as configuration language.
2020-11-11 09:58:10 +01:00
139 changed files with 1988 additions and 8262 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

1
.gitignore vendored
View File

@@ -15,6 +15,5 @@ benchmark_results*
tools/build-version
tools/build-date
tools/info-plist
tools/bindata
tools/vscode-tests/
*.hdr

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "tools/go-bindata"]
path = tools/go-bindata
url = https://github.com/zyedidia/go-bindata

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,4 +1,4 @@
.PHONY: runtime
.PHONY: runtime build generate build-quick
VERSION = $(shell GOOS=$(shell go env GOHOSTOS) GOARCH=$(shell go env GOHOSTARCH) \
go run tools/build-version.go)
@@ -7,52 +7,35 @@ DATE = $(shell GOOS=$(shell go env GOHOSTOS) GOARCH=$(shell go env GOHOSTARCH) \
go run tools/build-date.go)
ADDITIONAL_GO_LINKER_FLAGS = $(shell GOOS=$(shell go env GOHOSTOS) \
GOARCH=$(shell go env GOHOSTARCH) \
go run tools/info-plist.go "$(VERSION)")
go run tools/info-plist.go "$(shell go env GOOS)" "$(VERSION)")
GOBIN ?= $(shell go env GOPATH)/bin
GOVARS = -X github.com/zyedidia/micro/v2/internal/util.Version=$(VERSION) -X github.com/zyedidia/micro/v2/internal/util.CommitHash=$(HASH) -X 'github.com/zyedidia/micro/v2/internal/util.CompileDate=$(DATE)'
DEBUGVAR = -X github.com/zyedidia/micro/v2/internal/util.Debug=ON
VSCODE_TESTS_BASE_URL = 'https://raw.githubusercontent.com/microsoft/vscode/e6a45f4242ebddb7aa9a229f85555e8a3bd987e2/src/vs/editor/test/common/model/'
# Builds micro after checking dependencies but without updating the runtime
build:
build: generate build-quick
build-quick:
go build -trimpath -ldflags "-s -w $(GOVARS) $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro
build-dbg:
go build -trimpath -ldflags "-s -w $(ADDITIONAL_GO_LINKER_FLAGS) $(DEBUGVAR)" ./cmd/micro
build-tags: fetch-tags
build-tags: fetch-tags generate
go build -trimpath -ldflags "-s -w $(GOVARS) $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro
# Builds micro after building the runtime and checking dependencies
build-all: runtime build
build-all: build
# Builds micro without checking for dependencies
build-quick:
go build -trimpath -ldflags "-s -w $(GOVARS) $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro
# Same as 'build' but installs to $GOBIN afterward
install:
install: generate
go install -ldflags "-s -w $(GOVARS) $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro
# Same as 'build-all' but installs to $GOBIN afterward
install-all: runtime install
# Same as 'build-quick' but installs to $GOBIN afterward
install-quick:
go install -ldflags "-s -w $(GOVARS) $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro
install-all: install
fetch-tags:
git fetch --tags
# Builds the runtime
runtime:
git submodule update --init
rm -f runtime/syntax/*.hdr
go run runtime/syntax/make_headers.go runtime/syntax
go build -o tools/bindata ./tools/go-bindata
tools/bindata -pkg config -nomemcopy -nometadata -o runtime.go runtime/...
mv runtime.go internal/config
gofmt -w internal/config/runtime.go
generate:
GOOS=$(shell go env GOHOSTOS) GOARCH=$(shell go env GOHOSTARCH) go generate ./runtime
testgen:
mkdir -p tools/vscode-tests

View File

@@ -1,6 +1,6 @@
<img alt="micro logo" src="./assets/micro-logo.svg" width="500px"/>
<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)
@@ -25,7 +25,7 @@ You can also check out the website for Micro at https://micro-editor.github.io.
- [Features](#features)
- [Installation](#installation)
- [Prebuilt binaries](#prebuilt-binaries)
- [Prebuilt binaries](#pre-built-binaries)
- [Package Managers](#package-managers)
- [Building from source](#building-from-source)
- [Fully static binary](#fully-static-binary)
@@ -81,17 +81,13 @@ stable version if you install from the prebuilt binaries, Homebrew, or Snap.
A desktop entry file and man page can be found in the [assets/packaging](https://github.com/zyedidia/micro/tree/master/assets/packaging) directory.
### Prebuilt binaries
### Pre-built binaries
All you need to install micro is one file, the binary itself. It's as simple as that!
Pre-built binaries are distributed with [releases](https://github.com/zyedidia/micro/releases).
Download the binary from the [releases](https://github.com/zyedidia/micro/releases) page.
To uninstall micro, simply remove the binary, and the configuration directory at `~/.config/micro`.
### Installation script
There is a script which can install micro for you by downloading the latest prebuilt binary. You can find it at <https://getmic.ro>.
You can easily install micro by running
#### Quick-install script
```bash
curl https://getmic.ro | bash
@@ -99,7 +95,24 @@ curl https://getmic.ro | bash
The script will place the micro binary in the current directory. From there, you can move it to a directory on your path of your choosing (e.g. `sudo mv micro /usr/bin`). See its [GitHub repository](https://github.com/benweissmann/getmic.ro) for more information.
To uninstall micro, simply remove the binary, and the configuration directory at `~/.config/micro`.
#### Eget
With [Eget](https://github.com/zyedidia/eget) installed, you can easily get a pre-built binary:
```
eget zyedidia/micro
```
Use `--tag VERSION` to download a specific tagged version.
```
eget --tag nightly zyedidia/micro # download the nightly version (compiled every day at midnight UTC)
eget --tag v2.0.8 zyedidia/micro # download version 2.0.8 rather than the latest release
```
You can install `micro` by adding `--to /usr/local/bin` to the `eget` command, or move the binary manually to a directory on your `$PATH` after the download completes.
See [Eget](https://github.com/zyedidia/eget) for more information.
### Package managers
@@ -119,18 +132,19 @@ On Linux, you can install micro through [snap](https://snapcraft.io/docs/core/in
snap install micro --classic
```
**Note for Linux:** for interfacing with the local system clipboard, `xclip` or `xsel`
must be installed. Please see the section on [Linux clipboard support](https://github.com/zyedidia/micro#linux-clipboard-support)
further below.
Micro is also available through other package managers on Linux such as apt, dnf, AUR, Nix, and package managers
Micro is also available through other package managers on Linux such dnf, AUR, Nix, and package managers
for other operating systems. These packages are not guaranteed to be up-to-date.
<!-- * `apt install micro` (Ubuntu 20.04 `focal`, and Debian `unstable | testing | buster-backports`). At the moment, this package (2.0.1-1) is outdated and has a known bug where debug mode is enabled. -->
* Linux: Available in distro-specific package managers.
* `apt install micro` (Ubuntu 20.04 `focal`, and Debian `unstable | testing | buster-backports`). At the moment, this package (2.0.1-1) is outdated and has a known bug where debug mode is enabled.
* `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.
* Windows: [Chocolatey](https://chocolatey.org) and [Scoop](https://github.com/lukesampson/scoop).
* `choco install micro`.
@@ -139,12 +153,22 @@ for other operating systems. These packages are not guaranteed to be up-to-date.
* `pkd_add -v micro`.
* NetBSD, macOS, Linux, Illumos, etc. with [pkgsrc](http://www.pkgsrc.org/)-current:
* `pkg_add micro`
* macOS with [MacPorts](https://www.macports.org):
* `sudo port install micro`
**Note for Linux desktop environments:**
For interfacing with the local system clipboard, the following tools need to be installed:
* For X11 `xclip` or `xsel`
* For [Wayland](https://wayland.freedesktop.org/) `wl-clipboard`
Without these tools installed, micro will use an internal clipboard for copy and paste, but it won't be accessible to external applications.
### Building from source
If your operating system does not have a binary release, but does run Go, you can build from source.
Make sure that you have Go version 1.11 or greater and Go modules are enabled.
Make sure that you have Go version 1.16 or greater and Go modules are enabled.
```
git clone https://github.com/zyedidia/micro
@@ -179,14 +203,17 @@ 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>.
### Linux clipboard support
### WSL and Windows Console
On Linux, clipboard support requires:
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.
- On X11, the `xclip` or `xsel` commands (for Ubuntu: `sudo apt install xclip`)
- On Wayland, the `wl-clipboard` command
If you don't have these commands, micro will use an internal clipboard for copy and paste, but it won't work with external applications.
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
@@ -222,7 +249,7 @@ Once you have built the editor, start it by running `micro path/to/file.txt` or
micro also supports creating buffers from `stdin`:
```sh
ifconfig | micro
ip a | micro
```
You can move the cursor around with the arrow keys and mouse.
@@ -246,6 +273,8 @@ view the help files here:
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.
There is also an unofficial Discord, which you can join at https://discord.gg/nhWR6armnR.
## Contributing
If you find any bugs, please report them! I am also happy to accept pull requests from anyone.
@@ -253,6 +282,6 @@ If you find any bugs, please report them! I am also happy to accept pull request
You can use the [GitHub issue tracker](https://github.com/zyedidia/micro/issues)
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).
For a more informal setting to discuss the editor, you can join the [Gitter chat](https://gitter.im/zyedidia/micro) or the [Discord](https://discord.gg/nhWR6armnR). You can also use the [Discussions](https://github.com/zyedidia/micro/discussions) section on Github for a forum-like setting or for Q&A.
Sometimes I am unresponsive, and I apologize! If that happens, please ping me.

104
assets/micro-logo-drop.svg Normal file
View File

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version="1.1"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 304.70001 103.2"
enable-background="new 0 0 960 560"
xml:space="preserve"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="micro-logo-drop.svg"
width="304.70001"
height="103.2"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata
id="metadata21"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs19"><filter
style="color-interpolation-filters:sRGB"
inkscape:label="Blur"
id="filter1040"
x="-0.028037383"
y="-0.10549451"
width="1.0560748"
height="1.210989"><feGaussianBlur
stdDeviation="2 2"
result="blur"
id="feGaussianBlur1038" /></filter></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1043"
id="namedview17"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="2.5161345"
inkscape:cx="158.97401"
inkscape:cy="109.69207"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1"
inkscape:pagecheckerboard="0" /><g
id="g838"
transform="translate(-178,-172.8)"
style="fill:#ffffff;fill-opacity:1;filter:url(#filter1040)"><path
d="m 306.8,213.8 v -2.6 c 1.6,-0.1 2.9,-0.4 4.1,-0.8 1.2,-0.4 2.5,-1 4,-1.8 h 2.3 v 5.2 c 2.4,-1.9 4.2,-3.1 5.5,-3.8 2,-1 4,-1.5 5.8,-1.5 1.3,0 2.5,0.2 3.7,0.7 1.2,0.5 2.2,1 2.9,1.7 0.7,0.7 1.4,1.6 1.9,2.8 2.2,-1.9 4.2,-3.3 6,-4 1.9,-0.8 3.7,-1.2 5.6,-1.2 1.8,0 3.4,0.4 4.8,1.1 1.4,0.8 2.4,1.7 3,2.8 0.6,1.1 0.9,2.8 0.9,5 v 14.4 c 0,1.5 0,2.4 0.1,2.6 0.1,0.4 0.3,0.8 0.7,1.1 0.3,0.4 0.7,0.6 1.2,0.7 0.4,0.1 1.2,0.2 2.4,0.2 h 1 v 2.6 h -15.5 v -2.6 c 1.8,0 2.9,-0.1 3.5,-0.4 0.5,-0.2 0.9,-0.6 1.2,-1.2 0.3,-0.6 0.4,-1.6 0.4,-3.2 v -13.7 c 0,-1.7 -0.2,-2.9 -0.5,-3.6 -0.3,-0.7 -0.9,-1.2 -1.7,-1.7 -0.8,-0.4 -1.8,-0.7 -3,-0.7 -1.5,0 -3,0.4 -4.6,1.2 -2.2,1.1 -3.9,2.3 -5.1,3.6 v 14.8 c 0,1.4 0.1,2.4 0.2,2.8 0.1,0.4 0.4,0.8 0.7,1.1 0.3,0.3 0.7,0.5 1.1,0.6 0.4,0.1 1.5,0.2 3.1,0.2 v 2.6 h -15.3 v -2.6 h 0.9 c 1.2,0 2.1,-0.1 2.6,-0.4 0.5,-0.3 0.9,-0.7 1.2,-1.3 0.2,-0.5 0.3,-1.5 0.3,-2.9 v -13.2 c 0,-1.9 -0.2,-3.3 -0.5,-3.9 -0.3,-0.7 -0.9,-1.3 -1.7,-1.7 -0.8,-0.5 -1.8,-0.7 -3,-0.7 -1.3,0 -2.7,0.3 -4.1,1 -2,1 -3.9,2.2 -5.6,3.8 v 15.9 c 0,1 0.1,1.6 0.4,2.1 0.3,0.4 0.7,0.8 1.2,1.1 0.6,0.3 1.3,0.4 2.3,0.4 h 1.1 v 2.6 h -15.6 v -2.6 h 0.8 c 1.4,0 2.4,-0.1 2.8,-0.3 0.7,-0.3 1.1,-0.8 1.4,-1.5 0.2,-0.4 0.2,-1.3 0.2,-2.9 v -18.1 h -5.1 z"
id="path828"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1" /><path
d="m 366.4,213.7 v -2.6 c 1.7,-0.2 3.2,-0.5 4.3,-0.9 1.2,-0.4 2.5,-1 4,-1.7 h 2.3 v 24.9 c 0,0.9 0.1,1.5 0.4,2 0.2,0.4 0.6,0.8 1,0.9 0.4,0.2 1.3,0.3 2.4,0.3 h 1.5 v 2.6 h -15.9 v -2.6 h 1.3 c 1.4,0 2.3,-0.1 2.8,-0.4 0.5,-0.2 0.8,-0.6 1,-1.1 0.2,-0.5 0.3,-1.5 0.3,-3.2 v -18.3 h -5.4 z m 7.9,-19.2 c 1,0 1.8,0.3 2.5,1 0.7,0.7 1.1,1.5 1.1,2.5 0,1 -0.4,1.8 -1.1,2.5 -0.7,0.7 -1.6,1.1 -2.5,1.1 -1,0 -1.8,-0.4 -2.5,-1.1 -0.7,-0.7 -1.1,-1.6 -1.1,-2.5 0,-1 0.4,-1.8 1.1,-2.5 0.6,-0.6 1.5,-1 2.5,-1 z"
id="path830"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1" /><path
d="m 413.1,230.6 2,1.6 c -3.9,5.2 -8.6,7.8 -14,7.8 -4.2,0 -7.8,-1.5 -10.7,-4.5 -2.9,-3 -4.4,-6.8 -4.4,-11.3 0,-3 0.7,-5.7 2,-8.1 1.3,-2.4 3.2,-4.2 5.6,-5.6 2.4,-1.3 5.2,-2 8.3,-2 3.6,0 6.5,0.9 8.9,2.6 2.4,1.7 3.6,3.5 3.6,5.3 0,1 -0.3,1.7 -0.8,2.2 -0.5,0.5 -1.2,0.8 -1.9,0.8 -0.4,0 -0.7,-0.1 -1.1,-0.3 -0.4,-0.2 -0.7,-0.5 -1.1,-0.9 -0.2,-0.2 -0.5,-0.8 -0.9,-1.7 -0.6,-1.2 -1,-2 -1.3,-2.4 -0.6,-0.8 -1.4,-1.5 -2.4,-2 -0.9,-0.5 -2,-0.7 -3.1,-0.7 -1.8,0 -3.4,0.5 -4.9,1.5 -1.5,1 -2.7,2.4 -3.6,4.3 -0.9,1.9 -1.3,4.2 -1.3,6.8 0,4.1 1.1,7.3 3.3,9.7 1.9,2.1 4.1,3.1 6.7,3.1 1.2,0 2.4,-0.2 3.6,-0.6 1.2,-0.4 2.4,-1 3.5,-1.8 0.9,-0.6 2.2,-1.8 4,-3.8 z"
id="path832"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1" /><path
d="m 418.7,213.7 v -2.6 c 1.5,-0.1 2.8,-0.4 4,-0.8 1.2,-0.4 2.5,-1 4,-1.9 h 2.3 v 5.9 c 1.5,-1.8 3.2,-3.2 5.1,-4.3 1.9,-1.1 3.7,-1.6 5.2,-1.6 1.5,0 2.7,0.4 3.6,1.1 0.9,0.7 1.3,1.6 1.3,2.6 0,0.7 -0.3,1.4 -0.9,2 -0.6,0.6 -1.3,0.9 -2.1,0.9 -0.4,0 -0.7,-0.1 -1,-0.2 -0.3,-0.1 -0.7,-0.3 -1.2,-0.7 -1.1,-0.7 -2.1,-1.1 -2.9,-1.1 -1,0 -2.2,0.4 -3.4,1.3 -1.6,1.1 -2.8,2.2 -3.7,3.3 V 232 c 0,1.2 0.1,2.1 0.2,2.5 0.1,0.4 0.4,0.8 0.7,1.1 0.3,0.3 0.7,0.6 1.1,0.7 0.5,0.1 1.3,0.2 2.4,0.2 h 1 v 2.6 h -16 v -2.6 h 1.3 c 1.3,0 2.1,-0.1 2.5,-0.3 0.5,-0.3 0.9,-0.7 1.2,-1.3 0.3,-0.5 0.4,-1.5 0.4,-3 v -18.3 h -5.1 z"
id="path834"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1" /><path
d="m 462.8,208.5 c 3,0 5.7,0.6 7.9,1.9 2.2,1.3 4,3.1 5.3,5.5 1.3,2.4 1.9,5.2 1.9,8.3 0,3.1 -0.7,5.9 -2,8.3 -1.3,2.4 -3.1,4.3 -5.4,5.5 -2.3,1.3 -5,1.9 -8.1,1.9 -5,0 -8.8,-1.6 -11.3,-4.7 -2.5,-3.1 -3.8,-6.8 -3.8,-11 0,-3.1 0.7,-5.8 2,-8.2 1.3,-2.4 3.1,-4.2 5.5,-5.6 2.4,-1.2 5.1,-1.9 8,-1.9 z m -0.2,3 c -2.4,0 -4.4,0.9 -6,2.8 -2.1,2.3 -3.1,5.7 -3.1,10.1 0,4.3 0.9,7.5 2.6,9.7 1.6,2 3.8,3 6.5,3 1.8,0 3.3,-0.5 4.7,-1.4 1.4,-0.9 2.5,-2.4 3.3,-4.5 0.8,-2 1.3,-4.4 1.3,-7.2 0,-2.7 -0.5,-5.1 -1.4,-7.2 -0.7,-1.7 -1.8,-3 -3.2,-4 -1.3,-0.8 -2.9,-1.3 -4.7,-1.3 z"
id="path836"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1" /></g><g
id="g3"
transform="translate(-178,-172.8)"><path
d="m 306.8,213.8 v -2.6 c 1.6,-0.1 2.9,-0.4 4.1,-0.8 1.2,-0.4 2.5,-1 4,-1.8 h 2.3 v 5.2 c 2.4,-1.9 4.2,-3.1 5.5,-3.8 2,-1 4,-1.5 5.8,-1.5 1.3,0 2.5,0.2 3.7,0.7 1.2,0.5 2.2,1 2.9,1.7 0.7,0.7 1.4,1.6 1.9,2.8 2.2,-1.9 4.2,-3.3 6,-4 1.9,-0.8 3.7,-1.2 5.6,-1.2 1.8,0 3.4,0.4 4.8,1.1 1.4,0.8 2.4,1.7 3,2.8 0.6,1.1 0.9,2.8 0.9,5 v 14.4 c 0,1.5 0,2.4 0.1,2.6 0.1,0.4 0.3,0.8 0.7,1.1 0.3,0.4 0.7,0.6 1.2,0.7 0.4,0.1 1.2,0.2 2.4,0.2 h 1 v 2.6 h -15.5 v -2.6 c 1.8,0 2.9,-0.1 3.5,-0.4 0.5,-0.2 0.9,-0.6 1.2,-1.2 0.3,-0.6 0.4,-1.6 0.4,-3.2 v -13.7 c 0,-1.7 -0.2,-2.9 -0.5,-3.6 -0.3,-0.7 -0.9,-1.2 -1.7,-1.7 -0.8,-0.4 -1.8,-0.7 -3,-0.7 -1.5,0 -3,0.4 -4.6,1.2 -2.2,1.1 -3.9,2.3 -5.1,3.6 v 14.8 c 0,1.4 0.1,2.4 0.2,2.8 0.1,0.4 0.4,0.8 0.7,1.1 0.3,0.3 0.7,0.5 1.1,0.6 0.4,0.1 1.5,0.2 3.1,0.2 v 2.6 h -15.3 v -2.6 h 0.9 c 1.2,0 2.1,-0.1 2.6,-0.4 0.5,-0.3 0.9,-0.7 1.2,-1.3 0.2,-0.5 0.3,-1.5 0.3,-2.9 v -13.2 c 0,-1.9 -0.2,-3.3 -0.5,-3.9 -0.3,-0.7 -0.9,-1.3 -1.7,-1.7 -0.8,-0.5 -1.8,-0.7 -3,-0.7 -1.3,0 -2.7,0.3 -4.1,1 -2,1 -3.9,2.2 -5.6,3.8 v 15.9 c 0,1 0.1,1.6 0.4,2.1 0.3,0.4 0.7,0.8 1.2,1.1 0.6,0.3 1.3,0.4 2.3,0.4 h 1.1 v 2.6 h -15.6 v -2.6 h 0.8 c 1.4,0 2.4,-0.1 2.8,-0.3 0.7,-0.3 1.1,-0.8 1.4,-1.5 0.2,-0.4 0.2,-1.3 0.2,-2.9 v -18.1 h -5.1 z"
id="path5"
inkscape:connector-curvature="0" /><path
d="m 366.4,213.7 v -2.6 c 1.7,-0.2 3.2,-0.5 4.3,-0.9 1.2,-0.4 2.5,-1 4,-1.7 h 2.3 v 24.9 c 0,0.9 0.1,1.5 0.4,2 0.2,0.4 0.6,0.8 1,0.9 0.4,0.2 1.3,0.3 2.4,0.3 h 1.5 v 2.6 h -15.9 v -2.6 h 1.3 c 1.4,0 2.3,-0.1 2.8,-0.4 0.5,-0.2 0.8,-0.6 1,-1.1 0.2,-0.5 0.3,-1.5 0.3,-3.2 v -18.3 h -5.4 z m 7.9,-19.2 c 1,0 1.8,0.3 2.5,1 0.7,0.7 1.1,1.5 1.1,2.5 0,1 -0.4,1.8 -1.1,2.5 -0.7,0.7 -1.6,1.1 -2.5,1.1 -1,0 -1.8,-0.4 -2.5,-1.1 -0.7,-0.7 -1.1,-1.6 -1.1,-2.5 0,-1 0.4,-1.8 1.1,-2.5 0.6,-0.6 1.5,-1 2.5,-1 z"
id="path7"
inkscape:connector-curvature="0" /><path
d="m 413.1,230.6 2,1.6 c -3.9,5.2 -8.6,7.8 -14,7.8 -4.2,0 -7.8,-1.5 -10.7,-4.5 -2.9,-3 -4.4,-6.8 -4.4,-11.3 0,-3 0.7,-5.7 2,-8.1 1.3,-2.4 3.2,-4.2 5.6,-5.6 2.4,-1.3 5.2,-2 8.3,-2 3.6,0 6.5,0.9 8.9,2.6 2.4,1.7 3.6,3.5 3.6,5.3 0,1 -0.3,1.7 -0.8,2.2 -0.5,0.5 -1.2,0.8 -1.9,0.8 -0.4,0 -0.7,-0.1 -1.1,-0.3 -0.4,-0.2 -0.7,-0.5 -1.1,-0.9 -0.2,-0.2 -0.5,-0.8 -0.9,-1.7 -0.6,-1.2 -1,-2 -1.3,-2.4 -0.6,-0.8 -1.4,-1.5 -2.4,-2 -0.9,-0.5 -2,-0.7 -3.1,-0.7 -1.8,0 -3.4,0.5 -4.9,1.5 -1.5,1 -2.7,2.4 -3.6,4.3 -0.9,1.9 -1.3,4.2 -1.3,6.8 0,4.1 1.1,7.3 3.3,9.7 1.9,2.1 4.1,3.1 6.7,3.1 1.2,0 2.4,-0.2 3.6,-0.6 1.2,-0.4 2.4,-1 3.5,-1.8 0.9,-0.6 2.2,-1.8 4,-3.8 z"
id="path9"
inkscape:connector-curvature="0" /><path
d="m 418.7,213.7 v -2.6 c 1.5,-0.1 2.8,-0.4 4,-0.8 1.2,-0.4 2.5,-1 4,-1.9 h 2.3 v 5.9 c 1.5,-1.8 3.2,-3.2 5.1,-4.3 1.9,-1.1 3.7,-1.6 5.2,-1.6 1.5,0 2.7,0.4 3.6,1.1 0.9,0.7 1.3,1.6 1.3,2.6 0,0.7 -0.3,1.4 -0.9,2 -0.6,0.6 -1.3,0.9 -2.1,0.9 -0.4,0 -0.7,-0.1 -1,-0.2 -0.3,-0.1 -0.7,-0.3 -1.2,-0.7 -1.1,-0.7 -2.1,-1.1 -2.9,-1.1 -1,0 -2.2,0.4 -3.4,1.3 -1.6,1.1 -2.8,2.2 -3.7,3.3 V 232 c 0,1.2 0.1,2.1 0.2,2.5 0.1,0.4 0.4,0.8 0.7,1.1 0.3,0.3 0.7,0.6 1.1,0.7 0.5,0.1 1.3,0.2 2.4,0.2 h 1 v 2.6 h -16 v -2.6 h 1.3 c 1.3,0 2.1,-0.1 2.5,-0.3 0.5,-0.3 0.9,-0.7 1.2,-1.3 0.3,-0.5 0.4,-1.5 0.4,-3 v -18.3 h -5.1 z"
id="path11"
inkscape:connector-curvature="0" /><path
d="m 462.8,208.5 c 3,0 5.7,0.6 7.9,1.9 2.2,1.3 4,3.1 5.3,5.5 1.3,2.4 1.9,5.2 1.9,8.3 0,3.1 -0.7,5.9 -2,8.3 -1.3,2.4 -3.1,4.3 -5.4,5.5 -2.3,1.3 -5,1.9 -8.1,1.9 -5,0 -8.8,-1.6 -11.3,-4.7 -2.5,-3.1 -3.8,-6.8 -3.8,-11 0,-3.1 0.7,-5.8 2,-8.2 1.3,-2.4 3.1,-4.2 5.5,-5.6 2.4,-1.2 5.1,-1.9 8,-1.9 z m -0.2,3 c -2.4,0 -4.4,0.9 -6,2.8 -2.1,2.3 -3.1,5.7 -3.1,10.1 0,4.3 0.9,7.5 2.6,9.7 1.6,2 3.8,3 6.5,3 1.8,0 3.3,-0.5 4.7,-1.4 1.4,-0.9 2.5,-2.4 3.3,-4.5 0.8,-2 1.3,-4.4 1.3,-7.2 0,-2.7 -0.5,-5.1 -1.4,-7.2 -0.7,-1.7 -1.8,-3 -3.2,-4 -1.3,-0.8 -2.9,-1.3 -4.7,-1.3 z"
id="path13"
inkscape:connector-curvature="0" /></g><path
d="M 51.6,0 C 23.1,0 0,23.1 0,51.6 c 0,28.5 23.1,51.6 51.6,51.6 28.5,0 51.6,-23.1 51.6,-51.6 C 103.2,23.1 80.1,0 51.6,0 Z m 24.5,58.6 c -0.5,2 -1.3,3.6 -2.4,4.9 -1,1.3 -2,2.1 -3.1,2.5 -1.1,0.4 -2.2,0.6 -3.4,0.6 -1.2,0 -2.2,-0.2 -3,-0.7 C 63.4,65.5 62.8,64.8 62.3,64 61.8,63.2 61.5,62.2 61.3,61.1 61.1,60 61,58.8 61,57.5 c 0,-0.5 0,-1 0.1,-1.7 0.1,-0.7 0.2,-1.6 0.3,-1.6 h -0.2 c -1.6,4 -3.8,6.9 -6.6,9.2 -2.8,2.3 -5.9,3.4 -9.3,3.4 -2.3,0 -4.2,-0.9 -5.5,-2.6 -1.4,-1.7 -2.1,-4.3 -2.1,-7.7 0,-0.5 0,-1 0.1,-1.6 0.1,-0.5 0.1,-0.7 0.2,-1.7 h -0.7 c -0.9,2 -1.7,4.8 -2.3,7.3 -0.6,2.5 -1.1,4.8 -1.4,6.9 -0.4,2.1 -0.6,4 -0.8,5.6 -0.2,1.6 -0.3,2.7 -0.4,3.3 0.1,0.5 0.2,1 0.3,1.6 0.2,0.6 0.3,1.2 0.5,1.7 0.2,0.5 0.3,1.1 0.4,1.6 0.1,0.5 0.2,0.9 0.2,1.2 0,1.4 -0.3,2.5 -0.9,3.2 -0.6,0.7 -1.3,1.1 -2,1.1 -0.9,0 -1.7,-0.3 -2.3,-0.8 -0.7,-0.6 -1,-1.5 -1,-2.7 0,-1.7 0.3,-3.9 0.9,-6.5 0.6,-2.6 1.5,-5.9 2.6,-9.8 0.6,-1.8 1.1,-3.6 1.7,-5.4 0.6,-1.8 1.1,-3.5 1.6,-5 0.5,-1.5 0.9,-2.9 1.3,-4.1 0.4,-1.2 0.6,-2.1 0.7,-2.8 0.1,-0.3 0.2,-1 0.3,-2 0.1,-1 0.2,-2.1 0.4,-3.4 0.2,-1.3 0.3,-2.7 0.5,-4.1 0.2,-1.5 0.4,-2.8 0.5,-4 0.2,-0.9 0.3,-1.9 0.5,-3 0.2,-1.1 0.5,-2.2 0.9,-3.1 0.4,-1 1,-1.8 1.7,-2.5 0.7,-0.7 1.6,-1 2.7,-1 1.2,0 2,0.4 2.4,1.1 0.4,0.7 0.6,1.6 0.5,2.6 -0.1,1 -0.2,2.1 -0.5,3.2 -0.3,1.1 -0.6,2.1 -0.9,2.9 -0.8,2.5 -1.6,4.8 -2.5,6.7 -0.9,1.9 -1.7,4 -2.4,6.2 -0.6,1.5 -0.8,2.9 -0.8,4.1 0,2.2 0.7,3.8 2,5 1.4,1.2 3,1.7 4.9,1.7 1.5,0 3,-0.5 4.4,-1.6 1.4,-1.1 2.7,-2.4 3.9,-3.9 1.2,-1.5 2.2,-3.1 3,-4.9 0.8,-1.7 1.4,-3.3 1.8,-4.6 0.1,-0.2 0.2,-0.6 0.3,-1.4 0.2,-0.8 0.3,-1.7 0.5,-2.7 0.2,-1 0.4,-2 0.6,-3.1 0.2,-1.1 0.4,-2 0.5,-2.7 0.2,-0.8 0.3,-1.6 0.5,-2.6 0.2,-1 0.5,-1.9 0.9,-2.8 0.4,-0.9 1,-1.6 1.6,-2.2 0.7,-0.6 1.5,-0.9 2.6,-0.9 1.3,0 2.1,0.4 2.6,1.1 0.4,0.7 0.6,1.6 0.6,2.6 -0.1,1 -0.2,2 -0.5,3 -0.3,1 -0.5,1.8 -0.7,2.4 -0.8,2.5 -1.6,4.7 -2.4,6.7 -0.8,2 -1.5,3.8 -2.2,5.2 -0.6,1.5 -1.1,2.6 -1.5,3.5 -0.4,0.9 -0.6,1.5 -0.6,1.8 0,2.6 0.6,4.5 1.7,5.6 1.1,1.1 2.3,1.7 3.6,1.7 2.2,0 3.9,-0.7 5.2,-2 1.3,-1.4 2.3,-3.9 2.9,-6.9 h 0.8 c 0.2,2.9 -0.1,5.3 -0.6,7.3 z"
id="path15"
inkscape:connector-curvature="0"
style="fill:#2e3192" /></svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,9 @@
#!/bin/sh
set -e
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]; then
update-alternatives --install /usr/bin/editor editor /usr/bin/micro 40 \
--slave /usr/share/man/man1/editor.1 editor.1 \
/usr/share/man/man1/micro.1
fi

View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
if [ "$1" != "upgrade" ]; then
update-alternatives --remove editor /usr/bin/micro
fi

View File

@@ -23,12 +23,9 @@ func shouldContinue() bool {
return false
}
if len(text) <= 1 {
// default continue
return true
}
text = strings.TrimRight(text, "\r\n")
return strings.ToLower(text)[0] == 'y'
return len(text) == 0 || strings.ToLower(text)[0] == 'y'
}
// CleanConfig performs cleanup in the user's configuration directory

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)
@@ -274,12 +285,6 @@ func main() {
fmt.Println("Fatal: Micro could not initialize a Screen.")
os.Exit(1)
}
sigterm = make(chan os.Signal, 1)
sighup = make(chan os.Signal, 1)
signal.Notify(sigterm, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT)
signal.Notify(sighup, syscall.SIGHUP)
m := clipboard.SetMethod(config.GetGlobalOption("clipboard").(string))
clipErr := clipboard.Initialize(m)
@@ -319,6 +324,8 @@ func main() {
screen.TermMessage(err)
}
action.InitGlobals()
buffer.SetMessager(action.InfoBar)
args := flag.Args()
b := LoadInput(args)
@@ -329,7 +336,6 @@ func main() {
}
action.InitTabs(b)
action.InitGlobals()
err = config.RunPluginFn("init")
if err != nil {
@@ -352,6 +358,11 @@ func main() {
screen.Events = make(chan tcell.Event)
sigterm = make(chan os.Signal, 1)
sighup = make(chan os.Signal, 1)
signal.Notify(sigterm, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT)
signal.Notify(sighup, syscall.SIGHUP)
// Here is the event loop which runs in a separate thread
go func() {
for {

View File

@@ -60,7 +60,6 @@ func startup(args []string) (tcell.SimulationScreen, error) {
}
// Print the stack trace too
log.Fatalf(errors.Wrap(err, 2).ErrorStack())
os.Exit(1)
}
}()
@@ -171,7 +170,6 @@ func TestMain(m *testing.M) {
sim, err = startup([]string{})
if err != nil {
log.Fatalln(err)
os.Exit(1)
}
retval := m.Run()

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<component>
<id>com.github.zyedidia.micro</id>
<launchable type="desktop-id">micro.desktop</launchable>
<name>Micro Text Editor</name>
<summary>A modern and intuitive terminal-based text editor</summary>
<metadata_license>MIT</metadata_license>

15
go.mod
View File

@@ -8,20 +8,17 @@ require (
github.com/mattn/go-isatty v0.0.11
github.com/mattn/go-runewidth v0.0.7
github.com/mitchellh/go-homedir v1.1.0
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff
github.com/sergi/go-diff v1.1.0
github.com/stretchr/testify v1.4.0
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb
github.com/zyedidia/clipboard v1.0.3
github.com/zyedidia/clipper v0.1.1
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3
github.com/zyedidia/highlight v0.0.0-20170330143449-201131ce5cf5
github.com/zyedidia/json5 v0.0.0-20200102012142-2da050b1a98d
github.com/zyedidia/pty v2.0.0+incompatible // indirect
github.com/zyedidia/tcell/v2 v2.0.7
github.com/zyedidia/pty v1.1.20 // indirect
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/sourcemap.v1 v1.0.5 // indirect
gopkg.in/yaml.v2 v2.2.7
gopkg.in/yaml.v2 v2.2.8
layeh.com/gopher-luar v1.0.7
)
@@ -29,4 +26,6 @@ replace github.com/kballard/go-shellquote => github.com/zyedidia/go-shellquote v
replace github.com/mattn/go-runewidth => github.com/zyedidia/go-runewidth v0.0.12
go 1.11
replace layeh.com/gopher-luar => github.com/layeh/gopher-luar v1.0.7
go 1.16

41
go.sum
View File

@@ -17,23 +17,20 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/layeh/gopher-luar v1.0.7 h1:wnfZhYiJM748y1A4qYBfcFeMY9HWbdERny+ZL0f/jWc=
github.com/layeh/gopher-luar v1.0.7/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk=
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/p-e-w/go-runewidth v0.0.10-0.20200613030200-3e1705c5c059 h1:/+h2b6i15wh4EWsFkfdNdBE1jjGA872tpXEyhPM5aYg=
github.com/p-e-w/go-runewidth v0.0.10-0.20200613030200-3e1705c5c059/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff h1:+6NUiITWwE5q1KO6SAfUX918c+Tab0+tGAM/mtdlUyA=
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -42,26 +39,32 @@ github.com/xo/terminfo v0.0.0-20200218205459-454e5b68f9e8/go.mod h1:6Yhx5ZJl5942
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb h1:ZkM6LRnq40pR1Ox0hTHlnpkcOTuFIDQpZ1IN8rKKhX0=
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
github.com/zyedidia/clipboard v1.0.3 h1:F/nCDVYMdbDWTmY8s8cJl0tnwX32q96IF09JHM14bUI=
github.com/zyedidia/clipboard v1.0.3/go.mod h1:zykFnZUXX0ErxqvYLUFEq7QDJKId8rmh2FgD0/Y8cjA=
github.com/zyedidia/clipper v0.0.0-20220613212750-517cd4a6c524 h1:sWYUMHs1EAlsPERKLkaLCxLM0misLylZMEc9Ip5Csjw=
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=
github.com/zyedidia/go-runewidth v0.0.12/go.mod h1:vF8djYdLmG8BJaUZ4CznFYCJ3pFR8m4B4VinTvTTarU=
github.com/zyedidia/go-shellquote v0.0.0-20200613203517-eccd813c0655 h1:Z3RhH6hvcSx7eX6Q/pP6YVsgea/1eMDG99vtWwi3nK4=
github.com/zyedidia/go-shellquote v0.0.0-20200613203517-eccd813c0655/go.mod h1:1sTqqO+kcYzZp43M5VsJe1tns9IzlSeC9jB6c2+o/5Y=
github.com/zyedidia/highlight v0.0.0-20170330143449-201131ce5cf5 h1:Zs6mpwXvlqpF9zHl5XaN0p5V4J9XvP+WBuiuXyIgqvc=
github.com/zyedidia/highlight v0.0.0-20170330143449-201131ce5cf5/go.mod h1:c1r+Ob9tUTPB0FKWO1+x+Hsc/zNa45WdGq7Y38Ybip0=
github.com/zyedidia/json5 v0.0.0-20200102012142-2da050b1a98d h1:zmDMkh22zXOB7gz8jFaI4GpI7llsPgzm38/jG0UgxjE=
github.com/zyedidia/json5 v0.0.0-20200102012142-2da050b1a98d/go.mod h1:NDJSTTYWivnza6zkRapeX2/LwhKPEMQ7bJxqgDVT78I=
github.com/zyedidia/poller v1.0.1 h1:Tt9S3AxAjXwWGNiC2TUdRJkQDZSzCBNVQ4xXiQ7440s=
github.com/zyedidia/poller v1.0.1/go.mod h1:vZXJOHGDcuK08GXhF6IAY0ZFd2WcgOR5DOTp84Uk5eE=
github.com/zyedidia/pty v2.0.0+incompatible h1:Ou5vXL6tvjst+RV8sUFISbuKDnUJPhnpygApMFGweqw=
github.com/zyedidia/pty v2.0.0+incompatible/go.mod h1:4y9l9yJZNxRa7GB/fB+mmDmGkG3CqmzLf4vUxGGotEA=
github.com/zyedidia/tcell/v2 v2.0.6 h1:v0GoNpPYJ+Wbd1RiSL09SUFzoq4eVKTuT5awbW6aqGs=
github.com/zyedidia/tcell/v2 v2.0.6/go.mod h1:i4NNlquIQXFeNecrOgxDQQJdu+7LmTi3g62asvmwUws=
github.com/zyedidia/tcell/v2 v2.0.7 h1:kFzCRq9jgx5lOXBT8fVZidbTgVuX0ws++aMCj/MTCYY=
github.com/zyedidia/tcell/v2 v2.0.7/go.mod h1:i4NNlquIQXFeNecrOgxDQQJdu+7LmTi3g62asvmwUws=
github.com/zyedidia/pty v1.1.15 h1:XlxMFph7HDvTn4sDG8Klgmb/g4ATGiSj4655vAETp1U=
github.com/zyedidia/pty v1.1.15/go.mod h1:HWbpfrLoVM9FmU+/9NV+PzVQV8jSxgnQLk8fvx0q/i8=
github.com/zyedidia/pty v1.1.19 h1:GouvvD/u+uml5EPFUAt5N3rFQKPBmZuuUXHvzAJhVA0=
github.com/zyedidia/pty v1.1.19/go.mod h1:HWbpfrLoVM9FmU+/9NV+PzVQV8jSxgnQLk8fvx0q/i8=
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=
@@ -75,11 +78,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
layeh.com/gopher-luar v1.0.7 h1:53iv6CCkRs5wyofZ+qVXcyAYQOIG52s6pt4xkqZdq7k=
layeh.com/gopher-luar v1.0.7/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -1,6 +1,10 @@
package action
import (
"errors"
"fmt"
"io/fs"
"os"
"regexp"
"runtime"
"strings"
@@ -31,8 +35,8 @@ func (h *BufPane) ScrollDown(n int) {
h.SetView(v)
}
// If the user has scrolled past the last line, ScrollAdjust can be used
// to shift the view so that the last line is at the bottom
// ScrollAdjust can be used to shift the view so that the last line is at the
// bottom if the user has scrolled past the last line.
func (h *BufPane) ScrollAdjust() {
v := h.GetView()
end := h.SLocFromLoc(h.Buf.End())
@@ -787,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
@@ -807,7 +828,7 @@ func (h *BufPane) SaveAs() bool {
func (h *BufPane) saveBufToFile(filename string, action string, callback func()) bool {
err := h.Buf.SaveAs(filename)
if err != nil {
if strings.HasSuffix(err.Error(), "permission denied") {
if errors.Is(err, fs.ErrPermission) {
saveWithSudo := func() {
err = h.Buf.SaveAsWithSudo(filename)
if err != nil {
@@ -824,12 +845,15 @@ func (h *BufPane) saveBufToFile(filename string, action string, callback func())
if h.Buf.Settings["autosu"].(bool) {
saveWithSudo()
} else {
InfoBar.YNPrompt("Permission denied. Do you want to save this file using sudo? (y,n)", func(yes, canceled bool) {
if yes && !canceled {
saveWithSudo()
h.completeAction(action)
}
})
InfoBar.YNPrompt(
fmt.Sprintf("Permission denied. Do you want to save this file using %s? (y,n)", config.GlobalSettings["sucmd"].(string)),
func(yes, canceled bool) {
if yes && !canceled {
saveWithSudo()
h.completeAction(action)
}
},
)
return false
}
} else {
@@ -858,8 +882,10 @@ func (h *BufPane) FindLiteral() bool {
// Search searches for a given string/regex in the buffer and selects the next
// match if a match is found
// This function affects lastSearch and lastSearchRegex (saved searches) for
// use with FindNext and FindPrevious
// This function behaves the same way as Find and FindLiteral actions:
// it affects the buffer's LastSearch and LastSearchRegex (saved searches)
// for use with FindNext and FindPrevious, and turns HighlightSearch on or off
// according to hlsearch setting
func (h *BufPane) Search(str string, useRegex bool, searchDown bool) error {
match, found, err := h.Buf.FindNext(str, h.Buf.Start(), h.Buf.End(), h.Cursor.Loc, searchDown, useRegex)
if err != nil {
@@ -870,10 +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.lastSearch = str
h.lastSearchRegex = useRegex
h.Relocate()
h.GotoLoc(h.Cursor.CurSelection[1])
h.Buf.LastSearch = str
h.Buf.LastSearchRegex = useRegex
h.Buf.HighlightSearch = h.Buf.Settings["hlsearch"].(bool)
} else {
h.Cursor.ResetSelection()
}
@@ -895,15 +921,14 @@ 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()
}
}
InfoBar.Prompt(prompt, "", "Find", eventCallback, func(resp string, canceled bool) {
findCallback := func(resp string, canceled bool) {
// Finished callback
if !canceled {
match, found, err := h.Buf.FindNext(resp, h.Buf.Start(), h.Buf.End(), h.searchOrig, true, useRegex)
@@ -915,9 +940,10 @@ 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.lastSearch = resp
h.lastSearchRegex = useRegex
h.GotoLoc(h.Cursor.CurSelection[1])
h.Buf.LastSearch = resp
h.Buf.LastSearchRegex = useRegex
h.Buf.HighlightSearch = h.Buf.Settings["hlsearch"].(bool)
} else {
h.Cursor.ResetSelection()
InfoBar.Message("No matches found")
@@ -925,9 +951,27 @@ func (h *BufPane) find(useRegex bool) bool {
} else {
h.Cursor.ResetSelection()
}
h.Relocate()
})
}
pattern := string(h.Cursor.GetSelection())
if eventCallback != nil && pattern != "" {
eventCallback(pattern)
}
InfoBar.Prompt(prompt, pattern, "Find", eventCallback, findCallback)
if pattern != "" {
InfoBar.SelectAll()
}
return true
}
// ToggleHighlightSearch toggles highlighting all instances of the last used search term
func (h *BufPane) ToggleHighlightSearch() bool {
h.Buf.HighlightSearch = !h.Buf.HighlightSearch
return true
}
// UnhighlightSearch unhighlights all instances of the last used search term
func (h *BufPane) UnhighlightSearch() bool {
h.Buf.HighlightSearch = false
return true
}
@@ -941,7 +985,7 @@ func (h *BufPane) FindNext() bool {
if h.Cursor.HasSelection() {
searchLoc = h.Cursor.CurSelection[1]
}
match, found, err := h.Buf.FindNext(h.lastSearch, h.Buf.Start(), h.Buf.End(), searchLoc, true, h.lastSearchRegex)
match, found, err := h.Buf.FindNext(h.Buf.LastSearch, h.Buf.Start(), h.Buf.End(), searchLoc, true, h.Buf.LastSearchRegex)
if err != nil {
InfoBar.Error(err)
}
@@ -950,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
}
@@ -968,7 +1011,7 @@ func (h *BufPane) FindPrevious() bool {
if h.Cursor.HasSelection() {
searchLoc = h.Cursor.CurSelection[0]
}
match, found, err := h.Buf.FindNext(h.lastSearch, h.Buf.Start(), h.Buf.End(), searchLoc, false, h.lastSearchRegex)
match, found, err := h.Buf.FindNext(h.Buf.LastSearch, h.Buf.Start(), h.Buf.End(), searchLoc, false, h.Buf.LastSearchRegex)
if err != nil {
InfoBar.Error(err)
}
@@ -977,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
}
@@ -1012,17 +1054,19 @@ func (h *BufPane) Copy() bool {
return true
}
// Copy the current line to the clipboard
// CopyLine copies the current line to the clipboard
func (h *BufPane) CopyLine() bool {
if h.Cursor.HasSelection() {
return false
} else {
h.Cursor.SelectLine()
h.Cursor.CopySelection(clipboard.ClipboardReg)
h.freshClip = true
InfoBar.Message("Copied line")
}
origLoc := h.Cursor.Loc
h.Cursor.SelectLine()
h.Cursor.CopySelection(clipboard.ClipboardReg)
h.freshClip = true
InfoBar.Message("Copied line")
h.Cursor.Deselect(true)
h.Cursor.Loc = origLoc
h.Relocate()
return true
}
@@ -1064,14 +1108,15 @@ func (h *BufPane) Cut() bool {
h.Relocate()
return true
} else {
return h.CutLine()
}
return h.CutLine()
}
// DuplicateLine duplicates the current line or selection
func (h *BufPane) DuplicateLine() bool {
var infoMessage = "Duplicated line"
if h.Cursor.HasSelection() {
infoMessage = "Duplicated selection"
h.Buf.Insert(h.Cursor.CurSelection[1], string(h.Cursor.GetSelection()))
} else {
h.Cursor.End()
@@ -1079,7 +1124,7 @@ func (h *BufPane) DuplicateLine() bool {
// h.Cursor.Right()
}
InfoBar.Message("Duplicated line")
InfoBar.Message(infoMessage)
h.Relocate()
return true
}
@@ -1237,15 +1282,12 @@ func (h *BufPane) JumpToMatchingBrace() bool {
} else {
h.Cursor.GotoLoc(matchingBrace.Move(1, h.Buf))
}
break
} else {
return false
h.Relocate()
return true
}
}
}
h.Relocate()
return true
return false
}
// SelectAll selects the entire buffer
@@ -1625,12 +1667,12 @@ func (h *BufPane) PreviousSplit() bool {
}
var curmacro []interface{}
var recording_macro bool
var recordingMacro bool
// ToggleMacro toggles recording of a macro
func (h *BufPane) ToggleMacro() bool {
recording_macro = !recording_macro
if recording_macro {
recordingMacro = !recordingMacro
if recordingMacro {
curmacro = []interface{}{}
InfoBar.Message("Recording")
} else {
@@ -1642,7 +1684,7 @@ func (h *BufPane) ToggleMacro() bool {
// PlayMacro plays back the most recently recorded macro
func (h *BufPane) PlayMacro() bool {
if recording_macro {
if recordingMacro {
return false
}
for _, action := range curmacro {
@@ -1702,10 +1744,9 @@ func (h *BufPane) SpawnMultiCursor() bool {
func (h *BufPane) SpawnMultiCursorUp() bool {
if h.Cursor.Y == 0 {
return false
} else {
h.Cursor.GotoLoc(buffer.Loc{h.Cursor.X, h.Cursor.Y - 1})
h.Cursor.Relocate()
}
h.Cursor.GotoLoc(buffer.Loc{h.Cursor.X, h.Cursor.Y - 1})
h.Cursor.Relocate()
c := buffer.NewCursor(h.Buf, buffer.Loc{h.Cursor.X, h.Cursor.Y + 1})
h.Buf.AddCursor(c)
@@ -1720,10 +1761,9 @@ func (h *BufPane) SpawnMultiCursorUp() bool {
func (h *BufPane) SpawnMultiCursorDown() bool {
if h.Cursor.Y+1 == h.Buf.LinesNum() {
return false
} else {
h.Cursor.GotoLoc(buffer.Loc{h.Cursor.X, h.Cursor.Y + 1})
h.Cursor.Relocate()
}
h.Cursor.GotoLoc(buffer.Loc{h.Cursor.X, h.Cursor.Y + 1})
h.Cursor.Relocate()
c := buffer.NewCursor(h.Buf, buffer.Loc{h.Cursor.X, h.Cursor.Y - 1})
h.Buf.AddCursor(c)

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,20 +13,27 @@ 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"
)
// BufKeyAction represents an action bound to a key.
type BufKeyAction func(*BufPane) bool
// BufMouseAction is an action that must be bound to a mouse event.
type BufMouseAction func(*BufPane, *tcell.EventMouse) bool
// BufBindings stores the bindings for the buffer pane type.
var BufBindings *KeyTree
// BufKeyActionGeneral makes a general pane action from a BufKeyAction.
func BufKeyActionGeneral(a BufKeyAction) PaneKeyAction {
return func(p Pane) bool {
return a(p.(*BufPane))
}
}
// BufMouseActionGeneral makes a general pane mouse action from a BufKeyAction.
func BufMouseActionGeneral(a BufMouseAction) PaneMouseAction {
return func(p Pane, me *tcell.EventMouse) bool {
return a(p.(*BufPane), me)
@@ -37,6 +44,7 @@ func init() {
BufBindings = NewKeyTree()
}
// LuaAction makes a BufKeyAction from a lua function.
func LuaAction(fn string) func(*BufPane) bool {
luaFn := strings.Split(fn, ".")
if len(luaFn) <= 1 {
@@ -219,9 +227,6 @@ type BufPane struct {
// Same here, just to keep track for mouse move events
tripleClick bool
// Last search stores the last successful search for FindNext and FindPrev
lastSearch string
lastSearchRegex bool
// Should the current multiple cursor selection search based on word or
// based on selection (false for selection, true for word)
multiWord bool
@@ -231,9 +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
}
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
@@ -242,20 +252,47 @@ 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
}
func NewBufPaneFromBuf(buf *buffer.Buffer, tab *Tab) *BufPane {
w := display.NewBufWindow(0, 0, 0, 0, buf)
return NewBufPane(buf, w, tab)
// 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
}
// NewBufPaneFromBuf constructs a new pane from the given buffer and automatically
// creates a buf window.
func NewBufPaneFromBuf(buf *buffer.Buffer, tab *Tab) *BufPane {
w := display.NewBufWindow(0, 0, 0, 0, buf)
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.
func (h *BufPane) SetTab(t *Tab) {
h.tab = t
}
// Tab returns this pane's tab.
func (h *BufPane) Tab() *Tab {
return h.tab
}
@@ -266,9 +303,8 @@ func (h *BufPane) ResizePane(size int) {
h.tab.Resize()
}
// PluginCB calls all plugin callbacks with a certain name and
// displays an error if there is one and returns the aggregrate
// boolean response
// PluginCB calls all plugin callbacks with a certain name and displays an
// error if there is one and returns the aggregrate boolean response
func (h *BufPane) PluginCB(cb string) bool {
b, err := config.RunPluginFnBool(cb, luar.New(ulua.L, h))
if err != nil {
@@ -277,8 +313,7 @@ func (h *BufPane) PluginCB(cb string) bool {
return b
}
// PluginCBRune is the same as PluginCB but also passes a rune to
// the plugins
// PluginCBRune is the same as PluginCB but also passes a rune to the plugins
func (h *BufPane) PluginCBRune(cb string, r rune) bool {
b, err := config.RunPluginFnBool(cb, luar.New(ulua.L, h), luar.New(ulua.L, string(r)))
if err != nil {
@@ -287,30 +322,71 @@ func (h *BufPane) PluginCBRune(cb string, r rune) bool {
return b
}
// OpenBuffer opens the given buffer in this pane.
func (h *BufPane) OpenBuffer(b *buffer.Buffer) {
h.Buf.Close()
h.Buf = b
h.BWindow.SetBuffer(b)
h.Cursor = b.GetActiveCursor()
h.Resize(h.GetView().Width, h.GetView().Height)
h.Relocate()
// Set mouseReleased to true because we assume the mouse is not being pressed when
// the editor is opened
h.initialRelocate()
// Set mouseReleased to true because we assume the mouse is not being
// pressed when the editor is opened
h.mouseReleased = true
// Set isOverwriteMode to false, because we assume we are in the default mode when editor
// is opened
// Set isOverwriteMode to false, because we assume we are in the default
// mode when editor is opened
h.isOverwriteMode = false
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
}
// SetID sets the split ID of this pane.
func (h *BufPane) SetID(i uint64) {
h.splitID = i
}
// Name returns the BufPane's name.
func (h *BufPane) Name() string {
n := h.Buf.GetName()
if h.Buf.Modified() {
@@ -421,6 +497,7 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
}
}
// Bindings returns the current bindings tree for this buffer.
func (h *BufPane) Bindings() *KeyTree {
if h.bindings != nil {
return h.bindings
@@ -455,7 +532,7 @@ func (h *BufPane) execAction(action func(*BufPane) bool, name string, cursor int
success = success && h.PluginCB("on"+name)
if isMulti {
if recording_macro {
if recordingMacro {
if name != "ToggleMacro" && name != "PlayMacro" {
curmacro = append(curmacro, action)
}
@@ -527,7 +604,7 @@ func (h *BufPane) DoRuneInsert(r rune) {
} else {
h.Buf.Insert(c.Loc, string(r))
}
if recording_macro {
if recordingMacro {
curmacro = append(curmacro, r)
}
h.Relocate()
@@ -535,6 +612,7 @@ func (h *BufPane) DoRuneInsert(r rune) {
}
}
// VSplitIndex opens the given buffer in a vertical split on the given side.
func (h *BufPane) VSplitIndex(buf *buffer.Buffer, right bool) *BufPane {
e := NewBufPaneFromBuf(buf, h.tab)
e.splitID = MainTab().GetNode(h.splitID).VSplit(right)
@@ -543,6 +621,8 @@ func (h *BufPane) VSplitIndex(buf *buffer.Buffer, right bool) *BufPane {
MainTab().SetActive(len(MainTab().Panes) - 1)
return e
}
// HSplitIndex opens the given buffer in a horizontal split on the given side.
func (h *BufPane) HSplitIndex(buf *buffer.Buffer, bottom bool) *BufPane {
e := NewBufPaneFromBuf(buf, h.tab)
e.splitID = MainTab().GetNode(h.splitID).HSplit(bottom)
@@ -552,16 +632,22 @@ func (h *BufPane) HSplitIndex(buf *buffer.Buffer, bottom bool) *BufPane {
return e
}
// VSplitBuf opens the given buffer in a new vertical split.
func (h *BufPane) VSplitBuf(buf *buffer.Buffer) *BufPane {
return h.VSplitIndex(buf, h.Buf.Settings["splitright"].(bool))
}
// HSplitBuf opens the given buffer in a new horizontal split.
func (h *BufPane) HSplitBuf(buf *buffer.Buffer) *BufPane {
return h.HSplitIndex(buf, h.Buf.Settings["splitbottom"].(bool))
}
// Close this pane.
func (h *BufPane) Close() {
h.Buf.Close()
}
// SetActive marks this pane as active.
func (h *BufPane) SetActive(b bool) {
h.BWindow.SetActive(b)
if b {
@@ -659,6 +745,8 @@ var BufKeyActions = map[string]BufKeyAction{
"ToggleKeyMenu": (*BufPane).ToggleKeyMenu,
"ToggleDiffGutter": (*BufPane).ToggleDiffGutter,
"ToggleRuler": (*BufPane).ToggleRuler,
"ToggleHighlightSearch": (*BufPane).ToggleHighlightSearch,
"UnhighlightSearch": (*BufPane).UnhighlightSearch,
"ClearStatus": (*BufPane).ClearStatus,
"ShellMode": (*BufPane).ShellMode,
"CommandMode": (*BufPane).CommandMode,

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,9 +833,10 @@ func (h *BufPane) ReplaceCmd(args []string) {
h.Cursor.SetSelectionStart(locs[0])
h.Cursor.SetSelectionEnd(locs[1])
h.Cursor.GotoLoc(locs[0])
h.Relocate()
h.GotoLoc(locs[0])
h.Buf.LastSearch = search
h.Buf.LastSearchRegex = true
h.Buf.HighlightSearch = h.Buf.Settings["hlsearch"].(bool)
InfoBar.YNPrompt("Perform replacement (y,n,esc)", func(yes, canceled bool) {
if !canceled && yes {
@@ -850,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

@@ -38,6 +38,7 @@ var bufdefaults = map[string]string{
"Ctrl-o": "OpenFile",
"Ctrl-s": "Save",
"Ctrl-f": "Find",
"Alt-F": "FindLiteral",
"Ctrl-n": "FindNext",
"Ctrl-p": "FindPrevious",
"Ctrl-z": "Undo",
@@ -86,7 +87,7 @@ var bufdefaults = map[string]string{
"F4": "Quit",
"F7": "Find",
"F10": "Quit",
"Esc": "Escape,Deselect,ClearInfo,RemoveAllMultiCursors",
"Esc": "Escape,Deselect,ClearInfo,RemoveAllMultiCursors,UnhighlightSearch",
// Mouse bindings
"MouseWheelUp": "ScrollUp",

View File

@@ -40,6 +40,7 @@ var bufdefaults = map[string]string{
"Ctrl-o": "OpenFile",
"Ctrl-s": "Save",
"Ctrl-f": "Find",
"Alt-F": "FindLiteral",
"Ctrl-n": "FindNext",
"Ctrl-p": "FindPrevious",
"Ctrl-z": "Undo",
@@ -88,7 +89,7 @@ var bufdefaults = map[string]string{
"F4": "Quit",
"F7": "Find",
"F10": "Quit",
"Esc": "Escape,Deselect,ClearInfo,RemoveAllMultiCursors",
"Esc": "Escape,Deselect,ClearInfo,RemoveAllMultiCursors,UnhighlightSearch",
// Mouse bindings
"MouseWheelUp": "ScrollUp",

View File

@@ -2,7 +2,10 @@ package action
import "github.com/zyedidia/micro/v2/internal/buffer"
// InfoBar is the global info bar.
var InfoBar *InfoPane
// LogBufPane is a global log buffer.
var LogBufPane *BufPane
// InitGlobals initializes the log buffer and the info bar

View File

@@ -93,10 +93,10 @@ func (h *InfoPane) HandleEvent(event tcell.Event) {
done := h.DoKeyEvent(ke)
hasYN := h.HasYN
if e.Key() == tcell.KeyRune && hasYN {
if e.Rune() == 'y' && hasYN {
if (e.Rune() == 'y' || e.Rune() == 'Y') && hasYN {
h.YNResp = true
h.DonePrompt(false)
} else if e.Rune() == 'n' && hasYN {
} else if (e.Rune() == 'n' || e.Rune() == 'N') && hasYN {
h.YNResp = false
h.DonePrompt(false)
}

View File

@@ -229,7 +229,7 @@ func (k *KeyTree) ResetEvents() {
k.cursor.mouseInfo = nil
}
// CurrentEventsStr returns the list of recorded events as a string
// RecordedEventsStr returns the list of recorded events as a string
func (k *KeyTree) RecordedEventsStr() string {
buf := &bytes.Buffer{}
for _, e := range k.cursor.recordedEvents {

View File

@@ -4,6 +4,7 @@ import (
"github.com/zyedidia/micro/v2/internal/display"
)
// A Pane is a general interface for a window in the editor.
type Pane interface {
Handler
display.Window

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

@@ -26,8 +26,9 @@ The backup was created on %s, and the file is
When the buffer is closed, the backup will be removed.
* 'ignore' will ignore the backup, discarding its changes. The backup file
will be removed.
* 'abort' will abort the open operation, and instead open an empty buffer.
Options: [r]ecover, [i]gnore: `
Options: [r]ecover, [i]gnore, [a]bort: `
var backupRequestChan chan *Buffer
@@ -118,7 +119,7 @@ func (b *Buffer) RemoveBackup() {
// ApplyBackup applies the corresponding backup file to this buffer (if one exists)
// Returns true if a backup was applied
func (b *Buffer) ApplyBackup(fsize int64) bool {
func (b *Buffer) ApplyBackup(fsize int64) (bool, bool) {
if b.Settings["backup"].(bool) && !b.Settings["permbackup"].(bool) && len(b.Path) > 0 && b.Type == BTDefault {
backupfile := filepath.Join(config.ConfigDir, "backups", util.EscapePath(b.AbsPath))
if info, err := os.Stat(backupfile); err == nil {
@@ -127,20 +128,22 @@ func (b *Buffer) ApplyBackup(fsize int64) bool {
defer backup.Close()
t := info.ModTime()
msg := fmt.Sprintf(backupMsg, t.Format("Mon Jan _2 at 15:04, 2006"), util.EscapePath(b.AbsPath))
choice := screen.TermPrompt(msg, []string{"r", "i", "recover", "ignore"}, true)
choice := screen.TermPrompt(msg, []string{"r", "i", "a", "recover", "ignore", "abort"}, true)
if choice%2 == 0 {
if choice%3 == 0 {
// recover
b.LineArray = NewLineArray(uint64(fsize), FFAuto, backup)
b.isModified = true
return true
} else if choice%2 == 1 {
return true, true
} else if choice%3 == 1 {
// delete
os.Remove(backupfile)
} else if choice%3 == 2 {
return false, false
}
}
}
}
return false
return false, true
}

View File

@@ -146,18 +146,20 @@ func (b *SharedBuffer) remove(start, end Loc) []byte {
func (b *SharedBuffer) MarkModified(start, end int) {
b.ModifiedThisFrame = true
if !b.Settings["syntax"].(bool) || b.SyntaxDef == nil {
return
}
start = util.Clamp(start, 0, len(b.lines)-1)
end = util.Clamp(end, 0, len(b.lines)-1)
l := -1
for i := start; i <= end; i++ {
l = util.Max(b.Highlighter.ReHighlightStates(b, i), l)
if b.Settings["syntax"].(bool) && b.SyntaxDef != nil {
l := -1
for i := start; i <= end; i++ {
l = util.Max(b.Highlighter.ReHighlightStates(b, i), l)
}
b.Highlighter.HighlightMatches(b, start, l)
}
for i := start; i <= end; i++ {
b.LineArray.invalidateSearchMatches(i)
}
b.Highlighter.HighlightMatches(b, start, l)
}
// DisableReload disables future reloads of this sharedbuffer
@@ -181,6 +183,7 @@ type DiffStatus byte
// The syntax highlighting info must be stored with the buffer because the syntax
// highlighter attaches information to each line of the buffer for optimization
// purposes so it doesn't have to rehighlight everything on every update.
// Likewise for the search highlighting.
type Buffer struct {
*EventHandler
*SharedBuffer
@@ -202,6 +205,12 @@ type Buffer struct {
// This is hacky. Maybe it would be better to move all the visual x logic
// from buffer to display, but it would require rewriting a lot of code.
GetVisualX func(loc Loc) int
// Last search stores the last successful search
LastSearch string
LastSearchRegex bool
// HighlightSearch enables highlighting all instances of the last successful search
HighlightSearch bool
}
// NewBufferFromFileAtLoc opens a new buffer with a given cursor location
@@ -250,10 +259,14 @@ func NewBufferFromFileAtLoc(path string, btype BufType, cursorLoc Loc) (*Buffer,
return nil, err
} else {
buf = NewBuffer(file, util.FSize(file), filename, cursorLoc, btype)
if buf == nil {
return nil, errors.New("could not open file")
}
}
if readonly {
buf.SetOptionNative("readonly", true)
if readonly && prompt != nil {
prompt.Message(fmt.Sprintf("Warning: file is readonly - %s will be attempted when saving", config.GlobalSettings["sucmd"].(string)))
// buf.SetOptionNative("readonly", true)
}
return buf, nil
@@ -283,7 +296,10 @@ func NewBufferFromString(text, path string, btype BufType) *Buffer {
// Places the cursor at startcursor. If startcursor is -1, -1 places the
// cursor at an autodetected location (based on savecursor or :LINE:COL)
func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufType) *Buffer {
absPath, _ := filepath.Abs(path)
absPath, err := filepath.Abs(path)
if err != nil {
absPath = path
}
b := new(Buffer)
@@ -321,7 +337,7 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT
b.Settings[k] = v
}
}
config.InitLocalSettings(settings, path)
config.InitLocalSettings(settings, absPath)
b.Settings["readonly"] = settings["readonly"]
b.Settings["filetype"] = settings["filetype"]
b.Settings["syntax"] = settings["syntax"]
@@ -332,8 +348,12 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT
b.Settings["encoding"] = "utf-8"
}
hasBackup = b.ApplyBackup(size)
var ok bool
hasBackup, ok = b.ApplyBackup(size)
if !ok {
return NewBufferFromString("", "", btype)
}
if !hasBackup {
reader := bufio.NewReader(transform.NewReader(r, enc.NewDecoder()))
@@ -400,7 +420,7 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT
}
}
err := config.RunPluginFn("onBufferOpen", luar.New(ulua.L, b))
err = config.RunPluginFn("onBufferOpen", luar.New(ulua.L, b))
if err != nil {
screen.TermMessage(err)
}
@@ -1191,6 +1211,12 @@ func (b *Buffer) DiffStatus(lineN int) DiffStatus {
return b.diff[lineN]
}
// SearchMatch returns true if the given location is within a match of the last search.
// It is used for search highlighting
func (b *Buffer) SearchMatch(pos Loc) bool {
return b.LineArray.SearchMatch(b, pos)
}
// WriteLog writes a string to the log buffer
func WriteLog(s string) {
LogBuf.EventHandler.Insert(LogBuf.End(), s)

View File

@@ -32,6 +32,15 @@ func runeToByteIndex(n int, txt []byte) int {
return count
}
// A searchState contains the search match info for a single line
type searchState struct {
search string
useRegex bool
ignorecase bool
match [][2]int
done bool
}
// A Line contains the data in bytes as well as a highlight state, match
// and a flag for whether the highlighting needs to be updated
type Line struct {
@@ -41,6 +50,14 @@ type Line struct {
match highlight.LineMatch
rehighlight bool
lock sync.Mutex
// The search states for the line, used for highlighting of search matches,
// separately from the syntax highlighting.
// A map is used because the line array may be shared between multiple buffers
// (multiple instances of the same file opened in different edit panes)
// which have distinct searches, so in the general case there are multiple
// searches per a line, one search per a Buffer containing this line.
search map[*Buffer]*searchState
}
const (
@@ -356,3 +373,79 @@ func (la *LineArray) SetRehighlight(lineN int, on bool) {
defer la.lines[lineN].lock.Unlock()
la.lines[lineN].rehighlight = on
}
// SearchMatch returns true if the location `pos` is within a match
// of the last search for the buffer `b`.
// It is used for efficient highlighting of search matches (separately
// from the syntax highlighting).
// SearchMatch searches for the matches if it is called first time
// for the given line or if the line was modified. Otherwise the
// previously found matches are used.
//
// The buffer `b` needs to be passed because the line array may be shared
// between multiple buffers (multiple instances of the same file opened
// in different edit panes) which have distinct searches, so SearchMatch
// needs to know which search to match against.
func (la *LineArray) SearchMatch(b *Buffer, pos Loc) bool {
if b.LastSearch == "" {
return false
}
lineN := pos.Y
if la.lines[lineN].search == nil {
la.lines[lineN].search = make(map[*Buffer]*searchState)
}
s, ok := la.lines[lineN].search[b]
if !ok {
// Note: here is a small harmless leak: when the buffer `b` is closed,
// `s` is not deleted from the map. It means that the buffer
// will not be garbage-collected until the line array is garbage-collected,
// i.e. until all the buffers sharing this file are closed.
s = new(searchState)
la.lines[lineN].search[b] = s
}
if !ok || s.search != b.LastSearch || s.useRegex != b.LastSearchRegex ||
s.ignorecase != b.Settings["ignorecase"].(bool) {
s.search = b.LastSearch
s.useRegex = b.LastSearchRegex
s.ignorecase = b.Settings["ignorecase"].(bool)
s.done = false
}
if !s.done {
s.match = nil
start := Loc{0, lineN}
end := Loc{util.CharacterCount(la.lines[lineN].data), lineN}
for start.X < end.X {
m, found, _ := b.FindNext(b.LastSearch, start, end, start, true, b.LastSearchRegex)
if !found {
break
}
s.match = append(s.match, [2]int{m[0].X, m[1].X})
start.X = m[1].X
if m[1].X == m[0].X {
start.X = m[1].X + 1
}
}
s.done = true
}
for _, m := range s.match {
if pos.X >= m[0] && pos.X < m[1] {
return true
}
}
return false
}
// invalidateSearchMatches marks search matches for the given line as outdated.
// It is called when the line is modified.
func (la *LineArray) invalidateSearchMatches(lineN int) {
if la.lines[lineN].search != nil {
for _, s := range la.lines[lineN].search {
s.done = false
}
}
}

View File

@@ -82,3 +82,13 @@ func (b *Buffer) ClearMessages(owner string) {
func (b *Buffer) ClearAllMessages() {
b.Messages = make([]*Message, 0)
}
type Messager interface {
Message(msg ...interface{})
}
var prompt Messager
func SetMessager(m Messager) {
prompt = m
}

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

@@ -91,9 +91,10 @@ func (b *Buffer) findUp(r *regexp.Regexp, start, end Loc) ([2]Loc, bool) {
l = util.SliceStart(l, end.X)
}
match := r.FindIndex(l)
allMatches := r.FindAllIndex(l, -1)
if match != nil {
if allMatches != nil {
match := allMatches[len(allMatches)-1]
start := Loc{charpos + util.RunePos(l, match[0]), i}
end := Loc{charpos + util.RunePos(l, match[1]), i}
return [2]Loc{start, end}, true

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) {
@@ -39,6 +49,12 @@ func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error {
b.isModified = true
} else if option == "readonly" && b.Type.Kind == BTDefault.Kind {
b.Type.Readonly = nativeValue.(bool)
} else if option == "hlsearch" {
for _, buf := range OpenBuffers {
if b.SharedBuffer == buf.SharedBuffer {
buf.HighlightSearch = nativeValue.(bool)
}
}
}
if b.OptionCallback != nil {

View File

@@ -3,7 +3,7 @@ package clipboard
import (
"errors"
"github.com/zyedidia/clipboard"
"github.com/zyedidia/clipper"
)
type Method int
@@ -35,12 +35,19 @@ const (
PrimaryReg = -2
)
var clipboard clipper.Clipboard
// Initialize attempts to initialize the clipboard using the given method
func Initialize(m Method) error {
var err error
switch m {
case External:
err = clipboard.Initialize()
clips := make([]clipper.Clipboard, 0, len(clipper.Clipboards)+1)
clips = append(clips, &clipper.Custom{
Name: "micro-clip",
})
clips = append(clips, clipper.Clipboards...)
clipboard, err = clipper.GetClipboard(clips...)
}
if err != nil {
CurrentMethod = Internal
@@ -104,9 +111,11 @@ func read(r Register, m Method) (string, error) {
case External:
switch r {
case ClipboardReg:
return clipboard.ReadAll("clipboard")
b, e := clipboard.ReadAll(clipper.RegClipboard)
return string(b), e
case PrimaryReg:
return clipboard.ReadAll("primary")
b, e := clipboard.ReadAll(clipper.RegPrimary)
return string(b), e
default:
return internal.read(r), nil
}
@@ -132,9 +141,9 @@ func write(text string, r Register, m Method) error {
case External:
switch r {
case ClipboardReg:
return clipboard.WriteAll(text, "clipboard")
return clipboard.WriteAll(clipper.RegClipboard, []byte(text))
case PrimaryReg:
return clipboard.WriteAll(text, "primary")
return clipboard.WriteAll(clipper.RegPrimary, []byte(text))
default:
internal.write(text, r)
}

View File

@@ -9,10 +9,10 @@ import (
"github.com/zyedidia/tcell/v2"
)
// Micro's default style
// DefStyle is Micro's default style
var DefStyle tcell.Style = tcell.StyleDefault
// The current colorscheme
// Colorscheme is the current colorscheme
var Colorscheme map[string]tcell.Style
// GetColor takes in a syntax group and returns the colorscheme's style for that group
@@ -131,15 +131,22 @@ func StringToStyle(str string) tcell.Style {
bg = strings.TrimSpace(bg)
var fgColor, bgColor tcell.Color
if fg == "" {
var ok bool
if fg == "" || fg == "default" {
fgColor, _, _ = DefStyle.Decompose()
} else {
fgColor = StringToColor(fg)
fgColor, ok = StringToColor(fg)
if !ok {
fgColor, _, _ = DefStyle.Decompose()
}
}
if bg == "" {
if bg == "" || bg == "default" {
_, bgColor, _ = DefStyle.Decompose()
} else {
bgColor = StringToColor(bg)
bgColor, ok = StringToColor(bg)
if !ok {
_, bgColor, _ = DefStyle.Decompose()
}
}
style := DefStyle.Foreground(fgColor).Background(bgColor)
@@ -160,49 +167,52 @@ func StringToStyle(str string) tcell.Style {
// StringToColor returns a tcell color from a string representation of a color
// We accept either bright... or light... to mean the brighter version of a color
func StringToColor(str string) tcell.Color {
func StringToColor(str string) (tcell.Color, bool) {
switch str {
case "black":
return tcell.ColorBlack
return tcell.ColorBlack, true
case "red":
return tcell.ColorMaroon
return tcell.ColorMaroon, true
case "green":
return tcell.ColorGreen
return tcell.ColorGreen, true
case "yellow":
return tcell.ColorOlive
return tcell.ColorOlive, true
case "blue":
return tcell.ColorNavy
return tcell.ColorNavy, true
case "magenta":
return tcell.ColorPurple
return tcell.ColorPurple, true
case "cyan":
return tcell.ColorTeal
return tcell.ColorTeal, true
case "white":
return tcell.ColorSilver
return tcell.ColorSilver, true
case "brightblack", "lightblack":
return tcell.ColorGray
return tcell.ColorGray, true
case "brightred", "lightred":
return tcell.ColorRed
return tcell.ColorRed, true
case "brightgreen", "lightgreen":
return tcell.ColorLime
return tcell.ColorLime, true
case "brightyellow", "lightyellow":
return tcell.ColorYellow
return tcell.ColorYellow, true
case "brightblue", "lightblue":
return tcell.ColorBlue
return tcell.ColorBlue, true
case "brightmagenta", "lightmagenta":
return tcell.ColorFuchsia
return tcell.ColorFuchsia, true
case "brightcyan", "lightcyan":
return tcell.ColorAqua
return tcell.ColorAqua, true
case "brightwhite", "lightwhite":
return tcell.ColorWhite
return tcell.ColorWhite, true
case "default":
return tcell.ColorDefault
return tcell.ColorDefault, true
default:
// Check if this is a 256 color
if num, err := strconv.Atoi(str); err == nil {
return GetColor256(num)
return GetColor256(num), true
}
// Probably a truecolor hex value
return tcell.GetColor(str)
// Check if this is a truecolor hex value
if len(str) == 7 && str[0] == '#' {
return tcell.GetColor(str), true
}
return tcell.ColorDefault, false
}
}

View File

@@ -9,6 +9,8 @@ import (
"path/filepath"
"regexp"
"strings"
rt "github.com/zyedidia/micro/v2/runtime"
)
const (
@@ -90,7 +92,7 @@ func (af assetFile) Name() string {
}
func (af assetFile) Data() ([]byte, error) {
return Asset(string(af))
return rt.Asset(string(af))
}
func (nf namedFile) Name() string {
@@ -123,7 +125,7 @@ func AddRuntimeFilesFromDirectory(fileType RTFiletype, directory, pattern string
// AddRuntimeFilesFromAssets registers each file from the given asset-directory for
// the filetype which matches the file-pattern
func AddRuntimeFilesFromAssets(fileType RTFiletype, directory, pattern string) {
files, err := AssetDir(directory)
files, err := rt.AssetDir(directory)
if err != nil {
return
}
@@ -184,8 +186,9 @@ func InitRuntimeFiles() {
isID := regexp.MustCompile(`^[_A-Za-z0-9]+$`).MatchString
for _, d := range files {
if d.IsDir() {
srcs, _ := ioutil.ReadDir(filepath.Join(plugdir, d.Name()))
plugpath := filepath.Join(plugdir, d.Name())
if stat, err := os.Stat(plugpath); err == nil && stat.IsDir() {
srcs, _ := ioutil.ReadDir(plugpath)
p := new(Plugin)
p.Name = d.Name()
p.DirName = d.Name()
@@ -214,9 +217,9 @@ func InitRuntimeFiles() {
}
plugdir = filepath.Join("runtime", "plugins")
if files, err := AssetDir(plugdir); err == nil {
if files, err := rt.AssetDir(plugdir); err == nil {
for _, d := range files {
if srcs, err := AssetDir(filepath.Join(plugdir, d)); err == nil {
if srcs, err := rt.AssetDir(filepath.Join(plugdir, d)); err == nil {
p := new(Plugin)
p.Name = d
p.DirName = d
@@ -225,7 +228,7 @@ func InitRuntimeFiles() {
if strings.HasSuffix(f, ".lua") {
p.Srcs = append(p.Srcs, assetFile(filepath.Join(plugdir, d, f)))
} else if strings.HasSuffix(f, ".json") {
data, err := Asset(filepath.Join(plugdir, d, f))
data, err := rt.Asset(filepath.Join(plugdir, d, f))
if err != nil {
continue
}

File diff suppressed because one or more lines are too long

View File

@@ -51,6 +51,7 @@ var optionValidators = map[string]optionValidator{
"colorcolumn": validateNonNegativeValue,
"fileformat": validateLineEnding,
"encoding": validateEncoding,
"multiopen": validateMultiOpen,
}
func ReadSettings() error {
@@ -269,6 +270,7 @@ var defaultCommonSettings = map[string]interface{}{
"fastdirty": false,
"fileformat": "unix",
"filetype": "unknown",
"hlsearch": false,
"incsearch": true,
"ignorecase": true,
"indentchar": " ",
@@ -329,15 +331,19 @@ var DefaultGlobalOnlySettings = map[string]interface{}{
"colorscheme": "default",
"divchars": "|-",
"divreverse": true,
"fakecursor": false,
"infobar": true,
"keymenu": false,
"mouse": true,
"multiopen": "tab",
"parsecursor": false,
"paste": false,
"savehistory": true,
"sucmd": "sudo",
"pluginchannels": []string{"https://raw.githubusercontent.com/micro-editor/plugin-channel/master/channel.json"},
"pluginrepos": []string{},
"savehistory": true,
"sucmd": "sudo",
"tabhighlight": false,
"tabreverse": true,
"xterm": false,
}
@@ -488,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"
@@ -11,8 +12,7 @@ import (
"github.com/zyedidia/tcell/v2"
)
// The BufWindow provides a way of displaying a certain section
// of a buffer
// The BufWindow provides a way of displaying a certain section of a buffer.
type BufWindow struct {
*View
@@ -44,6 +44,7 @@ func NewBufWindow(x, y, width, height int, buf *buffer.Buffer) *BufWindow {
return w
}
// SetBuffer sets this window's buffer.
func (w *BufWindow) SetBuffer(b *buffer.Buffer) {
w.Buf = b
b.OptionCallback = func(option string, nativeValue interface{}) {
@@ -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()
}
@@ -65,31 +68,30 @@ func (w *BufWindow) SetBuffer(b *buffer.Buffer) {
}
}
// GetView gets the view.
func (w *BufWindow) GetView() *View {
return w.View
}
// GetView sets the view.
func (w *BufWindow) SetView(view *View) {
w.View = view
}
// Resize resizes this window.
func (w *BufWindow) Resize(width, height int) {
w.Width, w.Height = width, height
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.
func (w *BufWindow) SetActive(b bool) {
w.active = b
}
// IsActive returns true if this window is active.
func (w *BufWindow) IsActive() bool {
return w.active
}
@@ -145,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) {
@@ -214,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)) {
@@ -482,10 +492,17 @@ func (w *BufWindow) displayBuffer() {
draw := func(r rune, combc []rune, style tcell.Style, highlight bool, showcursor bool) {
if nColsBeforeStart <= 0 && vloc.Y >= 0 {
if highlight {
if w.Buf.HighlightSearch && w.Buf.SearchMatch(bloc) {
style = config.DefStyle.Reverse(true)
if s, ok := config.Colorscheme["hlsearch"]; ok {
style = s
}
}
_, origBg, _ := style.Decompose()
_, defBg, _ := config.DefStyle.Decompose()
// syntax highlighting with non-default background takes precedence
// syntax or hlsearch highlighting with non-default background takes precedence
// over cursor-line and color-column
dontOverrideBackground := origBg != defBg
@@ -608,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
}
@@ -642,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

@@ -47,6 +47,12 @@ var statusInfo = map[string]func(*buffer.Buffer) string{
}
return ""
},
"lines": func(b *buffer.Buffer) string {
return strconv.Itoa(b.LinesNum())
},
"percentage": func(b *buffer.Buffer) string {
return strconv.Itoa((b.GetActiveCursor().Y + 1) * 100 / b.LinesNum())
},
}
func SetStatusInfoFnLua(fn string) {

View File

@@ -2,6 +2,7 @@ package display
import (
runewidth "github.com/mattn/go-runewidth"
"github.com/zyedidia/tcell/v2"
"github.com/zyedidia/micro/v2/internal/buffer"
"github.com/zyedidia/micro/v2/internal/config"
"github.com/zyedidia/micro/v2/internal/screen"
@@ -94,16 +95,27 @@ func (w *TabWindow) Display() {
x := -w.hscroll
done := false
tabBarStyle := config.DefStyle.Reverse(true)
if style, ok := config.Colorscheme["tabbar"]; ok {
tabBarStyle = style
}
tabBarActiveStyle := tabBarStyle
if style, ok := config.Colorscheme["tabbar.active"]; ok {
tabBarActiveStyle = style
}
globalTabReverse := config.GetGlobalOption("tabreverse").(bool)
globalTabHighlight := config.GetGlobalOption("tabhighlight").(bool)
draw := func(r rune, n int, active bool) {
// xor of reverse and tab highlight to get tab character (as in filename and surrounding characters) reverse state
tabCharHighlight := (globalTabReverse || globalTabHighlight) && !(globalTabReverse && globalTabHighlight)
reverseStyles := func(reverse bool) (tcell.Style, tcell.Style) {
tabBarStyle := config.DefStyle.Reverse(reverse)
if style, ok := config.Colorscheme["tabbar"]; ok {
tabBarStyle = style
}
tabBarActiveStyle := tabBarStyle
if style, ok := config.Colorscheme["tabbar.active"]; ok {
tabBarActiveStyle = style
}
return tabBarStyle, tabBarActiveStyle
}
draw := func(r rune, n int, active bool, reversed bool) {
tabBarStyle, tabBarActiveStyle := reverseStyles(reversed)
style := tabBarStyle
if active {
style = tabBarActiveStyle
@@ -131,28 +143,33 @@ func (w *TabWindow) Display() {
for i, n := range w.Names {
if i == w.active {
draw('[', 1, true)
draw('[', 1, true, tabCharHighlight)
} else {
draw(' ', 1, false)
draw(' ', 1, false, tabCharHighlight)
}
for _, c := range n {
draw(c, 1, i == w.active)
draw(c, 1, i == w.active, tabCharHighlight)
}
if i == len(w.Names)-1 {
done = true
}
if i == w.active {
draw(']', 1, true)
draw(' ', 2, true)
draw(']', 1, true, tabCharHighlight)
draw(' ', 2, true, globalTabReverse)
} else {
draw(' ', 3, false)
draw(' ', 1, false, tabCharHighlight)
draw(' ', 2, false, globalTabReverse)
}
if x >= w.Width {
break
}
}
if x < w.Width {
draw(' ', w.Width-x, false)
draw(' ', w.Width-x, false, globalTabReverse)
}
}

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"
@@ -25,7 +26,7 @@ var (
// Version is the version number or commit hash
Version = "0.0.0-unknown"
// Semantic version
// SemVersion is the Semantic version
SemVersion semver.Version
// CommitHash is the commit this version was built on
CommitHash = "Unknown"
@@ -421,14 +422,17 @@ func Clamp(val, min, max int) int {
return val
}
// IsNonAlphaNumeric returns if the rune is not a number of letter or underscore.
func IsNonAlphaNumeric(c rune) bool {
return !unicode.IsLetter(c) && !unicode.IsNumber(c) && c != '_'
}
// IsAutocomplete returns whether a character should begin an autocompletion.
func IsAutocomplete(c rune) bool {
return c == '.' || !IsNonAlphaNumeric(c)
}
// ParseSpecial replaces escaped ts with '\t'.
func ParseSpecial(s string) string {
return strings.ReplaceAll(s, "\\t", "\t")
}
@@ -490,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

@@ -67,6 +67,7 @@ func combineLineMatch(src, dst LineMatch) LineMatch {
// A State represents the region at the end of a line
type State *region
// EmptyDef is an empty definition.
var EmptyDef = Def{nil, &rules{}}
// LineStates is an interface for a buffer-like object which can also store the states and matches for every line

View File

@@ -11,6 +11,7 @@ color-link special "#A6E22E,#1D1F21"
color-link underlined "#D33682,#1D1F21"
color-link error "bold #FF4444,#1D1F21"
color-link todo "bold #FF8844,#1D1F21"
color-link hlsearch "#000000,#B4EC85"
color-link statusline "#1D1F21,#C5C8C6"
color-link tabbar "#1D1F21,#C5C8C6"
color-link indent-char "#505050,#1D1F21"

View File

@@ -12,6 +12,7 @@ color-link special "167,231"
color-link error "231, 160"
color-link underlined "underline 241,231"
color-link todo "246,231"
color-link hlsearch "231,136"
color-link statusline "241,254"
color-link tabbar "241,254"
color-link diff-added "34"

View File

@@ -26,6 +26,7 @@ color-link special "magenta"
color-link ignore "default"
color-link error "bold ,brightred"
color-link todo "underline black,brightyellow"
color-link hlsearch "white,darkgreen"
color-link indent-char ",brightgreen"
color-link line-number "green"
color-link line-number.scrollbar "green"

View File

@@ -21,6 +21,7 @@ color-link special "#b57edc"
color-link ignore "default"
color-link error "bold ,#e34234"
color-link todo "bold underline #888888,#f26522"
color-link hlsearch "#b7b7b7,#32593d"
color-link indent-char ",#bdecb6"
color-link line-number "#bdecb6,#36393e"
color-link line-number.scrollbar "#3eb489"

View File

@@ -12,6 +12,7 @@ color-link special "#CC8242,#242424"
color-link underlined "#D33682,#242424"
color-link error "bold #CB4B16,#242424"
color-link todo "bold #D33682,#242424"
color-link hlsearch "#CCCCCC,#32593D"
color-link statusline "#242424,#CCCCCC"
color-link tabbar "#242424,#CCCCCC"
color-link indent-char "#4F4F4F,#242424"

View File

@@ -12,6 +12,7 @@ color-link special "#A6E22E,#282828"
color-link underlined "#D33682,#282828"
color-link error "bold #CB4B16,#282828"
color-link todo "bold #D33682,#282828"
color-link hlsearch "#282828,#E6DB74"
color-link statusline "#282828,#F8F8F2"
color-link tabbar "#282828,#F8F8F2"
color-link indent-char "#505050,#282828"

View File

@@ -24,6 +24,8 @@ color-link underlined "#FF79C6"
color-link error "bold #FF5555"
color-link todo "bold #FF79C6"
color-link hlsearch "#282A36,#50FA7B"
color-link diff-added "#50FA7B"
color-link diff-modified "#FFB86C"
color-link diff-deleted "#FF5555"

View File

@@ -15,6 +15,7 @@ color-link divider "#001e28,#d0d0d0"
color-link error "#cb4b16,#001e28"
color-link gutter-error "#cb4b16,#001e28"
color-link gutter-warning "#fce94f,#001e28"
color-link hlsearch "#ffffff,#005028"
color-link identifier "#00c8a0,#001e28"
color-link identifier.class "#00c8a0,#001e28"
color-link indent-char "#a0a0a0,#001e28"

View File

@@ -15,6 +15,7 @@ color-link divider "#f0f0f0,#004080"
color-link error "#500000,#f0f0f0"
color-link gutter-error "#500000,#f0f0f0"
color-link gutter-warning "#dcc800,#f0f0f0"
color-link hlsearch "#000000,#b8d8e8"
color-link identifier "bold #0078a0,#f0f0f0"
color-link identifier.class "bold #0078a0,#f0f0f0"
color-link indent-char "#404040,#f0f0f0"

View File

@@ -15,6 +15,7 @@ color-link divider "#2d0023,#d0d0d0"
color-link error "#cb4b16,#2d0023"
color-link gutter-error "#cb4b16,#2d0023"
color-link gutter-warning "#fce94f,#2d0023"
color-link hlsearch "#ffffff,#005028"
color-link identifier "#00c8a0,#2d0023"
color-link identifier.class "#00c8a0,#2d0023"
color-link indent-char "#a0a0a0,#2d0023"

View File

@@ -12,6 +12,7 @@ color-link type "blue"
color-link type.extended "default"
color-link error "red"
color-link todo "bold cyan"
color-link hlsearch "black,brightcyan"
color-link indent-char "bold black"
color-link line-number ""
color-link current-line-number ""

View File

@@ -11,6 +11,7 @@ color-link special "#D26937,#0C1014"
color-link underlined "#EDB443,#0C1014"
color-link error "bold #C23127,#0C1014"
color-link todo "bold #888CA6,#0C1014"
color-link hlsearch "#091F2E,#EDB443"
color-link statusline "#091F2E,#599CAB"
color-link indent-char "#505050,#0C1014"
color-link line-number "#245361,#11151C"

View File

@@ -9,8 +9,10 @@ color-link statement "#fb4934,#282828"
color-link preproc "#fb4934,235"
color-link type "#fb4934,#282828"
color-link special "#d79921,#282828"
color-link underlined "underline #282828"
color-link underlined "underline #458588,#282828"
color-link error "#9d0006,#282828"
color-link todo "bold #ebdbb2,#282828"
color-link hlsearch "#282828,#fabd2f"
color-link diff-added "#00AF00"
color-link diff-modified "#FFAF00"
color-link diff-deleted "#D70000"

View File

@@ -11,6 +11,7 @@ color-link special "172,235"
color-link underlined "underline 109,235"
color-link error "235,124"
color-link todo "bold 223,235"
color-link hlsearch "235,214"
color-link diff-added "34"
color-link diff-modified "214"
color-link diff-deleted "160"

View File

@@ -14,6 +14,7 @@ color-link divider "#263238,#80DEEA"
color-link error "bold #263238,#F07178"
color-link gutter-error "#EEFFFF,#F07178"
color-link gutter-warning "#EEFFFF,#FFF176"
color-link hlsearch "#FFFFFF,#546E7A"
color-link identifier "#82AAFF,#263238"
color-link identifier.macro "#FFCB6B,#263238"
color-link indent-char "#505050,#263238"

View File

@@ -11,6 +11,7 @@ color-link special "#A6E22E"
color-link underlined "#D33682"
color-link error "bold #CB4B16"
color-link todo "bold #D33682"
color-link hlsearch "#1D0000,#E6DB74"
color-link statusline "#282828,#F8F8F2"
color-link indent-char "#505050,#282828"
color-link line-number "#AAAAAA,#282828"

View File

@@ -12,6 +12,7 @@ color-link special "#A6E22E,#282828"
color-link underlined "#D33682,#282828"
color-link error "bold #CB4B16,#282828"
color-link todo "bold #D33682,#282828"
color-link hlsearch "#282828,#E6DB74"
color-link statusline "#282828,#F8F8F2"
color-link tabbar "#282828,#F8F8F2"
color-link indent-char "#505050,#282828"

View File

@@ -15,6 +15,7 @@ color-link diff-modified "#FFAF00"
color-link diff-deleted "#D70000"
color-link gutter-error "#9B859D"
color-link gutter-warning "#9B859D"
color-link hlsearch "#21252C,#E5C07B"
color-link identifier "#61AFEF"
color-link identifier.class "#C678DD"
color-link identifier.var "#C678DD"

View File

@@ -11,6 +11,7 @@ color-link underlined "#cc7833,#2b2b2b"
color-link todo "bold #cc7833,#2b2b2b"
color-link error "bold #cc7833,#2b2b2b"
color-link gutter-error "#cc7833,#11151C"
color-link hlsearch "#e6e1dc,#474d5c"
color-link indent-char "#414141,#2b2b2b"
color-link line-number "#a1a1a1,#232323"
color-link current-line-number "#e6e1dc,#2b2b2b"

View File

@@ -9,6 +9,7 @@ color-link special "magenta"
color-link ignore "default"
color-link error ",brightred"
color-link todo ",brightyellow"
color-link hlsearch "black,yellow"
color-link indent-char "black"
color-link line-number "yellow"
color-link current-line-number "red"

View File

@@ -11,6 +11,7 @@ color-link special "#268BD2,#002833"
color-link underlined "#D33682,#002833"
color-link error "bold #CB4B16,#002833"
color-link todo "bold #D33682,#002833"
color-link hlsearch "#002833,#B58900"
color-link statusline "#003541,#839496"
color-link tabbar "#003541,#839496"
color-link indent-char "#003541,#002833"

View File

@@ -10,6 +10,7 @@ color-link special "blue"
color-link underlined "magenta"
color-link error "bold brightred"
color-link todo "bold magenta"
color-link hlsearch "black,yellow"
color-link statusline "black,brightblue"
color-link tabbar "black,brightblue"
color-link indent-char "black"

View File

@@ -11,6 +11,7 @@ color-link special "22"
color-link underlined "61,230"
color-link error "88"
color-link todo "210"
color-link hlsearch "0,253"
color-link statusline "233,229"
color-link tabbar "233,229"
color-link indent-char "229"

View File

@@ -15,6 +15,7 @@ color-link diff-modified "#FFAF00"
color-link diff-deleted "#D70000"
color-link gutter-error "#9B859D"
color-link gutter-warning "#9B859D"
color-link hlsearch "#141414,#C0C000"
color-link identifier "#9B703F"
color-link identifier.class "#DAD085"
color-link identifier.var "#7587A6"

View File

@@ -12,6 +12,7 @@ color-link special "181,237"
color-link underlined "188,237"
color-link error "115,236"
color-link todo "bold 254,237"
color-link hlsearch "230,22"
color-link statusline "186,236"
color-link tabbar "186,236"
color-link indent-char "238,237"

View File

@@ -52,7 +52,7 @@ color support comes in three flavors.
environment variable `MICRO_TRUECOLOR` to 1. In addition your terminal
must support it (usually indicated by setting `$COLORTERM` to `truecolor`).
True-color colorschemes in micro typically end with `-tc`, such as
`solarized-tc`, `atom-dark-tc`, `material-tc`, etc... If true color is not
`solarized-tc`, `atom-dark`, `material-tc`, etc... If true color is not
enabled but a true color colorscheme is used, micro will do its best to
approximate the colors to the available 256 colors.
@@ -69,7 +69,7 @@ themes the most.
* `darcula`
* `twilight`
* `railscast`
* `bubblegum`
* `bubblegum` (light theme)
### 16 color
@@ -91,11 +91,10 @@ variable `MICRO_TRUECOLOR` must be set to 1. Note that you have to create
and set this variable yourself.
* `solarized-tc`: this is the solarized colorscheme for true color.
* `atom-dark-tc`: this colorscheme is based off of Atom's "dark" colorscheme.
* `atom-dark`: this colorscheme is based off of Atom's "dark" colorscheme.
* `cmc-tc`: A true colour variant of the cmc theme. It requires true color to
look its best. Use cmc-16 if your terminal doesn't support true color.
* `gruvbox-tc`: The true color version of the gruvbox colorscheme
* `github-tc`: The true color version of the Github colorscheme
* `material-tc`: Colorscheme based off of Google's Material Design palette
## Creating a Colorscheme

View File

@@ -22,13 +22,19 @@ quotes here but these are not necessary when entering the command in micro.
`key` that already exist.
* `help 'topic'?`: opens the corresponding help topic. If no topic is provided
opens the default help screen.
opens the default help screen. Help topics are stored as `.md` files in the
`runtime/help` directory of the source tree, which is embedded in the final
binary.
* `save 'filename'?`: saves the current buffer. If the file is provided it
will 'save as' the filename.
* `quit`: quits micro.
* `goto 'line'`: jumps to the given line number. A negative number can be
passed to jump inward from the end of the file; for example, -5 jumps
to the 5th-last line in the file.
* `replace 'search' 'value' 'flags'?`: This will replace `search` with `value`.
The `flags` are optional. Possible flags are:
* `-a`: Replace all occurrences at once

View File

@@ -31,6 +31,10 @@ Here is a list of terminal emulators and their status:
* `gnome-terminal`: does not support OSC 52.
* `alacritty`: supported.
* `foot`: supported.
**Summary:** If you want copy and paste to work over SSH, then you
should set `clipboard` to `terminal`, and make sure your terminal
supports OSC 52.

View File

@@ -23,7 +23,7 @@ can change it!
| Shift-arrows | Move and select text |
| Alt(Ctrl on Mac)-LeftArrow | Move to the beginning of the current line |
| Alt(Ctrl on Mac)-RightArrow | Move to the end of the current line |
| Home | Move to the beginning of text on the current line |
| Home | Move to the beginning of text on the current line |
| End | Move to the end of the current line |
| Ctrl(Alt on Mac)-LeftArrow | Move cursor one word left |
| Ctrl(Alt on Mac)-RightArrow | Move cursor one word right |
@@ -39,7 +39,7 @@ can change it!
### Tabs
| Key | Description of function |
|-------- |------------------------- |
|-------- |-------------------------- |
| Ctrl-t | Open a new tab |
| Alt-, | Previous tab |
| Alt-. | Next tab |
@@ -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 |
@@ -83,6 +87,8 @@ can change it!
| Alt-DownArrow | Move current line or selected lines down |
| Alt-Backspace or Alt-Ctrl-h | Delete word left |
| Ctrl-a | Select all |
| Tab | Indent selected text |
| Shift-Tab | Unindent selected text |
### Macros

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

@@ -14,8 +14,8 @@ at the end of this document).
If `~/.config/micro/bindings.json` does not exist, you can simply create it.
Micro will know what to do with it.
You can use the alt keys + arrows to move word by word. Ctrl left and right
move the cursor to the start and end of the line, and ctrl up and down move the
You can use Ctrl + arrows to move word by word (Alt + arrows for Mac). Alt + left and right
move the cursor to the start and end of the line (Ctrl + left/right for Mac), and Ctrl + up and down move the
cursor the start and end of the buffer.
You can hold shift with all of these movement actions to select while moving.
@@ -70,7 +70,7 @@ will execute `InsertTab`.
## Binding commands
You can also bind a key to execute a command in command mode (see
You can also bind a key to execute a command in command mode (see
`help commands`). Simply prepend the binding with `command:`. For example:
```json
@@ -88,9 +88,9 @@ instead insert unicode characters. To fix this, do the following:
Now when you press `Alt-p` the `pwd` command will be executed which will show
your working directory in the infobar.
You can also bind an "editable" command with `command-edit:`. This means that
You can also bind an "editable" command with `command-edit:`. This means that
micro won't immediately execute the command when you press the binding, but
instead just place the string in the infobar in command mode. For example,
instead just place the string in the infobar in command mode. For example,
you could rebind `Ctrl-g` to `> help`:
```json
@@ -105,13 +105,13 @@ cursor placement).
## Binding raw escape sequences
Only read this section if you are interested in binding keys that aren't on the
Only read this section if you are interested in binding keys that aren't on the
list of supported keys for binding.
One of the drawbacks of using a terminal-based editor is that the editor must
get all of its information about key events through the terminal. The terminal
sends these events in the form of escape sequences often (but not always)
starting with `0x1b`.
starting with `0x1b`.
For example, if micro reads `\x1b[1;5D`, on most terminals this will mean the
user pressed CtrlLeft.
@@ -149,7 +149,7 @@ Coming soon!
## Unbinding keys
It is also possible to disable any of the default key bindings by use of the
It is also possible to disable any of the default key bindings by use of the
`None` action in the user's `bindings.json` file.
## Bindable actions and bindable keys
@@ -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",
@@ -642,7 +643,7 @@ Note: On some old terminal emulators and on Windows machines, `Ctrl-h` should be
used for backspace.
Additionally, alt keys can be bound by using `Alt-key`. For example `Alt-a` or
`Alt-Up`. Micro supports an optional `-` between modifiers like `Alt` and
`Alt-Up`. Micro supports an optional `-` between modifiers like `Alt` and
`Ctrl` so `Alt-a` could be rewritten as `Alta` (case matters for alt bindings).
This is why in the default keybindings you can see `AltShiftLeft` instead of
`Alt-ShiftLeft` (they are equivalent).

View File

@@ -89,8 +89,8 @@ Here are the available options:
binary.
The colorscheme can be selected from all the files in the
~/.config/micro/colorschemes/ directory. Micro comes by default with three
colorschemes:
~/.config/micro/colorschemes/ directory. Micro comes by default with
three colorschemes:
You can read more about micro's colorschemes in the `colors` help topic
(`help colors`).
@@ -159,6 +159,15 @@ Here are the available options:
default value: `unknown`. This will be automatically overridden depending
on the file you open.
* `hlsearch`: highlight all instances of the searched text after a successful
search. This highlighting can be temporarily turned off via the
`UnhighlightSearch` action (triggered by the Esc key by default) or toggled
on/off via the `ToggleHighlightSearch` action. Note that these actions don't
change the `hlsearch` setting. As long as `hlsearch` is set to true, the next
search will have the highlighting turned on again.
default value: `false`
* `incsearch`: enable incremental search in "Find" prompt (matching as you type).
default value: `true`
@@ -167,7 +176,12 @@ Here are the available options:
default value: `true`
* `indentchar`: sets the indentation character.
* `indentchar`: sets the indentation character. This will not be inserted into
files; it is only a visual indicator that whitespace is present. If set to a
printing character, it functions as a subset of the "show invisibles"
setting available in many other text editors. The color of this character is
determined by the `indent-char` field in the current theme rather than the
default text color.
default value: ` ` (space)
@@ -209,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
@@ -224,7 +247,7 @@ Here are the available options:
given line and column 0. Note that with this option enabled it is not possible
to open a file such as `file.txt:10:5`, where `:10:5` is part of the filename.
It is also possible to open a file with a certain cursor location by using the
`+LINE,COL` flag syntax. See `micro -help` for the command line options.
`+LINE:COL` flag syntax. See `micro -help` for the command line options.
default value: `false`
@@ -253,7 +276,7 @@ Here are the available options:
default value: `false`
* `rmtrailingws`: micro will automatically trim trailing whitespaces at ends of
lines.
lines. Note: This setting overrides `keepautoindent`
default value: `false`
@@ -261,9 +284,9 @@ Here are the available options:
default value: `true`
* `relativeruler`: make line numbers display relatively. If set to true, all lines except
for the line that the cursor is located will display the distance from the
cursor's line.
* `relativeruler`: make line numbers display relatively. If set to true, all
lines except for the line that the cursor is located will display the distance
from the cursor's line.
default value: `false`
@@ -319,7 +342,8 @@ Here are the available options:
* `statusformatl`: format string definition for the left-justified part of the
statusline. Special directives should be placed inside `$()`. Special
directives include: `filename`, `modified`, `line`, `col`, `opt`, `bind`.
directives include: `filename`, `modified`, `line`, `col`, `lines`,
`percentage`, `opt`, `bind`.
The `opt` and `bind` directives take either an option or an action afterward
and fill in the value of the option or the key bound to the action.
@@ -351,11 +375,24 @@ Here are the available options:
default value: `false`
* `tabhighlight`: inverts the tab characters' (filename, save indicator, etc)
colors with respect to the tab bar.
default value: false
* `tabreverse`: reverses the tab bar colors when active.
default value: true
* `tabsize`: the size in spaces that a tab character should be displayed with.
default value: `4`
* `tabstospaces`: use spaces instead of tabs.
* `tabstospaces`: use spaces instead of tabs. Note: This option will be
overridden by [the `ftoptions` plugin](https://github.com/zyedidia/micro/blob/master/runtime/plugins/ftoptions/ftoptions.lua)
for certain filetypes. To disable this behavior, add `"ftoptions": false` to
your config. See [issue #2213](https://github.com/zyedidia/micro/issues/2213)
for more details.
default value: `false`
@@ -434,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,
@@ -473,6 +510,8 @@ so that you can see what the formatting should look like.
"sucmd": "sudo",
"syntax": true,
"tabmovement": false,
"tabhighlight": true,
"tabreverse": false,
"tabsize": 4,
"tabstospaces": false,
"useprimary": true,

View File

@@ -3,9 +3,9 @@
Micro supports creating plugins with a simple Lua system. Plugins are
folders containing Lua files and possibly other source files placed
in `~/.config/micro/plug`. The plugin directory (within `plug`) should
contain at least one Lua file and an `info.json` file. The info file
contain at least one Lua file and a `repo.json` file. The `repo.json` file
provides additional information such as the name of the plugin, the
plugin's website, dependencies, etc... Here is an example info file
plugin's website, dependencies, etc... [Here is an example `repo.json` file](https://github.com/micro-editor/updated-plugins/blob/master/go-plugin/repo.json)
from the go plugin, which has the following file structure:
```
@@ -17,7 +17,7 @@ from the go plugin, which has the following file structure:
```
The `go.lua` file contains the main code for the plugin, though the
code may be distributed across multiple Lua files. The `info.json`
code may be distributed across multiple Lua files. The `repo.json`
file contains information about the plugin such as the website,
description, version, and any requirements. Plugins may also
have additional files which can be added to micro's runtime files,
@@ -287,16 +287,17 @@ 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
public methods of an object returned by any of the functions above.
Unfortunately it is not possible to list all the available functions on this
page. Please go to the internal documentation at
https://godoc.org/github.com/zyedidia/micro to see the full list of available
methods. Note that only methods of types that are available to plugins via
the functions above can be called from a plugin. For an even more detailed
reference see the source code on Github.
https://pkg.go.dev/github.com/zyedidia/micro/v2/internal to see the full list
of available methods. Note that only methods of types that are available to
plugins via the functions above can be called from a plugin. For an even more
detailed reference see the source code on Github.
For example, with a BufPane object called `bp`, you could call the `Save`
function in Lua with `bp:Save()`.
@@ -401,7 +402,7 @@ There are 6 default plugins that come pre-installed with micro. These are
* `autoclose`: automatically closes brackets, quotes, etc...
* `comment`: provides automatic commenting for a number of languages
* `ftoptions`: alters some default options depending on the filetype
* `ftoptions`: alters some default options (notably indentation) depending on the filetype
* `linter`: provides extensible linting for many languages
* `literate`: provides advanced syntax highlighting for the Literate
programming tool.

View File

@@ -53,7 +53,7 @@ following in `bindings.json`:
```json
{
"Ctrl-r": "redo"
"Ctrl-r": "Redo"
}
```

View File

@@ -60,32 +60,42 @@ ft["zig"] = "// %s"
ft["zscript"] = "// %s"
ft["zsh"] = "# %s"
function onBufferOpen(buf)
if buf.Settings["commenttype"] == nil then
local last_ft
function updateCommentType(buf)
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)
local commentType = bp.Buf.Settings["commenttype"]
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
@@ -100,11 +110,16 @@ function commentLine(bp, lineN)
end
function uncommentLine(bp, lineN, commentRegex)
updateCommentType(bp.Buf)
local line = bp.Buf:Line(lineN)
local commentType = bp.Buf.Settings["commenttype"]
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)
@@ -126,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
@@ -139,18 +154,31 @@ 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
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
@@ -171,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

@@ -5,24 +5,24 @@ and parses the resulting output so that the messages and line numbers
can be viewed from within micro. By default, the plugin supports the
following filetypes and linters:
* c: gcc
* c++: g++
* d: dmd
* go: go build
* haskell: hlint
* java: javac
* javascript: jshint
* javascript: eslint
* literate: lit
* lua: luacheck
* nim: nim
* objective-c: clang
* python: pyflakes
* python: mypy
* python: pylint
* shell: shfmt
* swift: swiftc (MacOS and Linux only)
* yaml: yamllint
* **c**: gcc
* **c++**: g++
* **d**: dmd
* **go**: go build
* **haskell**: hlint
* **java**: javac
* **javascript**: jshint
* **javascript**: eslint
* **literate**: lit
* **lua**: luacheck
* **nim**: nim
* **objective-c**: clang
* **python**: pyflakes
* **python**: mypy
* **python**: pylint
* **shell**: shfmt
* **swift**: swiftc (MacOS and Linux only)
* **yaml**: yamllint
If the linter plugin is enabled and the file corresponds to one of
these filetypes, each time the buffer is saved, or when the `> lint`
@@ -34,31 +34,31 @@ From inside another micro plugin, the function `linter.makeLinter` can
be called to register a new filetype. Here is the spec for the `makeLinter`
function:
* `linter.makeLinter(name, filetype, cmd, args, errorformat, os, whitelist, domatch, loffset, coffset, callback)`
`linter.makeLinter(name, filetype, cmd, args, errorformat, os, whitelist, domatch, loffset, coffset, callback)`
> name: name of the linter
> filetype: filetype to check for to use linter
> cmd: main linter process that is executed
> args: arguments to pass to the linter process
use %f to refer to the current file name
use %d to refer to the current directory name
> errorformat: how to parse the linter/compiler process output
* **name**: name of the linter
* **filetype**: filetype to check for to use linter
* **cmd**: main linter process that is executed
* **args**: arguments to pass to the linter process
* use %f to refer to the current file name
* use %d to refer to the current directory name
* **errorformat**: how to parse the linter/compiler process output
%f: file, %l: line number, %m: error/warning message
> os: list of OSs this linter is supported or unsupported on
* **os**: list of OSs this linter is supported or unsupported on
optional param, default: {}
> whitelist: should the OS list be a blacklist (do not run the linter for these OSs)
* **whitelist**: should the OS list be a blacklist (do not run the linter for these OSs)
or a whitelist (only run the linter for these OSs)
optional param, default: false (should blacklist)
> domatch: should the filetype be interpreted as a lua pattern to match with
* **domatch**: should the filetype be interpreted as a lua pattern to match with
the actual filetype, or should the linter only activate on an exact match
optional param, default: false (require exact match)
> loffset: line offset will be added to the line number returned by the linter
* **loffset**: line offset will be added to the line number returned by the linter
useful if the linter returns 0-indexed lines
optional param, default: 0
> coffset: column offset will be added to the col number returned by the linter
* **coffset**: column offset will be added to the col number returned by the linter
useful if the linter returns 0-indexed columns
optional param, default: 0
> callback: function to call before executing the linter, if it returns
* **callback**: function to call before executing the linter, if it returns
false the lint is canceled. The callback is passed the buf.
optional param, default: nil

View File

@@ -70,7 +70,8 @@ function preinit()
makeLinter("dmd", "d", "dmd", {"-color=off", "-o-", "-w", "-wi", "-c", "%f"}, "%f%(%l%):.+: %m")
makeLinter("eslint", "javascript", "eslint", {"-f","compact","%f"}, "%f: line %l, col %c, %m")
makeLinter("gobuild", "go", "go", {"build", "-o", devnull, "%d"}, "%f:%l:%c:? %m")
-- makeLinter("golint", "go", "golint", {"%f"}, "%f:%l:%c: %m")
makeLinter("govet", "go", "go", {"vet"}, "%f:%l:%c: %m")
makeLinter("clippy", "rust", "cargo", {"clippy", "--message-format", "short"}, "%f:%l:%c: %m")
makeLinter("hlint", "haskell", "hlint", {"%f"}, "%f:%(?%l[,:]%c%)?.-: %m")
makeLinter("javac", "java", "javac", {"-d", "%d", "%f"}, "%f:%l: error: %m")
makeLinter("jshint", "javascript", "jshint", {"%f"}, "%f: line %l,.+, %m")
@@ -83,9 +84,11 @@ function preinit()
makeLinter("pylint", "python", "pylint", {"--output-format=parseable", "--reports=no", "%f"}, "%f:%l: %m")
makeLinter("flake8", "python", "flake8", {"%f"}, "%f:%l:%c: %m")
makeLinter("shfmt", "shell", "shfmt", {"%f"}, "%f:%l:%c: %m")
makeLinter("shellcheck", "shell", "shellcheck", {"-f", "gcc", "%f"}, "%f:%l:%c:.+: %m")
makeLinter("swiftc", "swift", "xcrun", {"swiftc", "%f"}, "%f:%l:%c:.+: %m", {"darwin"}, true)
makeLinter("swiftc", "swift", "swiftc", {"%f"}, "%f:%l:%c:.+: %m", {"linux"}, true)
makeLinter("swiftc-linux", "swift", "swiftc", {"%f"}, "%f:%l:%c:.+: %m", {"linux"}, true)
makeLinter("yaml", "yaml", "yamllint", {"--format", "parsable", "%f"}, "%f:%l:%c:.+ %m")
makeLinter("nix-linter", "nix", "nix-linter", {"%f"}, "%m at %f:%l:%c", {"linux"}, true)
config.MakeCommand("lint", function(bp, args)
bp:Save()
@@ -123,12 +126,11 @@ function runLinter(buf)
ftmatch = false
end
local args = {}
for k, arg in pairs(v.args) do
args[k] = arg:gsub("%%f", file):gsub("%%d", dir)
end
if ftmatch then
local args = {}
for k, arg in pairs(v.args) do
args[k] = arg:gsub("%%f", file):gsub("%%d", dir)
end
lint(buf, k, v.cmd, args, v.errorformat, v.loffset, v.coffset, v.callback)
end
end

36
runtime/runtime.go Normal file
View File

@@ -0,0 +1,36 @@
package config
import (
"embed"
"path/filepath"
"strings"
)
//go:generate go run syntax/make_headers.go syntax
//go:embed colorschemes help plugins syntax
var runtime embed.FS
func fixPath(name string) string {
return strings.TrimLeft(filepath.ToSlash(name), "runtime/")
}
// AssetDir lists file names in folder
func AssetDir(name string) ([]string, error) {
name = fixPath(name)
entries, err := runtime.ReadDir(name)
if err != nil {
return nil, err
}
names := make([]string, len(entries), len(entries))
for i, entry := range entries {
names[i] = entry.Name()
}
return names, nil
}
// Asset returns a file content
func Asset(name string) ([]byte, error) {
name = fixPath(name)
return runtime.ReadFile(name)
}

View File

@@ -7,8 +7,9 @@ rules:
- identifier: "\\b[A-Z_][0-9A-Z_]+\\b"
- type: "\\b(auto|float|double|char|int|short|long|sizeof|enum|void|static|const|struct|union|typedef|extern|(un)?signed|inline)\\b"
- 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)"
@@ -19,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

View File

@@ -7,6 +7,7 @@ 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"

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

@@ -10,7 +10,7 @@ rules:
# Octal integer literals are deprecated
- error: "(0[0-7_]*)(L[uU]?|[uU]L?)?"
# Decimal integer literals
- constant.number: "([0-9]|[1-9][0-9_]*)(L[uU]?|[uU]L?)?"
- constant.number: "([0-9]|[1-9][0-9_]*)(L[uU]?|[uU]L?)?\\b"
# Binary integer literals
- constant: "(0[bB][01_]*)(L[uU]?|[uU]L?)?"
# Decimal float literals

View File

@@ -1,6 +1,6 @@
filetype: erb
detect:
detect:
filename: "\\.erb$|\\.rhtml$"
rules:
@@ -12,7 +12,7 @@ rules:
- symbol: "[:=]"
- identifier: "(alt|bgcolor|height|href|id|label|longdesc|name|onclick|onfocus|onload|onmouseover|size|span|src|style|target|type|value|width)="
- constant.string: "\"[^\"]*\""
- constant.number: "(?i)#[0-9A-F]{6,6}"
- constant.number: "(?i)#[0-9a-fA-F]{6,6}"
- constant.string.url: "(ftp(s)?|http(s)?|git|chrome)://[^ ]+"
- comment: "<!--.+?-->"
- preproc: "<!DOCTYPE.+?>"

View File

@@ -38,4 +38,8 @@ rules:
start: "\\(\\*"
end: "\\*\\)"
rules:
- todo: "(TODO|FIXME|WONTFIX|NOTE|HACK):?"
- todo: "(TODO|FIXME|WONTFIX|NOTE|HACK):?"
- comment:
start: "%"
end: "$"
rules: []

View File

@@ -5,18 +5,18 @@ detect:
rules:
- type: "(?i)\\b(action|advance|all|allocatable|allocated|any|apostrophe)\\b"
- type: "(?i)\\b(append|asis|assign|assignment|associated|character|common)\\b"
- type: "(?i)\\b(append|asis|assign|assignment|associated|bind|character|common)\\b"
- type: "(?i)\\b(complex|data|default|delim|dimension|double precision)\\b"
- type: "(?i)\\b(elemental|epsilon|external|file|fmt|form|format|huge)\\b"
- type: "(?i)\\b(elemental|enum|enumerator|epsilon|external|file|fmt|form|format|huge)\\b"
- type: "(?i)\\b(implicit|include|index|inquire|integer|intent|interface)\\b"
- type: "(?i)\\b(intrinsic|iostat|kind|logical|module|none|null|only)\\\\b"
- type: "(?i)\\b(operator|optional|pack|parameter|pointer|position|private)\\b"
- type: "(?i)\\b(program|public|real|recl|recursive|selected_int_kind)\\b"
- type: "(?i)\\b(selected_real_kind|subroutine|status)\\b"
- type: "(?i)\\b(selected_real_kind|subroutine|status|module|function|logical)\\b"
- constant: "(?i)\\b(abs|achar|adjustl|adjustr|allocate|bit_size|call|char)\\b"
- constant: "(?i)\\b(close|contains|count|cpu_time|cshift|date_and_time)\\b"
- constant: "(?i)\\b(deallocate|digits|dot_product|eor|eoshift|function|iachar)\\b"
- constant: "(?i)\\b(deallocate|digits|dot_product|eor|eoshift|iachar)\\b"
- constant: "(?i)\\b(iand|ibclr|ibits|ibset|ichar|ieor|iolength|ior|ishft|ishftc)\\b"
- constant: "(?i)\\b(lbound|len|len_trim|matmul|maxexponent|maxloc|maxval|merge)\\b"
- constant: "(?i)\\b(minexponent|minloc|minval|mvbits|namelist|nearest|nullify)\\b"
@@ -24,16 +24,18 @@ rules:
- constant: "(?i)\\b(random_number|random_seed|range|read|readwrite|replace)\\b"
- constant: "(?i)\\b(reshape|rewind|save|scan|sequence|shape|sign|size|spacing)\\b"
- constant: "(?i)\\b(spread|sum|system_clock|target|transfer|transpose|trim)\\b"
- constant: "(?i)\\b(ubound|unpack|verify|write|tiny|type|use|yes)\\b"
- constant: "(?i)\\b(ubound|unpack|verify|write|tiny|type|use|yes|true|false|not)\\b"
- constant.number: "\\b([0-9]+)\\b"
- statement: "(?i)\\b(.and.|case|do|else|else?if|else?where|end|end?do|end?if)\\b"
- statement: "(?i)\\b(end?select|.eqv.|forall|if|lge|lgt|lle|llt|.neqv.|.not.)\\b"
- statement: "(?i)\\b(.or.|repeat|select case|then|where|while)\\b"
- statement: "(?i)\\b(or|and|repeat|select|case|then|where|while|import)\\b"
- special: "(?i)\\b(continue|cycle|exit|go?to|result|return)\\b"
#Operator Color
- symbol.operator: "[.:;,+*|=!\\%]|/|-|&"
- symbol.operator: "[.:;,+*|=!\\%]|/|-|>|<|&"
#Parenthetical Color
- symbol.bracket: "[(){}]|\\[|\\]"
@@ -60,4 +62,3 @@ rules:
end: "$"
rules:
- todo: "(TODO|XXX|FIXME):?"

View File

@@ -0,0 +1,14 @@
filetype: freebsd-kernel
detect:
filename: "GENERIC$"
rules:
- identifier: "^(cpu|ident|options|makeoptions|device|include)"
- statement: "\\s\\S*"
- comment:
start: "#"
end: "$"
rules:
- todo: "(TODO|XXX|FIXME):?"

View File

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

View File

@@ -5,9 +5,9 @@ detect:
rules:
# Rebase commands
- statement: "^(p(ick)?|r(eword)?|e(dit)?|s(quash)?|f(ixup)?|x|exec|d(rop)?)\\b"
- statement: "^(p(ick)?|r(eword)?|e(dit)?|s(quash)?|f(ixup)?|x|exec|b(reak)?|d(rop)?|l(abel)?|t|reset|m(erge)?)\\b"
# Commit IDs
- identifier: "\\b([0-9a-f]{7,40})\\b"
- identifier: "\\b([0-9a-fA-F]{7,40})\\b"
# Color keywords for Github (and others)
- type.keyword: "\\b(?i)((fix(es|ed)?|close(s|d)?) #[0-9]+)\\b"

View File

@@ -0,0 +1,15 @@
filetype: gnuplot
detect:
filename: "\\.(gnu|gpi|plt|gp)$"
rules:
- statement: "\\b(set|unset|plot|splot|replot|if|else|do|for|while|fit)\\b"
- symbol.operator: "[-+/*=<>?:!~%&|^$]"
- constant.number: "\\b([0-9]+|0x[0-9a-fA-F]*)\\b"
- comment:
start: "#"
end: "$"
rules:
- todo: "TODO:?"

30
runtime/syntax/groovy.yaml Executable file → Normal file
View File

@@ -9,13 +9,13 @@ rules:
- identifier: "\\b[A-Z_$]+\\b"
# The style guide for JVM languages is PascalCase for classes and interfaces
- identifier.class: "\\b[A-Z][a-zA-Z0-9$]+\\b"
# Primitive types
- type: "\\b(byte|short|int|long|float|double|char|boolean|void)\\b"
# Type-related keywords
- type.keyword: "\\b(private|public|protected|static|final|var|def)\\b"
# Keywords
- statement: "\\b(for|while|do|if|else|switch|case|default|try|catch|finally)\\b"
- statement: "\\b(break|continue|return|throw|assert)\\b"
@@ -23,11 +23,11 @@ rules:
- statement: "\\b(this|super)\\b"
# Unsused, but reserved keywords
- statement: "\\b(goto|const)\\b"
# Operators and punctuation
- symbol.operator: "[-+*/%=<>^~&|!?:;,.@]|\\b(in|is|as|instanceof|new)\\b"
- symbol.brackets: "[(){}]|\\[|\\]"
# Decimal integer literal
- constant.number: "(?i)\\b[1-9]([_0-9]*[0-9])?[GLIDF]?\\b"
# Binary integer literal
@@ -35,14 +35,14 @@ rules:
# Octal integer literal
- constant.number: "(?i)\\b0[0-7]([0-7_]*[0-7])?[GLIDF]?\\b"
# Hexadecimal integer literal
- constant.number: "(?i)\\b0x[0-9a-f]([0-9a-f_]*[0-9a-f])?[GLIDF]?\\b"
- constant.number: "(?i)\\b0x[0-9a-fA-F]([0-9a-f_]*[0-9a-fA-F])?[GLIDF]?\\b"
# Floating-point literal
- constant.number: "(?i)\\b[0-9]([0-9_]*[0-9])?([.][0-9]([0-9_]*[0-9])?)?(e[+-]?[0-9]([0-9_]*[0-9])?)?[DF]?\\b"
- constant.bool: "\\b(true|false|null)\\b"
# Annotations
- identifier: "@[A-Za-z_$][A-Za-z0-9_$]*\\b"
# Single-quoted strings
- constant.string:
start: "'"
@@ -50,7 +50,7 @@ rules:
skip: "\\\\."
rules:
- constant.specialChar: "\\\\([\"'bfnrst\\x24\\\\]|u[a-fA-F0-9]{4})"
# This also matches the Triple-double-quoted strings region, but I can't really find a way to mitigate it, all the while still matching "" as a string correctly
# Also, nesting ${} are never going to be matched correctly with just regex either, so highlighting will break if one is to nest interpolation
# These two problems combined mean slight mistakes in highlighing that the user is just going to have to deal with
@@ -63,7 +63,7 @@ rules:
- constant.specialChar: "\\\\([\"'bfnrst\\x24\\\\]|u[a-fA-F0-9]{4})"
- identifier.var: "\\x24[\\w\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\uFFFE]+([.][a-zA-Z0-9_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\uFFFE]+)*"
- identifier: "\\x24[{].*[}]"
# Triple-double-quoted strings
- constant.string:
start: "\"\"\""
@@ -76,7 +76,7 @@ rules:
start: "[$][{]"
end: "[}]"
rules: []
# Triple-single-quoted strings
- constant.string:
start: "'''"
@@ -84,28 +84,28 @@ rules:
skip: "\\\\."
rules:
- constant.specialChar: "\\\\([\"'bfnrst\\x24\\\\]|u[a-fA-F0-9]{4})"
# Slashy strings are left out, because they match in unwanted places pretty much all the time
# Dollar-slashy strings
- constant.string:
start: "[$]/"
end: "/[$]"
rules: []
# Single-line comments
- comment:
start: "//"
end: "$"
rules:
- todo: "(TODO|XXX|FIXME):?"
# Multiline comments
- comment:
start: "/[*]"
end: "[*]/"
rules:
- todo: "(TODO|XXX|FIXME):?"
# Groovydoc comments
- comment:
start: "/[*][*]@?"

52
runtime/syntax/hc.yaml Normal file
View File

@@ -0,0 +1,52 @@
filetype: hc
detect:
filename: "(\\.(hc|HC)$|\\.(hh|HH)$|\\.ii?$|\\.(def)$)"
rules:
- identifier: "\\b[A-Z_][0-9A-Z_]+\\b"
- type: "\\b(F64|I8|U8|I16|U16|I32|U32|I64|U64|sizeof|enum|U0|static|extern|struct|union|class|intern|public|argc|argv|asm)\\b"
- statement: "\\b(for|if|while|do|else|case|default|switch)\\b"
- statement: "\\b(try|catch|throw|goto|continue|break|return)\\b"
- preproc: "^[[:space:]]*#[[:space:]]*(define|pragma|include|(un|ifn?)def|endif|el(if|se)|if|help_index|ifjit|ifaot|exe)"
# Operator Color
- 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)"
# 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
- 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.number: "NULL"
- constant.number: "TRUE"
- constant.number: "FALSE"
- 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,6 +1,6 @@
filetype: html4
detect:
detect:
filename: "\\.htm[l]?4$"
header: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN|http://www.w3.org/TR/html4/strict.dtd\">"
@@ -13,7 +13,7 @@ rules:
- symbol: "[:=]"
- identifier: "(alt|bgcolor|height|href|id|label|longdesc|name|on(click|focus|load|mouseover)|size|span|src|style|target|type|value|width)="
- constant.string: "\"[^\"]*\""
- constant.number: "(?i)#[0-9A-F]{6,6}"
- constant.number: "(?i)#[0-9a-fA-F]{6,6}"
- default:
start: ">"
end: "<"

View File

@@ -1,6 +1,6 @@
filetype: html5
detect:
detect:
filename: "\\.htm[l]?5$"
header: "<!DOCTYPE html5>"
@@ -13,7 +13,7 @@ rules:
- symbol: "[:=]"
- identifier: "(alt|bgcolor|height|href|id|label|longdesc|name|on(click|focus|load|mouseover)|size|span|src|style|target|type|value|width)="
- constant.string: "\"[^\"]*\""
- constant.number: "(?i)#[0-9A-F]{6,6}"
- constant.number: "(?i)#[0-9a-fA-F]{6,6}"
- default:
start: ">"
end: "<"

Some files were not shown because too many files have changed in this diff Show More