GNU bug report logs - #66159
30.0.50; lua-ts-mode semantic indentation problems

Previous Next

Package: emacs;

Reported by: Andrey Listopadov <andreyorst <at> gmail.com>

Date: Fri, 22 Sep 2023 19:41:02 UTC

Severity: normal

Tags: patch

Found in version 30.0.50

Fixed in version 30.1

Done: Stefan Kangas <stefankangas <at> gmail.com>

Bug is archived. No further changes may be made.

Full log


Message #37 received at 66159 <at> debbugs.gnu.org (full text, mbox):

From: john muhl <jm <at> pub.pink>
To: Andrey Listopadov <andreyorst <at> gmail.com>
Cc: 66159 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: bug#66159: 30.0.50; lua-ts-mode semantic indentation problems
Date: Sat, 30 Sep 2023 08:57:06 -0500
[Message part 1 (text/plain, inline)]
Andrey Listopadov <andreyorst <at> gmail.com> writes:

> john muhl <jm <at> pub.pink> writes:
>
>> I agree there’s no immediate need.
>>
>> Could you explain what the lua-indent-* options do in lua-mode? I tried
>> toggling them but didn’t see any difference between on/off.
>
> I don't really know it myself, sorry. There seem to be some specifics
> regarding how the content inside parenthesis is indented, but I'm not
> using these either.

I found <https://github.com/immerrr/lua-mode/pull/151> with the
explanation of those options.

>>> There are also some weirdness in semantic navigation, but it's more
>>> likely that I'm just not used to new ts-backed navigation yet.
>>
>> I’m sure there is room for improvement here too. Suggestions welcome.
>
> Here are a few examples. the █ represents the point:

Fixed in the attached.

>>> If you're willing to dig into some (pretty crazy) involved examples, I
>>> can send here some really convoluted nested anonymous functions that
>>> currently are indented in a weird way in both modes. Neither does it
>>> exactly right in my opiion, but I also don't know if there is the right
>>> way to indent this.  I can send these examples later this week once I
>>> finish an article I'm working on rightnow.
>>
>> Sure. Whenever you have the time.
>
> I know, that this code is convoluted, and probably no one writes like
> this, it was done on purpose for an article about the power of anonymous
> functions, so perhaps it isn't really a problem for most Lua
> programmers. But it makes reading code a bit harder in rare cases like
> this. I have more examples in the article, feel free to grab them if you
> need code snippets for testing:
>
> https://andreyor.st/posts/2023-09-26-iterator-based-transducers-in-lua/

Thanks. The patch gets pretty close on the partitioning function from
your article (the mapping, filtering and taking functions indent
correctly now). The trouble is that you end up with a tree like:

  (return_statement
   (expression_list
    (function_call
     (parenthesized_expression
      (function_definition
       (end))))))

with two different indent styles.

  return (function (f, ...)                  -- L7
  end)(function (step)                       -- L14

  return (function (...)                     -- L21
          end)(collect(arr1, count1+1, ...)) -- L24

Is there some pattern for deciding that I’m missing?

> Other than that, and the navigation issues I've mentioned above, the
> mode works solidly. I've also noticed that some of the `lua-mode'
> default shortcuts are missing, like `C-c C-f'
> (lua-search-documentation)

The opening a browser to look at the docs approach isn’t very Emacs-y so
didn’t make the cut. Ideally it should integrate with info and/or eldoc
but I haven’t gotten to it yet. This should get you by in the meantime:

[lua-ts-dap.el (text/plain, inline)]
(defun jm~lua-ts-documentation-at-point ()
  "Show documentation of function at point in the Lua manual."
  (interactive)
  (save-excursion
    ;; When point is mid-word `treesit-thing-at-point' may return
    ;; the parent node of the thing at point. Go to the beginning
    ;; of the line or word to make sure we have the right thing.
    (unless (or (bolp)
                (not (string-match-p "[[:alnum:]]"
                                     (char-to-string (char-before)))))
      (backward-word))
    (when-let* ((node (treesit-thing-at-point 'sentence nil))
                ((equal "function_call" (treesit-node-type node)))
                (child (treesit-node-child-by-field-name node "name"))
                (name (treesit-node-text child t))
                (id (if (string-match-p ":" name)
                        (replace-regexp-in-string "^.*:" "file:" name)
                      name))
                ((string-match-p (rx-to-string `(: (? "file:")
                                                   (or ,@lua-ts--builtins)))
                                 id)))
      (browse-url (concat "file:///usr/share/doc/lua/manual.html"
                          "#pdf-" id)))))
[Message part 3 (text/plain, inline)]
> and `C-c C-l' (lua-send-buffer), but these may be out of the scope of
> this module, so let me know if I should just define these myself.

The attached patch includes lua-ts-send-{buffer,file,region}
commands with bindings for:

  C-c C-n start inferior Lua
  C-c C-c send buffer
  C-c C-l send file
  C-c C-r send region

I’ve been using a send-thing but wasn’t sure it’s worth including. What
do you think?

[lua-ts-st.el (text/plain, inline)]
(defun jm~lua-ts-send-thing (point)
  "Send thing near POINT to the inferior Lua process."
  (interactive "d")
  (when-let* ((node (treesit-node-at point))
              (parent (treesit-parent-until
                       node
                       (lambda (p)
                         (string-match-p (rx (or "do_statement"
                                                 "for_statement"
                                                 "function_call"
                                                 "function_declaration"
                                                 "if_statement"
                                                 "repeat_statement"
                                                 "while_statement"))
                                         (treesit-node-type p)))
                       t)))
    (lua-ts-send-region (treesit-node-start parent)
                        (treesit-node-end parent))))
[Message part 5 (text/plain, inline)]
It looks at the tree around point and tries to find something to eval;
e.g.

  function fun[1](n)
      if n > 1
      th[2]en print(1)
      else p[3]rint(0)
      end
  end

Point at [1] sends the function, [2] the if statement, [3] the print
statement.

[0001-Various-improvements-in-lus-ts-mode-Bug-66159.patch (text/x-patch, attachment)]

This bug report was last modified 1 year and 267 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.