├── .no-sublime-package ├── Default.sublime-keymap ├── demo_thumbnail.gif ├── README.md ├── package.json └── open_node_module.py /.no-sublime-package: -------------------------------------------------------------------------------- 1 | { 2 | "files_to_ignore": ["demo_thumbnail.gif"] 3 | } -------------------------------------------------------------------------------- /Default.sublime-keymap: -------------------------------------------------------------------------------- 1 | [{ 2 | "keys":["alt+."], 3 | "command": "open_required_file" 4 | }] -------------------------------------------------------------------------------- /demo_thumbnail.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyyd/open_node_module_for_sublime/master/demo_thumbnail.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Open Node Module for Sublime Text 2 | 3 | Static text analysing to help you open node modules in your Sublime text. 4 | 5 | ![alt tag](https://raw.github.com/oyyd/open_node_module_for_sublime/master/demo_thumbnail.gif) 6 | 7 | ##Default keymap 8 | 9 | `alt+.` 10 | 11 | ##TODO: 12 | 13 | * search global modules 14 | 15 | * better ES6 modules syntax support 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jump_to_node_module", 3 | "version": "0.1.0", 4 | "description": "Static text analysing to help you open node modules in your Sublime text. ", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/oyyd/open_node_module_for_sublime.git" 8 | }, 9 | "keywords": [ 10 | "node_modules", 11 | "sublime_text" 12 | ], 13 | "author": "oyyd", 14 | "license": "MIT" 15 | } 16 | -------------------------------------------------------------------------------- /open_node_module.py: -------------------------------------------------------------------------------- 1 | import sublime, sublime_plugin 2 | import re, json 3 | from os import path 4 | 5 | # NOTE: static requiring 6 | path_regs = [ 7 | re.compile('require\([\"\'](.*)[\"\']\)'), 8 | re.compile('import.*[\"\'](.*)[\"\']'), 9 | re.compile('from.*[\"\'](.*)[\"\']'), 10 | ] 11 | 12 | def alert_file_not_found(): 13 | sublime.error_message('File not found.') 14 | 15 | def get_require_text(line_text): 16 | for reg in path_regs: 17 | result = re.search(reg, line_text) 18 | if result != None: 19 | return result.group(1) 20 | return None 21 | 22 | def try_directory_module(possible_dir): 23 | if not path.isdir(possible_dir): 24 | return None 25 | 26 | main_file = 'index' 27 | package_path = path.join(possible_dir, 'package.json') 28 | if path.isfile(package_path): 29 | try: 30 | with open(package_path) as content: 31 | data = json.load(content) 32 | main_file = data['main'] 33 | except: 34 | pass 35 | try_file = path.join(possible_dir, main_file) 36 | return try_ext(try_file) 37 | 38 | trial_exts = ['js', 'json', 'jsx', 'es', 'es6'] 39 | def try_ext(dir_path): 40 | dot_index = None 41 | try: 42 | dot_index = dir_path.rindex('.') 43 | except: 44 | pass 45 | 46 | if dot_index != None: 47 | ext = dir_path[dot_index+1:] 48 | if ext in trial_exts and path.isfile(dir_path): 49 | return dir_path 50 | 51 | for ext in trial_exts: 52 | try_path = dir_path + '.' + ext 53 | if path.isfile(try_path): 54 | return try_path 55 | return None 56 | 57 | def walk_node_modules(current_file_name, require_text): 58 | current_dir = current_file_name[:current_file_name.rindex('/')] 59 | while current_dir != '': 60 | possible_dir = path.join(current_dir, 'node_modules', require_text) 61 | possible_file = try_directory_module(possible_dir) 62 | if possible_file: 63 | return possible_file 64 | current_dir = current_dir[:current_dir.rindex('/')] 65 | 66 | # try global module 67 | return None 68 | 69 | def get_file_path(current_file_name, require_text): 70 | if require_text[0] == '.': 71 | file_path = path.realpath(path.join(current_file_name, '../', require_text)) 72 | elif require_text[0] == '/': 73 | file_path = path.realpath(require_text) 74 | 75 | result = try_ext(file_path) 76 | if result == None: 77 | result = try_directory_module(file_path) 78 | return result 79 | 80 | class OpenRequiredFileCommand(sublime_plugin.TextCommand): 81 | def run(self, edit): 82 | window = sublime.active_window() 83 | view = window.active_view() 84 | current_file_name = view.file_name() 85 | 86 | line = view.line(view.sel()[0]) 87 | line_text = view.substr(line) 88 | require_text = get_require_text(line_text) 89 | print(require_text) 90 | if require_text == None: 91 | return 92 | 93 | file_path = None 94 | if require_text[0] == '.' or require_text[0] == '/': 95 | # relative path or absolute path 96 | file_path = get_file_path(current_file_name, require_text) 97 | else: 98 | # core module or node_modules 99 | file_path = walk_node_modules(current_file_name, require_text) 100 | 101 | if file_path: 102 | window.open_file(file_path) 103 | else: 104 | alert_file_not_found() 105 | --------------------------------------------------------------------------------