mirror of
				https://github.com/amix/vimrc
				synced 2025-10-26 09:33:36 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			294 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			294 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| priority -50
 | |
| 
 | |
| ###########################################################################
 | |
| #							   General Stuff							  #
 | |
| ###########################################################################
 | |
| global !p
 | |
| import vim
 | |
| from os import path as ospath
 | |
| from string import Template
 | |
| import re
 | |
| from collections import Counter
 | |
| 
 | |
| from vimsnippets import complete
 | |
| 
 | |
| #http://docutils.sourceforge.net/docs/ref/rst/roles.html
 | |
| TEXT_ROLES = ['emphasis','literal','code','math',
 | |
| 			  'pep-reference','rfc-reference',
 | |
| 			  'strong','subscript','superscript',
 | |
| 			  'title-reference','raw']
 | |
| TEXT_ROLES_REGEX = r'\.\.\srole::?\s(w+)'
 | |
| 
 | |
| #http://docutils.sourceforge.net/docs/ref/rst/directives.html#specific-admonitions
 | |
| SPECIFIC_ADMONITIONS = ["attention", "caution", "danger",
 | |
| 						"error", "hint", "important", "note",
 | |
| 						"tip", "warning"]
 | |
| #http://docutils.sourceforge.net/docs/ref/rst/directives.html
 | |
| DIRECTIVES = ['topic','sidebar','math','epigraph',
 | |
| 			  'parsed-literal','code','highlights',
 | |
| 			  'pull-quote','compound','container',
 | |
| 			  'list-table','class','sectnum',
 | |
| 			  'role','default-role','unicode',
 | |
| 			  'raw']
 | |
| 
 | |
| NONE_CONTENT_DIRECTIVES = ['rubric', 'contents', 'header',
 | |
| 						   'footer', 'date', 'include', 'title']
 | |
| 
 | |
| INCLUDABLE_DIRECTIVES = ['image', 'figure', 'include']
 | |
| # CJK chars
 | |
| # http://stackoverflow.com/questions/2718196/find-all-chinese-text-in-a-string-using-python-and-regex
 | |
| CJK_RE = re.compile(u'[⺀-⺙⺛-⻳⼀-⿕々〇〡-〩〸-〺〻㐀-䶵一-鿃豈-鶴侮-頻並-龎]', re.UNICODE)
 | |
| 
 | |
| 
 | |
| def has_cjk(s):
 | |
| 	"""Detect if s contains CJK characters."""
 | |
| 	return CJK_RE.search(s) is not None
 | |
| 
 | |
| def real_filename(filename):
 | |
| 	"""pealeextension name off if possible
 | |
| 	# i.e. "foo.bar.png will return "foo.bar"
 | |
| 	"""
 | |
| 	return ospath.splitext(filename)[0]
 | |
| 
 | |
| def check_file_exist(rst_path, relative_path):
 | |
| 	"""
 | |
| 	For RST file, it can just include files as relative path.
 | |
| 
 | |
| 	:param rst_path: absolute path to rst file
 | |
| 	:param relative_path: path related to rst file
 | |
| 	:return: relative file's absolute path if file exist
 | |
| 	"""
 | |
| 	abs_path = ospath.join(ospath.dirname(rst_path), relative_path)
 | |
| 	if ospath.isfile(abs_path):
 | |
| 		return abs_path
 | |
| 
 | |
| 
 | |
| try:
 | |
| 	rst_char_len = vim.strwidth  # Requires Vim 7.3+
 | |
| except AttributeError:
 | |
| 	from unicodedata import east_asian_width
 | |
| 	def rst_char_len(s):
 | |
| 		"""Return the required over-/underline length for s."""
 | |
| 		result = 0
 | |
| 		for c in s:
 | |
| 			result += 2 if east_asian_width(c) in ('W', 'F') else 1
 | |
| 		return result
 | |
| 
 | |
| 
 | |
| def	make_items(times, leading='+'):
 | |
| 	"""
 | |
| 	make lines with leading char multitimes
 | |
| 
 | |
| 	:param: times, how many times you need
 | |
| 	:param: leading, leading character
 | |
| 	"""
 | |
