>From 8f128eb7e68e0bafe0a123623e40cd59a062b93f Mon Sep 17 00:00:00 2001 From: john muhl Date: Wed, 4 Oct 2023 20:46:15 -0500 Subject: [PATCH] Various improvements to lua-ts-mode (Bug#66159) * lisp/progmodes/lua-ts-mode.el (lua-ts-mode): Navigate function declarations and parenthesized expressions with *-sexp commands. (lua-ts--simple-indent-rules): Improve indentation rules. (lua-ts-mode-map): Add key bindings and menus. (lua-ts-mode-hook): Make hook available in Customize. (lua-ts-inferior-history): (lua-ts-inferior--write-history): Add option to read/write an input history file. (lua-ts-inferior-lua): (lua-ts-send-buffer): (lua-ts-send-file): (lua-ts-send-region): (lua-ts-inferior-prompt): (lua-ts-inferior-prompt-continue): Support for sending buffer, file or region to the inferior process. (lua-ts-show-process-buffer): (lua-ts-hide-process-buffer): (lua-ts-kill-process): New functions. (lua-ts-inferior-prompt-regexp): Remove option. * test/lisp/progmodes/lua-ts-mode-resources/indent.erts: * test/lisp/progmodes/lua-ts-mode-resources/movement.erts: Add tests. --- lisp/progmodes/lua-ts-mode.el | 296 +++++++- .../lua-ts-mode-resources/indent.erts | 675 +++++++++++++++--- .../lua-ts-mode-resources/movement.erts | 56 ++ 3 files changed, 903 insertions(+), 124 deletions(-) diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el index 030a3585158..8b4a60e74bf 100644 --- a/lisp/progmodes/lua-ts-mode.el +++ b/lisp/progmodes/lua-ts-mode.el @@ -38,7 +38,11 @@ (require 'cl-lib) (require 'rx)) +(declare-function treesit-induce-sparse-tree "treesit.c") (declare-function treesit-node-child-by-field-name "treesit.c") +(declare-function treesit-node-first-child-for-pos "treesit.c") +(declare-function treesit-node-parent "treesit.c") +(declare-function treesit-node-start "treesit.c") (declare-function treesit-node-type "treesit.c") (declare-function treesit-parser-create "treesit.c") (declare-function treesit-search-subtree "treesit.c") @@ -48,6 +52,15 @@ lua-ts :prefix "lua-ts-" :group 'languages) +(defcustom lua-ts-mode-hook nil + "Hook run after entering `lua-ts-mode'." + :type 'hook + :options '(flymake-mode + hs-minor-mode + outline-minor-mode) + :group 'lua-ts + :version "30.1") + (defcustom lua-ts-indent-offset 4 "Number of spaces for each indentation step in `lua-ts-mode'." :type 'natnum @@ -86,9 +99,24 @@ lua-ts-inferior-startfile :group 'lua-ts :version "30.1") -(defcustom lua-ts-inferior-prompt-regexp "^>>?[[:blank:]]" - "Regular expression matching the prompt of the inferior Lua process." - :type 'regexp +(defcustom lua-ts-inferior-prompt ">" + "Prompt used by the inferior Lua process." + :type 'string + :safe 'stringp + :group 'lua-ts + :version "30.1") + +(defcustom lua-ts-inferior-prompt-continue ">>" + "Continuation prompt used by the inferior Lua process." + :type 'string + :safe 'stringp + :group 'lua-ts + :version "30.1") + +(defcustom lua-ts-inferior-history nil + "File used to save command history of the inferior Lua process." + :type '(choice (const nil) file) + :safe 'string-or-null-p :group 'lua-ts :version "30.1") @@ -235,27 +263,125 @@ lua-ts--font-lock-settings (defvar lua-ts--simple-indent-rules `((lua + ((or (node-is "comment") + (parent-is "comment_content") + (parent-is "string_content") + (node-is "]]")) + no-indent 0) + ((or (node-is "do") + (node-is "then") + (node-is "elseif_statement") + (node-is "else_statement") + (node-is "until") + (node-is ")") + (node-is "}")) + standalone-parent 0) + ((or (and (parent-is "arguments") lua-ts--first-child-matcher) + (and (parent-is "parameters") lua-ts--first-child-matcher) + (and (parent-is "table_constructor") lua-ts--first-child-matcher)) + standalone-parent lua-ts-indent-offset) + ((or (parent-is "arguments") + (parent-is "parameters") + (parent-is "table_constructor")) + (nth-sibling 1) 0) + ((and (n-p-gp "block" "function_definition" "parenthesized_expression") + lua-ts--nested-function-block-matcher + lua-ts--nested-function-block-include-matcher) + parent lua-ts-indent-offset) + ((and (n-p-gp "block" "function_definition" "arguments") + lua-ts--nested-function-argument-matcher) + parent lua-ts-indent-offset) + ((match "function_definition" "parenthesized_expression") + standalone-parent lua-ts-indent-offset) + ((node-is "block") standalone-parent lua-ts-indent-offset) + ((parent-is "block") parent 0) + ((and (node-is "end") lua-ts--end-line-matcher) + standalone-parent lua-ts--end-indent-offset) + ((match "end" "function_declaration") parent 0) + ((and (n-p-gp "end" "function_definition" "parenthesized_expression") + lua-ts--nested-function-end-argument-matcher) + parent 0) + ((and (n-p-gp "end" "function_definition" "parenthesized_expression") + lua-ts--nested-function-block-matcher + lua-ts--nested-function-end-matcher + lua-ts--nested-function-last-function-matcher) + parent 0) + ((n-p-gp "end" "function_definition" "arguments") parent 0) + ((or (match "end" "function_definition") + (node-is "end")) + standalone-parent 0) ((parent-is "chunk") column-0 0) - ((node-is "comment_end") column-0 0) - ((parent-is "block") parent-bol 0) - ((node-is "}") parent-bol 0) - ((node-is ")") parent-bol 0) - ((node-is "else_statement") parent-bol 0) - ((node-is "elseif_statement") parent-bol 0) - ((node-is "end") parent-bol 0) - ((node-is "until") parent-bol 0) - ((parent-is "for_statement") parent-bol lua-ts-indent-offset) - ((parent-is "function_declaration") parent-bol lua-ts-indent-offset) - ((parent-is "function_definition") parent-bol lua-ts-indent-offset) - ((parent-is "if_statement") parent-bol lua-ts-indent-offset) - ((parent-is "else_statement") parent-bol lua-ts-indent-offset) - ((parent-is "repeat_statement") parent-bol lua-ts-indent-offset) - ((parent-is "while_statement") parent-bol lua-ts-indent-offset) - ((parent-is "table_constructor") parent-bol lua-ts-indent-offset) - ((parent-is "arguments") parent-bol lua-ts-indent-offset) - ((parent-is "parameters") parent-bol lua-ts-indent-offset) ((parent-is "ERROR") no-indent 0)))) +(defun lua-ts--end-line-matcher (&rest _) + "Matches if there is more than one `end' on the current line." + (> (lua-ts--end-count) 1)) + +(defun lua-ts--end-indent-offset (&rest _) + "Calculate indent offset based on `end' count." + (- (* (1- (lua-ts--end-count)) lua-ts-indent-offset))) + +(defun lua-ts--end-count () + "Count the number of `end's on the current line." + (count-matches "end" (line-beginning-position) (line-end-position))) + +(defun lua-ts--first-child-matcher (node &rest _) + "Matches if NODE is the first among its siblings." + (= (treesit-node-index node) 1)) + +(defun lua-ts--function-definition-p (node) + "Return t if NODE is a function_definition." + (equal "function_definition" (treesit-node-type node))) + +(defun lua-ts--g-g-g-parent (node) + "Return the great-great-grand-parent of NODE." + (let* ((parent (treesit-node-parent node)) + (g-parent (treesit-node-parent parent)) + (g-g-parent (treesit-node-parent g-parent))) + (treesit-node-parent g-g-parent))) + +(defun lua-ts--nested-function-argument-matcher (node &rest _) + "Matches if NODE is in a nested function argument." + (save-excursion + (goto-char (treesit-node-start node)) + (treesit-beginning-of-defun) + (backward-char 2) + (not (looking-at ")(")))) + +(defun lua-ts--nested-function-block-matcher (node &rest _) + "Matches if NODE is in a nested function block." + (let* ((g-g-g-parent (lua-ts--g-g-g-parent node)) + (g-g-g-type (treesit-node-type g-g-g-parent))) + (not (equal g-g-g-type "chunk")))) + +(defun lua-ts--nested-function-block-include-matcher (node _p bol &rest _) + "Matches if NODE's child at BOL is not another block." + (let* ((child (treesit-node-first-child-for-pos node bol)) + (child-type (treesit-node-type child)) + (g-g-g-type (treesit-node-type (lua-ts--g-g-g-parent node)))) + (or (equal child-type "assignment_statement") + (and (equal child-type "return_statement") + (or (equal g-g-g-type "arguments") + (and (equal g-g-g-type "expression_list") + (not (treesit-search-subtree child "function_call")))))))) + +(defun lua-ts--nested-function-end-matcher (node &rest _) + "Matches if NODE is the `end' of a nested function." + (save-excursion + (goto-char (treesit-node-start node)) + (treesit-beginning-of-defun) + (looking-at "function[[:space:]]*"))) + +(defun lua-ts--nested-function-end-argument-matcher (node &rest _) + "Matches if great-great-grandparent of NODE is arguments." + (equal "arguments" (treesit-node-type (lua-ts--g-g-g-parent node)))) + +(defun lua-ts--nested-function-last-function-matcher (_n parent &rest _) + "Matches if PARENT is the last nested function." + (let ((sparse-tree + (treesit-induce-sparse-tree parent #'lua-ts--function-definition-p))) + (= 1 (length (cadr sparse-tree))))) + (defvar lua-ts--syntax-table (let ((table (make-syntax-table))) (modify-syntax-entry ?+ "." table) @@ -352,26 +478,124 @@ lua-ts-flymake-luacheck (defun lua-ts-inferior-lua () "Run a Lua interpreter in an inferior process." (interactive) - (let* ((buffer lua-ts-inferior-buffer) - (name (string-replace "*" "" buffer)) - (program lua-ts-inferior-program) - (prompt-regexp lua-ts-inferior-prompt-regexp) - (switches lua-ts-inferior-options) - (startfile lua-ts-inferior-startfile)) - (unless (comint-check-proc buffer) - (set-buffer (apply (function make-comint) name program startfile switches)) + (unless (comint-check-proc lua-ts-inferior-buffer) + (apply #'make-comint-in-buffer + (string-replace "*" "" lua-ts-inferior-buffer) + lua-ts-inferior-buffer + lua-ts-inferior-program + lua-ts-inferior-startfile + lua-ts-inferior-options) + (when lua-ts-inferior-history + (set-process-sentinel (get-buffer-process lua-ts-inferior-buffer) + 'lua-ts-inferior--write-history)) + (with-current-buffer lua-ts-inferior-buffer (setq-local comint-input-ignoredups t + comint-input-ring-file-name lua-ts-inferior-history + comint-use-prompt-regexp t comint-prompt-read-only t - comint-prompt-regexp prompt-regexp - comint-use-prompt-regexp t)) - (select-window (display-buffer buffer '((display-buffer-reuse-window - display-buffer-pop-up-frame) - (reusable-frames . t)))))) + comint-prompt-regexp (rx-to-string `(: bol + ,lua-ts-inferior-prompt + (1+ space)))) + (comint-read-input-ring t) + (add-hook 'comint-preoutput-filter-functions + (lambda (string) + (if (equal string (concat lua-ts-inferior-prompt-continue " ")) + string ; Don't mess with continuation prompts. + (concat + ;; Filter out the extra prompt characters that + ;; accumulate in the output when sending regions + ;; to the inferior process. + (replace-regexp-in-string (rx-to-string + `(: bol + (* ,lua-ts-inferior-prompt + (? ,lua-ts-inferior-prompt) + (1+ space)) + (group (* nonl)))) + "\\1" string) + ;; Re-add the prompt for the next line. + lua-ts-inferior-prompt " ")))))) + (select-window (display-buffer lua-ts-inferior-buffer + '((display-buffer-reuse-window + display-buffer-pop-up-frame) + (reusable-frames . t)))) + (get-buffer-process (current-buffer))) + +(defun lua-ts-send-buffer () + "Send current buffer to the inferior Lua process." + (interactive) + (lua-ts-send-region (point-min) (point-max))) + +(defun lua-ts-send-file (file) + "Send contents of FILE to the inferior Lua process." + (interactive "f") + (with-temp-buffer + (insert-file-contents-literally file) + (lua-ts-send-region (point-min) (point-max)))) + +(defun lua-ts-send-region (beg end) + "Send region between BEG and END to the inferior Lua process." + (interactive "r") + (let ((string (buffer-substring-no-properties beg end)) + (proc-buffer (lua-ts-inferior-lua))) + (comint-send-string proc-buffer "print()") ; Prevent output from + (comint-send-string proc-buffer "\n") ; appearing at prompt. + (comint-send-string proc-buffer string) + (comint-send-string proc-buffer "\n"))) + +(defun lua-ts-show-process-buffer () + "Show the inferior Lua process buffer." + (interactive) + (display-buffer lua-ts-inferior-buffer)) + +(defun lua-ts-hide-process-buffer () + "Hide the inferior Lua process buffer." + (interactive) + (delete-windows-on lua-ts-inferior-buffer)) + +(defun lua-ts-kill-process () + "Kill the inferior Lua process." + (interactive) + (with-current-buffer lua-ts-inferior-buffer + (kill-buffer-and-window))) + +(defun lua-ts-inferior--write-history (process _) + "Write history file for inferior Lua PROCESS." + ;; Depending on how the process is killed the buffer may not be + ;; around anymore; e.g. `kill-buffer'. + (when-let* ((buffer (process-buffer process)) + ((buffer-live-p (process-buffer process)))) + (with-current-buffer buffer (comint-write-input-ring)))) + +(defvar lua-ts-mode-map + (let ((map (make-sparse-keymap "Lua"))) + (define-key map "\C-c\C-n" 'lua-ts-inferior-lua) + (define-key map "\C-c\C-c" 'lua-ts-send-buffer) + (define-key map "\C-c\C-l" 'lua-ts-send-file) + (define-key map "\C-c\C-r" 'lua-ts-send-region) + map) + "Keymap for `lua-ts-mode' buffers.") + +(easy-menu-define lua-ts-mode-menu lua-ts-mode-map + "Menu bar entry for `lua-ts-mode'." + `("Lua" + ["Evaluate Buffer" lua-ts-send-buffer] + ["Evaluate File" lua-ts-send-file] + ["Evaluate Region" lua-ts-send-region] + "--" + ["Start Process" lua-ts-inferior-lua] + ["Show Process Buffer" lua-ts-show-process-buffer] + ["Hide Process Buffer" lua-ts-hide-process-buffer] + ["Kill Process" lua-ts-kill-process] + "--" + ["Customize" (lambda () (interactive) (customize-group "lua-ts"))])) ;;;###autoload (define-derived-mode lua-ts-mode prog-mode "Lua" - "Major mode for editing Lua files, powered by tree-sitter." + "Major mode for editing Lua files, powered by tree-sitter. + +\\{lua-ts-mode-map}" :syntax-table lua-ts--syntax-table + (use-local-map lua-ts-mode-map) (when (treesit-ready-p 'lua) (treesit-parser-create 'lua) @@ -415,7 +639,9 @@ lua-ts-mode "while_statement"))) (sexp ,(rx (or "arguments" "block" + "function_declaration" "parameters" + "parenthesized_expression" "string" "table_constructor"))) (text "comment")))) diff --git a/test/lisp/progmodes/lua-ts-mode-resources/indent.erts b/test/lisp/progmodes/lua-ts-mode-resources/indent.erts index 040225c8580..25d29e0fbc5 100644 --- a/test/lisp/progmodes/lua-ts-mode-resources/indent.erts +++ b/test/lisp/progmodes/lua-ts-mode-resources/indent.erts @@ -5,148 +5,645 @@ Code: (lua-ts-mode) (indent-region (point-min) (point-max))) -Name: Basic Indent +Name: Chunk Indent =-= - print( -0, - 1 -) + print(1) + print(2) +=-= +print(1) +print(2) +=-=-= -local function f(o) - if o.x > o.y then - return o.x -elseif o.y > o.z then - return o.y - else -return o.z - end +Name: Function Indent + +=-= +function f1(n) +print(n) +return n + 1 end -f({ - x = 1, - y = 2, - z = 3, -}) +local function f2(n) +print(n) +return n * 2 +end -;(function() -return false -)() +local f3 = function(n) +print(n) +return n / 3 +end + +function f4(...) +local f = function (...) +if ok +then print(1) +else print(0) +end +end +return f +end + +function f5(...) +local f = function (...) +if ok +then +print(1) +else +print(0) +end +end +return f +end + +function f6(...) +local f = function (...) +if ok then +print(1) +else +print(0) +end +end +return f +end + +;(function () + return true + end)() =-= -print( - 0, - 1 -) +function f1(n) + print(n) + return n + 1 +end + +local function f2(n) + print(n) + return n * 2 +end -local function f(o) - if o.x > o.y then - return o.x - elseif o.y > o.z then - return o.y - else - return o.z +local f3 = function(n) + print(n) + return n / 3 +end + +function f4(...) + local f = function (...) + if ok + then print(1) + else print(0) + end end + return f end -f({ - x = 1, - y = 2, - z = 3, -}) +function f5(...) + local f = function (...) + if ok + then + print(1) + else + print(0) + end + end + return f +end -;(function() - return false -)() +function f6(...) + local f = function (...) + if ok then + print(1) + else + print(0) + end + end + return f +end + +;(function () + return true +end)() =-=-= -Name: Argument Indent +Name: Conditional Indent =-= -function h( -string, -number, -options) -print(string, number, options) +if true then +print(true) +return 1 +elseif false then +print(false) +return -1 +else +print(nil) +return 0 end -local p = h( -"sring", - 1000, - { -cost = 2, -length = 8, - parallelism = 4, -}) +if true + then + print(true) + return 1 + elseif false + then + print(false) + return -1 + else + print(nil) + return 0 +end + +if true + then return 1 + elseif false + then return -1 + else return 0 +end =-= -function h( - string, - number, - options) - print(string, number, options) +if true then + print(true) + return 1 +elseif false then + print(false) + return -1 +else + print(nil) + return 0 end -local p = h( - "sring", - 1000, - { - cost = 2, - length = 8, - parallelism = 4, - }) +if true +then + print(true) + return 1 +elseif false +then + print(false) + return -1 +else + print(nil) + return 0 +end + +if true +then return 1 +elseif false +then return -1 +else return 0 +end +=-=-= + +Name: Loop Indent + +=-= +for k,v in pairs({}) do + print(k) + print(v) +end + +for i=1,10 + do print(i) +end + +while n < 10 do + n = n + 1 + print(n) +end + +while n < 10 + do + n = n + 1 + print(n) +end + +for i=0,9 do +repeat n = n+1 + until n > 99 +end + +repeat +z = z * 2 +print(z) +until z > 12 + + for i,x in ipairs(t) do + while i < 9 + do + local n = t[x] + repeat n = n + 1 + until n > #t + while n < 99 + do + print(n) + end + end + print(t[i]) + end +=-= +for k,v in pairs({}) do + print(k) + print(v) +end + +for i=1,10 +do print(i) +end + +while n < 10 do + n = n + 1 + print(n) +end + +while n < 10 +do + n = n + 1 + print(n) +end + +for i=0,9 do + repeat n = n+1 + until n > 99 +end + +repeat + z = z * 2 + print(z) +until z > 12 + +for i,x in ipairs(t) do + while i < 9 + do + local n = t[x] + repeat n = n + 1 + until n > #t + while n < 99 + do + print(n) + end + end + print(t[i]) +end +=-=-= + +Name: Bracket Indent + +=-= +fn( + ) + +tb={ + } +=-= +fn( +) + +tb={ +} =-=-= -Name: Continuation Indent +Name: Multi-line String Indent =-= +local s = [[ + Multi-line + string content + ]] + function f() local str = [[ multi-line string ]] ---[[ -multi-line -comment - ]] return true end =-= +local s = [[ + Multi-line + string content + ]] + function f() local str = [[ multi-line string ]] - --[[ + return true +end +=-=-= + +Name: Multi-line Comment Indent + +=-= +--[[ + Multi-line + comment content + ]] + +function f() +--[[ +multi-line + comment + ]] + return true +end +=-= +--[[ + Multi-line + comment content + ]] + +function f() +--[[ multi-line -comment + comment ]] return true end =-=-= -Name: Loop Indent +Name: Argument Indent =-= -for k, v in pairs({}) do - print(k, v) + h( + "string", + 1000 + ) + +local p = h( +"string", + 1000 +) + +fn(1, +2, + 3) + +fn( 1, 2, +3, 4 ) + +f({ +x = 1, +y = 2, +z = 3, +}) + +f({ x = 1, +y = 2, +z = 3, }) +=-= +h( + "string", + 1000 +) + +local p = h( + "string", + 1000 +) + +fn(1, + 2, + 3) + +fn( 1, 2, + 3, 4 ) + +f({ + x = 1, + y = 2, + z = 3, +}) + +f({ x = 1, + y = 2, + z = 3, }) +=-=-= + +Name: Parameter Indent + +=-= +function f1( +a, +b +) +print(a,b) end -while n < 10 do -n = n + 1 +local function f2(a, + b) +print(a,b) end -repeat -z = z * 2 - until z > 12 +local f3 = function( a, b, + c, d ) +print(a,b,c,d) +end =-= -for k, v in pairs({}) do - print(k, v) +function f1( + a, + b +) + print(a,b) end -while n < 10 do - n = n + 1 +local function f2(a, + b) + print(a,b) end -repeat - z = z * 2 -until z > 12 +local f3 = function( a, b, + c, d ) + print(a,b,c,d) +end +=-=-= + +Name: Table Indent + +=-= +local Other = { + First={up={Step=true,Jump=true}, + down={Step=true,Jump=true}, + left={Step=true,Jump=true}, + right={Step=true,Jump=true}}, + Second={up={Step=true,Jump=true}, + down={Step=true,Jump=true}, + left={Step=true,Jump=true}, + right={Step=true,Jump=true}}, + Third={up={Goto=true}, + down={Goto=true}, + left={Goto=true}, + right={Goto=true}} +} + +local Other = { +a = 1, + b = 2, + c = 3, +} +=-= +local Other = { + First={up={Step=true,Jump=true}, + down={Step=true,Jump=true}, + left={Step=true,Jump=true}, + right={Step=true,Jump=true}}, + Second={up={Step=true,Jump=true}, + down={Step=true,Jump=true}, + left={Step=true,Jump=true}, + right={Step=true,Jump=true}}, + Third={up={Goto=true}, + down={Goto=true}, + left={Goto=true}, + right={Goto=true}} +} + +local Other = { + a = 1, + b = 2, + c = 3, +} +=-=-= + +Code: + (lambda () + (setq indent-tabs-mode nil) + (setq lua-ts-indent-offset 4) + (lua-ts-mode) + (indent-region (point-min) (point-max))) + +Name: End Indent + +=-= +function f(x) + for y=1,x.y do + for x=1,x.z do + if x.y and x.z then + if y <= x then + y = y + 1 + end end end end + return {x,y} or {math.random(),math.random()} + end + +for y=1,x.y do + for x=1,x.z do + if x.y and x.z then + if y <= x then + y = y + 1 + end + end end end +=-= +function f(x) + for y=1,x.y do + for x=1,x.z do + if x.y and x.z then + if y <= x then + y = y + 1 + end end end end + return {x,y} or {math.random(),math.random()} +end + +for y=1,x.y do + for x=1,x.z do + if x.y and x.z then + if y <= x then + y = y + 1 + end +end end end +=-=-= + +Name: Nested Function Indent + +=-= +function a(...) + return (function (x) + return x + end)(foo(...)) +end + +function b(n) + local x = 1 + return function (i) + return function (...) + return (function (n, ...) + return function (f, ...) + return (function (...) + if ... and x < 9 then + x = x + 1 + return ... + end end)(n(f, ...)) + end, ... + end)(i(...)) +end end end + +function c(f) + local f1 = function (...) + if nil ~= ... then + return f(...) + end + end + return function (i) + return function (...) + local fn = function (n, ...) + local x = function (f, ...) + return f1(n(f, ...)) + end + return x + end + return fn(i(...)) + end + end +end + +function d(f) + local f1 = function (c, f, ...) + if ... then + if f(...) then + return ... + else + return c(f, ...) + end end end + return function (i) + return function (...) + return (function (n, ...) + local function j (f, ...) + return f1(j, f, n(f, ...)) + end + return j, ... + end)(i(...)) +end end end + +function e (n, t) + return function (i) + return function (...) + return ( + function (n, ...) + local x, y, z = 0, {} + return (function (f, ...) + return (function (i, ...) return i(i, ...) end)( + function (i, ...) + return f(function (x, ...) + return i(i, ...)(x, ...) + end, ...) + end) + end)(function (j) + return function(f, ...) + return (function (c, f, ...) + if ... then + if n+1 == x then + local y1, x1 = y, x + y, x = {}, 0 + return (function (...) + z = ... + return ... + end)(t(y1-1, x1-1, ...)) + else + x = x - 1 + return c(f, + (function (...) + z = ... + return ... + end)(t(y, x, ...))) + end + elseif x ~= 0 then + x = 0 + return z, y + end end)(j, f, n(f, ...)) + end end), ... + end)(i(...)) +end end end =-=-= diff --git a/test/lisp/progmodes/lua-ts-mode-resources/movement.erts b/test/lisp/progmodes/lua-ts-mode-resources/movement.erts index 770aa23b18d..afebe93de3f 100644 --- a/test/lisp/progmodes/lua-ts-mode-resources/movement.erts +++ b/test/lisp/progmodes/lua-ts-mode-resources/movement.erts @@ -481,6 +481,34 @@ local t = { 1, 3 }| =-=-= +Name: forward-sexp moves over parenthesized expressions + +=-= +|(function (x) return x + 1 end)(41) +=-= +(function (x) return x + 1 end)|(41) +=-=-= + +Name: forward-sexp moves over function declarations + +=-= +|function foo (x) + if false then + print "foo" + elseif true then + print "bar" + end +end +=-= +function foo (x) + if false then + print "foo" + elseif true then + print "bar" + end +end| +=-=-= + Code: (lambda () (lua-ts-mode) @@ -551,3 +579,31 @@ local t = |{ 1, 2, 3 } =-=-= + +Name: backward-sexp moves over parenthesized expressions + +=-= +(function (x) return x + 1 end)|(41) +=-= +|(function (x) return x + 1 end)(41) +=-=-= + +Name: backward-sexp moves over function declarations + +=-= +function foo (x) + if false then + print "foo" + elseif true then + print "bar" + end +end| +=-= +|function foo (x) + if false then + print "foo" + elseif true then + print "bar" + end +end +=-=-= -- 2.41.0