#@+leo-ver=4-thin
#@+node:ekr.20090113083258.1:@thin test_core.txt
#@+at
# This is a good place for running tests during development.
# 
# Run these tests with either:
# 
# - Alt-5, run-unit-tests
# - run-all-unit-tests
# - Alt-7, run-all-core-tests
# 
# The run-all-core-tests script button allows you to choose the gui.
#@-at
#@@c

#@+all
#@+node:ekr.20090703094259.6028:@suite run all doctests (windows only)
import unittest
import leo.core.leoTest as leoTest

import sys

# DocTestSuite exists in Python 2.3 and above.
# WARNING: this causes strange problems when run externally.

if sys.platform.lower().startswith('win'):

    version = '.'.join([str(sys.version_info[i]) for i in (0,1,2)])
    if g.CheckVersion(version, "2.3"):
        path = g.os_path_join(g.app.loadDir,"..","core")
        if 0:
            << define exclude >>
        else:
            exclude = []
        modules = leoTest.importAllModulesInPath(path,exclude=exclude)
        suite = leoTest.createUnitTestsFromDoctests(modules)
        if suite: g.app.scriptDict['suite'] = suite
    else:
        # Create an empty suite to suppress a warning.
        g.app.scriptDict['suite'] = unittest.TestSuite()
        print("\nCan't create unit tests from doctests")
        print("doctest.DocTestSuite requires Python 2.3 or above.\n")

else:
    pass # There are problems on Linux.
#@nonl
#@+node:ekr.20090703094259.6029:<< define exclude >>
exclude = [
    # These cause no problems, but will not have unit tests.
    'leo_Debugger.py',
    'leo_FileList.py',
    'leo_RemoteDebugger.py',
    'leo_run.py',
    'leo_Shell.py',
    'leoDynamicTest.py',
    'leoBridge.py',
    'leoBridgeTest.py',
    # 'leoApp.py','leoChapters.py',
    # 'leoAtFile.py',
    # 'leoColor.py',
    # 'leoCommands.py',
    # 'leoCompare.py',
    # 'leoConfig.py',
    # 'leoDebugger.py',
    # 'leoEditCommands.py',
    ####'leoFileCommands.py', # Causes problems!
    # 'leoFind.py',
    # 'leoFrame.py',
    # 'leoGlobals.py',
    # 'leoGui.py',
    # 'leoImport.py',
    # 'leoKeys.py',
    # 'leoMenu.py',
    # 'leoNodes.py',
    # 'leoPlugins.py',
    # 'leoPymacs.py',
    # 'leoRst.py',
    # 'leoShadow.py',
    # 'leoTangle.py',
    # 'leoTest.py',
    # 'leoUndo.py',
]
#@nonl
#@-node:ekr.20090703094259.6029:<< define exclude >>
#@-node:ekr.20090703094259.6028:@suite run all doctests (windows only)
#@+node:ekr.20090529103821.6840:General
#@+node:ekr.20090201135500.1:Check base classes & ivars
#@+node:ekr.20090630093812.6013:Tk gui tests
#@+node:ekr.20090201135500.2:@test leoBody is subset of leoTkBody
if g.app.gui.guiName() == 'tkinter':

    import leo.core.leoPlugins as leoPlugins
    tkGui = leoPlugins.loadOnePlugin ('tkGui',verbose=False)

    import leo.core.leoFrame as leoFrame
    import inspect,sys

    baseClass = leoFrame.leoBody
    subClasses  = (tkGui.leoTkinterBody,leoFrame.nullBody)
    baseObject = c.frame.body

    methods = inspect.getmembers(baseClass,inspect.ismethod)
    methodNames = [z[0] for z in methods]

    for name in baseObject.mustBeDefinedOnlyInBaseClass:
        try:
            assert name in methodNames, 'not defined in base class %s.%s' % (baseClass.__name__,name)
        except AssertionError:
            exctype, value = sys.exc_info()[:2]
            print(value)
            raise

    for subClass in subClasses:
        subclassName = subClass.__name__
        for name in methodNames:
            base_func = getattr(baseClass,name)
            sub_func =  getattr(subClass,name)
            try:
                if name in baseObject.mustBeDefinedOnlyInBaseClass:
                    assert base_func.im_func == sub_func.im_func, 'defined in subclass %s.%s' % (subclassName,name)
                if name in baseObject.mustBeDefinedInSubclasses:
                    assert base_func.im_func != sub_func.im_func, 'not defined in subclass %s.%s' % (subclassName,name)
            except AssertionError:
                #raise
                exctype, value = sys.exc_info()[:2]
                print(value)
#@nonl
#@-node:ekr.20090201135500.2:@test leoBody is subset of leoTkBody
#@+node:ekr.20090201135500.3:@test leoFrame is subset of leoTkFrame
if g.app.gui.guiName() == 'tkinter':

    import leo.core.leoPlugins as leoPlugins
    tkGui = leoPlugins.loadOnePlugin ('tkGui',verbose=False)

    import leo.core.leoFrame as leoFrame
    import inspect

    baseClass = leoFrame.leoFrame
    subClasses  = (tkGui.leoTkinterFrame,leoFrame.nullFrame)
    baseObject = c.frame

    methods = inspect.getmembers(baseClass,inspect.ismethod)
    methodNames = [z[0] for z in methods]

    for name in baseObject.mustBeDefinedOnlyInBaseClass:
        assert name in methodNames, 'not defined in base class %s.%s' % (baseClass.__name__,name)

    for subClass in subClasses:
        subclassName = subClass.__name__
        for name in methodNames:
            base_func = getattr(baseClass,name)
            sub_func =  getattr(subClass,name)
            if name in baseObject.mustBeDefinedOnlyInBaseClass:
                assert base_func.im_func == sub_func.im_func, 'defined in subclass %s.%s' % (subclassName,name)
            if name in baseObject.mustBeDefinedInSubclasses:
                assert base_func.im_func != sub_func.im_func, 'not defined in subclass %s.%s' % (subclassName,name)
#@-node:ekr.20090201135500.3:@test leoFrame is subset of leoTkFrame
#@+node:ekr.20090201135500.4:@test leoGui is subset of leoTkGui
if g.app.gui.guiName() == 'tkinter':

    import leo.core.leoPlugins as leoPlugins
    tkGui = leoPlugins.loadOnePlugin ('tkGui',verbose=False)

    import leo.core.leoGui as leoGui
    import inspect

    baseClass = leoGui.leoGui
    subClasses  = (tkGui.tkinterGui,) # nullGui can inherit almost all leoGui dummy methods.
    baseObject = g.app.gui

    methods = inspect.getmembers(baseClass,inspect.ismethod)
    methodNames = [z[0] for z in methods]

    for name in baseObject.mustBeDefinedOnlyInBaseClass:
        assert name in methodNames, 'not defined in base class %s.%s' % (baseClass.__name__,name)

    for subClass in subClasses:
        subclassName = subClass.__name__
        for name in methodNames:
            base_func = getattr(baseClass,name)
            sub_func =  getattr(subClass,name)
            try:
                if name in baseObject.mustBeDefinedOnlyInBaseClass:
                    assert base_func.im_func == sub_func.im_func, 'defined in subclass %s.%s' % (subclassName,name)
                if name in baseObject.mustBeDefinedInSubclasses:
                    assert base_func.im_func != sub_func.im_func, 'not defined in subclass %s.%s' % (subclassName,name)
            except AssertionError:
                raise
#@-node:ekr.20090201135500.4:@test leoGui is subset of leoTkGui
#@+node:ekr.20090201135500.5:@test leoTree is subset of leoTkTree
if g.app.gui.guiName() == 'tkinter':

    import leo.core.leoPlugins as leoPlugins
    tkGui = leoPlugins.loadOnePlugin ('tkGui',verbose=False)

    import leo.core.leoFrame as leoFrame
    import inspect

    baseClass = leoFrame.leoTree
    subClasses  = (tkGui.leoTkinterTree,leoFrame.nullTree)
    baseObject = c.frame.tree

    methods = inspect.getmembers(baseClass,inspect.ismethod)
    methodNames = [z[0] for z in methods]

    for name in baseObject.mustBeDefinedOnlyInBaseClass:
        assert name in methodNames, 'not defined in base class %s.%s' % (baseClass.__name__,name)

    for subClass in subClasses:
        subclassName = subClass.__name__
        for name in methodNames:
            base_func = getattr(baseClass,name)
            sub_func =  getattr(subClass,name)
            if name in baseObject.mustBeDefinedOnlyInBaseClass:
                assert base_func.im_func == sub_func.im_func, 'defined in subclass %s.%s' % (subclassName,name)
            if name in baseObject.mustBeDefinedInSubclasses:
                assert base_func.im_func != sub_func.im_func, 'not defined in subclass %s.%s' % (subclassName,name)
#@-node:ekr.20090201135500.5:@test leoTree is subset of leoTkTree
#@-node:ekr.20090630093812.6013:Tk gui tests
#@+node:ekr.20090630091825.5993:@test that leoQtLog/Body implements high-level interface
if g.app.gui.guiName() == 'qt':

    logCtrl = c.frame.log.logCtrl

    table = (
        ('mustBeDefinedInSubclasses',logCtrl.mustBeDefinedInHighLevelSubclasses),
        ('mustBeDefinedInBaseClass',logCtrl.mustBeDefinedOnlyInBaseClass),
        ('mustBeDefined',logCtrl.mustBeDefined),
    )

    # Check existence.
    for tag,aList in table:
        for z in aList:
            assert hasattr(c.frame.log,z),'%s %s' % (tag,z)
            assert hasattr(c.frame.body,z),'%s %s' % (tag,z)

    # Check signatures.
    import inspect
    for tag,aList in table:
        for z in aList:
            func = getattr(c.frame.body.bodyCtrl,z)
            func2 = getattr(c.frame.log.logCtrl,z)
            assert func,z
            assert func2,z
            d1 = inspect.getargspec(func)
            d2 = inspect.getargspec(func2)
            assert d1==d2,'\n%s\n\nd1 %s\n\nd2 %s' % (z,d1,d2)
#@-node:ekr.20090630091825.5993:@test that leoQtLog/Body implements high-level interface
#@+node:ekr.20090201135500.6:@test official commander ivars
f = c.frame
assert(f.c==c)
assert(c.frame==f)

ivars = (
    # Subcommanders...
    'atFileCommands','fileCommands','importCommands','tangleCommands','undoer',
    # Positions...
    '_currentPosition','_rootPosition','_topPosition',
    # Data structures...
    'hoistStack','recentFiles',
    # Args...
    'output_doc_flag','page_width','tab_width',
    # 'tangle_directory',
    'tangle_errors','tangle_batch_flag','target_language',
    'untangle_batch_flag','use_header_flag',
    # Others...
    'mFileName',
)

for ivar in ivars:
    assert hasattr(c,ivar), 'missing commander ivar: %s' % ivar
    val = getattr(c,ivar)
    assert val is not None,'null commander ivar: %s'% ivar
#@nonl
#@-node:ekr.20090201135500.6:@test official commander ivars
#@+node:ekr.20090201135500.7:@test official frame ivars
f = c.frame
assert(f.c==c)
assert(c.frame==f)

if g.app.gui.guiName() == 'tkinter':
    ivars = (
        'bar1','bar2',
        'body',
        #'bodyBar','bodyXBar', # 2007: 10/31: There are now injected in c.frame.body.bodyCtrl.
        #'bodyCtrl', # 2007/10/27: this ivar is evil and has been removed.
        'canvas',
        'f1','f2',
        'iconBar','iconFrame',
        'log','outerFrame',
        'statusLine','statusFrame','statusLabel','statusText',
        'title','top','tree',
        #'treeBar', # leo_treeBar is now injected into frame.canvas.
    )
else: ivars = ()

for ivar in ivars:
    assert hasattr(f,ivar), 'missing frame ivar: %s' % ivar
    val = getattr(f,ivar)
    assert val is not None,'null frame ivar: %s'% ivar

# These do not have to be initied.
for ivar in ('findPanel',):
    assert hasattr(f,ivar), 'missing frame ivar: %s' % ivar
#@nonl
#@-node:ekr.20090201135500.7:@test official frame ivars
#@+node:ekr.20090201135500.8:@test official g.app directories
ivars = ('extensionsDir','globalConfigDir','loadDir','testDir')

for ivar in ivars:
    assert hasattr(g.app,ivar), 'missing g.app directory: %s' % ivar
    val = getattr(g.app,ivar)
    assert val is not None, 'null g.app directory: %s'% ivar
    assert g.os_path_exists(g.os_path_abspath(val)), 'non-existent g.app directory: %s' % ivar

assert hasattr(g.app,'homeDir') # May well be None.
#@nonl
#@-node:ekr.20090201135500.8:@test official g.app directories
#@+node:ekr.20090201135500.9:@test official g.app ivars

ivars = (
    # These are non-official and might be removed...
        # 'afterHandler','count','positions',
        # 'menuWarningsGiven','unicodeErrorGiven',
    'batchMode','config',
    'debug','debugSwitch','defaultEncoding','disableSave',
    'gui','hasOpenWithMenu','hookError','hookFunction',
    'idle_imported','idleTimeDelay','idleTimeHook','initing','killed',
    'leoID','loadedPlugins','log','logIsLocked','logWaiting',
    'nodeIndices','numberOfWindows',
    'quitting','realMenuNameDict','searchDict','scriptDict',
    'trace','tracePositions','trace_list',
    'unitTestDict','unitTesting','use_psyco','windowList',
)

for ivar in ivars:
    assert hasattr(g.app,ivar), 'missing app ivar: %s' % ivar
    val = getattr(g.app,ivar)
    assert val is not None, 'null app ivar: %s'% ivar

# These do not have to be initied.
for ivar in (
    'commandName',
    'openWithFiles','openWithFileNum','openWithTable',
    'root',
):
    assert hasattr(g.app,ivar), 'missing app ivar: %s' % ivar
#@nonl
#@-node:ekr.20090201135500.9:@test official g.app ivars
#@-node:ekr.20090201135500.1:Check base classes & ivars
#@+node:ekr.20090529103821.7095:@test batch mode
import os
import sys

trace = False

python_interp = sys.executable
test_path = g.os_path_join(g.app.loadDir,"..","test","unittest")
src_path  = g.os_path_join(g.app.loadDir,"..","..")

leo_file   = g.os_path_join(src_path,"launchLeo.py")
batch_file = g.os_path_join(test_path,"batchTest.py")
test_file  = g.os_path_join(test_path,"createdFile.txt")

# Execute this command: python launchLeo.py --script test\unittest\batchTest.py

if 1:
    command = r"%s %s --silent --script %s" % (python_interp,leo_file,batch_file)
else:
    command = r"%s %s --script %s" % (python_interp,leo_file,batch_file)

@others

if trace:
    print('@test batch mode: loadDir: %s' % g.app.loadDir)

removeFile(test_file)
os.system(command)

assert(g.os_path_exists(test_file))
#@nonl
#@+node:ekr.20090529103821.7096:removeFile
def removeFile(path):

    trace = False

    if os.path.exists(test_file):
        if trace:
            print("@test batch mode: removeFile: deleting",test_file)
        os.remove(test_file)
    else:
        if trace:
            print("@test batch mode: removeFile: not found:",test_file)
#@-node:ekr.20090529103821.7096:removeFile
#@-node:ekr.20090529103821.7095:@test batch mode
#@+node:ekr.20090529103821.7102:@test all commands have an event arg
import inspect

d = c.commandsDict ; keys = list(d.keys()) ; keys.sort()

for key in keys:
    f = d.get(key) ; name = f and f.__name__
    args, varargs, varkw, defaults = data = inspect.getargspec(f)
    # print('%-28s' % (name),data)
    arg0 = len(args) > 0 and args[0]
    arg1 = len(args) > 1 and args[1]
    assert arg0 == 'self' and arg1 == 'event' or arg0 == 'event',\
       'no event arg for %s, args: %s' % (name,data)
#@nonl
#@-node:ekr.20090529103821.7102:@test all commands have an event arg
#@+node:ekr.20090529103821.7359:@@test that all @test nodes in derived files start with if g.unitTesting
# print('-' * 30)

@others

# This can't be run externally,
# And it is no longer an effective test.

p = c.rootPosition()
ok = True
while p and ok:
    if p.isAnyAtFileNode():
        h = p.h
        if h.endswith('.py'):
            ok = checkFile(p)
        p.moveToNodeAfterTree()
    else:
        p.moveToThreadNext()
assert ok
#@nonl
#@+node:ekr.20090529103821.7363:checkFile
def checkFile(p):

    print('checking',p.h)
    # Check all the descendant nodes.
    ok = True
    for p2 in p.subtree_iter():
        h = p2.h
        for tag in ('@test','@suite'):
            if h.startswith(tag):
                s = p2.b
                lines = g.splitLines(s)
                for line in lines:
                    # print('line',line)
                    if not line.strip() or line.startswith('#'):
                        continue
                    elif line.startswith('if g.unitTesting:'):
                        break
                    else:
                        print('in %s' % p.h)
                        print('missing "if g.unitTesting:" %s' % h)
                        ok = False
    return ok
#@nonl
#@-node:ekr.20090529103821.7363:checkFile
#@-node:ekr.20090529103821.7359:@@test that all @test nodes in derived files start with if g.unitTesting
#@-node:ekr.20090529103821.6840:General
#@+node:ekr.20090529103821.6587:Organized by file
# These would typically not be valid if placed in the actual core file.
#@nonl
#@+node:ekr.20090529103821.9335:plugins
#@+node:ekr.20090529103821.9336:@suite test syntax of all plugins
# N.B.  We don't import the files: multiple imports might cause problems.
import unittest
import leo.core.leoTest as leoTest
import sys

