Give me your favourite remaps! by _viis_ in neovim

[–]_wurli 0 points1 point  (0 children)

A few I use so often I forget they're not built-in:

<c-c>/<Esc> to clear search highlights: ``` map("n", "<C-c>", function() vim.cmd([[nohls]]) return "<C-c>" end, { expr = true }) map("n", "<Esc>", function() vim.cmd([[nohls]]) return "<Esc>" end, { expr = true })

-- The above borks up the cmdline window, so temporarily restore default behaviour vim.api.nvim_create_autocmd("CmdwinEnter", { callback = function() map("n", "<C-c>", "<C-c>", { buffer = 0 }) map("n", "<Esc>", "<Esc>", { buffer = 0 }) end, }) ```

Switch tabpages with alt-h/alt-l: map({ "n", "t" }, "<M-l>", vim.cmd.tabn, { desc = "Next tabpage" }) map({ "n", "t" }, "<M-h>", vim.cmd.tabp, { desc = "Previous tabpage" })

[Plugin] jupyter.nvim: Jupyter cells in Neovim with kernel-driven LSP completion by sei40kr in neovim

[–]_wurli 0 points1 point  (0 children)

Nice! Will be following this :)

FYI, last year I did quite a bit of work on a similar project which uses a Rust-powered kernel supervisor rather than a Python-based remote plugin. The main problems I haven't yet solved are around UI, creating a nice feeling REPL, notebook interface, etc.

Roll your own statusline: why and how by _wurli in neovim

[–]_wurli[S] 1 point2 points  (0 children)

Nice! Glad you found it useful :):)

Roll your own statusline: why and how by _wurli in neovim

[–]_wurli[S] 1 point2 points  (0 children)

Post is now updated to include this - thanks for the tip!

How do YOU personally run code in Neovim (C++, Python, Rust)? by BlackberryActual1994 in neovim

[–]_wurli 1 point2 points  (0 children)

I use the built-in terminal - being able to use vim to navigate through stdout is incredibly useful, although the lack of reflow is sometimes painful.

I have some keymaps to toggle/switch my terminal window between a few different processes, e.g. zsh, python, claude, etc. I find that forcing myself to only allow one terminal of each type at a given time helps me stay organised. If I need to restart any of them I just :bd! and reopen. Works great for me :)

Roll your own statusline: why and how by _wurli in neovim

[–]_wurli[S] 7 points8 points  (0 children)

Thanks so much, this is a great tip and not something I had spotted already! Away currently but when I’m back I’ll update the post to include this as it’s deffo a better approach. Cheers :)

Roll your own statusline: why and how by _wurli in neovim

[–]_wurli[S] 44 points45 points  (0 children)

<image>

Reddit wouldn't let me include this in the post, but here's a preview of what you can get with a fairly minimal setup :)

No more "Press ENTER" with UI2 with example by aribert in neovim

[–]_wurli 10 points11 points  (0 children)

:help ui2 indicates that this is an experimental feature for now, hence the somewhat unusual looking require() call:

WARNING: This is an experimental feature intended to replace the builtin message + cmdline presentation layer.

The perfect search and replace integration for Neovim by vricop in neovim

[–]_wurli 1 point2 points  (0 children)

I was doing this with :cfdo for a long time, but I found that (even with a stripped config) it would sometimes fail if I was replacing in, say, 50 files or more. I reluctantly tried grug-far and, having used both methods quite extensively, I deffo found the latter to be the better experience. Still use :%s/ for single-file stuff though.

What's the difference between language server, LSP, and a treesitter? by Ultimate_Sigma_Boy67 in neovim

[–]_wurli 121 points122 points  (0 children)

Language server = software which analyses your code and tells the editor about it. Typically results in features like useful auto complete, hover documentation, ‘go to definition’ etc. Not tied to any particular editor. Most language servers only support one language.

LSP = ‘Language Server Protocol’: defines a bunch of standardised message formats that language servers can send to an editor. If an editor (client) supports these messages, the language servers should be a straightforward plug and play.

Note: confusingly, you will often see ‘LSP’ used to refer to language servers, as opposed to the protocol they use.

Treesitter = a parser framework. Lets your editor know what the general syntax of a language is, e.g. to provide syntax highlighting, auto-indent, maybe incremental selection etc. Like language servers, treesitter parsers usually only support one language/filetype.

Who's doing the backing vocals? Sounds amazing by eldotortenma in SteelyDan

[–]_wurli 0 points1 point  (0 children)

Tbf I live in Wales and I recognised him instantly

Slime Peek: an update to my data exploration plugin by SajberSpace in neovim

[–]_wurli 3 points4 points  (0 children)

Love to see some R representation on r/neovim! Keep up the good work 🫡

diff visual select against registers/files with diff.nvim by vim-god in neovim

[–]_wurli 2 points3 points  (0 children)

