Sapthaka
Sapthaka

Reputation: 420

How to make vim for running and compiling Java files as an IDE?

I already use a vim function in Linux vimrc file to execute Java files by just pressing 'F5'.

Below is the function which I use.

inoremap <F5> <Esc> :call CompileRunGcc()<CR><CR>
func! CompileRunGcc()
exec "w"
if &filetype == 'java'
exec "!javac %"
exec "!time java -cp %:p:h %:t:r"
endif
endfunc

But when there is a compiling error, it shows the error message and also the output of the previous compiled program.

What I want is to be shown only the error message without the output of the previous compiled program. How can I do that?

Upvotes: 2

Views: 535

Answers (2)

Luc Hermitte
Luc Hermitte

Reputation: 32926

IMO, you'd better use the quickfix list feature to import the errors and warnings found into Vim. From there you'll be able to navigate the errors with :cnext, :cprev...

Regarding what's best with Java, you'll have to explore the various Java related compiler plugins. There is a :compiler javac for instance.

Regarding how to know whether the compilation has succeeded or not I use the method I've described in a similar Q/A: https://stackoverflow.com/a/56991040/15934

The only thing that changes is the way the exec_line variable would be built. It would look like (untested)

" From my build-tools-wrapper plugin
function! lh#btw#build#_get_metrics() abort
  let qf = getqflist()
  let recognized = filter(qf, 'get(v:val, "valid", 1)')
  " TODO: support other locales, see lh#po#context().tranlate()
  let errors   = filter(copy(recognized), 'v:val.type == "E" || v:val.text =~ "\\v^ *(error|erreur)"')
  let warnings = filter(copy(recognized), 'v:val.type == "W" || v:val.text =~ "\\v^ *(warning|attention)"')
  let res = { 'all': len(qf), 'errors': len(errors), 'warnings': len(warnings) }
  return res
endfunction


" in a java ftplugin    
function s:build_and_run(file) abort
  let tgt  = fnamemodify(a:file, ':r')
  " to make sure the buffer is saved
  exe 'update ' . a:file
  exe 'make ' . tgt
  if lh#btw#build#_get_metrics().errors
    echom "Error detected, execution aborted"
    copen
    return
  endif

  let path = fnamemodify(a:file, ':p:h')
  let exec_line = '!time java -cp ' . path. ' ' . tgt
  exe exec_line
endfunction

" With <buffer>, I assume this is defined in a java-ftplugin, because the 
" specific '!time java'. It could be generalized to many different 
" languages though.
nnoremap <buffer> µ :<C-U>call <sid>build_and_run(expand('%'))<cr>

Upvotes: 2

filbranden
filbranden

Reputation: 8898

You can use the v:shell_error variable to check whether the javac command has failed. In that case, you can skip running the program, in which case the error messages will be left around for you to inspect.

function! CompileRunGcc()
  exec "w"
  if &filetype ==# 'java'
    exec "!javac %"
    if !v:shell_error
      exec "!time java -cp %:p:h %:t:r"
    endif
  endif
endfunction

Upvotes: 1

Related Questions