@others

if sys.platform.lower().startswith('win'):

    print('@suite test syntax of all plugins')

    suite = unittest.makeSuite(unittest.TestCase)

    for path in leoTest.getAllPluginFilenames():

        f = open(path)
        assert f, "File not found: %s" % path
        # Do not test the syntax_error_plugin.
        if path.find('syntax_error_plugin') == -1:
            s = f.read() ; f.close()
            test = parseFileTestCase(c,path,checkCompile=True,checkTabs=True)
            suite.addTest(test)

    if suite:
        g.app.scriptDict['suite'] = suite

else:

    pass # Only test these on Windows.
#@nonl
#@+node:ekr.20090529103821.9337:class parseFileTestCase
class parseFileTestCase (unittest.TestCase):

    @others
#@nonl
#@+node:ekr.20090529103821.9338:__init__
def __init__ (self,c,path,checkCompile,checkTabs):

    # Init the base class.
    unittest.TestCase.__init__(self)

    self.c = c
    self.path = path
    self.checkCompile = checkCompile
    self.checkTabs = checkTabs
    assert self.checkCompile or self.checkTabs, "not checking anything"
#@nonl
#@-node:ekr.20090529103821.9338:__init__
#@+node:ekr.20090529103821.9339:runTest
def runTest(self):

    c = self.c ; path = self.path

    s = open(path).read()

    if self.checkCompile:
        leoTest.checkFileSyntax(path,s)

    if self.checkTabs:
        leoTest.checkFileTabs(path,s)
#@nonl
#@-node:ekr.20090529103821.9339:runTest
#@+node:ekr.20090529103821.9340:shortDescription
def shortDescription (self):

    fn = str(g.shortFileName(self.path))

    if self.checkCompile and self.checkTabs:
        return "Test syntax and tabbing of %s plugin" % fn
    elif self.checkCompile:
        return "Test syntax of %s plugin" % fn
    else:
        return "Test tabbing of %s plugin" % fn
#@nonl
#@-node:ekr.20090529103821.9340:shortDescription
#@-node:ekr.20090529103821.9337:class parseFileTestCase
#@-node:ekr.20090529103821.9336:@suite test syntax of all plugins
#@+node:ekr.20090529103821.9341:@test rClick.py
if g.app.gui.guiName() == 'tkinter':

    import rClick
    rClick.init()
#@-node:ekr.20090529103821.9341:@test rClick.py
#@+node:ekr.20090529103821.9342:detect_urls.py
#@+node:ekr.20090529103821.9343:Startup
import detect_urls

w = c.frame.body.bodyCtrl
s = w.getAllText()
w.setInsertPoint(len(s))
url = detect_urls.openURL(tag='test',keywords={'c':c})
assert url == 'http://webpages.charter.net/edreamleo/front.html','Got:%s' % repr(url)

@ The last line is the url
http://webpages.charter.net/edreamleo/front.html
#@nonl
#@-node:ekr.20090529103821.9343:Startup
#@+node:ekr.20090529103821.9344:Docs
# Only tk gui colorizers with tag_ranges.

if g.app.gui.guiName() == 'tkinter':

    import detect_urls
    w = c.frame.body.bodyCtrl
    s = w.getAllText()
    detect_urls.colorizeURLs(tag='test',keywords={'c':c})
    assert w.tag_ranges('URL'),'no URL tags'

@ The last line is the url
http://webpages.charter.net/edreamleo/front.html
#@nonl
#@-node:ekr.20090529103821.9344:Docs
#@-node:ekr.20090529103821.9342:detect_urls.py
#@+node:ekr.20090529103821.9345:@test mnplugins.insertBodystamp
import mnplugins

w = c.frame.body.bodyCtrl
s = w.getAllText()

try:
    w.setInsertPoint(len(s))
    mnplugins.insertBodystamp(c,p)
    s2 = w.getAllText()
    assert s2.startswith(s)
    assert len(s2) > len(s) + 15
finally:
    w.setAllText(s)
    p.setBodyString(s)
    c.recolor()

# end:
#@nonl
#@-node:ekr.20090529103821.9345:@test mnplugins.insertBodystamp
#@+node:ekr.20090529103821.9346:@test macros.parameterize
import macros

controller = macros.paramClass(c)
controller.parameterize()
    # Not much will happen because there are no children.
    # However, this does test recent changes.
#@nonl
#@-node:ekr.20090529103821.9346:@test macros.parameterize
#@+node:ekr.20090529103821.9347:@test restore the screen
# This is **not** a real unit test.
# It simply restores the screen to a more convenient state.
import leo.core.leoTest as leoTest
u = leoTest.testUtils(c) # This *is* used

c.contractAllHeadlines()
h = 'All unit tests'
p = u.findNodeAnywhere(h)
if p:
    p.expand()
    g.app.unitTestDict['restoreSelectedNode']=False
    c.selectPosition(p)
    c.redraw()

print('\nEnd of plugins unit tests')
#@nonl
#@-node:ekr.20090529103821.9347:@test restore the screen
#@+node:ekr.20090529103821.9349:gui plugins
#@+node:ekr.20090529103821.9350:@test c.vnode2position
trace = False

if trace: print('=' * 20)

for p in c.all_positions():

    p2 = c.vnode2position(p.v)

    if trace: print(p2.level(), p2.headString())

    # We can *not* assert that p == p2, only that
    # p2.v == p.v and c.positionExists(p2)
    assert p2
    assert p2.v == p.v,'p2.v: %s, p.v: %s' % (p2.v,v)
    assert c.positionExists(p2),'does not exist: %s' % p2
#@-node:ekr.20090529103821.9350:@test c.vnode2position
#@+node:ekr.20090529103821.9351:@test position2Item
tree = c.frame.tree

if hasattr(tree,'position2item'): # and hasattr(tree,'item2vnode'):

    c.redraw()

    p = c.rootPosition()
    while p:
        item = tree.position2item(p)
        v = tree.item2vnode(item)
        assert v == p.v, 'item2: %s, p.v: %s' % (item,p.v)
        p.moveToVisNext(c)
#@nonl
#@-node:ekr.20090529103821.9351:@test position2Item
#@+node:ekr.20090529103821.9352:@test item2position
def test_sibs(parent_p,parent_item):

    trace = False
    tree = c.frame.tree
    sib_items = tree.childItems(parent_item)
    sibs = [z for z in parent_p.self_and_siblings_iter(copy=True)]

    assert len(sib_items) == len(sibs),(
        'child_items: %s, children: %s' % (
            g.listToString(sib_items),g.listToString(sibs)))

    for item,p in zip(sib_items,sibs):
        p2 = tree.item2position(item)
        if trace: print (id(item),p2 and p2.headString() or not p2 and '**None**')
        assert p == p2, 'item: %s, p: %s, p2: %s' % (id(item),p,p2)

        # Recursively test.
        child = p.firstChild()
        if child.isVisible(c):
            test_sibs(child,parent_item=item)

if hasattr(c.frame.tree,'item2position'):
    c.redraw()
    test_sibs(c.rootPosition(),None)
#@-node:ekr.20090529103821.9352:@test item2position
#@-node:ekr.20090529103821.9349:gui plugins
#@-node:ekr.20090529103821.9335:plugins
#@+node:ekr.20090529103821.7633:leoApp
#@+node:ekr.20090529103821.7634:@test consistency of leoApp tables
@
language_delims_dict 
    # Keys are languages, values are 1,2 or 3-tuples of delims. 
language_extension_dict
    # Keys are languages, values are extensions.
