[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Using TeminalScreen.class to move cursor


On Sat, 6 Apr 2024 at 20:11, Brian G <brian@xxxxxxxxxxxxxxxx> wrote:

> Why would you not just use the absolute position escape sequence after
> calculating the needed position from your text buffer?
>
> '\e[vpos;hposH'
>
> or move n pos left or right
>
> '\e[nspacesD'  '\e24D' or '\e[nspacesC' '\e2C'
>
> Maybe I don't understand, But it seems correct to not be moving the cursor
> around bit by bit, but just put it where you want.
>
> Select Case iCode
>       Case Key.Up
>         sText = If(.AppCursorKey, "\eOA", subst("\e[&1A",len))
>       Case Key.Down
>         sText = If(.AppCursorKey, "\eOB", subst("\e[&1B",len))
>       Case Key.Right
>         sText = If(.AppCursorKey, "\eOC", subst("\e[&1C",len))
>       Case Key.Left
>         sText = If(.AppCursorKey, "\eOD", subst("\e[&1D",len))
>     End Select
>
> 'sText = String(Len, sText)
>
That did not work :(   it just printed D when i hit Ctrl+Left (the code was
correct '\e[15D' )
i think terminalview is handling it differently (i'm having to hack the
private api to make it work).

the commands seem to work if i use the recommended TerminalView.Print()
command but then i cannot move cursor right like before as it does not
update the cursor position so it thinks i'm still where i was before the
move.

The code I have that sends an amount of right or left escape sequences is
currently the only thing i've got working correctly.

Respects
BruceS

On 4/5/24 17:52, Bruce Steers wrote:
>
> Finally got something working...
> This CtrlMove function is called with Key.Code as argument if Ctrl key +
> Arrow key is hit.
> Left and right moves to previous/next white space
> Up and Down moves cursor up or down lines.
>
> The CtrlMove function is dirty and my code probably sucks but at least the
> MoveCursor function now works, the terminalview updates it's cursor
> position okay this way.
>
> Please feel free to suggest/implement a better method :)
>
>
> Public Sub MoveCursor(iCode As Integer, Optional Len As Integer = 1)
>
>   Dim sText As String
>
>   Select Case iCode
>     Case Key.Up
>       sText = String(TerminalView1.ScreenWidth, "\e[D")
>     Case Key.Down
>       sText = String(TerminalView1.ScreenWidth, "\e[C")
>     Case Key.Right
>       sText = "\e[C"
>     Case Key.Left
>       sText = "\e[D"
>   End Select
>
>   sText = String(Len, sText)
>
>   Dim hProcess As Stream = TerminalView1.GetOutputStream()
>   If TerminalView1._OutputTimer().Enabled Then
> TerminalView1._OutputTimer().Trigger
>
>   Wait
>
>   If hProcess Then
>     Print #hProcess, sText;
>   Endif
>
>   TerminalView1.ResetStart()
>
> End
>
>
> Public Sub CtrlMove(KeyCode As Integer)
>
>   If KeyCode = Key.Up Or If KeyCode = Key.Down Then
>     MoveCursor(KeyCode)
>     Return
>   Endif
>
>   Dim iDist As Integer
>   Dim iFind As Integer
>   Dim sLine As String = GetCommand()  ' get current command line string
>   Dim iAbove As Integer = TerminalView1.Count - 1 - TerminalView1.Line  '
> how many lines above the EOL is the cursor
>
>   ' get command line text position relevant to cursor pos
>   Dim iPos As Integer = TerminalView1.Column - Me.PromtLen + ((sLine.Len \
> TerminalView1.ScreenWidth) * TerminalView1.ScreenWidth)
>   iPos -= (iAbove * TerminalView1.ScreenWidth)
>   iPos = Max(0, Min(sLine.Len, iPos))
>
>   If KeyCode = Key.Left Then
>     iFind = RInStr(sLine, " ", Max(1, iPos - 1))
>     If iPos > 0 And If iFind > 0 Then
>       iDist = iPos - iFind + 1
>     Else
>       iDist = iPos
>     Endif
>   Else
>     iFind = InStr(sLine, " ", iPos + 2)
>     If iFind > 0 Then
>       iDist = iFind - iPos - 1
>     Else
>       iDist = Max(0, sLine.Len - iPos)
>     Endif
>   Endif
>
>   MoveCursor(KeyCode, iDist)
>
> End
>
> Pretty odd that the terminalview cannot realize position change when just
> using TerminalView.Print() though.
> Also this way if the cursor is on Column 0 moving left will go up to the
> end of the previous line (just like pressing left key),
> when using TerminalView.Print() the left escape would only go left and not
> go up to previous line.
> Respects
> BruceS
>
>
> On Sat, 30 Mar 2024 at 23:26, Bruce Steers <bsteers4@xxxxxxxxx> wrote:
>
>>
>>
>> On Sat, 30 Mar 2024 at 09:31, Benoît Minisini <
>> benoit.minisini@xxxxxxxxxxxxxxxx> wrote:
>>
>>> Le 30/03/2024 à 02:40, Bruce Steers a écrit :
>>> > If i move the cursor by using TerminalScreen what am i missing to
>>> update
>>> > the view?
>>> >
>>> > For example this code...
>>> >
>>> > Public Sub btnMoveLeft_Click()
>>> >
>>> >    TerminalView1._GetCurrentScreen().CursorLeft()
>>> >
>>> > End
>>> >
>>> > That moves the cursor left , if the cursor was initially at eol then
>>> if
>>> > i use the keyboard to go right the terminal thinks i am at eol still
>>> and
>>> > blinks and does not move.
>>> >
>>> > So either i need a way to move the cursor that updates the terminal
>>> > properly/correctly
>>> > or i need to update it manually after the position move.
>>> >
>>> > Can't figure out what i'm missing in how the terminalview works.
>>> >
>>> > (yes i know i'm tinkering with a hidden function of the internal API ,
>>> > but i couldn't find any other way, so how must I do it properly?)
>>> >
>>> > Cheers for any info/solutions
>>> > BruceS
>>> >
>>>
>>> You must use the 'TerminalView.Print()' method and send VT-100 escape
>>> codes if you want to move the cursor.
>>>
>>> Regards,
>>>
>>> --
>>> Benoît Minisini.
>>>
>>
>> That was the first method i tried. (i studied VT100 class InputTo to get
>> the escape chars I used)
>> But I get the same result. using TerminalView1.Print("\e[D")
>>
>> This is my code...
>> It is used to move the cursor and stop at a space if I'm holding Ctrl key
>> when hitting an arrow key.
>> the cursor goes left just fine but then i cannot move it right unless i
>> use Ctrl key again and Key.Right to run my code
>> If i press right key with no Ctrl then it flashes like i'm still at end
>> of line.
>>
>> I need to tell the terminalview of the position change (i just can't
>> figure out the workaround)
>> Or a better way to trigger a left/right move
>>
>> Respects
>> BruceS
>>
>> Public Sub TerminalView1_KeyPress()
>>
>>   If Key.Control Then
>>     If Key.Code = Key.Left Then
>>       GotoSpace(True)
>>     Else If Key.Code = Key.Right Then
>>       GotoSpace
>>     Endif
>>   Endif
>>
>> End
>>
>> Public Sub IsWordChar(C As String) As Boolean
>>
>>   If Len(C) = 1 Then
>>     If IsLetter(C) Or If IsDigit(C) Then Return True
>>     If InStr(":./_", C) Then Return True  ' don't stop at these chars
>>   Else
>>     Return
>>   Endif
>>
>> End
>>
>> Public Sub MoveCursor(iCode As Integer, Optional Len As Integer = 1)
>>
>>   Dim sText As String
>>
>>   With TerminalView1._GetCurrentScreen()
>>
>>     Select Case iCode
>>       Case Key.Up
>>         sText = If(.AppCursorKey, "\eOA", "\e[A")
>>       Case Key.Down
>>         sText = If(.AppCursorKey, "\eOB", "\e[B")
>>       Case Key.Right
>>         sText = If(.AppCursorKey, "\eOC", "\e[C")
>>       Case Key.Left
>>         sText = If(.AppCursorKey, "\eOD", "\e[D")
>>     End Select
>>   End With
>>
>>   sText = String(Len, sText)
>>   If sText Then TerminalView1.Print(sText)
>>
>> End
>>
>> Public Sub GotoSpace(Optional GoLeft As Boolean)
>>
>>   Dim iPrompt As Integer = FindPromptLine()
>>   Dim sChar As String
>>   Dim bWordChar As Boolean
>>   Dim bStartIsWordChar As Boolean = IsWordChar(TerminalView1.CharAt())
>>
>>   Do
>>     If GoLeft Then
>>       If TerminalView1.Line = iPrompt And If TerminalView1.Column =
>> Me.PromtLen Then Return
>>       If TerminalView1.Column = 0 Then
>>         MoveCursor(Key.Up)
>>         MoveCursor(Key.Right, TerminalView1.ScreenWidth)
>>       Endif
>>       MoveCursor(Key.Left)
>>     Else
>>       If TerminalView1.Line = TerminalView1.Count - 1 And If
>> TerminalView1.Column = TerminalView1.GetLineLength() Then Return
>>       If TerminalView1.Column = TerminalView1.ScreenWidth - 1 Then
>>         MoveCursor(Key.Left, TerminalView1.ScreenWidth)
>>         MoveCursor(Key.Down)
>>       Endif
>>       MoveCursor(Key.Right)
>>     Endif
>>
>>     sChar =
>> TerminalView1._GetCurrentScreen().Lines[TerminalView1.Line].Text[TerminalView1.Column]
>>     bWordChar = IsWordChar(sChar)
>>
>>     If Not bStartIsWordChar And If bWordChar Then
>>       bStartIsWordChar = True
>>       Continue
>>     Else If bStartIsWordChar And If Not bWordChar Then
>>       Break
>>     Endif
>>
>>     If TerminalView1.Line < iPrompt Then Break
>>     If TerminalView1.Line = iPrompt And If TerminalView1.Column =
>> Me.PromtLen Then Break
>>     If TerminalView1.Line >= TerminalView1.Count - 1 And If
>> TerminalView1.Column >= TerminalView1.GetLineLength() - 1 Then Break
>>   Loop
>>
>>   TerminalView1.Refresh
>>
>> End
>>
> --
> ~~~~ Brian
>
>

Follow-Ups:
Re: Using TeminalScreen.class to move cursorBruce Steers <bsteers4@xxxxxxxxx>
References:
Re: Using TeminalScreen.class to move cursorBruce Steers <bsteers4@xxxxxxxxx>
Re: Using TeminalScreen.class to move cursorBrian G <brian@xxxxxxxxxxxxxxxx>