Giter Club home page Giter Club logo

haskell-tools.nvim's Introduction

haskell-tools.nvim

Supercharge your Haskell experience in neovim!

Neovim Lua Haskell

Quick Links

Prerequisites

Required

Optional

Installation

Example using packer.nvim:

use {
  'MrcJkb/haskell-tools.nvim',
  requires = {
    'neovim/nvim-lspconfig',
    'nvim-lua/plenary.nvim',
    'nvim-telescope/telescope.nvim', -- optional
  },
  -- tag = 'x.y.z' -- [^1]
}

[^1] It is suggested to use the latest release tag and to update it manually, if you would like to avoid breaking changes.

Quick Setup

This plugin automatically configures the haskell-language-server neovim client.

โš ๏ธ Do not call the lspconfig.hls setup or set up the lsp manually, as doing so may cause conflicts.

To get started quickly with the default setup, add the following to your neovim config:

local ht = require('haskell-tools')
local def_opts = { noremap = true, silent = true, }
ht.setup {
  hls = {
    -- See nvim-lspconfig's  suggested configuration for keymaps, etc.
    on_attach = function(client, bufnr)
      local opts = vim.tbl_extend('keep', def_opts, { 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)
      vim.keymap.set('n', '<space>hs', ht.hoogle.hoogle_signature, opts)
      -- default_on_attach(client, bufnr)  -- if defined, see nvim-lspconfig
    end,
  },
}
-- Suggested keymaps that do not depend on haskell-language-server
-- Toggle a GHCi repl for the current package
vim.keymap.set('n', '<leader>rr', ht.repl.toggle, def_opts)
-- Toggle a GHCi repl for the current buffer
vim.keymap.set('n', '<leader>rf', funciton()
  ht.repl.toggle(vim.api.nvim_buf_get_name(0))
end, def_opts)
vim.keymap.set('n', '<leader>rq', ht.repl.quit, def_opts)

If using a local hoogle installation, follow these instructions to generate a database.

Features

  • Basic haskell-language-server functionality on par with nvim-lspconfig.hls

Beyond nvim-lspconfig.hls

  • Clean shutdown of language server on exit to prevent corrupted files (see ghc #14533).
  • Automatically adds capabilities for the following plugins, if loaded:
  • Automatically refreshes code lenses by default, which haskell-language-server heavily relies on. Can be disabled.
  • The following code lenses are currently supported:

asciicast

asciicast

asciicast

asciicast

Beyond haskell-language-server

The below features are not implemented by haskell-language-server.

Hoogle-search for signature

  • Search for the type signature under the cursor.
  • Falls back to the word under the cursor if the type signature cannot be determined.
  • Telescope keymaps:
    • <CR> to copy the selected entry ( :: ) to the clipboard.
    • <C-b> to open the selected entry's Hackage URL in a browser.
    • <C-r> to replace the word under the cursor with the selected entry.
require('haskell-tools').hoogle.hoogle_signature()

asciicast

Use Hoogle search to fill holes

With the <C-r> keymap, the Hoogle search telescope integration can be used to fill holes.

asciicast

GHCi repl

Start a GHCi repl for the current project / buffer.

  • Automagically detects the appropriate command (cabal new-repl, stack ghci or ghci) for your project.
  • Choose between a builtin handler or toggleterm.nvim.
  • Dynamically create a repl command for iron.nvim (see advanced configuration).
  • Interact with the repl from any buffer using a lua API.

asciicast

Open project/package files for the current buffer

asciicast

Planned

For planned features, refer to the issues.

Advanced configuration

To modify the default configs, call

-- defaults
require('haskell-tools').setup {
  tools = { -- haskell-tools options
    codeLens = {
      -- Whether to automatically display/refresh codeLenses
      autoRefresh = true,
    },
    hoogle = {
      -- 'auto': Choose a mode automatically, based on what is available.
      -- 'telescope-local': Force use of a local installation.
      -- 'telescope-web': The online version (depends on curl).
      -- 'browser': Open hoogle search in the default browser.
      mode = 'auto',
    },
    repl = {
      -- 'builtin': Use the simple builtin repl
      -- 'toggleterm': Use akinsho/toggleterm.nvim
      handler = 'builtin',
      builtin = {
        create_repl_window = function(view)
          -- create_repl_split | create_repl_vsplit | create_repl_tabnew | create_repl_cur_win
          return view.create_repl_split { size = vim.o.lines / 3 }
        end
      },
    },
  },
  hls = { -- LSP client options
    -- ...
    haskell = { -- haskell-language-server options
      formattingProvider = 'ormolu',
      checkProject = true, -- Setting this to true could have a performance impact on large mono repos.
      -- ...
    }
  }
}
  • The full list of defaults can be found here.
  • To view all available language server settings (including those not set by this plugin), run haskell-language-server generate-default-config.
  • For detailed descriptions of the configs, look at the haskell-language-server documentation.

How to disable individual code lenses

Some code lenses might be more interesting than others. For example, the importLens could be annoying if you prefer to import everything or use a custom prelude. Individual code lenses can be turned off by disabling them in the respective plugin configurations:

hls = {
  haskell = {
    plugin = {
      class = { -- missing class methods
        codeLensOn = false,
      },
      importLens = { -- make import lists fully explicit
        codeLensOn = false,
      },
      refineImports = { -- refine imports
        codeLensOn = false,
      },
      tactics = { -- wingman
        codeLensOn = false,
      },
      moduleName = { -- fix module names
        globalOn = false,
      },
      eval = { -- evaluate code snippets
        globalOn = false,
      },
      ['ghcide-type-lenses'] = { -- show/add missing type signatures
        globalOn = false,
      },
    },
  },
},

Set up iron.nvim to use haskell-tools.nvim

Depends on iron.nvim/#300.

local iron = require("iron.core")
iron.setup {
  config = {
    repl_definition = {
      haskell = {
        command = function(meta)
          local file = vim.api.nvim_buf_get_name(meta.current_bufnr)
          -- call `require` in case iron is set up before haskell-tools
          return require('haskell-tools').repl.mk_repl_cmd(file)
        end,
      },
    },
  },
}

Available functions

local ht = require('haskell-tools')

-- Run a hoogle signature for the value under the cursor
ht.hoogle.hoogle_signature()

-- Toggle a GHCi repl
ht.repl.toggle()
-- Toggle a GHCi repl for `file`
ht.repl.toggle(file)
-- Quit the repl
ht.repl.quit()
-- Paste a command to the repl from register `reg`. (`reg` defaults to '"')
ht.repl.paste(reg)
-- Query the repl for the type of register `reg`. (`reg` defaults to '"')
ht.repl.paste_type(reg)
-- Query the repl for the type of word under the cursor
ht.repl.cword_type()

Available commands

" Open the project file for the current buffer (cabal.project or stack.yaml)
:HsProjectFile

" Open the package.yaml file for the current buffer
:HsPackageYaml

" Open the *.cabal file for the current buffer
:HsPackageCabal

Troubleshooting

LSP features not working

Check which version of GHC you are using (:LspInfo). Sometimes, certain features take some time to be implemented for the latest GHC versions. You can see how well a specific GHC version is supported here.

Recommendations

Here are some other plugins I recommend for Haskell (and nix) development in neovim:

haskell-tools.nvim's People

Contributors

mrcjkb avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.