Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diagnostics Appear and Disappear #202

Open
acederberg opened this issue Jan 31, 2025 · 11 comments
Open

Diagnostics Appear and Disappear #202

acederberg opened this issue Jan 31, 2025 · 11 comments

Comments

@acederberg
Copy link

acederberg commented Jan 31, 2025

Hi!

I have an issue that I suspect is related to #180.
All of my problems appear in the context of a quarto document.

Otter Config

local otter = require("otter")
otter.setup({
    debug = true,
    buffers = { write_to_disk = true, set_filetype = true },
        verbose = { -- set to false to disable all verbose messages
        no_code_found = true, -- warn if otter.activate is called, but no injected code was found
    },
})

The Symptoms

  1. Code cell diagnostics only appear transiently right after opening and writing to a file.
  2. LSP feedback is not helpful or complete.

Observations

Buffers are created, and modifying the code at the end of the readme to show the current languages like

      local function get_otter_symbols_lang()
        local otterkeeper = require("otter.keeper")
        local main_nr = vim.api.nvim_get_current_buf()
        local langs = {}
        for i, l in ipairs(otterkeeper.rafts[main_nr].languages) do
          langs[i] = i .. ": " .. l
        end
        vim.print("langs", langs)
      end

outputs

{ "1: python", "2: yaml" }

Buffers are written to disk (because of config) and do match what is expected.

When I Write in a Code Cell

(Because of verbose mode)

Error detected while processing TextChangedI Autocommands for "*"..LspRequest Autocommands for "*":                                                                                                                                                                               
Error executing lua callback: ...ian/.local/share/nvim/lazy/otter.nvim/lua/otter/init.lua:244: attempt to concatenate local 'method' (a nil value)                                                                                                                                
stack traceback:                                                                                                                                                                                                                                                                  
        ...ian/.local/share/nvim/lazy/otter.nvim/lua/otter/init.lua:244: in function <...ian/.local/share/nvim/lazy/otter.nvim/lua/otter/init.lua:238>                                                                                                                            
        [C]: in function 'nvim_exec_autocmds'                                                                                                                                                                                                                                     
        /usr/local/share/nvim/runtime/lua/vim/lsp/client.lua:702: in function 'request'                                                                                                                                                                                           
        /usr/local/share/nvim/runtime/lua/vim/lsp.lua:877: in function 'buf_request'                                                                                                                                                                                              
        ....local/share/nvim/lazy/otter.nvim/lua/otter/lsp/init.lua:176: in function 'request'                                                                                                                                                                                    
        /usr/local/share/nvim/runtime/lua/vim/lsp/client.lua:679: in function 'request'                                                                                                                                                                                           
        ...share/nvim/lazy/cmp-nvim-lsp/lua/cmp_nvim_lsp/source.lua:139: in function '_request'                                                                                                                                                                                   
        ...share/nvim/lazy/cmp-nvim-lsp/lua/cmp_nvim_lsp/source.lua:71: in function 'complete'                                                                                                                                                                                    
        ...drian/.local/share/nvim/lazy/nvim-cmp/lua/cmp/source.lua:342: in function 'complete'                                                                                                                                                                                   
        .../adrian/.local/share/nvim/lazy/nvim-cmp/lua/cmp/core.lua:308: in function 'complete'                                                                                                                                                                                   
        .../adrian/.local/share/nvim/lazy/nvim-cmp/lua/cmp/core.lua:178: in function 'callback'                                                                                                                                                                                   
        .../adrian/.local/share/nvim/lazy/nvim-cmp/lua/cmp/core.lua:238: in function 'autoindent'                                                                                                                                                                                 
        .../adrian/.local/share/nvim/lazy/nvim-cmp/lua/cmp/core.lua:170: in function 'on_change'                                                                                                                                                                                  
        .../adrian/.local/share/nvim/lazy/nvim-cmp/lua/cmp/init.lua:372: in function 'callback'                                                                                                                                                                                   
        ...local/share/nvim/lazy/nvim-cmp/lua/cmp/utils/autocmd.lua:53: in function 'emit'                                                                                                                                                                                        
        ...local/share/nvim/lazy/nvim-cmp/lua/cmp/utils/autocmd.lua:14: in function <...local/share/nvim/lazy/nvim-cmp/lua/cmp/utils/autocmd.lua:13>    

