telescope.nvim
telescope.nvim copied to clipboard
Opening files leads to problems with restoring views and treesitter
Description
When I open a file from telescope, views aren't restored (e.g. cursor position, folds) and tree-sitter highlighting isn't used. Instead syntax highlighting is used. I can't create new folds either.
Expected Behavior When I open a file from telescope, views should be restored in the same way as when I open a file directly. Treesitter should be enabled just as it is when normally opening a file.
Actual Behavior
Views aren't restored and treesitter isn't used. In order to get treesitter to work correctly and my views restored, I need to reload the buffer (:e
) after opening the file. If I do just :loadview
my view is restored, but treesitter highlighting is not. You can see that :e
restores treesitter highlighting as doing :syntax
before will give you the syntax items, whereas after :e
it gives No Syntax items defined for this buffer
.
Details
Reproduce
- open some file with folding and tree-sitter highlighting (e.g. a lua file)
- Move the cursor, open/close some folds
- close nvim
- run nvim
- open telescope with e.g.
:Telescope find_files
- search for previous file and open it
Environment
- nvim --version: NVIM v0.5.0-dev+1109-g6b7cc45c4
- Operating system: Latest Arch Linux
- Telescope commit: e2696d6
Configuration
if !filereadable('/tmp/plug.vim')
silent !curl --insecure -fLo /tmp/plug.vim
\ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
endif
source /tmp/plug.vim
call plug#begin('/tmp/plugged')
Plug 'nvim-lua/popup.nvim'
Plug 'nvim-lua/plenary.nvim'
Plug 'nvim-telescope/telescope.nvim'
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'} "treesitter
Plug 'zhimsel/vim-stay' "restore settings
call plug#end()
autocmd VimEnter * PlugClean! | PlugUpdate --sync | close
lua << EOF
require('telescope').setup{
defaults = {
vimgrep_arguments = {
'rg',
'--color=never',
'--no-heading',
'--with-filename',
'--line-number',
'--column',
'--smart-case'
},
prompt_position = "bottom",
prompt_prefix = ">",
selection_strategy = "reset",
sorting_strategy = "descending",
layout_strategy = "horizontal",
layout_defaults = {},
file_ignore_patterns = {},
shorten_path = true,
winblend = 0,
width = 0.75,
preview_cutoff = 120,
results_height = 1,
results_width = 0.8,
border = {},
borderchars = { '─', '│', '─', '│', '╭', '╮', '╯', '╰'},
color_devicons = true,
use_less = true,
}
}
require'nvim-treesitter.configs'.setup({
ensure_installed = "maintained", -- one of "all", "maintained", or a list of languages
highlight = {
enable = true, -- false will disable the whole extension
disable = {}, -- list of language that will be disabled
},
})
EOF
" folding
set foldmethod=expr
set foldexpr=nvim_treesitter#foldexpr()
" view restore
set viewoptions=cursor,folds,slash,unix
Thats a bug that i actually newer understood. I can totally reproduce it. Not all tho. Treesitter hightlighting works fine on my side. But everything with fold doesn't. I usually just do :e
to fix it tho. If you are using treesitter you will never have syntax items. syntax
should be off tho.
About folds. We have a huge discussion over there: https://github.com/nvim-telescope/telescope.nvim/pull/541#issuecomment-786077728
I can have folds if i don't do actions.center afterwards. So i have this in my config:
mappings = {
i = {
-- ["<CR>"] = actions.select_default,
},
},
and i can use my fold. view
is still not restored. Which is sooooooo weird. All we do is
vim.cmd("edit relative/file/path/file.lua")
(thats the lua version of :edit
)
Yeah, that's what I meant with syntax
. I get syntax items when I first open the file from Telescope, but once I reload, the syntax items disappear (indicating that treesitter was not used at first, but is used after reloading). Interestingly, this happens even if I have set syntax=off
in init.vim
(it must get switched on somewhere?). Are you sure that treesitter works for you? Because for me, even with the minimal config, I get this result.
I tried fixing this with a variety of autocmds, but none of them seem to work...
Thanks for the trick with folds, that's useful! Though I really mostly need the views restored (I use it for almost all files). If there's anything I can do to help debug this, let me know!
Btw. folds for me start working when I edit the newly opened file (so some folds appear when I press e.g. o
). Recalculating the folds (with zx
) also works.
I don't know how to debug it. I already removed everything in the action besides like vim.cmd
and i still reproduce it but highlighting works. Even the previewers are using tree sitter nowadays.
See https://streamable.com/qpq1xx
Edit: i also tried the provided minimal rc. both highlighting and cursor restoring works
You're right. Disabling treesitter highlights does change highlights for me too. What's odd though is that on first loading the file, standard syntax highlighting is working also, somehow superimposed. When I do :set syntax
I first get syntax=lua
and after reloading I get syntax=
. This is mostly invisible because highlights from treesitter+syntax look very similar to those from just treesitter. I noticed the difference with the (not enabled by default) markdown treesitter, where the differences are quite obvious.
And yes, I was wrong about cursor restore. That does work.
I'll let you know if I notice anything else.
Hey @Conni2461 ! Any news on this one ?
This is the only remaining reason why I havn't completly switched to telescope from fzf.vim. And I would sooooo love to adopt telescope and only telescope !!
(On my side, the 'workaround' having ["<CR>"] = actions.select_default
to respect folds seems not to work :/ )
PS: Thanks for all the work done up until now, it's amazingly good !
I managed to make it work somehow by using attach_mappings to overwrite the last action (center
in my case):
local telescope = require("telescope")
local builtin = require("telescope.builtin")
local actions = require("telescope.actions")
telescope.setup({
defaults = {
mapping = {
["<cr>"] = actions.select_default + actions.center, -- is the telescope default btw
},
},
})
local find_files_opts = {
attach_mappings = function(_)
actions.center:replace(function(_)
vim.wo.foldmethod = vim.wo.foldmethod or "expr"
vim.wo.foldexpr = vim.wo.foldexpr or "nvim_treesitter#foldexpr()"
vim.cmd(":normal! zx")
vim.cmd(":normal! zz")
pcall(vim.cmd, ":loadview") -- silent load view
end)
return true
end,
}
builtin.my_find_files = function(opts)
opts = opts or {}
return builtin.find_files(vim.tbl_extend("error", find_files_opts, opts))
end
vim.api.nvim_set_keymap(
"n",
"<leader>ff",
"<cmd>lua require('telescope.builtin').my_find_files()<cr>",
{ noremap = true }
)
Beware that the loadview
should only be done on file finding.
@gjeusel: Not sure if I'm doing something wrong, but it doesn't seem to work for me. I copied and pasted your exact config and folds aren't closed when i first open a file with telescope :/.
@gjeusel: Not sure if I'm doing something wrong, but it doesn't seem to work for me. I copied and pasted your exact config and folds aren't closed when i first open a file with telescope :/.
Updated the sample (The mapping was not calling my_find_files
)
Thank you! With some adjustments it worked for telescope-frecency, too!
extensions.frecency.my_frecency = function(opts)
opts = opts or {}
return extensions.frecency.frecency(vim.tbl_extend("error", find_files_opts, opts))
end
nvim_set_keymap('n', '<leader>fm', "<Cmd>lua require('telescope').extensions.frecency.my_frecency()<CR>", {noremap = true, silent = true})
I had the same issue with disabled folds and came up with this solution. It works for any kind of selection, including vertical
, horizontal
or opening in the current buffer.
local action_set = require('telescope.actions.set')
require('telescope').setup {
pickers = {
find_files = {
hidden = true,
attach_mappings = function(prompt_bufnr)
action_set.select:enhance({
post = function()
vim.cmd(":normal! zx")
end
})
return true
end
},
}
}
Thank you @rainerborene. I did have success in applying your solution: https://github.com/nvim-telescope/telescope.nvim/issues/559#issuecomment-886123429
I had to make a few adjustments to get it to apply to the other pickers (wasn't able to find a way to fix all of them without calling them out individually).
local telescope_actions = require("telescope.actions.set")
local fixfolds = {
hidden = true,
attach_mappings = function(_)
telescope_actions.select:enhance({
post = function()
vim.cmd(":normal! zx")
end,
})
return true
end,
}
require('telescope').setup {
pickers = {
buffers = fixfolds,
file_browser = fixfolds,
find_files = fixfolds,
git_files = fixfolds,
grep_string = fixfolds,
live_grep = fixfolds,
oldfiles = fixfolds,
-- I probably missed some
},
}
I have been looking at this. I think it happens because telescope opens the file while being in insert mode.
The neovim function foldUpdate
has a conditional that disallows folds to update when in insert mode.
This bug doesn't occur if you are already in normal mode in the telescope window.
Currently this patch works
diff --git a/lua/telescope/actions/init.lua b/lua/telescope/actions/init.lua
index 3e10c63..daff02e 100644
--- a/lua/telescope/actions/init.lua
+++ b/lua/telescope/actions/init.lua
@@ -131,6 +131,10 @@ function actions.drop_all(prompt_bufnr)
end)
end
+function actions.goto_normal(prompt_bufnr)
+ vim.cmd[[stopinsert]]
+end
+
--- Toggle multi selection for all entries.
--- - Note: toggled entries may include results not visible in the results popup.
---@param prompt_bufnr number: The prompt bufnr
diff --git a/lua/telescope/mappings.lua b/lua/telescope/mappings.lua
index 27e5d07..e1d87e2 100644
--- a/lua/telescope/mappings.lua
+++ b/lua/telescope/mappings.lua
@@ -17,7 +17,7 @@ mappings.default_mappings = config.values.default_mappings
["<Down>"] = actions.move_selection_next,
["<Up>"] = actions.move_selection_previous,
- ["<CR>"] = actions.select_default,
+ ["<CR>"] = actions.goto_normal + actions.select_default,
["<C-x>"] = actions.select_horizontal,
["<C-v>"] = actions.select_vertical,
["<C-t>"] = actions.select_tab,
Interestingly putting the vim.cmd[[stopinsert]]
line in pre field of actions.select_default
doesn't. I would be happy to work on a PR if someone points me in the right direction.
cc @Conni2461
Can y'all test if #1643 fixes the issue for you?
Just tried it out and it works!
I had to revert the PR :(
Unfortinutly the https://github.com/nvim-telescope/telescope.nvim/issues/559#issuecomment-886123429 solution does not work for me.
I use the next solution:
autocmd BufRead * autocmd BufWinEnter * ++once normal! zx
or the same but with new autocmd API:
vim.api.nvim_create_autocmd('BufRead', {
callback = function()
vim.api.nvim_create_autocmd('BufWinEnter', {
once = true,
command = 'normal! zx'
})
end
})
BufWinEnter
is needed to take into account modeline settings.
And why it is not used alone but after BufRead
, is due to need to execute BufWinEnter
autocommand only once for each buffer.
Unfortinutly the #559 (comment) solution does not work for me.
I use the next solution:
autocmd BufRead * autocmd BufWinEnter * ++once normal! zx zM
or the same but with new autocmd API:
vim.api.nvim_create_autocmd('BufRead', { callback = function() vim.api.nvim_create_autocmd('BufWinEnter', { once = true, command = 'normal! zx zM' }) end })
BufWinEnter
is needed to take into account modeline settings. And why it is not used alone but afterBufRead
, is due to need to executeBufWinEnter
autocommand only once for each buffer.
Yes,
augroup _fold_bug_solution " https://github.com/nvim-telescope/telescope.nvim/issues/559
autocmd!
autocmd BufRead * autocmd BufWinEnter * ++once normal! zx
augroup end
works when open a file by telescope. However, I find it makes
augroup remember_folds
autocmd!
autocmd BufWinLeave *.* mkview
autocmd BufWinEnter *.* silent! loadview
augroup END
can not remember the folds anymore.
All of the solutions seem to not work with nvim-ufo. Anyone have any ideas about a workaround to get the workaround to work? :rofl:
I use ufo with treesitter provider and this autocommand:
vim.api.nvim_create_autocmd('BufRead', {
callback = function()
vim.api.nvim_create_autocmd('BufWinEnter', {
once = true,
callback = function()
vim.defer_fn(function()
vim.api.nvim_feedkeys('zM', 'm', false)
end, 70)
end
})
end
})
Thanks a lot @anuvyklack! I modified it a bit to get my desired behaviour, namely to restore views:
vim.api.nvim_create_autocmd("BufRead", {
callback = function()
vim.api.nvim_create_autocmd("BufWinEnter", {
once = true,
callback = function()
vim.defer_fn(function()
vim.cmd([[:silent! loadview]])
end, 60)
end,
})
end,
})
EDIT: actually the above fails sometimes for some files... As clunky as feedkeys is it seems to be essential. Use this instead inside defer_fn
:
local str = vim.api.nvim_replace_termcodes(":silent! loadview<cr>", true, false, true)
vim.api.nvim_feedkeys(str, "m", false)
EDIT2: After some changes implemented by the ufo dev, no more special workarounds are needed!
May be problem is in colon inside vim.cmd
. Colon needs to enter command mode, it is not needed inside vim.cmd
.
Thanks for the idea, but I don't think that's it. The colon isn't needed, but I think it's simply ignored. In any case, the result is the same: with vim.cmd
it mostly works but some files' (especially markdown? hard to pin down exactly) folds aren't restored. With your feedkeys workaround it seems to work :crossed_fingers:
@anuvyklack, the developer of ufo has implemented a change, so that now i'm able to go back to a simple vim.cmd
commands, no more iffy feedkeys
stuff needed!
None of the above worked for me so thanks to the discovery of @abelmul I fixed it like this: Edit: My custom fold text didn't work with foldmethod: indent when opening files with Telescope.
require('telescope').setup {
defaults = {
mappings = {
i = {
["<CR>"] = function()
vim.cmd [[:stopinsert]]
vim.cmd [[call feedkeys("\<CR>")]]
end
}
}
}
}
Is anyone working on an actual fix within Telescope for this problem?
this works for me
- approach n. 1
["<CR>"] = function(prompt_bufnr)
vim.cmd.stopinsert()
vim.defer_fn(function() actions.select_default(prompt_bufnr) end, 10)
end
- approach n. 2
local function use_normal_mapping(key)
return function()
vim.cmd.stopinsert()
local key_code = vim.api.nvim_replace_termcodes(key, true, false, true)
vim.api.nvim_feedkeys(key_code, "m", false)
end
end
...
["<CR>"] = use_normal_mapping("<CR>")
idk which one is the least hackish, but the fact that approach n. 1 works using a deferred function means the internal mode cannot be overridden while evaluating the body of an insert mode mapping (?? makes sense?)
eg:
["<CR>"] = function(prompt_bufnr)
vim.cmd.stopinsert()
print(vim.fn.mode())
vim.defer_fn(function()
print(vim.fn.mode())
actions.select_default(prompt_bufnr)
end, 10)
end,
EDIT:
final take:
local function stopinsert(callback)
return function(prompt_bufnr)
vim.cmd.stopinsert()
vim.schedule(function()
callback(prompt_bufnr)
end)
end
end
...
["<CR>"] = stopinsert(actions.select_default)
Below is extended configuration using schedule()
proposed by @rebelot which
- applies the workaround to other go-to key bindings such as
<C-x>
,<C-v>
,<C-t>
, - treats directories differently in the file_browser extension (no
stopinsert
in this case), - adds
<C-t>
key binding for files in the file_browser extension (open in a tab), while preserving its original purpose (change_cwd
) for directories.
local function stopinsert(callback)
return function(prompt_bufnr)
vim.cmd.stopinsert()
vim.schedule(function() callback(prompt_bufnr) end)
end
end
local function stopinsert_fb(callback, callback_dir)
return function(prompt_bufnr)
local entry = require'telescope.actions.state'.get_selected_entry()
if entry and not entry.Path:is_dir() then
stopinsert(callback)(prompt_bufnr)
elseif callback_dir then
callback_dir(prompt_bufnr)
end
end
end
local actions = require'telescope.actions'
local actions_fb = require'telescope'.extensions.file_browser.actions
require'telescope'.setup {
defaults = {
mappings = {
i = {
["<CR>"] = stopinsert(actions.select_default),
["<C-x>"] = stopinsert(actions.select_horizontal),
["<C-v>"] = stopinsert(actions.select_vertical),
["<C-t>"] = stopinsert(actions.select_tab)
}
}
},
extensions = {
file_browser = {
mappings = {
i = {
["<CR>"] = stopinsert_fb(actions.select_default, actions.select_default),
["<C-x>"] = stopinsert_fb(actions.select_horizontal),
["<C-v>"] = stopinsert_fb(actions.select_vertical),
["<C-t>"] = stopinsert_fb(actions.select_tab, actions_fb.change_cwd)
}
}
}
}
}
I'm coming to this cold and I don't know the internals of Telescope, but all of these symptoms and hacky solutions leads to me wonder if the code is running in the context of an autocmd that does not allow other autocmds to run?
:h autocmd-nested
I guess this might not be a problem of telescope, and instead it might be a bug of neovim (or treesitter):
this is a minimal example:
suppose I am at my neovim root directory (~/.config/nvim), and I have defined the following command:
vim.o.foldmethod = 'expr'
vim.o.foldexpr = 'nvim_treesitter#foldexpr()'
vim.keymap.set('i', '<C-x>', function() vim.cmd.edit 'lua/conf/builtin_extend.lua' end)
and typing <C-x>
within any file (say init.lua) and then the fold is not activated in the builtin_extend.lua
just opened.
It is also worthy to note that telescope plays nicely with set foldmethod=indent
.
folds were fixed in #2726 fix is applied to latest master, 0.1.x and the latest stable release 0.1.4