antonk52 / markdowny.nvim

Markdown like keymaps for toggling text formatting
73 stars 7 forks source link

[Bug]: Cyrillic words tear apart #1

Closed WhiteBlackGoose closed 1 year ago

WhiteBlackGoose commented 1 year ago

Hey there.

Great plugin! Really needed it for some time, but didn't have time to make it myself. Imma use it now.

Repro of the bug: Type a word:

Привет

Invoke any command (italics/bold/link)

Here's what you get:

⨪鿐胑룐닐뗐⫑航

Peek 2023-01-13 14-51

antonk52 commented 1 year ago

Glad you found useful and thanks for the bug report.

I looks like lua/neovim treats cyrillic characters rent to latin ones.

vim.split('привет', '')
{ "<d0>", "<bf>", "<d1>", "<80>", "<d0>", "<b8>", "<d0>", "<b2>", "<d0>", "<b5>", "<d1>", "<82>" }

I will try to look into this over the weekend. If you know of a solution do let me know.

Wansmer commented 1 year ago

If you know of a solution do let me know.

I think you can try this approach for handling non english (non one byte chars) text:

-- NOTE: example work only when cursor on last char of selection and only charwise visual mode.
-- Edge cases are also not taken into account.
vim.keymap.set('x', '<c-b>', function()
  -- get visual selection range
  -- for case when curson on start char it need reorder (sr = er, er = sr e.t.c)
  local er, ec = unpack(vim.fn.getpos('.'), 2, 3)
  local sr, sc = unpack(vim.fn.getpos('v'), 2, 3)

  -- save real text in 'v' register (no independent of count byte in char)
  vim.cmd.normal('"vy')
  local text = vim.split(vim.fn.getreg('v'), '\n', { plain = true })
  -- clear register
  vim.fn.setreg('v', '')

  -- check two byte on end of range
  local last_row = vim.fn.getline(er)
  local char = last_row:sub(ec, ec + 1)

  local last_col
  if #char ~= 0 then
    if #char == vim.fn.strdisplaywidth(char) then
      -- if display len equals with byte len, use normal end col
      last_col = ec
    else
      print('else')
      -- if display len not equals with byte len, use delta
      last_col = #char - vim.fn.strdisplaywidth(char) + ec
    end
  else
    last_col = 0
  end

  local prefix = '**'
  local postfix = '**'

  text[1] = prefix .. text[1]
  text[#text] = text[#text] .. postfix

  vim.api.nvim_buf_set_text(0, sr - 1, sc - 1, er - 1, last_col, text)
end)

https://user-images.githubusercontent.com/46977173/212364710-967ea943-03a7-460e-b281-f950435a3854.mov

Hope this will help

gerazov commented 1 year ago

:+1: for fixing this.

antonk52 commented 1 year ago

I was able to fix this in 4e84ca3. Thanks to the @Wansmer 's comment. I ended up doing it slightly different. Though, now it also supports [un]surrounding without having to have the cursor on the last character.

Thanks everyone