After editing for a while I got this instead of the above message

[otter.nvim] Hi there! You triggered an LSP request that is routed through otter.nvim while textlock is active. We would like to fix this, but need to find the exact form of the error message to match against. Please be so kind and open an issue with how you triggered this 
and the error object below:                                                                                                                                                                                                                                                       
"...n/.local/share/nvim/lazy/otter.nvim/lua/otter/keeper.lua:438: Invalid buffer id: 2"                                                                                                                                                                                           
Error detected while processing BufWritePost Autocommands for "<buffer=1>":                                                                                                                                                                                                       
Error executing lua callback: ...n/.local/share/nvim/lazy/otter.nvim/lua/otter/keeper.lua:399: ...n/.local/share/nvim/lazy/otter.nvim/lua/otter/keeper.lua:438: Invalid buffer id: 2                                                                                              
stack traceback:                                                                                                                                                                                                                                                                  
        [C]: in function 'error'                                                                                                                                                                                                                                                  
        ...n/.local/share/nvim/lazy/otter.nvim/lua/otter/keeper.lua:399: in function 'do_with_maybe_texlock'                                                                                                                                                                      
        ...n/.local/share/nvim/lazy/otter.nvim/lua/otter/keeper.lua:437: in function 'sync_raft'                                                                                                                                                                                  
        ...cal/share/nvim/lazy/otter.nvim/lua/otter/diagnostics.lua:41: in function <...cal/share/nvim/lazy/otter.nvim/lua/otter/diagnostics.lua:40>  

The Code

This is the code where the symptoms appeared.

---
title: NLTK Notes
---

`NLTK` stands for 'natural language tool kit'. Natural language processing
was done using hand written rules in its advent, eventually machine learing
algorithms were implemented and performed much better. `NLTK` includes tools
for the following standard computational linguistics concepts:

stemming :

tokenizing :

tagging :

parsing :

::: { .callout-note collapse='true' }

## Setup

First we will need to import `nltk` and get some text to process.
The piece of text I choose to use is from _The Catcher and the Rye_ by
_J.D. Salinger_.

```{python}
import nltk

# NOTE: From `The Catcher and the Rye` by `J.D. Salenger`.
#       Source: https://www.goodreads.com/quotes/629243-i-thought-what-i-d-do-was-i-d-pretend-i-was
text = """
I thought what I'd do was, I'd pretend I was one of those deaf-mutes. That way I
wouldn't have to have any goddam stupid useless conversations with anybody. If
anybody wanted to tell me something, they'd have to write it on a piece of paper
and shove it over to me. They'd get bored as hell doing that after a while, and
then I'd be through with having conversations for the rest of my life.
Everybody'd think I was just a poor deaf-mute bastard and they'd leave me alone.
I'd cook all my own food, and later on, if I wanted to get married or
something, I'd meet this beautiful girl that was also a deaf-mute and we'd get
married. She'd come and live in my cabin with me, and if she wanted to say
anything to me, she'd have to write it on a piece of paper, like everybody else
"""
```

:::

## Tokenization

Tokenization is very straight forward:

```{python}
import nltk
print(nltk.word_tokenize())
```

LspInfo

==============================================================================
lspconfig: require("lspconfig.health").check()

LSP configs active in this session (globally) ~
- Configured servers: lua_ls, ruff, html, yamlls, emmet_language_server, cssls, bashls, pyright, pylsp, somesass_ls, gopls, ts_ls, dotls
- OK Deprecated servers: (none)

LSP configs active in this buffer (bufnr: 1) ~
- Language client log: ~/.local/state/nvim/lsp.log
- Detected filetype: `quarto`
- 1 client(s) attached to this buffer
- Client: `otter-ls[1]` (id: 5, bufnr: [1])
  root directory:    ~/Projects/Blog/
  filetypes:         
  cmd:               ~/Projects/Blog/blog/posts/<function>
  version:           ? (cmd is a function)
  executable:        NA
  autostart:         false
- 4 active client(s) not attached to this buffer:
- Client: `ruff` (id: 1, bufnr: [2])
  root directory:    ~/Projects/Blog/blog/
  filetypes:         python
  cmd:               ~/.local/share/nvim/mason/bin/ruff server
  version:           `ruff 0.9.4`
  executable:        true
  autostart:         true
