### Copyright (C) 1996 Per Zacho
### This program is free software; you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation; either version 2 of the License, or
### (at your option) any later version.
###
### This program is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with this program; if not, write to the Free Software
### Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

proc bindKey {} {
    # User<->Bash interface / Keyboard bindings

    Desc "This configuration page will help you to setup keyboard bindings and macros. To make a new"\
	    "binding, please press the tre arrows in lower right corner."

    ShortDesc "Keyboard bindings"

    ### Keyboard macro ###

    Header head1 -text "Keyboard macro"\
	    -background gray\
	    -help "Setup of keyboard bindings and macros."

    Label index -text "Key 'sequence:binding': "\
	    -help "Setup of specific key combination."

    ### Key combination ###

    FillOutElm meta -text "Meta prefix"\
	    -show {print "<Meta>-"}\
	    -save {print "\\M-"}\
	    -help "When invoking keyboard macro, hold down \"Meta\" key (or press \"Escape\") and"\
	    "press the following key."

    FillOutElm control -text "Control prefix"\
	    -show {print "<Control>-"}\
	    -save {print "\\C-"}\
	    -help "When invoking keyboard macro, hold down \"Control\" key and press the"\
	    "following key."

    FillOutElm metacontrol -text "Meta-Control prefix"\
	    -show {print "<Meta+Control>-"}\
	    -save {print "\\M-\\C-"}\
	    -help "When invoking keyboard macro, hold down both \"Meta\" and \"Control\" keys at"\
	    "the same time (or press \"Escape\" and then hold down \"Control\"), then press the"\
	    "key following the dash."

    FillOutElm escape -text ""\
	    -show {print "<Escape>"}\
	    -save {print "\\e"}\
	    -help "When invoking keyboard macro, press \"Escape\" key and release, then press the"\
	    "following key."

    ### Other keys ###

    FillOutElm note -text "*** Elements below may not have prefixes ***"\
	    -show {print ""}\
	    -save {print ""}\
	    -help "Elements below are to be used individually, and for the majority, without"\
	    "prefixes of any kind--if in doubt; try.\nNOTE: depending on your keybindings, these"\
	    "predefined scancodes may not work. You can see the scancodes if you type the following"\
	    "in a shell:\ncat > scancode.txt\n(type the key(s) you want to check)\nCTRL-d (this is"\
	    "an EOF marker)\nless scancode.txt"

    FillOutElm tab -text "\"TAB\" key"\
	    -show {print "<TAB>"}\
	    -save {print "\\C-i"}\
	    -help "Tabulator: You can only use Meta-key as prefix."

    FillOutElm func1 -text "Function key 1"\
	    -show {print "<Func.key\#1>"}\
	    -save {print "\\e\[11~"}\
	    -help "Function key 1: No prefixes allowed."

    FillOutElm func2 -text "Function key 2"\
	    -show {print "<Func.key\#2>"}\
	    -save {print "\\e\[12~"}\
	    -help "Function key 2: No prefixes allowed."

    FillOutElm func3 -text "Function key 3"\
	    -show {print "<Func.key\#3>"}\
	    -save {print "\\e\[13~"}\
	    -help "Function key 3: No prefixes allowed."

    FillOutElm func4 -text "Function key 4"\
	    -show {print "<Func.key\#4>"}\
	    -save {print "\\e\[14~"}\
	    -help "Function key 4: No prefixes allowed."

    FillOutElm func5 -text "Function key 5"\
	    -show {print "<Func.key\#5>"}\
	    -save {print "\\e\[15~"}\
	    -help "Function key 5: No prefixes allowed."

    FillOutElm func6 -text "Function key 6"\
	    -show {print "<Func.key\#6>"}\
	    -save {print "\\e\[17~"}\
	    -help "Function key 6: No prefixes allowed."

    FillOutElm func7 -text "Function key 7"\
	    -show {print "<Func.key\#7>"}\
	    -save {print "\\e\[18~"}\
	    -help "Function key 7: No prefixes allowed."

     FillOutElm func8 -text "Function key 8"\
	    -show {print "<Func.key\#8>"}\
	    -save {print "\\e\[19~"}\
	    -help "Function key 8: No prefixes allowed."

    FillOutElm func9 -text "Function key 9"\
	    -show {print "<Func.key\#9>"}\
	    -save {print "\\e\[20~"}\
	    -help "Function key 9: No prefixes allowed."

    FillOutElm func10 -text "Function key 10"\
	    -show {print "<Func.key\#10>"}\
	    -save {print "\\e\[21~"}\
	    -help "Function key 10: No prefixes allowed."

    FillOutElm func11 -text "Function key 11"\
	    -show {print "<Func.key\#11>"}\
	    -save {print "\\e\[23~"}\
	    -help "Function key 11: No prefixes allowed."

    FillOutElm func12 -text "Function key 12"\
	    -show {print "<Func.key\#12>"}\
	    -save {print "\\e\[24~"}\
	    -help "Function key 12: No prefixes allowed."

    ##############################
    ### More keys may be added ###
    ##############################

    set keys {meta control metacontrol escape note tab func1 func2 func3 func4 func5 func6 func7 func8 func9 func10 func11 func12}

    FillOut key -text ""\
	    -entries $keys\
	    -help "Construct key sequence to invoke built-in command or macro"\
	    -packFrame:fill x\
	    -listbox:width 50

    ### Built-in command ###

    ListBox builtin -text "Built-in commands"\
	    -entryhelp {"* COMMANDS FOR MOVING *" ""\
	    "beginning-of-line" "Move to the start of the current line."\
	    "end-of-line" "Move to the end of the line."\
	    "forward-char" "Move forward a character."\
	    "backward-char" "Move back a character."\
	    "forward-word" "Move forward to the end of the next word. (word = letters and digits)"\
	    "backward-word" "Move back to the start of this, or previous, word. (word = letters and digits)"\
	    "clear-screen" "Clear the screen leaving the current line at the top of the screen. With an argument, refresh the current line without clearing the screen"\
	    "redraw-current-line" "Refresh the current line."\
	    "* COMMANDS FOR MANIPULATING HISTORY *" ""\
	    "accept-line" "Accept the line regardless of where the cursor is. If this line is non-empty, add it to the history list."\
	    "previous-history" "Fetch the previous command from the history list, moving back in the list."\
	    "next-history" "Fetch the next command from the history list, moving forward in the list."\
	    "beginning-of-history" "Move to the first line in the history."\
	    "end-of-history" "Move to the end of the input history, i.e., the line currently being entered"\
	    "reverse-search-history" "Search backward starting at the current line and moving 'up' through the history as necessary. This is an incremental search."\
	    "forward-search-history" "Search forward starting at the current line and moving 'down' through the history as necessary. This is an incremental search."\
	    "non-incremental-reverse-search-history" "Search backward through the history starting at the current line using a non-incremental search for a string supplied by the user."\
	    "non-incremental-forward-search-history" "Search forward through the history using a non-incremental search for a string supplied by the user."\
	    "history-search-forward" "Search forward through the history for the string of characters between the start of the current line and the current point. This is a non-incremental search."\
	    "history-search-backward" "Search backward through the history for the string of characters between the start of the current line and the current point. This is a non-incremental search."\
	    "yank-nth-arg" "Insert the first argument to the previous command (usually the second word on the previous line) at point (the current cursor position). With an argument n, insert the nth word from the previous command (the words in the previous command begin with word 0). A netative argument inserts the nth word from the end of the previous command."\
	    "yank-last-arg" "Insert the last argument to the previous command (the last word on the previous line). With an argument, behave exactly like yank-nth-arg."\
	    "shell-expand-line" "Expand the line the way the shell does when it reads it. This performs alias and history expansion as well as all of the shell word expansions."\
	    "history-expand-line" "Perform history expansion on the current line."\
	    "insert-last-argument" "A synonym for yank-last-arg."\
	    "operate-and-get-next" "Accept the current line for execution and fetch the next line relative to the current line from the history for editing. Any argument is ignored."\
	    "* COMMANDS FOR CHANGING TEXT *" ""\
	    "delete-char" "Delete the character under the cursor. If point is at the beginning of the line, there are no characters in the line, and the last character typed was not \"delete-char\", then return EOF."\
	    "backward-delete-char" "Delete the character behind the cursor. When given a numeric argument, save the deleted text on the kill-ring."\
	    "quoted-insert" "Add the next character that you type to the line verbatim."\
	    "tab-insert" "Insert a tab character."\
	    "self-insert" "Insert the character typed."\
	    "transpose-chars" "Drag the character before point forward over the character at point. Point moves forward as well. If point is at the end of the line, then transpose the two characters before point. Negative arguments don't work."\
	    "transpose-words" "Drag the word behind the cursor past the word in front of the cursor moving the cursor over that word as well."\
	    "upcase-word" "Uppercase the current (or following) word. With a negative argument, do the previous word, but do not move point."\
	    "downcase-word" "Lowercase the current (or following) word. With a negative argument, do the previous word, but do not move point."\
	    "capitalize-word" "Capitalize the current (or following) word. With a negative argument, do the previous word, but do not move point."\
	    "* KILLING AND YANKING *" ""\
	    "kill-line" "Kill the text from the current cursor position to the end of the line."\
	    "backward-kill-line" "Kill backward to the beginning of the line."\
	    "unix-line-discard" "Kill backward from point to the beginning of the line."\
	    "kill-whole-line" "Kill all characters on the current line, no matter where  the cursor is."\
	    "kill-word" "Kill from the cursor to the end of the current word, or if between words, to the end of the next word. Word boundaries are the same as those used by forward-word."\
	    "backward-kill-word" "Kill the word behind the cursor. Word boundaries are the same as those used by backward-word."\
	    "unix-word-rubout" "Kill the word behind the cursor, using white space as a word boundary. The word boundaries are different from backward-kill-word."\
	    "delete-horizontal-space" "Delete all spaces and tabs around point."\
	    "yank" "Yank the top of the kill ring into the buffer a the cursor."\
	    "yank-pop" "Rotate the kill-ring, and yank the new top. Only works following yank or yank-pop."\
	    "* NUMERIC ARGUMENTS *" ""\
	    "digit-argument" "Add this digit to the argument already accumulating, or start a new argument. M-- starts a negative argument."\
	    "universal-argument" "Each time this is executed, the argument count is multiplied by four. The argument count is initially one, so executing this function the first time makes the argument count four."\
	    "* COMPLETING *" ""\
	    "complete" "Attempt to perform completion on the text before point."\
	    "possible-completions" "List the possible completions of the text before point."\
	    "insert-completions" "Insert all completions of the text before point that would have been generated by possible-completions."\
	    "complete-filename" "Attempt filename completion on the text before point."\
	    "possible-filename-completions" "List the possible completions of the text before point, treating it as a filename."\
	    "complete-username" "Attempt completion on the text before point, treating it as a username."\
	    "possible-username-completions" "List the possible completions of the text before point, treating it as a username."\
	    "complete-variable" "Attempt completion on the text before point, treating it as a shell variable."\
	    "possible-variable-completions" "List the possible completions of the text before point, treating it as a shell variable."\
	    "complete-hostname" "Attempt completion on the text before point, treating it as a hostname."\
	    "possible-hostname-completions" "List the possible completions of the text before point, treating it as a hostname."\
	    "complete-command" "Attempt completion on the text before point, treating it as a command name."\
	    "possible-command-completions" "List the possible completions of the text before point, treating it as a command name."\
	    "dynamic-complete-history" "Attempt completion on the text before point, comparing the text against lines from the history list for possible completion matches."\
	    "complete-into-braces" "Perform filename completion and return the list of possible completions enclosed within braces so the list is available to the shell."\
	    "* KEYBOARD MACROS *" ""\
	    "start-kbd-macro" "Begin saving the characters typed into the current keyboard macro."\
	    "end-kbd-macro" "Stop saving the characters typed into the current keyboard macro and save the definition."\
	    "call-last-kbd-macro" "Re-execute the last keyboard macro defined, by making the characters in the macro appear as if typed at the keyboard."\
	    "* MISCELLANEOUS *" ""\
	    "re-read-init-file" "Read in the contents of your init file, and incorporate any bindings or variable assignments found there."\
	    "abort" "Abort the current editing command and ring the terminal's bell."\
	    "do-uppercase-version" "Run the command that is bound to the corresponding uppercase character."\
	    "prefix-meta" "Metafy the next character typed."\
	    "undo" "Incremental undo, separately remembered for each line."\
	    "revert-line" "Undo all changes made to this line."\
	    "tilde-expand" "Perform tilde expansion on the current word."\
	    "dump-functions" "Print all of the functions and their key bindings to the readline output stream."\
	    "display-shell-version" "Display version information about the current instance of bash."}\
	    -help "Choose a built-in command to bind to your key sequence."\
	    -listbox:selectmode singe\
	    -packFrame:fill x\
	    -listbox:width 50

    CheckBox quest1 -text "Make a userdefined text/command"\
	    -default 0

    Line line1

    ### User defined text/command ###

    FillOutElm Umeta -text "Meta prefix"\
	    -show {print "<Meta>-"}\
	    -save {print "\\M-"}\
	    -help "Activate \"Meta\" prefix commands."

    FillOutElm Ucontrol -text "Control prefix"\
	    -show {print "<Control>-"}\
	    -save {print "\\C-"}\
	    -help "Activate \"Control\" prefix commands."

    FillOutElm Uescape -text "Escape prefix"\
	    -show {print "<Escape>"}\
	    -save {print "\\e"}\
	    -help "Activate \"Escape\" prefix commands."

    FillOutElm Ubackslash -text "Backslash (\\\)"\
	    -show {print "<\\>"}\
	    -save {print "\\\\"}\
	    -help "Print a backslash."

    FillOutElm UliteralS -text "Single quote (')"\
	    -show {print "<'>"}\
	    -save {print "\\'"}\
	    -help "Print a single quoute."

    FillOutElm UliteralD -text "Double quote (\")"\
	    -show {print "<\">"}\
	    -save {print "\\\""}\
	    -help "Print a double quote."

    FillOutElm Uret -text "\"Return\"/\"Enter\" key"\
	    -show {print "<Return>"}\
	    -save {print "\\C-m"}\
	    -help "Execute commands till this point."

    ##############################
    ### More keys may be added ###
    ##############################

    set comm {Umeta Ucontrol Uescape Ubackslash UliteralS UliteralD Uret}

    FillOut userdef -text "Userdefined text/command"\
	    -entries $comm\
	    -help "Setup your keyboard shortcut--either just text (e.g. sentences often used) or"\
	    "command lines (remember to end these with af \"Return/Enter\""\
	    -packFrame:fill x\
	    -listbox:width 50

    ##############################

    ExtEntry bindkey -text ""\
	    -entries {index key builtin quest1 line1 userdef}\
	    -count 1\
	    -orient top\
	    -index index

    Init {
	forevery bindkey {
	    if {$quest1} {
		Disable builtin
		Enable userdef
	    } {
		Enable builtin
		Disable userdef
	    }
	    if {$key != ""} {
		set index "$key : [pick $quest1 "\"$userdef\"" $builtin(name)]"
	    }
	}
    }

    Change {
	if {$changeElm == "head1"} {return}
	if {$changeElm == "builtin"} {
	    switch $builtin(index) {
		0 {set builtin(name) ""}
		9 {set builtin(name) ""}
		27 {set builtin(name) ""}
		38 {set builtin(name) ""}
		49 {set builtin(name) ""}
		52 {set builtin(name) ""}
		68 {set builtin(name) ""}
		72 {set builtin(name) ""}
	    }
	}
	if {$changeElm != "key" && $key != ""} {
	    set index "$key : [pick $quest1 "\"$userdef\"" $builtin(name)]"
	} {
	    set index "Construct key sequence"
	}
	if {$changeElm == "builtin" && $key == ""} {
	    set builtin(name) ""
	}
	if {$changeElm == "quest1" && $key == ""} {
	    set quest1 0
	}
	if {$quest1} {
	    Disable builtin
	    Enable userdef
	} {
	    Enable builtin
	    Disable userdef
	}
    }

    PageEnd {
	set temp 0
	forevery bindkey {
	    incr temp
	    if {$key == ""} {
		if {$quest1} {
		    if {$userdef != ""} {
			error "You have defined a user text/command but no key sequence in line $temp"
		    }
		} {
		    if {$builtin(index) > 0} {
			error "You have chosen a built-in command but no key sequence in line $temp"
		    }
		}
	    } {
		if {$quest1} {
		    if {$userdef == ""} {
			error "You have defined a key sequence but no text/command in line $temp"
		    }
		}
	    }
	}
    }


    Save {
	forevery bindkey {
	    if {$key != ""} {
		print -file inputrc "\"$key\":[pick $quest1 "\"$userdef\"" $builtin(name)]"
	    }
	}
    }    
}

