Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto completion #174

Open
jannisch opened this issue Jun 20, 2016 · 43 comments
Open

Auto completion #174

jannisch opened this issue Jun 20, 2016 · 43 comments
Milestone

Comments

@jannisch
Copy link

Because micro already provides features like true color support, I wonder why there is not even an automatic completition for brackets and statements like def in python in ruby.
Is this feature not implemented yet or do I experience a bug? Unfortunately I can't code in go.

Thanks!

@zyedidia
Copy link
Owner

Unfortunately this feature is not implemented yet, although I plan to do it at some point. I think auto closing brackets, quotes, parentheses etc... is different from autocompletion for actual code keywords (and far easier to implement so that will probably get done first).

I think it would be best to have an autocompletion core in micro, and implement specific completion for each language in plugins. Micro can't magically know that def is a Python statement, and instead can use a code completion engine built for Python, such as Jedi. Of course, not all languages have something like Jedi to do auto completion, so in that case micro can just fall back to simple buffer completion (where it will auto complete any word that is already used in the current file).

Anyway, I'll try to implement auto complete for brackets soon, and I'll do more advanced auto completion some time in the future, but that's a lot more complex.

@jannisch
Copy link
Author

I totally agree, the benefit of code keywords and whole API catalogs is also smaller.

But let me explain the following example for a method definition in ruby:

def mymethod(myparam)
  # some action
end

If the user types in an usual bracket, a closed one will be added after the cursor. In the above example, \n \nend would do the same trick after the user types def. This can also be limited to ruby because micro already recognizes the language as I saw.
So the most important language features might still be in the scope, we just need a few contributers to collect those patterns.

I appreciate your effort.

@CamilleScholtz
Copy link
Contributor

CamilleScholtz commented Jun 20, 2016

IMO it would be best if something like this get handled very similar to how syntax highlighting is done. So just simple files with regex patterns, and some pre-defined actions, like "Add X character(s) on the next line" or "Add X character(s) after the cursor".

@zyedidia
Copy link
Owner

Yeah, I think what you're looking for here is snippets, and luckily, Vim users have already collected all those patterns. We just need a way of reading the snippet files and then of course actually implementing the snippet functionality. See here for lots of snippets that are already made. Those files are for the Vim plugin snipmate, but there are more complex ones in that repository for the Vim plugin UltiSnips. Those snippets are more complex but also more powerful, so we'll have to decide which one to use.

Anyway, I think this is a separate issue from snippets, although maybe snippets is what you meant originally. In any case, I think autocomplete and snippets are both features that would be great to have in micro and will hopefully get implemented at some point soon.

@zyedidia zyedidia mentioned this issue Jun 21, 2016
@zyedidia zyedidia changed the title Auto completition (at least for brackets) Auto completion Jun 21, 2016
@zyedidia zyedidia mentioned this issue Jun 21, 2016
@jannisch
Copy link
Author

Thanks for the new autoclose feature, it works very well.

The vim snippets look quite hard to read/parse, for example this one:

class ${1:`substitute(vim_snippets#Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`}
        ${0}
end

They also seem to cover many languages completely which I simply did not want to request here, originally I just thought of brackets and the most basic snippets.
But of course I'd be very happy about a very powerful snippet completition in the future, you can close this issue of course if you want to.

@ipstone
Copy link

ipstone commented Aug 30, 2016

Just as a reference for autocomplete function implemented in vim, there's one utilizing lua that is also popular: https://github.com/shougo/neocomplete.vim (I recall saw this or something similar before, using lua for auto-completion functionality in vim).

@niieani
Copy link

niieani commented Sep 1, 2016

It would be great if there was autocompletion not only for languages, but also for commands available - would make Micro even more intuitive as you'd discover commands by typing them!

@zyedidia
Copy link
Owner

zyedidia commented Sep 1, 2016

There is in fact autocompletion for commands. Maybe I should say that somewhere in the docs though... Just press tab and it should give you a list of suggestions in the statusline. It will also autocomplete filenames, and options when appropriate.

@niieani
Copy link

niieani commented Sep 1, 2016

Aah. I guess I was expecting autocompletion like the one fish does. It will show the first autocompletion match as faded colors like this:

