[Tkabber-dev] r1256 - in trunk/tkabber-plugins: . ctcomp

tkabber-svn at jabber.ru tkabber-svn at jabber.ru
Sun Oct 7 16:27:47 MSD 2007


Author: sergei
Date: 2007-10-07 16:27:46 +0400 (Sun, 07 Oct 2007)
New Revision: 1256

Added:
   trunk/tkabber-plugins/ctcomp/
   trunk/tkabber-plugins/ctcomp/AUTHORS
   trunk/tkabber-plugins/ctcomp/ChangeLog
   trunk/tkabber-plugins/ctcomp/INSTALL
   trunk/tkabber-plugins/ctcomp/README
   trunk/tkabber-plugins/ctcomp/TODO
   trunk/tkabber-plugins/ctcomp/VERSION
   trunk/tkabber-plugins/ctcomp/ctcomp.tcl
   trunk/tkabber-plugins/ctcomp/license.terms
Modified:
   trunk/tkabber-plugins/ChangeLog
Log:
	* ctcomp/*: Added new plugin which allow to complete words from chat
	  log windows (thanks to Konstantin Khomoutov).


Modified: trunk/tkabber-plugins/ChangeLog
===================================================================
--- trunk/tkabber-plugins/ChangeLog	2007-10-07 10:44:47 UTC (rev 1255)
+++ trunk/tkabber-plugins/ChangeLog	2007-10-07 12:27:46 UTC (rev 1256)
@@ -7,6 +7,9 @@
 	* floatinglog/TODO: Removed tasks which are already done or will never
 	  be done.
 
+	* ctcomp/*: Added new plugin which allow to complete words from chat
+	  log windows (thanks to Konstantin Khomoutov).
+
 2007-10-06  Sergei Golovan <sgolovan at nes.ru>
 
 	* browser/browser.tcl: Replaced ::jlib::route by the first connection

Added: trunk/tkabber-plugins/ctcomp/AUTHORS
===================================================================
--- trunk/tkabber-plugins/ctcomp/AUTHORS	                        (rev 0)
+++ trunk/tkabber-plugins/ctcomp/AUTHORS	2007-10-07 12:27:46 UTC (rev 1256)
@@ -0,0 +1 @@
+Konstantin Khomoutov <flatworm at users.sourceforge.com>


Property changes on: trunk/tkabber-plugins/ctcomp/AUTHORS
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Added: trunk/tkabber-plugins/ctcomp/ChangeLog
===================================================================
--- trunk/tkabber-plugins/ctcomp/ChangeLog	                        (rev 0)
+++ trunk/tkabber-plugins/ctcomp/ChangeLog	2007-10-07 12:27:46 UTC (rev 1256)
@@ -0,0 +1,48 @@
+2007-10-07  Konstantin Khomoutov  <flatworm at users.sourceforge.net>
+
+	* Heavily redone using bindtags and virtual events.
+
+	* Behaviour and keybindings are made more close to Vim/Emacs.
+
+	* Added possibility to show a menu with possible completions.
+
+	* Numerous bugfixes.
+
+	* README re-written.
+
+	* Now at version 2.0.
+
+
+2007-02-25  Konstantin Khomoutov  <flatworm at users.sourceforge.net>
+
+	* Fixed bug occured when chatting with JIDs containing
+	  the "%s" character.
+
+	* Stub ChangeLog file rewritten to reflect this project' state.
+
+
+2007-02-18  Konstantin Khomoutov  <flatworm at users.sourceforge.net>
+
+	* Added support for Customize.
+
+	* Misc bugfixes.
+
+	* Added preliminary support for virtual events.
+
+	* Added preliminary support for event validity checking.
+
+	* Support for per-chat state.
+
+	* Matching algorythm reworked.
+
+	* Added keybindings for committing and cancelling the current match.
+
+	* Proper deinitialization of completion mode.
+
+	* Added files: AUTHORS, README, TODO, INSTALL, ChangeLog and license.terms
+
+
+2007-02-15  Konstantin Khomoutov  <flatworm at users.sourceforge.net>
+
+	* Initial version.
+


Property changes on: trunk/tkabber-plugins/ctcomp/ChangeLog
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Added: trunk/tkabber-plugins/ctcomp/INSTALL
===================================================================
--- trunk/tkabber-plugins/ctcomp/INSTALL	                        (rev 0)
+++ trunk/tkabber-plugins/ctcomp/INSTALL	2007-10-07 12:27:46 UTC (rev 1256)
@@ -0,0 +1,9 @@
+As usually, copy this directory under the ~/.tkabber/plugins directory
+so that you get a hierarchy like this:
+  ~/.tkabber/plugins
+  ~/.tkabber/plugins/ctcomp/
+  ~/.tkabber/plugins/ctcomp/ctcomp.tcl
+
+Restart Tkabber, to get the plugin loaded.
+Consult the README file for the details about using this plugin.
+


Property changes on: trunk/tkabber-plugins/ctcomp/INSTALL
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Added: trunk/tkabber-plugins/ctcomp/README
===================================================================
--- trunk/tkabber-plugins/ctcomp/README	                        (rev 0)
+++ trunk/tkabber-plugins/ctcomp/README	2007-10-07 12:27:46 UTC (rev 1256)
@@ -0,0 +1,347 @@
+$Id$
+"Chat text completions" -- chat plugin for Tkabber.
+
+I. The idea
+
+This plugin adds support for "text completion" in Tkabber's chat
+input windows, i.e. it's possible to make Tkabber offer you
+possible completions of a current partially typed word in a chat
+input window. Possible completions are looked up in both the
+input window and the chat log window (also it's possible to
+provide custom list of matches, see the "Customization"
+section).
+
+This feature is loosely modeled after the text completion
+implementations found in Vim [1] and Emacs [2] text editors;
+default text completion key bindings of this plugin are the same
+as default key bindings for this feature in those editors (see
+the "Using" section).
+
+Note though, that while both Vim and Emacs offer you possible
+completions in a "recently typed -- first" manner, this
+plugin offers them in a dictionary-sorted order.
+
+
+II. Using
+
+At first, note that we'll use "Emacsish" notation of describing
+keystrokes for the sake of brevity. For those who isn't familiar
+with it here's a quick explanation:
+* "C" stands for "Control" key (also known as "Ctrl").
+* "M" stands for "Meta" key (also known as "Alt" on some
+  computers/OSes).
+* Any other key symbols stand for themselves.
+* Key combinations (groups of keys that are required to be
+  pressed simultaneously) are specified as a list of appropriate
+  key symbols joined by dashes ("-"). For example, "C-M-a"
+  stands for Control, Meta (Alt) and "a" keys pressed
+  simultaneously.
+
+There are two major modes of operation possible:
+* Requesting menu with possible completions.
+* Traversing the list of possible completions "in place".
+
+Entering each mode is requested by pressing one of the available
+keystrokes (discussed below) just after the first character(s)
+of a word you want to complete.
+For example, suppose the current chat log window and/or the
+current input window contain these words: abba, abbot,
+abbatisse. Now suppose you have just typed "ab" and want to
+complete it -- type C-M-/ to get the menu listing top 20 words
+starting from "ab" found in mentioned windows or type C-n to
+enter the "in place" mode and get the first proposed completion
+right at your insert cursor (with the completed part visually
+emphasized). Any completion mode can be cancelled -- you return
+to that piece of the word you started with.
+The completion keybindings will be described just in a moment.
+
+So, let's recap:
+* Type some first letters of the word you want to complete,
+* Engage one of the available completion modes.
+* Pick the required completion or chancel the completion mode.
+
+1. Using the completion menu
+
+The menu presenting the first 20 completions can be by default
+posted using C-M-/ gesture. Select whatever completion you're
+happy with or cancel the menu by clicking outside of it or
+pressing the <Escape> key. If you have selected a completion,
+the word being completed in the input window will be replaced by
+the selected completion. If you have cancelled the completion
+menu no change will be made to the input window.
+
+This gesture is modeled after the Emacs text editor.
+
+2. Using the "in place" traversing of possible completions
+
+This mode is modeled after the similar Vim text editor's
+facility and so the C-n and C-p keystrokes are used. They switch
+the input windows into the "completion mode" and insert the
+first or the last completion from the list of proposed
+completions at the insert cursor. The completed part of the
+inserted word is highlighted.
+
+Also the M-/ keystroke is equivalent to C-n -- this one is taken
+from Emacs.
+
+While being in the completion mode you can:
+* Continue using the C-n (and/or M-/) and C-p keystrokes to
+  iterate through the list of proposed completions "up" and
+  "down", respectively.
+* Hit the Return (Enter) key to accept the currently displayed
+  completion and return to the normal editing mode.
+* Hit the Escape key to remove the currently displayed
+  completion and return to the normal mode. In other words this
+  cancels the completon mode.
+
+Hitting any other key not listed above (i.e. a key which doesn't
+have special meaning in the completion mode) accepts the
+currently displayed completion, returns the input window to the
+normal mode, and then this keystroke is passed to the input
+window so that if it would result in a printable character being
+inserted this character will be inserted just after the
+completed word.
+
+
+III. Customization
+
+1. Keystrokes
+
+All the relevant bindings in Tkabber's chat input windows are
+done via Tk virtual events [3] so they are easily customizable.
+Here are these events and their default bindings:
+
+* Event: <<ChatTextCompNext>>
+  Default bindings: <Control-n>, <Alt-slash>, <Meta-slash>
+  Action: show next possible completion "in place",
+  activate the "in place" completion mode beforehang,
+  if currently in the normal mode.
+
+* Event: <<ChatTextCompPrev>>
+  Default bindings: <Control-p>
+  Action: same as above but shows the previous possible
+  completion.
+
+* Event: <<ChatTextCompAccept>>
+  Default keybindings: <Return>
+  Action: accept the completion currently proposed "in place"
+  and return to normal mode.
+
+* Event: <<ChatTextCompCancel>>
+  Default keybindings: <Escape>
+  Action: remove the completion currently proposed "in place"
+  and return to normal mode.
+
+* Event: <<ChatTextCompMenu>>
+  Default keybindings: <Alt-Control-slash>, <Meta-Control-slash>
+  Action: show menu with possible completions.
+
+
+If you're not familiar with Tk [event] [3] and [bind] [4]
+commands, here's a quick reference:
+
+* To bind your keystroke to a virtual event use
+  event add <<...event name...>> <...keystroke spec...>
+  For example, to bind posting of the completion menu to the F5
+  key, put this in the Tkabber's config file:
+  event add <<ChatTextCompMenu>> <F5>
+
+* To unbind existing binding from a virtual event use
+  event delete <<...event name...>> <...keystroke spec...>
+  For example to make the completion menu only be posted by the
+  F5 key, add also this lines to the config file:
+  event delete <<ChatTextCompMenu>> <Alt-Control-slash>
+  event delete <<ChatTextCompMenu>> <Meta-Control-slash>
+
+* To "substitute" (all) the default bindings for a virtual event
+  by yours you can use something like this:
+  event delete <<ChatTextCompMenu>>
+  event add <<ChatTextCompMenu>> <F5>
+  The first line kills all bindings for the virtual event, the
+  second adds one new.
+
+Be sure to read and understand [3] and [4] before proceeding!
+
+Specification of keystrokes is explained in [4], all keysyms
+known to Tk are listed in [5].
+
+Note that due to a bug in the Windows port of Tk users of non-US
+keymaps in this OS can have problems with these shortcuts.
+Please read "Working around Tk Windows keyboard bug" below for
+the (partial) solution to this problem.
+
+
+2. Highlighting colors of "in place" completion
+
+Two Tk option database resources are used, both are of class
+"Chat":
+
+* Resource: Chat.textCompletionForeground
+  Default: black
+  Meaning: foreground color of the "proposed" tail of the word
+  being completed "in place".
+
+* Resourec: Chat.textCompletionBackground
+  Default: pink
+  Meaning: same as above but for the background color.
+
+
+3. Search pattern
+
+The search pattern used to search for possible completions in Tk
+Text widgets is available via the
+::plugins::ctcomp::options(pattern) setting.
+
+This is an ARE [6] pattern containing the "%s" token which is
+replaced before searching by the part of the word being
+completed. This pattern makes the searching engine to look for
+"any word starting with the specified letters".
+
+Note that you should think twice before changing this pattern:
+for example the "in place" completion mode assumes that
+completions start from the prefix being completed and if you,
+say, change the pattern so that it will match in a middle of
+words, you'll get unexpected results in this completion mode.
+
+
+4. Hooks
+
+This plugin has four "hooks" [7] that run when certain chat text
+completion events occur. They can be used to fine-tune the
+operation of this plugin. Beware though that using them requires
+some knowledge of Tcl.
+
+These hooks are:
+
+* chat_text_completion_start_hook
+  This hook is run when the plugin enters the "in place"
+  completion mode and is about to show the first proposed
+  completion.
+  Two arguments are appended to the hook script before
+  evaluation:
+  * handle to the chat in which the completion
+    mode is entered (usually referred to as "chatid").
+  * word being completed.
+
+  Primary intent of this hook (and its "mirror" hook
+  chat_text_completion_end_hook) is to be used to provide some
+  sort of additional visual hint to the user indicating active
+  "in place" completion mode.
+
+* chat_text_completion_end_hook
+  This hook is run when the plugin leaves the "in place"
+  completion mode.
+  One argument is appended to the hook script before
+  evaluation -- handle to the chat ("chatid").
+
+* chat_text_completion_matches_hook
+  This hook is run when the plugin builds a list of possible
+  completions for the word being completed, just after the
+  proposed completions have been gathered from the relevant
+  input and chat log windows.
+  Four arguments are appended to the hook script before
+  evaluation:
+  * handle to the chat in which the completion
+    mode is entered ("chatid").
+  * word being completed.
+  * stack level containing the variable with proposed
+    completions.
+  * name of the variable holding a list with proposed
+    completions.
+  To modify this variable inside a proc use the [upvar] command,
+  for example:
+
+  proc gencomp {chatid what level compsName} {
+    upvar $level $compsName comps
+    lappend comps ${what}not ${what}sup
+  }
+  hook::add chat_text_completion_matches_hook gencomp
+
+  Note that scripts handling this hook must not do any
+  assumptions about the list of proposed completions they
+  operate on (like sorted/unsorted, uniquennes of the words,
+  etc).
+
+  Also note that while any strings can be added to the list of
+  possible completions using this hook, the "in place"
+  completion mode assumes that each proposed completion starts
+  from the word being completed; when this assumption is not
+  honored, strange things may happen.
+
+* chat_text_completion_menu_hook
+  This hook is run just before the menu with proposed
+  completions is shown to the user.
+  Three arguments are appended to the hook script before
+  evaluation:
+  * handle to the chat in which the completion
+    mode is entered ("chatid").
+  * word being completed.
+  * name of the menu window populated with proposed completions.
+
+  This hook can be used to tweak the menu before it will be
+  popped up.
+
+
+IV. Limitations and bugs
+
+No "automatic" completion ("propose completions as I type" found
+in certain text editing tools like Writer from the OpenOffice.org
+suite or some mobile phones) is not possible.
+
+The same holds for the "in place" completion mode: typing a
+regular keystroke terminates the completion mode, not narrows
+the list of possible completions (this is Vim-like).
+
+No guarantees of proper work are made if the user fiddles with
+the searching regexp pattern. The same is true for the case when
+the user modifies the list of proposed completion via the
+relevant hook.
+
+Not all completions will be shown in the completion menu if its
+number exceeds the hard-coded limit.
+
+Detecting of a word to be completed in the input window is
+somewhat strange, for example, if you have this string ("|"
+denotes the cursor position):
+so what ??|
+and try to complete, the string "what ??" will be used as the
+completion prefix.
+
+
+V. Working around Tk Windows keyboard bug
+
+Tk has unfortunate long-standing bug which prevents certain
+key combinations involving "letter keys" from working with
+"non-ASCII" keymaps (e.g. Russian keymap) in Windows.
+For example, C-n, C-p, M-/ and C-M-/ work when the US keymap
+is active but don't work when a Russian keymap is.
+
+Users of Russian keymaps may add following lines to their
+config.tcl file to work around this bug:
+
+event add <<ChatTextCompNext>> <Control-ograve>
+event add <<ChatTextCompNext>> <Alt-period>
+event add <<ChatTextCompPrev>> <Control-ccedilla>
+event add <<ChatTextCompMenu>> <Control-Alt-period>
+
+This will make C-n, C-p and C-M-/ to work as expected on both US
+and Russian ("QWERTY") keymaps.
+
+Note that if you change the default bindings you may also need
+to modify these "mirror" bindings. Please refer to the Russian
+Tkabber wiki [8] for more info.
+
+
+VI. Links
+
+1. http://vim.sf.net
+2. http://www.gnu.org/software/emacs/
+3. http://www.tcl.tk/man/tcl8.4/TkCmd/event.htm
+4. http://www.tcl.tk/man/tcl8.4/TkCmd/bind.htm
+5. http://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm
+6. http://www.tcl.tk/man/tcl8.4/TclCmd/re_syntax.htm
+7. http://tkabber.jabber.ru/files/doc/tkabber.html#s.extensibility
+8. http://ru.tkabber.jabe.ru
+
+
+# vim:tw=64:noet


Property changes on: trunk/tkabber-plugins/ctcomp/README
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Added: trunk/tkabber-plugins/ctcomp/TODO
===================================================================
--- trunk/tkabber-plugins/ctcomp/TODO	                        (rev 0)
+++ trunk/tkabber-plugins/ctcomp/TODO	2007-10-07 12:27:46 UTC (rev 1256)
@@ -0,0 +1,12 @@
+$Id$
+
+* Some way should be invented to allow foreground color to be
+  picked up from the input window itself, if not specified
+  directly by the user.
+
+* Finding of a word being completed is a bit broken:
+  for the string "mumble ??_" with the cursor denoted by "_"
+  pressing C-n will yield "mumble ??" instead of "??" or "".
+  So probably something needs to be rethought/fine-tuned.
+
+# vim:tw=64:noet


Property changes on: trunk/tkabber-plugins/ctcomp/TODO
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Added: trunk/tkabber-plugins/ctcomp/VERSION
===================================================================
--- trunk/tkabber-plugins/ctcomp/VERSION	                        (rev 0)
+++ trunk/tkabber-plugins/ctcomp/VERSION	2007-10-07 12:27:46 UTC (rev 1256)
@@ -0,0 +1,2 @@
+Version: 2.0
+Date: 07-Oct-2007


Property changes on: trunk/tkabber-plugins/ctcomp/VERSION
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Added: trunk/tkabber-plugins/ctcomp/ctcomp.tcl
===================================================================
--- trunk/tkabber-plugins/ctcomp/ctcomp.tcl	                        (rev 0)
+++ trunk/tkabber-plugins/ctcomp/ctcomp.tcl	2007-10-07 12:27:46 UTC (rev 1256)
@@ -0,0 +1,346 @@
+# $Id$
+# "Chat text completion -- Tkabber plugin.
+# Written by Konstantin Khomoutov <flatworm at users.sourceforge.net>
+# See "lisence.terms" for details about distribution.
+# Consult README for the information and usage guidelines.
+
+option add *Chat.textCompletionForeground    black   widgetDefault
+option add *Chat.textCompletionBackground    pink    widgetDefault
+
+namespace eval ctcomp {
+    variable options
+
+    set options(pattern) {\m%s\w+\M}
+
+    event add <<ChatTextCompNext>>    <Control-n>
+    event add <<ChatTextCompNext>>    <Alt-slash>
+    event add <<ChatTextCompNext>>    <Meta-slash>
+    event add <<ChatTextCompPrev>>    <Control-p>
+    event add <<ChatTextCompAccept>>  <Return>
+    event add <<ChatTextCompCancel>>  <Escape>
+    event add <<ChatTextCompMenu>>    <Alt-Control-slash>
+    event add <<ChatTextCompMenu>>    <Meta-Control-slash>
+
+    bind ChatTextCompInactive <<ChatTextCompNext>> [namespace code {
+	if {[matches in %W]} {
+	    activate %W
+	    match first next in %W
+	}
+	break
+    }]
+    bind ChatTextCompInactive <<ChatTextCompPrev>> [namespace code {
+	if {[matches in %W]} {
+	    activate %W
+	    match first prev in %W
+	}
+	break
+    }]
+    bind ChatTextCompInactive <<ChatTextCompMenu>> [namespace code {
+	if {[matches in %W]} {
+	    show_matches in %W
+	    reset_state %W
+	}
+	break
+    }]
+
+    bind ChatTextCompActive <<ChatTextCompNext>>   [namespace code {
+	match next next in %W
+	break
+    }]
+    bind ChatTextCompActive <<ChatTextCompPrev>>   [namespace code {
+	match next prev in %W
+	break
+    }]
+    bind ChatTextCompActive <<ChatTextCompAccept>> [namespace code {
+	accept %W
+	deactivate %W
+	break
+    }]
+    bind ChatTextCompActive <<ChatTextCompCancel>> [namespace code {
+	cancel %W
+	deactivate %W
+	break
+    }]
+    bind ChatTextCompActive <Key> [namespace code {
+	accept %W
+	deactivate %W
+    }]
+
+    hook::add open_chat_post_hook [namespace current]::prepare
+}
+
+proc ctcomp::initialize iw {
+    set btags [bindtags $iw]
+    set ix [lsearch -exact $btags $iw]
+    bindtags $iw [linsert $btags $ix ChatTextCompInactive]
+
+    reset_state $iw
+}
+
+proc ctcomp::activate iw {
+    variable $iw
+    upvar 0 $iw state
+
+    set btags [bindtags $iw]
+    set ix [lsearch -exact $btags ChatTextCompInactive]
+    bindtags $iw [lreplace $btags $ix $ix ChatTextCompActive]
+
+    hook::run chat_text_completion_start_hook $state(chatid) $state(what)
+}
+
+proc ctcomp::deactivate iw {
+    variable $iw
+    upvar 0 $iw state
+
+    set btags [bindtags $iw]
+    set ix [lsearch -exact $btags ChatTextCompActive]
+    bindtags $iw [lreplace $btags $ix $ix ChatTextCompInactive]
+
+    hook::run chat_text_completion_end_hook $state(chatid)
+
+    reset_state $iw
+}
+
+proc ctcomp::prepare {chatid type} {
+    variable options
+
+    set iw [chat::input_win $chatid]
+    set cw [chat::chat_win $chatid]
+
+    variable $iw
+    upvar 0 $iw state
+    set state(chatid) $chatid
+
+    initialize $iw
+
+    bind $iw <Destroy> +[list [namespace current]::cleanup $iw %W]
+}
+
+proc ctcomp::cleanup {w1 w2} {
+    if {![string equal $w1 $w2]} return
+
+    variable $w1
+    unset $w1
+}
+
+proc ctcomp::reset_state iw {
+    variable $iw
+    upvar 0 $iw state
+
+    set state(matches) [list]
+    set state(last)    ""
+    set state(what)    ""
+}
+
+proc ctcomp::accept iw {
+    $iw tag remove ctcomp/submatch comp_start comp_end
+    $iw mark unset comp_start
+    $iw mark unset comp_end
+}
+
+proc ctcomp::cancel iw {
+    $iw delete comp_start comp_end
+    $iw mark unset comp_start
+    $iw mark unset comp_end
+}
+
+proc ctcomp::pattern what {
+    variable options
+
+    format $options(pattern) [string map {
+	\\  \\\\
+	[   \\[
+	]   \\]
+	\{  \\\{
+	\}  \\\}
+	(   \\(
+	)   \\)
+	$   \\$
+	.   \\.
+	*   \\*
+	?   \\?
+    } $what]
+}
+
+proc ctcomp::matches {"in" iw} {
+    variable $iw
+    upvar 0 $iw state
+    upvar 0 state(what)    what
+    upvar 0 state(matches) matches
+
+    set what [word from $iw]
+    if {[string length $what] == 0} { return false }
+
+    set matches [get_matches for $what in $iw]
+    if {[llength $matches] == 0} {
+	show info $iw "No match for $what"
+	return false
+    }
+
+    return true
+}
+
+proc ctcomp::word {"from" t} {
+    set from [tk::TextPrevPos $t insert tcl_startOfPreviousWord]
+    $t get $from insert
+}
+
+proc ctcomp::get_matches {"for" what "in" iw} {
+    variable $iw
+    upvar 0 $iw state
+    upvar 0 state(chatid) chatid
+
+    set completions [concat \
+	[get_text_matches for $what in [chat::chat_win $chatid]] \
+	[get_text_matches for $what in $iw]]
+
+    hook::run chat_text_completion_matches_hook \
+	$chatid $what #[info level] completions
+
+    lsort -dictionary -unique $completions
+}
+
+proc ctcomp::get_text_matches {"for" what "in" t} {
+    set pos 1.0
+    set matches [list]
+
+    while 1 {
+	set at [$t search -count len -regexp [pattern $what] $pos end]
+	if {$at == {}} break
+
+	lappend matches [$t get $at "$at + $len chars"]
+
+	set pos [$t index "$at + 1 char"]
+    }
+
+    set matches
+}
+
+proc ctcomp::last L {
+    expr {[llength $L] - 1}
+}
+
+proc ctcomp::getopt {iw opt} {
+    variable $iw
+    upvar 0 $iw state
+
+    option get [chat::winid $state(chatid)] $opt Chat
+}
+
+proc ctcomp::tail {what match} {
+    string range $match [string length $what] end
+}
+
+proc ctcomp::match {seq dir "in" iw} {
+    variable $iw
+    upvar 0 $iw state
+    upvar 0 state(what)    what
+    upvar 0 state(matches) matches
+    upvar 0 state(last)    last
+
+    switch -- $seq {
+	first {
+	    switch -- $dir {
+		next { set last 0 }
+		prev { set last [last $matches] }
+	    }
+	    $iw mark set comp_start insert
+	    $iw mark gravity comp_start left
+	}
+	next {
+	    advance to $dir in $iw
+	    $iw delete comp_start comp_end
+	}
+    }
+
+    set submatch [tail $what [lindex $matches $last]]
+
+    $iw tag configure ctcomp/submatch \
+	-foreground [getopt $iw textCompletionForeground] \
+	-background [getopt $iw textCompletionBackground]
+
+    $iw insert comp_start $submatch ctcomp/submatch
+    $iw mark set comp_end insert
+    $iw mark gravity comp_end right
+}
+
+proc ctcomp::advance {"to" where "in" iw} {
+    variable $iw
+    upvar 0 $iw state
+    upvar 0 state(last)    last
+    upvar 0 state(matches) matches
+
+    set end [last $matches]
+
+    switch -- $where {
+	next {
+	    incr last
+	    if {$last > $end} {
+		set last 0
+		wraparound in $iw
+	    }
+	}
+	prev {
+	    incr last -1
+	    if {$last < 0} {
+		set last $end
+		wraparound in $iw
+	    }
+	}
+    }
+}
+
+proc ctcomp::wraparound {"in" iw} {
+    show info $iw "Wrapped around"
+}
+
+proc ctcomp::show_matches {"in" iw} {
+    set m $iw.matches
+    if {![winfo exists $m]} {
+	menu $iw.matches -tearoff no -postcommand [list \
+	    [namespace current]::repopulate_matches_menu $iw $m]
+    }
+
+    lassign [lrange [$iw bbox insert] 0 1] x y
+    set x [expr {[winfo rootx $iw] + $x}]
+    set y [expr {[winfo rooty $iw] + $y}]
+    tk_popup $m $x $y 0
+}
+
+proc ctcomp::repopulate_matches_menu {iw m} {
+    variable $iw
+    upvar 0 $iw state
+    upvar 0 state(what) what
+
+    $m delete 0 end
+
+    set i 0
+    foreach match $state(matches) {
+	if {[incr i] > 20} break
+	$m add command -label $match -command [list \
+	    [namespace current]::menu_insert_match $iw [tail $what $match]]
+    }
+
+    hook::run chat_text_completion_menu_hook $state(chatid) $state(what) $m
+}
+
+
+proc ctcomp::menu_insert_match {iw tail} {
+    variable $iw
+
+    $iw insert insert $tail
+}
+
+# $type should be either "info" or "error"
+proc ctcomp::show {type iw msg} {
+    variable $iw
+    upvar 0 $iw state
+    upvar 0 state(chatid) chatid
+
+    set jid [chat::get_jid $chatid]
+    set cw [chat::chat_win $chatid]
+
+    chat::add_message $chatid $jid $type $msg {}
+}
+
+# vim:ts=8:sw=4:sts=4:noet


Property changes on: trunk/tkabber-plugins/ctcomp/ctcomp.tcl
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Added: trunk/tkabber-plugins/ctcomp/license.terms
===================================================================
--- trunk/tkabber-plugins/ctcomp/license.terms	                        (rev 0)
+++ trunk/tkabber-plugins/ctcomp/license.terms	2007-10-07 12:27:46 UTC (rev 1256)
@@ -0,0 +1,19 @@
+Copyright (c) 2007 Konstantin Khomoutov <flatworm at users.sourceforge.net>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.


Property changes on: trunk/tkabber-plugins/ctcomp/license.terms
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native



More information about the Tkabber-dev mailing list