CodeEditor icon indicating copy to clipboard operation
CodeEditor copied to clipboard

When a range replaced with a string, the cursor is not at the end of the newly replaced string.

Open kelalaka153 opened this issue 1 year ago • 3 comments

I'm using the below function to insert the text at the current selection ( current cursor position is enough for me, though)

func insertText(_ text: String, at range: Range<String.Index>, in string: String) -> String {
        var newString = string
        newString.replaceSubrange(range, with: text)
        return newString
    }

With the help of the selection binding, the text insertion is quite easy ( thanks for that), however, the cursor stays at the beginning of the inserted text ( the one that replaced the text of the range).

In the usual approach, on the other hand, the cursor must be placed at the end of newly inserted text ( when the range size is 0)

If I select a range more than the cursor position, this time, there is no cursor but only a selection that has the same size of the replaced text. I was expecting that the selection after the text inserts keep the size of the replaced part.

Ok, this may be the expected behavior since we may just be replacing the text that the editor's string with a new value.

Is there a way to achieve the text insertion so that the cursor moved to the end of the inserted string? This is necessary for me. Maybe there is a workaround for this one can move the cursor to the x position.


P.S. Overall, it is a great CodeEditor.

kelalaka153 avatar Apr 23 '23 19:04 kelalaka153

Ok, I've solved my issue.

func insertText(_ text: String, at range: Range<String.Index>, in string: String) -> String {
        
        let rangeSize = source.distance(from: range.lowerBound, to: range.upperBound)

        let diff = text.count - rangeSize

        var newString = string
        newString.replaceSubrange(range, with: text)

        var startIndex = newString.index(newString.startIndex, offsetBy: 0 )
        var endIndex = startIndex

        if rangeSize == 0 {
            startIndex = newString.index(range.lowerBound, offsetBy: diff )
            endIndex = newString.index(range.upperBound, offsetBy: diff)

        } else {
            startIndex = newString.index(range.lowerBound, offsetBy: 0 )
            if diff >= 0 {
                endIndex = newString.index(range.upperBound, offsetBy: diff)
            } else {
                endIndex = newString.index(range.lowerBound, offsetBy: text.count)
            }
        }
        selection = startIndex..<endIndex
       
        return newString

Hope this helps whoever needs.

kelalaka153 avatar Apr 25 '23 21:04 kelalaka153

Looks good, want to put this in a pull request?

helje5 avatar May 01 '23 15:05 helje5

As far as I remember, system's copy past works flawlessly on the editor ( tested now to make sure that). I needed this to insert/replace some text within my application.

I don't think that the CodeEditor need such internal functionality, or am I missing something?

kelalaka153 avatar May 02 '23 08:05 kelalaka153