A Neovim plugin for automatically sorting and organizing PHP code elements using Tree-sitter.
- Sort namespace use statements alphabetically
- Remove unused imports automatically
- Sort class properties by visibility (private, protected, public)
- Sort constants alphabetically
- Sort trait uses alphabetically
- Smart spacing between elements (configurable)
- LSP integration with code actions
- Preview changes before applying
- Neovim >= 0.9.0
- nvim-treesitter
- Tree-sitter PHP parser (
:TSInstall php)
{
'RicardoRamirezR/php-elements-sorter.nvim',
dependencies = {
'nvim-treesitter/nvim-treesitter',
},
ft = 'php',
config = function()
require('php-elements-sorter').setup()
end,
}use {
'RicardoRamirezR/php-elements-sorter.nvim',
requires = { 'nvim-treesitter/nvim-treesitter' },
ft = 'php',
config = function()
require('php-elements-sorter').setup()
end
}require('php-elements-sorter').setup({
-- Add blank line when visibility changes (private -> public)
add_visibility_spacing = true,
-- Sort class properties
sort_properties = true,
-- Sort trait uses
sort_traits = true,
-- Sort namespace use statements
sort_namespace_uses = true,
-- Sort constants
sort_constants = true,
-- Default visibility for elements without explicit visibility
default_visibility = 'public', -- 'public' | 'protected' | 'private'
-- Remove unused namespace use statements
remove_unused_imports = true,
-- Add newline between constants and properties
add_newline_between_const_and_properties = true,
-- Add newline after namespace use statements
add_newline_after_namespace_uses = true,
-- Add newline after trait uses
add_newline_after_trait_uses = true,
-- Enable debug logging
debug = false,
-- Auto-sort on save (disabled by default)
auto_sort_on_save = false,
})local bufnr = vim.api.nvim_get_current_buf()
require('php-elements-sorter').set_buffer_config(bufnr, {
sort_properties = false,
debug = true,
})| Command | Description |
|---|---|
:SortPhpElements |
Sort all PHP elements (uses, traits, properties, constants) |
:SortPhpNamespaceUses |
Sort only namespace use statements |
:SortPhpClassElements |
Sort only class elements (properties, constants, traits) |
:RemoveUnusedUses |
Remove unused use statements |
:SortPhpElementsPreview |
Preview all sorting changes before applying |
:SortPhpNamespaceUsesPreview |
Preview namespace use sorting |
:SortPhpClassElementsPreview |
Preview class element sorting |
Diagnostic commands:
| Command | Description |
|---|---|
:PhpSorterInfo |
Show plugin diagnostic information |
:PhpSorterCleanup |
Clean up invalid buffer states |
:PhpSorterValidateConfig |
Validate current configuration |
:PhpSorterTimerStats |
Show timer statistics |
local sorter = require('php-elements-sorter')
-- Sort all elements
local stats = sorter.sort_all()
-- returns { uses, removed, constants, properties, traits }
-- Sort specific elements
sorter.sort_namespace_uses()
sorter.sort_elements()
sorter.remove_unused_uses()
-- Preview before applying
sorter.preview_all()
sorter.preview_namespace_uses()
sorter.preview_elements()The plugin integrates with Neovim's LSP to provide code actions in PHP files:
- Place cursor in a PHP file
- Trigger code actions:
:lua vim.lsp.buf.code_action() - Select from available actions:
- Sort namespace uses
- Remove unused use statements
- Sort properties/constants/traits
- Sort all PHP elements
vim.keymap.set('n', '<leader>ps', '<cmd>SortPhpElements<CR>', { desc = 'Sort PHP elements' })
vim.keymap.set('n', '<leader>pu', '<cmd>SortPhpNamespaceUses<CR>', { desc = 'Sort PHP uses' })
vim.keymap.set('n', '<leader>pr', '<cmd>RemoveUnusedUses<CR>', { desc = 'Remove unused uses' })
vim.keymap.set('n', '<leader>pp', '<cmd>SortPhpElementsPreview<CR>', { desc = 'Preview PHP sorting' })<?php
use Zebra\Animal;
use Apple\Fruit;
use Banana\Fruit;
class Product
{
const STATUS_INACTIVE = 0;
const STATUS_ACTIVE = 1;
public $name;
private $id;
protected $description;
private $price;
public $category;
}<?php
use Apple\Fruit;
use Banana\Fruit;
use Zebra\Animal;
class Product
{
const STATUS_ACTIVE = 1;
const STATUS_INACTIVE = 0;
private $id;
private $price;
protected $description;
public $category;
public $name;
}What changed:
- Use statements sorted alphabetically
- Constants sorted alphabetically
- Properties sorted by visibility (private, protected, public)
- Blank lines between visibility groups
- Blank line between constants and properties
-
Check PHP parser is installed:
:TSInstall php :checkhealth nvim-treesitter -
Enable debug logging:
require('php-elements-sorter').setup({ debug = true })
-
Check plugin state:
:PhpSorterInfo
-
Verify LSP is running:
:LspInfo
-
Check code action support:
local clients = vim.lsp.get_clients({ bufnr = 0 }) for _, client in ipairs(clients) do print(client.name, client.supports_method('textDocument/codeAction')) end
# Run all tests
nvim --headless -c "PlenaryBustedDirectory lua/tests/"
# Run specific test file
nvim --headless -c "PlenaryBustedFile lua/tests/result_pattern_spec.lua"- Fork the repository
- Create a feature branch
- Run tests
- Open a Pull Request
git clone https://github.com/RicardoRamirezR/php-elements-sorter.nvim.git
cd php-elements-sorter.nvim
# Install dependencies for testing
git clone https://github.com/nvim-lua/plenary.nvim.git ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim
git clone https://github.com/nvim-treesitter/nvim-treesitter.git ~/.local/share/nvim/site/pack/vendor/start/nvim-treesitter
# Run tests
nvim --headless -c "PlenaryBustedDirectory lua/tests/"MIT License - see LICENSE for details.