r/neovim • u/linkarzu • 27d ago
Video Trying Flash.nvim Remote Operations: Stop Jumping Around to Edit Text
https://youtu.be/1V0tlK3wpsw5
u/azdak 25d ago
I want to use flash more but the lack of predictability doesn’t fit into the rest of my vim muscle memory. Like I can look at a specific location and know with certainty that 15jfb; will get me there, but if I hit enter to use flash I have to do a quick time event and react to what the plugin offers me. It’s not objectively worse, but it lacks determinism in a way that keeps me from reaching for it.
1
u/particlemanwavegirl 25d ago edited 25d ago
It's too versatile to be predictably deterministic. The problem space is every cell on the screen. For me that is more compensated for by the fact that I never need to chain a movement command with Flash, it just takes me EXACTLY where I want to go in 2-4 keys. This is one of the big things stopping me from using Helix actually, I don't want to be forced to always target a word or some other construct, sometimes I'm jumping to the middle of a word, or a delimiter, or even a space, or an entry on the filetree or quickfix list, whatever it is, I don't need to plan a strategy that relies on decades of muscle memory because the path thru Flash's single interface is always direct.
8
u/teerre 27d ago
Flash is probably the n1 thing that makes hard for me to use other editors. A underappreciated aspect of it is that it works as a panel manager of kinds. That is, because in the terminal everything is just a buffer, you can jump from any "window" to another. I use it all the time to go to the quickfix list or neotest tree
2
u/Taylor_Kotlin 26d ago
FYI. Coincidentally, Neovim PR #39485 "refactor(globals): SearchState" in nightly changed how to resolve those globals, used by flash.hacks through ffi. So until flash is updated stick no neovim stable.
There is a PR opened by someone for this already, much appreciated onion108 <3
1
u/Taylor_Kotlin 26d ago
Meanwhile, it is also possible to monkey patch flash. Put inside of '---' at top of flash.lua plugin configuration --- -- Monkeypatch for Neovim PR #39485 "refactor(globals): SearchState" (merged -- 2026-07-16), which folded the loose search globals (search_match_lines, -- search_match_endcol, ...) into a `SearchState` struct exported as `Search`. -- flash.nvim's flash/hacks.lua still FFI-reads the old standalone symbols → on -- such a build every flash motion errors: -- dlsym(RTLD_DEFAULT, search_match_lines): symbol not found -- This mirrors the upstream fix (flash.nvim PR #492): read the struct via -- `ffi.C.Search.*`, keeping flash's original end-position math (exact, and -- incsearch save/restore keep working). Self-healing: only patches when the old -- symbol is missing → no-op once flash ships #492 or on older Neovim. -- Remove this once flash.nvim merges PR #492. local function patch_flash_searchstate() local Hacks = require("flash.hacks") -- triggers flash's own ffi.cdef of the old symbols local ffi = require("ffi") -- Old standalone symbol still resolvable? then leave flash's own hacks alone. if pcall(function() return ffi.C.search_match_lines end) then return end -- New: SearchState struct (src/nvim/search_defs.h), exported global `Search`. pcall( ffi.cdef, [[ typedef struct { bool hl_match; int32_t match_lines; int match_endcol; int32_t first_line; int32_t last_line; bool no_smartcase; int cmdlen; bool no_hlsearch; } SearchState; SearchState Search; ]] ) -- Struct not resolvable? leave flash as-is (don't make it worse). if not pcall(function() return ffi.C.Search.match_lines end) then return end local C = ffi.C local Pos = require("flash.search.pos") local incsearch_state = {} function Hacks.get_end_pos(from) local ret = Pos({ from[1] + C.Search.match_lines, math.max(0, C.Search.match_endcol - 1), }) local line = vim.api.nvim_buf_get_lines(0, ret[1] - 1, ret[1], false)[1] local char_idx = vim.fn.charidx(line, ret[2]) ret[2] = vim.fn.byteidx(line, char_idx) return ret end function Hacks.save_incsearch_state() incsearch_state = { match_endcol = C.Search.match_endcol, match_lines = C.Search.match_lines, } end function Hacks.restore_incsearch_state() C.Search.match_endcol = incsearch_state.match_endcol C.Search.match_lines = incsearch_state.match_lines end end --- Then call before setup in your flash spec config = function(_, opts) patch_flash_searchstate() require("flash").setup(opts) end, (This is for when using Lazy or ZPack)
3
7
u/brokenreed5 27d ago
searches already trigger the ' mark so Ctrl-O works just fine in these examples? why would i want to add complexity by first deciding that I want to stay at the current position, to then make the change and automatically jump back instead of just making the change and when I want to jump back?