1

For a bit of background, I'm trying to set up a function that runs a java file in Neovim, I've tried using the following autocmd:

vim.api.nvim_create_autocmd(
  { "FileType" },
  {
    command = "map <buffer> <F5> :w<cr>:exec '!java' shellescape(@%,1)<cr>",
    pattern = { 'java' },
    group = RunFile,
  }
)

which does work, however if I ask for input (effectively interrupting the program) it gives me an error.

Exception in thread "main" java.util.NoSuchElementException: No line found
        at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
        at com.mycompany.app.CoolApp.main(CoolApp.java:15)

shell returned 1

Now maybe there's an easier solution to my problem (if so please tell) but the solution I came up with is to start a new terminal using :terminal and running an equivalent of java % there.

trying that very literally map <buffer> <F5> :w<cr>:terminal 'java %' gives me the error no such file or directrory, which doesn't make sense to me because it perfectly gives me the path from where I opened neovim to the .java file (for the record it also doesn't work if I start from my home directory, or even from root), if I try doing things manually though (first :terminal, then typing java path/to/file.java) then it does work. I'm very confused, does anyone have any ideas?

2
  • 1
    Why the quotes? Would :map <buffer> <F5> :w<CR>:terminal java %<CR> work?
    – Friedrich
    Commented Jun 30, 2023 at 14:47
  • honestly good question, I removed them and now this seems to work! Thanks a lot Commented Jun 30, 2023 at 14:57

1 Answer 1

1

Quotes in the [command] of :terminal will be passed to the shell. As there's obviously no file called 'java %' (% will be expanded to the name of the current file, though), an error "no such file or directory" is raised.

The solution is to simply remove the quotes and use this mapping:

:map <buffer> <F5> :w<CR>:terminal java %<CR>

Following the famous rule of thumb

If you don't know that you don't want :nnoremap, you want :nnoremap.

you want :nnoremap instead of :map. While we're on it, we might as well make it a little more idiomatic by using <Cmd> instead of : and <Bar> to separate commands. So the final mapping would be:

:nnoremap <buffer> <F5> <Cmd>write <Bar> terminal java %<CR>

See :help :terminal, :help :nnoremap, :help <Cmd> and the somewhat dull looking :help :|.

3
  • 2
    I think you mean <cmd>write <bar> … and not <cmd>write<cr><bar><cmd>…
    – D. Ben Knoble
    Commented Jun 30, 2023 at 18:24
  • @D.BenKnoble that's what I meant. Thank you. It did look fishy when I wrote it but I didn't get it.
    – Friedrich
    Commented Jun 30, 2023 at 19:59
  • 1
    Thanks, that's gonna help a lot! Commented Jul 1, 2023 at 15:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.