And then you can "scroll" up and down with the arrow keys to see different matches. To accept the suggestion you can press right arrow - pretty intuitive.

@mikamiel
Copy link

As for VS Code - it uses an open JSON-based Language Server Protocol for things like syntax highlighting and code completion. I don't know how hard would it be to implement support for this protocol in micro, but IMO it's a very promising solution:
https://code.visualstudio.com/blogs/2016/06/27/common-language-protocol

@jannisch
Copy link
Author

I really like the idea of this standart, but the list of implementations is very limited and it is "immature", e.g. the server for rust:

This project is in the early stages of development, it is not yet ready for real use. It will probably eat your laundry.

@jantb jantb mentioned this issue Nov 24, 2016
6 tasks
@jantb
Copy link

jantb commented Nov 24, 2016

This box can be used to auto completion once it is exposed to plugins. There is a mode without the prompt that just shows the list.

@njskalski
Copy link

njskalski commented Nov 30, 2017

later in December I would like to try implementing Language Server Protocol (client) to micro. Golang has most of the primitives implemented already, so the communication part should be easy. I am wondering if this kind of improvement would be considered welcome. If so, can somebody provide clues how it would be suitable to be implemented?

@sum01
Copy link
Contributor

sum01 commented Dec 15, 2017

@askalski Maybe https://github.com/Alloyed/lua-lsp could be used in some way

@njskalski
Copy link

@sum01 thank you. From what I understand is that I need to implement LSP client and languages provide servers. Also, I think I will dive into editing micro with go-lang to implement client. But I am still learning language features.

@a-h
Copy link

a-h commented Dec 30, 2017

I put together a quick hack using gocode and a Lua plugin.

To run it, create the file ~/.config/micro/plugins/gocode_ac/gocode_ac.lua

function gocode(offset)
    --TODO: Work out how to get the current buffer contents and pass it to gocode via stdin instead
    -- of saving and using the -in parameter. For large files, this is likely to be inefficient, perhaps
    -- micro keeps a scratch temporary file?
    CurView():Save(false)
    -- Use gocode and output the results of the autocomplete in JSON.
    local handle = io.popen("gocode -f=json -in=" .. CurView().Buf.Path .. " autocomplete " .. offset)
    local result = handle:read("*a")
    --TODO: Work out how to parse the JSON (or text output) and create a list of options to return.
    messenger:AddLog("gocode result: " .. result)
    handle:close()
end

function onRune(r, v)
    --TODO: Add some logic to determine when to start autocompleting. This will be:
    -- * When a period is entered (e.g. "fmt." should produce "fmt.Println")
    -- * When a bracket is opened (e.g. "fmt.Println(" should give information about the parameters)
    -- * When Ctrl+Space is pressed

    --TODO: Add some logic to determine when to stop autocompleting, e.g.
    -- * Escape is pressed
    -- * A selection is made from the list and entered into the buffer
    -- * The bracket is closed
    -- * Space is pressed

    -- Convert the position of the cursor to a byte offset for use with gocode.

    -- The '-' here is to derefence the pointer to v.Cursor.Loc which is automatically made
    -- when converting go structs to lua
    local offset = ByteOffset(-v.Cursor.Loc, CurView().Buf)
    messenger:AddLog("rune: " .. r .. offset)

    gocode(offset)

    return false
end

Open up the editor again, and switch on logging by hitting Ctrl+E and then typing log.

Start editing the text...

At that point, every time you hit a rune in the editor, the onRune function will be hit. It's then possible to use the ByteOffset function to grab the offset, and pass it to the gocode command line tool.

It's very crude, but it shows that the autocomplete function is possible. The log shows r: .200 which means . was pressed at byte offset 200 and the JSON returned from gocode is what I'd expect to see.

screen shot 2017-12-30 at 14 53 55

So... any pointers on how to draw out a list of options, or does someone want to give that a blast?

@a-h
Copy link

a-h commented Dec 30, 2017

Apologies for the Go-specific nature of the above. I appreciate that it's not a globally useful solution.

If the approach is to tackle this via a language server integration, then I guess it doesn't need to be a plugin and could be added to the core (and therefore written in Go)?

