├── AUTHORS.md ├── CHANGELOG.md ├── Default (Linux).sublime-keymap ├── Default (Linux).sublime-mousemap ├── Default (OSX).sublime-keymap ├── Default (OSX).sublime-mousemap ├── Default (Windows).sublime-keymap ├── Default (Windows).sublime-mousemap ├── Default (copy).sublime-settings ├── Default.sublime-commands ├── Default.sublime-settings ├── GoGuruResults.tmLanguage ├── LICENSE.md ├── Main.sublime-menu ├── README.md ├── dep └── shellenv │ ├── __init__.py │ ├── __init__.pyc │ ├── _encoding.py │ ├── _encoding.pyc │ ├── _linux │ ├── __init__.py │ ├── __init__.pyc │ ├── getent.py │ └── getent.pyc │ ├── _osx │ ├── __init__.py │ ├── core_foundation.py │ └── open_directory.py │ ├── _posix.py │ ├── _posix.pyc │ ├── _types.py │ ├── _types.pyc │ └── _win.py ├── goGuru.py ├── messages.json └── messages ├── 0.1.12.txt └── install.txt /AUTHORS.md: -------------------------------------------------------------------------------- 1 | This is the official list of GoSublime authors for copyright purposes. 2 | 3 | * Jesse "waigani" Meek https://github.com/waigani 4 | * Jordan "Liggitt" https://github.com/liggitt 5 | * David Eads https://github.com/deads2k -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | GoGuru Changes 2 | ---------------- 3 | 4 | ## 0.1.0 5 | * ... 6 | 7 | ## 0.1.1 8 | * "first usable version" 9 | * new feature: 'definition' jumps straight to the definition 10 | * new feature: integrated official golangconfig dependency 11 | * fixed: flag provided but not defined: -format 12 | * fixed: shellenv missing 13 | 14 | ## 0.1.2 15 | * typos 16 | * fixed: guru commands updated to match latest version of guru (Chris Hines ) 17 | * fixed: GOPATH and local_package calculations on Windows (Chris Hines ) 18 | 19 | ## 0.1.3 20 | * fixed: Navigating to results file in windows (Chris Hines ) 21 | 22 | ## 0.1.4 23 | * fixed: shellenv missing - through packagecontrol.io #12 24 | * fixed: use relative instead absolute import path for dependencies. #11 25 | 26 | ## 0.1.5 27 | * fixed: User.sublime-settings is not editable 28 | 29 | ## 0.1.6 30 | * improvement: automatically creates the user settings file 31 | 32 | ## 0.1.7 33 | * fixed: user settings link in sublime commands -------------------------------------------------------------------------------- /Default (Linux).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+shift+g"], "command": "go_guru"}, 3 | { "keys": ["ctrl+alt+shift+g"], "command": "go_guru_show_results"}, 4 | { "keys": ["ctrl+.", "ctrl+g"], "command": "go_guru_goto_definition", "context": [{ "key": "selector", "operator": "equal", "operand": "source.go" }] }, 5 | /* 6 | You can also set a key binding for a specific mode by adding a "mode" arg, e.g.: 7 | ... 8 | { "keys": ["ctrl+super+c"], "command": "go_guru", "args": {"mode": "callers"} }, 9 | { "keys": ["ctrl+super+i"], "command": "go_guru", "args": {"mode": "implements"} }, 10 | { "keys": ["ctrl+super+r"], "command": "go_guru", "args": {"mode": "referrers"} }, 11 | { "keys": ["ctrl+.+ctrl+g"], "command": "go_guru", "args": {"mode": "definition", "output": false}}, 12 | ... 13 | Please set this in your user keybindings, not here. 14 | */ 15 | ] -------------------------------------------------------------------------------- /Default (Linux).sublime-mousemap: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "button": "button2", 4 | "modifiers": ["ctrl"], 5 | "press_command": "drag_select", 6 | "command": "go_guru", 7 | "args": { 8 | "mode": "definition", 9 | "output": false 10 | }, 11 | }, 12 | ] 13 | -------------------------------------------------------------------------------- /Default (OSX).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+shift+g"], "command": "go_guru"}, 3 | { "keys": ["ctrl+alt+shift+g"], "command": "go_guru_show_results"}, 4 | { "keys": ["ctrl+.", "ctrl+g"], "command": "go_guru_goto_definition", "context": [{ "key": "selector", "operator": "equal", "operand": "source.go" }] }, 5 | /* 6 | You can also set a key binding for a specific mode by adding a "mode" arg, e.g.: 7 | ... 8 | { "keys": ["ctrl+super+c"], "command": "go_guru", "args": {"mode": "callers"} }, 9 | { "keys": ["ctrl+super+i"], "command": "go_guru", "args": {"mode": "implements"} }, 10 | { "keys": ["ctrl+super+r"], "command": "go_guru", "args": {"mode": "referrers"} }, 11 | { "keys": ["ctrl+.+ctrl+g"], "command": "go_guru", "args": {"mode": "definition", "output": false}}, 12 | ... 13 | Please set this in your user keybindings, not here. 14 | */ 15 | ] -------------------------------------------------------------------------------- /Default (OSX).sublime-mousemap: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "button": "button2", 4 | "modifiers": ["ctrl"], 5 | "press_command": "drag_select", 6 | "command": "go_guru", 7 | "args": { 8 | "mode": "definition", 9 | "output": false 10 | }, 11 | }, 12 | ] 13 | -------------------------------------------------------------------------------- /Default (Windows).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+shift+g"], "command": "go_guru"}, 3 | { "keys": ["ctrl+alt+shift+g"], "command": "go_guru_show_results"}, 4 | { "keys": ["ctrl+.", "ctrl+g"], "command": "go_guru_goto_definition", "context": [{ "key": "selector", "operator": "equal", "operand": "source.go" }] }, 5 | /* 6 | You can also set a key binding for a specific mode by adding a "mode" arg, e.g.: 7 | ... 8 | { "keys": ["ctrl+super+c"], "command": "go_guru", "args": {"mode": "callers"} }, 9 | { "keys": ["ctrl+super+i"], "command": "go_guru", "args": {"mode": "implements"} }, 10 | { "keys": ["ctrl+super+r"], "command": "go_guru", "args": {"mode": "referrers"} }, 11 | { "keys": ["ctrl+.+ctrl+g"], "command": "go_guru", "args": {"mode": "definition", "output": false}}, 12 | ... 13 | Please set this in your user keybindings, not here. 14 | */ 15 | ] -------------------------------------------------------------------------------- /Default (Windows).sublime-mousemap: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "button": "button2", 4 | "modifiers": ["ctrl"], 5 | "press_command": "drag_select", 6 | "command": "go_guru", 7 | "args": { 8 | "mode": "definition", 9 | "output": false 10 | }, 11 | }, 12 | ] 13 | -------------------------------------------------------------------------------- /Default (copy).sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | // Please do not edit this file, instead use: User.sublime-settings 3 | // located at the same directory. 4 | 5 | // use golangconfig, if false then shellenv will be used to get golang environment variables 6 | "use_golangconfig": false, 7 | 8 | // use_current_package adds to the guru_scope the current package of the the working file 9 | "use_current_package" : true, 10 | 11 | // besides showing the result, jump directly to the definition 12 | "jumpto_definition": false, 13 | 14 | // The output can either be one of: 'buffer', 'output_panel' 15 | // Buffers can hold results from more than one invocation 16 | // Output panels sit underneath the editor area and are easily dismissed 17 | "output": "output_panel", 18 | 19 | // print debug info to the terminal 20 | "debug": false, 21 | 22 | // Set guru's output to json 23 | "guru_json": false, 24 | 25 | // guru_scope is an array of scopes of analysis for guru. 26 | // e.g (for github.com/juju/juju) "guru_scope": ["github.com/juju/juju/cmd/juju", "github.com/juju/juju/cmd/jujud"] 27 | // not used when use_golangconfig is set to true 28 | 29 | "guru_scope": [], 30 | 31 | // an array of build tags of analyzed source files 32 | "guru_tags": [], 33 | 34 | // env overwrites the default shell environment vars 35 | // e.g "env": { "GOPATH": "$HOME/go" } 36 | // not used when use_golangconfig is set to true 37 | "env": {}, 38 | } 39 | -------------------------------------------------------------------------------- /Default.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "GoGuru", 4 | "command": "go_guru" 5 | }, 6 | { 7 | "caption": "GoGuru: Show Results", 8 | "command": "go_guru_show_results" 9 | }, 10 | { 11 | "caption": "GoGuru: User Settings", 12 | "command": "open_file", 13 | "args": { 14 | "file": "${packages}/User/GoGuru.sublime-settings" 15 | } 16 | }, 17 | { 18 | "caption": "GoGuru: callees", 19 | "command": "go_guru", 20 | "args": { 21 | "mode": "callees" 22 | } 23 | }, 24 | { 25 | "caption": "GoGuru: callers", 26 | "command": "go_guru", 27 | "args": { 28 | "mode": "callers" 29 | } 30 | }, 31 | { 32 | "caption": "GoGuru: callstack", 33 | "command": "go_guru", 34 | "args": { 35 | "mode": "callstack" 36 | } 37 | }, 38 | { 39 | "caption": "GoGuru: definition", 40 | "command": "go_guru", 41 | "args": { 42 | "mode": "definition" 43 | } 44 | }, 45 | { 46 | "caption": "GoGuru: jump to definition", 47 | "command": "go_guru", 48 | "args": { 49 | "output": false, 50 | "mode": "definition" 51 | } 52 | }, 53 | { 54 | "caption": "GoGuru: describe", 55 | "command": "go_guru", 56 | "args": { 57 | "mode": "describe" 58 | } 59 | }, 60 | { 61 | "caption": "GoGuru: freevars", 62 | "command": "go_guru", 63 | "args": { 64 | "mode": "freevars" 65 | } 66 | }, 67 | { 68 | "caption": "GoGuru: implements", 69 | "command": "go_guru", 70 | "args": { 71 | "mode": "implements" 72 | } 73 | }, 74 | { 75 | "caption": "GoGuru: peers", 76 | "command": "go_guru", 77 | "args": { 78 | "mode": "peers" 79 | } 80 | }, 81 | { 82 | "caption": "GoGuru: pointsto", 83 | "command": "go_guru", 84 | "args": { 85 | "mode": "pointsto" 86 | } 87 | }, 88 | { 89 | "caption": "GoGuru: whicherrs", 90 | "command": "go_guru", 91 | "args": { 92 | "mode": "whicherrs" 93 | } 94 | }, 95 | { 96 | "caption": "GoGuru: referrers", 97 | "command": "go_guru", 98 | "args": { 99 | "mode": "referrers" 100 | } 101 | }, 102 | { 103 | "caption": "GoGuru: what", 104 | "command": "go_guru", 105 | "args": { 106 | "mode": "what" 107 | } 108 | }, 109 | { 110 | "caption": "GoGuru: Default Settings", 111 | "command": "open_file", 112 | "args": { 113 | "file": "${packages}/GoGuru/Default.sublime-settings" 114 | } 115 | }, 116 | { 117 | "caption": "GoGuru: Default Key Bindings", 118 | "command": "open_file", 119 | "args": { 120 | "file": "${packages}/GoGuru/Default (Linux).sublime-keymap", 121 | "platform": "Linux" 122 | } 123 | }, 124 | { 125 | "caption": "GoGuru: Default Key Bindings", 126 | "command": "open_file", 127 | "args": { 128 | "file": "${packages}/GoGuru/Default (Windows).sublime-keymap", 129 | "platform": "Windows" 130 | } 131 | }, 132 | { 133 | "caption": "GoGuru: Default Key Bindings", 134 | "command": "open_file", 135 | "args": { 136 | "file": "${packages}/GoGuru/Default (OSX).sublime-keymap", 137 | "platform": "OSX" 138 | } 139 | }, 140 | 141 | ] 142 | -------------------------------------------------------------------------------- /Default.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "goguru_version" : "0.1.22", // DO NOT MODIFY 3 | // Please do not edit this file, instead use the user config. 4 | 5 | // use golangconfig, if false then shellenv will be used to get golang environment variables 6 | "goguru_use_golangconfig": false, 7 | 8 | // adds to the guru_scope the current package of the the working file 9 | "goguru_use_current_package" : true, 10 | 11 | // besides showing the result, jump directly to the definition 12 | "goguru_jumpto_definition": false, 13 | 14 | // The output can either be one of: 'buffer', 'output_panel' 15 | // Buffers can hold results from more than one invocation 16 | // Output panels sit underneath the editor area and are easily dismissed 17 | "goguru_output": "output_panel", 18 | 19 | // print debug info to the terminal 20 | "goguru_debug": false, 21 | 22 | // Set guru's output to json 23 | "goguru_json": false, 24 | 25 | // an array of scopes of analysis for guru. 26 | // e.g (for github.com/juju/juju) "guru_scope": ["github.com/juju/juju/cmd/juju", "github.com/juju/juju/cmd/jujud"] 27 | "goguru_scope": [], 28 | 29 | // an array of build tags of analyzed source files 30 | "goguru_tags": [], 31 | 32 | // env overwrites the default shell environment vars 33 | // e.g "env": { "GOPATH": "$HOME/go/bin:$PATH" } 34 | // not used when goguru_use_golangconfig is set to true 35 | "goguru_env": {} 36 | } 37 | -------------------------------------------------------------------------------- /GoGuruResults.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | GoGuru Results 7 | 8 | patterns 9 | 10 | 11 | 12 | match 13 | "([^"]*:[0-9]+:[0-9]+)" 14 | captures 15 | 16 | 1 17 | 18 | name 19 | entity.name.filename.find-in-files 20 | 21 | 22 | 23 | 24 | 25 | match 26 | ^(.+\.go:[0-9]+.[0-9]+)[-:] 27 | captures 28 | 29 | 1 30 | 31 | name 32 | entity.name.filename.find-in-files 33 | 34 | 35 | 36 | 37 | 38 | 39 | match 40 | \>([^"]*:[0-9]+:[0-9]+)< 41 | captures 42 | 43 | 1 44 | 45 | name 46 | entity.name.filename.find-in-files 47 | 48 | 49 | 50 | 51 | 52 | scopeName 53 | text.goguru-results 54 | 55 | 56 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 The GoOracle Authors 2 | 3 | Permission is herby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Preferences", 4 | "id": "preferences", 5 | "children": 6 | [ 7 | { 8 | "caption": "Package Settings", 9 | "id": "package-settings", 10 | "children": 11 | [ 12 | { 13 | "caption": "GoGuru", 14 | "children": 15 | [ 16 | { 17 | "caption": "Settings – Default", 18 | "command": "open_file", 19 | "args": { 20 | "file": "${packages}/GoGuru/Default.sublime-settings" 21 | } 22 | }, 23 | { 24 | "caption": "Settings – User", 25 | "command": "open_file", 26 | "args": { 27 | "file": "${packages}/User/GoGuru.sublime-settings" 28 | } 29 | }, 30 | { "caption": "-" }, 31 | { 32 | "caption": "Key Bindings – Default", 33 | "platform": "Linux", 34 | "command": "open_file", 35 | "args": { 36 | "file": "${packages}/GoGuru/Default (Linux).sublime-keymap" 37 | } 38 | }, 39 | { 40 | "caption": "Key Bindings – Default", 41 | "platform": "Windows", 42 | "command": "open_file", 43 | "args": { 44 | "file": "${packages}/GoGuru/Default (Windows).sublime-keymap" 45 | } 46 | }, 47 | { 48 | "caption": "Key Bindings – Default", 49 | "platform": "OSX", 50 | "command": "open_file", 51 | "args": { 52 | "file": "${packages}/GoGuru/Default (OSX).sublime-keymap" 53 | } 54 | }, 55 | { "caption": "-" }, 56 | { 57 | "caption": "Changes & Announcements", 58 | "command": "open_file", 59 | "args": { 60 | "file": "${packages}/GoGuru/CHANGELOG.md" 61 | } 62 | }, 63 | { "caption": "-" }, 64 | { 65 | "caption": "Read Me", 66 | "command": "open_file", 67 | "args": { 68 | "file": "${packages}/GoGuru/README.md" 69 | } 70 | }, 71 | { 72 | "caption": "Authors & Contributors", 73 | "command": "open_file", 74 | "args": { 75 | "file": "${packages}/GoGuru/AUTHORS.md" 76 | } 77 | }, 78 | { 79 | "caption": "License (MIT)", 80 | "command": "open_file", 81 | "args": { 82 | "file": "${packages}/GoGuru/LICENSE.md" 83 | } 84 | } 85 | ] 86 | } 87 | ] 88 | } 89 | ] 90 | } 91 | ] 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![donate](https://img.shields.io/badge/donate-a%20bus%20ticket%2C%20cup%20of%20coffe%2C%20anything%20you%20can%2C%20thanks!-orange.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=alvarofleivam%40gmail%2ecom&lc=AL&item_name=Donation%20%5b%20for%20a%20bus%20ticket%2c%20coffe%20anything%20you%20can%20I%27m%20happy%20thanks%20%21%20%3a%29%20%5d&item_number=donation&button_subtype=services¤cy_code=USD&bn=PP%2dBuyNowBF%3abtn_buynowCC_LG%2egif%3aNonHosted) 2 | GoGuru [![documentation](https://img.shields.io/badge/info-documentation-blue.svg)](http://alvarolm.github.io/GoGuru/) 3 | ========= 4 | 5 | GoGuru is a Golang plugin for [SublimeText](http://www.sublimetext.com/) 3 that integrates the Go [guru](https://godoc.org/golang.org/x/tools/cmd/guru) tool. 6 | 7 | Please report any issues or improvements here [https://github.com/alvarolm/GoGuru/issues](https://github.com/alvarolm/GoGuru/issues) 8 | 9 | based on previous work from [waigani](http://github.com/waigani/GoOracle). 10 | 11 | the guru tool still is on development, 12 | check out the plan, the official git repo and the code review if you want to keep up: 13 | * https://docs.google.com/document/d/1UErU12vR7jTedYvKHVNRzGPmXqdMASZ6PfE7B-p6sIg/edit# 14 | * https://go.googlesource.com/tools/+log/master/cmd/guru 15 | * https://go-review.googlesource.com/#/q/guru 16 | 17 | 18 | Usage 19 | ----- 20 | 21 | Select, or place your cursor over, a symbol (function, variable, constant etc) and press `ctrl+shift+g`. You will be presented with the following modes of analysis to choose from: 22 | 23 | ``` 24 | callees show possible targets of selected function call 25 | callers show possible callers of selected function 26 | callstack show path from callgraph root to selected function 27 | definition show declaration of selected identifier 28 | describe describe selected syntax: definition, methods, etc 29 | freevars show free variables of selection 30 | implements show 'implements' relation for selected type or method 31 | peers show send/receive corresponding to selected channel op 32 | pointsto show variables the selected pointer may point to 33 | referrers show all refs to entity denoted by selected identifier 34 | what show basic information about the selected syntax node 35 | whicherrs show possible values of the selected error variable 36 | ``` 37 | 38 | Select one of the modes and the output will be displayed in a new tab. 39 | **double click on the file name in the results to jump directly to it.** 40 | 41 | You also can hold the `ctrl` key and `right-click` on a symbol to jump right to the definition. 42 | 43 | Install 44 | ------- 45 | 46 | Install Sublime Package Control (if you haven't done so already) from http://wbond.net/sublime_packages/package_control. Be sure to restart ST to complete the installation. 47 | 48 | Bring up the command palette (default ctrl+shift+p or cmd+shift+p) and start typing Package Control: Install Package then press return or click on that option to activate it. You will be presented with a new Quick Panel with the list of available packages. Type GoGuru and press return or on its entry to install GoGuru. If there is no entry for GoGuru, you most likely already have it installed. 49 | 50 | GoGuru has several variables to be set in order to work. These are explained in the comments of the default settings `Preferences > Package Settings > GoGuru > Settings-Default`: 51 | 52 | ```javascript 53 | { 54 | // use golangconfig, if false then shellenv will be used to get golang environment variables 55 | "goguru_use_golangconfig": false, 56 | 57 | // adds to the guru_scope the current package of the the working file 58 | "goguru_use_current_package" : true, 59 | 60 | // besides showing the result, jump directly to the definition 61 | "goguru_jumpto_definition": false, 62 | 63 | // The output can either be one of: 'buffer', 'output_panel' 64 | // Buffers can hold results from more than one invocation 65 | // Output panels sit underneath the editor area and are easily dismissed 66 | "goguru_output": "output_panel", 67 | 68 | // print debug info to the terminal 69 | "goguru_debug": false, 70 | 71 | // Set guru's output to json 72 | "goguru_json": false, 73 | 74 | // an array of scopes of analysis for guru. 75 | // e.g (for github.com/juju/juju) "guru_scope": ["github.com/juju/juju/cmd/juju", "github.com/juju/juju/cmd/jujud"] 76 | "goguru_scope": [], 77 | 78 | // an array of build tags of analyzed source files 79 | "goguru_tags": [], 80 | 81 | // env overwrites the default shell environment vars 82 | // e.g "env": { "GOPATH": "$HOME/go/bin:$PATH" } 83 | // not used when goguru_use_golangconfig is set to true 84 | "goguru_env": {}, 85 | } 86 | ``` 87 | You set your own variables in `Preferences > Package Settings > GoGuru > Settings-User`. 88 | 89 | You can also make project specific settings. First save your current workspace as a project `Project > Save as project ...`, then edit your project `Project > Edit Project`. Below is an example which sets up GoGuru to be used on the [github.com/juju/juju](https://github.com/juju/juju) codebase: 90 | 91 | ```javascript 92 | { 93 | "folders": 94 | [ 95 | { 96 | "follow_symlinks": true, 97 | "path": "/home/user/go/src/github.com/juju/juju" 98 | } 99 | ], 100 | "settings": 101 | { 102 | "GoGuru": { 103 | "goguru_scope": ["github.com/juju/juju/cmd/juju", "github.com/juju/juju/cmd/jujud"], 104 | "goguru_output": "output_panel" 105 | } 106 | }, 107 | } 108 | ``` 109 | 110 | Default key binding: 111 | 112 | ```javascript 113 | [ 114 | { "keys": ["ctrl+shift+g"], "command": "go_guru"}, 115 | { "keys": ["ctrl+alt+shift+g"], "command": "go_guru_show_results"}, 116 | { "keys": ["ctrl+.+ctrl+g"], "command": "go_guru_goto_definition", "context": [{ "key": "selector", "operator": "equal", "operand": "source.go" }] }, 117 | ] 118 | ``` 119 | 120 | You can set your own key binding by copying the above into `Preferences > Keybindings - User` and replacing ctrl+shift+g with your preferred key(s). 121 | 122 | You can also set a key binding for a specific mode by adding a "mode" arg, e.g.: 123 | 124 | ```javascript 125 | ... 126 | { "keys": ["ctrl+super+c"], "command": "go_guru", "args": {"mode": "callers"} }, 127 | { "keys": ["ctrl+super+i"], "command": "go_guru", "args": {"mode": "implements"} }, 128 | { "keys": ["ctrl+super+r"], "command": "go_guru", "args": {"mode": "referrers"} }, 129 | { "keys": ["ctrl+.+ctrl+g"], "command": "go_guru", "args": {"mode": "definition", output=false}}, 130 | ... 131 | ``` 132 | 133 | Default mouse bindings: 134 | 135 | ```javascript 136 | [ 137 | { 138 | "button": "button2", 139 | "modifiers": ["ctrl"], 140 | "press_command": "drag_select", 141 | "command": "go_guru", 142 | "args": { 143 | "mode": "definition", 144 | "output": false 145 | }, 146 | }, 147 | ] 148 | ``` 149 | 150 | 151 | Dependencies 152 | ------------ 153 | GoGuru relies on the guru tool. You must install it in order for GoGuru to work. Run the following on your command line: 154 | 155 | ### Go 1.16+ 156 | `go install golang.org/x/tools/cmd/guru@latest` 157 | 158 | ### Go version < 1.16 159 | `go get -u golang.org/x/tools/cmd/guru` 160 | 161 | 162 | Copyright, License & Contributors 163 | ================================= 164 | 165 | GoGuru is released under the MIT license. See [LICENSE.md](LICENSE.md) 166 | 167 | GoGuru is the copyrighted work of *The GoGuru Authors* i.e me ([alvarolm](https://github.com/alvarolm/GoGuru)) and *all* contributors. If you submit a change, be it documentation or code, so long as it's committed to GoGuru's history I consider you a contributor. See [AUTHORS.md](AUTHORS.md) for a list of all the GoGuru authors/contributors. 168 | -------------------------------------------------------------------------------- /dep/shellenv/__init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import unicode_literals, division, absolute_import, print_function 3 | 4 | import sys 5 | import os 6 | from getpass import getuser 7 | 8 | from ._types import str_cls, type_name 9 | from ._encoding import env_encode, env_decode, path_encode, path_decode # noqa 10 | 11 | if sys.platform == 'win32': 12 | from ._win import get_env, get_user_login_shell 13 | 14 | elif sys.platform == 'darwin': 15 | from ._osx import get_env 16 | from ._osx.open_directory import get_user_login_shell 17 | 18 | else: 19 | from ._linux import get_env 20 | from ._linux.getent import get_user_login_shell # noqa 21 | 22 | 23 | __version__ = '1.4.2' 24 | __version_info__ = (1, 4, 2) 25 | 26 | 27 | _paths = {} 28 | 29 | 30 | def get_path(shell=None): 31 | """ 32 | Returns the PATH as defined by the shell. If no shell is provided, gets the 33 | path from the user's login shell. 34 | 35 | :param shell: 36 | A unicode string of the shell to get the PATH from. Pass None to use 37 | the current user's login shell. 38 | 39 | :return: 40 | A 2-element tuple: 41 | 42 | - [0] a unicode string of the shell the path was retrieved from 43 | - [1] a list of unicode strings of the directories that are part of the PATH 44 | """ 45 | 46 | if shell is not None and not isinstance(shell, str_cls): 47 | raise TypeError('shell must be a unicode string, not %s' % type_name(shell)) 48 | 49 | shell_key = shell if shell else 'default' 50 | if shell_key not in _paths: 51 | shell, env = get_env(shell) 52 | _paths[shell_key] = (shell, env.get('PATH', '').split(os.pathsep)) 53 | return _paths[shell_key] 54 | 55 | 56 | def get_user(): 57 | """ 58 | Returns the current username as a unicode string 59 | 60 | :return: 61 | A unicode string of the current user's username 62 | """ 63 | 64 | output = getuser() 65 | if not isinstance(output, str_cls): 66 | output = output.decode('utf-8') 67 | return output 68 | -------------------------------------------------------------------------------- /dep/shellenv/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvarolm/GoGuru/bceaa8ccfd4d71820889091e401111d720f2f82f/dep/shellenv/__init__.pyc -------------------------------------------------------------------------------- /dep/shellenv/_encoding.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import locale 3 | 4 | from ._types import str_cls, byte_cls, type_name 5 | 6 | 7 | py2 = sys.version_info < (3,) 8 | 9 | # Encoding used for environment variables with ST2 10 | _env_encoding = locale.getpreferredencoding() if sys.platform == 'win32' else 'utf-8' 11 | 12 | # Encoding used for fileystem paths with ST2 13 | _fs_encoding = 'mbcs' if sys.platform == 'win32' else 'utf-8' 14 | 15 | 16 | def env_encode(value): 17 | """ 18 | Ensures a environment variable name or value is encoded properly to be 19 | used with subprocess.Popen() 20 | 21 | :param value: 22 | A unicode string 23 | 24 | :return: 25 | On Python 3, a unicode string, on Python 2, a byte string 26 | """ 27 | 28 | if not isinstance(value, str_cls): 29 | raise TypeError('value must be a unicode string, not %s' % type_name(value)) 30 | 31 | if not py2: 32 | return value 33 | 34 | return value.encode(_env_encoding) 35 | 36 | 37 | def env_decode(value): 38 | """ 39 | Decodes an environment variable name or value that was returned by 40 | get_env(for_subprocess=True) 41 | 42 | :param value: 43 | On Python 3, a unicode string, on Python 2, a byte string 44 | 45 | :return: 46 | A unicode string 47 | """ 48 | 49 | if not py2: 50 | if not isinstance(value, str_cls): 51 | raise TypeError('value must be a unicode string, not %s' % type_name(value)) 52 | 53 | return value 54 | 55 | if not isinstance(value, byte_cls): 56 | raise TypeError('value must be a byte string, not %s' % type_name(value)) 57 | 58 | return value.decode(_env_encoding) 59 | 60 | 61 | def path_encode(value): 62 | """ 63 | Ensures a filesystem path is encoded properly to be used with 64 | subprocess.Popen() 65 | 66 | :param value: 67 | A unicode string 68 | 69 | :return: 70 | On Python 3, a unicode string, on Python 2, a byte string 71 | """ 72 | 73 | if not isinstance(value, str_cls): 74 | raise TypeError('value must be a unicode string, not %s' % type_name(value)) 75 | 76 | if not py2: 77 | return value 78 | 79 | return value.encode(_fs_encoding) 80 | 81 | 82 | def path_decode(value): 83 | """ 84 | Decodes a filesystem path that was returned by get_env(for_subprocess=True) 85 | 86 | :param value: 87 | On Python 3, a unicode string, on Python 2, a byte string 88 | 89 | :return: 90 | A unicode string 91 | """ 92 | 93 | if not py2: 94 | if not isinstance(value, str_cls): 95 | raise TypeError('value must be a unicode string, not %s' % type_name(value)) 96 | 97 | return value 98 | 99 | if not isinstance(value, byte_cls): 100 | raise TypeError('value must be a byte string, not %s' % type_name(value)) 101 | 102 | return value.decode(_fs_encoding) 103 | -------------------------------------------------------------------------------- /dep/shellenv/_encoding.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvarolm/GoGuru/bceaa8ccfd4d71820889091e401111d720f2f82f/dep/shellenv/_encoding.pyc -------------------------------------------------------------------------------- /dep/shellenv/_linux/__init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import unicode_literals, division, absolute_import, print_function 3 | 4 | import os 5 | import sys 6 | 7 | from .._posix import get_shell_env 8 | from .getent import get_user_login_shell 9 | 10 | 11 | def get_env(shell=None, for_subprocess=False): 12 | """ 13 | Fetches the environmental variables for the current user. This is necessary 14 | since depending on how the sublime_text binary is launched, the process will 15 | not get the environment a user has in the terminal. 16 | 17 | Because sublime_text may have been launched from the terminal, the env from 18 | the shell specified and python's os.environ are compared to see which 19 | contains more information. 20 | 21 | :param shell: 22 | The shell to get the env from, if None, uses the current user's login 23 | shell 24 | 25 | :param for_subprocess: 26 | If True, and the code is being run in Sublime Text 2, the result will 27 | be byte strings instead of unicode strings 28 | 29 | :return: 30 | A 2-element tuple: 31 | 32 | - [0] unicode string shell path 33 | - [1] env dict with keys and values as unicode strings 34 | """ 35 | 36 | # If we should compare the login shell env and os.environ 37 | # to see which seems to contain the correct information 38 | compare = False 39 | 40 | login_shell = get_user_login_shell() 41 | 42 | if shell is None: 43 | shell = login_shell 44 | compare = True 45 | elif shell == login_shell: 46 | compare = True 47 | 48 | if not compare: 49 | return get_shell_env(shell, for_subprocess=for_subprocess) 50 | 51 | _, login_env = get_shell_env(shell, for_subprocess=for_subprocess) 52 | 53 | if sys.version_info < (3,) and for_subprocess: 54 | shell = shell.encode('utf-8') 55 | 56 | if len(login_env) >= len(os.environ): 57 | return (shell, login_env) 58 | 59 | if sys.version_info < (3,) and not for_subprocess: 60 | values = {} 61 | for key, value in os.environ.items(): 62 | values[key.decode('utf-8', 'replace')] = value.decode('utf-8', 'replace') 63 | else: 64 | values = dict(os.environ) 65 | 66 | return (shell, values) 67 | -------------------------------------------------------------------------------- /dep/shellenv/_linux/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvarolm/GoGuru/bceaa8ccfd4d71820889091e401111d720f2f82f/dep/shellenv/_linux/__init__.pyc -------------------------------------------------------------------------------- /dep/shellenv/_linux/getent.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import unicode_literals, division, absolute_import, print_function 3 | 4 | import subprocess 5 | from getpass import getuser 6 | 7 | from .._types import str_cls, type_name 8 | 9 | 10 | _login_shells = {} 11 | 12 | 13 | def get_user_login_shell(username=None): 14 | """ 15 | Uses getent to get the user's login shell 16 | 17 | :param username: 18 | A unicode string of the user to get the shell for - None for the 19 | current user 20 | 21 | :return: 22 | A unicode string of the user's login shell 23 | """ 24 | 25 | if username is None: 26 | username = getuser() 27 | if not isinstance(username, str_cls): 28 | username = username.decode('utf-8') 29 | 30 | if not isinstance(username, str_cls): 31 | raise TypeError('username must be a unicode string, not %s' % type_name(username)) 32 | 33 | if username not in _login_shells: 34 | 35 | proc = subprocess.Popen(['getent', 'passwd', username], stdout=subprocess.PIPE) 36 | 37 | out = b'' 38 | while proc.poll() is None: 39 | out += proc.stdout.read() 40 | out += proc.stdout.read() 41 | 42 | proc.stdout.close() 43 | 44 | line = out.decode('utf-8').strip() 45 | parts = line.split(':', 6) 46 | login_shell = parts[6] 47 | 48 | _login_shells[username] = login_shell 49 | 50 | return _login_shells.get(username) 51 | -------------------------------------------------------------------------------- /dep/shellenv/_linux/getent.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvarolm/GoGuru/bceaa8ccfd4d71820889091e401111d720f2f82f/dep/shellenv/_linux/getent.pyc -------------------------------------------------------------------------------- /dep/shellenv/_osx/__init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import unicode_literals, division, absolute_import, print_function 3 | 4 | from .._posix import get_shell_env 5 | 6 | 7 | def get_env(shell=None, for_subprocess=False): 8 | """ 9 | Uses the user's login shell to fetch the environmental variables that are 10 | set when a new shell is opened. This is necessary since on OS X, Sublime 11 | Text is launched from the dock, which does not pick up the user's shell 12 | environment. 13 | 14 | :param shell: 15 | The shell to get the env from, if None, uses the current user's login 16 | shell 17 | 18 | :param for_subprocess: 19 | If True, and the code is being run in Sublime Text 2, the result will 20 | be byte strings instead of unicode strings 21 | 22 | :return: 23 | A 2-element tuple: 24 | 25 | - [0] unicode string shell path 26 | - [1] env dict with keys and values as unicode strings 27 | """ 28 | 29 | return get_shell_env(shell, for_subprocess=for_subprocess) 30 | -------------------------------------------------------------------------------- /dep/shellenv/_osx/core_foundation.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import unicode_literals, division, absolute_import, print_function 3 | 4 | import ctypes 5 | from ctypes.util import find_library 6 | from ctypes import c_void_p, c_char_p, c_uint32, POINTER, c_long 7 | 8 | 9 | cf_path = find_library('CoreFoundation') 10 | CoreFoundation = ctypes.CDLL(cf_path, use_errno=True) 11 | 12 | 13 | CFIndex = c_long 14 | CFStringEncoding = c_uint32 15 | CFString = c_void_p 16 | CFArray = c_void_p 17 | CFDictionary = c_void_p 18 | CFError = c_void_p 19 | CFType = c_void_p 20 | 21 | CFAllocatorRef = c_void_p 22 | CFStringRef = POINTER(CFString) 23 | CFArrayRef = POINTER(CFArray) 24 | CFDictionaryRef = POINTER(CFDictionary) 25 | CFErrorRef = POINTER(CFError) 26 | CFTypeRef = POINTER(CFType) 27 | 28 | CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding] 29 | CoreFoundation.CFStringGetCStringPtr.restype = c_char_p 30 | 31 | CoreFoundation.CFStringGetCString.argtypes = [CFStringRef, c_char_p, CFIndex, CFStringEncoding] 32 | CoreFoundation.CFStringGetCString.restype = ctypes.c_bool 33 | 34 | CoreFoundation.CFStringCreateWithCString.argtypes = [CFAllocatorRef, c_char_p, CFStringEncoding] 35 | CoreFoundation.CFStringCreateWithCString.restype = CFStringRef 36 | 37 | CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef] 38 | CoreFoundation.CFArrayGetCount.restype = CFIndex 39 | 40 | CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex] 41 | CoreFoundation.CFArrayGetValueAtIndex.restype = CFTypeRef 42 | 43 | kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) 44 | setattr(CoreFoundation, 'kCFAllocatorDefault', CFAllocatorRef.in_dll(CoreFoundation, 'kCFAllocatorDefault')) 45 | setattr(CoreFoundation, 'CFIndex', CFIndex) 46 | setattr(CoreFoundation, 'CFStringRef', CFStringRef) 47 | setattr(CoreFoundation, 'CFTypeRef', CFTypeRef) 48 | setattr(CoreFoundation, 'CFAllocatorRef', CFAllocatorRef) 49 | setattr(CoreFoundation, 'CFArrayRef', CFArrayRef) 50 | setattr(CoreFoundation, 'CFDictionaryRef', CFDictionaryRef) 51 | setattr(CoreFoundation, 'CFErrorRef', CFErrorRef) 52 | 53 | 54 | def cfstring_to_unicode(value): 55 | """ 56 | Creates a python unicode string from a CoreFoundation CFStringRef 57 | 58 | :param value: 59 | A CFStringRef 60 | 61 | :return: 62 | A unicode string 63 | """ 64 | 65 | string = CoreFoundation.CFStringGetCStringPtr( 66 | ctypes.cast(value, CFStringRef), 67 | kCFStringEncodingUTF8 68 | ) 69 | if string is None: 70 | buf = ctypes.create_string_buffer(1024) 71 | result = CoreFoundation.CFStringGetCString( 72 | ctypes.cast(value, CFStringRef), 73 | buf, 74 | 1024, 75 | kCFStringEncodingUTF8 76 | ) 77 | if not result: 78 | raise OSError('Error copying C string from CFStringRef') 79 | string = buf.value 80 | if string is not None: 81 | string = string.decode('utf-8') 82 | return string 83 | 84 | 85 | def unicode_to_cfstring(value): 86 | """ 87 | Creates a CoreFoundation CFStringRef from a python unicode string 88 | 89 | :param value: 90 | A unicode string 91 | 92 | :return: 93 | A CFStringRef 94 | """ 95 | 96 | return CoreFoundation.CFStringCreateWithCString( 97 | CoreFoundation.kCFAllocatorDefault, 98 | value.encode('utf-8'), 99 | kCFStringEncodingUTF8 100 | ) 101 | -------------------------------------------------------------------------------- /dep/shellenv/_osx/open_directory.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import unicode_literals, division, absolute_import, print_function 3 | 4 | from getpass import getuser 5 | import ctypes 6 | from ctypes.util import find_library 7 | from ctypes import c_void_p, c_uint32, POINTER, c_bool, byref 8 | 9 | from .core_foundation import CoreFoundation, unicode_to_cfstring, cfstring_to_unicode 10 | from .._types import str_cls, type_name 11 | 12 | od_path = find_library('OpenDirectory') 13 | OpenDirectory = ctypes.CDLL(od_path, use_errno=True) 14 | 15 | 16 | ODAttributeType = CoreFoundation.CFStringRef 17 | ODMatchType = c_uint32 18 | ODRecordType = CoreFoundation.CFStringRef 19 | 20 | ODSessionRef = c_void_p 21 | ODNodeRef = c_void_p 22 | ODQueryRef = c_void_p 23 | ODRecordRef = c_void_p 24 | 25 | OpenDirectory.ODSessionCreate.argtypes = [ 26 | CoreFoundation.CFAllocatorRef, 27 | CoreFoundation.CFDictionaryRef, 28 | POINTER(CoreFoundation.CFErrorRef) 29 | ] 30 | OpenDirectory.ODSessionCreate.restype = ODSessionRef 31 | 32 | OpenDirectory.ODNodeCreateWithName.argtypes = [ 33 | CoreFoundation.CFAllocatorRef, 34 | ODSessionRef, 35 | CoreFoundation.CFStringRef, 36 | POINTER(CoreFoundation.CFErrorRef) 37 | ] 38 | OpenDirectory.ODNodeCreateWithName.restype = ODNodeRef 39 | 40 | OpenDirectory.ODQueryCreateWithNode.argtypes = [ 41 | CoreFoundation.CFAllocatorRef, 42 | ODNodeRef, 43 | CoreFoundation.CFTypeRef, 44 | ODAttributeType, 45 | ODMatchType, 46 | CoreFoundation.CFTypeRef, 47 | CoreFoundation.CFTypeRef, 48 | CoreFoundation.CFIndex, 49 | POINTER(CoreFoundation.CFErrorRef) 50 | ] 51 | OpenDirectory.ODQueryCreateWithNode.restype = ODQueryRef 52 | 53 | OpenDirectory.ODQueryCopyResults.argtypes = [ 54 | ODQueryRef, 55 | c_bool, 56 | POINTER(CoreFoundation.CFErrorRef) 57 | ] 58 | OpenDirectory.ODQueryCopyResults.restype = CoreFoundation.CFArrayRef 59 | 60 | OpenDirectory.ODRecordCopyValues.argtypes = [ 61 | ODRecordRef, 62 | ODAttributeType, 63 | POINTER(CoreFoundation.CFErrorRef) 64 | ] 65 | OpenDirectory.ODRecordCopyValues.restype = CoreFoundation.CFArrayRef 66 | 67 | kODMatchEqualTo = ODMatchType(0x2001) 68 | 69 | kODRecordTypeUsers = ODRecordType.in_dll(OpenDirectory, 'kODRecordTypeUsers') 70 | kODAttributeTypeRecordName = ODAttributeType.in_dll(OpenDirectory, 'kODAttributeTypeRecordName') 71 | kODAttributeTypeUserShell = ODAttributeType.in_dll(OpenDirectory, 'kODAttributeTypeUserShell') 72 | 73 | 74 | _login_shells = {} 75 | 76 | 77 | def get_user_login_shell(username=None): 78 | """ 79 | Uses OS X's OpenDirectory.framework to get the user's login shell 80 | 81 | :param username: 82 | A unicode string of the user to get the shell for - None for the 83 | current user 84 | 85 | :return: 86 | A unicode string of the user's login shell 87 | """ 88 | 89 | if username is None: 90 | username = getuser() 91 | if not isinstance(username, str_cls): 92 | username = username.decode('utf-8') 93 | 94 | if not isinstance(username, str_cls): 95 | raise TypeError('username must be a unicode string, not %s' % type_name(username)) 96 | 97 | if username not in _login_shells: 98 | 99 | error_ref = CoreFoundation.CFErrorRef() 100 | 101 | session = OpenDirectory.ODSessionCreate( 102 | CoreFoundation.kCFAllocatorDefault, 103 | None, 104 | byref(error_ref) 105 | ) 106 | if bool(error_ref): 107 | raise OSError('Error!') 108 | 109 | node = OpenDirectory.ODNodeCreateWithName( 110 | CoreFoundation.kCFAllocatorDefault, 111 | session, 112 | unicode_to_cfstring("/Local/Default"), 113 | byref(error_ref) 114 | ) 115 | if bool(error_ref): 116 | raise OSError('Error!') 117 | 118 | query = OpenDirectory.ODQueryCreateWithNode( 119 | CoreFoundation.kCFAllocatorDefault, 120 | node, 121 | kODRecordTypeUsers, 122 | kODAttributeTypeRecordName, 123 | kODMatchEqualTo, 124 | unicode_to_cfstring(username), 125 | kODAttributeTypeUserShell, 126 | 1, 127 | byref(error_ref) 128 | ) 129 | if bool(error_ref): 130 | raise OSError('Error!') 131 | 132 | results = OpenDirectory.ODQueryCopyResults( 133 | query, 134 | False, 135 | byref(error_ref) 136 | ) 137 | if bool(error_ref): 138 | raise OSError('Error!') 139 | 140 | login_shell = None 141 | 142 | num_results = CoreFoundation.CFArrayGetCount(results) 143 | if num_results == 1: 144 | od_record = CoreFoundation.CFArrayGetValueAtIndex(results, 0) 145 | attributes = OpenDirectory.ODRecordCopyValues(od_record, kODAttributeTypeUserShell, byref(error_ref)) 146 | if bool(error_ref): 147 | raise OSError('Error!') 148 | num_attributes = CoreFoundation.CFArrayGetCount(results) 149 | if num_attributes == 1: 150 | string_ref = CoreFoundation.CFArrayGetValueAtIndex(attributes, 0) 151 | login_shell = cfstring_to_unicode(string_ref) 152 | 153 | _login_shells[username] = login_shell 154 | 155 | return _login_shells.get(username) 156 | -------------------------------------------------------------------------------- /dep/shellenv/_posix.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import unicode_literals, division, absolute_import, print_function 3 | 4 | import re 5 | import os 6 | import sys 7 | import subprocess 8 | 9 | from ._types import str_cls, type_name 10 | 11 | if sys.platform == 'darwin': 12 | from ._osx.open_directory import get_user_login_shell 13 | else: 14 | from ._linux.getent import get_user_login_shell 15 | 16 | 17 | _envs = {'bytes': {}, 'unicode': {}} 18 | 19 | 20 | def get_shell_env(shell=None, for_subprocess=False): 21 | """ 22 | Fetches the environmental variables that are set when a new shell is opened. 23 | 24 | :param shell: 25 | The shell to get the env from, if None, uses the current user's login 26 | shell 27 | 28 | :param for_subprocess: 29 | If True, and the code is being run in Sublime Text 2, the result will 30 | be byte strings instead of unicode strings 31 | 32 | :return: 33 | A 2-element tuple: 34 | 35 | - [0] unicode string shell path 36 | - [1] env dict with keys and values as unicode strings 37 | """ 38 | 39 | if shell is not None and not isinstance(shell, str_cls): 40 | raise TypeError('shell must be a unicode string, not %s' % type_name(shell)) 41 | 42 | if shell is None: 43 | shell = get_user_login_shell() 44 | _, shell_name = shell.rsplit('/', 1) 45 | 46 | output_type = 'bytes' if sys.version_info < (3,) and for_subprocess else 'unicode' 47 | 48 | if shell not in _envs[output_type]: 49 | args = [shell, '-l'] 50 | # For bash we invoke interactively or else ~/.bashrc is not 51 | # loaded, and many distros and users use .bashrc for env vars 52 | if shell_name == 'bash': 53 | args.append('-i') 54 | env_proc = subprocess.Popen( 55 | args, 56 | stdin=subprocess.PIPE, 57 | stdout=subprocess.PIPE, 58 | stderr=subprocess.STDOUT 59 | ) 60 | 61 | stdout, _ = env_proc.communicate(b'/usr/bin/env\n') 62 | 63 | _envs[output_type][shell] = {} 64 | 65 | entries = re.split(b'\n(?=\\w+=)', stdout.strip()) 66 | for entry in entries: 67 | if entry == b'': 68 | continue 69 | parts = entry.split(b'=', 1) 70 | if len(parts) < 2: 71 | continue 72 | name = parts[0] 73 | value = parts[1] 74 | if output_type == 'unicode': 75 | name = name.decode('utf-8', 'replace') 76 | value = value.decode('utf-8', 'replace') 77 | _envs[output_type][shell][name] = value 78 | 79 | if output_type == 'bytes': 80 | shell = shell.encode('utf-8') 81 | 82 | return (shell, _envs[output_type][shell].copy()) 83 | -------------------------------------------------------------------------------- /dep/shellenv/_posix.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvarolm/GoGuru/bceaa8ccfd4d71820889091e401111d720f2f82f/dep/shellenv/_posix.pyc -------------------------------------------------------------------------------- /dep/shellenv/_types.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import unicode_literals, division, absolute_import, print_function 3 | 4 | import sys 5 | 6 | 7 | if sys.version_info < (3,): 8 | str_cls = unicode # noqa 9 | byte_cls = str 10 | 11 | else: 12 | str_cls = str 13 | byte_cls = bytes 14 | 15 | 16 | def type_name(value): 17 | """ 18 | Returns a user-readable name for the type of an object 19 | 20 | :param value: 21 | A value to get the type name of 22 | 23 | :return: 24 | A unicode string of the object's type name 25 | """ 26 | 27 | cls = value.__class__ 28 | if cls.__module__ in set(['builtins', '__builtin__']): 29 | return cls.__name__ 30 | return '%s.%s' % (cls.__module__, cls.__name__) 31 | -------------------------------------------------------------------------------- /dep/shellenv/_types.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvarolm/GoGuru/bceaa8ccfd4d71820889091e401111d720f2f82f/dep/shellenv/_types.pyc -------------------------------------------------------------------------------- /dep/shellenv/_win.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import unicode_literals, division, absolute_import, print_function 3 | 4 | import os 5 | import locale 6 | import sys 7 | import ctypes 8 | 9 | from ._types import str_cls 10 | 11 | 12 | _sys_encoding = locale.getpreferredencoding() 13 | 14 | kernel32 = ctypes.windll.kernel32 15 | 16 | kernel32.GetEnvironmentStringsW.argtypes = [] 17 | kernel32.GetEnvironmentStringsW.restype = ctypes.c_void_p 18 | 19 | 20 | def get_env(shell=None, for_subprocess=False): 21 | """ 22 | Return environment variables for the current user 23 | 24 | :param shell: 25 | The shell to get the env from - unused on Windows 26 | 27 | :param for_subprocess: 28 | If True, and the code is being run in Sublime Text 2, the result will 29 | be byte strings instead of unicode strings 30 | 31 | :return: 32 | A 2-element tuple: 33 | 34 | - [0] unicode string shell path 35 | - [1] env dict with keys and values as unicode strings 36 | """ 37 | 38 | shell = os.environ['ComSpec'] 39 | if not isinstance(shell, str_cls) and for_subprocess is False: 40 | shell = shell.decode(_sys_encoding) 41 | 42 | if sys.version_info < (3,) and for_subprocess is False: 43 | str_pointer = kernel32.GetEnvironmentStringsW() 44 | string = ctypes.wstring_at(str_pointer) 45 | 46 | values = {} 47 | while string != '': 48 | if string[0].isalpha(): 49 | name, value = string.split(u'=', 1) 50 | values[name.upper()] = value 51 | # Include the trailing null byte, and measure each 52 | # char as 2 bytes since Windows uses UTF-16 for 53 | # wide chars 54 | str_pointer += (len(string) + 1) * 2 55 | string = ctypes.wstring_at(str_pointer) 56 | else: 57 | values = dict(os.environ) 58 | 59 | return (shell, values) 60 | 61 | 62 | def get_user_login_shell(username=None): 63 | """ 64 | Return the path to cmd.exe. Exists for API compatiblity with OS X/Linux. 65 | 66 | :param username: 67 | A unicode string of the user to get the shell for - None for the 68 | current user 69 | 70 | :return: 71 | A unicode string of the user's login shell 72 | """ 73 | 74 | shell = os.environ['ComSpec'] 75 | if not isinstance(shell, str_cls): 76 | shell = shell.decode(_sys_encoding) 77 | return shell 78 | -------------------------------------------------------------------------------- /goGuru.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Jesse Meek 2 | # Copyright (c) 2016 Alvaro Leiva 3 | # This program is Free Software see LICENSE file for details. 4 | 5 | """ 6 | GoGuru is a Go guru plugin for Sublime Text 3. 7 | It depends on the guru tool being installed: 8 | go get golang.org/x/tools/cmd/guru 9 | """ 10 | 11 | # TODO: review & clean 12 | 13 | 14 | import sublime 15 | import sublime_plugin 16 | import re 17 | import os 18 | import subprocess 19 | import sys 20 | 21 | 22 | def log(*msg): 23 | print("GoGuru:", msg[0:]) 24 | 25 | 26 | def debug(*msg): 27 | if get_setting("goguru_debug", False): 28 | print("GoGuru [DEBUG]:", msg[0:]) 29 | 30 | 31 | def error(*msg): 32 | print("GoGuru [ERROR]:", msg[0:]) 33 | 34 | 35 | def plugin_loaded(): 36 | # load shellenv 37 | def load_shellenv(): 38 | global shellenv 39 | from .dep import shellenv 40 | 41 | # try golangconfig 42 | if get_setting("goguru_use_golangconfig", False): 43 | try: 44 | global golangconfig 45 | import golangconfig 46 | except: 47 | error("couldn't import golangconfig:", sys.exc_info()[0]) 48 | log("using shellenv instead of golangconfig") 49 | # use_golangconfig = False 50 | load_shellenv() 51 | 52 | else: 53 | load_shellenv() 54 | 55 | log("debug:", get_setting("goguru_debug", False)) 56 | log("use_golangconfig", get_setting("goguru_use_golangconfig", False)) 57 | 58 | # keep track of the version if possible (pretty nasty workaround, any other ideas ?) 59 | try: 60 | PluginPath = os.path.dirname(os.path.realpath(__file__)) 61 | p = subprocess.Popen(["git", "describe", "master", "--tags"], stdout=subprocess.PIPE, cwd=PluginPath) 62 | GITVERSION = p.communicate()[0].decode("utf-8").rstrip() 63 | if p.returncode != 0: 64 | debug("git return code", p.returncode) 65 | raise Exception("git return code", p.returncode) 66 | 67 | defsettings = os.path.join(PluginPath, 'Default.sublime-settings') 68 | f = open(defsettings, 'r') 69 | filedata = f.read() 70 | f.close() 71 | newdata = filedata.replace(get_setting('goguru_version'), GITVERSION + '_') 72 | f = open(defsettings, 'w') 73 | f.write(newdata) 74 | f.close() 75 | except: 76 | debug("couldn't get git tag:", sys.exc_info()[0]) 77 | 78 | # read version 79 | log("version:", get_setting('goguru_version')) 80 | 81 | # check if user setting exists and creates it 82 | us = sublime.load_settings("GoGuru.sublime-settings") 83 | if (not us.has('goguru_debug')): 84 | us.set('goguru_debug', get_setting("goguru_debug", False)) 85 | sublime.save_settings("GoGuru.sublime-settings") 86 | 87 | 88 | class GoGuruCommand(sublime_plugin.TextCommand): 89 | 90 | def __init__(self, view): 91 | self.view = view 92 | self.mode = 'None' 93 | self.env = 'None' 94 | self.local_package = 'None' 95 | 96 | def run(self, edit, mode=None, output=True): 97 | """ 98 | :param output: won't show the show_panel if set to False. It is particularly useful for mouse clicks. 99 | """ 100 | self.output = output 101 | try: 102 | region = self.view.sel()[0] 103 | text = self.view.substr(sublime.Region(0, region.end())) 104 | cb_map = self.get_map(text) 105 | byte_end = cb_map[sorted(cb_map.keys())[-1]] 106 | byte_begin = None 107 | if not region.empty(): 108 | byte_begin = cb_map[region.begin() - 1] 109 | except: 110 | sublime.error_message('GoGuru:\nCouldn\'t get cursor positon, make sure that the Go source file is saved and the cursor is over the identifier (variable, function ...) you want to query.') 111 | error("couldn't get cursor positon: ", sys.exc_info()) 112 | return 113 | 114 | if mode: 115 | self.write_running(mode) 116 | # expiremental 117 | # uses gosublime gs_doc commands to look for documentation 118 | # if it fails pareses the 'guru describe' output to query 'go doc' 119 | if mode == "godoc": 120 | self.view.window().run_command('gs_doc', {'mode': "hint"}) 121 | gsdoc = self.view.window().find_output_panel('GsDoc-output-output') 122 | if gsdoc is not None: 123 | if 'no docs found' not in gsdoc.substr(gsdoc.line(0)): 124 | return 125 | 126 | def messageLookingDoc(): 127 | self.write_out(None, "'gs_doc' failed,\nsearching documentation with 'goguru mode=godoc'...") 128 | sublime.set_timeout(lambda: messageLookingDoc(), 150) # any other choice besides timeout ? 129 | mode = "describe" 130 | elif mode == "godoc_direct": 131 | def messageLookingDoc(): 132 | self.write_out(None, "'searching documentation with 'goguru mode=godoc_direct'...") 133 | sublime.set_timeout(lambda: messageLookingDoc(), 150) # any other choice besides timeout ? 134 | mode = "describe" 135 | self.guru(byte_end, begin_offset=byte_begin, mode=mode, callback=self.guru_complete) 136 | return 137 | 138 | # Get the guru mode from the user. 139 | modes = ["callees", "callers", "callstack", "definition", "describe", "freevars", "implements", "peers", "pointsto", "referrers", "what", "whicherrs"] 140 | descriptions = [ 141 | "callees show possible targets of selected function call", 142 | "callers show possible callers of selected function", 143 | "callstack show path from callgraph root to selected function", 144 | "definition show declaration of selected identifier", 145 | "describe describe selected syntax: definition, methods, etc", 146 | "freevars show free variables of selection", 147 | "implements show 'implements' relation for selected type or method", 148 | "peers show send/receive corresponding to selected channel op", 149 | "pointsto show variables the selected pointer may point to", 150 | "referrers show all refs to entity denoted by selected identifier", 151 | "what show basic information about the selected syntax node", 152 | "whicherrs show possible values of the selected error variable"] 153 | 154 | # Call guru cmd with the given mode. 155 | def on_done(i): 156 | if i >= 0: 157 | self.write_running(modes[i]) 158 | 159 | self.guru(byte_end, begin_offset=byte_begin, mode=modes[i], callback=self.guru_complete) 160 | 161 | self.view.window().show_quick_panel(descriptions, on_done, sublime.MONOSPACE_FONT) 162 | 163 | def guru_complete(self, out, err): 164 | self.write_out(out, err) 165 | 166 | def write_running(self, mode): 167 | """ Write the "Running..." header to a new file and focus it to get results 168 | """ 169 | # remember mode for future actions 170 | self.mode = mode 171 | 172 | window = self.view.window() 173 | view = get_output_view(window) 174 | 175 | # Run a new command to use the edit object for this view. 176 | view.run_command('go_guru_write_running', {'mode': mode}) 177 | if get_setting("goguru_output", "buffer") == "output_panel" and self.output: 178 | window.run_command('show_panel', {'panel': "output." + view.name(), 'toggle': False}) 179 | else: 180 | window.focus_view(view) 181 | 182 | def write_out(self, result, err): 183 | """ Write the guru output to a new file. 184 | """ 185 | 186 | def cleanPackageAddr(p): 187 | return str(p).replace('"', '').replace('(', '').replace(')', '').replace('*', '') 188 | 189 | window = self.view.window() 190 | view = get_output_view(window) 191 | 192 | # parse guru describe to query go doc 193 | jump = False 194 | if (self.mode == 'godoc' or self.mode == 'godoc_direct') and result: 195 | parts = result.split() 196 | 197 | definitionLine = result.split('\n')[1] 198 | goType = parts[3] 199 | 200 | package = '' 201 | identifier = '' 202 | 203 | debug('godoc', 'goType', goType) 204 | if goType == 'package': 205 | # /home/username/go/src/myProject/utils/global/global.go:104.24-104.29: reference to package "errors" 206 | package = cleanPackageAddr(parts[4]) 207 | elif goType == 'func': 208 | # /home/username/go/src/myProject/utils/global/global.go:232.9-232.20: reference to method func (*myProject/utils/uid.GUIDGenerator).SetServiceID(ServiceID *string) 209 | if parts[4] == 'method': 210 | parts[4] = str(parts[4].split('(')[0]).split(".") 211 | package = parts[4][0] 212 | identifier = '.'.join(parts[4][1:]) 213 | else: 214 | # /home/usuario/go/src/myProject/watchdog/main.go:55.14-55.31: reference to func myProject/utils/global.ContainsAnyOfThese(str string, anyof []string) bool 215 | if '/' in parts[4]: 216 | parts[4] = parts[4].split('.') 217 | package = parts[4][0] 218 | identifier = parts[4][1].split('(')[0] 219 | 220 | # /home/username/go/src/myProject/watchdog/main.go:84.5-84.17: reference to func StartUpClient() 221 | else: 222 | package = "-u " + self.local_package 223 | parts[4] = cleanPackageAddr(parts[4]).split(".") 224 | identifier = '.'.join(parts[4]) 225 | 226 | elif goType == 'method': 227 | 228 | parts[5] = parts[5].split('(')[1] 229 | 230 | # /home/username/go/src/myProject/watchdog/main.go:78.10-78.17: reference to method func (*myProject/utils/global.Instance).ExitBool(returnErrorCodePtr *bool) 231 | if '/' in parts[5]: 232 | parts[5] = cleanPackageAddr(parts[5]).split(".") 233 | package = parts[5][0] 234 | identifier = '.'.join(parts[5][1:]) 235 | else: 236 | # /home/username/go/src/myProject/watchdog/main.go:151.4-151.7: reference to method func (*sync.Mutex).Lock() 237 | if '.' in parts[5].split(')')[0]: 238 | parts[5] = cleanPackageAddr(parts[5]).split(".") 239 | package = parts[5][0] 240 | identifier = '.'.join(parts[5][1:]) 241 | # /home/username/go/src/myProject/watchdog/main.go:200.18-200.19: reference to method func (*instanceStats).me() string 242 | else: 243 | parts[5] = parts[5].split(".") 244 | package = "-u " + self.local_package 245 | identifier = '.'.join(parts[5][1:]) 246 | 247 | elif goType == 'interface': 248 | # /home/username/go/src/myProject/utils/global/global.go:238.16-238.19: reference to interface method func (myProject/utils/crypto.GenericKeyHolder).Init( 249 | 250 | parts[6] = cleanPackageAddr(parts[6]).split('.') 251 | package = parts[6][0] 252 | identifier = parts[6][1] 253 | 254 | # /home/username/go/src/myProject/utils/uid/uid.go:99:26: concrete method func (*myProject/utils/uid.GUIDGenerator).SetServiceID(ServiceID *string) 255 | # /home/username/go/src/myProject/utils/log/log.go:50:2: implements method (myProject/utils/log.GUIDGenerator).SetServiceID 256 | else: 257 | result = goType + " not implemented yet." 258 | jump = True 259 | 260 | if not jump: 261 | cmd = "go doc %(package)s %(identifier)s " % { 262 | "package": package, 263 | "identifier": identifier, 264 | } 265 | debug("godoc", "cmd", cmd) 266 | 267 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True, env=self.env) 268 | o, e = proc.communicate() 269 | 270 | result = o.decode('utf-8') 271 | 272 | # comment non go code 273 | prettierResult = '' 274 | for line in result.splitlines(): 275 | if line[0:4] == ' ': 276 | prettierResult += '//' + line + '\n' 277 | else: 278 | prettierResult += line + '\n' 279 | result = '\n'.join(prettierResult, definitionLine) 280 | err = e.decode('utf-8') 281 | 282 | # Run a new command to use the edit object for this view. 283 | view.run_command('go_guru_write_results', { 284 | 'result': result, 285 | 'err': err}) 286 | 287 | if get_setting("goguru_output", "buffer") == "output_panel" and self.output: 288 | window.run_command('show_panel', {'panel': "output." + view.name()}) 289 | else: 290 | window.focus_view(view) 291 | 292 | # the case when clicking doesn't require showing the output 293 | if self.mode == 'definition' and not self.output: 294 | if result: 295 | coordinates = result.split(':')[:3] 296 | new_view = window.open_file(':'.join(coordinates), sublime.ENCODED_POSITION) 297 | group, _ = window.get_view_index(new_view) 298 | if group != -1: 299 | window.focus_group(group) 300 | # jump to definition if is set 301 | elif self.mode == 'definition': 302 | if get_setting("goguru_jumpto_definition", False): 303 | if result: 304 | coordinates = result.split(':')[:3] 305 | new_view = window.open_file(':'.join(coordinates), sublime.ENCODED_POSITION) 306 | group, _ = window.get_view_index(new_view) 307 | if group != -1: 308 | window.focus_group(group) 309 | 310 | def get_map(self, chars): 311 | """ Generate a map of character offset to byte offset for the given string 'chars'. 312 | """ 313 | 314 | byte_offset = 0 315 | cb_map = {} 316 | 317 | for char_offset, char in enumerate(chars): 318 | cb_map[char_offset] = byte_offset 319 | byte_offset += len(char.encode('utf-8')) 320 | if char == '\n' and self.view.line_endings() == "Windows": 321 | byte_offset += 1 322 | return cb_map 323 | 324 | def guru(self, end_offset, begin_offset=None, mode="describe", callback=None): 325 | """ Builds the guru shell command and calls it, returning it's output as a string. 326 | """ 327 | 328 | pos = "#" + str(end_offset) 329 | if begin_offset is not None: 330 | pos = "#%i,#%i" % (begin_offset, end_offset) 331 | 332 | 333 | # golang config or shellenv ? 334 | cmd_env = '' 335 | if get_setting("goguru_use_golangconfig", False): 336 | try: 337 | toolpath, cmd_env = golangconfig.subprocess_info('guru', ['GOPATH', 'PATH'], view=self.view) 338 | toolpath = os.path.realpath(toolpath) 339 | except: 340 | error("golangconfig:", sys.exc_info()) 341 | return 342 | else: 343 | toolpath = 'guru' 344 | cmd_env = shellenv.get_env(for_subprocess=True)[1] 345 | debug("cmd_env", cmd_env) 346 | goguru_env = get_setting("goguru_env", {}) 347 | debug("goguru_env", goguru_env) 348 | cmd_env.update(goguru_env) 349 | 350 | debug("final_env", cmd_env) 351 | self.env = cmd_env 352 | 353 | guru_scope = ",".join(get_setting("goguru_scope", "")) 354 | 355 | # add local package to guru scope 356 | useCurrentPackage = get_setting("goguru_use_current_package", True) 357 | debug("goguru_use_current_package", useCurrentPackage) 358 | file_path = self.view.file_name() 359 | 360 | if useCurrentPackage: 361 | try: 362 | GOPATH = os.path.realpath(cmd_env["GOPATH"]) 363 | except: 364 | log("WARNING: using default GOPATH since it isn't declared ($HOME/go)") 365 | GOPATH = os.path.expanduser("~/go") 366 | debug("GOPATH", GOPATH) 367 | 368 | local_package = get_local_package(GOPATH, file_path) 369 | debug("local_package", local_package) 370 | if sublime.platform() == 'windows': 371 | local_package = local_package.replace('\\', '/') 372 | self.local_package = local_package 373 | guru_scope = guru_scope + ',' + local_package 374 | 375 | guru_scope = guru_scope.strip() 376 | debug("guru_scope", guru_scope) 377 | if len(guru_scope) > 0: 378 | guru_scope = "-scope " + guru_scope 379 | 380 | guru_tags = "-tags \"" + " ".join(get_setting("goguru_tags", "")) + "\"" 381 | 382 | guru_json = "" 383 | if get_setting("goguru_json", False): 384 | guru_json = "-json" 385 | 386 | # Build guru cmd. 387 | # modified update 22/10/2019 - 3 (DD/MM/YYYY) 388 | contents = self.view.substr(sublime.Region(0, self.view.size())) 389 | cmd = "%(toolpath)s -modified %(scope)s %(tags)s %(guru_json)s %(mode)s %(file_path)s:%(pos)s" % { 390 | "toolpath": toolpath, 391 | "file_path": file_path, 392 | "pos": pos, 393 | "guru_json": guru_json, 394 | "mode": mode, 395 | "scope": guru_scope, 396 | "tags": guru_tags 397 | } 398 | debug("cmd", cmd) 399 | 400 | sublime.set_timeout_async(lambda: self.runInThread(cmd, callback, cmd_env, contents, file_path), 0) 401 | 402 | def runInThread(self, cmd, callback, env, contents, file_path): 403 | contentsbytes = contents.encode('utf-8',errors = 'strict') 404 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True, env=env) 405 | proc.stdin.write(bytes(file_path+'\n', encoding='utf8')) 406 | proc.stdin.write(bytes(str(len(contentsbytes))+'\n', encoding='utf8')) 407 | proc.stdin.write(contentsbytes) 408 | out, err = proc.communicate() 409 | callback(out.decode('utf-8'), err.decode('utf-8')) 410 | 411 | 412 | class GoGuruWriteResultsCommand(sublime_plugin.TextCommand): 413 | """ Writes the guru output to the current view. 414 | """ 415 | 416 | def run(self, edit, result, err): 417 | view = self.view 418 | 419 | view.insert(edit, view.size(), "\n") 420 | 421 | if result: 422 | view.insert(edit, view.size(), result) 423 | if err: 424 | error(err) 425 | view.insert(edit, view.size(), err) 426 | 427 | view.insert(edit, view.size(), "\n\n\n") 428 | 429 | 430 | class GoGuruWriteRunningCommand(sublime_plugin.TextCommand): 431 | """ Writes the guru output to the current view. 432 | """ 433 | 434 | def run(self, edit, mode): 435 | view = self.view 436 | 437 | content = "Running guru " + mode + " command...\n" 438 | view.set_viewport_position(view.text_to_layout(view.size() - 1)) 439 | 440 | view.insert(edit, view.size(), content) 441 | 442 | 443 | class GoGuruShowResultsCommand(sublime_plugin.TextCommand): 444 | 445 | def run(self, edit): 446 | if get_setting("goguru_output", "buffer") == "output_panel": 447 | self.view.window().run_command('show_panel', {'panel': "output.GoGuru Output"}) 448 | else: 449 | output_view = get_output_view(self.view.window()) 450 | self.view.window().focus_view(output_view) 451 | 452 | 453 | class GoGuruOpenResultCommand(sublime_plugin.EventListener): 454 | 455 | def on_selection_modified(self, view): 456 | if view.name() == "GoGuru Output": 457 | if len(view.sel()) != 1: 458 | return 459 | if view.sel()[0].size() == 0: 460 | return 461 | 462 | lines = view.lines(view.sel()[0]) 463 | if len(lines) != 1: 464 | return 465 | 466 | line = view.full_line(lines[0]) 467 | text = view.substr(line) 468 | 469 | # format = get_setting("guru_format") 470 | 471 | # "filename:line:col" pattern for json 472 | m = re.search("\"([^\"]+):([0-9]+):([0-9]+)\"", text) 473 | 474 | # >filename:line:col< pattern for xml 475 | if m is None: 476 | m = re.search(">([^<]+):([0-9]+):([0-9]+)<", text) 477 | 478 | # filename:line.col-line.col: pattern for plain 479 | if m is None: 480 | m = re.search("^(.+\.go):([0-9]+).([0-9]+)[-: ]", text) 481 | 482 | if m: 483 | w = view.window() 484 | new_view = w.open_file(m.group(1) + ':' + m.group(2) + ':' + m.group(3), sublime.ENCODED_POSITION) 485 | group, index = w.get_view_index(new_view) 486 | if group != -1: 487 | w.focus_group(group) 488 | 489 | 490 | class GoGuruGotoDefinitionCommand(GoGuruCommand): 491 | 492 | def run(self, edit, mode=None, output=True): 493 | super().run(edit=edit, mode="definition", output=False) 494 | 495 | 496 | def get_output_view(window): 497 | view = None 498 | buff_name = 'GoGuru Output' 499 | 500 | if get_setting("goguru_output", "buffer") == "output_panel": 501 | view = window.create_output_panel(buff_name) 502 | else: 503 | # If the output file is already open, use that. 504 | for v in window.views(): 505 | if v.name() == buff_name: 506 | view = v 507 | break 508 | # Otherwise, create a new one. 509 | if view is None: 510 | view = window.new_file() 511 | 512 | view.set_name(buff_name) 513 | view.set_scratch(True) 514 | view_settings = view.settings() 515 | view_settings.set('line_numbers', False) 516 | view.set_syntax_file('Packages/GoGuru/GoGuruResults.tmLanguage') 517 | view.set_syntax_file('Packages/Go/Go.sublime-syntax') 518 | 519 | return view 520 | 521 | 522 | def get_setting(key, default=None): 523 | """ Returns the setting in the following hierarchy: project setting, user setting, 524 | default setting. If none are set the 'default' value passed in is returned. 525 | """ 526 | project_settings = sublime.active_window().active_view().settings().get('GoGuru', {}) 527 | if key in project_settings: 528 | return project_settings.get(key) 529 | 530 | user_settings = sublime.load_settings("GoGuru.sublime-settings") 531 | if user_settings.has(key): 532 | return user_settings.get(key) 533 | 534 | return sublime.load_settings("Default.sublime-settings").get(key, default) 535 | 536 | 537 | def get_local_package(GOPATH, file_path): 538 | """ 539 | Returns the local package name based on file_path. 540 | Rational: the GOPATH is usually composed of multiple paths separated 541 | by ":". The idea is to check the first one that matches the file_path 542 | to get the package name. 543 | """ 544 | current_file_path = os.path.realpath(os.path.dirname(file_path)) 545 | for path in GOPATH.split(":"): 546 | guessing_path = os.path.join(path, "src") 547 | if file_path.startswith(guessing_path): 548 | return os.path.relpath(current_file_path, guessing_path) 549 | 550 | # the GOPATH and the file in question are not aligned 551 | return "" 552 | -------------------------------------------------------------------------------- /messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "install": "messages/install.txt", 3 | "0.1.12": "messages/0.1.12.txt" 4 | } 5 | -------------------------------------------------------------------------------- /messages/0.1.12.txt: -------------------------------------------------------------------------------- 1 | 2 | _____ _____ 3 | / ____| / ____| 4 | | | __ ___ | | __ _ _ _ __ _ _ 5 | | | |_ |/ _ \| | |_ | | | | '__| | | | 6 | | |__| | (_) | |__| | |_| | | | |_| | 7 | \_____|\___/ \_____|\__,_|_| \__,_| 8 | 9 | _ _ 10 | | | | | 11 | _ _ _ __ __| | __ _| |_ ___ 12 | | | | | '_ \ / _` |/ _` | __/ _ \ 13 | | |_| | |_) | (_| | (_| | || __/ 14 | \__,_| .__/ \__,_|\__,_|\__\___| 15 | | | 16 | |_| 17 | 18 | Version 0.1.12 19 | 20 | the settings variables have been renamed, 21 | so remember to update your user config 22 | otherwise GoGuru may not work as you expected. 23 | 24 | Alvaro -------------------------------------------------------------------------------- /messages/install.txt: -------------------------------------------------------------------------------- 1 | 2 | _____ _____ 3 | / ____| / ____| 4 | | | __ ___ | | __ _ _ _ __ _ _ 5 | | | |_ |/ _ \| | |_ | | | | '__| | | | 6 | | |__| | (_) | |__| | |_| | | | |_| | 7 | \_____|\___/ \_____|\__,_|_| \__,_| 8 | 9 | 10 | Thanks for using GoGuru ! 11 | 12 | For instructions on how to use this package 13 | check out README.md: from menu: 14 | Preferences > Package Settings > GoGuru > Read Me 15 | 16 | Please report any issues or improvements here: 17 | 18 | https://github.com/alvarolm/GoGuru/issues 19 | 20 | http://alvarolm.github.io/GoGuru 21 | 22 | **If it doesn't seems to be working, 23 | restart sublime and try again ** 24 | 25 | ;-) 26 | --------------------------------------------------------------------------------