0

Currently, I have begun using vim for C++ projects. I use vimspector for debugging help. This offers a command :call vimspector#Launch() to debug the current successful build. To build the current code, I have the following keybinding:

:nnoremap <F4> :%update \| :make CONF=Debug -C ./.vim \| :cope <CR>

which essentially:

  1. saves modified source code files,
  2. compiles and builds the source code files by running make on .vim/Makefile-Debug.mk , and,
  3. opens the quick-fix list containing warnings and possible errors.

After a successful build, I separately and manually launch the debugging session. Is there a way to have the above keymapping also execute :call vimspector#Launch() automatically if make did not return any errors?

This link specifies that make returns a 0 if there were no errors discovered (warnings while compilation seem to be OK and not affect the return value of 0).

So, can I have something like below (in pseudocode) in .vimrc?

:nnoremap <F4> :%update \| :make CONF=Debug -C ./.vim \| if not 0 -> :cope <CR> | if 0 -> :call vimspector#Launch()

where if make returns a 0 the debugging session is launched and if not, the quick fix list is opened?


ETA1: Following Luc Hermitte's suggestion, I had:

function Get_buildmetrics() 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

function Build_and_run() abort
  " to make sure the buffer is saved
  exe '%update'
  exe 'make CONF=Debug -C ./.vim'
  if get_buildmetrics().errors
    echom "Error detected, execution aborted"
    copen
    return
  endif
  exe 'call vimspector#Launch()'
endfunction

in my .vimrc. Then,

:call Build_and_run()

from within Vim does exactly what I want!

Merci beaucoup!

1 Answer 1

1

To detect :make has executed correctly and to continue with vimscript code, a little bit of programming is required. A few years back I've described on SO how it could be done: https://stackoverflow.com/a/56991040/15934

Note: I use a method that analyses the quickfix content instead of :make execution result as sometimes we may chain make with other programs without forwarding process results through pipefail. Counting the number of errors (and may be warnings) is more resilient IMO.

EDIT: quick and very dirty, for vimrc, rename the function name that contains dashes. And your latest issues were related to the fact commands and functions are not executed in the same way.

function s:get_buildmetrics() 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

function s:build_and_run() abort
  " to make sure the buffer is saved
  %update
  make CONF=Debug -C ./.vim

  if s:get_buildmetrics().errors
    echom "Error detected, execution aborted"
    copen
    return
  endif

  call vimspector#Launch()
endfunction

nnoremap <silent> <F5> :<c-u>call <sid>build_and_run()<cr>
2
  • 1
    This gives me something to work with. Let me try to incorporate my flow within the framework you suggest and see if it solve the problem.
    – Tryer
    Sep 23, 2021 at 13:57
  • 1
    I have updated my answer Sep 23, 2021 at 15:10

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.