Subject: bug#66159: closed (Re: bug#66159: [PATCH] Various improvements to lua-ts-mode (Bug#66159))

From: [email-masked] (GNU bug Tracking System)
Date: Mon, 23 Oct 2023 08:13:02 +0000

Your bug report

#66159: 30.0.50; lua-ts-mode semantic indentation problems

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
66159: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=66159
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#66159: [PATCH] Various improvements to lua-ts-mode (Bug#66159)
From: Stefan Kangas <[email-masked]>
To: john muhl <[email-masked]>
Cc: [email-masked], Andrey Listopadov <[email-masked]>, Mauro Aranda <[email-masked]>
Date: Mon, 23 Oct 2023 01:11:57 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

Version: 30.1

john muhl <[email-masked]> writes:

> It should be ok to install.

Thanks, installed on master.  I'm consequently closing this bug.

[1: 1c261e0a6ca]: 2023-10-23 10:07:52 +0200
  Various improvements to lua-ts-mode (Bug#66159)
  https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=1c261e0a6cae09e3ff36930442f2c9da44bccd6d

Subject: 30.0.50; lua-ts-mode semantic indentation problems
From: Andrey Listopadov <[email-masked]>
To: [email-masked]
Date: Fri, 22 Sep 2023 22:17:55 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

I've been editing Lua using the long-existing lua-mode[1] and it works
well enough for me, but it's indentation implementation is very slow.
Indenting a file with just 600 lines takes several seconds on my
machine.  So when I saw that Emacs now features a lua-ts-mode package in
its core, I tried to move to it, in hopes that it would be faster.

However, a lot of code is now indented differently, not how I used to,
and this creates a lot of noise in commits, as I often re-indent the
whole buffer before saving the file. Here are some examples.

lua-mode:

function foo (e)
    if e == nil
    then return 1000
    else return e
end end

lua-ts-mode:

function foo (e)
    if e == nil
        then return 1000
    else return e
    end end

My thoughts:

`then' is indented as the part of the block of code that is part of the
`true' branch itself. In lua-mode, it is indented the same as `if' itself,
and everything after `then' is indented if moved to a new line:

function foo (e)
    if e == nil
    then
        return 1000
    else
        return e
end end

In lua-ts-mode it is indented together with the body which isn't
idiomatic:

function foo (e)
    if e == nil
        then
        return 1000
    else
        return e
    end end

Another thing that bothers me is that I prefer Gassanenko-style packing
of `end' keywords so that they vertically align with the scope of the
opened block, as it saves so much vertical space and is easier for me to
read, but lua-ts-mode moves it to the latest innermost indentation
level, as opposed to the outermost depending on the count of ends in the
line itself:

function lowest_entropy_cell(world)
|   local lowest,res=math.huge,nil
|   for y=1,world.height do
|   |   for x=1,world.width do
|   |   |   local cell=world:get(x,y)
|   |   |   if cell.is_set then
|   |   |   |   local e=cell_enthropy(cell)
|   |   |   |   trace(e)
|   |   |   |   if e <= lowest then
|   |   |   |   |   lowest,res=e,{x,y}
|   end end end end
|   return res or {math.random(world.width),math.random(world.height)}
end

However, lua-ts-mode indents it like so:

function lowest_entropy_cell(world)
    local lowest,res=math.huge,nil
    for y=1,world.height do
        for x=1,world.width do
            local cell=world:get(x,y)
            if cell.is_set then
                local e=cell_enthropy(cell)
                trace(e)
                if e <= lowest then
                    lowest,res=e,{x,y}
                end end end end
    return res or {math.random(world.width),math.random(world.height)}
end

I noticed the difference in table indentations as well.

lua-mode:

local Recipe = {
    Floor={up={Floor=true,Wall=true},
           down={Floor=true,Wall=true},
           left={Floor=true,Wall=true},
           right={Floor=true,Wall=true}},
    Wall={up={Floor=true,Wall=true},
          down={Floor=true,Wall=true},
          left={Floor=true,Wall=true},
          right={Floor=true,Wall=true}},
    Corridor={up={Corridoor=true},
              down={Corridoor=true},
              left={Corridoor=true},
              right={Corridoor=true}}
}

lua-ts-mode:

local Recipe = {
    Floor={up={Floor=true,Wall=true},
        down={Floor=true,Wall=true},
        left={Floor=true,Wall=true},
        right={Floor=true,Wall=true}},
    Wall={up={Floor=true,Wall=true},
        down={Floor=true,Wall=true},
        left={Floor=true,Wall=true},
        right={Floor=true,Wall=true}},
    Corridor={up={Corridoor=true},
        down={Corridoor=true},
        left={Corridoor=true},
        right={Corridoor=true}}
}

The first one is more logical and obeys scope levels.

Should I expect this to be the default new way of indenting or the
indentation can be made to match the lua-mode where it is sensible?

Thanks!

P.S. I know that stacking `end' isn't really idiomatic Lua style, but it
works in old-lua mode sensible enough that it is actually surprising,
and transforms Lua into code that is easy to parse just by looking on
the indentation level, much like Lisps.

[1] https://github.com/immerrr/lua-mode

In GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
 3.24.38, cairo version 1.17.8) of 2023-09-18 built on toolbox
Repository revision: 861f9cb78370e2b78f852e5ccde9b63c94486ca8
Repository branch: master
System Description: Fedora Linux 38 (Container Image)

Configured using:
 'configure --without-compress-install --with-native-compilation=aot
 --with-pgtk --with-mailutils --with-xwidgets
 --prefix=/var/home/alist/.local'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
JSON LCMS2 LIBOTF LIBSELINUX LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY
PDUMPER PGTK PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER XIM XWIDGETS GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Lua

Minor modes in effect:
  repeat-mode: t
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  electric-pair-mode: t
  hl-todo-mode: t
  savehist-mode: t
  delete-selection-mode: t
  pixel-scroll-precision-mode: t
  global-auto-revert-mode: t
  corfu-popupinfo-mode: t
  global-corfu-mode: t
  corfu-mode: t
  global-region-bindings-mode: t
  recentf-mode: t
  gcmh-mode: t
  server-mode: t
  marginalia-mode: t
  vertico-mode: t
  override-global-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  context-menu-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-regexp-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  abbrev-mode: t
  hs-minor-mode: t

Load-path shadows:
/var/home/alist/.config/emacs/elpa/transient-20230915.1911/transient hides /var/home/alist/.local/share/emacs/30.0.50/lisp/transient
/var/home/alist/.config/emacs/elpa/modus-themes-20230916.905/theme-loaddefs hides /var/home/alist/.local/share/emacs/30.0.50/lisp/theme-loaddefs

Features:
(shadow emacsbug dabbrev lua-ts-mode rect lua-mode modus-operandi-theme
python geiser-mode geiser-xref geiser-compile geiser-guile tramp
trampver tramp-integration tramp-message tramp-compat tramp-loaddefs
info-look geiser geiser-debug geiser-repl geiser-image geiser-capf
geiser-doc geiser-menu geiser-autodoc geiser-edit etags fileloop
geiser-completion geiser-eval geiser-connection tq geiser-syntax
geiser-log geiser-popup geiser-impl help-fns radix-tree geiser-custom
geiser-base scheme find-dired grep display-line-numbers css-mode treesit
smie mu4e-alert advice time ht alert log4e notifications gntp mu4e
mu4e-org mu4e-main mu4e-view mu4e-headers mu4e-compose mu4e-draft
mu4e-actions smtpmail mu4e-search mu4e-lists mu4e-bookmarks mu4e-mark
mu4e-message flow-fill hl-line mu4e-contacts mu4e-update mu4e-folders
mu4e-server mu4e-context mu4e-vars mu4e-helpers mu4e-config ido tabify
cus-start repeat files-x org-archive puni pulse color consult ox-odt
rng-loc rng-uri rng-parse rng-match rng-dt rng-util rng-pttrn nxml-parse
nxml-ns nxml-enc xmltok nxml-util ox-icalendar org-agenda ox-ascii
ox-latex ox-hugo ox-hugo-deprecated ffap ox-blackfriday ox-md ox-html
table ox-publish tomelr ox sgml-mode facemenu xwidget magit-bookmark
bookmark goto-addr vc-hg vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs
log-view vc bug-reference vc-git vc-dispatcher misearch multi-isearch
dired-aux face-remap magit-extras orderless flyspell ispell org-element
org-persist org-id org-refile avl-tree generator oc-basic ol-eww eww xdg
url-queue mm-url ol-rmail ol-mhe ol-irc ol-info ol-gnus nnselect
gnus-art mm-uu mml2015 mm-view mml-smime smime gnutls dig gnus-sum shr
pixel-fill kinsoku url-file svg dom gnus-group gnus-undo gnus-start
gnus-dbus gnus-cloud nnimap nnmail mail-source utf7 nnoo parse-time
gnus-spec gnus-int gnus-range gnus-win gnus nnheader range ol-docview
doc-view jka-compr image-mode exif ol-bibtex bibtex iso8601 ol-bbdb
ol-w3m ol-doi org-link-doi org-tempo tempo ob-fennel fennel-proto-repl
fennel-mode inf-lisp xref magit-submodule magit-blame magit-stash
magit-reflog magit-bisect magit-push magit-pull magit-fetch magit-clone
magit-remote magit-commit magit-sequence magit-notes magit-worktree
magit-tag magit-merge magit-branch magit-reset magit-files magit-refs
magit-status magit magit-repos magit-apply magit-wip magit-log
which-func imenu magit-diff smerge-mode diff diff-mode git-commit
log-edit message sendmail yank-media puny dired dired-loaddefs rfc822
mml mml-sec epa epg rfc6068 epg-config gnus-util mm-decode mm-bodies
mm-encode mail-parse rfc2231 rfc2047 rfc2045 mm-util ietf-drums
mail-prsvr mailabbrev mail-utils gmm-utils mailheader pcvs-util add-log
magit-core magit-autorevert magit-margin magit-transient magit-process
with-editor magit-mode transient magit-git magit-base magit-section
cursor-sensor crm project ob-lua ob-shell shell org ob ob-tangle ob-ref
ob-lob ob-table ob-exp org-macro org-src ob-comint org-pcomplete
pcomplete org-list org-footnote org-faces org-entities ob-emacs-lisp
ob-core ob-eval org-cycle org-table org-keys oc org-loaddefs find-func
cal-menu calendar cal-loaddefs vertico-directory mule-util time-date
noutline outline elec-pair isayt disp-table hideshow hl-todo savehist
delsel pixel-scroll cua-base autorevert filenotify corfu-popupinfo cape
corfu region-bindings recentf tree-widget gcmh init proxy gsettings s
gvariant parsec dash zig-compilation-mode fennel-compilation-mode
clojure-compilation-mode derived compile text-property-search server
ediff ediff-merg ediff-mult ediff-wind ediff-diff ediff-help ediff-init
ediff-util sql-indent sql view thingatpt comint ansi-osc ring zig-mode
reformatter ansi-color ol org-fold org-fold-core org-compat org-version
org-macs format-spec blog marginalia vertico compat use-package-delight
formfeed modus-vivendi-theme modus-themes dbus xml common-lisp-modes
novice cus-edit pp cus-load wid-edit font mode-line edmacro kmacro
messages use-package-bind-key bind-key defaults functions local-config
delight comp comp-cstr warnings icons rx use-package-ensure cl-extra
help-mode use-package-core early-init cape-autoloads
clj-decompiler-autoloads clj-refactor-autoloads cider-autoloads
clojure-mode-autoloads common-lisp-modes-autoloads consult-autoloads
corfu-terminal-autoloads corfu-autoloads csv-mode-autoloads
delight-autoloads dumb-jump-autoloads eat-autoloads elfeed-autoloads
expand-region-autoloads fennel-mode-autoloads gcmh-autoloads
geiser-guile-autoloads geiser-autoloads gsettings-autoloads
gvariant-autoloads hl-todo-autoloads inflections-autoloads
isayt-autoloads jdecomp-autoloads lisp-extra-font-lock-autoloads
lsp-java-autoloads lsp-metals-autoloads dap-mode-autoloads
lsp-docker-autoloads bui-autoloads lsp-treemacs-autoloads
lsp-mode-autoloads f-autoloads lua-mode-autoloads marginalia-autoloads
markdown-mode-autoloads message-view-patch-autoloads magit-autoloads
pcase magit-section-autoloads git-commit-autoloads
modus-themes-autoloads mu4e-alert-autoloads alert-autoloads
log4e-autoloads gntp-autoloads multiple-cursors-autoloads
orderless-autoloads org-modern-autoloads org-tree-slide-autoloads
ox-hugo-autoloads package-lint-flymake-autoloads package-lint-autoloads
paredit-autoloads parsec-autoloads parseedn-autoloads parseclj-autoloads
phi-search-autoloads poly-org-autoloads polymode-autoloads
popon-autoloads popup-autoloads puni-autoloads easy-mmode finder-inf
queue-autoloads racket-mode-autoloads region-bindings-autoloads
request-autoloads scala-mode-autoloads separedit-autoloads
edit-indirect-autoloads sesman-autoloads sly-autoloads spinner-autoloads
sql-indent-autoloads tomelr-autoloads transient-autoloads
treemacs-autoloads cfrs-autoloads posframe-autoloads ht-autoloads
hydra-autoloads lv-autoloads pfuture-autoloads ace-window-autoloads
avy-autoloads s-autoloads dash-autoloads vertico-autoloads
vundo-autoloads with-editor-autoloads info compat-autoloads
yaml-autoloads yaml-mode-autoloads yasnippet-autoloads
zig-mode-autoloads reformatter-autoloads package browse-url url
url-proxy url-privacy url-expand url-methods url-history url-cookie
generate-lisp-file url-domsuf url-util mailcap url-handlers url-parse
auth-source cl-seq eieio eieio-core cl-macs password-cache json subr-x
map byte-opt gv bytecomp byte-compile url-vars cl-loaddefs cl-lib rmc
iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook
vc-hooks lisp-float-type elisp-mode mwheel term/pgtk-win pgtk-win
term/common-win pgtk-dnd touch-screen tool-bar dnd fontset image
regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode
prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu
timer select scroll-bar mouse jit-lock font-lock syntax font-core
term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
theme-loaddefs faces cus-face macroexp files window text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads xwidget-internal dbusbind
inotify dynamic-setting system-font-setting font-render-setting cairo
gtk pgtk lcms2 multi-tty move-toolbar make-network-process
native-compile emacs)

Memory information:
((conses 16 1147781 1425356) (symbols 48 52742 50)
 (strings 32 272573 78657) (string-bytes 1 9908365)
 (vectors 16 119200) (vector-slots 8 2827929 951125)
 (floats 8 888 21739) (intervals 56 40788 17575) (buffers 992 46))

-- 
Andrey Listopadov