Skip to content

About

Enhance f/t motions to search multiple character variants with a single keystroke

Topics

Resources

Stars

6 stars

Watchers

0 watching

Forks

Latest commit

 

History

27 Commits

Folders and files

Repository files navigation

ft-mapper.nvim

A Neovim plugin that extends f, F, t, and T motions to search for multiple character variants with a single keystroke. Perfect for multilingual environments where half-width and full-width characters are mixed.

✨ Features

  • Multi-character search: Search for multiple character variants with a single keystroke (e.g., f, jumps to ,, 、, or ,)
  • Full-width/Half-width support: Seamlessly handle Japanese, Chinese, and other full-width characters
  • Preserves native behavior: Falls back to default Vim behavior for unmapped characters
  • Repeat support: Works with ; and , for repeating searches
  • Count support: Compatible with count prefixes (e.g., 3f,)
  • All modes supported: Works in Normal, Visual, and Operator-pending modes
  • Multi-line search: Extends search range above and below the cursor line
  • Replace f/t/F/T/;/,: Ability to change f/t/F/T/;/, keys to any other keys

🛠️ Installation

Using lazy.nvim

Here's the configuration for lazy.nvim. No default mappings are provided, so mappings must be configured.

return {
  's-show/ft-mapper.nvim',
  opts = {
    mappings = {
      { ',', '、', ',' },
      { '.', '。', '.' },
      { ":", ":" },
      { ";", ";" },
      { "!", "!" },
      { "?", "?" },
      { "(", "(" },
      { ")", ")" },
      { "[", "「", "『", "【", "[", "{", "{" },
      { "]", "」", "』", "】", "]", "}", "}" },
    },
  },
}

⚙️ Configuration

Configuration Options

  • mappings (string[][])
    • Configure the key combinations for f or t and the characters you want to search for.
    • Example: { ",", "、", "," }
    • First element: The character to type with f or t (like , in f,)
    • Remaining elements: Characters to search for when typing f,
  • line_limit (integer) (optional)
    • Specify how many lines to extend the search range above and below the cursor line. 1 limits search to cursor line only. 2 includes cursor line and one line above/below. Default value is 5.
  • no_default_mappings (boolean) (optional)
    • Set to true to disable assignment of extended search functionality to f, t, F, T, ;, ,. Default value is false.
  • debug (boolean) (optional)
    • Enable debug output for troubleshooting. Should normally be false. Default value is false.

Example

return {
  's-show/ft-mapper.nvim',
  opts = {
    mappings = {
      -- This configuration is designed for Japanese editing
      { ',', '、', ',' },
      { '.', '。', '.' },
      { ":", ":" },
      { ";", ";" },
      { "!", "!" },
      { "?", "?" },
      { "(", "(" },
      { ")", ")" },
      { "[", "「", "『", "【", "[" },
      { "]", "」", "』", "】", "]" },
      { "'", "'", "'" },
      { '"', """, """, "゛" },
      { '<', "<", "«" },
      { '>', ">", "»" },
      { "-", "ー", "―", "—", "–" },
      { " ", " " }, -- half-width and full-width spaces
    },
    -- Search within 10 lines above and below cursor line (optional)
    line_limit = 10,
    -- Don't assign to default key mappings (optional)
    no_default_mappings = false,
    -- Enable debug output (optional)
    debug = false
  }
}

🚀 Usage

Once configured, simply use the f, F, t, and T motions as you normally would:

  • f, - Jump forward to the next ,, 、, or ,
  • F, - Jump backward to the previous ,, 、, or ,
  • t, - Jump forward to just before the next ,, 、, or ,
  • T, - Jump backward to just after the previous ,, 、, or ,

Repeat motions work as expected:

  • ; - Repeat the last search in the same direction
  • , - Repeat the last search in the opposite direction

Count prefixes are supported:

  • 3f, - Jump to the 3rd occurrence of ,, 、, or ,
  • v5f, - Select from cursor to the 5th occurrence of ,, 、, or ,
  • y4f, - Yank from cursor to the 4th occurrence of ,, 、, or ,

🔍 Example Use Cases

Japanese Text