- Client: `pylsp` (id: 2, bufnr: [2])
  root directory:    ~/Projects/Blog/blog/
  filetypes:         python
  cmd:               ~/Projects/Blog/.venv/bin/pylsp
  version:           `pylsp v1.12.0`
  executable:        true
  autostart:         true
- Client: `pyright` (id: 3, bufnr: [2])
  root directory:    ~/Projects/Blog/
  filetypes:         python
  cmd:               ~/.local/share/nvim/mason/bin/pyright-langserver --stdio
  version:           `?` (Failed to get version) Tried:
  `/home/adrian/.local/share/nvim/mason/bin/pyright-langserver --version`
  `/home/adrian/.local/share/nvim/mason/bin/pyright-langserver -version`
  `/home/adrian/.local/share/nvim/mason/bin/pyright-langserver version`
  `/home/adrian/.local/share/nvim/mason/bin/pyright-langserver --help`
  
  executable:        true
  autostart:         true
- Client: `yamlls` (id: 4, bufnr: [3])
  root directory:    ~/Projects/Blog/
  filetypes:         yaml, yaml.docker-compose, yaml.gitlab
  cmd:               ~/.local/share/nvim/mason/bin/yaml-language-server --stdio
  version:           `?` (Failed to get version) Tried:
  `/home/adrian/.local/share/nvim/mason/bin/yaml-language-server --version`
  `/home/adrian/.local/share/nvim/mason/bin/yaml-language-server -version`
  `/home/adrian/.local/share/nvim/mason/bin/yaml-language-server version`
  `/home/adrian/.local/share/nvim/mason/bin/yaml-language-server --help`
  
  executable:        true
  autostart:         true
@jmbuhr
Copy link
Owner

jmbuhr commented Jan 31, 2025

I don't think it's directly related to #180 (which is due to code chunks with indentations), but it looks like something I want to fix anyways

[otter.nvim] Hi there! You triggered an LSP request that is routed through otter.nvim while textlock is active. We would like to fix this, but need to find the exact form of the error message to match against. Please be so kind and open an issue with how you triggered this and the error object below

but it looks like even printing the error is stopped by another error.

And the first error

Error executing lua callback: ...ian/.local/share/nvim/lazy/otter.nvim/lua/otter/init.lua:244: attempt to concatenate local 'method' (a nil value)

is probably unrelated. It may be that I have to change the shape of the LspRequest debugging autocommand depending on the version of Neovim. So I would be more interested in the errors you get without otters debug option.

@jmbuhr
Copy link
Owner

jmbuhr commented Jan 31, 2025

The Invalid buffer id: 2 error is tripping me up, because as your analysis showed the buffer 2 certainly exists.

@acederberg
Copy link
Author

Thanks for looking at my issue, I really appreciate it, it is a huge help.

The Invalid buffer id: 2 error is tripping me up, because as your analysis showed the buffer 2 certainly exists.

Yeah, I only got that one once. It happened when I was writing up my issue. The output from the lua script was after a restart of nvim so they were not from the same run. However it is strange since I did get my buffers on disk for that run and they are always numbered one and two.

So I would be more interested in the errors you get without otters debug option.

What is interesting is that I don't get any error output with the transient diagnostics outside of debug mode - I only get diagnostics that disappear. Further transient diagnostics only show up for python (in the example) - yaml front matter has diagnostics that stick.

Image

Further, when I run :ls for the above I do not get any otter buffers:

Image

but otter still says the buffers exist:

{ "1: python", "2: yaml" }

@acederberg
Copy link
Author

I was printing the args to local sync_diagnostics = function(args) and went to turn off diagnostics for some of the python lsps (was using pyright, ruff, and pylsp) so that logs would be more clear. After turning off pylsp, my diagnostics started working. My pylsp config looks like

      lspconfig.pylsp.setup({
        settings = {
          pylsp = {
            plugins = {
              pycodestyle = { enabled = false },
              -- type checker
              pylsp_mypy = {
                enabled = true,
                report_progess = true,
              },
              -- auto-completion options
              jedi_completion = { enabled = true, fuzzy = true },
              -- import sorting
              pyls_isort = { enabled = true },
            },
          },
        },
      })