@a-h
Copy link

a-h commented Jan 1, 2018

I've started up on the autocomplete functionality as part of the core of micro in Go instead of as a plugin. I spent a few hours and I think what I've done would be a reasonable way to be able to extend it to other languages over at https://github.com/a-h/micro

It doesn't insert text into the buffer yet, that's next.

autocomplete_show_options

Look about right?

@a-h
Copy link

a-h commented Jan 1, 2018

Just added ability to select an option. For functions, it doesn't yet list the parameters, just everything you could write.

select_option

@sum01
Copy link
Contributor

sum01 commented Jan 1, 2018

I like it, simple and efficient. Hopefully you made sure to expose the proper functions so plugins can easily add onto it.

@a-h
Copy link

a-h commented Jan 2, 2018

Great, if I'm headed in the right direction, I'll keep on going. Good point on the plugin support, I'll make sure it's possible to write a plugin that can use autocomplete functionality. (adding options to, triggering and hiding the "dialog").

@a-h
Copy link

a-h commented Jan 3, 2018

Created pull request: #977

@TobiaszCudnik
Copy link

Definitive +1 for a general Language Server Protocol implementation. The project got a new website recently, with this page listing all the supported languages (that includes Go).

Looks like a quick win...

@zyedidia zyedidia added this to the v2 milestone Sep 1, 2019
zyedidia added a commit that referenced this issue Dec 25, 2019
The code from the refactor that I have been working on is
now more or less ready to be merged. These changes make some
breaking changes, notably with regards to the plugin
interface. Once a lot more documentation has been written, I
will release this code as micro 2.0. There are a lot of new
features, and in the coming days I will try to go through
the open issues to see exactly which ones are addressed by
the new features, and write lots more documentation
regarding what has been implemented.

Some highlights include:

* Simple autocompletion.
    * Autocompletion (tab by default) will do a simple
      "buffer completion" which will autocomplete according
      to words used elsewhere in the buffer. In the future
      plugin support could be added along with support for
      interfacing with language-specific autocompletion
      tools.
* Automatic backups.
    * Backup files are stored in `~/.config/micro/backups`
      for every open buffer and are saved roughly every 8
      seconds if the buffer is being modified. Backups
      are removed when the buffer is closed, but if micro
      or the system crashes, any unsaved changes can be
      recovered by re-opening the file (micro will auto-
      recover) or by manually viewing the backup in the
      `~/.config/micro/backups` directory.
* Configurable statusline.
* Configurable linter plugin.
* Resizeable splits.
* Complete re-organization of the code to support better go
  modules and maintain a better directory structure.
* Better plugin interface with better access to the Go
  standard library and internal Micro functions (lots of
  documentation still needs to be written).
    * Documentation still needs to be written, but in the
      meantime please see the default plugins as examples
      as they have been converted from their old versions
      to be compatible with the new interface.
* Buffer synchronization when the same file is opened
  multiple times.
* Keybindings and mouse support in the command bar.
* Support for non-utf8 encodings.
* General QoL improvements and bug fixes.
    * Notably I believe the autoclose plugin crash issue is
      fixed.
* No more plugin manager.
    * Plugin installation will now be performed manually
      by git cloning into the `~/.config/micro/plug`
      directory. This may not be a highlight for some but
      I believe it is much simpler, and there is no need
      to have a heavyweight dependency manager. Perhaps
      in the future, a good command-line tool can be made
      to manage plugins if people would find it useful.
* Other features that I have forgotten.

