//go:build unix

package core

import (
	
	
	
	
	
)

// GetCursorPos returns the current cursor position in the terminal.
// It is safe to call this function even if the shell is reading input.
func ( *Keys) () (,  int) {
	 := func() (int, int) {
		os.Stderr.WriteString("\r\ngetCursorPos() not supported by terminal emulator, disabling....\r\n")
		return -1, -1
	}

	var  []byte
	var  [][]string

	// Echo the query and wait for the main key
	// reading routine to send us the response back.
	fmt.Print("\x1b[6n")

	// In order not to get stuck with an input that might be user-one
	// (like when the user typed before the shell is fully started, and yet not having
	// queried cursor yet), we keep reading from stdin until we find the cursor response.
	// Everything else is passed back as user input.
	for {
		switch {
		case .waiting, .reading:
			 = <-.cursor
		default:
			 := make([]byte, keyScanBufSize)

			,  := os.Stdin.Read()
			if  != nil {
				return ()
			}

			 = [:]
		}

		// We have read (or have been passed) something.
		if len() == 0 {
			return ()
		}

		// Attempt to locate cursor response in it.
		 = rxRcvCursorPos.FindAllStringSubmatch(string(), 1)

		// If there is something but not cursor answer, its user input.
		if len() == 0 && len() > 0 {
			.mutex.RLock()
			.buf = append(.buf, ...)
			.mutex.RUnlock()

			continue
		}

		// And if empty, then we should abort.
		if len() == 0 {
			return ()
		}

		break
	}

	// We know that we have a cursor answer, process it.
	,  := strconv.Atoi([0][1])
	if  != nil {
		return ()
	}

	,  = strconv.Atoi([0][2])
	if  != nil {
		return ()
	}

	return , 
}

func ( *Keys) () ( []byte,  error) {
	// Start reading from os.Stdin in the background.
	// We will either read keys from user, or an EOF
	// send by ourselves, because we pause reading.
	 := make([]byte, keyScanBufSize)

	,  := Stdin.Read()
	if  != nil && errors.Is(, io.EOF) {
		return
	}

	// Always attempt to extract cursor position info.
	// If found, strip it and keep the remaining keys.
	,  := .extractCursorPos([:])

	if len() > 0 {
		.cursor <- 
	}

	return , nil
}