You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.8KB

  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from __future__ import print_function
  4. help_text = """
  5. Extracts tags from Elm files. Useful for the Tagbar plugin.
  6. Usage:
  7. Install Tagbar (http://majutsushi.github.io/tagbar/). Then, put this file
  8. anywhere and add the following to your .vimrc:
  9. let g:tagbar_type_elm = {
  10. \ 'ctagstype':'elm'
  11. \ , 'kinds':['h:header', 'i:import', 't:type', 'f:function']
  12. \ , 'sro':'&&&'
  13. \ , 'kind2scope':{'h':'header', 'i:import', 't:type', 'f:function'}
  14. \ , 'sort':0
  15. \ , 'ctagsbin':'/path/to/elmtags.py'
  16. \ }
  17. """
  18. import sys
  19. import re
  20. if len(sys.argv) < 2:
  21. print(help_text)
  22. exit()
  23. filename = sys.argv[1]
  24. re_header = re.compile(r"^-- (.*)$")
  25. re_import = re.compile(r"^import ([^ \n]+)( as ([^ \n]+))?( exposing (\([^)]+\)))?")
  26. re_type = re.compile(r"^type( alias)? ([^ \n]+)( =)?$")
  27. re_function = re.compile(r"^([^ ]+) : (.*)$")
  28. file_content = []
  29. try:
  30. with open(filename, "r") as vim_buffer:
  31. file_content = vim_buffer.readlines()
  32. except:
  33. exit()
  34. cur_head = ""
  35. for lnum, line in enumerate(file_content):
  36. match_header = re_header.match(line)
  37. match_import = re_import.match(line)
  38. match_type = re_type.match(line)
  39. match_function = re_function.match(line)
  40. cur_searchterm = ""
  41. cur_kind = ""
  42. args = ""
  43. lines = ""
  44. if match_header:
  45. cur_head = match_header.group(1)
  46. cur_tag = cur_head
  47. cur_searchterm = "^-- " + cur_tag + "$"
  48. cur_kind = "h"
  49. elif match_import:
  50. cur_tag = match_import.group(1)
  51. cur_searchterm = "^import " + cur_tag
  52. cur_kind = "i"
  53. args = "\theader:" + cur_head
  54. if match_import.group(3):
  55. args = args + "\tsignature:(" + cur_tag + ")"
  56. cur_tag = match_import.group(3)
  57. if match_import.group(5):
  58. exposing = match_import.group(5).strip("()").replace(" ", "").split(",")
  59. for exposed in exposing:
  60. lines = lines + '\n{0}\t{1}\t/{2}/;"\t{3}\tline:{4}{5}'.format(exposed, filename, cur_searchterm, "e", str(lnum+1), "\taccess:public\timport:" + cur_head + "&&&" + cur_tag)
  61. elif match_type:
  62. cur_tag = match_type.group(2)
  63. if match_type.group(1) == " alias":
  64. args = "\taccess:protected"
  65. cur_searchterm = "^type " + cur_tag + "$"
  66. cur_kind = "t"
  67. args = args + "\theader:" + cur_head
  68. elif match_function:
  69. cur_tag = match_function.group(1)
  70. cur_searchterm = "^" + cur_tag + " :"
  71. cur_kind = "f"
  72. args = "\theader:" + cur_head + "\tsignature:(" + match_function.group(2) + ")"
  73. else:
  74. continue
  75. print('{0}\t{1}\t/{2}/;"\t{3}\tline:{4}{5}'.format(
  76. cur_tag, filename, cur_searchterm, cur_kind, str(lnum+1), args) + lines)