# Changing the way line breaks are handled

**URL:** https://discuss.prosemirror.net/t/changing-the-way-line-breaks-are-handled/1682
**Category:** Uncategorized
**Created:** [December 7, 2018, 1:39pm UTC](https://discuss.prosemirror.net/t/changing-the-way-line-breaks-are-handled/1682 "2018-12-07T13:39:44Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![truefusion](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/t/a5b964/32.png) [@truefusion](https://discuss.prosemirror.net/u/truefusion)
#### Post date: [December 7, 2018, 1:39pm UTC](https://discuss.prosemirror.net/t/changing-the-way-line-breaks-are-handled/1682/1 "2018-12-07T13:39:44Z")

</div>

Is there a way I can set every single new line to use `<br>` tags and every double new lines to use `<p>` tags as the default behavior for treating new lines?

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [December 7, 2018, 1:54pm UTC](https://discuss.prosemirror.net/t/changing-the-way-line-breaks-are-handled/1682/2 "2018-12-07T13:54:09Z")

</div>

You could bind enter to a command that inserts a hard break, except when directly after a hard break, in which case it remove the hard break and splits textblocks instead.

---

<div class="post-metadata">

### Author: ![carlrannaberg](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/carlrannaberg/32/1681_2.png) [@carlrannaberg](https://discuss.prosemirror.net/u/carlrannaberg)
#### Post date: [August 21, 2020, 2:04pm UTC](https://discuss.prosemirror.net/t/changing-the-way-line-breaks-are-handled/1682/3 "2020-08-21T14:04:19Z")

</div>

@marijn That’s exactly what I would like to accomplish. How would you go about removing a hard break through Prosemirror transaction?

This is what I have tried in the keymap command with no success:

```auto
if ($from.nodeBefore && $from.nodeBefore.type === hardBreak) {
	dispatch(state.tr.delete($from.pos, $from.pos + $from.nodeBefore.nodeSize));

	return false;
}

```

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [August 22, 2020, 3:39pm UTC](https://discuss.prosemirror.net/t/changing-the-way-line-breaks-are-handled/1682/4 "2020-08-22T15:39:16Z")

</div>

A command that has an effect and then returns `false` seems dodgy—if you handle a key, you should probably return true.

The `delete` call deletes from the cursor to the size of the node before the cursor _after_ the cursor. Something like `delete($from.pos - $from.nodeBefore.nodeSize, $from.pos)` seems more reasonable. Also, leave nodes like hard breaks always have node size 1, so you could simplify that.

---

<div class="post-metadata">

### Author: ![carlrannaberg](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/carlrannaberg/32/1681_2.png) [@carlrannaberg](https://discuss.prosemirror.net/u/carlrannaberg)
#### Post date: [August 23, 2020, 9:52am UTC](https://discuss.prosemirror.net/t/changing-the-way-line-breaks-are-handled/1682/5 "2020-08-23T09:52:44Z")

</div>

Thanks @marijn! Your pointers helped to solve the issue. I got it working exactly the way OP intended.

Some important points to keep in mind:

1. Every command that is chained to a key should have only one transaction dispatched
2. After dispatching a transaction the command should return `true`
3. In order to make several changes with one transaction you need to chain the calls (`insert`, `replaceWith`, `delete` etc)
4. `delete` call deletes from the cursor to the size of the node before the cursor _after_ the cursor

Here’s my simplified, but working code:

```javascript
/**
 * Helper function to remove hard break and insert paragraph instead.
 * @param {Object} params
 * @param {import('prosemirror-model').NodeType} params.hardBreak
 * @param {import('prosemirror-model').NodeType} params.paragraph
 */
function removeHardBreakAndInsertParagraph({ hardBreak, paragraph }) {
	/**
	 * @param {import('prosemirror-state').EditorState} state ProseMirror editor state.
	 * @param {Function} dispatch Editor's dispatch function.
	 */
	return (state, dispatch) => {
		const { $from } = state.selection;

		if (!$from.parent.isBlock) {
			return false;
		}

		if ($from.parent.type !== paragraph) {
			return false;
		}

		if ($from.nodeBefore && $from.nodeBefore.type !== hardBreak) {
			return false;
		}

		if (dispatch) {
			dispatch(
				state.tr
					.delete($from.pos - $from.nodeBefore.nodeSize, $from.pos)
					.replaceSelectionWith(paragraph.create())
					.scrollIntoView()
			);
		}

		return true;
	};
}

/**
 * Helper function to insert hard break.
 * @param {Object} params
 * @param {import('prosemirror-model').NodeType} params.hardBreak
 * @param {import('prosemirror-model').NodeType} params.paragraph
 */
function insertHardBreak({ hardBreak, paragraph }) {
	/**
	 * @param {import('prosemirror-state').EditorState} state ProseMirror editor state.
	 * @param {Function} dispatch Editor's dispatch function.
	 */
	return (state, dispatch) => {
		const { $from } = state.selection;

		if (!$from.parent.isBlock) {
			return false;
		}

		if ($from.parent.type !== paragraph) {
			return false;
		}

		if (dispatch) {
			dispatch(state.tr.replaceSelectionWith(hardBreak.create()).scrollIntoView());
		}

		return true;
	};
}

/**
 * Build keymap that binds keyboard combinations to editor actions.
 * @param {import('prosemirror-model').Schema} schema Prosemirror schema.
 * @return {Object}
 */
export function buildKeymap(schema) {
	const keys = {};
	const { hardBreak, paragraph } = schema.nodes;

	keys.Enter = chainCommands(
		removeHardBreakAndInsertParagraph({ hardBreak, paragraph })
		insertHardBreak({ hardBreak, paragraph })
	);

	return keys;
}

```

---

<div class="post-metadata">

### Author: ![ProseMobile](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/p/71e660/32.png) [@ProseMobile](https://discuss.prosemirror.net/u/ProseMobile)
#### Post date: [August 28, 2021, 6:52am UTC](https://discuss.prosemirror.net/t/changing-the-way-line-breaks-are-handled/1682/6 "2021-08-28T06:52:13Z")

</div>

There is some control for this on laptop browsers, but that same control does not work on mobile browsers:

Shift-CR seems to insert \< br \> instead of closing the \< p \> on **laptop** chrome browser.

But shift-CR on chrome **mobile** (and firefox mobile) does not insert the \< br \> and acts just like CR.

Control-CR on laptop also inserts \< br \>
