Skip to content

Commit 0d53a53

Browse files
committed
feat(lualine): add global variables API for lazy-loading support
- Add vim.g.mcphub_status, vim.g.mcphub_servers_count, vim.g.mcphub_executing - Move state tracking logic from lualine extension to hub core - Update documentation with recommended global variables approach - Deprecate full lualine component with warning - Support spinners during hub startup/restart and execution - Show '-' when hub is stopped or not loaded Fixes #208
1 parent ad4d04d commit 0d53a53

5 files changed

Lines changed: 196 additions & 18 deletions

File tree

doc/extensions/lualine.md

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,82 @@
11
# Lualine Integration
22

3-
MCP Hub provides a lualine component that can be used to show the status of the MCP Hub and the number of connected servers. Add the component to a lualine section to use it. The following example shows how to add the component to the `lualine_x` section:
3+
MCP Hub provides multiple ways to integrate with lualine, with the recommended approach using global variables for optimal lazy-loading support.
4+
5+
## Recommended: Global Variables Approach
6+
7+
Use MCPHub's global variables for a lightweight, lazy-load friendly component:
48

59
```lua
610
require('lualine').setup {
711
sections = {
812
lualine_x = {
9-
-- Other lualine components in "x" section
10-
{require('mcphub.extensions.lualine')}, -- Uses defaults
13+
{
14+
function()
15+
-- Check if MCPHub is loaded
16+
if not vim.g.loaded_mcphub then
17+
return "󰐻 -"
18+
end
19+
20+
local count = vim.g.mcphub_servers_count or 0
21+
local status = vim.g.mcphub_status or "stopped"
22+
local executing = vim.g.mcphub_executing
23+
24+
-- Show "-" when stopped
25+
if status == "stopped" then
26+
return "󰐻 -"
27+
end
28+
29+
-- Show spinner when executing, starting, or restarting
30+
if executing or status == "starting" or status == "restarting" then
31+
local frames = { "", "", "", "", "", "", "", "", "", "" }
32+
local frame = math.floor(vim.loop.now() / 100) % #frames + 1
33+
return "󰐻 " .. frames[frame]
34+
end
35+
36+
return "󰐻 " .. count
37+
end,
38+
color = function()
39+
if not vim.g.loaded_mcphub then
40+
return { fg = "#6c7086" } -- Gray for not loaded
41+
end
42+
43+
local status = vim.g.mcphub_status or "stopped"
44+
if status == "ready" or status == "restarted" then
45+
return { fg = "#50fa7b" } -- Green for connected
46+
elseif status == "starting" or status == "restarting" then
47+
return { fg = "#ffb86c" } -- Orange for connecting
48+
else
49+
return { fg = "#ff5555" } -- Red for error/stopped
50+
end
51+
end,
52+
},
1153
},
1254
},
1355
}
1456
```
1557

58+
### Available Global Variables
59+
60+
MCPHub automatically maintains these global variables:
61+
- `vim.g.loaded_mcphub` - Whether MCPHub plugin is loaded (set by plugin loader)
62+
- `vim.g.mcphub_status` - Current hub state ("starting", "ready", "stopped", etc.)
63+
- `vim.g.mcphub_servers_count` - Number of connected servers
64+
- `vim.g.mcphub_executing` - Whether a tool/resource is currently executing
65+
66+
67+
## Legacy: Full Component (Loads MCPHub) - DEPRECATED
68+
69+
**⚠️ DEPRECATED**: This approach will load MCPHub even with lazy loading enabled and shows a deprecation warning. Use the global variables approach above instead.
70+
71+
```lua
72+
require('lualine').setup {
73+
sections = {
74+
lualine_x = {
75+
{require('mcphub.extensions.lualine')}, -- Uses defaults
76+
},
77+
},
78+
}
79+
```
1680

1781
#### When MCP Hub is connecting:
1882