What it looks like is (and the logs bellow show that) pyright pushes the right diagnostics for the injected code, but then pylsp overwrites the output making it disappear. What should really happen is that the diagnostics should be merged together. ...I might also be wrong about this.

Logs Without PyLSP

Logs by changing sync_diagnostics to

  local sync_diagnostics = function(args)
    if vim.tbl_contains(vim.tbl_values(keeper.rafts[main_nr].buffers), args.buf) then
      local diags = args.data.diagnostics
      vim.print("sync_diagnostics diagnostics", args)
      vim.diagnostic.reset(nss[args.buf], main_nr)
      if config.cfg.handle_leading_whitespace then
        for _, diag in ipairs(diags) do
          local offset = keeper.get_leading_offset(diag.lnum, main_nr)
          diag.col = diag.col + offset
          diag.end_col = diag.end_col + offset
        end
      end
      vim.diagnostic.set(nss[args.buf], main_nr, diags, {})
    end
  end
sync_diagnostics diagnostics                                                                                                                                                                                                                                                      
{                                                                                                                                                                                                                                                                                 
  buf = 3,                                                                                                                                                                                                                                                                        
  data = {                                                                                                                                                                                                                                                                        
    diagnostics = {}                                                                                                                                                                                                                                                              
  },                                                                                                                                                                                                                                                                              
  event = "DiagnosticChanged",                                                                                                                                                                                                                                                    
  file = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.yml",                                                                                                                                                                                                        
  group = 42,                                                                                                                                                                                                                                                                     
  id = 91,                                                                                                                                                                                                                                                                        
  match = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.yml"                                                                                                                                                                                                        
}                                                                                                                                                                                                                                                                                 
sync_diagnostics diagnostics                                                                                                                                                                                                                                                      
{                                                                                                                                                                                                                                                                                 
  buf = 2,                                                                                                                                                                                                                                                                        
  data = {                                                                                                                                                                                                                                                                        
    diagnostics = { {                                                                                                                                                                                                                                                             
        bufnr = 2,                                                                                                                                                                                                                                                                
        col = 6,                                                                                                                                                                                                                                                                  
        end_col = 11,                                                                                                                                                                                                                                                             
        end_lnum = 5,                                                                                                                                                                                                                                                             
        lnum = 5,                                                                                                                                                                                                                                                                 
        message = "Statements must be separated by newlines or semicolons",                                                                                                                                                                                                       
        namespace = 20,                                                                                                                                                                                                                                                           
        severity = 1,                                                                                                                                                                                                                                                             
        source = "Pyright",                                                                                                                                                                                                                                                       
        user_data = {                                                                                                                                                                                                                                                             
          lsp = {                                                                                                                                                                                                                                                                 
            message = "Statements must be separated by newlines or semicolons",                                                                                                                                                                                                   
            range = {                                                                                                                                                                                                                                                             
              ["end"] = {                                                                                                                                                                                                                                                         
                character = 11,                                                                                                                                                                                                                                                   
                line = 5                                                                                                                                                                                                                                                          
              },                                                                                                                                                                                                                                                                  
              start = {                                                                                                                                                                                                                                                           
                character = 6,                                                                                                                                                                                                                                                    
                line = 5                                                                                                                                                                                                                                                          
              }                                                                                                                                                                                                                                                                   
            },                                                                                                                                                                                                                                                                    
            severity = 1,                                                                                                                                                                                                                                                         
            source = "Pyright"                                                                                                                                                                                                                                                    
          }                                                                                                                                                                                                                                                                       
        }                                                                                                                                                                                                                                                                         
      }, {                                                                                                                                                                                                                                                                        
        bufnr = 2,                                                                                                                                                                                                                                                                
        code = "reportUnusedExpression",                                                                                                                                                                                                                                          
        col = 0,                                                                                                                                                                                                                                                                  
        end_col = 5,                                                                                                                                                                                                                                                              
        end_lnum = 5,                                                                                                                                                                                                                                                             
        lnum = 5,                                                                                                                                                                                                                                                                 
        message = "Expression value is unused",                                                                                                                                                                                                                                   
        namespace = 20,                                                                                                                                                                                                                                                           
        severity = 2,                                                                                                                                                                                                                                                             
        source = "Pyright",                                                                                                                                                                                                                                                       
        user_data = {                                                                                                                                                                                                                                                             
          lsp = {                                                                                                                                                                                                                                                                 
            code = "reportUnusedExpression",                                                                                                                                                                                                                                      
            codeDescription = {                                                                                                                                                                                                                                                   
              href = "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportUnusedExpression"                                                                                                                                                                
            },                                                                                                                                                                                                                                                                    
            message = "Expression value is unused",                                                                                                                                                                                                                               
            range = {                                                                                                                                                                                                                                                             
              ["end"] = {                                                                                                                                                                                                                                                         
                character = 5,                                                                                                                                                                                                                                                    
                line = 5                                                                                                                                                                                                                                                          
              },                                                                                                                                                                                                                                                                  
              start = {                                                                                                                                                                                                                                                           
                character = 0,                                                                                                                                                                                                                                                    
                line = 5                                                                                                                                                                                                                                                          
              }                                                                                                                                                                                                                                                                   
            },                                                                                                                                                                                                                                                                    
            severity = 2,                                                                                                                                                                                                                                                         
            source = "Pyright"                                                                                                                                                                                                                                                    
          } 
      } } 
  },      
  event = "DiagnosticChanged",
  file = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.py",
  group = 42,
  id = 91,
  match = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.py"
}         
sync_diagnostics diagnostics
{         
  buf = 3,
  data = {
    diagnostics = {}
  },      
  event = "DiagnosticChanged",
  file = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.yml",
  group = 42,
  id = 91,
  match = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.yml"
}                              

Logs With PyLSP

sync_diagnostics diagnostics                                                                                                                                                                                                                                            
{                                                                                                                                                                                                                                                                                 
  buf = 3,                                                                                                                                                                                                                                                                        
  data = {                                                                                                                                                                                                                                                                        
    diagnostics = {}                                                                                                                                                                                                                                                              
  },                                                                                                                                                                                                                                                                              
  event = "DiagnosticChanged",                                                                                                                                                                                                                                                    
  file = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.yml",                                                                                                                                                                                                        
  group = 42,                                                                                                                                                                                                                                                                     
  id = 92,                                                                                                                                                                                                                                                                        
  match = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.yml"                                                                                                                                                                                                        
}                                                                                                                                                                                                                                                                                 
sync_diagnostics diagnostics                                                                                                                                                                                                                                                      
{                                                                                                                                                                                                                                                                                 
  buf = 2,                                                                                                                                                                                                                                                                        
  data = {                                                                                                                                                                                                                                                                        
    diagnostics = { {                                                                                                                                                                                                                                                             
        bufnr = 2,                                                                                                                                                                                                                                                                
        col = 6,                                                                                                                                                                                                                                                                  
        end_col = 11,                                                                                                                                                                                                                                                             
        end_lnum = 5,                                                                                                                                                                                                                                                             
        lnum = 5,                                                                                                                                                                                                                                                                 
        message = "Statements must be separated by newlines or semicolons",                                                                                                                                                                                                       
        namespace = 20,                                                                                                                                                                                                                                                           
        severity = 1,                                                                                                                                                                                                                                                             
        source = "Pyright",                                                                                                                                                                                                                                                       
        user_data = {                                                                                                                                                                                                                                                             
          lsp = {                                                                                                                                                                                                                                                                 
            message = "Statements must be separated by newlines or semicolons",                                                                                                                                                                                                   
            range = {                                                                                                                                                                                                                                                             
              ["end"] = {                                                                                                                                                                                                                                                         
                character = 11,                                                                                                                                                                                                                                                   
                line = 5                                                                                                                                                                                                                                                          
              },                                                                                                                                                                                                                                                                  
              start = {                                                                                                                                                                                                                                                           
                character = 6,                                                                                                                                                                                                                                                    
                line = 5                                                                                                                                                                                                                                                          
              }                                                                                                                                                                                                                                                                   
            },                                                                                                                                                                                                                                                                    
            severity = 1,                                                                                                                                                                                                                                                         
            source = "Pyright"                                                                                                                                                                                                                                                    
          }                                                                                                                                                                                                                                                                       
        }                                                                                                                                                                                                                                                                         
      }, {                                                                                                                                                                                                                                                                        
        bufnr = 2,                                                                                                                                                                                                                                                                
        code = "reportUnusedExpression",                                                                                                                                                                                                                                          
        col = 0,                                                                                                                                                                                                                                                                  
        end_col = 5,                                                                                                                                                                                                                                                              
        end_lnum = 5,                                                                                                                                                                                                                                                             
        lnum = 5,                                                                                                                                                                                                                                                                 
        message = "Expression value is unused",                                                                                                                                                                                                                                   
        namespace = 20,                                                                                                                                                                                                                                                           
        severity = 2,                                                                                                                                                                                                                                                             
        source = "Pyright",                                                                                                                                                                                                                                                       
        user_data = {                                                                                                                                                                                                                                                             
          lsp = {                                                                                                                                                                                                                                                                 
            code = "reportUnusedExpression",                                                                                                                                                                                                                                      
            codeDescription = {                                                                                                                                                                                                                                                   
              href = "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportUnusedExpression"                                                                                                                                                                
            },                                                                                                                                                                                                                                                                    
            message = "Expression value is unused",                                                                                                                                                                                                                               
            range = {                                                                                                                                                                                                                                                             
              ["end"] = {                                                                                                                                                                                                                                                         
                character = 5,                                                                                                                                                                                                                                                    
                line = 5                                                                                                                                                                                                                                                          
              },                                                                                                                                                                                                                                                                  
              start = {                                                                                                                                                                                                                                                           
                character = 0,                                                                                                                                                                                                                                                    
                line = 5                                                                                                                                                                                                                                                          
              }                                                                                                                                                                                                                                                                   
            },                                                                                                                                                                                                                                                                    
            severity = 2,                                                                                                                                                                                                                                                         
            source = "Pyright"                                                                                                                                                                                                                                                    
          }                                                                                                                                                                                                                                                                       
        }     
      }                                                                                                                                                                                                                                                                         
      } }                                                                                                                                                                                                                                                                         
  },                                                                                                                                                                                                                                                                              
  event = "DiagnosticChanged",                                                                                                                                                                                                                                                    
  file = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.py",                                                                                                                                                                                                         
  group = 42,                                                                                                                                                                                                                                                                     
  id = 92,                                                                                                                                                                                                                                                                        
  match = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.py"                                                                                                                                                                                                         
}                                                                                                                                                                                                                                                                                 
sync_diagnostics diagnostics                                                                                                                                                                                                                                                      
{                                                                                                                                                                                                                                                                                 
  buf = 3,                                                                                                                                                                                                                                                                        
  data = {                                                                                                                                                                                                                                                                        
    diagnostics = {}                                                                                                                                                                                                                                                              
  },                                                                                                                                                                                                                                                                              
  event = "DiagnosticChanged",                                                                                                                                                                                                                                                    
  file = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.yml",                                                                                                                                                                                                        
  group = 42,                                                                                                                                                                                                                                                                     
  id = 92,                                                                                                                                                                                                                                                                        
  match = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.yml"                                                                                                                                                                                                        
}                                                                                                                                                                                                                                                                                 
sync_diagnostics diagnostics                                                                                                                                                                                                                                                      
{                                                                                                                                                                                                                                                                                 
  buf = 2,                                                                                                                                                                                                                                                                        
  data = {                                                                                                                                                                                                                                                                        
    diagnostics = {}                                                                                                                                                                                                                                                              
  },                                                                                                                                                                                                                                                                              
  event = "DiagnosticChanged",                                                                                                                                                                                                                                                    
  file = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.py",                                                                                                                                                                                                         
  group = 42,                                                                                                                                                                                                                                                                     
  id = 92,                                                                                                                                                                                                                                                                        
  match = "/home/adrian/Projects/experiment-1-31-2025/index.qmd.otter.py"                                                                                                                                                                                                         
}                

