Skip to content

Commit ddd1051

Browse files
squarebatrfindler
authored andcommitted
Add reopen closed tab menu item
closes #543 closes #508
1 parent 320cb51 commit ddd1051

File tree

7 files changed

+133
-9
lines changed

7 files changed

+133
-9
lines changed

drracket/drracket/HISTORY.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
------------------------------
2+
Version 8.5
3+
------------------------------
4+
5+
. added new file menu item 'Reopen Closed Tab' to open previously
6+
closed tabs.
7+
. Removed keyboard shortcut for 'Spell Check test' in edit menu due
8+
to conflict with 'Reopen Closed Tab'.
9+
110
------------------------------
211
Version 8.4
312
------------------------------

drracket/drracket/private/frame.rkt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,16 @@
936936
(demand-callback
937937
(λ (menu)
938938
(handler:install-recent-items menu))))
939+
(new menu:can-restore-menu-item%
940+
(label (string-constant reopen-closed-tab))
941+
(shortcut #\t)
942+
(shortcut-prefix (cons 'shift (get-default-shortcut-prefix)))
943+
(parent file-menu)
944+
[demand-callback (λ (item) (send item enable (pair? (preferences:get 'drracket:recently-closed-tabs))))]
945+
(callback
946+
(λ (x y)
947+
(define fr (handler:edit-file #f))
948+
(send fr reopen-closed-tab))))
939949
(new menu-item%
940950
[label (string-constant mfs-multi-file-search-menu-item)]
941951
[parent file-menu]

drracket/drracket/private/main.rkt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,41 @@
617617

618618
(preferences:set-default 'drracket:show-killed-dialog #t boolean?)
619619

620+
(preferences:set-default
621+
'drracket:recently-closed-tabs
622+
null
623+
(λ (x) (and (list? x)
624+
(andmap
625+
(λ (x)
626+
(and (list? x)
627+
(= 3 (length x))
628+
(path? (car x))
629+
(number? (cadr x))
630+
(number? (caddr x))))
631+
x))))
632+
633+
(preferences:set-un/marshall
634+
'drracket:recently-closed-tabs
635+
(λ (l) (map (λ (ele) (cons (path->bytes (car ele)) (cdr ele))) l))
636+
(λ (l)
637+
(let/ec k
638+
(unless (list? l)
639+
(k '()))
640+
(map (λ (x)
641+
(unless (and (list? x)
642+
(= 3 (length x))
643+
(bytes? (car x))
644+
(number? (cadr x))
645+
(number? (caddr x)))
646+
(k '()))
647+
(cons (bytes->path (car x)) (cdr x)))
648+
l))))
649+
650+
(preferences:set-default 'drracket:recently-closed-tabs-max-count
651+
1000
652+
(λ (x) (and (number? x)
653+
(x . > . 0)
654+
(integer? x))))
620655

621656
(drr:set-default 'drracket:large-letters-font #f
622657
(or/c #f

drracket/drracket/private/unit.rkt

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2877,6 +2877,7 @@
28772877
(send (send tab get-defs) on-close)
28782878
(send (send tab get-ints) on-close)))
28792879
tabs)
2880+
(update-recently-closed-tabs tabs)
28802881
(when (eq? this newest-frame)
28812882
(set! newest-frame #f))
28822883
(when transcript
@@ -3075,7 +3076,7 @@
30753076
;; create-new-tab : -> void
30763077
;; creates a new tab and updates the GUI for that new tab
30773078
(define/public create-new-tab
3078-
(lambda ([filename #f])
3079+
(lambda ([filename #f] #:start-pos [start-pos 0] #:end-pos [end-pos 'same])
30793080
(let* ([defs (new (drracket:get/extend:get-definitions-text))]
30803081
[tab-count (length tabs)]
30813082
[new-tab (new (drracket:get/extend:get-tab)
@@ -3086,6 +3087,7 @@
30863087
(ints-shown? (not filename)))]
30873088
[ints (make-object (drracket:get/extend:get-interactions-text) new-tab)])
30883089
(send new-tab set-ints ints)
3090+
(send (send new-tab get-defs) set-position start-pos end-pos)
30893091
(set! tabs (append tabs (list new-tab)))
30903092
(send tabs-panel append
30913093
(gui-utils:trim-string
@@ -3248,6 +3250,7 @@
32483250
(send tab set-i (- (send tab get-i) 1)))
32493251
(set! tabs (remq tab-to-close tabs))
32503252
(send tabs-panel delete (send tab-to-close get-i))
3253+
(update-recently-closed-tabs (list tab-to-close))
32513254
(update-menu-bindings)
32523255
(cond
32533256
[(eq? tab-to-close current-tab)
@@ -3265,9 +3268,34 @@
32653268
#t]
32663269
[else #f]))
32673270

3268-
(define/public (open-in-new-tab filename)
3269-
(create-new-tab filename))
3271+
(define/public (open-in-new-tab filename #:start-pos [start-pos 0] #:end-pos [end-pos 'same])
3272+
(create-new-tab filename #:start-pos start-pos #:end-pos end-pos))
32703273

3274+
;; reopen-closed-tab : -> void
3275+
;; Opens previously closed tabs. If no tabs were closed in current session, files from
3276+
;; previous sessions are opened.
3277+
(define/public (reopen-closed-tab)
3278+
(define closed-tabs (preferences:get 'drracket:recently-closed-tabs))
3279+
(define-values (file-to-open new-closed-tabs)
3280+
(let loop ([closed-tabs closed-tabs])
3281+
(cond
3282+
[(null? closed-tabs) (values #f '())]
3283+
[else
3284+
(define closed-tab (car closed-tabs))
3285+
(cond
3286+
[(file-exists? (car closed-tab))
3287+
(values closed-tab (cdr closed-tabs))]
3288+
[else (loop (cdr closed-tabs))])])))
3289+
(when file-to-open
3290+
(define tab (find-matching-tab (car file-to-open)))
3291+
(define start-pos (cadr file-to-open))
3292+
(define end-pos (caddr file-to-open))
3293+
(if tab
3294+
(change-to-tab tab)
3295+
(open-in-new-tab (car file-to-open) #:start-pos start-pos #:end-pos end-pos)))
3296+
(preferences:set 'drracket:recently-closed-tabs new-closed-tabs)
3297+
#f)
3298+
32713299
(define/public (get-tab-count) (length tabs))
32723300
(define/public (change-to-nth-tab n)
32733301
(unless (< n (length tabs))
@@ -3350,7 +3378,7 @@
33503378
(with-handlers ([exn:fail? (λ (x) #f)])
33513379
(string=? (path->string (normal-case-path (normalize-path p1)))
33523380
(path->string (normal-case-path (normalize-path p2))))))
3353-
3381+
33543382
(define/override (make-visible filename)
33553383
(let ([tab (find-matching-tab filename)])
33563384
(when tab
@@ -3396,7 +3424,27 @@
33963424
(when close-tab-menu-item
33973425
(update-close-tab-menu-item-shortcut close-tab-menu-item))
33983426
(update-close-menu-item-shortcut (file-menu:get-close-item)))
3399-
3427+
3428+
(define/private (update-recently-closed-tabs tabs)
3429+
(define closed-tabs (preferences:get 'drracket:recently-closed-tabs))
3430+
(define recently-closed-tabs-max-count (preferences:get 'drracket:recently-closed-tabs-max-count))
3431+
(for ([tab (in-list tabs)])
3432+
(define defs (send tab get-defs))
3433+
(define tab-filename (send defs get-filename))
3434+
(when tab-filename
3435+
(define start-pos (send defs get-start-position))
3436+
(define end-pos (send defs get-end-position))
3437+
(define new-ent (list tab-filename start-pos end-pos))
3438+
(set! closed-tabs
3439+
(cons new-ent
3440+
(remove* (list new-ent)
3441+
closed-tabs
3442+
(λ (l1 l2)
3443+
(pathname-equal? (car l1) (car l2))))))))
3444+
(unless (<= (length closed-tabs) recently-closed-tabs-max-count)
3445+
(set! closed-tabs (take closed-tabs recently-closed-tabs-max-count)))
3446+
(preferences:set 'drracket:recently-closed-tabs closed-tabs))
3447+
34003448
(define/private (update-close-tab-menu-item-shortcut item)
34013449
(define just-one? (and (pair? tabs) (null? (cdr tabs))))
34023450
(send item set-label (if just-one?
@@ -3932,6 +3980,15 @@
39323980
(let-values ([(base name dir?) (split-path editing-path)])
39333981
base))))
39343982
(when pth (handler:edit-file pth)))])
3983+
(new menu:can-restore-menu-item%
3984+
(label (string-constant reopen-closed-tab))
3985+
(shortcut #\t)
3986+
(shortcut-prefix (cons 'shift (get-default-shortcut-prefix)))
3987+
(parent file-menu)
3988+
[demand-callback (λ (item) (send item enable (pair? (preferences:get 'drracket:recently-closed-tabs))))]
3989+
(callback
3990+
(λ (x y)
3991+
(reopen-closed-tab))))
39353992
(super file-menu:between-open-and-revert file-menu)
39363993
(make-object separator-menu-item% file-menu))]
39373994
(define close-tab-menu-item #f)
@@ -4055,7 +4112,7 @@
40554112
(mk-menu-item (λ (ed) (send ed get-spell-check-text))
40564113
(λ (ed new-val) (send ed set-spell-check-text new-val))
40574114
'framework:spell-check-text?
4058-
#\t
4115+
#f
40594116
(string-constant spell-check-scribble-text))
40604117

40614118
(new menu:can-restore-menu-item%

drracket/info.rkt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"sandbox-lib"
1919
("scribble-lib" #:version "1.11")
2020
("snip-lib" #:version "1.2")
21-
["string-constants-lib" #:version "1.38"]
21+
["string-constants-lib" #:version "1.41"]
2222
"typed-racket-lib"
2323
"wxme-lib"
2424
["gui-lib" #:version "1.64"]

drracket/scribblings/drracket/menus.scrbl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
or @litchar{"x.rkt"})
3131
and edit the corresponding files in the @tech{definitions window}.}
3232

33+
@item{@defmenuitem{Reopen Closed Tab} Opens previously closed tabs.
34+
If no tabs were closed in current session, files from
35+
previous sessions are opened.}
36+
3337
@item{@defmenuitem{Install PLT File...} Opens a dialog asking for the
3438
location of the @filepath{.plt} file (either on the local disk or
3539
on the web) and installs the contents of the file.}

drracket/scribblings/tools/unit.scrbl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,15 +619,24 @@ Returns the currently active tab.
619619
Returns the number of open tabs in the frame.
620620
}
621621

622-
@defmethod[(open-in-new-tab [filename (or/c path-string? #f)]) void?]{
622+
@defmethod[(open-in-new-tab [filename (or/c path-string? #f)]
623+
[#:start-pos start-pos exact-nonnegative-integer? 0]
624+
[#:end-pos end-pos (or/c exact-nonnegative-integer? 'same) 'same])
625+
void?]{
623626
Opens a new tab in this frame. If @racket[filename] is a @racket[path-string?],
624-
It loads that file in the definitions window of the new tab.
627+
load that file in the definitions window of the new tab. If @racket[start-pos] and
628+
@racket[end-pos] are provided, call the tab's definition's window's @method[text% set-position]
629+
with them.
625630
}
626631

627632
@defmethod[(create-new-tab) void?]{
628633
Creates a new tab.
629634
}
630635

636+
@defmethod[(reopen-closed-tab) void?]{
637+
Opens the most recently closed tabs.
638+
}
639+
631640
@defmethod[(next-tab) void?]{
632641
Switches to the next tab.
633642
}

0 commit comments

Comments
 (0)