Skip to content
This repository

fix Magic menu in qtconsole, split in groups #1782

Merged
merged 1 commit into from almost 2 years ago

3 participants

Matthias Bussonnier Thomas Kluyver Min RK
Matthias Bussonnier
Collaborator
Carreau commented May 29, 2012

partially fixes #1774

alternative to #1776, that also reorganize magic in several menu.
Menu name is decided by inserting space in the CamelCasse name of the class of the magic.

screencap

Moreover, if there is a way to know if the magic have to take argument or not (%logstate vs %timeit),
I could tweak the menu to either execute, or to paste the magic at the beginning of the curent line.

Thomas Kluyver
Collaborator

The ... on 'All magics' looks odd, because it has a submenu. Normally, ... implies that clicking on it will bring up some sort of dialog.

Matthias Bussonnier
Collaborator
Carreau commented May 29, 2012

... removed .

IPython/core/magic.py
... ...
@@ -322,6 +322,17 @@ def auto_status(self):
322 322
         """Return descriptive string with automagic status."""
323 323
         return self._auto_status[self.auto_magic]
324 324
 
  325
+    def lsmagic_info(self):
  326
+        """return a json encode/decodable dict for frontend
  327
+
  328
+        mainly needed by qtconsole to build the Magics Menu
  329
+        """
  330
+        magic_list = []
  331
+        for m_type, m_list in self.magics.iteritems() :
  332
+            for m_name, mgc in m_list.iteritems():
  333
+                magic_list.append({'name':m_name, 'type':m_type, 'class':mgc.im_class.__name__})
1
Min RK Owner
minrk added a note June 01, 2012

mgc may be just a function here, in which case this will raise AttributeError on im_class. To see this, simply run this block in the qtconsole on master, where %guiref is such a magic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Matthias Bussonnier fix magic menu in qtconsole
Rearrange magics in menu, organize as submenu based on class of magic
d5bcd72
Matthias Bussonnier
Collaborator

Thanks, fixed, rebased and squashed to have cleaner commits.

Matthias Bussonnier
Collaborator

Does anybody ave something agains me merging it ?
Otherwise i'll do so in 24h.

Matthias Bussonnier
Collaborator

merging then...

Matthias Bussonnier Carreau merged commit 8b00a30 into from June 06, 2012
Matthias Bussonnier Carreau closed this June 06, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Jun 02, 2012
Matthias Bussonnier fix magic menu in qtconsole
Rearrange magics in menu, organize as submenu based on class of magic
d5bcd72
This page is out of date. Refresh to see the latest.
10  IPython/core/magic.py
@@ -321,6 +321,16 @@ def __init__(self, shell=None, config=None, user_magics=None, **traits):
321 321
     def auto_status(self):
322 322
         """Return descriptive string with automagic status."""
323 323
         return self._auto_status[self.auto_magic]
  324
+    
  325
+    def lsmagic_info(self):
  326
+        magic_list = []
  327
+        for m_type in self.magics :
  328
+            for m_name,mgc in self.magics[m_type].items():
  329
+                try :
  330
+                    magic_list.append({'name':m_name,'type':m_type,'class':mgc.im_class.__name__})
  331
+                except AttributeError :
  332
+                    magic_list.append({'name':m_name,'type':m_type,'class':'Other'})
  333
+        return magic_list
324 334
 
325 335
     def lsmagic(self):
326 336
         """Return a dict of currently available magic functions.
72  IPython/frontend/qt/console/mainwindow.py
@@ -22,6 +22,7 @@
22 22
 import sys
23 23
 import re
24 24
 import webbrowser
  25
+import ast
25 26
 from threading import Thread
26 27
 
27 28
 # System library imports
@@ -43,6 +44,8 @@ class MainWindow(QtGui.QMainWindow):
43 44
     # 'object' interface
44 45
     #---------------------------------------------------------------------------
45 46
 
  47
+    _magic_menu_dict = {}
  48
+
46 49
     def __init__(self, app,
47 50
                     confirm_exit=True,
48 51
                     new_frontend_factory=None, slave_frontend_factory=None,
@@ -592,23 +595,35 @@ def populate_all_magic_menu(self, listofmagic=None):
592 595
         `listofmagic`is a repr() of list because it is fed with the result of
593 596
         a 'user_expression'
594 597
         """