@@ -26,10 +90,7 @@ require('lualine').setup {
2690

2791
![image](https://github.com/user-attachments/assets/f6bdeeec-48f7-48de-89a5-22236a52843f)
2892

29-
30-
## Usage
31-
32-
#### Options
93+
### Legacy Component Options
3394

3495
The lualine component accepts the standard lualine options and the following options:
3596
- `icon`: Icon to display. (default: `"󰐻"`)

doc/mcphub.txt

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*mcphub.nvim.txt* For NVIM v0.10.0 Last change: 2025 July 18
1+
*mcphub.nvim.txt* For NVIM v0.10.0 Last change: 2025 July 19
22

33
==============================================================================
44
Table of Contents *mcphub.nvim-table-of-contents*
@@ -3372,16 +3372,84 @@ Resources from MCP servers will also be available as CopilotChat variables `#`.
33723372

33733373
LUALINE INTEGRATION *mcphub.nvim-extensions-lualine-integration*
33743374

3375-
MCP Hub provides a lualine component that can be used to show the status of the
3376-
MCP Hub and the number of connected servers. Add the component to a lualine
3377-
section to use it. The following example shows how to add the component to the
3378-
`lualine_x` section:
3375+
MCP Hub provides multiple ways to integrate with lualine, with the recommended
3376+
approach using global variables for optimal lazy-loading support.
3377+
3378+
3379+
RECOMMENDED: GLOBAL VARIABLES APPROACH ~
3380+
3381+
Use MCPHub’s global variables for a lightweight, lazy-load friendly
3382+
component:
3383+
3384+
>lua
3385+
require('lualine').setup {
3386+
sections = {
3387+
lualine_x = {
3388+
{
3389+
function()
3390+
-- Check if MCPHub is loaded
3391+
if not vim.g.loaded_mcphub then
3392+
return "󰐻 -"
3393+
end
3394+
3395+
local count = vim.g.mcphub_servers_count or 0
3396+
local status = vim.g.mcphub_status or "stopped"
3397+
local executing = vim.g.mcphub_executing
3398+
3399+
-- Show "-" when stopped
3400+
if status == "stopped" then
3401+
return "󰐻 -"
3402+
end
3403+
3404+
-- Show spinner when executing, starting, or restarting
3405+
if executing or status == "starting" or status == "restarting" then
3406+
local frames = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" }
3407+
local frame = math.floor(vim.loop.now() / 100) % #frames + 1
3408+
return "󰐻 " .. frames[frame]
3409+
end
3410+
3411+
return "󰐻 " .. count
3412+
end,
3413+
color = function()
3414+
if not vim.g.loaded_mcphub then
3415+
return { fg = "#6c7086" } -- Gray for not loaded
3416+
end
3417+
3418+
local status = vim.g.mcphub_status or "stopped"
3419+
if status == "ready" or status == "restarted" then
3420+
return { fg = "#50fa7b" } -- Green for connected
3421+
elseif status == "starting" or status == "restarting" then
3422+
return { fg = "#ffb86c" } -- Orange for connecting
3423+
else
3424+
return { fg = "#ff5555" } -- Red for error/stopped
3425+
end
3426+
end,
3427+
},
3428+
},
3429+
},
3430+
}
3431+
<
3432+
3433+
3434+
AVAILABLE GLOBAL VARIABLES
3435+
3436+
MCPHub automatically maintains these global variables: - `vim.g.loaded_mcphub`
3437+
- Whether MCPHub plugin is loaded (set by plugin loader) -
3438+
`vim.g.mcphub_status` - Current hub state ("starting", "ready", "stopped",
3439+
etc.) - `vim.g.mcphub_servers_count` - Number of connected servers -
3440+
`vim.g.mcphub_executing` - Whether a tool/resource is currently executing
3441+
3442+
3443+
LEGACY: FULL COMPONENT (LOADS MCPHUB) - DEPRECATED ~
3444+
3445+
**⚠️ DEPRECATED**: This approach will load MCPHub even with lazy loading
3446+
enabled and shows a deprecation warning. Use the global variables approach
3447+
above instead.
33793448

33803449
>lua
33813450
require('lualine').setup {
33823451
sections = {
33833452
lualine_x = {
3384-
-- Other lualine components in "x" section
33853453
{require('mcphub.extensions.lualine')}, -- Uses defaults
33863454
},
33873455
},
@@ -3398,10 +3466,7 @@ WHEN CONNECTED SHOWS NUMBER OF CONNECTED SERVERS:
33983466
WHEN A TOOL OR RESOURCE IS BEING CALLED, SHOWS SPINNER:
33993467

34003468

3401-
USAGE ~
3402-
3403-
3404-
OPTIONS
3469+
LEGACY COMPONENT OPTIONS
34053470

34063471
The lualine component accepts the standard lualine options and the following
34073472
options: - `icon`: Icon to display. (default: `"󰐻"`) - `colored`: Enable

lua/mcphub/extensions/lualine.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
--[[
22
--NOTE: Having cmd = "MCPHub" or lazy = true in user's lazy config, and adding lualine component using require("mcphub.extensions.lualine") will start the hub indirectly.
33
--]]
4+
5+
-- DEPRECATED: This lualine component will load MCPHub even with lazy loading.
6+
-- Use the global variables approach instead: vim.g.mcphub_status, vim.g.mcphub_servers_count, vim.g.mcphub_executing
7+
-- See documentation for recommended usage: doc/extensions/lualine.md
8+
49
local M = require("lualine.component"):extend()
510
local utils = require("lualine.utils.utils")
611
local spinner_frames = { "", "", "", "", "", "", "", "", "", "" }
@@ -31,6 +36,10 @@ M.HubState = {
3136
vim.g.mcphub_status = M.HubState.STARTING
3237
-- Initialize the component
3338
function M:init(options)
39+
vim.notify_once(
40+
"MCPHub lualine extension is deprecated. Use global variables instead for better lazy-loading. See :help mcphub-lualine",
41+
vim.log.levels.WARN
42+
)
3443
M.super.init(self, options)
3544
self:create_autocommands()
3645
self.options = vim.tbl_deep_extend("keep", self.options or {}, default_options)

lua/mcphub/hub.lua

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ MCPHub.__index = MCPHub
4444
--- @param opts table Configuration options
4545
--- @return MCPHub.Hub
4646
function MCPHub:new(opts)
47-
return setmetatable({
47+
local instance = setmetatable({
4848
port = opts.port,
4949
server_url = opts.server_url,
5050
config = opts.config,
@@ -62,6 +62,11 @@ function MCPHub:new(opts)
6262
on_error = opts.on_error or function() end,
6363
setup_opts = opts,
6464
}, MCPHub)
65+
66+
-- Setup global state tracking
67+
instance:_setup_global_state_tracking()
68+
69+
return instance
6570
end
6671

6772
--- Resolve context (workspace vs global) for the current directory
@@ -429,6 +434,7 @@ function MCPHub:handle_hub_ready()
429434
self.ready = true
430435
self.is_restarting = false
431436
self.is_starting = false
437+
self:_update_global_state()
432438
self.on_ready(self)
433439
self:update_servers()
434440
if State.marketplace_state.status == "empty" then
@@ -442,6 +448,7 @@ function MCPHub:_clean_up()
442448
self.is_starting = false
443449
self.is_restarting = false
444450
State:update_hub_state(constants.HubState.STOPPED)
451+
self:_update_global_state()
445452
end
446453

447454
---@param msg string
@@ -1066,6 +1073,9 @@ function MCPHub:refresh_native_servers()
10661073
end
10671074

10681075
function MCPHub:fire_servers_updated()
1076+
-- Update global state
1077+
self:_update_global_state()
1078+
10691079
-- Triggers UI update
10701080
State:notify_subscribers({
10711081
server_state = true,
@@ -1640,4 +1650,32 @@ function MCPHub:get_marketplace_catalog(opts)
16401650
})
16411651
end
16421652

1653+
--- Update global variables for lualine integration
1654+
function MCPHub:_update_global_state()
1655+
vim.g.mcphub_status = State.server_state.state
1656+
vim.g.mcphub_servers_count = #self:get_servers()
1657+
end
1658+
1659+
--- Setup global variable tracking for tool/resource execution
1660+
function MCPHub:_setup_global_state_tracking()
1661+
local group = vim.api.nvim_create_augroup("mcphub_global_state", { clear = true })
1662+
1663+
-- Track tool/resource/prompt execution
1664+
vim.api.nvim_create_autocmd("User", {
1665+
group = group,
1666+
pattern = { "MCPHubToolStart", "MCPHubResourceStart", "MCPHubPromptStart" },
1667+
callback = function()
1668+
vim.g.mcphub_executing = true
1669+
end,
1670+
})
1671+
1672+
vim.api.nvim_create_autocmd("User", {
1673+
group = group,
1674+
pattern = { "MCPHubToolEnd", "MCPHubResourceEnd", "MCPHubPromptEnd" },
1675+
callback = function()
1676+
vim.g.mcphub_executing = false
1677+
end,
1678+
})
1679+
end
1680+
16431681
return MCPHub

lua/mcphub/init.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ local native = require("mcphub.native")
88
local utils = require("mcphub.utils")
99
local validation = require("mcphub.utils.validation")
1010

11+
-- Initialize global variables for lualine integration
12+
vim.g.mcphub_status = "stopped"
13+
vim.g.mcphub_servers_count = 0
14+
vim.g.mcphub_executing = false
15+
1116
---@class MCPHub
1217
local M = {
1318
is_native_server = native.is_native_server,

0 commit comments

Comments
 (0)