-
Notifications
You must be signed in to change notification settings - Fork 47
Using template strings
Games commonly need to print formatted text and doing so in a convenient way is important.
Concatenating strings and wrapping non-string values in string()
is usually quickly established to not be a good flow, so people make string interpolation scripts (format("health: %/%", 1, 2)
-> health: 1/2
), but with a bit of preprocessing it is possible to make it even nicer.
First, you would to add a string interpolation script to your project.
These can be made arbitrarily complex, but here's a good starter with some optimization:
/// sfmt(format, ...values)
// sfmt("%/% hp", 1, 2) -> "1/2 hp"
gml_pragma("global", "global.sfmt_buf = buffer_create(1024, buffer_grow, 1); global.sfmt_map = ds_map_create();");
var f = argument[0];
var w = global.sfmt_map[?f], i, n;
if (w == undefined) {
w[0] = "";
global.sfmt_map[?f] = w;
i = string_pos("%", f);
n = 0;
while (i) {
w[n++] = string_copy(f, 1, i - 1);
f = string_delete(f, 1, i);
i = string_pos("%", f);
}
w[n++] = f;
} else n = array_length_1d(w);
//
var b = global.sfmt_buf;
buffer_seek(b, buffer_seek_start, 0);
buffer_write(b, buffer_text, w[0]);
var m = argument_count;
for (i = 1; i < n; i++) {
if (i < m) {
f = string(argument[i]);
if (f != "") buffer_write(b, buffer_text, f);
}
f = w[i];
if (f != "") buffer_write(b, buffer_text, f);
}
buffer_write(b, buffer_u8, 0);
buffer_seek(b, buffer_seek_start, 0);
return buffer_read(b, buffer_string);
Then, you would want to open your Project Properties (from menu or Ctrl+Shift+T), and put your string interpolation script name into "Template string script name" field (under "Syntax extensions").
From this point onward, any newly opened tabs can make use of the syntax.
This is simple enough, inside a backtick string you can use ${} to insert expressions,
show_debug_message(`2**4 = ${power(2, 4)}`); // 16
which would expand to
show_debug_message(your_script("2**4 = %", power(2, 4))); // 16
in the saved file;
If your expression is a single word/identifier, you can insert it without having to surround in {}:
show_debug_message(`x=$x, y=$y`);
which would expand to
show_debug_message(your_script("x=%, y=%",x,y));
If you want to insert ${
or $<word>
without it being parsed, you can do
show_debug_message(`... ${"$v"} ... ${"${"} ... %`);
which would expand to
show_debug_message(sfmt("... % ... % ... %", "$v", "${","%"));
- Smart auto-completion
- Types
- JSDoc tags (incl. additional ones)
- @hint tag (mostly 2.3)
- `vals: $v1 $v2` (template strings)
- #args (pre-2.3 named arguments)
- ??= (for pre-GM2022 optional arguments)
- ?? ?. ?[ (pre-GM2022 null-conditional operators)
- #lambda (pre-2.3 function literals)
- => (2.3+ function shorthands)
- #import (namespaces and aliases)
- v:Type (local variable types)
- #mfunc (macros with arguments)
- #gmcr (coroutines)