595  
-        alm_magic_menu = self.all_magic_menu
596  
-        alm_magic_menu.clear()
597  
-
598  
-        # list of protected magic that don't like to be called without argument
599  
-        # append '?' to the end to print the docstring when called from the menu
600  
-        protected_magic = set(["more","less","load_ext","pycat","loadpy","load","save"])
601  
-        magics=re.findall('\w+', listofmagic)
602  
-        for magic in magics:
603  
-            if magic in protected_magic:
604  
-                pmagic = '%s%s%s'%('%',magic,'?')
605  
-            else:
606  
-                pmagic = '%s%s'%('%',magic)
  598
+        for k,v in self._magic_menu_dict.items():
  599
+            v.clear()
  600
+        self.all_magic_menu.clear()
  601
+
  602
+
  603
+        protected_magic = set(["more","less","load_ext","pycat","loadpy","load","save","psource"])
  604
+        mlist=ast.literal_eval(listofmagic)
  605
+        for magic in mlist:
  606
+            cell = (magic['type'] == 'cell')
  607
+            name = magic['name']
  608
+            mclass = magic['class']
  609
+            if cell :
  610
+                prefix='%%'
  611
+            else :
  612
+                prefix='%'
  613
+            magic_menu = self._get_magic_menu(mclass)
  614
+
  615
+            if name in protected_magic:
  616
+                suffix = '?'
  617
+            else :
  618
+                suffix = ''
  619
+            pmagic = '%s%s%s'%(prefix,name,suffix)
  620
+
607 621
             xaction = QtGui.QAction(pmagic,
608 622
                 self,
609 623
                 triggered=self._make_dynamic_magic(pmagic)
610 624
                 )
611  
-            alm_magic_menu.addAction(xaction)
  625
+            magic_menu.addAction(xaction)
  626
+            self.all_magic_menu.addAction(xaction)
612 627
 
613 628
     def update_all_magic_menu(self):
614 629
         """ Update the list on magic in the "All Magics..." Menu
@@ -617,12 +632,37 @@ def update_all_magic_menu(self):
617 632
         menu with the list received back
618 633
 
619 634
         """
620  
-        # first define a callback which will get the list of all magic and put it in the menu.
621  
-        self.active_frontend._silent_exec_callback('get_ipython().lsmagic()', self.populate_all_magic_menu)
  635
+        self.active_frontend._silent_exec_callback('get_ipython().magics_manager.lsmagic_info()',
  636
+                self.populate_all_magic_menu)
  637
+
  638
+    def _get_magic_menu(self,menuidentifier, menulabel=None):
  639
+        """return a submagic menu by name, and create it if needed
  640
+       
  641
+        parameters:
  642
+        -----------
  643
+
  644
+        menulabel : str
  645
+            Label for the menu
  646
+
  647
+        Will infere the menu name from the identifier at creation if menulabel not given.
  648
+        To do so you have too give menuidentifier as a CamelCassedString
  649
+        """
  650
+        menu = self._magic_menu_dict.get(menuidentifier,None)
  651
+        if not menu :
  652
+            if not menulabel:
  653
+                menulabel = re.sub("([a-zA-Z]+)([A-Z][a-z])","\g<1> \g<2>",menuidentifier)
  654
+            menu = QtGui.QMenu(menulabel,self.magic_menu)
  655
+            self._magic_menu_dict[menuidentifier]=menu
  656
+            self.magic_menu.insertMenu(self.magic_menu_separator,menu)
  657
+        return menu
  658
+
622 659
 
  660
+        
623 661
     def init_magic_menu(self):
624 662
         self.magic_menu = self.menuBar().addMenu("&Magic")
625  
-        self.all_magic_menu = self.magic_menu.addMenu("&All Magics")
  663
+        self.magic_menu_separator = self.magic_menu.addSeparator()
  664
+        
  665
+        self.all_magic_menu = self._get_magic_menu("AllMagics", menulabel="&All Magics...")
626 666
 
627 667
         # This action should usually not appear as it will be cleared when menu
628 668
         # is updated at first kernel response. Though, it is necessary when
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.