sql server - Autohotkey will prematurely end loop during execution -


i've written autohotkey script allows me run sql query @ cursor's current position in microsoft sql server management studio 2012. , works--most of time anyway.

the implementation uses sort of delta movement determine when it's reached top of sql query block or top of window. selects downward until reaches bottom of window or bottom of block in same fashion. afterwards, presses f5 run script highlighted.

here's script:

$f5::     ; first check current line isn't blank (the cursor has on text)     send, {home}     hltext := selectnextchar()     if hltext = `r`n     {         ; return current position         send, {left}         return     }      ; move cursor until gets top of text block      ; first length future comparisons     send, {end}     send, {shift down}{home}{shift up}     send, ^c     stringlen, slctsize, clipboard      ; begin checking lengths see if there still 'movement'     loop     {         send, {shift down}{left}{home}{shift up}         send, ^c          ; if new length same we've hit top , can break out         stringlen, temp, clipboard         ifequal, slctsize, %temp%         {             send, {left}             break         }          ; if have hit blank space can stop here         firstchar := substr(clipboard, 1, 1)         if firstchar space         {             send, {left}{down}             break         }          ; if neither 1 of these conditions met, continue on         slctsize = %temp%         sleep, 50     }      ; select down until blank space or end of file      send, {shift down}{end}{shift up}     send, ^c     stringlen, slctsize, clipboard      loop     {         send, {shift down}{right}{end}{shift up}         send, ^c          stringlen, temp, clipboard         ifequal, slctsize, %temp%         {             break         }          ; if have hit blank space can stop here         lastchar := substr(clipboard, 0)         if lastchar space         {             break         }          ; if neither 1 of these conditions met, continue on         slctsize = %temp%         sleep, 50     }      ; execute!     send, {f5}     ; place cursor @ end of last line     send, {right} return   selectnextchar() {     send, {lshift down}{right}{lshift up}     send, ^c     return %clipboard% } 

these movements--up , down--will end prematurely, causing query not selected when f5 pressed. small queries isn't problem; large queries spanning more ~10 lines, becomes apparent going on.

i've tested placing sleep, 500 in loops, , seems trick, whole point of script make testing queries on fly lot faster. if i'm waiting more 2 or 3 seconds (hopefully) highlight, makes quicker old strategy, i.e. manually highlighting mouse?

to clear, larger queries are run part, process not fast enough warrant usage , there's no guarantee highlight before execution. understand implementation inherently o(x^2). if run script on full blast (setkeydelay, -1), wouldn't problem.

any thoughts on matter or limitation of os/program/ahk?

also, me or so's ahk syntax highlighting severely broken?

update: here's updated script suggested edits:

sendmode, input ; fast gives unpredictable results @ low sleep speeds setbatchlines, -1  $f5::     ; first check current line isn't blank (the cursor has on text)     send, {home}     hltext := selectnextchar()     if hltext = `r`n     {         ; return current position         send, {left}         return     }      ; move cursor until gets top of text block      ; first length future comparisons     send, {end}     send, {shift down}{home}{shift up}     send, ^c     sleepaftercopy()     stringlen, slctsize, clipboard      ; begin checking lengths see if there still 'movement'     loop     {         send, {shift down}{left}{home}{shift up}         send, ^c         sleepaftercopy()          ; if new length same we've hit top , can break out         stringlen, temp, clipboard         ifequal, slctsize, %temp%         {             send, {left}             break         }          ; if have hit blank space can stop here         firstchar := substr(clipboard, 1, 1)         if firstchar space         {             send, {left}{down}             break         }          ; if neither 1 of these conditions met, continue on         slctsize = %temp%     }      ; select down until blank space or end of file      send, {shift down}{end}{shift up}     send, ^c     sleepaftercopy()     stringlen, slctsize, clipboard      loop     {         send, {shift down}{right}{end}{shift up}         send, ^c         sleepaftercopy()          stringlen, temp, clipboard         ifequal, slctsize, %temp%         {             break         }          ; if have hit blank space can stop here         lastchar := substr(clipboard, 0)         if lastchar space         {             break         }          ; if neither 1 of these conditions met, continue on         slctsize = %temp%     }      ; execute!     send, {f5}     ; place cursor @ end of last line     send, {right} return   selectnextchar() {     send, {lshift down}{right}{lshift up}     send, ^c     return %clipboard% }  sleepaftercopy() {     sleep, 50 } 

