home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / incoming / jstools-.6v3 / jstools- / jstools-tk3.6v3.0 / lib / jedit_cmds.tcl < prev    next >
Encoding:
Text File  |  1995-03-14  |  22.0 KB  |  745 lines

  1. # jedit_cmds.tcl - most user-visible commands for jedit
  2. #   (preference commands are in jedit_prefs.tcl)
  3. # Copyright 1992-1994 by Jay Sekora.  All rights reserved, except 
  4. # that this file may be freely redistributed in whole or in part 
  5. # for non-profit, noncommercial use.
  6.  
  7. ######################################################################
  8. #
  9. # NOTE: these mostly take the arguments "t args", where t is the text
  10. # widget they apply to.  That way they can be used in a j:tkb:mkmap
  11. # table (where %W %K %A will be appended to the command before 
  12. # execution) as well as with just %W in bindings.  In a few cases
  13. # where t would be ignored, they just take "args".
  14. #
  15. ######################################################################
  16.  
  17. ######################################################################
  18. # view the help file
  19. ######################################################################
  20.  
  21. proc jedit:cmd:help { t args } {
  22.   exec jdoc jedit &
  23. }
  24.  
  25. ######################################################################
  26. # make the about box
  27. ######################################################################
  28.  
  29. proc jedit:cmd:about { t args } {
  30.   global VERSION
  31.   set about_editor [format {
  32.     j:rt:hl "jedit"
  33.     j:rt:cr
  34.     j:rt:rm "by Jay Sekora, "
  35.     j:rt:tt "js@bu.edu"
  36.     j:rt:par
  37.     j:rt:rm "A customisable text editor for X Windows."
  38.     j:rt:cr
  39.     j:rt:rm "Version %s."
  40.     j:rt:par
  41.     j:rt:rm "Copyright \251 1992-1994 by Jay Sekora.  "
  42.     j:rt:rm "All rights reserved, except that this file may be freely "
  43.     j:rt:rm "redistributed in whole or in part for non\255profit, "
  44.     j:rt:rm "noncommercial use."
  45.     j:rt:par
  46.     j:rt:rm "If you find bugs or have suggestions for improvement, "
  47.     j:rt:rm "please let me know.  "
  48.     j:rt:rm "Feel free to use bits of this code in your own "
  49.     j:rt:tt "wish"
  50.     j:rt:rm " scripts."
  51.   } $VERSION]
  52.   j:about .about $about_editor
  53.   j:about:button .about {About jedit} $about_editor
  54.   j:about:button .about {About the Author} [j:about_jay]
  55.   j:about:button .about {About Tk and Tcl} [j:about_tktcl]
  56.   
  57.   tkwait window .about
  58. }
  59.  
  60. ######################################################################
  61. # open a new editor window
  62. ######################################################################
  63.  
  64. proc jedit:cmd:new_window { args } {
  65.   jedit:jedit
  66. }
  67.  
  68. ######################################################################
  69. # prompt user for mode
  70. ######################################################################
  71.  
  72. proc jedit:cmd:ask_mode { t args } {
  73.   global MODE
  74.   
  75.   set window [jedit:text_to_top $t]
  76.   set prompt_result [j:prompt -text "Editing Mode:"]
  77.   if {$prompt_result != {}} then {
  78.     jedit:set_mode $t $prompt_result
  79.     jedit:apply_mode $window
  80.   }
  81. }
  82.  
  83. ######################################################################
  84. # close a window
  85. ######################################################################
  86.  
  87. proc jedit:cmd:close { t args } {
  88.   global JEDIT_WINDOW_COUNT
  89.   
  90.   if {$JEDIT_WINDOW_COUNT == 1} {
  91.     jedit:cmd:quit $t
  92.   } else {
  93.     set mode [jedit:get_mode $t]
  94.     if {[info procs mode:$mode:pre_close_hook] != {}} {
  95.       mode:$mode:pre_close_hook $t
  96.     }
  97.     
  98.     if {[info procs mode:$mode:close] == {}} {
  99.       if [j:confirm -text "Are you sure you want to close this window?"] {
  100.         incr JEDIT_WINDOW_COUNT -1    ;# one fewer window
  101.         destroy [jedit:text_to_top $t]
  102.       }
  103.     } else {
  104.       mode:$mode:close $t
  105.     }
  106.   }
  107. }
  108.  
  109. ######################################################################
  110. # quit the editor
  111. ######################################################################
  112.  
  113. proc jedit:cmd:quit { t args } {
  114.   set mode [jedit:get_mode $t]
  115.   
  116.   if {[info procs mode:$mode:pre_quit_hook] != {}} {
  117.     mode:$mode:pre_quit_hook $t
  118.   }
  119.   
  120.   if {[info procs mode:$mode:quit] == {}} {
  121.     if [j:confirm -text "Are you sure you want to quit?"] {
  122.       exit 0
  123.     }
  124.   } else {
  125.     mode:$mode:quit $t
  126.   }
  127. }
  128.  
  129. ######################################################################
  130. # read in a file
  131. ######################################################################
  132.  
  133. proc jedit:cmd:load { t args } {
  134.   jedit:cmd:save_checkpoint $t    ;# save undo information
  135.  
  136.   set filename [j:fs -prompt "Load:"]
  137.   if {"x$filename" != "x"} then {
  138.     jedit:set_filename $t $filename
  139.     
  140.     # if new filename should have a different mode, set it:
  141.     set old_mode [jedit:get_mode $t]
  142.     set new_mode [jedit:guess_mode $filename]
  143.     if {[string compare $old_mode $new_mode] != 0} {
  144.       jedit:set_mode $t $new_mode
  145.       jedit:apply_mode $t
  146.     }
  147.     
  148.     jedit:read $filename $t
  149.   }
  150. }
  151.   
  152. ######################################################################
  153. # write out a file, using window's filename if defined
  154. ######################################################################
  155.  
  156. proc jedit:cmd:save { t args } {
  157.   set filename [jedit:get_filename $t]
  158.   if {"x$filename" != "x"} then {
  159.     jedit:write $filename $t
  160.   } else {
  161.     set filename [j:fs -prompt "Save as:"]
  162.     if {"x$filename" != "x"} then {
  163.       jedit:set_filename $t $filename
  164.       jedit:set_label [jedit:text_to_top $t]
  165.       jedit:write $filename $t
  166.     }
  167.   }
  168. }
  169.  
  170. ######################################################################
  171. # write out a file, prompting for a filename
  172. ######################################################################
  173.  
  174. proc jedit:cmd:saveas { t args } {
  175.   set filename [j:fs -prompt "Save as:"]
  176.   if {"x$filename" != "x" && \
  177.      ( ! [file exists $filename] || \
  178.       [j:confirm -text \
  179.       "File \"$filename\" exists; replace it?"] )} then {
  180.     jedit:set_filename $t $filename
  181.     jedit:set_label [jedit:text_to_top $t]
  182.     jedit:write $filename $t
  183.   }
  184. }
  185.  
  186. ######################################################################
  187. # print the file using lpr
  188. ######################################################################
  189.  
  190. proc jedit:cmd:print { t args } {
  191.   global J_PREFS
  192.   if [j:confirm -priority 24 \
  193.     -text "Print using `lpr' to printer `$J_PREFS(printer)'?"] {
  194.     exec lpr -P$J_PREFS(printer) << [$t get 1.0 end]
  195.   }
  196. }
  197.  
  198. ######################################################################
  199. # print rich-text as postscript using lpr
  200. ######################################################################
  201.  
  202. proc jedit:cmd:print_postscript { t args } {
  203.   global J_PREFS
  204.   if [j:confirm -priority 24 \
  205.     -text "Print as PostScript using `lpr' to printer `$J_PREFS(printer)'?"] {
  206.     exec lpr -P$J_PREFS(printer) << [j:tc:ps:convert_text $t]
  207.   }
  208. }
  209.  
  210. ######################################################################
  211. # read in a file and insert it at the insert mark
  212. ######################################################################
  213.  
  214. proc jedit:cmd:insfile { t args } {
  215.   jedit:cmd:save_checkpoint $t            ;# save undo information
  216.   set prompt_result [j:fs -prompt "Insert:"]
  217.   if {$prompt_result != {}} then {
  218.     j:text:insert_string $t [exec cat $prompt_result]
  219.     j:text:insert_string $t "\n"
  220.   }
  221. }
  222.  
  223. ######################################################################
  224. # delete the selection and copy it to CUTBUFFER
  225. ######################################################################
  226.  
  227. proc jedit:cmd:cut { t args } {
  228.   global CUTBUFFER
  229.  
  230.   jedit:cmd:save_checkpoint $t            ;# save undo information
  231.  
  232.   set CUTBUFFER [$t get sel.first sel.last]
  233.   j:text:delete $t sel.first sel.last
  234. }
  235.  
  236. ######################################################################
  237. # copy the selection into CUTBUFFER
  238. ######################################################################
  239.  
  240. proc jedit:cmd:copy { t args } {
  241.   global CUTBUFFER
  242.  
  243.   set CUTBUFFER [$t get sel.first sel.last]
  244. }
  245.  
  246. ######################################################################
  247. # insert CUTBUFFER
  248. ######################################################################
  249.  
  250. proc jedit:cmd:paste { t args } {
  251.   global CUTBUFFER
  252.   
  253.   set mode [jedit:get_mode $t]
  254.   
  255.   jedit:cmd:save_checkpoint $t            ;# save undo information
  256.  
  257.   if {[info procs mode:$mode:pre_paste_hook] != {}} {
  258.     mode:$mode:pre_paste_hook $t
  259.   }
  260.  
  261.   j:text:insert_string $t $CUTBUFFER
  262.  
  263.   if {[info procs mode:$mode:post_paste_hook] != {}} {
  264.     mode:$mode:post_paste_hook $t
  265.   }
  266. }
  267.  
  268. ######################################################################
  269. # copy the selection into a text panel (as a note)
  270. ######################################################################
  271.  
  272. proc jedit:cmd:note { t args } {
  273.   j:more -title Note -text [$t get sel.first sel.last]
  274. }
  275.  
  276. ######################################################################
  277. # mark the entire text as selected
  278. ######################################################################
  279.  
  280. proc jedit:cmd:select_all { t args } {
  281.   $t tag add sel 1.0 end
  282. }
  283.  
  284. ######################################################################
  285. # prompt for a Unix command to run on the selection
  286. ######################################################################
  287.  
  288. proc jedit:cmd:run_pipe { t args } {
  289.   global UNIX_PIPE; append UNIX_PIPE {}
  290.  
  291.   set prompt_result [j:prompt -text "Unix Filter:" -default $UNIX_PIPE]
  292.   if {$prompt_result != {}} then {
  293.     set UNIX_PIPE $prompt_result
  294.     jedit:pipe $t $UNIX_PIPE        ;# handles checkpointing
  295.   }
  296. }
  297.  
  298. ######################################################################
  299. # prompt for a Unix command to insert
  300. ######################################################################
  301.  
  302. proc jedit:cmd:run_command { t args } {
  303.   global UNIX_COMMAND; append UNIX_COMMAND {}
  304.  
  305.   set prompt_result [j:prompt -text "Unix Command:" -default $UNIX_COMMAND]
  306.   if {$prompt_result != {}} then {
  307.     set UNIX_COMMAND $prompt_result
  308.     catch { eval exec $UNIX_COMMAND } result
  309.     if {$result != {}} {
  310.       append result "\n"
  311.       jedit:cmd:save_checkpoint $t            ;# save undo information
  312.       j:text:insert_string $t $result
  313.     }
  314.   }
  315. }
  316.  
  317. ######################################################################
  318. # expand dynamic abbreviation before insert
  319. ######################################################################
  320.  
  321. proc jedit:cmd:dabbrev { t args } {
  322.   # THIS COULD BE SIMPLIFIED: do i need both match... and abbrev... vars?
  323.   # PROBLEM: this depends on the Text widget's notion of words.
  324.   # it would be nice to be able to expand, say, $tk_l to $tk_library.
  325.  
  326.   global ABBREV ABBREV_POS MATCH MATCH_POS
  327.  
  328.   $t mark set abbrevend insert
  329.   $t mark set abbrevstart insert
  330.   while {[$t compare abbrevstart != 1.0] &&
  331.          [string match {[a-zA-Z0-9']} [$t get {abbrevstart - 1 char}]]} {
  332.     $t mark set abbrevstart {abbrevstart -1char}
  333.   }
  334.  
  335.   set ABBREV_POS [$t index abbrevstart]    ;# for dabbrev_again
  336.  
  337.   set ABBREV [$t get abbrevstart insert]
  338.  
  339.   set context [$t get 0.0 abbrevstart]
  340.  
  341.   while {1} {
  342.     set matchpos [string last $ABBREV $context]
  343.   
  344.     if {$matchpos == -1} {return 0}    ;# not found
  345.  
  346.     $t mark set matchstart [$t index "0.0 +$matchpos chars"]
  347.     if {[$t compare matchstart == {matchstart wordstart}]} {
  348.       $t mark set matchend [$t index {matchstart wordend}]
  349.       break                ;# sort of an `until'
  350.     }
  351.     set context [$t get 0.0 matchstart]
  352.   }
  353.  
  354.   set MATCH [$t get matchstart matchend]
  355.  
  356.   set MATCH_POS [$t index matchstart]
  357.  
  358.   j:text:replace $t abbrevstart abbrevend $MATCH
  359.   return 1
  360. }
  361.  
  362. # ######################################################################
  363. # # dabbrev_again - search earlier in the text for abbrevs
  364. # #   CURRENTLY NOT USED
  365. # ######################################################################
  366. # proc dabbrev_again { t args } {
  367. #   # THIS COULD BE SIMPLIFIED: do i need both match... and abbrev... vars?
  368. #   # PROBLEM: this depends on the Text widget's notion of words.
  369. #   # it would be nice to be able to expand, say, $tk_l to $tk_library.
  370. #   global ABBREV ABBREV_POS MATCH MATCH_POS
  371. #   set context [$t get 0.0 $MATCH_POS]
  372. #   while {1} {
  373. #     set matchpos [string last $ABBREV $context]
  374. #   
  375. #     if {$matchpos == -1} {
  376. #       return [sabbrev]            ;# try the static table
  377. #     }
  378. #     $t mark set matchstart [$t index "0.0 +$matchpos chars"]
  379. #     if {[$t compare matchstart == {matchstart wordstart}]} {
  380. #       $t mark set matchend [$t index {matchstart wordend}]
  381. #       break                ;# sort of an `until'
  382. #     }
  383. #     set context [$t get 0.0 matchstart]
  384. #   }
  385. #   set MATCH [$t get matchstart matchend]
  386. #   set MATCH_POS [$t index matchstart]
  387. #   j:text:replace $t $ABBREV_POS abbrevend "$MATCH "
  388. # }
  389.  
  390. ######################################################################
  391. # look up and expand static abbrev before insert
  392. ######################################################################
  393.  
  394. proc jedit:cmd:sabbrev { t args } {
  395.   $t mark set abbrevend insert
  396.   # following don't really need to be global (shared with dabbrev):
  397.   global ABBREV ABBREV_POS ABBREVS
  398.  
  399.   $t mark set abbrevend insert
  400.   $t mark set abbrevstart insert
  401.   while {[$t compare abbrevstart != 1.0] &&
  402.          [string match {[a-zA-Z0-9_']} [$t get {abbrevstart - 1 char}]]} {
  403.     $t mark set abbrevstart {abbrevstart -1char}
  404.   }
  405.  
  406.   # avoid expanding things like \def, .PP, file.c, etc.:
  407.   set prefix [$t get {abbrevstart -2chars} {abbrevstart}]
  408.   if {[string length $prefix] > 0} {
  409.     if {[string match {?[@$%&+=\:~.]} $prefix]} {
  410.       return 0
  411.     }
  412.     # don't expand "l" in "ls -l", but do expand "this---l"
  413.     if {[string match "\[ \t\n\]-" $prefix]} {    ;# don't expand "ls -l"
  414.       return 0
  415.     }
  416.     # don't expand "s" in "house(s)", but do expand "so (s) of"
  417.     if {[string match "\[a-zA-Z](" $prefix]} {    ;# don't expand "house(s)"
  418.       return 0
  419.     }
  420.   }
  421.  
  422.   set ABBREV_POS [$t index abbrevstart]    ;# for dabbrev_again
  423.  
  424.   # first try regular version:
  425.   set ABBREV [$t get abbrevstart insert]
  426.   if {[info exists ABBREVS($ABBREV)]} {
  427.     j:text:replace $t $ABBREV_POS abbrevend $ABBREVS($ABBREV)
  428.     return 1
  429.   }
  430.   # else try capitalised version
  431.   if {[string match {[A-Z][a-z]*} $ABBREV]} {
  432.     set lcabbrev [jedit:uncapitalise $ABBREV]
  433.     if {[info exists ABBREVS($lcabbrev)]} {
  434.       j:text:replace $t $ABBREV_POS abbrevend \
  435.         [jedit:capitalise $ABBREVS($lcabbrev)]
  436.       return 1
  437.     }
  438.   }
  439.   return 0
  440. }
  441.  
  442. ######################################################################
  443. # edit your abbrevs file
  444. ######################################################################
  445.  
  446. proc jedit:cmd:edit_abbrevs { args } {
  447.   global HOME
  448.   if {! [file isdirectory "$HOME/.tk"]} then {
  449.     exec mkdir "$HOME/.tk"
  450.     # above should have error-checking
  451.   }
  452.   exec jabbrevs "$HOME/.tk/abbrevs.tcl" &    ;# doesn't currently use arg
  453. }
  454.  
  455. ######################################################################
  456. # read abbrevs file
  457. ######################################################################
  458.  
  459. proc jedit:cmd:read_abbrevs { args } {
  460.   j:source_config abbrevs.tcl
  461. }
  462.  
  463. ######################################################################
  464. # toggle static abbrevs
  465. ######################################################################
  466.  
  467. proc jedit:cmd:toggle_sabbrev { t args } {
  468.   global JEDIT_MODEPREFS
  469.   
  470.   set mode [jedit:get_mode $t]
  471.   
  472.   set JEDIT_MODEPREFS($mode,sabbrev) \
  473.     [expr {! $JEDIT_MODEPREFS($mode,sabbrev)}]
  474. }
  475.  
  476. ######################################################################
  477. # toggle dynamic abbrevs
  478. ######################################################################
  479.  
  480. proc jedit:cmd:toggle_dabbrev { t args } {
  481.   global JEDIT_MODEPREFS
  482.   
  483.   set mode [jedit:get_mode $t]
  484.   
  485.   set JEDIT_MODEPREFS($mode,dabbrev) \
  486.     [expr {! $JEDIT_MODEPREFS($mode,dabbrev)}]
  487. }
  488.  
  489. ######################################################################
  490. # go to a particular line
  491. ######## NEED TO CHECK THAT AN INDEX WAS TYPED!
  492. ######################################################################
  493.  
  494. proc jedit:cmd:go_to_line { t args } {
  495.   set prompt_result [j:prompt -text "Go to line number:"]
  496.   if {$prompt_result != {}} then {
  497.     jedit:go_to_line $t $prompt_result
  498.   }
  499. }
  500.  
  501. ######################################################################
  502. # display which line the cursor is on
  503. ######################################################################
  504.  
  505. proc jedit:cmd:current_line { t args } {
  506.   set insertindex [split [$t index insert] {.}]
  507.   set line [lindex $insertindex 0]
  508.   set column [lindex $insertindex 1]
  509.   j:alert -title "Notice" \
  510.     -text "The insertion point is at line $line, column $column."
  511. }
  512.  
  513. ######################################################################
  514. # insert X selection
  515. ######################################################################
  516.  
  517. proc jedit:cmd:xpaste { t args } {
  518.   set mode [jedit:get_mode $t]
  519.   
  520.   jedit:cmd:save_checkpoint $t            ;# save undo information
  521.   
  522.   if {[info procs mode:$mode:pre_xpaste_hook] != {}} {
  523.     mode:$mode:pre_xpaste_hook $t
  524.   }
  525.  
  526.   j:text:insert_string $t [j:selection_if_any]
  527.  
  528.   if {[info procs mode:$mode:post_xpaste_hook] != {}} {
  529.     mode:$mode:post_xpaste_hook $t
  530.   }
  531. }
  532.  
  533. ######################################################################
  534. # front end for j:find to match jedit:cmd argument convention
  535. ######################################################################
  536.  
  537. proc jedit:cmd:find { t args } {
  538.   jedit:cmd:save_checkpoint $t
  539.   j:find $t
  540. }
  541.  
  542. ######################################################################
  543. # find same string again (same kind of search)
  544. ######################################################################
  545.  
  546. proc jedit:cmd:find_again { t args } {
  547.   jedit:cmd:save_checkpoint $t
  548.   j:find:again $t
  549. }
  550.  
  551. ######################################################################
  552. # hacks for more-specific kinds of finds (for vi/emacs bindings)
  553. ### BOGUS!  jedit should not need to know about the internals of j:find!
  554. ######################################################################
  555.  
  556. proc jedit:cmd:find_forward { t args } {
  557.   global j_find
  558.   set j_find(backwards) 0
  559.   j:find $t
  560. }
  561.  
  562. proc jedit:cmd:find_backward { t args } {
  563.   global j_find
  564.   set j_find(backwards) 1
  565.   j:find $t
  566. }
  567.  
  568. ######################################################################
  569. # save all windows and quit
  570. ######################################################################
  571.  
  572. # we need to make sure there's a filename before calling save, because
  573. # a cancel in the saveas file selector box will cancel the save, but
  574. # not the quit!
  575.  
  576. proc jedit:cmd:done { t args } {
  577.   set mode [jedit:get_mode $t]
  578.   
  579.   if {[info procs mode:$mode:done] == {}} {
  580.     set filename [jedit:get_filename $t]
  581.     if {"x$filename" == "x"} then {
  582.       set filename [j:fs -prompt "Save as:"]
  583.       if {"x$filename" == "x"} {            ;# user clicked cancel
  584.         return
  585.       } else {
  586.         jedit:set_filename $t $filename
  587.       }
  588.     }
  589.  
  590.     jedit:cmd:save $t
  591.     jedit:cmd:close $t
  592.   } else {
  593.     mode:$mode:done $t
  594.   }
  595. }
  596.  
  597. ######################################################################
  598. # panel to let user insert any iso-8859 character
  599. ######################################################################
  600.  
  601. proc jedit:cmd:char_panel { t args } {
  602.   set tl [j:new_toplevel .high_bit]
  603.   wm title $tl "Characters"
  604.   
  605.   message $tl.m -aspect 350 \
  606.     -text "Click on a character to insert it."
  607.   text $tl.t -width 16 -height 12 -wrap none \
  608.     -cursor top_left_arrow \
  609.     -font -*-courier-bold-r-normal-*-*-140-* \
  610.     -borderwidth 2 -relief groove
  611.   
  612.   # using j:buttonbar for visual consistency:  
  613.   j:buttonbar $tl.b -buttons {
  614.     {ok Done {}}
  615.   }
  616.   $tl.b.ok configure -command "destroy $tl"
  617.   
  618.   for {set i 32} {$i < 112} {incr i 16} {
  619.     for {set j 0} {$j < 16} {incr j} {
  620.       $tl.t insert end [format %c [expr {$i + $j}]]
  621.     }
  622.     $tl.t insert end "\n"
  623.   }
  624.   for {set j 112} {$j < 127} {incr j} {
  625.     $tl.t insert end [format %c $j]
  626.   }
  627.   $tl.t insert end " \n "
  628.   for {set i 160} {$i < 256} {incr i 16} {
  629.     for {set j 0} {$j < 16} {incr j} {
  630.       $tl.t insert end [format %c [expr {$i + $j}]]
  631.     }
  632.     $tl.t insert end "\n"
  633.   }
  634.   $tl.t configure -state disabled
  635.   
  636.   pack $tl.m -fill x
  637.   pack $tl.t -padx 10
  638.   pack $tl.b -anchor e
  639.   
  640.   bind $tl.t <ButtonRelease-1> "
  641.     j:text:insert_string $t \[%W get @%x,%y\]
  642.   "
  643.   foreach event {
  644.     <ButtonRelease-3> <B3-Motion> <Button-3> <ButtonRelease-2>
  645.     <ButtonRelease-1><B2-Motion> <Button-2> <Shift-B1-Motion>
  646.     <Shift-Button-1> <B1-Motion> <Triple-Button-1> <Double-Button-1>
  647.     <Button-1>
  648.     } {
  649.     bind $tl.t $event {;}
  650.   }
  651. }
  652.  
  653. ######################################################################
  654. # insert a hyphen
  655. ######################################################################
  656.  
  657. proc jedit:cmd:hyphen { t args } {
  658.   j:text:insert_string $t "\xad"
  659. }
  660.  
  661. ######################################################################
  662. # insert a copyright symbol
  663. ######################################################################
  664.  
  665. proc jedit:cmd:copyright { t args } {
  666.   j:text:insert_string $t "\xa9"
  667. }
  668.  
  669. ######################################################################
  670. # rich-text cut
  671. ######################################################################
  672.  
  673. proc jedit:cmd:rich_cut { t } {
  674.   jedit:cmd:rich_copy $t            ;# (saves checkpoint)
  675.   $t delete sel.first sel.last
  676. }
  677.  
  678. ######################################################################
  679. # rich-text copy
  680. ######################################################################
  681.  
  682. proc jedit:cmd:rich_copy { t } {
  683.   global RICHBUFFER
  684.   
  685.   jedit:cmd:save_checkpoint $t            ;# save undo information
  686.   
  687.   set RICHBUFFER {}
  688.   set curstring {}
  689.   set curtags [$t tag names sel.first]
  690.   
  691.   $t mark set richptr sel.first
  692.   
  693.   while {[$t compare richptr < sel.last]} {
  694.     set tags [$t tag names richptr]
  695.     set char [$t get richptr]
  696.     if {"x$tags" != "x$curtags"} {    ;# new "range" of text
  697.       lappend RICHBUFFER [list $curstring $curtags]
  698.       set curstring $char
  699.       set curtags $tags
  700.     } else {
  701.       append curstring $char
  702.     }
  703.     $t mark set richptr {richptr+1c}
  704.   }
  705.   lappend RICHBUFFER [list $curstring $curtags]
  706.   return
  707. }
  708.  
  709. ######################################################################
  710. # rich-text paste
  711. #   partly lifted from insertWithTags in mkStyles.tcl demo
  712. ######################################################################
  713.  
  714. proc jedit:cmd:rich_paste { t } {
  715.   global RICHBUFFER
  716.   
  717.   jedit:cmd:save_checkpoint $t            ;# save undo information
  718.   
  719.   lappend RICHBUFFER {}            ;# make sure it's defined
  720.   
  721.   foreach pair $RICHBUFFER {
  722.     set text [lindex $pair 0]
  723.     set tags [lindex $pair 1]
  724.     
  725.     set start [$t index insert]
  726.     $t insert insert $text
  727.     foreach tag [$t tag names $start] {
  728.       $t tag remove $tag $start insert    ;# clear tags inherited from left
  729.     }
  730.     foreach tag $tags {    
  731.       $t tag add $tag $start insert    ;# add new tags
  732.     }
  733.   }
  734.   $t tag remove sel 1.0 end        ;# clear selection (guaranteed in text)
  735.   return
  736. }
  737.