Search code examples
haskellgtkgtk2hs

Replace selected text and have the new text be selected


I'm using Gtk2Hs, and all this GTK stuff is new to me. I'm working with a TextView. I want to replace the currently selected text with some new text, and have the new text be selected. The closest I've been able to come up with is:

-- Create marks so I can "remember" where the selection was
(startIter, stopIter) <- textBufferGetSelectionBounds buffer
startMark <- textBufferCreateMark buffer (Just "start") startIter True
stopMark <- textBufferCreateMark buffer (Just "stop") stopIter True

-- Delete the currently selected text
textBufferDeleteSelection buffer True True
-- now startIter and stopIter are no longer valid

-- Insert the new text
somehow convert startMark to startIter2 ???
textBufferInsert buffer startIter2 text
-- now startIter2 is no longer valid

-- Select the new text
somehow convert startMark to startIter3 ???
somehow convert stopMark to stopIter3 ???
textBufferSelectRange buffer startIter3 stopIter3

The only functions I've found to set the selection require TextIters, not TextMarks. But I haven't been able to find any functions to get a TextIter from a TextMark. Is this the right procedure?


Solution

  • OK, I found a way to do it using TextMarks. The function I was looking for was textBufferGetIterAtMark.

    textBufferReplaceSelection 
      ∷ TextBufferClass self ⇒ self → String → IO ()
    textBufferReplaceSelection buffer text = do
      -- Create marks so I can "remember" where the selection was
      (startIter, stopIter) <- textBufferGetSelectionBounds buffer
      startMark <- textBufferCreateMark buffer (Just "start") startIter False
      stopMark <- textBufferCreateMark buffer (Just "stop") stopIter True
    
      -- Delete the currently selected text
      textBufferDeleteSelection buffer True True
      -- now startIter and stopIter are no longer valid
    
      -- Insert the new text
      startIter2 <- textBufferGetIterAtMark buffer startMark
      textBufferInsert buffer startIter2 text
      -- now startIter2 is no longer valid
    
      -- Select the new text
      startIter3 <- textBufferGetIterAtMark buffer startMark
      stopIter3 <- textBufferGetIterAtMark buffer stopMark
      textBufferSelectRange buffer startIter3 stopIter3