kevinhwang91 / nvim-ufo

Not UFO in the sky, but an ultra fold in Neovim.
BSD 3-Clause "New" or "Revised" License
2.16k stars 37 forks source link

Close all folders when file is opened the first time #146

Closed gzagatti closed 11 months ago

gzagatti commented 11 months ago

Feature description

I would like to have all folds closed when the file is opened for the first time. This is useful to get an overview of the file before any action.

Describe the solution you'd like

I would like a configuration an option that allows me to turn this option on.

Additional context

I have tried modifying vim.o.foldlevelstart=0 but it has undesired effects.

When I'm editing a function such as removing a line, it keeps folding which is distracting and causes mistakes.

I prefer to have vim.o.foldlevelstart=99 after I started editing the file. I have also tried playing with vim.o.foldlevel but didn't achieve the desired results. Maybe I have misunderstood these options.

gzagatti commented 11 months ago

I know I can use zM before I start editing the file. But I'd prefer that the file starts with all folds closed.

I have also played around with autocmd but also didn't manage to get the desired behaviour.

gzagatti commented 11 months ago

Thanks to your help on issue #129, I got the correct autocmd.

I am reproducing my modification below for future reference.

vim.api.nvim_create_autocmd('BufReadPost', {
  callback = function()
    if vim.bo.filetype == 'org' then return end
    local winid = vim.api.nvim_get_current_win()
    local method = vim.wo[winid].foldmethod
    if method == 'diff' or method == 'marker' then
      require('ufo').closeAllFolds()
      return
    end
    require('async')(function()
      local bufnr = vim.api.nvim_get_current_buf()
      -- make sure buffer is attached
      require('ufo').attach(bufnr)
      -- getFolds return Promise if providerName == 'lsp'
      local ranges = await(require('ufo').getFolds(bufnr, 'treesitter') or {})
      local ok = require('ufo').applyFolds(bufnr, ranges)
      if ok then
        require('ufo').closeAllFolds()
      end
    end)
  end
})
end

Feel free to suggest any improvements.

gzagatti commented 10 months ago

For future reference I modified my implementation above to deal with some bugs that showed up along the way. First, it deals with the errors raised by UFO when the treesitter grammar is not defined. Second, it ensures that the fold routine is synced such that we don't leave the buffer until the fold is complete or after the timeout.

vim.api.nvim_create_autocmd('BufRead', {
  callback = function()
    vim.cmd[[ silent! foldclose! ]]
    local bufnr = vim.api.nvim_get_current_buf()
    -- make sure buffer is attached
    vim.wait(100, function() require'ufo'.attach(bufnr) end)
    if require'ufo'.hasAttached(bufnr) then
      local winid = vim.api.nvim_get_current_win()
      local method = vim.wo[winid].foldmethod
      if method == 'diff' or method == 'marker' then
        require'ufo'.closeAllFolds()
        return
      end
      -- getFolds returns a Promise if providerName == 'lsp', use vim.wait in this case
      local ok, ranges = pcall(require'ufo'.getFolds, bufnr, 'treesitter')
      if ok and ranges then
        if require'ufo'.applyFolds(bufnr, ranges) then
          require'ufo'.closeAllFolds()
        end
      end
    end
  end
})