emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/lua-mode 993e042 113/468: Merge branch 'multiline_literals


From: Philip Kaludercic
Subject: [nongnu] elpa/lua-mode 993e042 113/468: Merge branch 'multiline_literals'
Date: Thu, 5 Aug 2021 04:58:18 -0400 (EDT)

branch: elpa/lua-mode
commit 993e042d0aa23d8b587148553354d493a2156a19
Merge: c69e150 f834c21
Author: immerrr <immerrr+lua@gmail.com>
Commit: immerrr <immerrr+lua@gmail.com>

    Merge branch 'multiline_literals'
---
 TODO        |  38 ++++++++++++++++----
 lua-mode.el | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 135 insertions(+), 18 deletions(-)

diff --git a/TODO b/TODO
index 6b5def5..2855b58 100644
--- a/TODO
+++ b/TODO
@@ -1,14 +1,40 @@
-* Add docs about lua-prefix-key machinery
-* Support line-continuation with commas, e.g.
-   x,y = long_value,
-         other_long_value
+# -*- mode: org -*-
 
-* Support line-continuation commas in `for ... do ' operators
-* Fix braces/parens that reduce indent by const offset
+* TODO Improve lua-prefix-key machinery [0/2]
+  - [ ] add docs
+  - [ ] improve setting prefix-key
+    Currently, prefix-key is parsed from a macro string (which may
+    contain more than one key) and all keys but the first one are
+    silently removed. Maybe there's a better way to do it.
+
+* TODO Support line-continuation with commas [0/2]
+  - [ ]  assignments
+    x,y = long_value,
+          other_long_value
+  - [ ] `for ... do' operators
+* TODO Fix braces/parens that reduce indent by const offset
    this causes wrong behavior when indented block was
    anchored to first line, e.g.
    my_func( hello,
             world
          )
 
+* TODO lua-mark-all-multiline-literals [4/5]
+  - [X] process --[[ as multiline comment
+  - [X] process ---[[ as single-line comment
+    distinguish by syntax state of last dash before square bracket
+  - [X] don't recognize [[ in comments or literals
+  - [ ] extend region backwards if BEGIN is inside multiline literal
+  - [X] don't change buffer-modified-p state
+
+* TODO lua-mark-multiline-region [0/3]
+  - [ ] handle all pre-existing  multiline markers inside the region
+    If region contains multiline beginning markers, delete them along
+    with their counterparts.
+  - [ ] mark-up regions that become unmarked during last operation
+    Specifically, there might be a problem when unmarked region spans
+    further than the original one (maybe, need to recurse the call)
+  - [ ] mark the whole multiline region with a property
+    It might be easier to track region modifications on-fly this way
+
 * Redo syntax engine using semantic/wisent
diff --git a/lua-mode.el b/lua-mode.el
index cf18d9c..27c8fd7 100644
--- a/lua-mode.el
+++ b/lua-mode.el
@@ -165,7 +165,8 @@ Should be a list of strings."
       (mapc (lambda (key_defn)
               (define-key result-map (read-kbd-macro (car key_defn)) (cdr 
key_defn)))
             '(("C-l" . lua-send-buffer)
-              ("C-f" . lua-search-documentation)))
+              ("C-f" . lua-search-documentation)
+              ("C-;" . lua-mark-all-multiline-literals)))
       result-map))
   "Keymap that is used to define keys accessible by `lua-prefix-key'.
 
@@ -261,10 +262,6 @@ traceback location."
      '("\\(\\(\\sw:\\|\\sw\\.\\|\\sw_\\|\\sw\\)+\\)[ \t]*=[ 
\t]*\\(function\\)\\_>"
        (1 font-lock-function-name-face nil t) (3 font-lock-keyword-face))
 
-     ;; Multi-line string literals.
-     '("[^-]\\[=*\\[\\(\\([^]]\\|][^]]\\|]=+[^]]\\)*?\\)]=*]"
-       (1 font-lock-string-face t))
-
      ;; Keywords.
      (concat "\\_<"
              (regexp-opt '("and" "break" "do" "else" "elseif" "end" "false"
@@ -370,12 +367,14 @@ The following keys are bound:
                      ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words) ;start
                      ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words) ;end
                      nil lua-forward-sexp)))