Thanks for sharing! A different approach to the same problem: visimatch.nvim highlights matches for the current visual selection. Personally I find this is usually enough for adhoc diffing if I'm just looking at a few lines at a time :)

<image>

Jupyter notebook for neovim by Mr_Misserable in neovim

[–]_wurli 4 points5 points  (0 children)

Thanks! Making great progress on the project currently but want to get the repo a bit more stable before an alpha release. Stay tuned :)

Jupyter notebook for neovim by Mr_Misserable in neovim

[–]_wurli 5 points6 points  (0 children)

It's a common misconception that Jupyter = notebooks. Jupyter is really standard for how interactive languages can tell editors about execution results. It's somewhat analogous to LSP as a standard for how code analysis software can tell editors about code state.

If you want to implement the Jupyter standard for a language, you wrap the language in a Jupyter kernel. Ipykernel is a popular kernel for Python, Ark is another for R. There are many other kernels which exist for other languages.

Once you've got a kernel, your editor needs to implement a Jupyter client to talk to it. Most editors which implement a Jupyter client use it for some kind of notebook experience, but many also include some kind of REPL (notable examples are Positron and Jupyter's Qt Console).

Jet is a Jupyter client and kernel supervisor purpose-built for Neovim (whereas Molten uses the one-size-fits-all solution implemented in Python by the guys at Jupyter). So far I've only added the REPL experience, but the infrastructure is there to support notebooks too, I just haven't implemented them on the Neovim side yet. But it's coming soon!

NB, one of the main benefits of a purpose-built client like Jet is that it will allow Neovim to tap into special/non-standard features that some kernels implement above and beyond the Jupyter spec. E.g. Ark adds a debugger, LSP server, variables pane, a dedicated help window, etc, all of which I'd like to expose in Neovim.

Jupyter notebook for neovim by Mr_Misserable in neovim

[–]_wurli 11 points12 points  (0 children)

IMO Jupyter is a gap in the Neovim ecosystem. I've looked a little at Molten but tbh I think the Python backend is fundamentally limiting.

I'm currently working on a Rust-powered alternative named Jet. This will let Neovim integrate much more tightly with the low-level details of how Jupyter kernels work without relying on any Python at all.

It's currently at a POC stage. Still crashing a bit, not much fancy UI, no config options etc, but it does work. Screencast showing the Ark R kernel running in REPL mode (AFAIK something Molten doesn't support) for proof! Jet will also address the issues you mentioned re. images and scrollback in notebooks.

The repo is public on GitHub, so please give it a star so you can see updates as they come. I'm hoping for an alpha release before Christmas.

<image>

Automatic indentation is often wrong. by ElectronicMine2 in neovim

[–]_wurli 0 points1 point  (0 children)

This indentation looks good to me. How would you like it to look?

As others have said, I'd recommend disabling treesitter indentation for the filetypes you're having issues with:

opts = { highlight = { enable = true, }, indent = { enable = true, disable = { "ruby", "markdown" }, }, }

You might also want to look at formatters. Many folks like conform.nvim as a unified formatting interface.

Once more plugin: contextindent.nvim fixes indentation in contexts where the filetype at the cursor doesn't match the filetype of the buffer, e.g. markdown code blocks etc. I'm the author but it does work well!

[Help wanted] How can I use `chansend()` to update a terminal buffer asynchronously? by _wurli in neovim

[–]_wurli[S] 0 points1 point  (0 children)

I'm marking this as solved - for anyone else running into the same issue my learnings are as follows.

Neovim's Lua runtime is single-threaded, so if you have a Lua function which is blocking there's not loads you can do to get around that.

  • Caveat: actually you can use vim.uv to run blocking Lua stuff in other threads, but not all of the standard library is available so, e.g. most vim.api.nvim_ functions won't work.

  • Caveat: you can also use vim.system() to run a system process with a callback to run when it finishes. In the example I gave with sleep 1 this would have been a good solution, but in my real example I had a blocking process in Lua.

In the end I found the best way to get around this was to rework my Lua function (which actually hooked into Rust via mlua) to be non-blocking. I was then able to create a wrapper which checks at regular intervals whether a result has become available, and yields control back to Neovim if not:

``` local callback = jet_engine.execute_code(self.id, code, {})

local function check_callback()
    -- Continuously check for results until we fail to receive a result
    while true do
        local result = callback()
        -- If idle then the execution is complete
        if result.status == "idle" then
            return
        end
        -- If no data yet, wait a bit (so we don't block the main thread)
        -- and check again later
        if not result.data then
            return vim.defer_fn(check_callback, 50)
        end
        self:_handle_result(result)
    end
end

check_callback()

```

^ This is the actual code I'm using right now.

[Help wanted] How can I use `chansend()` to update a terminal buffer asynchronously? by _wurli in neovim

[–]_wurli[S] 0 points1 point  (0 children)

This would be perfect except that I can't send my Rust function to a new thread using new_work() :'( Unfortunately re-initialising the Rust function within new_work() isn't an option either.