home *** CD-ROM | disk | FTP | other *** search
- # jedit_cmds.tcl - most user-visible commands for jedit
- # (preference commands are in jedit_prefs.tcl)
- #
- # Copyright 1992-1994 by Jay Sekora. All rights reserved, except
- # that this file may be freely redistributed in whole or in part
- # for non-profit, noncommercial use.
-
- ######################################################################
- #
- # NOTE: these mostly take the arguments "t args", where t is the text
- # widget they apply to. That way they can be used in a j:tkb:mkmap
- # table (where %W %K %A will be appended to the command before
- # execution) as well as with just %W in bindings. In a few cases
- # where t would be ignored, they just take "args".
- #
- ######################################################################
-
- ######################################################################
- # view the help file
- ######################################################################
-
- proc jedit:cmd:help { t args } {
- exec jdoc jedit &
- }
-
- ######################################################################
- # make the about box
- ######################################################################
-
- proc jedit:cmd:about { t args } {
- global VERSION
- set about_editor [format {
- j:rt:hl "jedit"
- j:rt:cr
- j:rt:rm "by Jay Sekora, "
- j:rt:tt "js@bu.edu"
- j:rt:par
- j:rt:rm "A customisable text editor for X Windows."
- j:rt:cr
- j:rt:rm "Version %s."
- j:rt:par
- j:rt:rm "Copyright \251 1992-1994 by Jay Sekora. "
- j:rt:rm "All rights reserved, except that this file may be freely "
- j:rt:rm "redistributed in whole or in part for non\255profit, "
- j:rt:rm "noncommercial use."
- j:rt:par
- j:rt:rm "If you find bugs or have suggestions for improvement, "
- j:rt:rm "please let me know. "
- j:rt:rm "Feel free to use bits of this code in your own "
- j:rt:tt "wish"
- j:rt:rm " scripts."
- } $VERSION]
- j:about .about $about_editor
- j:about:button .about {About jedit} $about_editor
- j:about:button .about {About the Author} [j:about_jay]
- j:about:button .about {About Tk and Tcl} [j:about_tktcl]
-
- tkwait window .about
- }
-
- ######################################################################
- # open a new editor window
- ######################################################################
-
- proc jedit:cmd:new_window { args } {
- jedit:jedit
- }
-
- ######################################################################
- # prompt user for mode
- ######################################################################
-
- proc jedit:cmd:ask_mode { t args } {
- global MODE
-
- set window [jedit:text_to_top $t]
- set prompt_result [j:prompt -text "Editing Mode:"]
- if {$prompt_result != {}} then {
- jedit:set_mode $t $prompt_result
- jedit:apply_mode $window
- }
- }
-
- ######################################################################
- # close a window
- ######################################################################
-
- proc jedit:cmd:close { t args } {
- global JEDIT_WINDOW_COUNT
-
- if {$JEDIT_WINDOW_COUNT == 1} {
- jedit:cmd:quit $t
- } else {
- set mode [jedit:get_mode $t]
- if {[info procs mode:$mode:pre_close_hook] != {}} {
- mode:$mode:pre_close_hook $t
- }
-
- if {[info procs mode:$mode:close] == {}} {
- if [j:confirm -text "Are you sure you want to close this window?"] {
- incr JEDIT_WINDOW_COUNT -1 ;# one fewer window
- destroy [jedit:text_to_top $t]
- }
- } else {
- mode:$mode:close $t
- }
- }
- }
-
- ######################################################################
- # quit the editor
- ######################################################################
-
- proc jedit:cmd:quit { t args } {
- set mode [jedit:get_mode $t]
-
- if {[info procs mode:$mode:pre_quit_hook] != {}} {
- mode:$mode:pre_quit_hook $t
- }
-
- if {[info procs mode:$mode:quit] == {}} {
- if [j:confirm -text "Are you sure you want to quit?"] {
- exit 0
- }
- } else {
- mode:$mode:quit $t
- }
- }
-
- ######################################################################
- # read in a file
- ######################################################################
-
- proc jedit:cmd:load { t args } {
- jedit:cmd:save_checkpoint $t ;# save undo information
-
- set filename [j:fs -prompt "Load:"]
- if {"x$filename" != "x"} then {
- jedit:set_filename $t $filename
-
- # if new filename should have a different mode, set it:
- set old_mode [jedit:get_mode $t]
- set new_mode [jedit:guess_mode $filename]
- if {[string compare $old_mode $new_mode] != 0} {
- jedit:set_mode $t $new_mode
- jedit:apply_mode $t
- }
-
- jedit:read $filename $t
- }
- }
-
- ######################################################################
- # write out a file, using window's filename if defined
- ######################################################################
-
- proc jedit:cmd:save { t args } {
- set filename [jedit:get_filename $t]
- if {"x$filename" != "x"} then {
- jedit:write $filename $t
- } else {
- set filename [j:fs -prompt "Save as:"]
- if {"x$filename" != "x"} then {
- jedit:set_filename $t $filename
- jedit:set_label [jedit:text_to_top $t]
- jedit:write $filename $t
- }
- }
- }
-
- ######################################################################
- # write out a file, prompting for a filename
- ######################################################################
-
- proc jedit:cmd:saveas { t args } {
- set filename [j:fs -prompt "Save as:"]
- if {"x$filename" != "x" && \
- ( ! [file exists $filename] || \
- [j:confirm -text \
- "File \"$filename\" exists; replace it?"] )} then {
- jedit:set_filename $t $filename
- jedit:set_label [jedit:text_to_top $t]
- jedit:write $filename $t
- }
- }
-
- ######################################################################
- # print the file using lpr
- ######################################################################
-
- proc jedit:cmd:print { t args } {
- global J_PREFS
- if [j:confirm -priority 24 \
- -text "Print using `lpr' to printer `$J_PREFS(printer)'?"] {
- exec lpr -P$J_PREFS(printer) << [$t get 1.0 end]
- }
- }
-
- ######################################################################
- # print rich-text as postscript using lpr
- ######################################################################
-
- proc jedit:cmd:print_postscript { t args } {
- global J_PREFS
- if [j:confirm -priority 24 \
- -text "Print as PostScript using `lpr' to printer `$J_PREFS(printer)'?"] {
- exec lpr -P$J_PREFS(printer) << [j:tc:ps:convert_text $t]
- }
- }
-
- ######################################################################
- # read in a file and insert it at the insert mark
- ######################################################################
-
- proc jedit:cmd:insfile { t args } {
- jedit:cmd:save_checkpoint $t ;# save undo information
- set prompt_result [j:fs -prompt "Insert:"]
- if {$prompt_result != {}} then {
- j:text:insert_string $t [exec cat $prompt_result]
- j:text:insert_string $t "\n"
- }
- }
-
- ######################################################################
- # delete the selection and copy it to CUTBUFFER
- ######################################################################
-
- proc jedit:cmd:cut { t args } {
- global CUTBUFFER
-
- jedit:cmd:save_checkpoint $t ;# save undo information
-
- set CUTBUFFER [$t get sel.first sel.last]
- j:text:delete $t sel.first sel.last
- }
-
- ######################################################################
- # copy the selection into CUTBUFFER
- ######################################################################
-
- proc jedit:cmd:copy { t args } {
- global CUTBUFFER
-
- set CUTBUFFER [$t get sel.first sel.last]
- }
-
- ######################################################################
- # insert CUTBUFFER
- ######################################################################
-
- proc jedit:cmd:paste { t args } {
- global CUTBUFFER
-
- set mode [jedit:get_mode $t]
-
- jedit:cmd:save_checkpoint $t ;# save undo information
-
- if {[info procs mode:$mode:pre_paste_hook] != {}} {
- mode:$mode:pre_paste_hook $t
- }
-
- j:text:insert_string $t $CUTBUFFER
-
- if {[info procs mode:$mode:post_paste_hook] != {}} {
- mode:$mode:post_paste_hook $t
- }
- }
-
- ######################################################################
- # copy the selection into a text panel (as a note)
- ######################################################################
-
- proc jedit:cmd:note { t args } {
- j:more -title Note -text [$t get sel.first sel.last]
- }
-
- ######################################################################
- # mark the entire text as selected
- ######################################################################
-
- proc jedit:cmd:select_all { t args } {
- $t tag add sel 1.0 end
- }
-
- ######################################################################
- # prompt for a Unix command to run on the selection
- ######################################################################
-
- proc jedit:cmd:run_pipe { t args } {
- global UNIX_PIPE; append UNIX_PIPE {}
-
- set prompt_result [j:prompt -text "Unix Filter:" -default $UNIX_PIPE]
- if {$prompt_result != {}} then {
- set UNIX_PIPE $prompt_result
- jedit:pipe $t $UNIX_PIPE ;# handles checkpointing
- }
- }
-
- ######################################################################
- # prompt for a Unix command to insert
- ######################################################################
-
- proc jedit:cmd:run_command { t args } {
- global UNIX_COMMAND; append UNIX_COMMAND {}
-
- set prompt_result [j:prompt -text "Unix Command:" -default $UNIX_COMMAND]
- if {$prompt_result != {}} then {
- set UNIX_COMMAND $prompt_result
- catch { eval exec $UNIX_COMMAND } result
- if {$result != {}} {
- append result "\n"
- jedit:cmd:save_checkpoint $t ;# save undo information
- j:text:insert_string $t $result
- }
- }
- }
-
- ######################################################################
- # expand dynamic abbreviation before insert
- ######################################################################
-
- proc jedit:cmd:dabbrev { t args } {
- # THIS COULD BE SIMPLIFIED: do i need both match... and abbrev... vars?
- # PROBLEM: this depends on the Text widget's notion of words.
- # it would be nice to be able to expand, say, $tk_l to $tk_library.
-
- global ABBREV ABBREV_POS MATCH MATCH_POS
-
- $t mark set abbrevend insert
- $t mark set abbrevstart insert
- while {[$t compare abbrevstart != 1.0] &&
- [string match {[a-zA-Z0-9']} [$t get {abbrevstart - 1 char}]]} {
- $t mark set abbrevstart {abbrevstart -1char}
- }
-
- set ABBREV_POS [$t index abbrevstart] ;# for dabbrev_again
-
- set ABBREV [$t get abbrevstart insert]
-
- set context [$t get 0.0 abbrevstart]
-
- while {1} {
- set matchpos [string last $ABBREV $context]
-
- if {$matchpos == -1} {return 0} ;# not found
-
- $t mark set matchstart [$t index "0.0 +$matchpos chars"]
- if {[$t compare matchstart == {matchstart wordstart}]} {
- $t mark set matchend [$t index {matchstart wordend}]
- break ;# sort of an `until'
- }
- set context [$t get 0.0 matchstart]
- }
-
- set MATCH [$t get matchstart matchend]
-
- set MATCH_POS [$t index matchstart]
-
- j:text:replace $t abbrevstart abbrevend $MATCH
- return 1
- }
-
- # ######################################################################
- # # dabbrev_again - search earlier in the text for abbrevs
- # # CURRENTLY NOT USED
- # ######################################################################
- #
- # proc dabbrev_again { t args } {
- # # THIS COULD BE SIMPLIFIED: do i need both match... and abbrev... vars?
- # # PROBLEM: this depends on the Text widget's notion of words.
- # # it would be nice to be able to expand, say, $tk_l to $tk_library.
- #
- # global ABBREV ABBREV_POS MATCH MATCH_POS
- #
- # set context [$t get 0.0 $MATCH_POS]
- #
- # while {1} {
- # set matchpos [string last $ABBREV $context]
- #
- # if {$matchpos == -1} {
- # return [sabbrev] ;# try the static table
- # }
- # $t mark set matchstart [$t index "0.0 +$matchpos chars"]
- # if {[$t compare matchstart == {matchstart wordstart}]} {
- # $t mark set matchend [$t index {matchstart wordend}]
- # break ;# sort of an `until'
- # }
- # set context [$t get 0.0 matchstart]
- # }
- #
- # set MATCH [$t get matchstart matchend]
- #
- # set MATCH_POS [$t index matchstart]
- #
- # j:text:replace $t $ABBREV_POS abbrevend "$MATCH "
- # }
-
- ######################################################################
- # look up and expand static abbrev before insert
- ######################################################################
-
- proc jedit:cmd:sabbrev { t args } {
- $t mark set abbrevend insert
- # following don't really need to be global (shared with dabbrev):
- global ABBREV ABBREV_POS ABBREVS
-
- $t mark set abbrevend insert
- $t mark set abbrevstart insert
- while {[$t compare abbrevstart != 1.0] &&
- [string match {[a-zA-Z0-9_']} [$t get {abbrevstart - 1 char}]]} {
- $t mark set abbrevstart {abbrevstart -1char}
- }
-
- # avoid expanding things like \def, .PP, file.c, etc.:
- set prefix [$t get {abbrevstart -2chars} {abbrevstart}]
- if {[string length $prefix] > 0} {
- if {[string match {?[@$%&+=\:~.]} $prefix]} {
- return 0
- }
- # don't expand "l" in "ls -l", but do expand "this---l"
- if {[string match "\[ \t\n\]-" $prefix]} { ;# don't expand "ls -l"
- return 0
- }
- # don't expand "s" in "house(s)", but do expand "so (s) of"
- if {[string match "\[a-zA-Z](" $prefix]} { ;# don't expand "house(s)"
- return 0
- }
- }
-
- set ABBREV_POS [$t index abbrevstart] ;# for dabbrev_again
-
- # first try regular version:
- set ABBREV [$t get abbrevstart insert]
- if {[info exists ABBREVS($ABBREV)]} {
- j:text:replace $t $ABBREV_POS abbrevend $ABBREVS($ABBREV)
- return 1
- }
- # else try capitalised version
- if {[string match {[A-Z][a-z]*} $ABBREV]} {
- set lcabbrev [jedit:uncapitalise $ABBREV]
- if {[info exists ABBREVS($lcabbrev)]} {
- j:text:replace $t $ABBREV_POS abbrevend \
- [jedit:capitalise $ABBREVS($lcabbrev)]
- return 1
- }
- }
- return 0
- }
-
- ######################################################################
- # edit your abbrevs file
- ######################################################################
-
- proc jedit:cmd:edit_abbrevs { args } {
- global HOME
- if {! [file isdirectory "$HOME/.tk"]} then {
- exec mkdir "$HOME/.tk"
- # above should have error-checking
- }
- exec jabbrevs "$HOME/.tk/abbrevs.tcl" & ;# doesn't currently use arg
- }
-
- ######################################################################
- # read abbrevs file
- ######################################################################
-
- proc jedit:cmd:read_abbrevs { args } {
- j:source_config abbrevs.tcl
- }
-
- ######################################################################
- # toggle static abbrevs
- ######################################################################
-
- proc jedit:cmd:toggle_sabbrev { t args } {
- global JEDIT_MODEPREFS
-
- set mode [jedit:get_mode $t]
-
- set JEDIT_MODEPREFS($mode,sabbrev) \
- [expr {! $JEDIT_MODEPREFS($mode,sabbrev)}]
- }
-
- ######################################################################
- # toggle dynamic abbrevs
- ######################################################################
-
- proc jedit:cmd:toggle_dabbrev { t args } {
- global JEDIT_MODEPREFS
-
- set mode [jedit:get_mode $t]
-
- set JEDIT_MODEPREFS($mode,dabbrev) \
- [expr {! $JEDIT_MODEPREFS($mode,dabbrev)}]
- }
-
- ######################################################################
- # go to a particular line
- ######## NEED TO CHECK THAT AN INDEX WAS TYPED!
- ######################################################################
-
- proc jedit:cmd:go_to_line { t args } {
- set prompt_result [j:prompt -text "Go to line number:"]
- if {$prompt_result != {}} then {
- jedit:go_to_line $t $prompt_result
- }
- }
-
- ######################################################################
- # display which line the cursor is on
- ######################################################################
-
- proc jedit:cmd:current_line { t args } {
- set insertindex [split [$t index insert] {.}]
- set line [lindex $insertindex 0]
- set column [lindex $insertindex 1]
- j:alert -title "Notice" \
- -text "The insertion point is at line $line, column $column."
- }
-
- ######################################################################
- # insert X selection
- ######################################################################
-
- proc jedit:cmd:xpaste { t args } {
- set mode [jedit:get_mode $t]
-
- jedit:cmd:save_checkpoint $t ;# save undo information
-
- if {[info procs mode:$mode:pre_xpaste_hook] != {}} {
- mode:$mode:pre_xpaste_hook $t
- }
-
- j:text:insert_string $t [j:selection_if_any]
-
- if {[info procs mode:$mode:post_xpaste_hook] != {}} {
- mode:$mode:post_xpaste_hook $t
- }
- }
-
- ######################################################################
- # front end for j:find to match jedit:cmd argument convention
- ######################################################################
-
- proc jedit:cmd:find { t args } {
- jedit:cmd:save_checkpoint $t
- j:find $t
- }
-
- ######################################################################
- # find same string again (same kind of search)
- ######################################################################
-
- proc jedit:cmd:find_again { t args } {
- jedit:cmd:save_checkpoint $t
- j:find:again $t
- }
-
- ######################################################################
- # hacks for more-specific kinds of finds (for vi/emacs bindings)
- ### BOGUS! jedit should not need to know about the internals of j:find!
- ######################################################################
-
- proc jedit:cmd:find_forward { t args } {
- global j_find
- set j_find(backwards) 0
- j:find $t
- }
-
- proc jedit:cmd:find_backward { t args } {
- global j_find
- set j_find(backwards) 1
- j:find $t
- }
-
- ######################################################################
- # save all windows and quit
- ######################################################################
-
- # we need to make sure there's a filename before calling save, because
- # a cancel in the saveas file selector box will cancel the save, but
- # not the quit!
-
- proc jedit:cmd:done { t args } {
- set mode [jedit:get_mode $t]
-
- if {[info procs mode:$mode:done] == {}} {
- set filename [jedit:get_filename $t]
- if {"x$filename" == "x"} then {
- set filename [j:fs -prompt "Save as:"]
- if {"x$filename" == "x"} { ;# user clicked cancel
- return
- } else {
- jedit:set_filename $t $filename
- }
- }
-
- jedit:cmd:save $t
- jedit:cmd:close $t
- } else {
- mode:$mode:done $t
- }
- }
-
- ######################################################################
- # panel to let user insert any iso-8859 character
- ######################################################################
-
- proc jedit:cmd:char_panel { t args } {
- set tl [j:new_toplevel .high_bit]
- wm title $tl "Characters"
-
- message $tl.m -aspect 350 \
- -text "Click on a character to insert it."
- text $tl.t -width 16 -height 12 -wrap none \
- -cursor top_left_arrow \
- -font -*-courier-bold-r-normal-*-*-140-* \
- -borderwidth 2 -relief groove
-
- # using j:buttonbar for visual consistency:
- j:buttonbar $tl.b -buttons {
- {ok Done {}}
- }
- $tl.b.ok configure -command "destroy $tl"
-
- for {set i 32} {$i < 112} {incr i 16} {
- for {set j 0} {$j < 16} {incr j} {
- $tl.t insert end [format %c [expr {$i + $j}]]
- }
- $tl.t insert end "\n"
- }
- for {set j 112} {$j < 127} {incr j} {
- $tl.t insert end [format %c $j]
- }
- $tl.t insert end " \n "
- for {set i 160} {$i < 256} {incr i 16} {
- for {set j 0} {$j < 16} {incr j} {
- $tl.t insert end [format %c [expr {$i + $j}]]
- }
- $tl.t insert end "\n"
- }
- $tl.t configure -state disabled
-
- pack $tl.m -fill x
- pack $tl.t -padx 10
- pack $tl.b -anchor e
-
- bind $tl.t <ButtonRelease-1> "
- j:text:insert_string $t \[%W get @%x,%y\]
- "
- foreach event {
- <ButtonRelease-3> <B3-Motion> <Button-3> <ButtonRelease-2>
- <ButtonRelease-1><B2-Motion> <Button-2> <Shift-B1-Motion>
- <Shift-Button-1> <B1-Motion> <Triple-Button-1> <Double-Button-1>
- <Button-1>
- } {
- bind $tl.t $event {;}
- }
- }
-
- ######################################################################
- # insert a hyphen
- ######################################################################
-
- proc jedit:cmd:hyphen { t args } {
- j:text:insert_string $t "\xad"
- }
-
- ######################################################################
- # insert a copyright symbol
- ######################################################################
-
- proc jedit:cmd:copyright { t args } {
- j:text:insert_string $t "\xa9"
- }
-
- ######################################################################
- # rich-text cut
- ######################################################################
-
- proc jedit:cmd:rich_cut { t } {
- jedit:cmd:rich_copy $t ;# (saves checkpoint)
- $t delete sel.first sel.last
- }
-
- ######################################################################
- # rich-text copy
- ######################################################################
-
- proc jedit:cmd:rich_copy { t } {
- global RICHBUFFER
-
- jedit:cmd:save_checkpoint $t ;# save undo information
-
- set RICHBUFFER {}
- set curstring {}
- set curtags [$t tag names sel.first]
-
- $t mark set richptr sel.first
-
- while {[$t compare richptr < sel.last]} {
- set tags [$t tag names richptr]
- set char [$t get richptr]
- if {"x$tags" != "x$curtags"} { ;# new "range" of text
- lappend RICHBUFFER [list $curstring $curtags]
- set curstring $char
- set curtags $tags
- } else {
- append curstring $char
- }
- $t mark set richptr {richptr+1c}
- }
- lappend RICHBUFFER [list $curstring $curtags]
- return
- }
-
- ######################################################################
- # rich-text paste
- # partly lifted from insertWithTags in mkStyles.tcl demo
- ######################################################################
-
- proc jedit:cmd:rich_paste { t } {
- global RICHBUFFER
-
- jedit:cmd:save_checkpoint $t ;# save undo information
-
- lappend RICHBUFFER {} ;# make sure it's defined
-
- foreach pair $RICHBUFFER {
- set text [lindex $pair 0]
- set tags [lindex $pair 1]
-
- set start [$t index insert]
- $t insert insert $text
- foreach tag [$t tag names $start] {
- $t tag remove $tag $start insert ;# clear tags inherited from left
- }
- foreach tag $tags {
- $t tag add $tag $start insert ;# add new tags
- }
- }
- $t tag remove sel 1.0 end ;# clear selection (guaranteed in text)
- return
- }
-