2021-12-07

A Simple Python Code-Runner in VIM

A Vim filter is a program that accepts text at standard input, changes it in some way, and sends it to standard output (from :h filter). It can be a shell program, like sort, sed, or tr. As shown below, for instance, it's possible to remove all digit characters inside a buffer with:

   :%! tr -d 0-9

A filter can also be as simple as a Python script, I have recently written one that can run Python code snippets directly within a VIM buffer.

This was achieved without special plugins or temporary files, by including either in the local or global .vimrc the following two lines:

    let @p='y}}Pv}'  " <--- Macro
    nnoremap <leader><Space> @p:! ~/bin/coderunner.py<CR>2j "<-- execute macro and filter
    

The macro duplicates a paragraph and then it selects in visual mode the duplicated paragraph. Pressing the leader ( the backslash \ in my configuration) and the space key together, will run the macro and pass the selection to the filter.

Below the entire Python script coderunner.py.

    #!/usr/bin/env python
    # filename : coderunner.py
    from sys import stdin
    import subprocess
    paragraph=[]
    for line in stdin:
        paragraph.append(line)
    p = subprocess.Popen(['python', '-c', '\n'.join(paragraph)],
                         stdout=subprocess.PIPE, bufsize=1,
                         universal_newlines=True)
    output = ""
    output_buf = p.stdout.readline()
    while output_buf:
        print(output_buf, end="")
        output += output_buf
        output_buf = p.stdout.readline()

    print("\n") # end with a new line