+
+    (set (make-local-variable 'parse-sexp-lookup-properties) t)
+    (lua-mark-all-multiline-literals)
     (run-hooks 'lua-mode-hook)))
 
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.lua$" . lua-mode))
 
-
 (defun lua-electric-match (arg)
   "Insert character and adjust indentation."
   (interactive "P")
@@ -407,17 +406,17 @@ This function replaces previous prefix-key binding with a 
new one."
   (lua--customize-set-prefix-key 'lua-prefix-key new-key-str)
   (lua-prefix-key-update-bindings))
 
-(defun lua-string-p ()
+(defun lua-string-p (&optional pos)
   "Returns true if the point is in a string."
-  (elt (syntax-ppss) 3))
+  (elt (syntax-ppss pos) 3))
 
-(defun lua-comment-p ()
+(defun lua-comment-p (&optional pos)
   "Returns true if the point is in a comment."
-  (elt (syntax-ppss) 4))
+  (elt (syntax-ppss pos) 4))
 
-(defun lua-comment-or-string-p ()
+(defun lua-comment-or-string-p (&optional pos)
   "Returns true if the point is in a comment or string."
-  (let ((parse-result (syntax-ppss)))
+  (let ((parse-result (syntax-ppss pos)))
     (or (elt parse-result 3) (elt parse-result 4))))
 
 (defun lua-indent-line ()
@@ -1175,6 +1174,98 @@ left out."
 (define-key lua-mode-menu [search-documentation]
   '("Search Documentation" . lua-search-documentation))
 
+(defsubst lua-put-char-property (pos property value &optional object)
+  (if value
+      (put-text-property pos (1+ pos) property value object)
+    (remove-text-properties pos (1+ pos) (list property nil))))
+
+(defsubst lua-put-char-syntax-table (pos value &optional object)
+  (lua-put-char-property pos 'syntax-table value object))
+
+(defsubst lua-get-multiline-delim-syntax (type)
+  (cond ((eq type 'string) '(15))
+        ((eq type 'comment) '(14))
+        (nil)))
+
+(defun lua-mark-char-multiline-delim (pos type)
+  "Mark character as a delimiter of Lua multiline construct
+
+If TYPE is string, mark char  as string delimiter. If TYPE is comment,
+mark char as comment delimiter.  Otherwise, remove the mark if any."
+  (let ((old-modified-p (buffer-modified-p)))
+    (unwind-protect
+        (lua-put-char-syntax-table pos (lua-get-multiline-delim-syntax type))
+      (set-buffer-modified-p old-modified-p))))
+
+(defsubst lua-inside-multiline-p (&optional pos)
+  (let ((status (syntax-ppss pos)))
+    (or (eq (elt status 3) t)                ;; inside generic string
+        (eq (elt status 7) 'syntax-table)))) ;; inside generic comment
+
+(defun lua-get-multiline-start (&optional pos)
+  (interactive)
+  (when (lua-inside-multiline-p pos) ;; return string/comment start
+    (elt (syntax-ppss pos) 8)))
+
+(defun lua-unmark-multiline-literals (&optional begin end)
+  "Clears all Lua multiline construct markers in region
+
+If BEGIN is nil, start from `beginning-of-buffer'.
+If END is nil, stop at `end-of-buffer'."
+  (interactive)
+  (let ((old-modified-p (buffer-modified-p)))
+    (unwind-protect
+        (remove-text-properties (or begin 1) (or end (buffer-size)) 
'(syntax-table ()))
+      (set-buffer-modified-p old-modified-p)))
+  (font-lock-fontify-buffer))
+
+(defun lua-mark-multiline-region (begin end)
+  (let ((type (if (eq ?- (char-after begin)) 'comment 'string)))
+  (lua-mark-char-multiline-delim begin type)
+  (when end
+    (lua-mark-char-multiline-delim (1- end) type))))
+
+(defun lua-mark-all-multiline-literals (&optional begin end)
+  "Marks all Lua multiline constructs in region
+
+If BEGIN is nil, start from `beginning-of-buffer'.
+If END is nil, stop at `end-of-buffer'."
+  (interactive)
+
+  (if (and (called-interactively-p 'any) (use-region-p))
+      (setq begin (region-beginning)
+            end (region-end)))
+
+  (lua-unmark-multiline-literals begin end)
+  (save-excursion
+    (goto-char (or begin 1))
+
+    (while (and
+            ;; must check  for point range,  because matching previous
+            ;; multiline  end might  move  point beyond  end and  this
+            ;; drives `re-search-forward' crazy
+            (if end (< (point) end) t)
+            ;; look for
+            ;; 1. (optional) two or more dashes followed by
+            ;; 2. lua multiline delimiter [[
+            (re-search-forward "\\(?2:--\\)?\\[\\(?1:=*\\)\\[" end 'noerror))
+      ;; match-start + 1 is considered instead of match-start, because
+      ;; such  approach  handles  '---[[' situation  correctly:  Emacs
+      ;; thinks 2nd dash (i.e.  match-start) is not yet a comment, but
+      ;; the third one is, hence the +1.  In all the other situations,
+      ;; '+1'  is safe  to use  because  it bears  the same  syntactic
+      ;; properties, i.e.  if match-start is inside string-or-comment,
+      ;; then '+1' is too and vice versa.
+      ;;
+      ;; PS. ping me if you find a situation in which this is not true
+      (unless (lua-comment-or-string-p (1+ (match-beginning 0)))
+        (let (ml-begin ml-end)
+          (setq ml-begin (match-beginning 0))
+          (when (re-search-forward (format "\\]%s\\]" (or (match-string 1) 
"")) nil 'noerror)
+            (message "found match %s" (match-string 0))
+            (setq ml-end (match-end 0)))
+          (lua-mark-multiline-region ml-begin ml-end))))))
+
 (provide 'lua-mode)
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]