ZyX_I avatar ZyX_I committed e76eebe

@/checks: Added squashing of args, improved .scanact() (it now has noaction and action described by check)

Comments (0)

Files changed (1)

plugin/frawor/checks.vim

 "▶2 scan.scanlist   :: farg + self → self
 " Scans a list of elements that looks either like "{e1}, {e2}", "({e1} {e2})" or 
 " "({e1}, {e2})" (last two can be combined).
+" Input: {<farg>} ( "," {<farg>} )*
+"      | "(" ( {<farg>} ","? )* ")"?
+" Output: context({<farg>}*)
 function s:F.scan.scanlist(farg)
     call self.addcon()
     if !self.eos
 " Input: "~" {matcher} ( {actdescr} ( "(" {arg}* ")"? | {arg} ) )* ">"?
 "        {actdescr} :: {str}
 "                    | {wordchar}+
-" Output: context(actions[, {matcher}], (context(String, {arg}+))*)
+" Output: context(actions[, {matcher}],
+"                 (context(0|String|context({arg}), {arg}+))*)
 function s:F.scan.scanact()
-    let p={}
-    call self.addcon('actions', p)
+    call self.addcon('actions')
     if self.eos
         call self.throw('actmis')
     endif
     else
         call self.ungetc(c)
     endif
+    let hasaction=0
     while !self.eos
         let c=self.readc()
-        if !exists('action')
+        if !hasaction
+            let hasaction=1
             if c is '"'
-                let c=self.readstr()
-                let action=c
+                call self.addcon(self.readstr())
+            elseif c is '_'
+                call self.addcon(0)
             elseif c=~#'^\w'
-                let action=c
+                call self.addcon(c)
             elseif c is '>'
                 break
             else
-                call self.throw('invact', c)
+                call self.ungetc(c).addcon().scan().conclose()
             endif
         else
-            call self.addcon(action)
-            unlet action
+            let hasaction=0
             if c is '('
                 while !self.eos
                     let c=self.readc()
                     endif
                     call self.ungetc(c).scan()
                 endwhile
-                call self.conclose()
             else
                 call self.ungetc(c).scan()
             endif
+            call self.conclose()
         endif
     endwhile
     return self.conclose()
 function s:F.scan.scan()
     let c=self.readc()
     let type=self.stack[-1][0]
-    if type is self.o || type is "actions"
+    if type is "top" || type is "actions"
         if c is '['
             return self.scanopt()
         elseif c is '{'
 endfunction
 "▶2 scan.scanopts   :: &self
 " Input: "-" "("? ( "no"? ( "only" ) )* ")"
+" Output: add(<self.o>)
 let s:options={'only': 0,}
 function s:F.scan.scanopts()
     let c=self.readc()
 "▶2 scan.string     :: String → SynTree
 function s:F.scan.string(string)
     let s   =   {    's': a:string,
-                \ 'tree': [],
+                \ 'tree': ["top"],
                 \'stack': [],
                 \'ungot': [],
                 \    'l': 0,
     let s.l=s.stack[-1]
     call s.scanopts()
     let prevlen=0
-    while !s.eos && len(s.s)!=prevlen
+    if s.o.only
         call s.scan()
-        let prevlen=len(s.s)
-    endwhile
+    else
+        while !s.eos && len(s.s)!=prevlen
+            let prevlen=len(s.s)
+            call s.scan()
+        endwhile
+    endif
+    "▶3 Squash {arg}s
+    if len(s.l)>2 && s.l[2][0] is s.type
+        let s.l[2]=["args", s.l[2]]
+        let i=3
+        while i<len(s.l)
+            if s.l[i][0] is s.type
+                call add(s.l[2], remove(s.l, i))
+            else
+                let i+=1
+            endif
+        endwhile
+    endif
+    "▲3
     return s.tree
 endfunction
 "▶1 FIXME this is for debugging
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.