-
Notifications
You must be signed in to change notification settings - Fork 47
Smart completion
GMEdit can provide contextual syntax completion and syntax highlighting for variables and methods.
In contrast to Feather (which largely tries to figure out types on its own)
An [as of yet] unique feature of GMEdit is in being able to provide contextual syntax completion and syntax highlighting for variables and (2.3) methods.
The premise is as following: if GMEdit knows what a type of an expression is, it can offer you contextual auto-completion (e.g. only showing variables from a specific instance) and better error checking (e.g. warning about assigning a string into a numeric variable or using wrong argument types.
Types and fields are determined as following:
-
Local variables
Local variable types can be indicated usingvar v:T
shorthand syntax. -
Built-in functions and variables
GMEdit comes with type definitions (see/resources/app/api/shared/
) for majority of GMS2 functions and most GMS2 functions. -
User scripts and functions
Argument types can be indicated using@param
or shorthand syntax (function(a:T)
in GMS≥2.3,#args a:T
for older versions).
Return type can be indicated using@returns
or shorthand syntax (function(...)->ReturnType
) in GMS≥2.3. -
Object and struct variables
GMEdit will automatically pick up variable names declared at top-level (read: not inside{}
) within Create events and 2.3 constructors, including inheritance.
Variable types can be specified using@is
; additional variables can be indicated using@hint
or@implements
. "Implicit types" can be enabled in linter preferences to auto-derive non-ambiguous types. -
Global variables
GMEdit will automatically indexglobal.name
andglobalvar
declarations. Types can be similarly indicated using@is
. -
Macros
GMEdit is able to expand macros and derive types from code within. -
self
Type ofself
is automatically known in objects and constructors and objects but can be set using@self
.
(note: you can summon self-specific completions without self-prefix by typing a period.
out-of-context)
This is now a separate page because it was taking up half of this one.
Allows to explicitly cast an expression to a compatible type - such as casting int?
to int
or picking a specific one of either-types.
For example,
var sn:string|int = ...;
var i:int = is_string(sn) ? real(sn as string) : sn as int;
In saved file, this becomes a /*#as T*/
.
Allows to explicitly cast an expression to any
, bypassing type checks in cases where that might be necessary.
For example,
var s:string = argument0;
if (is_real(s)) s = string_format(cast s, 0, 3); // no warning
// ...
In saved file, this becomes a /*#cast*/
.
Allows to explicitly cast an expression to a type (including "incompatible" ones). Generally used in parenthesis, so typing
(cast buffer_read(b, buffer_s32) as obj_entity).
would show you auto-completion for variables from obj_entity
and check for errors accordingly.
Suppose you have obj_enemy
with the following Create event:
maxhealth = 10; // @is {number}
my_health = maxhealth; // @is {number}
my_target = noone; // @is {obj_entity}
// attack = function(target) {} // 2.3 method
After saving, if you were to type self.
anywhere in the object, you would only get the variables defined in Create event and the built-in variables rather than everything that you have in your project.
Similarly, if you were to type obj_enemy.
anywhere in the project, you would only get those same variables.
With above setup, if you were to write
var e:obj_enemy = instance_nearest(x, y, obj_enemy);
After saving, typing e.
would show you only the variables from obj_enemy
.
Note: if you are confident that you are writing good code, you can enable "Implicit types for local variables" in Preferences or Project Properties to have types auto-derived for variable declarations with initial values (var v = val
).
2.2: Suppose you had scr_enemy_ai
that would be called by obj_enemy
with the following
/// @self {obj_enemy}
self.my_target = instance_nearest(x, y, obj_player);
After saving, typing self.
would show you only the variables from obj_enemy
.
2.3 version (much the same, but JSDoc tags sit outside the functions now):
/// @self {obj_enemy}
function scr_enemy_ai() {
self.my_target = instance_nearest(x, y, obj_player);
}
Suppose you had a pair of functions that represent things that you might assign into constructors/objects:
/// @interface {IHorsable}
function scr_init_horsable() {
neigh = function(magnitude) { throw "not implemented!" }
}
/// @interface
function scr_twovars() {
oneVar = 1;
twoVar = 2;
}
(in 2.2, make that two scripts with /// @interface
inside the script and replace function(){} by another script)
You would then be able to mark them for inclusion in auto-completion and highlighting by doing the following in Create event of an object:
/// @implements {IHorsable}
scr_twovars(); /// @implements
myVar = "hi!";
Or, for constructors,
/// @implements {IHorsable}
function Some() constructor {
// ...
scr_twovars(); /// @implements
myVar = "hi!";
}
which would then show you myVar
, oneVar
, twoVar
, and neigh(magnitude)
when typing self.
.
- Like with most GMEdit features, you'll need to save (Ctrl+S) when adding/changing code that specifies types.
- For compatibility purposes, object references are not
object
ortype<obj_name>
, but justobj_name
. With almost allinstance_
functions taking either an object or an instance, this can only backfire ininstance_create[_depth|_layer]
(as you would be able to pass in an instance instead of an object). - When using
@hint A extends B
or constructor inheritance on types with parameters (@template
), child's first parameters must match up with parent's parameters.
- 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)