Does anyone know how to get the searchcount() values in lua?

I am writing a function do squeeze blank lines, the main command is:

:%s/^\n\{2,}/\r/ge

It will squeeze blank lines substituting duplicate ones for a single blank line \r. I have found a vim function that gives me a vim dictionary with the total of matches, it is searchcount(), I just need a way to get the total of matches into a lua function.

Hi.

I’d meant to reply to you on Gitter/Matrix, but you’d gone by the time I’d had time to reply.
I’d written a function for consolidating blank lines:

M.consolidate_blank_lines = function()
  if api.nvim_get_current_line() ~= "" then
    return
  end

  local search_flags = {
    ["start"] = "nWb", -- prev line
    ["end"] = "nW", -- next line
  }

  local range = {}
  for dir, flags in pairs(search_flags) do
    -- TODO: check this regex
    range[dir] = fn.search("\\(^\\s*$\\)\\@!", flags)
  end

  -- remove the lines
  if range["end"] - range["start"] > 0 then
    api.nvim_buf_set_lines(0, range["start"] + 1, range["end"] - 1, true, {})
    api.nvim_win_set_cursor(0, {range["start"] + 1, 1})
  end
end

Call it with the following command (I’ve included a couple of related keymaps for adding blank lines above/below

" add empty line(s) above/below current
nnoremap <silent> [<space>  :<C-u>put!=repeat([''],v:count)<Bar>']+1<CR>
nnoremap <silent> ]<space>  :<C-u>put =repeat([''],v:count)<Bar>'[-1<CR>

" consolidate multiple blank lines
nnoremap <silent> <space><bs> :call v:lua.require'vimrc_utils'.consolidate_blank_lines()<cr>

My comments suggest it was a WIP, but it seems to work fine from my brief test.

1 Like

Just a one more question:

I have saved the function into ~/.config/nvim/lua/tools.lua
and added:

local M = {}

When a run the mapping:

map('n', '<leader>d', '<cmd>lua require("tools").consolidate_blank_lines()<cr>')

neovim says: E5108: Error executing lua /home/sergio/.config/nvim/lua/tools.lua:21: attempt to index global ‘fn’
(a nil value)

Then I fixed the aliases until been able to run the function, but the actual behavior does not fits my entire needs. Due to your level of knowledge in lua/vim I think you can help “us” a little bit more. (Thaks in advance)

And yet, it only squeezes blank lines between two paragraphs, the original idea was to make two, three or more blank lines into one in the whole documment.

My code

function _G.preserve(cmd)
    local cmd = string.format('keepjumps keeppatterns execute %q', cmd)
    local original_cursor = vim.fn.winsaveview()
    vim.api.nvim_command(cmd)
    vim.fn.winrestview(original_cursor)
end


function _G.delblanklines()
    -- searchresult() function to restore cursor properly
    if (vim.bo.filetype ~= 'binary') or (vim.bo.filetype ~= 'diff') then
        preserve('sil! keepp keepj %s/^\\n\\{2,}/\\r/ge')
        preserve('sil! keepp keepj %s/\\v($\\n\\s*)+%$/\\r/e')
    end
end

Now I have these functions

-- -- https://bit.ly/3g6vYIW
-- in my init.lua
function _G.preserve(cmd)
        local cmd = string.format('keepjumps keeppatterns execute %q', cmd)
        local original_cursor = vim.fn.winsaveview()
        vim.api.nvim_command(cmd)
        vim.fn.winrestview(original_cursor)
end

In my /lua/tools.lua

M = {}

M.squeeze_blank_lines = function()
    -- references: https://vi.stackexchange.com/posts/26304/revisions
    local old_query = vim.fn.getreg('/')    -- save search register
    preserve('sil! 1,.s/^\\n\\{2,}/\\r/gn') -- set current search count number
    local result = vim.fn.searchcount({maxcount = 1000, timeout = 500}).current
    local line, col = unpack(vim.api.nvim_win_get_cursor(0))
    preserve('sil! keepp keepj %s/^\\n\\{2,}/\\r/ge')
    preserve('sil! keepp keepj %s/\\v($\\n\\s*)+%$/\\r/e')
    vim.api.nvim_win_set_cursor({0}, {(line - result), col})
    vim.fn.setreg('/', old_query)           -- restore search register
end


return M

I am still testing these ideas, learning a lot about neovim and lua.