Bit late to this question, but I've got a slightly more involved solution that'll handle this without the need for manual post-processing regardless of file extension:
- Head into your File and Code Templates - The other answers already detail how to do this.
- In the File and Code Templates settings page, change to the Includes tab.
- Click the
+
to create a new Include template. Name it something like IncludeGuard
and set the Extension to h
.
- Input the following for the contents. Make sure you don't include any blank lines before or after.
#macro( includeGuard $filename $ext )
#set( $ucfull = ${filename.toUpperCase().replace('-', '_')} )
#set( $extidx = ${ucfull.lastIndexOf(".")} )
#set( $extstart = $extidx + 1 )
#if( $extidx > -1 )
#set( $ucname = ${ucfull.substring(0,$extidx)} )
#set( $ucext = ${ucfull.substring($extstart)} )
#else
#set( $ucname = $!{ucfull} )
#set( $ucext = ${ext.toUpperCase()} )
#end
${ucname}_${ucext}##
#end##
- Change back to the Files tab, and find the
C Header File
or C++ Class Header
file depending on which language you're looking to update.
- Change the contents of this file template to:
#parse("IncludeGuard.h")##
#set( $blank = "" )
#[[#ifndef]]# #includeGuard(${NAME} "h")${blank}
#[[#define]]# #includeGuard(${NAME} "h")${blank}
// ...
#[[#endif]]# // #includeGuard(${NAME} "h")
If everything works as intended, attempting to create a C Header File using the name test-include-guard
or test-include-guard.h
should both result in the following:
#ifndef TEST_INCLUDE_GUARD_H
#define TEST_INCLUDE_GUARD_H
// ...
#endif /* TEST_INCLUDE_GUARD_H */
Few notes:
- If you need to change the file extension, change the
includeGuard(${NAME} "h")
parts to use whatever extension you want for the second parameter. The template will attempt to parse the file extension from ${NAME}
, but ${NAME}
only contains the file extension if you explicitly enter it into the new filename dialog.
- The current state of whitespace handling in the Velocity templates used by CLion is a shit show, so you'll need to work around this as I did if you decide to further customize the templates. General guidelines:
- If you're experiencing undesired linebreaks, you'll want to try adding a terminating line comment
##
to the ends of lines before it.
- If you find yourself in the oppostie scenario, (missing an expected linebreak) you can work around this with the
#set( $blank = "" )
strategy I utilized above.
- Most of the IntelliJ-based IDEs seem to cache the compilation of Include templates the first time they get passed into
#parse()
. If you make changes to an Include template after this point, you'll usually need to use the File > Invalidate Caches/Restart menu command before the changes propagate.
FILENAME_H
, it is not that rare to have multiple files with the same name in a project. – Litigable#pragma once
instead of the#ifndef
include guards. The template used for header file creation can be changed underSettings->Editor->File and Code Templates
. – Keynote#define
compilation is faster. And#pragma once
is not a part of pre-C++11 versions of standard. I don't believe${PROJECT}_${FILE}_H
is hardcoded in CLion. – Retinoscope<FILENAME>_<EXT>_INCLUDED_<YYYYMMDD>
. When I happen to write2d/Vector.hh
and3d/Vector.hh
on the same day, I spontaneously add something additional, like wall time (VECTOR_HH_INCLUDED_20181003_1953
) or folder (MATH_2D_VECTOR_HH_INCLUDED_20181003
). Of course it's still not perfect (some library may also come withVECTOR_HH_INCLUDED_20181003
), but in reality, the vector-example is the only incident that happened to me. TheINCLUDED
part is just for aesthetics. – Arched