| 	times = int(times)
 | |
| 	if leading == 1:
 | |
| 		msg = ""
 | |
| 		for x in range(1, times+1):
 | |
| 			msg += "%s. Item\n" % x
 | |
| 		return msg
 | |
| 	else:
 | |
| 		return ("%s Item\n" % leading) * times
 | |
| 
 | |
| 
 | |
| def look_up_directives(regex, fpath):
 | |
| 	"""
 | |
| 	find all directive args in given file
 | |
| 	:param: regex, the regex that needs to match
 | |
| 	:param: path, to path to rst file
 | |
| 
 | |
| 	:return: list, empty list if nothing match
 | |
| 	"""
 | |
| 	try:
 | |
| 		with open(fpath) as source:
 | |
| 			match = re.findall(regex, source.read())
 | |
| 	except IOError:
 | |
| 		match = []
 | |
| 	return match
 | |
| 
 | |
| 
 | |
| def get_popular_code_type():
 | |
| 	"""
 | |
| 	find most popular code type in the given rst
 | |
| 
 | |
| 	:param path: file to detect
 | |
| 
 | |
| 	:return: string, most popular code type in file
 | |
| 	"""
 | |
| 	buf = "".join(vim.current.buffer)
 | |
| 	types = re.findall(r'[:|\.\.\s]code::?\s(\w+)', buf)
 | |
| 	try:
 | |
| 		popular_type = Counter(types).most_common()[0][0]
 | |
| 	except IndexError:
 | |
| 		popular_type = "lua" # Don't break default
 | |
| 	return popular_type
 | |
| endglobal
 | |
| 
 | |
| snippet part "Part" b
 | |
| `!p snip.rv = rst_char_len(t[1])*'#'`
 | |
| ${1:${VISUAL:Part name}}
 | |
| `!p snip.rv = rst_char_len(t[1])*'#'`
 | |
| 
 | |
| $0
 | |
| endsnippet
 | |
| 
 | |
| snippet chap "Chapter" b
 | |
| `!p snip.rv = rst_char_len(t[1])*'*'`
 | |
| ${1:${VISUAL:Chapter name}}
 | |
| `!p snip.rv = rst_char_len(t[1])*'*'`
 | |
| 
 | |
| $0
 | |
| endsnippet
 | |
| 
 | |
| snippet sec "Section" b
 | |
| ${1:${VISUAL:Section name}}
 | |
| `!p snip.rv = rst_char_len(t[1])*'='`
 | |
| 
 | |
| $0
 | |
| endsnippet
 | |
| 
 | |
| snippet ssec "Subsection" b
 | |
| ${1:${VISUAL:Subsection name}}
 | |
| `!p snip.rv = rst_char_len(t[1])*'-'`
 | |
| 
 | |
| $0
 | |
| endsnippet
 | |
| 
 | |
| snippet sssec "Subsubsection" b
 | |
| ${1:${VISUAL:Subsubsection name}}
 | |
| `!p snip.rv = rst_char_len(t[1])*'^'`
 | |
| 
 | |
| $0
 | |
| endsnippet
 | |
| 
 | |
| snippet para "Paragraph" b
 | |
| ${1:${VISUAL:Paragraph name}}
 | |
| `!p snip.rv = rst_char_len(t[1])*'"'`
 | |
| 
 | |
| $0
 | |
| endsnippet
 | |
| 
 | |
| snippet em "Emphasize string" i
 | |
| `!p
 | |
| # dirty but works with CJK character detection
 | |
| if has_cjk(vim.current.line):
 | |
| 	snip.rv ="\ "`*${1:${VISUAL:Em}}*`!p
 | |
| if has_cjk(vim.current.line):
 | |
| 	snip.rv ="\ "
 | |
| else:
 | |
| 	snip.rv = " "
 | |
| `$0
 | |
| endsnippet
 | |
| 
 | |
| snippet st "Strong string" i
 | |
| `!p
 | |
| if has_cjk(vim.current.line):
 | |
| 	snip.rv ="\ "`**${1:${VISUAL:Strong}}**`!p
 | |
| if has_cjk(vim.current.line):
 | |
| 	snip.rv ="\ "
 | |
| else:
 | |
| 	snip.rv = " "
 | |
| `$0
 | |
