+21
-7
src/view/com/composer/text-input/TextInput.web.tsx
+21
-7
src/view/com/composer/text-input/TextInput.web.tsx
···
211
211
const isNotSelection = view.state.selection.empty
212
212
if (isNotSelection) {
213
213
const cursorPosition = view.state.selection.$anchor.pos
214
-
const textBefore = view.state.doc.textBetween(0, cursorPosition)
214
+
const textBefore = view.state.doc.textBetween(
215
+
0,
216
+
cursorPosition,
217
+
// important - use \n as a block separator, otherwise
218
+
// all the lines get mushed together -sfn
219
+
'\n',
220
+
)
215
221
const graphemes = new Graphemer().splitGraphemes(textBefore)
216
222
217
223
if (graphemes.length > 0) {
218
224
const lastGrapheme = graphemes[graphemes.length - 1]
219
-
const deleteFrom = cursorPosition - lastGrapheme.length
220
-
editor?.commands.deleteRange({
221
-
from: deleteFrom,
222
-
to: cursorPosition,
223
-
})
224
-
return true
225
+
// deleteRange doesn't work on newlines, because tiptap
226
+
// treats them as separate 'blocks' and we're using \n
227
+
// as a stand-in. bail out if the last grapheme is a newline
228
+
// to let the default behavior handle it -sfn
229
+
if (lastGrapheme !== '\n') {
230
+
// otherwise, delete the last grapheme using deleteRange,
231
+
// so that emojis are deleted as a whole
232
+
const deleteFrom = cursorPosition - lastGrapheme.length
233
+
editor?.commands.deleteRange({
234
+
from: deleteFrom,
235
+
to: cursorPosition,
236
+
})
237
+
return true
238
+
}
225
239
}
226
240
}
227
241
}