5
5
import re
6
6
import codecs
7
7
from PySide2 .QtWidgets import (QLineEdit , QPushButton , QApplication , QTextEdit , QWidget ,
8
- QVBoxLayout , QHBoxLayout , QDialog , QFileSystemModel , QTreeView , QLabel , QSplitter ,
9
- QInputDialog , QMessageBox , QHeaderView , QMenu , QAction , QKeySequenceEdit ,
10
- QPlainTextEdit )
8
+ QVBoxLayout , QHBoxLayout , QDialog , QFileSystemModel , QTreeView , QLabel , QSplitter ,
9
+ QInputDialog , QMessageBox , QHeaderView , QMenu , QAction , QKeySequenceEdit ,
10
+ QPlainTextEdit )
11
11
from PySide2 .QtCore import (QDir , QObject , Qt , QFileInfo , QItemSelectionModel , QSettings , QUrl )
12
12
from PySide2 .QtGui import (QFont , QFontMetrics , QDesktopServices , QKeySequence , QIcon )
13
13
from binaryninja import user_plugin_path
14
14
from binaryninja .plugin import PluginCommand , MainThreadActionHandler
15
15
from binaryninja .mainthread import execute_on_main_thread
16
16
from binaryninja .log import (log_error , log_debug )
17
- from binaryninjaui import (getMonospaceFont , UIAction , UIActionHandler , Menu , DockHandler )
17
+ from binaryninjaui import (getMonospaceFont , UIAction , UIActionHandler , Menu , DockHandler ,
18
+ getThemeColor , ThemeColor )
18
19
import numbers
20
+ from .lntextedit import LNTextEdit
19
21
20
22
snippetPath = os .path .realpath (os .path .join (user_plugin_path (), ".." , "snippets" ))
21
23
try :
@@ -33,6 +35,7 @@ def includeWalk(dir, includeExt):
33
35
filePaths .append (os .path .join (root , f ))
34
36
return filePaths
35
37
38
+
36
39
def loadSnippetFromFile (snippetPath ):
37
40
try :
38
41
snippetText = codecs .open (snippetPath , 'r' , "utf-8" ).readlines ()
@@ -49,6 +52,7 @@ def loadSnippetFromFile(snippetPath):
49
52
'' .join (snippetText [2 :])
50
53
)
51
54
55
+
52
56
def actionFromSnippet (snippetName , snippetDescription ):
53
57
if not snippetDescription :
54
58
shortName = os .path .basename (snippetName )
@@ -113,6 +117,7 @@ def executeSnippet(code, context):
113
117
if snippetGlobals ['current_address' ] != context .address :
114
118
context .binaryView .file .navigate (context .binaryView .file .view , snippetGlobals ['current_address' ])
115
119
120
+
116
121
def makeSnippetFunction (code ):
117
122
return lambda context : executeSnippet (code , context )
118
123
@@ -135,8 +140,9 @@ def __init__(self, context, parent=None):
135
140
self .browseButton .setIcon (QIcon .fromTheme ("edit-undo" ))
136
141
self .deleteSnippetButton = QPushButton ("Delete" )
137
142
self .newSnippetButton = QPushButton ("New Snippet" )
138
- self .edit = QPlainTextEdit ()
139
- self .edit .setPlaceholderText ("python code" )
143
+ self .edit = LNTextEdit ()
144
+ self .edit .edit .setPlaceholderText ("python code" )
145
+ self .edit .edit .highlight_color = getThemeColor (ThemeColor .SelectionColor )
140
146
self .resetting = False
141
147
self .columns = 3
142
148
self .context = context
@@ -151,9 +157,9 @@ def __init__(self, context, parent=None):
151
157
152
158
#Set Editbox Size
153
159
font = getMonospaceFont (self )
154
- self .edit .setFont (font )
160
+ self .edit .edit . setFont (font )
155
161
font = QFontMetrics (font )
156
- self .edit .setTabStopWidth (4 * font .width (' ' )); #TODO, replace with settings API
162
+ self .edit .edit . setTabStopWidth (4 * font .width (' ' )); #TODO, replace with settings API
157
163
158
164
#Files
159
165
self .files = QFileSystemModel ()
@@ -240,9 +246,9 @@ def __init__(self, context, parent=None):
240
246
if self .tree .selectionModel ().hasSelection ():
241
247
self .selectFile (self .tree .selectionModel ().selection (), None )
242
248
self .edit .setFocus ()
243
- cursor = self .edit .textCursor ()
244
- cursor .setPosition (self .edit .document ().characterCount ()- 1 )
245
- self .edit .setTextCursor (cursor )
249
+ cursor = self .edit .edit . textCursor ()
250
+ cursor .setPosition (self .edit .edit . document ().characterCount ()- 1 )
251
+ self .edit .edit . setTextCursor (cursor )
246
252
else :
247
253
self .readOnly (True )
248
254
else :
@@ -276,7 +282,7 @@ def clearSelection(self):
276
282
self .currentHotkeyLabel .setText ("" )
277
283
self .currentFileLabel .setText ("" )
278
284
self .snippetDescription .setText ("" )
279
- self .edit .setPlainText ("" )
285
+ self .edit .edit . setPlainText ("" )
280
286
self .currentFile = ""
281
287
282
288
def reject (self ):
@@ -331,7 +337,7 @@ def loadSnippet(self):
331
337
(snippetDescription , snippetKeys , snippetCode ) = loadSnippetFromFile (self .currentFile )
332
338
self .snippetDescription .setText (snippetDescription ) if snippetDescription else self .snippetDescription .setText ("" )
333
339
self .keySequenceEdit .setKeySequence (snippetKeys ) if snippetKeys else self .keySequenceEdit .setKeySequence (QKeySequence ("" ))
334
- self .edit .setPlainText (snippetCode ) if snippetCode else self .edit .setPlainText ("" )
340
+ self .edit .edit . setPlainText (snippetCode ) if snippetCode else self . edit .edit .setPlainText ("" )
335
341
self .readOnly (False )
336
342
337
343
def newFileDialog (self ):
@@ -353,7 +359,7 @@ def newFileDialog(self):
353
359
def readOnly (self , flag ):
354
360
self .keySequenceEdit .setEnabled (not flag )
355
361
self .snippetDescription .setReadOnly (flag )
356
- self .edit .setReadOnly (flag )
362
+ self .edit .edit . setReadOnly (flag )
357
363
if flag :
358
364
self .snippetDescription .setDisabled (True )
359
365
self .edit .setDisabled (True )
@@ -379,15 +385,15 @@ def snippetChanged(self):
379
385
return True
380
386
if snippetKeys != None and snippetKeys != self .keySequenceEdit .keySequence ().toString ():
381
387
return True
382
- return self .edit .toPlainText () != snippetCode or \
388
+ return self .edit .edit . toPlainText () != snippetCode or \
383
389
self .snippetDescription .text () != snippetDescription
384
390
385
391
def save (self ):
386
392
log_debug ("Saving snippet %s" % self .currentFile )
387
393
outputSnippet = codecs .open (self .currentFile , "w" , "utf-8" )
388
394
outputSnippet .write ("#" + self .snippetDescription .text () + "\n " )
389
395
outputSnippet .write ("#" + self .keySequenceEdit .keySequence ().toString () + "\n " )
390
- outputSnippet .write (self .edit .toPlainText ())
396
+ outputSnippet .write (self .edit .edit . toPlainText ())
391
397
outputSnippet .close ()
392
398
self .registerAllSnippets ()
393
399
@@ -408,17 +414,19 @@ def run(self):
408
414
outputSnippet = codecs .open (self .currentFile , "w" , "utf-8" )
409
415
outputSnippet .write ("#" + self .snippetDescription .text () + "\n " )
410
416
outputSnippet .write ("#" + self .keySequenceEdit .keySequence ().toString () + "\n " )
411
- outputSnippet .write (self .edit .toPlainText ())
417
+ outputSnippet .write (self .edit .edit . toPlainText ())
412
418
outputSnippet .close ()
413
419
self .registerAllSnippets ()
414
420
415
421
def clearHotkey (self ):
416
422
self .keySequenceEdit .clear ()
417
423
424
+
418
425
def launchPlugin (context ):
419
426
snippets = Snippets (context )
420
427
snippets .exec_ ()
421
428
429
+
422
430
if __name__ == '__main__' :
423
431
app = QApplication (sys .argv )
424
432
snippets = Snippets (None )
0 commit comments