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

from powerline.theme import requires_segment_info
from powerline.bindings.vim import (current_tabpage, list_tabpages)

try:
	import vim
except ImportError:
	vim = {}


def tabpage_updated_segment_info(segment_info, tabpage):
	segment_info = segment_info.copy()
	window = tabpage.window
	buffer = window.buffer
	segment_info.update(
		tabpage=tabpage,
		tabnr=tabpage.number,
		window=window,
		winnr=window.number,
		window_id=int(window.vars.get('powerline_window_id', -1)),
		buffer=buffer,
		bufnr=buffer.number,
	)
	return segment_info


@requires_segment_info
def tablister(pl, segment_info, **kwargs):
	'''List all tab pages in segment_info format

	Specifically generates a list of segment info dictionaries with ``window``, 
	``winnr``, ``window_id``, ``buffer`` and ``bufnr`` keys set to tab-local 
	ones and additional ``tabpage`` and ``tabnr`` keys.

	Adds either ``tab:`` or ``tab_nc:`` prefix to all segment highlight groups.

	Works best with vim-7.4 or later: earlier versions miss tabpage object and 
	thus window objects are not available as well.
	'''
	cur_tabpage = current_tabpage()
	cur_tabnr = cur_tabpage.number

	def add_multiplier(tabpage, dct):
		dct['priority_multiplier'] = 1 + (0.001 * abs(tabpage.number - cur_tabnr))
		return dct

	return (
		(lambda tabpage, prefix: (
			tabpage_updated_segment_info(segment_info, tabpage),
			add_multiplier(tabpage, {
				'highlight_group_prefix': prefix,
				'divider_highlight_group': 'tab:divider'
			})
		))(tabpage, 'tab' if tabpage == cur_tabpage else 'tab_nc')
		for tabpage in list_tabpages()
	)


def buffer_updated_segment_info(segment_info, buffer):
	segment_info = segment_info.copy()
	segment_info.update(
		window=None,
		winnr=None,
		window_id=None,
		buffer=buffer,
		bufnr=buffer.number,
	)
	return segment_info


@requires_segment_info
def bufferlister(pl, segment_info, show_unlisted=False, **kwargs):
	'''List all buffers in segment_info format

	Specifically generates a list of segment info dictionaries with ``buffer`` 
	and ``bufnr`` keys set to buffer-specific ones, ``window``, ``winnr`` and 
	``window_id`` keys set to None.

	Adds one of ``buf:``, ``buf_nc:``, ``buf_mod:``, or ``buf_nc_mod`` 
	prefix to all segment highlight groups.

	:param bool show_unlisted:
		True if unlisted buffers should be shown as well. Current buffer is 
		always shown.
	'''
	cur_buffer = vim.current.buffer
	cur_bufnr = cur_buffer.number

	def add_multiplier(buffer, dct):
		dct['priority_multiplier'] = 1 + (0.001 * abs(buffer.number - cur_bufnr))
		return dct

	return (
		(lambda buffer, current, modified: (
			buffer_updated_segment_info(segment_info, buffer),
			add_multiplier(buffer, {
				'highlight_group_prefix': '%s%s' % (current, modified),
				'divider_highlight_group': 'tab:divider'
			})
		))(
			buffer,
			'buf' if buffer is cur_buffer else 'buf_nc',
			'_mod' if int(vim.eval('getbufvar(%s, \'&modified\')' % buffer.number)) > 0 else ''
		)
		for buffer in vim.buffers if (
		    buffer is cur_buffer
		    or show_unlisted
		    or int(vim.eval('buflisted(%s)' % buffer.number)) > 0
		)
	)

@@ -2817,16 +2817,22 @@
 ': '
-%25s%25s' %25 
+%7B0%7D%7B1%7D'.format
 (cur
@@ -3001,18 +3001,19 @@
 tbufvar(
-%25s
+%7B0%7D
 , %5C'&mod
@@ -3021,19 +3021,24 @@
 fied%5C')'
- %25 
+.format(
 buffer.n
@@ -3040,24 +3040,25 @@
 fer.number))
+)
  %3E 0 else ''
@@ -3145,16 +3145,610 @@
 nlisted%0A
+%09%09    # We can't use vim_getbufoption(segment_info, 'buflisted')%0A%09%09    # here for performance reasons. Querying the buffer options%0A%09%09    # through the vim python module's option attribute caused%0A%09%09    # vim to think it needed to update the tabline for every%0A%09%09    # keystroke after any event that changed the buffer's%0A%09%09    # options.%0A%09%09    #%0A%09%09    # Using the vim module's eval method to directly use the%0A%09%09    # buflisted(nr) vim method instead does not cause vim to%0A%09%09    # update the tabline after every keystroke, but rather after%0A%09%09    # events that would change that status. Fixes #1281%0A
 %09%09    or

use str.format() instead of % operator; add comment to explain the usage of vim.eval('buflisted..')