@jmbuhr
Copy link
Owner

jmbuhr commented Feb 1, 2025

It's :ls! to also list hidden/unlisted buffers (like the otter buffers).

Ok, that makes sense. It seems niche that one would have two language servers providing diagnostics for the same language (I personally use just pyright), but nonetheless something I would like to fix.

What is the effect of this in a pure python buffer? Do the diagnostics just accumulate?

@vandalt
Copy link

vandalt commented Feb 1, 2025

Hello,

Thanks for otter.nvim, it's great :)

I just wanted to chime in to say:

  • I am also seeing similar errors with debug=true when running with pyright and ruff (not pylsp)
  • Only pyright diagnostics are visible, nothing can be seen from ruff
  • Disabling pyright removes the error messages, but ruff diagnostics still cannot be seen, so the missing diagnostics might be a different issue

It seems niche that one would have two language servers providing diagnostics for the same language

I'd say it's relatively common, given that pyright can serve as a type checker and ruff has more extensive linting functionality. Also Lazyvim enables both, so by default many users will have them both.

What is the effect of this in a pure python buffer? Do the diagnostics just accumulate?

Indeed, when both are enabled in a Python file, the diagnostics are merged (see screenshot)

Image

I'll keep looking into this on my end. Let me know if there is anything specific I can do to help debugging!

