JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.14k stars 5.43k forks source link

[FEATURE] Using Right Arrow Key to Auto Complete Virtual Text? #54539

Closed TheCedarPrince closed 5 days ago

TheCedarPrince commented 2 months ago

Julia Information

Version info:

Julia Version 1.12.0-DEV.573
Commit 263928f9ad4 (2024-05-21 19:54 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
  WORD_SIZE: 64
  LLVM: libLLVM-17.0.6 (ORCJIT, tigerlake)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
Environment:
  JULIA_EDITOR = nvim

How I installed Julia: juliaup


Description: Would it be possible to allow auto-completions shown as virtual text in the Julia REPL complete by pressing the right arrow key as well? Currently on nightly I can hit tab, but I was hoping it would be alright to use the right arrow key to finish autocomplete as well. Currently, also pressing another arrow key (left or right in the written text) "hides" the virtual text instead.

Just for clarity, here is the functionality I am talking about:

image

AshlinHarris commented 1 month ago

Hey @TheCedarPrince. I love this suggestion! I got the feature working locally by replacing the existing methods of edit_move_right with the following:

function edit_move_right(q::MIState)
    s = state(q)
    buf = s.input_buffer
    completions, partial, should_complete = complete_line(s.p.complete, s, q.active_module)::Tuple{Vector{String},String,Bool}
    if !eof(buf)
        # move to the next base UTF8 character to the right
        while true
            c = char_move_right(buf)
            eof(buf) && break
            pos = position(buf)
            nextc = read(buf,Char)
            seek(buf,pos)
            (textwidth(nextc) != 0 || nextc == '\n') && break
        end
        refresh_line(state(s)) 
        return true
    elseif should_complete && length(completions) == 1 && length(partial) > 1
        # Replace word by completion
        prev_pos = position(s)
        push_undo(s)
        edit_splice!(s, (prev_pos - sizeof(partial)) => prev_pos, completions[1])
        refresh_line(state(s)) 
        return true
    end
    return false
end

I had to rewrite the function to take an ::MIState input in order to access all the necessary variables. Then, I basically just inserted the relevant code for the Tab key behavior. Normally, the right arrow key does nothing at the end of a line, but now it should complete the line if an autocomplete option is displayed (i.e., there is one unique autocomplete option and more than 1 character has been typed).

This is a quick hack, and I don't fully understand what all the State variables are doing, so I'll revise it and add some tests. But I don't see any downside to your suggested feature, so I plan to make a pull request soon.