| endsnippet
 | |
| 
 | |
| snippet "li(st)? (?P<num>\d+)" "List" br
 | |
| $0
 | |
| `!p
 | |
| # usage: li 4<tab>
 | |
| # which will extand into a unordered list contains 4 items
 | |
| snip.rv = make_items(match.groupdict()['num'])
 | |
| `
 | |
| endsnippet
 | |
| 
 | |
| snippet "ol(st)? (?P<num>\d+)" "Order List" br
 | |
| $0
 | |
| `!p
 | |
| # usage: ol 4<tab>
 | |
| # which will extand into a ordered list contains 4 items
 | |
| snip.rv = make_items(match.groupdict()['num'], 1)
 | |
| `
 | |
| endsnippet
 | |
| ###########################################################################
 | |
| #						  More Specialized Stuff.						  #
 | |
| ###########################################################################
 | |
| snippet cb "Code Block" b
 | |
| .. code-block:: ${1:`!p snip.rv = get_popular_code_type()`}
 | |
| 
 | |
| 	${2:${VISUAL:code}}
 | |
| 
 | |
| $0
 | |
| endsnippet
 | |
| 
 | |
| # match snippets :
 | |
| # img, inc, fig
 | |
| snippet id "Includable Directives" b
 | |
| `!p
 | |
| real_name=real_filename(ospath.basename(t[2]))
 | |
| di=t[1][:2]
 | |
| 
 | |
| link=""
 | |
| content=""
 | |
| 
 | |
| if di == 'im':
 | |
| 	link = "|{0}|".format(real_name)
 | |
| 
 | |
| if di == 'fi':
 | |
| 	content="""
 | |
| 	:alt: {0}
 | |
| 	{0}""".format(real_name)
 | |
| `
 | |
| ..`!p snip.rv = " %s" % link if link else ""` $1`!p
 | |
| snip.rv=complete(t[1], INCLUDABLE_DIRECTIVES)
 | |
| `:: ${2:${VISUAL:file}}`!p
 | |
| if content:
 | |
| 	snip.rv +="    "+content`
 | |
| `!p
 | |
| # Tip of whether file is exist in comment type
 | |
| if not check_file_exist(path, t[2]):
 | |
| 	snip.rv='.. FILE {0} does not exist'.format(t[2])
 | |
| else:
 | |
| 	snip.rv=""
 | |
| `$0
 | |
| endsnippet
 | |
| 
 | |
| snippet di "Directives" b
 | |
| .. $1`!p snip.rv=complete(t[1], DIRECTIVES)`:: $2
 | |
| 
 | |
| 	${3:${VISUAL:Content}}
 | |
| $0
 | |
| endsnippet
 | |
| 
 | |
| snippet nd "None Content Directives" b
 | |
| .. $1`!p snip.rv=complete(t[1], NONE_CONTENT_DIRECTIVES)`:: $2
 | |
| $0
 | |
| endsnippet
 | |
| 
 | |
| snippet sa "Specific Admonitions" b
 | |
| .. $1`!p snip.rv =complete(t[1], SPECIFIC_ADMONITIONS)`::
 | |
| 
 | |
| 	${2:${VISUAL:Content}}
 | |
| 
 | |
| $0
 | |
| endsnippet
 | |
| 
 | |
| #it will be trigger at start of line or after a word
 | |
| snippet ro "Text Roles" w
 | |
| \ :$1`!p snip.rv=complete(t[1],
 | |
| 						  TEXT_ROLES+look_up_directives(TEXT_ROLES_REGEX,
 | |
| 														path))`:\`$2\`\
 | |
| endsnippet
 | |
| 
 | |
| ############
 | |
| #  Sphinx  #
 | |
| ############
 | |
| 
 | |
| snippet sid "SideBar" b
 | |
| .. sidebar:: ${1:SideBar Title}
 | |
| 
 | |
| 	${2:${VISUAL:SideBar Content}}
 | |
| endsnippet
 | |
| # vim:ft=snippets:
 | 
