β‘ azfunc.nvim
November 9, 2025 Β· View on GitHub
Debug .NET isolated Azure Functions in Neovim with automatic process attachment and smart project detection.
π¬ Demo

β¨ Features
- π Smart Project Detection - Automatically finds Azure Functions projects in your workspace
- π― Intelligent Attachment - Finds and attaches to .NET worker processes with configurable retry logic
- π DAP Integration - Works seamlessly with your existing nvim-dap setup
- π¨ Interactive Picker - Choose from multiple projects with a beautiful selection UI
- π Terminal Management - Dedicated terminal for Azure Functions logs
- π« Visual Feedback - Spinner notifications to track the attachment process
- β¨οΈ Configurable Mappings - Customize or disable key mappings
- π§Ή Auto Cleanup - Automatically stops processes and closes terminals
π Requirements
Neovim
- Neovim >= 0.8.0
Plugins
- nvim-dap (required)
- Any notification plugin that integrates with
vim.notify(optional)
External Tools
- Azure Functions Core Tools (
funcCLI) - .NET SDK (6.0 or later)
- A .NET debugger (e.g., netcoredbg)
π¦ Installation
lazy.nvim
{
"fschaal/azfunc.nvim",
dependencies = { "mfussenegger/nvim-dap" },
config = function()
require("azfunc").setup({
mappings = {
start = "<leader>fs",
stop = "<leader>fS",
},
})
end,
}
packer.nvim
use {
"fschaal/azfunc.nvim",
requires = { "mfussenegger/nvim-dap" },
config = function()
require("azfunc").setup()
end
}
vim-plug
Plug 'mfussenegger/nvim-dap'
Plug 'fschaal/azfunc.nvim'
Then in your init.lua:
require("azfunc").setup()
π§ Configuration
DAP Adapter Setup
First, configure your .NET debugger with nvim-dap:
local dap = require("dap")
dap.adapters.coreclr = {
type = "executable",
command = "/path/to/netcoredbg",
args = { "--interpreter=vscode" },
}
Plugin Configuration
require("azfunc").setup({
-- β¨οΈ Key mappings
mappings = {
start = "<leader>fs", -- Start Azure Function
stop = "<leader>fS", -- Stop Azure Function
},
-- π Debug settings
debug = {
adapter_type = "coreclr", -- DAP adapter type
attach_retry_count = 20, -- Retry attempts
retry_interval = 2000, -- ms between retries
attach_timeout = 1000, -- Initial delay
},
-- π Terminal settings
terminal = {
split = "vsplit", -- "vsplit", "split", or "tabnew"
size = nil, -- nil = default size
},
-- π¨ UI settings
ui = {
notifications = true, -- Show notifications
spinner_preset = "default", -- "default", "dots", "arrows", "lines"
},
-- βοΈ Azure Functions CLI
func_cli = {
command = "func",
args = "host start --dotnet-isolated-debug",
},
})
Quick Examples
π Minimal Setup
require("azfunc").setup()
πΉ Custom Key Mappings
require("azfunc").setup({
mappings = {
start = "<leader>af",
stop = "<leader>as",
},
})
π« Disable Auto-Mappings
require("azfunc").setup({
mappings = false,
})
-- Define your own
vim.keymap.set("n", "<F5>", require("azfunc").start)
vim.keymap.set("n", "<F6>", require("azfunc").stop)
π Increase Retry Attempts
require("azfunc").setup({
debug = {
attach_retry_count = 30,
retry_interval = 1500,
},
})
π Usage
Commands
| Command | Description |
|---|---|
:AzFuncStart | Start debugging (opens picker for multiple projects) |
:AzFuncStop | Stop the current debug session |
:AzFuncList | List all Azure Functions projects |
Default Key Mappings
| Mapping | Action |
|---|---|
<leader>fs | Start debugging |
<leader>fS | Stop debugging |
Lua API
-- Start with project picker
require("azfunc").start()
-- Start specific project
require("azfunc").start_from_path("/path/to/project")
-- Stop current session
require("azfunc").stop()
-- List all projects
local projects = require("azfunc").list_projects()
π How It Works
1. π Scan workspace for Azure Functions projects
2. π Show project picker (if multiple found)
3. π Open terminal for logs
4. βΆοΈ Start Azure Functions in debug mode
5. π Poll for .NET worker process
6. π Attach nvim-dap to the process
7. β
Ready to debug!
Typical Workflow
- Open your Azure Functions project in Neovim
- Set breakpoints with
:lua require('dap').toggle_breakpoint() - Press
<leader>fsto start debugging - Select your project (if multiple exist)
- Wait for the spinner to confirm attachment
- Trigger your function (HTTP request, timer, etc.)
- Debug with DAP commands (step, inspect, etc.)
- Stop with
<leader>fSwhen done
Alternative ways to stop:
- Press
<F5>(DAP continue) and then terminate the DAP session - Use
:lua require('dap').terminate()to stop the DAP session directly
π§ Troubleshooting
β "nvim-dap is not installed"
Make sure you have nvim-dap installed and in your Neovim runtime path.
β "No Azure Functions projects found"
The plugin looks for .csproj files with <AzureFunctionsVersion>. Ensure:
- You're in your workspace root
- Your
.csprojhas<AzureFunctionsVersion>v4</AzureFunctionsVersion> - The project isn't in
bin/orobj/
β "Failed to attach to Azure Function"
Common causes:
- Azure Functions Core Tools not installed (
func --version) - Function app failed to start (check terminal output)
- Process exited before attachment
- Try increasing
attach_retry_countin config
β "A debug session is already active"
Stop the current session first with :AzFuncStop or <leader>fS.
β Debugger doesn't attach
Verify your DAP adapter configuration:
local dap = require("dap")
dap.adapters.coreclr = {
type = "executable",
command = "/path/to/netcoredbg",
args = { "--interpreter=vscode" },
}
Test with a simple .NET console app first.
π€ Contributing
Contributions are welcome! Here's how you can help:
- π Report bugs or request features via GitHub Issues
- π§ Submit pull requests with bug fixes or features
- π Improve documentation
- π¬ Share your configuration and workflows
Development Setup
- Clone the repository
- Make your changes
- Test with real Azure Functions projects
- Submit a pull request
πΊοΈ Roadmap
- π Multiple function apps running simultaneously
- βοΈ Azure portal integration for fetching app settings
π License
MIT License - See LICENSE file for details
π Acknowledgments
- nvim-dap - Excellent DAP client
- Azure Functions Core Tools - Local development support
- The Neovim community - Inspiration and support
π Related Projects
- nvim-dap - Debug Adapter Protocol client
- nvim-dap-ui - UI for nvim-dap
- nvim-dap-virtual-text - Virtual text support
- telescope-dap.nvim - Telescope integration
π Support
β If you find this plugin useful, please star the repository!
β Like this plugin? Buy me a coffee!
π¬ Questions or issues? Open an issue on GitHub!
Made with β€οΈ for the Neovim community