mrcjkb / haskell-tools.nvim

🦥 Supercharge your Haskell experience in neovim!
GNU General Public License v2.0
470 stars 19 forks source link

~/.config/nvim/after/ftplugin/haskell.lua fails loading ht #318

Closed BebeSparkelSparkel closed 9 months ago

BebeSparkelSparkel commented 9 months ago

Neovim version (nvim -v)

v0.9.1

Operating system/version

OpenBSD 7.4

Output of :checkhealth haskell-tools

──────────────────────────────────────────────────────────────────────────────
haskell-tools: require("haskell-tools.health").check()

Checking for Lua dependencies
- OK [nvim-telescope/telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) installed.

Checking external dependencies
- OK haskell-language-server: found haskell-language-server version: 2.5.0.0 (GHC: 9.2.7) (PATH: haskell-language-server-wrapper)
- OK hoogle: found Hoogle 5.0.18.3, https://hoogle.haskell.org/
- OK fast-tags: found fast-tags, version 2.0.2
- OK curl: found curl 8.4.0 (x86_64-unknown-openbsd7.4) libcurl/8.4.0 LibreSSL/3.8.2 zlib/1.3 nghttp2/1.57.0 ngtcp2/0.19.1 nghttp3/0.15.0
- OK haskell-debug-adapter: found haskell-debug-adapter-0.0.39.0
- OK ghci-dap: found The Glorious Glasgow Haskell Compilation System, version 9.2.7

Checking config
- OK No errors found in config.

Checking for conflicting plugins
- OK No conflicting plugins detected.

How to reproduce the issue

