Jason
Jason

Reputation: 3917

Vim Create File(s) Using Template(s)

I'm tending to rely on vim more than a full IDE for working on projects, and one of the things I find myself doing on a regular basis is creating a new file(s) with derived values.

For example, creating a new c++ class involves creating a .hpp file and a .cpp file, adding file comments, the license, the author, ctor/dtor, copy, assign, move, etc...

.hpp

class %Object% {

public:

    explicit %Object%() = default;
    ~%Object%() = default;

    %Object%(%Object%&& rhs) = default;
    %Object%(const %Object%& rhs) = default;
    %Object%& operator=(%Object%&& rhs) = default;
    %Object%& operator=(const %Object%& rhs) = default;

protected:

private:

}

.cpp

#include "%Object%.hpp"

Another example would be a .h and a .c file in c.

I'm a little familiar with UltiSnips and muTemplate, which both seem to cut down on boilerplate a lot. However, I'm not clear if there's a way to use these, or something else, outside of a file scope. I wrote a really quick and dirty set of bash scripts to do it, and I'm getting ready to re-implement it in python, but I'd rather use an existing plugin.

Is there a way to do this with UltiSnips, muTemplate, or something else? If not, is there a good way to extend an existing plugin?

Upvotes: 0

Views: 865

Answers (2)

Luc Hermitte
Luc Hermitte

Reputation: 32926

Discl. I'm the maintainer of mu-template and lh-cpp. Unfortunately I'm just seeing your question now -- I would say that you shouldn't have hesitated to drop me an email/an issue/... I'm not sure the question is still opened. I'm not even sure to have exactly grasped what you were looking for.

Since the version you've experimented with, I've added many templates/snippets/wizards in lh-cpp to generate classes according to their semantics. You can now either:

  • expand things like value-class, base-class, etc
  • or call a function to expand the same wizard/snippet/template and give it parameters. For instance, expanding a value class with a pointer-like parameter will trigger the generation of the copy constructor and assignment operator (otherwise, they would be defaulted, explicitly or implicitly depending on options and on the C++ flavour detected (C++98/03, C++11 or more -- rule of all or nothing still has to be enforced). Alas this approach is not very ergonomic at the moment. I have to find a way to simplify this task. You can find example of use in the test/spec directory of lh-cpp.

Note that the c++ template for C++ files are also highly customizable -- on a per project basis. Usual licence texts are ready to include. A new C++ file knows how to include its associated header file (if detected).

Upvotes: 1

R Sahu
R Sahu

Reputation: 206557

Add this to one of your start up file:

" Function to substitute the class names in a file
function! SubstituteClassName()
   execute "1,$s/%Object%/" . expand("%:t:r") . "/g"
endfunction

" Function to create the skeleton of a header file
function! CreateHeaderFile()
  1
  insert
#pragma once
#ifndef %Object%_H
#define %Object%_H

class %Object% {

public:

    explicit %Object%() = default;
    ~%Object%() = default;

    %Object%(%Object%&& rhs) = default;
    %Object%(const %Object%& rhs) = default;
    %Object%& operator=(%Object%&& rhs) = default;
    %Object%& operator=(const %Object%& rhs) = default;

protected:

private:

}
.
  call SubstituteClassName()
endfunction

" Function to create the skeleton of a source file
function! CreateSourceFile()
  1
  insert
#include "%Object%.hpp"
.
  call SubstituteClassName()
endfunction

function! CreateClassFiles(name)

  " Open the header file.
  execute "edit " . a:name . ".hpp"
  " Create the skeleton of the header file
  call CreateHeaderFile()
  " Write the file
  wa

  " Open the source file.
  execute "edit " . a:name . ".cpp"
  " Create the skeleton of the header file
  call CreateSourceFile()
  " Write the file
  wa

endfunction

Now you can create the skeleton .hpp and .cpp files using

call CreateClassFiles("myclassname")

Upvotes: 0

Related Questions