mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2025-12-26 02:12:33 +01:00
Added a python plugin, which adds, among others, command completion and editing commands in a texteditor to the python prompt
the plugin sets a provided pythonrc file as the startupscript for the python cli.
This commit is contained in:
parent
6526caa1c0
commit
e188ded31f
2 changed files with 213 additions and 0 deletions
17
plugins/python/python.plugin.zsh
Normal file
17
plugins/python/python.plugin.zsh
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# use the ./pythonrc.py file as the rc for the python
|
||||
# this enables among other things:
|
||||
# - command completion on <tab>,
|
||||
# - prettyprinting of long variables
|
||||
# - a colored prompt
|
||||
# - editing commands in an editor with '\e'
|
||||
# to change the editor: set the EDITOR env variable.
|
||||
|
||||
PYTHONSTARTUP=$ZSH/plugins/python/pythonrc.py
|
||||
export PYTHONSTARTUP
|
||||
|
||||
#aliases
|
||||
alias py=python
|
||||
alias pytohn=python
|
||||
alias pyton=python
|
||||
alias py=python
|
||||
alias py=python
|
||||
196
plugins/python/pythonrc.py
Normal file
196
plugins/python/pythonrc.py
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
# This is the python resource file used in the python-plugin for oh-my-zsh.
|
||||
# It is executed when the Python interactive shell is started
|
||||
# This file is is heavily based on the sontek's dotfiles, which can be found at https://github.com/sontek/dotfiles
|
||||
# any files generated by this plugin should be contained within oh-my-zsh
|
||||
|
||||
import sys
|
||||
import os
|
||||
import atexit
|
||||
import pprint
|
||||
from tempfile import mkstemp
|
||||
from code import InteractiveConsole
|
||||
|
||||
try:
|
||||
import readline
|
||||
except ImportError:
|
||||
print("Module readline not available.")
|
||||
else:
|
||||
import rlcompleter
|
||||
readline.parse_and_bind("tab: complete")
|
||||
|
||||
ZSH_ROOT = os.environ.get("ZSH")
|
||||
if not ZSH_ROOT:
|
||||
sys.stderr.write("""Either oh-my-zsh is not installed, or the $ZSH variable was never set.
|
||||
Check your zsh resource file or reinstall oh-my-zsh
|
||||
If you want the features implented in this python resource without
|
||||
oh-my-zsh, use the script this one was based off. It can be found at:
|
||||
https://github.com/sontek/dotfiles/blob/master/_pythonrc.py
|
||||
|
||||
exiting. """)
|
||||
sys.exit()
|
||||
|
||||
|
||||
|
||||
# Color Support
|
||||
class TermColors(dict):
|
||||
"""Gives easy access to ANSI color codes. Attempts to fall back to no color
|
||||
for certain TERM values. (Mostly stolen from IPython.)"""
|
||||
# Todo: Make these compatible or at least the same as the ones in oh-my-zsh
|
||||
|
||||
COLOR_TEMPLATES = (
|
||||
("Black" , "0;30"),
|
||||
("Red" , "0;31"),
|
||||
("Green" , "0;32"),
|
||||
("Brown" , "0;33"),
|
||||
("Blue" , "0;34"),
|
||||
("Purple" , "0;35"),
|
||||
("Cyan" , "0;36"),
|
||||
("LightGray" , "0;37"),
|
||||
("DarkGray" , "1;30"),
|
||||
("LightRed" , "1;31"),
|
||||
("LightGreen" , "1;32"),
|
||||
("Yellow" , "1;33"),
|
||||
("LightBlue" , "1;34"),
|
||||
("LightPurple" , "1;35"),
|
||||
("LightCyan" , "1;36"),
|
||||
("White" , "1;37"),
|
||||
("Normal" , "0"),
|
||||
)
|
||||
|
||||
NoColor = ''
|
||||
_base = '\001\033[%sm\002'
|
||||
|
||||
def __init__(self):
|
||||
if os.environ.get('TERM') in ('xterm-color', 'xterm-256color', 'linux',
|
||||
'screenecho $TER', 'screen-256color', 'screen-bce'):
|
||||
self.update(dict([(k, self._base % v) for k,v in self.COLOR_TEMPLATES]))
|
||||
else:
|
||||
self.update(dict([(k, self.NoColor) for k,v in self.COLOR_TEMPLATES]))
|
||||
_c = TermColors()
|
||||
|
||||
# Set a welcome message
|
||||
WELCOME='%s(Tricked out by the python plugin for oh-my-zsh)%s' % (_c['LightBlue'], _c['Normal'])
|
||||
|
||||
|
||||
# Enable a History
|
||||
HISTFILE="%s/custom/.pyhistory.zsh" % ZSH_ROOT
|
||||
# this has a .zsh extension so it will be ignored by git (only files with zsh are in the .gitignore)
|
||||
|
||||
# Read the existing history if there is one
|
||||
if os.path.exists(HISTFILE):
|
||||
readline.read_history_file(HISTFILE)
|
||||
|
||||
# Set maximum number of items that will be written to the history file
|
||||
readline.set_history_length(300)
|
||||
|
||||
def savehist():
|
||||
readline.write_history_file(HISTFILE)
|
||||
|
||||
atexit.register(savehist) # save history at exit
|
||||
|
||||
# Enable Color Prompts
|
||||
sys.ps1 = '%s>>> %s' % (_c['Green'], _c['Normal'])
|
||||
sys.ps2 = '%s... %s' % (_c['Red'], _c['Normal'])
|
||||
|
||||
|
||||
def my_displayhook(value):
|
||||
"""Enable Pretty Printing for stdout:
|
||||
this will hijack the way the python interpreter prints out long variables
|
||||
>>> s = ["this is a very long element of a list", "and this is another one, which makes the list quite long"]
|
||||
>>> s
|
||||
['this is a very long element of a list',
|
||||
'and this is another one, which makes the list quite long']
|
||||
"""
|
||||
if value is not None:
|
||||
try:
|
||||
import __builtin__
|
||||
__builtin__._ = value
|
||||
except ImportError:
|
||||
__builtins__._ = value
|
||||
|
||||
pprint.pprint(value)
|
||||
|
||||
sys.displayhook = my_displayhook
|
||||
|
||||
# TODO: move django functions to a separate plugin.
|
||||
|
||||
# Django Helpers
|
||||
def SECRET_KEY():
|
||||
"Generates a new SECRET_KEY that can be used in a project settings file."
|
||||
|
||||
from random import choice
|
||||
return ''.join(
|
||||
[choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)')
|
||||
for i in range(50)])
|
||||
|
||||
# If we're working with a Django project, set up the environment
|
||||
if 'DJANGO_SETTINGS_MODULE' in os.environ:
|
||||
from django.db.models.loading import get_models
|
||||
from django.test.client import Client
|
||||
from django.test.utils import setup_test_environment, teardown_test_environment
|
||||
from django.conf import settings as S
|
||||
|
||||
class DjangoModels(object):
|
||||
"""Loop through all the models in INSTALLED_APPS and import them."""
|
||||
def __init__(self):
|
||||
for m in get_models():
|
||||
setattr(self, m.__name__, m)
|
||||
|
||||
A = DjangoModels()
|
||||
C = Client()
|
||||
|
||||
WELCOME += """%(Green)s
|
||||
Django environment detected.
|
||||
* Your INSTALLED_APPS models are available as `A`.
|
||||
* Your project settings are available as `S`.
|
||||
* The Django test client is available as `C`.
|
||||
%(Normal)s""" % _c
|
||||
|
||||
setup_test_environment()
|
||||
S.DEBUG_PROPAGATE_EXCEPTIONS = True
|
||||
|
||||
WELCOME += """%(LightPurple)s
|
||||
Warning: the Django test environment has been set up; to restore the
|
||||
normal environment call `teardown_test_environment()`.
|
||||
|
||||
Warning: DEBUG_PROPAGATE_EXCEPTIONS has been set to True.
|
||||
%(Normal)s""" % _c
|
||||
|
||||
# Start an external editor with \e
|
||||
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/438813/
|
||||
|
||||
EDITOR = os.environ.get('EDITOR', failobj='vi') #get the editor, fail to vi
|
||||
EDIT_CMD = '\e'
|
||||
CD_COMMAND = "cd "
|
||||
|
||||
class EditableBufferInteractiveConsole(InteractiveConsole):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.last_buffer = [] # This holds the last executed statement
|
||||
InteractiveConsole.__init__(self, *args, **kwargs)
|
||||
|
||||
def runsource(self, source, *args):
|
||||
self.last_buffer = [ source.encode('latin-1') ]
|
||||
return InteractiveConsole.runsource(self, source, *args)
|
||||
|
||||
def raw_input(self, *args):
|
||||
line = InteractiveConsole.raw_input(self, *args)
|
||||
if line == EDIT_CMD:
|
||||
fd, tmpfl = mkstemp('.py')
|
||||
os.write(fd, b'\n'.join(self.last_buffer))
|
||||
os.close(fd)
|
||||
os.system('%s %s' % (EDITOR, tmpfl))
|
||||
line = open(tmpfl).read()
|
||||
os.unlink(tmpfl)
|
||||
tmpfl = ''
|
||||
lines = line.split( '\n' )
|
||||
for i in range(len(lines) - 1): self.push( lines[i] )
|
||||
line = lines[-1]
|
||||
if line.startswith(CD_COMMAND):
|
||||
return "os.chdir('%s')" % line.split()[1]
|
||||
return line
|
||||
|
||||
c = EditableBufferInteractiveConsole(locals=locals())
|
||||
c.interact(banner=WELCOME)
|
||||
|
||||
# Exit the Python shell on exiting the InteractiveConsole
|
||||
sys.exit()
|
||||
Loading…
Add table
Add a link
Reference in a new issue