ImGuiColorTextEdit icon indicating copy to clipboard operation
ImGuiColorTextEdit copied to clipboard

Incorrect cursor position after backspacing a Tab?

Open floooh opened this issue 6 years ago • 2 comments

Hi, I just started using ImGuiColorTextEdit and I'm seeing a weird behaviour when backspacing a Tab, however since it's such an obvious thing I'm not sure if the problem is on my side ;)

Basically, given a line like this:

--------Hello World.

...where the '--------' is a single Tab character (with tab width 8), when the cursor is positioned at the H, and Backspace is pressed (so that the Tab is deleted), the cursor will be positioned at column 7, and not be at the start of the line:

Nov-10-2019 14-20-17

The problem seems to be here, where the cursor position is always decremented by one:

https://github.com/BalazsJako/ImGuiColorTextEdit/blob/0a88824f7de8d0bd11d8419066caa7d3469395c4/TextEditor.cpp#L1875

I fix this here like this, checking if the removed character is a Tab, and if yes, decrement by the tabsize. Note the isTab and the extra if block where the column is decremented:

		else
		{
			auto& line = mLines[mState.mCursorPosition.mLine];
			auto cindex = GetCharacterIndex(pos) - 1;
			auto cend = cindex + 1;
			bool isTab = line[cindex].mChar == '\t';
			while (cindex > 0 && IsUTFSequence(line[cindex].mChar)) {
				--cindex;
			}

			//if (cindex > 0 && UTF8CharLength(line[cindex].mChar) > 1)
			//	--cindex;

			u.mRemovedStart = u.mRemovedEnd = GetActualCursorCoordinates();
			--u.mRemovedStart.mColumn;
			if (isTab && mState.mCursorPosition.mColumn >= mTabSize) {
				mState.mCursorPosition.mColumn -= mTabSize;
			}
			else {
				--mState.mCursorPosition.mColumn;
			}

			while (cindex < line.size() && cend-- > cindex)
			{
				u.mRemoved += line[cindex].mChar;
				line.erase(line.begin() + cindex);
			}
		}

...it seems to work, but being new to the code base I'm not sure if I overlooked something.

Do you want me to provide a PR for this?

Cheers!

floooh avatar Nov 10 '19 13:11 floooh

...and of course my crude fix doesn't work when the Tab in question isn't of width mTabSize because there's text "leaking" into the tab :D

I'll come up with a better solution (is there an existing function to convert a character index in a line into a cursor column, taking tabs into account?).

floooh avatar Nov 10 '19 13:11 floooh

...ok I came up with an easier fix, just replace the general decrement code with (no need to handle the Tab character specially in this case):

mState.mCursorPosition.mColumn = GetCharacterColumn(mState.mCursorPosition.mLine, cindex);

I'm not sure what to do with the code that's right above:

u.mRemovedStart = u.mRemovedEnd = GetActualCursorCoordinates();
--u.mRemovedStart.mColumn;

Is this used for Undo?

floooh avatar Nov 10 '19 13:11 floooh