Scratchpad

MJ - When working on Linux I used the Ion3 [L1 ] window manager, which has a very handy feature called a scratchpad. Pressing a specific key combination will popup or hide the scratchpad, allowing you to copy and paste small snippets of text.

On Windows I usually start notepad for similar purposes, but starting notepad all the time gets tedious very quickly. Below a small script that will create a scratchpad that will appear on Win-Space and hide in the tray on Ctrl-Win-Space.

Ctrl-j can be used to execute the current line in the interpreter.

The KHIM (optional), twapi, winico and dde extensions are required. Add a sp.ico file in the script directory. This will be used for the tray icon.

 package require twapi
 package require dde
 package require Winico
 catch {
     package require khim
     set khim::composeKey App
     ::khim::RedoBindings
 }
 
 proc show {} {
     wm deiconify .
     raise .
     focus .txt
 }
 
 proc checkRunning {} {
     set topicName scratchpad
     set otherServices [dde services TclEval $topicName]
     if { [llength $otherServices] > 0 } {
         dde execute TclEval $topicName {
             show
         }
         exit
     } else { 
         dde servername $topicName
     }        
 }
 
 proc cbTaskbar {msg} {
     if {$msg eq "WM_LBUTTONDOWN"} {
         if {[winfo ismapped .]} {
             wm withdraw .
         } else { 
             show
         }
     }
 }
 
 wm protocol . WM_DELETE_WINDOW {
     wm withdraw .
 }
 
 proc main {} {
     global icon
     checkRunning
     overrideCommands
 
     # start minimized
     wm withdraw .
 
     # import mathops to make more usable as calculator
     namespace import ::tcl::mathop::*
 
     set iconfile [file dirname [info script]]/sp.ico
     set icon [winico createfrom $iconfile]
     wm iconbitmap . $iconfile 
     wm iconbitmap . -default $iconfile 
     wm title . Scratchpad
     winico taskbar add $icon -callback {cbTaskbar %m} -text Scratchpad
 
     ::twapi::register_hotkey Win-Space show
     ::twapi::register_hotkey Ctrl-Win-Space {wm withdraw .}
 
     text .txt -font {Fixedsys 10} -yscrollcommand {.vbar set} -undo 1
     scrollbar .vbar -orient vertical -command {.txt yview}
     grid .txt -sticky nsew -row 0 -column 0
     grid .vbar -sticky ns -row 0 -column 1
     grid columnconfigure . 0 -weight 1
     grid rowconfigure . 0 -weight 1
 
     bind . <Key-F5> {console show}
 
     # define Emacs bindings
     bindtags .txt [linsert [bindtags .txt] 1 KHIM Emacs]
     set ::prefix 0
     bind Emacs <Key-h> {if {$::prefix} {%W tag add sel 1.0 end ; break}}
     bind Emacs <Control-x> {set ::prefix 1 ; after 2000 {set ::prefix 0} ; break}
     bind Emacs <Control-j> {
         if {![catch {eval [%W get {insert linestart} {insert lineend}]} result]} {
             set ::_ $result
         }
         %W mark set insert {insert lineend}
         %W insert {insert lineend} \n
         %W mark set r1 insert-1c
         %W insert insert $result
         %W mark set r2 insert
         %W tag add sel {r1+1line linestart} r2
     }
 }
 
 proc overrideCommands {} {
     interp hide {} exit
     proc exit {{code 0}} {
         global icon
         winico taskbar delete $icon
         interp invokehidden {} exit $code
     }
 }
 
 # utility commands
 
 # calculate the difference between two date: [dd {d m y} {d m y}]
 # or the date x days from now              : [dd {d m y} x]
 # if first date is the empty list {} today is used 
 proc dd {d1 d2} {
     if {$d1=={}} {
         set d1 [clock format [clock scan {today}] -format {%d %m %Y}]
     }
     set second1 [clock scan $d1 -format {%d %m %Y}]
     if {[llength $d2]==1} {
     # difference in days
         set second2 [expr {$second1+$d2*24*60*60}]
         return [clock format $second2 -format {%d %m %Y}]
     } else {
     # difference between days
         set second2 [clock scan $d2 -format {%d %m %Y}]
         return [expr {int(($second2-$second1)/60./60./24.)}]
     } 
 }
 
 # https://wiki.tcl-lang.org/cal
 proc cal {{month {}} {year {}}} {
     if {$month eq ""} {set month [clock format [clock sec] -format %B]}
     if {[llength $month] > 1} {
         set res {}
         foreach m $month {
             append res [cal $m $year]\n\n
         }
         return [string trimright $res]
     }
     if {$year eq ""}  {set year [clock format [clock sec] -format %Y]}
     set res "     $month $year\n Su Mo Tu We Th Fr Sa\n"
     set weekday [clock format [clock scan "1 $month $year"] -format %w]
     append res  [string repeat "   " $weekday]
     scan [clock format [clock scan "1 $month $year"] -format %m] %d decm
     set maxd [numberofdays $decm $year]
     for {set d 1} {$d <= $maxd} {incr d} {
         append res [format %3d $d]
         if {[incr weekday]>6} {append res \n; set weekday 0}
     }
     set res
 }
 
 proc numberofdays {month year} {
     if {$month==12} {set month 1; incr year}
     clock format [clock scan "[incr month]/1/$year  1 day ago"] \
         -format %d
 }
 
 main

So, why not just use Microsoft's clipbrd.exe ? It seems to do what you described the scratchpad would do... be a repository for copy/cut and paste.

MJ - I didn't know clibrd.exe, thanks for the tip. However that seems to be read only and I also use it to write small snippets of code to paste into the chat for instance. Additionaly the abillity to evaluate some Tcl code makes it for instance quite a powerful calculator as well.