@@ -237,7 +237,8 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
237
237
const text = toString ( )
238
238
const before = text . slice ( 0 , start )
239
239
const after = text . slice ( end )
240
- return { before, after}
240
+ const within = text . slice ( start , end )
241
+ return { before, after, within}
241
242
}
242
243
243
244
function handleNewLine ( event : KeyboardEvent ) {
@@ -303,25 +304,31 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
303
304
}
304
305
305
306
function handleTabCharacters ( event : KeyboardEvent ) {
306
- if ( event . key === 'Tab' ) {
307
- event . preventDefault ( )
308
- if ( event . shiftKey ) {
309
- const { before} = aroundCursor ( )
310
- const [ padding , start ] = findPadding ( before )
311
- if ( padding . length > 0 ) {
312
- const pos = save ( )
313
- // Remove full length tab or just remaining padding
314
- const len = Math . min ( options . tab . length , padding . length )
315
- restore ( { start, end : start + len } )
316
- insert ( '' ) // deletes the selection
317
- pos . start -= len
318
- pos . end -= len
319
- restore ( pos )
320
- }
321
- } else {
322
- insert ( options . tab )
323
- }
307
+ if ( event . key !== 'Tab' ) return
308
+ event . preventDefault ( )
309
+ const pos = save ( )
310
+ if ( ! event . shiftKey && pos . start === pos . end ) {
311
+ insert ( options . tab )
312
+ return
324
313
}
314
+
315
+ let { before, after, within} = aroundCursor ( )
316
+
317
+ const i = Math . max ( 0 , before . lastIndexOf ( '\n' ) )
318
+ const j = Math . min ( Infinity , after . indexOf ( '\n' ) )
319
+ within = before . slice ( i ) + within + after . slice ( 0 , j )
320
+ before = before . slice ( 0 , i )
321
+ after = after . slice ( j )
322
+
323
+ const replaced = event . shiftKey
324
+ ? within . replace ( new RegExp ( `^[\\t ]{0,${ options . tab . length } }` , 'gm' ) , '' )
325
+ : within . replace ( / ^ / gm, options . tab )
326
+ editor . textContent = before + replaced + after
327
+
328
+ const len = replaced . length - within . length
329
+ pos . start += len
330
+ pos . end += len
331
+ restore ( pos )
325
332
}
326
333
327
334
function handleUndoRedo ( event : KeyboardEvent ) {
0 commit comments