├── dep
└── shellenv
│ ├── __init__.pyc
│ ├── _posix.pyc
│ ├── _types.pyc
│ ├── _encoding.pyc
│ ├── _linux
│ ├── getent.pyc
│ ├── __init__.pyc
│ ├── getent.py
│ └── __init__.py
│ ├── _types.py
│ ├── _osx
│ ├── __init__.py
│ ├── core_foundation.py
│ └── open_directory.py
│ ├── __init__.py
│ ├── _win.py
│ ├── _posix.py
│ └── _encoding.py
├── messages.json
├── AUTHORS.md
├── Default (Linux).sublime-keymap
├── Default (OSX).sublime-keymap
├── Default (Windows).sublime-keymap
├── CHANGELOG.md
├── messages
├── install.txt
└── 0.1.9.txt
├── LICENSE.md
├── Default.sublime-settings
├── Default.sublime-commands
├── GoRenameResults.tmLanguage
├── Main.sublime-menu
├── README.md
└── goRename.py
/dep/shellenv/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alvarolm/GoRename/HEAD/dep/shellenv/__init__.pyc
--------------------------------------------------------------------------------
/dep/shellenv/_posix.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alvarolm/GoRename/HEAD/dep/shellenv/_posix.pyc
--------------------------------------------------------------------------------
/dep/shellenv/_types.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alvarolm/GoRename/HEAD/dep/shellenv/_types.pyc
--------------------------------------------------------------------------------
/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "install": "messages/install.txt",
3 | "0.1.9": "messages/0.1.9.txt"
4 | }
5 |
--------------------------------------------------------------------------------
/dep/shellenv/_encoding.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alvarolm/GoRename/HEAD/dep/shellenv/_encoding.pyc
--------------------------------------------------------------------------------
/dep/shellenv/_linux/getent.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alvarolm/GoRename/HEAD/dep/shellenv/_linux/getent.pyc
--------------------------------------------------------------------------------
/dep/shellenv/_linux/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alvarolm/GoRename/HEAD/dep/shellenv/_linux/__init__.pyc
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/Default (Linux).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | { "keys": ["ctrl+alt+r"], "command": "go_rename"},
3 | { "keys": ["ctrl+alt+shift+r"], "command": "go_rename_show_results"},
4 |
5 | { "keys": ["enter"], "command": "go_rename_confirm", "context":
6 | [{ "key": "selector", "operator": "equal", "operand": "text.gorename-results" }]
7 | }
8 |
9 | ]
--------------------------------------------------------------------------------
/Default (OSX).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | { "keys": ["ctrl+alt+r"], "command": "go_rename"},
3 | { "keys": ["ctrl+alt+shift+r"], "command": "go_rename_show_results"},
4 |
5 | { "keys": ["enter"], "command": "go_rename_confirm", "context":
6 | [{ "key": "selector", "operator": "equal", "operand": "text.gorename-results" }]
7 | }
8 |
9 | ]
--------------------------------------------------------------------------------
/Default (Windows).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | { "keys": ["ctrl+alt+r"], "command": "go_rename"},
3 | { "keys": ["ctrl+alt+shift+r"], "command": "go_rename_show_results"},
4 |
5 | { "keys": ["enter"], "command": "go_rename_confirm", "context":
6 | [{ "key": "selector", "operator": "equal", "operand": "text.gorename-results" }]
7 | }
8 |
9 | ]
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | GoRename Changes
2 | ----------------
3 |
4 | ## 0.1.0
5 | * ...
6 |
7 | ## 0.1.1 (first working version)
8 | * new feature: prevent renaming when referenced file has changed
9 | * new feature: arguments review before renaming
10 | * new feature: enable optional flags (-d, -force, -v) per renaming basis
11 |
12 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/messages/install.txt:
--------------------------------------------------------------------------------
1 |
2 | _____ _____
3 | / ____| | __ \
4 | | | __ ___ | |__) |___ _ __ __ _ _ __ ___ ___
5 | | | |_ |/ _ \| _ // _ \ '_ \ / _` | '_ ` _ \ / _ \
6 | | |__| | (_) | | \ \ __/ | | | (_| | | | | | | __/
7 | \_____|\___/|_| \_\___|_| |_|\__,_|_| |_| |_|\___|
8 |
9 |
10 | Thanks for using GoRename !
11 | Please report any issues or improvements here:
12 |
13 | https://github.com/alvarolm/GoRename/issues
14 |
15 | For instructions on how to use this package
16 | check out README.md: from menu:
17 | Preferences > Package Settings > GoRename > Read Me
18 |
19 | http://alvarolm.github.io/GoRename
20 |
21 | ;-)
--------------------------------------------------------------------------------
/messages/0.1.9.txt:
--------------------------------------------------------------------------------
1 |
2 | _____ _____
3 | / ____| | __ \
4 | | | __ ___ | |__) |___ _ __ __ _ _ __ ___ ___
5 | | | |_ |/ _ \| _ // _ \ '_ \ / _` | '_ ` _ \ / _ \
6 | | |__| | (_) | | \ \ __/ | | | (_| | | | | | | __/
7 | \_____|\___/|_| \_\___|_| |_|\__,_|_| |_| |_|\___|
8 | _ _
9 | | | | |
10 | _ _ _ __ __| | __ _| |_ ___
11 | | | | | '_ \ / _` |/ _` | __/ _ \
12 | | |_| | |_) | (_| | (_| | || __/
13 | \__,_| .__/ \__,_|\__,_|\__\___|
14 | | |
15 | |_|
16 |
17 | Version 0.1.9
18 |
19 | the settings variables have been renamed,
20 | so remember to update your user config
21 | otherwise GoRename may not work as you expected.
22 |
23 | Alvaro
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/Default.sublime-settings:
--------------------------------------------------------------------------------
1 | {
2 | "gorename_version" : "0.1.12", // DO NOT MODIFY
3 | // Please do not edit this file, instead use the user config.
4 |
5 | // rename files that had been modified after the 'go_rename' command has been executed.
6 | // (DO NOT set to true unless you want a renaming nightmare)
7 | "gorename_rename_modified_files": false,
8 |
9 | // use golangconfig, if false then shellenv will be used to get golang environment variables
10 | "gorename_use_golangconfig": false,
11 |
12 | // fill variable name text field by default
13 | "gorename_autofill": false,
14 |
15 | // The output can either be one of: 'buffer', 'output_panel'
16 | // Buffers can hold results from more than one invocation
17 | // Output panels sit underneath the editor area and are easily dismissed
18 | "gorename_output": "output_panel",
19 |
20 | // print debug info to the terminal
21 | "gorename_debug": false,
22 |
23 | // env overwrites the default shell environment vars
24 | // e.g "env": { "GOPATH": "$HOME/go/bin:$PATH" }
25 | // not used when gorename_use_golangconfig is set to true
26 | "gorename_env": {},
27 | }
28 |
--------------------------------------------------------------------------------
/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "GoRename",
4 | "command": "go_rename"
5 | },
6 | {
7 | "caption": "GoRename: Show Results",
8 | "command": "go_guru_show_results"
9 | },
10 | {
11 | "caption": "GoRename: User Settings",
12 | "command": "open_file",
13 | "args": {
14 | "file": "${packages}/User/GoRename.sublime-settings"
15 | }
16 | },
17 | {
18 | "caption": "GoRename: Default Settings",
19 | "command": "open_file",
20 | "args": {
21 | "file": "${packages}/GoRename/Default.sublime-settings"
22 | }
23 | },
24 | {
25 | "caption": "GoRename: Default Key Bindings",
26 | "command": "open_file",
27 | "args": {
28 | "file": "${packages}/GoRename/Default (Linux).sublime-keymap",
29 | "platform": "Linux"
30 | }
31 | },
32 | {
33 | "caption": "GoRename: Default Key Bindings",
34 | "command": "open_file",
35 | "args": {
36 | "file": "${packages}/GoRename/Default (Windows).sublime-keymap",
37 | "platform": "Windows"
38 | }
39 | },
40 | {
41 | "caption": "GoRename: Default Key Bindings",
42 | "command": "open_file",
43 | "args": {
44 | "file": "${packages}/GoRename/Default (OSX).sublime-keymap",
45 | "platform": "OSX"
46 | }
47 | },
48 |
49 | ]
50 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/GoRenameResults.tmLanguage:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Gorename 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 | ^([^:]*:[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.gorename-results
54 |
55 |
56 |
--------------------------------------------------------------------------------
/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/_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 |
--------------------------------------------------------------------------------
/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": "GoRename",
14 | "children":
15 | [
16 | {
17 | "caption": "Settings – Default",
18 | "command": "open_file",
19 | "args": {
20 | "file": "${packages}/GoRename/Default.sublime-settings"
21 | }
22 | },
23 | {
24 | "caption": "Settings – User",
25 | "command": "open_file",
26 | "args": {
27 | "file": "${packages}/User/GoRename.sublime-settings"
28 | }
29 | },
30 | { "caption": "-" },
31 | {
32 | "caption": "Key Bindings – Default",
33 | "platform": "Linux",
34 | "command": "open_file",
35 | "args": {
36 | "file": "${packages}/GoRename/Default (Linux).sublime-keymap"
37 | }
38 | },
39 | {
40 | "caption": "Key Bindings – Default",
41 | "platform": "Windows",
42 | "command": "open_file",
43 | "args": {
44 | "file": "${packages}/GoRename/Default (Windows).sublime-keymap"
45 | }
46 | },
47 | {
48 | "caption": "Key Bindings – Default",
49 | "platform": "OSX",
50 | "command": "open_file",
51 | "args": {
52 | "file": "${packages}/GoRename/Default (OSX).sublime-keymap"
53 | }
54 | },
55 | { "caption": "-" },
56 | {
57 | "caption": "Changes & Announcements",
58 | "command": "open_file",
59 | "args": {
60 | "file": "${packages}/GoRename/CHANGELOG.md"
61 | }
62 | },
63 | { "caption": "-" },
64 | {
65 | "caption": "Read Me",
66 | "command": "open_file",
67 | "args": {
68 | "file": "${packages}/GoRename/README.md"
69 | }
70 | },
71 | {
72 | "caption": "Authors & Contributors",
73 | "command": "open_file",
74 | "args": {
75 | "file": "${packages}/GoRename/AUTHORS.md"
76 | }
77 | },
78 | {
79 | "caption": "License (MIT)",
80 | "command": "open_file",
81 | "args": {
82 | "file": "${packages}/GoRename/LICENSE.md"
83 | }
84 | }
85 | ]
86 | }
87 | ]
88 | }
89 | ]
90 | }
91 | ]
92 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/_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/_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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | GoRename [](http://alvarolm.github.io/GoRename/)
2 | =========
3 |
4 | GoRename is a Golang plugin for [SublimeText](http://www.sublimetext.com/) 3 that integrates the Go [gorename](https://godoc.org/golang.org/x/tools/cmd/gorename) tool.
5 |
6 | ```
7 | The gorename command performs precise type-safe renaming of identifiers in Go source code.
8 | ```
9 | useful for refactoring.
10 |
11 | (based on previus work from [waigani](http://github.com/waigani/GoOracle))
12 |
13 | Usage
14 | -----
15 |
16 | 1) Place the cursor over the identifier you want to rename (could be a variable, method, etc.).
17 |
18 | 2) press CTRL+ALT+R, then using the up and down keys select the optional flags to be used with ENTER, once you're done press ESC or click away.
19 |
20 | 3) type the new name and press ENTER.
21 |
22 | 4) review the parameters and press ENTER again to confirm and execute the gorename tool.
23 |
24 | (If by any chance the results panel disappears just press CTRL+SHIFT+ALT+R)
25 |
26 | configurable flags:
27 | ```
28 | -force causes the renaming to proceed even if conflicts were reported.
29 | The resulting program may be ill-formed, or experience a change
30 | in behaviour.
31 |
32 | WARNING: this flag may even cause the renaming tool to crash.
33 | (In due course this bug will be fixed by moving certain
34 | analyses into the type-checker.)
35 |
36 | -d display diffs instead of rewriting files
37 |
38 | -v enables verbose logging.
39 | ```
40 |
41 | Install
42 | -------
43 |
44 | 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.
45 |
46 | 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 'GoRename' and press return or click on its entry to install GoRename. If there is no entry for 'GoRename', you most likely already have it installed.
47 |
48 | GoOracle has several variables to be set in order to work. These are explained in the comments of the default settings `Preferences > Package Settings > GoOracle > Settings-Default`:
49 |
50 | ```javascript
51 | {
52 | // rename files that had been modified after the 'go_rename' command has been executed.
53 | // (DO NOT set to true unless you want a renaming nightmare)
54 | "gorename_rename_modified_files": false,
55 |
56 | // use golangconfig, if false then shellenv will be used to get golang environment variables
57 | "gorename_use_golangconfig": false,
58 |
59 | // fill variable name text field by default
60 | "gorename_autofill": false,
61 |
62 | // The output can either be one of: 'buffer', 'output_panel'
63 | // Buffers can hold results from more than one invocation
64 | // Output panels sit underneath the editor area and are easily dismissed
65 | "gorename_output": "output_panel",
66 |
67 | // print debug info to the terminal
68 | "gorename_debug": false,
69 |
70 | // env overwrites the default shell environment vars
71 | // e.g "env": { "GOPATH": "$HOME/go/bin:$PATH" }
72 | // not used when gorename_use_golangconfig is set to true
73 | "gorename_env": {},
74 | }
75 | ```
76 | You set your own variables in `Preferences > Package Settings > GoRename > Settings-User`.
77 |
78 | 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 GoOracle to be used on the [github.com/juju/juju](https://github.com/juju/juju) codebase:
79 |
80 | ```javascript
81 | {
82 | "folders":
83 | [
84 | {
85 | "follow_symlinks": true,
86 | "path": "/home/user/go/src/github.com/juju/juju"
87 | }
88 | ],
89 | "settings":
90 | {
91 | "GoRename": {
92 | "gorename_scope": ["github.com/juju/juju/cmd/juju", "github.com/juju/juju/cmd/jujud"],
93 | "output": "output_panel"
94 | }
95 | },
96 | }
97 | ```
98 |
99 | Default key binding:
100 |
101 | ```javascript
102 | [
103 | { "keys": ["ctrl+alt+r"], "command": "go_rename"},
104 | { "keys": ["ctrl+alt+shift+r"], "command": "go_rename_show_results"},
105 |
106 | { "keys": ["enter"], "command": "go_rename_confirm", "context":
107 | [{ "key": "selector", "operator": "equal", "operand": "text.gorename-results" }]
108 | }
109 | ]
110 | ```
111 |
112 | 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).
113 |
114 |
115 | Dependencies
116 | ------------
117 | GoRename relies on the gorename tool. You must install it in order for Gorename to work. Run the following on your command line:
118 |
119 | `go get -u golang.org/x/tools/cmd/gorename`
120 |
121 |
122 |
123 | Copyright, License & Contributors
124 | =================================
125 |
126 | GoRename is released under the MIT license. See [LICENSE.md](LICENSE.md)
127 |
128 | GoRename is the copyrighted work of *The GoRename Authors* i.e me ([alvarolm](https://github.com/alvarolm/GoRename)) and *all* contributors. If you submit a change, be it documentation or code, so long as it's committed to GoRename's history I consider you a contributor. See [AUTHORS.md](AUTHORS.md) for a list of all the GoRename authors/contributors.
129 |
--------------------------------------------------------------------------------
/goRename.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 | GoRename is a Go gorename plugin for Sublime Text 3.
7 | It depends on the gorename tool being installed:
8 | go get -u golang.org/x/tools/cmd/gorename
9 | """
10 |
11 | # TODO: review & clean
12 |
13 | import sublime, sublime_plugin, subprocess, time, re, os, subprocess, sys, time, hashlib
14 |
15 | DEBUG = False
16 | VERSION = ''
17 | use_golangconfig = False
18 | # holds renaming parameters
19 | renameMe = {}
20 | runningTool = False
21 |
22 | def log(*msg):
23 | print("GoRename:", msg[0:])
24 |
25 | def debug(*msg):
26 | if DEBUG:
27 | print("GoRename [DEBUG]:", msg[0:])
28 |
29 | def error(*msg):
30 | print("GoRename [ERROR]:", msg[0:])
31 |
32 | def plugin_loaded():
33 | global DEBUG
34 | global VERSION
35 | global use_golangconfig
36 |
37 | DEBUG = get_setting("gorename_debug", False)
38 | use_golangconfig = get_setting("gorename_use_golangconfig", False)
39 |
40 | # load shellenv
41 | def load_shellenv():
42 | global shellenv
43 | from .dep import shellenv
44 |
45 | # try golangconfig
46 | if use_golangconfig:
47 | try:
48 | global golangconfig
49 | import golangconfig
50 | except:
51 | error("couldn't import golangconfig:", sys.exc_info()[0])
52 | log("using shellenv instead of golangconfig")
53 | use_golangconfig = False
54 | load_shellenv()
55 |
56 | else:
57 | load_shellenv()
58 |
59 | log("debug:", DEBUG)
60 | log("use_golangconfig", use_golangconfig)
61 |
62 | # keep track of the version if possible (pretty nasty workaround, any other ideas ?)
63 | try:
64 | PluginPath = os.path.dirname(os.path.realpath(__file__))
65 | p = subprocess.Popen(["git", "describe", "master", "--tags"], stdout=subprocess.PIPE, cwd=PluginPath)
66 | GITVERSION = p.communicate()[0].decode("utf-8").rstrip()
67 | if p.returncode != 0:
68 | debug("git return code", p.returncode)
69 | raise Exception("git return code", p.returncode)
70 |
71 |
72 | defsettings = os.path.join(PluginPath, 'Default.sublime-settings')
73 | f = open(defsettings,'r')
74 | filedata = f.read()
75 | f.close()
76 | newdata = filedata.replace(get_setting('gorename_version'), GITVERSION+'_')
77 | f = open(defsettings,'w')
78 | f.write(newdata)
79 | f.close()
80 | except:
81 | debug("couldn't get git tag:", sys.exc_info()[0])
82 |
83 | # read version
84 | VERSION = sublime.load_settings('Default.sublime-settings').get('gorename_version')
85 | log("version:", VERSION)
86 |
87 | # check if user setting exists and creates it
88 | us = sublime.load_settings("GoRename.sublime-settings")
89 | if (not us.has('gorename_debug')):
90 | us.set('gorename_debug', DEBUG)
91 | sublime.save_settings("GoRename.sublime-settings")
92 |
93 | class GoRenameCommand(sublime_plugin.TextCommand):
94 | def __init__(self, view):
95 | self.view = view
96 | # ...
97 | def run(self, edit, simulate=False, force=False, verbose=False):
98 |
99 | try:
100 | current_selection = self.view.sel()
101 | region = current_selection[0]
102 | text = self.view.substr(sublime.Region(0, region.end()))
103 | cb_map = self.get_map(text)
104 | byte_end = cb_map[sorted(cb_map.keys())[-1]]
105 | byte_begin = None
106 |
107 | if not region.empty():
108 | byte_begin = cb_map[region.begin()-1]
109 | else:
110 | byte_begin = byte_end
111 | except:
112 | sublime.error_message('GoRename:\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.')
113 | error("couldn't cursor position: ", sys.exc_info()[0])
114 |
115 | word = self.view.substr(self.view.word(region.begin())).rstrip()
116 | position = self.view.rowcol(region.begin())
117 | line_number = position[0]+1
118 | del position
119 | line_string = self.view.substr(self.view.line(region))
120 |
121 |
122 |
123 | # TODO: improve preliminary identifier validation
124 | if len(word) == 0:
125 | self.view.show_popup('Gorename:
Invalid identifier:\nno identifier here.')
126 | return
127 |
128 | message = 'Running GoRename %s:\nFrom %s to %s\n[Line Number: %s][Byte Offset: %s]\nFlags: %s\nReference:\n%s'
129 |
130 | global s, f, v, flags
131 | s = simulate
132 | f = force
133 | v = verbose
134 | flags = ''
135 |
136 | def compile_flags(only_enabled=False): # and construct flags argument
137 | compiled_flags_array = []
138 | enabledTitle = 'ENABLED: '
139 | if only_enabled:
140 | enabledTitle = ''
141 | global flags
142 |
143 | # reset
144 | flags = ''
145 |
146 | if s:
147 | compiled_flags_array.append(enabledTitle+'Simulate (-d)')
148 | flags = '-d '
149 | elif not only_enabled:
150 | compiled_flags_array.append('DISABLED: Simulate (-d)')
151 |
152 | if f:
153 | compiled_flags_array.append(enabledTitle+'force (-force)')
154 | flags = flags + '-force '
155 | elif not only_enabled:
156 | compiled_flags_array.append('DISABLED: force (-force)')
157 |
158 | if v:
159 | compiled_flags_array.append(enabledTitle+'verbose (-v)')
160 | flags = flags + '-v'
161 | elif not only_enabled:
162 | compiled_flags_array.append('DISABLED: verbose (-v)')
163 | return compiled_flags_array
164 |
165 | def rename_name_input(name):
166 | debug('flags:', flags)
167 |
168 | global renameMe
169 | renameMe['compiled_message'] = message % ('%s',
170 | word.replace('%', '%%'),
171 | name.replace('%', '%%'),
172 | line_number,
173 | byte_begin,
174 | str(compile_flags(True)).replace('%', '%%'),
175 | line_string.replace('%', '%%'),
176 | )
177 | self.write_running(renameMe['compiled_message'] % ('[press ENTER to continue]'), True, True)
178 | renameMe['offset'] = byte_begin
179 | renameMe['name'] = name
180 | renameMe['flags'] = flags
181 | renameMe['file_path'] = self.view.file_name()
182 | renameMe['checksum'] = hashlib.sha256(open(renameMe['file_path'],'rb').read()).hexdigest()
183 |
184 | def popup_menu_callback(flag_opt):
185 | global s,f,v
186 | if flag_opt == 0:
187 | s = not s
188 | elif flag_opt == 1:
189 | f = not f
190 | elif flag_opt == 2:
191 | v = not v
192 | if flag_opt != -1:
193 | pop_menu()
194 | else:
195 | varName = ''
196 | if get_setting("gorename_autofill", False):
197 | varName = word
198 | self.view.window().show_input_panel('GoRename: rename "%s" (from line %s) to' % (word, line_number), varName, rename_name_input, on_change=None, on_cancel=None)
199 |
200 | def pop_menu():
201 | self.view.show_popup_menu(compile_flags(), popup_menu_callback)
202 |
203 | pop_menu()
204 |
205 |
206 |
207 | def gorename_complete(self, out, err, focus=False):
208 | self.write_out(out, err)
209 |
210 | def write_running(self, content, readonly=False, focus=False):
211 | """ Write the "Running..." header to a new file and focus it to get results
212 | """
213 |
214 | #window = self.view.window()
215 | window = sublime.active_window()
216 | view = get_output_view(window)
217 | view.set_read_only(False)
218 |
219 | # Run a new command to use the edit object for this view.
220 | view.run_command('go_rename_write_running', {'content': content})
221 |
222 | if get_setting("gorename_output", "buffer") == "output_panel":
223 | window.run_command('show_panel', {'panel': "output." + view.name() })
224 | else:
225 | window.focus_view(view)
226 |
227 | view.set_read_only(readonly)
228 |
229 | # focus no matter what
230 | if focus:
231 | window.focus_view(view)
232 |
233 | def write_out(self, result, err):
234 |
235 | """ Write the gorename output to a new file.
236 | """
237 |
238 | #window = self.view.window()
239 | window = sublime.active_window()
240 | view = get_output_view(window)
241 |
242 | # Run a new command to use the edit object for this view.
243 | view.run_command('go_rename_write_results', {
244 | 'result': result,
245 | 'err': err})
246 |
247 | if get_setting("gorename_output", "buffer") == "output_panel":
248 | window.run_command('show_panel', {'panel': "output." + view.name() })
249 | else:
250 | window.focus_view(view)
251 |
252 | def get_map(self, chars):
253 | """ Generate a map of character offset to byte offset for the given string 'chars'.
254 | """
255 |
256 | byte_offset = 0
257 | cb_map = {}
258 |
259 | for char_offset, char in enumerate(chars):
260 | cb_map[char_offset] = byte_offset
261 | byte_offset += len(char.encode('utf-8'))
262 | if char == '\n' and self.view.line_endings() == "Windows":
263 | byte_offset += 1
264 | return cb_map
265 |
266 | def gorename(self, file_path, begin_offset=None, flags=None, name=None, callback=None):
267 | """ Builds the gorename shell command and calls it, returning it's output as a string.
268 | """
269 |
270 | global runningTool
271 | runningTool = True
272 |
273 | pos = "#" + str(begin_offset)
274 |
275 | # golangconfig or shellenv ?
276 | cmd_env = ''
277 | if use_golangconfig:
278 | try:
279 | toolpath, cmd_env = golangconfig.subprocess_info('gorename', ['GOPATH', 'PATH'], view=self.view)
280 | toolpath = os.path.realpath(toolpath)
281 | except:
282 | error("golangconfig:", sys.exc_info())
283 | return
284 | else:
285 | toolpath = 'gorename'
286 | cmd_env = shellenv.get_env(for_subprocess=True)[1]
287 | cmd_env.update(get_setting("gorename_env", {}))
288 |
289 | debug("env", cmd_env)
290 |
291 | gorename_json = ""
292 | if get_setting("gorename_json", False):
293 | gorename_json = "-json"
294 |
295 | # Build gorename cmd.
296 | cmd = "%(toolpath)s -offset \"%(file_path)s:%(pos)s\" -to %(name)s %(flags)s" % {
297 | "toolpath": toolpath,
298 | "file_path": os.path.realpath(file_path),
299 | "pos": pos,
300 | "name": name,
301 | "flags": flags}
302 |
303 | debug("cmd", cmd)
304 |
305 | sublime.set_timeout_async(lambda: self.runInThread(cmd, callback, cmd_env), 0)
306 |
307 | def runInThread(self, cmd, callback, env):
308 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True, env=env)
309 | out, err = proc.communicate()
310 | callback(out.decode('utf-8'), err.decode('utf-8'))
311 | global runningTool
312 | runningTool = False
313 |
314 | class GoRenameConfirmCommand(sublime_plugin.TextCommand):
315 | """ Writes the gorename output to the current view.
316 | """
317 |
318 | def run(self, edit):
319 | global renameMe
320 | #view = self.view
321 | debug('Stored rename parameters:', renameMe)
322 | # check that the referenced file hasn't changed
323 |
324 | if (len(renameMe)==0):
325 | sublime.error_message("Invalid GoRename parameters")
326 | if (runningTool == False):
327 | if ((hashlib.sha256(open(renameMe['file_path'],'rb').read()).hexdigest() != renameMe['checksum']) and (get_setting('gorename_rename_modified_files', False) == False)):
328 | sublime.error_message("Couldn't execute gorename, the referenced file has changed, please start over.")
329 | # reset renameMe
330 | renameMe = {}
331 | else:
332 | GR = GoRenameCommand(self)
333 | GR.write_running(renameMe['compiled_message'] % ('[Running...]'), True, True)
334 | GR.gorename(file_path=renameMe['file_path'] ,begin_offset=renameMe['offset'], name=renameMe['name'], flags=renameMe['flags'], callback=GR.gorename_complete)
335 | # reset renameMe
336 | renameMe = {}
337 | else:
338 | sublime.message_dialog("GoRename tool already executing")
339 |
340 |
341 |
342 | class GoRenameWriteResultsCommand(sublime_plugin.TextCommand):
343 | """ Writes the gorename output to the current view.
344 | """
345 |
346 | def run(self, edit, result, err):
347 | view = self.view
348 |
349 | view.set_read_only(False)
350 |
351 | if result:
352 | view.insert(edit, view.size(), result)
353 | if err:
354 | errLen = view.insert(edit, view.size(), err)
355 |
356 | view.set_read_only(True)
357 |
358 | # reset
359 | global renameMe
360 | renameMe = {}
361 |
362 |
363 | class GoRenameWriteRunningCommand(sublime_plugin.TextCommand):
364 | """ Writes the gorename output to the current view.
365 | """
366 |
367 | def run(self, edit, content):
368 | view = self.view
369 |
370 | view.set_viewport_position(view.text_to_layout(view.size() - 1))
371 | view.insert(edit, view.size(), content)
372 |
373 |
374 | class GoRenameShowResultsCommand(sublime_plugin.TextCommand):
375 | def run(self, edit):
376 | if get_setting("gorename_output", "buffer") == "output_panel":
377 | self.view.window().run_command('show_panel', {'panel': "output.GoRename Output" })
378 | else:
379 | output_view = get_output_view(self.view.window())
380 | self.view.window().focus_view(output_view)
381 |
382 |
383 | class GoRenameOpenResultCommand(sublime_plugin.EventListener):
384 |
385 | '''
386 | def on_modification(self, view):
387 | if view.name() == "GoRename Output":
388 | log("on modif")
389 | '''
390 |
391 | def on_selection_modified(self, view):
392 | if view.name() == "GoRename Output":
393 | if len(view.sel()) != 1:
394 | return
395 | if view.sel()[0].size() == 0:
396 | return
397 |
398 | lines = view.lines(view.sel()[0])
399 | if len(lines) != 1:
400 | return
401 |
402 | line = view.full_line(lines[0])
403 | text = view.substr(line)
404 |
405 | format = get_setting("gorename_format")
406 |
407 | # "filename:line:col" pattern for json
408 | m = re.search("\"([^\"]+):([0-9]+):([0-9]+)\"", text)
409 |
410 | # >filename:line:col< pattern for xml
411 | if m == None:
412 | m = re.search(">([^<]+):([0-9]+):([0-9]+)<", text)
413 |
414 | # filename:line.col-line.col: pattern for plain
415 | if m == None:
416 | m = re.search("^([^:]+):([0-9]+).([0-9]+)[-: ]", text)
417 |
418 | if m:
419 | w = view.window()
420 | new_view = w.open_file(m.group(1) + ':' + m.group(2) + ':' + m.group(3), sublime.ENCODED_POSITION)
421 | group, index = w.get_view_index(new_view)
422 | if group != -1:
423 | w.focus_group(group)
424 |
425 |
426 | def get_output_view(window):
427 | view = None
428 | buff_name = 'GoRename Output'
429 |
430 | if get_setting("gorename_output", "buffer") == "output_panel":
431 | view = window.create_output_panel(buff_name)
432 | else:
433 | # If the output file is already open, use that.
434 | for v in window.views():
435 | if v.name() == buff_name:
436 | view = v
437 | break
438 | # Otherwise, create a new one.
439 | if view is None:
440 | view = window.new_file()
441 |
442 | view.set_name(buff_name)
443 | view.set_scratch(True)
444 | view_settings = view.settings()
445 | view_settings.set('line_numbers', False)
446 | view.set_syntax_file('Packages/GoRename/GoRenameResults.tmLanguage')
447 |
448 | return view
449 |
450 | def get_setting(key, default=None):
451 | """ Returns the setting in the following hierarchy: project setting, user setting,
452 | default setting. If none are set the 'default' value passed in is returned.
453 | """
454 |
455 | val = None
456 | try:
457 | val = sublime.active_window().active_view().settings().get('GoRename', {}).get(key)
458 | except AttributeError:
459 | pass
460 |
461 | if not val:
462 | val = sublime.load_settings("GoRename.sublime-settings").get(key)
463 | if not val:
464 | val = sublime.load_settings("Default.sublime-settings").get(key)
465 | if not val:
466 | val = default
467 | return val
--------------------------------------------------------------------------------