2 * (C) Copyright 2008 Jeremy Maitin-Shepard
3 * (C) Copyright 2008 Nelson Elhage
4 * (C) Copyright 2012-2013 John J. Foerch
6 * Use, modification, and distribution are subject to the terms specified in the
11 require("completers.js");
14 function directory_p (file) {
15 return file.exists() && file.isDirectory();
18 function separator_p (s) {
19 return s == "/" || (WINDOWS && s == "\\");
23 function file_path_completions (completer, data, common_prefix, suffix) {
24 completions.call(this, completer, data);
25 this.common_prefix = common_prefix;
28 file_path_completions.prototype = {
29 constructor: file_path_completions,
30 __proto__: completions.prototype,
31 toString: function () "#<file_path_completions>",
34 get_string: function (i) this.data[i].path,
35 get_input_state: function (i) {
36 var s = this.get_string(i);
37 if (this.data[i].isDirectory() &&
39 ! separator_p(this.suffix[0])))
44 return [s + this.suffix, sel, sel];
46 get common_prefix_input_state () {
47 if (this.count == 1) {
48 var prefix = this.get_string(0);
49 if (this.data[0].isDirectory())
52 prefix = this.common_prefix;
54 var i = prefix.length;
55 return [prefix, i, i];
60 define_keywords("$test");
61 function file_path_completer () {
62 keywords(arguments, $test = constantly(true));
64 this.test = arguments.$test;
66 file_path_completer.prototype = {
67 constructor: file_path_completer,
68 __proto__: completer.prototype,
69 toString: function () "#<file_path_completer>",
71 complete: function (input, pos) {
72 var s = input.substring(0, pos);
73 var suffix = input.substring(pos);
77 if (separator_p(s.substr(pos - 1, 1))) {
87 var iter = dir.directoryEntries;
88 while (iter.hasMoreElements()) {
89 var e = iter.getNext().QueryInterface(Ci.nsIFile);
90 if (e.leafName.substr(0, ll) == leaf &&
99 entries.sort(function (a, b) {
108 var first = entries[0].path;
109 var last = entries[entries.length - 1].path;
110 var cpi = common_prefix_length(first, last);
111 var common_prefix = first.substring(0, cpi);
112 return new file_path_completions(this, entries, common_prefix, suffix);
117 /* keywords: $prompt, $initial_value, $history, $completer, $auto_complete */
118 minibuffer.prototype.read_file_path = function () {
121 $initial_value = cwd.path,
124 var result = yield this.read(
125 $completer = arguments.$completer || new file_path_completer(),
126 forward_keywords(arguments),
128 yield co_return(result);
131 minibuffer.prototype.read_file = function () {
132 var result = yield this.read_file_path(forward_keywords(arguments));
133 yield co_return(make_file(result));
136 minibuffer.prototype.read_existing_file = function () {
137 function validator (x) {
139 return make_file(x).exists();
144 var result = yield this.read_file_path(
145 forward_keywords(arguments),
146 $validator = validator);
147 yield co_return(result);
150 //XXX: why '_path' instead of just 'read_directory' returning an nsIFile?
151 minibuffer.prototype.read_directory_path = function () {
152 function validator (x) {
154 var f = make_file(x);
155 return !f.exists() || f.isDirectory();
160 var result = yield this.read_file_path(
161 forward_keywords(arguments),
162 $completer = new file_path_completer($test = directory_p),
163 $validator = validator); //XXX: overridden by read_existing_directory_path?
164 yield co_return(result);
167 //XXX: why '_path' instead of just 'read_existing_directory' returning an nsIFile?
168 minibuffer.prototype.read_existing_directory_path = function () {
169 function validator (x) {
171 return directory_p(make_file(x));
176 var result = yield this.read_directory_path(
177 forward_keywords(arguments),
178 $validator = validator);
179 yield co_return(result);
182 minibuffer.prototype.read_file_check_overwrite = function () {
184 var initial_value = arguments.$initial_value;
186 var path = yield this.read_file_path(forward_keywords(arguments),
187 $initial_value = initial_value);
188 var file = make_file(path);
190 var overwrite = yield this.read_yes_or_no(
191 $prompt = "Overwrite existing file " + path + "?");
193 initial_value = path;
197 yield co_return(file);
201 provide("minibuffer-read-file");