1+ import * as React from "react" ;
2+ import { Command } from "../types" ;
3+ import { TextApi , TextState } from "../types/CommandOptions" ;
4+ import { getBreaksNeededForEmptyLineAfter , getBreaksNeededForEmptyLineBefore , selectWord } from "../util/MarkdownUtil" ;
5+
6+ export type AlterLineFunction = ( line : string , index : number ) => string ;
7+
8+ /**
9+ * Inserts insertionString before each line
10+ */
11+ export function insertBeforeEachLine ( selectedText : string , insert : string | AlterLineFunction ) :
12+ { modifiedText : string , insertionLength : number } {
13+ const lines = selectedText . split ( / \n / ) ;
14+
15+ let insertionLength = 0 ;
16+ const modifiedText = lines . map ( ( item , index ) => {
17+ if ( typeof insert === "string" ) {
18+ insertionLength += insert . length ;
19+ return insert + item ;
20+ } else if ( typeof insert === "function" ) {
21+ const insertionResult = insert ( item , index ) ;
22+ insertionLength += insertionResult . length ;
23+ return insert ( item , index ) + item ;
24+ }
25+ throw Error ( "insertion is expected to be either a string or a function" ) ;
26+ } ) . join ( "\n" ) ;
27+
28+ return { modifiedText, insertionLength}
29+ }
30+
31+ export const unorderedListCommand : Command = {
32+ name : "code" ,
33+ buttonContentBuilder : ( { iconProvider} ) => iconProvider ( "list-ul" ) ,
34+ buttonProps : { "aria-label" : "Add unordered list" } ,
35+ execute : ( state0 : TextState , api : TextApi ) => {
36+ // Adjust the selection to encompass the whole word if the caret is inside one
37+ const newSelectionRange = selectWord ( { text : state0 . text , selection : state0 . selection } ) ;
38+ const state1 = api . setSelectionRange ( newSelectionRange ) ;
39+
40+ const breaksBeforeCount = getBreaksNeededForEmptyLineBefore ( state1 . text , state1 . selection . start ) ;
41+ const breaksBefore = Array ( breaksBeforeCount + 1 ) . join ( "\n" ) ;
42+
43+ const breaksAfterCount = getBreaksNeededForEmptyLineAfter ( state1 . text , state1 . selection . end ) ;
44+ const breaksAfter = Array ( breaksAfterCount + 1 ) . join ( "\n" ) ;
45+
46+ const state2 = api . replaceSelection ( `${ breaksBefore } ${ state1 . selectedText } ${ breaksAfter } ` ) ;
47+
48+ // const modifiedText = insertBeforeEachLine(state2.selectedText, "- ");
49+ // const state3 = api.replaceSelection(modifiedText.modifiedText);
50+
51+ const modifiedText = { insertionLength : 0 } ;
52+ const state3 = state2 ;
53+
54+ const selectionRange = {
55+ start : state3 . selection . end - state1 . selectedText . length - breaksAfterCount ,
56+ end : state3 . selection . end - breaksAfterCount
57+ } ;
58+
59+ // Adjust the selection to not contain the **
60+ api . setSelectionRange ( selectionRange ) ;
61+ }
62+ ,
63+ keyCommand : "code" ,
64+ }
0 commit comments