MiniM Knowledge Base | Dec 12, 2013
How to get $Y and $X for telnet
MUMPS standard does not guaranteed that MUMPS system on the server side can correctrly recount each time real values of system variables $Y and $X, especially after writing one char given by code and after using mnemonics.
MUMPS language definition does not contain strong alhorithm for recalculating system variables $Y and $X (caret position) for telnet. And, anyway, position of caret after writing chars or mnemonics is dependent of telnet client.
On executing write commands with code of chars and mremonics
w *char w /MNEMONIC[(params)]client side can rights to change caret by algorithm, unknown on the server side. This behavior can be dependent of language settings, unicode usage, previous caret position, current line wrapping mode and many more.
To strongly say, server side cannot determine position of caret after any input-output in all cases, but can determine in some cases after direct positioning and determinated output.
In the case of application must determine caret position from current caret position, need to know this current caret position, values of $Y and $X.
The best way is to query caret position from currently used telnet client. Telnet protocol contains for this action special command as control escape sequence
ESC [ 6 n
In the case of telnet client supports this command (mostly used telnets supports this), client must send responce as special escape sequence with caret position in the following format
ESC [ YY ; XX R
For reading escape sequence from client side in MiniM need to read one char and if this char have code 27 (Escape), get valye of $key special variable. This variabe contains char sequence of read terminator.
Example of demo routine to get $Y and $X values from telnet clientusing special caret position query:
YX ; this only for TNT device q:$p($io,"|",2)'="TNT" "" n ch,ans ; send query to telnet client w *27,"[6n" ; get answer as an escape sequence r *ch s ans=$s(ch=27:$key,1:"") ; remove unneed symbols s ans=$tr(ans,$c(27)_"[R") ; return $Y + $X delimited by ; q ans Y ; return only $Y q $p($$YX,";",1) X ; return only $X q $p($$YX,";",2)
Here function $select checks that answer contains escape code.
Given code removes unneed characters from telnet responce with $translate function. In the case of telnet does not support telnet standard and have response in other format, may be used regular expressions to get numeric sequences from responce:
YXRE ; this only for TNT device q:$p($io,"|",2)'="TNT" "" n ch,ans ; send query to telnet client w *27,"[6n" ; get answer as an escape sequence r *ch s ans=$s(ch=27:$key,1:"") ; return all number sequences as $list structure q $zpcres(ans,"\d+","g") YRE ; return only $Y q $lg($$YXRE,1) XRE ; return only $X q $lg($$YXRE,2)
Also, if telnet client does not support this query and have no answer, need to use char reading with timeout.
Even if telnet client implements caret position query and correctly answers, this does not guarantees common correct working. Telnet client can paste multiline text from the clipboard and still stay in sending big sequence of symbols, and quering inside this sequence can be wasted, mixed with other ordinal input and readed char can be omitted from correct input.Eugene Karataev