ZyX_I avatar ZyX_I committed ec9bc14

@/fwc: Fixed `either' key when one of the alternatives contains a check

Comments (0)

Files changed (3)

plugin/frawor/fwc/compiler.vim

     endif
     return self.getvar(a:str)
 endfunction
+"▶1 getmatchstr     :: ldstr, exptype, varname + self → vimlexpr + self
+function s:compiler.getmatchstr(ldstr, exptype, ldtmp)
+    if a:exptype==type([])
+        return 'copy('.a:ldstr.')'
+    elseif a:exptype==type({})
+        return 'sort(keys('.a:ldstr.'))'
+    else
+        call self.let(a:ldtmp, a:ldstr)
+        return '((type('.a:ldtmp.')=='.type([]).')?'.
+                    \'('.a:ldtmp.'):'.
+                    \'(sort(keys('.a:ldtmp.'))))'
+    endif
+endfunction
 "▶1 addmatches      :: &self(ldstr, exptype)
 function s:compiler.addmatches(ldstr, exptype)
     if self.joinlists
 function s:compiler.addjoinedmtchs()
     if !self.joinlists && !empty(self.ldstrs)
         let curldbase=self.getlvarid('curld').'_'
-        let ambstrs=[]
-        let i=0
-        for [ldstr, exptype] in remove(self.ldstrs, 0, -1)
-            if exptype==type([])
-                call add(lststrs, ldstr)
-            elseif exptype==type({})
-                call add(lststrs, 'sort(keys('.ldstr.'))')
-            else
-                let curldstr=curldbase.i
-                call add(ambstrs, curldstr)
-                call self.let(curldstr, ldstr)
-                call add(lststrs, '((type('.curldstr.')=='.type([]).')?'.
-                            \           '('.curldstr.'):'.
-                            \           '(sort(keys('.curldstr.'))))')
-            endif
-            let i+=1
-        endfor
+        let lststrs=map(remove(self.ldstrs, 0, -1),
+                    \   'self.getmatchstr(v:val[0], v:val[1], curldbase.v:key)')
         call self.addmatches(join(lststrs, '+'), type([]))
-        if !empty(ambstrs)
-            call self.unlet(ambstrs)
-        endif
     endif
     return self
 endfunction
+"▶1 joinmatches     :: &self(idx, varname)
+function s:compiler.joinmatches(jstart, matchesstr)
+    if len(self.ldstrs)<=a:jstart
+        return self
+    endif
+    let curldbase=self.getlvarid('curld').'_'
+    call self.let(a:matchesstr,
+                \ join(map(remove(self.ldstrs, a:jstart, -1),
+                \          'self.getmatchstr(v:val[0], v:val[1], '.
+                \                           'curldbase.v:key)'),
+                \      '+'))
+    call add(self.ldstrs, [a:matchesstr, type([])])
+    return self
+endfunction
 "▶1 addthrow        :: &self(msg::String, msgarg, needcurarg, ...)
 function s:compiler.addthrow(msg, needcurarg, ...)
     let args=self.string(a:msg).', '
     endif
     return 0
 endfunction
-"▶1 optimizecompf   :: &self
+"▶1 optimizecompf   :: &self(varname)
 " XXX low-level hacks here
-function s:compiler.optimizecompf()
+function s:compiler.optimizecompf(vstr)
     call self.down(self.l[2][-1][1])
     let conditions=self.optgetconds()
     call self.up()
         let argidxstr=self.l[-1][1][-1][1]
         let removestr=self.l[-1][-1][0][1]
         let condition=join(conditions, ' || ')
-        let chargstr='@-@['.argidxstr.']'
+        let chargstr=a:vstr.'['.argidxstr.']'
         if condition=~#'\v^%([^@]|\V'.chargstr.'\v)+$'
             call self.up().up()
             call remove(self.l, -2, -1)
             let condition=substitute(condition, '\V'.chargstr, 'v:val', 'g')
-            call self.call('filter(@-@, '.string('!('.condition.')').')')
+            call self.call('filter('.a:vstr.', '.string('!('.condition.')').')')
         else
             call remove(self.l, -1)
             call self.if(condition)
         let addedcompletion=0
         let addedcycle=0
         let argidxstr=self.getlvarid('argidx')
+        let vstr='@-@'
+        let jstart=len(self.ldstrs)
     endif
     for proc in arg
         let i+=1
         if a:type is# 'complete'
             if addedcompletion && !addedcycle
                 let addedcycle=1
+                if self.joinlists && vstr is# '@-@'
+                    let mtchsstr=self.getlvarid('matches').'_'.matchstr(a:idx,
+                                \                                      '\v\d+$')
+                    let vstr=mtchsstr
+                    call self.joinmatches(jstart, mtchsstr)
+                endif
                 call self.let(argidxstr, 0)
-                            \.while(argidxstr.'<len(@-@)')
+                            \.while(argidxstr.'<len('.vstr.')')
                                 \.try()
                                     \.pushms('throwignore')
-                                    \.witharg(['@-@', [[argidxstr]]])
+                                    \.witharg([vstr, [[argidxstr]]])
             elseif compargs[0][1][0] is# 'intfunc' &&
                         \has_key(s:_r.FWC_intfuncs[compargs[0][1][1]],
                         \        'breakscomp')
         call self.without().popms()
                     \.increment(argidxstr)
                 \.up().catch(s:cfreg)
-                    \.call('remove(@-@, '.argidxstr.')')
+                    \.call('remove('.vstr.', '.argidxstr.')')
                 \.up()
             \.up().up()
-            \.optimizecompf()
+            \.optimizecompf(vstr)
     endif
     return self
 endfunction

plugin/frawor/fwc/intfuncs.vim

     lockvar! s:vimoptions
     return copy(s:vimoptions)
 endfunction
+"▶1 compexpr :: () + ? → [String]
+" TODO
 "▲1
 "Filters/checkers --------------------------------------------------------------
 "▶1 `func', `eval'

test/fwccompletetests.dat

 
   @d
   def-ghi
+`either ((in list match /b/), (key dict match /e/))
+  @+
+  abc ab-c adb aef
+
+`either (in list3, either ((in list match /b/), (key dict match /e/)))
+  @+
+  foo bar baz abc ab-c adb aef
 #▶2 first
 `first in list, key dict
   @+
 
   @abc+
   allfolds noallfolds
-# vim: cms=#%s fmr=▶,▲ sw=2 ts=2 sts=2 et
+# vim: cms=#%s fmr=▶,▲ sw=2 ts=2 sts=2 et ft=conf
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.