Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

fix Magic menu in qtconsole, split in groups #1782

Merged
merged 1 commit into from

3 participants

@Carreau
Owner

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.

@takluyver
Owner

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

@Carreau
Owner

... removed .

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

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
@Carreau Carreau fix magic menu in qtconsole
Rearrange magics in menu, organize as submenu based on class of magic
d5bcd72
@Carreau
Owner

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

@Carreau
Owner

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

@Carreau
Owner

merging then...

@Carreau Carreau merged commit 8b00a30 into ipython:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 2, 2012
  1. @Carreau

    fix magic menu in qtconsole

    Carreau authored
    Rearrange magics in menu, organize as submenu based on class of magic
This page is out of date. Refresh to see the latest.
Showing with 66 additions and 16 deletions.
  1. +10 −0 IPython/core/magic.py
  2. +56 −16 IPython/frontend/qt/console/mainwindow.py
View
10 IPython/core/magic.py
@@ -321,6 +321,16 @@ def __init__(self, shell=None, config=None, user_magics=None, **traits):
def auto_status(self):
"""Return descriptive string with automagic status."""
return self._auto_status[self.auto_magic]
+
+ def lsmagic_info(self):
+ magic_list = []
+ for m_type in self.magics :
+ for m_name,mgc in self.magics[m_type].items():
+ try :
+ magic_list.append({'name':m_name,'type':m_type,'class':mgc.im_class.__name__})
+ except AttributeError :
+ magic_list.append({'name':m_name,'type':m_type,'class':'Other'})
+ return magic_list
def lsmagic(self):
"""Return a dict of currently available magic functions.
View
72 IPython/frontend/qt/console/mainwindow.py
@@ -22,6 +22,7 @@
import sys
import re
import webbrowser
+import ast
from threading import Thread
# System library imports
@@ -43,6 +44,8 @@ class MainWindow(QtGui.QMainWindow):
# 'object' interface
#---------------------------------------------------------------------------
+ _magic_menu_dict = {}
+
def __init__(self, app,
confirm_exit=True,
new_frontend_factory=None, slave_frontend_factory=None,
@@ -592,23 +595,35 @@ def populate_all_magic_menu(self, listofmagic=None):
`listofmagic`is a repr() of list because it is fed with the result of
a 'user_expression'
"""
- alm_magic_menu = self.all_magic_menu
- alm_magic_menu.clear()
-
- # list of protected magic that don't like to be called without argument
- # append '?' to the end to print the docstring when called from the menu
- protected_magic = set(["more","less","load_ext","pycat","loadpy","load","save"])
- magics=re.findall('\w+', listofmagic)
- for magic in magics:
- if magic in protected_magic:
- pmagic = '%s%s%s'%('%',magic,'?')
- else:
- pmagic = '%s%s'%('%',magic)
+ for k,v in self._magic_menu_dict.items():
+ v.clear()
+ self.all_magic_menu.clear()
+
+
+ protected_magic = set(["more","less","load_ext","pycat","loadpy","load","save","psource"])
+ mlist=ast.literal_eval(listofmagic)
+ for magic in mlist:
+ cell = (magic['type'] == 'cell')
+ name = magic['name']
+ mclass = magic['class']
+ if cell :
+ prefix='%%'
+ else :
+ prefix='%'
+ magic_menu = self._get_magic_menu(mclass)
+
+ if name in protected_magic:
+ suffix = '?'
+ else :
+ suffix = ''
+ pmagic = '%s%s%s'%(prefix,name,suffix)
+
xaction = QtGui.QAction(pmagic,
self,
triggered=self._make_dynamic_magic(pmagic)
)
- alm_magic_menu.addAction(xaction)
+ magic_menu.addAction(xaction)
+ self.all_magic_menu.addAction(xaction)
def update_all_magic_menu(self):
""" Update the list on magic in the "All Magics..." Menu
@@ -617,12 +632,37 @@ def update_all_magic_menu(self):
menu with the list received back
"""
- # first define a callback which will get the list of all magic and put it in the menu.
- self.active_frontend._silent_exec_callback('get_ipython().lsmagic()', self.populate_all_magic_menu)
+ self.active_frontend._silent_exec_callback('get_ipython().magics_manager.lsmagic_info()',
+ self.populate_all_magic_menu)
+
+ def _get_magic_menu(self,menuidentifier, menulabel=None):
+ """return a submagic menu by name, and create it if needed
+
+ parameters:
+ -----------
+
+ menulabel : str
+ Label for the menu
+
+ Will infere the menu name from the identifier at creation if menulabel not given.
+ To do so you have too give menuidentifier as a CamelCassedString
+ """
+ menu = self._magic_menu_dict.get(menuidentifier,None)
+ if not menu :
+ if not menulabel:
+ menulabel = re.sub("([a-zA-Z]+)([A-Z][a-z])","\g<1> \g<2>",menuidentifier)
+ menu = QtGui.QMenu(menulabel,self.magic_menu)
+ self._magic_menu_dict[menuidentifier]=menu
+ self.magic_menu.insertMenu(self.magic_menu_separator,menu)
+ return menu
+
+
def init_magic_menu(self):
self.magic_menu = self.menuBar().addMenu("&Magic")
- self.all_magic_menu = self.magic_menu.addMenu("&All Magics")
+ self.magic_menu_separator = self.magic_menu.addSeparator()
+
+ self.all_magic_menu = self._get_magic_menu("AllMagics", menulabel="&All Magics...")
# This action should usually not appear as it will be cleared when menu
# is updated at first kernel response. Though, it is necessary when
Something went wrong with that request. Please try again.