Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ body:
- **OS**: Ubuntu 20.04
- **Flutter version**: 3.7.0
- **Is flutter in $PATH**: yes
- **neovim version**: 0.8.3
- **neovim version**: 0.11.0
value: |
- OS:
- Flutter version:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
uses: kdheepak/panvimdoc@main
with:
vimdoc: flutter-tools
version: "Neovim >= 0.8.0"
version: "Neovim >= 0.11"
demojify: true
treesitter: true
- name: Push changes
Expand Down
46 changes: 34 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,15 @@ nnoremap K <Cmd>lua vim.lsp.buf.hover()<CR>
nnoremap gd <Cmd>lua vim.lsp.buf.definition()<CR>
" Open code actions using the default lsp UI, if you want to change this please see the plugins above
nnoremap <leader>ca <Cmd>lua vim.lsp.buf.code_action()<CR>
" Open code actions for the selected visual range
xnoremap <leader>ca <Cmd>lua vim.lsp.buf.range_code_action()<CR>
xnoremap <leader>ca <Cmd>lua vim.lsp.buf.code_action()<CR>
```

Please note this is not a replacement for reading the documentation, this is only to show new users what
some basic setup might look like.

## Prerequisites

- neovim 0.8.0+
- Neovim 0.11+

## Installation

Expand Down Expand Up @@ -159,14 +158,21 @@ require("flutter-tools").setup {} -- use defaults
- `FlutterDetach` - Ends a running session locally but keeps the process running on the device.
- `FlutterOutlineToggle` - Toggle the outline window showing the widget tree for the given file.
- `FlutterOutlineOpen` - Opens an outline window showing the widget tree for the given file.
- `FlutterVisualDebug` - Toggle Flutter visual debugging.
- `FlutterChangeTargetPlatform` - Cycle the target platform override for the running app.
- `FlutterToggleBrightness` - Toggle the app brightness override.
- `FlutterDevTools` - Starts a Dart Dev Tools server.
- `FlutterDevToolsActivate` - Activates a Dart Dev Tools server.
- `FlutterOpenDevTools` - Open the currently connected DevTools page.
- `FlutterInspectWidget` - Toggle widget inspection for the running app.
- `FlutterCopyProfilerUrl` - Copies the profiler url to your system clipboard (+ register). Note that commands `FlutterRun` and
`FlutterDevTools` must be executed first.
- `FlutterPubGet` - Run `flutter pub get` in the project root.
- `FlutterPubUpgrade [args]` - Run `flutter pub upgrade` with optional extra arguments.
- `FlutterLspRestart` - This command restarts the dart language server, and is intended for situations where it begins to work incorrectly.
- `FlutterSuper` - Go to super class, method using custom LSP method `dart/textDocument/super`.
- `FlutterReanalyze` - Forces LSP server reanalyze using custom LSP method `dart/reanalyze`.
- `FlutterRename` - Renames and updates imports if `lsp.settings.renameFilesWithClasses == "always"`
- `FlutterRename` - Rename a symbol and update imports if `lsp.settings.renameFilesWithClasses == "always"`.
- `FlutterLogClear` - Clears the log buffer.
- `FlutterLogToggle` - Toggles the log buffer.

Expand Down Expand Up @@ -270,14 +276,6 @@ require("flutter-tools").setup {
auto_open = false -- if true this will open the outline automatically when it is first populated
},
lsp = {
color = { -- show the derived colours for dart variables
enabled = false, -- whether or not to highlight color variables at all, only supported on flutter >= 2.10
background = false, -- highlight the background
background_color = nil, -- required, when background is transparent (i.e. background_color = { r = 19, g = 17, b = 24},)
foreground = false, -- highlight the foreground
virtual_text = true, -- show the highlight using virtual text
virtual_text_str = "■", -- the virtual text character to highlight
},
on_attach = my_custom_on_attach,
capabilities = my_custom_capabilities, -- e.g. lsp_status capabilities
--- OR you can specify a function to deactivate or change or control how the config is created
Expand All @@ -302,6 +300,30 @@ require("flutter-tools").setup {
You can override any options available in the `lspconfig` setup, this call essentially wraps
it and adds some extra `flutter` specific handlers and utilisation options.

### Document colors

Plugin-managed `lsp.color` rendering is deprecated and will be removed when flutter-tools.nvim requires Neovim `0.12+`.

On Neovim `0.12+`, use the built-in LSP document color support instead:

```lua
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(ev)
vim.lsp.document_color.enable(true, { bufnr = ev.buf })
end,
})
```

If you want to opt out of Neovim's built-in document colors for some buffers:

```lua
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(ev)
vim.lsp.document_color.enable(false, { bufnr = ev.buf })
end,
})
```

**NOTE:**
By default this plugin excludes analysis of the packages in the flutter SDK. If for example
you jump to the definition of `StatelessWidget`, the lsp will not try and index the 100s (maybe 1000s) of
Expand Down
52 changes: 38 additions & 14 deletions doc/flutter-tools.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
*flutter-tools.txt*
For Neovim >= 0.8.0 Last change: 2026 April 23
For Neovim >= 0.11 Last change: 2026 May 03

==============================================================================
Table of Contents *flutter-tools-table-of-contents*
Expand Down Expand Up @@ -62,9 +62,8 @@ A minimal native LSP configuration might look like:
" Jump to definition
nnoremap gd <Cmd>lua vim.lsp.buf.definition()<CR>
" Open code actions using the default lsp UI, if you want to change this please see the plugins above
nnoremap <leader>ca <Cmd>lua vim.lsp.buf.code_action()<CR>
" Open code actions for the selected visual range
xnoremap <leader>ca <Cmd>lua vim.lsp.buf.range_code_action()<CR>
nnoremap <leader>ca <Cmd>lua vim.lsp.buf.code_action()<CR>
xnoremap <leader>ca <Cmd>lua vim.lsp.buf.code_action()<CR>
<

Please note this is not a replacement for reading the documentation, this is
Expand All @@ -73,7 +72,7 @@ only to show new users what some basic setup might look like.

PREREQUISITES *flutter-tools-flutter-tools.nvim-prerequisites*

- neovim 0.8.0+
- Neovim 0.11+


INSTALLATION *flutter-tools-flutter-tools.nvim-installation*
Expand Down Expand Up @@ -193,14 +192,21 @@ APP VERSION
- `FlutterDetach` - Ends a running session locally but keeps the process running on the device.
- `FlutterOutlineToggle` - Toggle the outline window showing the widget tree for the given file.
- `FlutterOutlineOpen` - Opens an outline window showing the widget tree for the given file.
- `FlutterVisualDebug` - Toggle Flutter visual debugging.
- `FlutterChangeTargetPlatform` - Cycle the target platform override for the running app.
- `FlutterToggleBrightness` - Toggle the app brightness override.
- `FlutterDevTools` - Starts a Dart Dev Tools server.
- `FlutterDevToolsActivate` - Activates a Dart Dev Tools server.
- `FlutterOpenDevTools` - Open the currently connected DevTools page.
- `FlutterInspectWidget` - Toggle widget inspection for the running app.
- `FlutterCopyProfilerUrl` - Copies the profiler url to your system clipboard (+ register). Note that commands `FlutterRun` and
`FlutterDevTools` must be executed first.
- `FlutterPubGet` - Run `flutter pub get` in the project root.
- `FlutterPubUpgrade [args]` - Run `flutter pub upgrade` with optional extra arguments.
- `FlutterLspRestart` - This command restarts the dart language server, and is intended for situations where it begins to work incorrectly.
- `FlutterSuper` - Go to super class, method using custom LSP method `dart/textDocument/super`.
- `FlutterReanalyze` - Forces LSP server reanalyze using custom LSP method `dart/reanalyze`.
- `FlutterRename` - Renames and updates imports if `lsp.settings.renameFilesWithClasses == "always"`
- `FlutterRename` - Rename a symbol and update imports if `lsp.settings.renameFilesWithClasses == "always"`.
- `FlutterLogClear` - Clears the log buffer.
- `FlutterLogToggle` - Toggles the log buffer.

Expand Down Expand Up @@ -306,14 +312,6 @@ both are set.
auto_open = false -- if true this will open the outline automatically when it is first populated
},
lsp = {
color = { -- show the derived colours for dart variables
enabled = false, -- whether or not to highlight color variables at all, only supported on flutter >= 2.10
background = false, -- highlight the background
background_color = nil, -- required, when background is transparent (i.e. background_color = { r = 19, g = 17, b = 24},)
foreground = false, -- highlight the foreground
virtual_text = true, -- show the highlight using virtual text
virtual_text_str = "■", -- the virtual text character to highlight
},
on_attach = my_custom_on_attach,
capabilities = my_custom_capabilities, -- e.g. lsp_status capabilities
--- OR you can specify a function to deactivate or change or control how the config is created
Expand All @@ -339,6 +337,32 @@ You can override any options available in the `lspconfig` setup, this call
essentially wraps it and adds some extra `flutter` specific handlers and
utilisation options.


DOCUMENT COLORS ~

Plugin-managed `lsp.color` rendering is deprecated and will be removed when
flutter-tools.nvim requires Neovim `0.12+`.

On Neovim `0.12+`, use the built-in LSP document color support instead:

>lua
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(ev)
vim.lsp.document_color.enable(true, { bufnr = ev.buf })
end,
})
<

If you want to opt out of Neovim's built-in document colors for some buffers:

>lua
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(ev)
vim.lsp.document_color.enable(false, { bufnr = ev.buf })
end,
})
<

**NOTE:** By default this plugin excludes analysis of the packages in the
flutter SDK. If for example you jump to the definition of `StatelessWidget`,
the lsp will not try and index the 100s (maybe 1000s) of files in that
Expand Down
54 changes: 39 additions & 15 deletions lua/flutter-tools/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,9 @@ local function validate_prefs(prefs)
end
)
end
if vim.fn.has("nvim-0.11") == 1 then
vim.validate("outline", prefs.outline, "table", true)
vim.validate("dev_log", prefs.dev_log, "table", true)
vim.validate("closing_tags", prefs.closing_tags, "table", true)
else
vim.validate({
outline = { prefs.outline, "table", true },
dev_log = { prefs.dev_log, "table", true },
closing_tags = { prefs.closing_tags, "table", true },
})
end
vim.validate("outline", prefs.outline, "table", true)
vim.validate("dev_log", prefs.dev_log, "table", true)
vim.validate("closing_tags", prefs.closing_tags, "table", true)
end

---Create a proportional split using a percentage specified as a float
Expand Down Expand Up @@ -163,15 +155,47 @@ local deprecations = {
fallback = "widget_guides",
message = "please use 'widget_guides' instead",
},
lsp = {
nested = {
color = {
when = function() return vim.fn.has("nvim-0.12") == 1 end,
message = "plugin-managed document colors are deprecated and will be removed when flutter-tools.nvim requires Neovim 0.12+. On Neovim 0.12+, use vim.lsp.document_color.enable() instead",
},
},
},
}

local function handle_deprecation(key, value, conf)
local deprecation = deprecations[key]
if not deprecation then return end
local function notify_deprecation(key, message)
vim.defer_fn(
function() ui.notify(fmt("%s is deprecated: %s", key, deprecation.message), ui.WARN) end,
function() ui.notify(fmt("%s is deprecated: %s", key, message), ui.WARN, { once = true }) end,
1000
)
end

local function should_notify_deprecation(deprecation)
return not deprecation.when or deprecation.when()
end

local function handle_nested_deprecation(prefix, value, deprecation)
if type(value) ~= "table" or type(deprecation.nested) ~= "table" then return end
for key, nested_value in pairs(value) do
local nested_deprecation = deprecation.nested[key]
if nested_deprecation then
if nested_deprecation.message and should_notify_deprecation(nested_deprecation) then
notify_deprecation(("%s.%s"):format(prefix, key), nested_deprecation.message)
end
handle_nested_deprecation(("%s.%s"):format(prefix, key), nested_value, nested_deprecation)
end
end
end

local function handle_deprecation(key, value, conf)
local deprecation = deprecations[key]
if not deprecation then return end
if deprecation.message and should_notify_deprecation(deprecation) then
notify_deprecation(key, deprecation.message)
end
handle_nested_deprecation(key, value, deprecation)
if deprecation.fallback then conf[deprecation.fallback] = value end
end

Expand Down
2 changes: 1 addition & 1 deletion lua/flutter-tools/dev_tools.lua
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ end

function M.stop()
if devtools_pid then
local uv = vim.loop
local uv = vim.uv
uv.kill(devtools_pid, uv.constants.SIGTERM)
devtools_pid = nil
devtools_url = nil
Expand Down
13 changes: 12 additions & 1 deletion lua/flutter-tools/devices.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,18 @@ function M.to_selection_entries(result, device_type)
if not result or #result < 1 then return {} end
if not device_type then device_type = DEVICE end
local devices = get_devices(result, device_type)
if #devices == 0 then vim.tbl_map(function(item) return { text = item } end, result) end
if #devices == 0 then
return vim.tbl_map(
function(item)
return {
text = item,
type = ui.entry_type.INFO,
data = nil,
}
end,
result
)
end
return vim.tbl_map(function(device)
local has_platform = device.platform and device.platform ~= ""
return {
Expand Down
6 changes: 3 additions & 3 deletions lua/flutter-tools/executable.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ local Job = require("plenary.job")

local fn = vim.fn
local fs = vim.fs
local luv = vim.loop
local uv = vim.uv

local M = {}

Expand Down Expand Up @@ -124,13 +124,13 @@ end

local function flutter_bin_from_fvm()
local fvm_root =
fs.dirname(fs.find(".fvm", { path = luv.cwd(), upward = true, type = "directory" })[1])
fs.dirname(fs.find(".fvm", { path = uv.cwd(), upward = true, type = "directory" })[1])

local binary_name = path.is_windows and "flutter.bat" or "flutter"
local flutter_bin_symlink = path.join(fvm_root, ".fvm", "flutter_sdk", "bin", binary_name)
flutter_bin_symlink = fn.exepath(flutter_bin_symlink)

local flutter_bin = luv.fs_realpath(flutter_bin_symlink)
local flutter_bin = uv.fs_realpath(flutter_bin_symlink)
if path.exists(flutter_bin_symlink) and path.exists(flutter_bin) then return flutter_bin end
end

Expand Down
Loading
Loading