-1

In vim, version 8.1, I need to use a shell command, not on a constant text, but containing a vim variable.

e.g. in Ex cmdline display by echo the difference in years from current date to a given date (hard coded 2000 - because I know no solution to apply the variable), reduced by 20.

let date_given_vim="1990-01-01"
exec '!echo $(( (date_given_sh="2000-01-01"; $(date "+\%Y") - $(date "+\%Y") --date="$date_given_sh") )) >/tmp/vim_aux'
let aux_a=join(readfile('/tmp/vim_aux'))
let aux_b=aux_a - 20
echo aux_b

In the shell command line the variable data_given_vim ought to be assigned to data_given_sh.

But I do not know how to accomplish this.

Also here another bad feature of vim is seen: the output of the !{cmd} cannot be assigned to a vim variable.

2
  • Welcome to Vi and Vim!
    – filbranden
    Apr 28 at 8:08
  • 1
    Since you are already using exe why not simply add the variable in the command like exe '!echo $( ' . date_vim . ') ...'? Also you are wrong about the output of a command not being assignable to a variable see here and there and finally How to export information from vim to bash which is probably a duplicate.
    – statox
    Apr 28 at 8:25
1

To answer your direct question, you can use the :let command to set a shell variable from Vim directly, using the $ prefix on the variable name. That's probably the most straightforward way to do so, even though it ends up creating an exported variable.

So:

let $date_given_sh = date_given_vim

Or even:

let $date_given_sh = "2000-01-01"

See :help :let-$ for more details. Note also that you can read shell variables inside Vim using the $ prefix, in most contexts.

As for the second part, reading back the contents of the external command, you can use the system() or systemlist() function to run an external command and return the captured output. Such as in:

let aux_a = system('echo $(( $(date "+\%Y") - $(date "+\%Y" --date="$date_given_sh") ))')

See :help system() and :help systemlist() for more details. Note that in Vimscript it's often more convenient to use systemlist() to capture the output as a list of lines and then use list operations on the lines.

And finally, note that you can perform most date conversions within Vim itself, without the need to shell out. For example, to convert from your date format to a Unix date (in seconds from the Unix epoch), then extract the year only, you can use:

:let date = strptime('%Y-%m-%d', '1990-01-01')
:echo date
631180800
:echo strftime('%Y', date)
1990
:echo strftime('%Y', date) - 20
1970

See :help strptime() and :help strftime() for more details on the date functions to parse and format dates available in Vimscript.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.