@@ -514,7 +514,7 @@ def _handled_by_polars_sql(self, obj):
514514
515515 def insert_completion (self , completion ):
516516 cursor = self .textCursor ()
517- cursor .select (cursor .WordUnderCursor )
517+ cursor .select (QTextCursor .WordUnderCursor )
518518 cursor .removeSelectedText ()
519519 cursor .insertText (completion )
520520 self .setTextCursor (cursor )
@@ -537,7 +537,7 @@ def keyPressEvent(self, event):
537537 return
538538 if event .key () == Qt .Key .Key_Tab :
539539 cursor = self .textCursor ()
540- cursor .select (cursor .WordUnderCursor )
540+ cursor .select (QTextCursor .WordUnderCursor )
541541 prefix = cursor .selectedText ()
542542 self .completer .setCompletionPrefix (prefix .upper ())
543543 if self .completer .completionCount () == 1 :
@@ -547,7 +547,7 @@ def keyPressEvent(self, event):
547547 else :
548548 # create a new cursor and move it to the start of the word
549549 word_start_cursor = self .textCursor ()
550- word_start_cursor .movePosition (word_start_cursor .StartOfWord )
550+ word_start_cursor .movePosition (QTextCursor .StartOfWord )
551551 rect = self .cursorRect (word_start_cursor )
552552 popup_scrollbar = completer_popup .verticalScrollBar ()
553553 popup_scrollbar_width = popup_scrollbar .sizeHint ().width () + 10
@@ -561,21 +561,45 @@ def keyPressEvent(self, event):
561561 if query_text :
562562 self .append_to_history (query_text )
563563 self .execute_sql (query_text )
564- elif event .key () == Qt .Key .Key_Up and self .history :
565- if self .history_index > 0 :
566- self .history_index -= 1
567- self .setPlainText (self .history [self .history_index ])
568- self .moveCursor (QTextCursor .End )
569- elif event .key () == Qt .Key .Key_Down and self .history :
570- if self .history_index < len (self .history ) - 1 :
571- self .history_index += 1
564+ return
565+
566+ cursor = self .textCursor ()
567+ block_number = cursor .blockNumber ()
568+ total_blocks = self .document ().blockCount ()
569+
570+ if event .key () == Qt .Key .Key_Up :
571+ if block_number == 0 : # Cursor is on the first line
572+ if self .search_and_recall_history (direction = - 1 ):
573+ return
574+ elif event .key () == Qt .Key .Key_Down :
575+ if block_number == total_blocks - 1 : # Cursor is on the last line
576+ if self .history_index < len (self .history ) - 1 :
577+ if self .search_and_recall_history (direction = 1 ):
578+ return
579+ else :
580+ self .history_index = len (self .history )
581+ self .clear ()
582+ return
583+ super ().keyPressEvent (event )
584+
585+ def search_and_recall_history (self , direction : int ):
586+ if not self .history :
587+ return False
588+ cursor = self .textCursor ()
589+ query_text = self .toPlainText ()
590+ cursor_pos = cursor .position ()
591+ prefix = query_text [:cursor_pos ]
592+ index = self .history_index + direction
593+ while 0 <= index <= len (self .history ) - 1 :
594+ if self .history [index ].startswith (prefix ):
595+ self .history_index = index
572596 self .setPlainText (self .history [self .history_index ])
573- self . moveCursor ( QTextCursor . End )
574- else :
575- self . history_index = len ( self . history )
576- self . clear ()
577- else :
578- super (). keyPressEvent ( event )
597+ cursor . setPosition ( cursor_pos )
598+ self . setTextCursor ( cursor )
599+ return True
600+ index += direction
601+ # no matching prefix found, do not change history_index
602+ return False
579603
580604 def append_to_history (self , sql_text ):
581605 history = self .history
0 commit comments