-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
some changes to make it work like Emacs vertical file completion. #185
base: master
Are you sure you want to change the base?
Changes from 1 commit
c6c13fd
988b8a5
9066872
c4dcae7
26a17b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,5 +8,17 @@ | |
"context": [{ | ||
"key": "setting.anf_panel" | ||
}] | ||
} | ||
}, | ||
{"keys": ["ctrl+n"],"command": "advanced_new_file_next", | ||
"context": [{"key": "setting.anf_panel"}] | ||
}, | ||
{"keys": ["ctrl+p"],"command": "advanced_new_file_prev", | ||
"context": [{"key": "setting.anf_panel"}] | ||
}, | ||
{"keys": ["ctrl+l"],"command": "advanced_new_file_updir", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why L? Is that how emacs does it? Please add some comments above the binding to explain their inspiration because I (for example) wouldn't know otherwise. Probably to the readme as well. |
||
"context": [{"key": "setting.anf_panel"}] | ||
}, | ||
{"keys": ["ctrl+j"],"command": "insert", "args": {"characters": "\t"}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose this is how tab completion works currently, but I find that questionable when you could instead bind the tab key to a proper command instead. |
||
"context": [{"key": "setting.anf_panel"}] | ||
}, | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,25 +12,25 @@ Note with either method, you may need to restart Sublime Text 2 for the plugin t | |
Installation through [package control](http://wbond.net/sublime_packages/package_control) is recommended. It will handle updating your packages as they become available. To install, do the following. | ||
|
||
* In the Command Palette, enter `Package Control: Install Package` | ||
* Search for `ANF` to see the list of available commands | ||
* Search for `AdvancedNewFile` | ||
|
||
### Manual | ||
Clone or copy this repository into the packages directory. You will need to rename the folder to `AdvancedNewFile` if using this method. By default, the Package directory is located at: | ||
|
||
* OS X: ~/Library/Application Support/Sublime Text 2/Packages/ | ||
* Windows: %APPDATA%/Sublime Text 2/Packages/ | ||
* Windows: %APPDATA%/Roaming/Sublime Text 2/Packages/ | ||
* Linux: ~/.config/sublime-text-2/Packages/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This commit removed ST2 (and Python 2.6) support by changing the |
||
|
||
or | ||
|
||
* OS X: ~/Library/Application Support/Sublime Text 3/Packages/ | ||
* Windows: %APPDATA%/Sublime Text 3/Packages/ | ||
* Windows: %APPDATA%/Roaming/Sublime Text 3/Packages/ | ||
* Linux: ~/.config/sublime-text-3/Packages/ | ||
|
||
Depending on your install on windows, the ST packages path may be `%APPDATA%/Sublime Text 2/...` | ||
|
||
## Usage | ||
Simply bring up the AdvancedNewFile input through the appropriate [key binding](https://github.com/skuroda/Sublime-AdvancedNewFile#keymaps). Then, enter the path, along with the file name into the input field. Upon pressing enter, the file will be created. In addition, if the directories specified do not yet exists, they will also be created. For more advanced usage of this plugin, be sure to look at [Advanced Path Usage](https://github.com/skuroda/Sublime-AdvancedNewFile#advanced-path-usage). By default, the path to the file being created will be filled shown in the status bar as you enter the path information. | ||
Simply bring up the AdvancedNewFile input through the appropriate [key binding](https://github.com/skuroda/Sublime-AdvancedNewFile). Then, enter the path, along with the file name into the input field. Upon pressing enter, the file will be created. In addition, if the directories specified do not yet exists, they will also be created. For more advanced usage of this plugin, be sure to look at [Advanced Path Usage](https://github.com/skuroda/Sublime-AdvancedNewFile#advanced-path-usage). By default, the path to the file being created will be filled shown in the status bar as you enter the path information. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the "key binding" link supposed to point to? (needs to be updated for the repo move, too) A mention of the command palette would also be nice. |
||
|
||
**Default directory:** | ||
The default directory is specified by the `default_root` setting. By default, it will be the top directory of the folders listed in the window. If this cannot be resolved, the home directory will be used. See [Settings](https://github.com/skuroda/Sublime-AdvancedNewFile#settings) (`default_root`) for more information. | ||
|
@@ -233,7 +233,7 @@ To begin at the home directory simply start with `~/` like you would in the shel | |
#### Aliases: | ||
You can create an alias to quickly navigate to a directory. Simply type in the alias followed by a colon. Then specify the path as you would normally. Note, in an event a specified alias conflicts with a [predefined alias](https://github.com/skuroda/Sublime-AdvancedNewFile#predefined-aliases), the specified alias will take precedence. | ||
|
||
Alias paths may be relative or absolute. If a relative path is specified, the `alias_root` setting will be used as the base. When specifying absolute paths, be sure to use the system specific style (e.g. Windows `C:\\Users\\username\\Desktop`, OS X and Linux `/home/username/desktop/`). In addition, you may specify an alias from the home directory by using `~/`. | ||
Alias paths may be relative or absolute. If a relative path is specified, the `alias_root` setting will be used as the base. When specifying absolute paths, be sure to use the system specific style (e.g. Windows `C:\\Users\\username\\Desktop`, OS X and Linix `/home/username/desktop/`). In addition, you may specify an alias from the home directory by using `~/`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This introduced a typo. |
||
|
||
If an invalid alias is specified, an error pop up will be displayed when trying to create the file. | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
import sublime | ||
import sublime_plugin | ||
import shlex | ||
import json | ||
|
||
from ..anf_util import * | ||
from ..platform.windows_platform import WindowsPlatform | ||
|
@@ -22,9 +23,12 @@ | |
|
||
|
||
class AdvancedNewFileBase(object): | ||
static_input_panel_view = None | ||
FichteFoll marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def __init__(self, window): | ||
super(AdvancedNewFileBase, self).__init__(window) | ||
super() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No-op. Can be removed or replaced with |
||
self.window = window | ||
self.prev_text = None | ||
|
||
if PLATFORM == "windows": | ||
self.platform = WindowsPlatform(window.active_view()) | ||
|
@@ -91,9 +95,10 @@ def run_setup(self): | |
def __get_aliases(self): | ||
aliases = self.settings.get(ALIAS_SETTING) | ||
all_os_aliases = self.settings.get(OS_SPECIFIC_ALIAS_SETTING) | ||
for key in all_os_aliases: | ||
if PLATFORM in all_os_aliases.get(key): | ||
aliases[key] = all_os_aliases.get(key).get(PLATFORM) | ||
if all_os_aliases is not None and aliases is not None: | ||
for key in all_os_aliases: | ||
if PLATFORM in all_os_aliases.get(key): | ||
aliases[key] = all_os_aliases.get(key).get(PLATFORM) | ||
|
||
return aliases | ||
|
||
|
@@ -281,28 +286,53 @@ def show_filename_input(self, initial): | |
self.input_panel_view.settings().set("anf_panel", True) | ||
if self.settings.get(CURSOR_BEFORE_EXTENSION_SETTING): | ||
self.__place_cursor_before_extension(self.input_panel_view) | ||
AdvancedNewFileBase.static_input_panel_view = self.input_panel_view | ||
self.__update_filename_input('') | ||
|
||
def __update_filename_input(self, path_in): | ||
new_content = path_in | ||
if self.settings.get(COMPLETION_TYPE_SETTING) == "windows": | ||
if "prev_text" in dir(self) and self.prev_text != path_in: | ||
if self.view is not None: | ||
self.view.erase_status("AdvancedNewFile2") | ||
|
||
if path_in.endswith("\t"): | ||
new_content = self.completion.completion(path_in.replace("\t", "")) | ||
if new_content != path_in: | ||
self.input_panel_view.run_command("anf_replace", | ||
{"content": new_content}) | ||
creation_path, candidate, completion_list = self.parse_status_line(self.get_status_line()) # type: ignore | ||
print("candidate", candidate, str(completion_list)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Debug prints. |
||
new_content = self.completion_input(path_in.replace("\t", ""), candidate) | ||
print("new_content", new_content) | ||
# new_content = candidate | ||
else: | ||
base, path = self.split_path(path_in) | ||
completion_list = self.completion.hint(path_in) | ||
if completion_list: | ||
candidate = completion_list[0] | ||
completion_list.remove(candidate) | ||
else: | ||
candidate = '' | ||
|
||
creation_path = generate_creation_path(self.settings, base, path, | ||
True) | ||
input_view = AdvancedNewFileBase.static_input_panel_view | ||
if input_view: | ||
input_view.hide_popup() | ||
if input_view and new_content != path_in: | ||
input_view.run_command("anf_replace", {"content": new_content}) | ||
else: | ||
base, path = self.split_path(path_in) | ||
status_line = generate_creation_path(self.settings, base, path, True) + '|' + candidate + str(completion_list) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand this format. What is the purpose? |
||
if self.settings.get(SHOW_PATH_SETTING, False): | ||
self.update_status_message(creation_path) | ||
self.update_status_message(status_line) | ||
if input_view and candidate and not new_content.endswith(candidate): | ||
input_view.show_popup('<strong>' + candidate + '</strong><br/>' + '<br/>'.join(completion_list)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You may be interested to know that normal completions as in the auto-complete popup should also be working in input panels, though that is probably something for later. It might only work for ST4 though, iirc. Could even make use of the async completion provider API because of having to query the filesystem. |
||
|
||
def update_status_message(self, creation_path): | ||
pass | ||
def completion_input(self, path_in, candidate): | ||
pattern = r"(.*[/\\:])(.*)" | ||
|
||
match = re.match(pattern, path_in) | ||
if match: | ||
new_content = re.sub(pattern, r"\1", path_in) | ||
new_content += candidate | ||
else: | ||
new_content = candidate | ||
return new_content | ||
|
||
def entered_file_action(self, path): | ||
pass | ||
|
@@ -364,6 +394,7 @@ def clear(self): | |
if self.view is not None: | ||
self.view.erase_status("AdvancedNewFile") | ||
self.view.erase_status("AdvancedNewFile2") | ||
AdvancedNewFileBase.static_input_panel_view = None | ||
|
||
def create(self, filename): | ||
base, filename = os.path.split(filename) | ||
|
@@ -466,3 +497,70 @@ def __place_cursor_before_extension(self, view): | |
initial_position = len(matcher.group(1)) | ||
cursors.clear() | ||
cursors.add(sublime.Region(initial_position, initial_position)) | ||
|
||
def get_status_line(self): | ||
return self.view.get_status("AdvancedNewFile") | ||
|
||
def update_status_message(self, creation_path): | ||
if self.view is not None: | ||
self.view.set_status("AdvancedNewFile", creation_path) | ||
else: | ||
sublime.status_message(creation_path) | ||
|
||
def get_status_prefix(self): | ||
pass | ||
|
||
def create_status_line(self, creation_path, candidate, completion_list): | ||
return creation_path + '|' + candidate + str(completion_list) | ||
|
||
def parse_status_line(self, status_line): | ||
# Creating file at AdvancedNewFile/advanced_new_file/commands/|__init__.py['command_base.py'] | ||
FichteFoll marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if status_line: | ||
status_line = status_line.strip() | ||
index1 = status_line.rindex('[') | ||
completion_list = status_line[index1:] | ||
try: | ||
completion_list = json.loads(completion_list.replace("'", '"')) | ||
except Exception as e: | ||
print("completion_list", completion_list, e) | ||
raise e | ||
index2 = status_line.rindex('|') | ||
candidate = status_line[index2 + 1:index1] | ||
# TODO: prefix_len = len(self.get_status_prefix()) | ||
creation_path = status_line[0:index2] | ||
return (creation_path, candidate, completion_list) | ||
else: | ||
return ('', '', []) | ||
|
||
def next_candidate(self, candidate, completion_list): | ||
if candidate and completion_list: | ||
# replace the candidate with the first, and append the old candidate to the last | ||
completion_list.append(candidate) | ||
candidate = completion_list[0] | ||
completion_list.remove(candidate) | ||
|
||
return (candidate, completion_list) | ||
|
||
def prev_candidate(self, candidate, completion_list): | ||
if candidate and completion_list: | ||
# replace the candidate with the last, and insert the old candidate to the first | ||
completion_list.insert(0, candidate) | ||
candidate = completion_list.pop() | ||
|
||
return (candidate, completion_list) | ||
|
||
def create_next_status_line(self, creation_path, candidate, completion_list): | ||
if candidate and completion_list: | ||
candidate, completion_list = self.next_candidate(candidate, completion_list) | ||
return self.create_status_line(creation_path, candidate, completion_list) | ||
else: | ||
# case1: origin completion_list is empty. case2: origin completion_list contains only 1 item | ||
sublime.status_message("Completion list is empty.") | ||
|
||
def create_prev_status_line(self, creation_path, candidate, completion_list): | ||
if candidate and completion_list: | ||
candidate, completion_list = self.prev_candidate(candidate, completion_list) | ||
return self.create_status_line(creation_path, candidate, completion_list) | ||
else: | ||
# case1: origin completion_list is empty. case2: origin completion_list contains only 1 item | ||
sublime.status_message("Completion list is empty.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first I questioned why the setting was removed, but in hindsight it never made it into a release (a5f062b), the name is questionable, I'm not sure if the code even works, and the behavior is somewhat as well, though I can see the appeal. Regardless, the opposite should have been the default.
A mention of that in the commit message (and having it in a separate comment) would have been nice, though.