feat: add setting for line wrapping

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-04-05 19:23:10 +02:00
parent 4790c7cd1b
commit e368203e16
8 changed files with 74 additions and 4 deletions

View file

@ -612,6 +612,10 @@
"syncScroll": {
"label": "Sync Scrolling",
"help": "Synchronizes the scroll state of editor and rendering view."
},
"lineWrapping": {
"label": "Line Wrapping",
"help": "Breaks long lines so they're visible without scrolling."
}
},
"global": {

View file

@ -13,6 +13,7 @@ import type { ScrollProps } from '../synced-scroll/scroll-props'
import styles from './extended-codemirror/codemirror.module.scss'
import { useCodeMirrorAutocompletionsExtension } from './hooks/codemirror-extensions/use-code-mirror-autocompletions-extension'
import { useCodeMirrorFileInsertExtension } from './hooks/codemirror-extensions/use-code-mirror-file-insert-extension'
import { useCodeMirrorLineWrappingExtension } from './hooks/codemirror-extensions/use-code-mirror-line-wrapping-extension'
import { useCodeMirrorRemoteCursorsExtension } from './hooks/codemirror-extensions/use-code-mirror-remote-cursor-extensions'
import { useCodeMirrorScrollWatchExtension } from './hooks/codemirror-extensions/use-code-mirror-scroll-watch-extension'
import { useCodeMirrorSpellCheckExtension } from './hooks/codemirror-extensions/use-code-mirror-spell-check-extension'
@ -39,7 +40,6 @@ import { markdown, markdownLanguage } from '@codemirror/lang-markdown'
import { languages } from '@codemirror/language-data'
import { lintGutter } from '@codemirror/lint'
import { oneDark } from '@codemirror/theme-one-dark'
import { EditorView } from '@codemirror/view'
import ReactCodeMirror from '@uiw/react-codemirror'
import React, { useEffect, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
@ -67,6 +67,7 @@ export const EditorPane: React.FC<EditorPaneProps> = ({ scrollState, onScroll, o
const tablePasteExtensions = useCodeMirrorTablePasteExtension()
const fileInsertExtension = useCodeMirrorFileInsertExtension()
const spellCheckExtension = useCodeMirrorSpellCheckExtension()
const lineWrappingExtension = useCodeMirrorLineWrappingExtension()
const cursorActivityExtension = useCursorActivityCallback()
const autoCompletionExtension = useCodeMirrorAutocompletionsExtension()
@ -95,7 +96,7 @@ export const EditorPane: React.FC<EditorPaneProps> = ({ scrollState, onScroll, o
codeLanguages: (input) => findLanguageByCodeBlockName(languages, input)
}),
remoteCursorsExtension,
EditorView.lineWrapping,
lineWrappingExtension,
editorScrollExtension,
tablePasteExtensions,
fileInsertExtension,
@ -115,7 +116,8 @@ export const EditorPane: React.FC<EditorPaneProps> = ({ scrollState, onScroll, o
cursorActivityExtension,
updateViewContextExtension,
yjsExtension,
spellCheckExtension
spellCheckExtension,
lineWrappingExtension
]
)

View file

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { useApplicationState } from '../../../../../hooks/common/use-application-state'
import type { Extension } from '@codemirror/state'
import { EditorView } from '@codemirror/view'
import { useMemo } from 'react'
/**
* Creates a {@link Extension codemirror extension} that activates or deactivates line wrapping.
*/
export const useCodeMirrorLineWrappingExtension = (): Extension => {
const lineWrapping = useApplicationState((state) => state.editorConfig.lineWrapping)
return useMemo(() => (lineWrapping ? EditorView.lineWrapping : []), [lineWrapping])
}

View file

@ -5,6 +5,7 @@
*/
import { SettingLine } from '../utils/setting-line'
import { LigatureSettingButtonGroup } from './ligature-setting-button-group'
import { LineWrappingSettingButtonGroup } from './line-wrapping-setting-button-group'
import { SmartPasteSettingButtonGroup } from './smart-paste-setting-button-group'
import { SyncScrollSettingButtonGroup } from './sync-scroll-setting-button-group'
import React from 'react'
@ -28,6 +29,9 @@ export const EditorSettingsTabContent: React.FC = () => {
<SettingLine i18nKey={'editor.syncScroll'}>
<SyncScrollSettingButtonGroup />
</SettingLine>
<SettingLine i18nKey={'editor.lineWrapping'}>
<LineWrappingSettingButtonGroup />
</SettingLine>
</ListGroup>
)
}

View file

@ -0,0 +1,17 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { useApplicationState } from '../../../../hooks/common/use-application-state'
import { setEditorLineWrapping } from '../../../../redux/editor/methods'
import { OnOffButtonGroup } from '../utils/on-off-button-group'
import React from 'react'
/**
* Allows to change if line wrapping should be used or not in the editor.
*/
export const LineWrappingSettingButtonGroup: React.FC = () => {
const enabled = useApplicationState((state) => state.editorConfig.lineWrapping)
return <OnOffButtonGroup value={enabled} onSelect={setEditorLineWrapping} />
}

View file

@ -8,6 +8,7 @@ import { Logger } from '../../utils/logger'
import type {
EditorConfig,
SetEditorLigaturesAction,
SetEditorLineWrappingAction,
SetEditorSmartPasteAction,
SetEditorSyncScrollAction
} from './types'
@ -44,6 +45,14 @@ export const setEditorSyncScroll = (syncScroll: boolean): void => {
store.dispatch(action)
}
export const setEditorLineWrapping = (lineWrapping: boolean): void => {
const action: SetEditorLineWrappingAction = {
type: EditorConfigActionType.SET_LINE_WRAPPING,
lineWrapping
}
store.dispatch(action)
}
export const setEditorLigatures = (ligatures: boolean): void => {
const action: SetEditorLigaturesAction = {
type: EditorConfigActionType.SET_LIGATURES,

View file

@ -12,7 +12,8 @@ const initialState: EditorConfig = {
ligatures: true,
syncScroll: true,
smartPaste: true,
spellCheck: false
spellCheck: false,
lineWrapping: true
}
const getInitialState = (): EditorConfig => {
@ -53,6 +54,13 @@ export const EditorConfigReducer: Reducer<EditorConfig, EditorConfigActions> = (
}
saveToLocalStorage(newState)
return newState
case EditorConfigActionType.SET_LINE_WRAPPING:
newState = {
...state,
lineWrapping: action.lineWrapping
}
saveToLocalStorage(newState)
return newState
default:
return state
}

View file

@ -9,6 +9,7 @@ export enum EditorConfigActionType {
SET_EDITOR_VIEW_MODE = 'editor/view-mode/set',
SET_SYNC_SCROLL = 'editor/syncScroll/set',
SET_LIGATURES = 'editor/preferences/setLigatures',
SET_LINE_WRAPPING = 'editor/preferences/setLineWrapping',
SET_SMART_PASTE = 'editor/preferences/setSmartPaste',
SET_SPELL_CHECK = 'editor/preferences/setSpellCheck'
}
@ -18,14 +19,21 @@ export interface EditorConfig {
ligatures: boolean
smartPaste: boolean
spellCheck: boolean
lineWrapping: boolean
}
export type EditorConfigActions =
| SetEditorSyncScrollAction
| SetEditorLigaturesAction
| SetEditorSmartPasteAction
| SetEditorLineWrappingAction
| SetSpellCheckAction
export interface SetEditorLineWrappingAction extends Action<EditorConfigActionType> {
type: EditorConfigActionType.SET_LINE_WRAPPING
lineWrapping: boolean
}
export interface SetEditorSyncScrollAction extends Action<EditorConfigActionType> {
type: EditorConfigActionType.SET_SYNC_SCROLL
syncScroll: boolean