update 2: here's version includes clipwait per @sidola. runs fast possible. update includes logic make sure if had copied before hand, isn't obliterated because of our overuse of clipboard. , finally, takes account indents or spaces @ beginning/ end of lines:

sendmode, input ; fast gives unpredictable results @ low sleep speeds setbatchlines, -1  #ifwinactive ahk_exe ssms.exe  $f5::     ; save current clipboard material , restore @ end     before = %clipboard%      ; first check current line isn't blank (the cursor has on text)     send, {home}     clipboard =     hltext := selectnextchar()     if hltext = `r`n     {         ; return current position         send, {left}         return     }      ; move cursor until gets top of text block      ; first length future comparisons     send, {end}     send, {shift down}{home}{home}{shift up}     clipboard =     send, ^c     sleepaftercopy()     stringlen, slctsize, clipboard      ; begin checking lengths see if there still 'movement'     loop     {         send, {shift down}{left}{home}{home}{shift up}         clipboard =         send, ^c         sleepaftercopy()          ; if new length same we've hit top , can break out         stringlen, temp, clipboard         ifequal, slctsize, %temp%         {             send, {left}             break         }          ; if have hit blank space can stop here         firstchar := substr(clipboard, 1, 1)         if firstchar = `r         {             send, {left}{down}             break         }            ; if neither 1 of these conditions met, continue on         slctsize = %temp%     }      ; select down until blank space or end of file      send, {shift down}{end}{shift up}     clipboard =     send, ^c     sleepaftercopy()     stringlen, slctsize, clipboard      loop     {         send, {shift down}{right}{end}{shift up}         clipboard =         send, ^c         sleepaftercopy()          stringlen, temp, clipboard         ifequal, slctsize, %temp%         {             break         }          ; if have hit blank space can stop here         lastchar := substr(clipboard, 0)         if lastchar = `n         {             break         }          ; if neither 1 of these conditions met, continue on         slctsize = %temp%     }      ; execute!     send, {f5}     ; place cursor @ end of last line     send, {right}      ; restore clipboard     clipboard = %before% return  +f5::     send, {f5} return   selectnextchar() {     send, {lshift down}{right}{lshift up}     send, ^c     sleepaftercopy()     return %clipboard% }  sleepaftercopy() {     clipwait     ; sleep, 30 } 

the reason ends prematurely due copy-command not having enough time update clipboard before go work on it.

the best way handle clear clipboard before copying anything, , relying on clipwait tell when has been copied. alternatively let time-out tell nothing has been copied.

clipwait allows detect top , bottom of document without checking duplicates, we'll waiting time-out.

below working example fast make it.

note however: script works programs copy-command behaves normally. meaning if copy without selection, nothing gets copied. while trying discovered programs don't have behavior, , such script won't work programs. in cases have resort checking duplicates way or another.

sendmode, input setbatchlines, -1  esc::exitapp  $f5::     ; check if line we're @ line break     if (islinebreak( getfirstchar() ))         return      ; top of document     traversetext("up")     ; bottom     linecount := traversetext("down")     ; select     selectalllines(linecount) return  ; --- functions below ---  selectalllines(linecount) {     send, {lshift down}     loop, % linecount {         send, {up}     }     send, {home}     send, {lshift up} }   traversetext(direction) {     loop {         selectline(direction)         thisline := copytext()          ; if it's line break, we're out         if (islinebreak(thisline)) {              ; if going want move down once first             if (direction = "up")                 send, {down}              break         }          ; if nothing copied, we're out         if (!thisline)             break          := a_index ; keep track of how many lines we've moved passed     }      ; if had line break beneath     ; need add 1 counter     if (thisline)         i++      return ; return amount of lines traversed }  islinebreak(value) {     return value = "`r`n" }  getfirstchar() {     send, {home}+{down} ; home, shift + down     char := copytext()     send, {left}     return char }  selectline(direction) {     send, % direction = "up" ? "{home}" : "{end}" ; ternary operator      send, {lshift down}     send, % direction = "up" ? "{up}" : "{down}" ; ternary operator      send, {lshift up} }  copytext() {     clipboard := ""     send, ^c     clipwait, 0.2 ; time-out after 200ms     return clipboard } 

Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -