Re: Is this readable?
- Posted by Bob Elia <bobelia200 at netzero.net> Aug 08, 2005
- 551 views
At 01:56 AM 8/7/05 +0100, Pete Lomax wrote: > > >Bob Elia wrote: > >Without knowing how you feel about other people working on your > >program, I took the liberty of porting a few features from my never > >released Euphoria Editor (originally by David Cuny and Carl White) to Edita. > >Bob: I welcome almost all requests and suggestions for improvements. >Code which already works, which you supplied, even moreso. I have to >admit I would probably never have thought it could be done without >seeing your code. > >I saw an opportunity to write bracket match code, so I chose to >rewrite rather than modify, which I hope does not bother you too much. Not in the least. Though I wish I had also included the bracket match code which also "jumps" using Ctrl+]. Although some of my code is multi-purpose, your elegant solution makes it appear that I created a jackhammer to drive a finishing nail. I really just wanted to get your reaction to the feature. >I would appreciate comments (from you and and others on EUforum) re >the following code. One thing which does not work is jumping to >next(/prev) control structure when not on a cs word. I am hesitating, >especially since I used the same keystroke for bracket matching, over >whether it would be sensible anyway. I installed your code in place of mine to see how it felt to use. While I still prefer my way, I attribute that to the natural preference for one's own children. ;-> In combination with my HOME key mod plus a slight change to your code I think it works just fine. >BTW: For those on EUforum not particularly familiar with Edita source, >I am assuming that globals filetext, currfile, CursorX, CursorY, >wordChar, TokenChar, MapToByte(), paintCursorY(), >forceCursorOnscreen(), and ExpLength(), are sufficiently self-evident. This change, below, looks on both sides of the cursor for a bracket character, enabling the user to use the CTRL + arrow keys to land on one if there's no intervening white space. >}}} <eucode> >global procedure ctrlBracket(integer direction) >-- >-- process ctrl [ and ctrl ]. >-- jump to matching [end] procedure/function/type/for/while; >-- cycle fwd/back through if/{elsif}/else/endif; >-- jump to matching [,], (,), {,}. >-- >sequence oneline -- scratch var >integer bX, -- CursorX of begin position, adjusted > k, > ch, > bracketmatch, -- 0=go for if/while etc; else go for {} etc > wordstart, wordend > sequence onword > sequence r -- local copy of routines[currfile], speedwise > integer cS, -- scratch var > chunkStart, -- 1..start of 1st routine-1, or: > chunkEnd -- start..end of current routine, or: > -- end prev rtn+1.. start nxt rtn-1, or: > -- end last rtn+1.. end of file. > integer len, -- length(oneline), speedwise > level, -- stack pointer of saved stuff > bracketTarget, -- want stuff at this level > skipword, -- after "end" > eWord -- scratch (1=end, 2/3=elsif/else) > sequence oX,oY -- *The Stack*: examples: > -- '{' found line 2 col 7, - trashed, or used, > when we find '}', or: > -- "if" found line 7 col 9; might be replaced by > an elsif/else; > -- - trashed, or used, when we find the "end". > >-- if isEu then --DEV currently checks for "test2.exw" >-- if isEu and rtnList then >--trace(1) > -- > -- First determine what we seek > -- > oneline=filetext[currfile][CursorY+1] > k=MapToByte(oneline,CursorX)
---------------------------------------- -- if k then -- ch = oneline[k] -- bracketmatch = find(ch,"(){}[]") ---------------------------------------- if k > 1 then ch = oneline[k - 1] bracketmatch = find(ch,"(){}[]") if not bracketmatch then ch = oneline[k] bracketmatch = find(ch,"(){}[]") else k -= 1 end if elsif k then ch = oneline[k] bracketmatch = find(ch,"(){}[]") ----------------------------------------
> else > k=length(oneline)+1 > bracketmatch=0 > end if > if not bracketmatch then > -- process eg "else" on the e, l, s, or e, equally.. > while k>1 and wordChar[oneline[k-1]] = TokenChar do > k-=1 > end while > end if > bX=k > -- > -- Calculate the smallest area to scan > -- routines[currfile] contains {names,starts,ends}, > -- eg {{"me","my"},{2,10},{8,18}} > -- > r=routines[currfile] > chunkStart=1 > chunkEnd=length(filetext[currfile]) > for i=1 to length(r[rtnNAMES]) do > cS=r[rtnSTART][i] > if cS>CursorY+1 then chunkEnd = cS-1 exit end if > chunkStart=cS > cS = r[rtnEND][i] > if cS>=CursorY+1 then chunkEnd = cS exit end if > chunkStart=cS+1 > end for > --setText(Main,sprint({chunkStart,chunkEnd})) > -- > -- And scan! > -- > level=0 > bracketTarget=-1 > skipword=0 > oX=repeat(0,32) > oY=repeat(0,32) > for i=chunkStart to chunkEnd do > oneline=filetext[currfile][i] > len=length(oneline) > k=1 > while k<=len do > ch=oneline[k] > if ch='-' and k<len and oneline[k+1]='-' > then -- skip comments > exit > elsif ch='\"' then >--- .. and strings > while k<len do > k+=1 > ch=oneline[k] > if ch='\"' then exit end if > if ch='\\' and k<len then k+=1 end if > end while > elsif bracketmatch then --count {} etc > if find(ch,"({[") then > level+=1 > if level>length(oX) then > oX&=repeat(0,32) > oY&=repeat(0,32) > end if > oX[level]=k oY[level]=i -- > remember open point > if i=CursorY+1 and k=bX then > bracketTarget=level > -- find close for this > end if > elsif find(ch,")}]") then > if i=CursorY+1 and k=bX and level > then -- jump to saved open point > paintCursorY() > CursorY=oY[level]-1 > >CursorX=ExpLength(filetext[currfile][CursorY+1][1..oX[level]-1]) > forceCursorOnscreen() > paintCursorY() > return > elsif level=bracketTarget > then -- we wanted this close point > paintCursorY() > CursorY=i-1 > >CursorX=ExpLength(oneline[1..k-1]) > forceCursorOnscreen() > paintCursorY() > return > end if > level-=1 > end if > elsif k<=length(oneline) and wordChar[oneline[k]] > = TokenChar then > wordstart=k > while k<length(oneline) and > wordChar[oneline[k+1]] = TokenChar do > k+=1 > end while > wordend=k > if skipword then > skipword=0 > else > onword = oneline[wordstart..wordend] > if > find(onword,{"if","for","while","procedure","function","type"}) then > level+=1 > if level>length(oX) then > oX&=repeat(0,32) > oY&=repeat(0,32) > end if > oX[level]=wordstart > oY[level]=i -- remember cs start > if i=CursorY+1 and > wordstart=bX then > >bracketTarget=level -- find close (or elsif/else) for this > end if > else > >eWord=find(onword,{"end","elsif","else"}) > if eWord then > -- > -- This code is <snip> control words are not balanced, though mine does catch one error. I think that this should be addressed. Thanks for your interest, Bob