@@ -245,7 +245,8 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
245245 const text = toString ( )
246246 const before = text . slice ( 0 , start )
247247 const after = text . slice ( end )
248- return { before, after}
248+ const within = text . slice ( start , end )
249+ return { before, after, within}
249250 }
250251
251252 function handleNewLine ( event : KeyboardEvent ) {
@@ -311,25 +312,31 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
311312 }
312313
313314 function handleTabCharacters ( event : KeyboardEvent ) {
314- if ( event . key === 'Tab' ) {
315- event . preventDefault ( )
316- if ( event . shiftKey ) {
317- const { before} = aroundCursor ( )
318- const [ padding , start ] = findPadding ( before )
319- if ( padding . length > 0 ) {
320- const pos = save ( )
321- // Remove full length tab or just remaining padding
322- const len = Math . min ( options . tab . length , padding . length )
323- restore ( { start, end : start + len } )
324- insert ( '' ) // deletes the selection
325- pos . start -= len
326- pos . end -= len
327- restore ( pos )
328- }
329- } else {
330- insert ( options . tab )
331- }
315+ if ( event . key !== 'Tab' ) return
316+ event . preventDefault ( )
317+ const pos = save ( )
318+ if ( ! event . shiftKey && pos . start === pos . end ) {
319+ insert ( options . tab )
320+ return
332321 }
322+
323+ let { before, after, within} = aroundCursor ( )
324+
325+ const i = Math . max ( 0 , before . lastIndexOf ( '\n' ) )
326+ const j = Math . min ( Infinity , after . indexOf ( '\n' ) )
327+ within = before . slice ( i ) + within + after . slice ( 0 , j )
328+ before = before . slice ( 0 , i )
329+ after = after . slice ( j )
330+
331+ const replaced = event . shiftKey
332+ ? within . replace ( new RegExp ( `^[\\t ]{0,${ options . tab . length } }` , 'gm' ) , '' )
333+ : within . replace ( / ^ / gm, options . tab )
334+ editor . textContent = before + replaced + after
335+
336+ const len = replaced . length - within . length
337+ pos . start += len
338+ pos . end += len
339+ restore ( pos )
333340 }
334341
335342 function handleUndoRedo ( event : KeyboardEvent ) {
0 commit comments