Skip to content

Commit c6c13fd

Browse files
committed
some changes to make it work like Emacs vertical file completion.
1 parent 416d26c commit c6c13fd

22 files changed

+388
-97
lines changed

AdvancedNewFile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
# Make sure all dependencies are reloaded on upgrade
1414
if reloader in sys.modules:
15-
reload(sys.modules[reloader])
15+
reload(sys.modules[reloader]) # type: ignore
1616

1717
if VERSION > 3000:
1818
from .advanced_new_file import reloader

AdvancedNewFile.sublime-settings

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@
1717
// A default initial value to fill the create new file input path with.
1818
"default_initial": "",
1919

20-
// When renaming a file it will we pre populated with the file existing filename.
21-
"autofill_path_the_existing": false,
22-
2320
// A boolean defining if cursor text should be used. Text bound by single or
2421
// double quotes or within a region will be used. If multiple cursors
2522
// are used, the earliest selection containing a region or existing

Default (Linux).sublime-keymap

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,17 @@
88
"context": [{
99
"key": "setting.anf_panel"
1010
}]
11-
}
11+
},
12+
{"keys": ["ctrl+n"],"command": "advanced_new_file_next",
13+
"context": [{"key": "setting.anf_panel"}]
14+
},
15+
{"keys": ["ctrl+p"],"command": "advanced_new_file_prev",
16+
"context": [{"key": "setting.anf_panel"}]
17+
},
18+
{"keys": ["ctrl+l"],"command": "advanced_new_file_updir",
19+
"context": [{"key": "setting.anf_panel"}]
20+
},
21+
{"keys": ["ctrl+j"],"command": "insert", "args": {"characters": "\t"},
22+
"context": [{"key": "setting.anf_panel"}]
23+
},
1224
]

Default (OSX).sublime-keymap

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,17 @@
88
"context": [{
99
"key": "setting.anf_panel"
1010
}]
11-
}
11+
},
12+
{"keys": ["ctrl+n"],"command": "advanced_new_file_next",
13+
"context": [{"key": "setting.anf_panel"}]
14+
},
15+
{"keys": ["ctrl+p"],"command": "advanced_new_file_prev",
16+
"context": [{"key": "setting.anf_panel"}]
17+
},
18+
{"keys": ["ctrl+l"],"command": "advanced_new_file_updir",
19+
"context": [{"key": "setting.anf_panel"}]
20+
},
21+
{"keys": ["ctrl+j"],"command": "insert", "args": {"characters": "\t"},
22+
"context": [{"key": "setting.anf_panel"}]
23+
},
1224
]

Default (Windows).sublime-keymap

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,17 @@
88
"context": [{
99
"key": "setting.anf_panel"
1010
}]
11-
}
11+
},
12+
{"keys": ["ctrl+n"],"command": "advanced_new_file_next",
13+
"context": [{"key": "setting.anf_panel"}]
14+
},
15+
{"keys": ["ctrl+p"],"command": "advanced_new_file_prev",
16+
"context": [{"key": "setting.anf_panel"}]
17+
},
18+
{"keys": ["ctrl+l"],"command": "advanced_new_file_updir",
19+
"context": [{"key": "setting.anf_panel"}]
20+
},
21+
{"keys": ["ctrl+j"],"command": "insert", "args": {"characters": "\t"},
22+
"context": [{"key": "setting.anf_panel"}]
23+
},
1224
]

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,25 @@ Note with either method, you may need to restart Sublime Text 2 for the plugin t
1212
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.
1313

1414
* In the Command Palette, enter `Package Control: Install Package`
15-
* Search for `ANF` to see the list of available commands
15+
* Search for `AdvancedNewFile`
1616

1717
### Manual
1818
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:
1919

2020
* OS X: ~/Library/Application Support/Sublime Text 2/Packages/
21-
* Windows: %APPDATA%/Sublime Text 2/Packages/
21+
* Windows: %APPDATA%/Roaming/Sublime Text 2/Packages/
2222
* Linux: ~/.config/sublime-text-2/Packages/
2323

2424
or
2525

2626
* OS X: ~/Library/Application Support/Sublime Text 3/Packages/
27-
* Windows: %APPDATA%/Sublime Text 3/Packages/
27+
* Windows: %APPDATA%/Roaming/Sublime Text 3/Packages/
2828
* Linux: ~/.config/sublime-text-3/Packages/
2929

3030
Depending on your install on windows, the ST packages path may be `%APPDATA%/Sublime Text 2/...`
3131

3232
## Usage
33-
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.
33+
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.
3434

3535
**Default directory:**
3636
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
233233
#### Aliases:
234234
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.
235235

236-
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 `~/`.
236+
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 `~/`.
237237

238238
If an invalid alias is specified, an error pop up will be displayed when trying to create the file.
239239

