2

I'd like to add commands in my .vimrc programmatically in a function. For example, instead of hardcoding commands like this

command! MyCommand echom "My command"

I'd prefer to add them in a simple function like this

function! AddCommands()

  for commandName in ["One", "Two", "Three"]
    " TODO: Add a command with the given name that prints something
  endfor

endfunction

How can I add the commands One, Two, and Three using the for loop above?


Once I got that working, I want to read a file containing file paths and automatically create commands that open those files. I call that file "bookmarks file".

A line in the bookmarks file looks like this:

BookmarkName: /path/to/bookmarked/file.txt

Here's what I got so far:

" Read file paths from our bookmark file 
" and create a command for each bookmark that, when executed, opens the
" file in a new tab.
function! ReadBookmarks()
  let bookmarks = readfile(fnameescape($BOOKMARKS_FILE))
  let bookmarkSeparator = ": "
  for bookmark in bookmarks
    let nameAndPath = split(bookmark, bookmarkSeparator)
    let name = nameAndPath[0]
    let path = nameAndPath[1]

    " TODO: Add a command that opens the file in a new tab
  endfor
endfunction
  • 2
    This isn't even phrased as a question, and it is in no way clear that your own answer is the one you were looking for. – Karl Yngve Lervåg Jan 29 '17 at 17:15
  • Well, the TODO in the code makes clear what I was looking for, i.e., code that adds commands to Vim. – Matthias Braun Jan 30 '17 at 9:49
  • Yes. But this is a question/answer site. The question should not be implicit, it should be explicit. If you rephrase and improve the question, then I would vote to reopen. – Karl Yngve Lervåg Jan 30 '17 at 9:59
  • Fair enough, I'll update my question to make what I was asking for more explicit. – Matthias Braun Jan 30 '17 at 10:11
  • 2
    I voted to reopen because, after your edit, it seems pretty clear to me what you're asking. However, I think the title is still pretty misleading: a). I thought the question was going to be about how to persist changes made at runtime in your .vimrc b). What you're actually asking about (how to build ex-commands from variables using execute) is in no way specific to code that exists in the .vimrc. I also agree with @statox that a marginally less-contrived example would improve the question. – Rich Jan 30 '17 at 10:48
7

With execute

This does the trick:

function! AddCommands()

  for commandName in ["One", "Two", "Three"]
    " Adds a command that, when executed, prints its own name
    execute "command! " . commandName . " echom \"" . commandName . "\""
  endfor

endfunction

Now I can call, for example, :Three which will print

Three


The missing lines in the example involving the bookmarks file are thus:

let openFileCommand = "command! " . name . " :tabe " . path
execute openFileCommand

The whole example:

function! ReadBookmarks()
  let bookmarks = readfile(fnameescape($BOOKMARKS_FILE))
  let bookmarkSeparator = ": "
  for bookmark in bookmarks
    let nameAndPath = split(bookmark, bookmarkSeparator)
    let name = nameAndPath[0]
    let path = nameAndPath[1]

    " This adds a command that opens the file in a new tab
    let openFileCommand = "command! " . name . " :tabe " . path
    execute openFileCommand
  endfor
endfunction
  • 1
    I can't see a use case where this would be useful. You are still hardcoding the name of your command but in two separate place. And maybe this way to do it reduce your code when you have a lot of commands like this but once again it can't see a case where you'd need a lot of commands of this type. Could you give us a real world example? – statox Jan 30 '17 at 7:54
  • Sure, I added the code for which I actually used the programmatic definition of commands. – Matthias Braun Jan 30 '17 at 14:39
  • 2
    Thanks for your example, that's an interesting way to handle your bookmarks :) – statox Jan 30 '17 at 15:11
  • I am always happy to share! What's your way of handling bookmarks? Netrw, Nerdtree? – Matthias Braun Jan 30 '17 at 16:59
  • I don't use bookmarks, I use a combination of find and CtrlP To find my files and search my MRU and I have the mark 'V set on my vimrc. I don't use Netrw anymore because it was too buggy and NerdTree is bad ;) – statox Jan 30 '17 at 17:20

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.