-
-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Introduction
Hi! First of all I really appreciate Haskell Snippets, it would be amazing if I could (hopefully) bring some value.
I think that would be great to have snippets for generating Haddock documentation. I've put together an implementation that I'd love to contribute if you're interested. The snippets include smart auto-detection of function signatures and module names to make documentation writing faster and more convenient.
I'm completely open to feedback, suggestions, or alternative approaches. Please let me know if there's anything you'd like me to change or if you have any questions about the implementation. I'm happy to iterate on this based on your guidance.
Summary
Add two new snippets for generating Haddock documentation blocks with smart auto-detection capabilities, including support for multiline signatures, forall quantifiers, and type class constraints.
New Snippets
fdoc - Function Documentation
Generates a Haddock documentation block for functions with automatic type signature detection.
Smart behavior: When the line below the cursor contains a type signature (single or multiline), the snippet automatically:
- Detects the function name
- Parses parameter types from the signature (stripping forall and constraints)
- Generates example placeholders with the detected types
Supported signature patterns:
-- Simple signatures
f :: Int -> Int
-- Multiline signatures
longFunc :: Int
-> String
-> Bool
-- Name on separate line
fmap
:: (a -> b)
-> f a
-> f b
-- With forall quantifiers
polymorphic :: forall a b. a -> b -> (a, b)
-- With type class constraints
showIt :: Show a => a -> String
-- Combined forall and constraints
complicated :: forall a. Show a => a -> String
-- Tuple constraints
multiConstraint :: (Show a, Eq b) => a -> b -> BoolExample with detection:
-- Cursor here, line below is: add :: Int -> Int -> IntExpands to:
-- | `add` description.
--
-- Examples:
--
-- >>> add Int Int
-- Int
add :: Int -> Int -> IntEach type (Int) becomes an editable tab stop so users can replace them with actual example values.
Fallback (no signature detected):
-- | Brief description.
--
-- Examples:
--
-- >>> example
-- expectedmdoc - Module Documentation
Generates a Haddock module documentation header with automatic module name detection.
Smart behavior: Uses LSP CodeLens (from haskell-language-server) or filename-based detection to auto-fill the module name.
Example:
-- |
-- Module : MyApp.Utils
-- Description : Short description here
--
-- Longer description of the module.When module name is detected, it appears as non-editable text. When not detected, it defaults to MyModule as an editable placeholder.
Implementation Details
New Utility Functions
Added to lua/haskell-snippets/util.lua:
-
strip_forall(signature)- Strips forall quantifiers from signatures, including nested foralls likeforall a. forall b. ... -
strip_constraints(signature)- Strips type class constraints, handling both single (Show a =>) and tuple ((Show a, Eq b) =>) constraints with proper bracket depth tracking -
normalize_signature(signature)- Applies both forall and constraint stripping -
parse_type_signature(signature)- Parses Haskell type signatures into parameter types and return type. Now automatically normalizes signatures first. Handles complex types including:- Parenthesized function types:
(Int -> Int) -> Int - List types with arrows:
[Int -> Int] -> Bool - Record types:
{f :: Int -> Int} -> Bool - Nested parentheses:
((a -> b) -> c) -> d
- Parenthesized function types:
-
parse_function_line(line)- Parses a function type declaration line and returns structured data with name, params, and return type. -
is_signature_continuation(line)- Detects if a line is a continuation of a multiline type signature (indented, no::, not a function definition/guard/where) -
collect_multiline_signature(start_row)- Collects a potentially multiline type signature starting from a given row, joining continuation lines. Supports bothname :: sigandname\n :: sigformats. -
get_function_context()- Gets function information from the line below the cursor position, now with full multiline signature support
Test Coverage
Added 52 unit tests in tests/util_spec.lua:
- 5 tests for
strip_forall - 4 tests for
strip_constraints - 7 tests for
is_signature_continuation - 17 tests for
parse_type_signature(including forall/constraint handling) - 7 tests for
parse_function_line - 14 tests for
get_function_context(including multiline signatures and name-on-separate-line format)
All tests pass on both neovim stable and nightly.
Environment
- Neovim: v0.11.2
- LuaSnip: v2.4.1
- OS: Linux 6.12.47-1.qubes.fc37.x86_64

