folke / flash.nvim

Navigate your code with search labels, enhanced character motions and Treesitter integration
Apache License 2.0
2.53k stars 32 forks source link

feature: Support keymaps (Ctrl+^). #66

Closed D00mch closed 1 year ago

D00mch commented 1 year ago

Did you check the docs?

Is your feature request related to a problem? Please describe.

When I write a blogpost in my native language, I use my native keyboard layout (utilizing keymaps). If I use search (/) with Flash, lables are provided in English, and I can't type them (as my layout is not English at the moment).

f and F don't work as well.

Describe the solution you'd like

lables are provided in the language that is currently set. f and F also work (both of them work without Flash with other layouts).

Describe alternatives you've considered

🤷

Additional context

Here is the code I use to switch between layouts.

set keymap=russian-jcukenmac
set iminsert=0
set imsearch=0

function! s:SetLangCmd(langName)
    let n = (a:langName == "en_US") ? 0 : 1
    execute "set iminsert=" . n . " imsearch=" . n
    execute "lang " . a:langName . ".UTF-8"
endfunction

function! s:ToggleKeyboard()
    call <SID>SetLangCmd(&iminsert == 0 ? "ru_RU" : "en_US")
endfunction

xnoremap <C-6> :call <SID>ToggleKeyboard()<CR>
nnoremap <C-6> :call <SID>ToggleKeyboard()<CR>
folke commented 1 year ago

Have you tried configuring different labels?

D00mch commented 1 year ago

No. Do you propose to call flash.setup with different labels on changing layout?

P.S. Could the setup function take a function as a labels parameter?

folke commented 1 year ago

I've added some improvents that should already deal with at least some unicode issues.

Yes, you should change the labels config to the unicode labels you want to use.

I won't add a function. You can pass in custom labels for the jump function and if needed, update the default config afterwards with require("flash.config").labels = "..."

D00mch commented 1 year ago

I invoke require ("flash.config").labels = "фыва....", but lables are still eng. When I invoke flash.setup with russian labels, I still have eng labels in russian layout. When I change layout to English — labels are now Russian.

I use fennel to setup my config, here is the video where I interactively change layout and search:

https://github.com/folke/flash.nvim/assets/14236531/90482c4f-04fd-4a6f-b195-dcd55c214011

folke commented 1 year ago

Not sure what you're doing wrong, but if you do:

require("flash").setup({labels = "😅😀🏇🐎🐴🐵🐒"})

Then you'll see the emoji labels

D00mch commented 1 year ago

Yes, this works as well as when I set Cyrillic labels. But when I change my keymap to Cyrillic, it stops working.

P.S. I updated the name of the issue a little.

So in the video above I was changing my keymap with <ctrl+^> (:h imsearch). Now I also tried to change my OS layout, and Cyrillic symbols don't work either.

folke commented 1 year ago

sorry, I don't use langmap or keymap, so I'm not even sure what has to be changed to make this work.

If anyone feels inclined to make a PR for this, go ahead

rasulomaroff commented 1 year ago

Can confirm that when using Russian labels, flash doesn't jump to a label when pressing it. (Maybe this happens in other layouts as well, not English ones)

folke commented 1 year ago

I think I was able to fully implement support for custom keymaps.

No need to configure custom labels.

When iminsert==1, flash will translate the labels to the new symbols.

When inputting a character, the character will also be translated.

Everything should work as expected now.

Would be great if you could confirm!

rasulomaroff commented 1 year ago

Not sure about iminsert because I don't use it and don't really know how to, but I can confirm that jumping with Russian labels works correctly right now (it doesn't before).

folke commented 1 year ago

iminsert is set to 1 when a keymap is active with lmaps. It's toggled with C-^, so that's what I check to see if I need to enable the special processing

D00mch commented 1 year ago

I still have problems. When I set russian keymap (the way that is described in the Additional context) and search, I need to enter several characters before I see a label:

https://github.com/folke/flash.nvim/assets/14236531/fa93306c-6407-4ebb-acc9-dfe81d2f8196

folke commented 1 year ago

Just pushed another update that now properly calculates skip labels for multi-byte keymaps.

@D00mch would be great if you could test again

D00mch commented 1 year ago

Not a problem at all. I can still reproduce the issue:

https://github.com/folke/flash.nvim/assets/14236531/c4049ee2-88a6-40c3-ab17-a71198547dae

Sometimes it takes less amount of letters to have a label:

image
folke commented 1 year ago

I can't reproduce this. Are you 100% sure you updated flash and are not using something like version="*"?

folke commented 1 year ago

the behavior you're showing is what I've fixed in that specific commit

folke commented 1 year ago

I use this for testing:

vim.cmd([[set keymap=russian-jcukenmac]])

-- фывапролдйцукенгшщзячсмить

Then type /a (a will be inserted as ф), you should see labels right away.

What is your full flash config?

D00mch commented 1 year ago

Yes, just opened the source code of a plugin and see that your changes are here: labeler.lua:192

      local line = vim.api.nvim_buf_get_lines(0, pos[1] - 1, pos[1], false)[1]
      local char = vim.fn.strpart(line, pos[2] - 1, 1, true)

https://github.com/folke/flash.nvim/assets/14236531/b3b2b562-dd2e-4727-a994-829aef289e40

I can also reproduce this on a default config.

folke commented 1 year ago

Try the minimal config below:

nvim -u repro.lua repro.lua


local root = vim.fn.fnamemodify("./.repro", ":p")

-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
  vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  "folke/tokyonight.nvim",
  {
    "folke/flash.nvim",
    opts = {},
    event = "VeryLazy",
    keys = { {
      "s",
      function()
        require("flash").jump()
      end,
    } },
  },
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

vim.cmd.colorscheme("tokyonight")
-- add anything else here
vim.cmd([[set keymap=russian-jcukenmac]])

-- фывапролдйцукенгшщзячсмить
folke commented 1 year ago

An try in the terminal. Maybe Neovide does something weird

folke commented 1 year ago

ok, seems that if you do search first / then it indeed doesn't sem to work.

If you press s, then cancel, then search will work.

Will see what's going on here.

Edit: nevermind, that's because the repro was lazy-loaded. Fixed the repro.

All works in the repro for me

D00mch commented 1 year ago

try in the terminal Didn't help. I have the same behavior in terminal.

I also try jumps, it works the opposite, removing the last typed letter from selection (instead of adding a label):

image
D00mch commented 1 year ago

All works in repro for me also. So something wrong with my config somewhere.

folke commented 1 year ago

Maybe your fennel is clashing somewhere?

I know that fennel has their own byte-compiled lua cache. So does lazy and Neovim nightly (I upstreamed that part of the lazy code).

Lazy will enable the new optimized Neovim loader if it detects it has access to it and won't use its own.

Maybe check if you can clear the fennel cache.

folke commented 1 year ago

I'm closing this for now, since at least in a minimal setup it does what it should do

D00mch commented 1 year ago

I finally found the problem: when I set label.uppercase to false in the config, everything works.