advanced_new_file/anf_util.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
ALIAS_SETTING = "alias"
66
DEFAULT_INITIAL_SETTING = "default_initial"
7-
AUTOFILL_RENAME = "autofill_path_the_existing"
87
USE_CURSOR_TEXT_SETTING = "use_cursor_text"
98
SHOW_FILES_SETTING = "show_files"
109
SHOW_PATH_SETTING = "show_path"
@@ -46,7 +45,6 @@
4645
SETTINGS = [
4746
ALIAS_SETTING,
4847
DEFAULT_INITIAL_SETTING,
49-
AUTOFILL_RENAME,
5048
USE_CURSOR_TEXT_SETTING,
5149
SHOW_FILES_SETTING,
5250
SHOW_PATH_SETTING,

advanced_new_file/commands/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .helper_commands import AnfReplaceCommand, AdvancedNewFileCommand, AnfRemoveRegionContentAndRegionCommand
2-
from .new_file_command import AdvancedNewFileNew, AdvancedNewFileNewAtCommand, AdvancedNewFileNewAtFileCommand, AdvancedNewFileNewEventListener
2+
from .new_file_command import AdvancedNewFileNew, AdvancedNewFileNextCommand, AdvancedNewFilePrevCommand, AdvancedNewFileUpdirCommand, AdvancedNewFileNewAtCommand, AdvancedNewFileNewAtFileCommand, AdvancedNewFileNewEventListener
33
from .delete_file_command import AdvancedNewFileDelete
44
from .cut_to_file import AdvancedNewFileCutToFile
55
from .move_file_command import AdvancedNewFileMove, AdvancedNewFileMoveAtCommand
@@ -9,6 +9,9 @@
99
"AnfReplaceCommand",
1010
"AdvancedNewFileCommand",
1111
"AdvancedNewFileNew",
12+
"AdvancedNewFileNextCommand",
13+
"AdvancedNewFilePrevCommand",
14+
"AdvancedNewFileUpdirCommand",
1215
"AdvancedNewFileNewAtCommand",
1316
"AdvancedNewFileNewAtFileCommand",
1417
"AdvancedNewFileNewEventListener",

advanced_new_file/commands/command_base.py

Lines changed: 112 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sublime
55
import sublime_plugin
66
import shlex
7+
import json
78

89
from ..anf_util import *
910
from ..platform.windows_platform import WindowsPlatform
@@ -22,9 +23,12 @@
2223

2324

2425
class AdvancedNewFileBase(object):
26+
static_input_panel_view = None
2527

2628
def __init__(self, window):
27-
super(AdvancedNewFileBase, self).__init__(window)
29+
super()
30+
self.window = window
31+
self.prev_text = None
2832

2933
if PLATFORM == "windows":
3034
self.platform = WindowsPlatform(window.active_view())
@@ -91,9 +95,10 @@ def run_setup(self):
9195
def __get_aliases(self):
9296
aliases = self.settings.get(ALIAS_SETTING)
9397
all_os_aliases = self.settings.get(OS_SPECIFIC_ALIAS_SETTING)
94-
for key in all_os_aliases:
95-
if PLATFORM in all_os_aliases.get(key):
96-
aliases[key] = all_os_aliases.get(key).get(PLATFORM)
98+
if all_os_aliases is not None and aliases is not None:
99+
for key in all_os_aliases:
100+
if PLATFORM in all_os_aliases.get(key):
101+
aliases[key] = all_os_aliases.get(key).get(PLATFORM)
97102

98103
return aliases
99104

@@ -281,28 +286,53 @@ def show_filename_input(self, initial):
281286
self.input_panel_view.settings().set("anf_panel", True)
282287
if self.settings.get(CURSOR_BEFORE_EXTENSION_SETTING):
283288
self.__place_cursor_before_extension(self.input_panel_view)
289+
AdvancedNewFileBase.static_input_panel_view = self.input_panel_view
290+
self.__update_filename_input('')
284291

285292
def __update_filename_input(self, path_in):
286293
new_content = path_in
287294
if self.settings.get(COMPLETION_TYPE_SETTING) == "windows":
288295
if "prev_text" in dir(self) and self.prev_text != path_in:
289296
if self.view is not None:
290297
self.view.erase_status("AdvancedNewFile2")
298+
291299
if path_in.endswith("\t"):
292-
new_content = self.completion.completion(path_in.replace("\t", ""))
293-
if new_content != path_in:
294-
self.input_panel_view.run_command("anf_replace",
295-
{"content": new_content})
300+
creation_path, candidate, completion_list = self.parse_status_line(self.get_status_line()) # type: ignore
301+
print("candidate", candidate, str(completion_list))
302+
new_content = self.completion_input(path_in.replace("\t", ""), candidate)
303+
print("new_content", new_content)
304+
# new_content = candidate
296305
else:
297-
base, path = self.split_path(path_in)
306+
completion_list = self.completion.hint(path_in)
307+
if completion_list:
308+
candidate = completion_list[0]
309+
completion_list.remove(candidate)
310+
else:
311+
candidate = ''
298312

299-
creation_path = generate_creation_path(self.settings, base, path,
300-
True)
313+
input_view = AdvancedNewFileBase.static_input_panel_view
314+
if input_view:
315+
input_view.hide_popup()
316+
if input_view and new_content != path_in:
317+
input_view.run_command("anf_replace", {"content": new_content})
318+
else:
319+
base, path = self.split_path(path_in)
320+
status_line = generate_creation_path(self.settings, base, path, True) + '|' + candidate + str(completion_list)
301321
if self.settings.get(SHOW_PATH_SETTING, False):
302-
self.update_status_message(creation_path)
322+
self.update_status_message(status_line)
323+
if input_view and candidate and not new_content.endswith(candidate):
324+
input_view.show_popup('<strong>' + candidate + '</strong><br/>' + '<br/>'.join(completion_list))
303325

304-
def update_status_message(self, creation_path):
305-
pass
326+
def completion_input(self, path_in, candidate):
327+
pattern = r"(.*[/\\:])(.*)"
328+
329+
match = re.match(pattern, path_in)
330+
if match:
331+
new_content = re.sub(pattern, r"\1", path_in)
332+
new_content += candidate
333+
else:
334+
new_content = candidate
335+
return new_content
306336

307337
def entered_file_action(self, path):
308338
pass
@@ -364,6 +394,7 @@ def clear(self):
364394
if self.view is not None:
365395
self.view.erase_status("AdvancedNewFile")
366396
self.view.erase_status("AdvancedNewFile2")
397+
AdvancedNewFileBase.static_input_panel_view = None
367398

368399
def create(self, filename):
369400
base, filename = os.path.split(filename)
@@ -466,3 +497,70 @@ def __place_cursor_before_extension(self, view):
466497
initial_position = len(matcher.group(1))
467498
cursors.clear()
468499
cursors.add(sublime.Region(initial_position, initial_position))
500+
501+
def get_status_line(self):
502+
return self.view.get_status("AdvancedNewFile")
503+
504+
def update_status_message(self, creation_path):
505+
if self.view is not None:
506+
self.view.set_status("AdvancedNewFile", creation_path)
507+
else:
508+
sublime.status_message(creation_path)
509+
510+
def get_status_prefix(self):
511+
pass
512+
513+
def create_status_line(self, creation_path, candidate, completion_list):
514+
return creation_path + '|' + candidate + str(completion_list)
515+
516+
def parse_status_line(self, status_line):
517+
# Creating file at AdvancedNewFile/advanced_new_file/commands/|__init__.py['command_base.py']
518+
if status_line:
519+
status_line = status_line.strip()
520+
index1 = status_line.rindex('[')
521+
completion_list = status_line[index1:]
522+
try:
523+
completion_list = json.loads(completion_list.replace("'", '"'))
524+
except Exception as e:
525+
print("completion_list", completion_list, e)
526+
raise e
527+
index2 = status_line.rindex('|')
528+
candidate = status_line[index2 + 1:index1]
529+
# TODO: prefix_len = len(self.get_status_prefix())
530+
creation_path = status_line[0:index2]
531+
return (creation_path, candidate, completion_list)
532+
else:
533+
return ('', '', [])
534+
535+
def next_candidate(self, candidate, completion_list):
536+
if candidate and completion_list:
537+
# replace the candidate with the first, and append the old candidate to the last
538+
completion_list.append(candidate)
539+
candidate = completion_list[0]
540+
completion_list.remove(candidate)
541+
542+
return (candidate, completion_list)
543+
544+
def prev_candidate(self, candidate, completion_list):
545+
if candidate and completion_list:
546+
# replace the candidate with the last, and insert the old candidate to the first
547+
completion_list.insert(0, candidate)
548+
candidate = completion_list.pop()
549+
550+
return (candidate, completion_list)
551+
552+
def create_next_status_line(self, creation_path, candidate, completion_list):
553+
if candidate and completion_list:
554+
candidate, completion_list = self.next_candidate(candidate, completion_list)
555+
return self.create_status_line(creation_path, candidate, completion_list)
556+
else:
557+
# case1: origin completion_list is empty. case2: origin completion_list contains only 1 item
558+
sublime.status_message("Completion list is empty.")
559+
560+
def create_prev_status_line(self, creation_path, candidate, completion_list):
561+
if candidate and completion_list:
562+
candidate, completion_list = self.prev_candidate(candidate, completion_list)
563+
return self.create_status_line(creation_path, candidate, completion_list)
564+
else:
565+
# case1: origin completion_list is empty. case2: origin completion_list contains only 1 item
566+
sublime.status_message("Completion list is empty.")

advanced_new_file/commands/copy_file_command.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class AdvancedNewFileCopy(DuplicateFileBase):
1010
def __init__(self, window):
11-
super(AdvancedNewFileCopy, self).__init__(window)
11+
super().__init__(window)
1212

1313
def get_default_setting(self):
1414
return COPY_DEFAULT_SETTING

0 commit comments

Comments
 (0)