# Source code for powerline.segments.shell

    # vim:fileencoding=utf-8:noet
    from __future__ import (unicode_literals, division, absolute_import, print_function)

    from powerline.theme import requires_segment_info
    from powerline.segments import with_docstring
    from powerline.segments.common.env import CwdSegment
    from powerline.lib.unicode import out_u

    @requires_segment_info
    def jobnum(pl, segment_info, show_zero=False):
    	'''Return the number of jobs.

    	:param bool show_zero:
    		If False (default) shows nothing if there are no jobs. Otherwise shows
    		zero for no jobs.
    	'''
    	jobnum = segment_info['args'].jobnum
    	if jobnum is None or (not show_zero and jobnum == 0):
    		return None
    	else:
    		return str(jobnum)

    try:
    	import signal
    	exit_codes = dict((k, v) for v, k in reversed(sorted(signal.__dict__.items())) \
    		if v.startswith('SIG') and not v.startswith('SIG_'))
    except ImportError:
    	exit_codes = dict()

    @requires_segment_info
    def last_status(pl, segment_info, signal_names=True):
    	'''Return last exit code.

    	:param bool signal_names:
    		If True (default), translate signal numbers to human-readable names.

    	Highlight groups used: ``exit_fail``
    	'''
    	if not segment_info['args'].last_exit_code:
    		return None

    	try:
    		if signal_names and segment_info['args'].last_exit_code - 128 in exit_codes:
    			return [{'contents': exit_codes[segment_info['args'].last_exit_code - 128], 'highlight_groups': ['exit_fail']}]
    	except TypeError:
    		pass
    	return [{'contents': str(segment_info['args'].last_exit_code), 'highlight_groups': ['exit_fail']}]

    @requires_segment_info
    def last_pipe_status(pl, segment_info, signal_names=True):
    	'''Return last pipe status.

    	:param bool signal_names:
    		If True (default), translate signal numbers to human-readable names.

    	Highlight groups used: ``exit_fail``, ``exit_success``
    	'''
    	last_pipe_status = (
    		segment_info['args'].last_pipe_status
    		or (segment_info['args'].last_exit_code,)
    	)
    	if any(last_pipe_status):
    		try:
    			return [{
    				'contents': exit_codes[status - 128] if signal_names and \
    					status - 128 in exit_codes else str(status),
    				'highlight_groups': ['exit_fail' if status else 'exit_success'],
    				'draw_inner_divider': True
    			} for status in last_pipe_status]
    		except TypeError:
    			return [{
    				'contents': str(status),
    				'highlight_groups': ['exit_fail' if status else 'exit_success'],
    				'draw_inner_divider': True
    			} for status in last_pipe_status]
    	else:
    		return None

    @requires_segment_info
    def mode(pl, segment_info, override={'vicmd': 'COMMND', 'viins': 'INSERT'}, default=None):
    	'''Return the current mode.

    	:param dict override:
    		dict for overriding mode strings.
    	:param str default:
    		If current mode is equal to this string then this segment will not get
    		displayed. If not specified the value is taken from
    		``$POWERLINE_DEFAULT_MODE`` variable. This variable is set by zsh
    		bindings for any mode that does not start from ``vi``.
    	'''
    	mode = segment_info.get('mode', None)
    	if not mode:
    		pl.debug('No mode specified')
    		return None
    	default = default or segment_info.get('default_mode', None)
    	if mode == default:
    		return None
    	try:
    		return override[mode]
    	except KeyError:
    		# Note: with zsh line editor you can emulate as much modes as you wish.
    		# Thus having unknown mode is not an error: maybe just some developer
    		# added support for his own zle widgets. As there is no built-in mode()
    		# function like in VimL and mode is likely be defined by our code or by
    		# somebody knowing what he is doing there is absolutely no need in
    		# keeping translations dictionary.
    		return mode.upper()

    @requires_segment_info
    def continuation(pl, segment_info, omit_cmdsubst=True, right_align=False, renames={}):
    	'''Display parser state.

    	:param bool omit_cmdsubst:
    		Do not display cmdsubst parser state if it is the last one.
    	:param bool right_align:
    		Align to the right.
    	:param dict renames:
    		Rename states: ``{old_name : new_name}``. If ``new_name`` is ``None``
    		then given state is not displayed.

    	Highlight groups used: ``continuation``, ``continuation:current``.
    	'''
    	if not segment_info.get('parser_state'):
    		return [{
    			'contents': '',
    			'width': 'auto',
    			'highlight_groups': ['continuation:current', 'continuation'],
    		}]
    	ret = []

    	for state in segment_info['parser_state'].split():
    		state = renames.get(state, state)
    		if state:
    			ret.append({
    				'contents': state,
    				'highlight_groups': ['continuation'],
    				'draw_inner_divider': True,
    			})

    	if omit_cmdsubst and ret[-1]['contents'] == 'cmdsubst':
    		ret.pop(-1)

    	if not ret:
    		ret.append({
    			'contents': ''
    		})

    	if right_align:
    		ret[0].update(width='auto', align='r')
    		ret[-1]['highlight_groups'] = ['continuation:current', 'continuation']
    	else:
    		ret[-1].update(width='auto', align='l', highlight_groups=['continuation:current', 'continuation'])

    	return ret

    @requires_segment_info
    class ShellCwdSegment(CwdSegment):
    	def get_shortened_path(self, pl, segment_info, use_shortened_path=True, **kwargs):
    		if use_shortened_path:
    			try:
    				return out_u(segment_info['shortened_path'])
    			except KeyError:
    				pass
    		return super(ShellCwdSegment, self).get_shortened_path(pl, segment_info, **kwargs)

    cwd = with_docstring(ShellCwdSegment(),
    '''Return the current working directory.

    Returns a segment list to create a breadcrumb-like effect.

    :param int dir_shorten_len:
    	shorten parent directory names to this length (e.g.
    	:file:`/long/path/to/powerline` → :file:`/l/p/t/powerline`)
    :param int dir_limit_depth:
    	limit directory depth to this number (e.g.
    	:file:`/long/path/to/powerline` → :file:`⋯/to/powerline`)
    :param bool use_path_separator:
    	Use path separator in place of soft divider.
    :param bool use_shortened_path:
    	Use path from shortened_path ``--renderer-arg`` argument. If this argument
    	is present ``shorten_home`` argument is ignored.
    :param bool shorten_home:
    	Shorten home directory to ``~``.
    :param str ellipsis:
    	Specifies what to use in place of omitted directories. Use None to not
    	show this subsegment at all.

    Divider highlight group used: ``cwd:divider``.

    Highlight groups used: ``cwd:current_folder`` or ``cwd``. It is recommended to define all highlight groups.
    ''')