Next I plan to write up more documentation for all the new
features, and make a "release candidate" for micro 2.0. I
will also be working to fix any bugs that come up (hopefully
not too many, but this is a big change and bound to have
some issues). After release I hope to focus more on
optimization (for example loading syntax files is currently
somewhat inefficient, and the bottleneck for startup time #1427).

Sorry for not being so active recently, but I hope merging
this big change can help me get back to more regular
development. Thanks to everyone for using micro and for
giving feedback and engaging with development online (even
if I don't always respond).

Merry Christmas!

Issues that are fixed/affected by this change:

Ref #1419 (configurable statusline)
Ref #1413 (cursor behaves better)
Ref #1401 (softwrap problems)
Ref #1383 (better save with sudo)
Ref #1424 (better save with sudo)
Ref #1382 (go modules)
Ref #1381 (install plugins from command line)
Ref #1357 (sorting -- textfilter)
Ref #1351 (custom linting)
Ref #1350 (sudo problem might be fixed)
Ref #1298 (readonly option)
Ref #1250 (autoclose bug)
Ref #1239 (go modules)
Ref #813  (autoclose bug)
Ref #812  (cursor sync across same buffers)
Ref #770  (resizeable panes)
Ref #635  (keybindings in infobar)
Ref #596  (disable builtin plugins)
Ref #550  (backups)
Ref #174  (autocompletion)
@zyedidia
Copy link
Owner

zyedidia commented Dec 27, 2019

Simple buffer autocompletion (based on words in the current buffer) is now supported. The framework for autocompletion is also implemented so hopefully soon we can have support for more complex autocompletion and a plugin interface.

@theAkito
Copy link
Contributor

It's amazing to see how Micro is growing sometimes slowly but steady. Have been waiting for buffer auto-completion for so long. Great job everyone involved, keep going.

@theAkito
Copy link
Contributor

Are there any status updates? Just curious.

@Anachron
Copy link

I'd love to be able to provide additional autocomplete support via a plugin.
Use-Case: I'd love to be able to provide a list of additional words that are auto-completed, for example when writing emails with my ${EDITOR} I'd like to auto-complete email-addresses.

Is there a starting point for this yet where I can pick up?

@Titaniumtown
Copy link

Would love to use micro as my daily-driver text editor, will this feature be added?

@szw
Copy link

szw commented Aug 1, 2020

@zyedidia Is there a way to customize the word boundaries in the simple buffer autocompletion based on the filetype? I can't make it to work for so-called lispy identifiers (Lisp/Clojure/Scheme use dashes in identifiers-, the same way as underscores everywhere else).

@Titaniumtown
Copy link

we need a tabnine port for micro.

@zyedidia
Copy link
Owner

zyedidia commented Aug 9, 2020

Thanks for the suggestion, tabnine looks like it could be a good as a solution to more advanced autocompletion than what currently exists in micro.

@sebkolind
Copy link
Contributor

sebkolind commented Feb 11, 2021

@zyedidia How do you use the built-in buffer autocompletion? Is it supposed to popup by itself, or do I have to use some keybinding? It turns out you just press TAB and you get a completion.

I am also a big fan of the LSP implementation and would love to see if someone has started working on this, as I might be able to help.

@Artembrenner
Copy link

wow i love this

@informeai
Copy link

Hello, how are you ✋
Do you still have the plan to implement go autocomplete natively on the micro?
I had a look at the gocode but I couldn't find the settings for the micro.
I love this editor. ❤️

@baris-inandi
Copy link

any updates? will native autocomplete be implemented?

@silvioprog
Copy link

I'm just waiting for this LSP feature to definitively leave NeoVIM+CoC. 🙂

@XxnittanixX
Copy link

I put together a quick hack using gocode and a Lua plugin.

To run it, create the file ~/.config/micro/plugins/gocode_ac/gocode_ac.lua

function gocode(offset)
    --TODO: Work out how to get the current buffer contents and pass it to gocode via stdin instead
    -- of saving and using the -in parameter. For large files, this is likely to be inefficient, perhaps
    -- micro keeps a scratch temporary file?
    CurView():Save(false)
    -- Use gocode and output the results of the autocomplete in JSON.
    local handle = io.popen("gocode -f=json -in=" .. CurView().Buf.Path .. " autocomplete " .. offset)
    local result = handle:read("*a")
    --TODO: Work out how to parse the JSON (or text output) and create a list of options to return.
    messenger:AddLog("gocode result: " .. result)
    handle:close()
end

function onRune(r, v)
    --TODO: Add some logic to determine when to start autocompleting. This will be:
    -- * When a period is entered (e.g. "fmt." should produce "fmt.Println")
    -- * When a bracket is opened (e.g. "fmt.Println(" should give information about the parameters)
    -- * When Ctrl+Space is pressed

    --TODO: Add some logic to determine when to stop autocompleting, e.g.
    -- * Escape is pressed
    -- * A selection is made from the list and entered into the buffer
    -- * The bracket is closed
    -- * Space is pressed

    -- Convert the position of the cursor to a byte offset for use with gocode.

    -- The '-' here is to derefence the pointer to v.Cursor.Loc which is automatically made
    -- when converting go structs to lua
    local offset = ByteOffset(-v.Cursor.Loc, CurView().Buf)
    messenger:AddLog("rune: " .. r .. offset)

    gocode(offset)

    return false
end

Open up the editor again, and switch on logging by hitting Ctrl+E and then typing log.

Start editing the text...

At that point, every time you hit a rune in the editor, the onRune function will be hit. It's then possible to use the ByteOffset function to grab the offset, and pass it to the gocode command line tool.

It's very crude, but it shows that the autocomplete function is possible. The log shows r: .200 which means . was pressed at byte offset 200 and the JSON returned from gocode is what I'd expect to see.

screen shot 2017-12-30 at 14 53 55

So... any pointers on how to draw out a list of options, or does someone want to give that a blast?

so um whered the damn thing go!

@Yu-Vitaqua-fer-Chronos
Copy link

Any progress on this? (Or a plugin that intergrates Jedi with Micro?)

@terokarvinen
Copy link

terokarvinen commented Apr 8, 2022

@XxnittanixX , nice to see you playing with high quality completion. I tried similar approach to LSP, executing gopls binary to get function signatures. However, @AndCake has now created a real JSON-RPC LSP plugin. As it keeps the language server running and communicates trough RPC, it's likely more efficient. It has some rudimentary support for LSP auto completion. Micro's LSP support and the plugin are also discussed in #1138.

If you want to try it out, it's a two line install. E.g. on Debian 'sudo apt-get update; sudo apt-get -y install micro golang-go gopls; micro --plugin install lsp'. To test it, write a hello world 'micro hello.go', move cursor over PrintLn and press alt-K. Auto completion is ctrl-space.

Update: Go installation is the easiest. Python installation is detailed in help/lsp.md. It has also been briefly tested with Javascript, Typescript, Rust and Lua; installation instructions for these would be nice.

@rochacbruno
Copy link

This looks amazing, thanks @AndCake

micro_lsp

@ryan-caesar-ramos
Copy link

ryan-caesar-ramos commented Mar 6, 2024

Sorry to bump this, but I'm having a hard time recreating the behavior shown here

This looks amazing, thanks @AndCake

micro_lsp micro_lsp

I ran

micro -plugin install lsp
pip install "python-lsp-server[rope,ruff,pylsp-mypy]"
pip install pylsp-mypy

Then set my ~/.config/micro/settings.json to

{
	"lsp.server": "python=pylsp",
	"lsp.formatOnSave": true,
	"lsp.tabcompletion": true,
	"lsp.autocompleteDetails": false
}

which, for some reason, after quitting micro automatically gets rewritten to

{
	"lsp.server": "python=pylsp"
}

After this, none of the commands (ctrl+space, alt+k, alt+r, alt+d) do anything. I was hoping someone could point me in the right direction? Is there something I forgot to configure or some docs that I missed on accident?

Edit: Okay maybe it's not that nothing's happening, but it's incredibly delayed? I smashed ctrl+space over and over again and eventually something did show up, but

  1. the completions don't seem to be for what precedes (i.e. ctrl+space after gc. shows ArithmeticError, AssertionError, etc. instead of say collect)
  2. trying to ctrl+space after gc.colle just wipes out the .colle instead of autocompleting, which I assumed was possible as shown here

@Andriamanitra
Copy link
Contributor

@ryan-caesar-ramos micro-plugin-lsp is a 3rd party plugin so a better place for the discussion would be its own repository (I wouldn't expect much as the project is not very active though).

In my experience the autocompletion feature in micro-plugin-lsp is too buggy to be usable. I wrote my own alternative LSP plugin a while back, it's also far from perfect but its autocompletion has worked better for me most of the time.

@ryan-caesar-ramos
Copy link

@Andriamanitra Thank you for the tip! Also appreciate you linking your alternative, I'll take a look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests