nvim-ts-context-commentstring icon indicating copy to clipboard operation
nvim-ts-context-commentstring copied to clipboard

fix: ignore Haskell char node function match

Open yogan opened this issue 11 months ago • 4 comments

This is obviously just a hack, but without it, the autocommand is going haywire when moving around in Haskell files, making it impossible to work.

I could not find out where the function is for char nodes is coming from. Any hints / help for a proper fix are welcome.

yogan avatar Mar 02 '24 12:03 yogan

Hey! What exactly is going on in Haskell files? I couldn't really reproduce any weird behaviour with this file:

Example
putTodo :: (Int, String) -> IO ()
putTodo (n, todo) = putStrLn (show n ++ ": " ++ todo)

prompt :: [String] -> IO ()
prompt todos = do
    putStrLn ""
    putStrLn "Current TODO list:"
    mapM_ putTodo (zip [0..] todos)
    command <- getLine
    interpret command todos

interpret :: String -> [String] -> IO ()
interpret ('+':' ':todo) todos = prompt (todo:todos)
interpret ('-':' ':num ) todos =
    case delete (read num) todos of
        Nothing -> do
            putStrLn "No TODO entry matches the given number\
\hello"
            prompt todos
        Just todos' -> prompt todos'
interpret  "q"           todos = return ()
interpret  command       todos = do
    putStrLn ("Invalid command: `" ++ command ++ "`")
    prompt todos

delete :: Int -> [a] -> Maybe [a]
delete 0 (_:as) = Just as
delete n (a:as) = do
    as' <- delete (n - 1) as
    return (a:as')
delete _  []    = Nothing

main = do
    putStrLn "Commands:"
    putStrLn "+ <String> - Add a TODO entry"
    putStrLn "- <Int>    - Delete the numbered entry"
    putStrLn "q          - Quit"
    prompt []

I was moving the cursor around and didn't notice anything weird.

Maybe it's an issue with your config? Could you try a minimal config to reproduce the issue?

JoosepAlviste avatar Mar 27 '24 19:03 JoosepAlviste

It does not seem to happen for all files, but I found one that cause me trouble:

module DNA (nucleotideCounts, Nucleotide (..)) where

import Data.List (group, sort)
import Data.Map (Map)
import qualified Data.Map as Map

data Nucleotide = A | C | G | T deriving (Eq, Ord, Show)

nucleotideCounts :: String -> Either String (Map Nucleotide Int)
nucleotideCounts dna = case counts of
  Just xs -> Right $ Map.fromList xs
  Nothing -> Left $ "invalid DNA strand" ++ dna
  where
    counts = mapM count $ group $ sort dna

    count :: String -> Maybe (Nucleotide, Int)
    count xs = case xs of
      [] -> Nothing
      x : _ -> case x of
        'A' -> Just (A, length xs)
        'C' -> Just (C, length xs)
        'G' -> Just (G, length xs)
        'T' -> Just (T, length xs)
        _ -> Nothing

image

   Error  08:06:29 AM msg_show.lua_error Error detected while processing CursorHold Autocommands for "<buffer=1>":
08:06:29 AM msg_show Error executing lua callback: ...-commentstring/lua/ts_context_commentstring/internal.lua:126: attempt to index local 'match' (a function value)
stack traceback:
	...-commentstring/lua/ts_context_commentstring/internal.lua:126: in function 'calculate_commentstring'
	...-commentstring/lua/ts_context_commentstring/internal.lua:86: in function 'update_commentstring'
	...-commentstring/lua/ts_context_commentstring/internal.lua:33: in function <...-commentstring/lua/ts_context_commentstring/internal.lua:32>

I'll try to recreate with a minimal config…

yogan avatar Mar 28 '24 07:03 yogan

I tried to use the minimal config from here: https://github.com/JoosepAlviste/nvim-ts-context-commentstring/blob/main/utils/minimal_init.lua

~But this does not seem to load ts-context-commentstring, only treesitter.~ Update: works just fine.

Indeed there are no issues with this minimal config, even with the problematic source file I posted in the comment above. I'll try to dig deeper where the issues are coming from…

yogan avatar Mar 28 '24 09:03 yogan

I've just encountered this in a Markdown document too:

Debug print:

commentstring_key "__default" language_config "<!-- %s -->" node_type "comment" match nil
commentstring_key "__default" language_config "<!-- %s -->" node_type "document" match nil

Edit: And now in a Lua file.

mrcjkb avatar Jun 20 '24 23:06 mrcjkb

Hi @JoosepAlviste could you please re-review this pull request? I've run into the same issue and come up with the same fix (sans comment :p ).

I was able to reproduce with the minimal config that yogan linked after running TSInstall haskell

Here is a minimal haskell file that triggers the issue:

main :: IO ()
main = hspec $ describe "Addition" $ do
  it "1 + 1 is 2" $ do      -- ISSUE IS PRESENT ON THIS LINE
    (1 + 1) `shouldBe` 2

I believe this is the same issue as #103, and 1dr0z's comment explains why it happens. Basically, the name of the TSnode collides with the name of a string method.

Here's a contrived lua file that reproduces what is going on:

local languages = {
    haskell = '-- %s',
}

local language_config = languages['haskell']
local node_type = 'char'
-- Match is expected to be a table property but is instead a string method
local match = language_config[node_type]
print("match is a string method? " .. vim.inspect(match == ("foo").char))

Thank you

michaelPotter avatar Oct 05 '24 19:10 michaelPotter

Hey! Thanks everyone for debugging this, accessing the string methods was exactly what was happening. It's especially noticeable if you use the autocmd because then we're constantly re-calculating the commentstring.

I've pushed a commit fixing this: https://github.com/JoosepAlviste/nvim-ts-context-commentstring/commit/9c74db656c3d0b1c4392fc89a016b1910539e7c0 and will close the PR.

Let me know if this wasn't fixed or comes up again!

JoosepAlviste avatar Oct 06 '24 08:10 JoosepAlviste

Seems to be fixed, thank you, @JoosepAlviste!

yogan avatar Oct 08 '24 11:10 yogan