简体   繁体   中英

Detect resulting executable from Vim

I have a multi-file project and I use Cmake build system. I have mapped :make to a key as I need to compile it very often. The problem is that I need to run the resulting executable just as often. However typing :!./variable_program_name is very tedious.

Is there any way to detect/get the resulting executable file name?

The recommended way to do this is via a separate target in the Makefile, so that for example :make just triggers the build, and :make run triggers (build and) run of the executable. After all, the Makefile knows best what it's building, so the decision how to run the build artifacts (maybe also with passed arguments) is best delegated to it.

Alternative

To "return" the executable from the Makefile, the :make output is parsed and populates the quickfix list . You could define a custom mapping (for the qf filetype, which is set for such windows) that parses the executable name from the current quickfix line, or even use getqflist() to parse the entire output. That requires that your Makefile prints out the executable name (and path) in a way that can be detected.

Alternative

If you can't even reliably get the executable name from the output, but know the directory where the executable is generated in, you can create a list of files (with glob() ) before running :make , then after it again, and compare the two lists to get the executable name. If you don't want to remove the previous executable from within Vim, a filetime check ( getftime() ) could help.

For anyone viewing this.. I had the same need and decided to solve it with a vim script/plugin. vim-target

Expanding on Ingo Karkat's ideas, this script should do the trick (I am not good with vimscript so I wrote it in bash)

#!/bin/sh

# This script tries to build the project using Makefile, and if that fails
# it tries to generate the Makefile with Cmake.
# Then it finds the latest executable file and runs it

# Remember to manually run cmake after changing CMakeLists.txt as a new 
# Makefile will not be automatically regenerated

if [[ -e "Makefile" ]] || [[ -e "makefile" ]]; then
    make
    if [[ $? -ne 0 ]]; then
        echo "Error when running make"
        exit
    fi
else
    if [[ -e "CMakeLists.txt" ]]; then
        cmake .
        if [[ $? -ne 0 ]]; then
            echo "Error when running cmake"
            exit
        fi
        make
        if [[ $? -ne 0 ]]; then
            echo "Error when running make"
            exit
        fi
    else
        echo "CMakeLists.txt doesn't exist"
        exit
    fi
fi

# Find latest executable file
unset latest
for file in "${1:-.}"/*
do
    if [[ -f "$file" ]]; then
        latest=${latest-$file}
        find "$file" -executable -prune -newer "$latest" | read -r dummy && latest=$file
    fi
done

if [[ -x "$latest" ]]; then
    ./$latest
else
    echo "Latest file $latest is not executable"
fi

Just put this script in your $PATH and map a key to execute it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM