8000 Fontify the names of struct fields by 1buran · Pull Request #454 · dominikh/go-mode.el · GitHub
[go: up one dir, main page]

Skip to content

Fontify the names of struct fields - #454

Open
1buran wants to merge 1 commit into
dominikh:masterfrom
1buran:fontify-struct-field-names
Open

1buran wants to merge 1 commit into
dominikh:masterfrom
1buran:fontify-struct-field-names

Conversation

@1buran
@1buran 1buran commented Oct 8, 2026 •
Copy link
Copy Markdown

Part of #453 (the declaration half): the use side is left alone, see below.

What changes

Struct field names are fontified with font-lock-property-name-face:

type Film struct {
	Countries, Directors, Genres, Cast []string
	Desc, Time, Translate, FileType    string
}

This is the face Emacs 29 added for the purpose (NEWS.29: "New faces
for font-lock ... primarily meant for use with tree-sitter") and the one
go-ts-mode already uses:

(field_declaration name: (field_identifier) @font-lock-property-name-face)

How it works

A field name is an identifier that starts a field declaration -- it is
at the beginning of a line, or follows a comma or a semicolon -- and is
followed by the type of the field on the same line. Requiring the type
is what keeps

  • embedded fields, i.e. a type with no name such as io.Reader, unfontified;
  • qualified types (io.Reader after a name) as they were;
  • composite literal keys (foo: 1) and comments untouched.

Names of a field list are matched one by one, so the commas between them
keep their own face.

Tests

go--should-fontify gained a P marker for the new face. Three tests
covered struct fields (go--fontify-struct, go--fontify-type-switch
and go--fontify-var-decl); they now expect the name to be fontified,
and the struct test additionally covers a name list, a field whose type
starts with a keyword (chan), a slice type and an embedded field.

All 31 tests pass, and byte-compilation reports the same 13 warnings as
master.

Not in this PR

The use side of #453 -- film.Title in an expression -- is left alone.
Unlike a declaration, the field of a selector cannot be told apart from
a qualified type (foo.Zebra) without looking at the context, and
go-mode fontifies foo.Zebra as a type today. That is a separate
decision, and this PR does not change any existing fontification: over
95 Go files the only difference is 435 characters gaining the new face,
with nothing losing a face.

Performance

Fontifying those 95 files (10 passes, best pass, font-lock-ensure
alone) goes from 0.348s to 0.387s, about 11%. The matcher fires for
every identifier that starts a field declaration and checks
go--in-struct-definition-p once per candidate -- the same shape as
go--match-decl and go--containing-decl.

A field of a struct is now fontified with
`font-lock-property-name-face', the face Emacs 29 added for exactly
this and the one `go-ts-mode' uses for field declarations.

The names of a field are the identifiers at the start of the field
declaration, followed by its type on the same line.  A field that
consists of a type alone is embedded and has no name, so it is left
alone, and so are qualified names such as "io.Reader".

Selector expressions such as "film.Title" are not affected: there
the field is a use rather than a declaration.

The new face is only used when it exists, so Emacs 26 still works.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0