@jmbuhr
Copy link
Owner

jmbuhr commented Feb 1, 2025

I have now also configured Ruff and it is behaving a bit strangely. Given the following file test.qmd:

```{python}
plt.plot()
```

with the default quarto/otter config, we see Pyright diagnostics in the buffer.

Now if we investigate the otter buffer for python with :b2 (assuming you just opened nvim with nvim test.qmd, 2 should be its number) we see a python file that also only shows the pyright diagnostics. But re-editing the buffer (triggering it's buffopen autocommands etc.) with :e then does show both diagnostics and at that point the printing in #203 also shows the diagnostics.

@jmbuhr
Copy link
Owner

jmbuhr commented Feb 1, 2025

Disabling Pyright still shows the same issues with Ruff, so it's not necessarily just an issue with competition, it's an issue with Ruff not starting up (and maybe also not updating) in our hidden otter buffers. Though if I only have Ruff and then manually trigger ruff by :editing the otter buffer, the ruff diagnostics also show up in the main buffer.

I'm glad about any more hints.

@acederberg
Copy link
Author

Multiple LSPs

What is the effect of this in a pure python buffer? Do the diagnostics just accumulate?

Typically yes, for instance:

Image

I'd say it's relatively common, given that pyright can serve as a type checker and ruff has more extensive linting functionality.

True that, I've heard the same and this is my use case.

Ruff Diagnostics not Working in Injected Buffers

Disabling Pyright still shows the same issues with Ruff, so it's not necessarily just an issue with competition, it's an issue with Ruff not starting up (and maybe also not updating) in our hidden otter buffers. Though if I only have Ruff and then manually trigger ruff by :editing the otter buffer, the ruff diagnostics also show up in the main buffer.

ruff diagnostics do not show up in qmd at all, even when it is the only lsp.

Ruff Diagnostics in Pure python

Image

Ruff Diagnostics in qmd

Image

@jmbuhr
Copy link
Owner

jmbuhr commented Feb 2, 2025

Yes, but curiously they do with the extra manual step I described above (only ruff, no pyright configured, manually open otter buffer, :e, back to qmd).

@vandalt
Copy link

vandalt commented Feb 2, 2025

Some extra info I gathered:

  1. Entering the otter.py buffer and running LspRestart from there also works (similar to :e). Editing the file (e.g. just typing o) also triggers diagnostics.
  2. When going back to the md file, the diagnostics are shown, but they do not update as you type you have to re-do the "python file -> edit -> qmd" loop to see diagnostics updated.

In the LSP log, ruff typically outputs this message when you start editing a python file, and re-prints it on every keypress when you edit.

[ERROR][2025-02-01 17:45:28] ...p/_transport.lua:36	"rpc"	"/home/vandal/.local/share/nvim/mason/bin/ruff"	"stderr"	"   0.385388895s DEBUG ruff:worker:1 ruff_server::resolve: Included path via `include`: /home/vandal/afile.py\n"

In the case of otter buffers, it triggers only when doing the "edit trick" described above, and then stops doing it when you go back to the quarto file.

I'll keep looking into this when I have more time, but wanted to share this in case it's useful.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants