One of the finest universities north of Prospect in Fort Collins

Jack Applin

PmWiki

Running Programs from Vim

Overview

Students are sometimes curious about how I run C or Java programs from vim during lecture. Basically, I map a key in vim to feed the current file to a script. This script compiles and executes the program.

Vim Mapping

I have this line in my ~/.vimrc:

    map [ :!run %<enter>

This means: Whenever the “[” key is pressed in command mode (as opposed to insert mode), execute the external command called “run”, with a single argument, the current filename. The “%” expands to the current filename. “<enter>” (literally, the word “enter” surrounded by “<>”) expands to the enter key.

You might want to also do this vim command, to automatically write out the current file whenever an external command is executed:

    :set autowrite

or

    :set aw

Otherwise, you’ll have to do “:w” before pressing the “[” key.

The Run script

I have a bash script in ~applin/bin/run. Feel free to copy it. It can be found by the vim mapping, since ~/bin is in my $PATH. You might want to put your copy in your ~/bin, since that’s in your $PATH by default.

It does the following:

  • Display the file with line numbers (for error messages).
  • Figure out the file type, based on the suffix or the file command.
  • Compile the file.
  • Exit if the compilation failed.
  • Execute the file.
  • Print an appropriate message, based on the exit code.
    #! /bin/bash

    # Show the file with line numbers so we can find compilation errors:

    clear
    expand "$@" | nl -ba -w2 -s' '
    echo                            # Space between the listing & output

    # Compile it:

    case "$1" in
    *.cc|*.cpp)
        g++ -g -Wall -Wextra -ansi -pedantic -D_GLIBCXX_DEBUG "$@" || exit
        ./a.out;;
    *.c)
        c99 -g -Wall -Wextra -pedantic -fstack-protector-all -O1 "$@" || exit
        ./a.out;;
    *.java)
        javac -Xlint:all "$@" || exit
        java ${1%.java};;
    *.php)
        php -f "$@";;
    [Mm]akefile)
        make;;
    *)
        # Is it a script?
        if [[ -x "$1" && $(file "$1") =~ " script " ]]
        then
            [[ "$1" =~ / ]] && "$1" || "./$1"
        else
            echo "Unknown file type \"$1\"" >&2
            exit 1
        fi;;
    esac

    exit_code=$?

    case $exit_code in
    0)   ;;
    129) echo Terminated with SIGHUP;;
    130) echo Terminated with SIGINT;;
    131) echo Terminated with SIGQUIT;;
    132) echo Terminated with SIGILL;;
    133) echo Terminated with SIGTRAP;;
    134) echo Terminated with SIGABRT;;
    135) echo Terminated with SIGBUS;;
    136) echo Terminated with SIGFPE;;
    137) echo Terminated with SIGKILL;;
    138) echo Terminated with SIGUSR1;;
    139) echo Terminated with SIGSEGV;;
    140) echo Terminated with SIGUSR2;;
    141) echo Terminated with SIGPIPE;;
    142) echo Terminated with SIGALRM;;
    143) echo Terminated with SIGTERM;;
    144) echo Terminated with SIGSTKFLT;;
    145) echo Terminated with SIGCHLD;;
    146) echo Terminated with SIGCONT;;
    147) echo Terminated with SIGSTOP;;
    148) echo Terminated with SIGTSTP;;
    149) echo Terminated with SIGTTIN;;
    150) echo Terminated with SIGTTOU;;
    151) echo Terminated with SIGURG;;
    152) echo Terminated with SIGXCPU;;
    153) echo Terminated with SIGXFSZ;;
    154) echo Terminated with SIGVTALRM;;
    155) echo Terminated with SIGPROF;;
    156) echo Terminated with SIGWINCH;;
    157) echo Terminated with SIGIO;;
    158) echo Terminated with SIGPWR;;
    159) echo Terminated with SIGSYS;;
    *)   echo Exit code is $exit_code;;
    esac

    exit $exit_code