ctags-lang-gdscript(7)

πŸ“¦ version 6.2.1, in ubuntu resolute, ubuntu stonking

ctags-lang-gdscript πŸ’–

okay bestie, so this is one of the manual pages from Universal Ctags, and it's the one all about tagging GDScript source code. It's literally just a lil collection of random notes, no cap β€” but they're the good notes, the ones that actually tell you how the parser behaves. πŸŽ€


✨ SYNOPSIS ✨

ctags ... --languages=+GDScript ...
ctags ... --language-force=GDScript ...
ctags ... --map-GDScript=+.gd ...

🌸 DESCRIPTION 🌸

This man page gathers random notes about tagging GDScript source code with Universal Ctags. That's it, that's the whole vibe. Lowkey iconic of it. πŸ’…


πŸ¦‹ Storing Annotations πŸ¦‹

So the Python parser stores decorations into the decorations field, right? Well the GDScript parser does the same lil trick but for annotations β€” anything starting with @ gets stored in a language-specific field called annotations. And here's the tea: even though the examples below explicitly enable the field, it's enabled by default anyway. So you don't gotta do anything. Slay. ✨

"input.gd"

@export
var s = "Hello"

@master
func f(msg):
        print(msg)

"output.tags" with --options=NONE --sort=no --fields-GDScript=+{annotations} -o - input.gd

s       input.gd        /^var s = "Hello"$/;"   v       annotations:export
f       input.gd        /^func f(msg):$/;"      m       annotations:master

🧚 Extracting func 🧚

When a language object is defined with the func keyword, it gets tagged with the method kind. And just like with annotations, the parser takes keywords that modify func β€” stuff like static β€” and tucks them into the annotations field. Obsessed with the consistency fr fr. πŸ’œ

"input.gd"

func f(x):
        return x

static func f_s(x):
        reutrn x

remote func f_r(x):
        return x
yes bestie, reutrn is really in there, we keep the source verbatim, no editing, periodt πŸ™ˆ

"output.tags" with --options=NONE --sort=no --fields=+K --fields-GDScript=+{annotations} -o - input.gd

f       input.gd        /^func f(x):$/;"        method
f_s     input.gd        /^static func f_s(x):$/;"       method  annotations:static
f_r     input.gd        /^remote func f_r(x):$/;"       method  annotations:remote

🌈 Tagging implicitly defined classes 🌈

In GDScript, the motto is literally "A file is a class!" A class is implicitly defined. Functions, variables, constants, and signals are all parts of that class β€” even though the class itself is unnamed by default. Main character energy but anonymous. πŸ’€

So if the language-specific extra implicitClass is enabled, the parser makes an anonymous tag for the class, and then it fills the scope fields of the tags for all language objects defined in the file with that anonymous tag. Cute, right? 🫢

Let's see an example demonstrating the effect of the extra.

Turning off the extra

"input.gd"

func f(x):
        return x

"output.tags" with --options=NONE --fields=+KZ --extras-GDScript=-{implicitClass} -o - input.gd

f       input.gd        /^func f(x):$/;"        method

Turning on the extra

"input.gd"

func g(x):
        return x

"output.tags" with --options=NONE --fields=+KZ --extras-GDScript=+{implicitClass} -o - input.gd

anon_class_84011bee0100 input.gd        /^func g(x):$/;"        class
g       input.gd        /^func g(x):$/;"        method  scope:class:anon_class_84011bee0100

πŸ‘‘ Tagging the name specified with class_name πŸ‘‘

class_name is the keyword that gives a name to that implicitly defined class we were just talking about. Here's how it goes down:

  • If implicitClass is turned off, the parser just extracts the name coming after the keyword with class kind.
  • If implicitClass is turned on, the parser converts the anonymous tag into a non-anonymous tag using the specified name. And when it converts, it also updates the scope fields of the other tags in the file.

Glow-up moment for the anonymous tag honestly. ✨

Turning off the extra

"input.gd"

class_name c

func f(x):
        return x

"output.tags" with --options=NONE --fields=+KZ --extras-GDScript=-{implicitClass} -o - input.gd

c       input.gd        /^class_name c$/;"      class
f       input.gd        /^func f(x):$/;"        method

Turning on the extra

"input.gd"

class_name C
func g(x):
        return x

"output.tags" with --options=NONE --fields=+KZ --extras-GDScript=+{implicitClass} -o - input.gd

C       input.gd        /^class_name C$/;"      class
g       input.gd        /^func g(x):$/;"        method  scope:class:C

πŸ’… Filling inherits field πŸ’…

The extends keyword specifies the super class for the implicitly defined class. And if the implicitClass extra is turned on, the parser fills the inherits field of the tag for that implicitly defined class with the name of the super class. It's giving lineage. 🌸

"input.gd"

extends B
class_name C

"output.tags" with --options=NONE --fields=+Ki --extras-GDScript=+{implicitClass} -o - input.gd

C       input.gd        /^class_name C$/;"      class   inherits:B

And when --extras=+r is given, the parser extracts the class specified with the extends keyword as a reference tag of class kind with the extended role. Look at it go. πŸ”₯

"input.gd"

extends B

"output.tags" with --options=NONE --fields=+rEK --extras=+r -o - input.gd

B       input.gd        /^extends B$/;" class   roles:extended  extras:reference

⭐ SEE ALSO ⭐


okay that's the whole page bestie, you ate it, you understood it, you're a GDScript tagging icon now πŸŽ€βœ¨

This was ctags-lang-gdscript(7) from Universal Ctags, version 6.2.1 β€” mwah, go tag something pretty. πŸ’–πŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from