How can I Insert the result of a ".w" evaluation at the end of a line in Vim?

5

I'd like to be able to evaluate a line of Javascript (or other code) in Vim, and have the result appear in a comment at the end of the line.

For example, if I have a file like:

console.log(4 + 5);

and my cursor is on that line, and I use the command :.w !node -e, the result "9" will appear in the buffer below. if I use :. !node -e, the whole line will be replaced with the result, 9.

How can I instead create a command that will append the result to the line's end in a comment, like so:

console.log(4 + 5);    // 9

Also of note is that using :r will print whatever is passed to it in the next line. r !echo "This is text." will insert "This is text." on the line below the cursor. However a command like...

:r ". !node -e"

...will try to read ". !node -e" as a file instead of a command; I don't really understand this behavior, but it makes things a bit less intuitive.

I'd like the end result to be somewhat reminiscent of the way the Atom text editor handles Hydrogen kernels, with the result of the code eval appearing at the left of the code. The plan is to create a keybinding (<C-Enter> or <F5>) to auto-evaluate the current line and display the result.

diplomaticDeveloper

Posted 2018-07-24T04:15:32.093

Reputation: 173

Answers

3

If your lines look like: 4+5= you could use something like:

 :map  "_ay/=^Mo^[!!echo ^Ra \| bc^MkJ
  1. _ ............... to jump to start of actual line
  2. "ay/=^M ... to yank till = into buffer a
  3. o^[ ........... make a new empty line
  4. !! .............. start a shell program to write result into this new line
  5. ^Ra .......... insert content of buffer a in comand: echo ^Ra \| bc^M
  6. k .............. go to pevious line
  7. J .............. join next line (result) to aktual line
  8. perhaps you want to delete blank from joining with x

I hope this is what you are .

Horst

Posted 2018-07-24T04:15:32.093

Reputation: 46

Oh wow, this works almost perfectly! Now I just need to find a way to adapt it to analyzing code. Is there a way to have this read to the end of the line, and then pipe the line to node or python3 instead? I'll set as the accepted answer once I figure out how to do that, as this technically doesn't answer my question exactly. That said, it's pretty dang close! – diplomaticDeveloper – 2018-07-26T04:02:59.340

To add to this, I think you have the first two characters of the command swapped around; it should be _"ay/.... – diplomaticDeveloper – 2018-07-26T04:46:25.927

2

Thanks to Horst's suggestion, I was able to parse how to get Vim to do this with any language that has an "evaluate" command line option. For JavaScript, the command I put together is as follows:

imap <F5> ^[_"ay$o//^[kJo^[!!node -e "^Ra"^MkJi
nmap <F5> _"ay$o//^[kJo^[!!node -e "^Ra"^MkJ

For a breakdown:

  1. For INSERT mode mapping, Escape (^[) returns to normal mode.
  2. _"ay$ places the whole line into register a.
  3. o//^[kJ adds the "//" for a comment.
  4. o^[ starts another new line.
  5. !!node -e "^Ra"^M runs the register (the line) through Node.js and returns the result on the current line.
  6. Finally, kJ pulls this new line back up to the first to become the comment.
  7. (For INSERT mode, i returns the mode from NORMAL to INSERT again.)

The same can be done for Python with a few minor edits:

imap <F5> ^[_"ay$o#^[kJo^[!!python -c "import math; ^Ra"^MkJi
nmap <F5> _"ay$o#^[kJo^[!!python -c "import math; ^Ra"^MkJ

For this, the // comment is replaced with Python's #. In addition, I automatically import the math module, as it can be very useful for quick calculations that way.

My recommendation is to place each of these mappings in their own respective ~/.vim/ftplugin/<language>.vim files, and place set ftplugin on in your .vimrc. This allows the mapping to change based on which language you're working with!

I hope that anyone who wants to run code interactively in Vim can find this and possibly even improve on it. A huge "Thank you!" goes to Horst for answering this question and kick-starting this little project!

diplomaticDeveloper

Posted 2018-07-24T04:15:32.093

Reputation: 173