MiDe è un piccolo ambiente di sviluppo scritto in python, utilizzando le librerie wx, quasi completamente basato sul componente StyledTextCtrl di Scintilla.
MiDe è pensato per essere un tool estremamente ridotto, con funzioni molto essenziali.
Attualmente fornisce supporto completo per i seguenti linguaggi:
C
C++
Python
Perl
E le seguenti funzioni:
Code Folding
Compilazione ed Esecuzione del Codice
Indentazione Automatica
Syntax Highlighting
più alcune altre di scarso interesse.
Ovviamente per l'esecuzione/compilazione del vostro codice è necessario che abbiate l'interprete/compilatore adeguato installato sul vostro computer e la path all'interprete settata nelle variabili globali.
Perché MiDe funzioni correttamente, è necessario che scarichiate tutto il pacchetto (che comprende le icone necessarie), e che abbiate installato wxPython e Python 2.5 o superiore.
MiDe è pensato per essere un tool estremamente ridotto, con funzioni molto essenziali.
Attualmente fornisce supporto completo per i seguenti linguaggi:
C
C++
Python
Perl
E le seguenti funzioni:
Code Folding
Compilazione ed Esecuzione del Codice
Indentazione Automatica
Syntax Highlighting
più alcune altre di scarso interesse.
Ovviamente per l'esecuzione/compilazione del vostro codice è necessario che abbiate l'interprete/compilatore adeguato installato sul vostro computer e la path all'interprete settata nelle variabili globali.
Perché MiDe funzioni correttamente, è necessario che scarichiate tutto il pacchetto (che comprende le icone necessarie), e che abbiate installato wxPython e Python 2.5 o superiore.
Codice:
Copyright (c) 2009 HackLife
License: CC - by/nc/sa
Codice:
#----- MiDe -----#
#Title: MiDe
#Author: HackLife
#Descr: A minimalistic application, intended to be an IDE for many languages
#Version: 1.2
#---------------#
#Copyright: 2009 HackLife
#Mail: [email protected]
#---------------#
#Changelog:
#@1.0
#@1.0.1 Fixed IndexError @OnWrite
#@1.0.2 Fixed Error @OnClose
#@1.0.3
#Add Cut/Copy/Paste
#@1.1
#C/C++ Support
#@1.2
#Perl Support
#---------------#
#This far, MiDe supports completely Python, C, C++ and Perl.
#For further information, please, see the readme.
import wx
from wx import stc
import os
import keyword
CPP_KEYWORDS = """asm auto bool break case catch char class const
const_cast continue default delete do double dynamic_cast else enum explicit
export extern false float for friend goto id inline int long mutable namespace
new operator private protected public register reinterpret_cast return short
signed static static_cast struct switch template this throw true try typedef
typeid typename union unsigned using virtual void volatile wchar_t while"""
PL_KEYWORDS = """delete if sub switch"""
class IO:
def __init__(self):
self.UNKNOWN_FILETYPE = " !Unknown Filetype!"
self.PY_RECOG = "Python Recognized"
self.CPP_RECOG = "C++ Recognized"
self.PL_RECOG = "Perl Recognized"
self.C_RECOG = "C Recognized"
self.NO_PAGE = "Selected Page Doesn't Exist"
def out(self, param):
myMiDe.statusbar.SetFields([param])
buff = IO()
class FilePanel(wx.Panel):
def __init__(self, parent, id, lang):
wx.Panel.__init__(self, parent, id)
vBox = wx.BoxSizer(wx.VERTICAL)
self.tcCode = stc.StyledTextCtrl(self, 1)
if lang == 'py':
buff.out(buff.PY_RECOG)
self.tcCode.SetKeyWords(0, ' '.join(keyword.kwlist))
self.tcCode.SetLexer(stc.STC_LEX_PYTHON)
elif lang == 'pp':
buff.out(buff.CPP_RECOG)
self.tcCode.SetKeyWords(0, CPP_KEYWORDS)
self.tcCode.SetLexer(stc.STC_LEX_CPP)
elif lang == 'pl':
buff.out(buff.PL_RECOG)
self.tcCode.SetKeyWords(0, PL_KEYWORDS)
self.tcCode.SetLexer(stc.STC_LEX_PERL)
self.SetStyle('standard')
self.indent = 4 #--------------------------------User may want to vary
self.tcCode.SetTabWidth(self.indent)
self.tcCode.SetProperty('fold', '1')
self.tcCode.SetMargins(0,0)
self.tcCode.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
self.tcCode.SetEdgeColumn(78)
self.tcCode.SetCaretForeground('white')
self.tcCode.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
self.tcCode.SetMarginMask(2, stc.STC_MASK_FOLDERS)
self.tcCode.SetMarginSensitive(2, True)
self.tcCode.SetMarginWidth(2, 12)
self.tcCode.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,
stc.STC_MARK_BOXMINUS, "white", "#808080")
self.tcCode.MarkerDefine(stc.STC_MARKNUM_FOLDER,
stc.STC_MARK_BOXPLUS, "white", "#808080")
self.tcCode.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,
stc.STC_MARK_VLINE, "white", "#808080")
self.tcCode.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,
stc.STC_MARK_LCORNER, "white", "#808080")
self.tcCode.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,
stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
self.tcCode.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID,
stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
self.tcCode.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL,
stc.STC_MARK_TCORNER, "white", "#808080")
self.Bind(stc.EVT_STC_MARGINCLICK, self.OnFold)
self.tcCode.Bind(wx.EVT_KEY_DOWN, self.OnWrite)
vBox.Add(self.tcCode, 1, wx.EXPAND)
self.SetSizer(vBox)
#The Following Function Has Been Copy-Pasted From Dietrich
#Thanks :)
def OnFold(self, event):
if event.GetMargin() == 2:
lineClicked = self.tcCode.LineFromPosition(event.GetPosition())
if self.tcCode.GetFoldLevel(lineClicked) &\
stc.STC_FOLDLEVELHEADERFLAG:
if event.GetShift():
self.tcCode.SetFoldexpanded(lineClicked, True)
self.tcCode.expand(lineClicked, True, True, 1)
elif event.GetControl():
if self.tcCode.GetFoldexpanded(lineClicked):
self.tcCode.SetFoldexpanded(lineClicked, False)
self.tcCode.expand(lineClicked, False, True, 0)
else:
self.tcCode.SetFoldexpanded(lineClicked, True)
self.tcCode.expand(lineClicked, True, True, 100)
else:
self.tcCode.ToggleFold(lineClicked)
#This is a function for setting StyledTextCtrl style.
#Flame_Alchemist helped a lot in this. Thanks man.
def SetStyle(self, style):
if style == 'standard':
caratteristiche = { 'times': 'Arial',
'mono' : 'Courier New',
'helv' : 'Helvetica',
'size' : 10
}
self.tcCode.StyleSetSpec(stc.STC_STYLE_DEFAULT,
"fore:#008000,face:%(mono)s,size:%(size)d" % caratteristiche)
self.tcCode.StyleSetBackground(style=stc.STC_STYLE_DEFAULT,
back='#000000')
self.tcCode.StyleClearAll()
self.tcCode.StyleSetSpec(stc.STC_P_CLASSNAME,
"fore:#0000FF,face:%(mono)s,size:%(size)d" % caratteristiche)
self.tcCode.StyleSetSpec(stc.STC_P_IDENTIFIER,
"fore:#00FF00,face:%(mono)s,size:%(size)d" % caratteristiche)
self.tcCode.StyleSetSpec(stc.STC_P_DEFNAME,
"fore:#0000FF,face:%(mono)s,size:%(size)d" % caratteristiche)
self.tcCode.StyleSetSpec(stc.STC_P_COMMENTLINE,
"fore:#FF0000,face:%(mono)s,size:%(size)d" % caratteristiche)
self.tcCode.StyleSetSpec(stc.STC_P_NUMBER,
"fore:#0000FF,size:%(size)d" % caratteristiche)
self.tcCode.StyleSetSpec(stc.STC_P_STRING,
"fore:#00FFFF,face:%(mono)s,size:%(size)d" % caratteristiche)
self.tcCode.StyleSetSpec(stc.STC_P_CHARACTER,
"fore:#00FFFF,face:%(mono)s,size:%(size)d" % caratteristiche)
self.tcCode.StyleSetSpec(stc.STC_PL_COMMENTLINE,
"fore:#FF0000,face:%(mono)s,size:%(size)d" % caratteristiche)
return True
def OnWrite(self, event):
#Oh man, I'm ***so*** proud of this function!
##I'm keeping the old version in case the updated one doesnt work well :P
## if event.GetKeyCode() == 13:
## j = 0
## while self.tcCode.GetLine(self.tcCode.GetCurrentLine())[j] == ' ':
## j += 1
## if self.tcCode.GetLine(
## self.tcCode.GetCurrentLine())[-2] == ':' or \
## self.tcCode.GetLine(
## self.tcCode.GetCurrentLine())[-2] == '{':
## self.tcCode.InsertText(
## self.tcCode.GetCurrentPos(), '\n'+(' '*j)+' '*self.indent)
## self.tcCode.GotoPos(
## self.tcCode.GetCurrentPos()+j+1+self.indent)
## elif self.tcCode.GetLine(
## self.tcCode.GetCurrentLine())[-1] == ':' or \
## self.tcCode.GetLine(
## self.tcCode.GetCurrentLine())[-1] == '{':
## self.tcCode.InsertText(
## self.tcCode.GetCurrentPos(), '\n'+(' '*j)+' '*self.indent)
## self.tcCode.GotoPos(
## self.tcCode.GetCurrentPos()+j+1+self.indent)
## else:
## self.tcCode.InsertText(
## self.tcCode.GetCurrentPos(), '\n'+(' '*j))
## self.tcCode.GotoPos(
## self.tcCode.GetCurrentPos()+j+1)
## if j == 0:
## return
## else:
## event.Skip()
if event.GetKeyCode() == 13:
#You see? It works with tabs *and* spaces.
j = 0
k = 0
while self.tcCode.GetLine(self.tcCode.GetCurrentLine())[j] == ' ':
j += 1
while self.tcCode.GetLine(self.tcCode.GetCurrentLine())[k] == '\t':
j += 4
k += 1
try:
if self.tcCode.GetLine(
self.tcCode.GetCurrentLine())[-2] == ':' or \
self.tcCode.GetLine(
self.tcCode.GetCurrentLine())[-2] == '{':
self.tcCode.InsertText(
self.tcCode.GetCurrentPos(), '\n'+('\t'*(j/4))+'\t'*(self.indent/4))
self.tcCode.GotoPos(
self.tcCode.GetCurrentPos()+j/4+1+self.indent/4)
elif self.tcCode.GetLine(
self.tcCode.GetCurrentLine())[-1] == ':' or \
self.tcCode.GetLine(
self.tcCode.GetCurrentLine())[-1] == '{':
self.tcCode.InsertText(
self.tcCode.GetCurrentPos(), '\n'+('\t'*(j/4))+'\t'*(self.indent/4))
self.tcCode.GotoPos(
self.tcCode.GetCurrentPos()+j/4+1+self.indent/4)
else:
self.tcCode.InsertText(
self.tcCode.GetCurrentPos(), '\n'+('\t'*(j/4)))
self.tcCode.GotoPos(
self.tcCode.GetCurrentPos()+j/4+1)
if j == 0:
return
except IndexError:
event.Skip()
else:
event.Skip()
class MiDe(wx.Frame):
def __init__(self, parent, id, title):
self.openfiles = {}
wx.Frame.__init__(self, parent, id, title, size =(800,600))
#These are for shortcuts:
newId = wx.NewId()
openId = wx.NewId()
saveId = wx.NewId()
runId = wx.NewId()
closeId = wx.NewId()
undoId = wx.NewId()
redoId = wx.NewId()
exitId = wx.NewId()
sTable = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('N'), newId),
(wx.ACCEL_CTRL, ord('O'), openId),
(wx.ACCEL_CTRL, ord('S'), saveId),
(wx.ACCEL_CTRL, ord('R'), runId),
(wx.ACCEL_CTRL, ord('Q'), closeId),
(wx.ACCEL_CTRL, ord('Z'), undoId),
(wx.ACCEL_CTRL, ord('A'), redoId),
(wx.ACCEL_CTRL, ord('E'), exitId)])
#^^^
toolbar = self.CreateToolBar()
toolbar.AddLabelTool(1, 'New', wx.Bitmap('ico/new.png'))
toolbar.AddLabelTool(2, 'Open', wx.Bitmap('ico/open.png'))
toolbar.AddLabelTool(3, 'Save', wx.Bitmap('ico/save.png'))
toolbar.AddSeparator()
toolbar.AddLabelTool(4, 'Run', wx.Bitmap('ico/run.png'))
toolbar.AddLabelTool(5, 'Close', wx.Bitmap('ico/close.png'))
toolbar.AddSeparator()
toolbar.AddLabelTool(6, 'Undo', wx.Bitmap('ico/undo.png'))
toolbar.AddLabelTool(7, 'Redo', wx.Bitmap('ico/redo.png'))
toolbar.AddSeparator()
toolbar.AddLabelTool(8, 'Cut', wx.Bitmap('ico/cut.png'))
toolbar.AddLabelTool(9, 'Copy', wx.Bitmap('ico/copy.png'))
toolbar.AddLabelTool(10, 'Paste', wx.Bitmap('ico/paste.png'))
toolbar.Realize()
self.statusbar = self.CreateStatusBar()
self.notebook = wx.Notebook(self, -1)
self.Bind(wx.EVT_TOOL, self.OnNew, id = 1)
self.Bind(wx.EVT_TOOL, self.OnOpen, id = 2)
self.Bind(wx.EVT_TOOL, self.OnSave, id = 3)
self.Bind(wx.EVT_TOOL, self.OnRun, id = 4)
self.Bind(wx.EVT_TOOL, self.OnClose, id = 5)
self.Bind(wx.EVT_TOOL, self.OnUndo, id = 6)
self.Bind(wx.EVT_TOOL, self.OnRedo, id = 7)
self.Bind(wx.EVT_TOOL, self.OnCut, id = 8)
self.Bind(wx.EVT_TOOL, self.OnCopy, id = 9)
self.Bind(wx.EVT_TOOL, self.OnPaste, id = 10)
self.Bind(wx.EVT_MENU, self.OnNew, id = newId)
self.Bind(wx.EVT_MENU, self.OnOpen, id = openId)
self.Bind(wx.EVT_MENU, self.OnSave, id = saveId)
self.Bind(wx.EVT_MENU, self.OnRun, id = runId)
self.Bind(wx.EVT_MENU, self.OnClose, id = closeId)
self.Bind(wx.EVT_MENU, self.OnUndo, id = undoId)
self.Bind(wx.EVT_MENU, self.OnRedo, id = redoId)
self.Bind(wx.EVT_MENU, self.OnExit, id = exitId)
self.Bind(wx.EVT_CLOSE, self.OnExit, id = -1)
self.SetAcceleratorTable(sTable)
self.Center()
self.Show(True)
def OnNew(self, event):
fileBrowser = wx.FileDialog(self, 'New File', style = wx.OPEN)
fileBrowser.ShowModal()
if fileBrowser.GetFilename() == '':
return
filePanel = FilePanel(self.notebook, -1, fileBrowser.GetFilename()[-2:])
self.notebook.InsertPage(0, filePanel, fileBrowser.GetFilename())
self.notebook.ChangeSelection(0)
self.openfiles[self.notebook.GetCurrentPage()] = fileBrowser.GetPath()
def OnOpen(self, event):
fileBrowser = wx.FileDialog(self, 'Open File', style = wx.OPEN)
fileBrowser.ShowModal()
try:
mfile = open(fileBrowser.GetPath(), 'r')
except IOError:
return
datas = mfile.read()
mfile.close()
filePanel = FilePanel(self.notebook, -1, fileBrowser.GetFilename()[-2:])
self.notebook.InsertPage(0, filePanel, fileBrowser.GetFilename())
self.notebook.ChangeSelection(0)
filePanel.tcCode.AddText(datas)
self.openfiles[self.notebook.GetCurrentPage()] = fileBrowser.GetPath()
def OnSave(self, event):
mfile = open(self.openfiles[self.notebook.GetCurrentPage()], 'w')
mfile.write(self.notebook.GetCurrentPage().tcCode.GetText())
mfile.close()
def OnRun(self, event):
#This section is meant to be expanded:
if self.openfiles[self.notebook.GetCurrentPage()][-2:] == 'py': #Python
os.system('python "%s"'
% self.openfiles[self.notebook.GetCurrentPage()])
elif self.openfiles[self.notebook.GetCurrentPage()][-2:] == 'pp': #C++
path = self.openfiles[self.notebook.GetCurrentPage()]
os.system('g++ "'+path+'" -o "'+path[:-3]+'exe"')
os.system('"'+path[:-3]+'exe"')
elif self.openfiles[self.notebook.GetCurrentPage()][-2:] == '.c': #C
path = self.openfiles[self.notebook.GetCurrentPage()]
os.system('gcc "'+path+'" -o "'+path[:-3]+'exe"')
os.system('"'+path[:-3]+'exe"')
elif self.openfiles[self.notebook.GetCurrentPage()][-2:] == 'pl': #Perl
os.system('perl "%s"' %
self.openfiles[self.notebook.GetCurrentPage()])
else:
buff.out(buff.UNKNOWN_FILETYPE)
#^^^
def OnClose(self, event):
try:
ufile = open(self.openfiles[self.notebook.GetCurrentPage()], 'r')
if self.notebook.GetCurrentPage().tcCode.GetText() != \
ufile.read():
saveControl = wx.MessageDialog(None, 'Save before closing?',
'Save', wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
if saveControl.ShowModal() == 5103:
self.OnSave(None)
self.notebook.DeletePage(self.notebook.GetSelection())
except:
buff.out(buff.NO_PAGE)
def OnUndo(self, event):
self.notebook.GetCurrentPage().tcCode.Undo()
def OnRedo(self, event):
self.notebook.GetCurrentPage().tcCode.Redo()
def OnCut(self, event):
self.notebook.GetCurrentPage().tcCode.Cut()
def OnCopy(self, event):
self.notebook.GetCurrentPage().tcCode.Copy()
def OnPaste(self, event):
self.notebook.GetCurrentPage().tcCode.Paste()
def OnExit(self, event):
for i in range(0,self.notebook.GetPageCount()):
ufile = open(self.openfiles[self.notebook.GetPage(0)],
'r')
if self.notebook.GetPage(0).tcCode.GetText() != \
ufile.read():
saveControl = wx.MessageDialog(None,'Save before closing?',
'Save', wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
if saveControl.ShowModal() == 5103:
self.OnSave(None)
self.Destroy()
if __name__ == "__main__":
app = wx.App()
myMiDe = MiDe(None, -1, "MiDe")
app.MainLoop()