diff --git a/pyreadline/console/console.py b/pyreadline/console/console.py index 413b7d9..38f7c35 100644 --- a/pyreadline/console/console.py +++ b/pyreadline/console/console.py @@ -16,7 +16,7 @@ This was modeled after the C extension of the same name by Fredrik Lundh. import sys,os import traceback import re -from pyreadline.logger import log,log_sock +from pyreadline.logger import log from pyreadline.unicode_helper import ensure_unicode,ensure_str import pyreadline.unicode_helper as unicode_helper try: @@ -29,6 +29,13 @@ except ImportError: from pyreadline.keysyms import make_KeyPress from pyreadline.console.ansi import AnsiState,AnsiWriter + +def nolog(string): + pass + +log=nolog + + # some constants we need STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE = -11 @@ -297,7 +304,6 @@ class Console(object): # split the string into ordinary characters and funny characters chunks = self.motion_char_re.split(text) for chunk in chunks: - log('C:'+chunk) n = self.write_color(chunk, attr) if len(chunk) == 1: # the funny characters will be alone if chunk[0] == '\n': # newline @@ -339,8 +345,8 @@ class Console(object): n,res= self.ansiwriter.write_color(text,attr) junk = c_int(0) for attr,chunk in res: - log(unicode(attr)) - log(unicode(chunk)) + log(u"console.attr:%s"%unicode(attr)) + log(u"console.chunk:%s"%unicode(chunk)) self.SetConsoleTextAttribute(self.hout, attr.winattr) for short_chunk in split_block(chunk): self.WriteConsoleW(self.hout, short_chunk, len(short_chunk), byref(junk), None) @@ -480,7 +486,7 @@ class Console(object): status = self.ReadConsoleInputW(self.hin, byref(Cevent), 1, byref(count)) if status and count.value == 1: e = event(self, Cevent) - log_sock(ensure_unicode(e.keyinfo),"keypress") + log(u"console.get %s"%ensure_unicode(e.keyinfo)) return e def getkeypress(self): @@ -488,7 +494,7 @@ class Console(object): while 1: e = self.get() if e.type == 'KeyPress' and e.keycode not in key_modifiers: - log(e) + log("console.getleypress %s"%e) if e.keyinfo.keyname == 'next': self.scroll_window(12) elif e.keyinfo.keyname == 'prior': diff --git a/pyreadline/console/ironpython_console.py b/pyreadline/console/ironpython_console.py index d8c048a..df18bd1 100644 --- a/pyreadline/console/ironpython_console.py +++ b/pyreadline/console/ironpython_console.py @@ -35,7 +35,7 @@ import os import System from event import Event -from pyreadline.logger import log,log_sock +from pyreadline.logger import log #print "Codepage",System.Console.InputEncoding.CodePage from pyreadline.keysyms import make_keysym, make_keyinfo,make_KeyPress,make_KeyPress_from_keydescr @@ -85,15 +85,14 @@ class Console(object): self.saveattr = winattr[str(System.Console.ForegroundColor).lower()] self.savebg=System.Console.BackgroundColor log('initial attr=%s' % self.attr) - log_sock("%s"%self.saveattr) def _get(self): top=System.Console.WindowTop - log_sock("WindowTop:%s"%top,"console") + log("WindowTop:%s"%top) return top def _set(self,value): top=System.Console.WindowTop - log_sock("Set WindowTop:old:%s,new:%s"%(top,value),"console") + log("Set WindowTop:old:%s,new:%s"%(top,value)) WindowTop=property(_get,_set) del _get,_set @@ -148,7 +147,6 @@ class Console(object): # split the string into ordinary characters and funny characters chunks = self.motion_char_re.split(text) for chunk in chunks: - log('C:'+chunk) n = self.write_color(chunk, attr) if len(chunk) == 1: # the funny characters will be alone if chunk[0] == '\n': # newline @@ -311,7 +309,7 @@ class Console(object): elif e.Key == System.ConsoleKey.PageUp:#PageUp self.scroll_window(-12) elif str(e.KeyChar)=="\000":#Drop deadkeys - log_sock("Deadkey: %s"%e) + log("Deadkey: %s"%e) return event(self,e) pass else: @@ -364,7 +362,7 @@ class event(Event): self.char = str(input.KeyChar) self.keycode = input.Key self.state = input.Modifiers - log_sock("%s,%s,%s"%(input.Modifiers,input.Key,input.KeyChar),"console") + log("%s,%s,%s"%(input.Modifiers,input.Key,input.KeyChar)) self.type="KeyRelease" self.keysym = make_keysym(self.keycode) self.keyinfo = make_KeyPress(self.char, self.state, self.keycode) diff --git a/pyreadline/keysyms/ironpython_keysyms.py b/pyreadline/keysyms/ironpython_keysyms.py index dc7168a..6b3534d 100644 --- a/pyreadline/keysyms/ironpython_keysyms.py +++ b/pyreadline/keysyms/ironpython_keysyms.py @@ -8,7 +8,7 @@ #***************************************************************************** import System from common import validkey,KeyPress,make_KeyPress_from_keydescr -#from pyreadline.logger import log_sock + c32=System.ConsoleKey Shift=System.ConsoleModifiers.Shift Control=System.ConsoleModifiers.Control @@ -196,7 +196,6 @@ def make_KeyPress(char,state,keycode): control=bool(int(state)&int(Control)) meta=bool(int(state)&int(Alt)) keyname=code2sym_map.get(keycode,"").lower() -# log_sock("make key %s %s %s %s"%(shift,control,meta,keycode),"keysyms") if control and meta: #equivalent to altgr so clear flags control=False meta=False diff --git a/pyreadline/keysyms/keysyms.py b/pyreadline/keysyms/keysyms.py index f07e1f5..1eecd34 100644 --- a/pyreadline/keysyms/keysyms.py +++ b/pyreadline/keysyms/keysyms.py @@ -7,6 +7,7 @@ # the file COPYING, distributed as part of this software. #***************************************************************************** import winconstants as c32 +from pyreadline.logger import log from ctypes import windll import ctypes # table for translating virtual keys to X windows key symbols @@ -111,21 +112,21 @@ def char_to_keyinfo(char, control=False, meta=False, shift=False): k.char=chr(vk & 0xff) return k -def make_KeyPress(char,state,keycode): +def make_KeyPress(char, state, keycode): control = (state & (4+8)) != 0 meta = (state & (1+2)) != 0 shift = (state & 0x10) != 0 - if control and char !="\x00": - char = chr(VkKeyScan(ord(char)) & 0xff) - elif control and meta and char !="\x00": - char = chr(VkKeyScan(ord(char)) & 0xff) - elif control: + if control and not meta:#Matches ctrl- chords should pass keycode as char char=chr(keycode) + elif control and meta: #Matches alt gr and should just pass on char + control=False + meta=False try: keyname=code2sym_map[keycode] except KeyError: keyname="" - return KeyPress(char,shift,control,meta,keyname) + out=KeyPress(char, shift, control, meta, keyname) + return out if __name__=="__main__": import startup diff --git a/pyreadline/lineeditor/history.py b/pyreadline/lineeditor/history.py index a433f55..9eee20e 100644 --- a/pyreadline/lineeditor/history.py +++ b/pyreadline/lineeditor/history.py @@ -20,7 +20,7 @@ import exceptions class EscapeHistory(exceptions.Exception): pass -from pyreadline.logger import log_sock +from pyreadline.logger import log _ignore_leading_spaces=False @@ -35,20 +35,20 @@ class LineHistory(object): def get_history_length(self): value=self._history_length - log_sock("get_history_length:%d"%value,"history") + log("get_history_length:%d"%value) return value def set_history_length(self,value): - log_sock("set_history_length: old:%d new:%d"%(self._history_length,value),"history") + log("set_history_length: old:%d new:%d"%(self._history_length,value)) self._history_length=value def get_history_cursor(self): value=self._history_cursor - log_sock("get_history_cursor:%d"%value,"history") + log("get_history_cursor:%d"%value) return value def set_history_cursor(self,value): - log_sock("set_history_cursor: old:%d new:%d"%(self._history_cursor,value),"history") + log("set_history_cursor: old:%d new:%d"%(self._history_cursor,value)) self._history_cursor=value history_length=property(get_history_length,set_history_length) diff --git a/pyreadline/lineeditor/lineobj.py b/pyreadline/lineeditor/lineobj.py index 8748dd1..0e62108 100644 --- a/pyreadline/lineeditor/lineobj.py +++ b/pyreadline/lineeditor/lineobj.py @@ -9,7 +9,7 @@ import re,operator,sys import wordmatcher import pyreadline.clipboard as clipboard -from pyreadline.logger import log,log_sock +from pyreadline.logger import log from pyreadline.unicode_helper import ensure_unicode kill_ring_to_clipboard=False #set to true to copy every addition to kill ring to clipboard diff --git a/pyreadline/logger.py b/pyreadline/logger.py index 0996036..e4f7d3f 100644 --- a/pyreadline/logger.py +++ b/pyreadline/logger.py @@ -6,42 +6,59 @@ # the file COPYING, distributed as part of this software. #***************************************************************************** -import socket +import socket, logging, logging.handlers from pyreadline.unicode_helper import ensure_str -_logfile=False - -def start_log(on,filename): - global _logfile - if on=="on": - _logfile=open(filename,"w") - else: - _logfile=False - -def log(s): - if _logfile: - s = ensure_str(s) - print >>_logfile, s - _logfile.flush() - host="localhost" -port=8081 -logsocket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) +port=logging.handlers.DEFAULT_TCP_LOGGING_PORT -show_event=["keypress","bound_function","bind_key","console"] -show_event=["bound_function"] -sock_silent=True +root_logger=logging.getLogger('') +root_logger.setLevel(logging.DEBUG) +formatter = logging.Formatter('%(message)s') +file_handler=None -def log_sock(s,event_type=None): - if sock_silent: +class NULLHandler(logging.Handler): + def emit(self, s): pass - else: - if event_type is None: - logsocket.sendto(ensure_str(s),(host,port)) - elif event_type in show_event: - logsocket.sendto(ensure_str(s),(host,port)) - else: - pass - +class SocketStream(object): + def __init__(self, host, port): + self.logsocket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) + + def write(self, s): + self.logsocket.sendto(ensure_str(s),(host,port)) + + def flush(self): + pass + + def close(self): + pass + +socket_handler = logging.StreamHandler(SocketStream(host, port)) +socket_handler.setFormatter(formatter) +root_logger.addHandler(NULLHandler()) + + +def start_socket_log(): + root_logger.addHandler(socket_handler) + +def stop_socket_log(): + root_logger.removeHandler(socket_handler) + +def start_file_log(filename): + global file_handler + file_handler=logging.handlers.FileHandler(filename, "w") + root_logger.addHandler(file_handler) + +def stop_file_log(): + global file_handler + if file_handler: + root_logger.removeHandler(file_handler) + file_handler.close() + file_handler=None + +def log(s): + s = ensure_str(s) + root_logger.debug(s) + diff --git a/pyreadline/logserver.py b/pyreadline/logserver.py index 6b761b2..c5c73fe 100644 --- a/pyreadline/logserver.py +++ b/pyreadline/logserver.py @@ -5,28 +5,21 @@ # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #***************************************************************************** -import socket - +import cPickle +import logging +import logging.handlers +import SocketServer +import struct,socket try: import msvcrt except ImportError: msvcrt=None print "problem" - -port =8081 - -s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) - -s.bind(("",port)) -s.settimeout(0.05) - -print "Starting logserver on port:",port -print "Press q to quit logserver",port -singleline=False - +port=logging.handlers.DEFAULT_TCP_LOGGING_PORT +host='localhost' def check_key(): if msvcrt is None: @@ -34,27 +27,31 @@ def check_key(): else: if msvcrt.kbhit()!=0: q=msvcrt.getch() - - return q in "q" - else: - return False + return q + return "" -while 1: - try: - data,addr=s.recvfrom(1024) - except socket.timeout: - if check_key(): - print "Quitting logserver" - break - else: - continue - if data.startswith("@@"): - continue - if singleline: - print "\r"," "*78,"\r",data,#,addr - else: - print data - - +singleline=False +def main(): + print "Starting TCP logserver on port:",port + print "Press q to quit logserver", port + print "Press c to clear screen", port + s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) + + s.bind(("",port)) + s.settimeout(1) + while 1: + try: + data, addr=s.recvfrom(100000) + print data, + except socket.timeout: + key=check_key().lower() + if "q"==key: + print "Quitting logserver" + break + elif "c" == key: + print "\n"*100 + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/pyreadline/modes/basemode.py b/pyreadline/modes/basemode.py index dc4e573..6b5f9be 100644 --- a/pyreadline/modes/basemode.py +++ b/pyreadline/modes/basemode.py @@ -8,7 +8,7 @@ #***************************************************************************** import os,re,math,glob,sys,time import pyreadline.logger as logger -from pyreadline.logger import log,log_sock +from pyreadline.logger import log from pyreadline.keysyms.common import make_KeyPress_from_keydescr import pyreadline.lineeditor.lineobj as lineobj import pyreadline.lineeditor.history as history @@ -203,7 +203,7 @@ class BaseMode(object): completions.append(r) else: break - log('text completions=%s' % completions) + log('text completions=<%s>' % completions) if not completions: # get the filename to complete while self.begidx > 0: @@ -222,7 +222,7 @@ class BaseMode(object): else: mc.append(f) completions = mc - log('fnames=%s' % completions) + log('fnames=<%s>' % completions) return completions @@ -498,7 +498,7 @@ class BaseMode(object): self.insert_text(t[0]) self.add_history(self.l_buffer.copy()) self.paste_line_buffer=t[1:] - log("multi: %s"%self.paste_line_buffer) + log("multi: >%s<"%self.paste_line_buffer) return True else: return False diff --git a/pyreadline/modes/emacs.py b/pyreadline/modes/emacs.py index 65478c2..2e4d47b 100644 --- a/pyreadline/modes/emacs.py +++ b/pyreadline/modes/emacs.py @@ -8,7 +8,7 @@ #***************************************************************************** import os,sys,time import pyreadline.logger as logger -from pyreadline.logger import log,log_sock +from pyreadline.logger import log from pyreadline.lineeditor.lineobj import Point import pyreadline.lineeditor.lineobj as lineobj import pyreadline.lineeditor.history as history @@ -31,7 +31,7 @@ class IncrementalSearchPromptMode(object): def _process_incremental_search_keyevent(self, keyinfo): keytuple=keyinfo.tuple() - log_sock("%s %s"%(keyinfo,keytuple)) + log("IncrementalSearchPromptMode %s %s"%(keyinfo,keytuple)) if keyinfo.keyname == 'backspace': self.subsearch_query = self.subsearch_query[:-1] if len(self.subsearch_query) > 0: @@ -98,7 +98,7 @@ class SearchPromptMode(object): def _process_non_incremental_search_keyevent(self, keyinfo): keytuple=keyinfo.tuple() - log_sock("%s %s"%(keyinfo,keytuple)) + log("SearchPromptMode %s %s"%(keyinfo,keytuple)) if keyinfo.keyname == 'backspace': self.non_inc_query = self.non_inc_query[:-1] @@ -154,9 +154,9 @@ class DigitArgumentMode(object): pass def _process_digit_argument_keyevent(self, keyinfo): - log_sock("_process_digit_argument_keyevent %s"%keyinfo) + log("DigitArgumentMode.keyinfo %s"%keyinfo) keytuple=keyinfo.tuple() - log_sock("%s %s"%(keyinfo,keytuple)) + log("DigitArgumentMode.keytuple %s %s"%(keyinfo,keytuple)) if keyinfo.keyname in ['return']: self.prompt=self._digit_argument_oldprompt self.process_keyevent_queue=self.process_keyevent_queue[:-1] @@ -164,7 +164,7 @@ class DigitArgumentMode(object): elif keyinfo.keyname: pass elif keyinfo.char in "0123456789" and keyinfo.control==False and keyinfo.meta==False : - log_sock("arg %s %s"%(self.argument,keyinfo.char)) + log("arg %s %s"%(self.argument,keyinfo.char)) self.argument=self.argument*10+int(keyinfo.char) else: self.prompt=self._digit_argument_oldprompt @@ -183,9 +183,9 @@ class DigitArgumentMode(object): self.argument=-1 elif keyinfo.char in "0123456789": self.argument=int(keyinfo.char) - log_sock("<%s> %s"%(self.argument,type(self.argument))) + log("<%s> %s"%(self.argument,type(self.argument))) self.prompt="(arg: %s) "%self.argument - log_sock("arg-init %s %s"%(self.argument,keyinfo.char)) + log("arg-init %s %s"%(self.argument,keyinfo.char)) @@ -229,7 +229,7 @@ class EmacsMode(DigitArgumentMode, IncrementalSearchPromptMode, SearchPromptMode """return True when line is final """ #Process exit keys. Only exit on empty line - log_sock("_process_keyevent %s"%keyinfo) + log("_process_keyevent <%s>"%keyinfo) def nop(e): pass if self.next_meta: @@ -244,17 +244,16 @@ class EmacsMode(DigitArgumentMode, IncrementalSearchPromptMode, SearchPromptMode return False if keytuple in self.exit_dispatch: - log_sock("exit_dispatch:%s, %s"%(self.l_buffer, lineobj.EndOfLine(self.l_buffer))) + log("exit_dispatch:<%s, %s>"%(self.l_buffer, lineobj.EndOfLine(self.l_buffer))) if lineobj.EndOfLine(self.l_buffer) == 0: raise EOFError - if keyinfo.keyname: + if keyinfo.keyname or keyinfo.control or keyinfo.meta: default=nop else: default=self.self_insert dispatch_func = self.key_dispatch.get(keytuple, default) - log("readline from keyboard:%s,%s"%(keytuple, dispatch_func)) - log_sock((u"%s|%s"%(ensure_unicode(format(keytuple)),dispatch_func.__name__)),"bound_function") + log("readline from keyboard:<%s,%s>"%(keytuple, dispatch_func)) r = None if dispatch_func: diff --git a/pyreadline/modes/vi.py b/pyreadline/modes/vi.py index d6710ac..5b5683e 100644 --- a/pyreadline/modes/vi.py +++ b/pyreadline/modes/vi.py @@ -9,7 +9,7 @@ #***************************************************************************** import os import pyreadline.logger as logger -from pyreadline.logger import log,log_sock +from pyreadline.logger import log import pyreadline.lineeditor.lineobj as lineobj import pyreadline.lineeditor.history as history import basemode diff --git a/pyreadline/rlmain.py b/pyreadline/rlmain.py index 026022d..8700b57 100644 --- a/pyreadline/rlmain.py +++ b/pyreadline/rlmain.py @@ -11,7 +11,7 @@ import sys,os,re,time from glob import glob import clipboard,logger,console -from logger import log,log_sock +from logger import log from error import ReadlineError,GetSetError from pyreadline.keysyms.common import make_KeyPress_from_keydescr @@ -146,7 +146,7 @@ class BaseReadline(object): '''Load a readline history file. The default filename is ~/.history.''' if filename is None: filename=self.mode._history.history_filename - log_sock("read_history_file from %s"%filename) + log("read_history_file from %s"%filename) self.mode._history.read_history_file(filename) def write_history_file(self, filename=None): @@ -266,7 +266,6 @@ class BaseReadline(object): def setmode(name): self.mode=modes[name] def bind_key(key,name): - log("bind %s %s"%(key,name)) if hasattr(modes[mode],name): modes[mode]._bind_key(key,getattr(modes[mode],name)) else: @@ -286,31 +285,51 @@ class BaseReadline(object): def setkill_ring_to_clipboard(killring): import pyreadline.lineeditor.lineobj pyreadline.lineeditor.lineobj.kill_ring_to_clipboard=killring + def sethistoryfilename(filename): self.mode._history.history_filename=os.path.expanduser(filename) + def setbellstyle(mode): self.bell_style=mode + def sethistorylength(length): self.mode._history.history_length=int(length) + def allow_ctrl_c(mode): - log_sock("allow_ctrl_c:%s:%s"%(self.allow_ctrl_c,mode)) + log("allow_ctrl_c:%s:%s"%(self.allow_ctrl_c,mode)) self.allow_ctrl_c=mode + def setbellstyle(mode): self.bell_style=mode + def show_all_if_ambiguous(mode): self.mode.show_all_if_ambiguous=mode + def ctrl_c_tap_time_interval(mode): self.ctrl_c_tap_time_interval=mode + def mark_directories(mode): self.mode.mark_directories=mode + def completer_delims(delims): self.mode.completer_delims=delims + def debug_output(on,filename="pyreadline_debug_log.txt"): #Not implemented yet if on in ["on","on_nologfile"]: self.debug=True - logger.start_log(on,filename) - logger.log("STARTING LOG") -# print release.branch + + if on == "on": + logger.start_file_log(filename) + logger.start_socket_log() + logger.log("STARTING LOG") + elif on =="on_nologfile": + logger.start_socket_log() + logger.log("STARTING LOG") + else: + logger.log("STOPING LOG") + logger.stop_file_log() + logger.stop_socket_log() + def set_prompt_color(color): trtable={"black":0,"darkred":4,"darkgreen":2,"darkyellow":6,"darkblue":1,"darkmagenta":5,"darkcyan":3,"gray":7, "red":4+8,"green":2+8,"yellow":6+8,"blue":1+8,"magenta":5+8,"cyan":3+8,"white":7+8} @@ -512,14 +531,14 @@ class Readline(BaseReadline): def handle_ctrl_c(self): from pyreadline.keysyms.common import KeyPress from pyreadline.console.event import Event - log_sock("KBDIRQ") + log("KBDIRQ") event=Event(0,0) event.char="c" event.keyinfo=KeyPress("c",shift=False,control=True,meta=False,keyname=None) if self.allow_ctrl_c: now=time.time() if (now-self.ctrl_c_timeout)