Code Templates
This article is about code templates, in JetBrains IDEs they are called Live Templates. You write a keyword, and the IDE outputs code associated with it. It can speed up code writing if you have well-defined templates that are easy to remember between multiple languages.
For example, you may define a keyword fori
. To write a loop, one only types:
fori TAB 20 TAB
If the language is Python, it will output
for i in range(20):
$END$
and if it is in C#, the result is
for (int i = 0; i < 20; i++) {
$END$
}
This article describes the shortcuts I use, and it targets TypeScript, C# and Haskell. I recommend you design a system that suits you, it will help in learning a new language.
When defining the templates, refer to your IDE's documentation e.g. in JetBrains IDEs they should be $TEMPLATE_ARG$
.
Below examples, I prefix the variables with t_
to ensure that syntax highlighting works as expected.
Basic types
You may also define syntax for basic types, but I myself find it easier to just type them out. Some types could be
Type | Abbreviation | Example template |
---|---|---|
integer | tint | int t_NAME = t_END; |
decimal | tdec | decimal t_NAME = t_END; |
boolean | tbool | bool T_NAME = t_END; |
A more complex data structures are usually suggested by intellisense and named similarly (e.g. Stack is Stack, and Tree is Tree) so there shouldn't be difficulty in finding them.
Loops
The loops are commonly using a keyword for
. In functional languages, it may not exist and loops are typically constructed by recursion.
Iterate with index fori
tfori $VAR$ TAB $MAX$ TAB
Iterate all fore
It is also common to iterate all items in a collection such as lists, commonly denoted with foreach
.
tfore $ITEM$ TAB $COLLECTION$ TAB
Mappings map
Mapping is commonly used in functional languages, and the syntax is typically so.
tmap $COLLECTION$ TAB $ITEM$ TAB
Control Structures
Common control structures are if
and switch
, some languages such as Haskell supports a guard -syntax.
If conditions
This is usually predefined and looks almost same, also else
statements.
if $CONDITION$ TAB
if (t_CONDITION)
{
t_END
}
Switches and guards switch
A common C-like switch case is used on object-oriented languages. However, C# also support a guard-like syntax for switch.
tswitch $VARIABLE$ TAB $DEFAULT_CASE$ TAB
Functions
The kind of functions used in everyday programming are usually generic functions, lambda functions, extension functions, and class methods. The function templates shouldn't include documentation since, there are separate templates for them.
The normal methods have a predefined templates and lambdas are usually trivial so we only need to define templates for generic functions. Template functions, if the language supports it
Generic fng
With generics, the less types the better. So this, thing defaults to one argument and following the naming conventions it is a single letter T
.
MODIFIERS tfng $RETURN_TYPE$ TAB $NAME$ TAB $ARGUMENTS$
Extension method fne
As far as I know C# and Java has extension methods
tfne $RETURN_TYPE$ $NAME$ TAB $EXTENDS_TYPE$ TAB $ARGUMENTS$
public static t_RETURN_TYPE t_NAME(this t_EXTENDS_TYPE instance, t_ARGUMENTS) {
t_END
}
Type definitions
The class
itself, enum
, and type aliases are usually used as type. They are conviently defined as File Templates where
are bare definition is added when file is created.
Since, the "best practice" is to put class per file, there is no need to define abbreviations for them.
Web Development
Some in online communities describe web development being similar and "just CRUD". In some ways, it is true since most applications have same features e.g. email authentication, subscriptions, etc.
Most importantly a boilerplate need to be define every time an endpoint is defined!
Since they vary wildly by web framework in use, you should prefix them with the name of framework e.g. djcreate
for Django abbreviation for apicreate
. Because it would conflict if you define them in Python and also use FastAPI.
API operations
Similarly as this create, you can define them for other CRUD operations list, delete, and update.
tapicreate $RESPONSE$ TAB $REQUEST$ TAB
Testing
I think the values comes with assertions e.g. the object comparison need to be deep comparison which compares the attributes.
For example, Chai would assert it as expect(a).deep.equal(b)
but jest does it by default expect(a).toEqual(b)
.
By defining common assertions as templates, you don't need to memorize the backend framework assertion and different frontend assertions. There is potentially three different ways: end-to-end (Puppeteer, Cypress), unit (Jest, Mocha-Chai), and backend tests (XUnit).