1. これは、テストです。次の文,そして,最後の文.
2. これは、テストです。次の文,そして,最後の文.
3. これは、テストです。次の文,そして,最後の文.
4. これは、テストです。次の文,そして,最後の文.
  • Type f, at the beginning of line 1 to jump to "、" in "これは、", then type ; to jump to "," in "次の文,"

  • Type f, at the beginning of line 1 to jump to "、" in "これは、", then type 5; to jump to "," in "そして," on line 2

  • Type 5f. at the beginning of line 1 to jump to "." in "2." on line 2, then type 3, to jump backward to "." in "1." on line 1

  • Type y4f, at the beginning of line 1 to yank up to "、" in "2. これは、" on line 2

  • Type f, at the beginning of line 1 to jump to "、" in "これは、", then type c5; to change up to "," in "そして," on line 2

  • Type F. at the end of line 1 to jump backward to "。" in "テストです。"

  • Type 3F. at the end of line 2 to jump backward to "." in "最後の文." on line 1

  • Type F. at the end of line 3 to jump backward to "。" in "テストです。" on line 3, then type 8; to jump backward to "." in "1." on line 1

Multilingual Mixed Documents

Hello, world! こんにちは、世界!
  • Search for both ! and ! with f!
  • Search for both , and 、 with f,

Demo Video

demo.mp4

🛠️ Advanced Features

Disabling Default Key Mappings

While this plugin extends the search functionality of f, t, F, T, ;, ,, you can configure it not to assign the extended functionality to these default keys.

return {
  opts = {
    mappings = { --[[ your mappings ]] },
    no_default_mappings = true
  },
}

After this configuration, assign the extended functionality to any keys you prefer:

return {
  opts = {
    mappings = { --[[ your mappings ]] },
  },
  -- Assign extended functionality to <leader>f/t/F/T
  vim.keymap.set({ 'n', 'v', 'o' }, '<leader>f', '<Plug>(f_motion)'),
  vim.keymap.set({ 'n', 'v', 'o' }, '<leader>t', '<Plug>(t_motion)'),
  vim.keymap.set({ 'n', 'v', 'o' }, '<leader>F', '<Plug>(F_motion)'),
  vim.keymap.set({ 'n', 'v', 'o' }, '<leader>T', '<Plug>(T_motion)'),
  -- Assign forward repeat search (;) to ">"
  vim.keymap.set({ 'n', 'v', 'o' }, '>', '<Plug>(forward_repeat)'),
  -- Assign backward repeat search (,) to "<"
  vim.keymap.set({ 'n', 'v', 'o' }, '<', '<Plug>(backward_repeat)'),
}

Checking Current Configuration

:lua require("ft-mapper").show_config()
" or
:= require("ft-mapper").show_config()

Check if Repeat Search is Available

require("ft-mapper").is_ft_repeatable()

Using this function, you can configure "execute repeat search if available, otherwise send normal <Right>":

local ft_mapper = require('ft-mapper')
vim.keymap.set({ 'n', 'v', 'o' }, '<Right>', function()
  if ft_mapper.is_ft_repeatable() then
    return '<Plug>(forward_repeat)'
  else
    return '<Right>'
  end
end, { expr = true })

Debug Mode

Enable debug output to troubleshoot mappings:

return {
  opts = {
    mappings = { --[[ your mappings ]] },
    debug = true
  }
}

Requirements

  • Neovim 0.7.0 or higher
  • No external dependencies

License

This project is licensed under the MIT License - see the LICENSE file for details.

Original Plugin

This plugin is a Lua rewrite and extension of juro106/ftjpn, which I used daily.

Thanks to juro106/ftjpn for creating a plugin that improves the efficiency of editing Japanese documents.

FAQ

Q: Why do I need this plugin?

A: In documents mixing Japanese and English, punctuation marks often appear in both half-width (,) and full-width (、) forms. While the normal f, only searches for half-width commas, this plugin allows you to search for both.

Q: Can I add custom mappings?

A: Simply add new entries to the mappings table. The first element is the input character, and the rest are the search target characters.

About

Enhance f/t motions to search multiple character variants with a single keystroke

Topics

Resources

Stars

6 stars

Watchers

0 watching

Forks

Used by

Contributors

Languages