extension_dict = {
    # Keys are extensions, values are languages.
@c

delims_d    = g.app.language_delims_dict
lang_d      = g.app.language_extension_dict
ext_d       = g.app.extension_dict

for lang in lang_d:
    ext = lang_d.get(lang)
    assert lang in delims_d,'fail 1: %s' % lang
    assert ext in ext_d,'fail 2: %s' % ext
for ext in ext_d:
    lang = ext_d.get(ext)
    assert lang in lang_d,'fail 3: %s' % lang
#@nonl
#@-node:ekr.20090529103821.7634:@test consistency of leoApp tables
#@-node:ekr.20090529103821.7633:leoApp
#@+node:ekr.20090529103821.7640:leoBridge
#@+node:ekr.20090529103821.7641:@test leoBridge init logic
import leo.core.leoBridge as leoBridge

if 0: # This can not be run locally: it contains another Tk event loop.
    controller = leoBridge.controller(gui='nullGui',verbose=False)
    g = controller.globals()
#@-node:ekr.20090529103821.7641:@test leoBridge init logic
#@-node:ekr.20090529103821.7640:leoBridge
#@+node:ekr.20090529103821.7724:leoColor
#@+node:ekr.20090529103821.7725:@test @comment after @language plain
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7726:Startup
@language plain
@comment # /* */

This is plain text.

# This is a comment.

More plain text.

/* A block comment
continues */

More plain text.
#@nonl
#@-node:ekr.20090529103821.7726:Startup
#@-node:ekr.20090529103821.7725:@test @comment after @language plain
#@+node:ekr.20090529103821.7727:@test colorizer Actionscript
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7728:Startup
@language actionscript

break
call, continue
delete, do
else
false, for, function
goto
if, in
new, null
return
true, typeof
undefined
var, void, while, with
#include
catch, constructor
prototype
this, try
_parent, _root, __proto__
// Jeeze hasn't anyone ever heard of namespaces??
ASnative, abs, acos, appendChild, asfunction, asin, atan, atan2, attachMovie, attachSound, attributes
BACKSPACE
CAPSLOCK, CONTROL, ceil, charAt, charCodeAt, childNodes, chr, cloneNode, close, concat, connect, cos, createElement, createTextNode
DELETEKEY, DOWN, docTypeDecl, duplicateMovieClip
END, ENTER, ESCAPE, enterFrame, entry, equal, eval, evaluate, exp
firstChild, floor, fromCharCode, fscommand, getAscii
getBeginIndex, getBounds, getBytesLoaded, getBytesTotal, getCaretIndex, getCode, getDate, getDay, getEndIndex, getFocus, getFullYear, getHours, getMilliseconds, getMinutes, getMonth, getPan, getProperty, getRGB, getSeconds, getTime, getTimer, getTimezoneOffset, getTransform, getURL, getUTCDate, getUTCDay, getUTCFullYear, getUTCHours, getUTCMilliseconds, getUTCMinutes, getUTCMonth, getUTCSeconds, getVersion, getVolume, getYear, globalToLocal, gotoAndPlay, gotoAndStop
HOME, haschildNodes, hide, hitTest
INSERT, Infinity, ifFrameLoaded, ignoreWhite, indexOf, insertBefore, int, isDown, isFinite, isNaN, isToggled
join
keycode, keyDown, keyUp
LEFT, LN10, LN2, LOG10E, LOG2E, lastChild, lastIndexOf, length, load, loaded, loadMovie, loadMovieNum, loadVariables, loadVariablesNum, localToGlobal, log
MAX_VALUE, MIN_VALUE, max, maxscroll, mbchr, mblength, mbord, mbsubstring, min, 
NEGATIVE_INFINITY, NaN, newline, nextFrame, nextScene, nextSibling, nodeName, nodeType, nodeValue
on, onClipEvent, onClose, onConnect, onData, onLoad, onXML, ord
PGDN, PGUP, PI, POSITIVE_INFINITY, parentNode, parseFloat, parseInt, parseXML, play, pop, pow, press, prevFrame, previousSibling, prevScene, print, printAsBitmap, printAsBitmapNum, printNum, push
RIGHT, random, release, removeMovieClip, removeNode, reverse, round
SPACE, SQRT1_2, SQRT2, scroll, send, sendAndLoad, set, setDate, setFocus, setFullYear, setHours, setMilliseconds, setMinutes, setMonth, setPan, setProperty, setRGB, setSeconds, setSelection, setTime, setTransform, setUTCDate, setUTCFullYear, setUTCHours, setUTCMilliseconds, setUTCMinutes, setUTCMonth, setUTCSeconds, setVolume, setYear, shift, show, sin, slice, sort, start, startDrag, status, stop, stopAllSounds, stopDrag, substr, substring, swapDepths, splice, split, sqrt
TAB, tan, targetPath, tellTarget, toggleHighQuality, toLowerCase, toString, toUpperCase, trace
UP, UTC, unescape, unloadMovie, unLoadMovieNum, unshift, updateAfterEvent
valueOf
xmlDecl, _alpha
_currentframe
_droptarget
_focusrect, _framesloaded
_height, _highquality
_name
_quality
_rotation
_soundbuftime
_target, _totalframes
_url
_visible
_width
_x, _xmouse, _xscale
_y, _ymouse, _yscale
and, add, eq, ge, gt, le, lt, ne, not, or, Array, Boolean, Color, Date, Key, Math, MovieClip, Mouse, Number, Object, Selection, Sound, String, XML, XMLSocket
#@nonl
#@-node:ekr.20090529103821.7728:Startup
#@-node:ekr.20090529103821.7727:@test colorizer Actionscript
#@+node:ekr.20090529103821.7729:@test colorizer C
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7730:Startup
@language c
@comment /* */

@
@c

#define WIPEOUT 0 /* 
                   * Causes database card number & flags to be set to zero. 
                   * This is so I don't need an infinite supply of cards!
                   */
// Not colored (because of @language /* */)
#include "equ.h"
#include "cmn.h"
#include "ramdef.h"
#include "eeprom.h"
#include <hpc_ram.h>
#include <rlydef.h>
#@nonl
#@-node:ekr.20090529103821.7730:Startup
#@-node:ekr.20090529103821.7729:@test colorizer C
#@+node:ekr.20090529103821.7731:@test colorizer C#
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7732:Startup
@language csharp
@ comment
@c

/* block
comment */

// test

id // not a keyword

abstract as 
base bool break byte 
case catch char checked class const continue 
decimal default delegate do double 
else enum event explicit extern 
false finally fixed float for foreach 
get goto 
if implicit in int interface internal is 
lock long 
namespace new null 
object operator out override 
params partial private protected public 
readonly ref return 
sbyte sealed set short sizeof stackalloc 
static string struct switch 
this throw true try typeof 
uint ulong unchecked unsafe ushort using 
value virtual void volatile 
where while
yield
#@nonl
#@-node:ekr.20090529103821.7732:Startup
#@-node:ekr.20090529103821.7731:@test colorizer C#
#@+node:ekr.20090529103821.7733:@test colorizer css
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7734:Startup
@language css
/* New in 4.2. */

/*html tags*/
address, applet, area, a, base, basefont,
big, blockquote, body, br, b, caption, center,
cite, code, dd, dfn, dir, div, dl, dt, em, font,
form, h1, h2, h3, h4, h5, h6, head, hr, html, img,
input, isindex, i, kbd, link, li, link, map, menu,
meta, ol, option, param, pre, p, samp,
select, small, span, strike, strong, style, sub, sup,
table, td, textarea, th, title, tr, tt, ul, u, var,
/*units*/
mm, cm, in, pt, pc, em, ex, px,
/*colors*/
aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, purple, red, silver, teal, yellow, white,
/*important directive*/
!important,
/*font rules*/
font, font-family, font-style, font-variant, font-weight, font-size,
/*font values*/
cursive, fantasy, monospace, normal, italic, oblique, small-caps,
bold, bolder, lighter, medium, larger, smaller,
serif, sans-serif,
/*background rules*/
background, background-color, background-image, background-repeat, background-attachment, background-position,
/*background values*/
contained, none, top, center, bottom, left, right, scroll, fixed,
repeat, repeat-x, repeat-y, no-repeat,
/*text rules*/
word-spacing, letter-spacing, text-decoration, vertical-align, text-transform, text-align, text-indent, text-transform, text-shadow, unicode-bidi, line-height,
/*text values*/
normal, none, underline, overline, blink, sub, super, middle, top, text-top, text-bottom,
capitalize, uppercase, lowercase, none, left, right, center, justify,
line-through,
/*box rules*/
margin, margin-top, margin-bottom, margin-left, margin-right,
margin, padding-top, padding-bottom, padding-left, padding-right,
border, border-width, border-style, border-top, border-top-width, border-top-style, border-bottom, border-bottom-width, border-bottom-style, border-left, border-left-width, border-left-style, border-right, border-right-width, border-right-style, border-color,
/*box values*/
width, height, float, clear,
auto, thin, medium, thick, left, right, none, both,
none, dotted, dashed, solid, double, groove, ridge, inset, outset,
/*display rules*/
display, white-space, 
min-width, max-width, min-height, max-height,
outline-color, outline-style, outline-width,
/*display values*/
run-in, inline-block, list-item, block, inline, none, normal, pre, nowrap, table-cell, table-row, table-row-group, table-header-group, inline-table, table-column, table-column-group, table-cell, table-caption
/*list rules*/
list-style, list-style-type, list-style-image, list-style-position,
/*list values*/
disc, circle, square, decimal, decimal-leading-zero, none,
lower-roman, upper-roman, lower-alpha, upper-alpha, lower-latin, upper-latin,
/*table rules*/
border-collapse, caption-side,
/*table-values*/
empty-cells, table-layout,
/*misc values/rules*/
counter-increment, counter-reset,
marker-offset, z-index,
cursor, direction, marks, quotes,
clip, content, orphans, overflow, visibility,
/*aural rules*/
pitch, range, pitch-during, cue-after, pause-after, cue-before, pause-before, speak-header, speak-numeral, speak-punctuation, speed-rate, play-during, voice-family,
/*aural values*/
stress, azimuth, elevation, pitch, richness, volume,
page-break, page-after, page-inside
#@nonl
#@-node:ekr.20090529103821.7734:Startup
#@-node:ekr.20090529103821.7733:@test colorizer css
#@+node:ekr.20090529103821.7735:@test colorizer CWEB
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7736:Startup
@language cweb

% This is limbo in cweb mode... It should be in \LaTeX mode, not \c mode.
% The following should not be colorized: class,if,else.

@* this is a _cweb_ comment.  Code is written in \c.
"strings" should not be colorized.
It should be colored in \LaTeX mode.
The following are not keywords in latex mode: if, else, etc.
Noweb section references are _valid_ in cweb comments!
<< section ref >>
<< missing ref >>
@c

and this is C code. // It is colored in \LaTeX mode by default.
/* This is a C block comment.  It may also be colored in restricted \LaTeX mode. */

// Section refs are valid in code too, of course.
<< section ref >>
<< missing ref >>

\LaTeX and \c should not be colored.
if else, while, do // C keywords.
#@nonl
#@+node:ekr.20090529103821.7737:<< section ref >>
<< section def >>=

    my \c code goes here // This is \LaTeX text
    /* This is also \LaTeX text */
#@nonl
#@-node:ekr.20090529103821.7737:<< section ref >>
#@-node:ekr.20090529103821.7736:Startup
#@-node:ekr.20090529103821.7735:@test colorizer CWEB
#@+node:ekr.20090529103821.7738:@test colorizer elisp
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7739:Startup
@language elisp

; Maybe...
error princ 

; More typical of other lisps...
and apply
car cdr cons cond
defconst defun defvar 
eq equal eval
gt ge
if 
let le lt
mapcar 
ne nil 
or not 
prog progn 
set setq 
t type-of 
unless 
when while
#@nonl
#@-node:ekr.20090529103821.7739:Startup
#@-node:ekr.20090529103821.7738:@test colorizer elisp
#@+node:ekr.20090529103821.7740:@test colorizer erlang
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7741:Startup
@language erlang

halt()

-module()
#@nonl
#@-node:ekr.20090529103821.7741:Startup
#@-node:ekr.20090529103821.7740:@test colorizer erlang
#@+node:ekr.20090529103821.7742:@test colorizer forth
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7743:Startup
@language forth

\ tiny demo of Leo forth syntax colouring

: some-forth-word ( x1 x2 -- x3 ) \ blue :, black/bold some-forth-word
   label: y  \ blue label:
   asm[ s" some string" type ]asm cr
   asm[ abc ]asm
   a
   s" abc "
   s" abc"
   a
   tty" abc "
   lcd2" abc "
   until

@ test
@c

{ abc }

a b @ c

asm[ abc ]asm

.( ab ) \ a string

: foo [ .s ] ;

   [ a b c
   x y z]
;
#@nonl
#@-node:ekr.20090529103821.7743:Startup
#@-node:ekr.20090529103821.7742:@test colorizer forth
#@+node:ekr.20090529103821.7744:@test colorizer HTML string bug
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7745:Startup
@language html

b = "cd"
d
#@-node:ekr.20090529103821.7745:Startup
#@-node:ekr.20090529103821.7744:@test colorizer HTML string bug
#@+node:ekr.20090529103821.7746:@test colorizer HTML1
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7747:Startup
@language html

<HTML>
<!-- Author: Edward K. Ream, edream@tds.net -->
<HEAD>
  <META NAME="GENERATOR" CONTENT="Microsoft FrontPage 4.0">
  <TITLE> Leo's Home Page </TITLE>
  <META NAME="description" CONTENT="This page describes Leo.
Leo adds powerful outlines to the noweb and CWEB literate programming languages.">
  <META NAME="keywords" CONTENT="LEO, LITERATE PROGRAMMING, OUTLINES, CWEB,
NOWEB, OUTLINES, EDWARD K. REAM, DONALD E. KNUTH, SILVIO LEVY, OPEN SOFTWARE">
</HEAD>
<!-- Last Modified: May 12, 2002 -->
<BODY BGCOLOR="#fffbdc">

<H1 ALIGN=CENTER><a NAME="top"></a><IMG SRC="Blank.gif" width=
"32" height="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"><IMG SRC="leo.gif" 
WIDTH="32" HEIGHT="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"><a href="leo_TOC.html#top"><IMG SRC=
"arrow_rt.gif" WIDTH="32" HEIGHT="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"></a> &nbsp;</H1>

<H1 ALIGN=CENTER> Leo's Home Page</H1>

<p align="center"><a href="http://www.python.org/"><img border="0" src="PythonPowered.gif" width="110" height="44"> </a> <A HREF="http://sourceforge.net/"><IMG SRC="http://sourceforge.net/sflogo.php?group_id=3458&type=1" NATURALSIZEFLAG="0" ALT="SourceForge Logo"></A>&nbsp;&nbsp;&nbsp;
<A HREF="http://sourceforge.net/project/?group_id=3458">Leo at SourceForge</A>&nbsp;&nbsp;
<a href="icons.html"><img border="0" src="LeoCodeGray.gif" width="77" height="42"></a>&nbsp;&nbsp;
<a href="icons.html"><img border="0" src="LeoProse.gif" width="81" height="42"></a>&nbsp;&nbsp;&nbsp;&nbsp;

<H3><A NAME="anchor127554"></A>Summary</H3>

<UL>
  <LI>Leo is a <i> programmer's editor</i>  and a flexible <i>browser</i> for
    projects, programs, classes or data. Leo clarifies design, coding, debugging, testing
  and maintenance.
  <LI>Leo is an <i>outlining editor</i>. Outlines clarify the big picture while
    providing unlimited space for details.
  <LI>Leo
    is a <a HREF="http://www.literateprogramming.com/"><i>literate
    programming</i></a> tool, compatible with <A HREF="http://www.eecs.harvard.edu/~nr/noweb/">noweb</A>
    and <a HREF="http://www-cs-faculty.stanford.edu/~knuth/cweb.html">CWEB</a>.
    Leo enhances any text-based
programming language, from assembly language and C to Java, Python and XML.
  <LI>Leo is also a <i>data organizer</i>. A single Leo outline can generate complex
    data spanning many different files.&nbsp; Leo has been used to manage web sites.
  <LI>Leo is a <i> project manager</i>. Leo provides multiple views
of a project within a single outline. Leo naturally represents tasks that remain
    up-to-date.
  <LI>Leo is fully <i> scriptable</i> using <A HREF="http://www.python.org/">Python</A>
  and saves its files in <A HREF="http://www.w3.org/XML/">XML</A> format.
  <LI>Leo is <i>portable</i>.&nbsp; Leo.py is 100% pure Python and will run on
    any platform supporting <A HREF="http://www.python.org/">Python</A>
    and <a href="http://tcl.activestate.com/">Tk/tcl</a>, including Windows,
    Linux and MacOS X.&nbsp; Leo.exe runs on any Windows platform.
  <LI>Leo is <a href="http://www.opensource.org/"> <i> Open Software</i></a>, distributed under
    the <a href="http://www.python.org/doc/Copyright.html"> Python License</a>.
</UL>

<H3>More Information and downloads</H3>

<ul>
  <LI>An excellent <a href="http://www.3dtree.com/ev/e/sbooks/leo/sbframetoc_ie.htm">online
    tutorial</a> and <A HREF="http://www.jserv.com/jk_orr/xml/leo.htm">Leo resource
  page</A>, both written by <a href="http://www.jserv.com/jk_orr">Joe Orr</a>.
  <LI>My brother's <a href="SpeedReam.html">slashdot
    article about Leo</a>, the best description about why Leo is special.
  <LI><A HREF="testimonials.html#anchor104391">What people are saying about Leo</A>
  <LI><A HREF="leo_TOC.html#anchor964914">Complete users guide</A>
    and
    <A HREF="intro.html#anchor887874">tutorial introduction</A>  with
  screen shots.
  <li><a href="FAQ.html">FAQ</a> and <a href="http://sourceforge.net/forum/?group_id=3458">help and discussion
    forums</a>, preferable to <A HREF="mailto:edream@tds.net">email</A> so others may join
    in.</li>
  <li><a href="icons.html">Icons</a> for bragging about Leo.</li>
</ul>

<a href="http://sourceforge.net/project/showfiles.php?group_id=3458">Download
    Leo</a> from <A HREF="http://sourceforge.net/project/?group_id=3458">Leo's SourceForge
site</A>.

<P ALIGN=left>Leo's author is <A HREF="http://personalpages.tds.net/~edream/index.html">Edward
  K. Ream</A> email: <A HREF="mailto:edream@tds.net">edream@tds.net</A> voice: (608) 231-0766

<HR ALIGN=LEFT>

<p align="center">

<IMG SRC="Blank.gif" ALIGN="left" NATURALSIZEFLAG=
"3" width="34" height="34"><IMG SRC="leo.gif" ALIGN="left" NATURALSIZEFLAG=
"3" width="32" height="32"><a HREF="leo_TOC.html"><IMG SRC="arrow_rt.gif" WIDTH="32"
HEIGHT="32" ALIGN="left" NATURALSIZEFLAG="3">

</BODY>
</HTML>
#@nonl
#@-node:ekr.20090529103821.7747:Startup
#@-node:ekr.20090529103821.7746:@test colorizer HTML1
#@+node:ekr.20090529103821.7748:@test colorizer HTML2
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7749:Startup
@language html

<? xml version="1.0">
<!-- test -->
<project name="Converter" default="dist">
</project>"""
#@nonl
#@-node:ekr.20090529103821.7749:Startup
#@-node:ekr.20090529103821.7748:@test colorizer HTML2
#@+node:ekr.20090529103821.7750:@test colorizer Java
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7751:Startup
@ doc part
@c

@language java /* Colored by match_leo_keyword: tag = leoKeyword. */

@whatever /* Colored by java match_following rule: tag = keyword4. */

/** A javadoc: tag = comment3 */

/** <!-- comment --> tag = comment1. */

/** @see tag = label */
#@nonl
#@-node:ekr.20090529103821.7751:Startup
#@-node:ekr.20090529103821.7750:@test colorizer Java
#@+node:ekr.20090529103821.7752:@test colorizer LaTex
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7753:Startup
@language latex

% This is a \LaTeX mode comment.

This is a test of \LaTeX mode.

@ blah blah blah
@c

\c and \LaTeX are latex keywords.

This is a keyword \% not the start of a comment.

More keywords: \@ and \( and \) and \{ and \}

The following should be colored:

\documentclass{report}

The following 2-letter words should be colored, regardless of what follows:

\(\)\{\}\@
\(abc\)abc\{abc\}abc\@abc
#@nonl
#@-node:ekr.20090529103821.7753:Startup
#@-node:ekr.20090529103821.7752:@test colorizer LaTex
#@+node:ekr.20090529103821.7754:@test colorizer lisp
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7755:Startup
@language lisp

; Maybe...
error princ 

; More typical of other lisps...
and apply
car cdr cons cond
defconst defun defvar 
eq equal eval
gt ge
if 
let le lt
mapcar 
ne nil 
or not 
prog progn 
set setq 
t type-of 
unless 
when while
#@nonl
#@-node:ekr.20090529103821.7755:Startup
#@-node:ekr.20090529103821.7754:@test colorizer lisp
#@+node:ekr.20090529103821.7756:@test colorizer perl
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7757:Startup
@language perl

# From a perl tutorial.

print 'Hello world.';		# Print a message

$a = $b;	# Assign $b to $a

@food  = ("apples", "pears", "eels");

$grub = pop(@food);	# Now $grub = "eels"

$#food

@lines = <INFO>;

#!/usr/local/bin/perl
print "Password? ";		# Ask for input
$a = <STDIN>;			# Get input
chop $a;			# Remove the newline at end
while ($a ne "fred")		# While input is wrong...
{
    print "sorry. Again? ";	# Ask again
    $a = <STDIN>;		# Get input again
    chop $a;			# Chop off newline again
}

if ($sentence =~ /under/)
{
	print "We're talking about rugby\\n";
}

$sentence =~ s/london/London/

$_ = "Capes:Geoff::Shot putter:::Big Avenue";
@personal = split(/:/);

foreach $age (values %ages)
{
	print "Somebody is $age\\n";
}

&mysubroutine;		# Call the subroutine
&mysubroutine($_);	# Call it with a parameter
&mysubroutine(1+2, $_);	# Call it with two parameters

sub inside
{
	local($a, $b);			# Make local variables
	($a, $b) = ($_[0], $_[1]);	# Assign values
	$a =~ s/ //g;			# Strip spaces from
	$b =~ s/ //g;			#   local variables
	($a =~ /$b/ || $b =~ /$a/);	# Is $b inside $a
					#   or $a inside $b?
}
#@nonl
#@-node:ekr.20090529103821.7757:Startup
#@-node:ekr.20090529103821.7756:@test colorizer perl
#@+node:ekr.20090529103821.7758:@test colorizer PHP
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7759:Startup
@language php
@ doc
This is a doc part.
@c

and or
array
array()
/* Multi-line comment
*/
this is a test.
__CLASS__
<?php and or array() ?>
<?PHP and or array() ?>
#@nonl
#@-node:ekr.20090529103821.7759:Startup
#@-node:ekr.20090529103821.7758:@test colorizer PHP
#@+node:ekr.20090529103821.7760:@test colorizer plsql
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7761:Startup
@language plsql

"a string"
-- reserved keywords
ABORT,
abort,
ACceSS,
access,
add,
all,
allocate,
alter,
analyze,
and,
any,
archive,
archivelog,
array,
arraylen,
as,
asc,
assert,
assign,
at,
audit,
authorization,
avg,
backup,
base_table,
become,
before,
begin,
between,
binary_integer,
block,
body,
boolean,
by,
cache,
cancel,
cascade,
case,
change,
char,
char_base,
character,
check,
checkpoint,
close,
cluster,
clusters,
cobol,
colauth,
column,
columns,
comment,
commit,
compile,
compress,
connect,
constant,
constraint,
constraints,
contents,
continue,
controlfile,
count,
crash,
create,
current,
currval,
cursor,
cycle,
data_base,
database,
datafile,
date,
dba,
debugoff,
debugon,
dec,
decimal,
declare,
default,
definition,
delay,
delete,
delta,
desc,
digits,
disable,
dismount,
dispose,
distinct,
distinct,
do,
double,
drop,
drop,
dump,
each,
else,
else,
elsif,
enable,
end,
end,
entry,
escape,
events,
except,
exception,
exception_init,
exceptions,
exclusive,
exec,
execute,
exists,
exists,
exit,
explain,
extent,
externally,
false,
fetch,
fetch,
file,
float,
float,
flush,
for,
for,
force,
foreign,
form,
fortran,
found,
freelist,
freelists,
from,
from,
function,
generic,
go,
goto,
grant,
group,
groups,
having,
identified,
if,
immediate,
in,
including,
increment,
index,
indexes,
indicator,
initial,
initrans,
insert,
instance,
int,
integer,
intersect,
into,
is,
key,
language,
layer,
level,
like,
limited,
link,
lists,
lock,
logfile,
long,
loop,
manage,
manual,
max,
maxdatafiles,
maxextents,
maxinstances,
maxlogfiles,
maxloghistory,
maxlogmembers,
maxtrans,
maxvalue,
min,
minextents,
minus,
minvalue,
mlslabel,
mod,
mode,
modify,
module,
mount,
natural,
new,
new,
next,
nextval,
noarchivelog,
noaudit,
nocache,
nocompress,
nocycle,
nomaxvalue,
nominvalue,
none,
noorder,
noresetlogs,
normal,
nosort,
not,
notfound,
nowait,
null,
number,
number_base,
numeric,
of,
off,
offline,
old,
on,
online,
only,
open,
open,
optimal,
option,
or,
order,
others,
out,
own,
package,
package,
parallel,
partition,
pctfree,
pctincrease,
pctused,
plan,
pli,
positive,
pragma,
precision,
primary,
prior,
private,
private,
privileges,
procedure,
procedure,
profile,
public,
quota,
raise,
range,
raw,
read,
real,
record,
recover,
references,
referencing,
release,
remr,
rename,
resetlogs,
resource,
restricted,
return,
reuse,
reverse,
revoke,
role,
roles,
rollback,
row,
rowid,
rowlabel,
rownum,
rows,
rowtype,
run,
savepoint,
schema,
scn,
section,
segment,
select,
select,
separate,
sequence,
session,
set,
set,
share,
shared,
size,
size,
smallint,
smallint,
snapshot,
some,
sort,
space,
sql,
sqlbuf,
sqlcode,
sqlerrm,
sqlerror,
sqlstate,
start,
start,
statement,
statement_id,
statistics,
stddev,
stop,
storage,
subtype,
successful,
sum,
sum,
switch,
synonym,
sysdate,
system,
tabauth,
table,
tables,
tables,
tablespace,
task,
temporary,
terminate,
then,
thread,
time,
to,
tracing,
transaction,
trigger,
triggers,
true,
truncate,
type,
uid,
under,
union,
unique,
unlimited,
until,
update,
use,
user,
using,
validate,
values,
varchar,
varchar2,
variance,
view,
views,
when,
whenever,
where,
while,
with,
work,
write,
xor
#@nonl
#@-node:ekr.20090529103821.7761:Startup
#@-node:ekr.20090529103821.7760:@test colorizer plsql
#@+node:ekr.20090529103821.7762:@test colorizer python.xml (jEdit)
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7763:Startup
@language html

<?xml version="1.0"?>

<!DOCTYPE MODE SYSTEM "xmode.dtd">
<< remarks >>

<MODE>
    <PROPS>
        <PROPERTY NAME="indentPrevLine" VALUE="\s*.{3,}:\s*(#.*)?" />
        <PROPERTY NAME="lineComment" VALUE="#" />
    </PROPS>
    <RULES ESCAPE="\" IGNORE_CASE="FALSE" HIGHLIGHT_DIGITS="TRUE">
        << comments >>
        << literals >>
        << operators >>
        <MARK_PREVIOUS TYPE="FUNCTION" EXCLUDE_MATCH="TRUE">(</MARK_PREVIOUS>
        << keywords >>
    </RULES>
</MODE>
#@nonl
#@+node:ekr.20090529103821.7764:<< remarks >>
<!-- Python mode, by Slava Pestov. Based on PythonTokenMarker by -->
<!-- Jonathan Revusky -->

<!-- Modified 19-Jul-00 by Ivan Frohne to: -->
<!--  (a) implement 'indentOnEnter'; -->
<!--  (b) indent next line automatically after control structures followed -->
<!--	  by ':'; -->
<!--  (c) make """ or ''' multiline quotes TYPE LITERAL2; -->
<!--  (d) add TYPE FUNCTION identified by a following '(' -->
<!--  (e) eliminate the '?' SEQ TYPE ('?' has no meaning in Python); -->
<!--  (f) change the TYPE of 'and', 'or', and 'not' to KEYWORD1; and -->
<!--  (g) add all builtin functions, builtin exceptions, -->
<!--	  builtin type methods, File object methods, and special type -->
<!--	  attributes as TYPE KEYWORD3. -->
#@nonl
#@-node:ekr.20090529103821.7764:<< remarks >>
#@+node:ekr.20090529103821.7765:<< comments >>
<!-- Comment -->
<EOL_SPAN TYPE="COMMENT1">#</EOL_SPAN>

<!-- Triple-quotes -->
<SPAN TYPE="LITERAL2">
    <BEGIN>"""</BEGIN>
    <END>"""</END>
</SPAN>

<SPAN TYPE="LITERAL2">
    <BEGIN>'''</BEGIN>
    <END>'''</END>
</SPAN>
#@nonl
#@-node:ekr.20090529103821.7765:<< comments >>
#@+node:ekr.20090529103821.7766:<< literals >>
<!-- Standard literals -->
<SPAN TYPE="LITERAL1">
    <BEGIN>"</BEGIN>
    <END>"</END>
</SPAN>

<SPAN TYPE="LITERAL1">
    <BEGIN>'</BEGIN>
    <END>'</END>
</SPAN>
#@-node:ekr.20090529103821.7766:<< literals >>
#@+node:ekr.20090529103821.7767:<< operators >>
<SEQ TYPE="OPERATOR">=</SEQ>
<SEQ TYPE="OPERATOR">!</SEQ>
<SEQ TYPE="OPERATOR">&gt;=</SEQ>
<SEQ TYPE="OPERATOR">&lt;=</SEQ>
<SEQ TYPE="OPERATOR">+</SEQ>
<SEQ TYPE="OPERATOR">-</SEQ>
<SEQ TYPE="OPERATOR">/</SEQ>
<SEQ TYPE="OPERATOR">*</SEQ>
<SEQ TYPE="OPERATOR">&gt;</SEQ>
<SEQ TYPE="OPERATOR">&lt;</SEQ>
<SEQ TYPE="OPERATOR">%</SEQ>
<SEQ TYPE="OPERATOR">&amp;</SEQ>
<SEQ TYPE="OPERATOR">|</SEQ>
<SEQ TYPE="OPERATOR">^</SEQ>
<SEQ TYPE="OPERATOR">~</SEQ>
#@nonl
#@-node:ekr.20090529103821.7767:<< operators >>
#@+node:ekr.20090529103821.7768:<< keywords >>
<KEYWORDS>
    << reserved words >>
    << builtins >>
    << exceptions >>
    << types >>
</KEYWORDS>
#@nonl
#@+node:ekr.20090529103821.7769:<< reserved words >>
<!--  Reserved Words  -->
<KEYWORD1>and</KEYWORD1>
<KEYWORD1>as</KEYWORD1>
<KEYWORD1>assert</KEYWORD1>
<KEYWORD1>break</KEYWORD1>
<KEYWORD1>class</KEYWORD1>
<KEYWORD1>continue</KEYWORD1>
<KEYWORD1>def</KEYWORD1>
<KEYWORD1>del</KEYWORD1>
<KEYWORD1>elif</KEYWORD1>
<KEYWORD1>else</KEYWORD1>
<KEYWORD1>except</KEYWORD1>
<KEYWORD1>exec</KEYWORD1>
<KEYWORD1>finally</KEYWORD1>
<KEYWORD1>for</KEYWORD1>
<KEYWORD1>from</KEYWORD1>
<KEYWORD1>global</KEYWORD1>
<KEYWORD1>if</KEYWORD1>
<KEYWORD1>import</KEYWORD1>
<KEYWORD1>in</KEYWORD1>
<KEYWORD1>is</KEYWORD1>
<KEYWORD1>lambda</KEYWORD1>
<KEYWORD1>not</KEYWORD1>
<KEYWORD1>or</KEYWORD1>
<KEYWORD1>pass</KEYWORD1>
<KEYWORD1>print</KEYWORD1>
<KEYWORD1>raise</KEYWORD1>
<KEYWORD1>return</KEYWORD1>
<KEYWORD1>try</KEYWORD1>
<KEYWORD1>while</KEYWORD1>
<KEYWORD1>yield</KEYWORD1>
#@nonl
#@-node:ekr.20090529103821.7769:<< reserved words >>
#@+node:ekr.20090529103821.7770:<< builtins >>
<!-- builtins -->
<KEYWORD2>abs</KEYWORD2>
<KEYWORD2>apply</KEYWORD2>
<KEYWORD2>bool</KEYWORD2>
<KEYWORD2>buffer</KEYWORD2>
<KEYWORD2>callable</KEYWORD2>
<KEYWORD2>chr</KEYWORD2>
<KEYWORD2>classmethod</KEYWORD2>
<KEYWORD2>cmp</KEYWORD2>
<KEYWORD2>coerce</KEYWORD2>
<KEYWORD2>compile</KEYWORD2>
<KEYWORD2>complex</KEYWORD2>
<KEYWORD2>delattr</KEYWORD2>
<KEYWORD2>dict</KEYWORD2>
<KEYWORD2>dir</KEYWORD2>
<KEYWORD2>divmod</KEYWORD2>
<KEYWORD2>eval</KEYWORD2>
<KEYWORD2>execfile</KEYWORD2>
<KEYWORD2>file</KEYWORD2>
<KEYWORD2>filter</KEYWORD2>
<KEYWORD2>float</KEYWORD2>
<KEYWORD2>getattr</KEYWORD2>
<KEYWORD2>globals</KEYWORD2>
<KEYWORD2>hasattr</KEYWORD2>
<KEYWORD2>hash</KEYWORD2>
<KEYWORD2>hex</KEYWORD2>
<KEYWORD2>id</KEYWORD2>
<KEYWORD2>input</KEYWORD2>
<KEYWORD2>int</KEYWORD2>
<KEYWORD2>intern</KEYWORD2>
<KEYWORD2>isinstance</KEYWORD2>
<KEYWORD2>issubclass</KEYWORD2>
<KEYWORD2>iter</KEYWORD2>
<KEYWORD2>len</KEYWORD2>
<KEYWORD2>list</KEYWORD2>
<KEYWORD2>locals</KEYWORD2>
<KEYWORD2>long</KEYWORD2>
<KEYWORD2>map</KEYWORD2>
<KEYWORD2>max</KEYWORD2>
<KEYWORD2>min</KEYWORD2>
<KEYWORD2>object</KEYWORD2>
<KEYWORD2>oct</KEYWORD2>
<KEYWORD2>open</KEYWORD2>
<KEYWORD2>ord</KEYWORD2>
<KEYWORD2>pow</KEYWORD2>
<KEYWORD2>property</KEYWORD2>
<KEYWORD2>range</KEYWORD2>
<KEYWORD2>raw_input</KEYWORD2>
<KEYWORD2>reduce</KEYWORD2>
<KEYWORD2>reload</KEYWORD2>
<KEYWORD2>repr</KEYWORD2>
<KEYWORD2>round</KEYWORD2>
<KEYWORD2>setattr</KEYWORD2>
<KEYWORD2>slice</KEYWORD2>
<KEYWORD2>staticmethod</KEYWORD2>
<KEYWORD2>str</KEYWORD2>
<KEYWORD2>super</KEYWORD2>
<KEYWORD2>tuple</KEYWORD2>
<KEYWORD2>type</KEYWORD2>
<KEYWORD2>unichr</KEYWORD2>
<KEYWORD2>unicode</KEYWORD2>
<KEYWORD2>vars</KEYWORD2>
<KEYWORD2>xrange</KEYWORD2>
<KEYWORD2>zip</KEYWORD2>
#@nonl
#@-node:ekr.20090529103821.7770:<< builtins >>
#@+node:ekr.20090529103821.7771:<< exceptions >>
<!-- exceptions -->
<KEYWORD3>ArithmeticError</KEYWORD3>
<KEYWORD3>AssertionError</KEYWORD3>
<KEYWORD3>AttributeError</KEYWORD3>
<KEYWORD3>DeprecationWarning</KEYWORD3>
<KEYWORD3>EOFError</KEYWORD3>
<KEYWORD3>EnvironmentError</KEYWORD3>
<KEYWORD3>Exception</KEYWORD3>
<KEYWORD3>FloatingPointError</KEYWORD3>
<KEYWORD3>IOError</KEYWORD3>
<KEYWORD3>ImportError</KEYWORD3>
<KEYWORD3>IndentationError</KEYWORD3>
<KEYWORD3>IndexError</KEYWORD3>
<KEYWORD3>KeyError</KEYWORD3>
<KEYWORD3>KeyboardInterrupt</KEYWORD3>
<KEYWORD3>LookupError</KEYWORD3>
<KEYWORD3>MemoryError</KEYWORD3>
<KEYWORD3>NameError</KEYWORD3>
<KEYWORD3>NotImplemented</KEYWORD3>
<KEYWORD3>NotImplementedError</KEYWORD3>
<KEYWORD3>OSError</KEYWORD3>
<KEYWORD3>OverflowError</KEYWORD3>
<KEYWORD3>OverflowWarning</KEYWORD3>
<KEYWORD3>ReferenceError</KEYWORD3>
<KEYWORD3>RuntimeError</KEYWORD3>
<KEYWORD3>RuntimeWarning</KEYWORD3>
<KEYWORD3>StandardError</KEYWORD3>
<KEYWORD3>StopIteration</KEYWORD3>
<KEYWORD3>SyntaxError</KEYWORD3>
<KEYWORD3>SyntaxWarning</KEYWORD3>
<KEYWORD3>SystemError</KEYWORD3>
<KEYWORD3>SystemExit</KEYWORD3>
<KEYWORD3>TabError</KEYWORD3>
<KEYWORD3>TypeError</KEYWORD3>
<KEYWORD3>UnboundLocalError</KEYWORD3>
<KEYWORD3>UnicodeError</KEYWORD3>
<KEYWORD3>UserWarning</KEYWORD3>
<KEYWORD3>ValueError</KEYWORD3>
<KEYWORD3>Warning</KEYWORD3>
<KEYWORD3>WindowsError</KEYWORD3>
<KEYWORD3>ZeroDivisionError</KEYWORD3>
#@nonl
#@-node:ekr.20090529103821.7771:<< exceptions >>
#@+node:ekr.20090529103821.7772:<< types >>
<!-- types (from types module) -->
<KEYWORD3>BufferType</KEYWORD3>
<KEYWORD3>BuiltinFunctionType</KEYWORD3>
<KEYWORD3>BuiltinMethodType</KEYWORD3>
<KEYWORD3>ClassType</KEYWORD3>
<KEYWORD3>CodeType</KEYWORD3>
<KEYWORD3>ComplexType</KEYWORD3>
<KEYWORD3>DictProxyType</KEYWORD3>
<KEYWORD3>DictType</KEYWORD3>
<KEYWORD3>DictionaryType</KEYWORD3>
<KEYWORD3>EllipsisType</KEYWORD3>
<KEYWORD3>FileType</KEYWORD3>
<KEYWORD3>FloatType</KEYWORD3>
<KEYWORD3>FrameType</KEYWORD3>
<KEYWORD3>FunctionType</KEYWORD3>
<KEYWORD3>GeneratorType</KEYWORD3>
<KEYWORD3>InstanceType</KEYWORD3>
<KEYWORD3>IntType</KEYWORD3>
<KEYWORD3>LambdaType</KEYWORD3>
<KEYWORD3>ListType</KEYWORD3>
<KEYWORD3>LongType</KEYWORD3>
<KEYWORD3>MethodType</KEYWORD3>
<KEYWORD3>ModuleType</KEYWORD3>
<KEYWORD3>NoneType</KEYWORD3>
<KEYWORD3>ObjectType</KEYWORD3>
<KEYWORD3>SliceType</KEYWORD3>
<KEYWORD3>StringType</KEYWORD3>
<KEYWORD3>StringTypes</KEYWORD3>
<KEYWORD3>TracebackType</KEYWORD3>
<KEYWORD3>TupleType</KEYWORD3>
<KEYWORD3>TypeType</KEYWORD3>
<KEYWORD3>UnboundMethodType</KEYWORD3>
<KEYWORD3>UnicodeType</KEYWORD3>
<KEYWORD3>XRangeType</KEYWORD3>

<KEYWORD3>False</KEYWORD3>
<KEYWORD3>None</KEYWORD3>
<KEYWORD3>True</KEYWORD3>

<KEYWORD3>__abs__</KEYWORD3>
<KEYWORD3>__add__</KEYWORD3>
<KEYWORD3>__all__</KEYWORD3>
<KEYWORD3>__author__</KEYWORD3>
<KEYWORD3>__bases__</KEYWORD3>
<KEYWORD3>__builtins__</KEYWORD3>
<KEYWORD3>__call__</KEYWORD3>
<KEYWORD3>__class__</KEYWORD3>
<KEYWORD3>__cmp__</KEYWORD3>
<KEYWORD3>__coerce__</KEYWORD3>
<KEYWORD3>__contains__</KEYWORD3>
<KEYWORD3>__debug__</KEYWORD3>
<KEYWORD3>__del__</KEYWORD3>
<KEYWORD3>__delattr__</KEYWORD3>
<KEYWORD3>__delitem__</KEYWORD3>
<KEYWORD3>__delslice__</KEYWORD3>
<KEYWORD3>__dict__</KEYWORD3>
<KEYWORD3>__div__</KEYWORD3>
<KEYWORD3>__divmod__</KEYWORD3>
<KEYWORD3>__doc__</KEYWORD3>
<KEYWORD3>__eq__</KEYWORD3>
<KEYWORD3>__file__</KEYWORD3>
<KEYWORD3>__float__</KEYWORD3>
<KEYWORD3>__floordiv__</KEYWORD3>
<KEYWORD3>__future__</KEYWORD3>
<KEYWORD3>__ge__</KEYWORD3>
<KEYWORD3>__getattr__</KEYWORD3>
<KEYWORD3>__getattribute__</KEYWORD3>
<KEYWORD3>__getitem__</KEYWORD3>
<KEYWORD3>__getslice__</KEYWORD3>
<KEYWORD3>__gt__</KEYWORD3>
<KEYWORD3>__hash__</KEYWORD3>
<KEYWORD3>__hex__</KEYWORD3>
<KEYWORD3>__iadd__</KEYWORD3>
<KEYWORD3>__import__</KEYWORD3>
<KEYWORD3>__imul__</KEYWORD3>
<KEYWORD3>__init__</KEYWORD3>
<KEYWORD3>__int__</KEYWORD3>
<KEYWORD3>__invert__</KEYWORD3>
<KEYWORD3>__iter__</KEYWORD3>
<KEYWORD3>__le__</KEYWORD3>
<KEYWORD3>__len__</KEYWORD3>
<KEYWORD3>__long__</KEYWORD3>
<KEYWORD3>__lshift__</KEYWORD3>
<KEYWORD3>__lt__</KEYWORD3>
<KEYWORD3>__members__</KEYWORD3>
<KEYWORD3>__metaclass__</KEYWORD3>
<KEYWORD3>__mod__</KEYWORD3>
<KEYWORD3>__mro__</KEYWORD3>
<KEYWORD3>__mul__</KEYWORD3>
<KEYWORD3>__name__</KEYWORD3>
<KEYWORD3>__ne__</KEYWORD3>
<KEYWORD3>__neg__</KEYWORD3>
<KEYWORD3>__new__</KEYWORD3>
<KEYWORD3>__nonzero__</KEYWORD3>
<KEYWORD3>__oct__</KEYWORD3>
<KEYWORD3>__or__</KEYWORD3>
<KEYWORD3>__path__</KEYWORD3>
<KEYWORD3>__pos__</KEYWORD3>
<KEYWORD3>__pow__</KEYWORD3>
<KEYWORD3>__radd__</KEYWORD3>
<KEYWORD3>__rdiv__</KEYWORD3>
<KEYWORD3>__rdivmod__</KEYWORD3>
<KEYWORD3>__reduce__</KEYWORD3>
<KEYWORD3>__repr__</KEYWORD3>
<KEYWORD3>__rfloordiv__</KEYWORD3>
<KEYWORD3>__rlshift__</KEYWORD3>
<KEYWORD3>__rmod__</KEYWORD3>
<KEYWORD3>__rmul__</KEYWORD3>
<KEYWORD3>__ror__</KEYWORD3>
<KEYWORD3>__rpow__</KEYWORD3>
<KEYWORD3>__rrshift__</KEYWORD3>
<KEYWORD3>__rsub__</KEYWORD3>
<KEYWORD3>__rtruediv__</KEYWORD3>
<KEYWORD3>__rxor__</KEYWORD3>
<KEYWORD3>__setattr__</KEYWORD3>
<KEYWORD3>__setitem__</KEYWORD3>
<KEYWORD3>__setslice__</KEYWORD3>
<KEYWORD3>__self__</KEYWORD3>
<KEYWORD3>__slots__</KEYWORD3>
<KEYWORD3>__str__</KEYWORD3>
<KEYWORD3>__sub__</KEYWORD3>
<KEYWORD3>__truediv__</KEYWORD3>
<KEYWORD3>__version__</KEYWORD3>
<KEYWORD3>__xor__</KEYWORD3>
#@nonl
#@-node:ekr.20090529103821.7772:<< types >>
#@-node:ekr.20090529103821.7768:<< keywords >>
#@-node:ekr.20090529103821.7763:Startup
#@-node:ekr.20090529103821.7762:@test colorizer python.xml (jEdit)
#@+node:ekr.20090529103821.7773:@test colorizer Python1
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7774:Startup
@language plsql

"a string"
-- reserved keywords
abort
accept,
access,
add,
admin,
after,
all,
allocate,
alter,
analyze,
and,
any,
archive,
archivelog,
array,
arraylen,
as,
asc,
assert,
assign,
at,
audit,
authorization,
avg,
backup,
base_table,
become,
before,
begin,
between,
binary_integer,
block,
body,
boolean,
by,
cache,
cancel,
cascade,
case,
change,
char,
char_base,
character,
check,
checkpoint,
close,
cluster,
clusters,
cobol,
colauth,
column,
columns,
comment,
commit,
compile,
compress,
connect,
constant,
constraint,
constraints,
contents,
continue,
controlfile,
count,
crash,
create,
current,
currval,
cursor,
cycle,
data_base,
database,
datafile,
date,
dba,
debugoff,
debugon,
dec,
decimal,
declare,
default,
definition,
delay,
delete,
delta,
desc,
digits,
disable,
dismount,
dispose,
distinct,
distinct,
do,
double,
drop,
drop,
dump,
each,
else,
else,
elsif,
enable,
end,
end,
entry,
escape,
events,
except,
exception,
exception_init,
exceptions,
exclusive,
exec,
execute,
exists,
exists,
exit,
explain,
extent,
externally,
false,
fetch,
fetch,
file,
float,
float,
flush,
for,
for,
force,
foreign,
form,
fortran,
found,
freelist,
freelists,
from,
from,
function,
generic,
go,
goto,
grant,
group,
groups,
having,
identified,
if,
immediate,
in,
including,
increment,
index,
indexes,
indicator,
initial,
initrans,
insert,
instance,
int,
integer,
intersect,
into,
is,
key,
language,
layer,
level,
like,
limited,
link,
lists,
lock,
logfile,
long,
loop,
manage,
manual,
max,
maxdatafiles,
maxextents,
maxinstances,
maxlogfiles,
maxloghistory,
maxlogmembers,
maxtrans,
maxvalue,
min,
minextents,
minus,
minvalue,
mlslabel,
mod,
mode,
modify,
module,
mount,
natural,
new,
new,
next,
nextval,
noarchivelog,
noaudit,
nocache,
nocompress,
nocycle,
nomaxvalue,
nominvalue,
none,
noorder,
noresetlogs,
normal,
nosort,
not,
notfound,
nowait,
null,
number,
number_base,
numeric,
of,
off,
offline,
old,
on,
online,
only,
open,
open,
optimal,
option,
or,
order,
others,
out,
own,
package,
package,
parallel,
partition,
pctfree,
pctincrease,
pctused,
plan,
pli,
positive,
pragma,
precision,
primary,
prior,
private,
private,
privileges,
procedure,
procedure,
profile,
public,
quota,
raise,
range,
raw,
read,
real,
record,
recover,
references,
referencing,
release,
remr,
rename,
resetlogs,
resource,
restricted,
return,
reuse,
reverse,
revoke,
role,
roles,
rollback,
row,
rowid,
rowlabel,
rownum,
rows,
rowtype,
run,
savepoint,
schema,
scn,
section,
segment,
select,
select,
separate,
sequence,
session,
set,
set,
share,
shared,
size,
size,
smallint,
smallint,
snapshot,
some,
sort,
space,
sql,
sqlbuf,
sqlcode,
sqlerrm,
sqlerror,
sqlstate,
start,
start,
statement,
statement_id,
statistics,
stddev,
stop,
storage,
subtype,
successful,
sum,
sum,
switch,
synonym,
sysdate,
system,
tabauth,
table,
tables,
tables,
tablespace,
task,
temporary,
terminate,
then,
thread,
time,
to,
tracing,
transaction,
trigger,
triggers,
true,
truncate,
type,
uid,
under,
union,
unique,
unlimited,
until,
update,
use,
user,
using,
validate,
values,
varchar,
varchar2,
variance,
view,
views,
when,
whenever,
where,
while,
with,
work,
write,
xor
#@nonl
#@-node:ekr.20090529103821.7774:Startup
#@-node:ekr.20090529103821.7773:@test colorizer Python1
#@+node:ekr.20090529103821.7775:@test colorizer Python2
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7776:Startup
"""This creates a free-floating copy of v's tree for undo.
The copied trees must use different tnodes than the original."""

def copyTree(self,root):

    c = self
    # Create the root vnode.
    result = v = leoNodes.vnode(c,root.t)
    # Copy the headline and icon values v.copyNode(root,v)
    # Copy the rest of tree.
    v.copyTree(root,v)
    # Replace all tnodes in v by copies.
    assert(v.nodeAfterTree() == None)
    while v:
        v.t = leoNodes.tnode(0, v.b)
        v = v.threadNext()
    return result
#@nonl
#@-node:ekr.20090529103821.7776:Startup
#@-node:ekr.20090529103821.7775:@test colorizer Python2
#@+node:ekr.20090529103821.7777:@test colorizer r
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7778:Startup
@language r

x <- rnorm(10) 

vv <- function(z) return(z) 

def python_funct(uu): 
return uu
#@nonl
#@-node:ekr.20090529103821.7778:Startup
#@-node:ekr.20090529103821.7777:@test colorizer r
#@+node:ekr.20090529103821.7779:@test colorizer rapidq
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7780:Startup
' New in 4.2.
@language rapidq
' a comment.

$APPTYPE,$DEFINE,$ELSE,$ENDIF,$ESCAPECHARS,$IFDEF,$IFNDEF,
$INCLUDE,$MACRO,$OPTIMIZE,$OPTION,$RESOURCE,$TYPECHECK,$UNDEF,
ABS,ACOS,ALIAS,AND,AS,ASC,ASIN,ATAN,ATN,BIN$,BIND,BYTE,
CALL,CALLBACK,CALLFUNC,CASE,CEIL,CHDIR,CHDRIVE,CHR$,CINT,
CLNG,CLS,CODEPTR,COMMAND$,COMMANDCOUNT,CONSOLE,CONST,CONSTRUCTOR,
CONVBASE$,COS,CREATE,CSRLIN,CURDIR$,DATA,DATE$,DEC,DECLARE,
DEFBYTE,DEFDBL,DEFDWORD,DEFINT,DEFLNG,DEFSHORT,DEFSNG,DEFSTR,
DEFWORD,DELETE$,DIM,DIR$,DIREXISTS,DO,DOEVENTS,DOUBLE,DWORD,
ELSE,ELSEIF,END,ENVIRON,ENVIRON$,EVENT,EXIT,EXP,EXTENDS,
EXTRACTRESOURCE,FIELD$,FILEEXISTS,FIX,FLOOR,FOR,FORMAT$,FRAC,
FUNCTION,FUNCTIONI,GET$,GOSUB,GOTO,HEX$,IF,INC,INITARRAY,
INKEY$,INP,INPUT,INPUT$,INPUTHANDLE,INSERT$,INSTR,INT,INTEGER,
INV,IS,ISCONSOLE,KILL,KILLMESSAGE,LBOUND,LCASE$,LEFT$,LEN,
LFLUSH,LIB,LIBRARYINST,LOCATE,LOG,LONG,LOOP,LPRINT,LTRIM$,
MEMCMP,MESSAGEBOX,MESSAGEDLG,MID$,MKDIR,MOD,MOUSEX,MOUSEY,
NEXT,NOT,OFF,ON,OR,OUT,OUTPUTHANDLE,PARAMSTR$,PARAMSTRCOUNT,
PARAMVAL,PARAMVALCOUNT,PCOPY,PEEK,PLAYWAV,POKE,POS,POSTMESSAGE,
PRINT,PROPERTY,QUICKSORT,RANDOMIZE,REDIM,RENAME,REPLACE$,
REPLACESUBSTR$,RESOURCE,RESOURCECOUNT,RESTORE,RESULT,RETURN,
REVERSE$,RGB,RIGHT$,RINSTR,RMDIR,RND,ROUND,RTRIM$,RUN,
SCREEN,SELECT,SENDER,SENDMESSAGE,SETCONSOLETITLE,SGN,SHELL,
SHL,SHORT,SHOWMESSAGE,SHR,SIN,SINGLE,SIZEOF,SLEEP,SOUND,
SPACE$,SQR,STACK,STATIC,STEP,STR$,STRF$,STRING,STRING$,
SUB,SUBI,SWAP,TALLY,TAN,THEN,TIME$,TIMER,TO,TYPE,UBOUND,
UCASE$,UNLOADLIBRARY,UNTIL,VAL,VARIANT,VARPTR,VARPTR$,VARTYPE,
WEND,WHILE,WITH,WORD,XOR
#@nonl
#@-node:ekr.20090529103821.7780:Startup
#@-node:ekr.20090529103821.7779:@test colorizer rapidq
#@+node:ekr.20090529103821.7781:@test colorizer Rebol
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7782:Startup
@language rebol

; a comment
about abs absolute add alert alias all alter and and~ any append arccosine arcsine arctangent array ask at  
back bind boot-prefs break browse build-port build-tag  
call caret-to-offset catch center-face change change-dir charset checksum choose clean-path clear clear-fields close comment complement compose compress confirm continue-post context copy cosine create-request crypt cvs-date cvs-version  
debase decode-cgi decode-url decompress deflag-face dehex delete demo desktop detab dh-compute-key dh-generate-key dh-make-key difference dirize disarm dispatch divide do do-boot do-events do-face do-face-alt does dsa-generate-key dsa-make-key dsa-make-signature dsa-verify-signature  
echo editor either else emailer enbase entab exclude exit exp extract 
fifth find find-key-face find-window flag-face first flash focus for forall foreach forever form forskip fourth free func function  
get get-modes get-net-info get-style  
halt has head help hide hide-popup  
if import-email in inform input insert insert-event-func intersect 
join 
last launch launch-thru layout license list-dir load load-image load-prefs load-thru log-10 log-2 log-e loop lowercase  
make make-dir make-face max maximum maximum-of min minimum minimum-of mold multiply  
negate net-error next not now  
offset-to-caret open open-events or or~ 
parse parse-email-addrs parse-header parse-header-date parse-xml path-thru pick poke power prin print probe protect protect-system  
q query quit  
random read read-io read-net read-thru reboot recycle reduce reform rejoin remainder remold remove remove-event-func rename repeat repend replace request request-color request-date request-download request-file request-list request-pass request-text resend return reverse rsa-encrypt rsa-generate-key rsa-make-key 
save save-prefs save-user scroll-para second secure select send send-and-check set set-modes set-font set-net set-para set-style set-user set-user-name show show-popup sine size-text skip sort source split-path square-root stylize subtract switch  
tail tangent textinfo third throw throw-on-error to to-binary to-bitset to-block to-char to-date to-decimal to-email to-event to-file to-get-word to-hash to-hex to-idate to-image to-integer to-issue to-list to-lit-path to-lit-word to-local-file to-logic to-money to-none to-pair to-paren to-path to-rebol-file to-refinement to-set-path to-set-word to-string to-tag to-time to-tuple to-url to-word trace trim try  
unfocus union unique uninstall unprotect unset until unview update upgrade uppercase usage use  
vbug view view-install view-prefs  
wait what what-dir while write write-io  
xor xor~  
action! any-block! any-function! any-string! any-type! any-word!  
binary! bitset! block!  
char!  
datatype! date! decimal! 
email! error! event!  
file! function!  
get-word!  
hash!  
image! integer! issue!  
library! list! lit-path! lit-word! logic!  
money!  
native! none! number!  
object! op!  
pair! paren! path! port!  
refinement! routine!  
series! set-path! set-word! string! struct! symbol!  
tag! time! tuple!  
unset! url!  
word!  
any-block? any-function? any-string? any-type? any-word?  
binary? bitset? block?  
char? connected? crypt-strength? 
datatype? date? decimal? dir?  
email? empty? equal? error? even? event? exists? exists-key?
file? flag-face? found? function?  
get-word? greater-or-equal? greater?  
hash? head?  
image? in-window? index? info? input? inside? integer? issue?  
length? lesser-or-equal? lesser? library? link-app? link? list? lit-path? lit-word? logic?  
modified? money?  
native? negative? none? not-equal? number?  
object? odd? offset? op? outside?  
pair? paren? path? port? positive?  
refinement? routine?  
same? screen-offset? script? series? set-path? set-word? size? span? strict-equal? strict-not-equal? string? struct?  
tag? tail? time? tuple? type?  
unset? url?  
value? view? 
within? word?  
zero?
#@nonl
#@-node:ekr.20090529103821.7782:Startup
#@-node:ekr.20090529103821.7781:@test colorizer Rebol
#@+node:ekr.20090529103821.7783:@test colorizer rest
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7784:Startup
@language rest

@ @rst-options
code_mode=False
generate_rst=True
http_server_support = False
show_organizer_nodes=True
show_headlines=True
show_leo_directives=True
stylesheet_path=..\doc
write_intermediate_file = False
verbose=True
@c

. Links used in this document...

.. _`Pmw`:                  http://pmw.sourceforge.net/
.. _run:                    `Running Leo`_

.. WARNING: image targets may not have upper case letters!

.. |back| image:: arrow_lt.gif
    :target: FAQ.html

.. |leo| image:: leo.gif
    :target: front.html

.. |next| image:: arrow_rt.gif
    :target: intro.html

|back| |leo| |next|

###########################
Chapter 1: Installing Leo
###########################

This chapter tells how to install and run Leo.

**Important**:

If you have *any* problems installing Leo,
please ask for help on Leo's help forum:

.. contents::

**Windows**
    If you have `associated .leo files with Leo`_ you may run Leo by double-clicking any .leo file.
    You can also use a batch file.
    Put the following .bat file in c:\\Windows::

        cd c:\prog\LeoCVS\leo
        c:\python22\python c:\prog\LeoCVS\leo\leo.py %1

-   Download the latest version of Leo from `Leo's download page`_.

-   In Windows 2K or XP, go to ``Start->Settings->Control panel``, open the ``Folder Options`` tab.

    **Warning**: When building Tcl on Linux, do **not** specify
    "--enable-threads".
    Only use Tcl with the default "threads not enabled" case.

-------------

|back| |leo| |next|
#@nonl
#@-node:ekr.20090529103821.7784:Startup
#@-node:ekr.20090529103821.7783:@test colorizer rest
#@+node:ekr.20090529103821.7785:@test colorizer shell
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7786:Startup
# New in 4.2.

@language shell

# comment
$# not a comment
break
case,continue,
do,done
elif,else,esac
fi,for
if,in
return,
then
until
while,

cd,chdir,eval,exec,
exit,kill,newgrp,pwd,read,readonly,
shift,test,trap,ulimit,
umask,wait
#@nonl
#@-node:ekr.20090529103821.7786:Startup
#@-node:ekr.20090529103821.7785:@test colorizer shell
#@+node:ekr.20090529103821.7787:@test colorizer shellscript
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7788:Startup
@language shellscript

# comment
$# not a comment
break
case,continue,
do,done
elif,else,esac
fi,for
if,in
return,
then
until
while,

cd,chdir,eval,exec,
exit,kill,newgrp,pwd,read,readonly,
shift,test,trap,ulimit,
umask,wait
#@nonl
#@-node:ekr.20090529103821.7788:Startup
#@-node:ekr.20090529103821.7787:@test colorizer shellscript
#@+node:ekr.20090529103821.7789:@test colorizer tex.xml (jEdit)
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7790:Startup
@language html

<!-- ekr uses the MARK_FOLLOWING to mark _anything_ after \ -->

<?xml version="1.0"?>

<!DOCTYPE MODE SYSTEM "xmode.dtd">

<MODE>
    <PROPS>
        <PROPERTY NAME="lineComment" VALUE="%" />
    </PROPS>

    <RULES>
        << general rules >>
    </RULES>

    <RULES SET="MATH" DEFAULT="MARKUP">
        << math rules >>
    </RULES>
</MODE>
#@nonl
#@+node:ekr.20090529103821.7791:<< general rules >>
<!-- $$...$$ -->
<SPAN TYPE="MARKUP" DELEGATE="MATH">
    <BEGIN>$$</BEGIN>
    <END>$$</END>
</SPAN>

<!-- $...$ -->
<SPAN TYPE="MARKUP" DELEGATE="MATH">
    <BEGIN>$</BEGIN>
    <END>$</END>
</SPAN>

<!-- \[...\] (LaTeX math mode) -->
<SPAN TYPE="MARKUP" DELEGATE="MATH">
    <BEGIN>\[</BEGIN>
    <END>\]</END>
</SPAN>

<!-- some commands must be handled specially -->
<SEQ TYPE="KEYWORD1">\$</SEQ>
<SEQ TYPE="KEYWORD1">\\</SEQ>
<SEQ TYPE="KEYWORD1">\%</SEQ>

<!-- \... commands -->
<MARK_FOLLOWING TYPE="KEYWORD1">\</MARK_FOLLOWING>

<!-- comments -->
<EOL_SPAN TYPE="COMMENT1">%</EOL_SPAN>

<!-- word separators -->
<SEQ TYPE="OPERATOR">{</SEQ>
<SEQ TYPE="OPERATOR">}</SEQ>
<SEQ TYPE="OPERATOR">[</SEQ>
<SEQ TYPE="OPERATOR">]</SEQ>
#@nonl
#@-node:ekr.20090529103821.7791:<< general rules >>
#@+node:ekr.20090529103821.7792:<< math rules >>
<!-- some commands must be handled specially -->
<SEQ TYPE="KEYWORD3">\$</SEQ>
<SEQ TYPE="KEYWORD3">\\</SEQ>
<SEQ TYPE="KEYWORD3">\%</SEQ>

<!-- \... commands -->
<MARK_FOLLOWING TYPE="KEYWORD3">\</MARK_FOLLOWING>

<!-- word separators -->
<SEQ TYPE="KEYWORD2">)</SEQ>
<SEQ TYPE="KEYWORD2">(</SEQ>
<SEQ TYPE="KEYWORD2">{</SEQ>
<SEQ TYPE="KEYWORD2">}</SEQ>
<SEQ TYPE="KEYWORD2">[</SEQ>
<SEQ TYPE="KEYWORD2">]</SEQ>
<SEQ TYPE="KEYWORD2">=</SEQ>
<SEQ TYPE="KEYWORD2">!</SEQ>
<SEQ TYPE="KEYWORD2">+</SEQ>
<SEQ TYPE="KEYWORD2">-</SEQ>
<SEQ TYPE="KEYWORD2">/</SEQ>
<SEQ TYPE="KEYWORD2">*</SEQ>
<SEQ TYPE="KEYWORD2">&gt;</SEQ>
<SEQ TYPE="KEYWORD2">&lt;</SEQ>
<SEQ TYPE="KEYWORD2">&amp;</SEQ>
<SEQ TYPE="KEYWORD2">|</SEQ>
<SEQ TYPE="KEYWORD2">^</SEQ>
<SEQ TYPE="KEYWORD2">~</SEQ>
<SEQ TYPE="KEYWORD2">.</SEQ>
<SEQ TYPE="KEYWORD2">,</SEQ>
<SEQ TYPE="KEYWORD2">;</SEQ>
<SEQ TYPE="KEYWORD2">?</SEQ>
<SEQ TYPE="KEYWORD2">:</SEQ>
<SEQ TYPE="KEYWORD2">'</SEQ>
<SEQ TYPE="KEYWORD2">"</SEQ>
<SEQ TYPE="KEYWORD2">`</SEQ>

<!-- comments -->
<EOL_SPAN TYPE="COMMENT1">%</EOL_SPAN>
#@nonl
#@-node:ekr.20090529103821.7792:<< math rules >>
#@-node:ekr.20090529103821.7790:Startup
#@-node:ekr.20090529103821.7789:@test colorizer tex.xml (jEdit)
#@+node:ekr.20090529103821.7793:@test colorizer wikiTest1
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7794:Startup
# both color_markup & add_directives plugins must be enabled.

@markup wiki
@language python

""" {picture file=../Icons/Leoapp.GIF}this """ # Problems with correct indexing following a graphic.

""" {picture file=../Icons/Leoapp.GIF}this """ # two copies work.

abc

""" {picture file=../Icons/Leodoc.GIF} """ # xyz

""" continued
string"""

@ ''ab'' __xxx__ ''wx'' __xyz__
@c

# /* ''ab'' __xxx__ ''wx'' __xyz__ */

# Test

""" ''' """ ''' """'''  # Leo handles the common cases correctly.

''' ''ab'' __xxx__ ''wx'' __xyz__ ''' # No wiki markup in ''' strings.

""" ''ab'' __xxx__ ''wx'' __xyz__ """

# ''ab'' __xxx__ ''wx'' __xyz__

""" ''y'' """

""" text~~#ff00ff:some text~~more text"""

if 1 and 2:
    pass

print g.app().loadDir
#@nonl
#@-node:ekr.20090529103821.7794:Startup
#@-node:ekr.20090529103821.7793:@test colorizer wikiTest1
#@+node:ekr.20090529103821.7795:@test colorizer wikiTest2
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7796:Startup
# both color_markup & add_directives plugins must be enabled.
@markup wiki

""" continued
string"""

@ ''ab'' __xxx__ ''wx'' __xyz__  __''bolditalic''__ and ''__italicbold__''
@c

# /* ''ab'' __xxx__ ''wx'' __xyz__ */

__abc__ 

# Test

""" ''' """ ''' """'''  # Leo handles the __b__ common cases correctly.

''' ''ab'' __xxx__ ''wx'' __xyz__ ''' # No wiki markup in ''' strings.

""" ''ab'' __xxx__ ''wx'' __xyz__ """

# ''ab'' __xxx__ ''wx'' __xyz__

""" ''y'' """

""" text~~#ee00ff:some text~~more text"""


if 1 and 2:
    pass

print g.app().loadDir
#@-node:ekr.20090529103821.7796:Startup
#@-node:ekr.20090529103821.7795:@test colorizer wikiTest2
#@+node:ekr.20090529103821.7797:@test colorizer wikiTest3
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7798:Startup
# both color_markup & add_directives plugins must be enabled.

@markup wiki

""" text~~red:some text~~more text"""

""" text~~#ee0ff:some text~~more text"""

if 1 and 2:
    pass
#@nonl
#@-node:ekr.20090529103821.7798:Startup
#@-node:ekr.20090529103821.7797:@test colorizer wikiTest3
#@+node:ekr.20090529103821.7799:@test leoColor.doNowebSecRef
<< test defined >>
#@nonl
#@+node:ekr.20090529103821.7800:<< test defined >>
pass
#@nonl
#@-node:ekr.20090529103821.7800:<< test defined >>
#@-node:ekr.20090529103821.7799:@test leoColor.doNowebSecRef
#@+node:ekr.20090529103821.7801:@test python keywords (new colorizer)
try:
    mode = c.frame.body.colorizer.modes.get('python')
    mode.keywords['as'] = 1 # append the keyword, colorize with 'keyword1' tag.
except AttributeError:
    pass # modes only exists for new colorizer.
#@nonl
#@-node:ekr.20090529103821.7801:@test python keywords (new colorizer)
#@+node:ekr.20090529103821.7802:@test scanColorDirectives
# This will work regardless of where this method is.
@language python

language = g.findLanguageDirectives(c,p)
assert language == 'python','got:%s' % language
#@-node:ekr.20090529103821.7802:@test scanColorDirectives
#@+node:ekr.20090529103821.7803:@test vbscript
p = c.p.firstChild()

c.selectPosition(p) # Sets body text.
val = c.frame.body.colorizer.colorize(p,incremental=False)
assert val=="ok", "colorizer test failed: %s" % p.h
#@+node:ekr.20090529103821.7804:Startup
@language vbscript

if
IF
#@-node:ekr.20090529103821.7804:Startup
#@-node:ekr.20090529103821.7803:@test vbscript
#@+node:ekr.20090529103821.7805:@test zz restore the screen
# This is **not** a real unit test.
# It simply restores the screen to a more convenient state.

c.contractParent()
g.app.unitTestDict['restoreSelectedNode']=False

print('\nEnd of leoColor tests')
#@nonl
#@-node:ekr.20090529103821.7805:@test zz restore the screen
#@-node:ekr.20090529103821.7724:leoColor
#@+node:ekr.20090529103821.7808:leoDialogs
#@+node:ekr.20090529103821.7809:@test ctors for all dialogs
# For some reason these don't select the dialog properly when run as a script.
# However, the main reason for the tests is to make sure the ctors don't crash.
# Also, for unit testing the value of c doesn't matter.

oldGui = g.app.gui ; guis = [g.app.gui]

import leo.core.leoGui as leoGui
guis.append(leoGui.unitTestGui())

for gui in guis:
    gui.runAboutLeoDialog(c,'version','copyright','url','email')
    gui.runAskLeoIDDialog()
    gui.runAskOkDialog(c,'title','message')
    gui.runAskOkCancelNumberDialog(c,'title','message')
    gui.runAskOkCancelStringDialog(c,'title','message')
    gui.runAskYesNoDialog(c,'title','message')
    gui.runAskYesNoCancelDialog(c,'title','message')
    # gui.runCompareDialog(c) # Removed.

g.app.gui = oldGui
#@nonl
#@-node:ekr.20090529103821.7809:@test ctors for all dialogs
#@-node:ekr.20090529103821.7808:leoDialogs
#@+node:ekr.20090517020744.5918:leoGlobals
#@+node:ekr.20090517020744.5905:@@test g.scanAtPathDirectives
if g.unitTesting:

    if 0:
        print 'c',c
        for z in c.all_positions(): print '.'*z.level(),z.h

    table = (
        # at-path-test1.py does not use an @path directive.
        '@thin at-path-test2.py',
        '@thin at-path-test3.py',
    )

    for h in table:
        p2 = g.findNodeAnywhere(c,h)
        # Kludge.  Because of the @thin bug, @thin has a child called @thin.
        p2 = p2.firstChild()
        assert p2,h
        aList = g.get_directives_dict_list(p2)
        s = c.scanAtPathDirectives(aList,force=True)
        end = g.os_path_normpath(r'leo/test/unittest')

        assert s.endswith(end),'for %s\nexpected to end with %s\ngot %s' % (
            h,repr(end),repr(s))
#@nonl
#@-node:ekr.20090517020744.5905:@@test g.scanAtPathDirectives
#@+node:ekr.20090517020744.5908:@@test g.scanAtPathDirectives @path ../test @path unittest @file at-path-test3.py
greatGrandChild = p.firstChild().firstChild().firstChild()
aList = g.get_directives_dict_list(greatGrandChild)
s = c.scanAtPathDirectives(aList,force=True)
end = g.os_path_normpath(r'leo/test/unittest')

assert s.endswith(end),repr(s)
#@nonl
#@-node:ekr.20090517020744.5908:@@test g.scanAtPathDirectives @path ../test @path unittest @file at-path-test3.py
#@+node:ekr.20090517020744.5903:@@test g.scanAtPathDirectives ../test/unittest/at-path-test1.py
aList = g.get_directives_dict_list(p.firstChild())
s = c.scanAtPathDirectives(aList,force=True)
end = g.os_path_normpath(r'leo/test')

assert s.endswith(end),repr(s)
#@nonl
#@-node:ekr.20090517020744.5903:@@test g.scanAtPathDirectives ../test/unittest/at-path-test1.py
#@+node:ekr.20090517020744.5876:@@test g.get_directives_dict
# This will work regardless of where this method is.
@language python
@tabwidth -4
# @path xyzzy # Creates folder called xyzzy: interferes with other unit tests.
@pagewidth 120

d = c.atFileCommands.scanAllDirectives(p)
# print d
assert d.get('language') == 'python'
assert d.get('tabwidth') == -4
# assert d.get('path').endswith('xyzzy')
assert d.get('pagewidth') == 120
#@-node:ekr.20090517020744.5876:@@test g.get_directives_dict
#@-node:ekr.20090517020744.5918:leoGlobals
#@+node:ekr.20090529103821.7815:leoGui
#@+node:ekr.20090529103821.7816:@test w.toGui/PythonIndex
w = c.frame.body.bodyCtrl
s = w.getAllText()

for i in range(len(s)):
    i2 = w.toGuiIndex(i)
    i3 = w.toPythonIndex(i2)
    assert(i3==i)
#@-node:ekr.20090529103821.7816:@test w.toGui/PythonIndex
#@+node:ekr.20090529103821.7817:@test w.toGuiIndex (test2)
#ab
#

w = c.frame.body.bodyCtrl

# This test applies only to tkinter indices.
if g.app.gui.guiName() == 'tkinter':

    table = (
        (-1,'1.0'), # One too small.
        (0,'1.0'),
        (1,'1.1'),
        (2,'1.2'),
        (3,'1.3'), # The newline ends a row.
        (4,'2.0'),
        (5,'2.1'),
    )

    for i,expected in table:
        result = w.toGuiIndex(i)
        assert result == expected,'toGuiIndex(i): %s, expected: %s, got: %s' % (i,expected,result)
#@nonl
#@-node:ekr.20090529103821.7817:@test w.toGuiIndex (test2)
#@+node:ekr.20090529103821.7818:@test leoTextWidget
if g.app.gui.guiName() == 'tkinter':

    import leo.core.leoPlugins as leoPlugins
    tkGui = leoPlugins.loadOnePlugin ('tkGui',verbose=False)
    import Tkinter as Tk
    w = tkGui.leoTkTextWidget()
    w.setAllText('abcdef\n')
    s = w.getAllText()
    assert s == 'abcdef\n'
    s1 = w.get(0,len(s))
    assert s1 == 'abcdef\n'
    w.delete(0,len(s))
    assert len(w.getAllText()) == 0
    w.setAllText('')
    w.insert(0,'abcdef\n')
    s = w.getAllText()
    assert s == 'abcdef\n','got: %s' % repr(s)
    w.setInsertPoint(2)
    i = w.getInsertPoint()
    assert i == 2
    w.setSelectionRange(2,4)
    assert w.hasSelection()
    i,j = w.getSelectionRange()
    assert i==2 and j==4
    s3 = w.getSelectedText()
    assert s3 == 'cd'
    w.deleteTextSelection()
    s4 = w.getAllText()
    assert s4 == 'abef\n'
    w.selectAllText()
    i,j = w.getSelectionRange()
    assert i==0 and j==5,'getSelectionRange failed: i=%d,j=%d' % (i,j)
    w.replace(0,3,'wxyz')
    s5 = w.getAllText()
    assert s5 == 'wxyzf\n','getAllText failed'
    w.flashCharacter(3)
    i = w.xyToGuiIndex(0,0)
    assert i == '1.0','wxToGuiIndex failed'
    i = w.xyToPythonIndex(0,0)
    assert i == 0
    w.mark_set('insert','1.3'),'xyToPythonIndex failed'
    i = w.getInsertPoint()
    assert i == 3
    w.tag_add('test',4,6)
    aTuple = w.tag_ranges('test')
    assert aTuple == (4,6),'tag_add failed: %s' % aTuple
#@-node:ekr.20090529103821.7818:@test leoTextWidget
#@+node:ekr.20090529103821.7819:@test zz restore the screen
# This is **not** a real unit test.
# It simply restores the screen to a more convenient state.

c.contractParent()
g.app.unitTestDict['restoreSelectedNode']=False

# print('\nEnd of leoGui tests.')
#@nonl
#@-node:ekr.20090529103821.7819:@test zz restore the screen
#@-node:ekr.20090529103821.7815:leoGui
#@+node:ekr.20090529103821.9303:leoKeys
#@+node:ekr.20090529103821.9304:@test isPlainKey
import string

k = c.k

for ch in (string.printable):
    if ch == '\n': continue # A special case.
    assert k.isPlainKey(ch), 'wrong: not plain: %s' % (ch)

special = (
    'Return', # A special case.
    'Begin','Break','Caps_Lock','Clear','Down','End','Escape',
    'F1','F2','F3','F4','F5','F6','F7','F8','F9','F10','F11','F12',
    'KP_Add', 'KP_Decimal', 'KP_Divide', 'KP_Enter', 'KP_Equal',
    'KP_Multiply, KP_Separator,KP_Space, KP_Subtract, KP_Tab',
    'KP_F1','KP_F2','KP_F3','KP_F4',
    'KP_0','KP_1','KP_2','KP_3','KP_4','KP_5','KP_6','KP_7','KP_8','KP_9',
    'Home','Left','Linefeed','Next','Num_Lock',
    'PageDn','PageUp','Pause','Prior','Right','Up',
    'Sys_Req',
)

for ch in special:
    assert not k.isPlainKey(ch), 'wrong: is plain: %s' % (ch)
#@-node:ekr.20090529103821.9304:@test isPlainKey
#@+node:ekr.20090529103821.9305:@test k.autoCompleterClass.calltip
try:
    k = c.k ; ac = k.autoCompleter
    w = c.frame.body.bodyCtrl
    ac.widget = w
    s = w.getAllText()
    import string
    # Just test that this doesn't crash.
    for obj in (None,g,string,c,p):
        w.setInsertPoint('end')
        c.k.autoCompleter.calltip(obj=g)
finally:
    w.setAllText(s)
    p.setBodyString(s)
    c.recolor()

# end:
#@nonl
#@-node:ekr.20090529103821.9305:@test k.autoCompleterClass.calltip
#@+node:ekr.20090529103821.9306:@test k.registerCommand
import leo.core.leoTest as leoTest ; u = leoTest.testUtils(c)
k = c.k ; p = c.p ; w = c.edit_widget(p)
commandName = 'test-registerCommand'

def callback (event=None,c=c): # Must have an event param to pass later unit test.
    g.app.unitTestDict[commandName] = True

# Test 1
g.app.unitTestDict[commandName] = False
k.registerCommand(commandName,'Alt-Ctrl-Shift-z',callback,pane='all',verbose=True)
k.simulateCommand(commandName)
assert g.app.unitTestDict.get(commandName)

if 0: # Test 2
    g.app.unitTestDict[commandName] = False
    k.manufactureKeyPressForCommandName(w,commandName)
    assert g.app.unitTestDict.get(commandName)
#@nonl
#@-node:ekr.20090529103821.9306:@test k.registerCommand
#@+node:ekr.20090529103821.9307:@test strokeFromSetting
# print('settingsNameDict',c.k.settingsNameDict)

table = (
    ('a','a'),
    ('A','a'),
    ('Alt-a','Alt+a'),
    ('Alt-A','Alt+a'),
    ('Alt-Shift-a','Alt+A'),
    ('Alt-=','Alt+equal'),
    ('Alt-+','Alt+plus'),
    # We can no longer igtnore the shift.
    # ('Alt-Shift++','Alt+plus'), # Ignore the shift.
    ('Alt--','Alt+minus'),
    ('Shift-a','A'),
    ('Shift-A','A'),
    ('RtArrow','Right'),
    ('Shift-RtArrow','Shift+Right'),
    ('Ctrl-RtArrow','Ctrl+Right'),
    ('Control-Right','Ctrl+Right'),
    ('PageUp','Prior'), ('Prior','Prior'),('Shift-PageUp','Shift+Prior'),
    ('PageDn','Next'),('Next','Next'),('Shift-Next','Shift+Next'),
)
for setting, result in table:
    val = c.k.strokeFromSetting(setting)
    assert val==result,'Expected %s, Got %s' % (result,val)
#@nonl
#@-node:ekr.20090529103821.9307:@test strokeFromSetting
#@+node:ekr.20090529103821.9308:@test zz restore the screen
# This is **not** a real unit test.
# It simply restores the screen to a more convenient state.

c.contractParent()
g.app.unitTestDict['restoreSelectedNode']=False

# print('\nEnd of leoKeys tests.')
#@nonl
#@-node:ekr.20090529103821.9308:@test zz restore the screen
#@-node:ekr.20090529103821.9303:leoKeys
#@+node:ekr.20090529103821.9311:leoPlugins
#@+node:ekr.20090529103821.9312:@test getHandlersForTag
import leo.core.leoPlugins as leoPlugins

aList1 = leoPlugins.getHandlersForTag('select1')
aList2 = leoPlugins.getHandlersForOneTag('select1')

assert type(aList1) == type([])
assert type(aList2) == type([])
assert aList1 == aList2
#@-node:ekr.20090529103821.9312:@test getHandlersForTag
#@-node:ekr.20090529103821.9311:leoPlugins
#@+node:ekr.20090529103821.9315:leoTest
#@+node:ekr.20090529103821.9316:@test unit testing with embedded class
def sendEmail(self):
    pass # g.trace('self2',self)

class test:
    pass

X = test()
sendEmail(X)
#@-node:ekr.20090529103821.9316:@test unit testing with embedded class
#@-node:ekr.20090529103821.9315:leoTest
#@+node:ekr.20090529061522.6449:leoShadow
#@+node:ekr.20090529061522.6450:@suite run @shadow-test nodes in the @shadow-tests tree
import unittest

if 1:
    x = c.shadowController
else:
    import leo.core.leoShadow as leoShadow
    x = leoShadow.shadowController(c,trace=False,trace_writers=False)

suite = unittest.makeSuite(unittest.TestCase)
root = g.findNodeAnywhere(c,'@shadow-tests')
assert root, 'Node not found: @shadow-tests'

trace = False ; vrbose = False
for p in root.children_iter():
    h = p.h.strip()
    if h.startswith('@shadow-test-lax'):
        test = x.atShadowTestCase(c,p,x,lax=True)
    elif h.startswith('@shadow-test'):
        test = x.atShadowTestCase(c,p,x,lax=False)
    else:
        test = None
    if test:
        if trace and verbose: print(h)
        suite.addTest(test)
if suite:
    g.app.scriptDict['suite'] = suite
#@+node:ekr.20090529061522.6451:@shadow-tests
@

All the tags should be tested at least once (equal, replace, delete, insert).

The replace, delete, insert operations should happen at least once:
    1. At the beginning of a node.
    2. In the middle of a node.
    3. At the end of a node.

For the delete and replace operators we must also test the case that the
deletion or replacement spans more than one block.
#@+node:ekr.20090529061522.6452:passed
#@-node:ekr.20090529061522.6452:passed
#@+node:ekr.20090529061522.6453:@shadow-test change middle line
#@+node:ekr.20090529061522.6454:old
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6454:old
#@+node:ekr.20090529061522.6455:new
line 1
line 2 changed
line 3
#@nonl
#@-node:ekr.20090529061522.6455:new
#@-node:ekr.20090529061522.6453:@shadow-test change middle line
#@+node:ekr.20090529061522.6456:@shadow-test change first line
#@+node:ekr.20090529061522.6457:old
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6457:old
#@+node:ekr.20090529061522.6458:new
line 1 changed
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6458:new
#@-node:ekr.20090529061522.6456:@shadow-test change first line
#@+node:ekr.20090529061522.6459:@shadow-test change last line
#@+node:ekr.20090529061522.6460:old
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6460:old
#@+node:ekr.20090529061522.6461:new
line 1
line 2
line 3 changed
#@nonl
#@-node:ekr.20090529061522.6461:new
#@-node:ekr.20090529061522.6459:@shadow-test change last line
#@+node:ekr.20090529061522.6462:@shadow-test delete first line
#@+node:ekr.20090529061522.6463:old
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6463:old
#@+node:ekr.20090529061522.6464:new
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6464:new
#@-node:ekr.20090529061522.6462:@shadow-test delete first line
#@+node:ekr.20090529061522.6465:@shadow-test delete middle line
#@+node:ekr.20090529061522.6466:old
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6466:old
#@+node:ekr.20090529061522.6467:new
line 1
line 3
#@nonl
#@-node:ekr.20090529061522.6467:new
#@-node:ekr.20090529061522.6465:@shadow-test delete middle line
#@+node:ekr.20090529061522.6468:@shadow-test delete last line
#@+node:ekr.20090529061522.6469:old
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6469:old
#@+node:ekr.20090529061522.6470:new
line 1
line 2
#@nonl
#@-node:ekr.20090529061522.6470:new
#@-node:ekr.20090529061522.6468:@shadow-test delete last line
#@+node:ekr.20090529061522.6471:@shadow-test insert before first line
#@+node:ekr.20090529061522.6472:old
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6472:old
#@+node:ekr.20090529061522.6473:new
inserted line
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6473:new
#@-node:ekr.20090529061522.6471:@shadow-test insert before first line
#@+node:ekr.20090529061522.6474:@shadow-test insert after first line
#@+node:ekr.20090529061522.6475:old
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6475:old
#@+node:ekr.20090529061522.6476:new
line 1
inserted line
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6476:new
#@-node:ekr.20090529061522.6474:@shadow-test insert after first line
#@+node:ekr.20090529061522.6477:@shadow-test insert before last line
#@+node:ekr.20090529061522.6478:old
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6478:old
#@+node:ekr.20090529061522.6479:new
line 1
line 2
inserted line
line 3
#@nonl
#@-node:ekr.20090529061522.6479:new
#@-node:ekr.20090529061522.6477:@shadow-test insert before last line
#@+node:ekr.20090529061522.6480:@shadow-test insert after last line
#@+node:ekr.20090529061522.6481:old
line 1
line 2
line 3
#@nonl
#@-node:ekr.20090529061522.6481:old
#@+node:ekr.20090529061522.6482:new
line 1
line 2
line 3
inserted line
#@nonl
#@-node:ekr.20090529061522.6482:new
#@-node:ekr.20090529061522.6480:@shadow-test insert after last line
#@+node:ekr.20090529061522.6483:@shadow-test-lax insert between nodes: at end of prev node
#@+node:ekr.20090529061522.6484:old
@others
#@nonl
#@+node:ekr.20090529061522.6485:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6485:node 1
#@+node:ekr.20090529061522.6486:node 2
node 2 line 1
#@nonl
#@-node:ekr.20090529061522.6486:node 2
#@-node:ekr.20090529061522.6484:old
#@+node:ekr.20090529061522.6487:new
@others
#@nonl
#@+node:ekr.20090529061522.6488:node 1
node 1 line 1
inserted node at end of node 1
#@nonl
#@-node:ekr.20090529061522.6488:node 1
#@+node:ekr.20090529061522.6489:node 2
node 2 line 1
#@nonl
#@-node:ekr.20090529061522.6489:node 2
#@-node:ekr.20090529061522.6487:new
#@-node:ekr.20090529061522.6483:@shadow-test-lax insert between nodes: at end of prev node
#@+node:ekr.20090529061522.6490:@shadow-test insert between nodes: at start of next node
#@+node:ekr.20090529061522.6491:old
@others
#@nonl
#@+node:ekr.20090529061522.6492:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6492:node 1
#@+node:ekr.20090529061522.6493:node 2
node 2 line 1
#@nonl
#@-node:ekr.20090529061522.6493:node 2
#@-node:ekr.20090529061522.6491:old
#@+node:ekr.20090529061522.6494:new
@others
#@nonl
#@+node:ekr.20090529061522.6495:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6495:node 1
#@+node:ekr.20090529061522.6496:node 2
inserted node at start of node 2
node 2 line 1
#@nonl
#@-node:ekr.20090529061522.6496:node 2
#@-node:ekr.20090529061522.6494:new
#@-node:ekr.20090529061522.6490:@shadow-test insert between nodes: at start of next node
#@+node:ekr.20090529061522.6497:@shadow-test delete between nodes: at end of prev node
#@+node:ekr.20090529061522.6498:old
@others
#@nonl
#@+node:ekr.20090529061522.6499:node 1
node 1 line 1
node 1 line 2
#@nonl
#@-node:ekr.20090529061522.6499:node 1
#@+node:ekr.20090529061522.6500:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6500:node 2
#@-node:ekr.20090529061522.6498:old
#@+node:ekr.20090529061522.6501:new
@others
#@nonl
#@+node:ekr.20090529061522.6502:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6502:node 1
#@+node:ekr.20090529061522.6503:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6503:node 2
#@-node:ekr.20090529061522.6501:new
#@-node:ekr.20090529061522.6497:@shadow-test delete between nodes: at end of prev node
#@+node:ekr.20090529061522.6504:@shadow-test delete between nodes: at start of next node
#@+node:ekr.20090529061522.6505:old
@others
#@nonl
#@+node:ekr.20090529061522.6506:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6506:node 1
#@+node:ekr.20090529061522.6507:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6507:node 2
#@-node:ekr.20090529061522.6505:old
#@+node:ekr.20090529061522.6508:new
@others
#@nonl
#@+node:ekr.20090529061522.6509:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6509:node 1
#@+node:ekr.20090529061522.6510:node 2
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6510:node 2
#@-node:ekr.20090529061522.6508:new
#@-node:ekr.20090529061522.6504:@shadow-test delete between nodes: at start of next node
#@+node:ekr.20090529061522.6511:@shadow-test change end of prev node
#@+node:ekr.20090529061522.6512:old
@others
#@nonl
#@+node:ekr.20090529061522.6513:node 1
node 1 line 1
node 1 line 2
#@nonl
#@-node:ekr.20090529061522.6513:node 1
#@+node:ekr.20090529061522.6514:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6514:node 2
#@-node:ekr.20090529061522.6512:old
#@+node:ekr.20090529061522.6515:new
@others
#@nonl
#@+node:ekr.20090529061522.6516:node 1
node 1 line 1
node 1 line 1 changed
#@nonl
#@-node:ekr.20090529061522.6516:node 1
#@+node:ekr.20090529061522.6517:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6517:node 2
#@-node:ekr.20090529061522.6515:new
#@-node:ekr.20090529061522.6511:@shadow-test change end of prev node
#@+node:ekr.20090529061522.6518:@shadow-test change start of next node
#@+node:ekr.20090529061522.6519:old
@others
#@nonl
#@+node:ekr.20090529061522.6520:node 1
node 1 line 1
node 1 line 2
#@nonl
#@-node:ekr.20090529061522.6520:node 1
#@+node:ekr.20090529061522.6521:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6521:node 2
#@-node:ekr.20090529061522.6519:old
#@+node:ekr.20090529061522.6522:new
@others
#@nonl
#@+node:ekr.20090529061522.6523:node 1
node 1 line 1
node 1 line 2
#@nonl
#@-node:ekr.20090529061522.6523:node 1
#@+node:ekr.20090529061522.6524:node 2
node 2 line 1 changed
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6524:node 2
#@-node:ekr.20090529061522.6522:new
#@-node:ekr.20090529061522.6518:@shadow-test change start of next node
#@+node:ekr.20090529061522.6525:@shadow-test-lax multiple-line insert between nodes: at end of prev node
#@+node:ekr.20090529061522.6526:old
@others
#@nonl
#@+node:ekr.20090529061522.6527:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6527:node 1
#@+node:ekr.20090529061522.6528:node 2
node 2 line 1
#@nonl
#@-node:ekr.20090529061522.6528:node 2
#@-node:ekr.20090529061522.6526:old
#@+node:ekr.20090529061522.6529:new
@others
#@nonl
#@+node:ekr.20090529061522.6530:node 1
node 1 line 1
inserted node 1 at end of node 1
inserted node 2 at end of node 1
#@nonl
#@-node:ekr.20090529061522.6530:node 1
#@+node:ekr.20090529061522.6531:node 2
node 2 line 1
#@nonl
#@-node:ekr.20090529061522.6531:node 2
#@-node:ekr.20090529061522.6529:new
#@-node:ekr.20090529061522.6525:@shadow-test-lax multiple-line insert between nodes: at end of prev node
#@+node:ekr.20090529061522.6532:@shadow-test multiple-line insert between nodes: at start of next node
#@+node:ekr.20090529061522.6533:old
@others
#@nonl
#@+node:ekr.20090529061522.6534:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6534:node 1
#@+node:ekr.20090529061522.6535:node 2
node 2 line 1
#@nonl
#@-node:ekr.20090529061522.6535:node 2
#@-node:ekr.20090529061522.6533:old
#@+node:ekr.20090529061522.6536:new
@others
#@nonl
#@+node:ekr.20090529061522.6537:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6537:node 1
#@+node:ekr.20090529061522.6538:node 2
inserted node 1 at start of node 2
inserted node 2 at start of node 2
node 2 line 1
#@nonl
#@-node:ekr.20090529061522.6538:node 2
#@-node:ekr.20090529061522.6536:new
#@-node:ekr.20090529061522.6532:@shadow-test multiple-line insert between nodes: at start of next node
#@+node:ekr.20090529061522.6539:@shadow-test multiple-line change end of prev node
#@+node:ekr.20090529061522.6540:old
@others
#@nonl
#@+node:ekr.20090529061522.6541:node 1
node 1 line 1
node 1 line 2
node 1 line 3
#@nonl
#@-node:ekr.20090529061522.6541:node 1
#@+node:ekr.20090529061522.6542:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6542:node 2
#@-node:ekr.20090529061522.6540:old
#@+node:ekr.20090529061522.6543:new
@others
#@nonl
#@+node:ekr.20090529061522.6544:node 1
node 1 line 1
node 1 line 2 changed
node 1 line 3 changed
#@nonl
#@-node:ekr.20090529061522.6544:node 1
#@+node:ekr.20090529061522.6545:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6545:node 2
#@-node:ekr.20090529061522.6543:new
#@-node:ekr.20090529061522.6539:@shadow-test multiple-line change end of prev node
#@+node:ekr.20090529061522.6546:@shadow-test multiple-line change start of next node
#@+node:ekr.20090529061522.6547:old
@others
#@nonl
#@+node:ekr.20090529061522.6548:node 1
node 1 line 1
node 1 line 2
#@nonl
#@-node:ekr.20090529061522.6548:node 1
#@+node:ekr.20090529061522.6549:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6549:node 2
#@-node:ekr.20090529061522.6547:old
#@+node:ekr.20090529061522.6550:new
@others
#@nonl
#@+node:ekr.20090529061522.6551:node 1
node 1 line 1
node 1 line 2
#@nonl
#@-node:ekr.20090529061522.6551:node 1
#@+node:ekr.20090529061522.6552:node 2
node 2 line 1 changed
node 2 line 2 changed
#@nonl
#@-node:ekr.20090529061522.6552:node 2
#@-node:ekr.20090529061522.6550:new
#@-node:ekr.20090529061522.6546:@shadow-test multiple-line change start of next node
#@+node:ekr.20090529061522.6553:@shadow-test multiple-line delete between nodes: at end of prev node
#@+node:ekr.20090529061522.6554:old
@others
#@nonl
#@+node:ekr.20090529061522.6555:node 1
node 1 line 1
node 1 line 2
node 1 line 3
#@nonl
#@-node:ekr.20090529061522.6555:node 1
#@+node:ekr.20090529061522.6556:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6556:node 2
#@-node:ekr.20090529061522.6554:old
#@+node:ekr.20090529061522.6557:new
@others
#@nonl
#@+node:ekr.20090529061522.6558:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6558:node 1
#@+node:ekr.20090529061522.6559:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6559:node 2
#@-node:ekr.20090529061522.6557:new
#@-node:ekr.20090529061522.6553:@shadow-test multiple-line delete between nodes: at end of prev node
#@+node:ekr.20090529061522.6560:@shadow-test multiple-line delete between nodes: at start of next node
#@+node:ekr.20090529061522.6561:old
@others
#@nonl
#@+node:ekr.20090529061522.6562:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6562:node 1
#@+node:ekr.20090529061522.6563:node 2
node 2 line 1
node 2 line 2
node 2 line 3
#@nonl
#@-node:ekr.20090529061522.6563:node 2
#@-node:ekr.20090529061522.6561:old
#@+node:ekr.20090529061522.6564:new
@others
#@nonl
#@+node:ekr.20090529061522.6565:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6565:node 1
#@+node:ekr.20090529061522.6566:node 2
node 2 line 3
#@nonl
#@-node:ekr.20090529061522.6566:node 2
#@-node:ekr.20090529061522.6564:new
#@-node:ekr.20090529061522.6560:@shadow-test multiple-line delete between nodes: at start of next node
#@+node:ekr.20090529061522.6567:@shadow-test verbatim sentinels-delete verbatim line
#@+node:ekr.20090529061522.6568:old
@others
#@nonl
#@+node:ekr.20090529061522.6569:node 1
node 1 line 1
#@verbatim
#@ should be handled by verbatim
line 1 line 3
#@nonl
#@-node:ekr.20090529061522.6569:node 1
#@+node:ekr.20090529061522.6570:node 2
node 2 line 1
node 2 line 2
node 2 line 3
#@nonl
#@-node:ekr.20090529061522.6570:node 2
#@-node:ekr.20090529061522.6568:old
#@+node:ekr.20090529061522.6571:new
@others
#@nonl
#@+node:ekr.20090529061522.6572:node 1
node 1 line 1
line 1 line 3
#@nonl
#@-node:ekr.20090529061522.6572:node 1
#@+node:ekr.20090529061522.6573:node 2
node 2 line 1
node 2 line 2
node 2 line 3
#@nonl
#@-node:ekr.20090529061522.6573:node 2
#@-node:ekr.20090529061522.6571:new
#@-node:ekr.20090529061522.6567:@shadow-test verbatim sentinels-delete verbatim line
#@+node:ekr.20090529061522.6574:@shadow-test verbatim sentinels-delete verbatim line: at start of node
#@+node:ekr.20090529061522.6575:old
@others
#@nonl
#@+node:ekr.20090529061522.6576:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6576:node 1
#@+node:ekr.20090529061522.6577:node 2
#@verbatim
#@ should be handled by verbatim
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6577:node 2
#@-node:ekr.20090529061522.6575:old
#@+node:ekr.20090529061522.6578:new
@others
#@nonl
#@+node:ekr.20090529061522.6579:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6579:node 1
#@+node:ekr.20090529061522.6580:node 2
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6580:node 2
#@-node:ekr.20090529061522.6578:new
#@-node:ekr.20090529061522.6574:@shadow-test verbatim sentinels-delete verbatim line: at start of node
#@+node:ekr.20090529061522.6581:@shadow-test verbatim sentinels-no change
#@+node:ekr.20090529061522.6582:old
@others
#@nonl
#@+node:ekr.20090529061522.6583:node 1
node 1 line 1
#@verbatim
#@ should be handled by verbatim
line 1 line 3
#@nonl
#@-node:ekr.20090529061522.6583:node 1
#@+node:ekr.20090529061522.6584:node 2
node 2 line 1
node 2 line 2
node 2 line 3
#@nonl
#@-node:ekr.20090529061522.6584:node 2
#@-node:ekr.20090529061522.6582:old
#@+node:ekr.20090529061522.6585:new
@others
#@nonl
#@+node:ekr.20090529061522.6586:node 1
node 1 line 1
#@verbatim
#@ should be handled by verbatim
line 1 line 3
#@nonl
#@-node:ekr.20090529061522.6586:node 1
#@+node:ekr.20090529061522.6587:node 2
node 2 line 1
node 2 line 2
node 2 line 3
#@nonl
#@-node:ekr.20090529061522.6587:node 2
#@-node:ekr.20090529061522.6585:new
#@-node:ekr.20090529061522.6581:@shadow-test verbatim sentinels-no change
#@+node:ekr.20090529061522.6588:@shadow-test verbatim sentinels-delete verbatim line: at end of node
#@+node:ekr.20090529061522.6589:old
@others
#@nonl
#@+node:ekr.20090529061522.6590:node 1
node 1 line 1
#@verbatim
#@ should be handled by verbatim
#@nonl
#@-node:ekr.20090529061522.6590:node 1
#@+node:ekr.20090529061522.6591:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6591:node 2
#@-node:ekr.20090529061522.6589:old
#@+node:ekr.20090529061522.6592:new
@others
#@nonl
#@+node:ekr.20090529061522.6593:node 1
node 1 line 1
#@nonl
#@-node:ekr.20090529061522.6593:node 1
#@+node:ekr.20090529061522.6594:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6594:node 2
#@-node:ekr.20090529061522.6592:new
#@-node:ekr.20090529061522.6588:@shadow-test verbatim sentinels-delete verbatim line: at end of node
#@+node:ekr.20090529061522.6595:@@shadow-test verbatim sentinels-add verbatim line
# This fails because the @all read logic inserts a second verbatim, I think.
#@nonl
#@+node:ekr.20090529061522.6596:old
@others
#@nonl
#@+node:ekr.20090529061522.6597:node 1
node 1 line 1
node 1 line 2
#@nonl
#@-node:ekr.20090529061522.6597:node 1
#@+node:ekr.20090529061522.6598:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6598:node 2
#@-node:ekr.20090529061522.6596:old
#@+node:ekr.20090529061522.6599:new
@others
#@nonl
#@+node:ekr.20090529061522.6600:node 1
node 1 line 1
#@verbatim
#@ should be handled by verbatim
node 1 line 2
#@nonl
#@-node:ekr.20090529061522.6600:node 1
#@+node:ekr.20090529061522.6601:node 2
node 2 line 1
node 2 line 2
#@nonl
#@-node:ekr.20090529061522.6601:node 2
#@-node:ekr.20090529061522.6599:new
#@-node:ekr.20090529061522.6595:@@shadow-test verbatim sentinels-add verbatim line
#@-node:ekr.20090529061522.6451:@shadow-tests
#@-node:ekr.20090529061522.6450:@suite run @shadow-test nodes in the @shadow-tests tree
#@+node:ekr.20090529061522.6602:Other unit tests of shadowController
#@+node:ekr.20090529061522.6603:@test x.baseDirName
x = c.shadowController

path = x.baseDirName()
expected = g.os_path_dirname(g.os_path_abspath(g.os_path_join(c.fileName())))

# print(path)
# print(expected)

assert path == expected,'\nexpected: %s\ngot     : %s' % (expected,path)
#@nonl
#@-node:ekr.20090529061522.6603:@test x.baseDirName
#@+node:ekr.20090529061522.6604:@test x.pathName
x = c.shadowController

filename = 'xyzzy'

path = x.pathName(filename)
expected = g.os_path_abspath(g.os_path_join(x.baseDirName(),filename))

# print(path)
# print(expected)

assert path == expected,'\nexpected: %s\ngot     : %s' % (expected,path)
#@nonl
#@-node:ekr.20090529061522.6604:@test x.pathName
#@+node:ekr.20090529061522.6605:@test x.dirName
x = c.shadowController

filename = 'xyzzy'
path = x.dirName(filename)
expected = g.os_path_dirname(g.os_path_abspath(
    g.os_path_join(g.os_path_dirname(c.fileName()),filename)))

# print(path)
# print(expected)

assert path == expected,'\nexpected: %s\ngot     : %s' % (expected,path)
#@nonl
#@-node:ekr.20090529061522.6605:@test x.dirName
#@+node:ekr.20090529061522.6606:@test x.shadowPathName
x = c.shadowController

# print c.config.getString('shadow_subdir')

subdir = c.config.getString('shadow_subdir') or '.leo_shadow'
prefix = c.config.getString('shadow_prefix') or ''

# print('c.fileName',c.fileName())
# print('c.relativeFileName',c.relativeFileName())

filename = 'xyzzy'
path = x.shadowPathName(filename)
expected = g.os_path_abspath(g.os_path_join(
    g.os_path_dirname(c.fileName()),subdir,prefix+filename))

if 0:
    print('prefix',prefix)
    print(path)
    print(expected)

assert path == expected,'\nexpected: %s\ngot     : %s' % (expected,path)
#@nonl
#@-node:ekr.20090529061522.6606:@test x.shadowPathName
#@+node:ekr.20090529061522.6607:@test x.shadowDirName
x = c.shadowController

subdir = c.config.getString('shadow_subdir') or '.leo_shadow'
prefix = c.config.getString('shadow_prefix') or ''

# print('c.fileName',c.fileName())
# print('c.relativeFileName',c.relativeFileName())

filename = 'xyzzy'
path = x.shadowDirName(filename)
expected = g.os_path_abspath(
    g.os_path_join(g.os_path_dirname(c.fileName()),subdir))

# print(path)
# print(expected)

assert path == expected,'\nexpected: %s\ngot     : %s' % (expected,path)
#@nonl
#@-node:ekr.20090529061522.6607:@test x.shadowDirName
#@+node:ekr.20090529061522.6608:@test x.rename
x = c.shadowController

filename = x.pathName('xyzzy')
assert not g.os_path_exists(filename)
n = x.errors
x.rename('xyzzy','xyzzy2',silent=True)
assert x.errors == n+1
assert x.last_error.startswith('can not rename')
# print(x.last_error)
#@nonl
#@-node:ekr.20090529061522.6608:@test x.rename
#@+node:ekr.20090529061522.6609:@test x.unlink
x = c.shadowController

filename = x.pathName('xyzzy')
# print(filename)
assert not g.os_path_exists(filename)
n = x.errors
x.unlink('xyzzy',silent=True)
assert x.errors == n+1
assert x.last_error.startswith('can not delete xyzzy')
# print(x.last_error)
#@nonl
#@-node:ekr.20090529061522.6609:@test x.unlink
#@+node:ekr.20090529061522.6610:@test x.makeShadowDirectory
import glob
import os

x = c.shadowController

@others

shadow_fn  = x.shadowPathName('unittest/xyzzy')
shadow_dir = x.shadowDirName('unittest/xyzzy')

if g.os_path_exists(shadow_fn):
    g.utils_remove(shadow_fn,verbose=True)
    assert not os.path.exists(shadow_fn),'still exists: %s' % shadow_fn

deleteShadowDir(shadow_dir)

x.makeShadowDirectory(shadow_dir)
assert os.path.exists(shadow_dir)

deleteShadowDir(shadow_dir)
#@+node:ekr.20090529061522.6611:deleteShadowDir
def deleteShadowDir(shadowDir):

    if g.os_path_exists(shadow_dir):
        files = g.os_path_abspath(g.os_path_join(shadow_dir,"*.*"))
        files = glob.glob(files)
        for z in files:
            if z != shadow_dir:
                os.unlink(z)
        os.rmdir(shadow_dir)
        assert not os.path.exists(shadow_dir),'still exists: %s' % shadow_dir
#@nonl
#@-node:ekr.20090529061522.6611:deleteShadowDir
#@-node:ekr.20090529061522.6610:@test x.makeShadowDirectory
#@+node:ekr.20090529061522.6612:@test x.replaceFileWithString
x = c.shadowController
s = 'abc'

fn = '../test/unittest/replaceFileWithStringTestFile.py'
path = g.os_path_abspath(g.os_path_join(g.app.loadDir,fn))

x.replaceFileWithString(path,s)
f = open(path)
s2 = f.read()
f.close()
assert s == s2
#@nonl
#@-node:ekr.20090529061522.6612:@test x.replaceFileWithString
#@+node:ekr.20090529061522.6614:@@test (minitest) x.show_error
x = c.shadowController

lines1 = ('a','b','c')
lines2 = ('a','x','c')

x.show_error(
    lines1,lines2,
    message = "Test of x.show_error",
    lines1_message = "lines1",
    lines2_message = "lines2")
#@-node:ekr.20090529061522.6614:@@test (minitest) x.show_error
#@-node:ekr.20090529061522.6602:Other unit tests of shadowController
#@+node:ekr.20090529061522.6615:Unit tests for atFileCommands
#@+node:ekr.20090529061522.6616:@test at.open/closeStringFile
at = c.atFileCommands

# at.toString is set by the execute-script command.

f = at.openStringFile('abc')

assert f.__class__.__name__ == 'fileLikeObject'

s = 'abc'
f.write(s)
s2 = at.closeStringFile(f)

assert s == s2

# assert at.toString

#@-node:ekr.20090529061522.6616:@test at.open/closeStringFile
#@+node:ekr.20090529061522.6617:@test at.openForWrite: not a shadow file
at = c.atFileCommands
x = c.shadowController

filename = x.pathName('xyzzy')
assert not g.os_path_exists(filename)

try:
    kind,theFile = at.openForWrite(filename)
    assert kind == 'check'
    # print(repr(theFile))
    if theFile: theFile.close()

finally:
    if g.os_path_exists(filename):
        x.unlink(filename)
        assert not g.os_path_exists(filename)
#@nonl
#@-node:ekr.20090529061522.6617:@test at.openForWrite: not a shadow file
#@+node:ekr.20090529061522.6618:@test at.readOneAtShadowNode
at = c.atFileCommands
x = c.shadowController

changed = c.changed
child = p.firstChild()
s = child.b

try:
    fn = 'unittest/read_test.py'
    child.setHeadString('@shadow %s' % fn)
    # shadow_fn = x.shadowPathName(fn)
    at.writeOneAtShadowNode(child,toString=False,force=True)
    at.readOneAtShadowNode(fn,child)
finally:
    child.setHeadString('@@shadow %s' % fn)
    c.setChanged(changed)
    # c.redraw_now()
#@nonl
#@+node:ekr.20090529061522.6619:@@shadow unittest/read_test.py
@language python
@tabwidth -4
@others
# body of @shadow test node
# The last line.
#@-node:ekr.20090529061522.6619:@@shadow unittest/read_test.py
#@-node:ekr.20090529061522.6618:@test at.readOneAtShadowNode
#@+node:ekr.20090529061522.6620:@test at.replaceFileWithString
import os
s = 'abc'
fn = 'unitTestFile.py'
path = g.os_path_abspath(g.os_path_join(g.app.loadDir,'..','test','unittest',fn))
try:
    c.atFileCommands.replaceFileWithString(path,s)
    f = open(path)
    s2 = f.read()
    f.close()
    assert s == s2
finally:
    if g.os_path_exists(path):
        os.unlink(path)
#@nonl
#@-node:ekr.20090529061522.6620:@test at.replaceFileWithString
#@+node:ekr.20090529061522.6621:@test at.writeOneAtShadowNode
at = c.atFileCommands
x = c.shadowController
changed = c.changed
child = p.firstChild()
s = child.b

try:
    child.setHeadString('@shadow unittest/test_1.py')
    fn = 'unittest/test_1.py'
    shadow_fn = x.shadowPathName(fn)
    shadow_dir = x.shadowDirName(fn)
    x.makeShadowDirectory(shadow_dir)
    if g.os_path_exists(shadow_fn):
        g.utils_remove(shadow_fn,verbose=True)
    at.writeOneAtShadowNode(child,toString=True,force=True)
    assert at.startSentinelComment == '#','startSentinelComment: %s' % (
        repr(at.startSentinelComment))
    assert at.endSentinelComment == '','endSentinelComment: %s' % (
        repr(at.endSentinelComment))
    if 0:
        print('public...\n',at.public_s)
        print('private...\n',at.private_s)
    at.writeOneAtShadowNode(child,toString=False,force=True)
    assert g.os_path_exists(shadow_fn),'not found: %s' % shadow_fn
    # No need to remove this: it's in the unittest directory.
    # g.utils_remove(shadow_fn,verbose=True)
finally:
    child.setHeadString('@@shadow unittest/test_1.py')
    c.setChanged(changed)
    # c.redraw_now()
#@nonl
#@+node:ekr.20090529061522.6622:@@shadow unittest/test_1.py
# body of @shadow test node
# The last line. changed 2
#@nonl
#@-node:ekr.20090529061522.6622:@@shadow unittest/test_1.py
#@-node:ekr.20090529061522.6621:@test at.writeOneAtShadowNode
#@-node:ekr.20090529061522.6615:Unit tests for atFileCommands
#@+node:ekr.20090529061522.6623:@test delete unittest shadow directory
# This unit test should come last.

import glob
import os

x = c.shadowController

shadow_dir = x.shadowDirName('unittest/xyzzy')

if g.os_path_exists(shadow_dir):
    files = g.os_path_abspath(g.os_path_join(shadow_dir,"*.*"))
    files = glob.glob(files)
    for z in files:
        if z != shadow_dir:
            os.unlink(z)
    os.rmdir(shadow_dir)
    assert not os.path.exists(shadow_dir)
    # g.es_print('deleted directory',shadow_dir,color='red')
#@-node:ekr.20090529061522.6623:@test delete unittest shadow directory
#@-node:ekr.20090529061522.6449:leoShadow
#@-node:ekr.20090529103821.6587:Organized by file
#@-all
#@nonl
#@-node:ekr.20090113083258.1:@thin test_core.txt
#@-leo
