Skip to content

Honor major-mode-remap-alist in php-mode-maybe#816

Merged
zonuexe merged 1 commit into
masterfrom
fix/honor-major-mode-remap
Jul 16, 2026
Merged

Honor major-mode-remap-alist in php-mode-maybe#816
zonuexe merged 1 commit into
masterfrom
fix/honor-major-mode-remap

Conversation

@zonuexe

@zonuexe zonuexe commented Jul 16, 2026

Copy link
Copy Markdown
Member

Interop fix for Emacs's built-in php-ts-mode (checked against Emacs 32.0.50).

The bug

php-ts-mode registers this on load:

;; To be able to toggle between an external package and core ts-mode:
(add-to-list 'treesit-major-mode-remap-alist '(php-mode . php-ts-mode))

and treesit-enabled-modes copies the entry into major-mode-remap-alist when the user opts in. So a user who installs this package and enables php-ts-mode is explicitly asking for php-ts-mode — Emacs core added that entry for our benefit.

They didn't get it for .php files. set-auto-mode applies the remapping to whatever auto-mode-alist names; entries pointing straight at php-mode honored it, but ".php"/".phtml" go through php-mode-maybe, which is not itself a remap target and called the derived mode directly. The result was inconsistent within the same configuration:

file auto-mode-alist resulting mode
a.stub php-mode remapped
a.php php-mode-maybe not remapped

The fix

Resolve the derived mode through major-mode-remap, so php-mode-maybe behaves as if auto-mode-alist had named the mode directly. major-mode-remap is Emacs 30+, hence the fboundp guard — on older Emacs the mode is used unchanged, exactly as before, so this is safe for the Emacs 27-supporting series.

A regression test is included. It uses a stub mode rather than php-ts-mode itself, so it does not depend on the PHP tree-sitter grammar being installed, and it is skipped where major-mode-remap does not exist. Verified that it fails before the fix and passes after.

What needed no change

php-base-mode is fine as-is. php-ts-mode declares php-mode an extra parent via derived-mode-add-parents, and our php-mode derives from php-base-mode, so once this package is loaded:

(derived-mode-all-parents 'php-ts-mode)
;; => (php-ts-mode php-mode php-base-mode prog-mode)

(derived-mode-p 'php-base-mode) already works in php-ts-mode buffers, and the php-base-mode docstring naming both modes is accurate. Note also that adding parents from our side would be actively harmful: derived-mode-add-parents replaces the extra-parents list, so it would clobber php-ts-mode's (php-mode) link.

Emacs's built-in php-ts-mode registers

    (add-to-list 'treesit-major-mode-remap-alist '(php-mode . php-ts-mode))

with the comment "To be able to toggle between an external package and
core ts-mode", and `treesit-enabled-modes' copies that entry into
`major-mode-remap-alist' when the user opts in.  So a user who installs
this package and enables php-ts-mode is asking for php-ts-mode.

They did not get it for .php files.  `set-auto-mode' applies the
remapping to whatever `auto-mode-alist' names, so entries pointing
straight at `php-mode' honored it, but ".php"/".phtml" go through
`php-mode-maybe', which is not itself a remap target and called the
derived mode directly.  The same buffer therefore opened in different
modes depending on the extension:

    a.stub   auto-mode-alist=php-mode        -> php-ts-mode   (remapped)
    a.php    auto-mode-alist=php-mode-maybe  -> php-mode      (not remapped)

Resolve the derived mode through `major-mode-remap' so `php-mode-maybe'
behaves as if `auto-mode-alist' had named the mode directly.  The
function is Emacs 30 or later, hence the `fboundp' guard; on older
Emacs the mode is used unchanged, as before.

Note that no adjustment is needed for `php-base-mode': php-ts-mode
declares `php-mode' as an extra parent via `derived-mode-add-parents',
and `php-mode' derives from `php-base-mode', so once this package is
loaded `derived-mode-all-parents' of php-ts-mode already resolves to
(php-ts-mode php-mode php-base-mode prog-mode).
@zonuexe
zonuexe force-pushed the fix/honor-major-mode-remap branch from 63422d6 to 82ab795 Compare July 16, 2026 14:34
@zonuexe
zonuexe merged commit deab481 into master Jul 16, 2026
14 checks passed
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