kevinhwang91 / nvim-ufo

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

Automatically fold imports on entry #64

Closed ecosse3 closed 2 years ago

ecosse3 commented 2 years ago

Feature description

Hi,

it would be nice to have such an option that we can enable to fold all imports automatically on entry. Personally, I'm working with Javascript/TypeScript/TSX daily and some of my files have a long list of imports. It would be nice if they would be folded by default so I can easily unfold them with za or zo.

Pretty often I'm going to definition by LSP which brings me to the imported statement so they will unfold anyway and if they are folded by default I have a better overview of the whole file context.

Describe the solution you'd like

Config option to automatically fold imports on file entry. Maybe a list of filetypes (or attach option via lsp?) where it's enabled/disabled would be great.

Additional context

No response

kevinhwang91 commented 2 years ago

UFO_LOG=info nvim tail -f ~/.cache/nvim/ufo.log Does the kind field include imports for your language server?

ecosse3 commented 2 years ago

@kevinhwang91 Yes, I work mainly with typescript/tsx:

[22-08-15 12:39:05] [INFO] manager.lua:191 : apply fold ranges: { {
    endLine = 7,
    kind = "imports",
    startLine = 0
  }, {
    endLine = 36,
    startLine = 9
  }, {
    endLine = 35,
    startLine = 9
  }, {
    endLine = 20,
    startLine = 10
  }, {
    endLine = 19,
    startLine = 10
  }, {
    endLine = 19,
    startLine = 11
  }, {
    endLine = 18,
    startLine = 12
  }, {
    endLine = 17,
    startLine = 13
  }, {
    endLine = 16,
    startLine = 14
  }, {
    endLine = 35,
    startLine = 21
  }, {
    endLine = 34,
    startLine = 21
  }, {
    endLine = 34,
    startLine = 26
  }, {
    endLine = 33,
    startLine = 26
  }, {
    endLine = 32,
    startLine = 27
  } }
[22-08-15 12:39:05] [INFO] manager.lua:192 : apply fold rowPairs: {}
kevinhwang91 commented 2 years ago

Great.

kevinhwang91 commented 2 years ago

Add openFoldsExceptKinds action, the workflow is better now. vim.keymap.set('n', 'zr', require('ufo').openFoldsExceptKinds)

akinsho commented 2 years ago

This feature would be so great to have for treesitter as well, maybe it could be done using the capture names which is how a lot of treesitter based functionality works e.g. @include etc.

kevinhwang91 commented 2 years ago

This feature would be so great to have for treesitter as well, maybe it could be done using the capture names which is how a lot of treesitter based functionality works e.g. @include etc.

It's difficult to imp the feature for treesitter provider.

  1. Default query in fold without capturing comment;
  2. Even capturing comment, the node range is discontinuous, and per node range only occupies a single line;
  3. imports is similar to comment, node range of some language is discontinuous;
  4. No idea how to caputre the imports because node type in languages is different;
akinsho commented 2 years ago

Default query in fold without capturing comment;

I'm not sure if I understand this limitation, I don't think it matters if there are comments inside the region a user choses to fold. It's their choice, after all

Even capturing comment, the node range is discontinuous, and per node range only occupies a single line;

When I fold using treesitter the ranges appear to span multiple lines and to be continuous? Is this some hidden implementation issue?

No idea how to caputre the imports because node type in languages is different;

These details should be left to the user I think, I think a user should simply specify the name of the capture for their language and if the treesitter node matches that name then it should be closed.

I'm sure some of this is over simplified on my side, but I don't know the internal workings of this plugin. I only know there are a lot of treesitter based plugins that work by allowing a user to specify the name of a capture, i.e. (comment) @comment then user says include = {'@comment' or 'comment'}.

kevinhwang91 commented 2 years ago

Default query in fold without capturing comment;

I'm not sure if I understand this limitation, I don't think it matters if there are comments inside the region a user choses to fold. It's their choice, after all

Even capturing comment, the node range is discontinuous, and per node range only occupies a single line;

When I fold using treesitter the ranges appear to span multiple lines and to be continuous? Is this some hidden implementation issue?

No idea how to caputre the imports because node type in languages is different;

These details should be left to the user I think, I think a user should simply specify the name of the capture for their language and if the treesitter node matches that name then it should be closed.

I'm sure some of this is over simplified on my side, but I don't know the internal workings of this plugin. I only know there are a lot of treesitter based plugins that work by allowing a user to specify the name of a capture, i.e. (comment) @comment then user says include = {'@comment' or 'comment'}.

Run TSPlaygroundToggle, observe the folding range in Neovim and check out nvim-treesitter/queries/xxx/folds.scm you can peek some details of how folding work with treesitter.

I have no idea how to imp, PR is welcome.

akinsho commented 2 years ago

@kevinhwang91 I've spent a bit of time contributing to nvim-treesitter, so I'm familiar with things on that side, it's more how the folds are detected and implemented in this plugin that I don't know. In either case, thought I'd ask. Realistically, got more than enough bugs and issues to occupy my time in my own plugins, but might have a look at some point.

kevinhwang91 commented 2 years ago

@kevinhwang91 I've spent a bit of time contributing to nvim-treesitter, so I'm familiar with things on that side, it's more how the folds are detected and implemented in this plugin that I don't know. In either case, thought I'd ask. Realistically, got more than enough bugs and issues to occupy my time in my own plugins, but might have a look at some point.

Getting folding range is similar to nvim_treesitter#foldexpr(), https://github.com/kevinhwang91/nvim-ufo/blob/0ed92b53e5f356d1b9dfa2bf39d152620a3874e0/lua/ufo/provider/treesitter.lua#L71-L82

jrmoulton commented 1 year ago

This is awesome! From what I can tell LSP only supports comments, imports and regions. Would there be any way to get similar functionality as folding comments for folding functions or other specific region types?

kevinhwang91 commented 1 year ago

This is awesome! From what I can tell LSP only supports comments, imports and regions. Would there be any way to get similar functionality as folding comments for folding functions or other specific region types?

https://github.com/kevinhwang91/nvim-ufo/blob/3f649eedec68dfa62d49a6fe80c19e1cad6d7afc/lua/ufo/fold/manager.lua#L178-L182

You can hack in two ways.

  1. If you are using the LSP client like coc.nvim which can process results by using middleware, add specified kind to range;
  2. Select a provider with a function like doc/example.lua, getFolds('lsp', bufnr) and process the result to add specified kind to range;

setup close_fold_kinds = {'your_kind'}