diff --git a/LICENSE-MIT b/LICENSE-MIT
index ee2fcf7..72289bb 100644
--- a/LICENSE-MIT
+++ b/LICENSE-MIT
@@ -1,4 +1,4 @@
-Copyright (c) 2015 anseki
+Copyright (c) 2016 anseki
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/README.md b/README.md
index a7655b7..95f775c 100644
--- a/README.md
+++ b/README.md
@@ -1445,10 +1445,68 @@ If `true` is specified, a string like `'[1...5]'` as guide for the user is added
##### `cancel`
-*Type:* boolean
-*Default:* `true`
+*Type:* boolean, string or others
+*Default:* `'CANCEL'`
-If `true` is specified, an item to let the user tell "cancel" is added to the item list. "[0] CANCEL" is displayed, and if `0` key is pressed, `-1` is returned.
+If a value other than `false` is specified, an item to let the user tell "cancel" is added to the item list. "[0] CANCEL" (default) is displayed, and if `0` key is pressed, `-1` is returned.
+You can specify a label of this item other than `'CANCEL'`. A string such as `'Go back'` (empty string `''` also), something that is converted to string such as `Date`, a string that includes [placeholder](#placeholders) such as `'Next ${itemsCount} items'` are accepted.
+
+#### Additional Placeholders
+
+The following additional [placeholder](#placeholders) parameters are available.
+
+##### `itemsCount`
+
+A length of a current `items` Array.
+
+For example:
+
+```js
+items = ['item-A', 'item-B', 'item-C', 'item-D', 'item-E'];
+index = readlineSync.keyInSelect(items, null,
+ {cancel: 'Show more items than ${itemsCount}'});
+```
+
+```console
+[1] item-A
+[2] item-B
+[3] item-C
+[4] item-D
+[5] item-E
+[0] Show more items than 5
+```
+
+##### `firstItem`
+
+A first item in a current `items` Array.
+
+For example:
+
+```js
+index = readlineSync.keyInSelect(items, 'Choose ${firstItem} or another :');
+```
+
+##### `lastItem`
+
+A last item in a current `items` Array.
+
+For example:
+
+```js
+items = ['January', 'February', 'March', 'April', 'May', 'June'];
+index = readlineSync.keyInSelect(items, null,
+ {cancel: 'In after ${lastItem}'});
+```
+
+```console
+[1] January
+[2] February
+[3] March
+[4] April
+[5] May
+[6] June
+[0] In after June
+```
## Placeholders
diff --git a/lib/encrypt.js b/lib/encrypt.js
index 576eda2..a09cab4 100644
--- a/lib/encrypt.js
+++ b/lib/encrypt.js
@@ -2,7 +2,7 @@
* readlineSync
* https://github.com/anseki/readline-sync
*
- * Copyright (c) 2015 anseki
+ * Copyright (c) 2016 anseki
* Licensed under the MIT license.
*/
diff --git a/lib/read.cs.js b/lib/read.cs.js
index e8fbed7..c5aa354 100644
--- a/lib/read.cs.js
+++ b/lib/read.cs.js
@@ -4,7 +4,7 @@
* readlineSync
* https://github.com/anseki/readline-sync
*
- * Copyright (c) 2015 anseki
+ * Copyright (c) 2016 anseki
* Licensed under the MIT license.
*/
diff --git a/lib/read.ps1 b/lib/read.ps1
index c5b931b..9455d52 100644
--- a/lib/read.ps1
+++ b/lib/read.ps1
@@ -1,7 +1,7 @@
# readlineSync
# https://github.com/anseki/readline-sync
#
-# Copyright (c) 2015 anseki
+# Copyright (c) 2016 anseki
# Licensed under the MIT license.
Param(
diff --git a/lib/read.sh b/lib/read.sh
index 735f589..66cd29d 100644
--- a/lib/read.sh
+++ b/lib/read.sh
@@ -1,7 +1,7 @@
# readlineSync
# https://github.com/anseki/readline-sync
#
-# Copyright (c) 2015 anseki
+# Copyright (c) 2016 anseki
# Licensed under the MIT license.
# Use perl for compatibility of sed/awk of GNU / POSIX, BSD. (and tr)
diff --git a/lib/readline-sync.js b/lib/readline-sync.js
index f9e3ad7..cc54f25 100644
--- a/lib/readline-sync.js
+++ b/lib/readline-sync.js
@@ -2,7 +2,7 @@
* readlineSync
* https://github.com/anseki/readline-sync
*
- * Copyright (c) 2015 anseki
+ * Copyright (c) 2016 anseki
* Licensed under the MIT license.
*/
@@ -1198,8 +1198,13 @@ exports.keyInSelect = function(items, query, options) {
// -------- forced
trueValue: null,
falseValue: null,
- caseSensitive: false
- // limit (by items)
+ caseSensitive: false,
+ // limit (by items),
+ phContent: function(param) {
+ return param === 'itemsCount' ? items.length + '' :
+ param === 'firstItem' ? (items[0] + '').trim() :
+ param === 'lastItem' ? (items[items.length - 1] + '').trim() : null;
+ }
}),
// added: guide, cancel
keylist = '', key2i = {}, charCode = 49 /* '1' */, display = '\n';
@@ -1210,13 +1215,17 @@ exports.keyInSelect = function(items, query, options) {
var key = String.fromCharCode(charCode);
keylist += key;
key2i[key] = i;
- display += '[' + key + '] ' + item.trim() + '\n';
+ display += '[' + key + '] ' + (item + '').trim() + '\n';
charCode = charCode === 57 /* '9' */ ? 97 /* 'a' */ : charCode + 1;
});
if (!options || options.cancel !== false) {
keylist += '0';
key2i['0'] = -1;
- display += '[' + '0' + '] CANCEL\n';
+ /* jshint eqnull:true */
+ display += '[' + '0' + '] ' +
+ (options && options.cancel != null && typeof options.cancel !== 'boolean' ?
+ (options.cancel + '').trim() : 'CANCEL') + '\n';
+ /* jshint eqnull:false */
}
readOptions.limit = keylist;
display += '\n';
diff --git a/package.json b/package.json
index d0402d6..b678851 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "readline-sync",
- "version": "1.2.22",
+ "version": "1.3.0",
"title": "readlineSync",
"description": "Synchronous Readline for interactively running to have a conversation with the user via a console(TTY).",
"keywords": [