nvim src/*.hs

Expected behaviour

I expected the language server to start and have the key maps defined.

Actual behaviour

The language server does not start and the key maps specified in ~/.config/nvim/after/ftplugin/haskell.lua are not defined.

It seems that the require('haskell-tools') fails.

Log files

No response

The minimal config used to reproduce this issue.

~/.config/nvim/init.lua

-- lazy package manager
local plugins = {
        { 'mrcjkb/haskell-tools.nvim'
        , tag = "3.1.1"
        , ft = { 'haskell', 'lhaskell', 'cabal', 'cabalproject' }
        },
        { 'nvim-telescope/telescope.nvim'
        , tag = '0.1.5'
        },
        { 'nvim-treesitter/nvim-treesitter'
        , tag = 'v0.9.1'
        },
        { 'nvim-lua/plenary.nvim'
        , tag = 'v0.1.4'
        },
  { 'neovim/nvim-lspconfig'
  , tag = 'v0.1.7'
  },
}
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    "--branch=stable", -- latest stable release
    lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup(plugins)

~/.config/nvim/after/ftplugin/haskell.lua

local ht = require('haskell-tools')
local bufnr = vim.api.nvim_get_current_buf()
local def_opts = { noremap = true, silent = true, buffer = bufnr, }
-- haskell-language-server relies heavily on codeLenses,
-- so auto-refresh (see advanced configuration) is enabled by default
vim.keymap.set('n', '<space>ca', vim.lsp.codelens.run, opts)
-- Hoogle search for the type signature of the definition under the cursor
vim.keymap.set('n', '<space>hs', ht.hoogle.hoogle_signature, opts)
-- Evaluate all code snippets
vim.keymap.set('n', '<space>ea', ht.lsp.buf_eval_all, opts)
-- Toggle a GHCi repl for the current package
vim.keymap.set('n', '<leader>rr', ht.repl.toggle, opts)
-- Toggle a GHCi repl for the current buffer
vim.keymap.set('n', '<leader>rf', function()
  ht.repl.toggle(vim.api.nvim_buf_get_name(0))
end, def_opts)
vim.keymap.set('n', '<leader>rq', ht.repl.quit, opts)
mrcjkb commented 9 months ago

Hey :wave:

Thanks for reporting. Some questions:

Cheers :smile:

BebeSparkelSparkel commented 9 months ago

The language server works fine without ~/.config/nvim/after/ftplugin/haskell.lua the file.

If the ~/.config/nvim/after/ftplugin/haskell.lua file only has the line

local ht = vim.print(require('haskell-tools'))

the following is printed on nvim start but the sever is not started

{
  dap = {
    discover_configurations = <function 1>
  },
  hoogle = {
    hoogle_signature = <function 2>
  },
  log = {
    get_hls_logfile = <function 3>,
    get_logfile = <function 4>,
    nvim_open_hls_logfile = <function 5>,
    nvim_open_logfile = <function 6>,
    set_level = <function 7>
  },
  lsp = {
    buf_eval_all = <function 8>,
    load_hls_settings = <function 9>,
    restart = <function 10>,
    start = <function 11>,
    stop = <function 12>
  },
  project = {
    open_package_cabal = <function 13>,
    open_package_yaml = <function 14>,
    open_project_file = <function 15>,
    root_dir = <function 16>,
    telescope_package_files = <function 17>,
    telescope_package_grep = <function 18>
  },
  repl = {
    buf_mk_repl_cmd = <function 19>,
    cword_info = <function 20>,
    cword_type = <function 21>,
    load_file = <function 22>,
    mk_repl_cmd = <function 23>,
    operator = <function 24>,
    paste = <function 25>,
    paste_info = <function 26>,
    paste_type = <function 27>,
    quit = <function 28>,
    reload = <function 29>,
    toggle = <function 30>
  },
  tags = {
    generate_package_tags = <function 31>,
    generate_project_tags = <function 32>
  }
}
Press ENTER or type command to continue

However, if ~/.config/nvim/after/ftplugin/haskell.lua only contains

vim.print('test print haskell.lua') 

it prints the following and the server is started

test print haskell.lua
test print haskell.lua
Press ENTER or type command to continue

The following log is from ~/.local/state/nvim/haskell-tools.log . The log ~/.local/state/nvim/lsp.log is not created when the server fails to start but is created when the sever does start.

[START][2024-01-05 15:56:24] haskell-tools.nvim logging initiated
DEBUG | 2024-01-05 15:56:24 | ...zy/haskell-tools.nvim/lua/haskell-tools/log/internal.lua:143 | { "Config", {    dap = {      auto_discover = true,      cmd = { "haskell-debug-adapter" },      logFile = "/home/wjr/.local/share/nvim/haskell-dap.log",      logLevel = "Warning"    },    debug_info = {      unrecognized_keys = {},      was_g_haskell_tools_sourced = true    },    hls = {      auto_attach = <function 1>,      capabilities = {        textDocument = {          callHierarchy = {            dynamicRegistration = false          },          codeAction = {            codeActionLiteralSupport = {              codeActionKind = {                valueSet = { "", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" }              }            },            dataSupport = true,            dynamicRegistration = false,            isPreferredSupport = true,            resolveSupport = {              properties = { "edit" }            }          },          completion = {            completionItem = {              commitCharactersSupport = false,              deprecatedSupport = false,              documentationFormat = { "markdown", "plaintext" },              preselectSupport = false,              snippetSupport = false            },            completionItemKind = {              valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }            },            contextSupport = false,            dynamicRegistration = false          },          declaration = {            linkSupport = true          },          definition = {            linkSupport = true          },          documentHighlight = {            dynamicRegistration = false          },          documentSymbol = {            dynamicRegistration = false,            hierarchicalDocumentSymbolSupport = true,            symbolKind = {              valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }            }          },          hover = {            contentFormat = { "markdown", "plaintext" },            dynamicRegistration = false          },          implementation = {            linkSupport = true          },          publishDiagnostics = {            relatedInformation = true,            tagSupport = {              valueSet = { 1, 2 }            }          },          references = {            dynamicRegistration = false          },          rename = {            dynamicRegistration = false,            prepareSupport = true          },          semanticTokens = {            augmentsSyntaxTokens = true,            dynamicRegistration = false,            formats = { "relative" },            multilineTokenSupport = false,            overlappingTokenSupport = true,            requests = {              full = {                delta = true              },              range = false            },            serverCancelSupport = false,            tokenModifiers = { "declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary" },            tokenTypes = { "namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator" }          },          signatureHelp = {            dynamicRegistration = false,            signatureInformation = {              activeParameterSupport = true,              documentationFormat = { "markdown", "plaintext" },              parameterInformation = {                labelOffsetSupport = true              }            }          },          synchronization = {            didSave = true,            dynamicRegistration = false,            willSave = true,            willSaveWaitUntil = true          },          typeDefinition = {            linkSupport = true          }        },        window = {          showDocument = {            support = true          },          showMessage = {            messageActionItem = {              additionalPropertiesSupport = false            }          },          workDoneProgress = true        },        workspace = {          applyEdit = true,          configuration = true,          didChangeWatchedFiles = {            dynamicRegistration = false,            relativePatternSupport = true          },          semanticTokens = {            refreshSupport = true          },          symbol = {            dynamicRegistration = false,            hierarchicalWorkspaceSymbolSupport = true,            symbolKind = {              valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }            }          },          workspaceEdit = {            resourceOperations = { "rename", "create", "delete" }          },          workspaceFolders = true        }      },      cmd = <function 2>,      debug = false,      default_settings = {        haskell = {          checkParents = "CheckOnSave",          checkProject = true,          formattingProvider = "fourmolu",          maxCompletions = 40,          plugin = {            alternateNumberFormat = {              globalOn = true            },            callHierarchy = {              globalOn = true            },            changeTypeSignature = {              globalOn = true            },            class = {              codeActionsOn = true,              codeLensOn = true            },            eval = {              config = {                diff = true,                exception = true              },              globalOn = true            },            excplicitFixity = {              globalOn = true            },            gadt = {              globalOn = true            },            ["ghcide-code-actions-bindings"] = {              globalOn = true            },            ["ghcide-code-actions-fill-holes"] = {              globalOn = true            },            ["ghcide-code-actions-imports-exports"] = {              globalOn = true            },            ["ghcide-code-actions-type-signatures"] = {              globalOn = true            },            ["ghcide-completions"] = {              config = {                autoExtendOn = true,                snippetsOn = true              },              globalOn = true            },            ["ghcide-hover-and-symbols"] = {              hoverOn = true,              symbolsOn = true            },            ["ghcide-type-lenses"] = {              config = {                mode = "always"              },              globalOn = true            },            haddockComments = {              globalOn = true            },            hlint = {              codeActionsOn = true,              diagnosticsOn = true            },            importLens = {              codeActionsOn = true,              codeLensOn = true,              globalOn = true            },            moduleName = {              globalOn = true            },            pragmas = {              codeActionsOn = true,              completionOn = true            },            qualifyImportedNames = {              globalOn = true            },            refineImports = {              codeActionsOn = true,              codeLensOn = true            },            rename = {              config = {                crossModule = true              },              globalOn = true            },            retrie = {              globalOn = true            },            splice = {              globalOn = true            },            tactics = {              codeActionsOn = true,              codeLensOn = true,              config = {                auto_gas = 4,                max_use_ctor_actions = 5,                proofstate_styling = true,                timeout_duration = 2              },              hoverOn = true            }          }        }      },      logfile = "/tmp/nvim.wjr/cYMgAh/0-haskell-language-server.log",      on_attach = <function 3>,      settings = <function 4>    },    tools = {      codeLens = {        autoRefresh = true      },      definition = {        hoogle_signature_fallback = false      },      hoogle = {        mode = "auto"      },      hover = {        auto_focus = false,        border = { { "╭", "FloatBorder" }, { "─", "FloatBorder" }, { "╮", "FloatBorder" }, { "│", "FloatBorder" }, { "╯", "FloatBorder" }, { "─", "FloatBorder" }, { "╰", "FloatBorder" }, { "│", "FloatBorder" } },        enable = true,        stylize_markdown = false      },      log = {        level = 1,        logfile = "/home/wjr/.local/state/nvim/haskell-tools.log"      },      repl = {        builtin = {          create_repl_window = <function 5>        },        handler = "builtin",        prefer = <function 6>      },      tags = {        enable = <function 7>,        package_events = { "BufWritePost" }      }    }  } }
DEBUG | 2024-01-05 15:56:24 | ...e/nvim/lazy/haskell-tools.nvim/lua/haskell-tools/lsp.lua:53 | Setting up the LSP client...
DEBUG | 2024-01-05 15:56:24 | ...vim/lazy/haskell-tools.nvim/lua/haskell-tools/hoogle.lua:49 | handler = telescope-local
INFO | 2024-01-05 15:56:24 | .../nvim/lazy/haskell-tools.nvim/lua/haskell-tools/repl.lua:129 | handler = builtin
DEBUG | 2024-01-05 15:56:24 | ...zy/haskell-tools.nvim/lua/haskell-tools/repl/builtin.lua:211 | { "repl.builtin setup", {    builtin = {      create_repl_window = <function 1>    },    handler = "builtin",    prefer = <function 2>  } }
DEBUG | 2024-01-05 15:56:24 | ...im/lazy/haskell-tools.nvim/lua/haskell-tools/project.lua:39 | Setting up project tools...
DEBUG | 2024-01-05 15:56:24 | .../nvim/lazy/haskell-tools.nvim/lua/haskell-tools/tags.lua:13 | Setting up fast-tags tools
mrcjkb commented 9 months ago

Ahh. There's an error in the readme snippet: https://github.com/mrcjkb/haskell-tools.nvim/commit/51250d2a6b6085a653eab13b6fe1d7ce7c66f0f9

def_opts should be opts. I wonder how that went unnoticed for so long...

BebeSparkelSparkel commented 9 months ago

I am still having the same result even with that fix. It seems that lua doesn't care about the undefined variable.

If the haskell.lua file is

local ht = vim.print(require('haskell-tools'))

it fails to load the server, but if it just

vim.keymap.set('n', '<space>AAAAAAAAAAAAAAAAAAAAAAAA', vim.lsp.codelens.run, opts) 

With :map i can see the key map

n  <Space>AAAAAAAAAAAAAAAAAAAAAAAA * <Lua 105: /usr/local/share/nvim/runtime/lua/vim/lsp/codelens.lua:80>
x  #           * y?\V<C-R>"<CR>
                 Nvim builtin
o  %             <Plug>(MatchitOperationForward)
x  %             <Plug>(MatchitVisualForward)
n  %             <Plug>(MatchitNormalForward)
n  &           * :&&<CR>
                 Nvim builtin
x  *           * y/\V<C-R>"<CR>
                 Nvim builtin
n  Y           * y$
                 Nvim builtin
o  [%            <Plug>(MatchitOperationMultiBackward)
x  [%            <Plug>(MatchitVisualMultiBackward)
n  [%            <Plug>(MatchitNormalMultiBackward)
o  ]%            <Plug>(MatchitOperationMultiForward)
x  ]%            <Plug>(MatchitVisualMultiForward)
n  ]%            <Plug>(MatchitNormalMultiForward)
x  a%            <Plug>(MatchitVisualTextObject)
n  ghc         * <Lua 74: ~/.local/share/nvim/lazy/haskell-tools.nvim/lua/haskell-tools/repl.lua:180>
x  gx            <Plug>NetrwBrowseXVis
n  gx            <Plug>NetrwBrowseX
o  g%            <Plug>(MatchitOperationBackward)
x  g%            <Plug>(MatchitVisualBackward)
n  g%            <Plug>(MatchitNormalBackward)
x  <Plug>NetrwBrowseXVis * :<C-U>call netrw#BrowseXVis()<CR>
n  <Plug>NetrwBrowseX * :call netrw#BrowseX(netrw#GX(),netrw#CheckIfRemote(netrw#GX()))<CR>
x  <Plug>(MatchitVisualTextObject)   <Plug>(MatchitVisualMultiBackward)o<Plug>(MatchitVisualMultiForward)
o  <Plug>(MatchitOperationMultiForward) * :<C-U>call matchit#MultiMatch("W",  "o")<CR>
o  <Plug>(MatchitOperationMultiBackward) * :<C-U>call matchit#MultiMatch("bW", "o")<CR>
x  <Plug>(MatchitVisualMultiForward) * :<C-U>call matchit#MultiMatch("W",  "n")<CR>m'gv``
x  <Plug>(MatchitVisualMultiBackward) * :<C-U>call matchit#MultiMatch("bW", "n")<CR>m'gv``
n  <Plug>(MatchitNormalMultiForward) * :<C-U>call matchit#MultiMatch("W",  "n")<CR>
n  <Plug>(MatchitNormalMultiBackward) * :<C-U>call matchit#MultiMatch("bW", "n")<CR>
o  <Plug>(MatchitOperationBackward) * :<C-U>call matchit#Match_wrapper('',0,'o')<CR>
o  <Plug>(MatchitOperationForward) * :<C-U>call matchit#Match_wrapper('',1,'o')<CR>
x  <Plug>(MatchitVisualBackward) * :<C-U>call matchit#Match_wrapper('',0,'v')<CR>m'gv``
x  <Plug>(MatchitVisualForward) * :<C-U>call matchit#Match_wrapper('',1,'v')<CR>:if col("''") != col("$") | exe ":normal! m'" | endif<CR>gv``
n  <Plug>(MatchitNormalBackward) * :<C-U>call matchit#Match_wrapper('',0,'n')<CR>
n  <Plug>(MatchitNormalForward) * :<C-U>call matchit#Match_wrapper('',1,'n')<CR>
n  <Plug>PlenaryTestFile * :lua require('plenary.test_harness').test_file(vim.fn.expand("%:p"))<CR>
n  <C-L>       * <Cmd>nohlsearch|diffupdate|normal! <C-L><CR>
                 Nvim builtin
Press ENTER or type command to continue
mrcjkb commented 9 months ago

I've found that Neovim sometimes suppresses error messages when you open a file directly.

Could you please try the following:

It should print an error message if there is one.

mrcjkb commented 9 months ago

Closing and moving to a discussion, as I cannot reproduce this.