@@ -8,53 +8,77 @@ export type AlterLineFunction = (line: string, index: number) => string;
88/**
99 * Inserts insertionString before each line
1010 */
11- export function insertBeforeEachLine ( selectedText : string , insert : string | AlterLineFunction ) :
11+ export function insertBeforeEachLine ( selectedText : string , insertBefore : string | AlterLineFunction ) :
1212 { modifiedText : string , insertionLength : number } {
1313 const lines = selectedText . split ( / \n / ) ;
1414
1515 let insertionLength = 0 ;
1616 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 ) ;
17+ if ( typeof insertBefore === "string" ) {
18+ insertionLength += insertBefore . length ;
19+ return insertBefore + item ;
20+ } else if ( typeof insertBefore === "function" ) {
21+ const insertionResult = insertBefore ( item , index ) ;
2222 insertionLength += insertionResult . length ;
23- return insert ( item , index ) + item ;
23+ return insertBefore ( item , index ) + item ;
2424 }
2525 throw Error ( "insertion is expected to be either a string or a function" ) ;
2626 } ) . join ( "\n" ) ;
2727
2828 return { modifiedText, insertionLength}
2929}
3030
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 ) ;
31+ export const makeList = ( state0 : TextState , api : TextApi , insertBefore : string | AlterLineFunction ) => {
32+ // Adjust the selection to encompass the whole word if the caret is inside one
33+ const newSelectionRange = selectWord ( { text : state0 . text , selection : state0 . selection } ) ;
34+ const state1 = api . setSelectionRange ( newSelectionRange ) ;
3935
40- const breaksBeforeCount = getBreaksNeededForEmptyLineBefore ( state1 . text , state1 . selection . start ) ;
41- const breaksBefore = Array ( breaksBeforeCount + 1 ) . join ( "\n" ) ;
36+ const breaksBeforeCount = getBreaksNeededForEmptyLineBefore ( state1 . text , state1 . selection . start ) ;
37+ const breaksBefore = Array ( breaksBeforeCount + 1 ) . join ( "\n" ) ;
4238
43- const breaksAfterCount = getBreaksNeededForEmptyLineAfter ( state1 . text , state1 . selection . end ) ;
44- const breaksAfter = Array ( breaksAfterCount + 1 ) . join ( "\n" ) ;
39+ const breaksAfterCount = getBreaksNeededForEmptyLineAfter ( state1 . text , state1 . selection . end ) ;
40+ const breaksAfter = Array ( breaksAfterCount + 1 ) . join ( "\n" ) ;
4541
46- const modifiedText = insertBeforeEachLine ( state1 . selectedText , "- " ) ;
42+ const modifiedText = insertBeforeEachLine ( state1 . selectedText , insertBefore ) ;
4743
48- api . replaceSelection ( `${ breaksBefore } ${ modifiedText . modifiedText } ${ breaksAfter } ` ) ;
44+ api . replaceSelection ( `${ breaksBefore } ${ modifiedText . modifiedText } ${ breaksAfter } ` ) ;
4945
50- const selectionStart = state1 . selection . start + breaksBeforeCount ;
51- const selectionEnd = selectionStart + modifiedText . modifiedText . length ;
46+ // Specifically when the text has only one line, we can exclude the "- ", for example, from the selection
47+ const oneLinerOffset = state1 . selectedText . indexOf ( "\n" ) === - 1 ? modifiedText . insertionLength : 0 ;
5248
53- // Adjust the selection to not contain the **
54- api . setSelectionRange ( {
55- start : selectionStart ,
56- end : selectionEnd
57- } ) ;
49+ const selectionStart = state1 . selection . start + breaksBeforeCount + oneLinerOffset ;
50+ const selectionEnd = selectionStart + modifiedText . modifiedText . length - oneLinerOffset ;
51+
52+ // Adjust the selection to not contain the **
53+ api . setSelectionRange ( {
54+ start : selectionStart ,
55+ end : selectionEnd
56+ } ) ;
57+ }
58+
59+ export const unorderedListCommand : Command = {
60+ name : "unordered-list" ,
61+ buttonProps : { "aria-label" : "Add unordered list" } ,
62+ execute : ( state0 : TextState , api : TextApi ) => {
63+ makeList ( state0 , api , "- " )
64+ } ,
65+ keyCommand : "code" ,
66+ } ;
67+
68+ export const orderedListCommand : Command = {
69+ name : "ordered-list" ,
70+ buttonProps : { "aria-label" : "Add ordered list" } ,
71+ execute : ( state0 : TextState , api : TextApi ) => {
72+ makeList ( state0 , api , ( item , index ) => `${ index + 1 } . ` )
73+ } ,
74+ keyCommand : "code" ,
75+ } ;
76+
77+ export const checkedListCommand : Command = {
78+ name : "checked-list" ,
79+ buttonProps : { "aria-label" : "Add ordered list" } ,
80+ execute : ( state0 : TextState , api : TextApi ) => {
81+ makeList ( state0 , api , ( item , index ) => `${ index + 1 } . ` )
5882 } ,
5983 keyCommand : "code" ,
60- }
84+ } ;
0 commit comments